зеркало из https://github.com/mozilla/gecko-dev.git
Bug 342200 - Remove nsSVGPathGeometryFrame subclasses. r+sr=roc
This commit is contained in:
Родитель
aa0670b627
Коммит
3f9980a5fd
|
@ -110,6 +110,7 @@ CPPSRCS = \
|
|||
nsSVGNumberList.cpp \
|
||||
nsSVGPathDataParser.cpp \
|
||||
nsSVGPathElement.cpp \
|
||||
nsSVGPathGeometryElement.cpp \
|
||||
nsSVGPathSeg.cpp \
|
||||
nsSVGPathSegList.cpp \
|
||||
nsSVGPatternElement.cpp \
|
||||
|
|
|
@ -36,12 +36,13 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsIDOMSVGCircleElement.h"
|
||||
#include "nsSVGLength2.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGCircleElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGCircleElementBase;
|
||||
|
||||
class nsSVGCircleElement : public nsSVGCircleElementBase,
|
||||
public nsIDOMSVGCircleElement
|
||||
|
@ -61,6 +62,9 @@ public:
|
|||
NS_FORWARD_NSIDOMELEMENT(nsSVGCircleElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGCircleElementBase::)
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
|
@ -137,3 +141,15 @@ nsSVGCircleElement::GetLengthInfo()
|
|||
NS_ARRAY_LENGTH(sLengthInfo));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
void
|
||||
nsSVGCircleElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, r;
|
||||
|
||||
GetAnimatedLengthValues(&x, &y, &r, nsnull);
|
||||
|
||||
cairo_arc(aCtx, x, y, r, 0, 2*M_PI);
|
||||
}
|
||||
|
|
|
@ -37,12 +37,13 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsIDOMSVGEllipseElement.h"
|
||||
#include "nsSVGLength2.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGEllipseElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGEllipseElementBase;
|
||||
|
||||
class nsSVGEllipseElement : public nsSVGEllipseElementBase,
|
||||
public nsIDOMSVGEllipseElement
|
||||
|
@ -62,6 +63,9 @@ public:
|
|||
NS_FORWARD_NSIDOMELEMENT(nsSVGEllipseElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGEllipseElementBase::)
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
|
@ -144,3 +148,20 @@ nsSVGEllipseElement::GetLengthInfo()
|
|||
return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
|
||||
NS_ARRAY_LENGTH(sLengthInfo));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
void
|
||||
nsSVGEllipseElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, rx, ry;
|
||||
|
||||
GetAnimatedLengthValues(&x, &y, &rx, &ry, nsnull);
|
||||
|
||||
cairo_save(aCtx);
|
||||
cairo_translate(aCtx, x, y);
|
||||
cairo_scale(aCtx, rx, ry);
|
||||
cairo_arc(aCtx, 0, 0, 1, 0, 2 * M_PI);
|
||||
cairo_restore(aCtx);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#include "nsSVGPreserveAspectRatio.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsIDOMSVGImageElement.h"
|
||||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsImageLoadingContent.h"
|
||||
|
@ -57,7 +57,7 @@
|
|||
class nsIDOMSVGAnimatedString;
|
||||
class nsIDOMSVGAnimatedPreserveAspectRatio;
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGImageElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGImageElementBase;
|
||||
|
||||
class nsSVGImageElement : public nsSVGImageElementBase,
|
||||
public nsIDOMSVGImageElement,
|
||||
|
@ -92,6 +92,9 @@ public:
|
|||
|
||||
NS_IMETHODIMP_(PRBool) IsAttributeMapped(const nsIAtom* name) const;
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
|
@ -316,3 +319,21 @@ nsSVGImageElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
||||
nsSVGImageElementBase::IsAttributeMapped(name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
/* For the purposes of the update/invalidation logic pretend to
|
||||
be a rectangle. */
|
||||
void
|
||||
nsSVGImageElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, width, height;
|
||||
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
cairo_rectangle(aCtx, x, y, width, height);
|
||||
}
|
||||
|
|
|
@ -37,12 +37,12 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsIDOMSVGLineElement.h"
|
||||
#include "nsSVGLength2.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGLineElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGLineElementBase;
|
||||
|
||||
class nsSVGLineElement : public nsSVGLineElementBase,
|
||||
public nsIDOMSVGLineElement
|
||||
|
@ -65,6 +65,11 @@ public:
|
|||
// nsIContent interface
|
||||
NS_IMETHODIMP_(PRBool) IsAttributeMapped(const nsIAtom* name) const;
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
|
@ -161,3 +166,37 @@ nsSVGLineElement::GetLengthInfo()
|
|||
return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
|
||||
NS_ARRAY_LENGTH(sLengthInfo));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
void
|
||||
nsSVGLineElement::GetMarkPoints(nsVoidArray *aMarks) {
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nsnull);
|
||||
|
||||
nsSVGMark *m1, *m2;
|
||||
m1 = new nsSVGMark();
|
||||
m2 = new nsSVGMark();
|
||||
|
||||
m1->x = x1;
|
||||
m1->y = y1;
|
||||
m2->x = x2;
|
||||
m2->y = y2;
|
||||
m1->angle = m2->angle = atan2(y2 - y1, x2 - x1);
|
||||
|
||||
aMarks->AppendElement(m1);
|
||||
aMarks->AppendElement(m2);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGLineElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nsnull);
|
||||
|
||||
cairo_move_to(aCtx, x1, y1);
|
||||
cairo_line_to(aCtx, x2, y2);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsSVGPathDataParser.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsISVGValueUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Path)
|
||||
|
||||
|
@ -403,6 +404,478 @@ nsSVGPathElement::GetFlattenedPath()
|
|||
return retval;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
PRBool
|
||||
nsSVGPathElement::IsDependentAttribute(nsIAtom *aName)
|
||||
{
|
||||
if (aName == nsGkAtoms::d)
|
||||
return PR_TRUE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGPathElement::IsMarkable()
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static double
|
||||
CalcVectorAngle(double ux, double uy, double vx, double vy)
|
||||
{
|
||||
double ta = atan2(uy, ux);
|
||||
double tb = atan2(vy, vx);
|
||||
if (tb >= ta)
|
||||
return tb-ta;
|
||||
return 2 * M_PI - (ta-tb);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPathElement::GetMarkPoints(nsVoidArray *aMarks) {
|
||||
if (NS_FAILED(CreatePathSegList()))
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mSegments->GetNumberOfItems(&count);
|
||||
nsCOMPtr<nsIDOMSVGPathSeg> segment;
|
||||
|
||||
float cx = 0.0f; // current point
|
||||
float cy = 0.0f;
|
||||
|
||||
float cx1 = 0.0f; // last controlpoint (for s,S,t,T)
|
||||
float cy1 = 0.0f;
|
||||
|
||||
PRUint16 lastSegmentType = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
|
||||
|
||||
float px, py; // subpath initial point
|
||||
float pathAngle;
|
||||
PRUint32 pathIndex;
|
||||
|
||||
float prevAngle = 0, startAngle, endAngle;
|
||||
|
||||
PRBool newSegment = PR_FALSE;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPathSeg> segment;
|
||||
mSegments->GetItem(i, getter_AddRefs(segment));
|
||||
|
||||
PRUint16 type = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
|
||||
segment->GetPathSegType(&type);
|
||||
|
||||
float x, y;
|
||||
PRBool absCoords = PR_FALSE;
|
||||
|
||||
switch (type) {
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CLOSEPATH:
|
||||
{
|
||||
x = px;
|
||||
y = py;
|
||||
startAngle = endAngle = atan2(y - cy, x - cx);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_MOVETO_REL:
|
||||
{
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegMovetoRel> moveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(moveseg, "interface not implemented");
|
||||
moveseg->GetX(&x);
|
||||
moveseg->GetY(&y);
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegMovetoAbs> moveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(moveseg, "interface not implemented");
|
||||
moveseg->GetX(&x);
|
||||
moveseg->GetY(&y);
|
||||
}
|
||||
px = x;
|
||||
py = y;
|
||||
startAngle = endAngle = prevAngle;
|
||||
newSegment = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_REL:
|
||||
{
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoRel> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
lineseg->GetY(&y);
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoAbs> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
lineseg->GetY(&y);
|
||||
}
|
||||
startAngle = endAngle = atan2(y - cy, x - cx);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_REL:
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
x += cx;
|
||||
y += cy;
|
||||
x1 += cx;
|
||||
y1 += cy;
|
||||
x2 += cx;
|
||||
y2 += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
}
|
||||
|
||||
cx1 = x2;
|
||||
cy1 = y2;
|
||||
|
||||
if (x1 == cx && y1 == cy) {
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
|
||||
if (x2 == x && y2 == y) {
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
}
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y2, x - x2);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL:
|
||||
{
|
||||
float x1, y1;
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
x += cx;
|
||||
y += cy;
|
||||
x1 += cx;
|
||||
y1 += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
}
|
||||
|
||||
cx1 = x1;
|
||||
cy1 = y1;
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y1, x - x1);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_ARC_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_ARC_REL:
|
||||
{
|
||||
float r1, r2, angle;
|
||||
PRBool largeArcFlag, sweepFlag;
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegArcRel> arcseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(arcseg, "interface not implemented");
|
||||
arcseg->GetX(&x);
|
||||
arcseg->GetY(&y);
|
||||
arcseg->GetR1(&r1);
|
||||
arcseg->GetR2(&r2);
|
||||
arcseg->GetAngle(&angle);
|
||||
arcseg->GetLargeArcFlag(&largeArcFlag);
|
||||
arcseg->GetSweepFlag(&sweepFlag);
|
||||
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegArcAbs> arcseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(arcseg, "interface not implemented");
|
||||
arcseg->GetX(&x);
|
||||
arcseg->GetY(&y);
|
||||
arcseg->GetR1(&r1);
|
||||
arcseg->GetR2(&r2);
|
||||
arcseg->GetAngle(&angle);
|
||||
arcseg->GetLargeArcFlag(&largeArcFlag);
|
||||
arcseg->GetSweepFlag(&sweepFlag);
|
||||
}
|
||||
|
||||
/* check for degenerate ellipse */
|
||||
if (r1 == 0.0 || r2 == 0.0) {
|
||||
startAngle = endAngle = atan2(y - cy, x - cx);
|
||||
break;
|
||||
}
|
||||
|
||||
r1 = fabs(r1); r2 = fabs(r2);
|
||||
|
||||
float xp, yp, cxp, cyp;
|
||||
|
||||
/* slope fun&games ... see SVG spec, section F.6 */
|
||||
angle = angle*M_PI/180.0;
|
||||
xp = cos(angle)*(cx-x)/2.0 + sin(angle)*(cy-y)/2.0;
|
||||
yp = -sin(angle)*(cx-x)/2.0 + cos(angle)*(cy-y)/2.0;
|
||||
|
||||
/* make sure radii are large enough */
|
||||
float root, numerator = r1*r1*r2*r2 - r1*r1*yp*yp - r2*r2*xp*xp;
|
||||
if (numerator < 0.0) {
|
||||
float s = sqrt(1.0 - numerator/(r1*r1*r2*r2));
|
||||
r1 *= s;
|
||||
r2 *= s;
|
||||
root = 0.0;
|
||||
} else {
|
||||
root = sqrt(numerator/(r1*r1*yp*yp + r2*r2*xp*xp));
|
||||
if (largeArcFlag == sweepFlag)
|
||||
root = -root;
|
||||
}
|
||||
cxp = root*r1*yp/r2;
|
||||
cyp = -root*r2*xp/r1;
|
||||
|
||||
float theta, delta;
|
||||
theta = CalcVectorAngle(1.0, 0.0, (xp-cxp)/r1, (yp-cyp)/r2);
|
||||
delta = CalcVectorAngle((xp-cxp)/r1, (yp-cyp)/r2,
|
||||
(-xp-cxp)/r1, (-yp-cyp)/r2);
|
||||
if (!sweepFlag && delta > 0)
|
||||
delta -= 2.0*M_PI;
|
||||
else if (sweepFlag && delta < 0)
|
||||
delta += 2.0*M_PI;
|
||||
|
||||
float tx1, ty1, tx2, ty2;
|
||||
tx1 = -cos(angle)*r1*sin(theta) - sin(angle)*r2*cos(theta);
|
||||
ty1 = -sin(angle)*r1*sin(theta) + cos(angle)*r2*cos(theta);
|
||||
tx2 = -cos(angle)*r1*sin(theta+delta) - sin(angle)*r2*cos(theta+delta);
|
||||
ty2 = -sin(angle)*r1*sin(theta+delta) + cos(angle)*r2*cos(theta+delta);
|
||||
|
||||
if (delta < 0.0f) {
|
||||
tx1 = -tx1;
|
||||
ty1 = -ty1;
|
||||
tx2 = -tx2;
|
||||
ty2 = -ty2;
|
||||
}
|
||||
|
||||
startAngle = atan2(ty1, tx1);
|
||||
endAngle = atan2(ty2, tx2);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL:
|
||||
{
|
||||
y = cy;
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoHorizontalRel> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
x += cx;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoHorizontalAbs> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
}
|
||||
startAngle = endAngle = atan2(0, x - cx);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_VERTICAL_REL:
|
||||
{
|
||||
x = cx;
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoVerticalRel> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetY(&y);
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoVerticalAbs> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetY(&y);
|
||||
}
|
||||
startAngle = endAngle = atan2(y - cy, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
if (lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS ) {
|
||||
// the first controlpoint is the reflection of the last one about the current point:
|
||||
x1 = 2*cx - cx1;
|
||||
y1 = 2*cy - cy1;
|
||||
}
|
||||
else {
|
||||
// the first controlpoint is equal to the current point:
|
||||
x1 = cx;
|
||||
y1 = cy;
|
||||
}
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicSmoothRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
x += cx;
|
||||
y += cy;
|
||||
x2 += cx;
|
||||
y2 += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicSmoothAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
}
|
||||
|
||||
cx1 = x2;
|
||||
cy1 = y2;
|
||||
|
||||
if (x1 == cx && y1 == cy) {
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
|
||||
if (x2 == x && y2 == y) {
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
}
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y2, x - x2);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
|
||||
{
|
||||
float x1, y1;
|
||||
|
||||
if (lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS ) {
|
||||
// the first controlpoint is the reflection of the last one about the current point:
|
||||
x1 = 2*cx - cx1;
|
||||
y1 = 2*cy - cy1;
|
||||
}
|
||||
else {
|
||||
// the first controlpoint is equal to the current point:
|
||||
x1 = cx;
|
||||
y1 = cy;
|
||||
}
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticSmoothRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticSmoothAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
}
|
||||
|
||||
cx1 = x1;
|
||||
cy1 = y1;
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y1, x - x1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION(1==0, "unknown path segment");
|
||||
break;
|
||||
}
|
||||
lastSegmentType = type;
|
||||
|
||||
if (newSegment &&
|
||||
type != nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS &&
|
||||
type != nsIDOMSVGPathSeg::PATHSEG_MOVETO_REL) {
|
||||
pathIndex = aMarks->Count() - 1;
|
||||
pathAngle = startAngle;
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = pathAngle;
|
||||
newSegment = PR_FALSE;
|
||||
prevAngle = endAngle;
|
||||
} else if (type == nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS ||
|
||||
type == nsIDOMSVGPathSeg::PATHSEG_MOVETO_REL) {
|
||||
if (aMarks->Count())
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = prevAngle;
|
||||
} else {
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, startAngle);
|
||||
prevAngle = endAngle;
|
||||
}
|
||||
|
||||
nsSVGMark *mark = new nsSVGMark;
|
||||
mark->x = x;
|
||||
mark->y = y;
|
||||
aMarks->AppendElement(mark);
|
||||
|
||||
if (type == nsIDOMSVGPathSeg::PATHSEG_CLOSEPATH) {
|
||||
prevAngle = nsSVGUtils::AngleBisect(endAngle, pathAngle);
|
||||
((nsSVGMark *)aMarks->ElementAt(pathIndex))->angle = prevAngle;
|
||||
}
|
||||
|
||||
cx = x;
|
||||
cy = y;
|
||||
}
|
||||
|
||||
if (aMarks->Count())
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = prevAngle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==================================================================
|
||||
// nsSVGPathList
|
||||
|
||||
|
@ -537,4 +1010,8 @@ nsSVGFlattenedPath::FindPoint(float aAdvance, float aXOffset, float aYOffset,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsSVGPathElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
mPathData.Playback(aCtx);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#ifndef __NS_SVGPATHELEMENT_H__
|
||||
#define __NS_SVGPATHELEMENT_H__
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsIDOMSVGPathElement.h"
|
||||
#include "nsIDOMSVGAnimatedPathData.h"
|
||||
|
||||
|
@ -80,7 +80,7 @@ public:
|
|||
float *aX, float *aY, float *aAngle);
|
||||
};
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGPathElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGPathElementBase;
|
||||
|
||||
class nsSVGPathElement : public nsSVGPathElementBase,
|
||||
public nsIDOMSVGPathElement,
|
||||
|
@ -113,6 +113,12 @@ public:
|
|||
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType);
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual PRBool IsDependentAttribute(nsIAtom *aName);
|
||||
virtual PRBool IsMarkable();
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
nsSVGFlattenedPath *GetFlattenedPath();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
|
||||
nsSVGPathGeometryElement::nsSVGPathGeometryElement(nsINodeInfo *aNodeInfo)
|
||||
: nsSVGPathGeometryElementBase(aNodeInfo)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGPathGeometryElement::IsDependentAttribute(nsIAtom *aName)
|
||||
{
|
||||
// Check for nsSVGLength2 attribute
|
||||
LengthAttributesInfo info = GetLengthInfo();
|
||||
for (PRUint32 i = 0; i < info.mLengthCount; i++) {
|
||||
if (aName == *info.mLengthInfo[i].mName) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGPathGeometryElement::IsMarkable()
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPathGeometryElement::GetMarkPoints(nsVoidArray *aMarks)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __NS_SVGPATHGEOMETRYELEMENT_H__
|
||||
#define __NS_SVGPATHGEOMETRYELEMENT_H__
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "cairo.h"
|
||||
|
||||
struct nsSVGMark {
|
||||
float x, y, angle;
|
||||
};
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGPathGeometryElementBase;
|
||||
|
||||
class nsSVGPathGeometryElement : public nsSVGPathGeometryElementBase
|
||||
{
|
||||
public:
|
||||
nsSVGPathGeometryElement(nsINodeInfo *aNodeInfo);
|
||||
|
||||
virtual PRBool IsDependentAttribute(nsIAtom *aName);
|
||||
virtual PRBool IsMarkable();
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx) = 0;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -36,14 +36,16 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsSVGAtoms.h"
|
||||
#include "nsSVGPointList.h"
|
||||
#include "nsIDOMSVGPolygonElement.h"
|
||||
#include "nsIDOMSVGAnimatedPoints.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGPolygonElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGPolygonElementBase;
|
||||
|
||||
class nsSVGPolygonElement : public nsSVGPolygonElementBase,
|
||||
public nsIDOMSVGPolygonElement,
|
||||
|
@ -69,7 +71,13 @@ public:
|
|||
|
||||
// nsIContent interface
|
||||
NS_IMETHODIMP_(PRBool) IsAttributeMapped(const nsIAtom* name) const;
|
||||
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual PRBool IsDependentAttribute(nsIAtom *aName);
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDOMSVGPointList> mPoints;
|
||||
};
|
||||
|
@ -159,3 +167,95 @@ nsSVGPolygonElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
||||
nsSVGPolygonElementBase::IsAttributeMapped(name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
PRBool
|
||||
nsSVGPolygonElement::IsDependentAttribute(nsIAtom *aName)
|
||||
{
|
||||
if (aName == nsGkAtoms::points)
|
||||
return PR_TRUE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPolygonElement::GetMarkPoints(nsVoidArray *aMarks)
|
||||
{
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
float px = 0.0, py = 0.0, prevAngle, startAngle;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
|
||||
float angle = atan2(y-py, x-px);
|
||||
if (i == 1)
|
||||
startAngle = angle;
|
||||
else if (i > 1)
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, angle);
|
||||
|
||||
nsSVGMark *mark;
|
||||
mark = new nsSVGMark;
|
||||
mark->x = x;
|
||||
mark->y = y;
|
||||
aMarks->AppendElement(mark);
|
||||
|
||||
prevAngle = angle;
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
|
||||
float nx, ny, angle;
|
||||
mPoints->GetItem(0, getter_AddRefs(point));
|
||||
point->GetX(&nx);
|
||||
point->GetY(&ny);
|
||||
angle = atan2(ny - py, nx - px);
|
||||
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, angle);
|
||||
((nsSVGMark *)aMarks->ElementAt(0))->angle =
|
||||
nsSVGUtils::AngleBisect(angle, startAngle);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPolygonElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
if (i == 0)
|
||||
cairo_move_to(aCtx, x, y);
|
||||
else
|
||||
cairo_line_to(aCtx, x, y);
|
||||
}
|
||||
// the difference between a polyline and a polygon is that the
|
||||
// polygon is closed:
|
||||
cairo_close_path(aCtx);
|
||||
}
|
||||
|
|
|
@ -36,14 +36,16 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsSVGAtoms.h"
|
||||
#include "nsSVGPointList.h"
|
||||
#include "nsIDOMSVGPolylineElement.h"
|
||||
#include "nsIDOMSVGAnimatedPoints.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGPolylineElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGPolylineElementBase;
|
||||
|
||||
class nsSVGPolylineElement : public nsSVGPolylineElementBase,
|
||||
public nsIDOMSVGPolylineElement,
|
||||
|
@ -69,7 +71,13 @@ public:
|
|||
|
||||
// nsIContent interface
|
||||
NS_IMETHODIMP_(PRBool) IsAttributeMapped(const nsIAtom* name) const;
|
||||
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual PRBool IsDependentAttribute(nsIAtom *aName);
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIDOMSVGPointList> mPoints;
|
||||
};
|
||||
|
@ -159,3 +167,83 @@ nsSVGPolylineElement::IsAttributeMapped(const nsIAtom* name) const
|
|||
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
||||
nsSVGPolylineElementBase::IsAttributeMapped(name);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
PRBool
|
||||
nsSVGPolylineElement::IsDependentAttribute(nsIAtom *aName)
|
||||
{
|
||||
if (aName == nsGkAtoms::points)
|
||||
return PR_TRUE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPolylineElement::GetMarkPoints(nsVoidArray *aMarks)
|
||||
{
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
float px = 0.0, py = 0.0, prevAngle;
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
|
||||
float angle = atan2(y-py, x-px);
|
||||
if (i == 1)
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = angle;
|
||||
else if (i > 1)
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, angle);
|
||||
|
||||
nsSVGMark *mark;
|
||||
mark = new nsSVGMark;
|
||||
mark->x = x;
|
||||
mark->y = y;
|
||||
aMarks->AppendElement(mark);
|
||||
|
||||
prevAngle = angle;
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = prevAngle;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPolylineElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
if (i == 0)
|
||||
cairo_move_to(aCtx, x, y);
|
||||
else
|
||||
cairo_line_to(aCtx, x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,12 +37,12 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGGraphicElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
#include "nsIDOMSVGRectElement.h"
|
||||
#include "nsSVGLength2.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
typedef nsSVGGraphicElement nsSVGRectElementBase;
|
||||
typedef nsSVGPathGeometryElement nsSVGRectElementBase;
|
||||
|
||||
class nsSVGRectElement : public nsSVGRectElementBase,
|
||||
public nsIDOMSVGRectElement
|
||||
|
@ -62,6 +62,9 @@ public:
|
|||
NS_FORWARD_NSIDOMELEMENT(nsSVGRectElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGRectElementBase::)
|
||||
|
||||
// nsSVGPathGeometryElement methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
|
@ -158,3 +161,77 @@ nsSVGRectElement::GetLengthInfo()
|
|||
return LengthAttributesInfo(mLengthAttributes, sLengthInfo,
|
||||
NS_ARRAY_LENGTH(sLengthInfo));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryElement methods
|
||||
|
||||
void
|
||||
nsSVGRectElement::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, width, height, rx, ry;
|
||||
|
||||
GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nsnull);
|
||||
|
||||
/* In a perfect world, this would be handled by the DOM, and
|
||||
return a DOM exception. */
|
||||
if (width <= 0 || height <= 0 || ry < 0 || rx < 0)
|
||||
return;
|
||||
|
||||
/* Clamp rx and ry to half the rect's width and height respectively. */
|
||||
float halfWidth = width/2;
|
||||
float halfHeight = height/2;
|
||||
if (rx > halfWidth)
|
||||
rx = halfWidth;
|
||||
if (ry > halfHeight)
|
||||
ry = halfHeight;
|
||||
|
||||
/* If either the 'rx' or the 'ry' attribute isn't set in the markup, then we
|
||||
have to set it to the value of the other. We do this after clamping rx and
|
||||
ry since omitting one of the attributes implicitly means they should both
|
||||
be the same. */
|
||||
PRBool hasRx = HasAttr(kNameSpaceID_None, nsGkAtoms::rx);
|
||||
PRBool hasRy = HasAttr(kNameSpaceID_None, nsGkAtoms::ry);
|
||||
if (hasRx && !hasRy)
|
||||
ry = rx;
|
||||
else if (hasRy && !hasRx)
|
||||
rx = ry;
|
||||
|
||||
/* However, we may now have made rx > width/2 or else ry > height/2. (If this
|
||||
is the case, we know we must be giving rx and ry the same value.) */
|
||||
if (rx > halfWidth)
|
||||
rx = ry = halfWidth;
|
||||
else if (ry > halfHeight)
|
||||
rx = ry = halfHeight;
|
||||
|
||||
if (rx == 0 && ry == 0) {
|
||||
cairo_rectangle(aCtx, x, y, width, height);
|
||||
} else {
|
||||
// Conversion factor used for ellipse to bezier conversion.
|
||||
// Gives radial error of 0.0273% in circular case.
|
||||
// See comp.graphics.algorithms FAQ 4.04
|
||||
const float magic = 4*(sqrt(2.)-1)/3;
|
||||
|
||||
cairo_move_to(aCtx, x+rx, y);
|
||||
cairo_line_to(aCtx, x+width-rx, y);
|
||||
cairo_curve_to(aCtx,
|
||||
x+width-rx + magic*rx, y,
|
||||
x+width, y+ry-magic*ry,
|
||||
x+width, y+ry);
|
||||
cairo_line_to(aCtx, x+width, y+height-ry);
|
||||
cairo_curve_to(aCtx,
|
||||
x+width, y+height-ry + magic*ry,
|
||||
x+width-rx + magic*rx, y+height,
|
||||
x+width-rx, y+height);
|
||||
cairo_line_to(aCtx, x+rx, y+height);
|
||||
cairo_curve_to(aCtx,
|
||||
x+rx - magic*rx, y+height,
|
||||
x, y+height-ry + magic*ry,
|
||||
x, y+height-ry);
|
||||
cairo_line_to(aCtx, x, y+ry);
|
||||
cairo_curve_to(aCtx,
|
||||
x, y+ry - magic*ry,
|
||||
x+rx - magic*rx, y,
|
||||
x+rx, y);
|
||||
cairo_close_path(aCtx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,17 +181,7 @@ NS_NewSVGOuterSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleCo
|
|||
nsIFrame*
|
||||
NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGPolylineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGPolygonFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGCircleFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGEllipseFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGLineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGRectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
NS_NewSVGPathGeometryFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGGFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
|
@ -201,8 +191,6 @@ nsIFrame*
|
|||
NS_NewSVGForeignObjectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
#endif
|
||||
nsIFrame*
|
||||
NS_NewSVGPathFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGGlyphFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* parent, nsStyleContext* aContext);
|
||||
nsIFrame*
|
||||
NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
@ -7707,28 +7695,22 @@ nsCSSFrameConstructor::ConstructSVGFrame(nsFrameConstructorState& aState,
|
|||
else if (aTag == nsSVGAtoms::g) {
|
||||
newFrame = NS_NewSVGGFrame(mPresShell, aContent, aStyleContext);
|
||||
}
|
||||
else if (aTag == nsSVGAtoms::polygon)
|
||||
newFrame = NS_NewSVGPolygonFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::polyline)
|
||||
newFrame = NS_NewSVGPolylineFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::circle)
|
||||
newFrame = NS_NewSVGCircleFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::polygon ||
|
||||
aTag == nsSVGAtoms::polyline ||
|
||||
aTag == nsSVGAtoms::circle ||
|
||||
aTag == nsSVGAtoms::ellipse ||
|
||||
aTag == nsSVGAtoms::line ||
|
||||
aTag == nsSVGAtoms::rect ||
|
||||
aTag == nsSVGAtoms::path)
|
||||
newFrame = NS_NewSVGPathGeometryFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::defs) {
|
||||
newFrame = NS_NewSVGContainerFrame(mPresShell, aContent, aStyleContext);
|
||||
}
|
||||
else if (aTag == nsSVGAtoms::ellipse)
|
||||
newFrame = NS_NewSVGEllipseFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::line)
|
||||
newFrame = NS_NewSVGLineFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::rect)
|
||||
newFrame = NS_NewSVGRectFrame(mPresShell, aContent, aStyleContext);
|
||||
#ifdef MOZ_SVG_FOREIGNOBJECT
|
||||
else if (aTag == nsSVGAtoms::foreignObject) {
|
||||
newFrame = NS_NewSVGForeignObjectFrame(mPresShell, aContent, aStyleContext);
|
||||
}
|
||||
#endif
|
||||
else if (aTag == nsSVGAtoms::path)
|
||||
newFrame = NS_NewSVGPathFrame(mPresShell, aContent, aStyleContext);
|
||||
else if (aTag == nsSVGAtoms::text) {
|
||||
newFrame = NS_NewSVGTextFrame(mPresShell, aContent, aStyleContext);
|
||||
}
|
||||
|
|
|
@ -67,10 +67,8 @@ REQUIRES = xpcom \
|
|||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsSVGCircleFrame.cpp \
|
||||
nsSVGClipPathFrame.cpp \
|
||||
nsSVGContainerFrame.cpp \
|
||||
nsSVGEllipseFrame.cpp \
|
||||
nsSVGFilterFrame.cpp \
|
||||
nsSVGGFrame.cpp \
|
||||
nsSVGGenericContainerFrame.cpp \
|
||||
|
@ -80,17 +78,12 @@ CPPSRCS = \
|
|||
nsSVGImageFrame.cpp \
|
||||
nsSVGInnerSVGFrame.cpp \
|
||||
nsSVGLeafFrame.cpp \
|
||||
nsSVGLineFrame.cpp \
|
||||
nsSVGMarkerFrame.cpp \
|
||||
nsSVGMaskFrame.cpp \
|
||||
nsSVGOuterSVGFrame.cpp \
|
||||
nsSVGPaintServerFrame.cpp \
|
||||
nsSVGPathFrame.cpp \
|
||||
nsSVGPathGeometryFrame.cpp \
|
||||
nsSVGPatternFrame.cpp \
|
||||
nsSVGPolygonFrame.cpp \
|
||||
nsSVGPolylineFrame.cpp \
|
||||
nsSVGRectFrame.cpp \
|
||||
nsSVGStopFrame.cpp \
|
||||
nsSVGTextFrame.cpp \
|
||||
nsSVGTextPathFrame.cpp \
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGCircleElement.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
class nsSVGCircleFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
protected:
|
||||
friend nsIFrame*
|
||||
NS_NewSVGCircleFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
nsSVGCircleFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgCircleFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGCircle"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
// nsSVGPathGeometryFrame methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGCircleFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGCircleElement> circle = do_QueryInterface(aContent);
|
||||
if (!circle) {
|
||||
#ifdef DEBUG
|
||||
printf("warning: trying to construct an SVGCircleFrame for a content element that doesn't support the right interfaces\n");
|
||||
#endif
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGCircleFrame(aContext);
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGCircleFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgCircleFrame;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGCircleFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::cx ||
|
||||
aAttribute == nsGkAtoms::cy ||
|
||||
aAttribute == nsGkAtoms::r)) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryFrame methods:
|
||||
|
||||
void
|
||||
nsSVGCircleFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, r;
|
||||
|
||||
nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent);
|
||||
element->GetAnimatedLengthValues(&x, &y, &r, nsnull);
|
||||
|
||||
cairo_arc(aCtx, x, y, r, 0, 2*M_PI);
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* William Cook <william.cook@crocodile-clips.com> (original author)
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGEllipseElement.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
class nsSVGEllipseFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
friend nsIFrame*
|
||||
NS_NewSVGEllipseFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
nsSVGEllipseFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgEllipseFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGEllipse"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
// nsSVGPathGeometryFrame methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGEllipseFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGEllipseElement> ellipse = do_QueryInterface(aContent);
|
||||
if (!ellipse) {
|
||||
#ifdef DEBUG
|
||||
printf("warning: trying to construct an SVGEllipseFrame for a content element that doesn't support the right interfaces\n");
|
||||
#endif
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGEllipseFrame(aContext);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods:
|
||||
|
||||
nsIAtom *
|
||||
nsSVGEllipseFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgEllipseFrame;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGEllipseFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::cx ||
|
||||
aAttribute == nsGkAtoms::cy ||
|
||||
aAttribute == nsGkAtoms::rx ||
|
||||
aAttribute == nsGkAtoms::ry)) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
void
|
||||
nsSVGEllipseFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, rx, ry;
|
||||
|
||||
nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent);
|
||||
element->GetAnimatedLengthValues(&x, &y, &rx, &ry, nsnull);
|
||||
|
||||
cairo_save(aCtx);
|
||||
cairo_translate(aCtx, x, y);
|
||||
cairo_scale(aCtx, rx, ry);
|
||||
cairo_arc(aCtx, 0, 0, 1, 0, 2 * M_PI);
|
||||
cairo_restore(aCtx);
|
||||
}
|
|
@ -96,7 +96,6 @@ public:
|
|||
virtual nsresult GetFillPaintType() { return eStyleSVGPaintType_Color; }
|
||||
|
||||
// nsSVGPathGeometryFrame methods:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
virtual PRUint16 GetHittestMask();
|
||||
|
||||
// nsIFrame interface:
|
||||
|
@ -211,27 +210,6 @@ nsSVGImageFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
/* For the purposes of the update/invalidation logic pretend to
|
||||
be a rectangle. */
|
||||
void
|
||||
nsSVGImageFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, width, height;
|
||||
|
||||
nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent);
|
||||
element->GetAnimatedLengthValues(&x, &y, &width, &height, nsnull);
|
||||
|
||||
/* In a perfect world, this would be handled by the DOM, and
|
||||
return a DOM exception. */
|
||||
if (width == 0 || height == 0)
|
||||
return;
|
||||
|
||||
cairo_rectangle(aCtx, x, y, width, height);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGChildFrame methods:
|
||||
NS_IMETHODIMP
|
||||
|
@ -482,6 +460,9 @@ nsSVGImageFrame::ConvertFrame(gfxIImageFrame *aNewFrame)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometryFrame methods:
|
||||
|
||||
// Lie about our fill/stroke so that hit detection works properly
|
||||
|
||||
PRUint16
|
||||
|
|
|
@ -1,159 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* William Cook <william.cook@crocodile-clips.com> (original author)
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGLineElement.h"
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsSVGMarkerFrame.h"
|
||||
|
||||
class nsSVGLineFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
friend nsIFrame*
|
||||
NS_NewSVGLineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
nsSVGLineFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgLineFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGLine"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
// nsSVGPathGeometryFrame methods
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGLineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLineElement> line = do_QueryInterface(aContent);
|
||||
if (!line) {
|
||||
#ifdef DEBUG
|
||||
printf("warning: trying to construct an SVGLineFrame for a content element that doesn't support the right interfaces\n");
|
||||
#endif
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGLineFrame(aContext);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods:
|
||||
|
||||
nsIAtom *
|
||||
nsSVGLineFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgLineFrame;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGLineFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::x1 ||
|
||||
aAttribute == nsGkAtoms::y1 ||
|
||||
aAttribute == nsGkAtoms::x2 ||
|
||||
aAttribute == nsGkAtoms::y2)) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
void
|
||||
nsSVGLineFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent);
|
||||
element->GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nsnull);
|
||||
|
||||
// move to start coordinates then draw line to end coordinates
|
||||
cairo_move_to(aCtx, x1, y1);
|
||||
cairo_line_to(aCtx, x2, y2);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometry methods:
|
||||
|
||||
void
|
||||
nsSVGLineFrame::GetMarkPoints(nsVoidArray *aMarks) {
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent);
|
||||
element->GetAnimatedLengthValues(&x1, &y1, &x2, &y2, nsnull);
|
||||
|
||||
nsSVGMark *m1, *m2;
|
||||
m1 = new nsSVGMark();
|
||||
m2 = new nsSVGMark();
|
||||
|
||||
m1->x = x1;
|
||||
m1->y = y1;
|
||||
m2->x = x2;
|
||||
m2->y = y2;
|
||||
m1->angle = m2->angle = atan2(y2-y1, x2-x1);
|
||||
|
||||
aMarks->AppendElement(m1);
|
||||
aMarks->AppendElement(m2);
|
||||
}
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsISVGRendererCanvas.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsSVGMarkerElement.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsSVGMarkerFrame)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISVGValue)
|
||||
|
|
|
@ -49,10 +49,7 @@ class nsISVGRendererCanvas;
|
|||
class nsSVGPathGeometryFrame;
|
||||
class nsIURI;
|
||||
class nsIContent;
|
||||
|
||||
struct nsSVGMark {
|
||||
float x, y, angle;
|
||||
};
|
||||
struct nsSVGMark;
|
||||
|
||||
typedef nsSVGContainerFrame nsSVGMarkerFrameBase;
|
||||
|
||||
|
|
|
@ -1,596 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
* Daniele Nicolodi <daniele@grinta.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGAnimatedPathData.h"
|
||||
#include "nsIDOMSVGPathSegList.h"
|
||||
#include "nsIDOMSVGPathSeg.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGMarkerFrame.h"
|
||||
|
||||
class nsSVGPathFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
protected:
|
||||
friend nsIFrame*
|
||||
NS_NewSVGPathFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
public:
|
||||
nsSVGPathFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
// nsSVGPathGeometryFrame methods
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgPathFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGPath"), aResult);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGPathFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPathData> anim_data = do_QueryInterface(aContent);
|
||||
if (!anim_data) {
|
||||
#ifdef DEBUG
|
||||
printf("warning: trying to construct an SVGPathFrame for a content element that doesn't support the right interfaces\n");
|
||||
#endif
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGPathFrame(aContext);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGFrame methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPathFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::d) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
static double
|
||||
CalcVectorAngle(double ux, double uy, double vx, double vy)
|
||||
{
|
||||
double ta = atan2(uy, ux);
|
||||
double tb = atan2(vy, vx);
|
||||
if (tb >= ta)
|
||||
return tb-ta;
|
||||
return 2 * M_PI - (ta-tb);
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGPathFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
nsSVGPathElement *element = NS_STATIC_CAST(nsSVGPathElement*, mContent);
|
||||
element->mPathData.Playback(aCtx);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometry methods:
|
||||
|
||||
void
|
||||
nsSVGPathFrame::GetMarkPoints(nsVoidArray *aMarks) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegList> segmentList;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPathData> anim_data = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(anim_data,"wrong content element");
|
||||
anim_data->GetAnimatedPathSegList(getter_AddRefs(segmentList));
|
||||
NS_ASSERTION(segmentList, "no pathseglist");
|
||||
if (!segmentList) return;
|
||||
|
||||
PRUint32 count;
|
||||
segmentList->GetNumberOfItems(&count);
|
||||
nsCOMPtr<nsIDOMSVGPathSeg> segment;
|
||||
|
||||
float cx = 0.0f; // current point
|
||||
float cy = 0.0f;
|
||||
|
||||
float cx1 = 0.0f; // last controlpoint (for s,S,t,T)
|
||||
float cy1 = 0.0f;
|
||||
|
||||
PRUint16 lastSegmentType = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
|
||||
|
||||
float px, py; // subpath initial point
|
||||
float pathAngle;
|
||||
PRUint32 pathIndex;
|
||||
|
||||
float prevAngle = 0, startAngle, endAngle;
|
||||
|
||||
PRBool newSegment = PR_FALSE;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPathSeg> segment;
|
||||
segmentList->GetItem(i, getter_AddRefs(segment));
|
||||
|
||||
PRUint16 type = nsIDOMSVGPathSeg::PATHSEG_UNKNOWN;
|
||||
segment->GetPathSegType(&type);
|
||||
|
||||
float x, y;
|
||||
PRBool absCoords = PR_FALSE;
|
||||
|
||||
switch (type) {
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CLOSEPATH:
|
||||
{
|
||||
x = px;
|
||||
y = py;
|
||||
startAngle = endAngle = atan2(y - cy, x - cx);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_MOVETO_REL:
|
||||
{
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegMovetoRel> moveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(moveseg, "interface not implemented");
|
||||
moveseg->GetX(&x);
|
||||
moveseg->GetY(&y);
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegMovetoAbs> moveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(moveseg, "interface not implemented");
|
||||
moveseg->GetX(&x);
|
||||
moveseg->GetY(&y);
|
||||
}
|
||||
px = x;
|
||||
py = y;
|
||||
startAngle = endAngle = prevAngle;
|
||||
newSegment = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_REL:
|
||||
{
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoRel> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
lineseg->GetY(&y);
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoAbs> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
lineseg->GetY(&y);
|
||||
}
|
||||
startAngle = endAngle = atan2(y - cy, x - cx);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_REL:
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
x += cx;
|
||||
y += cy;
|
||||
x1 += cx;
|
||||
y1 += cy;
|
||||
x2 += cx;
|
||||
y2 += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
}
|
||||
|
||||
cx1 = x2;
|
||||
cy1 = y2;
|
||||
|
||||
if (x1 == cx && y1 == cy) {
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
|
||||
if (x2 == x && y2 == y) {
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
}
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y2, x - x2);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL:
|
||||
{
|
||||
float x1, y1;
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
x += cx;
|
||||
y += cy;
|
||||
x1 += cx;
|
||||
y1 += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX1(&x1);
|
||||
curveseg->GetY1(&y1);
|
||||
}
|
||||
|
||||
cx1 = x1;
|
||||
cy1 = y1;
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y1, x - x1);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_ARC_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_ARC_REL:
|
||||
{
|
||||
float r1, r2, angle;
|
||||
PRBool largeArcFlag, sweepFlag;
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegArcRel> arcseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(arcseg, "interface not implemented");
|
||||
arcseg->GetX(&x);
|
||||
arcseg->GetY(&y);
|
||||
arcseg->GetR1(&r1);
|
||||
arcseg->GetR2(&r2);
|
||||
arcseg->GetAngle(&angle);
|
||||
arcseg->GetLargeArcFlag(&largeArcFlag);
|
||||
arcseg->GetSweepFlag(&sweepFlag);
|
||||
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegArcAbs> arcseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(arcseg, "interface not implemented");
|
||||
arcseg->GetX(&x);
|
||||
arcseg->GetY(&y);
|
||||
arcseg->GetR1(&r1);
|
||||
arcseg->GetR2(&r2);
|
||||
arcseg->GetAngle(&angle);
|
||||
arcseg->GetLargeArcFlag(&largeArcFlag);
|
||||
arcseg->GetSweepFlag(&sweepFlag);
|
||||
}
|
||||
|
||||
/* check for degenerate ellipse */
|
||||
if (r1 == 0.0 || r2 == 0.0) {
|
||||
startAngle = endAngle = atan2(y - cy, x - cx);
|
||||
break;
|
||||
}
|
||||
|
||||
r1 = fabs(r1); r2 = fabs(r2);
|
||||
|
||||
float xp, yp, cxp, cyp;
|
||||
|
||||
/* slope fun&games ... see SVG spec, section F.6 */
|
||||
angle = angle*M_PI/180.0;
|
||||
xp = cos(angle)*(cx-x)/2.0 + sin(angle)*(cy-y)/2.0;
|
||||
yp = -sin(angle)*(cx-x)/2.0 + cos(angle)*(cy-y)/2.0;
|
||||
|
||||
/* make sure radii are large enough */
|
||||
float root, numerator = r1*r1*r2*r2 - r1*r1*yp*yp - r2*r2*xp*xp;
|
||||
if (numerator < 0.0) {
|
||||
float s = sqrt(1.0 - numerator/(r1*r1*r2*r2));
|
||||
r1 *= s;
|
||||
r2 *= s;
|
||||
root = 0.0;
|
||||
} else {
|
||||
root = sqrt(numerator/(r1*r1*yp*yp + r2*r2*xp*xp));
|
||||
if (largeArcFlag == sweepFlag)
|
||||
root = -root;
|
||||
}
|
||||
cxp = root*r1*yp/r2;
|
||||
cyp = -root*r2*xp/r1;
|
||||
|
||||
float theta, delta;
|
||||
theta = CalcVectorAngle(1.0, 0.0, (xp-cxp)/r1, (yp-cyp)/r2);
|
||||
delta = CalcVectorAngle((xp-cxp)/r1, (yp-cyp)/r2,
|
||||
(-xp-cxp)/r1, (-yp-cyp)/r2);
|
||||
if (!sweepFlag && delta > 0)
|
||||
delta -= 2.0*M_PI;
|
||||
else if (sweepFlag && delta < 0)
|
||||
delta += 2.0*M_PI;
|
||||
|
||||
float tx1, ty1, tx2, ty2;
|
||||
tx1 = -cos(angle)*r1*sin(theta) - sin(angle)*r2*cos(theta);
|
||||
ty1 = -sin(angle)*r1*sin(theta) + cos(angle)*r2*cos(theta);
|
||||
tx2 = -cos(angle)*r1*sin(theta+delta) - sin(angle)*r2*cos(theta+delta);
|
||||
ty2 = -sin(angle)*r1*sin(theta+delta) + cos(angle)*r2*cos(theta+delta);
|
||||
|
||||
if (delta < 0.0f) {
|
||||
tx1 = -tx1;
|
||||
ty1 = -ty1;
|
||||
tx2 = -tx2;
|
||||
ty2 = -ty2;
|
||||
}
|
||||
|
||||
startAngle = atan2(ty1, tx1);
|
||||
endAngle = atan2(ty2, tx2);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_HORIZONTAL_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_HORIZONTAL_REL:
|
||||
{
|
||||
y = cy;
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoHorizontalRel> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
x += cx;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoHorizontalAbs> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetX(&x);
|
||||
}
|
||||
startAngle = endAngle = atan2(0, x - cx);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_VERTICAL_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_LINETO_VERTICAL_REL:
|
||||
{
|
||||
x = cx;
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoVerticalRel> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetY(&y);
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegLinetoVerticalAbs> lineseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(lineseg, "interface not implemented");
|
||||
lineseg->GetY(&y);
|
||||
}
|
||||
startAngle = endAngle = atan2(y - cy, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
|
||||
{
|
||||
float x1, y1, x2, y2;
|
||||
|
||||
if (lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_CUBIC_SMOOTH_ABS ) {
|
||||
// the first controlpoint is the reflection of the last one about the current point:
|
||||
x1 = 2*cx - cx1;
|
||||
y1 = 2*cy - cy1;
|
||||
}
|
||||
else {
|
||||
// the first controlpoint is equal to the current point:
|
||||
x1 = cx;
|
||||
y1 = cy;
|
||||
}
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicSmoothRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
x += cx;
|
||||
y += cy;
|
||||
x2 += cx;
|
||||
y2 += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoCubicSmoothAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
curveseg->GetX2(&x2);
|
||||
curveseg->GetY2(&y2);
|
||||
}
|
||||
|
||||
cx1 = x2;
|
||||
cy1 = y2;
|
||||
|
||||
if (x1 == cx && y1 == cy) {
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
|
||||
if (x2 == x && y2 == y) {
|
||||
x2 = x1;
|
||||
y2 = y1;
|
||||
}
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y2, x - x2);
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
|
||||
absCoords = PR_TRUE;
|
||||
case nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
|
||||
{
|
||||
float x1, y1;
|
||||
|
||||
if (lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_ABS ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL ||
|
||||
lastSegmentType == nsIDOMSVGPathSeg::PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS ) {
|
||||
// the first controlpoint is the reflection of the last one about the current point:
|
||||
x1 = 2*cx - cx1;
|
||||
y1 = 2*cy - cy1;
|
||||
}
|
||||
else {
|
||||
// the first controlpoint is equal to the current point:
|
||||
x1 = cx;
|
||||
y1 = cy;
|
||||
}
|
||||
|
||||
if (!absCoords) {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticSmoothRel> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
x += cx;
|
||||
y += cy;
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPathSegCurvetoQuadraticSmoothAbs> curveseg = do_QueryInterface(segment);
|
||||
NS_ASSERTION(curveseg, "interface not implemented");
|
||||
curveseg->GetX(&x);
|
||||
curveseg->GetY(&y);
|
||||
}
|
||||
|
||||
cx1 = x1;
|
||||
cy1 = y1;
|
||||
|
||||
startAngle = atan2(y1 - cy, x1 - cx);
|
||||
endAngle = atan2(y - y1, x - x1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ASSERTION(1==0, "unknown path segment");
|
||||
break;
|
||||
}
|
||||
lastSegmentType = type;
|
||||
|
||||
if (newSegment &&
|
||||
type != nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS &&
|
||||
type != nsIDOMSVGPathSeg::PATHSEG_MOVETO_REL) {
|
||||
pathIndex = aMarks->Count() - 1;
|
||||
pathAngle = startAngle;
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = pathAngle;
|
||||
newSegment = PR_FALSE;
|
||||
prevAngle = endAngle;
|
||||
} else if (type == nsIDOMSVGPathSeg::PATHSEG_MOVETO_ABS ||
|
||||
type == nsIDOMSVGPathSeg::PATHSEG_MOVETO_REL) {
|
||||
if (aMarks->Count())
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = prevAngle;
|
||||
} else {
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, startAngle);
|
||||
prevAngle = endAngle;
|
||||
}
|
||||
|
||||
nsSVGMark *mark = new nsSVGMark;
|
||||
mark->x = x;
|
||||
mark->y = y;
|
||||
aMarks->AppendElement(mark);
|
||||
|
||||
if (type == nsIDOMSVGPathSeg::PATHSEG_CLOSEPATH) {
|
||||
prevAngle = nsSVGUtils::AngleBisect(endAngle, pathAngle);
|
||||
((nsSVGMark *)aMarks->ElementAt(pathIndex))->angle = prevAngle;
|
||||
}
|
||||
|
||||
cx = x;
|
||||
cy = y;
|
||||
}
|
||||
|
||||
if (aMarks->Count())
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = prevAngle;
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGPathFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgPathFrame;
|
||||
}
|
|
@ -63,6 +63,7 @@
|
|||
#include "nsSVGOuterSVGFrame.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsISVGCairoCanvas.h"
|
||||
#include "nsSVGPathGeometryElement.h"
|
||||
|
||||
struct nsSVGMarkerProperty {
|
||||
nsSVGMarkerFrame *mMarkerStart;
|
||||
|
@ -76,6 +77,17 @@ struct nsSVGMarkerProperty {
|
|||
{}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGPathGeometryFrame(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent,
|
||||
nsStyleContext* aContext)
|
||||
{
|
||||
return new (aPresShell) nsSVGPathGeometryFrame(aContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsSVGPathGeometryFrame
|
||||
|
||||
|
@ -134,9 +146,11 @@ nsSVGPathGeometryFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::transform)
|
||||
(NS_STATIC_CAST(nsSVGPathGeometryElement*,
|
||||
mContent)->IsDependentAttribute(aAttribute) ||
|
||||
aAttribute == nsGkAtoms::transform))
|
||||
UpdateGraphic();
|
||||
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -271,7 +285,7 @@ nsSVGPathGeometryFrame::PaintSVG(nsISVGRendererCanvas* canvas)
|
|||
/* render */
|
||||
Render(canvas);
|
||||
|
||||
if (IsMarkable()) {
|
||||
if (NS_STATIC_CAST(nsSVGPathGeometryElement*, mContent)->IsMarkable()) {
|
||||
// Marker Property is added lazily and may have been removed by a restyle
|
||||
UpdateMarkerProperty();
|
||||
nsSVGMarkerProperty *property = GetMarkerProperty();
|
||||
|
@ -283,7 +297,8 @@ nsSVGPathGeometryFrame::PaintSVG(nsISVGRendererCanvas* canvas)
|
|||
float strokeWidth = GetStrokeWidth();
|
||||
|
||||
nsVoidArray marks;
|
||||
GetMarkPoints(&marks);
|
||||
NS_STATIC_CAST(nsSVGPathGeometryElement*,
|
||||
mContent)->GetMarkPoints(&marks);
|
||||
|
||||
PRUint32 num = marks.Count();
|
||||
|
||||
|
@ -346,7 +361,7 @@ nsSVGPathGeometryFrame::GetFrameForPointSVG(float x, float y, nsIFrame** hit)
|
|||
NS_IMETHODIMP_(nsRect)
|
||||
nsSVGPathGeometryFrame::GetCoveredRegion()
|
||||
{
|
||||
if (IsMarkable()) {
|
||||
if (NS_STATIC_CAST(nsSVGPathGeometryElement*, mContent)->IsMarkable()) {
|
||||
nsSVGMarkerProperty *property = GetMarkerProperty();
|
||||
|
||||
if (!property ||
|
||||
|
@ -360,7 +375,7 @@ nsSVGPathGeometryFrame::GetCoveredRegion()
|
|||
float strokeWidth = GetStrokeWidth();
|
||||
|
||||
nsVoidArray marks;
|
||||
GetMarkPoints(&marks);
|
||||
NS_STATIC_CAST(nsSVGPathGeometryElement*, mContent)->GetMarkPoints(&marks);
|
||||
|
||||
PRUint32 num = marks.Count();
|
||||
|
||||
|
@ -666,7 +681,7 @@ nsSVGPathGeometryFrame::GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas)
|
|||
cairo_set_matrix(ctx, &matrix);
|
||||
|
||||
cairo_new_path(ctx);
|
||||
ConstructPath(ctx);
|
||||
NS_STATIC_CAST(nsSVGPathGeometryElement*, mContent)->ConstructPath(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,11 +62,10 @@ typedef nsSVGGeometryFrame nsSVGPathGeometryFrameBase;
|
|||
class nsSVGPathGeometryFrame : public nsSVGPathGeometryFrameBase,
|
||||
public nsISVGChildFrame
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
nsSVGPathGeometryFrame(nsStyleContext* aContext);
|
||||
virtual ~nsSVGPathGeometryFrame();
|
||||
|
||||
public:
|
||||
|
||||
// nsISupports interface:
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return 1; }
|
||||
|
@ -126,15 +125,12 @@ protected:
|
|||
virtual nsresult UpdateGraphic(PRBool suppressInvalidation = PR_FALSE);
|
||||
|
||||
protected:
|
||||
virtual PRBool IsMarkable() { return PR_FALSE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks) {}
|
||||
virtual void ConstructPath(cairo_t *aCtx) = 0;
|
||||
virtual PRUint16 GetHittestMask();
|
||||
|
||||
private:
|
||||
void Render(nsISVGRendererCanvas *aCanvas);
|
||||
void GeneratePath(cairo_t *ctx, nsISVGCairoCanvas* aCanvas);
|
||||
|
||||
private:
|
||||
nsSVGMarkerProperty *GetMarkerProperty();
|
||||
void GetMarkerFromStyle(nsSVGMarkerFrame **aResult,
|
||||
nsSVGMarkerProperty *property,
|
||||
|
|
|
@ -1,227 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGAnimatedPoints.h"
|
||||
#include "nsIDOMSVGPointList.h"
|
||||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGMarkerFrame.h"
|
||||
|
||||
class nsSVGPolygonFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
protected:
|
||||
friend nsIFrame*
|
||||
NS_NewSVGPolygonFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
NS_IMETHOD InitSVG();
|
||||
|
||||
public:
|
||||
nsSVGPolygonFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGPointList> mPoints;
|
||||
|
||||
// nsSVGPathGeometry methods
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgPolygonFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGPolygon"), aResult);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGPolygonFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPoints> anim_points = do_QueryInterface(aContent);
|
||||
if (!anim_points) {
|
||||
#ifdef DEBUG
|
||||
printf("warning: trying to construct an SVGPolygonFrame for a content element that doesn't support the right interfaces\n");
|
||||
#endif
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGPolygonFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPolygonFrame::InitSVG()
|
||||
{
|
||||
nsresult rv = nsSVGPathGeometryFrame::InitSVG();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPoints> anim_points = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(anim_points,"wrong content element");
|
||||
anim_points->GetPoints(getter_AddRefs(mPoints));
|
||||
NS_ASSERTION(mPoints, "no points");
|
||||
if (!mPoints) return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPolygonFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::points) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
void
|
||||
nsSVGPolygonFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
if (i == 0)
|
||||
cairo_move_to(aCtx, x, y);
|
||||
else
|
||||
cairo_line_to(aCtx, x, y);
|
||||
}
|
||||
// the difference between a polyline and a polygon is that the
|
||||
// polygon is closed:
|
||||
cairo_close_path(aCtx);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometry methods:
|
||||
|
||||
void
|
||||
nsSVGPolygonFrame::GetMarkPoints(nsVoidArray *aMarks) {
|
||||
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
float px = 0.0, py = 0.0, prevAngle, startAngle;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
|
||||
float angle = atan2(y-py, x-px);
|
||||
if (i == 1)
|
||||
startAngle = angle;
|
||||
else if (i > 1)
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, angle);
|
||||
|
||||
nsSVGMark *mark;
|
||||
mark = new nsSVGMark;
|
||||
mark->x = x;
|
||||
mark->y = y;
|
||||
aMarks->AppendElement(mark);
|
||||
|
||||
prevAngle = angle;
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
|
||||
float nx, ny, angle;
|
||||
mPoints->GetItem(0, getter_AddRefs(point));
|
||||
point->GetX(&nx);
|
||||
point->GetY(&ny);
|
||||
angle = atan2(ny - py, nx - px);
|
||||
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, angle);
|
||||
((nsSVGMark *)aMarks->ElementAt(0))->angle =
|
||||
nsSVGUtils::AngleBisect(angle, startAngle);
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGPolygonFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgPolygonFrame;
|
||||
}
|
|
@ -1,215 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGAnimatedPoints.h"
|
||||
#include "nsIDOMSVGPointList.h"
|
||||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsSVGMarkerFrame.h"
|
||||
|
||||
class nsSVGPolylineFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
protected:
|
||||
friend nsIFrame*
|
||||
NS_NewSVGPolylineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
NS_IMETHOD InitSVG();
|
||||
|
||||
public:
|
||||
nsSVGPolylineFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgPolylineFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
// nsIFrame interface:
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGPolyline"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGPointList> mPoints;
|
||||
|
||||
// nsSVGPathGeometryFrame methods
|
||||
virtual PRBool IsMarkable() { return PR_TRUE; }
|
||||
virtual void GetMarkPoints(nsVoidArray *aMarks);
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGPolylineFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPoints> anim_points = do_QueryInterface(aContent);
|
||||
if (!anim_points) {
|
||||
#ifdef DEBUG
|
||||
printf("warning: trying to construct an SVGPolylineFrame for a content element that doesn't support the right interfaces\n");
|
||||
#endif
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGPolylineFrame(aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPolylineFrame::InitSVG()
|
||||
{
|
||||
nsresult rv = nsSVGPathGeometryFrame::InitSVG();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPoints> anim_points = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(anim_points,"wrong content element");
|
||||
anim_points->GetPoints(getter_AddRefs(mPoints));
|
||||
NS_ASSERTION(mPoints, "no points");
|
||||
if (!mPoints) return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGPolylineFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgPolylineFrame;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGPolylineFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
aAttribute == nsGkAtoms::points) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
void
|
||||
nsSVGPolylineFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
if (i == 0)
|
||||
cairo_move_to(aCtx, x, y);
|
||||
else
|
||||
cairo_line_to(aCtx, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGPathGeometry methods:
|
||||
|
||||
void
|
||||
nsSVGPolylineFrame::GetMarkPoints(nsVoidArray *aMarks) {
|
||||
|
||||
if (!mPoints)
|
||||
return;
|
||||
|
||||
PRUint32 count;
|
||||
mPoints->GetNumberOfItems(&count);
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
float px = 0.0, py = 0.0, prevAngle;
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIDOMSVGPoint> point;
|
||||
mPoints->GetItem(i, getter_AddRefs(point));
|
||||
|
||||
float x, y;
|
||||
point->GetX(&x);
|
||||
point->GetY(&y);
|
||||
|
||||
float angle = atan2(y-py, x-px);
|
||||
if (i == 1)
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = angle;
|
||||
else if (i > 1)
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle =
|
||||
nsSVGUtils::AngleBisect(prevAngle, angle);
|
||||
|
||||
nsSVGMark *mark;
|
||||
mark = new nsSVGMark;
|
||||
mark->x = x;
|
||||
mark->y = y;
|
||||
aMarks->AppendElement(mark);
|
||||
|
||||
prevAngle = angle;
|
||||
px = x;
|
||||
py = y;
|
||||
}
|
||||
|
||||
((nsSVGMark *)aMarks->ElementAt(aMarks->Count()-1))->angle = prevAngle;
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Crocodile Clips Ltd..
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* William Cook <william.cook@crocodile-clips.com> (original author)
|
||||
* Håkan Waara <hwaara@chello.se>
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com>
|
||||
* Jonathan Watt <jonathan.watt@strath.ac.uk>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGPathGeometryFrame.h"
|
||||
#include "nsIDOMSVGRectElement.h"
|
||||
#include "nsSVGElement.h"
|
||||
|
||||
class nsSVGRectFrame : public nsSVGPathGeometryFrame
|
||||
{
|
||||
protected:
|
||||
friend nsIFrame*
|
||||
NS_NewSVGRectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
|
||||
|
||||
nsSVGRectFrame(nsStyleContext* aContext) : nsSVGPathGeometryFrame(aContext) {}
|
||||
public:
|
||||
/**
|
||||
* Get the "type" of the frame
|
||||
*
|
||||
* @see nsLayoutAtoms::svgRectFrame
|
||||
*/
|
||||
virtual nsIAtom* GetType() const;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("SVGRect"), aResult);
|
||||
}
|
||||
#endif
|
||||
|
||||
// nsIFrame interface:
|
||||
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType);
|
||||
|
||||
// nsSVGPathGeometryFrame interface:
|
||||
virtual void ConstructPath(cairo_t *aCtx);
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Implementation
|
||||
|
||||
nsIFrame*
|
||||
NS_NewSVGRectFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext)
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGRectElement> Rect = do_QueryInterface(aContent);
|
||||
if (!Rect) {
|
||||
NS_ASSERTION(Rect != nsnull, "wrong content element");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return new (aPresShell) nsSVGRectFrame(aContext);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGRectFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
(aAttribute == nsGkAtoms::x ||
|
||||
aAttribute == nsGkAtoms::y ||
|
||||
aAttribute == nsGkAtoms::width ||
|
||||
aAttribute == nsGkAtoms::height ||
|
||||
aAttribute == nsGkAtoms::rx ||
|
||||
aAttribute == nsGkAtoms::ry)) {
|
||||
UpdateGraphic();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsSVGPathGeometryFrame::AttributeChanged(aNameSpaceID,
|
||||
aAttribute, aModType);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGPathGeometrySource methods:
|
||||
|
||||
void
|
||||
nsSVGRectFrame::ConstructPath(cairo_t *aCtx)
|
||||
{
|
||||
float x, y, width, height, rx, ry;
|
||||
|
||||
nsSVGElement *element = NS_STATIC_CAST(nsSVGElement*, mContent);
|
||||
element->GetAnimatedLengthValues(&x, &y, &width, &height, &rx, &ry, nsnull);
|
||||
|
||||
/* In a perfect world, this would be handled by the DOM, and
|
||||
return a DOM exception. */
|
||||
if (width <= 0 || height <= 0 || ry < 0 || rx < 0)
|
||||
return;
|
||||
|
||||
/* Clamp rx and ry to half the rect's width and height respectively. */
|
||||
float halfWidth = width/2;
|
||||
float halfHeight = height/2;
|
||||
if (rx > halfWidth)
|
||||
rx = halfWidth;
|
||||
if (ry > halfHeight)
|
||||
ry = halfHeight;
|
||||
|
||||
/* If either the 'rx' or the 'ry' attribute isn't set in the markup, then we
|
||||
have to set it to the value of the other. We do this after clamping rx and
|
||||
ry since omitting one of the attributes implicitly means they should both
|
||||
be the same. */
|
||||
PRBool hasRx = mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::rx);
|
||||
PRBool hasRy = mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::ry);
|
||||
if (hasRx && !hasRy)
|
||||
ry = rx;
|
||||
else if (hasRy && !hasRx)
|
||||
rx = ry;
|
||||
|
||||
/* However, we may now have made rx > width/2 or else ry > height/2. (If this
|
||||
is the case, we know we must be giving rx and ry the same value.) */
|
||||
if (rx > halfWidth)
|
||||
rx = ry = halfWidth;
|
||||
else if (ry > halfHeight)
|
||||
rx = ry = halfHeight;
|
||||
|
||||
if (rx == 0 && ry == 0) {
|
||||
cairo_rectangle(aCtx, x, y, width, height);
|
||||
} else {
|
||||
// Conversion factor used for ellipse to bezier conversion.
|
||||
// Gives radial error of 0.0273% in circular case.
|
||||
// See comp.graphics.algorithms FAQ 4.04
|
||||
const float magic = 4*(sqrt(2.)-1)/3;
|
||||
|
||||
cairo_move_to(aCtx, x+rx, y);
|
||||
cairo_line_to(aCtx, x+width-rx, y);
|
||||
cairo_curve_to(aCtx,
|
||||
x+width-rx + magic*rx, y,
|
||||
x+width, y+ry-magic*ry,
|
||||
x+width, y+ry);
|
||||
cairo_line_to(aCtx, x+width, y+height-ry);
|
||||
cairo_curve_to(aCtx,
|
||||
x+width, y+height-ry + magic*ry,
|
||||
x+width-rx + magic*rx, y+height,
|
||||
x+width-rx, y+height);
|
||||
cairo_line_to(aCtx, x+rx, y+height);
|
||||
cairo_curve_to(aCtx,
|
||||
x+rx - magic*rx, y+height,
|
||||
x, y+height-ry + magic*ry,
|
||||
x, y+height-ry);
|
||||
cairo_line_to(aCtx, x, y+ry);
|
||||
cairo_curve_to(aCtx,
|
||||
x, y+ry - magic*ry,
|
||||
x+rx - magic*rx, y,
|
||||
x+rx, y);
|
||||
cairo_close_path(aCtx);
|
||||
}
|
||||
}
|
||||
|
||||
nsIAtom *
|
||||
nsSVGRectFrame::GetType() const
|
||||
{
|
||||
return nsLayoutAtoms::svgRectFrame;
|
||||
}
|
Загрузка…
Ссылка в новой задаче