Bug 655877 - Part 1: Move some path drawing functions from nsSVGGeometryFrame to nsSVGUtils. r=jwatt

This commit is contained in:
Cameron McCormack 2012-08-10 21:13:43 +10:00
parent bad716eec5
commit 4efeaa9269
7 changed files with 259 additions and 262 deletions

View File

@ -357,9 +357,9 @@ nsSVGFilterInstance::BuildSourcePaint(PrimitiveInfo *aPrimitive)
gfx->Multiply(matrix);
gfx->Rectangle(r);
if ((aPrimitive == &mFillPaint &&
nsSVGUtils::SetupCairoFill(gfx, mTargetFrame)) ||
nsSVGUtils::SetupCairoFillPaint(mTargetFrame, gfx)) ||
(aPrimitive == &mStrokePaint &&
nsSVGUtils::SetupCairoStroke(gfx, mTargetFrame))) {
nsSVGUtils::SetupCairoStrokePaint(mTargetFrame, gfx))) {
gfx->Fill();
}
}

View File

@ -32,213 +32,14 @@ nsSVGGeometryFrame::Init(nsIContent* aContent,
//----------------------------------------------------------------------
float
nsSVGGeometryFrame::GetStrokeWidth()
{
nsSVGElement *ctx = static_cast<nsSVGElement*>
(mContent->IsNodeOfType(nsINode::eTEXT) ?
mContent->GetParent() : mContent);
return
nsSVGUtils::CoordToFloat(PresContext(),
ctx,
GetStyleSVG()->mStrokeWidth);
}
bool
nsSVGGeometryFrame::GetStrokeDashData(FallibleTArray<gfxFloat>& dashes,
gfxFloat *dashOffset)
{
PRUint32 count = GetStyleSVG()->mStrokeDasharrayLength;
if (!count || !dashes.SetLength(count)) {
return false;
}
gfxFloat pathScale = 1.0;
if (mContent->Tag() == nsGkAtoms::path) {
pathScale = static_cast<nsSVGPathElement*>(mContent)->
GetPathLengthScale(nsSVGPathElement::eForStroking);
if (pathScale <= 0) {
return false;
}
}
nsSVGElement *ctx = static_cast<nsSVGElement*>
(mContent->IsNodeOfType(nsINode::eTEXT) ?
mContent->GetParent() : mContent);
const nsStyleCoord *dasharray = GetStyleSVG()->mStrokeDasharray;
nsPresContext *presContext = PresContext();
gfxFloat totalLength = 0.0;
for (PRUint32 i = 0; i < count; i++) {
dashes[i] =
nsSVGUtils::CoordToFloat(presContext,
ctx,
dasharray[i]) * pathScale;
if (dashes[i] < 0.0) {
return false;
}
totalLength += dashes[i];
}
*dashOffset = nsSVGUtils::CoordToFloat(presContext,
ctx,
GetStyleSVG()->mStrokeDashoffset);
return (totalLength > 0.0);
}
PRUint16
nsSVGGeometryFrame::GetClipRule()
{
return GetStyleSVG()->mClipRule;
}
float
nsSVGGeometryFrame::MaybeOptimizeOpacity(float aFillOrStrokeOpacity)
{
float opacity = GetStyleDisplay()->mOpacity;
if (opacity < 1 && nsSVGUtils::CanOptimizeOpacity(this)) {
return aFillOrStrokeOpacity * opacity;
}
return aFillOrStrokeOpacity;
}
bool
nsSVGGeometryFrame::HasStroke()
{
const nsStyleSVG *style = GetStyleSVG();
return style->mStroke.mType != eStyleSVGPaintType_None &&
style->mStrokeOpacity > 0 &&
GetStrokeWidth() > 0;
}
void
nsSVGGeometryFrame::SetupCairoStrokeGeometry(gfxContext *aContext)
{
float width = GetStrokeWidth();
if (width <= 0)
return;
aContext->SetLineWidth(width);
// Apply any stroke-specific transform
aContext->Multiply(nsSVGUtils::GetStrokeTransform(this));
const nsStyleSVG* style = GetStyleSVG();
switch (style->mStrokeLinecap) {
case NS_STYLE_STROKE_LINECAP_BUTT:
aContext->SetLineCap(gfxContext::LINE_CAP_BUTT);
break;
case NS_STYLE_STROKE_LINECAP_ROUND:
aContext->SetLineCap(gfxContext::LINE_CAP_ROUND);
break;
case NS_STYLE_STROKE_LINECAP_SQUARE:
aContext->SetLineCap(gfxContext::LINE_CAP_SQUARE);
break;
}
aContext->SetMiterLimit(style->mStrokeMiterlimit);
switch (style->mStrokeLinejoin) {
case NS_STYLE_STROKE_LINEJOIN_MITER:
aContext->SetLineJoin(gfxContext::LINE_JOIN_MITER);
break;
case NS_STYLE_STROKE_LINEJOIN_ROUND:
aContext->SetLineJoin(gfxContext::LINE_JOIN_ROUND);
break;
case NS_STYLE_STROKE_LINEJOIN_BEVEL:
aContext->SetLineJoin(gfxContext::LINE_JOIN_BEVEL);
break;
}
}
void
nsSVGGeometryFrame::SetupCairoStrokeHitGeometry(gfxContext *aContext)
{
SetupCairoStrokeGeometry(aContext);
AutoFallibleTArray<gfxFloat, 10> dashes;
gfxFloat dashOffset;
if (GetStrokeDashData(dashes, &dashOffset)) {
aContext->SetDash(dashes.Elements(), dashes.Length(), dashOffset);
}
}
bool
nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext)
{
return nsSVGUtils::SetupCairoFill(aContext, this);
}
bool
nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext)
{
if (!HasStroke()) {
return false;
}
SetupCairoStrokeHitGeometry(aContext);
return nsSVGUtils::SetupCairoStroke(aContext, this);
}
PRUint16
nsSVGGeometryFrame::GetHitTestFlags()
{
PRUint16 flags = 0;
switch(GetStyleVisibility()->mPointerEvents) {
case NS_STYLE_POINTER_EVENTS_NONE:
break;
case NS_STYLE_POINTER_EVENTS_AUTO:
case NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED:
if (GetStyleVisibility()->IsVisible()) {
if (GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_FILL;
if (GetStyleSVG()->mStroke.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_STROKE;
if (GetStyleSVG()->mStrokeOpacity > 0)
flags |= SVG_HIT_TEST_CHECK_MRECT;
}
break;
case NS_STYLE_POINTER_EVENTS_VISIBLEFILL:
if (GetStyleVisibility()->IsVisible()) {
flags |= SVG_HIT_TEST_FILL;
}
break;
case NS_STYLE_POINTER_EVENTS_VISIBLESTROKE:
if (GetStyleVisibility()->IsVisible()) {
flags |= SVG_HIT_TEST_STROKE;
}
break;
case NS_STYLE_POINTER_EVENTS_VISIBLE:
if (GetStyleVisibility()->IsVisible()) {
flags |= SVG_HIT_TEST_FILL | SVG_HIT_TEST_STROKE;
}
break;
case NS_STYLE_POINTER_EVENTS_PAINTED:
if (GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_FILL;
if (GetStyleSVG()->mStroke.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_STROKE;
if (GetStyleSVG()->mStrokeOpacity)
flags |= SVG_HIT_TEST_CHECK_MRECT;
break;
case NS_STYLE_POINTER_EVENTS_FILL:
flags |= SVG_HIT_TEST_FILL;
break;
case NS_STYLE_POINTER_EVENTS_STROKE:
flags |= SVG_HIT_TEST_STROKE;
break;
case NS_STYLE_POINTER_EVENTS_ALL:
flags |= SVG_HIT_TEST_FILL | SVG_HIT_TEST_STROKE;
break;
default:
NS_ERROR("not reached");
break;
}
return flags;
return nsSVGUtils::GetGeometryHitTestFlags(this);
}

View File

@ -23,10 +23,6 @@ struct nsStyleSVGPaint;
typedef nsFrame nsSVGGeometryFrameBase;
#define SVG_HIT_TEST_FILL 0x01
#define SVG_HIT_TEST_STROKE 0x02
#define SVG_HIT_TEST_CHECK_MRECT 0x04
/* nsSVGGeometryFrame is a base class for SVG objects that directly
* have geometry (circle, ellipse, line, polyline, polygon, path, and
* glyph frames). It knows how to convert the style information into
@ -59,31 +55,6 @@ public:
virtual gfxMatrix GetCanvasTM(PRUint32 aFor) = 0;
PRUint16 GetClipRule();
float GetStrokeWidth();
/*
* Set up a cairo context for filling a path
* @return false to skip rendering
*/
bool SetupCairoFill(gfxContext *aContext);
/*
* @return false if there is no stroke
*/
bool HasStroke();
/*
* Set up a cairo context for measuring a stroked path
*/
void SetupCairoStrokeGeometry(gfxContext *aContext);
/*
* Set up a cairo context for hit testing a stroked path
*/
void SetupCairoStrokeHitGeometry(gfxContext *aContext);
/*
* Set up a cairo context for stroking a path
* @return false to skip rendering
*/
bool SetupCairoStroke(gfxContext *aContext);
protected:
/**
* This function returns a set of bit flags indicating which parts of the
@ -92,18 +63,6 @@ protected:
* property on the element.
*/
virtual PRUint16 GetHitTestFlags();
/**
* Returns the given 'fill-opacity' or 'stroke-opacity' value multiplied by
* the value of the 'opacity' property if it's possible to avoid the expense
* of creating and compositing an offscreen surface for 'opacity' by
* combining 'opacity' with the 'fill-opacity'/'stroke-opacity'. If not, the
* given 'fill-opacity'/'stroke-opacity' is returned unmodified.
*/
float MaybeOptimizeOpacity(float aFillOrStrokeOpacity);
private:
bool GetStrokeDashData(FallibleTArray<gfxFloat>& dashes, gfxFloat *dashOffset);
};
#endif // __NS_SVGGEOMETRYFRAME_H__

View File

@ -677,7 +677,8 @@ nsSVGGlyphFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
// Account for stroke:
if ((aFlags & nsSVGUtils::eBBoxIncludeStrokeGeometry) ||
((aFlags & nsSVGUtils::eBBoxIncludeStroke) && HasStroke())) {
((aFlags & nsSVGUtils::eBBoxIncludeStroke) &&
nsSVGUtils::HasStroke(this))) {
bbox.UnionEdges(nsSVGUtils::PathExtentsToMaxStrokeExtents(pathExtents,
this,
aToBBoxUserspace));
@ -949,13 +950,13 @@ nsSVGGlyphFrame::SetupCairoState(gfxContext *aContext, gfxPattern **aStrokePatte
DrawMode toDraw = DrawMode(0);
const nsStyleSVG* style = GetStyleSVG();
if (HasStroke()) {
if (nsSVGUtils::HasStroke(this)) {
gfxContextMatrixAutoSaveRestore matrixRestore(aContext);
aContext->IdentityMatrix();
toDraw = DrawMode(toDraw | gfxFont::GLYPH_STROKE);
SetupCairoStrokeHitGeometry(aContext);
nsSVGUtils::SetupCairoStrokeHitGeometry(this, aContext);
float opacity = style->mStrokeOpacity;
nsSVGPaintServerFrame *ps =
nsSVGEffects::GetPaintServer(this, &style->mStroke,
@ -982,7 +983,7 @@ nsSVGGlyphFrame::SetupCairoState(gfxContext *aContext, gfxPattern **aStrokePatte
strokePattern.forget(aStrokePattern);
}
if (SetupCairoFill(aContext)) {
if (nsSVGUtils::SetupCairoFillPaint(this, aContext)) {
toDraw = DrawMode(toDraw | gfxFont::GLYPH_FILL);
}

View File

@ -188,7 +188,7 @@ nsSVGPathGeometryFrame::PaintSVG(nsRenderingContext *aContext,
MarkerProperties properties = GetMarkerProperties(this);
if (properties.MarkersExist()) {
float strokeWidth = GetStrokeWidth();
float strokeWidth = nsSVGUtils::GetStrokeWidth(this);
nsTArray<nsSVGMark> marks;
static_cast<nsSVGPathGeometryElement*>
@ -258,7 +258,7 @@ nsSVGPathGeometryFrame::GetFrameForPoint(const nsPoint &aPoint)
if (hitTestFlags & SVG_HIT_TEST_FILL)
isHit = tmpCtx->PointInFill(userSpacePoint);
if (!isHit && (hitTestFlags & SVG_HIT_TEST_STROKE)) {
SetupCairoStrokeHitGeometry(tmpCtx);
nsSVGUtils::SetupCairoStrokeHitGeometry(this, tmpCtx);
isHit = tmpCtx->PointInStroke(userSpacePoint);
}
@ -390,7 +390,8 @@ nsSVGPathGeometryFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
// Account for stroke:
if ((aFlags & nsSVGUtils::eBBoxIncludeStrokeGeometry) ||
((aFlags & nsSVGUtils::eBBoxIncludeStroke) && HasStroke())) {
((aFlags & nsSVGUtils::eBBoxIncludeStroke) &&
nsSVGUtils::HasStroke(this))) {
// We can't use tmpCtx->GetUserStrokeExtent() since it doesn't work for
// device space extents. Instead we approximate the stroke extents from
// pathExtents using PathExtentsToMaxStrokeExtents.
@ -401,7 +402,7 @@ nsSVGPathGeometryFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
// though, because if pathExtents is empty, its position will not have
// been set. Happily we can use tmpCtx->GetUserStrokeExtent() to find
// the center point of the extents even though it gets the extents wrong.
SetupCairoStrokeGeometry(tmpCtx);
nsSVGUtils::SetupCairoStrokeGeometry(this, tmpCtx);
pathExtents.MoveTo(tmpCtx->GetUserStrokeExtent().Center());
pathExtents.SizeTo(0, 0);
}
@ -414,7 +415,7 @@ nsSVGPathGeometryFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
if ((aFlags & nsSVGUtils::eBBoxIncludeMarkers) != 0 &&
static_cast<nsSVGPathGeometryElement*>(mContent)->IsMarkable()) {
float strokeWidth = GetStrokeWidth();
float strokeWidth = nsSVGUtils::GetStrokeWidth(this);
MarkerProperties properties = GetMarkerProperties(this);
if (properties.MarkersExist()) {
@ -567,11 +568,11 @@ nsSVGPathGeometryFrame::Render(nsRenderingContext *aContext)
return;
}
if (SetupCairoFill(gfx)) {
if (nsSVGUtils::SetupCairoFillPaint(this, gfx)) {
gfx->Fill();
}
if (SetupCairoStroke(gfx)) {
if (nsSVGUtils::SetupCairoStroke(this, gfx)) {
gfx->Stroke();
}

View File

@ -48,6 +48,7 @@
#include "nsSVGLength2.h"
#include "nsSVGMaskFrame.h"
#include "nsSVGOuterSVGFrame.h"
#include "nsSVGPathElement.h"
#include "nsSVGPathGeometryElement.h"
#include "nsSVGPathGeometryFrame.h"
#include "nsSVGPaintServerFrame.h"
@ -1655,7 +1656,7 @@ nsSVGUtils::CanOptimizeOpacity(nsIFrame *aFrame)
}
if (style->mFill.mType == eStyleSVGPaintType_None ||
style->mFillOpacity <= 0 ||
!static_cast<nsSVGPathGeometryFrame*>(aFrame)->HasStroke()) {
!HasStroke(aFrame)) {
return true;
}
return false;
@ -1762,7 +1763,7 @@ PathExtentsToMaxStrokeExtents(const gfxRect& aPathExtents,
const gfxMatrix& aMatrix)
{
double style_expansion =
styleExpansionFactor * aFrame->GetStrokeWidth();
styleExpansionFactor * nsSVGUtils::GetStrokeWidth(aFrame);
gfxMatrix matrix = aMatrix;
matrix.Multiply(nsSVGUtils::GetStrokeTransform(aFrame));
@ -1865,7 +1866,7 @@ MaybeOptimizeOpacity(nsIFrame *aFrame, float aFillOrStrokeOpacity)
}
bool
nsSVGUtils::SetupCairoFill(gfxContext *aContext, nsIFrame *aFrame)
nsSVGUtils::SetupCairoFillPaint(nsIFrame *aFrame, gfxContext* aContext)
{
const nsStyleSVG* style = aFrame->GetStyleSVG();
if (style->mFill.mType == eStyleSVGPaintType_None)
@ -1886,7 +1887,7 @@ nsSVGUtils::SetupCairoFill(gfxContext *aContext, nsIFrame *aFrame)
}
bool
nsSVGUtils::SetupCairoStroke(gfxContext *aContext, nsIFrame *aFrame)
nsSVGUtils::SetupCairoStrokePaint(nsIFrame *aFrame, gfxContext* aContext)
{
const nsStyleSVG* style = aFrame->GetStyleSVG();
if (style->mStroke.mType == eStyleSVGPaintType_None)
@ -1907,3 +1908,199 @@ nsSVGUtils::SetupCairoStroke(gfxContext *aContext, nsIFrame *aFrame)
return true;
}
bool
nsSVGUtils::HasStroke(nsIFrame* aFrame)
{
const nsStyleSVG *style = aFrame->GetStyleSVG();
return style->mStroke.mType != eStyleSVGPaintType_None &&
style->mStrokeOpacity > 0 &&
GetStrokeWidth(aFrame) > 0;
}
float
nsSVGUtils::GetStrokeWidth(nsIFrame* aFrame)
{
nsIContent* content = aFrame->GetContent();
if (content->IsNodeOfType(nsINode::eTEXT)) {
content = content->GetParent();
}
nsSVGElement *ctx = static_cast<nsSVGElement*>(content);
return nsSVGUtils::CoordToFloat(aFrame->PresContext(), ctx,
aFrame->GetStyleSVG()->mStrokeWidth);
}
void
nsSVGUtils::SetupCairoStrokeGeometry(nsIFrame* aFrame, gfxContext *aContext)
{
float width = GetStrokeWidth(aFrame);
if (width <= 0)
return;
aContext->SetLineWidth(width);
// Apply any stroke-specific transform
aContext->Multiply(GetStrokeTransform(aFrame));
const nsStyleSVG* style = aFrame->GetStyleSVG();
switch (style->mStrokeLinecap) {
case NS_STYLE_STROKE_LINECAP_BUTT:
aContext->SetLineCap(gfxContext::LINE_CAP_BUTT);
break;
case NS_STYLE_STROKE_LINECAP_ROUND:
aContext->SetLineCap(gfxContext::LINE_CAP_ROUND);
break;
case NS_STYLE_STROKE_LINECAP_SQUARE:
aContext->SetLineCap(gfxContext::LINE_CAP_SQUARE);
break;
}
aContext->SetMiterLimit(style->mStrokeMiterlimit);
switch (style->mStrokeLinejoin) {
case NS_STYLE_STROKE_LINEJOIN_MITER:
aContext->SetLineJoin(gfxContext::LINE_JOIN_MITER);
break;
case NS_STYLE_STROKE_LINEJOIN_ROUND:
aContext->SetLineJoin(gfxContext::LINE_JOIN_ROUND);
break;
case NS_STYLE_STROKE_LINEJOIN_BEVEL:
aContext->SetLineJoin(gfxContext::LINE_JOIN_BEVEL);
break;
}
}
static bool
GetStrokeDashData(nsIFrame* aFrame,
FallibleTArray<gfxFloat>& aDashes,
gfxFloat* aDashOffset)
{
const nsStyleSVG* style = aFrame->GetStyleSVG();
PRUint32 count = style->mStrokeDasharrayLength;
if (!count || !aDashes.SetLength(count)) {
return false;
}
gfxFloat pathScale = 1.0;
nsIContent* content = aFrame->GetContent();
if (content->IsSVG() && content->Tag() == nsGkAtoms::path) {
pathScale = static_cast<nsSVGPathElement*>(content)->
GetPathLengthScale(nsSVGPathElement::eForStroking);
if (pathScale <= 0) {
return false;
}
}
if (content->IsNodeOfType(nsINode::eTEXT)) {
content = content->GetParent();
}
nsSVGElement *ctx = static_cast<nsSVGElement*>(content);
const nsStyleCoord *dasharray = style->mStrokeDasharray;
nsPresContext *presContext = aFrame->PresContext();
gfxFloat totalLength = 0.0;
for (PRUint32 i = 0; i < count; i++) {
aDashes[i] =
nsSVGUtils::CoordToFloat(presContext,
ctx,
dasharray[i]) * pathScale;
if (aDashes[i] < 0.0) {
return false;
}
totalLength += aDashes[i];
}
*aDashOffset = nsSVGUtils::CoordToFloat(presContext,
ctx,
style->mStrokeDashoffset);
return (totalLength > 0.0);
}
void
nsSVGUtils::SetupCairoStrokeHitGeometry(nsIFrame* aFrame, gfxContext* aContext)
{
SetupCairoStrokeGeometry(aFrame, aContext);
AutoFallibleTArray<gfxFloat, 10> dashes;
gfxFloat dashOffset;
if (GetStrokeDashData(aFrame, dashes, &dashOffset)) {
aContext->SetDash(dashes.Elements(), dashes.Length(), dashOffset);
}
}
PRUint16
nsSVGUtils::GetGeometryHitTestFlags(nsIFrame* aFrame)
{
PRUint16 flags = 0;
switch(aFrame->GetStyleVisibility()->mPointerEvents) {
case NS_STYLE_POINTER_EVENTS_NONE:
break;
case NS_STYLE_POINTER_EVENTS_AUTO:
case NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED:
if (aFrame->GetStyleVisibility()->IsVisible()) {
if (aFrame->GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_FILL;
if (aFrame->GetStyleSVG()->mStroke.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_STROKE;
if (aFrame->GetStyleSVG()->mStrokeOpacity > 0)
flags |= SVG_HIT_TEST_CHECK_MRECT;
}
break;
case NS_STYLE_POINTER_EVENTS_VISIBLEFILL:
if (aFrame->GetStyleVisibility()->IsVisible()) {
flags |= SVG_HIT_TEST_FILL;
}
break;
case NS_STYLE_POINTER_EVENTS_VISIBLESTROKE:
if (aFrame->GetStyleVisibility()->IsVisible()) {
flags |= SVG_HIT_TEST_STROKE;
}
break;
case NS_STYLE_POINTER_EVENTS_VISIBLE:
if (aFrame->GetStyleVisibility()->IsVisible()) {
flags |= SVG_HIT_TEST_FILL | SVG_HIT_TEST_STROKE;
}
break;
case NS_STYLE_POINTER_EVENTS_PAINTED:
if (aFrame->GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_FILL;
if (aFrame->GetStyleSVG()->mStroke.mType != eStyleSVGPaintType_None)
flags |= SVG_HIT_TEST_STROKE;
if (aFrame->GetStyleSVG()->mStrokeOpacity)
flags |= SVG_HIT_TEST_CHECK_MRECT;
break;
case NS_STYLE_POINTER_EVENTS_FILL:
flags |= SVG_HIT_TEST_FILL;
break;
case NS_STYLE_POINTER_EVENTS_STROKE:
flags |= SVG_HIT_TEST_STROKE;
break;
case NS_STYLE_POINTER_EVENTS_ALL:
flags |= SVG_HIT_TEST_FILL | SVG_HIT_TEST_STROKE;
break;
default:
NS_ERROR("not reached");
break;
}
return flags;
}
bool
nsSVGUtils::SetupCairoStroke(nsIFrame* aFrame, gfxContext* aContext)
{
if (!HasStroke(aFrame)) {
return false;
}
SetupCairoStrokeHitGeometry(aFrame, aContext);
return SetupCairoStrokePaint(aFrame, aContext);
}

View File

@ -90,6 +90,10 @@ class Element;
#define SVG_WSP_DELIM "\x20\x9\xD\xA"
#define SVG_COMMA_WSP_DELIM "," SVG_WSP_DELIM
#define SVG_HIT_TEST_FILL 0x01
#define SVG_HIT_TEST_STROKE 0x02
#define SVG_HIT_TEST_CHECK_MRECT 0x04
inline bool
IsSVGWhitespace(char aChar)
{
@ -671,13 +675,47 @@ public:
nsStyleSVGPaint nsStyleSVG::*aFillOrStroke);
/**
* Set the graphics context ready for filling.
* Sets the current paint on the specified gfxContent to be the SVG 'fill'
* for the given frame.
*/
static bool SetupCairoFill(gfxContext *aContext, nsIFrame *aFrame);
static bool SetupCairoFillPaint(nsIFrame* aFrame, gfxContext* aContext);
/**
* Set the graphics context ready for stroking.
* Sets the current paint on the specified gfxContent to be the SVG 'stroke'
* for the given frame.
*/
static bool SetupCairoStroke(gfxContext *aContext, nsIFrame *aFrame);
static bool SetupCairoStrokePaint(nsIFrame* aFrame, gfxContext* aContext);
/*
* @return false if there is no stroke
*/
static bool HasStroke(nsIFrame* aFrame);
static float GetStrokeWidth(nsIFrame* aFrame);
/*
* Set up a cairo context for measuring a stroked path
*/
static void SetupCairoStrokeGeometry(nsIFrame* aFrame, gfxContext *aContext);
/*
* Set up a cairo context for hit testing a stroked path
*/
static void SetupCairoStrokeHitGeometry(nsIFrame* aFrame, gfxContext *aContext);
/*
* Set up a cairo context for stroking, including setting up any stroke-related
* properties such as dashing and setting the current paint on the gfxContext.
*/
static bool SetupCairoStroke(nsIFrame* aFrame, gfxContext *aContext);
/**
* This function returns a set of bit flags indicating which parts of the
* element (fill, stroke, bounds) should intercept pointer events. It takes
* into account the type of element and the value of the 'pointer-events'
* property on the element.
*/
static PRUint16 GetGeometryHitTestFlags(nsIFrame* aFrame);
};
#endif