Fonctions, quatrième partie: alternates positionnelles

  • by Rainer Erich Scheichelbauer
  • Tutorial
  • – Modified on

L’un des principaux problèmes pour les polices scriptes et les designs similaires est que les lettres adoptent des formes différentes selon leur position relative dans un mot. Au total, nous pouvons différencier quatre positions:

  • .init: forme initiale au début d’un mot
  • .medi: forme médiale au milieu d’un mot
  • .fina: forme finale à la fin d’un mot
  • .isol: forme isolée lorsqu’une lettre est seule

Les codes de quatre lettres init, medi, fina et isol sont les noms des fonctions OpenType correspondantes. Vous l’avez peut-être déjà deviné: vous pouvez activer la création automatique de ces quatre fonctions en ajoutant leurs noms en tant que suffixes des glyphes. Par exemple, si vous avez à la fois adieresis et adieresis.init dans votre police, et bien Glyphs pourra générer automatiquement la fonction init pour vous. Tout ce que vous avez à faire est de cliquer sur le bouton Mettre à jour (marqué d’une flèche circulaire) dans le bas vers la gauche dans Fichier > Informations de police… > Fonctions, puis d’exporter à nouveau votre police.

Ce qui est ennuyeux, c’est que peu de logiciels font usage des fonctions par défaut. Dans InDesign par exemple, il vous faut activer les Formes positionnelles automatiques dans les options OpenType. Plusieurs utilisateurs ne savent pas encore comment bien utiliser les fontes OpenType et vous pourriez recevoir de nombreux courriels à ce sujet. Après tout, la police que vos clients ont achetée avec de l’argent durement gagné ne semble pas bien fonctionner. La simple expression ‘activez les formes positionnelles automatiques’ peut donner une crise d’urticaire à plus d’un utilisateur.

Donc, afin de vous sauver bien du temps et de préserver vos précieux nerfs, nous avons tout intérêt à trouver une façon de faire apparaître les formes positionnelles de façon automatique. Comme vous vous en doutez sans doute, cette façon existe déjà. Restez à l’écoute.

Formes médiales par défaut

À partir de maintenant dans ce tutoriel, je vais faire deux suppositions: premièrement, je présume que vos glyphes par défaut sont des formes médiales. Deuxièmement, je présume que votre police comprend les quatre variations de formes pour chaque lettre. Cela signifie qu’il y a des glyphes par défaut comme a, b, c, et ainsi de suite, tous avec des formes médiales, plus trois variations, chacune avec l’un de ces suffixes: .isol, .init ou .fina. Si cela n’est pas le cas pour votre design, vous devrez adapter le code en conséquence, ce qui, toutefois, devrait être assez facile après que vous aurez lu ce tutoriel.

Créer des classes OpenType

Je pense que c’est clair. Il nous faut quatre classes:

  • Isolated pour les glyphes isolés avec un suffixe .isol;
  • Initial pour les variations initiales avec un suffixe .init;
  • Medial pour les lettres médiales par défaut sans suffixe;
  • Final pour les formes finales avec un suffixe .fina.

Commençons avec Isolated: celle-ci est facile, nous n’avons qu’à taper .isol dans le champ Rechercher dans le coin en bas à droite des Informations de police. Glyphs limitera la sélection aux lettres avec .isol dans leur nom. Tout ce qu’il nous reste à faire maintenant est de sélectionner tous les glyphes affichés (Cmd-A) et de choisir Copier les noms de glyphes > Séparés d’une espace à partir du menu contextuel.

Nous avons maintenant tous les noms de glyphes de tous les glyphes .isol dans notre presse-papiers. Allez maintenant à Fichier > Informations de police… > Fonctions, puis cliquez sur le bouton plus du coin en bas à gauche; en le maintenant enfoncé, sélectionnez Classe du menu pop-up. Une nouvelle classe OpenType apparaîtra. Nous changerons son nom pour Isolated. Collons ensuite les noms de glyphes dans le champ du code.

Votre code de classe devrait être à peu près comme ceci:

A.isol B.isol C.isol D.isol E.isol F.isol G.isol H.isol I.isol J.isol K.isol L.isol M.isol N.isol O.isol P.isol Q.isol R.isol S.isol T.isol U.isol V.isol W.isol X.isol Y.isol Z.isol a.isol b.isol c.isol d.isol e.isol f.isol g.isol h.isol i.isol j.isol k.isol l.isol m.isol n.isol o.isol p.isol q.isol r.isol s.isol t.isol u.isol v.isol w.isol x.isol y.isol z.isol

