Home | History | Annotate | Download | only in mac
      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 
     13 static 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 
     25 static 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 
     40 static 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 
     67 static 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 
    106 void 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