/*
Copyright (c) 2004-2010, 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
  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.
*/



/**	@file	dkfigeps.c	EPS output driver module.
*/


/**	Inside the dkfigeps module.
*/
#define DKFIGEPS_C 1



#include "dkfig.h"




#line 54 "dkfigeps.ctr"




/**	Restrict number of digits after decimal dot.
*/
#define drd(v,o,w) dkfig_tool2_drd(v,o,w)



/**	Pattern data.
*/
typedef struct {
  char *name;		/**< Pattern name. */
  char *filename;	/**< Pattern file name. */
  char *version;	/**< Pattern version. */
  char *revision;	/**< Pattern revision. */
} pattern_data;
 


/** Flag: Font must be re-encoded.
*/
#define OI_FLAG_FONT_RE_ENCODING	0x0001

/** Flag: Document setup.
*/
#define OI_FLAG_DOCUMENT_SETUP		0x0002

/** Flag: Aligned text.
*/
#define OI_FLAG_ALIGNED_TEXT		0x0004

/** Flag: Color known.
*/
#define HAVE_COLOR			0x0001

/** Flag: Linewidth known.
*/
#define HAVE_LINEWIDTH			0x0002

/** Flag: Linecap known.
*/
#define HAVE_LINECAP			0x0004

/** Flag: Linejoin known.
*/
#define HAVE_LINEJOIN			0x0008

/** Flag: Dash pattern known.
*/
#define HAVE_DASH			0x0010

/** Flag: PS font name known.
*/
#define HAVE_PSFONT			0x0020



/** File name: Font re-encoding procedure for PS level 2 and above.
    Usage "/Times-Roman /IsoLatin1-Times-Roman FontReEncode"
*/
static char new_fre_proc_file[] = { "f2vfre2.ps" };

/** File name: Font re-encoding procecure for PS level 1.
*/
static char old_fre_proc_file[] = { "f2vfre1.ps" };

/** File name: Procset for aligned text.
*/
static char f2v_aligned_text_procset[] = { "f2vtal.ps" };



/**	String pointer.
*/
typedef char *PCHAR;



/**   keywords for EPS output.
*/
static char *kw[] = {
/*   0 */ "\r\n",
/*   1 */ " ",
/*   2 */ "%!PS-Adobe-",
/*   3 */ ".0 EPSF-",
/*   4 */ ".0",
/*   5 */ "%%BoundingBox:",
/*   6 */ "%%Title: ",
/*   7 */ "%%Creator: fig2vect, see http://dktools.sourceforge.net/fig2vect.html",
/*   8 */ "%%Pages: 1",
/*   9 */ "%%PageOrder: Ascend",
/*  10 */ "%%EndComments",
/*  11 */ "%%DocumentData: Clean7Bit",
/*  12 */ "%%DocumentNeededFonts: ",
/*  13 */ "%%DocumentNeededResources: ",
/*  14 */ "font ",
/*  15 */ "%%+ ",
/*  16 */ "%%BeginProlog",
/*  17 */ "%%EndProlog",
/*  18 */ "%%BeginProcSet: ",
/*  19 */ "%%EndProcSet",
/*  20 */ "%%BeginResource: ",
/*  21 */ "%%EndResource",
/*  22 */ "fig2vect-fre",
/*  23 */ "1.0",
/*  24 */ "1",
/*  25 */ "2.0",
/*  26 */ "2",
/*  27 */ "%%BeginSetup",
/*  28 */ "%%EndSetup",
/*  29 */ "/",
/*  30 */ "DocFont",
/*  31 */ "def",
/*  32 */ "FontReEncode",
/*  33 */ "%%Page: 1 1",
/*  34 */ "%%Trailer",
/*  35 */ "%%EOF",
/*  36 */ "showpage",
/*  37 */ "%",
/*  38 */ "setrgbcolor",
/*  39 */ "setlinewidth",
/*  40 */ "setlinecap",
/*  41 */ "setlinejoin",
/*  42 */ "fill",
/*  43 */ "stroke",
/*  44 */ "gsave",
/*  45 */ "grestore",
/*  46 */ "newpath",
/*  47 */ "closepath",
/*  48 */ "moveto",
/*  49 */ "lineto",
/*  50 */ "-90",
/*  51 */ "0",
/*  52 */ "90",
/*  53 */ "180",
/*  54 */ "270",
/*  55 */ "arc",
/*  56 */ "curveto",
/*  57 */ "translate",
/*  58 */ "scale",
/*  59 */ "rotate",
/*  60 */ "setdash",
/*  61 */ "[",
/*  62 */ "]",
/*  63 */ "clip",
/*  64 */ "findfont",
/*  65 */ "scalefont",
/*  66 */ "setfont",
/*  67 */ "f2vtal",
/*  68 */ "show",
/*  69 */ "TextAlignedRight",
/*  70 */ "TextAlignedCentered",
/*  71 */ "(",
/*  72 */ ")",
/*  73 */ "\\",
/*  74 */ "matrix currentmatrix",
/*  75 */ "setmatrix",
/*  76 */ "f2vpat",
/*  77 */ "imgstr",
/*  78 */ "string",
/*  79 */ "image",
/*  80 */ "colorimage",
/*  81 */ "{",
/*  82 */ "}",
/*  83 */ "currentfile",
/*  84 */ "readhexstring",
/*  85 */ "readstring",
/*  86 */ "pop",
/*  87 */ "/ASCII85Decode filter",
/*  88 */ "/FlateDecode filter",
/*  89 */ "/RunLengthDecode filter",
/*  90 */ "false",
/*  91 */ "-",
/*  92 */ "inputf",
/*  93 */ "true",
/*  94 */ "A",
/*  95 */ "B",
/*  96 */ "C",
/*  97 */ "eps",
/*  98 */ "dict",
/*  99 */ "begin",
/* 100 */ "end",
/* 101 */ "1 vmreclaim",
/* 102 */ "currentdict",
/* 103 */ "undef",
/* 104 */ "%%BeginDocument: ",
/* 105 */ "%%EndDocument",
/* 106 */ "%",
/* 107 */ "\\begin{picture}",
/* 108 */ "(0,0)",
/* 109 */ "\\end{picture}%",
/* 110 */ "% ----- Change the file name in the next line -----",
/* 111 */ "\\includegraphics{",
/* 112 */ "inputfile",
/* 113 */ "\\setlength{\\unitlength}{1bp}%",
/* 114 */ ",",
/* 115 */ "\\put",
/* 116 */ "\\makebox",
/* 117 */ "\\smash",
/* 118 */ "\\rotatebox",
/* 119 */ "b",
/* 120 */ "rb",
/* 121 */ "lb",
/* 122 */ "\\color[rgb]",
/* 123 */ "\\mbox",
/* 124 */ "\\setlength{",
/* 125 */ "\\paperwidth",
/* 126 */ "\\paperheight",
/* 127 */ "bp",
/* 128 */ "\n",
/* 129 */ "\\usepackage{graphicx}",
/* 130 */ "\\usepackage{color}",
/* 131 */ "\\usepackage{ifpdf}",
/* 132 */ "\\begin{document}%",
/* 133 */ "\\end{document}",
/* 134 */ "\\pagestyle{empty}",
/* 135 */ "\\setlength{\\voffset}{-1in}",
/* 136 */ "\\setlength{\\topmargin}{0mm}",
/* 137 */ "\\setlength{\\headheight}{0mm}",
/* 138 */ "\\setlength{\\headsep}{0mm}",
/* 139 */ "\\setlength{\\topskip}{0mm}",
/* 140 */ "\\setlength{\\hoffset}{-1in}",
/* 141 */ "\\setlength{\\oddsidemargin}{0mm}",
/* 142 */ "\\setlength{\\evensidemargin}{0mm}",
/* 143 */ "\\setlength{\\marginparwidth}{0mm}",
/* 144 */ "\\setlength{\\marginparsep}{0mm}",
/* 145 */ "\\setlength{\\textwidth}{\\paperwidth}",
/* 146 */ "\\setlength{\\textheight}{\\paperheight}",
/* 147 */ "\\setlength{\\parskip}{0mm}",
/* 148 */ "\\setlength{\\parindent}{0mm}",
/* 149 */ "\\ifpdf",
/* 150 */ "\\setlength{\\pdfpagewidth}{\\paperwidth}",
/* 151 */ "\\setlength{\\pdfpageheight}{\\paperheight}",
/* 152 */ "\\fi",
/* 153 */ "<<",
/* 154 */ ">>",
/* 155 */ "setpagedevice",
/* 156 */ "/PageSize",
/* 157 */
"\\ifpdf\\pdfpageattr{/Group <</S /Transparency /I true /CS /DeviceRGB>>}\\fi",
/* 158 */ "setgray",
/* 159 */ "\\color[gray]",
};

/** Number of elements in the kw array.
*/
static size_t nkw = sizeof(kw)/sizeof(PCHAR);




/** File open mode: Read binary.
*/
static char str_open_rb[] = { "rb" };

/** File open mode: Read.
*/
static char str_open_read[] = { "r" };

/** Pattern version.
*/
static char apv[] = { "1.0" };

/** Pattern revision.
*/
static char apr[] = { "1" };



/** List of patterns used in Fig files.
    For each pattern there is a pattern name, a file name for the pattern
    procedure, pattern version and revision.
*/
static pattern_data pd[] = {
  { (char *)"ThirtyLeft",		(char *)"f2vpat00.ps", apv, apr },
  { (char *)"ThirtyRight",		(char *)"f2vpat01.ps", apv, apr },
  { (char *)"ThirtyHatch",		(char *)"f2vpat02.ps", apv, apr },
  { (char *)"FourtyFiveLeft",		(char *)"f2vpat03.ps", apv, apr },
  { (char *)"FourtyFiveRight",		(char *)"f2vpat04.ps", apv, apr },
  { (char *)"FourtyFiveHatch",		(char *)"f2vpat05.ps", apv, apr },
  { (char *)"HorizontalBricks",		(char *)"f2vpat06.ps", apv, apr },
  { (char *)"VerticalBricks",		(char *)"f2vpat07.ps", apv, apr },
  { (char *)"HorizontalLines",		(char *)"f2vpat08.ps", apv, apr },
  { (char *)"VerticalLines",		(char *)"f2vpat09.ps", apv, apr },
  { (char *)"CrossHatch",		(char *)"f2vpat10.ps", apv, apr },
  { (char *)"HorizontalShinglesLeft",	(char *)"f2vpat11.ps", apv, apr },
  { (char *)"HorizontalShinglesRight",	(char *)"f2vpat12.ps", apv, apr },
  { (char *)"VerticalShinglesLeft",	(char *)"f2vpat13.ps", apv, apr },
  { (char *)"VerticalShinglesRight",	(char *)"f2vpat14.ps", apv, apr },
  { (char *)"FishScales",		(char *)"f2vpat15.ps", apv, apr },
  { (char *)"SmallFishScales",		(char *)"f2vpat16.ps", apv, apr },
  { (char *)"Circles",			(char *)"f2vpat17.ps", apv, apr },
  { (char *)"Hexagons",			(char *)"f2vpat18.ps", apv, apr },
  { (char *)"Octagons",			(char *)"f2vpat19.ps", apv, apr },
  { (char *)"HorizontalTireTreads",	(char *)"f2vpat20.ps", apv, apr },
  { (char *)"VerticalTireTreads",	(char *)"f2vpat21.ps", apv, apr }
};



#if DK_HAVE_ZLIB_H
#if DK_HAVE_PNG_H
/**	File name suffix for PNG files.
*/
static char str_suffix_png[] = { "PNG" };
#endif
#endif


/**	Initialize dkfig_eps_output_instruction.
	@param	oi	EPS output instruction structure.
*/
static
void
null_oi DK_P1(dkfig_eps_output_instruction *,oi)
{
  oi->c = NULL;
  oi->d = NULL;
  oi->s = NULL;
  oi->dro = NULL;
  oi->fl = NULL;
  oi->fli = NULL;
  oi->iw = NULL;
  oi->iwi = NULL;
  oi->fdvi = NULL;
  oi->fps = NULL;
  oi->fnused = NULL;
  oi->xfactor = 0.06; oi->yfactor = 0.06;
  oi->xshift  = 0.0;  oi->yshift  = 0.0;
  oi->xleft = oi->xright = oi->ybottom = oi->ytop = 0.0;
  oi->flags = 0;
  oi->o = NULL;
  oi->me = 0;
  oi->have = HAVE_DASH;
  oi->lw = 0.0;
  oi->lc = 0;
  oi->lj = 0;
  oi->a = NULL;
  oi->ls = 0;
  oi->sv = 0.0;
  oi->psfont = 0;
  oi->psfsize = 0.0;
  oi->numimw = 0UL;
  oi->allimw = 0;
  oi->spcpass = 0;
  oi->errprinted = 0;
  oi->skip_images = 0;
}



/**	Put unsigned long to stream.
	@param	s	Stream to write to.
	@param	ul	The value to write.
*/
static
void
stream_putul DK_P2(dk_stream_t *,s, unsigned long, ul)
{
  char buffer[64];
#if DK_HAVE_SNPRINTF
  snprintf(buffer, sizeof(buffer), "%lu", ul);
  buffer[sizeof(buffer)-1] = '\0';
#else
  sprintf(buffer, "%lu", ul);
#endif
  dkstream_puts(s, buffer);
}



/**	Put double to stream.
	@param	s	Stream to write to.
	@param	d	The value to write.
	@param	c	Conversion job structure.
	@param	w	Number of digits after decimal dot.
*/
static
void
stream_putdouble DK_P4(dk_stream_t *,s, double,d, dk_fig_conversion *,c, int,w)
{
  double x;
  /* x = dkma_double_restrict_digits(d, 7); */
  x = drd(d,c,w);
  dkstream_puts_double(s, x);
}



/**	Write keyword to output stream.
	@param	s	Stream to write to.
	@param	i	Index of keyword to write.
*/
static
void
kw_out DK_P2(dk_stream_t *,s, size_t,i)
{
  if(s && (i < nkw)) {
    dkstream_puts(s, kw[i]);
  }
}



/**	Corect one color value for a web-optimized palette.
	@param	d	Color value (input/output, 0 -- 1).
	@param	i	Integer color value (output, 0 -- 255).

*/
static
void
correct_color_for_palette DK_P2(double *,d, int *,i)
{
  double x;
  x = 256.0 * (*d);
  x = floor(x);
  *i = (int)dkma_double_to_l(x);
  if(*i > 255) { *i = 255; }
  *d = x / 256.0;
}



/**	Correct a color cell for using a web optimized
	color palette.
	@param	dcc	Color cell to correct.
*/
void
dkfig_eps_correct_for_palette DK_P1(dk_fig_dcc *,dcc)
{
  correct_color_for_palette(&(dcc->red), &(dcc->ired));
  correct_color_for_palette(&(dcc->green), &(dcc->igreen));
  correct_color_for_palette(&(dcc->blue), &(dcc->iblue));
}



/**	Check whether or not two double values are nearly equal.
	@param	d1	One double value.
	@param	d2	Other double value.
	@return	1 for equal, 0 for unequal.

*/
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;
}



/**	Print name of re-encoded font.
	@param	oi	EPS output instruction structure.
	@param	i	Index of PS font.
*/
static
void
ps_my_font_name DK_P2( dkfig_eps_output_instruction *,oi, unsigned,i)
{
  kw_out(oi->s, 30);
  dkfig_tool_num_as_string(oi->s, i, 2);
}



/**	Set font, scale, etc.
	@param	oi	EPS output instruction structure.
	@param	fontno	Index of PS font.
	@param	sz	Font size.
*/
static
void
set_psfont DK_P3(dkfig_eps_output_instruction *,oi, unsigned,fontno, double,sz)
{
  int must_set = 1;
  if((oi->have) & HAVE_PSFONT) {
    if(oi->psfont == fontno) {
      if(double_nearly_equal(oi->psfsize, sz)) {
        must_set = 0;
      }
    }
  }
  if(must_set) {
    kw_out(oi->s, 29);
    ps_my_font_name(oi, fontno);
    kw_out(oi->s, 1);
    kw_out(oi->s, 64); kw_out(oi->s, 1);
    stream_putdouble(
      oi->s,
      dkma_mul_double_ok(sz, (oi->c)->fsf, &(oi->me)),
      oi->c, 1
    );
    kw_out(oi->s, 1);
    kw_out(oi->s, 65); kw_out(oi->s, 1);
    kw_out(oi->s, 66); kw_out(oi->s, 0);
  }
}



/**	Set dash pattern.
	@param	oi	EPS output instruction structure.
	@param	ls	Dash line style.
	@param	sv	Dash unit length.
*/
static void
set_dash DK_P3(dkfig_eps_output_instruction *,oi, int,ls, double,sv)
{
  int must_set = 1;
  int xls;
  double dist, dashgap;
  dist = 0.9 * sv;
  dashgap = 0.1;
  if((oi->have) & HAVE_LINEWIDTH) {
    if(dashgap > (0.1 * oi->lw)) {
      dashgap = 0.1 * oi->lw;
    }
  }
  if(((oi->c)->opt1) & DKFIG_OPT_DP_DOT_LW) {
    dashgap = oi->lw;
  }
  xls = ls; if(xls == -1) { xls = 0; }
  if((oi->have) & HAVE_DASH) {
    if(oi->ls == xls) {
      if(xls == 0) {
        must_set = 0;
      } else {
        if(double_nearly_equal(oi->sv, sv)) {
	  must_set = 0;
	}
      }
    }
  }
  if(must_set) {
    switch(xls) {
      case 1: {
        kw_out(oi->s, 61);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 62);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, 0.0, oi->c, 1);
      } break;
      case 2: {
        kw_out(oi->s, 61);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 62);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, 0.0, oi->c, 1);
      } break;
      case 3: {
        kw_out(oi->s, 61);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 62);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, 0.0, oi->c, 1);
      } break;
      case 4: {
        kw_out(oi->s, 61);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 62);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, 0.0, oi->c, 1);
      } break;
      case 5: {
        kw_out(oi->s, 61);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dashgap, oi->c, 1);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, dist, oi->c, 1);
	kw_out(oi->s, 62);
	kw_out(oi->s, 1);
	stream_putdouble(oi->s, 0.0, oi->c, 1);
      } break;
      default: {
        kw_out(oi->s, 61); kw_out(oi->s, 62);
	kw_out(oi->s, 1); kw_out(oi->s, 51);
      } break;
    }
    kw_out(oi->s, 1); kw_out(oi->s, 60); kw_out(oi->s, 0);
    oi->have |= HAVE_DASH;
    oi->ls = xls; oi->sv = sv;
    if(oi->ls == -1) { oi->ls = 0; }
  }
}



