Commit db4dabc7 authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Use Image::SizeAsFloat() and unsnapped rectangle in ImagePainter

The pixel-snapping of the destination rectangle can end up distorting
the geometry use for painting an SVG image preserveAspectRatio is used -
the larger the aspect ratio, the larger the error.
By passing the unsnapped rectangle to LayoutImageResource::GetImage, and
using Image::SizeAsFloat() to compute the source rectangle of the image,
e can minimize the error and allow the Image in question (an SVGImage)
to perform compensation for the difference in aspect ratio between the
snapped and unsnapped rectangles. This means that the painted result
will better approximate the intended rendering.

Also clean up accesses to the LayoutImageResource and ImageResourceContent
by adding and using local variables for them.

Bug: 812239
Change-Id: I0778648e7dd6fcca778a95123509f15b3519564c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1969831Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#726375}
parent f76a7298
...@@ -187,8 +187,8 @@ void ImagePainter::PaintReplaced(const PaintInfo& paint_info, ...@@ -187,8 +187,8 @@ void ImagePainter::PaintReplaced(const PaintInfo& paint_info,
void ImagePainter::PaintIntoRect(GraphicsContext& context, void ImagePainter::PaintIntoRect(GraphicsContext& context,
const PhysicalRect& dest_rect, const PhysicalRect& dest_rect,
const PhysicalRect& content_rect) { const PhysicalRect& content_rect) {
if (!layout_image_.ImageResource()->HasImage() || const LayoutImageResource& image_resource = *layout_image_.ImageResource();
layout_image_.ImageResource()->ErrorOccurred()) if (!image_resource.HasImage() || image_resource.ErrorOccurred())
return; // FIXME: should we just ASSERT these conditions? (audit all return; // FIXME: should we just ASSERT these conditions? (audit all
// callers). // callers).
...@@ -197,11 +197,11 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context, ...@@ -197,11 +197,11 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
return; return;
scoped_refptr<Image> image = scoped_refptr<Image> image =
layout_image_.ImageResource()->GetImage(pixel_snapped_dest_rect.Size()); image_resource.GetImage(FloatSize(dest_rect.size));
if (!image || image->IsNull()) if (!image || image->IsNull())
return; return;
FloatRect src_rect = FloatRect(image->Rect()); FloatRect src_rect(FloatPoint(), image->SizeAsFloat());
// If the content rect requires clipping, adjust |srcRect| and // If the content rect requires clipping, adjust |srcRect| and
// |pixelSnappedDestRect| over using a clip. // |pixelSnappedDestRect| over using a clip.
if (!content_rect.Contains(dest_rect)) { if (!content_rect.Contains(dest_rect)) {
...@@ -249,17 +249,19 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context, ...@@ -249,17 +249,19 @@ void ImagePainter::PaintIntoRect(GraphicsContext& context,
layout_image_.StyleRef().HasFilterInducingProperty(), layout_image_.StyleRef().HasFilterInducingProperty(),
SkBlendMode::kSrcOver, SkBlendMode::kSrcOver,
LayoutObject::ShouldRespectImageOrientation(&layout_image_)); LayoutObject::ShouldRespectImageOrientation(&layout_image_));
ImageResourceContent* image_content = image_resource.CachedImage();
if ((IsA<HTMLImageElement>(node) || IsA<HTMLVideoElement>(node)) && if ((IsA<HTMLImageElement>(node) || IsA<HTMLVideoElement>(node)) &&
!context.ContextDisabled() && layout_image_.CachedImage() && !context.ContextDisabled() && image_content &&
layout_image_.CachedImage()->IsLoaded()) { image_content->IsLoaded()) {
LocalDOMWindow* window = layout_image_.GetDocument().domWindow(); LocalDOMWindow* window = layout_image_.GetDocument().domWindow();
DCHECK(window); DCHECK(window);
ImageElementTiming::From(*window).NotifyImagePainted( ImageElementTiming::From(*window).NotifyImagePainted(
&layout_image_, layout_image_.CachedImage(), &layout_image_, image_content,
context.GetPaintController().CurrentPaintChunkProperties()); context.GetPaintController().CurrentPaintChunkProperties());
} }
PaintTimingDetector::NotifyImagePaint( PaintTimingDetector::NotifyImagePaint(
layout_image_, image->Size(), layout_image_.CachedImage(), layout_image_, image->Size(), image_content,
context.GetPaintController().CurrentPaintChunkProperties()); context.GetPaintController().CurrentPaintChunkProperties());
} }
......
...@@ -39,6 +39,7 @@ class PLATFORM_EXPORT GeneratedImage : public Image { ...@@ -39,6 +39,7 @@ class PLATFORM_EXPORT GeneratedImage : public Image {
bool HasIntrinsicSize() const override { return false; } bool HasIntrinsicSize() const override { return false; }
IntSize Size() const override { return RoundedIntSize(size_); } IntSize Size() const override { return RoundedIntSize(size_); }
FloatSize SizeAsFloat() const override { return size_; }
// Assume that generated content has no decoded data we need to worry about // Assume that generated content has no decoded data we need to worry about
void DestroyDecodedData() override {} void DestroyDecodedData() override {}
......
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-sizing/#intrinsic-sizes">
<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
<style>
.target {
height: 12.5px;
background-color: red;
display: block;
}
</style>
<p>Test passes if there is a filled green square.</p>
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 12'><rect width='96' height='12' fill='green'/></svg>"
class="target">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment