/*
Copyright (c) 2004-2005, Dirk Krause
All rights reserved.

Redistribution and use in source and binary forms,
with or without modification, are permitted provided
that the following conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.
* Redistributions in binary form must reproduce the above 
  opyright notice, this list of conditions and the following
  disclaimer in the documentation and/or other materials
  provided with the distribution.
* Neither the name of the Dirk Krause nor the names of
  its contributors may be used to endorse or promote
  products derived from this software without specific
  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/

#define DKFIGPDF_C 1
#include "dkfig.h"

#line 40 "dkfigpdf.ctr"




/* {{{ HAVE_....

   These flags indicate which information was
   already written to the PDF file.

*/
#define HAVE_STROKE_COLOR	1
#define HAVE_NON_STROKE_COLOR	2
#define HAVE_DASH		4
#define HAVE_LINEWIDTH		8
#define HAVE_LINECAP		16
#define HAVE_LINEJOIN		32
/* }}} */



/* {{{ kw

   The keywords used by this driver.

*/
typedef char *PCHAR;
static char *kw[] = {
  /*   0 */ "\r\n",
  /*   1 */ " ",
  /*   2 */ "%PDF-1.4",
  /*   3 */ " 0 obj",
  /*   4 */ "endobj",
  /*   5 */ "<<",
  /*   6 */ ">>",
  /*   7 */ "xref",
  /*   8 */ "f",
  /*   9 */ "n",
  /*  10 */ "trailer",
  /*  11 */ "/Size",
  /*  12 */ "/Root",
  /*  13 */ "R",
  /*  14 */ "/Info",
  /*  15 */ "startxref",
  /*  16 */ "%%EOF",
  /*  17 */ "0000000000 65535 f",
  /*  18 */ " 00000 n",
  /*  19 */ "0",
  /*  20 */ "/Producer (fig2vect, see http://fig2vect.sourceforge.net)",
  /*  21 */ "/Type /Catalog /Pages 3 0 R",
  /*  22 */ "/Type /Pages /Kids [4 0 R] /Count 1",
  /*  23 */ "/Type /Page",
  /*  24 */ "/MediaBox [",
  /*  25 */ "]",
  /*  26 */ "/Rotate 0",
  /*  27 */ "/Parent 3 0 R",
  /*  28 */ "/Resources",
  /*  29 */ "/ProcSet [",
  /*  30 */ "/PDF",
  /*  31 */ "/ImageC",
  /*  32 */ "/ImageG",
  /*  33 */ "/XObject",
  /*  34 */ "/Pattern",
  /*  35 */ "/",
  /*  36 */ "/Contents 5 0 R",
  /*  37 */ "q",
  /*  38 */ "Q",
  /*  39 */ "/Length",
  /*  40 */ "/Filter [/ASCII85Decode /FlateDecode]",
  /*  41 */ "stream",
  /*  42 */ "endstream",
  /*  43 */ " /PageMode /FullScreen",
  /*  44 */ "/Font",
  /*  45 */ "Obj",
  /*  46 */"/Type /Font /Subtype /Type1 /Encoding /WinAnsiEncoding /BaseFont /",
  /*  47 */ "BT",
  /*  48 */ "ET",
  /*  49 */ "Tf",
  /*  50 */ "Td",
  /*  51 */ "Tj",
  /*  52 */ "(",
  /*  53 */ ")",
  /*  54 */ "/Text",
  /*  55 */ "cm",
  /*  56 */ "1",
  /*  57 */ "-",
  /*  58 */ "/ImageB",
  /*  59 */ "/ImageC",
  /*  60 */ "rg",
  /*  61 */ "RG",
  /*  62 */ "/Type /Pattern /PatternType 1 /PaintType 1 /TilingType 1",
  /*  63 */ "/BBox [0 0 ",
  /*  64 */ "/XStep",
  /*  65 */ "/YStep",
  /*  66 */ "m",		/* moveto */
  /*  67 */ "l",		/* lineto */
  /*  68 */ "h",		/* closepath */
  /*  69 */ "f",		/* fill (nonzero) */
  /*  70 */ "S",		/* stroke */
  /*  71 */ "w",		/* setlinewidth */
  /*  72 */ "/Pattern cs ",
  /*  73 */ "scn",		/* set color non-stroking */
  /*  74 */ "d",		/* setdash */
  /*  75 */ "[",
  /*  76 */ "J",		/* setlinecap */
  /*  77 */ "j",		/* setlinejoin */
  /*  78 */ "h B",		/* close, fill (nonzero), stroke */
  /*  79 */ "h B*",		/* close, fill (eo), stroke */
  /*  80 */ "h f",		/* close, fill (nonzero) */
  /*  81 */ "h f*",		/* close, fill (eo) */
  /*  82 */ "s",		/* close, stroke */
  /*  83 */ "c",		/* bezierto */
  /*  84 */ "% text ",
  /*  85 */ "% polyline ",
  /*  86 */ "% ellipse ",
  /*  87 */ "% spline ",
  /*  88 */ "% arc ",
  /*  89 */ "pdf",
  /*  90 */ "/Subtype /Image",
  /*  91 */ "/ColorSpace",
  /*  92 */ "/DeviceRGB",
  /*  93 */ "/DeviceGray",
  /*  94 */ "/BitsPerComponent 8",
  /*  95 */ "/Width",
  /*  96 */ "/Height",
  /*  97 */ "/Interpolate true",
  /*  98 */ "/SMask",
  /*  99 */ "0 R",
  /* 100 */ "/Type /XObject",
  /* 101 */ "Do",
  /* 102 */ "/CropBox [",
  /* 103 */ "h W n",
};
static size_t nkw = sizeof(kw)/sizeof(PCHAR);
/* }}} */



/* {{{ pdf_font_names

   Names of the PDF standard fonts.

*/
static char *pdf_font_names[] = {
  "Times-Roman", "Times-Bold", "Times-Italic", "Times-BoldItalic",
  "Helvetica", "Helvetica-Bold", "Helvetica-Oblique", "Helvetica-BoldOblique",
  "Courier", "Courier-Bold", "Courier-Oblique", "Courier-BoldOblique",
  "Symbol", "ZapfDingbats",
  NULL
}; /* }}} */


/* file open modes {{{ */
static char str_open_read_binary[] = { "rb" };
static char str_open_write_binary[] = { "wb" };
/* }}} */





/* {{{ pdf_arc_calc

   A struct to support arc / circle interpolations using
   Bezier splines.

   x(phi) = rx * cos(phi)
   y(phi) = ry * sin(phi)
   dx / dphi = - rx * sin (phi)
   dy / dphi =   ry * cos (phi)

*/
typedef struct {
  double xm;		/* center */
  double ym;
  double rx;		/* radius x */
  double ry;		/* radius y */
  double phi0;		/* arc start */
  double phi1;		/* arc end */
  unsigned segs;	/* number of bezier segments */
  double x0;		/* start and end point */
  double y0;
  double x1;
  double y1;
} pdf_arc_calc;
/* }}} */



/* {{{ OI OPOS PAT   are abbrebiations.
*/
typedef dkfig_pdf_output_instruction OI;
typedef dkfig_pdf_object_position OPOS;
typedef dkfig_pdf_pattern PAT;
/* }}} */


#define drd(v,o,w) dkfig_tool2_drd(v,o,w)
#define MULD(a,b,c) dkma_mul_double_ok(a,b,c)
#define DIVD(a,b,c) dkma_div_double_ok(a,b,c)
#define ADDD(a,b,c) dkma_add_double_ok(a,b,c)
#define SUBD(a,b,c) dkma_sub_double_ok(a,b,c)


/* {{{ new_drve - Create a new driver-specific extension
*/
static
dkfig_pdf_drve_text *new_drve DK_P0()
{
  dkfig_pdf_drve_text *back = NULL;
  
  back = dk_new(dkfig_pdf_drve_text,1);
  if(back) {
    back->fn = 0;
    back->p = NULL;
    back->i = NULL;
  } 
  return back;
} /* }}} */



/* {{{ delete_drve - Delete driver-specific extension
*/
static
void delete_drve DK_P1(dkfig_pdf_drve_text *,p)
{
  
  if(p) {
    p->fn = 0; p->p = NULL; p->i = NULL;
    dk_delete(p);
  } 
} /* }}} */



/* {{{ delete_image - Delete image extension data.
*/
static
void delete_image DK_P1(dkfig_pdf_image *,iptr)
{
  char *ptr;
  
  if(iptr) {
    if(iptr->inputfilename) {
      
      ptr = iptr->inputfilename;
      dk_delete((void *)ptr);
    } iptr->inputfilename = NULL;
    if(iptr->ofn) {
      dksf_remove_file(iptr->ofn);
      ptr = iptr->ofn;
      dk_delete((void *)ptr);
    } iptr->ofn = NULL;
    if(iptr->afn) {
      dksf_remove_file(iptr->afn);
      ptr = iptr->afn;
      dk_delete((void *)ptr);
    } iptr->afn = NULL;
    iptr->w = iptr->h = 0UL; iptr->bpp = iptr->ch = 0;
    dk_delete(iptr);
  } 
} /* }}} */



/* {{{ new_image - Create image extension data.
*/
static
dkfig_pdf_image *new_image DK_P1(char *,ifn)
{
  dkfig_pdf_image *back = NULL;
  
  if(ifn) {
    back = dk_new(dkfig_pdf_image,1);
    if(back) {
      DK_MEMRES(back,sizeof(dkfig_pdf_image));
      back->inputfilename = dkstr_dup(ifn);
      if(back->inputfilename) {
        back->flipped = 0;
        back->ofn = back->afn = NULL;
	back->w = back->h = 0UL;
	back->bpp = back->ch = 0;
	back->ol = back->al = 0UL;
      } else {
        dk_delete(back); back = NULL;
      }
    }
  } 
  return back;
} /* }}} */



/* {{{ compate_image - Comparison function for sorted storage.
*/
static
int compare_images DK_P3(void *,l, void *,r, int,cr)
{
  int back = 0;
  dkfig_pdf_image *pr, *pl;
  
  if(l) {
    if(r) {
      pl = (dkfig_pdf_image *)l; pr = (dkfig_pdf_image *)r;
      if(pl->inputfilename) {
        if(pr->inputfilename) {
	  
#if DK_HAVE_FNCASEINS
          back = dkstr_casecmp(pl->inputfilename, pr->inputfilename);
#else
          back = strcmp(pl->inputfilename, pr->inputfilename);
#endif
	} else { back = 1; }
      } else {
        if(pr->inputfilename) { back = -1; }
      }
      if(!back) {
        if(pl->flipped > pr->flipped) {
	  back = 1;
	} else {
	  if(pl->flipped < pr->flipped) {
	    back = -1;
	  }
	}
      }
    } else { back = 1; }
  } else {
    if(r) { back = -1; }
  } 
  return back;
} /* }}} */



/* {{{ ccdx - convert coordinates double x
*/
static double ccdx DK_P2(OI *,oi, double,x)
{
  double back;
  back = dkma_add_double_ok(
    dkma_mul_double_ok(oi->xfactor, x, &(oi->me)),
    oi->xadd,
    &(oi->me)
  );
  return back;
} /* }}} */



/* {{{ ccdy - convert coordinates double y
*/
static double ccdy DK_P2(OI *,oi, double,y)
{
  double back;
  back = dkma_add_double_ok(
    dkma_mul_double_ok(oi->yfactor, y, &(oi->me)),
    oi->yadd,
    &(oi->me)
  );
  return back;
} /* }}} */



/* {{{ cclx - convert coordinates long x
*/
static double cclx DK_P2(OI *,oi, long,x)
{
  return(ccdx(oi, dkma_l_to_double(x)));
} /* }}} */



/* {{{ ccly - convert coordinates long y
*/
static double ccly DK_P2(OI *,oi, long,y)
{
  return(ccdy(oi, dkma_l_to_double(y)));
} /* }}} */



/* {{{ null_oi - initialize OI
*/
static
void null_oi DK_P1(OI *,oi)
{
  DK_MEMRES(oi, sizeof(OI));
  oi->c    = NULL;
  oi->d    = NULL;
  oi->s    = NULL; oi->gcs = NULL;
  oi->pdfo = NULL; oi->pdfoi = NULL;
  oi->fl   = NULL;  oi->fli = NULL;
  oi->ec   = 0;
  oi->me   = 0;
  oi->patl = NULL; oi->patli = NULL;
  oi->imgl = NULL; oi->imgli = NULL;
  oi->co = NULL;
  oi->fu = NULL;
  oi->no   = 1UL; oi->nostr = (size_t)0;
  oi->me = 0; oi->procs = 0; oi->flags = 0;
  oi->xfactor = 0.06;
  oi->yfactor = 0.06;
  oi->xadd = 0.0; oi->yadd = 0.0;
  oi->xleft = oi->xright = oi->ybottom = oi->ytop = 0.0;
  (oi->strok).red = (oi->strok).green = (oi->strok).blue = 0.0;
  (oi->nonst).red = (oi->nonst).green = (oi->nonst).blue = 0.0;
  oi->spcpass = 0;
  oi->errprinted = 0;
} /* }}} */



/* {{{ compare_object_positions - comparison for sorted storage
*/
static
int
compare_object_positions DK_P3(void *,l, void *,r, int,c)
{
  int back = 0;
  OPOS *pl, *pr;
  pl = (OPOS *)l; pr = (OPOS *)r;
  if(pl) {
    if(pr) {
      if(pl->objno > pr->objno) {
        back = 1;
      } else {
        if(pl->objno < pr->objno) {
	  back = -1;
	}
      }
    } else {
      back = 1;
    }
  } else {
    if(pr) {
      back = -1;
    }
  }
  return back;
} /* }}} */



/* {{{ compare_pattern - Comparison for sorted storage
*/
static
int
compare_pattern DK_P3(void *,l, void *,r, int,cr)
{
  int back = 0;
  dkfig_pdf_pattern *pl, *pr;
  pl = (dkfig_pdf_pattern *)l; pr = (dkfig_pdf_pattern *)r;
  if(l) {
    if(r) {
      if(pl->patno > pr->patno) {
        back = 1;
      } else {
        if(pl->patno < pr->patno) {
	  back = -1;
	}
      }
      if(!back) {
        if(pl->bgcol > pr->bgcol) {
	  back = 1;
	} else {
	  if(pl->bgcol < pr->bgcol) {
	    back = -1;
	  }
	}
      }
      if(!back) {
        if(pl->fgcol > pr->fgcol) {
	  back = 1;
	} else {
	  if(pl->fgcol < pr->fgcol) {
	    back = -1;
	  }
	}
      }
      /* 
      if(!back) {
        if(pl->lt > pr->lt) {
	  back = 1;
	} else {
	  if(pl->lt < pr->lt) {
	    back = -1;
	  }
	}
      }
      */
      if(!back) {
        if(pl->tile > pr->tile) {
	  back = 1;
	} else {
	  if(pl->tile < pr->tile) {
	    back = -1;
	  }
	}
      }
    } else {
      back = 1;
    }
  } else {
    if(r) {
      back = -1;
    }
  }
  return back;
} /* }}} */



/* {{{ kw_out - write keyword to output stream
*/
static
void kw_out DK_P2(OI *,oi, size_t,n)
{
  if(oi) {
    if(oi->s) {
      if(n < nkw) {
        dkstream_puts(oi->s, kw[n]);
      }
    }
  }
} /* }}} */



/* {{{ is_literal: check whether or not to encode octal
*/
static int
is_literal DK_P1(char,c)
{
  int back = 0;
  if((c >= 'A') && (c <= 'Z')) {
    back = 1;
  } else {
    if((c >= 'a') && (c <= 'z')) {
      back = 1;
    } else {
      if((c >= '0') && (c <= '9')) {
        back = 1;
      } else {
        switch(c) {
	  case ' ':
	  {
	    back = 1;
	  } break;
	}
      }
    }
  }
  return back;
} /* }}} */



/* {{{ gcs_out - write keyword to graphics contents stream (gcs)
*/
static
void gcs_out DK_P2(OI *,oi, size_t,n)
{
  if(oi) {
    if(oi->gcs) {
      if(n < nkw) {
        dkstream_puts(oi->gcs, kw[n]);
      }
    }
  }
} /* }}} */



/* {{{ pdf_encode_utf8 - write string to gcs
*/
static
void pdf_encode_utf8 DK_P3(OI *,oi, dk_stream_t *,s, char *,str)
{
  int cc;
  dk_udword ucb; unsigned char uc; char chr; int i;
  size_t max, avail, used, step;
  char buffer[128];
  
  dkstream_puts(s, kw[52]);
  cc = 1; max = strlen(str); avail = max; used = 0; step = 0;
  while(cc) {
    cc = 0;
    if(avail) {
      step = 0;
      cc = dkenc_utf82uc(&ucb, (unsigned char *)(&(str[used])), avail, &step);
      if(cc) {
        used = used + step;
	if(avail > step) {
	  avail = avail - step;
	} else {
	  avail = 0;
	}
	uc = (unsigned char)ucb; chr = (char)uc; i = (int)chr;
	if(ucb < 256UL) {
	  
	  if(is_literal(chr)) {
	    buffer[0] = uc; buffer[1] = '\0';
	  } else {
	    if(i < 0) { i = i + 256; }
	    if(i < 0) { i = 0; }
	    if(i > 255) { i = 255; }
#if DK_HAVE_SNPRINTF
              snprintf(buffer, sizeof(buffer), "\\%03o", i);
	      buffer[sizeof(buffer)-1] = '\0';
#else
              sprintf(buffer, "\\%03o", i);
#endif
	  } 
	  dkstream_puts(s, buffer);
	}
      }
    }
  }
  dkstream_puts(s, kw[53]);
  
} /* }}} */



/* {{{ pdf_encode_str - write string to gcs
*/
static
void pdf_encode_str DK_P3(OI *,oi, dk_stream_t *,s, char *,str)
{
  char buffer[128];
  char c, *ptr;
  int  i;
  
  if(str) { 
  }
  ptr = str;
  dkstream_puts(s, kw[52]);
  while(*ptr) {
    c = *(ptr++); 
    if(is_literal(c)) {
      buffer[0] = c; buffer[1] = '\0';
    } else {
      i = c;
      if(i < 0) { i = 256 + i; }
      if(i < 0) { i = 0; }
      if(i > 255) { i = 255; }
#if DK_HAVE_SNPRINTF || HAVE_SNPRINTF
      snprintf(buffer, sizeof(buffer), "\\%03o", i);
      buffer[sizeof(buffer)-1] = '\0';
#else
      sprintf(buffer, "\\%03o", i);
#endif
    } 
    dkstream_puts(s, buffer);
  }
  dkstream_puts(s, kw[53]);
  
} /* }}} */



/* {{{ double_nearly_equal

   Check whether or not two double values are
   nearly equal.

*/
static int
double_nearly_equal DK_P2(double,d1,double,d2)
{
  int back = 0;
  int me = 0;
  double diff;
  diff = fabs(dkma_sub_double_ok(d1,d2,&me));
  if(!me) {
    if(diff < DKFIG_EPSILON) {
      back = 1;
    }
  }
  return back;
}
/* }}} */



/* {{{ set_stroking
*/
static
void write_dcc_triple DK_P2(OI *,oi, dk_fig_dcc *,dcc)
{
  dkstream_puts_double(oi->gcs, drd(dcc->red, oi->c, 0));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(dcc->green, oi->c, 0));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(dcc->blue, oi->c, 0));
  gcs_out(oi, 1);
}
static
void ll_set_stroking DK_P2(OI *,oi, dk_fig_dcc *,dcc)
{
  write_dcc_triple(oi, dcc);
  gcs_out(oi, 61); gcs_out(oi, 0);
}
static
void set_stroking DK_P2(OI *,oi, dk_fig_dcc *,dcc)
{
  int must_set = 1;
  if((oi->flags) & HAVE_STROKE_COLOR) {
    if(double_nearly_equal((oi->strok).red, dcc->red)) {
    if(double_nearly_equal((oi->strok).green, dcc->green)) {
    if(double_nearly_equal((oi->strok).blue, dcc->blue)) {
      must_set = 0;
    } } }
  }
  if(must_set) {
    oi->flags |= HAVE_STROKE_COLOR;
    (oi->strok).red = dcc->red;
    (oi->strok).green = dcc->green;
    (oi->strok).blue = dcc->blue;
    ll_set_stroking(oi, dcc);
  }
}
/* }}} */



