Flutter Impeller
typographer_context_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 <numeric>
8 #include <utility>
9 
10 #include "flutter/fml/logging.h"
11 #include "flutter/fml/trace_event.h"
18 #include "include/core/SkColor.h"
19 #include "include/core/SkSize.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "third_party/skia/include/core/SkCanvas.h"
22 #include "third_party/skia/include/core/SkFont.h"
23 #include "third_party/skia/include/core/SkSurface.h"
24 
25 namespace impeller {
26 
27 // TODO(bdero): We might be able to remove this per-glyph padding if we fix
28 // the underlying causes of the overlap.
29 // https://github.com/flutter/flutter/issues/114563
30 constexpr auto kPadding = 2;
31 
32 std::shared_ptr<TypographerContext> TypographerContextSkia::Make() {
33  return std::make_shared<TypographerContextSkia>();
34 }
35 
37 
39 
40 std::shared_ptr<GlyphAtlasContext>
42  return std::make_shared<GlyphAtlasContextSkia>();
43 }
44 
45 static size_t PairsFitInAtlasOfSize(
46  const std::vector<FontGlyphPair>& pairs,
47  const ISize& atlas_size,
48  std::vector<Rect>& glyph_positions,
49  const std::shared_ptr<RectanglePacker>& rect_packer) {
50  if (atlas_size.IsEmpty()) {
51  return false;
52  }
53 
54  glyph_positions.clear();
55  glyph_positions.reserve(pairs.size());
56 
57  size_t i = 0;
58  for (auto it = pairs.begin(); it != pairs.end(); ++i, ++it) {
59  const auto& pair = *it;
60 
61  const auto glyph_size =
62  ISize::Ceil(pair.glyph.bounds.GetSize() * pair.scaled_font.scale);
63  IPoint16 location_in_atlas;
64  if (!rect_packer->addRect(glyph_size.width + kPadding, //
65  glyph_size.height + kPadding, //
66  &location_in_atlas //
67  )) {
68  return pairs.size() - i;
69  }
70  glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
71  location_in_atlas.y(), //
72  glyph_size.width, //
73  glyph_size.height //
74  ));
75  }
76 
77  return 0;
78 }
79 
81  const std::shared_ptr<GlyphAtlas>& atlas,
82  const std::vector<FontGlyphPair>& extra_pairs,
83  std::vector<Rect>& glyph_positions,
84  ISize atlas_size,
85  const std::shared_ptr<RectanglePacker>& rect_packer) {
86  TRACE_EVENT0("impeller", __FUNCTION__);
87  if (!rect_packer || atlas_size.IsEmpty()) {
88  return false;
89  }
90 
91  // We assume that all existing glyphs will fit. After all, they fit before.
92  // The glyph_positions only contains the values for the additional glyphs
93  // from extra_pairs.
94  FML_DCHECK(glyph_positions.size() == 0);
95  glyph_positions.reserve(extra_pairs.size());
96  for (size_t i = 0; i < extra_pairs.size(); i++) {
97  const FontGlyphPair& pair = extra_pairs[i];
98 
99  const auto glyph_size =
101  IPoint16 location_in_atlas;
102  if (!rect_packer->addRect(glyph_size.width + kPadding, //
103  glyph_size.height + kPadding, //
104  &location_in_atlas //
105  )) {
106  return false;
107  }
108  glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
109  location_in_atlas.y(), //
110  glyph_size.width, //
111  glyph_size.height //
112  ));
113  }
114 
115  return true;
116 }
117 
119  const std::vector<FontGlyphPair>& pairs,
120  std::vector<Rect>& glyph_positions,
121  const std::shared_ptr<GlyphAtlasContext>& atlas_context,
122  GlyphAtlas::Type type,
123  const ISize& max_texture_size) {
124  static constexpr auto kMinAtlasSize = 8u;
125  static constexpr auto kMinAlphaBitmapSize = 1024u;
126 
127  TRACE_EVENT0("impeller", __FUNCTION__);
128 
129  ISize current_size = type == GlyphAtlas::Type::kAlphaBitmap
130  ? ISize(kMinAlphaBitmapSize, kMinAlphaBitmapSize)
131  : ISize(kMinAtlasSize, kMinAtlasSize);
132  size_t total_pairs = pairs.size() + 1;
133  do {
134  auto rect_packer = std::shared_ptr<RectanglePacker>(
135  RectanglePacker::Factory(current_size.width, current_size.height));
136 
137  auto remaining_pairs = PairsFitInAtlasOfSize(pairs, current_size,
138  glyph_positions, rect_packer);
139  if (remaining_pairs == 0) {
140  atlas_context->UpdateRectPacker(rect_packer);
141  return current_size;
142  } else if (remaining_pairs < std::ceil(total_pairs / 2)) {
143  current_size = ISize::MakeWH(
144  std::max(current_size.width, current_size.height),
146  std::min(current_size.width, current_size.height) + 1));
147  } else {
148  current_size = ISize::MakeWH(
149  Allocation::NextPowerOfTwoSize(current_size.width + 1),
150  Allocation::NextPowerOfTwoSize(current_size.height + 1));
151  }
152  } while (current_size.width <= max_texture_size.width &&
153  current_size.height <= max_texture_size.height);
154  return ISize{0, 0};
155 }
156 
157 static void DrawGlyph(SkCanvas* canvas,
158  const ScaledFont& scaled_font,
159  const Glyph& glyph,
160  const Rect& location,
161  bool has_color) {
162  const auto& metrics = scaled_font.font.GetMetrics();
163  const auto position = SkPoint::Make(location.GetX() / scaled_font.scale,
164  location.GetY() / scaled_font.scale);
165  SkGlyphID glyph_id = glyph.index;
166 
167  SkFont sk_font(
169  metrics.point_size, metrics.scaleX, metrics.skewX);
170  sk_font.setEdging(SkFont::Edging::kAntiAlias);
171  sk_font.setHinting(SkFontHinting::kSlight);
172  sk_font.setEmbolden(metrics.embolden);
173 
174  auto glyph_color = has_color ? SK_ColorWHITE : SK_ColorBLACK;
175 
176  SkPaint glyph_paint;
177  glyph_paint.setColor(glyph_color);
178  canvas->resetMatrix();
179  canvas->scale(scaled_font.scale, scaled_font.scale);
180  canvas->drawGlyphs(1u, // count
181  &glyph_id, // glyphs
182  &position, // positions
183  SkPoint::Make(-glyph.bounds.GetLeft(),
184  -glyph.bounds.GetTop()), // origin
185  sk_font, // font
186  glyph_paint // paint
187  );
188 }
189 
190 static bool UpdateAtlasBitmap(const GlyphAtlas& atlas,
191  const std::shared_ptr<SkBitmap>& bitmap,
192  const std::vector<FontGlyphPair>& new_pairs) {
193  TRACE_EVENT0("impeller", __FUNCTION__);
194  FML_DCHECK(bitmap != nullptr);
195 
196  auto surface = SkSurfaces::WrapPixels(bitmap->pixmap());
197  if (!surface) {
198  return false;
199  }
200  auto canvas = surface->getCanvas();
201  if (!canvas) {
202  return false;
203  }
204 
205  bool has_color = atlas.GetType() == GlyphAtlas::Type::kColorBitmap;
206 
207  for (const FontGlyphPair& pair : new_pairs) {
208  auto pos = atlas.FindFontGlyphBounds(pair);
209  if (!pos.has_value()) {
210  continue;
211  }
212  DrawGlyph(canvas, pair.scaled_font, pair.glyph, pos.value(), has_color);
213  }
214  return true;
215 }
216 
217 static std::shared_ptr<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
218  const ISize& atlas_size) {
219  TRACE_EVENT0("impeller", __FUNCTION__);
220  auto bitmap = std::make_shared<SkBitmap>();
221  SkImageInfo image_info;
222 
223  switch (atlas.GetType()) {
225  image_info =
226  SkImageInfo::MakeA8(SkISize{static_cast<int32_t>(atlas_size.width),
227  static_cast<int32_t>(atlas_size.height)});
228  break;
230  image_info =
231  SkImageInfo::MakeN32Premul(atlas_size.width, atlas_size.height);
232  break;
233  }
234 
235  if (!bitmap->tryAllocPixels(image_info)) {
236  return nullptr;
237  }
238 
239  auto surface = SkSurfaces::WrapPixels(bitmap->pixmap());
240  if (!surface) {
241  return nullptr;
242  }
243  auto canvas = surface->getCanvas();
244  if (!canvas) {
245  return nullptr;
246  }
247 
248  bool has_color = atlas.GetType() == GlyphAtlas::Type::kColorBitmap;
249 
250  atlas.IterateGlyphs([canvas, has_color](const ScaledFont& scaled_font,
251  const Glyph& glyph,
252  const Rect& location) -> bool {
253  DrawGlyph(canvas, scaled_font, glyph, location, has_color);
254  return true;
255  });
256 
257  return bitmap;
258 }
259 
260 static bool UpdateGlyphTextureAtlas(std::shared_ptr<SkBitmap> bitmap,
261  const std::shared_ptr<Texture>& texture) {
262  TRACE_EVENT0("impeller", __FUNCTION__);
263 
264  FML_DCHECK(bitmap != nullptr);
265  auto texture_descriptor = texture->GetTextureDescriptor();
266 
267  auto mapping = std::make_shared<fml::NonOwnedMapping>(
268  reinterpret_cast<const uint8_t*>(bitmap->getAddr(0, 0)), // data
269  texture_descriptor.GetByteSizeOfBaseMipLevel(), // size
270  [bitmap](auto, auto) mutable { bitmap.reset(); } // proc
271  );
272 
273  return texture->SetContents(mapping);
274 }
275 
276 static std::shared_ptr<Texture> UploadGlyphTextureAtlas(
277  const std::shared_ptr<Allocator>& allocator,
278  std::shared_ptr<SkBitmap> bitmap,
279  const ISize& atlas_size,
280  PixelFormat format) {
281  TRACE_EVENT0("impeller", __FUNCTION__);
282  if (!allocator) {
283  return nullptr;
284  }
285 
286  FML_DCHECK(bitmap != nullptr);
287  const auto& pixmap = bitmap->pixmap();
288 
289  TextureDescriptor texture_descriptor;
290  texture_descriptor.storage_mode = StorageMode::kHostVisible;
291  texture_descriptor.format = format;
292  texture_descriptor.size = atlas_size;
293 
294  if (pixmap.rowBytes() * pixmap.height() !=
295  texture_descriptor.GetByteSizeOfBaseMipLevel()) {
296  return nullptr;
297  }
298 
299  auto texture = allocator->CreateTexture(texture_descriptor);
300  if (!texture || !texture->IsValid()) {
301  return nullptr;
302  }
303  texture->SetLabel("GlyphAtlas");
304 
305  auto mapping = std::make_shared<fml::NonOwnedMapping>(
306  reinterpret_cast<const uint8_t*>(bitmap->getAddr(0, 0)), // data
307  texture_descriptor.GetByteSizeOfBaseMipLevel(), // size
308  [bitmap](auto, auto) mutable { bitmap.reset(); } // proc
309  );
310 
311  if (!texture->SetContents(mapping)) {
312  return nullptr;
313  }
314  return texture;
315 }
316 
317 std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
318  Context& context,
319  GlyphAtlas::Type type,
320  const std::shared_ptr<GlyphAtlasContext>& atlas_context,
321  const FontGlyphMap& font_glyph_map) const {
322  TRACE_EVENT0("impeller", __FUNCTION__);
323  if (!IsValid()) {
324  return nullptr;
325  }
326  auto& atlas_context_skia = GlyphAtlasContextSkia::Cast(*atlas_context);
327  std::shared_ptr<GlyphAtlas> last_atlas = atlas_context->GetGlyphAtlas();
328 
329  if (font_glyph_map.empty()) {
330  return last_atlas;
331  }
332 
333  // ---------------------------------------------------------------------------
334  // Step 1: Determine if the atlas type and font glyph pairs are compatible
335  // with the current atlas and reuse if possible.
336  // ---------------------------------------------------------------------------
337  std::vector<FontGlyphPair> new_glyphs;
338  for (const auto& font_value : font_glyph_map) {
339  const ScaledFont& scaled_font = font_value.first;
340  const FontGlyphAtlas* font_glyph_atlas =
341  last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
342  if (font_glyph_atlas) {
343  for (const Glyph& glyph : font_value.second) {
344  if (!font_glyph_atlas->FindGlyphBounds(glyph)) {
345  new_glyphs.emplace_back(scaled_font, glyph);
346  }
347  }
348  } else {
349  for (const Glyph& glyph : font_value.second) {
350  new_glyphs.emplace_back(scaled_font, glyph);
351  }
352  }
353  }
354  if (last_atlas->GetType() == type && new_glyphs.size() == 0) {
355  return last_atlas;
356  }
357 
358  // ---------------------------------------------------------------------------
359  // Step 2: Determine if the additional missing glyphs can be appended to the
360  // existing bitmap without recreating the atlas. This requires that
361  // the type is identical.
362  // ---------------------------------------------------------------------------
363  std::vector<Rect> glyph_positions;
364  if (last_atlas->GetType() == type &&
365  CanAppendToExistingAtlas(last_atlas, new_glyphs, glyph_positions,
366  atlas_context->GetAtlasSize(),
367  atlas_context->GetRectPacker())) {
368  // The old bitmap will be reused and only the additional glyphs will be
369  // added.
370 
371  // ---------------------------------------------------------------------------
372  // Step 3a: Record the positions in the glyph atlas of the newly added
373  // glyphs.
374  // ---------------------------------------------------------------------------
375  for (size_t i = 0, count = glyph_positions.size(); i < count; i++) {
376  last_atlas->AddTypefaceGlyphPosition(new_glyphs[i], glyph_positions[i]);
377  }
378 
379  // ---------------------------------------------------------------------------
380  // Step 4a: Draw new font-glyph pairs into the existing bitmap.
381  // ---------------------------------------------------------------------------
382  auto bitmap = atlas_context_skia.GetBitmap();
383  if (!UpdateAtlasBitmap(*last_atlas, bitmap, new_glyphs)) {
384  return nullptr;
385  }
386 
387  // ---------------------------------------------------------------------------
388  // Step 5a: Update the existing texture with the updated bitmap.
389  // ---------------------------------------------------------------------------
390  if (!UpdateGlyphTextureAtlas(bitmap, last_atlas->GetTexture())) {
391  return nullptr;
392  }
393  return last_atlas;
394  }
395  // A new glyph atlas must be created.
396 
397  // ---------------------------------------------------------------------------
398  // Step 3b: Get the optimum size of the texture atlas.
399  // ---------------------------------------------------------------------------
400  std::vector<FontGlyphPair> font_glyph_pairs;
401  font_glyph_pairs.reserve(std::accumulate(
402  font_glyph_map.begin(), font_glyph_map.end(), 0,
403  [](const int a, const auto& b) { return a + b.second.size(); }));
404  for (const auto& font_value : font_glyph_map) {
405  const ScaledFont& scaled_font = font_value.first;
406  for (const Glyph& glyph : font_value.second) {
407  font_glyph_pairs.push_back({scaled_font, glyph});
408  }
409  }
410  auto glyph_atlas = std::make_shared<GlyphAtlas>(type);
411  auto atlas_size = OptimumAtlasSizeForFontGlyphPairs(
412  font_glyph_pairs, //
413  glyph_positions, //
414  atlas_context, //
415  type, //
416  context.GetResourceAllocator()->GetMaxTextureSizeSupported() //
417  );
418 
419  atlas_context->UpdateGlyphAtlas(glyph_atlas, atlas_size);
420  if (atlas_size.IsEmpty()) {
421  return nullptr;
422  }
423  // ---------------------------------------------------------------------------
424  // Step 4b: Find location of font-glyph pairs in the atlas. We have this from
425  // the last step. So no need to do create another rect packer. But just do a
426  // sanity check of counts. This could also be just an assertion as only a
427  // construction issue would cause such a failure.
428  // ---------------------------------------------------------------------------
429  if (glyph_positions.size() != font_glyph_pairs.size()) {
430  return nullptr;
431  }
432 
433  // ---------------------------------------------------------------------------
434  // Step 5b: Record the positions in the glyph atlas.
435  // ---------------------------------------------------------------------------
436  {
437  size_t i = 0;
438  for (auto it = font_glyph_pairs.begin(); it != font_glyph_pairs.end();
439  ++i, ++it) {
440  glyph_atlas->AddTypefaceGlyphPosition(*it, glyph_positions[i]);
441  }
442  }
443 
444  // ---------------------------------------------------------------------------
445  // Step 6b: Draw font-glyph pairs in the correct spot in the atlas.
446  // ---------------------------------------------------------------------------
447  auto bitmap = CreateAtlasBitmap(*glyph_atlas, atlas_size);
448  if (!bitmap) {
449  return nullptr;
450  }
451  atlas_context_skia.UpdateBitmap(bitmap);
452 
453  // ---------------------------------------------------------------------------
454  // Step 7b: Upload the atlas as a texture.
455  // ---------------------------------------------------------------------------
456  PixelFormat format;
457  switch (type) {
459  format = context.GetCapabilities()->GetDefaultGlyphAtlasFormat();
460  break;
463  break;
464  }
465  auto texture = UploadGlyphTextureAtlas(context.GetResourceAllocator(), bitmap,
466  atlas_size, format);
467  if (!texture) {
468  return nullptr;
469  }
470 
471  // ---------------------------------------------------------------------------
472  // Step 8b: Record the texture in the glyph atlas.
473  // ---------------------------------------------------------------------------
474  glyph_atlas->SetTexture(std::move(texture));
475 
476  return glyph_atlas;
477 }
478 
479 } // namespace impeller
impeller::GlyphAtlas::Type::kColorBitmap
@ kColorBitmap
glyph_atlas_context_skia.h
impeller::TypographerContextSkia::CreateGlyphAtlasContext
std::shared_ptr< GlyphAtlasContext > CreateGlyphAtlasContext() const override
Definition: typographer_context_skia.cc:41
impeller::GlyphAtlas::Type::kAlphaBitmap
@ kAlphaBitmap
impeller::GlyphAtlas::FindFontGlyphBounds
std::optional< Rect > FindFontGlyphBounds(const FontGlyphPair &pair) const
Find the location of a specific font-glyph pair in the atlas.
Definition: glyph_atlas.cc:66
allocation.h
impeller::TRect< Scalar >::MakeXYWH
constexpr static TRect MakeXYWH(Type x, Type y, Type width, Type height)
Definition: rect.h:136
impeller::FontGlyphAtlas
An object that can look up glyph locations within the GlyphAtlas for a particular typeface.
Definition: glyph_atlas.h:185
impeller::Allocation::NextPowerOfTwoSize
static uint32_t NextPowerOfTwoSize(uint32_t x)
Definition: allocation.cc:41
impeller::Context::GetCapabilities
virtual const std::shared_ptr< const Capabilities > & GetCapabilities() const =0
Get the capabilities of Impeller context. All optionally supported feature of the platform,...
impeller::CreateAtlasBitmap
static std::shared_ptr< SkBitmap > CreateAtlasBitmap(const GlyphAtlas &atlas, const ISize &atlas_size)
Definition: typographer_context_skia.cc:217
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:40
impeller::ScaledFont::font
Font font
Definition: font_glyph_pair.h:25
impeller::PixelFormat::kR8G8B8A8UNormInt
@ kR8G8B8A8UNormInt
impeller::RectanglePacker::Factory
static std::unique_ptr< RectanglePacker > Factory(int width, int height)
Return an empty packer with area specified by width and height.
Definition: rectangle_packer.cc:169
impeller::PairsFitInAtlasOfSize
static size_t PairsFitInAtlasOfSize(const std::vector< FontGlyphPair > &pairs, const ISize &atlas_size, std::vector< Rect > &glyph_positions, const std::shared_ptr< RectanglePacker > &rect_packer)
Definition: typographer_context_skia.cc:45
impeller::TSize< int64_t >::Ceil
constexpr TSize Ceil() const
Definition: size.h:96
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< Glyph > > FontGlyphMap
Definition: font_glyph_pair.h:29
impeller::IPoint16::x
int16_t x() const
Definition: rectangle_packer.h:15
typographer_context.h
impeller::TRect::GetX
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition: rect.h:300
impeller::UpdateAtlasBitmap
static bool UpdateAtlasBitmap(const GlyphAtlas &atlas, const std::shared_ptr< SkBitmap > &bitmap, const std::vector< FontGlyphPair > &new_pairs)
Definition: typographer_context_skia.cc:190
impeller::StorageMode::kHostVisible
@ kHostVisible
impeller::IPoint16::y
int16_t y() const
Definition: rectangle_packer.h:16
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:100
typographer_context_skia.h
impeller::Font::GetTypeface
const std::shared_ptr< Typeface > & GetTypeface() const
The typeface whose intrinsic properties this font modifies.
Definition: font.cc:23
impeller::GlyphAtlas::IterateGlyphs
size_t IterateGlyphs(const std::function< bool(const ScaledFont &scaled_font, const Glyph &glyph, const Rect &rect)> &iterator) const
Iterate of all the glyphs along with their locations in the atlas.
Definition: glyph_atlas.cc:91
impeller::TypefaceSkia::GetSkiaTypeface
const sk_sp< SkTypeface > & GetSkiaTypeface() const
Definition: typeface_skia.cc:31
impeller::CanAppendToExistingAtlas
static bool CanAppendToExistingAtlas(const std::shared_ptr< GlyphAtlas > &atlas, const std::vector< FontGlyphPair > &extra_pairs, std::vector< Rect > &glyph_positions, ISize atlas_size, const std::shared_ptr< RectanglePacker > &rect_packer)
Definition: typographer_context_skia.cc:80
impeller::Glyph
The glyph index in the typeface.
Definition: glyph.h:20
impeller::TSize< int64_t >
impeller::UpdateGlyphTextureAtlas
static bool UpdateGlyphTextureAtlas(std::shared_ptr< SkBitmap > bitmap, const std::shared_ptr< Texture > &texture)
Definition: typographer_context_skia.cc:260
impeller::FontGlyphPair::glyph
const Glyph & glyph
Definition: font_glyph_pair.h:39
impeller::TRect::GetLeft
constexpr auto GetLeft() const
Definition: rect.h:318
impeller::TypographerContextSkia::CreateGlyphAtlas
std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, GlyphAtlas::Type type, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const FontGlyphMap &font_glyph_map) const override
Definition: typographer_context_skia.cc:317
rectangle_packer.h
impeller::FontGlyphPair::scaled_font
const ScaledFont & scaled_font
Definition: font_glyph_pair.h:38
impeller::GlyphAtlas::GetType
Type GetType() const
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.cc:49
impeller::TypographerContextSkia::TypographerContextSkia
TypographerContextSkia()
impeller::GlyphAtlas::Type
Type
Describes how the glyphs are represented in the texture.
Definition: glyph_atlas.h:32
impeller::UploadGlyphTextureAtlas
static std::shared_ptr< Texture > UploadGlyphTextureAtlas(const std::shared_ptr< Allocator > &allocator, std::shared_ptr< SkBitmap > bitmap, const ISize &atlas_size, PixelFormat format)
Definition: typographer_context_skia.cc:276
impeller::Glyph::index
uint16_t index
Definition: glyph.h:26
impeller::FontGlyphPair
A font along with a glyph in that font rendered at a particular scale.
Definition: font_glyph_pair.h:35
impeller::Font::GetMetrics
const Metrics & GetMetrics() const
Definition: font.cc:37
impeller::kPadding
constexpr auto kPadding
Definition: typographer_context_skia.cc:30
impeller::TSize::width
Type width
Definition: size.h:22
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:41
impeller::ScaledFont::scale
Scalar scale
Definition: font_glyph_pair.h:26
typeface_skia.h
allocator.h
impeller::GlyphAtlas
A texture containing the bitmap representation of glyphs in different fonts along with the ability to...
Definition: glyph_atlas.h:28
impeller::TRect::GetSize
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
Definition: rect.h:294
impeller::Context
To do anything rendering related with Impeller, you need a context.
Definition: context.h:46
impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel
constexpr size_t GetByteSizeOfBaseMipLevel() const
Definition: texture_descriptor.h:47
impeller::TypographerContextSkia::~TypographerContextSkia
~TypographerContextSkia() override
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::BackendCast< TypefaceSkia, Typeface >::Cast
static TypefaceSkia & Cast(Typeface &base)
Definition: backend_cast.h:13
impeller::IPoint16
Definition: rectangle_packer.h:14
impeller::OptimumAtlasSizeForFontGlyphPairs
static ISize OptimumAtlasSizeForFontGlyphPairs(const std::vector< FontGlyphPair > &pairs, std::vector< Rect > &glyph_positions, const std::shared_ptr< GlyphAtlasContext > &atlas_context, GlyphAtlas::Type type, const ISize &max_texture_size)
Definition: typographer_context_skia.cc:118
impeller::FontGlyphAtlas::FindGlyphBounds
std::optional< Rect > FindGlyphBounds(const Glyph &glyph) const
Find the location of a glyph in the atlas.
Definition: glyph_atlas.cc:111
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:38
impeller::TSize::height
Type height
Definition: size.h:23
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:37
impeller::TSize::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:105
impeller::TSize< int64_t >::MakeWH
static constexpr TSize MakeWH(Type width, Type height)
Definition: size.h:34
impeller::TRect::GetY
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition: rect.h:304
impeller
Definition: aiks_blur_unittests.cc:20
impeller::Context::GetResourceAllocator
virtual std::shared_ptr< Allocator > GetResourceAllocator() const =0
Returns the allocator used to create textures and buffers on the device.
impeller::TRect::GetTop
constexpr auto GetTop() const
Definition: rect.h:320
impeller::Glyph::bounds
Rect bounds
Visibility coverage of the glyph in text run space (relative to the baseline, no scaling applied).
Definition: glyph.h:37
impeller::TypographerContextSkia::Make
static std::shared_ptr< TypographerContext > Make()
Definition: typographer_context_skia.cc:32
impeller::TRect
Definition: rect.h:122
impeller::DrawGlyph
static void DrawGlyph(SkCanvas *canvas, const ScaledFont &scaled_font, const Glyph &glyph, const Rect &location, bool has_color)
Definition: typographer_context_skia.cc:157
impeller::ScaledFont
A font and a scale. Used as a key that represents a typeface within a glyph atlas.
Definition: font_glyph_pair.h:24
impeller::TypographerContext::IsValid
virtual bool IsValid() const
Definition: typographer_context.cc:17