// // "$Id$" // // Rectangle drawing routines for the Fast Light Tool Kit (FLTK). // // Copyright 1998-2005 by Bill Spitzak and others. // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 // USA. // // Please report all bugs and problems on the following page: // // http://www.fltk.org/str.php // // These routines from fl_draw.H are used by the standard boxtypes // and thus are always linked into an fltk program. // Also all fl_clip routines, since they are always linked in so // that minimal update works. #include #include #include #include #include #ifdef __APPLE_QUARTZ__ extern float fl_quartz_line_width_; #endif void fl_rect(int x, int y, int w, int h) { if (w<=0 || h<=0) return; #ifdef WIN32 MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x+w-1, y); LineTo(fl_gc, x+w-1, y+h-1); LineTo(fl_gc, x, y+h-1); LineTo(fl_gc, x, y); #elif defined(__APPLE_QD__) Rect rect; SetRect(&rect, x, y, x+w, y+h); FrameRect(&rect); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGRect rect = CGRectMake(x, y, w-1, h-1); CGContextStrokeRect(fl_gc, rect); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1); #endif } void fl_rectf(int x, int y, int w, int h) { if (w<=0 || h<=0) return; #ifdef WIN32 RECT rect; rect.left = x; rect.top = y; rect.right = x + w; rect.bottom = y + h; FillRect(fl_gc, &rect, fl_brush()); #elif defined(__APPLE_QD__) Rect rect; SetRect(&rect, x, y, x+w, y+h); PaintRect(&rect); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGRect rect = CGRectMake(x, y, w-1, h-1); CGContextFillRect(fl_gc, rect); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h); #endif } void fl_xyline(int x, int y, int x1) { #ifdef WIN32 MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y); #elif defined(__APPLE_QD__) MoveTo(x, y); LineTo(x1, y); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y); CGContextStrokePath(fl_gc); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y); #endif } void fl_xyline(int x, int y, int x1, int y2) { #ifdef WIN32 if (y2 < y) y2--; else y2++; MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1, y); LineTo(fl_gc, x1, y2); #elif defined(__APPLE_QD__) MoveTo(x, y); LineTo(x1, y); LineTo(x1, y2); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y); CGContextAddLineToPoint(fl_gc, x1, y2); CGContextStrokePath(fl_gc); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else XPoint p[3]; p[0].x = x; p[0].y = p[1].y = y; p[1].x = p[2].x = x1; p[2].y = y2; XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); #endif } void fl_xyline(int x, int y, int x1, int y2, int x3) { #ifdef WIN32 if(x3 < x1) x3--; else x3++; MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1, y); LineTo(fl_gc, x1, y2); LineTo(fl_gc, x3, y2); #elif defined(__APPLE_QD__) MoveTo(x, y); LineTo(x1, y); LineTo(x1, y2); LineTo(x3, y2); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x1, y); CGContextAddLineToPoint(fl_gc, x1, y2); CGContextAddLineToPoint(fl_gc, x3, y2); CGContextStrokePath(fl_gc); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else XPoint p[4]; p[0].x = x; p[0].y = p[1].y = y; p[1].x = p[2].x = x1; p[2].y = p[3].y = y2; p[3].x = x3; XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); #endif } void fl_yxline(int x, int y, int y1) { #ifdef WIN32 if (y1 < y) y1--; else y1++; MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); #elif defined(__APPLE_QD__) MoveTo(x, y); LineTo(x, y1); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x, y1); CGContextStrokePath(fl_gc); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1); #endif } void fl_yxline(int x, int y, int y1, int x2) { #ifdef WIN32 if (x2 > x) x2++; else x2--; MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); LineTo(fl_gc, x2, y1); #elif defined(__APPLE_QD__) MoveTo(x, y); LineTo(x, y1); LineTo(x2, y1); #elif defined(__APPLE_QUARTZ__) if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); CGContextMoveToPoint(fl_gc, x, y); CGContextAddLineToPoint(fl_gc, x, y1); CGContextAddLineToPoint(fl_gc, x2, y1); CGContextStrokePath(fl_gc); if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); #else XPoint p[3]; p[0].x = p[1].x = x; p[0].y = y; p[1].y = p[2].y = y1; p[2].x = x2; XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); #endif } void fl_yxline(int x, int y, int y1, int x2, int y3) { #ifdef WIN32 if(y3 0 && h > 0) { r = XRectangleRegion(x,y,w,h); Fl_Region current = rstack[rstackptr]; if (current) { #ifdef WIN32 CombineRgn(r,r,current,RGN_AND); #elif defined(__APPLE_QD__) SectRgn(r, current, r); #elif defined(__APPLE_QUARTZ__) SectRgn(r, current, r); #else Fl_Region temp = XCreateRegion(); XIntersectRegion(current, r, temp); XDestroyRegion(r); r = temp; #endif } } else { // make empty clip region: #ifdef WIN32 r = CreateRectRgn(0,0,0,0); #elif defined(__APPLE_QD__) r = NewRgn(); SetEmptyRgn(r); #elif defined(__APPLE_QUARTZ__) r = NewRgn(); SetEmptyRgn(r); #else r = XCreateRegion(); #endif } if (rstackptr < STACK_MAX) rstack[++rstackptr] = r; else Fl::warning("fl_push_clip: clip stack overflow!\n"); fl_restore_clip(); } // make there be no clip (used by fl_begin_offscreen() only!) void fl_push_no_clip() { if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0; else Fl::warning("fl_push_no_clip: clip stack overflow!\n"); fl_restore_clip(); } // pop back to previous clip: void fl_pop_clip() { if (rstackptr > 0) { Fl_Region oldr = rstack[rstackptr--]; if (oldr) XDestroyRegion(oldr); } else Fl::warning("fl_pop_clip: clip stack underflow!\n"); fl_restore_clip(); } // does this rectangle intersect current clip? int fl_not_clipped(int x, int y, int w, int h) { if (x+w <= 0 || y+h <= 0) return 0; Fl_Region r = rstack[rstackptr]; #ifdef WIN32 if (!r) return 1; RECT rect; rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; return RectInRegion(r,&rect); #elif defined(__APPLE_QD__) if (!r) return 1; Rect rect; rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; return RectInRgn(&rect, r); #elif defined(__APPLE_QUARTZ__) if (!r) return 1; Rect rect; rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; return RectInRgn(&rect, r); #else return r ? XRectInRegion(r, x, y, w, h) : 1; #endif } // return rectangle surrounding intersection of this rectangle and clip: int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ X = x; Y = y; W = w; H = h; Fl_Region r = rstack[rstackptr]; if (!r) return 0; #ifdef WIN32 // The win32 API makes no distinction between partial and complete // intersection, so we have to check for partial intersection ourselves. // However, given that the regions may be composite, we have to do // some voodoo stuff... Fl_Region rr = XRectangleRegion(x,y,w,h); Fl_Region temp = CreateRectRgn(0,0,0,0); int ret; if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint W = H = 0; ret = 2; } else if (EqualRgn(temp, rr)) { // complete ret = 0; } else { // parital intersection RECT rect; GetRgnBox(temp, &rect); X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y; ret = 1; } DeleteObject(temp); DeleteObject(rr); return ret; #elif defined(__APPLE_QD__) RgnHandle rr = NewRgn(); SetRectRgn( rr, x, y, x+w, y+h ); SectRgn( r, rr, rr ); Rect rp; GetRegionBounds(rr, &rp); X = rp.left; Y = rp.top; W = rp.right - X; H = rp.bottom - Y; DisposeRgn( rr ); if ( H==0 ) return 2; if ( h==H && w==W ) return 0; return 0; #elif defined(__APPLE_QUARTZ__) RgnHandle rr = NewRgn(); SetRectRgn( rr, x, y, x+w, y+h ); SectRgn( r, rr, rr ); Rect rp; GetRegionBounds(rr, &rp); X = rp.left; Y = rp.top; W = rp.right - X; H = rp.bottom - Y; DisposeRgn( rr ); if ( H==0 ) return 2; if ( h==H && w==W ) return 0; return 0; #else switch (XRectInRegion(r, x, y, w, h)) { case 0: // completely outside W = H = 0; return 2; case 1: // completely inside: return 0; default: // partial: break; } Fl_Region rr = XRectangleRegion(x,y,w,h); Fl_Region temp = XCreateRegion(); XIntersectRegion(r, rr, temp); XRectangle rect; XClipBox(temp, &rect); X = rect.x; Y = rect.y; W = rect.width; H = rect.height; XDestroyRegion(temp); XDestroyRegion(rr); return 1; #endif } // // End of "$Id$". //