1
0

osx_canvas_quartz.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #include <bfc/platform/types.h>
  2. #include <Carbon/Carbon.h>
  3. #include <tataki/canvas/canvas.h>
  4. #include <api/wnd/basewnd.h>
  5. #include <tataki/region/api_region.h>
  6. /* various functions that might help out
  7. for drawSysObject:
  8. HIThemeDrawButton
  9. HIThemeDrawTitleBarWidget for minimize, maximize, exit
  10. */
  11. inline float QuartzBlue(RGB32 color)
  12. {
  13. unsigned char *pixel = (unsigned char *)&color;
  14. return pixel[0] / 255.f;
  15. }
  16. inline float QuartzGreen(RGB32 color)
  17. {
  18. unsigned char *pixel = (unsigned char *)&color;
  19. return pixel[1] / 255.f;
  20. }
  21. inline float QuartzRed(RGB32 color)
  22. {
  23. unsigned char *pixel = (unsigned char *)&color;
  24. return pixel[2] / 255.f;
  25. }
  26. inline float QuartzAlpha(RGB32 color)
  27. {
  28. unsigned char *pixel = (unsigned char *)&color;
  29. return pixel[3] / 255.f;
  30. }
  31. Canvas::Canvas(CGrafPtr _context)
  32. {
  33. }
  34. void Canvas::fillRect(const RECT *r, ARGB32 color)
  35. {
  36. CGContextSetRGBFillColor(context,
  37. QuartzRed(color), // red
  38. QuartzGreen(color), // green
  39. QuartzBlue(color), // blue
  40. QuartzAlpha(color) // alpha
  41. );
  42. HIRect rect = HIRectFromRECT(r);
  43. CGContextFillRect(context, rect);
  44. }
  45. void Canvas::fillRgn(api_region *r, ARGB32 color)
  46. {
  47. CGContextSetRGBFillColor(context,
  48. QuartzRed(color), // red
  49. QuartzGreen(color), // green
  50. QuartzBlue(color), // blue
  51. QuartzAlpha(color) // alpha
  52. );
  53. HIShapeRef shape = r->getOSHandle();
  54. HIShapeReplacePathInCGContext(shape, context);
  55. CGContextFillPath(context);
  56. }
  57. void Canvas::blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
  58. {
  59. // clip dest
  60. // Create CGImage from context
  61. // CGContextDrawImage
  62. }
  63. HDC Canvas::getHDC()
  64. {
  65. return context;
  66. }
  67. void Canvas::selectClipRgn(api_region *r)
  68. {
  69. if (r)
  70. {
  71. HIShapeRef shape = r->getOSHandle();
  72. HIShapeReplacePathInCGContext(shape, context);
  73. CGContextClip(context);
  74. }
  75. else
  76. {
  77. CGContextClipToRect(context, CGRectInfinite);
  78. }
  79. }
  80. void Canvas::stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth)
  81. {
  82. // Create CGImage from context
  83. // CGContextDrawImage
  84. }
  85. void Canvas::textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  86. {
  87. // TODO: turn this code into a svc_fontI, and use api_font here instead
  88. size_t len = wcslen(txt);
  89. UniChar *unistr = (UniChar *)malloc((len + 1) * sizeof(UniChar));
  90. UniChar *copy = unistr;
  91. while (*txt)
  92. *copy++=*txt++;
  93. *copy=0;
  94. ATSUStyle style;
  95. ATSUCreateStyle(&style);
  96. CGContextSaveGState(context);
  97. CGContextSetRGBFillColor(context,
  98. QuartzRed(fontInfo->color), // red
  99. QuartzGreen(fontInfo->color), // green
  100. QuartzBlue(fontInfo->color), // blue
  101. QuartzAlpha(fontInfo->color) // alpha
  102. );
  103. ATSUTextLayout layout;
  104. ATSUCreateTextLayout(&layout);
  105. ATSUSetTextPointerLocation(layout, unistr, kATSUFromTextBeginning, kATSUToTextEnd, len);
  106. ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd);
  107. Rect imageRect;
  108. ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &imageRect);
  109. y-=(imageRect.bottom - imageRect.top);
  110. CGContextScaleCTM(context, 1.0, -1.0);
  111. ATSUAttributeTag tags[] = {kATSUCGContextTag};
  112. ATSUAttributeValuePtr values[] = {&context};
  113. ByteCount sizes[] = {sizeof(CGContextRef)};
  114. ATSUSetLayoutControls(layout, 1, tags, sizes, values);
  115. ATSUDrawText(layout, kATSUFromTextBeginning, kATSUToTextEnd, FloatToFixed(x), FloatToFixed(y));
  116. ATSUDisposeTextLayout(layout);
  117. ATSUDisposeStyle(style);
  118. CGContextRestoreGState(context);
  119. free(unistr);
  120. }
  121. void Canvas::drawSysObject(const RECT *r, int sysobj, int alpha)
  122. {
  123. #warning TODO
  124. using namespace DrawSysObj;
  125. switch(sysobj)
  126. {
  127. case OSBUTTON:
  128. {
  129. HIRect buttonRect = HIRectFromRECT(r);
  130. HIThemeButtonDrawInfo buttonDrawInfo;
  131. buttonDrawInfo.version=0;
  132. buttonDrawInfo.state = kThemeStateActive;
  133. buttonDrawInfo.kind = kThemePushButton;
  134. buttonDrawInfo.value = kThemeButtonOn;
  135. buttonDrawInfo.adornment = kThemeAdornmentNone;
  136. buttonDrawInfo.animation.time.start = 0;
  137. buttonDrawInfo.animation.time.current=0;
  138. HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0);
  139. }
  140. break;
  141. case OSBUTTON_PUSHED:
  142. {
  143. HIRect buttonRect = HIRectFromRECT(r);
  144. HIThemeButtonDrawInfo buttonDrawInfo;
  145. buttonDrawInfo.version=0;
  146. buttonDrawInfo.state = kThemeStatePressed;
  147. buttonDrawInfo.kind = kThemePushButton;
  148. buttonDrawInfo.value = kThemeButtonOn;
  149. buttonDrawInfo.adornment = kThemeAdornmentNone;
  150. buttonDrawInfo.animation.time.start = 0;
  151. buttonDrawInfo.animation.time.current=0;
  152. HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0);
  153. }
  154. break;
  155. case OSBUTTON_DISABLED:
  156. {
  157. HIRect buttonRect = HIRectFromRECT(r);
  158. HIThemeButtonDrawInfo buttonDrawInfo;
  159. buttonDrawInfo.version=0;
  160. buttonDrawInfo.state = kThemeStateInactive;
  161. buttonDrawInfo.kind = kThemePushButton;
  162. buttonDrawInfo.value = kThemeButtonOn;
  163. buttonDrawInfo.adornment = kThemeAdornmentNone;
  164. buttonDrawInfo.animation.time.start = 0;
  165. buttonDrawInfo.animation.time.current=0;
  166. HIThemeDrawButton(&buttonRect, &buttonDrawInfo, context, /*kHIThemeOrientationNormal*/kHIThemeOrientationInverted, 0);
  167. }
  168. break;
  169. }
  170. }
  171. void Canvas::getTextExtent(const wchar_t *text, int *w, int *h, const Wasabi::FontInfo *fontInfo)
  172. {
  173. // TODO: turn this code into a svc_fontI, and use api_font here instead
  174. size_t len = wcslen(text);
  175. UniChar *unistr = (UniChar *)malloc((len + 1) * sizeof(UniChar));
  176. UniChar *copy = unistr;
  177. while (*text)
  178. *copy++=*text++;
  179. *copy=0;
  180. ATSUStyle style;
  181. ATSUCreateStyle(&style);
  182. ATSUTextLayout layout;
  183. ATSUCreateTextLayout(&layout);
  184. ATSUSetTextPointerLocation(layout, unistr, kATSUFromTextBeginning, kATSUToTextEnd, len);
  185. ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd);
  186. Rect imageRect;
  187. ATSUMeasureTextImage(layout, kATSUFromTextBeginning, kATSUToTextEnd, 0, 0, &imageRect);
  188. *h=(imageRect.bottom - imageRect.top);
  189. *w = (imageRect.right - imageRect.left);
  190. ATSUDisposeTextLayout(layout);
  191. ATSUDisposeStyle(style);
  192. free(unistr);
  193. }
  194. void Canvas::textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo)
  195. {
  196. textOut(r->left, r->top, txt, fontInfo);
  197. }
  198. #define CBCLASS Canvas
  199. START_DISPATCH;
  200. CB(GETHDC, getHDC);
  201. END_DISPATCH;
  202. #undef CBCLASS
  203. BaseCloneCanvas::BaseCloneCanvas(api_canvas *cloner)
  204. {
  205. if (cloner != NULL) clone(cloner);
  206. }
  207. int BaseCloneCanvas::clone(api_canvas *cloner)
  208. {
  209. ASSERTPR(context == NULL, "can't clone twice");
  210. context = cloner->getHDC();
  211. CGContextRetain(context);
  212. // bits = cloner->getBits();
  213. // cloner->getDim(&width, &height, &pitch);
  214. // srcwnd = cloner->getBaseWnd();
  215. // cloner->getOffsets(&xoffset, &yoffset);
  216. // setTextFont(cloner->getTextFont());
  217. // setTextSize(cloner->getTextSize());
  218. // setTextBold(cloner->getTextBold());
  219. // setTextOpaque(cloner->getTextOpaque());
  220. // setTextUnderline(cloner->getTextUnderline());
  221. // setTextItalic(cloner->getTextItalic());
  222. // setTextAlign(cloner->getTextAlign());
  223. // setTextColor(cloner->getTextColor());
  224. // setTextBkColor(cloner->getTextBkColor());
  225. return (context != NULL);
  226. }
  227. BaseCloneCanvas::~BaseCloneCanvas()
  228. {
  229. CGContextRelease(context);
  230. context = NULL;
  231. }