Műszaki cikk

PDF annotációk Delphiben a HotPDF segítségével: Típusok és téglalapok (Rects)

Az annotáció nem oldaltartalom. Amikor meghívja a TextOut-ot, vagy rajzol egy téglalapot, a jelek az oldal tartalom-folyamának (content stream) részévé válnak, belesütve a bájtokba, amelyeket a renderelő megfest. Az annotáció egy különálló szótár (dictionary), amely az oldalon lóg az /Annots tömbjén keresztül, saját téglalappal, saját megjelenéssel és saját életciklussal. Az olvasó megnyithatja, áthelyezheti, elrejtheti vagy eltávolíthatja anélkül, hogy az alatta lévő oldal egyetlen glifáját is érintené. Ez a szétválasztás az oka annak, hogy az annotációk egyáltalán léteznek, és ez a forrása annak a két dolognak is, ami az embereket először meglepi: hogy hol landol egy annotáció, és hogyan néz ki, miután egy adott nézegető a kezébe veszi

A HotPDF az ISO 32000 annotáció altípusait egy AddXxxAnnotation hívás-családon keresztül teszi elérhetővé az oldal objektumon. Mindegyik ugyanazt az alakzatot osztja meg: egy téglalapot, amely rögzíti az annotációt az oldalon a PDF felhasználói térben, valamilyen hasznos terhet (szöveget, bélyegzőnevet, egy pontpárt) és egy színt. Találja el jól a téglalapot, és a munka nagy része kész. A többi annak ismerete, hogy mely altípusok hordozzák saját megjelenésüket, és melyek támaszkodnak a nézegetőre a megrajzolásukhoz

A PDF page produced by HotPDF showing text note icons, free text boxes, square and line markups, and approval stamps placed across the page
Egy oldal, amely egyszerre több annotáció altípust hordoz: szöveges jegyzeteket, szabad szöveget, geometriai jelöléseket és bélyegzőket

A téglalap az annotáció, nem a szöveg

Minden annotáció hívás egy TRect-et vesz fel, és ez a téglalap mást jelent, mint azok a koordináták, amelyeket a TextOut-nak ad át. Szöveges jegyzet (text note) esetén ez a kattintható forró pont (hotspot), az a kis régió, ahol a jegyzet ikonja ül, és ahol egy kattintás megnyitja a megjegyzést. Négyzet vagy szabad szöveg (free text) doboz esetén ez a jelölés (markup) látható kiterjedése. Bélyegző (stamp) esetén ez az a doboz, amelybe a bélyegző grafikája (art) skálázódik. A számok PDF felhasználói térbeli pontok, az oldal bal alsó sarkától mérve, felfelé növekvő Y-nal – ugyanaz a konvenció, amelyet a HotPDF többi része is használ

A szöveges jegyzet a legkönnyebb altípus. Megadja neki a törzsszöveget, egy téglalapot az ikonhoz, egy jelzőt (flag) arra vonatkozóan, hogy alapértelmezés szerint kinyílik-e, egy ikonnevet és egy színt

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);

A téglalap itt szándékosan kicsi, körülbelül húsz pont egy-egy oldal, mert a szöveges jegyzet csak egy ikon, amíg valaki rá nem kattint. Ha a téglalapot nagyra méretezi, nem kap nagy jegyzetet; egy túlméretezett kattintási célpontot (click target) kap úgy, hogy az ikon az egyik sarokba van rögzítve. Az Open jelző vezérli, hogy az előugró ablak látható-e a dokumentum betöltésekor. Ha egy maroknyi jegyzetet True-ra állít, akkor egymásra és a tartalom tetejére fognak halmozódni, ezért tartogassa ezt arra az egyetlen jegyzetre, amelyet valójában azonnal látni akar az olvasóval

Az ikonnév a THPDFTextAnnotationType-ból származik, amely a szabványos jegyzetikonokra képeződik le: taComment, taKey, taNote, taHelp, taParagraph, taNewParagraph és taInsert. Az ikon az egyetlen dolog, amit a típus megváltoztat. Nem változtatja meg a viselkedést, és érdemes tudni, hogy nem minden nézegető rajzolja meg mind a hetet; a régiek és újak olvasók között a biztonságosak a taComment, taNote és a taHelp

