Back to index

texmacs  1.0.7.15
Functions
pkfont.h File Reference
#include "pdffont.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int pdf_font_open_pkfont (pdf_font *font)
int pdf_font_load_pkfont (pdf_font *font)
void PKFont_set_dpi (int dpi)

Function Documentation

int pdf_font_load_pkfont ( pdf_font font)

Definition at line 570 of file pkfont.c.

{
  pdf_obj  *fontdict;
  char     *usedchars;
  char     *ident;
  unsigned  dpi;
  FILE     *fp;
  double    point_size, pix2charu;
  int       opcode, code, firstchar, lastchar, prev;
  pdf_obj  *charprocs, *procset, *encoding, *tmp_array;
  double    widths[256];
  pdf_rect  bbox;
  char      charavail[256];
#if  ENABLE_GLYPHENC
  int       encoding_id;
  char    **enc_vec;
#endif /* ENABLE_GLYPHENC */
  int       error = 0;

  if (!pdf_font_is_in_use(font)) {
    return 0;
  }

  ident       = pdf_font_get_ident(font);
  point_size  = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE);
  usedchars   = pdf_font_get_usedchars(font);
#if  ENABLE_GLYPHENC
  encoding_id = pdf_font_get_encoding(font);
  if (encoding_id < 0)
    enc_vec = NULL;
  else {
    enc_vec = pdf_encoding_get_encoding(encoding_id);
  }
