| Index: Source/platform/graphics/Image.cpp
|
| diff --git a/Source/platform/graphics/Image.cpp b/Source/platform/graphics/Image.cpp
|
| index 368a0373f78afd8d3b3ae495b415c2ef9a31c55d..ccee6b77f7fa5823aa504a897df9a4bf30028f62 100644
|
| --- a/Source/platform/graphics/Image.cpp
|
| +++ b/Source/platform/graphics/Image.cpp
|
| @@ -29,16 +29,20 @@
|
|
|
| #include "platform/Length.h"
|
| #include "platform/MIMETypeRegistry.h"
|
| +#include "platform/PlatformInstrumentation.h"
|
| +#include "platform/RuntimeEnabledFeatures.h"
|
| #include "platform/SharedBuffer.h"
|
| #include "platform/TraceEvent.h"
|
| #include "platform/geometry/FloatPoint.h"
|
| #include "platform/geometry/FloatRect.h"
|
| #include "platform/geometry/FloatSize.h"
|
| #include "platform/graphics/BitmapImage.h"
|
| +#include "platform/graphics/DeferredImageDecoder.h"
|
| #include "platform/graphics/GraphicsContext.h"
|
| #include "platform/graphics/GraphicsContextStateSaver.h"
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/WebData.h"
|
| +#include "third_party/skia/include/core/SkCanvas.h"
|
| #include "third_party/skia/include/core/SkImage.h"
|
| #include "wtf/MainThread.h"
|
| #include "wtf/StdLibExtras.h"
|
| @@ -218,12 +222,77 @@ void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const Flo
|
| startAnimation();
|
| }
|
|
|
| +static SkBitmap createBitmapWithSpace(const SkBitmap& bitmap, int spaceWidth, int spaceHeight)
|
| +{
|
| + SkImageInfo info = bitmap.info();
|
| + info = SkImageInfo::Make(info.width() + spaceWidth, info.height() + spaceHeight, info.colorType(), kPremul_SkAlphaType);
|
| +
|
| + SkBitmap result;
|
| + result.allocPixels(info);
|
| + result.eraseColor(SK_ColorTRANSPARENT);
|
| + bitmap.copyPixelsTo(reinterpret_cast<uint8_t*>(result.getPixels()), result.rowBytes() * result.height(), result.rowBytes());
|
| +
|
| + return result;
|
| +}
|
| +
|
| void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect, const FloatSize& scale,
|
| - const FloatPoint& phase, SkXfermode::Mode op, const FloatRect& destRect, const IntSize& repeatSpacing)
|
| + const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& destRect, const IntSize& repeatSpacing)
|
| {
|
| TRACE_EVENT0("skia", "Image::drawPattern");
|
| - if (RefPtr<NativeImageSkia> bitmap = nativeImageForCurrentFrame())
|
| - bitmap->drawPattern(context, adjustForNegativeSize(floatSrcRect), scale, phase, op, destRect, repeatSpacing);
|
| + SkBitmap bitmap;
|
| + if (!bitmapForCurrentFrame(&bitmap))
|
| + return;
|
| +
|
| + FloatRect normSrcRect = floatSrcRect;
|
| +
|
| + normSrcRect.intersect(FloatRect(0, 0, bitmap.width(), bitmap.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());
|
| +
|
| + SkBitmap bitmapToPaint;
|
| + bitmap.extractSubset(&bitmapToPaint, enclosingIntRect(normSrcRect));
|
| + if (!repeatSpacing.isZero()) {
|
| + SkScalar ctmScaleX = 1.0;
|
| + SkScalar ctmScaleY = 1.0;
|
| +
|
| + if (!RuntimeEnabledFeatures::slimmingPaintEnabled()) {
|
| + AffineTransform ctm = context->getCTM();
|
| + ctmScaleX = ctm.xScale();
|
| + ctmScaleY = ctm.yScale();
|
| + }
|
| +
|
| + bitmapToPaint = createBitmapWithSpace(
|
| + bitmapToPaint,
|
| + repeatSpacing.width() * ctmScaleX / scale.width(),
|
| + repeatSpacing.height() * ctmScaleY / scale.height());
|
| + }
|
| + RefPtr<SkShader> shader = adoptRef(SkShader::CreateBitmapShader(bitmapToPaint, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
|
| +
|
| + bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap);
|
| + {
|
| + SkPaint paint;
|
| + int initialSaveCount = context->preparePaintForDrawRectToRect(&paint, floatSrcRect,
|
| + destRect, compositeOp, !bitmap.isOpaque(), isLazyDecoded, bitmap.isImmutable());
|
| + paint.setShader(shader.get());
|
| + context->drawRect(destRect, paint);
|
| + context->canvas()->restoreToCount(initialSaveCount);
|
| + }
|
| +
|
| + if (isLazyDecoded)
|
| + PlatformInstrumentation::didDrawLazyPixelRef(bitmap.getGenerationID());
|
| }
|
|
|
| void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio)
|
| @@ -240,6 +309,11 @@ PassRefPtr<Image> Image::imageForDefaultFrame()
|
| return image.release();
|
| }
|
|
|
| +bool Image::bitmapForCurrentFrame(SkBitmap* bitmap)
|
| +{
|
| + return false;
|
| +}
|
| +
|
| PassRefPtr<SkImage> Image::skImage()
|
| {
|
| return nullptr;
|
|
|