aboutsummaryrefslogtreecommitdiff
path: root/Src/tataki/bitmap/mac
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/tataki/bitmap/mac
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/tataki/bitmap/mac')
-rw-r--r--Src/tataki/bitmap/mac/osx_bitmap_cgimage.cpp219
-rw-r--r--Src/tataki/bitmap/mac/osx_bitmap_cgimage.h48
2 files changed, 267 insertions, 0 deletions
diff --git a/Src/tataki/bitmap/mac/osx_bitmap_cgimage.cpp b/Src/tataki/bitmap/mac/osx_bitmap_cgimage.cpp
new file mode 100644
index 00000000..9e1c33c2
--- /dev/null
+++ b/Src/tataki/bitmap/mac/osx_bitmap_cgimage.cpp
@@ -0,0 +1,219 @@
+#include "osx_bitmap_cgimage.h"
+
+SkinBitmap::SkinBitmap(ARGB32 *_bits, int w, int h) : image(0)
+{
+ // TODO: allow a mechanism for SkinBitmap to take ownership of the data
+ bits = malloc(w*h*4);
+ if (bits)
+ {
+ memcpy(bits, _bits, w*h*4);
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ imageContext = CGBitmapContextCreate(bits, w, h, 8, w*4, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
+ image = CGBitmapContextCreateImage(imageContext);
+ CGColorSpaceRelease(colorSpace);
+ }
+}
+
+SkinBitmap::~SkinBitmap()
+{
+ CGImageRelease(image);
+#ifndef SKINBITMAP_USE_CGIMAGE
+ free(bits);
+ CGContextRelease(imageContext);
+#endif
+}
+
+#ifdef WASABI_COMPILE_IMGLDR
+SkinBitmap::SkinBitmap(const wchar_t *elementname, int _cached)
+{
+ ASSERT(elementname!= NULL);
+
+ bitmapname = elementname;
+ x_offset = -1;
+ y_offset = -1;
+ subimage_w = -1;
+ subimage_h = -1;
+ fullimage_w=fullimage_h=0;
+ ownbits=1;
+ bits = NULL;
+ fromskin = 0;
+ last_failed = 0;
+#ifdef WASABI_COMPILE_SKIN
+ bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(elementname, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ fromskin = (bits != NULL);
+#endif
+ if (bits == NULL)
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(elementname, &has_alpha, &fullimage_w, &fullimage_h);
+#ifdef WASABI_COMPILE_SKIN
+ if (bits == NULL)
+ {
+ bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(ERRORBMP, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
+ last_failed = 1;
+ }
+#endif
+ if (bits == NULL)
+ {
+ bits = WASABI_API_IMGLDR->imgldr_makeBmp(HARDERRORBMP, &has_alpha, &fullimage_w, &fullimage_h);
+ last_failed = 1;
+ }
+
+ // check that coordinates are correct
+ if(x_offset!=-1 && x_offset>fullimage_w) x_offset=fullimage_w-1;
+ if(y_offset!=-1 && y_offset>fullimage_h) y_offset=fullimage_h-1;
+ if(subimage_w!=-1 && (x_offset+subimage_w)>fullimage_w) subimage_w=fullimage_w-x_offset;
+ if(subimage_h!=-1 && (y_offset+subimage_h)>fullimage_h) subimage_h=fullimage_h-y_offset;
+
+ // ASSERTPR(bits != NULL, elementname);
+ if (bits == NULL) {
+ DebugString("element not found ! %s\n", elementname);
+ int n = 10*10;
+ bits = (ARGB32 *)WASABI_API_MEMMGR->sysMalloc(n * 4);
+
+
+ ARGB32 *p = bits;
+ while (n--)
+ *p++ = 0xFFFF00FF;
+ }
+}
+#endif
+
+
+int SkinBitmap::getWidth()
+{
+ if (!image)
+ return 0;
+
+ return CGImageGetWidth(image);
+}
+
+int SkinBitmap::getFullWidth()
+{
+ if (!image)
+ return 0;
+
+ return CGImageGetBytesPerRow(image)/4; // assumes 32bit pixel data
+}
+
+int SkinBitmap::getHeight()
+{
+ if (!image)
+ return 0;
+ return CGImageGetHeight(image);
+}
+
+void SkinBitmap::blit(api_canvas *canvas, int x, int y)
+{
+ if (!image)
+ return;
+
+ CGContextRef context = canvas->getHDC();
+ CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
+ CGContextDrawImage(context, rect, image);
+}
+
+void SkinBitmap::blitAlpha(api_canvas *canvas, int x, int y, int alpha)
+{
+ if (!image)
+ return;
+
+ float floatAlpha = alpha / 255.f;
+
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+// CGContextTranslateCTM(context, 0, r->bottom);
+// CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextSetAlpha(context, floatAlpha);
+ CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
+ CGContextDrawImage(context, rect, image);
+ CGContextRestoreGState(context);
+}
+
+void SkinBitmap::stretchToRect(api_canvas *canvas, RECT *r)
+{
+ if (!image)
+ return;
+
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+ CGContextTranslateCTM (context, 0, r->bottom);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
+ CGContextDrawImage(context, rect, image);
+
+ CGContextRestoreGState(context);
+}
+
+void SkinBitmap::stretchToRectAlpha(api_canvas *canvas, RECT *r, int alpha)
+{
+ if (!image)
+ return;
+
+ float floatAlpha = alpha / 255.f;
+
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+ CGContextTranslateCTM (context, 0, r->bottom);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextSetAlpha(context, floatAlpha);
+ CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
+ CGContextDrawImage(context, rect, image);
+ CGContextRestoreGState(context);
+}
+
+void SkinBitmap::stretchToRectAlpha(api_canvas *canvas, RECT *src, RECT *dst, int alpha)
+{
+ if (!image)
+ return;
+
+ float floatAlpha = alpha / 255.f;
+
+ // make a new image ref clipped to the source rect
+ CGRect srcRect = CGRectMake(src->left, src->top, src->right-src->left, src->bottom-src->top);
+ CGImageRef clippedImage = CGImageCreateWithImageInRect(image, srcRect);
+
+ // blit onto canvas
+ CGContextRef context = canvas->getHDC();
+ CGContextSaveGState(context);
+
+ CGContextTranslateCTM(context, 0, dst->bottom);
+ CGContextScaleCTM(context, 1.0, -1.0);
+
+ CGContextSetAlpha(context, floatAlpha);
+ CGRect rect = CGRectMake(dst->left, dst->top, dst->right-dst->left, dst->bottom-dst->top);
+ CGContextDrawImage(context, rect, clippedImage);
+ CGContextRestoreGState(context);
+
+ // release the reference to our clipped image
+ CGImageRelease(clippedImage);
+}
+
+uint8_t *SkinBitmap::getBits()
+{
+ return static_cast<uint8_t *>(CGBitmapContextGetData(imageContext));
+}
+
+void SkinBitmap::UpdateBits(uint8_t *bits)
+{
+ CGImageRelease(image);
+ image = CGBitmapContextCreateImage(imageContext);
+}
+
+ARGB32 SkinBitmap::getPixel(int x, int y)
+{
+ ARGB32 *array = (ARGB32 *)getBits();
+ return array[x + y*getFullWidth()];
+}
+
+#define CBCLASS SkinBitmap
+START_DISPATCH;
+CB(IFC_BITMAP_GETBITMAP, GetBitmap);
+CB(IFC_BITMAP_GETBITS, getBits);
+VCB(IFC_BITMAP_UPDATEBITS, UpdateBits);
+END_DISPATCH;
+#undef CBCLASS \ No newline at end of file
diff --git a/Src/tataki/bitmap/mac/osx_bitmap_cgimage.h b/Src/tataki/bitmap/mac/osx_bitmap_cgimage.h
new file mode 100644
index 00000000..0e842c08
--- /dev/null
+++ b/Src/tataki/bitmap/mac/osx_bitmap_cgimage.h
@@ -0,0 +1,48 @@
+#ifndef NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H
+#define NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H
+
+#include <tataki/export.h>
+#include <bfc/platform/platform.h>
+#include <tataki/canvas/api_canvas.h>
+#include <api/wnd/ifc_bitmap.h>
+
+/*
+ TODO:
+ need some kind of updateBits() so that the underlying image can be updated to reflect changes
+ */
+class TATAKIAPI SkinBitmap : public ifc_bitmap
+{
+public:
+ SkinBitmap(ARGB32 *bits, int w, int h); // added by benski, use if you have raw image bits
+ SkinBitmap(const wchar_t *elementname, int cached = 1);
+ ~SkinBitmap();
+ int getWidth();
+ int getHeight();
+ int getFullWidth(); // aka pitch
+
+ // blits
+ void blit(api_canvas *canvas, int x, int y);
+ void blitAlpha(api_canvas *canvas, int x, int y, int alpha = 255);
+ // stretch blits
+ void stretchToRect(api_canvas *canvas, RECT *r);
+ void stretchToRectAlpha(api_canvas *canvas, RECT *r, int alpha = 255);
+ void stretchToRectAlpha(api_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
+// tiled blits
+ void blitTile(api_canvas *canvas, RECT *dest, int xoffs = 0, int yoffs = 0, int alpha = 255);
+
+ ARGB32 getPixel(int x, int y);
+public: // ifc_bitmap implementations
+ OSBITMAPHANDLE GetBitmap() { return image; }
+ uint8_t *getBits();
+ void UpdateBits(uint8_t *bits);
+
+private:
+ CGImageRef image;
+ CGContextRef imageContext;
+ void *bits;
+
+protected:
+ RECVS_DISPATCH;
+};
+
+#endif \ No newline at end of file