4 * Copyright (C) 2011 by Werner Lemberg.
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.
11 * The file `COPYING' mentioned in the previous paragraph is distributed
12 * with the ttfautohint library.
20 TA_sfnt_build_glyf_hints(SFNT
* sfnt
,
23 FT_Face face
= sfnt
->face
;
28 /* this loop doesn't include the artificial `.ttfautohint' glyph */
29 for (idx
= 0; idx
< face
->num_glyphs
; idx
++)
31 error
= TA_sfnt_build_glyph_instructions(sfnt
, font
, idx
);
35 font
->progress(idx
, face
->num_glyphs
,
36 sfnt
- font
->sfnts
, font
->num_sfnts
,
45 TA_glyph_get_components(GLYPH
* glyph
,
51 FT_UShort
* components_new
;
63 /* walk over component records */
67 return FT_Err_Invalid_Table
;
72 /* add component to list */
73 component
= *(p
++) << 8;
76 glyph
->num_components
++;
77 components_new
= (FT_UShort
*)realloc(glyph
->components
,
79 * sizeof (FT_UShort
));
82 glyph
->num_components
--;
83 return FT_Err_Out_Of_Memory
;
86 glyph
->components
= components_new
;
88 glyph
->components
[glyph
->num_components
- 1] = component
;
90 /* skip scaling and offset arguments */
91 if (flags
& ARGS_ARE_WORDS
)
96 if (flags
& WE_HAVE_A_SCALE
)
98 else if (flags
& WE_HAVE_AN_XY_SCALE
)
100 else if (flags
& WE_HAVE_A_2X2
)
102 } while (flags
& MORE_COMPONENTS
);
109 TA_glyph_parse_composite(GLYPH
* glyph
,
111 FT_UShort num_glyphs
)
113 FT_ULong flags_offset
; /* after the loop, this is the offset */
114 /* to the last element in the flags array */
126 /* walk over component records */
129 flags_offset
= p
- buf
;
137 /* skip scaling and offset arguments */
138 if (flags
& ARGS_ARE_WORDS
)
143 /* XXX adjust point indices for !ARGS_ARE_XY_VALUES */
145 if (flags
& WE_HAVE_A_SCALE
)
147 else if (flags
& WE_HAVE_AN_XY_SCALE
)
149 else if (flags
& WE_HAVE_A_2X2
)
151 } while (flags
& MORE_COMPONENTS
);
153 /* we prepend a composite glyph component to call some bytecode */
154 /* which eventually becomes the last glyph in the `glyf' table; */
155 /* for convenience, however, it is not added to the `components' array */
156 /* (doing so simplifies the conversion of point indices later on) */
158 /* adjust glyph record length (6 bytes for the additional component) */
159 new_len
= p
- buf
+ 6;
161 glyph
->flags_offset
= flags_offset
+ 6;
163 glyph
->len1
= new_len
;
164 /* glyph->len2 = 0; */
165 glyph
->buf
= (FT_Byte
*)malloc(new_len
);
167 return FT_Err_Out_Of_Memory
;
169 /* copy record without instructions (if any) */
170 /* and construct additional component */
172 memcpy(glyph
->buf
, buf
, 10); /* header */
174 glyph
->buf
[10] = 0x00; /* additional component */
175 glyph
->buf
[11] = ARGS_ARE_XY_VALUES
| MORE_COMPONENTS
;
176 glyph
->buf
[12] = HIGH(num_glyphs
- 1);
177 glyph
->buf
[13] = LOW(num_glyphs
- 1);
178 glyph
->buf
[14] = 0x00;
179 glyph
->buf
[15] = 0x00;
181 memcpy(glyph
->buf
+ 16, buf
+ 10, new_len
- 6 - 10); /* the rest */
183 glyph
->buf
[glyph
->flags_offset
] &= ~(WE_HAVE_INSTR
>> 8);
190 TA_glyph_parse_simple(GLYPH
* glyph
,
195 FT_Byte
* flags_start
;
200 FT_ULong flags_size
; /* size of the flags array */
201 FT_ULong xy_size
; /* size of x and y coordinate arrays together */
212 ins_offset
= 10 + glyph
->num_contours
* 2;
217 return FT_Err_Invalid_Table
;
219 /* get number of instructions */
220 num_ins
= *(p
++) << 8;
226 return FT_Err_Invalid_Table
;
228 num_pts
= glyph
->endpoint
+ 1;
245 return FT_Err_Invalid_Table
;
249 x_short
= (flags
& X_SHORT_VECTOR
) ? 1 : 2;
250 y_short
= (flags
& Y_SHORT_VECTOR
) ? 1 : 2;
252 have_x
= ((flags
& SAME_X
) && !(flags
& X_SHORT_VECTOR
)) ? 0 : 1;
253 have_y
= ((flags
& SAME_Y
) && !(flags
& Y_SHORT_VECTOR
)) ? 0 : 1;
260 return FT_Err_Invalid_Table
;
264 if (i
+ count
> num_pts
)
265 return FT_Err_Invalid_Table
;
268 xy_size
+= count
* x_short
* have_x
;
269 xy_size
+= count
* y_short
* have_y
;
274 if (p
+ xy_size
> endp
)
275 return FT_Err_Invalid_Table
;
277 flags_size
= p
- flags_start
;
279 /* store the data before and after the bytecode instructions */
280 /* in the same array */
281 glyph
->len1
= ins_offset
;
282 glyph
->len2
= flags_size
+ xy_size
;
283 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
285 return FT_Err_Out_Of_Memory
;
287 /* now copy everything but the instructions */
288 memcpy(glyph
->buf
, buf
, glyph
->len1
);
289 memcpy(glyph
->buf
+ glyph
->len1
, flags_start
, glyph
->len2
);
296 TA_iterate_composite_glyph(glyf_Data
* data
,
297 FT_UShort
* components
,
298 FT_UShort num_components
,
299 FT_UShort
** endpoints
,
300 FT_UShort
* num_endpoints
,
301 FT_UShort
* num_composite_contours
,
302 FT_UShort
* num_composite_points
)
304 FT_UShort
* endpoints_new
;
308 /* save current state */
311 endpoints_new
= (FT_UShort
*)realloc(*endpoints
,
313 * sizeof (FT_UShort
));
317 return FT_Err_Out_Of_Memory
;
320 *endpoints
= endpoints_new
;
322 (*endpoints
)[*num_endpoints
- 1] = *num_composite_points
;
324 for (i
= 0; i
< num_components
; i
++)
327 FT_UShort component
= components
[i
];
331 if (component
>= data
->num_glyphs
)
332 return FT_Err_Invalid_Table
;
334 glyph
= &data
->glyphs
[component
];
336 if (glyph
->num_components
)
338 error
= TA_iterate_composite_glyph(data
,
340 glyph
->num_components
,
343 num_composite_contours
,
344 num_composite_points
);
350 *num_composite_contours
+= glyph
->num_contours
;
351 *num_composite_points
+= glyph
->endpoint
+ 1;
359 /* this function actually stores `endpoint + 1' values */
362 TA_sfnt_compute_composite_endpoints(SFNT
* sfnt
,
365 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
366 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
371 for (i
= 0; i
< data
->num_glyphs
; i
++)
373 GLYPH
* glyph
= &data
->glyphs
[i
];
376 if (glyph
->num_components
)
379 FT_UShort num_composite_contours
= 0;
380 FT_UShort num_composite_points
= 0;
383 error
= TA_iterate_composite_glyph(data
,
385 glyph
->num_components
,
387 &glyph
->num_endpoints
,
388 &num_composite_contours
,
389 &num_composite_points
);
393 /* update maximum values, */
394 /* including the subglyphs not in `components' array */
395 /* (each of them has a single point in a single contour) */
396 if (num_composite_points
+ glyph
->num_endpoints
397 > sfnt
->max_composite_points
)
398 sfnt
->max_composite_points
= num_composite_points
399 + glyph
->num_endpoints
;
400 if (num_composite_contours
+ glyph
->num_endpoints
401 > sfnt
->max_composite_contours
)
402 sfnt
->max_composite_contours
= num_composite_contours
403 + glyph
->num_endpoints
;
412 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
415 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
416 SFNT_Table
* loca_table
= &font
->tables
[sfnt
->loca_idx
];
417 SFNT_Table
* head_table
= &font
->tables
[sfnt
->head_idx
];
423 FT_ULong offset_next
;
427 FT_UShort loop_count
;
432 /* in case of success, all allocated arrays are */
433 /* linked and eventually freed in `TA_font_unload' */
435 /* nothing to do if table has already been split */
436 if (glyf_table
->data
)
439 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
441 return FT_Err_Out_Of_Memory
;
443 glyf_table
->data
= data
;
445 loca_format
= head_table
->buf
[LOCA_FORMAT_OFFSET
];
447 data
->num_glyphs
= loca_format
? loca_table
->len
/ 4
448 : loca_table
->len
/ 2;
449 loop_count
= data
->num_glyphs
- 1;
451 /* allocate one more glyph slot if we have composite glyphs */
452 if (!sfnt
->max_components
)
453 data
->num_glyphs
-= 1;
454 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
456 return FT_Err_Out_Of_Memory
;
458 /* first loop over `loca' and `glyf' data */
464 offset_next
= *(p
++) << 24;
465 offset_next
+= *(p
++) << 16;
466 offset_next
+= *(p
++) << 8;
467 offset_next
+= *(p
++);
471 offset_next
= *(p
++) << 8;
472 offset_next
+= *(p
++);
476 for (i
= 0; i
< loop_count
; i
++)
478 GLYPH
* glyph
= &data
->glyphs
[i
];
482 offset
= offset_next
;
486 offset_next
= *(p
++) << 24;
487 offset_next
+= *(p
++) << 16;
488 offset_next
+= *(p
++) << 8;
489 offset_next
+= *(p
++);
493 offset_next
= *(p
++) << 8;
494 offset_next
+= *(p
++);
498 if (offset_next
< offset
499 || offset_next
> glyf_table
->len
)
500 return FT_Err_Invalid_Table
;
502 len
= offset_next
- offset
;
504 continue; /* empty glyph */
510 /* check header size */
512 return FT_Err_Invalid_Table
;
514 /* we need number of contours and the last point for */
515 /* `TA_sfnt_compute_composite_endpoints' */
516 buf
= glyf_table
->buf
+ offset
;
517 glyph
->num_contours
= (FT_Short
)((buf
[0] << 8) + buf
[1]);
519 if (glyph
->num_contours
< 0)
521 error
= TA_glyph_get_components(glyph
, buf
, len
);
530 off
= 10 + (glyph
->num_contours
- 1) * 2;
531 glyph
->endpoint
= buf
[off
] << 8;
532 glyph
->endpoint
+= buf
[off
+ 1];
537 if (sfnt
->max_components
)
539 error
= TA_sfnt_compute_composite_endpoints(sfnt
, font
);
544 /* second loop over `loca' and `glyf' data */
550 offset_next
= *(p
++) << 24;
551 offset_next
+= *(p
++) << 16;
552 offset_next
+= *(p
++) << 8;
553 offset_next
+= *(p
++);
557 offset_next
= *(p
++) << 8;
558 offset_next
+= *(p
++);
562 for (i
= 0; i
< loop_count
; i
++)
564 GLYPH
* glyph
= &data
->glyphs
[i
];
568 offset
= offset_next
;
572 offset_next
= *(p
++) << 24;
573 offset_next
+= *(p
++) << 16;
574 offset_next
+= *(p
++) << 8;
575 offset_next
+= *(p
++);
579 offset_next
= *(p
++) << 8;
580 offset_next
+= *(p
++);
584 len
= offset_next
- offset
;
586 continue; /* empty glyph */
592 buf
= glyf_table
->buf
+ offset
;
594 /* We must parse the rest of the glyph record to get the exact */
595 /* record length. Since the `loca' table rounds record lengths */
596 /* up to multiples of 4 (or 2 for older fonts), and we must round */
597 /* up again after stripping off the instructions, it would be */
598 /* possible otherwise to have more than 4 bytes of padding which */
599 /* is more or less invalid. */
601 if (glyph
->num_contours
< 0)
602 error
= TA_glyph_parse_composite(glyph
, buf
, data
->num_glyphs
);
604 error
= TA_glyph_parse_simple(glyph
, buf
, len
);
610 if (sfnt
->max_components
)
612 /* construct and append our special glyph used as a composite element */
613 GLYPH
* glyph
= &data
->glyphs
[data
->num_glyphs
- 1];
616 FT_Byte bytecode
[] = {
618 /* increment `cvtl_is_subglyph' counter */
631 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
633 return FT_Err_Out_Of_Memory
;
637 buf
[0] = 0x00; /* one contour */
639 buf
[2] = 0x00; /* no dimensions */
647 buf
[10] = 0x00; /* one contour end point */
650 buf
[12] = ON_CURVE
| SAME_X
| SAME_Y
; /* the flags for a point at 0,0 */
652 /* add bytecode also; */
653 /* this works because the loop in `TA_sfnt_build_glyf_hints' */
654 /* doesn't include the newly appended glyph */
655 glyph
->ins_len
= sizeof (bytecode
);
656 glyph
->ins_buf
= (FT_Byte
*)malloc(glyph
->ins_len
);
658 return FT_Err_Out_Of_Memory
;
659 memcpy(glyph
->ins_buf
, bytecode
, glyph
->ins_len
);
661 sfnt
->max_components
+= 1;
669 TA_sfnt_build_glyf_table(SFNT
* sfnt
,
672 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
673 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
683 if (glyf_table
->processed
)
688 glyph
= data
->glyphs
;
689 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
691 /* glyph records should have offsets which are multiples of 4 */
692 len
= (len
+ 3) & ~3;
693 len
+= glyph
->len1
+ glyph
->len2
+ glyph
->ins_len
;
694 /* add two bytes for the instructionLength field */
695 if (glyph
->len2
|| glyph
->ins_len
)
699 /* to make the short format of the `loca' table always work, */
700 /* assure an even length of the `glyf' table */
701 glyf_table
->len
= (len
+ 1) & ~1;
703 buf_new
= (FT_Byte
*)realloc(glyf_table
->buf
, (len
+ 3) & ~3);
705 return FT_Err_Out_Of_Memory
;
707 glyf_table
->buf
= buf_new
;
710 glyph
= data
->glyphs
;
711 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
713 len
= glyph
->len1
+ glyph
->len2
+ glyph
->ins_len
;
714 if (glyph
->len2
|| glyph
->ins_len
)
719 /* copy glyph data and insert new instructions */
720 memcpy(p
, glyph
->buf
, glyph
->len1
);
726 *(p
++) = HIGH(glyph
->ins_len
);
727 *(p
++) = LOW(glyph
->ins_len
);
728 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
730 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
735 /* composite glyph */
738 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
740 *(p
++) = HIGH(glyph
->ins_len
);
741 *(p
++) = LOW(glyph
->ins_len
);
742 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
749 /* pad with zero bytes to have an offset which is a multiple of 4; */
750 /* this works even for the last glyph record since the `glyf' */
751 /* table length is a multiple of 4 also */
766 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
768 glyf_table
->processed
= 1;
775 TA_create_glyph_data(FT_Outline
* outline
,
778 FT_Error error
= TA_Err_Ok
;
784 FT_Byte
* flags
= NULL
;
798 if (!outline
->n_contours
)
799 return TA_Err_Ok
; /* empty glyph */
801 /* in case of success, all non-local allocated arrays are */
802 /* linked and eventually freed in `TA_font_unload' */
806 /* we use `calloc' since we rely on the array */
807 /* being initialized to zero; */
808 /* additionally, we need one more byte for a test after the loop */
809 flags
= (FT_Byte
*)calloc(1, outline
->n_points
+ 1);
812 error
= FT_Err_Out_Of_Memory
;
816 /* we have either one-byte or two-byte elements */
817 x
= (FT_Byte
*)malloc(2 * outline
->n_points
);
820 error
= FT_Err_Out_Of_Memory
;
824 y
= (FT_Byte
*)malloc(2 * outline
->n_points
);
827 error
= FT_Err_Out_Of_Memory
;
834 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
835 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
838 oldf
= 0x80; /* start with an impossible value */
840 /* convert the FreeType representation of the glyph's outline */
841 /* into the representation format of the `glyf' table */
842 for (i
= 0; i
< outline
->n_points
; i
++)
844 FT_Pos xcur
= (outline
->points
[i
].x
+ 32) >> 6;
845 FT_Pos ycur
= (outline
->points
[i
].y
+ 32) >> 6;
847 FT_Pos xdelta
= xcur
- lastx
;
848 FT_Pos ydelta
= ycur
- lasty
;
851 /* we are only interested in bit 0 of the `tags' array */
852 f
= outline
->tags
[i
] & ON_CURVE
;
860 if (xdelta
< 256 && xdelta
> -256)
869 *(xp
++) = (FT_Byte
)xdelta
;
873 *(xp
++) = HIGH(xdelta
);
874 *(xp
++) = LOW(xdelta
);
884 if (ydelta
< 256 && ydelta
> -256)
893 *(yp
++) = (FT_Byte
)ydelta
;
897 *(yp
++) = HIGH(ydelta
);
898 *(yp
++) = LOW(ydelta
);
904 /* set repeat flag */
905 *(flagsp
- 1) |= REPEAT
;
909 /* we can only handle 256 repetitions at once, */
910 /* so use a new counter */
915 *flagsp
+= 1; /* increase repetition counter */
920 flagsp
++; /* skip repetition counter */
938 /* if the last byte was a repetition counter, */
939 /* we must increase by one to get the correct array size */
943 header
[0] = HIGH(outline
->n_contours
);
944 header
[1] = LOW(outline
->n_contours
);
945 header
[2] = HIGH(xmin
);
946 header
[3] = LOW(xmin
);
947 header
[4] = HIGH(ymin
);
948 header
[5] = LOW(ymin
);
949 header
[6] = HIGH(xmax
);
950 header
[7] = LOW(xmax
);
951 header
[8] = HIGH(ymax
);
952 header
[9] = LOW(ymax
);
954 /* concatenate all arrays and fill needed GLYPH structure elements */
956 glyph
->len1
= 10 + 2 * outline
->n_contours
;
957 glyph
->len2
= (flagsp
- flags
) + (xp
- x
) + (yp
- y
);
959 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
962 error
= FT_Err_Out_Of_Memory
;
967 memcpy(p
, header
, 10);
971 glyph
->ins_buf
= NULL
;
973 for (i
= 0; i
< outline
->n_contours
; i
++)
975 *(p
++) = HIGH(outline
->contours
[i
]);
976 *(p
++) = LOW(outline
->contours
[i
]);
979 memcpy(p
, flags
, flagsp
- flags
);
981 memcpy(p
, x
, xp
- x
);
983 memcpy(p
, y
, yp
- y
);
994 /* We hint each glyph at EM size and construct a new `glyf' table. */
995 /* Some fonts need this; in particular, */
996 /* there are CJK fonts which use hints to scale and position subglyphs. */
997 /* As a consequence, there are no longer composite glyphs. */
1000 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
1003 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
1004 FT_Face face
= sfnt
->face
;
1012 /* in case of success, all allocated arrays are */
1013 /* linked and eventually freed in `TA_font_unload' */
1015 /* nothing to do if table has already been created */
1016 if (glyf_table
->data
)
1019 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
1021 return FT_Err_Out_Of_Memory
;
1023 glyf_table
->data
= data
;
1025 data
->num_glyphs
= face
->num_glyphs
;
1026 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
1028 return FT_Err_Out_Of_Memory
;
1030 /* XXX: Make size configurable */
1031 /* we use the EM size */
1032 /* so that the resulting coordinates can be used without transformation */
1033 error
= FT_Set_Char_Size(face
, face
->units_per_EM
* 64, 0, 72, 0);
1037 /* loop over all glyphs in font face */
1038 for (i
= 0; i
< data
->num_glyphs
; i
++)
1040 GLYPH
* glyph
= &data
->glyphs
[i
];
1043 error
= FT_Load_Glyph(face
, i
, FT_LOAD_NO_BITMAP
| FT_LOAD_NO_AUTOHINT
);
1047 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
1055 /* end of taglyf.c */