Back to index

texmacs  1.0.7.15
Defines | Functions | Variables
sfnt.c File Reference
#include <string.h>
#include "system.h"
#include "error.h"
#include "mem.h"
#include "mfileio.h"
#include "sfnt.h"
#include "pdfobj.h"

Go to the source code of this file.

Defines

#define SFNT_TRUETYPE   0x00010000UL
#define SFNT_OPENTYPE   0x00010000UL
#define SFNT_POSTSCRIPT   0x4f54544fUL
#define SFNT_TTC   0x74746366UL

Functions

sfntsfnt_open (FILE *fp)
sfntdfont_open (FILE *fp, int index)
static void release_directory (struct sfnt_table_directory *td)
void sfnt_close (sfnt *sfont)
int put_big_endian (void *s, LONG q, int n)
static void convert_tag (char *tag, unsigned long u_tag)
static unsigned max2floor (unsigned n)
static unsigned log2floor (unsigned n)
static ULONG sfnt_calc_checksum (void *data, ULONG length)
static int find_table_index (struct sfnt_table_directory *td, const char *tag)
void sfnt_set_table (sfnt *sfont, const char *tag, void *data, ULONG length)
ULONG sfnt_find_table_len (sfnt *sfont, const char *tag)
ULONG sfnt_find_table_pos (sfnt *sfont, const char *tag)
ULONG sfnt_locate_table (sfnt *sfont, const char *tag)
int sfnt_read_table_directory (sfnt *sfont, ULONG offset)
int sfnt_require_table (sfnt *sfont, const char *tag, int must_exist)
pdf_objsfnt_create_FontFile_stream (sfnt *sfont)

Variables

static unsigned char wbuf [1024]
static unsigned char padbytes [4] = {0, 0, 0, 0}

Define Documentation

#define SFNT_OPENTYPE   0x00010000UL
#define SFNT_POSTSCRIPT   0x4f54544fUL
#define SFNT_TRUETYPE   0x00010000UL
#define SFNT_TTC   0x74746366UL

Function Documentation

static void convert_tag ( char *  tag,
unsigned long  u_tag 
) [static]

Definition at line 197 of file sfnt.c.

{
  int i;

  for (i = 3; i >= 0; i--) {
    tag[i] = (char) (u_tag % 256);
    u_tag /= 256;
  }

  return;
}

Here is the caller graph for this function:

sfnt* dfont_open ( FILE *  fp,
int  index 
)

Definition at line 88 of file sfnt.c.

{
  sfnt  *sfont;
  ULONG  rdata_pos, map_pos, tags_pos, types_pos, res_pos, tag;
  USHORT tags_num, types_num, i;

  ASSERT(fp);

  rewind(fp);

  sfont = NEW(1, sfnt);

  sfont->stream = fp;

  rdata_pos = sfnt_get_ulong(sfont);
  map_pos   = sfnt_get_ulong(sfont);
  sfnt_seek_set(sfont, map_pos + 0x18);
  tags_pos = map_pos + sfnt_get_ushort(sfont);
  sfnt_seek_set(sfont, tags_pos);
  tags_num = sfnt_get_ushort(sfont);

  for (i = 0; i <= tags_num; i++) {
    tag = sfnt_get_ulong(sfont); /* tag name */
    types_num = sfnt_get_ushort(sfont); /* typefaces number */
    types_pos = tags_pos + sfnt_get_ushort(sfont); /* typefaces position */
    if (tag == 0x73666e74UL) /* "sfnt" */
      break;
  }

  if (i > tags_num) {
    RELEASE(sfont);
    return NULL;
  }

  sfnt_seek_set(sfont, types_pos);
  if (index > types_num) {
    ERROR("Invalid index %d for dfont.", index);
  }

  for (i = 0; i <= types_num; i++) {
    (void) sfnt_get_ushort(sfont); /* resource id */
    (void) sfnt_get_ushort(sfont); /* resource name position from name_list */
    res_pos = sfnt_get_ulong(sfont);   /* resource flag (byte) + resource offset */
    sfnt_get_ulong(sfont);  /* mbz */
    if (i == index) break;
  }

  rewind(sfont->stream);

  sfont->type = SFNT_TYPE_DFONT;
  sfont->directory = NULL;
  sfont->offset = (res_pos & 0x00ffffffUL) + rdata_pos + 4;

  return sfont;
}

