Back to index

texmacs  1.0.7.15
Classes | Defines | Functions | Variables
subfont.c File Reference
#include <errno.h>
#include "system.h"
#include "mem.h"
#include "error.h"
#include "dpxfile.h"
#include "subfont.h"

Go to the source code of this file.

Classes

struct  sfd_file_
struct  sfd_rec_

Defines

#define LINE_BUF_SIZE   4096
#define clear_vector(v)
#define IS_TOKSEP(c)   ((c) == '\0' || isspace((c)))

Functions

void subfont_set_verbose (void)
static void init_sfd_file_ (struct sfd_file_ *sfd)
static void clean_sfd_file_ (struct sfd_file_ *sfd)
static char * readline (char *buf, int buf_len, FILE *fp)
static int read_sfd_record (struct sfd_rec_ *rec, const char *lbuf)
static int scan_sfd_file (struct sfd_file_ *sfd, FILE *fp)
static int find_sfd_file (const char *sfd_name)
char ** sfd_get_subfont_ids (const char *sfd_name, int *num_ids)
int sfd_load_record (const char *sfd_name, const char *subfont_id)
unsigned short lookup_sfd_record (int rec_id, unsigned char c)
void release_sfd_record (void)

Variables

static int verbose = 0
static struct sfd_file_sfd_files = NULL
static int num_sfd_files = 0
static int max_sfd_files = 0
static struct sfd_rec_sfd_record = NULL
static int num_sfd_records = 0
static int max_sfd_records = 0
static char line_buf [LINE_BUF_SIZE]

Class Documentation

struct sfd_file_

Definition at line 56 of file subfont.c.

Class Members
char * ident
int max_subfonts
int num_subfonts
int * rec_id
char ** sub_id
struct sfd_rec_

Definition at line 68 of file subfont.c.

Class Members
unsigned short vector

Define Documentation

#define clear_vector (   v)
Value:
if ((v)) { \
  int __i; \
  for (__i = 0; __i < 256; __i++) \
    (v)[__i] = 0; \
}

Definition at line 154 of file subfont.c.

#define IS_TOKSEP (   c)    ((c) == '\0' || isspace((c)))
#define LINE_BUF_SIZE   4096

Definition at line 113 of file subfont.c.


Function Documentation

static void clean_sfd_file_ ( struct sfd_file_ sfd) [static]

Definition at line 84 of file subfont.c.

