mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 610594 - "ABORT: F.6.6.3 should prevent this. Will sqrt(-num)!". r=longsonr, a=blocking
This commit is contained in:
parent
43225ec75d
commit
c7eb7f1b6c
@ -554,9 +554,9 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
|
||||
case nsIDOMSVGPathSeg::PATHSEG_ARC_ABS:
|
||||
case nsIDOMSVGPathSeg::PATHSEG_ARC_REL:
|
||||
{
|
||||
float rx = mData[i];
|
||||
float ry = mData[i+1];
|
||||
float angle = mData[i+2];
|
||||
double rx = mData[i];
|
||||
double ry = mData[i+1];
|
||||
double angle = mData[i+2];
|
||||
PRBool largeArcFlag = mData[i+3] != 0.0f;
|
||||
PRBool sweepFlag = mData[i+4] != 0.0f;
|
||||
if (segType == nsIDOMSVGPathSeg::PATHSEG_ARC_ABS) {
|
||||
@ -595,46 +595,47 @@ SVGPathData::GetMarkerPositioningData(nsTArray<nsSVGMark> *aMarks) const
|
||||
|
||||
// F.6.5.1:
|
||||
angle = angle * M_PI/180.0;
|
||||
float x1p = cos(angle) * (segStart.x - segEnd.x) / 2.0
|
||||
+ sin(angle) * (segStart.y - segEnd.y) / 2.0;
|
||||
float y1p = -sin(angle) * (segStart.x - segEnd.x) / 2.0
|
||||
+ cos(angle) *(segStart.y - segEnd.y) / 2.0;
|
||||
double x1p = cos(angle) * (segStart.x - segEnd.x) / 2.0
|
||||
+ sin(angle) * (segStart.y - segEnd.y) / 2.0;
|
||||
double y1p = -sin(angle) * (segStart.x - segEnd.x) / 2.0
|
||||
+ cos(angle) * (segStart.y - segEnd.y) / 2.0;
|
||||
|
||||
// This is the root in F.6.5.2 and the numerator under that root:
|
||||
float root;
|
||||
float numerator = rx*rx*ry*ry - rx*rx*y1p*y1p - ry*ry*x1p*x1p;
|
||||
double root;
|
||||
double numerator = rx*rx*ry*ry - rx*rx*y1p*y1p - ry*ry*x1p*x1p;
|
||||
|
||||
if (numerator < 0.0) {
|
||||
// F.6.6 step 3 - |numerator < 0.0| is equivalent to the result of
|
||||
// F.6.6.2 (lamedh) being greater than one. What we have here is radii
|
||||
// that do not reach between segStart and segEnd, so we need to correct
|
||||
// them.
|
||||
float lamedh = 1.0 - numerator/(rx*rx*ry*ry); // equiv to eqn F.6.6.2
|
||||
float s = sqrt(lamedh);
|
||||
if (numerator >= 0.0) {
|
||||
root = sqrt(numerator/(rx*rx*y1p*y1p + ry*ry*x1p*x1p));
|
||||
if (largeArcFlag == sweepFlag)
|
||||
root = -root;
|
||||
} else {
|
||||
// F.6.6 step 3 - |numerator < 0.0|. This is equivalent to the result
|
||||
// of F.6.6.2 (lamedh) being greater than one. What we have here is
|
||||
// ellipse radii that are too small for the ellipse to reach between
|
||||
// segStart and segEnd. We scale the radii up uniformly so that the
|
||||
// ellipse is just big enough to fit (i.e. to the point where there is
|
||||
// exactly one solution).
|
||||
|
||||
double lamedh = 1.0 - numerator/(rx*rx*ry*ry); // equiv to eqn F.6.6.2
|
||||
double s = sqrt(lamedh);
|
||||
rx *= s; // F.6.6.3
|
||||
ry *= s;
|
||||
// rx and ry changed, so we have to recompute numerator
|
||||
numerator = rx*rx*ry*ry - rx*rx*y1p*y1p - ry*ry*x1p*x1p;
|
||||
NS_ABORT_IF_FALSE(numerator >= 0,
|
||||
"F.6.6.3 should prevent this. Will sqrt(-num)!");
|
||||
root = 0.0;
|
||||
}
|
||||
root = sqrt(numerator/(rx*rx*y1p*y1p + ry*ry*x1p*x1p));
|
||||
if (largeArcFlag == sweepFlag)
|
||||
root = -root;
|
||||
|
||||
float cxp = root * rx * y1p / ry; // F.6.5.2
|
||||
float cyp = -root * ry * x1p / rx;
|
||||
double cxp = root * rx * y1p / ry; // F.6.5.2
|
||||
double cyp = -root * ry * x1p / rx;
|
||||
|
||||
float theta, delta;
|
||||
theta = CalcVectorAngle(1.0, 0.0, (x1p-cxp)/rx, (y1p-cyp)/ry); // F.6.5.5
|
||||
delta = CalcVectorAngle((x1p-cxp)/rx, (y1p-cyp)/ry,
|
||||
(-x1p-cxp)/rx, (-y1p-cyp)/ry); // F.6.5.6
|
||||
double theta, delta;
|
||||
theta = CalcVectorAngle(1.0, 0.0, (x1p-cxp)/rx, (y1p-cyp)/ry); // F.6.5.5
|
||||
delta = CalcVectorAngle((x1p-cxp)/rx, (y1p-cyp)/ry,
|
||||
(-x1p-cxp)/rx, (-y1p-cyp)/ry); // F.6.5.6
|
||||
if (!sweepFlag && delta > 0)
|
||||
delta -= 2.0 * M_PI;
|
||||
else if (sweepFlag && delta < 0)
|
||||
delta += 2.0 * M_PI;
|
||||
|
||||
float tx1, ty1, tx2, ty2;
|
||||
double tx1, ty1, tx2, ty2;
|
||||
tx1 = -cos(angle)*rx*sin(theta) - sin(angle)*ry*cos(theta);
|
||||
ty1 = -sin(angle)*rx*sin(theta) + cos(angle)*ry*cos(theta);
|
||||
tx2 = -cos(angle)*rx*sin(theta+delta) - sin(angle)*ry*cos(theta+delta);
|
||||
|
6
layout/svg/crashtests/610594-1.html
Normal file
6
layout/svg/crashtests/610594-1.html
Normal file
@ -0,0 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<svg><path d="M 0 5 a 2 5 -30 104 -5" marker-mid="url(#q)"></path></svg>
|
||||
</body>
|
||||
</html>
|
@ -97,7 +97,9 @@ load 587336-1.html
|
||||
load 590291-1.svg
|
||||
load 601999-1.html
|
||||
load 605626-1.svg
|
||||
load 610594-1.html
|
||||
load 610954-1.html
|
||||
load 612662-1.svg
|
||||
load 612662-2.svg
|
||||
|
||||
load 621598-1.svg
|
||||
|
Loading…
Reference in New Issue
Block a user