зеркало из https://github.com/mozilla/pjs.git
Bug 340859 - Implement pathLength attribute.
Patch by amenzie@us.ibm.com, r=tor, sr=roc.
This commit is contained in:
Родитель
8cf4d352b0
Коммит
02ed0eb6bf
|
@ -46,6 +46,7 @@
|
|||
#include "nsSVGPathElement.h"
|
||||
#include "nsISVGValueUtils.h"
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGAnimatedNumber.h"
|
||||
|
||||
NS_IMPL_NS_NEW_SVG_ELEMENT(Path)
|
||||
|
||||
|
@ -72,6 +73,20 @@ nsSVGPathElement::nsSVGPathElement(nsINodeInfo* aNodeInfo)
|
|||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGPathElement::Init()
|
||||
{
|
||||
nsresult rv = nsSVGPathElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
{
|
||||
rv = NS_NewSVGAnimatedNumber(getter_AddRefs(mPathLength), 0.0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::pathLength, mPathLength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsSVGPathElement::~nsSVGPathElement()
|
||||
{
|
||||
if (mSegments)
|
||||
|
@ -90,7 +105,9 @@ NS_IMPL_DOM_CLONENODE_WITH_INIT(nsSVGPathElement)
|
|||
NS_IMETHODIMP
|
||||
nsSVGPathElement::GetPathLength(nsIDOMSVGAnimatedNumber * *aPathLength)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
*aPathLength = mPathLength;
|
||||
NS_IF_ADDREF(*aPathLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* float getTotalLength (); */
|
||||
|
|
|
@ -94,6 +94,7 @@ protected:
|
|||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGPathElement(nsINodeInfo *aNodeInfo);
|
||||
virtual ~nsSVGPathElement();
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
|
@ -131,6 +132,7 @@ protected:
|
|||
nsresult CreatePathSegList();
|
||||
|
||||
nsCOMPtr<nsIDOMSVGPathSegList> mSegments;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedNumber> mPathLength;
|
||||
nsSVGPathList mPathData;
|
||||
};
|
||||
|
||||
|
|
|
@ -43,10 +43,11 @@
|
|||
#include "nsIDOMSVGLengthList.h"
|
||||
|
||||
class nsISVGRendererGlyphMetrics;
|
||||
class nsSVGTextPathFrame;
|
||||
|
||||
// {33397E2B-C1DC-49f0-9738-4891FE083C92}
|
||||
// {bc02467f-f611-4c0f-8d95-e2923d66f775}
|
||||
#define NS_ISVGGLYPHFRAGMENTLEAF_IID \
|
||||
{ 0x33397e2b, 0xc1dc, 0x49f0, { 0x97, 0x38, 0x48, 0x91, 0xfe, 0x8, 0x3c, 0x92 } }
|
||||
{ 0xbc02467f, 0xf611, 0x4c0f, { 0x8d, 0x95, 0xe2, 0x92, 0x3d, 0x66, 0xf7, 0x75 } }
|
||||
|
||||
class nsISVGGlyphFragmentLeaf : public nsISVGGlyphFragmentNode
|
||||
{
|
||||
|
@ -56,6 +57,7 @@ public:
|
|||
|
||||
NS_IMETHOD_(void) SetGlyphPosition(float x, float y)=0;
|
||||
NS_IMETHOD GetGlyphMetrics(nsISVGRendererGlyphMetrics** metrics)=0;
|
||||
NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent()=0;
|
||||
NS_IMETHOD_(PRBool) IsStartOfChunk()=0; // == is new absolutely positioned chunk.
|
||||
NS_IMETHOD_(void) GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y)=0;
|
||||
|
||||
|
|
|
@ -412,24 +412,12 @@ nsSVGGlyphFrame::GetCharacterData(nsAString & aCharacterData)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void GetCharacterPosition (out nsSVGCharacterPosition aCP); */
|
||||
/* void GetCharacterPosition (out nsSVGCharacterPosition aCP); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::GetCharacterPosition(nsSVGCharacterPosition **aCharacterPosition)
|
||||
{
|
||||
*aCharacterPosition = nsnull;
|
||||
nsSVGTextPathFrame *textPath = nsnull;
|
||||
|
||||
/* check if we're the child of a textPath */
|
||||
for (nsIFrame *frame = GetParent();
|
||||
frame != nsnull;
|
||||
frame = frame->GetParent()) {
|
||||
if (frame->GetType() == nsLayoutAtoms::svgTextPathFrame) {
|
||||
textPath = NS_STATIC_CAST(nsSVGTextPathFrame*, frame);
|
||||
break;
|
||||
}
|
||||
if (frame->GetType() == nsLayoutAtoms::svgTextFrame)
|
||||
break;
|
||||
}
|
||||
nsSVGTextPathFrame *textPath = FindTextPathParent();
|
||||
|
||||
/* we're an ordinary fragment - return */
|
||||
/* XXX: we might want to use this for individual x/y/dx/dy adjustment */
|
||||
|
@ -479,7 +467,7 @@ nsSVGGlyphFrame::GetCharacterPosition(nsSVGCharacterPosition **aCharacterPositio
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void GetGlyphPosition (out float aGlyphPositionX, out float aGlyphPositionY); */
|
||||
/* void GetGlyphPosition (out float aGlyphPositionX, out float aGlyphPositionY); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::GetGlyphPosition(float *aGlyphPositionX, float *aGlyphPositionY)
|
||||
{
|
||||
|
@ -692,6 +680,22 @@ nsSVGGlyphFrame::GetGlyphMetrics(nsISVGRendererGlyphMetrics** metrics)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsSVGTextPathFrame*)
|
||||
nsSVGGlyphFrame::FindTextPathParent()
|
||||
{
|
||||
/* check if we're the child of a textPath */
|
||||
for (nsIFrame *frame = GetParent();
|
||||
frame != nsnull;
|
||||
frame = frame->GetParent()) {
|
||||
nsIAtom* type = frame->GetType();
|
||||
if (type == nsLayoutAtoms::svgTextPathFrame) {
|
||||
return NS_STATIC_CAST(nsSVGTextPathFrame*, frame);
|
||||
} else if (type == nsLayoutAtoms::svgTextFrame)
|
||||
return nsnull;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsSVGGlyphFrame::IsStartOfChunk()
|
||||
{
|
||||
|
|
|
@ -127,6 +127,7 @@ public:
|
|||
// nsISVGGlyphFragmentLeaf interface:
|
||||
NS_IMETHOD_(void) SetGlyphPosition(float x, float y);
|
||||
NS_IMETHOD GetGlyphMetrics(nsISVGRendererGlyphMetrics** metrics);
|
||||
NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent();
|
||||
NS_IMETHOD_(PRBool) IsStartOfChunk(); // == is new absolutely positioned chunk.
|
||||
NS_IMETHOD_(void) GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y);
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "nsIDOMSVGLengthList.h"
|
||||
#include "nsIDOMSVGLength.h"
|
||||
#include "nsIDOMSVGAnimatedNumber.h"
|
||||
#include "nsISVGGlyphFragmentNode.h"
|
||||
#include "nsISVGGlyphFragmentLeaf.h"
|
||||
#include "nsISVGRendererGlyphMetrics.h"
|
||||
|
@ -515,31 +516,42 @@ GetSingleValue(nsISVGGlyphFragmentLeaf *fragment,
|
|||
list->GetItem(0, getter_AddRefs(length));
|
||||
length->GetValue(val);
|
||||
|
||||
/* check for % sizing of textpath */
|
||||
PRUint16 type;
|
||||
length->GetUnitType(&type);
|
||||
if (type == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
|
||||
nsIFrame *glyph;
|
||||
CallQueryInterface(fragment, &glyph);
|
||||
nsSVGTextPathFrame *textPath = fragment->FindTextPathParent();
|
||||
|
||||
nsSVGTextPathFrame *textPath = nsnull;
|
||||
/* check if we're the child of a textPath */
|
||||
for (nsIFrame *frame = glyph; frame != nsnull; frame = frame->GetParent())
|
||||
if (frame->GetType() == nsLayoutAtoms::svgTextPathFrame) {
|
||||
textPath = NS_STATIC_CAST(nsSVGTextPathFrame*, frame);
|
||||
break;
|
||||
}
|
||||
if (textPath) {
|
||||
nsAutoPtr<nsSVGFlattenedPath> data(textPath->GetFlattenedPath());
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (textPath) {
|
||||
nsAutoPtr<nsSVGFlattenedPath> data(textPath->GetFlattenedPath());
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
nsIFrame *pathFrame = textPath->GetPathFrame();
|
||||
if (!pathFrame)
|
||||
return;
|
||||
|
||||
/* check for % sizing of textpath */
|
||||
PRUint16 type;
|
||||
length->GetUnitType(&type);
|
||||
if (type == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
|
||||
float percent;
|
||||
length->GetValueInSpecifiedUnits(&percent);
|
||||
|
||||
*val = data->GetLength()*percent/100.0f;
|
||||
} else if (pathFrame->GetContent()->HasAttr(kNameSpaceID_None,
|
||||
nsGkAtoms::pathLength)) {
|
||||
nsCOMPtr<nsIDOMSVGPathElement> pathElement =
|
||||
do_QueryInterface(pathFrame->GetContent());
|
||||
if (!pathElement)
|
||||
return;
|
||||
|
||||
nsIDOMSVGAnimatedNumber* pathLength;
|
||||
pathElement->GetPathLength(&pathLength);
|
||||
if (!pathLength)
|
||||
return;
|
||||
float pl;
|
||||
pathLength->GetAnimVal(&pl);
|
||||
if (pl)
|
||||
*val *= data->GetLength() / pl;
|
||||
else
|
||||
*val = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -169,8 +169,8 @@ nsSVGTextPathFrame::GetDy()
|
|||
//----------------------------------------------------------------------
|
||||
// nsSVGTextPathFrame methods:
|
||||
|
||||
nsSVGFlattenedPath *
|
||||
nsSVGTextPathFrame::GetFlattenedPath() {
|
||||
nsIFrame *
|
||||
nsSVGTextPathFrame::GetPathFrame() {
|
||||
nsIFrame *path = nsnull;
|
||||
|
||||
nsAutoString str;
|
||||
|
@ -178,13 +178,21 @@ nsSVGTextPathFrame::GetFlattenedPath() {
|
|||
|
||||
nsCOMPtr<nsIURI> targetURI;
|
||||
nsCOMPtr<nsIURI> base = mContent->GetBaseURI();
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI),
|
||||
str, mContent->GetCurrentDoc(), base);
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(targetURI), str,
|
||||
mContent->GetCurrentDoc(), base);
|
||||
|
||||
nsSVGUtils::GetReferencedFrame(&path, targetURI, mContent,
|
||||
GetPresContext()->PresShell());
|
||||
if (!path || (path->GetType() != nsGkAtoms::svgPathGeometryFrame))
|
||||
return nsnull;
|
||||
return path;
|
||||
}
|
||||
|
||||
nsSVGFlattenedPath *
|
||||
nsSVGTextPathFrame::GetFlattenedPath() {
|
||||
nsIFrame *path = GetPathFrame();
|
||||
if (!path)
|
||||
return nsnull;
|
||||
|
||||
if (!mSegments) {
|
||||
nsCOMPtr<nsIDOMSVGAnimatedPathData> data =
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
|
||||
// nsSVGTextPathFrame methods:
|
||||
nsSVGFlattenedPath *GetFlattenedPath();
|
||||
nsIFrame *GetPathFrame();
|
||||
|
||||
// nsISupports interface:
|
||||
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
|
||||
|
|
Загрузка…
Ссылка в новой задаче