void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect, const FloatSize& scale, const FloatPoint& phase, SkBlendMode compositeOp, const FloatRect& destRect, const FloatSize& repeatSpacing) { TRACE_EVENT0("skia", "Image::drawPattern"); sk_sp<SkImage> image = imageForCurrentFrame(); if (!image) return; FloatRect normSrcRect = floatSrcRect; normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); if (destRect.isEmpty() || normSrcRect.isEmpty()) return; // nothing to draw SkMatrix localMatrix; // We also need to translate it such that the origin of the pattern is the // origin of the destination rect, which is what WebKit expects. Skia uses // the coordinate system origin as the base for the pattern. If WebKit wants // a shifted image, it will shift it from there using the localMatrix. const float adjustedX = phase.x() + normSrcRect.x() * scale.width(); const float adjustedY = phase.y() + normSrcRect.y() * scale.height(); localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjustedY)); // Because no resizing occurred, the shader transform should be // set to the pattern's transform, which just includes scale. localMatrix.preScale(scale.width(), scale.height()); // Fetch this now as subsetting may swap the image. auto imageID = image->uniqueID(); image = image->makeSubset(enclosingIntRect(normSrcRect)); if (!image) return; { SkPaint paint = context.fillPaint(); paint.setColor(SK_ColorBLACK); paint.setBlendMode(static_cast<SkBlendMode>(compositeOp)); paint.setFilterQuality( context.computeFilterQuality(this, destRect, normSrcRect)); paint.setAntiAlias(context.shouldAntialias()); paint.setShader(createPatternShader( image.get(), localMatrix, paint, FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.height() / scale.height()))); context.drawRect(destRect, paint); } if (currentFrameIsLazyDecoded()) PlatformInstrumentation::didDrawLazyPixelRef(imageID); }
void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImageOrientation, ImageClampingMode clampMode) { TRACE_EVENT0("skia", "BitmapImage::draw"); RefPtr<SkImage> image = imageForCurrentFrame(); if (!image) return; // It's too early and we don't have an image yet. FloatRect adjustedSrcRect = srcRect; adjustedSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) return; // Nothing to draw. ImageOrientation orientation = DefaultImageOrientation; if (shouldRespectImageOrientation == RespectImageOrientation) orientation = frameOrientationAtIndex(m_currentFrame); int initialSaveCount = canvas->getSaveCount(); FloatRect adjustedDstRect = dstRect; if (orientation != DefaultImageOrientation) { canvas->save(); // ImageOrientation expects the origin to be at (0, 0) canvas->translate(adjustedDstRect.x(), adjustedDstRect.y()); adjustedDstRect.setLocation(FloatPoint()); canvas->concat(affineTransformToSkMatrix(orientation.transformFromDefault(adjustedDstRect.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. adjustedDstRect = FloatRect(adjustedDstRect.x(), adjustedDstRect.y(), adjustedDstRect.height(), adjustedDstRect.width()); } } SkRect skSrcRect = adjustedSrcRect; canvas->drawImageRect(image.get(), skSrcRect, adjustedDstRect, &paint, WebCoreClampingModeToSkiaRectConstraint(clampMode)); canvas->restoreToCount(initialSaveCount); if (currentFrameIsLazyDecoded()) PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID()); if (ImageObserver* observer = imageObserver()) observer->didDraw(this); startAnimation(); }
bool Image::applyShader(SkPaint& paint, const SkMatrix& localMatrix) { // Default shader impl: attempt to build a shader based on the current frame // SkImage. sk_sp<SkImage> image = imageForCurrentFrame(); if (!image) return false; paint.setShader(image->makeShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix)); // Animation is normally refreshed in draw() impls, which we don't call when // painting via shaders. startAnimation(); return true; }
bool Image::deprecatedBitmapForCurrentFrame(SkBitmap* bitmap) { RefPtr<SkImage> image = imageForCurrentFrame(); return image && image->asLegacyBitmap(bitmap, SkImage::kRO_LegacyBitmapMode); }
bool Image::isTextureBacked() { RefPtr<SkImage> image = imageForCurrentFrame(); return image ? image->isTextureBacked() : false; }