#endif /* ENABLE_GLYPHENC */

  ASSERT(ident && usedchars && point_size > 0.0);

  dpi  = truedpi(ident, point_size, base_dpi);
  
  {
    char *fontfile =   pdf_font_get_fontfile  (font);
    
    if (fontfile)
      fp = MFOPEN(fontfile, FOPEN_RBIN_MODE);
    else
      fp = dpx_open_pk_font_at(ident, dpi);
  }
  
  
  
  if (!fp) {
    ERROR("Could not find/open PK font file: %s (at %udpi)", ident, dpi);
  }

  memset(charavail, 0, 256);
  charprocs  = pdf_new_dict();
  /* Include bitmap as 72dpi image:
   * There seems to be problems in "scaled" bitmap glyph
   * rendering in several viewers.
   */
  pix2charu  = 72. * 1000. / ((double) base_dpi) / point_size;
  bbox.llx = bbox.lly =  HUGE_VAL;
  bbox.urx = bbox.ury = -HUGE_VAL;
  while ((opcode = fgetc(fp)) >= 0 && opcode != PK_POST) {
    if (opcode < 240) {
      struct pk_header_  pkh;

      error = read_pk_char_header(&pkh, opcode, fp);
      if (error)
        ERROR("Error in reading PK character header.");
      else if (charavail[pkh.chrcode & 0xff])
        WARN("More than two bitmap image for single glyph?: font=\"%s\" code=0x%02x",
             ident, pkh.chrcode);

      if (!usedchars[pkh.chrcode & 0xff])
        do_skip(fp, pkh.pkt_len);
      else {
        char          *charname;
        pdf_obj       *charproc;
        unsigned char *pkt_ptr;
        size_t         bytesread;
        double         charwidth;

        /* Charwidth in PDF units */
        charwidth = ROUND(1000.0 * pkh.wd / (((double) (1<<20))*pix2charu), 0.1);
        widths[pkh.chrcode & 0xff] = charwidth;

        /* Update font BBox info */
        bbox.llx = MIN(bbox.llx, -pkh.bm_hoff);
        bbox.lly = MIN(bbox.lly,  pkh.bm_voff - pkh.bm_ht);
        bbox.urx = MAX(bbox.urx,  pkh.bm_wd - pkh.bm_hoff);
        bbox.ury = MAX(bbox.ury,  pkh.bm_voff);

        pkt_ptr = NEW(pkh.pkt_len, unsigned char);
        if ((bytesread = fread(pkt_ptr, 1, pkh.pkt_len, fp))!= pkh.pkt_len) {
          ERROR("Only %ld bytes PK packet read. (expected %ld bytes)",
                bytesread, pkh.pkt_len);
        }
        charproc = create_pk_CharProc_stream(&pkh, charwidth, pkt_ptr, bytesread);
        RELEASE(pkt_ptr);
        if (!charproc)
          ERROR("Unpacking PK character data failed.");
#if  ENABLE_GLYPHENC
        if (encoding_id >= 0 && enc_vec) {
          charname = (char *) enc_vec[pkh.chrcode & 0xff];
          if (!charname) {
            WARN("\".notdef\" glyph used in font (code=0x%02x): %s", pkh.chrcode, ident);
            charname = work_buffer;
            pk_char2name(charname, pkh.chrcode);
          }
        }
        else
#endif /* ENABLE_GLYPHENC */
        {
          charname = work_buffer;
          pk_char2name(charname, pkh.chrcode);
        }

        pdf_add_dict(charprocs, pdf_new_name(charname), pdf_ref_obj(charproc)); /* _FIXME_ */
        pdf_release_obj(charproc);
      }
      charavail[pkh.chrcode & 0xff] = 1;
    } else { /* A command byte */
      switch (opcode) {
      case PK_NO_OP: break;
      case PK_XXX1: do_skip(fp, get_unsigned_byte(fp));   break;
      case PK_XXX2: do_skip(fp, get_unsigned_pair(fp));   break;
      case PK_XXX3: do_skip(fp, get_unsigned_triple(fp)); break;
      case PK_XXX4: do_skip(fp, get_unsigned_quad(fp));   break;
      case PK_YYY:  do_skip(fp, 4);  break;
      case PK_PRE:  do_preamble(fp); break;
      }
    }
  }
  MFCLOSE(fp);

  /* Check if we really got all glyphs needed. */
  for (code = 0; code < 256; code++) {
    if (usedchars[code] && !charavail[code])
      WARN("Missing glyph code=0x%02x in PK font \"%s\".", code, ident);
  }

  /* Now actually fill fontdict. */
  fontdict = pdf_font_get_resource(font);

  pdf_add_dict(fontdict,
               pdf_new_name("CharProcs"), pdf_ref_obj(charprocs));
  pdf_release_obj(charprocs);

  /*
   * Resources:
   *
   *  PDF Reference 4th ed. describes it as "Optional but strongly recommended".
   *  There are no reason to put it in our case, but we will put this.
   *  We do not care about compatibility with Acrobat 2.x. (See implementation
   *  note 47, Appendix H of PDF Ref., 4th ed.).
   */
  procset   = pdf_new_dict();
  tmp_array = pdf_new_array();
  pdf_add_array(tmp_array, pdf_new_name("PDF"));
  pdf_add_array(tmp_array, pdf_new_name("ImageB"));
  pdf_add_dict(procset,
               pdf_new_name("ProcSet"), tmp_array);
  pdf_add_dict(fontdict,
               pdf_new_name("Resources"), procset);

  /* Encoding */
  tmp_array = pdf_new_array();
  prev = -2; firstchar = 255; lastchar = 0;
  for (code = 0; code < 256; code++) {
    char  *charname;
    if (usedchars[code]) {
      if (code < firstchar) firstchar = code;
      if (code > lastchar)  lastchar  = code;
      if (code != prev + 1)
        pdf_add_array(tmp_array, pdf_new_number(code));

#if  ENABLE_GLYPHENC
      if (encoding_id >= 0 && enc_vec) {
        charname = (char *) enc_vec[(unsigned char) code];
        if (!charname) {
          charname = work_buffer;
          pk_char2name(charname, code);
        }
      }
      else
#endif /* ENABLE_GLYPHENC */
      {
        charname = work_buffer;
        pk_char2name(charname, code);
      }
      pdf_add_array(tmp_array, pdf_new_name(charname));
      prev = code;
    }
  }
  if (firstchar > lastchar) {
    ERROR("Unexpected error: firstchar > lastchar (%d %d)",
          firstchar, lastchar);
    pdf_release_obj(tmp_array);
    return  -1;
  }
