mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-23 10:54:33 +00:00
Bug 284675 - Handle svg text chunks separately, support dx/dy. r=afri
This commit is contained in:
parent
26cf2bbe92
commit
f9c5c6513b
@ -102,6 +102,8 @@ SVG_ATOM(d, "d")
|
||||
SVG_ATOM(direction, "direction")
|
||||
SVG_ATOM(display, "display")
|
||||
SVG_ATOM(dominant_baseline, "dominant-baseline")
|
||||
SVG_ATOM(dx, "dx")
|
||||
SVG_ATOM(dy, "dy")
|
||||
SVG_ATOM(fill, "fill")
|
||||
SVG_ATOM(fill_opacity, "fill-opacity")
|
||||
SVG_ATOM(fill_rule, "fill-rule")
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsSVGStylableElement.h"
|
||||
#include "nsSVGAtoms.h"
|
||||
#include "nsIDOMSVGTSpanElement.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -45,7 +45,7 @@
|
||||
#include "nsISVGSVGElement.h"
|
||||
#include "nsSVGCoordCtxProvider.h"
|
||||
|
||||
typedef nsSVGElement nsSVGTSpanElementBase;
|
||||
typedef nsSVGStylableElement nsSVGTSpanElementBase;
|
||||
|
||||
class nsSVGTSpanElement : public nsSVGTSpanElementBase,
|
||||
public nsIDOMSVGTSpanElement // : nsIDOMSVGTextPositioningElement
|
||||
@ -125,7 +125,8 @@ nsSVGTSpanElement::~nsSVGTSpanElement()
|
||||
nsresult
|
||||
nsSVGTSpanElement::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = nsSVGTSpanElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// Create mapped properties:
|
||||
|
||||
@ -153,6 +154,30 @@ nsSVGTSpanElement::Init()
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dx, #IMPLIED attrib: dx
|
||||
{
|
||||
nsCOMPtr<nsISVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdX),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::dx, mdX);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dy, #IMPLIED attrib: dy
|
||||
{
|
||||
nsCOMPtr<nsISVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdY),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::dy, mdY);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -190,15 +215,17 @@ NS_IMETHODIMP nsSVGTSpanElement::GetY(nsIDOMSVGAnimatedLengthList * *aY)
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList dx; */
|
||||
NS_IMETHODIMP nsSVGTSpanElement::GetDx(nsIDOMSVGAnimatedLengthList * *aDx)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("write me!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
*aDx = mdX;
|
||||
NS_IF_ADDREF(*aDx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList dy; */
|
||||
NS_IMETHODIMP nsSVGTSpanElement::GetDy(nsIDOMSVGAnimatedLengthList * *aDy)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("write me!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
*aDy = mdY;
|
||||
NS_IF_ADDREF(*aDy);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedNumberList rotate; */
|
||||
@ -344,6 +371,26 @@ void nsSVGTSpanElement::ParentChainChanged()
|
||||
lengthlist->SetContext(nsRefPtr<nsSVGCoordCtx>(ctx->GetContextY()));
|
||||
}
|
||||
|
||||
// dx:
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> dom_lengthlist;
|
||||
mdX->GetAnimVal(getter_AddRefs(dom_lengthlist));
|
||||
nsCOMPtr<nsISVGLengthList> lengthlist = do_QueryInterface(dom_lengthlist);
|
||||
NS_ASSERTION(lengthlist, "svg lengthlist missing interface");
|
||||
|
||||
lengthlist->SetContext(nsRefPtr<nsSVGCoordCtx>(ctx->GetContextX()));
|
||||
}
|
||||
|
||||
// dy:
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> dom_lengthlist;
|
||||
mdY->GetAnimVal(getter_AddRefs(dom_lengthlist));
|
||||
nsCOMPtr<nsISVGLengthList> lengthlist = do_QueryInterface(dom_lengthlist);
|
||||
NS_ASSERTION(lengthlist, "svg lengthlist missing interface");
|
||||
|
||||
lengthlist->SetContext(nsRefPtr<nsSVGCoordCtx>(ctx->GetContextY()));
|
||||
}
|
||||
|
||||
// recurse into child content:
|
||||
nsSVGTSpanElementBase::ParentChainChanged();
|
||||
}
|
||||
|
@ -160,6 +160,30 @@ nsSVGTextElement::Init()
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dx, #IMPLIED attrib: dx
|
||||
{
|
||||
nsCOMPtr<nsISVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdX),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::dx, mdX);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
// DOM property: nsIDOMSVGTextPositioningElement::dy, #IMPLIED attrib: dy
|
||||
{
|
||||
nsCOMPtr<nsISVGLengthList> lengthList;
|
||||
rv = NS_NewSVGLengthList(getter_AddRefs(lengthList));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = NS_NewSVGAnimatedLengthList(getter_AddRefs(mdY),
|
||||
lengthList);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
rv = AddMappedSVGValue(nsSVGAtoms::dy, mdY);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -197,15 +221,17 @@ NS_IMETHODIMP nsSVGTextElement::GetY(nsIDOMSVGAnimatedLengthList * *aY)
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList dx; */
|
||||
NS_IMETHODIMP nsSVGTextElement::GetDx(nsIDOMSVGAnimatedLengthList * *aDx)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("write me!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
*aDx = mdX;
|
||||
NS_IF_ADDREF(*aDx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedLengthList dy; */
|
||||
NS_IMETHODIMP nsSVGTextElement::GetDy(nsIDOMSVGAnimatedLengthList * *aDy)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("write me!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
*aDy = mdY;
|
||||
NS_IF_ADDREF(*aDy);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedNumberList rotate; */
|
||||
@ -359,6 +385,26 @@ void nsSVGTextElement::ParentChainChanged()
|
||||
lengthlist->SetContext(nsRefPtr<nsSVGCoordCtx>(ctx->GetContextY()));
|
||||
}
|
||||
|
||||
// dx:
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> dom_lengthlist;
|
||||
mdX->GetAnimVal(getter_AddRefs(dom_lengthlist));
|
||||
nsCOMPtr<nsISVGLengthList> lengthlist = do_QueryInterface(dom_lengthlist);
|
||||
NS_ASSERTION(lengthlist, "svg lengthlist missing interface");
|
||||
|
||||
lengthlist->SetContext(nsRefPtr<nsSVGCoordCtx>(ctx->GetContextX()));
|
||||
}
|
||||
|
||||
// dy:
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> dom_lengthlist;
|
||||
mdY->GetAnimVal(getter_AddRefs(dom_lengthlist));
|
||||
nsCOMPtr<nsISVGLengthList> lengthlist = do_QueryInterface(dom_lengthlist);
|
||||
NS_ASSERTION(lengthlist, "svg lengthlist missing interface");
|
||||
|
||||
lengthlist->SetContext(nsRefPtr<nsSVGCoordCtx>(ctx->GetContextY()));
|
||||
}
|
||||
|
||||
// recurse into child content:
|
||||
nsSVGTextElementBase::ParentChainChanged();
|
||||
}
|
||||
|
@ -40,12 +40,12 @@
|
||||
#define __NS_ISVGGLYPHFRAGMENTLEAF_H__
|
||||
|
||||
#include "nsISVGGlyphFragmentNode.h"
|
||||
#include "nsIDOMSVGLengthList.h"
|
||||
|
||||
class nsISVGRendererGlyphMetrics;
|
||||
|
||||
// {3D47D8F2-BFE9-44FC-847C-8FEFD0AC2624}
|
||||
#define NS_ISVGGLYPHFRAGMENTLEAF_IID \
|
||||
{ 0x3d47d8f2, 0xbfe9, 0x44fc, { 0x84, 0x7c, 0x8f, 0xef, 0xd0, 0xac, 0x26, 0x24 } }
|
||||
{ 0x7e8500f1, 0xb3a5, 0x4e8a, { 0x90, 0x78, 0x03, 0x34, 0xc7, 0xcb, 0x30, 0x16 } }
|
||||
|
||||
class nsISVGGlyphFragmentLeaf : public nsISVGGlyphFragmentNode
|
||||
{
|
||||
@ -61,6 +61,13 @@ public:
|
||||
NS_IMETHOD_(void) GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y)=0;
|
||||
NS_IMETHOD_(PRUint32) GetNumberOfChars()=0;
|
||||
NS_IMETHOD_(PRUint32) GetCharNumberOffset()=0;
|
||||
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX()=0;
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY()=0;
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDx()=0;
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy()=0;
|
||||
NS_IMETHOD_(PRUint16) GetTextAnchor()=0;
|
||||
NS_IMETHOD_(PRBool) IsAbsolutelyPositioned()=0;
|
||||
};
|
||||
|
||||
#endif // __NS_ISVGGLYPHFRAGMENTLEAF_H__
|
||||
|
@ -40,11 +40,11 @@
|
||||
#define __NS_ISVGTEXTCONTAINERFRAME_H__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIDOMSVGLengthList.h"
|
||||
class nsISVGTextFrame;
|
||||
|
||||
// {1044E336-41E2-414D-9542-FCDBA11C15A8}
|
||||
#define NS_ISVGTEXTCONTAINERFRAME_IID \
|
||||
{ 0x1044e336, 0x41e2, 0x414d, { 0x95, 0x42, 0xfc, 0xdb, 0xa1, 0x1c, 0x15, 0xa8 } }
|
||||
{ 0x3d3a12c4, 0x06bb, 0x4662, { 0xa3, 0xe3, 0x55, 0xaf, 0x5a, 0x48, 0x22, 0x78 } }
|
||||
|
||||
class nsISVGTextContainerFrame : public nsISupports
|
||||
{
|
||||
@ -57,6 +57,11 @@ public:
|
||||
NS_IMETHOD_(PRBool) GetAbsolutePositionAdjustmentY(float &y, PRUint32 charNum)=0;
|
||||
NS_IMETHOD_(PRBool) GetRelativePositionAdjustmentX(float &dx, PRUint32 charNum)=0;
|
||||
NS_IMETHOD_(PRBool) GetRelativePositionAdjustmentY(float &dy, PRUint32 charNum)=0;
|
||||
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX()=0;
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY()=0;
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDx()=0;
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy()=0;
|
||||
};
|
||||
|
||||
#endif // __NS_ISVGTEXTCONTAINERFRAME_H__
|
||||
|
@ -60,6 +60,8 @@
|
||||
#include "nsSVGPoint.h"
|
||||
#include "nsSVGAtoms.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsContainerFrame.h"
|
||||
|
||||
typedef nsFrame nsSVGGlyphFrameBase;
|
||||
|
||||
@ -132,6 +134,13 @@ public:
|
||||
NS_IMETHOD_(PRUint32) GetNumberOfChars();
|
||||
NS_IMETHOD_(PRUint32) GetCharNumberOffset();
|
||||
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDx();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy();
|
||||
NS_IMETHOD_(PRUint16) GetTextAnchor();
|
||||
NS_IMETHOD_(PRBool) IsAbsolutelyPositioned();
|
||||
|
||||
// nsISVGGlyphFragmentNode interface:
|
||||
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment();
|
||||
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetNextGlyphFragment();
|
||||
@ -988,6 +997,72 @@ nsSVGGlyphFrame::GetCharNumberOffset()
|
||||
return mCharOffset;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGGlyphFrame::GetX()
|
||||
{
|
||||
nsISVGTextContainerFrame *containerFrame;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
|
||||
(void**)&containerFrame);
|
||||
if (containerFrame)
|
||||
return containerFrame->GetX();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGGlyphFrame::GetY()
|
||||
{
|
||||
nsISVGTextContainerFrame *containerFrame;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
|
||||
(void**)&containerFrame);
|
||||
if (containerFrame)
|
||||
return containerFrame->GetY();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGGlyphFrame::GetDx()
|
||||
{
|
||||
nsISVGTextContainerFrame *containerFrame;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
|
||||
(void**)&containerFrame);
|
||||
if (containerFrame)
|
||||
return containerFrame->GetDx();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGGlyphFrame::GetDy()
|
||||
{
|
||||
nsISVGTextContainerFrame *containerFrame;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
|
||||
(void**)&containerFrame);
|
||||
if (containerFrame)
|
||||
return containerFrame->GetDy();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRUint16)
|
||||
nsSVGGlyphFrame::GetTextAnchor()
|
||||
{
|
||||
return GetStyleSVG()->mTextAnchor;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsSVGGlyphFrame::IsAbsolutelyPositioned()
|
||||
{
|
||||
nsISVGTextContainerFrame *textFrame;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
|
||||
(void**)&textFrame);
|
||||
if (textFrame) {
|
||||
if (mParent->GetFirstChild(nsnull) == this &&
|
||||
(mParent->GetContent()->HasAttr(kNameSpaceID_None, nsSVGAtoms::x) ||
|
||||
mParent->GetContent()->HasAttr(kNameSpaceID_None, nsSVGAtoms::y)))
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGGlyphFragmentNode interface:
|
||||
|
||||
|
@ -58,6 +58,8 @@
|
||||
#include "nsISVGOuterSVGFrame.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsSVGMatrix.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsSVGAtoms.h"
|
||||
|
||||
typedef nsContainerFrame nsSVGTSpanFrameBase;
|
||||
|
||||
@ -133,6 +135,10 @@ public:
|
||||
NS_IMETHOD_(PRBool) GetAbsolutePositionAdjustmentY(float &y, PRUint32 charNum);
|
||||
NS_IMETHOD_(PRBool) GetRelativePositionAdjustmentX(float &dx, PRUint32 charNum);
|
||||
NS_IMETHOD_(PRBool) GetRelativePositionAdjustmentY(float &dy, PRUint32 charNum);
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDx();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy();
|
||||
|
||||
// nsISVGGlyphFragmentNode interface:
|
||||
NS_IMETHOD_(nsISVGGlyphFragmentLeaf *) GetFirstGlyphFragment();
|
||||
@ -144,8 +150,6 @@ public:
|
||||
NS_IMETHOD_(void) NotifyGlyphFragmentTreeUnsuspended();
|
||||
|
||||
protected:
|
||||
already_AddRefed<nsIDOMSVGLengthList> GetX();
|
||||
already_AddRefed<nsIDOMSVGLengthList> GetY();
|
||||
nsISVGGlyphFragmentNode *GetFirstGlyphFragmentChildNode();
|
||||
nsISVGGlyphFragmentNode *GetNextGlyphFragmentChildNode(nsISVGGlyphFragmentNode*node);
|
||||
|
||||
@ -205,6 +209,16 @@ nsSVGTSpanFrame::~nsSVGTSpanFrame()
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetY();
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDx();
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDy();
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsSVGTSpanFrame::Init()
|
||||
@ -220,6 +234,16 @@ nsresult nsSVGTSpanFrame::Init()
|
||||
NS_ADD_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDx();
|
||||
NS_ADD_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDy();
|
||||
NS_ADD_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -779,12 +803,20 @@ nsSVGTSpanFrame::NotifyGlyphFragmentTreeUnsuspended()
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
|
||||
already_AddRefed<nsIDOMSVGLengthList>
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTSpanFrame::GetX()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(tpElement, "wrong content element");
|
||||
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::x)) {
|
||||
nsISVGTextContainerFrame *parent;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame), (void **)&parent);
|
||||
if (parent)
|
||||
return parent->GetX();
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetX(getter_AddRefs(animLengthList));
|
||||
nsIDOMSVGLengthList *retval;
|
||||
@ -792,12 +824,20 @@ nsSVGTSpanFrame::GetX()
|
||||
return retval;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGLengthList>
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTSpanFrame::GetY()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(tpElement, "wrong content element");
|
||||
|
||||
if (!mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::y)) {
|
||||
nsISVGTextContainerFrame *parent;
|
||||
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame), (void **)&parent);
|
||||
if (parent)
|
||||
return parent->GetY();
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetY(getter_AddRefs(animLengthList));
|
||||
nsIDOMSVGLengthList *retval;
|
||||
@ -805,6 +845,32 @@ nsSVGTSpanFrame::GetY()
|
||||
return retval;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTSpanFrame::GetDx()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(tpElement, "wrong content element");
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetDx(getter_AddRefs(animLengthList));
|
||||
nsIDOMSVGLengthList *retval;
|
||||
animLengthList->GetAnimVal(&retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTSpanFrame::GetDy()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(tpElement, "wrong content element");
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetDy(getter_AddRefs(animLengthList));
|
||||
nsIDOMSVGLengthList *retval;
|
||||
animLengthList->GetAnimVal(&retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
nsISVGGlyphFragmentNode *
|
||||
nsSVGTSpanFrame::GetFirstGlyphFragmentChildNode()
|
||||
{
|
||||
|
@ -155,13 +155,15 @@ public:
|
||||
NS_IMETHOD_(PRBool) GetAbsolutePositionAdjustmentY(float &y, PRUint32 charNum);
|
||||
NS_IMETHOD_(PRBool) GetRelativePositionAdjustmentX(float &dx, PRUint32 charNum);
|
||||
NS_IMETHOD_(PRBool) GetRelativePositionAdjustmentY(float &dy, PRUint32 charNum);
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDx();
|
||||
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy();
|
||||
|
||||
protected:
|
||||
void EnsureFragmentTreeUpToDate();
|
||||
void UpdateFragmentTree();
|
||||
void UpdateGlyphPositioning();
|
||||
already_AddRefed<nsIDOMSVGLengthList> GetX();
|
||||
already_AddRefed<nsIDOMSVGLengthList> GetY();
|
||||
already_AddRefed<nsIDOMSVGAnimatedTransformList> GetTransform();
|
||||
nsISVGGlyphFragmentNode *GetFirstGlyphFragmentChildNode();
|
||||
nsISVGGlyphFragmentNode *GetNextGlyphFragmentChildNode(nsISVGGlyphFragmentNode*node);
|
||||
@ -171,10 +173,10 @@ protected:
|
||||
unsuspended,
|
||||
suspended,
|
||||
updating};
|
||||
UpdateState mMetricsState;
|
||||
UpdateState mFragmentTreeState;
|
||||
PRBool mPositioningDirty;
|
||||
UpdateState mMetricsState;
|
||||
PRBool mFragmentTreeDirty;
|
||||
PRBool mPositioningDirty;
|
||||
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
|
||||
PRBool mPropagateTransform;
|
||||
@ -227,6 +229,16 @@ nsSVGTextFrame::~nsSVGTextFrame()
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDx();
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDy();
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTransformable> transformable = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(transformable, "wrong content element");
|
||||
@ -249,6 +261,16 @@ nsresult nsSVGTextFrame::Init()
|
||||
NS_ADD_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDx();
|
||||
NS_ADD_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> lengthList = GetDy();
|
||||
NS_ADD_SVGVALUE_OBSERVER(lengthList);
|
||||
}
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGAnimatedTransformList> transforms = GetTransform();
|
||||
NS_ADD_SVGVALUE_OBSERVER(transforms);
|
||||
@ -970,77 +992,34 @@ nsSVGTextFrame::UpdateFragmentTree()
|
||||
UpdateGlyphPositioning();
|
||||
}
|
||||
|
||||
static void
|
||||
GetSingleValue(nsIDOMSVGLengthList *list, float *val)
|
||||
{
|
||||
*val = 0.0f;
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
PRUint32 count = 0;
|
||||
list->GetNumberOfItems(&count);
|
||||
#ifdef DEBUG
|
||||
if (count > 1)
|
||||
NS_WARNING("multiple lengths for x/y attributes on <text> elements not implemented yet!");
|
||||
#endif
|
||||
if (count) {
|
||||
nsCOMPtr<nsIDOMSVGLength> length;
|
||||
list->GetItem(0, getter_AddRefs(length));
|
||||
length->GetValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGTextFrame::UpdateGlyphPositioning()
|
||||
{
|
||||
// XXX need to iterate separately over each chunk (currently we
|
||||
// treat everything underneath this text-element as a single chunk)
|
||||
|
||||
NS_ASSERTION(mMetricsState == unsuspended, "updating during suspension");
|
||||
|
||||
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
|
||||
if (!node) return;
|
||||
|
||||
nsISVGGlyphFragmentLeaf* fragment;
|
||||
|
||||
float x=0.0f;
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = GetX();
|
||||
PRUint32 count = 0;
|
||||
list->GetNumberOfItems(&count);
|
||||
#ifdef DEBUG
|
||||
if (count > 1)
|
||||
NS_WARNING("multiple lengths for x/y attributes on <text> elements not implemented yet!");
|
||||
#endif
|
||||
if (count) {
|
||||
nsCOMPtr<nsIDOMSVGLength> length;
|
||||
list->GetItem(0, getter_AddRefs(length));
|
||||
length->GetValue(&x);
|
||||
}
|
||||
}
|
||||
|
||||
float y=0.0f;
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = GetY();
|
||||
PRUint32 count = 0;
|
||||
list->GetNumberOfItems(&count);
|
||||
#ifdef DEBUG
|
||||
if (count > 1)
|
||||
NS_WARNING("multiple lengths for x/y attributes on <text> elements not implemented yet!");
|
||||
#endif
|
||||
if (count) {
|
||||
nsCOMPtr<nsIDOMSVGLength> length;
|
||||
list->GetItem(0, getter_AddRefs(length));
|
||||
length->GetValue(&y);
|
||||
}
|
||||
}
|
||||
|
||||
// determine x offset based on text_anchor:
|
||||
|
||||
PRUint8 anchor = GetStyleSVG()->mTextAnchor;
|
||||
|
||||
float chunkLength = 0.0f;
|
||||
if (anchor != NS_STYLE_TEXT_ANCHOR_START) {
|
||||
// need to get the total chunk length
|
||||
|
||||
fragment = node->GetFirstGlyphFragment();
|
||||
while (fragment) {
|
||||
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
|
||||
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
|
||||
if (!metrics) continue;
|
||||
|
||||
float advance;
|
||||
metrics->GetAdvance(&advance);
|
||||
chunkLength+=advance;
|
||||
fragment = fragment->GetNextGlyphFragment();
|
||||
}
|
||||
}
|
||||
|
||||
if (anchor == NS_STYLE_TEXT_ANCHOR_MIDDLE)
|
||||
x -= chunkLength/2.0f;
|
||||
else if (anchor == NS_STYLE_TEXT_ANCHOR_END)
|
||||
x -= chunkLength;
|
||||
|
||||
// we'll align every fragment in this chunk on the dominant-baseline:
|
||||
// XXX should actually inspect 'alignment-baseline' for each fragment
|
||||
|
||||
@ -1074,31 +1053,90 @@ nsSVGTextFrame::UpdateGlyphPositioning()
|
||||
baseline = nsISVGRendererGlyphMetrics::BASELINE_ALPHABETIC;
|
||||
break;
|
||||
}
|
||||
|
||||
nsISVGGlyphFragmentLeaf *fragment, *firstFragment;
|
||||
|
||||
firstFragment = node->GetFirstGlyphFragment();
|
||||
|
||||
// loop over chunks
|
||||
while (firstFragment) {
|
||||
float x, y;
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = firstFragment->GetX();
|
||||
GetSingleValue(list, &x);
|
||||
}
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = firstFragment->GetY();
|
||||
GetSingleValue(list, &y);
|
||||
}
|
||||
|
||||
// determine x offset based on text_anchor:
|
||||
|
||||
// set position of each fragment in this chunk:
|
||||
PRUint8 anchor = firstFragment->GetTextAnchor();
|
||||
|
||||
float chunkLength = 0.0f;
|
||||
if (anchor != NS_STYLE_TEXT_ANCHOR_START) {
|
||||
// need to get the total chunk length
|
||||
|
||||
fragment = firstFragment;
|
||||
while (fragment) {
|
||||
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
|
||||
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
|
||||
if (!metrics) continue;
|
||||
|
||||
float advance, dx;
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDx();
|
||||
GetSingleValue(list, &dx);
|
||||
metrics->GetAdvance(&advance);
|
||||
chunkLength += advance + dx;
|
||||
fragment = fragment->GetNextGlyphFragment();
|
||||
if (fragment && fragment->IsAbsolutelyPositioned())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anchor == NS_STYLE_TEXT_ANCHOR_MIDDLE)
|
||||
x -= chunkLength/2.0f;
|
||||
else if (anchor == NS_STYLE_TEXT_ANCHOR_END)
|
||||
x -= chunkLength;
|
||||
|
||||
fragment = node->GetFirstGlyphFragment();
|
||||
while (fragment) {
|
||||
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
|
||||
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
|
||||
if (!metrics) continue;
|
||||
// set position of each fragment in this chunk:
|
||||
|
||||
fragment = firstFragment;
|
||||
while (fragment) {
|
||||
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
|
||||
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
|
||||
if (!metrics) continue;
|
||||
|
||||
float baseline_offset;
|
||||
metrics->GetBaselineOffset(baseline, &baseline_offset);
|
||||
float baseline_offset, dx, dy;
|
||||
metrics->GetBaselineOffset(baseline, &baseline_offset);
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDx();
|
||||
GetSingleValue(list, &dx);
|
||||
}
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDy();
|
||||
GetSingleValue(list, &dy);
|
||||
}
|
||||
|
||||
fragment->SetGlyphPosition(x, y - baseline_offset);
|
||||
fragment->SetGlyphPosition(x + dx, y + dy - baseline_offset);
|
||||
|
||||
float advance;
|
||||
metrics->GetAdvance(&advance);
|
||||
x+=advance;
|
||||
fragment = fragment->GetNextGlyphFragment();
|
||||
float advance;
|
||||
metrics->GetAdvance(&advance);
|
||||
x += dx + advance;
|
||||
y += dy;
|
||||
fragment = fragment->GetNextGlyphFragment();
|
||||
if (fragment && fragment->IsAbsolutelyPositioned())
|
||||
break;
|
||||
}
|
||||
firstFragment = fragment;
|
||||
}
|
||||
|
||||
mPositioningDirty = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<nsIDOMSVGLengthList>
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTextFrame::GetX()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
@ -1111,7 +1149,7 @@ nsSVGTextFrame::GetX()
|
||||
return retval;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGLengthList>
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTextFrame::GetY()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
@ -1124,6 +1162,32 @@ nsSVGTextFrame::GetY()
|
||||
return retval;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTextFrame::GetDx()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(tpElement, "wrong content element");
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetDx(getter_AddRefs(animLengthList));
|
||||
nsIDOMSVGLengthList *retval;
|
||||
animLengthList->GetAnimVal(&retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
|
||||
nsSVGTextFrame::GetDy()
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
|
||||
NS_ASSERTION(tpElement, "wrong content element");
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
|
||||
tpElement->GetDy(getter_AddRefs(animLengthList));
|
||||
nsIDOMSVGLengthList *retval;
|
||||
animLengthList->GetAnimVal(&retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMSVGAnimatedTransformList>
|
||||
nsSVGTextFrame::GetTransform()
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user