Bug 295850 -- Set up general GetReferencedFrame routine and use it for ClipPath, Glyph, Gradients, Markers, and Paths.

r=tor
This commit is contained in:
scootermorris%comcast.net 2005-08-04 20:32:02 +00:00
parent 42ea3948cd
commit 9696ed8972
13 changed files with 360 additions and 203 deletions

View File

@ -264,6 +264,7 @@ LAYOUT_ATOM(svgMarkerFrame,"SVGMarkerFrame")
LAYOUT_ATOM(svgOuterSVGFrame,"SVGOuterSVGFrame")
LAYOUT_ATOM(svgPathFrame,"SVGPathFrame")
LAYOUT_ATOM(svgPathGeometryFrame,"SVGPathGeometryFrame")
LAYOUT_ATOM(svgPatternFrame,"SVGPatternFrame")
LAYOUT_ATOM(svgPolylineFrame,"SVGPolylineFrame")
LAYOUT_ATOM(svgPolygonFrame,"SVGPolygonFrame")
LAYOUT_ATOM(svgRadialGradientFrame,"SVGRadialGradientFrame")

View File

@ -43,6 +43,7 @@
#include "nsIDOMSVGTransformList.h"
#include "nsSVGAnimatedTransformList.h"
#include "nsIDOMSVGAnimatedEnum.h"
#include "nsSVGUtils.h"
NS_IMETHODIMP_(nsrefcnt)
nsSVGClipPathFrame::AddRef()
@ -98,50 +99,32 @@ NS_NewSVGClipPathFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame*
nsresult
NS_GetSVGClipPathFrame(nsSVGClipPathFrame **aResult, nsIURI *aURI, nsIContent *aContent)
{
nsresult rv;
*aResult = nsnull;
// Get the PresShell
nsIDocument *myDoc = aContent->GetCurrentDoc();
if (!myDoc) {
NS_WARNING("No document for this content!");
return NS_ERROR_FAILURE;
}
nsIPresShell *aPresShell = myDoc->GetShellAt(0);
// Get the URI Spec
nsCAutoString uriSpec;
aURI->GetSpec(uriSpec);
// Get ID from spec
PRInt32 pos = uriSpec.FindChar('#');
if (pos == -1) {
NS_ASSERTION(pos != -1, "URI Spec not a reference");
return NS_ERROR_FAILURE;
}
// Strip off hash and get name
nsCAutoString idC;
uriSpec.Right(idC, uriSpec.Length() - (pos + 1));
// Convert to unicode
nsAutoString id;
CopyUTF8toUTF16(idC, id);
// Get document
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aContent->GetCurrentDoc());
NS_ASSERTION(doc, "Content doesn't reference a dom Document");
if (!doc)
// Find the referenced frame
nsIFrame *cpframe;
if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&cpframe,
uriSpec, aContent, aPresShell)))
return NS_ERROR_FAILURE;
// Get element
nsCOMPtr<nsIDOMElement> element;
nsCOMPtr<nsIPresShell> ps = do_QueryInterface(aContent->GetCurrentDoc()->GetShellAt(0));
rv = doc->GetElementById(id, getter_AddRefs(element));
if (!NS_SUCCEEDED(rv) || element == nsnull)
return rv;
nsIFrame *frame;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
rv = ps->GetPrimaryFrameFor(content, &frame);
if (!frame)
nsIAtom* frameType = cpframe->GetType();
if (frameType != nsLayoutAtoms::svgClipPathFrame)
return NS_ERROR_FAILURE;
nsSVGClipPathFrame *cpframe;
CallQueryInterface(frame, &cpframe);
*aResult = cpframe;
return rv;
*aResult = (nsSVGClipPathFrame *)cpframe;
return NS_OK;
}
nsSVGClipPathFrame::~nsSVGClipPathFrame()

View File

