зеркало из https://github.com/mozilla/pjs.git
Bug 406312 - textPath startOffset does not react to DOM changes. r=tor,sr=roc,a1.9=tor
This commit is contained in:
Родитель
0aeb073df4
Коммит
c0561ebaca
|
@ -71,6 +71,7 @@ class nsSVGPathElement : public nsSVGPathElementBase,
|
|||
public nsIDOMSVGAnimatedPathData
|
||||
{
|
||||
friend class nsSVGPathFrame;
|
||||
friend class nsSVGTextPathFrame;
|
||||
|
||||
protected:
|
||||
friend nsresult NS_NewSVGPathElement(nsIContent **aResult,
|
||||
|
|
|
@ -41,63 +41,9 @@
|
|||
#include "nsIDOMSVGURIReference.h"
|
||||
#include "nsISVGTextContentMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsSVGTextPathElement.h"
|
||||
#include "nsSVGAnimatedString.h"
|
||||
#include "nsSVGEnum.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsSVGLength2.h"
|
||||
|
||||
typedef nsSVGStylableElement nsSVGTextPathElementBase;
|
||||
|
||||
class nsSVGTextPathElement : public nsSVGTextPathElementBase,
|
||||
public nsIDOMSVGTextPathElement,
|
||||
public nsIDOMSVGURIReference
|
||||
{
|
||||
protected:
|
||||
friend nsresult NS_NewSVGTextPathElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGTextPathElement(nsINodeInfo* aNodeInfo);
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGTEXTPATHELEMENT
|
||||
NS_DECL_NSIDOMSVGTEXTCONTENTELEMENT
|
||||
NS_DECL_NSIDOMSVGURIREFERENCE
|
||||
|
||||
// xxx If xpcom allowed virtual inheritance we wouldn't need to
|
||||
// forward here :-(
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTextPathElementBase::)
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual EnumAttributesInfo GetEnumInfo();
|
||||
|
||||
virtual PRBool IsEventName(nsIAtom* aName);
|
||||
|
||||
already_AddRefed<nsISVGTextContentMetrics> GetTextContentMetrics();
|
||||
|
||||
enum { STARTOFFSET };
|
||||
nsSVGLength2 mLengthAttributes[1];
|
||||
static LengthInfo sLengthInfo[1];
|
||||
|
||||
enum { METHOD, SPACING };
|
||||
nsSVGEnum mEnumAttributes[2];
|
||||
static nsSVGEnumMapping sMethodMap[];
|
||||
static nsSVGEnumMapping sSpacingMap[];
|
||||
static EnumInfo sEnumInfo[2];
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
};
|
||||
|
||||
nsSVGElement::LengthInfo nsSVGTextPathElement::sLengthInfo[1] =
|
||||
{
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Mozilla SVG project.
|
||||
*
|
||||
* The Initial Developer of the Original Code is IBM Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2005
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alex Fritze <alex.fritze@crocodile-clips.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __NS_SVGTEXTPATHELEMENT_H__
|
||||
#define __NS_SVGTEXTPATHELEMENT_H__
|
||||
|
||||
#include "nsSVGEnum.h"
|
||||
#include "nsSVGLength2.h"
|
||||
|
||||
typedef nsSVGStylableElement nsSVGTextPathElementBase;
|
||||
|
||||
class nsSVGTextPathElement : public nsSVGTextPathElementBase,
|
||||
public nsIDOMSVGTextPathElement,
|
||||
public nsIDOMSVGURIReference
|
||||
{
|
||||
friend class nsSVGTextPathFrame;
|
||||
|
||||
protected:
|
||||
friend nsresult NS_NewSVGTextPathElement(nsIContent **aResult,
|
||||
nsINodeInfo *aNodeInfo);
|
||||
nsSVGTextPathElement(nsINodeInfo* aNodeInfo);
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
// interfaces:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGTEXTPATHELEMENT
|
||||
NS_DECL_NSIDOMSVGTEXTCONTENTELEMENT
|
||||
NS_DECL_NSIDOMSVGURIREFERENCE
|
||||
|
||||
// xxx If xpcom allowed virtual inheritance we wouldn't need to
|
||||
// forward here :-(
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGTextPathElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGTextPathElementBase::)
|
||||
|
||||
// nsIContent interface
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual EnumAttributesInfo GetEnumInfo();
|
||||
|
||||
virtual PRBool IsEventName(nsIAtom* aName);
|
||||
|
||||
already_AddRefed<nsISVGTextContentMetrics> GetTextContentMetrics();
|
||||
|
||||
enum { STARTOFFSET };
|
||||
nsSVGLength2 mLengthAttributes[1];
|
||||
static LengthInfo sLengthInfo[1];
|
||||
|
||||
enum { METHOD, SPACING };
|
||||
nsSVGEnum mEnumAttributes[2];
|
||||
static nsSVGEnumMapping sMethodMap[];
|
||||
static nsSVGEnumMapping sSpacingMap[];
|
||||
static EnumInfo sEnumInfo[2];
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -322,45 +322,6 @@ GetSingleValue(nsISVGGlyphFragmentLeaf *fragment,
|
|||
nsCOMPtr<nsIDOMSVGLength> length;
|
||||
list->GetItem(0, getter_AddRefs(length));
|
||||
length->GetValue(val);
|
||||
|
||||
nsSVGTextPathFrame *textPath = fragment->FindTextPathParent();
|
||||
|
||||
if (textPath) {
|
||||
nsRefPtr<gfxFlattenedPath> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,6 +400,12 @@ nsSVGTextFrame::UpdateGlyphPositioning()
|
|||
GetSingleValue(firstFragment, list, &y);
|
||||
}
|
||||
|
||||
// check for startOffset on textPath
|
||||
nsSVGTextPathFrame *textPath = firstFragment->FindTextPathParent();
|
||||
if (textPath) {
|
||||
x = textPath->GetStartOffset();
|
||||
}
|
||||
|
||||
// determine x offset based on text_anchor:
|
||||
|
||||
PRUint8 anchor = firstFragment->GetTextAnchor();
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMSVGAnimatedPathData.h"
|
||||
#include "nsSVGPathElement.h"
|
||||
#include "nsSVGTextPathElement.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsSVGPathListener, nsIMutationObserver)
|
||||
|
@ -103,40 +104,6 @@ nsSVGTextPathFrame::Init(nsIContent* aContent,
|
|||
{
|
||||
nsSVGTextPathFrameBase::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGTextPathElement> tpath = do_QueryInterface(mContent);
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLength> length;
|
||||
tpath->GetStartOffset(getter_AddRefs(length));
|
||||
|
||||
// XXX: Gross hack as stand-in until length lists converted
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr,
|
||||
"### Using nsSVGTextPathFrame mStartOffset hack - fix me\n");
|
||||
#endif
|
||||
nsCOMPtr<nsIDOMSVGLength> offset;
|
||||
length->GetAnimVal(getter_AddRefs(offset));
|
||||
PRUint16 type;
|
||||
float value;
|
||||
offset->GetUnitType(&type);
|
||||
offset->GetValueInSpecifiedUnits(&value);
|
||||
nsCOMPtr<nsISVGLength> l;
|
||||
NS_NewSVGLength(getter_AddRefs(l), value, type);
|
||||
mStartOffset = l;
|
||||
|
||||
NS_ASSERTION(mStartOffset, "no startOffset");
|
||||
if (!mStartOffset)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_NewSVGLengthList(getter_AddRefs(mX),
|
||||
static_cast<nsSVGElement*>(mContent),
|
||||
nsSVGUtils::X);
|
||||
if (mX) {
|
||||
nsCOMPtr<nsIDOMSVGLength> length;
|
||||
mX->AppendItem(mStartOffset, getter_AddRefs(length));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGURIReference> aRef = do_QueryInterface(mContent);
|
||||
if (aRef)
|
||||
|
@ -158,9 +125,7 @@ nsSVGTextPathFrame::GetType() const
|
|||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTextPathFrame::GetX()
|
||||
{
|
||||
nsIDOMSVGLengthList *retval = mX;
|
||||
NS_IF_ADDREF(retval);
|
||||
return retval;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
|
@ -208,9 +173,13 @@ already_AddRefed<gfxFlattenedPath>
|
|||
nsSVGTextPathFrame::GetFlattenedPath()
|
||||
{
|
||||
nsIFrame *path = GetPathFrame();
|
||||
if (!path)
|
||||
return nsnull;
|
||||
|
||||
return path ? GetFlattenedPath(path) : nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<gfxFlattenedPath>
|
||||
nsSVGTextPathFrame::GetFlattenedPath(nsIFrame *path)
|
||||
{
|
||||
NS_PRECONDITION(path, "Unexpected null path");
|
||||
nsSVGPathGeometryElement *element = static_cast<nsSVGPathGeometryElement*>
|
||||
(path->GetContent());
|
||||
|
||||
|
@ -223,6 +192,42 @@ nsSVGTextPathFrame::GetFlattenedPath()
|
|||
return element->GetFlattenedPath(localTM);
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
nsSVGTextPathFrame::GetStartOffset()
|
||||
{
|
||||
nsSVGTextPathElement *tp = static_cast<nsSVGTextPathElement*>(mContent);
|
||||
nsSVGLength2 *length = &tp->mLengthAttributes[nsSVGTextPathElement::STARTOFFSET];
|
||||
float val = length->GetAnimValInSpecifiedUnits();
|
||||
|
||||
if (val == 0.0f)
|
||||
return 0.0;
|
||||
|
||||
if (length->GetSpecifiedUnitType() ==
|
||||
nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE) {
|
||||
nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath();
|
||||
return data ? (val * data->GetLength() / 100.0) : 0.0;
|
||||
} else {
|
||||
return val * GetPathScale();
|
||||
}
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
nsSVGTextPathFrame::GetPathScale()
|
||||
{
|
||||
nsIFrame *pathFrame = GetPathFrame();
|
||||
if (!pathFrame)
|
||||
return 1.0;
|
||||
|
||||
nsSVGPathElement *path = static_cast<nsSVGPathElement*>(pathFrame->GetContent());
|
||||
float pl = path->mPathLength.GetAnimValue();
|
||||
|
||||
if (pl == 0.0f)
|
||||
return 1.0;
|
||||
|
||||
nsRefPtr<gfxFlattenedPath> data = GetFlattenedPath(pathFrame);
|
||||
return data ? data->GetLength() / pl : 1.0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIFrame methods
|
||||
|
||||
|
|
|
@ -99,6 +99,8 @@ public:
|
|||
already_AddRefed<gfxFlattenedPath> GetFlattenedPath();
|
||||
nsIFrame *GetPathFrame();
|
||||
|
||||
gfxFloat GetStartOffset();
|
||||
gfxFloat GetPathScale();
|
||||
protected:
|
||||
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX();
|
||||
|
@ -107,13 +109,11 @@ protected:
|
|||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy();
|
||||
|
||||
private:
|
||||
already_AddRefed<gfxFlattenedPath> GetFlattenedPath(nsIFrame *path);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGLength> mStartOffset;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedString> mHref;
|
||||
nsRefPtr<nsSVGPathListener> mPathListener;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGLengthList> mX;
|
||||
|
||||
friend class nsSVGPathListener;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче