#include "platform/LengthFunctions.h"
#include "platform/TraceEvent.h"
#include "platform/geometry/IntRect.h"
+#include "platform/graphics/DisplayList.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "platform/graphics/ImageBuffer.h"
#include "platform/graphics/ImageObserver.h"
return buffer->copyImage(CopyBackingStore)->nativeImageForCurrentFrame();
}
-void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize, float zoom, const FloatRect& srcRect,
- const FloatSize& scale, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& dstRect, blink::WebBlendMode blendMode, const IntSize& repeatSpacing)
+void SVGImage::drawPatternForContainer(GraphicsContext* context, const FloatSize containerSize,
+ float zoom, const FloatRect& srcRect, const FloatSize& tileScale, const FloatPoint& phase,
+ CompositeOperator compositeOp, const FloatRect& dstRect, blink::WebBlendMode blendMode,
+ const IntSize& repeatSpacing)
{
- FloatRect zoomedContainerRect = FloatRect(FloatPoint(), containerSize);
- zoomedContainerRect.scale(zoom);
-
- // The ImageBuffer size needs to be scaled to match the final resolution.
- // FIXME: No need to get the full CTM here, we just need the scale.
- // FIXME: See crbug.com/382491. This scale does not reflect compositor applied
- // scale factors, such a High DPI or device zoom.
- AffineTransform transform = context->getCTM();
- FloatSize imageBufferScale = FloatSize(transform.xScale(), transform.yScale());
- ASSERT(imageBufferScale.width());
- ASSERT(imageBufferScale.height());
-
- FloatSize scaleWithoutCTM(scale.width() / imageBufferScale.width(), scale.height() / imageBufferScale.height());
-
- FloatRect imageBufferSize = zoomedContainerRect;
- imageBufferSize.scale(imageBufferScale.width(), imageBufferScale.height());
-
- OwnPtr<ImageBuffer> buffer = ImageBuffer::create(expandedIntSize(imageBufferSize.size()));
- if (!buffer) // Failed to allocate buffer.
- return;
-
- drawForContainer(buffer->context(), containerSize, zoom, imageBufferSize, zoomedContainerRect, CompositeSourceOver, blink::WebBlendModeNormal);
- RefPtr<Image> image = buffer->copyImage(DontCopyBackingStore, Unscaled);
-
- // Adjust the source rect and transform due to the image buffer's scaling.
- FloatRect scaledSrcRect = srcRect;
- scaledSrcRect.scale(imageBufferScale.width(), imageBufferScale.height());
-
- image->drawPattern(context, scaledSrcRect, scaleWithoutCTM, phase, compositeOp, dstRect, blendMode, repeatSpacing);
+ // Tile adjusted for scaling/stretch.
+ FloatRect tile(srcRect);
+ tile.scale(tileScale.width(), tileScale.height());
+
+ // Expand the tile to account for repeat spacing.
+ FloatRect spacedTile(tile);
+ spacedTile.expand(repeatSpacing);
+
+ // Record using a dedicated GC, to avoid inheriting unwanted state (pending color filters
+ // for example must be applied atomically during the final fill/composite phase).
+ GraphicsContext recordingContext(0);
+ recordingContext.beginRecording(spacedTile);
+ // When generating an expanded tile, make sure we don't draw into the spacing area.
+ if (tile != spacedTile)
+ recordingContext.clipRect(tile);
+ drawForContainer(&recordingContext, containerSize, zoom, tile, srcRect, CompositeSourceOver,
+ blink::WebBlendModeNormal);
+ RefPtr<DisplayList> tileDisplayList = recordingContext.endRecording();
+
+ SkMatrix patternTransform;
+ patternTransform.setTranslate(phase.x() + tile.x(), phase.y() + tile.y());
+ SkRect tileRect = SkRect::MakeWH(spacedTile.width(), spacedTile.height());
+ RefPtr<SkShader> patternShader = adoptRef(SkShader::CreatePictureShader(
+ tileDisplayList->picture().get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
+ &patternTransform, &tileRect));
+
+ SkPaint paint;
+ paint.setShader(patternShader.get());
+ paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp, blendMode));
+ paint.setColorFilter(context->colorFilter());
+ context->drawRect(dstRect, paint);
}
void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp, blink::WebBlendMode blendMode)
page->settings().setAcceleratedCompositingEnabled(false);
}
- RefPtr<LocalFrame> frame;
+ RefPtrWillBeRawPtr<LocalFrame> frame = nullptr;
{
TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame");
frame = LocalFrame::create(dummyFrameLoaderClient, &page->frameHost(), 0);
m_page = page.release();
TRACE_EVENT0("blink", "SVGImage::dataChanged::load");
- loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), "image/svg+xml", "UTF-8", KURL(), ForceSynchronousLoad)));
+ loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), AtomicString("image/svg+xml", AtomicString::ConstructFromLiteral),
+ AtomicString("UTF-8", AtomicString::ConstructFromLiteral), KURL(), ForceSynchronousLoad)));
// Set the intrinsic size before a container size is available.
m_intrinsicSize = containerSize();
}