@ -743,6 +743,14 @@ nsSVGGlyphFrame::GetStrokePaintType(PRUint16 *aStrokePaintType)
return NS_OK;
}
/* readonly attribute unsigned short strokePaintServerType; */
NS_IMETHODIMP
nsSVGGlyphFrame::GetStrokePaintServerType(PRUint16 *aStrokePaintServerType)
{
return nsSVGUtils::GetPaintType(aStrokePaintServerType, GetStyleSVG()->mStroke, mContent,
nsSVGGlyphFrameBase::GetPresContext()->PresShell());
}
/* [noscript] readonly attribute nscolor strokePaint; */
NS_IMETHODIMP
nsSVGGlyphFrame::GetStrokePaint(nscolor *aStrokePaint)
@ -778,6 +786,14 @@ nsSVGGlyphFrame::GetFillPaintType(PRUint16 *aFillPaintType)
return NS_OK;
}
/* readonly attribute unsigned short fillPaintServerType; */
NS_IMETHODIMP
nsSVGGlyphFrame::GetFillPaintServerType(PRUint16 *aFillPaintServerType)
{
return nsSVGUtils::GetPaintType(aFillPaintServerType, GetStyleSVG()->mFill, mContent,
nsSVGGlyphFrameBase::GetPresContext()->PresShell());
}
/* [noscript] readonly attribute nscolor fillPaint; */
NS_IMETHODIMP
nsSVGGlyphFrame::GetFillPaint(nscolor *aFillPaint)

View File

