From 57193e52c0ea34a6af53289b72b232e226466bc1 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Tue, 31 Aug 2004 00:27:40 +0000 Subject: [PATCH] Quartz for FLTK 1.1: - added pixmap drawing (no masking yet) - added bitmap drawing - added line styles (complete) todo: - missing refresh (double test, fluid, others) - missing pixmap mask - color_chooser has alignment issues - images scale instead of beeing scissored - fonts git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@3798 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- FL/mac.H | 6 ++- src/Fl_Bitmap.cxx | 75 ++++++++------------------- src/Fl_Double_Window.cxx | 104 ++++++++++++++++++-------------------- src/Fl_Image.cxx | 10 ++-- src/Fl_Pixmap.cxx | 25 ++------- src/Fl_mac.cxx | 54 +++++++++++--------- src/fl_draw_image_mac.cxx | 51 +++++++++++++++++-- src/fl_line_style.cxx | 71 ++++++++++++++++++++------ test/demo.menu | 2 +- 9 files changed, 215 insertions(+), 183 deletions(-) diff --git a/FL/mac.H b/FL/mac.H index 4d38025a2..8f29c45e5 100644 --- a/FL/mac.H +++ b/FL/mac.H @@ -1,5 +1,5 @@ // -// "$Id: mac.H,v 1.1.2.13 2004/08/27 20:02:43 matthiaswm Exp $" +// "$Id: mac.H,v 1.1.2.14 2004/08/31 00:27:40 matthiaswm Exp $" // // Mac header file for the Fast Light Tool Kit (FLTK). // @@ -82,6 +82,8 @@ public: static void q_fill_context(); // fill a Quartz context with current FLTK state static void q_clear_clipping(); // remove all clipping from a Quartz context static void q_release_context(Fl_X *x=0); // free all resources associated with fl_gc + static void q_begin_image(CGRect&, int x, int y); + static void q_end_image(); }; inline Window fl_xid(const Fl_Window*w) @@ -124,6 +126,6 @@ extern void fl_open_callback(void (*cb)(const char *)); extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); // -// End of "$Id: mac.H,v 1.1.2.13 2004/08/27 20:02:43 matthiaswm Exp $". +// End of "$Id: mac.H,v 1.1.2.14 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/src/Fl_Bitmap.cxx b/src/Fl_Bitmap.cxx index c1799e29c..83c44aa9f 100644 --- a/src/Fl_Bitmap.cxx +++ b/src/Fl_Bitmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.24 2004/08/25 00:20:25 matthiaswm Exp $" +// "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.25 2004/08/31 00:27:40 matthiaswm Exp $" // // Bitmap drawing routines for the Fast Light Tool Kit (FLTK). // @@ -78,49 +78,23 @@ void fl_delete_bitmask(Fl_Bitmask id) { if (id) DisposeGWorld(id); } #elif defined(__APPLE_QUARTZ__) -# warning quartz Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { - Rect srcRect; - srcRect.left = 0; srcRect.right = w; - srcRect.top = 0; srcRect.bottom = h; - GrafPtr savePort; - - GetPort(&savePort); // remember the current port - - Fl_Bitmask gw; - NewGWorld( &gw, 1, &srcRect, 0L, 0L, 0 ); - PixMapHandle pm = GetGWorldPixMap( gw ); - if ( pm ) - { - LockPixels( pm ); - if ( *pm ) - { - uchar *base = (uchar*)GetPixBaseAddr( pm ); - if ( base ) - { - PixMapPtr pmp = *pm; - // verify the parameters for direct memory write - if ( pmp->pixelType == 0 || pmp->pixelSize == 1 || pmp->cmpCount == 1 || pmp->cmpSize == 1 ) - { - static uchar reverse[16] = /* Bit reversal lookup table */ - { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; - uchar *dst = base; - const uchar *src = array; - int rowBytesSrc = (w+7)>>3 ; - int rowPatch = (pmp->rowBytes&0x3fff) - rowBytesSrc; - for ( int j=0; j> 4) & 0x0f] & 0x0f); - } - } - UnlockPixels( pm ); - } + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, + 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + int rowBytes = (w+7)>>3 ; + uchar *bmask = (uchar*)malloc(rowBytes*h), *dst = bmask; + const uchar *src = array; + for ( int i=rowBytes*h; i>0; i--,src++ ) { + *dst++ = ((reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f))^0xff; } - SetPort(savePort); - return gw; /* tell caller we succeeded! */ + CGDataProviderRef srcp = CGDataProviderCreateWithData( 0L, bmask, rowBytes*h, 0L); + CGImageRef id = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false); + CGDataProviderRelease(srcp); + return (Fl_Bitmask)id; } void fl_delete_bitmask(Fl_Bitmask id) { - if (id) DisposeGWorld(id); + if (id) CGImageRelease((CGImageRef)id); } #elif defined(WIN32) // Windows bitmask functions... // 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing... @@ -416,20 +390,13 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { srcOr, // mode 0L); // mask region #elif defined(__APPLE_QUARTZ__) -# warning quartz if (!id) id = fl_create_bitmask(w(), h(), array); - GrafPtr dstPort; - GetPort( &dstPort ); - Rect src, dst; - GetPortBounds( (Fl_Offscreen)id, &src ); - SetRect( &src, cx, cy, cx+W, cy+H ); - SetRect( &dst, X, Y, X+W, Y+H ); - CopyBits(GetPortBitMapForCopyBits((Fl_Offscreen)id), // srcBits - GetPortBitMapForCopyBits(dstPort), // dstBits - &src, // src bounds - &dst, // dst bounds - srcOr, // mode - 0L); // mask region + if (id && fl_gc) { + CGRect rect = { X, Y, W, H }; + Fl_X::q_begin_image(rect, cx, cy); + CGContextDrawImage(fl_gc, rect, (CGImageRef)id); + Fl_X::q_end_image(); + } #else if (!id) id = fl_create_bitmask(w(), h(), array); @@ -534,5 +501,5 @@ Fl_Image *Fl_Bitmap::copy(int W, int H) { // -// End of "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.24 2004/08/25 00:20:25 matthiaswm Exp $". +// End of "$Id: Fl_Bitmap.cxx,v 1.5.2.4.2.25 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx index a14aac216..4c597b110 100644 --- a/src/Fl_Double_Window.cxx +++ b/src/Fl_Double_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Double_Window.cxx,v 1.12.2.4.2.10 2004/08/25 00:20:25 matthiaswm Exp $" +// "$Id: Fl_Double_Window.cxx,v 1.12.2.4.2.11 2004/08/31 00:27:40 matthiaswm Exp $" // // Double-buffered window code for the Fast Light Tool Kit (FLTK). // @@ -164,70 +164,62 @@ void fl_end_offscreen() { extern void fl_restore_clip(); #elif defined(__APPLE_QUARTZ__) -#warning quartz -GWorldPtr fl_create_offscreen(int w, int h) { - GWorldPtr gw; - Rect bounds; - bounds.left=0; bounds.right=w; bounds.top=0; bounds.bottom=h; - QDErr err = NewGWorld(&gw, 0, &bounds, 0L, 0L, 0); // 'useTempMem' should not be used (says the Carbon port manual) - if ( err == -108 ) - { } -// fl_message( "The application memory is low. Please increase the initial memory assignment.\n" ); - if (err!=noErr || gw==0L) return 0L; - return gw; + +Fl_Offscreen fl_create_offscreen(int w, int h) { + void *data = malloc(w*h*4); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGContextRef ctx = CGBitmapContextCreate( + data, w, h, 8, w*4, lut, kCGImageAlphaNoneSkipLast); + CGColorSpaceRelease(lut); + return (Fl_Offscreen)ctx; } -void fl_copy_offscreen(int x,int y,int w,int h,GWorldPtr gWorld,int srcx,int srcy) { - Rect src; - if ( !gWorld ) return; - src.top = srcy; src.left = srcx; src.bottom = srcy+h; src.right = srcx+w; - Rect dst; - GrafPtr dstPort; GetPort(&dstPort); - dst.top = y; dst.left = x; dst.bottom = y+h; dst.right = x+w; - RGBColor rgb; - rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; - RGBBackColor( &rgb ); - rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; - RGBForeColor( &rgb ); - CopyBits(GetPortBitMapForCopyBits(gWorld), GetPortBitMapForCopyBits(dstPort), &src, &dst, srcCopy, 0L); +void fl_copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) { +#warning : test this implementation! + CGContextRef src = (CGContextRef)osrc; + void *data = CGBitmapContextGetData(src); + int sw = CGBitmapContextGetWidth(src); + int sh = CGBitmapContextGetHeight(src); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src_bytes = CGDataProviderCreateWithData( 0L, data, sw*sh*4, 0L); + CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, kCGImageAlphaNoneSkipLast, + src_bytes, 0L, false, kCGRenderingIntentDefault); + // fl_push_clip(); + CGRect rect = { x, y, w, h }; + Fl_X::q_begin_image(rect, srcx, srcy); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CGImageRelease(img); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src_bytes); } -void fl_delete_offscreen(GWorldPtr gWorld) { - DisposeGWorld(gWorld); +void fl_delete_offscreen(Fl_Offscreen ctx) { + if (!ctx) return; + void *data = CGBitmapContextGetData((CGContextRef)ctx); + CGContextRelease((CGContextRef)ctx); + if (!data) return; + free(data); } -static GrafPtr prevPort; -static GDHandle prevGD; +static CGContextRef prev_gc = 0; +static Window prev_window = 0; -void fl_begin_offscreen(GWorldPtr gWorld) { - GetGWorld( &prevPort, &prevGD ); - if ( gWorld ) - { - SetGWorld( gWorld, 0 ); // sets the correct port - PixMapHandle pm = GetGWorldPixMap(gWorld); - Boolean ret = LockPixels(pm); - if ( ret == false ) - { - Rect rect; - GetPortBounds( gWorld, &rect ); - UpdateGWorld( &gWorld, 0, &rect, 0, 0, 0 ); - pm = GetGWorldPixMap( gWorld ); - LockPixels( pm ); - } - fl_window = 0; - } - fl_push_no_clip(); +void fl_begin_offscreen(Fl_Offscreen ctx) { + prev_gc = fl_gc; + prev_window = fl_window; + fl_gc = (CGContextRef)ctx; + fl_window = 0; + //fl_push_no_clip(); + CGContextSaveGState(fl_gc); + Fl_X::q_fill_context(); } void fl_end_offscreen() { - GWorldPtr currPort; - GDHandle currGD; - GetGWorld( &currPort, &currGD ); - fl_pop_clip(); - PixMapHandle pm = GetGWorldPixMap(currPort); - UnlockPixels(pm); - SetGWorld( prevPort, prevGD ); - fl_window = GetWindowFromPort( prevPort ); + Fl_X::q_release_context(); + //fl_pop_clip(); + fl_gc = prev_gc; + fl_window = prev_window; } extern void fl_restore_clip(); @@ -375,5 +367,5 @@ Fl_Double_Window::~Fl_Double_Window() { } // -// End of "$Id: Fl_Double_Window.cxx,v 1.12.2.4.2.10 2004/08/25 00:20:25 matthiaswm Exp $". +// End of "$Id: Fl_Double_Window.cxx,v 1.12.2.4.2.11 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx index 8cf8af3fa..bfb0fc0ab 100644 --- a/src/Fl_Image.cxx +++ b/src/Fl_Image.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Image.cxx,v 1.5.2.3.2.35 2004/08/28 13:45:27 easysw Exp $" +// "$Id: Fl_Image.cxx,v 1.5.2.3.2.36 2004/08/31 00:27:40 matthiaswm Exp $" // // Image drawing code for the Fast Light Tool Kit (FLTK). // @@ -327,7 +327,6 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { fl_begin_offscreen((Fl_Offscreen)id); fl_draw_image(array, 0, 0, w(), h(), d(), ld()); fl_end_offscreen(); - if (d() == 2 || d() == 4) { mask = fl_create_alphamask(w(), h(), d(), ld(), array); } @@ -380,10 +379,11 @@ void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); } #elif defined(__APPLE_QUARTZ__) -# warning : Quartz implementation not finished yet if (id && fl_gc) { - CGRect rect = { X, Y, w(), h() }; + CGRect rect = { X, Y, W, H }; + Fl_X::q_begin_image(rect, cx, cy); CGContextDrawImage(fl_gc, rect, (CGImageRef)id); + Fl_X::q_end_image(); } #else if (mask) { @@ -418,5 +418,5 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) { // -// End of "$Id: Fl_Image.cxx,v 1.5.2.3.2.35 2004/08/28 13:45:27 easysw Exp $". +// End of "$Id: Fl_Image.cxx,v 1.5.2.3.2.36 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/src/Fl_Pixmap.cxx b/src/Fl_Pixmap.cxx index 924246a13..620d3f308 100644 --- a/src/Fl_Pixmap.cxx +++ b/src/Fl_Pixmap.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.29 2004/08/25 00:20:25 matthiaswm Exp $" +// "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.30 2004/08/31 00:27:40 matthiaswm Exp $" // // Pixmap drawing code for the Fast Light Tool Kit (FLTK). // @@ -80,6 +80,7 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { if (cy+H > h()) H = h()-cy; if (H <= 0) return; if (!id) { +#warning : to enable masking in Quartz, write our own version of this little function! id = fl_create_offscreen(w(), h()); fl_begin_offscreen((Fl_Offscreen)id); uchar *bitmap = 0; @@ -124,25 +125,7 @@ void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); } #elif defined(__APPLE_QUARTZ__) -#warning quartz - if (mask) { - Rect src, dst; - src.left = cx; src.right = cx+W; - src.top = cy; src.bottom = cy+H; - dst.left = X; dst.right = X+W; - dst.top = Y; dst.bottom = Y+H; - RGBColor rgb; - rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; - RGBBackColor(&rgb); - rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; - RGBForeColor(&rgb); - CopyMask(GetPortBitMapForCopyBits((GrafPtr)id), - GetPortBitMapForCopyBits((GrafPtr)mask), - GetPortBitMapForCopyBits(GetWindowPort(fl_window)), - &src, &src, &dst); - } else { - fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); - } + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); #else if (mask) { // I can't figure out how to combine a mask with existing region, @@ -481,5 +464,5 @@ void Fl_Pixmap::desaturate() { } // -// End of "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.29 2004/08/25 00:20:25 matthiaswm Exp $". +// End of "$Id: Fl_Pixmap.cxx,v 1.9.2.4.2.30 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx index 76aae83a4..f1ff1621d 100644 --- a/src/Fl_mac.cxx +++ b/src/Fl_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_mac.cxx,v 1.1.2.61 2004/08/27 20:02:44 matthiaswm Exp $" +// "$Id: Fl_mac.cxx,v 1.1.2.62 2004/08/31 00:27:40 matthiaswm Exp $" // // MacOS specific code for the Fast Light Tool Kit (FLTK). // @@ -1859,29 +1859,10 @@ void Fl_Window::make_current() SetPortClipRegion( GetWindowPort(i->xid), fl_window_region ); #ifdef __APPLE_QUARTZ__ #warning : bracket all the QD stuff above with ifdefs! -#warning : verbose copy of patch; please check code -#if 0 - Rect portRect; - GetPortBounds(GetWindowPort(i->xid), &portRect); - short port_height = portRect.bottom - portRect.top; - if (!i->gc) { - //CreateCGContextForPort(GetWindowPort(i->xid), &i->gc); - QDBeginCGContext(GetWindowPort(i->xid), &i->gc); - // save the unclipped state for later - CGContextSaveGState(i->gc); - // translate coordinate system to coorespond with fltk's. - CGContextTranslateCTM(i->gc, 0.5f, port_height-0.5f); - CGContextScaleCTM(i->gc, 1.0f, -1.0f); - static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; - CGContextSetTextMatrix(i->gc, font_mx); - } - fl_gc = i->gc; -#else QDBeginCGContext(GetWindowPort(i->xid), &i->gc); fl_gc = i->gc; CGContextSaveGState(fl_gc); Fl_X::q_fill_context(); -#endif #endif return; } @@ -1891,19 +1872,27 @@ void Fl_Window::make_current() extern Fl_Color fl_color_; extern class Fl_FontSize *fl_fontsize; extern void fl_font(class Fl_FontSize*); +extern void fl_quartz_restore_line_style_(); // FLTK has only on global graphics state. This function copies the FLTK state into the // current Quartz context void Fl_X::q_fill_context() { if (!fl_gc) return; - Rect portRect; - GetPortBounds(GetWindowPort( fl_window ), &portRect); - CGContextTranslateCTM(fl_gc, 0.5, portRect.bottom-portRect.top-0.5f); + int hgt = 0; + if (fl_window) { + Rect portRect; + GetPortBounds(GetWindowPort( fl_window ), &portRect); + hgt = portRect.bottom-portRect.top; + } else { + hgt = CGBitmapContextGetHeight(fl_gc); + } + CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f); CGContextScaleCTM(fl_gc, 1.0f, -1.0f); static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; CGContextSetTextMatrix(fl_gc, font_mx); fl_font(fl_fontsize); fl_color(fl_color_); + fl_quartz_restore_line_style_(); } // The only way to reste clipping to its original state is to pop the current graphics @@ -1919,10 +1908,25 @@ void Fl_X::q_release_context(Fl_X *x) { if (x && x->gc!=fl_gc) return; if (!fl_gc) return; CGContextRestoreGState(fl_gc); - QDEndCGContext(GetWindowPort(fl_window), &fl_gc); + if (fl_window) QDEndCGContext(GetWindowPort(fl_window), &fl_gc); fl_gc = 0; } +void Fl_X::q_begin_image(CGRect &rect, int cx, int cy) { + CGContextSaveGState(fl_gc); + CGAffineTransform mx = CGContextGetCTM(fl_gc); + mx.d = -1.0; + CGContextConcatCTM(fl_gc, mx); + rect.origin.y = (mx.ty-0.5f) - rect.origin.y - rect.size.height + 1; +#warning : quartz - this needs to be fixed! + // this version will scale images into some position. Instead, it should clip them! + // we probably need the image size as an additional argument! +} + +void Fl_X::q_end_image() { + CGContextRestoreGState(fl_gc); +} + #endif //////////////////////////////////////////////////////////////// @@ -1997,6 +2001,6 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) { // -// End of "$Id: Fl_mac.cxx,v 1.1.2.61 2004/08/27 20:02:44 matthiaswm Exp $". +// End of "$Id: Fl_mac.cxx,v 1.1.2.62 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/src/fl_draw_image_mac.cxx b/src/fl_draw_image_mac.cxx index 5e656b5f3..08820ffd6 100644 --- a/src/fl_draw_image_mac.cxx +++ b/src/fl_draw_image_mac.cxx @@ -1,5 +1,5 @@ // -// "$Id: fl_draw_image_mac.cxx,v 1.1.2.7 2004/08/25 00:20:27 matthiaswm Exp $" +// "$Id: fl_draw_image_mac.cxx,v 1.1.2.8 2004/08/31 00:27:40 matthiaswm Exp $" // // MacOS image drawing code for the Fast Light Tool Kit (FLTK). // @@ -58,6 +58,7 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, { if (!linedelta) linedelta = W*delta; +#ifdef __APPLE_QD__ // theoretically, if the current GPort permits, we could write // directly into it, avoiding the temporary GWorld. For now I // will go the safe way... . @@ -167,7 +168,51 @@ static void innards(const uchar *buf, int X, int Y, int W, int H, } } } - +#elif defined(__APPLE_QUARTZ__) + // following the very save (and very slow) way to write the image into the give port + CGContextSetShouldAntialias(fl_gc, false); + if ( cb ) + { + uchar *tmpBuf = new uchar[ W*4 ]; + for ( int i=0; i +#ifdef __APPLE_QUARTZ__ +static float fl_quartz_line_width_ = 1.0f; +static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt; +static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter; +static float *fl_quartz_line_pattern = 0; +static int fl_quartz_line_pattern_size = 0; +void fl_quartz_restore_line_style_() { + CGContextSetLineWidth(fl_gc, fl_quartz_line_width_); + CGContextSetLineCap(fl_gc, fl_quartz_line_cap_); + CGContextSetLineJoin(fl_gc, fl_quartz_line_join_); + CGContextSetLineDash(fl_gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size); +} +#endif + void fl_line_style(int style, int width, char* dashes) { #ifdef WIN32 // According to Bill, the "default" cap and join should be the @@ -69,20 +83,45 @@ void fl_line_style(int style, int width, char* dashes) { if (style > 2) style = 2; PenPat(styles + style); #elif defined(__APPLE_QUARTZ__) -#warning quartz - // QuickDraw supports pen size and pattern, but no arbitrary line styles. - static Pattern styles[] = { - { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }, // FL_SOLID - { { 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f } }, // FL_DASH - { { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 } } // FL_DOT - }; - - if (!width) width = 1; - PenSize(width, width); - - style &= 0xff; - if (style > 2) style = 2; - PenPat(styles + style); + static enum CGLineCap Cap[4] = { kCGLineCapButt, kCGLineCapButt, + kCGLineCapRound, kCGLineCapSquare }; + static enum CGLineJoin Join[4] = { kCGLineJoinMiter, kCGLineJoinMiter, + kCGLineJoinRound, kCGLineJoinBevel }; + if (width<1) width = 1; + fl_quartz_line_width_ = (float)width; + fl_quartz_line_cap_ = Cap[(style>>8)&3]; + fl_quartz_line_join_ = Join[(style>>12)&3]; + char *d = dashes; + static float pattern[16]; + if (d && *d) { + float *p = pattern; + while (*d) { *p++ = (float)*d++; } + fl_quartz_line_pattern = pattern; + fl_quartz_line_pattern_size = d-dashes; + } else if (style & 0xff) { + char dash, dot, gap; + // adjust lengths to account for cap: + if (style & 0x200) { + dash = char(2*width); + dot = 1; + gap = char(2*width-1); + } else { + dash = char(3*width); + dot = gap = char(width); + } + float *p = pattern; + switch (style & 0xff) { + case FL_DASH: *p++ = dash; *p++ = gap; break; + case FL_DOT: *p++ = dot; *p++ = gap; break; + case FL_DASHDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break; + case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break; + } + fl_quartz_line_pattern_size = p-pattern; + fl_quartz_line_pattern = pattern; + } else { + fl_quartz_line_pattern = 0; fl_quartz_line_pattern_size = 0; + } + fl_quartz_restore_line_style_(); #else int ndashes = dashes ? strlen(dashes) : 0; // emulate the WIN32 dash patterns on X @@ -119,5 +158,5 @@ void fl_line_style(int style, int width, char* dashes) { // -// End of "$Id: fl_line_style.cxx,v 1.3.2.3.2.15 2004/08/25 00:20:27 matthiaswm Exp $". +// End of "$Id: fl_line_style.cxx,v 1.3.2.3.2.16 2004/08/31 00:27:40 matthiaswm Exp $". // diff --git a/test/demo.menu b/test/demo.menu index 60c9e1cc1..75417d01f 100644 --- a/test/demo.menu +++ b/test/demo.menu @@ -48,7 +48,7 @@ @u:navigation:navigation @u:minimum update:minimum @u:keyboard:keyboard - @u:fast & slow widgets:fast_slow + @u:fast && slow widgets:fast_slow @u:inactive:inactive @main:Fluid\n(UI design tool):../fluid/fluid valuators.fl