/**	Set linecap.
	@param	oi	EPS output instruction structure.
	@param	lc	Linecap.
*/
static
void
set_linecap DK_P2(dkfig_eps_output_instruction *,oi, int,lc)
{
  int must_set = 1;
  if((oi->have) & HAVE_LINECAP) {
    if(oi->lc == lc) {
      must_set = 0;
    }
  }
  if(must_set) {
    stream_putul(oi->s, (unsigned long)lc);
    kw_out(oi->s, 1); kw_out(oi->s, 40); kw_out(oi->s, 0);
    oi->have |= HAVE_LINECAP;
    oi->lc = lc;
  }
}



/**	Set linejoin.
	@param	oi	EPS output instruction structure.
	@param	lj	Linejoin.
*/
static
void
set_linejoin DK_P2(dkfig_eps_output_instruction *,oi, int,lj)
{
  int must_set = 1;
  if((oi->have) & HAVE_LINEJOIN) {
    if(oi->lj == lj) {
      must_set = 0;
    }
  }
  if(must_set) {
    stream_putul(oi->s, (unsigned long)lj);
    kw_out(oi->s, 1); kw_out(oi->s, 41); kw_out(oi->s, 0);
    oi->have |= HAVE_LINEJOIN;
    oi->lj = lj;
  }
}



/**	Set linewidth.
	@param	oi	EPS output instruction structure.
	@param	lw	Linewidth.
*/
static
void
set_linewidth DK_P2(dkfig_eps_output_instruction *,oi, double,lw)
{
  int must_set = 1;
  if((oi->have) & HAVE_LINEWIDTH) {
    if(double_nearly_equal(oi->lw, lw)) {
      must_set = 0;
    }
  }
  if(must_set) {
    stream_putdouble(oi->s, lw, oi->c, 1);
    kw_out(oi->s, 1); kw_out(oi->s, 39); kw_out(oi->s, 0);
    oi->have |= HAVE_LINEWIDTH;
    oi->lw = lw;
  }
}



/**	Set color.
	@param	oi	EPS output instruction structure.
	@param	dcc	Color cell containing the new color.
*/
static
void
set_color DK_P2(dkfig_eps_output_instruction *,oi, dk_fig_dcc *,dcc)
{
  int must_set = 1;
  int use_color = 1;
  double g;
  if((oi->have) & HAVE_COLOR) {
    if(double_nearly_equal((oi->dcc).red, dcc->red)) {
    if(double_nearly_equal((oi->dcc).green, dcc->green)) {
    if(double_nearly_equal((oi->dcc).blue, dcc->blue)) {
      must_set = 0;
    } } }
  }
  if(must_set) {
    if(oi->c) {
      if(!(((oi->c)->opt2) & DKFIG_OPT_COLOR)) {
        use_color = 0;
      }
    }
    (oi->dcc).red = dcc->red;
    (oi->dcc).green = dcc->green;
    (oi->dcc).blue = dcc->blue;
    oi->have |= HAVE_COLOR;
    if(use_color) {
      stream_putdouble(oi->s, dcc->red, oi->c, 0);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, dcc->green, oi->c, 0);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, dcc->blue, oi->c, 0);
      kw_out(oi->s, 1);
      kw_out(oi->s, 38);
      kw_out(oi->s, 0);
    } else {
      g = 0.3 * dcc->red + 0.59 * dcc->green + 0.11 * dcc->blue;
      stream_putdouble(oi->s, g, oi->c, 0);
      kw_out(oi->s, 1);
      kw_out(oi->s, 158);
      kw_out(oi->s, 0);
    }
  }
}



/**	Convert double y coordinate.
	@param	oi	EPS output instruction structure.
	@param	y	Original y value (Fig units).
	@return	Converted y value (PS points).
*/
static
double
ccdy DK_P2(dkfig_eps_output_instruction *,oi, double,y)
{
  double back;
  back = dkma_add_double_ok(
    dkma_mul_double_ok(oi->yfactor, y, &(oi->me)),
    oi->yshift,
    &(oi->me)
  );
  return back;
}



/**	Convert double x coordinate.
	@param	oi	EPS output instruction structure.
	@param	x	Original x value (Fig units).
	@return	Converted x value (PS points).
*/
static double
ccdx DK_P2(dkfig_eps_output_instruction *,oi, double,x)
{
  double back;
  back = dkma_add_double_ok(
    dkma_mul_double_ok(oi->xfactor, x, &(oi->me)),
    oi->xshift,
    &(oi->me)
  );
  return back;
}



/**	Convert double distance.
	@param	oi	EPS output instruction structure.
	@param	d	Original distance (Fig units).
	@return	Converted distance (PS points).
*/
static double
ccdd DK_P2(dkfig_eps_output_instruction *,oi, double,d)
{
  double back;
  back = dkma_mul_double_ok(oi->xfactor, d, &(oi->me));
  return back;
}



/**	Convert long x coordinate.
	@param	oi	EPS output instruction structure.
	@param	x	Original x value (Fig units).
	@return	Converted x value (PS points).
*/
static double
cclx DK_P2(dkfig_eps_output_instruction *,oi, long,x)
{
  double back;
  back = ccdx(oi, dkma_l_to_double(x));
  return back;
}



/**	Convert long y coordinate.
	@param	oi	EPS output instruction structure.
	@param	y	Original y value (Fig units).
	@return	Converted y value (PS points).
*/
static double
ccly DK_P2(dkfig_eps_output_instruction *,oi, long,y)
{
  double back;
  back = ccdy(oi, dkma_l_to_double(y));
  return back;
}



/**	Print double x coordinate.
	@param	oi	EPS output instruction structure.
	@param	x	Value to print.
	@param	w	Number of digits after decimal dot.
*/
static void
xout DK_P3(dkfig_eps_output_instruction *,oi, double,x, int,w)
{
  stream_putdouble(oi->s, ccdx(oi,x), oi->c, w);
}



/**	Get linewidth for object.
	@param	oi	EPS output instruction set.
	@param	ispat	Flag: Is pattern.
	@return	Linewidth.
*/
static double
get_object_linewidth DK_P2(dkfig_eps_output_instruction *,oi, int,ispat)
{
  double back = 0.0;
  back = dkma_mul_double_ok(
    dkma_l_to_double(((oi->o)->fpd).lt),
    0.9,
    &(oi->me)
  );
  if(ispat) {
    if(!(((oi->o)->fpd).lt)) {
      back = 0.9;
    }
    back = 0.9;
  }
  if(((oi->c)->opt1) & DKFIG_OPT_ENLIGHTEN_LOOK) {
    back = 0.5 * back;
  }
  return back;
}



/**	Print y coordinate.
	@param	oi	EPS output instruction structure.
	@param	y	Coordinate value.
	@param	w	Number of digits after decimal dot.
*/
static void
yout DK_P3(dkfig_eps_output_instruction *,oi, double,y, int,w)
{
  stream_putdouble(oi->s, ccdy(oi,y), oi->c, w);
}



/**	Print point coordinates.
	@param	oi	EPS output instruction structure.
	@param	x	X coordiate.
	@param	y	Y coordinate.
	@param	w	Number of digits after decimal dot.
*/
static void
dpointout DK_P4(dkfig_eps_output_instruction *,oi, double,x, double,y, int,w)
{
  xout(oi, x, w);
  kw_out(oi->s, 1);
  yout(oi, y, w);
  kw_out(oi->s, 1);
}



/**	Print point coordinates without conversion.
	@param	oi	EPS output instruction structure.
	@param	x	X value.
	@param	y	Y value.
	@param	w	Number of digits after decimal dot.
*/
static void
ncdpointout DK_P4(dkfig_eps_output_instruction *,oi, double,x, double,y, int,w)
{
  stream_putdouble(oi->s, x, oi->c, w);
  kw_out(oi->s, 1);
  stream_putdouble(oi->s, y, oi->c, w);
  kw_out(oi->s, 1);
}



/**	Print long point coordinates.
	@param	oi	EPS output instruction structure.
	@param	x	X value.
	@param	y	Y value.
	@param	w	Number of digits after decimal dot.
*/
static void
lpointout DK_P4(dkfig_eps_output_instruction *,oi, long,x, long,y, int,w)
{
  dpointout(oi, dkma_l_to_double(x), dkma_l_to_double(y), w);
}



/**	Mark pattern as used.
	@param	pu	Flag array: Pattern used or unused.
	@param	o	Fig object structure.
*/
static void
register_pattern DK_P2(int *,pu, dk_fig_object *,o)
{
  int i;
  
  i = (o->fpd).af;
  if(i > 40) {
    if(i < 63) {
      pu[i - 41] = 1;
    }
  }
  
}



/**	Handle special comments.
	@param	oi	EPS output instruction structure.
	@param	o	Fig object.
*/
static void
handle_special_comments DK_P2(dkfig_eps_output_instruction *,oi, dk_fig_object *,o)
{
    int i;
    if((o->osc) && (o->osci)) {
      dk_fig_opt *speccom;
      
      dksto_it_reset(o->osci);
      while((speccom = (dk_fig_opt *)dksto_it_next(o->osci)) != NULL) {
        
        i = dkfig_opt_process_special_comment(
	  oi->c, speccom->name, kw[97], 0
	);
	if((oi->spcpass) == 0) {
	  dkfig_tool2_report_special_comment(oi->c, speccom, i);
	}
      }
    }
}



/**	Gather information (which fonts are used etc)
   	and run LaTeX/TeX and dvips if required.
	@param	oi	EPS output instruction structure.
*/
static int
gather_information_and_run_latex DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1; int oldback;
  int must_run_latex = 0;
  dk_fig_object *o;
  dk_fig_text   *t;
  unsigned long backupopt1, backupopt2;
  int backupia;
  dk_fig_polyline *p;
  
  dksto_it_reset(oi->fli);
  while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) {
    /* DK_MEMCPY(&backupc,oi->c,sizeof(dk_fig_conversion)) ; */
    backupopt1 = (oi->c)->opt1;
    backupopt2 = (oi->c)->opt2;
    backupia = (oi->c)->image_align;
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, o->lineno);
    }
    handle_special_comments(oi,o);
    switch(o->objtype) {
      case DK_FIG_OBJ_TEXT: {
        
        t = (dk_fig_text *)(o->data);
	if(t) {
	  if(t->font_handling) {
	    switch((t->font_handling)->handling) {
	      case 2: case 3: case 4: case 5: {
	        
	        must_run_latex = 1;
	      } break;
	      default: {
	        
	        if(((t->font_handling)->fontno) >= 0) {
	          if(((t->font_handling)->fontno) < 35) {
		    (oi->fnused)[(t->font_handling)->fontno] = 1;
		    
		  }
		}
		if((o->subtype) > 0) {
		  
		  oi->flags |= OI_FLAG_ALIGNED_TEXT;
		}
		if((o->fpd).st > 0) {
		  
		  oi->flags |= OI_FLAG_ALIGNED_TEXT;
		}
	      } break;
	    }
	  }
	}
      } break;
      case DK_FIG_OBJ_ARC: {
        register_pattern(oi->patused, o);
      } break;
      case DK_FIG_OBJ_ELLIPSE: {
        register_pattern(oi->patused, o);
      } break;
      case DK_FIG_OBJ_POLYLINE: {
        register_pattern(oi->patused, o);
	if(o->subtype == 5) {	
	if(!(oi->skip_images)) {
	  /* get information for included image */
	  
	  p = (dk_fig_polyline *)(o->data);
	  dkfig_tool2_msg3(oi->c, DK_LOG_LEVEL_PROGRESS, 62, 63, p->imagename);
	  if(!dkfig_eps_attach_image_info(oi,o)) {
	    back = 0;		
	  } else {		
	    
	    dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_PROGRESS, 64);
	    if(o->drve) {
	      dkfig_eps_image_info *ii; long width, height;
	      
	      ii = (dkfig_eps_image_info *)(o->drve);
	      if(p->flipped) {	
	        if(((oi->c)->opt2) & DKFIG_OPT_FLIP_DIAGONAL) {
		  ii->fl = 2;	
		} else {
		  ii->fl = 1;	
		}
	      } else {
	        ii->fl = 0;	
	      }
	      if(ii->type > 0) {	
                width = ii->width; height = ii->height;
		
	        if(!(oi->iw)) {		
		  oi->iw = dkfig_tool2_image_width_storage();
	        }
	        if(oi->iw) {		
	          if(!(oi->iwi)) {	
		    oi->iwi = dksto_it_open(oi->iw);
		  }
		  if(oi->iwi) {
		    int sep = 0; 
		    if(((oi->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) {
		      sep = 1;
	              if(!dkfig_ei_check_separated_strings(ii->width, ii->height)) {
		        sep = 0;
		      }
		      if(!(ii->colored)) {
		        sep = 0;
		      }
		    }
                    if(!dkfig_tool2_add_image_width(
		      oi->iw, oi->iwi, width, height, ii->colored, sep, ii->fl
		    ))
		    {
		      back = 0;		
		      
		      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(dk_storage_iterator_t), 1);
		    }
		  }
	        } else {		
	          back = 0;
		  
		  if((oi->c)->app) {
		    dkapp_err_memory((oi->c)->app, sizeof(dk_storage_t), 1);
		  }
	        }
	      } else {
	        if(ii->type == 0) {	
		  /* nothing to do for EPS image */
		}
	      }
	    } else {		
	      back = 0;
	    }
	  }
	}
	}
      } break;
      case DK_FIG_OBJ_SPLINE: {
        register_pattern(oi->patused, o);
      } break;
    }
    dkapp_set_source_lineno((oi->c)->app, 0UL);
    /* DK_MEMCPY(oi->c,&backupc,sizeof(dk_fig_conversion)) ; */
    (oi->c)->opt2 = backupopt2;
    (oi->c)->opt1 = backupopt1;
    (oi->c)->image_align = backupia;
  }
  oi->spcpass += 1;
  if((oi->iw) && (oi->iwi)) {
    dkfig_bitmap_width *bmw;
    oi->numimw = 0UL;
    dksto_it_reset(oi->iwi);
    while((bmw = (dkfig_bitmap_width *)dksto_it_next(oi->iwi)) != NULL) {
      bmw->number = oi->numimw;
      oi->numimw += 1UL;
    }
    oi->allimw = dkfig_dt_needed_alpha(oi->numimw);
  }
  if(must_run_latex) {
    oldback = back;
    back = 0; /* ## auf 1 setzen fuer pstex ## */
    if(dkfig_dt_run_tex(oi->c, oi->d, oi->fli)) {
      if((oi->c)->app) {
        oi->fdvi = dkapp_fopen((oi->c)->app, (oi->c)->dvin, str_open_rb);
      } else {
        oi->fdvi = dksf_fopen((oi->c)->dvin, str_open_rb);
      }
      if((oi->c)->app) {
        oi->fps = dkapp_fopen((oi->c)->app, (oi->c)->psn,  str_open_read);
      } else {
        oi->fps = dksf_fopen((oi->c)->psn, str_open_read);
      }
      if((oi->fdvi) && (oi->fps)) {
        back = 1;
      } else {
        back = 1; /* silently ignore LaTeX text */
      }
    } else {	
    }
    if(!oldback) { back = 0; }
  }
  
  return back;
}



/**	Find factors and shiftings for coord
   	transformations.
	@param	oi	EPS output instruction structure.
*/
static int
establish_coord_transformation DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  int math_error = 0;
  double xmin = 0.0, xmax = 0.0, ymin = 0.0, ymax = 0.0;
  double cxmin = 0.0, cxmax = 0.0, cymin = 0.0, cymax = 0.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, &math_error);
  oi->yfactor = dkma_div_double_ok( 72.0, (oi->d)->fres, &math_error);
  if(dkfig_tool_invert_y(oi->d)) {
    oi->yfactor = 0.0 - oi->yfactor;
  }
  xmin = dkma_mul_double_ok(xmin, oi->xfactor, &math_error);
  xmax = dkma_mul_double_ok(xmax, oi->xfactor, &math_error);
  ymin = dkma_mul_double_ok(ymin, oi->yfactor, &math_error);
  ymax = dkma_mul_double_ok(ymax, oi->yfactor, &math_error);
  if(xmax < xmin) {
    cxmin = xmin; xmin = xmax; xmax = cxmin;
  }
  if(ymax < ymin) {
    cxmin = ymin; ymin = ymax; ymax = cxmin;
  }
  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, &math_error);
  oi->ytop   = dkma_sub_double_ok(cymax, cymin, &math_error);
  oi->xshift = 0.5 * dkma_sub_double_ok(
    oi->xright,
    dkma_sub_double_ok(cxmax, cxmin, &math_error),
    &math_error
  );
  oi->yshift = 0.5 * dkma_sub_double_ok(
    oi->ytop,
    dkma_sub_double_ok(cymax, cymin, &math_error),
    &math_error
  );
  oi->xshift = dkma_sub_double_ok(oi->xshift, cxmin, &math_error);
  oi->yshift = dkma_sub_double_ok(oi->yshift, cymin, &math_error);
  if(math_error) {
    back = 0;
  }
  
  
  return back;
}


/**	Check whether or not to align the graphics on a
	sheet of paper.
	@param	c	Conversion structure.
	@return	1 for do align, 0 for do not align.
*/
static
int
must_align DK_P1(dk_fig_conversion *,c) {
  int back = 0;
  if((c->bdnum) == DKFIG_DRIVER_PS) {
    if((c->opt2) & DKFIG_OPT_ALIGN_ON_PAPER) {
      back = 1;
    }
  }
  return back;
}



