DirectWrite to use aliased if ClearType is empty.
Some CJK fonts with some versions of DirectWrite return valid data for bitmaps, but not for cleartype data. For reference, two screenshots. M37 Stable and then with this patch: http://imgur.com/9pf3rB9,EiTb6Li See https://code.google.com/p/chromium/issues/detail?id=396624#c10 for content of test html file. R=eae@chromium.org, reed@google.com, shrikant@chromium.org, bungeman@chromium.org, cpu@chromium.org BUG=chromium:407945 Review URL: https://codereview.chromium.org/504343007
This commit is contained in:
parent
56fa442503
commit
b2f7fce9e0
@ -32,6 +32,7 @@ struct SkGlyph {
|
||||
void* fDistanceField;
|
||||
uint8_t fMaskFormat;
|
||||
int8_t fRsbDelta, fLsbDelta; // used by auto-kerning
|
||||
int8_t fForceBW;
|
||||
|
||||
void init(uint32_t id) {
|
||||
fID = id;
|
||||
@ -39,6 +40,7 @@ struct SkGlyph {
|
||||
fPath = NULL;
|
||||
fDistanceField = NULL;
|
||||
fMaskFormat = MASK_FORMAT_UNKNOWN;
|
||||
fForceBW = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -398,11 +398,11 @@ void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
|
||||
glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
|
||||
}
|
||||
|
||||
void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
||||
glyph->fWidth = 0;
|
||||
|
||||
this->generateAdvance(glyph);
|
||||
|
||||
void SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
|
||||
DWRITE_RENDERING_MODE renderingMode,
|
||||
DWRITE_TEXTURE_TYPE textureType,
|
||||
RECT* bbox)
|
||||
{
|
||||
//Measure raster size.
|
||||
fXform.dx = SkFixedToFloat(glyph->getSubXFixed());
|
||||
fXform.dy = SkFixedToFloat(glyph->getSubYFixed());
|
||||
@ -430,16 +430,41 @@ void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
||||
&run,
|
||||
1.0f, // pixelsPerDip,
|
||||
&fXform,
|
||||
fRenderingMode,
|
||||
renderingMode,
|
||||
fMeasuringMode,
|
||||
0.0f, // baselineOriginX,
|
||||
0.0f, // baselineOriginY,
|
||||
&glyphRunAnalysis),
|
||||
"Could not create glyph run analysis.");
|
||||
|
||||
RECT bbox;
|
||||
HRVM(glyphRunAnalysis->GetAlphaTextureBounds(fTextureType, &bbox),
|
||||
HRVM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox),
|
||||
"Could not get texture bounds.");
|
||||
}
|
||||
|
||||
void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
|
||||
glyph->fWidth = 0;
|
||||
|
||||
this->generateAdvance(glyph);
|
||||
|
||||
RECT bbox;
|
||||
this->getBoundingBox(glyph, fRenderingMode, fTextureType, &bbox);
|
||||
|
||||
// GetAlphaTextureBounds succeeds but returns an empty RECT if there are no
|
||||
// glyphs of the specified texture type. When this happens, try with the
|
||||
// alternate texture type.
|
||||
if (bbox.left == bbox.right || bbox.top == bbox.bottom) {
|
||||
if (DWRITE_TEXTURE_CLEARTYPE_3x1 == fTextureType) {
|
||||
this->getBoundingBox(glyph,
|
||||
DWRITE_RENDERING_MODE_ALIASED,
|
||||
DWRITE_TEXTURE_ALIASED_1x1,
|
||||
&bbox);
|
||||
if (bbox.left != bbox.right && bbox.top != bbox.bottom) {
|
||||
glyph->fForceBW = 1;
|
||||
}
|
||||
}
|
||||
// TODO: handle the case where a request for DWRITE_TEXTURE_ALIASED_1x1
|
||||
// fails, and try DWRITE_TEXTURE_CLEARTYPE_3x1.
|
||||
}
|
||||
|
||||
glyph->fWidth = SkToU16(bbox.right - bbox.left);
|
||||
glyph->fHeight = SkToU16(bbox.bottom - bbox.top);
|
||||
@ -602,9 +627,12 @@ static void rgb_to_lcd32(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
|
||||
}
|
||||
}
|
||||
|
||||
const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) {
|
||||
const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
|
||||
DWRITE_RENDERING_MODE renderingMode,
|
||||
DWRITE_TEXTURE_TYPE textureType)
|
||||
{
|
||||
int sizeNeeded = glyph.fWidth * glyph.fHeight;
|
||||
if (DWRITE_RENDERING_MODE_ALIASED != fRenderingMode) {
|
||||
if (DWRITE_RENDERING_MODE_ALIASED != renderingMode) {
|
||||
sizeNeeded *= 3;
|
||||
}
|
||||
if (sizeNeeded > fBits.count()) {
|
||||
@ -639,7 +667,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) {
|
||||
HRNM(fTypeface->fFactory->CreateGlyphRunAnalysis(&run,
|
||||
1.0f, // pixelsPerDip,
|
||||
&fXform,
|
||||
fRenderingMode,
|
||||
renderingMode,
|
||||
fMeasuringMode,
|
||||
0.0f, // baselineOriginX,
|
||||
0.0f, // baselineOriginY,
|
||||
@ -653,7 +681,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) {
|
||||
bbox.top = glyph.fTop;
|
||||
bbox.right = glyph.fLeft + glyph.fWidth;
|
||||
bbox.bottom = glyph.fTop + glyph.fHeight;
|
||||
HRNM(glyphRunAnalysis->CreateAlphaTexture(fTextureType,
|
||||
HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
|
||||
&bbox,
|
||||
fBits.begin(),
|
||||
sizeNeeded),
|
||||
@ -663,7 +691,13 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph) {
|
||||
|
||||
void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
|
||||
//Create the mask.
|
||||
const void* bits = this->drawDWMask(glyph);
|
||||
DWRITE_RENDERING_MODE renderingMode = fRenderingMode;
|
||||
DWRITE_TEXTURE_TYPE textureType = fTextureType;
|
||||
if (glyph.fForceBW) {
|
||||
renderingMode = DWRITE_RENDERING_MODE_ALIASED;
|
||||
textureType = DWRITE_TEXTURE_ALIASED_1x1;
|
||||
}
|
||||
const void* bits = this->drawDWMask(glyph, renderingMode, textureType);
|
||||
if (!bits) {
|
||||
sk_bzero(glyph.fImage, glyph.computeImageSize());
|
||||
return;
|
||||
@ -671,7 +705,7 @@ void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
|
||||
|
||||
//Copy the mask into the glyph.
|
||||
const uint8_t* src = (const uint8_t*)bits;
|
||||
if (DWRITE_RENDERING_MODE_ALIASED == fRenderingMode) {
|
||||
if (DWRITE_RENDERING_MODE_ALIASED == renderingMode) {
|
||||
bilevel_to_bw(src, glyph);
|
||||
const_cast<SkGlyph&>(glyph).fMaskFormat = SkMask::kBW_Format;
|
||||
} else if (!isLCD(fRec)) {
|
||||
|
@ -33,7 +33,14 @@ protected:
|
||||
virtual void generateFontMetrics(SkPaint::FontMetrics*) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
const void* drawDWMask(const SkGlyph& glyph);
|
||||
const void* drawDWMask(const SkGlyph& glyph,
|
||||
DWRITE_RENDERING_MODE renderingMode,
|
||||
DWRITE_TEXTURE_TYPE textureType);
|
||||
|
||||
void getBoundingBox(SkGlyph* glyph,
|
||||
DWRITE_RENDERING_MODE renderingMode,
|
||||
DWRITE_TEXTURE_TYPE textureType,
|
||||
RECT* bbox);
|
||||
|
||||
SkTDArray<uint8_t> fBits;
|
||||
/** The total matrix without the text height scale. */
|
||||
|
Loading…
Reference in New Issue
Block a user