Tehnički članak

Oblikovanje arapskog i RTL teksta u Delphi PDF-ovima uz HotPDF

Proslijedite arapsku frazu يوضح ملف PDF pozivu TextOut i otvorite rezultat. Slova teku u pogrešnom smjeru, i svako od njih nalazi se u svom izoliranom obliku s vidljivim razmakom prije sljedećeg, kao da je netko utipkao engleski naopako i pritisnuo razmaknicu između svakog znaka. Nije se oglasila nikakva iznimka. Nije ispisano nikakvo upozorenje. Izlaz je jednostavno pogrešan, a pogrešan je zato što se dvije zasebne transformacije o kojima arapski jezik ovisi nikada nisu dogodile. Poznavanje onoga što su te dvije transformacije, i koji poziv ih izvodi, čini većinu onoga na što se svodi PDF izlaz za složena pisma

HotPDF je izvorna VCL PDF komponenta za Delphi i C++Builder, te umjesto vas obavlja posao obrade s desna na lijevo putem posebnog poziva. Također se zaustavlja na nekoliko specifičnih mjesta kojih biste trebali biti svjesni prije nego što se obvežete na određenu lokalizaciju, pa ovaj tekst mapira koncepte i iskrene granice; praktično postavljanje za sam poziv nalazi se u RtLTextOut referentnom članku

Zašto se ispravan niz i dalje pogrešno ispisuje

