En kommentar är inte sidinnehåll. När du anropar TextOut eller ritar en rektangel blir markeringarna en del av sidans innehållsström, inbakade i de byte som en renderare målar. En kommentar är en separat ordbok som hänger av sidan genom dess /Annots-array, med sin egen rektangel, sitt eget utseende och sin egen livscykel. En läsare kan öppna den, flytta den, dölja den eller ta bort den utan att röra en enda glyf på den underliggande sidan. Denna separation är hela anledningen till att kommentarer existerar, och det är också källan till de två saker som överraskar folk först: var en kommentar landar, och hur den ser ut när ett visst visningsprogram får tag i den
HotPDF exponerar ISO 32000-kommentarundertyperna genom en familj av AddXxxAnnotation-anrop på sidobjektet. De delar alla samma form: en rektangel som fäster kommentaren på sidan i PDF-användarutrymmet, viss nyttolast (text, ett stämpelnamn, ett par punkter) och en färg. Få rektangeln rätt och det mesta av jobbet är gjort. Resten är att veta vilka undertyper som bär sitt eget utseende och vilka som förlitar sig på visningsprogrammet för att rita dem

Rektangeln är kommentaren, inte texten
Varje kommentarsanrop tar en TRect, och den rektangeln betyder något annat än de koordinater du skickar till TextOut. För en textanteckning är det den klickbara hotspoten, den lilla regionen där anteckningsikonen sitter och där ett klick fäller ut kommentaren. För en fyrkant eller fritextruta är det markeringens synliga utsträckning. För en stämpel är det rutan som stämpelkonsten skalas in i. Siffrorna är PDF-användarutrymmets punkter, mätta från det nedre vänstra hörnet av sidan med Y ökande uppåt, samma konvention som resten av HotPDF använder
En textanteckning är den lättaste undertypen. Du ger den brödtexten, en rektangel för ikonen, en flagga för om den öppnas som standard, ett ikonnamn och en färg
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);
Rektangeln här är avsiktligt liten, runt tjugo punkter på varje sida, eftersom en textanteckning bara är en ikon tills någon klickar på den. Gör du rektangeln stor får du inte en stor anteckning; du får ett överdimensionerat klickmål med ikonen fastnålad i ena hörnet. Open-flaggan styr om popup-fönstret visas när dokumentet laddas. Sätter du en handfull anteckningar till True staplas de ovanpå varandra och ovanpå innehållet, så reservera det för den enda anteckning som du faktiskt vill att läsaren ska se omedelbart
Ikonnamnet kommer från THPDFTextAnnotationType, som mappar till de standardiserade anteckningsikonerna: taComment, taKey, taNote, taHelp, taParagraph, taNewParagraph och taInsert. Ikonen är det enda som typen ändrar. Det ändrar inte beteendet, och det är värt att veta att inte alla visningsprogram ritar alla sju; de säkra för gamla och nya läsare är taComment, taNote och taHelp
Fritext skriver på sidan, men förblir en kommentar
En fritextkommentar ser ut som innehåll eftersom texten är synlig utan klick, och sitter i sin rektangel som en bildtext. Den är fortfarande en kommentar, med all den separerbarhet det innebär, vilket är exakt vad du vill ha för en granskningsstämpel eller en utkastetikett som någon bör kunna ta bort senare. Signaturen byter ut ikonen och öppningsflaggan mot ett justeringsvärde
Pdf.CurrentPage.AddFreeTextAnnotation(
'DRAFT - not for distribution',
Rect(200, 210, 400, 235), // the box the text is laid into
ftCenter, // ftLeftJust / ftCenter / ftRightJust
clRed);
Här spelar rektangeln större roll än vad den gör för en textanteckning, eftersom texten radbryts och justeras inuti den. Dimensionera rutan för kort så klipps texten i underkanten; för smal så bryts den på ställen du inte avsåg. Justeringen kommer från THPDFFreeTextAnnotationJust och har bara tre värden. Eftersom fritext är en markeringskommentar kan en läsare som öppnar filen i en redigerare markera den, flytta den eller ta bort den som en enhet, vilket är skillnaden som avgör om du sträcker dig efter fritext eller bara ritar orden med TextOut. Om etiketten måste vara permanent, rita den. Om den är redaktionell och tänkt att tas bort, gör den till en kommentar
Geometriska markeringar och linjemarkeringar för att peka på saker
Fyrkanter, cirklar och linjer är markeringen du använder för att peka på en region snarare än att beskriva den i ord. AddCircleSquareAnnotation täcker de två rutformerna genom en THPDFCSAnnotationType med csCircle eller csSquare, med rektangeln som anger formens gränser
// 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;
Observera att linjekommentaren bryter rektangelmönstret: den tar två THPDFCurrPoint-poster, en början och ett slut, eftersom en linje definieras av sina ändpunkter, inte av en avgränsningsbox. Färgen sätter strecket. Om du vill ha pilspetsar har HotPDF överlagringar av AddLineAnnotation som accepterar linjeslutsstilar, men den vanliga tre-argumentformen ritar en kal linje, vilket vanligtvis är vad en utropstext vill ha
Textmarkeringsundertyper arbetar på en region du redan har layoutat. AddHighlightAnnotation tar en rektangel, valfritt innehåll och en färg som standard är gul, och tonar området på det sätt som en överstrykningspenna skulle göra. Den är tänkt att sitta över riktig text, så rektangeln bör matcha gränserna för orden du ritade, vilket innebär att du i allmänhet beräknar den från samma koordinater som du skickade till TextOut snarare än att gissa
Stämplar beror på visningsprogrammet för att renderas
En stämpelkommentar är den som med störst sannolikhet kommer att se annorlunda ut från en läsare till nästa, och anledningen är värd att förstå. AddStampAnnotation namnger en standardstämpel genom THPDFStampAnnotationType, med värden som satApproved, satConfidential, satFinal, satDraft och satForComment
Pdf.CurrentPage.AddStampAnnotation(
'Approved for release on review',
Rect(50, 400, 200, 440),
satApproved,
clGreen);
Stämpelnamnet är en begäran. PDF definierar uppsättningen av standardstämpelnamn men inte konsten bakom dem, så varje visningsprogram levererar sin egen rendering av "APPROVED" eller "CONFIDENTIAL", och några få renderar ingenting alls för namn de inte känner igen. Rektangeln styr rutan som konsten skalas in i, och färgen är en ledtråd som visningsprogrammet kan eller kanske inte respekterar. Om en stämpel måste se identisk ut överallt, är den pålitliga vägen inte en standardstämpel alls: rita markeringen själv med TextOut och ritanropen, eller placera den som en fritextkommentar vars utseende du kontrollerar. Välj standardstämpeln när du vill ha visningsprogrammets välbekanta utseende och kan tolerera variationen
Filbilagor följer samma rektangel-plus-nyttolast-form. AddFileAttachmentAnnotation tar beskrivningen, sökvägen till filen som ska bäddas in, en rektangel för gemikonen och en färg. Filen följer med inuti PDF:en, och ikonen är det handtag en läsare använder för att extrahera den
Hur kommentarer skiljer sig från AcroForm-fält
Den förvirring som kostar mest tid är att behandla en kommentar som om den vore ett formulärfält. Båda fästs på sidan genom /Annots, och ett formulärfält är i själva verket en speciell kommentarundertyp (en widget), vilket är anledningen till att de ser besläktade ut. De är inte utbytbara. Ett formulärfält har ett värde, har ett namn, deltar i tabbordningen och kan skickas in, återställas eller skriptas; du skapar dessa med anropen AddTextField, AddCheckBox och AddPushButton, inte med kommentarsanropen på denna sida. En markeringskommentar håller en kommentar eller en form, har inget värde att skicka in, och är fel verktyg så fort du behöver samla in inmatning
Det praktiska testet är enkelt. Om en användare är tänkt att skriva, välja eller klicka och få dokumentet att minnas det, vill du ha ett AcroForm-fält. Om du lämnar en anteckning, markerar en region eller stämplar en status som färdas med filen men inte är data, vill du ha en kommentar. Att blanda ihop dem producerar dokument som ser rätt ut och beter sig fel: ett "fält" som ingen kan fylla i, eller en kommentar som försvinner när ett formulär återställs. Den interaktiva sidan, med fälttyper, validering och åtgärder vid inskickande, är sitt eget ämne som behandlas i genomgången av AcroForm-fält och -åtgärder
Att sätta ihop en sida
Bitarna sätts samman på samma sätt som resten av HotPDF gör. Ställ in dokumentegenskaper, anropa BeginDoc, rita vilket sidinnehåll du än behöver med text- och grafikanropen, lägg till kommentarer ovanpå, och stäng med EndDoc. Kommentarer fästs vid CurrentPage, så efter en AddPage landar de på den nya sidan, och en anteckning du menade för sida ett kommer tyst att dyka upp på sida två om du lägger till den efter brytningen
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;
En sista reflex värd att bygga upp när utdata ser fel ut: öppna filen i mer än ett visningsprogram innan du bestämmer dig för att koden är trasig. Stämplar och de mer sällsynta anteckningsikonerna är de vanliga syndarna, och eftersom kommentaren är en begäran till läsaren snarare än målade pixlar, är en skillnad mellan Acrobat och ett lättviktigt visningsprogram ofta specifikationen som fungerar som avsett, inte en bugg i ditt anrop
De kommentarsanrop som visas här är en del av HotPDF-komponenten för Delphi och C++Builder