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