Back to index

texmacs  1.0.7.15
Classes | Defines | Functions | Variables
pdffont.c File Reference
#include <string.h>
#include <time.h>
#include "system.h"
#include "error.h"
#include "mem.h"
#include "dpxfile.h"
#include "dpxutil.h"
#include "pdfobj.h"
#include "pdfencoding.h"
#include "cmap.h"
#include "unicode.h"
#include "type1.h"
#include "type1c.h"
#include "truetype.h"
#include "pkfont.h"
#include "type0.h"
#include "tt_cmap.h"
#include "cidtype0.h"
#include "otl_conf.h"
#include "pdffont.h"
#include "t1_load.h"

Go to the source code of this file.

Classes

struct  pdf_font

Defines

#define MREC_HAS_TOUNICODE(m)   ((m) && (m)->opt.tounicode)
#define CACHE_ALLOC_SIZE   16u
#define CHECK_ID(n)
#define GET_FONT(n)   (&(font_cache.fonts[(n)]))
#define MAYBE_CMAP(s)   (!strstr((s), ".enc") || strstr((s), ".cmap"))
#define MAYBE_CMAP(s)   (!strstr((s), ".enc") || strstr((s), ".cmap"))

Functions

void pdf_font_set_verbose (void)
int pdf_font_get_verbose (void)
void pdf_font_set_dpi (int font_dpi)
void pdf_font_make_uniqueTag (char *tag)
static void pdf_init_font_struct (pdf_font *font)
static void pdf_flush_font (pdf_font *font)
static void pdf_clean_font_struct (pdf_font *font)
void pdf_init_fonts (void)
pdf_objpdf_get_font_reference (int font_id)
char * pdf_get_font_usedchars (int font_id)
int pdf_get_font_wmode (int font_id)
int pdf_get_font_subtype (int font_id)
int pdf_get_font_encoding (int font_id)
static int try_load_ToUnicode_CMap (pdf_font *font)
void pdf_close_fonts (void)
int pdf_font_findresource (const char *tex_name, double font_scale, fontmap_rec *mrec)
int pdf_font_physical (const char *tex_name, double font_scale, const char *font_file, const char *tfm_file)
int pdf_font_physical_old (const char *tex_name, double font_scale, const char *font_file)
int pdf_font_is_in_use (pdf_font *font)
int pdf_font_get_index (pdf_font *font)
char * pdf_font_get_ident (pdf_font *font)
char * pdf_font_get_mapname (pdf_font *font)
char * pdf_font_get_fontname (pdf_font *font)
char * pdf_font_get_fontfile (pdf_font *font)
char * pdf_font_get_tfmfile (pdf_font *font)
pdf_objpdf_font_get_resource (pdf_font *font)
pdf_objpdf_font_get_descriptor (pdf_font *font)
char * pdf_font_get_usedchars (pdf_font *font)
int pdf_font_get_encoding (pdf_font *font)
int pdf_font_get_flag (pdf_font *font, int mask)
double pdf_font_get_param (pdf_font *font, int param_type)
char * pdf_font_get_uniqueTag (pdf_font *font)
int pdf_font_set_fontname (pdf_font *font, const char *fontname)
int pdf_font_set_subtype (pdf_font *font, int subtype)
int pdf_font_set_flags (pdf_font *font, int flags)

Variables

