[Webkit-unassigned] [Bug 85532] [meta] Enable sub-pixel layout on all platforms
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Wed Jul 4 11:06:49 PDT 2012
https://bugs.webkit.org/show_bug.cgi?id=85532
Philip Rogers <pdr at google.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |pdr at google.com
--- Comment #7 from Philip Rogers <pdr at google.com> 2012-07-04 11:06:49 PST ---
(In reply to comment #6)
> (In reply to comment #3)
> > I'd love an update on plans for enabling it in the KDE project ;)
> I'm not working on KDE stuff since half a decade btw, historical reasons for my bugzilla account :-)
>
> Anyhow, I've experimented lots with SUBPIXEL_LAYOUT turned on, on Mac. You've done a great job, it's working as-expected for most parts.
>
> I've ran into an issue with transforming an absolute positioned <div>, which is aligned on sub-pixel boundaries, like this:
>
> <html>
> <body>
> <div style="-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px;"></div>
> </body>
> </html>
>
> If you run this in trunk, you won't see anything, unless you zoom in or out at least once.
> I've nailed down the problem, but I'm yet unsure on how to fix it properly, so I'd like to share it with you to get your insight:
> void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
> {
> LayoutPoint adjustedPaintOffset = paintOffset + location();
>
> PaintPhase phase = paintInfo.phase;
>
> // Check if we need to do anything at all.
> // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
> // paints the root's background.
> if (!isRoot()) {
> LayoutRect overflowBox = visualOverflowRect();
> flipForWritingMode(overflowBox);
> overflowBox.inflate(maximalOutlineSize(paintInfo.phase));
> overflowBox.moveBy(adjustedPaintOffset);
> if (!overflowBox.intersects(paintInfo.rect))
> return;
> ....
>
> Break on RenderBlock::paint(), at some point:
> Breakpoint 1, WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2626
> 2626 LayoutPoint adjustedPaintOffset = paintOffset + location();
> (gdb) p showRenderTreeForThis()
> RenderView 0x109124108 #document 0x10882a600
> RenderBlock 0x109125b78 HTML 0x109120380
> RenderBody 0x1091266d8 BODY 0x109125ca0
> * RenderBlock (positioned) 0x1091271e8 DIV 0x109126400 STYLE=-moz-transform: scale(100); -webkit-transform: scale(100); background-color: green; position: absolute; left: -0.5px; top: -0.5px; width: 1px; height: 1px;
>
> is reached.
>
> 2638 if (!overflowBox.intersects(paintInfo.rect))
> (gdb) p overflowBox
> $39 = {
> m_location = {
> m_x = {
> m_value = 0
> },
> m_y = {
> m_value = 0
> }
> },
> m_size = {
> m_width = {
> m_value = 60
> },
> m_height = {
> m_value = 60
> }
> }
> }
>
> p paintInfo.rect
> $40 = {
> m_location = {
> m_x = 1,
> m_y = 1
> },
> m_size = {
> m_width = 8,
> m_height = 6
> }
> }
>
> 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638
> 2638 if (!overflowBox.intersects(paintInfo.rect))
> Value returned is $41 = false
>
> And here's the problem. The paintInfo.rect has a location of 1x1, and a size of 8x6.
> So let's examine where the incorrect paintInfo.rect is coming from:
>
> (gdb) bt
> #0 0x000000010269d7af in WebCore::RenderBlock::paint (this=0x1091271e8, paintInfo=@0x7fff5fbf97a8, paintOffset=@0x7fff5fbf98d0) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderBlock.cpp:2638
> #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149
>
> Looking at frame #1:
> #1 0x000000010279d729 in WebCore::RenderLayer::paintLayerContents (this=0x1091272b8, rootLayer=0x1091272b8, context=0x7fff5fbfb4c0, parentPaintDirtyRect=@0x7fff5fbf9b10, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3149
> 3147 // Paint the background.
> 3148 PaintInfo paintInfo(context, pixelSnappedIntRect(damageRect.rect()), PaintPhaseBlockBackground, false, paintingRootForRenderer, region, 0);
> 3149 renderer()->paint(paintInfo, paintOffset);
>
> (gdb) p damageRect.rect()
> $51 = (const LayoutRect &) @0x7fff5fbf9908: {
> m_location = {
> m_x = {
> m_value = 30
> },
> m_y = {
> m_value = 30
> }
> },
> m_size = {
> m_width = {
> m_value = 480
> },
> m_height = {
> m_value = 360
> }
> }
> }
>
> The pixelSnappedIntRect() produces the x/y=1, width=8, height=6 IntRect.
>
> Some more background info:
> The RenderLayer associated with the <div> has a transform, scale(100).
> #3 0x000000010279c370 in WebCore::RenderLayer::paintLayer (this=0x1091272b8, rootLayer=0x1091244c8, context=0x7fff5fbfb4c0, paintDirtyRect=@0x7fff5fbfa2d0, paintBehavior=0, paintingRoot=0x0, region=0x0, overlapTestRequests=0x7fff5fbfb1c0, paintFlags=480) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/rendering/RenderLayer.cpp:3006
>
> 3001 {
> 3002 GraphicsContextStateSaver stateSaver(*context);
> 3003 context->concatCTM(transform.toAffineTransform());
> 3004
> 3005 // Now do a paint with the root layer shifted to be us.
> 3006 paintLayerContentsAndReflection(this, context, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, region, overlapTestRequests, paintFlags);
> 3007 }
> 3008
> 3009 // Restore the clip.
> 3010 if (parent())
>
> (gdb) p transform
> $56 = {
> m_matrix = {{100, 0, 0, 0}, {0, 100, 0, 0}, {0, 0, 1, 0}, {-50, -50, 0, 1}}
> }
>
> (gdb) p paintDirtyRect
> $58 = (const LayoutRect &) @0x7fff5fbfa2d0: {
> m_location = {
> m_x = {
> m_value = 0
> },
> m_y = {
> m_value = 0
> }
> },
> m_size = {
> m_width = {
> m_value = 48000
> },
> m_height = {
> m_value = 36000
> }
> }
> }
>
> The mapping of the paintDirtyRect through the inverse of the transform, produces x/y=30 (aka. 0.5).
> Now that we know the root of the problem, if you change left/top to 0.4999px, it'll show up as expected, as the paintInfo.rect is now at 0x0, as 0.4999px is pixel-snapped to 0, instead of 1.
>
> I'm unsure on how to fix this properly: the intersection between the pixel-snapped paint info rect and the overflow box is lossy, as the overflow box is sub-pixel aware.
>
> (gdb) p toRenderBox(renderer())->m_frameRect
> $61 = {
> m_location = {
> m_x = {
> m_value = -30
> },
> m_y = {
> m_value = -30
> }
> },
> m_size = {
> m_width = {
> m_value = 60
> },
> m_height = {
> m_value = 60
> }
> }
> }
>
> As no overflow is involved in my example, visualOverflowRect() == borderBoxRect(), aka. LayoutRect(0, 0, m_frameRect->width(), m_frameRect->height()) (in this example).
>
> Sorry for the long post, but I thought I'd give as much information as possible, so we can discuss this easier. Levi, any idea?
Levi, eae: ping? This is somewhat of a blocker for the SVG2.0 work.
--
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.
More information about the webkit-unassigned
mailing list