Here is the caller graph for this function:

static int find_table_index ( struct sfnt_table_directory td,
const char *  tag 
) [static]

Definition at line 260 of file sfnt.c.

{
  int  idx;

  if (!td)
    return -1;

  for (idx = 0; idx < td->num_tables; idx++) {
    if (!memcmp(td->tables[idx].tag, tag, 4))
      return idx;
  }

  return -1;
}

Here is the caller graph for this function:

static unsigned log2floor ( unsigned  n) [static]

Definition at line 229 of file sfnt.c.

{
  unsigned val = 0;

  while (n > 1) {
    n /= 2;
    val++;
  }

  return val;
}

Here is the caller graph for this function:

static unsigned max2floor ( unsigned  n) [static]

Definition at line 213 of file sfnt.c.

{
  int val = 1;

  while (n > 1) {
    n   /= 2;
    val *= 2;
  }

  return val;
}

Here is the caller graph for this function:

int put_big_endian ( void *  s,
LONG  q,
int  n 
)

Definition at line 179 of file sfnt.c.

{
  int   i;
  char *p;

  p = (char *) s;
  for (i = n - 1; i >= 0; i--) {
    p[i] = (char) (q & 0xff);
    q >>= 8;
  }

  return n;
}
static void release_directory ( struct sfnt_table_directory td) [static]

Definition at line 145 of file sfnt.c.

{
  long i;

  if (td) {
    if (td->tables) {
      for (i = 0; i < td->num_tables; i++) {
       if (td->tables[i].data)
         RELEASE(td->tables[i].data);
      }
      RELEASE(td->tables);
    }
    if (td->flags)
      RELEASE(td->flags);
    RELEASE(td);
  }

  return;
}

Here is the caller graph for this function:

static ULONG sfnt_calc_checksum ( void *  data,
ULONG  length 
) [static]

Definition at line 242 of file sfnt.c.

{
  ULONG  chksum = 0;
  BYTE  *p, *endptr;
  int    count  = 0;

  p      = (BYTE *) data;
  endptr = p + length;
  while (p < endptr) {
    chksum += (p[0] << (8 * ( 3 - count)));
    count   = ((count + 1) & 3);
    p++;
  }

  return chksum;
}

Here is the caller graph for this function:

void sfnt_close ( sfnt sfont)

Definition at line 166 of file sfnt.c.

{

  if (sfont) {
    if (sfont->directory)
      release_directory(sfont->directory);
    RELEASE(sfont);
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 435 of file sfnt.c.

{
  pdf_obj *stream;
  pdf_obj *stream_dict;
  struct sfnt_table_directory *td;
  long     offset, nb_read, length;
  int      i, sr;
  char    *p;

  ASSERT(sfont && sfont->directory);

  stream = pdf_new_stream(STREAM_COMPRESS);

  td  = sfont->directory;

  /* Header */
  p  = (char *) wbuf;
  p += sfnt_put_ulong (p, td->version);
  p += sfnt_put_ushort(p, td->num_kept_tables);
  sr = max2floor(td->num_kept_tables) * 16;
  p += sfnt_put_ushort(p, sr);
  p += sfnt_put_ushort(p, log2floor(td->num_kept_tables));
  p += sfnt_put_ushort(p, td->num_kept_tables * 16 - sr);

  pdf_add_stream(stream, wbuf, 12);

  /*
   * Compute start of actual tables (after headers).
   */
  offset = 12 + 16 * td->num_kept_tables;
  for (i = 0; i < td->num_tables; i++) {
    /* This table must exist in FontFile */
    if (td->flags[i] & SFNT_TABLE_REQUIRED) {
      if ((offset % 4) != 0) {
       offset += 4 - (offset % 4);
      }

      p = (char *) wbuf;
      memcpy(p, td->tables[i].tag, 4);
      p += 4;
      p += sfnt_put_ulong(p, td->tables[i].check_sum);
      p += sfnt_put_ulong(p, offset);
      p += sfnt_put_ulong(p, td->tables[i].length);
      pdf_add_stream(stream, wbuf, 16);

      offset += td->tables[i].length;
    }
  }

  offset = 12 + 16 * td->num_kept_tables;
  for (i = 0; i < td->num_tables; i++) {
    if (td->flags[i] & SFNT_TABLE_REQUIRED) {
      if ((offset % 4) != 0) {
       length  = 4 - (offset % 4);
       pdf_add_stream(stream, padbytes, length);
       offset += length;
      }
      if (!td->tables[i].data) {
       if (!sfont->stream) {
         pdf_release_obj(stream);
         ERROR("Font file not opened or already closed...");
         return NULL;
       }

       length = td->tables[i].length;
       sfnt_seek_set(sfont, td->tables[i].offset); 
       while (length > 0) {
         nb_read = sfnt_read(wbuf, MIN(length, 1024), sfont);
         if (nb_read < 0) {
           pdf_release_obj(stream);
           ERROR("Reading file failed...");
           return NULL;
         } else if (nb_read > 0) {
           pdf_add_stream(stream, wbuf, nb_read);
         }
         length -= nb_read;
       }
      } else {
       pdf_add_stream(stream,
                     td->tables[i].data, td->tables[i].length);
       RELEASE(td->tables[i].data);
       td->tables[i].data = NULL;
      }
      /* Set offset for next table */
      offset += td->tables[i].length;
    }
  }

  stream_dict = pdf_stream_dict(stream);
  pdf_add_dict(stream_dict,
              pdf_new_name("Length1"),
              pdf_new_number(offset));

  return stream;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ULONG sfnt_find_table_len ( sfnt sfont,
const char *  tag 
)

Definition at line 302 of file sfnt.c.

{
  ULONG  length;
  struct sfnt_table_directory *td;
  int    idx;

  ASSERT(sfont && tag);

  td  = sfont->directory;
  idx = find_table_index(td, tag);
  if (idx < 0)
    length = 0;
  else {
    length = td->tables[idx].length;
  }

  return length;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ULONG sfnt_find_table_pos ( sfnt sfont,
const char *  tag 
)

Definition at line 322 of file sfnt.c.

{
  ULONG  offset;
  struct sfnt_table_directory *td;
  int    idx;

  ASSERT(sfont && tag);

  td  = sfont->directory;
  idx = find_table_index(td, tag);
  if (idx < 0)
    offset = 0;
  else {
    offset = td->tables[idx].offset;
  }

  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ULONG sfnt_locate_table ( sfnt sfont,
const char *  tag 
)

Definition at line 342 of file sfnt.c.

{
  ULONG offset;

  ASSERT(sfont && tag);

  offset = sfnt_find_table_pos(sfont, tag);
  if (offset == 0)
    ERROR("sfnt: table not found...");

  sfnt_seek_set(sfont, offset);

  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

sfnt* sfnt_open ( FILE *  fp)

Definition at line 41 of file sfnt.c.

{
  sfnt  *sfont;
  ULONG  type;

  ASSERT(fp);

  rewind(fp);

  sfont = NEW(1, sfnt);

  sfont->stream = fp;

/*
 * type:
 *  `true' (0x74727565): TrueType (Mac)
 *  `typ1' (0x74797031) (Mac): PostScript font housed in a sfnt wrapper
 *  0x00010000: TrueType (Win)/OpenType
 *  `OTTO': PostScript CFF font with OpenType wrapper
 *  `ttcf': TrueType Collection
*/
#define SFNT_TRUETYPE   0x00010000UL
#define SFNT_OPENTYPE   0x00010000UL
#define SFNT_POSTSCRIPT 0x4f54544fUL
#define SFNT_TTC        0x74746366UL

  type = sfnt_get_ulong(sfont);

  if (type == SFNT_TRUETYPE) {
    sfont->type = SFNT_TYPE_TRUETYPE;
  } else if (type == SFNT_OPENTYPE) {
    sfont->type = SFNT_TYPE_OPENTYPE;
  } else if (type == SFNT_POSTSCRIPT) { 
    sfont->type = SFNT_TYPE_POSTSCRIPT;
  } else if (type == SFNT_TTC) {
    sfont->type = SFNT_TYPE_TTC;
  }

  rewind(sfont->stream);

  sfont->directory = NULL;
  sfont->offset = 0UL;

  return sfont;
}

Here is the caller graph for this function:

int sfnt_read_table_directory ( sfnt sfont,
ULONG  offset 
)

Definition at line 358 of file sfnt.c.

{
  struct sfnt_table_directory *td;
  unsigned long i, u_tag;

  ASSERT(sfont && sfont->stream);

  sfnt_seek_set(sfont, offset);

  if (sfont->directory)
    release_directory(sfont->directory);    

  sfont->directory = td = NEW (1, struct sfnt_table_directory);

  td->version      = sfnt_get_ulong(sfont);
  td->num_tables   = sfnt_get_ushort(sfont);
  td->search_range = sfnt_get_ushort(sfont);
  td->entry_selector = sfnt_get_ushort(sfont);
  td->range_shift    = sfnt_get_ushort(sfont);

  td->flags  = NEW(td->num_tables, char);
  td->tables = NEW(td->num_tables, struct sfnt_table);

  for (i = 0; i < td->num_tables; i++) {
    u_tag = sfnt_get_ulong(sfont);

    convert_tag(td->tables[i].tag, u_tag);
    td->tables[i].check_sum = sfnt_get_ulong(sfont);
    td->tables[i].offset    = sfnt_get_ulong(sfont) + sfont->offset;
    td->tables[i].length    = sfnt_get_ulong(sfont);
    td->tables[i].data      = NULL;
//fprintf(stderr, "[%4s:%x]", td->tables[i].tag, td->tables[i].offset);

    td->flags[i] = 0;
  }
  td->num_kept_tables = 0;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int sfnt_require_table ( sfnt sfont,
const char *  tag,
int  must_exist 
)

Definition at line 399 of file sfnt.c.

{
  struct sfnt_table_directory *td;
  int    idx;

  ASSERT(sfont && sfont->directory);

  td  = sfont->directory;
  idx = find_table_index(td, tag);
  if (idx < 0) {
    if (must_exist)
      return -1;
  } else {
    td->flags[idx] |= SFNT_TABLE_REQUIRED;
    td->num_kept_tables++;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sfnt_set_table ( sfnt sfont,
const char *  tag,
void *  data,
ULONG  length 
)

Definition at line 276 of file sfnt.c.

{
  struct sfnt_table_directory *td;
  int    idx;

  ASSERT(sfont);

  td  = sfont->directory;
  idx = find_table_index(td, tag);

  if (idx < 0) {
    idx = td->num_tables;
    td->num_tables++;
    td->tables = RENEW(td->tables, td->num_tables, struct sfnt_table);
    memcpy(td->tables[idx].tag, tag, 4);
  }

  td->tables[idx].check_sum = sfnt_calc_checksum(data, length);
  td->tables[idx].offset    = 0L;
  td->tables[idx].length    = length;
  td->tables[idx].data      = data;

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

unsigned char padbytes[4] = {0, 0, 0, 0} [static]

Definition at line 432 of file sfnt.c.

unsigned char wbuf[1024] [static]

Definition at line 432 of file sfnt.c.