home *** CD-ROM | disk | FTP | other *** search
- {--------------------------------------------------}
- { David A. SInclair }
- { COS 55b }
- { Assignment #6, Part 2: Paint program }
- { 90.03.26 }
- { Release notes: File system now works fine, as }
- { does Fill menu selection. }
- { Forthcoming: Printer driver for IBM/Epson }
- {--------------------------------------------------}
-
-
-
- program PasPaint;
- uses GRAPH, CRT;
-
- const
- minpx = 67; (* Picture area coordinates. *)
- minpy = 21;
- maxpx = 500;
- maxpy = 300;
-
- var loopcnt : integer;
- ximage : pointer;
- clearmsg : pointer;
- curx, cury : integer;
- oldx, oldy : integer;
- done : boolean;
- CurTS : textsettingstype;
- MenuTS : textsettingstype;
- PENFLAG : boolean;
-
- (*********************************************************)
- procedure moveit; FORWARD; (* Forward so we can use during subs*)
- (*********************************************************)
- procedure prepit;
- var driver,
- mode : integer; (* Init graphics.....*)
- begin
- driver := DETECT;
- initgraph(driver, mode, '');
- end;
- (*********************************************************)
- procedure startscr;
- const cop = 'Copryright (C) 1990';
- pname = 'PasPaint 1.0';
- author = 'by: David A. Sinclair';
- continue = '| Press any key to continue. |';
- var
- xstart : integer;
- begin
- setcolor(yellow);
- line(5,5,635,5);
- line(5,5,5,330);
- line(635,5,635,330);
- setcolor(white);
- Settextstyle(3, 0, 6);
- xstart := round((640-(textwidth(pname)))/2);
- Outtextxy(xstart, 70, pname);
- SetTextStyle(3, 0, 3);
- xstart := round((640-(textwidth(cop)))/2);
- Outtextxy(xstart, 140, cop);
- Settextstyle(1, 0, 4);
- xstart := round((640-(textwidth(author)))/2);
- Outtextxy(xstart, 220, author);
- settextstyle(0, 0, 1);
- setcolor(red);
- xstart := round((640 - (textwidth(continue)))/2);
- outtextxy(xstart, 330, continue);
- setcolor(yellow);
- line(5, 330, xstart, 330);
- line(xstart + textwidth(continue), 330, 635, 330);
- repeat
- delay(1); (* Intro screen..... *)
- until KEYPRESSED
- end;
- (*********************************************************)
- procedure setupscr;
- const statusl = ' Message Line: ';
- menu = ' MENU';
- mfile = ' File';
- mfont = ' Font'; (* Do menu bar ... *)
- mfill = ' Fill';
- mabout = ' Info.';
- mttool = ' A';
-
- var x,
- y : integer;
-
- begin
- Cleardevice;
- setbkcolor(white);
- setcolor(blue);
- PENFLAG := false;
- Rectangle(66,1,635,20); outtextxy(70,8,statusl);
- rectangle(2,20,66,330); outtextxy(8, 25, menu);
- rectangle(minpx, minpy, maxpx, maxpy);
- line(2, 30+(textheight(menu)), 66, 30+(textheight(menu)));
- line(2, 60, 66, 60); circle(33, 50, 10);
- line(2, 85, 66, 85); rectangle(8, 65, 28, 80);
- line(34, 60, 34, 85); line(40, 65, 60, 80);
- line(2, 110, 66, 110); outtextxy(8, 95, mfile);
- line(2, 135, 66, 135); outtextxy(8, 120, mfont);
- line(2, 160, 66, 160); line(34, 135, 34, 160);
- line(12, 140, 20, 140); line(12, 150, 20, 150);
- line(12, 140, 12, 150); line(20, 140, 20, 150);
- line(12, 143, 20, 143);
- line(12, 150, 16, 156); line(20, 150, 16, 156);
- outtextxy(40, 145, mttool);
- settextstyle(0,0,1);
- for loopcnt := 1 to 8 do
- begin
- line(2, 160 + 12*loopcnt, 66, 160 + 12*loopcnt);
- line(34, 135 + 12*loopcnt, 34, 160 + 12*loopcnt);
- setfillstyle(solidfill, loopcnt - 1);
- floodfill(4, 150 + 12*loopcnt, blue);
- setfillstyle(solidfill, loopcnt + 7);
- floodfill(40, 150 + 12*loopcnt, blue);
- end;
- line(2, 280, 66, 280); outtextxy(8, 265, mfill);
- outtextxy(8, 298, mabout);
- end;
- (*********************************************************)
- procedure xhair(x, y : integer);
- begin (* How you show the cursor. *)
- oldx := curx; oldy := cury;
- putimage(oldx, oldy, ximage^, xorput);
- curx := x; cury := y;
- putimage(curx, cury, ximage^, xorput);
- end;
- (*********************************************************)
- procedure init_xhair;
- var size : integer;
-
- begin (* Initialize crosshair cursor...*)
- curx := 200; cury := 200;
- line (curx-4, cury, curx+4, cury);
- line (curx, cury-4, curx, cury+4);
- size := imagesize(curx-4, cury-4, curx+4, cury+4);
- getmem(ximage, size);
- getimage(curx-4, cury-4, curx+4, cury+4, ximage^);
- setcolor(white);
- line (curx-4, cury, curx+4, cury);
- line(curx, cury-4, curx, cury+4);
- setcolor(black);
- putimage(curx, cury, ximage^, xorput);
- xhair(250, 250);
- end;
- (*********************************************************)
- procedure Init_Msg;
- const msx = 185;
- msy = 3; (* Initialize message line. *)
- mex = 625; (* Save clear space to clear line later. *)
- mey = 19;
- var size : integer;
-
- begin
- size := imagesize(msx, msy, mex, mey);
- getmem(clearmsg, size);
- getimage(msx, msy, mex, mey, clearmsg^);
- end;
- (*********************************************************)
- procedure Message( newmsg : string);
- var curcol : integer;
- begin
- curcol := getcolor; (* Takes string to output in message line. *)
- setcolor(red);
- putimage(185, 3, clearmsg^, 3);
- outtextxy(185, 8, newmsg);
- setcolor(curcol);
- end;
- (*********************************************************)
- procedure Mcolor(x, y:integer);
- var newcol : integer; (* Set curcol to menu selection. *)
- begin
- newcol := getpixel(x, y);
- setcolor(newcol);
- end;
- (*********************************************************)
- procedure Trim_XY(var x, y: integer);
-
- begin (* Keep within picture coords. *)
- if (x<minpx) then x:= minpx
- else if (x>maxpx) then x:= maxpx;
- if (y<minpy) then y:= minpy
- else if (y>maxpy) then y:= maxpy;
- end;
- (*********************************************************)
- procedure Do_circ;
- var dist: integer;
- dx, dy: integer; (* Make circle in cur color. *)
- centx, centy : integer;
-
- begin
- Message(' Place cursor on center point, then hit F5.');
- Moveit;
- centx := curx; centy := cury;
- Message(' Now place cursor on circle and hit F5 again.');
- moveit;
- dx := curx; dy := cury;
- Trim_XY(centx, centy);
- Trim_XY(dx, dy);
- dist := round(sqrt(((centx-dx)*(centx-dx) + (centy-dy)*(centy-dy))));
- circle(centx, centy, dist);
- message(' ');
- end;
- (*********************************************************)
- procedure Do_rect;
- var x1, y1: integer; (* User-determined rectangle.. *)
- x2, y2: integer;
-
- begin
- message(' Place cursor at upper left corner, then hit F5.');
- moveit;
- x1 := curx; y1:= cury;
- message(' Now go to lower right, and hit F5.');
- moveit;
- x2:= curx; y2:= cury;
- Trim_XY(x1, y1); Trim_XY(x2, y2);
- rectangle(x1, y1, x2, y2);
- message(' ');
- end;
- (*********************************************************)
- procedure Do_File;
- const mfile=' S(ave) L(oad) N(ew) or Q(uit)';
- var choice : char; (* File submenu...*)
- subch : char;
- {------------------------------------------}
- procedure Clearpic;
- begin
- message(' Clear picture? Y(es) or N(o)');
- subch := upcase(readkey);
- if subch = 'Y' then (* Clear picture window. *)
- begin
- putimage(curx, cury, ximage^, xorput);
- setviewport(minpx, minpy, maxpx, maxpy, clipon);
- clearviewport;
- setviewport(0, 0, 640, 345, true);
- end
- else message(' ')
- end;
- {------------------------------------------}
- procedure Leave;
- begin
- Message(' Exit PasPaint? Y(es) or N(o)');
- subch := upcase(readkey);
- case subch of (* Quit PasPaint *)
- 'Y' : DONE:=TRUE;
- end;
- Message(' ')
- end;
- {------------------------------------------}
- procedure save;
- var fchar : char; (* Save file to disk!! *)
- writ, tell, sfile : string;
- outf : file;
- index, totwrit, size : integer;
- pic : pointer;
- result : word;
-
- begin
- message(' File to save? (include pathname) ');
- fchar:= readkey;
- message(' ');
- sfile:= fchar;
- moveto(185, 8);
- outtext(fchar);
- while ord(fchar) <> 13 do
- begin
- fchar := readkey;
- sfile := sfile + fchar;
- outtext(fchar);
- end;
- index := length(sfile);
- delete(sfile, index, 1);
- size := imagesize(minpx, minpy, maxpx, maxpy);
- getmem(pic, size);
- getimage(minpx, minpy, maxpx, maxpy, pic^);
- assign(outf, sfile);
- message(sfile);
- readln;
- rewrite(outf, 1);
- blockwrite(outf, pic^, size, result);
- totwrit := filesize(outf);
- close(outf);
- freemem(pic, size);
- str(totwrit, writ);
- tell := writ + ' bytes written to file ' + sfile + '.';
- message(tell);
- end;
- {------------------------------------------}
- procedure load;
- var fsize, lfile : string;
- inpf : file; (* Load saved picture!! *)
- index, size : integer;
- lpic : pointer;
- fchar : char;
- result : word;
-
- begin
- message(' File to load? (include pathname) ');
- fchar:= readkey;
- message(' ');
- lfile:= fchar;
- moveto(185, 8);
- outtext(fchar);
- while ord(fchar) <> 13 do
- begin
- fchar := readkey;
- lfile := lfile + fchar;
- outtext(fchar);
- end;
- index := length(lfile);
- delete(lfile, index, 1);
- message(lfile);
- readln;
- assign(inpf, lfile);
- reset(inpf, 1);
- size := imagesize(minpx, minpy, maxpx, maxpy);
- getmem(lpic, size);
- blockread(inpf, lpic^, size, result);
- close(inpf);
- putimage(minpx, minpy, lpic^, 0);
- freemem(lpic, size);
- str(result, fsize);
- fsize := fsize + ' bytes read from file ' + lfile + '.';
- message(fsize);
- end;
- {------------------------------------------}
- begin
- Message(mfile);
- choice := upcase(readkey);
- case choice of
- 'S' : save;
- 'L' : load;
- 'N' : Clearpic;
- 'Q' : Leave;
- else message(' ')
- end
- end;
- (*********************************************************)
- procedure Do_font;
- const chfont=' Which? 0 (System) 1 (Triplex) 2 (Small) 3 (Gothic)';
- var fontch : char;
- begin
- message(chfont);
- fontch := readkey; (* Change text style for picture. *)
- case fontch of
- '0' : MenuTS.font:= 0;
- '1' : MenuTS.font:= 1;
- '2' : MenuTS.font:= 2;
- '3' : MenuTS.font:= 3;
- else MenuTS.font := CurTS.font;
- end;
- message(' Size? 1(pix) 4(pix) 8(pix)');
- fontch := readkey;
- case fontch of
- '1' : MenuTS.charsize:= 1;
- '4' : MenuTS.charsize:= 4;
- '8' : MenuTS.charsize:= 8;
- else MenuTS.charsize:= CurTS.Charsize;
- end;
- message(' H(orizontal) or V(ertical) Orientation?');
- fontch := upcase(readkey);
- case fontch of
- 'H' : MenuTS.direction:= 0;
- 'V' : MenuTS.direction:= 1;
- else MenuTS.direction:= CurTS.direction;
- end;
- message(' ');
- end;
- (*********************************************************)
- procedure DoUse;
- var tchar : char;
- tempx, tempy : integer;
- (* Put text in picture. *)
- begin
- Message(' Position cursor, then hit F5 and start typing.');
- Moveit;
- message(' Hit ENTER when done typing.');
- moveto(curx, cury);
- Settextstyle(MenuTS.font, MenuTS.direction, MenuTS.charsize);
- repeat
- tchar := readkey;
- outtext(tchar);
- until ord(tchar) = 13;
- Settextstyle(CurTS.font, Horizdir, CurTS.charsize);
- message(' ');
- end;
- (*********************************************************)
- procedure do_draw;
- var x, y :integer;
- begin
- message(' Position cursor, then hit F5 to start drawing.');
- moveit;
- PENFLAG := TRUE;
- message(' Hit F5 again to stop drawing.');
- moveto(curx, cury);
- moveit;
- PENFLAG := FALSE; (* Use pencil icon to draw. *)
- message(' ');
- end;
- (*********************************************************)
- procedure Do_line;
- var x1, y1: integer;
- x2, y2: integer;
- CurLN : linesettingstype;
- choice : char;
- width, style : word; (* Select line style; make line. *)
-
- begin
- getlinesettings(CurLN);
- Message(' Position cursor at first point, then hit F5.');
- moveit;
- x1 := curx; y1 := cury;
- Message(' Now position cursor on point two, and hit F5.');
- moveit;
- x2 := curx; y2 := cury;
- Message(' Line width? 1 (Normal) or 2 (Thick)');
- choice := readkey;
- case choice of
- '1' : width := Normwidth;
- '2' : width := ThickWidth;
- else width := CurLN.thickness;
- end;
- Message(' Type? 1 (Solid) or 2 (Dotted)');
- choice := readkey;
- case choice of
- '1' : style:= solidln;
- '2' : style:= dottedln;
- else style:= CurLN.linestyle;
- end;
- Setlinestyle(style, CurLN.pattern, width);
- Trim_XY(x1, y1); Trim_XY(x2, y2);
- line(x1, y1, x2, y2);
- Setlinestyle(CurLN.linestyle, CurLN.pattern, CurLN.thickness);
- message(' ');
- end;
- (*********************************************************)
- procedure Do_fill;
- var fillx, filly: integer;
- bordcol, fillcol, curcol: integer;
- oldpat: fillpatterntype;
- showcol: string;
- waitchar : char;
- (* Fill selected area with selected color. *)
- begin
- getfillpattern(oldpat);
- message(' Position cursor in area to be filled, then press F5.');
- moveit;
- fillx := curx; filly:= cury;
- curcol := getcolor;
- message(' Select fill color from palette (F5 to select).');
- moveit;
- fillcol := getpixel(curx, cury);
- message(' Select boundary color by moving to palette.');
- waitchar := readkey;
- message(' Hit F5 when cursor is on proper boundary color.');
- moveit;
- bordcol:= getpixel(curx, cury);
- setfillpattern(oldpat, fillcol);
- floodfill(fillx, filly, bordcol);
- message(' '); setcolor(curcol);
- end;
- (*********************************************************)
- procedure Do_about(curcol: integer);
- const exitm = 'Press any key to exit Help';
- var helpsp : pointer;
- size : integer;
- (* POP-UP HELP WINDOW!! NEAT!! *)
- begin
- message(' HELP SCREEN ACTIVE.');
- size := imagesize(100, 80, 600, 300);
- getmem(helpsp, size);
- getimage(100, 80, 600, 300, helpsp^);
- setviewport(100, 80, 600, 300, true);
- clearviewport;
- setcolor(red);
- rectangle(10, 10, 490, 210);
- setcolor(blue);
- settextstyle(3,0,4);
- outtextxy(round(((490-10) - textwidth('About PasPaint'))/2), 15, 'About PasPaint');
- settextstyle(0,0,1);
- outtextxy(20, 55, ' David A. Sinclair, COSI 55b 18 March 1990');
- outtextxy(20, 70, ' Cursor Movement Keys:');
- outtextxy(50, 85, '"j" : Horizontal Left "l" : Horizontal Right');
- outtextxy(50, 98, '"i" : Vertical Up "m" : Vertical Down');
- outtextxy(50, 111, '"o" : Up and Right "u" : Up and Left');
- outtextxy(50, 124, '"m" : Down and Left "," : Down and Right');
- outtextxy(20, 140, ' Other Command Keys:');
- outtextxy(50, 155, '"f" : Speed Up (Fast) "s" : Slow Down');
- outtextxy(50, 168, ' F1 : Select Menu Option or Position Cursor');
- outtextxy(round(((490-10)-textwidth(exitm))/2), 195, exitm);
- repeat
- delay(1);
- UNTIL keypressed;
- setviewport(0, 0, getmaxx, getmaxy, true);
- setcolor(curcol);
- putimage(100, 80, helpsp^, normalput);
- release(helpsp);
- message(' ');
- end;
- (*********************************************************)
- procedure find_func(x, y:integer);
- begin
- if (2<x) and (x<66) then (* Get function based on coords. *)
- if (y>160) and (y<245) then
- Mcolor(x, y)
- else if (y>35) and (y<60) then Do_circ
- else if (y>60) and (y<85) then begin
- if (x<34) then Do_rect
- else Do_Line
- end
- else if (y>85) and (y<110) then Do_file
- else if (y>110) and (y<135) then Do_font
- else if (y>135) and (y<160) then begin
- if (x<34) then Do_Draw
- else DoUse
- end
- else if (y>245) and (y<280) then Do_Fill
- else if (y>280) and (y<320) then Do_About(blue)
- end;
- (*********************************************************)
- procedure moveit;
- var which : char;
- newx, newy : integer;
- incr : integer;
- (* General cursor driver.. *)
- begin
- done := FALSE;
- incr := 5;
- repeat
- which := upcase(readkey);
- case which of
- 'N' : begin
- newx := curx-incr;
- newy := cury+incr;
- xhair(newx, newy);
- end;
- 'M' : begin
- newx := curx;
- newy := cury+incr;
- xhair(newx, newy);
- end;
- ',' : begin
- newx := curx+incr;
- newy := cury+incr;
- xhair(newx, newy);
- end;
- 'J' : begin
- newx := curx-incr;
- newy := cury;
- xhair(newx, newy);
- end;
- 'L' : begin
- newx := curx+incr;
- newy := cury;
- xhair(newx, newy);
- end;
- 'O' : begin
- newx := curx+incr;
- newy := cury-incr;
- xhair(newx, newy);
- end;
- 'I' : begin
- newx := curx;
- newy := cury-incr;
- xhair(newx, newy);
- end;
- 'U' : begin
- newx := curx-incr;
- newy := cury-incr;
- xhair(newx, newy);
- end;
- 'F' : incr := 5;
- 'S' : incr := 1;
- #0 : begin
- which := readkey;
- if ord(which) = 59 then
- find_func(curx+2, cury)
- else if ord(which) = 63 then EXIT
- end;
- end;
- if PENFLAG then if (curx<maxpx) and (curx>minpx) and (cury<maxpy) and (cury>minpy)
- then lineto(curx, cury);
- until DONE
- end;
- (*********************************************************)
- begin
- prepit;
- startscr;
- setupscr;
- init_xhair;
- init_msg;
- moveit;
- closegraph;
- end.