PageRenderTime 159ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/Utilities/FLTK/src/fl_rect.cxx

https://github.com/paniwani/OTB
C++ | 688 lines | 596 code | 32 blank | 60 comment | 86 complexity | 6a68d03d3c42bfe0a8b5a122990928ee MD5 | raw file
  1. //
  2. // "$Id$"
  3. //
  4. // Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-2005 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems on the following page:
  24. //
  25. // http://www.fltk.org/str.php
  26. //
  27. // These routines from fl_draw.H are used by the standard boxtypes
  28. // and thus are always linked into an fltk program.
  29. // Also all fl_clip routines, since they are always linked in so
  30. // that minimal update works.
  31. // OTB Modifications
  32. //#include <config.h>
  33. #include "fltk-config.h"
  34. #include <FL/Fl.H>
  35. #include <FL/Fl_Widget.H>
  36. #include <FL/fl_draw.H>
  37. #include <FL/x.H>
  38. #ifdef __APPLE_QUARTZ__
  39. extern float fl_quartz_line_width_;
  40. #endif
  41. void fl_rect(int x, int y, int w, int h) {
  42. if (w<=0 || h<=0) return;
  43. #ifdef WIN32
  44. MoveToEx(fl_gc, x, y, 0L);
  45. LineTo(fl_gc, x+w-1, y);
  46. LineTo(fl_gc, x+w-1, y+h-1);
  47. LineTo(fl_gc, x, y+h-1);
  48. LineTo(fl_gc, x, y);
  49. #elif defined(__APPLE_QD__)
  50. Rect rect;
  51. SetRect(&rect, x, y, x+w, y+h);
  52. FrameRect(&rect);
  53. #elif defined(__APPLE_QUARTZ__)
  54. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  55. CGRect rect = CGRectMake(x, y, w-1, h-1);
  56. CGContextStrokeRect(fl_gc, rect);
  57. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  58. #else
  59. XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
  60. #endif
  61. }
  62. void fl_rectf(int x, int y, int w, int h) {
  63. if (w<=0 || h<=0) return;
  64. #ifdef WIN32
  65. RECT rect;
  66. rect.left = x; rect.top = y;
  67. rect.right = x + w; rect.bottom = y + h;
  68. FillRect(fl_gc, &rect, fl_brush());
  69. #elif defined(__APPLE_QD__)
  70. Rect rect;
  71. SetRect(&rect, x, y, x+w, y+h);
  72. PaintRect(&rect);
  73. #elif defined(__APPLE_QUARTZ__)
  74. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  75. CGRect rect = CGRectMake(x, y, w-1, h-1);
  76. CGContextFillRect(fl_gc, rect);
  77. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  78. #else
  79. if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
  80. #endif
  81. }
  82. void fl_xyline(int x, int y, int x1) {
  83. #ifdef WIN32
  84. MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
  85. #elif defined(__APPLE_QD__)
  86. MoveTo(x, y); LineTo(x1, y);
  87. #elif defined(__APPLE_QUARTZ__)
  88. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  89. CGContextMoveToPoint(fl_gc, x, y);
  90. CGContextAddLineToPoint(fl_gc, x1, y);
  91. CGContextStrokePath(fl_gc);
  92. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  93. #else
  94. XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
  95. #endif
  96. }
  97. void fl_xyline(int x, int y, int x1, int y2) {
  98. #ifdef WIN32
  99. if (y2 < y) y2--;
  100. else y2++;
  101. MoveToEx(fl_gc, x, y, 0L);
  102. LineTo(fl_gc, x1, y);
  103. LineTo(fl_gc, x1, y2);
  104. #elif defined(__APPLE_QD__)
  105. MoveTo(x, y);
  106. LineTo(x1, y);
  107. LineTo(x1, y2);
  108. #elif defined(__APPLE_QUARTZ__)
  109. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  110. CGContextMoveToPoint(fl_gc, x, y);
  111. CGContextAddLineToPoint(fl_gc, x1, y);
  112. CGContextAddLineToPoint(fl_gc, x1, y2);
  113. CGContextStrokePath(fl_gc);
  114. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  115. #else
  116. XPoint p[3];
  117. p[0].x = x; p[0].y = p[1].y = y;
  118. p[1].x = p[2].x = x1; p[2].y = y2;
  119. XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
  120. #endif
  121. }
  122. void fl_xyline(int x, int y, int x1, int y2, int x3) {
  123. #ifdef WIN32
  124. if(x3 < x1) x3--;
  125. else x3++;
  126. MoveToEx(fl_gc, x, y, 0L);
  127. LineTo(fl_gc, x1, y);
  128. LineTo(fl_gc, x1, y2);
  129. LineTo(fl_gc, x3, y2);
  130. #elif defined(__APPLE_QD__)
  131. MoveTo(x, y);
  132. LineTo(x1, y);
  133. LineTo(x1, y2);
  134. LineTo(x3, y2);
  135. #elif defined(__APPLE_QUARTZ__)
  136. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  137. CGContextMoveToPoint(fl_gc, x, y);
  138. CGContextAddLineToPoint(fl_gc, x1, y);
  139. CGContextAddLineToPoint(fl_gc, x1, y2);
  140. CGContextAddLineToPoint(fl_gc, x3, y2);
  141. CGContextStrokePath(fl_gc);
  142. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  143. #else
  144. XPoint p[4];
  145. p[0].x = x; p[0].y = p[1].y = y;
  146. p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
  147. p[3].x = x3;
  148. XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  149. #endif
  150. }
  151. void fl_yxline(int x, int y, int y1) {
  152. #ifdef WIN32
  153. if (y1 < y) y1--;
  154. else y1++;
  155. MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1);
  156. #elif defined(__APPLE_QD__)
  157. MoveTo(x, y); LineTo(x, y1);
  158. #elif defined(__APPLE_QUARTZ__)
  159. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  160. CGContextMoveToPoint(fl_gc, x, y);
  161. CGContextAddLineToPoint(fl_gc, x, y1);
  162. CGContextStrokePath(fl_gc);
  163. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  164. #else
  165. XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
  166. #endif
  167. }
  168. void fl_yxline(int x, int y, int y1, int x2) {
  169. #ifdef WIN32
  170. if (x2 > x) x2++;
  171. else x2--;
  172. MoveToEx(fl_gc, x, y, 0L);
  173. LineTo(fl_gc, x, y1);
  174. LineTo(fl_gc, x2, y1);
  175. #elif defined(__APPLE_QD__)
  176. MoveTo(x, y);
  177. LineTo(x, y1);
  178. LineTo(x2, y1);
  179. #elif defined(__APPLE_QUARTZ__)
  180. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  181. CGContextMoveToPoint(fl_gc, x, y);
  182. CGContextAddLineToPoint(fl_gc, x, y1);
  183. CGContextAddLineToPoint(fl_gc, x2, y1);
  184. CGContextStrokePath(fl_gc);
  185. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  186. #else
  187. XPoint p[3];
  188. p[0].x = p[1].x = x; p[0].y = y;
  189. p[1].y = p[2].y = y1; p[2].x = x2;
  190. XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
  191. #endif
  192. }
  193. void fl_yxline(int x, int y, int y1, int x2, int y3) {
  194. #ifdef WIN32
  195. if(y3<y1) y3--;
  196. else y3++;
  197. MoveToEx(fl_gc, x, y, 0L);
  198. LineTo(fl_gc, x, y1);
  199. LineTo(fl_gc, x2, y1);
  200. LineTo(fl_gc, x2, y3);
  201. #elif defined(__APPLE_QD__)
  202. MoveTo(x, y);
  203. LineTo(x, y1);
  204. LineTo(x2, y1);
  205. LineTo(x2, y3);
  206. #elif defined(__APPLE_QUARTZ__)
  207. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  208. CGContextMoveToPoint(fl_gc, x, y);
  209. CGContextAddLineToPoint(fl_gc, x, y1);
  210. CGContextAddLineToPoint(fl_gc, x2, y1);
  211. CGContextAddLineToPoint(fl_gc, x2, y3);
  212. CGContextStrokePath(fl_gc);
  213. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  214. #else
  215. XPoint p[4];
  216. p[0].x = p[1].x = x; p[0].y = y;
  217. p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
  218. p[3].y = y3;
  219. XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  220. #endif
  221. }
  222. void fl_line(int x, int y, int x1, int y1) {
  223. #ifdef WIN32
  224. MoveToEx(fl_gc, x, y, 0L);
  225. LineTo(fl_gc, x1, y1);
  226. // Draw the last point *again* because the GDI line drawing
  227. // functions will not draw the last point ("it's a feature!"...)
  228. SetPixel(fl_gc, x1, y1, fl_RGB());
  229. #elif defined(__APPLE_QD__)
  230. MoveTo(x, y);
  231. LineTo(x1, y1);
  232. #elif defined(__APPLE_QUARTZ__)
  233. if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false);
  234. CGContextMoveToPoint(fl_gc, x, y);
  235. CGContextAddLineToPoint(fl_gc, x1, y1);
  236. CGContextStrokePath(fl_gc);
  237. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  238. #else
  239. XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1);
  240. #endif
  241. }
  242. void fl_line(int x, int y, int x1, int y1, int x2, int y2) {
  243. #ifdef WIN32
  244. MoveToEx(fl_gc, x, y, 0L);
  245. LineTo(fl_gc, x1, y1);
  246. LineTo(fl_gc, x2, y2);
  247. // Draw the last point *again* because the GDI line drawing
  248. // functions will not draw the last point ("it's a feature!"...)
  249. SetPixel(fl_gc, x2, y2, fl_RGB());
  250. #elif defined(__APPLE_QD__)
  251. MoveTo(x, y);
  252. LineTo(x1, y1);
  253. LineTo(x2, y2);
  254. #elif defined(__APPLE_QUARTZ__)
  255. if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, false);
  256. CGContextMoveToPoint(fl_gc, x, y);
  257. CGContextAddLineToPoint(fl_gc, x1, y1);
  258. CGContextAddLineToPoint(fl_gc, x2, y2);
  259. CGContextStrokePath(fl_gc);
  260. if (fl_quartz_line_width_==1.0f ) CGContextSetShouldAntialias(fl_gc, true);
  261. #else
  262. XPoint p[3];
  263. p[0].x = x; p[0].y = y;
  264. p[1].x = x1; p[1].y = y1;
  265. p[2].x = x2; p[2].y = y2;
  266. XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
  267. #endif
  268. }
  269. void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {
  270. #ifdef WIN32
  271. MoveToEx(fl_gc, x, y, 0L);
  272. LineTo(fl_gc, x1, y1);
  273. LineTo(fl_gc, x2, y2);
  274. LineTo(fl_gc, x, y);
  275. #elif defined(__APPLE_QD__)
  276. MoveTo(x, y);
  277. LineTo(x1, y1);
  278. LineTo(x2, y2);
  279. LineTo(x, y);
  280. #elif defined(__APPLE_QUARTZ__)
  281. CGContextMoveToPoint(fl_gc, x, y);
  282. CGContextAddLineToPoint(fl_gc, x1, y1);
  283. CGContextAddLineToPoint(fl_gc, x2, y2);
  284. CGContextClosePath(fl_gc);
  285. CGContextStrokePath(fl_gc);
  286. #else
  287. XPoint p[4];
  288. p[0].x = x; p[0].y = y;
  289. p[1].x = x1; p[1].y = y1;
  290. p[2].x = x2; p[2].y = y2;
  291. p[3].x = x; p[3].y = y;
  292. XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  293. #endif
  294. }
  295. void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
  296. #ifdef WIN32
  297. MoveToEx(fl_gc, x, y, 0L);
  298. LineTo(fl_gc, x1, y1);
  299. LineTo(fl_gc, x2, y2);
  300. LineTo(fl_gc, x3, y3);
  301. LineTo(fl_gc, x, y);
  302. #elif defined(__APPLE_QD__)
  303. MoveTo(x, y);
  304. LineTo(x1, y1);
  305. LineTo(x2, y2);
  306. LineTo(x3, y3);
  307. LineTo(x, y);
  308. #elif defined(__APPLE_QUARTZ__)
  309. CGContextMoveToPoint(fl_gc, x, y);
  310. CGContextAddLineToPoint(fl_gc, x1, y1);
  311. CGContextAddLineToPoint(fl_gc, x2, y2);
  312. CGContextAddLineToPoint(fl_gc, x3, y3);
  313. CGContextClosePath(fl_gc);
  314. CGContextStrokePath(fl_gc);
  315. #else
  316. XPoint p[5];
  317. p[0].x = x; p[0].y = y;
  318. p[1].x = x1; p[1].y = y1;
  319. p[2].x = x2; p[2].y = y2;
  320. p[3].x = x3; p[3].y = y3;
  321. p[4].x = x; p[4].y = y;
  322. XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
  323. #endif
  324. }
  325. void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {
  326. XPoint p[4];
  327. p[0].x = x; p[0].y = y;
  328. p[1].x = x1; p[1].y = y1;
  329. p[2].x = x2; p[2].y = y2;
  330. #ifdef WIN32
  331. SelectObject(fl_gc, fl_brush());
  332. Polygon(fl_gc, p, 3);
  333. #elif defined(__APPLE_QD__)
  334. PolyHandle poly = OpenPoly();
  335. MoveTo(x, y);
  336. LineTo(x1, y1);
  337. LineTo(x2, y2);
  338. LineTo(x, y);
  339. ClosePoly();
  340. PaintPoly(poly);
  341. FramePoly(poly);
  342. KillPoly(poly);
  343. #elif defined(__APPLE_QUARTZ__)
  344. CGContextMoveToPoint(fl_gc, x, y);
  345. CGContextAddLineToPoint(fl_gc, x1, y1);
  346. CGContextAddLineToPoint(fl_gc, x2, y2);
  347. CGContextClosePath(fl_gc);
  348. CGContextFillPath(fl_gc);
  349. #else
  350. p[3].x = x; p[3].y = y;
  351. XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0);
  352. XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  353. #endif
  354. }
  355. void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
  356. XPoint p[5];
  357. p[0].x = x; p[0].y = y;
  358. p[1].x = x1; p[1].y = y1;
  359. p[2].x = x2; p[2].y = y2;
  360. p[3].x = x3; p[3].y = y3;
  361. #ifdef WIN32
  362. SelectObject(fl_gc, fl_brush());
  363. Polygon(fl_gc, p, 4);
  364. #elif defined(__APPLE_QD__)
  365. PolyHandle poly = OpenPoly();
  366. MoveTo(x, y);
  367. LineTo(x1, y1);
  368. LineTo(x2, y2);
  369. LineTo(x3, y3);
  370. LineTo(x, y);
  371. ClosePoly();
  372. PaintPoly(poly);
  373. FramePoly(poly);
  374. KillPoly(poly);
  375. #elif defined(__APPLE_QUARTZ__)
  376. CGContextMoveToPoint(fl_gc, x, y);
  377. CGContextAddLineToPoint(fl_gc, x1, y1);
  378. CGContextAddLineToPoint(fl_gc, x2, y2);
  379. CGContextAddLineToPoint(fl_gc, x3, y3);
  380. CGContextClosePath(fl_gc);
  381. CGContextFillPath(fl_gc);
  382. #else
  383. p[4].x = x; p[4].y = y;
  384. XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0);
  385. XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
  386. #endif
  387. }
  388. void fl_point(int x, int y) {
  389. #ifdef WIN32
  390. SetPixel(fl_gc, x, y, fl_RGB());
  391. #elif defined(__APPLE_QD__)
  392. MoveTo(x, y); Line(0, 0);
  393. #elif defined(__APPLE_QUARTZ__)
  394. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false);
  395. CGContextMoveToPoint(fl_gc, x, y);
  396. CGContextAddLineToPoint(fl_gc, x, y);
  397. CGContextStrokePath(fl_gc);
  398. if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true);
  399. #else
  400. XDrawPoint(fl_display, fl_window, fl_gc, x, y);
  401. #endif
  402. }
  403. ////////////////////////////////////////////////////////////////
  404. #define STACK_SIZE 10
  405. #define STACK_MAX (STACK_SIZE - 1)
  406. static Fl_Region rstack[STACK_SIZE];
  407. static int rstackptr=0;
  408. int fl_clip_state_number=0; // used by gl_begin.cxx to update GL clip
  409. #if !defined(WIN32) && !defined(__APPLE__)
  410. // Missing X call: (is this the fastest way to init a 1-rectangle region?)
  411. // MSWindows equivalent exists, implemented inline in win32.H
  412. Fl_Region XRectangleRegion(int x, int y, int w, int h) {
  413. XRectangle R;
  414. R.x = x; R.y = y; R.width = w; R.height = h;
  415. Fl_Region r = XCreateRegion();
  416. XUnionRectWithRegion(&R, r, r);
  417. return r;
  418. }
  419. #endif
  420. #ifdef __APPLE_QD__
  421. extern Fl_Region fl_window_region;
  422. #elif defined(__APPLE_QUARTZ__)
  423. // warning: the Quartz implementation currently uses Quickdraw calls to achieve
  424. // clipping. A future version should instead use 'CGContectClipToRect'
  425. // and friends.
  426. extern Fl_Region fl_window_region;
  427. #endif
  428. // undo any clobbering of clip done by your program:
  429. void fl_restore_clip() {
  430. fl_clip_state_number++;
  431. Fl_Region r = rstack[rstackptr];
  432. #ifdef WIN32
  433. SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared
  434. #elif defined(__APPLE_QD__)
  435. # if 1
  436. // This code is required to allow true subwindows to work on Mac.
  437. // During regular operation however, this seems overkill.
  438. // See also: Fl_Window::make_current()
  439. if ( fl_window ) {
  440. GrafPtr port = GetWindowPort( fl_window );
  441. if ( port ) { // port will be NULL if we are using a GWorld (and fl_window_region is invalid)
  442. RgnHandle portClip = NewRgn();
  443. CopyRgn( fl_window_region, portClip ); // changed
  444. if ( r )
  445. SectRgn( portClip, r, portClip );
  446. SetPortClipRegion( port, portClip );
  447. DisposeRgn( portClip );
  448. }
  449. } else {
  450. if (r)
  451. SetClip(r);
  452. else {
  453. Rect rect; rect.left=0; rect.top=0; rect.right=0x7fff; rect.bottom=0x7fff;
  454. ClipRect(&rect);
  455. }
  456. }
  457. # else
  458. if (r) SetClip(r);
  459. else {
  460. Rect rect; rect.left=0; rect.top=0; rect.right=0x7fff; rect.bottom=0x7fff;
  461. ClipRect(&rect);
  462. }
  463. # endif
  464. #elif defined(__APPLE_QUARTZ__)
  465. if ( fl_window ) // clipping for a true window
  466. {
  467. GrafPtr port = GetWindowPort( fl_window );
  468. if ( port ) {
  469. RgnHandle portClip = NewRgn();
  470. CopyRgn( fl_window_region, portClip ); // changed
  471. if ( r )
  472. SectRgn( portClip, r, portClip );
  473. Rect portRect; GetPortBounds(port, &portRect);
  474. Fl_X::q_clear_clipping();
  475. ClipCGContextToRegion(fl_gc, &portRect, portClip );
  476. Fl_X::q_fill_context();
  477. DisposeRgn( portClip );
  478. }
  479. } else if (fl_gc) { // clipping for an offscreen drawing world (CGBitmap)
  480. Rect portRect;
  481. portRect.top = 0;
  482. portRect.left = 0;
  483. portRect.bottom = CGBitmapContextGetHeight(fl_gc);
  484. portRect.right = CGBitmapContextGetWidth(fl_gc);
  485. Fl_X::q_clear_clipping();
  486. if (r)
  487. ClipCGContextToRegion(fl_gc, &portRect, r);
  488. Fl_X::q_fill_context();
  489. }
  490. #else
  491. if (r) XSetRegion(fl_display, fl_gc, r);
  492. else XSetClipMask(fl_display, fl_gc, 0);
  493. #endif
  494. }
  495. // Replace the top of the clip stack:
  496. void fl_clip_region(Fl_Region r) {
  497. Fl_Region oldr = rstack[rstackptr];
  498. if (oldr) XDestroyRegion(oldr);
  499. rstack[rstackptr] = r;
  500. fl_restore_clip();
  501. }
  502. // Return the current clip region...
  503. Fl_Region fl_clip_region() {
  504. return rstack[rstackptr];
  505. }
  506. // Intersect & push a new clip rectangle:
  507. void fl_push_clip(int x, int y, int w, int h) {
  508. Fl_Region r;
  509. if (w > 0 && h > 0) {
  510. r = XRectangleRegion(x,y,w,h);
  511. Fl_Region current = rstack[rstackptr];
  512. if (current) {
  513. #ifdef WIN32
  514. CombineRgn(r,r,current,RGN_AND);
  515. #elif defined(__APPLE_QD__)
  516. SectRgn(r, current, r);
  517. #elif defined(__APPLE_QUARTZ__)
  518. SectRgn(r, current, r);
  519. #else
  520. Fl_Region temp = XCreateRegion();
  521. XIntersectRegion(current, r, temp);
  522. XDestroyRegion(r);
  523. r = temp;
  524. #endif
  525. }
  526. } else { // make empty clip region:
  527. #ifdef WIN32
  528. r = CreateRectRgn(0,0,0,0);
  529. #elif defined(__APPLE_QD__)
  530. r = NewRgn();
  531. SetEmptyRgn(r);
  532. #elif defined(__APPLE_QUARTZ__)
  533. r = NewRgn();
  534. SetEmptyRgn(r);
  535. #else
  536. r = XCreateRegion();
  537. #endif
  538. }
  539. if (rstackptr < STACK_MAX) rstack[++rstackptr] = r;
  540. else Fl::warning("fl_push_clip: clip stack overflow!\n");
  541. fl_restore_clip();
  542. }
  543. // make there be no clip (used by fl_begin_offscreen() only!)
  544. void fl_push_no_clip() {
  545. if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0;
  546. else Fl::warning("fl_push_no_clip: clip stack overflow!\n");
  547. fl_restore_clip();
  548. }
  549. // pop back to previous clip:
  550. void fl_pop_clip() {
  551. if (rstackptr > 0) {
  552. Fl_Region oldr = rstack[rstackptr--];
  553. if (oldr) XDestroyRegion(oldr);
  554. } else Fl::warning("fl_pop_clip: clip stack underflow!\n");
  555. fl_restore_clip();
  556. }
  557. // does this rectangle intersect current clip?
  558. int fl_not_clipped(int x, int y, int w, int h) {
  559. if (x+w <= 0 || y+h <= 0) return 0;
  560. Fl_Region r = rstack[rstackptr];
  561. #ifdef WIN32
  562. if (!r) return 1;
  563. RECT rect;
  564. rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
  565. return RectInRegion(r,&rect);
  566. #elif defined(__APPLE_QD__)
  567. if (!r) return 1;
  568. Rect rect;
  569. rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
  570. return RectInRgn(&rect, r);
  571. #elif defined(__APPLE_QUARTZ__)
  572. if (!r) return 1;
  573. Rect rect;
  574. rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
  575. return RectInRgn(&rect, r);
  576. #else
  577. return r ? XRectInRegion(r, x, y, w, h) : 1;
  578. #endif
  579. }
  580. // return rectangle surrounding intersection of this rectangle and clip:
  581. int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
  582. X = x; Y = y; W = w; H = h;
  583. Fl_Region r = rstack[rstackptr];
  584. if (!r) return 0;
  585. #ifdef WIN32
  586. // The win32 API makes no distinction between partial and complete
  587. // intersection, so we have to check for partial intersection ourselves.
  588. // However, given that the regions may be composite, we have to do
  589. // some voodoo stuff...
  590. Fl_Region rr = XRectangleRegion(x,y,w,h);
  591. Fl_Region temp = CreateRectRgn(0,0,0,0);
  592. int ret;
  593. if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
  594. W = H = 0;
  595. ret = 2;
  596. } else if (EqualRgn(temp, rr)) { // complete
  597. ret = 0;
  598. } else { // parital intersection
  599. RECT rect;
  600. GetRgnBox(temp, &rect);
  601. X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
  602. ret = 1;
  603. }
  604. DeleteObject(temp);
  605. DeleteObject(rr);
  606. return ret;
  607. #elif defined(__APPLE_QD__)
  608. RgnHandle rr = NewRgn();
  609. SetRectRgn( rr, x, y, x+w, y+h );
  610. SectRgn( r, rr, rr );
  611. Rect rp; GetRegionBounds(rr, &rp);
  612. X = rp.left;
  613. Y = rp.top;
  614. W = rp.right - X;
  615. H = rp.bottom - Y;
  616. DisposeRgn( rr );
  617. if ( H==0 ) return 2;
  618. if ( h==H && w==W ) return 0;
  619. return 0;
  620. #elif defined(__APPLE_QUARTZ__)
  621. RgnHandle rr = NewRgn();
  622. SetRectRgn( rr, x, y, x+w, y+h );
  623. SectRgn( r, rr, rr );
  624. Rect rp; GetRegionBounds(rr, &rp);
  625. X = rp.left;
  626. Y = rp.top;
  627. W = rp.right - X;
  628. H = rp.bottom - Y;
  629. DisposeRgn( rr );
  630. if ( H==0 ) return 2;
  631. if ( h==H && w==W ) return 0;
  632. return 0;
  633. #else
  634. switch (XRectInRegion(r, x, y, w, h)) {
  635. case 0: // completely outside
  636. W = H = 0;
  637. return 2;
  638. case 1: // completely inside:
  639. return 0;
  640. default: // partial:
  641. break;
  642. }
  643. Fl_Region rr = XRectangleRegion(x,y,w,h);
  644. Fl_Region temp = XCreateRegion();
  645. XIntersectRegion(r, rr, temp);
  646. XRectangle rect;
  647. XClipBox(temp, &rect);
  648. X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
  649. XDestroyRegion(temp);
  650. XDestroyRegion(rr);
  651. return 1;
  652. #endif
  653. }
  654. //
  655. // End of "$Id$".
  656. //