Note: tout le code doit demeurer tel qu’il est, en anglais, pour que l’automatisation des fonctions puisse s’effectuer. C’est pourquoi nous recommandons de conserver les noms de classes également en anglais. Les notes dans la fenêtre grise peuvent être rédigées dans la langue de votre choix, mais gardez à l’esprit que vos fichiers pourraient un jour se retrouver entre les mains d’ingénieurs de polices de caractères qui ne parlent pas votre langue. Pour cette raison, vaut mieux créer un fichier de police qui soit à tout le moins compréhensible en anglais.

Encore mieux. Pour les classes restantes, notre tâche est claire et facile: nous allons copier-coller la classe Isolated trois fois en cliquant sur le nom de classe Isolated puis en appuyant sur Cmd-C pour finir par Cmd-V trois fois. Vous verrez quatre classes nommées Isolated. Changez le noms de trois d’entre elles pour Initial, Medial et Final. Cliquez ensuite sur le code de chacune des nouvelles classes et remplacez le suffixe .isol pour les suffixes respectifs et ne mettez pas de suffixe pour la classe Medial. Vous pouvez facilement faire cela en appuyant sur Cmd-Shift-F, ce fera surgir la fonction Rechercher et remplacer. Remplacez le suffixe .isol avec le suffixe respectif, et n’inscrivez rien pour Medial.

De cette façon, toutes les classes sont synchronisées, c’est-à-dire que le même nombre et ordre de glyphes y sont stockés. C’est important pour la substitution de code que nous allons écrire dans une minute.

Soit dit en passant, vous pouvez réarranger les classes en faisant glisser leurs noms dans la barre latérale. L’ordre n’affecte pas la bonne marche des fonctions, mais est utile pour garder une bonne vue d’ensemble.

Il nous reste à faire la définition de classe. Il nous faut une classe nommée AllLetters, créez-la avec le menu Plus dans Fichier > Informations de police… > Fonctions, et assurez-vous que la boîte Générer la fonction automatiquement est cochée. De cette façon, nous obtiendrons la liste complète de noms pour toutes les lettres de votre police, incluant les formes positionnelles. Pourquoi? Parce que, par exemple, la fonction initiale procédera à peu près comme ceci: changer une lettre pour sa forme initiale à moins qu’il y ait une lettre en avant d’elle.

Il va sans dire que la classe AllLetters sera plus grande que les classes positionnelles que nous avons créées auparavant. C’est pourquoi elle ne peut avoir le même nombre et ordre de glyphes que ces autres classes.

Formes positionnelles en tant que alternates contextuelles

Ce dont nous avons maintenant besoin, c’est une fonction Alternates contextuelles, ou calt, car nous voulons substituer des glyphes selon le contexte. Donc, notre première étape est de créer cette fonction. Allez encore une fois à Fichier > Informations de police… > Fonctions, puis cliquez et maintenez enfoncé le bouton Plus en bas à gauche. Mais cette fois-ci, sélectionnez Fonction du menu pop-up. Une nouvelle fonction appelée xxxx apparaîtra, son nom déjà sélectionné, nous pouvons donc commodément le changer pour calt, en lettres bas de casse:

Appuyez sur le bouton Retour afin de confirmer. Si vous avez déjà d’autres fonctions dans votre police, cliquez également sur le bouton Mettre à jour, afin que Glyphs réordonne correctement les fonctions. Contrairement aux classes, l’ordre des fonctions a de l’importance. À moins d’avoir une bonne raison de ne pas le faire, je vous recommande de suivre l’ordre par défaut suggéré par Glyphs.

Écrire le code de fonction

Rappelez-vous comment j’ai résumé la fonction initiale: ‘Changez une lettre par défaut pour sa forme initiale à moins qu’une lettre soit en avant d’elle.’

Okay, construisons-la petit à petit. ‘Changez une lettre par défaut pour sa forme initiale’ signifie que la classe Medial sera substituée pour la classe Initial. Nous pouvons donc commencer par écrire cette ligne:

sub @Medial by @Initial;