/* {{{ set_nonstroking
*/
static
void ll_set_nonstroking DK_P2(OI *,oi, dk_fig_dcc *,dcc)
{
  write_dcc_triple(oi, dcc);
  gcs_out(oi, 60); gcs_out(oi, 0);
}
static
void set_nonstroking DK_P2(OI *,oi, dk_fig_dcc *,dcc)
{
  int must_set = 1;
  if((oi->flags) & HAVE_NON_STROKE_COLOR) {
    if(double_nearly_equal((oi->nonst).red, dcc->red)) {
    if(double_nearly_equal((oi->nonst).green, dcc->green)) {
    if(double_nearly_equal((oi->nonst).blue, dcc->blue)) {
      must_set = 0;
    } } }
  }
  if(must_set) {
    oi->flags |= HAVE_NON_STROKE_COLOR;
    (oi->nonst).red = dcc->red;
    (oi->nonst).green = dcc->green;
    (oi->nonst).blue = dcc->blue;
    ll_set_nonstroking(oi, dcc);
  }
} /* }}} */



/* {{{ get_object_linewidth
*/
static
double get_object_linewidth DK_P1(OI *,oi)
{
  double back = 0.0;
  back = dkma_mul_double_ok(
    0.9,
    dkma_l_to_double(((oi->co)->fpd).lt),
    &(oi->me)
  );
  if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) {
    back = 0.5 * back;
  }
  return back;
} /* }}} */



/* {{{ set_linecap
*/
static
void ll_set_linecap DK_P2(OI *,oi, int,lc)
{
  dkstream_puts_long(oi->gcs, (long)lc);
  gcs_out(oi, 1); gcs_out(oi, 76); gcs_out(oi, 0);
}
static
void set_linecap DK_P2(OI *,oi, int,lc)
{
  int must_set = 1;
  if((oi->flags) & HAVE_LINECAP) {
  if(oi->lc == lc) {
    must_set = 0;
  } }
  if(must_set) {
    oi->flags |= HAVE_LINECAP;
    oi->lc = lc;
    ll_set_linecap(oi, lc);
  }
} /* }}} */



/* {{{ set_linejoin
*/
static
void ll_set_linejoin DK_P2(OI *,oi, int,lj)
{
  dkstream_puts_long(oi->gcs, (long)lj);
  gcs_out(oi, 1); gcs_out(oi, 77); gcs_out(oi, 0);
}
static
void set_linejoin DK_P2(OI *,oi, int,lj)
{
  int must_set = 1;
  if((oi->flags) & HAVE_LINEJOIN) {
  if(oi->lj == lj) {
    must_set = 0;
  } }
  if(must_set) {
    oi->flags |= HAVE_LINEJOIN;
    oi->lj = lj;
    ll_set_linejoin(oi,lj);
  }
} /* }}} */



/* {{{ set_dash
*/
static
void set_dash DK_P3(OI *,oi, int,ls, double,sv)
{
  int must_set = 1;
  if((oi->flags) & HAVE_DASH) {
    if(oi->dash == ls) {
    if(double_nearly_equal(sv, oi->dasv)) {
      must_set = 0;
    } }
  }
  if(must_set) {
    double s, l;
    oi->flags |= HAVE_DASH;
    oi->dash = ls; oi->dasv = sv;
    s = 0.9 * sv;
    l = get_object_linewidth(oi);
    gcs_out(oi, 75);
    switch(ls) {
      case 2: {
        if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) {
	  dkstream_puts_double(oi->gcs, drd(l, oi->c, 1));
	} else {
	  dkstream_puts_long(oi->gcs, 0L);
	}
	gcs_out(oi, 1);
	dkstream_puts_double(oi->gcs, drd(s, oi->c, 1));
      } break;
      case 1: case 3: case 4: case 5: {
        dkstream_puts_double(oi->gcs, drd(s, oi->c, 1));
	gcs_out(oi, 1);
	dkstream_puts_double(oi->gcs, drd(s, oi->c, 1));
	if(ls > 1) {
          gcs_out(oi, 1);
          if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) {
	    dkstream_puts_double(oi->gcs, drd(l, oi->c, 1));
	  } else {
	    dkstream_puts_long(oi->gcs, 0L);
	  }
	  gcs_out(oi, 1);
	  dkstream_puts_double(oi->gcs, drd(s, oi->c, 1));
	  if(ls > 3) {
	    gcs_out(oi, 1);
	    if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) {
	      dkstream_puts_double(oi->gcs, drd(l, oi->c, 1));
	    } else {
	      dkstream_puts_long(oi->gcs, 0L);
	    }
	    gcs_out(oi, 1);
	    dkstream_puts_double(oi->gcs, drd(s, oi->c, 1));
	    if(ls > 4) {
	      gcs_out(oi, 1);
	      if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) {
	        dkstream_puts_double(oi->gcs, drd(l, oi->c, 1));
	      } else {
	        dkstream_puts_long(oi->gcs, 0L);
	      }
	      gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, drd(s, oi->c, 1));
	    }
	  }
	}
      } break;
    }
    gcs_out(oi, 25); gcs_out(oi, 1);
    gcs_out(oi, 19); gcs_out(oi, 1);
    gcs_out(oi, 74); gcs_out(oi, 0);
  }
} /* }}} */



/* {{{ set_linewidth
*/
static
void ll_set_linewidth DK_P2(OI *,oi, double,lw)
{
  dkstream_puts_double(oi->gcs, drd(lw, oi->c, 1));
  gcs_out(oi, 1); gcs_out(oi, 71); gcs_out(oi, 0);
}
static
void set_linewidth DK_P2(OI *,oi, double,lw)
{
  int must_set = 1;
  if((oi->flags) & HAVE_LINEWIDTH) {
    if(double_nearly_equal(oi->lw, lw)) {
      must_set = 0;
    }
  }
  if(must_set) {
    oi->lw = lw;
    oi->flags |= HAVE_LINEWIDTH;
    ll_set_linewidth(oi, lw);
  }
} /* }}} */



/* {{{ begin_object - Begin new PDF object, save start position

*/
static
int begin_object DK_P2(OI *,oi, unsigned long,objno)
{
  int back = 0;
  OPOS pos, *pp;
  pos.objno = objno;
  pos.pos = dkstream_get_bytes_written(oi->s);
  if(!(dksto_it_find_like(oi->pdfoi, (void *)(&pos), 0))) {
    pp = dk_new(OPOS, 1);
    if(pp) {
      pp->objno = objno;
      pp->pos = pos.pos;
      if(dksto_add(oi->pdfo, (void *)pp)) {
        back = 1;
	dkstream_puts_ul(oi->s, objno);
	kw_out(oi, 3);
	kw_out(oi, 0);
      } else {
        dk_delete(pp);
	if((oi->c)->app) {
	  dkapp_err_memory((oi->c)->app, sizeof(dk_storage_node_t), 1);
	}
      }
    } else {
      if((oi->c)->app) {
        dkapp_err_memory((oi->c)->app, sizeof(OPOS), 1);
      }
    }
  }
  return back;
} /* }}} */



/* {{{ end_object - End PDF object
*/
static
void end_object DK_P1(OI *,oi)
{
  kw_out(oi, 4);
  kw_out(oi, 0);
} /* }}} */



/* {{{ finalize_pdf - write xref section ...
*/
static
int finalize_pdf DK_P1(OI *,oi)
{
  int back = 0;
  OPOS *p;
  unsigned long xrefpos;
  char buffer[32];
  xrefpos = dkstream_get_bytes_written(oi->s);
  kw_out(oi, 7); kw_out(oi, 0);
  dkstream_puts_ul(oi->s, 0UL);
  kw_out(oi, 1);
  dkstream_puts_ul(oi->s, oi->no);
  kw_out(oi, 0);
  kw_out(oi, 17); kw_out(oi, 0);
  dksto_it_reset(oi->pdfoi);
  while((p = (OPOS *)dksto_it_next(oi->pdfoi)) != NULL) {
#if DK_HAVE_SNPRINTF
    snprintf(buffer, sizeof(buffer), "%010lu", p->pos);
    buffer[sizeof(buffer)-1] = '\0';
#else
    sprintf(buffer, "%010lu", p->pos);
#endif
    dkstream_puts(oi->s, buffer);
    kw_out(oi, 18); kw_out(oi, 0);
  }
  kw_out(oi, 10); kw_out(oi, 0);
  kw_out(oi, 5); kw_out(oi, 1);
  kw_out(oi, 11); kw_out(oi, 1);
  dkstream_puts_ul(oi->s, oi->no);
  kw_out(oi, 1);
  kw_out(oi, 14); kw_out(oi, 1); dkstream_puts_ul(oi->s, 1UL);
  kw_out(oi, 1); kw_out(oi, 19); kw_out(oi, 1); kw_out(oi, 13);
  kw_out(oi, 1);
  kw_out(oi, 12); kw_out(oi, 1); dkstream_puts_ul(oi->s, 2UL);
  kw_out(oi, 1); kw_out(oi, 19); kw_out(oi, 1); kw_out(oi, 13);
  kw_out(oi, 1);
  kw_out(oi, 6); kw_out(oi, 0);
  kw_out(oi, 15); kw_out(oi, 0);
  dkstream_puts_ul(oi->s, xrefpos); kw_out(oi, 0);
  kw_out(oi, 16); kw_out(oi, 0);
  back = 1;
  return back;
} /* }}} */



/* {{{ establish_coord_transformation
*/
static
int establish_coord_transformation DK_P1(OI *,oi)
{
  int back = 1;
  double xmin = 0.0, ymin = 0.0, xmax = 0.0, ymax = 0.0;
  double cxmin, cxmax, cymin, cymax;
  
  oi->me = 0;
  xmin = dkfig_tool_bb_get_xmin(&((oi->d)->dbb));
  xmax = dkfig_tool_bb_get_xmax(&((oi->d)->dbb));
  ymin = dkfig_tool_bb_get_ymin(&((oi->d)->dbb));
  ymax = dkfig_tool_bb_get_ymax(&((oi->d)->dbb));
  oi->xfactor = dkma_div_double_ok(72.0, (oi->d)->fres, &(oi->me));
  oi->yfactor = dkma_div_double_ok(72.0, (oi->d)->fres, &(oi->me));
  if(dkfig_tool_invert_y(oi->d)) {
    oi->yfactor = 0.0 - oi->yfactor;
  }
  xmin = dkma_mul_double_ok(xmin, oi->xfactor, &(oi->me));
  xmax = dkma_mul_double_ok(xmax, oi->xfactor, &(oi->me));
  ymin = dkma_mul_double_ok(ymin, oi->yfactor, &(oi->me));
  ymax = dkma_mul_double_ok(ymax, oi->yfactor, &(oi->me));
  if(xmax < xmin) { double cx; cx = xmax; xmax = xmin; xmin = cx; }
  if(ymax < ymin) { double cy; cy = ymax; ymax = ymin; ymin = cy; }
  cxmin = floor(xmin); cxmax = ceil(xmax);
  cymin = floor(ymin); cymax = ceil(ymax);
  oi->xleft = 0.0; oi->ybottom = 0.0;
  oi->xright = dkma_sub_double_ok(cxmax, cxmin, &(oi->me));
  oi->ytop =   dkma_sub_double_ok(cymax, cymin, &(oi->me));
  oi->xadd = 0.5 * dkma_sub_double_ok(
    oi->xright,
    dkma_sub_double_ok(cxmax, cxmin, &(oi->me)),
    &(oi->me)
  );
  oi->yadd = 0.5 * dkma_sub_double_ok(
    oi->ytop,
    dkma_sub_double_ok(cymax, cymin, &(oi->me)),
    &(oi->me)
  );
  oi->xadd = dkma_sub_double_ok(oi->xadd, cxmin, &(oi->me));
  oi->yadd = dkma_sub_double_ok(oi->yadd, cymin, &(oi->me));
  if(oi->me) {
    back = 0;
    dkfig_tool2_simple_error_message(oi->c, 13);
  }
  
  
  return back;
} /* }}} */



/* {{{ gather_text - save information from inspecting one text object
*/
static
int gather_text DK_P1(OI *,oi)
{
  int back = 0;
  int is_special = 0;
  int font_no = 0;
  int font_features = 0;
  dk_fig_fonth_t *fhptr = NULL;
  
  if((oi->co)->data) {
    dk_fig_text *t;
    t = (dk_fig_text *)((oi->co)->data);
    fhptr = t->font_handling;
    if(fhptr) {
      back = 1;
      switch(fhptr->handling) {
        case 2: case 3: case 4: case 5: {
	  is_special = 1;
	} break;
      }
      if(!is_special) {
        if((((oi->co)->fpd).st) == 0) {
          if(fhptr->fontno >= 0) {
	    if(fhptr->fontno < 35) {
	      oi->procs |= DKFIG_PDF_PROCSET_TEXT;
	      font_features = dkfont_get_features(fhptr->fontno);
	      switch(font_features & DK_FONT_FEATURE_FAMILY) {
	        case DK_FONT_FEATURE_TT: {
	          font_no = 8;
	        } break;
	        case DK_FONT_FEATURE_SF: {
	          font_no = 4;
	        } break;
	        default: {
	          font_no = 0;
	        } break;
	      }
	      if(font_features & DK_FONT_FEATURE_IT) {
	        font_no += 2;
	      }
	      if(font_features & DK_FONT_FEATURE_BD) {
	        font_no += 1;
	      }
	      switch(fhptr->fontno) {
	        case 32: { font_no = 12; }
	        case 34: { font_no = 13; }
	      } 
	      (oi->fu)[font_no] = 1UL;
	      (oi->co)->drve = (void *)new_drve();
	      if((oi->co)->drve) {
	        dkfig_pdf_drve_text *ext;
	        ext = (dkfig_pdf_drve_text *)((oi->co)->drve);
	        ext->fn = font_no;
	      } else {
	        back = 0;
	      }
	    } else {
	      back = 0;
	      dkfig_tool2_simple_error_message(oi->c, 109);
	    }
	  } else {
	    back = 0;
	    dkfig_tool2_simple_error_message(oi->c, 109);
	  }
        } else {
          if(!(((oi->c)->opt2) & DKFIG_OPT_SKIP_ALL_TEXTS)) {
  	    if(!((oi->errprinted) & 2)) {
	      
  	      dkfig_tool2_simple_error_message(oi->c, 110);
  	      if(!(((oi->c)->opt1) & DKFIG_OPT_REPORT_MULTIPLE)) {
	        oi->errprinted |= 2;
  	      }
  	    }
          }
	}
      }
    } else {
      if((oi->c)->app) { 
        dkfig_tool2_simple_error_message(oi->c, 44);
      }
    }
  } else {
    if((oi->c)->app) {	
      dkfig_tool2_simple_error_message(oi->c, 44);
    }
  } 
  return back;
} /* }}} */



/* {{{ handle_special_comments - process s.c. for one object
*/
static
void handle_special_comments DK_P1(OI *,oi)
{
  int i;
  if(((oi->co)->osc) && ((oi->co)->osci)) {
    dk_fig_opt *speccom;
    dksto_it_reset((oi->co)->osci);
    while((speccom = (dk_fig_opt *)dksto_it_next((oi->co)->osci)) != NULL) {
      i = dkfig_opt_process_special_comment(
        oi->c, speccom->name, kw[89], 0
      );
      if((oi->spcpass) == 0) {
        dkfig_tool2_report_special_comment(oi->c, speccom, i);
      }
    }
  }
} /* }}} */



/* {{{ gather_information - The style collection pass
*/
static
int gather_information DK_P1(OI *,oi) 
{
  int back = 1, i;
  dk_fig_object *o;
  dkfig_pdf_pattern pdfpat, *patp;
  dkfig_pdf_image *iptr;
  unsigned long backupopt1, backupopt2;
  
  oi->no = 6UL;
  dksto_it_reset(oi->fli);
  oi->co = NULL;
  while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) {
    
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, o->lineno);
    }
    oi->co = o;
    backupopt1 = (oi->c)->opt1;
    backupopt2 = (oi->c)->opt2;
    handle_special_comments(oi);
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, o->lineno);
    }
    switch(o->objtype) {
      case DK_FIG_OBJ_TEXT: {
        if(!gather_text(oi)) { back = 0; }
      } break;
      case DK_FIG_OBJ_POLYLINE: {
        if(((oi->co)->fpd).st == 5) {
	  
	  if(!((oi->co)->drve)) {
	    (oi->co)->drve = new_drve();
	  }
	  if((oi->co)->drve) {
	    dk_fig_polyline *polyline;
	    polyline = (dk_fig_polyline *)((oi->co)->data);
	    if(polyline) {
	      if(polyline->imagename) {
	        dkfig_pdf_image pdfi, *pdfiptr;
		pdfi.inputfilename = polyline->imagename;
		pdfi.flipped = 0;
		if(polyline->flipped) {
		  if(((oi->c)->opt2) & DKFIG_OPT_FLIP_DIAGONAL) {
		    pdfi.flipped = 2;
		  } else {
		    pdfi.flipped = 1;
		  }
		}
		pdfiptr = (dkfig_pdf_image *)dksto_it_find_like(
		  oi->imgli, (void *)(&pdfi), 0
		);
		if(pdfiptr) {
		  ((dkfig_pdf_drve_text *)((oi->co)->drve))->i = pdfiptr;
		} else {
		  pdfiptr = new_image(polyline->imagename);
		  if(pdfiptr) {
		    pdfiptr->flipped = pdfi.flipped;
		    if(dksto_add(oi->imgl, (void *)(pdfiptr))) {
		      ((dkfig_pdf_drve_text *)((oi->co)->drve))->i = pdfiptr;
		    } else {
		      delete_image(pdfiptr);
		      pdfiptr = NULL;
		      back = 0;
		      if((oi->c)->app) {
	                dkapp_err_memory((oi->c)->app, sizeof(dk_storage_node_t), 1);
		      }
		    }
		    pdfiptr->lineno = (oi->co)->lineno;
		  } else {
		    back = 0;
		    if((oi->c)->app) {
	              dkapp_err_memory((oi->c)->app, sizeof(dkfig_pdf_pattern), 1);
		    }
		  }
		}
	      } else {
	        back = 0; 
		dkfig_tool2_simple_error_message(oi->c, 44);
	      }
	    } else {
	      back = 0;	
	      dkfig_tool2_simple_error_message(oi->c, 44);
	    }
	  } else {
	    back = 0;
	    if((oi->c)->app) {
	      dkapp_err_memory((oi->c)->app, sizeof(dkfig_pdf_drve_text), 1);
	    }
	  }
	}
      } /* fall-through */
      case DK_FIG_OBJ_ELLIPSE:
      case DK_FIG_OBJ_SPLINE:
      case DK_FIG_OBJ_ARC: {
        if(((oi->co)->fpd).cl) {
          if(dkfig_tool_must_pattern(((oi->co)->fpd).af, (oi->c)->opt1)) {
	    if(!((oi->co)->drve)) {
	      (oi->co)->drve = new_drve();
	    }
	    if((oi->co)->drve) {
	      pdfpat.patno = ((oi->co)->fpd).af;
	      pdfpat.bgcol = ((oi->co)->fpd).fc;
	      pdfpat.fgcol = ((oi->co)->fpd).pc;
	      /* pdfpat.lt    = ((oi->co)->fpd).lt; */
	      pdfpat.tile  = 0;		
	      if(((oi->c)->opt2) & DKFIG_OPT_PDF_PATTERN_TILE) {
	        pdfpat.tile = 1;	
	      }
	      patp = (dkfig_pdf_pattern *)dksto_it_find_like(
	        oi->patli, (void *)(&pdfpat), 0
	      );
	      if(patp) {
	        ((dkfig_pdf_drve_text *)((oi->co)->drve))->p = patp;
	      } else {
	        patp = dk_new(dkfig_pdf_pattern,1);
		if(patp) {
		  patp->patno  = pdfpat.patno;
		  patp->bgcol  = pdfpat.bgcol;
		  patp->fgcol  = pdfpat.fgcol;
		  /* patp->lt     = pdfpat.lt; */
		  patp->tile   = pdfpat.tile;
		  patp->lineno = (oi->co)->lineno;
		  if(dksto_add(oi->patl, (void *)patp)) {
		    ((dkfig_pdf_drve_text *)((oi->co)->drve))->p = patp;
		  } else {
		    back = 0;
		    dk_delete(patp);
		    if((oi->c)->app) {
	              dkapp_err_memory((oi->c)->app, sizeof(dk_storage_node_t), 1);
		    }
		  }
		} else {
		  back = 0;
		  if((oi->c)->app) {
	            dkapp_err_memory((oi->c)->app, sizeof(dkfig_pdf_pattern), 1);
		  }
		}
	      }
	    } else {
	      back = 0;
	      if((oi->c)->app) {
	        dkapp_err_memory((oi->c)->app, sizeof(dkfig_pdf_drve_text), 1);
	      }
	    }
	  }
	}
      } break;
    }
    (oi->c)->opt1 = backupopt1;
    (oi->c)->opt2 = backupopt2;
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, 0UL);
    }
  } oi->co = NULL;
  /* fonts */
  for(i = 0; i < 14; i++) {
    if((oi->fu)[i]) {
      (oi->fu)[i] = oi->no; oi->no += 1UL;
    }
  }
  /* patterns */
  dksto_it_reset(oi->patli);
  while((patp = (dkfig_pdf_pattern *)dksto_it_next(oi->patli)) != NULL) {
    patp->objno = oi->no;
    oi->no += 1UL;
  }
  /* images */
  dksto_it_reset(oi->imgli);
  while((iptr = (dkfig_pdf_image *)dksto_it_next(oi->imgli)) != NULL) {
    oi->ci = iptr;
    if(dkfigpi_prepare_image(oi)) {
      iptr->objno = oi->no;
      oi->no += 1UL;
      switch(iptr->ch) {
        case 2: case 4: {
	  oi->no += 1UL;
	  oi->procs |= DKFIG_PDF_PROCSET_IMGG;
	} break;
      }
      switch(iptr->ch) {
        case 1: case 2: {
	  oi->procs |= DKFIG_PDF_PROCSET_IMGG;
	} break;
	default: {
	  oi->procs |= DKFIG_PDF_PROCSET_IMGC;
	} break;
      }
    } else {
      back = 0;
    }
    oi->ci = NULL;
  }
  oi->nostr = dkfig_dt_needed_alpha(oi->no);
  if(oi->me) {
    back = 0;
    dkfig_tool2_simple_error_message(oi->c, 13);
  }
  
  return back;
} /* }}} */



