FR/Draw/Forme Personnalisée

= Introduction = Ce tutoriel s'adresse aux utilisateurs avancés qui sont prêts à entrer dans le code XML d'un fichier au format OpenDocument (ODT pour le texte, ODS pour les classeurs, ODP pour les présentations, ODG pour les dessins). Il expose comment créer une nouvelle forme personnalisée, en particulier dans un dessin. Ceci nécessite d'éditer le code source XML du fichier. Cependant, aucune connaissance du langage XML, ou de tout autre langage de programmation, n'est nécessaire. Aucune macro n'est utilisée. Ce tutoriel est en même temps une introduction aux spécifications ODF des formes personnalisées.

= Nouveau document =

Format du fichier
LibreOffice utilise pour enregistrer les documents le format OpenDocument (ODF). Il s'agit en fait d'un fichier compressé au format ZIP contenant des fichiers répartis dans une arborescence. Pour plus d'informations sur le format ODF, référez-vous à l'entrée de la FAQ : LibreOffice et le XML. La modification du code XML d'un fichier demande alors de décompresser l'arborescence du ZIP, d'éditer le code XML, d'enregistrer et de recompresser l'ensemble (dans le bon ordre pour faire un fichier conforme). Cela devient vite fastidieux si de nombreux essais-erreurs doivent être réalisés.

En plus du format OpenDocument, LibreOffice permet d'enregistrer au format Flat OpenDocument (FODF). Dans ce cas, le fichier généré dispose d'une extension avec un 'F' en plus (FODT, FODS, FODP, FODG) et est un simple fichier texte contenant tout le code XML ainsi que l'ensemble des autres fichiers. Pour éditer le code XML, plus besoin de passer par les étapes de compression/décompression. C'est bien sûr ce format que nous vous encourageons à utiliser dans le cadre de ce tutoriel. Une fois la forme obtenue, vous pourrez enregistrer votre fichier au format OpenDocument classique.

Si vous devez utiliser le format OpenDocument, n'oubliez cependant pas de désactiver l'option Optimisation de la taille pour le format OpenDocument dans le menu : cela permettra d'obtenir un code XML lisible par un être humain.

Nouveau dessin

 * Créez un nouveau dessin.
 * Dessinez un rectangle. Utilisez l'outil Rectangle de la barre d'outils Formes de base.
 * Renommez la forme rectangle  ou tout autre nom qui vous paraitrait plus approprié :
 * cliquez droit sur la forme et sélectionnez
 * renseignez le nom choisi.
 * Note : il n'est pas indispensable de renommer la forme, mais cela permettra de la retrouver plus facilement.


 * Enregistrez le fichier, de préférence au format Flat OpenDocument : modifiez le type en OpenDocument Drawing (Flat XML) (.fodg), par exemple.
 * Note : prendre comme point de départ non pas un fichier vide, mais un fichier contenant une forme personnalisée présente certains avantages : vous n'avez pas à vous préoccuper du document lui-même, comment insérer la forme dans une page et une couche, ou comment appliquer certains styles.


 * Si vous souhaitez modifier la forme personnalisée au travers de son code XML, vous devez fermer le fichier. Si vous ne souhaitez que regarder le code, il n'est même pas nécessaire de le faire.

= Examiner le code =

Éditeur de texte
Pour examiner le code, vous pouvez utiliser n'importe quel éditeur de texte capable d'écrire le codage UTF-8. Il est cependant recommandé d'utiliser un éditeur de texte reconnaissant la syntaxe XML, en la coloriant et en gérant les nœuds. Par exemple sous Windows, le logiciel libre Notepad++ fait très bien ce travail. On peut également citer XML Notepad 2007 de Microsoft.

Avec Notepad++ :
 * dans l'explorateur de fichiers, retrouvez votre fichier ;
 * cliquez droit sur le fichier FODG et sélectionnez ;
 * de nombreux langages sont reconnus par Notepad++ ; comme l'extension FDOG n'est pas connue de Notepad++, il faut lui préciser que le fichier est en langage XML, :
 * soit en sélectionnant le menu (vous devrez le refaire à chaque ouverture du fichier),
 * soit en modifiant les paramètres de Notepad++ :
 * sélectionnez le menu ,
 * sélectionnez le langage XML,
 * ajoutez dans le champ Ext. utilisateur : les extensions fodg, fodt, fods et fodp (Notepad++ reconnaitra désormais automatiquement le format de ces fichiers).

Le code XML
Une petite partie du fichier nous intéresse : celle concernant la forme personnalisée. Voici cependant une rapide description des autres parties, dont la connaissance n'est malgré tout pas indispensable.

