1

Changer de police selon la langue

8 juillet 2006
par ARNO*

[SPIP 1.9 et GD2] Voici une technique qui répond à un besoin d’un site sur lequel je suis en train de travailler. Le site en question est multilingue : en français, en anglais, en chinois et en japonais. Pour les besoins de notre démonstration, je me contentera de travailler avec le français et le chinois.

Dans chaque page d’article, le titre est transformé en image typographique, ce qui permet notamment d’utiliser la police de mon choix. Pour le français, pas de problème, nous utilisons le l’ITC Slimbach de Robert Slimbach.

Jusque là, rien de bien compliqué, cela peut être obtenu ainsi :

  1. <h1>
  2. [(#TITRE|image_typo{police=SlimbBol.ttf,
  3.                                 taille=15,couleur=d83d1f,largeur=450})]
  4. </h1>

Télécharger

En réalité, pour obtenir un rendu plus lissé, je calcule mon image typographique deux fois plus grande et je réduis ensuite l’image d’un facteur 2. Ensuite j’aplatis l’image au format GIF sur fond blanc, ce qui annule les difficultés du PNG 24 transparent avec MSIE.

La difficulté apparaît avec le chinois : évidemment la police Slimbach ne contient pas les milliers de caractères du chinois. Il faut donc que je change de police. Je n’y connais pas grand chose, mais je trouve en tout cas une belle collection de polices chinoises Unicode en ligne. J’aime beaucoup la police nommée HanWangKanTan, qui semble tracée avec un large pinceau. Le nom du fichier est : « wt034.ttf ».

Le but de l’exercice est donc d’utiliser la police Slimbach si mon article est en français ou en anglais, et la police HanWangKanTan s’il est en chinois.

Je pourrais évidemment créer un squelette pour chaque langue. Mais comme c’est quasiment l’unique élément qui change dans la page, je préfère éviter de multiplier les fichiers.

Je pourrais aussi utiliser un « boucle de contrôle », c’est-à-dire une boucle ARTICLE, qui appelle l’article en cours, en ajoutant comme critère une langue ; à l’intérieur de la boucle, code correspondant au français, et comme texte alternatif (hors de la boucle), le code pour les autres langues. Pour un site comportant deux langues, cela convient ; mais ici j’aurai quatre langues, et au moins trois polices de caractères différentes, et les boucles de contrôle les unes dans les autres donnent rapidement un code un peu long.

La solution va consister à créer mon propre filtre, qui affichera le texte avec la police de mon choix en fonction de la langue.

Commençons par remplacer notre appel à image_typo par un appel à une fonction personnelle qui fera tout le travail :

  1. [(#TITRE|image_typo_titre_article)]

En définissant ce filtre dans mes_fonctions.php :

  1. function image_typo_titre_article ($titre) {
  2.         $ret = image_typo($titre, "police=SlimbBol.ttf", "taille=30", "couleur=d83d1f", "largeur=900");
  3.         $ret = image_diviser_par($ret, 2);
  4.         $ret = image_aplatir($ret, "gif", "ffffff");
  5.         return $ret;
  6. }

Télécharger

C’est l’exact traduction de ce que j’avais auparavant sous forme de squelettes SPIP, et cela ne change rigoureusement rien. Je n’ai évidemment pas encore de possibilité de choisir la police en fonction de la langue.

Nous allons exploiter une des nouvelles possibilités de SPIP (introduite avec le nouveau moteur dans la version 1.8) : on peut passer comme variable pour un filtre une autre pseudo-balise SPIP. C’est très simple à utiliser, et cela simplifie radicalement un certain nombre de choses...

Ici, nous allons passer à notre fonction la langue de l’article :

  1. [(#TITRE|image_typo_titre_article{#LANG})]

et nous modifions notre fonction ainsi :

  1. function image_typo_titre_article ($titre, $lang) {
  2.         if ($lang == "fr" OR $lang == "en") {
  3.                 $ret = image_typo($titre, "police=SlimbBol.ttf", "taille=30", "couleur=d83d1f", "largeur=900");
  4.         } else if ($lang == "zh") {
  5.                 $ret = image_typo($titre, "police=wt034.ttf", "taille=40", "couleur=d83d1f", "largeur=900");
  6.         }
  7.         $ret = image_diviser_par($ret, 2);
  8.         $ret = image_aplatir($ret, "gif", "ffffff");
  9.         return $ret;
  10. }

Télécharger

Et voilà : si l’article est en chinois, la police utilisée est le « wt034.ttf », si l’article est en français ou en anglais, c’est « SlimbBol.tff ». Et il sera très simple d’ajouter une police pour le japonais.

L’astuce, ici, ne réside pas dans l’affichage de texte chinois (c’est très facile, il n’y a aucune bidouille) ; la fonction utile à connaître est la possibilité de passer deux balises SPIP (ici #TITRE et #LANG) à un filtre, cela en utilisant la possibilité d’envoyer la deuxième balise en tant que variable du filtre appliqué à la première (on applique le filtre à #TITRE, en lui passant la variable #LANG). Si nécessaire, on peut évidemment utiliser autant de variables que nécessaire.

Sur le même site, une autre utilisation découlant de cette logique consiste à afficher le nom de la rubrique verticalement dans une colonne sur la gauche de l’écran. Pour le français, le texte est tourné à 90° :

Pour le chinois, c’est très différent, puisqu’il me semble qu’on ne peut pas se permettre d’afficher des idéogrammes à 90°, mais bien plutôt qu’on les affiche les uns sous les autres.

Là encore, il s’agit d’une très simple fonction personnelle à laquelle on passe le titre et la langue, et qui fabrique un affiche différent selon la langue.

Si cette fonction vous intéresse, la voici :

  1. function image_typo_titre_secteur($titre, $lang) {
  2.         if ($lang == "fr" OR $lang == "en") {
  3.                 $ret = mb_strtoupper ($titre);
  4.                 $ret = image_typo($ret, "police=SlimbBol.ttf", "taille=24", "couleur=ffffff", "largeur=2000");
  5.                 $ret = image_rotation ($ret, -90);
  6.                 $ret = image_diviser_par($ret, 2);
  7.                 $ret = image_aplatir($ret, "gif", "d83d1f");
  8.         } else if ($lang == "zh") {
  9.                 for ($i = 0; $i < mb_strlen($titre); $i++) {
  10.                         $ret .= mb_substr($titre, $i, 1) . " ";
  11.                 }
  12.                 $ret = image_typo($ret, "police=wt034.ttf", "taille=30", "couleur=ffffff", "largeur=50", "hauteur_ligne=50");
  13.                 $ret = image_diviser_par($ret, 2);
  14.                 $ret = image_aplatir($ret, "gif", "d83d1f");
  15.                 $ret = "<div style='margin-left: -2px; margin-top: -17px;'>$ret</div>";
  16.         }
  17.         return $ret;
  18. }

Télécharger

La petite subtilité est située dans le chinois : pour forcer l’affichage des idéogrammes les uns sous les autres, j’insère un espace entre chaque lettre, et je passe une taille très faible (30 pixels) lors du rendu typographique. Notez l’utilisation des fonctions multibyte mb_strlen et mb_substr pour manipuler le texte : nous sommes ici en utf-8 (en théorie, il aurait été certainement plus propre d’appliquer une expression régulière en mode multibyte, mais j’avoue ne pas y être parvenu — le multibyte reste relativement difficile à gérer.

Qui êtes-vous ?
Votre message

Ce formulaire accepte les raccourcis SPIP [->url] {{gras}} {italique} <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.