static int __verbose = 0
struct {
int count
int capacity
pdf_fontfonts
font_cache

Class Documentation

struct pdf_font

Definition at line 110 of file pdffont.c.

Collaboration diagram for pdf_font:
Class Members
pdf_obj * descriptor
double design_size
int encoding_id
int flags
int font_id
char * fontfile
char * fontname
char * ident
int index
char * map_name
double point_size
pdf_obj * reference
pdf_obj * resource
int subtype
char * tfmfile
char uniqueID
char * usedchars

Define Documentation

#define CACHE_ALLOC_SIZE   16u

Definition at line 273 of file pdffont.c.

#define CHECK_ID (   n)
Value:
do {\
  if ((n) < 0 || (n) >= font_cache.count) {\
    ERROR("Invalid font ID: %d", (n));\
  }\
} while (0)

Definition at line 301 of file pdffont.c.

#define GET_FONT (   n)    (&(font_cache.fonts[(n)]))

Definition at line 306 of file pdffont.c.

#define MAYBE_CMAP (   s)    (!strstr((s), ".enc") || strstr((s), ".cmap"))
#define MAYBE_CMAP (   s)    (!strstr((s), ".enc") || strstr((s), ".cmap"))
#define MREC_HAS_TOUNICODE (   m)    ((m) && (m)->opt.tounicode)

Definition at line 62 of file pdffont.c.


Function Documentation

static void pdf_clean_font_struct ( pdf_font font) [static]

Definition at line 239 of file pdffont.c.

{
  if (font) {
    if (font->ident)
      RELEASE(font->ident);
    if (font->map_name)
      RELEASE(font->map_name);
    if (font->fontname)
      RELEASE(font->fontname);
    if (font->fontfile)
      RELEASE(font->fontfile);
    if (font->tfmfile)
      RELEASE(font->tfmfile);
    if (font->usedchars)
      RELEASE(font->usedchars);

    if (font->reference)
      ERROR("pdf_font>> Object not flushed.");
    if (font->resource)
      ERROR("pdf_font> Object not flushed.");
    if (font->descriptor)
      ERROR("pdf_font>> Object not flushed.");

    font->ident     = NULL;
    font->map_name  = NULL;
    font->fontname  = NULL;
    font->fontfile  = NULL;
    font->tfmfile  = NULL;
    font->usedchars = NULL;
  }

  return;
}

Here is the caller graph for this function:

void pdf_close_fonts ( void  )

Definition at line 465 of file pdffont.c.

{
  int  font_id, retval;

  for (font_id = 0;
       font_id < font_cache.count; font_id++) {
    pdf_font  *font;

    font = GET_FONT(font_id);

    if (__verbose) {
      if (font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
       MESG("(%s", pdf_font_get_ident(font));
       if (__verbose > 2 &&
           !pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) {
         MESG("[%s+%s]",
              pdf_font_get_uniqueTag(font),
              pdf_font_get_fontname(font));
       } else if (__verbose > 1) {
         MESG("[%s]",
              pdf_font_get_fontname(font));
       }
       if (__verbose > 1) {
         if (pdf_font_get_encoding(font) >= 0) {
           MESG("[%s]",
               pdf_encoding_get_name(pdf_font_get_encoding(font)));
         } else {
           MESG("[built-in]");
         }
       }

      }
    }

    /* Must come before load_xxx */
    try_load_ToUnicode_CMap(font);

    /* Type 0 is handled separately... */
    switch (font->subtype) {
    case PDF_FONT_FONTTYPE_TYPE1:
      if (__verbose)
       MESG("[Type1]");
      if (!pdf_font_get_flag(font, PDF_FONT_FLAG_BASEFONT))
       retval = pdf_font_load_type1(font);
      else
       retval = 0;
      break;
    case PDF_FONT_FONTTYPE_TYPE1C:
      if (__verbose)
       MESG("[Type1C]");
      retval = pdf_font_load_type1c(font);
      break;
    case PDF_FONT_FONTTYPE_TRUETYPE:
      if (__verbose)
       MESG("[TrueType]");
      retval = pdf_font_load_truetype(font);
      break;
    case PDF_FONT_FONTTYPE_TYPE3:
      if (__verbose)
       MESG("[Type3/PK]");
      retval = pdf_font_load_pkfont (font);
      break;
    case PDF_FONT_FONTTYPE_TYPE0:
      break;
    default:
      ERROR("Unknown font type: %d", font->subtype);
      break;
    }

    if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0)
      pdf_encoding_add_usedchars(font->encoding_id, font->usedchars);

    if (__verbose) {
      if (font->subtype != PDF_FONT_FONTTYPE_TYPE0)
       MESG(")");
    }
  }

  pdf_encoding_complete();

  for (font_id = 0; font_id < font_cache.count; font_id++) {
    pdf_font *font = GET_FONT(font_id);

    if (font->encoding_id >= 0 && font->subtype != PDF_FONT_FONTTYPE_TYPE0) {
      pdf_obj *enc_obj = pdf_get_encoding_obj(font->encoding_id);
      pdf_obj *tounicode;

      /* Predefined encodings (and those simplified to them) are embedded
        as direct objects, but this is purely a matter of taste. */
      if (enc_obj)
        pdf_add_dict(font->resource,
                   pdf_new_name("Encoding"),
                   PDF_OBJ_NAMETYPE(enc_obj) ? pdf_link_obj(enc_obj) : pdf_ref_obj(enc_obj));

      if (!pdf_lookup_dict(font->resource, "ToUnicode")
         && (tounicode = pdf_encoding_get_tounicode(font->encoding_id)))
       pdf_add_dict(font->resource,
                   pdf_new_name("ToUnicode"), pdf_ref_obj(tounicode));
    } else if (font->subtype == PDF_FONT_FONTTYPE_TRUETYPE) {
      /* encoding_id < 0 means MacRoman here (but not really)
       * We use MacRoman as "default" encoding. */
      pdf_add_dict(font->resource,
                   pdf_new_name("Encoding"),
                 pdf_new_name("MacRomanEncoding"));
    }

    pdf_flush_font(font);
    pdf_clean_font_struct(font);
  }
  RELEASE(font_cache.fonts);
  font_cache.fonts    = NULL;
  font_cache.count    = 0;
  font_cache.capacity = 0;

  Type0Font_cache_close();

  CMap_cache_close();
  pdf_close_encodings();