A szabad szöveg az oldalra íródik, de annotáció marad

A szabad szöveges annotáció (free text annotation) tartalomnak tűnik, mert a szöveg kattintás nélkül látható, a téglalapjában ülve, mint egy felirat. Még mindig egy annotáció, annak minden elválaszthatóságával, ami pontosan az, amit egy ellenőrző bélyegzőhöz vagy egy vázlat (draft) címkéhez szeretne, amelyet később valakinek el kell tudnia távolítani. Az aláírás lecseréli az ikont és a megnyitás jelzőt (open flag) egy igazítási értékre

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

Itt a téglalap jobban számít, mint a szöveges jegyzetnél, mert a szöveg ezen belül törik meg és igazodik. Ha a doboz túl rövid, a szöveg levágódik az alsó szélen; ha túl keskeny, olyan helyeken törik meg, ahol nem szándékozta. Az igazítás a THPDFFreeTextAnnotationJust-ból származik, és csak a három értékkel rendelkezik. Mivel a szabad szöveg egy jelölő annotáció (markup annotation), az olvasó, aki megnyitja a fájlt egy szerkesztőben, egységként kiválaszthatja, áthelyezheti vagy törölheti, és ez a különbség dönti el, hogy a szabad szöveghez nyúl, vagy egyszerűen megrajzolja a szavakat a TextOut-tal. Ha a címkének állandónak kell lennie, rajzolja meg. Ha szerkesztői, és le kell jönnie, tegye annotációvá

Geometriai és vonalas jelölések dolgokra mutatáshoz

Négyzetek, körök és vonalak azok a jelölések, amelyeket arra használ, hogy egy régióra mutasson, ahelyett, hogy szavakkal írná le. Az AddCircleSquareAnnotation lefedi a két doboz alakzatot egy csCircle vagy csSquare értékű THPDFCSAnnotationType-on keresztül, a téglalappal pedig megadja az alakzat határait

// 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;

Vegye figyelembe, hogy a vonal annotáció (line annotation) megtöri a téglalap mintát: két THPDFCurrPoint rekordot vesz fel, egy kezdetet és egy véget, mert a vonalat a végpontjai határozzák meg, nem pedig egy határolókeret. A szín a körvonalat (stroke) állítja be. Ha nyílhegyeket szeretne, a HotPDF-nek vannak az AddLineAnnotation-höz olyan túlterhelései (overloads), amelyek elfogadják a vonalvégi (line-ending) stílusokat, de az egyszerű három argumentumos forma csupasz vonalat rajzol, ami általában az, amit egy kiemelés (callout) akar

A szövegkiemelő (text-markup) altípusok olyan régión működnek, amelyet Ön már elrendezett. Az AddHighlightAnnotation vesz egy téglalapot, opcionális tartalmat és egy színt, amely alapértelmezés szerint sárga, és úgy színezi ki a területet, ahogy egy szövegkiemelő toll tenné. Arra szolgál, hogy valódi szöveg fölött üljön, így a téglalapnak meg kell egyeznie a rajzolt szavak határaival, ami azt jelenti, hogy általában azokból a koordinátákból számítja ki, amelyeket átadott a TextOut-nak, ahelyett, hogy találgatna

A bélyegzők a nézegetőtől függnek a rendereléshez

A bélyegző (stamp) annotáció valószínűleg az, amelyik a legkülönbözőbben fog kinézni az egyik olvasóban a másikhoz képest, és az okot érdemes megérteni. Az AddStampAnnotation egy szabványos bélyegzőt nevez meg a THPDFStampAnnotationType-on keresztül, olyan értékekkel, mint a satApproved, satConfidential, satFinal, satDraft és a satForComment

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

