Skip to content

Commit 0af1253

Browse files
committed
Add method to FontHelper to get the size of the outline data for a set of glyphs.
1 parent 0b72634 commit 0af1253

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

common/font_helper.cc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "hb-ot.h"
1414
#include "hb-subset.h"
1515
#include "hb.h"
16+
#include "common/try.h"
1617

1718
using absl::btree_set;
1819
using absl::flat_hash_map;
@@ -47,6 +48,7 @@ bool FontHelper::HasWideGvar(const hb_face_t* face) {
4748
return (((uint8_t)gvar.str()[gvar_flags_offset]) & 0x01);
4849
}
4950

51+
5052
absl::StatusOr<string_view> FontHelper::GlyfData(const hb_face_t* face,
5153
uint32_t gid) {
5254
auto loca = Loca(face);
@@ -124,6 +126,33 @@ FontData FontHelper::Cff2Data(hb_face_t* face, uint32_t gid) {
124126
return data;
125127
}
126128

129+
StatusOr<uint32_t> FontHelper::TotalGlyphData(hb_face_t* face, const GlyphSet& gids) {
130+
auto tags = FontHelper::GetTags(face);
131+
132+
uint32_t total = 0;
133+
for (uint32_t gid : gids) {
134+
// TODO(grieger): write this using indexed data readers instead so we can
135+
// avoid the per glyph setup overhead incurred by the *Data() methods.
136+
if (tags.contains(FontHelper::kGlyf)) {
137+
total += TRY(FontHelper::GlyfData(face, gid)).size();
138+
}
139+
140+
if (tags.contains(FontHelper::kGvar)) {
141+
total += TRY(FontHelper::GvarData(face, gid)).size();
142+
}
143+
144+
if (tags.contains(FontHelper::kCFF)) {
145+
total += FontHelper::CffData(face, gid).size();
146+
}
147+
148+
if (tags.contains(FontHelper::kCFF2)) {
149+
total += FontHelper::Cff2Data(face, gid).size();
150+
}
151+
}
152+
153+
return total;
154+
}
155+
127156
Status FontHelper::Cff2GetCharstrings(hb_face_t* face,
128157
FontData& non_charstrings,
129158
FontData& charstrings) {

common/font_helper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ class FontHelper {
145145

146146
static FontData Cff2Data(hb_face_t* face, uint32_t gid);
147147

148+
// Counts up the total size of all glyph data (gvar, glyf, cff, cff2)
149+
// for the provided set of gids.
150+
static absl::StatusOr<uint32_t> TotalGlyphData(hb_face_t* face, const GlyphSet& gids);
151+
148152
static absl::Status Cff2GetCharstrings(hb_face_t* face,
149153
FontData& non_charstrings,
150154
FontData& charstrings);

common/font_helper_test.cc

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,48 @@ TEST_F(FontHelperTest, GlyfData_ShortOverflowSynthetic) {
618618
ASSERT_EQ(*data, expected);
619619
}
620620

621+
TEST_F(FontHelperTest, TotalGlyphData_GlyfGvar) {
622+
auto size = FontHelper::TotalGlyphData(roboto_vf.get(), GlyphSet {78, 83, 95});
623+
ASSERT_TRUE(size.ok()) << size.status();
624+
625+
uint32_t expected =
626+
FontHelper::GlyfData(roboto_vf.get(), 78)->size() +
627+
FontHelper::GlyfData(roboto_vf.get(), 83)->size() +
628+
FontHelper::GlyfData(roboto_vf.get(), 95)->size() +
629+
FontHelper::GvarData(roboto_vf.get(), 78)->size() +
630+
FontHelper::GvarData(roboto_vf.get(), 83)->size() +
631+
FontHelper::GvarData(roboto_vf.get(), 95)->size();
632+
633+
ASSERT_GT(*size, 0);
634+
ASSERT_EQ(*size, expected);
635+
}
636+
637+
TEST_F(FontHelperTest, TotalGlyphData_Cff) {
638+
auto size = FontHelper::TotalGlyphData(noto_sans_jp_otf.get(), GlyphSet {78, 83, 95});
639+
ASSERT_TRUE(size.ok()) << size.status();
640+
641+
uint32_t expected =
642+
FontHelper::CffData(noto_sans_jp_otf.get(), 78).size() +
643+
FontHelper::CffData(noto_sans_jp_otf.get(), 83).size() +
644+
FontHelper::CffData(noto_sans_jp_otf.get(), 95).size();
645+
646+
ASSERT_GT(*size, 0);
647+
ASSERT_EQ(*size, expected);
648+
}
649+
650+
TEST_F(FontHelperTest, TotalGlyphData_Cff2) {
651+
auto size = FontHelper::TotalGlyphData(noto_sans_vf_jp_otf.get(), GlyphSet {34, 35, 46});
652+
ASSERT_TRUE(size.ok()) << size.status();
653+
654+
uint32_t expected =
655+
FontHelper::Cff2Data(noto_sans_vf_jp_otf.get(), 34).size() +
656+
FontHelper::Cff2Data(noto_sans_vf_jp_otf.get(), 35).size() +
657+
FontHelper::Cff2Data(noto_sans_vf_jp_otf.get(), 46).size();
658+
659+
ASSERT_GT(*size, 0);
660+
ASSERT_EQ(*size, expected);
661+
}
662+
621663
// TODO test BuildFont...
622664

623665
} // namespace common

0 commit comments

Comments
 (0)