mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-06 14:44:26 +00:00
Bug 496989 - Simplify text/glyph interface. r=jwatt
This commit is contained in:
parent
ac050d8a8d
commit
df2c2b87cf
@ -56,20 +56,9 @@ public:
|
||||
NS_IMETHOD GetExtentOfChar(PRUint32 charnum, nsIDOMSVGRect **_retval)=0;
|
||||
NS_IMETHOD GetRotationOfChar(PRUint32 charnum, float *_retval)=0;
|
||||
|
||||
enum { BASELINE_ALPHABETIC = 0U };
|
||||
enum { BASELINE_HANGING = 1U };
|
||||
enum { BASELINE_IDEOGRAPHC = 2U };
|
||||
enum { BASELINE_MATHEMATICAL = 3U };
|
||||
enum { BASELINE_CENTRAL = 4U };
|
||||
enum { BASELINE_MIDDLE = 5U };
|
||||
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_(void) SetGlyphPosition(float x, float y)=0;
|
||||
NS_IMETHOD_(void) SetGlyphPosition(float x, float y, PRBool aForceGlobalTransform)=0;
|
||||
NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent()=0;
|
||||
NS_IMETHOD_(PRBool) IsStartOfChunk()=0; // == is new absolutely positioned chunk.
|
||||
NS_IMETHOD_(void) GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y)=0;
|
||||
|
@ -720,6 +720,65 @@ nsSVGGlyphFrame::GetCharacterPositions(nsTArray<CharacterPosition>* aCharacterPo
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
float
|
||||
nsSVGGlyphFrame::GetSubStringAdvance(PRUint32 charnum,
|
||||
PRUint32 fragmentChars)
|
||||
{
|
||||
if (fragmentChars == 0)
|
||||
return 0.0f;
|
||||
|
||||
gfxFloat advance = mTextRun->GetAdvanceWidth(charnum, fragmentChars, nsnull);
|
||||
return float(advance);
|
||||
}
|
||||
|
||||
gfxFloat
|
||||
nsSVGGlyphFrame::GetBaselineOffset(PRBool aForceGlobalTransform)
|
||||
{
|
||||
float drawScale, metricsScale;
|
||||
|
||||
if (!EnsureTextRun(&drawScale, &metricsScale, aForceGlobalTransform))
|
||||
return 0.0;
|
||||
|
||||
gfxTextRun::Metrics metrics =
|
||||
mTextRun->MeasureText(0, mTextRun->GetLength(),
|
||||
gfxFont::LOOSE_INK_EXTENTS, nsnull, nsnull);
|
||||
|
||||
PRUint16 dominantBaseline;
|
||||
|
||||
for (nsIFrame *frame = GetParent(); frame; frame = frame->GetParent()) {
|
||||
dominantBaseline = frame->GetStyleSVGReset()->mDominantBaseline;
|
||||
if (dominantBaseline != NS_STYLE_DOMINANT_BASELINE_AUTO ||
|
||||
frame->GetType() == nsGkAtoms::svgTextFrame) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gfxFloat baselineAppUnits;
|
||||
switch (dominantBaseline) {
|
||||
case NS_STYLE_DOMINANT_BASELINE_HANGING:
|
||||
// not really right, but the best we can do with the information provided
|
||||
// FALLTHROUGH
|
||||
case NS_STYLE_DOMINANT_BASELINE_TEXT_BEFORE_EDGE:
|
||||
baselineAppUnits = -metrics.mAscent;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_TEXT_AFTER_EDGE:
|
||||
case NS_STYLE_DOMINANT_BASELINE_IDEOGRAPHIC:
|
||||
baselineAppUnits = metrics.mDescent;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_CENTRAL:
|
||||
case NS_STYLE_DOMINANT_BASELINE_MIDDLE:
|
||||
baselineAppUnits = -(metrics.mAscent - metrics.mDescent) / 2.0;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_AUTO:
|
||||
case NS_STYLE_DOMINANT_BASELINE_ALPHABETIC:
|
||||
return 0.0;
|
||||
default:
|
||||
NS_WARNING("We don't know about this type of dominant-baseline");
|
||||
return 0.0;
|
||||
}
|
||||
return baselineAppUnits * metricsScale;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Utilities for converting from indices in the uncompressed content
|
||||
@ -865,9 +924,9 @@ nsSVGGlyphFrame::GetHighlight(PRUint32 *charnum, PRUint32 *nchars,
|
||||
// nsISVGGlyphFragmentLeaf interface:
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsSVGGlyphFrame::SetGlyphPosition(float x, float y)
|
||||
nsSVGGlyphFrame::SetGlyphPosition(float x, float y, PRBool aForceGlobalTransform)
|
||||
{
|
||||
mPosition.MoveTo(x, y);
|
||||
mPosition.MoveTo(x, y - GetBaselineOffset(aForceGlobalTransform));
|
||||
nsSVGUtils::UpdateGraphic(this);
|
||||
}
|
||||
|
||||
@ -947,42 +1006,6 @@ nsSVGGlyphFrame::GetRotationOfChar(PRUint32 charnum, float *_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(float)
|
||||
nsSVGGlyphFrame::GetBaselineOffset(PRUint16 baselineIdentifier,
|
||||
PRBool aForceGlobalTransform)
|
||||
{
|
||||
float drawScale, metricsScale;
|
||||
|
||||
if (!EnsureTextRun(&drawScale, &metricsScale, aForceGlobalTransform))
|
||||
return 0.0f;
|
||||
|
||||
gfxTextRun::Metrics metrics =
|
||||
mTextRun->MeasureText(0, mTextRun->GetLength(),
|
||||
gfxFont::LOOSE_INK_EXTENTS, nsnull, nsnull);
|
||||
|
||||
gfxFloat baselineAppUnits;
|
||||
switch (baselineIdentifier) {
|
||||
case BASELINE_HANGING:
|
||||
// not really right, but the best we can do with the information provided
|
||||
// FALLTHROUGH
|
||||
case BASELINE_TEXT_BEFORE_EDGE:
|
||||
baselineAppUnits = -metrics.mAscent;
|
||||
break;
|
||||
case BASELINE_TEXT_AFTER_EDGE:
|
||||
baselineAppUnits = metrics.mDescent;
|
||||
break;
|
||||
case BASELINE_CENTRAL:
|
||||
case BASELINE_MIDDLE:
|
||||
baselineAppUnits = -(metrics.mAscent - metrics.mDescent) / 2.0f;
|
||||
break;
|
||||
case BASELINE_ALPHABETIC:
|
||||
default:
|
||||
baselineAppUnits = 0.0;
|
||||
break;
|
||||
}
|
||||
return float(baselineAppUnits)*metricsScale;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(float)
|
||||
nsSVGGlyphFrame::GetAdvance(PRBool aForceGlobalTransform)
|
||||
{
|
||||
@ -990,9 +1013,8 @@ nsSVGGlyphFrame::GetAdvance(PRBool aForceGlobalTransform)
|
||||
if (!EnsureTextRun(&drawScale, &metricsScale, aForceGlobalTransform))
|
||||
return 0.0f;
|
||||
|
||||
gfxFloat advanceAppUnits =
|
||||
mTextRun->GetAdvanceWidth(0, mTextRun->GetLength(), nsnull);
|
||||
return float(advanceAppUnits)*metricsScale;
|
||||
float advanceAppUnits = GetSubStringAdvance(0, mTextRun->GetLength());
|
||||
return advanceAppUnits * metricsScale;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(nsSVGTextPathFrame*)
|
||||
@ -1130,9 +1152,8 @@ nsSVGGlyphFrame::GetSubStringLength(PRUint32 charnum, PRUint32 fragmentChars)
|
||||
if (!EnsureTextRun(&drawScale, &metricsScale, PR_FALSE))
|
||||
return 0.0f;
|
||||
|
||||
gfxFloat advanceAppUnits =
|
||||
mTextRun->GetAdvanceWidth(charnum, fragmentChars, nsnull);
|
||||
return float(advanceAppUnits)*metricsScale;
|
||||
float advanceAppUnits = GetSubStringAdvance(charnum, fragmentChars);
|
||||
return advanceAppUnits * metricsScale;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -143,19 +143,13 @@ public:
|
||||
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_(void) SetGlyphPosition(float x, float y);
|
||||
NS_IMETHOD_(void) SetGlyphPosition(float x, float y, PRBool aForceGlobalTransform);
|
||||
NS_IMETHOD_(nsSVGTextPathFrame*) FindTextPathParent();
|
||||
NS_IMETHOD_(PRBool) IsStartOfChunk(); // == is new absolutely positioned chunk.
|
||||
NS_IMETHOD_(void) GetAdjustedPosition(/* inout */ float &x, /* inout */ float &y);
|
||||
@ -216,6 +210,8 @@ protected:
|
||||
void SetupGlobalTransform(gfxContext *aContext);
|
||||
nsresult GetHighlight(PRUint32 *charnum, PRUint32 *nchars,
|
||||
nscolor *foreground, nscolor *background);
|
||||
float GetSubStringAdvance(PRUint32 charnum, PRUint32 fragmentChars);
|
||||
gfxFloat GetBaselineOffset(PRBool aForceGlobalTransform);
|
||||
const nsTextFragment* GetFragment() const
|
||||
{
|
||||
return !(GetStateBits() & NS_STATE_SVG_PRINTING) ?
|
||||
|
@ -290,8 +290,7 @@ nsSVGTextFrame::NotifyGlyphMetricsChange()
|
||||
}
|
||||
|
||||
static void
|
||||
GetSingleValue(nsISVGGlyphFragmentLeaf *fragment,
|
||||
nsIDOMSVGLengthList *list, float *val)
|
||||
GetSingleValue(nsIDOMSVGLengthList *list, float *val)
|
||||
{
|
||||
if (!list)
|
||||
return;
|
||||
@ -322,40 +321,6 @@ nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
|
||||
|
||||
mPositioningDirty = PR_FALSE;
|
||||
|
||||
// we'll align every fragment in this chunk on the dominant-baseline:
|
||||
// XXX should actually inspect 'alignment-baseline' for each fragment
|
||||
|
||||
PRUint8 baseline;
|
||||
switch(GetStyleSVGReset()->mDominantBaseline) {
|
||||
case NS_STYLE_DOMINANT_BASELINE_TEXT_BEFORE_EDGE:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_TEXT_BEFORE_EDGE;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_TEXT_AFTER_EDGE:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_TEXT_AFTER_EDGE;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_MIDDLE:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_MIDDLE;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_CENTRAL:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_CENTRAL;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_MATHEMATICAL:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_MATHEMATICAL;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_IDEOGRAPHIC:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_IDEOGRAPHC;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_HANGING:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_HANGING;
|
||||
break;
|
||||
case NS_STYLE_DOMINANT_BASELINE_AUTO:
|
||||
case NS_STYLE_DOMINANT_BASELINE_USE_SCRIPT:
|
||||
case NS_STYLE_DOMINANT_BASELINE_ALPHABETIC:
|
||||
default:
|
||||
baseline = nsISVGGlyphFragmentLeaf::BASELINE_ALPHABETIC;
|
||||
break;
|
||||
}
|
||||
|
||||
nsISVGGlyphFragmentLeaf *fragment, *firstFragment;
|
||||
|
||||
firstFragment = node->GetFirstGlyphFragment();
|
||||
@ -367,22 +332,22 @@ nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
|
||||
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = GetX();
|
||||
GetSingleValue(firstFragment, list, &x);
|
||||
GetSingleValue(list, &x);
|
||||
}
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = GetY();
|
||||
GetSingleValue(firstFragment, list, &y);
|
||||
GetSingleValue(list, &y);
|
||||
}
|
||||
|
||||
// loop over chunks
|
||||
while (firstFragment) {
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = firstFragment->GetX();
|
||||
GetSingleValue(firstFragment, list, &x);
|
||||
GetSingleValue(list, &x);
|
||||
}
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = firstFragment->GetY();
|
||||
GetSingleValue(firstFragment, list, &y);
|
||||
GetSingleValue(list, &y);
|
||||
}
|
||||
|
||||
// check for startOffset on textPath
|
||||
@ -407,7 +372,7 @@ nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
|
||||
while (fragment) {
|
||||
float dx = 0.0f;
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDx();
|
||||
GetSingleValue(fragment, list, &dx);
|
||||
GetSingleValue(list, &dx);
|
||||
chunkLength += dx + fragment->GetAdvance(aForceGlobalTransform);
|
||||
fragment = fragment->GetNextGlyphFragment();
|
||||
if (fragment && fragment->IsAbsolutelyPositioned())
|
||||
@ -428,16 +393,14 @@ nsSVGTextFrame::UpdateGlyphPositioning(PRBool aForceGlobalTransform)
|
||||
float dx = 0.0f, dy = 0.0f;
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDx();
|
||||
GetSingleValue(fragment, list, &dx);
|
||||
GetSingleValue(list, &dx);
|
||||
}
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGLengthList> list = fragment->GetDy();
|
||||
GetSingleValue(fragment, list, &dy);
|
||||
GetSingleValue(list, &dy);
|
||||
}
|
||||
|
||||
float baseline_offset =
|
||||
fragment->GetBaselineOffset(baseline, aForceGlobalTransform);
|
||||
fragment->SetGlyphPosition(x + dx, y + dy - baseline_offset);
|
||||
fragment->SetGlyphPosition(x + dx, y + dy, aForceGlobalTransform);
|
||||
|
||||
x += dx + fragment->GetAdvance(aForceGlobalTransform);
|
||||
y += dy;
|
||||
|
Loading…
x
Reference in New Issue
Block a user