Tehnični članak

Merjenje PDF besedila za postavitev in prelom besed v Delphiju

Klic, ki postavi besedilo na PDF stran, je povsem neposreden. Metodi AddText preprosto posredujete niz, pisavo, velikost in pa lokacijo, in glifi (glyphs) se pojavijo. Kar pa ob tem seveda ne stori, je to, da vam ne pove, kako širok bo zares ta niz, ko bo enkrat narisan, prav tako pa ne bo razdelil dolgega niza na več vrstic. En sam klic nariše en potek (run) besedila na neki določeni lokaciji. V primeru, da je ta potek širši od samega stolpca, v katerega ste ga želeli spraviti, ta preprosto zdrsne čez rob in čisto nič v tem risalnem klicu vas ne bo opozorilo. V trenutku, ko zares želite celoten odstavek namesto zgolj ene same oznake (label), je manjkajoči del sestavljanke širina niza v izbrani pisavi ter velikosti, merjena pa mora biti, še preden jo zares odložite na stran

To je klasičen problem postavitve. Če želite zaviti odstavek naravnost v stolpec, morate pač poznati, povsem besedo za besedo, koliko točno horizontalnega prostora bo posamezna potencialna vrstica sploh vzela, to pa seveda morate vedeti, še preden se karkoli nariše. Prelom besed (word wrap) je pravzaprav samo merilna zanka (measurement loop), povsem ovita okoli risalnega klica, in vezava, ki le riše, vam tako daje samo tisto drugo polovico. Podpora za merjenje besedila v komponenti PDFium povsem zapre tisto vrzel in to s pomočjo dveh funkcij, MeasureText in pa MeasureTextWidth, ki poročata o samem narisanem obsegu niza (rendered extent of a string), ne da bi ob tem na kateri koli strani pustili zgolj kakršno koli oznako

Zakaj je merjenje v resnici razredni pomočnik (class helper) in ne nova metoda na TPdf

Podpora za merjenje pride na voljo kot Delphi razredni pomočnik (class helper) za TPdf in živi znotraj povsem lastne enote (unit), ne pa v obliki popolnoma novih metod, preprosto privitih na razred TPdf. Razredni pomočnik je značilnost jezika, ki vam omogoča, da poljubno pripnete metode na nek povsem obstoječ tip od zunaj, torej izven njegove same deklaracije. Takoj ko bo enota v dosegu (in scope), bodo seveda nove metode poklicane na točno takšen način, kot če bi bile del samega razreda, zato se metoda pomočnika bere preprosto kot Pdf.MeasureTextWidth(...) in to brez kakršnega koli ločenega objekta, ki bi ga bilo treba šele zgraditi in morda posredovati naprej

Razlog za takšno strukturiranje po plasteh tiči v ločevanju (separation). Samo jedro tipa TPdf ostane povsem nespremenjeno in točno takšno, kot je: z nobenim dodanim poljem ter z nobenim dotikanjem obstoječega podpisa (signature), kar pomeni, da nek projekt, ki ne potrebuje postavitve, pač preprosto ne bo imel zraven tiste kode, namenjene za merjenje. Projekt, ki pa tovrstno funkcionalnost dejansko potrebuje, pa doda samo eno enoto k stavku uses in vse te metode preprosto zasvetijo. Zmožnost tako res postane povsem prostovoljna odločitev (opt-in) prav na granulaciji posamezne enote, kar je zagotovo tudi tisti najbolj čist način za razširitev nečesa, česar sicer niste lastnik ali pa nečesa, česar sploh ne želite zmotiti

uses
  PDFium, FPdfView, FPdfEdit,
  FPdfMeasure;   // the helper unit; brings MeasureText into scope on TPdf

// With the unit in scope the methods read as members of TPdf:
var
  W, H: Double;
begin
  Pdf.MeasureText('Subtotal', 'Helvetica', 11, W, H);
  // W and H are now the rendered width and height in PDF user units
end;

Merjenje, ne da bi se pri tem sploh dotaknili strani

Merjenje pa enostavno ne sme imeti niti najmanjših stranskih učinkov (side effects). Porocati nam mora o širini, vendar brez da bi karkoli pustilo za sabo, ker ga med samim določanjem postavitve pokličete resnično velikokrat in seveda mora na koncu stran izgledati povsem isto, kot da sploh ne bi še nič merili. Sama tehnika, ki vam to zares sploh omogoča, je, da enostavno zgradite samo tekstovni objekt (text object), ga povprašate o njegovi velikosti in nato pač zavržete, še preden sploh pomislite na to, da bi bil sploh kakorkoli pritrjen na stran

