Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -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()
{
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1 @@
#include <tataki/canvas/win/canvas.h>

View file

@ -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