Bug 151791

Summary: Clipping along compositing borders in svg-edit
Product: WebKit Reporter: Philip Rogers <pdr>
Component: SVGAssignee: Simon Fraser (smfr) <simon.fraser>
Status: RESOLVED FIXED    
Severity: Normal CC: commit-queue, krit, sabouhallawa, simon.fraser, thorton, webkit-bug-importer, zalan, zimmermann
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Screenshot of svg-edit
none
Maybe testcase
none
Patch none

Description Philip Rogers 2015-12-02 20:48:42 PST
Created attachment 266505 [details]
Screenshot of svg-edit

The main content area in svg-edit is clipped in Safari 9 and nightly@r192882:
https://svg-edit.github.io/svgedit/releases/svg-edit-2.8.1/svg-editor.html

Removing position:absolute on the #svgroot element seems to fix this.

If compositing borders are turned on it's a bit more obvious where the clipping is. This does depend on your window size so you may need to resize it to see the bug.
Comment 1 Simon Fraser (smfr) 2015-12-03 18:18:07 PST
I think we have other bugs about SVG not being prepared to paint across multiple tiles sometimes.
Comment 2 Simon Fraser (smfr) 2015-12-03 18:21:43 PST
Would be nice to have a reduction.
Comment 3 Philip Rogers 2015-12-03 21:31:39 PST
Minimizing this reproduction ended up being very difficult but I got it in the end.

<!DOCTYPE HTML>
This test passes if there is a green rectangle with a blue border going all the way around.<br>
<svg id="svgroot" width="640" height="480" overflow="visible">
  <svg id="canvasBackground" x="0" y="0" width="640" height="480">
    <rect width="100%" height="100%" fill="green" stroke-width="5" stroke="blue"/>
  </svg>
</svg>
<script>
  setTimeout(function() {
    canvasBackground.setAttribute('x', 640);
    canvasBackground.setAttribute('y', 240);
    svgroot.setAttribute('width', 1920);
    svgroot.setAttribute('height', 1440);
  }, 0);
</script>
Comment 4 Simon Fraser (smfr) 2015-12-03 22:00:27 PST
Created attachment 266599 [details]
Maybe testcase

This testcase shows a repaint bug related to overflow=visible, but I'm not sure that's the same as the original, since a window resize doesn't fix the drawing of svg-edit.
Comment 5 Simon Fraser (smfr) 2015-12-04 21:52:10 PST
I think the problem is that InlineBoxes know nothing about the overflowing SVG.

Here's the render tree in the small testcase:
(R)elative/A(B)solute/Fi(X)ed/Stick(Y) positioned, (O)verflow clipping, (A)nonymous, (G)enerated, (F)loating, has(L)ayer, (C)omposited, (D)irty layout, Dirty (S)tyle
---G-LC --  RenderView  (0.00, 0.00) (897.00, 465.00) renderer->(0x115ac92a0)
-----L- --    HTML RenderBlock  (0.00, 0.00) (897.00, 506.00) renderer->(0x115bdd730) node->(0x115b3f5b0)
------- --*     BODY RenderBody  (0.00, 0.00) (897.00, 506.00) renderer->(0x115bdd7e8) node->(0x115b3f6e8)
------- --        RootInlineBox  (0.00, 488.00) (502.00, 18.00) (0x115b3a2a0) renderer->(0x115bdd7e8)
------- --          InlineBox  (0.00, 0.00) (502.00, 502.00) (0x115b50e10) renderer->(0x115aef5e0)
------- --        svg RenderSVGRoot  (0.00, 0.00) (502.00, 502.00) renderer->(0x115aef5e0) node->(0x115af08e8)
------- --          svg RenderSVGViewportContainer renderer->(0x115b91288) node->(0x115af0ab0)
------- --            rect RenderSVGRect renderer->(0x115a86108) node->(0x115ae1680)
------- --        #text RenderText renderer->(0x115be7ea0) node->(0x115b8a730) length->(1) "\n"

After the rect in the SVG moves, the SVG bounds are actually 608x608, but line boxes only know about 502x502. So InlineFlowBox::paint() short-circuits, and we never paint the overflowing SVG.
Comment 6 Simon Fraser (smfr) 2015-12-04 22:25:18 PST
After the SVG changes, we run RenderSVGRoot::layout() which calls addVisualOverflow(), but we never hit InlineFlowBox::computeOverflow().
Comment 7 Simon Fraser (smfr) 2015-12-04 22:33:33 PST
That testcase is fixed by not treating the RenderSVGRoot as a layout boundary, if it has overflow. We need to trigger layout on the enclosing line boxes to recompute visual overflow.

However, that doesn't fix svg-edit.
Comment 8 Simon Fraser (smfr) 2015-12-06 11:27:31 PST
Debugging svg-editor. We're bailing from RenderReplaced::shouldPaint() for the RenderSVGRoot:

      RenderSVGRoot 0x1242bf468 {svg} id="svgroot" (layout overflow 0,0 640x480) (visual overflow 0,0 641x481) at (0,0) size 1920x1440 clipped  at (40,70) size 947x377
        RenderSVGViewportContainer 0x1253fb288 {svg} id="canvasBackground" clipped  at (40,70) size 947x377
          RenderSVGRect 0x124ef4840 {rect} at (40,70) size 947x377 [stroke={[type=SOLID] [color=#000000]}] [fill={[type=SOLID] [color=#FFFFFF]}] [x=0.00] [y=0.00] [width=640.00] [height=480.00]

What seems wrong is that its visual overflow is smaller than its size.
Comment 9 Simon Fraser (smfr) 2015-12-06 11:58:13 PST
The bug here is that RenderSVGRoot fails to call clearOverflow() before recomputing visual overflow, and in svg-editor it gets resize from 640x480 to 1920x1400, but retains stale visual overflow of 640x480.
Comment 10 Simon Fraser (smfr) 2015-12-06 21:16:31 PST
Created attachment 266750 [details]
Patch
Comment 11 Radar WebKit Bug Importer 2015-12-06 21:17:12 PST
<rdar://problem/23778937>
Comment 12 WebKit Commit Bot 2015-12-06 22:27:26 PST
Comment on attachment 266750 [details]
Patch

Clearing flags on attachment: 266750

Committed r193613: <http://trac.webkit.org/changeset/193613>
Comment 13 WebKit Commit Bot 2015-12-06 22:27:29 PST
All reviewed patches have been landed.  Closing bug.
Comment 14 Simon Fraser (smfr) 2015-12-08 09:55:23 PST
I filed bug 151995 on the remaining issue.