Skip to content

Commit 23b606a

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

File tree

1 file changed

+171
-0
lines changed

1 file changed

+171
-0
lines changed

ift/encoder/encoder_config.proto

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

0 commit comments

Comments
 (0)