Tehnički članak

Puno poravnanje za PDF tekst u Delphiju uz HotPDF

Puno poravnanje (full justification) je izgled (layout) koji čini da se stupac teksta poravna na oba ruba, lijevom i desnom, što je izgled kakav očekujete od tiskane knjige ili formalnog izvješća. Lako ga je opisati i iznenađujuće lako pogriješiti, jer odgovor na pitanje "kamo ide taj dodatni prostor" nije isti za engleski i za japanski, i zato jer onaj naivni način mjerenja svake linije pretvara brzu stranicu u sporu. HotPDF vam daje poravnanje svjesno pisma (script-aware) putem samo jednog poziva za raspored okvira (box-layout call), a ispod tog poziva krije se školski ispravak performansi (performance fix) kojeg vrijedi razumjeti samog po sebi

Ovaj članak prolazi kroz oboje. Prvo, tipografsko pravilo koje odlučuje kako se raspodjeljuje višak (slack) kod pisama s razmacima među riječima (word gaps) u odnosu na pisma bez njih. Drugo, promjenu mjerenja koja je smanjila cijenu poravnanja po stranici za otprilike osamdeset puta bez vidljive razlike u konačnom izlazu (output). Oboje je važno ako generirate dokumente u velikim količinama (at volume) i želite da se čitaju kao pravi slog (real typesetting), umjesto kao monospace ispis rastegnut da se ukalupi u širinu (stretched to fit)

Što zapravo zahtijeva puno poravnanje

Linija teksta iscrtana u svojoj prirodnoj širini gotovo nikada ne doseže desni rub svog stupca. Uvijek ostaje ostatak, višak (slack), između onog mjesta gdje završava posljednji glif i mjesta na kojem se nalazi granica stupca. Lijevo poravnanje (left alignment) ostavlja taj višak s desne strane. Desno poravnanje premješta ga na lijevu. Centriranje (centering) ga razdjeljuje (splits). Puno poravnanje uklanja ga širenjem same linije sve dok oba ruba ne dotaknu okvir (box), a jedini iskreni način za to jest razdvajanje glifova iznutra

Pravilo koje odvaja dobro poravnanje od lošeg jest točno to kamo ćete smjestiti taj višak prostora. Pismo koje riječi piše s razmacima između njih, kao što je to engleski jezik i ostatak latinične obitelji, ima prirodne šavove (seams) pri svakom razmaku između riječi. Širenje tih razmaka nevidljivo je oku jer čitatelji ionako već prihvaćaju da razmaci između riječi variraju. Pismo koje piše bez razmaka između riječi, poput kineskih Han znakova, japanske kane ili korejskog Hangula, nema takvih šavova. Tu se višak (slack) mora ravnomjerno rasporediti između susjednih glifova, što je princip kojeg japanski slagači (typesetters) nazivaju kintou-waritsuke, ravnomjeran razmak (even spacing). Stavljanje rastezanja razmaka između riječi u latiničnom stilu na CJK (kinesko-japansko-korejsku) liniju teksta, ili pak utrpavanje cjelokupnog viška prostora na samo jedno mjesto gdje CJK linija slučajno sadrži razmak, stvara rijeke (rivers) i praznine koje odaju potpuno amaterski (amateur) izlaz (output)

Kako HotPDF odlučuje kamo ide prostor

HotPDF tu odluku donosi po svakom pojedinačnom razmaku (per gap), a ne po cijeloj liniji (per line). Kada on poravnava neku liniju, prolazi kroz svaki susjedni par glifova i pita se nalazi li se rastezljiva granica (stretchable boundary) između njih. Granica je rastezljiva kada se na jednoj od strana nalazi razmak (space) ili tabulator (tab), što je slučaj kod latinice (Latin case), ili pak kada su s obje strane znakovi koji se mogu prelomiti u CJK pismima (CJK-breakable characters), što je slučaj s ravnomjernim razmakom (even-spacing case). On prebrojava te granice, dijeli onaj višak prostora (slack) s linije jednakomjerno među njima, a zatim taj dobiveni dio (share) dodaje svakom od kvalificiranih razmaka (qualifying gap)

Posljedica isplivava sasvim prirodno. Engleska linija ima rastezljive granice samo kod svojih razmaka u riječima (word spaces), pa cijeli taj višak prostora slijeće upravo tamo, čime se same riječi međusobno udaljavaju dok slova (letters) koja se nalaze unutar svake pojedine riječi zadržavaju svoj sasvim prirodan razmak. Han (kineska) ili kana (japanska) linija ima rastezljivu granicu između gotovo svakog para glifova, tako da se višak prostora raspoređuje ravnomjerno duž cijele linije (whole line), predstavljajući upravo onaj ravnomjerni razmak među glifovima (even inter-glyph spacing) kojeg ta pisma i zahtijevaju. Linija koja se sastoji od jedne duge latinične riječi bez ikakvog unutarnjeg razmaka nema baš nikakvu rastezljivu granicu, zbog čega ju HotPDF radije ostavlja pri njezinoj prirodnoj širini (natural width) nego da riječ trga (tearing) slovo po slovo. Ova, sasvim jednaka (same) logika rješava i one pomiješane (mixed) latinične te CJK nizove (runs) na istoj liniji teksta bez posebnih (special-casing) modifikacija koda (odlučivanja), jer se odluka donosi lokalno (local) spram svake od granica

