Flutter Engine
The Flutter Engine
SDFTControl.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
10#include "include/core/SkFont.h"
15#include "src/core/SkFontPriv.h"
16#include "src/core/SkGlyph.h"
19
20#include <tuple>
21
22struct SkPoint;
23
24namespace sktext::gpu {
25
26#if !defined(SK_DISABLE_SDF_TEXT)
27// DF sizes and thresholds for usage of the small and medium sizes. For example, above
28// kSmallDFFontLimit we will use the medium size. The large size is used up until the size at
29// which we switch over to drawing as paths as controlled by Control.
30static const int kSmallDFFontLimit = 32;
31static const int kMediumDFFontLimit = 72;
32static const int kLargeDFFontLimit = 162;
33#ifdef SK_BUILD_FOR_MAC
34static const int kExtraLargeDFFontLimit = 256;
35#endif
36
37SkScalar SDFTControl::MinSDFTRange(bool useSDFTForSmallText, SkScalar min) {
38 if (!useSDFTForSmallText) {
39 return kLargeDFFontLimit;
40 }
41 return min;
42}
43
45 bool ableToUseSDFT, bool useSDFTForSmallText, bool useSDFTForPerspectiveText,
47 : fMinDistanceFieldFontSize{MinSDFTRange(useSDFTForSmallText, min)}
48 , fMaxDistanceFieldFontSize{max}
49 , fAbleToUseSDFT{ableToUseSDFT}
50 , fAbleToUsePerspectiveSDFT{useSDFTForPerspectiveText} {
51 SkASSERT_RELEASE(0 < min && min <= max);
52}
53#endif // !defined(SK_DISABLE_SDF_TEXT)
54
55bool SDFTControl::isDirect(SkScalar approximateDeviceTextSize, const SkPaint& paint,
56 const SkMatrix& matrix) const {
57#if !defined(SK_DISABLE_SDF_TEXT)
58 const bool isSDFT = this->isSDFT(approximateDeviceTextSize, paint, matrix);
59#else
60 const bool isSDFT = false;
61#endif
62 return !isSDFT &&
63 !matrix.hasPerspective() &&
64 0 < approximateDeviceTextSize &&
65 approximateDeviceTextSize < SkGlyphDigest::kSkSideTooBigForAtlas;
66}
67
68#if !defined(SK_DISABLE_SDF_TEXT)
69bool SDFTControl::isSDFT(SkScalar approximateDeviceTextSize, const SkPaint& paint,
70 const SkMatrix& matrix) const {
71 const bool wideStroke = paint.getStyle() == SkPaint::kStroke_Style &&
72 paint.getStrokeWidth() > 0;
73 return fAbleToUseSDFT &&
74 paint.getMaskFilter() == nullptr &&
75 (paint.getStyle() == SkPaint::kFill_Style || wideStroke) &&
76 0 < approximateDeviceTextSize &&
77 (fAbleToUsePerspectiveSDFT || !matrix.hasPerspective()) &&
78 (fMinDistanceFieldFontSize <= approximateDeviceTextSize || matrix.hasPerspective()) &&
79 approximateDeviceTextSize <= fMaxDistanceFieldFontSize;
80}
81
82std::tuple<SkFont, SkScalar, SDFTMatrixRange>
83SDFTControl::getSDFFont(const SkFont& font, const SkMatrix& viewMatrix,
84 const SkPoint& textLoc) const {
85 SkScalar textSize = font.getSize();
86 SkScalar scaledTextSize = SkFontPriv::ApproximateTransformedTextSize(font, viewMatrix, textLoc);
87 if (scaledTextSize <= 0 || SkScalarNearlyEqual(textSize, scaledTextSize)) {
88 scaledTextSize = textSize;
89 }
90
91 SkFont dfFont{font};
92
93 SkScalar dfMaskScaleFloor;
94 SkScalar dfMaskScaleCeil;
95 SkScalar dfMaskSize;
96 if (scaledTextSize <= kSmallDFFontLimit) {
97 dfMaskScaleFloor = fMinDistanceFieldFontSize;
98 dfMaskScaleCeil = kSmallDFFontLimit;
99 dfMaskSize = kSmallDFFontLimit;
100 } else if (scaledTextSize <= kMediumDFFontLimit) {
101 dfMaskScaleFloor = kSmallDFFontLimit;
102 dfMaskScaleCeil = kMediumDFFontLimit;
103 dfMaskSize = kMediumDFFontLimit;
104#ifdef SK_BUILD_FOR_MAC
105 } else if (scaledTextSize <= kLargeDFFontLimit) {
106 dfMaskScaleFloor = kMediumDFFontLimit;
107 dfMaskScaleCeil = kLargeDFFontLimit;
108 dfMaskSize = kLargeDFFontLimit;
109 } else {
110 dfMaskScaleFloor = kLargeDFFontLimit;
111 dfMaskScaleCeil = fMaxDistanceFieldFontSize;
112 dfMaskSize = kExtraLargeDFFontLimit;
113 }
114#else
115 } else {
116 dfMaskScaleFloor = kMediumDFFontLimit;
117 dfMaskScaleCeil = fMaxDistanceFieldFontSize;
118 dfMaskSize = kLargeDFFontLimit;
119 }
120#endif
121
122 dfFont.setSize(dfMaskSize);
123 dfFont.setEdging(SkFont::Edging::kAntiAlias);
124 dfFont.setForceAutoHinting(false);
125 dfFont.setHinting(SkFontHinting::kNormal);
126
127 // The sub-pixel position will always happen when transforming to the screen.
128 dfFont.setSubpixel(false);
129
130 SkScalar minMatrixScale = dfMaskScaleFloor / textSize,
131 maxMatrixScale = dfMaskScaleCeil / textSize;
132 return {dfFont, textSize / dfMaskSize, {minMatrixScale, maxMatrixScale}};
133}
134
135bool SDFTMatrixRange::matrixInRange(const SkMatrix& matrix) const {
136 SkScalar maxScale = matrix.getMaxScale();
137 return fMatrixMin < maxScale && maxScale <= fMatrixMax;
138}
139
140void SDFTMatrixRange::flatten(SkWriteBuffer& buffer) const {
141 buffer.writeScalar(fMatrixMin);
142 buffer.writeScalar(fMatrixMax);
143}
144
145SDFTMatrixRange SDFTMatrixRange::MakeFromBuffer(SkReadBuffer& buffer) {
146 SkScalar min = buffer.readScalar();
147 SkScalar max = buffer.readScalar();
148 return SDFTMatrixRange{min, max};
149}
150#endif // !defined(SK_DISABLE_SDF_TEXT)
151
152} // namespace sktext::gpu
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
@ kNormal
glyph outlines modified to improve constrast
static bool SkScalarNearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance=SK_ScalarNearlyZero)
Definition: SkScalar.h:107
static SkScalar ApproximateTransformedTextSize(const SkFont &font, const SkMatrix &matrix, const SkPoint &textLocation)
Definition: SkFont.cpp:366
Definition: SkFont.h:35
@ kAntiAlias
may have transparent pixels on glyph edges
static constexpr uint16_t kSkSideTooBigForAtlas
Definition: SkGlyph.h:333
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
std::tuple< SkFont, SkScalar, SDFTMatrixRange > getSDFFont(const SkFont &font, const SkMatrix &viewMatrix, const SkPoint &textLocation) const
Definition: SDFTControl.cpp:83
bool isSDFT(SkScalar approximateDeviceTextSize, const SkPaint &paint, const SkMatrix &matrix) const
Definition: SDFTControl.cpp:69
SDFTControl(bool ableToUseSDFT, bool useSDFTForSmallText, bool useSDFTForPerspectiveText, SkScalar min, SkScalar max)
Definition: SDFTControl.cpp:44
bool isDirect(SkScalar approximateDeviceTextSize, const SkPaint &paint, const SkMatrix &matrix) const
Definition: SDFTControl.cpp:55
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
font
Font Metadata and Metrics.
static const int kMediumDFFontLimit
Definition: SDFTControl.cpp:31
static const int kSmallDFFontLimit
Definition: SDFTControl.cpp:30
static const int kLargeDFFontLimit
Definition: SDFTControl.cpp:32