@ -70,6 +70,7 @@
#include "nsSVGNumber.h"
#include "nsIDOMSVGStopElement.h"
#include "nsLayoutAtoms.h"
#include "nsSVGUtils.h"
typedef nsContainerFrame nsSVGGradientFrameBase;
@ -262,9 +263,6 @@ private:
};
static nsresult GetSVGGradient(nsSVGGradientFrame **result, nsCAutoString& aSpec,
nsIContent *aContent, nsIPresShell *aPresShell);
//----------------------------------------------------------------------
// Implementation
@ -605,7 +603,7 @@ nsSVGGradientFrame::checkURITarget(nsIAtom *attr) {
PRBool
nsSVGGradientFrame::checkURITarget(void) {
nsSVGGradientFrame *aNextGrad;
nsIFrame *aNextGrad;
// Have we already figured out the next Gradient?
if (mNextGrad != nsnull) {
return PR_TRUE;
@ -621,8 +619,12 @@ nsSVGGradientFrame::checkURITarget(void) {
CopyUTF16toUTF8(mNextGradStr, aGradStr);
// Note that we are using *our* frame tree for this call, otherwise we're going to have
// to get the PresShell in each call
if (GetSVGGradient(&aNextGrad, aGradStr, mContent, GetPresContext()->PresShell()) == NS_OK) {
mNextGrad = aNextGrad;
if (nsSVGUtils::GetReferencedFrame(&aNextGrad, aGradStr, mContent, GetPresContext()->PresShell()) == NS_OK) {
nsIAtom* frameType = aNextGrad->GetType();
if ((frameType != nsLayoutAtoms::svgLinearGradientFrame) &&
(frameType != nsLayoutAtoms::svgRadialGradientFrame))
return PR_FALSE;
mNextGrad = (nsSVGGradientFrame *)aNextGrad;
// Add ourselves to the observer list
if (mNextGrad) {
// Can't use the NS_ADD macro here because of nsISupports ambiguity
@ -1170,68 +1172,14 @@ nsresult NS_GetSVGGradient(nsISVGGradient **aGrad, nsIURI *aURI, nsIContent *aCo
// Get the spec from the URI
nsCAutoString uriSpec;
aURI->GetSpec(uriSpec);
nsSVGGradientFrame *result;
nsresult rv = GetSVGGradient(&result, uriSpec, aContent, aPresShell);
*aGrad = (nsISVGGradient*)result;
return rv;
}
// Static (helper) function to get a gradient from URI spec
static nsresult GetSVGGradient(nsSVGGradientFrame **result, nsCAutoString& aSpec, nsIContent *aContent,
nsIPresShell *aPresShell)
{
nsresult rv = NS_OK;
*result = nsnull;
// Get the ID from the spec (no ID = an error)
PRInt32 pos = aSpec.FindChar('#');
if (pos == -1) {
NS_ASSERTION(pos != -1, "URI Spec not a reference");
return NS_ERROR_FAILURE;
}
// Strip off the hash and get the name
nsCAutoString aURICName;
aSpec.Right(aURICName, aSpec.Length()-(pos + 1));
// Get a unicode string
nsAutoString aURIName;
CopyUTF8toUTF16(aURICName, aURIName);
// Get the domDocument
nsCOMPtr<nsIDOMDocument>domDoc = do_QueryInterface(aContent->GetDocument());
NS_ASSERTION(domDoc, "Content doesn't reference a dom Document");
if (domDoc == nsnull) {
return NS_ERROR_FAILURE;
}
// Get the gradient element
nsCOMPtr<nsIDOMElement> element;
rv = domDoc->GetElementById(aURIName, getter_AddRefs(element));
if (!NS_SUCCEEDED(rv) || element == nsnull) {
return rv;
}
// Note: the following queries are not really required, but we want to make sure
// we're pointing to gradient elements.
nsCOMPtr<nsIDOMSVGLinearGradientElement> lGradient = do_QueryInterface(element);
if (!lGradient) {
nsCOMPtr<nsIDOMSVGRadialGradientElement> rGradient = do_QueryInterface(element);
if (!rGradient) {
NS_ASSERTION(PR_FALSE, "Not a gradient element!");
return NS_ERROR_FAILURE;
}
}
// Get the Primary Frame
nsCOMPtr<nsIContent> aGContent = do_QueryInterface(element);
NS_ASSERTION(aPresShell, "svg get gradient -- no pres shell provided");
if (!aPresShell)
return NS_ERROR_FAILURE;
nsIFrame *grad;
rv = aPresShell->GetPrimaryFrameFor(aGContent, &grad);
*result = (nsSVGGradientFrame *)grad;
return rv;
#ifdef DEBUG_scooter
printf("NS_GetSVGGradient: uri = %s\n",uriSpec.get());
#endif
nsIFrame *result;
if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&result,
uriSpec, aContent, aPresShell))) {
return NS_ERROR_FAILURE;
}
return result->QueryInterface(NS_GET_IID(nsISVGGradient), (void **)aGrad);
}

View File

@ -55,6 +55,7 @@
#include "nsSVGMarkerFrame.h"
#include "nsSVGPathGeometryFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsSVGUtils.h"
NS_IMETHODIMP_(nsrefcnt)
nsSVGMarkerFrame::AddRef()
@ -101,52 +102,32 @@ NS_NewSVGMarkerFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame**
nsresult
NS_GetSVGMarkerFrame(nsSVGMarkerFrame **aResult, nsIURI *aURI, nsIContent *aContent)
{
nsresult rv;
*aResult = nsnull;
// Get the PresShell
nsIDocument *myDoc = aContent->GetCurrentDoc();
if (!myDoc) {
NS_WARNING("No document for this content!");
return NS_ERROR_FAILURE;
}
nsIPresShell *aPresShell = myDoc->GetShellAt(0);
// Get the URI Spec
nsCAutoString uriSpec;
aURI->GetSpec(uriSpec);
// Get ID from spec
PRInt32 pos = uriSpec.FindChar('#');
if (pos == -1) {
NS_ASSERTION(pos != -1, "URI Spec not a reference");
return NS_ERROR_FAILURE;
}
// Strip off hash and get name
nsCAutoString idC;
uriSpec.Right(idC, uriSpec.Length() - (pos + 1));
// Convert to unicode
nsAutoString id;
CopyUTF8toUTF16(idC, id);
// Get document
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aContent->GetCurrentDoc());
NS_ASSERTION(doc, "Content doesn't reference a dom Document");
if (!doc)
// Find the referenced frame
nsIFrame *marker;
if (!NS_SUCCEEDED(nsSVGUtils::GetReferencedFrame(&marker,
uriSpec, aContent, aPresShell)))
return NS_ERROR_FAILURE;
// Get element
nsCOMPtr<nsIDOMElement> element;
nsCOMPtr<nsIPresShell> ps = do_QueryInterface(aContent->GetCurrentDoc()->GetShellAt(0));
rv = doc->GetElementById(id, getter_AddRefs(element));
if (!NS_SUCCEEDED(rv) || element == nsnull)
return rv;
nsIFrame *frame;
nsCOMPtr<nsIContent> content = do_QueryInterface(element);
rv = ps->GetPrimaryFrameFor(content, &frame);
if (!frame)
nsIAtom* frameType = marker->GetType();
if (frameType != nsLayoutAtoms::svgMarkerFrame)
return NS_ERROR_FAILURE;
// see comment preceeding nsSVGMarkerFrame::QueryInterface
// nsCOMPtr<nsSVGMarkerFrame> marker = do_QueryInterface(frame);
nsSVGMarkerFrame *marker;
CallQueryInterface(frame, &marker);
*aResult = marker;
return rv;
*aResult = (nsSVGMarkerFrame *)marker;
return NS_OK;
}
nsSVGMarkerFrame::~nsSVGMarkerFrame()

View File

@ -43,6 +43,7 @@
#include "nsISVGRenderer.h"
#include "nsISVGRendererRegion.h"
#include "nsISVGValueUtils.h"
#include "nsISVGGeometrySource.h"
#include "nsIDOMSVGTransformable.h"
#include "nsIDOMSVGAnimTransformList.h"
#include "nsIDOMSVGTransformList.h"
@ -58,7 +59,6 @@
#include "nsSVGMatrix.h"
#include "nsSVGClipPathFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsSVGAtoms.h"
#include "nsIViewManager.h"
#include "nsSVGUtils.h"
@ -621,6 +621,13 @@ nsSVGPathGeometryFrame::GetStrokePaintType(PRUint16 *aStrokePaintType)
return NS_OK;
}
/* readonly attribute unsigned short strokePaintServerType; */
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetStrokePaintServerType(PRUint16 *aStrokePaintServerType) {
return nsSVGUtils::GetPaintType(aStrokePaintServerType, GetStyleSVG()->mStroke, mContent,
nsSVGPathGeometryFrameBase::GetPresContext()->PresShell());
}
/* [noscript] readonly attribute nscolor strokePaint; */
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetStrokePaint(nscolor *aStrokePaint)
@ -656,6 +663,14 @@ nsSVGPathGeometryFrame::GetFillPaintType(PRUint16 *aFillPaintType)
return NS_OK;
}
/* readonly attribute unsigned short fillPaintServerType; */
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetFillPaintServerType(PRUint16 *aFillPaintServerType)
{
return nsSVGUtils::GetPaintType(aFillPaintServerType, GetStyleSVG()->mFill, mContent,
nsSVGPathGeometryFrameBase::GetPresContext()->PresShell());
}
/* [noscript] readonly attribute nscolor fillPaint; */
NS_IMETHODIMP
nsSVGPathGeometryFrame::GetFillPaint(nscolor *aFillPaint)

View File

@ -35,13 +35,22 @@
* ***** END LICENSE BLOCK ***** */
#include "nsSVGLength.h"
#include "nsIDOMDocument.h"
#include "nsIDOMSVGElement.h"
#include "nsIDOMSVGSVGElement.h"
#include "nsStyleCoord.h"
#include "nsPresContext.h"
#include "nsSVGCoordCtxProvider.h"
#include "nsIContent.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "nsLayoutAtoms.h"
#include "nsIURI.h"
#include "nsStyleStruct.h"
#include "nsIPresShell.h"
#include "nsSVGUtils.h"
#include "nsISVGGeometrySource.h"
#include "nsNetUtil.h"
float
nsSVGUtils::CoordToFloat(nsPresContext *aPresContext, nsIContent *aContent,
@ -82,3 +91,114 @@ nsSVGUtils::CoordToFloat(nsPresContext *aPresContext, nsIContent *aContent,
return val;
}
nsresult nsSVGUtils::GetReferencedFrame(nsIFrame **aRefFrame, nsCAutoString& uriSpec, nsIContent *aContent,
nsIPresShell *aPresShell)
{
nsresult rv = NS_OK;
*aRefFrame = nsnull;
// Get the ID from the spec (no ID = an error)
PRInt32 pos = uriSpec.FindChar('#');
if (pos == -1) {
NS_ASSERTION(pos != -1, "URI Spec not a reference");
return NS_ERROR_FAILURE;
}
// Get the current document
nsIDocument *myDoc = aContent->GetCurrentDoc();
if (!myDoc) {
NS_WARNING("Content doesn't reference a Document!");
return NS_ERROR_FAILURE;
}
// Get our URI
nsCOMPtr<nsIURI> myURI = myDoc->GetDocumentURI();
#ifdef DEBUG_scooter
// Get the uri Spec
nsCAutoString dSpec;
myURI->GetSpec(dSpec);
printf("Document URI = %s, target URI = %s\n",dSpec.get(), uriSpec.get());
#endif
// Create a URI out of the target
nsCAutoString aURISName;
uriSpec.Left(aURISName, pos);
nsCOMPtr<nsIURI> targetURI;
NS_NewURI(getter_AddRefs(targetURI), aURISName, nsnull, myDoc->GetBaseURI());
PRBool match;
myURI->Equals(targetURI, &match);
if (!match) {
// Oops -- we don't support off-document references
return NS_ERROR_FAILURE;
}
// At this point, we know we have a target within our document, but
// it may not point to anything
// Strip off the hash and get the name
nsCAutoString aURICName;
uriSpec.Right(aURICName, uriSpec.Length()-(pos + 1));
// Get a unicode string
nsAutoString aURIName;
CopyUTF8toUTF16(aURICName, aURIName);
// Get the domDocument
nsCOMPtr<nsIDOMDocument>domDoc = do_QueryInterface(myDoc);
NS_ASSERTION(domDoc, "Content doesn't reference a dom Document");
if (domDoc == nsnull) {
return NS_ERROR_FAILURE;
}
// Get the element
nsCOMPtr<nsIDOMElement> element;
rv = domDoc->GetElementById(aURIName, getter_AddRefs(element));
if (!NS_SUCCEEDED(rv) || element == nsnull) {
return NS_ERROR_FAILURE;
}
// Get the Primary Frame
nsCOMPtr<nsIContent> aGContent = do_QueryInterface(element);
NS_ASSERTION(aPresShell, "Get referenced SVG frame -- no pres shell provided");
if (!aPresShell)
return NS_ERROR_FAILURE;
rv = aPresShell->GetPrimaryFrameFor(aGContent, aRefFrame);
NS_ASSERTION(*aRefFrame, "Get referenced SVG frame -- can't find primary frame");
if (!(*aRefFrame)) return NS_ERROR_FAILURE;
return rv;
}
nsresult nsSVGUtils::GetPaintType(PRUint16 *aPaintType, const nsStyleSVGPaint& aPaint,
nsIContent *aContent, nsIPresShell *aPresShell )
{
*aPaintType = aPaint.mType;
// If the type is a Paint Server, determine what kind
if (*aPaintType == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
nsIURI *aServer = aPaint.mPaint.mPaintServer;
if (aServer == nsnull)
return NS_ERROR_FAILURE;
// Get the uri Spec
nsCAutoString uriSpec;
aServer->GetSpec(uriSpec);
// Get the frame
nsIFrame *aFrame = nsnull;
nsresult rv;
rv = nsSVGUtils::GetReferencedFrame(&aFrame, uriSpec, aContent, aPresShell);
if (!NS_SUCCEEDED(rv) || !aFrame)
return NS_ERROR_FAILURE;
// Finally, figure out what type it is
if (aFrame->GetType() == nsLayoutAtoms::svgLinearGradientFrame ||
aFrame->GetType() == nsLayoutAtoms::svgRadialGradientFrame)
*aPaintType = nsISVGGeometrySource::PAINT_TYPE_GRADIENT;
else if (aFrame->GetType() == nsLayoutAtoms::svgPatternFrame)
*aPaintType = nsISVGGeometrySource::PAINT_TYPE_PATTERN;
else
return NS_ERROR_FAILURE;
}
return NS_OK;
}

View File

@ -51,6 +51,20 @@ public:
*/
static float CoordToFloat(nsPresContext *aPresContext, nsIContent *aContent,
const nsStyleCoord &aCoord);
/*
* Gets an internal frame for an element referenced by a URI. Note that this
* only works for URIs that reference elements within the same document.
*/
static nsresult GetReferencedFrame(nsIFrame **aRefFrame, nsCAutoString& uriSpec,
nsIContent *aContent,
nsIPresShell *aPresShell);
/*
* For SVGPaint attributes (fills, strokes), return the type of the Paint. This
* is an expanded type that includes whether this is a solid fill, a gradient, or
* a pattern.
*/
static nsresult GetPaintType(PRUint16 *aPaintType, const nsStyleSVGPaint& aPaint,
nsIContent *aContent, nsIPresShell *aPresShell);
};
#endif

View File

@ -68,7 +68,7 @@ interface nsISVGGradient;
*
* @nosubgrouping
*/
[uuid(1130c772-f329-4ab7-8a77-41dac7b85add)]
[uuid(b2c3119b-a27d-4b25-97a9-a9d60981a95e)]
interface nsISVGGeometrySource : nsISupports
{
/**
@ -190,6 +190,8 @@ interface nsISVGGeometrySource : nsISupports
const unsigned short PAINT_TYPE_NONE = 0;
const unsigned short PAINT_TYPE_SOLID_COLOR = 1;
const unsigned short PAINT_TYPE_SERVER = 2;
const unsigned short PAINT_TYPE_GRADIENT = 3;
const unsigned short PAINT_TYPE_PATTERN = 4;
/** @} */
/**
@ -199,12 +201,16 @@ interface nsISVGGeometrySource : nsISupports
readonly attribute unsigned short strokePaintType;
const unsigned long UPDATEMASK_STROKE_PAINT_TYPE = 0x00000800;
/* strokePaintServerType will only be valid if strokePaintType ==
* PAINT_TYPE_SERVER */
readonly attribute unsigned short strokePaintServerType;
/* strokePaint will only be valid if strokePaintType ==
* PAINT_TYPE_SOLID_COLOR */
readonly attribute nscolor strokePaint;
/* GetStrokeGradient will only return a valid result if
* strokePaintType == PAINT_TYPE_SERVER */
* strokePaintType == PAINT_TYPE_GRADIENT */
void GetStrokeGradient(out nsISVGGradient aGrad);
/* signifies that either paint color or server have changed,
@ -220,12 +226,16 @@ interface nsISVGGeometrySource : nsISupports
readonly attribute unsigned short fillPaintType;
const unsigned long UPDATEMASK_FILL_PAINT_TYPE = 0x00004000;
/* fillPaintServerType will only be valid if fillPaintType ==
* PAINT_TYPE_SERVER */
readonly attribute unsigned short fillPaintServerType;
/* fillPaint will only be valid if fillPaintType ==
* PAINT_TYPE_SOLID_COLOR */
readonly attribute nscolor fillPaint;
/* GetFillGradient will only return a valid result if
* fillPaintType == PAINT_TYPE_SERVER */
* fillPaintType == PAINT_TYPE_GRADIENT */
void GetFillGradient(out nsISVGGradient aGrad);
/* signifies that either paint color or server have changed,

View File

@ -214,14 +214,26 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
PRBool hasFill = PR_FALSE;
PRUint16 filltype;
mSource->GetFillPaintType(&filltype);
if (filltype != nsISVGGeometrySource::PAINT_TYPE_NONE)
PRUint16 fillServerType = 0;
if (filltype != nsISVGGeometrySource::PAINT_TYPE_NONE) {
hasFill = PR_TRUE;
if (filltype == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (NS_FAILED(mSource->GetFillPaintServerType(&fillServerType)))
hasFill = PR_FALSE;
}
}
PRBool hasStroke = PR_FALSE;
PRUint16 stroketype;
mSource->GetStrokePaintType(&stroketype);
if (stroketype != nsISVGGeometrySource::PAINT_TYPE_NONE)
PRUint16 strokeServerType = 0;
if (stroketype != nsISVGGeometrySource::PAINT_TYPE_NONE) {
hasStroke = PR_TRUE;
if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (NS_FAILED(mSource->GetStrokePaintServerType(&strokeServerType)))
hasStroke = PR_FALSE;
}
}
if (!hasFill && !hasStroke) return NS_OK; // nothing to paint
@ -241,15 +253,17 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
mSource->GetCharacterData(text);
if (filltype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
cairo_show_text(ctx, NS_ConvertUCS2toUTF8(text).get());
} else {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetFillGradient(getter_AddRefs(aGrad));
cairo_show_text(ctx, (const char*)NS_ConvertUCS2toUTF8(text).get());
} else if (filltype == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetFillGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_show_text(ctx, NS_ConvertUCS2toUTF8(text).get());
cairo_pattern_destroy(gradient);
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_show_text(ctx, (const char*)NS_ConvertUCS2toUTF8(text).get());
cairo_pattern_destroy(gradient);
}
}
}
@ -319,14 +333,16 @@ nsSVGCairoGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
cairo_stroke(ctx);
} else {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
} else if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
}
}
}

View File

@ -294,13 +294,27 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
}
PRUint16 strokeType, fillType;
PRUint16 strokeServerType = 0;
PRBool bStroking = PR_FALSE;
mSource->GetStrokePaintType(&strokeType);
if (strokeType != nsISVGGeometrySource::PAINT_TYPE_NONE)
if (strokeType != nsISVGGeometrySource::PAINT_TYPE_NONE) {
bStroking = PR_TRUE;
if (strokeType == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (NS_FAILED(mSource->GetStrokePaintServerType(&strokeServerType)))
// unknown type or missing frame
bStroking = PR_FALSE;
}
}
mSource->GetFillPaintType(&fillType);
PRUint16 fillServerType = 0;
if (fillType == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (NS_FAILED(mSource->GetFillPaintServerType(&fillServerType)))
// unknown type or missing frame
fillType = nsISVGGeometrySource::PAINT_TYPE_NONE;
}
if (fillType != nsISVGGeometrySource::PAINT_TYPE_NONE) {
nscolor rgb;
mSource->GetFillPaint(&rgb);
@ -315,14 +329,18 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
if (fillType == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
cairo_fill_preserve(ctx);
} else {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetFillGradient(getter_AddRefs(aGrad));
} else if (fillType == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetFillGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_fill_preserve(ctx);
cairo_pattern_destroy(gradient);
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_fill_preserve(ctx);
cairo_pattern_destroy(gradient);
} else {
cairo_fill_preserve(ctx);
}
}
if (!bStroking)
@ -342,14 +360,20 @@ nsSVGCairoPathGeometry::Render(nsISVGRendererCanvas *canvas)
if (strokeType == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
cairo_stroke(ctx);
} else {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
} else if (strokeType == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
PRUint16 serverType;
mSource->GetStrokePaintServerType(&serverType);
if (serverType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
cairo_pattern_t *gradient = CairoGradient(ctx, aGrad, mSource);
cairo_set_source(ctx, gradient);
cairo_stroke(ctx);
cairo_pattern_destroy(gradient);
} else {
cairo_stroke(ctx);
}
}
}

View File

@ -366,15 +366,26 @@ nsSVGGDIPlusGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
PRBool hasFill = PR_FALSE, hasStroke = PR_FALSE;
PRUint16 filltype, stroketype;
PRUint16 fillServerType = 0, strokeServerType = 0;
mSource->GetFillPaintType(&filltype);
if (filltype != nsISVGGeometrySource::PAINT_TYPE_NONE)
hasFill = PR_TRUE;
if (filltype == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if(NS_FAILED(mSource->GetFillPaintServerType(&fillServerType)))
hasFill = PR_FALSE;
}
mSource->GetStrokePaintType(&stroketype);
if (stroketype != nsISVGGeometrySource::PAINT_TYPE_NONE && mStroke)
hasStroke = PR_TRUE;
if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if(NS_FAILED(mSource->GetStrokePaintServerType(&strokeServerType)))
hasStroke = PR_FALSE;
}
if (!hasFill && !hasStroke) return NS_OK; // nothing to paint
SectionIterator sections(mSource);
@ -422,8 +433,11 @@ nsSVGGDIPlusGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
SolidBrush brush(Color((BYTE)(opacity*255),NS_GET_R(color),NS_GET_G(color),NS_GET_B(color)));
nsCOMPtr<nsISVGGradient> aGrad;
if (filltype != nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR)
mSource->GetFillGradient(getter_AddRefs(aGrad));
if (filltype != nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
if (fillServerType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
mSource->GetFillGradient(getter_AddRefs(aGrad));
}
}
DrawFill(gdiplusCanvas->GetGraphics(), brush, aGrad,
sections.GetSectionPtr(), sections.GetLength(), sections.GetAdvance()+x, y);
@ -440,8 +454,11 @@ nsSVGGDIPlusGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
mSource->GetStrokeOpacity(&opacity);
nsCOMPtr<nsISVGGradient> aGrad;
if (stroketype != nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR)
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
if (stroketype != nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
}
}
SolidBrush brush(Color((BYTE)(opacity*255), NS_GET_R(color), NS_GET_G(color), NS_GET_B(color)));
@ -449,7 +466,7 @@ nsSVGGDIPlusGlyphGeometry::Render(nsISVGRendererCanvas *canvas)
// this is the 'normal' case
if (stroketype == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
gdiplusCanvas->GetGraphics()->FillPath(&brush, mStroke);
} else {
} else if (strokeServerType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGRendererRegion> region;
GetCoveredRegion(getter_AddRefs(region));
nsCOMPtr<nsISVGGDIPlusRegion> aRegion = do_QueryInterface(region);

View File

@ -426,49 +426,61 @@ nsSVGGDIPlusPathGeometry::Render(nsISVGRendererCanvas *canvas)
nscolor color;
float opacity;
PRUint16 type;
PRUint16 type, serverType = 0;
// paint fill:
mSource->GetFillPaintType(&type);
if (type == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if(NS_FAILED(mSource->GetFillPaintServerType(&serverType)))
type = nsISVGGeometrySource::PAINT_TYPE_NONE;
}
if (type != nsISVGGeometrySource::PAINT_TYPE_NONE && GetFill()) {
if (type == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
mSource->GetFillPaint(&color);
mSource->GetFillOpacity(&opacity);
RenderPath(GetFill(), color, opacity, gdiplusCanvas);
} else {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetFillGradient(getter_AddRefs(aGrad));
if (serverType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetFillGradient(getter_AddRefs(aGrad));
nsCOMPtr<nsISVGRendererRegion> region;
GetCoveredRegion(getter_AddRefs(region));
nsCOMPtr<nsISVGGDIPlusRegion> aRegion = do_QueryInterface(region);
nsCOMPtr<nsIDOMSVGMatrix> ctm;
mSource->GetCanvasTM(getter_AddRefs(ctm));
nsCOMPtr<nsISVGRendererRegion> region;
GetCoveredRegion(getter_AddRefs(region));
nsCOMPtr<nsISVGGDIPlusRegion> aRegion = do_QueryInterface(region);
nsCOMPtr<nsIDOMSVGMatrix> ctm;
mSource->GetCanvasTM(getter_AddRefs(ctm));
GDIPlusGradient(aRegion, aGrad, ctm, gdiplusCanvas->GetGraphics(),
mSource, gradCBFill, this);
GDIPlusGradient(aRegion, aGrad, ctm, gdiplusCanvas->GetGraphics(),
mSource, gradCBFill, this);
}
}
}
// paint stroke:
mSource->GetStrokePaintType(&type);
if (type == nsISVGGeometrySource::PAINT_TYPE_SERVER) {
if(NS_FAILED(mSource->GetStrokePaintServerType(&serverType)))
type = nsISVGGeometrySource::PAINT_TYPE_NONE;
}
if (type != nsISVGGeometrySource::PAINT_TYPE_NONE && GetStroke()) {
if (type == nsISVGGeometrySource::PAINT_TYPE_SOLID_COLOR) {
mSource->GetStrokePaint(&color);
mSource->GetStrokeOpacity(&opacity);
RenderPath(GetStroke(), color, opacity, gdiplusCanvas);
} else {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
if (serverType == nsISVGGeometrySource::PAINT_TYPE_GRADIENT) {
nsCOMPtr<nsISVGGradient> aGrad;
mSource->GetStrokeGradient(getter_AddRefs(aGrad));
nsCOMPtr<nsISVGRendererRegion> region;
GetCoveredRegion(getter_AddRefs(region));
nsCOMPtr<nsISVGGDIPlusRegion> aRegion = do_QueryInterface(region);
nsCOMPtr<nsIDOMSVGMatrix> ctm;
mSource->GetCanvasTM(getter_AddRefs(ctm));
nsCOMPtr<nsISVGRendererRegion> region;
GetCoveredRegion(getter_AddRefs(region));
nsCOMPtr<nsISVGGDIPlusRegion> aRegion = do_QueryInterface(region);
nsCOMPtr<nsIDOMSVGMatrix> ctm;
mSource->GetCanvasTM(getter_AddRefs(ctm));
GDIPlusGradient(aRegion, aGrad, ctm, gdiplusCanvas->GetGraphics(),
mSource, gradCBStroke, this);
GDIPlusGradient(aRegion, aGrad, ctm, gdiplusCanvas->GetGraphics(),
mSource, gradCBStroke, this);
}
}
}