#if  ENABLE_GLYPHENC
  if (encoding_id < 0 || !enc_vec) {
#else
  if (1) {
#endif /* ENABLE_GLYPHENC */
    encoding  = pdf_new_dict();
    pdf_add_dict(encoding,
               pdf_new_name("Type"), pdf_new_name("Encoding"));
    pdf_add_dict(encoding,
               pdf_new_name("Differences"), tmp_array);
    pdf_add_dict(fontdict,
               pdf_new_name("Encoding"),    pdf_ref_obj(encoding));
    pdf_release_obj(encoding);
  } else
    pdf_release_obj(tmp_array);

  /* FontBBox: Accurate value is important.
   */
  tmp_array = pdf_new_array();
  pdf_add_array(tmp_array, pdf_new_number(bbox.llx));
  pdf_add_array(tmp_array, pdf_new_number(bbox.lly));
  pdf_add_array(tmp_array, pdf_new_number(bbox.urx));
  pdf_add_array(tmp_array, pdf_new_number(bbox.ury));
  pdf_add_dict (fontdict , pdf_new_name("FontBBox"), tmp_array);

  /* Widths:
   *  Indirect reference preffered. (See PDF Reference)
   */
  tmp_array = pdf_new_array();
  for (code = firstchar; code <= lastchar; code++) {
    if (usedchars[code])
      pdf_add_array(tmp_array, pdf_new_number(widths[code]));
    else {
      pdf_add_array(tmp_array, pdf_new_number(0));
    }
  }
  pdf_add_dict(fontdict,
               pdf_new_name("Widths"), pdf_ref_obj(tmp_array));
  pdf_release_obj(tmp_array);

  /* FontMatrix */
  tmp_array = pdf_new_array();
  pdf_add_array(tmp_array, pdf_new_number(0.001 * pix2charu));
  pdf_add_array(tmp_array, pdf_new_number(0.0));
  pdf_add_array(tmp_array, pdf_new_number(0.0));
  pdf_add_array(tmp_array, pdf_new_number(0.001 * pix2charu));
  pdf_add_array(tmp_array, pdf_new_number(0.0));
  pdf_add_array(tmp_array, pdf_new_number(0.0));
  pdf_add_dict (fontdict , pdf_new_name("FontMatrix"), tmp_array);


  pdf_add_dict(fontdict,
               pdf_new_name("FirstChar"), pdf_new_number(firstchar));
  pdf_add_dict(fontdict,
               pdf_new_name("LastChar"),  pdf_new_number(lastchar));

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_font_open_pkfont ( pdf_font font)

Definition at line 112 of file pkfont.c.

{
  char     *ident;
  double    point_size;
  int       encoding_id;
  unsigned  dpi;
  FILE     *fp;

  ident       = pdf_font_get_ident(font);
  point_size  = pdf_font_get_param(font, PDF_FONT_PARAM_POINT_SIZE);
  encoding_id = pdf_font_get_encoding(font);

  if (!ident || point_size <= 0.0)
    return  -1;

  {
    char *fontfile =   pdf_font_get_fontfile  (font);
    char *tfmfile =   pdf_font_get_tfmfile  (font);
    
    if (fontfile)
      fp = MFOPEN(fontfile, FOPEN_RBIN_MODE);
    else
      fp = dpx_open_pk_font_at(ident, dpi);

    if (tfmfile) 
      dpi = truedpi(tfmfile, point_size, base_dpi);
    else 
      dpi = base_dpi;
  
  }
  
  if (!fp)
    return  -1;
  MFCLOSE(fp);

  /* Type 3 fonts doesn't have FontName.
   * FontFamily is recommended for PDF 1.5.
   */
  pdf_font_set_fontname(font, ident);

  if (encoding_id >= 0) {
    pdf_encoding_used_by_type3(encoding_id);
    WARN("PK font is found for font \"%s\" but non built-in encoding \"%s\" is specified.",
         ident, pdf_encoding_get_name(encoding_id));
#if  ENABLE_GLYPHENC
    WARN(">> Assuming this is for glyph name assignment.");
#else
    WARN(">> I can't reencode PK font. (not enough information available)");
    WARN(">> Maybe you need to install pfb/opentype/truetype font.");
#endif
  }

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PKFont_set_dpi ( int  dpi)

Definition at line 55 of file pkfont.c.

{
  if (dpi <= 0)
    ERROR("Invalid DPI: %d\n", dpi);
  base_dpi = dpi;
}

Here is the caller graph for this function: