Back to index

tetex-bin  3.0
Classes | Defines | Functions | Variables
writettf.c File Reference
#include "ptexlib.h"
#include "writettf.h"
#include "macnames.c"

Go to the source code of this file.

Classes

struct  glyph_entry
struct  ttfenc_entry
struct  name_record

Defines

#define DEFAULT_NTABS   14
#define NEW_CMAP_SIZE   2
#define ttf_putchar   fb_putchar
#define ttf_offset   fb_offset
#define ttf_seek_outbuf   fb_seek
#define INFILE   ttf_file
#define ttf_open()   open_input(&ttf_file, kpse_truetype_format, FOPEN_RBIN_MODE)
#define ttf_close()   xfclose(ttf_file, cur_file_name)
#define ttf_getchar()   xgetc(ttf_file)
#define ttf_eof()   feof(ttf_file)
#define ttf_append_byte(B)
#define BYTE_ENCODING_LENGTH   ((MAX_CHAR_CODE + 1)*TTF_BYTE_SIZE + 3*TTF_USHORT_SIZE)
#define TRIMMED_TABLE_MAP_LENGTH   (TTF_USHORT_SIZE*(5 + (MAX_CHAR_CODE + 1)))
#define SEG_MAP_DELTA_LENGTH   ((16 + (MAX_CHAR_CODE + 1))*TTF_USHORT_SIZE)
#define CMAP_ENTRY_LENGTH   (2*TTF_USHORT_SIZE + TTF_ULONG_SIZE)

Functions

static unsigned char ttf_addchksm (unsigned char b)
static TTF_ULONG ttf_getchksm (void)
static long ttf_putnum (int s, long n)
static long ttf_getnum (int s)
static long ttf_funit (long n)
static void ttf_ncopy (int n)
static dirtab_entryttf_name_lookup (const char *s, boolean required)
static dirtab_entryttf_seek_tab (const char *name, TTF_LONG offset)
static void ttf_seek_off (TTF_LONG offset)
static void ttf_copy_encoding (void)
static void ttf_read_name (void)
static void ttf_read_mapx (void)
static void ttf_read_head (void)
static void ttf_read_hhea (void)
static void ttf_read_pclt (void)
static void ttf_read_hmtx (void)
static void ttf_read_post (void)
static void ttf_read_loca (void)
static void ttf_read_tabdir ()
static void ttf_read_cmap (void)
static void ttf_read_font (void)
static void ttf_reset_chksm (dirtab_entry *tab)
static void ttf_set_chksm (dirtab_entry *tab)
static void ttf_copytab (const char *name)
static void ttf_byte_encoding (void)
static void ttf_trimmed_table_map (void)
static void ttf_seg_map_delta (void)
static void ttf_select_cmap (void)
static void ttf_write_cmap (void)
static int prepend_subset_tags (int index, char *p)
static void ttf_write_name (void)
static void ttf_write_dirtab (void)
static void ttf_write_glyf (void)
static void ttf_reindex_glyphs (void)
static void ttf_write_head ()
static void ttf_write_hhea (void)
static void ttf_write_htmx (void)
static void ttf_write_loca (void)
static void ttf_write_mapx (void)
static void ttf_write_OS2 (void)
static boolean unsafe_name (char *s)
static void ttf_write_post (void)
static void ttf_init_font (int n)
static void ttf_subset_font (void)
static void ttf_copy_font (void)
void writettf ()
void writeotf ()

Variables

static const char perforce_id [] = "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writettf.c#14 $"
static TTF_USHORT ntabs
static TTF_USHORT upem
static TTF_FIXED post_format
static TTF_SHORT loca_format
static TTF_ULONG last_glyf_offset
static TTF_USHORT glyphs_count
static TTF_USHORT new_glyphs_count
static TTF_USHORT nhmtxs
static TTF_USHORT new_ntabs
static glyph_entryglyph_tab
static shortglyph_index
static cmap_entrycmap_tab
static cmap_entry new_cmap_tab [NEW_CMAP_SIZE]
static name_recordname_tab
static int name_record_num
static char * name_buf
static int name_buf_size
static dirtab_entrydir_tab
static char * glyph_name_buf
static TTF_ULONG checksum
static TTF_ULONG tab_length
static TTF_ULONG tmp_ulong
static TTF_ULONG checkSumAdjustment_offset
static FILEttf_file
static ttfenc_entry ttfenc_tab [MAX_CHAR_CODE+1]
static TTF_USHORT unicode_map [0xFFFF]
integer ttf_length
char * fb_array
static const char * newtabnames []

