void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op, BlendMode, RespectImageOrientationEnum shouldRespectImageOrientation) { if (!dst.width() || !dst.height() || !src.width() || !src.height()) return; startAnimation(); NativeImageCairo* nativeImage = frameAtIndex(m_currentFrame); if (!nativeImage) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(context, dst, solidColor(), styleColorSpace, op); return; } context->save(); // Set the compositing operation. if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame)) context->setCompositeOperation(CompositeCopy); else context->setCompositeOperation(op); #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) cairo_surface_t* surface = nativeImage->surface(); IntSize scaledSize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface)); FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(src, scaledSize); #else FloatRect adjustedSrcRect(src); #endif ImageOrientation orientation = DefaultImageOrientation; if (shouldRespectImageOrientation == RespectImageOrientation) orientation = frameOrientationAtIndex(m_currentFrame); FloatRect dstRect = dst; if (orientation != DefaultImageOrientation) { // ImageOrientation expects the origin to be at (0, 0). context->translate(dstRect.x(), dstRect.y()); dstRect.setLocation(FloatPoint()); context->concatCTM(orientation.transformFromDefault(dstRect.size())); if (orientation.usesWidthAsHeight()) { // The destination rectangle will have it's width and height already reversed for the orientation of // the image, as it was needed for page layout, so we need to reverse it back here. dstRect = FloatRect(dstRect.x(), dstRect.y(), dstRect.height(), dstRect.width()); } } context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, adjustedSrcRect, context); context->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op) { FloatRect srcRect(src); FloatRect dstRect(dst); if (!dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.height()) return; startAnimation(); NativeImageCairo* nativeImage = frameAtIndex(m_currentFrame); if (!nativeImage) // If it's too early we won't have an image yet. return; if (mayFillWithSolidColor()) { fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op); return; } context->save(); // Set the compositing operation. if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame)) context->setCompositeOperation(CompositeCopy); else context->setCompositeOperation(op); context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, srcRect, context); context->restore(); if (imageObserver()) imageObserver()->didDraw(this); }
void BitmapImage::checkForSolidColor() { m_isSolidColor = false; m_checkedForSolidColor = true; if (frameCount() > 1) return; NativeImageCairo* nativeImage = frameAtIndex(m_currentFrame); if (!nativeImage) // If it's too early we won't have an image yet. return; cairo_surface_t* surface = nativeImage->surface(); ASSERT(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE); int width = cairo_image_surface_get_width(surface); int height = cairo_image_surface_get_height(surface); if (width != 1 || height != 1) return; unsigned* pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(surface)); m_solidColor = colorFromPremultipliedARGB(*pixelColor); m_isSolidColor = true; }
static bool decodeImage(ArgumentDecoder* decoder, GRefPtr<GdkPixbuf>& pixbuf) { ShareableBitmap::Handle handle; if (!decoder->decode(handle)) return false; RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(handle); if (!bitmap) return false; RefPtr<Image> image = bitmap->createImage(); if (!image) return false; NativeImageCairo* nativeImage = image->nativeImageForCurrentFrame(); if (!nativeImage) return false; cairo_surface_t* surface = nativeImage->surface(); pixbuf = adoptGRef(gdk_pixbuf_get_from_surface(surface, 0, 0, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface))); if (!pixbuf) return false; return true; }
bool GraphicsContext3D::ImageExtractor::extractImage(bool premultiplyAlpha, bool ignoreGammaAndColorProfile) { if (!m_image) return false; // We need this to stay in scope because the native image is just a shallow copy of the data. m_decoder = new ImageSource(premultiplyAlpha ? ImageSource::AlphaPremultiplied : ImageSource::AlphaNotPremultiplied, ignoreGammaAndColorProfile ? ImageSource::GammaAndColorProfileIgnored : ImageSource::GammaAndColorProfileApplied); if (!m_decoder) return false; ImageSource& decoder = *m_decoder; m_alphaOp = AlphaDoNothing; if (m_image->data()) { decoder.setData(m_image->data(), true); if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0)) return false; OwnPtr<NativeImageCairo> nativeImage = adoptPtr(decoder.createFrameAtIndex(0)); m_imageSurface = nativeImage->surface(); } else { NativeImageCairo* nativeImage = m_image->nativeImageForCurrentFrame(); m_imageSurface = (nativeImage) ? nativeImage->surface() : 0; // 1. For texImage2D with HTMLVideoElment input, assume no PremultiplyAlpha had been applied and the alpha value is 0xFF for each pixel, // which is true at present and may be changed in the future and needs adjustment accordingly. // 2. For texImage2D with HTMLCanvasElement input in which Alpha is already Premultiplied in this port, // do AlphaDoUnmultiply if UNPACK_PREMULTIPLY_ALPHA_WEBGL is set to false. if (!premultiplyAlpha && m_imageHtmlDomSource != HtmlDomVideo) m_alphaOp = AlphaDoUnmultiply; } if (!m_imageSurface) return false; m_imageWidth = cairo_image_surface_get_width(m_imageSurface.get()); m_imageHeight = cairo_image_surface_get_height(m_imageSurface.get()); if (!m_imageWidth || !m_imageHeight) return false; if (cairo_image_surface_get_format(m_imageSurface.get()) != CAIRO_FORMAT_ARGB32) return false; unsigned int srcUnpackAlignment = 1; size_t bytesPerRow = cairo_image_surface_get_stride(m_imageSurface.get()); size_t bitsPerPixel = 32; unsigned padding = bytesPerRow - bitsPerPixel / 8 * m_imageWidth; if (padding) { srcUnpackAlignment = padding + 1; while (bytesPerRow % srcUnpackAlignment) ++srcUnpackAlignment; } m_imagePixelData = cairo_image_surface_get_data(m_imageSurface.get()); m_imageSourceFormat = DataFormatBGRA8; m_imageSourceUnpackAlignment = srcUnpackAlignment; return true; }
cairo_pattern_t* Pattern::createPlatformPattern(const AffineTransform&) const { NativeImageCairo* image = tileImage()->nativeImageForCurrentFrame(); if (!image) return 0; cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image->surface()); // cairo merges patter space and user space itself cairo_matrix_t matrix = m_patternSpaceTransformation; cairo_matrix_invert(&matrix); cairo_pattern_set_matrix(pattern, &matrix); if (m_repeatX || m_repeatY) cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); return pattern; }
DragImageRef createDragImageFromImage(Image* img, RespectImageOrientationEnum) { HBITMAP hbmp = 0; HDC dc = GetDC(0); HDC workingDC = CreateCompatibleDC(dc); if (!workingDC) goto exit; PlatformContextCairo* drawContext = 0; hbmp = allocImage(workingDC, img->size(), &drawContext); if (!hbmp) goto exit; if (!drawContext) { ::DeleteObject(hbmp); hbmp = 0; } cairo_t* cr = drawContext->cr(); cairo_set_source_rgb(cr, 1.0, 0.0, 1.0); cairo_fill_preserve(cr); NativeImageCairo* srcNativeImage = img->nativeImageForCurrentFrame(); cairo_surface_t* srcImage = (srcNativeImage) ? srcNativeImage->surface() : 0; if (srcImage) { // Draw the image. cairo_set_source_surface(cr, srcImage, 0.0, 0.0); cairo_paint(cr); } deallocContext(drawContext); exit: if (workingDC) DeleteDC(workingDC); ReleaseDC(0, dc); return hbmp; }