This commit is contained in:
roc+@cs.cmu.edu 2008-03-18 01:37:48 -07:00
Родитель c45ebddfaf
Коммит 07f6438f46
7 изменённых файлов: 590 добавлений и 637 удалений

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

@ -47,8 +47,6 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_getSubStringLength.xhtml \
getSubStringLength-helper.svg \
test_text.html \
text-helper.svg \
$(NULL)
libs:: $(_TEST_FILES)

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

@ -56,7 +56,6 @@ fails == style-property-not-on-script-element-01.svg pass.svg
== svg-in-foreignObject-02.xhtml svg-in-foreignObject-01-ref.xhtml # reuse -01-ref.xhtml
random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == text-font-weight-01.svg text-font-weight-01-ref.svg # bug 386713
== text-in-link-01.svg text-in-link-01-ref.svg
== text-scale-01.svg text-scale-01-ref.svg
== text-style-01a.svg text-style-01-ref.svg
== text-style-01b.svg text-style-01-ref.svg
== text-style-01c.svg text-style-01-ref.svg

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

@ -46,11 +46,9 @@ class nsIDOMSVGPoint;
class nsIDOMSVGRect;
class nsSVGTextPathFrame;
// {ec9a9965-3ff2-4bb5-b0e2-dd8830e9f41a}
// {2C466AED-CF7B-4479-A807-98151215A645}
#define NS_ISVGGLYPHFRAGMENTLEAF_IID \
{ 0xec9a9965, 0x3ff2, 0x4bb5, \
{ 0xb0, 0xe2, 0xdd, 0x88, 0x30, 0xe9, 0xf4, 0x1a } }
{ 0x2c466aed, 0xcf7b, 0x4479, { 0xa8, 0x7, 0x98, 0x15, 0x12, 0x15, 0xa6, 0x45 } }
class nsISVGGlyphFragmentLeaf : public nsISVGGlyphFragmentNode
{
@ -72,9 +70,8 @@ public:
enum { BASELINE_TEXT_BEFORE_EDGE = 6U };
enum { BASELINE_TEXT_AFTER_EDGE = 7U };
NS_IMETHOD_(float) GetBaselineOffset(PRUint16 baselineIdentifier,
PRBool aForceGlobalTransform)=0;
NS_IMETHOD_(float) GetAdvance(PRBool aForceGlobalTransform)=0;
NS_IMETHOD_(float) GetBaselineOffset(PRUint16 baselineIdentifier)=0;
NS_IMETHOD_(float) GetAdvance()=0;
NS_IMETHOD_(void) SetGlyphPosition(float x, float y)=0;
NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent()=0;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -44,11 +44,11 @@
#include "nsISVGChildFrame.h"
#include "gfxContext.h"
#include "gfxFont.h"
#include "gfxTextRunCache.h"
struct nsSVGCharacterPosition;
class nsSVGTextFrame;
class nsSVGGlyphFrame;
class CharacterIterator;
struct CharacterPosition;
typedef nsSVGGeometryFrame nsSVGGlyphFrameBase;
@ -61,14 +61,8 @@ class nsSVGGlyphFrame : public nsSVGGlyphFrameBase,
nsIFrame* parentFrame, nsStyleContext* aContext);
protected:
nsSVGGlyphFrame(nsStyleContext* aContext)
: nsSVGGlyphFrameBase(aContext),
mTextRun(nsnull),
mWhitespaceHandling(COMPRESS_WHITESPACE)
{}
~nsSVGGlyphFrame()
{
ClearTextRun();
}
: nsSVGGlyphFrameBase(aContext),
mWhitespaceHandling(COMPRESS_WHITESPACE) {}
public:
// nsISupports interface:
@ -113,13 +107,10 @@ public:
#endif
// nsISVGChildFrame interface:
// These four always use the global transform, even if NS_STATE_NONDISPLAY_CHILD
NS_IMETHOD PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect);
NS_IMETHOD GetFrameForPointSVG(float x, float y, nsIFrame** hit);
NS_IMETHOD UpdateCoveredRegion();
NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval);
NS_IMETHOD_(nsRect) GetCoveredRegion();
NS_IMETHOD UpdateCoveredRegion();
NS_IMETHOD InitialUpdate();
virtual void NotifySVGChanged(PRUint32 aFlags);
NS_IMETHOD NotifyRedrawSuspended();
@ -127,6 +118,7 @@ public:
NS_IMETHOD SetMatrixPropagation(PRBool aPropagate) { return NS_OK; }
NS_IMETHOD SetOverrideCTM(nsIDOMSVGMatrix *aCTM) { return NS_ERROR_FAILURE; }
virtual already_AddRefed<nsIDOMSVGMatrix> GetOverrideCTM() { return nsnull; }
NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval);
NS_IMETHOD_(PRBool) IsDisplayContainer() { return PR_FALSE; }
NS_IMETHOD_(PRBool) HasValidCoveredRect() { return PR_TRUE; }
@ -135,22 +127,12 @@ public:
virtual nsresult UpdateGraphic(PRBool suppressInvalidation = PR_FALSE);
// nsISVGGlyphFragmentLeaf interface:
// These do not use the global transform if NS_STATE_NONDISPLAY_CHILD
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);
/**
* @param aForceGlobalTransform controls whether to use the
* global transform even when NS_STATE_NONDISPLAY_CHILD
*/
NS_IMETHOD_(float) GetBaselineOffset(PRUint16 baselineIdentifier,
PRBool aForceGlobalTransform);
/**
* @param aForceGlobalTransform controls whether to use the
* global transform even when NS_STATE_NONDISPLAY_CHILD
*/
NS_IMETHOD_(float) GetAdvance(PRBool aForceGlobalTransform);
NS_IMETHOD_(float) GetBaselineOffset(PRUint16 baselineIdentifier);
NS_IMETHOD_(float) GetAdvance();
NS_IMETHOD_(void) SetGlyphPosition(float x, float y);
NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent();
@ -165,7 +147,6 @@ public:
NS_IMETHOD_(PRBool) IsAbsolutelyPositioned();
// nsISVGGlyphFragmentNode interface:
// These do not use the global transform if NS_STATE_NONDISPLAY_CHILD
NS_IMETHOD_(PRUint32) GetNumberOfChars();
NS_IMETHOD_(float) GetComputedTextLength();
NS_IMETHOD_(float) GetSubStringLength(PRUint32 charnum, PRUint32 fragmentChars);
@ -175,47 +156,66 @@ public:
NS_IMETHOD_(void) SetWhitespaceHandling(PRUint8 aWhitespaceHandling);
protected:
friend class CharacterIterator;
struct nsSVGCharacterPosition {
gfxPoint pos;
gfxFloat angle;
PRBool draw;
};
// Use a power of 2 here. It's not so important to match
// nsIDeviceContext::AppUnitsPerDevPixel, but since we do a lot of
// multiplying by 1/GetTextRunUnitsFactor, it's good for it to be a
// power of 2 to avoid accuracy loss.
static PRUint32 GetTextRunUnitsFactor() { return 64; }
/**
* @aParam aDrawScale font drawing must be scaled into user units
* by this factor
* @param aMetricsScale font metrics must be scaled into user units
* by this factor
* @param aForceGlobalTransform set to true if we should force use of
* the global transform; otherwise we won't use the global transform
* if we're a NONDISPLAY_CHILD
*/
PRBool EnsureTextRun(float *aDrawScale, float *aMetricsScale,
PRBool aForceGlobalTransform);
void ClearTextRun();
// VC6 does not allow the inner class to access protected members
// of the outer class
class nsSVGAutoGlyphHelperContext;
friend class nsSVGAutoGlyphHelperContext;
// A helper class to deal with gfxTextRuns and temporary thebes
// contexts.
class nsSVGAutoGlyphHelperContext
{
public:
nsSVGAutoGlyphHelperContext(nsSVGGlyphFrame *aSource,
const nsString &aText)
{
Init(aSource, aText);
}
nsSVGAutoGlyphHelperContext(nsSVGGlyphFrame *aSource,
const nsString &aText,
nsSVGCharacterPosition **cp);
gfxContext *GetContext() { return mCT; }
gfxTextRun *GetTextRun() { return mTextRun.get(); }
private:
void Init(nsSVGGlyphFrame *aSource, const nsString &aText);
nsRefPtr<gfxContext> mCT;
gfxTextRunCache::AutoTextRun mTextRun;
};
// The textrun must be released via gfxTextRunCache::AutoTextRun
gfxTextRun *GetTextRun(gfxContext *aCtx,
const nsString &aText);
PRBool GetCharacterData(nsAString & aCharacterData);
PRBool GetCharacterPositions(nsTArray<CharacterPosition>* aCharacterPositions,
float aMetricsScale);
nsresult GetCharacterPosition(gfxContext *aContext,
const nsString &aText,
nsSVGCharacterPosition **aCharacterPosition);
void AddCharactersToPath(CharacterIterator *aIter,
gfxContext *aContext);
void AddBoundingBoxesToPath(CharacterIterator *aIter,
gfxContext *aContext);
void FillCharacters(CharacterIterator *aIter,
gfxContext *aContext);
enum FillOrStroke { FILL, STROKE};
void LoopCharacters(gfxContext *aCtx, const nsString &aText,
const nsSVGCharacterPosition *aCP,
FillOrStroke aFillOrStroke);
void UpdateGeometry(PRBool bRedraw, PRBool suppressInvalidation);
void UpdateMetrics();
PRBool ContainsPoint(float x, float y);
PRBool GetGlobalTransform(gfxMatrix *aContext);
nsresult GetGlobalTransform(gfxContext *aContext);
nsresult GetHighlight(PRUint32 *charnum, PRUint32 *nchars,
nscolor *foreground, nscolor *background);
// Owning pointer, must call gfxTextRunWordCache::RemoveTextRun before deleting
gfxTextRun *mTextRun;
nsRefPtr<gfxFontGroup> mFontGroup;
nsAutoPtr<gfxFontStyle> mFontStyle;
gfxPoint mPosition;
PRUint8 mWhitespaceHandling;
};

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

