Techninis straipsnis

Vertikalus japonų ir kinų tekstas PDF su Delphi

PDFlibPas braižo japonų ir kinų tekstą puslapiu žemyn. SetVerticalWritingMode įjungia vertikalų rašymą, tuomet paprasti DrawText kvietimai eina žemyn, o GetVerticalWritingMode praneša esamą būseną. Kol to nebuvo, vertikaliai išdėstyti tekstą reiškė kiekvieną simbolį padėti rankiniu būdu ir tikėtis, kad tarpai atrodys teisingai

Vertikalus rašymas nėra horizontalus tekstas, pasuktas devyniasdešimt laipsnių. Simboliai lieka statmeni, pažanga eina žemyn, o ne skersai, ir nemažai simbolių visiškai pakeičia formą — ir tai yra dalis, kuri atskiria dokumentą, kuris skaitosi natūraliai, nuo to, kurį japonų skaitytojas iškart atpažįsta kaip mašiniškai pagamintą

Kas pasikeičia PDF viduje

Taip nubraižytas tekstas eina per Type0 šriftą vertikalaus rašymo režime, nešantį paties šrifto vertikalius metrikus. Tai svarbu dviem kryptimis. Skaitytuvas kiekvieną simbolį pažymi atstumu, kurį numatė jo dizaineris, o ne vienodu žingsniu, todėl stulpelis turi ritmą, kuriam šriftas buvo braižytas. Ir iškopijavus tekstą grąžinami originalūs simboliai, nes vertikali sekos dalis vis dar yra tikras tekstas su tinkamu atvaizdavimu, o ne pozicionuotų glifų seka

Šriftas, neturintis savų vertikalių metrikų, pažymi vieną em už simbolį, ir tai yra tai, ką skaitytuvas darytų su numatytuoju. Tas atsarginis variantas vertas žinoti, nes tai yra skirtumas, kurį matysite, kai dokumentas atvaizduojamas teisingai su tinkamu CJK šriftu ir atrodo mechaniškai išdėstytas su lotynišku šriftu, kuris atsitiktinai turi šiek tiek kanų

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;

Kodėl skliaustai atrodo neteisingi vertikaliame tekste?

Nes skliaustas turi dvi formas ir tik viena iš jų priklauso stulpelyje. Skliaustai, ilgo balsės ženklas ir mažos kanos braižomi skirtingai, kai tekstas eina puslapiu žemyn — skliaustas pasisuka, kad sėdėtų išilgai stulpelio, o ne gulėtų skersai jo, o ilgo balsės ženklas tampa vertikaliu brūkšniu. Nubraižykite horizontalias formas vertikaliame stulpelyje, ir kiekvienas iš jų guli ant šono

PDFlibPas ima formas iš paties šrifto vertikaliosios savybės, todėl kiekvienas šriftas teikia tai, ką nubraižė jo dizaineris, o ne pakaitą, spėtą iš simbolio. Šis skirtumas svarbus teisingumui: spėjama pakaitų lentelė tinka įprastiems atvejams ir yra neteisinga šriftams, kurie simbolį traktuoja kitaip, o šriftas, nepaminėjęs jokių vertikalių formų, braižomas lygiai taip pat, kaip anksčiau, užuot buvęs verčiamas per lentelę, kurios jis niekada neprašė

GetVerticalTextHeight išmatuoja formas, kurios tikrai bus nubraižytos, todėl stulpelis, kurio simboliai keičia formą, vis dar išmatuojamas teisingai. Horizontalių formų matavimas ir vertikalių braižymas yra klasikinis šaltinis stulpelių, kurie peržengia savo dėžutę keliais simboliais

Vienos sekos braižymas nekeičiant režimo

DrawVerticalText braižo vieną seką vertikaliai, imdamas poziciją, šrifto pavadinimą, dydį ir tekstą, ir palieka rašymo režimą ramybėje. Naudokite jį vertikaliai išimčiai horizontaliame dokumente — nugarėlės etiketė, antspaudas, vienas vardų stulpelis — kur globalaus režimo įjungimas ir išjungimas aplink kiekvieną kvietimą yra daugiau būsenos, nei uždavinys nusipelnė

Vieno šrifto horizontalios ir vertikalios formos viduje laikomos atskirai, todėl puslapis gali nešti abipus be to, kad vienas trukdytų kitam. Būtent tai padaro mišrų puslapį praktišku: japonų knygos puslapis su vertikaliu pagrindiniiu tekstu ir horizontaliomis tekusiomis antraštėmis, arba kinų sertifikatas su vertikaliu pavadinimu virš horizontalių detalių eilučių

// 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');

Šrifto paruošimas teisingai prieš viską kitą

Vertikalus rašymas visiškai priklauso nuo šrifto. CJK šriftas su tinkamais vertikaliais metrikais ir vertikalia savybe gamina teisingą išvestį be papildomo darbo; šriftas be jų gamina statmenis simbolius, pažyminčius vieną em už kartą, be jokių formos pasikeitimų. Jei vertikalus tekstas atrodo subtiliai neteisingai, ištirkite šriftą prieš tirdami kodą

Įterpimas vadovaujasi įprastomis taisyklėmis ir įprastomis sąnaudomis. Pilnas CJK šriftas yra didelis, todėl poaibių sudarymas nėra pasirinktinis dokumentams, kurie eina bet kur — PDF failo dydžio optimizavimo ir šriftų poaibių pastabos padengia, ko tikėtis, o trūkstamų šriftų įterpimo į esamą PDF aprašymas padengia taisymo atvejį, kai vertikalus dokumentas atkeliauja be savo šriftų

Kur vertikalus tekstas vis dar reikalauja išdėstymo sprendimo iš jūsų

Stulpelių tvarka. Japonų vertikalus tekstas eina iš dešinės į kairę pagal stulpelius, todėl dviejų stulpelių puslapis prasideda dešiniu kraštu, ir joks rašymo režimo nustatymas negali to išvesti iš teksto. Tas pats taikoma puslapių tvarkai dokumente, kuris skaitosi iš dešinės į kairę kaip visuma, ir kur yra furigana, išnašos ir paveikslų antraštės

Ką biblioteka garantuoja, tai, kad kiekviena seka yra išdėstyta teisingai: teisingos formos, teisingos pažangos, ištraukiamas tekstas. Kur sekos eina puslapyje, yra išdėstymo problema, o dokumentams, surinktiems iš duomenų, teksto paieškos ir puslapio elementų išvardijimo aprašymas yra naudingas vėliau patikrinti, ar tai, kas nusileido puslapyje, yra tai, ką planavote

PDFlibPas yra natyvi Pascal PDF biblioteka, skirta Delphi, C++Builder ir Lazarus, o vertikalus CJK rašymas yra braižymo API dalis, o ne priedas — žr. PDFlibPas produkto puslapį dėl teksto ir šriftų savybių sąrašo