Back to index

texmacs  1.0.7.15
Functions
cidtype0.h File Reference
#include "cid.h"
#include "cid_p.h"
#include "fontmap.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void CIDFont_type0_set_verbose (void)
void CIDFont_type0_set_flags (long flags)
int CIDFont_type0_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt)
void CIDFont_type0_dofont (CIDFont *font)
void CIDFont_type0_release (CIDFont *font)
int t1_load_UnicodeCMap (const char *font_name, const char *otl_tags, int wmode)
int CIDFont_type0_t1open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt)
void CIDFont_type0_t1dofont (CIDFont *font)
int CIDFont_type0_t1copen (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt)
void CIDFont_type0_t1cdofont (CIDFont *font)

Function Documentation

void CIDFont_type0_dofont ( CIDFont font)

Definition at line 466 of file cidtype0.c.

{
  sfnt     *sfont;
  cff_font *cffont;
  FILE     *fp;
  cff_index    *charstrings, *idx;
  cff_charsets *charset = NULL;
  cff_fdselect *fdselect = NULL;
  long   charstring_len, max_len;
  long   destlen = 0;
  long   size, offset = 0;
  card8 *data;
  card16 num_glyphs, gid;
  long   cid, cid_count;
  card16 cs_count, last_cid;
  int    fd, prev_fd, parent_id;
  char  *used_chars;
  unsigned char *CIDToGIDMap = NULL;

  ASSERT(font);

  if (!font->indirect)
    return;

  pdf_add_dict(font->fontdict, 
              pdf_new_name("FontDescriptor"),
              pdf_ref_obj (font->descriptor));

  if (CIDFont_is_BaseFont(font))
    return;
  else if (!CIDFont_get_embedding(font) &&
          (opt_flags & CIDFONT_FORCE_FIXEDPITCH)) {
    /* No metrics needed. */
    pdf_add_dict(font->fontdict,
               pdf_new_name("DW"), pdf_new_number(1000.0));
    return;
  }

  if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
      (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
    ERROR("No parent Type 0 font !");

  used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
  if (!used_chars)
    ERROR("Unexpected error: Font not actually used???");

  fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
  if (!fp)
    ERROR("Could not open OpenType font file: %s", font->ident);
  sfont = sfnt_open(fp);
  if (!sfont)
    ERROR("Could not open OpenType font file: %s", font->ident);

  if (sfnt_read_table_directory(sfont, 0) < 0 ||
      sfont->type != SFNT_TYPE_POSTSCRIPT)
    ERROR("Not a CFF/OpenType font ?");
  offset = sfnt_find_table_pos(sfont, "CFF ");
  if (offset == 0)
    ERROR("Not a CFF/OpenType font ?");

  cffont = cff_open(fp, offset, font->options->index);
  if (!cffont)
    ERROR("Could not open CFF font.");
  if (!(cffont->flag & FONTTYPE_CIDFONT))
    ERROR("Not a CIDFont.");

  if (cff_dict_known(cffont->topdict, "CIDCount")) {
    cid_count = (long) cff_dict_get(cffont->topdict, "CIDCount", 0);
  } else {
    cid_count = CID_MAX + 1;
  }

  cff_read_charsets(cffont);
  CIDToGIDMap = NEW(2*cid_count, unsigned char);
  memset(CIDToGIDMap, 0, 2*cid_count);
  add_to_used_chars2(used_chars, 0); /* .notdef */
  cid = 0; last_cid = 0; num_glyphs = 0;
  for (cid = 0; cid <= CID_MAX; cid++) {
    if (is_used_char2(used_chars, cid)) {
      gid = cff_charsets_lookup(cffont, cid);
      if (cid != 0 && gid == 0) {
       WARN("Glyph for CID %u missing in font \"%s\".", (CID) cid, font->ident);
       used_chars[cid/8] &= ~(1 << (7 - (cid % 8)));
       continue;
      }
      CIDToGIDMap[2*cid]   = (gid >> 8) & 0xff;
      CIDToGIDMap[2*cid+1] = gid & 0xff;
      last_cid = cid;
      num_glyphs++;
    }
  }

  /*
   * DW, W, DW2 and W2:
   * Those values are obtained from OpenType table (not TFM).
   */
  if (opt_flags & CIDFONT_FORCE_FIXEDPITCH) {
    pdf_add_dict(font->fontdict,
               pdf_new_name("DW"), pdf_new_number(1000.0));
  } else {
    add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
                 ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
  }

  if (!CIDFont_get_embedding(font)) {
    RELEASE(CIDToGIDMap);
    cff_close(cffont);
    sfnt_close(sfont);
    DPXFCLOSE(fp);

    return;
  }

  /*
   * Embed font subset.
   */
  cff_read_fdselect(cffont);
  cff_read_fdarray(cffont);
  cff_read_private(cffont);

  cff_read_subrs(cffont);

  offset = (long) cff_dict_get(cffont->topdict, "CharStrings", 0);
  cff_seek_set(cffont, offset);
  idx = cff_get_index_header(cffont);
  /* offset is now absolute offset ... bad */
  offset = ftell(cffont->stream);
  
  if ((cs_count = idx->count) < 2) {
    ERROR("No valid charstring data found.");
  }

  /* New Charsets data */
  charset = NEW(1, cff_charsets);
  charset->format = 0;
  charset->num_entries = 0;
  charset->data.glyphs = NEW(num_glyphs, s_SID);

  /* New FDSelect data */
  fdselect = NEW(1, cff_fdselect);
  fdselect->format = 3;
  fdselect->num_entries = 0;
  fdselect->data.ranges = NEW(num_glyphs, cff_range3);

  /* New CharStrings INDEX */
  charstrings = cff_new_index(num_glyphs+1);
  max_len = 2 * CS_STR_LEN_MAX;
  charstrings->data = NEW(max_len, card8);
  charstring_len = 0;

  /*
   * TODO: Re-assign FD number.
   */
  prev_fd = -1; gid = 0;
  data = NEW(CS_STR_LEN_MAX, card8);
  for (cid = 0; cid <= last_cid; cid++) {
    unsigned short gid_org;

    if (!is_used_char2(used_chars, cid))
      continue;

    gid_org = (CIDToGIDMap[2*cid] << 8)|(CIDToGIDMap[2*cid+1]);
    if ((size = (idx->offset)[gid_org+1] - (idx->offset)[gid_org])
       > CS_STR_LEN_MAX)
      ERROR("Charstring too long: gid=%u", gid_org);
    if (charstring_len + CS_STR_LEN_MAX >= max_len) {
      max_len = charstring_len + 2 * CS_STR_LEN_MAX;
      charstrings->data = RENEW(charstrings->data, max_len, card8);
    }
    (charstrings->offset)[gid] = charstring_len + 1;
    seek_absolute(cffont->stream, offset + (idx->offset)[gid_org] - 1);
    fread(data, 1, size, cffont->stream);
    fd = cff_fdselect_lookup(cffont, gid_org);
    charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
                                    max_len - charstring_len,
                                    data, size,
                                    cffont->gsubr, (cffont->subrs)[fd], 0, 0, NULL);
    if (cid > 0 && gid_org > 0) {
      charset->data.glyphs[charset->num_entries] = cid;
      charset->num_entries += 1;
    }
    if (fd != prev_fd) {
      fdselect->data.ranges[fdselect->num_entries].first = gid;
      fdselect->data.ranges[fdselect->num_entries].fd    = fd;
      fdselect->num_entries += 1;
      prev_fd = fd;
    }
    gid++;
  }
  if (gid != num_glyphs)
    ERROR("Unexpeced error: ?????");
  RELEASE(data);
  cff_release_index(idx);

  RELEASE(CIDToGIDMap);
  
  (charstrings->offset)[num_glyphs] = charstring_len + 1;
  charstrings->count = num_glyphs;
  cffont->num_glyphs    = num_glyphs;
  cffont->cstrings      = charstrings;
  
  /* discard old one, set new data */
  cff_release_charsets(cffont->charsets);
  cffont->charsets = charset;
  cff_release_fdselect(cffont->fdselect);
  cffont->fdselect = fdselect;

  /* no Global subr */
  if (cffont->gsubr)
    cff_release_index(cffont->gsubr);
  cffont->gsubr = cff_new_index(0);

  for (fd = 0; fd < cffont->num_fds; fd++) {
    if (cffont->subrs && cffont->subrs[fd]) {
      cff_release_index(cffont->subrs[fd]);
      cffont->subrs[fd] = NULL;
    }
    if (cffont->private && (cffont->private)[fd]) {
      cff_dict_remove((cffont->private)[fd], "Subrs"); /* no Subrs */
    }
  }

  destlen = write_fontfile(font, cffont);

  cff_close(cffont);
  sfnt_close(sfont);
  DPXFCLOSE(fp);

  if (verbose > 1)
    MESG("[%u/%u glyphs][%ld bytes]", num_glyphs, cs_count, destlen);

  /*
   * CIDSet:
   * Length of CIDSet stream is not clear. Must be 8192 bytes long?
   */
  {
    pdf_obj *cidset;

    cidset = pdf_new_stream(STREAM_COMPRESS);
    pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
    pdf_add_dict(font->descriptor,
               pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
    pdf_release_obj(cidset);
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CIDFont_type0_open ( CIDFont font,
const char *  name,
CIDSysInfo cmap_csi,
cid_opt opt 
)

Definition at line 715 of file cidtype0.c.

{
  CIDSysInfo *csi;
  char       *fontname;
  sfnt       *sfont;
  cff_font   *cffont;
  FILE       *fp;
  unsigned long offset = 0;

  ASSERT(font);

  fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
  if (!fp)
    return -1;

  sfont = sfnt_open(fp);
  if (!sfont) {
    ERROR("Not a CFF/OpenType font?");
  }
  if (sfont->type != SFNT_TYPE_POSTSCRIPT     ||
      sfnt_read_table_directory(sfont, 0) < 0 ||
      (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
    ERROR("Not a CFF/OpenType font?");
  }

  cffont = cff_open(sfont->stream, offset, opt->index);
  if (!cffont) {
    ERROR("Cannot read CFF font data");
  }

  if (!(cffont->flag & FONTTYPE_CIDFONT)) {
    cff_close(cffont);
    sfnt_close(sfont);
    DPXFCLOSE(fp);
    return -1;
  }

  csi = NEW(1, CIDSysInfo);
  csi->registry =
    cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 0));
  csi->ordering =
    cff_get_string(cffont, (s_SID)cff_dict_get(cffont->topdict, "ROS", 1));
  csi->supplement = (int)cff_dict_get(cffont->topdict, "ROS", 2);

  if (cmap_csi) {
    if (strcmp(csi->registry, cmap_csi->registry) != 0 ||
       strcmp(csi->ordering, cmap_csi->ordering) != 0) {
      MESG("\nCharacter collection mismatched:\n");
      MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement);
      MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
      ERROR("Inconsistent CMap specified for this font.");
    }
    if (csi->supplement < cmap_csi->supplement) {
      WARN("CMap have higher supplmement number.");
      WARN("Some characters may not be displayed or printed.");
    }
  }

  {
    char *shortname;

    shortname = cff_get_name(cffont);
    if (!shortname)
      ERROR("No valid FontName found.");
    /*
     * Mangled name requires more 7 bytes.
     * Style requires more 11 bytes.
     */
    fontname = NEW(strlen(shortname)+19, char);
    memset(fontname, 0, strlen(shortname)+19);
    strcpy(fontname, shortname);
    RELEASE(shortname);
  }
  cff_close(cffont);

  if (opt->embed && opt->style != FONT_STYLE_NONE) {
    WARN("Embedding disabled due to style option for %s.", name);
    opt->embed = 0;
  }
  switch (opt->style) {
  case FONT_STYLE_BOLD:
    strcat(fontname, ",Bold");
    break;
  case FONT_STYLE_ITALIC:
    strcat(fontname, ",Italic");
    break;
  case FONT_STYLE_BOLDITALIC:
    strcat(fontname, ",BoldItalic");
    break;
  }

  font->fontname = fontname;
  font->subtype  = CIDFONT_TYPE0;
  font->csi      = csi;

  font->fontdict = pdf_new_dict();
  pdf_add_dict(font->fontdict,
              pdf_new_name("Type"),
              pdf_new_name("Font"));
  pdf_add_dict(font->fontdict,
              pdf_new_name("Subtype"),
              pdf_new_name("CIDFontType0"));

  /* getting font info. from TrueType tables */
  if ((font->descriptor
       = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL)
    ERROR("Could not obtain neccesary font info.");

  if (opt->embed) {
    memmove(fontname + 7, fontname, strlen(fontname) + 1);
    pdf_font_make_uniqueTag(fontname); 
    fontname[6] = '+';
  }

  pdf_add_dict(font->descriptor,
              pdf_new_name("FontName"),
              pdf_new_name(fontname));
  pdf_add_dict(font->fontdict, 
              pdf_new_name("BaseFont"),
              pdf_new_name(fontname));
  {
    pdf_obj *csi_dict = pdf_new_dict();
    pdf_add_dict(csi_dict,
               pdf_new_name("Registry"),
               pdf_new_string(csi->registry, strlen(csi->registry)));
    pdf_add_dict(csi_dict,
               pdf_new_name("Ordering"),
               pdf_new_string(csi->ordering, strlen(csi->ordering)));
    pdf_add_dict(csi_dict,
               pdf_new_name("Supplement"),
               pdf_new_number(csi->supplement));
    pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
  }
  pdf_add_dict(font->fontdict, 
              pdf_new_name("DW"),
              pdf_new_number(1000)); /* not sure */

  sfnt_close(sfont);
  DPXFCLOSE(fp);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CIDFont_type0_release ( CIDFont font)

Definition at line 2037 of file cidtype0.c.

{
  return;
}

Here is the caller graph for this function:

void CIDFont_type0_set_flags ( long  flags)

Definition at line 74 of file cidtype0.c.

{
  opt_flags = flags;
}

Here is the caller graph for this function:

void CIDFont_type0_set_verbose ( void  )

Definition at line 68 of file cidtype0.c.

{
  verbose++;
}

Here is the caller graph for this function:

void CIDFont_type0_t1cdofont ( CIDFont font)

Definition at line 860 of file cidtype0.c.

{
  sfnt      *sfont;
  cff_font  *cffont;
  cff_index *charstrings, *idx;
  long   charstring_len, max_len;
  long   destlen = 0;
  long   size, offset = 0;
  card8 *data;
  card16 num_glyphs, gid, last_cid;
  long   i, cid;
  int    parent_id;
  char  *used_chars;
  double default_width, nominal_width;
  FILE  *fp;

  ASSERT(font);

  if (!font->indirect)
    return;

  pdf_add_dict(font->fontdict, 
              pdf_new_name("FontDescriptor"),
              pdf_ref_obj (font->descriptor));

  if ((parent_id = CIDFont_get_parent_id(font, 0)) < 0 &&
      (parent_id = CIDFont_get_parent_id(font, 1)) < 0)
    ERROR("No parent Type 0 font !");

  used_chars = Type0Font_get_usedchars(Type0Font_cache_get(parent_id));
  if (!used_chars)
    ERROR("Unexpected error: Font not actually used???");

  fp = DPXFOPEN(font->ident, DPX_RES_TYPE_OTFONT);
  if (!fp)
    ERROR("Could not open OpenType font file: %s", font->ident);

  sfont = sfnt_open(fp);
  if (!sfont)
    ERROR("Could not open OpenType font file: %s", font->ident);

  if (sfnt_read_table_directory(sfont, 0) < 0 ||
      sfont->type != SFNT_TYPE_POSTSCRIPT)
    ERROR("Not a CFF/OpenType font ?");
  offset = sfnt_find_table_pos(sfont, "CFF ");
  if (offset == 0)
    ERROR("Not a CFF/OpenType font ?");

  cffont = cff_open(fp, offset, font->options->index);
  if (!cffont)
    ERROR("Could not open CFF font.");
  if (cffont->flag & FONTTYPE_CIDFONT)
    ERROR("This is CIDFont...");

  cff_read_private(cffont);
  cff_read_subrs  (cffont);

  if (cffont->private[0] && cff_dict_known(cffont->private[0], "StdVW")) {
    double stemv;
    stemv = cff_dict_get(cffont->private[0], "StdVW", 0);
    pdf_add_dict(font->descriptor,
               pdf_new_name("StemV"), pdf_new_number(stemv));
  }
  if (cffont->private[0] && cff_dict_known(cffont->private[0], "defaultWidthX")) {
    default_width = (double) cff_dict_get(cffont->private[0], "defaultWidthX", 0);
  } else {
    default_width = CFF_DEFAULTWIDTHX_DEFAULT;
  }
  if (cffont->private[0] && cff_dict_known(cffont->private[0], "nominalWidthX")) {
    nominal_width = (double) cff_dict_get(cffont->private[0], "nominalWidthX", 0);
  } else {
    nominal_width = CFF_NOMINALWIDTHX_DEFAULT;
  }

  num_glyphs = 0; last_cid = 0;
  add_to_used_chars2(used_chars, 0); /* .notdef */
  for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
    int c, j;

    c = used_chars[i];
    for (j = 7; j >= 0; j--) {
      if (c & (1 << j)) {
       num_glyphs++;
       last_cid = (i + 1) * 8 - j - 1;
      }
    }
  }

  {
    cff_fdselect *fdselect;

    fdselect = NEW(1, cff_fdselect);
    fdselect->format = 3;
    fdselect->num_entries = 1;
    fdselect->data.ranges = NEW(1, cff_range3);
    fdselect->data.ranges[0].first = 0;
    fdselect->data.ranges[0].fd    = 0;
    cffont->fdselect = fdselect;
  }

  {
    cff_charsets *charset;

    charset  = NEW(1, cff_charsets);
    charset->format = 0;
    charset->num_entries = num_glyphs-1;
    charset->data.glyphs = NEW(num_glyphs-1, s_SID);

    for (gid = 0, cid = 0; cid <= last_cid; cid++) {
      if (is_used_char2(used_chars, cid)) {
       if (gid > 0)
         charset->data.glyphs[gid-1] = cid;
       gid++;
      }
    }
    /* cff_release_charsets(cffont->charsets); */
    cffont->charsets = charset;
  }

  cff_dict_add(cffont->topdict, "CIDCount", 1);
  cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);

  cffont->fdarray    = NEW(1, cff_dict *);
  cffont->fdarray[0] = cff_new_dict();
  cff_dict_add(cffont->fdarray[0], "FontName", 1);
  cff_dict_set(cffont->fdarray[0], "FontName", 0,
              (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
  cff_dict_add(cffont->fdarray[0], "Private", 2);
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
  /* FDArray  - index offset, not known yet */
  cff_dict_add(cffont->topdict, "FDArray", 1);
  cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
  /* FDSelect - offset, not known yet */
  cff_dict_add(cffont->topdict, "FDSelect", 1);
  cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);

  cff_dict_remove(cffont->topdict, "UniqueID");
  cff_dict_remove(cffont->topdict, "XUID");
  cff_dict_remove(cffont->topdict, "Private");
  cff_dict_remove(cffont->topdict, "Encoding");


  /* */
  offset = (long) cff_dict_get(cffont->topdict, "CharStrings", 0);
  cff_seek_set(cffont, offset);
  idx = cff_get_index_header(cffont);
  /* offset is now absolute offset ... bad */
  offset = ftell(cffont->stream);

  if (idx->count < 2)
    ERROR("No valid charstring data found.");

  /* New CharStrings INDEX */
  charstrings = cff_new_index(num_glyphs+1);
  max_len = 2 * CS_STR_LEN_MAX;
  charstrings->data = NEW(max_len, card8);
  charstring_len = 0;

  gid  = 0;
  data = NEW(CS_STR_LEN_MAX, card8);
  for (cid = 0; cid <= last_cid; cid++) {
    if (!is_used_char2(used_chars, cid))
      continue;

    if ((size = (idx->offset)[cid+1] - (idx->offset)[cid])
       > CS_STR_LEN_MAX)
      ERROR("Charstring too long: gid=%u", cid);
    if (charstring_len + CS_STR_LEN_MAX >= max_len) {
      max_len = charstring_len + 2 * CS_STR_LEN_MAX;
      charstrings->data = RENEW(charstrings->data, max_len, card8);
    }
    (charstrings->offset)[gid] = charstring_len + 1;
    seek_absolute(cffont->stream, offset + (idx->offset)[cid] - 1);
    fread(data, 1, size, cffont->stream);
    charstring_len += cs_copy_charstring(charstrings->data + charstring_len,
                                    max_len - charstring_len,
                                    data, size,
                                    cffont->gsubr, (cffont->subrs)[0],
                                    default_width, nominal_width, NULL);
    gid++;
  }
  if (gid != num_glyphs)
    ERROR("Unexpeced error: ?????");
  RELEASE(data);
  cff_release_index(idx);

  (charstrings->offset)[num_glyphs] = charstring_len + 1;
  charstrings->count = num_glyphs;
  cffont->num_glyphs    = num_glyphs;
  cffont->cstrings      = charstrings;
  
  /* no Global subr */
  if (cffont->gsubr)
    cff_release_index(cffont->gsubr);
  cffont->gsubr = cff_new_index(0);

  if (cffont->subrs && cffont->subrs[0]) {
    cff_release_index(cffont->subrs[0]);
    cffont->subrs[0] = NULL;
  }
  if (cffont->private && (cffont->private)[0]) {
    cff_dict_remove((cffont->private)[0], "Subrs"); /* no Subrs */
  }

  cff_add_string(cffont, "Adobe", 1);
  cff_add_string(cffont, "Identity", 1);

  cff_dict_update(cffont->topdict, cffont);
  cff_dict_update(cffont->private[0], cffont);
  cff_update_string(cffont);

  /* CFF code need to be rewrote... */
  cff_dict_add(cffont->topdict, "ROS", 3);
  cff_dict_set(cffont->topdict, "ROS", 0,
              (double) cff_get_sid(cffont, (char *)"Adobe"));
  cff_dict_set(cffont->topdict, "ROS", 1,
              (double) cff_get_sid(cffont, (char *)"Identity"));
  cff_dict_set(cffont->topdict, "ROS", 2, 0.0);

  destlen = write_fontfile(font, cffont);

  cff_close(cffont);

  /*
   * DW, W, DW2 and W2:
   * Those values are obtained from OpenType table (not TFM).
   */
  {
    unsigned char *CIDToGIDMap;

    CIDToGIDMap = NEW(2 * (last_cid+1), unsigned char);
    memset(CIDToGIDMap, 0, 2 * (last_cid + 1));
    for (cid = 0; cid <= last_cid; cid++) {
      if (is_used_char2(used_chars, cid)) {
       CIDToGIDMap[2*cid  ] = (cid >> 8) & 0xff;
       CIDToGIDMap[2*cid+1] = cid & 0xff;
      }
    }
    add_CIDMetrics(sfont, font->fontdict, CIDToGIDMap, last_cid,
                 ((CIDFont_get_parent_id(font, 1) < 0) ? 0 : 1));
    RELEASE(CIDToGIDMap);
  }

  sfnt_close(sfont);
  DPXFCLOSE(fp);

  if (verbose > 1)
    MESG("[%u glyphs][%ld bytes]", num_glyphs, destlen);

  /*
   * CIDSet:
   * Length of CIDSet stream is not clear. Must be 8192 bytes long?
   */
  {
    pdf_obj *cidset;

    cidset = pdf_new_stream(STREAM_COMPRESS);
    pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
    pdf_add_dict(font->descriptor,
               pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
    pdf_release_obj(cidset);
  }

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CIDFont_type0_t1copen ( CIDFont font,
const char *  name,
CIDSysInfo cmap_csi,
cid_opt opt 
)

Definition at line 1128 of file cidtype0.c.

{
  CIDSysInfo *csi;
  char       *fontname;
  sfnt       *sfont;
  cff_font   *cffont;
  unsigned long offset = 0;
  FILE       *fp;

  ASSERT(font);

  fp = DPXFOPEN(name, DPX_RES_TYPE_OTFONT);
  if (!fp)
    return -1;

  sfont = sfnt_open(fp);
  if (!sfont) {
    ERROR("Not a CFF/OpenType font?");
  }
  if (sfont->type != SFNT_TYPE_POSTSCRIPT     ||
      sfnt_read_table_directory(sfont, 0) < 0 ||
      (offset = sfnt_find_table_pos(sfont, "CFF ")) == 0) {
    ERROR("Not a CFF/OpenType font?");
  }

  cffont = cff_open(fp, offset, opt->index);
  if (!cffont) {
    ERROR("Cannot read CFF font data");
  }

  if (cffont->flag & FONTTYPE_CIDFONT) {
    cff_close(cffont);
    sfnt_close(sfont);
    DPXFCLOSE(fp);

    return -1;
  }

  csi = NEW(1, CIDSysInfo);
  csi->registry   = NEW(strlen("Adobe")+1, char);
  strcpy(csi->registry, "Adobe");
  csi->ordering   = NEW(strlen("Identity")+1, char);
  strcpy(csi->ordering, "Identity");
  csi->supplement = 0;

  if (cmap_csi) {
    if (strcmp(csi->registry, cmap_csi->registry) != 0 ||
       strcmp(csi->ordering, cmap_csi->ordering) != 0) {
      MESG("\nCharacter collection mismatched:\n");
      MESG("\tFont: %s-%s-%d\n", csi->registry, csi->ordering, csi->supplement);
      MESG("\tCMap: %s-%s-%d\n", cmap_csi->registry, cmap_csi->ordering, cmap_csi->supplement);
      ERROR("Inconsistent CMap specified for this font.");
    }
    if (csi->supplement < cmap_csi->supplement) {
      WARN("CMap have higher supplmement number.");
      WARN("Some characters may not be displayed or printed.");
    }
  }

  {
    char *shortname;

    shortname = cff_get_name(cffont);
    if (!shortname)
      ERROR("No valid FontName found.");
    /* Mangled name requires more 7 bytes. */

    fontname = NEW(strlen(shortname) + 8, char);
    memset(fontname, 0, strlen(shortname) + 8);
    strcpy(fontname, shortname);
    RELEASE(shortname);
  }
  cff_close(cffont);

  opt->embed = 1;

  font->fontname = fontname;
  font->subtype  = CIDFONT_TYPE0;
  font->csi      = csi;
  font->flags   |= CIDFONT_FLAG_TYPE1C;

  font->fontdict = pdf_new_dict();
  pdf_add_dict(font->fontdict,
              pdf_new_name("Type"),
              pdf_new_name("Font"));
  pdf_add_dict(font->fontdict,
              pdf_new_name("Subtype"),
              pdf_new_name("CIDFontType0"));

  /* getting font info. from TrueType tables */
  if ((font->descriptor
       = tt_get_fontdesc(sfont, &(opt->embed), opt->stemv, 0)) == NULL)
    ERROR("Could not obtain neccesary font info.");

  if (opt->embed) {
    memmove(fontname + 7, fontname, strlen(fontname) + 1);
    pdf_font_make_uniqueTag(fontname);
    fontname[6] = '+';
  }

  pdf_add_dict(font->descriptor,
              pdf_new_name("FontName"),
              pdf_new_name(fontname));
  pdf_add_dict(font->fontdict, 
              pdf_new_name("BaseFont"),
              pdf_new_name(fontname));
  {
    pdf_obj *csi_dict = pdf_new_dict();
    pdf_add_dict(csi_dict,
               pdf_new_name("Registry"),
               pdf_new_string(csi->registry, strlen(csi->registry)));
    pdf_add_dict(csi_dict,
               pdf_new_name("Ordering"),
               pdf_new_string(csi->ordering, strlen(csi->ordering)));
    pdf_add_dict(csi_dict,
               pdf_new_name("Supplement"),
               pdf_new_number(csi->supplement));
    pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
  }
  sfnt_close(sfont);
  DPXFCLOSE(fp);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CIDFont_type0_t1dofont ( CIDFont font)

Definition at line 1783 of file cidtype0.c.

{
  cff_font *cffont;
  double    defaultwidth, nominalwidth;
  long      num_glyphs = 0;
  FILE     *fp;
  long      i, offset;
  char     *used_chars = NULL;
  card16    last_cid, gid, cid;
  unsigned char *CIDToGIDMap;

  ASSERT(font);

  if (!font->indirect) {
    return;
  }

  pdf_add_dict(font->fontdict, 
              pdf_new_name("FontDescriptor"),
              pdf_ref_obj (font->descriptor));

  fp = DPXFOPEN(font->ident, DPX_RES_TYPE_T1FONT);
  if (!fp) {
    ERROR("Type1: Could not open Type1 font.");
  }

  cffont = t1_load_font(NULL, 0, fp);
  if (!cffont)
    ERROR("Could not read Type 1 font...");
  DPXFCLOSE(fp);

  if (!font->fontname)
    ERROR("Fontname undefined...");

  {
    Type0Font *hparent, *vparent;
    pdf_obj   *tounicode;
    int        vparent_id, hparent_id;

    hparent_id = CIDFont_get_parent_id(font, 0);
    vparent_id = CIDFont_get_parent_id(font, 1);
    if (hparent_id < 0 && vparent_id < 0)
      ERROR("No parent Type 0 font !");

    /* usedchars is same for h and v */
    if (hparent_id < 0)
      hparent = NULL;
    else {
      hparent    = Type0Font_cache_get(hparent_id);
      used_chars = Type0Font_get_usedchars(hparent);
    }
    if (vparent_id < 0)
      vparent = NULL;
    else {
      vparent    = Type0Font_cache_get(vparent_id);
      used_chars = Type0Font_get_usedchars(vparent);
    }
    if (!used_chars)
      ERROR("Unexpected error: Font not actually used???");

    tounicode = create_ToUnicode_stream(cffont, font->fontname, used_chars);

    if (hparent)
      Type0Font_set_ToUnicode(hparent, pdf_ref_obj(tounicode));
    if (vparent)
      Type0Font_set_ToUnicode(vparent, pdf_ref_obj(tounicode));
    pdf_release_obj(tounicode);
  }

  cff_set_name(cffont, font->fontname);

  /* defaultWidthX, CapHeight, etc. */
  get_font_attr(font, cffont);
  if (cff_dict_known(cffont->private[0], "defaultWidthX")) {
    defaultwidth = cff_dict_get(cffont->private[0], "defaultWidthX", 0);
  } else {
    defaultwidth = 0.0;
  }
  if (cff_dict_known(cffont->private[0], "nominalWidthX")) {
    nominalwidth = cff_dict_get(cffont->private[0], "nominalWidthX", 0);
  } else {
    nominalwidth = 0.0;
  }

  num_glyphs = 0; last_cid = 0;
  add_to_used_chars2(used_chars, 0); /* .notdef */
  for (i = 0; i < (cffont->num_glyphs + 7)/8; i++) {
    int c, j;

    c = used_chars[i];
    for (j = 7; j >= 0; j--) {
      if (c & (1 << j)) {
       num_glyphs++;
       last_cid = (i + 1) * 8 - j - 1;
      }
    }
  }

  {
    cff_fdselect *fdselect;

    fdselect = NEW(1, cff_fdselect);
    fdselect->format = 3;
    fdselect->num_entries = 1;
    fdselect->data.ranges = NEW(1, cff_range3);
    fdselect->data.ranges[0].first = 0;
    fdselect->data.ranges[0].fd    = 0;
    cffont->fdselect = fdselect;
  }

  CIDToGIDMap = NEW(2*(last_cid+1), unsigned char);
  memset(CIDToGIDMap, 0, 2*(last_cid+1));
  {
    cff_charsets *charset;

    charset  = NEW(1, cff_charsets);
    charset->format = 0;
    charset->num_entries = num_glyphs-1;
    charset->data.glyphs = NEW(num_glyphs-1, s_SID);

    for (gid = 0, cid = 0; cid <= last_cid; cid++) {
      if (is_used_char2(used_chars, cid)) {
       if (gid > 0)
         charset->data.glyphs[gid-1] = cid;
       CIDToGIDMap[2*cid  ] = (gid >> 8) & 0xff;
       CIDToGIDMap[2*cid+1] = gid & 0xff;
       gid++;
      }
    }

    cff_release_charsets(cffont->charsets);
    cffont->charsets = charset;
  }

  cff_dict_add(cffont->topdict, "CIDCount", 1);
  cff_dict_set(cffont->topdict, "CIDCount", 0, last_cid + 1);

  cffont->fdarray    = NEW(1, cff_dict *);
  cffont->fdarray[0] = cff_new_dict();
  cff_dict_add(cffont->fdarray[0], "FontName", 1);
  cff_dict_set(cffont->fdarray[0], "FontName", 0,
              (double) cff_add_string(cffont, font->fontname + 7, 1)); /* FIXME: Skip XXXXXX+ */
  cff_dict_add(cffont->fdarray[0], "Private", 2);
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);
  cff_dict_set(cffont->fdarray[0], "Private", 0, 0.0);

  /* FDArray  - index offset, not known yet */
  cff_dict_add(cffont->topdict, "FDArray", 1);
  cff_dict_set(cffont->topdict, "FDArray", 0, 0.0);
  /* FDSelect - offset, not known yet */
  cff_dict_add(cffont->topdict, "FDSelect", 1);
  cff_dict_set(cffont->topdict, "FDSelect", 0, 0.0);

  cff_dict_add(cffont->topdict, "charset", 1);
  cff_dict_set(cffont->topdict, "charset", 0, 0.0);

  cff_dict_add(cffont->topdict, "CharStrings", 1);
  cff_dict_set(cffont->topdict, "CharStrings", 0, 0.0);

  {
    cff_index *cstring;
    t1_ginfo   gm;
    long       max = 0;
    double    *widths;
    int        w_stat[1001], max_count, dw;

    widths = NEW(num_glyphs, double);
    memset(w_stat, 0, sizeof(int)*1001);
    offset  = 0L;
    cstring = cff_new_index(num_glyphs);
    cstring->data = NULL;
    cstring->offset[0] = 1;
    gid = 0;
    for (cid = 0; cid <= last_cid; cid++) {
      if (!is_used_char2(used_chars, cid))
         continue;

      if (offset + CS_STR_LEN_MAX >= max) {
       max += CS_STR_LEN_MAX*2;
       cstring->data = RENEW(cstring->data, max, card8);
      }
      offset += t1char_convert_charstring(cstring->data + cstring->offset[gid] - 1, CS_STR_LEN_MAX,
                                     cffont->cstrings->data + cffont->cstrings->offset[cid] - 1,
                                     cffont->cstrings->offset[cid+1] - cffont->cstrings->offset[cid],
                                     cffont->subrs[0], defaultwidth, nominalwidth, &gm);
      cstring->offset[gid+1] = offset + 1;
      if (gm.use_seac) {
       ERROR("This font using the \"seac\" command for accented characters...");
      }
      widths[gid] = gm.wx;
      if (gm.wx >= 0.0 && gm.wx <= 1000.0) {
       w_stat[((int) gm.wx)] += 1;
      }
      gid++;
    }

    cff_release_index(cffont->cstrings);
    cffont->cstrings = cstring;

    max_count = 0; dw = -1;
    for (i = 0; i <= 1000; i++) {
      if (w_stat[i] > max_count) {
       dw        = i;
       max_count = w_stat[i];
      }
    }
    if (dw >= 0) {
      add_metrics(font, cffont, CIDToGIDMap, widths, dw, last_cid);
    } else {
      add_metrics(font, cffont, CIDToGIDMap, widths, defaultwidth, last_cid);
    }
    RELEASE(widths);
  }
  cff_release_index(cffont->subrs[0]);
  cffont->subrs[0] = NULL;

  RELEASE(CIDToGIDMap);

  cff_add_string(cffont, "Adobe", 1);
  cff_add_string(cffont, "Identity", 1);

  cff_dict_update(cffont->topdict, cffont);
  cff_dict_update(cffont->private[0], cffont);

  cff_update_string(cffont);

  /* CFF code need to be rewrote... */
  cff_dict_add(cffont->topdict, "ROS", 3);
  cff_dict_set(cffont->topdict, "ROS", 0,
              (double) cff_get_sid(cffont, (char *)"Adobe"));
  cff_dict_set(cffont->topdict, "ROS", 1,
              (double) cff_get_sid(cffont, (char *)"Identity"));
  cff_dict_set(cffont->topdict, "ROS", 2, 0.0);

  cffont->num_glyphs = num_glyphs;
  offset = write_fontfile(font, cffont);

  cff_close(cffont);

  {
    pdf_obj *cidset;

    cidset = pdf_new_stream(STREAM_COMPRESS);
    pdf_add_stream(cidset, used_chars, (last_cid/8)+1);
    pdf_add_dict(font->descriptor,
               pdf_new_name("CIDSet"), pdf_ref_obj(cidset));
    pdf_release_obj(cidset);
  }


  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CIDFont_type0_t1open ( CIDFont font,
const char *  name,
CIDSysInfo cmap_csi,
cid_opt opt 
)

Definition at line 1480 of file cidtype0.c.

{
  FILE       *fp;
  char       *fontname, *shortname;
  cff_font   *cffont;

  ASSERT(font);

  if (cmap_csi &&
      (strcmp(cmap_csi->registry, "Adobe")    != 0 ||
       strcmp(cmap_csi->ordering, "Identity") != 0)) {
    return -1;
  }
  fp = DPXFOPEN(name, DPX_RES_TYPE_T1FONT);
  if (!fp)
    return -1;

  cffont = t1_load_font(NULL, 1, fp);
  if (!cffont) {
    DPXFCLOSE(fp);
    return -1;
  }
  DPXFCLOSE(fp);

  shortname = cff_get_name(cffont);
  if (!shortname)
    ERROR("No valid FontName found.");
  fontname = NEW(strlen(shortname) + 8, char);
  memset(fontname, 0, strlen(shortname) + 8);
  strcpy(fontname, shortname);
  RELEASE(shortname);

  cff_close(cffont);

  if (opt->style != FONT_STYLE_NONE) {
    WARN(",Bold, ,Italic, ... not supported for this type of font...");
    opt->style = FONT_STYLE_NONE;
  }

  font->fontname = fontname;
  font->subtype  = CIDFONT_TYPE0;
  font->csi      = NEW(1, CIDSysInfo);
  font->csi->registry = NEW(strlen("Adobe")+1, char);
  strcpy(font->csi->registry, "Adobe");
  font->csi->ordering = NEW(strlen("Identity")+1, char);
  strcpy(font->csi->ordering, "Identity");
  font->csi->supplement = 0;
  font->flags   |= CIDFONT_FLAG_TYPE1;

  font->fontdict = pdf_new_dict();
  pdf_add_dict(font->fontdict,
              pdf_new_name("Type"),
              pdf_new_name("Font"));
  pdf_add_dict(font->fontdict,
              pdf_new_name("Subtype"),
              pdf_new_name("CIDFontType0"));

  memmove(fontname + 7, fontname, strlen(fontname) + 1);
  pdf_font_make_uniqueTag(fontname);
  fontname[6] = '+';

  font->descriptor = pdf_new_dict();
  pdf_add_dict(font->descriptor,
              pdf_new_name("FontName"),
              pdf_new_name(fontname));
  pdf_add_dict(font->fontdict, 
              pdf_new_name("BaseFont"),
              pdf_new_name(fontname));
  {
    pdf_obj *csi_dict;

    csi_dict = pdf_new_dict();
    pdf_add_dict(csi_dict,
               pdf_new_name("Registry"),
               pdf_new_string("Adobe", strlen("Adobe")));
    pdf_add_dict(csi_dict,
               pdf_new_name("Ordering"),
               pdf_new_string("Identity", strlen("Identity")));
    pdf_add_dict(csi_dict,
               pdf_new_name("Supplement"),
               pdf_new_number(0.0));
    pdf_add_dict(font->fontdict, pdf_new_name("CIDSystemInfo"), csi_dict);
  }


  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int t1_load_UnicodeCMap ( const char *  font_name,
const char *  otl_tags,
int  wmode 
)

Definition at line 1359 of file cidtype0.c.

{
  int       cmap_id = -1;
  cff_font *cffont;
  FILE     *fp;

  if (!font_name)
    return -1;

  fp = DPXFOPEN(font_name, DPX_RES_TYPE_T1FONT);
  if (!fp)
    return -1;

  cffont = t1_load_font(NULL, 1, fp);
  if (!cffont) {
    DPXFCLOSE(fp);
    return -1;
  }
  DPXFCLOSE(fp);

  cmap_id = load_base_CMap(font_name, wmode, cffont);
  
  cff_close(cffont);

  if (cmap_id < 0) {
    ERROR("Failed to create Unicode charmap for font \"%s\".", font_name);
    return -1;
  }

  if (otl_tags) {
    WARN("Glyph substitution not supported for Type1 font yet...");
  }

  return cmap_id;
}

Here is the call graph for this function:

Here is the caller graph for this function: