Back to index

texmacs  1.0.7.15
Classes | Defines | Functions
tt_cmap.h File Reference
#include "sfnt.h"
#include "pdfobj.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  tt_cmap

Defines

#define TT_MAC   1u
#define TT_WIN   3u
#define TT_WIN_SYMBOL   0u
#define TT_WIN_UNICODE   1u
#define TT_WIN_SJIS   2u
#define TT_WIN_RPC   3u
#define TT_WIN_BIG5   4u
#define TT_WIN_WANSUNG   5u
#define TT_WIN_JOHAB   6u
#define TT_WIN_UCS4   10u
#define TT_MAC_ROMAN   0u
#define TT_MAC_JAPANESE   1u
#define TT_MAC_TRADITIONAL_CHINESE   2u
#define TT_MAC_KOREAN   3u
#define TT_MAC_SIMPLIFIED_CHINESE   25u

Functions

void otf_cmap_set_verbose (void)
tt_cmaptt_cmap_read (sfnt *sfont, USHORT platform, USHORT encoding)
USHORT tt_cmap_lookup (tt_cmap *cmap, long cc)
void tt_cmap_release (tt_cmap *cmap)
pdf_objotf_create_ToUnicode_stream (const char *map_name, int ttc_index, const char *used_glyphs)
int otf_load_Unicode_CMap (const char *map_name, int ttc_index, const char *otl_opts, int wmode)

Class Documentation

struct tt_cmap

Definition at line 31 of file tt_cmap.h.

Class Members
USHORT encoding
USHORT format
ULONG language
void * map
USHORT platform

Define Documentation

#define TT_MAC   1u

Definition at line 41 of file tt_cmap.h.

#define TT_MAC_JAPANESE   1u

Definition at line 58 of file tt_cmap.h.

#define TT_MAC_KOREAN   3u

Definition at line 60 of file tt_cmap.h.

#define TT_MAC_ROMAN   0u

Definition at line 57 of file tt_cmap.h.

#define TT_MAC_SIMPLIFIED_CHINESE   25u

Definition at line 61 of file tt_cmap.h.

#define TT_MAC_TRADITIONAL_CHINESE   2u

Definition at line 59 of file tt_cmap.h.

#define TT_WIN   3u

Definition at line 42 of file tt_cmap.h.

#define TT_WIN_BIG5   4u

Definition at line 51 of file tt_cmap.h.

#define TT_WIN_JOHAB   6u

Definition at line 53 of file tt_cmap.h.

#define TT_WIN_RPC   3u

Definition at line 50 of file tt_cmap.h.

#define TT_WIN_SJIS   2u

Definition at line 49 of file tt_cmap.h.

#define TT_WIN_SYMBOL   0u

Definition at line 47 of file tt_cmap.h.

#define TT_WIN_UCS4   10u

Definition at line 54 of file tt_cmap.h.

#define TT_WIN_UNICODE   1u

Definition at line 48 of file tt_cmap.h.

#define TT_WIN_WANSUNG   5u

Definition at line 52 of file tt_cmap.h.


Function Documentation

void otf_cmap_set_verbose ( void  )

Definition at line 63 of file tt_cmap.c.

Here is the call graph for this function:

Here is the caller graph for this function:

pdf_obj* otf_create_ToUnicode_stream ( const char *  map_name,
int  ttc_index,
const char *  used_glyphs 
)

Definition at line 1021 of file tt_cmap.c.