  otl_close_conf();
  agl_close_map (); /* After encoding */

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_flush_font ( pdf_font font) [static]

Definition at line 184 of file pdffont.c.

{
  char *fontname, *uniqueTag;

  if (!font) {
    return;
  }

  if (font->resource && font->reference) {
    if (font->subtype != PDF_FONT_FONTTYPE_TYPE3) {
      if (pdf_font_get_flag(font, PDF_FONT_FLAG_NOEMBED)) {
       pdf_add_dict(font->resource,
                   pdf_new_name("BaseFont"), pdf_new_name(font->fontname));
       if (font->descriptor) {
         pdf_add_dict(font->descriptor,
                     pdf_new_name("FontName"), pdf_new_name(font->fontname));
       }
      } else {
       if (!font->fontname) {
         ERROR("Undefined in fontname... (%s)", font->ident);
       }
       fontname  = NEW(7+strlen(font->fontname)+1, char);
       uniqueTag = pdf_font_get_uniqueTag(font);
       sprintf(fontname, "%6s+%s", uniqueTag, font->fontname);
       pdf_add_dict(font->resource,
                   pdf_new_name("BaseFont"), pdf_new_name(fontname));
       if (font->descriptor) {
         pdf_add_dict(font->descriptor,
                     pdf_new_name("FontName"), pdf_new_name(fontname));
       }
       RELEASE(fontname);
      }
      if (font->descriptor) {
       pdf_add_dict(font->resource,
                   pdf_new_name("FontDescriptor"), pdf_ref_obj(font->descriptor));
      }
    }
  }


  if (font->resource)
    pdf_release_obj(font->resource);
  if (font->descriptor)
    pdf_release_obj(font->descriptor);
  if (font->reference)
    pdf_release_obj(font->reference);

  font->reference  = NULL;
  font->resource   = NULL;
  font->descriptor = NULL;

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_font_findresource ( const char *  tex_name,
double  font_scale,
fontmap_rec mrec 
)

Definition at line 591 of file pdffont.c.

{
  int          font_id = -1;
  pdf_font    *font;
  int          encoding_id = -1, cmap_id = -1;
  const char  *fontname;

  /*
   * Get appropriate info from map file. (PK fonts at two different
   * point sizes would be looked up twice unecessarily.)
   */
  fontname = mrec ? mrec->font_name : tex_name;
  if (mrec && mrec->enc_name) {
#define MAYBE_CMAP(s) (!strstr((s), ".enc") || strstr((s), ".cmap"))
    if (MAYBE_CMAP(mrec->enc_name)) {
      cmap_id = CMap_cache_find(mrec->enc_name);
      if (cmap_id >= 0) {
       CMap  *cmap;
       int    cmap_type, minbytes;

       cmap      = CMap_cache_get(cmap_id);
       cmap_type = CMap_get_type (cmap);
       minbytes  = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN);
       /*
        * Check for output encoding.
        */
       if (cmap_type != CMAP_TYPE_IDENTITY    &&
           cmap_type != CMAP_TYPE_CODE_TO_CID &&
           cmap_type != CMAP_TYPE_TO_UNICODE) {
         WARN("Only 16-bit encoding supported for output encoding.");
       }
       /*
        * Turn on map option.
        */
       if (minbytes == 2 && mrec->opt.mapc < 0) {
         if (__verbose) {
           MESG("\n");
           MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n",
               CMap_get_name(cmap));
           MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name);
         }
         mrec->opt.mapc = 0; /* _FIXME_ */
       }
      } else if (!strcmp(mrec->enc_name, "unicode")) {
       cmap_id = otf_load_Unicode_CMap(mrec->font_name,
                                   mrec->opt.index, mrec->opt.otl_tags,
                                   ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
       if (cmap_id < 0) {
         cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags,
                                   ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
       }
       if (cmap_id < 0)
         ERROR("Failed to read UCS2/UCS4 TrueType cmap...");
      }
    }
    if (cmap_id < 0) {
      encoding_id = pdf_encoding_findresource(mrec->enc_name);
      if (encoding_id < 0)
       ERROR("Could not find encoding file \"%s\".", mrec->enc_name);
    }
  }

  if (mrec && cmap_id >= 0) {
    /*
     * Composite Font
     */
    int  type0_id, found = 0;

    type0_id = pdf_font_findfont0(mrec->font_name, cmap_id, &mrec->opt);
    if (type0_id < 0) {
      return -1;
    }

    for (font_id = 0;
        font_id < font_cache.count; font_id++) {
      font = GET_FONT(font_id);
      if (font->subtype == PDF_FONT_FONTTYPE_TYPE0 &&
         font->font_id == type0_id &&
         font->encoding_id == cmap_id) {
       found = 1;
       if (__verbose) {
         MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n",
              mrec->font_name, cmap_id, font_id);
       }
       break;
      }
    }