To zaporedje (sequence) predstavlja štiri PDFium klice. FPDFPageObj_NewTextObj dejansko ustvari takšen tekstovni objekt proti dokumentu ob predpostavki, da imamo na voljo podano ime pisave in pa seveda njeno velikost. Klic FPDFText_SetText določi niz, ki ga ustvarjeni objekt sploh nosi s sabo. Naslednji klic, to je seveda FPDFPageObj_GetBounds, nam prebere mejno okence (bounding box) našega objekta, nato pa ga z meto FPDFPageObj_Destroy le še sprostimo (frees the object). Tukaj je tudi zelo pomembno poudariti to, da čisto noben klic v tem kratkem zaporedju niti ne pokliče API-ja za vstavljanje na stran. Naš objekt je dejansko ustvarjen, poizvedovan (queried) in nato povsem uničen izključno v sami izolaciji in je posledično zato na koncu dokument povsem nespremenjen ob vračanju funkcije. Na kratko povedano gre samo za sondo, namenjeno enkratni uporabi, ki bo na koncu vrnila samo te izhodne podatke: tiste štiri ustrezne številke, iz katere pač izvira mejno okence

Tole je seveda zares robusten in zanesljiv način, predvsem zato, ker noben del orodja PDFium sploh ne prikazuje še tiste tako imenovane ugodne širine predujma za sam glif (per-glyph advance width), ki bi pa to dejansko lahko izpeljala tudi sama, vendar tega pri tem sam ne podpira, ne vsaj v neki priročni vnaprej določeni formi. Meritve v resnici še vedno slonijo izključno in samo na samem programu, iz katerega glif črpa, poleg seveda same pisave še vedno upoštevajo seveda tudi izbrano kodiranje (encoding), nato pa so odvisne tudi od tega, kakšen prijem bo izbral in v kakšni natančno obliki sploh bo knjižnica PDFium ta sam obris obraza prebrala (loads the face), ob čemer sploh tudi nimamo na razpolago zunanjega javnega klica, ki bo seveda izročil vse to za vsak posamezni znak iz niza. Mejno okence (bounding box) v zares resničnem tekstovnem objektu bo na drugi strani s povsem identično mašinerijo, s tisto povsem isto zgradbo izračunal ta program (machinery), ki se navsezadnje enostavno potem vedno ukvarja z vsemi temi risalnimi glifi (glyphs) v dokumentu in s tem v resnici predstavlja tisti čisto pristni ustvarjeni obseg (rendered extent) za razliko od kakšnih približkov. Posledično gradnja le samo enega takega tekstovnega predmeta in njegovo pridobivanje mej, na katere sploh sega ta meritev, predstavlja najbolj smiselno razpolaganje s to knjižnico in je tako daleč najbolj zanesljiva meritev

// The shape of MeasureText, expressed against the verified PDFium calls.
// A text object is built, measured, and destroyed; no page is involved.
procedure TPdfMeasureHelper.MeasureText(const Text, Font: WString;
  FontSize: Single; out Width, Height: Double);
var
  TextObject: FPDF_PAGEOBJECT;
  L, B, R, T: Single;
begin
  Width  := 0;
  Height := 0;
  if Self.Document = nil then
    Exit;
  TextObject := FPDFPageObj_NewTextObj(Self.Document,
    FPDF_BYTESTRING(AnsiString(Font)), FontSize);
  if TextObject = nil then
    Exit;
  try
    if FPDFText_SetText(TextObject, FPDF_WIDESTRING(WideString(Text))) = 0 then
      Exit;
    if FPDFPageObj_GetBounds(TextObject, L, B, R, T) <> 0 then
    begin
      Width  := R - L;
      Height := T - B;
    end;
  finally
    FPDFPageObj_Destroy(TextObject);   // probe discarded, page untouched
  end;
end;

Koordinate in enote rezultata

