https://bugs.webkit.org/show_bug.cgi?id=67415
authorbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Sep 2011 03:29:50 +0000 (03:29 +0000)
committerbdakin@apple.com <bdakin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 22 Sep 2011 03:29:50 +0000 (03:29 +0000)
Text drawn via -webkit-background-clip:text is blurry at device scale factors >1.0
-and corresponding-
<rdar://problem/10060379>

Reviewed by Darin Adler.

New helper function RenderBoxModelObject scales the mask image by the
deviceScaleFactor to get an image of the appropriate resolution. It also scales
the image's GraphicsContext so that the clip is set up on the same scale. Back in
paintFillLayerExtended() we still clip the image to the original maskRect to get
everything scaled back to the appropriate size.
* rendering/RenderBoxModelObject.cpp:
(WebCore::createDeviceScaledImageBuffer):
(WebCore::RenderBoxModelObject::paintFillLayerExtended):

Make the deviceScaleFactor convenience function just a namespace-level function in
Page rather than a static member or Page.
* page/Page.cpp:
(WebCore::deviceScaleFactor):
* page/Page.h:

Pre-existing callers of Page::deviceScaleFactor(Frame*) must now use
WebCore::deviceScaleFactor(Frame*)
* editing/DeleteButtonController.cpp:
(WebCore::DeleteButtonController::createDeletionUI):
* rendering/RenderImage.cpp:
(WebCore::RenderImage::imageSizeForError):
(WebCore::RenderImage::paintReplaced):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::drawPlatformResizerImage):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@95697 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/editing/DeleteButtonController.cpp
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderImage.cpp
Source/WebCore/rendering/RenderLayer.cpp

index 53665ce..bb42501 100644 (file)
@@ -1,3 +1,37 @@
+2011-09-21  Beth Dakin  <bdakin@apple.com>
+
+        https://bugs.webkit.org/show_bug.cgi?id=67415
+        Text drawn via -webkit-background-clip:text is blurry at device scale factors >1.0
+        -and corresponding-
+        <rdar://problem/10060379>
+
+        Reviewed by Darin Adler.
+
+        New helper function RenderBoxModelObject scales the mask image by the 
+        deviceScaleFactor to get an image of the appropriate resolution. It also scales 
+        the image's GraphicsContext so that the clip is set up on the same scale. Back in 
+        paintFillLayerExtended() we still clip the image to the original maskRect to get 
+        everything scaled back to the appropriate size.
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::createDeviceScaledImageBuffer):
+        (WebCore::RenderBoxModelObject::paintFillLayerExtended):
+
+        Make the deviceScaleFactor convenience function just a namespace-level function in 
+        Page rather than a static member or Page.
+        * page/Page.cpp:
+        (WebCore::deviceScaleFactor):
+        * page/Page.h:
+        
+        Pre-existing callers of Page::deviceScaleFactor(Frame*) must now use 
+        WebCore::deviceScaleFactor(Frame*)
+        * editing/DeleteButtonController.cpp:
+        (WebCore::DeleteButtonController::createDeletionUI):
+        * rendering/RenderImage.cpp:
+        (WebCore::RenderImage::imageSizeForError):
+        (WebCore::RenderImage::paintReplaced):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::drawPlatformResizerImage):
+
 2011-09-21  Tim Horton  <timothy_horton@apple.com>
 
         [CG] ImageBufferData::getData has an invariant comparison in the inner part of a loop which doesn't get optimized out
index 2d7d43c..046d67d 100644 (file)
@@ -255,7 +255,7 @@ void DeleteButtonController::createDeletionUI()
     style->setProperty(CSSPropertyHeight, String::number(buttonHeight) + "px");
     style->setProperty(CSSPropertyVisibility, CSSValueVisible);
 
-    float deviceScaleFactor = Page::deviceScaleFactor(m_frame);
+    float deviceScaleFactor = WebCore::deviceScaleFactor(m_frame);
     RefPtr<Image> buttonImage;
     if (deviceScaleFactor >= 2)
         buttonImage = Image::loadPlatformResource("deleteButton@2x");
index be52797..b5a28a0 100644 (file)
@@ -109,6 +109,16 @@ static void networkStateChanged()
         frames[i]->document()->dispatchWindowEvent(Event::create(eventName, false, false));
 }
 
+float deviceScaleFactor(Frame* frame)
+{
+    if (!frame)
+        return 1;
+    Page* page = frame->page();
+    if (!page)
+        return 1;
+    return page->deviceScaleFactor();
+}
+
 Page::Page(PageClients& pageClients)
     : m_chrome(adoptPtr(new Chrome(this, pageClients.chromeClient)))
     , m_dragCaretController(adoptPtr(new DragCaretController))
