Bug 342200 - Remove nsSVGPathGeometryFrame subclasses. r+sr=roc

This commit is contained in:
tor%cs.brown.edu 2006-06-21 15:42:28 +00:00
Родитель 6fc2761be5
Коммит 1dbf6462c0
26 изменённых файлов: 1031 добавлений и 93 удалений

Просмотреть файл

@ -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 \

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -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

Просмотреть файл

Просмотреть файл

@ -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;

Просмотреть файл

Просмотреть файл

@ -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,

Просмотреть файл

Просмотреть файл

Просмотреть файл