DirectWrite to detect GDI only fonts.
The exist a number of webfonts which have poor hinting which look very bad with any vertical subsampling. The fonts often rely on drop out control to avoid zero coverage in the y direction. As a result, any font with hints but no 'gasp' table is considered to be poorly hinted in this way, and will not be rendered with vertical subsampling when hinted. R=eae@chromium.org, reed@google.com, mtklein@google.com Author: bungeman@google.com Review URL: https://codereview.chromium.org/363433002
This commit is contained in:
parent
26337e9702
commit
761b2509d5
@ -18,6 +18,7 @@
|
||||
#include "SkOTTable_EBLC.h"
|
||||
#include "SkOTTable_EBSC.h"
|
||||
#include "SkOTTable_gasp.h"
|
||||
#include "SkOTTable_maxp.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkScalerContext.h"
|
||||
#include "SkScalerContext_win_dw.h"
|
||||
@ -31,6 +32,27 @@ static bool isLCD(const SkScalerContext::Rec& rec) {
|
||||
SkMask::kLCD32_Format == rec.fMaskFormat;
|
||||
}
|
||||
|
||||
static bool is_hinted_without_gasp(DWriteFontTypeface* typeface) {
|
||||
AutoTDWriteTable<SkOTTableMaximumProfile> maxp(typeface->fDWriteFontFace.get());
|
||||
if (!maxp.fExists) {
|
||||
return false;
|
||||
}
|
||||
if (maxp.fSize < sizeof(SkOTTableMaximumProfile::Version::TT)) {
|
||||
return false;
|
||||
}
|
||||
if (maxp->version.version != SkOTTableMaximumProfile::Version::TT::VERSION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 == maxp->version.tt.maxSizeOfInstructions) {
|
||||
// No hints.
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoTDWriteTable<SkOTTableGridAndScanProcedure> gasp(typeface->fDWriteFontFace.get());
|
||||
return !gasp.fExists;
|
||||
}
|
||||
|
||||
/** A PPEMRange is inclusive, [min, max]. */
|
||||
struct PPEMRange {
|
||||
int min;
|
||||
@ -254,6 +276,17 @@ SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
|
||||
fTextSizeMeasure = gdiTextSize;
|
||||
fMeasuringMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
|
||||
|
||||
// Fonts that have hints but no gasp table get non-symmetric rendering.
|
||||
// Usually such fonts have low quality hints which were never tested
|
||||
// with anything but GDI ClearType classic. Such fonts often rely on
|
||||
// drop out control in the y direction in order to be legible.
|
||||
} else if (is_hinted_without_gasp(typeface)) {
|
||||
fTextSizeRender = gdiTextSize;
|
||||
fRenderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
|
||||
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
|
||||
fTextSizeMeasure = realTextSize;
|
||||
fMeasuringMode = DWRITE_MEASURING_MODE_NATURAL;
|
||||
|
||||
// The normal case is to use natural symmetric rendering and linear metrics.
|
||||
} else {
|
||||
fTextSizeRender = realTextSize;
|
||||
@ -354,6 +387,9 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
|
||||
if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
|
||||
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
|
||||
{
|
||||
// DirectWrite produced 'compatible' metrics, but while close,
|
||||
// the end result is not always an integer as it would be with GDI.
|
||||
vecs[0].fX = SkScalarRoundToScalar(advanceX);
|
||||
fG_inv.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
|
||||
} else {
|
||||
fSkXform.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
|
||||
|
Loading…
Reference in New Issue
Block a user