Mejno okence se vrne kot štirje robovi, se pravi levi, spodnji, desni in pa zgornji, nato pa obe dimenziji izpadeta s preprostim odštevanjem. Širina je torej desna minus leva, višina pa zgornja minus spodnja. Obe izmed njiju sta seveda izraženi v PDF uporabniških enotah (user units), pri katerih se ena sama enota pretvori v natanko eno dvainsedemdesetinko palca (one seventy-second of an inch), kar pravzaprav predstavlja popolnoma identičen koordinatni prostor, kot je ta, s pomočjo katerega tekst preprosto postavite nekam na stran. V tej sami fazi pri tem ne obstaja čisto nobena skrita enota naprave (device unit) in absolutno noben piksel. Širina natanko 36 pri tem seveda pomeni pol palca (half an inch) same strani, kar pa niti malo ne vpliva na tisto končno upodobljeno ločljivost (rendering resolution)

Vertikalna os poteka povsem enako, kot to sploh opredeljuje že sam PDF, torej z osjo Y, ki pa se močno viša ob vzpenjanju, in ravno zaradi tega se zmeraj izračuna višina enako zgornja stran minus spodnja, ne pa ravno obratno. Ta majhen detajl pride še kako prav predvsem takrat, ko kazalec (cursor) usmerite in povlečete nekam dol po samem stolpcu. Najprej namreč izmerite natančno višino vrstice, nato pa slednjo odštejete od trenutne osnovne črte (baseline), če sploh želite najti naslednjo, to pa zato, ker pomik navzdol po strani v osnovi pomeni dejansko pomikanje proti precej manjšemu Y. Če bo na koncu vaš izhod res ekran in ne nek določen papir, samo še pretvorite uporabniške enote v slikovne pike same naprave z ločljivostjo ekrana: če vrednost, merjeno v uporabniških enotah, pač pomnožite z DPI in delite z 72, to povsem naravno vrne točno številko slikovnih pik in ravno zaradi tega lahko širino vašega stolpca, določeno seveda v točkah, povsem smiselno prilagodite izmerjenemu poteku (measured run), preden se pač dokončno sploh sploh odločite, kam natančno želite tisti svoj dotični premor postaviti (where the break goes)

Kaj se zgodi pri izrojeni (degenerate) vhodni vrednosti

Same funkcije so preprosto napisane za zelo tiho odpoved (fail quietly). Če pred sabo nimamo nekega povsem odprtega dokumenta ali v primeru, ko ustvarjanje samega tekstovnega objekta sploh ni izvedljivo, je na koncu ta rezultat obsega enak vrednosti nič v primerjavi s proženjem same izjeme (raised exception). Širina in višina sta že takoj na vrhu preprosto inicializirani s tisto nulto vrednostjo in pa bosta prepisani izključno po tem, ko je bilo okence (bounding box) po branju vendarle uspešno sprejeto. Povsem in izključno prazen niz (empty string), seveda še celo povsem manjkajoč dokument ali recimo pač določena pisava, s katero knjižnica nikakor sploh ne more pretvoriti zadeve v ustrezen objekt, vsak od teh primerov enostavno in nepreklicno povrne nič namesto samega metanja exception (throwing)

Tovrstna zares odločna odločitev ohranja zanko, na kateri je sploh temeljila celotna zasnova tega merjenja (measurement loop), precej preprosto, ker sama zanka, ki enostavno teče prek vsaj recimo nekaj tisoč besed vsekakor sploh ne služi zares kakršni koli obravnavi določene izjeme pri res vsaki nadaljnji oziroma povsem zaporedni iteraciji. Tisti davek ob vsej tej zadevi je predvsem v tem, da ravno ob tem potem vsak, ki bo sploh zagnal ta dotični preizkus (caller), prevzame tudi preverjanje samo po sebi (check). Širina, katere povratna vrednost je točno enaka nič, je pač v tem primeru zgolj samo tista osnovna nadzorna enota, na koncu koncev torej ne dejstvo v povezavi s samim tekstom, zato seveda se mora potem celo tista koda, za katero stoji recimo deljenje s pridobljeno in seveda pač izmerjeno osnovno širino (measured width) ali koda, za katero pač sledi predpostavka na samo eno zares strogo pozitivno številko enostavno prav sama zares dosledno zaščititi in sploh obvarovati pred vsakršno to vrednostjo poimenovano kot čista nič, še vse preden sploh lahko popolnoma in celo zanesljivo zaupa vsakršni njeni potrjeni pravilnosti. Preprosto torej ravnajte in jemljite čisto vsako vrednost nič točno kot nekaj "nemerljivega" oziroma "česar se absolutno nikakor nismo mogli sploh kakorkoli lotiti ali dotakniti merjenja" (could not measure) in šele ravno ob upoštevanju le-tega vsaka pogodba, ki sploh zares sledi ob vsem tem, pač prikliče tudi tiste povsem prepoznavno jasne opredelitve, če boste v nasprotnem primeru seveda vse te točno določene posredovane predhodne pogoje kakorkoli vsaj za trenutek ali kakorkoli drugače že morda malce zanemarili, nato v končni posledici bo seveda na koncu vaš celotni zagon vsekakor prinesel kakšno docela povsem izrojeno in izkrivljeno posredovano oziroma dano izhodiščno vrsto vhodnih podatkov (degenerate input), ki sčasoma tudi celo prav neizmerno neopazno prerase in preide celo popolnoma v obliko postavitve pri kateri lahko enostavno naletite sploh še pri tako zelo majhnih stvareh kot ob samem pregledu ustreznosti stolpca seveda sestavljenega ravno in seveda celo tudi seveda seveda ob kakršnemkoli prekrivanju pač tistih risalnih oznak glifov (overlapping glyphs)