{
  int  i;
  if (sfd->ident)
    RELEASE(sfd->ident);
  if (sfd->sub_id) {
    for (i = 0; i < sfd->num_subfonts; i++) {
      if (sfd->sub_id[i])
        RELEASE(sfd->sub_id[i]);
    }
    RELEASE(sfd->sub_id);
  }
  if (sfd->rec_id)
    RELEASE(sfd->rec_id);
  init_sfd_file_(sfd);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int find_sfd_file ( const char *  sfd_name) [static]

Definition at line 296 of file subfont.c.

{
  int    id = -1;
  int    i, error = -1;

  /* Check if we already opened SFD file */
  for (i = 0; i < num_sfd_files; i++) {
    if (!strcmp(sfd_files[i].ident, sfd_name)) {
      id = i;
      break;
    }
  }

  if (id < 0) {
    struct sfd_file_ *sfd = NULL;
    FILE  *fp;

    if (num_sfd_files >= max_sfd_files) {
      max_sfd_files += 8;
      sfd_files = RENEW(sfd_files, max_sfd_files, struct sfd_file_);
    }
    sfd = &sfd_files[num_sfd_files];
    init_sfd_file_(sfd);
    sfd->ident = NEW(strlen(sfd_name) + 1, char);
    strcpy(sfd->ident, sfd_name);
    fp = DPXFOPEN(sfd->ident, DPX_RES_TYPE_SFD);
    if (!fp) {
      clean_sfd_file_(sfd);
      return  -1;
    }
    error = scan_sfd_file(sfd, fp);
    DPXFCLOSE(fp);
    if (!error)
      id = num_sfd_files++;
    else {
      WARN("Error occured while reading SFD file \"%s\"", sfd_name);
      clean_sfd_file_(sfd);
      id = -1;
    }
  }

  return  id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_sfd_file_ ( struct sfd_file_ sfd) [static]

Definition at line 75 of file subfont.c.

{
  sfd->ident  = NULL;
  sfd->sub_id = NULL;
  sfd->rec_id = NULL;
  sfd->max_subfonts = sfd->num_subfonts = 0;
}

Here is the caller graph for this function:

unsigned short lookup_sfd_record ( int  rec_id,
unsigned char  c 
)

Definition at line 451 of file subfont.c.

{
  if (!sfd_record ||
       rec_id < 0 || rec_id >= num_sfd_records)
    ERROR("Invalid subfont_id: %d", rec_id);
  return sfd_record[rec_id].vector[c];
}
static int read_sfd_record ( struct sfd_rec_ rec,
const char *  lbuf 
) [static]

Definition at line 169 of file subfont.c.

{
  char  *p = (char *) lbuf, *q;
  int    repos  = 0;
  long   c,  v1 = 0, v2 = 0;
  int    curpos = 0;
  int    error  = 0;

#define IS_TOKSEP(c) ((c) == '\0' || isspace((c)))
  for ( ; *p && isspace(*p); p++);
  while (!error && *p) {
    repos = 0; q = p;
    v1    = strtol(p, &q, 0);
    if (q == p ||
        (!IS_TOKSEP(*q) && *q != ':' && *q != '_')) {
      WARN("Unknown token in subfont mapping table: %c", *q);
      return  -1;
    }

    switch (*q) {
    case  ':':
      if (v1 < 0 || v1 > 0xff) {
        WARN("Invalud value for subfont table offset: %ld", v1);
        return  -1;
      }
      repos = 1;
      q++;
      break;
    case  '_':
      p  = q + 1;
      v2 = strtol(p, &q, 0);
      if (v1 < 0 || v1 > 0xffffL ||
          v2 < 0 || v2 > 0xffffL) {
        WARN("Invalid value in subfont mapping table: 0x%x_0x%x", v1, v2);
        return -1;
      } else if (q == p || !IS_TOKSEP(*q)) {
        WARN("Invalid char in subfont mapping table: %c", *q);
        return  -1;
      }
      break;
    default:
      if (v1 < 0 || v1 > 0xffffL) {
        WARN("Invalid character code in subfont mapping table: 0x%x", v1);
        return -1;
      }
      v2 = v1;
      break;
    }

    if (repos)
      curpos = v1;
    else {
      if (v2 < v1 || curpos + (v2 - v1) > 0xff) {
        WARN("Invalid range in subfont mapping: curpos=\"0x%02x\" range=\"0x%04x,0x%04x\"",
             curpos, v1, v2);
        return  -1;
      }
      for (c = v1; c <= v2; c++) {
        if (rec->vector[curpos] != 0) {
          WARN("Subfont mapping for slot=\"0x%02x\" already defined...", curpos);
          return  -1;
        }
        ASSERT( curpos >= 0 && curpos <= 255 );
        rec->vector[curpos++] = (unsigned short) c;
      }
    }
    for (p = q; *p && isspace(*p); p++);
  }

  return  error;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* readline ( char *  buf,
int  buf_len,
FILE *  fp 
) [static]

Definition at line 122 of file subfont.c.

{
  char  *r, *q, *p = buf;
  int    n = 0, c = 0;

  while (buf_len - n > 0 && (q = mfgets(p, buf_len - n, fp))) {
    c++;
    r = strchr(q, '#');
    /* Comment is converted to single wsp (followed by a newline). */
    if (r) {
      *r = ' ';
      *(r + 1) = '\0';
    }
    if (strlen(q) == 0)
      break; /* empty line */
    n += strlen(q);
    q += strlen(q) - 1;
    if (*q != '\\')
      break;
    else { /* line continued */
      n -= 1;
      p  = buf + n;
    }
  }
  if (n >= buf_len - 1) {
    WARN("Possible buffer overflow in reading SFD file (buffer full, size=%d bytes)",
         buf_len - 1);
  }

  return  (c > 0 ? buf : NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void release_sfd_record ( void  )

Definition at line 460 of file subfont.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static int scan_sfd_file ( struct sfd_file_ sfd,
FILE *  fp 
) [static]

Definition at line 243 of file subfont.c.

{
  char  *id;
  char  *q, *p;
  int    n, lpos = 0;

  ASSERT( sfd && fp );

  if (verbose > 3) {
    MESG("\nsubfont>> Scanning SFD file \"%s\"...\n", sfd->ident);
  }

  rewind(fp);
  sfd->max_subfonts = sfd->num_subfonts = 0;
  while ((p = readline(line_buf, LINE_BUF_SIZE, fp)) != NULL) {
    lpos++;
    for ( ; *p && isspace(*p); p++);
    if (*p == 0)
      continue; /* empty */

    /* Saw non-wsp here */
    for (n = 0, q = p; *p && !isspace(*p); p++, n++);
    id = NEW(n + 1, char);
    memcpy(id, q, n); id[n] = '\0';
    if (sfd->num_subfonts >= sfd->max_subfonts) {
      sfd->max_subfonts += 16;
      sfd->sub_id = RENEW(sfd->sub_id, sfd->max_subfonts, char *);
    }

    if (verbose > 3) {
      MESG("subfont>>   id=\"%s\" at line=\"%d\"\n", id, lpos);
    }
    sfd->sub_id[sfd->num_subfonts] = id;
    sfd->num_subfonts++;
  }

  sfd->rec_id = NEW(sfd->num_subfonts, int);
  for (n = 0; n < sfd->num_subfonts; n++) {
    sfd->rec_id[n] = -1; /* Not loaded yet. We do lazy loading of map definitions. */
  }

  if (verbose > 3) {
    MESG("subfont>> %d entries found in SFD file \"%s\".\n", sfd->num_subfonts, sfd->ident);
  }

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char** sfd_get_subfont_ids ( const char *  sfd_name,
int *  num_ids 
)

Definition at line 341 of file subfont.c.

{
  int  sfd_id;

  if (!sfd_name)
    return  NULL;

  sfd_id = find_sfd_file(sfd_name);
  if (sfd_id < 0)
    return  NULL;

  if (num_ids)
    *num_ids = sfd_files[sfd_id].num_subfonts;
  return  sfd_files[sfd_id].sub_id;
}

Here is the call graph for this function:

int sfd_load_record ( const char *  sfd_name,
const char *  subfont_id 
)

Definition at line 361 of file subfont.c.

{
  int               rec_id = -1;
  struct sfd_file_ *sfd;
  FILE             *fp;
  int               sfd_id, i, error = 0;
  char             *p, *q;

  if (!sfd_name || !subfont_id)
    return  -1;

  sfd_id = find_sfd_file(sfd_name);
  if (sfd_id < 0)
    return  -1;

  sfd = &sfd_files[sfd_id];
  /* Check if we already loaded mapping table. */
  for (i = 0;
       i < sfd->num_subfonts && strcmp(sfd->sub_id[i], subfont_id); i++);
  if (i == sfd->num_subfonts) {
    WARN("Subfont id=\"%s\" not exist in SFD file \"%s\"...",
         subfont_id, sfd->ident);
    return  -1;
  } else if (sfd->rec_id[i] >= 0) {
    return  sfd->rec_id[i];
  }

  if (verbose > 3) {
    MESG("\nsubfont>> Loading SFD mapping table for <%s,%s>...",
         sfd->ident, subfont_id);
  }

  /* reopen */
  fp = DPXFOPEN(sfd->ident, DPX_RES_TYPE_SFD);
  if (!fp) {
    return  -1;
    /* ERROR("Could not open SFD file \"%s\"", sfd_name); */
  }

  /* Seek to record for 'sub_name'. */
  while ((p = readline(line_buf, LINE_BUF_SIZE, fp))) {
    for ( ; *p && isspace(*p); p++);
    if (*p == 0)
      continue; /* empty line */

    /* q = parse_ident(&p, p + strlen(p)); */
    for (q = p; *p && !isspace(*p); p++);
    *p = '\0'; p++;
    if (!strcmp(q, subfont_id)) {
      if (num_sfd_records >= max_sfd_records) {
        max_sfd_records += 16;
        sfd_record = RENEW(sfd_record, max_sfd_records, struct sfd_rec_);
      }
      clear_vector(sfd_record[num_sfd_records].vector);
      error = read_sfd_record(&sfd_record[num_sfd_records], p);
      if (error)
        WARN("Error occured while reading SFD file: file=\"%s\" subfont_id=\"%s\"",
             sfd->ident, subfont_id);
      else {
        rec_id = num_sfd_records++;
      }
    }
  }
  if (rec_id < 0) {
    WARN("Failed to load subfont mapping table for SFD=\"%s\" subfont_id=\"%s\"",
         sfd->ident, subfont_id);
  }
  sfd->rec_id[i] = rec_id;
  DPXFCLOSE(fp);

  if (verbose > 3) {
    int __i;
    if (rec_id >= 0) {
      MESG(" at id=\"%d\"", rec_id);
      MESG("\nsubfont>> Content of mapping table:");
      for (__i = 0; __i < 256; __i++) {
        if (__i % 16 == 0)
          MESG("\nsubfont>>  ");
        MESG(" %04x", sfd_record[rec_id].vector[__i]);
      }
    }
    MESG("\n");
  }

  return  rec_id;
}

Here is the call graph for this function:

void subfont_set_verbose ( void  )

Definition at line 38 of file subfont.c.

{
  verbose++;
}

Variable Documentation

char line_buf[LINE_BUF_SIZE] [static]

Definition at line 114 of file subfont.c.

int max_sfd_files = 0 [static]

Definition at line 102 of file subfont.c.

int max_sfd_records = 0 [static]

Definition at line 105 of file subfont.c.

int num_sfd_files = 0 [static]

Definition at line 102 of file subfont.c.

int num_sfd_records = 0 [static]

Definition at line 105 of file subfont.c.

struct sfd_file_* sfd_files = NULL [static]

Definition at line 101 of file subfont.c.

struct sfd_rec_* sfd_record = NULL [static]

Definition at line 104 of file subfont.c.

int verbose = 0 [static]

Definition at line 36 of file subfont.c.