Tekninen artikkeli

PDF-merkinnät Delphissä HotPDFillä

Annotation ei ole osa sivun sisältöä. TextOut-kutsulla kirjoitettu teksti tai piirretty suorakulmio tallentuu sivun content stream -virtaan, mutta annotation on erillinen dictionary, johon sivu viittaa /Annots-taulukosta. Sillä on oma suorakulmio, ulkoasu ja elinkaari, joten lukija voi avata, siirtää, piilottaa tai poistaa sen muuttamatta sivun alla olevia glyphs-merkkejä. Tämä ero selittää sekä annotation-kohdan että sen, miksi ulkoasu voi vaihdella katseluohjelmittain

HotPDF paljastaa ISO 32000 -merkintöjen alatyypit (subtypes) sivuobjektin AddXxxAnnotation-kutsujen perheen kautta. Ne kaikki jakavat saman muodon: suorakulmio, joka kiinnittää merkinnän sivulle PDF-käyttäjätilassa (PDF user space), jokin hyötykuorma (teksti, leiman nimi, pistepari) ja väri. Kun saat suorakulmion oikein, suurin osa työstä on tehty. Loppu on sen tietämistä, mitkä alatyypit kantavat oman ulkoasunsa ja mitkä tukeutuvat katseluohjelmaan niiden piirtämisessä

HotPDF:n tuottama PDF-sivu, joka näyttää tekstihuomautuskuvakkeita, vapaan tekstin laatikoita, neliö- ja viivamerkintöjä sekä hyväksymisleimoja sijoitettuna eri puolille sivua
Yksi sivu, joka kantaa useita merkintöjen alatyyppejä kerralla: tekstihuomautuksia, vapaata tekstiä, geometrisia merkintöjä ja leimoja

Suorakulmio on merkintä, ei teksti

Jokainen merkintäkutsu ottaa TRect-tyypin, ja tuo suorakulmio merkitsee eri asiaa kuin koordinaatit, jotka välität TextOut-toiminnolle. Tekstihuomautukselle se on napsautettava aktiivinen alue (hotspot), pieni alue, jossa huomautuskuvake istuu ja jossa napsautus avaa kommentin. Neliölle tai vapaan tekstin laatikolle se on merkinnän näkyvä laajuus. Leimalle se on laatikko, johon leiman grafiikka skaalataan. Luvut ovat PDF-käyttäjätilan pisteitä, mitattuna sivun vasemmasta alakulmasta siten, että Y kasvaa ylöspäin, sama käytäntö, jota muu osa HotPDF:stä käyttää

Tekstihuomautus on kevyin alatyyppi. Annat sille leipätekstin, suorakulmion kuvakkeelle, lipun siitä, avautuuko se oletuksena, kuvakkeen nimen ja värin

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

Suorakulmio on tässä tarkoituksella pieni, noin kaksikymmentä pistettä sivultaan, koska tekstihuomautus on vain kuvake, kunnes joku napsauttaa sitä. Tee suorakulmiosta suuri, etkä saa suurta huomautusta; saat ylisuuren napsautuskohteen (click target), jonka kuvake on kiinnitetty yhteen nurkkaan. Open-lippu ohjaa sitä, näkyykö ponnahdusikkuna asiakirjan latautuessa. Aseta kourallinen huomautuksia arvoon True, ja ne pinoutuvat päällekkäin ja sisällön päälle, joten varaa se sille yhdelle huomautukselle, jonka todella haluat lukijan näkevän välittömästi

Kuvakkeen nimi tulee THPDFTextAnnotationType-tyypistä, joka yhdistyy standardeihin huomautuskuvakkeisiin: taComment, taKey, taNote, taHelp, taParagraph, taNewParagraph ja taInsert. Kuvake on ainoa asia, jonka tyyppi muuttaa. Se ei muuta käyttäytymistä, ja on hyvä tietää, että kaikki katseluohjelmat eivät piirrä kaikkia seitsemää; turvalliset vaihtoehdot vanhoissa ja uusissa lukijoissa ovat taComment, taNote ja taHelp

Vapaa teksti kirjoittaa sivulle, mutta pysyy merkintänä

