Article technique

Texte Japonais et Chinois Vertical en PDF avec Delphi

PDFlibPas dessine le texte japonais et chinois le long de la page. SetVerticalWritingMode active l'écriture verticale, les appels DrawText ordinaires descendent ensuite, et GetVerticalWritingMode signale l'état courant. Avant que cela n'existe, poser du texte verticalement signifiait placer chaque caractère à la main en espérant que l'espacement ait l'air correct

L écriture verticale n'est pas du texte horizontal pivoté de quatre-vingt-dix degrés. Les caractères restent droits, l'avancement descend au lieu de traverser, et un certain nombre de caractères changent entièrement de forme — c'est la partie qui sépare un document qui se lit naturellement d'un qu'un lecteur japonais reconnaît immédiatement comme fabriqué à la machine

Ce qui change à l'intérieur du PDF

Le texte dessiné de cette façon passe par une police Type0 en mode d'écriture vertical portant les propres métriques verticales de la police. Cela compte dans deux directions. Un lecteur avance chaque caractère de la distance que son concepteur a prévue plutôt que par un pas uniforme, donc la colonne a le rythme pour lequel la police a été dessinée. Et copier le texte hors renvoie les caractères originaux, car la séquence verticale est encore du vrai texte avec un mappage correct plutôt qu'une suite de glyphes positionnés

Une police qui ne porte pas ses propres métriques verticales avance un cadratin par caractère, ce qu'un lecteur ferait par défaut. Ce repli vaut la peine d'être connu car c'est la différence que vous verrez quand un document se rend correctement avec une police CJK appropriée et paraît mécaniquement espacé avec une police latine qui se trouve contenir quelques 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;

Pourquoi les parenthèses paraissent-elles fausses en vertical ?

Parce qu'une parenthèse a deux formes et qu'une seule appartient à une colonne. Les parenthèses, la marque de voyelle longue et les petits kana sont dessinés différemment quand le texte descend la page — une parenthèse pivote pour s'asseoir le long de la colonne plutôt que de s'allonger à travers, et la marque de voyelle longue devient un trait vertical. Dessinez les formes horizontales dans une colonne verticale et chacune est couchée sur le côté

PDFlibPas prend les formes de la propre caractéristique verticale de la police, donc chaque police fournit ce que son concepteur a dessiné plutôt qu'une substitution devinée à partir du caractère. Cette distinction compte pour la correction : une table de substitution devinée est juste pour les cas courants et fausse pour les polices qui traitent un caractère différemment, et une police qui ne nomme aucune forme verticale est dessinée exactement comme avant plutôt que d'être forcée à travers une table qu'elle n'a jamais demandée

GetVerticalTextHeight mesure les formes qui seront effectivement dessinées, donc une colonne dont les caractères changent de forme est encore mesurée correctement. Mesurer les formes horizontales et dessiner les verticales est la source classique des colonnes qui débordent de leur cadre de quelques caractères

Dessiner une séquence sans changer le mode

DrawVerticalText dessine une seule séquence verticalement, prend la position, le nom de police, la taille et le texte, et laisse le mode d'écriture tranquille. Utilisez-le pour l'exception verticale à l'intérieur d'un document horizontal — un dos de livre, un tampon, une seule colonne de noms — où basculer un mode global on et off autour de chaque appel est plus d'état que la tâche ne le mérite

Les formes horizontales et verticales d'une même police sont maintenues séparées en interne, donc une page peut porter les deux sans qu'aucune ne dérange l'autre. C'est ce qui rend une page mixte pratique : une page de livre japonais avec du texte courant vertical et des en-têtes courants horizontaux, ou un certificat chinois avec un titre vertical sur des lignes de détail horizontales

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

Bien régler la police avant toute autre chose

L écriture verticale dépend entièrement de la police. Une police CJK avec des métriques verticales appropriées et une caractéristique verticale produit une sortie correcte sans autre travail ; une police sans eux produit des caractères droits avançant d'un cadratin à la fois et aucun changement de forme du tout. Si le texte vertical paraît subtilement faux, examinez la police avant d'examiner le code

L incorporation suit les règles habituelles et les coûts habituels. Une police CJK complète est volumineuse, donc le sous-ensemble n'est pas optionnel pour les documents qui vont quelque part — les notes sur optimisation de la taille du PDF et sous-ensemble de polices couvrent à quoi s'attendre, et la visite guidée de l'incorporation de polices manquantes dans un PDF existant couvre le cas de réparation où un document vertical arrive sans ses polices

Où le texte vertical a encore besoin d'une décision de mise en page de votre part

L ordre des colonnes. Le texte vertical japonais se déroule de droite à gauche par colonne, donc une page à deux colonnes commence au bord droit, et aucun paramètre de mode d'écriture ne peut le déduire du texte. Il en va de même pour l'ordre des pages dans un document qui se lit de droite à gauche dans son ensemble, et pour l'endroit où s'assoient le furigana, les notes de bas de page et les légendes de figures

Ce que la bibliothèque garantit, c'est que chaque séquence est posée correctement : formes correctes, avancements corrects, texte extractible. Où les séquences vont sur la page est un problème de mise en page, et pour les documents assemblés à partir de données la visite guidée de recherche de texte et énumération d'éléments de page est utile pour vérifier ensuite que ce qui a atterri sur la page est bien ce que vous aviez prévu

PDFlibPas est une bibliothèque PDF native en Pascal pour Delphi, C++Builder et Lazarus, et l'écriture CJK verticale fait partie de l'API de dessin plutôt que d'un module complémentaire — voir la page produit PDFlibPas pour la liste des fonctionnalités texte et police