[Webkit-unassigned] [Bug 53512] [CG] getBBox() on a SVGPathElement with curves incorrectly includes control points
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Thu Jul 28 17:53:21 PDT 2011
https://bugs.webkit.org/show_bug.cgi?id=53512
--- Comment #4 from Nikolas Zimmermann <zimmermann at kde.org> 2011-07-28 17:53:21 PST ---
(In reply to comment #2)
> Created an attachment (id=102313)
--> (https://bugs.webkit.org/attachment.cgi?id=102313&action=review) [details]
> pure-CG non-reproducing case
>
> I haven't taken enough of a look yet, but attached is a pure-CG example that gets the bounding box for exactly the same shape perfectly correct.
>
> So, it could still be CG, if we're getting it in some weird state, but someone will have to dig deeper.
Great catch! I traced down what we're passing to CG, by breaking on SVGPathBuilder::moveTo/lineTo/curveToCubic.
Let's compare your testcase and what we feed to CG:
1.
<code>
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 131, 210);
</code>
WebCore::Path::moveTo (this=0x21bd315c, point=@0x21b5bbe8) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/platform/graphics/cg/PathCG.cpp:191
191 CGPathMoveToPoint(m_path, 0, point.x(), point.y());
(gdb) p point
$9 = (const 'WebCore::FloatPoint' &) @0x21b5bbe8: {
m_x = 131,
m_y = 210
}
That's the same.
2.
<code>
CGPathAddCurveToPoint(path, NULL, 152, 173, 207, 125, 240, 177);
</code>
WebCore::Path::addBezierCurveTo (this=0x21bd315c, cp1=@0xbfffbd08, cp2=@0xbfffbd00, p=@0x21b5bbe8) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/platform/graphics/cg/PathCG.cpp:206
206 CGPathAddCurveToPoint(m_path, 0, cp1.x(), cp1.y(), cp2.x(), cp2.y(), p.x(), p.y());
(gdb) p cp1
$10 = (const 'WebCore::FloatPoint' &) @0xbfffbd08: {
m_x = 152,
m_y = 173
}
(gdb) p cp2
$11 = (const 'WebCore::FloatPoint' &) @0xbfffbd00: {
m_x = 207,
m_y = 125
}
(gdb) p p
$12 = (const 'WebCore::FloatPoint' &) @0x21b5bbe8: {
m_x = 240,
m_y = 177
}
That's the same.
3.
<code>
CGPathAddCurveToPoint(path, NULL, 273, 229, 211, 293, 193, 257);
</code>
WebCore::Path::addBezierCurveTo (this=0x21bd315c, cp1=@0xbfffbd08, cp2=@0xbfffbd00, p=@0x21b5bbe8) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/platform/graphics/cg/PathCG.cpp:206
206 CGPathAddCurveToPoint(m_path, 0, cp1.x(), cp1.y(), cp2.x(), cp2.y(), p.x(), p.y());
(gdb) p cp1
$13 = (const 'WebCore::FloatPoint' &) @0xbfffbd08: {
m_x = 273,
m_y = 229
}
(gdb) p cp2
$14 = (const 'WebCore::FloatPoint' &) @0xbfffbd00: {
m_x = 211,
m_y = 293
}
(gdb) p p
$15 = (const 'WebCore::FloatPoint' &) @0x21b5bbe8: {
m_x = 193,
m_y = 257
}
That's the same.
4.
<code>
CGPathAddCurveToPoint(path, NULL, 175, 221, 110, 247, 131, 210);
</code>
WebCore::Path::addBezierCurveTo (this=0x21bd315c, cp1=@0xbfffbd08, cp2=@0xbfffbd00, p=@0x21b5bbe8) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/platform/graphics/cg/PathCG.cpp:206
206 CGPathAddCurveToPoint(m_path, 0, cp1.x(), cp1.y(), cp2.x(), cp2.y(), p.x(), p.y());
(gdb) p cp1
$16 = (const 'WebCore::FloatPoint' &) @0xbfffbd08: {
m_x = 175,
m_y = 221
}
(gdb) p cp2
$17 = (const 'WebCore::FloatPoint' &) @0xbfffbd00: {
m_x = 110,
m_y = 247
}
(gdb) p p
$18 = (const 'WebCore::FloatPoint' &) @0x21b5bbe8: {
m_x = 131,
m_y = 210
}
That's the same.
5.
<code>
CGPathCloseSubpath(path);
</code>
WebCore::Path::closeSubpath (this=0x21bd315c) at /Users/nzimmermann/Coding/WebKit/Source/WebCore/platform/graphics/cg/PathCG.cpp:216
216 CGPathCloseSubpath(m_path);
Also the same!
So we're constructing the path in an identical way.
Okay, where's the problem?
Stepping down from my last breakpoint SVGPathBuilder::closePath shows the answer:
Breakpoint 4, WebCore::SVGPathBuilder::closePath (this=0x108ca590) at SVGPathBuilder.cpp:66
66 ASSERT(m_path);
(gdb) s
67 m_path->closeSubpath();
(gdb) fin
Run till exit from #0 WebCore::SVGPathBuilder::closePath (this=0x108ca590) at SVGPathBuilder.cpp:67
WebCore::SVGPathParser::parseClosePathSegment (this=0x108c49c0) at SVGPathParser.cpp:48
48 }
(gdb) fin
Run till exit from #0 WebCore::SVGPathParser::parseClosePathSegment (this=0x108c49c0) at SVGPathParser.cpp:48
WebCore::SVGPathParser::parsePathDataFromSource (this=0x108c49c0, pathParsingMode=WebCore::NormalizedParsing) at SVGPathParser.cpp:331
331 break;
(gdb) fin
Run till exit from #0 WebCore::SVGPathParser::parsePathDataFromSource (this=0x108c49c0, pathParsingMode=WebCore::NormalizedParsing) at SVGPathParser.cpp:331
0x09b421ca in WebCore::SVGPathParserFactory::buildPathFromByteStream (this=0x108c4990, stream=0x108c4050, result=@0x108c4d9c) at SVGPathParserFactory.cpp:172
172 bool ok = parser->parsePathDataFromSource(NormalizedParsing);
Value returned is $59 = true
(gdb) p (CGRect)CGPathGetPathBoundingBox(result.m_path)
$60 = {
origin = {
x = 126.869362,
y = 154.158096
},
size = {
width = 122.646141,
height = 113.340134
}
}
(gdb)
All fine here at this point!
(gdb) fin
Run till exit from #0 0x09b421ca in WebCore::SVGPathParserFactory::buildPathFromByteStream (this=0x11a2f140, stream=0x11a361a0, result=@0x11a3fc6c) at SVGPathParserFactory.cpp:172
WebCore::SVGPathElement::toPathData (this=0x11a54f10, path=@0x11a3fc6c) at SVGPathElement.cpp:334
334 }
Value returned is $70 = true
(gdb) fin
Run till exit from #0 WebCore::SVGPathElement::toPathData (this=0x11a54f10, path=@0x11a3fc6c) at SVGPathElement.cpp:334
WebCore::RenderSVGPath::layout (this=0x11a3fc4c) at RenderSVGPath.cpp:120
120 m_needsPathUpdate = false;
(gdb) pQuit
(gdb) p (CGRect)CGPathGetPathBoundingBox(m_path.m_path)
$71 = {
origin = {
x = 126.869362,
y = 154.158096
},
size = {
width = 122.646141,
height = 113.340134
}
}
(gdb)
Still fine.
Stepping on...
359 m_fillBoundingBox = m_path.boundingRect();
Value returned is $74 = {m_location = {m_x = 110, m_y = 125}, m_size = {m_width = 163, m_height = 168}}
FloatRect Path::boundingRect() const
{
return CGPathGetBoundingBox(m_path);
}
Funny bug, eh? :-) The value magically is truncated.
I've stepped through WebCore::SVGPathParserFactory::buildPathFromByteStream (this=0x209b8200, stream=0x209b7440, result=@0x21bd315c) at SVGPathParserFactory.cpp:174
and it turns out that
(gdb) p (CGRect)CGPathGetPathBoundingBox(result.m_path)
$23 = {
origin = {
x = 126.869362,
y = 154.158096
},
size = {
width = 122.646141,
height = 113.340134
}
Your program gives:
x=126.869362, y=154.158096, w=122.646141, h=113.340134
At this point your CG demo program and WebCore still agree!
Breaking on the next call of Path::boundingRect(), gives:
0x09a2a92d in WebCore::RenderSVGPath::updateCachedBoundaries (this=0x21bd313c) at RenderSVGPath.cpp:359
359 m_fillBoundingBox = m_path.boundingRect();
Value returned is $25 = {m_location = {m_x = 110, m_y = 125}, m_size = {m_width = 163, m_height = 168}}
--
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