Vapaan tekstin merkintä (free text annotation) näyttää sisällöltä, koska teksti on näkyvissä ilman napsautusta istuen suorakulmiossaan kuin kuvateksti. Se on edelleen merkintä kaikkine erotettavuuksineen (separability), mitä se tarkoittaa, ja se on juuri sitä, mitä haluat tarkistusleimalle tai luonnostarralle, jonka jonkun pitäisi pystyä poistamaan myöhemmin. Allekirjoitus (signature) vaihtaa kuvakkeen ja avoimen lipun (open flag) tasauksen arvoon (justification value)

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

Tässä suorakulmiolla on enemmän merkitystä kuin tekstihuomautuksella, koska teksti rivittyy ja tasaantuu sen sisällä. Jos laatikon mitoittaa liian lyhyeksi, teksti leikkautuu alareunasta; liian kapeaksi, ja se rivittyy paikoissa, joita et tarkoittanut. Tasaus tulee THPDFFreeTextAnnotationJust-tyypistä, ja sillä on vain kolme arvoa. Koska vapaa teksti on tekstimerkkausmerkintä (markup annotation), lukija, joka avaa tiedoston editorissa, voi valita sen, siirtää sitä tai poistaa sen kokonaisuutena, mikä on se ero, joka ratkaisee, tartutko vapaaseen tekstiin vai piirrätkö sanat vain TextOut-toiminnolla. Jos tarran on oltava pysyvä, piirrä se. Jos se on toimituksellinen (editorial) ja tarkoitettu poistettavaksi, tee siitä merkintä

Geometriset ja viivamerkinnät asioihin osoittamiseen

Neliöt, ympyrät ja viivat ovat merkintöjä, joita käytät osoittamaan alueeseen pikemminkin kuin kuvailemaan sitä sanoin. AddCircleSquareAnnotation kattaa kaksi laatikkomuotoa THPDFCSAnnotationType-tyypin csCircle tai csSquare kautta, ja suorakulmio antaa muodon rajat

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

Huomaa, että viivamerkintä rikkoo suorakulmiokuvion: se ottaa kaksi THPDFCurrPoint-tietuetta, alun ja lopun, koska viiva määritellään sen päätepisteillä, ei rajoituslaatikolla (bounding box). Väri asettaa viivan (stroke). Jos haluat nuolenpäitä, HotPDF:ssä on AddLineAnnotation-ylikuormituksia (overloads), jotka hyväksyvät viivan päättymistyylejä, mutta yksinkertainen kolmen argumentin muoto piirtää paljaan viivan, mikä on yleensä se, mitä huomioteksti (callout) haluaa

Tekstimerkkausalatyypit (text-markup subtypes) toimivat alueella, jonka olet jo asettanut. AddHighlightAnnotation ottaa suorakulmion, valinnaisen sisällön ja värin, joka on oletuksena keltainen, ja sävyttää alueen samalla tavalla kuin korostuskynä. Se on tarkoitettu istumaan oikean tekstin päälle, joten suorakulmion tulisi vastata piirtämiesi sanojen rajoja, mikä tarkoittaa, että yleensä lasket sen samoista koordinaateista, jotka välitit TextOut-toiminnolle, etkä arvaamalla

Leimat riippuvat katseluohjelmasta niiden renderöinnissä

Leimamerkintä (stamp annotation) on todennäköisimmin erinäköinen lukijasta toiseen, ja syy on ymmärtämisen arvoinen. AddStampAnnotation nimeää standardin leiman THPDFStampAnnotationType-tyypin kautta, jolla on arvoja kuten satApproved, satConfidential, satFinal, satDraft ja satForComment

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