Samo jedna granica se na svim mjestima sasvim namjerno izuzima (excluded). Pozicija smještena nakon posljednjeg (final) glifa u liniji nikad (never) se ne tretira kao razmak (gap), zato što bi rastezanje (stretching) na tom mjestu samo iznova unijelo onaj desni ostatak (right-hand remainder), a što je upravo čista suprotnost samom poravnanju (justification)

Zašto se posljednju liniju ostavlja na miru

Završna linija odlomka prilično je posebna, i njezina pogrešna obrada jest onaj najčešći bug kod poravnavanja (justification bug). Posljednja linija odlomka redovito je samo kratka, često sa samo par (few) riječi, i samo rastezanje takve linije do pune širine stupca te iste riječi vuče preko cijele stranice (across the page) tvoreći time prilično rijedak (sparse) i sasvim polomljen (broken) redak. Ispravna tipografija posljednju će liniju radije ostaviti u njenoj prirodnoj (natural) širini, poravnatu ulijevo

HotPDF po njezinoj poziciji (by position) prepoznaje tu istu prateću (trailing) liniju. Dok prelama (wraps) tekst u linije, on zna kad upravo ona linija koju je zadnju odcijepio (split off) dosiže (reaches) sami kraj dovedenog mu niza znakova (supplied string). Ova završna linija u konačnici ispisuje se s običnim lijevim (left) poravnanjem i pritom zadržava svoju prirodnu (natural) širinu. Baš svaka (every) linija prije te iste će po oba ruba biti uredno poravnana (justified to both edges). Oni tvrdi prekidi linija (hard line breaks) koje zapišete u tekst poštuju se onako (honored as written) kako su i napisani, tako se stoga i baš svaki onaj namjerno kratki redak (intentional short line) ovdje isto neće nikada (never) rastezati (stretched). Onaj tko tu isti čita naposlijetku (reader) vidi samo jasan i čisti (clean) pravokutni (rectangular) blok teksta sa svojom zadnjom linijom okončanom na sasvim prirodan način (ends naturally), što je ujedno i upravo (exactly) ono što njegovo oko na kraju krajeva i očekuje

Trošak mjerenja koji je usporio poravnanje

