Back to index

texmacs  1.0.7.15
Classes | Defines | Typedefs | Functions | Variables
pdfdraw.c File Reference
#include <math.h>
#include "system.h"
#include "error.h"
#include "mem.h"
#include "mfileio.h"
#include "dpxutil.h"
#include "numbers.h"
#include "pdfdoc.h"
#include "pdfdev.h"
#include "pdfcolor.h"
#include "pdfdraw.h"

Go to the source code of this file.

Classes

struct  pa_elem_
struct  pdf_path_
struct  pdf_gstate_
struct  m_stack_elem
struct  m_stack
struct  pdf_gstate_.linedash

Defines

#define detM(M)   ((M).a * (M).d - (M).b * (M).c)
#define detP(M)   ((M)->a * (M)->d - (M)->b * (M)->c)
#define vecprd(v, w)   ((v).x * (w).x + (v).y * (w).y)
#define vecrot(v, w)   ((v).x * (w).y - (v).y * (w).x)
#define dsign(v)   (((v) >= 0.0) ? 1.0 : -1.0)
#define vecang(v, w)
#define COORD_EQUAL(p, q)   pdf_coord__equal((p),(q))
#define PE_TYPE__INVALID   -1
#define PE_TYPE__MOVETO   0
#define PE_TYPE__LINETO   1
#define PE_TYPE__CURVETO   2
#define PE_TYPE__CURVETO_V   3
#define PE_TYPE__CURVETO_Y   4
#define PE_TYPE__CLOSEPATH   5
#define PE_TYPE__TERMINATE   6
#define PE_VALID(p)
#define PE_N_PTS(p)   (PE_VALID((p)) ? petypes[(p)->type].n_pts : 0)
#define PE_OPCHR(p)   (PE_VALID((p)) ? petypes[(p)->type].opchr : ' ')
#define PA_LENGTH(pa)   ((pa)->num_paths)
#define GS_FLAG_CURRENTPOINT_SET   (1 << 0)
#define FORMAT_BUFF_PTR(p)   fmt_buf
#define FORMAT_BUFF_LEN(p)   1024
#define PT_OP_VALID(c)
#define m_stack_depth(s)   (((s) != NULL) ? (s)->size : 0)

Typedefs

typedef void pdf_dev
typedef struct pa_elem_ pa_elem
typedef struct pdf_gstate_ pdf_gstate
typedef struct m_stack_elem m_stack_elem
typedef struct m_stack m_stack

Functions

static int inversematrix (pdf_tmatrix *W, const pdf_tmatrix *M)
static int pdf_coord__equal (const pdf_coord *p1, const pdf_coord *p2)
static int pdf_coord__transform (pdf_coord *p, const pdf_tmatrix *M)
static int pdf_coord__dtransform (pdf_coord *p, const pdf_tmatrix *M)
static int pdf_coord__idtransform (pdf_coord *p, const pdf_tmatrix *M)
void pdf_invertmatrix (pdf_tmatrix *M)
static void init_a_path (pdf_path *p)
static void pdf_path__clearpath (pdf_path *p)
static int pdf_path__growpath (pdf_path *p, int max_pe)
static void clear_a_path (pdf_path *p)
static int pdf_path__copypath (pdf_path *p1, const pdf_path *p0)
static int pdf_path__moveto (pdf_path *pa, pdf_coord *cp, const pdf_coord *p0)
static pa_elempdf_path__next_pe (pdf_path *pa, const pdf_coord *cp)
static int pdf_path__transform (pdf_path *pa, const pdf_tmatrix *M)
static int pdf_path__lineto (pdf_path *pa, pdf_coord *cp, const pdf_coord *p0)
static int pdf_path__curveto (pdf_path *pa, pdf_coord *cp, const pdf_coord *p0, const pdf_coord *p1, const pdf_coord *p2)
static int pdf_path__elliptarc (pdf_path *pa, pdf_coord *cp, const pdf_coord *ca, double r_x, double r_y, double xar, double a_0, double a_1, int a_d)
static int pdf_path__closepath (pdf_path *pa, pdf_coord *cp)
static int pdf_path__isarect (pdf_path *pa, int f_ir)
static int INVERTIBLE_MATRIX (const pdf_tmatrix *M)
static int pdf_dev__rectshape (pdf_dev *P, const pdf_rect *r, const pdf_tmatrix *M, char opchr)
static int pdf_dev__flushpath (pdf_dev *P, pdf_path *pa, char opchr, int rule, int ignore_rule)
static void m_stack_init (m_stack *stack)
static void m_stack_push (m_stack *stack, void *data)
static void * m_stack_pop (m_stack *stack)
static void * m_stack_top (m_stack *stack)
static void init_a_gstate (pdf_gstate *gs)
static void clear_a_gstate (pdf_gstate *gs)
static void copy_a_gstate (pdf_gstate *gs1, pdf_gstate *gs2)
void pdf_dev_init_gstates (void)
void pdf_dev_clear_gstates (void)
int pdf_dev_gsave (void)
int pdf_dev_grestore (void)
int pdf_dev_push_gstate (void)
int pdf_dev_pop_gstate (void)
int pdf_dev_current_depth (void)
void pdf_dev_grestore_to (int depth)
int pdf_dev_currentpoint (pdf_coord *p)
int pdf_dev_currentmatrix (pdf_tmatrix *M)
void pdf_dev_set_color (const pdf_color *color, char mask, int force)
void pdf_dev_reset_color (int force)
int pdf_dev_concat (const pdf_tmatrix *M)
int pdf_dev_setmiterlimit (double mlimit)
int pdf_dev_setlinecap (int capstyle)
int pdf_dev_setlinejoin (int joinstyle)
int pdf_dev_setlinewidth (double width)
int pdf_dev_setdash (int count, double *pattern, double offset)
int pdf_dev_clip (void)
int pdf_dev_eoclip (void)
int pdf_dev_flushpath (char p_op, int fill_rule)
int pdf_dev_newpath (void)
int pdf_dev_moveto (double x, double y)
int pdf_dev_rmoveto (double x, double y)
int pdf_dev_lineto (double x, double y)
int pdf_dev_rlineto (double x, double y)
int pdf_dev_curveto (double x0, double y0, double x1, double y1, double x2, double y2)
int pdf_dev_rcurveto (double x0, double y0, double x1, double y1, double x2, double y2)
int pdf_dev_closepath (void)
void pdf_dev_dtransform (pdf_coord *p, const pdf_tmatrix *M)
void pdf_dev_idtransform (pdf_coord *p, const pdf_tmatrix *M)
void pdf_dev_transform (pdf_coord *p, const pdf_tmatrix *M)
int pdf_dev_arc (double c_x, double c_y, double r, double a_0, double a_1)
int pdf_dev_arcn (double c_x, double c_y, double r, double a_0, double a_1)
int pdf_dev_arcx (double c_x, double c_y, double r_x, double r_y, double a_0, double a_1, int a_d, double xar)
int pdf_dev_bspline (double x0, double y0, double x1, double y1, double x2, double y2)
int pdf_dev_rectfill (double x, double y, double w, double h)
int pdf_dev_rectclip (double x, double y, double w, double h)

