зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
af4fdc577c
Коммит
c5e1a54d59
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1442,10 +1442,21 @@ public:
|
|||
// equal to .aveCharWidth
|
||||
};
|
||||
|
||||
const Metrics& GetMetrics()
|
||||
enum Orientation {
|
||||
eHorizontal,
|
||||
eVertical
|
||||
};
|
||||
|
||||
const Metrics& GetMetrics(Orientation aOrientation)
|
||||
{
|
||||
if (aOrientation == eHorizontal) {
|
||||
return GetHorizontalMetrics();
|
||||
}
|
||||
if (!mVerticalMetrics) {
|
||||
mVerticalMetrics = CreateVerticalMetrics();
|
||||
}
|
||||
return *mVerticalMetrics;
|
||||
}
|
||||
|
||||
/**
|
||||
* We let layout specify spacing on either side of any
|
||||
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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));
|
||||
|
|
Загрузка…
Ссылка в новой задаче