Rappelez-vous, dans le code de fonction, sub...by veut dire substituer…pour, et les noms de classes ont besoin d’être précédés par un signe arobase afin d’être reconnu en tant que classes. Finalement chaque règle a besoin de se terminer par un point-virgule, autrement elle ne s’applique pas.

Jusqu’ici tout va bien. Mais le problème est le suivant: toutes les lettres par défaut (Medial) seraient substituées pour leur forme initiale. Et nous voulons faire cela seulement s’il n’y a pas de lettre qui la précède, en d’autres mots, à moins qu’il y ait une lettre quelconque en avant. Ou, en d’autres mots encore, ignorez le cas si une lettre se trouve en avant. Cela semble vraiment bien, étant donné que nous avons une classe nommée AllLetters et que le fichier de syntaxe de fonction AFDKO connaît un énoncé ignore sub. Et voici comment il faut l’écrire:

ignore sub @AllLetters @Medial';
sub @Medial' by @Initial;

Cliquez sur le bouton Compiler pour vous assurer que vous avez tout bon.

J’aimerais maintenant attirer votre attention sur deux choses. Premièrement, l’énoncé ignore sub précède les énoncés sub auxquels il est destiné. Ce qui veut dire que tous les énoncés sub qui suivent comptent seulement si la condition du ignore sub n’est pas remplie. Laborieux. Pour le moment, ça va, mais les maux de tête viendront plus tard. Poursuivez votre lecture.

En deuxième, observez les apostrophes dactylographiques ' (ou marqueurs). Dans la règle ignore sub, nous spécifions que l’exception compte pour tous les glyphes de la classe Medial. Et dans la règle sub qui suit, nous avons besoin de la marquer à nouveau. En fait, je suppose que, dans ce cas ce serait clair, puisque rien d’autre n’est substitué. Mais nous avons quand même besoin de la marquer car il pourrait s’agir d’une classe différente que dans l’énoncé ignore sub ci-dessus. Cela pourrait être deux classes différentes qui partagent quelques glyphes. De plus, il pourrait s’agir d’une substitution contextuelle plus complexe.

Laissez-moi insister: vous avez besoin de marquer d’apostrophes dactylographiques les classes de glyphes respectives dans les deux énoncés, ignore sub et sub. Si votre ignore sub ne fonctionne pas pour vous, vous avez probablement oublié un ou deux marqueurs. Soyez sans inquiétude, cela arrive aux meilleurs d’entre nous.

Voyons si cela fonctionne. Dans un nouvel onglet Édition, tapez simplement n à quelques reprises, et sélectionnez Contextual Alternates (c’est-à-dire alternates contextuelles) à partir du menu déroulant des Fonctions dans le coin en bas à gauche de la fenêtre.

Yé! Ça fonctionne! Donc, en théorie, il nous suffit de faire la même chose pour Isolated et Final, n’est-ce pas? N’est-ce pas?!

Et bien non, pas tout-à-fait. Futés comme nous le sommes, nous nous rappelons que l’énoncé ignore sub s’applique à tout ce qui suit. Et trois énoncés ignore sub s’empêtreraient. Que faut-il donc faire?

Les lookups à l’aide!

En fait, je ne vous ai pas dit toute la vérité auparavant. Un énoncé ignore sub ne compte pas pour tout ce qui suit, mais seulement pour tout ce qui suit dans le même lookup**.

Euh? Lookup? C’est quoi un lookup? Et bien, dans un lookup, vous pouvez résumer quelques règles sous un nom, et si vous le voulez, les utiliser plus tard. Nous avons donc besoin de tout mettre ce que nous avons écrit dans un lookup et de lui attribuer un nom. Voici comment faire:

lookup INITIAL {
    ignore sub @AllLetters @Medial';
    sub @Medial' by @Initial;
} INITIAL;

