mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-04 13:07:52 +00:00
bug 594889 - improve glyph spacing with DirectWrite fonts when ClearType is disabled by using GDI-compatible instead of 'ideal' metrics. r=bas a=blocking2.0
This commit is contained in:
parent
8056d8607f
commit
20bd210d2f
@ -68,6 +68,51 @@ GetCairoAntialiasOption(gfxFont::AntialiasOption anAntialiasOption)
|
||||
}
|
||||
}
|
||||
|
||||
// Code to determine whether Windows is set to use ClearType font smoothing;
|
||||
// based on private functions in cairo-win32-font.c
|
||||
|
||||
#ifndef SPI_GETFONTSMOOTHINGTYPE
|
||||
#define SPI_GETFONTSMOOTHINGTYPE 0x200a
|
||||
#endif
|
||||
#ifndef FE_FONTSMOOTHINGCLEARTYPE
|
||||
#define FE_FONTSMOOTHINGCLEARTYPE 2
|
||||
#endif
|
||||
|
||||
static bool
|
||||
HasClearType()
|
||||
{
|
||||
OSVERSIONINFO versionInfo;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
|
||||
return (GetVersionEx(&versionInfo) &&
|
||||
(versionInfo.dwMajorVersion > 5 ||
|
||||
(versionInfo.dwMajorVersion == 5 &&
|
||||
versionInfo.dwMinorVersion >= 1))); // XP or newer
|
||||
}
|
||||
|
||||
static bool
|
||||
UsingClearType()
|
||||
{
|
||||
BOOL fontSmoothing;
|
||||
if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothing, 0) ||
|
||||
!fontSmoothing)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasClearType()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UINT type;
|
||||
if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &type, 0) &&
|
||||
type == FE_FONTSMOOTHINGCLEARTYPE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// gfxDWriteFont
|
||||
gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry,
|
||||
@ -79,6 +124,7 @@ gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry,
|
||||
, mCairoScaledFont(nsnull)
|
||||
, mNeedsOblique(PR_FALSE)
|
||||
, mNeedsBold(aNeedsBold)
|
||||
, mUsingClearType(PR_FALSE)
|
||||
{
|
||||
gfxDWriteFontEntry *fe =
|
||||
static_cast<gfxDWriteFontEntry*>(aFontEntry);
|
||||
@ -101,6 +147,12 @@ gfxDWriteFont::gfxDWriteFont(gfxFontEntry *aFontEntry,
|
||||
return;
|
||||
}
|
||||
|
||||
if ((anAAOption == gfxFont::kAntialiasDefault && UsingClearType()) ||
|
||||
anAAOption == gfxFont::kAntialiasSubpixel)
|
||||
{
|
||||
mUsingClearType = PR_TRUE;
|
||||
}
|
||||
|
||||
ComputeMetrics();
|
||||
|
||||
if (FontCanSupportHarfBuzz()) {
|
||||
@ -427,3 +479,29 @@ gfxDWriteFont::GetFontTable(PRUint32 aTag)
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
gfxDWriteFont::GetHintedGlyphWidth(gfxContext *aCtx, PRUint16 aGID)
|
||||
{
|
||||
if (!mGlyphWidths.IsInitialized()) {
|
||||
mGlyphWidths.Init(200);
|
||||
}
|
||||
|
||||
PRInt32 width;
|
||||
if (mGlyphWidths.Get(aGID, &width)) {
|
||||
return width;
|
||||
}
|
||||
|
||||
DWRITE_GLYPH_METRICS glyphMetrics;
|
||||
HRESULT hr = mFontFace->GetGdiCompatibleGlyphMetrics(
|
||||
GetAdjustedSize(), 1.0f, nsnull, TRUE,
|
||||
&aGID, 1, &glyphMetrics, FALSE);
|
||||
|
||||
if (NS_SUCCEEDED(hr)) {
|
||||
width = NS_lround(glyphMetrics.advanceWidth * mFUnitsConvFactor) << 16;
|
||||
mGlyphWidths.Put(aGID, width);
|
||||
return width;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -79,6 +79,12 @@ public:
|
||||
// use DWrite API to get direct access to system font data
|
||||
virtual hb_blob_t *GetFontTable(PRUint32 aTag);
|
||||
|
||||
virtual PRBool ProvidesHintedWidths() const {
|
||||
return !mUsingClearType;
|
||||
}
|
||||
|
||||
virtual PRInt32 GetHintedGlyphWidth(gfxContext *aCtx, PRUint16 aGID);
|
||||
|
||||
protected:
|
||||
virtual void CreatePlatformShaper();
|
||||
|
||||
@ -95,8 +101,13 @@ protected:
|
||||
cairo_scaled_font_t *mCairoScaledFont;
|
||||
|
||||
gfxFont::Metrics mMetrics;
|
||||
PRBool mNeedsOblique;
|
||||
PRBool mNeedsBold;
|
||||
|
||||
// cache of glyph widths in 16.16 fixed-point pixels
|
||||
nsDataHashtable<nsUint32HashKey,PRInt32> mGlyphWidths;
|
||||
|
||||
PRPackedBool mNeedsOblique;
|
||||
PRPackedBool mNeedsBold;
|
||||
PRPackedBool mUsingClearType;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -175,24 +175,49 @@ trymoreglyphs:
|
||||
continue;
|
||||
}
|
||||
|
||||
hr = analyzer->GetGlyphPlacements(aString + range.start,
|
||||
clusters.Elements(),
|
||||
textProperties.Elements(),
|
||||
range.Length(),
|
||||
indices.Elements(),
|
||||
glyphProperties.Elements(),
|
||||
actualGlyphs,
|
||||
font->GetFontFace(),
|
||||
font->GetAdjustedSize(),
|
||||
FALSE,
|
||||
FALSE,
|
||||
&runHead->mScript,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
advances.Elements(),
|
||||
glyphOffsets.Elements());
|
||||
if (mFont->ProvidesHintedWidths()) {
|
||||
hr = analyzer->GetGdiCompatibleGlyphPlacements(
|
||||
aString + range.start,
|
||||
clusters.Elements(),
|
||||
textProperties.Elements(),
|
||||
range.Length(),
|
||||
indices.Elements(),
|
||||
glyphProperties.Elements(),
|
||||
actualGlyphs,
|
||||
font->GetFontFace(),
|
||||
font->GetAdjustedSize(),
|
||||
1.0,
|
||||
nsnull,
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE,
|
||||
&runHead->mScript,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
advances.Elements(),
|
||||
glyphOffsets.Elements());
|
||||
} else {
|
||||
hr = analyzer->GetGlyphPlacements(aString + range.start,
|
||||
clusters.Elements(),
|
||||
textProperties.Elements(),
|
||||
range.Length(),
|
||||
indices.Elements(),
|
||||
glyphProperties.Elements(),
|
||||
actualGlyphs,
|
||||
font->GetFontFace(),
|
||||
font->GetAdjustedSize(),
|
||||
FALSE,
|
||||
FALSE,
|
||||
&runHead->mScript,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
advances.Elements(),
|
||||
glyphOffsets.Elements());
|
||||
}
|
||||
if (FAILED(hr)) {
|
||||
NS_WARNING("Analyzer failed to get glyph placements.");
|
||||
result = PR_FALSE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user