Odborný článok

Vertikálny japonský a čínsky text v PDF s Delphi

PDFlibPas kreslí japonský a čínsky text zhora nadol po strane. SetVerticalWritingMode zapne vertikálny zápis, bežné volania DrawText následne bežia nadol a GetVerticalWritingMode hlási aktuálny stav. Kým toto existovalo, znamenalo vertikálne nastavenie textu umiestniť každý znak ručne a dúfať, že rozostupy budú vyzerať správne

Vertikálny zápis nie je horizontálny text otočený o deväťdesiat stupňov. Znaky zostávajú vzpriamené, postup beží nadol namiesto vodorovne a viacero znakov mení tvar úplne — čo je časť, ktorá oddeľuje dokument čitateľný prirodzene od dokumentu, ktorý japonský čitateľ okamžite rozpozná ako strojovo vyrobený

Čo sa mení vo vnútri PDF

Text kreslený týmto spôsobom prechádza Type0 fontom v režime vertikálneho zápisu, ktorý nesie vlastné vertikálne metriky rezu. To je dôležité v oboch smeroch. Čítačka posúva každý znak o vzdialenosť, ktorú navrhol jeho autor, a nie o jednotný krok, takže stĺpec má rytmus, pre ktorý bol typografický rez navrhnutý. A skopírovanie textu von vráti pôvodné znaky, pretože vertikálny beh je stále skutočný text so správnym mapovaním a nie sekvencia umiestnených glyphov

Rez, ktorý nenesie žiadne vlastné vertikálne metriky, posúva sa o jeden em na znak, čo je to, čo by urobila čítačka s predvolenou hodnotou. Tento fallback sa oplatí poznať, pretože je to rozdiel, ktorý uvidíte, keď dokument renderuje správne s riadnym CJK rezom a pôsobí mechanicky rozmiestneným s latinským rezom, ktorý sa náhodou obsahuje niekoľko kana

var
  Lib: TPDFlib;
  H: Double;
begin
  Lib := TPDFlib.Create;
  try
    Lib.SetOrigin(1);
    Lib.AddTrueTypeFont('MS Mincho', 1);      // 1 = embed the face
    Lib.SetTextSize(12);
    Lib.SetVerticalWritingMode(1);            // ordinary DrawText now runs down
    H := Lib.GetVerticalTextHeight('MS Mincho', 12, '第三章 保守点検');
    Lib.DrawText(480, 72, '第三章 保守点検');
    Lib.SetVerticalWritingMode(0);            // back to horizontal
    Lib.DrawText(72, 72 + H, 'Chapter 3');
    Lib.SaveToFile('manual-ja.pdf');
  finally
    Lib.Free;
  end;
end;

Prečo zátvorky v vertikálnom texte vyzerajú zle?

Pretože zátvorka má dve formy a v stĺpci patrí iba jedna z nich. Zátvorky, značka dlhej samohlásky a malé kana sa kreslia odlišne, keď text beží nadol po strane — zátvorka sa otočí, aby sedela pozdĺž stĺpca namiesto toho, aby ležala naprieč, a značka dlhej samohlásky sa stane vertikálnou čiarou. Nakreslite horizontálne formy do vertikálneho stĺpca a každá z nich bude ležať na boku

PDFlibPas berie formy z vlastnej vertikálnej vlastnosti fontu, takže každý rez dodáva to, čo nakreslil jeho autor, a nie substitúciu hádanú zo znaku. Toto rozlíšenie je dôležité pre správnosť: hádací tabuľka substitúcií má pravdu v bežných prípadoch a mýli sa pri rezoch, ktoré so znakom zaobchádzajú inak, a rez, ktorý neuvedie žiadne vertikálne formy, je kreslený presne tak ako predtým, namiesto toho, aby bol pretlačený tabuľkou, o ktorú nežiadal

GetVerticalTextHeight meria formy, ktoré budú skutočne nakreslené, takže stĺpec, ktorého znaky menia tvar, je stále nameraný správne. Meranie horizontálnych foriem a kreslenie vertikálnych je klasickým zdrojom stĺpcov, ktoré o niekoľko znakov presahujú svoj rámec

Kreslenie jedného behu bez zmeny režimu

DrawVerticalText kreslí jeden beh vertikálne, prijíma pozíciu, názov fontu, veľkosť a text a nechá režim zápisu na pokoji. Použite ho pre vertikálnu výnimku vo vnútri horizontálneho dokumentu — chrbtovú etiketu, pečiatku, jeden stĺpec mien — kde zapínanie a vypínanie globálneho režimu okolo každého volania prináša viac stavu, než si úloha zaslúži

Horizontálne a vertikálne formy jedného rezu sa vnútorne držia oddelene, takže jedna strana môže niesť obe bez toho, aby sa navzájom ovplyvňovali. To je to, čo robí zmiešanú stranu praktickou: japonská knižná strana s vertikálnym telom textu a horizontálnymi hlavičkami, alebo čínsky certifikát s vertikálnym titulom nad horizontálnymi detailnými riadkami

// One vertical run inside an otherwise horizontal page
Lib.DrawVerticalText(520, 96, 'MS Mincho', 14, '保守点検記録');
// The horizontal text around it is unaffected
Lib.DrawText(72, 96, 'Maintenance inspection record');

Správa fontu predovšetkým

Vertikálny zápis závisí celkom od rezu. CJK font s riadnymi vertikálnymi metrikami a vertikálnou vlastnosťou produkuje správny výstup bez ďalšej práce; font bez nich produkuje vzpriamené znaky posúvajúce sa o jeden em bez akejkoľvek zmeny tvaru. Ak vertikálny text pôsobí jemne nesprávne, skúmajte najprv font a až potom kód

Vkladanie fontu sleduje bežné pravidlá a bežné náklady. Plný CJK rez je veľký, takže subsetting nie je voliteľný pre dokumenty, ktoré idú hocikam — poznámky k optimalizácii veľkosti PDF a subsettingu fontov popisujú, čo očakávať, a návod k vkladaniu chýbajúcich fontov do existujúceho PDF pokrýva opravný prípad, keď vertikálny dokument príde bez svojich fontov

Kde vertikálny text stále potrebuje vaše rozhodnutie o rozvrhnutí

Poradie stĺpcov. Japonský vertikálny text beží sprava doľava po stĺpcoch, takže dvojstĺpcová strana začína pri pravom okraji a žiadne nastavenie režimu zápisu to nedokáže odvodiť z textu. To isté platí na poradie strán v dokumente, ktorý sa ako celok číta sprava doľava, a na to, kde sedia furigana, poznámky pod čiarou a popisy obrázkov

Čo knižnica garantuje, je, že každý beh je nastavený správne: správne formy, správne postupy, extrahovateľný text. Kam behy na strane smerujú, je problém rozvrhnutia a pre dokumenty zložené z dát je návod k vyhľadávaniu textu a enumerácii elementov strany užitočný na neskoršie overenie, že to, čo skončilo na strane, je to, čo ste zamýšľali

PDFlibPas je natívna Pascal PDF knižnica pre Delphi, C++Builder a Lazarus a vertikálny CJK zápis je súčasťou API kreslenia a nie doplnkom — zoznam textových a fontových funkcií nájdete na produktovej stránke PDFlibPas