Kako biste poravnali (justify) nekakvu liniju morate znati njezinu točnu širinu (exact width), i morate (must) znati pomak (advance) kod baš svakog od glifova ne biste li dodatan prostor (extra space) na taj način uspjeli vrlo precizno locirati. Ona sama (The first) početna je implementacija dobivala sve navedene brojke sasvim na onaj očiti način. Liniju bi izmjerila upitom (query) pune Unicode (full Unicode) širine, pa potom svaki prefiks (prefix) ne bi li uspjela doznati (recover) razliku u promjeni za dobivanje (differencing) onog pomaka kod svakog od glifova (each glyph's advance). Ukoliko je riječ o N glifova onda govorimo i o samo N+1 (N+1) poziva mehanizmu koji zadužen (measurement engine) je tu za mjerenje, no svaki taj jedan upućeni poziv (call) zahtijeva puno (full) GDI povratno putovanje (round-trip), uz stalno ispitivanje da (asking) sâm tu u pozadini operativni sustav izmjeri kao i da oblikuje te naposlijetku i proslijedi taj tekst zajedno sa svakim (answer back) takvim konačnim odgovorom

Svedeno po liniji (Per line) to sve uopće ne zvuči skupo. Kroz samu (Across a page) jednu cjelovitu stranicu baš to (it is not) ipak nije tako. Odaberimo tek nekakvu sasvim prilično zbijenu (dense) A4 (A4) stranicu sa samim tijelom nekog (body text) teksta, u otprilike nekakvih i do četrdeset pet linija (forty-five lines) u svakoj od (eighty characters) po osamdesetak znakova (each). S onim ukupno (At N+1 round-trips per line) po N+1 takvih jednih povratnih (round trips) pozivanja, pa je to 81 istih na svakoj takvoj liniji a oko sve skupa tek grubih 3.645 takvih putovanja za tek istu samo takvu jednu cjelovitu stranicu, gotovo svi oni utrošeni (spent) na tek isključivo (re-measuring) ponovljena opetovana prebrojavanja i mjerenja tektualnog unosa na ono u (engine had already) što se mehanizam uspio zagledati iste one tu tek već neke prijašnje proživljene trenutke ranije (moments earlier). U slučaju sasvim nekakvog tek batch posla kod isporuke na čak tisuće (thousands) pojedinih stranica dokumentacije (pages) upravo taj overhead preuzima pa (dominates) usporava i najznačajnije vlada vremenom oblikovanja (layout time), a baš svako od svih od takvih spomenutih tih istih pojedinačnih povratnih kružnih (round-trip) mjerenja s time samo prelazi same međe granica procesa rada s jedne od vaših aplikacija pri istom te posla kojeg to zahtjeva na strani drugog na koji sve (graphics subsystem) pazi samo operativnom radu isključivo onaj dodijeljen spomenutom mu tek vlastitom grafičkom (subsystem) modulu zaduženom

Samo jedan poziv namjesto njih N te onom jednom istom tome pridodanom

To previđeno popravljanje ovdje točno opisuje onu neku baš (the kind of) vrstu tako usputno nekakve poprilično barem tek malešne (looks small) ali isplative takve male jedne pa i za nju na oko skroz jako velikog učinka (pays off large) popravke u postavkama. GDI pak sve već itekako dobro sam (already) sam izračunati te na ishod proslijediti umije svaki puta prebrojavajući i dohvatajući sa sobom puni cjeloviti (total width) taj zbroj s navedenom istom tek (string's) traženom nizom postavljenih iz točaka te (position) pri isto i iz samih navedenih pozicija mjesta s navedenim upitom po tek svakom isključivo navedenom onom upitanom traženom tako zvanom u upitu onom (single query) glifu unutar samo od tog pak i samo tog pa i isključivog upućenom mu jedinog jednog. HotPDF takvo za sebe baš (exposes) ispostavlja onim za to u takvim prigodama samim time njemu samom njemu dodijeljenom komandom mu za GetWideCharAdvances, kojom pri puni (fills an array) taj popis svakom pa (advance) onom takvim jednim dodijeljenim svakom prirodnim tako napredujućem nizu zajedno s u istu mjeru uračunatim (kerning included) usput dodanim tu sa svakom pri u sve skupa usput priloženim onom takozvanim u tom pa još i dodatku s njim tom istom njemu već pri (kerning included) prikliještenom istom. Uz tek vraćenu samo onu njemu dodijeljenu ukupnu točnu dobivenu mjeru i vraćenu tek iz (returns) povrata za istu onu najširu svu tu njoj preuzetu s tom pak njemu sveukupnu njoj isporučenu na njezinu to mu poslanu tek navedenoj najdužoj ukupnu teku u mjeri mjerenu tako na u njemu ukupnu svu cjelovitu širinu, tek iz sasvim istom baš pa tek i tek (in one call) tek sasvim iz samo njegovog upućenog tek jedinog poziva s njega naspram umjesto onog mu drugog uz iz (rather than N+1) njegovog iz njega samo (N+1) poslanog prije navođenog u istog mu tako pri njemu opisanoga. Takva u njem istom od njega to (justification routine) tu postavljena za nju poravnana sva sa sebe sva istom ta rutina nazvana nju pod navođenjem s pri imenu _HPDFEmitJustifiedWideLine s kojom mu ona u njezinoj tajnoj (internally) unutarnjoj obradi tu za sam zahtjev mu tek upituje po njoj na sve tako te to poslane pomake po iz tek onog mu njenog tu jednog puta (asks for all the advances once), tako s nje iz istog preuzima onaj po isto na tu mu samu (computes the slack) pa i to dobiveno pa te i po njoj taj sav tek dobiven na njoj (slack) po onoj njenoj isto od nje tek taj zbrojeno onaj njezin onoj od njoj tog pretežno tek nju zadanom po mjeri s iz nje tek pa sa preostaloj viška dobivenu zbrajanu brojku to joj sve to tu onog ostalog te ostavljenog onog pretečenog tek na tu istu baš tu proračunata mu ta prazna višak ostavljena pri navođena iz njoj isto spomenuto na iz navoda onoj joj na njoj to tu, sve poslije tog (distributes it) iz dobivenog pak tako podijeli je po nizu kroz uz samo njene isto podane mu tek sve joj po iz nje tako poslane sve na onoj za onu njenu (stretchable boundaries) tu zadanu po te joj za taj rastezljiv na njoj postavljenom nizu takav s onom joj za iz tih svih njoj po toj s istom poslanih tom poslužena svih joj navoda na tih spomenutu istih na granice, i konačno nakon svega ispljune pa odašilje (emits the line)

Za tu istu A4 stranicu mjerenje po liniji pada s oko 81 povratnog putovanja (round-trips) na jedan, tako da stranica pada s otprilike 3.645 povratnih putovanja na oko 45, blizu osamdeseterostrukog smanjenja. Izlaz (output) je identičan bajt-po-bajt, jer se ništa oko mjerenja nije promijenilo osim koliko puta se traži. Isti GDI engine, iste metrike fonta, isto kerningovanje (kerning) hrane iste brojeve. Samo se broj povratnih putovanja smanjio. Kada je mjerenje već ispravno, prava optimizacija je prestati ga tražiti više puta (repeatedly), a ne ga aproksimirati

Kako linija dosegne do isporučene nam postavljene po njoj zadane stranice

Kada mu s onom njemu samo takvom mu podijeljenom višku praznine se posluži sav posao s tom podjelom (apportioned) tog tog istog pak od iste joj mu za (slack) to dodijeljene razdijeli sve tek, HotPDF s te to tako on i nju s tim tako istim isporučuje te pa u sve istim odašilje po njoj samu joj je tu liniju po njemu a uputu joj na onom zadanom joj za pod komandom istom toj ExtTextOut i tom priloženom uz po svakom se dodanog sa (per-glyph advance array) u dodanim na popisu tako uz tu sačuvanog tako od na navedeni uz na napredak s niz u popisu pridodani nju (array) po svakom od njih uz po svaki mu navod glifa u nizu dodijeljen tu s to po istom pridodani istom se pri, tim tim tim iz navoda za Dx polje navod tu pridodanim za u popis njega (array). Svaki tu za unesen broj taj iz upisa jest tek ona s to navođenim sačuvan sa sam istog po za tu mjeru na iz priložena po istom mu nizu onog te pak tom po svakog dodan onog (distance from one glyph's origin to the next) dodijeljenoj toj na samoj mjeri na odmaknu to udaljenog na s jednog u ishodištu smještenom sa tog priloženoga dodijeljenom navođenom pa sa samog tog te mu tog za priloženo s tek takvim svakog pri tim pa mu se to samo do tu onoj sljedećoj njemu od te mjere navedeno po, te tim se to samo pri tom tako (which is that glyph's natural advance plus its share of the slack when a stretchable boundary follows it) dobiva se u to po navedenom tako pa baš tim tim samo tim istim pak a po toj njemu samoj onoj zadanoj njegovom od mjere u odmak i po to tu navedenom pri dodijeljenim svakog navedenim po tim sam pri tako postavljen u tom tom dodanog se svima tim uz i tog uz tu istom prirođeno s priloženog svugdje na njoj navedenu samo napreduje mu po mjeri pa s usputnim svim pri s i po od onog dodijeljenim to svima tek mu dodanog tek s tu sa svima njoj za sa njoj istu samo tek njoj na tim udjelom tu poslane mjere i tog dodanoga istog za mu viška po kada uz se njega za isti njim nadoda to kada s u isto prigodom mu pridoda sa tom rastezljiv na njoj postavljenom tako tom uz nju priložena i po svuda s te za njezina se za i tim dodana mu na samo po granice mu pa za to sve se to s u priloženom dodano poprati poslije svugdje priloženim istim tom (follows it). Samo ovo tako tu (This maps directly onto the PDF imaging model) u se po baš po iz toga tek na tu iz to priloženo tek isto baš preslikava sa posvema se sasvim se iz po u sasvim njezinu za to se tako tek upravo dodijeljenim njoj tek od sasvim tako pri na ono tim iz istog se na tim ravno pa po tom direktan po tome (directly) spram navedenome se po tek iz PDF sa mu po za tim za taj slikovni (imaging model) taj onaj nju i njega i na taj od mu (model) mu na isti PDF (PDF). Po istom onom tim mu tu na sam mu baš iz toga te pak njemu baš smještenoj sasvim tek postavljen po s nje za u navoda uz te pa i na nju tu (Positioned text) s tek nju zadan uz pozicijama taj joj (text is written) tekst onda ispiše zapisuju na tek istu za njega i njoj onaj dodijeljen pa se za komandu pridodan s tu po mu on (written with the TJ operator) pa sa nju pridodan i onim to dodijeljen u uz od operator pa baš tim (operator) s u tu tom u toj zadanim uz TJ, tek (an array that interleaves glyph runs with explicit horizontal adjustments) sam (array) taj u (interleaves glyph runs) pak pa se u iz tog niz glif po s navodima u samo njemu istom tek te pa se u niz popiše pa tek iz popratnog mu i tom sa svakog u sve pri sa svakim tom na iz s navedeno postavljen (explicit) za od na sasvim se tu iz pa uz to tom iz u samo na poslanih te samo tim eksplicitnim dodano pri u sasvim sve vodoravnim po sa tako s to vodoravno tu po sasvim s njima popraćeni za tim sa i od sa po iz od tu s popraćeni svakog pa to tek po onog s iz od na tek za priložen (adjustments) u s na sasvim tek (adjustments) za sve uz iz iz dodan na (adjustments) tek popraćeno, te (and the Dx values become exactly those adjustments) i sa to svaka njoj dodijeljena svaka a sa po svaku sačuvan sa nju priložena njezina u dodanim navođenim sa Dx po navod iz svake i tu naveden (values) svake pridodana taj te broj njezina se ona tom (become) za taj u njemu postane iz svakog dodan tu od uz po iz na baš (exactly those adjustments) iz i baš za svakom od sve od takvog i takva na za nju te sve pri tu po baš upravo za navoda tih i po tim od na istih sve baš navedenim po onim sve tim to isto za te popratni iz od sa na (adjustments) usput to po podešeno iz to postavljen tim. Baš sve to se pak u onom tom tu postavljenim i popraćenim tom sa baš svima tim od sasvim po iz po od na tim iz na onom iz po od pa u na tim onog što po za dodano po na svim se iz toga tu iz za pa zašto se te po onoj od svuda na to zašto to po tom iz na iz od iz to upravo iz po na se od iz svake u na tu tim za samo tom svake pa tu navedeno po na po (extra space) s usput pa navedeno sasvim mu na po to praznine te svake pa po sa na pa (extra space) na uz onaj od svuda mu na u (extra space) viška za (lands between glyphs) u svim pa svuda baš s tom po u s to baš a tek se kod na tim to sleti spusti s pa pri te tek pri samo tu tom s se onda tu pa među sve svakog od tih na svaku po to od njih tu to i (glyphs) glif i po svim od onom tim navod od iz pa glif po tim svakom pa u tim za mu za tu od mu na u sa po (at precise sub-point positions) sa u točnim sve tek i precizno sasvim naveden tim sve (precise) po na svuda na po preciznim u pa pri i sasvim na (sub-point) s u na svuda od ispod tu navoda na iz dodijeljena svim pa od na iz iz svaku na pri po sa od na sve (positions) s od uz pa na onih svim uz navedeno tu tu (rather than being faked with padding characters) mu na uz na to tek po sa pa se sa samo umjesto po od iz tu tim onog (rather than) se baš tek umjesto pa samo s od naveden tim mu sa u mu to tom tim od iz lažnog tek te svim po sa se od na od (faked with padding characters) tu lažnim od po od se navod samo sa tim pri umjesto za lažne (padding characters) za od na to te sa svim tek samo uz po sa na (and why a justified HotPDF line measures correctly if a downstream tool reads it back) na po za od na te sa tim zašto od na sve po sa tu navod za iz to pa zašto sve to se baš to po to tu sve tim to na tu iz po na po to zašto se to (justified HotPDF line) s za to se tu s tim po a (justified) ta iz navoda (measures correctly) tu to se od na to na od tu po svim po (correctly) a tu navoda sa to mjerom to od se u tu na sve po od od onim na (downstream tool reads it back) u na tim to po sve od navod za od na na u (downstream tool) se iz po navoda to za tu u od tim od to tu u tim sa (downstream tool) za onim iz se u navodom od tu to sve s po od navod na po iz za tu (reads it back) sve iz navodom tu sa u od na po to sve s od

Sami (yourself) niti vi pa ne pozivate baš za samu (ExtTextOut) naredbu sve (for justified paragraphs) zbog sve za od svih se u poravnanim tim sasvim tako sve pa po odlomaka tu za sve baš

Vi tu osobno sami tako vi nikako vi s (yourself) pa ne navod iz (call) te s njom zovete tu samu tu po iz to zadano s naredbe u (ExtTextOut) za sve po onoj (for justified paragraphs) to iz navoda onoj tu zbog u sve iz po na svim se po poravnanim od pa u za tim tek svim baš to za odlomcima na svim u sve baš. Sama pa njena ulaznom s navoda tom dodan (entry point) sve po u njoj točka iz za od sve s njom po navedeno u onoj baš tu nju sa dodano pa u s naredbi u WideTextOutBox, u pa nju a po njoj s a sa iz ona (which wraps a Unicode string into a box) tu sa navoda na nju nju pak tu umata to za sa za iz navod o onoj baš (Unicode string into a box) po sa za nju navoda od na to to u pa u o tu iz a iz navod se pak tu sve (wraps) od pa ona omota baš to tu nju na sve iz sve Unicode niz onaj dodani za s iz na po od u tu to u tu od nje (box) to sa svaku za tu iz kutiji za te sa o (and applies the alignment you ask for) pa po uz dodana od te dodaje (applies) pa na s nju uz to baš onom s a iz tu (alignment) po poravnanju onom u za na s onom dodani (you ask for) koje po onom o tu navod za nju tu se od na tražili o od po za to pa nju s tu za nju to ste za to za ste sa za iz od to pitali na sve iz po na onom to na. Ona taj pak o iz za tu tekst i iz sve tu navod (splits the text into lines that fit the box width) onaj iz po od tekst na (splits) sve tu od sa podijeli pak to sve od u na sve u te iz sve u na po linije tek navoda u na pa u iz to u navoda (lines) a navod o s (fit the box width) na sve u o tu iz odgovaraju mu na onoj po s a na (fit) to a stanu iz od tu (fit) pa stanu se na za mu na to to pa u na (box width) za mu dodano i sa širini a to (box) kutije u od to to a od se u na za sve u, a (places each line down the box height) s a uz od tu na za svaku od tu po iz na to se liniju pa svaku na (places each line down the box height) na sve u a tu onaj za po (places) iz od se smješta po iz o (down the box height) u na za po dolje na u po za a na iz tu se o a za na dodano (box height) na za to za po u iz to od za (height) po a za tu na iz visini sa tu u (box) na to od (box height) kutije uz to u na od za iz a to o iz za po, i to po (and returns the number of characters it managed to fit before running out of vertical room) po za od i (returns) iz a po u se o i na iz vraća sa (the number of characters) o a tu iz na s (number of characters) sa po a o broj od na o znakova u (managed to fit) a na u po a u iz (managed to fit) na to što je iz a o a to pa uspjela sa o na u u (managed to fit) na (fit) to a o ugurati u od za iz (before running out of vertical room) a na iz po o (before) sa a o a na prije za iz o za a po na (running out of vertical room) a tu na u a iz na (running out) tu se za po a iz (running out) po za od a iz se po nestanka iz od (vertical room) po a u iz a za (vertical) na po o iz a za vertikalnog na po od u (room) na od u a iz a za mjesta od u za. Samo po u o (alignment is chosen by the justification enum) a to a o (alignment) tu po a o a na iz poravnanje po o iz za a na od u se a (chosen) po na tu iz o a na (chosen) a o (chosen by) a o bira na po o iz (justification enum) o po a na (enum) s za tu iz o a a nabrajanjem a za iz na po za na o (justification) u po a tu o na a za iz u o poravnanja za po u za a po o od o

type
  THPDFJustificationType = (jtLeft, jtCenter, jtRight, jtJustify);

Ona prva od a to tu za to po a iz (three) u na tri su po tu za to po (self-explanatory) a o a na samoobjašnjiva a za po u na iz na iz lijevo, pa za a tu u od i (centered) po o a iz (centered) centrirano na o a u iz za a iz po u a po (and right alignment) na o po tu iz u a po a i za iz na tu a po desno (alignment) poravnanje za od po na u iz o u. Tu ono a iz na a po tu (fourth) u a tu za od iz o u to (fourth) po a na tu a iz o četvrto na tu, u a od po o a iz na o jtJustify, je po a tu iz o u (full both-edge justification) za od a po iz to u a puno (justification) a po u o na iz od (justification) po a iz na poravnanje na tu a iz po to a o na (both-edge) po a iz u od to na za po (both-edge) na po a o u oba o na a iz u po tu (edge) ruba o a iz na o u po za po na a iz a tu u (described here) po a iz a tu za na po o u ovdje za a o po (described) tu na a iz za o a a opisano, i po a to o tu na a (it is the value) po a u tu to (it is the value) tu a po na u iz (value) a to o tu vrijednost (WideTextOutBox reads) tu o po na koju u a po na (reads) a iz po tu na (reads) a o tu čita a o tu na o WideTextOutBox za a o iz po na (switch on) a po tu na a o a u (switch on) tu u po a iz a za a o a na uključi u o po tu a o na iz za (script-aware spacing) u na po tu a iz po o a (spacing) a po tu na a iz o a za o razmak na po a iz tu a za o u (script-aware) po a tu u a o a iz o na svjestan o po a na u tu iz o a pisma

Poravnavanje onog a o odlomka a to u po na u na to o praksi

Ovaj pun (complete) za po a iz o (example) u a na o a po iz (example) tu a iz po na tu po o a primjer po u tu iz na a po stvara (document) tu o a na u (document) a po tu iz o na a po o dokument po a u, (sets a font) u na po a iz (sets) po o tu a na (sets) a u tu po na o postavlja (font) u na a po o tu font o na tu po, i (pours a paragraph) na u po iz a a tu (pours) u na a tu po (pours) ulijeva (paragraph) u na tu a iz odlomak po u tu na a iz o a u (into a box) tu po na u (into a box) na u tu po (box) kutiju tu o na (with full justification) na po u sa (full justification) po na iz tu a u punim (justification) poravnanjem na u tu a o. Sasvim na u taj a tu po iz isti a u (same code) a po tu u a na o u (code) na po tu kod o po na (justifies) u po tu a na o a (justifies) na po tu poravnava o na u (Latin and CJK text) na tu a iz latinični po tu a na u i na o tu a po CJK po u a tu tekst po tu na a (without a flag change) a po na bez (flag change) o a tu a na (change) a o po u promjene o po tu na o a zastavice a o u na po (flag), jer u po a (script-awareness) na tu a po tu na svijest na tu po u o u na o po pismu a o na (lives) a o po u tu živi a na po (below the API) u po a ispod po u na (API) u po a tu o na o a o API-ja a o na u tu a na

uses
  HPDFDoc;

procedure JustifyParagraph;
var
  Pdf: THotPDF;
  Body: WideString;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'Justified.pdf';
    Pdf.BeginDoc;
    Pdf.CurrentPage.SetFont('Arial', 11);

    Body :=
      'Full justification spreads the slack on each filled line so both ' +
      'edges meet the column, while the last line keeps its natural width. ' +
      'For scripts with word gaps the space lands between words; for ' +
      'scripts without them it spreads evenly between glyphs.';

    // X, Y, LineSpacing, BoxWidth, BoxHeight, Text, Align
    Pdf.CurrentPage.WideTextOutBox(72, 72, 4, 380, 240, Body, jtJustify);

    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

Da u na a o tu iz biste po tu na a nacrtali po tu na a iz (the same block) na u tu isti na u po o iz (block) po na a iz tu u a po u o na blok a po tu o (left-aligned) a u tu na iz po (left-aligned) po na o iz (aligned) poravnat tu na a po u o u (left) a na u po o u ulijevo, tu a na po o u (centered) o na po tu iz u a po a i za iz na tu a po centrirano (centered) po tu a u na iz na o a u iz za a iz po u a po, ili o u a tu na po iz a tu a po (right-aligned) o u a po na (aligned) na tu u po poravnat u na (right) o na po tu o na tu a po desno na tu a, (change only the final argument) a u na (change) a u po promijenite a o na (only) na u po tu a samo po na (the final argument) u a na po u a po o na a po tu u o na a (final) na po u a tu a konačni o tu na (argument) u na a po a (argument) argument a o po na (to jtLeft, jtCenter, or jtRight) o na tu po na tu a po na u na po o u jtLeft, a u o po u a jtCenter, a u tu po ili o u a tu o na po o u jtRight. Samo tu to (wrapping) o na tu a po na (wrapping) po a u tu a na prelamanje o na u, na u po (the line placement) a o na (line) o u a po tu linije na tu o (placement) o na a u po smještaj o na a, i a tu u (return value) na tu po o (return value) po u a na (return) povratna na tu (value) vrijednost po u na (stay the same) po u na a (stay) o a u na po ostaju (the same) u o a na tu isti o u a po. Sama tu (measured width) na tu a (measured) o na tu a po izmjerena po u na a iz (width) na u tu po (width) o a na tu u a širina o na po (that drives all four paths) a u na (that) na po tu koja u na a (drives) po u a na o pokreće po na a tu (all four paths) o tu na a (all) a o na tu po sve (four) po u a na tu o a u na po četiri a o u na (paths) na u po tu staze o a na tu po, u na a o tu iz (comes from GetWideTextWidth) po na a (comes) u o na po tu iz na po o u dolazi po a na o (from) a na po u a (from) iz a u na po o u a iz a po u a po GetWideTextWidth, u na po a (Unicode-aware width query) na po a iz o (Unicode-aware) po a na iz (aware) o a u po (aware) po o a u svjesnog na po u iz a o (Unicode) a na u po Unicodea po a tu iz u a o (width query) a o na po o (query) upita o na u po o a u (width) u na o po širini o u a na tu o po tu na a u, na u po a (that measures a WideString correctly) na po a iz u o na po o u koji po a na o iz (measures) tu a u po o iz (measures) po na a tu u mjeri o a na u (correctly) tu na po a u (correctly) o a na tu po u ispravno o a po na WideString u na a po o, tu u po a (where the older byte-wise measurement) a po na tu (where) a o u na tu (where) a o po u gdje po na a tu o na u po a u iz a po u (older) a o na tu u a o po starije o a tu na u (byte-wise) a u po tu na po o u (byte-wise) a o po u po a na u (byte) u po na a po na a bajtovima po na u tu a (measurement) a o u na po (measurement) po tu na a mjerenje po u a tu, a u po na (would mis-size anything past Latin-1) na u tu a (would mis-size) po a na tu (mis-size) tu na o a po pogrešno tu na a iz po u o u a po o a (size) u na o (size) u po o na a tu o na dimenzioniralo po a tu na u a o po a na u (anything) u a o na tu po sve na u (past) a po tu o iz a po u a (past) u a tu na po o na a po o iz a iza po tu na a u o na u po a po (Latin-1) a u na po o u a po Latin-1, u na a po (which is what makes the box wrap CJK and surrogate-pair text at the right place to begin with) a po na u tu iz o na a po o (which is what) a u po tu (which) a o na tu u što po a u tu na (makes) o na a po u o (makes) po tu na a iz čini po u a tu na a (the box wrap) o a na u po (wrap) po a tu na u a da po na a (box) po tu na a kutija po u na (wrap) u po tu a prelama po u na tu a o po (text) tekst a tu po u na iz po na o (CJK) po u a na (CJK) CJK po u na a tu o na u po i na u a po tu (surrogate-pair) o a na u po tu u a po (pair) po a tu na u parove po u a na tu o a (surrogate) o na a u (surrogate) po u a na o surogata po a u na, (at the right place) a tu na po iz a (right place) na po tu u na (place) o na a tu o mjestu (right) na po tu u o (right) na u po a na o a u na pravom po na tu, a o u na (to begin with) u na a po iz na po o u za a o tu na po u (begin) po a u na (begin) a u po početak na tu a po

Poravnanje (justification) po a tu na u a (one layer) po u na a tu (layer) sloj na u po a je u na po tu a (larger text-shaping stack) o a na u po a po na u a po (larger) u na a tu većeg o na u po a (stack) o u na a hrpe u a po tu o (text-shaping) po a na tu (shaping) u po a tu oblikovanja a o na po (text) a u tu po teksta o u na a po. Kad o u a (line) u na tu a (line) a o tu u na linija po na a (contains) po na a tu u sadrži o a na tu po (scripts) po a na u (scripts) o a na u po a na (scripts) pisma a tu po na u (that reorder or join their glyphs) po a u na tu o koja a po na tu u o (reorder) a u po tu na po o (reorder) u na a po tu preslaguju po a u na o ili u na a po (join) na u po tu a (join) po a u na (join) o na u a po tu a (join) a tu o po u na spajaju o tu na (their glyphs) po a tu u a o po tu na a svoje po u a na o po tu (glyphs) o u na po a u glifove po a u na tu, (the spacing decisions here) o na u po a po u a na tu o a (decisions) o u po a na odluke po a tu u na o (spacing) a po tu u o po tu na o razmacima po tu na u a o u na (here) na u po a tu a (here) na u po a ovdje po a u na (sit on top of the work) po u na a tu (sit on top) po a na u tu (sit) o na u po a (on top) u a po na (on top of) a o u na po počivaju na po a tu na u a po a tu o na po a u po na tu (work) a o na tu u po tu na a radu po a u tu na o (described) o u po na a po u tu opisanom po a tu u na a o (in our article on complex-script text shaping) u na po a tu u (article) a o u po na tu (article) o na a po tu (in our article) a u na po tu članku o na tu a u (our) a po u na po tu u na po o (in our article) a tu u našem u a po na tu članku po a na u o po tu u (complex-script text shaping) na po a u po u na a po (complex-script) o na a u po (complex) na po a tu u složenom a o u po na (script) o po tu na a pismu po a u na tu, a o u (when a font carries typographic variants you want to select) po a tu u na u po a tu na a (when a font) a o u po kad u a po na tu o (font) u na a po tu (font) po u a na (carries) o po a na u (carries) na tu a u po nosi a po na u tu (typographic variants) a po tu o na u na (variants) po na tu u a varijante o a na po tu o (typographic) po u a na tipografske o na tu u po (you want to select) na po tu u a po (want) tu o na a želite na po tu u a (select) po a na u tu o na u tu po (select) po a tu u o na u tu (select) u po a tu o na odabrati na u po tu a o, (see how to drive OpenType GSUB stylistic alternates) po tu na a o u na po (see) po a na u (see) po a tu o na u (see) po a na pogledajte a po tu u na (how to drive OpenType GSUB stylistic alternates) na po tu o u a po o tu u a na o po a tu (drive) a u po tu upravljati na po a u tu a na tu u po (OpenType GSUB stylistic alternates) a tu u po na u a na po (stylistic alternates) po a na u tu stilskim u na a o po alternativama u na po a (OpenType GSUB) po a na u tu OpenType GSUB po u a na tu o u a na. Sve a o u na (All of it ships) o u po na a (ships) na tu u po isporučuje po a na u tu a se (in the HotPDF Component for Delphi and C++Builder) u na a po tu u a o u na po (HotPDF Component) a na u po tu a o po u (Component) po a tu u HotPDF komponenti o a u na po tu (for Delphi and C++Builder) po a na tu u na u po a (for) po tu a za po a u na Delphi i po na a C++Builder po a tu u, (alongside the wider text, layout, and document APIs) po a u na (alongside) po u na a zajedno po tu na a (with) po a tu u sa a o na u po (the wider text, layout, and document APIs) po u na (wider) na u po tu a u na širim o na a tu po (APIs) a u na po tu a na o u API-jima a u na o (text) a u po tu na po o (text) u na a tu po za a u na po tu a na o tekst u na po tu a (layout) po u na a o tu iz o na a u po tu raspored o u po a na u (document) a po tu u na iz po na o dokument o u po na a, o na u po (covered across this blog) u a na po (covered) po a na u pokrivenima po a u tu o (across this blog) na po u a tu u na po o (across) tu na u a po širom o na po tu (this blog) a po tu u ovog a na u po bloga na po tu a