Contactez-nous

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.

  • Octobre 2006

    Sinogrammes pas idéogrammes (erreur trop courante, peut etre du au fait que pour les japonais qui oublient parfois un peu l’éthymologie les sinogrammes (traduction littérale et exacte de kanji)) ne representent plus que des idées. :) Les sinogrammes incluent des idéogrammes, des pictogrammes (comme le caractere soleil (un soleil stylisé 日) + racine (un trait en bas du caractere arbre 本) dans le mot japon), etc...

    Sinon, cette fonte est en chinois traditionnel (utilisé a Taïwan, Hong-Kong, et Macao). A Singapour et en Chine populaire (en dehors des provinces autonomes de Xianggang (hong kong en cantonais) et de omen (Macao en je sais pas quelle langue), on écrit dans une écriture simplifiée, officialisée depuis 1956 environ. Lire l’article sinogramme simplifié (voir le lien pour comprendre) Les plus jeunes chinois (ceux qui ne sont pas à Taïwan, Hongkong ou Macao, autant dire la majorité) risquent donc de ne pas comprendre.

  • nadine
    Octobre 2006

    salut,

    j’ai reçu un email en arabe et j’arrive pas à le lire, j’ai instaler la langue arabe et malgré ça j’arrive pas, je l’ai reçu avec des lettres inconues sur le site yahoo.

  • Bernard
    Novembre 2006

    Bonsoir je cherche le moyen de remplacer le #TITRE et #TEXTE en une image genénérée en GD pour obliger certaines polices et faires des lettrines dignet du nom. Est-ce possible avec le filtre image_typo seulement ?

  • Mehdi Cherifi
    Août 2007

    bonjour,

    merci c’est exactement ce que je chercher à mettre en place !

    cependant une erreur notée dans le code :

    $ret = image_diviser_par($ret, 2) ;

    la fonction

    image_diviser_par

    est déclarée non définie !

    j’ai remplacée avec

    image_reduire_par

    et tout marche super bien

    bonne continuation.

    PS : pour l’arabe, la bibliothèque GD2 ne prends pas ne charge les ligatures entres les lettres, même si vous utiliser une police arabe Array cela donnera un résultat illisible !

    si quelqu’un connait la solution ou une alternative pour l’arabe cela m’interesse !

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.