diff options
| author | maxim nikonov <maxim.nikonov@hqo.co> | 2026-02-05 15:21:34 +0500 |
|---|---|---|
| committer | maxim nikonov <maxim.nikonov@hqo.co> | 2026-02-05 15:21:34 +0500 |
| commit | db214d1145e46d527a46d1fc2519548d2c4d23f1 (patch) | |
| tree | cf0fd9922e4d54f6beb63888f9b28c8e2a787bdf /src/drivers/Quartz | |
| parent | 75fc94d6c71fe686f6dde5b41ad91cba2f6bdd6f (diff) | |
wip: fork
Diffstat (limited to 'src/drivers/Quartz')
| -rw-r--r-- | src/drivers/Quartz/Fl_Font.H | 42 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.H | 39 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx | 71 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H | 149 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx | 133 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx | 65 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx | 70 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx | 561 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx | 284 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx | 83 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx | 310 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx | 98 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H | 38 | ||||
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx | 167 |
14 files changed, 0 insertions, 2110 deletions
diff --git a/src/drivers/Quartz/Fl_Font.H b/src/drivers/Quartz/Fl_Font.H deleted file mode 100644 index f1a710eea..000000000 --- a/src/drivers/Quartz/Fl_Font.H +++ /dev/null @@ -1,42 +0,0 @@ -// -// Font definitions for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2026 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -// Two internal fltk data structures: -// -// Fl_Fontdesc: an entry into the fl_font() table. There is one of these -// for each fltk font number. -// -#ifndef FL_FONT_ -#define FL_FONT_ - -#include <config.h> -#include "Fl_Quartz_Graphics_Driver.H" -#include "../../Fl_Scalable_Graphics_Driver.H" // Fl_Font_Descriptor -#include <ApplicationServices/ApplicationServices.h> - -class Fl_Quartz_Font_Descriptor : public Fl_Font_Descriptor { -public: - Fl_Quartz_Font_Descriptor(const char* fontname, Fl_Fontsize size); - virtual FL_EXPORT ~Fl_Quartz_Font_Descriptor(); - CTFontRef fontref; - // the unicode span is divided in 512 blocks of 128 characters - float *width[512]; // array of arrays of character widths - short q_width; -}; - -extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table - -#endif diff --git a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.H b/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.H deleted file mode 100644 index 8ef586624..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.H +++ /dev/null @@ -1,39 +0,0 @@ -// -// Definition of Apple Quartz graphics driver -// for the Fast Light Tool Kit (FLTK). -// -// Copyright 2010-2016 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - - -#ifndef Fl_Quartz_Copy_Surface_Driver_H -#define Fl_Quartz_Copy_Surface_Driver_H - -#include <FL/Fl_Copy_Surface.H> -#include <FL/platform.H> - -class Fl_Quartz_Copy_Surface_Driver : public Fl_Copy_Surface_Driver { - friend class Fl_Copy_Surface_Driver; -protected: - CFMutableDataRef pdfdata; - CGContextRef gc; - static size_t MyPutBytes(void* info, const void* buffer, size_t count); - Fl_Quartz_Copy_Surface_Driver(int w, int h); - // implemented in Fl_cocoa.mm because uses Objective-c - ~Fl_Quartz_Copy_Surface_Driver(); - void set_current() FL_OVERRIDE; - void translate(int x, int y) FL_OVERRIDE; - void untranslate() FL_OVERRIDE; -}; - -#endif /* Fl_Quartz_Copy_Surface_Driver_H */ diff --git a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx deleted file mode 100644 index 77ecdaa0a..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Copy_Surface_Driver.cxx +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copy-to-clipboard code for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2019 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include <FL/Fl_Copy_Surface.H> -#include <FL/platform.H> -#include "Fl_Quartz_Graphics_Driver.H" -#include "Fl_Quartz_Copy_Surface_Driver.H" -#include "../Cocoa/Fl_Cocoa_Window_Driver.H" - - -Fl_Quartz_Copy_Surface_Driver::Fl_Quartz_Copy_Surface_Driver(int w, int h) : Fl_Copy_Surface_Driver(w, h) { - driver(new Fl_Quartz_Printer_Graphics_Driver); - pdfdata = CFDataCreateMutable(NULL, 0); - CGDataConsumerRef myconsumer; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040 - if (&CGDataConsumerCreateWithCFData != NULL) { - myconsumer = CGDataConsumerCreateWithCFData(pdfdata); // 10.4 - } - else -#endif - { - static CGDataConsumerCallbacks callbacks = { Fl_Quartz_Copy_Surface_Driver::MyPutBytes, NULL }; - myconsumer = CGDataConsumerCreate((void*) pdfdata, &callbacks); - } - float d = fl_graphics_driver->scale(); - CGRect bounds = CGRectMake(0, 0, w * d, h * d); - gc = CGPDFContextCreate(myconsumer, &bounds, NULL); - CGDataConsumerRelease(myconsumer); - if (gc) { - CGContextBeginPage(gc, &bounds); - CGContextScaleCTM(gc, d, -d); - CGContextTranslateCTM(gc, 0.5, -h + 0.5); - CGContextSaveGState(gc); - } -} - -void Fl_Quartz_Copy_Surface_Driver::set_current() { - driver()->gc(gc); - fl_window = (FLWindow*)1; - Fl_Surface_Device::set_current(); -} - -size_t Fl_Quartz_Copy_Surface_Driver::MyPutBytes(void* info, const void* buffer, size_t count) -{ - CFDataAppendBytes ((CFMutableDataRef) info, (const UInt8 *)buffer, count); - return count; -} - -void Fl_Quartz_Copy_Surface_Driver::translate(int x, int y) { - CGContextRestoreGState(gc); - CGContextSaveGState(gc); - CGContextTranslateCTM(gc, x, y); - CGContextSaveGState(gc); -} - -void Fl_Quartz_Copy_Surface_Driver::untranslate() { - CGContextRestoreGState(gc); -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H deleted file mode 100644 index 0afc7369e..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.H +++ /dev/null @@ -1,149 +0,0 @@ -// -// Definition of Apple Quartz graphics driver -// for the Fast Light Tool Kit (FLTK). -// -// Copyright 2010-2026 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -/** - \file Fl_Quartz_Graphics_Driver.H - \brief Definition of Apple Quartz graphics driver. - */ - -#ifndef FL_QUARTZ_GRAPHICS_DRIVER_H -#define FL_QUARTZ_GRAPHICS_DRIVER_H - -#include <FL/platform.H> -#include <FL/Fl_Graphics_Driver.H> -#include <ApplicationServices/ApplicationServices.h> - -struct Fl_Fontdesc; -class Fl_Quartz_Font_Descriptor; - -/** - \brief The Mac OS X-specific graphics class. - - This class is implemented only on the Mac OS X platform. - */ -class Fl_Quartz_Graphics_Driver : public Fl_Graphics_Driver { - friend class Fl_Cocoa_Printer_Driver; - friend class Fl_Quartz_Font_Descriptor; -protected: - CGContextRef gc_; - bool high_resolution_; - float quartz_line_width_; - CGLineCap quartz_line_cap_; - CGLineJoin quartz_line_join_; - CGFloat *quartz_line_pattern; - int quartz_line_pattern_size; - void cache_size(Fl_Image* img, int &width, int &height) FL_OVERRIDE; -public: - Fl_Quartz_Graphics_Driver(); - int has_feature(driver_feature mask) FL_OVERRIDE { return mask & NATIVE; } - void gc(void *ctxt) FL_OVERRIDE { gc_ = (CGContextRef)ctxt; global_gc(); } - void *gc() FL_OVERRIDE {return gc_;} - char can_do_alpha_blending() FL_OVERRIDE; - - // --- bitmap stuff - static CGImageRef create_bitmask(int w, int h, const uchar *array); // NOT virtual - void delete_bitmask(fl_uintptr_t bm) FL_OVERRIDE; - void draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; - void draw_bitmap(Fl_Bitmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; - void draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) FL_OVERRIDE; - void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) FL_OVERRIDE; - void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) FL_OVERRIDE; - void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0) FL_OVERRIDE; - void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) FL_OVERRIDE; - void cache(Fl_Pixmap *img) FL_OVERRIDE; - void cache(Fl_Bitmap *img) FL_OVERRIDE; - void cache(Fl_RGB_Image *img) FL_OVERRIDE; - void uncache(Fl_RGB_Image *img, fl_uintptr_t &id_, fl_uintptr_t &mask_) FL_OVERRIDE; - void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) FL_OVERRIDE; - void draw_CGImage(CGImageRef cgimg, int x, int y, int w, int h, int srcx, int srcy, int sw, int sh); - static CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h); - void add_rectangle_to_region(Fl_Region r, int x, int y, int w, int h) FL_OVERRIDE; - Fl_Region XRectangleRegion(int x, int y, int w, int h) FL_OVERRIDE; - void XDestroyRegion(Fl_Region r) FL_OVERRIDE; - void high_resolution(bool b) { high_resolution_ = b; } -protected: - void point(int x, int y) FL_OVERRIDE; - void rect(int x, int y, int w, int h) FL_OVERRIDE; - void focus_rect(int x, int y, int w, int h) FL_OVERRIDE; - void rectf(int x, int y, int w, int h) FL_OVERRIDE; - void line(int x, int y, int x1, int y1) FL_OVERRIDE; - void line(int x, int y, int x1, int y1, int x2, int y2) FL_OVERRIDE; - void xyline(int x, int y, int x1) FL_OVERRIDE; - void xyline(int x, int y, int x1, int y2) FL_OVERRIDE; - void xyline(int x, int y, int x1, int y2, int x3) FL_OVERRIDE; - void yxline(int x, int y, int y1) FL_OVERRIDE; - void yxline(int x, int y, int y1, int x2) FL_OVERRIDE; - void yxline(int x, int y, int y1, int x2, int y3) FL_OVERRIDE; - void loop(int x0, int y0, int x1, int y1, int x2, int y2) FL_OVERRIDE; - void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) FL_OVERRIDE; - void polygon(int x0, int y0, int x1, int y1, int x2, int y2) FL_OVERRIDE; - void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) FL_OVERRIDE; - // --- clipping - void push_clip(int x, int y, int w, int h) FL_OVERRIDE; - int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) FL_OVERRIDE; - int not_clipped(int x, int y, int w, int h) FL_OVERRIDE; - void restore_clip() FL_OVERRIDE; - void end_points() FL_OVERRIDE; - void end_line() FL_OVERRIDE; - void end_polygon() FL_OVERRIDE; - void end_complex_polygon() FL_OVERRIDE; - void circle(double x, double y, double r) FL_OVERRIDE; - void arc(int x, int y, int w, int h, double a1, double a2) FL_OVERRIDE; - void pie(int x, int y, int w, int h, double a1, double a2) FL_OVERRIDE; - void line_style(int style, int width=0, char* dashes=0) FL_OVERRIDE; - void color(Fl_Color c) FL_OVERRIDE; - Fl_Color color() FL_OVERRIDE { return color_; } - void color(uchar r, uchar g, uchar b) FL_OVERRIDE; - void draw(const char *str, int n, int x, int y) FL_OVERRIDE; - void draw(const char *str, int n, float x, float y) FL_OVERRIDE; - void draw(int angle, const char *str, int n, int x, int y) FL_OVERRIDE; - double width(const UniChar* txt, int n); - void rtl_draw(const char *str, int n, int x, int y) FL_OVERRIDE; - void font(Fl_Font face, Fl_Fontsize fsize) FL_OVERRIDE; - double width(const char *str, int n) FL_OVERRIDE; - double width(unsigned int c) FL_OVERRIDE; - int height() FL_OVERRIDE; - int descent() FL_OVERRIDE; - virtual bool high_resolution() { return high_resolution_; } - void global_gc() FL_OVERRIDE; - void quartz_restore_line_style(); - inline Fl_Quartz_Font_Descriptor *valid_font_descriptor(); - const char* get_font_name(Fl_Font fnum, int* ap) FL_OVERRIDE; - int get_font_sizes(Fl_Font fnum, int*& sizep) FL_OVERRIDE; - const char *font_name(int num) FL_OVERRIDE; - void font_name(int num, const char *name) FL_OVERRIDE; - Fl_Fontdesc* calc_fl_fonts(void) FL_OVERRIDE; - - void text_extents(const char*, int n, int& dx, int& dy, int& w, int& h) FL_OVERRIDE; - Fl_Font set_fonts(const char* xstarname) FL_OVERRIDE; - void set_fontname_in_fontdesc(Fl_Fontdesc *f); - void uncache_pixmap(fl_uintptr_t p) FL_OVERRIDE; - - void descriptor_init(const char* name, Fl_Fontsize Size, Fl_Quartz_Font_Descriptor *d); - void overlay_rect(int x, int y, int w , int h) FL_OVERRIDE; - float override_scale() FL_OVERRIDE; - void restore_scale(float) FL_OVERRIDE; - void antialias(int state) FL_OVERRIDE; - int antialias() FL_OVERRIDE; -}; - -class Fl_Quartz_Printer_Graphics_Driver : public Fl_Quartz_Graphics_Driver { -public: - int has_feature(driver_feature mask) FL_OVERRIDE { return mask & (NATIVE | PRINTER); } -}; - -#endif // FL_QUARTZ_GRAPHICS_DRIVER_H diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx deleted file mode 100644 index 21c5eda4c..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver.cxx +++ /dev/null @@ -1,133 +0,0 @@ -// -// Rectangle drawing routines for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2026 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include <config.h> -#include "Fl_Quartz_Graphics_Driver.H" -#include "../Darwin/Fl_Darwin_System_Driver.H" -#include "../Cocoa/Fl_Cocoa_Screen_Driver.H" -#include <FL/platform.H> -#include <FL/fl_draw.H> -#include <FL/Fl_Image_Surface.H> - - -void Fl_Quartz_Graphics_Driver::antialias(int state) { -} - -int Fl_Quartz_Graphics_Driver::antialias() { - return 1; -} - -Fl_Quartz_Graphics_Driver::Fl_Quartz_Graphics_Driver() : Fl_Graphics_Driver(), gc_(NULL) { - quartz_line_width_ = 1.f; - quartz_line_cap_ = kCGLineCapButt; - quartz_line_join_ = kCGLineJoinMiter; - quartz_line_pattern = 0; - quartz_line_pattern_size = 0; - high_resolution_ = false; -} - -char Fl_Quartz_Graphics_Driver::can_do_alpha_blending() { - return 1; -} - -static void bmProviderRelease (void *src, const void *data, size_t size) { - CFIndex count = CFGetRetainCount(src); - CFRelease(src); - if(count == 1) free((void*)data); -} - -/* Reference to the current CGContext - For back-compatibility only. The preferred procedure to get this reference is - Fl_Surface_Device::surface()->driver()->gc(). - */ -CGContextRef fl_gc = 0; - -void Fl_Quartz_Graphics_Driver::global_gc() -{ - fl_gc = (CGContextRef)gc(); -} - - -CGContextRef fl_mac_gc() { return fl_gc; } - - -void Fl_Quartz_Graphics_Driver::copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) { - // draw portion srcx,srcy,w,h of osrc to position x,y (top-left) of the graphics driver's surface - CGContextRef src = (CGContextRef)osrc; - int sw = (int)CGBitmapContextGetWidth(src); - int sh = (int)CGBitmapContextGetHeight(src); - CGImageRef img; - img = CGBitmapContextCreateImage(src); // requires 10.4 - CGAffineTransform at = CGContextGetCTM(src); - float s = at.a; - draw_CGImage(img, x, y, w, h, srcx, srcy, sw/s, sh/s); - CGImageRelease(img); -} - -// so a CGRect matches exactly what is denoted x,y,w,h for clipping purposes -CGRect Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(int x, int y, int w, int h) { - return CGRectMake(x - 0.5, y - 0.5, w, h); -} - -void Fl_Quartz_Graphics_Driver::add_rectangle_to_region(Fl_Region r_, int X, int Y, int W, int H) { - struct flCocoaRegion *r = (struct flCocoaRegion*)r_; - CGRect arg = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(X, Y, W, H); - int j; // don't add a rectangle totally inside the Fl_Region - for(j = 0; j < r->count; j++) { - if(CGRectContainsRect(r->rects[j], arg)) break; - } - if( j >= r->count) { - r->rects = (CGRect*)realloc(r->rects, (++(r->count)) * sizeof(CGRect)); - r->rects[r->count - 1] = arg; - } -} - -Fl_Region Fl_Quartz_Graphics_Driver::XRectangleRegion(int x, int y, int w, int h) { - struct flCocoaRegion* R = (struct flCocoaRegion*)malloc(sizeof(struct flCocoaRegion)); - R->count = 1; - R->rects = (CGRect *)malloc(sizeof(CGRect)); - *(R->rects) = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); - return R; -} - -void Fl_Quartz_Graphics_Driver::XDestroyRegion(Fl_Region r_) { - if (r_) { - struct flCocoaRegion *r = (struct flCocoaRegion*)r_; - free(r->rects); - free(r); - } -} - -void Fl_Quartz_Graphics_Driver::cache_size(Fl_Image *img, int &width, int &height) { - width *= 2 * scale(); - height *= 2 * scale(); -} - -float Fl_Quartz_Graphics_Driver::override_scale() { - float s = scale(); - if (s != 1.f && Fl_Display_Device::display_device()->is_current()) { - CGContextScaleCTM(gc_, 1./s, 1./s); - Fl_Graphics_Driver::scale(1); - } - return s; -} - -void Fl_Quartz_Graphics_Driver::restore_scale(float s) { - if (s != 1.f && Fl_Display_Device::display_device()->is_current()) { - CGContextScaleCTM(gc_, s, s); - Fl_Graphics_Driver::scale(s); - } -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx deleted file mode 100644 index 4163de685..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_arci.cxx +++ /dev/null @@ -1,65 +0,0 @@ -// -// Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2018 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include "Fl_Quartz_Graphics_Driver.H" -#include <FL/platform.H> - -/** - \file quartz_arci.cxx - \brief Utility functions for drawing circles using integers -*/ - -void Fl_Quartz_Graphics_Driver::arc(int x,int y,int w,int h,double a1,double a2) { - if (w <= 0 || h <= 0) return; - a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; - float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; - CGContextSetShouldAntialias(gc_, true); - if (w!=h) { - CGContextSaveGState(gc_); - CGContextTranslateCTM(gc_, cx, cy); - CGContextScaleCTM(gc_, w-1.0f, h-1.0f); - CGContextAddArc(gc_, 0, 0, 0.5, a1, a2, 1); - CGContextRestoreGState(gc_); - } else { - float r = (w+h)*0.25f-0.5f; - CGContextAddArc(gc_, cx, cy, r, a1, a2, 1); - } - CGContextStrokePath(gc_); - CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::pie(int x,int y,int w,int h,double a1,double a2) { - if (w <= 0 || h <= 0) return; - a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; - float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; - CGContextSetShouldAntialias(gc_, true); - if (w!=h) { - CGContextSaveGState(gc_); - CGContextTranslateCTM(gc_, cx, cy); - CGContextScaleCTM(gc_, w, h); - CGContextAddArc(gc_, 0, 0, 0.5, a1, a2, 1); - CGContextAddLineToPoint(gc_, 0, 0); - CGContextClosePath(gc_); - CGContextRestoreGState(gc_); - } else { - float r = (w+h)*0.25f; - CGContextAddArc(gc_, cx, cy, r, a1, a2, 1); - CGContextAddLineToPoint(gc_, cx, cy); - CGContextClosePath(gc_); - } - CGContextFillPath(gc_); - CGContextSetShouldAntialias(gc_, false); -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx deleted file mode 100644 index 9d31f8573..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_color.cxx +++ /dev/null @@ -1,70 +0,0 @@ -// -// MacOS color functions for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2018 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -// The fltk "colormap". This allows ui colors to be stored in 8-bit -// locations, and provides a level of indirection so that global color -// changes can be made. Not to be confused with the X colormap, which -// I try to hide completely. - -// matt: Neither Quartz nor Quickdraw support colormaps in this implementation -// matt: Quartz support done - -#include "Fl_Quartz_Graphics_Driver.H" - -#include <config.h> -#include <FL/Fl.H> -#include <FL/platform.H> -#include <FL/fl_draw.H> - -extern unsigned fl_cmap[256]; // defined in fl_color.cxx - -void Fl_Quartz_Graphics_Driver::color(Fl_Color i) { - Fl_Graphics_Driver::color(i); - uchar r, g, b; - float fa = 1.0f; - if (i & 0xFFFFFF00) { - // translate rgb colors into color index - r = i>>24; - g = i>>16; - b = i>> 8; - } else { - // translate index into rgb: - unsigned c = fl_cmap[i]; - c = c ^ 0x000000ff; // trick to restore the color's correct alpha value - r = c>>24; - g = c>>16; - b = c>> 8; - uchar a = c & 0xff; - //printf("i=%d rgb=%u,%u,%u a=%u\n",i,r,g,b,a); - fa = a/255.0f; - } - if (!gc_) return; // no context yet? We will assign the color later. - float fr = r/255.0f; - float fg = g/255.0f; - float fb = b/255.0f; - CGContextSetRGBFillColor(gc_, fr, fg, fb, fa); - CGContextSetRGBStrokeColor(gc_, fr, fg, fb, fa); -} - -void Fl_Quartz_Graphics_Driver::color(uchar r, uchar g, uchar b) { - Fl_Graphics_Driver::color( fl_rgb_color(r, g, b) ); - float fr = r/255.0f; - float fg = g/255.0f; - float fb = b/255.0f; - if (!gc_) return; // no context yet? We will assign the color later. - CGContextSetRGBFillColor(gc_, fr, fg, fb, 1.0f); - CGContextSetRGBStrokeColor(gc_, fr, fg, fb, 1.0f); -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx deleted file mode 100644 index d373c1768..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_font.cxx +++ /dev/null @@ -1,561 +0,0 @@ -// -// MacOS font selection routines for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2026 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include "Fl_Quartz_Graphics_Driver.H" -#include "Fl_Font.H" -#include <math.h> -#include <FL/Fl.H> -#include <FL/platform.H> -#include <FL/fl_utf8.h> // for fl_utf8toUtf16() -#include <FL/fl_string_functions.h> // fl_strdup() - -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 -const NSUInteger kCTFontOrientationHorizontal = kCTFontHorizontalOrientation; -#endif - -Fl_Fontdesc* fl_fonts = NULL; - -static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; - -static int fl_free_font = FL_FREE_FONT; - - -static CFMutableDictionaryRef attributes = NULL; - -static Fl_Fontdesc built_in_table_PS[] = { // PostScript font names preferred when Mac OS ≥ 10.5 - {"ArialMT"}, - {"Arial-BoldMT"}, - {"Arial-ItalicMT"}, - {"Arial-BoldItalicMT"}, - {"Courier"}, - {"Courier-Bold"}, - {"Courier-Oblique"}, - {"Courier-BoldOblique"}, - {"TimesNewRomanPSMT"}, - {"TimesNewRomanPS-BoldMT"}, - {"TimesNewRomanPS-ItalicMT"}, - {"TimesNewRomanPS-BoldItalicMT"}, - {"Symbol"}, - {"Monaco"}, - {"AndaleMono"}, // there is no bold Monaco font on standard Mac - {"ZapfDingbatsITC"} -}; - - -// Bug: older versions calculated the value for *ap as a side effect of -// making the name, and then forgot about it. To avoid having to change -// the header files I decided to store this value in the last character -// of the font name array. -#define ENDOFBUFFER sizeof(fl_fonts->fontname)-1 - -// turn a stored font name into a pretty name: -const char* Fl_Quartz_Graphics_Driver::get_font_name(Fl_Font fnum, int* ap) { - if (!fl_fonts) fl_fonts = calc_fl_fonts(); - Fl_Fontdesc *f = fl_fonts + fnum; - if (!f->fontname[0]) { - this->set_fontname_in_fontdesc(f); - const char* thisFont = f->name; - if (!thisFont || !*thisFont) {if (ap) *ap = 0; return "";} - int type = 0; - if (strstr(f->name, "Bold")) type |= FL_BOLD; - if (strstr(f->name, "Italic") || strstr(f->name, "Oblique")) type |= FL_ITALIC; - f->fontname[ENDOFBUFFER] = (char)type; - } - if (ap) *ap = f->fontname[ENDOFBUFFER]; - return f->fontname; -} - - -int Fl_Quartz_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) { - static int array[128]; - if (!fl_fonts) fl_fonts = calc_fl_fonts(); - Fl_Fontdesc *s = fl_fonts+fnum; - if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 - int cnt = 0; - - // ATS supports all font size - array[0] = 0; - sizep = array; - cnt = 1; - - return cnt; -} - -Fl_Quartz_Font_Descriptor::Fl_Quartz_Font_Descriptor(const char* name, Fl_Fontsize Size) : Fl_Font_Descriptor(name, Size) { - fontref = NULL; - Fl_Quartz_Graphics_Driver *driver = (Fl_Quartz_Graphics_Driver*)&Fl_Graphics_Driver::default_driver(); - driver->descriptor_init(name, size, this); -} - - -Fl_Quartz_Font_Descriptor::~Fl_Quartz_Font_Descriptor() { -/* -#if HAVE_GL - // ++ todo: remove OpenGL font allocations -// Delete list created by gl_draw(). This is not done by this code -// as it will link in GL unnecessarily. There should be some kind -// of "free" routine pointer, or a subclass? -#endif - */ - if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL); - if (fontref) { - CFRelease(fontref); - for (unsigned i = 0; i < sizeof(width)/sizeof(float*); i++) { - if (width[i]) free(width[i]); - } - } -} - - -static UniChar *utfWbuf = 0; -static unsigned utfWlen = 0; - -static UniChar *mac_Utf8_to_Utf16(const char *txt, int len, int *new_len) -{ - unsigned wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen); - if (wlen >= utfWlen) - { - utfWlen = wlen + 100; - if (utfWbuf) free(utfWbuf); - utfWbuf = (UniChar*)malloc((utfWlen)*sizeof(UniChar)); - wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen); - } - *new_len = wlen; - return utfWbuf; -} - - -static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) { - if (!fl_fonts) fl_fonts = Fl_Graphics_Driver::default_driver().calc_fl_fonts(); - Fl_Fontdesc* s = fl_fonts+fnum; - if (!s->name) s = fl_fonts; // use 0 if fnum undefined - Fl_Font_Descriptor* f; - for (f = s->first; f; f = f->next) - if (f->size == size) return f; - f = new Fl_Quartz_Font_Descriptor(s->name, size); - f->next = s->first; - s->first = f; - return f; -} - - -void Fl_Quartz_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize size) { - if (fnum == -1) { - Fl_Graphics_Driver::font(0, 0); - return; - } - Fl_Graphics_Driver::font(fnum, size); - font_descriptor( find(fnum, size) ); -} - -Fl_Quartz_Font_Descriptor *Fl_Quartz_Graphics_Driver::valid_font_descriptor() { - // avoid a crash if no font has been selected by user yet - if (!font_descriptor()) font(FL_HELVETICA, FL_NORMAL_SIZE); - return (Fl_Quartz_Font_Descriptor*)font_descriptor(); -} - -int Fl_Quartz_Graphics_Driver::height() { - Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor(); - return fl_fontsize->ascent + fl_fontsize->descent; -} - -int Fl_Quartz_Graphics_Driver::descent() { - Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor(); - return fl_fontsize->descent + 1; -} - -void Fl_Quartz_Graphics_Driver::draw(const char* str, int n, int x, int y) { - draw(str, n, (float)x, y+0.5f); -} - -void Fl_Quartz_Graphics_Driver::draw(int angle, const char *str, int n, int x, int y) { - CGContextSaveGState(gc_); - CGContextTranslateCTM(gc_, x, y); - CGContextRotateCTM(gc_, - angle*(M_PI/180) ); - draw(str, n, 0, 0); - CGContextRestoreGState(gc_); -} - -void Fl_Quartz_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) { - int dx, dy, w, h; - text_extents(c, n, dx, dy, w, h); - draw(c, n, x - w - dx, y); -} - -double Fl_Quartz_Graphics_Driver::width(const char* txt, int n) { - if (n == 0) return 0; - int len1 = fl_utf8len1(*txt); - if (len1 > 0 && n > len1) { // a text with several codepoints: compute its typographical width - CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n, kCFStringEncodingUTF8, false); - if (str) { - CFDictionarySetValue(attributes, kCTFontAttributeName, valid_font_descriptor()->fontref); - CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str, attributes); - CFRelease(str); - CTLineRef ctline = CTLineCreateWithAttributedString(mastr); - CFRelease(mastr); - double d = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL); - CFRelease(ctline); - return d; - } - } - int wc_len = n; - UniChar *uniStr = mac_Utf8_to_Utf16(txt, n, &wc_len); - return width(uniStr, wc_len); -} - -double Fl_Quartz_Graphics_Driver::width(unsigned int wc) { - UniChar utf16[3]; - int l = 1; - if (wc <= 0xFFFF) { - *utf16 = wc; - } - else { - l = (int)fl_ucs_to_Utf16(wc, utf16, 3); - } - return width(utf16, l); -} - -void Fl_Quartz_Graphics_Driver::set_fontname_in_fontdesc(Fl_Fontdesc *f) { - CFStringRef cfname = CFStringCreateWithCString(NULL, f->name, kCFStringEncodingUTF8); - CTFontRef ctfont = cfname ? CTFontCreateWithName(cfname, 0, NULL) : NULL; - if (cfname) { CFRelease(cfname); cfname = NULL; } - if (ctfont) { - cfname = CTFontCopyFullName(ctfont); - CFRelease(ctfont); - if (cfname) { - CFStringGetCString(cfname, f->fontname, ENDOFBUFFER, kCFStringEncodingUTF8); - CFRelease(cfname); - } - } - if (!cfname) strlcpy(f->fontname, f->name, ENDOFBUFFER); -} - -const char *Fl_Quartz_Graphics_Driver::font_name(int num) { - if (!fl_fonts) fl_fonts = calc_fl_fonts(); - return fl_fonts[num].name; -} - -void Fl_Quartz_Graphics_Driver::font_name(int num, const char *name) { - Fl_Fontdesc *s = fl_fonts + num; - if (s->name) { - if (!strcmp(s->name, name)) {s->name = name; return;} - for (Fl_Font_Descriptor* f = s->first; f;) { - Fl_Font_Descriptor* n = f->next; delete f; f = n; - } - s->first = 0; - } - s->name = name; - s->fontname[0] = 0; - s->first = 0; -} - - -Fl_Fontdesc* Fl_Quartz_Graphics_Driver::calc_fl_fonts(void) -{ - return built_in_table_PS; -} - - -void Fl_Quartz_Graphics_Driver::descriptor_init(const char* name, - Fl_Fontsize size, Fl_Quartz_Font_Descriptor *d) -{ - CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); - d->fontref = CTFontCreateWithName(str, size, NULL); - CGGlyph glyph[2]; - const UniChar A[2]={'W','.'}; - CTFontGetGlyphsForCharacters(d->fontref, A, glyph, 2); - CGSize advances[2]; - double w; - CTFontGetAdvancesForGlyphs(d->fontref, kCTFontOrientationHorizontal, glyph, advances, 2); - w = advances[0].width; - if ( fabs(advances[0].width - advances[1].width) < 1E-2 ) {//this is a fixed-width font - // slightly rescale fixed-width fonts so the character width has an integral value - CFRelease(d->fontref); - CGFloat fsize = size / ( w/floor(w + 0.5) ); - d->fontref = CTFontCreateWithName(str, fsize, NULL); - w = CTFontGetAdvancesForGlyphs(d->fontref, kCTFontOrientationHorizontal, glyph, NULL, 1); - } - CFRelease(str); - d->ascent = (short)(CTFontGetAscent(d->fontref) + 0.5); - d->descent = (short)(CTFontGetDescent(d->fontref) + 0.5); - d->q_width = w + 0.5; - for (unsigned i = 0; i < sizeof(d->width)/sizeof(float*); i++) d->width[i] = NULL; - if (!attributes) { - static CFNumberRef zero_ref; - float zero = 0.; - zero_ref = CFNumberCreate(NULL, kCFNumberFloat32Type, &zero); - // deactivate kerning for all fonts, so that string width = sum of character widths - // which allows fast fl_width() implementation. - attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, - 3, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue (attributes, kCTKernAttributeName, zero_ref); - } - if (d->ascent == 0) { // this may happen with some third party fonts - CFDictionarySetValue (attributes, kCTFontAttributeName, d->fontref); - CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, CFSTR("Wj"), attributes); - CTLineRef ctline = CTLineCreateWithAttributedString(mastr); - CFRelease(mastr); - CGFloat fascent, fdescent; - CTLineGetTypographicBounds(ctline, &fascent, &fdescent, NULL); - CFRelease(ctline); - d->ascent = (short)(fascent + 0.5); - d->descent = (short)(fdescent + 0.5); - } -} - -// returns width of a pair of UniChar's in the surrogate range -static CGFloat surrogate_width(const UniChar *txt, Fl_Quartz_Font_Descriptor *fl_fontsize) -{ - CTFontRef font2 = fl_fontsize->fontref; - bool must_release = false; - CGGlyph glyphs[2]; - bool b = CTFontGetGlyphsForCharacters(font2, txt, glyphs, 2); - CGSize a; - if(!b) { // the current font doesn't contain this char - CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, txt, 2, kCFAllocatorNull); - // find a font that contains it - font2 = CTFontCreateForString(font2, str, CFRangeMake(0,2)); - must_release = true; - CFRelease(str); - b = CTFontGetGlyphsForCharacters(font2, txt, glyphs, 2); - } - if (b) CTFontGetAdvancesForGlyphs(font2, kCTFontOrientationHorizontal, glyphs, &a, 1); - else a.width = fl_fontsize->q_width; - if(must_release) CFRelease(font2); - return a.width; -} - -static CGFloat variation_selector_width(CFStringRef str16, Fl_Quartz_Font_Descriptor *fl_fontsize) -{ - CGFloat retval; - CFDictionarySetValue(attributes, kCTFontAttributeName, fl_fontsize->fontref); - CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes); - CTLineRef ctline = CTLineCreateWithAttributedString(mastr); - CFRelease(mastr); - retval = CTLineGetOffsetForStringIndex(ctline, 2, NULL); - CFRelease(ctline); - return retval; -} - -double Fl_Quartz_Graphics_Driver::width(const UniChar* txt, int n) -{ - double retval = 0; - UniChar uni; - int i; - Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor(); - for (i = 0; i < n; i++) { // loop over txt - uni = txt[i]; - if (uni >= 0xD800 && uni <= 0xDBFF) { // handles the surrogate range - retval += surrogate_width(&txt[i], fl_fontsize); - i++; // because a pair of UniChar's represent a single character - continue; - } - if (i+1 < n && txt[i+1] >= 0xFE00 && txt[i+1] <= 0xFE0F) { // handles variation selectors - CFStringRef substr = CFStringCreateWithCharacters(NULL, txt + i, 2); - retval += variation_selector_width(substr, fl_fontsize); - CFRelease(substr); - i++; - continue; - } - const int block = 0x10000 / (sizeof(fl_fontsize->width)/sizeof(float*)); // block size - // r: index of the character block containing uni - unsigned int r = uni >> 7; // change 7 if sizeof(width) is changed - if (!fl_fontsize->width[r]) { // this character block has not been hit yet - //fprintf(stderr,"r=%d size=%d name=%s\n",r,fl_fontsize->size,fl_fonts[fl_font()].name); - // allocate memory to hold width of each character in the block - fl_fontsize->width[r] = (float*) malloc(sizeof(float) * block); - UniChar ii = r * block; - CGSize advance_size; - CGGlyph glyph; - for (int j = 0; j < block; j++) { // loop over the block - // ii spans all characters of this block - bool b = CTFontGetGlyphsForCharacters(fl_fontsize->fontref, &ii, &glyph, 1); - if (b) - CTFontGetAdvancesForGlyphs(fl_fontsize->fontref, kCTFontOrientationHorizontal, &glyph, &advance_size, 1); - else - advance_size.width = -1e9; // calculate this later - // the width of one character of this block of characters - fl_fontsize->width[r][j] = advance_size.width; - ii++; - } - } - // sum the widths of all characters of txt - double wdt = fl_fontsize->width[r][uni & (block-1)]; - if (wdt == -1e9) { - CGSize advance_size; - CGGlyph glyph; - CTFontRef font2 = fl_fontsize->fontref; - bool must_release = false; - bool b = CTFontGetGlyphsForCharacters(font2, &uni, &glyph, 1); - if (!b) { // the current font doesn't contain this char - CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, &uni, 1, kCFAllocatorNull); - // find a font that contains it - font2 = CTFontCreateForString(font2, str, CFRangeMake(0,1)); - must_release = true; - CFRelease(str); - b = CTFontGetGlyphsForCharacters(font2, &uni, &glyph, 1); - } - if (b) CTFontGetAdvancesForGlyphs(font2, kCTFontOrientationHorizontal, &glyph, &advance_size, 1); - else advance_size.width = 0.; - // the width of the 'uni' character - wdt = fl_fontsize->width[r][uni & (block-1)] = advance_size.width; - if (must_release) CFRelease(font2); - } - retval += wdt; - } - return retval; -} - - -// text extent calculation -void Fl_Quartz_Graphics_Driver::text_extents(const char *str8, int n, - int &dx, int &dy, int &w, int &h) { - Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor(); - UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n); - CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, txt, n, kCFAllocatorNull); - CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref); - CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes); - CFRelease(str16); - CTLineRef ctline = CTLineCreateWithAttributedString(mastr); - CFRelease(mastr); - CGContextSetTextPosition(gc_, 0, 0); - CGContextSetShouldAntialias(gc_, true); - CGRect rect = CTLineGetImageBounds(ctline, gc_); - CGContextSetShouldAntialias(gc_, false); - CFRelease(ctline); - dx = floor(rect.origin.x + 0.5); - dy = floor(- rect.origin.y - rect.size.height + 0.5); - w = rect.size.width + 0.5; - h = rect.size.height + 0.5; -} - - -static CGColorRef flcolortocgcolor(Fl_Color i) -{ - uchar r, g, b; - Fl::get_color(i, r, g, b); - CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.}; - static CGColorSpaceRef cspace = NULL; - if (cspace == NULL) { - cspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); - } - return CGColorCreate(cspace, components); -} - -void Fl_Quartz_Graphics_Driver::draw(const char *str, int n, float x, float y) -{ - Fl_Quartz_Font_Descriptor *fl_fontsize = valid_font_descriptor(); - // convert to UTF-16 first - UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); - CGContextRef gc = (CGContextRef)this->gc(); - CFMutableStringRef str16 = CFStringCreateMutableWithExternalCharactersNoCopy(NULL, uniStr, n, n, kCFAllocatorNull); - if (str16 == NULL) return; // shd not happen - CGColorRef color = flcolortocgcolor(this->color()); - CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref); - CFDictionarySetValue (attributes, kCTForegroundColorAttributeName, color); - CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes); - CFRelease(str16); - CFRelease(color); - CTLineRef ctline = CTLineCreateWithAttributedString(mastr); - CFRelease(mastr); - CGContextSetTextMatrix(gc, font_mx); - CGContextSetTextPosition(gc, x, y); - CGContextSetShouldAntialias(gc, true); - CTLineDraw(ctline, gc); - CGContextSetShouldAntialias(gc, false); - CFRelease(ctline); -} - -// Skip over bold/italic/oblique qualifiers part of PostScript font names -// Example: -// input: '-Regular_Light-Condensed' -// return: '_Light-Condensed' -// -static char *skip(char *p, int& derived) -{ - // 0 5 10 - // | | | - if (strncmp(p, "-BoldItalic", 11) == 0) { p += 11; derived = 3; } - else if (strncmp(p, "-BoldOblique", 12) == 0) { p += 12; derived = 3; } - else if (strncmp(p, "-Bold", 5) == 0) { p += 5; derived = 1; } - else if (strncmp(p, "-Italic", 7) == 0) { p += 7; derived = 2; } - else if (strncmp(p, "-Oblique", 8) == 0) { p += 8; derived = 2; } - else if (strncmp(p, "-Regular", 8) == 0) { p += 8; } - else if (strncmp(p, "-Roman", 6) == 0) { p += 6; } - return p; -} - -static int name_compare(const void *a, const void *b) -{ - /* Compare PostScript font names. - First compare font family names ignoring bold, italic and oblique qualifiers. - When families are identical, order them according to regular, bold, italic, bolditalic. - */ - char *n1 = *(char**)a; - char *n2 = *(char**)b; - int derived1 = 0; - int derived2 = 0; - while (true) { - if (*n1 == '-') n1 = skip(n1, derived1); - if (*n2 == '-') n2 = skip(n2, derived2); - if (*n1 < *n2) return -1; - if (*n1 > *n2) return +1; - if (*n1 == 0) { - return derived1 - derived2; - } - n1++; n2++; - } -} - -Fl_Font Fl_Quartz_Graphics_Driver::set_fonts(const char* xstarname) -{ -#pragma unused ( xstarname ) - if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called - - int value[1] = {1}; - CFDictionaryRef dict = CFDictionaryCreate(NULL, - (const void **)kCTFontCollectionRemoveDuplicatesOption, - (const void **)&value, 1, NULL, NULL); - CTFontCollectionRef fcref = CTFontCollectionCreateFromAvailableFonts(dict); - CFRelease(dict); - CFArrayRef arrayref = CTFontCollectionCreateMatchingFontDescriptors(fcref); - CFRelease(fcref); - CFIndex count = CFArrayGetCount(arrayref); - CFIndex i; - char **tabfontnames = new char*[count]; - for (i = 0; i < count; i++) { - CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i); - CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL); - CFStringRef cfname = CTFontCopyPostScriptName(font); - CFRelease(font); - CFDataRef cfdata = CFStringCreateExternalRepresentation(NULL, cfname, kCFStringEncodingUTF8, '?'); - CFIndex l = CFDataGetLength(cfdata); - tabfontnames[i] = (char*)malloc(l+1); // never free'ed - memcpy(tabfontnames[i], CFDataGetBytePtr(cfdata), l); - tabfontnames[i][l] = 0; - CFRelease(cfdata); - CFRelease(cfname); - } - CFRelease(arrayref); - qsort(tabfontnames, count, sizeof(char*), name_compare); - for (i = 0; i < count; i++) { - Fl::set_font((Fl_Font)(fl_free_font++), tabfontnames[i]); - } - delete[] tabfontnames; - return (Fl_Font)fl_free_font; -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx deleted file mode 100644 index 932ef7d82..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_image.cxx +++ /dev/null @@ -1,284 +0,0 @@ -// -// MacOS image drawing code for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2018 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include <config.h> -#include "Fl_Quartz_Graphics_Driver.H" -#include <FL/Fl.H> -#include <FL/fl_draw.H> -#include <FL/platform.H> -#include <FL/Fl_Image_Surface.H> - -#define MAXBUFFER 0x40000 // 256k - -static void dataReleaseCB(void *info, const void *data, size_t size) -{ - delete[] (uchar *)data; -} - -/* - draw an image based on the input parameters - - buf: image source data - X, Y: position (in buffer?!) - W, H: size of picture (in pixel?) - delta: distance from pixel to pixel in buf in bytes - linedelta: distance from line to line in buf in bytes - mono: if set, pixel is one byte - if zero, pixel is 3 byte - cb: callback to copy image data into (RGB?) buffer - buf: pointer to first byte in image source - x, y: position in buffer - w: width (in bytes?) - dst: destination buffer - userdata: ? - */ -static void innards(const uchar *buf, int X, int Y, int W, int H, - int delta, int linedelta, int mono, - Fl_Draw_Image_Cb cb, void* userdata, CGContextRef gc, Fl_Quartz_Graphics_Driver *driver) -{ - if (!linedelta) linedelta = W*abs(delta); - - uchar *tmpBuf = 0; - if (!cb) { - if (delta < 0) buf -= (W-1)*(-delta); - if (linedelta < 0) buf -= (H-1)*abs(linedelta); - } - const void *array = buf; - if (cb || driver->has_feature(Fl_Quartz_Graphics_Driver::PRINTER)) { - tmpBuf = new uchar[ H*W*abs(delta) ]; - if (cb) { - for (int i=0; i<H; i++) { - cb(userdata, 0, i, W, tmpBuf+i*W*abs(delta)); - } - } else { - uchar *p = tmpBuf; - for (int i=0; i<H; i++) { - memcpy(p, buf+i*abs(linedelta), W*abs(delta)); - p += W*abs(delta); - } - } - array = (void*)tmpBuf; - linedelta = W*abs(delta); - } - // create an image context - CGColorSpaceRef lut = 0; - if (abs(delta)<=2) - lut = CGColorSpaceCreateDeviceGray(); - else - lut = CGColorSpaceCreateDeviceRGB(); - // a release callback is necessary when the gc is a print context because the image data - // must be kept until the page is closed. Thus tmpBuf can't be deleted here. It's too early. - CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, abs(linedelta)*H, - tmpBuf ? dataReleaseCB : NULL - ); - CGImageRef img = CGImageCreate( W, H, 8, 8*abs(delta), abs(linedelta), - lut, abs(delta)&1?kCGImageAlphaNone:kCGImageAlphaLast, - src, 0L, false, kCGRenderingIntentDefault); - CGColorSpaceRelease(lut); - CGDataProviderRelease(src); - // draw the image into the destination context - if (img) { - CGContextSaveGState(gc); - CGContextTranslateCTM(gc, X, Y); - if (linedelta < 0) { - CGContextTranslateCTM(gc, 0, H-1); - CGContextScaleCTM(gc, 1, -1); - } - if (delta < 0) { - CGContextTranslateCTM(gc, W-1, 0); - CGContextScaleCTM(gc, -1, 1); - } - driver->draw_CGImage(img, 0,0,W,H, 0,0,W,H); - CGImageRelease(img); - CGContextRestoreGState(gc); - } -} - -void Fl_Quartz_Graphics_Driver::draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ - d &= ~FL_IMAGE_WITH_ALPHA; - innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0,gc_,this); -} -void Fl_Quartz_Graphics_Driver::draw_image(Fl_Draw_Image_Cb cb, void* data, - int x, int y, int w, int h,int d) { - innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data,gc_,this); -} -void Fl_Quartz_Graphics_Driver::draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ - innards(buf,x,y,w,h,d,l,1,0,0,gc_,this); -} -void Fl_Quartz_Graphics_Driver::draw_image_mono(Fl_Draw_Image_Cb cb, void* data, - int x, int y, int w, int h,int d) { - innards(0,x,y,w,h,d,0,1,cb,data,gc_,this); -} - - -void Fl_Quartz_Graphics_Driver::draw_bitmap(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) { - int X, Y, W, H; - if (!bm->array) { - draw_empty(bm, XP, YP); - return; - } - if (start_image(bm, XP,YP,WP,HP,cx,cy,X,Y,W,H)) return; - if (!*id(bm)) - cache(bm); - - if (*Fl_Graphics_Driver::id(bm) && gc_) { - draw_CGImage((CGImageRef)*Fl_Graphics_Driver::id(bm), X,Y,W,H, cx, cy, bm->w(), bm->h()); - } -} - -void Fl_Quartz_Graphics_Driver::cache(Fl_RGB_Image *rgb) { - CGColorSpaceRef lut = rgb->d()<=2 ? CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB(); - int ld = rgb->ld(); - if (!ld) ld = rgb->data_w() * rgb->d(); - CGDataProviderRef src; - if ( has_feature(PRINTER) ) { - // When printing or copying to clipboard, the data at rgb->array are used when - // the PDF page is completed, that is, after return from this function. - // At that stage, the rgb object has possibly been deleted. It is therefore necessary - // to use a copy of rgb->array. The mask_ member of rgb - // is used to avoid repeating the copy operation if rgb is drawn again. - // The CGImage data provider deletes the copy at the latest of these two events: - // deletion of rgb, and completion of the PDF page where rgb was drawn. - size_t total = ld * rgb->data_h(); - uchar *copy = new uchar[total]; - memcpy(copy, rgb->array, total); - src = CGDataProviderCreateWithData(NULL, copy, total, dataReleaseCB); - *Fl_Graphics_Driver::mask(rgb) = 1; - } else { - // the CGImage data provider must not release the image data. - src = CGDataProviderCreateWithData(NULL, rgb->array, ld * rgb->data_h(), NULL); - } - CGImageRef cgimg = CGImageCreate(rgb->data_w(), rgb->data_h(), 8, rgb->d()*8, ld, - lut, (rgb->d()&1)?kCGImageAlphaNone:kCGImageAlphaLast, - src, 0L, false, kCGRenderingIntentDefault); - *Fl_Graphics_Driver::id(rgb) = (fl_uintptr_t)cgimg; - CGColorSpaceRelease(lut); - CGDataProviderRelease(src); -} - -void Fl_Quartz_Graphics_Driver::draw_rgb(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) { - int X, Y, W, H; - // Don't draw an empty image... - if (!img->d() || !img->array) { - Fl_Graphics_Driver::draw_empty(img, XP, YP); - return; - } - if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) { - return; - } - CGImageRef cgimg = (CGImageRef)*Fl_Graphics_Driver::id(img); - if (cgimg && has_feature(PRINTER) && !*Fl_Graphics_Driver::mask(img)) { - CGImageRelease(cgimg); - *Fl_Graphics_Driver::id(img) = 0; - cgimg = NULL; - } - if (!cgimg) { - cache(img); - cgimg = (CGImageRef)*Fl_Graphics_Driver::id(img); - } - if (cgimg && gc_) { - draw_CGImage(cgimg, X,Y,W,H, cx,cy, img->w(), img->h()); - } -} - -void Fl_Quartz_Graphics_Driver::draw_pixmap(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) { - int X, Y, W, H; - if (!pxm->data() || !pxm->w()) { - draw_empty(pxm, XP, YP); - return; - } - if ( start_image(pxm, XP,YP,WP,HP,cx,cy,X,Y,W,H) ) return; - if (!*id(pxm)) { - cache(pxm); - } - - CGImageRef cgimg = (CGImageRef)*Fl_Graphics_Driver::id(pxm); - draw_CGImage(cgimg, X,Y,W,H, cx,cy, pxm->w(), pxm->h()); -} - -CGImageRef Fl_Quartz_Graphics_Driver::create_bitmask(int w, int h, const uchar *array) { - 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 = new uchar[rowBytes*h]; - uchar *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; - } - CGDataProviderRef srcp = CGDataProviderCreateWithData( NULL, bmask, rowBytes*h, dataReleaseCB); - CGImageRef id_ = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false); - CGDataProviderRelease(srcp); - return id_; -} - -void Fl_Quartz_Graphics_Driver::delete_bitmask(fl_uintptr_t bm) { - if (bm) CGImageRelease((CGImageRef)bm); -} - -void Fl_Quartz_Graphics_Driver::uncache(Fl_RGB_Image*, fl_uintptr_t &id_, fl_uintptr_t &mask_) { - if (id_) { - CGImageRelease((CGImageRef)id_); - id_ = 0; - mask_ = 0; - } -} - -void Fl_Quartz_Graphics_Driver::cache(Fl_Bitmap *bm) { - *Fl_Graphics_Driver::id(bm) = (fl_uintptr_t)create_bitmask(bm->data_w(), bm->data_h(), bm->array); -} - - -static void pmProviderRelease (void *ctxt, const void *data, size_t size) { - CFRelease(ctxt); -} - -void Fl_Quartz_Graphics_Driver::cache(Fl_Pixmap *img) { - Fl_Image_Surface *surf = new Fl_Image_Surface(img->data_w(), img->data_h()); - Fl_Surface_Device::push_current(surf); - fl_draw_pixmap(img->data(), 0, 0, FL_BLACK); - Fl_Surface_Device::pop_current(); - CGContextRef src = (CGContextRef)Fl_Graphics_Driver::get_offscreen_and_delete_image_surface(surf); - void *cgdata = CGBitmapContextGetData(src); - int sw = (int)CGBitmapContextGetWidth(src); - int sh = (int)CGBitmapContextGetHeight(src); - CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src); - CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); - CGDataProviderRef src_bytes = CGDataProviderCreateWithData(src, cgdata, sw*sh*4, pmProviderRelease); - CGImageRef cgimg = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha, - src_bytes, 0L, false, kCGRenderingIntentDefault); - CGColorSpaceRelease(lut); - CGDataProviderRelease(src_bytes); - *Fl_Graphics_Driver::id(img) = (fl_uintptr_t)cgimg; -} - -void Fl_Quartz_Graphics_Driver::draw_CGImage(CGImageRef cgimg, int x, int y, int w, int h, int srcx, int srcy, int sw, int sh) -{ - CGRect rect = CGRectMake(x, y, w, h); - CGContextSaveGState(gc_); - CGContextClipToRect(gc_, CGRectOffset(rect, -0.5, -0.5 )); - // move graphics context to origin of vertically reversed image - // The 0.5 here cancels the 0.5 offset present in Quartz graphics contexts. - // Thus, image and surface pixels are in phase. - CGContextTranslateCTM(gc_, rect.origin.x - srcx - 0.5, rect.origin.y - srcy + sh - 0.5); - CGContextScaleCTM(gc_, 1, -1); - CGContextDrawImage(gc_, CGRectMake(0, 0, sw, sh), cgimg); - CGContextRestoreGState(gc_); -} - -void Fl_Quartz_Graphics_Driver::uncache_pixmap(fl_uintptr_t pixmap_ref) { - CGImageRelease((CGImageRef)pixmap_ref); -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx deleted file mode 100644 index 6a63ae483..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_line_style.cxx +++ /dev/null @@ -1,83 +0,0 @@ -// -// Line style code for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2018 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include <FL/fl_draw.H> -#include <FL/platform.H> - - -/** - \file quartz_line_style.cxx - \brief Line style drawing utility hiding different platforms. -*/ - -#include "Fl_Quartz_Graphics_Driver.H" - -void Fl_Quartz_Graphics_Driver::quartz_restore_line_style() { - CGContextSetLineWidth(gc_, quartz_line_width_); - CGContextSetLineCap(gc_, quartz_line_cap_); - CGContextSetLineJoin(gc_, quartz_line_join_); - CGContextSetLineDash(gc_, 0, quartz_line_pattern, quartz_line_pattern_size); -} - -void Fl_Quartz_Graphics_Driver::line_style(int style, int width, char* dashes) { - - static CGLineCap Cap[4] = { kCGLineCapButt, kCGLineCapButt, - kCGLineCapRound, kCGLineCapSquare }; - static CGLineJoin Join[4] = { kCGLineJoinMiter, kCGLineJoinMiter, - kCGLineJoinRound, kCGLineJoinBevel }; - if (width<1) width = 1; - quartz_line_width_ = (float)width; - quartz_line_cap_ = Cap[(style>>8)&3]; - // when printing kCGLineCapSquare seems better for solid lines - if ( Fl_Surface_Device::surface() != Fl_Display_Device::display_device() - && style == FL_SOLID && dashes == NULL ) - { - quartz_line_cap_ = kCGLineCapSquare; - } - quartz_line_join_ = Join[(style>>12)&3]; - char *d = dashes; - static CGFloat pattern[16]; - if (d && *d) { - CGFloat *pDst = pattern; - while (*d) { *pDst++ = (float)*d++; } - quartz_line_pattern = pattern; - quartz_line_pattern_size = (int)(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); - } - CGFloat *pDst = pattern; - switch (style & 0xff) { - case FL_DASH: *pDst++ = dash; *pDst++ = gap; break; - case FL_DOT: *pDst++ = dot; *pDst++ = gap; break; - case FL_DASHDOT: *pDst++ = dash; *pDst++ = gap; *pDst++ = dot; *pDst++ = gap; break; - case FL_DASHDOTDOT: *pDst++ = dash; *pDst++ = gap; *pDst++ = dot; *pDst++ = gap; *pDst++ = dot; *pDst++ = gap; break; - } - quartz_line_pattern_size = (int)(pDst-pattern); - quartz_line_pattern = pattern; - } else { - quartz_line_pattern = 0; - quartz_line_pattern_size = 0; - } - quartz_restore_line_style(); -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx deleted file mode 100644 index 234853ad6..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_rect.cxx +++ /dev/null @@ -1,310 +0,0 @@ -// -// Rectangle drawing routines for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2018 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - - -#include <FL/Fl.H> -#include <FL/platform.H> -#include <math.h> - - -/** - \file quartz_rect.cxx - \brief Apple Quartz specific line and polygon drawing with integer coordinates. -*/ - - -#include "Fl_Quartz_Graphics_Driver.H" - - -// --- line and polygon drawing with integer coordinates - -void Fl_Quartz_Graphics_Driver::point(int x, int y) { - CGContextFillRect(gc_, CGRectMake(x - 0.5, y - 0.5, 1, 1) ); -} - -void Fl_Quartz_Graphics_Driver::rect(int x, int y, int w, int h) { - if (w<=0 || h<=0) return; - double offset = (quartz_line_width_ >= 2 ? quartz_line_width_/4 : 0); - CGRect rect = CGRectMake(x - offset, y - offset, w-1, h-1); - CGContextStrokeRect(gc_, rect); -} - -void Fl_Quartz_Graphics_Driver::focus_rect(int x, int y, int w, int h) -{ - CGContextSaveGState(gc_); - float s = scale(); - CGContextScaleCTM(gc_, 1/s, 1/s); - CGFloat lw = (s >= 1 ? floor(s) : 1); - CGContextSetLineWidth(gc_, lw); - CGFloat dots[2] = {lw, lw}; - CGContextSetLineDash(gc_, 0, dots, 2); - CGContextStrokeRect(gc_, CGRectMake(x*s, y*s, (w-1)*s, (h-1)*s)); - CGContextRestoreGState(gc_); -} - -void Fl_Quartz_Graphics_Driver::rectf(int x, int y, int w, int h) { - if (w<=0 || h<=0) return; - CGRect rect = CGRectMake(x - 0.5, y - 0.5, w , h); - CGContextFillRect(gc_, rect); -} - -void Fl_Quartz_Graphics_Driver::line(int x, int y, int x1, int y1) { - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y1); - CGContextStrokePath(gc_); - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::line(int x, int y, int x1, int y1, int x2, int y2) { - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y1); - CGContextAddLineToPoint(gc_, x2, y2); - CGContextStrokePath(gc_); - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::xyline(int x, int y, int x1) { - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y); - CGContextStrokePath(gc_); - if (high_resolution() || scale()>=2) { - /* On retina displays, all xyline() and yxline() functions produce lines that are half-unit - (or one pixel) too short at both ends. This is corrected by filling at both ends rectangles - of size one unit by line-width. - */ - CGContextFillRect(gc_, CGRectMake(x-0.5 , y - quartz_line_width_/2, 1 , quartz_line_width_)); - CGContextFillRect(gc_, CGRectMake(x1-0.5 , y - quartz_line_width_/2, 1 , quartz_line_width_)); - } - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::xyline(int x, int y, int x1, int y2) { - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y); - CGContextAddLineToPoint(gc_, x1, y2); - CGContextStrokePath(gc_); - if (high_resolution() || scale()>=2) { - CGContextFillRect(gc_, CGRectMake(x-0.5, y - quartz_line_width_/2, 1 , quartz_line_width_)); - CGContextFillRect(gc_, CGRectMake(x1 - quartz_line_width_/2, y2-0.5, quartz_line_width_, 1)); - } - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) { - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y); - CGContextAddLineToPoint(gc_, x1, y2); - CGContextAddLineToPoint(gc_, x3, y2); - CGContextStrokePath(gc_); - if (high_resolution() || scale()>=2) { - CGContextFillRect(gc_, CGRectMake(x-0.5, y - quartz_line_width_/2, 1 , quartz_line_width_)); - CGContextFillRect(gc_, CGRectMake(x3-0.5, y2 - quartz_line_width_/2, 1 , quartz_line_width_)); - } - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::yxline(int x, int y, int y1) { - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x, y1); - CGContextStrokePath(gc_); - if (high_resolution() || scale()>=2) { - CGContextFillRect(gc_, CGRectMake(x - quartz_line_width_/2, y-0.5, quartz_line_width_, 1)); - CGContextFillRect(gc_, CGRectMake(x - quartz_line_width_/2, y1-0.5, quartz_line_width_, 1)); - } - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::yxline(int x, int y, int y1, int x2) { - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x, y1); - CGContextAddLineToPoint(gc_, x2, y1); - CGContextStrokePath(gc_); - if (high_resolution() || scale()>=2) { - CGContextFillRect(gc_, CGRectMake(x - quartz_line_width_/2, y-0.5, quartz_line_width_, 1)); - CGContextFillRect(gc_, CGRectMake(x2-0.5, y1 - quartz_line_width_/2, 1 , quartz_line_width_)); - } - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) { - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x, y1); - CGContextAddLineToPoint(gc_, x2, y1); - CGContextAddLineToPoint(gc_, x2, y3); - CGContextStrokePath(gc_); - if (high_resolution() || scale()>=2) { - CGContextFillRect(gc_, CGRectMake(x - quartz_line_width_/2, y-0.5, quartz_line_width_, 1)); - CGContextFillRect(gc_, CGRectMake(x2 - quartz_line_width_/2, y3-0.5, quartz_line_width_, 1)); - } - if (has_feature(PRINTER) || quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2) { - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y1); - CGContextAddLineToPoint(gc_, x2, y2); - CGContextClosePath(gc_); - CGContextStrokePath(gc_); - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y1); - CGContextAddLineToPoint(gc_, x2, y2); - CGContextAddLineToPoint(gc_, x3, y3); - CGContextClosePath(gc_); - CGContextStrokePath(gc_); - if (quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::overlay_rect(int x, int y, int w , int h) { - float s = scale(); if (s < 2) s = 0; - CGContextSetLineWidth(gc_, 0.05); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x+w-1 +s/8, y); - CGContextAddLineToPoint(gc_, x+w-1 +s/8, y+h-1 -s/8); - CGContextAddLineToPoint(gc_, x, y+h-1 -s/8); - CGContextClosePath(gc_); - CGContextStrokePath(gc_); - CGContextSetLineWidth(gc_, quartz_line_width_); -} - -void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2) { - CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y1); - CGContextAddLineToPoint(gc_, x2, y2); - CGContextClosePath(gc_); - CGContextFillPath(gc_); - CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) { - CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, x, y); - CGContextAddLineToPoint(gc_, x1, y1); - CGContextAddLineToPoint(gc_, x2, y2); - CGContextAddLineToPoint(gc_, x3, y3); - CGContextClosePath(gc_); - CGContextFillPath(gc_); - CGContextSetShouldAntialias(gc_, false); -} - -// --- clipping - -// intersects current and x,y,w,h rectangle and returns result as a new Fl_Region -static Fl_Region intersect_region_and_rect(Fl_Region current_, int x,int y,int w, int h) -{ - if (current_ == NULL) return Fl_Graphics_Driver::default_driver().XRectangleRegion(x,y,w,h); - struct flCocoaRegion* current = (struct flCocoaRegion*)current_; - CGRect r = Fl_Quartz_Graphics_Driver::fl_cgrectmake_cocoa(x, y, w, h); - struct flCocoaRegion* outr = (struct flCocoaRegion*)malloc(sizeof(struct flCocoaRegion)); - outr->count = current->count; - outr->rects =(CGRect*)malloc(outr->count * sizeof(CGRect)); - int j = 0; - for(int i = 0; i < current->count; i++) { - CGRect test = CGRectIntersection(current->rects[i], r); - if (!CGRectIsEmpty(test)) outr->rects[j++] = test; - } - if (j) { - outr->count = j; - outr->rects = (CGRect*)realloc(outr->rects, outr->count * sizeof(CGRect)); - } - else { - Fl_Graphics_Driver::default_driver().XDestroyRegion(outr); - outr = (struct flCocoaRegion*)Fl_Graphics_Driver::default_driver().XRectangleRegion(0,0,0,0); - } - return outr; -} - - -void Fl_Quartz_Graphics_Driver::push_clip(int x, int y, int w, int h) { - Fl_Region r; - if (w > 0 && h > 0) { - r = XRectangleRegion(x,y,w,h); - Fl_Region current = rstack[rstackptr]; - if (current) { - XDestroyRegion(r); - r = intersect_region_and_rect(current, x,y,w,h); - } - } else { // make empty clip region: - r = XRectangleRegion(0,0,0,0); - } - if (rstackptr < region_stack_max) rstack[++rstackptr] = r; - else Fl::warning("Fl_Quartz_Graphics_Driver::push_clip: clip stack overflow!\n"); - restore_clip(); -} - -int Fl_Quartz_Graphics_Driver::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; - struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; - if (!r) return 0; - CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); - CGRect u = CGRectMake(0,0,0,0); - CGRect test; - for (int i = 0; i < r->count; i++) { - test = CGRectIntersection(r->rects[i], arg); - if ( !CGRectIsEmpty(test) ) { - if(CGRectIsEmpty(u)) u = test; - else u = CGRectUnion(u, test); - } - } - X = int(u.origin.x + 0.5); // reverse offset introduced by fl_cgrectmake_cocoa() - Y = int(u.origin.y + 0.5); - W = int(u.size.width + 0.5); // round to nearest integer - H = int(u.size.height + 0.5); - if (CGRectIsEmpty(u)) W = H = 0; - return !CGRectEqualToRect(arg, u); -} - -int Fl_Quartz_Graphics_Driver::not_clipped(int x, int y, int w, int h) { - if (x+w <= 0 || y+h <= 0) return 0; - struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; - if (!r) return 1; - CGRect arg = fl_cgrectmake_cocoa(x, y, w, h); - for (int i = 0; i < r->count; i++) { - CGRect test = CGRectIntersection(r->rects[i], arg); - if (!CGRectIsEmpty(test)) return 1; - } - return 0; -} - -void Fl_Quartz_Graphics_Driver::restore_clip() { - fl_clip_state_number++; - struct flCocoaRegion* r = (struct flCocoaRegion*)rstack[rstackptr]; - if ( fl_window || gc_ ) { // clipping for a true window or an offscreen buffer - if (gc_) { - CGContextRestoreGState(gc_); - CGContextSaveGState(gc_); - } - color(color()); - quartz_restore_line_style(); - if (r) { //apply program clip - CGContextClipToRects(gc_, r->rects, r->count); - } - } -} diff --git a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx b/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx deleted file mode 100644 index 16c6c6c29..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Graphics_Driver_vertex.cxx +++ /dev/null @@ -1,98 +0,0 @@ -// -// Portable drawing routines for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2022 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -/** - \file quartz_vertex.cxx - \brief Portable drawing code for drawing arbitrary shapes with - simple 2D transformations, implemented for OS X Quartz. -*/ - -#include "Fl_Quartz_Graphics_Driver.H" - -#include <FL/fl_draw.H> -#include <FL/platform.H> -#include <FL/math.h> - - -void Fl_Quartz_Graphics_Driver::end_points() { - for (int i = 0; i < n; i++) { - point(xpoint[i].x, xpoint[i].y); - } -} - -void Fl_Quartz_Graphics_Driver::end_line() { - if (n < 2) { - end_points(); - return; - } - if (n<=1) return; - CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, xpoint[0].x, xpoint[0].y); - for (int i=1; i<n; i++) - CGContextAddLineToPoint(gc_, xpoint[i].x, xpoint[i].y); - CGContextStrokePath(gc_); - CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::end_polygon() { - fixloop(); - if (n < 3) { - end_line(); - return; - } - if (n<=1) return; - CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, xpoint[0].x, xpoint[0].y); - for (int i=1; i<n; i++) - CGContextAddLineToPoint(gc_, xpoint[i].x, xpoint[i].y); - CGContextClosePath(gc_); - CGContextFillPath(gc_); - CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::end_complex_polygon() { - gap(); - if (n < 3) { - end_line(); - return; - } - if (n<=1) return; - CGContextSetShouldAntialias(gc_, true); - CGContextMoveToPoint(gc_, xpoint[0].x, xpoint[0].y); - for (int i=1; i<n; i++) - CGContextAddLineToPoint(gc_, xpoint[i].x, xpoint[i].y); - CGContextClosePath(gc_); - CGContextFillPath(gc_); - CGContextSetShouldAntialias(gc_, false); -} - -void Fl_Quartz_Graphics_Driver::circle(double x, double y,double r) { - double xt = transform_x(x,y); - double yt = transform_y(x,y); - double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a)); - double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d)); - int llx = (int)rint(xt-rx); - int w = (int)rint(xt+rx)-llx; - int lly = (int)rint(yt-ry); - int h = (int)rint(yt+ry)-lly; - - // Quartz warning: circle won't scale to current matrix! - // Last argument must be 0 (counter-clockwise) or it draws nothing under __LP64__ !!!! - CGContextSetShouldAntialias(gc_, true); - CGContextAddArc(gc_, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 0); - (what == POLYGON ? CGContextFillPath : CGContextStrokePath)(gc_); - CGContextSetShouldAntialias(gc_, false); -} diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H deleted file mode 100644 index 3849ea4df..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.H +++ /dev/null @@ -1,38 +0,0 @@ -// -// Draw-to-image code for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2026 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#ifndef FL_QUARTZ_IMAGE_SURFACE_DRIVER_H -#define FL_QUARTZ_IMAGE_SURFACE_DRIVER_H - -#include <FL/Fl_Image_Surface.H> -#include <FL/platform.H> - -class Fl_Quartz_Image_Surface_Driver : public Fl_Image_Surface_Driver { -private: - CGImageRef mask_; - void mask(const Fl_RGB_Image *) FL_OVERRIDE; - void end_current() FL_OVERRIDE; -public: - FLWindow *pre_window; - Fl_Quartz_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off); - ~Fl_Quartz_Image_Surface_Driver(); - void set_current() FL_OVERRIDE; - void translate(int x, int y) FL_OVERRIDE; - void untranslate() FL_OVERRIDE; - Fl_RGB_Image *image() FL_OVERRIDE; -}; - -#endif // FL_QUARTZ_IMAGE_SURFACE_DRIVER_H diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx deleted file mode 100644 index 4615ba475..000000000 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx +++ /dev/null @@ -1,167 +0,0 @@ -// -// Draw-to-image code for the Fast Light Tool Kit (FLTK). -// -// Copyright 1998-2026 by Bill Spitzak and others. -// -// This library is free software. Distribution and use rights are outlined in -// the file "COPYING" which should have been included with this file. If this -// file is missing or damaged, see the license at: -// -// https://www.fltk.org/COPYING.php -// -// Please see the following page on how to report bugs and issues: -// -// https://www.fltk.org/bugs.php -// - -#include <FL/platform.H> -#include <FL/fl_draw.H> -#include "Fl_Quartz_Image_Surface_Driver.H" -#include "Fl_Quartz_Graphics_Driver.H" -#include "../Cocoa/Fl_Cocoa_Window_Driver.H" -#include <ApplicationServices/ApplicationServices.h> - - -Fl_Quartz_Image_Surface_Driver::Fl_Quartz_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) { - mask_ = NULL; - int W = w, H = h; - float s = 1; - if (high_res) { - s = Fl_Graphics_Driver::default_driver().scale(); - Fl_Window *cw = Fl::first_window(); - Fl_Cocoa_Window_Driver *dr = cw ? Fl_Cocoa_Window_Driver::driver(cw) : NULL; - if (dr && dr->mapped_to_retina()) s *= 2; - W *= s; H *= s; - } - CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); - offscreen = off ? off : (Fl_Offscreen)CGBitmapContextCreate(calloc(W*H,4), W, H, 8, W*4, lut, kCGImageAlphaPremultipliedLast); - CGColorSpaceRelease(lut); - driver(new Fl_Quartz_Graphics_Driver); - CGContextTranslateCTM((CGContextRef)offscreen, 0.5*s, -0.5*s); // as when drawing to a window - if (high_res) { - CGContextScaleCTM((CGContextRef)offscreen, s, s); - driver()->scale(s); - } - CGContextSetShouldAntialias((CGContextRef)offscreen, false); - CGContextTranslateCTM((CGContextRef)offscreen, 0, height); - CGContextScaleCTM((CGContextRef)offscreen, 1.0f, -1.0f); - CGContextSaveGState((CGContextRef)offscreen); - CGContextSetRGBFillColor((CGContextRef)offscreen, 1, 1, 1, 0); - CGContextFillRect((CGContextRef)offscreen, CGRectMake(0,0,w,h)); -} - -Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { - if (mask_) { - CGImageRelease(mask_); - } - if (offscreen) CGContextRestoreGState((CGContextRef)offscreen); - if (offscreen && !external_offscreen) { - void *data = CGBitmapContextGetData((CGContextRef)offscreen); - free(data); - CGContextRelease((CGContextRef)offscreen); - } - delete driver(); -} - - -void Fl_Quartz_Image_Surface_Driver::set_current() { - Fl_Surface_Device::set_current(); - pre_window = fl_window; - driver()->gc((CGContextRef)offscreen); - fl_window = 0; - ((Fl_Quartz_Graphics_Driver*)driver())->high_resolution( CGBitmapContextGetWidth((CGContextRef)offscreen) > (size_t)width ); - if (mask_) { - int W, H; - printable_rect(&W, &H); - CGContextSaveGState((CGContextRef)offscreen); - CGContextClipToMask((CGContextRef)offscreen, CGRectMake(0,0,W,H), mask_); // 10.4 - CGContextSaveGState((CGContextRef)offscreen); - } -} - -void Fl_Quartz_Image_Surface_Driver::translate(int x, int y) { - CGContextRestoreGState((CGContextRef)offscreen); - CGContextSaveGState((CGContextRef)offscreen); - CGContextTranslateCTM((CGContextRef)offscreen, x, y); - CGContextSaveGState((CGContextRef)offscreen); -} - -void Fl_Quartz_Image_Surface_Driver::untranslate() { - CGContextRestoreGState((CGContextRef)offscreen); -} - -Fl_RGB_Image* Fl_Quartz_Image_Surface_Driver::image() -{ - CGContextFlush((CGContextRef)offscreen); - if (mask_) { - CGContextRestoreGState((CGContextRef)offscreen); - CGImageRelease(mask_); - mask_ = NULL; - } - int W = (int)CGBitmapContextGetWidth((CGContextRef)offscreen); - int H = (int)CGBitmapContextGetHeight((CGContextRef)offscreen); - int bpr = (int)CGBitmapContextGetBytesPerRow((CGContextRef)offscreen); - int bpp = (int)CGBitmapContextGetBitsPerPixel((CGContextRef)offscreen)/8; - uchar *base = (uchar*)CGBitmapContextGetData((CGContextRef)offscreen); - int idx, idy; - uchar *pdst, *psrc; - unsigned char *data = new uchar[W * H * 3]; - for (idy = 0, pdst = data; idy < H; idy ++) { - for (idx = 0, psrc = base + idy * bpr; idx < W; idx ++, psrc += bpp, pdst += 3) { - pdst[0] = psrc[0]; // R - pdst[1] = psrc[1]; // G - pdst[2] = psrc[2]; // B - } - } - Fl_RGB_Image *image = new Fl_RGB_Image(data, W, H); - image->alloc_array = 1; - return image; -} - -void Fl_Quartz_Image_Surface_Driver::end_current() -{ - if (mask_) { - CGContextRestoreGState((CGContextRef)offscreen); - CGContextRestoreGState((CGContextRef)offscreen); - } - fl_window = pre_window; - Fl_Surface_Device::end_current(); -} - - -static void MyProviderReleaseData (void *info, const void *data, size_t size) { - delete[] (uchar*)data; -} - - -void Fl_Quartz_Image_Surface_Driver::mask(const Fl_RGB_Image *img) { - if (!&CGContextClipToMask) return; - int W = (int)CGBitmapContextGetWidth((CGContextRef)offscreen); - int H = (int)CGBitmapContextGetHeight((CGContextRef)offscreen); - bool using_copy = false; - if (W != img->data_w() || H != img->data_h()) { - Fl_RGB_Image *copy = (Fl_RGB_Image*)img->copy(W, H); - img = copy; - using_copy = true; - } - - int i, d = img->d(), w = img->data_w(), h = img->data_h(); - // reverse top and bottom and convert to gray scale if img->d() == 3 and complement bits - int bytes_per_row = (img->ld() ? img->ld() : w * d); - uchar *from = new uchar[w * h]; - for ( i = 0; i < h; i++) { - const uchar *p = img->array + bytes_per_row * i; - const uchar *last = p + bytes_per_row; - uchar *q = from + (h - 1 - i) * w; - while (p < last) { - unsigned u = *p++; - u += *p++; - u += *p++; - *q++ = ~(u/3); - } - } - CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, w * h, MyProviderReleaseData); - mask_ = CGImageMaskCreate(w, h, 8, 8, w, provider, NULL, false); - CFRelease(provider); - if (using_copy) delete img; -} |
