static int clt_read_range (struct clt_range *rec, sfnt *sfont) { ASSERT(rec && sfont); rec->Start = sfnt_get_ushort(sfont); rec->End = sfnt_get_ushort(sfont); rec->StartCoverageIndex = sfnt_get_ushort(sfont); return 6; }
static int read_v2_post_names (struct tt_post_table *post, sfnt *sfont) { USHORT i, idx, *indices, maxidx; int len; post->numberOfGlyphs = sfnt_get_ushort(sfont); indices = NEW(post->numberOfGlyphs, USHORT); maxidx = 257; for (i = 0; i < post->numberOfGlyphs; i++) { idx = sfnt_get_ushort(sfont); if (idx >= 258) { if (idx > maxidx) maxidx = idx; if (idx > 32767) { /* Although this is strictly speaking out of spec, it seems to work and there are real-life fonts that use it. We show a warning only once, instead of thousands of times */ static char warning_issued = 0; if (!warning_issued) { WARN("TrueType post table name index %u > 32767", idx); warning_issued = 1; } /* In a real-life large font, (x)dvipdfmx crashes if we use nonvanishing idx in the case of idx > 32767. If we set idx = 0, (x)dvipdfmx works fine for the font and created pdf seems fine. The post table may not be important in such a case */ idx = 0; } } indices[i] = idx; } post->count = maxidx - 257; if (post->count < 1) { post->names = NULL; } else { post->names = NEW(post->count, char *); for (i = 0; i < post->count; i++) { /* read Pascal strings */ len = sfnt_get_byte(sfont); if (len > 0) { post->names[i] = NEW(len + 1, char); sfnt_read(post->names[i], len, sfont); post->names[i][len] = 0; } else { post->names[i] = NULL; } }
sfnt * dfont_open (FILE *fp, int index) { sfnt *sfont; ULONG rdata_pos, map_pos, tags_pos, types_pos, res_pos, tag; USHORT tags_num, types_num, i; ASSERT(fp); rewind(fp); sfont = NEW(1, sfnt); sfont->stream = fp; rdata_pos = sfnt_get_ulong(sfont); map_pos = sfnt_get_ulong(sfont); sfnt_seek_set(sfont, map_pos + 0x18); tags_pos = map_pos + sfnt_get_ushort(sfont); sfnt_seek_set(sfont, tags_pos); tags_num = sfnt_get_ushort(sfont); for (i = 0; i <= tags_num; i++) { tag = sfnt_get_ulong(sfont); /* tag name */ types_num = sfnt_get_ushort(sfont); /* typefaces number */ types_pos = tags_pos + sfnt_get_ushort(sfont); /* typefaces position */ if (tag == 0x73666e74UL) /* "sfnt" */ break; } if (i > tags_num) { RELEASE(sfont); return NULL; } sfnt_seek_set(sfont, types_pos); if (index > types_num) { ERROR("Invalid index %d for dfont.", index); } for (i = 0; i <= types_num; i++) { (void) sfnt_get_ushort(sfont); /* resource id */ (void) sfnt_get_ushort(sfont); /* resource name position from name_list */ res_pos = sfnt_get_ulong(sfont); /* resource flag (byte) + resource offset */ sfnt_get_ulong(sfont); /* mbz */ if (i == index) break; } rewind(sfont->stream); sfont->type = SFNT_TYPE_DFONT; sfont->directory = NULL; sfont->offset = (res_pos & 0x00ffffffUL) + rdata_pos + 4; return sfont; }
static int clt_read_record (struct clt_record *rec, sfnt *sfont) { int i; ASSERT(rec && sfont); for (i = 0; i < 4; i++) { rec->tag[i] = sfnt_get_char(sfont); } rec->tag[4] = '\0'; rec->offset = sfnt_get_ushort(sfont); return 6; }