зеркало из https://github.com/mozilla/gecko-dev.git
Bug 814101: Respect system-wide cleartype setting. r=jrmuizel,jfkthame
This commit is contained in:
Родитель
c2caba3ae9
Коммит
b084ef8c84
|
@ -73,7 +73,7 @@ struct DrawOptions {
|
|||
|
||||
Float mAlpha;
|
||||
CompositionOp mCompositionOp : 8;
|
||||
AntialiasMode mAntialiasMode : 2;
|
||||
AntialiasMode mAntialiasMode : 3;
|
||||
Snapping mSnapping : 1;
|
||||
};
|
||||
|
||||
|
|
|
@ -900,8 +900,15 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
|
|||
}
|
||||
}
|
||||
|
||||
AntialiasMode aaMode = font->GetDefaultAAMode();
|
||||
|
||||
if (aOptions.mAntialiasMode != AA_DEFAULT) {
|
||||
aaMode = aOptions.mAntialiasMode;
|
||||
}
|
||||
|
||||
if (mFormat == FORMAT_B8G8R8A8 && mPermitSubpixelAA &&
|
||||
aOptions.mCompositionOp == OP_OVER && aPattern.GetType() == PATTERN_COLOR) {
|
||||
aOptions.mCompositionOp == OP_OVER && aPattern.GetType() == PATTERN_COLOR &&
|
||||
aaMode == AA_SUBPIXEL) {
|
||||
if (FillGlyphsManual(font, aBuffer,
|
||||
static_cast<const ColorPattern*>(&aPattern)->mColor,
|
||||
params, aOptions)) {
|
||||
|
@ -913,6 +920,29 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
|
|||
|
||||
PrepareForDrawing(rt);
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE d2dAAMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
|
||||
|
||||
switch (aaMode) {
|
||||
case AA_NONE:
|
||||
d2dAAMode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
|
||||
break;
|
||||
case AA_GRAY:
|
||||
d2dAAMode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
|
||||
break;
|
||||
case AA_SUBPIXEL:
|
||||
d2dAAMode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
break;
|
||||
default:
|
||||
d2dAAMode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
|
||||
}
|
||||
|
||||
if (d2dAAMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE &&
|
||||
mFormat != FORMAT_B8G8R8X8) {
|
||||
d2dAAMode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
|
||||
}
|
||||
|
||||
rt->SetTextAntialiasMode(d2dAAMode);
|
||||
|
||||
if (rt != mRT || params != mTextRenderingParams) {
|
||||
rt->SetTextRenderingParams(params);
|
||||
if (rt == mRT) {
|
||||
|
|
|
@ -138,7 +138,80 @@ public:
|
|||
private:
|
||||
std::vector<uint8_t> mData;
|
||||
uint32_t mRefCnt;
|
||||
};
|
||||
};
|
||||
|
||||
static BYTE
|
||||
GetSystemTextQuality()
|
||||
{
|
||||
BOOL font_smoothing;
|
||||
UINT smoothing_type;
|
||||
|
||||
if (!SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &font_smoothing, 0)) {
|
||||
return DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
if (font_smoothing) {
|
||||
if (!SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE,
|
||||
0, &smoothing_type, 0)) {
|
||||
return DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
if (smoothing_type == FE_FONTSMOOTHINGCLEARTYPE) {
|
||||
return CLEARTYPE_QUALITY;
|
||||
}
|
||||
|
||||
return ANTIALIASED_QUALITY;
|
||||
}
|
||||
|
||||
return DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
#define GASP_TAG 0x70736167
|
||||
#define GASP_DOGRAY 0x2
|
||||
|
||||
static inline unsigned short
|
||||
readShort(const char *aBuf)
|
||||
{
|
||||
return (*aBuf << 8) | *(aBuf + 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
DoGrayscale(IDWriteFontFace *aDWFace, unsigned int ppem)
|
||||
{
|
||||
void *tableContext;
|
||||
char *tableData;
|
||||
UINT32 tableSize;
|
||||
BOOL exists;
|
||||
aDWFace->TryGetFontTable(GASP_TAG, (const void**)&tableData, &tableSize, &tableContext, &exists);
|
||||
|
||||
if (exists) {
|
||||
if (tableSize < 4) {
|
||||
aDWFace->ReleaseFontTable(tableContext);
|
||||
return true;
|
||||
}
|
||||
struct gaspRange {
|
||||
unsigned short maxPPEM; // Stored big-endian
|
||||
unsigned short behavior; // Stored big-endian
|
||||
};
|
||||
unsigned short numRanges = readShort(tableData + 2);
|
||||
if (tableSize < (UINT)4 + numRanges * 4) {
|
||||
aDWFace->ReleaseFontTable(tableContext);
|
||||
return true;
|
||||
}
|
||||
gaspRange *ranges = (gaspRange *)(tableData + 4);
|
||||
for (int i = 0; i < numRanges; i++) {
|
||||
if (readShort((char*)&ranges[i].maxPPEM) > ppem) {
|
||||
if (!(readShort((char*)&ranges[i].behavior) & GASP_DOGRAY)) {
|
||||
aDWFace->ReleaseFontTable(tableContext);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
aDWFace->ReleaseFontTable(tableContext);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
IDWriteFontFileLoader* DWriteFontFileLoader::mInstance = NULL;
|
||||
|
||||
|
@ -322,5 +395,30 @@ ScaledFontDWrite::GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton
|
|||
return true;
|
||||
}
|
||||
|
||||
AntialiasMode
|
||||
ScaledFontDWrite::GetDefaultAAMode()
|
||||
{
|
||||
AntialiasMode defaultMode = AA_SUBPIXEL;
|
||||
|
||||
switch (GetSystemTextQuality()) {
|
||||
case CLEARTYPE_QUALITY:
|
||||
defaultMode = AA_SUBPIXEL;
|
||||
break;
|
||||
case ANTIALIASED_QUALITY:
|
||||
defaultMode = AA_GRAY;
|
||||
break;
|
||||
case DEFAULT_QUALITY:
|
||||
defaultMode = AA_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (defaultMode == AA_GRAY) {
|
||||
if (!DoGrayscale(mFontFace, mSize)) {
|
||||
defaultMode = AA_NONE;
|
||||
}
|
||||
}
|
||||
return defaultMode;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ public:
|
|||
|
||||
virtual bool GetFontFileData(FontFileDataOutput aDataCallback, void *aBaton);
|
||||
|
||||
virtual AntialiasMode GetDefaultAAMode();
|
||||
|
||||
#ifdef USE_SKIA
|
||||
virtual SkTypeface* GetSkTypeface()
|
||||
{
|
||||
|
|
|
@ -87,7 +87,7 @@ enum FontStyle
|
|||
enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST_IN, OP_DEST_OUT, OP_DEST_OVER, OP_DEST_ATOP, OP_XOR, OP_COUNT };
|
||||
enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
|
||||
enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
|
||||
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL };
|
||||
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT };
|
||||
enum Snapping { SNAP_NONE, SNAP_ALIGNED };
|
||||
enum Filter { FILTER_LINEAR, FILTER_POINT };
|
||||
enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
|
||||
|
|
|
@ -1577,6 +1577,19 @@ struct GlyphBuffer {
|
|||
#undef GLYPH_BUFFER_SIZE
|
||||
};
|
||||
|
||||
static AntialiasMode Get2DAAMode(gfxFont::AntialiasOption aAAOption) {
|
||||
switch (aAAOption) {
|
||||
case gfxFont::kAntialiasSubpixel:
|
||||
return AA_SUBPIXEL;
|
||||
case gfxFont::kAntialiasGrayscale:
|
||||
return AA_GRAY;
|
||||
case gfxFont::kAntialiasNone:
|
||||
return AA_NONE;
|
||||
default:
|
||||
return AA_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
struct GlyphBufferAzure {
|
||||
#define GLYPH_BUFFER_SIZE (2048/sizeof(Glyph))
|
||||
Glyph mGlyphBuffer[GLYPH_BUFFER_SIZE];
|
||||
|
@ -1591,7 +1604,8 @@ struct GlyphBufferAzure {
|
|||
|
||||
void Flush(DrawTarget *aDT, gfxTextObjectPaint *aObjectPaint, ScaledFont *aFont,
|
||||
gfxFont::DrawMode aDrawMode, bool aReverse, const GlyphRenderingOptions *aOptions,
|
||||
gfxContext *aThebesContext, const Matrix *aInvFontMatrix, bool aFinish = false)
|
||||
gfxContext *aThebesContext, const Matrix *aInvFontMatrix, const DrawOptions &aDrawOptions,
|
||||
bool aFinish = false)
|
||||
{
|
||||
// Ensure there's enough room for a glyph to be added to the buffer
|
||||
if ((!aFinish && mNumGlyphs < GLYPH_BUFFER_SIZE) || !mNumGlyphs) {
|
||||
|
@ -1645,7 +1659,7 @@ struct GlyphBufferAzure {
|
|||
}
|
||||
|
||||
aDT->FillGlyphs(aFont, buf, *pat,
|
||||
DrawOptions(), aOptions);
|
||||
aDrawOptions, aOptions);
|
||||
|
||||
if (mat) {
|
||||
*mat = saved;
|
||||
|
@ -1654,10 +1668,10 @@ struct GlyphBufferAzure {
|
|||
aDT->FillGlyphs(aFont, buf, SurfacePattern(state.sourceSurface,
|
||||
EXTEND_CLAMP,
|
||||
state.surfTransform),
|
||||
DrawOptions(), aOptions);
|
||||
aDrawOptions, aOptions);
|
||||
} else {
|
||||
aDT->FillGlyphs(aFont, buf, ColorPattern(state.color),
|
||||
DrawOptions(), aOptions);
|
||||
aDrawOptions, aOptions);
|
||||
}
|
||||
}
|
||||
if (aDrawMode & gfxFont::GLYPH_PATH) {
|
||||
|
@ -1930,6 +1944,9 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
RefPtr<GlyphRenderingOptions> renderingOptions =
|
||||
GetGlyphRenderingOptions();
|
||||
|
||||
DrawOptions drawOptions;
|
||||
drawOptions.mAntialiasMode = Get2DAAMode(mAntialiasOption);
|
||||
|
||||
if (mScaledFont) {
|
||||
cairo_matrix_t matrix;
|
||||
cairo_scaled_font_get_font_matrix(mScaledFont, &matrix);
|
||||
|
@ -1992,7 +2009,8 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
glyph->mPosition = matInv * glyph->mPosition;
|
||||
glyphs.Flush(dt, aObjectPaint, scaledFont,
|
||||
aDrawMode, isRTL, renderingOptions,
|
||||
aContext, passedInvMatrix);
|
||||
aContext, passedInvMatrix,
|
||||
drawOptions);
|
||||
|
||||
// synthetic bolding by multi-striking with 1-pixel offsets
|
||||
// at least once, more if there's room (large font sizes)
|
||||
|
@ -2011,7 +2029,8 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
strikeOffset += synBoldOnePixelOffset;
|
||||
glyphs.Flush(dt, aObjectPaint, scaledFont,
|
||||
aDrawMode, isRTL, renderingOptions,
|
||||
aContext, passedInvMatrix);
|
||||
aContext, passedInvMatrix,
|
||||
drawOptions);
|
||||
} while (--strikeCount > 0);
|
||||
}
|
||||
} else {
|
||||
|
@ -2057,7 +2076,8 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
glyph->mPosition.y = ToDeviceUnits(y + details->mYOffset, devUnitsPerAppUnit);
|
||||
glyph->mPosition = matInv * glyph->mPosition;
|
||||
glyphs.Flush(dt, aObjectPaint, scaledFont, aDrawMode,
|
||||
isRTL, renderingOptions, aContext, passedInvMatrix);
|
||||
isRTL, renderingOptions, aContext, passedInvMatrix,
|
||||
drawOptions);
|
||||
|
||||
if (IsSyntheticBold()) {
|
||||
double strikeOffset = synBoldOnePixelOffset;
|
||||
|
@ -2075,7 +2095,7 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
doubleglyph->mPosition = matInv * doubleglyph->mPosition;
|
||||
glyphs.Flush(dt, aObjectPaint, scaledFont,
|
||||
aDrawMode, isRTL, renderingOptions,
|
||||
aContext, passedInvMatrix);
|
||||
aContext, passedInvMatrix, drawOptions);
|
||||
} while (--strikeCount > 0);
|
||||
}
|
||||
}
|
||||
|
@ -2095,7 +2115,8 @@ gfxFont::Draw(gfxTextRun *aTextRun, uint32_t aStart, uint32_t aEnd,
|
|||
}
|
||||
|
||||
glyphs.Flush(dt, aObjectPaint, scaledFont, aDrawMode, isRTL,
|
||||
renderingOptions, aContext, passedInvMatrix, true);
|
||||
renderingOptions, aContext, passedInvMatrix,
|
||||
drawOptions, true);
|
||||
|
||||
dt->SetTransform(oldMat);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче