blob: 1f9bfaff8d7aeb24496dad64b8697e0c4339bbec [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/typographer/glyph_atlas.h"
#include <numeric>
#include <utility>
namespace impeller {
GlyphAtlasContext::GlyphAtlasContext()
: atlas_(std::make_shared<GlyphAtlas>(GlyphAtlas::Type::kAlphaBitmap)),
atlas_size_(ISize(0, 0)) {}
GlyphAtlasContext::~GlyphAtlasContext() {}
std::shared_ptr<GlyphAtlas> GlyphAtlasContext::GetGlyphAtlas() const {
return atlas_;
}
const ISize& GlyphAtlasContext::GetAtlasSize() const {
return atlas_size_;
}
std::shared_ptr<RectanglePacker> GlyphAtlasContext::GetRectPacker() const {
return rect_packer_;
}
void GlyphAtlasContext::UpdateGlyphAtlas(std::shared_ptr<GlyphAtlas> atlas,
ISize size) {
atlas_ = std::move(atlas);
atlas_size_ = size;
}
void GlyphAtlasContext::UpdateRectPacker(
std::shared_ptr<RectanglePacker> rect_packer) {
rect_packer_ = std::move(rect_packer);
}
GlyphAtlas::GlyphAtlas(Type type) : type_(type) {}
GlyphAtlas::~GlyphAtlas() = default;
bool GlyphAtlas::IsValid() const {
return !!texture_;
}
GlyphAtlas::Type GlyphAtlas::GetType() const {
return type_;
}
const std::shared_ptr<Texture>& GlyphAtlas::GetTexture() const {
return texture_;
}
void GlyphAtlas::SetTexture(std::shared_ptr<Texture> texture) {
texture_ = std::move(texture);
}
void GlyphAtlas::AddTypefaceGlyphPosition(const FontGlyphPair& pair,
Rect rect) {
font_atlas_map_[pair.scaled_font].positions_[pair.glyph] = rect;
}
std::optional<Rect> GlyphAtlas::FindFontGlyphBounds(
const FontGlyphPair& pair) const {
const auto& found = font_atlas_map_.find(pair.scaled_font);
if (found == font_atlas_map_.end()) {
return std::nullopt;
}
return found->second.FindGlyphBounds(pair.glyph);
}
const FontGlyphAtlas* GlyphAtlas::GetFontGlyphAtlas(const Font& font,
Scalar scale) const {
const auto& found = font_atlas_map_.find({font, scale});
if (found == font_atlas_map_.end()) {
return nullptr;
}
return &found->second;
}
size_t GlyphAtlas::GetGlyphCount() const {
return std::accumulate(font_atlas_map_.begin(), font_atlas_map_.end(), 0,
[](const int a, const auto& b) {
return a + b.second.positions_.size();
});
}
size_t GlyphAtlas::IterateGlyphs(
const std::function<bool(const ScaledFont& scaled_font,
const Glyph& glyph,
const Rect& rect)>& iterator) const {
if (!iterator) {
return 0u;
}
size_t count = 0u;
for (const auto& font_value : font_atlas_map_) {
for (const auto& glyph_value : font_value.second.positions_) {
count++;
if (!iterator(font_value.first, glyph_value.first, glyph_value.second)) {
return count;
}
}
}
return count;
}
std::optional<Rect> FontGlyphAtlas::FindGlyphBounds(const Glyph& glyph) const {
const auto& found = positions_.find(glyph);
if (found == positions_.end()) {
return std::nullopt;
}
return found->second;
}
} // namespace impeller