Technical Article

PDF anotacijų kūrimas su „HotPDF“ „Delphi“ aplinkoje: tipai ir stačiakampiai

Anotacija nėra puslapio turinys. Kai iškviečiate TextOut arba nubrėžiate stačiakampį, šie objektai tampa puslapio turinio srauto dalimi, įrašoma tiesiai į baitus, kuriuos piešia atvaizdavimo variklis. Anotacija yra atskiras žodynas (angl. dictionary), susietas su puslapiu per jo /Annots masyvą, turintis savo stačiakampį, savo išvaizdą ir savo gyvavimo ciklą. Skaityklė gali ją atidaryti, perkelti, paslėpti arba pašalinti neliesdama nė vieno po ja esančio puslapio simbolio. Šis atskyrimas yra pagrindinė anotacijų gyvavimo priežastis, o kartu ir dviejų dalykų, kurie dažniausiai nustebina programuotojus, šaltinis: kur anotacija atsiranda ir kaip ji atrodo, kai ją atidaro konkreti peržiūros programa.

„HotPDF“ pateikia ISO 32000 anotacijų potipius per puslapio objekto AddXxxAnnotation metodų šeimą. Visi jie turi bendrą struktūrą: stačiakampį, kuris fiksuoja anotaciją puslapyje PDF naudotojo erdvėje, naudingąjį turinį (tekstą, antspaudo pavadinimą, taškų porą) ir spalvą. Teisingai nustačius stačiakampį, didžioji dalis darbo jau atlikta. Likusi dalis – žinoti, kurie potipiai turi savo išvaizdą, o kurie priklauso nuo peržiūros programos atvaizdavimo.

„HotPDF“ sukurtas PDF puslapis, kuriame rodomos tekstinių pastabų piktogramos, laisvo teksto laukai, stačiakampiai bei linijiniai žymėjimai ir patvirtinimo antspaudai
Vienas puslapis, kuriame vienu metu talpinami keli anotacijų potipiai: tekstinės pastabos, laisvas tekstas, geometriniai žymėjimai ir antspaudai

Anotacija yra stačiakampis, o ne tekstas

Kiekvienas anotacijos iškvietimas priima TRect struktūrą, ir šis stačiakampis reiškia visai ką kita nei koordinatės, kurias perduodate metodui TextOut. Tekstinėje pastaboje tai yra spustelėjama sritis, nedidelis regionas, kuriame yra pastabos piktograma ir kurį spustelėjus atidaromas komentaras. Stačiakampio arba laisvo teksto laukelio atveju tai yra matomos žymėjimo ribos. Antspaudo atveju tai yra rėmelis, į kurį keičiamas antspaudo piešinio mastelis. Skaičiai nurodomi PDF naudotojo erdvės taškais (angl. points), matuojamais nuo apatinio kairiojo puslapio kampo, o Y koordinatė didėja į viršų, tai yra ta pati taisyklė, kurią naudoja ir likusios „HotPDF“ dalys.

Tekstinė pastaba yra paprasčiausias potipis. Jai pateikiamas pagrindinis tekstas, piktogramos stačiakampis, požymis, ar ji atidaroma pagal numatytuosius nustatymus, piktogramos pavadinimas ir spalva.

Pdf.CurrentPage.AddTextAnnotation(
  'Reviewer: confirm the totals on this line before sign-off.',
  Rect(120, 700, 140, 720),   // icon hotspot, ~20pt square
  False,                      // closed until the reader clicks it
  taComment,                  // bubble icon
  clBlue);

Stačiakampis čia sąmoningai parinktas mažas, maždaug dvidešimties taškų kraštinės, nes tekstinė pastaba yra tik piktograma, kol kas nors ją spustelėja. Padarę stačiakampį didelį, negausite didelės pastabos; gausite tiesiog per didelį spustelėjimo taikinį su piktograma, prisegta prie vieno kampo. Open požymis valdo, ar iškylantysis langas rodomas įkeliant dokumentą. Jei nustatysite kelias pastabas kaip True, jos bus išdėstytos viena ant kitos ir ant turinio, todėl šį nustatymą palikite tik tai pastabai, kurią skaitytojas iš tikrųjų turi pamatyti nedelsiant.

Piktogramos pavadinimas paimamas iš THPDFTextAnnotationType tipo, kuris atitinka standartines pastabų piktogramas: taComment, taKey, taNote, taHelp, taParagraph, taNewParagraph ir taInsert. Piktograma yra vienintelis dalykas, kurį pakeičia šis tipas. Ji nekeičia elgsenos, be to, naudinga žinoti, kad ne kiekviena peržiūros programa atvaizduoja visas septynias; saugiausios naudoti tiek senose, tiek naujose skaityklėse yra taComment, taNote ir taHelp.

Laisvas tekstas rašomas puslapyje, bet išlieka anotacija

