зеркало из https://github.com/mozilla/gecko-dev.git
bug 581087 - get true maxAdvance and aveCharWidth in DWrite font metrics. r=bas a=blocking2.0
This commit is contained in:
Родитель
4214a38f34
Коммит
97bbe78e82
|
@ -294,10 +294,7 @@ gfxDWriteFontEntry::ReadCMAP()
|
|||
isUnicode,
|
||||
isSymbol);
|
||||
}
|
||||
|
||||
if (tableContext) {
|
||||
fontFace->ReleaseFontTable(tableContext);
|
||||
}
|
||||
fontFace->ReleaseFontTable(tableContext);
|
||||
|
||||
mCmapInitialized = PR_TRUE;
|
||||
mHasCmapTable = NS_SUCCEEDED(rv);
|
||||
|
|
|
@ -178,6 +178,27 @@ gfxDWriteFont::ComputeMetrics()
|
|||
|
||||
mMetrics.maxAdvance = mAdjustedSize;
|
||||
|
||||
// try to get the true maxAdvance value from 'hhea'
|
||||
PRUint8 *tableData;
|
||||
PRUint32 len;
|
||||
void *tableContext = NULL;
|
||||
BOOL exists;
|
||||
HRESULT hr =
|
||||
mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('h', 'h', 'e', 'a'),
|
||||
(const void**)&tableData,
|
||||
&len,
|
||||
&tableContext,
|
||||
&exists);
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (exists && len >= sizeof(mozilla::HheaTable)) {
|
||||
const mozilla::HheaTable* hhea =
|
||||
reinterpret_cast<const mozilla::HheaTable*>(tableData);
|
||||
mMetrics.maxAdvance = ((gfxFloat)PRUint16(hhea->advanceWidthMax) /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
}
|
||||
mFontFace->ReleaseFontTable(tableContext);
|
||||
}
|
||||
|
||||
mMetrics.internalLeading =
|
||||
ceil(((gfxFloat)(fontMetrics.ascent +
|
||||
fontMetrics.descent -
|
||||
|
@ -193,18 +214,44 @@ gfxDWriteFont::ComputeMetrics()
|
|||
mMetrics.spaceWidth =
|
||||
((gfxFloat)metrics.advanceWidth /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
UINT32 ucs = L'x';
|
||||
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
|
||||
SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
|
||||
mMetrics.aveCharWidth =
|
||||
((gfxFloat)metrics.advanceWidth /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
} else {
|
||||
// Let's just assume the X is square.
|
||||
mMetrics.aveCharWidth =
|
||||
((gfxFloat)fontMetrics.xHeight /
|
||||
|
||||
// try to get aveCharWidth from the OS/2 table, fall back to measuring 'x'
|
||||
// if the table is not available
|
||||
mMetrics.aveCharWidth = 0;
|
||||
hr = mFontFace->TryGetFontTable(DWRITE_MAKE_OPENTYPE_TAG('O', 'S', '/', '2'),
|
||||
(const void**)&tableData,
|
||||
&len,
|
||||
&tableContext,
|
||||
&exists);
|
||||
if (SUCCEEDED(hr)) {
|
||||
if (exists && len >= 4) {
|
||||
// Not checking against sizeof(mozilla::OS2Table) here because older
|
||||
// versions of the table have different sizes; we only need the first
|
||||
// two 16-bit fields here.
|
||||
const mozilla::OS2Table* os2 =
|
||||
reinterpret_cast<const mozilla::OS2Table*>(tableData);
|
||||
mMetrics.aveCharWidth = ((gfxFloat)PRInt16(os2->xAvgCharWidth) /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
}
|
||||
mFontFace->ReleaseFontTable(tableContext);
|
||||
}
|
||||
|
||||
UINT32 ucs;
|
||||
if (mMetrics.aveCharWidth < 1) {
|
||||
ucs = L'x';
|
||||
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
|
||||
SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
|
||||
mMetrics.aveCharWidth =
|
||||
((gfxFloat)metrics.advanceWidth /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
} else {
|
||||
// Let's just assume the X is square.
|
||||
mMetrics.aveCharWidth =
|
||||
((gfxFloat)fontMetrics.xHeight /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
}
|
||||
}
|
||||
|
||||
ucs = L'0';
|
||||
if (SUCCEEDED(mFontFace->GetGlyphIndicesA(&ucs, 1, &glyph)) &&
|
||||
SUCCEEDED(mFontFace->GetDesignGlyphMetrics(&glyph, 1, &metrics))) {
|
||||
|
@ -214,6 +261,7 @@ gfxDWriteFont::ComputeMetrics()
|
|||
} else {
|
||||
mMetrics.zeroOrAveCharWidth = mMetrics.aveCharWidth;
|
||||
}
|
||||
|
||||
mMetrics.underlineOffset =
|
||||
((gfxFloat)fontMetrics.underlinePosition /
|
||||
fontMetrics.designUnitsPerEm) * mAdjustedSize;
|
||||
|
@ -239,7 +287,8 @@ gfxDWriteFont::ComputeMetrics()
|
|||
printf(" emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
|
||||
printf(" maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics.maxAscent, mMetrics.maxDescent, mMetrics.maxAdvance);
|
||||
printf(" internalLeading: %f externalLeading: %f\n", mMetrics.internalLeading, mMetrics.externalLeading);
|
||||
printf(" spaceWidth: %f aveCharWidth: %f xHeight: %f\n", mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.xHeight);
|
||||
printf(" spaceWidth: %f aveCharWidth: %f zeroOrAve: %f xHeight: %f\n",
|
||||
mMetrics.spaceWidth, mMetrics.aveCharWidth, mMetrics.zeroOrAveCharWidth, mMetrics.xHeight);
|
||||
printf(" uOff: %f uSize: %f stOff: %f stSize: %f supOff: %f subOff: %f\n",
|
||||
mMetrics.underlineOffset, mMetrics.underlineSize, mMetrics.strikeoutOffset, mMetrics.strikeoutSize,
|
||||
mMetrics.superscriptOffset, mMetrics.subscriptOffset);
|
||||
|
|
Загрузка…
Ссылка в новой задаче