arc.ppi 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. procedure GetArcCoords(var ArcCoords:ArcCoordsType);
  12. begin
  13. ArcCoords:=ActArcCoords;
  14. end;
  15. procedure Arc(x,y,alpha,beta:Integer;Radius:word);
  16. const i:Array[0..20]of Byte=
  17. (0,3,0, 2,3,1, 2,1,0, 0,1,1, 0,3,0, 2,3,1, 2,1,0);
  18. var counter,index : integer;
  19. endofs,ofs : integer;
  20. xa,ya,xe,ye : Array[0..2]of Integer;
  21. xp,yp : integer;
  22. xradius,yradius : word;
  23. first,ready : Boolean;
  24. ofscount : byte;
  25. procedure DrawArc(index1,index2,index3:byte);
  26. var ende,incr:integer;
  27. begin
  28. if index3=0 then begin
  29. counter:=index;
  30. ende:=0;
  31. incr:=-4;
  32. end else begin
  33. counter:=-4;
  34. ende:=index-4;
  35. incr:=4;
  36. end;
  37. if first then begin
  38. repeat
  39. first:=false;
  40. counter:=counter+incr;
  41. xp:=PInteger(BufferMem)[counter+index1];
  42. yp:=PInteger(BufferMem)[counter+index2];
  43. until (counter=ende) or
  44. (((xp=xa[0]) or (xp=xa[1]) or (xp=xa[2])) and
  45. ((yp=ya[0]) or (yp=ya[1]) or (yp=ya[2])));
  46. if Counter=Ende then exit else putpixeli(xp,yp,aktcolor);
  47. end;
  48. repeat
  49. if (((xp=xe[0]) or (xp=xe[1]) or (xp=xe[2])) and
  50. ((yp=ye[0]) or (yp=ye[1]) or (yp=ye[2]))) and
  51. ((ofs mod 4)=endofs) then
  52. begin
  53. putpixeli(xp,yp,aktcolor);
  54. ready:=true;
  55. exit;
  56. end;
  57. counter:=counter+incr;
  58. xp:=PInteger(BufferMem)[counter+index1];
  59. yp:=PInteger(BufferMem)[counter+index2];
  60. putpixeli(xp,yp,aktcolor);
  61. until counter=Ende;
  62. end;
  63. begin
  64. first:=true; ready:=false;
  65. XRadius:=(Radius*10000) div XAsp;
  66. YRadius:=(Radius*10000) div YAsp;
  67. alpha:=alpha mod 360; beta:=beta mod 360;
  68. case alpha of
  69. 0.. 89 : ofs:=0;
  70. 90..179 : ofs:=1;
  71. 180..269 : ofs:=2;
  72. 270..359 : ofs:=3;
  73. end;
  74. case beta of
  75. 0.. 89 : endofs:=0;
  76. 90..179 : endofs:=1;
  77. 180..269 : endofs:=2;
  78. 270..359 : endofs:=3;
  79. end;
  80. xa[1]:=x+round(sin((alpha+90)*Pi/180) * XRadius);
  81. ya[1]:=y+round(cos((alpha+90)*Pi/180) * YRadius);
  82. xe[1]:=x+round(sin((beta+90)*Pi/180) * XRadius);
  83. ye[1]:=y+round(cos((beta+90)*Pi/180) * YRadius);
  84. ActArcCoords.x:=x;
  85. ActArcCoords.y:=y;
  86. ActArcCoords.xstart:=xa[1];
  87. ActArcCoords.ystart:=ya[1];
  88. ActArcCoords.xend:=xe[1];
  89. ActArcCoords.yend:=ye[1];
  90. xa[0]:=xa[1]-1; xa[2]:=xa[1]+1; ya[0]:=ya[1]-1; ya[2]:=ya[1]+1;
  91. xe[0]:=xe[1]-1; xe[2]:=xe[1]+1; ye[0]:=ye[1]-1; ye[2]:=ye[1]+1;
  92. index:=Calcellipse(x,y,Radius,Radius);
  93. ofscount:=0;
  94. repeat
  95. DrawArc(i[ofs*3],i[ofs*3+1],i[ofs*3+2]);
  96. ofs:=(ofs+1) mod 7;
  97. inc(ofscount);
  98. until ready or (ofscount>16);
  99. end;
  100. procedure PieSlice(X,Y,alpha,beta:integer;Radius: Word);
  101. var angle : real;
  102. XRadius, YRadius : word;
  103. stline : LineSettingsType;
  104. writemode : word;
  105. begin
  106. Arc(x,y,alpha,beta,Radius);
  107. GetLineSettings(stline);
  108. writemode:=aktwritemode;
  109. aktwritemode:=normalput;
  110. SetLineStyle(SolidLn,0,NormWidth);
  111. MoveTo(ActArcCoords.xstart,ActArcCoords.ystart);
  112. LineTo(x,y);
  113. LineTo(ActArcCoords.xend,ActArcCoords.yend);
  114. PutPixeli(ActArcCoords.xstart,ActArcCoords.ystart,aktcolor);
  115. PutPixeli(x,y,aktcolor);
  116. PutPixeli(ActArcCoords.xend,ActArcCoords.yend,aktcolor);
  117. alpha:=alpha mod 360; beta:=beta mod 360;
  118. if alpha<=beta then
  119. angle:=(alpha+beta)/2
  120. else
  121. angle:=(alpha-360+beta)/2;
  122. { fill from the point in the middle of the slice }
  123. XRadius:=(Radius*10000) div XAsp;
  124. YRadius:=(Radius*10000) div YAsp;
  125. {$ifdef GraphDebug}
  126. Writeln(stderr,'Arc Center ',x,' ',y);
  127. Writeln(stderr,'Radii ',xradius,' ',yradius);
  128. Writeln(stderr,'Start ',ActArcCoords.xstart,' ',ActArcCoords.ystart);
  129. if not ColorsEqual(truecolor,getpixel(ActArcCoords.xstart,ActArcCoords.ystart)) then
  130. Writeln('Start error not set');
  131. Writeln(stderr,'End ',ActArcCoords.xend,' ',ActArcCoords.yend);
  132. if not ColorsEqual(truecolor,getpixel(ActArcCoords.xend,ActArcCoords.yend)) then
  133. Writeln('End error not set');
  134. Writeln(stderr,'Fill start ',x+round(sin((angle+90)*Pi/180)*XRadius/2),' ',
  135. y+round(cos((angle+90)*Pi/180)*YRadius/2));
  136. {$endif GraphDebug}
  137. { avoid rounding errors }
  138. if abs(ActArcCoords.xstart-ActArcCoords.xend)
  139. +abs(ActArcCoords.ystart-ActArcCoords.yend)>2 then
  140. FloodFill(x+round(sin((angle+90)*Pi/180)*XRadius/2),
  141. y+round(cos((angle+90)*Pi/180)*YRadius/2),truecolor);
  142. aktwritemode:=writemode;
  143. aktlineinfo:=stline;
  144. end;
  145. {
  146. $Log$
  147. Revision 1.6 1998-11-23 10:04:17 pierre
  148. * pieslice and sector work now !!
  149. * bugs in text writing removed
  150. + scaling for defaultfont added
  151. + VertDir for default font added
  152. * RestoreCRTMode corrected
  153. Revision 1.5 1998/11/20 18:42:05 pierre
  154. * many bugs related to floodfill and ellipse fixed
  155. Revision 1.4 1998/11/19 15:09:35 pierre
  156. * several bugfixes for sector/ellipse/floodfill
  157. + graphic driver mode const in interface G800x600x256...
  158. + added backput mode as in linux graph.pp
  159. (clears the background of textoutput)
  160. Revision 1.3 1998/11/19 09:48:46 pierre
  161. + added some functions missing like sector ellipse getarccoords
  162. (the filling of sector and ellipse is still buggy
  163. I use floodfill but sometimes the starting point
  164. is outside !!)
  165. * fixed a bug in floodfill for patterns
  166. (still has problems !!)
  167. Revision 1.2 1998/11/18 09:31:30 pierre
  168. * changed color scheme
  169. all colors are in RGB format if more than 256 colors
  170. + added 24 and 32 bits per pixel mode
  171. (compile with -dDEBUG)
  172. 24 bit mode with banked still as problems on pixels across
  173. the bank boundary, but works in LinearFrameBufferMode
  174. Look at install/demo/nmandel.pp
  175. Revision 1.1.1.1 1998/03/25 11:18:42 root
  176. * Restored version
  177. Revision 1.3 1998/01/26 11:58:53 michael
  178. + Added log at the end
  179. Working file: rtl/dos/ppi/arc.ppi
  180. description:
  181. ----------------------------
  182. revision 1.2
  183. date: 1997/12/01 12:21:27; author: michael; state: Exp; lines: +13 -0
  184. + added copyright reference in header.
  185. ----------------------------
  186. revision 1.1
  187. date: 1997/11/27 08:33:51; author: michael; state: Exp;
  188. Initial revision
  189. ----------------------------
  190. revision 1.1.1.1
  191. date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
  192. FPC RTL CVS start
  193. =============================================================================
  194. }