@@ -656,16 +666,6 @@ void Page::setDeviceScaleFactor(float scaleFactor)
     backForward()->markPagesForFullStyleRecalc();
 }
 
-float Page::deviceScaleFactor(Frame* frame)
-{
-    if (!frame)
-        return 1;
-    Page* page = frame->page();
-    if (!page)
-        return 1;
-    return page->deviceScaleFactor();
-}
-
 void Page::didMoveOnscreen()
 {
     for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
index 48512e0..1390c98 100644 (file)
@@ -94,6 +94,8 @@ namespace WebCore {
 
     enum FindDirection { FindDirectionForward, FindDirectionBackward };
 
+    float deviceScaleFactor(Frame*);
+
     class Page {
         WTF_MAKE_NONCOPYABLE(Page);
         friend class Settings;
@@ -249,7 +251,6 @@ namespace WebCore {
 
         float deviceScaleFactor() const { return m_deviceScaleFactor; }
         void setDeviceScaleFactor(float);
-        static float deviceScaleFactor(Frame*);
 
         // Notifications when the Page starts and stops being presented via a native window.
         void didMoveOnscreen();
index dc6e258..60e9f9d 100644 (file)
@@ -595,6 +595,24 @@ static LayoutRect backgroundRectAdjustedForBleedAvoidance(GraphicsContext* conte
     return adjustedRect;
 }
 
+static PassOwnPtr<ImageBuffer> createDeviceScaledImageBuffer(IntSize imageSize, float deviceScaleFactor)
+{
+    // To create an image of the appropriate resolution, we need to scale imageRect's size
+    // by the device scale factor.
+    IntSize scaledImageSize = imageSize;
+    scaledImageSize.scale(deviceScaleFactor);
+
+    OwnPtr<ImageBuffer> scaledImageBuffer = ImageBuffer::create(scaledImageSize);
+    if (!scaledImageBuffer)
+        return nullptr;
+
+    // Scale the whole context by the device scale factor so that all of the clips set up at 
+    // the appropriate size.
+    scaledImageBuffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
+
+    return scaledImageBuffer.release();
+}
+
 void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, const Color& color, const FillLayer* bgLayer, const LayoutRect& rect,
     BackgroundBleedAvoidance bleedAvoidance, InlineFlowBox* box, const LayoutSize& boxSize, CompositeOperator op, RenderObject* backgroundObject)
 {
@@ -688,7 +706,7 @@ void RenderBoxModelObject::paintFillLayerExtended(const PaintInfo& paintInfo, co
         maskRect.intersect(paintInfo.rect);
         
         // Now create the mask.
-        OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskRect.size());
+        OwnPtr<ImageBuffer> maskImage = createDeviceScaledImageBuffer(maskRect.size(), WebCore::deviceScaleFactor(frame()));
         if (!maskImage)
             return;
         
index 07ecb66..f63dd37 100644 (file)
@@ -86,7 +86,7 @@ IntSize RenderImage::imageSizeForError(CachedImage* newImage) const
 
     IntSize imageSize;
     if (newImage->willPaintBrokenImage()) {
-        float deviceScaleFactor = Page::deviceScaleFactor(frame());
+        float deviceScaleFactor = WebCore::deviceScaleFactor(frame());
         pair<Image*, float> brokenImageAndImageScaleFactor = newImage->brokenImage(deviceScaleFactor);
         imageSize = brokenImageAndImageScaleFactor.first->size();
         imageSize.scale(1 / brokenImageAndImageScaleFactor.second);
@@ -277,7 +277,7 @@ void RenderImage::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOf
             RefPtr<Image> image = m_imageResource->image();
 
             if (m_imageResource->errorOccurred() && !image->isNull() && usableWidth >= image->width() && usableHeight >= image->height()) {
-                float deviceScaleFactor = Page::deviceScaleFactor(frame());
+                float deviceScaleFactor = WebCore::deviceScaleFactor(frame());
                 // Call brokenImage() explicitly to ensure we get the broken image icon at the appropriate resolution.
                 pair<Image*, float> brokenImageAndImageScaleFactor = m_imageResource->cachedImage()->brokenImage(deviceScaleFactor);
                 image = brokenImageAndImageScaleFactor.first;
index 98b5eed..dbd2483 100644 (file)
@@ -2416,7 +2416,7 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, const LayoutPoint&
 
 void RenderLayer::drawPlatformResizerImage(GraphicsContext* context, LayoutRect resizerCornerRect)
 {
-    float deviceScaleFactor = Page::deviceScaleFactor(renderer()->frame());
+    float deviceScaleFactor = WebCore::deviceScaleFactor(renderer()->frame());
 
     RefPtr<Image> resizeCornerImage;
     IntSize cornerResizerSize;