summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/pdftexdir/writettf.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/pdftexdir/writettf.c')
-rw-r--r--Build/source/texk/web2c/pdftexdir/writettf.c913
1 files changed, 550 insertions, 363 deletions
diff --git a/Build/source/texk/web2c/pdftexdir/writettf.c b/Build/source/texk/web2c/pdftexdir/writettf.c
index e2d0d1641d6..4c33f568434 100644
--- a/Build/source/texk/web2c/pdftexdir/writettf.c
+++ b/Build/source/texk/web2c/pdftexdir/writettf.c
@@ -1,5 +1,5 @@
/*
-Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
+Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org>
This file is part of pdfTeX.
@@ -22,9 +22,7 @@ $Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writettf.c#16 $
#include "ptexlib.h"
#include "writettf.h"
-
-static const char perforce_id[] =
- "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writettf.c#16 $";
+#include <string.h>
#define DEFAULT_NTABS 14
#define NEW_CMAP_SIZE 2
@@ -46,14 +44,16 @@ typedef struct {
TTF_LONG newoffset;
TTF_UFWORD advWidth;
TTF_FWORD lsb;
- char *name; /* name of glyph */
- TTF_SHORT newindex; /* new index of glyph in output file */
- TTF_USHORT name_index; /* index of name as read from font file */
+ char *name; /* name of glyph */
+ TTF_SHORT newindex; /* new index of glyph in output file */
+ TTF_USHORT name_index; /* index of name as read from font file */
} glyph_entry;
typedef struct {
- char *name; /* name of glyph */
- short newindex; /* new index of glyph in output file */
+ char *name; /* name of glyph */
+ long code; /* charcode in case of subfonts */
+ short newindex; /* new index of glyph in output file */
+
} ttfenc_entry;
typedef struct {
@@ -67,6 +67,13 @@ typedef struct {
TTF_USHORT new_length;
} name_record;
+typedef struct {
+ char *ttf_name;
+ TTF_USHORT pid;
+ TTF_USHORT eid;
+ short *table;
+} ttf_cmap_entry;
+
static TTF_USHORT ntabs;
static TTF_USHORT upem;
static TTF_FIXED post_format;
@@ -78,7 +85,7 @@ static TTF_USHORT nhmtxs;
static TTF_USHORT new_ntabs;
static glyph_entry *glyph_tab;
-static short *glyph_index;
+static long *glyph_index;
static cmap_entry *cmap_tab, new_cmap_tab[NEW_CMAP_SIZE];
static name_record *name_tab;
static int name_record_num;
@@ -91,16 +98,18 @@ static TTF_ULONG tab_length;
static TTF_ULONG tmp_ulong;
static TTF_ULONG checkSumAdjustment_offset;
static FILE *ttf_file;
-static ttfenc_entry ttfenc_tab[MAX_CHAR_CODE + 1];
+static ttfenc_entry ttfenc_tab[256];
-static TTF_USHORT unicode_map[0xFFFF];
+static fd_entry *fd_cur; /* pointer to the current font descriptor */
+static struct avl_table *ttf_cmap_tree = NULL;
integer ttf_length;
#include "macnames.c"
extern char *fb_array;
+extern char charsetstr[];
static const char *newtabnames[] = {
"OS/2",
@@ -119,6 +128,43 @@ static const char *newtabnames[] = {
"prep"
};
+ttf_cmap_entry *new_ttf_cmap_entry(void)
+{
+ ttf_cmap_entry *e;
+ e = xtalloc(1, ttf_cmap_entry);
+ e->ttf_name = NULL;
+ e->table = NULL;
+ return e;
+}
+
+static void destroy_ttf_cmap_entry(void *pa, void *pb)
+{
+ ttf_cmap_entry *p;
+ p = (ttf_cmap_entry *) pa;
+ xfree(p->ttf_name);
+ xfree(p->table);
+ xfree(p);
+}
+
+void ttf_free(void)
+{
+ if (ttf_cmap_tree != NULL)
+ avl_destroy(ttf_cmap_tree, destroy_ttf_cmap_entry);
+}
+
+static int comp_ttf_cmap_entry(const void *pa, const void *pb, void *p)
+{
+ const ttf_cmap_entry *p1 = (const ttf_cmap_entry *) pa,
+ *p2 = (const ttf_cmap_entry *) pb;
+ int i;
+ assert(p1->ttf_name != NULL && p2->ttf_name != NULL);
+ if ((i = strcmp(p1->ttf_name, p2->ttf_name)) != 0)
+ return i;
+ cmp_return(p1->pid, p2->pid);
+ cmp_return(p1->eid, p2->eid);
+ return 0;
+}
+
static unsigned char ttf_addchksm(unsigned char b)
{
tmp_ulong = (tmp_ulong << 8) + b;
@@ -133,7 +179,7 @@ static unsigned char ttf_addchksm(unsigned char b)
static TTF_ULONG ttf_getchksm(void)
{
while (tab_length % 4 != 0)
- ttf_putchar(ttf_addchksm(0)); /* ttf_addchksm updates tab_length */
+ ttf_putchar(ttf_addchksm(0)); /* ttf_addchksm updates tab_length */
return checksum;
}
@@ -167,9 +213,9 @@ static long ttf_getnum(int s)
static long ttf_funit(long n)
{
if (n < 0)
- return -((-n/upem)*1000 + ((-n%upem)*1000)/upem);
+ return -((-n / upem) * 1000 + ((-n % upem) * 1000) / upem);
else
- return (n/upem)*1000 + ((n%upem)*1000)/upem;
+ return (n / upem) * 1000 + ((n % upem) * 1000) / upem;
}
static void ttf_ncopy(int n)
@@ -207,16 +253,66 @@ static void ttf_seek_off(TTF_LONG offset)
static void ttf_copy_encoding(void)
{
- int i;
- char **glyph_names = (fm_cur->encoding)->glyph_names;
+ int i, *q;
+ void **aa;
+ char **glyph_names;
+ long *charcodes;
+ static char buf[SMALL_BUF_SIZE];
+ struct avl_traverser t;
ttfenc_entry *e = ttfenc_tab;
- pdfmarkchar(tex_font, 'a'); /* workaround for a bug of AcroReader 4.0 */
- for (i = 0; i <= MAX_CHAR_CODE; i++, e++) {
- if (pdfcharmarked(tex_font, i))
- e->name = glyph_names[i];
- else
- e->name = (char*) notdef;
- }
+
+ assert(fd_cur->tx_tree != NULL); /* this must be set in create_fontdictionary */
+
+ if (fd_cur->fe != NULL) {
+ glyph_names = fd_cur->fe->glyph_names;
+ assert(glyph_names != NULL);
+
+ for (i = 0; i < 256; i++)
+ ttfenc_tab[i].name = (char *) notdef;
+
+ /* a workaround for a bug of AcroReader 4.0 */
+ if (strcmp(glyph_names[97], "a") == 0) {
+ q = xtalloc(1, int);
+ *q = 'a';
+ aa = avl_probe(fd_cur->tx_tree, q);
+ assert(aa != NULL);
+ }
+ /* end of workaround */
+
+ /* take over collected characters from TeX, reencode them */
+ avl_t_init(&t, fd_cur->tx_tree);
+ for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL;
+ q = (int *) avl_t_next(&t)) {
+ assert(*q >= 0 && *q < 256);
+ ttfenc_tab[*q].name = glyph_names[*q];
+ }
+ make_subset_tag(fd_cur);
+ } else if (is_subfont(fd_cur->fm)) {
+ charcodes = fd_cur->fm->subfont->charcodes;
+ assert(charcodes != NULL);
+
+ for (i = 0; i < 256; i++)
+ ttfenc_tab[i].code = -1;
+
+ /* take over collected characters from TeX */
+ avl_t_init(&t, fd_cur->tx_tree);
+ for (q = (int *) avl_t_first(&t, fd_cur->tx_tree); q != NULL;
+ q = (int *) avl_t_next(&t)) {
+ assert(*q >= 0 && *q < 256);
+ e = ttfenc_tab + *q;
+ e->code = charcodes[*q];
+ if (e->code == -1)
+ pdftex_warn("character %i is not mapped to any charcode", *q);
+ else {
+ assert(e->code < 0x10000);
+ sprintf(buf, "/c%4.4X", (int) e->code);
+ aa = avl_probe(fd_cur->gl_tree, xstrdup(buf));
+ assert(aa != NULL);
+ }
+ }
+ make_subset_tag(fd_cur);
+ } else
+ assert(0);
}
#define ttf_append_byte(B)\
@@ -226,6 +322,24 @@ do {\
*q++ = B;\
} while (0)
+static char *strip_spaces_and_delims(char *s, int l)
+{
+ static char buf[SMALL_BUF_SIZE];
+ assert(l >= 0 && l < (int) sizeof(buf));
+ char *p = buf;
+ int i;
+
+ for (i = 0; i < l; s++, i++) {
+ if (*s == '(' || *s == ')' || *s == '<' || *s == '>' ||
+ *s == '[' || *s == ']' || *s == '{' || *s == '}' ||
+ *s == '/' || *s == '%' || isspace(*s))
+ continue;
+ *p++ = *s;
+ }
+ *p = 0;
+ return buf;
+}
+
static void ttf_read_name(void)
{
int i, j;
@@ -233,8 +347,8 @@ static void ttf_read_name(void)
char *p;
name_record_num = get_ushort();
name_tab = xtalloc(name_record_num, name_record);
- name_buf_size = tab->length -
- (3*TTF_USHORT_SIZE + name_record_num*6*TTF_USHORT_SIZE);
+ name_buf_size = tab->length -
+ (3 * TTF_USHORT_SIZE + name_record_num * 6 * TTF_USHORT_SIZE);
name_buf = xtalloc(name_buf_size, char);
ttf_skip(TTF_USHORT_SIZE);
for (i = 0; i < name_record_num; i++) {
@@ -246,28 +360,29 @@ static void ttf_read_name(void)
name_tab[i].offset = get_ushort();
}
for (p = name_buf; p - name_buf < name_buf_size; p++)
- *p = get_char();
+ *p = get_char();
/* look for PS font name */
for (i = 0; i < name_record_num; i++) {
- if (name_tab[i].platform_id == 1 &&
- name_tab[i].encoding_id == 0 &&
- name_tab[i].name_id == 6) {
- strncpy(fontname_buf, name_buf + name_tab[i].offset, name_tab[i].length);
- fontname_buf[name_tab[i].length] = 0;
- font_keys[FONTNAME_CODE].valid = true;
+ if (name_tab[i].platform_id == 1 &&
+ name_tab[i].encoding_id == 0 && name_tab[i].name_id == 6) {
+ xfree(fd_cur->fontname);
+ fd_cur->fontname =
+ xstrdup(strip_spaces_and_delims(name_buf + name_tab[i].offset,
+ name_tab[i].length));
+ fd_cur->font_dim[FONTNAME_CODE].set = true;
break;
}
}
- if (!font_keys[FONTNAME_CODE].valid) {
+ if (!fd_cur->font_dim[FONTNAME_CODE].set) {
for (i = 0; i < name_record_num; i++) {
- if (name_tab[i].platform_id == 3 &&
- (name_tab[i].encoding_id == 0 ||
- name_tab[i].encoding_id == 1) &&
- name_tab[i].name_id == 6) {
- for (j = 0, p = fontname_buf; j < name_tab[i].length; j += 2)
+ if (name_tab[i].platform_id == 3 &&
+ (name_tab[i].encoding_id == 0 ||
+ name_tab[i].encoding_id == 1) && name_tab[i].name_id == 6) {
+ for (j = 0, p = fd_cur->fontname; j < name_tab[i].length;
+ j += 2)
*p++ = name_buf[name_tab[i].offset + j + 1];
*p = 0;
- font_keys[FONTNAME_CODE].valid = true;
+ fd_cur->font_dim[FONTNAME_CODE].set = true;
break;
}
}
@@ -276,7 +391,6 @@ static void ttf_read_name(void)
static void ttf_read_mapx(void)
{
- int i;
glyph_entry *glyph;
ttf_seek_tab("maxp", TTF_FIXED_SIZE);
glyph_tab = xtalloc(1 + (glyphs_count = get_ushort()), glyph_entry);
@@ -284,38 +398,40 @@ static void ttf_read_mapx(void)
glyph->newindex = -1;
glyph->newoffset = 0;
glyph->name_index = 0;
- glyph->name = (char*) notdef;
+ glyph->name = (char *) notdef;
}
- glyph_index = xtalloc(glyphs_count, short);
- glyph_index[0] = 0; /* index of ".notdef" glyph */
- glyph_index[1] = 1; /* index of ".null" glyph */
+ glyph_index = xtalloc(glyphs_count, long);
+ glyph_index[0] = 0; /* index of ".notdef" glyph */
+ glyph_index[1] = 1; /* index of ".null" glyph */
}
static void ttf_read_head(void)
{
- ttf_seek_tab("head", 2*TTF_FIXED_SIZE + 2*TTF_ULONG_SIZE + TTF_USHORT_SIZE);
+ ttf_seek_tab("head",
+ 2 * TTF_FIXED_SIZE + 2 * TTF_ULONG_SIZE + TTF_USHORT_SIZE);
upem = get_ushort();
ttf_skip(16);
- font_keys[FONTBBOX1_CODE].value = ttf_funit(get_fword());
- font_keys[FONTBBOX2_CODE].value = ttf_funit(get_fword());
- font_keys[FONTBBOX3_CODE].value = ttf_funit(get_fword());
- font_keys[FONTBBOX4_CODE].value = ttf_funit(get_fword());
- font_keys[FONTBBOX1_CODE].valid = true;
- font_keys[FONTBBOX2_CODE].valid = true;
- font_keys[FONTBBOX3_CODE].valid = true;
- font_keys[FONTBBOX4_CODE].valid = true;
- ttf_skip(2*TTF_USHORT_SIZE + TTF_SHORT_SIZE);
+ fd_cur->font_dim[FONTBBOX1_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX2_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX3_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX4_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[FONTBBOX1_CODE].set = true;
+ fd_cur->font_dim[FONTBBOX2_CODE].set = true;
+ fd_cur->font_dim[FONTBBOX3_CODE].set = true;
+ fd_cur->font_dim[FONTBBOX4_CODE].set = true;
+ ttf_skip(2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE);
loca_format = get_short();
}
static void ttf_read_hhea(void)
{
ttf_seek_tab("hhea", TTF_FIXED_SIZE);
- font_keys[ASCENT_CODE].value = ttf_funit(get_fword());
- font_keys[DESCENT_CODE].value = ttf_funit(get_fword());
- font_keys[ASCENT_CODE].valid = true;
- font_keys[DESCENT_CODE].valid = true;
- ttf_skip(TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3*TTF_FWORD_SIZE + 8*TTF_SHORT_SIZE);
+ fd_cur->font_dim[ASCENT_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[DESCENT_CODE].val = ttf_funit(get_fword());
+ fd_cur->font_dim[ASCENT_CODE].set = true;
+ fd_cur->font_dim[DESCENT_CODE].set = true;
+ ttf_skip(TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3 * TTF_FWORD_SIZE +
+ 8 * TTF_SHORT_SIZE);
nhmtxs = get_ushort();
}
@@ -324,11 +440,11 @@ static void ttf_read_pclt(void)
if (ttf_name_lookup("PCLT", false) == NULL)
return;
ttf_seek_tab("PCLT", TTF_FIXED_SIZE + TTF_ULONG_SIZE + TTF_USHORT_SIZE);
- font_keys[XHEIGHT_CODE].value = ttf_funit(get_ushort());
- ttf_skip(2*TTF_USHORT_SIZE);
- font_keys[CAPHEIGHT_CODE].value = ttf_funit(get_ushort());
- font_keys[XHEIGHT_CODE].valid = true;
- font_keys[CAPHEIGHT_CODE].valid = true;
+ fd_cur->font_dim[XHEIGHT_CODE].val = ttf_funit(get_ushort());
+ ttf_skip(2 * TTF_USHORT_SIZE);
+ fd_cur->font_dim[CAPHEIGHT_CODE].val = ttf_funit(get_ushort());
+ fd_cur->font_dim[XHEIGHT_CODE].set = true;
+ fd_cur->font_dim[CAPHEIGHT_CODE].set = true;
}
static void ttf_read_hmtx(void)
@@ -342,7 +458,7 @@ static void ttf_read_hmtx(void)
}
if (nhmtxs < glyphs_count) {
last_advWidth = glyph[-1].advWidth;
- for (;glyph - glyph_tab < glyphs_count; glyph++) {
+ for (; glyph - glyph_tab < glyphs_count; glyph++) {
glyph->advWidth = last_advWidth;
glyph->lsb = get_ufword();
}
@@ -358,29 +474,30 @@ static void ttf_read_post(void)
TTF_FIXED italic_angle;
char *p;
glyph_entry *glyph;
- dirtab_entry *tab = ttf_seek_tab("post", 0);
+ const dirtab_entry *tab = ttf_seek_tab("post", 0);
post_format = get_fixed();
italic_angle = get_fixed();
int_part = italic_angle >> 16;
- if (int_part > 0x7FFF) { /* a negative number */
+ if (int_part > 0x7FFF) { /* a negative number */
int_part = 0x10000 - int_part;
sign = -1;
}
frac_part = italic_angle % 0x10000;
- font_keys[ITALIC_ANGLE_CODE].value = sign*(int_part + frac_part*1.0/0x10000);
- font_keys[ITALIC_ANGLE_CODE].valid = true;
+ fd_cur->font_dim[ITALIC_ANGLE_CODE].val =
+ sign * (int_part + frac_part * 1.0 / 0x10000);
+ fd_cur->font_dim[ITALIC_ANGLE_CODE].set = true;
if (glyph_tab == NULL)
- return; /* being called from writeotf() */
- ttf_skip(2*TTF_FWORD_SIZE + 5*TTF_ULONG_SIZE);
+ return; /* being called from writeotf() */
+ ttf_skip(2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE);
switch (post_format) {
case 0x10000:
for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) {
- glyph->name = (char*)mac_glyph_names[glyph - glyph_tab];
+ glyph->name = (char *) mac_glyph_names[glyph - glyph_tab];
glyph->name_index = glyph - glyph_tab;
}
break;
case 0x20000:
- nnames = get_ushort(); /* some fonts have this value different from nglyphs */
+ nnames = get_ushort(); /* some fonts have this value different from nglyphs */
for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++)
glyph->name_index = get_ushort();
length = tab->length - (xftell(INFILE, cur_file_name) - tab->offset);
@@ -392,7 +509,7 @@ static void ttf_read_post(void)
}
for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) {
if (glyph->name_index < NMACGLYPHS)
- glyph->name = (char*)mac_glyph_names[glyph->name_index];
+ glyph->name = (char *) mac_glyph_names[glyph->name_index];
else {
p = glyph_name_buf;
k = glyph->name_index - NMACGLYPHS;
@@ -408,7 +525,8 @@ static void ttf_read_post(void)
}
break;
default:
- pdftex_fail("unsupported format (%.8X) of `post' table", (unsigned int) post_format);
+ pdftex_fail("unsupported format (%.8X) of `post' table",
+ (unsigned int) post_format);
}
}
@@ -428,11 +546,9 @@ static void ttf_read_tabdir()
{
int i;
dirtab_entry *tab;
-/* if ((version= get_fixed()) != 0x00010000) */
-/* pdftex_fail("unsupport version 0x%.8X; can handle only version 1.0", (int)version); */
- ttf_skip(TTF_FIXED_SIZE); /* ignore the sfnt number */
+ ttf_skip(TTF_FIXED_SIZE); /* ignore the sfnt number */
dir_tab = xtalloc(ntabs = get_ushort(), dirtab_entry);
- ttf_skip(3*TTF_USHORT_SIZE);
+ ttf_skip(3 * TTF_USHORT_SIZE);
for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
for (i = 0; i < 4; i++)
tab->tag[i] = get_char();
@@ -442,93 +558,119 @@ static void ttf_read_tabdir()
}
}
-static void ttf_read_cmap(void)
+static ttf_cmap_entry *ttf_read_cmap(char *ttf_name, int pid, int eid,
+ boolean warn)
{
- cmap_entry *e;
seg_entry *seg_tab, *s;
TTF_USHORT *glyphId, format, segCount;
- TTF_USHORT ncmapsubtabs;
- long cmap_offset;
- long int n, i, j, k, first_code, length, last_sep, index;
- int unicode_map_count = 0;
- int select_unicode = 1; /* may be changed later if needed */
- ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table vesrion number (=0) */
+ TTF_USHORT ncmapsubtabs, tmp_pid, tmp_eid;
+ TTF_ULONG cmap_offset, tmp_offset;
+ long n, i, k, length, index;
+ ttf_cmap_entry tmp_e, *p;
+ void **aa;
+
+ /* loop up in ttf_cmap_tree first, return if found */
+ tmp_e.ttf_name = ttf_name;
+ tmp_e.pid = pid;
+ tmp_e.eid = eid;
+ if (ttf_cmap_tree == NULL) {
+ ttf_cmap_tree = avl_create(comp_ttf_cmap_entry, NULL, &avl_xallocator);
+ assert(ttf_cmap_tree != NULL);
+ }
+ p = (ttf_cmap_entry *) avl_find(ttf_cmap_tree, &tmp_e);
+ if (p != NULL)
+ return p;
+
+ /* not found, have to read it */
+ ttf_seek_tab("cmap", TTF_USHORT_SIZE); /* skip the table vesrion number (=0) */
ncmapsubtabs = get_ushort();
- cmap_offset = xftell(INFILE, cur_file_name) - 2*TTF_USHORT_SIZE;
+ cmap_offset = xftell(INFILE, cur_file_name) - 2 * TTF_USHORT_SIZE;
cmap_tab = xtalloc(ncmapsubtabs, cmap_entry);
- for (e = cmap_tab; e - cmap_tab < ncmapsubtabs; e++) {
- e->platform_id = get_ushort();
- e->encoding_id = get_ushort();
- e->offset = get_ulong();
- }
- for (i = 0; i < 0xFFFF; ++i)
- unicode_map[i] = NOGLYPH_ASSIGNED_YET;
- for (e = cmap_tab; e - cmap_tab < ncmapsubtabs; e++) {
- ttf_seek_off(cmap_offset + e->offset);
- format = get_ushort();
- if (is_unicode_mapping(e) && format == 4) {
- ++unicode_map_count;
- if (unicode_map_count == select_unicode)
- goto read_unicode_mapping;
+ for (i = 0; i < ncmapsubtabs; ++i) {
+ tmp_pid = get_ushort();
+ tmp_eid = get_ushort();
+ tmp_offset = get_ulong();
+ if (tmp_pid == pid && tmp_eid == eid) {
+ ttf_seek_off(cmap_offset + tmp_offset);
+ format = get_ushort();
+ if (format == 4)
+ goto read_cmap_format_4;
+ else {
+ if (warn)
+ pdftex_warn("cmap format %i unsupported", format);
+ return NULL;
+ }
}
- continue;
-read_unicode_mapping:
- length = get_ushort(); /* length of subtable */
- get_ushort(); /* skip the version number */
- segCount = get_ushort()/2;
- get_ushort(); /* skip searchRange */
- get_ushort(); /* skip entrySelector */
- get_ushort(); /* skip rangeShift */
- seg_tab = xtalloc(segCount, seg_entry);
- for (s = seg_tab; s - seg_tab < segCount; s++)
- s->endCode = get_ushort();
- get_ushort(); /* skip reversedPad */
- for (s = seg_tab; s - seg_tab < segCount; s++)
- s->startCode = get_ushort();
- for (s = seg_tab; s - seg_tab < segCount; s++)
- s->idDelta = get_ushort();
- for (s = seg_tab; s - seg_tab < segCount; s++)
- s->idRangeOffset = get_ushort();
- length -= 8*TTF_USHORT_SIZE + 4*segCount*TTF_USHORT_SIZE;
- n = length/TTF_USHORT_SIZE; /* number of glyphID's */
- glyphId = xtalloc(n, TTF_USHORT);
- for (i = 0; i < n; i++)
- glyphId[i] = get_ushort();
- for (s = seg_tab; s - seg_tab < segCount; s++) {
- for (i = s->startCode; i <= s->endCode; i++) {
- if (i == 0xFFFF)
- break;
- if (s->idRangeOffset != 0xFFFF) {
- if (s->idRangeOffset == 0)
- index = (s->idDelta + i) & 0xFFFF;
- else {
- k = (i - s->startCode) + s->idRangeOffset/2 +
- (s - seg_tab) - segCount ;
- assert(k >= 0 && k < n);
- index = glyphId[k];
- if (index != 0)
- index = (index + s->idDelta) & 0xFFFF;
- }
- if (index >= glyphs_count)
- pdftex_fail("cmap: glyph index %i out of range [0..%i)",
- index, glyphs_count);
- if (unicode_map[i] != NOGLYPH_ASSIGNED_YET)
- pdftex_warn("cmap: multiple glyphs are mapped to unicode %.4X, "
- "only %i will be used (glyph %i being ignored)",
- i, unicode_map[i], index);
- else
- unicode_map[i] = index;
+ }
+ if (warn)
+ pdftex_warn("cannot find cmap subtable for (pid,eid) = (%i, %i)",
+ pid, eid);
+ return NULL;
+ read_cmap_format_4:
+ /* initialize the new entry */
+ p = new_ttf_cmap_entry();
+ p->ttf_name = xstrdup(ttf_name);
+ p->pid = pid;
+ p->eid = eid;
+ p->table = xtalloc(0x10000, short);
+ for (i = 0; i < 0x10000; ++i)
+ p->table[i] = -1; /* unassigned yet */
+
+ /* read the subtable */
+ length = get_ushort(); /* length of subtable */
+ (void) get_ushort(); /* skip the version number */
+ segCount = get_ushort() / 2;
+ (void) get_ushort(); /* skip searchRange */
+ (void) get_ushort(); /* skip entrySelector */
+ (void) get_ushort(); /* skip rangeShift */
+ seg_tab = xtalloc(segCount, seg_entry);
+ for (s = seg_tab; s - seg_tab < segCount; s++)
+ s->endCode = get_ushort();
+ (void) get_ushort(); /* skip reversedPad */
+ for (s = seg_tab; s - seg_tab < segCount; s++)
+ s->startCode = get_ushort();
+ for (s = seg_tab; s - seg_tab < segCount; s++)
+ s->idDelta = get_ushort();
+ for (s = seg_tab; s - seg_tab < segCount; s++)
+ s->idRangeOffset = get_ushort();
+ length -= 8 * TTF_USHORT_SIZE + 4 * segCount * TTF_USHORT_SIZE;
+ n = length / TTF_USHORT_SIZE; /* number of glyphID's */
+ glyphId = xtalloc(n, TTF_USHORT);
+ for (i = 0; i < n; i++)
+ glyphId[i] = get_ushort();
+ for (s = seg_tab; s - seg_tab < segCount; s++) {
+ for (i = s->startCode; i <= s->endCode; i++) {
+ if (i == 0xFFFF)
+ break;
+ if (s->idRangeOffset != 0xFFFF) {
+ if (s->idRangeOffset == 0)
+ index = (s->idDelta + i) & 0xFFFF;
+ else {
+ k = (i - s->startCode) + s->idRangeOffset / 2 +
+ (s - seg_tab) - segCount;
+ assert(k >= 0 && k < n);
+ index = glyphId[k];
+ if (index != 0)
+ index = (index + s->idDelta) & 0xFFFF;
}
+ if (index >= glyphs_count)
+ pdftex_fail("cmap: glyph index %li out of range [0..%i)",
+ index, glyphs_count);
+ if (p->table[i] != -1)
+ pdftex_warn
+ ("cmap: multiple glyphs are mapped to unicode %.4lX, "
+ "only %i will be used (glyph %li being ignored)", i,
+ p->table[i], index);
+ else
+ p->table[i] = index;
}
}
- xfree(seg_tab);
- xfree(glyphId);
- break;
}
- if (e - cmap_tab == ncmapsubtabs)
- pdftex_fail("Invalid argument `-m %i': out of range [1..%i]",
- select_unicode, unicode_map_count);
- xfree(cmap_tab);
+ xfree(seg_tab);
+ xfree(glyphId);
+ aa = avl_probe(ttf_cmap_tree, p);
+ assert(aa != NULL);
+ return p;
}
static void ttf_read_font(void)
@@ -550,10 +692,9 @@ static void ttf_read_font(void)
ttf_read_post();
ttf_read_loca();
ttf_read_name();
- ttf_read_cmap();
}
-static void ttf_reset_chksm(dirtab_entry *tab)
+static void ttf_reset_chksm(dirtab_entry * tab)
{
checksum = 0;
tab_length = 0;
@@ -564,7 +705,7 @@ static void ttf_reset_chksm(dirtab_entry *tab)
}
-static void ttf_set_chksm(dirtab_entry *tab)
+static void ttf_set_chksm(dirtab_entry * tab)
{
tab->length = ttf_offset() - tab->offset;
tab->checksum = ttf_getchksm();
@@ -581,77 +722,77 @@ static void ttf_copytab(const char *name)
}
#define BYTE_ENCODING_LENGTH \
- ((MAX_CHAR_CODE + 1)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE)
+ ((256)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE)
static void ttf_byte_encoding(void)
{
ttfenc_entry *e;
- put_ushort(0); /* format number (0: byte encoding table) */
- put_ushort(BYTE_ENCODING_LENGTH); /* length of table */
- put_ushort(0); /* version number */
- for (e = ttfenc_tab; e - ttfenc_tab <= MAX_CHAR_CODE; e++)
+ (void) put_ushort(0); /* format number (0: byte encoding table) */
+ (void) put_ushort(BYTE_ENCODING_LENGTH); /* length of table */
+ (void) put_ushort(0); /* version number */
+ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++)
if (e->newindex < 256) {
put_byte(e->newindex);
- }
- else {
+ } else {
if (e->name != notdef)
- pdftex_warn("glyph `%s' has been mapped to `%s' in `ttf_byte_encoding' cmap table",
- e->name, notdef);
- put_byte(0); /* notdef */
+ pdftex_warn
+ ("glyph `%s' has been mapped to `%s' in `ttf_byte_encoding' cmap table",
+ e->name, notdef);
+ put_byte(0); /* notdef */
}
}
-#define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (MAX_CHAR_CODE + 1)))
+#define TRIMMED_TABLE_MAP_LENGTH (TTF_USHORT_SIZE*(5 + (256)))
static void ttf_trimmed_table_map(void)
{
ttfenc_entry *e;
- put_ushort(6); /* format number (6): trimmed table mapping */
- put_ushort(TRIMMED_TABLE_MAP_LENGTH);
- put_ushort(0); /* version number (0) */
- put_ushort(0); /* first character code */
- put_ushort(MAX_CHAR_CODE + 1); /* number of character code in table */
- for (e = ttfenc_tab; e - ttfenc_tab <= MAX_CHAR_CODE; e++)
- put_ushort(e->newindex);
+ (void) put_ushort(6); /* format number (6): trimmed table mapping */
+ (void) put_ushort(TRIMMED_TABLE_MAP_LENGTH);
+ (void) put_ushort(0); /* version number (0) */
+ (void) put_ushort(0); /* first character code */
+ (void) put_ushort(256); /* number of character code in table */
+ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++)
+ (void) put_ushort(e->newindex);
}
-#define SEG_MAP_DELTA_LENGTH ((16 + (MAX_CHAR_CODE + 1))*TTF_USHORT_SIZE)
+#define SEG_MAP_DELTA_LENGTH ((16 + (256))*TTF_USHORT_SIZE)
static void ttf_seg_map_delta(void)
{
ttfenc_entry *e;
- put_ushort(4); /* format number (4: segment mapping to delta values) */
- put_ushort(SEG_MAP_DELTA_LENGTH);
- put_ushort(0); /* version number */
- put_ushort(4); /* 2*segCount */
- put_ushort(4); /* searchRange */
- put_ushort(1); /* entrySelector */
- put_ushort(0); /* rangeShift */
- put_ushort(0xF0FF); /* endCount[0] */
- put_ushort(0xFFFF); /* endCount[1] */
- put_ushort(0); /* reversedPad */
- put_ushort(0xF000); /* startCount[0] */
- put_ushort(0xFFFF); /* startCount[1] */
- put_ushort(0); /* idDelta[0] */
- put_ushort(1); /* idDelta[1] */
- put_ushort(2*TTF_USHORT_SIZE); /* idRangeOffset[0] */
- put_ushort(0); /* idRangeOffset[1] */
- for (e = ttfenc_tab; e - ttfenc_tab <= MAX_CHAR_CODE; e++)
- put_ushort(e->newindex);
+ (void) put_ushort(4); /* format number (4: segment mapping to delta values) */
+ (void) put_ushort(SEG_MAP_DELTA_LENGTH);
+ (void) put_ushort(0); /* version number */
+ (void) put_ushort(4); /* 2*segCount */
+ (void) put_ushort(4); /* searchRange */
+ (void) put_ushort(1); /* entrySelector */
+ (void) put_ushort(0); /* rangeShift */
+ (void) put_ushort(0xF0FF); /* endCount[0] */
+ (void) put_ushort(0xFFFF); /* endCount[1] */
+ (void) put_ushort(0); /* reversedPad */
+ (void) put_ushort(0xF000); /* startCount[0] */
+ (void) put_ushort(0xFFFF); /* startCount[1] */
+ (void) put_ushort(0); /* idDelta[0] */
+ (void) put_ushort(1); /* idDelta[1] */
+ (void) put_ushort(2 * TTF_USHORT_SIZE); /* idRangeOffset[0] */
+ (void) put_ushort(0); /* idRangeOffset[1] */
+ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++)
+ (void) put_ushort(e->newindex);
}
#define CMAP_ENTRY_LENGTH (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE)
static void ttf_select_cmap(void)
{
- assert(sizeof(new_cmap_tab) <= NEW_CMAP_SIZE*sizeof(cmap_entry));
- new_cmap_tab[0].platform_id = 1; /* Macintosh */
- new_cmap_tab[0].encoding_id = 0; /* Symbol; ignore code page */
- new_cmap_tab[0].format = new_glyphs_count < 256 ? 0 /* byte encoding */
- : 6; /* trimmed table mapping */
- new_cmap_tab[1].platform_id = 3; /* Microsoft */
- new_cmap_tab[1].encoding_id = 0; /* Symbol; ignore code page */
- new_cmap_tab[1].format = 4; /* segment mapping to delta */
+ assert(sizeof(new_cmap_tab) <= NEW_CMAP_SIZE * sizeof(cmap_entry));
+ new_cmap_tab[0].platform_id = 1; /* Macintosh */
+ new_cmap_tab[0].encoding_id = 0; /* Symbol; ignore code page */
+ new_cmap_tab[0].format = new_glyphs_count < 256 ? 0 /* byte encoding */
+ : 6; /* trimmed table mapping */
+ new_cmap_tab[1].platform_id = 3; /* Microsoft */
+ new_cmap_tab[1].encoding_id = 0; /* Symbol; ignore code page */
+ new_cmap_tab[1].format = 4; /* segment mapping to delta */
}
static void ttf_write_cmap(void)
@@ -661,37 +802,37 @@ static void ttf_write_cmap(void)
dirtab_entry *tab = ttf_name_lookup("cmap", true);
ttf_select_cmap();
ttf_reset_chksm(tab);
- put_ushort(0); /* table version number (0) */
- put_ushort(NEW_CMAP_SIZE); /* number of encoding tables */
- offset = 2*TTF_USHORT_SIZE + NEW_CMAP_SIZE*CMAP_ENTRY_LENGTH;
+ (void) put_ushort(0); /* table version number (0) */
+ (void) put_ushort(NEW_CMAP_SIZE); /* number of encoding tables */
+ offset = 2 * TTF_USHORT_SIZE + NEW_CMAP_SIZE * CMAP_ENTRY_LENGTH;
for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) {
ce->offset = offset;
switch (ce->format) {
- case 0:
- offset += BYTE_ENCODING_LENGTH;
+ case 0:
+ offset += BYTE_ENCODING_LENGTH;
break;
- case 4:
- offset += SEG_MAP_DELTA_LENGTH;
+ case 4:
+ offset += SEG_MAP_DELTA_LENGTH;
break;
- case 6:
- offset += TRIMMED_TABLE_MAP_LENGTH;
+ case 6:
+ offset += TRIMMED_TABLE_MAP_LENGTH;
break;
default:
pdftex_fail("invalid format (it should not have happened)");
}
- put_ushort(ce->platform_id);
- put_ushort(ce->encoding_id);
+ (void) put_ushort(ce->platform_id);
+ (void) put_ushort(ce->encoding_id);
put_ulong(ce->offset);
}
for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) {
switch (ce->format) {
- case 0:
+ case 0:
ttf_byte_encoding();
break;
- case 4:
+ case 4:
ttf_seg_map_delta();
break;
- case 6:
+ case 6:
ttf_trimmed_table_map();
break;
}
@@ -701,19 +842,19 @@ static void ttf_write_cmap(void)
static int prepend_subset_tags(int index, char *p)
{
- boolean is_unicode = (name_tab[index].platform_id == 3);
+ const boolean is_unicode = (name_tab[index].platform_id == 3);
int i;
- assert(index > 0 && index < name_record_num && fm_cur->subset_tag != NULL);
+ assert(index > 0 && index < name_record_num && fd_cur->subset_tag != NULL);
if (is_unicode) {
for (i = 0; i < 6; ++i) {
*p++ = 0;
- *p++ = fm_cur->subset_tag[i];
+ *p++ = fd_cur->subset_tag[i];
}
*p++ = 0;
*p++ = '+';
return 14;
} else {
- strncpy(p, fm_cur->subset_tag, 6);
+ strncpy(p, fd_cur->subset_tag, 6);
p += 6;
*p++ = '+';
return 7;
@@ -729,10 +870,10 @@ static void ttf_write_name(void)
char *new_name_buf;
name_record *n;
dirtab_entry *tab = ttf_name_lookup("name", true);
- if (is_subsetted(fm_cur)) {
+ if (is_subsetted(fd_cur->fm)) {
l = 0;
for (i = 0; i < name_record_num; i++)
- l += name_tab[i].length + 14; /* maximum lengh of new stogare area */
+ l += name_tab[i].length + 14; /* maximum lengh of new stogare area */
new_name_buf = xtalloc(l, char);
/* additional space for subset tags */
p = new_name_buf;
@@ -743,37 +884,35 @@ static void ttf_write_name(void)
n->name_id == 4 || n->name_id == 6) &&
((n->platform_id == 1 && n->encoding_id == 0) ||
(n->platform_id == 3 && n->encoding_id == 0) ||
- (n->platform_id == 3 && n->encoding_id == 1)))
- {
+ (n->platform_id == 3 && n->encoding_id == 1))) {
l = prepend_subset_tags(i, p);
p += l;
- }
- else
+ } else
l = 0;
memcpy(p, name_buf + n->offset, n->length);
p += n->length;
n->new_length = n->length + l;
}
new_name_buf_size = p - new_name_buf;
- }
- else {
+ } else {
new_name_buf = name_buf;
new_name_buf_size = name_buf_size;
}
ttf_reset_chksm(tab);
- put_ushort(0); /* Format selector */
- put_ushort(name_record_num);
- put_ushort(3*TTF_USHORT_SIZE + name_record_num*6*TTF_USHORT_SIZE);
+ (void) put_ushort(0); /* Format selector */
+ (void) put_ushort(name_record_num);
+ (void) put_ushort(3 * TTF_USHORT_SIZE +
+ name_record_num * 6 * TTF_USHORT_SIZE);
for (i = 0; i < name_record_num; i++) {
- put_ushort(name_tab[i].platform_id);
- put_ushort(name_tab[i].encoding_id);
- put_ushort(name_tab[i].language_id);
- put_ushort(name_tab[i].name_id);
- put_ushort(name_tab[i].new_length);
- put_ushort(name_tab[i].new_offset);
+ (void) put_ushort(name_tab[i].platform_id);
+ (void) put_ushort(name_tab[i].encoding_id);
+ (void) put_ushort(name_tab[i].language_id);
+ (void) put_ushort(name_tab[i].name_id);
+ (void) put_ushort(name_tab[i].new_length);
+ (void) put_ushort(name_tab[i].new_offset);
}
for (p = new_name_buf; p - new_name_buf < new_name_buf_size; p++)
- put_char(*p);
+ put_char(*p);
ttf_set_chksm(tab);
if (new_name_buf != name_buf)
xfree(new_name_buf);
@@ -784,24 +923,23 @@ static void ttf_write_dirtab(void)
dirtab_entry *tab;
TTF_ULONG i, k;
char *p;
- integer save_offset = ttf_offset();
+ const integer save_offset = ttf_offset();
ttf_seek_outbuf(TABDIR_OFF);
- if (is_subsetted(fm_cur)) {
+ if (is_subsetted(fd_cur->fm)) {
for (i = 0; i < DEFAULT_NTABS; i++) {
tab = ttf_name_lookup(newtabnames[i], false);
if (tab == NULL)
continue;
for (k = 0; k < 4; k++)
- put_char(tab->tag[k]);
+ put_char(tab->tag[k]);
put_ulong(tab->checksum);
put_ulong(tab->offset);
put_ulong(tab->length);
}
- }
- else {
+ } else {
for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
for (k = 0; k < 4; k++)
- put_char(tab->tag[k]);
+ put_char(tab->tag[k]);
put_ulong(tab->checksum);
put_ulong(tab->offset);
put_ulong(tab->length);
@@ -810,7 +948,7 @@ static void ttf_write_dirtab(void)
/* adjust checkSumAdjustment */
tmp_ulong = 0;
checksum = 0;
- for (p = fb_array, i = 0; i < save_offset;) {
+ for (p = fb_array, i = 0; i < (unsigned) save_offset;) {
tmp_ulong = (tmp_ulong << 8) + *p++;
i++;
if (i % 4 == 0) {
@@ -820,7 +958,7 @@ static void ttf_write_dirtab(void)
}
if (i % 4 != 0) {
pdftex_warn("font length is not a multiple of 4 (%li)", i);
- checksum <<= 8*(4 - i % 4);
+ checksum <<= 8 * (4 - i % 4);
}
k = 0xB1B0AFBA - checksum;
ttf_seek_outbuf(checkSumAdjustment_offset);
@@ -830,19 +968,19 @@ static void ttf_write_dirtab(void)
static void ttf_write_glyf(void)
{
- short *id, k;
+ long *id, k;
TTF_USHORT idx;
TTF_USHORT flags;
dirtab_entry *tab = ttf_name_lookup("glyf", true);
- long glyf_offset = tab->offset;
- long new_glyf_offset = ttf_offset();
+ const long glyf_offset = tab->offset;
+ const long new_glyf_offset = ttf_offset();
ttf_reset_chksm(tab);
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
glyph_tab[*id].newoffset = ttf_offset() - new_glyf_offset;
if (glyph_tab[*id].offset != glyph_tab[*id + 1].offset) {
ttf_seek_off(glyf_offset + glyph_tab[*id].offset);
k = copy_short();
- ttf_ncopy(4*TTF_FWORD_SIZE);
+ ttf_ncopy(4 * TTF_FWORD_SIZE);
if (k < 0) {
do {
flags = copy_ushort();
@@ -850,29 +988,28 @@ static void ttf_write_glyf(void)
if (glyph_tab[idx].newindex < 0) {
glyph_tab[idx].newindex = new_glyphs_count;
glyph_index[new_glyphs_count++] = idx;
- /*
- N.B.: Here we change `new_glyphs_count',
- which appears in the condition of the `for' loop
- */
+ /*
+ N.B.: Here we change `new_glyphs_count',
+ which appears in the condition of the `for' loop
+ */
}
- put_ushort(glyph_tab[idx].newindex);
+ (void) put_ushort(glyph_tab[idx].newindex);
if (flags & ARG_1_AND_2_ARE_WORDS)
- ttf_ncopy(2*TTF_SHORT_SIZE);
+ ttf_ncopy(2 * TTF_SHORT_SIZE);
else
ttf_ncopy(TTF_USHORT_SIZE);
if (flags & WE_HAVE_A_SCALE)
ttf_ncopy(TTF_F2DOT14_SIZE);
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- ttf_ncopy(2*TTF_F2DOT14_SIZE);
+ ttf_ncopy(2 * TTF_F2DOT14_SIZE);
else if (flags & WE_HAVE_A_TWO_BY_TWO)
- ttf_ncopy(4*TTF_F2DOT14_SIZE);
+ ttf_ncopy(4 * TTF_F2DOT14_SIZE);
} while (flags & MORE_COMPONENTS);
if (flags & WE_HAVE_INSTRUCTIONS)
ttf_ncopy(copy_ushort());
- }
- else
- ttf_ncopy(glyph_tab[*id + 1].offset - glyph_tab[*id].offset -
- TTF_USHORT_SIZE - 4*TTF_FWORD_SIZE);
+ } else
+ ttf_ncopy(glyph_tab[*id + 1].offset - glyph_tab[*id].offset -
+ TTF_USHORT_SIZE - 4 * TTF_FWORD_SIZE);
}
}
last_glyf_offset = ttf_offset() - new_glyf_offset;
@@ -883,20 +1020,52 @@ static void ttf_reindex_glyphs(void)
{
ttfenc_entry *e;
glyph_entry *glyph;
- unsigned int index;
- /*
+ int index;
+ short *t;
+ ttf_cmap_entry *cmap = NULL;
+ boolean cmap_not_found = false;
+
+ /*
* reindexing glyphs: we append index of used glyphs to `glyph_index'
* while going through `ttfenc_tab'. After appending a new entry to
* `glyph_index' we set field `newindex' of corresponding entries in both
* `glyph_tab' and `ttfenc_tab' to the newly created index
- *
*/
- for (e = ttfenc_tab; e - ttfenc_tab <= MAX_CHAR_CODE; e++) {
- e->newindex = 0; /* index of ".notdef" glyph */
+ for (e = ttfenc_tab; e - ttfenc_tab < 256; e++) {
+ e->newindex = 0; /* index of ".notdef" glyph */
+
+ /* handle case of subfonts first */
+ if (is_subfont(fd_cur->fm)) {
+ if (e->code == -1)
+ continue;
+ assert(fd_cur->fm->pid != -1 && fd_cur->fm->eid != -1);
+ if (cmap == NULL && !cmap_not_found) {
+ cmap =
+ ttf_read_cmap(fd_cur->fm->ff_name, fd_cur->fm->pid,
+ fd_cur->fm->eid, true);
+ if (cmap == NULL)
+ cmap_not_found = true;
+ }
+ if (cmap == NULL)
+ continue;
+ t = cmap->table;
+ assert(t != NULL && e->code < 0x10000);
+ if (t[e->code] < 0) {
+ pdftex_warn
+ ("subfont %s: wrong mapping: character %li --> 0x%4.4lX --> .notdef",
+ fd_cur->fm->tfm_name, (long) (e - ttfenc_tab), e->code);
+ continue;
+ }
+ assert(t[e->code] >= 0 && t[e->code] < glyphs_count); /* t has been read from ttf */
+ glyph = glyph_tab + t[e->code];
+ goto append_new_glyph;
+ }
+
+ /* handle case of reencoded fonts */
if (e->name == notdef)
continue;
/* scan form `index123' */
- if (sscanf(e->name, GLYPH_PREFIX_INDEX "%i", &index) == 1) {
+ if (sscanf(e->name, GLYPH_PREFIX_INDEX "%i", &index) == 1) {
if (index >= glyphs_count) {
pdftex_warn("`%s' out of valid range [0..%i)",
e->name, glyphs_count);
@@ -907,18 +1076,32 @@ static void ttf_reindex_glyphs(void)
}
/* scan form `uniABCD' */
if (sscanf(e->name, GLYPH_PREFIX_UNICODE "%X", &index) == 1) {
- assert(index <= 0xFFFF);
- if (unicode_map[index] != NOGLYPH_ASSIGNED_YET) {
- if (unicode_map[index] >= glyphs_count) {
- pdftex_warn("`%s' is mapped to index %i which is out of valid range [0..%i)",
- e->name, unicode_map[index], glyphs_count);
+ if (cmap == NULL && !cmap_not_found) {
+ /* need to read the unicode mapping, ie (pid,eid) = (3,1) or (0,3) */
+ cmap = ttf_read_cmap(fd_cur->fm->ff_name, 3, 1, false);
+ if (cmap == NULL)
+ cmap = ttf_read_cmap(fd_cur->fm->ff_name, 0, 3, false);
+ if (cmap == NULL) {
+ pdftex_warn
+ ("no unicode mapping found, all `uniXXXX' names will be ignored");
+ cmap_not_found = true; /* once only */
+ }
+ }
+ if (cmap == NULL)
+ continue;
+ t = cmap->table;
+ assert(t != NULL);
+ if (t[index] != -1) {
+ if (t[index] >= glyphs_count) {
+ pdftex_warn
+ ("`%s' is mapped to index %i which is out of valid range [0..%i)",
+ e->name, t[index], glyphs_count);
continue;
}
- glyph = glyph_tab + unicode_map[index];
+ glyph = glyph_tab + t[index];
goto append_new_glyph;
- }
- else {
- pdftex_warn("`unicode %s%.4X' is not mapped to any glyph",
+ } else {
+ pdftex_warn("`unicode %s%.4X' is not mapped to any glyph",
GLYPH_PREFIX_UNICODE, index);
continue;
}
@@ -931,8 +1114,8 @@ static void ttf_reindex_glyphs(void)
pdftex_warn("glyph `%s' not found", e->name);
continue;
}
-append_new_glyph:
- assert(glyph - glyph_tab < glyphs_count);
+ append_new_glyph:
+ assert(glyph > glyph_tab && glyph - glyph_tab < glyphs_count);
if (glyph->newindex < 0) {
glyph_index[new_glyphs_count] = glyph - glyph_tab;
glyph->newindex = new_glyphs_count;
@@ -941,40 +1124,40 @@ append_new_glyph:
e->newindex = glyph->newindex;
}
}
-
+
static void ttf_write_head()
{
dirtab_entry *tab;
tab = ttf_seek_tab("head", 0);
ttf_reset_chksm(tab);
- ttf_ncopy(2*TTF_FIXED_SIZE);
+ ttf_ncopy(2 * TTF_FIXED_SIZE);
checkSumAdjustment_offset = ttf_offset();
put_ulong(0);
- ttf_skip(TTF_ULONG_SIZE); /* skip checkSumAdjustment */
- ttf_ncopy(TTF_ULONG_SIZE + 2*TTF_USHORT_SIZE + 16 +
- 4*TTF_FWORD_SIZE + 2*TTF_USHORT_SIZE + TTF_SHORT_SIZE);
- if (is_subsetted(fm_cur)) {
- put_short(loca_format);
- put_short(0);
- }
- else
- ttf_ncopy(2*TTF_SHORT_SIZE);
+ ttf_skip(TTF_ULONG_SIZE); /* skip checkSumAdjustment */
+ ttf_ncopy(TTF_ULONG_SIZE + 2 * TTF_USHORT_SIZE + 16 +
+ 4 * TTF_FWORD_SIZE + 2 * TTF_USHORT_SIZE + TTF_SHORT_SIZE);
+ if (is_subsetted(fd_cur->fm)) {
+ (void) put_short(loca_format);
+ (void) put_short(0);
+ } else
+ ttf_ncopy(2 * TTF_SHORT_SIZE);
ttf_set_chksm(tab);
}
-
+
static void ttf_write_hhea(void)
{
dirtab_entry *tab;
tab = ttf_seek_tab("hhea", 0);
ttf_reset_chksm(tab);
- ttf_ncopy(TTF_FIXED_SIZE + 3*TTF_FWORD_SIZE + TTF_UFWORD_SIZE + 3*TTF_FWORD_SIZE + 8*TTF_SHORT_SIZE);
- put_ushort(new_glyphs_count);
+ ttf_ncopy(TTF_FIXED_SIZE + 3 * TTF_FWORD_SIZE + TTF_UFWORD_SIZE +
+ 3 * TTF_FWORD_SIZE + 8 * TTF_SHORT_SIZE);
+ (void) put_ushort(new_glyphs_count);
ttf_set_chksm(tab);
}
static void ttf_write_htmx(void)
{
- short *id;
+ long *id;
dirtab_entry *tab = ttf_seek_tab("hmtx", 0);
ttf_reset_chksm(tab);
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
@@ -986,7 +1169,7 @@ static void ttf_write_htmx(void)
static void ttf_write_loca(void)
{
- short *id;
+ long *id;
dirtab_entry *tab = ttf_seek_tab("loca", 0);
ttf_reset_chksm(tab);
loca_format = 0;
@@ -1002,11 +1185,10 @@ static void ttf_write_loca(void)
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
put_ulong(glyph_tab[*id].newoffset);
put_ulong(last_glyf_offset);
- }
- else {
+ } else {
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
- put_ushort(glyph_tab[*id].newoffset/2);
- put_ushort(last_glyf_offset/2);
+ (void) put_ushort(glyph_tab[*id].newoffset / 2);
+ (void) put_ushort(last_glyf_offset / 2);
}
ttf_set_chksm(tab);
}
@@ -1016,8 +1198,8 @@ static void ttf_write_mapx(void)
dirtab_entry *tab = ttf_seek_tab("maxp", TTF_FIXED_SIZE + TTF_USHORT_SIZE);
ttf_reset_chksm(tab);
put_fixed(0x00010000);
- put_ushort(new_glyphs_count);
- ttf_ncopy(13*TTF_USHORT_SIZE);
+ (void) put_ushort(new_glyphs_count);
+ ttf_ncopy(13 * TTF_USHORT_SIZE);
ttf_set_chksm(tab);
}
@@ -1027,22 +1209,22 @@ static void ttf_write_OS2(void)
TTF_USHORT version;
ttf_reset_chksm(tab);
version = get_ushort();
- if (version != 0x0000 && version != 0x0001 && version != 0x0002)
- pdftex_fail("unknown verssion of OS/2 table (%.4X)", version);
- put_ushort(0x0001); /* fix version to 1*/
- ttf_ncopy(2*TTF_USHORT_SIZE + 13*TTF_SHORT_SIZE + 10*TTF_BYTE_SIZE);
- ttf_skip(4*TTF_ULONG_SIZE); /* ulUnicodeRange 1--4 */
- put_ulong(0x00000003); /* Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */
- put_ulong(0x10000000); /* Private Use (0xE000--0xF8FF) */
+ if (version > 3)
+ pdftex_fail("unknown version of OS/2 table (%.4X)", version);
+ (void) put_ushort(0x0001); /* fix version to 1 */
+ ttf_ncopy(2 * TTF_USHORT_SIZE + 13 * TTF_SHORT_SIZE + 10 * TTF_BYTE_SIZE);
+ ttf_skip(4 * TTF_ULONG_SIZE); /* ulUnicodeRange 1--4 */
+ put_ulong(0x00000003); /* Basic Latin + Latin-1 Supplement (0x0000--0x00FF) */
+ put_ulong(0x10000000); /* Private Use (0xE000--0xF8FF) */
put_ulong(0x00000000);
put_ulong(0x00000000);
- ttf_ncopy(4*TTF_CHAR_SIZE + TTF_USHORT_SIZE); /* achVendID + fsSelection */
- ttf_skip(2*TTF_USHORT_SIZE);
- put_ushort(0x0000); /* usFirstCharIndex */
- put_ushort(0xF0FF); /* usLastCharIndex */
- ttf_ncopy(5*TTF_USHORT_SIZE);
- /* for version 0 the OS/2 table ends here, the rest is for version 1 */
- put_ulong(0x80000000); /* Symbol Character Set---don't use any code page */
+ ttf_ncopy(4 * TTF_CHAR_SIZE + TTF_USHORT_SIZE); /* achVendID + fsSelection */
+ ttf_skip(2 * TTF_USHORT_SIZE);
+ (void) put_ushort(0x0000); /* usFirstCharIndex */
+ (void) put_ushort(0xF0FF); /* usLastCharIndex */
+ ttf_ncopy(5 * TTF_USHORT_SIZE);
+ /* for version 0 the OS/2 table ends here, the rest is for version 1 */
+ put_ulong(0x80000000); /* Symbol Character Set---don't use any code page */
put_ulong(0x00000000);
ttf_set_chksm(tab);
}
@@ -1061,23 +1243,22 @@ static void ttf_write_post(void)
dirtab_entry *tab = ttf_seek_tab("post", TTF_FIXED_SIZE);
glyph_entry *glyph;
char *s;
- short *id;
+ long *id;
int l;
ttf_reset_chksm(tab);
- if (!write_ttf_glyph_names || post_format == 0x00030000) {
+ if (!fd_cur->write_ttf_glyph_names || post_format == 0x00030000) {
put_fixed(0x00030000);
- ttf_ncopy(TTF_FIXED_SIZE + 2*TTF_FWORD_SIZE + 5*TTF_ULONG_SIZE);
- }
- else {
+ ttf_ncopy(TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE);
+ } else {
put_fixed(0x00020000);
- ttf_ncopy(TTF_FIXED_SIZE + 2*TTF_FWORD_SIZE + 5*TTF_ULONG_SIZE);
- put_ushort(new_glyphs_count);
+ ttf_ncopy(TTF_FIXED_SIZE + 2 * TTF_FWORD_SIZE + 5 * TTF_ULONG_SIZE);
+ (void) put_ushort(new_glyphs_count);
k = 0;
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
glyph = glyph_tab + *id;
if (glyph->name_index >= NMACGLYPHS || unsafe_name(glyph->name))
glyph->name_index = NMACGLYPHS + k++;
- put_ushort(glyph->name_index);
+ (void) put_ushort(glyph->name_index);
}
for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
glyph = glyph_tab + *id;
@@ -1097,12 +1278,12 @@ static void ttf_init_font(int n)
{
int i, k;
for (i = 1, k = 0; i <= n; i <<= 1, k++);
- put_fixed(0x00010000); /* font version */
- put_ushort(n); /* number of tables */
- put_ushort(i << 3); /* search range */
- put_ushort(k - 1); /* entry selector */
- put_ushort((n<<4) - (i<<3)); /* range shift */
- ttf_seek_outbuf(TABDIR_OFF + n*4*TTF_ULONG_SIZE);
+ put_fixed(0x00010000); /* font version */
+ (void) put_ushort(n); /* number of tables */
+ (void) put_ushort(i << 3); /* search range */
+ (void) put_ushort(k - 1); /* entry selector */
+ (void) put_ushort((n << 4) - (i << 3)); /* range shift */
+ ttf_seek_outbuf(TABDIR_OFF + n * 4 * TTF_ULONG_SIZE);
}
static void ttf_subset_font(void)
@@ -1143,25 +1324,29 @@ static void ttf_copy_font(void)
ttf_write_dirtab();
}
-void writettf()
+void writettf(fd_entry * fd)
{
- set_cur_file_name(fm_cur->ff_name);
- if (is_subsetted(fm_cur) && !(is_reencoded(fm_cur))) {
- pdftex_warn("encoding vector required for TrueType font subsetting");
+ fd_cur = fd; /* fd_cur is global inside writettf.c */
+ assert(fd_cur->fm != NULL);
+ assert(is_truetype(fd_cur->fm));
+ assert(is_included(fd_cur->fm));
+
+ set_cur_file_name(fd_cur->fm->ff_name);
+ if (is_subsetted(fd_cur->fm) && (fd_cur->fe == NULL)
+ && !is_subfont(fd_cur->fm)) {
+ pdftex_warn("Subset TrueType must be a reencoded or a subfont");
cur_file_name = NULL;
return;
}
if (!ttf_open()) {
pdftex_fail("cannot open TrueType font file for reading");
}
- cur_file_name = (char*)nameoffile + 1;
- if (!is_included(fm_cur))
- tex_printf("{%s", cur_file_name);
- else if (is_subsetted(fm_cur))
+ cur_file_name = (char *) nameoffile + 1;
+ if (is_subsetted(fd_cur->fm))
tex_printf("<%s", cur_file_name);
else
tex_printf("<<%s", cur_file_name);
- fontfile_found = true;
+ fd_cur->ff_found = true;
new_glyphs_count = 2;
new_ntabs = DEFAULT_NTABS;
dir_tab = NULL;
@@ -1171,18 +1356,16 @@ void writettf()
name_tab = NULL;
name_buf = NULL;
ttf_read_font();
- if (is_included(fm_cur)) {
- pdfsaveoffset = pdfoffset();
- pdfflush();
- if (is_subsetted(fm_cur)) {
- ttf_copy_encoding();
- make_subset_tag(fm_cur, fm_cur->encoding->glyph_names);
- ttf_subset_font();
- }
- else
- ttf_copy_font();
- ttf_length = ttf_offset();
- }
+
+ pdfsaveoffset = pdfoffset();
+ pdfflush();
+ if (is_subsetted(fd_cur->fm)) {
+ ttf_copy_encoding();
+ ttf_subset_font();
+ } else
+ ttf_copy_font();
+ ttf_length = ttf_offset();
+
xfree(dir_tab);
xfree(glyph_tab);
xfree(glyph_index);
@@ -1190,26 +1373,32 @@ void writettf()
xfree(name_tab);
xfree(name_buf);
ttf_close();
- if (!is_included(fm_cur))
- tex_printf("}");
- else if (is_subsetted(fm_cur))
+ if (is_subsetted(fd_cur->fm))
tex_printf(">");
else
tex_printf(">>");
cur_file_name = NULL;
}
-void writeotf()
+void writeotf(fd_entry * fd)
{
dirtab_entry *tab;
long i;
- set_cur_file_name(fm_cur->ff_name);
- if (!open_input(&ttf_file, kpse_type1_format, FOPEN_RBIN_MODE)) {
+
+ fd_cur = fd; /* fd_cur is global inside writettf.c */
+ assert(fd_cur->fm != NULL);
+ assert(is_opentype(fd_cur->fm));
+ assert(is_included(fd_cur->fm));
+
+ set_cur_file_name(fd_cur->fm->ff_name);
+ if (is_subsetted(fd_cur->fm))
+ pdftex_fail("OTF fonts must be included entirely");
+ if (!open_input(&ttf_file, kpse_opentype_format, FOPEN_RBIN_MODE)) {
pdftex_fail("cannot open OpenType font file for reading");
}
- cur_file_name = (char*)nameoffile + 1;
+ cur_file_name = (char *) nameoffile + 1;
tex_printf("<<%s", cur_file_name);
- fontfile_found = true;
+ fd_cur->ff_found = true;
dir_tab = NULL;
glyph_tab = NULL;
ttf_read_tabdir();
@@ -1252,6 +1441,4 @@ void writeotf()
The table directory also includes the offset of the associated tagged
table from the beginning of the font file and the length of that table.
-
-
*/