L'encapsulation
La commande "lpgrp"

--ooOoo--

     Le professeur de mathématiques m'exposa ses difficultés pour démarrer. Il me confirma un peu plus en détail ce qu'il attendait de ce type de fonction. Il était plutôt intéressé par l'aspect graphique pour permettre à ses élèves d'afficher des courbes étudiées en classe. Il devait donc pratiquement faire un programme à chaque type d'étude. De plus, l'aspect "saisie" de l'interactivité devait être prise un minimum en compte. Je lui objectais qu'une méthode plus générale devrait être préférable et que, de toutes manières, il lui faudrait traiter des primitives normalisées dont les élèves devraient apprendre le codage.

     J'étais en train de travailler sur mes curses personnelles "jprs" à ce moment-là pour écrire une petite commande "lpgdb" de debugging interactif qui encapsule la commande standard "gdb" de Linux, simplement pour évaluer la difficulté, pour voir, par curiosité. Je lui proposai de l'aider un peu plus en tâchant de réaliser un outil un peu plus général basé sur des primitives délibérément orientées graphiques. Je lui en expliquai les principes et la manière de l'aborder dans ses grandes lignes.

     Personnellement, je regrette que, pour des raisons d'indisponibilité de part et d'autre, il n'ait pas pu suivre de plus près l'évolution de la programmation de cette commande "lpgrp", les corrections, les examens et les vacances d'été approchant à grands pas n'ayant rien arrangé aux choses.

     Le développement étant en cours d'élaboration donc incomplet, j'en présente ici ses aspects théoriques et fonctionnels :

I - Les structures graphiques :

     Pour présenter des courbes et plus généralement des dessins, l'utilisateur doit suivre quelques principes de composition du document qu'il compte réaliser. La figure ci-dessous illustre la structure des images de la composition de l'exemple "lissajous" :

     Pour élaborer sa composition, l'utilisateur doit effectuer les opérations suivantes :

     Dans la commande "lpgrp", la notion d'image est repérée par un numéro, ce que nous verrons au § II  :

(*Remarque :

     Si l'on regarde les images de plus prêt, l'image A par exemple, la peau de caoutchouc rectangulaire blanche peut être considérée comme un support sur laquelle sont projetées les trois figurines, le titre "Programme Fortran", le sous-titre "une illustration des pseudo-terminaux" et le trait horizontal vert. On peut raisonner de même avec les autres images.

     Si l'on descend encore une fois dans la décomposition, on pourrait imaginer que le titre "Programme Fortran" soit aussi une figurine qui est plaquée sur un support rectangulaire qui, lui-même, est projeté sur le support rectangulaire blanc de l'image A qui, à son tour, sera projetée sur le support P.

     On en déduit donc que le concept d'image illustré ici est un concept récursif et qu'une image peut être décomposée en une suite d'images "fille-mère" en cascade.

     On se trouve alors devant des entités graphiques :

     Cette théorie est appliquée dans le développement du "Noyau Graphique d'Images Structurées" (NGIS) limitée aux images dans le plan (2D).

II - Les attributs des primitives graphiques :

     Les primitives graphiques s'appuient sur la bibliothèque 'SDL'. Leur approche tente de coller le plus possible au comportement naturel en la matière. Il faut rappeler que ces primitives sont des textes envoyés dans le "stdout" du programme encapsulé. Elles sont réunies sous la forme de fonctions dans le source "lpgrp_graph.c".

     Remarquer au passage la faible qualité des caractères représentant les codes des couleurs et des grains. Cette qualité est très limite au niveau de la librairie TTF de la SDL, cela n'arrange pas les choses quand on traite les textes pour qu'ils se placent exactement dans des images appropriées définies par l'utilisateur.

     Presque toutes les directives admettent un attribut comme paramètre en tant que chaîne de caractères où chaque caractère positionnel définit.




III - Les primitives graphiques :

     Dans le nom de la primitive, le caractère "*" marqué optionnel par les accolades "{" et "}" indique que l'utilisateur demande à la commande "lpgrp" d'afficher la primitive à traiter dans la zone-dialogue (couleur magenta).

Attention : 1) - 

Pour éviter des surprises de fonctionnement, il est conseillé en C de terminer toutes les sorties sur le 'stdout' par un '\n' (new line).

  2) - 

Ne pas omettre le lancement d'un ordre de lecture sur le 'stdin' pour pouvoir laisser l'image à l'écran précédé d'une primitive "$rafraîchir:" pour mettre à jour l'image du support de diffusion.

