Een annotatie is geen paginainhoud. Wanneer u TextOut aanroept of een rechthoek tekent, worden de markeringen onderdeel van de contentstream van de pagina, ingebakken in de bytes die een renderer tekent. Een annotatie is een afzonderlijk dictionary dat aan de pagina hangt via de /Annots-array, met een eigen rechthoek, een eigen weergave en een eigen levenscyclus. Een lezer kan deze openen, verplaatsen, verbergen of verwijderen zonder een enkel glyph van de onderliggende pagina aan te raken. Die scheiding is de hele reden waarom annotaties bestaan, en het is ook de bron van de twee dingen die mensen als eerste verrassen: waar een annotatie terechtkomt en hoe deze eruitziet zodra een specifieke viewer deze in handen krijgt.
HotPDF stelt de ISO 32000-annotatiesubtypes beschikbaar via een reeks AddXxxAnnotation-aanroepen op het pagina-object. Ze delen allemaal dezelfde vorm: een rechthoek die de annotatie op de pagina vastlegt in de PDF-gebruikersruimte, wat payload (tekst, een stempelnaam, een paar punten) en een kleur. Als de rechthoek goed is, is het meeste werk gedaan. De rest is weten welke subtypes hun eigen weergave dragen en welke op de viewer vertrouwen om ze te tekenen.

