Back to index

texmacs  1.0.7.15
Classes | Defines | Functions | Variables
pdfdev.c File Reference
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "system.h"
#include "mem.h"
#include "error.h"
#include "mfileio.h"
#include "numbers.h"
#include "pdfdoc.h"
#include "pdfobj.h"
#include "pdffont.h"
#include "fontmap.h"
#include "cmap.h"
#include "pdfximage.h"
#include "pdfdraw.h"
#include "pdfcolor.h"
#include "pdflimits.h"
#include "pdfdev.h"

Go to the source code of this file.

Classes

struct  dev_font
struct  .matrix

Defines

#define TEX_ONE_HUNDRED_BP   6578176
#define DEV_PRECISION_MAX   8
#define bpt2spt(b)   ( (spt_t) round( (b) / dev_unit.dvi2pts ) )
#define spt2bpt(s)   ( (s) * dev_unit.dvi2pts )
#define dround_at(v, p)   (ROUND( (v), ten_pow_inv[(p)] ))
#define GRAPHICS_MODE   1
#define TEXT_MODE   2
#define STRING_MODE   3
#define FORMAT_BUF_SIZE   4096
#define TEXT_WMODE_HH   0
#define TEXT_WMODE_HV   1
#define TEXT_WMODE_VH   2
#define TEXT_WMODE_VV   3
#define ANGLE_CHANGES(m1, m2)   ((abs((m1)-(m2)) % 3) == 0 ? 0 : 1)
#define ROTATE_TEXT(m)   ((m) != TEXT_WMODE_HH && (m) != TEXT_WMODE_VV)
#define PDF_FONTTYPE_SIMPLE   1
#define PDF_FONTTYPE_BITMAP   2
#define PDF_FONTTYPE_COMPOSITE   3
#define CURRENTFONT()   ((text_state.font_id < 0) ? NULL : &(dev_fonts[text_state.font_id]))
#define GET_FONT(n)   (&(dev_fonts[(n)]))
#define WORD_SPACE_MAX(f)   (spt_t) (3.0 * (f)->extend * (f)->sptsize)
#define WORD_SPACE_MAX(f)   (spt_t) (3.0 * (f)->extend * (f)->sptsize)
#define PDF_LINE_THICKNESS_MAX   5.0

Functions