/**	Check alignment, correct scale factors and shift.
*/
static
void
check_align DK_P1(dkfig_eps_output_instruction *,oi) {
  double xmin, xmax, ymin, ymax, osx, osy, s, w, h, nw, nh;
  
  xmin = dkma_l_to_double((oi->c)->paper_xleft);
  xmax = dkma_l_to_double((oi->c)->paper_xright);
  ymin = dkma_l_to_double((oi->c)->paper_ybottom);
  ymax = dkma_l_to_double((oi->c)->paper_ytop);
  if(xmax < xmin) { s = xmax; xmax = xmin; xmin = s; }
  if(ymax < ymin) { s = ymax; ymax = ymin; ymin = s; }
  w    = oi->xright;
  h    = oi->ytop;
  if((w >= 1.0) && (h >= 1.0)) {
    osx = osy = s = 1.0;
    nw = w; nh = h;
    if((w <= (xmax - xmin)) && (h <= (ymax - ymin))) {	
      oi->must_scale = 0;
      oi->translate_x = xmin;
      oi->translate_y = ymin;
      switch((oi->c)->align_h) {
        case DKFIG_ALIGN_H_RIGHT: {	
          oi->translate_x = xmax - w;
        } break;
        case DKFIG_ALIGN_H_CENTERED: {		
          oi->translate_x += 0.5 * (xmax - xmin - w);
        } break;
      }
      switch((oi->c)->align_v) {
        case DKFIG_ALIGN_V_TOP: {		
          oi->translate_y = ymax - h;
        } break;
        case DKFIG_ALIGN_V_CENTERED: {		
          oi->translate_y += 0.5 * (ymax - ymin - h);
        } break;
      }
    } else {	
      oi->must_scale = 1;
      osx = fabs((xmax - xmin) / w);
      osy = fabs((ymax - ymin) / h);
      if(osx < osy) s = osx; else s = osy;
      nw = w * s;
      nh = h * s;
      oi->translate_x = xmin;
      oi->translate_y = ymin;
      oi->scaleval = s;
      switch((oi->c)->align_h) {
        case DKFIG_ALIGN_H_RIGHT: {	
          oi->translate_x = xmax - nw;
        } break;
        case DKFIG_ALIGN_H_CENTERED: {	
          oi->translate_x += 0.5 * (xmax - xmin - nw);
        } break;
      }
      switch((oi->c)->align_v) {
        case DKFIG_ALIGN_V_TOP: {		
          oi->translate_y = ymax - nh;
        } break;
        case DKFIG_ALIGN_V_CENTERED: {		
          oi->translate_y += 0.5 * (ymax - ymin - nh);
        } break;
      }
    }
  } 
}


/**	Do all the preparations necessary before starting
   	output.
	@param	oi	EPS output instruction structure.
*/
static int
preparation_pass DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  dk_fig_object *o;
  int error_code = 0;	/* 0=internal setup error, 1=handled */
  
  if(oi->c) {
   if((oi->c)->ostrm) {
    oi->s = (oi->c)->ostrm;
    o = (oi->c)->drwng;
    if(o) {
     oi->dro = o;
     oi->d = (dk_fig_drawing *)(o->data);
     if(oi->d) {
      error_code = 1;
      oi->fl = dkfig_flat_list(oi->c, (oi->c)->drwng);
      if(oi->fl) {
       oi->fli = dksto_it_open(oi->fl);
       if(oi->fli) {
        back = gather_information_and_run_latex(oi);
	if(back) {
	 back = establish_coord_transformation(oi);
	 if(!back) {
	  
	  dkfig_tool2_eps_error_message(oi, 13);
	 }
	}
       } else {
	if((oi->c)->app) {
	 dkapp_err_memory((oi->c)->app, sizeof(dk_storage_iterator_t), 1);
	}
       }
      } else {
       if((oi->c)->app) {
        dkapp_err_memory((oi->c)->app, sizeof(dk_storage_t), 1);
       }
      }
     }
    }
   }
  }
  if(back) {
   oi->translate_x = oi->translate_y = 0.0;
   oi->scaleval = 1.0; oi->must_scale = 0;
   if(must_align(oi->c)) {
    check_align(oi);
   }
  } else {
   if(!error_code) {
    
    dkfig_tool2_eps_error_message(oi, 44);
   }
  }
  
  return back;
}




/**	Print %!PS-Adobe.
	@param	oi	EPS output instruction structure.
*/
static void
ps_header_string DK_P1(dkfig_eps_output_instruction *,oi)
{
  char buffer[16];
  if((oi->c)->psl > 3) {
    (oi->c)->psl = 3;
  }
  if((oi->c)->psl < 1) {
    (oi->c)->psl = 1;
  }
#if DK_HAVE_SNPRINTF
  snprintf(buffer, sizeof(buffer), "%u", (oi->c)->psl);
  buffer[sizeof(buffer)-1] = '\0';
#else
  sprintf(buffer, "%u", (oi->c)->psl);
#endif
  kw_out(oi->s, 2);
  dkstream_puts(oi->s, buffer);
  if((oi->c)->bdnum == DKFIG_DRIVER_EPS) {
    kw_out(oi->s, 3);
    dkstream_puts(oi->s, buffer);
  }
  kw_out(oi->s, 4);
  kw_out(oi->s, 0);
}



/**	Write instructions to re-encode the used fonts.
	@param	oi	EPS output instruction structure.
*/
static void
setup_ps_fonts DK_P1(dkfig_eps_output_instruction *, oi)
{
  unsigned i;
  for(i = 0; i < 35; i++) {
    if((oi->fnused)[i]) {
      kw_out(oi->s, 29);
      dkstream_puts(oi->s, dkfont_get_ps_name(i));
      kw_out(oi->s, 1);
      kw_out(oi->s, 29);
      ps_my_font_name(oi, i);
      kw_out(oi->s, 1);
      kw_out(oi->s, 32);
      kw_out(oi->s, 0);
    }
  }
}



/**	Write bounding box.
	@param	oi	EPS output instruction structure.
*/
static void
ps_bounding_box DK_P1(dkfig_eps_output_instruction *, oi)
{
  char buffer[256];

  if(must_align(oi->c)) {
#if DK_HAVE_SNPRINTF
    snprintf(buffer, sizeof(buffer), "0 0 %d %d",
#else
    sprintf(buffer, "0 0 %d %d",
#endif
      (oi->c)->paper_width, (oi->c)->paper_height
    );
  } else {
#if DK_HAVE_SNPRINTF
    snprintf(buffer, sizeof(buffer), "%ld %ld %ld %ld",
#else
    sprintf(buffer, "%ld %ld %ld %ld",
#endif
      dkma_double_to_l(oi->xleft),
      dkma_double_to_l(oi->ybottom),
      dkma_double_to_l(oi->xright),
      dkma_double_to_l(oi->ytop)
    );
  }
  buffer[sizeof(buffer)-1] = '\0';
  kw_out(oi->s, 5); kw_out(oi->s, 1);
  dkstream_puts(oi->s, buffer); kw_out(oi->s, 0);
}



/**	Check whether or not to encode octal.
	@param	c	Character to check.
	@return	1 for non-octal encoding, 0 for octal encoding.
*/
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;
}



/**	Write PS string for UTF-8 encoded input string.
	@param	s	Stream to write to.
	@param	c	Conversion job structure.
	@param	str	String to write.
*/
static void
ps_encode_utf8 DK_P3(dk_stream_t *,s, dk_fig_conversion *,c, char *,str)
{
  dk_udword ucb;
  unsigned char uc;
  char chr, buffer[128];
  int cc, i;
  size_t max, used, avail, step, curpos;
  cc = 1; max = strlen(str); used = 0; avail = max; curpos = 0;
  
#line 1578 "dkfigeps.ctr"
  
#line 1579 "dkfigeps.ctr"
  
#line 1580 "dkfigeps.ctr"
  
#line 1581 "dkfigeps.ctr"
  
#line 1582 "dkfigeps.ctr"
  
#line 1583 "dkfigeps.ctr"
  
#line 1584 "dkfigeps.ctr"
  
#line 1585 "dkfigeps.ctr"
  kw_out(s, 71);
  while(cc) {
    cc = 0;
    if(avail > 0) {
      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;
	}
	if(ucb < 256UL) {
	  uc = (unsigned char)ucb; chr = (char)uc; i = (int)chr;
	  
	  if(curpos > 250) {
	    kw_out(s, 73); kw_out(s, 0); curpos = 0;
	  }
	  if(is_literal(chr)) {
	    buffer[0] = chr; buffer[1] = '\0';
	  } else {
	    if(i < 0) { i = i + 256; }
	    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);
	  curpos += strlen(buffer);
	} else {
	  
	  /* ERROR: Character out of range */
	  if(c->app) {
	    dkfig_tool2_msg1(c, DK_LOG_LEVEL_ERROR, 119);
	    dkfig_tool2_msg1(c, DK_LOG_LEVEL_INFO, 120);
	  }
	}
      }
    }
  }
  kw_out(s, 72);
}


/**	Write PS string
	@param	s	Stream to write to.
	@param	str	String to write.
*/
static void
ps_encode_string DK_P2(dk_stream_t *,s, char *,str)
{
  char *ptr;
  char buffer[128];
  size_t curpos;
  int i;
  ptr = str;
  curpos = 1;
  kw_out(s, 71);
  while(*ptr) {
    if(curpos > 250) {
      kw_out(s, 73);
      kw_out(s, 0);
      curpos = 0;
    }
    if(is_literal(*ptr)) {
      buffer[0] = *ptr; buffer[1] = '\0';
    } else {
      i = *ptr;
      if(i < 0) { i = 256 + i; }
      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);
    curpos += strlen(buffer);
    ptr++;
  }
  kw_out(s, 72);
}



/**	Print a text object.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
print_text_object DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  dk_fig_dcc dcc;
  dk_fig_text *t;
  int th;
  dk_fig_fonth_t *fhptr = NULL;
  
  dkfig_tool_fill_dcc(oi->d, &dcc, ((oi->o)->fpd).pc);
  dkfig_eps_correct_for_palette(&dcc);
  set_color(oi, &dcc);
  t = (dk_fig_text *)((oi->o)->data);
  if(t) {
    th = (((t->font_flags) & 2) ? ((oi->c)->special_text) : ((oi->c)->normal_text));
    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)) {
	    oi->have &= (~(HAVE_PSFONT));
  	    if(!((oi->errprinted) & 1)) {
  	      dkfig_tool2_eps_error_message(oi, 85);
  	      if(!(((oi->c)->opt1) & DKFIG_OPT_REPORT_MULTIPLE)) {
	        oi->errprinted |= 1;
  	      }
  	    }
	  }
	} break;
	default: {
	  int rotation;
	  
	  rotation = 0;
	  set_psfont(oi, (unsigned)(fhptr->fontno), fhptr->fontsize);
	  if(fabs(t->angle) > DKFIG_EPSILON) {
	    double dv;
	    kw_out(oi->s, 44); kw_out(oi->s, 0);
	    lpointout(oi, t->x, t->y, 1);
	    kw_out(oi->s, 57);
	    kw_out(oi->s, 1);
	    dv = (180.0 * t->angle) / M_PI;
            dkstream_puts_double(
	      oi->s, drd(dv, oi->c, 1)
	    );
	    kw_out(oi->s, 1); kw_out(oi->s, 59);
	    kw_out(oi->s, 0);
	    /* lpointout(oi, 0.0, 0.0); */
	    dkstream_puts_double(oi->s, 0.0);
	    kw_out(oi->s, 1);
	    dkstream_puts_double(oi->s, 0.0);
	    kw_out(oi->s, 1);
	    kw_out(oi->s, 48); kw_out(oi->s, 0);
	    if(((oi->c)->opt2) & DKFIG_OPT_UTF_8) {
	      ps_encode_utf8(oi->s, oi->c, t->text);
	    } else {
	      ps_encode_string(oi->s, t->text);
	    }
	    kw_out(oi->s, 1);
	    switch((oi->o)->subtype) {
	      case 1: { kw_out(oi->s, 70); } break;
	      case 2: { kw_out(oi->s, 69); } break;
	      default: { kw_out(oi->s, 68); } break;
	    }
	    kw_out(oi->s, 0);
	    kw_out(oi->s, 45); kw_out(oi->s, 0);
	  } else {
	    kw_out(oi->s, 46); kw_out(oi->s, 0);
	    lpointout(oi, t->x, t->y, 1);
            kw_out(oi->s, 48); kw_out(oi->s, 0);
	    if(((oi->c)->opt2) & DKFIG_OPT_UTF_8) {
	      ps_encode_utf8(oi->s, oi->c, t->text);
	    } else {
	      ps_encode_string(oi->s, t->text);
	    }
	    kw_out(oi->s, 1);
	    switch((oi->o)->subtype) {
	      case 1: { kw_out(oi->s, 70); } break;
	      case 2: { kw_out(oi->s, 69); } break;
	      default: { kw_out(oi->s, 68); } break;
	    }
	    kw_out(oi->s, 0);
	  }
	} break;
      }
    }
  }
  
  return back;
}



/**	Check whether or not the current object changes
   	the current transformation matrix.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
ctm_change DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  switch((oi->o)->objtype) {
    case DK_FIG_OBJ_ELLIPSE: {
      switch((oi->o)->subtype) {
        case 3: case 4: back = 0; break;
	default: {
          dk_fig_ellipse *e;
	  back = 1;
	  e = (dk_fig_ellipse *)((oi->o)->data);
	  if(e) {
	    if(e->radiusx == e->radiusy) {
	      back = 0;
	    }
	  }
	} break;
      }
    } break;
  }
  return back;
}



/**	Write path for ellipse.
	@param	oi	EPS output instruction structure.
*/
static void
path_ellipse DK_P1(dkfig_eps_output_instruction *,oi)
{
  dk_fig_ellipse *e;
  e = (dk_fig_ellipse *)((oi->o)->data);
  if(e) {
    if(ctm_change(oi)) {
      lpointout(oi, e->centerx, e->centery, 1);
      kw_out(oi->s, 57); kw_out(oi->s, 0);
      if(fabs(e->angle) > DKFIG_EPSILON) {
        stream_putdouble(
	  oi->s,
	  drd(
	    dkma_div_double_ok(
	      dkma_mul_double_ok(180.0, e->angle, &(oi->me)),
	      M_PI,
	      &(oi->me)
	    ), oi->c, 1
	  ), oi->c, 1
	); kw_out(oi->s, 1);
	kw_out(oi->s, 59); kw_out(oi->s, 0);
      }
      stream_putdouble(oi->s, 1.0, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(
        oi->s,
	dkma_div_double_ok(
	  dkma_l_to_double(e->radiusy),
	  dkma_l_to_double(e->radiusx),
	  &(oi->me)
	), oi->c, 1
      ); kw_out(oi->s, 1);
      kw_out(oi->s, 58); kw_out(oi->s, 0);
      stream_putdouble(oi->s, 0.0, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, 0.0, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(
        oi->s, ccdd(oi, dkma_l_to_double(e->radiusx)),
	oi->c, 1
      );
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, 0.0, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, 360.0, oi->c, 1); kw_out(oi->s, 1);
      kw_out(oi->s, 55); kw_out(oi->s, 0);
    } else {
      lpointout(
        oi,
	dkma_add_long_ok( e->centerx, e->radiusx, &(oi->me)),
	e->centery, 1
      );
      kw_out(oi->s, 48); kw_out(oi->s, 0);
      lpointout(oi, e->centerx, e->centery, 1);
      stream_putdouble(
        oi->s,
	ccdd(oi, dkma_l_to_double(e->radiusx)),
	oi->c, 1
      );
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, 0.0, oi->c, 1);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, 360.0, oi->c, 1);
      kw_out(oi->s, 1); kw_out(oi->s, 55); kw_out(oi->s, 0);
    }
  }
}



/**	Write path for a polyline.
	@param	oi	EPS output instruction structure.
*/
static void
path_polyline DK_P1(dkfig_eps_output_instruction *,oi)
{
  dk_fig_polyline *p;
  long *xptr, *yptr;
  size_t i;
  dk_fig_bb bbdest;
  double x1, x2, y1, y2, radius, deltax, deltay;
  p = (dk_fig_polyline *)((oi->o)->data);
  if(p) {
    switch(((oi->o)->fpd).st) {
      case 2: case 4: case 5: {	/* box, arc box or image box */
	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++;
	}
	if(((oi->o)->fpd).st == 4) {	/* arc box */
          deltax = dkma_sub_double_ok(bbdest.xmax, bbdest.xmin, &(oi->me));
	  deltay = dkma_sub_double_ok(bbdest.ymax, bbdest.ymin, &(oi->me));
          radius = 0.9 * dkma_l_to_double(p->radius);
	  if(radius > (0.5 * deltax)) { radius = 0.5 * deltax; }
	  if(radius > (0.5 * deltay)) { radius = 0.5 * deltay; }
	  x1 = bbdest.xmin + radius; x2 = bbdest.xmax - radius;
	  y1 = bbdest.ymin + radius; y2 = bbdest.ymax - radius;
	  ncdpointout(oi, x2, bbdest.ymin, 1);
	  kw_out(oi->s, 48); kw_out(oi->s, 0);
	  ncdpointout(oi, x2, y1, 1);
	  stream_putdouble(oi->s, radius, oi->c, 1); kw_out(oi->s, 1);
	  kw_out(oi->s, 50); kw_out(oi->s, 1);
	  kw_out(oi->s, 51); kw_out(oi->s, 1);
	  kw_out(oi->s, 55); kw_out(oi->s, 0);
	  ncdpointout(oi, bbdest.xmax, y2, 1);
	  kw_out(oi->s, 49); kw_out(oi->s, 0);
          ncdpointout(oi, x2, y2, 1);
	  stream_putdouble(oi->s, radius, oi->c, 1); kw_out(oi->s, 1);
	  kw_out(oi->s, 51); kw_out(oi->s, 1);
	  kw_out(oi->s, 52); kw_out(oi->s, 1);
	  kw_out(oi->s, 55); kw_out(oi->s, 0);
	  ncdpointout(oi, x1, bbdest.ymax, 1);
	  kw_out(oi->s, 49); kw_out(oi->s, 0);
	  ncdpointout(oi, x1, y2, 1);
	  stream_putdouble(oi->s, radius, oi->c, 1); kw_out(oi->s, 1);
	  kw_out(oi->s, 52); kw_out(oi->s, 1);
	  kw_out(oi->s, 53); kw_out(oi->s, 1);
	  kw_out(oi->s, 55); kw_out(oi->s, 0);
	  ncdpointout(oi, bbdest.xmin, y1, 1);
	  kw_out(oi->s, 49); kw_out(oi->s, 0);
	  ncdpointout(oi, x1, y1, 1);
	  stream_putdouble(oi->s, radius, oi->c, 1); kw_out(oi->s, 1);
	  kw_out(oi->s, 53); kw_out(oi->s, 1);
	  kw_out(oi->s, 54); kw_out(oi->s, 1);
	  kw_out(oi->s, 55); kw_out(oi->s, 0);
	} else {			/* non-arc box */
	  ncdpointout(oi, bbdest.xmin, bbdest.ymin, 1);
          kw_out(oi->s, 48); kw_out(oi->s, 0);
	  ncdpointout(oi, bbdest.xmax, bbdest.ymin, 1);
	  kw_out(oi->s, 49); kw_out(oi->s, 0);
	  ncdpointout(oi, bbdest.xmax, bbdest.ymax, 1);
	  kw_out(oi->s, 49); kw_out(oi->s, 0);
	  ncdpointout(oi, bbdest.xmin, bbdest.ymax, 1);
	  kw_out(oi->s, 49); kw_out(oi->s, 0);
	}
      } break;
      default: {			/* real polyline or polygon */
        xptr = p->xvalues; yptr = p->yvalues;
        if((!(((oi->o)->fpd).cl)) && (((oi->o)->fpd).ar & 2)) {
          /* backward arrowhead */
	  dpointout(oi, (p->pa).x, (p->pa).y, 2);
        } else {
          /* no backward arrowhead */
	  lpointout(oi, *xptr, *yptr, 1);
        }
	kw_out(oi->s, 1); kw_out(oi->s, 48); kw_out(oi->s, 0);
	xptr++; yptr++;
	for(i = 1; i < p->npoints; i++) {
	  if(i == (p->npoints - 1)) {
	    if(((oi->o)->fpd).cl) {
	      lpointout(oi, *xptr, *yptr, 1);
	    } else {
	      if(((oi->o)->fpd).ar & 1) {
	        dpointout(oi, (p->pe).x, (p->pe).y, 2);
	      } else {
	        lpointout(oi, *xptr, *yptr, 1);
	      }
	    }
	  } else {
	    lpointout(oi, *xptr, *yptr, 1);
	  }
	  kw_out(oi->s, 1); kw_out(oi->s, 49); kw_out(oi->s, 0);
	  xptr++; yptr++;
	}
      } break;
    }
  }
}