/* {{{ preparation_pass - Prepare PDF output
*/
static
int preparation_pass DK_P1(OI *,oi)
{
  int back = 0;
  int error_code;
  error_code = 2;
  
  oi->spcpass = 0;
  dkfig_tool2_simple_progress_message(oi->c, 98);
  oi->fl = dkfig_flat_list(oi->c, (oi->c)->drwng);
  if(oi->fl) {
    error_code = 3;
    oi->fli = dksto_it_open(oi->fl);
    if(oi->fli) {
      error_code = 2;
      oi->imgl = dksto_open(0);
      if(oi->imgl) {
	dksto_set_comp(oi->imgl, compare_images, 0);
        error_code = 3;
        oi->imgli = dksto_it_open(oi->imgl);
	if(oi->imgli) {
	  error_code = 2;
	  oi->patl = dksto_open(0);
	  if(oi->patl) {
	    dksto_set_comp(oi->patl, compare_pattern, 0);
	    error_code = 3;
	    oi->patli = dksto_it_open(oi->patl);
	    if(oi->patli) {
	      error_code = 2;
	      oi->pdfo = dksto_open(0);
	      if(oi->pdfo) {
	        error_code = 3;
		dksto_set_comp(oi->pdfo, compare_object_positions, 0);
		oi->pdfoi = dksto_it_open(oi->pdfo);
		if(oi->pdfoi) {
		  error_code = 0;
		  if(establish_coord_transformation(oi)) {
		    /* oi->no = 5UL; */
		    back = gather_information(oi);
		  } else {
		    dkfig_tool2_simple_error_message(oi->c, 13);
		  }
		}
	      }
	    }
	  }
	}
      }
    }
  }
  if(!back) {
    switch(error_code) {
      case 1: {
	dkfig_tool2_simple_error_message(oi->c, 11);
      } break;
      case 2: {
        if((oi->c)->app) {
	  dkapp_err_memory((oi->c)->app, sizeof(dk_storage_t), 1);
	}
      } break;
      case 3: {
        if((oi->c)->app) {
	  dkapp_err_memory((oi->c)->app, sizeof(dk_storage_iterator_t), 1);
	}
      } break;
    }
  }
  oi->spcpass = 1;
  
  return back;
} /* }}} */



/* {{{ change_ctm - translate and rotate
*/
static
void change_ctm DK_P5(OI *,oi, dk_stream_t *,s, double,x, double,y, double,phi)
{
  double a, b;
  a = cos(phi); b = sin(phi);
  /*
  a = dkma_double_restrict_digits(a, 3);
  b = dkma_double_restrict_digits(b, 3);
  */
  dkstream_puts(s, kw[56]);
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[19]);
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[19]);
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[56]);
  dkstream_puts(s, kw[1]);
  dkstream_puts_double(s, drd(x, oi->c, 1));
  dkstream_puts(s, kw[1]);
  dkstream_puts_double(s, drd(y, oi->c, 1));
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[55]);
  dkstream_puts(s, kw[0]);
  dkstream_puts_double(s, drd(a, oi->c, 2));
  dkstream_puts(s, kw[1]);
  dkstream_puts_double(s, drd(b, oi->c, 2));
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[57]);
  dkstream_puts_double(s, drd(b, oi->c, 2));
  dkstream_puts(s, kw[1]);
  dkstream_puts_double(s, drd(a, oi->c, 2));
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[19]);
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[19]);
  dkstream_puts(s, kw[1]);
  dkstream_puts(s, kw[55]);
  dkstream_puts(s, kw[0]);
} /* }}} */



/* {{{ dpointout - Write points in double coordinates
*/
static
void dpointout DK_P4(OI *,oi, double,x, double,y, int,h)
{
  dkstream_puts_double(oi->gcs,drd(ccdx(oi,x),oi->c,h));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs,drd(ccdy(oi,y),oi->c,h));
  gcs_out(oi, 1);
} /* }}} */



/* {{{ nocdpointout - Write points in double coordinates, no transformation
*/
static
void nocdpointout DK_P4(OI *,oi, double,x, double,y, int,h)
{
  dkstream_puts_double(oi->gcs, drd(x,oi->c,h));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(y,oi->c,h));
  gcs_out(oi, 1);
} /* }}} */



/* {{{ lpointout - Write points in long coordinates
*/
static
void lpointout DK_P4(OI *,oi, long,x, long,y, int,h)
{
  dkstream_puts_double(oi->gcs,drd(cclx(oi,x),oi->c,h));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs,drd(ccly(oi,y),oi->c,h));
  gcs_out(oi, 1);
} /* }}} */



/* {{{ create_contents_text - write text object to gcs
*/
static
int create_contents_text DK_P1(OI *,oi)
{
  int back = 0;
  dk_fig_text *t = NULL;
  dk_fig_fonth_t *fhptr = NULL;
  int is_special = 0, is_rotated = 0;
  dkfig_pdf_drve_text *e = NULL;
  unsigned long objno = 0UL;
  dk_fig_dcc dcc;
  
  if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) {
    gcs_out(oi, 84);
    dkstream_puts_ul(oi->gcs, (oi->co)->lineno);
    gcs_out(oi, 0);
  }
  t = (dk_fig_text *)((oi->co)->data);
  e = (dkfig_pdf_drve_text *)((oi->co)->drve);
  if((t) && (e)) {
    fhptr = t->font_handling;
    if(fhptr) {
      back = 1;
      is_special = 0;
      switch(fhptr->handling) {
        case 2: case 3: case 4: case 5: { is_special = 1; } break;
      }
      if(is_special) {
        
	if(!(((oi->c)->opt2) & DKFIG_OPT_SKIP_ALL_TEXTS)) {
  	  if(!((oi->errprinted) & 1)) {
  	    dkfig_tool2_simple_error_message(oi->c, 85);
  	    if(!(((oi->c)->opt1) & DKFIG_OPT_REPORT_MULTIPLE)) {
	      oi->errprinted |= 1;
  	    }
  	  }
	}
      } else {
        
        is_rotated = 0;
	if(fabs(t->angle) > DKFIG_EPSILON) { is_rotated = 1; }
	objno = (oi->fu)[e->fn];
	
        dkfig_tool_fill_dcc(oi->d, &dcc, ((oi->co)->fpd).pc);
	
	set_nonstroking(oi, &dcc);
	
	if(is_rotated) {
	  
	  gcs_out(oi, 37); gcs_out(oi, 0);
	  change_ctm(oi, oi->gcs, cclx(oi, t->x), ccly(oi, t->y), t->angle);
	  gcs_out(oi, 47); gcs_out(oi, 0);
	  gcs_out(oi, 35); gcs_out(oi, 45);
	  dkfig_tool_num_as_string(oi->gcs, objno, oi->nostr);
	  gcs_out(oi, 1);
	  dkstream_puts_double(
	    oi->gcs,
	    dkfig_tool2_drd(
	      dkma_mul_double_ok((oi->c)->fsf, fhptr->fontsize, &(oi->me)),
	      oi->c, 1
	    )
	  );
	  gcs_out(oi, 1);
	  gcs_out(oi, 49); gcs_out(oi, 0);
	  dkstream_puts_double(oi->gcs, 0.0);
	  gcs_out(oi, 1);
	  dkstream_puts_double(oi->gcs, 0.0);
	  gcs_out(oi, 1);
	  gcs_out(oi, 50); gcs_out(oi, 0);
	  if(((oi->c)->opt2) & DKFIG_OPT_UTF_8) {
	    /* UTF-8 encoded */
	    
	    pdf_encode_utf8(oi, oi->gcs, t->text);
	  } else {
	    
	    pdf_encode_str(oi, oi->gcs, t->text);
	  }
	  gcs_out(oi, 1); gcs_out(oi, 51); gcs_out(oi, 0);
	  gcs_out(oi, 48); gcs_out(oi, 0);
	  gcs_out(oi, 38); gcs_out(oi, 0);
	} else {
	  
	  gcs_out(oi, 47); gcs_out(oi, 0);
	  gcs_out(oi, 35); gcs_out(oi, 45);
	  dkfig_tool_num_as_string(oi->gcs, objno, oi->nostr);
	  gcs_out(oi, 1); 
	  dkstream_puts_double(
	    oi->gcs,
	    dkfig_tool2_drd(
	      dkma_mul_double_ok((oi->c)->fsf, fhptr->fontsize, &(oi->me)),
	      oi->c, 1
	    )
	  ); 
	  gcs_out(oi, 1);
	  gcs_out(oi, 49); gcs_out(oi, 0);
	  dkstream_puts_double(oi->gcs, drd(cclx(oi, t->x), oi->c, 1));
	  gcs_out(oi, 1); 
	  dkstream_puts_double(oi->gcs, drd(ccly(oi, t->y), oi->c, 1));
	  gcs_out(oi, 1); 
	  gcs_out(oi, 50); gcs_out(oi, 0);
	  if(((oi->c)->opt2) & DKFIG_OPT_UTF_8) {
	    pdf_encode_utf8(oi, oi->gcs, t->text);
	  } else {
	    pdf_encode_str(oi, oi->gcs, t->text);
	  }
	  
	  gcs_out(oi, 1); gcs_out(oi, 51); gcs_out(oi, 0);
	  gcs_out(oi, 48); gcs_out(oi, 0); 
	}
	
      }
    } else {	
      dkfig_tool2_simple_error_message(oi->c, 44);
    }
  } else {
    
    if(((oi->co)->fpd).st) {
      back = 1; /* It is okay to skip aligned text */
#if VERSION_BEFORE_20050604
        /* If we do not have to deal with this text, we do not
	   complain about it.
	*/
        if(!(((oi->c)->opt2) & DKFIG_OPT_SKIP_ALL_TEXTS)) {
  	  if(!((oi->errprinted) & 2)) {
	    
  	    dkfig_tool2_simple_error_message(oi->c, 110);
  	    if(!(((oi->c)->opt1) & DKFIG_OPT_REPORT_MULTIPLE)) {
	      oi->errprinted |= 2;
  	    }
  	  }
        }
#endif
    } else {	
      if(t) {
        fhptr = t->font_handling;
	if(fhptr) {
	  switch(fhptr->handling) {
	    case 2: case 3: case 4: case 5: {
	      if(!(((oi->c)->opt2) & DKFIG_OPT_SKIP_ALL_TEXTS)) {
  	        if(!((oi->errprinted) & 1)) {
  	          dkfig_tool2_simple_error_message(oi->c, 85);
  	          if(!(((oi->c)->opt1) & DKFIG_OPT_REPORT_MULTIPLE)) {
	            oi->errprinted |= 1;
  	          }
  	        }
	      }
	    } break;
	    default: {
	      dkfig_tool2_simple_error_message(oi->c, 44);
	    } break;
	  }
	} else {
	  dkfig_tool2_simple_error_message(oi->c, 44);
	}
      } else {
        dkfig_tool2_simple_error_message(oi->c, 44);
      }
    }
  }
  
  return back;
} /* }}} */



/* {{{ reason_for_no_filling - Is there a reason to deny object filling?
*/
static
int reason_for_no_filling DK_P1(OI *,oi)
{
  int back = 0;
  if(((oi->co)->fpd).fc == (oi->d)->transparent) {
    back = 1;
  }
  if((oi->co)->objtype == DK_FIG_OBJ_POLYLINE) {
    if((oi->co)->subtype == 5) {
      if(!(((oi->c)->opt1) & DKFIG_OPT_FILL_BITMAP_AREA)) {
        back = 1;
      }
    } else {
      if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BG_RECTANGLE) {
        int wbgr = 0;
	if(((oi->c)->opt2) & DKFIG_OPT_WHITE_BGRECT) {
	  wbgr = 1;
	}
        if(dkfig_tool2_obj_is_bg_rect(oi->co, wbgr)) {
	  back = 1;
	}
      }
    }
  }
  return back;
} /* }}} */



/* {{{ must_fill - Is it necessary to fill the current object
*/
static
int must_fill DK_P1(OI *,oi)
{
  int back = 0;
  if(((oi->co)->fpd).cl) {
    if(dkfig_tool_must_fill(((oi->co)->fpd).af, (oi->c)->opt1)) {
      back = 1;
      if(reason_for_no_filling(oi)) {
        back = 0;
      }
    }
  }
  return back;
} /* }}} */



/* {{{ must_pattern - Is it necessary to pattern the current object
*/
static
int must_pattern DK_P1(OI *,oi)
{
  int back = 0;
  if(((oi->co)->fpd).cl) {
    if(dkfig_tool_must_pattern(((oi->co)->fpd).af, (oi->c)->opt1)) {
      back = 1;
      if(reason_for_no_filling(oi)) {
        back = 0;
      }
    }
  }
  return back;
} /* }}} */



/* {{{ reason_for_no_stroking - Is there a reason to deny stroking
*/
static
int reason_for_no_stroking DK_P1(OI *,oi)
{
  int back = 0;
  if(((oi->co)->fpd).pc == (oi->d)->transparent) {
    back = 1;
  }
  if((oi->co)->objtype == DK_FIG_OBJ_POLYLINE) {
    if((oi->co)->subtype == 5) {
      if((((oi->c)->opt1) & DKFIG_OPT_REMOVE_BITMAP_BORDER)) {
        back = 1;
      }
      if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_THIN_BORDERS) {
        if(((oi->co)->fpd).lt == 0L) {
	  back = 1;
	}
      }
    } else {
      if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BG_RECTANGLE) {
        int wbgr = 0;
	if(((oi->c)->opt2) & DKFIG_OPT_WHITE_BGRECT) {
	  wbgr = 1;
	}
        if(dkfig_tool2_obj_is_bg_rect(oi->co, wbgr)) {
	  back = 1;
	}
      }
    }
  }
  if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_THIN_BORDERS) {
    if(((oi->co)->fpd).lt == 0L) {
      if(((oi->co)->fpd).cl) {
        if(must_fill(oi) || must_pattern(oi)) {
	  back = 1;
	}
      }
    }
  }
  return back;
} /* }}} */



/* {{{ must_stroke - Do we need to stroke we current object
*/
static
int must_stroke DK_P1(OI *,oi)
{
  int back = 1;
  if(reason_for_no_stroking(oi)) {
    back = 0;
  }
  return back;
} /* }}} */



/* {{{ set_lw_and_colors - Set up graphics state for current object
*/
static
void set_lw_and_colors DK_P1(OI *,oi)
{
  if(must_pattern(oi)) {
    dkfig_pdf_drve_text *pdrve;
    if((oi->co)->drve) {
        pdrve = (dkfig_pdf_drve_text *)((oi->co)->drve);
	if(pdrve->p) {
	  dkfig_pdf_pattern *patp;
	  patp = pdrve->p;
          gcs_out(oi, 72);
	  gcs_out(oi, 35); gcs_out(oi, 45);
	  dkfig_tool_num_as_string(oi->gcs, patp->objno, oi->nostr);
	  gcs_out(oi, 1); gcs_out(oi, 73); gcs_out(oi, 0);
	  oi->flags &= (~(HAVE_NON_STROKE_COLOR));
	}
    }
  } else {
    if(must_fill(oi)) {
        dk_fig_dcc bdcc;
	dkfig_tool_fill_dcc(oi->d, &bdcc, ((oi->co)->fpd).fc);
	dkfig_tool_correct_dcc(&bdcc, ((oi->co)->fpd).fc, ((oi->co)->fpd).af);
	set_nonstroking(oi, &bdcc);
    }
  }
  if(must_stroke(oi)) {
    dk_fig_dcc fdcc;
    dkfig_tool_fill_dcc(oi->d, &fdcc, ((oi->co)->fpd).pc);
    set_stroking(oi, &fdcc);
    set_linewidth(oi, get_object_linewidth(oi));
    set_dash(oi, ((oi->co)->fpd).ls, ((oi->co)->fpd).sv);
    set_linecap(oi, ((oi->co)->fpd).cs);
    set_linejoin(oi, ((oi->co)->fpd).js);
  }
} /* }}} */



/* {{{ final_keyword - add keyword to fill/stroke the current object
*/
static
void final_keyword DK_P1(OI *,oi)
{
  int kwno = 0;
  if(((oi->co)->fpd).cl) {	/* closed object */
    if(must_fill(oi) || must_pattern(oi)) {
      if(must_stroke(oi)) {
        if(((oi->c)->opt2) & DKFIG_OPT_FILL_NONZERO) {
	  kwno = 78;
	} else {
	  kwno = 79;
	}
      } else {
        if(((oi->c)->opt2) & DKFIG_OPT_FILL_NONZERO) {
	  kwno = 80;
	} else {
	  kwno = 81;
	}
      }
    } else {
      if(must_stroke(oi)) {
        kwno = 82;
      }
    }
  } else {			/* non-closed object */
    if(must_stroke(oi)) {
      kwno = 70;
    }
  }
  if(kwno) {
    gcs_out(oi, kwno); gcs_out(oi, 0);
  }
} /* }}} */



/* {{{ pdf_arc_path - approximate arc by Bezier segments
*/
static
void pdf_arc_path DK_P2(OI *,oi, pdf_arc_calc *,ac)
{
  double phistep;
  double nsteps;
  double dxdt0, dydt0, dxdt1, dydt1, x0, y0, x1, y1, phi0, phi1;
  double xa, ya, xb, yb;
  double ddtfactor;
  unsigned i;
  
  
  phistep = dkma_sub_double_ok(ac->phi1,ac->phi0,&(oi->me));
  ddtfactor = dkma_div_double_ok(
    dkma_sub_double_ok(ac->phi1, ac->phi0, &(oi->me)),
    dkma_l_to_double((long)(ac->segs)),
    &(oi->me)
  );
  nsteps = dkma_l_to_double(ac->segs);
  for(i = 0; i < ac->segs; i++) {
    if(i == 0) {
      phi0 = ac->phi0;
      x0 = ac->x0; y0 = ac->y0;
      dxdt0 = 0.0 - ac->rx * sin(phi0);
      dydt0 = ac->ry * cos(phi0);
      dxdt0 = dkma_mul_double_ok(ddtfactor, dxdt0, &(oi->me));
      dydt0 = dkma_mul_double_ok(ddtfactor, dydt0, &(oi->me));
    } else {
      phi0 = phi1;
      x0 = x1; y0 = y1;
      dxdt0 = dxdt1; dydt0 = dydt1;
    }
    phi1 = dkma_div_double_ok(
      dkma_mul_double_ok(
        dkma_l_to_double(1L + (long)i),
	phistep, &(oi->me)
      ),
      dkma_l_to_double((long)(ac->segs)),
      &(oi->me)
    );
    phi1 = dkma_add_double_ok(phi1, ac->phi0, &(oi->me));
    
    if(i == (ac->segs - 1)) {
      x1 = ac->x1; y1 = ac->y1;
    } else {
      x1 = ac->rx * cos(phi1);
      y1 = ac->ry * sin(phi1);
      
      x1 = dkma_add_double_ok(x1, ac->xm, &(oi->me));
      y1 = dkma_add_double_ok(y1, ac->ym, &(oi->me));
      
    }
    dxdt1 = 0.0 - ac->rx * sin(phi1);
    dydt1 = ac->ry * cos(phi1);
    
    dxdt1 = dkma_mul_double_ok(ddtfactor, dxdt1, &(oi->me));
    dydt1 = dkma_mul_double_ok(ddtfactor, dydt1, &(oi->me));
    
    xa = dkma_add_double_ok(x0, (dxdt0/3.0), &(oi->me));
    ya = dkma_add_double_ok(y0, (dydt0/3.0), &(oi->me));
    xb = dkma_sub_double_ok(x1, (dxdt1/3.0), &(oi->me));
    yb = dkma_sub_double_ok(y1, (dydt1/3.0), &(oi->me));
    nocdpointout(oi, xa, ya, 2);
    nocdpointout(oi, xb, yb, 2);
    if(i == (ac->segs - 1)) {
      nocdpointout(oi, x1, y1, 1);
    } else {
      nocdpointout(oi, x1, y1, 2);
    }
    gcs_out(oi, 83); gcs_out(oi, 0);
  } 
} /* }}} */