Class Documentation

struct glyph_entry

Definition at line 44 of file writettf.c.

Class Members
TTF_UFWORD advWidth
TTF_FWORD lsb
char * name
TTF_USHORT name_index
TTF_SHORT newindex
TTF_LONG newoffset
TTF_LONG offset
struct ttfenc_entry

Definition at line 54 of file writettf.c.

Class Members
char * name
short newindex
struct name_record

Definition at line 59 of file writettf.c.

Class Members
TTF_USHORT encoding_id
TTF_USHORT language_id
TTF_USHORT length
TTF_USHORT name_id
TTF_USHORT new_length
TTF_USHORT new_offset
TTF_USHORT offset
TTF_USHORT platform_id

Define Documentation

Definition at line 579 of file writettf.c.

Definition at line 639 of file writettf.c.

#define DEFAULT_NTABS   14

Definition at line 29 of file writettf.c.

#define INFILE   ttf_file

Definition at line 36 of file writettf.c.

#define NEW_CMAP_SIZE   2

Definition at line 30 of file writettf.c.

#define SEG_MAP_DELTA_LENGTH   ((16 + (MAX_CHAR_CODE + 1))*TTF_USHORT_SIZE)

Definition at line 614 of file writettf.c.

Definition at line 600 of file writettf.c.

#define ttf_append_byte (   B)
Value:
do {\
    if (name_tab[i].platform_id == 3)\
        *q++ = 0;\
    *q++ = B;\
} while (0)

Definition at line 222 of file writettf.c.

#define ttf_close ( )    xfclose(ttf_file, cur_file_name)

Definition at line 40 of file writettf.c.

#define ttf_eof ( )    feof(ttf_file)

Definition at line 42 of file writettf.c.

#define ttf_getchar ( )    xgetc(ttf_file)

Definition at line 41 of file writettf.c.

#define ttf_offset   fb_offset

Definition at line 33 of file writettf.c.

#define ttf_open ( )    open_input(&ttf_file, kpse_truetype_format, FOPEN_RBIN_MODE)

Definition at line 38 of file writettf.c.

#define ttf_putchar   fb_putchar

Definition at line 32 of file writettf.c.

#define ttf_seek_outbuf   fb_seek

Definition at line 34 of file writettf.c.


Function Documentation

static int prepend_subset_tags ( int  index,
char *  p 
) [static]

Definition at line 698 of file writettf.c.

{
    boolean is_unicode = (name_tab[index].platform_id == 3);
    int i;
    assert(index > 0 && index < name_record_num && fm_cur->subset_tag != NULL);
    if (is_unicode) {
        for (i = 0; i < 6; ++i) {
            *p++ = 0;
            *p++ = fm_cur->subset_tag[i];
        }
        *p++ = 0;
        *p++ = '+';
        return 14;
    } else {
        strncpy(p, fm_cur->subset_tag, 6);
        p += 6;
        *p++ = '+';
        return 7;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned char ttf_addchksm ( unsigned char  b) [static]

Definition at line 122 of file writettf.c.

{
    tmp_ulong = (tmp_ulong << 8) + b;
    tab_length++;
    if (tab_length % 4 == 0) {
        checksum += tmp_ulong;
        tmp_ulong = 0;
    }
    return b;
}

Here is the caller graph for this function:

static void ttf_byte_encoding ( void  ) [static]

Definition at line 582 of file writettf.c.

{
    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++)
        if (e->newindex < 256) {
            put_byte(e->newindex);
        }
        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 */
        }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_copy_encoding ( void  ) [static]

Definition at line 208 of file writettf.c.

{
    int i;
    char **glyph_names = (fm_cur->encoding)->glyph_names;
    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;
    }
}