Variables

struct {
char opchr
int n_pts
const char * strkey
petypes []
static char fmt_buf [1024]
static m_stack gs_stack

Class Documentation

struct pa_elem_

Definition at line 220 of file pdfdraw.c.

Collaboration diagram for pa_elem_:
Class Members
pdf_coord p
int type
struct pdf_path_

Definition at line 227 of file pdfdraw.c.

Collaboration diagram for pdf_path_:
Class Members
int max_paths
int num_paths
pa_elem * path
struct pdf_gstate_

Definition at line 882 of file pdfdraw.c.

Collaboration diagram for pdf_gstate_:
Class Members
pdf_coord cp
pdf_color fillcolor
long flags
int flatness
int linecap
struct pdf_gstate_ linedash
int linejoin
double linewidth
pdf_tmatrix matrix
double miterlimit
pdf_path path
pdf_color strokecolor
struct m_stack_elem

Definition at line 912 of file pdfdraw.c.

Collaboration diagram for m_stack_elem:
Class Members
void * data
struct m_stack_elem * prev
struct m_stack

Definition at line 918 of file pdfdraw.c.

Collaboration diagram for m_stack:
Class Members
m_stack_elem * bottom
int size
m_stack_elem * top
struct pdf_gstate_.linedash

Definition at line 892 of file pdfdraw.c.

Class Members
int num_dash
double offset
double pattern

Define Documentation

#define COORD_EQUAL (   p,
 
)    pdf_coord__equal((p),(q))

Definition at line 96 of file pdfdraw.c.

#define detM (   M)    ((M).a * (M).d - (M).b * (M).c)

Definition at line 53 of file pdfdraw.c.

#define detP (   M)    ((M)->a * (M)->d - (M)->b * (M)->c)

Definition at line 54 of file pdfdraw.c.

#define dsign (   v)    (((v) >= 0.0) ? 1.0 : -1.0)

Definition at line 81 of file pdfdraw.c.

#define FORMAT_BUFF_LEN (   p)    1024

Definition at line 269 of file pdfdraw.c.

#define FORMAT_BUFF_PTR (   p)    fmt_buf

Definition at line 268 of file pdfdraw.c.

#define GS_FLAG_CURRENTPOINT_SET   (1 << 0)

Definition at line 264 of file pdfdraw.c.

#define m_stack_depth (   s)    (((s) != NULL) ? (s)->size : 0)

Definition at line 995 of file pdfdraw.c.

#define PA_LENGTH (   pa)    ((pa)->num_paths)

Definition at line 262 of file pdfdraw.c.

#define PE_N_PTS (   p)    (PE_VALID((p)) ? petypes[(p)->type].n_pts : 0)

Definition at line 259 of file pdfdraw.c.

#define PE_OPCHR (   p)    (PE_VALID((p)) ? petypes[(p)->type].opchr : ' ')

Definition at line 260 of file pdfdraw.c.

#define PE_TYPE__CLOSEPATH   5
#define PE_TYPE__CURVETO   2
#define PE_TYPE__CURVETO_V   3
#define PE_TYPE__CURVETO_Y   4
#define PE_TYPE__INVALID   -1
#define PE_TYPE__LINETO   1
#define PE_TYPE__MOVETO   0
#define PE_TYPE__TERMINATE   6
#define PE_VALID (   p)
Value:
((p) && \
  (p)->type > PE_TYPE__INVALID && (p)->type < PE_TYPE__TERMINATE)

Definition at line 257 of file pdfdraw.c.

#define PT_OP_VALID (   c)
Value:
( \
 (c) == 'f' || (c) == 'F' || \
 (c) == 's' || (c) == 'S' || \
 (c) == 'b' || (c) == 'B' || \
 (c) == 'W' \
)

Definition at line 713 of file pdfdraw.c.

#define vecang (   v,
 
)
Value:
( \
  dsign(vecrot((v),(w))) * \
    acos(vecprd((v),(w)) / sqrt(vecprd((v),(v)) * vecprd((w),(w)))) \
)

Definition at line 83 of file pdfdraw.c.

#define vecprd (   v,
 
)    ((v).x * (w).x + (v).y * (w).y)

Definition at line 79 of file pdfdraw.c.

#define vecrot (   v,
 
)    ((v).x * (w).y - (v).y * (w).x)

Definition at line 80 of file pdfdraw.c.


Typedef Documentation

typedef struct m_stack m_stack
typedef struct m_stack_elem m_stack_elem
typedef struct pa_elem_ pa_elem
typedef void pdf_dev

Definition at line 45 of file pdfdraw.c.

typedef struct pdf_gstate_ pdf_gstate

Function Documentation

static void clear_a_gstate ( pdf_gstate gs) [static]

Definition at line 1027 of file pdfdraw.c.