/* {{{ set_imgbb - find bounding box for image
*/
static
void set_imgbb DK_P1(OI *,oi)
{
  dk_fig_polyline *p;
  dk_fig_bb bbdest;
  long *xptr, *yptr;
  size_t i;
  double xmin, xmax, ymin, ymax;
  
  p = (dk_fig_polyline *)((oi->co)->data);
  if(p) {
    dkfig_tool_bb_reset(&bbdest);
    xptr = p->xvalues; yptr = p->yvalues;
    for(i = 0; i < p->npoints; i++) {
      dkfig_tool_bb_add_x(&bbdest, cclx(oi, *xptr));
      dkfig_tool_bb_add_y(&bbdest, ccly(oi, *yptr));
      xptr++; yptr++;
    }
    xmin = bbdest.xmin; xmax = bbdest.xmax;
    ymin = bbdest.ymin; ymax = bbdest.ymax;
    xmin = drd(xmin,oi->c,1); xmax = drd(xmax,oi->c,1);
    ymin = drd(ymin,oi->c,1); ymax = drd(ymax,oi->c,1);
    dkfig_tool_bb_reset(&(oi->imgbb));
    dkfig_tool_bb_add_x(&(oi->imgbb), xmin);
    dkfig_tool_bb_add_x(&(oi->imgbb), xmax);
    dkfig_tool_bb_add_y(&(oi->imgbb), ymin);
    dkfig_tool_bb_add_y(&(oi->imgbb), ymax);
  }
} /* }}} */



/* {{{ write_polyline_path 
*/
static
int write_polyline_path DK_P1(OI *,oi)
{
  int back = 0;
  dk_fig_polyline *p;
  long *xptr, *yptr; size_t i;
  
  p = (dk_fig_polyline *)((oi->co)->data);
  if(p) {
    back = 1;
    switch(((oi->co)->fpd).st) {
      case 2: case 4: case 5: {	/* box, arc-box, image */
        dk_fig_bb bbdest;
	double xmin, xmax, ymin, ymax, x1, x2, y1, y2, r;
	
	dkfig_tool_bb_reset(&bbdest);
	xptr = p->xvalues; yptr = p->yvalues;
	for(i = 0; i < p->npoints; i++) {
	  dkfig_tool_bb_add_x(&bbdest, cclx(oi, *xptr));
	  dkfig_tool_bb_add_y(&bbdest, ccly(oi, *yptr));
	  xptr++; yptr++;
	}
	xmin = bbdest.xmin; xmax = bbdest.xmax;
	ymin = bbdest.ymin; ymax = bbdest.ymax;
	xmin = drd(xmin,oi->c,1); xmax = drd(xmax,oi->c,1);
	ymin = drd(ymin,oi->c,1); ymax = drd(ymax,oi->c,1);
	dkfig_tool_bb_reset(&(oi->imgbb));	/* save bb for image showing */
	dkfig_tool_bb_add_x(&(oi->imgbb), xmin);
	dkfig_tool_bb_add_x(&(oi->imgbb), xmax);
	dkfig_tool_bb_add_y(&(oi->imgbb), ymin);
	dkfig_tool_bb_add_y(&(oi->imgbb), ymax);
	if(must_fill(oi) || must_pattern(oi) || must_stroke(oi)) {
	  switch(((oi->co)->fpd).st) {
	    case 2: case 5: {	/* box or image box */
	      dkstream_puts_double(oi->gcs, xmin); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, ymin); gcs_out(oi, 1);
	      gcs_out(oi, 66); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, xmax); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, ymin); gcs_out(oi, 1);
	      gcs_out(oi, 67); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, xmax); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, ymax); gcs_out(oi, 1);
	      gcs_out(oi, 67); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, xmin); gcs_out(oi, 1);
	      dkstream_puts_double(oi->gcs, ymax); gcs_out(oi, 1);
	      gcs_out(oi, 67); gcs_out(oi, 0);
	    } break;
	    default: {		/* arc-box */
	      pdf_arc_calc ac;
	      r = 0.9 * dkma_l_to_double(p->radius);
	      r = drd(r,oi->c,1);
	      x1 = dkma_add_double_ok(xmin, r, &(oi->me));
	      x2 = dkma_sub_double_ok(xmax, r, &(oi->me));
	      y1 = dkma_add_double_ok(ymin, r, &(oi->me));
	      y2 = dkma_sub_double_ok(ymax, r, &(oi->me));
	      ac.segs = (oi->c)->circlesteps;
	      nocdpointout(oi, xmin, y1, 1);
	      gcs_out(oi, 66); gcs_out(oi, 0);
	      ac.rx = ac.ry = r;
	      ac.xm = x1; ac.ym = y1;
	      ac.phi0 = M_PI; ac.phi1 = 1.5 * M_PI;
	      ac.segs = (oi->c)->circlesteps;
	      ac.x0 = xmin; ac.y0 = y1;
	      ac.x1 = x1; ac.y1 = ymin;
	      pdf_arc_path(oi, &ac);
	      nocdpointout(oi, x2, ymin, 1);
	      gcs_out(oi, 67); gcs_out(oi, 0);
	      ac.rx = ac.ry = r;
	      ac.xm = x2; ac.ym = y1;
	      ac.phi0 = 1.5 * M_PI; ac.phi1 = 2.0 * M_PI;
	      ac.segs = (oi->c)->circlesteps;
	      ac.x0 = x2; ac.y0 = ymin;
	      ac.x1 = xmax; ac.y1 = y1;
	      pdf_arc_path(oi, &ac);
	      nocdpointout(oi, xmax, y2, 1);
	      gcs_out(oi, 67); gcs_out(oi, 0);
	      ac.rx = ac.ry = r;
	      ac.xm = x2; ac.ym = y2;
	      ac.phi0 = 0.0; ac.phi1 = 0.5 * M_PI;
	      ac.segs = (oi->c)->circlesteps;
	      ac.x0 = xmax; ac.y0 = y2;
	      ac.x1 = x2; ac.y1 = ymax;
	      pdf_arc_path(oi, &ac);
	      nocdpointout(oi, x1, ymax, 1);
	      gcs_out(oi, 67); gcs_out(oi, 0);
	      ac.rx = ac.ry = r;
	      ac.xm = x1; ac.ym = y2;
	      ac.phi0 = 0.5 * M_PI; ac.phi1 = M_PI;
	      ac.segs = (oi->c)->circlesteps;
	      ac.x0 = x1; ac.y0 = ymax;
	      ac.x1 = xmin; ac.y1 = y2;
	      pdf_arc_path(oi, &ac);
	    } break;
	  }
	}
      } break;
      default: {		/* polyline or polygon */
        if(must_fill(oi) || must_pattern(oi) || must_stroke(oi)) {
	  xptr = p->xvalues; yptr = p->yvalues;
	  if((!(((oi->co)->fpd).cl)) && (((oi->co)->fpd).ar & 2)) {
	    dpointout(oi, (p->pa).x, (p->pa).y, 1);
	  } else {
	    lpointout(oi, *xptr, *yptr, 1);
	  }
	  xptr++; yptr++;
	  gcs_out(oi, 1); gcs_out(oi, 66); gcs_out(oi, 0);
	  for(i = 1; i < p->npoints; i++) {
	    if(i == (p->npoints - 1)) {
	      if(!(((oi->co)->fpd).cl)) {
	        if((((oi->co)->fpd).ar) & 1) {
		  dpointout(oi, (p->pe).x, (p->pe).y, 1);
		  gcs_out(oi, 1); gcs_out(oi, 67); gcs_out(oi, 0);
		} else {
		  lpointout(oi, *xptr, *yptr, 1);
	          gcs_out(oi, 1); gcs_out(oi, 67); gcs_out(oi, 0);
		}
	      }
	    } else {
	      lpointout(oi, *xptr, *yptr, 1);
	      gcs_out(oi, 1); gcs_out(oi, 67); gcs_out(oi, 0);
	    }
	    xptr++; yptr++;
	  }
	}
      } break;
    }
  } else {	
    dkfig_tool2_simple_error_message(oi->c, 44);
  } 
  return back;
} /* }}} */



/* {{{ one_arrow_head - draw on arrow head
*/
static
void one_arrow_head DK_P2(OI *,oi, dk_fig_arrow *,a)
{
  dk_fig_dcc bdcc;
  int final_kw = 0;
  set_dash(oi, 0, 0.0);
  set_linecap(oi, 0);
  set_linejoin(oi, (oi->c)->ahlj);
  if(a->type) {
    if(a->style) {
      dkfig_tool_fill_dcc(oi->d, &bdcc, ((oi->co)->fpd).pc);
    } else {
      bdcc.red = bdcc.green = bdcc.blue = 1.0;
    }
    set_nonstroking(oi, &bdcc);
    final_kw = 78;
  } else {
    final_kw = 70;
  }
  dpointout(oi, (a->p1).x, (a->p1).y, 2);
  gcs_out(oi, 66); gcs_out(oi, 0);
  dpointout(oi, (a->p2).x, (a->p2).y, 2);
  gcs_out(oi, 67); gcs_out(oi, 0);
  dpointout(oi, (a->p3).x, (a->p3).y, 2);
  gcs_out(oi, 67); gcs_out(oi, 0);
  if(a->numpoints > 3) {
    dpointout(oi, (a->p4).x, (a->p4).y, 2);
    gcs_out(oi, 67); gcs_out(oi, 0);
  }
  if(final_kw) {
    gcs_out(oi, final_kw); gcs_out(oi, 0);
  }
} /* }}} */



/* {{{ both_arrow_heads - draw both arrow heads for current object
*/
static
void
both_arrow_heads DK_P1(OI *,oi)
{
  if(!(((oi->co)->fpd).cl)) {
    if((((oi->co)->fpd).ar) & 1) { /* forward */
      one_arrow_head(oi, &(((oi->co)->fpd).ahf));
    }
    if((((oi->co)->fpd).ar) & 2) { /* backward */
      one_arrow_head(oi, &(((oi->co)->fpd).ahb));
    }
  }
} /* }}} */



/* {{{ show_image - show embedded image
*/
static
int show_image DK_P1(OI *,oi)
{
  int back = 1;
  dk_fig_polyline *p;
  dkfig_pdf_drve_text *e;
  dkfig_pdf_image *i, *oldci;
  double lwhalf, deltax, deltay, sfx, sfy, x0, y0, dwi, dhi;
  unsigned long wi, hi;
  p = (dk_fig_polyline *)((oi->co)->data);
  e = (dkfig_pdf_drve_text *)((oi->co)->drve);
  if((p) && (e)) {
    i = e->i;
    oldci = oi->ci;
    oi->ci = i;
    switch(i->flipped) {
      case 2:  { wi = i->h; hi = i->w; } break;
      default: { wi = i->w; hi = i->h; } break;
    }
    lwhalf = 0.0;
    deltax = dkma_sub_double_ok((oi->imgbb).xmax,(oi->imgbb).xmin,&(oi->me));
    deltay = dkma_sub_double_ok((oi->imgbb).ymax,(oi->imgbb).ymin,&(oi->me));
    if(must_stroke(oi)) {
      lwhalf = get_object_linewidth(oi);
      deltax = dkma_sub_double_ok(deltax, lwhalf, &(oi->me));
      deltay = dkma_sub_double_ok(deltay, lwhalf, &(oi->me));
      lwhalf = 0.5 * lwhalf;
    }
    sfx = deltax;
    sfy = deltay;
    x0 = dkma_add_double_ok((oi->imgbb).xmin, lwhalf, &(oi->me));
    y0 = dkma_add_double_ok((oi->imgbb).ymin, lwhalf, &(oi->me));
    if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
      /* correct x0, y0, sfx, sfy */
      dwi = dkma_l_to_double(wi);
      dhi = dkma_l_to_double(hi);
      if(MULD(deltay,dwi,&(oi->me)) > MULD(deltax,dhi,&(oi->me))) {
        sfy = MULD(deltax,DIVD(dhi,dwi,&(oi->me)),&(oi->me));
	y0 = ADDD(
	  y0,
	  (0.5 * SUBD(deltay,sfy,&(oi->me))),
	  &(oi->me)
	);
      } else {
        sfx = MULD(deltay,DIVD(dwi,dhi,&(oi->me)),&(oi->me));
	x0 = ADDD(x0,(0.5 * SUBD(deltax,sfx,&(oi->me))),&(oi->me));
      }
    }
    gcs_out(oi, 37); gcs_out(oi, 0);
    /* shift */
    dkstream_puts_ul(oi->gcs, 1UL);
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 0UL);
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 0UL);
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 1UL);
    gcs_out(oi, 1);
    dkstream_puts_double(oi->gcs, drd(x0,oi->c,1));
    gcs_out(oi, 1);
    dkstream_puts_double(oi->gcs, drd(y0,oi->c,1));
    gcs_out(oi, 1);
    gcs_out(oi, 55); gcs_out(oi, 0);
    /* scale */
    dkstream_puts_double(oi->gcs, drd(sfx,oi->c,1));
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 0UL);
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 0UL);
    gcs_out(oi, 1);
    dkstream_puts_double(oi->gcs, drd(sfy,oi->c,1));
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 0UL);
    gcs_out(oi, 1);
    dkstream_puts_ul(oi->gcs, 0UL);
    gcs_out(oi, 1);
    gcs_out(oi, 55); gcs_out(oi, 0);
    /* do */
    gcs_out(oi, 35); gcs_out(oi, 45);
    dkfig_tool_num_as_string(oi->gcs, i->objno, oi->nostr);
    gcs_out(oi, 1);
    gcs_out(oi, 101);
    gcs_out(oi, 0);
    gcs_out(oi, 38); gcs_out(oi, 0);
    oi->ci = oldci;
  }
  return back;
} /* }}} */



/* {{{ create_contents_polyline - write polyline object to gcs
*/
static
int create_contents_polyline DK_P1(OI *,oi)
{
  int back = 1;
  if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) {
    gcs_out(oi, 85);
    dkstream_puts_ul(oi->gcs, (oi->co)->lineno);
    gcs_out(oi, 0);
  }
  if(must_fill(oi) || must_pattern(oi) || must_stroke(oi)) {
    set_lw_and_colors(oi);
    back = write_polyline_path(oi);
    final_keyword(oi);
    both_arrow_heads(oi);
  }
  if(((oi->co)->fpd).st == 5) {
    set_imgbb(oi);
    show_image(oi);
  }
  return back;
} /* }}} */



/* {{{ create_contents_ellipse - write ellipse object to gcs
*/
static
int create_contents_ellipse DK_P1(OI *,oi)
{
  int back = 1;
  int is_rotated;
  dk_fig_ellipse *e;
  pdf_arc_calc ac;
  if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) {
    gcs_out(oi, 86);
    dkstream_puts_ul(oi->gcs, (oi->co)->lineno);
    gcs_out(oi, 0);
  }
  e = (dk_fig_ellipse *)((oi->co)->data);
  if(must_fill(oi) || must_pattern(oi) || must_stroke(oi)) {
    back = 0;
    is_rotated = 0;
    ac.xm = ac.ym = 0.0;
    if(e) {
      back = 1;
      if(fabs(e->angle) > DKFIG_EPSILON) {
        is_rotated = 1;
      }
      set_lw_and_colors(oi);
      ac.rx = fabs(dkma_mul_double_ok(oi->xfactor, e->radiusx, &(oi->me)));
      ac.ry = fabs(dkma_mul_double_ok(oi->yfactor, e->radiusy, &(oi->me)));
      ac.phi0 = 0.0;
      ac.phi1 = 2.0 * M_PI;
      ac.segs = (oi->c)->circlesteps;
      if(ac.segs < 1) ac.segs = 1;
      ac.segs = ac.segs * 4;
      ac.x0 = ac.rx;
      ac.y0 = 0.0;
      if(is_rotated) {
        gcs_out(oi, 37); gcs_out(oi, 0);
	change_ctm(oi,oi->gcs,cclx(oi,e->centerx),ccly(oi,e->centery),e->angle);
      } else {
        ac.xm = cclx(oi,e->centerx);
	ac.ym = ccly(oi,e->centery);
	ac.x0 = dkma_add_double_ok(ac.x0,ac.xm,&(oi->me));
	ac.y0 = dkma_add_double_ok(ac.y0,ac.ym,&(oi->me));
      }
      ac.x0 = drd(ac.x0,oi->c,1);
      ac.y0 = drd(ac.y0,oi->c,1);
      ac.x1 = ac.x0;
      ac.y1 = ac.y0;
      nocdpointout(oi,ac.x0,ac.y0,1);
      gcs_out(oi, 66); gcs_out(oi, 0);
      pdf_arc_path(oi, &ac);
      final_keyword(oi);
      if(is_rotated) {
        gcs_out(oi, 38); gcs_out(oi, 0);
      }
    } else {	
      dkfig_tool2_simple_error_message(oi->c, 44);
    }
  }
  return back;
} /* }}} */



/* {{{ write_spline_path
*/
static
void write_spline_path DK_P1(OI *,oi)
{
  dk_fig_spline *s;
  dk_fig_bezier_point *bpptr;
  size_t nsegs, li, ri, maxli;
  s = (dk_fig_spline *)((oi->co)->data);
  if(s) {
    bpptr = s->bpoints; nsegs = s->nbpoints - 1;
    if(((oi->co)->fpd).cl) { nsegs = s->nbpoints; }
    if((!(((oi->co)->fpd).cl)) && (((oi->co)->fpd).ar & 2)) {
      dpointout(oi, (s->pa).value.x, (s->pa).value.y, 1);
      gcs_out(oi, 66); gcs_out(oi, 0);
      dpointout(oi, (s->pa).rcontrol.x, (s->pa).rcontrol.y, 1);
      dpointout(oi, (s->pa2).lcontrol.x, (s->pa2).lcontrol.y, 1);
      dpointout(oi, (s->pa2).value.x, (s->pa2).value.y, 1);
      gcs_out(oi, 83); gcs_out(oi, 0);
      li = s->normals;
    } else {
      dpointout(oi, bpptr[0].value.x, bpptr[0].value.y, 1);
      gcs_out(oi, 66); gcs_out(oi, 0);
      li = 0;
    }
    if((s->normale > 0) || (((oi->co)->fpd).cl) || (!((((oi->co)->fpd).ar) & 1))) {
      maxli = s->nbpoints - 2;
      if(((oi->co)->fpd).cl) { maxli = s->nbpoints - 1; }
      if((!(((oi->co)->fpd).cl)) && (((oi->co)->fpd).ar & 1)) {
        maxli = s->normale - 1;
      }
      while(li <= maxli) {
        ri = li + 1;
	if(ri >= s->nbpoints) { ri = 0; }
	dpointout(oi, bpptr[li].rcontrol.x, bpptr[li].rcontrol.y, 1);
	dpointout(oi, bpptr[ri].lcontrol.x, bpptr[ri].lcontrol.y, 1);
	dpointout(oi, bpptr[ri].value.x, bpptr[ri].value.y, 1);
	gcs_out(oi, 83); gcs_out(oi, 0);
        li++;
      }
    }
    if((!(((oi->co)->fpd).cl)) && (((oi->co)->fpd).ar & 1)) {
      dpointout(oi, (s->pe2).rcontrol.x, (s->pe2).rcontrol.y, 1);
      dpointout(oi, (s->pe).lcontrol.x, (s->pe).lcontrol.y, 1);
      dpointout(oi, (s->pe).value.x, (s->pe).value.y, 1);
      gcs_out(oi, 83); gcs_out(oi, 0);
    }
  } else {	
    dkfig_tool2_simple_error_message(oi->c, 44);
  }
} /* }}} */