Here is the caller graph for this function:

static void ttf_copy_font ( void  ) [static]

Definition at line 1129 of file writettf.c.

{
    dirtab_entry *tab;
    ttf_init_font(ntabs);
    for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
        if (strncmp(tab->tag, "head", 4) == 0)
            ttf_write_head();
        else
            ttf_copytab(tab->tag);
    }
    ttf_write_dirtab();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_copytab ( const char *  name) [static]

Definition at line 569 of file writettf.c.

{
    long i;
    dirtab_entry *tab = ttf_seek_tab(name, 0);
    ttf_reset_chksm(tab);
    for (i = tab->length; i > 0; i--)
        copy_char();
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long ttf_funit ( long  n) [static]

Definition at line 167 of file writettf.c.

{
    if (n < 0)
        return -((-n/upem)*1000 + ((-n%upem)*1000)/upem);
    else
        return (n/upem)*1000 + ((n%upem)*1000)/upem;
}

Here is the caller graph for this function:

static TTF_ULONG ttf_getchksm ( void  ) [static]

Definition at line 133 of file writettf.c.

{
    while (tab_length % 4 != 0)
        ttf_putchar(ttf_addchksm(0)); /* ttf_addchksm updates tab_length */
    return checksum;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long ttf_getnum ( int  s) [static]

Definition at line 154 of file writettf.c.

{
    long i = 0;
    int c;
    while (s > 0) {
        if ((c = ttf_getchar()) < 0)
            pdftex_fail("unexpected EOF");
        i = (i << 8) + c;
        s--;
    }
    return i;
}
static void ttf_init_font ( int  n) [static]

Definition at line 1092 of file writettf.c.

{
    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);
}

Here is the caller graph for this function:

static dirtab_entry* ttf_name_lookup ( const char *  s,
boolean  required 
) [static]

Definition at line 181 of file writettf.c.

{
    dirtab_entry *tab;
    for (tab = dir_tab; tab - dir_tab < ntabs; tab++)
        if (strncmp(tab->tag, s, 4) == 0)
            break;
    if (tab - dir_tab == ntabs) {
        if (required)
            pdftex_fail("can't find table `%s'", s);
        else
            tab = NULL;
    }
    return tab;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_ncopy ( int  n) [static]

Definition at line 175 of file writettf.c.

{
    while (n-- > 0)
        copy_byte();
}

Here is the caller graph for this function:

static long ttf_putnum ( int  s,
long  n 
) [static]

Definition at line 140 of file writettf.c.

{
    long i = n;
    char buf[TTF_LONG_SIZE + 1], *p = buf;
    while (s-- > 0) {
        *p++ = i & 0xFF;
        i >>= 8;
    }
    p--;
    while (p >= buf)
        ttf_putchar(ttf_addchksm(*p--));
    return n;
}

Here is the call graph for this function:

static void ttf_read_cmap ( void  ) [static]

Definition at line 445 of file writettf.c.

{
    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) */
    ncmapsubtabs = get_ushort();
    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;
        }
        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 out of range [0..%i)", glyphs_count);
                    if (unicode_map[i] != NOGLYPH_ASSIGNED_YET)
                        pdftex_fail("cmap: unicode %.4X is mapped to multiple glyphs", i);
                    unicode_map[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);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_font ( void  ) [static]

Definition at line 530 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_head ( void  ) [static]
static void ttf_read_hhea ( void  ) [static]

Definition at line 311 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_hmtx ( void  ) [static]

Definition at line 334 of file writettf.c.

{
    glyph_entry *glyph;
    TTF_UFWORD last_advWidth;
    ttf_seek_tab("hmtx", 0);
    for (glyph = glyph_tab; glyph - glyph_tab < nhmtxs; glyph++) {
        glyph->advWidth = get_ufword();
        glyph->lsb = get_ufword();
    }
    if (nhmtxs < glyphs_count) {
        last_advWidth = glyph[-1].advWidth;
        for (;glyph - glyph_tab <  glyphs_count; glyph++) {
            glyph->advWidth = last_advWidth;
            glyph->lsb = get_ufword();
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_loca ( void  ) [static]

Definition at line 415 of file writettf.c.

{
    glyph_entry *glyph;
    ttf_seek_tab("loca", 0);
    if (loca_format != 0)
        for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++)
            glyph->offset = get_ulong();
    else
        for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count + 1; glyph++)
            glyph->offset = get_ushort() << 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_mapx ( void  ) [static]

Definition at line 277 of file writettf.c.

{
    int i;
    glyph_entry *glyph;
    ttf_seek_tab("maxp", TTF_FIXED_SIZE);
    glyph_tab = xtalloc(1 + (glyphs_count = get_ushort()), glyph_entry);
    for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count; glyph++) {
        glyph->newindex = -1;
        glyph->newoffset = 0;
        glyph->name_index = 0;
        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 */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_name ( void  ) [static]

Definition at line 229 of file writettf.c.

{
    int i, j;
    dirtab_entry *tab = ttf_seek_tab("name", TTF_USHORT_SIZE);
    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 = xtalloc(name_buf_size, char);
    ttf_skip(TTF_USHORT_SIZE);
    for (i = 0; i < name_record_num; i++) {
        name_tab[i].platform_id = get_ushort();
        name_tab[i].encoding_id = get_ushort();
        name_tab[i].language_id = get_ushort();
        name_tab[i].name_id = get_ushort();
        name_tab[i].length = get_ushort();
        name_tab[i].offset = get_ushort();
    }
    for (p = name_buf; p - name_buf < name_buf_size; p++)
         *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;
            break;
        }
    }
    if (!font_keys[FONTNAME_CODE].valid) {
        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)
                    *p++ = name_buf[name_tab[i].offset + j + 1];
                *p = 0;
                font_keys[FONTNAME_CODE].valid = true;
                break;
            }
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_pclt ( void  ) [static]

Definition at line 322 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_post ( void  ) [static]

Definition at line 352 of file writettf.c.

{
    int k, nnames;
    long length;
    long int_part, frac_part;
    int sign = 1;
    TTF_FIXED italic_angle;
    char *p;
    glyph_entry *glyph;
    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 */
        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;
    if (glyph_tab == NULL)
        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_index = glyph - glyph_tab;
        }
        break;
    case 0x20000:
        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);
        glyph_name_buf = xtalloc(length, char);
        for (p = glyph_name_buf; p - glyph_name_buf < length;) {
            for (k = get_byte(); k > 0; k--)
                *p++ = get_char();
            *p++ = 0;
        }
        for (glyph = glyph_tab; glyph - glyph_tab < nnames; glyph++) {
            if (glyph->name_index < NMACGLYPHS)
                glyph->name = (char*)mac_glyph_names[glyph->name_index];
            else {
                p = glyph_name_buf;
                k = glyph->name_index - NMACGLYPHS;
                for (; k > 0; k--)
                    p = strend(p) + 1;
                glyph->name = p;
            }
        }
        break;
    case 0x00030000:
        for (glyph = glyph_tab; glyph - glyph_tab < NMACGLYPHS; glyph++) {
            glyph->name_index = glyph - glyph_tab;
        }
        break;
    default:
        pdftex_fail("unsupported format (%.8X) of `post' table", (unsigned int) post_format);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_read_tabdir ( ) [static]

Definition at line 427 of file writettf.c.

{
    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 */
    dir_tab = xtalloc(ntabs = get_ushort(), dirtab_entry);
    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();
        tab->checksum = get_ulong();
        tab->offset = get_ulong();
        tab->length = get_ulong();
    }
}

