image-rendering: -webkit-optimize-contrast not working for background images
https://bugs.webkit.org/show_bug.cgi?id=97991
Reviewed by Darin Adler.
Source/WebCore:
Don't equate "pixelated" and "crisp-edges" values for image-rendering with low
quality scaling; they should map to InterpolationNone, not InterpolationLow.
To support this change ImageQualityController to return a InterpolationQuality
from the renamed chooseInterpolationQuality(). If the returned value is not
InterpolationDefault, set the GraphicsContext image interpolation when drawing
images and image buffers.
Remove the redundant "useLowQualityScale" from
Test: fast/images/image-rendering-interpolation.html
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::paint):
* html/HTMLCanvasElement.h:
* page/DragController.cpp:
(WebCore::DragController::doImageDrag):
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawImage):
(WebCore::GraphicsContext::drawTiledImage):
(WebCore::GraphicsContext::drawImageBuffer):
(WebCore::GraphicsContext::drawConsumingImageBuffer):
(WebCore::InterpolationQualityMaintainer::InterpolationQualityMaintainer): Deleted.
(WebCore::InterpolationQualityMaintainer::~InterpolationQualityMaintainer): Deleted.
* platform/graphics/GraphicsContext.h:
(WebCore::ImagePaintingOptions::ImagePaintingOptions):
(WebCore::ImagePaintingOptions::usesDefaultInterpolation):
(WebCore::InterpolationQualityMaintainer::InterpolationQualityMaintainer):
(WebCore::InterpolationQualityMaintainer::~InterpolationQualityMaintainer):
* platform/graphics/GraphicsTypes.h:
* platform/graphics/ImageBuffer.h:
* platform/graphics/cg/ImageBufferCG.cpp:
(WebCore::ImageBuffer::drawConsuming):
(WebCore::ImageBuffer::draw):
* rendering/ImageQualityController.cpp:
(WebCore::ImageQualityController::interpolationQualityFromStyle):
(WebCore::ImageQualityController::chooseInterpolationQuality):
(WebCore::ImageQualityController::ImageQualityController): Deleted.
(WebCore::ImageQualityController::shouldPaintAtLowQuality): Deleted.
* rendering/ImageQualityController.h:
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::chooseInterpolationQuality):
(WebCore::RenderBoxModelObject::paintFillLayerExtended):
(WebCore::RenderBoxModelObject::shouldPaintAtLowQuality): Deleted.
* rendering/RenderBoxModelObject.h:
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::paintSnapshotImage):
* rendering/RenderHTMLCanvas.cpp:
(WebCore::RenderHTMLCanvas::paintReplaced):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::paintIntoRect):
* rendering/RenderSnapshottedPlugIn.cpp:
(WebCore::RenderSnapshottedPlugIn::paintSnapshot):
* rendering/style/RenderStyle.h:
LayoutTests:
* fast/images/image-rendering-interpolation-expected.html: Added.
* fast/images/image-rendering-interpolation.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@195848 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 69fd47c..384bc04 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2016-01-29 Simon Fraser <simon.fraser@apple.com>
+
+ image-rendering: -webkit-optimize-contrast not working for background images
+ https://bugs.webkit.org/show_bug.cgi?id=97991
+
+ Reviewed by Darin Adler.
+
+ * fast/images/image-rendering-interpolation-expected.html: Added.
+ * fast/images/image-rendering-interpolation.html: Added.
+
2016-01-29 Brady Eidson <beidson@apple.com>
Modern IDB: storage/indexeddb/modern/index-3.html fails.
diff --git a/LayoutTests/fast/images/image-rendering-interpolation-expected.html b/LayoutTests/fast/images/image-rendering-interpolation-expected.html
new file mode 100644
index 0000000..8ca6fc6
--- /dev/null
+++ b/LayoutTests/fast/images/image-rendering-interpolation-expected.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .clipper {
+ display: inline-block;
+ margin: 2px;
+ height: 100px;
+ width: 100px;
+ overflow: hidden;
+ border: 1px solid black;
+ }
+ img {
+ height: 1100px;
+ width: 1100px;
+ }
+
+ .backgrounder {
+ height: 1100px;
+ width: 1100px;
+ background-image: url('resources/grid-small.png');
+ background-size: 100%;
+ }
+ </style>
+</head>
+<body>
+
+<div class="clipper">
+ <img src="resources/grid-small.png" width="11" height="11">
+</div>
+
+<div class="clipper">
+</div>
+
+<div class="clipper">
+</div>
+
+<div class="clipper">
+ <div class="backgrounder"></div>
+</div>
+
+<div class="clipper">
+</div>
+
+<div class="clipper">
+</div>
+
+</body>
+</html>
diff --git a/LayoutTests/fast/images/image-rendering-interpolation.html b/LayoutTests/fast/images/image-rendering-interpolation.html
new file mode 100644
index 0000000..1dfd7da
--- /dev/null
+++ b/LayoutTests/fast/images/image-rendering-interpolation.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ .clipper {
+ display: inline-block;
+ margin: 2px;
+ height: 100px;
+ width: 100px;
+ overflow: hidden;
+ border: 1px solid black;
+ }
+ img {
+ image-rendering: pixelated;
+ height: 1100px;
+ width: 1100px;
+ }
+
+ .backgrounder {
+ height: 1100px;
+ width: 1100px;
+ background-image: url('resources/grid-small.png');
+ background-size: 100%;
+ }
+ </style>
+</head>
+<body>
+
+<div class="clipper">
+ <img src="resources/grid-small.png" width="11" height="11" style="image-rendering: auto;">
+</div>
+
+<div class="clipper">
+ <img src="resources/grid-small.png" width="11" height="11" style="image-rendering: pixelated;">
+</div>
+
+<div class="clipper">
+ <img src="resources/grid-small.png" width="11" height="11" style="image-rendering: crisp-edges;">
+</div>
+
+<div class="clipper">
+ <div class="backgrounder" style="image-rendering: auto;"></div>
+</div>
+
+<div class="clipper">
+ <div class="backgrounder" style="image-rendering: pixelated;"></div>
+</div>
+
+<div class="clipper">
+ <div class="backgrounder" style="image-rendering: crisp-edges;"></div>
+</div>
+
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index e51be2c..02338b5 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,65 @@
+2016-01-29 Simon Fraser <simon.fraser@apple.com>
+
+ image-rendering: -webkit-optimize-contrast not working for background images
+ https://bugs.webkit.org/show_bug.cgi?id=97991
+
+ Reviewed by Darin Adler.
+
+ Don't equate "pixelated" and "crisp-edges" values for image-rendering with low
+ quality scaling; they should map to InterpolationNone, not InterpolationLow.
+
+ To support this change ImageQualityController to return a InterpolationQuality
+ from the renamed chooseInterpolationQuality(). If the returned value is not
+ InterpolationDefault, set the GraphicsContext image interpolation when drawing
+ images and image buffers.
+
+ Remove the redundant "useLowQualityScale" from
+
+ Test: fast/images/image-rendering-interpolation.html
+
+ * html/HTMLCanvasElement.cpp:
+ (WebCore::HTMLCanvasElement::paint):
+ * html/HTMLCanvasElement.h:
+ * page/DragController.cpp:
+ (WebCore::DragController::doImageDrag):
+ * platform/graphics/GraphicsContext.cpp:
+ (WebCore::GraphicsContext::drawImage):
+ (WebCore::GraphicsContext::drawTiledImage):
+ (WebCore::GraphicsContext::drawImageBuffer):
+ (WebCore::GraphicsContext::drawConsumingImageBuffer):
+ (WebCore::InterpolationQualityMaintainer::InterpolationQualityMaintainer): Deleted.
+ (WebCore::InterpolationQualityMaintainer::~InterpolationQualityMaintainer): Deleted.
+ * platform/graphics/GraphicsContext.h:
+ (WebCore::ImagePaintingOptions::ImagePaintingOptions):
+ (WebCore::ImagePaintingOptions::usesDefaultInterpolation):
+ (WebCore::InterpolationQualityMaintainer::InterpolationQualityMaintainer):
+ (WebCore::InterpolationQualityMaintainer::~InterpolationQualityMaintainer):
+ * platform/graphics/GraphicsTypes.h:
+ * platform/graphics/ImageBuffer.h:
+ * platform/graphics/cg/ImageBufferCG.cpp:
+ (WebCore::ImageBuffer::drawConsuming):
+ (WebCore::ImageBuffer::draw):
+ * rendering/ImageQualityController.cpp:
+ (WebCore::ImageQualityController::interpolationQualityFromStyle):
+ (WebCore::ImageQualityController::chooseInterpolationQuality):
+ (WebCore::ImageQualityController::ImageQualityController): Deleted.
+ (WebCore::ImageQualityController::shouldPaintAtLowQuality): Deleted.
+ * rendering/ImageQualityController.h:
+ * rendering/RenderBoxModelObject.cpp:
+ (WebCore::RenderBoxModelObject::chooseInterpolationQuality):
+ (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+ (WebCore::RenderBoxModelObject::shouldPaintAtLowQuality): Deleted.
+ * rendering/RenderBoxModelObject.h:
+ * rendering/RenderEmbeddedObject.cpp:
+ (WebCore::RenderEmbeddedObject::paintSnapshotImage):
+ * rendering/RenderHTMLCanvas.cpp:
+ (WebCore::RenderHTMLCanvas::paintReplaced):
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::paintIntoRect):
+ * rendering/RenderSnapshottedPlugIn.cpp:
+ (WebCore::RenderSnapshottedPlugIn::paintSnapshot):
+ * rendering/style/RenderStyle.h:
+
2016-01-29 Brady Eidson <beidson@apple.com>
Modern IDB: storage/indexeddb/modern/index-3.html fails.
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index f6f5165..7b35699 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -403,7 +403,7 @@
}
-void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r, bool useLowQualityScale)
+void HTMLCanvasElement::paint(GraphicsContext& context, const LayoutRect& r)
{
// Clear the dirty rect
m_dirtyRect = FloatRect();
@@ -426,9 +426,9 @@
#if ENABLE(CSS_IMAGE_ORIENTATION)
orientationDescription.setImageOrientationEnum(renderer()->style().imageOrientation());
#endif
- context.drawImage(*m_presentedImage, snappedIntRect(r), ImagePaintingOptions(orientationDescription, useLowQualityScale));
+ context.drawImage(*m_presentedImage, snappedIntRect(r), ImagePaintingOptions(orientationDescription));
} else
- context.drawImageBuffer(*imageBuffer, snappedIntRect(r), useLowQualityScale);
+ context.drawImageBuffer(*imageBuffer, snappedIntRect(r));
}
}
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 02dbc57..a774900 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -109,7 +109,7 @@
void didDraw(const FloatRect&);
void notifyObserversCanvasChanged(const FloatRect&);
- void paint(GraphicsContext&, const LayoutRect&, bool useLowQualityScale = false);
+ void paint(GraphicsContext&, const LayoutRect&);
GraphicsContext* drawingContext() const;
GraphicsContext* existingDrawingContext() const;
diff --git a/Source/WebCore/page/DragController.cpp b/Source/WebCore/page/DragController.cpp
index 4c52a28..b01683e 100644
--- a/Source/WebCore/page/DragController.cpp
+++ b/Source/WebCore/page/DragController.cpp
@@ -935,10 +935,7 @@
if (!element.renderer())
return;
- ImageOrientationDescription orientationDescription(element.renderer()->shouldRespectImageOrientation());
-#if ENABLE(CSS_IMAGE_ORIENTATION)
- orientationDescription.setImageOrientationEnum(element.renderer()->style().imageOrientation());
-#endif
+ ImageOrientationDescription orientationDescription(element.renderer()->shouldRespectImageOrientation(), element.renderer()->style().imageOrientation());
Image* image = getImage(element);
if (image && image->size().height() * image->size().width() <= MaxOriginalImageArea
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp
index 7ddcc72..965503c 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp
@@ -77,30 +77,6 @@
unsigned m_offset;
};
-class InterpolationQualityMaintainer {
-public:
- explicit InterpolationQualityMaintainer(GraphicsContext& graphicsContext, InterpolationQuality interpolationQualityToUse)
- : m_graphicsContext(graphicsContext)
- , m_currentInterpolationQuality(graphicsContext.imageInterpolationQuality())
- , m_interpolationQualityChanged(m_currentInterpolationQuality != interpolationQualityToUse)
- {
- if (m_interpolationQualityChanged)
- m_graphicsContext.setImageInterpolationQuality(interpolationQualityToUse);
- }
-
- ~InterpolationQualityMaintainer()
- {
- if (m_interpolationQualityChanged)
- m_graphicsContext.setImageInterpolationQuality(m_currentInterpolationQuality);
- }
-
-private:
- GraphicsContext& m_graphicsContext;
- InterpolationQuality m_currentInterpolationQuality;
- bool m_interpolationQualityChanged;
-};
-
-
#define CHECK_FOR_CHANGED_PROPERTY(flag, property) \
if ((m_changeFlags & GraphicsContextState::flag) && (m_state.property != state.property)) \
changeFlags |= GraphicsContextState::flag;
@@ -767,7 +743,7 @@
return;
}
- InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_useLowQualityScale ? InterpolationLow : imageInterpolationQuality());
+ InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_interpolationQuality);
image.draw(*this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode, imagePaintingOptions.m_orientationDescription);
}
@@ -781,7 +757,7 @@
return;
}
- InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_useLowQualityScale ? InterpolationLow : imageInterpolationQuality());
+ InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_interpolationQuality);
image.drawTiled(*this, destination, source, tileSize, spacing, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode);
}
@@ -802,7 +778,7 @@
return;
}
- InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_useLowQualityScale ? InterpolationLow : imageInterpolationQuality());
+ InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_interpolationQuality);
image.drawTiled(*this, destination, source, tileScaleFactor, hRule, vRule, imagePaintingOptions.m_compositeOperator);
}
@@ -821,8 +797,8 @@
if (paintingDisabled())
return;
- InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_useLowQualityScale ? InterpolationLow : imageInterpolationQuality());
- image.draw(*this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode, imagePaintingOptions.m_useLowQualityScale);
+ InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_interpolationQuality);
+ image.draw(*this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode);
}
void GraphicsContext::drawConsumingImageBuffer(std::unique_ptr<ImageBuffer> image, const FloatPoint& destination, const ImagePaintingOptions& imagePaintingOptions)
@@ -846,9 +822,8 @@
if (paintingDisabled() || !image)
return;
- InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_useLowQualityScale ? InterpolationLow : imageInterpolationQuality());
-
- ImageBuffer::drawConsuming(WTFMove(image), *this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode, imagePaintingOptions.m_useLowQualityScale);
+ InterpolationQualityMaintainer interpolationQualityForThisScope(*this, imagePaintingOptions.m_interpolationQuality);
+ ImageBuffer::drawConsuming(WTFMove(image), *this, destination, source, imagePaintingOptions.m_compositeOperator, imagePaintingOptions.m_blendMode);
}
void GraphicsContext::clipRoundedRect(const FloatRoundedRect& rect)
diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h
index 4ffa7c6..a4608e0 100644
--- a/Source/WebCore/platform/graphics/GraphicsContext.h
+++ b/Source/WebCore/platform/graphics/GraphicsContext.h
@@ -102,14 +102,6 @@
WavyStroke,
};
-enum InterpolationQuality {
- InterpolationDefault,
- InterpolationNone,
- InterpolationLow,
- InterpolationMedium,
- InterpolationHigh
-};
-
namespace DisplayList {
class Recorder;
}
@@ -194,34 +186,36 @@
};
struct ImagePaintingOptions {
- ImagePaintingOptions(CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), bool useLowQualityScale = false)
+ ImagePaintingOptions(CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), InterpolationQuality interpolationQuality = InterpolationDefault)
: m_compositeOperator(compositeOperator)
, m_blendMode(blendMode)
, m_orientationDescription(orientationDescription)
- , m_useLowQualityScale(useLowQualityScale)
+ , m_interpolationQuality(interpolationQuality)
{
}
- ImagePaintingOptions(ImageOrientationDescription orientationDescription, bool useLowQualityScale = false, CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal)
+ ImagePaintingOptions(ImageOrientationDescription orientationDescription, InterpolationQuality interpolationQuality = InterpolationDefault, CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal)
: m_compositeOperator(compositeOperator)
, m_blendMode(blendMode)
, m_orientationDescription(orientationDescription)
- , m_useLowQualityScale(useLowQualityScale)
+ , m_interpolationQuality(interpolationQuality)
{
}
- ImagePaintingOptions(bool useLowQualityScale, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal)
+ ImagePaintingOptions(InterpolationQuality interpolationQuality, ImageOrientationDescription orientationDescription = ImageOrientationDescription(), CompositeOperator compositeOperator = CompositeSourceOver, BlendMode blendMode = BlendModeNormal)
: m_compositeOperator(compositeOperator)
, m_blendMode(blendMode)
, m_orientationDescription(orientationDescription)
- , m_useLowQualityScale(useLowQualityScale)
+ , m_interpolationQuality(interpolationQuality)
{
}
+
+ bool usesDefaultInterpolation() const { return m_interpolationQuality == InterpolationDefault; }
CompositeOperator m_compositeOperator;
BlendMode m_blendMode;
ImageOrientationDescription m_orientationDescription;
- bool m_useLowQualityScale;
+ InterpolationQuality m_interpolationQuality;
};
struct GraphicsContextStateChange {
@@ -657,6 +651,34 @@
bool m_saveAndRestore;
};
+class InterpolationQualityMaintainer {
+public:
+ explicit InterpolationQualityMaintainer(GraphicsContext& graphicsContext, InterpolationQuality interpolationQualityToUse)
+ : m_graphicsContext(graphicsContext)
+ , m_currentInterpolationQuality(graphicsContext.imageInterpolationQuality())
+ , m_interpolationQualityChanged(interpolationQualityToUse != InterpolationDefault && m_currentInterpolationQuality != interpolationQualityToUse)
+ {
+ if (m_interpolationQualityChanged)
+ m_graphicsContext.setImageInterpolationQuality(interpolationQualityToUse);
+ }
+
+ explicit InterpolationQualityMaintainer(GraphicsContext& graphicsContext, Optional<InterpolationQuality> interpolationQuality)
+ : InterpolationQualityMaintainer(graphicsContext, interpolationQuality ? interpolationQuality.value() : graphicsContext.imageInterpolationQuality())
+ {
+ }
+
+ ~InterpolationQualityMaintainer()
+ {
+ if (m_interpolationQualityChanged)
+ m_graphicsContext.setImageInterpolationQuality(m_currentInterpolationQuality);
+ }
+
+private:
+ GraphicsContext& m_graphicsContext;
+ InterpolationQuality m_currentInterpolationQuality;
+ bool m_interpolationQualityChanged;
+};
+
} // namespace WebCore
#endif // GraphicsContext_h
diff --git a/Source/WebCore/platform/graphics/GraphicsTypes.h b/Source/WebCore/platform/graphics/GraphicsTypes.h
index 4ef3be8..ede792d 100644
--- a/Source/WebCore/platform/graphics/GraphicsTypes.h
+++ b/Source/WebCore/platform/graphics/GraphicsTypes.h
@@ -75,6 +75,14 @@
SpreadMethodRepeat
};
+enum InterpolationQuality {
+ InterpolationDefault,
+ InterpolationNone,
+ InterpolationLow,
+ InterpolationMedium,
+ InterpolationHigh
+};
+
enum LineCap { ButtCap, RoundCap, SquareCap };
enum LineJoin { MiterJoin, RoundJoin, BevelJoin };
diff --git a/Source/WebCore/platform/graphics/ImageBuffer.h b/Source/WebCore/platform/graphics/ImageBuffer.h
index f419d32..04f9ef9 100644
--- a/Source/WebCore/platform/graphics/ImageBuffer.h
+++ b/Source/WebCore/platform/graphics/ImageBuffer.h
@@ -142,10 +142,10 @@
void flushContext() const;
#endif
- void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, bool useLowQualityScale = false);
+ void draw(GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal);
void drawPattern(GraphicsContext&, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator, const FloatRect& destRect, BlendMode = BlendModeNormal);
- static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal, bool useLowQualityScale = false);
+ static void drawConsuming(std::unique_ptr<ImageBuffer>, GraphicsContext&, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, BlendMode = BlendModeNormal);
inline void genericConvertToLuminanceMask();
diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
index 4866519..387a20a 100644
--- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
+++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
@@ -214,17 +214,17 @@
return DontCopyBackingStore;
}
-void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool useLowQualityScale)
+void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode)
{
- imageBuffer->draw(destContext, destRect, srcRect, op, blendMode, useLowQualityScale);
+ imageBuffer->draw(destContext, destRect, srcRect, op, blendMode);
}
void ImageBuffer::draw(GraphicsContext& destinationContext, const FloatRect& destRect, const FloatRect& srcRect,
- CompositeOperator op, BlendMode blendMode, bool useLowQualityScale)
+ CompositeOperator op, BlendMode blendMode)
{
BackingStoreCopy copyMode = &destinationContext == &context() ? CopyBackingStore : DontCopyBackingStore;
RefPtr<Image> image = copyImage(copyMode);
- destinationContext.drawImage(*image, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription(), useLowQualityScale));
+ destinationContext.drawImage(*image, destRect, srcRect, ImagePaintingOptions(op, blendMode, ImageOrientationDescription()));
}
void ImageBuffer::drawPattern(GraphicsContext& context, const FloatRect& srcRect, const AffineTransform& patternTransform,
diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
index 95e4b15..846396c 100644
--- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
+++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
@@ -264,11 +264,11 @@
return image;
}
-void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool useLowQualityScale)
+void ImageBuffer::drawConsuming(std::unique_ptr<ImageBuffer> imageBuffer, GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode)
{
#if USE(IOSURFACE_CANVAS_BACKING_STORE)
if (!imageBuffer->m_data.surface) {
- imageBuffer->draw(destContext, destRect, srcRect, op, blendMode, useLowQualityScale);
+ imageBuffer->draw(destContext, destRect, srcRect, op, blendMode);
return;
}
@@ -283,11 +283,11 @@
adjustedSrcRect.scale(resolutionScale, resolutionScale);
destContext.drawNativeImage(image.get(), backingStoreSize, destRect, adjustedSrcRect, op, blendMode);
#else
- imageBuffer->draw(destContext, destRect, srcRect, op, blendMode, useLowQualityScale);
+ imageBuffer->draw(destContext, destRect, srcRect, op, blendMode);
#endif
}
-void ImageBuffer::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode, bool)
+void ImageBuffer::draw(GraphicsContext& destContext, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, BlendMode blendMode)
{
RetainPtr<CGImageRef> image;
if (&destContext == &context() || destContext.isAcceleratedContext())
diff --git a/Source/WebCore/rendering/ImageQualityController.cpp b/Source/WebCore/rendering/ImageQualityController.cpp
index be0d94a..4ecd85a 100644
--- a/Source/WebCore/rendering/ImageQualityController.cpp
+++ b/Source/WebCore/rendering/ImageQualityController.cpp
@@ -40,8 +40,6 @@
ImageQualityController::ImageQualityController(const RenderView& renderView)
: m_renderView(renderView)
, m_timer(*this, &ImageQualityController::highQualityRepaintTimerFired)
- , m_animatedResizeIsActive(false)
- , m_liveResizeOptimizationIsActive(false)
{
}
@@ -99,23 +97,30 @@
m_timer.startOneShot(cLowQualityTimeThreshold);
}
-bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext& context, RenderBoxModelObject* object, Image& image, const void *layer, const LayoutSize& size)
+Optional<InterpolationQuality> ImageQualityController::interpolationQualityFromStyle(const RenderStyle& style)
{
- // If the image is not a bitmap image, then none of this is relevant and we just paint at high
- // quality.
- if (!(image.isBitmapImage() || image.isPDFDocumentImage()) || context.paintingDisabled())
- return false;
-
- switch (object->style().imageRendering()) {
+ switch (style.imageRendering()) {
case ImageRenderingOptimizeSpeed:
+ return InterpolationLow;
case ImageRenderingCrispEdges:
case ImageRenderingPixelated:
- return true;
+ return InterpolationNone;
case ImageRenderingOptimizeQuality:
- return false; // FIXME: CSS 3 Images says that optimizeQuality should behave like 'auto', but that prevents authors from overriding this low quality rendering behavior.
+ return InterpolationDefault; // FIXME: CSS 3 Images says that optimizeQuality should behave like 'auto', but that prevents authors from overriding this low quality rendering behavior.
case ImageRenderingAuto:
break;
}
+ return Nullopt;
+}
+
+InterpolationQuality ImageQualityController::chooseInterpolationQuality(GraphicsContext& context, RenderBoxModelObject* object, Image& image, const void *layer, const LayoutSize& size)
+{
+ // If the image is not a bitmap image, then none of this is relevant and we just paint at high quality.
+ if (!(image.isBitmapImage() || image.isPDFDocumentImage()) || context.paintingDisabled())
+ return InterpolationDefault;
+
+ if (Optional<InterpolationQuality> styleInterpolation = interpolationQualityFromStyle(object->style()))
+ return styleInterpolation.value();
// Make sure to use the unzoomed image size, since if a full page zoom is in effect, the image
// is actually being scaled.
@@ -141,10 +146,10 @@
set(object, innerMap, layer, size);
restartTimer();
m_liveResizeOptimizationIsActive = true;
- return true;
+ return InterpolationLow;
}
if (m_liveResizeOptimizationIsActive)
- return false;
+ return InterpolationDefault;
}
const AffineTransform& currentTransform = context.getCTM();
@@ -152,21 +157,21 @@
if (!contextIsScaled && size == imageSize) {
// There is no scale in effect. If we had a scale in effect before, we can just remove this object from the list.
removeLayer(object, innerMap, layer);
- return false;
+ return InterpolationDefault;
}
// There is no need to hash scaled images that always use low quality mode when the page demands it. This is the iChat case.
if (m_renderView.frame().page()->inLowQualityImageInterpolationMode()) {
double totalPixels = static_cast<double>(image.width()) * static_cast<double>(image.height());
if (totalPixels > cInterpolationCutoff)
- return true;
+ return InterpolationLow;
}
// If an animated resize is active, paint in low quality and kick the timer ahead.
if (m_animatedResizeIsActive) {
set(object, innerMap, layer, size);
restartTimer();
- return true;
+ return InterpolationLow;
}
// If this is the first time resizing this image, or its size is the
// same as the last resize, draw at high res, but record the paint
@@ -174,13 +179,13 @@
if (isFirstResize || oldSize == size) {
restartTimer();
set(object, innerMap, layer, size);
- return false;
+ return InterpolationDefault;
}
// If the timer is no longer active, draw at high quality and don't
// set the timer.
if (!m_timer.isActive()) {
removeLayer(object, innerMap, layer);
- return false;
+ return InterpolationDefault;
}
// This object has been resized to two different sizes while the timer
// is active, so draw at low quality, set the flag for animated resizes and
@@ -188,7 +193,7 @@
set(object, innerMap, layer, size);
m_animatedResizeIsActive = true;
restartTimer();
- return true;
+ return InterpolationLow;
}
}
diff --git a/Source/WebCore/rendering/ImageQualityController.h b/Source/WebCore/rendering/ImageQualityController.h
index 5f71164..4ff846f 100644
--- a/Source/WebCore/rendering/ImageQualityController.h
+++ b/Source/WebCore/rendering/ImageQualityController.h
@@ -26,24 +26,28 @@
#ifndef ImageQualityController_h
#define ImageQualityController_h
+#include "GraphicsTypes.h"
#include "Timer.h"
#include <wtf/HashMap.h>
+#include <wtf/Optional.h>
namespace WebCore {
-class Frame;
class GraphicsContext;
class Image;
class LayoutSize;
class RenderBoxModelObject;
class RenderView;
+class RenderStyle;
class ImageQualityController {
WTF_MAKE_NONCOPYABLE(ImageQualityController); WTF_MAKE_FAST_ALLOCATED;
public:
explicit ImageQualityController(const RenderView&);
- bool shouldPaintAtLowQuality(GraphicsContext&, RenderBoxModelObject*, Image&, const void* layer, const LayoutSize&);
+ static Optional<InterpolationQuality> interpolationQualityFromStyle(const RenderStyle&);
+ InterpolationQuality chooseInterpolationQuality(GraphicsContext&, RenderBoxModelObject*, Image&, const void* layer, const LayoutSize&);
+
void rendererWillBeDestroyed(RenderBoxModelObject& renderer) { removeObject(&renderer); }
private:
@@ -59,8 +63,8 @@
const RenderView& m_renderView;
ObjectLayerSizeMap m_objectLayerSizeMap;
Timer m_timer;
- bool m_animatedResizeIsActive;
- bool m_liveResizeOptimizationIsActive;
+ bool m_animatedResizeIsActive { false };
+ bool m_liveResizeOptimizationIsActive { false };
};
} // namespace
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index 7c1d0a7..747f6ff 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -161,11 +161,6 @@
layer()->backing()->suspendAnimations(time);
}
-bool RenderBoxModelObject::shouldPaintAtLowQuality(GraphicsContext& context, Image& image, const void* layer, const LayoutSize& size)
-{
- return view().imageQualityController().shouldPaintAtLowQuality(context, this, image, layer, size);
-}
-
RenderBoxModelObject::RenderBoxModelObject(Element& element, Ref<RenderStyle>&& style, BaseTypeFlags baseTypeFlags)
: RenderLayerModelObject(element, WTFMove(style), baseTypeFlags | RenderBoxModelObjectFlag)
{
@@ -594,6 +589,11 @@
context.setLegacyShadow(shadowOffset, boxShadow->radius(), boxShadow->color());
}
+InterpolationQuality RenderBoxModelObject::chooseInterpolationQuality(GraphicsContext& context, Image& image, const void* layer, const LayoutSize& size)
+{
+ return view().imageQualityController().chooseInterpolationQuality(context, this, image, layer, size);
+}
+
void RenderBoxModelObject::paintMaskForTextFillBox(ImageBuffer* maskImage, const IntRect& maskRect, InlineFlowBox* box, const LayoutRect& scrolledPaintRect)
{
GraphicsContext& maskImageContext = maskImage->context();
@@ -834,8 +834,9 @@
if (!geometry.destRect().isEmpty() && (image = bgImage->image(backgroundObject ? backgroundObject : this, geometry.tileSize()))) {
CompositeOperator compositeOp = op == CompositeSourceOver ? bgLayer->composite() : op;
context.setDrawLuminanceMask(bgLayer->maskSourceType() == MaskLuminance);
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, *image, bgLayer, geometry.tileSize());
- context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer->blendMode(), ImageOrientationDescription(), useLowQualityScaling));
+
+ InterpolationQuality interpolation = chooseInterpolationQuality(context, *image, bgLayer, geometry.tileSize());
+ context.drawTiledImage(*image, geometry.destRect(), toLayoutPoint(geometry.relativePhase()), geometry.tileSize(), geometry.spaceSize(), ImagePaintingOptions(compositeOp, bgLayer->blendMode(), ImageOrientationDescription(), interpolation));
}
}
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.h b/Source/WebCore/rendering/RenderBoxModelObject.h
index a509b39..b535811 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.h
+++ b/Source/WebCore/rendering/RenderBoxModelObject.h
@@ -251,7 +251,7 @@
RoundedRect backgroundRoundedRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance, InlineFlowBox*, const LayoutSize&, bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
LayoutRect borderInnerRectAdjustedForBleedAvoidance(const GraphicsContext&, const LayoutRect&, BackgroundBleedAvoidance) const;
- bool shouldPaintAtLowQuality(GraphicsContext&, Image&, const void*, const LayoutSize&);
+ InterpolationQuality chooseInterpolationQuality(GraphicsContext&, Image&, const void*, const LayoutSize&);
RenderBoxModelObject* continuation() const;
void setContinuation(RenderBoxModelObject*);
diff --git a/Source/WebCore/rendering/RenderEmbeddedObject.cpp b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
index de91014..8805631 100644
--- a/Source/WebCore/rendering/RenderEmbeddedObject.cpp
+++ b/Source/WebCore/rendering/RenderEmbeddedObject.cpp
@@ -214,12 +214,9 @@
if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
return;
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, &image, alignedRect.size());
- ImageOrientationDescription orientationDescription(shouldRespectImageOrientation());
-#if ENABLE(CSS_IMAGE_ORIENTATION)
- orientationDescription.setImageOrientationEnum(style().imageOrientation());
-#endif
- context.drawImage(image, alignedRect, ImagePaintingOptions(orientationDescription, useLowQualityScaling));
+ InterpolationQuality interpolation = chooseInterpolationQuality(context, image, &image, alignedRect.size());
+ ImageOrientationDescription orientationDescription(shouldRespectImageOrientation(), style().imageOrientation());
+ context.drawImage(image, alignedRect, ImagePaintingOptions(orientationDescription, interpolation));
}
void RenderEmbeddedObject::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
diff --git a/Source/WebCore/rendering/RenderHTMLCanvas.cpp b/Source/WebCore/rendering/RenderHTMLCanvas.cpp
index 37b588f..f2de75d 100644
--- a/Source/WebCore/rendering/RenderHTMLCanvas.cpp
+++ b/Source/WebCore/rendering/RenderHTMLCanvas.cpp
@@ -33,6 +33,7 @@
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
#include "HTMLNames.h"
+#include "ImageQualityController.h"
#include "Page.h"
#include "PaintInfo.h"
#include "RenderView.h"
@@ -84,8 +85,8 @@
page->addRelevantRepaintedObject(this, intersection(replacedContentRect, contentBoxRect));
}
- bool useLowQualityScale = style().imageRendering() == ImageRenderingCrispEdges || style().imageRendering() == ImageRenderingPixelated || style().imageRendering() == ImageRenderingOptimizeSpeed;
- canvasElement().paint(context, replacedContentRect, useLowQualityScale);
+ InterpolationQualityMaintainer interpolationMaintainer(context, ImageQualityController::interpolationQualityFromStyle(style()));
+ canvasElement().paint(context, replacedContentRect);
}
void RenderHTMLCanvas::canvasSizeChanged()
diff --git a/Source/WebCore/rendering/RenderImage.cpp b/Source/WebCore/rendering/RenderImage.cpp
index c068eab..60270ae 100644
--- a/Source/WebCore/rendering/RenderImage.cpp
+++ b/Source/WebCore/rendering/RenderImage.cpp
@@ -547,14 +547,13 @@
HTMLImageElement* imageElement = is<HTMLImageElement>(element()) ? downcast<HTMLImageElement>(element()) : nullptr;
CompositeOperator compositeOperator = imageElement ? imageElement->compositeOperator() : CompositeSourceOver;
+
+ // FIXME: Document when image != img.get().
Image* image = imageResource().image().get();
- bool useLowQualityScaling = image && shouldPaintAtLowQuality(context, *image, image, LayoutSize(rect.size()));
- ImageOrientationDescription orientationDescription(shouldRespectImageOrientation());
-#if ENABLE(CSS_IMAGE_ORIENTATION)
- orientationDescription.setImageOrientationEnum(style().imageOrientation());
-#endif
- context.drawImage(*img, rect,
- ImagePaintingOptions(compositeOperator, BlendModeNormal, orientationDescription, useLowQualityScaling));
+ InterpolationQuality interpolation = image ? chooseInterpolationQuality(context, *image, image, LayoutSize(rect.size())) : InterpolationDefault;
+
+ ImageOrientationDescription orientationDescription(shouldRespectImageOrientation(), style().imageOrientation());
+ context.drawImage(*img, rect, ImagePaintingOptions(compositeOperator, BlendModeNormal, orientationDescription, interpolation));
}
bool RenderImage::boxShadowShouldBeAppliedToBackground(const LayoutPoint& paintOffset, BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox*) const
diff --git a/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp b/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp
index 99c967a..8e100eb 100644
--- a/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp
+++ b/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp
@@ -135,13 +135,9 @@
if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
return;
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, *image, image, alignedRect.size());
-
- ImageOrientationDescription orientationDescription(shouldRespectImageOrientation());
-#if ENABLE(CSS_IMAGE_ORIENTATION)
- orientationDescription.setImageOrientationEnum(style().imageOrientation());
-#endif
- context.drawImage(*image, alignedRect, ImagePaintingOptions(orientationDescription, useLowQualityScaling));
+ InterpolationQuality interpolation = chooseInterpolationQuality(context, *image, image, alignedRect.size());
+ ImageOrientationDescription orientationDescription(shouldRespectImageOrientation(), style().imageOrientation());
+ context.drawImage(*image, alignedRect, ImagePaintingOptions(orientationDescription, interpolation));
}
CursorDirective RenderSnapshottedPlugIn::getCursor(const LayoutPoint& point, Cursor& overrideCursor) const
diff --git a/Source/WebCore/rendering/style/RenderStyle.h b/Source/WebCore/rendering/style/RenderStyle.h
index af666a4..adf105d 100644
--- a/Source/WebCore/rendering/style/RenderStyle.h
+++ b/Source/WebCore/rendering/style/RenderStyle.h
@@ -1163,9 +1163,14 @@
bool isFlippedLinesWritingMode() const { return WebCore::isFlippedLinesWritingMode(writingMode()); }
bool isFlippedBlocksWritingMode() const { return WebCore::isFlippedWritingMode(writingMode()); }
+ ImageOrientationEnum imageOrientation() const
+ {
#if ENABLE(CSS_IMAGE_ORIENTATION)
- ImageOrientationEnum imageOrientation() const { return static_cast<ImageOrientationEnum>(rareInheritedData->m_imageOrientation); }
+ return static_cast<ImageOrientationEnum>(rareInheritedData->m_imageOrientation);
+#else
+ return DefaultImageOrientation;
#endif
+ }
EImageRendering imageRendering() const { return static_cast<EImageRendering>(rareInheritedData->m_imageRendering); }