Bug 1065002 pt 1.3 - Add an Orientation parameter to gfxFont::GetMetrics and dispatch to horizontal or vertical as needed. r=jdaggett

This commit is contained in:
Jonathan Kew 2014-09-30 07:38:26 +01:00
parent cbdf2b8244
commit 9407713a2b
10 changed files with 64 additions and 29 deletions

View File

@ -3443,7 +3443,7 @@ CanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
// offset pt.y based on text baseline
processor.mFontgrp->UpdateUserFonts(); // ensure user font generation is current
const gfxFont::Metrics& fontMetrics =
processor.mFontgrp->GetFirstValidFont()->GetMetrics();
processor.mFontgrp->GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
gfxFloat anchorY;

View File

@ -147,7 +147,7 @@ nsFontMetrics::Destroy()
const gfxFont::Metrics& nsFontMetrics::GetMetrics() const
{
return mFontGroup->GetFirstValidFont()->GetMetrics();
return mFontGroup->GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
}
nscoord

View File

@ -658,7 +658,7 @@ gfxShapedText::SetMissingGlyph(uint32_t aIndex, uint32_t aChar, gfxFont *aFont)
details->mAdvance = 0;
} else {
gfxFloat width =
std::max(aFont->GetMetrics().aveCharWidth,
std::max(aFont->GetMetrics(gfxFont::eHorizontal).aveCharWidth,
gfxFontMissingGlyphs::GetDesiredMinWidth(aChar,
mAppUnitsPerDevUnit));
details->mAdvance = uint32_t(width * mAppUnitsPerDevUnit);
@ -788,7 +788,7 @@ gfxFont::GetGlyphHAdvance(gfxContext *aCtx, uint16_t aGID)
return GetGlyphWidth(aCtx, aGID) / 65536.0;
}
if (mFUnitsConvFactor == 0.0f) {
GetMetrics();
GetMetrics(eHorizontal);
}
NS_ASSERTION(mFUnitsConvFactor > 0.0f,
"missing font unit conversion factor");
@ -1780,7 +1780,7 @@ gfxFont::DrawGlyphs(gfxShapedText *aShapedText,
ToDeviceUnits(aPt->y, aRunParams.devPerApp));
gfxFloat advanceDevUnits =
ToDeviceUnits(advance, aRunParams.devPerApp);
gfxFloat height = GetMetrics().maxAscent;
gfxFloat height = GetMetrics(eHorizontal).maxAscent;
gfxRect glyphRect(pt.x, pt.y - height,
advanceDevUnits, height);
@ -2059,7 +2059,9 @@ gfxFont::Measure(gfxTextRun *aTextRun,
const int32_t appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
// Current position in appunits
const gfxFont::Metrics& fontMetrics = GetMetrics();
gfxFont::Orientation orientation =
aTextRun->IsVertical() ? gfxFont::eVertical : gfxFont::eHorizontal;
const gfxFont::Metrics& fontMetrics = GetMetrics(orientation);
RunMetrics metrics;
metrics.mAscent = fontMetrics.maxAscent*appUnitsPerDevUnit;
@ -2103,6 +2105,7 @@ gfxFont::Measure(gfxTextRun *aTextRun,
} else {
gfxRect glyphRect;
if (!extents->GetTightGlyphExtentsAppUnits(this,
orientation,
aRefContext, glyphIndex, &glyphRect)) {
glyphRect = gfxRect(0, metrics.mBoundingBox.Y(),
advance, metrics.mBoundingBox.Height());
@ -2130,6 +2133,7 @@ gfxFont::Measure(gfxTextRun *aTextRun,
gfxRect glyphRect;
if (glyphData->IsMissing() || !extents ||
!extents->GetTightGlyphExtentsAppUnits(this,
orientation,
aRefContext, glyphIndex, &glyphRect)) {
// We might have failed to get glyph extents due to
// OOM or something
@ -2937,7 +2941,8 @@ gfxFont::GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit) {
}
void
gfxFont::SetupGlyphExtents(gfxContext *aContext, uint32_t aGlyphID, bool aNeedTight,
gfxFont::SetupGlyphExtents(gfxContext *aContext, Orientation aOrientation,
uint32_t aGlyphID, bool aNeedTight,
gfxGlyphExtents *aExtents)
{
gfxContextMatrixAutoSaveRestore matrixRestore(aContext);
@ -2962,7 +2967,7 @@ gfxFont::SetupGlyphExtents(gfxContext *aContext, uint32_t aGlyphID, bool aNeedTi
cairo_text_extents_t extents;
cairo_glyph_extents(aContext->GetCairo(), &glyph, 1, &extents);
const Metrics& fontMetrics = GetMetrics();
const Metrics& fontMetrics = GetMetrics(aOrientation);
int32_t appUnitsPerDevUnit = aExtents->GetAppUnitsPerDevUnit();
if (!aNeedTight && extents.x_bearing >= 0 &&
extents.y_bearing >= -fontMetrics.maxAscent &&
@ -3368,8 +3373,8 @@ gfxFont::SynthesizeSpaceWidth(uint32_t aCh)
case 0x2004: return GetAdjustedSize() / 3; // three-per-em space
case 0x2005: return GetAdjustedSize() / 4; // four-per-em space
case 0x2006: return GetAdjustedSize() / 6; // six-per-em space
case 0x2007: return GetMetrics().zeroOrAveCharWidth; // figure space
case 0x2008: return GetMetrics().spaceWidth; // punctuation space
case 0x2007: return GetMetrics(eHorizontal).zeroOrAveCharWidth; // figure space
case 0x2008: return GetMetrics(eHorizontal).spaceWidth; // punctuation space
case 0x2009: return GetAdjustedSize() / 5; // thin space
case 0x200a: return GetAdjustedSize() / 10; // hair space
case 0x202f: return GetAdjustedSize() / 5; // narrow no-break space

View File

@ -1442,9 +1442,20 @@ public:
// equal to .aveCharWidth
};
const Metrics& GetMetrics()
enum Orientation {
eHorizontal,
eVertical
};
const Metrics& GetMetrics(Orientation aOrientation)
{
return GetHorizontalMetrics();
if (aOrientation == eHorizontal) {
return GetHorizontalMetrics();
}
if (!mVerticalMetrics) {
mVerticalMetrics = CreateVerticalMetrics();
}
return *mVerticalMetrics;
}
/**
@ -1562,7 +1573,8 @@ public:
gfxGlyphExtents *GetOrCreateGlyphExtents(int32_t aAppUnitsPerDevUnit);
// You need to call SetupCairoFont on the aCR just before calling this
virtual void SetupGlyphExtents(gfxContext *aContext, uint32_t aGlyphID,
virtual void SetupGlyphExtents(gfxContext *aContext,
Orientation aOrientation, uint32_t aGlyphID,
bool aNeedTight, gfxGlyphExtents *aExtents);
// This is called by the default Draw() implementation above.

View File

@ -36,6 +36,7 @@ gfxGlyphExtents::~gfxGlyphExtents()
bool
gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont *aFont,
gfxFont::Orientation aOrientation,
gfxContext *aContext, uint32_t aGlyphID, gfxRect *aExtents)
{
HashEntry *entry = mTightGlyphExtents.GetEntry(aGlyphID);
@ -49,7 +50,8 @@ gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont *aFont,
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupLazyTight;
#endif
aFont->SetupGlyphExtents(aContext, aGlyphID, true, this);
aFont->SetupGlyphExtents(aContext, aOrientation, aGlyphID, true,
this);
entry = mTightGlyphExtents.GetEntry(aGlyphID);
}
if (!entry) {

View File

@ -6,13 +6,13 @@
#ifndef GFX_GLYPHEXTENTS_H
#define GFX_GLYPHEXTENTS_H
#include "gfxFont.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "nsTArray.h"
#include "mozilla/MemoryReporting.h"
class gfxContext;
class gfxFont;
struct gfxRect;
/**
@ -62,8 +62,9 @@ public:
// Get glyph extents; a rectangle relative to the left baseline origin
// Returns true on success. Can fail on OOM or when aContext is null
// and extents were not (successfully) prefetched.
bool GetTightGlyphExtentsAppUnits(gfxFont *aFont, gfxContext *aContext,
uint32_t aGlyphID, gfxRect *aExtents);
bool GetTightGlyphExtentsAppUnits(gfxFont *aFont,
gfxFont::Orientation aOrientation,
gfxContext *aContext, uint32_t aGlyphID, gfxRect *aExtents);
void SetContainedGlyphWidthAppUnits(uint32_t aGlyphID, uint16_t aWidth) {
mContainedGlyphWidths.Set(aGlyphID, aWidth);

View File

@ -1861,7 +1861,8 @@ gfxPangoFontGroup::GetBaseFontSet()
if (size != 0.0 && mStyle.sizeAdjust != 0.0) {
gfxFcFont *font = fontSet->GetFontAt(0, GetStyle());
if (font) {
const gfxFont::Metrics& metrics = font->GetMetrics();
const gfxFont::Metrics& metrics =
font->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
// The factor of 0.1 ensures that xHeight is sane so fonts don't
// become huge. Strictly ">" ensures that xHeight and emHeight are

View File

@ -1264,8 +1264,12 @@ gfxTextRun::SetSpaceGlyphIfSimple(gfxFont *aFont, gfxContext *aContext,
return false;
}
gfxFont::Orientation fontOrientation =
(aOrientation & gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT) ?
gfxFont::eVertical : gfxFont::eHorizontal;
uint32_t spaceWidthAppUnits =
NS_lroundf(aFont->GetMetrics().spaceWidth * mAppUnitsPerDevUnit);
NS_lroundf(aFont->GetMetrics(fontOrientation).spaceWidth *
mAppUnitsPerDevUnit);
if (!CompressedGlyph::IsSimpleAdvance(spaceWidthAppUnits)) {
return false;
}
@ -1306,6 +1310,8 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
for (j = start; j < end; ++j) {
const gfxTextRun::CompressedGlyph *glyphData = &charGlyphs[j];
gfxFont::Orientation orientation =
IsVertical() ? gfxFont::eVertical : gfxFont::eHorizontal;
if (glyphData->IsSimpleGlyph()) {
// If we're in speed mode, don't set up glyph extents here; we'll
// just return "optimistic" glyph bounds later
@ -1322,7 +1328,8 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupEagerSimple;
#endif
font->SetupGlyphExtents(aRefContext, glyphIndex, false, extents);
font->SetupGlyphExtents(aRefContext, orientation,
glyphIndex, false, extents);
}
}
} else if (!glyphData->IsMissing()) {
@ -1347,7 +1354,8 @@ gfxTextRun::FetchGlyphExtents(gfxContext *aRefContext)
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupEagerTight;
#endif
font->SetupGlyphExtents(aRefContext, glyphIndex, true, extents);
font->SetupGlyphExtents(aRefContext, orientation,
glyphIndex, true, extents);
}
}
}
@ -2474,16 +2482,19 @@ gfxFontGroup::GetUnderlineOffset()
if (!font) {
continue;
}
gfxFloat bad = font->GetMetrics().underlineOffset;
gfxFloat bad = font->GetMetrics(gfxFont::eHorizontal).
underlineOffset;
gfxFloat first =
GetFirstValidFont()->GetMetrics().underlineOffset;
GetFirstValidFont()->GetMetrics(gfxFont::eHorizontal).
underlineOffset;
mUnderlineOffset = std::min(first, bad);
return mUnderlineOffset;
}
}
// no bad underline fonts, use the first valid font's metric
mUnderlineOffset = GetFirstValidFont()->GetMetrics().underlineOffset;
mUnderlineOffset = GetFirstValidFont()->
GetMetrics(gfxFont::eHorizontal).underlineOffset;
}
return mUnderlineOffset;

View File

@ -1798,7 +1798,7 @@ GetFirstFontMetrics(gfxFontGroup* aFontGroup)
gfxFont* font = aFontGroup->GetFirstValidFont();
if (!font)
return gfxFont::Metrics();
return font->GetMetrics();
return font->GetMetrics(gfxFont::eHorizontal); // XXX vertical
}
PR_STATIC_ASSERT(NS_STYLE_WHITESPACE_NORMAL == 0);
@ -5672,7 +5672,8 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
gfxFont* firstFont = aProvider.GetFontGroup()->GetFirstValidFont();
if (!firstFont)
return; // OOM
gfxFont::Metrics decorationMetrics(firstFont->GetMetrics());
gfxFont::Metrics
decorationMetrics(firstFont->GetMetrics(gfxFont::eHorizontal)); // XXX vertical?
decorationMetrics.underlineOffset =
aProvider.GetFontGroup()->GetUnderlineOffset();
@ -6353,7 +6354,8 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
gfxFont* firstFont = fontGroup->GetFirstValidFont();
if (!firstFont)
return false; // OOM
const gfxFont::Metrics& metrics = firstFont->GetMetrics();
const gfxFont::Metrics& metrics =
firstFont->GetMetrics(gfxFont::eHorizontal); // XXX vertical?
gfxFloat underlineOffset = fontGroup->GetUnderlineOffset();
gfxFloat ascent = aPresContext->AppUnitsToGfxUnits(mAscent);
gfxFloat descentLimit =

View File

@ -500,8 +500,9 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
nsRefPtr<nsFontMetrics> fm =
GetMetricsFor(aPresContext, aStyleContext, styleFont,
aFontSize, aUseUserFontSet);
gfxFloat zeroWidth = (fm->GetThebesFontGroup()->GetFirstValidFont()
->GetMetrics().zeroOrAveCharWidth);
gfxFloat zeroWidth =
fm->GetThebesFontGroup()->GetFirstValidFont()->
GetMetrics(gfxFont::eHorizontal).zeroOrAveCharWidth; // XXX vertical?
return ScaleCoordRound(aValue, ceil(aPresContext->AppUnitsPerDevPixel() *
zeroWidth));