Skip to content

Commit 0aaa84e

Browse files
bderodnfield
authored andcommitted
Render glyphs at the correct resolution with respect to the current transform (flutter#101)
1 parent 39f4ebd commit 0aaa84e

File tree

12 files changed

+93
-24
lines changed

12 files changed

+93
-24
lines changed

impeller/display_list/display_list_dispatcher.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,8 @@ void DisplayListDispatcher::setMaskFilter(const flutter::DlMaskFilter* filter) {
247247
}
248248

249249
// |flutter::Dispatcher|
250-
void DisplayListDispatcher::setImageFilter(const flutter::DlImageFilter* filter) {
250+
void DisplayListDispatcher::setImageFilter(
251+
const flutter::DlImageFilter* filter) {
251252
UNIMPLEMENTED;
252253
}
253254

@@ -609,9 +610,10 @@ void DisplayListDispatcher::drawDisplayList(
609610
void DisplayListDispatcher::drawTextBlob(const sk_sp<SkTextBlob> blob,
610611
SkScalar x,
611612
SkScalar y) {
612-
canvas_.DrawTextFrame(TextFrameFromTextBlob(blob), //
613-
impeller::Point{x, y}, //
614-
paint_ //
613+
Scalar scale = canvas_.GetCurrentTransformation().GetMaxBasisLength();
614+
canvas_.DrawTextFrame(TextFrameFromTextBlob(blob, scale), //
615+
impeller::Point{x, y}, //
616+
paint_ //
615617
);
616618
}
617619

impeller/geometry/constants.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,7 @@ constexpr float kSqrt2 = 1.41421356237309504880;
4343
// 1/sqrt(2)
4444
constexpr float k1OverSqrt2 = 0.70710678118654752440;
4545

46+
// 0.001
47+
constexpr float kEhCloseEnough = 1e-3;
48+
4649
} // namespace impeller

impeller/geometry/geometry_unittests.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,21 @@ TEST(GeometryTest, MatrixTransformDirection) {
212212
}
213213
}
214214

215+
TEST(GeometryTest, MatrixGetMaxBasisLength) {
216+
{
217+
auto m = Matrix::MakeScale({3, 1, 1});
218+
ASSERT_EQ(m.GetMaxBasisLength(), 3);
219+
220+
m = m * Matrix::MakeSkew(0, 4);
221+
ASSERT_EQ(m.GetMaxBasisLength(), 5);
222+
}
223+
224+
{
225+
auto m = Matrix::MakeScale({-3, 4, 2});
226+
ASSERT_EQ(m.GetMaxBasisLength(), 4);
227+
}
228+
}
229+
215230
TEST(GeometryTest, QuaternionLerp) {
216231
auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
217232
auto q2 = Quaternion{{0.0, 0.0, 1.0}, M_PI_4};
@@ -570,6 +585,21 @@ TEST(GeometryTest, CanUsePointAssignmentOperators) {
570585
ASSERT_EQ(p.x, 1u);
571586
ASSERT_EQ(p.y, 2u);
572587
}
588+
589+
// Arithmetic type on RHS
590+
{
591+
IPoint p(1, 2);
592+
p *= 3;
593+
ASSERT_EQ(p.x, 3u);
594+
ASSERT_EQ(p.y, 6u);
595+
}
596+
597+
{
598+
IPoint p(3, 6);
599+
p /= 3;
600+
ASSERT_EQ(p.x, 1u);
601+
ASSERT_EQ(p.y, 2u);
602+
}
573603
}
574604

575605
TEST(GeometryTest, PointDotProduct) {

impeller/geometry/matrix.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ Scalar Matrix::GetDeterminant() const {
193193
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
194194
}
195195

196+
Scalar Matrix::GetMaxBasisLength() const {
197+
Scalar max = 0;
198+
for (int i = 0; i < 3; i++) {
199+
max = std::max(max,
200+
e[i][0] * e[i][0] + e[i][1] * e[i][1] + e[i][2] * e[i][2]);
201+
}
202+
return std::sqrt(max);
203+
}
204+
196205
/*
197206
* Adapted for Impeller from Graphics Gems:
198207
* http://www.realtimerendering.com/resources/GraphicsGems/gemsii/unmatrix.c

impeller/geometry/matrix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ struct Matrix {
219219

220220
Scalar GetDeterminant() const;
221221

222+
Scalar GetMaxBasisLength() const;
223+
222224
constexpr bool IsAffine() const {
223225
return (m[2] == 0 && m[3] == 0 && m[6] == 0 && m[7] == 0 && m[8] == 0 &&
224226
m[9] == 0 && m[10] == 1 && m[11] == 0 && m[14] == 0 && m[15] == 1);

impeller/geometry/point.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ struct TPoint {
8888
return *this;
8989
}
9090

91+
template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
92+
inline TPoint operator*=(U scale) {
93+
x *= static_cast<Type>(scale);
94+
y *= static_cast<Type>(scale);
95+
return *this;
96+
}
97+
9198
template <class U>
9299
inline TPoint operator/=(const TPoint<U>& p) {
93100
x /= static_cast<Type>(p.x);
@@ -102,6 +109,13 @@ struct TPoint {
102109
return *this;
103110
}
104111

112+
template <class U, class = std::enable_if_t<std::is_arithmetic_v<U>>>
113+
inline TPoint operator/=(U scale) {
114+
x /= static_cast<Type>(scale);
115+
y /= static_cast<Type>(scale);
116+
return *this;
117+
}
118+
105119
constexpr TPoint operator-() const { return {-x, -y}; }
106120

107121
constexpr TPoint operator+(const TPoint& p) const {

impeller/geometry/scalar.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ namespace impeller {
1414

1515
using Scalar = float;
1616

17-
constexpr Scalar kEhCloseEnough = 1e-3f;
18-
1917
template <class T, class = std::enable_if_t<std::is_arithmetic_v<T>>>
2018
constexpr T Absolute(const T& val) {
2119
return val >= T{} ? val : -val;

impeller/typographer/backends/skia/text_frame_skia.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212

1313
namespace impeller {
1414

15-
static Font ToFont(const SkFont& font) {
15+
static Font ToFont(const SkFont& font, Scalar scale) {
1616
auto typeface = std::make_shared<TypefaceSkia>(font.refTypefaceOrDefault());
1717

1818
SkFontMetrics sk_metrics;
1919
font.getMetrics(&sk_metrics);
2020

2121
Font::Metrics metrics;
22+
metrics.scale = scale;
2223
metrics.point_size = font.getSize();
2324
metrics.ascent = sk_metrics.fAscent;
2425
metrics.descent = sk_metrics.fDescent;
@@ -28,15 +29,16 @@ static Font ToFont(const SkFont& font) {
2829
return Font{std::move(typeface), std::move(metrics)};
2930
}
3031

31-
TextFrame TextFrameFromTextBlob(sk_sp<SkTextBlob> blob) {
32+
TextFrame TextFrameFromTextBlob(sk_sp<SkTextBlob> blob,
33+
Scalar scale) {
3234
if (!blob) {
3335
return {};
3436
}
3537

3638
TextFrame frame;
3739

3840
for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
39-
TextRun text_run(ToFont(run.font()));
41+
TextRun text_run(ToFont(run.font(), scale));
4042
const auto glyph_count = run.glyphCount();
4143
const auto* glyphs = run.glyphs();
4244
switch (run.positioning()) {

impeller/typographer/backends/skia/text_frame_skia.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010

1111
namespace impeller {
1212

13-
TextFrame TextFrameFromTextBlob(sk_sp<SkTextBlob> blob);
13+
TextFrame TextFrameFromTextBlob(sk_sp<SkTextBlob> blob, Scalar scale = 1.0f);
1414

1515
} // namespace impeller

impeller/typographer/backends/skia/text_render_context_skia.cc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ static bool PairsFitInAtlasOfSize(const FontGlyphPair::Vector& pairs,
6565

6666
for (const auto& pair : pairs) {
6767
const auto glyph_size =
68-
ISize::Ceil(pair.font.GetMetrics().GetBoundingBox().size);
68+
ISize::Ceil(pair.font.GetMetrics().GetBoundingBox().size *
69+
pair.font.GetMetrics().scale);
6970
SkIPoint16 location_in_atlas;
7071
if (!rect_packer->addRect(glyph_size.width, //
7172
glyph_size.height, //
@@ -125,21 +126,23 @@ static std::optional<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
125126

126127
SkFont sk_font(
127128
TypefaceSkia::Cast(*font_glyph.font.GetTypeface()).GetSkiaTypeface(),
128-
font_glyph.font.GetMetrics().point_size);
129+
font_glyph.font.GetMetrics().point_size *
130+
font_glyph.font.GetMetrics().scale);
129131

130132
const auto& metrics = font_glyph.font.GetMetrics();
131133

132134
auto glyph_color = SK_ColorWHITE;
133135

134136
SkPaint glyph_paint;
135137
glyph_paint.setColor(glyph_color);
136-
canvas->drawGlyphs(1u, // count
137-
&glyph_id, // glyphs
138-
&position, // positions
139-
SkPoint::Make(-metrics.min_extent.x,
140-
-metrics.ascent), // origin
141-
sk_font, // font
142-
glyph_paint // paint
138+
canvas->drawGlyphs(
139+
1u, // count
140+
&glyph_id, // glyphs
141+
&position, // positions
142+
SkPoint::Make(-metrics.min_extent.x * metrics.scale,
143+
-metrics.ascent * metrics.scale), // origin
144+
sk_font, // font
145+
glyph_paint // paint
143146
);
144147
return true;
145148
});

impeller/typographer/font.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ class Font : public Comparable<Font> {
2828
/// the baseline with an upper-left-origin coordinate system.
2929
///
3030
struct Metrics {
31+
//--------------------------------------------------------------------------
32+
/// The scaling factor that should be used when rendering this font to an
33+
/// atlas. This should normally be set in accordance with the transformation
34+
/// matrix that will be used to position glyph geometry.
35+
///
36+
Scalar scale = 1.0f;
3137
//--------------------------------------------------------------------------
3238
/// The point size of the font.
3339
///
@@ -69,9 +75,9 @@ class Font : public Comparable<Font> {
6975
}
7076

7177
constexpr bool operator==(const Metrics& o) const {
72-
return point_size == o.point_size && ascent == o.ascent &&
73-
descent == o.descent && min_extent == o.min_extent &&
74-
max_extent == o.max_extent;
78+
return scale == o.scale && point_size == o.point_size &&
79+
ascent == o.ascent && descent == o.descent &&
80+
min_extent == o.min_extent && max_extent == o.max_extent;
7581
}
7682
};
7783

@@ -107,6 +113,6 @@ class Font : public Comparable<Font> {
107113
template <>
108114
struct std::hash<impeller::Font::Metrics> {
109115
constexpr std::size_t operator()(const impeller::Font::Metrics& m) const {
110-
return fml::HashCombine(m.point_size, m.ascent, m.descent);
116+
return fml::HashCombine(m.scale, m.point_size, m.ascent, m.descent);
111117
}
112118
};

impeller/typographer/glyph_atlas.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class GlyphAtlas {
4747
const std::shared_ptr<Texture>& GetTexture() const;
4848

4949
//----------------------------------------------------------------------------
50-
/// @brief Record there location of a specific font-glyph pair within the
50+
/// @brief Record the location of a specific font-glyph pair within the
5151
/// atlas.
5252
///
5353
/// @param[in] pair The font-glyph pair

0 commit comments

Comments
 (0)