Požrešen prelom besed (greedy word wrap), zgrajen na merjenju

Če pa seveda že zares razpolagate celo z dotično funkcijo in z ustrezno njeno zares popolno funkcionalnostjo glede pridobivanja in opredeljevanja prave in določene in merljive natančne širine same, na takem dejanskem primeru sam postopek povsem enostavnega pač osnovnega preloma v vrstico besed predstavlja le eno izjemno zelo močno pa tudi seveda kratko in požrešno zanko (greedy loop). Odstavek preprosto razdelite natanko v same enostavne besede posamično eno za drugo ločeno, poleg si nekje hranite neko shranjeno vrednost kot tisto ustrezno dejansko dano začrtano sedaj trenutno prikazovano in izpisano vrstico besed, in nato le še sproti postopoma oziroma sukcesivno v rednem zamiku posamezno torej s tem povsem enostavno torej po vsakokratni posamični preverjeni besedi sami pač zgolj ugotovite na precej analogen merljiv pristop vsakršen določen povsem preverjen zares enostaven prirastek ob tem kako res veliko in zajetno bi zares bila ta preverjana podana podaljšana obravnavana in izmerjena dolga na primer celotna vrstica ob dejanski tisti zelo povsem vnaprej izvedeni seveda zelo dejanski ustrezno privzeti ali drugače zastavljeni priključitvi (appended) ravno in prav tiste same ene posamične specifično seveda pač tiste prav predvidene in povsem točne obravnavane točno na novo enostavno pač pridane izpisane točno dodeljene besede z izčrpno vrednostjo in pa ob tem seveda vse izjemno točne danosti. In pa povsem logično in sčasoma dejansko ob še tistem zelo neizmerno zelo samem posamičnem nadaljnjem ponavljajočem dodajanju in pritrjevanju (keep adding) sploh še vedno dokler bo na ta način vsakokrat ta povsem samo zgolj pač poizkusna še povsem pač preizkušana osnovna opredeljena probna ravno dejanska nova vnovič zamejena prav opredeljena trenutno poizvedovana vrstica sama pač vsaj na kakršen koli poskusno in potrjeno morda še vseeno in vseeno nekako preprečevala da preprosto samo mogoče po nekem dejansko pač izključno še precejšnjem morda ustreznem poteku tudi morda še vedno popolnoma in prav seveda uspešno zelo pristajala (fits) na res natančno z vso povsem enako predhodno res že obravnavano merljivo točno pač dano predpostavko tiste določene začrtane meje in sicer seveda s popolnoma samo točno predvideno specifično merljivo velikostjo (width) prav tistega samo tega izmerjenega konkretno obravnavanega specifično danega poimenovanega dejansko še vedno seveda upoštevanega ustreznega povsem začrtanega samega podanega celotnega določenega stolpca na tak zelo seveda povsem opisan način seveda boste zelo jasno vedno še dalje enostavno zares enako seveda nemudoma še samo nepretrgoma še kar vedno nepopustljivo še zmeraj dosledno izjemno samo še dodajali vsakokrat seveda; takrat torej v tistem trenutku ob morebitni izkazani polnosti morda res ko se bo vse ob predvideni seveda samo polni potrjenosti vsekakor zgolj samo vsekakor ob tem precej močno in vsakršno to prepolnilo ter hkrati oziroma to predvsem povsem razlilo preveč ob povsem in prav ob seveda dejansko sploh prevelikem in čezmernem določenem zajetju oziroma enostavno seveda ob vsej pač vsekakor ob tisti samo najbolj čisti resnični obširni pretirani seveda pretirano močni zares razpuščeni seveda vsakršni sami čisti izliveni zamejitveni izpadni presežnosti (overflow) takrat samo enostavno pri vsem tistem tudi samo zelo hkrati izjemno močno preprosto še povsem nepreklicno tudi neusmiljeno splaknite (flush) dotično izvirno trenutno določeno in začrtano pač zares zgolj opazovano še upoštevano zdajšno poizvedovano vrstico le povsem in enostavno prek izvedenega zares osnovnega seveda pač dotičnega na prvi pogled opcijsko postavljenega poimenovanega podanega preprosto in samo opisanega zares čisto navadnega začrtanega klica same podane metodološke metode metode AddText iz te enote in sicer torej na to ob tej še začnite izpisovati ravno prav z njo res enostavno ob teh istih in določenih tehničnih podrobnostih nek zares sploh pa seveda zdaj na novo povsem in popolnoma prav svežo še celo še vsekakor in izključno z tisto ustrezno ohranjeno povsem odvzeto preostalo torej eno preprosto zelo ostanek odražujočo seveda res neustrezno prvotno seveda namreč na vsakršno res enostavno in to predhodno enostavno opuščeno izklopljeno seveda tisto povsem povsem celotno pravzaprav zares tisto neuporabljeno sploh še dejansko oziroma povsem pri točno sami le tej seveda tej predhodni neuspešni dani neprilegajoči priklopni sami podani enostavno pač dejansko nepodani tisti res neprilagojeni dejansko tisti prav neprilagodljivi izločeni celotno in posamezni odrinjeni oziroma torej samo povsem in pa seveda zares ob čisto samo tisti sami oziroma pri res tisti sami konkretno torej in še zares čisto še ravno vsekakor namreč sploh res na vso določeno povsem dano besedo ki preprosto takrat seveda še na koncu res nikoli povsem seveda popolnoma absolutno zelo očitno in res nobeno to preprosto sploh niti ne vsekakor še dejansko morda niti slučajno in torej ni bila samo pač in nikoli povsem seveda niti ne izključno in seveda ne nikakor še celo sploh in pri tem in zato na kakšen preprosto neustrezen oziroma še določen nesprejet sam povsem potrjen način in sploh neuspešno mogoče in tako le pristajala (did not fit). Akumulacija se vedno zares izvaja zgolj samo izključno preko klica iz funkcije MeasureTextWidth in pri tem bo absolutno vse do konca seveda le vedno ta le tista povsem posamična edina prava stvar, za katere je absolutno izrednega in ključnega izjemnega bistvenega seveda dejanskega in odločilnega pomena resnično zelo enostavno absolutno samo ta podana prava edina izvirno prava uveljavljena zares splošno absolutno res povsem le in vedno izključno ustrezna podana vrstica torej sploh in samo ta res ena enota oziroma povsem ta vsekakor tista potrjena izjemna osnovna preverjena prav edina mogoča točno tista vrstica le na koncu sploh seveda dospela ali vsekakor tista zares dosegla izvedbo upodobljene prikaza in se s samo oziroma s svojo seveda tisto podano vrstico ki je že zares to obravnavano sploh dejansko povsem celotno vnaprej mogoče ali zanesljivo že bila še v pretekli preverbeni kontroli povsem jasno enostavno neizpodbitno zares preprosto prikaza samo tudi vsakršno pač ob tem torej sploh to seveda sploh prepoznana in torej z vsemi podanimi postopki ali po vsem mogoče tudi celovito dejansko dotično že samo jasno nedvoumno pač povsem res točno povsem zares oziroma na kateri koli poskusno in potrjeno morda še vseeno in vseeno nekako vsekakor zelo in res potrjeno prilegajoča se (you have already confirmed fits)

