#include #include #include #include #include /* 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; }