/**	Write one procedure to fill binary data into
   	a string. Used for included bitmaps.
	@param	oi	EPS output instruction structure.
	@param	ii	Image information structure.
	@param	wi	Image width structure.
	@param	number	Index of width.

*/
static void
write_eps_read_procedure DK_P4(dkfig_eps_output_instruction *,oi, dkfig_eps_image_info *,ii, dkfig_bitmap_width *,wi, int, number)
{
  kw_out(oi->s, 81); kw_out(oi->s, 1);
  if((oi->c)->psl > 1) {
    kw_out(oi->s, 92);
  } else {
    kw_out(oi->s, 83);
  } kw_out(oi->s, 1);
  kw_out(oi->s, 77);
  switch(number) {
    case 1: {
      kw_out(oi->s, 94);
    } break;
    case 2: {
      kw_out(oi->s, 95);
    } break;
    case 3: {
      kw_out(oi->s, 96);
    } break;
  }
  dkfig_tool_num_as_string(oi->s, wi->number, oi->allimw);
  kw_out(oi->s, 1);
  if((oi->c)->psl > 1) {
    kw_out(oi->s, 85);
  } else {
    kw_out(oi->s, 84);
  } kw_out(oi->s, 1);
  kw_out(oi->s, 86); kw_out(oi->s, 1);
  kw_out(oi->s, 82); kw_out(oi->s, 0);
}



/**	Remove  trailing whitespaces.
	@param	s	String.
*/
static void
my_chomp DK_P1(char *,s)
{
  char *ptr, *xptr;
  xptr = NULL; ptr = s;
  while(*ptr) {
    switch(*ptr) {
      case ' ': case '\t': case '\r': case '\n': {
        if(!xptr) {
	  xptr = ptr;
	}
      } break;
      default: {
        xptr = NULL;
      } break;
    }
    ptr++;
  }
  if(xptr) {
    *xptr = '\0';
  }
}



/**	Pass-through a PS file containing binary data.
	@param	oi	EPS output instruction structure.
	@param	fipo	Source file.
*/
static void
bin_pass_through DK_P2(dkfig_eps_output_instruction *,oi, FILE *,fipo)
{
  char inbuffer[512]; size_t sz;
  int cc;
  cc = 1;
  while(cc) {
    sz = fread(inbuffer,1,512,fipo);
    if(sz) {
      if(dkstream_write(oi->s, inbuffer, sz) != sz) {
        cc = 0;
      }
    } else {
      cc = 0;
    }
  }
}



/**	Pass-through ASCII PS file.
	@param	oi	EPS output instruction structure.
	@param	fipo	Source file.
*/
static void
file_pass_through DK_P2(dkfig_eps_output_instruction *,oi, FILE *,fipo)
{
  char inbuffer[256], *ptr;
  while(fgets(inbuffer, sizeof(inbuffer), fipo)) {
    ptr = dkstr_start(inbuffer, NULL);
    if(ptr) {
      my_chomp(inbuffer);
      dkstream_puts(oi->s, inbuffer);
    }
    kw_out(oi->s, 0);
  }
}



/**	Write inserted image.
	@param	oi	EPS output instruction structure.
*/
static int
insert_image DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  dk_fig_polyline *p;
  dk_fig_bb bbdest;
  long *xptr, *yptr;
  double	lw;	/* Line width of surrounding rectangle. */
  double	h;	/* Image height. */
  double	w;	/* Image width. */
  double	deltax;	/* Polygon width. */
  double	deltay;	/* Polygon height. */
  double	sf;	/* Scale factor to show image. */
  double	q1;
  double	q2;
  double	xa;	/* Left side of imageable area. */
  double	ya;	/* Bottom of imageable area. */
  double	xb;	/* Right side of imageable area. */
  double	yb;	/* Top of imageable area. */
  double	a;
  double	b;
  double	c;
  double	d;
  double	e;
  double	f;
  dkfig_eps_image_info *ii;
  dkfig_bitmap_width *wi;
  FILE *fipo = NULL;
  size_t i;
  
  lw = h = w = deltax = deltay = sf = 0.0;
  xa = xb = ya = yb = 0.0;
  a = b = c = d = e = f = 0.0;
  wi = NULL;
  p = (dk_fig_polyline *)((oi->o)->data);
  ii = (dkfig_eps_image_info *)((oi->o)->drve);
  if((p) && (ii)) {
    if((oi->iw) && (oi->iwi)) {
      int sep = 0;
      if(((oi->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) {
        sep = 1;
	if(!dkfig_ei_check_separated_strings(ii->width, ii->height)) {
	  sep = 0;
	}
	if(ii->type == 0) {
	  sep = 0;
	}
	if(!(ii->colored)) {
	  sep = 0;
	}
      }
      wi = dkfig_tool2_find_entry_for_width(
        oi->iwi, ii->width, ii->height, ii->colored, sep, ii->fl
      );
    }
    if((wi) || (ii->type == 0)) {	
      /* get polygon box */
      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++;
      }
      if(((oi->o)->fpd).pc != (oi->d)->transparent) {
        if(!(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BITMAP_BORDER)) {
          lw = get_object_linewidth(oi, 0);
	}
      }
      /* get polygon width and height */
      deltax = dkma_sub_double_ok(
        dkma_sub_double_ok(bbdest.xmax, bbdest.xmin, &(oi->me)),
        lw,
        &(oi->me)
      );
      deltay = dkma_sub_double_ok(
        dkma_sub_double_ok(bbdest.ymax, bbdest.ymin, &(oi->me)),
        lw,
        &(oi->me)
      );
      /* get image width and height */
      w = dkma_l_to_double(ii->width);
      h = dkma_l_to_double(ii->height);
      if(ii->fl == 2) {
        
        w = dkma_l_to_double(ii->height);
	h = dkma_l_to_double(ii->width);
      }
      if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
        /* compare image aspect ration against polygon aspect ratio */
        q1 = dkma_div_double_ok(h, w, &(oi->me));
        q2 = dkma_div_double_ok(deltay, deltax, &(oi->me));
        if(q1 > q2) {
          /* image is "too high" */
          sf = dkma_div_double_ok(deltay, h, &(oi->me));
          ya = dkma_add_double_ok( bbdest.ymin, (0.5 * lw), &(oi->me));
          yb = dkma_sub_double_ok( bbdest.ymax, (0.5 * lw), &(oi->me));
	  switch(((oi->c)->image_align) & 3) {
	    case DKFIG_ALIGN_H_LEFT: {
	      xa = dkma_add_double_ok(bbdest.xmin, (0.5 * lw), &(oi->me));
	      xb = dkma_add_double_ok(
	        xa,
		dkma_mul_double_ok(w, sf, &(oi->me)),
		&(oi->me)
	      );
	    } break;
	    case DKFIG_ALIGN_H_RIGHT: {
	      xb = dkma_sub_double_ok(bbdest.xmax, (0.5 * lw), &(oi->me));
	      xa = dkma_sub_double_ok(
	        xb,
		dkma_mul_double_ok(w, sf, &(oi->me)),
		&(oi->me)
	      );
	    } break;
	    default: {
              q1 = 0.5 * dkma_add_double_ok(bbdest.xmin, bbdest.xmax, &(oi->me));
              q2 = 0.5 * dkma_mul_double_ok(w, sf, &(oi->me));
              xa = dkma_sub_double_ok(q1, q2, &(oi->me));
              xb = dkma_add_double_ok(q1, q2, &(oi->me));
	    } break;
	  }
        } else {
          /* image is "too wide" */
          sf = dkma_div_double_ok(deltax, w, &(oi->me));
          xa = dkma_add_double_ok(bbdest.xmin, (0.5 * lw), &(oi->me));
          xb = dkma_sub_double_ok(bbdest.xmax, (0.5 * lw), &(oi->me));
	  switch((((oi->c)->image_align) >> 2) & 3) {
	    case DKFIG_ALIGN_V_TOP: {
	      yb = dkma_sub_double_ok(bbdest.ymax, (0.5 * lw), &(oi->me));
	      ya = dkma_sub_double_ok(
	        yb,
		dkma_mul_double_ok(sf, h, &(oi->me)),
		&(oi->me)
	      );
	    } break;
	    case DKFIG_ALIGN_V_BOTTOM: {
	      ya = dkma_add_double_ok(bbdest.ymin, (0.5 * lw), &(oi->me));
	      yb = dkma_add_double_ok(
	        ya,
		dkma_mul_double_ok(sf, h, &(oi->me)),
		&(oi->me)
	      );
	    } break;
	    default: {
              q1 = 0.5 * dkma_add_double_ok(bbdest.ymin, bbdest.ymax, &(oi->me));
              q2 = 0.5 * dkma_mul_double_ok(h, sf, &(oi->me));
              ya = dkma_sub_double_ok(q1, q2, &(oi->me));
              yb = dkma_add_double_ok(q1, q2, &(oi->me));
	    } break;
	  }
        }
      } else {
        xa = dkma_add_double_ok(bbdest.xmin, (0.5 * lw), &(oi->me));
	xb = dkma_sub_double_ok(bbdest.xmax, (0.5 * lw), &(oi->me));
	ya = dkma_add_double_ok(bbdest.ymin, (0.5 * lw), &(oi->me));
	yb = dkma_sub_double_ok(bbdest.ymax, (0.5 * lw), &(oi->me));
      }
      /* calculate ITM */
      a = dkma_sub_double_ok(xb, xa, &(oi->me));
      d = dkma_sub_double_ok(ya, yb, &(oi->me));
      e = xa; f = yb;
      /* write image */
      
      if((oi->c)->app) {
        fipo = dkapp_fopen((oi->c)->app, ii->filename, str_open_rb);
      } else {
        fipo = dksf_fopen(ii->filename, str_open_rb);
      }
      if(fipo) {	
        switch(ii->type) {
	  case 1: case 2: case 3: {
            back = 1;
            /* w h 8 [a b c d e f] procedure image */
            if((oi->c)->psl > 1) {
              kw_out(oi->s, 29);
              kw_out(oi->s, 92); kw_out(oi->s, 1);
              kw_out(oi->s, 83); kw_out(oi->s, 1);
              kw_out(oi->s, 87); kw_out(oi->s, 1);
              if((oi->c)->psl > 2) {
                kw_out(oi->s, 88); kw_out(oi->s, 1);
              } else {
                if(((oi->c)->opt1) & DKFIG_OPT_ALLOW_PSRL) {
                  kw_out(oi->s, 89); kw_out(oi->s, 1);
	        }
              }
              kw_out(oi->s, 31); kw_out(oi->s, 0);
            }
	    kw_out(oi->s, 44); kw_out(oi->s, 0);
	    stream_putdouble(oi->s, xa, oi->c, 1); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, yb, oi->c, 1); kw_out(oi->s, 1);
	    kw_out(oi->s, 57); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, a, oi->c, 1); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, (0.0 - d), oi->c, 1); kw_out(oi->s, 1);
	    kw_out(oi->s, 58); kw_out(oi->s, 0);
            stream_putul(oi->s, ((ii->fl == 2) ? ii->height : ii->width));
	    kw_out(oi->s, 1);
            stream_putul(oi->s, ((ii->fl == 2) ? ii->width : ii->height));
	    kw_out(oi->s, 1);
            stream_putul(oi->s, 8L); kw_out(oi->s, 1);
            kw_out(oi->s, 61); kw_out(oi->s, 1);
            /* stream_putdouble(oi->s, a, oi->c, 1); kw_out(oi->s, 1); */
	    stream_putul(oi->s, ((ii->fl == 2) ? ii->height : ii->width));
	    kw_out(oi->s, 1);
            stream_putdouble(oi->s, b, oi->c, 1); kw_out(oi->s, 1);
            stream_putdouble(oi->s, c, oi->c, 1); kw_out(oi->s, 1);
            /* stream_putdouble(oi->s, d); kw_out(oi->s, 1); */
	    kw_out(oi->s, 91);
	    stream_putul(oi->s, ((ii->fl == 2) ? ii->width : ii->height));
	    kw_out(oi->s, 1);
            /* stream_putdouble(oi->s, e); kw_out(oi->s, 1); */
	    stream_putul(oi->s, 0L); kw_out(oi->s, 1);
	    stream_putul(oi->s, 0L); kw_out(oi->s, 1);
            /* stream_putdouble(oi->s, f); kw_out(oi->s, 1); */
            kw_out(oi->s, 62); kw_out(oi->s, 0);
            if(((oi->c)->psl > 1) && (ii->colored)) {
              
	      if(wi->seprgb) {
	        write_eps_read_procedure(oi, ii, wi, 1);
	        write_eps_read_procedure(oi, ii, wi, 2);
	        write_eps_read_procedure(oi, ii, wi, 3);
                kw_out(oi->s, 93); kw_out(oi->s, 1);
	      } else {
	        write_eps_read_procedure(oi, ii, wi, 0);
	        kw_out(oi->s, 90); kw_out(oi->s, 1);
	      }
	      stream_putul(oi->s, 3L); kw_out(oi->s, 1);
	      kw_out(oi->s, 80); kw_out(oi->s, 0);
            } else {
              
	      write_eps_read_procedure(oi, ii, wi, 0);
	      kw_out(oi->s, 79); kw_out(oi->s, 0);
            }
	    file_pass_through(oi, fipo);
	    kw_out(oi->s, 45); kw_out(oi->s, 0);
	  } break;
	  case 0: {
	    double xt = 0.0, yt = 0.0, sfx = 0.0, sfy = 0.0;
	    /* gsave clip translate scale */
	    
	    back = 1;
	    /* gsave */
	    kw_out(oi->s, 44); kw_out(oi->s, 0);
	    /* newpath / + clip */
	    kw_out(oi->s, 46); kw_out(oi->s, 0);
	    stream_putdouble(oi->s, xa, oi->c, 1); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, ya, oi->c, 1); kw_out(oi->s, 1);
	    kw_out(oi->s, 48); kw_out(oi->s, 0);
	    stream_putdouble(oi->s, xb, oi->c, 1); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, ya, oi->c, 1); kw_out(oi->s, 1);
	    kw_out(oi->s, 49); kw_out(oi->s, 0);
	    stream_putdouble(oi->s, xb, oi->c, 1); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, yb, oi->c, 1); kw_out(oi->s, 1);
	    kw_out(oi->s, 49); kw_out(oi->s, 0);
	    stream_putdouble(oi->s, xa, oi->c, 1); kw_out(oi->s, 1);
	    stream_putdouble(oi->s, yb, oi->c, 1); kw_out(oi->s, 1);
	    kw_out(oi->s, 49); kw_out(oi->s, 0);
	    kw_out(oi->s, 47); kw_out(oi->s, 1);
	    kw_out(oi->s, 63); kw_out(oi->s, 0);
	    /* - clip */
	    switch(ii->fl) {
	      case 2: {	/* diagonal flip */
		if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
		  sfy = sf;
		  sfx = 0.0 - sf;
		} else {
	          sfx = 0.0 - dkma_div_double_ok(
	            dkma_sub_double_ok(xb, xa, &(oi->me)),
		    dkma_l_to_double(ii->height),
		    &(oi->me)
	          );
	          sfy = dkma_div_double_ok(
	            dkma_sub_double_ok(yb, ya, &(oi->me)),
		    dkma_l_to_double(ii->width),
		    &(oi->me)
	          );
		}
#if USE_WRONG_COORDINATE_CALCULATION
		xt = dkma_sub_double_ok(
		  xb,
		  dkma_mul_double_ok(sfx, dkma_l_to_double(ii->ymin), &(oi->me)),
		  &(oi->me)
		);
		yt = dkma_add_double_ok(
		  yb,
		  dkma_mul_double_ok(sfy, dkma_l_to_double(ii->xmin), &(oi->me)),
		  &(oi->me)
		);
#endif
		xt = dkma_sub_double_ok(
		  dkma_div_double_ok(yb, sfx, &(oi->me)),
		  dkma_l_to_double(ii->xmin),
		  &(oi->me)
		);
		yt = dkma_sub_double_ok(
		  dkma_div_double_ok((0.0 - xb), sfy, &(oi->me)),
		  dkma_l_to_double(ii->ymin),
		  &(oi->me)
		);
		dkstream_puts_ul(oi->s, 90UL);
		kw_out(oi->s, 1);
		kw_out(oi->s, 59); kw_out(oi->s, 0);
		dkstream_puts_double(oi->s, drd(sfx, oi->c, 2));
		kw_out(oi->s, 1);
		dkstream_puts_double(oi->s, drd(sfy, oi->c, 2));
		kw_out(oi->s, 1);
		kw_out(oi->s, 58); kw_out(oi->s, 0);
		dkstream_puts_double(oi->s, drd(xt, oi->c, 2));
		kw_out(oi->s, 1);
		dkstream_puts_double(oi->s, drd(yt, oi->c, 2));
		kw_out(oi->s, 1);
		kw_out(oi->s, 57); kw_out(oi->s, 0);
	      } break;
	      case 1: {	/* horizontal flip */
                if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
	          xt = dkma_add_double_ok(
	            xa,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->xmin + ii->width),
		      sf,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	          yt = dkma_sub_double_ok(
	            ya,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->ymin)
		      ,sf,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	        } else {
	          sfx = dkma_div_double_ok(
	            dkma_sub_double_ok(xb, xa, &(oi->me)),
		    dkma_l_to_double(ii->width),
		    &(oi->me)
	          );
	          sfy = dkma_div_double_ok(
	            dkma_mul_double_ok(yb, ya, &(oi->me)),
		    dkma_l_to_double(ii->height),
		    &(oi->me)
	          );
	          xt  = dkma_add_double_ok(
	            xa,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->xmin + ii->width),
		      sfx,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	          yt  = dkma_sub_double_ok(
	            ya,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->ymin),
		      sfy,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	        }
	        stream_putdouble(oi->s, xt, oi->c, 1); kw_out(oi->s, 1);
	        stream_putdouble(oi->s, yt, oi->c, 1); kw_out(oi->s, 1);
                kw_out(oi->s, 57); kw_out(oi->s, 0);
                if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
	          stream_putdouble(oi->s, (0.0 - sf), oi->c, 1);
		  kw_out(oi->s, 1);
	          stream_putdouble(oi->s, sf, oi->c, 1);
	        } else {
	          stream_putdouble(oi->s, (0.0 - sfx), oi->c, 1);
		  kw_out(oi->s, 1);
	          stream_putdouble(oi->s, sfy, oi->c, 1);
	        } kw_out(oi->s, 1);
	        kw_out(oi->s, 58); kw_out(oi->s, 0);
	      } break;
	      default: {	/* 0 = no flip */
                if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
	          xt = dkma_sub_double_ok(
	            xa,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->xmin),
		      sf,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	          yt = dkma_sub_double_ok(
	            ya,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->ymin)
		      ,sf,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	        } else {
	          sfx = dkma_div_double_ok(
	            dkma_sub_double_ok(xb, xa, &(oi->me)),
		    dkma_l_to_double(ii->width),
		    &(oi->me)
	          );
	          sfy = dkma_div_double_ok(
	            dkma_mul_double_ok(yb, ya, &(oi->me)),
		    dkma_l_to_double(ii->height),
		    &(oi->me)
	          );
	          xt  = dkma_sub_double_ok(
	            xa,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->xmin),
		      sfx,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	          yt  = dkma_sub_double_ok(
	            ya,
		    dkma_mul_double_ok(
		      dkma_l_to_double(ii->ymin),
		      sfy,
		      &(oi->me)
		    ),
		    &(oi->me)
	          );
	        }
	        stream_putdouble(oi->s, xt, oi->c, 1); kw_out(oi->s, 1);
	        stream_putdouble(oi->s, yt, oi->c, 1); kw_out(oi->s, 1);
                kw_out(oi->s, 57); kw_out(oi->s, 0);
                if(((oi->c)->opt1) & DKFIG_OPT_KEEP_BITMAP_WH_RATIO) {
	          stream_putdouble(oi->s, sf, oi->c, 1); kw_out(oi->s, 1);
	          stream_putdouble(oi->s, sf, oi->c, 1);
	        } else {
	          stream_putdouble(oi->s, sfx, oi->c, 1); kw_out(oi->s, 1);
	          stream_putdouble(oi->s, sfy, oi->c, 1);
	        } kw_out(oi->s, 1);
	        kw_out(oi->s, 58); kw_out(oi->s, 0);
	      } break;
	    }
	    /* image */
	    if((oi->c)->dscl) {
	      /* %%BeginDocument: */
	      kw_out(oi->s, 104);
	      dkstream_puts(
	        oi->s,
		dksf_get_last_filename(p->imagename)
	      );
	      kw_out(oi->s, 0);
	    }
	    /* pass-through */
	    if(ii->binary) {
	      bin_pass_through(oi, fipo);
	    } else {
	      file_pass_through(oi, fipo);
	    }
	    if((oi->c)->dscl) {
	      /* %%EndDocument */
	      kw_out(oi->s, 105); kw_out(oi->s, 0);
	    }
	    /* grestore */
	    kw_out(oi->s, 45); kw_out(oi->s, 0);
	    
	  } break;
        }
        fclose(fipo); fipo = NULL;
      } else {	
      }
    } else {	
    }
  }
  
  return back;
}