/* {{{ create_contents_spline - write spline object to gcs
*/
static
int create_contents_spline DK_P1(OI *,oi)
{
  int back = 1;
  if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) {
    gcs_out(oi, 87);
    dkstream_puts_ul(oi->gcs, (oi->co)->lineno);
    gcs_out(oi, 0);
  }
  if(must_fill(oi) || must_pattern(oi) || must_stroke(oi)) {
    set_lw_and_colors(oi);
    write_spline_path(oi);
    final_keyword(oi);
    both_arrow_heads(oi);
  }
  return back;
} /* }}} */



/* {{{ write_arc_path
*/
static
void write_arc_path DK_P1(OI *,oi)
{
  pdf_arc_calc ac;
  dk_fig_arc *a;
  long lsegs;
  
  a = (dk_fig_arc *)((oi->co)->data);
  if(a) {
    lsegs = dkma_double_to_l(
      ceil(
        dkma_mul_double_ok(
	  dkma_l_to_double((oi->c)->circlesteps),
	  dkma_div_double_ok((a->calc).alength,(0.5 * M_PI), &(oi->me)),
	  &(oi->me)
	)
      )
    ); ac.segs = (unsigned)lsegs;
    ac.rx = fabs(dkma_mul_double_ok(oi->xfactor,(a->calc).ra,&(oi->me)));
    ac.ry = ac.rx;
    ac.xm = ccdx(oi, (a->calc).xm);
    ac.ym = ccdy(oi, (a->calc).ym);
    ac.phi0 = (a->calc).astart;
    ac.phi1 = dkma_add_double_ok(ac.phi0, (a->calc).alength, &(oi->me));
    if(!(((oi->co)->fpd).cl)) {		
      if((((oi->co)->fpd).ar) & 2) {	
        ac.phi0 = dkma_add_double_ok(ac.phi0, fabs(a->lba), &(oi->me));
      }
      if((((oi->co)->fpd).ar) & 1) {	
        ac.phi1 = dkma_sub_double_ok(ac.phi1, fabs(a->rba), &(oi->me));
      }
    }
    ac.x0 = dkma_add_double_ok(ac.xm, ac.rx * cos(ac.phi0), &(oi->me));
    ac.y0 = dkma_add_double_ok(ac.ym, ac.ry * sin(ac.phi0), &(oi->me));
    ac.x1 = dkma_add_double_ok(ac.xm, ac.rx * cos(ac.phi1), &(oi->me));
    ac.y1 = dkma_add_double_ok(ac.ym, ac.ry * sin(ac.phi1), &(oi->me));
    ac.x0 = drd(ac.x0, oi->c, 1); ac.y0 = drd(ac.y0, oi->c, 1);
    ac.x1 = drd(ac.x1, oi->c, 1); ac.y1 = drd(ac.y1, oi->c, 1);
    if(((oi->co)->fpd).cl) {
      nocdpointout(oi, ac.xm, ac.ym, 1);
      gcs_out(oi, 66); gcs_out(oi, 0);
      nocdpointout(oi, ac.x0, ac.y0, 1);
      gcs_out(oi, 67); gcs_out(oi, 0);
    } else {
      nocdpointout(oi, ac.x0, ac.y0, 1);
      gcs_out(oi, 66); gcs_out(oi, 0);
    }
    pdf_arc_path(oi, &ac);
  } else {	
    dkfig_tool2_simple_error_message(oi->c, 44);
  } 
} /* }}} */



/* {{{ create_contents_arc - write arc object to gcs
*/
static
int create_contents_arc DK_P1(OI *,oi)
{
  int back = 1;
  if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) {
    gcs_out(oi, 88);
    dkstream_puts_ul(oi->gcs, (oi->co)->lineno);
    gcs_out(oi, 0);
  }
  if(must_fill(oi) || must_pattern(oi) || must_stroke(oi)) {
    set_lw_and_colors(oi);
    write_arc_path(oi);
    final_keyword(oi);
    both_arrow_heads(oi);
  }
  return back;
} /* }}} */



/* {{{ create_contents_primitive - write current object to gcs
*/
static
int create_contents_primitive DK_P1(OI *,oi)
{
  int back = 1;
  switch((oi->co)->objtype) {
    case DK_FIG_OBJ_TEXT: {
      back = create_contents_text(oi);
    } break;
    case DK_FIG_OBJ_POLYLINE: {
      back = create_contents_polyline(oi);
    } break;
    case DK_FIG_OBJ_ELLIPSE: {
      back = create_contents_ellipse(oi);
    } break;
    case DK_FIG_OBJ_SPLINE: {
      back = create_contents_spline(oi);
    } break;
    case DK_FIG_OBJ_ARC: {
      back = create_contents_arc(oi);
    } break;
    default: {
      dkfig_tool2_simple_error_message(oi->c, 104);
    } break;
  }
  if(oi->me) {
    back = 0;
    oi->me = 0;
    dkfig_tool2_simple_error_message(oi->c, 13);
  }
  return back;
} /* }}} */



/* {{{ set_clip_path
*/
static
void set_clip_path DK_P1(OI *,oi)
{
  dkstream_puts_double(oi->gcs, 0.0);
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, 0.0);
  gcs_out(oi, 1);
  gcs_out(oi, 66);
  gcs_out(oi, 1);

  dkstream_puts_double(oi->gcs, oi->xright);
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, 0.0);
  gcs_out(oi, 1);
  gcs_out(oi, 67);
  gcs_out(oi, 1);

  dkstream_puts_double(oi->gcs, oi->xright);
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, oi->ytop);
  gcs_out(oi, 1);
  gcs_out(oi, 67);
  gcs_out(oi, 1);

  dkstream_puts_double(oi->gcs, 0.0);
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, oi->ytop);
  gcs_out(oi, 1);
  gcs_out(oi, 67);
  gcs_out(oi, 1);

  gcs_out(oi, 103);
  gcs_out(oi, 0);

} /* }}} */



/* {{{ create_contents_stream - write all graphics objects to gcs
*/
static
int create_contents_stream DK_P1(OI *,oi)
{
  int back = 1;
  dk_fig_object *o;
  unsigned long backupopt1, backupopt2;
  
  gcs_out(oi, 37); gcs_out(oi, 0);
  set_clip_path(oi);
  dksto_it_reset(oi->fli);
  oi->co = NULL;
  while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) {
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, o->lineno);
    }
    backupopt1 = (oi->c)->opt1;
    backupopt2 = (oi->c)->opt2;
    oi->co = o;
    if(!create_contents_primitive(oi)) {
      back = 0;
    }
    (oi->c)->opt1 = backupopt1;
    (oi->c)->opt2 = backupopt2;
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, 0UL);
    }
  } oi->co = NULL;
  gcs_out(oi, 38); gcs_out(oi, 0);
  back = 1;
  
  return back;
} /* }}} */



/* {{{ copy_file_to_stream - copy data file to gcs
*/
static
int copy_file_to_stream DK_P3(OI *,oi, char *,buffer, unsigned long,lgt)
{
  int back = 0;
  FILE *fipo;
  char smallbuf[256], *bigbuf, *buf;
  size_t buflgt, rdbytes; int cc; unsigned long summary;
  
  fipo = dkapp_fopen((oi->c)->app, buffer, str_open_read_binary);
  if(fipo) {
    bigbuf = dk_new(char, 4096);
    if(bigbuf) {
      buf = bigbuf; buflgt = 4096;
    } else {
      buf = smallbuf; buflgt = 256;
    }
    cc = 1; summary = 0UL; back = 1;
    while((cc == 1) && (summary < lgt)) {
      rdbytes = buflgt;
      if(((unsigned long)rdbytes) > (lgt - summary)) {
        rdbytes = (size_t)(lgt - summary);
      }
      rdbytes = fread(buf, 1, rdbytes, fipo);
      if(rdbytes) {
        if(dkstream_write(oi->s, buf, rdbytes) != rdbytes) {
	  cc = 0;
	} else {
	  summary += (unsigned long)rdbytes;
	  if(summary >= lgt) {
	    back = 1; cc = 0;
	  }
	}
      } else {
        cc = 0;
      }
    }
    if(bigbuf) {
      dk_delete(bigbuf); bigbuf = NULL;
    }
    fclose(fipo);
    if(!back) {
      dkfig_tool2_simple_error_message(oi->c, 105);
    }
  } else {
    if((oi->c)->app) {
      dkapp_err_fopenr((oi->c)->app, buffer);
    }
  } 
  return back;
} /* }}} */



/* {{{ write_graphics_stream
*/
static
int write_graphics_stream DK_P1(OI *,oi)
{
  int back = 0;
  char *buffer; size_t lgt; unsigned long streamlgt;
  
  if((oi->c)->app) {
    lgt = dksf_get_maxpathlen();
    buffer = dk_new(char,lgt);
    if(buffer) {
      if(dkapp_tmpnam((oi->c)->app, buffer, lgt)) {
        dk_stream_t *plainfile;
	
	oi->gcs = NULL;
	plainfile = dkapp_stream_openfile(
	  (oi->c)->app, buffer, str_open_write_binary
	);
	if(plainfile) {
	  if(((oi->c)->opt2) & DKFIG_OPT_PLAIN_TEXT_STREAMS) {
	    oi->gcs = plainfile;
	    back = create_contents_stream(oi);
	  } else {
	    dk_stream_t *compressedfile;
	    compressedfile = dkof_open(plainfile, 3);
	    if(compressedfile) {
	      dkof_set_crnl(compressedfile, 1);
	      back = 1;
	      if(!dkof_set(compressedfile,0,DK_OF_TYPE_BUFFERED)) { back = 0; }
	      if(!dkof_set(compressedfile,1,DK_OF_TYPE_ASCII85)) { back = 0; }
	      if(!dkof_set(compressedfile,2,DK_OF_TYPE_FLATE)) { back = 0; }
	      if(back) {
	        back = 0;
		if(dkof_start_chunk(compressedfile)) {
		  oi->gcs = compressedfile;
		  back = create_contents_stream(oi);
		  if(!dkof_end_chunk(compressedfile)) {
		    back = 0;
                    dkfig_tool2_simple_error_message(oi->c, 74);
		  }
		} else {
		  dkfig_tool2_simple_error_message(oi->c, 73);
		}
	      } else {
		dkfig_tool2_simple_error_message(oi->c, 72);
	      }
	      dkof_close(compressedfile);
	      compressedfile = NULL;
	    } else {
	      dkfig_tool2_simple_error_message(oi->c, 72);
	    }
	  }
	  streamlgt = dkstream_get_bytes_written(plainfile);
	  dkstream_close(plainfile); plainfile = NULL;
	  if(back) {
            kw_out(oi, 5); kw_out(oi, 1);
	    kw_out(oi, 39); kw_out(oi, 1);
	    dkstream_puts_ul(oi->s, streamlgt);
	    if(!(((oi->c)->opt2) & DKFIG_OPT_PLAIN_TEXT_STREAMS)) {
	      kw_out(oi, 1);
              kw_out(oi, 40);
	    }
	    kw_out(oi, 1); kw_out(oi, 6); kw_out(oi, 0);
	    kw_out(oi, 41); kw_out(oi, 0);
	    back = copy_file_to_stream(oi, buffer, streamlgt);
	    kw_out(oi, 42); kw_out(oi, 0);
	    dksf_remove_file(buffer);
	  }
	} else {
	  if((oi->c)->app) {
	    dkapp_err_fopenw((oi->c)->app, buffer);
	  }
	}
	oi->gcs = NULL;
      } else {
	dkfig_tool2_simple_error_message(oi->c, 67);
      }
      dk_delete(buffer); buffer = NULL;
    } else {
      if((oi->c)->app) {
        dkapp_err_memory((oi->c)->app,sizeof(char),lgt);
      }
    }
  } else {	
    dkfig_tool2_simple_error_message(oi->c, 44);
  } 
  return back;
} /* }}} */



/* {{{ write_fonts - write font definitions to resources dictionary
*/
static
void write_fonts DK_P1(OI *,oi)
{
  int i, is_first;
  is_first = 1;
  for(i = 0; i < 14; i++) {
    if((oi->fu)[i]) {
      if(is_first) {
        kw_out(oi, 44); kw_out(oi, 1);
	kw_out(oi, 5); kw_out(oi, 0);
      }
      is_first = 0;
      kw_out(oi, 35); kw_out(oi, 45);
      dkfig_tool_num_as_string(oi->s, (oi->fu)[i], oi->nostr);
      kw_out(oi, 1);
      dkstream_puts_ul(oi->s, (oi->fu)[i]);
      kw_out(oi, 1); kw_out(oi, 19);
      kw_out(oi, 1); kw_out(oi, 13);
      kw_out(oi, 0);
    }
  }
  if(!is_first) {
    kw_out(oi, 6); kw_out(oi, 0);
  }
} /* }}} */



/* {{{ write_patterns - write pattern definitions to resource dictionary
*/
static
void
write_patterns DK_P1(OI *,oi)
{
  int is_first = 1;
  dkfig_pdf_pattern *patp;
  dksto_it_reset(oi->patli);
  while((patp = (dkfig_pdf_pattern *)dksto_it_next(oi->patli)) != NULL) {
    if(is_first) {
      is_first = 0;
      kw_out(oi, 34); kw_out(oi, 1); kw_out(oi, 5); kw_out(oi, 0);
    }
    kw_out(oi, 35); kw_out(oi, 45);
    dkfig_tool_num_as_string(oi->s, patp->objno, oi->nostr);
    kw_out(oi, 1);
    dkstream_puts_ul(oi->s, patp->objno);
    kw_out(oi, 1); kw_out(oi, 19);
    kw_out(oi, 1); kw_out(oi, 13);
    kw_out(oi, 0);
  }
  if(!is_first) {
    kw_out(oi, 6); kw_out(oi, 0);
  }
} /* }}} */



/* {{{ write_images - write image definitions to resource dictionary
*/
static
void write_images DK_P1(OI *,oi)
{
  int is_first = 1;
  dkfig_pdf_image *imgp;
  dksto_it_reset(oi->imgli);
  while((imgp = (dkfig_pdf_image *)dksto_it_next(oi->imgli)) != NULL) {
    if(is_first) {
      is_first = 0;
      kw_out(oi, 33); kw_out(oi, 1);
      kw_out(oi, 5); kw_out(oi, 0);
    }
    kw_out(oi, 35); kw_out(oi, 45);
    dkfig_tool_num_as_string(oi->s, imgp->objno, oi->nostr);
    kw_out(oi, 1);
    dkstream_puts_ul(oi->s, imgp->objno);
    kw_out(oi, 1); kw_out(oi, 19);
    kw_out(oi, 1); kw_out(oi, 13);
    kw_out(oi, 0);
  }
  if(!is_first) {
    kw_out(oi, 6); kw_out(oi, 0);
  }
} /* }}} */



/* {{{ write_font_objects  - write font definition objects to output stream (os)
*/
static
int write_font_objects DK_P1(OI *,oi)
{
  int back = 1;
  int i;
  for(i = 0; i < 14; i++) {
    if((oi->fu)[i]) {
      if(begin_object(oi, (oi->fu)[i])) {
        kw_out(oi, 5); kw_out(oi, 1);
	kw_out(oi, 46);
	dkstream_puts(oi->s, pdf_font_names[i]);
	kw_out(oi, 1);
	kw_out(oi, 6); kw_out(oi, 0);
        end_object(oi);
      } else {
        back = 0;
      }
    }
  }
  return back;
} /* }}} */



/* {{{ PATD - data for one pattern
*/
typedef struct {
  double patrp;
  double lt;
  double w;
  double h;
  int    tiled;
} PATD;
/* }}} */



/* {{{ fill_rect - fill a rectangle
*/
static
void fill_rect DK_P5(OI *,oi, double,x1, double,y1, double,x2, double,y2)
{
  dkstream_puts_double(oi->gcs, drd(x1,oi->c,2));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(y1,oi->c,2));
  gcs_out(oi, 1); gcs_out(oi, 66); gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(x2,oi->c,2));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(y1,oi->c,2));
  gcs_out(oi, 1); gcs_out(oi, 67); gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(x2,oi->c,2));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(y2,oi->c,2));
  gcs_out(oi, 1); gcs_out(oi, 67); gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(x1,oi->c,2));
  gcs_out(oi, 1);
  dkstream_puts_double(oi->gcs, drd(y2,oi->c,2));
  gcs_out(oi, 1); gcs_out(oi, 67); gcs_out(oi, 1);
  gcs_out(oi, 68); gcs_out(oi, 1);
  gcs_out(oi, 69); gcs_out(oi, 0);
} /* }}} */



/* {{{ draw_line - draw a line
*/
static
void draw_line DK_P6(OI *,oi,double,x0,double,y0,double,x1,double,y1,int,cr)
{
  nocdpointout(oi, x0, y0, cr);
  gcs_out(oi, 66); gcs_out(oi, 1);
  nocdpointout(oi, x1, y1, cr);
  gcs_out(oi, 67); gcs_out(oi, 1);
  gcs_out(oi, 70); gcs_out(oi, 0);
} /* }}} */



/* {{{ pattern creation functions
*/
static
void stroke_41 DK_P2(OI *,oi, PATD *,p)
{
  int cc;
  double x, xstep, xend, x0, y0, x1, y1, f1, ystep;
  cc = 1;
  x = p->patrp;
  f1 = tan(M_PI / 6.0);
  xstep = 2.0 * p->patrp;
  if(p->tiled) {
    ystep = dkma_mul_double_ok(xstep, f1, &(oi->me));
    ystep = drd(ystep,oi->c,2);
    draw_line(oi, 0.0, ystep, xstep, 0.0, 2);
    draw_line(oi,(0.5 * xstep),(1.5 * ystep),(1.5 * xstep),(0.5 * ystep), 1);
    draw_line(oi,(-0.5 * xstep),(0.5 * ystep),(0.5 * xstep),(-0.5 * ystep), 1);
    p->w = xstep; p->h = ystep;
  } else {
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    while(cc) {
      x0 = x;   y0 = 0.0;
      x1 = 0.0;
      y1 = dkma_mul_double_ok(x0, f1, &(oi->me));
      if(y1 > oi->ytop) {
        y1 = oi->ytop;
	x1 = dkma_sub_double_ok(
	  x,
	  dkma_div_double_ok(oi->ytop, f1, &(oi->me)),
	  &(oi->me)
	);
        if(x1 > xend) {
          cc = 0;
        }
      }
      if(cc) {
        if(x0 > oi->xright) {
          x0 = oi->xright;
	  y0 = dkma_mul_double_ok(
	    f1,
	    dkma_sub_double_ok(x, oi->xright, &(oi->me)),
	    &(oi->me)
	  );
        }
        draw_line(oi, x0, y0, x1, y1, 1);
      }
      x += xstep;
    }
  }
}


  
static
void stroke_42 DK_P2(OI *,oi, PATD *,p)
{
  int cc;
  double x, xstep, xend, x0, y0, x1, y1, f1, ystep;
  
  xstep = dkma_mul_double_ok(2.0, p->patrp, &(oi->me));
  f1 = tan(M_PI / 6.0);
  if(p->tiled) {
    ystep = dkma_mul_double_ok(f1, xstep, &(oi->me));
    ystep = drd(ystep,oi->c,2);
    p->w = xstep; p->h = ystep;
    draw_line(oi, 0.0, 0.0, xstep, ystep, 2);
    draw_line(oi, (-0.5*xstep), (0.5*ystep), (0.5*xstep), (1.5*ystep), 2);
    draw_line(oi, (0.5*xstep), (-0.5*ystep), (1.5*xstep), (0.5*ystep), 2);
  } else {
    cc = 1;
    x = dkma_sub_double_ok(oi->xright, p->patrp, &(oi->me));
    xend = 0.0 - 0.5 * p->lt;
    while(cc) {
      x0 = x; y0 = 0.0;
      x1 = oi->xright;
      y1 = dkma_mul_double_ok(
        f1,
	dkma_sub_double_ok(oi->xright, x, &(oi->me)),
	&(oi->me)
      );
      if(y1 > oi->ytop) {
        y1 = oi->ytop;
	x1 = dkma_add_double_ok(
	  x,
	  dkma_div_double_ok(oi->ytop, f1, &(oi->me)),
	  &(oi->me)
	);
        if(x1 < xend) {
          cc = 0;
        }
      }
      if(cc) {
        if(x0 < 0.0) {
          x0 = 0.0;
	  y0 = dkma_mul_double_ok(f1, (0.0 - x), &(oi->me));
        }
        draw_line(oi, x0, y0, x1, y1, 1);
      }
      x -= xstep;
    }
  } 
}