Here is the caller graph for this function:

static void ttf_reindex_glyphs ( void  ) [static]

Definition at line 878 of file writettf.c.

{
    ttfenc_entry *e;
    glyph_entry *glyph;
    unsigned int index;
    /* 
     * 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 */
        if (e->name == notdef)
            continue;
        /* scan form `index123' */
        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);
                continue;
            }
            glyph = glyph_tab + index;
            goto append_new_glyph;
        }
        /* 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);
                    continue;
                }
                glyph = glyph_tab + unicode_map[index];
                goto append_new_glyph;
            }
            else {
                pdftex_warn("`unicode %s%.4X' is not mapped to any glyph", 
                            GLYPH_PREFIX_UNICODE, index);
                continue;
            }
        }
        /* look up by name */
        for (glyph = glyph_tab; glyph - glyph_tab < glyphs_count; glyph++)
            if (glyph->name != notdef && strcmp(glyph->name, e->name) == 0)
                break;
        if (!(glyph - glyph_tab < glyphs_count)) {
            pdftex_warn("glyph `%s' not found", e->name);
            continue;
        }
append_new_glyph:
        assert(glyph - glyph_tab < glyphs_count);
        if (glyph->newindex < 0) {
            glyph_index[new_glyphs_count] = glyph - glyph_tab;
            glyph->newindex = new_glyphs_count;
            new_glyphs_count++;
        }
        e->newindex = glyph->newindex;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_reset_chksm ( dirtab_entry tab) [static]

