Bug 284675 - Handle svg text chunks separately, support dx/dy. r=afri

This commit is contained in:
tor%cs.brown.edu 2005-03-07 04:02:02 +00:00
parent 26cf2bbe92
commit f9c5c6513b
8 changed files with 413 additions and 101 deletions

View File

@ -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")

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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__

View File

@ -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__

View File

@ -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:

View File

@ -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()
{

View File

@ -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()
{