/**	Write path for arc.
	@param	oi	EPS output instruction structure.
*/
static void
path_arc DK_P1(dkfig_eps_output_instruction *,oi)
{
  dk_fig_arc *a;
  double radius, ahl, xm, ym, x1, y1, astart, aend;
  
  a = (dk_fig_arc *)((oi->o)->data);
  if(a) {	
    radius = ccdd(oi, (a->calc).ra);
    if(((oi->o)->fpd).cl) {	
      dpointout(oi, (a->calc).xm, (a->calc).ym, 1);
      kw_out(oi->s, 48); kw_out(oi->s, 0);
      dpointout(oi, (a->calc).xm, (a->calc).ym, 1);
      stream_putdouble(oi->s, radius, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s,
        dkma_div_double_ok(
	  dkma_mul_double_ok(180.0, (a->calc).astart, &(oi->me)),
	  M_PI,
	  &(oi->me)
	), oi->c, 1
      );
      kw_out(oi->s, 1);
      stream_putdouble(oi->s,
        dkma_div_double_ok(
	  dkma_mul_double_ok(180.0,
	  dkma_add_double_ok(
	    (a->calc).astart, ((a->calc).alength), &(oi->me)
	  ),
	  &(oi->me)),
	  M_PI,
	  &(oi->me)
	), oi->c, 1
      );
      kw_out(oi->s, 1);
      kw_out(oi->s, 55); kw_out(oi->s, 0);
    } else {	
      ahl = 0.0;
      if((((oi->o)->fpd).ar) & 1) {	
        ahl = a->rba;
      }
      if((((oi->o)->fpd).ar) & 2) {	
        ahl = dkma_add_double_ok(ahl, a->lba, &(oi->me));
      } 
      if(ahl <= (a->calc).alength) {
        astart = (a->calc).astart;
	if((((oi->o)->fpd).ar) & 2) {
          astart = dkma_add_double_ok(astart, a->lba, &(oi->me));
	}
	aend = dkma_add_double_ok((a->calc).astart, (a->calc).alength, &(oi->me));
	if((((oi->o)->fpd).ar) & 1) {
	  aend = dkma_sub_double_ok(aend, fabs(a->rba), &(oi->me));
	}
	xm = ccdx(oi, (a->calc).xm);
	ym = ccdy(oi, (a->calc).ym);
	x1 = dkma_add_double_ok(
	  xm,
	  (radius*cos(astart)),
	  &(oi->me)
	);
	y1 = dkma_add_double_ok(
	  ym,
	  (radius*sin(astart)),
	  &(oi->me)
	);
	ncdpointout(oi, x1, y1, 2);
	kw_out(oi->s, 48); kw_out(oi->s, 0);
	ncdpointout(oi, xm, ym, 1);
	stream_putdouble(oi->s, radius, oi->c, 1);
	kw_out(oi->s, 1);
        stream_putdouble(oi->s,
          dkma_div_double_ok(
	    dkma_mul_double_ok(180.0, astart, &(oi->me)),
	    M_PI,
	    &(oi->me)
	  ), oi->c, 1
        );
        kw_out(oi->s, 1);
        stream_putdouble(oi->s,
          dkma_div_double_ok(
	    dkma_mul_double_ok(180.0, aend, &(oi->me)),
	    M_PI,
	    &(oi->me)
	  ), oi->c, 2
        );
        kw_out(oi->s, 1);
        kw_out(oi->s, 55); kw_out(oi->s, 0);
      } else {	
      }
    }
  }
  
}



