//----------------------------------------------------------------------------- bool IPlatformBitmap::createMemoryPNGRepresentation (IPlatformBitmap* bitmap, void** ptr, uint32_t& size) { bool result = false; #if !TARGET_OS_IPHONE CGBitmap* cgBitmap = dynamic_cast<CGBitmap*> (bitmap); if (cgBitmap) { CGImageRef image = cgBitmap->getCGImage (); if (image) { CFMutableDataRef data = CFDataCreateMutable (NULL, 0); if (data) { CGImageDestinationRef dest = CGImageDestinationCreateWithData (data, kUTTypePNG, 1, 0); if (dest) { CGImageDestinationAddImage (dest, image, 0); if (CGImageDestinationFinalize (dest)) { size = (uint32_t)CFDataGetLength (data); *ptr = malloc (size); CFDataGetBytes (data, CFRangeMake (0, size), (UInt8*)*ptr); result = true; } CFRelease (dest); } CFRelease (data); } } } #endif return result; }
//----------------------------------------------------------------------------- void CGDrawContext::drawBitmap (CBitmap* bitmap, const CRect& inRect, const CPoint& inOffset, float alpha) { if (bitmap == 0 || alpha == 0.f) return; CGBitmap* cgBitmap = bitmap->getPlatformBitmap () ? dynamic_cast<CGBitmap*> (bitmap->getPlatformBitmap ()) : 0; CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0; if (image) { CGContextRef context = beginCGContext (false, true); if (context) { CRect rect (inRect); rect.makeIntegral (); CPoint offset (inOffset); offset.makeIntegral (); CGContextSetAlpha (context, (CGFloat)alpha*currentState.globalAlpha); CGRect dest; dest.origin.x = rect.left - offset.h; dest.origin.y = -(rect.top) - (bitmap->getHeight () - offset.v); dest.size.width = cgBitmap->getSize ().x; dest.size.height = cgBitmap->getSize ().y; CGRect clipRect2; clipRect2.origin.x = rect.left; clipRect2.origin.y = -(rect.top) - rect.height (); clipRect2.size.width = rect.width (); clipRect2.size.height = rect.height (); CGContextClipToRect (context, clipRect2); CGLayerRef layer = cgBitmap->getCGLayer (); if (layer == 0) { BitmapDrawCountMap::iterator it = bitmapDrawCount.find (cgBitmap); if (it == bitmapDrawCount.end ()) { bitmapDrawCount.insert (std::pair<CGBitmap*, int32_t> (cgBitmap, 1)); CGContextDrawImage (context, dest, image); } else { it->second++; layer = cgBitmap->createCGLayer (context); } } if (layer) { CGContextDrawLayerInRect (context, dest, layer); } releaseCGContext (context); } } }
//----------------------------------------------------------------------------- void CGDrawContext::fillRectWithBitmap (CBitmap* bitmap, const CRect& srcRect, const CRect& dstRect, float alpha) { if (bitmap == 0 || alpha == 0.f || srcRect.isEmpty () || dstRect.isEmpty ()) return; if (!(srcRect.left == 0 && srcRect.right == 0 && srcRect.right == bitmap->getWidth () && srcRect.bottom == bitmap->getHeight ())) { // CGContextDrawTiledImage does not work with parts of a bitmap CDrawContext::fillRectWithBitmap(bitmap, srcRect, dstRect, alpha); return; } IPlatformBitmap* platformBitmap = bitmap->getBestPlatformBitmapForScaleFactor (scaleFactor); CPoint bitmapSize = platformBitmap->getSize (); if (srcRect.right > bitmapSize.x || srcRect.bottom > bitmapSize.y) return; CGBitmap* cgBitmap = platformBitmap ? dynamic_cast<CGBitmap*> (platformBitmap) : 0; CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0; if (image) { CGContextRef context = beginCGContext (false, true); if (context) { // TODO: Check if this works with retina images CGRect clipRect = CGRectFromCRect (dstRect); clipRect.origin.y = -(clipRect.origin.y) - clipRect.size.height; clipRect = pixelAlligned (clipRect); CGContextClipToRect (context, clipRect); CGRect r = {}; r.size.width = CGImageGetWidth (image); r.size.height = CGImageGetHeight (image); CGContextDrawTiledImage (context, r, image); releaseCGContext (context); } } }
//----------------------------------------------------------------------------- void CGDrawContext::drawBitmap (CBitmap* bitmap, const CRect& inRect, const CPoint& inOffset, float alpha) { if (bitmap == 0 || alpha == 0.f) return; double transformedScaleFactor = scaleFactor; CGraphicsTransform t = getCurrentTransform (); if (t.m11 == t.m22 && t.m12 == 0 && t.m21 == 0) transformedScaleFactor *= t.m11; IPlatformBitmap* platformBitmap = bitmap->getBestPlatformBitmapForScaleFactor (transformedScaleFactor); CGBitmap* cgBitmap = platformBitmap ? dynamic_cast<CGBitmap*> (platformBitmap) : 0; CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0; if (image) { CGContextRef context = beginCGContext (false, true); if (context) { CGLayerRef layer = cgBitmap->getCGLayer (); if (layer == 0) { BitmapDrawCountMap::iterator it = bitmapDrawCount.find (cgBitmap); if (it == bitmapDrawCount.end ()) { bitmapDrawCount.insert (std::pair<CGBitmap*, int32_t> (cgBitmap, 1)); } else { it->second++; layer = cgBitmap->createCGLayer (context); } } drawCGImageRef (context, image, layer, cgBitmap->getScaleFactor (), inRect, inOffset, alpha, bitmap); releaseCGContext (context); } } }