La première ligne contient le prologue qui indique qu'il s'agit d'un fichier XML classique : Le reste du code est, comme pour tout langage à balises, de la forme où  est le nom d'une balise et   l'information pour cette balise. Les balises peuvent être imbriquées les unes dans les autres, ce qui rend le document difficile à lire pour un être humain. Pour faciliter la lecture, l'éditeur de texte doit avoir créé des nœuds à chaque ouverture de balise. Un symbole   indique un nœud ouvert et un symbole   indique un nœud fermé. Dans ce dernier cas, tout le texte compris entre la balise ouvrante et la balise fermante est masqué.

Après une ligne vide, la première balise   contient l'ensemble du document. Si vous fermez le nœud associé à cette balise tout l'affichage se résume à la première ligne.

La balise   contient les informations sur le document, puis   contient les options du document. En fermant ce nœud, près d'une centaine de lignes sans intérêt pour ce que nous voulons faire sont masquées.

La balise   va stocker les macros enregistrées avec le document.

Les balises   et   vont contenir tous les styles automatiques et personnalisés disponibles pour ce document. Nous n'utiliserons pas ces parties du code, car il sera beaucoup plus facile d'utiliser LibreOffice lui-même pour mettre en forme les formes personnalisées.

La balise   contient les couches et les pages maitresses du document.

Enfin la balise   annonce le contenu du document. Si vous avez fermé les balises précédentes, et sans retour à la ligne automatique, votre affichage doit ressembler à cette figure :

En entrant dans la balise, on trouve   puis  , puis enfin  . On y est ! Sur la figure précédente, ce sont donc uniquement les lignes 346, 347 et 348 qui vont dessiner le rectangle et qui nous intéressent.

= L'élément  = À l'opposé du langage OOXML avec ses abréviations, ODF est très bavard. Cela vous permettra de comprendre instinctivement beaucoup de choses. L'élément  a des attributs et quelques sous-éléments.

Les attributs décrivent la relation avec la page de dessin. Il n'y a rien de spécifique aux, vous les trouverez pour tous les dessins.
 * :La référence au style de graphique employé pour cette forme. Dans le style vous trouverez des informations telles que l'épaisseur du trait ou la couleur de remplissage.
 * :La référence au style de texte employé pour le texte dans la forme. Dans ce style vous trouverez la police employée par exemple.
 * :Une page de Draw est constituée de plusieurs couches. La couche par défaut pour les formes est celle appelée “layout”. Les autres couches par défaut sont “background” et “controls”, mais vous pouvez également définir vos propres couches dans Draw.
 * :Vous le reconnaissez ? C'est le nom donné au rectangle.
 * :La taille de la forme.
 * :La position du coin haut gauche de la forme.
 * Les quatre derniers attributs correspondent aux paramètres à régler dans la boite de dialogue Position et taille de la forme. Ils définissent le rectangle avec les poignées vertes entourant la forme lorsqu'elle est sélectionnée. Ces poignées sont bleues s'il s'agit d'une forme personnalisée. Cette information peut être étendue à l'aide d'un attribut  pour réaliser une rotation, un cisaillement ou tout autre matrice de transformation linéaire. La spécification ODF n'a pas créé sa propre définition pour ces attributs, mais utilise les attributs bien définis par les spécification SVG du consortium W3. À chaque fois que c'est possible, la spécification ODF utilise les spécifications SVG, ou au moins les suit d'aussi près que possible.


 * :Dans cette balise, apparait le texte qui a été entré dans la forme. Comme le rectangle ne contient pas de texte, l'élément est vide.
 * :C'est cette partie qui distingue la forme personnalisée des autres objets et qui est spécifique aux . Nous allons opérer nos modifications à cet endroit. Le rectangle étant une forme très simple, l'élément n'a que quelques attributs mais pas de sous-éléments.
 * :Cet élément définit le système de coordonnées local. Il ne définit pas la taille de la forme, qui a été défini précédemment. Les deux premiers nombres sont les valeurs minimales en abscisse (x) et ordonnée (y) ; ils correspondent au coin haut gauche. Les troisième et quatrième nombres correspondent à la largeur et la hauteur dans les coordonnées locales. Si vous omettez ce paramètre, LibreOffice utilise des valeurs minimales en x et y de 0 et des valeurs de hauteur/largeur de 21600. Vous pouvez utiliser des valeurs plus petites si vous préférez, car les coordonnées peuvent être des réels. Faites cependant attention si vous devez partager vos fichiers avec des utilisateurs de PowerPoint, vous devriez conserver ces valeurs de 21600, car PowerPoint ne peut utiliser que des valeurs entières dans ses versions actuelles. De même, des valeurs négatives pour les minima en x et y ne sont pas recommandées (voir le bogue ).
 * :Cet élément définit le type de forme. LibreOffice l'utilise pour faire le lien avec les formes qui ont une correspondance avec les formes personnalisées de Microsoft et les formes prédéfinies en OOXML. Ainsi lors de l'export d'un document dans un format de MS-Office, la forme est correctement exportée. Les formes sans ces traitements spéciaux devraient avoir le type par défaut.
 * :Cet élément décrit la ligne qui dessine la forme. Vous pouvez imaginer votre forme personnalisée comme un canevas rectangulaire, sur lequel des lignes sont dessinées. Ces lignes constituent le  (chemin en français). Les commandes pour construire un chemin sont basées sur les définitions de chemin SVG, mais ne sont pas identiques à elles. C'est pourquoi le mot clé   est utilisé à la place de  . Une restriction concerne les coordonnées : les coordonnées employées pour les points sont toujours absolues. Par conséquent, les commandes sont toutes en majuscules.


 * La plupart des commandes commence à dessiner à partir de la dernière position résultant des commandes précédentes. C'est pourquoi le chemin commence la plupart du temps par la commande  M. Une ligne droite est dessinée par la commande   L. Et la commande Z ferme le chemin : le dernier point rejoint le premier. Pour une liste complète des commandes disponibles, référez-vous à la section 19.145 de la spécification ODF ou à la liste ci-dessous.