Definition at line 552 of file writettf.c.

{
    checksum = 0;
    tab_length = 0;
    tmp_ulong = 0;
    tab->offset = ttf_offset();
    if (tab->offset % 4 != 0)
        pdftex_warn("offset of `%4.4s' is not a multiple of 4", tab->tag);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_seek_off ( TTF_LONG  offset) [static]

Definition at line 203 of file writettf.c.

static dirtab_entry* ttf_seek_tab ( const char *  name,
TTF_LONG  offset 
) [static]

Definition at line 196 of file writettf.c.

{
    dirtab_entry *tab = ttf_name_lookup(name, true);
    xfseek(INFILE, tab->offset + offset, SEEK_SET, cur_file_name);
    return tab;
}

Here is the call graph for this function:

static void ttf_seg_map_delta ( void  ) [static]

Definition at line 616 of file writettf.c.

{
    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);
}

Here is the caller graph for this function:

static void ttf_select_cmap ( void  ) [static]

Definition at line 641 of file writettf.c.

{
    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 */
}

Here is the caller graph for this function:

static void ttf_set_chksm ( dirtab_entry tab) [static]

Definition at line 563 of file writettf.c.

{
    tab->length = ttf_offset() - tab->offset;
    tab->checksum = ttf_getchksm();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_subset_font ( void  ) [static]

Definition at line 1104 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_trimmed_table_map ( void  ) [static]

Definition at line 602 of file writettf.c.

{
    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);
}

Here is the caller graph for this function:

static void ttf_write_cmap ( void  ) [static]

Definition at line 653 of file writettf.c.

{
    cmap_entry *ce;
    long offset;
    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;
    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;
            break;
        case 4: 
            offset +=  SEG_MAP_DELTA_LENGTH;
            break;
        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);
        put_ulong(ce->offset);
    }
    for (ce = new_cmap_tab; ce - new_cmap_tab < NEW_CMAP_SIZE; ce++) {
        switch (ce->format) {
        case 0: 
            ttf_byte_encoding();
            break;
        case 4: 
            ttf_seg_map_delta();
            break;
        case 6: 
            ttf_trimmed_table_map();
            break;
        }
    }
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_dirtab ( void  ) [static]

Definition at line 778 of file writettf.c.

