diff options
Diffstat (limited to 'Src/tataki/canvas/mac')
-rw-r--r-- | Src/tataki/canvas/mac/PaintCanvas.cpp | 51 | ||||
-rw-r--r-- | Src/tataki/canvas/mac/PaintCanvas.h | 46 | ||||
-rw-r--r-- | Src/tataki/canvas/mac/bltcanvas.h | 27 | ||||
-rw-r--r-- | Src/tataki/canvas/mac/canvas.h | 70 | ||||
-rw-r--r-- | Src/tataki/canvas/mac/osx_canvas_layer.cpp | 95 | ||||
-rw-r--r-- | Src/tataki/canvas/mac/osx_canvas_quartz.cpp | 275 |
6 files changed, 564 insertions, 0 deletions
diff --git a/Src/tataki/canvas/mac/PaintCanvas.cpp b/Src/tataki/canvas/mac/PaintCanvas.cpp new file mode 100644 index 00000000..6cfeb126 --- /dev/null +++ b/Src/tataki/canvas/mac/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/tataki/canvas/mac/PaintCanvas.h b/Src/tataki/canvas/mac/PaintCanvas.h new file mode 100644 index 00000000..58379508 --- /dev/null +++ b/Src/tataki/canvas/mac/PaintCanvas.h @@ -0,0 +1,46 @@ +#ifndef NULLSOFT_WASABI_OSX_PAINTCANVAS_H +#define NULLSOFT_WASABI_OSX_PAINTCANVAS_H + +#include <tataki/export.h> +#include <tataki/canvas/canvas.h> +#include <api/wnd/basewnd.h> + +class TATAKIAPI PaintCanvas : public Canvas +{ +public: + PaintCanvas(); + ~PaintCanvas(); + bool beginPaint(BaseWnd *wnd); +protected: + CGrafPtr qdcontext; +}; + +class TATAKIAPI PaintBltCanvas : public PaintCanvas +{ +public: + bool beginPaintNC(BaseWnd *wnd) + { + return beginPaint(wnd); + } +}; +#warning port PaintBltCanvas +class TATAKIAPI WndCanvas : public Canvas +{ +public: + WndCanvas(); + virtual ~WndCanvas(); + + // address client area + int attachToClient(BaseWnd *basewnd); + +private: + CGrafPtr qdcontext; +}; + +class TATAKIAPI TextInfoCanvas : public Canvas +{ +public: + TextInfoCanvas(BaseWnd *baseWnd); + virtual ~TextInfoCanvas(); +}; +#endif
\ No newline at end of file diff --git a/Src/tataki/canvas/mac/bltcanvas.h b/Src/tataki/canvas/mac/bltcanvas.h new file mode 100644 index 00000000..e1005dc8 --- /dev/null +++ b/Src/tataki/canvas/mac/bltcanvas.h @@ -0,0 +1,27 @@ +#ifndef _BLTCANVAS_H +#define _BLTCANVAS_H + +#include <tataki/export.h> +#include "canvas.h" + +class TATAKIAPI 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(api_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(api_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/tataki/canvas/mac/canvas.h b/Src/tataki/canvas/mac/canvas.h new file mode 100644 index 00000000..5258af4e --- /dev/null +++ b/Src/tataki/canvas/mac/canvas.h @@ -0,0 +1,70 @@ +#ifndef NULLSOFT_WASABI_CANVAS_H +#define NULLSOFT_WASABI_CANVAS_H + +#include <tataki/export.h> +#include <Carbon/Carbon.h> +#include <tataki/canvas/api_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 TATAKIAPI Canvas : public api_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 TATAKIAPI BaseCloneCanvas : public Canvas +{ +public: + BaseCloneCanvas(api_canvas *cloner=NULL); + virtual ~BaseCloneCanvas(); + + int clone(api_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/tataki/canvas/mac/osx_canvas_layer.cpp b/Src/tataki/canvas/mac/osx_canvas_layer.cpp new file mode 100644 index 00000000..c6f80347 --- /dev/null +++ b/Src/tataki/canvas/mac/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(api_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(api_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/tataki/canvas/mac/osx_canvas_quartz.cpp b/Src/tataki/canvas/mac/osx_canvas_quartz.cpp new file mode 100644 index 00000000..dcbae59f --- /dev/null +++ b/Src/tataki/canvas/mac/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(api_canvas *cloner) +{ + if (cloner != NULL) clone(cloner); +} + +int BaseCloneCanvas::clone(api_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; +} + |