= Utilisation de l'élément  =

Nous allons maintenant réaliser un exemple d'application en créant une parabole simple d'équation  dans la plage [-3;3]. La valeur en  sera donc sur la plage [0;9]. Le code complet est donc :
 * 1) Modifiez la valeur de l'attribut   à.
 * 2) L'amplitude en abscisse est de 6 et en ordonnée de 9 : modifiez la taille de la boite de visualisation.
 * 3) Le type doit être modifié, car sinon il y aura toujours un rectangle de tracé :   ou toute autre valeur non utilisée.
 * Il faut maintenant translater les coordonnées mathématiques (dont l'origine est au centre en bas) dans le système de coordonnée local (dont l'origine est dans le coin haut gauche).
 * Une parabole se trace avec une courbe de Bézier quadratique, dont la commande est   : le point de départ est le point courant, le point (x1;y1) est le point de construction, à placer en (0;-9) dans notre cas, soit (3;18) pour les coordonnées locales, et le point (x;y) le point terminal, (3;9) dans notre cas, soit (6;0) pour les coordonnées locales.
 * FR.HT Draw-Forme personnalisee parabole.png
 * 1) L'attribut   doit donc commencer la commande   pour placer le point de départ (-3;9), qui correspond aux coordonnées locales (0;0) :
 * 2) La suite de l'attribut correspond à la courbe de Bézier :
 * Notez que le point de contrôle sort de la fenêtre définie par l'attribut . Les points de la courbe peuvent également sortir de cette fenêtre. Cela ne sera cependant pas forcément logique pour l'utilisateur.
 * 1) Il faut enfin terminer la courbe. Si on souhaite que la courbe soit fermée, il faut ajouter la commande  , sinon on n'ajoute rien :
 * Notez que le point de contrôle sort de la fenêtre définie par l'attribut . Les points de la courbe peuvent également sortir de cette fenêtre. Cela ne sera cependant pas forcément logique pour l'utilisateur.
 * 1) Il faut enfin terminer la courbe. Si on souhaite que la courbe soit fermée, il faut ajouter la commande  , sinon on n'ajoute rien :

Note : certaines versions anciennes de LibO peuvent ne pas savoir interpréter la courbe de Bézier quadratique (commande  ). Il faut alors utiliser une courbe de Bézier cubique, commande  . Le point de départ est le point courant, les points (x1;y1) et (x2;y2) sont les points de construction, à placer en (-1;-3) et (1;-3) dans notre cas, soit (2;12) et (4;12) pour les coordonnées locales, et le point (x;y) le point terminal, (3;9) dans notre cas, soit (6;0) pour les coordonnées locales. Ce qui donne le code équivalent au code précédent : draw:enhanced-path="M 0 0 C 2 12 4 12 6 0 Z"

La version 4.2 de LibreOffice permettra d'utiliser des virgules comme séparateur, ce qui rendra les longues chaînes de coordonnées beaucoup plus lisibles. Attention cependant à la compatibilité descendante pour les versions de LibO antérieures à la 4.2 et les versions d'AOO antérieures à la 4.0.

= Retour dans LibreOffice =

