Kubadilisha HTML kuwa PDF huonekana kuwa rahisi kwenye karatasi. Unatengeneza kiolezo (template) kilichoboreshwa, unaweka data yako, na unatarajia hati inayofanana na ukurasa wa wavuti kwa kila piksel. Katika hali halisi, mchakato huo mara nyingi unageuka kuwa mapambano ya kila siku dhidi ya programu kuzima (crashes), alama (glyphs) zinazokosekana, na uharibifu wa picha. Katika mradi wa hivi karibuni, matatizo matatu yaliendelea kujirudia: iText ingezima kabisa ilipokutana na michoro fulani ya SVG, emoji zilipotea na kuwa miraba mweupe isiyo na kitu, na mandhari nyepesi ya uwazi (transparent backgrounds) yaligeuka kuwa vizuizi vyeusi visivyopitisha mwanga. Kila hitilafu ilikuwa na chanzo chake, na kutatua matatizo yote matatu kulihitaji kufikiria upya jinsi programu inavyoandaa maudhui kabla ya injini ya PDF kuyaona.

Wakati SVG Inapovuruga Mchakato

iText inakuja na SVG renderer ya ndani kwa urahisi, lakini muunganisho huo una udhaifu mkubwa. SVG inapokuwa na njia (paths) tata, mitindo mizito ya CSS, au mabadiliko fulani ya kuratibu (coordinate transformations), mchambuzi (parser) aliyewekwa ndani hautoi kosa (exception) la kawaida na kuendelea. Badala yake, unalipuka. Hizi ni programu zinazozima mfumo mzima ambazo huua mchakato (thread) wa kutengeneza PDF bila onyo, kukuachia faili isiyo kamili na stack trace inayoelekeza mahali fulani ndani kabisa ya mchambuzi wa vector.

Suluhisho la kuaminika ni kuacha kuomba iText itengeneze SVG kabisa. Badala yake, hamisha kazi hiyo kwa Apache Batik inayofanya kazi katika hali ya kusimama peke yake (standalone mode). Batik inashughulikia njia tata na sheria za CSS bila ulegevu ule ule, na kuifanya iwe tofauti inalinda injini yako ya PDF dhidi ya kutokuwa thabiti kwa picha. Mtiririko wa kazi ni rahisi: kabla ya uundaji wa hati kuanza, pitisha SVG kupitia Batik ili kuzalisha URL ya data ya PNG. Tumia picha hiyo ya raster kwenye iText badala ya markup ghafi ya vector. Batik ya standalone inafuata maelezo ya SVG kwa karibu zaidi kuliko renderer iliyowekwa ndani ambayo imefungwa ndani ya maktaba kubwa, na kutengwa huku kunamaanisha kuwa picha iliyoharibika haiwezi kusababisha mchakato mzima wa ubadilishaji wa hati kusimama.

Jambo moja dogo huamua ikiwa chati yako itaonekana ya kitaalamu au kama ripoti ya hitilafu (bug report). SVG inategemea sifa ya viewBox ili kufafanua mfumo wake wa kuratibu na tabia ya kurekebisha ukubwa (scaling). Ikiwa kodi yako ya ubadilishaji inapuuza viewBox, chati iliyo sahihi kabisa inaweza kusinyaa hadi kuwa nukta isiyosomika au kutanuka na kuwa vurugu iliyopotoka. Chambua sifa hiyo waziwazi na uunganishe vipimo hivyo na ukubwa wa matokeo yako. Kuruka hatua hii kutapoteza saa nyingi ukirekebisha tatizo la mpangilio (layout) ambalo halina uhusiano na ubora wa rendering bali linahusiana na kukosekana kwa tamko la kuratibu.

Tatizo la Wino Usioonekana

Miraba mitupu ambapo emoji zinapaswa kuwa inatoa habari rahisi: fonti inayotumika haielewi lugha hiyo. Helvetica na fonti nyingine za kawaida za PDF zilikuwepo kabla ya matumizi mapana ya emoji. Hazijajumuisha glyphs kwa ajili ya masafa ya Unicode ya emoji, hivyo iText inapokutana na pointi hizo za kodi, haionyeshi kitu chochote na kuendelea. Matokeo yake ni hati iliyojaa masanduku matupu ambayo hufanya ripoti za hisia za kijamii au matoleo ya maoni ya watumiaji kuonekana yameharibika.

Huwezi kutegemea mfumo wa uendeshaji wa mteja kuziba pengo hilo. PDF hubeba rasilimali zake za fonti, na kile kinachoonekana kuwa sahihi kwenye kivinjari chako hakina maana mara tu faili linapotenganishwa na fonti za mfumo wako. Suluhisho ni kujenga tabaka la wazi la uelekezaji wa fonti (font routing layer). Sajili fonti maalum inayoweza kushughulikia emoji kama Symbola, ambayo hutoa alama za rangi moja (monochrome) zinazofunika vizuizi vya Unicode vya emoji. Moyo mweusi na mweupe au alama ya onyo inaweza kukosa urembo wa seti ya rangi, lakini inawasilisha maana. Mraba mtupu unawasilisha kushindwa. Fonti za emoji za rangi kamili bado ni ngumu kuonyeshwa kwa uthabiti ndani ya vionyeshaji vya PDF, na kutafuta uunganishaji wa rangi mara nyingi huleta matatizo zaidi ya utangamano kuliko yanayotatuliwa.