{
    dirtab_entry *tab;
    TTF_ULONG i, k;
    char *p;
    integer save_offset = ttf_offset();
    ttf_seek_outbuf(TABDIR_OFF);
    if (is_subsetted(fm_cur)) {
        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_ulong(tab->checksum);
            put_ulong(tab->offset);
            put_ulong(tab->length);
        }
    }
    else {
        for (tab = dir_tab; tab - dir_tab < ntabs; tab++) {
            for (k = 0; k < 4; k++)
               put_char(tab->tag[k]);
            put_ulong(tab->checksum);
            put_ulong(tab->offset);
            put_ulong(tab->length);
        }
    }
    /* adjust checkSumAdjustment */
    tmp_ulong = 0;
    checksum = 0;
    for (p = fb_array, i = 0; i < save_offset;) {
        tmp_ulong = (tmp_ulong << 8) + *p++;
        i++;
        if (i % 4 == 0) {
            checksum += tmp_ulong;
            tmp_ulong = 0;
        }
    }
    if (i % 4 != 0) {
        pdftex_warn("font length is not a multiple of 4 (%li)", i);
        checksum <<= 8*(4 - i % 4);
    }
    k = 0xB1B0AFBA - checksum;
    ttf_seek_outbuf(checkSumAdjustment_offset);
    put_ulong(k);
    ttf_seek_outbuf(save_offset);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_glyf ( void  ) [static]

Definition at line 827 of file writettf.c.

{
    short *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();
    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);
            if (k < 0) {
                do {
                    flags = copy_ushort();
                    idx = get_ushort();
                    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
                        */
                    }
                    put_ushort(glyph_tab[idx].newindex);
                    if (flags & ARG_1_AND_2_ARE_WORDS)
                        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);
                    else if (flags & WE_HAVE_A_TWO_BY_TWO)
                        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);
        }
    }
    last_glyf_offset = ttf_offset() - new_glyf_offset;
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_head ( ) [static]

Definition at line 941 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_hhea ( void  ) [static]

Definition at line 961 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_htmx ( void  ) [static]

Definition at line 971 of file writettf.c.

{
    short *id;
    dirtab_entry *tab = ttf_seek_tab("hmtx", 0);
    ttf_reset_chksm(tab);
    for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
        put_ufword(glyph_tab[*id].advWidth);
        put_ufword(glyph_tab[*id].lsb);
    }
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_loca ( void  ) [static]

Definition at line 983 of file writettf.c.

{
    short *id;
    dirtab_entry *tab = ttf_seek_tab("loca", 0);
    ttf_reset_chksm(tab);
    loca_format = 0;
    if (last_glyf_offset >= 0x00020000 || (last_glyf_offset & 1))
        loca_format = 1;
    else
        for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
            if (glyph_tab[*id].newoffset & 1) {
                loca_format = 1;
                break;
            }
    if (loca_format != 0) {
        for (id = glyph_index; id - glyph_index < new_glyphs_count; id++)
            put_ulong(glyph_tab[*id].newoffset);
        put_ulong(last_glyf_offset);
    }
    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);
    }
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_mapx ( void  ) [static]

Definition at line 1010 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_name ( void  ) [static]

Definition at line 720 of file writettf.c.

{
    int i, l;
    char *p;
    int new_name_buf_size;
    char *new_name_buf;
    name_record *n;
    dirtab_entry *tab = ttf_name_lookup("name", true);
    if (is_subsetted(fm_cur)) {
        l = 0;
        for (i = 0; i < name_record_num; i++)
            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;
        for (i = 0; i < name_record_num; i++) {
            n = name_tab + i;
            n->new_offset = p - new_name_buf;
            if ((n->name_id == 1 || n->name_id == 3 ||
                 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)))
            {
                l = prepend_subset_tags(i, p);
                p += l;
            }
            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 {
        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);
    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);
    }
    for (p = new_name_buf; p - new_name_buf < new_name_buf_size; p++)
         put_char(*p);
    ttf_set_chksm(tab);
    if (new_name_buf != name_buf)
        xfree(new_name_buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_OS2 ( void  ) [static]

Definition at line 1020 of file writettf.c.

{
    dirtab_entry *tab = ttf_seek_tab("OS/2", 0);
    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) */
    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 */
    put_ulong(0x00000000);
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void ttf_write_post ( void  ) [static]

Definition at line 1055 of file writettf.c.

{
    dirtab_entry *tab = ttf_seek_tab("post", TTF_FIXED_SIZE);
    glyph_entry *glyph;
    char *s;
    short *id;
    int l;
    ttf_reset_chksm(tab);
    if (!write_ttf_glyph_names || post_format == 0x00030000) {
        put_fixed(0x00030000);
        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);
        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);
        }
        for (id = glyph_index; id - glyph_index < new_glyphs_count; id++) {
            glyph = glyph_tab + *id;
            if (glyph->name_index >= NMACGLYPHS) {
                s = glyph->name;
                l = strlen(s);
                put_byte(l);
                while (l-- > 0)
                    put_char(*s++);
            }
        }
    }
    ttf_set_chksm(tab);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static boolean unsafe_name ( char *  s) [static]