    if (!found) {
      font_id = font_cache.count;
      if (font_cache.count >= font_cache.capacity) {
       font_cache.capacity += CACHE_ALLOC_SIZE;
       font_cache.fonts     = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
      }
      font    = GET_FONT(font_id);
      pdf_init_font_struct(font);

      font->font_id     = type0_id;
      font->subtype     = PDF_FONT_FONTTYPE_TYPE0;
      font->encoding_id = cmap_id;

      font_cache.count++;

      if (__verbose) {
       MESG("\npdf_font>> Type0 font \"%s\"", fontname);
        MESG(" cmap_id=<%s,%d>", mrec->enc_name, font->encoding_id);
        MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
      }

    }
  } else {
    /*
     * Simple Font - always embed.
     */
    int  found = 0;

    for (font_id = 0;
        font_id < font_cache.count; font_id++) {
      font = GET_FONT(font_id);
      switch (font->subtype) {
      case PDF_FONT_FONTTYPE_TYPE1:
      case PDF_FONT_FONTTYPE_TYPE1C:
      case PDF_FONT_FONTTYPE_TRUETYPE:
       /* fontname here is font file name.
        * We must compare both font file name and encoding
        *
        * TODO: Embed a font only once if it is used
        *       with two different encodings
        */
       if (!strcmp(fontname, font->ident)   &&
           encoding_id == font->encoding_id) {
          if (mrec && mrec->opt.index == font->index)
            found = 1;
       }
       break;
      case PDF_FONT_FONTTYPE_TYPE3:
       /* There shouldn't be any encoding specified for PK font.
        * It must be always font's build-in encoding.
        *
        * TODO: a PK font with two encodings makes no sense. Change?
         */
       if (!strcmp(fontname, font->ident) &&
           font_scale == font->point_size) {
         found = 1;
       }
       break;
      case PDF_FONT_FONTTYPE_TYPE0:
       break;
      default:
       ERROR("Unknown font type: %d", font->subtype);
       break;
      }

      if (found) {
       if (__verbose) {
         MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n",
              fontname, encoding_id, font_id);
       }
       break;
      }
    }


    if (!found) {
      font_id = font_cache.count;
      if (font_cache.count >= font_cache.capacity) {
       font_cache.capacity += CACHE_ALLOC_SIZE;
       font_cache.fonts     = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
      }

      font = GET_FONT(font_id);

      pdf_init_font_struct(font);

      font->point_size  = font_scale;
      font->encoding_id = encoding_id;
      font->ident       = NEW(strlen(fontname) + 1, char);
      strcpy(font->ident, fontname);
      font->map_name    = NEW(strlen(tex_name) + 1, char);
      strcpy(font->map_name, tex_name);
      font->index       = (mrec && mrec->opt.index) ? mrec->opt.index : 0;

      if (pdf_font_open_type1(font) >= 0) {
       font->subtype = PDF_FONT_FONTTYPE_TYPE1;
      } else if (pdf_font_open_type1c(font) >= 0) {
       font->subtype = PDF_FONT_FONTTYPE_TYPE1C;
      } else if (pdf_font_open_truetype(font) >= 0) {
       font->subtype = PDF_FONT_FONTTYPE_TRUETYPE;
      } else if (pdf_font_open_pkfont(font) >= 0) {
       font->subtype = PDF_FONT_FONTTYPE_TYPE3;
      } else {
       pdf_clean_font_struct(font);
       return -1;
      }

      font_cache.count++;

      if (__verbose) {
       MESG("\npdf_font>> Simple font \"%s\"", fontname);
        MESG(" enc_id=<%s,%d>",
             (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id);
        MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
      }
    }
  }

  return  font_id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1242 of file pdffont.c.