Enregistrer le fichier
Si vous utilisez le format Flat OpenDocument (FODG), il vous suffit d'enregistrer votre fichier. Si votre éditeur de texte ne bloque pas le fichier, vous pouvez directement l'ouvrir dans LibreOffice. Si vous utilisez le format OpenDocument (ODG), vous devrez rezipper le fichier. Le tutoriel est ici.

Utiliser la forme créée
Dans LibreOffice, vous obtenez donc votre superbe parabole. Vous pouvez maintenant appliquer tous les styles de ligne (épaisseur, couleur,...) ou de remplissage qui vous conviennent, comme avec n'importe quelle forme prédéfinie. Vous pouvez élargir, rétrécir ou faire tourner la forme : ce sera toujours une parabole parfaite.

Réutiliser et distribuer la forme
Si vous êtes insatisfait de votre forme, il vous suffit de rééditer le fichier .FODG pour modifier les coordonnées des points.

Si la forme vous convient, le moyen le plus simple pour l'avoir à disposition dans n'importe quel module est d'utiliser la Gallery. Voir Comment réutiliser un dessin à l'aide de la Gallery ?

Si vous voulez diffuser votre dessin, il peut être suffisant d'envoyer un fichier ODG contenant votre forme. Mais si vous avez plusieurs formes, il peut être intéressant de diffuser votre collection sous forme d'extension de Gallery. Voir le tutoriel Comment créer une extension - Application à la création d'un thème pour la Gallery.

= Pour aller plus loin =

Liste des commandes pour
Selon la norme OpenDocument Format, à la section 19.145, les commandes disponibles sont :

Les points de collage
Les formes peuvent disposer de points de collage afin d'accrocher à un endroit précis de la forme un connecteur. Par défaut, quatre points de collage sont définis au milieu de chaque côté du rectangle défini par la. Pour définir des points de collage supplémentaires, il suffit d'ajouter l'attribut   dans la balise  et donner les coordonnées (x;y) de ces points :

Dans l'exemple précédent, des points de collage ont été positionnés sur la courbe pour les nombres entiers : (-3;9) (-2;4) (-1;1) (le point 0;0 existe déjà) (1;1) (2;4) et (3;9). Pour visualiser ces points, dans LibreOffice sélectionnez un connecteur dans la barre d'outils Dessin et approchez la souris de la forme comme sur la figure ci-dessous. Il existe cependant une limitation : les points de collage ne peuvent pas sortir de la zone définie par.

Objectif
Certaines formes disposent de poignées, sous l'aspect de ronds jaunes, qui permettent de déformer la forme, par exemple le sourire gai/triste de la frimousse. Nous allons voir comment en gérer une pour une forme très simple : un triangle dont le côté gauche est vertical et le sommet opposé sur le côté droit sera mobile verticalement à l'aide d'une poignée. Une forme peut cependant comporter plusieurs poignées.

Le triangle est dessiné dans un patron de 10x10. Les coordonnées fixées de ses trois angles sont (0;0), (10;6) et (0;10) comme sur cette figure :

Tracé sans la poignée
En s'inspirant du codage XML du rectangle de la section Le code XML ci-dessus, on obtient le code suivant :

Veuillez noter que le  se termine par la commande Z. Pourquoi ne pas relier au point de départ (0;0) à l'aide d'un point supplémentaire ? L'utilisation d'une commande L ne fermerait pas la figure en polygone, mais formerait une polyligne de quatre points, dont le dernier point tomberait par accident sur le premier. Il ne serait pas possible d'y appliquer un remplissage par exemple. La commande Z permet donc de former un polygone avec trois points.

Création de la poignée
La poignée peut être déplacée par cliquer-glisser sur le cercle jaune. Ses coordonnées sont variables. La forme a donc besoin de disposer de ces valeurs variables. Cela s'obtient à l'aide de l'attribut  de l'élément , qui contient une liste de valeurs, en général une par poignée car une poignée n'a en général qu'un degré de liberté. Si la poignée a ses deux degrés de liberté, alors il faut prévoir deux valeurs. La valeur indiquée dans le code XML correspond à la valeur initiale, mais elle sera modifiée dès que l'on déplacera la poignée. 

La poignée elle-même est constituée d'un élément, un sous-élément de l'élément. Ce sous-élément dispose d'un attribut  avec les coordonnées x et y de la poignée. Pour que la poignée se déplace verticalement sur le côté droit, la valeur de x est fixée à 10, alors que la valeur y doit prendre la position de la poignée. Cette position est récupérée à l'aide d'une référence, codée avec le caratère $ suivi par un entier correspondant au numéro de la poignée suivant l'ordre de l'attribut. La numérotation commence à 0. Le code est donc le suivant :

