PDFlibPas naleje uchovanú pasáž do jedného až 64 stĺpcov rovnakej šírky pomocou DrawTextFlowColumns a jej riadky láme s ohraničeným jazykovo citlivým delením slov, keď zavoláte SetTextFlowLanguage a SetTextFlowHyphenation. Podporovaných je deväť jazykov a jazyk sa dá zdediť z hodnoty /Lang v Catalogu dokumentu namiesto nastavovania pre každý tok zvlášť
Obe funkcie existujú z rovnakého dôvodu: úzky stĺpec je miesto, kde naivné lámanie riadkov prestáva vyzerať ako sadzba a začína vyzerať ako hlásenie o chybe
Prečo sa zarovnaný text v úzkych stĺpcoch rozpadá?
Pretože zarovnávanie do bloku rozdeľuje zvyšný priestor do medzier medzi slovami na riadku, a to, koľko priestoru zvýši, závisí od toho, čo sa zmestí. Pri širokom stĺpci je zvyšok malý a oko si ho nikdy nevšimne. Zmenšite šírku na polovicu a jedno dlhé slovo, ktoré sa už nezmestí, sa presunie na ďalší riadok — a slová pred ním musia pohltiť celý ten priestor. Tri takéto riadky za sebou vytvárajú zvislé biele kanály, ktoré typografi nazývajú rieky, a čitatelia ich vnímajú ako text, ktorý sa ťažko sleduje, hoci nevedia prečo
Delenie slov rieši príčinu, nie symptóm, tým, že umožní zlom vo vnútri slova. Nemecké a holandské zložené slová to robia nevyhnutným: 24-znakové podstatné meno v 60-milimetrovom stĺpci nemá dobrý výsledok bez miesta na zlom. Angličtina absenciu delenia znáša lepšie, a preto produkty orientované najprv na angličtinu často dodávajú kód rozloženia, ktorý sa zrúti hneď pri prvom nemeckom zákazníkovi
Ktoré jazyky, a odkiaľ sa jazyk berie?
Delenie slov pokrýva angličtinu, nemčinu, holandčinu, francúzštinu, španielčinu, taliančinu, portugalčinu, ruštinu a turečtinu. Nastavte ho explicitne pre každý tok pomocou SetTextFlowLanguage, alebo ho nechajte zdediť z položky /Lang v Catalogu dokumentu — hodnoty, ktorú označený a prístupný dokument už aj tak nesie
Toto dedenie sa oplatí využívať namiesto prepisovania. Dokument, ktorý deklaruje svoj jazyk v Catalogu, oznamuje čítačkám obrazovky, vyhľadávacím indexerom aj deleniu slov ten istý fakt z jedného miesta, a jedno miesto je presne tam, kde má fakt žiť. Ak už produkujete označený výstup opísaný v článku automatické značkovanie prístupných PDF, položka jazyka je nastavená a tok ju môže jednoducho nasledovať
var
Lib: TPDFlib;
Flow, Drawn: Integer;
begin
Lib := TPDFlib.Create;
try
Lib.SetOrigin(1);
Lib.AddTrueTypeFont('Georgia', 1);
Lib.SetTextSize(10.5);
Flow := Lib.NewTextFlow(ArticleBody);
try
Lib.SetTextFlowLanguage(Flow, 'de');
// Zapnúť, aspoň 3 znaky pred zlomom, 3 za ním
Lib.SetTextFlowHyphenation(Flow, 1, 3, 3);
Lib.SetTextFlowMinLines(Flow, 2); // nikdy nenechať osamotený jeden riadok
repeat
// Tri stĺpce v oblasti 480 pt, 18 pt medzery, vyvážené
Drawn := Lib.DrawTextFlowColumns(Flow, 72, 720, 480, 620, 3, 18, 1);
if (Drawn = 0) or (Lib.TextFlowFinished(Flow) = 1) then
Break;
Lib.NewPage;
until False;
finally
Lib.ReleaseTextFlow(Flow);
end;
Lib.SaveToFile('newsletter.pdf');
finally
Lib.Free;
end;
end;
MinPrefix a MinSuffix sú typografia, nie validácia
Dve celé čísla za príznakom zapnutia určujú minimálny počet znakov, ktoré musia zostať pred zlomom a za ním. Tri a tri je konzervatívna predvolená hodnota, ktorú akceptuje väčšina firemných štýlov. Dve a dve dáva viac možností na zlom a citeľne škaredšie výsledky, pretože dvojpísmenový zvyšok visiaci na konci riadku pôsobí ako preklep
Minimá zvýšte, keď je písmo veľké, kde je každý zvyšok vizuálne nápadný, a znížte ich iba vtedy, keď je stĺpec naozaj úzky a rozhodli ste sa, že tesná sadzba je dôležitejšia než čistá. Ide o rozhodnutie firemného štýlu, nie technické — a presne preto je to parameter, nie konštanta
Čo tu vlastne znamená „vyvážené“?
Parameter Balance mení správanie len na konci pasáže. Keď je vyvažovanie zapnuté, stĺpce sa skrátia na presne rovnaký počet riadkov vtedy, keď sa všetko zvyšné zmestí do danej oblasti — a práve to zabraňuje tomu, aby posledná strana ukázala dva plné stĺpce a tretí s jedným osamoteným riadkom. Keď sa pasáž nezmestí, každý stĺpec si ponechá plnú výšku, takže strana nesie čo najviac textu a zvyšok pokračuje na ďalšej strane
Táto asymetria je správna predvoľba pre plynulé dokumenty. Vyvažovanie uprostred plynúceho článku by na každej strane plytvalo zvislým priestorom kvôli kozmetickému efektu, ktorý si nikto nevšimne, keďže stĺpce sú aj tak plné. Vyvažovanie na konci je miesto, kde si to oko naozaj všimne, a presne tam sa aj uplatňuje
Lámanie riadkov meria celé slová
Algoritmus lámania meria celé slová namiesto sčítavania šírok jednotlivých znakov a vyhradzuje ohraničené hľadanie pre nadmerne dlhé tokeny, ktoré sa na riadok vôbec nezmestia, ako je URL adresa alebo evidenčné číslo. Vďaka tomu je bežný prípad rýchly a patologický prípad ohraničený — nie naopak
Voliteľné mäkké spojovníky a automatické spojovníky sa vykreslia iba vtedy, keď zlom, ktorý označujú, je aj skutočne vybraný zlom. Znie to samozrejme a ide o klasickú chybu: naivná implementácia zapíše znak spojovníka už počas merania, a ak sa zlom presunie, spojovník ostane visieť uprostred riadku. Nič nevyzerá viac ako pokazený textový engine než zablúdený spojovník uprostred slova
var
Lib: TPDFlib;
Flow, Needed: Integer;
begin
// Rozhodnite o rozložení skôr, než čokoľvek nakreslíte
Flow := Lib.NewTextFlow(ArticleBody);
try
Lib.SetTextFlowLanguage(Flow, 'fr');
Lib.SetTextFlowHyphenation(Flow, 1, 3, 3);
// Počet riadkov, ktoré zvyšok pasáže potrebuje pri šírke jedného stĺpca
Needed := Lib.MeasureTextFlow(Flow, 148);
if Needed > 3 * LinesPerColumn then
UseTwoPageSpread
else
UseSinglePage;
Lib.DrawTextFlowColumns(Flow, 72, 720, 480, 620, 3, 18, 1);
if Lib.TextFlowFinished(Flow) <> 1 then
CarryOver(Lib.GetTextFlowRemaining(Flow));
finally
Lib.ReleaseTextFlow(Flow);
end;
end;
Udržujte nastavenia písma identické naprieč rámčekmi
Jedno pravidlo riadi každé rozloženie založené na toku a stojí za to povedať ho na rovinu: DrawTextFlow, DrawTextFlowColumns aj MeasureTextFlow lámu riadky pomocou písma, ktoré je vybrané v okamihu ich volania. Zmeňte písmo alebo veľkosť medzi dvoma rámčekmi toho istého toku, alebo začnite novú stranu bez opätovného výberu písma, a druhý rámček sa zalomí inak, než čo zmeral prvý
Príznak je znepokojivý práve preto, že vyzerá nesúvislo: text, ktorý sa zmestí na prvú stranu, na druhej pretečie, alebo zmeraný počet riadkov nesúhlasí s tým, čo sa nakreslilo. Vyberte písmo raz pred slučkou, znovu ho vyberte po každom NewPage, a tok sa bude správať predvídateľne. Keď sa v jednej pasáži zmiešajú viaceré písma, riešenie opísané v článku automatické náhradné písma pre CJK a emoji text platí rovnako pre meranie aj kreslenie, takže šírky ostávajú konzistentné aj naprieč náhradnými behmi
Pri rozloženiach reportov, kde je tok len jedným prvkom medzi hlavičkami, pätami a blokmi riadenými dátami, sa vzory skladby z článku report engine nad datasetom čisto kombinujú so stĺpcovými tokmi: najprv zmerajte, umiestnite pevné prvky a tok potom dostane akúkoľvek zvyšnú oblasť
PDFlibPas je knižnica PDF pre Delphi, C++Builder a Lazarus a celý životný cyklus TextFlow — vytvorenie, kreslenie, meranie, inšpekcia, návrat na začiatok a uvoľnenie — je dostupný aj cez rozhrania DLL a ActiveX. Úplná dokumentácia je na stránke PDFlibPas Delphi PDF library