Definition at line 1046 of file writettf.c.

{
    const char **p;
    for (p = ambiguous_names; *p != NULL; p++)
        if (strcmp(s, *p) == 0)
            return true;
    return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1198 of file writettf.c.

{
    dirtab_entry *tab;
    long i;
    set_cur_file_name(fm_cur->ff_name);
    if (!open_input(&ttf_file, kpse_type1_format, FOPEN_RBIN_MODE)) {
        pdftex_fail("cannot open OpenType font file for reading");
    }
    cur_file_name = (char*)nameoffile + 1;
    tex_printf("<<%s", cur_file_name);
    fontfile_found = true;
    dir_tab = NULL;
    glyph_tab = NULL;
    ttf_read_tabdir();
    /* read font parameters */
    if (ttf_name_lookup("head", false) != NULL)
        ttf_read_head();
    if (ttf_name_lookup("hhea", false) != NULL)
        ttf_read_hhea();
    if (ttf_name_lookup("PCLT", false) != NULL)
        ttf_read_pclt();
    if (ttf_name_lookup("post", false) != NULL)
        ttf_read_post();
    /* copy font file */
    tab = ttf_seek_tab("CFF ", 0);
    for (i = tab->length; i > 0; i--)
        copy_char();
    xfree(dir_tab);
    ttf_close();
    tex_printf(">>");
    cur_file_name = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1142 of file writettf.c.

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

TTF_ULONG checksum [static]

Definition at line 89 of file writettf.c.

Definition at line 92 of file writettf.c.

cmap_entry* cmap_tab [static]

Definition at line 82 of file writettf.c.

dirtab_entry* dir_tab [static]

Definition at line 87 of file writettf.c.

char* fb_array
short* glyph_index [static]

Definition at line 81 of file writettf.c.

char* glyph_name_buf [static]

Definition at line 88 of file writettf.c.

Definition at line 80 of file writettf.c.

Definition at line 75 of file writettf.c.

Definition at line 74 of file writettf.c.

Definition at line 73 of file writettf.c.

char* name_buf [static]

Definition at line 85 of file writettf.c.

int name_buf_size [static]

Definition at line 86 of file writettf.c.

int name_record_num [static]

Definition at line 84 of file writettf.c.

name_record* name_tab [static]

Definition at line 83 of file writettf.c.

Definition at line 82 of file writettf.c.

Definition at line 76 of file writettf.c.

Definition at line 78 of file writettf.c.

const char* newtabnames[] [static]
Initial value:
 {
    "OS/2",
    "PCLT",
    "cmap",
    "cvt ",
    "fpgm",
    "glyf",
    "head",
    "hhea",
    "hmtx",
    "loca",
    "maxp",
    "name",
    "post",
    "prep"
}

Definition at line 105 of file writettf.c.

TTF_USHORT nhmtxs [static]

Definition at line 77 of file writettf.c.

TTF_USHORT ntabs [static]

Definition at line 70 of file writettf.c.

const char perforce_id[] = "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writettf.c#14 $" [static]

Definition at line 26 of file writettf.c.

Definition at line 72 of file writettf.c.

Definition at line 90 of file writettf.c.

TTF_ULONG tmp_ulong [static]

Definition at line 91 of file writettf.c.

FILE* ttf_file [static]

Definition at line 93 of file writettf.c.

Definition at line 99 of file writettf.c.

Definition at line 94 of file writettf.c.

TTF_USHORT unicode_map[0xFFFF] [static]

Definition at line 96 of file writettf.c.

TTF_USHORT upem [static]

Definition at line 71 of file writettf.c.