osx_bitmap_cgimage.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include "osx_bitmap_cgimage.h"
  2. SkinBitmap::SkinBitmap(ARGB32 *_bits, int w, int h) : image(0)
  3. {
  4. // TODO: allow a mechanism for SkinBitmap to take ownership of the data
  5. bits = malloc(w*h*4);
  6. if (bits)
  7. {
  8. memcpy(bits, _bits, w*h*4);
  9. CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
  10. imageContext = CGBitmapContextCreate(bits, w, h, 8, w*4, colorSpace, kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);
  11. image = CGBitmapContextCreateImage(imageContext);
  12. CGColorSpaceRelease(colorSpace);
  13. }
  14. }
  15. SkinBitmap::~SkinBitmap()
  16. {
  17. CGImageRelease(image);
  18. #ifndef SKINBITMAP_USE_CGIMAGE
  19. free(bits);
  20. CGContextRelease(imageContext);
  21. #endif
  22. }
  23. #ifdef WASABI_COMPILE_IMGLDR
  24. SkinBitmap::SkinBitmap(const wchar_t *elementname, int _cached)
  25. {
  26. ASSERT(elementname!= NULL);
  27. bitmapname = elementname;
  28. x_offset = -1;
  29. y_offset = -1;
  30. subimage_w = -1;
  31. subimage_h = -1;
  32. fullimage_w=fullimage_h=0;
  33. ownbits=1;
  34. bits = NULL;
  35. fromskin = 0;
  36. last_failed = 0;
  37. #ifdef WASABI_COMPILE_SKIN
  38. bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(elementname, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
  39. fromskin = (bits != NULL);
  40. #endif
  41. if (bits == NULL)
  42. bits = WASABI_API_IMGLDR->imgldr_makeBmp(elementname, &has_alpha, &fullimage_w, &fullimage_h);
  43. #ifdef WASABI_COMPILE_SKIN
  44. if (bits == NULL)
  45. {
  46. bits = WASABI_API_IMGLDR->imgldr_requestSkinBitmap(ERRORBMP, &has_alpha, &x_offset, &y_offset, &subimage_w, &subimage_h, &fullimage_w, &fullimage_h,_cached);
  47. last_failed = 1;
  48. }
  49. #endif
  50. if (bits == NULL)
  51. {
  52. bits = WASABI_API_IMGLDR->imgldr_makeBmp(HARDERRORBMP, &has_alpha, &fullimage_w, &fullimage_h);
  53. last_failed = 1;
  54. }
  55. // check that coordinates are correct
  56. if(x_offset!=-1 && x_offset>fullimage_w) x_offset=fullimage_w-1;
  57. if(y_offset!=-1 && y_offset>fullimage_h) y_offset=fullimage_h-1;
  58. if(subimage_w!=-1 && (x_offset+subimage_w)>fullimage_w) subimage_w=fullimage_w-x_offset;
  59. if(subimage_h!=-1 && (y_offset+subimage_h)>fullimage_h) subimage_h=fullimage_h-y_offset;
  60. // ASSERTPR(bits != NULL, elementname);
  61. if (bits == NULL) {
  62. DebugString("element not found ! %s\n", elementname);
  63. int n = 10*10;
  64. bits = (ARGB32 *)WASABI_API_MEMMGR->sysMalloc(n * 4);
  65. ARGB32 *p = bits;
  66. while (n--)
  67. *p++ = 0xFFFF00FF;
  68. }
  69. }
  70. #endif
  71. int SkinBitmap::getWidth()
  72. {
  73. if (!image)
  74. return 0;
  75. return CGImageGetWidth(image);
  76. }
  77. int SkinBitmap::getFullWidth()
  78. {
  79. if (!image)
  80. return 0;
  81. return CGImageGetBytesPerRow(image)/4; // assumes 32bit pixel data
  82. }
  83. int SkinBitmap::getHeight()
  84. {
  85. if (!image)
  86. return 0;
  87. return CGImageGetHeight(image);
  88. }
  89. void SkinBitmap::blit(api_canvas *canvas, int x, int y)
  90. {
  91. if (!image)
  92. return;
  93. CGContextRef context = canvas->getHDC();
  94. CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
  95. CGContextDrawImage(context, rect, image);
  96. }
  97. void SkinBitmap::blitAlpha(api_canvas *canvas, int x, int y, int alpha)
  98. {
  99. if (!image)
  100. return;
  101. float floatAlpha = alpha / 255.f;
  102. CGContextRef context = canvas->getHDC();
  103. CGContextSaveGState(context);
  104. // CGContextTranslateCTM(context, 0, r->bottom);
  105. // CGContextScaleCTM(context, 1.0, -1.0);
  106. CGContextSetAlpha(context, floatAlpha);
  107. CGRect rect = CGRectMake(x, y, getWidth(), getHeight());
  108. CGContextDrawImage(context, rect, image);
  109. CGContextRestoreGState(context);
  110. }
  111. void SkinBitmap::stretchToRect(api_canvas *canvas, RECT *r)
  112. {
  113. if (!image)
  114. return;
  115. CGContextRef context = canvas->getHDC();
  116. CGContextSaveGState(context);
  117. CGContextTranslateCTM (context, 0, r->bottom);
  118. CGContextScaleCTM(context, 1.0, -1.0);
  119. CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
  120. CGContextDrawImage(context, rect, image);
  121. CGContextRestoreGState(context);
  122. }
  123. void SkinBitmap::stretchToRectAlpha(api_canvas *canvas, RECT *r, int alpha)
  124. {
  125. if (!image)
  126. return;
  127. float floatAlpha = alpha / 255.f;
  128. CGContextRef context = canvas->getHDC();
  129. CGContextSaveGState(context);
  130. CGContextTranslateCTM (context, 0, r->bottom);
  131. CGContextScaleCTM(context, 1.0, -1.0);
  132. CGContextSetAlpha(context, floatAlpha);
  133. CGRect rect = CGRectMake(r->left, r->top, r->right-r->left, r->bottom-r->top);
  134. CGContextDrawImage(context, rect, image);
  135. CGContextRestoreGState(context);
  136. }
  137. void SkinBitmap::stretchToRectAlpha(api_canvas *canvas, RECT *src, RECT *dst, int alpha)
  138. {
  139. if (!image)
  140. return;
  141. float floatAlpha = alpha / 255.f;
  142. // make a new image ref clipped to the source rect
  143. CGRect srcRect = CGRectMake(src->left, src->top, src->right-src->left, src->bottom-src->top);
  144. CGImageRef clippedImage = CGImageCreateWithImageInRect(image, srcRect);
  145. // blit onto canvas
  146. CGContextRef context = canvas->getHDC();
  147. CGContextSaveGState(context);
  148. CGContextTranslateCTM(context, 0, dst->bottom);
  149. CGContextScaleCTM(context, 1.0, -1.0);
  150. CGContextSetAlpha(context, floatAlpha);
  151. CGRect rect = CGRectMake(dst->left, dst->top, dst->right-dst->left, dst->bottom-dst->top);
  152. CGContextDrawImage(context, rect, clippedImage);
  153. CGContextRestoreGState(context);
  154. // release the reference to our clipped image
  155. CGImageRelease(clippedImage);
  156. }
  157. uint8_t *SkinBitmap::getBits()
  158. {
  159. return static_cast<uint8_t *>(CGBitmapContextGetData(imageContext));
  160. }
  161. void SkinBitmap::UpdateBits(uint8_t *bits)
  162. {
  163. CGImageRelease(image);
  164. image = CGBitmapContextCreateImage(imageContext);
  165. }
  166. ARGB32 SkinBitmap::getPixel(int x, int y)
  167. {
  168. ARGB32 *array = (ARGB32 *)getBits();
  169. return array[x + y*getFullWidth()];
  170. }
  171. #define CBCLASS SkinBitmap
  172. START_DISPATCH;
  173. CB(IFC_BITMAP_GETBITMAP, GetBitmap);
  174. CB(IFC_BITMAP_GETBITS, getBits);
  175. VCB(IFC_BITMAP_UPDATEBITS, UpdateBits);
  176. END_DISPATCH;
  177. #undef CBCLASS