void GraphicsContext::drawWindowsBitmap(WindowsBitmap* image, const IntPoint& point) { RetainPtr<CGColorSpaceRef> deviceRGB(AdoptCF, CGColorSpaceCreateDeviceRGB()); // FIXME: Creating CFData is non-optimal, but needed to avoid crashing when printing. Ideally we should // make a custom CGDataProvider that controls the WindowsBitmap lifetime. see <rdar://6394455> RetainPtr<CFDataRef> imageData(AdoptCF, CFDataCreate(kCFAllocatorDefault, image->buffer(), image->bufferLength())); RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(imageData.get())); RetainPtr<CGImageRef> cgImage(AdoptCF, CGImageCreate(image->size().width(), image->size().height(), 8, 32, image->bytesPerRow(), deviceRGB.get(), kCGBitmapByteOrder32Little | kCGImageAlphaFirst, dataProvider.get(), 0, true, kCGRenderingIntentDefault)); CGContextDrawImage(m_data->m_cgContext, CGRectMake(point.x(), point.y(), image->size().width(), image->size().height()), cgImage.get()); }
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const { CGContextRef platformContext = context->platformContext(); RetainPtr<CGImageRef> image; if (!m_accelerateRendering) image.adoptCF(cgImage(m_size, m_data)); #if USE(IOSURFACE_CANVAS_BACKING_STORE) else image.adoptCF(wkIOSurfaceContextCreateImage(platformContext)); #endif CGContextTranslateCTM(platformContext, rect.x(), rect.y() + rect.height()); CGContextScaleCTM(platformContext, 1, -1); CGContextClipToMask(platformContext, FloatRect(FloatPoint(), rect.size()), image.get()); CGContextScaleCTM(platformContext, 1, -1); CGContextTranslateCTM(platformContext, -rect.x(), -rect.y() - rect.height()); }
void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) { if (!m_accelerateRendering) { if (destContext == context()) { // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. RefPtr<Image> copy = copyImage(); copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } else { RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data)); imageForRendering->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } } else { RefPtr<Image> copy = copyImage(); copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } }
void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale) { if (!m_accelerateRendering) { if (destContext == context()) { // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. RefPtr<Image> copy = copyImage(); destContext->drawImage(copy.get(), ColorSpaceDeviceRGB, destRect, srcRect, op, useLowQualityScale); } else { RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data)); destContext->drawImage(imageForRendering.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); } } else { RefPtr<Image> copy = copyImage(); ColorSpace colorSpace = (destContext == context()) ? ColorSpaceDeviceRGB : styleColorSpace; destContext->drawImage(copy.get(), colorSpace, destRect, srcRect, op, useLowQualityScale); } }
void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, CGContextRef context) { if (!imagePixels || imageWidth <= 0 || imageHeight <= 0 || canvasWidth <= 0 || canvasHeight <= 0 || !context) return; int rowBytes = imageWidth * 4; RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithData(0, imagePixels, rowBytes * imageHeight, 0)); RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); RetainPtr<CGImageRef> cgImage(AdoptCF, CGImageCreate(imageWidth, imageHeight, 8, 32, rowBytes, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, dataProvider.get(), 0, false, kCGRenderingIntentDefault)); // CSS styling may cause the canvas's content to be resized on // the page. Go back to the Canvas to figure out the correct // width and height to draw. CGRect rect = CGRectMake(0, 0, canvasWidth, canvasHeight); // We want to completely overwrite the previous frame's // rendering results. CGContextSaveGState(context); CGContextSetBlendMode(context, kCGBlendModeCopy); CGContextSetInterpolationQuality(context, kCGInterpolationNone); CGContextDrawImage(context, rect, cgImage.get()); CGContextRestoreGState(context); }