home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / library / dos / grafik / wct_unit / xgraph.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1991-12-04  |  9.3 KB  |  308 lines

  1. unit xgraph;
  2.  
  3. { Written by William C. Thompson (wct@po.cwru.edu) - 1991 }
  4.  
  5. { This unit was written for programs with heavy graphics usage.
  6.   There are a number of procedures to make graphics more bearable.
  7.   There are some procedures that do different drawings.
  8.   There are some procedures that can save/recall a screen image. }
  9.  
  10. { Designer's Notes:
  11.  
  12.   1. I have left some of the error checking, such as checking if
  13.      a file exists or not, out of the procedures.  That is the
  14.      responsibility of the programmer. }
  15.  
  16. interface
  17.  
  18. uses graph,math;
  19.  
  20. type
  21.   imagebuffer=array[0..65534] of byte;
  22.   image=record
  23.     p: ^imagebuffer;   { buffer for image }
  24.     size: word;   { size of image }
  25.     end;
  26.   { Instead of making p a generic pointer, I decided to make it
  27.     point to an array, so the contents of the array could be examined
  28.     more easily if the programmer so desired. }
  29.  
  30. var
  31.   europeanfont,complexfont,triplexscriptfont,scriptfont,simplefont:integer;
  32.  
  33. procedure setfillcolor(col:word);
  34. procedure setfillpatt(pat: word);
  35. procedure settextfont(font:word);
  36. procedure settextsize(size:word);
  37. procedure settextdir(dir:word);
  38. procedure settextall(font,dir,size,hor,ver:word);
  39. procedure xouttextxy(x1,y1:word; spacing:byte; s:string);
  40. procedure ngon(cx,cy,sides: word; r,ang: real);
  41. procedure fline(x1,y1,x2,y2:word; warp,pixres:real);
  42. procedure fbranch(fn:string ; warp,pixres:real);
  43. procedure frip(fn: string; warp,pixres: real);
  44. procedure writeimage(fn:string; var im:image);
  45. procedure readimage(fn:string; var im:image);
  46. procedure grabimage(x1,y1,x2,y2:word; var im:image);
  47. procedure showimage(x1,y1: word; var im:image; bitblt:word);
  48. procedure killimage(var im:image);
  49.  
  50. implementation
  51.  
  52. procedure setfillcolor(col:word);
  53. { Sets color in fillstyle }
  54. var
  55.   s: fillsettingstype;
  56. begin
  57.   getfillsettings(s);
  58.   setfillstyle(s.pattern,col)
  59. end;
  60.  
  61. procedure setfillpatt(pat: word);
  62. { Sets pattern in fill style }
  63. var
  64.   s: fillsettingstype;
  65. begin
  66.   getfillsettings(s);
  67.   setfillstyle(pat,s.color)
  68. end;
  69.  
  70. procedure settextfont(font:word);
  71. { Sets font in textsetting }
  72. var
  73.   s: textsettingstype;
  74. begin
  75.   gettextsettings(s);
  76.   settextstyle(font, s.direction, s.charsize)
  77. end;
  78.  
  79. procedure settextsize(size:word);
  80. { Sets size in textsetting }
  81. var
  82.   s: textsettingstype;
  83. begin
  84.   gettextsettings(s);
  85.   settextstyle(s.font, s.direction, size)
  86. end;
  87.  
  88. procedure settextdir(dir:word);
  89. { Sets direction in textsetting }
  90. var
  91.   s: textsettingstype;
  92. begin
  93.   gettextsettings(s);
  94.   settextstyle(s.font, dir, s.charsize)
  95. end;
  96.  
  97. procedure settextall(font,dir,size,hor,ver:word);
  98. { This is an EXTREMELY useful procedure to set all attributes of
  99.   graphics text settings. }
  100. begin
  101.   settextstyle(font,dir,size);
  102.   settextjustify(hor,ver)
  103. end;
  104.  
  105. procedure xouttextxy(x1,y1:word; spacing:byte; s:string);
  106. { Writing text in graphics mode can be very tedious.  If you want
  107.   to write line after line after line, you have to type OutTextXY
  108.   about a million times and make quite a few mistakes doing it.
  109.   This is usually a big headache for me and makes me not want to
  110.   work on whatever I'm doing because it's so tedious.  And thus
  111.   a procedure was born.  What this procedure does is start writing
  112.   at (x1,y1) when it finds #13 in the string, it skips down Spacing
  113.   pixels and writes until the next #13, and so on.  This lets you
  114.   change the spacing and move the text around more easily.  You are
  115.   still limited to 255 characters, but it's still worth it.  For
  116.   example, if you want to write 'Press (I) for Instructions' and
  117.   'Or (S) to Start' 20 pixels apart, you would use
  118.   xouttextxy(x,y,20,'Press (I) for Instructions'+#13+'Or (S) to start').
  119.   See how easy? }
  120. var
  121.   j: word;
  122.   p: byte;
  123. begin
  124.   j:=y1;
  125.   while s<>'' do begin
  126.     { find #13 in string }
  127.     p:=pos(#13,s);
  128.     if p>0 then begin
  129.       outtextxy(x1,j,copy(s,1,p-1));
  130.       delete(s,1,p);
  131.       j:=j+spacing
  132.       end
  133.     else begin
  134.       outtextxy(x1,j,s);
  135.       s:=''
  136.       end
  137.     end
  138. end;
  139.  
  140. procedure ngon(cx,cy,sides: word; r,ang: real);
  141. { This procedure draws an n-sided polygon.  (Cx,Cy) is the center.
  142.   Sides is obviously the number of sides.  R is the distance from
  143.   the center to one of the elbows, and Ang is the angle of rotation.
  144.   Ang must be given in radians. }
  145. var
  146.   i: word;
  147. begin
  148.   for i:=0 to sides-1 do
  149.     line(round(cx+r*cos(i/sides*2*pi+ang-pi/2)),
  150.          round(cy+r*sin(i/sides*2*pi+ang-pi/2)),
  151.          round(cx+r*cos((i+1)/sides*2*pi+ang-pi/2)),
  152.          round(cy+r*sin((i+1)/sides*2*pi+ang-pi/2)));
  153. end;
  154.  
  155. procedure fline(x1,y1,x2,y2:word; warp,pixres:real);
  156. { Generates a fractal line from (x1,y1) bent by Warp % such that no
  157.   two points are more than PixRes pixels apart.  A higher Warp means
  158.   the line can deviate more.  Caution: a Warp above 1.0 is not good.
  159.   Play around with this.  It's pretty cool.  It looks sort of like
  160.   a river. }
  161. var
  162.   d,ang:real;
  163.   x3,y3:word;        { point of bend }
  164. begin
  165.   d:=distance(x1,y1,x2,y2);
  166.   if d<=pixres then line(x1,y1,x2,y2)
  167.   else begin
  168.     ang:=random(65535)*9.5875262E-5;       { generate [0,2 pi) }
  169.     x3:=round((x1+x2)/2+d/2*warp*sin(ang));
  170.     y3:=round((y1+y2)/2+d/2*warp*cos(ang));
  171.     fline(x1,y1,x3,y3,warp,pixres);
  172.     fline(x3,y3,x2,y2,warp,pixres)
  173.     end
  174. end;
  175.  
  176. procedure fbranch(fn:string; warp,pixres:real);
  177. { reads a fractal branch file from disk and draws it with
  178.   parameters warp and pixres, as described in fline.  There
  179.   is a maximum of MaxNodes nodes, but only as much space as
  180.   needed is allocated.  Define a branch as follows:
  181.  
  182.   number of nodes                         e.g.  5
  183.   list of each node's coordinates               100 100
  184.                                                 ...
  185.   list of connections from node to node         1 2
  186.                                                 ... }
  187. const
  188.   maxnodes=1000;
  189. type
  190.   nodelist=array[1..2*maxnodes] of word;
  191. var
  192.   f: text;
  193.   i: word;
  194.   a,b: word;             { node numbers }
  195.   pts: word;             { number of nodes }
  196.   nl: ^nodelist;         { pointer to list of nodes }
  197. begin
  198.   assign(f,fn);
  199.   reset(f);
  200.   { read in points }
  201.   readln(f,pts);
  202.   if pts<=maxnodes then getmem(nl,pts*4) else getmem(nl,maxnodes*4);
  203.   for i:=1 to pts do
  204.     if i<=maxnodes then readln(f,nl^[i*2-1],nl^[i*2]) else readln(f);
  205.   while not eof(f) do begin
  206.     readln(f,a,b);
  207.     if [a,b]*[1..pts]=[a,b] then
  208.       fline(nl^[a*2-1],nl^[a*2],nl^[b*2-1],nl^[b*2],warp,pixres)
  209.     end;
  210.   close(f);
  211. end;
  212.  
  213. procedure frip(fn:string; warp,pixres:real);
  214. { Reads and draws a fractal rip (looks like a river)
  215.   A rip file is defined as follows:
  216.  
  217.   List of coordinates to connect    e.g.    100 100
  218.                                             150 120
  219.                                             160 180
  220.                                             ...
  221.  
  222.   This can be used to draw lakes, borders, etc.
  223.   There is no limit on the number of nodes. }
  224. var
  225.   x1,y1,x2,y2: word;
  226.   f: text;
  227. begin
  228.   assign(f,fn);
  229.   reset(f);
  230.   { read first point }
  231.   readln(f,x1,y1);
  232.   while not eof(f) do begin
  233.     readln(f,x2,y2);
  234.     fline(x1,y1,x2,y2,warp,pixres);
  235.     x1:=x2;
  236.     y1:=y2
  237.     end;
  238.   close(f)
  239. end;
  240.  
  241. procedure writeimage(fn:string; var im:image);
  242. { This procedure writes an image to the specified file. }
  243. var
  244.   f: file;
  245.   p: pointer;
  246.   n: word;
  247. begin
  248.   assign(f,fn);
  249.   rewrite(f,1);                    { objects are 1 byte large }
  250.   blockwrite(f,im.p^,im.size,n);   { write image to disk }
  251.   close(f);
  252. end;
  253.  
  254. procedure readimage(fn:string; var im:image);
  255. { There is no error checking as to how much memory is available.  The
  256.   size of an image is approximately the number of pixels divided by
  257.   two (VGA mode).  A good use of this procedure is to write a program that
  258.   draws a fairly complex image to be used in another program.  Then, use
  259.   GrabImage to capture the smallest area containing the image you want
  260.   and WriteImage to save it to disk.  Then use ReadImage and ShowImage to
  261.   draw the image in another program.  That way the image doesn't have to be
  262.   drawn at run-time. }
  263. var
  264.   f: file;
  265.   n: word;
  266. begin
  267.   assign(f,fn);
  268.   reset(f,1);
  269.   im.size:=filesize(f);           { assumes entire file is image }
  270.   getmem(im.p,im.size);           { allocate space }
  271.   blockread(f,im.p^,im.size,n);   { read in image }
  272.   close(f);
  273. end;
  274.  
  275. procedure grabimage(x1,y1,x2,y2:word; var im:image);
  276. { This procedure captures the specified image into a buffer.  It also
  277.   allocates enough memory, which can be released with KillImage.  This
  278.   is very similar to GetImage, but I have hidden away the details and
  279.   memory (de)allocation to make the procedures more complementary. }
  280. begin
  281.   im.size:=imagesize(x1,y1,x2,y2);
  282.   getmem(im.p,im.size);
  283.   getimage(x1,y1,x2,y2,im.p^)
  284. end;
  285.  
  286. procedure showimage(x1,y1:word; var im:image; bitblt:word);
  287. { The only difference between this and PutImage is the programmer
  288.   specifies an image instead of a buffer.  This helps to preserve
  289.   consistency. }
  290. begin
  291.   putimage(x1,y1,im.p^,bitblt)
  292. end;
  293.  
  294. procedure killimage(var im:image);
  295. { This procedure deallocates any memory used to store an image. }
  296. begin
  297.   freemem(im.p,im.size);
  298.   im.size:=0;
  299. end;
  300.  
  301. begin
  302.   europeanfont:=installuserfont('euro');
  303.   complexfont:=installuserfont('lcom');
  304.   triplexscriptfont:=installuserfont('tscr');
  305.   scriptfont:=installuserfont('scri');
  306.   simplefont:=installuserfont('simp');
  307. end.
  308.