@ -73,6 +73,15 @@ NS_NewSVGTextFrame(nsIPresShell* aPresShell, nsIContent* aContent, nsStyleContex
//----------------------------------------------------------------------
// nsIFrame methods
NS_IMETHODIMP
nsSVGTextFrame::SetInitialChildList(nsIAtom* aListName,
nsIFrame* aChildList)
{
nsresult rv = nsSVGTextFrameBase::SetInitialChildList(aListName, aChildList);
NotifyGlyphMetricsChange();
return rv;
}
NS_IMETHODIMP
nsSVGTextFrame::AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
@ -118,7 +127,7 @@ nsSVGTextFrame::GetType() const
NS_IMETHODIMP
nsSVGTextFrame::GetNumberOfChars(PRInt32 *_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetNumberOfChars(_retval);
}
@ -126,7 +135,7 @@ nsSVGTextFrame::GetNumberOfChars(PRInt32 *_retval)
NS_IMETHODIMP
nsSVGTextFrame::GetComputedTextLength(float *_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetComputedTextLength(_retval);
}
@ -134,7 +143,7 @@ nsSVGTextFrame::GetComputedTextLength(float *_retval)
NS_IMETHODIMP
nsSVGTextFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetSubStringLength(charnum, nchars, _retval);
}
@ -142,7 +151,7 @@ nsSVGTextFrame::GetSubStringLength(PRUint32 charnum, PRUint32 nchars, float *_re
NS_IMETHODIMP
nsSVGTextFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetStartPositionOfChar(charnum, _retval);
}
@ -150,7 +159,7 @@ nsSVGTextFrame::GetStartPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retva
NS_IMETHODIMP
nsSVGTextFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetEndPositionOfChar(charnum, _retval);
}
@ -158,7 +167,7 @@ nsSVGTextFrame::GetEndPositionOfChar(PRUint32 charnum, nsIDOMSVGPoint **_retval)
NS_IMETHODIMP
nsSVGTextFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetExtentOfChar(charnum, _retval);
}
@ -166,7 +175,7 @@ nsSVGTextFrame::GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)
NS_IMETHODIMP
nsSVGTextFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetRotationOfChar(charnum, _retval);
}
@ -174,7 +183,7 @@ nsSVGTextFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
NS_IMETHODIMP
nsSVGTextFrame::GetCharNumAtPosition(nsIDOMSVGPoint *point, PRInt32 *_retval)
{
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetCharNumAtPosition(point, _retval);
}
@ -216,7 +225,8 @@ NS_IMETHODIMP
nsSVGTextFrame::NotifyRedrawUnsuspended()
{
mMetricsState = unsuspended;
UpdateGlyphPositioning(PR_FALSE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::NotifyRedrawUnsuspended();
}
@ -242,34 +252,10 @@ nsSVGTextFrame::GetOverrideCTM()
return matrix;
}
NS_IMETHODIMP
nsSVGTextFrame::PaintSVG(nsSVGRenderState* aContext, nsRect *aDirtyRect)
{
UpdateGlyphPositioning(PR_TRUE);
return nsSVGTextFrameBase::PaintSVG(aContext, aDirtyRect);
}
NS_IMETHODIMP
nsSVGTextFrame::GetFrameForPointSVG(float x, float y, nsIFrame** hit)
{
UpdateGlyphPositioning(PR_TRUE);
return nsSVGTextFrameBase::GetFrameForPointSVG(x, y, hit);
}
NS_IMETHODIMP
nsSVGTextFrame::UpdateCoveredRegion()
{
UpdateGlyphPositioning(PR_TRUE);
return nsSVGTextFrameBase::UpdateCoveredRegion();
}
NS_IMETHODIMP
nsSVGTextFrame::GetBBox(nsIDOMSVGRect **_retval)
{
UpdateGlyphPositioning(PR_TRUE);
UpdateGlyphPositioning();
return nsSVGTextFrameBase::GetBBox(_retval);
}
@ -322,6 +308,7 @@ void
nsSVGTextFrame::NotifyGlyphMetricsChange()
{
mPositioningDirty = PR_TRUE;
UpdateGlyphPositioning();
}
static void
@ -345,7 +332,7 @@ GetSingleValue(nsISVGGlyphFragmentLeaf *fragment,
}
void
nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
nsSVGTextFrame::UpdateGlyphPositioning()
{
if (mMetricsState == suspended || !mPositioningDirty)
return;
@ -438,7 +425,7 @@ nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
float dx = 0.0f;
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDx();
GetSingleValue(fragment, list, &dx);
chunkLength += dx + fragment->GetAdvance(aForceGlobalTransform);
chunkLength += dx + fragment->GetAdvance();
fragment = fragment->GetNextGlyphFragment();
if (fragment && fragment->IsAbsolutelyPositioned())
break;
@ -465,11 +452,10 @@ nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
GetSingleValue(fragment, list, &dy);
}
float baseline_offset =
fragment->GetBaselineOffset(baseline, aForceGlobalTransform);
float baseline_offset = fragment->GetBaselineOffset(baseline);
fragment->SetGlyphPosition(x + dx, y + dy - baseline_offset);
x += dx + fragment->GetAdvance(aForceGlobalTransform);
x += dx + fragment->GetAdvance();
y += dy;
fragment = fragment->GetNextGlyphFragment();
if (fragment && fragment->IsAbsolutelyPositioned())

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