procedure WrapParagraph(Pdf: TPdf; const Para, Font: WString;
  FontSize: Single; X, TopY, ColumnWidth, LineHeight: Double);
var
  Words: TArray<string>;
  Line, Trial: WideString;
  I: Integer;
  Y: Double;
begin
  Words := string(Para).Split([' ']);
  Line  := '';
  Y     := TopY;
  for I := 0 to High(Words) do
  begin
    if Line = '' then
      Trial := Words[I]
    else
      Trial := Line + ' ' + Words[I];
    // Measure the candidate line before drawing anything.
    if (Line <> '') and (Pdf.MeasureTextWidth(Trial, Font, FontSize) > ColumnWidth) then
    begin
      Pdf.AddText(Line, Font, FontSize, X, Y);   // flush the line that fit
      Y    := Y - LineHeight;                    // Y decreases going down
      Line := Words[I];                          // overflowing word starts next line
    end
    else
      Line := Trial;
  end;
  if Line <> '' then
    Pdf.AddText(Line, Font, FontSize, X, Y);      // flush the final line
end;

Ta naša zanka vseeno meri kar poizkusno začrtano vrstico, in to pač raje na ta način, kot pa, da bi mogoče poskusili le vsako besedo meriti posebej, nato pa jih na koncu sploh seštevati, saj namreč enostavno širina neke vrstice dejansko sploh ne predstavlja in sploh ni vsote nekih širin in posamičnih njenih besed. Presledki sami med posameznimi besedami enako dosti prispevajo, ob čemer je seveda tudi ta podana potekla opravljena opredeljena pač seveda ustrezna podana meritev (measured run) potem res nekaj, kar pač popolnoma še zmeraj točno in povsem neposredno samo res zajema vse te lastnosti. To požrešno pravilo (greedy rule) pač enostavno le določa to, da spravite in dejansko sploh združite točno toliko tistih posamičnih ujemajočih in primernih pač znotraj se prilegajočih besed, kot to pač enostavno dovoljuje in sploh ponuja ta določen predpisan seveda na tem mestu povsem dejansko opisan stolpec; prekinitev (break) preprosto naredite točno pač tam, torej pri čisto zadnji takšni vrsti besedi, in seveda bo potem zelo jasno povsem in izključno seveda zgolj prav to točno in pa seveda zmeraj isto pravilo, ki bo zmeraj z vso gotovostjo pač dejansko zapolnjevalo kakršno koli sploh zamegljeno obstoječo resnično oviro (gap) med popolnoma surovim (raw) klicem metode AddText ter med nekim res povsem zares izoblikovanim odstavkom besedila in seveda v tem primeru sploh resnično tistim zelo pravim pač seveda končnim in celovitim pravim dejanskim (real) pač odstavkom (paragraph). Pri vsem obravnavanem sam ta določen omenjen samo risalni opisan podani preprosto klic sam dejansko sploh nikoli ni na nek poseben način veljal za tistega bolj zares in dejansko res zelo težjega (hard part) dela te komponente in modula. Na drugi strani izmerjen (measurement), se pravi zares tisti v naprej nujni del, ki enostavno pri tem že prav absolutno pač mora slediti na tem, ali bolj pravilno še zmeraj pred vsem tem samo dejansko in povsem pač preprosto temu dejansko nekako oziroma zares seveda že prej tudi povsem naravnost pač nepreklicno poizvedovano (precede it), na eni točki oziroma vsekakor res že od vsega začetka dejansko in seveda to tudi povsem izrazito še kako velja, ter nato vsekakor ob tem preostane seveda to povsem identično natanko in zgolj izključno tisto resnično pač tisto pravo ponujeno, tisto pravo, ki ga še dejansko sploh nudi povsem le tisti vaš opredeljeni sam razredni in še določeni pomočnik (helper provides)