Unicode čuva tekst u logičkom redoslijedu, onom kojim ga upisujete i čitate naglas. Program za iscrtavanje mora postaviti glifove u vizualni redoslijed. Za pisma s lijeva na desno ti se redoslijedi podudaraju i nitko o tome ne razmišlja. Za arapski i hebrejski to nije slučaj, a kada jedna linija miješa smjerove, recimo arapska rečenica koja sadrži latinični znak "PDF" ili cijena napisana u znamenkama, Unicode algoritam za dvosmjernost (UAX #9) odlučuje točno kako se fragmenti s lijeva na desno ugnježđuju unutar linije s desna na lijevo. To je prva transformacija, preuređivanje, a njeno preskakanje je ono što preokreće liniju

Druga je kontekstualno oblikovanje. Arapsko slovo se crta drugačije ovisno o tome gdje se nalazi u riječi: na početku, u sredini, na kraju ili stoji samostalno. Kodna točka ostaje ista tijekom cijelog procesa; mijenja se samo glif. Cjevovod (pipeline) koji predaje svaku kodnu točku ravno svom zadanom glifu proizvodi upravo onaj nepovezani izlaz u izoliranom obliku iz uvodnog odlomka. Hebrejski preskače ovaj korak, budući da se njegova slova ne spajaju, ali mu i dalje treba preuređivanje. Arapski treba oboje, i to je razlog zašto je arapski, a ne hebrejski, niz s kojim testirate

Na radnoj površini ništa od ovoga nije vaš problem. Kada VCL obrazac iscrtava arapski u TEdit, operativni sustav za obradu teksta to tiho preuređuje i oblikuje, što je upravo razlog zašto niz koji izgleda savršeno na ekranu izlazi slomljen u naivnom PDF-u. Tok sadržaja ne pohranjuje tekst koji se može uređivati. On pohranjuje pozicionirane glifove, tako da onaj tko emitira tok preuzima posao oblikovanja kojim se operativni sustav inače bavio. RtLTextOut je poziv koji taj posao uzima natrag

Što RtLTextOut oblikuje za vas

HotPDF zadržava latiničnu putanju i putanju složenog pisma kao dvije različite metode. TextOut ispisuje ono što mu date onim redoslijedom kojim mu date. RtLTextOut prvo izvodi obje transformacije — dvosmjerno preuređivanje preko cijele linije, kontekstualnu analizu za pisma koja se spajaju — a zatim ispisuje. Pravila kojeg pisma se primjenjuju putuju kroz skup znakova fonta, a ne kroz sam poziv, pa je smjer eksplicitan izbor na svakom mjestu poziva, a ne nagađanje temeljeno na znakovima. Postavljanje parametar po parametar, vrijednosti skupa znakova, koraci registracije fonta i cjelovit primjer koji se može kompajlirati nalaze se u RtLTextOut referentnom članku; ovaj dio zadržava se na onome što transformacije znače, gdje se zaustavljaju i kako dokazati da su uspjele

Jedno pravilo korištenja bitno je čak i na ovoj visini: ulaz mora biti u logičkom redoslijedu, jer RtLTextOut sam izvodi preokretanje, a niz koji ste već ručno preokrenuli izlazi dvostruko preokrenut — referentni članak prolazi kroz tu zamku i njeno čišćenje. Ono što ovdje zaslužuje spomen ove zamke je razlog zašto ona preživljava testiranje. Dvostruko preokrenuti čisti arapski niz može izgledati savršeno ispravno, a raspada se tek kada linija nosi latiničnu riječ ili broj, jer se ti umetnuti nizovi više ne ugnježđuju onako kako diktira UAX #9. Greška nije u iscrtavanju; ona je u davanju teksta algoritmu koji je već bio napola obrađen

To isto ponašanje miješanog smjera spotakne recenzente češće nego što spotakne kôd. Unutar linije s desna na lijevo, znamenke i umetnute latinične riječi još uvijek se čitaju s lijeva na desno. Netko tko nije radio s dvosmjernim izgledom pogledat će iscrtani račun, vidjeti broj računa kako se čita na "pogrešan" način u odnosu na arapski oko njega i prijaviti to kao grešku. To je rezultat ispravan prema specifikaciji. Kratka napomena u vašim kriterijima prihvaćanja, napisana prije prvog pregleda izvornog govornika, spašava taj povratni ciklus

Kada su preuređivanje i spajanje dovoljni, a kada nisu

Za arapski i hebrejski tekući tekst — izvještaje, račune, ugovore, pisma — preuređivanje plus kontekstualno spajanje je cijeli posao, i RtLTextOut ga nosi samostalno. Granica se pojavljuje kada tipografija zahtijeva više od spajanja. Odgovor HotPDF-a na arapskoj strani je alat za oblikovanje na strani proizvođača na zahtjev (opt-in): postavite AutoShapeArabic := True i komponenta prepisuje niz u logičkom redoslijedu u Unicode prezentacijske oblike prije dvosmjernog prolaza, tako da se oblici spajanja izračunavaju prema logičkim susjedima i nabori ligatura peku u kodne točke koje PDF zapravo nosi, umjesto da ih ostavlja pregledniku za rješavanje. Prekidač je prema zadanim postavkama isključen, a izlaz je stabilan u bajtovima kada ostane isključen, pa je njegovo uključivanje namjerna odluka po cjevovodu dokumenta, a ne globalna nadogradnja. Isti opt-in model proteže se na ostala pisma s desna na lijevo koja se spajaju i koja HotPDF oblikuje: sirjački, N'Ko, adlam i hanifi rohingya svako ima vlastitu zastavicu za automatsko oblikovanje koja preslikava onu arapsku

Neobavezna svojstva OpenTypea opet su drugačiji mehanizam. Diskrecijske ligature i slična svojstva pojedinačne zamjene prolaze kroz GetSingleSubstituteGlyph(GID, 'liga'), koji rješava jednu po jednu zamjenu — prvo ID ulaznog glifa, zatim oznaku svojstva — i vraća ulazni glif nepromijenjen kada se svojstvo ne primjenjuje. To je dovoljno da pokreće poznat, konačan popis ligatura koji sami održavate. To nije potpuni GSUB mehanizam, a razlika je upravo ono gdje ambiciozni planovi za lokalizaciju pođu po zlu: cjevovod za oblikovanje koji besprijekorno rukuje arapskim jezikom pokazao je preuređivanje i spajanje, i ništa više

Pokrivenost kroz pisma

Arapski jezik vježba obje transformacije, što je razlog zašto je to niz s kojim se testira, i zašto je prolaz arapskog jezika najjači pojedinačni dokaz da cjevovod radi. Hebrejskom jeziku potrebno je preuređivanje, ali ne i spajanje, budući da njegova slova stoje sama za sebe; ako se hebrejski ispravno iscrtava, a arapski izlazi nepovezan, dvosmjerna polovica je u redu, a kontekstualna polovica nikada se nije pokrenula. Perzijski i urdu jašu na arapskom pismu i nasljeđuju njegovo ponašanje, iako je preferencija urdu jezika za stil Nastaliq odluka o fontu s posljedicama za čitljivost koje bi izvorni čitatelj trebao prosuditi

Tajlandski jezik u potpunosti stoji s druge strane linije. Teče s lijeva na desno, tako da mu ne treba dvosmjerni rad, a njegova se slova ne spajaju, tako da mu ne treba kontekstualna analiza; tajlandski nizovi idu kroz običnu putanju TextOut poput latiničnih. Ono što tajlandski ima su naslagane oznake — samoglasnici i oznake tona iznad i ispod osnovnog suglasnika — a da li one sjede ispravno ovisi o fontu koji gradi svoje kombinirajuće oznake za slaganje bez pomoći mehanizma za oblikovanje. Većina namjenskih tajlandskih fontova to čini. Testirajte s točno onim fontom koji ćete ugraditi, a ne s nečim što sliči

Devanagari i ostatak indijske obitelji predstavljaju pravo, tvrdo zaustavljanje. Njihovi znakovi samoglasnika preuređuju se oko skupina suglasnika, a njihovi se veznici formiraju kroz lance zamjena ovisnih o kontekstu, što je područje punog GSUB-a, izvan preuređivanja i spajanja. Ako je indijska lokalizacija na rasporedu, pokrenite pravi probni projekt na autentičnim nizovima korisnika prije nego što ga obećate — to što arapski jezik radi nije dokaz da će devanagari raditi. CJK nizovi, vijetnamski sa svojim naslaganim dijakritičkim znakovima i miješani europski tekst idu običnom putanjom bez dvosmjerne analize, a isplati se fizički držati te dvije putanje odvojenima u kodu izvještaja, jedna rutina za RTL nizove i jedna za sve ostalo, tako da logika lokalizacije bude vidljiva na mjestu poziva umjesto skrivena iza zastavice koju netko zaboravi postaviti

Pokrivenost glifovima određuje se prije nego što se oblikovanje uopće pokrene

Oblikovanje bira glifove iz fonta. Ako ih font ne nosi, nema se što odabrati, što je razlog zašto je klasični neuspjeh u postavljanju — besprijekoran na stroju programera, prazni okviri na serveru korisnika nakon tihe zamjene fonta — problem s pokrivenošću, a ne problem s oblikovanjem. Praktični lijek, registriranje fonta koji isporučujete umjesto oslanjanja na ono što je stroj instalirao, opisan je korak po korak u referentnom članku. Konceptualna točka je da se pokrivenost mora uspostaviti prije nego što ikakvo pitanje oblikovanja uopće postane smisleno, i da se može uspostaviti programski umjesto da se izlaz procjenjuje odokativno

// Nakon RegisterUnicodeTTF, provjerite pokrivenost za
// kodne točke koje vaši podaci zapravo koriste
GID := Pdf.GetUnicodeGlyphForCodepoint($0628);  // U+0628 ARABIC LETTER BEH
LogGlyphAudit($0628, GID);

Sama registracija nosi dva ograničenja — prag PDF-a 1.5 za ugrađeno rukovanje Unicodeom i bitove dozvole za ugrađivanje fonta — oba obrađena zajedno s koracima za postavljanje u RtLTextOut referentnom članku. Ono što ovdje pripada je navika revizije: GetUnicodeGlyphForCodepoint je vaš sustav ranog upozoravanja. Prođite kroz raspone kodnih točaka koje vaši podaci zapravo koriste pri pokretanju usluge i zabilježite koji se ID-ovi glifova vraćaju. Praznina u pokrivenosti tada se pojavljuje kao redak u zapisniku pri pokretanju tijekom uvođenja, umjesto kao znakovi koji nedostaju u računu koji je već stigao do kupca

Redoslijed čitanja pripada dokumentu, a ne glifovima

Kada dobijete svaki glif točnim, još uvijek ostaje jedna stvar neurađena. ISO 32000-1 §12.2 definira preferenciju preglednika zvanu /Direction koja navodi opći redoslijed čitanja dokumenta. To ne utječe na glifove. Ono što radi je da govori pregledniku kako da uredi prikaz po dvije stranice (spread), s koje strane bi trebao početi raspored stranica koje su okrenute jedna prema drugoj, i na koju stranu bi korisničko sučelje za čitanje trebalo naginjati. Ništa od toga se ne vidi na jednoj stranici, što je upravo razlog zašto se to zaboravlja

// Deklarirajte redoslijed čitanja s desna na lijevo na razini dokumenta
Pdf.Direction := RightToLeft;  // dodaje vpDirection u ViewerPreferences

Postavljanje Direction je cijeli posao: postavljač (setter) svojstva dodaje vpDirection u ViewerPreferences dokumenta, tako da jedan redak unosi preferenciju u datoteku. Ako tekst ide van kroz RtLTextOut, to dobivate besplatno, jer poziv mijenja smjer dokumenta kao nuspojavu — referentni članak pokriva kada za miješani dokument to treba poništiti. Slučaj u kojem to morate sami postaviti je dokument s desna na lijevo proizveden na bilo koji drugi način, na primjer iz ulaza koji ste unaprijed oblikovali uzvodno i iscrtali uobičajenom putanjom. Izostavite to i dokaz za jednu stranicu u koji buljite izgleda identično u oba slučaja; tada netko ispiše obostranu knjižicu, pripremljene stranice (spreads) izađu zrcaljene, a uzrok je jedan redak koji nedostaje od prije nekoliko tjedana

Provjera oblikovanog izlaza

Provjerite od početka do kraja, jer stranica može izgledati ispravno, a i dalje biti beskorisna za sve nizvodno. Tri provjere pronalaze većinu problema. Kopirajte tekst natrag iz Acrobata i usporedite kodne točke sa svojim izvornim nizom. Pokrenite pretragu unutar dokumenta u pregledniku za riječ koju možete vidjeti na stranici. I otvorite izlaz na stroju koji nema vaše razvojne fontove, stroju koji će najvjerojatnije otkriti zamjenu fontova. Ništa od toga ne zamjenjuje izvornog govornika koji gleda u pravi dokument, što hvata stvari koje nijedan sintetički korpus neće. Zakažite taj pregled na kalendar prije nego što format krene u isporuku

S namjerom birajte testne nizove umjesto recikliranja onoga što je prevoditelj poslao prošle godine. Djelotvorni minimum po lokalizaciji: čista rečenica na pismu, rečenica s ugnježđenim latiničnim imenima robnih marki, linija koja nosi znamenke i valutu, te imena s dijakritičkim znakovima ili znakovima koji se kombiniraju. Stvarna imena korisnika razbijaju pretpostavke koje probni tekst ostavlja netaknutima, stoga neka skup regresija raste za po jedan niz svaki put kad slučaj podrške iznese uzorak koji niste prije vidjeli

Registracija fonta, stvaranje podskupa (subsetting) i API za svakodnevno crtanje teksta obrađeni su u članku o izlazu izvještaja, fontovima i slikama s HotPDF-om. Kada ti isti dokumenti moraju ispuniti i profile pristupačnosti, pravila o označavanju jezika i strukturi u članku o validaciji PDF/A i PDF/UA sjede na vrhu rada na oblikovanju koji je ovdje

API-ji fontova za pisanje s desna na lijevo i Unicode fontova opisani gore isporučuju se uz HotPDF komponentu za Delphi i C++Builder; stranica proizvoda povezuje potpunu referencu za izlaz teksta