static
void stroke_44 DK_P2(OI *,oi, PATD *,p)
{
  int cc;
  double x, xstep, xend, x0, y0, x1, y1;
  cc = 1;
  xstep = sqrt(2.0) * p->patrp;
  if(p->tiled) {
    p->w = p->h = drd(xstep,oi->c,2);
    draw_line(oi, 0.0, xstep, xstep, 0.0, 2);
    draw_line(oi, (0.5*xstep), (1.5*xstep), (1.5*xstep), (0.5*xstep), 2);
    draw_line(oi, (-0.5*xstep), (0.5*xstep), (0.5*xstep), (-0.5*xstep), 2);
  } else {
    x = 0.5 * xstep;
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    while(cc) {
      x0 = x;   y0 = 0.0;
      x1 = 0.0; y1 = x0;
      if(y1 > oi->ytop) {
        y1 = oi->ytop;
	x1 = dkma_sub_double_ok(x, oi->ytop, &(oi->me));
        if(x1 > xend) {
          cc = 0;
        }
      }
      if(cc) {
        if(x0 > oi->xright) {
          x0 = oi->xright;
	  y0 = dkma_sub_double_ok(x, oi->xright, &(oi->me));
        }
        draw_line(oi, x0, y0, x1, y1, 1);
      }
      x += xstep;
    }
  }
}



static
void stroke_45 DK_P2(OI *,oi, PATD *,p)
{
  int cc;
  double x, xstep, xend, x0, y0, x1, y1;
  
  cc = 1;
  xstep = dkma_mul_double_ok(sqrt(2.0), p->patrp, &(oi->me));
  if(p->tiled) {
    xstep = drd(xstep,oi->c,2);
    p->w = p->h = xstep;
    draw_line(oi, 0.0, 0.0, xstep, xstep, 2);
    draw_line(oi, (-0.5*xstep), (0.5*xstep), (0.5*xstep),(1.5*xstep),2);
    draw_line(oi, (0.5*xstep), (-0.5*xstep), (1.5*xstep),(0.5*xstep),2);
  } else {
    xend = 0.0 - 0.5 * p->lt;
    x = dkma_sub_double_ok(oi->xright, (0.5 * xstep), &(oi->me));
    while(cc) {
      x0 = x; y0 = 0.0;
      x1 = oi->xright;
      y1 = dkma_sub_double_ok(oi->xright, x, &(oi->me));
      if(y1 > oi->ytop) {
        y1 = oi->ytop;
	x1 = dkma_add_double_ok(x, oi->ytop, &(oi->me));
        if(x1 < xend) {
          cc = 0;
        }
      }
      if(cc) {
        if(x0 < 0.0) {
          x0 = 0.0;
	  y0 = 0.0 - x;
        }
        draw_line(oi, x0, y0, x1, y1, 1);
      }
      x -= xstep;
    }
  } 
}



static
void stroke_49 DK_P2(OI *,oi, PATD *,p)
{
  double y, yend, ystep;
  y = 0.0;
  ystep = drd(p->patrp,oi->c,1);
  if(p->tiled) {
    draw_line(oi, 0.0, 0.0, oi->xright, 0.0, 1);
    draw_line(oi, 0.0, ystep, oi->xright, ystep, 1);
    p->w = oi->xright;
    p->h = ystep;
  } else {
    yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
    while(y < yend) {
      draw_line(oi, 0.0, y, oi->xright, y, 1);
      y = dkma_add_double_ok(y, ystep, &(oi->me));
    }
  }
}



