Pascal sur Macintosh (et sur Vax Berkeley par l'intermédiaire de
l'émulateur terminal TGiX de Philippe Chassignet, cf Le manuel
TGiX, version 2.2) donne la
possibilité de faire très simplement des fonctions graphiques,
grâce à une interface très simple avec la bibliothèque QuickDraw
du Macintosh. Sur Macintosh, une fenêtre Drawing permet de
gérer un écran de
points. L'origine du système de
coordonnées est en haut et à gauche. L'axe des
va classiquement
de la gauche vers la droite, l'axe des
va plus curieusement du
haut vers le bas (c'est une vieille tradition de l'informatique, dure
à remettre en cause). En QuickDraw,
et
sont souvent appelés
h (horizontal) et v (vertical). Il y a une notion de
point courant et de crayon avec une taille et une couleur courantes.
On peut déplacer le crayon, en le levant ou en dessinant des vecteurs
par les fonctions suivantes
MoveTo (x, y)
x, y.
Move (dx, dy)
dx, dy.
LineTo (x, y)
x, y.
Line (dx, dy)
dx, dy)
depuis le point courant.
PenPat(pattern)
white, black, gray, dkGray (dark
gray), ltGray (light gray).
PenSize(dx, dy)
PenMode(mode)
patCopy (mode par défaut qui efface ce sur quoi on
trace), patOr (mode Union, i.e. sans effacer ce sur quoi on
trace), patXor (mode Xor, i.e. en inversant ce sur quoi on
trace).
Certaines opérations sont possibles sur les rectangles. Un
rectangle r a un type prédéfini Rect. Ce type est en
fait un record qui a le format suivant
type
VHSelect = (V, H);
Point = record case indicateur of
0: (v: integer;
h: integer);
1: (vh: array [VHSelect] of integer)
end;
Rect = record case indicateur of
0: (top: integer;
left: integer;
bottom: integer;
right: integer);
1: (topLeft: Point;
botRight: Point);
end;
Fort heureusement, il n'y a pas besoin de connaître le format internes des rectangles, et on peut faire simplement les opérations graphiques suivantes sur les rectangles
SetRect(r, g, h, d, b)
r. C'est équivalent à faire
les opérations r.left := g;, r.top := h;,
r.right := d;, r.bottom := b.
UnionRect(r1, r2, r)
r
comme l'enveloppe englobante des rectangles r1 et r2.
FrameRect(r)
r
avec la largeur, la couleur et le mode du crayon courant.
PaintRect(r)
r
avec la couleur courante.
InvertRect(r)
r.
EraseRect(r)
r.
FillRect(r,pat)
r avec la couleur pat.
DrawChar(c), DrawString(s)
c ou la chaîne s au point courant dans la fenêtre
graphique. Ces fonctions diffèrent de write ou writeln
qui écrivent dans la fenêtre texte.
FrameOval(r)
r avec la largeur, la couleur et le mode du
crayon courant.
PaintOval(r)
r avec la couleur courante.
InvertOval(r)
r.
EraseOval(r)
r.
FillOval(r,pat)
r avec la couleur pat.
FrameArc(r,start,arc)
r démarrant à l'angle start
et sur la longueur définie par l'angle arc.
FrameArc(r,start,arc)
Button
GetMouse(p)
p le point de
coordonnées
courantes du curseur.
GetPixel(p)
p.
Répond un booléen: false si blanc, true. si noir.
HideCursor, ShowCursor
Dans le fichier <MacLib.h> du directory
/usr/local/pascal/vax sur Vax, on trouve toutes les signatures
des fonctiosn de QuickDraw, qui sont par ailleurs définies dans le
document Inside The Macinstosh. Voici quelques exemples. La
procédure suivante permet de lire les coordonnées d'un point, quand
on appuie sur le bouton de la souris.
procedure GetXY (var x, y: integer);
const N = 2;
var r: Rect; p: Point;
begin
while not Button do (* - *)
;
GetMouse (p); (* - *)
x := p.h; y := p.v;
SetRect (r, x-N, y-N, x+N, y+N);
PaintOval (r); (* On affiche le point pour signifier la lecture *)
while Button do (* - *)
;
end;
Mais la lecture est souvent plus commode sur le front montant.
procedure GetXY (var x, y: integer);
const N = 2;
var r: Rect; p: Point;
begin
while not Button do (* - *)
;
while Button do (* - *)
;
GetMouse (p); (* - *)
x := p.h; y := p.v;
SetRect (r, x-N, y-N, x+N, y+N);
PaintOval (r); (* On affiche le point pour signifier la lecture *)
end;
Un exemple plus amusant est le programme qui fait rebondir une balle dans un rectangle première étape vers un pong.
program Pong;
const
C = 5; (* Le rayon de la balle *)
X0 = 5; X1 = 250;
Y0 = 5; Y1 = 180;
var
x, y, dx, dy: integer;
r, s: Rect;
i: integer;
procedure GetXY (var x, y: integer);
begin
...
end;
begin
SetRect(s, 50, 50, X1 + 100, Y1 + 100);
SetDrawingRect(s); (* - *)
ShowDrawing; (* - *)
SetRect(s, X0, Y0, X1, Y1);
FrameRect(s); (* Le rectangle de jeu *)
GetXY(x, y); (* - *)
dx := 1; (* La vitesse initiale *)
dy := 1; (* de la balle *)
while true do
begin
SetRect(r, x - C, y - C, x + C, y + C);
PaintOval(r); (* On dessine la balle en $x,y$ *)
x := x + dx;
if (x - C <= X0 + 1) or (x + C >= X1 - 1) then
dx := -dx;
y := y + dy;
if (y - C <= Y0 + 1) or (y + C >= Y1 - 1) then
dy := -dy;
for i := 1 to 500 do
; (* On temporise *)
InvertOval(r); (* On efface la balle *)
end;
end.