osx_bitmap_cgimage.cpp 5.7 KB

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