clipping.pp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2003 by the Free Pascal development team
  4. Clipping support.
  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. {$mode objfpc}{$h+}
  12. unit Clipping;
  13. interface
  14. uses classes;
  15. procedure SortRect (var rect : TRect);
  16. procedure SortRect (var left,top, right,bottom : integer);
  17. function PointInside (const x,y:integer; bounds:TRect) : boolean;
  18. Function CheckRectClipping (ClipRect:TRect; var Rect:Trect) : Boolean;
  19. Function CheckRectClipping (ClipRect:TRect; var x1,y1, x2,y2 : integer) : Boolean;
  20. procedure CheckLineClipping (ClipRect:TRect; var x1,y1, x2,y2 : integer);
  21. implementation
  22. procedure SortRect (var rect : TRect);
  23. begin
  24. with rect do
  25. SortRect (left,top, right,bottom);
  26. end;
  27. procedure SortRect (var left,top, right,bottom : integer);
  28. var r : integer;
  29. begin
  30. if left > right then
  31. begin
  32. r := left;
  33. left := right;
  34. right := r;
  35. end;
  36. if top > bottom then
  37. begin
  38. r := top;
  39. top := bottom;
  40. bottom := r;
  41. end;
  42. end;
  43. function PointInside (const x,y:integer; bounds:TRect) : boolean;
  44. begin
  45. SortRect (bounds);
  46. with Bounds do
  47. result := (x >= left) and (x <= right) and
  48. (y >= top) and (y <= bottom);
  49. end;
  50. Function CheckRectClipping (ClipRect:TRect; var Rect:Trect) : Boolean;
  51. begin
  52. with ClipRect do
  53. Result:=CheckRectClipping (ClipRect, left,top,right,bottom);
  54. end;
  55. Function CheckRectClipping (ClipRect:TRect; var x1,y1, x2,y2 : integer) : boolean;
  56. procedure ClearRect;
  57. begin
  58. x1 := -1;
  59. x2 := -1;
  60. y1 := -1;
  61. y2 := -1;
  62. end;
  63. begin
  64. Result:=true;
  65. SortRect (ClipRect);
  66. SortRect (x1,y1, x2,y2);
  67. with ClipRect do
  68. begin
  69. if ( x1 < Left ) then // left side needs to be clipped
  70. x1 := left;
  71. if ( x2 > right ) then // right side needs to be clipped
  72. x2 := right;
  73. if ( y1 < top ) then // top side needs to be clipped
  74. y1 := top;
  75. if ( y2 > bottom ) then // bottom side needs to be clipped
  76. y2 := bottom;
  77. if (x1 > x2) or (y1 > y2) then
  78. begin
  79. ClearRect;
  80. Result:=False;
  81. end;
  82. end;
  83. end;
  84. procedure CheckLineClipping (ClipRect:TRect; var x1,y1, x2,y2 : integer);
  85. var a,b : single;
  86. Calculated : boolean;
  87. xdiff,n : integer;
  88. procedure CalcLine;
  89. begin
  90. if not Calculated then
  91. begin
  92. xdiff := (x1-x2);
  93. a := (y1-y2) / xdiff;
  94. b := (x1*y2 - x2*y1) / xdiff;
  95. Calculated := true;
  96. end;
  97. end;
  98. procedure ClearLine;
  99. begin
  100. x1 := -1;
  101. y1 := -1;
  102. x2 := -1;
  103. y2 := -1;
  104. end;
  105. begin
  106. Calculated := false;
  107. SortRect (ClipRect);
  108. xdiff := (x1-x2);
  109. with ClipRect do
  110. if xdiff = 0 then
  111. begin // vertical line
  112. if y1 > bottom then
  113. y1 := bottom
  114. else if y1 < top then
  115. y1 := top;
  116. if y2 > bottom then
  117. y2 := bottom
  118. else if y2 < top then
  119. y2 := top;
  120. end
  121. else if (y1-y2) = 0 then
  122. begin // horizontal line
  123. if x1 < left then
  124. x1 := left
  125. else if x1 > right then
  126. x1 := right;
  127. if x2 < left then
  128. x2 := left
  129. else if x2 > right then
  130. x2 := right;
  131. end
  132. else
  133. if ( (y1 < top) and (y2 < top) ) or
  134. ( (y1 > bottom) and (y2 > bottom) ) or
  135. ( (x1 > right) and (x2 > right) ) or
  136. ( (x1 < left) and (x2 < left) ) then
  137. ClearLine // completely outside ClipRect
  138. else
  139. begin
  140. if (y1 < top) or (y2 < top) then
  141. begin
  142. CalcLine;
  143. n := round ((top - b) / a);
  144. if (n >= left) and (n <= right) then
  145. if (y1 < top) then
  146. begin
  147. x1 := n;
  148. y1 := top;
  149. end
  150. else
  151. begin
  152. x2 := n;
  153. y2 := top;
  154. end;
  155. end;
  156. if (y1 > bottom) or (y2 > bottom) then
  157. begin
  158. CalcLine;
  159. n := round ((bottom - b) / a);
  160. if (n >= left) and (n <= right) then
  161. if (y1 > bottom) then
  162. begin
  163. x1 := n;
  164. y1 := bottom;
  165. end
  166. else
  167. begin
  168. x2 := n;
  169. y2 := bottom;
  170. end;
  171. end;
  172. if (x1 < left) or (x2 < left) then
  173. begin
  174. CalcLine;
  175. n := round ((left * a) + b);
  176. if (n <= bottom) and (n >= top) then
  177. if (x1 < left) then
  178. begin
  179. x1 := left;
  180. y1 := n;
  181. end
  182. else
  183. begin
  184. x2 := left;
  185. y2 := n;
  186. end;
  187. end;
  188. if (x1 > right) or (x2 > right) then
  189. begin
  190. CalcLine;
  191. n := round ((right * a) + b);
  192. if (n <= bottom) and (n >= top) then
  193. if (x1 > right) then
  194. begin
  195. x1 := right;
  196. y1 := n;
  197. end
  198. else
  199. begin
  200. x2 := right;
  201. y2 := n;
  202. end;
  203. end;
  204. end;
  205. end;
  206. end.