"$support{*}: ouverture du support de diffusion (l'image primaire ou physique)
"$ferme{*}: fermeture du support de diffusion
"$image{*}: ouverture d'une image en unités utilisateurs
"$trace{*}: tracé d'un vecteur
"$rafraichir{*}: mise à jour du support de diffusion
"$palette{*}: modification d'une couleur de la palette

     La primitive "$support:" est la première primitive à appeler. Elle ouvre l'image du support de diffusion appelée aussi "image primaire" ou "image physique". C'est celle qui est appliquée sur le périphérique physique (ici c'est une fenêtre-écran). La primitive doit être codée comme suit :

$support{*}: <attribut> <largeur> <hauteur> <titre>

 
attribut : attribut de l'image de fond (description ci-dessus).
largeur : largeur du cadre exprimé en pixels
hauteur : hauteur du cadre exprimé en pixels
titre :

texte à afficher sur le bandeau de la fenêtre. Tous les blancs doivent être marqués par '_' pour faire une chaîne continue..... en attendant mieux !...

Exemple :

"$support*: 351051 800 600 --_attributs_\'lpgrp\'_--"

     La primitive "$ferme:" est la dernière primitive à appeler avant de sortir du programme. Elle ferme l'image du support de diffusion ouverte avec la primitive "$support". La primitive doit être codée comme suit :

$ferme{*}:

  Exemple :

"$ferme*:"

     La primitive "$image:" permet d'ouvrir une image de la composition appelée aussi "image secondaire" ou "image sujet". C'est celle qui est appliquée sur le support de diffusion. L'utilisateur définit grâce à cette primitive un système d'unités qui lui est propre.

     Remarquer que, dans pratiquement tous les logiciels de dessin, il est demandé dans quel système d'unités le programme doit travailler. Il me semble que cette notion est superflue car l'utilisateur doit être libre de définir son propre système d'unités. Il doit même avoir la possibilité de faire cohabiter simultanément des systèmes d'unités différents. Ici, les unités de mesure ne sont pas explicitées. Si l'utilisateur veut imprimer une composition sur une feuille de papier A4 à 300 points par inch avec 15 mm de marge tout autour, il devra alors ouvrir un support :

     Pour tracer des vecteurs et des textes dans son propre système d'unités, la primitive doit être codée comme suit :

a) - L'image est un rectangle :
  $image{*}:
<
image> <attribut> <xmin> <xmax> <ymin> <ymmax> <x1> <y1> <x2> <y2>

b) - l'image est un parallélogramme :
  $image{*}: <image> <attribut> <xmin> <xmax> <ymin> <ymax> <x1> <y1> <x2> <y2> <x0> <y0>

c) - l'image est un quadrilatère quelconque  :
  $image{*}: <image> <attribut> <xmin> <xmax> <ymin> <ymax> <x1> <y1> <x2> <y2> <x0> <y0> <x3> <y3>

 
image :

n° de 1 à 20 de l'image à ouvrir,

attribut :

attribut du fond de l'image (description ci-dessus),

xmin, xmax :

domaine des abscisses,

ymin, ymax :

domaine des ordonnées,

x1, y1 :

coordonnées du coin supérieur gauche de l'image dans le support de diffusion.

x2, y2 :

coordonnées du coin inférieur droit de l'image dans le support de diffusion.

x0, y0 :

coordonnées du coin inférieur gauche de l'image dans le support de diffusion.

x3, y3 :

coordonnées du coin supérieur droit de l'image dans le support de diffusion.


Exemples  :

1°) - L'image A se projette sur un rectangle A' avec une primitive du type :

"$image*: 20 0000c1 0 100 0 60 25 675 425 525"

2°) - L'image B se projette sur un parallélogramme B' avec une primitive du type :

$image*: 1 10001 -20 +20 -50 +200 80 200 400 90 30 70"

3°) - L'image C se projette sur un quadrilatère quelconque C' avec une primitive du type :

"$image*: 2 020tc -1 +1 -1 +1 100 510 400 390 50 300 290 490"

     La primitive "$trace:" permet de déplacer le point courant d'un image vers le point donné conformément à un attribut donné. La génération du vecteur par incréments de 1 pixel est basé sur l'algorithme de Bresenham.

     La primitive doit être codée comme suit :

  $trace{*}: <image> <attribut> <x> <y>

 
image :

n° de 1 à 20 d'une image ouverte,

attribut :

attribut du tracé de l'image (description ci-dessus),

x, y :

coordonnées du point à atteindre dans le système d'unités de l'utilisateur.

Exemples :

"$trace*: 2 0aa -0.5 0.8"
"$trace*: 2 2ar +0.85 -0.2"

