Flutter Impeller
text_frame_skia.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <vector>
8 
9 #include "flutter/fml/logging.h"
11 #include "include/core/SkRect.h"
12 #include "third_party/skia/include/core/SkFont.h"
13 #include "third_party/skia/include/core/SkFontMetrics.h"
14 #include "third_party/skia/src/core/SkStrikeSpec.h" // nogncheck
15 #include "third_party/skia/src/core/SkTextBlobPriv.h" // nogncheck
16 
17 namespace impeller {
18 
19 static Font ToFont(const SkTextBlobRunIterator& run) {
20  auto& font = run.font();
21  auto typeface = std::make_shared<TypefaceSkia>(font.refTypeface());
22 
23  SkFontMetrics sk_metrics;
24  font.getMetrics(&sk_metrics);
25 
26  Font::Metrics metrics;
27  metrics.point_size = font.getSize();
28  metrics.embolden = font.isEmbolden();
29  metrics.skewX = font.getSkewX();
30  metrics.scaleX = font.getScaleX();
31 
32  return Font{std::move(typeface), metrics};
33 }
34 
35 static Rect ToRect(const SkRect& rect) {
36  return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
37 }
38 
39 static constexpr Scalar kScaleSize = 100000.0f;
40 
41 std::shared_ptr<TextFrame> MakeTextFrameFromTextBlobSkia(
42  const sk_sp<SkTextBlob>& blob) {
43  bool has_color = false;
44  std::vector<TextRun> runs;
45  for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
46  // TODO(jonahwilliams): ask Skia for a public API to look this up.
47  // https://github.com/flutter/flutter/issues/112005
48  SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(run.font());
49  SkBulkGlyphMetricsAndPaths paths{strikeSpec};
50 
51  const auto glyph_count = run.glyphCount();
52  const auto* glyphs = run.glyphs();
53  switch (run.positioning()) {
54  case SkTextBlobRunIterator::kFull_Positioning: {
55  std::vector<SkRect> glyph_bounds;
56  glyph_bounds.resize(glyph_count);
57  SkFont font = run.font();
58  auto font_size = font.getSize();
59  // For some platforms (including Android), `SkFont::getBounds()` snaps
60  // the computed bounds to integers. And so we scale up the font size
61  // prior to fetching the bounds to ensure that the returned bounds are
62  // always precise enough.
63  font.setSize(kScaleSize);
64  font.getBounds(glyphs, glyph_count, glyph_bounds.data(), nullptr);
65 
66  std::vector<TextRun::GlyphPosition> positions;
67  positions.reserve(glyph_count);
68  for (auto i = 0u; i < glyph_count; i++) {
69  // kFull_Positioning has two scalars per glyph.
70  const SkPoint* glyph_points = run.points();
71  const auto* point = glyph_points + i;
72  Glyph::Type type = paths.glyph(glyphs[i])->isColor()
75  has_color |= type == Glyph::Type::kBitmap;
76 
77  positions.emplace_back(TextRun::GlyphPosition{
78  Glyph{glyphs[i], type,
79  ToRect(glyph_bounds[i]).Scale(font_size / kScaleSize)},
80  Point{point->x(), point->y()}});
81  }
82  TextRun text_run(ToFont(run), positions);
83  runs.emplace_back(text_run);
84  break;
85  }
86  default:
87  FML_DLOG(ERROR) << "Unimplemented.";
88  continue;
89  }
90  }
91  return std::make_shared<TextFrame>(runs, ToRect(blob->bounds()), has_color);
92 }
93 
94 } // namespace impeller
impeller::Glyph::Type
Type
Definition: glyph.h:21
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:22
impeller::Font::Metrics::embolden
bool embolden
Definition: font.h:36
impeller::kScaleSize
static constexpr Scalar kScaleSize
Definition: text_frame_skia.cc:39
impeller::Glyph::Type::kBitmap
@ kBitmap
impeller::TextRun
Represents a collection of positioned glyphs from a specific font.
Definition: text_run.h:20
text_frame_skia.h
impeller::Font::Metrics::skewX
Scalar skewX
Definition: font.h:37
impeller::Glyph
The glyph index in the typeface.
Definition: glyph.h:20
impeller::TRect::Scale
constexpr TRect Scale(Type scale) const
Definition: rect.h:188
impeller::Font::Metrics::point_size
Scalar point_size
Definition: font.h:35
impeller::ToFont
static Font ToFont(const SkTextBlobRunIterator &run)
Definition: text_frame_skia.cc:19
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:41
impeller::TPoint::x
Type x
Definition: point.h:30
typeface_skia.h
impeller::TPoint< Scalar >
impeller::TextRun::GlyphPosition
Definition: text_run.h:22
impeller::Font::Metrics::scaleX
Scalar scaleX
Definition: font.h:38
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller::Glyph::Type::kPath
@ kPath
impeller::ToRect
static Rect ToRect(const SkRect &rect)
Definition: dl_vertices_geometry.cc:16
impeller
Definition: aiks_blur_unittests.cc:20
impeller::Font::Metrics
Describes the modifications made to the intrinsic properties of a typeface.
Definition: font.h:31
impeller::TRect
Definition: rect.h:122