Laisvo teksto anotacija atrodo kaip puslapio turinys, nes tekstas yra matomas be jokių spustelėjimų, esantis savo stačiakampyje kaip antraštė. Tačiau tai vis tiek yra anotacija su visomis iš to išplaukiančiomis atskyrimo galimybėmis, o tai yra būtent tai, ko reikia peržiūros žymai ar juodraščio etiketei, kurią vėliau turėtų būti galima pašalinti. Šio metodo parašas pakeičia piktogramą ir atidarymo požymį lygiavimo reikšme.

Pdf.CurrentPage.AddFreeTextAnnotation(
  'DRAFT - not for distribution',
  Rect(200, 210, 400, 235),   // the box the text is laid into
  ftCenter,                   // ftLeftJust / ftCenter / ftRightJust
  clRed);

Čia stačiakampis yra svarbesnis nei tekstinės pastabos atveju, nes tekstas jame keliamas į kitą eilutę ir lygiuojamas. Jei stačiakampis bus per žemas, tekstas bus nukirptas ties apatiniu kraštu; jei per siauras, jis bus perkeltas į kitas eilutes nepageidaujamose vietose. Lygiavimas nurodomas naudojant THPDFFreeTextAnnotationJust ir turi tik tris reikšmes. Kadangi laisvas tekstas yra žymėjimo anotacija, vartotojas, atidaręs failą redaktoriuje, gali jį pasirinkti, perkelti arba ištrinti kaip vientisą objektą, ir to pakanka apsispręsti, ar naudoti laisvą tekstą, ar tiesiog nupiešti žodžius su TextOut. Jei užrašas turi būti nuolatinis, nupieškite jį. Jei jis yra redakcinio pobūdžio ir skirtas vėliau pašalinti, paverskite jį anotacija.

Geometrinis ir linijinis žymėjimas, skirtas nurodyti objektus

Stačiakampiai, apskritimai ir linijos yra žymėjimo priemonės, naudojamos norint nurodyti tam tikrą sritį, o ne aprašyti ją žodžiais. Metodas AddCircleSquareAnnotation apima dvi formas naudojant THPDFCSAnnotationType reikšmes csCircle arba csSquare, o stačiakampis apibrėžia formos ribas.

// A box drawn around a figure that needs attention
Pdf.CurrentPage.AddCircleSquareAnnotation(
  'Check this region against the source data',
  Rect(50, 300, 120, 360),
  csSquare,
  clGreen);

// A line, given two points rather than a rectangle
var
  StartPt, EndPt: THPDFCurrPoint;
begin
  StartPt.X := 130; StartPt.Y := 360;
  EndPt.X   := 250; EndPt.Y   := 320;
  Pdf.CurrentPage.AddLineAnnotation(
    'Points from the note to the figure',
    StartPt, EndPt,
    clBlue);
end;

Atkreipkite dėmesį, kad linijos anotacija pažeidžia stačiakampio šabloną: ji priima du THPDFCurrPoint įrašus (pradžią ir pabaigą), nes linija apibrėžiama jos galiniais taškais, o ne ribojančiu stačiakampiu. Spalva nustato brėžį. Jei pageidaujate rodyklių antgalių, „HotPDF“ siūlo perkrautus AddLineAnnotation metodus, kurie priima linijos pabaigos stilius, tačiau paprasta trijų argumentų forma nubrėžia tiesiog paprastą liniją, kurios dažniausiai ir pakanka nuorodai.

Teksto žymėjimo potipiai veikia jau suformuotoje srityje. Metodas AddHighlightAnnotation priima stačiakampį, pasirinktinį turinį bei spalvą (kuri pagal numatytuosius nustatymus yra geltona) ir nuspalvina sritį panašiai kaip žymeklis. Ji skirta dėti ant tikro teksto, todėl stačiakampis turėtų atitikti jūsų nupieštų žodžių ribas, o tai reiškia, kad paprastai jį apskaičiuojate pagal tas pačias koordinates, kurias perdavėte TextOut, o ne spėliojate.

Antspaudai priklauso nuo peržiūros programos atvaizdavimo

Antspaudo anotacija yra ta, kuri greičiausiai atrodys skirtingai įvairiose skaityklėse, ir priežastį verta suprasti. Metodas AddStampAnnotation nurodo standartinį antspaudą per THPDFStampAnnotationType su tokiomis reikšmėmis kaip satApproved, satConfidential, satFinal, satDraft ir satForComment.

Pdf.CurrentPage.AddStampAnnotation(
  'Approved for release on review',
  Rect(50, 400, 200, 440),
  satApproved,
  clGreen);

Antspaudo pavadinimas yra tik užklausa. PDF specifikacijoje apibrėžti standartiniai antspaudų pavadinimai, bet ne patys grafiniai elementai, todėl kiekviena peržiūros programa pateikia savo „APPROVED“ arba „CONFIDENTIAL“ vizualizaciją, o kelios išvis nieko neatvaizduoja neatpažįstamiems pavadinimams. Stačiakampis valdo rėmelį, į kurį keičiamas piešinio mastelis, o spalva tėra rekomendacija, kurios peržiūros programa gali ir nepaisyti. Jei antspaudas visur turi atrodyti identiškai, patikimiausias būdas yra nenaudoti standartinio antspaudo: nupieškite ženklą patys naudodami TextOut bei grafikos metodus arba įdėkite jį kaip laisvo teksto anotaciją, kurios išvaizdą patys kontroliuojate. Rinkitės standartinį antspaudą tada, kai norite skaityklei būdingos išvaizdos ir galite toleruoti nedidelius skirtumus.