{
  ASSERT(font);

  if (!font->descriptor) {
    font->descriptor = pdf_new_dict();
    pdf_add_dict(font->descriptor,
               pdf_new_name("Type"), pdf_new_name("FontDescriptor"));
  }

  return font->descriptor;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1264 of file pdffont.c.

{
  ASSERT(font);

  return font->encoding_id;
}

Here is the caller graph for this function:

int pdf_font_get_flag ( pdf_font font,
int  mask 
)

Definition at line 1272 of file pdffont.c.

{
  ASSERT(font);

  return ((font->flags & mask) ? 1 : 0);
}

Here is the caller graph for this function:

char* pdf_font_get_fontfile ( pdf_font font)

Definition at line 1195 of file pdffont.c.

{
  ASSERT(font);
  
  return font->fontfile;
}

Here is the caller graph for this function:

char* pdf_font_get_fontname ( pdf_font font)

Definition at line 1186 of file pdffont.c.

{
  ASSERT(font);

  return font->fontname;
}

Here is the caller graph for this function:

char* pdf_font_get_ident ( pdf_font font)

Definition at line 1170 of file pdffont.c.

{
  ASSERT(font);

  return font->ident;
}

Here is the caller graph for this function:

int pdf_font_get_index ( pdf_font font)

Definition at line 1162 of file pdffont.c.

{
  ASSERT(font);

  return font->index;
}

Here is the caller graph for this function:

char* pdf_font_get_mapname ( pdf_font font)

Definition at line 1178 of file pdffont.c.

{
  ASSERT(font);

  return font->map_name;
}

Here is the caller graph for this function:

double pdf_font_get_param ( pdf_font font,
int  param_type 
)

Definition at line 1290 of file pdffont.c.

{
  double param = 0.0;

  ASSERT(font);

  switch (param_type) {
  case PDF_FONT_PARAM_DESIGN_SIZE:
    param = font->design_size;
    break;
  case PDF_FONT_PARAM_POINT_SIZE:
    param = font->point_size;
    break;
  default:
    break;
  }

  return param;
}

Here is the caller graph for this function:

Definition at line 1211 of file pdffont.c.

{
  ASSERT(font);

  if (!font->resource) {
    font->resource = pdf_new_dict();
    pdf_add_dict(font->resource,
               pdf_new_name("Type"),      pdf_new_name("Font"));
    switch (font->subtype) {
    case PDF_FONT_FONTTYPE_TYPE1:
    case PDF_FONT_FONTTYPE_TYPE1C:
      pdf_add_dict(font->resource,
                 pdf_new_name("Subtype"), pdf_new_name("Type1"));
      break;
    case PDF_FONT_FONTTYPE_TYPE3:
      pdf_add_dict(font->resource,
                 pdf_new_name("Subtype"), pdf_new_name("Type3"));
      break;
    case PDF_FONT_FONTTYPE_TRUETYPE:
      pdf_add_dict(font->resource,
                 pdf_new_name("Subtype"), pdf_new_name("TrueType"));
      break;
    default:
      break;
    }
  }

  return font->resource;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* pdf_font_get_tfmfile ( pdf_font font)

Definition at line 1203 of file pdffont.c.

{
  ASSERT(font);
  
  return font->tfmfile;
}

Here is the caller graph for this function:

char* pdf_font_get_uniqueTag ( pdf_font font)

Definition at line 1311 of file pdffont.c.

{
  ASSERT(font);

  if (font->uniqueID[0] == '\0') {
    pdf_font_make_uniqueTag(font->uniqueID);
  }

  return font->uniqueID;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* pdf_font_get_usedchars ( pdf_font font)

Definition at line 1256 of file pdffont.c.

{
  ASSERT(font);

  return font->usedchars;
}

Here is the caller graph for this function:

int pdf_font_get_verbose ( void  )

Definition at line 79 of file pdffont.c.

{
  return __verbose;
}

Here is the caller graph for this function:

int pdf_font_is_in_use ( pdf_font font)

Definition at line 1154 of file pdffont.c.

{
  ASSERT(font);

  return ((font->reference) ? 1 : 0);
}

Here is the caller graph for this function:

void pdf_font_make_uniqueTag ( char *  tag)

Definition at line 91 of file pdffont.c.

{
  int    i;
  char   ch;
  static char first = 1;

  if (first) {
    srand(time(NULL));
    first = 0;
  }

  for (i = 0; i < 6; i++) {
    ch = rand() % 26;
    tag[i] = ch + 'A';
  }
  tag[6] = '\0';
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_font_physical ( const char *  tex_name,
double  font_scale,
const char *  font_file,
const char *  tfm_file 
)

Definition at line 805 of file pdffont.c.

{
  int          font_id = -1;
  pdf_font    *font;
  int          encoding_id = -1, cmap_id = -1;
  const char  *fontname;
  
  
  fontmap_rec *mrec = NULL; // FIXME: maybe reenable mrec in future
  
  /*
   * Get appropriate info from map file. (PK fonts at two different
   * point sizes would be looked up twice unecessarily.)
   */
  fontname = mrec ? mrec->font_name : tex_name;
  if (mrec && mrec->enc_name) {
#define MAYBE_CMAP(s) (!strstr((s), ".enc") || strstr((s), ".cmap"))
    if (MAYBE_CMAP(mrec->enc_name)) {
      cmap_id = CMap_cache_find(mrec->enc_name);
      if (cmap_id >= 0) {
        CMap  *cmap;
        int    cmap_type, minbytes;
        
        cmap      = CMap_cache_get(cmap_id);
        cmap_type = CMap_get_type (cmap);
        minbytes  = CMap_get_profile(cmap, CMAP_PROF_TYPE_INBYTES_MIN);
        /*
         * Check for output encoding.
         */
        if (cmap_type != CMAP_TYPE_IDENTITY    &&
            cmap_type != CMAP_TYPE_CODE_TO_CID &&
            cmap_type != CMAP_TYPE_TO_UNICODE) {
          WARN("Only 16-bit encoding supported for output encoding.");
        }
        /*
         * Turn on map option.
         */
        if (minbytes == 2 && mrec->opt.mapc < 0) {
          if (__verbose) {
            MESG("\n");
            MESG("pdf_font>> Input encoding \"%s\" requires at least 2 bytes.\n",
                 CMap_get_name(cmap));
            MESG("pdf_font>> The -m <00> option will be assumed for \"%s\".\n", mrec->font_name);
          }
          mrec->opt.mapc = 0; /* _FIXME_ */
        }
      } else if (!strcmp(mrec->enc_name, "unicode")) {
        cmap_id = otf_load_Unicode_CMap(mrec->font_name,
                                        mrec->opt.index, mrec->opt.otl_tags,
                                        ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
        if (cmap_id < 0) {
          cmap_id = t1_load_UnicodeCMap(mrec->font_name, mrec->opt.otl_tags,
                                        ((mrec->opt.flags & FONTMAP_OPT_VERT) ? 1 : 0));
        }
        if (cmap_id < 0)
          ERROR("Failed to read UCS2/UCS4 TrueType cmap...");
      }
    }
    if (cmap_id < 0) {
      encoding_id = pdf_encoding_findresource(mrec->enc_name);
      if (encoding_id < 0)
        ERROR("Could not find encoding file \"%s\".", mrec->enc_name);
    }
  }
  
  if (mrec && cmap_id >= 0) {
    /*
     * Composite Font
     */
    int  type0_id, found = 0;
    
    type0_id = pdf_font_findfont0(mrec->font_name, cmap_id, &mrec->opt);
    if (type0_id < 0) {
      return -1;
    }
    
    for (font_id = 0;
         font_id < font_cache.count; font_id++) {
      font = GET_FONT(font_id);
      if (font->subtype == PDF_FONT_FONTTYPE_TYPE0 &&
          font->font_id == type0_id &&
          font->encoding_id == cmap_id) {
        found = 1;
        if (__verbose) {
          MESG("\npdf_font>> Type0 font \"%s\" (cmap_id=%d) found at font_id=%d.\n",
               mrec->font_name, cmap_id, font_id);
        }
        break;
      }
    }
    
    if (!found) {
      font_id = font_cache.count;
      if (font_cache.count >= font_cache.capacity) {
        font_cache.capacity += CACHE_ALLOC_SIZE;
        font_cache.fonts     = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
      }
      font    = GET_FONT(font_id);
      pdf_init_font_struct(font);
      
      font->font_id     = type0_id;
      font->subtype     = PDF_FONT_FONTTYPE_TYPE0;
      font->encoding_id = cmap_id;
      
      font_cache.count++;
      
      if (__verbose) {
        MESG("\npdf_font>> Type0 font \"%s\"", fontname);
        MESG(" cmap_id=<%s,%d>", mrec->enc_name, font->encoding_id);
        MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
      }
      
    }
  } else {
    /*
     * Simple Font - always embed.
     */
    int  found = 0;
    
    for (font_id = 0;
         font_id < font_cache.count; font_id++) {
      font = GET_FONT(font_id);
      switch (font->subtype) {
        case PDF_FONT_FONTTYPE_TYPE1:
        case PDF_FONT_FONTTYPE_TYPE1C:
        case PDF_FONT_FONTTYPE_TRUETYPE:
          /* fontname here is font file name.
           * We must compare both font file name and encoding
           *
           * TODO: Embed a font only once if it is used
           *       with two different encodings
           */
          if (!strcmp(fontname, font->ident)   &&
              encoding_id == font->encoding_id) {
            if (mrec && mrec->opt.index == font->index)
              found = 1;
          }
          break;
        case PDF_FONT_FONTTYPE_TYPE3:
          /* There shouldn't be any encoding specified for PK font.
           * It must be always font's build-in encoding.
           *
           * TODO: a PK font with two encodings makes no sense. Change?
           */
          if (!strcmp(fontname, font->ident) &&
              font_scale == font->point_size) {
            found = 1;
          }
          break;
        case PDF_FONT_FONTTYPE_TYPE0:
          break;
        default:
          ERROR("Unknown font type: %d", font->subtype);
          break;
      }
      
      if (found) {
        if (__verbose) {
          MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n",
               fontname, encoding_id, font_id);
        }
        break;
      }
    }
    
    
    if (!found) {
      font_id = font_cache.count;
      if (font_cache.count >= font_cache.capacity) {
        font_cache.capacity += CACHE_ALLOC_SIZE;
        font_cache.fonts     = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
      }
      
      font = GET_FONT(font_id);
      
      pdf_init_font_struct(font);
      
      font->point_size  = font_scale;
      font->encoding_id = encoding_id;
      font->ident       = NEW(strlen(fontname) + 1, char);
      strcpy(font->ident, fontname);
      font->map_name    = NEW(strlen(tex_name) + 1, char);
      strcpy(font->map_name, tex_name);
      font->index       = (mrec && mrec->opt.index) ? mrec->opt.index : 0;
      if (font_file) {  
        font->fontfile       = NEW(strlen(font_file) + 1, char);
        strcpy(font->fontfile, font_file);
      }
      if (tfm_file) {
        font->tfmfile       = NEW(strlen(tfm_file) + 1, char);
        strcpy(font->tfmfile, tfm_file);
      }
      if (pdf_font_open_type1(font) >= 0) {
        font->subtype = PDF_FONT_FONTTYPE_TYPE1;
      } else if (pdf_font_open_type1c(font) >= 0) {
        font->subtype = PDF_FONT_FONTTYPE_TYPE1C;
      } else if (pdf_font_open_truetype(font) >= 0) {
        font->subtype = PDF_FONT_FONTTYPE_TRUETYPE;
      } else if (pdf_font_open_pkfont(font) >= 0) {
        font->subtype = PDF_FONT_FONTTYPE_TYPE3;
      } else {
        pdf_clean_font_struct(font);
        return -1;
      }
      
      font_cache.count++;
      
      if (__verbose) {
        MESG("\npdf_font>> Simple font \"%s\"", fontname);
        MESG(" enc_id=<%s,%d>",
             (mrec && mrec->enc_name) ? mrec->enc_name : "builtin", font->encoding_id);
        MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
      }
    }
  }
  
  return  font_id;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_font_physical_old ( const char *  tex_name,
double  font_scale,
const char *  font_file 
)

Definition at line 1027 of file pdffont.c.

{
  int          font_id = -1;
  pdf_font    *font;
  int          encoding_id = -1;
  const char  *fontname;
  
  /*
   * Get appropriate info from map file. (PK fonts at two different
   * point sizes would be looked up twice unecessarily.)
   */
  fontname = tex_name;
  {
    /*
     * Simple Font - always embed.
     */
    int  found = 0;
    
    for (font_id = 0;
         font_id < font_cache.count; font_id++) {
      font = GET_FONT(font_id);
      switch (font->subtype) {
        case PDF_FONT_FONTTYPE_TYPE1:
        case PDF_FONT_FONTTYPE_TYPE1C:
        case PDF_FONT_FONTTYPE_TRUETYPE:
          /* fontname here is font file name.
           * We must compare both font file name and encoding
           *
           * TODO: Embed a font only once if it is used
           *       with two different encodings
           */
          if (!strcmp(fontname, font->ident)   &&
              encoding_id == font->encoding_id) {
              found = 1;
          }
          break;
        case PDF_FONT_FONTTYPE_TYPE3:
          /* There shouldn't be any encoding specified for PK font.
           * It must be always font's build-in encoding.
           *
           * TODO: a PK font with two encodings makes no sense. Change?
           */
          if (!strcmp(fontname, font->ident) &&
              font_scale == font->point_size) {
            found = 1;
          }
          break;
        case PDF_FONT_FONTTYPE_TYPE0:
          break;
        default:
          ERROR("Unknown font type: %d", font->subtype);
          break;
      }
      
      if (found) {
        if (__verbose) {
          MESG("\npdf_font>> Simple font \"%s\" (enc_id=%d) found at id=%d.\n",
               fontname, encoding_id, font_id);
        }
        break;
      }
    }
    
    
    if (!found) {
      font_id = font_cache.count;
      if (font_cache.count >= font_cache.capacity) {
        font_cache.capacity += CACHE_ALLOC_SIZE;
        font_cache.fonts     = RENEW(font_cache.fonts, font_cache.capacity, pdf_font);
      }
      
      font = GET_FONT(font_id);
      
      pdf_init_font_struct(font);
      
      font->point_size  = font_scale;
      font->encoding_id = encoding_id;
      font->ident       = NEW(strlen(fontname) + 1, char);
      strcpy(font->ident, fontname);
      font->map_name    = NEW(strlen(tex_name) + 1, char);
      strcpy(font->map_name, tex_name);
      font->index       = 0;
      
      font->subtype = PDF_FONT_FONTTYPE_TYPE1;

      font->fontfile       = NEW(strlen(font_file) + 1, char);
      strcpy(font->fontfile, font_file);
      
      {
        char    *ident;
        FILE    *fp;
        char     fontname[PDF_NAME_LEN_MAX+1];

        memset(fontname, 0, PDF_NAME_LEN_MAX+1);
        
        fp = MFOPEN(font_file, FOPEN_RBIN_MODE);

        if (!fp || !is_pfb(fp) || t1_get_fontname(fp, fontname) < 0) {
          ERROR("Failed to read Type 1 font \"%s\".", font_file);
          pdf_clean_font_struct(font);
          return -1;
        }
        
        MFCLOSE(fp);
          
        pdf_font_set_fontname(font, fontname);
      }
      
      font_cache.count++;
      
      if (__verbose) {
        MESG("\npdf_font>> Simple font \"%s\"", fontname);
        MESG(" enc_id=<%s,%d>",
              "builtin", font->encoding_id);
        MESG(" opened at font_id=<%s,%d>.\n", tex_name, font_id);
      }
    }
  }
  
  return  font_id;

}

Here is the call graph for this function:

void pdf_font_set_dpi ( int  font_dpi)

Definition at line 85 of file pdffont.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_font_set_flags ( pdf_font font,
int  flags 
)

Definition at line 1351 of file pdffont.c.

{
  ASSERT(font);

  font->flags |= flags;

  return 0;
}

Here is the caller graph for this function:

int pdf_font_set_fontname ( pdf_font font,
const char *  fontname 
)

Definition at line 1323 of file pdffont.c.

{
  ASSERT(font && fontname);

  if (strlen(fontname) > PDF_NAME_LEN_MAX) {
    ERROR("Unexpected error...");
    return -1;
  }
  if (font->fontname) {
    RELEASE(font->fontname);
  }
  font->fontname = NEW(strlen(fontname)+1, char);
  strcpy(font->fontname, fontname);

  return 0;
}

Here is the caller graph for this function:

int pdf_font_set_subtype ( pdf_font font,
int  subtype 
)

Definition at line 1341 of file pdffont.c.

{
  ASSERT(font);

  font->subtype = subtype;

  return 0;
}

Here is the caller graph for this function:

void pdf_font_set_verbose ( void  )

Definition at line 65 of file pdffont.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_get_font_encoding ( int  font_id)

Definition at line 399 of file pdffont.c.

{
  pdf_font *font;

  CHECK_ID(font_id);

  font = GET_FONT(font_id);

  return font->encoding_id;
}

Here is the caller graph for this function:

pdf_obj* pdf_get_font_reference ( int  font_id)

Definition at line 310 of file pdffont.c.

{
  pdf_font  *font;

  CHECK_ID(font_id);

  font = GET_FONT(font_id);
  if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
    Type0Font *t0font;

    t0font = Type0Font_cache_get(font->font_id);
    return Type0Font_get_resource(t0font);
  } else {
    if (!font->reference) {
      font->reference = pdf_ref_obj(pdf_font_get_resource(font));
    }
  }

  return pdf_link_obj(font->reference);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_get_font_subtype ( int  font_id)

Definition at line 372 of file pdffont.c.

{
  pdf_font *font;

  CHECK_ID(font_id);

  font = GET_FONT(font_id);

  return font->subtype;
}

Here is the caller graph for this function:

char* pdf_get_font_usedchars ( int  font_id)

Definition at line 332 of file pdffont.c.

{
  pdf_font *font;

  CHECK_ID(font_id);

  font = GET_FONT(font_id);
  if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
    Type0Font *t0font;

    t0font = Type0Font_cache_get(font->font_id);
    return Type0Font_get_usedchars(t0font);
  } else {
    if (!font->usedchars) {
      font->usedchars = NEW(256, char);
      memset(font->usedchars, 0, 256 * sizeof(char));
    }
    return font->usedchars;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_get_font_wmode ( int  font_id)

Definition at line 354 of file pdffont.c.

{
  pdf_font *font;

  CHECK_ID(font_id);

  font = GET_FONT(font_id);
  if (font->subtype == PDF_FONT_FONTTYPE_TYPE0) {
    Type0Font *t0font;

    t0font = Type0Font_cache_get(font->font_id);
    return Type0Font_get_wmode(t0font);
  } else {
    return 0;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void pdf_init_font_struct ( pdf_font font) [static]

Definition at line 154 of file pdffont.c.

{
  ASSERT(font);

  font->ident    = NULL;
  font->map_name = NULL;
  font->subtype  = -1;
  font->font_id  = -1; /* Type0 ID */
  font->fontname = NULL;
  font->fontfile = NULL;
  font->tfmfile = NULL;
  memset(font->uniqueID, 0, 7);
  font->index    = 0;

  font->encoding_id = -1;

  font->reference   = NULL;
  font->resource    = NULL;
  font->descriptor  = NULL;

  font->point_size  = 0;
  font->design_size = 0;

  font->usedchars   = NULL;
  font->flags       = 0;

  return;
}

Here is the caller graph for this function:

void pdf_init_fonts ( void  )

Definition at line 284 of file pdffont.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static int try_load_ToUnicode_CMap ( pdf_font font) [static]

Definition at line 419 of file pdffont.c.

{
  pdf_obj     *fontdict;
  pdf_obj     *tounicode;
  const char  *cmap_name = NULL;
  fontmap_rec *mrec; /* Be sure fontmap is still alive here */

  ASSERT(font);

  /* We are using different encoding for Type0 font.
   * This feature is unavailable for them.
   */
  if (font->subtype == PDF_FONT_FONTTYPE_TYPE0)
    return  0;

  ASSERT(font->map_name);

  mrec = pdf_lookup_fontmap_record(font->map_name);
  if (MREC_HAS_TOUNICODE(mrec))
    cmap_name = mrec->opt.tounicode;
  else {
    cmap_name = font->map_name;
  }

  fontdict  = pdf_font_get_resource(font);
  tounicode = pdf_load_ToUnicode_stream(cmap_name);
  if (!tounicode && MREC_HAS_TOUNICODE(mrec))
    WARN("Failed to read ToUnicode mapping \"%s\"...", mrec->opt.tounicode);
  else if (tounicode) {
    if (pdf_obj_typeof(tounicode) != PDF_STREAM)
      ERROR("Object returned by pdf_load_ToUnicode_stream() not stream object! (This must be bug)");
    else if (pdf_stream_length(tounicode) > 0) {
      pdf_add_dict(fontdict,
                   pdf_new_name("ToUnicode"),
                   pdf_ref_obj (tounicode)); /* _FIXME_ */
      if (__verbose)
        MESG("pdf_font>> ToUnicode CMap \"%s\" attached to font id=\"%s\".\n",
             cmap_name, font->map_name);
    }
    pdf_release_obj(tounicode);
  }

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

int __verbose = 0 [static]

Definition at line 60 of file pdffont.c.

struct { ... } font_cache [static]