From 47d8870658c716c4d6511f2e67865355c39ad077 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 6 Feb 2007 22:48:16 +0000 Subject: [PATCH] Construct a table for mapping glyph names back into glyph indices, for use when we come to embed TrueType fonts in PDF. Also provide functions for using this table and its inverse. Unrelatedly, support extracting the italic angle from the 'post' table. git-svn-id: svn://svn.tartarus.org/sgt/halibut@7242 cda61777-01e9-0310-a592-d414129be87e --- in_sfnt.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/in_sfnt.c b/in_sfnt.c index 4348aab..fe10c46 100644 --- a/in_sfnt.c +++ b/in_sfnt.c @@ -62,14 +62,12 @@ static void decode_uint32(void *src, void *dest) { } #define d_uint32 decode_uint32, 4 -#if 0 /* unused */ static void decode_int32(void *src, void *dest) { signed char *cp = src; unsigned char *ucp = src; *(int *)dest = (cp[0] << 24) + (ucp[1] << 16) + (ucp[2] << 8) + ucp[3]; } #define d_int32 decode_int32, 4 -#endif static void decode_skip(void *src, void *dest) { IGNORE(src); @@ -277,7 +275,7 @@ sfnt_decode namerecord_decode[] = { typedef struct t_post_Tag t_post; struct t_post_Tag { unsigned format; - unsigned italicAngle; + int italicAngle; int underlinePosition; int underlineThickness; unsigned isFixedPitch; @@ -286,7 +284,7 @@ struct t_post_Tag { }; sfnt_decode t_post_decode[] = { { d_uint32, offsetof(t_post, format) }, - { d_uint32, offsetof(t_post, italicAngle) }, + { d_int32, offsetof(t_post, italicAngle) }, { d_int16, offsetof(t_post, underlinePosition) }, { d_int16, offsetof(t_post, underlineThickness) }, { d_uint32, offsetof(t_post, isFixedPitch) }, @@ -360,13 +358,30 @@ static char *sfnt_psname(font_info *fi) { return NULL; } +static unsigned short *cmp_glyphsbyindex; +static int glyphsbyname_cmp(void const *a, void const *b) { + glyph ga = cmp_glyphsbyindex[*(unsigned short *)a]; + glyph gb = cmp_glyphsbyindex[*(unsigned short *)b]; + if (ga < gb) return -1; + if (ga > gb) return 1; + return 0; +} +static int glyphsbyname_cmp_search(void const *a, void const *b) { + glyph ga = *(glyph *)a; + glyph gb = cmp_glyphsbyindex[*(unsigned short *)b]; + if (ga < gb) return -1; + if (ga > gb) return 1; + return 0; +} + /* * Extract data from the 'post' table (mostly glyph mappings) * * TODO: cope better with duplicated glyph names (usually .notdef) * TODO: when presented with format 3.0, try to use 'CFF' if present. */ -static void sfnt_mapglyphs(sfnt *sf) { +static void sfnt_mapglyphs(font_info *fi) { + sfnt *sf = fi->fontfile; t_post post; void *ptr, *end; unsigned char *sptr; @@ -378,8 +393,10 @@ static void sfnt_mapglyphs(sfnt *sf) { if (!sfnt_findtable(sf, TAG_post, &ptr, &end)) abort(); ptr = decode(t_post_decode, ptr, end, &post); + sf->minmem = post.minMemType42; sf->maxmem = post.maxMemType42; + fi->italicangle = post.italicAngle / 65536.0; if (ptr == NULL) abort(); switch (post.format) { case 0x00010000: @@ -421,6 +438,24 @@ static void sfnt_mapglyphs(sfnt *sf) { default: abort(); } + /* Construct glyphsbyname */ + sf->glyphsbyname = snewn(sf->nglyphs, unsigned short); + for (i = 0; i < sf->nglyphs; i++) + sf->glyphsbyname[i] = i; + cmp_glyphsbyindex = sf->glyphsbyindex; + qsort(sf->glyphsbyname, sf->nglyphs, sizeof(*sf->glyphsbyname), + glyphsbyname_cmp); +} + +static glyph sfnt_indextoglyph(sfnt *sf, unsigned short idx) { + return sf->glyphsbyindex[idx]; +} + +static unsigned short sfnt_glyphtoindex(sfnt *sf, glyph g) { + cmp_glyphsbyindex = sf->glyphsbyindex; + return *(unsigned short *)bsearch(&g, sf->glyphsbyname, sf->nglyphs, + sizeof(*sf->glyphsbyname), + glyphsbyname_cmp_search); } /* @@ -451,7 +486,7 @@ void sfnt_getmetrics(font_info *fi) { abort(); for (i = 0; i < sf->nglyphs; i++) { glyph_width *w = snew(glyph_width); - w->glyph = sf->glyphsbyindex[i]; + w->glyph = sfnt_indextoglyph(sf, i); j = i < hhea.numOfLongHorMetrics ? i : hhea.numOfLongHorMetrics - 1; w->width = hmtx[j] * UNITS_PER_PT / sf->head.unitsPerEm; add234(fi->widths, w); @@ -523,7 +558,7 @@ void sfnt_getmap(font_info *fi) { idx = (k + idDelta[j]) & 0xffff; if (idx != 0) { if (idx > sf->nglyphs) abort(); - fi->bmp[k] = sf->glyphsbyindex[idx]; + fi->bmp[k] = sfnt_indextoglyph(sf, idx); } } } else { @@ -533,7 +568,7 @@ void sfnt_getmap(font_info *fi) { if (idx != 0) { idx = (idx + idDelta[j]) & 0xffff; if (idx > sf->nglyphs) abort(); - fi->bmp[k] = sf->glyphsbyindex[idx]; + fi->bmp[k] = sfnt_indextoglyph(sf, idx); } } } @@ -595,7 +630,7 @@ void read_sfnt_file(input *in) { if ((sf->head.version & 0xffff0000) != 0x00010000) abort(); fi->name = sfnt_psname(fi); - sfnt_mapglyphs(sf); + sfnt_mapglyphs(fi); sfnt_getmetrics(fi); sfnt_getmap(fi); fi->next = all_fonts; @@ -649,7 +684,8 @@ void sfnt_writeps(font_info const *fi, FILE *ofp) { fprintf(ofp, "/PaintType 0 def\n"); fprintf(ofp, "/CharStrings %u dict dup begin\n", sf->nglyphs); for (i = 0; i < sf->nglyphs; i++) - fprintf(ofp, "/%s %u def\n", glyph_extern(sf->glyphsbyindex[i]), i); + fprintf(ofp, "/%s %u def\n", + glyph_extern(sfnt_indextoglyph(sf, i)), i); fprintf(ofp, "end readonly def\n"); fprintf(ofp, "/sfnts [<"); breaks = snewn(sf->osd.numTables + sf->nglyphs, size_t); -- 2.11.0