J’ai choisi le nom INITIAL, pour des raisons évidentes. La syntaxe est claire: lookup, suivi d’un nom, suivi par l’ouverture d’une accolade. Suivent ensuite toutes les règles qui ont besoin d’être dans le lookup. Cela n’est pas obligatoire, mais vous pouvez les mettre en alinéa avec Cmd-] pour faire plus joli. Vous pouvez enlever un alinéa avec Cmd-[. À la fin des règles, nous devons fermer l’accolade, répéter le nom du lookup, pour finalement terminer le lookup avec un point-virgule.

Il faut maintenant que je vous dise une autre chose indispensable: l’ordre des blocs de lookups a de l’importance. Tout comme pour les fonctions. La police passera la fonction en révision jusqu’à ce qu’elle trouve quelque chose d’approprié pour le glyphe courant et ne cherchera ensuite pas plus loin.

C’est pourquoi nous avons besoin de placer en premier le lookup avec le plus grand ignore sub. Dans notre cas, c’est celui pour les variations isolées (isolated), puisque dans ce lookup en question, nous avons besoin d’ignorer tous les cas où quelque chose se trouve devant et tous les cas où quelque chose se trouve derrière. Ce qui fait deux règles ignore sub. Avons-nous donc besoin de rédiger deux énoncés ignore sub?

lookup ISOLATED {
  ignore sub @Medial' @AllLetters;
  ignore sub @AllLetters @Medial';
  sub @Medial' by @Isolated;
} ISOLATED;

Bien sûr, nous pourrions faire cela, ce qui fonctionnerait parfaitement. Certaines personnes préfèrent cependant aligner les chaînes ignore sub entre des virgules, comme ceci:

lookup ISOLATED {
   ignore sub @Medial' @AllLetters, @AllLetters @Medial';
   sub @Medial' by @Isolated;
} ISOLATED;

J’en fais partie. Je vais donc le garder comme cela, ha ha.

Pendant que nous y sommes, nous pourrions aussi bien ajouter les substitutions Final.Dans ce cas-ci, le lookup est placé à la fin:

lookup ISOLATED {
   ignore sub @Medial' @AllLetters, @AllLetters @Medial';
   sub @Medial' by @Isolated;
} ISOLATED;

lookup INITIAL {
   ignore sub @AllLetters @Medial';
   sub @Medial' by @Initial;
} INITIAL;

lookup FINAL {
   ignore sub @Medial' @AllLetters;
   sub @Medial' by @Final;
} FINAL;

Encore une fois, soyez super certains que les apostrophes dactylographiques sont placés correctement. Nous voulons toujours marquer la classe Medial, à la fois dans la règle ignore sub et la règle sub. Après tout, la classe Medial contient nos glyphes par défaut, et ce sont eux qui ont besoin d’être substitués chaque fois que l’occasion le demande.

Okay, appuyez sur le bouton Compiler. Si vous obtenez une erreur, lisez attentivement ce que le message d’erreur vous dit. Avez-vous oublié un point-virgule? Mal épelé un nom de classe? Oublié un signe arobase? Si vous ne pouvez identifier votre erreur, voyez la longue section de dépannage dans le manuel Glyphs: allez à la section OpenType Feature Code dans le chapitre Error Handling.

Si vos fonctions se compilent, nous pouvons les tester dans un onglet Édition, comme nous avons fait tout-à-l’heure. Voici ce qui se passe quand je tape n à quelques reprises à nouveau:

Regardez le n isolé sur la gauche, et trois fois l’un à la suite de l’autre sur la droite, dans une forme différente à chaque fois: initiale, médiale, puis finale. Cool, top là!

Il y a un script pour cela!

Vous avez donc lu tout lu, et vous comprenez maintenant la nature des blocs de lookups et des énoncés ignore sub. Je soupçonne que vous aimeriez avoir un peu de répit.

Aussitôt dit aussitôt fait: j’ai écrit un script qui insère un code positionnel dans à l’intérieur de calt. Il analyse la structure des glyphes, et recherche les suffixes .init, .medi, .fina, and .isol. La meilleure chose: il ne prend pas pour acquis que vos quatre groupes positionnels sont synchronisés. Ce qui fait que les structures de classe et de code seront légèrement différentes, mais l’idée de base sera la même. Si vous relancez le script, il mettre à jour les classes et le code de fonctions.

Téléchargez le répertoire de scripts Glyphs de la page GitHub de mekkablue. Placez les scripts dans le dossier de scripts (Script > Ouvrir le dossier des scripts, Cmd-Shift-Y) puis rechargez les scripts (avec la touche Opt enfoncée: Script > Recharger les scripts, ou bien avec Cmd-Opt-Shift-Y). Vous trouverez ensuite Features > Build positional calt feature quelque part dans le menu Script. Amusez-vous bien.


2015-06-22: Mise à jour pour Glyphs 2.
2017-01-09: Correction d’erreurs typographiques, mise à jour des captures d’écran et clarification de la classe AllLetters (merci @Raseone).

Traduction française de Nathalie Dumont.