FT_Error TA_sfnt_build_gasp_table(SFNT* sfnt, FONT* font) { FT_Error error; FT_Byte* gasp_buf; error = TA_sfnt_add_table_info(sfnt); if (error) return error; error = TA_table_build_gasp(&gasp_buf); if (error) return error; /* in case of success, `gasp_buf' gets linked */ /* and is eventually freed in `TA_font_unload' */ error = TA_font_add_table(font, &sfnt->table_infos[sfnt->num_table_infos - 1], TTAG_gasp, GASP_LEN, gasp_buf); if (error) { free(gasp_buf); return error; } return FT_Err_Ok; }
FT_Error TA_sfnt_build_prep_table(SFNT* sfnt, FONT* font) { FT_Error error; SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx]; glyf_Data* data = (glyf_Data*)glyf_table->data; FT_Byte* prep_buf; FT_ULong prep_len; error = TA_sfnt_add_table_info(sfnt); if (error) goto Exit; /* `glyf', `cvt', `fpgm', and `prep' are always used in parallel */ if (glyf_table->processed) { sfnt->table_infos[sfnt->num_table_infos - 1] = data->prep_idx; goto Exit; } error = TA_table_build_prep(&prep_buf, &prep_len, sfnt, font); if (error) goto Exit; #if 0 /* ttfautohint's bytecode in `fpgm' is larger */ /* than the bytecode in `prep'; */ /* this commented out code here is just for completeness */ if (prep_len > sfnt->max_instructions) sfnt->max_instructions = prep_len; #endif /* in case of success, `prep_buf' gets linked */ /* and is eventually freed in `TA_font_unload' */ error = TA_font_add_table(font, &sfnt->table_infos[sfnt->num_table_infos - 1], TTAG_prep, prep_len, prep_buf); if (error) free(prep_buf); else data->prep_idx = sfnt->table_infos[sfnt->num_table_infos - 1]; Exit: return error; }
FT_Error TA_sfnt_build_prep_table(SFNT* sfnt, FONT* font) { FT_Error error; FT_Byte* prep_buf; FT_ULong prep_len; error = TA_sfnt_add_table_info(sfnt); if (error) return error; error = TA_table_build_prep(&prep_buf, &prep_len, font); if (error) return error; #if 0 /* ttfautohint's bytecode in `fpgm' is larger */ /* than the bytecode in `prep'; */ /* this commented out code here is just for completeness */ if (prep_len > sfnt->max_instructions) sfnt->max_instructions = prep_len; #endif /* in case of success, `prep_buf' gets linked */ /* and is eventually freed in `TA_font_unload' */ error = TA_font_add_table(font, &sfnt->table_infos[sfnt->num_table_infos - 1], TTAG_prep, prep_len, prep_buf); if (error) { free(prep_buf); return error; } return FT_Err_Ok; }
FT_Error TA_sfnt_build_gasp_table(SFNT* sfnt, FONT* font) { FT_Error error; FT_Byte* gasp_buf; error = TA_sfnt_add_table_info(sfnt); if (error) goto Exit; if (font->gasp_idx != MISSING) { sfnt->table_infos[sfnt->num_table_infos - 1] = font->gasp_idx; goto Exit; } error = TA_table_build_gasp(&gasp_buf); if (error) goto Exit; /* in case of success, `gasp_buf' gets linked */ /* and is eventually freed in `TA_font_unload' */ error = TA_font_add_table(font, &sfnt->table_infos[sfnt->num_table_infos - 1], TTAG_gasp, GASP_LEN, gasp_buf); if (error) free(gasp_buf); else font->gasp_idx = sfnt->table_infos[sfnt->num_table_infos - 1]; Exit: return error; }
FT_Error TA_font_build_TTC(FONT* font) { SFNT* sfnts = font->sfnts; FT_Long num_sfnts = font->num_sfnts; SFNT_Table* tables; FT_ULong num_tables; FT_Byte* DSIG_buf; SFNT_Table_Info dummy; FT_Byte* TTC_header_buf; FT_ULong TTC_header_len; FT_Byte** TTF_header_bufs = NULL; FT_ULong* TTF_header_lens = NULL; FT_ULong offset; FT_Long i; FT_ULong j; FT_Error error; /* replace an existing `DSIG' table with a dummy */ if (font->have_DSIG) { error = TA_table_build_DSIG(&DSIG_buf); if (error) return error; /* in case of success, `DSIG_buf' gets linked */ /* and is eventually freed in `TA_font_unload' */ error = TA_font_add_table(font, &dummy, TTAG_DSIG, DSIG_LEN, DSIG_buf); if (error) { free(DSIG_buf); return error; } } /* this also computes the SFNT table offsets */ error = TA_font_build_TTC_header(font, &TTC_header_buf, &TTC_header_len); if (error) return error; TTF_header_bufs = (FT_Byte**)calloc(1, num_sfnts * sizeof (FT_Byte*)); if (!TTF_header_bufs) goto Err; TTF_header_lens = (FT_ULong*)malloc(num_sfnts * sizeof (FT_ULong)); if (!TTF_header_lens) goto Err; for (i = 0; i < num_sfnts; i++) { error = TA_sfnt_build_TTF_header(&sfnts[i], font, &TTF_header_bufs[i], &TTF_header_lens[i], 1); if (error) goto Err; } /* build font */ tables = font->tables; num_tables = font->num_tables; /* get font length from last SFNT table array element */ font->out_len = tables[num_tables - 1].offset + ((tables[num_tables - 1].len + 3) & ~3); font->out_buf = (FT_Byte*)malloc(font->out_len); if (!font->out_buf) { error = FT_Err_Out_Of_Memory; goto Err; } memcpy(font->out_buf, TTC_header_buf, TTC_header_len); offset = TTC_header_len; for (i = 0; i < num_sfnts; i++) { memcpy(font->out_buf + offset, TTF_header_bufs[i], TTF_header_lens[i]); offset += TTF_header_lens[i]; } for (j = 0; j < num_tables; j++) { SFNT_Table* table = &tables[j]; /* buffer length is a multiple of 4 */ memcpy(font->out_buf + table->offset, table->buf, (table->len + 3) & ~3); } error = TA_Err_Ok; Err: free(TTC_header_buf); if (TTF_header_bufs) { for (i = 0; i < font->num_sfnts; i++) free(TTF_header_bufs[i]); free(TTF_header_bufs); } free(TTF_header_lens); return error; }
FT_Error TA_font_build_TTF(FONT* font) { SFNT* sfnt = &font->sfnts[0]; SFNT_Table* tables; FT_ULong num_tables; FT_ULong SFNT_offset; FT_Byte* DSIG_buf; FT_Byte* header_buf; FT_ULong header_len; FT_ULong i; FT_Error error; /* replace an existing `DSIG' table with a dummy */ if (font->have_DSIG) { error = TA_sfnt_add_table_info(sfnt); if (error) return error; error = TA_table_build_DSIG(&DSIG_buf); if (error) return error; /* in case of success, `DSIG_buf' gets linked */ /* and is eventually freed in `TA_font_unload' */ error = TA_font_add_table(font, &sfnt->table_infos[sfnt->num_table_infos - 1], TTAG_DSIG, DSIG_LEN, DSIG_buf); if (error) { free(DSIG_buf); return error; } } TA_sfnt_sort_table_info(sfnt, font); /* the first SFNT table immediately follows the header */ (void)TA_sfnt_build_TTF_header(sfnt, font, NULL, &SFNT_offset, 0); TA_font_compute_table_offsets(font, SFNT_offset); error = TA_sfnt_build_TTF_header(sfnt, font, &header_buf, &header_len, 1); if (error) return error; /* build font */ tables = font->tables; num_tables = font->num_tables; /* get font length from last SFNT table array element */ font->out_len = tables[num_tables - 1].offset + ((tables[num_tables - 1].len + 3) & ~3); font->out_buf = (FT_Byte*)malloc(font->out_len); if (!font->out_buf) { error = FT_Err_Out_Of_Memory; goto Err; } memcpy(font->out_buf, header_buf, header_len); for (i = 0; i < num_tables; i++) { SFNT_Table* table = &tables[i]; /* buffer length is a multiple of 4 */ memcpy(font->out_buf + table->offset, table->buf, (table->len + 3) & ~3); } error = TA_Err_Ok; Err: free(header_buf); return error; }