Fix SkScalerContext_FreeType::generateFontMetrics.
SkScalerContext::generateFontMetrics implementations should not attempt to take into account skew. This implementation should correctly handle bitmap fonts as well. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2165323002 Review-Url: https://codereview.chromium.org/2165323002
This commit is contained in:
parent
dfe4f2e4fe
commit
5379051ee7
@ -77,16 +77,19 @@ protected:
|
||||
const char* text = emojiFont.text;
|
||||
|
||||
// draw text at different point sizes
|
||||
const int textSize[] = { 10, 30, 50, };
|
||||
const int textYOffset[] = { 10, 40, 100, };
|
||||
SkASSERT(sizeof(textSize) == sizeof(textYOffset));
|
||||
size_t y_offset = 0;
|
||||
for (size_t y = 0; y < sizeof(textSize) / sizeof(int); y++) {
|
||||
paint.setTextSize(SkIntToScalar(textSize[y]));
|
||||
canvas->drawText(text, strlen(text), 10, SkIntToScalar(textYOffset[y]), paint);
|
||||
y_offset += textYOffset[y];
|
||||
static constexpr SkScalar textSizes[] = { 10, 30, 50, };
|
||||
SkPaint::FontMetrics metrics;
|
||||
SkScalar y = 0;
|
||||
for (const SkScalar& textSize : textSizes) {
|
||||
paint.setTextSize(textSize);
|
||||
paint.getFontMetrics(&metrics);
|
||||
y += -metrics.fAscent;
|
||||
canvas->drawText(text, strlen(text), 10, y, paint);
|
||||
y += metrics.fDescent + metrics.fLeading;
|
||||
}
|
||||
|
||||
y += 20;
|
||||
SkScalar savedY = y;
|
||||
// draw with shaders and image filters
|
||||
for (int makeLinear = 0; makeLinear < 2; makeLinear++) {
|
||||
for (int makeBlur = 0; makeBlur < 2; makeBlur++) {
|
||||
@ -107,15 +110,15 @@ protected:
|
||||
shaderPaint.setImageFilter(make_grayscale(nullptr));
|
||||
}
|
||||
shaderPaint.setTextSize(30);
|
||||
canvas->drawText(text, strlen(text), 380, SkIntToScalar(y_offset),
|
||||
shaderPaint);
|
||||
y_offset += 32;
|
||||
shaderPaint.getFontMetrics(&metrics);
|
||||
y += -metrics.fAscent;
|
||||
canvas->drawText(text, strlen(text), 380, y, shaderPaint);
|
||||
y += metrics.fDescent + metrics.fLeading;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setup work needed to draw text with different clips
|
||||
canvas->translate(10, 160);
|
||||
canvas->translate(10, savedY);
|
||||
paint.setTextSize(40);
|
||||
|
||||
// compute the bounds of the text
|
||||
@ -134,22 +137,23 @@ protected:
|
||||
SkRect interiorClip = bounds;
|
||||
interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight);
|
||||
|
||||
const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip };
|
||||
static const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip };
|
||||
|
||||
SkPaint clipHairline;
|
||||
clipHairline.setColor(SK_ColorWHITE);
|
||||
clipHairline.setStyle(SkPaint::kStroke_Style);
|
||||
|
||||
for (size_t x = 0; x < sizeof(clipRects) / sizeof(SkRect); ++x) {
|
||||
for (const SkRect& clipRect : clipRects) {
|
||||
canvas->translate(0, bounds.height());
|
||||
canvas->save();
|
||||
canvas->drawRect(clipRects[x], clipHairline);
|
||||
canvas->drawRect(clipRect, clipHairline);
|
||||
paint.setAlpha(0x20);
|
||||
canvas->drawText(text, strlen(text), 0, 0, paint);
|
||||
canvas->clipRect(clipRects[x]);
|
||||
canvas->clipRect(clipRect);
|
||||
paint.setAlpha(0xFF);
|
||||
canvas->drawText(text, strlen(text), 0, 0, paint);
|
||||
canvas->restore();
|
||||
canvas->translate(0, bounds.height() + SkIntToScalar(25));
|
||||
canvas->translate(0, SkIntToScalar(25));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1315,10 +1315,6 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
|
||||
}
|
||||
|
||||
FT_Face face = fFace;
|
||||
SkScalar scaleX = fScale.x();
|
||||
SkScalar scaleY = fScale.y();
|
||||
SkScalar mxy = -fMatrix22Scalar.getSkewX() * scaleY;
|
||||
SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY;
|
||||
|
||||
// fetch units/EM from "head" table if needed (ie for bitmap fonts)
|
||||
SkScalar upem = SkIntToScalar(face->units_per_EM);
|
||||
@ -1335,10 +1331,10 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
|
||||
SkScalar cap_height = 0.0f;
|
||||
TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
|
||||
if (os2) {
|
||||
x_height = scaleX * SkIntToScalar(os2->sxHeight) / upem;
|
||||
x_height = SkIntToScalar(os2->sxHeight) / upem * fScale.y();
|
||||
avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem;
|
||||
if (os2->version != 0xFFFF && os2->version >= 2) {
|
||||
cap_height = scaleX * SkIntToScalar(os2->sCapHeight) / upem;
|
||||
cap_height = SkIntToScalar(os2->sCapHeight) / upem * fScale.y();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1389,8 +1385,7 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
|
||||
SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem);
|
||||
ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f);
|
||||
descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f);
|
||||
leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f))
|
||||
+ ascent - descent;
|
||||
leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f)) + ascent - descent;
|
||||
xmin = 0.0f;
|
||||
xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
|
||||
ymin = descent + leading;
|
||||
@ -1407,13 +1402,13 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
|
||||
|
||||
// synthesize elements that were not provided by the os/2 table or format-specific metrics
|
||||
if (!x_height) {
|
||||
x_height = -ascent;
|
||||
x_height = -ascent * fScale.y();
|
||||
}
|
||||
if (!avgCharWidth) {
|
||||
avgCharWidth = xmax - xmin;
|
||||
}
|
||||
if (!cap_height) {
|
||||
cap_height = -ascent;
|
||||
cap_height = -ascent * fScale.y();
|
||||
}
|
||||
|
||||
// disallow negative linespacing
|
||||
@ -1421,22 +1416,18 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* metrics
|
||||
leading = 0.0f;
|
||||
}
|
||||
|
||||
SkScalar scale = myy;
|
||||
if (this->isVertical()) {
|
||||
scale = mxy;
|
||||
}
|
||||
metrics->fTop = ymax * scale;
|
||||
metrics->fAscent = ascent * scale;
|
||||
metrics->fDescent = descent * scale;
|
||||
metrics->fBottom = ymin * scale;
|
||||
metrics->fLeading = leading * scale;
|
||||
metrics->fAvgCharWidth = avgCharWidth * scale;
|
||||
metrics->fXMin = xmin * scale;
|
||||
metrics->fXMax = xmax * scale;
|
||||
metrics->fTop = ymax * fScale.y();
|
||||
metrics->fAscent = ascent * fScale.y();
|
||||
metrics->fDescent = descent * fScale.y();
|
||||
metrics->fBottom = ymin * fScale.y();
|
||||
metrics->fLeading = leading * fScale.y();
|
||||
metrics->fAvgCharWidth = avgCharWidth * fScale.y();
|
||||
metrics->fXMin = xmin * fScale.y();
|
||||
metrics->fXMax = xmax * fScale.y();
|
||||
metrics->fXHeight = x_height;
|
||||
metrics->fCapHeight = cap_height;
|
||||
metrics->fUnderlineThickness = underlineThickness * scale;
|
||||
metrics->fUnderlinePosition = underlinePosition * scale;
|
||||
metrics->fUnderlineThickness = underlineThickness * fScale.y();
|
||||
metrics->fUnderlinePosition = underlinePosition * fScale.y();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user