/**	Write path for spline.
	@param	oi	EPS output instruction structure.
*/
static void
path_spline DK_P1(dkfig_eps_output_instruction *,oi)
{
  dk_fig_spline *s;
  dk_fig_bezier_point *bpptr;
  size_t nsegs, li, ri, maxli;
  s = (dk_fig_spline *)((oi->o)->data);
  if(s) {
    bpptr = s->bpoints;
    nsegs = s->nbpoints - 1;
    if(((oi->o)->fpd).cl) { nsegs = s->nbpoints; }
    if((!(((oi->o)->fpd).cl)) && (((oi->o)->fpd).ar & 2)) {
      dpointout(oi, (s->pa).value.x, (s->pa).value.y, 2);
      kw_out(oi->s, 48); kw_out(oi->s, 0);
      dpointout(oi, (s->pa).rcontrol.x, (s->pa).rcontrol.y, 2);
      dpointout(oi, (s->pa2).lcontrol.x, (s->pa2).lcontrol.y, 2);
      dpointout(oi, (s->pa2).value.x, (s->pa2).value.y, 2);
      kw_out(oi->s, 56); kw_out(oi->s, 0);
      li = s->normals;
    } else {
      dpointout(oi, bpptr[0].value.x, bpptr[0].value.y, 2);
      kw_out(oi->s, 48); kw_out(oi->s, 0);
      li = 0;
    }
    if((s->normale > 0) || (((oi->o)->fpd).cl) || (!((((oi->o)->fpd).ar) & 1))) {
      maxli = s->nbpoints - 2;
      if(((oi->o)->fpd).cl) { maxli = s->nbpoints - 1; }
      if((!(((oi->o)->fpd).cl)) && (((oi->o)->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, 2);
        dpointout(oi, bpptr[ri].lcontrol.x, bpptr[ri].lcontrol.y, 2);
        dpointout(oi, bpptr[ri].value.x,    bpptr[ri].value.y, 2);
        kw_out(oi->s, 56); kw_out(oi->s, 0);
        li++;
      }
    }
    if((!(((oi->o)->fpd).cl)) && (((oi->o)->fpd).ar & 1)) {
      dpointout(oi, (s->pe2).rcontrol.x, (s->pe2).rcontrol.y, 2);
      dpointout(oi, (s->pe).lcontrol.x, (s->pe).lcontrol.y, 2);
      dpointout(oi, (s->pe).value.x, (s->pe).value.y, 2);
      kw_out(oi->s, 56); kw_out(oi->s, 0);
    }
  }
}



/**	Write path for current object.
	@param	oi	EPS output instruction structure.
*/
static void
write_path DK_P1(dkfig_eps_output_instruction *,oi)
{
  kw_out(oi->s, 46); kw_out(oi->s, 0);
  switch((oi->o)->objtype) {
    case DK_FIG_OBJ_ELLIPSE: {
      path_ellipse(oi);
    } break;
    case DK_FIG_OBJ_POLYLINE: {
      path_polyline(oi);
    } break;
    case DK_FIG_OBJ_SPLINE: {
      path_spline(oi);
    } break;
    case DK_FIG_OBJ_ARC: {
      path_arc(oi);
    } break;
  }
  if(((oi->o)->fpd).cl) {
    kw_out(oi->s, 47); kw_out(oi->s, 0);
  }
}



/**	Write path for arrowhead(s).
	@param	oi	EPS output instruction structure.
*/
static void
arrowhead_path DK_P1(dkfig_eps_output_instruction *,oi)
{
  kw_out(oi->s, 46); kw_out(oi->s, 0);
  dpointout(oi, ((oi->a)->p1).x, ((oi->a)->p1).y, 1);
  kw_out(oi->s, 48); kw_out(oi->s, 0);
  dpointout(oi, ((oi->a)->p2).x, ((oi->a)->p2).y, 1);
  kw_out(oi->s, 49); kw_out(oi->s, 0);
  dpointout(oi, ((oi->a)->p3).x, ((oi->a)->p3).y, 1);
  kw_out(oi->s, 49); kw_out(oi->s, 0);
  if((oi->a)->type > 1) {
    dpointout(oi, ((oi->a)->p4).x, ((oi->a)->p4).y, 1);
    kw_out(oi->s, 49); kw_out(oi->s, 0);
  }
  if((oi->a)->type > 0) {
    kw_out(oi->s, 47); kw_out(oi->s, 0);
  }
}



/**	Print arrowhead(s).
	@param	oi	EPS output instruction structure.
	@param	dcc	Color cell to use for arrowheads.
*/
static void
arrowhead_print DK_P2(dkfig_eps_output_instruction *,oi, dk_fig_dcc *,dcc)
{
  set_dash(oi, 0, 0.0);
  set_linecap(oi, 0);
  set_linejoin(oi, (oi->c)->ahlj);
  switch((oi->a)->type) {
    case 0: {
      arrowhead_path(oi);
      kw_out(oi->s, 43); kw_out(oi->s, 0);
    } break;
    default: {
      if((oi->a)->style == 0) {
        dk_fig_dcc xdcc;
	xdcc.red = 1.0; xdcc.green = 1.0; xdcc.blue = 1.0;
        set_color(oi, &xdcc);
      }
      arrowhead_path(oi);
      kw_out(oi->s, 42); kw_out(oi->s, 0);
      if((oi->a)->style == 0) {
        set_color(oi, dcc);
      }
      arrowhead_path(oi);
      kw_out(oi->s, 43); kw_out(oi->s, 0);
    } break;
  }
}



/**	Write instructions for pattern filling.
	@param	oi	EPS output instruction structure.
*/
static void
write_pattern DK_P1(dkfig_eps_output_instruction *,oi)
{
  double patrp;
  dk_fig_bb obb;
  
  if((oi->c)->patrp) {
    patrp = 0.9 * dkma_l_to_double((oi->c)->patrp);
  } else {
    patrp = 3.6;
  }
  patrp = fabs(patrp);
  dkfig_tool_bb_reset(&obb);
  dkfig_tool_bb_add_x(&obb, ccdx(oi, ((oi->o)->dbb).xmin));
  dkfig_tool_bb_add_x(&obb, ccdx(oi, ((oi->o)->dbb).xmax));
  dkfig_tool_bb_add_y(&obb, ccdy(oi, ((oi->o)->dbb).ymin));
  dkfig_tool_bb_add_y(&obb, ccdy(oi, ((oi->o)->dbb).ymax));
  switch((((oi->o)->fpd).af) - 41) {
    case 0: {	/* ThirtyLeft */
      double yat0, ystart, ynew, sf30;
      sf30 = 1.0 / sqrt(3.0);
      patrp = dkma_div_double_ok(patrp,cos(M_PI / 6.0),&(oi->me));
      patrp = drd(patrp, oi->c, 1);
      ystart = dkma_sub_double_ok(
        obb.ymin,
	(sf30 * dkma_sub_double_ok(obb.xmax,obb.xmin,&(oi->me))),
	&(oi->me)
      );
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_add_double_ok(
	  obb.ymin, (sf30 * obb.xmin), &(oi->me)
	);
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp,ynew,&(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1);
      kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);
      kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[0].name);  kw_out(oi->s, 0);
    } break;
    case 1: {	/* ThirtyRight */
      double yat0, ystart, ynew, sf30;	
      sf30 = 1.0 / sqrt(3.0);
      patrp = dkma_div_double_ok(patrp,cos(M_PI / 6.0),&(oi->me));
      patrp = drd(patrp, oi->c, 1); 
      ystart = dkma_sub_double_ok(
        obb.ymin,
	(sf30 * dkma_sub_double_ok(obb.xmax,obb.xmin,&(oi->me))),
	&(oi->me)
      );
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_sub_double_ok(ystart,(sf30 * obb.xmin),&(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp,ynew,&(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[1].name);  kw_out(oi->s, 0);
    } break;
    case 2: {	/* ThirtyHatch */
      double yat0, ystart, ynew, sf30;
      sf30 = 1.0 / sqrt(3.0);
      patrp = dkma_div_double_ok(patrp,cos(M_PI / 6.0), &(oi->me));
      patrp = drd(patrp, oi->c, 1);
      ystart = dkma_sub_double_ok(obb.ymin,(sf30 * (obb.xmax - obb.xmin)),&(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_add_double_ok(obb.ymin,(sf30 * obb.xmin),&(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp,ynew, &(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 0);
      ystart = dkma_sub_double_ok(obb.ymin,(sf30 * (obb.xmax - obb.xmin)),&(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_sub_double_ok(ystart,(sf30 * obb.xmin),&(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp,ynew, &(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[2].name);  kw_out(oi->s, 0);
    } break;
    case 3: {	/* FourtyFiveLeft */
      double yat0, ystart, ynew;
      patrp = dkma_mul_double_ok(patrp,sqrt(2.0),&(oi->me));
      patrp = drd(patrp, oi->c, 1);
      ystart = dkma_sub_double_ok(
        obb.ymin,
	dkma_sub_double_ok(obb.xmax,obb.xmin,&(oi->me)),
        &(oi->me)
      );
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_add_double_ok(obb.ymin,obb.xmin, &(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp, ynew, &(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[3].name);  kw_out(oi->s, 0);
    } break;
    case 4: {	/* FourtyFiveRight */
      double yat0, ystart, ynew;	
      patrp = dkma_mul_double_ok(patrp, sqrt(2.0), &(oi->me));
      patrp = drd(patrp, oi->c, 1); 
      ystart = dkma_sub_double_ok(
        obb.ymin,
	dkma_sub_double_ok(obb.xmax,obb.xmin,&(oi->me)),
	&(oi->me)
      );
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_sub_double_ok(ystart, obb.xmin, &(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp, ynew, &(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[4].name);  kw_out(oi->s, 0);
    } break;
    case 5: {	/* FourtyFiveHatch */
      double yat0, ystart, ynew;	
      patrp = dkma_mul_double_ok(patrp, sqrt(2.0), &(oi->me));
      patrp = drd(patrp, oi->c, 1); 
      ystart = dkma_sub_double_ok(
        obb.ymin,
	dkma_sub_double_ok(obb.xmax,obb.xmin,&(oi->me)),
	&(oi->me)
      );
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_sub_double_ok(ystart, obb.xmin, &(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp, ynew, &(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1); kw_out(oi->s, 0);
      ystart = dkma_sub_double_ok(
        obb.ymin,
	dkma_sub_double_ok(obb.xmax,obb.xmin,&(oi->me)),
        &(oi->me)
      );
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        yat0 = dkma_add_double_ok(obb.ymin,obb.xmin, &(oi->me));
	ynew = floor(dkma_div_double_ok(yat0,patrp,&(oi->me)));
	ynew = dkma_mul_double_ok(patrp, ynew, &(oi->me));
	ynew = dkma_sub_double_ok(yat0, ynew, &(oi->me));
	ystart = dkma_sub_double_ok(ystart, ynew, &(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[5].name);  kw_out(oi->s, 0);
    } break;
    case 6: {	/* HorizontalBricks */
      double ystart, xstart, pr2;
      patrp = dkma_mul_double_ok(2.0,patrp, &(oi->me));
      ystart = obb.ymin; xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        pr2 = dkma_mul_double_ok(2.0,patrp, &(oi->me));
        ystart = floor(dkma_div_double_ok(ystart,pr2,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,pr2,&(oi->me));
	xstart = floor(dkma_div_double_ok(xstart,pr2,&(oi->me)));
	xstart =  dkma_mul_double_ok(xstart,pr2, &(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[6].name);  kw_out(oi->s, 0);
    } break;
    case 7: {	/* VerticalBricks */
      double xstart, ystart, pr2;
      patrp = dkma_mul_double_ok(2.0,patrp, &(oi->me));
      xstart = obb.xmin; ystart = obb.ymin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        pr2 = dkma_mul_double_ok(2.0,patrp, &(oi->me));
        xstart = floor(dkma_div_double_ok(xstart,pr2,&(oi->me)));
	xstart = dkma_mul_double_ok(xstart,pr2,&(oi->me));
	ystart = floor(dkma_div_double_ok(ystart,pr2,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,pr2,&(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[7].name); kw_out(oi->s, 0);
    } break;
    case 8: {	/* HorizontalLines */
      double ystart;
      ystart = obb.ymin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        ystart = floor(dkma_div_double_ok(ystart,patrp,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,patrp,&(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[8].name); kw_out(oi->s, 0);
    } break;
    case 9: {	/* VerticalLines */
      double xstart;
      xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        xstart = floor(dkma_div_double_ok(xstart,patrp,&(oi->me)));
	xstart = dkma_mul_double_ok(xstart,patrp,&(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 2);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[9].name); kw_out(oi->s, 0);
    } break;
    case 10: {	/* Crosshatch */
      double ystart, xstart;
      ystart = obb.ymin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        ystart = floor(dkma_div_double_ok(ystart,patrp,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,patrp,&(oi->me));
      }
      stream_putdouble(oi->s, obb.xmin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1); kw_out(oi->s, 0);
      xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        xstart = floor(dkma_div_double_ok(xstart,patrp,&(oi->me)));
	xstart = dkma_mul_double_ok(xstart,patrp,&(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymin, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[10].name); kw_out(oi->s, 0);
    } break;
    case 11: {	/* ShinglesRight */
      double ystart, xstart, pr2;
      patrp = dkma_mul_double_ok(2.0,patrp, &(oi->me));
      ystart = obb.ymin; xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        pr2 = dkma_mul_double_ok(4.0,patrp, &(oi->me));
        ystart = floor(dkma_div_double_ok(ystart,pr2,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,pr2,&(oi->me));
	pr2 = dkma_mul_double_ok(2.0,patrp, &(oi->me));
	xstart = floor(dkma_div_double_ok(xstart,pr2,&(oi->me)));
	xstart =  dkma_mul_double_ok(xstart,pr2, &(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[11].name);  kw_out(oi->s, 0);
    } break;
    case 12: {	/* ShinglesLeft */
      double ystart, xstart, pr2;
      patrp = dkma_mul_double_ok(2.0,patrp, &(oi->me));
      ystart = obb.ymin; xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        pr2 = dkma_mul_double_ok(4.0,patrp, &(oi->me));
        ystart = floor(dkma_div_double_ok(ystart,pr2,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,pr2,&(oi->me));
	pr2 = dkma_mul_double_ok(2.0,patrp, &(oi->me));
	xstart = floor(dkma_div_double_ok(xstart,pr2,&(oi->me)));
	xstart =  dkma_mul_double_ok(xstart,pr2, &(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[12].name);  kw_out(oi->s, 0);
    } break;
    case 13: {	/* Vshingles1 */
      double ystart, xstart, pr2;
      patrp = dkma_mul_double_ok(2.0,patrp, &(oi->me));
      ystart = obb.ymin; xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        pr2 = dkma_mul_double_ok(2.0,patrp, &(oi->me));
	ystart = floor(dkma_div_double_ok(ystart,pr2,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,pr2,&(oi->me));
	pr2 = dkma_mul_double_ok(4.0,patrp, &(oi->me));
	xstart = floor(dkma_div_double_ok(xstart,pr2,&(oi->me)));
	xstart =  dkma_mul_double_ok(xstart,pr2, &(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[13].name);  kw_out(oi->s, 0);
    } break;
    case 14: {	/* Vshingles2 */
      double ystart, xstart, pr2;
      patrp = dkma_mul_double_ok(2.0,patrp, &(oi->me));
      ystart = obb.ymin; xstart = obb.xmin;
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        pr2 = dkma_mul_double_ok(2.0,patrp, &(oi->me));
	ystart = floor(dkma_div_double_ok(ystart,pr2,&(oi->me)));
	ystart = dkma_mul_double_ok(ystart,pr2,&(oi->me));
	pr2 = dkma_mul_double_ok(4.0,patrp, &(oi->me));
	xstart = floor(dkma_div_double_ok(xstart,pr2,&(oi->me)));
	xstart =  dkma_mul_double_ok(xstart,pr2, &(oi->me));
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1);   kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1);    kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[14].name);  kw_out(oi->s, 0);
    } break;
    case 15: {	/* FishScales */
      double alpha, deltax, deltay, xstart, ystart;
      alpha = 1.881618;
      patrp = dkma_mul_double_ok(2.5,patrp, &(oi->me));
      deltax = patrp * sin(0.5*alpha);
      deltax = dkma_mul_double_ok(2.0,deltax,&(oi->me));
      deltay = patrp * (1.0 - cos(0.5*alpha));
      alpha  = dkma_mul_double_ok(
        90.0,
	dkma_div_double_ok(alpha, M_PI, &(oi->me)),
	&(oi->me)
      );
      alpha = drd(alpha, oi->c, 2);
      xstart = dkma_sub_double_ok(
        obb.xmin,
	dkma_mul_double_ok(1.5,deltax,&(oi->me)),
	&(oi->me)
      );
      ystart = dkma_sub_double_ok(obb.ymin, deltay, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        xstart = floor(dkma_div_double_ok(xstart,deltax,&(oi->me)));
	xstart = dkma_mul_double_ok(xstart,deltax,&(oi->me));
	ystart = floor(
	  dkma_div_double_ok(
	    xstart,
	    dkma_mul_double_ok(deltay,2.0,&(oi->me)),
	    &(oi->me)
	  )
	);
	ystart = dkma_mul_double_ok(
	  ystart,dkma_mul_double_ok(2.0,deltay,&(oi->me)),&(oi->me)
	);
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltay, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(
        oi->s, dkma_sub_double_ok(270.0, alpha, &(oi->me)),
	oi->c, 1
      );
      kw_out(oi->s, 1);
      stream_putdouble(
        oi->s, dkma_add_double_ok(270.0, alpha, &(oi->me)),
	oi->c, 1
      );
      kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[15].name); kw_out(oi->s, 0);
    } break;
    case 16: {	/* SmallFishScales */
      double alpha, deltax, deltay, xstart, ystart;
      alpha = M_PI;
      deltax = patrp * sin(0.5*alpha);
      deltax = dkma_mul_double_ok(2.0,deltax,&(oi->me));
      deltay = patrp * (1.0 - cos(0.5*alpha));
      alpha  = dkma_mul_double_ok(
        90.0,
	dkma_div_double_ok(alpha, M_PI, &(oi->me)),
	&(oi->me)
      );
      alpha = drd(alpha, oi->c, 2);
      xstart = dkma_sub_double_ok(
        obb.xmin,
	dkma_mul_double_ok(1.5,deltax,&(oi->me)),
	&(oi->me)
      );
      ystart = dkma_sub_double_ok(obb.ymin, deltay, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        xstart = floor(dkma_div_double_ok(xstart,deltax,&(oi->me)));
	xstart = dkma_mul_double_ok(xstart,deltax,&(oi->me));
	ystart = floor(
	  dkma_div_double_ok(
	    xstart,
	    dkma_mul_double_ok(deltay,2.0,&(oi->me)),
	    &(oi->me)
	  )
	);
	ystart = dkma_mul_double_ok(
	  ystart,dkma_mul_double_ok(2.0,deltay,&(oi->me)),&(oi->me)
	);
      }
      stream_putdouble(oi->s, xstart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, ystart, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltay, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(
        oi->s, dkma_sub_double_ok(270.0, alpha, &(oi->me)),
	oi->c, 1
      );
      kw_out(oi->s, 1);
      stream_putdouble(
        oi->s, dkma_add_double_ok(270.0, alpha, &(oi->me)),
	oi->c, 1
      );
      kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[16].name); kw_out(oi->s, 0);
    } break;
    case 17: {	/* Circles */
      double deltax, startx, starty;
      patrp = dkma_mul_double_ok(2.0, patrp, &(oi->me));
      deltax = dkma_mul_double_ok(2.0, patrp, &(oi->me));
      startx = dkma_sub_double_ok(obb.xmin, deltax, &(oi->me));
      starty = dkma_sub_double_ok(obb.ymin, deltax, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        startx = floor(dkma_div_double_ok(startx,deltax,&(oi->me)));
	startx = dkma_mul_double_ok(startx,deltax,&(oi->me));
	starty = floor(dkma_div_double_ok(starty,deltax,&(oi->me)));
	starty = dkma_mul_double_ok(starty,deltax,&(oi->me));
      }
      stream_putdouble(oi->s, startx, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, starty, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, patrp, oi->c, 1); kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[17].name); kw_out(oi->s, 0);
    } break;
    case 18: {	/* Hexagons */
      double r, deltax, deltay, startx, starty;
      r = dkma_mul_double_ok(patrp, 2.0, &(oi->me));
      /* deltay = dkma_mul_double_ok(2.0, r, &(oi->me)) / sqrt(3.0); */
      deltay = dkma_mul_double_ok(2.0, r, &(oi->me));
      deltay = deltay * sqrt(3.0/4.0);
      deltax = dkma_mul_double_ok(3.0, r, &(oi->me));
      startx = dkma_sub_double_ok(obb.xmin, deltax, &(oi->me));
      starty = dkma_sub_double_ok(obb.ymin, deltay, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        startx = floor(dkma_div_double_ok(startx,deltax,&(oi->me)));
	startx = dkma_mul_double_ok(startx,deltax,&(oi->me));
	starty = floor(dkma_div_double_ok(starty,deltay,&(oi->me)));
	starty = dkma_mul_double_ok(starty,deltay,&(oi->me));
      }
      stream_putdouble(oi->s, startx, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, starty, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltay, oi->c, 1); kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[18].name); kw_out(oi->s, 0);
    } break;
    case 19: {	/* Octagons */
      double deltax, corner, startx, starty;
      deltax = dkma_mul_double_ok(patrp, 2.0, &(oi->me));
      corner = deltax / (2.0+sqrt(2.0));
      startx = dkma_sub_double_ok(obb.xmin, deltax, &(oi->me));
      starty = dkma_sub_double_ok(obb.ymin, deltax, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        startx = floor(dkma_div_double_ok(startx,deltax,&(oi->me)));
	startx = dkma_mul_double_ok(startx,deltax,&(oi->me));
	starty = floor(dkma_div_double_ok(starty,deltax,&(oi->me)));
	starty = dkma_mul_double_ok(starty,deltax,&(oi->me));
      }
      stream_putdouble(oi->s, startx, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, starty, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, corner, oi->c, 1); kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[19].name); kw_out(oi->s, 0);
    } break;
    case 20: {	/* HorizontalTires */
      double deltax, startx, starty;
      deltax = dkma_mul_double_ok(patrp, 2.0, &(oi->me));
      startx = dkma_sub_double_ok(obb.xmin, deltax, &(oi->me));
      starty = dkma_sub_double_ok(obb.ymin, deltax, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        startx = floor(dkma_div_double_ok(startx,deltax,&(oi->me)));
	startx = dkma_mul_double_ok(startx,deltax,&(oi->me));
	starty = floor(dkma_div_double_ok(starty,deltax,&(oi->me)));
	starty = dkma_mul_double_ok(starty,deltax,&(oi->me));
      }
      stream_putdouble(oi->s, startx, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, starty, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltax, oi->c, 1); kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[20].name); kw_out(oi->s, 0);
    } break;
    case 21: {	/* VerticalTires */
      double deltax, startx, starty;
      deltax = dkma_mul_double_ok(patrp, 2.0, &(oi->me));
      startx = dkma_sub_double_ok(obb.xmin, deltax, &(oi->me));
      starty = dkma_sub_double_ok(obb.ymin, deltax, &(oi->me));
      if(((oi->c)->opt1) & DKFIG_OPT_FILL_CONTIGOUS) {
        startx = floor(dkma_div_double_ok(startx,deltax,&(oi->me)));
	startx = dkma_mul_double_ok(startx,deltax,&(oi->me));
	starty = floor(dkma_div_double_ok(starty,deltax,&(oi->me)));
	starty = dkma_mul_double_ok(starty,deltax,&(oi->me));
      }
      stream_putdouble(oi->s, startx, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.xmax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, starty, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, obb.ymax, oi->c, 1); kw_out(oi->s, 1);
      stream_putdouble(oi->s, deltax, oi->c, 1); kw_out(oi->s, 1);
      dkstream_puts(oi->s, pd[21].name); kw_out(oi->s, 0);
    } break;
  }
  
}



/**	Print non-text object.
	@param	oi	EPS output instruction structure.
*/
static int
print_path_object DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  int must_draw;
  dk_fig_dcc dcc;
  double lw;
  
  if(((oi->o)->fpd).cl) {
    if(dkfig_tool_must_fill(((oi->o)->fpd).af, (oi->c)->opt1)
       || dkfig_tool_must_pattern(((oi->o)->fpd).af, (oi->c)->opt1))
    {
      must_draw = 1;
      if((oi->o)->objtype == DK_FIG_OBJ_POLYLINE) {
        if((oi->o)->subtype == 5) {
	  if(!(((oi->c)->opt1) & DKFIG_OPT_FILL_BITMAP_AREA)) {
	    must_draw = 0;
	  }
        }
      }
      /* 2009/05/08 + The background rectangle must not be filled. */
      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->o, wbgr)) { must_draw = 0; }
      } /* 2009/05/08 - */
      if(must_draw) {
        if(((oi->o)->fpd).fc != (oi->d)->transparent) {
          
          dkfig_tool_fill_dcc(oi->d, &dcc, ((oi->o)->fpd).fc);
          dkfig_tool_correct_dcc(&dcc, ((oi->o)->fpd).fc, ((oi->o)->fpd).af);
	  dkfig_eps_correct_for_palette(&dcc);
	  set_color(oi, &dcc);
	  set_linecap(oi, ((oi->o)->fpd).cs);
	  set_linejoin(oi, ((oi->o)->fpd).js);
	  if(ctm_change(oi)) { kw_out(oi->s, 74); kw_out(oi->s, 0); }
	  write_path(oi);
	  kw_out(oi->s, 42); kw_out(oi->s, 0);
	  if(ctm_change(oi)) { kw_out(oi->s, 75); kw_out(oi->s, 0); }
        }
        if(dkfig_tool_must_pattern(((oi->o)->fpd).af, (oi->c)->opt1)) {
          if(((oi->o)->fpd).pc != (oi->d)->transparent) {
	    
            dkfig_tool_fill_dcc(oi->d, &dcc, ((oi->o)->fpd).pc);
            dkfig_eps_correct_for_palette(&dcc);
            set_color(oi, &dcc);
	    lw = get_object_linewidth(oi, 1);
	    set_linewidth(oi, lw);
	    set_linecap(oi, ((oi->o)->fpd).cs);
	    set_linejoin(oi, ((oi->o)->fpd).js);
	    kw_out(oi->s, 44); kw_out(oi->s, 0);
	    if(ctm_change(oi)) { kw_out(oi->s, 74); kw_out(oi->s, 0); }
	    write_path(oi);
	    kw_out(oi->s, 63); kw_out(oi->s, 0);
	    if(ctm_change(oi)) { kw_out(oi->s, 75); kw_out(oi->s, 0); }
	    write_pattern(oi);
	    kw_out(oi->s, 45); kw_out(oi->s, 0);
	  }
        }
      }
    }
    /* image in the image box */
    if((oi->o)->objtype == DK_FIG_OBJ_POLYLINE) {
      if((oi->o)->subtype == 5) {
        
	if((oi->o)->drve) {	
	  if(!insert_image(oi)) {
	    back = 0;
	  }
	} else {		
	}
      }
    }
  }
  must_draw = 1;
  if((oi->o)->objtype == DK_FIG_OBJ_POLYLINE) {
    if((oi->o)->subtype == 5) {
      if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_BITMAP_BORDER) {
        must_draw = 0;
      }
    }
  }
  if(((oi->c)->opt1) & DKFIG_OPT_REMOVE_THIN_BORDERS) {
    if(((oi->o)->fpd).lt == 0L) {
      if(((oi->o)->fpd).cl) {
        if(dkfig_tool_must_fill(((oi->o)->fpd).af, (oi->c)->opt1)) {
	  must_draw = 0; 
	}
	if(dkfig_tool_must_pattern(((oi->o)->fpd).af, (oi->c)->opt1)) {
	  must_draw = 0; 
	}
	if((oi->o)->objtype == DK_FIG_OBJ_POLYLINE) {
	  if((oi->o)->subtype == 5) {
	    must_draw = 0;
	  }
	}
      }
    }
  }
  if(((oi->o)->fpd).pc == (oi->d)->transparent) {
    must_draw = 0; 
  }
  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->o, wbgr)) { must_draw = 0; }
  }
  if(must_draw) { 
    dkfig_tool_fill_dcc(oi->d, &dcc, ((oi->o)->fpd).pc);
    dkfig_eps_correct_for_palette(&dcc);
    set_color(oi, &dcc);
    lw = get_object_linewidth(oi, 0);
    set_linewidth(oi, lw);
    set_dash(oi, ((oi->o)->fpd).ls, ((oi->o)->fpd).sv);
    set_linecap(oi, ((oi->o)->fpd).cs);
    set_linejoin(oi, ((oi->o)->fpd).js);
    if(ctm_change(oi)) { kw_out(oi->s, 74); kw_out(oi->s, 0); }
    write_path(oi);
    kw_out(oi->s, 43); kw_out(oi->s, 0);
    if(ctm_change(oi)) { kw_out(oi->s, 75); kw_out(oi->s, 0); }
    if((((oi->o)->fpd).ar) & 1) {
      oi->a = &(((oi->o)->fpd).ahf);
      arrowhead_print(oi, &dcc);
    }
    if((((oi->o)->fpd).ar) & 2) {
      oi->a = &(((oi->o)->fpd).ahb);
      arrowhead_print(oi, &dcc);
    }
    oi->a = NULL;
  }
  
  return back;
}



/**	Process current object.
	@param	oi	EPS output instruction structure.
*/
static int
process_object DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  
  switch((oi->o)->objtype) {
    case DK_FIG_OBJ_TEXT: {
      back = print_text_object(oi);
    } break;
    case DK_FIG_OBJ_ELLIPSE:
    case DK_FIG_OBJ_POLYLINE:
    case DK_FIG_OBJ_SPLINE:
    case DK_FIG_OBJ_ARC: {
      back = print_path_object(oi);
    } break;
    default: {		
    } break;
  } 
  return back;
}



/**	Write undef instruction for string to release PS memory.
	@param	oi	EPS output instruction structure.
	@param	bmw	Bitmap width structure.
	@param	nr	Number of string to undef.
*/
static void
undef_string DK_P3(dkfig_eps_output_instruction *,oi, dkfig_bitmap_width *,bmw, int,nr)
{
  kw_out(oi->s, 102); kw_out(oi->s, 1);
  kw_out(oi->s, 29); kw_out(oi->s, 77);
  switch(nr) {
    case 1: { kw_out(oi->s, 94); } break;
    case 2: { kw_out(oi->s, 95); } break;
    case 3: { kw_out(oi->s, 96); } break;
  }
  dkfig_tool_num_as_string(oi->s, bmw->number, oi->allimw);
  kw_out(oi->s, 1);
  kw_out(oi->s, 103); kw_out(oi->s, 0);
}



/**	Pass to process contents (write output).
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
contents_pass DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1, need_filter = 0, dictused = 0;
  dk_fig_object *o;
  dkfig_bitmap_width *bmw;
  /* dk_fig_conversion backupc; */
  unsigned long backupopt1, backupopt2;
  int backupia;
  
  if((oi->iw) && (oi->iwi)) {
    if(oi->numimw) {
      if(((oi->c)->opt1) & DKFIG_OPT_BITMAP_DICTIONARY) {
        unsigned long dictlgt;
	dictused = 1;
        dictlgt = dkma_add_ulong_ok(
          1UL,
	  dkma_mul_ulong_ok(
	    3UL,
	    oi->numimw,
	    &(oi->me)
	  ),
          &(oi->me)
        );
        stream_putul(oi->s, dictlgt); kw_out(oi->s, 1);
	kw_out(oi->s, 98); kw_out(oi->s, 1);
	kw_out(oi->s, 99); kw_out(oi->s, 0);
      }
    }
    dksto_it_reset(oi->iwi);
    while((bmw = (dkfig_bitmap_width *)dksto_it_next(oi->iwi)) != NULL) {
      need_filter = 1;
      
      if((bmw->seprgb) && (bmw->colored) && ((oi->c)->psl > 1)) {
        kw_out(oi->s, 29); kw_out(oi->s, 77); kw_out(oi->s, 94);
        dkfig_tool_num_as_string(oi->s, bmw->number, oi->allimw);
        kw_out(oi->s, 1);
        stream_putul(
	  oi->s,
	  dkma_mul_ulong_ok(
	    (unsigned long)(bmw->width),
	    (unsigned long)(bmw->height),
	    &(oi->me)
	  )
	);
        kw_out(oi->s, 1); kw_out(oi->s, 78); kw_out(oi->s, 1);
        kw_out(oi->s, 31); kw_out(oi->s, 0);
        kw_out(oi->s, 29); kw_out(oi->s, 77); kw_out(oi->s, 95);
        dkfig_tool_num_as_string(oi->s, bmw->number, oi->allimw);
        kw_out(oi->s, 1);
        stream_putul(
	  oi->s,
	  dkma_mul_ulong_ok(
	    (unsigned long)(bmw->width),
	    (unsigned long)(bmw->height),
	    &(oi->me)
	  )
	);
        kw_out(oi->s, 1); kw_out(oi->s, 78); kw_out(oi->s, 1);
        kw_out(oi->s, 31); kw_out(oi->s, 0);
        kw_out(oi->s, 29); kw_out(oi->s, 77); kw_out(oi->s, 96);
        dkfig_tool_num_as_string(oi->s, bmw->number, oi->allimw);
        kw_out(oi->s, 1);
        stream_putul(
	  oi->s,
	  dkma_mul_ulong_ok(
	    (unsigned long)(bmw->width),
	    (unsigned long)(bmw->height),
	    &(oi->me)
	  )
	);
        kw_out(oi->s, 1); kw_out(oi->s, 78); kw_out(oi->s, 1);
        kw_out(oi->s, 31); kw_out(oi->s, 0);
      } else {
        kw_out(oi->s, 29); kw_out(oi->s, 77);
        dkfig_tool_num_as_string(oi->s, bmw->number, oi->allimw);
        kw_out(oi->s, 1);
        stream_putul(
	  oi->s,
	  dkma_mul_ulong_ok(
	    (unsigned long)(bmw->width),
	    ((bmw->colored) ? 3UL : 1UL),
	    &(oi->me)
	  )
	);
        kw_out(oi->s, 1); kw_out(oi->s, 78); kw_out(oi->s, 1);
        kw_out(oi->s, 31); kw_out(oi->s, 0);
      }
    }
  }
  dksto_it_reset(oi->fli);
  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->o = o; oi->me = 0;
    /* DK_MEMCPY(&backupc,oi->c,sizeof(dk_fig_conversion)) ; */
    backupopt1 = (oi->c)->opt1;
    backupopt2 = (oi->c)->opt2;
    backupia = (oi->c)->image_align;
    handle_special_comments(oi,o);
    if(((oi->c)->opt1) & DKFIG_OPT_VERBOSE_OUTPUT) {
      kw_out(oi->s, 37); kw_out(oi->s, 1);
      stream_putul(oi->s, o->lineno);
      kw_out(oi->s, 0);
    }
    if(!process_object(oi)) {
      back = 0;
    }
    if(oi->me) {
      back = 0;
      
      dkfig_tool2_eps_error_message(oi, 13);
    }
    /* DK_MEMCPY(oi->c,&backupc,sizeof(dk_fig_conversion)) ; */
    (oi->c)->opt2 = backupopt2;
    (oi->c)->opt1 = backupopt1;
    (oi->c)->image_align = backupia;
    oi->o = NULL;
    if((oi->c)->app) {
      dkapp_set_source_lineno((oi->c)->app, 0UL);
    }
  }
  oi->spcpass += 1;
  if((oi->iw) && (oi->iwi)) {
    if(oi->numimw) {
      if(((oi->c)->opt1) & DKFIG_OPT_BITMAP_DICTIONARY) {
        kw_out(oi->s, 100); kw_out(oi->s, 0);
      }
    }
  }
  if((oi->c)->psl > 1) {
    if(!dictused) {
      if((oi->iw) && (oi->iwi)) {
        dksto_it_reset(oi->iwi);
        while((bmw = (dkfig_bitmap_width *)dksto_it_next(oi->iwi)) != NULL) {
          if((bmw->seprgb) && (bmw->colored) && ((oi->c)->psl > 1)) {
	    undef_string(oi, bmw, 1);
	    undef_string(oi, bmw, 2);
	    undef_string(oi, bmw, 3);
	  } else {
	    undef_string(oi, bmw, 0);
	  }
	}
      }
    }
    if(((oi->c)->opt1) & DKFIG_OPT_GARBAGE_COLLECTION) {
      kw_out(oi->s, 101); kw_out(oi->s, 0);
    }
  }
  
  return back;
}



/**	Write a procset to output.
	@param	oi	EPS output instruction structure.
	@param	pname	Procset name.
	@param	v1	Procset version.
	@param	v2	Procset revision.
	@param	fn	File name.
	@return	1 on success, 0 on error.
*/
static int
write_procset DK_P5(dkfig_eps_output_instruction *,oi, char *,pname, char *,v1, char *,v2, char *,fn)
{
  int back = 0;
  char buffer[256];
  char *filename;
  FILE *fipo;
  if((oi->c)->dscl) {
    if((oi->c)->dscl > DKFIG_DSC_OLD) {
      kw_out(oi->s, 20);
      dkstream_puts(oi->s, pname);
      kw_out(oi->s, 1);
      dkstream_puts(oi->s, v1);
    } else {
      kw_out(oi->s, 18);
      dkstream_puts(oi->s, pname);
      kw_out(oi->s, 1);
      dkstream_puts(oi->s, v2);
    }
    kw_out(oi->s, 1);
    dkstream_puts(oi->s, v2); kw_out(oi->s, 0);
  }
  filename = NULL;
  if((oi->c)->app) {
    filename = dkapp_find_file_dup((oi->c)->app, fn);
  }
  if(filename) {
    if((oi->c)->app) {
      fipo = dkapp_fopen((oi->c)->app, filename, str_open_read);
    } else {
      fipo = dksf_fopen(filename, str_open_read);
    }
    if(fipo) {
      back = 1; /* success */
      while(fgets(buffer, sizeof(buffer), fipo)) {
        dkstr_chomp(buffer, NULL);
	dkstream_puts(oi->s, buffer);
	kw_out(oi->s, 0);
      }
      fclose(fipo); fipo = NULL;
    } else {
      
      if((oi->c)->app) {
        dkapp_err_fopenr((oi->c)->app, filename);
      }
    }
    dk_delete(filename); filename = NULL;
  } else {
    
    if((oi->c)->app) {
      dkapp_err_no_such_file((oi->c)->app, fn);
    }
  }
  if((oi->c)->dscl) {
    if((oi->c)->dscl > DKFIG_DSC_OLD) {
      kw_out(oi->s, 21);
    } else {
      kw_out(oi->s, 19);
    }
    kw_out(oi->s, 0);
  }
  return back;
}



/**	Print PS font-reencoding function.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
print_ps_font_re_encoding DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  int i, nr;
  /* procset for font re-encoding */
  if((oi->flags & OI_FLAG_FONT_RE_ENCODING) || (DKFIG_ALWAYS_RE_ENCODE)) {
    i = write_procset(
      oi,
      kw[22],
      ((((oi->c)->psl) > 1) ? kw[25] : kw[23] ),
      ((((oi->c)->psl) > 1) ? kw[26] : kw[24] ),
      ((((oi->c)->psl) > 1) ? new_fre_proc_file : old_fre_proc_file)
    );
    if(!i) { back = 0; }
  }
  /* procset for aligned text */
  if((oi->flags) & OI_FLAG_ALIGNED_TEXT) {
    i = write_procset(
      oi, kw[67], kw[23], kw[24], f2v_aligned_text_procset
    );
    if(!i) { back = 0; }
  }
  /* procsets for patterns */
  for(nr = 0; nr < DKFIG_NUMBER_OF_PATTERNS; nr++) {
    if((oi->patused)[nr]) {
      i = write_procset(
        oi,
	pd[nr].filename,
	pd[nr].version,
	pd[nr].revision,
	pd[nr].filename
      );
      if(!i) { back = 0; }
    }
  }
  return back;
}


/**	Check list of needed fonts.
	If at least one font is needed, the font reencoding
	procedure must be written to output.
	@param	oi	EPS output instruction structure.
*/
static void
check_list_of_needed_fonts DK_P1(dkfig_eps_output_instruction *,oi)
{
  int i;
  for(i = 0; i < 35; i++) {
    if((oi->fnused)[i]) {
      oi->flags |= OI_FLAG_FONT_RE_ENCODING;
    }
  }
}


/**	Print list of needed fonts.
	@param	oi	EPS output instruction structure.
*/
static void
print_list_of_needed_fonts DK_P1(dkfig_eps_output_instruction *,oi)
{
  int isfirst = 1, i;
  for(i = 0; i < 35; i++) {
    if((oi->fnused)[i]) {
      oi->flags |= OI_FLAG_FONT_RE_ENCODING;
      oi->flags |= OI_FLAG_DOCUMENT_SETUP;
      if(isfirst) {
        if((oi->c)->dscl > DKFIG_DSC_OLD) {
	  kw_out(oi->s, 13); kw_out(oi->s, 14);
	} else {
	  kw_out(oi->s, 12);
	}
      } else {
        kw_out(oi->s, 15);
        if((oi->c)->dscl > DKFIG_DSC_OLD) {
	  kw_out(oi->s, 14);
	}
      }
      dkstream_puts(oi->s, dkfont_get_ps_name(i));
      kw_out(oi->s, 0);
      isfirst = 0;
    }
  }
}



/**	Print filename without the suffix to the stream.
	@param	s	Stream to write to.
	@param	fn	File name.
*/
static void
filename_without_suffix DK_P2(dk_stream_t *,s, char *,fn)
{
  char *p1, *p2;
  if(fn) {
    p1 = fn; p2 = NULL;
    while(*p1) {
      if(*p1 == '.') {
        if(p2) {
	  dkstream_write(s, p2++, 1);
	  while((*p2) && (*p2 != '.')) {
	    dkstream_write(s, p2++, 1);
	  }
	}
	p2 = p1;
      } else {
        if(!p2) {
	  dkstream_write(s, p1, 1);
	}
      }
      p1++;
    }
  } else {
    kw_out(s, 112);
  }
}



/**	Print packages for default preamble.
	@param	oi	EPS output instruction structure.
*/
static
void my_preamble_additions DK_P1(dkfig_eps_output_instruction *,oi)
{
  size_t start, end, i;
  start = 134; end = 152;
  kw_out(oi->s, 129); kw_out(oi->s, 128);
  kw_out(oi->s, 130); kw_out(oi->s, 128);
  kw_out(oi->s, 131); kw_out(oi->s, 128);
  kw_out(oi->s, 124);
  kw_out(oi->s, 125);
  kw_out(oi->s, 82);
  kw_out(oi->s, 81);
  dkstream_puts_ul(
    oi->s,
    dkma_double_to_ul_ok(
      dkma_sub_double_ok(oi->xright, oi->xleft, &(oi->me)),
      &(oi->me)
    )
  );
  kw_out(oi->s, 127);
  kw_out(oi->s, 82);
  kw_out(oi->s, 128);
  kw_out(oi->s, 124);
  kw_out(oi->s, 126);
  kw_out(oi->s, 82);
  kw_out(oi->s, 81);
  dkstream_puts_ul(
    oi->s,
    dkma_double_to_ul_ok(
      dkma_sub_double_ok(oi->ytop, oi->ybottom, &(oi->me)),
      &(oi->me)
    )
  );
  kw_out(oi->s, 127);
  kw_out(oi->s, 82);
  kw_out(oi->s, 128);
  for(i = start; i <= end; i++) {
    kw_out(oi->s, i);
    kw_out(oi->s, 128);
  }
  if(((oi->d)->opt2) & DKFIG_OPT_HAVE_ALPHA_CHANNEL) {
    kw_out(oi->s, 157); kw_out(oi->s, 128);
  }
  kw_out(oi->s, 132); kw_out(oi->s, 128);
}


/**	Write TeX output to include image to stream
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
first_picture DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  char *fn = NULL; /* file name for includegraphics */
  char *xn = NULL;
  if(((oi->c)->opt2) & DKFIG_OPT_FULL_TEX_FILE) {
    if(!dkfig_dt_tex_preamble(oi->c, oi->s)) {
      back = 0;
    }
    my_preamble_additions(oi);
  }
  
  kw_out(oi->s, 107); kw_out(oi->s, 108); kw_out(oi->s, 128);
  if((oi->c)->ifn2) {		
    fn = (oi->c)->ifn2;
  }
  if(fn) {			
#if DK_HAVE_FEATURE_BACKSLASH
    xn = dkstr_rchr(fn, '\\');
#else
    xn = dkstr_rchr(fn, '/');
#endif
  }
  if(xn) {			
    fn = xn;
    fn++;
  }
  if(!fn) {
    kw_out(oi->s, 110); kw_out(oi->s, 128);
  }
  kw_out(oi->s, 111);
  if((oi->c)->incg) {
    dkstream_puts(oi->s, (oi->c)->incg);
  } else {
    filename_without_suffix(oi->s, fn);
  }
  kw_out(oi->s, 82);  kw_out(oi->s, 128);
  kw_out(oi->s, 109); kw_out(oi->s, 128);
  
  return back;
}



/**	Font definitions and commands for the second picture in the TeX output.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
picture_settings DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  
  /* ##### */
  
  return back;
}



/**	Process one text object (TeX output driver).
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
process_tex_text DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  int use_color = 1;
  dk_fig_text *t;
  int did_rotate;
  double dv;
  dk_fig_dcc dcc;
  int th;
  char *ptr;
  
  t = (dk_fig_text *)((oi->o)->data);
  if(t) {
    if(t->font_handling) {
      back = 1;
      switch((t->font_handling)->handling) {
        case 2: case 3: case 4: case 5: {	
	  th = (((t->font_flags) & 2) ? ((oi->c)->special_text) : ((oi->c)->normal_text));
	  did_rotate = 0;
	  dkfig_tool_fill_dcc(oi->d, &dcc, ((oi->o)->fpd).pc);
	  kw_out(oi->s, 115); kw_out(oi->s, 71);
	  /* placement */
	  dkstream_puts_double(oi->s, drd(ccdx(oi, t->x), oi->c, 1));
	  kw_out(oi->s, 114);
	  dkstream_puts_double(oi->s, drd(ccdy(oi, t->y), oi->c, 1));
	  kw_out(oi->s, 72);
	  kw_out(oi->s, 81);
	  if(fabs(t->angle) > DKFIG_EPSILON) {
	    did_rotate = 1;
	    kw_out(oi->s, 118);
	    kw_out(oi->s, 81);
	    /* rotation in degree */
	    dv = (180.0 * t->angle) / M_PI;
	    dv = drd(dv, oi->c, 1);
	    dkstream_puts_double(oi->s, dv);
	    kw_out(oi->s, 82);
	    kw_out(oi->s, 81);
	  }
	  kw_out(oi->s, 116);		/* makebox */
	  kw_out(oi->s, 108);		/* (0,0) */
	  kw_out(oi->s, 61);		/* [ */
	  /* alignment */
	  switch(((oi->o)->fpd).st) {
	    case 1: {	/* top -> b */
	      kw_out(oi->s, 119);
	    } break;
	    case 2: {	/* ulft -> rb */
	      kw_out(oi->s, 120);
	    } break;
	    default: {	/* urt -> lb */
	      kw_out(oi->s, 121);
	    } break;
	  }
	  kw_out(oi->s, 62);		/* ] */
	  kw_out(oi->s, 81);		/* { */
	  kw_out(oi->s, 117);		/* smash */
	  kw_out(oi->s, 81);		/* { */
	  if(th & DKFIG_TH_MBOX) {
	    kw_out(oi->s, 123); kw_out(oi->s, 81);
	  }
	  if((t->font_handling)->handling != 2) {
	    dkfig_dt_write_fontname(oi->s, oi->d, t->font_handling);
	    kw_out(oi->s, 81);
	    kw_out(oi->s, 82);
	  }
	  if(oi->c) {
	    if(!(((oi->c)->opt2) & DKFIG_OPT_COLOR)) {
	      use_color = 0;
	    }
	  }
	  if(use_color) {
	    kw_out(oi->s, 122);
	    kw_out(oi->s, 81);
	    /* color */
	    dv = dcc.red;
	    dv = drd(dv, oi->c, 0);
	    dkstream_puts_double(oi->s, dv);
	    kw_out(oi->s, 114);
	    dv = dcc.green;
	    dv = drd(dv, oi->c, 0);
	    dkstream_puts_double(oi->s, dv);
	    kw_out(oi->s, 114);
	    dv = dcc.blue;
	    dv = drd(dv, oi->c, 0);
	    dkstream_puts_double(oi->s, dv);
	    kw_out(oi->s, 82);
	  } else {
	    dv = 0.3 * dcc.red + 0.59 * dcc.green + 0.11 * dcc.blue;
	    dv = drd(dv, oi->c, 0);
	    kw_out(oi->s, 159);
	    kw_out(oi->s, 81);
	    dkstream_puts_double(oi->s, dv);
	    kw_out(oi->s, 82);
	  }
	  /* contents */
	  if((t->font_flags) & 2) {
	    /* special text, leave as is */
	    dkstream_puts(oi->s, t->text);
	  } else {
	    /* non-special text, translate umlauts,... */
	    if(((oi->c)->opt2) & DKFIG_OPT_UTF_8) {
	      /* UTF-8 encoded */
	      dkfig_tool2_utf8_to_latex(oi->s, oi->c, t->text);
	    } else {
	      ptr = t->text;
	      while(*ptr) {
	        dkstream_puts(oi->s, dk_l2l_encoding(*ptr));
	        ptr++;
	      }
	    }
	  }
	  if(th & DKFIG_TH_MBOX) {
	    kw_out(oi->s, 82);
	  }
	  kw_out(oi->s, 82);		/* }   from: smash{ */
	  kw_out(oi->s, 82);		/* }   from: makebox(0,0)[]{ */
	  if(did_rotate) {
	    kw_out(oi->s, 82);		/* }   from: rotatebox{}{ */
	  }
	  kw_out(oi->s, 82);
	  kw_out(oi->s, 128);
	} break;
      }
    }
  }
  
  return back;
}



/**	Print the second picture environment (text labels) in the TeX output.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
second_picture DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 1;
  dk_fig_object *o;
  unsigned long backupopt1, backupopt2;
  int	backupia;
  
  if(!dkfig_dt_font_redef(oi->c, oi->s, 0)) {
    back = 0;
  }
  kw_out(oi->s, 113); kw_out(oi->s, 128);
  kw_out(oi->s, 107);
  kw_out(oi->s, 71);
  dkstream_puts_long(oi->s, dkma_double_to_l(oi->xright));
  kw_out(oi->s, 114);
  dkstream_puts_long(oi->s, dkma_double_to_l(oi->ytop));
  kw_out(oi->s, 72);
  kw_out(oi->s, 128);
  if((oi->fl) && (oi->fli)) {
    dksto_it_reset(oi->fli);
    while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) {
      oi->o = o; oi->me = 0;
      if((oi->c)->app) {
        dkapp_set_source_lineno((oi->c)->app, o->lineno);
      }
      backupopt1 = (oi->c)->opt1; backupopt2 = (oi->c)->opt2;
      backupia = (oi->c)->image_align;
      if(o->objtype == DK_FIG_OBJ_TEXT) {
        if(!process_tex_text(oi)) {
          back = 0;
        }
      }
      (oi->c)->opt2 = backupopt2; (oi->c)->opt1 = backupopt1;
      (oi->c)->image_align = backupia;
      if((oi->c)->app) {
        dkapp_set_source_lineno((oi->c)->app, 0UL);
      }
      if(oi->me) {	/* math error */
        back = 0;
	dkfig_tool2_eps_error_message(oi, 13);
      }
    }
  }
  kw_out(oi->s, 109); kw_out(oi->s, 128);
  if(((oi->c)->opt2) & DKFIG_OPT_FULL_TEX_FILE) {
    kw_out(oi->s, 133); kw_out(oi->s, 128);
  }
  
  return back;
}