Leiman nimi on pyyntö. PDF määrittelee joukon standardeja leiman nimiä, mutta ei niiden takana olevaa grafiikkaa, joten jokainen katseluohjelma toimittaa oman renderöintinsä nimille "APPROVED" tai "CONFIDENTIAL", ja muutama ei renderöi mitään nimille, joita he eivät tunnista. Suorakulmio ohjaa laatikkoa, johon grafiikka skaalautuu, ja väri on vihje, jota katseluohjelma saattaa kunnioittaa tai olla kunnioittamatta. Jos leiman on näytettävä identtiseltä kaikkialla, luotettava reitti ei ole standardi leima lainkaan: piirrä merkki itse TextOut-toiminnolla ja piirtokutsuilla tai aseta se vapaan tekstin merkintänä, jonka ulkoasua ohjaat. Tartu standardiin leimaan, kun haluat katseluohjelman tutun ilmeen ja voit sietää vaihtelua

Tiedostoliitteet noudattavat samaa suorakulmio-plus-hyötykuorma-muotoa (rectangle-plus-payload). AddFileAttachmentAnnotation ottaa kuvauksen, upotettavan tiedoston polun, suorakulmion paperiliitinkuvakkeelle ja värin. Tiedosto kulkee PDF:n sisällä, ja kuvake on kahva, jota lukija käyttää sen purkamiseen

Kuinka merkinnät eroavat AcroForm-kentistä

Hämmennys, joka maksaa eniten aikaa, on merkinnän käsitteleminen ikään kuin se olisi lomakekenttä. Molemmat kiinnittyvät sivulle /Annots-taulukon kautta, ja lomakekenttä on itse asiassa erityinen merkinnän alatyyppi (widget), minkä vuoksi ne näyttävät liittyvän toisiinsa. Ne eivät ole keskenään vaihdettavissa. Lomakekenttä pitää sisällään arvon, sillä on nimi, se osallistuu sarkainjärjestykseen (tab order) ja se voidaan lähettää, nollata tai ohjelmoida (scripted); luot niitä AddTextField-, AddCheckBox- ja AddPushButton-kutsuilla, et tällä sivulla olevilla merkintäkutsuilla. Tekstimerkkausmerkintä pitää sisällään kommentin tai muodon, sillä ei ole lähetettävää arvoa, ja se on väärä työkalu sillä hetkellä, kun sinun on kerättävä syötettä

Käytännön testi on yksinkertainen. Jos käyttäjän on tarkoitus kirjoittaa, valita tai napsauttaa ja asiakirjan tulee muistaa se, haluat AcroForm-kentän. Jos olet jättämässä huomautuksen, merkitsemässä alueen tai leimaamassa tilan, joka matkustaa tiedoston mukana, mutta ei ole dataa, haluat merkinnän. Niiden sekoittaminen tuottaa asiakirjoja, jotka näyttävät oikeilta ja käyttäytyvät väärin: "kentän", jota kukaan ei voi täyttää, tai kommentin, joka katoaa, kun lomake nollataan. Interaktiivinen puoli kenttätyyppeineen, vahvistuksineen ja lähetystoimintoineen on oma aiheensa, jota käsitellään AcroForm-kenttien ja -toimintojen katsauksessa

Sivun kokoaminen

Palaset koostuvat (compose) samalla tavalla kuin muu HotPDF. Aseta asiakirjan ominaisuudet, kutsu BeginDoc, piirrä tarvitsemasi sivun sisältö teksti- ja grafiikkakutsuilla, lisää merkinnät päälle ja sulje EndDoc-kutsulla. Merkinnät kiinnittyvät CurrentPage-objektiin, joten AddPage-kutsun jälkeen ne laskeutuvat uudelle sivulle, ja huomautus, jonka tarkoitit sivulle yksi, ilmestyy hiljaa sivulle kaksi, jos lisäät sen tauon (break) jälkeen

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;

Vielä yksi viimeinen refleksi (reflex), joka on rakentamisen arvoinen, kun tuloste näyttää väärältä: avaa tiedosto useammassa kuin yhdessä katseluohjelmassa, ennen kuin päätät koodin olevan rikki. Leimat ja harvinaisemmat huomautuskuvakkeet ovat yleisiä syyllisiä, ja koska merkintä on pyyntö lukijalle maalattujen pikselien sijaan, ero Acrobatin ja kevyen katseluohjelman välillä on usein spesifikaatio, joka toimii suunnitellusti, ei bugi kutsussasi

Tässä esitetyt merkintäkutsut ovat osa HotPDF Componentia Delphille ja C++Builderille