diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Wasabi/api/wnd/platform | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Wasabi/api/wnd/platform')
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp | 51 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h | 45 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/bltcanvas.h | 26 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/canvas.h | 69 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp | 220 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h | 47 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp | 95 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp | 275 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp | 217 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/osx/region.h | 115 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/win32/bitmap.h | 81 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/win32/canvas.h | 1 | ||||
-rw-r--r-- | Src/Wasabi/api/wnd/platform/win32/region.h | 135 |
13 files changed, 1377 insertions, 0 deletions
diff --git a/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp new file mode 100644 index 00000000..6cfeb126 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.cpp @@ -0,0 +1,51 @@ +#include "PaintCanvas.h" + +PaintCanvas::PaintCanvas() +{ + qdcontext=0; +} + +bool PaintCanvas::beginPaint(BaseWnd *wnd) +{ + HIWindowRef macWnd = wnd->getOsWindowHandle(); + + qdcontext = GetWindowPort(macWnd); + QDBeginCGContext(qdcontext, &context); + + return true; +} + +PaintCanvas::~PaintCanvas() +{ + if (qdcontext) + QDEndCGContext(qdcontext, &context); +} + +WndCanvas::WndCanvas() +{ + qdcontext=0; +} + +WndCanvas::~WndCanvas() +{ + if (qdcontext) + QDEndCGContext(qdcontext, &context); +} + +int WndCanvas::attachToClient(BaseWnd *basewnd) +{ + HIWindowRef macWnd = basewnd->getOsWindowHandle(); + + qdcontext = GetWindowPort(macWnd); + QDBeginCGContext(qdcontext, &context); + return 1; +} + + +TextInfoCanvas::TextInfoCanvas(BaseWnd */*unused*/) +{ +} + +TextInfoCanvas::~TextInfoCanvas() +{ +} diff --git a/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h new file mode 100644 index 00000000..f9091404 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/PaintCanvas.h @@ -0,0 +1,45 @@ +#ifndef NULLSOFT_WASABI_OSX_PAINTCANVAS_H +#define NULLSOFT_WASABI_OSX_PAINTCANVAS_H + +#include <tataki/canvas/canvas.h> +#include <api/wnd/basewnd.h> + +class PaintCanvas : public Canvas +{ +public: + PaintCanvas(); + ~PaintCanvas(); + bool beginPaint(BaseWnd *wnd); +protected: + CGrafPtr qdcontext; +}; + +class PaintBltCanvas : public PaintCanvas +{ +public: + bool beginPaintNC(BaseWnd *wnd) + { + return beginPaint(wnd); + } +}; +#warning port PaintBltCanvas +class WndCanvas : public Canvas +{ +public: + WndCanvas(); + virtual ~WndCanvas(); + + // address client area + int attachToClient(BaseWnd *basewnd); + +private: + CGrafPtr qdcontext; +}; + +class TextInfoCanvas : public Canvas +{ +public: + TextInfoCanvas(BaseWnd *baseWnd); + virtual ~TextInfoCanvas(); +}; +#endif
\ No newline at end of file diff --git a/Src/Wasabi/api/wnd/platform/osx/bltcanvas.h b/Src/Wasabi/api/wnd/platform/osx/bltcanvas.h new file mode 100644 index 00000000..399deb71 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/bltcanvas.h @@ -0,0 +1,26 @@ +#ifndef _BLTCANVAS_H +#define _BLTCANVAS_H + +#include "canvas.h" + +class BltCanvas : public Canvas +{ +public: + BltCanvas(); + BltCanvas(int width, int height, OSWINDOWHANDLE wnd); + + // override blit and stretchblit so we can use CGContextDrawLayerAtPoint/CGContextDrawLayerInRect + virtual void blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth); + void blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255); + + virtual void stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth); + void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255); + + void DestructiveResize(int w, int h, int nb_bpp = 32); // resizes the bitmap, destroying the contents + void fillBits(ARGB32 color); + +protected: + CGLayerRef layer; +}; + +#endif diff --git a/Src/Wasabi/api/wnd/platform/osx/canvas.h b/Src/Wasabi/api/wnd/platform/osx/canvas.h new file mode 100644 index 00000000..9a434026 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/canvas.h @@ -0,0 +1,69 @@ +#ifndef NULLSOFT_WASABI_CANVAS_H +#define NULLSOFT_WASABI_CANVAS_H + +#include <Carbon/Carbon.h> +#include <tataki/canvas/ifc_canvas.h> +#include <bfc/platform/platform.h> +#include <api/service/svcs/svc_font.h> // for STDFONT_* stuff. should make a std_font thingy later +#include <bfc/std.h> // for WASABI_DEFAULT_FONTNAMEW +class BaseWnd; +class api_region; + +class Canvas : public ifc_canvas +{ +public: + Canvas() :context(0), wnd(0) {} + Canvas(CGContextRef _context) : context(_context), wnd(0) {} + Canvas(CGrafPtr _context); + HDC getHDC(); + void fillRect(const RECT *r, RGB32 color); + void fillRgn(api_region *r, RGB32 color); + void setBaseWnd(BaseWnd *_wnd) { wnd=_wnd; } + void selectClipRgn(api_region *r); + + virtual void blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth); + virtual void stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth); + + void textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo); + + static float getSystemFontScale() { return 1.0f; } + + int getTextWidth(const wchar_t *text, const Wasabi::FontInfo *fontInfo); + int getTextHeight(const wchar_t *text, const Wasabi::FontInfo *fontInfo); + int getTextHeight(const Wasabi::FontInfo *fontInfo) + { + return getTextHeight(L"M", fontInfo); + } + void getTextExtent(const wchar_t *text, int *w, int *h, const Wasabi::FontInfo *fontInfo); + void textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo); + void textOut(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo); + void textOutEllipsed(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo); + + void drawSysObject(const RECT *r, int sysobj, int alpha=255); +protected: + RECVS_DISPATCH; + + CGContextRef context; + BaseWnd *wnd; // TODO: not 100% sure we'll need this. win32 version has it so we'll keep it for now +}; + +class BaseCloneCanvas : public Canvas +{ +public: + BaseCloneCanvas(ifc_canvas *cloner=NULL); + virtual ~BaseCloneCanvas(); + + int clone(ifc_canvas *cloner); +}; + +namespace DrawSysObj { + enum { + BUTTON, BUTTON_PUSHED, BUTTON_DISABLED, + OSBUTTON, OSBUTTON_PUSHED, OSBUTTON_DISABLED, + OSBUTTON_CLOSE, OSBUTTON_CLOSE_PUSHED, OSBUTTON_CLOSE_DISABLED, + OSBUTTON_MINIMIZE, OSBUTTON_MINIMIZE_PUSHED, OSBUTTON_MINIMIZE_DISABLED, + OSBUTTON_MAXIMIZE, OSBUTTON_MAXIMIZE_PUSHED, OSBUTTON_MAXIMIZE_DISABLED, + }; +}; + +#endif diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp new file mode 100644 index 00000000..fe9f3363 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.cpp @@ -0,0 +1,220 @@ +#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; + 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); +#else + 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(ifc_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(ifc_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(ifc_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(ifc_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(ifc_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/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h new file mode 100644 index 00000000..5a30637e --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/osx_bitmap_cgimage.h @@ -0,0 +1,47 @@ +#ifndef NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H +#define NULLSOFT_WASABI_OSX_BITMAP_CGIMAGE_H + +#include <bfc/platform/platform.h> +#include <tataki/canvas/ifc_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 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(ifc_canvas *canvas, int x, int y); + void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha = 255); + // stretch blits + void stretchToRect(ifc_canvas *canvas, RECT *r); + void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha = 255); + void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255); +// tiled blits + void blitTile(ifc_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 diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp new file mode 100644 index 00000000..43c2984b --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_layer.cpp @@ -0,0 +1,95 @@ +#include <tataki/canvas/bltcanvas.h> + +inline float QuartzBlue(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[0] / 255.f; +} + +inline float QuartzGreen(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[1] / 255.f; +} + +inline float QuartzRed(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[2] / 255.f; +} + +inline float QuartzAlpha(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[3] / 255.f; +} + +BltCanvas::BltCanvas(int width, int height, OSWINDOWHANDLE wnd) +{ + CGrafPtr qdcontext = GetWindowPort(wnd); + CGContextRef temp; + QDBeginCGContext(qdcontext, &temp); + CGSize size = CGSizeMake(width, height); + layer = CGLayerCreateWithContext(temp, size, NULL); + context = CGLayerGetContext(layer); + QDEndCGContext(qdcontext, &temp); +} + +void BltCanvas::blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth) +{ + CGPoint point = CGPointMake(dstx-srcx, dsty-srcy); + CGContextDrawLayerAtPoint(dest->getHDC(), point, layer); +} + +void BltCanvas::blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha) +{ + CGContextRef dest = canvas->getHDC(); + CGContextSaveGState(dest); + CGContextSetAlpha(dest, (float)alpha/255.f); + // TODO: deal with width properly + CGRect rect = CGRectMake(dst->left - src->left, dst->top - src->top, dst->right - dst->left, dst->bottom - dst->top); + CGContextDrawLayerInRect(dest, rect, layer); + CGContextRestoreGState(dest); +} + +void BltCanvas::stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth) +{ + CGContextSaveGState(context); + CGContextTranslateCTM(context, srcx, srcy); + CGRect rect = CGRectMake(dstx, dsty, dstw, dsth); + CGContextDrawLayerInRect(dest->getHDC(), rect, layer); + CGContextRestoreGState(context); +} + +void BltCanvas::stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha) +{ + CGContextRef dest = canvas->getHDC(); + CGContextSaveGState(dest); + CGContextSetAlpha(dest, (float)alpha/255.f); +// TODO: deal with width properly + CGRect rect = CGRectMake(dst->left - src->left, dst->top - src->top, dst->right - dst->left, dst->bottom - dst->top); + CGContextDrawLayerInRect(dest, rect, layer); + CGContextRestoreGState(dest); +} + +void BltCanvas::DestructiveResize(int w, int h, int nb_bpp) +{ + CGSize size = CGSizeMake(w, h); + CGLayerRef newlayer = CGLayerCreateWithContext(context, size, NULL); + CGContextRelease(context); + CGLayerRelease(layer); + layer = newlayer; + context = CGLayerGetContext(layer); +} + +void BltCanvas::fillBits(ARGB32 color) +{ + CGContextSetRGBFillColor(context, + QuartzRed(color), // red + QuartzGreen(color), // green + QuartzBlue(color), // blue + QuartzAlpha(color) // alpha + ); + + CGContextFillRect(context, CGRectInfinite); +}
\ No newline at end of file diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp new file mode 100644 index 00000000..093ab5e5 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/osx_canvas_quartz.cpp @@ -0,0 +1,275 @@ +#include <bfc/platform/types.h> +#include <Carbon/Carbon.h> +#include <tataki/canvas/canvas.h> +#include <api/wnd/basewnd.h> +#include <tataki/region/api_region.h> + + + +/* various functions that might help out + +for drawSysObject: +HIThemeDrawButton +HIThemeDrawTitleBarWidget for minimize, maximize, exit +*/ + +inline float QuartzBlue(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[0] / 255.f; +} + +inline float QuartzGreen(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[1] / 255.f; + +} + +inline float QuartzRed(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[2] / 255.f; + +} + +inline float QuartzAlpha(RGB32 color) +{ + unsigned char *pixel = (unsigned char *)&color; + return pixel[3] / 255.f; + +} + +Canvas::Canvas(CGrafPtr _context) +{ + +} + +void Canvas::fillRect(const RECT *r, ARGB32 color) +{ + CGContextSetRGBFillColor(context, + QuartzRed(color), // red + QuartzGreen(color), // green + QuartzBlue(color), // blue + QuartzAlpha(color) // alpha + ); + + HIRect rect = HIRectFromRECT(r); + CGContextFillRect(context, rect); +} + +void Canvas::fillRgn(api_region *r, ARGB32 color) +{ + CGContextSetRGBFillColor(context, + QuartzRed(color), // red + QuartzGreen(color), // green + QuartzBlue(color), // blue + QuartzAlpha(color) // alpha + ); + + HIShapeRef shape = r->getOSHandle(); + HIShapeReplacePathInCGContext(shape, context); + CGContextFillPath(context); +} + +void Canvas::blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth) +{ + // clip dest + // Create CGImage from context + // CGContextDrawImage +} + +HDC Canvas::getHDC() +{ + return context; +} + +void Canvas::selectClipRgn(api_region *r) +{ + if (r) + { + HIShapeRef shape = r->getOSHandle(); + HIShapeReplacePathInCGContext(shape, context); + CGContextClip(context); + } + else + { + CGContextClipToRect(context, CGRectInfinite); + } +} + +void Canvas::stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth) +{ + // Create CGImage from context + // CGContextDrawImage +} + +void Canvas::textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo) +{ + // TODO: turn this code into a svc_fontI, and use api_font here instead + size_t len = wcslen(txt); + UniChar *unistr = (UniChar *)malloc((len + 1) * sizeof(UniChar)); + UniChar *copy = unistr; + while (*txt) + *copy++=*txt++; + *copy=0; + + ATSUStyle style; + ATSUCreateStyle(&style); + + CGContextSaveGState(context); + CGContextSetRGBFillColor(context, + QuartzRed(fontInfo->color), // red + QuartzGreen(fontInfo->color), // green + QuartzBlue(fontInfo->color), // blue + QuartzAlpha(fontInfo->color) // alpha + ); + + ATSUTextLayout layout; + ATSUCreateTextLayout(&layout); + + ATSUSetTextPointerLocation(layout, unistr, kATSUFromTextBeginning, kATSUToTextEnd, len); + + ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd); + + Rect imageRect; + ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &imageRect); + y-=(imageRect.bottom - imageRect.top); + CGContextScaleCTM(context, 1.0, -1.0); + + ATSUAttributeTag tags[] = {kATSUCGContextTag}; + ATSUAttributeValuePtr values[] = {&context}; + ByteCount sizes[] = {sizeof(CGContextRef)}; + ATSUSetLayoutControls(layout, 1, tags, sizes, values); + ATSUDrawText(layout, kATSUFromTextBeginning, kATSUToTextEnd, FloatToFixed(x), FloatToFixed(y)); + ATSUDisposeTextLayout(layout); + ATSUDisposeStyle(style); + CGContextRestoreGState(context); + free(unistr); +} + +void Canvas::drawSysObject(const RECT *r, int sysobj, int alpha) +{ +#warning TODO + using namespace DrawSysObj; + switch(sysobj) + { + case OSBUTTON: + { + HIRect buttonRect = HIRectFromRECT(r); + HIThemeButtonDrawInfo buttonDrawInfo; + buttonDrawInfo.version=0; + buttonDrawInfo.state = kThemeStateActive; + buttonDrawInfo.kind = kThemePushButton; + buttonDrawInfo.value = kThemeButtonOn; + buttonDrawInfo.adornment = kThemeAdornmentNone; + buttonDrawInfo.animation.time.start = 0; + buttonDrawInfo.animation.time.current=0; + HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0); + } + break; + case OSBUTTON_PUSHED: + { + HIRect buttonRect = HIRectFromRECT(r); + HIThemeButtonDrawInfo buttonDrawInfo; + buttonDrawInfo.version=0; + buttonDrawInfo.state = kThemeStatePressed; + buttonDrawInfo.kind = kThemePushButton; + buttonDrawInfo.value = kThemeButtonOn; + buttonDrawInfo.adornment = kThemeAdornmentNone; + buttonDrawInfo.animation.time.start = 0; + buttonDrawInfo.animation.time.current=0; + HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0); + } + break; + case OSBUTTON_DISABLED: + { + HIRect buttonRect = HIRectFromRECT(r); + HIThemeButtonDrawInfo buttonDrawInfo; + buttonDrawInfo.version=0; + buttonDrawInfo.state = kThemeStateInactive; + buttonDrawInfo.kind = kThemePushButton; + buttonDrawInfo.value = kThemeButtonOn; + buttonDrawInfo.adornment = kThemeAdornmentNone; + buttonDrawInfo.animation.time.start = 0; + buttonDrawInfo.animation.time.current=0; + HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0); + } + break; + } +} + +void Canvas::getTextExtent(const wchar_t *text, int *w, int *h, const Wasabi::FontInfo *fontInfo) +{ + // TODO: turn this code into a svc_fontI, and use api_font here instead + size_t len = wcslen(text); + UniChar *unistr = (UniChar *)malloc((len + 1) * sizeof(UniChar)); + UniChar *copy = unistr; + while (*text) + *copy++=*text++; + *copy=0; + + ATSUStyle style; + ATSUCreateStyle(&style); + + ATSUTextLayout layout; + ATSUCreateTextLayout(&layout); + + ATSUSetTextPointerLocation(layout, unistr, kATSUFromTextBeginning, kATSUToTextEnd, len); + + ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd); + + Rect imageRect; + ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &imageRect); + *h=(imageRect.bottom - imageRect.top); + *w = (imageRect.right - imageRect.left); + + ATSUDisposeTextLayout(layout); + ATSUDisposeStyle(style); + free(unistr); +} + +void Canvas::textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo) +{ + textOut(r->left, r->top, txt, fontInfo); +} + + +#define CBCLASS Canvas +START_DISPATCH; +CB(GETHDC, getHDC); +END_DISPATCH; +#undef CBCLASS + +BaseCloneCanvas::BaseCloneCanvas(ifc_canvas *cloner) +{ + if (cloner != NULL) clone(cloner); +} + +int BaseCloneCanvas::clone(ifc_canvas *cloner) +{ + ASSERTPR(context == NULL, "can't clone twice"); + context = cloner->getHDC(); + CGContextRetain(context); +// bits = cloner->getBits(); +// cloner->getDim(&width, &height, &pitch); + // srcwnd = cloner->getBaseWnd(); +// cloner->getOffsets(&xoffset, &yoffset); +// setTextFont(cloner->getTextFont()); +// setTextSize(cloner->getTextSize()); +// setTextBold(cloner->getTextBold()); +// setTextOpaque(cloner->getTextOpaque()); +// setTextUnderline(cloner->getTextUnderline()); +// setTextItalic(cloner->getTextItalic()); +// setTextAlign(cloner->getTextAlign()); +// setTextColor(cloner->getTextColor()); +// setTextBkColor(cloner->getTextBkColor()); + return (context != NULL); +} + +BaseCloneCanvas::~BaseCloneCanvas() +{ + CGContextRelease(context); + context = NULL; +} + diff --git a/Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp b/Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp new file mode 100644 index 00000000..348ba1de --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/osx_region_hishape.cpp @@ -0,0 +1,217 @@ +#include <Carbon/Carbon.h> +#include <tataki/region/region.h> +#include <tataki/bitmap/bitmap.h> + +RegionI::RegionI() : rgn(0) +{ +} + +RegionI::RegionI(const RECT *r) : rgn(0) +{ + setRect(r); +} + +RegionI::RegionI(HIMutableShapeRef _rgn) : rgn(_rgn) +{ +} + +RegionI::RegionI(HIShapeRef _rgn) +{ + rgn=HIShapeCreateMutableCopy(_rgn); +} + +RegionI::~RegionI() +{ + if (rgn) + CFRelease(rgn); +} + +RegionI::RegionI(RgnHandle qdrgn) +{ + HIShapeRef shape = HIShapeCreateWithQDRgn(qdrgn); + rgn = HIShapeCreateMutableCopy(shape); + CFRelease(shape); +} + +RegionI::RegionI(SkinBitmap *bitmap) +{ + // TODO: we need to find a much better way to do this + RECT r; + r.left=0; + r.top=0; + r.right=bitmap->getWidth(); + r.bottom=bitmap->getHeight(); + setRect(&r); +} + + +OSREGIONHANDLE RegionI::getOSHandle() +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + return rgn; +} + +api_region *RegionI::clone() +{ + if (!rgn) + return new RegionI(); + else + return new RegionI(HIShapeCreateMutableCopy(rgn)); +} + +void RegionI::disposeClone(api_region *r) +{ + if (r) // yes we need to check for NULL here because r != static_cast<>(r) + delete static_cast<RegionI *>(r); +} + +bool RegionI::ptInRegion(const POINT *pt) +{ + if (!rgn) + return false; + HIPoint hipt = HIPointFromPOINT(pt); + return !!HIShapeContainsPoint(rgn, &hipt); +} + +void RegionI::offset(int x, int y) +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + + HIShapeOffset(rgn, x, y); +} + +void RegionI::getBox(RECT *r) +{ + if (!rgn) // TODO: we could manually set r to 0,0,0,0 + rgn = HIShapeCreateMutable(); + + HIRect rect; + HIShapeGetBounds(rgn, &rect); + *r = RECTFromHIRect(&rect); +} + +void RegionI::subtractRegion(const api_region *r) +{ + if (rgn) + { + api_region *reg = const_cast<api_region *>(r); + HIShapeRef sub = reg->getOSHandle(); + HIShapeDifference(rgn,sub, rgn); + } +} + +void RegionI::subtractRect(const RECT *r) +{ + if (rgn) + { + HIRect rect = HIRectFromRECT(r); + HIShapeRef sub = HIShapeCreateWithRect(&rect); + HIShapeDifference(rgn, sub, rgn); + } +} + +void RegionI::addRect(const RECT *r) +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + HIRect rect = HIRectFromRECT(r); + HIShapeRef add = HIShapeCreateWithRect(&rect); + HIShapeUnion(rgn, add, rgn); +} + +void RegionI::addRegion(const api_region *r) +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + api_region *reg = const_cast<api_region *>(r); + HIShapeRef add = reg->getOSHandle(); + HIShapeUnion(rgn, add, rgn); +} + +void RegionI::andRegion(const api_region *r) +{ + if (rgn) // intersection with empty region will always be empty + { + api_region *reg = const_cast<api_region *>(r); + HIShapeRef intersection = reg->getOSHandle(); + HIShapeIntersect(rgn, intersection, rgn); + } +} + +void RegionI::setRect(const RECT *r) +{ + if (rgn) + CFRelease(rgn); + HIRect rect = HIRectFromRECT(r); + HIShapeRef rectRgn = HIShapeCreateWithRect(&rect); + rgn = HIShapeCreateMutableCopy(rectRgn); + CFRelease(rectRgn); +} + +void RegionI::empty() +{ + if (rgn) + CFRelease(rgn); + rgn=0; +} + +int RegionI::isEmpty() +{ + if (!rgn) + return 1; + return !!HIShapeIsEmpty(rgn); +} + +int RegionI::isRect() +{ + if (!rgn) + return 1; + return !!HIShapeIsRectangular(rgn); +} + +int RegionI::intersectRgn(const api_region *r, api_region *intersection) +{ + intersection->empty(); + intersection->addRegion(this); + intersection->andRegion(r); + return !intersection->isEmpty(); +} + +int RegionI::intersectRect(const RECT *r, api_region *intersection) +{ + intersection->setRect(r); + intersection->andRegion(this); + return !intersection->isEmpty(); +} + +#define CBCLASS RegionI +START_DISPATCH; +CB(REGION_GETOSHANDLE, getOSHandle); +CB(REGION_CLONE, clone); +VCB(REGION_DISPOSECLONE, disposeClone); +CB(REGION_PTINREGION, ptInRegion); +VCB(REGION_OFFSET, offset); +VCB(REGION_GETBOX, getBox); +VCB(REGION_SUBTRACTRGN, subtractRegion); +VCB(REGION_SUBTRACTRECT, subtractRect); +VCB(REGION_ADDRECT, addRect); +VCB(REGION_ADD, addRegion); +VCB(REGION_AND, andRegion); +VCB(REGION_SETRECT, setRect); +VCB(REGION_EMPTY, empty); +CB(REGION_ISEMPTY, isEmpty); +CB(REGION_ISRECT, isRect); +CB(REGION_INTERSECTRGN, intersectRgn); +CB(REGION_INTERSECTRECT, intersectRect); +END_DISPATCH; +#undef CBCLASS + +#define CBCLASS RegionServerI +START_DISPATCH; +VCB(REGIONSERVER_ADDREF, addRef); +VCB(REGIONSERVER_DELREF, delRef); +CB(REGIONSERVER_GETREGION, getRegion); +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/Wasabi/api/wnd/platform/osx/region.h b/Src/Wasabi/api/wnd/platform/osx/region.h new file mode 100644 index 00000000..9879b642 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/osx/region.h @@ -0,0 +1,115 @@ +#ifndef __REGION_H +#define __REGION_H + +#include <Carbon/Carbon.h> +#include <bfc/platform/platform.h> +#include <tataki/region/api_region.h> + +class SkinBitmap; + +class RegionI : public api_region +{ +public: + RegionI(); + RegionI(const RECT *r); + RegionI(RgnHandle qdrgn); + RegionI(HIShapeRef _rgn); + RegionI(SkinBitmap *bitmap); + ~RegionI(); + + // api_region + OSREGIONHANDLE getOSHandle(); + api_region *clone(); + void disposeClone(api_region *r); + bool ptInRegion(const POINT *pt); + void offset(int x, int y); + void getBox(RECT *r); + void subtractRegion(const api_region *r); + void subtractRect(const RECT *r); + void addRect(const RECT *r); + void addRegion(const api_region *r); + void andRegion(const api_region *r); + void setRect(const RECT *r); + void empty(); + int isEmpty(); + int equals(const api_region *r); + int enclosed(const api_region *r, api_region *outside = NULL); + int intersectRgn(const api_region *r, api_region *intersection); + int doesIntersectRgn(const api_region *r); + int intersectRect(const RECT *r, api_region *intersection); + + int isRect(); + void scale(double sx, double sy, bool round = 0); + void debug(int async = 0); + OSREGIONHANDLE makeWindowRegion(); // gives you a handle to a clone of the OSREGION object so you can insert it into a window's region with SetWindowRgn. ANY other use is prohibited + + // this is how you can enumerate the subrects that compose to make up the + // entire region + int getNumRects(); + int enumRect(int n, RECT *r); + + +private: + RegionI(HIMutableShapeRef _rgn); + HIMutableShapeRef rgn; + +protected: + RECVS_DISPATCH; +}; + + +// TODO: we could take of advantage of HIShapeRef's built in reference counting to implement this +class RegionServer : public Dispatchable { + +protected: + RegionServer() {} + virtual ~RegionServer() {} + +public: + + void addRef(void *client); + void delRef(void *client); + api_region *getRegion(); + + enum { + REGIONSERVER_ADDREF = 500, + REGIONSERVER_DELREF = 550, + REGIONSERVER_GETREGION = 600, + }; +}; + +inline void RegionServer::addRef(void *client) { + _voidcall(REGIONSERVER_ADDREF, (api_region *)NULL, client); +} + +inline void RegionServer::delRef(void *client) { + _voidcall(REGIONSERVER_DELREF, client); +} + +inline api_region * RegionServer::getRegion() { + return _call(REGIONSERVER_GETREGION, (api_region *)NULL); +} + +class RegionServerI : public RegionServer { +public : + + RegionServerI() { numrefs = 0; } + virtual ~RegionServerI() {} + + virtual void addRef(void *client) { numrefs++; } + virtual void delRef(void *client) { numrefs--; } + virtual api_region *getRegion()=0; + + virtual int getNumRefs() { return numrefs; } + +protected: + + RECVS_DISPATCH; + +private: + + int numrefs; +}; +#endif + + diff --git a/Src/Wasabi/api/wnd/platform/win32/bitmap.h b/Src/Wasabi/api/wnd/platform/win32/bitmap.h new file mode 100644 index 00000000..589f9a13 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/win32/bitmap.h @@ -0,0 +1,81 @@ +//NONPORTABLE +#ifndef _BITMAP_H +#define _BITMAP_H + +//#include <wasabicfg.h> +//#include <bfc/common.h> +#include <bfc/string/string.h> +#include <bfc/string/StringW.h> + +class ifc_canvas; // see canvas.h + +//#define NO_MMX + +class api_region; + +// a skinnable bitmap +class SkinBitmap +{ +public: +#ifndef _NOSTUDIO +#ifdef WASABI_COMPILE_IMGLDR +#ifdef _WIN32 + SkinBitmap(HINSTANCE hInst, int _id, const wchar_t *colorgroup = NULL); //NONPORTABLE +#endif + SkinBitmap(const wchar_t *elementname, int cached = 1); +#endif +#endif + // SkinBitmap(SkinBitmap *source, int w, int h); + SkinBitmap(int w, int h, ARGB32 bgcolor = RGBA(255,255,255,255)); //untested --BU +#ifdef _WIN32 + SkinBitmap(HBITMAP bitmap); + SkinBitmap(HBITMAP bitmap, HDC dc, int has_alpha = 0, void *bits = NULL); +#endif + SkinBitmap(ARGB32 *bits, int w, int h); // added by benski, use if you have raw image bits + ~SkinBitmap(); + +int getWidth() const { return subimage_w == -1 ? fullimage_w : subimage_w; }; +int getHeight() const { return subimage_h == -1 ? fullimage_h : subimage_h; }; + int getFullWidth() const { return fullimage_w; }; + int getFullHeight() const { return fullimage_h; }; +int getX() const { return x_offset == -1 ? 0 : x_offset; }; +int getY() const { return y_offset == -1 ? 0 : y_offset; }; + int getBpp() const { return 32; }; + int getAlpha() const { return has_alpha; }; + void setHasAlpha(int ha); + virtual void *getBits(); + int isInvalid(); + + const wchar_t *getBitmapName(); + + void blit(ifc_canvas *canvas, int x, int y); + void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha = 255); + // blits a chunk of source into dest rect + void blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255); + void blitTile(ifc_canvas *canvas, RECT *dest, int xoffs = 0, int yoffs = 0, int alpha = 255); + void blitRectToTile(ifc_canvas *canvas, RECT *dest, RECT *src, int xoffs = 0, int yoffs = 0, int alpha = 255); + void stretch(ifc_canvas *canvas, int x, int y, int w, int h); + void stretchToRect(ifc_canvas *canvas, RECT *r); + void stretchRectToRect(ifc_canvas *canvas, RECT *src, RECT *dst); + + void stretchToRectAlpha(ifc_canvas *canvas, RECT *r, int alpha = 255); + void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255); + ARGB32 getPixel(int x, int y); + +private: +#ifdef _WIN32 + void bmpToBits(HBITMAP hbmp, HDC defaultDC = NULL); +#endif + + int has_alpha; + + int x_offset, y_offset, subimage_w, subimage_h, fullimage_w, fullimage_h; + + ARGB32 *bits; + int ownbits; + int last_failed; + StringW bitmapname; + int fromskin; +}; + +#endif diff --git a/Src/Wasabi/api/wnd/platform/win32/canvas.h b/Src/Wasabi/api/wnd/platform/win32/canvas.h new file mode 100644 index 00000000..e6dea753 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/win32/canvas.h @@ -0,0 +1 @@ +#include <tataki/canvas/win/canvas.h> diff --git a/Src/Wasabi/api/wnd/platform/win32/region.h b/Src/Wasabi/api/wnd/platform/win32/region.h new file mode 100644 index 00000000..88491634 --- /dev/null +++ b/Src/Wasabi/api/wnd/platform/win32/region.h @@ -0,0 +1,135 @@ +#ifndef __REGION_H +#define __REGION_H + +#include <api/wnd/bitmap.h> +#include <bfc/dispatch.h> + +class BaseWnd; +class Canvas; +class api_region; +class RegionServer; + +#include "api_region.h" + +class RegionI : public api_region +{ +public: + RegionI(); + RegionI(const RegionI *copy); + RegionI(const RECT *r); + RegionI(int l, int t, int r, int b); + RegionI(OSREGIONHANDLE region); + RegionI(SkinBitmap *bitmap, RECT *r=NULL, int xoffset=0, int yoffset=0, bool inverted=false, int dothreshold=0, __int8 threshold=0, int threversed=0, int minalpha=1); + RegionI(Canvas *c, RECT *defboundbox=NULL); + virtual ~RegionI(); + + api_region *clone(); + void disposeClone(api_region *r); + bool ptInRegion(const POINT *pt); + void offset(int x, int y); + void getBox(RECT *r); + void subtractRegion(const api_region *reg); + void subtractRect(const RECT *r); + void addRect(const RECT *r); + void addRegion(const api_region *r); + void andRegion(const api_region *r); + void setRect(const RECT *r); + void empty(); + int isEmpty(); + int equals(const api_region *r); + int enclosed(const api_region *r, api_region *outside=NULL); + int intersectRgn(const api_region *r, api_region *intersection); + int doesIntersectRgn(const api_region *r); + int intersectRect(const RECT *r, api_region *intersection); + int doesIntersectRect(const RECT *r); + int isRect(); + void scale(double sx, double sy, bool round=0); + void debug(int async=0); + + // NONPORTABLE + + OSREGIONHANDLE makeWindowRegion(); // gives you a handle to a clone of the OSREGION object so you can insert it into a window's region with SetWindowRgn. ANY other use is prohibited + OSREGIONHANDLE getOSHandle(); // avoid as much as you can, should be used only by WIN32-dependant classes + + // END NONPORTABLE + + int getNumRects(); + int enumRect(int n, RECT *r); + + OSREGIONHANDLE alphaToRegionRect(void *pbits32, int bmX, int bmY, int bmWidth, int bmHeight, int fullw, int fullh, int xoffset, int yoffset, bool portion, int _x, int _y, int _w, int _h, bool inverted, int dothreshold, unsigned __int8 threshold, int thinverse, int minalpha); + +private: + + inline void init(); + void optimize(); + void deoptimize(); + + OSREGIONHANDLE hrgn; + OSREGIONHANDLE alphaToRegionRect(SkinBitmap *bitmap, int xoffset, int yoffset, bool portion, int _x, int _y, int _w, int _h, bool inverted=false, int dothreshold=0, unsigned __int8 threshold=0, int thinverse=0, int minalpha=1/* 1..255*/); + RECT overlay; + int clonecount; + RegionI *lastdebug; + RegionServer *srv; + RECT optrect; + int optimized; + +protected: + + RECVS_DISPATCH; +}; + +class RegionServer : public Dispatchable { + + protected: + RegionServer() {} + virtual ~RegionServer() {} + + public: + + void addRef(void *client); + void delRef(void *client); + api_region *getRegion(); + + enum { + REGIONSERVER_ADDREF = 500, + REGIONSERVER_DELREF = 550, + REGIONSERVER_GETREGION = 600, + }; +}; + +inline void RegionServer::addRef(void *client) { + _voidcall(REGIONSERVER_ADDREF, (api_region *)NULL, client); +} + +inline void RegionServer::delRef(void *client) { + _voidcall(REGIONSERVER_DELREF, client); +} + +inline api_region * RegionServer::getRegion() { + return _call(REGIONSERVER_GETREGION, (api_region *)NULL); +} + +class RegionServerI : public RegionServer { + public : + + RegionServerI() { numrefs = 0; } + virtual ~RegionServerI() {} + + virtual void addRef(void *client) { numrefs++; } + virtual void delRef(void *client) { numrefs--; } + virtual api_region *getRegion()=0; + + virtual int getNumRefs() { return numrefs; } + + protected: + + RECVS_DISPATCH; + + private: + + int numrefs; +}; + +#endif + + |