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"
13 #include "third_party/skia/include/core/SkFont.h"
14 #include "third_party/skia/include/core/SkFontMetrics.h"
15 #include "third_party/skia/include/core/SkPaint.h"
16 #include "third_party/skia/include/core/SkRect.h"
17 #include "third_party/skia/src/core/SkStrikeSpec.h" // nogncheck
18 #include "third_party/skia/src/core/SkTextBlobPriv.h" // nogncheck
19 
20 namespace impeller {
21 
22 /// @brief Convert a Skia axis alignment into an Impeller alignment.
23 ///
24 /// This does not include a case for AxisAlignment::kNone, that should
25 /// be used if SkFont::isSubpixel is false.
26 static AxisAlignment ToAxisAligment(SkAxisAlignment aligment) {
27  switch (aligment) {
28  case SkAxisAlignment::kNone:
29  // Skia calls this case none, meaning alignment in both X and Y.
30  // Impeller will call it "all" since that is less confusing. "none"
31  // is reserved for no subpixel alignment.
32  return AxisAlignment::kAll;
33  case SkAxisAlignment::kX:
34  return AxisAlignment::kX;
35  case SkAxisAlignment::kY:
36  return AxisAlignment::kY;
37  }
38  FML_UNREACHABLE();
39 }
40 
41 static Font ToFont(const SkTextBlobRunIterator& run, AxisAlignment alignment) {
42  auto& font = run.font();
43  auto typeface = std::make_shared<TypefaceSkia>(font.refTypeface());
44 
45  SkFontMetrics sk_metrics;
46  font.getMetrics(&sk_metrics);
47 
48  Font::Metrics metrics;
49  metrics.point_size = font.getSize();
50  metrics.embolden = font.isEmbolden();
51  metrics.skewX = font.getSkewX();
52  metrics.scaleX = font.getScaleX();
53 
54  return Font{std::move(typeface), metrics, alignment};
55 }
56 
57 static Rect ToRect(const SkRect& rect) {
58  return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
59 }
60 
61 std::shared_ptr<TextFrame> MakeTextFrameFromTextBlobSkia(
62  const sk_sp<SkTextBlob>& blob) {
63  bool has_color = false;
64  std::vector<TextRun> runs;
65  for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
66  // TODO(jonahwilliams): ask Skia for a public API to look this up.
67  // https://github.com/flutter/flutter/issues/112005
68  SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(run.font());
69  SkBulkGlyphMetricsAndPaths paths{strikeSpec};
71  if (run.font().isSubpixel()) {
72  alignment = ToAxisAligment(
73  strikeSpec.createScalerContext()->computeAxisAlignmentForHText());
74  }
75 
76  const auto glyph_count = run.glyphCount();
77  const auto* glyphs = run.glyphs();
78  switch (run.positioning()) {
79  case SkTextBlobRunIterator::kFull_Positioning: {
80  std::vector<TextRun::GlyphPosition> positions;
81  positions.reserve(glyph_count);
82  for (auto i = 0u; i < glyph_count; i++) {
83  // kFull_Positioning has two scalars per glyph.
84  const SkPoint* glyph_points = run.points();
85  const SkPoint* point = glyph_points + i;
86  Glyph::Type type = paths.glyph(glyphs[i])->isColor()
89  has_color |= type == Glyph::Type::kBitmap;
90  positions.emplace_back(
92  point->x(),
93  point->y(),
94  }});
95  }
96  TextRun text_run(ToFont(run, alignment), positions);
97  runs.emplace_back(text_run);
98  break;
99  }
100  default:
101  FML_DLOG(ERROR) << "Unimplemented.";
102  continue;
103  }
104  }
105  return std::make_shared<TextFrame>(runs, ToRect(blob->bounds()), has_color);
106 }
107 
108 } // namespace impeller
impeller::Glyph::Type
Type
Definition: glyph.h:17
impeller::AxisAlignment::kAll
@ kAll
impeller::Font
Describes a typeface along with any modifications to its intrinsic properties.
Definition: font.h:35
impeller::ToAxisAligment
static AxisAlignment ToAxisAligment(SkAxisAlignment aligment)
Convert a Skia axis alignment into an Impeller alignment.
Definition: text_frame_skia.cc:26
impeller::Font::Metrics::embolden
bool embolden
Definition: font.h:49
impeller::Glyph::Type::kBitmap
@ kBitmap
impeller::ToFont
static Font ToFont(const SkTextBlobRunIterator &run, AxisAlignment alignment)
Definition: text_frame_skia.cc:41
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:50
impeller::Glyph
The glyph index in the typeface.
Definition: glyph.h:16
glyph.h
font.h
type
GLenum type
Definition: blit_command_gles.cc:126
impeller::Font::Metrics::point_size
Scalar point_size
Definition: font.h:48
impeller::AxisAlignment
AxisAlignment
Determines the axis along which there is subpixel positioning.
Definition: font.h:20
impeller::AxisAlignment::kX
@ kX
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:61
impeller::TPoint::x
Type x
Definition: point.h:30
typeface_skia.h
impeller::TPoint
Definition: point.h:27
impeller::TextRun::GlyphPosition
Definition: text_run.h:22
impeller::Font::Metrics::scaleX
Scalar scaleX
Definition: font.h:51
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::AxisAlignment::kNone
@ kNone
impeller::ToRect
static Rect ToRect(const SkRect &rect)
Definition: dl_vertices_geometry.cc:16
impeller
Definition: aiks_blend_unittests.cc:18
impeller::Font::Metrics
Describes the modifications made to the intrinsic properties of a typeface.
Definition: font.h:44
impeller::TRect< Scalar >
impeller::AxisAlignment::kY
@ kY