Notez que l'élément  n'a pas de sous-élément, et peut donc utiliser une balise combinée début-fin, alors que l'élément   a maintenant un sous-élément et nécessite alors une balise de fin séparée.

Utilisation de la poignée
Vous pouvez enregistrer le fichier et observer le comportement de la poignée dans LibreOffice : le triangle n'a pas changé, une poignée est apparue à son sommet droit ; vous pouvez déplacer la poignée verticalement, mais le sommet ne suit pas la poignée pour le moment. Il suffit de remplacer l'ordonnée de ce point par la référence à la valeur de la poignée avec la même syntaxe : draw:enhanced-path="M 0 0 L 10 $0 0 10 Z" Le code final est donc : Vous pouvez enregistrer le fichier et jouer avec la poignée : le triangle se déforme mais conserve sa pointe sur la verticale.

Limitation de la plage de la poignée
Vous remarquerez que vous pouvez même sortir de la zone définie par le patron du début. Si vous souhaitez l'empêcher, vous pouvez fixer des valeurs minimales et maximales à la référence. Ajoutez les attributs  et   ou   et   au sous-élément. Le code devient : Ainsi la poignée se retrouve bloquée à l'intérieur de la zone définie par.

Application au point de collage
Un point de collage peut se déplacer avec la poignée, ou même être confondu avec la poignée. Il suffit d'utiliser la référence à la valeur de la poignée dans les coordonnées du point de collage : draw:glue-points="10 $0" Ce qui donne le code : Notez que contrairement à la poignée ou au tracé du polygone, les points de collage ne peuvent pas sortir de la zone définie par  (voir ).

Premier essai
Cet exemple va vous montrer comment utiliser des formules pour calculer les coordonnées des points de votre forme. En particulier lorsque vous utilisez une poignée, la forme se déforme et certains points doivent être recalculés en fonction de la position de la poignée. Nous allons utiliser l'exemple du parallélogramme qui a un côté gauche vertical fixe et le côté opposé qui sera déplaçable verticalement, comme sur cette figure : Le système de coordonnées choisi reste dimensionné à 10x10. En repartant de l'exemple du triangle ci-dessus, ce n'est pas très difficile à construire, sauf en ce qui concerne le coin inférieur droit. Un premier essai pourrait ressembler à : Cependant ce tracé ne fonctionne pas, car il contient  dans le chemin qui n'est pas reconnu : il n'est pas possible d'utiliser une expression comme paramètre d'une commande. Un nouvel élément est nécessaire, ce sera l'élément.

L'élément
L'élément  est un sous-élément de. Il contient deux attributs :  et. Il ne contient pas de sous-élément et est donc combiné dans une balise début-fin :  Le nom de la formule est utilisé pour faire référence à la valeur. La spécification d'ODF permet de choisir n'importe quel nom arbitraire, mais LibreOffice convertira systématiquement les noms en  etc. Pour identifier vos formules, il est donc plus facile d'utiliser dès le début ces noms.

L'expression de la formule est indiquée dans l'attribut. En plus des opérateurs arithmétiques +, -, *, /, vous pouvez utilisez quelques fonctions (par exemple  pour la racine carrée (square root)) et quelques constantes (comme  ). Vous en trouverez une liste complète au chapitre 19.171 draw:formula des spécifications ou dans le tableau ci-dessous.

Application à l'exemple
Pour revenir à notre exemple, la formule est donc  et se code ainsi :  Dans l'expression du chemin, il faut utiliser une référence à cette formule à l'aide du caractère ? immédiatement suivi du nom de l'équation. Le chemin devient : draw:enhanced-path="M 0 0 L 10 $0 10 ?f0 0 10 Z" L'ensemble de l'élément  s'écrit :

Liste des fonctions utilisables dans une formule
La liste fournie par les spécifications est donnée dans le tableau suivant. Note : la spécification ODF donne le degré comme unité d'angle mais LibreOffice utilise le radian.

= Bibliographie = Quelques liens (en anglais) pour creuser la question :
 * Ce tutoriel est basé sur celui écrit par Regina Henschel pour AOO.
 * Eisenberg, J. David
 * Creating Custom Shapes.2005.
 * http://books.evc-cit.info/odbook/custom_shapes_article.odt [vérifié le 30 juin 2013]


 * OpenDocument-v1.2-part1
 * Open Document Format for Office Applications (OpenDocument) Version 1.2
 * Part1: OpenDocument Schema. 29 September 2011. OASIS Standard.
 * http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html.


 * W3C SVG Working Group
 * SVG 1.1 Second Edition Recommendation. 16 August 2011.
 * http://www.w3.org/TR/SVG/Overview.html