Bug 78054 - Add pixelSnappedIntRect method
Summary: Add pixelSnappedIntRect method
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Levi Weintraub
URL:
Keywords:
Depends on:
Blocks: 60318 78287
  Show dependency treegraph
 
Reported: 2012-02-07 16:15 PST by Levi Weintraub
Modified: 2012-02-10 16:58 PST (History)
4 users (show)

See Also:


Attachments
Patch (35.15 KB, patch)
2012-02-08 12:06 PST, Levi Weintraub
no flags Details | Formatted Diff | Diff
Patch (35.21 KB, patch)
2012-02-09 15:18 PST, Levi Weintraub
eric: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Levi Weintraub 2012-02-07 16:15:07 PST
Adding a pixelSnappedIntRect method that operates on LayoutRects. Once we transition to sub-pixel layout, this will snap a LayoutRect to pixel bounds. From Emil's description on Bug 78040:

x: round(x)
y: round(y)
maxX: round(x + width) - round(x)
maxY: round(y + height) - round(y)

The idea is to land this as a no-op for now, so ultimately we can flip the switch using a much smaller patch.
Comment 1 Levi Weintraub 2012-02-08 12:06:53 PST
Created attachment 126130 [details]
Patch
Comment 2 Eric Seidel (no email) 2012-02-08 13:30:33 PST
Comment on attachment 126130 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=126130&action=review

> Source/WebCore/rendering/style/RenderStyle.cpp:889
> +    RoundedRect roundedRect(pixelSnappedIntRect(borderRect));

This sort of thing makes me think that we should not allow transparent conversion from LayoutRect to IntRect/FloatRect, and that all callsites should have to choose one or the other.  That might help make it clear when we're snapping vs. not.
Comment 3 Eric Seidel (no email) 2012-02-08 13:35:19 PST
Comment on attachment 126130 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=126130&action=review

> Source/WebCore/accessibility/AccessibilityRenderObject.cpp:713
> +    viewRect.intersect(pixelSnappedIntRect(contentRect));

I would have done this when assigning the local, and made the local IntRect contentRect = pixelSnappedIntRect(m_renderer->absoluteClippedOverflowRect()).  But this is part of my general feeling that only the layout code should deal with Layout*, and anyone ouside of layout will need to make an explicit choice if they want an int rect or float rect,a nd if they want it snapped or not.

> Source/WebCore/accessibility/AccessibilityRenderObject.cpp:2633
> +    return m_renderer->document()->view()->contentsToScreen(pixelSnappedIntRect(ourrect));

I probably would have used a local here to avoid two separate snapped calls.

> Source/WebCore/html/HTMLCanvasElement.cpp:287
> +                context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, useLowQualityScale);

This makes me wonder why we don't define pixelSnappedIntRect() on LayoutRect directly?  (And until then on IntRect directly?)

> Source/WebCore/html/shadow/TextControlInnerElements.cpp:553
> +    IntRect rect = pixelSnappedIntRect(renderer()->view()->frameView()->contentsToWindow(renderer()->absoluteBoundingBoxRectIgnoringTransforms()));

What a horribly complicated line.
Comment 4 Levi Weintraub 2012-02-08 13:51:01 PST
Comment on attachment 126130 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=126130&action=review

>> Source/WebCore/accessibility/AccessibilityRenderObject.cpp:713
>> +    viewRect.intersect(pixelSnappedIntRect(contentRect));
> 
> I would have done this when assigning the local, and made the local IntRect contentRect = pixelSnappedIntRect(m_renderer->absoluteClippedOverflowRect()).  But this is part of my general feeling that only the layout code should deal with Layout*, and anyone ouside of layout will need to make an explicit choice if they want an int rect or float rect,a nd if they want it snapped or not.

Seems reasonable.

>> Source/WebCore/accessibility/AccessibilityRenderObject.cpp:2633
>> +    return m_renderer->document()->view()->contentsToScreen(pixelSnappedIntRect(ourrect));
> 
> I probably would have used a local here to avoid two separate snapped calls.

It's only one actual call, since only one of these is compiled depending on the platform.

>> Source/WebCore/html/HTMLCanvasElement.cpp:287
>> +                context->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, pixelSnappedIntRect(r), CompositeSourceOver, useLowQualityScale);
> 
> This makes me wonder why we don't define pixelSnappedIntRect() on LayoutRect directly?  (And until then on IntRect directly?)

We followed the enclosingIntRect convention by making this a global method. Neither seems clearer to me, so I'm happy to go the other way if you have strong feelings about it.

>> Source/WebCore/html/shadow/TextControlInnerElements.cpp:553
>> +    IntRect rect = pixelSnappedIntRect(renderer()->view()->frameView()->contentsToWindow(renderer()->absoluteBoundingBoxRectIgnoringTransforms()));
> 
> What a horribly complicated line.

:(

>> Source/WebCore/rendering/style/RenderStyle.cpp:889
>> +    RoundedRect roundedRect(pixelSnappedIntRect(borderRect));
> 
> This sort of thing makes me think that we should not allow transparent conversion from LayoutRect to IntRect/FloatRect, and that all callsites should have to choose one or the other.  That might help make it clear when we're snapping vs. not.

I agree!
Comment 5 Levi Weintraub 2012-02-09 15:18:38 PST
Created attachment 126387 [details]
Patch
Comment 6 Eric Seidel (no email) 2012-02-09 17:13:47 PST
Comment on attachment 126387 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=126387&action=review

I'm willing to aprove this and let you all move foward.  But I think you/we shoudl focus on making the boundaries crystal clear.  It's less important that we get each spot right, more than that it's easy to tell when a spot is right or wrong.  Right now it's very difficult to tell what should be a layout rect vs. an IntRect because the rules are not clear (at least to me).  We need to make them clear.  NOt just for me, but for all the others who are going to touch this code and be confused as to what type of rect to use where.

> Source/WebCore/page/FrameView.cpp:1777
> +                unionedRect.unite(pixelSnappedIntRect(m_repaintRects[i]));

Isn't a repaint rect a pixel rect by definition already?  And thus an IntRect and not a LayoutRect?

> Source/WebCore/rendering/RenderObject.cpp:968
> -                graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, y2 - y1));
> +                graphicsContext->drawRect(pixelSnappedIntRect(LayoutRect(x1, y1, x2 - x1, y2 - y1)));

Feels a little odd that we convert from int to layout to int here...
Comment 7 Levi Weintraub 2012-02-10 16:58:27 PST
Committed r107461: <http://trac.webkit.org/changeset/107461>