Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First pass at defining an updated encoder configuration scheme that does not rely on IFTB. #87

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
171 changes: 171 additions & 0 deletions ift/encoder/encoder_config.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
edition = "2023";

// This message is used to configure an IFT encoder to generate and IFT encoding of some input font.
//
// The produced encoding will be a "mixed mode" encoding that makes use of both table keyed (https://w3c.github.io/IFT/Overview.html#table-keyed)
// patches to extend non-glyph data (everything other than glyf, gvar, CFF, and CFF2) and glyph keyed patches
// to extend the glyph data tables (glyf, gvar, CFF, CFF2).
//
// The configuration has two distinct parts, the first "Glyph Data Extension Configuration" section
// configures how the font will be split into a set of glyph keyed patches. The generated encoding will
// contain one glyph keyed patch per specified glyph segment and unique configuration of the design space
// reachable via the non glyph table keyed patches.
//
// By default each glyph segment will be reachable by matching any code points that map to any glyph in that
// segment. However, this default mapping can be overriden use the glyph_patch_dependecies map to specify a
// set of glyph segments and features that when matched will trigger that glyph segment. For example if there
// were three input segments (1, 2, 3) where segment 1 contained the f glyph, segment 2 contained the i glyph
// and segment 3 contains the fi ligature glyph then segment 3 should be configured to be dependent on
// segments 1 and 2 which would result in segment 3 to only be selected by the client if segments 1 and 2
// were also selected.
//
// The second section of the configuration is the "Non Glyph Extension Configuration" which describes how to
// segment the data in all non-glyph tables (everything but glyf, gvar, CFF, and CFF2). These tables will be
// extended by table keyed patches. Since table keyed patches are invalidating
// (see: https://w3c.github.io/IFT/Overview.html#font-patch-invalidations) a graph of patches will be
// produced such that the font can be extended to include data for any of the specified segments.
//
// In the simplest case a graph is generated by the following process:
// - each node will contain one patch per code point, feature, and design space segment that has not yet
// been included. Where each patch will extend the font to add data only for the associated segment.
//
// Additional controls are provided which can modify how the graph is formed. For example to reduce
// potential client round trips or reduce the number of patches in the graph. The following options are
// provided:
//
// - jump_ahead: defaults to 1, normally each node would contain one patch per outstanding segment. If
// jump ahead is greater than 1 then additional patches will be included at each node which
// simultaneously extends the font to all combinations of 2 through jump_ahead segments. For
// example if a node has three segments a, b, and c and jump ahead is set to 2 then the node
// will include patches for a, b, c, a+b, a+c, and b+c.
//
// - max_depth: max depth limits the depth of the produced graph. In the second last level of the graph all
// nodes will contain only a single patch which adds all remaining segments. This setting is
// useful to limit the total size of the graph.
//
// - include_all_segment_patches: if true in the generated table keyed patch graph every node (in addition
// to the usual patches) will have a patch available which adds all remaining
// segments to the font. This makes it possible for the client to reach any
// combination of coverage in at most one round trip from any intermediate
// (or initial) state.
message EncoderConfig {

// TODO validation criteria for the configuration:
// - check that fully expanded font meets closure requirement.
// TODO mechanism to specify uvs to glyph patch deps.

// ### Glyph Data Extension Configuration ###

// A list of segments. In the generated encoding there will be one glyph keyed patch (containing all
// data for all of the glyphs in the segment) per segment and unique design space configuration.
//
// The key of the mapping is an integer id which other parts of the configuration can use to reference
// the segment.
map<uint32, GlyphPatches> glyph_segments = 1;

// Encodes a depencies between other glyph patches and layout features.
//
// An entry in this map implies that the patch mapping entry for the glyph patch identified by the key
// will be set up such that it will only be matched for loading iff:
// - All of GlyphPatchDependency.required_patches are matched, AND
// - All of GlyphPatchDependency.required_features are matched.
map<uin32, GlyphPatchDependency> glyph_patch_dependencies = 2;

// ### Non Glyph Extension Configuration ###

// For table keyed patches the patch graph will include patches that can add up to this many
// segments in a single patch. Defaults to 1.
uint32 jump_ahead = 3;

// For table keyed patches the patch graph will be at most this many levels deep, or in other
// words at most max depth round trips will ever be needed to reach any content in the font.
//
// This is implemented in the graph by having the nodes in the second last level contain
// only a single patch which adds everything remaining.
//
// Defaults to unlimited depth.
uint32 max_depth = 4;

// In the generated table keyed patch graph every node (in addition to the usual patches) will
// have a patch available which adds everything remaining to the font. This makes it possible
// for the client to reach any combination of coverage in at most one round trip from any
// intermediate (or initial) state.
bool include_all_segment_patches = 5;

// The initial_* fields defines all of the data that the initial IFT font will include. If these are all
// left empty then the initial font will be a desiccated font which contains the minimum possible amount of
// data.
//
// Any glyph patches listed in initial_glyph_patches will be added to the initial font and patch files will
// not be generated for them. Glyph dependencies will be automatically updated to reflect the inclusion of
// these patches in the initial font. Any glyph patches whose dependencies are satisfied as a result will
// also be included in the initial font (this is done recursively).
Codepoints initial_codepoints = 6;
GlyphPatches initial_glyph_patches = 7;
Features initial_features = 8;
DesignSpace initial_design_space = 9;

// Groups of codepoints which the non glyph data in the font can be extended in a single
// jump. These can be specified as either groups of codepoints
// (via non_glyph_codepoint_segmentation), or by grouping together glyph keyed patches defined
// above (via glyph_patch_groupings).
repeated Codepoints non_glyph_codepoint_segmentation = 10;

// An alternative way to specify codepoint segmentations. One segment will be formed from
// the union of all of the codepoints associated with each referenced glyph patch. Glyph
// patches are defined above. This field can be used in addition to non_glyph_codepoint_segmentation.
repeated GlyphPatches glyph_patch_groupings = 11;

// Groups of open type layout features which the non glyph data in the font can be extended
// for in a single jump.
//
// Note: all segments (codepoints, features, design space) implicitly include the features
// in the "default feature list" (https://w3c.github.io/IFT/Overview.html#feature-tag-list)
// so this segmentation should be used to provide optional access to features not already
// on that list.
repeated Features non_glyph_feature_segmentation = 12;

// Parts of the fonts overall design space which the non glyph data in the font can be extended
// for in a single jump.
repeated DesignSpace non_glyph_design_space_segmentation = 13;

// ### Glyph and Non Glyph Configuration ###

// If true, the for each of glyph, codepoint, feature, and design space segmentations an additional segment
// will be automatically added (if needed) which includes anything not covered by the specified segments
//
// Note: this applies to both the glyph and non-glyph segmentations.
//
// Setting this ensures that all data in the original font is always reachable.
bool add_everything_else_segments = 14;
}

message GlyphPatchDependency {
GlyphPatches required_patches = 1;
Features required_features = 2;
}

// A list of glyph patch ids
message GlyphPatches {
repeated uint32 values = 1;
}

// A list of glyph ids
message Glyphs {
repeated uint32 values = 1;
}

// A list of unicode code points.
message Codepoints {
repeated uint32 values = 1;
}

// A list of open type layout feature tags.
message Features {
repeated string values = 1;
}

// A variable font design space.
message DesignSpace {
// TODO
}
Loading