{
  pdf_obj    *cmap_ref = NULL;
  long        res_id;
  pdf_obj    *cmap_obj = NULL;
  CMap       *cmap_add;
  int         cmap_add_id;
  tt_cmap    *ttcmap;
  char       *cmap_name;
  FILE       *fp;
  sfnt       *sfont;
  long        offset = 0;


  cmap_name = NEW(strlen(font_name)+strlen("-UTF16")+5, char);
  sprintf(cmap_name, "%s,%03d-UTF16", font_name, ttc_index);

  res_id = pdf_findresource("CMap", cmap_name);
  if (res_id >= 0) {
    RELEASE(cmap_name);
    cmap_ref = pdf_get_resource_reference(res_id);
    return cmap_ref;
  }

  if (verbose > VERBOSE_LEVEL_MIN) {
    MESG("\n");
    MESG("otf_cmap>> Creating ToUnicode CMap for \"%s\"...\n", font_name);
  }

  fp = DPXFOPEN(font_name, DPX_RES_TYPE_TTFONT);
  if (!fp) {
    fp = DPXFOPEN(font_name, DPX_RES_TYPE_OTFONT);
  }

  if (!fp) {
    RELEASE(cmap_name);
    return NULL;
  }

  sfont = sfnt_open(fp);
  if (!sfont) {
    ERROR("Could not open TrueType font file \"%s\"", font_name);
  }

  switch (sfont->type) {
  case SFNT_TYPE_TTC:
    offset = ttc_read_offset(sfont, ttc_index);
    if (offset == 0) {
      ERROR("Invalid TTC index");
    }
    break;
  default:
    offset = 0;
    break;
  }

  if (sfnt_read_table_directory(sfont, offset) < 0) {
    ERROR("Could not read TrueType table directory.");
  }

  cmap_add_id = CMap_cache_find(cmap_name);
  if (cmap_add_id < 0) {
    cmap_add = NULL;
  } else {
    cmap_add = CMap_cache_get(cmap_add_id);
  }

  CMap_set_silent(1); /* many warnings without this... */
  ttcmap = tt_cmap_read(sfont, 3, 10); /* Microsoft UCS4 */
  if (ttcmap &&
      ttcmap->format == 12) {
    WARN("Format 12 cmap table ... untested");
    cmap_obj = create_ToUnicode_cmap12(ttcmap->map,
                                   cmap_name, cmap_add, used_glyphs);
  } else {
    ttcmap = tt_cmap_read(sfont, 3, 1); /* Microsoft UCS2 */
    if (ttcmap &&
       ttcmap->format == 4) {
      cmap_obj = create_ToUnicode_cmap4(ttcmap->map,
                                   cmap_name, cmap_add, used_glyphs);
    } else {
      ttcmap = tt_cmap_read(sfont, 0, 3); /* Unicode 2.0 or later */
      if (ttcmap &&
         ttcmap->format == 4) {
        cmap_obj = create_ToUnicode_cmap4(ttcmap->map,
                                     cmap_name, cmap_add, used_glyphs);
      } else {
        ERROR("Unable to read OpenType/TrueType Unicode cmap table.");
      }
    }
  }
  tt_cmap_release(ttcmap);
  CMap_set_silent(0);

  if (cmap_obj) {
    res_id   = pdf_defineresource("CMap", cmap_name,
                              cmap_obj, PDF_RES_FLUSH_IMMEDIATE);
    cmap_ref = pdf_get_resource_reference(res_id);
  } else {
    cmap_ref = NULL;
  }
  RELEASE(cmap_name);

  sfnt_close(sfont);
  DPXFCLOSE(fp);

  return cmap_ref;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int otf_load_Unicode_CMap ( const char *  map_name,
int  ttc_index,
const char *  otl_opts,
int  wmode 
)

Definition at line 1595 of file tt_cmap.c.

{
  int    cmap_id = -1;
  int    tounicode_id = -1, is_cidfont = 0;
  sfnt  *sfont;
  unsigned long   offset = 0;
  char  *base_name = NULL, *cmap_name = NULL;
  char  *tounicode_name = NULL;
  FILE  *fp;
  otl_gsub      *gsub_list = NULL;
  tt_cmap       *ttcmap;
  CMap          *cmap, *base, *tounicode = NULL;
  CIDSysInfo     csi = {NULL, NULL, 0};
  unsigned char *GIDToCIDMap = NULL;

  if (!map_name)
    return -1;

  if (ttc_index > 999 || ttc_index < 0) {
    return -1; /* Sorry for this... */
  }

  fp = DPXFOPEN(map_name, DPX_RES_TYPE_TTFONT);
  if (!fp) {
    fp = DPXFOPEN(map_name, DPX_RES_TYPE_OTFONT);
  }
  if (!fp) {
    fp = DPXFOPEN(map_name, DPX_RES_TYPE_DFONT);
    if (!fp) return -1;
    sfont = dfont_open(fp, ttc_index);
  } else {
    sfont = sfnt_open(fp);
  }

  if (!sfont) {
    ERROR("Could not open OpenType/TrueType/dfont font file \"%s\"", map_name);
  }
  switch (sfont->type) {
  case SFNT_TYPE_TTC:
    offset = ttc_read_offset(sfont, ttc_index);
    if (offset == 0) {
      ERROR("Invalid TTC index");
    }
    break;
  case SFNT_TYPE_TRUETYPE:
  case SFNT_TYPE_POSTSCRIPT:
    offset = 0;
    break;
  case SFNT_TYPE_DFONT:
    offset = sfont->offset;
    break;
  default:
    ERROR("Not a OpenType/TrueType/TTC font?: %s", map_name);
    break;
  }

  if (sfnt_read_table_directory(sfont, offset) < 0)
    ERROR("Could not read OpenType/TrueType table directory.");

  base_name = NEW(strlen(map_name)+strlen("-UCS4-H")+5, char);
  if (wmode)
    sprintf(base_name, "%s,%03d-UCS4-V", map_name, ttc_index);
  else {
    sprintf(base_name, "%s,%03d-UCS4-H", map_name, ttc_index);
  }

  if (otl_tags) {
    cmap_name = NEW(strlen(map_name)+strlen(otl_tags)+strlen("-UCS4-H")+6, char);
    if (wmode)
      sprintf(cmap_name, "%s,%03d,%s-UCS4-V", map_name, ttc_index, otl_tags);
    else
      sprintf(cmap_name, "%s,%03d,%s-UCS4-H", map_name, ttc_index, otl_tags);
  } else {
    cmap_name = NEW(strlen(base_name)+1, char);
    strcpy(cmap_name, base_name);
  }

  if (sfont->type == SFNT_TYPE_POSTSCRIPT) {
    is_cidfont = handle_CIDFont(sfont, &GIDToCIDMap, &csi);
  } else {
    is_cidfont = 0;
  }

  if (is_cidfont) {
    tounicode_name = NULL;
  } else {
    tounicode_name = NEW(strlen(map_name)+strlen("-UTF16")+5, char);
    sprintf(tounicode_name, "%s,%03d-UTF16", map_name, ttc_index);
  }

  if (verbose > VERBOSE_LEVEL_MIN) {
    MESG("\n");
    MESG("otf_cmap>> Unicode charmap for font=\"%s\" layout=\"%s\"\n",
        map_name, (otl_tags ? otl_tags : "none"));
  }

  cmap_id = CMap_cache_find(cmap_name);
  if (cmap_id >= 0) {
    RELEASE(cmap_name);
    RELEASE(base_name);
    if (GIDToCIDMap)
      RELEASE(GIDToCIDMap);
    if (tounicode_name)
      RELEASE(tounicode_name);

    sfnt_close(sfont);
    DPXFCLOSE(fp);

    if (verbose > VERBOSE_LEVEL_MIN)
      MESG("otf_cmap>> Found at cmap_id=%d.\n", cmap_id);

    return cmap_id;
  }

  ttcmap = tt_cmap_read(sfont, 3, 10); /* Microsoft UCS4 */
  if (!ttcmap) {
    ttcmap = tt_cmap_read(sfont, 3, 1); /* Microsoft UCS2 */
    if (!ttcmap) {
      ttcmap = tt_cmap_read(sfont, 0, 3); /* Unicode 2.0 or later */
      if (!ttcmap) {
        ERROR("Unable to read OpenType/TrueType Unicode cmap table.");
      }
    }
  }
  cmap_id = load_base_CMap(base_name, wmode,
                        (is_cidfont ? &csi : NULL),
                        GIDToCIDMap, ttcmap);
  if (cmap_id < 0)
    ERROR("Failed to read OpenType/TrueType cmap table.");

  if (!otl_tags) {
    RELEASE(cmap_name);
    RELEASE(base_name);
    if (GIDToCIDMap)
      RELEASE(GIDToCIDMap);
    if (tounicode_name)
      RELEASE(tounicode_name);
    if (is_cidfont) {
      if (csi.registry)
       RELEASE(csi.registry);
      if (csi.ordering)
       RELEASE(csi.ordering);
    }
    tt_cmap_release(ttcmap);
    sfnt_close(sfont);
    DPXFCLOSE(fp);

    return cmap_id;
  }

  base = CMap_cache_get(cmap_id);

  cmap = CMap_new();
  CMap_set_name (cmap, cmap_name);
  CMap_set_type (cmap, CMAP_TYPE_CODE_TO_CID);
  CMap_set_wmode(cmap, wmode);
  /* CMap_add_codespacerange(cmap, lrange_min, lrange_max, 4); */
  CMap_set_usecmap(cmap, base);
  CMap_add_cidchar(cmap, lrange_max, 4, 0); /* FIXME */

  if (is_cidfont) {
    CMap_set_CIDSysInfo(cmap, &csi);
    if (csi.registry)
      RELEASE(csi.registry);
    if (csi.ordering)
      RELEASE(csi.ordering);
  } else {
    CMap_set_CIDSysInfo(cmap, &CSI_IDENTITY);
  }

  gsub_list = otl_gsub_new();

  {
    struct ht_table unencoded;
    char    *conf_name, *opt_tag;
    pdf_obj *conf, *opt_conf;

    conf_name = NEW(strlen(otl_tags)+1, char);
    memset (conf_name, 0, strlen(otl_tags)+1);
    opt_tag  = strchr(otl_tags, ':');
    if (opt_tag) {
      opt_tag++;
      strncpy(conf_name, otl_tags,
             strlen(otl_tags) - strlen(opt_tag) - 1);
    } else {
      strcpy(conf_name, otl_tags);
    }

    if (verbose > VERBOSE_LEVEL_MIN) {
      MESG("otf_cmap>> Read layout config. \"%s\"\n", conf_name);
    }

    conf = otl_find_conf(conf_name);
    if (!conf)
      ERROR("Layout file \"%s\" not found...", conf_name);

    load_gsub(conf, gsub_list, sfont);
    if (opt_tag) {
      if (verbose > VERBOSE_LEVEL_MIN) {
       MESG("otf_cmap>> Layout option \"%s\" enabled\n", opt_tag);
      }
      opt_conf = otl_conf_find_opt(conf, opt_tag);
      if (!opt_conf)
       ERROR("There are no option \"%s\" in \"%s\".",
             opt_tag, conf_name);
      load_gsub(opt_conf, gsub_list, sfont);
    }

    ht_init_table(&unencoded, hval_free);

    handle_gsub(conf, ttcmap, gsub_list, &unencoded);
    if (opt_tag) {
      opt_conf = otl_conf_find_opt(conf, opt_tag);
      if (!opt_conf)
       ERROR("There are no option \"%s\" in \"%s\".",
             opt_tag, conf_name);
      handle_gsub(opt_conf, ttcmap, gsub_list, &unencoded);
    }
    if (is_cidfont) {
      tounicode_id = -1;
      tounicode    = NULL;
    } else {
      tounicode_id = CMap_cache_find(tounicode_name);
      if (tounicode_id >= 0)
       tounicode  = CMap_cache_get(tounicode_id);
      else {
       tounicode = CMap_new();
       CMap_set_name (tounicode, tounicode_name);
       CMap_set_type (tounicode, CMAP_TYPE_TO_UNICODE);
       CMap_set_wmode(tounicode, 0);
       CMap_add_codespacerange(tounicode, srange_min, srange_max, 2);
       CMap_set_CIDSysInfo(tounicode, &CSI_UNICODE);
       /* FIXME */
       CMap_add_bfchar(tounicode, srange_min, 2, srange_max, 2);
      }
    }
    create_cmaps(cmap, tounicode, &unencoded, GIDToCIDMap);

    ht_clear_table(&unencoded);
    RELEASE(conf_name);
  }

  cmap_id = CMap_cache_add(cmap);
  if (!is_cidfont && tounicode_id < 0) /* New */
    CMap_cache_add(tounicode);

  tt_cmap_release(ttcmap);
  if (gsub_list)
    otl_gsub_release(gsub_list);

  if (verbose > VERBOSE_LEVEL_MIN) {
    MESG("otf_cmap>> Overwrite CMap \"%s\" by \"%s\" with usecmap\n",
        base_name, cmap_name);
  }

  if (GIDToCIDMap)
    RELEASE(GIDToCIDMap);
  if (base_name)
    RELEASE(base_name);
  if (cmap_name)
    RELEASE(cmap_name);
  if (tounicode_name)
    RELEASE(tounicode_name);

  sfnt_close(sfont);
  DPXFCLOSE(fp);

  return cmap_id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

USHORT tt_cmap_lookup ( tt_cmap cmap,
long  cc 
)

Definition at line 567 of file tt_cmap.c.

{
  USHORT gid = 0;

  ASSERT(cmap);

  if (cc > 0xffffL && cmap->format < 12) {
    WARN("Four bytes charcode not supported in TrueType cmap format 0...6.");
    return 0;
  }

  switch (cmap->format) {
  case 0:
    gid = lookup_cmap0(cmap->map,  (USHORT) cc);
    break;
  case 2:
    gid = lookup_cmap2(cmap->map,  (USHORT) cc);
    break;
  case 4:
    gid = lookup_cmap4(cmap->map,  (USHORT) cc);
    break;
  case 6:
    gid = lookup_cmap6(cmap->map,  (USHORT) cc);
    break;
  case 12:
    gid = lookup_cmap12(cmap->map, (ULONG) cc);
    break;
  default:
    ERROR("Unrecognized TrueType cmap subtable format");
    break;
  }

  return gid;
}

Here is the call graph for this function:

Here is the caller graph for this function:

tt_cmap* tt_cmap_read ( sfnt sfont,
USHORT  platform,
USHORT  encoding 
)

Definition at line 451 of file tt_cmap.c.

{
  tt_cmap *cmap = NULL;
  ULONG    offset, length = 0;
  USHORT   version, p_id, e_id;
  USHORT   i, n_subtabs;

  ASSERT(sfont);

  offset    = sfnt_locate_table(sfont, "cmap");
  version   = sfnt_get_ushort(sfont);
  n_subtabs = sfnt_get_ushort(sfont);

  for (i = 0; i < n_subtabs; i++) {
    p_id = sfnt_get_ushort(sfont);
    e_id = sfnt_get_ushort(sfont);
    if (p_id != platform || e_id != encoding)
      sfnt_get_ulong(sfont);
    else {
      offset += sfnt_get_ulong(sfont);
      break;
    }
  }

  if (i == n_subtabs)
    return NULL;

  cmap = NEW(1, tt_cmap);
  cmap->map      = NULL;
  cmap->platform = platform;
  cmap->encoding = encoding;

  sfnt_seek_set(sfont, offset);
  cmap->format = sfnt_get_ushort(sfont);
  /* Length and version (language) is ULONG for
   * format 8, 10, 12 !
   */
  if (cmap->format <= 6) {
    length         = sfnt_get_ushort(sfont);
    cmap->language = sfnt_get_ushort(sfont); /* language (Mac) */
  } else {
    if (sfnt_get_ushort(sfont) != 0) { /* reverved - 0 */
      WARN("Unrecognized cmap subtable format.");
      tt_cmap_release(cmap);
      return NULL;
    } else {
      length         = sfnt_get_ulong(sfont);
      cmap->language = sfnt_get_ulong(sfont);
    }
  }
  
  switch(cmap->format) {
  case 0:
    cmap->map = read_cmap0(sfont, length);
    break;
  case 2:
    cmap->map = read_cmap2(sfont, length);
    break;
  case 4:
    cmap->map = read_cmap4(sfont, length);
    break;
  case 6:
    cmap->map = read_cmap6(sfont, length);
    break;
  case 12:
    WARN("UCS-4 TrueType cmap table...");
    cmap->map = read_cmap12(sfont, length);
    break;
  default:
    WARN("Unrecognized TrueType cmap format.");
    tt_cmap_release(cmap);
    return NULL;
  }

  if (!cmap->map) {
    tt_cmap_release(cmap);
    cmap = NULL;
  }

  return cmap;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tt_cmap_release ( tt_cmap cmap)

Definition at line 534 of file tt_cmap.c.

{

  if (cmap) {
    if (cmap->map) {
      switch(cmap->format) {
      case 0:
       release_cmap0(cmap->map);
       break;
      case 2:
       release_cmap2(cmap->map);
       break;
      case 4:
       release_cmap4(cmap->map);
       break;
      case 6:
       release_cmap6(cmap->map);
       break;
      case 12:
       release_cmap12(cmap->map);
       break;
      default:
       ERROR("Unrecognized TrueType cmap format.");
      }
    }
    RELEASE(cmap);
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function: