void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace colorSpace, CompositeOperator compositeOp, BlendMode, RespectImageOrientationEnum shouldRespectImageOrientation) { // Spin the animation to the correct frame before we try to draw it, so we // don't draw an old frame and then immediately need to draw a newer one, // causing flicker and wasting CPU. startAnimation(); RefPtr<NativeImageSkia> bm = nativeImageForCurrentFrame(); if (!bm) return; // It's too early and we don't have an image yet. FloatRect normDstRect = normalizeRect(dstRect); FloatRect normSrcRect = normalizeRect(srcRect); normSrcRect.intersect(FloatRect(0, 0, bm->bitmap().width(), bm->bitmap().height())); if (normSrcRect.isEmpty() || normDstRect.isEmpty()) return; // Nothing to draw. ImageOrientation orientation = DefaultImageOrientation; if (shouldRespectImageOrientation == RespectImageOrientation) orientation = frameOrientationAtIndex(m_currentFrame); GraphicsContextStateSaver saveContext(*ctxt, false); if (orientation != DefaultImageOrientation) { saveContext.save(); // ImageOrientation expects the origin to be at (0, 0) ctxt->translate(normDstRect.x(), normDstRect.y()); normDstRect.setLocation(FloatPoint()); ctxt->concatCTM(orientation.transformFromDefault(normDstRect.size())); if (orientation.usesWidthAsHeight()) { // The destination rect 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. normDstRect = FloatRect(normDstRect.x(), normDstRect.y(), normDstRect.height(), normDstRect.width()); } } paintSkBitmap(ctxt->platformContext(), *bm, normSrcRect, normDstRect, WebCoreCompositeToSkiaComposite(compositeOp)); if (ImageObserver* observer = imageObserver()) observer->didDraw(this); }
PassOwnPtr<DragImage> DragImage::create(Image* image, RespectImageOrientationEnum shouldRespectImageOrientation, float deviceScaleFactor) { if (!image) return nullptr; RefPtr<NativeImageSkia> bitmap = image->nativeImageForCurrentFrame(); if (!bitmap) return nullptr; if (image->isBitmapImage()) { ImageOrientation orientation = DefaultImageOrientation; BitmapImage* bitmapImage = toBitmapImage(image); IntSize sizeRespectingOrientation = bitmapImage->sizeRespectingOrientation(); if (shouldRespectImageOrientation == RespectImageOrientation) orientation = bitmapImage->currentFrameOrientation(); if (orientation != DefaultImageOrientation) { FloatRect destRect(FloatPoint(), sizeRespectingOrientation); if (orientation.usesWidthAsHeight()) destRect = destRect.transposedRect(); SkBitmap skBitmap; skBitmap.setConfig( SkBitmap::kARGB_8888_Config, sizeRespectingOrientation.width(), sizeRespectingOrientation.height()); if (!skBitmap.allocPixels()) return nullptr; SkCanvas canvas(skBitmap); canvas.concat(affineTransformToSkMatrix(orientation.transformFromDefault(sizeRespectingOrientation))); canvas.drawBitmapRect(bitmap->bitmap(), 0, destRect); return adoptPtr(new DragImage(skBitmap, deviceScaleFactor)); } } SkBitmap skBitmap; #if defined(SBROWSER_GPU_RASTERIZATION_ENABLE) if (!bitmap->bitmap().copyTo(&skBitmap, kPMColor_SkColorType)) #else if (!bitmap->bitmap().copyTo(&skBitmap, SkBitmap::kARGB_8888_Config)) #endif return nullptr; return adoptPtr(new DragImage(skBitmap, deviceScaleFactor)); }
DragImageRef createDragImageFromImage(Image* image, RespectImageOrientationEnum shouldRespectImageOrientation) { if (!image) return 0; NativeImageSkia* bitmap = image->nativeImageForCurrentFrame(); if (!bitmap) return 0; DragImageChromium* dragImageChromium = new DragImageChromium; dragImageChromium->bitmap = new SkBitmap(); dragImageChromium->resolutionScale = bitmap->resolutionScale(); if (image->isBitmapImage()) { ImageOrientation orientation = DefaultImageOrientation; BitmapImage* bitmapImage = static_cast<BitmapImage*>(image); IntSize sizeRespectingOrientation = bitmapImage->sizeRespectingOrientation(); if (shouldRespectImageOrientation == RespectImageOrientation) orientation = bitmapImage->currentFrameOrientation(); if (orientation != DefaultImageOrientation) { // Construct a correctly-rotated copy of the image to use as the drag image. dragImageChromium->bitmap->setConfig( SkBitmap::kARGB_8888_Config, sizeRespectingOrientation.width(), sizeRespectingOrientation.height()); dragImageChromium->bitmap->allocPixels(); FloatRect destRect(FloatPoint(), sizeRespectingOrientation); SkCanvas canvas(*dragImageChromium->bitmap); canvas.concat(orientation.transformFromDefault(sizeRespectingOrientation)); if (orientation.usesWidthAsHeight()) destRect = FloatRect(destRect.x(), destRect.y(), destRect.height(), destRect.width()); canvas.drawBitmapRect(bitmap->bitmap(), 0, destRect); return dragImageChromium; } } bitmap->bitmap().copyTo(dragImageChromium->bitmap, SkBitmap::kARGB_8888_Config); return dragImageChromium; }
PassRefPtr<SkImage> DragImage::resizeAndOrientImage(PassRefPtr<SkImage> image, ImageOrientation orientation, FloatSize imageScale, float opacity, InterpolationQuality interpolationQuality) { IntSize size(image->width(), image->height()); size.scale(imageScale.width(), imageScale.height()); AffineTransform transform; if (orientation != DefaultImageOrientation) { if (orientation.usesWidthAsHeight()) size = size.transposedSize(); transform *= orientation.transformFromDefault(size); } transform.scaleNonUniform(imageScale.width(), imageScale.height()); if (size.isEmpty()) return nullptr; if (transform.isIdentity() && opacity == 1) { // Nothing to adjust, just use the original. ASSERT(image->width() == size.width()); ASSERT(image->height() == size.height()); return image; } RefPtr<SkSurface> surface = adoptRef(SkSurface::NewRasterN32Premul(size.width(), size.height())); if (!surface) return nullptr; SkPaint paint; ASSERT(opacity >= 0 && opacity <= 1); paint.setAlpha(opacity * 255); paint.setFilterQuality(interpolationQuality == InterpolationNone ? kNone_SkFilterQuality : kHigh_SkFilterQuality); SkCanvas* canvas = surface->getCanvas(); canvas->clear(SK_ColorTRANSPARENT); canvas->concat(affineTransformToSkMatrix(transform)); canvas->drawImage(image.get(), 0, 0, &paint); return adoptRef(surface->newImageSnapshot()); }
PassOwnPtr<DragImage> DragImage::create(Image* image, RespectImageOrientationEnum shouldRespectImageOrientation, float deviceScaleFactor) { if (!image) return nullptr; RefPtr<NativeImageSkia> bitmap = image->nativeImageForCurrentFrame(); if (!bitmap) return nullptr; if (image->isBitmapImage()) { ImageOrientation orientation = DefaultImageOrientation; BitmapImage* bitmapImage = toBitmapImage(image); IntSize sizeRespectingOrientation = bitmapImage->sizeRespectingOrientation(); if (shouldRespectImageOrientation == RespectImageOrientation) orientation = bitmapImage->currentFrameOrientation(); if (orientation != DefaultImageOrientation) { FloatRect destRect(FloatPoint(), sizeRespectingOrientation); if (orientation.usesWidthAsHeight()) destRect = destRect.transposedRect(); SkBitmap skBitmap; if (!skBitmap.tryAllocN32Pixels(sizeRespectingOrientation.width(), sizeRespectingOrientation.height())) return nullptr; SkCanvas canvas(skBitmap); canvas.concat(affineTransformToSkMatrix(orientation.transformFromDefault(sizeRespectingOrientation))); canvas.drawBitmapRect(bitmap->bitmap(), 0, destRect); return adoptPtr(new DragImage(skBitmap, deviceScaleFactor)); } } SkBitmap skBitmap; if (!bitmap->bitmap().copyTo(&skBitmap, kN32_SkColorType)) return nullptr; return adoptPtr(new DragImage(skBitmap, deviceScaleFactor)); }