static
void stroke_50 DK_P2(OI *,oi, PATD *,p)
{
  double x, xend, xstep;
  x = 0.0;
  xstep = drd(p->patrp,oi->c,1);
  if(p->tiled) {
    p->w = xstep; p->h = oi->ytop;
    draw_line(oi, 0.0, 0.0, 0.0, oi->ytop, 1);
    draw_line(oi, xstep, 0.0, xstep, oi->ytop, 1);
  } else {
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    while(x < xend) {
      draw_line(oi, x, 0.0, x, oi->ytop, 1);
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
  }
}



static
void stroke_51_c DK_P2(OI *,oi, PATD *,p)
{
  double x, ystep, xstep;
  x = 0.0;
  ystep = xstep = drd(p->patrp,oi->c,1);
  p->w = xstep; p->h = ystep;
  nocdpointout(oi, 0.0, 0.0, 1);
  gcs_out(oi, 66); gcs_out(oi, 1);
  nocdpointout(oi, xstep, 0.0, 1);
  gcs_out(oi, 67); gcs_out(oi, 1);
  nocdpointout(oi, xstep, ystep, 1);
  gcs_out(oi, 67); gcs_out(oi, 1);
  nocdpointout(oi, 0.0, ystep, 1);
  gcs_out(oi, 67); gcs_out(oi, 1);
  gcs_out(oi, 68); gcs_out(oi, 1);
  gcs_out(oi, 70); gcs_out(oi, 0);
}



static
void stroke_47_a DK_P2(OI *,oi, PATD *,p)
{
  double y, yend, ystep;
  
  y = 0.0;
  ystep = drd(p->patrp,oi->c,1);
  ystep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  yend = dkma_add_double_ok(
    oi->ytop,
    (0.5 * p->lt),
    &(oi->me)
  );
  while(y < yend) {
    draw_line(oi, 0.0, y, oi->xright, y, 1);
    y = dkma_add_double_ok(y, ystep, &(oi->me));
  }
  
}



static
void stroke_47_c DK_P2(OI *,oi, PATD *,p)
{
  double ystep, xshift, xstep;
  
  xshift = ystep = drd(p->patrp, oi->c, 1);
  ystep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  xstep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  ll_set_linecap(oi, 2);
  draw_line(oi, 0.0, 0.0, xstep, 0.0, 1);
  draw_line(oi, 0.0, ystep, xstep, ystep, 1);
  draw_line(oi, 0.0, xstep, xstep, xstep, 1);
  ll_set_linecap(oi, 0);
  draw_line(oi, xshift, 0.0, xshift, ystep, 1);
  xshift = dkma_mul_double_ok(xshift, 3.0, &(oi->me));
  draw_line(oi, xshift, ystep, xshift, (2.0 * ystep), 1);
  ystep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  p->w = xstep; p->h = ystep;
  
}



static
void stroke_47_b DK_P2(OI *,oi, PATD *,p)
{
  double y, yend, ystep;
  double x, xend, xstep, xini;
  int i;
  
  y = 0.0;
  xini = ystep = drd(p->patrp,oi->c,1);
  ystep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
  xstep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  i = 0;
  while(y < yend) {
    
    if(i) {
      x = xini; i = 0;
    } else {
      x = 3.0 * xini; i = 1;
    } 
    while(x < xend) {
      
      draw_line(oi, x, y, x, (y + ystep), 1);
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
    y += ystep;
  } 
}



static
void stroke_48_a DK_P2(OI *,oi, PATD *,p)
{
  double x, xend, xstep, yini, ystep, yend;
  x = 0.0;
  yini = xstep = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  ystep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  yend = oi->ytop + 0.5 * p->lt;
  yend = dkma_add_double_ok(oi->ytop,(0.5 * p->lt),&(oi->me));
  while(x < xend) {
    draw_line(oi, x, 0.0, x, oi->ytop, 1);
    x = dkma_add_double_ok(x,xstep,&(oi->me));
  }
}



static
void stroke_48_c DK_P2(OI *,oi, PATD *,p)
{
  double xstep, ystep, yshift;
  yshift = xstep = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  ystep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  ll_set_linecap(oi,2);
  draw_line(oi, 0.0, 0.0, 0.0, ystep, 1);
  draw_line(oi, xstep, 0.0, xstep, ystep, 1);
  draw_line(oi, ystep, 0.0, ystep, ystep, 1);
  ll_set_linecap(oi, 0);
  draw_line(oi, 0.0, yshift, xstep, yshift, 1);
  yshift = dkma_mul_double_ok(3.0, yshift, &(oi->me));
  draw_line(oi, xstep, yshift, ystep, yshift, 1);
  xstep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  p->w = xstep; p->h = ystep;
}



static
void stroke_48_b DK_P2(OI *,oi, PATD *,p)
{
  double x, xend, xstep, y, yini, ystep, yend; int i;
  x = 0.0; i = 0;
  yini = xstep = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  ystep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  xend = dkma_add_double_ok(
    oi->xright,
    (0.5 * p->lt),
    &(oi->me)
  );
  yend = dkma_add_double_ok(
    oi->ytop,
    (0.5 * p->lt),
    &(oi->me)
  );
  while(x < xend) {
    /* draw_line(oi, x, 0.0, x, oi->ytop, 1); */
    if(i) {
      i = 0; y = yini;
    } else {
      i = 1;
      y = dkma_mul_double_ok(3.0, yini, &(oi->me));
    }
    while(y < yend) {
      draw_line(oi, x, y, (x+xstep), y, 1);
      y = dkma_add_double_ok(y, ystep, &(oi->me));
    }
    x = dkma_add_double_ok(x, xstep, &(oi->me));
  }
}



static
void stroke_52_b DK_P2(OI *,oi, PATD *,p)
{
  double y, yend, ystep;
  double x, xend, xstep, xini, xshift;
  int i;
  
  y = 0.0;
  xshift = xini = ystep = drd(p->patrp,oi->c,1);
  ystep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  yend  = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
  xstep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  xend  = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  i = 0;
  while(y < yend) {
    
    switch(i) {
      case 0: { i = 1; x = 0.0; } break;
      case 1: { i = 2;
        x = dkma_mul_double_ok(3.0, xini, &(oi->me));
      } break;
      case 2: { i = 3;
        x = dkma_mul_double_ok(2.0, xini, &(oi->me));
      } break;
      case 3: { i = 0; x = xini; } break;
    }
    
    while(x < xend) {
      
      draw_line(oi, x, y, (x+xshift), (y + ystep), 1);
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
    y = dkma_add_double_ok(y, ystep, &(oi->me));
  } 
}



static
void stroke_52_tiled DK_P2(OI *,oi, PATD *,p)
{
  double xstep, ystep, xini, xi2, xi3, xi4, xi5, xi6, xi8;
  xini = drd(p->patrp,oi->c,1);
  xi8 = ystep = dkma_mul_double_ok(8.0, xini, &(oi->me));
  xi4 = xstep = dkma_mul_double_ok(4.0, xini, &(oi->me));
  xi2 = dkma_mul_double_ok(2.0, xini, &(oi->me));
  xi3 = dkma_mul_double_ok(3.0, xini, &(oi->me));
  xi5 = dkma_mul_double_ok(5.0, xini, &(oi->me));
  xi6 = dkma_mul_double_ok(6.0, xini, &(oi->me));
  p->w = xstep; p->h = ystep;
  ll_set_linecap(oi, 1);
  draw_line(oi, 0.0, 0.0, xstep, 0.0, 1);
  draw_line(oi, 0.0, xi2, xstep, xi2, 1);
  draw_line(oi, 0.0, xi4, xstep, xi4, 1);
  draw_line(oi, 0.0, xi6, xstep, xi6, 1);
  draw_line(oi, 0.0, xi8, xstep, xi8, 1);
  draw_line(oi, 0.0, 0.0, xini, xi2, 1);
  draw_line(oi, xi3, xi2, xi4, xi4, 1);
  draw_line(oi, xi2, xi4, xi3, xi6, 1);
  draw_line(oi, xini, xi6, xi2, xi8, 1);
  draw_line(oi, xi4, 0.0, xi5, xi2, 1);
  draw_line(oi, (-1.0*xini), xi2, 0.0, xi4, 1);
}



static
void stroke_53_tiled DK_P2(OI *,oi, PATD *,p)
{
  double xstep, ystep, xini, xi2, xi3, xi4, xi5, xi6, xi8;
  xini = drd(p->patrp,oi->c,1);
  xi8 = ystep = dkma_mul_double_ok(8.0, xini, &(oi->me));
  xi4 = xstep = dkma_mul_double_ok(4.0, xini, &(oi->me));
  xi2 = dkma_mul_double_ok(2.0, xini, &(oi->me));
  xi3 = dkma_mul_double_ok(3.0, xini, &(oi->me));
  xi5 = dkma_mul_double_ok(5.0, xini, &(oi->me));
  xi6 = dkma_mul_double_ok(6.0, xini, &(oi->me));
  p->w = xstep; p->h = ystep;
  ll_set_linecap(oi, 1);
  draw_line(oi, 0.0, 0.0, xstep, 0.0, 1);
  draw_line(oi, 0.0, xi2, xstep, xi2, 1);
  draw_line(oi, 0.0, xi4, xstep, xi4, 1);
  draw_line(oi, 0.0, xi6, xstep, xi6, 1);
  draw_line(oi, 0.0, xi8, xstep, xi8, 1);
  draw_line(oi, 0.0, xi2, xini, 0.0, 1);
  draw_line(oi, xini, xi4, xi2, xi2, 1);
  draw_line(oi, xi2, xi6, xi3, xi4, 1);
  draw_line(oi, xi3, xi8, xi4, xi6, 1);
  draw_line(oi, xi4, xi2, xi5, 0.0, 1);
  draw_line(oi, (-1.0*xini), xi8, 0.0, xi6, 1);
}



static
void stroke_53_b DK_P2(OI *,oi, PATD *,p)
{
  double y, yend, ystep;
  double x, xend, xstep, xini, xshift;
  int i;
  
  y = 0.0;
  xshift = xini = ystep = drd(p->patrp,oi->c,1);
  ystep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
  xstep = dkma_mul_double_ok(2.0, ystep, &(oi->me));
  xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  i = 0;
  while(y < yend) {
    
    switch(i) {
      case 0: { i = 1; x = 0.0; } break;
      case 1: { i = 2; x = xini; } break;
      case 2: { i = 3; x = dkma_mul_double_ok(2.0,xini,&(oi->me)); } break;
      case 3: { i = 0; x = dkma_mul_double_ok(3.0,xini,&(oi->me)); } break;
    }
    
    while(x < xend) {
      
      draw_line(oi, (x+xshift), y, x, (y + ystep), 1);
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
    y = dkma_add_double_ok(y, ystep, &(oi->me));
  } 
}



static
void stroke_54_b DK_P2(OI *,oi, PATD *,p)
{
  double x, xend, xstep, y, yini, ystep, yend, yshift; int i;
  x = 0.0; i = 0;
  yshift = yini = xstep = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  ystep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
  while(x < xend) {
    switch(i) {
      case 0: {
        i = 1; y = 0.0;
      } break;
      case 1: {
        i = 2; y = yini;
      } break;
      case 2: {
        i = 3; y = dkma_mul_double_ok(2.0, yini, &(oi->me));
      } break;
      case 3: {
        i = 0; y = dkma_mul_double_ok(3.0, yini, &(oi->me));
      } break;
    }
    while(y < yend) {
      draw_line(oi, x, (y+yshift), (x+xstep), y, 1);
      y = dkma_add_double_ok(y, ystep, &(oi->me));
    }
    x = dkma_add_double_ok(x, xstep, &(oi->me));
  }
}



static
void stroke_55_b DK_P2(OI *,oi, PATD *,p)
{
  double x, xend, xstep, y, yini, ystep, yend, yshift; int i;
  x = 0.0; i = 0;
  yshift = yini = xstep = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  ystep = dkma_mul_double_ok(2.0, xstep, &(oi->me));
  xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
  while(x < xend) {
    switch(i) {
      case 0: {
        i = 1; y = dkma_mul_double_ok(3.0, yini, &(oi->me));
      } break;
      case 1: {
        i = 2; y = dkma_mul_double_ok(2.0, yini, &(oi->me));
      } break;
      case 2: {
        i = 3; y = yini;
      } break;
      case 3: {
        i = 0; y = 0.0;
      } break;
    }
    while(y < yend) {
      draw_line(oi, x, y, (x+xstep), (y+yshift), 1);
      y = dkma_add_double_ok(y, ystep, &(oi->me));
    }
    x = dkma_add_double_ok(x, xstep, &(oi->me));
  }
}



static
void stroke_54_tiled DK_P2(OI *,oi, PATD *,p)
{
  double yini, xstep, ystep, yi2, yi3, yi4, yi5, yi6, yi8;
  yini = drd(p->patrp,oi->c,1);
  yi8 = xstep = dkma_mul_double_ok(8.0, yini, &(oi->me));
  yi4 = ystep = dkma_mul_double_ok(4.0, yini, &(oi->me));
  yi2 = dkma_mul_double_ok(2.0, yini, &(oi->me));
  yi3 = dkma_mul_double_ok(3.0, yini, &(oi->me));
  yi5 = dkma_mul_double_ok(5.0, yini, &(oi->me));
  yi6 = dkma_mul_double_ok(6.0, yini, &(oi->me));
  p->w = xstep; p->h = ystep;
  draw_line(oi, 0.0, 0.0, 0.0, ystep, 1);
  draw_line(oi, yi2, 0.0, yi2, ystep, 1);
  draw_line(oi, yi4, 0.0, yi4, ystep, 1);
  draw_line(oi, yi6, 0.0, yi6, ystep, 1);
  draw_line(oi, yi8, 0.0, yi8, ystep, 1);
  draw_line(oi, 0.0, yi2, yi2, yini, 1);
  draw_line(oi, yi2, yi3, yi4, yi2, 1);
  draw_line(oi, yi4, yi4, yi6, yi3, 1);
  draw_line(oi, yi6, yini, yi8, 0.0, 1);
  draw_line(oi, yi4, 0.0, yi6, (-1.0*yini), 1);
  draw_line(oi, yi6, yi5, yi8, yi4, 1);
}



static
void stroke_55_tiled DK_P2(OI *,oi, PATD *,p)
{
  double yini, xstep, ystep, yi2, yi3, yi4, yi5, yi6, yi8;
  yini = drd(p->patrp,oi->c,1);
  yi8 = xstep = dkma_mul_double_ok(8.0, yini, &(oi->me));
  yi4 = ystep = dkma_mul_double_ok(4.0, yini, &(oi->me));
  yi2 = dkma_mul_double_ok(2.0, yini, &(oi->me));
  yi3 = dkma_mul_double_ok(3.0, yini, &(oi->me));
  yi5 = dkma_mul_double_ok(5.0, yini, &(oi->me));
  yi6 = dkma_mul_double_ok(6.0, yini, &(oi->me));
  p->w = xstep; p->h = ystep;
  draw_line(oi, 0.0, 0.0, 0.0, ystep, 1);
  draw_line(oi, yi2, 0.0, yi2, ystep, 1);
  draw_line(oi, yi4, 0.0, yi4, ystep, 1);
  draw_line(oi, yi6, 0.0, yi6, ystep, 1);
  draw_line(oi, yi8, 0.0, yi8, ystep, 1);
  draw_line(oi, 0.0, yi3, yi2, yi4, 1);
  draw_line(oi, yi2, yi2, yi4, yi3, 1);
  draw_line(oi, yi4, yini, yi6, yi2, 1);
  draw_line(oi, yi6, 0.0, yi8, yini, 1);
  draw_line(oi, 0.0, (-1.0*yini), yi2, 0.0, 1);
  draw_line(oi, yi6, yi5, yi8, yi4, 1);
}



static
void stroke_58 DK_P2(OI *,oi, PATD *,p)
{
  pdf_arc_calc ac;
  double x, y, xstep, ystep, xend, yend, r;
  r = 2.0 * p->patrp;
  r = drd(r,oi->c,1);
  xstep = ystep = 2.0 * r;
  if(p->tiled) {
    p->w = xstep; p->h = ystep;
    ac.xm = r; ac.ym = r;
    ac.rx = r; ac.ry = r;
    ac.phi0 = 0.0; ac.phi1 = 2.0 * M_PI;
    ac.segs = 4 * (oi->c)->circlesteps;
    ac.x0 = ac.x1 = dkma_mul_double_ok(2.0, r, &(oi->me));
    ac.y0 = ac.y1 = r;
    nocdpointout(oi, ac.x0, ac.y0, 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    pdf_arc_path(oi, &ac);
    gcs_out(oi, 68); gcs_out(oi, 1);
    gcs_out(oi, 70); gcs_out(oi, 0);
  } else {
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
    x = 0.0;
    while(x < xend) {
      y = 0.0;
      while(y < yend) {
        ac.xm = dkma_add_double_ok(x, r, &(oi->me));
        ac.ym = dkma_add_double_ok(y, r, &(oi->me));
        ac.rx = ac.ry = r;
        ac.phi0 = 0.0;
        ac.phi1 = 2.0 * M_PI;
        ac.segs = 4 * (oi->c)->circlesteps;
        ac.x0 = ac.x1 = dkma_add_double_ok(ac.xm, r, &(oi->me));
        ac.y0 = ac.y1 = ac.ym;
        nocdpointout(oi, ac.x0, ac.y0, 1);
        gcs_out(oi, 66); gcs_out(oi, 0);
        pdf_arc_path(oi, &ac);
        gcs_out(oi, 68); gcs_out(oi, 1);
        gcs_out(oi, 70); gcs_out(oi, 0);
	y = dkma_add_double_ok(y, ystep, &(oi->me));
      }
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
  }
}



static
void stroke_59 DK_P2(OI *,oi, PATD *,p)
{
  double r, x, y, x1, x2, x3, x4, y1, y2;
  double xstep, ystep, xend, yend;
  r = dkma_mul_double_ok(2.0, p->patrp, &(oi->me));
  r = drd(r, oi->c, 1);
  ystep = dkma_mul_double_ok(2.0, r, &(oi->me));
  r = dkma_mul_double_ok(2.0, r, &(oi->me)) / sqrt(3.0);
  xstep = dkma_mul_double_ok(3.0, r, &(oi->me));
  xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
  yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
  x = 0.0;
  if(p->tiled) {
    y = 0.0;
    x1 = dkma_add_double_ok(x, (0.5 * r), &(oi->me));
    x2 = dkma_add_double_ok(x1, r, &(oi->me));
    x3 = dkma_add_double_ok(x2, (0.5 * r), &(oi->me));
    x4 = dkma_add_double_ok(x3, r, &(oi->me));
    y1 = dkma_add_double_ok(y, (0.5 * ystep), &(oi->me));
    y2 = dkma_add_double_ok(y, ystep, &(oi->me));
    nocdpointout(oi, x, y1, 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(oi, x1, y, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x2, y, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x3, y1, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x2, y2, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x1, y2, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    gcs_out(oi, 68); gcs_out(oi, 1);
    gcs_out(oi, 70); gcs_out(oi, 0);
    nocdpointout(oi, x3, y1, 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(oi, x4, y1, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    gcs_out(oi, 70); gcs_out(oi, 0);
    nocdpointout(oi, x4, y1, 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(oi, dkma_add_double_ok(x4,x1,&(oi->me)), y2, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    gcs_out(oi, 70); gcs_out(oi, 0);
    nocdpointout(oi, x4, y1, 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(oi, dkma_add_double_ok(x4,x1,&(oi->me)), 0, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    gcs_out(oi, 70); gcs_out(oi, 0);
    p->w = xstep; p->h = ystep;
  } else {
    while(x < xend) {
      y = 0.0;
      while(y < yend) {
        x1 = dkma_add_double_ok(x, (0.5 * r), &(oi->me));
        x2 = dkma_add_double_ok(x1, r, &(oi->me));
        x3 = dkma_add_double_ok(x2, (0.5 * r), &(oi->me));
        x4 = dkma_add_double_ok(x3, r, &(oi->me));
        y1 = dkma_add_double_ok(y, (0.5 * ystep), &(oi->me));
        y2 = dkma_add_double_ok(y, ystep, &(oi->me));
        nocdpointout(oi, x, y1, 1);
        gcs_out(oi, 66); gcs_out(oi, 0);
        nocdpointout(oi, x1, y, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x2, y, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x3, y1, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x2, y2, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x1, y2, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        gcs_out(oi, 68); gcs_out(oi, 1);
        gcs_out(oi, 70); gcs_out(oi, 0);
        nocdpointout(oi, x3, y1, 1);
        gcs_out(oi, 66); gcs_out(oi, 0);
        nocdpointout(oi, x4, y1, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        gcs_out(oi, 70); gcs_out(oi, 0);
	y = dkma_add_double_ok(y, ystep, &(oi->me));
      }
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
  }
}



static
void stroke_60 DK_P2(OI *,oi, PATD *,p)
{
  double xstep, m, x, y, x1, x2, x3, y1, y2, y3, xend, yend;
  xstep = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(4.0, xstep, &(oi->me));
  m = xstep / (2.0 + sqrt(2.0));
  m = drd(m,oi->c,2);
  if(p->tiled) {
    x = y = 0.0;
    x1 = y1 = m;
    x2 = y2 = xstep - m;
    x3 = y3 = xstep;
    nocdpointout(oi, 0.0, y1, 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(oi, x1, 0.0, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x2, 0.0, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x3, y1, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x3, y2, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x2, y3, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, x1, y3, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    nocdpointout(oi, 0.0, y2, 1);
    gcs_out(oi, 67); gcs_out(oi, 0);
    gcs_out(oi, 68); gcs_out(oi, 1);
    gcs_out(oi, 70); gcs_out(oi, 0);
    p->w = xstep; p->h = xstep;
  } else {
    x = 0.0;
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
    while(x < xend) {
      y = 0.0;
      while(y < yend) {
        x1 = dkma_add_double_ok(x, m, &(oi->me));
	y1 = dkma_add_double_ok(y, m, &(oi->me));
        x2 = dkma_add_double_ok(x, (xstep - m), &(oi->me));
	y2 = dkma_add_double_ok(y, (xstep - m), &(oi->me));
        x3 = dkma_add_double_ok(x, xstep, &(oi->me));
	y3 = dkma_add_double_ok(y, xstep, &(oi->me));
        nocdpointout(oi, x, y1, 1);
        gcs_out(oi, 66); gcs_out(oi, 0);
        nocdpointout(oi, x1, y, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x2, y, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x3, y1, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x3, y2, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x2, y3, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x1, y3, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        nocdpointout(oi, x, y2, 1);
        gcs_out(oi, 67); gcs_out(oi, 0);
        gcs_out(oi, 68); gcs_out(oi, 1);
        gcs_out(oi, 70); gcs_out(oi, 0);
	y = dkma_add_double_ok(y, xstep, &(oi->me));
      }
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
  }
}



static
void stroke_61 DK_P2(OI *,oi, PATD *,p)
{
  double x, y, xstep, ystep, xend, yend, xshift, y1, y2;
  int i;
  xshift = drd(p->patrp,oi->c,1);
  xstep = dkma_mul_double_ok(2.0, xshift, &(oi->me));
  ystep = xstep;
  if(p->tiled) {
    y1 = 0.5 * xshift;
    y2 = dkma_add_double_ok(y1, xshift, &(oi->me));
    ll_set_linecap(oi, 1);
    ll_set_linejoin(oi, 1);
    nocdpointout(oi, 0.0, y1, 1);
    gcs_out(oi, 66); gcs_out(oi, 1);
    nocdpointout(oi, xshift, y2, 1);
    gcs_out(oi, 67); gcs_out(oi, 1);
    nocdpointout(oi, xstep, y1, 1);
    gcs_out(oi, 67); gcs_out(oi, 1);
    gcs_out(oi, 70); gcs_out(oi, 0);
    p->w = xstep; p->h = ystep;
  } else {
    ll_set_linecap(oi, 2);
    ll_set_linejoin(oi, 0);
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
    y = 0.0;
    while(y < yend) {
      i = 0; x = 0.0;
      y1 = dkma_add_double_ok(y, (0.5 * xshift), &(oi->me));
      y2 = dkma_add_double_ok(y1, xshift, &(oi->me));
      nocdpointout(oi, x, y1, 1);
      gcs_out(oi, 66); gcs_out(oi, 0);
      do {
	x = dkma_add_double_ok(x, xshift, &(oi->me));
        if(i) {
	  i = 0;
	  nocdpointout(oi, x, y1, 1);
	} else {
	  i = 1;
	  nocdpointout(oi, x, y2, 1);
	}
	gcs_out(oi, 67); gcs_out(oi, 0);
      } while(x < xend);
      gcs_out(oi, 70); gcs_out(oi, 0);
      y = dkma_add_double_ok(y, ystep, &(oi->me));
    }
  }
}



static
void stroke_62 DK_P2(OI *,oi, PATD *,p)
{
  double x, y, x1, x2, xstep, ystep, xshift, xend, yend;
  int i;
  xshift = drd(p->patrp,oi->c,1);
  xstep = ystep = dkma_mul_double_ok(2.0, xshift, &(oi->me));
  if(p->tiled) {
    x = y = 0.0;
    x1 = 0.5 * xshift;
    x2 = dkma_add_double_ok(x1, xshift, &(oi->me));
    ll_set_linejoin(oi, 1); ll_set_linecap(oi, 1);
    nocdpointout(oi, x1, 0.0, 1);
    gcs_out(oi, 66); gcs_out(oi, 1);
    nocdpointout(oi, x2, xshift, 1);
    gcs_out(oi, 67); gcs_out(oi, 1);
    nocdpointout(oi, x1, xstep, 1);
    gcs_out(oi, 67); gcs_out(oi, 1);
    gcs_out(oi, 70); gcs_out(oi, 0);
    p->w = xstep; p->h = ystep;
  } else {
    ll_set_linejoin(oi, 0); ll_set_linecap(oi, 2);
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
    x = 0.0;
    while(x < xend) {
      y = 0.0; i = 0;
      x1 = dkma_add_double_ok(x, (0.5 * xshift), &(oi->me));
      x2 = dkma_add_double_ok(x1, xshift, &(oi->me));
      nocdpointout(oi, x1, 0.0, 1);
      gcs_out(oi, 66); gcs_out(oi, 0);
      do {
	y = dkma_add_double_ok(y, xshift, &(oi->me));
	if(i) {
	  i = 0;
	  nocdpointout(oi, x1, y, 1);
	} else {
	  i = 1;
	  nocdpointout(oi, x2, y, 1);
	}
	gcs_out(oi, 67); gcs_out(oi, 1);
      } while(y < yend);
      gcs_out(oi, 70); gcs_out(oi, 0);
      x = dkma_add_double_ok(x, xstep, &(oi->me));
    }
  }
}



/* 0=large, 1=small */

static
void stroke_56 DK_P3(OI *,oi, PATD *,p, int,cr)
{
  double radius, deltax, deltay, xshift, yshift, xstep, ystep, x, y;
  double deltaxa;
  radius = fabs(p->patrp);
  if(cr) {	/* small */
    xshift = yshift = radius;
    xstep = ystep = dkma_mul_double_ok(2.0, xshift, &(oi->me));
    deltax = deltay = dkma_mul_double_ok((0.5 * M_PI), radius, &(oi->me)) / 3.0;
    deltaxa = 0.0;
  } else {	/* large */
    double phi;
    radius = dkma_mul_double_ok(2.5, radius, &(oi->me));
    phi = 1.5 * M_PI - 0.5 * 1.881618;
    deltaxa = radius * fabs(sin(phi));
    deltay  = radius * fabs(cos(phi));
    deltax  = radius;
    deltaxa = dkma_mul_double_ok(deltaxa, (0.5 * 1.881618), &(oi->me));
    deltax  = dkma_mul_double_ok(deltax, (0.5 * 1.881618), &(oi->me));
    deltay  = dkma_mul_double_ok(deltay, (0.5 * 1.881618), &(oi->me));
    deltaxa = deltaxa / 3.0;
    deltax  = deltax  / 3.0;
    deltay  = deltay  / 3.0;
    xshift  = dkma_mul_double_ok(2.0, p->patrp, &(oi->me));
    xstep   = dkma_mul_double_ok(2.0, xshift, &(oi->me));
    yshift  = radius * (1.0 - cos(0.5 * 1.881618));
    yshift  = drd(yshift,oi->c,1);
    ystep   = dkma_mul_double_ok(2.0, yshift, &(oi->me));
  }
  if(p->tiled) {
    p->w = xstep; p->h = ystep;
    x = y = 0.0;
    nocdpointout(oi, x, dkma_add_double_ok(y,ystep,&(oi->me)), 1);
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(oi, dkma_add_double_ok(x,deltaxa,&(oi->me)),
      dkma_sub_double_ok(
        dkma_add_double_ok(y,ystep,&(oi->me)),
	deltay,&(oi->me)
      ), 2
    ); 
    nocdpointout(
      oi,
      dkma_sub_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xshift,&(oi->me)),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    nocdpointout(
      oi,
      dkma_add_double_ok(
        x,
	dkma_add_double_ok(xshift,deltax,&(oi->me)),
	&(oi->me)
      ),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    nocdpointout(
      oi,
      dkma_sub_double_ok(
        dkma_add_double_ok(x,xstep,&(oi->me)),
	deltaxa,&(oi->me)
      ),
      dkma_sub_double_ok(
        dkma_add_double_ok(y,ystep,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_add_double_ok(y,ystep,&(oi->me)),
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    gcs_out(oi, 70); gcs_out(oi, 0);
    x = 0.0 - xshift;
    nocdpointout(
      oi, x, dkma_add_double_ok(y,yshift,&(oi->me)), 1
    );
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(
      oi, x,
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_sub_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y, 2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xshift,&(oi->me)),
      y,
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    nocdpointout(
      oi,
      dkma_add_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y, 1
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
        deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    x = dkma_add_double_ok(x, xstep, &(oi->me));
    nocdpointout(
      oi,
      x,
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_sub_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y, 2
    );
    nocdpointout(
      oi, dkma_add_double_ok(x,xshift,&(oi->me)), y, 1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    nocdpointout(
      oi,
      dkma_add_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y, 1
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    gcs_out(oi, 70); gcs_out(oi, 0);
    y = ystep;
    x = 0.0 - xshift;
    nocdpointout(
      oi,
      x,
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    gcs_out(oi, 66); gcs_out(oi, 0);
    nocdpointout(
      oi,
      x,
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_sub_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y,
      2
    );
    nocdpointout(oi, (x+xshift), y, 1);
    gcs_out(oi, 83); gcs_out(oi, 0);
    nocdpointout(
      oi,
      dkma_add_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y,
      1
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    x = dkma_add_double_ok(x,xstep,&(oi->me));
    nocdpointout(
      oi,
      x,
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_sub_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y,
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xshift,&(oi->me)),
      y,
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    nocdpointout(
      oi,
      dkma_add_double_ok(
        dkma_add_double_ok(x,xshift,&(oi->me)),
	deltax,&(oi->me)
      ),
      y,
      1
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_sub_double_ok(
        dkma_add_double_ok(y,yshift,&(oi->me)),
	deltay,&(oi->me)
      ),
      2
    );
    nocdpointout(
      oi,
      dkma_add_double_ok(x,xstep,&(oi->me)),
      dkma_add_double_ok(y,yshift,&(oi->me)),
      1
    );
    gcs_out(oi, 83); gcs_out(oi, 0);
    gcs_out(oi, 70); gcs_out(oi, 0);
  } else {
    double xend, yend;
    ll_set_linecap(oi, 1); ll_set_linejoin(oi, 1);
    xend = dkma_add_double_ok(oi->xright, (0.5 * p->lt), &(oi->me));
    yend = dkma_add_double_ok(oi->ytop, (0.5 * p->lt), &(oi->me));
    y = 0.0;
    while(y < yend) {
      x = 0.0;
      nocdpointout(
        oi,
	x,
	dkma_add_double_ok(y,ystep,&(oi->me)),
	1
      );
      gcs_out(oi, 66); gcs_out(oi, 0);
      do {
        nocdpointout(
	  oi,
	  dkma_add_double_ok(x,deltaxa,&(oi->me)),
	  dkma_sub_double_ok(
	    dkma_add_double_ok(y,ystep,&(oi->me)),
	    deltay,&(oi->me)
	  ),
	  2
	);
	nocdpointout(
	  oi,
	  dkma_sub_double_ok(
	    dkma_add_double_ok(x,xshift,&(oi->me)),
	    deltax,&(oi->me)
	  ),
	  dkma_add_double_ok(y,yshift,&(oi->me)),
	  2
	);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(x,xshift,&(oi->me)),
	  dkma_add_double_ok(y,yshift,&(oi->me)),
	  1
	);
	gcs_out(oi, 83); gcs_out(oi, 0);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(
	    dkma_add_double_ok(x,xshift,&(oi->me)),
	    deltax,&(oi->me)
	  ),
	  dkma_add_double_ok(y,yshift,&(oi->me)),
	  1
	);
	nocdpointout(
	  oi,
	  dkma_sub_double_ok(
	    dkma_add_double_ok(x,xstep,&(oi->me)),
	    deltaxa,&(oi->me)
	  ),
	  dkma_sub_double_ok(
	    dkma_add_double_ok(y,ystep,&(oi->me)),
	    deltay,&(oi->me)
	  ),
	  2
	);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(x,xstep,&(oi->me)),
	  dkma_add_double_ok(y,ystep,&(oi->me)),
	  1
	);
	gcs_out(oi, 83); gcs_out(oi, 0);
	x = dkma_add_double_ok(x,xstep,&(oi->me));
      } while(x < xend);
      gcs_out(oi, 70); gcs_out(oi, 0);
      x = 0.0 - xshift;
      nocdpointout(
        oi,
	x,
	dkma_add_double_ok(y,yshift,&(oi->me)),
	1
      );
      gcs_out(oi, 66); gcs_out(oi, 0);
      do {
        nocdpointout(
	  oi,
	  x,
	  dkma_sub_double_ok(
	    dkma_add_double_ok(y,yshift,&(oi->me)),
	    deltay,&(oi->me)
	  ),
	  2
	);
	nocdpointout(
	  oi,
	  dkma_sub_double_ok(
	    dkma_add_double_ok(x,xshift,&(oi->me)),
	    deltax,&(oi->me)
	  ),
	  y,
	  2
	);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(x,xshift,&(oi->me)),
	  y,
	  1
	);
	gcs_out(oi, 83); gcs_out(oi, 0);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(
	    dkma_add_double_ok(x,xshift,&(oi->me)),
	    deltax,&(oi->me)
	  ),
	  y,
	  1
	);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(x,xstep,&(oi->me)),
	  dkma_sub_double_ok(
	    dkma_add_double_ok(y,yshift,&(oi->me)),
	    deltay,&(oi->me)
	  ),
	  2
	);
	nocdpointout(
	  oi,
	  dkma_add_double_ok(x,xstep,&(oi->me)),
	  dkma_add_double_ok(y,yshift,&(oi->me)),
	  1
	);
	gcs_out(oi, 83); gcs_out(oi, 0);
	x = dkma_add_double_ok(x, xstep, &(oi->me));
      } while(x < xend);
      gcs_out(oi, 70); gcs_out(oi, 0);
      y = dkma_add_double_ok(y, ystep, &(oi->me));
    }
  }
}
/* }}} */



/* {{{ create_pattern_stream - write one pattern data to gcs
*/
static
int
create_pattern_stream DK_P3(OI *,oi, double *,w, double *,h)
{
  int back = 1;
  PATD patd;
  dk_fig_dcc fdcc, bdcc;
  
  if((oi->c)->patrp) {
    patd.patrp = 0.9 * dkma_l_to_double((oi->c)->patrp);
  } else {
    patd.patrp = 3.6;
  }
  patd.w = oi->xright;
  patd.h = oi->ytop;
  patd.tiled = 0;
  if((oi->cp)->tile) {
    patd.tiled = 1;
    
  } else {
    
  }
  /* foreground and background color */
  dkfig_tool_fill_dcc(oi->d, &fdcc, (oi->cp)->fgcol);
  dkfig_tool_fill_dcc(oi->d, &bdcc, (oi->cp)->bgcol);
  /* patd.lt = 0.9 * dkma_l_to_double((oi->cp)->lt); */
  patd.lt = 0.9;
  /*
  if(((oi->cp)->lt) == 0L) {
    patd.lt = 0.9;
  }
  */
  if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) {
    patd.lt = 0.5 * patd.lt;
  }
  ll_set_stroking(oi, &fdcc);
  ll_set_nonstroking(oi, &bdcc);
  ll_set_linewidth(oi, drd(patd.lt,oi->c,1));
  fill_rect(oi, 0.0, 0.0, oi->xright, oi->ytop);

  switch((oi->cp)->patno) {
    case 41: {
      ll_set_linecap(oi, 2);
      stroke_41(oi, &patd);
    } break;
    case 42: {
      ll_set_linecap(oi, 2);
      stroke_42(oi, &patd);
    } break;
    case 43: {
      ll_set_linecap(oi, 2);
      stroke_41(oi, &patd);
      stroke_42(oi, &patd);
    } break;
    case 44: {
      ll_set_linecap(oi, 2);
      stroke_44(oi, &patd);
    } break;
    case 45: {
      ll_set_linecap(oi, 2);
      stroke_45(oi, &patd);
    } break;
    case 46: {
      ll_set_linecap(oi, 2);
      stroke_44(oi, &patd);
      stroke_45(oi, &patd);
    } break;
    case 47: {	/* horizontal bricks */
      if(patd.tiled) {
	stroke_47_c(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_47_a(oi, &patd);
        stroke_47_b(oi, &patd);
      }
    } break;
    case 48: {	/* vertical bricks */
      if(patd.tiled) {
        stroke_48_c(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_48_a(oi, &patd);
        stroke_48_b(oi, &patd);
      }
    } break;
    case 49: {	/* horizontal lines */
      ll_set_linecap(oi, 0);
      stroke_49(oi, &patd);
    } break;
    case 50: {	/* vertical lines */
      ll_set_linecap(oi, 0);
      stroke_50(oi, &patd);
    } break;
    case 51: {	/* crosshatch */
      if(patd.tiled) {
        ll_set_linecap(oi, 0);
	ll_set_linejoin(oi, 0);
        stroke_51_c(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_49(oi, &patd);
        stroke_50(oi, &patd);
      }
    } break;
    case 52: {	/* horizontal shingles 1 */
      if(patd.tiled) {
        stroke_52_tiled(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_47_a(oi, &patd);
        stroke_52_b(oi, &patd);
      }
    } break;
    case 53: {	/* horizontal shingles 2 */
      if(patd.tiled) {
        stroke_53_tiled(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_47_a(oi, &patd);
        stroke_53_b(oi, &patd);
      }
    } break;
    case 54: {	/* vertical shingles 1 */
      if(patd.tiled) {
        stroke_54_tiled(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_48_a(oi, &patd);
        stroke_54_b(oi, &patd);
      }
    } break;
    case 55: {	/* vertical shingles 2 */
      if(patd.tiled) {
        stroke_55_tiled(oi, &patd);
      } else {
        ll_set_linecap(oi, 0);
        stroke_48_a(oi, &patd);
        stroke_55_b(oi, &patd);
      }
    } break;
    case 56: {	/* large fish scales */
      stroke_56(oi, &patd, 0);
    } break;
    case 57: {	/* small fish scales */
      stroke_56(oi, &patd, 1);
    } break;
    case 58: {	/* circles */
      stroke_58(oi, &patd);
    } break;
    case 59: {	/* hexagons */
      ll_set_linecap(oi, 1);
      stroke_59(oi, &patd);
    } break;
    case 60: {	/* octagons */
      ll_set_linejoin(oi, 0);
      stroke_60(oi, &patd);
    } break;
    case 61: {	/* horizontal tire treads */
      stroke_61(oi, &patd);
    } break;
    case 62: {	/* vertical tire treads */
      stroke_62(oi, &patd);
    } break;
  }
  *w = patd.w; *h = patd.h;
  
  return back;
} /* }}} */



/* {{{ write_one_pattern_object - write pattern object to os
*/
static
int
write_one_pattern_object DK_P1(OI *,oi)
{
  int back = 0;
  double w, h;	/* width and height of a pattern tile */
  char *buffer; size_t lgt; unsigned long streamlgt;
  if((oi->c)->app) {
    lgt = dksf_get_maxpathlen();
    buffer = dk_new(char, lgt);
    if(buffer) {
      if(dkapp_tmpnam((oi->c)->app, buffer, lgt)) {
        dk_stream_t *plainfile;
	oi->gcs = NULL;
	plainfile = dkapp_stream_openfile(
	  (oi->c)->app, buffer, str_open_write_binary
	);
	if(plainfile) {
	  if(((oi->c)->opt2) & DKFIG_OPT_PLAIN_TEXT_STREAMS) {
	    oi->gcs = plainfile;
	    back = create_pattern_stream(oi, &w, &h);
	  } else {
	    dk_stream_t *compressedfile;
	    compressedfile = dkof_open(plainfile, 3);
	    if(compressedfile) {
	      dkof_set_crnl(compressedfile, 1);
	      back = 1;
	      if(!dkof_set(compressedfile,0,DK_OF_TYPE_BUFFERED)) { back = 0; }
	      if(!dkof_set(compressedfile,1,DK_OF_TYPE_ASCII85)) { back = 0; }
	      if(!dkof_set(compressedfile,2,DK_OF_TYPE_FLATE)) { back = 0; }
	      if(back) {
	        back = 0;
		if(dkof_start_chunk(compressedfile)) {
		  oi->gcs = compressedfile;
		  back = create_pattern_stream(oi, &w, &h);
		  if(!dkof_end_chunk(compressedfile)) {
		    back = 0;
		    dkfig_tool2_simple_error_message(oi->c, 74);
		  }
		} else {
		  dkfig_tool2_simple_error_message(oi->c, 73);
		}
	      } else {
		dkfig_tool2_simple_error_message(oi->c, 72);
	      }
	    } else {
	      dkfig_tool2_simple_error_message(oi->c, 72);
	    }
	  }
	  streamlgt = dkstream_get_bytes_written(plainfile);
	  dkstream_close(plainfile); plainfile = NULL;
	  if(back) {
	    /* dictionary and stream */
	    back = 0;
	    if(begin_object(oi, (oi->cp)->objno)) {
	      kw_out(oi, 5); kw_out(oi, 0);
              kw_out(oi, 62); kw_out(oi, 0);
	      kw_out(oi, 63);
	      dkstream_puts_double(oi->s, w);
	      kw_out(oi, 1);
	      dkstream_puts_double(oi->s, h);
	      kw_out(oi, 25); kw_out(oi, 1);
	      kw_out(oi, 64); kw_out(oi, 1);
	      dkstream_puts_double(oi->s, w);
	      kw_out(oi, 1);
	      kw_out(oi, 65); kw_out(oi, 1);
	      dkstream_puts_double(oi->s, h);
	      kw_out(oi, 0);
	      kw_out(oi, 28); kw_out(oi, 1);
	      kw_out(oi, 5); kw_out(oi, 1);
	      kw_out(oi, 29);
	      kw_out(oi, 30);
	      kw_out(oi, 25); kw_out(oi, 1);
	      kw_out(oi, 6); kw_out(oi, 0);
	      kw_out(oi, 39); kw_out(oi, 1);
	      dkstream_puts_ul(oi->s, streamlgt);
	      if(!(((oi->c)->opt2) & DKFIG_OPT_PLAIN_TEXT_STREAMS)) {
                kw_out(oi, 1);
		kw_out(oi, 40);
	      }
	      kw_out(oi, 0);
	      kw_out(oi, 6); kw_out(oi, 0);
	      kw_out(oi, 41); kw_out(oi, 0);
	      back = copy_file_to_stream(oi, buffer, streamlgt);
	      kw_out(oi, 42); kw_out(oi, 0);
	      dksf_remove_file(buffer);
	      end_object(oi);
	    }
	  }
	} else {
	  if((oi->c)->app) {
	    dkapp_err_fopenw((oi->c)->app, buffer);
	  }
	}
	oi->gcs = NULL;
      } else {
	dkfig_tool2_simple_error_message(oi->c, 67);
      }
      dk_delete(buffer); buffer = NULL;
    } else {
      if((oi->c)->app) {
        dkapp_err_memory((oi->c)->app,sizeof(char),lgt);
      }
    }
  } else {	
    dkfig_tool2_simple_error_message(oi->c, 44);
  }
  return back;
} /* }}} */



/* {{{ write_pattern_objects - write all pattern objects to os
*/
static
int
write_pattern_objects DK_P1(OI *,oi)
{
  int back = 1;
  dkfig_pdf_pattern *patp;
  dksto_it_reset(oi->patli);
  while((patp = (dkfig_pdf_pattern *)dksto_it_next(oi->patli)) != NULL) {
    oi->cp = patp;
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, patp->lineno);
    }
    if(!write_one_pattern_object(oi)) {
      back = 0;
      dkfig_tool2_simple_error_message(oi->c, 106);
    }
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, 0UL);
    }
  }
  return back;
} /* }}} */



/* {{{ write_one_image - write one image object to os
*/
static
int write_one_image DK_P1(OI *,oi)
{
  int back = 0;
  if(begin_object(oi, (oi->ci)->objno)) {
    kw_out(oi, 5); kw_out(oi, 0);
    kw_out(oi, 90); kw_out(oi, 0);
    kw_out(oi, 91); kw_out(oi, 1);
    switch((oi->ci)->ch) {
      case 1: case 2: {
        kw_out(oi, 93);
      } break;
      default: {
        kw_out(oi, 92);
      } break;
    }
    kw_out(oi, 0);
    kw_out(oi, 94); kw_out(oi, 0);
    kw_out(oi, 40); kw_out(oi, 0);
    kw_out(oi, 95); kw_out(oi, 1);
    switch((oi->ci)->flipped) {
      case 2: {
        dkstream_puts_ul(oi->s, (oi->ci)->h);
      } break;
      default: {
        dkstream_puts_ul(oi->s, (oi->ci)->w);
      } break;
    }
    kw_out(oi, 0);
    kw_out(oi, 96); kw_out(oi, 1);
    switch((oi->ci)->flipped) {
      case 2: {
        dkstream_puts_ul(oi->s, (oi->ci)->w);
      } break;
      default: {
        dkstream_puts_ul(oi->s, (oi->ci)->h);
      } break;
    }
    kw_out(oi, 0);
    if(((oi->c)->opt2) & DKFIG_OPT_INTERPOLATE_IMAGES) {
      kw_out(oi, 97); kw_out(oi, 0);
    }
    switch((oi->ci)->ch) {
      case 2: case 4: {
        kw_out(oi, 98); kw_out(oi, 1);
	dkstream_puts_ul(oi->s, ((oi->ci)->objno + 1UL));
	kw_out(oi, 1); kw_out(oi, 99);
	kw_out(oi, 0);
      } break;
    }
    kw_out(oi, 39); kw_out(oi, 1);
    dkstream_puts_ul(oi->s, (oi->ci)->ol);
    kw_out(oi, 0);
    kw_out(oi, 6); kw_out(oi, 0);
    kw_out(oi, 41); kw_out(oi, 0);
    back = copy_file_to_stream(oi, (oi->ci)->ofn, (oi->ci)->ol);
    kw_out(oi, 42); kw_out(oi, 0);
    end_object(oi);
    if(back) {
      switch((oi->ci)->ch) {
        case 2: case 4: {
	  back = 0;
	  if(begin_object(oi, ((oi->ci)->objno + 1UL))) {
	    kw_out(oi, 5); kw_out(oi, 0);
            kw_out(oi, 100); kw_out(oi, 1);
            kw_out(oi, 90); kw_out(oi, 0);
            kw_out(oi, 91); kw_out(oi, 1);
            kw_out(oi, 93); kw_out(oi, 0);
            kw_out(oi, 94); kw_out(oi, 0);
            kw_out(oi, 40); kw_out(oi, 0);
            kw_out(oi, 95); kw_out(oi, 1);
            switch((oi->ci)->flipped) {
              case 2: {
                dkstream_puts_ul(oi->s, (oi->ci)->h);
              } break;
              default: {
                dkstream_puts_ul(oi->s, (oi->ci)->w);
              } break;
            }
            kw_out(oi, 0);
            kw_out(oi, 96); kw_out(oi, 1);
            switch((oi->ci)->flipped) {
              case 2: {
                dkstream_puts_ul(oi->s, (oi->ci)->w);
              } break;
              default: {
                dkstream_puts_ul(oi->s, (oi->ci)->h);
              } break;
            }
            kw_out(oi, 0);
            /*
            if(((oi->c)->opt2) & DKFIG_OPT_INTERPOLATE_IMAGES) {
              kw_out(oi, 97); kw_out(oi, 0);
            }
            */
            kw_out(oi, 39); kw_out(oi, 1);
            dkstream_puts_ul(oi->s, (oi->ci)->al);
            kw_out(oi, 0);
	    kw_out(oi, 6); kw_out(oi, 0);
	    kw_out(oi, 41); kw_out(oi, 0);
	    back = copy_file_to_stream(oi, (oi->ci)->afn, (oi->ci)->al);
	    kw_out(oi, 42); kw_out(oi, 0);
	    end_object(oi);
	  }
	} break;
      }
    }
  }
  return back;
} /* }}} */



/* {{{ write_image_objects - write all image objects to os
*/
static
int write_image_objects DK_P1(OI *,oi)
{
  int back = 1;
  dkfig_pdf_image *pi;
  dksto_it_reset(oi->imgli);
  while((pi = (dkfig_pdf_image *)dksto_it_next(oi->imgli)) != NULL) {
    oi->ci = pi;
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, pi->lineno);
    }
    if(!write_one_image(oi)) {
      back = 0;
      dkfig_tool2_combined_error_message(oi->c, 107, 108, (oi->ci)->inputfilename);
    }
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, 0UL);
    }
    oi->ci = NULL;
  }
  return back;
} /* }}} */



static
void media_crop_box DK_P2(OI *,oi, int,kwno)
{
	  kw_out(oi, kwno);
	  dkstream_puts_double(oi->s, 0.0);
	  kw_out(oi, 1);
	  dkstream_puts_double(oi->s, 0.0);
	  kw_out(oi, 1);
	  dkstream_puts_double(oi->s, oi->xright);
	  kw_out(oi, 1);
	  dkstream_puts_double(oi->s, oi->ytop);
	  kw_out(oi, 25); kw_out(oi, 0);
}



/* {{{ output_pass - produce PDF output
*/
static
int output_pass DK_P1(OI *,oi)
{
  int back = 1;
  
  kw_out(oi, 2); kw_out(oi, 0);
  dkfig_tool2_simple_progress_message(oi->c, 99);
  if(begin_object(oi, 1UL)) {
    kw_out(oi, 5); kw_out(oi, 1);
    kw_out(oi, 20); kw_out(oi, 1);
    kw_out(oi, 6); kw_out(oi, 0);
    end_object(oi);
    if(begin_object(oi, 2UL)) {
      kw_out(oi, 5); kw_out(oi, 1);
      kw_out(oi, 21);
      if(((oi->c)->opt2) & DKFIG_OPT_FULL_SCREEN) {
        kw_out(oi, 43);
      }
      kw_out(oi, 1); kw_out(oi, 6); kw_out(oi, 0);
      end_object(oi);
      if(begin_object(oi, 3UL)) {
        kw_out(oi, 5); kw_out(oi, 1);
	kw_out(oi, 22);
	kw_out(oi, 1); kw_out(oi, 6); kw_out(oi, 0);
        end_object(oi);
	if(begin_object(oi, 4UL)) {
	  kw_out(oi, 5); kw_out(oi, 0);
	  kw_out(oi, 23); kw_out(oi, 0);
	  kw_out(oi, 27); kw_out(oi, 0);
	  media_crop_box(oi, 24);
	  media_crop_box(oi, 102);
	  kw_out(oi, 36); kw_out(oi, 0);
	  kw_out(oi, 26); kw_out(oi, 0);
	  kw_out(oi, 28); kw_out(oi, 1); kw_out(oi, 5); kw_out(oi, 0);
	  kw_out(oi, 29); 
	  kw_out(oi, 30);
	  if((oi->procs) & DKFIG_PDF_PROCSET_TEXT) {
	    kw_out(oi, 1); kw_out(oi, 54);
	  }
	  if((oi->procs) & DKFIG_PDF_PROCSET_IMGG) {
	    kw_out(oi, 1); kw_out(oi, 58);
	  }
	  if((oi->procs) & DKFIG_PDF_PROCSET_IMGC) {
	    kw_out(oi, 1); kw_out(oi, 59);
	  }
	  kw_out(oi, 25); kw_out(oi, 0);
	  write_fonts(oi);
	  write_patterns(oi);
	  write_images(oi);
	  kw_out(oi, 6); kw_out(oi, 0);
	  kw_out(oi, 6); kw_out(oi, 0);
	  end_object(oi);
	  if(begin_object(oi, 5UL)) {
	    /* oi->no = 6UL; */
	    dkfig_tool2_simple_progress_message(oi->c, 100);
	    back = write_graphics_stream(oi);
	    end_object(oi);
	    if(back) {
	      dkfig_tool2_simple_progress_message(oi->c, 101);
	      back = write_font_objects(oi);
	      if(back) {
	        dkfig_tool2_simple_progress_message(oi->c, 102);
	        back = write_pattern_objects(oi);
		if(back) {
		  dkfig_tool2_simple_progress_message(oi->c, 103);
		  back = write_image_objects(oi);
		}
	      }
	    }
	  }
	}
      }
    }
  }
  if(back) {
    back = finalize_pdf(oi);
  } 
  return back;
} /* }}} */



/* {{{ cleanup_pass - release collected style information...
*/
static
void cleanup_pass DK_P1(OI *,oi)
{
  dk_fig_object *o;
  dkfig_pdf_pattern *patp;
  
  if((oi->fl) && (oi->fli)) {
    dksto_it_reset(oi->fli);
    while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) {
      if(o->drve) {
        delete_drve((dkfig_pdf_drve_text *)(o->drve));
	o->drve = NULL;
      }
    }
    dksto_it_close(oi->fli);
  }
  if(oi->fl) {
    dksto_close(oi->fl);
  }
  oi->fl = NULL; oi->fli = NULL;
  if((oi->patl) && (oi->patli)) {
    dksto_it_reset(oi->patli);
    while((patp = (dkfig_pdf_pattern *)dksto_it_next(oi->patli)) != NULL) {
      
      dk_delete(patp);
    }
    dksto_it_close(oi->patli);
  }
  if(oi->patl) {
    dksto_close(oi->patl);
  }
  oi->patl = NULL; oi->patli = NULL;
  if((oi->imgl) && (oi->imgli)) {
    dkfig_pdf_image *i;
    dksto_it_reset(oi->imgli);
    while((i = (dkfig_pdf_image *)dksto_it_next(oi->imgli)) != NULL) {
      delete_image(i);
    }
    dksto_it_close(oi->imgli);
  }
  if(oi->imgl) {
    dksto_close(oi->imgl);
  }
  oi->imgl = NULL; oi->imgli = NULL;
  if((oi->pdfo) && (oi->pdfoi)) {
    OPOS *p;
    dksto_it_reset(oi->pdfoi);
    /* free all object position structures */
    while((p = (OPOS *)dksto_it_next(oi->pdfoi)) != NULL) {
      dk_delete(p);
    }
    dksto_it_close(oi->pdfoi);
  }
  if(oi->pdfo) {
    dksto_close(oi->pdfo);
  }
  oi->pdfo = NULL; oi->pdfoi = NULL;
  
} /* }}} */



/* {{{ dkfig_output_pdf - output driver function
*/
int
dkfig_output_pdf DK_P1(dk_fig_conversion *,c)
{
  int back = 0, i;
  unsigned long fonts_used[14];
  OI oi;
  null_oi(&oi);
  oi.fu = fonts_used;
  for(i = 0; i < 14; i++) { fonts_used[i] = 0UL; }
  if(c) {
    if(c->app) {
      dkapp_set_source_lineno(c->app, 0UL);
    }
    oi.c = c;
    if(c->ostrm) {
      oi.s = c->ostrm;
      if(c->drwng) {
        dk_fig_object *o;
	o = c->drwng;
	oi.d = (dk_fig_drawing *)(o->data);
	/* Progress: Gathering information */
	dkfig_tool2_msg1(c, DK_LOG_LEVEL_PROGRESS, 121);
	if(preparation_pass(&oi)) {
          dkfig_tool2_report_unused_options(c);
	  /*  Progress: Starting output */
	  if(c->msg1) {
	    dkfig_tool2_msg3(
	      c, DK_LOG_LEVEL_PROGRESS, 20, 21,
	      ((c->ofn2) ? (c->ofn2) : ((c->msg1)[122]))
	    );
	  }
	  back = output_pass(&oi);
	  /* Progress: finished output */
	  dkfig_tool2_msg1(c, DK_LOG_LEVEL_PROGRESS, 22);
	}
	cleanup_pass(&oi);
      }
    }
  }
  return back;
} /* }}} */




/* {{{ SCCS ID */
#ifndef LINT
static char sccs_id[] = {
"@(#)dkfigpdf.ctr 1.31 05/29/07\t(krause) - fig2vect"
};
#endif
/* }}} */
