Bug 341638 - Rationalise nsSVGTextFrame, nsSVGTextPathFrame and nsSVGTSpanFrame. r=tor,sr=roc

This commit is contained in:
longsonr%gmail.com 2006-06-28 15:23:40 +00:00
Родитель a05eecad70
Коммит bea6a3f15c
20 изменённых файлов: 824 добавлений и 1098 удалений

Просмотреть файл

@ -41,6 +41,7 @@
#include "nsISupports.h"
class nsIDOMSVGRect;
class nsIDOMSVGPoint;
////////////////////////////////////////////////////////////////////////
// nsISVGTextContentMetrics

Просмотреть файл

@ -42,6 +42,7 @@
#include "nsSVGPathGeometryElement.h"
#include "nsIDOMSVGPathElement.h"
#include "nsIDOMSVGAnimatedPathData.h"
#include "cairo.h"
class nsSVGPathList
{

Просмотреть файл

@ -172,7 +172,7 @@ NS_NewHTMLCanvasFrame (nsIPresShell* aPresShell, nsStyleContext* aContext);
#ifdef MOZ_SVG
#include "nsSVGAtoms.h"
#include "nsISVGTextContainerFrame.h"
#include "nsISVGTextContentMetrics.h"
#include "nsStyleUtil.h"
#include "nsSVGUtils.h"
@ -5489,8 +5489,9 @@ nsCSSFrameConstructor::ConstructTextFrame(nsFrameConstructorState& aState,
#ifdef MOZ_SVG
if (aParentFrame->IsFrameOfType(nsIFrame::eSVG)) {
nsCOMPtr<nsISVGTextContainerFrame> svg_parent = do_QueryInterface(aParentFrame);
if (!svg_parent) {
nsISVGTextContentMetrics* metrics;
CallQueryInterface(aParentFrame, &metrics);
if (!metrics) {
return NS_OK;
}
newFrame = NS_NewSVGGlyphFrame(mPresShell, aContent, aParentFrame, aStyleContext);

Просмотреть файл

@ -85,6 +85,7 @@ CPPSRCS = \
nsSVGPathGeometryFrame.cpp \
nsSVGPatternFrame.cpp \
nsSVGStopFrame.cpp \
nsSVGTextContainerFrame.cpp \
nsSVGTextFrame.cpp \
nsSVGTextPathFrame.cpp \
nsSVGTSpanFrame.cpp \

Просмотреть файл

@ -1,70 +0,0 @@
/* -*- 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
* Crocodile Clips Ltd..
* Portions created by the Initial Developer are Copyright (C) 2002
* 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_ISVGTEXTCONTAINERFRAME_H__
#define __NS_ISVGTEXTCONTAINERFRAME_H__
#include "nsISupports.h"
#include "nsIDOMSVGLengthList.h"
class nsISVGTextFrame;
#define NS_ISVGTEXTCONTAINERFRAME_IID \
{ 0x3d3a12c4, 0x06bb, 0x4662, { 0xa3, 0xe3, 0x55, 0xaf, 0x5a, 0x48, 0x22, 0x78 } }
class nsISVGTextContainerFrame : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISVGTEXTCONTAINERFRAME_IID)
NS_IMETHOD_(nsISVGTextFrame *) GetTextFrame()=0;
NS_IMETHOD_(PRBool) GetAbsolutePositionAdjustmentX(float &x, PRUint32 charNum)=0;
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;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGTextContainerFrame,
NS_ISVGTEXTCONTAINERFRAME_IID)
#endif // __NS_ISVGTEXTCONTAINERFRAME_H__

Просмотреть файл

@ -1,65 +0,0 @@
/* -*- 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
* Crocodile Clips Ltd..
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alex Fritze <alex@croczilla.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_ISVGTEXTFRAME_H__
#define __NS_ISVGTEXTFRAME_H__
#include "nsISVGTextContainerFrame.h"
class nsISVGGlyphFragmentNode;
class nsIDOMSVGMatrix;
// {24717461-465F-4575-85B2-923285EC18D5}
#define NS_ISVGTEXTFRAME_IID \
{ 0x24717461, 0x465f, 0x4575, { 0x85, 0xb2, 0x92, 0x32, 0x85, 0xec, 0x18, 0xd5 } }
class nsISVGTextFrame : public nsISVGTextContainerFrame
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISVGTEXTFRAME_IID)
NS_IMETHOD_(void) NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller)=0;
NS_IMETHOD_(void) NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller)=0;
NS_IMETHOD_(PRBool) IsMetricsSuspended()=0;
NS_IMETHOD_(PRBool) IsGlyphFragmentTreeSuspended()=0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsISVGTextFrame, NS_ISVGTEXTFRAME_IID)
#endif // __NS_ISVGTEXTFRAME_H__

Просмотреть файл

@ -38,6 +38,9 @@
#include "nsSVGUtils.h"
#include "nsSVGOuterSVGFrame.h"
//----------------------------------------------------------------------
// nsISupports methods
NS_INTERFACE_MAP_BEGIN(nsSVGDisplayContainerFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGChildFrame)
NS_INTERFACE_MAP_END_INHERITING(nsSVGContainerFrame)

Просмотреть файл

@ -39,7 +39,6 @@
#include "nsContainerFrame.h"
#include "nsISVGChildFrame.h"
#include "nsSVGUtils.h"
#include "nsIDOMSVGMatrix.h"
#include "nsSVGCoordCtxProvider.h"
@ -92,6 +91,11 @@ public:
// nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public:
// nsIFrame:
NS_IMETHOD InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,

Просмотреть файл

@ -54,9 +54,6 @@ class nsSVGGenericContainerFrame : public nsSVGGenericContainerFrameBase
protected:
nsSVGGenericContainerFrame(nsStyleContext* aContext) : nsSVGGenericContainerFrameBase(aContext) {}
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public:
// nsIFrame:
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,

Просмотреть файл

@ -41,24 +41,14 @@
#include "nsISVGRenderer.h"
#include "nsITextContent.h"
#include "nsSVGOuterSVGFrame.h"
#include "nsISVGTextFrame.h"
#include "nsSVGContainerFrame.h"
#include "nsISVGTextContainerFrame.h"
#include "nsISVGValueUtils.h"
#include "nsReadableUtils.h"
#include "nsCRT.h"
#include "prdtoa.h"
#include "nsIDOMSVGRect.h"
#include "nsSVGTextFrame.h"
#include "nsILookAndFeel.h"
#include "nsTextFragment.h"
#include "nsSVGRect.h"
#include "nsSVGPoint.h"
#include "nsSVGAtoms.h"
#include "nsIViewManager.h"
#include "nsINameSpaceManager.h"
#include "nsContainerFrame.h"
#include "nsLayoutAtoms.h"
#include "nsSVGUtils.h"
#include "nsIDOMSVGLengthList.h"
#include "nsIDOMSVGLength.h"
#include "nsIDOMSVGRect.h"
#include "nsIDOMSVGPoint.h"
#include "nsSVGGlyphFrame.h"
#include "nsSVGTextPathFrame.h"
#include "nsSVGPathElement.h"
@ -69,15 +59,13 @@
nsIFrame*
NS_NewSVGGlyphFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsIFrame* parentFrame, nsStyleContext* aContext)
{
#ifdef DEBUG
NS_ASSERTION(parentFrame, "null parent");
nsISVGTextContainerFrame *text_container;
parentFrame->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame), (void**)&text_container);
NS_ASSERTION(text_container, "trying to construct an SVGGlyphFrame for an invalid container");
nsISVGTextContentMetrics *metrics;
CallQueryInterface(parentFrame, &metrics);
NS_ASSERTION(metrics, "trying to construct an SVGGlyphFrame for an invalid container");
nsCOMPtr<nsITextContent> tc = do_QueryInterface(aContent);
NS_ASSERTION(tc, "trying to construct an SVGGlyphFrame for wrong content element");
#endif
return new (aPresShell) nsSVGGlyphFrame(aContext);
}
@ -722,9 +710,8 @@ nsSVGGlyphFrame::GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y)
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGGlyphFrame::GetX()
{
nsISVGTextContainerFrame *containerFrame;
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
(void**)&containerFrame);
nsSVGTextContainerFrame *containerFrame;
containerFrame = NS_STATIC_CAST (nsSVGTextContainerFrame *, mParent);
if (containerFrame)
return containerFrame->GetX();
return nsnull;
@ -733,9 +720,8 @@ nsSVGGlyphFrame::GetX()
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGGlyphFrame::GetY()
{
nsISVGTextContainerFrame *containerFrame;
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
(void**)&containerFrame);
nsSVGTextContainerFrame *containerFrame;
containerFrame = NS_STATIC_CAST (nsSVGTextContainerFrame *, mParent);
if (containerFrame)
return containerFrame->GetY();
return nsnull;
@ -744,9 +730,8 @@ nsSVGGlyphFrame::GetY()
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGGlyphFrame::GetDx()
{
nsISVGTextContainerFrame *containerFrame;
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
(void**)&containerFrame);
nsSVGTextContainerFrame *containerFrame;
containerFrame = NS_STATIC_CAST (nsSVGTextContainerFrame *, mParent);
if (containerFrame)
return containerFrame->GetDx();
return nsnull;
@ -755,9 +740,8 @@ nsSVGGlyphFrame::GetDx()
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGGlyphFrame::GetDy()
{
nsISVGTextContainerFrame *containerFrame;
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
(void**)&containerFrame);
nsSVGTextContainerFrame *containerFrame;
containerFrame = NS_STATIC_CAST (nsSVGTextContainerFrame *, mParent);
if (containerFrame)
return containerFrame->GetDy();
return nsnull;
@ -788,8 +772,8 @@ nsSVGGlyphFrame::IsAbsolutelyPositioned()
return PR_TRUE;
if (frame &&
(frame->GetContent()->HasAttr(kNameSpaceID_None, nsSVGAtoms::x) ||
frame->GetContent()->HasAttr(kNameSpaceID_None, nsSVGAtoms::y)))
(frame->GetContent()->HasAttr(kNameSpaceID_None, nsGkAtoms::x) ||
frame->GetContent()->HasAttr(kNameSpaceID_None, nsGkAtoms::y)))
return PR_TRUE;
if (frame->GetType() == nsLayoutAtoms::svgTextFrame)
@ -905,7 +889,7 @@ nsSVGGlyphFrame::NotifyMetricsUnsuspended()
mMetrics->Update(&metricsDirty);
if (metricsDirty) {
AddStateBits(NS_STATE_SVG_DIRTY);
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
NS_ASSERTION(text_frame, "null text frame");
if (text_frame)
text_frame->NotifyGlyphMetricsChange(this);
@ -924,7 +908,7 @@ NS_IMETHODIMP_(void)
nsSVGGlyphFrame::NotifyGlyphFragmentTreeUnsuspended()
{
if (mFragmentTreeDirty) {
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
NS_ASSERTION(text_frame, "null text frame");
if (text_frame)
text_frame->NotifyGlyphFragmentTreeChange(this);
@ -974,7 +958,7 @@ void nsSVGGlyphFrame::UpdateGeometry(PRBool bRedraw,
void nsSVGGlyphFrame::UpdateMetrics()
{
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
if (!text_frame) {
NS_ERROR("null text_frame");
return;
@ -999,7 +983,7 @@ void nsSVGGlyphFrame::UpdateFragmentTree()
{
mFragmentTreeDirty = PR_TRUE;
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
if (!text_frame) {
NS_ERROR("null text_frame");
return;
@ -1012,13 +996,13 @@ void nsSVGGlyphFrame::UpdateFragmentTree()
}
}
nsISVGTextFrame *
nsSVGTextFrame *
nsSVGGlyphFrame::GetTextFrame()
{
NS_ASSERTION(mParent, "null parent");
nsISVGTextContainerFrame *containerFrame;
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame), (void**)&containerFrame);
nsSVGTextContainerFrame *containerFrame;
containerFrame = NS_STATIC_CAST (nsSVGTextContainerFrame *, mParent);
if (!containerFrame) {
NS_ERROR("invalid container");
return nsnull;

Просмотреть файл

@ -44,7 +44,7 @@
#include "nsISVGGlyphFragmentLeaf.h"
#include "nsISVGChildFrame.h"
class nsISVGTextFrame;
class nsSVGTextFrame;
typedef nsSVGGeometryFrame nsSVGGlyphFrameBase;
@ -152,7 +152,7 @@ protected:
void UpdateGeometry(PRBool bRedraw, PRBool suppressInvalidation);
void UpdateMetrics();
void UpdateFragmentTree();
nsISVGTextFrame *GetTextFrame();
nsSVGTextFrame *GetTextFrame();
nsString mCharacterData;
nsCOMPtr<nsISVGRendererGlyphGeometry> mGeometry;

Просмотреть файл

@ -36,9 +36,12 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMSVGTSpanElement.h"
#include "nsSVGTSpanFrame.h"
#include "nsSVGUtils.h"
#include "nsSVGTextFrame.h"
#include "nsSVGOuterSVGFrame.h"
#include "nsSVGMatrix.h"
//----------------------------------------------------------------------
// Implementation
@ -48,10 +51,9 @@ NS_NewSVGTSpanFrame(nsIPresShell* aPresShell, nsIContent* aContent,
nsIFrame* parentFrame, nsStyleContext* aContext)
{
NS_ASSERTION(parentFrame, "null parent");
nsISVGTextContainerFrame *text_container;
parentFrame->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame),
(void**)&text_container);
if (!text_container) {
nsISVGTextContentMetrics *metrics;
CallQueryInterface(parentFrame, &metrics);
if (!metrics) {
NS_ERROR("trying to construct an SVGTSpanFrame for an invalid container");
return nsnull;
}
@ -66,12 +68,6 @@ NS_NewSVGTSpanFrame(nsIPresShell* aPresShell, nsIContent* aContent,
return new (aPresShell) nsSVGTSpanFrame(aContext);
}
nsSVGTSpanFrame::nsSVGTSpanFrame(nsStyleContext* aContext)
: nsSVGTSpanFrameBase(aContext),
mFragmentTreeDirty(PR_FALSE), mPropagateTransform(PR_TRUE)
{
}
nsIAtom *
nsSVGTSpanFrame::GetType() const
{
@ -82,12 +78,9 @@ nsSVGTSpanFrame::GetType() const
// nsISupports methods
NS_INTERFACE_MAP_BEGIN(nsSVGTSpanFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGTextContainerFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGGlyphFragmentNode)
NS_INTERFACE_MAP_ENTRY(nsISVGTextContentMetrics)
NS_INTERFACE_MAP_END_INHERITING(nsSVGTSpanFrameBase)
//----------------------------------------------------------------------
// nsIFrame methods
@ -118,7 +111,7 @@ nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID,
aAttribute == nsGkAtoms::y ||
aAttribute == nsGkAtoms::dx ||
aAttribute == nsGkAtoms::dy)) {
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
if (text_frame)
text_frame->NotifyGlyphMetricsChange(this);
}
@ -126,80 +119,9 @@ nsSVGTSpanFrame::AttributeChanged(PRInt32 aNameSpaceID,
return NS_OK;
}
//----------------------------------------------------------------------
// nsISVGTextContentMetrics
NS_IMETHODIMP
nsSVGTSpanFrame::GetNumberOfChars(PRInt32 *_retval)
{
*_retval = nsSVGUtils::GetNumberOfChars(&mFrames);
return NS_OK;
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetComputedTextLength(float *_retval)
{
*_retval = nsSVGUtils::GetComputedTextLength(&mFrames);
return NS_OK;
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval)
{
return nsSVGUtils::GetSubStringLength(&mFrames, charnum, nchars, _retval);
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
return nsSVGUtils::GetStartPositionOfChar(&mFrames, charnum, _retval);
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
return nsSVGUtils::GetEndPositionOfChar(&mFrames, charnum, _retval);
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
{
return nsSVGUtils::GetExtentOfChar(&mFrames, charnum, _retval);
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
{
return nsSVGUtils::GetRotationOfChar(&mFrames, charnum, _retval);
}
NS_IMETHODIMP
nsSVGTSpanFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval)
{
*_retval = nsSVGUtils::GetCharNumAtPosition(&mFrames, point);
return NS_OK;
}
//----------------------------------------------------------------------
// nsISVGChildFrame methods
NS_IMETHODIMP
nsSVGTSpanFrame::PaintSVG(nsISVGRendererCanvas* canvas)
{
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsISVGChildFrame* SVGFrame = nsnull;
CallQueryInterface(kid, &SVGFrame);
if (SVGFrame)
SVGFrame->PaintSVG(canvas);
}
return NS_OK;
}
NS_IMETHODIMP
nsSVGTSpanFrame::SetMatrixPropagation(PRBool aPropagate)
{
@ -237,72 +159,31 @@ nsSVGTSpanFrame::GetCanvasTM()
return containerFrame->GetCanvasTM();
}
//----------------------------------------------------------------------
// nsISVGTextContainerFrame methods:
NS_IMETHODIMP_(nsISVGTextFrame *)
nsSVGTSpanFrame::GetTextFrame()
{
NS_ASSERTION(mParent, "null parent");
nsISVGTextContainerFrame *containerFrame;
mParent->QueryInterface(NS_GET_IID(nsISVGTextContainerFrame), (void**)&containerFrame);
if (!containerFrame) {
return nsnull;
}
return containerFrame->GetTextFrame();
}
NS_IMETHODIMP_(PRBool)
nsSVGTSpanFrame::GetAbsolutePositionAdjustmentX(float &x, PRUint32 charNum)
{
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSVGTSpanFrame::GetAbsolutePositionAdjustmentY(float &y, PRUint32 charNum)
{
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSVGTSpanFrame::GetRelativePositionAdjustmentX(float &dx, PRUint32 charNum)
{
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSVGTSpanFrame::GetRelativePositionAdjustmentY(float &dy, PRUint32 charNum)
{
return PR_FALSE;
}
//----------------------------------------------------------------------
// nsISVGGlyphFragmentNode methods:
NS_IMETHODIMP_(PRUint32)
nsSVGTSpanFrame::GetNumberOfChars()
{
return nsSVGUtils::GetNumberOfChars(&mFrames);
return nsSVGTSpanFrameBase::GetNumberOfChars();
}
NS_IMETHODIMP_(float)
nsSVGTSpanFrame::GetComputedTextLength()
{
return nsSVGUtils::GetComputedTextLength(&mFrames);
return nsSVGTSpanFrameBase::GetComputedTextLength();
}
NS_IMETHODIMP_(float)
nsSVGTSpanFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars)
{
return nsSVGUtils::GetSubStringLengthNoValidation(&mFrames, charnum, nchars);
return nsSVGTSpanFrameBase::GetSubStringLengthNoValidation(charnum, nchars);
}
NS_IMETHODIMP_(PRInt32)
nsSVGTSpanFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point)
{
return nsSVGUtils::GetCharNumAtPosition(&mFrames, point);
return nsSVGTSpanFrameBase::GetCharNumAtPosition(point);
}
NS_IMETHODIMP_(nsISVGGlyphFragmentLeaf *)
@ -312,7 +193,7 @@ nsSVGTSpanFrame::GetFirstGlyphFragment()
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
kid->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode),(void**)&node);
CallQueryInterface(kid, &node);
if (node)
return node->GetFirstGlyphFragment();
kid = kid->GetNextSibling();
@ -329,7 +210,7 @@ nsSVGTSpanFrame::GetNextGlyphFragment()
nsIFrame* sibling = mNextSibling;
while (sibling) {
nsISVGGlyphFragmentNode *node = nsnull;
sibling->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode), (void**)&node);
CallQueryInterface(sibling, &node);
if (node)
return node->GetFirstGlyphFragment();
sibling = sibling->GetNextSibling();
@ -339,14 +220,14 @@ nsSVGTSpanFrame::GetNextGlyphFragment()
NS_ASSERTION(mParent, "null parent");
nsISVGGlyphFragmentNode *node = nsnull;
mParent->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode), (void**)&node);
CallQueryInterface(mParent, &node);
return node ? node->GetNextGlyphFragment() : nsnull;
}
NS_IMETHODIMP_(PRUint32)
nsSVGTSpanFrame::BuildGlyphFragmentTree(PRUint32 charNum, PRBool lastBranch)
{
return nsSVGUtils::BuildGlyphFragmentTree(&mFrames, charNum, lastBranch);
return nsSVGTSpanFrameBase::BuildGlyphFragmentTree(charNum, lastBranch);
}
NS_IMETHODIMP_(void)
@ -355,7 +236,7 @@ nsSVGTSpanFrame::NotifyMetricsSuspended()
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
kid->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode), (void**)&node);
CallQueryInterface(kid, &node);
if (node)
node->NotifyMetricsSuspended();
kid = kid->GetNextSibling();
@ -368,7 +249,7 @@ nsSVGTSpanFrame::NotifyMetricsUnsuspended()
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
kid->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode), (void**)&node);
CallQueryInterface(kid, &node);
if (node)
node->NotifyMetricsUnsuspended();
kid = kid->GetNextSibling();
@ -381,7 +262,7 @@ nsSVGTSpanFrame::NotifyGlyphFragmentTreeSuspended()
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
kid->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode), (void**)&node);
CallQueryInterface(kid, &node);
if (node)
node->NotifyGlyphFragmentTreeSuspended();
kid = kid->GetNextSibling();
@ -392,7 +273,7 @@ NS_IMETHODIMP_(void)
nsSVGTSpanFrame::NotifyGlyphFragmentTreeUnsuspended()
{
if (mFragmentTreeDirty) {
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
NS_ASSERTION(text_frame, "null text frame");
if (text_frame)
text_frame->NotifyGlyphFragmentTreeChange(this);
@ -402,75 +283,9 @@ nsSVGTSpanFrame::NotifyGlyphFragmentTreeUnsuspended()
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
nsISVGGlyphFragmentNode *node = nsnull;
kid->QueryInterface(NS_GET_IID(nsISVGGlyphFragmentNode), (void**)&node);
CallQueryInterface(kid, &node);
if (node)
node->NotifyGlyphFragmentTreeUnsuspended();
kid = kid->GetNextSibling();
}
}
//----------------------------------------------------------------------
//
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTSpanFrame::GetX()
{
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
if (!tpElement)
return nsnull;
if (!mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::x))
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetX(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTSpanFrame::GetY()
{
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
if (!tpElement)
return nsnull;
if (!mContent->HasAttr(kNameSpaceID_None, nsSVGAtoms::y))
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetY(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTSpanFrame::GetDx()
{
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
if (!tpElement)
return nsnull;
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);
if (!tpElement)
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetDy(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}

Просмотреть файл

@ -39,50 +39,30 @@
#ifndef NSSVGTSPANFRAME_H
#define NSSVGTSPANFRAME_H
#include "nsIDOMSVGTSpanElement.h"
#include "nsPresContext.h"
#include "nsISVGTextContainerFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsISVGValue.h"
#include "nsIDOMSVGSVGElement.h"
#include "nsIDOMSVGMatrix.h"
#include "nsIDOMSVGLengthList.h"
#include "nsIDOMSVGLength.h"
#include "nsISVGValueUtils.h"
#include "nsIDOMSVGAnimatedLengthList.h"
#include "nsSVGContainerFrame.h"
#include "nsISVGChildFrame.h"
#include "nsISVGTextFrame.h"
#include "nsSVGTextContainerFrame.h"
#include "nsISVGGlyphFragmentNode.h"
#include "nsIDOMSVGRect.h"
#include "nsISVGTextContentMetrics.h"
#include "nsSVGRect.h"
#include "nsSVGMatrix.h"
#include "nsINameSpaceManager.h"
#include "nsSVGAtoms.h"
#include "nsLayoutAtoms.h"
typedef nsSVGDisplayContainerFrame nsSVGTSpanFrameBase;
typedef nsSVGTextContainerFrame nsSVGTSpanFrameBase;
class nsSVGTSpanFrame : public nsSVGTSpanFrameBase,
public nsISVGTextContainerFrame,
public nsISVGGlyphFragmentNode,
public nsISVGTextContentMetrics
public nsISVGGlyphFragmentNode
{
friend nsIFrame*
NS_NewSVGTSpanFrame(nsIPresShell* aPresShell, nsIContent* aContent,
nsIFrame* parentFrame, nsStyleContext* aContext);
protected:
nsSVGTSpanFrame(nsStyleContext* aContext);
nsSVGTSpanFrame(nsStyleContext* aContext) :
nsSVGTextContainerFrame(aContext),
mFragmentTreeDirty(PR_FALSE), mPropagateTransform(PR_TRUE) {}
// nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public:
// nsIFrame:
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
@ -102,39 +82,13 @@ public:
return MakeFrameName(NS_LITERAL_STRING("SVGTSpan"), aResult);
}
#endif
// nsISVGTextContentMetrics
NS_IMETHOD GetNumberOfChars(PRInt32 *_retval);
NS_IMETHOD GetComputedTextLength(float *_retval);
NS_IMETHOD GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval);
NS_IMETHOD GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval);
NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval);
NS_IMETHOD GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval);
// nsISupportsWeakReference
// implementation inherited from nsSupportsWeakReference
// nsISVGChildFrame interface:
NS_IMETHOD PaintSVG(nsISVGRendererCanvas* canvas);
NS_IMETHOD SetMatrixPropagation(PRBool aPropagate);
NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM);
// nsSVGContainerFrame methods:
virtual already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM();
// nsISVGTextContainerFrame interface:
NS_IMETHOD_(nsISVGTextFrame *) GetTextFrame();
NS_IMETHOD_(PRBool) GetAbsolutePositionAdjustmentX(float &x, PRUint32 charNum);
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_(PRUint32) GetNumberOfChars();
NS_IMETHOD_(float) GetComputedTextLength();

Просмотреть файл

@ -0,0 +1,451 @@
/* -*- 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) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#include "nsSVGContainerFrame.h"
#include "nsSVGTextFrame.h"
#include "nsSVGUtils.h"
#include "nsSVGMatrix.h"
#include "nsSVGOuterSVGFrame.h"
#include "nsIDOMSVGTextElement.h"
#include "nsIDOMSVGAnimatedLengthList.h"
#include "nsISVGRendererGlyphMetrics.h"
#include "nsISVGGlyphFragmentLeaf.h"
#include "nsDOMError.h"
//----------------------------------------------------------------------
// nsISupports methods
NS_INTERFACE_MAP_BEGIN(nsSVGTextContainerFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGTextContentMetrics)
NS_INTERFACE_MAP_END_INHERITING(nsSVGDisplayContainerFrame)
NS_IMETHODIMP_(nsSVGTextFrame *)
nsSVGTextContainerFrame::GetTextFrame()
{
for (nsIFrame *frame = this; frame != nsnull; frame = frame->GetParent()) {
if (frame->GetType() == nsLayoutAtoms::svgTextFrame) {
return NS_STATIC_CAST(nsSVGTextFrame*, frame);
}
}
return nsnull;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTextContainerFrame::GetX()
{
nsIDOMSVGTextPositioningElement *tpElement = nsnull;
CallQueryInterface(mContent, &tpElement);
if (!tpElement)
return nsnull;
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::x))
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetX(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTextContainerFrame::GetY()
{
nsIDOMSVGTextPositioningElement *tpElement = nsnull;
CallQueryInterface(mContent, &tpElement);
if (!tpElement)
return nsnull;
if (!mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::y))
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetY(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTextContainerFrame::GetDx()
{
nsIDOMSVGTextPositioningElement *tpElement = nsnull;
CallQueryInterface(mContent, &tpElement);
if (!tpElement)
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetDx(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTextContainerFrame::GetDy()
{
nsIDOMSVGTextPositioningElement *tpElement = nsnull;
CallQueryInterface(mContent, &tpElement);
if (!tpElement)
return nsnull;
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetDy(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
//----------------------------------------------------------------------
// nsISVGTextContentMetrics methods
NS_IMETHODIMP
nsSVGTextContainerFrame::GetNumberOfChars(PRInt32 *_retval)
{
*_retval = GetNumberOfChars();
return NS_OK;
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetComputedTextLength(float *_retval)
{
*_retval = GetComputedTextLength();
return NS_OK;
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetSubStringLength(PRUint32 charnum,
PRUint32 nchars,
float *_retval)
{
if (nchars == 0) {
*_retval = 0.0f;
return NS_OK;
}
if (charnum + nchars > GetNumberOfChars()) {
*_retval = 0.0f;
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
*_retval = GetSubStringLengthNoValidation(charnum, nchars);
return NS_OK;
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
*_retval = nsnull;
if (charnum >= GetNumberOfChars()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the start position of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetStartPositionOfChar(charnum - offset, _retval);
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
*_retval = nsnull;
if (charnum >= GetNumberOfChars()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the end position of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetEndPositionOfChar(charnum - offset, _retval);
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
{
*_retval = nsnull;
if (charnum >= GetNumberOfChars()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the bounds of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetExtentOfChar(charnum - offset, _retval);
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
{
*_retval = 0.0f;
if (charnum >= GetNumberOfChars()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the rotation of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetRotationOfChar(charnum - offset, _retval);
}
NS_IMETHODIMP
nsSVGTextContainerFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval)
{
*_retval = GetCharNumAtPosition(point);
return NS_OK;
}
// -------------------------------------------------------------------------
// Protected functions
// -------------------------------------------------------------------------
nsISVGGlyphFragmentNode *
nsSVGTextContainerFrame::GetFirstGlyphFragmentChildNode()
{
nsISVGGlyphFragmentNode *retval = nsnull;
nsIFrame* kid = mFrames.FirstChild();
while (kid) {
CallQueryInterface(kid, &retval);
if (retval) break;
kid = kid->GetNextSibling();
}
return retval;
}
nsISVGGlyphFragmentNode *
nsSVGTextContainerFrame::GetNextGlyphFragmentChildNode(nsISVGGlyphFragmentNode *node)
{
nsISVGGlyphFragmentNode *retval = nsnull;
nsIFrame *frame = nsnull;
CallQueryInterface(node, &frame);
NS_ASSERTION(frame, "interface not implemented");
frame = frame->GetNextSibling();
while (frame) {
CallQueryInterface(frame, &retval);
if (retval) break;
frame = frame->GetNextSibling();
}
return retval;
}
PRUint32
nsSVGTextContainerFrame::BuildGlyphFragmentTree(PRUint32 charNum,
PRBool lastBranch)
{
// init children:
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
nsISVGGlyphFragmentNode* next;
while (node) {
next = GetNextGlyphFragmentChildNode(node);
charNum = node->BuildGlyphFragmentTree(charNum, lastBranch && !next);
node = next;
}
return charNum;
}
PRUint32
nsSVGTextContainerFrame::GetNumberOfChars()
{
PRUint32 nchars = 0;
nsISVGGlyphFragmentNode* node;
node = GetFirstGlyphFragmentChildNode();
while (node) {
nchars += node->GetNumberOfChars();
node = GetNextGlyphFragmentChildNode(node);
}
return nchars;
}
float
nsSVGTextContainerFrame::GetComputedTextLength()
{
float length = 0.0f;
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
while (node) {
length += node->GetComputedTextLength();
node = GetNextGlyphFragmentChildNode(node);
}
return length;
}
float
nsSVGTextContainerFrame::GetSubStringLengthNoValidation(PRUint32 charnum,
PRUint32 nchars)
{
float length = 0.0f;
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
while (node) {
PRUint32 count = node->GetNumberOfChars();
if (count > charnum) {
PRUint32 fragmentChars = PR_MIN(nchars, count);
float fragmentLength = node->GetSubStringLength(charnum, fragmentChars);
length += fragmentLength;
nchars -= fragmentChars;
if (nchars == 0) break;
}
charnum -= PR_MIN(charnum, count);
node = GetNextGlyphFragmentChildNode(node);
}
return length;
}
PRInt32
nsSVGTextContainerFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point)
{
PRInt32 index = -1;
PRInt32 offset = 0;
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode();
while (node) {
PRUint32 count = node->GetNumberOfChars();
if (count > 0) {
PRInt32 charnum = node->GetCharNumAtPosition(point);
if (charnum >= 0) {
index = charnum + offset;
}
offset += count;
// Keep going, multiple characters may match
// and we must return the last one
}
node = GetNextGlyphFragmentChildNode(node);
}
return index;
}
// -------------------------------------------------------------------------
// Private functions
// -------------------------------------------------------------------------
nsISVGGlyphFragmentLeaf *
nsSVGTextContainerFrame::GetGlyphFragmentAtCharNum(nsISVGGlyphFragmentNode* node,
PRUint32 charnum,
PRUint32 *offset)
{
nsISVGGlyphFragmentLeaf *fragment = node->GetFirstGlyphFragment();
*offset = 0;
while (fragment) {
PRUint32 count = fragment->GetNumberOfChars();
if (count > charnum)
return fragment;
charnum -= count;
*offset += count;
fragment = fragment->GetNextGlyphFragment();
}
// not found
return nsnull;
}

Просмотреть файл

@ -0,0 +1,129 @@
/* -*- 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) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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_SVGTEXTCONTAINERFRAME_H
#define NS_SVGTEXTCONTAINERFRAME_H
#include "nsSVGContainerFrame.h"
#include "nsIDOMSVGLengthList.h"
#include "nsISVGTextContentMetrics.h"
class nsISVGGlyphFragmentNode;
class nsISVGGlyphFragmentLeaf;
class nsSVGTextFrame;
class nsSVGTextContainerFrame : public nsSVGDisplayContainerFrame,
public nsISVGTextContentMetrics
{
public:
nsSVGTextContainerFrame(nsStyleContext* aContext) :
nsSVGDisplayContainerFrame(aContext) {}
NS_IMETHOD_(nsSVGTextFrame *) GetTextFrame();
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetX();
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetY();
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDx();
NS_IMETHOD_(already_AddRefed<nsIDOMSVGLengthList>) GetDy();
// nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public:
// nsISVGTextContentMetrics
NS_IMETHOD GetNumberOfChars(PRInt32 *_retval);
NS_IMETHOD GetComputedTextLength(float *_retval);
NS_IMETHOD GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval);
NS_IMETHOD GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval);
NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval);
NS_IMETHOD GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval);
protected:
/*
* Returns the first child node for a frame
*/
nsISVGGlyphFragmentNode *
GetFirstGlyphFragmentChildNode();
/*
* Returns the next child node for a frame
*/
nsISVGGlyphFragmentNode *
GetNextGlyphFragmentChildNode(nsISVGGlyphFragmentNode *node);
/*
* Build the glyph fragment tree
*/
PRUint32
BuildGlyphFragmentTree(PRUint32 charNum, PRBool lastBranch);
/*
* Returns the number of characters in a string
*/
PRUint32 GetNumberOfChars();
/*
* Determines the length of a string
*/
float GetComputedTextLength();
/*
* Determines the length of a substring
*/
float GetSubStringLengthNoValidation(PRUint32 charnum, PRUint32 nchars);
/*
* Get the character at the specified position
*/
PRInt32 GetCharNumAtPosition(nsIDOMSVGPoint *point);
private:
/*
* Returns the glyph fragment containing a particular character
*/
static nsISVGGlyphFragmentLeaf *
GetGlyphFragmentAtCharNum(nsISVGGlyphFragmentNode* node,
PRUint32 charnum,
PRUint32 *offset);
};
#endif

Просмотреть файл

@ -37,20 +37,10 @@
* ***** END LICENSE BLOCK ***** */
#include "nsIDOMSVGTextElement.h"
#include "nsPresContext.h"
#include "nsISVGTextFrame.h"
#include "nsISVGRendererCanvas.h"
#include "nsSVGTextFrame.h"
#include "nsWeakReference.h"
#include "nsISVGValue.h"
#include "nsISVGValueObserver.h"
#include "nsIDOMSVGSVGElement.h"
#include "nsIDOMSVGMatrix.h"
#include "nsIDOMSVGLengthList.h"
#include "nsIDOMSVGLength.h"
#include "nsISVGValueUtils.h"
#include "nsIDOMSVGAnimatedLengthList.h"
#include "nsSVGContainerFrame.h"
#include "nsISVGChildFrame.h"
#include "nsISVGGlyphFragmentNode.h"
#include "nsISVGGlyphFragmentLeaf.h"
#include "nsISVGRendererGlyphMetrics.h"
@ -63,125 +53,8 @@
#include "nsSVGTextPathFrame.h"
#include "nsSVGPathElement.h"
#include "nsSVGUtils.h"
#include "nsSVGUtils.h"
#include "nsSVGClipPathFrame.h"
#include "nsISVGRendererSurface.h"
#include "nsINameSpaceManager.h"
#include "nsGkAtoms.h"
#include "nsSVGGraphicElement.h"
typedef nsSVGDisplayContainerFrame nsSVGTextFrameBase;
class nsSVGTextFrame : public nsSVGTextFrameBase,
public nsISVGTextFrame, // : nsISVGTextContainerFrame
public nsISVGValueObserver,
public nsISVGTextContentMetrics,
public nsSupportsWeakReference
{
friend nsIFrame*
NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
protected:
nsSVGTextFrame(nsStyleContext* aContext);
// nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public:
// nsIFrame:
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType);
NS_IMETHOD DidSetStyleContext();
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::svgTextFrame
*/
virtual nsIAtom* GetType() const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("SVGText"), aResult);
}
#endif
// nsISVGValueObserver
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType);
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
nsISVGValue::modificationType aModType);
// nsISVGTextContentMetrics
NS_IMETHOD GetNumberOfChars(PRInt32 *_retval);
NS_IMETHOD GetComputedTextLength(float *_retval);
NS_IMETHOD GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval);
NS_IMETHOD GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval);
NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval);
NS_IMETHOD GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval);
// nsISupportsWeakReference
// implementation inherited from nsSupportsWeakReference
// nsISVGChildFrame interface:
NS_IMETHOD PaintSVG(nsISVGRendererCanvas* canvas);
NS_IMETHOD NotifyCanvasTMChanged(PRBool suppressInvalidation);
NS_IMETHOD NotifyRedrawSuspended();
NS_IMETHOD NotifyRedrawUnsuspended();
NS_IMETHOD SetMatrixPropagation(PRBool aPropagate);
NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM);
NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval);
// nsSVGContainerFrame methods:
virtual already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM();
// nsISVGTextFrame interface:
NS_IMETHOD_(void) NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller);
NS_IMETHOD_(void) NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller);
NS_IMETHOD_(PRBool) IsMetricsSuspended();
NS_IMETHOD_(PRBool) IsGlyphFragmentTreeSuspended();
// nsISVGTextContainerFrame interface:
NS_IMETHOD_(nsISVGTextFrame *) GetTextFrame();
NS_IMETHOD_(PRBool) GetAbsolutePositionAdjustmentX(float &x, PRUint32 charNum);
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();
enum UpdateState{
unsuspended,
suspended,
updating};
UpdateState mFragmentTreeState;
UpdateState mMetricsState;
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM;
PRPackedBool mFragmentTreeDirty;
PRPackedBool mPositioningDirty;
PRPackedBool mPropagateTransform;
};
//----------------------------------------------------------------------
// Implementation
@ -203,8 +76,8 @@ NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContex
nsSVGTextFrame::nsSVGTextFrame(nsStyleContext* aContext)
: nsSVGTextFrameBase(aContext),
mFragmentTreeState(suspended), mMetricsState(suspended),
mFragmentTreeDirty(PR_FALSE), mPositioningDirty(PR_FALSE),
mPropagateTransform(PR_TRUE)
mFragmentTreeDirty(PR_FALSE), mPropagateTransform(PR_TRUE),
mPositioningDirty(PR_FALSE)
{
}
@ -212,11 +85,8 @@ nsSVGTextFrame::nsSVGTextFrame(nsStyleContext* aContext)
// nsISupports methods
NS_INTERFACE_MAP_BEGIN(nsSVGTextFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGTextFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGTextContainerFrame)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_INTERFACE_MAP_ENTRY(nsISVGTextContentMetrics)
NS_INTERFACE_MAP_END_INHERITING(nsSVGTextFrameBase)
@ -321,9 +191,7 @@ nsSVGTextFrame::GetNumberOfChars(PRInt32 *_retval)
{
EnsureFragmentTreeUpToDate();
*_retval = nsSVGUtils::GetNumberOfChars(&mFrames);
return NS_OK;
return nsSVGTextFrameBase::GetNumberOfChars(_retval);
}
NS_IMETHODIMP
@ -331,9 +199,7 @@ nsSVGTextFrame::GetComputedTextLength(float *_retval)
{
EnsureFragmentTreeUpToDate();
*_retval = nsSVGUtils::GetComputedTextLength(&mFrames);
return NS_OK;
return nsSVGTextFrameBase::GetComputedTextLength(_retval);
}
NS_IMETHODIMP
@ -341,7 +207,7 @@ nsSVGTextFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_re
{
EnsureFragmentTreeUpToDate();
return nsSVGUtils::GetSubStringLength(&mFrames, charnum, nchars, _retval);
return nsSVGTextFrameBase::GetSubStringLength(charnum, nchars, _retval);
}
NS_IMETHODIMP
@ -349,7 +215,7 @@ nsSVGTextFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retva
{
EnsureFragmentTreeUpToDate();
return nsSVGUtils::GetStartPositionOfChar(&mFrames, charnum, _retval);
return nsSVGTextFrameBase::GetStartPositionOfChar(charnum, _retval);
}
NS_IMETHODIMP
@ -357,7 +223,7 @@ nsSVGTextFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
EnsureFragmentTreeUpToDate();
return nsSVGUtils::GetEndPositionOfChar(&mFrames, charnum, _retval);
return nsSVGTextFrameBase::GetEndPositionOfChar(charnum, _retval);
}
NS_IMETHODIMP
@ -365,7 +231,7 @@ nsSVGTextFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
{
EnsureFragmentTreeUpToDate();
return nsSVGUtils::GetExtentOfChar(&mFrames, charnum, _retval);
return nsSVGTextFrameBase::GetExtentOfChar(charnum, _retval);
}
NS_IMETHODIMP
@ -373,7 +239,7 @@ nsSVGTextFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
{
EnsureFragmentTreeUpToDate();
return nsSVGUtils::GetRotationOfChar(&mFrames, charnum, _retval);
return nsSVGTextFrameBase::GetRotationOfChar(charnum, _retval);
}
NS_IMETHODIMP
@ -381,33 +247,13 @@ nsSVGTextFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval)
{
EnsureFragmentTreeUpToDate();
*_retval = nsSVGUtils::GetCharNumAtPosition(&mFrames, point);
return NS_OK;
return nsSVGTextFrameBase::GetCharNumAtPosition(point, _retval);
}
//----------------------------------------------------------------------
// nsISVGChildFrame methods
NS_IMETHODIMP
nsSVGTextFrame::PaintSVG(nsISVGRendererCanvas* canvas)
{
const nsStyleDisplay *display = mStyleContext->GetStyleDisplay();
if (display->mOpacity == 0.0)
return NS_OK;
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsISVGChildFrame* SVGFrame = nsnull;
CallQueryInterface(kid, &SVGFrame);
if (SVGFrame)
SVGFrame->PaintSVG(canvas);
}
return NS_OK;
}
NS_IMETHODIMP
nsSVGTextFrame::NotifyCanvasTMChanged(PRBool suppressInvalidation)
{
@ -495,6 +341,7 @@ NS_IMETHODIMP
nsSVGTextFrame::GetBBox(nsIDOMSVGRect **_retval)
{
EnsureFragmentTreeUpToDate();
return nsSVGTextFrameBase::GetBBox(_retval);
}
@ -540,9 +387,9 @@ nsSVGTextFrame::GetCanvasTM()
}
//----------------------------------------------------------------------
// nsISVGTextFrame methods
//
NS_IMETHODIMP_(void)
void
nsSVGTextFrame::NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller)
{
NS_ASSERTION(mMetricsState!=suspended, "notification during suspension");
@ -552,7 +399,7 @@ nsSVGTextFrame::NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller)
}
}
NS_IMETHODIMP_(void)
void
nsSVGTextFrame::NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller)
{
NS_ASSERTION(mFragmentTreeState!=suspended, "notification during suspension");
@ -562,54 +409,18 @@ nsSVGTextFrame::NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller)
}
}
NS_IMETHODIMP_(PRBool)
PRBool
nsSVGTextFrame::IsMetricsSuspended()
{
return (mMetricsState != unsuspended);
}
NS_IMETHODIMP_(PRBool)
PRBool
nsSVGTextFrame::IsGlyphFragmentTreeSuspended()
{
return (mFragmentTreeState != unsuspended);
}
//----------------------------------------------------------------------
// nsISVGTextContainerFrame methods:
NS_IMETHODIMP_(nsISVGTextFrame *)
nsSVGTextFrame::GetTextFrame()
{
return this;
}
NS_IMETHODIMP_(PRBool)
nsSVGTextFrame::GetAbsolutePositionAdjustmentX(float &x, PRUint32 charNum)
{
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSVGTextFrame::GetAbsolutePositionAdjustmentY(float &y, PRUint32 charNum)
{
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSVGTextFrame::GetRelativePositionAdjustmentX(float &dx, PRUint32 charNum)
{
return PR_FALSE;
}
NS_IMETHODIMP_(PRBool)
nsSVGTextFrame::GetRelativePositionAdjustmentY(float &dy, PRUint32 charNum)
{
return PR_FALSE;
}
//----------------------------------------------------------------------
//
// ensure that the tree and positioning of the nodes is up-to-date
void
nsSVGTextFrame::EnsureFragmentTreeUpToDate()
@ -677,7 +488,7 @@ nsSVGTextFrame::UpdateFragmentTree()
{
NS_ASSERTION(mFragmentTreeState == unsuspended, "updating during suspension!");
nsSVGUtils::BuildGlyphFragmentTree(&mFrames, 0, PR_TRUE);
BuildGlyphFragmentTree(0, PR_TRUE);
mFragmentTreeDirty = PR_FALSE;
@ -739,8 +550,7 @@ nsSVGTextFrame::UpdateGlyphPositioning()
{
NS_ASSERTION(mMetricsState == unsuspended, "updating during suspension");
nsISVGGlyphFragmentNode* node;
node = nsSVGUtils::GetFirstGlyphFragmentChildNode(&mFrames);
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode();
if (!node) return;
// we'll align every fragment in this chunk on the dominant-baseline:
@ -867,56 +677,3 @@ nsSVGTextFrame::UpdateGlyphPositioning()
mPositioningDirty = PR_FALSE;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTextFrame::GetX()
{
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
NS_ASSERTION(tpElement, "wrong content element");
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetX(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
return retval;
}
NS_IMETHODIMP_(already_AddRefed<nsIDOMSVGLengthList>)
nsSVGTextFrame::GetY()
{
nsCOMPtr<nsIDOMSVGTextPositioningElement> tpElement = do_QueryInterface(mContent);
NS_ASSERTION(tpElement, "wrong content element");
nsCOMPtr<nsIDOMSVGAnimatedLengthList> animLengthList;
tpElement->GetY(getter_AddRefs(animLengthList));
nsIDOMSVGLengthList *retval;
animLengthList->GetAnimVal(&retval);
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;
}

Просмотреть файл

@ -0,0 +1,143 @@
/* -*- 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
* Crocodile Clips Ltd..
* Portions created by the Initial Developer are Copyright (C) 2002
* 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_SVGTEXTFRAME_H
#define NS_SVGTEXTFRAME_H
#include "nsSVGTextContainerFrame.h"
#include "nsISVGValueObserver.h"
#include "nsWeakReference.h"
typedef nsSVGTextContainerFrame nsSVGTextFrameBase;
class nsSVGTextFrame : public nsSVGTextFrameBase,
public nsISVGValueObserver,
public nsSupportsWeakReference
{
friend nsIFrame*
NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContext* aContext);
protected:
nsSVGTextFrame(nsStyleContext* aContext);
// nsISupports interface:
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
private:
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
public:
// nsIFrame:
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType);
NS_IMETHOD DidSetStyleContext();
/**
* Get the "type" of the frame
*
* @see nsLayoutAtoms::svgTextFrame
*/
virtual nsIAtom* GetType() const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const
{
return MakeFrameName(NS_LITERAL_STRING("SVGText"), aResult);
}
#endif
// nsISVGValueObserver
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType);
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
nsISVGValue::modificationType aModType);
// nsISupportsWeakReference
// implementation inherited from nsSupportsWeakReference
// nsISVGChildFrame interface:
NS_IMETHOD SetMatrixPropagation(PRBool aPropagate);
NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM);
NS_IMETHOD NotifyCanvasTMChanged(PRBool suppressInvalidation);
NS_IMETHOD NotifyRedrawSuspended();
NS_IMETHOD NotifyRedrawUnsuspended();
NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval);
// nsSVGContainerFrame methods:
virtual already_AddRefed<nsIDOMSVGMatrix> GetCanvasTM();
// nsISVGTextContentMetrics
NS_IMETHOD GetNumberOfChars(PRInt32 *_retval);
NS_IMETHOD GetComputedTextLength(float *_retval);
NS_IMETHOD GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval);
NS_IMETHOD GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval);
NS_IMETHOD GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval);
NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval);
NS_IMETHOD GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval);
void NotifyGlyphMetricsChange(nsISVGGlyphFragmentNode* caller);
void NotifyGlyphFragmentTreeChange(nsISVGGlyphFragmentNode* caller);
PRBool IsMetricsSuspended();
PRBool IsGlyphFragmentTreeSuspended();
private:
void EnsureFragmentTreeUpToDate();
void UpdateFragmentTree();
void UpdateGlyphPositioning();
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM;
enum UpdateState{
unsuspended,
suspended,
updating};
UpdateState mFragmentTreeState;
UpdateState mMetricsState;
PRPackedBool mFragmentTreeDirty;
PRPackedBool mPropagateTransform;
PRPackedBool mPositioningDirty;
};
#endif

