mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
Bug 295850 -- Set up general GetReferencedFrame routine and use it for ClipPath, Glyph, Gradients, Markers, and Paths.
r=tor
This commit is contained in:
parent
42ea3948cd
commit
9696ed8972
@ -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")
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user