iText inaongeza tatizo la pili, baya zaidi, kupitia ulijaji wa mistari (line breaking). Maktaba inaweza kutenganisha emoji surrogate pairs kwenye mpaka usio sahihi, ikipasua herufi moja kuwa sehemu mbili zisizofaa. Hapo inapotokea, mtiririko wa maandishi unaharibika na unakuja na vipande visivyosomika mahali ambapo glyph moja ilipaswa kuwepo. Ili kuzuia hili, tekeleza ISplitCharacter maalum inayotambua surrogate pairs na kuzichukulia kama vitengo vya atomiki. Hii inazuia injini ya mpangilio kuingiza mrejari (line break) katikati ya emoji na kuhifadhi uadilifu wa maandishi.

Wakati Uwazi Unageuka Kuwa Nyeusi

SVG yenye mandhari laini ya rgba au athari ya fill-opacity ya tabaka inapoonekana vizuri kwenye kivinjari. Ikiwa utapeleka markup hiyo hiyo kwenye iText, uwazi mara nyingi hugeuka kuwa mraba mweusi thabiti. Injini inashughulikia vibaya kazi za rangi za CSS na sifa za opacity, ikibadilisha opacity na wino wenye msongamano kamili.

Kuuchakata SVG kabla haujafika kwenye kigeuzi (converter) ndiyo ulinzi pekee unaoweza kuaminika. Ondoa au badilisha kipengele chochote kinachotegemea alpha blending. Badilisha thamani za rgba() kuwa rangi thabiti za rgb(). Ikiwa ni lazima ubaki na dhana fulani ya opacity, hamisha thamani kutoka kwenye CSS shorthand na uziweke kwenye sifa za kawaida za opacity, ingawa kuondoa uwazi (transparency) kabisa ndiyo njia salama zaidi. Mabadiliko haya yanaonekana kama hatua ya nyuma kwa usanifu wa wavuti, lakini PDF hutumia mfumo tofauti wa picha ambao ulikuja kabla ya uwazi wa CSS wa kisasa. Muundo huu unatarajia thamani thabiti za rangi, na kuupa thamani zisizoeleweka huleta maafa.

Unapofanya usafishaji wa markup, hakikisha tena kwamba kila SVG ina tamko sahihi la xmlns namespace. HTML iliyotengenezwa na injini za template mara nyingi hupoteza sifa za namespace wakati wa minification au DOM serialization. Bila namespace hiyo, SVG parser inaweza kutambua vibaya vipengele au kushindwa bila kutoa taarifa, ikisababisha hitilafu ya parser au data ya vector iliyoharibika ambayo haifiki kwenye ukurasa. Ni ukaguzi wa msingi unaochukua sekunde chache na kuokoa saa nyingi.

Template Moja, Dunia Mbili

Suluhisho baya zaidi la muda mrefu ni kudumisha template za HTML tofauti kwa ajili ya kivinjari (browser) na PDF. Lebo zinabadilika, pembe (margins) zinabadilika, na hivi karibuni ripoti iliyochapishwa hailingani tena na dashboard. Usanifu safi zaidi unategemea template moja na unagawa mantiki ya rendering kwa kutumia flag moja, kama vile context.isForPdf().

Wakati flag hiyo ikiwa ni false, template inatoa uzoefu kamili wa kivinjari. Inatoa SVG asilia kwa zoom isiyo na kikomo, CSS ya kisasa, na rasilimali za rangi yoyote ambayo kivinjari inaiunga mkono. Wakati flag hiyo ikiwa ni true, template hiyo hiyo inabadilisha rasilimali za SVG na PNG zilizochakatwa mapema, huwasha font stack salama kwa emoji, na huondoa madoido yoyote ya uwazi (transparency) ambayo hayajaungwa mkono. Maandishi na muundo unabaki vilevile; ni asset pipeline na sheria za styling pekee zinazobadilika kulingana na lengo.

Mtazamo huu wa njia mbili unaweka codebase katika hali ya uaminifu. Unasasisha maudhui mahali pamoja, na tabaka la routing hushughulikia tofauti za kimekanika kati ya skrini na karatasi. Pia inafanya majaribio kuwa rahisi zaidi. Unaweza kuhakiki mantiki ya template kwenye kivinjari ukitumia zana kamili za developer tools, kisha uwashe flag ya PDF na kuthibitisha kwamba data ileile inazalisha hati safi bila kuharibu kigeuzi (converter).

Ukweli Mchungu Kuhusu Uundaji wa PDF

PDF haitawahi kufanya kazi kama kivinjari. Mifumo ya rendering ni tofauti kimsingi, na maktaba kama iText hufanya maamuzi ya makusudi kati ya kasi, ukubwa wa faili, na uzingatiaji wa specification. Mafanikio hayatokani na kupambana na injini na kutumaini matokeo bora. Yanatokana na kukubali mipaka mapema na kuunda pipeline inayozingatia mipaka hiyo.

Badilisha vector zako kabla ya hatua ya PDF. Elekeza font zako waziwazi ili kila glyph iwe na fallback. Ondoa uwazi na urudishe kwenye rangi thabiti. Pa template zako muktadha unaohitaji ili zijue ni ulimwengu upi zinazofanya rendering. Fanya hivi kwa uthabiti, na hati zako zitaacha kupambana na renderer na kuanza kuonekana vile vile ulivyokusudia.