Failų prisegtukai naudoja tą pačią stačiakampio ir naudingojo turinio formą. Metodas AddFileAttachmentAnnotation priima aprašymą, įterpiamo failo kelią, stačiakampį sąvaržėlės piktogramai ir spalvą. Failas patalpinamas PDF viduje, o piktograma yra nuoroda, kurią skaitytojas naudoja jam išskleisti.

Kuo anotacijos skiriasi nuo „AcroForm“ laukų

Painiava, kuri atima daugiausiai laiko, kyla traktuojant anotaciją kaip formos lauką. Abu objektai yra susieti su puslapiu per /Annots, o formos laukas iš tikrųjų yra specialus anotacijos potipis (valdiklis), todėl jie atrodo panašūs. Tačiau jie nėra keičiami vienas kitu. Formos laukas saugo reikšmę, turi pavadinimą, dalyvauja tabuliacijos tvarkoje ir gali būti pateikiamas, nustatomas iš naujo arba programuojamas scenarijais; juos kuriate naudodami AddTextField, AddCheckBox ir AddPushButton metodus, o ne šio puslapio anotacijų metodus. Žymėjimo anotacija tiesiog saugo komentarą arba formą, neturi jokios pateikiamos reikšmės ir yra netinkamas įrankis, kai reikia rinkti naudotojo įvestį.

Praktinis testas yra paprastas. Jei vartotojas turi įvesti tekstą, pasirinkti ar spustelėti ir dokumentas turi tai įsiminti, jums reikia „AcroForm“ lauko. Jei tiesiog paliekate pastabą, pažymite sritį ar uždedate būsenos antspaudą, kuris keliauja kartu su failu, bet nėra duomenys, jums reikia anotacijos. Sumaišius juos, gaunami dokumentai, kurie atrodo teisingai, bet veikia blogai: laukas, kurio niekas negali užpildyti, arba komentaras, kuris išnyksta išvalius formą. Interaktyvioji pusė su laukų tipais, patvirtinimu ir pateikimo veiksmais yra atskira tema, aprašyta „AcroForm“ laukų ir veiksmų vadove.

Puslapio sujungimas į visumą

Dalys sujungiamos taip pat, kaip ir likusiose „HotPDF“ funkcijose. Nustatykite dokumento savybes, iškvieskite BeginDoc, nupieškite reikiamą puslapio turinį naudodami teksto bei grafikos iškvietimus, viršuje pridėkite anotacijas ir užbaikite su EndDoc. Anotacijos pridedamos prie CurrentPage, todėl po AddPage iškvietimo jos atsidurs naujame puslapyje, o pastaba, kurią skyrėte pirmam puslapiui, tyliai atsiras antrame puslapyje, jei ją pridėsite po puslapio lūžio.

Pdf := THotPDF.Create(nil);
try
  Pdf.FileName := 'annotated.pdf';
  Pdf.Compression := cmFlateDecode;
  Pdf.FontEmbedding := True;
  Pdf.BeginDoc;

  Pdf.CurrentPage.SetFont('Arial', [], 11);
  Pdf.CurrentPage.TextOut(50, 740, 0, 'Quarterly figures, draft for review');

  Pdf.CurrentPage.AddTextAnnotation(
    'Confirm the totals before sign-off.',
    Rect(50, 720, 70, 740), False, taComment, clBlue);
  Pdf.CurrentPage.AddFreeTextAnnotation(
    'DRAFT', Rect(450, 720, 540, 745), ftCenter, clRed);
  Pdf.CurrentPage.AddStampAnnotation(
    'For comment', Rect(50, 660, 180, 695), satForComment, clGreen);

  Pdf.EndDoc;
finally
  Pdf.Free;
end;

Paskutinis įprotis, kurį verta išsiugdyti, kai rezultatas atrodo neteisingas: prieš nuspręsdami, kad kodas yra sugadintas, atidarykite failą daugiau nei vienoje peržiūros programoje. Antspaudai ir retesnės pastabų piktogramos dažniausiai yra pagrindiniai nesuderinamumo šaltiniai. Kadangi anotacija yra tik užklausa skaityklei, o ne nupiešti pikseliai, skirtumas tarp „Acrobat“ ir paprastos peržiūros programos dažnai yra tiesiog specifikacijos veikimas taip, kaip suprojektuota, o ne klaida jūsų programos iškvietime.

Čia parodyti anotacijų metodai yra „Delphi“ ir „C++Builder“ skirtos „HotPDF“ komponento dalis.