Просмотреть файл

@ -35,18 +35,22 @@
* ***** END LICENSE BLOCK ***** */
#include "nsSVGTextPathFrame.h"
#include "nsSVGTextFrame.h"
#include "nsIDOMSVGTextPathElement.h"
#include "nsIDOMSVGAnimatedLength.h"
#include "nsSVGLength.h"
#include "nsIDOMSVGURIReference.h"
#include "nsSVGUtils.h"
#include "nsContentUtils.h"
#include "nsIDOMSVGAnimatedPathData.h"
#include "nsSVGPathElement.h"
#include "nsISVGValueUtils.h"
#include "nsIDOMSVGPathSegList.h"
NS_INTERFACE_MAP_BEGIN(nsSVGTextPathFrame)
NS_INTERFACE_MAP_ENTRY(nsISVGValueObserver)
NS_INTERFACE_MAP_ENTRY(nsSupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(nsSVGTSpanFrame)
NS_INTERFACE_MAP_END_INHERITING(nsSVGTextPathFrameBase)
//----------------------------------------------------------------------
// Implementation
@ -56,9 +60,9 @@ NS_NewSVGTextPathFrame(nsIPresShell* aPresShell, nsIContent* aContent,
nsIFrame* parentFrame, nsStyleContext* aContext)
{
NS_ASSERTION(parentFrame, "null parent");
nsISVGTextFrame *text_container;
parentFrame->QueryInterface(NS_GET_IID(nsISVGTextFrame), (void**)&text_container);
if (!text_container) {
nsISVGTextContentMetrics *metrics;
CallQueryInterface(parentFrame, &metrics);
if (!metrics) {
NS_ERROR("trying to construct an SVGTextPathFrame for an invalid container");
return nsnull;
}
@ -75,7 +79,8 @@ NS_NewSVGTextPathFrame(nsIPresShell* aPresShell, nsIContent* aContent,
nsSVGTextPathFrame::~nsSVGTextPathFrame()
{
NS_REMOVE_SVGVALUE_OBSERVER(mSegments);
if (mSegments)
NS_REMOVE_SVGVALUE_OBSERVER(mSegments);
}
NS_IMETHODIMP
@ -210,7 +215,7 @@ NS_IMETHODIMP
nsSVGTextPathFrame::DidModifySVGObservable(nsISVGValue* observable,
nsISVGValue::modificationType aModType)
{
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
if (text_frame)
text_frame->NotifyGlyphMetricsChange(this);
@ -227,7 +232,7 @@ nsSVGTextPathFrame::AttributeChanged(PRInt32 aNameSpaceID,
{
if (aNameSpaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::startOffset) {
nsISVGTextFrame* text_frame = GetTextFrame();
nsSVGTextFrame* text_frame = GetTextFrame();
if (text_frame)
text_frame->NotifyGlyphMetricsChange(this);
} else if (aNameSpaceID == kNameSpaceID_XLink &&

Просмотреть файл

@ -238,280 +238,6 @@ nsSVGUtils::GetBBox(nsFrameList *aFrames, nsIDOMSVGRect **_retval)
return NS_ERROR_FAILURE;
}
nsISVGGlyphFragmentNode *
nsSVGUtils::GetFirstGlyphFragmentChildNode(nsFrameList *aFrames)
{
nsISVGGlyphFragmentNode *retval = nsnull;
nsIFrame* kid = aFrames->FirstChild();
while (kid) {
CallQueryInterface(kid, &retval);
if (retval) break;
kid = kid->GetNextSibling();
}
return retval;
}
nsISVGGlyphFragmentNode *
nsSVGUtils::GetNextGlyphFragmentChildNode(nsISVGGlyphFragmentNode *node)
{
nsISVGGlyphFragmentNode *retval = nsnull;
nsIFrame *frame = nsnull;
CallQueryInterface(node, &frame);
NS_ASSERTION(frame, "interface not implemented");
frame = frame->GetNextSibling();
while (frame) {
CallQueryInterface(frame, &retval);
if (retval) break;
frame = frame->GetNextSibling();
}
return retval;
}
PRUint32
nsSVGUtils::BuildGlyphFragmentTree(nsFrameList *aFrames,
PRUint32 charNum,
PRBool lastBranch)
{
// init children:
nsISVGGlyphFragmentNode* node = GetFirstGlyphFragmentChildNode(aFrames);
nsISVGGlyphFragmentNode* next;
while (node) {
next = GetNextGlyphFragmentChildNode(node);
charNum = node->BuildGlyphFragmentTree(charNum, lastBranch && !next);
node = next;
}
return charNum;
}
PRUint32
nsSVGUtils::GetNumberOfChars(nsFrameList *aFrames)
{
PRUint32 nchars = 0;
nsISVGGlyphFragmentNode* node;
node = GetFirstGlyphFragmentChildNode(aFrames);
while (node) {
nchars += node->GetNumberOfChars();
node = GetNextGlyphFragmentChildNode(node);
}
return nchars;
}
float
nsSVGUtils::GetComputedTextLength(nsFrameList *aFrames)
{
float length = 0.0f;
nsISVGGlyphFragmentNode* node;
node = GetFirstGlyphFragmentChildNode(aFrames);
while (node) {
length += node->GetComputedTextLength();
node = GetNextGlyphFragmentChildNode(node);
}
return length;
}
nsresult
nsSVGUtils::GetSubStringLength(nsFrameList *aFrames,
PRUint32 charnum,
PRUint32 nchars,
float *_retval)
{
if (nchars == 0) {
*_retval = 0.0f;
return NS_OK;
}
if (charnum + nchars > nsSVGUtils::GetNumberOfChars(aFrames)) {
*_retval = 0.0f;
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
*_retval = GetSubStringLengthNoValidation(aFrames, charnum, nchars);
return NS_OK;
}
float
nsSVGUtils::GetSubStringLengthNoValidation(nsFrameList *aFrames,
PRUint32 charnum,
PRUint32 nchars)
{
float length = 0.0f;
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode(aFrames);
while (node) {
PRUint32 count = node->GetNumberOfChars();
if (count > charnum) {
PRUint32 fragmentChars = PR_MIN(nchars, count);
float fragmentLength = node->GetSubStringLength(charnum, fragmentChars);
length += fragmentLength;
nchars -= fragmentChars;
if (nchars == 0) break;
}
charnum -= PR_MIN(charnum, count);
node = GetNextGlyphFragmentChildNode(node);
}
return length;
}
nsresult
nsSVGUtils::GetStartPositionOfChar(nsFrameList *aFrames,
PRUint32 charnum,
nsIDOMSVGPoint **_retval)
{
*_retval = nsnull;
if (charnum >= nsSVGUtils::GetNumberOfChars(aFrames)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode(aFrames);
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the start position of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetStartPositionOfChar(charnum - offset, _retval);
}
nsresult
nsSVGUtils::GetEndPositionOfChar(nsFrameList *aFrames,
PRUint32 charnum,
nsIDOMSVGPoint **_retval)
{
*_retval = nsnull;
if (charnum >= nsSVGUtils::GetNumberOfChars(aFrames)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode(aFrames);
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the end position of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetEndPositionOfChar(charnum - offset, _retval);
}
nsresult
nsSVGUtils::GetExtentOfChar(nsFrameList *aFrames,
PRUint32 charnum,
nsIDOMSVGRect **_retval)
{
*_retval = nsnull;
if (charnum >= nsSVGUtils::GetNumberOfChars(aFrames)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode(aFrames);
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the bounds of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetExtentOfChar(charnum - offset, _retval);
}
nsresult
nsSVGUtils::GetRotationOfChar(nsFrameList *aFrames,
PRUint32 charnum,
float *_retval)
{
*_retval = 0.0f;
if (charnum >= nsSVGUtils::GetNumberOfChars(aFrames)) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode(aFrames);
if (!node) {
return NS_ERROR_FAILURE;
}
PRUint32 offset;
nsISVGGlyphFragmentLeaf *fragment = GetGlyphFragmentAtCharNum(node, charnum, &offset);
if (!fragment) {
return NS_ERROR_FAILURE;
}
// query the renderer metrics for the rotation of the character
nsCOMPtr<nsISVGRendererGlyphMetrics> metrics;
fragment->GetGlyphMetrics(getter_AddRefs(metrics));
if (!metrics) {
return NS_ERROR_FAILURE;
}
return metrics->GetRotationOfChar(charnum - offset, _retval);
}
PRInt32
nsSVGUtils::GetCharNumAtPosition(nsFrameList *aFrames,
nsIDOMSVGPoint *point)
{
PRInt32 index = -1;
PRInt32 offset = 0;
nsISVGGlyphFragmentNode *node = GetFirstGlyphFragmentChildNode(aFrames);
while (node) {
PRUint32 count = node->GetNumberOfChars();
if (count > 0) {
PRInt32 charnum = node->GetCharNumAtPosition(point);
if (charnum >= 0) {
index = charnum + offset;
}
offset += count;
// Keep going, multiple characters may match
// and we must return the last one
}
node = GetNextGlyphFragmentChildNode(node);
}
return index;
}
nsRect
nsSVGUtils::FindFilterInvalidation(nsIFrame *aFrame)
{
@ -604,27 +330,6 @@ nsSVGUtils::GetSurface(nsSVGOuterSVGFrame *aOuterSVGFrame,
return NS_ERROR_FAILURE;
}
nsISVGGlyphFragmentLeaf *
nsSVGUtils::GetGlyphFragmentAtCharNum(nsISVGGlyphFragmentNode* node,
PRUint32 charnum,
PRUint32 *offset)
{
nsISVGGlyphFragmentLeaf *fragment = node->GetFirstGlyphFragment();
*offset = 0;
while (fragment) {
PRUint32 count = fragment->GetNumberOfChars();
if (count > charnum)
return fragment;
charnum -= count;
*offset += count;
fragment = fragment->GetNextGlyphFragment();
}
// not found
return nsnull;
}
float
nsSVGUtils::AngleBisect(float a1, float a2)
{

Просмотреть файл

@ -50,12 +50,9 @@ class nsPresContext;
class nsIContent;
class nsStyleCoord;
class nsIDOMSVGRect;
class nsIDOMSVGPoint;
class nsFrameList;
class nsIFrame;
struct nsStyleSVGPaint;
class nsISVGGlyphFragmentLeaf;
class nsISVGGlyphFragmentNode;
class nsIDOMSVGLength;
class nsIDOMSVGMatrix;
class nsIURI;
@ -126,85 +123,6 @@ public:
*/
static nsresult GetBBox(nsFrameList *aFrames, nsIDOMSVGRect **_retval);
/*
* Returns the first child node for a frame
*/
static nsISVGGlyphFragmentNode *
GetFirstGlyphFragmentChildNode(nsFrameList *aFrames);
/*
* Returns the next child node for a frame
*/
static nsISVGGlyphFragmentNode *
GetNextGlyphFragmentChildNode(nsISVGGlyphFragmentNode *node);
/*
* Build the glyph fragment tree
*/
static PRUint32
BuildGlyphFragmentTree(nsFrameList *aFrames,
PRUint32 charNum,
PRBool lastBranch);
/*
* Returns the number of characters in a string
*/
static PRUint32 GetNumberOfChars(nsFrameList *aFrames);
/*
* Determines the length of a string
*/
static float GetComputedTextLength(nsFrameList *aFrames);
/*
* Determines the length of a substring
*/
static nsresult GetSubStringLength(nsFrameList *aFrames,
PRUint32 charnum,
PRUint32 nchars,
float *_retval);
/*
* Determines the length of a substring
*/
static float GetSubStringLengthNoValidation(nsFrameList *aFrames,
PRUint32 charnum,
PRUint32 nchars);
/*
* Determines the start position of a character
*/
static nsresult GetStartPositionOfChar(nsFrameList *aFrames,
PRUint32 charnum,
nsIDOMSVGPoint **_retval);
/*
* Determines the end position of a character
*/
static nsresult GetEndPositionOfChar(nsFrameList *aFrames,
PRUint32 charnum,
nsIDOMSVGPoint **_retval);
/*
* Determines the bounds of a character
*/
static nsresult GetExtentOfChar(nsFrameList *aFrames,
PRUint32 charnum,
nsIDOMSVGRect **_retval);
/*
* Determines the rotation of a character
*/
static nsresult GetRotationOfChar(nsFrameList *aFrames,
PRUint32 charnum,
float *_retval);
/*
* Get the character at the specified position
*/
static PRInt32 GetCharNumAtPosition(nsFrameList *aFrames,
nsIDOMSVGPoint *point);
/*
* Figures out the worst case invalidation area for a frame, taking
* into account filters. Empty return if no filter in the hierarchy.
@ -324,14 +242,6 @@ public:
GetCairoComputationalSurface();
private:
/*
* Returns the glyph fragment containing a particular character
*/
static nsISVGGlyphFragmentLeaf *
GetGlyphFragmentAtCharNum(nsISVGGlyphFragmentNode* node,
PRUint32 charnum,
PRUint32 *offset);
/* Cairo computational (nil) surface */
static cairo_surface_t *mCairoComputationalSurface;
};