1#include "SkBitmap.h" 2#include "SkColorPriv.h" 3#include "SkMath.h" 4 5#if defined(SK_BUILD_FOR_MAC) && !defined(SK_USE_WXWIDGETS) 6 7#include <ApplicationServices/ApplicationServices.h> 8 9#ifndef __ppc__ 10 #define SWAP_16BIT 11#endif 12 13static void convertGL32_to_Mac32(uint32_t dst[], const SkBitmap& bm) { 14 memcpy(dst, bm.getPixels(), bm.getSize()); 15 return; 16 17 uint32_t* stop = dst + (bm.getSize() >> 2); 18 const uint8_t* src = (const uint8_t*)bm.getPixels(); 19 while (dst < stop) { 20 *dst++ = src[2] << 24 | src[1] << 16 | src[0] << 8 | src[3] << 0; 21 src += sizeof(uint32_t); 22 } 23} 24 25static void convert565_to_32(uint32_t dst[], const SkBitmap& bm) { 26 for (int y = 0; y < bm.height(); y++) { 27 const uint16_t* src = bm.getAddr16(0, y); 28 const uint16_t* stop = src + bm.width(); 29 while (src < stop) { 30 unsigned c = *src++; 31 unsigned r = SkPacked16ToR32(c); 32 unsigned g = SkPacked16ToG32(c); 33 unsigned b = SkPacked16ToB32(c); 34 35 *dst++ = (b << 24) | (g << 16) | (r << 8) | 0xFF; 36 } 37 } 38} 39 40static void convert4444_to_555(uint16_t dst[], const uint16_t src[], int count) 41{ 42 const uint16_t* stop = src + count; 43 44 while (src < stop) 45 { 46 unsigned c = *src++; 47 48 unsigned r = SkGetPackedR4444(c); 49 unsigned g = SkGetPackedG4444(c); 50 unsigned b = SkGetPackedB4444(c); 51 // convert to 5 bits 52 r = (r << 1) | (r >> 3); 53 g = (g << 1) | (g >> 3); 54 b = (b << 1) | (b >> 3); 55 // build the 555 56 c = (r << 10) | (g << 5) | b; 57 58#ifdef SWAP_16BIT 59 c = (c >> 8) | (c << 8); 60#endif 61 *dst++ = c; 62 } 63} 64 65#include "SkTemplates.h" 66 67static CGImageRef bitmap2imageref(const SkBitmap& bm) { 68 size_t bitsPerComp; 69 size_t bitsPerPixel; 70 CGBitmapInfo info; 71 CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); 72 CGDataProviderRef data = CGDataProviderCreateWithData(NULL, 73 bm.getPixels(), 74 bm.getSize(), 75 NULL); 76 SkAutoTCallVProc<CGDataProvider, CGDataProviderRelease> acp(data); 77 SkAutoTCallVProc<CGColorSpace, CGColorSpaceRelease> acp2(cs); 78 79 switch (bm.config()) { 80 case SkBitmap::kARGB_8888_Config: 81 bitsPerComp = 8; 82 bitsPerPixel = 32; 83 info = kCGImageAlphaPremultipliedLast; 84 break; 85 case SkBitmap::kARGB_4444_Config: 86 bitsPerComp = 4; 87 bitsPerPixel = 16; 88 info = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder16Little; 89 break; 90#if 0 // not supported by quartz !!! 91 case SkBitmap::kRGB_565_Config: 92 bitsPerComp = 5; 93 bitsPerPixel = 16; 94 info = kCGImageAlphaNone | kCGBitmapByteOrder16Little; 95 break; 96#endif 97 default: 98 return NULL; 99 } 100 101 return CGImageCreate(bm.width(), bm.height(), bitsPerComp, bitsPerPixel, 102 bm.rowBytes(), cs, info, data, 103 NULL, false, kCGRenderingIntentDefault); 104} 105 106void SkBitmap::drawToPort(WindowRef wind, CGContextRef cg) const { 107 if (fPixels == NULL || fWidth == 0 || fHeight == 0) { 108 return; 109 } 110 111 bool useQD = false; 112 if (NULL == cg) { 113 SetPortWindowPort(wind); 114 QDBeginCGContext(GetWindowPort(wind), &cg); 115 useQD = true; 116 } 117 118 SkBitmap bm; 119 if (this->config() == kRGB_565_Config) { 120 this->copyTo(&bm, kARGB_8888_Config); 121 } else { 122 bm = *this; 123 } 124 bm.lockPixels(); 125 126 CGImageRef image = bitmap2imageref(bm); 127 if (image) { 128 CGRect rect; 129 rect.origin.x = rect.origin.y = 0; 130 rect.size.width = bm.width(); 131 rect.size.height = bm.height(); 132 133 CGContextDrawImage(cg, rect, image); 134 CGImageRelease(image); 135 } 136 137 if (useQD) { 138 QDEndCGContext(GetWindowPort(wind), &cg); 139 } 140} 141 142#endif 143