Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions ift/config/config_compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ Status ConfigCompiler::Configure(const SegmentationPlan& plan,
compiler.SetJumpAhead(plan.jump_ahead());
}
compiler.SetUsePrefetchLists(plan.use_prefetch_lists());
if (plan.max_depth() > 0) {
compiler.SetMaxDepth(plan.max_depth());
}

if (plan.has_advanced_settings()) {
const auto& advanced = plan.advanced_settings();
Expand All @@ -167,10 +170,6 @@ Status ConfigCompiler::Configure(const SegmentationPlan& plan,
"include_all_segment_patches is not yet supported.");
}

if (plan.max_depth() > 0) {
return absl::UnimplementedError("max_depth is not yet supported.");
}

return absl::OkStatus();
}

Expand Down
11 changes: 11 additions & 0 deletions ift/config/config_compiler_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,15 @@ TEST(ConfigCompilerTest, ConfigureOverrideUrlTemplatePrefix) {
EXPECT_EQ(compiler.override_url_template_prefix(), expected);
}

TEST(ConfigCompilerTest, ConfigureMaxDepth) {
Compiler compiler;
SegmentationPlan plan;
plan.set_max_depth(3);

absl::Status status = ConfigCompiler::Configure(plan, compiler);
ASSERT_TRUE(status.ok()) << status;

EXPECT_EQ(compiler.max_depth(), 3);
}

} // namespace ift::config
2 changes: 0 additions & 2 deletions ift/config/segmentation_plan.proto
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ message SegmentationPlan {
// only a single patch which adds everything remaining.
//
// Defaults to unlimited depth.
//
// Note: this is currently UNIMPLEMENTED in the encoder.
uint32 max_depth = 6;

// In the generated table keyed patch graph every node (in addition to the usual patches) will
Expand Down
58 changes: 55 additions & 3 deletions ift/encoder/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ StatusOr<FontData> Compiler::FullyExpandedSubset(
return CutSubset(context, face_.get(), all, false);
}

std::vector<Compiler::Edge> Compiler::OutgoingEdges(
const SubsetDefinition& node_subset, uint32_t choose) const {
std::vector<SubsetDefinition> Compiler::RemainingSubsets(
const SubsetDefinition& node_subset) const {
std::vector<SubsetDefinition> remaining_subsets;
for (const auto& s : extension_subsets_) {
SubsetDefinition filtered = s;
Expand All @@ -115,6 +115,22 @@ std::vector<Compiler::Edge> Compiler::OutgoingEdges(

remaining_subsets.push_back(std::move(filtered));
}
return remaining_subsets;
}

SubsetDefinition Compiler::RemainingSubsetDefinition(
const SubsetDefinition& node_subset) const {
SubsetDefinition remaining;
for (const auto& s : RemainingSubsets(node_subset)) {
remaining.Union(s);
}
return remaining;
}

std::vector<Compiler::Edge> Compiler::OutgoingEdges(
const SubsetDefinition& node_subset, uint32_t choose) const {
std::vector<SubsetDefinition> remaining_subsets =
RemainingSubsets(node_subset);

std::vector<const SubsetDefinition*> input;
for (const auto& s : remaining_subsets) {
Expand All @@ -129,6 +145,40 @@ std::vector<Compiler::Edge> Compiler::OutgoingEdges(
return result;
}

std::vector<Compiler::Edge> Compiler::OutgoingEdgesWithMaxDepth(
const ProcessingContext& context,
const SubsetDefinition& node_subset) const {
std::vector<Edge> edges {};
std::vector<SubsetDefinition> remaining_subsets =
RemainingSubsets(node_subset);
if (remaining_subsets.empty()) {
return edges;
}

bool depth_is_limited = max_depth_ > 0;

// The init font node is considered depth 0, one subset added is depth 1, and so on.
size_t depth =
context.initial_remaining_subsets_count_ - remaining_subsets.size();

// Jump ahead needs to be restricted to jump to at most the second last depth
uint32_t choose = jump_ahead_;
if (depth_is_limited && depth + choose >= max_depth_) {
choose = max_depth_ - 1 - depth;
}

if (choose > 0) {
edges = OutgoingEdges(node_subset, choose);
}

if (choose != jump_ahead_ && remaining_subsets.size() >= max_depth_ - depth) {
// Lastly if jump ahead can reach the max depth then we should include a jump to add all remaining subsets.
edges.push_back(Edge{ RemainingSubsetDefinition(node_subset) });
}

return edges;
}

Status Compiler::AddGlyphDataPatch(uint32_t id, const IntSet& gids) {
if (!face_) {
return absl::FailedPreconditionError("Encoder must have a face set.");
Expand Down Expand Up @@ -210,6 +260,8 @@ StatusOr<Compiler::Encoding> Compiler::Compile() const {
ProcessingContext context(next_id_);
context.init_subset_ = init_subset_;
AddInitSubsetDefaults(context.init_subset_);
context.initial_remaining_subsets_count_ =
RemainingSubsets(context.init_subset_).size();
if (IsMixedMode()) {
// Glyph keyed patches can't change the glyph count in the font (and hence
// loca len) so always include the last gid in the init subset to force the
Expand Down Expand Up @@ -540,7 +592,7 @@ StatusOr<Compiler::CompileResult> Compiler::Compile(
glyph_keyed_url_template,
glyph_keyed_compat_id));

std::vector<Edge> edges = OutgoingEdges(node_subset, jump_ahead_);
std::vector<Edge> edges = OutgoingEdgesWithMaxDepth(context, node_subset);

// The first subset forms the base file, the remaining subsets are made
// reachable via patches.
Expand Down
20 changes: 20 additions & 0 deletions ift/encoder/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ class Compiler {
*/
void SetJumpAhead(uint32_t count) { this->jump_ahead_ = count; }

/*
* Configures the maximum depth of the table keyed patch graph.
* Defaults to 0 (unlimited depth).
*/
void SetMaxDepth(uint32_t max_depth) { this->max_depth_ = max_depth; }
uint32_t max_depth() const { return max_depth_; }

/*
* If enabled then for jump ahead entries preload lists will be used instead
* of a single patch which jumps multiple levels.
Expand Down Expand Up @@ -182,6 +189,9 @@ class Compiler {
}
}

explicit Edge(const SubsetDefinition& value)
: subsets_({value}), combined_(value) {}

void Add(const SubsetDefinition& s) {
subsets_.insert(subsets_.begin(), s);
combined_.Union(s);
Expand Down Expand Up @@ -376,13 +386,22 @@ class Compiler {
std::vector<uint8_t>& url_template,
ift::common::CompatId& compat_id) const;

std::vector<SubsetDefinition> RemainingSubsets(
const SubsetDefinition& node_subset) const;
SubsetDefinition RemainingSubsetDefinition(
const SubsetDefinition& node_subset) const;
std::vector<Edge> OutgoingEdgesWithMaxDepth(
const ProcessingContext& context,
const SubsetDefinition& node_subset) const;

ift::common::hb_face_unique_ptr face_;
absl::btree_map<uint32_t, ift::common::IntSet> glyph_data_patches_;
std::vector<proto::PatchMap::Entry> glyph_patch_conditions_;

SubsetDefinition init_subset_;
std::vector<SubsetDefinition> extension_subsets_;
uint32_t jump_ahead_ = 1;
uint32_t max_depth_ = 0;
uint32_t next_id_ = 0;
bool use_prefetch_lists_ = false;
bool woff2_encode_ = false;
Expand All @@ -400,6 +419,7 @@ class Compiler {
ift::common::FontData fully_expanded_subset_;
bool force_long_loca_and_gvar_ = false;

size_t initial_remaining_subsets_count_ = 0;
uint32_t next_id_ = 0;
uint32_t next_patch_set_id_ =
1; // id 0 is reserved for table keyed patches.
Expand Down
Loading
Loading