Skip to content

Commit 3bce7df

Browse files
committed
First pass at defining an updated encoder configuration scheme that does not rely on IFTB.
1 parent 4e08ef3 commit 3bce7df

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed

ift/encoder/encoder_config.proto

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
edition = "2023";
2+
3+
// This message is used to configure and IFT encoder to generate and IFT encoding of some input font.
4+
//
5+
// 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)
6+
// patches to extend non-glyph data (everything other than glyf, gvar, CFF, and CFF2) and glyph keyed patches to extend
7+
// the glyph data tables (glyf, gvar, CFF, CFF2).
8+
//
9+
// The configuration has two distinct parts, the first "Glyph Data Extension Configuration" section configures how the font
10+
// will be split into a set of glyph keyed patches. The generated encoding will contain one glyph keyed patch per specified
11+
// glyph segment and unique configuration of the design space reachable via the non glyph table keyed patches.
12+
//
13+
// By default each glyph segment will be reachable by matching any code points that map to any glyph in that segment.
14+
// However, this default mapping can be overriden use the glyph_patch_dependecies map to specify a set of glyph segments
15+
// and features that when matched will trigger that glyph segment. For example if there were three input segments (1, 2, 3)
16+
// where segment 1 contained the f glyph, segment 2 contained the i glyph and segment 3 contains the fi ligature glyph
17+
// then segment 3 should be configured to be dependent on segments 1 and 2 which would result in segment 3 to only be
18+
// selected by the client if segments 1 and 2 were also selected.
19+
//
20+
// The second section of the configuration is the "Non Glyph Extension Configuration" which describes how to segment the
21+
// data in all non-glyph tables (everything but glyf, gvar, CFF, and CFF2). These tables will be extended by table keyed
22+
// patches. Since table keyed patches are invalidating (see: https://w3c.github.io/IFT/Overview.html#font-patch-invalidations)
23+
// a graph of patches will be produced such that the font can be extended to include data for any of the specified segments.
24+
//
25+
// In the simplest case a graph is generated by the following process:
26+
// - each node will contain one patch per code point, feature, and design space segment that has not yet been included.
27+
// Where each patch will extend the font to add data only for the associated segment.
28+
//
29+
// Additional controls are provided which can modify how the graph is formed. For example to reduce potential client
30+
// round trips or reduce the number of patches in the graph. The following options are provided:
31+
//
32+
// - jump_ahead: defaults to 1, normally each node would contain one patch per outstanding segment. If jump ahead is greater
33+
// than 1 then additional patches will be included at each node which simultaneously extends the font to
34+
// all combinations of 2 through jump_ahead segments. For example if a node has three segments a, b, and c
35+
// and jump ahead is set to 2 then the node will include patches for a, b, c, a+b, a+c, and b+c.
36+
//
37+
// - max_depth: max depth limits the depth of the produced graph. In the second last level of the graph all nodes will
38+
// contain only a single patch which adds all remaining segments. This setting is useful to limit the total
39+
// size of the graph.
40+
//
41+
// - include_all_segment_patches: if true in the generated table keyed patch graph every node (in addition to the usual patches)
42+
// will have a patch available which adds all remaining segments to the font. This makes
43+
// it possible for the client to reach any combination of coverage in at most one round
44+
// trip from any intermediate (or initial) state.
45+
message EncoderConfig {
46+
47+
// TODO validation criteria for the configuration:
48+
// - check that fully expanded font meets closure requirement.
49+
50+
// ### Glyph Data Extension Configuration ###
51+
52+
// A list of segments. In the generated encoding there will be one glyph keyed patch (containing all
53+
// data for all of the glyphs in the segment) per segment and unique design space configuration.
54+
//
55+
// The key of the mapping is an integer id which other parts of the configuration can use to reference the segment.
56+
map<uint32, GlyphPatches> glyph_segments = 1;
57+
58+
// Encodes a depencies between other glyph patches and layout features.
59+
//
60+
// An entry in this map implies that the patch mapping entry for the glyph patch identified by the key
61+
// will be set up such that it will only be matched for loading iff:
62+
// - All of GlyphPatchDependency.required_patches are matched, AND
63+
// - All of GlyphPatchDependency.required_features are matched.
64+
map<uin32, GlyphPatchDependency> glyph_patch_dependencies = 2;
65+
66+
// ### Non Glyph Extension Configuration ###
67+
68+
// For table keyed patches the patch graph will include patches that can add up to this many
69+
// segments in a single patch. Defaults to 1.
70+
uint32 jump_ahead = 3;
71+
72+
// For table keyed patches the patch graph will be at most this many levels deep, or in other
73+
// words at most max depth round trips will ever be needed to reach any content in the font.
74+
//
75+
// This is implemented in the graph by having the nodes in the second last level contain
76+
// only a single patch which adds everything remaining.
77+
//
78+
// Defaults to unlimited depth.
79+
uint32 max_depth = 4;
80+
81+
// In the generated table keyed patch graph every node (in addition to the usual patches) will
82+
// have a patch available which adds everything remaining to the font. This makes it possible
83+
// for the client to reach any combination of coverage in at most one round trip from any
84+
// intermediate (or initial) state.
85+
bool include_all_segment_patches = 5;
86+
87+
// The initial_* fields defines all of the data that the initial IFT font will include. If these are all
88+
// left empty then the initial font will be a desiccated font which contains the minimum possible amount of
89+
// data.
90+
//
91+
// Any glyph patches listed in initial_glyph_patches will be added to the initial font and patch files will
92+
// not be generated for them. Glyph dependencies will be automatically updated to reflect the inclusion of
93+
// these patches in the initial font. Any glyph patches whose dependencies are satisfied as a result will also be
94+
// included in the initial font (this is done recursively).
95+
Codepoints initial_codepoints = 6;
96+
GlyphPatches initial_glyph_patches = 7;
97+
Features initial_features = 8;
98+
DesignSpace initial_design_space = 9;
99+
100+
// Groups of codepoints which the non glyph data in the font can be extended in a single
101+
// jump. These can be specified as either groups of codepoints
102+
// (via non_glyph_codepoint_segmentation), or by grouping together glyph keyed patches defined
103+
// above (via glyph_patch_groupings).
104+
repeated Codepoints non_glyph_codepoint_segmentation = 10;
105+
106+
// An alternative way to specify codepoint segmentations. One segment will be formed from
107+
// the union of all of the codepoints associated with each referenced glyph patch. Glyph
108+
// patches are defined above. This field can be used in addition to non_glyph_codepoint_segmentation.
109+
repeated GlyphPatches glyph_patch_groupings = 11;
110+
111+
// Groups of open type layout features which the non glyph data in the font can be extended
112+
// for in a single jump.
113+
//
114+
// Note: all segments (codepoints, features, design space) implicitly include the features
115+
// in the "default feature list" (https://w3c.github.io/IFT/Overview.html#feature-tag-list)
116+
// so this segmentation should be used to provide optional access to features not already
117+
// on that list.
118+
repeated Features non_glyph_feature_segmentation = 12;
119+
120+
// Parts of the fonts overall design space which the non glyph data in the font can be extended
121+
// for in a single jump.
122+
repeated DesignSpace non_glyph_design_space_segmentation = 13;
123+
124+
// ### Glyph and Non Glyph Configuration ###
125+
126+
// If true, the for each of glyph, codepoint, feature, and design space segmentations an additional segment
127+
// will be automatically added (if needed) which includes anything not covered by the specified segments
128+
//
129+
// Note: this applies to both the glyph and non-glyph segmentations.
130+
//
131+
// Setting this ensures that all data in the original font is always reachable.
132+
bool add_everything_else_segments = 14;
133+
}
134+
135+
message GlyphPatchDependency {
136+
GlyphPatches required_patches = 1;
137+
Features required_features = 2;
138+
}
139+
140+
// A list of glyph patch ids
141+
message GlyphPatches {
142+
repeated uint32 values = 1;
143+
}
144+
145+
// A list of glyph ids
146+
message Glyphs {
147+
repeated uint32 values = 1;
148+
}
149+
150+
// A list of unicode code points.
151+
message Codepoints {
152+
repeated uint32 values = 1;
153+
}
154+
155+
// A list of open type layout feature tags.
156+
message Features {
157+
repeated string values = 1;
158+
}
159+
160+
// A variable font design space.
161+
message DesignSpace {
162+
// TODO
163+
}

0 commit comments

Comments
 (0)