De rechthoek is de annotatie, niet de tekst
Elke annotatie-aanroep vereist een TRect, en die rechthoek betekent iets anders dan de coördinaten die u aan TextOut doorgeeft. Voor een tekstnotitie is het de klikbare hotspot, het kleine gebied waar het notitiepictogram zich bevindt en waar een klik de opmerking opent. Voor een vierkant of een vrij tekstvak is het de zichtbare omvang van de markering. Voor een stempel is het het vak waarin de stempelafbeelding wordt geschaald. De getallen zijn PDF-gebruikersruimtepunten, gemeten vanaf de linksonderhoek van de pagina waarbij Y naar boven toe toeneemt, dezelfde conventie die de rest van HotPDF gebruikt.
Een tekstnotitie is het lichtste subtype. U geeft het de tekstinhoud, een rechthoek voor het pictogram, een vlag of het standaard wordt geopend, een pictogramnaam en een kleur.
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);
De rechthoek is hier bewust klein gehouden, ongeveer twintig punten aan elke kant, omdat een tekstnotitie alleen een pictogram is totdat iemand erop klikt. Als u de rechthoek groot maakt, krijgt u geen grote notitie, maar een te groot klikdoel waarbij het pictogram in een hoek is vastgezet. De Open-vlag bepaalt of de popup wordt getoond wanneer het document wordt geladen. Als u een handvol notities op True instelt, stapelen ze zich op elkaar en bovenop de inhoud, dus reserveer dat voor die ene notitie die u de lezer daadwerkelijk direct wilt laten zien.
De pictogramnaam is afkomstig van THPDFTextAnnotationType, die verwijst naar de standaard notitiepictogrammen: taComment, taKey, taNote, taHelp, taParagraph, taNewParagraph en taInsert. Het pictogram is het enige wat door het type wordt gewijzigd. Het verandert het gedrag niet, en het is goed om te weten dat niet elke viewer ze alle zeven tekent; de veilige opties voor zowel oude als nieuwe lezers zijn taComment, taNote en taHelp.
Vrije tekst schrijft op de pagina, maar blijft een annotatie
Een vrije-tekstannotatie ziet eruit als inhoud omdat de tekst zichtbaar is zonder klik en als een bijschrift in de rechthoek staat. Het is echter nog steeds een annotatie, met alle scheidbaarheid van dien, wat precies is wat u wilt voor een revisiestempel of een conceptlabel dat later moet kunnen worden verwijderd. De signatuur wisselt het pictogram en de open-vlag in voor een uitlijningswaarde.
Pdf.CurrentPage.AddFreeTextAnnotation(
'DRAFT - not for distribution',
Rect(200, 210, 400, 235), // the box the text is laid into
ftCenter, // ftLeftJust / ftCenter / ftRightJust
clRed);
Hier is de rechthoek belangrijker dan bij een tekstnotitie, omdat de tekst erin wordt afgebroken en uitgelijnd. Als u het vak te laag maakt, wordt de tekst aan de onderkant afgekapt; maakt u het te smal, dan breekt de tekst af op ongewenste plaatsen. De uitlijning is afkomstig van THPDFFreeTextAnnotationJust en kent slechts drie waarden. Omdat vrije tekst een markeertekenannotatie is, kan een lezer die het bestand in een editor opent deze als één geheel selecteren, verplaatsen of verwijderen. Dit is het verschil dat bepaalt of u vrije tekst gebruikt of de woorden gewoon tekent met TextOut. Als het label permanent moet zijn, teken het dan. Als het redactioneel is en later verwijderd moet worden, maak er dan een annotatie van.
Geometrische en lijnmarkeringen om naar dingen te wijzen
Vierkanten, cirkels en lijnen zijn de markeringen die u gebruikt om naar een gebied te wijzen in plaats van het in woorden te beschrijven. AddCircleSquareAnnotation ondersteunt de twee vormen via een THPDFCSAnnotationType van csCircle of csSquare, waarbij de rechthoek de grenzen van de vorm aangeeft.
// 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;
Merk op dat de lijnannotatie afwijkt van het rechthoekpatroon: deze vereist twee THPDFCurrPoint-records, een begin en een eind, omdat een lijn wordt gedefinieerd door zijn eindpunten en niet door een omsluitend kader. De kleur bepaalt de omlijning. Als u pijlpunten wilt, heeft HotPDF overloads van AddLineAnnotation die lijnstijlen accepteren, maar de eenvoudige vorm met drie argumenten tekent een kale lijn, wat meestal is wat gewenst is voor een aanduiding.
Tekstmarkeringssubtypes werken op een gebied dat u al hebt opgemaakt. AddHighlightAnnotation vereist een rechthoek, optionele inhoud en een kleur die standaard geel is, en kleurt het gebied in zoals een markeerstift dat zou doen. Het is bedoeld om over echte tekst te liggen, dus de rechthoek moet overeenkomen met de grenzen van de woorden die u hebt getekend, wat betekent dat u deze over het algemeen berekent op basis van dezelfde coördinaten die u aan TextOut hebt doorgegeven in plaats van te gokken.
Stempels zijn afhankelijk van de viewer voor de weergave
Een stempelannotatie is de annotatie die er waarschijnlijk het meest verschillend uitziet van de ene lezer tot de andere, en het is de moeite waard om de reden daarvan te begrijpen. AddStampAnnotation benoemt een standaardstempel via THPDFStampAnnotationType, met waarden zoals satApproved, satConfidential, satFinal, satDraft en satForComment.
Pdf.CurrentPage.AddStampAnnotation(
'Approved for release on review',
Rect(50, 400, 200, 440),
satApproved,
clGreen);
De stempelnaam is een verzoek. PDF definieert de set van standaard stempelnamen, maar niet de grafische weergave erachter, dus elke viewer levert zijn eigen weergave van "APPROVED" of "CONFIDENTIAL", en sommige viewers tonen helemaal niets voor namen die ze niet herkennen. De rechthoek bepaalt het vak waarin de afbeelding wordt geschaald, en de kleur is een suggestie die de viewer al dan niet kan overnemen. Als een stempel er overal identiek uit moet zien, is de betrouwbare weg helemaal geen standaardstempel: teken de markering zelf met TextOut en de tekenaanroepen, of plaats deze als een vrije-tekstannotatie waarvan u de weergave beheert. Kies voor de standaardstempel wanneer u de vertrouwde look van de viewer wilt en de variatie kunt tolereren.
Bestandsbijlagen volgen dezelfde vorm van een rechthoek plus payload. AddFileAttachmentAnnotation vereist de beschrijving, het pad van het in te sluiten bestand, een rechthoek voor het paperclippictogram en een kleur. Het bestand bevindt zich in de PDF en het pictogram is de handgreep die een lezer gebruikt om het uit te pakken.
Hoe annotaties verschillen van AcroForm-velden
De verwarring die de meeste tijd kost, is het behandelen van een annotatie als of het een formulierveld is. Beide worden aan de pagina gekoppeld via /Annots, en een formulierveld is in feite een speciaal annotatiesubtype (een widget), wat verklaart waarom ze op elkaar lijken. Ze zijn echter niet uitwisselbaar. Een formulierveld bevat een waarde, heeft een naam, neemt deel aan de tabvolgorde en kan worden verzonden, gereset of gescript; u maakt deze aan met de aanroepen AddTextField, AddCheckBox en AddPushButton, en niet met de annotatie-aanroepen op deze pagina. Een markeerannotatie bevat een opmerking of een vorm, heeft geen waarde om te verzenden en is het verkeerde hulpmiddel zodra u invoer moet verzamelen.
De praktische test is eenvoudig. Als het de bedoeling is dat een gebruiker typt, kiest of klikt en het document dit onthoudt, wilt u een AcroForm-veld. Als u een notitie achterlaat, een gebied markeert of een status stempelt die met het bestand meereist maar geen gegevens bevat, wilt u een annotatie. Het door elkaar halen leidt tot documenten die er goed uitzien maar verkeerd werken: een "veld" dat niemand kan invullen, of een opmerking die verdwijnt wanneer een formulier wordt gereset. De interactieve kant, met veldtypen, validatie en verzendacties, is een op zichzelf staand onderwerp dat wordt behandeld in de handleiding voor AcroForm-velden en -acties.
Een pagina samenstellen
De onderdelen worden op dezelfde manier samengesteld als de rest van HotPDF. Stel documenteigenschappen in, roep BeginDoc aan, teken de gewenste paginainhoud met de tekst- en grafische aanroepen, voeg annotaties daarbovenop toe en sluit af met EndDoc. Annotaties worden gekoppeld aan CurrentPage, dus na een AddPage komen ze op de nieuwe pagina terecht, en een notitie die bedoeld was voor pagina één zal stilletjes op pagina twee verschijnen als u deze na de pagina-einde toevoegt.
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;
Een laatste reflex die de moeite waard is om te ontwikkelen wanneer de uitvoer er verkeerd uitziet: open het bestand in meer dan één viewer voordat u besluit dat de code defect is. Stempels en de minder vaak voorkomende notitiepictogrammen zijn meestal de boosdoeners. Omdat de annotatie een verzoek aan de lezer is in plaats van getekende pixels, is een verschil tussen Acrobat en een lichte viewer vaak de specificatie die werkt zoals ontworpen, en geen fout in uw aanroep.
De hier getoonde annotatie-aanroepen maken deel uit van de HotPDF-component voor Delphi en C++Builder.