@ -52,10 +52,12 @@ protected:
: nsSVGTextFrameBase(aContext),
mMetricsState(unsuspended),
mPropagateTransform(PR_TRUE),
mPositioningDirty(PR_TRUE) {}
mPositioningDirty(PR_FALSE) {}
public:
// nsIFrame:
NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD AttributeChanged(PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aModType);
@ -82,11 +84,6 @@ public:
virtual void NotifySVGChanged(PRUint32 aFlags);
NS_IMETHOD NotifyRedrawSuspended();
NS_IMETHOD NotifyRedrawUnsuspended();
// Override these four to ensure that UpdateGlyphPositioning is called
// to bring glyph positions up to date
NS_IMETHOD PaintSVG(nsSVGRenderState* aContext, nsRect *aDirtyRect);
NS_IMETHOD GetFrameForPointSVG(float x, float y, nsIFrame** hit);
NS_IMETHOD UpdateCoveredRegion();
NS_IMETHOD GetBBox(nsIDOMSVGRect **_retval);
// nsSVGContainerFrame methods:
@ -106,12 +103,7 @@ public:
void NotifyGlyphMetricsChange();
private:
/**
* @param aForceGlobalTransform passed down to nsSVGGlyphFrames to
* control whether they should use the global transform even when
* NS_STATE_NONDISPLAY_CHILD
*/
void UpdateGlyphPositioning(PRBool aForceGlobalTransform);
void UpdateGlyphPositioning();
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
nsCOMPtr<nsIDOMSVGMatrix> mOverrideCTM;