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:
MP3PrtIni
'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] ML0 © Travail en mode normal
[2] :If 0=NC'G'
[3] G'PR' © Nom
par défaut = "PR"
[4] :End
[5] D1+/'lL'¹D © Orientation
"P" ou "L"
[6] vo'Orientation'(D'Portrait'
'Landscape')
[7] G WC'Printer'vo © Création
de l'objet Printer
[8] vrG WG'DevCaps' © Ses capacités de représentation
[9] vl vc2vr © Dimensions
d'une page, en mm
[10] vm(/1vr)÷3369 © Facteur multiplicatif des polices
[11] vv('YRange' 0 vl)('XRange' 0 vc) © Coordonnées
[12] G WC'Printer'vo('Coord' 'User'),vv
[13] Rvl 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.