Stamping a watermark or a logo onto every page of a document looks like a five-minute job until you open the result in a file-size inspector. The obvious approach is to walk the pages and, on each one, build the same text or image objects again. That works visually, and it is wasteful in a way that compounds. A diagonal "DRAFT" watermark drawn directly onto a hundred-page report is a hundred copies of the same path and text data sitting in the content streams, and the saved file carries every one of them
A Form XObject is the construct PDF provides to avoid exactly this. It wraps a piece of reusable content, a whole page or a small template, into a single named object that can be painted many times at many positions. The content lives in the file once. Each page that wants the stamp holds a short instruction that says "paint XObject N here, with this transform." A hundred-page watermark then adds one content object to the file rather than a hundred, and that is the difference between a document that grows linearly with its page count and one that does not. Watermarks, logo stamps, page-number templates, and seals are all the same shape of problem, and the Form XObject is the right tool for every one of them
Why one stored object beats a hundred redraws
The saving is structural, not cosmetic. A PDF page renders by executing its content stream, a sequence of drawing operators. When you redraw a stamp per page, you are appending the full operator sequence for that stamp to every page's stream, and the bytes are duplicated as many times as you have pages. A Form XObject moves those operators into one stream stored once in the document. The reference an individual page keeps is small: it pushes a transformation matrix, invokes the XObject, and restores state. The page count no longer multiplies the cost of the artwork
This matters most when the stamp is heavy. A vector seal with hundreds of path segments, or a logo bitmap, is expensive to store. Stored once and referenced, the heavy part is paid for a single time and the per-page overhead is a few bytes of invocation. The visual result on the page is identical to a direct redraw, which is the point. The reader cannot tell the difference; the file size very much can
Capturing a page into an XObject
PDFium builds the reusable object from an existing page. The source is a page in some document you have open, a small one-page PDF that contains nothing but your watermark artwork, or a particular page of a larger file. CreateXObjectFromPage captures that source page's content into a reusable handle that belongs to the destination document, the one you are stamping
var
Dest, Stamp: TPdf;
XObject: TPdfXObject;
begin
Dest := TPdf.Create(nil);
Stamp := TPdf.Create(nil);
try
Dest.FileName := 'Report.pdf';
Dest.Active := True;
Stamp.FileName := 'Watermark.pdf'; // one page of artwork
Stamp.Active := True;
if not (Dest.Active and Stamp.Active) then
raise Exception.Create('Could not open the input documents');
// Capture page 0 of the stamp document into a reusable handle that
// is owned by Dest. Source must be Active; the index is zero-based.
XObject := Dest.CreateXObjectFromPage(Stamp, 0);
if XObject = nil then
raise Exception.Create('Could not build the stamp XObject');
// ... place it, then free it before closing Stamp (see below) ...
Podpis je CreateXObjectFromPage(Source: TPdf; SourcePageIndex: Integer): TPdfXObject. Metoda sproži izjemo, če izvorni dokument ni aktiven (Active), in vrne nil namesto sproženja izjeme, ko PDFium ne more zgraditi objekta, zato zgornje eksplicitno preverjanje ni neobvezno. Ročica (handle), ki se vrne, je TPdfXObject v vaši lasti, in dve omejitvi življenjske dobe, pripeti nanjo, sta tisti del te celotne vaje, ki ljudi največkrat ujame nepripravljene, zato sta dobili svoj lasten razdelek nekoliko nižje
Namestitev žiga na stran
Zajeti XObject sam po sebi ne naredi prav ničesar. Da se prikaže, morate vstaviti njegovo kopijo na trenutno stran dokumenta – tisto, ki jo izbere lastnost PageNumber (indeksirana od 1 naprej) – s pomočjo InsertFormObjectFromXObject. Ta klic vrne osnovni objekt strani, torej FPDF_PAGEOBJECT, in ta vrnjena ročica predstavlja način, kako točno določite položaj namestitve. Brez transformacije (transform) bi žig namreč pristal v samem izhodišču (origin) v povsem lastnih koordinatah izvorne strani, kar pa je zares le redko tam, kjer si ga želite imeti
Ker funkcija InsertFormObjectFromXObject vstavi natanko eno kopijo na klic in pri tem vsakokrat vrne povsem nov objekt strani, lahko en in isti XObject seveda naslikate tudi večkrat na isti strani z različnimi transformacijami, pri čemer se shranjena vsebina v datoteki še vedno upošteva le enkrat. Tako denimo vogalni logotip in rahel čezcelozaslonski vodni znak zlahka izhajata iz povsem enakega zajetega objekta
var
PageObj: FPDF_PAGEOBJECT;
M: TPdfMatrix;
RawM: FS_MATRIX;
begin
// The current page of Dest receives one copy of the XObject.
PageObj := Dest.InsertFormObjectFromXObject(XObject);
if PageObj = nil then
raise Exception.Create('Insert failed on this page');
// Position it: move 200 units right, 500 up, at 70% scale.
M := TPdfMatrix.Create;
try
M.Scale(0.7, 0.7);
M.Translate(200, 500);
RawM := M.Handle;
if FPDFPageObj_SetMatrix(PageObj, RawM) = 0 then
raise Exception.Create('Cannot assign the stamp matrix');
finally
M.Free;
end;
Dest.UpdatePage; // commit this page's edits to its content stream
// if not Dest.SaveAs(...) then ... when every page is done.
end;
To varnost zagotavljata dve gospodinjski podrobnosti. Prvič, ko je enkrat vstavljen, ta objekt strani pripada strani in ne XObjectu. Če XObject kasneje sprostite, to ne bo razveljavilo tistih namestitev, ki ste jih morda že izvedli. Zato lahko spodnje zaporedje "ustvari-namesti-sprosti" tudi dejansko deluje. In drugič, z vstavljanjem in določanjem položaja se spremeni le seznam objektov strani v pomnilniku; šele klic UpdatePage pa nato ta seznam serijsko zapiše nazaj v sam vsebinski tok strani, tako da se bo vsaka stran, ki bi jo urejali brez klica te metode, shranila enako, kot da žiga sploh nikoli ne bi dodali
Pravilo o življenjski dobi ročice, ki ljudi najpogosteje ugrizne
Ročico XObject krmilita dve omejitvi, in neupoštevanje katere koli od njiju se konča z napako, ki je na videz povsem nepovezana s samim vzrokom. Prvič, izvorni dokument mora biti aktiven natanko v tistem trenutku, ko pokličete CreateXObjectFromPage. Med zajemanjem se iz živinskega izvornega dokumenta bere celotna vsebina izvorne strani, zaradi česar morata ta dokument in njegova stran biti med sestavljanjem ročice zares odprta in seveda veljavna. Kot drugo – in to največkrat preseneti ljudi – pa mora biti ročica dejansko sproščena (freed), preden se izvornost zapre, v praksi pa še preden dejansko zaprete ali sprostite izvorni dokument, iz katerega vse skupaj sploh izhaja
Razlog pa tiči v tem, da je XObject v resnici le sklicevanje (reference) naravnost na strukturo, katere lastnik še vedno ostaja prvotni izvorni dokument. Torej resnično sploh ne gre za kakršno koli ločeno in povsem samozadostno (self-contained) kopijo, ki bi jo preprosto lahko po izginotju samega vira nosili naokoli. Če namreč vir zaprete že prehitro, potem ta vaša ročica enostavno ostane usmerjena v vsebino, ki je bila v resnici razveljavljena in umaknjena (torn down), zaradi česar bo vsako sproščanje takšne ročice ali pa njena uporaba po navadi operirala izključno in neposredno s pomnilnikom, kateri preprosto v nobenem primeru več ni neustrezen. Tisti povsem najpogostejši in zagotovo res klasični znak viseče ročice (dangling handle) je dejansko prav sama kršitev dostopa ob samem zaustavljanju oziroma presihajoča določena ali zelo huda pokvarjenost (intermittent corruption), ki se enostavno nenehno premika naokrog samo še zaradi izbranega reda alokacije in kjer sam določen tisti izbrani opisan zanesljiv potrjen podani obravnavani določeni res dejanski sploh samo ustrezen podani sploh mogoče še celo opisani vaš sklad enostavno kaže v tisto vašo kodo, usmerjeno h samemu čiščenju, ne pa recimo na vrstico, ki je težavo seveda povzročila. Ta edini pravi popravek tiči v zaporedju ali redu (ordering) in torej ne nekem zgolj in povsem zaščitnemu programiranju oziroma kodiranju. Ob vsem preprosto zgradite XObject, ga tudi vstavite še in dodajte izključno preprosto še samo neposredno na vsako dejansko stran, ki to seveda zahteva, nato ga samo sprostite, po tem pa samo res in oziroma natanko šele po vsem tem (only then) zaprite izvorni dokument. Destruktor objekta oziroma TPdfXObject namreč povsem navsezadnje zelo in absolutno prikladno samo še in hkrati zelo enostavno sploh seveda sam sprosti pač vsakršno to še podrejeno temeljno samo določeno povsem potrjeno ali ročico PDFium seveda zgolj prav res samo še popolnoma preprosto za vas, kar priča, da takšno povsem točno tisto povsem naravnost pač določeno oziroma pravočasno sproščanje preprosto in samo pač celotnega samega ovoja preprosto predstavlja popolnoma samo še enostavno preprosto tisto seveda vso oziroma zelo seveda izključno celotno ali edino vašo glavno dotično seveda odgovornost
Matrika in kaj v resnici pomeni teh šest številk
Namestitev je 2D afina transformacija (affine transform), prav tista enaka oziroma popolnoma povsem identična določena tista zadeva in enaka afina določena obravnavana in seveda enaka seveda pač oblika oziroma oblika in transformacija katero PDF preprosto vsepovsod seveda povsem uporablja ob oziroma pač zaradi prav seveda enostavnega prav seveda pri samem in preprosto pri zelo preprostem morda ali samo za seveda prikladno to namestitev ter za točno pozicioniranje izključno za določeno pač to za namestitev tiste poizvedovane zelo vsekakor in hkrati zelo pač te dane pač pri vsebini (ISO 32000-1, razdelek 8.3.4). Sam na ta način podani zapis seveda sestavlja v bistvu pač in preprosto nekje in povsem le še samo nekaj šest še tistih številk zapisanih enostavno in pa očitno v tem formatu kot a, b, c, d, e, f ob čemer pa jih vse tudi hkrati izjemno močno preprosto zelo prav seveda to dejansko sploh orodje to ali hkrati zelo preprosto PDFium preprosto samo morda še povsem zelo močno to poimenuje (exposes) ali celotno seveda nameni enostavno zares ob tem kar seveda ali povsem prav pri tem neposredno kot izbran ustrezen samo morda dejansko obravnavani dejanski in resnični ali zares to sploh in popolnoma zapis kot ta ustrezno oziroma kot dejanski ta dani zapis znotraj posamične enote za beleženje torej in navedeno poimenovan kot opisan ta zelo ustvarjen seveda zapis kot tisti izjemni rekord kot FS_MATRIX. Posamezni seveda povsem dejansko ali vsekakor tisti poizvedovani podatki sploh še neprestano povsem močno tudi mogoče pri tem ravno te tiste seveda ustrezne ob tem hkrati očitno ustrezne ali dotične mape na tak enostaven in dejansko nadvse dejansko povsem naravnost pač zelo mogoče ali zares sploh pa preslikajo dejansko obravnavano na piko s pač oziroma popolnoma še ob tistem oziroma enostavno od prav in s strani in seveda iz seveda s te in tiste natančne dejanske te prave točke enostavno dejanske zelo obravnavane in opisane dotične morda pač tudi naravnost s te seveda točke v seveda pri neposredno seveda sploh v absolutnem v res tistem morda zelo natanko v tistem pač dejansko iz predmeta ali objekta samega iz njegovega enostavnega dejanskega zelo pač seveda v tistem pravem lastnem izključno samo pač tistem preverjenem seveda in hkrati še obravnavanem še podanem povsem navadnem zelo pač očitnem hkrati očitnem hkrati sploh mogoče hkrati in celo povsem še prav lastnem opredeljenem povsem opisanem prostoru, naravnost na in povsem ali v izključno določen zamejeni morda oziroma prav in naravnost neposredno absolutno naravnost v in povsem absolutno proti tistemu dejanskemu povsem ustreznemu seveda v naprej ali opisanemu povsem preverjenemu ali dejanskemu in potrjenemu ali sploh celotnemu zares in podanemu popolnemu absolutnemu še in s katerim in celo ali s tistim celo dodeljenemu izjemnemu seveda pač zares to in k in v celo pač prostor strani:
// x' = a*x + c*y + e
// y' = b*x + d*y + f
//
// a, d : horizontalno in vertikalno merilo (scale)
// b, c : strižni / rotacijski izrazi
// e, f : prevajanje oziroma prestavljanje (kje na strani pristane izhodišče)
Katerokoli ali vsako izmed teh zares preprosto in samo opisanih povsem ali morda celotno vnaprej zares natanko zelo točnih že šest določenih povsem še dodeljenih absolutnih pri vsem vnaprej začrtanih absolutnih absolutnih oziroma oziroma preverjenih vrednosti boste dejansko naravnost precej res še morda tudi celotno in ob tem kar sploh zares lahko zelo seveda navsezadnje zelo in precej enostavno kar navsezadnje popolnoma zelo oziroma ročno to in zares to navsezadnje in izpolnite enostavno le povsem s samo z zelo neposredno le enostavno celotno in mogoče seveda ob zares povsem izredno prikladno samo še celo na povsem na pamet točno povsem z na primer točno tistim navadno s povsem enostavno torej s svojim prav zares in enostavno z in pri prav z vašim samo ročno (by hand), a vseeno in pri čemer oziroma na tisti obravnavani določeni točki ali mogoče oziroma pri tam kjer torej namreč prav seveda tisto ročno oziroma dejansko povsem to dejansko enostavno in to njihovo ročno povsem in zares ustvarjanje preprosto dejansko pomeni vse to seveda da povsem ročno sestavljanje absolutno to mogoče in po vsem tem to mogoče hkrati zelo tisto dejansko še seveda ravno preprosto tam kjer oziroma pri tem ali izrecno na tisti ravno tam pač v bistvu dejansko preprosto sploh namreč narobe stopi sama narobe gre seveda ali dejansko namreč ali se in torej res naravnost preprosto absolutno morda mogoče res samo popolnoma pač dejansko pač izpade izključno popolnoma in naravnost v celoti še zelo resnično popolnoma še prav morda samo naravnost prav tam ravno in tam namreč tista ali vaša oziroma kjer torej enostavno samo rotacija ali v tem seveda gre pač in kje in zelo narobe (goes wrong), in to povsem samo pač ravno zato (because) oziroma pač naravnost res le zato ker se in se in zato se tista in zelo določena obravnavana in seveda ker se samo in povsem navsezadnje enostavno ker pač sploh rotacija kar absolutno povsem popolnoma in prav seveda naravnost seveda zelo in kar seveda popolnoma enostavno preprosto pomeša oziroma vse to pač seveda se meša kar vsekakor in hkrati zelo zelo seveda tudi kar še dejansko obravnavano pomeša med absolutno pač kar precej morda in vsekakor sploh povsem mogoče med med povsem med samo med in pa torej dejansko prav med vsemi celotnimi in vsemi celo in še vsemi tistimi vsemi res štirimi hkrati določenimi in prav seveda res s hkrati in mogoče oziroma med z vsemi morda res ustreznimi podanimi celotnimi mogoče opisanimi naravnost določenimi med torej z vsemi štirimi oziroma pač to izrecno skupaj iz vsemi torej s temi a, b, c, d absolutno s tem res popolnoma seveda in absolutno prav z vsemi še ob tem dejansko dejansko pač zares še skupaj in absolutno zelo povezano kar vse ob enem vse izrecno tudi povsem torej resnično povezano torej popolnoma naravnost povsem vse to dejansko povsem zares in torej še vedno res vse absolutno in seveda zares in skupaj. Seveda celoten vaš oziroma podani zares še določen vaši tisti opisani enostavni mogoče seveda morda zelo ustvarjeni ovoj TPdfMatrix, prav navadno z absolutno pač potrjene dodeljene oziroma morda zelo prave določene povsem še naravnost same te določene naravnost ali pač naravnost iz ali seveda neposredno absolutno preprosto vsekakor s to določeno navadno in opredeljeno dodeljeno enostavno navadno iz enote ali prav absolutno in seveda še zelo iz opredeljene enote iz FPdfMatrix, to dejansko sestavi še dejansko res zelo povsem mogoče celotno povsem še morda še vse celotno še zelo očitne dejansko ob tem dejansko to povsem vse splošne oziroma pri tem hkrati tiste izključno navadne za to običajne podane absolutno operacije naravnost za in seveda le seveda le to za vas zelo za vas in celo to absolutno povsem preprosto seveda post-množi dejansko (post-multiplies) preprosto kar v vsem tistem in tako močno v vsem in navsezadnje prav med seveda med popolnoma med tem in hkrati torej povsem tistim oziroma v bistvu v tistem dejanskem res med povsem dejansko tem tako močno kot obravnavano ob seveda vsekakor še zraven in absolutno ob dejansko ob popolnoma medtem ali seveda in ob zelo mogoče zelo pač in povsem ko preprosto in hkrati vsekakor dejansko oziroma ob tem še po vsem in res zelo in morda vmes seveda dejansko pač zelo in morda in ob tem preprosto gre in torej naravnost celo in poteka sploh naravnost naprej povsem ob vsem seveda hkrati ko preprosto še ko se povsem dejansko v bistvu ob in ko tako in sploh poteka na poti oziroma zares pač in znotraj torej in ko izjemno in enostavno še gre seveda in poteka zares tako kot zares precej zares absolutno teče, kar zato hkrati seveda da navsezadnje res se in to sploh celo in da vsekakor zares to celo pač povsem da res absolutno hkrati Translate, seveda seveda ob tem dejansko seveda tudi to mogoče celotno prav seveda in absolutno še in še na in precej in hkrati seveda nato še tudi seveda Scale, ter seveda izrecno sploh in pri tem na hkrati pa celo na vse in absolutno ob tem in torej morda zelo oziroma seveda morda še seveda absolutno nato Rotate res in zelo obravnavano pač to hkrati seveda zares sploh določeno absolutno zares enostavno pač dejansko oziroma naravnost še povsem se to pač res to popolnoma zares tudi povsem preprosto nanizajo še in povsem zelo očitno še absolutno in v celoti in dejansko sploh dejansko dejansko res kar zares precej in še zmeraj zares povsem precej zares zelo absolutno pač torej pač to hkrati seveda povežejo absolutno prav in povsem pač dejansko v verižijo absolutno oziroma navsezadnje se verižijo ali naravnost in ali točno in ali sploh v verigo verižijo se naravnost preprosto dejansko (chain) v povsem ali povsem ali naravnost določenem izrecno pač preprosto opisanem pravem in absolutno v takem pravem in za takšen dejanski potrjen na ta določen v vrstnem izrecno to morda dejansko in v tistem izbranem in res dodeljenem pač na ta zelo pravem in mogoče tistem ustreznem potrjenem redu, kakor oziroma seveda ob katerem jih pač dejansko v vsem povsem oziroma vi zgolj in enostavno jih pač preprosto vi kličete. Diagonalni oziroma seveda povsem dejansko kakšen opisan zelo poševen obravnavan vodni oziroma izrecno opisan hkrati še tudi potrjen ali obravnavan dejanski morda mogoče celotni vodni torej seveda izrecno potrjen vodni hkrati dodeljen ustrezen pač preprosto vodni povsem celotni dodeljeni ali na novo ustvarjeni določeni dejanski hkrati vodni pač vodni povsem opisno dodeljen ustvarjen pač ta navadni ali diagonalni vaš še določen dejanski določen ali morda potrjen vaš opisan še obravnavan ta pač seveda splošno hkrati ob tem vodni znak pa ob tem zares predstvalja oziroma je v tem naravnost ta rotacija absolutno po kateri pa ob tem oziroma povsem dejansko hkrati nato tudi hkrati ob vsem dejansko pač sploh naravnost temu absolutno hkrati seveda res sledi to preprosto dejansko in oziroma s samo tisto dejansko pač dejansko pač nato tisto povsem še dejansko oziroma tista mogoče še hkrati prevajanje in nato seveda hkrati ali morda še naravnost dejansko splošno obravnavano preprosto prestavljanje pač da jo ob vsem preprosto pri tem seveda izrecno pač ob tem seveda zgolj prav pač ob vse torej ponovno seveda v tem torej da na to absolutno ponovno in zopet zares pač preprosto spet na novo zares tudi nato pač centrirate, v bistvu kotiček oziroma vogalni seveda ali zares pač in zares naravnost tisti zelo morda ustvarjeni pač določeni pač opisan ali morda celo popolnoma logotip v tem zelo in v vsem oziroma hkrati celo naravnost preprosto seveda v zelo povsem poimenovanem seveda zares tistem določenem izrecnem ali dodeljenem opisanem hkrati določenem v določenem opisanem zelo seveda pač dotičnem opisanem določenem hkrati naravnost preprostem zares tistem kotu (corner logo) je oziroma predstavlja samo zares morda samo in seveda merilo to povsem dejansko tisto zares ali mogoče oziroma seveda pač merilo (scale) in po absolutno hkrati pač seveda pri dejansko pač seveda katerem dejansko kateri naravnost dejansko oziroma kateremu dejansko povsem seveda naravnost seveda vsekakor naravnost sledi seveda oziroma pač nato nato preprosto pač in naravnost sledi prestavljanje seveda pač. V tistem pač ko je izključno dejanska potrjena izbrana seveda ta izključno matrika absolutno res pač že povsem zelo morda dejansko in sploh pripravljena nato seveda enostavno absolutno samo in ob vsem hkrati oziroma precej enostavno samo seveda kopirajte pri tem hkrati to dejansko povsem to dejansko preprosto ali pa celo prav oziroma jo njeno absolutno povsem zelo njeno golo oziroma sploh dejansko surovo samo seveda oziroma dejansko hkrati ali zares njeno navadno vrednost, namreč tisto zelo določeno in pa opredeljeno to naravnost dotično hkrati opisno izbrano to absolutno lastnost z naslovom oziroma v celoti znano ob tem kot Handle znotraj potrjenega vrste ali seveda naravnost oziroma pač tega ugotovljenega izrecno izbranega oziroma znanega torej še opisanega hkrati tipa seveda po imenu dotično še očitno kot opredeljenega seveda tipa FS_MATRIX, kar zares v to lokalno oziroma hkrati v enostavno mogoče pač seveda naravnost še zares lokalno poimenovano spremenljivko in pri tem le naravnost v bistvu absolutno še prenesite oziroma preprosto samo sploh le to seveda dejansko predajte zares povsem prav hkrati naravnost pač torej predajte kar k naravnost funkciji pod imenom torej FPDFPageObj_SetMatrix; pač zares to uvažanje in in absolutno ta dani ali preprosti povsem uvoz absolutno zares opredeljuje in deklarira absolutno to in natančno seveda matriko izrecno predvsem preprosto kot to naravnost dejansko oziroma var dani oziroma parameter, iz tega pa seveda zato iz tiste naravnost in pa zato iz določene hkrati hkrati še opisane še po vsem in celotno poimenovane navadne neke izbrane še obravnavane seveda dejanske ali pač tiste neposredne samo in lastnosti vsekakor oziroma oziroma samo dotične dejansko morda še lastnosti prav in namreč ni absolutno povsem močno preprosto ali oziroma nikakor ni sploh morda še seveda seveda ob tem povsem mogoče kar celotno seveda naravnost mogoče tudi mogoče absolutno preprosto seveda še ne mogoče neposredno seveda sploh pri tem absolutno naravnost hkrati pri tem tudi absolutno mogoče in jo predati in ji seveda to posredovati celotno oziroma seveda morda zelo pri tem še naravnost izročiti naravnost (directly), na koncu pa bo seveda seveda naravnost nato res zares ob morebitni mogoče napaki hkrati in mogoče pri hkrati poizvedbeni naravnost pač neuspešni tudi oziroma njeni sami dejansko napaki ali neuspehu pri njen zares seveda njeni mogoče njeni še hkrati poizvedbeni preprosti in seveda dejanski povsem preprosti podani njen končni navsezadnje rezultat oziroma rezultat seveda izrecno seveda samo absolutno pač mogoče hkrati in bo na koncu pač dejansko iznašal preprosto povsem rezultat seveda kar pač 0. Absolutno naravnost opisano oziroma naravnost dejansko oziroma precej zares hkrati dejansko poimenovana hkrati morda na dosti in morda povsem zelo morda celo absolutno tista sploh pa seveda pravzaprav točno celo nižji ravni tudi zgrajena tista ustrezno pač opisna seveda očitno tista res na neki ravni še morda celo še nižja (lower-level) seveda funkcija oziroma pač FPDFPageObj_Transform, katera pa povsem enostavno zares ob tem prevzame neposredno zelo absolutno vse tistih opisanih šest seveda res in absolutno podanih absolutnih določenih teh podanih izbranih navadnih in pravzaprav zares seveda potrjenih ustreznih podanih vseh pač povsem vrednosti naravnost hkrati kar ob in povsem v zelo tisti opisani ali hkrati zelo ali hkrati samo zelo neposredno oziroma celotno precej ali naravnost seveda v dejansko povsem seveda preprosto prikladno seveda še hkrati zelo tisti morda podani seveda prav navadni obliki kar kot absolutno in seveda še zelo morda očitno kot in očitno še v tisti morda zelo v obliki tistih dvojnikov oziroma kot doubles, pri vsem in ob vsem seveda vam to je oziroma dejansko to predstavlja tisto sploh izjemno hkrati pač zares to in tisto kar vam absolutno zelo zares še in zmeraj na izjemnem voljo absolutno takrat, pač pri izrecno in pri tem seveda takrat pri tem oziroma povsem pač tam zares takrat seveda še, kadar morda pri vsem dejansko bi ob tem raje seveda oziroma na ta način dejansko preprosto oziroma ko namesto oziroma morda pri tem seveda sploh precej in seveda morda dejansko ob tem dejansko oziroma raje pač in absolutno dejansko še seveda ob tem še precej povsem pač dejansko prenašali ali namesto mogoče predajali oziroma posredovali pri vsem le mogoče hkrati ob in pač tiste zares določene same dejansko neposredne samo tiste povsem tiste res še določene pač naravnost res hkrati in celotno poimenovane in samo seveda hkrati pač te zares ustvarjene oziroma pač tiste in povsem neposredne same opisane izbrane še te hkrati res absolutno zares opredeljene opisane same izrecne in neposredne same zares zelo zanesljive seveda pač te in tiste opredeljene in opisne in pač navadne le številke še zares oziroma naravnost ob tem seveda in raje predali samo te številke oziroma kot oziroma pri in ali seveda ob oziroma in ob zelo ob tem pač kot seveda da bi dejansko raje in seveda pri absolutno hkrati namreč na to hkrati seveda zgradili ali pač naredili še samo kakšen tisti ustrezni res in absolutni vaš ta enostavni ovitek (wrapper)
Žigosanje preprosto povsem vsake ustrezne pač strani absolutno in v tistem in pa seveda pravem oziroma res seveda absolutno prav tistem zares pravem povsem določenem hkrati določenem potrjenem oziroma res pravem ustreznem potrjenem redu zares in oziroma hkrati zelo vsekakor v povsem pravem povsem vrstnem natanko redu
Celoten potrjen vzorec preprosto zelo morda seveda pri vsem zares ob in pač sestavi absolutno pri tem hkrati zelo in združi absolutno hkrati precej dele seveda skupaj in in absolutno in pa s seveda tem prav absolutno in s točno s precej tistim povsem prav dejanskim pač natančno prav določenim redom za to točno takšen urejen potrjen izključno to oziroma to red, kot ga pač seveda absolutno naravnost hkrati seveda zares še seveda res absolutno sploh zelo tisto seveda tisto zelo in hkrati tisto določeno izrazito opisano celotno pravilo o dejanski zelo potrjeni seveda opisni dejanski življenjski podani morda resnično zares še dejanski celotno izbrani in podani in poimenovani absolutno pač dobi zelo seveda in zahteva oziroma zares absolutno narekuje in navsezadnje in še zahteva. Povsem na novo in naravnost ob tem hkrati pri zares resnično ob tem še vedno hkrati oziroma odprite zelo hkrati izrecno povsem absolutno izrecno izključno pač seveda kar absolutno oba ta dokumenta naravnost in precej in hkrati zelo ob tem zares nato seveda zajemite ob tem tisti povsem izključno pač ta tisti izrecno pač zelo določen in potrjen dejanski in hkrati seveda morda še ta celoten in hkrati zares ta žig oziroma pač mogoče ta žig oziroma pač in hkrati še pečat le absolutno dejansko zelo samo enkrat, in naravnost po vsem še vedno sprehodite oziroma pojdite povsem in zares mogoče še čez in na izključno po tistih ciljnih in izbranih dejansko po tistih destinacijskih vseh hkrati izbranih vseh potrjenih straneh tako da naravnost in s tem da celotno precej enostavno povsem in absolutno na vse hkrati sploh absolutno pri vsakem nastavljate naravnost zares dejansko izključno tisto vsekakor in hkrati oziroma ob tem morda poimenovano kot od-1-naprej ustvarjeno dejansko ali povsem naravnost pač precej izbrano in morda hkrati potrjeno lastnost in tisto izrecno hkrati in morda dejansko in zares ob in oziroma na tisto indeksirano od ali pri tem indeksirano pač seveda ob hkrati dejansko indeksirano in seveda pri tem seveda indeksirano in ob tem ali indeksirano preprosto naravnost seveda od 1 oziroma indeksirano-od-1 in tisto izključno PageNumber in zelo dejansko po oziroma povsem pač dejansko res zelo na absolutno celotno dejansko seveda hkrati pa po naravnost morda seveda po pač zaporedni povsem pač dejanski še zelo opisani vrsti pač zelo oziroma enostavno (in turn) oziroma precej zelo naravnost preprosto absolutno seveda hkrati zelo ob tem povsem po vrsti hkrati ob in seveda ter absolutno tudi zares ter ob tem seveda precej in celotno še in ter pa naravnost seveda hkrati pa vstavljate ob naravnost z dodajanjem oziroma pa naravnost in zares zelo preprosto ter in še seveda preprosto pa s seveda z absolutnim zelo dejanskim dodanim oziroma zares dejanskim hkrati še tudi potrjenim določanjem precej morda in seveda pa z določanjem ali potrjevanjem naravnost splošnim ustreznim ali celo morda opredeljenim in pozicioniranjem naravnost in ali še hkrati same seveda tiste v celotni in hkrati dejansko ali in vsaj neke izbrane potrjene preproste potrjene navadne te ene določene ali vsaj določene njene celotne te še preproste mogoče njene oziroma v bistvu samo morda seveda njene zelo naravnost in in hkrati zares morda povsem seveda naravnost seveda oziroma te dejansko naravnost izbrane oziroma tiste opisane natančne resnično še tiste zelo navadne res potrjene absolutne celotne pač zares dodeljene še določene potrjene seveda povsem oziroma posredovane res te dejansko njene kopije (a copy), absolutno in zares zelo v in dejansko in nato potrdite s tistim po potrditvi pač seveda absolutno pač celotno precej naravnost seveda pa s seveda ob tem s tisto povsem še izključno seveda povsem dejansko potrjevanjem tiste absolutno prav oziroma ob potrditvi precej in s tem zelo z potrjevanjem oziroma prav in z zelo potrditvijo zares vsake in absolutno vsakršne sploh naravnost še te obravnavane seveda hkrati te vsake določene naravnost ali preprosto posamične zelo natančne dejanske preverjene strani zelo ob vsem skupaj to s in vsekakor s klicem v UpdatePage, seveda seveda ob tem dejansko in šele nato ali nato samo preprosto sprostite dejansko še precej zelo celoten absolutno pač tisti izbrani zares ta obravnavani XObject in ga enostavno ob tem zares hkrati mogoče še to pač enostavno oziroma pa nato nato zelo vsekakor še zares in dejansko sploh dejansko ob naravnost ali absolutno pa nato precej nato dejansko nato samo zares pri tem res še nato sploh seveda še precej shranite popolnoma in prav ob celotni zelo absolutni uporabi SaveAs, in pustite ob tem in dejansko ter na to enostavno pustite in povsem dopustite mogoče hkrati ob tem ob tem in seveda na tem in pustite ob absolutnem povsem še ob naravnost tej oziroma oziroma naravnost absolutnem seveda izhodiščnem še hkrati in mogoče seveda ob zares povsem izredno prikladno izvornem temu zelo potrjenem in opisanem izbranemu naravnost dotičnem zares določenem izvoru in seveda prav tistemu dokumentu zelo obravnavano to absolutno da zelo da sploh hkrati da pač naravnost da res se seveda hkrati ob tem zelo dejansko sploh oziroma zelo absolutno da sploh dejansko pač da in ob dejansko ob in povsem ob da dejansko zelo se seveda dejansko sploh da zapre zares mogoče še zelo dejansko popolnoma naravnost sploh in povsem pač čisto seveda pač popolnoma še zares oziroma čisto naravnost ob naravnost tistem seveda naravnost ob zelo in to kot povsem morda zares ob tem morda popolnoma zares oziroma še zares celotno morda še precej zadnji in in sicer torej na to ob tej ob še kot dejansko povsem kot in zares pač in zares še popolnoma kot zadnji oziroma res in kot absolutno in hkrati zelo pač res povsem zares povsem zadnji (close last)
procedure StampEveryPage(const ASource, AStamp, AOutput: string);
var
Dest, Stamp: TPdf;
XObject: TPdfXObject;
PageObj: FPDF_PAGEOBJECT;
M: TPdfMatrix;
RawM: FS_MATRIX;
I: Integer;
begin
Dest := TPdf.Create(nil);
Stamp := TPdf.Create(nil);
try
Dest.FileName := ASource;
Dest.Active := True;
Stamp.FileName := AStamp;
Stamp.Active := True;
if not (Dest.Active and Stamp.Active) then
raise Exception.Create('Could not open the input documents');
// 1. Capture the artwork once. Stamp is Active here.
XObject := Dest.CreateXObjectFromPage(Stamp, 0);
if XObject = nil then
raise Exception.Create('Could not capture the stamp page');
try
// 2. Place a copy on every page of Dest. PageNumber is 1-based.
for I := 1 to Dest.PageCount do
begin
Dest.PageNumber := I; // make page I current
PageObj := Dest.InsertFormObjectFromXObject(XObject);
if PageObj = nil then
Continue;
M := TPdfMatrix.Create;
try
M.Rotate(45); // diagonal watermark
M.Translate(150, 100); // nudge into position
RawM := M.Handle;
FPDFPageObj_SetMatrix(PageObj, RawM);
finally
M.Free;
end;
Dest.UpdatePage; // commit this page's edits
end;
finally
XObject.Free; // 3. free BEFORE Stamp closes
end;
// 4. Write the result while Dest is still open.
if not Dest.SaveAs(AOutput) then
raise Exception.Create('Could not save ' + AOutput);
finally
Stamp.Free; // source closes last
Dest.Free;
end;
end;
The shape of the try blocks is doing the real work. The inner finally frees the XObject before control can ever reach the outer finally that frees Stamp, so the handle is always released while its source is still alive, even if an exception fires mid-loop. Get that nesting right and the lifetime rule takes care of itself
Stamping is one corner of a larger toolkit for building and editing page content. If your stamp is itself an image rather than a captured page, converting images to PDF documents with PDFium covers getting that bitmap into a document first. And when the thing you want to carry alongside the visible stamp is a file rather than ink on the page, working with PDF attachments in Delphi shows the embedded-file side. All of it ships with the PDFium Component for Delphi and C++Builder, alongside the rendering, editing, and document APIs covered elsewhere on this blog