Draw perspective text as paths.

Perspective glyphs can vary in screen size so it's unclear which SDF
level is best, and even if we choose one for an entire subrun it's
possible that a given glyph will have artifacts if it's too big.
Instead we fall back to paths.

Bug: skia:9515
Change-Id: I88f03b25651df0222459f5dbd03eee9465b97487
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/247437
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
Jim Van Verth 2019-10-09 15:11:56 -04:00 committed by Skia Commit-Bot
parent 7951a0da32
commit 76826fc91c
3 changed files with 31 additions and 34 deletions

View File

@ -181,6 +181,7 @@ SkStrikeSpec::MakeSDFT(const SkFont& font, const SkPaint& paint,
const SkSurfaceProps& surfaceProps, const SkMatrix& deviceMatrix, const SkSurfaceProps& surfaceProps, const SkMatrix& deviceMatrix,
const GrTextContext::Options& options) { const GrTextContext::Options& options) {
SkStrikeSpec storage; SkStrikeSpec storage;
SkASSERT(!deviceMatrix.hasPerspective());
SkPaint dfPaint = GrTextContext::InitDistanceFieldPaint(paint); SkPaint dfPaint = GrTextContext::InitDistanceFieldPaint(paint);
SkFont dfFont = GrTextContext::InitDistanceFieldFont( SkFont dfFont = GrTextContext::InitDistanceFieldFont(

View File

@ -95,24 +95,8 @@ bool GrTextContext::CanDrawAsDistanceFields(const SkPaint& paint, const SkFont&
const SkSurfaceProps& props, const SkSurfaceProps& props,
bool contextSupportsDistanceFieldText, bool contextSupportsDistanceFieldText,
const Options& options) { const Options& options) {
if (!viewMatrix.hasPerspective()) { if (viewMatrix.hasPerspective()) {
SkScalar maxScale = viewMatrix.getMaxScale(); return false;
SkScalar scaledTextSize = maxScale * font.getSize();
// Hinted text looks far better at small resolutions
// Scaling up beyond 2x yields undesireable artifacts
if (scaledTextSize < options.fMinDistanceFieldFontSize ||
scaledTextSize > options.fMaxDistanceFieldFontSize) {
return false;
}
bool useDFT = props.isUseDeviceIndependentFonts();
#if SK_FORCE_DISTANCE_FIELD_TEXT
useDFT = true;
#endif
if (!useDFT && scaledTextSize < kLargeDFFontSize) {
return false;
}
} }
// mask filters modify alpha, which doesn't translate well to distance // mask filters modify alpha, which doesn't translate well to distance
@ -125,24 +109,38 @@ bool GrTextContext::CanDrawAsDistanceFields(const SkPaint& paint, const SkFont&
return false; return false;
} }
SkScalar maxScale = viewMatrix.getMaxScale();
SkScalar scaledTextSize = maxScale * font.getSize();
// Hinted text looks far better at small resolutions
// Scaling up beyond 2x yields undesirable artifacts
if (scaledTextSize < options.fMinDistanceFieldFontSize ||
scaledTextSize > options.fMaxDistanceFieldFontSize) {
return false;
}
bool useDFT = props.isUseDeviceIndependentFonts();
#if SK_FORCE_DISTANCE_FIELD_TEXT
useDFT = true;
#endif
if (!useDFT && scaledTextSize < kLargeDFFontSize) {
return false;
}
return true; return true;
} }
SkScalar scaled_text_size(const SkScalar textSize, const SkMatrix& viewMatrix) { SkScalar scaled_text_size(const SkScalar textSize, const SkMatrix& viewMatrix) {
SkASSERT(!viewMatrix.hasPerspective());
SkScalar scaledTextSize = textSize; SkScalar scaledTextSize = textSize;
if (viewMatrix.hasPerspective()) { SkScalar maxScale = viewMatrix.getMaxScale();
// for perspective, we simply force to the medium size // if we have non-unity scale, we need to choose our base text size
// TODO: compute a size based on approximate screen area // based on the SkPaint's text size multiplied by the max scale factor
scaledTextSize = kMediumDFFontLimit; // TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
} else { if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
SkScalar maxScale = viewMatrix.getMaxScale(); scaledTextSize *= maxScale;
// if we have non-unity scale, we need to choose our base text size
// based on the SkPaint's text size multiplied by the max scale factor
// TODO: do we need to do this if we're scaling down (i.e. maxScale < 1)?
if (maxScale > 0 && !SkScalarNearlyEqual(maxScale, SK_Scalar1)) {
scaledTextSize *= maxScale;
}
} }
return scaledTextSize; return scaledTextSize;

View File

@ -678,10 +678,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRemoteGlyphCache_DrawTextAsDFT, reporter, c
SkPaint paint; SkPaint paint;
SkFont font; SkFont font;
// A perspective transform forces fallback to dft. // A scale transform forces fallback to dft.
SkMatrix matrix = SkMatrix::I(); SkMatrix matrix = SkMatrix::MakeScale(16);
matrix[SkMatrix::kMPersp0] = 0.5f;
REPORTER_ASSERT(reporter, matrix.hasPerspective());
SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry); SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
GrTextContext::Options options; GrTextContext::Options options;
GrTextContext::SanitizeOptions(&options); GrTextContext::SanitizeOptions(&options);