A bélyegzőnév egy kérés. A PDF meghatározza a szabványos bélyegzőnevek készletét, de a mögöttük lévő grafikát nem, így minden nézegető a saját "APPROVED" (jóváhagyott) vagy "CONFIDENTIAL" (bizalmas) renderelésével (rendering) érkezik, és néhányuk egyáltalán nem renderel semmit azokra a nevekre, amelyeket nem ismer fel. A téglalap vezérli a dobozt, amelybe a grafika skálázódik, a szín pedig egy utalás (hint), amelyet a nézegető tiszteletben tarthat vagy sem. Ha egy bélyegzőnek mindenhol azonosnak kell kinéznie, a megbízható út egyáltalán nem a szabványos bélyegző: rajzolja meg magát a jelet a TextOut és a rajzoló hívások segítségével, vagy helyezze el egy szabad szöveges annotációként, amelynek megjelenését Ön szabályozza. Nyúljon a szabványos bélyegzőhöz, amikor a nézegető ismerős megjelenését szeretné, és el tudja viselni a variációt

A fájlmellékletek ugyanazt a téglalap-plusz-hasznos teher alakzatot követik. Az AddFileAttachmentAnnotation vesz fel egy leírást, a beágyazandó fájl útvonalát, egy téglalapot a gemkapocs ikonhoz, és egy színt. A fájl a PDF-en belül utazik, és az ikon a fogantyú, amelyet az olvasó a kibontáshoz használ

Miben különböznek az annotációk az AcroForm mezőktől

A legtöbb időbe kerülő zűrzavar az annotáció formamezőként (form field) történő kezelése. Mindkettő csatlakozik az oldalhoz az /Annots-on keresztül, és a formamező valójában egy speciális annotációs altípus (egy widget), ezért tűnnek rokonoknak. De nem felcserélhetők. Egy formamező értéket tart, neve van, részt vesz a tabulátor sorrendben (tab order), és beküldhető (submitted), visszaállítható (reset) vagy szkriptelhető (scripted); ezeket az AddTextField, az AddCheckBox és az AddPushButton hívásokkal hozza létre, nem pedig a jelen oldalon található annotációs hívásokkal. A jelölő annotáció (markup annotation) megjegyzést vagy alakzatot tartalmaz, nincs beküldendő értéke, és rossz eszköz attól a pillanattól kezdve, hogy adatokat (input) kell gyűjtenie

A gyakorlati teszt egyszerű. Ha a felhasználónak be kell gépelnie, ki kell választania, vagy kattintania kell, és azt szeretné, hogy a dokumentum emlékezzen rá, akkor Ön egy AcroForm mezőt akar. Ha egy jegyzetet hagy, megjelöl egy régiót, vagy egy olyan állapotot (status) bélyegyez le, amely a fájllal utazik, de nem adat, akkor egy annotációt akar. Keverésük olyan dokumentumokat eredményez, amelyek helyesnek tűnnek és rosszul viselkednek: egy "mező", amelyet senki sem tud kitölteni, vagy egy megjegyzés, amely eltűnik, amikor egy űrlapot alaphelyzetbe állítanak (reset). Az interaktív oldal, a mezőtípusokkal, ellenőrzéssel (validation) és beküldési műveletekkel, a saját témája, amelyet az AcroForm mezők és műveletek végigjárásában ismertetünk

Egy oldal összerakása

A darabok úgy állnak össze, mint a HotPDF többi részében. Állítsa be a dokumentum tulajdonságait, hívja meg a BeginDoc-ot, rajzolja meg a szükséges oldaltartalmat a szöveg- és grafikai hívásokkal, adjon hozzá annotációkat a tetejére, és zárja be az EndDoc-kal. Az annotációk a CurrentPage-hez kapcsolódnak, így egy AddPage után az új oldalon landolnak, és egy olyan jegyzet, amelyet az első oldalra szánt, csendben megjelenik a második oldalon, ha a törés (break) után adja hozzá

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;

Egy utolsó reflex, amit érdemes kiépíteni, amikor a kimenet rossznak tűnik: nyissa meg a fájlt egynél több nézegetőben, mielőtt úgy dönt, hogy a kód hibás. Általában a bélyegzők és a ritkább jegyzetikonok a bűnösök, és mivel az annotáció inkább az olvasóhoz intézett kérés (request), mintsem megfestett pixelek, a különbség az Acrobat és egy könnyűsúlyú nézegető között gyakran az előírás szerinti (as designed) működés a specifikáció (spec) alapján, nem pedig hiba (bug) a hívásban

Az itt bemutatott annotáció hívások a Delphihez és C++Builderhez készült HotPDF komponens részét képezik