/**	Check whether or not the current bitmap image contains an alpha channel.
	@param	oi	EPS output instruction structure.
*/
static
void
check_alpha DK_P1(dkfig_eps_output_instruction *,oi)
{
#if DK_HAVE_ZLIB_H
#if DK_HAVE_PNG_H
  dk_fig_object *o;
  png_structp pp;
  png_infop pi;
  char *p1;
  FILE *inputfile = NULL;
  unsigned long w = 0UL;
  unsigned long h = 0UL;
  int b = 0; int c = 0; int i = 0; int z = 0;
  int f = 0; int ch = 0;
  int ne = 0; int ns = 0; int np = 0;
  
  if((oi->fl) && (oi->fli)) {
    dksto_it_reset(oi->fli);
    o = (dk_fig_object *)dksto_it_next(oi->fli);
    while((o != NULL) && (!(((oi->d)->opt2) & DKFIG_OPT_HAVE_ALPHA_CHANNEL))) {
      switch(o->objtype) {
        case DK_FIG_OBJ_POLYLINE: {
	  switch((o->fpd).st) {
	    case 5: {
	      dk_fig_polyline *polyline;
	      polyline = (dk_fig_polyline *)(o->data);
	      if(polyline) {
	        if(polyline->imagename) {
		  p1 = dksf_get_file_type_dot(polyline->imagename);
		  if(p1) {
		    p1++;
		    if(dkstr_casecmp(str_suffix_png, p1) == 0) {
		      inputfile = dkapp_fopen((oi->c)->app, polyline->imagename, "rb");
		      if(inputfile) {
		        pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
			if(pp) {
			  pi = png_create_info_struct(pp);
			  if(pi) {
#if DK_HAVE_SETJMP_H
			    if(setjmp(png_jmpbuf(pp)) == 0) {
#endif
			      png_init_io(pp, inputfile);
			      png_read_info(pp, pi);
			      png_get_IHDR(pp, pi, &w, &h, &b, &c, &i, &z, &f);
			      ch = png_get_channels(pp, pi);
			      if((c == PNG_COLOR_TYPE_PALETTE) && (b <= 8)) {
	  		        ne = 1;	
			      }
			      if((c == PNG_COLOR_TYPE_GRAY) && (b < 8)) {
	  		        ne = 1;	
			      }
			      if(png_get_valid(pp, pi, PNG_INFO_tRNS)) {
	  		        ne = 1;	
			      }
			      if(b > 8) {
	  		        ns = 1;	
			      } else {
	  		        if(b < 8) {
	    		          np = 1;	
	  		        }
			      }
			      if(ne) { png_set_expand(pp); }
			      if(ns) { png_set_strip_16(pp); }
			      if(np) { png_set_packing(pp); }
			      png_read_update_info(pp, pi);
			      ch = png_get_channels(pp, pi);
			      switch(ch) {
			        case 2: case 4: {
				  (oi->d)->opt2 |= DKFIG_OPT_HAVE_ALPHA_CHANNEL;
				  
				} break;
			      }
#if DK_HAVE_SETJMP_H
			    }
#endif
			    png_destroy_info_struct(pp, &pi); pi = NULL;
			  } else {
			    /* ##### ERROR: Memory */
			  }
			  png_destroy_read_struct(&pp, NULL, NULL); pp = NULL;
			} else {
			  /* ##### ERROR: Memory */
			}
		        fclose(inputfile); inputfile = NULL;
		      } else {
		        /* ##### ERROR: Read input file */
		      }
		    }
		  }
		}
	      }
	    } break;
	  }
	} break;
      }
      o = (dk_fig_object *)dksto_it_next(oi->fli);
    }
  }
  
#endif
#endif
}



