1 /* tacontrol.h */
2 
3 /*
4  * Copyright (C) 2014-2021 by Werner Lemberg.
5  *
6  * This file is part of the ttfautohint library, and may only be used,
7  * modified, and distributed under the terms given in `COPYING'.  By
8  * continuing to use, modify, or distribute this file you indicate that you
9  * have read `COPYING' and understand and accept it fully.
10  *
11  * The file `COPYING' mentioned in the previous paragraph is distributed
12  * with the ttfautohint library.
13  */
14 
15 
16 #ifndef TACONTROL_H_
17 #define TACONTROL_H_
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #include <setjmp.h>  /* for flex error handling */
24 
25 
26 /* see the section `Managing exceptions' in chapter 6 */
27 /* (`The TrueType Instruction Set') of the OpenType reference */
28 /* how `delta_shift' works */
29 
30 #define CONTROL_DELTA_SHIFT 3 /* 1/8px */
31 #define CONTROL_DELTA_FACTOR (1 << CONTROL_DELTA_SHIFT)
32 
33 #define CONTROL_DELTA_SHIFT_MAX ((1.0 / CONTROL_DELTA_FACTOR) * 8)
34 #define CONTROL_DELTA_SHIFT_MIN -CONTROL_DELTA_SHIFT_MAX
35 
36 
37 /*
38  * For the generated TrueType bytecode, we use
39  *
40  *   delta_base = 6   ,
41  *
42  * which gives us the following ppem ranges for the three delta
43  * instructions:
44  *
45  *   DELTAP1    6-21ppem
46  *   DELTAP2   22-37ppem
47  *   DELTAP3   38-53ppem   .
48  */
49 
50 #define CONTROL_DELTA_PPEM_MIN 6
51 #define CONTROL_DELTA_PPEM_MAX 53
52 
53 
54 /*
55  * The control type.
56  */
57 
58 typedef enum Control_Type_
59 {
60   Control_Delta_before_IUP,
61   Control_Delta_after_IUP,
62   Control_Single_Point_Segment_Left,
63   Control_Single_Point_Segment_Right,
64   Control_Single_Point_Segment_None,
65   Control_Script_Feature_Glyphs,
66   Control_Script_Feature_Widths
67 } Control_Type;
68 
69 
70 /*
71  * A structure to hold control instructions.  A linked list of it gets
72  * allocated by a successful call to `TA_control_parse_buffer'.  Use
73  * `TA_control_free' to deallocate the list.
74  *
75  * `x_shift' and `y_shift' are in the range [-8;8] for delta exceptions
76  * and in the range [SHRT_MIN;SHRT_MAX] for one-point segment offsets.
77  *
78  * The `Control' typedef is in `ta.h'.
79  */
80 
81 struct Control_
82 {
83   Control_Type type;
84 
85   long font_idx;
86   long glyph_idx;
87   number_range* points;
88   int x_shift;
89   int y_shift;
90   number_range* ppems;
91 
92   int line_number;
93 
94   struct Control_* next;
95 };
96 
97 
98 /*
99  * A structure to hold a single control instruction.
100  */
101 
102 typedef struct Ctrl_
103 {
104   Control_Type type;
105 
106   long font_idx;
107   long glyph_idx;
108   int ppem;
109   int point_idx;
110 
111   int x_shift;
112   int y_shift;
113 
114   int line_number;
115 } Ctrl;
116 
117 
118 /*
119  * This structure is used for communication with `TA_control_parse'.
120  */
121 
122 typedef struct Control_Context_
123 {
124   /* The error code returned by the parser or lexer. */
125   TA_Error error;
126 
127   /* If no error, this holds the parsing result. */
128   Control* result;
129 
130   /*
131    * The parser's or lexer's error message in case of error; might be the
132    * empty string.
133    */
134   char errmsg[256];
135 
136   /*
137    * In case of error, `errline_num' gives the line number of the offending
138    * line in `font->control_buf', starting with value 1; `errline_pos_left'
139    * and `errline_pos_right' hold the left and right position of the
140    * offending token in this line, also starting with value 1.  For
141    * allocation errors or internal parser or lexer errors those values are
142    * meaningless, though.
143    */
144   int errline_num;
145   int errline_pos_left;
146   int errline_pos_right;
147 
148   /*
149    * The current font index, useful for `TA_Err_Control_Invalid_Font_Index'.
150    */
151   long font_idx;
152 
153   /*
154    * The current glyph index, useful for
155    * `TA_Err_Control_Invalid_Glyph_Index'.
156    */
157   long glyph_idx;
158 
159   /*
160    * If the returned error is `TA_Err_Control_Invalid_Range', these two
161    * values set up the allowed range.
162    */
163   int number_set_min;
164   int number_set_max;
165 
166   /*
167    * Some sets restrict the number of elements.
168    */
169   int number_set_num_elems;
170 
171   /* private flex data */
172   void* scanner;
173   int eof;
174   jmp_buf jump_buffer;
175 
176   /* private bison data */
177   FONT* font;
178 } Control_Context;
179 
180 
181 /*
182  * Create and initialize a `Control' object.  In case of an allocation error,
183  * the return value is NULL.  `point_set' and `ppem_set' are expected to be
184  * in reverse list order; `TA_control_new' then reverts them to normal order.
185  */
186 
187 Control*
188 TA_control_new(Control_Type type,
189                long font_idx,
190                long glyph_idx,
191                number_range* point_set,
192                double x_shift,
193                double y_shift,
194                number_range* ppem_set,
195                int line_number);
196 
197 
198 /*
199  * Prepend `element' to `list' of `Control' objects.  If `element' is NULL,
200  * return `list.
201  */
202 
203 Control*
204 TA_control_prepend(Control* list,
205                    Control* element);
206 
207 
208 /*
209  * Reverse a list of `Control' objects.
210  */
211 
212 Control*
213 TA_control_reverse(Control* list);
214 
215 
216 /*
217  * Initialize the scanner data within a `Control_Context' object.
218  * `font->control_buf' is the control instructions buffer to be parsed,
219  * `font->control_len' its length.
220  *
221  * This function is defined in `tacontrol.flex'.
222  */
223 
224 void
225 TA_control_scanner_init(Control_Context* context,
226                         FONT* font);
227 
228 
229 /*
230  * Free the scanner data within a `Control_Context' object.
231  *
232  * This function is defined in `tacontrol.flex'.
233  */
234 
235 void
236 TA_control_scanner_done(Control_Context* context);
237 
238 
239 /*
240  * Parse buffer with ttfautohint control instructions, stored in
241  * `font->control_buf' with length `font->control_len'.
242  *
243  * The format of entries in such a control instructions buffer is given in
244  * `ttfautohint.h' (option `control-file'); the following describes more
245  * technical details, using the constants defined above.
246  *
247  * x shift and y shift values represent floating point numbers that get
248  * rounded to multiples of 1/(2^CONTROL_DELTA_SHIFT) pixels.
249  *
250  * Values for x and y shifts must be in the range
251  * [CONTROL_DELTA_SHIFT_MIN;CONTROL_DELTA_SHIFT_MAX].  Values for ppems must
252  * be in the range [CONTROL_DELTA_PPEM_MIN;CONTROL_DELTA_PPEM_MAX].
253  *
254  * The returned error codes are 0 (TA_Err_Ok) or in the range 0x200-0x2FF;
255  * see `ttfautohint-errors.h' for all possible values.
256  *
257  * `TA_control_parse_buffer' stores the parsed result in `font->control', to
258  * be freed with `TA_control_free' after use.  If there is no control
259  * instructions data (for example, an empty string or whitespace only)
260  * nothing gets allocated, and `font->control' is set to NULL.
261  *
262  * In case of error, `error_string_p' holds an error message, `errlinenum_p'
263  * gives the line number in the control instructions buffer where the error
264  * occurred, `errline_p' the corresponding line, and `errpos_p' the position
265  * in this line.  After use, `error_string_p' and `errline_p' must be
266  * deallocated by the user.  Note that `errline_p' and `errpos_p' can be
267  * NULL even in case of an error.  If there is no error, those four values
268  * are undefined.
269  */
270 
271 TA_Error
272 TA_control_parse_buffer(FONT* font,
273                         char** error_string_p,
274                         unsigned int* errlinenum_p,
275                         char** errline_p,
276                         char** errpos_p);
277 
278 
279 /*
280  * Apply coverage data from the control instructions file.
281  */
282 
283 void
284 TA_control_apply_coverage(SFNT* sfnt,
285                           FONT* font);
286 
287 
288 /*
289  * Handle stem width data from the control instructions file.
290  */
291 
292 void
293 TA_control_set_stem_widths(TA_LatinMetrics metrics,
294                            FONT* font);
295 
296 
297 /*
298  * Free the allocated data in `control'.
299  */
300 
301 void
302 TA_control_free(Control* control);
303 
304 
305 /*
306  * Return a string representation of `font->control'.  After use, the string
307  * should be deallocated with a call to `free'.  In case of an allocation
308  * error, the return value is NULL.
309  */
310 
311 char*
312 TA_control_show(FONT* font);
313 
314 
315 /*
316  * Build a tree providing sequential access to the control instructions data
317  * in `font->control'.  This also sets `font->control_data_cur' to the first
318  * element (or NULL if there isn't one).
319  */
320 
321 TA_Error
322 TA_control_build_tree(FONT* font);
323 
324 
325 /*
326  * Free the control instructions data tree.
327  */
328 
329 void
330 TA_control_free_tree(FONT* font);
331 
332 
333 /*
334  * Get next control instruction and store it in `font->control_data_cur'.
335  */
336 
337 void
338 TA_control_get_next(FONT* font);
339 
340 
341 /*
342  * Access control instruction.  Return NULL if there is no more data.
343  */
344 
345 const Ctrl*
346 TA_control_get_ctrl(FONT* font);
347 
348 
349 /*
350  * Collect one-point segment data for a given glyph index and store them in
351  * `font->control_segment_dirs'.
352  */
353 
354 TA_Error
355 TA_control_segment_dir_collect(FONT* font,
356                                long font_idx,
357                                long glyph_idx);
358 
359 
360 /*
361  * Access next one-point segment data.  Returns 1 on success or 0 if no more
362  * data.  In the latter case, it resets the internal iterator so that
363  * calling this function another time starts at the beginning again.
364  */
365 
366 int
367 TA_control_segment_dir_get_next(FONT* font,
368                                 int* point_idx,
369                                 TA_Direction* dir,
370                                 int* left_offset,
371                                 int* right_offset);
372 
373 
374 #ifdef __cplusplus
375 } /* extern "C" */
376 #endif
377 
378 #endif /* TACONTROL_H_ */
379 
380 /* end of control.h */
381