Imprimer sous Windows avec Dyalog APL

      par Bernard Legrand
       Legrand Consultants

1 - Préambule

Autrefois, pour imprimer des résultats, la solution simple consistait à fabriquer un fichier de texte puis à demander au système de l'imprimer. C'est une méthode assez pauvre, puisqu'elle ne permet ni de bénéficier des multiples polices de caractères de Windows, ni de tracer des encadrements, ni des graphiques.

Sous Dyalog APL, on imprime en s'appuyant sur les ressources de Windows, moyen d'un "objet" spécial, appelé Printer, qui représente à la fois le lien avec l'imprimante, et le contenu d'une unique page de papier.

On peut alors choisir ses polices de caractères, ses couleurs, tracer des cadres, tracer des graphiques, etc ...

Mais l'usage de l'objet Printer demande un peu de doigté ou de savoir-faire ; c'est pourquoi j'ai souhaité publier ici un document extrait des supports de cours que j'ai rédigés pour mes séminaires de formation à l'usage de Dyalog APL sous Windows.

Cet article se veut avant tout simple et pratique ; il n'épuise donc pas le sujet.

Si d'aventure il épuisait certains lecteurs, je leur saurais gré de me le faire savoir.

Voici comment est organisé ce document :

2                                           Généralités Comment créer l'objet "Printer"
3   Systèmes de coordonnées Comment travailler en millimètres
4   Les imprimantes une imprimante et la paramétrer
5   Les polices de caractères
6   Instructions d'écriture Comment rédiger l'ordre d'écriture
7   Contrôle de l'impression Sauts de pages et impression physique
8   Utilitaires
9   Exemple

2 - Généralités

 

Il est conseillé, dès la création de l'objet Printer, d'imposer l'orientation du papier, en spécifiant "Portrait" ou "Landscape" selon le cas.

La création de cet objet s'effectue alors ainsi :

'Pr' Œwc 'Printer' ('Orientation' 'Portrait')

Une fois cette page définie, on peut y écrire du texte ou des lignes destinées à encadrer ce texte. On peut aussi y placer des graphiques.

Les objets ainsi écrits dans la page se superposent les uns aux autres, sans qu'il soit possible d'en effacer aucun.

Une fois la page prête, on l'envoie à l'imprimante, et on en commence une nouvelle si nécessaire.

C'est donc au programmeur de faire son découpage en pages, comme il est d'usage.

3 - Les Systèmes de coordonnées

·     Par défaut, les coordonnées et la taille de chaque objet sont données en pourcentages de la page. Ce système "proportionnel" proposé par défaut n'est guère exploitable ; cherchons autre chose.

·     Comme la résolution d'une imprimante s'exprime en points par pouce, ou "dpi" (dots per inch), on pourrait aussi raisonner en "points". Les premières imprimantes laser avaient une résolution de 300 dpi ; on arrive aujourd'hui à 1.200 dpi. Pour utiliser un tel système de coordonnées, il faudrait créer l'objet Printer comme suit :

'PR' ŒWC 'Printer' ('Coord' 'Pixel')

·     Mais un tel système ne serait guère plus parlant. En effet, si un programme fait imprimer un texte à 300 points de la marge gauche, le résultat visuel sera différent selon que l'imprimante a une résolution de 300 ou de 600 dpi.

Il est infiniment préférable de travailler dans une unité simple et facile à mesurer sur une feuille : le millimètre.

Pour y parvenir, une fois créé le lien avec l'imprimante, il faut demander quelles sont ses capacités de représentation (DevCaps), puis définir un système de coordonnées personnalisées (User) exactement calqué sur les capacités de l'imprimante.

Exemple :

     'PR' ŒWC 'Printer' ('Orientation' 'Portrait')
     'PR' ŒWC 'DevCaps'
3369 2323  285 197  2

Cette réponse indique que la page de papier mesure 3369 sur 2323 "points", ou encore 285 sur 197 millimètres.

En réalité, une page A4 mesure 297 sur 210 millimètres, mais l'imprimante impose une marge d'environ 6 à 7 mm à la périphérie.

La valeur 2 indique une imprimante 2 couleurs (noir et blanc).

On peut alors définir un système de coordonnées avec Y variant entre 0 et 285, et X variant entre 0 et 197.

Pour cela, il faut redéfinir l'objet Printer, car le choix des coordonnées doit être fait au moment du ŒWC et non à la faveur d'un ŒWS ultérieur :

'PR' ŒWC 'Printer' ('Orientation' 'Portrait')
    ('Coord' 'User')('YRange' 0 285)('XRange' 0 197)

