arc.ppi 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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.1 1998-12-21 13:07:03 peter
  148. * use -FE
  149. Revision 1.6 1998/11/23 10:04:17 pierre
  150. * pieslice and sector work now !!
  151. * bugs in text writing removed
  152. + scaling for defaultfont added
  153. + VertDir for default font added
  154. * RestoreCRTMode corrected
  155. Revision 1.5 1998/11/20 18:42:05 pierre
  156. * many bugs related to floodfill and ellipse fixed
  157. Revision 1.4 1998/11/19 15:09:35 pierre
  158. * several bugfixes for sector/ellipse/floodfill
  159. + graphic driver mode const in interface G800x600x256...
  160. + added backput mode as in linux graph.pp
  161. (clears the background of textoutput)
  162. Revision 1.3 1998/11/19 09:48:46 pierre
  163. + added some functions missing like sector ellipse getarccoords
  164. (the filling of sector and ellipse is still buggy
  165. I use floodfill but sometimes the starting point
  166. is outside !!)
  167. * fixed a bug in floodfill for patterns
  168. (still has problems !!)
  169. Revision 1.2 1998/11/18 09:31:30 pierre
  170. * changed color scheme
  171. all colors are in RGB format if more than 256 colors
  172. + added 24 and 32 bits per pixel mode
  173. (compile with -dDEBUG)
  174. 24 bit mode with banked still as problems on pixels across
  175. the bank boundary, but works in LinearFrameBufferMode
  176. Look at install/demo/nmandel.pp
  177. Revision 1.1.1.1 1998/03/25 11:18:42 root
  178. * Restored version
  179. Revision 1.3 1998/01/26 11:58:53 michael
  180. + Added log at the end
  181. Working file: rtl/dos/ppi/arc.ppi
  182. description:
  183. ----------------------------
  184. revision 1.2
  185. date: 1997/12/01 12:21:27; author: michael; state: Exp; lines: +13 -0
  186. + added copyright reference in header.
  187. ----------------------------
  188. revision 1.1
  189. date: 1997/11/27 08:33:51; author: michael; state: Exp;
  190. Initial revision
  191. ----------------------------
  192. revision 1.1.1.1
  193. date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
  194. FPC RTL CVS start
  195. =============================================================================
  196. }