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 for (idx
= 0; idx
< face
->num_glyphs
; idx
++)
30 error
= TA_sfnt_build_glyph_instructions(sfnt
, font
, idx
);
34 font
->progress(idx
, face
->num_glyphs
,
35 sfnt
- font
->sfnts
, font
->num_sfnts
,
44 TA_glyph_parse_composite(GLYPH
* glyph
,
48 FT_ULong flags_offset
; /* after the loop, this is the offset */
49 /* to the last element in the flags array */
52 FT_UShort
* components_new
;
64 /* walk over component records */
68 return FT_Err_Invalid_Table
;
70 flags_offset
= p
- buf
;
75 /* add component to list */
76 component
= *(p
++) << 8;
79 glyph
->num_components
++;
80 components_new
= (FT_UShort
*)realloc(glyph
->components
,
82 * sizeof (FT_UShort
));
85 glyph
->num_components
--;
86 return FT_Err_Out_Of_Memory
;
89 glyph
->components
= components_new
;
91 glyph
->components
[glyph
->num_components
- 1] = component
;
93 /* skip scaling and offset arguments */
94 if (flags
& ARGS_ARE_WORDS
)
99 if (flags
& WE_HAVE_A_SCALE
)
101 else if (flags
& WE_HAVE_AN_XY_SCALE
)
103 else if (flags
& WE_HAVE_A_2X2
)
105 } while (flags
& MORE_COMPONENTS
);
107 glyph
->flags_offset
= flags_offset
;
109 /* adjust glyph record length */
113 /* glyph->len2 = 0; */
114 glyph
->buf
= (FT_Byte
*)malloc(len
);
116 return FT_Err_Out_Of_Memory
;
118 /* copy record without instructions (if any) */
119 memcpy(glyph
->buf
, buf
, len
);
120 glyph
->buf
[flags_offset
] &= ~(WE_HAVE_INSTR
>> 8);
127 TA_glyph_parse_simple(GLYPH
* glyph
,
129 FT_UShort num_contours
,
133 FT_Byte
* flags_start
;
138 FT_ULong flags_size
; /* size of the flags array */
139 FT_ULong xy_size
; /* size of x and y coordinate arrays together */
150 ins_offset
= 10 + num_contours
* 2;
155 return FT_Err_Invalid_Table
;
157 /* get number of instructions */
158 num_ins
= *(p
++) << 8;
164 return FT_Err_Invalid_Table
;
166 /* get number of points from last outline point */
167 num_pts
= buf
[ins_offset
- 2] << 8;
168 num_pts
+= buf
[ins_offset
- 1];
186 return FT_Err_Invalid_Table
;
190 x_short
= (flags
& X_SHORT_VECTOR
) ? 1 : 2;
191 y_short
= (flags
& Y_SHORT_VECTOR
) ? 1 : 2;
193 have_x
= ((flags
& SAME_X
) && !(flags
& X_SHORT_VECTOR
)) ? 0 : 1;
194 have_y
= ((flags
& SAME_Y
) && !(flags
& Y_SHORT_VECTOR
)) ? 0 : 1;
201 return FT_Err_Invalid_Table
;
205 if (i
+ count
> num_pts
)
206 return FT_Err_Invalid_Table
;
209 xy_size
+= count
* x_short
* have_x
;
210 xy_size
+= count
* y_short
* have_y
;
215 if (p
+ xy_size
> endp
)
216 return FT_Err_Invalid_Table
;
218 flags_size
= p
- flags_start
;
220 /* store the data before and after the bytecode instructions */
221 /* in the same array */
222 glyph
->len1
= ins_offset
;
223 glyph
->len2
= flags_size
+ xy_size
;
224 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
226 return FT_Err_Out_Of_Memory
;
228 /* now copy everything but the instructions */
229 memcpy(glyph
->buf
, buf
, glyph
->len1
);
230 memcpy(glyph
->buf
+ glyph
->len1
, flags_start
, glyph
->len2
);
237 TA_iterate_composite_glyph(glyf_Data
* data
,
238 FT_UShort
* components
,
239 FT_UShort num_components
,
240 FT_UShort
** endpoints
,
241 FT_UShort
* num_endpoints
,
242 FT_UShort
* num_composite_contours
)
247 for (i
= 0; i
< num_components
; i
++)
250 FT_UShort component
= components
[i
];
254 if (component
>= data
->num_glyphs
)
255 return FT_Err_Invalid_Table
;
257 glyph
= &data
->glyphs
[component
];
259 if (glyph
->num_components
)
261 error
= TA_iterate_composite_glyph(data
,
263 glyph
->num_components
,
266 num_composite_contours
);
272 FT_UShort num_contours
;
274 FT_UShort
* endpoints_new
;
277 /* collect end points of simple glyphs */
279 num_contours
= glyph
->buf
[0] << 8;
280 num_contours
+= glyph
->buf
[1];
281 endpoint
= glyph
->buf
[10 + (num_contours
- 1) * 2] << 8;
282 endpoint
+= glyph
->buf
[10 + (num_contours
- 1) * 2 + 1];
285 endpoints_new
= (FT_UShort
*)realloc(*endpoints
,
287 * sizeof (FT_UShort
));
291 return FT_Err_Out_Of_Memory
;
294 *endpoints
= endpoints_new
;
296 (*endpoints
)[*num_endpoints
- 1] = endpoint
;
297 if (*num_endpoints
> 1)
298 (*endpoints
)[*num_endpoints
- 1]
299 += (*endpoints
)[*num_endpoints
- 2] + 1;
301 *num_composite_contours
+= num_contours
;
310 TA_sfnt_compute_composite_endpoints(SFNT
* sfnt
,
313 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
314 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
319 for (i
= 0; i
< data
->num_glyphs
; i
++)
321 GLYPH
* glyph
= &data
->glyphs
[i
];
324 if (glyph
->num_components
)
327 FT_UShort num_composite_contours
= 0;
330 error
= TA_iterate_composite_glyph(data
,
332 glyph
->num_components
,
334 &glyph
->num_endpoints
,
335 &num_composite_contours
);
339 if (glyph
->endpoints
[glyph
->num_endpoints
- 1] + 1
340 > sfnt
->max_composite_points
)
341 sfnt
->max_composite_points
=
342 glyph
->endpoints
[glyph
->num_endpoints
- 1] + 1;
343 if (num_composite_contours
> sfnt
->max_composite_contours
)
344 sfnt
->max_composite_contours
= num_composite_contours
;
353 TA_sfnt_split_glyf_table(SFNT
* sfnt
,
356 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
357 SFNT_Table
* loca_table
= &font
->tables
[sfnt
->loca_idx
];
358 SFNT_Table
* head_table
= &font
->tables
[sfnt
->head_idx
];
364 FT_ULong offset_next
;
372 /* in case of success, all allocated arrays are */
373 /* linked and eventually freed in `TA_font_unload' */
375 /* nothing to do if table has already been split */
376 if (glyf_table
->data
)
379 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
381 return FT_Err_Out_Of_Memory
;
383 glyf_table
->data
= data
;
385 loca_format
= head_table
->buf
[LOCA_FORMAT_OFFSET
];
387 data
->num_glyphs
= loca_format
? loca_table
->len
/ 4 - 1
388 : loca_table
->len
/ 2 - 1;
389 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
391 return FT_Err_Out_Of_Memory
;
397 offset_next
= *(p
++) << 24;
398 offset_next
+= *(p
++) << 16;
399 offset_next
+= *(p
++) << 8;
400 offset_next
+= *(p
++);
404 offset_next
= *(p
++) << 8;
405 offset_next
+= *(p
++);
409 /* loop over `loca' and `glyf' data */
410 for (i
= 0; i
< data
->num_glyphs
; i
++)
412 GLYPH
* glyph
= &data
->glyphs
[i
];
416 offset
= offset_next
;
420 offset_next
= *(p
++) << 24;
421 offset_next
+= *(p
++) << 16;
422 offset_next
+= *(p
++) << 8;
423 offset_next
+= *(p
++);
427 offset_next
= *(p
++) << 8;
428 offset_next
+= *(p
++);
432 if (offset_next
< offset
433 || offset_next
> glyf_table
->len
)
434 return FT_Err_Invalid_Table
;
436 len
= offset_next
- offset
;
438 continue; /* empty glyph */
442 FT_Short num_contours
;
445 /* check header size */
447 return FT_Err_Invalid_Table
;
449 buf
= glyf_table
->buf
+ offset
;
450 num_contours
= (FT_Short
)((buf
[0] << 8) + buf
[1]);
452 /* We must parse the rest of the glyph record to get the exact */
453 /* record length. Since the `loca' table rounds record lengths */
454 /* up to multiples of 4 (or 2 for older fonts), and we must round */
455 /* up again after stripping off the instructions, it would be */
456 /* possible otherwise to have more than 4 bytes of padding which */
457 /* is more or less invalid. */
459 if (num_contours
< 0)
460 error
= TA_glyph_parse_composite(glyph
, buf
, len
);
462 error
= TA_glyph_parse_simple(glyph
, buf
, num_contours
, len
);
468 if (sfnt
->max_components
)
470 error
= TA_sfnt_compute_composite_endpoints(sfnt
, font
);
480 TA_sfnt_build_glyf_table(SFNT
* sfnt
,
483 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
484 glyf_Data
* data
= (glyf_Data
*)glyf_table
->data
;
494 if (glyf_table
->processed
)
499 glyph
= data
->glyphs
;
500 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
502 /* glyph records should have offsets which are multiples of 4 */
503 len
= (len
+ 3) & ~3;
504 len
+= glyph
->len1
+ glyph
->len2
+ glyph
->ins_len
;
505 /* add two bytes for the instructionLength field */
506 if (glyph
->len2
|| glyph
->ins_len
)
510 /* to make the short format of the `loca' table always work, */
511 /* assure an even length of the `glyf' table */
512 glyf_table
->len
= (len
+ 1) & ~1;
514 buf_new
= (FT_Byte
*)realloc(glyf_table
->buf
, (len
+ 3) & ~3);
516 return FT_Err_Out_Of_Memory
;
518 glyf_table
->buf
= buf_new
;
521 glyph
= data
->glyphs
;
522 for (i
= 0; i
< data
->num_glyphs
; i
++, glyph
++)
524 len
= glyph
->len1
+ glyph
->len2
+ glyph
->ins_len
;
525 if (glyph
->len2
|| glyph
->ins_len
)
530 /* copy glyph data and insert new instructions */
531 memcpy(p
, glyph
->buf
, glyph
->len1
);
537 *(p
++) = HIGH(glyph
->ins_len
);
538 *(p
++) = LOW(glyph
->ins_len
);
539 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
541 memcpy(p
, glyph
->buf
+ glyph
->len1
, glyph
->len2
);
546 /* composite glyph */
549 *(p
+ glyph
->flags_offset
) |= (WE_HAVE_INSTR
>> 8);
551 *(p
++) = HIGH(glyph
->ins_len
);
552 *(p
++) = LOW(glyph
->ins_len
);
553 memcpy(p
, glyph
->ins_buf
, glyph
->ins_len
);
560 /* pad with zero bytes to have an offset which is a multiple of 4; */
561 /* this works even for the last glyph record since the `glyf' */
562 /* table length is a multiple of 4 also */
577 glyf_table
->checksum
= TA_table_compute_checksum(glyf_table
->buf
,
579 glyf_table
->processed
= 1;
586 TA_create_glyph_data(FT_Outline
* outline
,
589 FT_Error error
= TA_Err_Ok
;
595 FT_Byte
* flags
= NULL
;
609 if (!outline
->n_contours
)
610 return TA_Err_Ok
; /* empty glyph */
612 /* in case of success, all non-local allocated arrays are */
613 /* linked and eventually freed in `TA_font_unload' */
617 /* we use `calloc' since we rely on the array */
618 /* being initialized to zero; */
619 /* additionally, we need one more byte for a test after the loop */
620 flags
= (FT_Byte
*)calloc(1, outline
->n_points
+ 1);
623 error
= FT_Err_Out_Of_Memory
;
627 /* we have either one-byte or two-byte elements */
628 x
= (FT_Byte
*)malloc(2 * outline
->n_points
);
631 error
= FT_Err_Out_Of_Memory
;
635 y
= (FT_Byte
*)malloc(2 * outline
->n_points
);
638 error
= FT_Err_Out_Of_Memory
;
645 xmin
= xmax
= (outline
->points
[0].x
+ 32) >> 6;
646 ymin
= ymax
= (outline
->points
[0].y
+ 32) >> 6;
649 oldf
= 0x80; /* start with an impossible value */
651 /* convert the FreeType representation of the glyph's outline */
652 /* into the representation format of the `glyf' table */
653 for (i
= 0; i
< outline
->n_points
; i
++)
655 FT_Pos xcur
= (outline
->points
[i
].x
+ 32) >> 6;
656 FT_Pos ycur
= (outline
->points
[i
].y
+ 32) >> 6;
658 FT_Pos xdelta
= xcur
- lastx
;
659 FT_Pos ydelta
= ycur
- lasty
;
662 /* we are only interested in bit 0 of the `tags' array */
663 f
= outline
->tags
[i
] & ON_CURVE
;
671 if (xdelta
< 256 && xdelta
> -256)
680 *(xp
++) = (FT_Byte
)xdelta
;
684 *(xp
++) = HIGH(xdelta
);
685 *(xp
++) = LOW(xdelta
);
695 if (ydelta
< 256 && ydelta
> -256)
704 *(yp
++) = (FT_Byte
)ydelta
;
708 *(yp
++) = HIGH(ydelta
);
709 *(yp
++) = LOW(ydelta
);
715 /* set repeat flag */
716 *(flagsp
- 1) |= REPEAT
;
720 /* we can only handle 256 repetitions at once, */
721 /* so use a new counter */
726 *flagsp
+= 1; /* increase repetition counter */
731 flagsp
++; /* skip repetition counter */
749 /* if the last byte was a repetition counter, */
750 /* we must increase by one to get the correct array size */
754 header
[0] = HIGH(outline
->n_contours
);
755 header
[1] = LOW(outline
->n_contours
);
756 header
[2] = HIGH(xmin
);
757 header
[3] = LOW(xmin
);
758 header
[4] = HIGH(ymin
);
759 header
[5] = LOW(ymin
);
760 header
[6] = HIGH(xmax
);
761 header
[7] = LOW(xmax
);
762 header
[8] = HIGH(ymax
);
763 header
[9] = LOW(ymax
);
765 /* concatenate all arrays and fill needed GLYPH structure elements */
767 glyph
->len1
= 10 + 2 * outline
->n_contours
;
768 glyph
->len2
= (flagsp
- flags
) + (xp
- x
) + (yp
- y
);
770 glyph
->buf
= (FT_Byte
*)malloc(glyph
->len1
+ glyph
->len2
);
773 error
= FT_Err_Out_Of_Memory
;
778 memcpy(p
, header
, 10);
782 glyph
->ins_buf
= NULL
;
784 for (i
= 0; i
< outline
->n_contours
; i
++)
786 *(p
++) = HIGH(outline
->contours
[i
]);
787 *(p
++) = LOW(outline
->contours
[i
]);
790 memcpy(p
, flags
, flagsp
- flags
);
792 memcpy(p
, x
, xp
- x
);
794 memcpy(p
, y
, yp
- y
);
805 /* We hint each glyph at EM size and construct a new `glyf' table. */
806 /* Some fonts need this; in particular, */
807 /* there are CJK fonts which use hints to scale and position subglyphs. */
808 /* As a consequence, there are no longer composite glyphs. */
811 TA_sfnt_create_glyf_data(SFNT
* sfnt
,
814 SFNT_Table
* glyf_table
= &font
->tables
[sfnt
->glyf_idx
];
815 FT_Face face
= sfnt
->face
;
823 /* in case of success, all allocated arrays are */
824 /* linked and eventually freed in `TA_font_unload' */
826 /* nothing to do if table has already been created */
827 if (glyf_table
->data
)
830 data
= (glyf_Data
*)calloc(1, sizeof (glyf_Data
));
832 return FT_Err_Out_Of_Memory
;
834 glyf_table
->data
= data
;
836 data
->num_glyphs
= face
->num_glyphs
;
837 data
->glyphs
= (GLYPH
*)calloc(1, data
->num_glyphs
* sizeof (GLYPH
));
839 return FT_Err_Out_Of_Memory
;
841 /* XXX: Make size configurable */
842 /* we use the EM size */
843 /* so that the resulting coordinates can be used without transformation */
844 error
= FT_Set_Char_Size(face
, face
->units_per_EM
* 64, 0, 72, 0);
848 /* loop over all glyphs in font face */
849 for (i
= 0; i
< data
->num_glyphs
; i
++)
851 GLYPH
* glyph
= &data
->glyphs
[i
];
854 error
= FT_Load_Glyph(face
, i
, FT_LOAD_NO_BITMAP
| FT_LOAD_NO_AUTOHINT
);
858 error
= TA_create_glyph_data(&face
->glyph
->outline
, glyph
);
866 /* end of taglyf.c */