/**	The TeX output driver function.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
output_tex DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  
  check_alpha(oi);
  if(first_picture(oi)) {
    if(picture_settings(oi)) {
      if(second_picture(oi)) {
        back = 1;
	if(!(((oi->c)->opt2) & DKFIG_OPT_FULL_TEX_FILE)) {
	  if(((oi->d)->opt2) & DKFIG_OPT_HAVE_ALPHA_CHANNEL) {
	    if(!(((oi->c)->opt2) & DKFIG_OPT_SUPPRESS_ALPHA_INFO)) {
	      dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_WARNING, 129);
	    }
	  }
	}
      }
    }
  }
  
  return back;
}



/**	Write EPS output to stream.
	@param	oi	EPS output instruction structure.
	@return	1 on success, 0 on error.
*/
static int
output_pass DK_P1(dkfig_eps_output_instruction *,oi)
{
  int back = 0;
  char buffer[256];
  
  /* %!PS-Adobe... */
  ps_header_string(oi);
  /* BoundingBox */
  ps_bounding_box(oi);
  if((oi->c)->dscl) {	/* Title ... */
    kw_out(oi->s, 7); kw_out(oi->s, 0);
    if((oi->c)->ifn2) {
      kw_out(oi->s, 6);
      dkstream_puts(oi->s, (oi->c)->ifn2);
      kw_out(oi->s, 0);
    }
    kw_out(oi->s, 8); kw_out(oi->s, 0);
    kw_out(oi->s, 9); kw_out(oi->s, 0);
    kw_out(oi->s, 11); kw_out(oi->s, 0);
    print_list_of_needed_fonts(oi);
    kw_out(oi->s, 10); kw_out(oi->s, 0);
    kw_out(oi->s, 16); kw_out(oi->s, 0);
  } else {
    check_list_of_needed_fonts(oi);
  }
  back = print_ps_font_re_encoding(oi);
  if(((oi->c)->dscl >= 2) && (((oi->c)->opt2) & DKFIG_OPT_SETPAGEDEVICE)) {
    oi->flags |= OI_FLAG_DOCUMENT_SETUP;
  }
  if((oi->c)->dscl) {
    kw_out(oi->s, 17); kw_out(oi->s, 0);
    if(oi->flags & OI_FLAG_DOCUMENT_SETUP) {
      kw_out(oi->s, 27); kw_out(oi->s, 0);
      if(((oi->c)->dscl >= 2) && (((oi->c)->opt2) & DKFIG_OPT_SETPAGEDEVICE)) {
	if(((oi->c)->bdnum) == DKFIG_DRIVER_EPS) {
	  dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_WARNING, 114);
	} else {
          kw_out(oi->s, 153);
	  kw_out(oi->s, 1);
	  kw_out(oi->s, 156); kw_out(oi->s, 1);
	  if(must_align(oi->c)) {
	    sprintf(
	      buffer,
	      "%d %d",
	      (oi->c)->paper_width, (oi->c)->paper_height
	    );
	  } else {
	    sprintf(
	      buffer, "%ld %ld", 
	      dkma_double_to_l(oi->xright),
	      dkma_double_to_l(oi->ytop)
	    );
	  }
	  kw_out(oi->s, 61);
	  dkstream_puts(oi->s, buffer);
	  kw_out(oi->s, 62);
	  kw_out(oi->s, 1);
	  kw_out(oi->s, 154);
	  kw_out(oi->s, 1); kw_out(oi->s, 155); kw_out(oi->s, 0);
	}
      }
    }
  }
  setup_ps_fonts(oi);
  if((oi->c)->dscl) {
    if(oi->flags & OI_FLAG_DOCUMENT_SETUP) {
      kw_out(oi->s, 28); kw_out(oi->s,0);
    }
    kw_out(oi->s, 33); kw_out(oi->s, 0);
  }
  if(must_align(oi->c)) {
    kw_out(oi->s, 44); kw_out(oi->s, 0);
    sprintf(buffer, "%lg %lg ", oi->translate_x, oi->translate_y);
    dkstream_puts(oi->s, buffer); kw_out(oi->s, 57); kw_out(oi->s, 0);
    if(oi->must_scale) {
      sprintf(buffer, "%lg %lg ", oi->scaleval, oi->scaleval);
      dkstream_puts(oi->s, buffer); kw_out(oi->s, 58); kw_out(oi->s, 0);
    }
  }
  if(back) {
    back = contents_pass(oi);
  } else {
    contents_pass(oi);
  }
  if(must_align(oi->c)) {
    kw_out(oi->s, 45); kw_out(oi->s, 0);
  }
  if(((oi->c)->opt1) & DKFIG_OPT_USE_PS_SHOWPAGE) {
    if(((oi->c)->bdnum) == DKFIG_DRIVER_EPS) {
      dkfig_tool2_msg1(oi->c, DK_LOG_LEVEL_WARNING, 115);
    } else {
      kw_out(oi->s, 36); kw_out(oi->s, 0);
    }
  }
  if((oi->c)->dscl) {	/* Trailer, EOF*/
    kw_out(oi->s, 34); kw_out(oi->s, 0);
    kw_out(oi->s, 35); kw_out(oi->s, 0);
  }
  
  return back;
}



/**	Cleanup after doing output.
	Close temporary files, release memory...
	@param	oi	EPS output instruction structure.
*/
static void
cleanup_pass DK_P1(dkfig_eps_output_instruction *,oi)
{
  dk_fig_object *o;
  dkfig_bitmap_width *bmw;
  
  if((oi->fli) && (oi->fl)) {
    dksto_it_reset(oi->fli);
    while((o = (dk_fig_object *)dksto_it_next(oi->fli)) != NULL) {
      switch(o->objtype) {
        case DK_FIG_OBJ_POLYLINE: {
	  switch(o->subtype) {
	    case 5: {
	      if(o->drve) {
	        dkfig_eps_image_info_delete(
		  (dkfig_eps_image_info *)(o->drve)
		);
		o->drve = NULL;
	      }
	    } break;
	  }
	} break;
      }
    }
    dksto_it_close(oi->fli);
  }
  if(oi->fl) {
    dksto_close(oi->fl);
  }
  oi->fli = NULL; oi->fl = NULL;
  if((oi->iwi) && (oi->iw)) {
    dksto_it_reset(oi->iwi);
    while((bmw = (dkfig_bitmap_width *)dksto_it_next(oi->iwi)) != NULL) {
      
      dk_delete(bmw);
    }
    dksto_it_close(oi->iwi);
  }
  if(oi->iw) {
    dksto_close(oi->iw);
  }
  oi->iw = NULL; oi->iwi = NULL;
  if(oi->fdvi) {
    fclose(oi->fdvi); oi->fdvi = NULL;
  }
  if(oi->fps) {
    fclose(oi->fps); oi->fps = NULL;
  }
  if(!(((oi->c)->opt1) & DKFIG_OPT_KEEP_TEX_FILES)) {
    dkfig_tool_delete_tex_files(oi->c);
  }
  
}



/**	EPS output driver function.
	@param	c	Conversion job structure.
	@return	1 on success, 0 on error.
*/
int
dkfig_output_eps DK_P1(dk_fig_conversion *,c)
{
  int back = 0;
  int fnused[35], patused[DKFIG_NUMBER_OF_PATTERNS], i;
  dkfig_eps_output_instruction oi;
  
  if(c) {
    null_oi(&oi);
    oi.d = NULL;
    oi.c = c;
    oi.s = c->ostrm;
    dkstream_set_double_no_exponent(oi.s, 1);
    oi.dro = c->drwng;
    if(c->drwng) { oi.d = (dk_fig_drawing *)((oi.dro)->data); }
    if(oi.d) {
      oi.fnused = fnused;	/* no fonts used yet */
      for(i = 0; i < 35; i++) { fnused[i] = 0; }
      oi.patused = patused;	/* no patterns used so far */
      for(i = 0; i < DKFIG_NUMBER_OF_PATTERNS; i++) { patused[i] = 0; }
      oi.skip_images = 0;
      /* 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: output finished */
        dkfig_tool2_msg1(c, DK_LOG_LEVEL_PROGRESS, 22);
      }
      cleanup_pass(&oi);
    }
  }
  
  return back;
}



/**	PS output driver function.
	@param	c	Conversion job structure.
	@return	1 on success, 0 on error.
*/
int
dkfig_output_ps DK_P1(dk_fig_conversion *,c)
{
  int back = 0;
  
  back = dkfig_output_eps(c);
  
  return back;
}



/**	TeX output driver function.
	@param	c	Conversion job structure.
	@return	1 on success, 0 on error.
*/
int
dkfig_output_tex DK_P1(dk_fig_conversion *,c)
{
  int back = 0;
  int fnused[35], patused[DKFIG_NUMBER_OF_PATTERNS], i;
  dkfig_eps_output_instruction oi;
  unsigned long backupopt2;
  int backupia;
  
  if(c) {
    null_oi(&oi); oi.d = NULL;
    /* c->opt2 |= DKFIG_OPT_CRNL; */
    backupopt2 = c->opt2; backupia = c->image_align;
    c->opt2 |= DKFIG_OPT_TEX_DRIVER;
    oi.c = c;
    oi.s = c->ostrm;
    dkstream_set_double_no_exponent(oi.s, 1);
    oi.dro = c->drwng;
    if(c->drwng) { oi.d = (dk_fig_drawing *)((oi.dro)->data); }
    if(oi.d) {
      oi.fnused = fnused;	/* no fonts used yet */
      for(i = 0; i < 35; i++) { fnused[i] = 0; }
      oi.patused = patused;	/* no patterns used so far */
      for(i = 0; i < DKFIG_NUMBER_OF_PATTERNS; i++) { patused[i] = 0; }
      oi.skip_images = 1;
      if(preparation_pass(&oi)) {
        dkfig_tool2_report_unused_options(c);
        back = output_tex(&oi);
      }
      cleanup_pass(&oi);
    }
    c->opt2 = backupopt2; c->image_align = backupia;
  }
  
  return back;
}



/**	Bounding box output driver function.
	@param	c	Conversion job structure.
	@return	1 on success, 0 on error.
*/
int
dkfig_output_bb DK_P1(dk_fig_conversion *,c)
{
  int back = 0;
  int fnused[35], patused[DKFIG_NUMBER_OF_PATTERNS], i;
  dkfig_eps_output_instruction oi;
  
  if(c) {
    null_oi(&oi); oi.d = NULL;
    /* c->opt2 |= DKFIG_OPT_CRNL; */
    oi.c = c;
    oi.s = c->ostrm;
    oi.dro = c->drwng;
    if(c->drwng) { oi.d = (dk_fig_drawing *)((oi.dro)->data); }
    if(oi.d) {
      oi.fnused = fnused;	/* no fonts used yet */
      for(i = 0; i < 35; i++) { fnused[i] = 0; }
      oi.patused = patused;	/* no patterns used so far */
      oi.skip_images = 1;
      for(i = 0; i < DKFIG_NUMBER_OF_PATTERNS; i++) { patused[i] = 0; }
      if(preparation_pass(&oi)) {
        dkfig_tool2_report_unused_options(c);
        ps_bounding_box(&oi);
        back = 1;
      }
      cleanup_pass(&oi);
    }
  }
  
  return back;
}