Ici "-0.5" et "+0.85" sont des abscisses absolues, "0.8" est une ordonnées absolue et "-0.2" est un déplacement par rapport au point courant <-0.5 , 0.8>.

     La primitive "$ttf:" permet à l'utilisateur de tracer une chaîne de caractère avec une police TTF.

     Pour tracer un texte dans son propre système d'unités, la primitive doit être codée comme suit :

a) - Le texte s'étale sur un rectangle :
  $ttf{*}:
<
image> <attribut> <texte> <x1> <y1> <x2> <y2>

b) - Le texte s'étale sur un parallélogramme :
  $image{*}: <image> <attribut> <texte> <x1> <y1> <x2> <y2> <x0> <y0>

c) - Le texte s'étale sur un quadrilatère quelconque  :
  $image{*}: <image> <attribut> <texte> <x1> <y1> <x2> <y2> <x0> <y0> <x3> <y3>

 
image :

n° de 1 à 20 de l'image à ouvrir,

attribut :

attribut du texte (description ci-dessus),

texte :

chaîne de caractères à tracer. Les blancs doivent être marqués par le caractère '_' (blanc souligné),

x1, y1 :

coordonnées du coin supérieur gauche du texte dans le support de diffusion.

x2, y2 :

coordonnées du coin inférieur droit du texte dans le support de diffusion.

x0, y0 :

coordonnées du coin inférieur gauche du texte dans le support de diffusion.

x3, y3 :

coordonnées du coin supérieur droit du texte dans le support de diffusion.

Pour le moment :

Note 1
:
le texte est justifié dans tous les cas
Note 2
:
certains attributs ne sont pas traités, la librairie TTF de donnant pas tous les éléments pour les prendre en compte.

Exemple :

"$ttf*:  20  jq___comic.ttf  ___Programme_Fortran___  0 60 100 40"

     NOTE : La primitive est en attente d'écriture en fonction de la destiné du programme

     La primitive "$texte:" permet à l'utilisateur de tracer une chaîne de caractère avec une police propre au logiciel.

     Pour tracer un texte dans son propre système d'unités, la primitive doit être codée comme suit :

a) - Le texte s'étale sur un rectangle :
  $texte{*}:
<
image> <attribut> <texte> <x1> <y1> <x2> <y2>

b) - Le texte s'étale sur un parallélogramme :
  $texte{*}: <image> <attribut> <texte> <x1> <y1> <x2> <y2> <x0> <y0>

c) - Le texte s'étale sur un quadrilatère quelconque  :
  $texte{*}: <image> <attribut> <texte> <x1> <y1> <x2> <y2> <x0> <y0> <x3> <y3>

 
image :

n° de 1 à 20 de l'image à ouvrir,

attribut :

attribut du texte (description ci-dessus),

texte :

chaîne de caractères à tracer. Les blancs doivent être marqués par le caractère '_' (blanc souligné),

x1, y1 :

coordonnées du coin supérieur gauche du texte dans le support de diffusion.

x2, y2 :

coordonnées du coin inférieur droit du texte dans le support de diffusion.

x0, y0 :

coordonnées du coin inférieur gauche du texte dans le support de diffusion.

x3, y3 :

coordonnées du coin supérieur droit du texte dans le support de diffusion.

Pour le moment :

Note 1
:
le texte est justifié dans tous les cas
Note 2
:
certains attributs ne sont pas traités, la librairie TTF de donnant pas tous les éléments pour les prendre en compte.

Exemple :

"$texte*:  20  jn1fxlucida_handwriting.ttf  Illustration_des_pseudo-terminaux  0 60 100 40

 

     La primitive "$rafraichir:" est la primitive à appeler toutes les fois que l'on veut mettre à jour l'image du support de diffusion. La primitive doit être codée comme suit :

$rafraichir{*}:

  Exemple :

"$rafraichir*:"

     La primitive "$palette:" permet d'affecter à un code couleur ('0'-'9', 'A'-'V') une nouvelle composition RVB pour redéfinir une nouvelle couleur. La primitive doit être codée comme suit :

$palette{*}: <code> <rrr> <vvv> <bbb>
$palette{*}:
<
code> #<rrvvbb>

 
code : code de la couleur à modifier ('0'-'9', 'A'-'V').
rrr : valeur de la composante rouge (0-255)
vvv : valeur de la composante verte (0-255)
bbb :

valeur de la composante bleue (0-255)

rrvvbb :

valeur des trois composantes en hexadécimal('00'-'FF')

Exemple :

"$palette*: B 32 255 128"
"$palette*: B #ccabed"

--ooOoo--