diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-11-20 17:13:09 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2023-12-04 12:34:44 +0100 |
| commit | 3e61ec7044942ebaeda948c64df762a0250f8954 (patch) | |
| tree | 642c08a6f7b120c2237f5e457074670d0ccf3e86 /src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx | |
| parent | b9ac6bd728659a7780d7cde024f34607601e8a7f (diff) | |
New member function Fl_Image_Surface::mask(Fl_RGB_Image*)
Diffstat (limited to 'src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx')
| -rw-r--r-- | src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx | 76 |
1 files changed, 75 insertions, 1 deletions
diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx index 451078484..fb522745a 100644 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx @@ -1,7 +1,7 @@ // // Draw-to-image code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2018 by Bill Spitzak and others. +// Copyright 1998-2023 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 @@ -23,6 +23,9 @@ 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) { +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + mask_ = NULL; +#endif int W = w, H = h; float s = 1; if (high_res) { @@ -49,6 +52,12 @@ Fl_Quartz_Image_Surface_Driver::Fl_Quartz_Image_Surface_Driver(int w, int h, int } Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if (mask_) { + CGImageRelease(mask_); + } +#endif + if (offscreen) CGContextRestoreGState((CGContextRef)offscreen); if (offscreen && !external_offscreen) { void *data = CGBitmapContextGetData((CGContextRef)offscreen); free(data); @@ -56,6 +65,7 @@ Fl_Quartz_Image_Surface_Driver::~Fl_Quartz_Image_Surface_Driver() { } delete driver(); } + void Fl_Quartz_Image_Surface_Driver::set_current() { Fl_Surface_Device::set_current(); @@ -63,6 +73,15 @@ void Fl_Quartz_Image_Surface_Driver::set_current() { driver()->gc((CGContextRef)offscreen); fl_window = 0; ((Fl_Quartz_Graphics_Driver*)driver())->high_resolution( CGBitmapContextGetWidth((CGContextRef)offscreen) > (size_t)width ); +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + 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); + } +# endif } void Fl_Quartz_Image_Surface_Driver::translate(int x, int y) { @@ -79,6 +98,13 @@ void Fl_Quartz_Image_Surface_Driver::untranslate() { Fl_RGB_Image* Fl_Quartz_Image_Surface_Driver::image() { CGContextFlush((CGContextRef)offscreen); +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if (mask_) { + CGContextRestoreGState((CGContextRef)offscreen); + CGImageRelease(mask_); + mask_ = NULL; + } +#endif int W = (int)CGBitmapContextGetWidth((CGContextRef)offscreen); int H = (int)CGBitmapContextGetHeight((CGContextRef)offscreen); int bpr = (int)CGBitmapContextGetBytesPerRow((CGContextRef)offscreen); @@ -101,6 +127,54 @@ Fl_RGB_Image* Fl_Quartz_Image_Surface_Driver::image() void Fl_Quartz_Image_Surface_Driver::end_current() { +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + if (mask_) { + CGContextRestoreGState((CGContextRef)offscreen); + CGContextRestoreGState((CGContextRef)offscreen); + } +# endif fl_window = pre_window; Fl_Surface_Device::end_current(); } + + +# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + +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; +} + +#endif |