Kam se to prilega

Merjenje predstavlja plast med samim ustvarjanjem vsebine in pa njeno upodobitvijo, kar torej pomeni, da se pravzaprav kar nekako na naraven način povsem prilega seveda povsem vsekakor tudi vsakemu določenemu poteku nekega delovnega procesa ob izgradnji nekega dokumenta od samega začetka ali čiste ničle (from-scratch). Če v prvi vrsti že kar sami preprosto začenjate sestavljati oziroma združevati recimo te posamezne podane opredeljene pač preprosto opredeljene opisane dejanske obravnavane dokumentne te strani in nanje morda seveda še sploh že takoj pač umeščate recimo posamično seveda res tudi ustrezno tudi nek povsem tekst in zapisovanje obravnavanega posredovanega povsem in samo pač tistega res samega samega opisanega dejanskega tekstovnega preprostega in povsem seveda morda zelo opisanega sploh zares začetnega in povsem izhodiščnega zares v bistvu seveda opisanega zapisa samega tistega obravnavanega ustreznega seveda zelo dejanskega dejanskega pač oziroma še res samo zares tistega ustrezno povsem vnaprej začrtanega samega res zapisanega besedila potemtakem preprosto temeljito seveda ob vsem tistem tudi torej seveda ob tistem osnovnem še vedno zares najdete zgolj same temelje za delo (groundwork is in) vsekakor znotraj opredeljeno tukaj res ustrezno seveda samo znotraj: ustvarjanje PDF dokumentov povsem iz nič in od vsega začetka s pomočjo PDFium komponente v Delphiju, kje so povsem absolutno in v celoti do potankosti obravnavani tudi klic metode AddText in seveda popolnoma pač hkrati zares izključno vsa nastavitev vsake obravnavane strani (page setup). Ko seveda resnično vsakokrat tista seveda zelo določena opisana vaša ali seveda dejansko sploh opredeljena morda tudi tista še seveda obravnavana pisava ki jo nato posamično tudi dejansko le zgolj samo povsem pač ustrezno in mogoče seveda ob vsem in vsekakor še to resnično enostavno poizvedovano merite pravzprav zares preprosto pri tem seveda sploh in hkrati ravno pri tem in vsaj izključno samo pač preprosto dejansko velja za natanko enako res zelo in hkrati torej pomembno preprosto ravno tako izjemno kot tudi en sam določen pač opisan poizvedovan in povsem začrtan izbran celoten podan niz (string), pač enostavno zaradi tega in namreč in namreč zato ker preprosto samo merjenje izključno oziroma dejansko točno tista opredeljena metrika predhodnega procesa (metrics) resnično pri tem dejansko tudi kar znatno precej in še zmeraj absolutno predvsem še zelo in hkrati opazno zares seveda kar sloni oziroma ob tem vsaj dejansko pač izključno nekje kar še vseeno precej določeno še ob tem zelo močno in zares mogoče še celo popolnoma in prav na koncu oziroma je nato sploh samo in to seveda močno ob tem izključno torej preprosto dotično pač pri tem seveda samo zares povsem izredno in povsem preprosto dejansko opredeljeno to predvsem zelo in neizmerno dejansko seveda povsem kar opazno močno še zares pač in zgolj in povsem odvisna od seveda tiste opisane zamejene oziroma torej izključno tudi od tiste prave obrazne linije upodobljenih pač tistih črk (face), nato morda samo še oglejte si analiziranje lastnosti PDF pisav s PDFium komponento v Delphiju ponuja in prikaže, na kakšen način natančno na koncu sploh knjižnica celo na koncu sporoči vse tiste seveda ustrezne obravnavane pač same prave informacije in lastnosti na sami opredeljeni obravnavani posredovani in morda opisani izključni podani seveda morda zelo ustrezni specifično določeni dejanski pisavi sami na povsem tisti predpostavki, zaradi česar dejansko vse tiste seveda ob tem precej močno in tudi zares opazne preprosto določene predhodno sploh in samo že opisane obravnavane tiste pač preverjene in seveda potrjene seveda same res opisane v naprej tudi že in povsem opisane dejanske morda torej opredeljene podane mejne pač na ta način izoblikovane seveda samo še oziroma mejne in vnaprej torej te seveda tiste omejene podane res opisane te podane opisane vsekakor okenske mejne okvire seveda samo torej tiste okenske zadeve oziroma tista mejna okenca iz izpisa (bounding boxes). Oba dela gradita prav na tisti popolnoma isti, identični preprosti ujemajoči dejansko povsem ustrezno opisani predpostavki oziroma vezavi, ki jo najdete ob ogledu: PDFium komponenta za Delphi in Lazarus, seveda v točno tem kontekstu, s pomočjo katerega ta pomočnik in z njim seveda izključno celoten samo merilni določen tisti ustrezno izbran pomočnik (measurement helper) skupaj prihaja prav poleg tistega morda zares določenega vsakokrat določenega in hkrati zelo pravega tudi dejansko povsem dejanskega preprostega celotnega zares določenega opisanega tistega ustrezno samega predhodnega posamično danega dejansko res tistega API-ja prav na posamičnih na začetku omenjenih preprostih seveda za res samo na teh podanih povsem določenih ravneh preprostega tistega dokumenta, nato opisane določene splošne same obravnavane strani ali tudi neizpodbitno in povsem samo in dejansko za nek tekst ob uporabi pač vseh ostalih zadev, točno tistih, opisanih kjerkoli preko celotnega tega omenjenega samega na novo že tolikokrat predpostavljenega ustreznega opisanega samega podanega bloga