void pdf_dev_set_verbose (void)
double pdf_dev_scale (void)
double dev_unit_dviunit (void)
static int p_itoa (long value, char *buf)
static int p_dtoa (double value, int prec, char *buf)
static int dev_sprint_bp (char *buf, spt_t value, spt_t *error)
int pdf_sprint_matrix (char *buf, const pdf_tmatrix *M)
int pdf_sprint_rect (char *buf, const pdf_rect *rect)
int pdf_sprint_coord (char *buf, const pdf_coord *p)
int pdf_sprint_length (char *buf, double value)
int pdf_sprint_number (char *buf, double value)
static void dev_set_text_matrix (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
static void reset_text_state (void)
static void text_mode (void)
void graphics_mode (void)
static void start_string (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
static void string_mode (spt_t xpos, spt_t ypos, double slant, double extend, int rotate)
static int dev_set_font (int font_id)
int pdf_dev_get_font_wmode (int font_id)
static int handle_multibyte_string (struct dev_font *font, unsigned char **str_ptr, int *str_len, int ctype)
void pdf_dev_get_coord (double *xpos, double *ypos)
void pdf_dev_push_coord (double xpos, double ypos)
void pdf_dev_pop_coord (void)
spt_t pdf_dev_string_width (int font_id, unsigned char *str, unsigned len)
void pdf_dev_set_string (spt_t xpos, spt_t ypos, const void *instr_ptr, int instr_len, spt_t width, int font_id, int ctype)
void pdf_dev_set_raw_glyph (spt_t xpos, spt_t ypos, unsigned char glyph, int font_id)
void pdf_init_device (double dvi2pts, int precision, int black_and_white)
void pdf_close_device (void)
void pdf_dev_reset_fonts (void)
void pdf_dev_bop (const pdf_tmatrix *M)
void pdf_dev_eop (void)
static void print_fontmap (const char *font_name, fontmap_rec *mrec)
int pdf_dev_locate_font (const char *font_name, spt_t ptsize)
int pdf_dev_physical_font (const char *font_name, spt_t ptsize, const char *font_file, const char *tfm_file)
static int dev_sprint_line (char *buf, spt_t width, spt_t p0_x, spt_t p0_y, spt_t p1_x, spt_t p1_y)
void pdf_dev_set_rule (spt_t xpos, spt_t ypos, spt_t width, spt_t height)
void pdf_dev_set_rect (pdf_rect *rect, spt_t x_user, spt_t y_user, spt_t width, spt_t height, spt_t depth)
int pdf_dev_get_dirmode (void)
void pdf_dev_set_dirmode (int text_dir)
static void dev_set_param_autorotate (int auto_rotate)
int pdf_dev_get_param (int param_type)
void pdf_dev_set_param (int param_type, int value)
int pdf_dev_put_image (int id, transform_info *p, double ref_x, double ref_y)
void transform_info_clear (transform_info *info)

Variables

static int verbose = 0
struct {
double dvi2pts
long min_bp_val
int precision
dev_unit
static unsigned long ten_pow [10]
static double ten_pow_inv [10]
struct {
int autorotate
int colormode
dev_param
static int motion_state = GRAPHICS_MODE
static char format_buffer [FORMAT_BUF_SIZE]
struct {
int font_id
spt_t offset
spt_t ref_x
spt_t ref_y
spt_t raise
spt_t leading
struct .matrix matrix
double bold_param
int dir_mode
int force_reset
int is_mb
text_state
static struct dev_fontdev_fonts = NULL
static int num_dev_fonts = 0
static int max_dev_fonts = 0
static int num_phys_fonts = 0
static unsigned char sbuf0 [FORMAT_BUF_SIZE]
static unsigned char sbuf1 [FORMAT_BUF_SIZE]
static pdf_coorddev_coords = NULL
static int num_dev_coords = 0
static int max_dev_coords = 0

Class Documentation

struct dev_font

Definition at line 431 of file pdfdev.c.

Collaboration diagram for dev_font:
Class Members
double bold
int enc_id
double extend
int font_id
int format
int is_unicode
int mapc
pdf_obj * resource
char short_name
double slant
spt_t sptsize
char * tex_name
int tfm_id
int ucs_group
int ucs_plane
char * used_chars
int used_on_this_page
int wmode
struct .matrix

Definition at line 382 of file pdfdev.c.

Class Members
double extend
int rotate
double slant

Define Documentation

#define ANGLE_CHANGES (   m1,
  m2 
)    ((abs((m1)-(m2)) % 3) == 0 ? 0 : 1)

Definition at line 347 of file pdfdev.c.

#define bpt2spt (   b)    ( (spt_t) round( (b) / dev_unit.dvi2pts ) )

Definition at line 101 of file pdfdev.c.

#define CURRENTFONT ( )    ((text_state.font_id < 0) ? NULL : &(dev_fonts[text_state.font_id]))

Definition at line 498 of file pdfdev.c.

#define DEV_PRECISION_MAX   8

Definition at line 92 of file pdfdev.c.

#define dround_at (   v,
 
)    (ROUND( (v), ten_pow_inv[(p)] ))

Definition at line 103 of file pdfdev.c.

#define FORMAT_BUF_SIZE   4096

Definition at line 327 of file pdfdev.c.

#define GET_FONT (   n)    (&(dev_fonts[(n)]))

Definition at line 499 of file pdfdev.c.

#define GRAPHICS_MODE   1

Definition at line 321 of file pdfdev.c.

#define PDF_FONTTYPE_BITMAP   2

Definition at line 428 of file pdfdev.c.

#define PDF_FONTTYPE_COMPOSITE   3

Definition at line 429 of file pdfdev.c.

#define PDF_FONTTYPE_SIMPLE   1

Definition at line 427 of file pdfdev.c.

#define PDF_LINE_THICKNESS_MAX   5.0

Definition at line 1718 of file pdfdev.c.

#define ROTATE_TEXT (   m)    ((m) != TEXT_WMODE_HH && (m) != TEXT_WMODE_VV)

Definition at line 348 of file pdfdev.c.

#define spt2bpt (   s)    ( (s) * dev_unit.dvi2pts )

Definition at line 102 of file pdfdev.c.

#define STRING_MODE   3

Definition at line 323 of file pdfdev.c.

#define TEX_ONE_HUNDRED_BP   6578176

Definition at line 74 of file pdfdev.c.

#define TEXT_MODE   2

Definition at line 322 of file pdfdev.c.

#define TEXT_WMODE_HH   0

Definition at line 342 of file pdfdev.c.

#define TEXT_WMODE_HV   1

Definition at line 343 of file pdfdev.c.

#define TEXT_WMODE_VH   2

Definition at line 344 of file pdfdev.c.

#define TEXT_WMODE_VV   3

Definition at line 345 of file pdfdev.c.

#define WORD_SPACE_MAX (   f)    (spt_t) (3.0 * (f)->extend * (f)->sptsize)
#define WORD_SPACE_MAX (   f)    (spt_t) (3.0 * (f)->extend * (f)->sptsize)

Function Documentation

static int dev_set_font ( int  font_id) [static]

Definition at line 785 of file pdfdev.c.

{
  struct dev_font *font;
  int    text_rotate;
  double font_scale;
  int    len;
  int    vert_dir, vert_font;

  /* text_mode() must come before text_state.is_mb is changed. */
  text_mode();

  font = GET_FONT(font_id);
  ASSERT(font); /* Caller should check font_id. */

  text_state.is_mb = (font->format == PDF_FONTTYPE_COMPOSITE) ? 1 : 0;

  vert_font  = font->wmode ? 1 : 0;
  if (dev_param.autorotate) {
    vert_dir = text_state.dir_mode ? 1 : 0;
  } else {
    vert_dir = vert_font;
  }
  text_rotate = (vert_font << 1)|vert_dir;

  if (font->slant  != text_state.matrix.slant  ||
      font->extend != text_state.matrix.extend ||
      ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) {
    text_state.force_reset = 1;
  }
  text_state.matrix.slant  = font->slant;
  text_state.matrix.extend = font->extend;
  text_state.matrix.rotate = text_rotate;

  if (!font->resource) {
    font->resource   = pdf_get_font_reference(font->font_id);
    font->used_chars = pdf_get_font_usedchars(font->font_id);
  }

  if (!font->used_on_this_page) { 
    pdf_doc_add_page_resource("Font",
                              font->short_name,
                              pdf_link_obj(font->resource));
    font->used_on_this_page = 1;
  }

  font_scale = (double) font->sptsize * dev_unit.dvi2pts;
  len  = sprintf(format_buffer, " /%s", font->short_name); /* space not necessary. */
  format_buffer[len++] = ' ';
  len += p_dtoa(font_scale, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), format_buffer+len);
  format_buffer[len++] = ' ';
  format_buffer[len++] = 'T';
  format_buffer[len++] = 'f';
  pdf_doc_add_page_content(format_buffer, len);  /* op: Tf */

  if (font->bold > 0.0 || font->bold != text_state.bold_param) {
    if (font->bold <= 0.0)
      len = sprintf(format_buffer, " 0 Tr");
    else
      len = sprintf(format_buffer, " 2 Tr %.2f w", font->bold); /* _FIXME_ */
    pdf_doc_add_page_content(format_buffer, len);  /* op: Tr w */
  }
  text_state.bold_param = font->bold;

  text_state.font_id    = font_id;

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dev_set_param_autorotate ( int  auto_rotate) [static]

Definition at line 1880 of file pdfdev.c.

{
  struct dev_font *font;
  int    text_rotate, vert_font, vert_dir;

  font = CURRENTFONT();

  vert_font = (font && font->wmode) ? 1 : 0;
  if (auto_rotate) {
    vert_dir = text_state.dir_mode ? 1 : 0;
  } else {
    vert_dir = vert_font;
  }
  text_rotate = (vert_font << 1)|vert_dir;

  if (ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) {
    text_state.force_reset = 1;
  }
  text_state.matrix.rotate = text_rotate;
  dev_param.autorotate     = auto_rotate;
}

Here is the caller graph for this function:

static void dev_set_text_matrix ( spt_t  xpos,
spt_t  ypos,
double  slant,
double  extend,
int  rotate 
) [static]

Definition at line 503 of file pdfdev.c.

{
  pdf_tmatrix tm;
  int         len = 0;

  /* slant is negated for vertical font so that right-side
   * is always lower. */
  switch (rotate) {
  case TEXT_WMODE_VH:
    /* Vertical font */
    tm.a =  slant ;   tm.b =  1.0;
    tm.c = -extend;   tm.d =  0.0   ;
    break;
  case TEXT_WMODE_HV:
    /* Horizontal font */
    tm.a =  0.0;    tm.b = -extend;
    tm.c =  1.0;    tm.d = -slant ;
    break;
  case TEXT_WMODE_HH:
    /* Horizontal font */
    tm.a =  extend; tm.b =  0.0;
    tm.c =  slant ; tm.d =  1.0;
    break;
  case TEXT_WMODE_VV:
    /* Vertical font */
    tm.a =  1.0; tm.b =  -slant;
    tm.c =  0.0; tm.d =   extend;
    break;
  }
  tm.e = xpos * dev_unit.dvi2pts;
  tm.f = ypos * dev_unit.dvi2pts;

  format_buffer[len++] = ' ';
  len += pdf_sprint_matrix(format_buffer+len, &tm);
  format_buffer[len++] = ' ';
  format_buffer[len++] = 'T';
  format_buffer[len++] = 'm';

  pdf_doc_add_page_content(format_buffer, len);  /* op: Tm */

  text_state.ref_x = xpos;
  text_state.ref_y = ypos;
  text_state.matrix.slant  = slant;
  text_state.matrix.extend = extend;
  text_state.matrix.rotate = rotate;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int dev_sprint_bp ( char *  buf,
spt_t  value,
spt_t error 
) [static]

Definition at line 199 of file pdfdev.c.

{
  double  value_in_bp;
  double  error_in_bp;
  int     prec = dev_unit.precision;

  value_in_bp = spt2bpt(value);
  if (error) {
    error_in_bp = value_in_bp - dround_at(value_in_bp, prec);
    *error = bpt2spt(error_in_bp);
  }

  return  p_dtoa(value_in_bp, prec, buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int dev_sprint_line ( char *  buf,
spt_t  width,
spt_t  p0_x,
spt_t  p0_y,
spt_t  p1_x,
spt_t  p1_y 
) [static]

Definition at line 1688 of file pdfdev.c.

{
  int    len = 0;
  double w;

  w = width * dev_unit.dvi2pts;

  len += p_dtoa(w, MIN(dev_unit.precision+1, DEV_PRECISION_MAX), buf+len);
  buf[len++] = ' ';
  buf[len++] = 'w';
  buf[len++] = ' ';
  len += dev_sprint_bp(buf+len, p0_x, NULL);
  buf[len++] = ' ';
  len += dev_sprint_bp(buf+len, p0_y, NULL);
  buf[len++] = ' ';
  buf[len++] = 'm';
  buf[len++] = ' ';
  len += dev_sprint_bp(buf+len, p1_x, NULL);
  buf[len++] = ' ';
  len += dev_sprint_bp(buf+len, p1_y, NULL);
  buf[len++] = ' ';
  buf[len++] = 'l';
  buf[len++] = ' ';
  buf[len++] = 'S';

  return len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

double dev_unit_dviunit ( void  )

Definition at line 87 of file pdfdev.c.

{
  return (1.0/dev_unit.dvi2pts);
}
void graphics_mode ( void  )

Definition at line 600 of file pdfdev.c.

{
  switch (motion_state) {
  case GRAPHICS_MODE:
    break;
  case STRING_MODE:
    pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4);  /* op: TJ */
    /* continue */
  case TEXT_MODE:
    pdf_doc_add_page_content(" ET", 3);  /* op: ET */
    text_state.force_reset =  0;
    text_state.font_id     = -1;
    break;
  }
  motion_state = GRAPHICS_MODE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int handle_multibyte_string ( struct dev_font font,
unsigned char **  str_ptr,
int *  str_len,
int  ctype 
) [static]

Definition at line 894 of file pdfdev.c.

{
  unsigned char *p;
  int            i, length;

  p      = *str_ptr;
  length = *str_len;

  /* _FIXME_ */
  if (font->is_unicode) { /* UCS-4 */
    if (ctype == 1) {
      if (length * 4 >= FORMAT_BUF_SIZE) {
        WARN("Too long string...");
        return -1;
      }
      for (i = 0; i < length; i++) {
        sbuf1[i*4  ] = font->ucs_group;
        sbuf1[i*4+1] = font->ucs_plane;
        sbuf1[i*4+2] = '\0';
        sbuf1[i*4+3] = p[i];
      }
      length *= 4;
    } else if (ctype == 2) {
      if (length * 2 >= FORMAT_BUF_SIZE) {
        WARN("Too long string...");
        return -1;
      }
      for (i = 0; i < length; i += 2) {
        sbuf1[i*2  ] = font->ucs_group;
        sbuf1[i*2+1] = font->ucs_plane;
        sbuf1[i*2+2] = p[i];
        sbuf1[i*2+3] = p[i+1];
      }
      length *= 2;
    }
    p = sbuf1;
  } else if (ctype == 1 && font->mapc >= 0) {
    /* Omega workaround...
     * Translate single-byte chars to double byte code space.
     */
    if (length * 2 >= FORMAT_BUF_SIZE) {
      WARN("Too long string...");
      return -1;
    }
    for (i = 0; i < length; i++) {
      sbuf1[i*2  ] = (font->mapc & 0xff);
      sbuf1[i*2+1] = p[i];
    }
    length *= 2;
    p       = sbuf1;
  }

  /*
   * Font is double-byte font. Output is assumed to be 16-bit fixed length
   * encoding.
   * TODO: A character decomposed to multiple characters.
   */
  if (font->enc_id >= 0) {
    unsigned char *inbuf, *outbuf;
    long           inbytesleft, outbytesleft;
    CMap          *cmap;

    cmap         = CMap_cache_get(font->enc_id);
    inbuf        = p;
    outbuf       = sbuf0;
    inbytesleft  = length;
    outbytesleft = FORMAT_BUF_SIZE;

    CMap_decode(cmap,
                (const unsigned char **) &inbuf, &inbytesleft, &outbuf, &outbytesleft);
    if (inbytesleft != 0) {
      WARN("CMap conversion failed. (%d bytes remains)", inbytesleft);
      return -1;
    }
    length  = FORMAT_BUF_SIZE - outbytesleft;
    p       = sbuf0;
  }

  *str_ptr = p;
  *str_len = length;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int p_dtoa ( double  value,
int  prec,
char *  buf 
) [static]

Definition at line 143 of file pdfdev.c.

{
  const long p[10] = { 1, 10, 100, 1000, 10000,
                     100000, 1000000, 10000000, 100000000, 1000000000 };
  long i, f;
  char *c = buf;
  int n;

  if (value < 0) {
    value = -value;
    *c++ = '-';
    n = 1;
  } else
    n = 0;

  i = (long) value;
  f = (long) ((value-i)*p[prec] + 0.5);

  if (f == p[prec]) {
    f = 0;
    i++;
  }

  if (i) {
    int m = p_itoa(i, c);
    c += m;
    n += m;
  } else if (!f) {
    *(c = buf) = '0';
    n = 1;
  }

  if (f) {
    int j = prec;

    *c++ = '.';

    while (j--) {
      c[j] = (f % 10) + '0';
      f /= 10;
    }
    c += prec-1;
    n += 1+prec;

    while (*c == '0') {
      c--;
      n--;
    }
  }

  *(++c) = 0;

  return n;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int p_itoa ( long  value,
char *  buf 
) [static]

Definition at line 106 of file pdfdev.c.

{
  int   sign, ndigits;
  char *p = buf;

  if (value < 0) {
    *p++  = '-';
    value = -value;
    sign  = 1;
  } else {
    sign  = 0;
  }

  ndigits = 0;
  /* Generate at least one digit in reverse order */
  do {
    p[ndigits++] = (value % 10) + '0';
    value /= 10;
  } while (value != 0);

  /* Reverse the digits */
  {
    int i;

    for (i = 0; i < ndigits / 2 ; i++) {
      char tmp = p[i];
      p[i] = p[ndigits-i-1];
      p[ndigits-i-1] = tmp;
    }
  }
  p[ndigits] = '\0';

  return  (sign ? ndigits + 1 : ndigits);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_close_device ( void  )

Definition at line 1333 of file pdfdev.c.

{
  if (dev_fonts) {
    int    i;

    for (i = 0; i < num_dev_fonts; i++) {
      if (dev_fonts[i].tex_name)
        RELEASE(dev_fonts[i].tex_name);
      if (dev_fonts[i].resource)
        pdf_release_obj(dev_fonts[i].resource);
      dev_fonts[i].tex_name = NULL;
      dev_fonts[i].resource = NULL;
    }
    RELEASE(dev_fonts);
  }
  if (dev_coords) RELEASE(dev_coords);
  pdf_dev_clear_gstates();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_bop ( const pdf_tmatrix M)

Definition at line 1395 of file pdfdev.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_eop ( void  )

Definition at line 1409 of file pdfdev.c.

{
  int  depth;

  graphics_mode();

  depth = pdf_dev_current_depth();
  if (depth != 1) {
    WARN("Unbalenced q/Q nesting...: %d", depth);
    pdf_dev_grestore_to(0);
  } else {
    pdf_dev_grestore();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_get_coord ( double *  xpos,
double *  ypos 
)

Definition at line 983 of file pdfdev.c.

{
  if (num_dev_coords > 0) {
    *xpos = dev_coords[num_dev_coords-1].x;
    *ypos = dev_coords[num_dev_coords-1].y;
  } else {
    *xpos = *ypos = 0.0;
  }
}

Here is the caller graph for this function:

int pdf_dev_get_dirmode ( void  )

Definition at line 1848 of file pdfdev.c.

{
  return text_state.dir_mode;
}
int pdf_dev_get_font_wmode ( int  font_id)

Definition at line 878 of file pdfdev.c.

{
  struct dev_font *font;

  font = GET_FONT(font_id);
  if (font) {
    return font->wmode;
  }

  return 0;
}
int pdf_dev_get_param ( int  param_type)

Definition at line 1903 of file pdfdev.c.

{
  int value = 0;

  switch (param_type) {
  case PDF_DEV_PARAM_AUTOROTATE:
    value = dev_param.autorotate;
    break;
  case PDF_DEV_PARAM_COLORMODE:
    value = dev_param.colormode;
    break;
  default:
    ERROR("Unknown device parameter: %d", param_type);
  }

  return value;
}

Here is the caller graph for this function:

int pdf_dev_locate_font ( const char *  font_name,
spt_t  ptsize 
)

Definition at line 1471 of file pdfdev.c.

{
  int              i;
  fontmap_rec     *mrec;
  struct dev_font *font;

  if (!font_name)
    return  -1;

  if (ptsize == 0) {
    ERROR("pdf_dev_locate_font() called with the zero ptsize.");
    return -1;
  }

  for (i = 0; i < num_dev_fonts; i++) {
    if (!strcmp(font_name, dev_fonts[i].tex_name) && ptsize == dev_fonts[i].sptsize) {
      return  i;
    }
  }

  /*
   * Make sure we have room for a new one, even though we may not
   * actually create one.
   */
  if (num_dev_fonts >= max_dev_fonts) {
    max_dev_fonts += 16;
    dev_fonts      = RENEW(dev_fonts, max_dev_fonts, struct dev_font);
  }

  font = &dev_fonts[num_dev_fonts];

  /* New font */
  mrec = pdf_lookup_fontmap_record(font_name);

  if (verbose > 1)
    print_fontmap(font_name, mrec);

  font->font_id = pdf_font_findresource(font_name, ptsize * dev_unit.dvi2pts, mrec);
  if (font->font_id < 0)
    return  -1;

  /* We found device font here. */
  font->short_name[0] = 'F';
  p_itoa(num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */
  num_phys_fonts++;

  font->used_on_this_page = 0;

  font->tex_name = NEW(strlen(font_name) + 1, char);
  strcpy(font->tex_name, font_name);
  font->sptsize  = ptsize;

  switch (pdf_get_font_subtype(font->font_id)) {
  case PDF_FONT_FONTTYPE_TYPE3:
    font->format = PDF_FONTTYPE_BITMAP;
    break;
  case PDF_FONT_FONTTYPE_TYPE0:
    font->format = PDF_FONTTYPE_COMPOSITE;
    break;
  default:
    font->format = PDF_FONTTYPE_SIMPLE;
    break;
  }

  font->wmode      = pdf_get_font_wmode   (font->font_id);
  font->enc_id     = pdf_get_font_encoding(font->font_id);

  font->resource   = NULL; /* Don't ref obj until font is actually used. */  
  font->used_chars = NULL;

  font->extend     = 1.0;
  font->slant      = 0.0;
  font->bold       = 0.0;
  font->mapc       = -1;
  font->is_unicode = 0;
  font->ucs_group  = 0;
  font->ucs_plane  = 0;

  if (mrec) {
    font->extend = mrec->opt.extend;
    font->slant  = mrec->opt.slant;
    font->bold   = mrec->opt.bold;
    if (mrec->opt.mapc >= 0)
      font->mapc = (mrec->opt.mapc >> 8) & 0xff;
    else {
      font->mapc = -1;
    }
    if (mrec->enc_name &&
        !strcmp(mrec->enc_name, "unicode")) {
      font->is_unicode   = 1;
      if (mrec->opt.mapc >= 0) {
        font->ucs_group  = (mrec->opt.mapc >> 24) & 0xff;
        font->ucs_plane  = (mrec->opt.mapc >> 16) & 0xff;
      } else {
        font->ucs_group  = 0;
        font->ucs_plane  = 0;
      }
    } else {
      font->is_unicode   = 0;
    }
  }

  return  num_dev_fonts++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_physical_font ( const char *  font_name,
spt_t  ptsize,
const char *  font_file,
const char *  tfm_file 
)

Definition at line 1577 of file pdfdev.c.

{
  int              i;
  fontmap_rec     *mrec = NULL;
  struct dev_font *font;
  
  if (!font_name)
    return  -1;
  
  if (ptsize == 0) {
    ERROR("pdf_dev_physical_font() called with the zero ptsize.");
    return -1;
  }
  
  for (i = 0; i < num_dev_fonts; i++) {
    if (!strcmp(font_name, dev_fonts[i].tex_name) && ptsize == dev_fonts[i].sptsize) {
      return  i;
    }
  }
  
  /*
   * Make sure we have room for a new one, even though we may not
   * actually create one.
   */
  if (num_dev_fonts >= max_dev_fonts) {
    max_dev_fonts += 16;
    dev_fonts      = RENEW(dev_fonts, max_dev_fonts, struct dev_font);
  }
  
  font = &dev_fonts[num_dev_fonts];
  
  /* New font */
//  mrec = pdf_lookup_fontmap_record(font_name);
  
  if (verbose > 1)
    print_fontmap(font_name, mrec);
  
  font->font_id = pdf_font_physical(font_name, ptsize * dev_unit.dvi2pts, font_file, tfm_file);
  if (font->font_id < 0)
    return  -1;
  
  /* We found device font here. */
  font->short_name[0] = 'F';
  p_itoa(num_phys_fonts + 1, &font->short_name[1]); /* NULL terminated here */
  num_phys_fonts++;
  
  font->used_on_this_page = 0;
  
  font->tex_name = NEW(strlen(font_name) + 1, char);
  strcpy(font->tex_name, font_name);
  font->sptsize  = ptsize;
  
  switch (pdf_get_font_subtype(font->font_id)) {
    case PDF_FONT_FONTTYPE_TYPE3:
      font->format = PDF_FONTTYPE_BITMAP;
      break;
    case PDF_FONT_FONTTYPE_TYPE0:
      font->format = PDF_FONTTYPE_COMPOSITE;
      break;
    default:
      font->format = PDF_FONTTYPE_SIMPLE;
      break;
  }
  
  font->wmode      = pdf_get_font_wmode   (font->font_id);
  font->enc_id     = pdf_get_font_encoding(font->font_id);
  
  font->resource   = NULL; /* Don't ref obj until font is actually used. */  
  font->used_chars = NULL;
  
  font->extend     = 1.0;
  font->slant      = 0.0;
  font->bold       = 0.0;
  font->mapc       = -1;
  font->is_unicode = 0;
  font->ucs_group  = 0;
  font->ucs_plane  = 0;
  
  font->tfm_id = (tfm_file ? tfm_open(tfm_file, 1) : -1);
  
  if (mrec) {
    font->extend = mrec->opt.extend;
    font->slant  = mrec->opt.slant;
    font->bold   = mrec->opt.bold;
    if (mrec->opt.mapc >= 0)
      font->mapc = (mrec->opt.mapc >> 8) & 0xff;
    else {
      font->mapc = -1;
    }
    if (mrec->enc_name &&
        !strcmp(mrec->enc_name, "unicode")) {
      font->is_unicode   = 1;
      if (mrec->opt.mapc >= 0) {
        font->ucs_group  = (mrec->opt.mapc >> 24) & 0xff;
        font->ucs_plane  = (mrec->opt.mapc >> 16) & 0xff;
      } else {
        font->ucs_group  = 0;
        font->ucs_plane  = 0;
      }
    } else {
      font->is_unicode   = 0;
    }
  }
  
  return  num_dev_fonts++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_pop_coord ( void  )

Definition at line 1004 of file pdfdev.c.

void pdf_dev_push_coord ( double  xpos,
double  ypos 
)
int pdf_dev_put_image ( int  id,
transform_info p,
double  ref_x,
double  ref_y 
)

Definition at line 1940 of file pdfdev.c.

{
  char        *res_name;
  pdf_tmatrix  M, M1;
  pdf_rect     r;
  int          len = 0;

  if (num_dev_coords > 0) {
    ref_x -= dev_coords[num_dev_coords-1].x;
    ref_y -= dev_coords[num_dev_coords-1].y;
  }

  pdf_copymatrix(&M, &(p->matrix));
  M.e += ref_x; M.f += ref_y;
  /* Just rotate by -90, but not tested yet. Any problem if M has scaling? */
  if (dev_param.autorotate &&
      text_state.dir_mode) {
    double tmp;
    tmp = -M.a; M.a = M.b; M.b = tmp;
    tmp = -M.c; M.c = M.d; M.d = tmp;
  }

  graphics_mode();
  pdf_dev_gsave();

  pdf_ximage_scale_image(id, &M1, &r, p);
  pdf_concatmatrix(&M, &M1);
  pdf_dev_concat(&M);

  /* Clip */
  if (p->flags & INFO_DO_CLIP) {
#if  0
    pdf_dev_newpath();
    pdf_dev_moveto(r.llx, r.lly);
    pdf_dev_lineto(r.urx, r.lly);
    pdf_dev_lineto(r.urx, r.ury);
    pdf_dev_lineto(r.llx, r.ury);
    pdf_dev_closepath();
    pdf_dev_clip();
    pdf_dev_newpath();
#else
    pdf_dev_rectclip(r.llx, r.lly, r.urx - r.llx, r.ury - r.lly);
#endif
  }

  res_name = pdf_ximage_get_resname(id);
  len = sprintf(work_buffer, " /%s Do", res_name);
  pdf_doc_add_page_content(work_buffer, len);  /* op: Do */

  pdf_dev_grestore();

  pdf_doc_add_page_resource("XObject",
                            res_name,
                            pdf_ximage_get_reference(id));

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_reset_fonts ( void  )

Definition at line 1358 of file pdfdev.c.

{
  int  i;

  for (i = 0; i < num_dev_fonts; i++) {
    dev_fonts[i].used_on_this_page = 0;
  }

  text_state.font_id       = -1;

  text_state.matrix.slant  = 0.0;
  text_state.matrix.extend = 1.0;
  text_state.matrix.rotate = TEXT_WMODE_HH;

  text_state.bold_param    = 0.0;

  text_state.is_mb         = 0;
}

Here is the caller graph for this function:

double pdf_dev_scale ( void  )

Definition at line 65 of file pdfdev.c.

{
  return 1.0;
}
void pdf_dev_set_dirmode ( int  text_dir)

Definition at line 1854 of file pdfdev.c.

{
  struct dev_font *font;
  int text_rotate;
  int vert_dir, vert_font;

  font = CURRENTFONT();

  vert_font = (font && font->wmode) ? 1 : 0;
  if (dev_param.autorotate) {
    vert_dir = text_dir ? 1 : 0;
  } else {
    vert_dir = vert_font;
  }
  text_rotate = (vert_font << 1)|vert_dir;

  if (font &&
      ANGLE_CHANGES(text_rotate, text_state.matrix.rotate)) {
    text_state.force_reset = 1;
  }

  text_state.matrix.rotate = text_rotate;
  text_state.dir_mode      = text_dir;
}
void pdf_dev_set_param ( int  param_type,
int  value 
)

Definition at line 1922 of file pdfdev.c.

{
  switch (param_type) {
  case PDF_DEV_PARAM_AUTOROTATE:
    dev_set_param_autorotate(value);
    break;
  case PDF_DEV_PARAM_COLORMODE:
    dev_param.colormode = value; /* 0 for B&W */
    break;
  default:
    ERROR("Unknown device parameter: %d", param_type);
  }

  return;
}

Here is the call graph for this function:

void pdf_dev_set_raw_glyph ( spt_t  xpos,
spt_t  ypos,
unsigned char  glyph,
int  font_id 
)

Definition at line 1177 of file pdfdev.c.

{
  struct dev_font *font;
  int              i, len = 0;
  spt_t            kern, delh, delv;
  spt_t            text_xorigin;
  spt_t            text_yorigin;
  
  if (font_id < 0 || font_id >= num_dev_fonts) {
    ERROR("Invalid font: %d (%d)", font_id, num_dev_fonts);
    return;
  }
  if (font_id != text_state.font_id) {
    dev_set_font(font_id);
  }
  
  font = CURRENTFONT();
  if (!font) {
    ERROR("Currentfont not set.");
    return;
  }
  
  text_xorigin = text_state.ref_x;
  text_yorigin = text_state.ref_y;
  
  if (font->format == PDF_FONTTYPE_COMPOSITE) {
    ERROR("This should not happen...");
    return;
  } else {
    if (font->used_chars != NULL) {
          font->used_chars[glyph] = 1;
    }
  }
  
  if (num_dev_coords > 0) {
    xpos -= bpt2spt(dev_coords[num_dev_coords-1].x);
    ypos -= bpt2spt(dev_coords[num_dev_coords-1].y);
  }
  
  /*
   * Kern is in units of character units, i.e., 1000 = 1 em.
   *
   * Positive kern means kerning (reduce excess white space).
   *
   * The following formula is of the form a*x/b where a, x, and b are signed long
   * integers.  Since in integer arithmetic (a*x) could overflow and a*(x/b) would
   * not be accurate, we use floating point arithmetic rather than trying to do
   * this all with integer arithmetic.
   *
   * 1000.0 / (font->extend * font->sptsize) is caluculated each times...
   * Is accuracy really a matter? Character widths are always rounded to integer
   * (in 1000 units per em) but dvipdfmx does not take into account of this...
   */
  
  if (text_state.dir_mode) {
    /* Top-to-bottom */
    delh = ypos - text_yorigin + text_state.offset;
    delv = xpos - text_xorigin;
  } else {
    /* Left-to-right */
    delh = text_xorigin + text_state.offset - xpos;
    delv = ypos - text_yorigin;
  }
  
  /* White-space more than 3em is not considered as a part of single text.
   * So we will break string mode in that case.
   * Dvipdfmx spend most of time processing strings with kern = 0 (but far
   * more times in font handling).
   * You may want to use pre-calculated value for WORD_SPACE_MAX.
   * More text compression may be possible by replacing kern with space char
   * when -kern is equal to space char width.
   */
#define WORD_SPACE_MAX(f) (spt_t) (3.0 * (f)->extend * (f)->sptsize)
  
  text_mode();
  kern = 0;

  /* Inaccucary introduced by rounding of character width appears within
   * single text block. There are point_size/1000 rounding error per character.
   * If you really care about accuracy, you should compensate this here too.
   */
  if (motion_state != STRING_MODE)
    string_mode(xpos, ypos,
                font->slant, font->extend, text_state.matrix.rotate);
  else if (kern != 0) {
    /*
     * Same issues as earlier. Use floating point for simplicity.
     * This routine needs to be fast, so we don't call sprintf() or strcpy().
     */
    text_state.offset -= 
    (spt_t) (kern * font->extend * (font->sptsize / 1000.0));
    format_buffer[len++] = text_state.is_mb ? '>' : ')';
    if (font->wmode)
      len += p_itoa(-kern, format_buffer + len);
    else {
      len += p_itoa( kern, format_buffer + len);
    }
    format_buffer[len++] = text_state.is_mb ? '<' : '(';
    pdf_doc_add_page_content(format_buffer, len);  /* op: */
    len = 0;
  }
  
  if (text_state.is_mb) {
    if (FORMAT_BUF_SIZE - len < 2)
      ERROR("Buffer overflow...");
      int first, second;
      
      first  = (glyph >> 4) & 0x0f;
      second = glyph & 0x0f;
      format_buffer[len++] = ((first >= 10)  ? first  + 'W' : first  + '0');
      format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0');
  } else {
    len += pdfobj_escape_str(format_buffer + len,
                             FORMAT_BUF_SIZE - len, &glyph, 1);
  }
  /* I think if you really care about speed, you should avoid memcopy here. */
  pdf_doc_add_page_content(format_buffer, len);  /* op: */
  
 // text_state.offset += width;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_set_rect ( pdf_rect rect,
spt_t  x_user,
spt_t  y_user,
spt_t  width,
spt_t  height,
spt_t  depth 
)

Definition at line 1788 of file pdfdev.c.

{
  double      dev_x, dev_y;
  pdf_coord   p0, p1, p2, p3;
  double      min_x, min_y, max_x, max_y;

  dev_x = x_user * dev_unit.dvi2pts;
  dev_y = y_user * dev_unit.dvi2pts;
  if (text_state.dir_mode) {
    p0.x = dev_x - dev_unit.dvi2pts * depth;
    p0.y = dev_y - dev_unit.dvi2pts * width;
    p1.x = dev_x + dev_unit.dvi2pts * height;
    p1.y = p0.y;
    p2.x = p1.x;
    p2.y = dev_y;
    p3.x = p0.x;
    p3.y = p2.y;
  } else {
    p0.x = dev_x;
    p0.y = dev_y - dev_unit.dvi2pts * depth;
    p1.x = dev_x + dev_unit.dvi2pts * width;
    p1.y = p0.y;
    p2.x = p1.x;
    p2.y = dev_y + dev_unit.dvi2pts * height;
    p3.x = p0.x;
    p3.y = p2.y;
  }

  pdf_dev_transform(&p0, NULL); /* currentmatrix */
  pdf_dev_transform(&p1, NULL);
  pdf_dev_transform(&p2, NULL);
  pdf_dev_transform(&p3, NULL);

  min_x = MIN(p0.x , p1.x);
  min_x = MIN(min_x, p2.x);
  min_x = MIN(min_x, p3.x);

  max_x = MAX(p0.x , p1.x);
  max_x = MAX(max_x, p2.x);
  max_x = MAX(max_x, p3.x);

  min_y = MIN(p0.y , p1.y);
  min_y = MIN(min_y, p2.y);
  min_y = MIN(min_y, p3.y);

  max_y = MAX(p0.y , p1.y);
  max_y = MAX(max_y, p2.y);
  max_y = MAX(max_y, p3.y);

  rect->llx = min_x;
  rect->lly = min_y;
  rect->urx = max_x;
  rect->ury = max_y;

  return;
}

Here is the call graph for this function:

void pdf_dev_set_rule ( spt_t  xpos,
spt_t  ypos,
spt_t  width,
spt_t  height 
)

Definition at line 1720 of file pdfdev.c.

{
  int    len = 0;
  double width_in_bp;

  if (num_dev_coords > 0) {
    xpos -= bpt2spt(dev_coords[num_dev_coords-1].x);
    ypos -= bpt2spt(dev_coords[num_dev_coords-1].y);
  }

  graphics_mode();

  format_buffer[len++] = ' ';
  format_buffer[len++] = 'q';
  format_buffer[len++] = ' ';
  /* Don't use too thick line. */
  width_in_bp = ((width < height) ? width : height) * dev_unit.dvi2pts;
  if (width_in_bp < 0.0 || /* Shouldn't happen */
      width_in_bp > PDF_LINE_THICKNESS_MAX) {
    pdf_rect rect;

    rect.llx =  dev_unit.dvi2pts * xpos;
    rect.lly =  dev_unit.dvi2pts * ypos;
    rect.urx =  dev_unit.dvi2pts * width;
    rect.ury =  dev_unit.dvi2pts * height;
    len += pdf_sprint_rect(format_buffer+len, &rect);
    format_buffer[len++] = ' ';
    format_buffer[len++] = 'r';
    format_buffer[len++] = 'e';
    format_buffer[len++] = ' ';
    format_buffer[len++] = 'f';
  } else {
    if (width > height) {
      /* NOTE:
       *  A line width of 0 denotes the thinnest line that can be rendered at
       *  device resolution. See, PDF Reference Manual 4th ed., sec. 4.3.2,
       *  "Details of Graphics State Parameters", p. 185.
       */
      if (height < dev_unit.min_bp_val) {
        WARN("Too thin line: height=%ld (%g bp)", height, width_in_bp);
        WARN("Please consider using \"-d\" option.");
      }
      len += dev_sprint_line(format_buffer+len,
                             height,
                             xpos,
                             ypos + height/2,
                             xpos + width,
                             ypos + height/2);
    } else {
      if (width < dev_unit.min_bp_val) {
        WARN("Too thin line: width=%ld (%g bp)", width, width_in_bp);
        WARN("Please consider using \"-d\" option.");
      }
      len += dev_sprint_line(format_buffer+len,
                             width,
                             xpos + width/2,
                             ypos,
                             xpos + width/2,
                             ypos + height);
    }
  }
  format_buffer[len++] = ' ';
  format_buffer[len++] = 'Q';
  pdf_doc_add_page_content(format_buffer, len);  /* op: q re f Q */
}

Here is the call graph for this function:

void pdf_dev_set_string ( spt_t  xpos,
spt_t  ypos,
const void *  instr_ptr,
int  instr_len,
spt_t  width,
int  font_id,
int  ctype 
)

Definition at line 1031 of file pdfdev.c.

{
  struct dev_font *font;
  unsigned char   *str_ptr; /* Pointer to the reencoded string. */
  int              length, i, len = 0;
  spt_t            kern, delh, delv;
  spt_t            text_xorigin;
  spt_t            text_yorigin;

  if (font_id < 0 || font_id >= num_dev_fonts) {
    ERROR("Invalid font: %d (%d)", font_id, num_dev_fonts);
    return;
  }
  if (font_id != text_state.font_id) {
    dev_set_font(font_id);
  }

  font = CURRENTFONT();
  if (!font) {
    ERROR("Currentfont not set.");
    return;
  }

  text_xorigin = text_state.ref_x;
  text_yorigin = text_state.ref_y;

  str_ptr = (unsigned char *) instr_ptr;
  length  = instr_len;

  if (font->format == PDF_FONTTYPE_COMPOSITE) {
    if (handle_multibyte_string(font, &str_ptr, &length, ctype) < 0) {
      ERROR("Error in converting input string...");
      return;
    }
    if (font->used_chars != NULL) {
      for (i = 0; i < length; i += 2)
        add_to_used_chars2(font->used_chars,
                           (unsigned short) (str_ptr[i] << 8)|str_ptr[i+1]);
    }
  } else {
    if (font->used_chars != NULL) {
      for (i = 0; i < length; i++)
        font->used_chars[str_ptr[i]] = 1;
    }
  }

  if (num_dev_coords > 0) {
    xpos -= bpt2spt(dev_coords[num_dev_coords-1].x);
    ypos -= bpt2spt(dev_coords[num_dev_coords-1].y);
  }

  /*
   * Kern is in units of character units, i.e., 1000 = 1 em.
   *
   * Positive kern means kerning (reduce excess white space).
   *
   * The following formula is of the form a*x/b where a, x, and b are signed long
   * integers.  Since in integer arithmetic (a*x) could overflow and a*(x/b) would
   * not be accurate, we use floating point arithmetic rather than trying to do
   * this all with integer arithmetic.
   *
   * 1000.0 / (font->extend * font->sptsize) is caluculated each times...
   * Is accuracy really a matter? Character widths are always rounded to integer
   * (in 1000 units per em) but dvipdfmx does not take into account of this...
   */

  if (text_state.dir_mode) {
    /* Top-to-bottom */
    delh = ypos - text_yorigin + text_state.offset;
    delv = xpos - text_xorigin;
  } else {
    /* Left-to-right */
    delh = text_xorigin + text_state.offset - xpos;
    delv = ypos - text_yorigin;
  }

  /* White-space more than 3em is not considered as a part of single text.
   * So we will break string mode in that case.
   * Dvipdfmx spend most of time processing strings with kern = 0 (but far
   * more times in font handling).
   * You may want to use pre-calculated value for WORD_SPACE_MAX.
   * More text compression may be possible by replacing kern with space char
   * when -kern is equal to space char width.
   */
#define WORD_SPACE_MAX(f) (spt_t) (3.0 * (f)->extend * (f)->sptsize)

  if (text_state.force_reset ||
      labs(delv) > dev_unit.min_bp_val ||
      labs(delh) > WORD_SPACE_MAX(font)) {
    text_mode();
    kern = 0;
  } else {
    kern = (spt_t) (1000.0 / font->extend * delh / font->sptsize);
  }

  /* Inaccucary introduced by rounding of character width appears within
   * single text block. There are point_size/1000 rounding error per character.
   * If you really care about accuracy, you should compensate this here too.
   */
  if (motion_state != STRING_MODE)
    string_mode(xpos, ypos,
                font->slant, font->extend, text_state.matrix.rotate);
  else if (kern != 0) {
    /*
     * Same issues as earlier. Use floating point for simplicity.
     * This routine needs to be fast, so we don't call sprintf() or strcpy().
     */
    text_state.offset -= 
      (spt_t) (kern * font->extend * (font->sptsize / 1000.0));
    format_buffer[len++] = text_state.is_mb ? '>' : ')';
    if (font->wmode)
      len += p_itoa(-kern, format_buffer + len);
    else {
      len += p_itoa( kern, format_buffer + len);
    }
    format_buffer[len++] = text_state.is_mb ? '<' : '(';
    pdf_doc_add_page_content(format_buffer, len);  /* op: */
    len = 0;
  }

  if (text_state.is_mb) {
    if (FORMAT_BUF_SIZE - len < 2 * length)
      ERROR("Buffer overflow...");
    for (i = 0; i < length; i++) {
      int first, second;

      first  = (str_ptr[i] >> 4) & 0x0f;
      second = str_ptr[i] & 0x0f;
      format_buffer[len++] = ((first >= 10)  ? first  + 'W' : first  + '0');
      format_buffer[len++] = ((second >= 10) ? second + 'W' : second + '0');
    }
  } else {
    len += pdfobj_escape_str(format_buffer + len,
                             FORMAT_BUF_SIZE - len, str_ptr, length);
  }
  /* I think if you really care about speed, you should avoid memcopy here. */
  pdf_doc_add_page_content(format_buffer, len);  /* op: */

  text_state.offset += width;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_set_verbose ( void  )

Definition at line 58 of file pdfdev.c.

{
  verbose++;
}
spt_t pdf_dev_string_width ( int  font_id,
unsigned char *  str,
unsigned  len 
)

Definition at line 1010 of file pdfdev.c.

{
  if (font_id < 0 || font_id >= num_dev_fonts) {
    ERROR("Invalid font: %d (%d)", font_id, num_dev_fonts);
    return;
  }
  
  return tfm_string_width(GET_FONT(font_id)->tfm_id, str, len);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_init_device ( double  dvi2pts,
int  precision,
int  black_and_white 
)

Definition at line 1301 of file pdfdev.c.

{
  if (precision < 0 ||
      precision > DEV_PRECISION_MAX)
    WARN("Number of decimal digits out of range [0-%d].",
         DEV_PRECISION_MAX);

  if (precision < 0) {
    dev_unit.precision  = 0;
  } else if (precision > DEV_PRECISION_MAX) {
    dev_unit.precision  = DEV_PRECISION_MAX;
  } else {
    dev_unit.precision  = precision;
  }
  dev_unit.dvi2pts      = dvi2pts;
  dev_unit.min_bp_val   = (long) ROUND(1.0/(ten_pow[dev_unit.precision]*dvi2pts), 1);
  if (dev_unit.min_bp_val < 0)
    dev_unit.min_bp_val = -dev_unit.min_bp_val;

  dev_param.colormode = (black_and_white ? 0 : 1);

  graphics_mode();
  pdf_color_clear_stack();
  pdf_dev_init_gstates();

  num_dev_fonts  = max_dev_fonts = 0;
  dev_fonts      = NULL;
  num_dev_coords = max_dev_coords = 0;
  dev_coords     = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_sprint_coord ( char *  buf,
const pdf_coord p 
)

Definition at line 256 of file pdfdev.c.

{
  int  len;

  len  = p_dtoa(p->x, dev_unit.precision, buf);
  buf[len++] = ' ';
  len += p_dtoa(p->y, dev_unit.precision, buf+len);
  buf[len]   = '\0'; /* xxx_sprint_xxx NULL terminates strings. */

  return  len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_sprint_length ( char *  buf,
double  value 
)

Definition at line 269 of file pdfdev.c.

{
  int  len;

  len = p_dtoa(value, dev_unit.precision, buf);
  buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */

  return  len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_sprint_matrix ( char *  buf,
const pdf_tmatrix M 
)

Definition at line 216 of file pdfdev.c.

{
  int  len;
  int  prec2 = MIN(dev_unit.precision + 2, DEV_PRECISION_MAX);
  int  prec0 = MAX(dev_unit.precision, 2);

  len  = p_dtoa(M->a, prec2, buf);
  buf[len++] = ' ';
  len += p_dtoa(M->b, prec2, buf+len);
  buf[len++] = ' ';
  len += p_dtoa(M->c, prec2, buf+len);
  buf[len++] = ' ';
  len += p_dtoa(M->d, prec2, buf+len);
  buf[len++] = ' ';
  len += p_dtoa(M->e, prec0, buf+len);
  buf[len++] = ' ';
  len += p_dtoa(M->f, prec0, buf+len);
  buf[len]   = '\0'; /* xxx_sprint_xxx NULL terminates strings. */

  return  len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_sprint_number ( char *  buf,
double  value 
)

Definition at line 281 of file pdfdev.c.

{
  int  len;

  len = p_dtoa(value, DEV_PRECISION_MAX, buf);
  buf[len] = '\0'; /* xxx_sprint_xxx NULL terminates strings. */

  return  len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_sprint_rect ( char *  buf,
const pdf_rect rect 
)

Definition at line 239 of file pdfdev.c.

{
  int  len;

  len  = p_dtoa(rect->llx, dev_unit.precision, buf);
  buf[len++] = ' ';
  len += p_dtoa(rect->lly, dev_unit.precision, buf+len);
  buf[len++] = ' ';
  len += p_dtoa(rect->urx, dev_unit.precision, buf+len);
  buf[len++] = ' ';
  len += p_dtoa(rect->ury, dev_unit.precision, buf+len);
  buf[len]   = '\0'; /* xxx_sprint_xxx NULL terminates strings. */

  return  len;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void print_fontmap ( const char *  font_name,
fontmap_rec mrec 
) [static]

Definition at line 1425 of file pdfdev.c.

{
  if (!mrec)
    return;

  MESG("\n");

  MESG("fontmap: %s -> %s", font_name, mrec->font_name);
  if (mrec->enc_name)
    MESG("(%s)",  mrec->enc_name);
  if (mrec->opt.extend != 1.0)
    MESG("[extend:%g]", mrec->opt.extend);
  if (mrec->opt.slant  != 0.0)
    MESG("[slant:%g]",  mrec->opt.slant);
  if (mrec->opt.bold   != 0.0) 
    MESG("[bold:%g]",   mrec->opt.bold);
  if (mrec->opt.flags & FONTMAP_OPT_NOEMBED)
    MESG("[noemb]");
  if (mrec->opt.mapc >= 0)
    MESG("[map:<%02x>]", mrec->opt.mapc);
  if (mrec->opt.charcoll)  
    MESG("[csi:%s]",     mrec->opt.charcoll);
  if (mrec->opt.index) 
    MESG("[index:%d]",   mrec->opt.index);

  switch (mrec->opt.style) {
  case FONTMAP_STYLE_BOLD:
    MESG("[style:bold]");
    break;
  case FONTMAP_STYLE_ITALIC:
    MESG("[style:italic]");
    break;
  case FONTMAP_STYLE_BOLDITALIC:
    MESG("[style:bolditalic]");
    break;
  }
  MESG("\n");

}

Here is the call graph for this function:

Here is the caller graph for this function:

static void reset_text_state ( void  ) [static]

Definition at line 556 of file pdfdev.c.

{
  /*
   * We need to reset the line matrix to handle slanted fonts.
   */
  pdf_doc_add_page_content(" BT", 3);  /* op: BT */
  /*
   * text_state.matrix is identity at top of page.
   * This sometimes write unnecessary "Tm"s when transition from
   * GRAPHICS_MODE to TEXT_MODE occurs.
   */
  if (text_state.force_reset ||
      text_state.matrix.slant  != 0.0 ||
      text_state.matrix.extend != 1.0 ||
      ROTATE_TEXT(text_state.matrix.rotate)) {
    dev_set_text_matrix(0, 0,
                        text_state.matrix.slant,
                        text_state.matrix.extend,
                        text_state.matrix.rotate);
  }
  text_state.ref_x = 0;
  text_state.ref_y = 0;
  text_state.offset   = 0;
  text_state.force_reset = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void start_string ( spt_t  xpos,
spt_t  ypos,
double  slant,
double  extend,
int  rotate 
) [static]

Definition at line 618 of file pdfdev.c.

{
  spt_t delx, dely, error_delx, error_dely;
  spt_t desired_delx, desired_dely;
  int   len = 0;

  delx = xpos - text_state.ref_x;
  dely = ypos - text_state.ref_y;
  /*
   * Precompensating for line transformation matrix.
   *
   * Line transformation matrix L for horizontal font in horizontal
   * mode and it's inverse I is
   *
   *          | e  0|          | 1/e  0|
   *   L_hh = |     | , I_hh = |       |
   *          | s  1|          |-s/e  1|
   *
   * For vertical font in vertical mode,
   *
   *          | 1  -s|          | 1  s/e|
   *   L_vv = |      | , I_vv = |       |
   *          | 0   e|          | 0  1/e|
   *
   * For vertical font in horizontal mode,
   *
   *          | s   1|          | 0  1|
   *   L_vh = |      | = L_vv x |     |
   *          |-e   0|          |-1  0|
   *
   *          | 0  -1|
   *   I_vh = |      | x I_vv
   *          | 1   0|
   *
   * For horizontal font in vertical mode,
   *
   *          | 0  -e|          | 0  -1|
   *   L_hv = |      | = L_hh x |      |
   *          | 1  -s|          | 1   0|
   *
   *          | 0   1|
   *   I_hv = |      | x I_hh
   *          |-1   0|
   *
   */
  switch (rotate) {
  case TEXT_WMODE_VH:
    /* Vertical font in horizontal mode: rot = +90
     *                           | 0  -1/e|
     * d_user =  d x I_vh = d x  |        |
     *                           | 1   s/e|
     */
    desired_delx = dely;
    desired_dely = (spt_t) (-(delx - dely*slant)/extend);

    /* error_del is in device space
     *
     *               | 0  1|
     *  e = e_user x |     | = (-e_user_y, e_user_x)
     *               |-1  0|
     *
     * We must care about rotation here but not extend/slant...
     * The extend and slant actually is font matrix.
     */
    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely);
    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_dely, &error_delx);
    error_delx = -error_delx;
    break;
  case TEXT_WMODE_HV:
    /* Horizontal font in vertical mode: rot = -90
     *
     *                         |-s/e  1|
     * d_user = d x I_hv = d x |       |
     *                         |-1/e  0|
     */
    desired_delx = (spt_t)(-(dely + delx*slant)/extend);
    desired_dely = delx;

    /*
     * e = (e_user_y, -e_user_x)
     */
    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_delx, &error_dely);
    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_dely, &error_delx);
    error_dely = -error_dely;
    break;
  case TEXT_WMODE_HH:
    /* Horizontal font in horizontal mode:
     *                         | 1/e    0|
     * d_user = d x I_hh = d x |         |
     *                         |-s/e    1|
     */
    desired_delx = (spt_t)((delx - dely*slant)/extend);
    desired_dely = dely;

    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx);
    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely);
    break;
  case TEXT_WMODE_VV:
    /* Vertical font in vertical mode:
     *                         | 1  s/e|
     * d_user = d x I_vv = d x |       |
     *                         | 0  1/e|
     */
    desired_delx = delx;
    desired_dely = (spt_t)((dely + delx*slant)/extend);

    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_delx, &error_delx);
    format_buffer[len++] = ' ';
    len += dev_sprint_bp(format_buffer+len, desired_dely, &error_dely);
    break;
  }
  pdf_doc_add_page_content(format_buffer, len);  /* op: */
  /*
   * dvipdfm wrongly using "TD" in place of "Td".
   * The TD operator set leading, but we are not using T* etc.
   */
  pdf_doc_add_page_content(text_state.is_mb ? " Td[<" : " Td[(", 5);  /* op: Td */

  /* Error correction */
  text_state.ref_x = xpos - error_delx;
  text_state.ref_y = ypos - error_dely;

  text_state.offset   = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void string_mode ( spt_t  xpos,
spt_t  ypos,
double  slant,
double  extend,
int  rotate 
) [static]

Definition at line 751 of file pdfdev.c.

{
  switch (motion_state) {
  case STRING_MODE:
    break;
  case GRAPHICS_MODE:
    reset_text_state();
    /* continue */
  case TEXT_MODE:
    if (text_state.force_reset) {
      dev_set_text_matrix(xpos, ypos, slant, extend, rotate);
      pdf_doc_add_page_content(text_state.is_mb ? "[<" : "[(", 2);  /* op: */
      text_state.force_reset = 0;
    } else {
      start_string(xpos, ypos, slant, extend, rotate);
    }
    break;
  }
  motion_state = STRING_MODE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void text_mode ( void  ) [static]

Definition at line 583 of file pdfdev.c.

{
  switch (motion_state) {
  case TEXT_MODE:
    break;
  case STRING_MODE:
    pdf_doc_add_page_content(text_state.is_mb ? ">]TJ" : ")]TJ", 4);  /* op: TJ */
    break;
  case GRAPHICS_MODE:
    reset_text_state();
    break;
  }
  motion_state      = TEXT_MODE;
  text_state.offset = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2003 of file pdfdev.c.

{
  /* Physical dimensions */
  info->width    = 0.0;
  info->height   = 0.0;
  info->depth    = 0.0;

  info->bbox.llx = 0.0;
  info->bbox.lly = 0.0;
  info->bbox.urx = 0.0;
  info->bbox.ury = 0.0;

  /* Transformation matrix */
  pdf_setmatrix(&(info->matrix), 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);

  info->flags    = 0;
}

Here is the caller graph for this function:


Variable Documentation

pdf_coord* dev_coords = NULL [static]

Definition at line 979 of file pdfdev.c.

struct dev_font* dev_fonts = NULL [static]

Definition at line 492 of file pdfdev.c.

struct { ... } dev_param [static]
struct { ... } dev_unit [static]

Definition at line 328 of file pdfdev.c.

int max_dev_coords = 0 [static]

Definition at line 981 of file pdfdev.c.

int max_dev_fonts = 0 [static]

Definition at line 495 of file pdfdev.c.

int motion_state = GRAPHICS_MODE [static]

Definition at line 325 of file pdfdev.c.

int num_dev_coords = 0 [static]

Definition at line 980 of file pdfdev.c.

int num_dev_fonts = 0 [static]

Definition at line 494 of file pdfdev.c.

int num_phys_fonts = 0 [static]

Definition at line 496 of file pdfdev.c.

unsigned char sbuf0[FORMAT_BUF_SIZE] [static]

Definition at line 890 of file pdfdev.c.

unsigned char sbuf1[FORMAT_BUF_SIZE] [static]

Definition at line 891 of file pdfdev.c.

unsigned long ten_pow[10] [static]
Initial value:
 {
  1ul, 10ul, 100ul, 1000ul, 10000ul, 100000ul, 1000000ul, 10000000ul, 100000000ul, 1000000000ul
}

Definition at line 93 of file pdfdev.c.

double ten_pow_inv[10] [static]
Initial value:
 {
  1.0, 0.1,  0.01,  0.001,  0.0001,  0.00001,  0.000001,  0.0000001,  0.00000001,  0.000000001
}

Definition at line 97 of file pdfdev.c.

struct { ... } text_state [static]
int verbose = 0 [static]

Definition at line 55 of file pdfdev.c.