(l'instruction, trop longue, est ici repliée pour les besoins de la revue)

Ces opérations peuvent être prises en charge par une fonction d'initialisation, comme par exemple la fonction PrtIni, fournie par Legrand Consultants dans l'espace de travail "SemUtil". On en trouvera une copie en fin d'article.

4 - Les Imprimantes

4.1 - Choix de l'imprimante

La liste des imprimantes disponibles sur le système s'obtient par

      †'.' Œwg 'PrintList'

HPL4,\\Serveur\hpl4   
HP LaserJet 4L,LPT1:  
HP DeskJet 660C,LPT1:
HP LaserJet 4/4M,LPT1:

La première ligne indique le "driver" (pilote) d'imprimante qui sera utilisé par défaut.

Lors de la création de l'objet "Printer", on peut décider d'utiliser une autre imprimante. Il suffit, après le mot "Printer", de spécifier le paramètre "PName", comme suit :

'PR' ŒWC 'Printer' 'HP DeskJet 660C,LPT1:'

Le mot-clé "PName" n'est utile que si le paramètre n'est pas spécifié en seconde position. Attention à bien orthographier le nom du driver, jusqu'au double-point final éventuel (" : ").

4.2 - Paramétrage de l'imprimante

La boîte de paramétrage d'imprimante s'obtient par : 1 ŒNQ 'PR' 101

5 - Choix des Polices de caractères

5.1 - Polices disponibles

La liste des polices disponibles s'obtient par

†'.'  Œwg 'FontList'    Polices connues de Windows
†'PR' Œwg 'FontList'       Polices connues de l'imprimante

Les noms des polices sont suivis de 6 paramètres numériques.

1 -                      Taille           des caractères.                         Ce paramètre doit toujours être spécifié
2 -      La                            police est-elle                  fixe (1) ou proportionnelle (0) ?
          Ce paramètre "Read-Only" ne peut pas être modifié
3 -      Impression italique ou non
4 -      Impression soulignée ou non
5 -      Épaisseur du trait, entre 0 et 1000
6 -      Angle de rotation en radians par rapport à l'axe des X.

Cet angle de rotation ne peut pas être spécifié "à la volée", il doit être spécifié à la faveur de la création d'un "objet font" (voir ci-dessous).

5.2 - Choix d'une police

On peut spécifier avec quelle police sera imprimé un texte au moyen d'un paramètre "Font" placé "à la volée", sur la même ligne. Par exemple

'PR.' ŒWC 'Text' Matrice (20 20)('Font' 'Arial' 60)

Cette technique est suffisante pour un usage élémentaire.

Mais la police "Arial" connue de Windows n'a peut-être pas rigoureusement la même définition (disons la même "métrique") que celle qui a été vendue avec l'imprimante.

Or, pour faire des impressions de précision, il faut savoir exactement quelle place occupera un texte. Il faut donc s'assurer que la police dont on parle est bien celle de l'imprimante et non celle de Windows.

Pour cela, il faut que l'objet "Font" soit créé comme enfant de l'objet "Printer", et l'employer ensuite dans les instructions d'écriture. Ci-après, la première instruction crée un objet "Font", et la seconde instruction s'esn sert pour écrire un texte :

'PR.F1' ŒWC 'Font' 'Arial' 80
'PR.'   ŒWC 'Text' Matrice (20 20)('Font' 'PR.F1')

Imaginons qu'on veuille imprimer un texte verticalement. On fera subir à la police une rotation égale à p/2, au moyen de la fonction trigonométrique ± , comme ici :

'PR.F2' ŒWC 'Font' 'Arial' 80 0 0 0 800, ±0.5
'PR.'   ŒWC 'Text' 'Essai' (20 20)('Font' 'PR.F2')

5.3 - Taille des caractères

La taille d'un caractère (son "corps") est fournie par le paramètre qui suit le nom de la police (80 dans l'exemple précédent). Mais l'effet produit dépend de la résolution de l'imprimante. Un caractère de "corps" 80, qui fait environ 4mm de haut sur une imprimante 300 dpi, n'en fera plus que 2 sur une imprimante 600 dpi.

Quand on indique la taille d'un caractère, il faut tenir compte de ce facteur.

Une technique simple consiste à indiquer quelle taille on souhaite donner aux caractères sur une imprimante familière, qu'on connaît bien (par exemple une 300 dpi), et multiplier cette taille par un facteur d'autant plus grand que l'imprimante réellement utilisée a une plus grande résolution.

Pour faciliter ce travail, la fonction PrtIni, déjà évoquée, donne un résultat de 3 éléments.

-  Les deux premiers sont la taille effective de la page, en millimètres (285 197 dans notre exemple),

-  Le dernier est le facteur par lequel il faut multiplier un "corps" exprimé pour une imprimante 300 dpi.

Exemple :

On définit un objet Printer, et on note le facteur multiplicatif de police MP:

   MP„3œPrtIni 'P'

Ayant fait des essais sur une imprimante 300 dpi, nous aimerions :

- écrire les textes normaux en corps 48
- écrire les titres en corps 90, en italiques

Pour que l'effet visuel soit préservé quelle que soit l'imprimante utilisée, on définira deux objets "Font" appropriés comme suit :

'PR.Fn' ŒWC 'Font' 'Dyalog Std TT' (—48×MP)
'PR.Ft' ŒWC 'Font' 'Arial' (—90×MP) 0 1

6 - Instructions d'écriture

Comme les objets écrits dans une page ne peuvent plus être effacés on modifiés, il est inutile de leur donner un nom complet. Par contre, le point qui suit le nom de l'objet Printer est indispensable. Par exemple :

'PR.' ŒWC 'Text' Matrice (20 20)('Font' 'PR.F1')

7 - Contrôle de l'impression

7.1 - Sauts de pages

Si un programme doit enchaîner l'impression de plusieurs pages (imaginons 20 pages), il n'est pas conseillé de les envoyer l'une après l'autre à l'imprimante. En effet, si on découvre qu'on a commis une erreur et qu'on veuille arrêter ce flot d'impression, ce sont 20 documents qu'il faudra intercepter et détruire au moyen du "Gestionnaire d'impression" de Windows, ce qui est particulièrement mal commode.

La bonne technique consiste à programmer un saut de page au moyen de :

     1 ŒNQ 'PR' 100

Cette instruction fige la page en l'état, et la prépare en vue de son impression.
On se trouve à nouveau devant une page vierge dans laquelle on peut écrire.

7.2 - Fin de travail

En fin de travail, pour envoyer ce qu'on a préparé à l'imprimante, il suffit :

- soit d'effacer explicitement l'objet Printer par  ŒEX 'PR'
- soit de localiser PR dans le titre du programme d'impression
- soit d'envoyer le document à l'imprimante par
 1 ŒNQ 'PR' 100

Dans le cas où on n'imprime qu'une seule page, on emploie directement cette technique, sans écrire de saut de page préalable.

8 - Utilitaires

L'espace de travail SemUtil que je donne au cours de mes séminaires contient, entre autres, les fonctions utilitaires suivantes :

PrtIni           Initialise un "Printer" avec des coordonnées en millimètres
PrtGrid    Trace un carroyage dans une page                        
PrtNum                Place des nombres  dans une page                       
PrtTexUni         Place une matrice de texte dans une page, en un seul bloc
PrtTexMul           Idem, mais chaque ligne est écrite à un emplacement spécifique

La fonction PrtIni attend "P" ou "L" en opérande droit, pour contrôler la présentation pu papier à la Française ou à l'Italienne.

Par défaut, elle fabrique un objet Printer nommé "PR". Si on veut imposer un autre nom, il suffit de le passer en opérande gauche. Par exemple ;

   'WinPrt' PrtIni 'L'

Cette fonction donne un résultat composé de trois nombres (voir § 5.3).

  ’ {R}„{G}PrtIni D;vc;vl;vm;vo;vr;vv;ŒML
[1]  ŒML„0                  © Travail en mode normal
[2]  :If 0=ŒNC'G'
[3]      G„'PR'             © Nom par défaut = "PR"
[4]  :End
[5]  D„1+Ÿ/'lL'¹D           © Orientation "P" ou "L"
[6]  vo„'Orientation'(Dœ'Portrait' 'Landscape')
[7]  G ŒWC'Printer'vo       © Création de l'objet Printer
[8]  vr„G ŒWG'DevCaps'      © Ses capacités de représentation
[9]  vl vc„2œvr             © Dimensions d'une page, en mm
[10] vm„(—/œ1†vr)÷3369      © Facteur multiplicatif des polices
[11] vv„('YRange' 0 vl)('XRange' 0 vc) © Coordonnées
[12] G ŒWC'Printer'vo('Coord' 'User'),vv
[13] R„vl vc vm
   

L'espace de travail contient aussi une fonction de démonstration nommée DemoPrt qui enchaîne divers travaux d'impression s'appuyant sur les utilitaires évoqués plus haut, mais le résultat produit pouvant être difficile à reproduire à l'impression, il a été un peu édulcoré pour les besoins de la revue.

On y voit l'usage de différentes polices, le tracé de cadres dans lesquels on a écrit du texte ou des nombres, des encadrements avec coins arrondis, et un graphique très simplifié pour les besoins de la reproduction.

J'espère que ces éléments faciliteront la vie aux nombreux utilisateurs de Dyalog APL.