diff options
author | Jean-Francois Mauguit <jfmauguit@mac.com> | 2024-09-24 09:03:25 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 09:03:25 -0400 |
commit | bab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/tataki/bitmap/mac | |
parent | 4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff) | |
parent | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff) | |
download | winamp-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.cpp | 219 | ||||
-rw-r--r-- | Src/tataki/bitmap/mac/osx_bitmap_cgimage.h | 48 |
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 |