{
  clear_a_path(&gs->path);
  memset(gs, 0, sizeof(pdf_gstate));

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void clear_a_path ( pdf_path *  p) [static]

Definition at line 306 of file pdfdraw.c.

{
  ASSERT(p);

  if (p->path)
    RELEASE(p->path);
  p->path = NULL;
  p->num_paths = 0;
  p->max_paths = 0;

  return;
}

Here is the caller graph for this function:

static void copy_a_gstate ( pdf_gstate gs1,
pdf_gstate gs2 
) [static]

Definition at line 1036 of file pdfdraw.c.

{
  int   i;

  ASSERT(gs1 && gs2);

  gs1->cp.x = gs2->cp.x;
  gs1->cp.y = gs2->cp.y;

  pdf_copymatrix(&gs1->matrix, &gs2->matrix);

  /* TODO:
   * Path should be linked list and gsave only
   * record starting point within path rather than
   * copying whole path.
   */
  pdf_path__copypath(&gs1->path, &gs2->path);

  gs1->linedash.num_dash = gs2->linedash.num_dash;
  for (i = 0; i < gs2->linedash.num_dash; i++) {
    gs1->linedash.pattern[i] = gs2->linedash.pattern[i];
  }
  gs1->linedash.offset = gs2->linedash.offset;

  gs1->linecap    = gs2->linecap;
  gs1->linejoin   = gs2->linejoin;
  gs1->linewidth  = gs2->linewidth;
  gs1->miterlimit = gs2->miterlimit;
  gs1->flatness   = gs2->flatness;

  pdf_color_copycolor(&gs1->fillcolor  , &gs2->fillcolor);
  pdf_color_copycolor(&gs1->strokecolor, &gs2->strokecolor);

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_a_gstate ( pdf_gstate gs) [static]

Definition at line 1000 of file pdfdraw.c.

{
  gs->cp.x = 0.0;
  gs->cp.y = 0.0;

  pdf_setmatrix(&gs->matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);

  pdf_color_black(&gs->strokecolor);
  pdf_color_black(&gs->fillcolor);

  gs->linedash.num_dash = 0;
  gs->linedash.offset   = 0;
  gs->linecap    = 0;
  gs->linejoin   = 0;
  gs->linewidth  = 1.0;
  gs->miterlimit = 10.0;

  gs->flatness   = 1; /* default to 1 in PDF */

  /* Internal variables */
  gs->flags = 0;
  init_a_path(&gs->path);

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_a_path ( pdf_path *  p) [static]

Definition at line 272 of file pdfdraw.c.

{
  ASSERT(p);

  p->num_paths = 0;
  p->max_paths = 0;
  p->path      = NULL;

  return;
}

Here is the caller graph for this function:

static int inversematrix ( pdf_tmatrix W,
const pdf_tmatrix M 
) [static]

Definition at line 58 of file pdfdraw.c.

{
  double  det;

  det = detP(M);
  if (fabs(det) < 1.e-8) {
#if 1
    WARN("Inverting matrix with zero determinant...");
#endif 
    return -1; /* result is undefined. */
  }

  W->a =  (M->d) / det;  W->b = -(M->b) / det;
  W->c = -(M->c) / det;  W->d =  (M->a) / det;
  W->e =  (M->c) * (M->f) - (M->d) * (M->e);
  W->f =  (M->b) * (M->e) - (M->a) * (M->f);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int INVERTIBLE_MATRIX ( const pdf_tmatrix M) [static]

Definition at line 721 of file pdfdraw.c.

{
  if (fabs(detP(M)) < 1.e-8) {
    WARN("Transformation matrix not invertible.");
    WARN("--- M = [%g %g %g %g %g %g]",
         M->a, M->b, M->c, M->d, M->e, M->f);
    return -1;
  }
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void m_stack_init ( m_stack stack) [static]

Definition at line 926 of file pdfdraw.c.

{
  ASSERT(stack);

  stack->size   = 0;
  stack->top    = NULL;
  stack->bottom = NULL;

  return;
}

Here is the caller graph for this function:

static void* m_stack_pop ( m_stack stack) [static]

Definition at line 958 of file pdfdraw.c.

{
  m_stack_elem *elem;
  void         *data;

  ASSERT(stack);

  if (stack->size == 0)
    return NULL;

  data = stack->top->data;
  elem = stack->top;
  stack->top = elem->prev;
  if (stack->size == 1)
    stack->bottom = NULL;
  RELEASE(elem);

  stack->size--;

  return data;
}

Here is the caller graph for this function:

static void m_stack_push ( m_stack stack,
void *  data 
) [static]

Definition at line 938 of file pdfdraw.c.

{
  m_stack_elem  *elem;

  ASSERT(stack);

  elem = NEW(1, m_stack_elem);
  elem->prev = stack->top;
  elem->data = data;

  stack->top = elem;
  if (stack->size == 0)
    stack->bottom = elem;

  stack->size++;

  return;
}

Here is the caller graph for this function:

static void* m_stack_top ( m_stack stack) [static]

Definition at line 981 of file pdfdraw.c.

{
  void  *data;

  ASSERT(stack);

  if (stack->size == 0)
    return NULL;

  data = stack->top->data;

  return data;
}

Here is the caller graph for this function:

static int pdf_coord__dtransform ( pdf_coord p,
const pdf_tmatrix M 
) [static]

Definition at line 162 of file pdfdraw.c.

{
  double x, y;

  x = p->x; y = p->y;
  p->x = x * M->a + y * M->c;
  p->y = x * M->b + y * M->d;

  return 0;
}

Here is the caller graph for this function:

static int pdf_coord__equal ( const pdf_coord p1,
const pdf_coord p2 
) [static]

Definition at line 89 of file pdfdraw.c.

{
  if (fabs(p1->x - p2->x) < 1.e-7 &&
      fabs(p1->y - p2->y) < 1.e-7)
    return 1;
  return 0;
}
static int pdf_coord__idtransform ( pdf_coord p,
const pdf_tmatrix M 
) [static]

Definition at line 174 of file pdfdraw.c.

{
  pdf_tmatrix W;  
  double      x, y;
  int         error;

  error = inversematrix(&W, M);
  if (error) 
    return error;

  x = p->x;  y = p->y;
  p->x = x * W.a + y * W.c;
  p->y = x * W.b + y * W.d;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_coord__transform ( pdf_coord p,
const pdf_tmatrix M 
) [static]

Definition at line 130 of file pdfdraw.c.

{
  double x, y;

  x = p->x; y = p->y;
  p->x = x * M->a + y * M->c + M->e;
  p->y = x * M->b + y * M->d + M->f;

  return 0;
}

Here is the caller graph for this function:

static int pdf_dev__flushpath ( pdf_dev P,
pdf_path *  pa,
char  opchr,
int  rule,
int  ignore_rule 
) [static]

Definition at line 809 of file pdfdraw.c.

{
  pa_elem   *pe, *pe1;
  char      *b      = FORMAT_BUFF_PTR(P);
  long       b_len  = FORMAT_BUFF_LEN(P);
  pdf_rect   r; /* FIXME */
  pdf_coord *pt;
  int        n_pts, n_seg;
  int        len = 0;
  int        isrect, i, j;

  ASSERT(pa && PT_OP_VALID(opchr));

  if (PA_LENGTH(pa) <= 0)
    return 0;

  graphics_mode();
  isrect = pdf_path__isarect(pa, ignore_rule); 
  if (isrect) {
    pe  = &(pa->path[0]);
    pe1 = &(pa->path[2]);

    r.llx = pe->p[0].x;
    r.lly = pe->p[0].y;
    r.urx = pe1->p[0].x - pe->p[0].x; /* width...  */
    r.ury = pe1->p[0].y - pe->p[0].y; /* height... */

    b[len++] = ' ';
    len += pdf_sprint_rect(b + len, &r);
    b[len++] = ' ';
    b[len++] = 'r';
    b[len++] = 'e';
    pdf_doc_add_page_content(b, len);  /* op: re */
    len = 0;
  } else {
    n_seg = PA_LENGTH(pa);
    for (i = 0, len = 0, pe = &pa->path[0];
         i < n_seg; pe++, i++) {
      n_pts = PE_N_PTS(pe);
      for (j = 0, pt = &pe->p[0];
           j < n_pts; j++, pt++) {
        b[len++] = ' ';
        len += pdf_sprint_coord(b + len, pt);
      }
      b[len++] = ' ';
      b[len++] = PE_OPCHR(pe);
      if (len + 128 > b_len) {
        pdf_doc_add_page_content(b, len);  /* op: m l c v y h */
       len = 0;
      }
    }
    if (len > 0) {
      pdf_doc_add_page_content(b, len);  /* op: m l c v y h */
      len = 0;
    }
  }

  b[len++] = ' ';
  b[len++] = opchr;
  if (rule == PDF_FILL_RULE_EVENODD)
    b[len++] = '*';

  pdf_doc_add_page_content(b, len);  /* op: f F s S b B W f* F* s* S* b* B* W* */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_dev__rectshape ( pdf_dev P,
const pdf_rect r,
const pdf_tmatrix M,
char  opchr 
) [static]

Definition at line 745 of file pdfdraw.c.

{
  char     *buf = FORMAT_BUFF_PTR(P);
  int       len = 0;
  int       isclip = 0;
  pdf_coord p;
  double    wd, ht;

  ASSERT(r && PT_OP_VALID(opchr));

  isclip = (opchr == 'W') ? 1 : 0;

  /* disallow matrix for clipping.
   * q ... clip Q does nothing and
   * n M cm ... clip n alter CTM.
   */
  if (M && (isclip ||
            !INVERTIBLE_MATRIX(M)))
    return -1;

  graphics_mode();

  buf[len++] = ' ';
  if (!isclip) {
    buf[len++] = 'q';
    if (M) {
      buf[len++] = ' ';
      len += pdf_sprint_matrix(buf + len, M);
      buf[len++] = ' ';
      buf[len++] = 'c'; buf[len++] = 'm';
    }
    buf[len++] = ' ';
  }
  buf[len++] = 'n';

  p.x = r->llx; p.y = r->lly;
  wd  = r->urx - r->llx;
  ht  = r->ury - r->lly;
  buf[len++] = ' ';
  len += pdf_sprint_coord (buf + len, &p);
  buf[len++] = ' ';
  len += pdf_sprint_length(buf + len, wd);
  buf[len++] = ' ';
  len += pdf_sprint_length(buf + len, ht);
  buf[len++] = ' ';
  buf[len++] = 'r'; buf[len++] = 'e';

  buf[len++] = ' ';
  buf[len++] = opchr;

  buf[len++] = ' ';
  buf[len++] = isclip ? 'n' : 'Q';

  pdf_doc_add_page_content(buf, len);  /* op: q cm n re Q */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_arc ( double  c_x,
double  c_y,
double  r,
double  a_0,
double  a_1 
)

Definition at line 1697 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   c;

  c.x = c_x; c.y = c_y;

  return  pdf_path__elliptarc(cpa, cpt, &c, r, r, 0.0, a_0, a_1, +1);
}

Here is the call graph for this function:

int pdf_dev_arcn ( double  c_x,
double  c_y,
double  r,
double  a_0,
double  a_1 
)

Definition at line 1713 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   c;

  c.x = c_x; c.y = c_y;

  return  pdf_path__elliptarc(cpa, cpt, &c, r, r, 0.0, a_0, a_1, -1);
}

Here is the call graph for this function:

int pdf_dev_arcx ( double  c_x,
double  c_y,
double  r_x,
double  r_y,
double  a_0,
double  a_1,
int  a_d,
double  xar 
)

Definition at line 1728 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   c;

  c.x = c_x; c.y = c_y;

  return  pdf_path__elliptarc(cpa, cpt, &c, r_x, r_y, xar, a_0, a_1, a_d);
}

Here is the call graph for this function:

int pdf_dev_bspline ( double  x0,
double  y0,
double  x1,
double  y1,
double  x2,
double  y2 
)

Definition at line 1747 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;  
  pdf_coord   p1, p2, p3;

  p1.x = x0 + 2.0 * (x1 - x0) / 3.0;
  p1.y = y0 + 2.0 * (y1 - y0) / 3.0;
  p2.x = x1 + (x2 - x1) / 3.0;
  p2.y = y1 + (y2 - y1) / 3.0;
  p3.x = x2;
  p3.y = y2;

  return  pdf_path__curveto(cpa, cpt, &p1, &p2, &p3);
}

Here is the call graph for this function:

void pdf_dev_clear_gstates ( void  )

Definition at line 1088 of file pdfdraw.c.

{
  pdf_gstate *gs;

  if (m_stack_depth(&gs_stack) > 1) /* at least 1 elem. */
    WARN("GS stack depth is not zero at the end of the document.");

  while ((gs = m_stack_pop(&gs_stack)) != NULL) {
    clear_a_gstate(gs);
    RELEASE(gs);
  }
  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_clip ( void  )

Definition at line 1479 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;

  return pdf_dev__flushpath(NULL, cpa, 'W', PDF_FILL_RULE_NONZERO, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_closepath ( void  )

Definition at line 1627 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_coord  *cpt = &gs->cp;
  pdf_path   *cpa = &gs->path;

  return pdf_path__closepath(cpa, cpt);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_concat ( const pdf_tmatrix M)

Definition at line 1305 of file pdfdraw.c.

{
  m_stack     *gss = &gs_stack;
  pdf_gstate  *gs  = m_stack_top(gss);
  pdf_path    *cpa = &gs->path;
  pdf_coord   *cpt = &gs->cp;
  pdf_tmatrix *CTM = &gs->matrix;
  pdf_tmatrix  W   = {0, 0, 0, 0, 0, 0};  /* Init to avoid compiler warning */
  char        *buf = FORMAT_BUFF_PTR(NULL);
  int          len = 0;

  ASSERT(M);

  /* Adobe Reader erases page content if there are
   * non invertible transformation.
   */
  if (fabs(detP(M)) < 1.0e-8) {
    WARN("Transformation matrix not invertible.");
    WARN("--- M = [%g %g %g %g %g %g]",
         M->a, M->b, M->c, M->d, M->e, M->f);
    return -1;
  }

  buf[len++] = ' ';
  len += pdf_sprint_matrix(buf + len, M);
  buf[len++] = ' ';
  buf[len++] = 'c';
  buf[len++] = 'm';
  pdf_doc_add_page_content(buf, len);  /* op: cm */

  pdf_concatmatrix(CTM, M);

  inversematrix(&W, M);

  pdf_path__transform (cpa, &W);
  pdf_coord__transform(cpt, &W);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_current_depth ( void  )

Definition at line 1176 of file pdfdraw.c.

{
  return (m_stack_depth(&gs_stack) - 1); /* 0 means initial state */
}

Here is the caller graph for this function:

Definition at line 1219 of file pdfdraw.c.

{
  m_stack     *gss = &gs_stack;
  pdf_gstate  *gs  = m_stack_top(gss);
  pdf_tmatrix *CTM = &gs->matrix;

  ASSERT(M);

  pdf_copymatrix(M, CTM);

  return 0;
}

Here is the call graph for this function:

Definition at line 1205 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_coord  *cpt = &gs->cp;

  ASSERT(p);

  p->x = cpt->x; p->y = cpt->y;

  return 0;
}

Here is the call graph for this function:

int pdf_dev_curveto ( double  x0,
double  y0,
double  x1,
double  y1,
double  x2,
double  y2 
)

Definition at line 1590 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   p0, p1, p2;

  p0.x = x0; p0.y = y0;
  p1.x = x1; p1.y = y1;
  p2.x = x2; p2.y = y2;

  return pdf_path__curveto(cpa, cpt, &p0, &p1, &p2);
}

Here is the call graph for this function:

void pdf_dev_dtransform ( pdf_coord p,
const pdf_tmatrix M 
)

Definition at line 1639 of file pdfdraw.c.

{
  m_stack     *gss = &gs_stack;
  pdf_gstate  *gs  = m_stack_top(gss);
  pdf_tmatrix *CTM = &gs->matrix;

  ASSERT(p);

  pdf_coord__dtransform(p, (M ? M : CTM));

  return;
}

Here is the call graph for this function:

int pdf_dev_eoclip ( void  )

Definition at line 1489 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;

  return pdf_dev__flushpath(NULL, cpa, 'W', PDF_FILL_RULE_EVENODD, 0);
}

Here is the call graph for this function:

int pdf_dev_flushpath ( char  p_op,
int  fill_rule 
)

Definition at line 1499 of file pdfdraw.c.

{
  m_stack    *gss   = &gs_stack;
  pdf_gstate *gs    = m_stack_top(gss);
  pdf_path   *cpa   = &gs->path;
  int         error = 0;

  /* last arg 'ignore_rule' is only for single object
   * that can be converted to a rect where fill rule
   * is inessential.
   */
  error = pdf_dev__flushpath(NULL, cpa, p_op, fill_rule, 1);
  pdf_path__clearpath(cpa);

  gs->flags &= ~GS_FLAG_CURRENTPOINT_SET;

  return error;
}

Here is the call graph for this function:

int pdf_dev_grestore ( void  )

Definition at line 1119 of file pdfdraw.c.

{
  pdf_gstate *gs;

  if (m_stack_depth(&gs_stack) <= 1) { /* Initial state at bottom */
    WARN("Too many grestores.");
    return  -1;
  }

  gs = m_stack_pop(&gs_stack);
  clear_a_gstate(gs);
  RELEASE(gs);

  pdf_doc_add_page_content(" Q", 2);  /* op: Q */

  pdf_dev_reset_fonts();

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_grestore_to ( int  depth)

Definition at line 1182 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs;

  ASSERT(depth >= 0);

  if (m_stack_depth(gss) > depth + 1) {
    WARN("Closing pending transformations at end of page/XObject.");
  }

  while (m_stack_depth(gss) > depth + 1) {
    pdf_doc_add_page_content(" Q", 2);  /* op: Q */
    gs = m_stack_pop(gss);
    clear_a_gstate(gs);
    RELEASE(gs);
  }
  pdf_dev_reset_fonts();

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_gsave ( void  )

Definition at line 1103 of file pdfdraw.c.

{
  pdf_gstate *gs0, *gs1;

  gs0 = m_stack_top(&gs_stack);
  gs1 = NEW(1, pdf_gstate);
  init_a_gstate(gs1);
  copy_a_gstate(gs1, gs0);
  m_stack_push(&gs_stack, gs1);

  pdf_doc_add_page_content(" q", 2);  /* op: q */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_idtransform ( pdf_coord p,
const pdf_tmatrix M 
)

Definition at line 1653 of file pdfdraw.c.

{
  m_stack     *gss = &gs_stack;
  pdf_gstate  *gs  = m_stack_top(gss);
  pdf_tmatrix *CTM = &gs->matrix;

  ASSERT(p);

  pdf_coord__idtransform(p, (M ? M : CTM));

  return;
}

Here is the call graph for this function:

void pdf_dev_init_gstates ( void  )

Definition at line 1073 of file pdfdraw.c.

{
  pdf_gstate *gs;

  m_stack_init(&gs_stack);

  gs = NEW(1, pdf_gstate);
  init_a_gstate(gs);

  m_stack_push(&gs_stack, gs); /* Initial state */

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_lineto ( double  x,
double  y 
)

Definition at line 1562 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   p0;

  p0.x = x; p0.y = y;

  return pdf_path__lineto(cpa, cpt, &p0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_moveto ( double  x,
double  y 
)

Definition at line 1535 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   p;

  p.x = x; p.y = y;
  return pdf_path__moveto(cpa, cpt, &p); /* cpt updated */
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_newpath ( void  )

Definition at line 1519 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *p   = &gs->path;

  if (PA_LENGTH(p) > 0) {
    pdf_path__clearpath (p);
  }
  /* The following is required for "newpath" operator in mpost.c. */
  pdf_doc_add_page_content(" n", 2);  /* op: n */

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_pop_gstate ( void  )

Definition at line 1157 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs;

  if (m_stack_depth(gss) <= 1) { /* Initial state at bottom */
    WARN("Too many grestores.");
    return  -1;
  }

  gs = m_stack_pop(gss);
  clear_a_gstate(gs);
  RELEASE(gs);

  return  0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_push_gstate ( void  )

Definition at line 1141 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs0;

  gs0 = NEW(1, pdf_gstate);

  init_a_gstate(gs0);

  m_stack_push(gss, gs0);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_rcurveto ( double  x0,
double  y0,
double  x1,
double  y1,
double  x2,
double  y2 
)

Definition at line 1608 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   p0, p1, p2;

  p0.x = x0 + cpt->x; p0.y = y0 + cpt->y;
  p1.x = x1 + cpt->x; p1.y = y1 + cpt->y;
  p2.x = x2 + cpt->x; p2.y = y2 + cpt->y;

  return pdf_path__curveto(cpa, cpt, &p0, &p1, &p2);
}

Here is the call graph for this function:

int pdf_dev_rectclip ( double  x,
double  y,
double  w,
double  h 
)

Definition at line 1800 of file pdfdraw.c.

{
  pdf_rect r;

  r.llx = x;
  r.lly = y;
  r.urx = x + w;
  r.ury = y + h;
  
  return  pdf_dev__rectshape(NULL, &r, NULL, 'W');
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_rectfill ( double  x,
double  y,
double  w,
double  h 
)

Definition at line 1786 of file pdfdraw.c.

{
  pdf_rect r;

  r.llx = x;
  r.lly = y;
  r.urx = x + w;
  r.ury = y + h;

  return  pdf_dev__rectshape(NULL, &r, NULL, 'f');
}

Here is the call graph for this function:

Here is the caller graph for this function:

void pdf_dev_reset_color ( int  force)

Definition at line 1295 of file pdfdraw.c.

{
  pdf_color *sc, *fc;

  pdf_color_get_current(&sc, &fc);
  pdf_dev_set_color(sc,    0, force);
  pdf_dev_set_color(fc, 0x20, force);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_rlineto ( double  x,
double  y 
)

Definition at line 1576 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   p0;

  p0.x = x + cpt->x; p0.y = y + cpt->y;

  return pdf_path__lineto(cpa, cpt, &p0);
}

Here is the call graph for this function:

int pdf_dev_rmoveto ( double  x,
double  y 
)

Definition at line 1548 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  pdf_path   *cpa = &gs->path;
  pdf_coord  *cpt = &gs->cp;
  pdf_coord   p;

  p.x = cpt->x + x;
  p.y = cpt->y + y;
  return pdf_path__moveto(cpa, cpt, &p); /* cpt updated */
}

Here is the call graph for this function:

void pdf_dev_set_color ( const pdf_color color,
char  mask,
int  force 
)

Definition at line 1256 of file pdfdraw.c.

{
  int len;

  pdf_gstate *gs  = m_stack_top(&gs_stack);
  pdf_color *current = mask ? &gs->fillcolor : &gs->strokecolor;

  ASSERT(pdf_color_is_valid(color));

  if (!(pdf_dev_get_param(PDF_DEV_PARAM_COLORMODE) &&
       (force || pdf_color_compare(color, current))))
    /* If "color" is already the current color, then do nothing
     * unless a color operator is forced
     */
    return;

  graphics_mode();
  len = pdf_color_to_string(color, fmt_buf);
  fmt_buf[len++] = ' ';
  switch (pdf_color_type(color)) {
  case  PDF_COLORSPACE_TYPE_RGB:
    fmt_buf[len++] = 'R' | mask;
    fmt_buf[len++] = 'G' | mask;
    break;
  case  PDF_COLORSPACE_TYPE_CMYK:
    fmt_buf[len++] = 'K' | mask;
    break;
  case  PDF_COLORSPACE_TYPE_GRAY:
    fmt_buf[len++] = 'G' | mask;
    break;
  default: /* already verified the given color */
    break;
  }
  pdf_doc_add_page_content(fmt_buf, len);  /* op: RG K G rg k g */

  pdf_color_copycolor(current, color);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int pdf_dev_setdash ( int  count,
double *  pattern,
double  offset 
)

Definition at line 1430 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  int         len = 0;
  char       *buf = FORMAT_BUFF_PTR(NULL);
  int         i;

  gs->linedash.num_dash = count;
  gs->linedash.offset   = offset;
  pdf_doc_add_page_content(" [", 2);  /* op: */
  for (i = 0; i < count; i++) {
    buf[0] = ' ';
    len = pdf_sprint_length (buf + 1, pattern[i]);
    pdf_doc_add_page_content(buf, len + 1);  /* op: */
    gs->linedash.pattern[i] = pattern[i];
  }
  pdf_doc_add_page_content("] ", 2);  /* op: */
  len = pdf_sprint_length (buf, offset);
  pdf_doc_add_page_content(buf, len);  /* op: */
  pdf_doc_add_page_content(" d", 2);  /* op: d */

  return 0;
}

Here is the call graph for this function:

int pdf_dev_setlinecap ( int  capstyle)

Definition at line 1376 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  int         len = 0;
  char       *buf = FORMAT_BUFF_PTR(NULL);

  if (gs->linecap != capstyle) {
    len = sprintf(buf, " %d J", capstyle);
    pdf_doc_add_page_content(buf, len);  /* op: J */
    gs->linecap = capstyle;
  }

  return 0;
}

Here is the call graph for this function:

int pdf_dev_setlinejoin ( int  joinstyle)

Definition at line 1393 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  int         len = 0;
  char       *buf = FORMAT_BUFF_PTR(NULL);

  if (gs->linejoin != joinstyle) {
    len = sprintf(buf, " %d j", joinstyle);
    pdf_doc_add_page_content(buf, len);  /* op: j */
    gs->linejoin = joinstyle;
  }

  return 0;
}

Here is the call graph for this function:

int pdf_dev_setlinewidth ( double  width)

Definition at line 1410 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);  
  int         len = 0;
  char       *buf = FORMAT_BUFF_PTR(NULL);

  if (gs->linewidth != width) {
    buf[len++] = ' ';
    len += pdf_sprint_length(buf + len, width);
    buf[len++] = ' ';
    buf[len++] = 'w';
    pdf_doc_add_page_content(buf, len);  /* op: w */
    gs->linewidth = width;
  }

  return 0;
}

Here is the call graph for this function:

int pdf_dev_setmiterlimit ( double  mlimit)

Definition at line 1356 of file pdfdraw.c.

{
  m_stack    *gss = &gs_stack;
  pdf_gstate *gs  = m_stack_top(gss);
  int         len = 0;
  char       *buf = FORMAT_BUFF_PTR(NULL);

  if (gs->miterlimit != mlimit) {
    buf[len++] = ' ';
    len += pdf_sprint_length(buf + len, mlimit);
    buf[len++] = ' ';
    buf[len++] = 'M';
    pdf_doc_add_page_content(buf, len);  /* op: M */
    gs->miterlimit = mlimit;
  }

  return 0;
}

Here is the call graph for this function:

void pdf_dev_transform ( pdf_coord p,
const pdf_tmatrix M 
)

Definition at line 1667 of file pdfdraw.c.

{
  m_stack     *gss = &gs_stack;
  pdf_gstate  *gs  = m_stack_top(gss);
  pdf_tmatrix *CTM = &gs->matrix;

  ASSERT(p);

  pdf_coord__transform(p, (M ? M : CTM));

  return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 194 of file pdfdraw.c.

{
  pdf_tmatrix W;  
  double      det;

  ASSERT(M);

  det = detP(M);
  if (fabs(det) < 1.e-8) {
    WARN("Inverting matrix with zero determinant...");
    W.a = 1.0; W.c = 0.0;
    W.b = 0.0; W.d = 1.0;
    W.e = 0.0; W.f = 0.0;
  } else {
    W.a =  (M->d) / det;  W.b = -(M->b) / det;
    W.c = -(M->c) / det;  W.d =  (M->a) / det;
    W.e =  (M->c) * (M->f) - (M->d) * (M->e);
    W.f =  (M->b) * (M->e) - (M->a) * (M->f);
  }

  pdf_copymatrix(M, &W);

  return;
}

Here is the call graph for this function:

static void pdf_path__clearpath ( pdf_path *  p) [static]

Definition at line 284 of file pdfdraw.c.

{
  ASSERT(p);

  p->num_paths = 0;
  
  return;
}

Here is the caller graph for this function:

static int pdf_path__closepath ( pdf_path *  pa,
pdf_coord cp 
) [static]

Definition at line 626 of file pdfdraw.c.

{
  pa_elem  *pe = NULL;
  int       i;

  /* search for start point of the last subpath */
  for (i = PA_LENGTH(pa) - 1; i >= 0; i--) {
    pe = &pa->path[i];
    if (pe->type == PE_TYPE__MOVETO)
      break;
  }

  if (!pe || i < 0)
    return -1; /* No path or no start point(!) */

  cp->x = pe->p[0].x;
  cp->y = pe->p[0].y;

  pdf_path__growpath(pa, PA_LENGTH(pa) + 1);

  /* NOTE:
   *  Manually closed path without closepath is not
   *  affected by linejoin. A path with coincidental
   *  starting and ending point is not the same as
   *  'closed' path.
   */
  pe = &pa->path[pa->num_paths++];
  pe->type = PE_TYPE__CLOSEPATH;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_path__copypath ( pdf_path *  p1,
const pdf_path *  p0 
) [static]

Definition at line 320 of file pdfdraw.c.

{
  pa_elem  *pe0, *pe1;
  int       i;

  pdf_path__growpath(p1, PA_LENGTH(p0));
  for (i = 0; i < PA_LENGTH(p0); i++) {
    pe1 = &(p1->path[i]);
    pe0 = &(p0->path[i]);
    /* FIXME */
    pe1->type   = pe0->type;
    pe1->p[0].x = pe0->p[0].x;
    pe1->p[0].y = pe0->p[0].y;
    pe1->p[1].x = pe0->p[1].x;
    pe1->p[1].y = pe0->p[1].y;
    pe1->p[2].x = pe0->p[2].x;
    pe1->p[2].y = pe0->p[2].y;
  }
  p1->num_paths = PA_LENGTH(p0);

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_path__curveto ( pdf_path *  pa,
pdf_coord cp,
const pdf_coord p0,
const pdf_coord p1,
const pdf_coord p2 
) [static]

Definition at line 470 of file pdfdraw.c.

{
  pa_elem *pe;

  pe = pdf_path__next_pe(pa, cp);
  if (COORD_EQUAL(cp, p0)) {
    pe->type   = PE_TYPE__CURVETO_V;
    pe->p[0].x = p1->x;
    pe->p[0].y = p1->y;
    pe->p[1].x = cp->x = p2->x;
    pe->p[1].y = cp->y = p2->y;
  } else if (COORD_EQUAL(p1, p2)) {
    pe->type   = PE_TYPE__CURVETO_Y;
    pe->p[0].x = p0->x;
    pe->p[0].y = p0->y;
    pe->p[1].x = cp->x = p1->x;
    pe->p[1].y = cp->y = p1->y;
  } else {
    pe->type   = PE_TYPE__CURVETO;
    pe->p[0].x = p0->x;
    pe->p[0].y = p0->y;
    pe->p[1].x = p1->x;
    pe->p[1].y = p1->y;
    pe->p[2].x = cp->x = p2->x;
    pe->p[2].y = cp->y = p2->y;
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_path__elliptarc ( pdf_path *  pa,
pdf_coord cp,
const pdf_coord ca,
double  r_x,
double  r_y,
double  xar,
double  a_0,
double  a_1,
int  a_d 
) [static]

Definition at line 531 of file pdfdraw.c.

{
  double      b, b_x, b_y;
  double      d_a, q;
  pdf_coord   p0, p1, p2, p3;
  pdf_coord   e0, e1;
  pdf_tmatrix T;
  int         n_c; /* number of segments */
  int         i, error = 0;

  if (fabs(r_x) < 1.e-8 ||
      fabs(r_y) < 1.e-8)
    return -1;

  if (a_d < 0) {
    for ( ; a_1 > a_0; a_1 -= 360.0);
  } else {
    for ( ; a_1 < a_0; a_0 -= 360.0);
  }

  d_a  = a_1 - a_0;
  for (n_c = 1; fabs(d_a) > 90.0 * n_c; n_c++);
  d_a /= n_c;
  if (fabs(d_a) < 1.e-8)
    return -1;

  a_0 *= M_PI / 180.0;
  a_1 *= M_PI / 180.0;
  d_a *= M_PI / 180.0;
  xar *= M_PI / 180.0;
  T.a  = cos(xar);  T.c = -sin(xar);
  T.b  = -T.c    ;  T.d = T.a;
  T.e  = 0.0     ;  T.f = 0.0;

  /* A parameter that controls cb-curve (off-curve) points */
  b    = 4.0 * (1.0 - cos(.5 * d_a)) / (3.0 * sin(.5 * d_a));
  b_x  = r_x * b;
  b_y  = r_y * b;

  p0.x = r_x * cos(a_0);
  p0.y = r_y * sin(a_0);
  pdf_coord__transform(&p0, &T);
  p0.x += ca->x; p0.y += ca->y;
  if (PA_LENGTH(pa) == 0) {
    pdf_path__moveto(pa, cp, &p0);
  } else if (!COORD_EQUAL(cp, &p0)) {
    pdf_path__lineto(pa, cp, &p0); /* add line seg */
  } 
  for (i = 0; !error && i < n_c; i++) {
    q = a_0 + i * d_a;
    e0.x = cos(q); e0.y = sin(q);
    e1.x = cos(q + d_a); e1.y = sin(q + d_a);

   /* Condition for tangent vector requirs
    *  d1 = p1 - p0 = f ( sin a, -cos a)
    *  d2 = p2 - p3 = g ( sin b, -cos b)
    * and from symmetry
    *  g^2 = f^2
    */ 
    p0.x = r_x * e0.x; /* s.p. */
    p0.y = r_y * e0.y;
    p3.x = r_x * e1.x; /* e.p. */
    p3.y = r_y * e1.y;

    p1.x = -b_x * e0.y;
    p1.y =  b_y * e0.x;
    p2.x =  b_x * e1.y;
    p2.y = -b_y * e1.x;

    pdf_coord__transform(&p0, &T);
    pdf_coord__transform(&p1, &T);
    pdf_coord__transform(&p2, &T);
    pdf_coord__transform(&p3, &T);
    p0.x += ca->x; p0.y += ca->y;
    p3.x += ca->x; p3.y += ca->y;
    p1.x += p0.x ; p1.y += p0.y ;
    p2.x += p3.x ; p2.y += p3.y ;

    error = pdf_path__curveto(pa, &p0, &p1, &p2, &p3);
    cp->x = p3.x; cp->y = p3.y;
  }

  return error;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_path__growpath ( pdf_path *  p,
int  max_pe 
) [static]

Definition at line 294 of file pdfdraw.c.

{
  if (max_pe < p->max_paths)
    return 0;

  p->max_paths = MAX(p->max_paths + 8, max_pe);
  p->path = RENEW(p->path, p->max_paths, pa_elem);

  return 0;
}

Here is the caller graph for this function:

static int pdf_path__isarect ( pdf_path *  pa,
int  f_ir 
) [static]

Definition at line 671 of file pdfdraw.c.

{
  pa_elem *pe0, *pe1, *pe2, *pe3, *pe4;

  if (PA_LENGTH(pa) == 5) {
    pe0 = &(pa->path[0]);
    pe1 = &(pa->path[1]);
    pe2 = &(pa->path[2]);
    pe3 = &(pa->path[3]);
    pe4 = &(pa->path[4]);
    if (pe0->type == PE_TYPE__MOVETO &&
        pe1->type == PE_TYPE__LINETO &&
        pe2->type == PE_TYPE__LINETO &&
        pe3->type == PE_TYPE__LINETO &&
        pe4->type == PE_TYPE__CLOSEPATH) {
      if (pe1->p[0].y - pe0->p[0].y == 0 &&
          pe2->p[0].x - pe1->p[0].x == 0 &&
          pe3->p[0].y - pe2->p[0].y == 0) {
        if (pe1->p[0].x - pe0->p[0].x
            == pe2->p[0].x - pe3->p[0].x) {
          return 1;
        }
    /* Winding number is different but ignore it here. */
      } else if (f_ir &&
                 pe1->p[0].x - pe0->p[0].x == 0 &&
                 pe2->p[0].y - pe1->p[0].y == 0 &&
                 pe3->p[0].x - pe2->p[0].x == 0) {
        if (pe1->p[0].y - pe0->p[0].y
              == pe2->p[0].y - pe3->p[0].y) {
          return 1;
        }
      }
    }
  }

  return 0;
}

Here is the caller graph for this function:

static int pdf_path__lineto ( pdf_path *  pa,
pdf_coord cp,
const pdf_coord p0 
) [static]

Definition at line 455 of file pdfdraw.c.

{
  pa_elem  *pe;

  pe = pdf_path__next_pe(pa, cp);
  pe->type   = PE_TYPE__LINETO;
  pe->p[0].x = cp->x = p0->x;
  pe->p[0].y = cp->y = p0->y;

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_path__moveto ( pdf_path *  pa,
pdf_coord cp,
const pdf_coord p0 
) [static]

Definition at line 346 of file pdfdraw.c.

{
  pa_elem  *pe;
  
  pdf_path__growpath(pa, PA_LENGTH(pa) + 1);
  if (PA_LENGTH(pa) > 0) {
    pe = &pa->path[pa->num_paths-1];
    if (pe->type == PE_TYPE__MOVETO) {
      pe->p[0].x = cp->x = p0->x;
      pe->p[0].y = cp->y = p0->y;
      return 0;
    }
  }
  pe = &pa->path[pa->num_paths++];
  pe->type   = PE_TYPE__MOVETO;
  pe->p[0].x = cp->x = p0->x;
  pe->p[0].y = cp->y = p0->y;

  return 0;  
}

Here is the call graph for this function:

Here is the caller graph for this function:

static pa_elem* pdf_path__next_pe ( pdf_path *  pa,
const pdf_coord cp 
) [static]

Definition at line 378 of file pdfdraw.c.

{
  pa_elem  *pe;

  pdf_path__growpath(pa, PA_LENGTH(pa) + 2);
  if (PA_LENGTH(pa) == 0) {
    pe = &pa->path[pa->num_paths++];
    pe->type   = PE_TYPE__MOVETO;
    pe->p[0].x = cp->x;
    pe->p[0].y = cp->y;

    return &pa->path[pa->num_paths++];
  }
    
  pe = &pa->path[pa->num_paths-1];
  switch (pe->type) {
  case PE_TYPE__MOVETO:
    pe->p[0].x = cp->x;
    pe->p[0].y = cp->y;
    break;
  case PE_TYPE__LINETO:
    if (!COORD_EQUAL(&pe->p[0], cp)) {
      pe = &pa->path[pa->num_paths++];
      pe->type   = PE_TYPE__MOVETO;
      pe->p[0].x = cp->x;
      pe->p[0].y = cp->y;
    }
    break;
  case PE_TYPE__CURVETO:
    if (!COORD_EQUAL(&pe->p[2], cp)) {
      pe = &pa->path[pa->num_paths++];
      pe->type   = PE_TYPE__MOVETO;
      pe->p[0].x = cp->x;
      pe->p[0].y = cp->y;
    }
    break;
  case PE_TYPE__CURVETO_Y:
  case PE_TYPE__CURVETO_V:
    if (!COORD_EQUAL(&pe->p[1], cp)) {
      pe = &pa->path[pa->num_paths++];
      pe->type   = PE_TYPE__MOVETO;
      pe->p[0].x = cp->x;
      pe->p[0].y = cp->y;
    }
    break;
  case PE_TYPE__CLOSEPATH:
    pe = &pa->path[pa->num_paths++];
    pe->type   = PE_TYPE__MOVETO;
    pe->p[0].x = cp->x;
    pe->p[0].y = cp->y;
    break;
  }

  return &pa->path[pa->num_paths++];
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int pdf_path__transform ( pdf_path *  pa,
const pdf_tmatrix M 
) [static]

Definition at line 435 of file pdfdraw.c.

{
  pa_elem *pe;
  int      n = 0, i;

  ASSERT(pa && M);

  for (i = 0; i < PA_LENGTH(pa); i++) {
    pe = &(pa->path[i]);
    n  = PE_N_PTS(pe);
    while (n-- > 0)
      pdf_coord__transform(&(pe->p[n]), M);
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char fmt_buf[1024] [static]

Definition at line 267 of file pdfdraw.c.

m_stack gs_stack [static]

Definition at line 997 of file pdfdraw.c.

struct { ... } petypes[] [static]