/*
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	dkfigopt.c	Fig2vect options module.
*/



/**	Inside the dkfigopt module.
*/
#define DKFIGOPT_C	1



#include "dkfig.h"




#line 55 "dkfigopt.ctr"




/**	Pointer to characters.
*/
typedef char *PCHAR;



/** Option: tex command.
*/
static char *cmd00[] = { "tex",		"command",	NULL };

/** Option: embed fonts.
*/
static char *cmd01[] = { "embed",	"fonts",	NULL };

/** Option: normal text.
*/
static char *cmd02[] = { "normal",	"text",		NULL };

/** Option: special text.
*/
static char *cmd03[] = { "special",	"text",		NULL };

/** Option: latex font setup.
*/
static char *cmd04[] = { "latex",	"font",		"setup", NULL };

/** Option: web palette.
*/
static char *cmd05[] = { "web",		"palette",	NULL };

/** Option: spline segments.
*/
static char *cmd06[] = { "spline",	"segments",	NULL };

/** Option: preamble file.
*/
static char *cmd07[] = { "preamble",	"file",		NULL };

/** Option: use cs setting.
*/
static char *cmd08[] = { "use",		"cs",		"setting", NULL };

/** Option: lighten look.
*/
static char *cmd09[] = { "lighten",	"look",		NULL };

/** Option: verbose output.
*/
static char *cmd10[] = { "verbose",	"output",	NULL};

/** Option: pattern line width.
*/
static char *cmd11[] = { "pattern",	"line",		"width", NULL};

/** Option: pattern repeat.
*/
static char *cmd12[] = { "pattern",	"repeat",	NULL};

/** Option: remove zero borders.
*/
static char *cmd13[] = { "remove",	"zero",		"borders", NULL };

/** Option: arrowhead linejoin.
*/
static char *cmd14[] = { "arrowhead",	"linejoin",	NULL};

/** Option: use metapost arrowheads.
*/
static char *cmd15[] = { "use",		"metapost",	"arrowheads",	NULL};

/** Option: min iteration steps.
*/
static char *cmd16[] = { "min",		"iteration",	"steps",	NULL};

/** Option: max iteration steps.
*/
static char *cmd17[] = { "max",		"iteration",	"steps",	NULL};

/** Option: fill patterns.
*/
static char *cmd18[] = { "fill",	"patterns",	NULL };

/** Option: ps level.
*/
static char *cmd19[] = { "ps",		"level",	NULL };

/** Option: dsc comments.
*/
static char *cmd20[] = { "dsc",		"comments",	NULL };

/** Option: enable write18 (unused).
*/
static char *cmd21[] = { "enable",	"write18",	NULL };

/** Option: ps showpage.
*/
static char *cmd22[] = { "ps",		"showpage",	NULL };

/** Option: keep tex files (unused).
*/
static char *cmd23[] = { "keep",	"tex",		"files",	NULL };

/** Option: font scale factor.
*/
static char *cmd24[] = { "font",	"scale",	"factor",	NULL };

/** Option: ps run-length encoding.
*/
static char *cmd25[] = { "ps",		"run-length",	"encoding",	NULL };

/** Option: separated rgb channels.
*/
static char *cmd26[] = { "separated",	"rgb",		"channels",	NULL};

/** Option: remove bitmap border.
*/
static char *cmd27[] = { "remove",	"bitmap",	"border",	NULL};

/** Option: fill bitmap background.
*/
static char *cmd28[] = { "fill",	"bitmap",	"background",	NULL};

/** Option: keep bitmap aspect ration.
*/
static char *cmd29[] = { "keep", "bitmap", "aspect", "ratio",	NULL };

/** Option: bitmap image dictionary.
*/
static char *cmd30[] = { "bitmap",	"image",	"dictionary",	NULL };

/** Option: force garbage collection.
*/
static char *cmd31[] = { "force",	"garbage",	"collection",	NULL };

/** Option: svg version.
*/
static char *cmd32[] = { "svg",		"version",	NULL };

/** Option: use css.
*/
static char *cmd33[] = { "use",		"css",		NULL };

/** Option: wh specification.
*/
static char *cmd34[] = { "wh",		"specification",	NULL };

/** Option: embedded svg fragment.
*/
static char *cmd35[] = { "embedded",	"svg",		"fragment",	NULL };

/** Option: repeat error messages.
*/
static char *cmd36[] = { "repeat",	"error",	"messages",	NULL };

/** Option: accept unknown paper size.
*/
static char *cmd37[] = { "accept",	"unknown",	"paper", "size", NULL}; 

/** Option: prepare for modifications.
*/
static char *cmd38[] = { "prepare",	"for",	"modifications",	NULL};

/** Option: dashpattern dot length.
*/
static char *cmd39[] = { "dashpattern",	"dot",	"length",	NULL };

/** Option: write tex command.
*/
static char *cmd40[] = { "write",	"tex",	"command",	NULL };

/** Option: remove background rectangle.
*/
static char *cmd41[] = { "remove",	"background",	"rectangle",	NULL };

/** Option: skip all texts.
*/
static char *cmd42[] = { "skip",	"all",	"texts",	NULL };

/** Option: plain text streams.
*/
static char *cmd43[] = { "plain",	"text",	"streams",	NULL };

/** Option: full screen.
*/
static char *cmd44[] = { "full",	"screen",	NULL};

/** Option: position digits.
*/
static char *cmd45[] = { "position",	"digits",	NULL };

/** Option: additional trigonometric digits.
*/
static char *cmd46[] = { "additional",	"trigonometric","digits", NULL };

/** Option: color digits.
*/
static char *cmd47[] = { "color",	"digits",	NULL };

/** Option: arc bezier steps.
*/
static char *cmd48[] = { "arc", "bezier", "steps", NULL };

/** Option: tiled patterns.
*/
static char *cmd49[] = { "tiled",	"patterns",	NULL };

/** Option: flip direction.
*/
static char *cmd50[] = { "flip",	"direction",	NULL };

/** Option: interpolate images.
*/
static char *cmd51[] = { "interpolate",	"images",	NULL };

/** Option: full tex file.
*/
static char *cmd52[] = { "full",	"tex",	"file",	NULL };

/** Option: background rectangle color.
*/
static char *cmd53[] = { "background",	"rectangle",	"color",	NULL };

/** Option: ps setpagedevice.
*/
static char *cmd54[] = { "ps",		"setpagedevice",	NULL };

/** Option: svg fontsize unit.
*/
static char *cmd55[] = { "svg",		"fontsize",	"unit",	NULL };

/** Option: font configuration file.
*/
static char *cmd56[] = { "font",	"configuration",	"file",	NULL };

/** Option: utf-8.
*/
static char *cmd57[] = { "utf-8",	NULL };

/** Option: gs svg-font directory.
*/
static char *cmd58[] = { "gs", "svg-font", "directory", NULL };

/** Option: js library.
*/
static char *cmd59[] = { "js", "library", NULL };

/** Option: allow pdf page attributes.
*/
static char *cmd60[] = { "allow", "pdf", "page", "attributes", NULL };

/** Option: fill bounding box.
*/
static char *cmd61[] = { "fill", "bounding", "box", NULL };

/** Option: color.
*/
static char *cmd62[] = { "color", NULL };

/** Option: page size.
*/
static char *cmd63[] = { "page", "size", NULL };

/** Option: page alignment.
*/
static char *cmd64[] = { "page", "alignment", NULL };

/** Option: use ghostscript fonts.
*/
static char *cmd65[] = { "use", "ghostscript", "fonts", NULL };

/** Option: Image alignment in rectangle.
*/
static char *cmd66[] = { "image", "alignment", NULL };

/** Option: Use dklibsj application or webstart.
*/
static char *cmd67[] = { "dklibsj", NULL };

/** Option: Correct interpolation/approximation on open splines.
*/
static char *cmd68[] = { "correct", "open", "splines", NULL};

/** Option: Write UNICODE escape sequences to Java output.
*/
static char *cmd69[] = { "java", "unicode", "escape", "sequences", NULL};

/** Commands to print.
*/
static char *cmds_to_print[] = {
  "tex command",
  "embed fonts",
  "normal text",
  "special text",
  "latex font setup",
  "web palette",
  "spline segments",
  "preamble file",
  "use cs setting",
  "lighten look",
  "verbose output",
  "pattern line width",
  "pattern repeat",
  "remove zero borders",
  "arrowhead linejoin",
  "use metapost arrowheads",
  "min iteration steps",
  "max iteration steps",
  "fill patterns",
  "ps level",
  "dsc comments",
  "enable write18",
  "ps showpage",
  "keep tex files",
  "font scale factor",
  "ps run-length encoding",
  "separated rgb channels",
  "remove bitmap border",
  "fill bitmap background",
  "keep bitmap aspect ratio",
  "bitmap image dictionary",
  "force garbage collection",
  "svg version",
  "use css",
  "wh specification",
  "embedded svg fragment",
  "repeat error messages",
  "accept unknown paper size",
  "prepare for modifications",
  "dashpattern dot length",
  "write tex command",
  "remove background rectangle",
  "skip all texts",
  "plain text streams",
  "full screen",
  "position digits",
  "additional trigonometric digits",
  "color digits",
  "arc bezier steps",
  "tiled patterns",
  "flip direction",
  "interpolate images",
  "full tex file",
  "background rectangle color",
  "ps setpagedevice",
  "svg fontsize unit",
  "font configuration file",
  "utf-8",
  "gs svg-font directory",
  "js library",
  "allow pdf page attributes",
  "fill bounding box",
  "color",
  "page size",
  "page alignment",
  "use ghostscript fonts",
  "image alignment",
  "dklibsj",
  "correct open splines",
  "java unicode escape sequences",
};



/** Options array.
*/
char **cmds[] = {
  /*  0 */	cmd00,
  /*  1 */	cmd01,
  /*  2 */	cmd02,
  /*  3 */	cmd03,
  /*  4 */	cmd04,
  /*  5 */	cmd05,
  /*  6 */	cmd06,
  /*  7 */	cmd07,
  /*  8 */	cmd08,
  /*  9 */	cmd09,
  /* 10 */	cmd10,
  /* 11 */	cmd11,
  /* 12 */	cmd12,
  /* 13 */	cmd13,
  /* 14 */	cmd14,
  /* 15 */	cmd15,
  /* 16 */	cmd16,
  /* 17 */	cmd17,
  /* 18 */	cmd18,
  /* 19 */	cmd19,
  /* 20 */	cmd20,
  /* 21 */	cmd21,
  /* 22 */	cmd22,
  /* 23 */	cmd23,
  /* 24 */	cmd24,
  /* 25 */	cmd25,
  /* 26 */	cmd26,
  /* 27 */	cmd27,
  /* 28 */	cmd28,
  /* 29 */	cmd29,
  /* 30 */	cmd30,
  /* 31 */	cmd31,
  /* 32 */	cmd32,
  /* 33 */	cmd33,
  /* 34 */	cmd34,
  /* 35 */	cmd35,
  /* 36 */	cmd36,
  /* 37 */	cmd37,
  /* 38 */	cmd38,
  /* 39 */	cmd39,
  /* 40 */	cmd40,
  /* 41 */	cmd41,
  /* 42 */	cmd42,
  /* 43 */	cmd43,
  /* 44 */	cmd44,
  /* 45 */	cmd45,
  /* 46 */	cmd46,
  /* 47 */	cmd47,
  /* 48 */	cmd48,
  /* 49 */	cmd49,
  /* 50 */	cmd50,
  /* 51 */	cmd51,
  /* 52 */	cmd52,
  /* 53 */	cmd53,
  /* 54 */	cmd54,
  /* 55 */	cmd55,
  /* 56 */	cmd56,
  /* 57 */	cmd57,
  /* 58 */	cmd60,
  /* 59 */	cmd61,
  /* 60 */	cmd62,
  /* 61 */	cmd63,
  /* 62 */	cmd64,
  /* 63 */	cmd65,
  /* 64 */	cmd66,
  /* 65 */	cmd67,
  /* 66 */	cmd68,
  /* 67 */	cmd69,
  NULL
};



/** Options to check.
*/
char **cmds_to_check[] = {
  /*  0 */	cmd00,
  /*  1 */	cmd01,
  /*  2 */	cmd02,
  /*  3 */	cmd03,
  /*  4 */	cmd04,
  /*  5 */	cmd05,
  /*  6 */	cmd06,
  /*  7 */	cmd07,
  /*  8 */	cmd08,
  /*  9 */	cmd09,
  /* 10 */	cmd10,
  /* 11 */	cmd11,
  /* 12 */	cmd12,
  /* 13 */	cmd13,
  /* 14 */	cmd14,
  /* 15 */	cmd15,
  /* 16 */	cmd16,
  /* 17 */	cmd17,
  /* 18 */	cmd18,
  /* 19 */	cmd19,
  /* 20 */	cmd20,
  /* 21 */	cmd21,
  /* 22 */	cmd22,
  /* 23 */	cmd23,
  /* 24 */	cmd24,
  /* 25 */	cmd25,
  /* 26 */	cmd26,
  /* 27 */	cmd27,
  /* 28 */	cmd28,
  /* 29 */	cmd29,
  /* 30 */	cmd30,
  /* 31 */	cmd31,
  /* 32 */	cmd32,
  /* 33 */	cmd33,
  /* 34 */	cmd34,
  /* 35 */	cmd35,
  /* 36 */	cmd36,
  /* 37 */	cmd37,
  /* 38 */	cmd38,
  /* 39 */	cmd39,
  /* 40 */	cmd40,
  /* 41 */	cmd41,
  /* 42 */	cmd42,
  /* 43 */	cmd43,
  /* 44 */	cmd44,
  /* 45 */	cmd45,
  /* 46 */	cmd46,
  /* 47 */	cmd47,
  /* 48 */	cmd48,
  /* 49 */	cmd49,
  /* 50 */	cmd50,
  /* 51 */	cmd51,
  /* 52 */	cmd52,
  /* 53 */	cmd53,
  /* 54 */	cmd54,
  /* 54 */	cmd55,
  /* 56 */	cmd56,
  /* 57 */	cmd57,
  /* 58 */	cmd58,
  /* 59 */	cmd59,
  /* 60 */	cmd60,
  /* 61 */	cmd61,
  /* 62 */	cmd62,
  /* 63 */	cmd63,
  /* 64 */	cmd64,
  /* 65 */	cmd65,
  /* 66 */	cmd66,
  /* 67 */	cmd67,
  /* 68 */	cmd68,
  /* 69 */	cmd69,
  NULL
};


/**	Possible  values for alignment.
*/
static char *alignment_values[] = {
  "top", "bottom", "left", "right",
  NULL
};


/**	Keywords to set up dklibsj usage.
*/
static char *dklibsj_settings[] = {
  "app$lication",
  "web$start",
  NULL
};

/** Pattern to find user home directory.
*/
static char home_pattern[] = { "$(user.home)" };

/** Defaults subdirectory in user home directory.
*/
static char default_dir[] = { "/.defaults" };

/** Path component delimiter.
*/
static char delimiter[] = { "/" };

/** Strings to write boolean values as text.
*/
static char *bool_val[] = { "off", "on", NULL };

/** Suffixes for compressed files.
*/
static char *compression_suffixes[] = { "", ".gz", ".bz2", NULL };




/** Values for arrowhead linejoin.
*/
static char *ahlj_kw[] = {
  "m$itered", "r$ounded", "b$eveled",
  NULL
};




/** Value contiguous for fill patterns.
*/
static char cont_kw[] = { "c$ontiguous" };




/** Value ignore.
*/
static char ignore_kw[] = { "i$gnore" };




/** Values for latex command.
*/
static char *tex_commands[] = { "latex", "tex", NULL };




/** keywords for text setup components.
*/
static char *font_setup_keywords[] = {
  /*  0 */ "handling",
  /*  1 */ "font",
  /*  2 */ "size",
  /*  3 */ "mbox",
  NULL
};

/** Values for handling in text setup.
*/
static char *font_setup_value_keywords[] = {
  /*  0 */ "none",
  /*  1 */ "tex",
  /*  2 */ "fig",
  /*  3 */ "similar",
  NULL
};

/** Keywords for latex font setup (font packages selection).
*/
static char *latex_font_setup_keywords[] = {
  /*  0 */ "ams",
  /*  1 */ "pdf",
  /*  2 */ "newcent",
  /*  3 */ "ams12",
  /*  4 */ "pdf12",
  /*  5 */ "newcent12",
  NULL
};

/** Delimiter between components of text setup.
*/
static char str_comma[] = { "," };



/** Whitespaces for text exploding.
*/
static char exploder_pattern[] = { " \t\r\n." };



/** Values for svg version.
*/
static char *known_svg_versions[] = {
  "1.0", "1.1", "1.2",
  NULL
};



/** Values for svg viewport specification.
*/
static char *svg_viewport_specifications[] = {
  "po$ints",
  "pi$xels",
  "i$nches",
};



/** Values for dashpattern dot length.
*/
static char *dp_dot_length[] = {
  "0", "linewidth", NULL
};



/** Values for flip direction.
*/
static char *flip_styles[] = {
  "h$orizontal", "d$iagonal", NULL
};



/** Values for background rectangle color.
*/
static char *bgcolordefs[] = {
  "d$efault",
  "w$hite",
  NULL
};


/**	Default separator set for options.
*/
static char sp_or_colon[] = { " \t:\r\n" };


/**	Compare two stored options by line number.
	@param	p1	Pointer to left option.
	@param	p2	Pointer to right options.
	@param	cr	Comparison criteria, 1=pointer/lineno, default=pointer/pointer.
	@return	The comparison result.
*/
int
dkfig_opt_compare DK_P3(void *,p1,void *,p2,int,cr)
{
  int back = 0;
  unsigned long ul, *ulptr;
  dk_fig_opt *fip1, *fip2;
  
  if (p1) {
    if (p2) {
      fip1 = (dk_fig_opt *)p1;
      fip2 = (dk_fig_opt *)p2;
      ulptr = (unsigned long *)p2;
      switch (cr) {
        case 1: {
	  ul = *ulptr;
	  if ( (fip1->number) > ul ) {
	    back = 1;
	  } else {
	    if ( (fip1->number) < ul ) {
	      back = -1;
	    }
	  }
	} break;
	default: {
	  if ( (fip1->number) > (fip2->number) ) {
	    back = 1;
	  } else {
	    if ( (fip1->number) < (fip2->number) ) {
	      back = -1;
	    }
	  }
	} break;
      }
    } else {
      back = 1;
    }
  } else {
    if (p2) {
      back = -1;
    }
  }
  
  return back;
}



/**	Destroy option structure, release memory.
	@param	o	Option structure to destroy.
*/
void
dkfig_opt_delete DK_P1(dk_fig_opt *,o)
{
  char *cptr;
  
  if (o) {	
    cptr = o->name;
    if (cptr) { dk_delete(cptr); }
    o->name = NULL; o->number = 0UL;
    dk_delete(o);
  }
  
}



/**	Create new option structure.
	Option structures created by this function must be
	destroyed using dkfig_opt_delete().
	@param	number	Line number of option in config file.
	@param	text	Text line (key = value).
	@return	Pointer to new option structure or NULL.
*/
dk_fig_opt *
dkfig_opt_new DK_P2(unsigned long,number,char *,text)
{
  dk_fig_opt *back = NULL;
  
  if (text) {
    back = dk_new(dk_fig_opt,1);
    if (back) {
      back->name = dkstr_dup(text);
      if (back->name) {
        back->number = number;
	back->used   = 0x00;
      } else {
        dk_delete(back); back = NULL;
      }
    }
  }
  
  return back;
}



/**	Retrieve text (key = value) from option structure.
	@param	o	Option structure.
	@return	The option text.
*/
char *
dkfig_opt_get_text DK_P1(dk_fig_opt *,o)
{
  char *back = NULL;
  
  if (o) {
    back = o->name;
  }
  
  return back;
}



/**	Select the TeX command (tex or latex).
	@param	c	Conversion job structure.
	@param	v	tex command value text ("latex" or "tex").
*/
static
void
set_tex_command DK_P2(dk_fig_conversion *,c,char *,v)
{
  int p;
  char *cptr;
  
  if(v) {
    cptr = dkstr_start(v, NULL);
    if(cptr) {
      dkstr_chomp(cptr, NULL);
      p = dkstr_array_index(tex_commands, cptr, 0);
      if(p > 0) {
        c->opt1 |= DKFIG_OPT_OLD_TEX;
      } else {
        c->opt1 &= (~(DKFIG_OPT_OLD_TEX));
      }
    }
  }
  
}



/**	Check whether or not to embed fonts in output.
	@param	c	Conversion job structure.
	@param	v	Embed fonts value text (boolean).
*/
static
void
set_embed_fonts DK_P2(dk_fig_conversion *,c,char *,v)
{
  int do_embed = 0; char *cptr;
  
  if(v) {
    cptr = dkstr_start(v, NULL);
    if(cptr) {
      dkstr_chomp(cptr, NULL);
      if(dkstr_is_bool(cptr)) {
        do_embed = dkstr_is_on(cptr); 
	if(do_embed) {
	  
	  c->opt1 &= (~(DKFIG_OPT_NO_EMBEDDED_FONTS));
	} else {
	  
	  c->opt1 |= DKFIG_OPT_NO_EMBEDDED_FONTS;
	}
      }
    }
  }
  
}



/**	Process a string containing text handling configuration.
	@param	c	Conversion job structure.
	@param	v	Value of "normal text" or "special text".
	@param	old	Previous text handling flag set (ignored).
	@return	The text handling flag built from \arg v.
*/
static
int
scan_th DK_P3(dk_fig_conversion *,c,char *,v,int,old)
{
  int back = 0;
  int have_error = 0;
  char *cptr, *vptr, *nptr;
  int ck, cv;
  
  cptr = dkstr_start(v, NULL);
  have_error = 0;
  if(cptr) {
    dkstr_chomp(cptr, NULL);
    while(cptr) {
      ck = cv = -1;
      nptr = dkstr_next(cptr, str_comma);
      cptr = dkstr_start(cptr, NULL);
      if(cptr) {
        dkstr_chomp(cptr, NULL);
	vptr = dkstr_chr(cptr, ':');
	if(vptr) {
	  *(vptr++) = '\0';
	  dkstr_chomp(cptr, NULL);
	  vptr = dkstr_start(vptr, NULL);
	  if(vptr) {
	    dkstr_chomp(vptr, NULL);
	    cv = dkstr_array_index(font_setup_value_keywords,vptr,0);
	  }
	}
	ck = dkstr_array_index(font_setup_keywords,cptr,0);
	switch(ck) {
	  /* handling */
	  case 0: {
	    switch(cv) {
	      case 0: {
	        back &= (~(DKFIG_TH_HANDLING));
	      } break;
	      case 1: {
	        back |= DKFIG_TH_HANDLING;
	      } break;
	      default: {
	        have_error = 1; 
		/* Warning: Invalid text handling */
		dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 32, 33, vptr);
	      } break;
	    }
	  } break;
	  /* font */
	  case 1: {
	    switch(cv) {
	      case 1: {
	        back =
		(back & (~(DKFIG_TH_FONT_MASK))) | DKFIG_TH_FONT_TEX;
	      } break;
	      case 2: {
	        back =
		(back & (~(DKFIG_TH_FONT_MASK))) | DKFIG_TH_FONT_FIG;
	      } break;
	      case 3: {
	        back =
		(back & (~(DKFIG_TH_FONT_MASK))) | DKFIG_TH_FONT_SIMILAR;
	      } break;
	      default: {
	        have_error = 1; 
		/* Warning: Invalid font */
		dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 34, 35, vptr);
	      } break; 
	    }
	  } break;
	  /* size */
	  case 2: {
	    switch(cv) {
	      case 1: {
	        back &= (~(DKFIG_TH_SIZE_FIG));
	      } break;
	      case 2: {
	        back |= DKFIG_TH_SIZE_FIG;
	      } break;
	      default: {
	        have_error = 1; 
		/* Warning: Invalid text size handling */
		dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 36, 37, vptr);
	      } break;
	    }
	  } break;
	  /* mbox */
	  case 3: {
	    switch(cv) {
	      case -1: {
	        back |= DKFIG_TH_MBOX;
	      } break;
	      case 0: {
	        back &= (~(DKFIG_TH_MBOX));
	      } break;
	      default: {
	        have_error = 1; 
		/* Warning: Invalid mbox specification */
		dkfig_tool2_msg1(c, DK_LOG_LEVEL_WARNING, 38);
	      } break;
	    }
	  } break;
	  default: {
	    have_error = 1; 
	    /* Warning: Invalid keyword in text handling */
	    dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 39, 40, cptr);
	  } break;
	}
      }
      cptr = nptr;
    }
  }
  
  return back;
}



/**	Set or reset flag bit in a flag set.
	@param	old	Old flag set.
	@param	vptr	Text containing a boolean.
	@param	flag	Bit to set or reset depending on \arg vptr.
	@return	The modified flag set.
*/
static
unsigned long
set_bool DK_P3(unsigned long,old, char *,vptr, unsigned long,flag)
{
  unsigned long back;
  back = old;
  if(vptr) {
    if(dkstr_is_bool(vptr)) {
      if(dkstr_is_on(vptr)) {
        back |= flag;
      } else {
        back &= (~flag);
      }
    } else {
      back |= flag;
    }
  } else {
    back |= flag;
  }
  return back;
}



/**	Apply text handling from string for normal texts.
	@param	c	Conversion job structure.
	@param	v	Text handling string.
*/
static
void
set_normal_text DK_P2(dk_fig_conversion *,c,char *,v)
{
  
  if(v) { c->normal_text = scan_th(c,v,c->normal_text); }
  
}



/**	Apply text handling from string for special texts.
	@param	c	Conversion job structure.
	@param	v	Text handling string.
*/
static
void
set_special_text DK_P2(dk_fig_conversion *,c,char *,v)
{
  
  if(v) { c->special_text = scan_th(c,v,c->special_text); }
  
}



/**	Set LaTeX font setup.
	@param	c	Conversion job structure.
	@param	v	Font setup name.
*/
static
void
set_latex_font_setup DK_P2(dk_fig_conversion *,c,char *,v)
{
  char *cptr;
  
  if(v) {
    cptr = dkstr_start(v, NULL);
    if(cptr) {
      dkstr_chomp(cptr, NULL);
      c->latfs = dkstr_array_index(latex_font_setup_keywords, cptr, 0);
    }
  }
  
}



/**	Set pattern line width.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the dash pattern line width.
*/
static void
set_pattern_line_width DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  if(vptr) {
    long l;
    if(sscanf(vptr, "%ld", &l) == 1) {
      if(l < 0L) l = 0L - l;
      if(l < 1L) l = 1L;
      c->patlw = l;
    }
  }
}



/**	Set pattern period.
	@param	c	Conversion job structure.
	@param	vptr	Text containing a number for pattern period.
*/
static void
set_pattern_period DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  if(vptr) {
    long l;
    if(sscanf(vptr, "%ld", &l) == 1) {
      if(l < 0L) l = 0L - l;
      if(l < 1L) l = 1L;
      c->patrp = l;
    }
  }
}



/**	Set arrowhead linejoin.
	@param	c	Conversion job structure.
	@param	vptr	Text containgin the arrowhead linejoin.
*/
static void
set_arrowhead_linejoin DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  c->ahlj = 0;
  if(vptr) {
    c->ahlj = dkstr_array_abbr(ahlj_kw, vptr, '$', 0);
    if(c->ahlj < 0) { c->ahlj = 0; }
  }
}




/**	Set minimum number of iteration steps to shorten a spline.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the number.
*/
static void
set_min_iteration_steps DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  unsigned long val = 1UL;
  if(vptr) {
    if(sscanf(vptr, "%lu", &val) == 1) {
      c->minitsteps = val;
    }
  }
}



/**	Set maximum number of iteration steps to shorten a spline.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the number.
*/
static void
set_max_iteration_steps DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  unsigned long val = 1UL;
  if(vptr) {
    if(sscanf(vptr, "%lu", &val) == 1) {
      c->maxitsteps = val;
    }
  }
}



/**	Set fill pattern usage.
	@param	c	Conversion job structure.
	@param	vptr	Text containing a boolean or "contiguous".
*/
static void
set_fill_patterns DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  unsigned long newfp = 0UL;
  unsigned long maskfp;
  if(vptr) {
    if(dkstr_is_bool(vptr)) {
      if(dkstr_is_on(vptr)) {
        newfp = DKFIG_OPT_FILL_PATTERNS;
	
      }
    } else {
      if(dkstr_is_abbr(vptr, cont_kw, '$', 0)) {
        newfp = DKFIG_OPT_FILL_PATTERNS | DKFIG_OPT_FILL_CONTIGOUS;
	
      } else {	
      }
    }
  } else {
    
    newfp = DKFIG_OPT_FILL_PATTERNS | DKFIG_OPT_FILL_CONTIGOUS;
  }
  maskfp = DKFIG_OPT_FILL_PATTERNS | DKFIG_OPT_FILL_CONTIGOUS;
  maskfp = (~maskfp);
  c->opt1 = (c->opt1 & maskfp) | newfp;
}



/**	Set PS level.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the PS level.
*/
static void
set_ps_level DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  int found = 0;
  unsigned psl = 2;
  /* ps level */
  if(vptr) {
    if(sscanf(vptr, "%u", &psl) == 1) {
      if(psl < 1) psl = 1;
      if(psl > 3) psl = 3;
      c->psl = psl; found = 1;
    }
  }
  if(!found) {
    c->psl = 2;
  }
}



/**	Set DSC level.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the DSC level or a boolean
			(true for DSC=PS, false for nor DSC).
*/
static void
set_dsc_level DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  unsigned u;
  if(vptr) {
    if(sscanf(vptr, "%u", &u) == 1) {
      c->dscl = u;
    } else {
      if(dkstr_is_bool(vptr)) {
        if(dkstr_is_on(vptr)) {
	  c->dscl = 255;
	} else {
	  c->dscl = 0;
	}
      } else {
        c->dscl = 1;
      }
    }
  } else {
    c->dscl = 1;
  }
}



/**	Enable/disable the use of write18 in latex/dvips.
	@param	c	Conversion job structure.
	@param	vptr	Text containing a boolean.
*/
static void
set_enable_write18 DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  if(vptr) {
    if(dkstr_is_bool(vptr)) {
      c->opt1 |= DKFIG_OPT_SPECIFY_WRITE18;
      if(dkstr_is_on(vptr)) {
        c->opt1 |= DKFIG_OPT_ENABLE_WRITE18;
      } else {
        c->opt1 &= (~DKFIG_OPT_ENABLE_WRITE18);
      }
    } else {
      if(dkstr_is_abbr(vptr, ignore_kw, '$', 0)) {
        c->opt1 &= (~DKFIG_OPT_SPECIFY_WRITE18);
      } else {
        /* ERROR: Unknown keyword */
	c->opt1 &= (~DKFIG_OPT_ENABLE_WRITE18);
      }
    }
  } else {
    c->opt1 |= DKFIG_OPT_SPECIFY_WRITE18;
    c->opt1 |= DKFIG_OPT_ENABLE_WRITE18;
  }
}



/**	Set font scale factor.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the factor (double value, nearly 1).
*/
static void
set_font_scale_factor DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  if(vptr) {
    double x;
    if(sscanf(vptr, "%lg", &x) == 1) {
      c->fsf = fabs(x);
    } else {
      c->fsf = 1.0;
    }
  } else {
    c->fsf = 1.0;
  }
}



/**	Set dash pattern dot length.
	@param	c	Conversion job structure.
	@param	vptr	Text containing "0" or "linewidth".
*/
static
void
set_dashpattern_dot_length DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  if(vptr) {
    switch(dkstr_array_index(dp_dot_length, vptr, 0)) {
      case 0: {
        c->opt1 &= (~(DKFIG_OPT_DP_DOT_LW));
      } break;
      default: {
        c->opt1 |= DKFIG_OPT_DP_DOT_LW;
      } break;
    }
  }
}



/**	Set name of TeX/LaTeX preamble file.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the file name.
*/
static void
set_preamble_file DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  if(vptr) {
    char *newptr, *cp;
    newptr = dkstr_dup(vptr);
    if(newptr) {
      if(c->tpfn) {
        cp = c->tpfn; dk_delete(cp); c->tpfn = NULL;
      }
      c->tpfn = newptr;
    } else { 
    }
  }
}



/**	Set number of Bezier spline segments to use for each X-spline segment.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the number (unsigned int).
*/
static void
set_spline_subsegments DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  unsigned u;
  if(vptr) {
    if(sscanf(vptr, "%u", &u) == 1) {
      if(u < 1) { u = 1; }
      c->spseg = (size_t)u;
      
    }
  }
}



/**	Set SVG version.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the SVG version.
*/
static
void
set_svg_version DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  int x;
  
  if(vptr) {
    x = dkstr_array_index(known_svg_versions, vptr, 0);
    if(x > -1) {
      c->svgv = x;
    }
  }
}



/**	Set SVG viewport specification.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the specification.
*/
static
void
set_svg_viewport_specification DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  int i;
  
  if(vptr) {
    i = dkstr_array_abbr(
      svg_viewport_specifications, vptr, '$', 0
    );
    if(i > -1) {
      c->svgs = i;
    }
  }
  
}



/**	Set flip style for flipped images.
	@param	c	Conversion job structure.
	@param	vptr	Text containing the flip style.
*/
static
void
set_flip_style DK_P2(dk_fig_conversion *,c, char *,vptr)
{
  int x;
  x = dkstr_array_abbr(flip_styles, vptr, '$', 0);
  if(x > 0) {
    c->opt2 |= DKFIG_OPT_FLIP_DIAGONAL;
    
  } else {
    c->opt2 &= (~(DKFIG_OPT_FLIP_DIAGONAL));
    
  }
}



/**	Set background rectangle color.
	@param	old	Old value.
	@param	vptr	Text containing "white" or "default".
	@return	Modified rectangle color.
*/
static
unsigned long
set_bg_rect_color DK_P2(unsigned long,old, char *,vptr)
{
  unsigned long back; int on = 0;
  back = old;
  
  if(vptr) {
    on = dkstr_array_abbr(bgcolordefs, vptr, '$', 0);
    if(on == -1) on = 0;
  }
  if(on) {
    back = back | DKFIG_OPT_WHITE_BGRECT;
  } else {
    back &= (~(DKFIG_OPT_WHITE_BGRECT));
  } 
  return back;
}




/**	Retrieve special comment text (key = value) from
	special comment line (driverlist: key = value).
	@param	line	Text line to inspect.
	@param	dr	Name of the current driver.
	@return	Pointer to the text on success (Current driver
	is in the driver list and the line syntax is correct),
	NULL on error.
*/
char *
dkfig_opt_special_comment_contents DK_P2(char *,line, char *,dr)
{
  char *back = NULL, *c, *n;
  int found = 0;
  
  back = dkstr_chr(line, ':');
  if(back) {
    *(back++) = '\0';
    back = dkstr_start(back, NULL);
    if(back) {
      c = dkstr_start(line, NULL);
      while(c) {
        n = dkstr_next(c, NULL);
	if(strcmp(c, dr) == 0) {
	  found = 1;
	} else {
	  if(strcmp(c, "*") == 0) {
	    found = 1;
	  }
	}
	c = n;
      }
    }
  }
  if(!found) {
    back = NULL;
  } 
  return back;
}



/**	Set image alignment.
	@param	c	Conversion structure.
	@param	vptr	Text describing image alignment.
	@return	Success flag.
*/
static
int
set_image_alignment DK_P2(dk_fig_conversion *,c, char *,vptr) {
  int back = 0;
  char buffer[256], *pc, *pn;
  
  if(vptr) {
    if(strlen(vptr) < sizeof(buffer)) {
      strcpy(buffer, vptr); back = 1;
      pc = dkstr_start(buffer, sp_or_colon);
      while(pc) {
        pn = dkstr_next(pc, sp_or_colon);
	switch(dkstr_array_index(alignment_values, pc, 0)) {
	  case 0: {	/* top */
	    c->image_align = ((c->image_align) & 3);
	  } break;
	  case 1: {	/* bottom */
	    c->image_align = 4 * DKFIG_ALIGN_V_BOTTOM + ((c->image_align) & 3);
	  } break;
	  case 2: {	/* left */
	    c->image_align = ((c->image_align) & 12);
	  } break;
	  case 3: {	/* right */
	    c->image_align = DKFIG_ALIGN_H_RIGHT + ((c->image_align) & 12);
	  } break;
	  default: { back = 0; } break;
	}
	pc = pn;
      }
    }
  } 
  return back;
}



/**	Enable or disable use of GS fonts.
	@param	c	Conversion structure.
	@param	vptr	Boolean value (text representation).
	@return	Success flag.
*/
static
int
set_use_gs_fonts DK_P2(dk_fig_conversion *,c, char *,vptr) {
  int back = 0;
  if(vptr) {
    if(dkstr_is_bool(vptr)) {
      if(dkstr_is_on(vptr)) {
        c->opt2 |= DKFIG_OPT_USE_GS_FONTS;
      } else {
        c->opt2 &= (~(DKFIG_OPT_USE_GS_FONTS));
      }
    } else {
      c->opt2 |= DKFIG_OPT_USE_GS_FONTS;
    }
  } else {
    c->opt2 |= DKFIG_OPT_USE_GS_FONTS;
  }
  return back;
}



/**	Set up use of dklibsj or not.
	@param	c	Conversion job.
	@param	vptr	Option value.
	@return	1 on success, 0 on error.
*/
static
int
set_use_dklibsj DK_P2(dk_fig_conversion *,c, char *,vptr) {
  int back = 0;
  if(vptr) {
    if(dkstr_is_bool(vptr)) {
      back = 1;
      if(dkstr_is_on(vptr)) {
        c->opt2 |= DKFIG_OPT_DKLIBSJ_LIBRARIES;
	c->opt2 &= (~(DKFIG_OPT_DKLIBSJ_WEBSTART));
      } else {
        c->opt2 &= (~(DKFIG_OPT_DKLIBSJ_LIBRARIES));
	c->opt2 &= (~(DKFIG_OPT_DKLIBSJ_WEBSTART));
      }
    } else {
      switch(dkstr_array_abbr(dklibsj_settings, vptr, '$', 0)) {
        case 0: {
	  c->opt2 |= DKFIG_OPT_DKLIBSJ_LIBRARIES;
	  c->opt2 &= (~(DKFIG_OPT_DKLIBSJ_WEBSTART));
	  back = 1;
	} break;
	case 1: {
	  c->opt2 |= DKFIG_OPT_DKLIBSJ_LIBRARIES;
	  c->opt2 |= DKFIG_OPT_DKLIBSJ_WEBSTART;
	  back = 1;
	} break;
      }
    }
  }
  return back;
}


/**	Set alignment of printout on page.
	@param	c	Conversion structure.
	@param	vptr	Alignment string.
	@return	Success flag.
*/
static
int
set_align DK_P2(dk_fig_conversion *,c, char *,vptr) {
  int back = 0;
  char buffer[256], *pc, *pn;
  
  if(strlen(vptr) < sizeof(buffer)) {
    strcpy(buffer, vptr);
    pc = dkstr_start(buffer, sp_or_colon);
    if(pc) { back = 1; }
    while(pc) {
      c->opt2 |= DKFIG_OPT_ALIGN_ON_PAPER;
      pn = dkstr_next(pc, sp_or_colon);
      
      switch(dkstr_array_abbr(alignment_values, pc, '$', 0)) {
        case 0: { c->align_v = DKFIG_ALIGN_V_TOP;	
	} break;	
	case 1: { c->align_v = DKFIG_ALIGN_V_BOTTOM;	
	} break;
	case 2: { c->align_h = DKFIG_ALIGN_H_LEFT;	
	} break;
	case 3: { c->align_h = DKFIG_ALIGN_H_RIGHT;	
	} break;
	default: back = 0; break;
      }
      pc = pn;
    }
  } 
  return back;
}



/**	Set paper size.
	@param	c	Conversion structure.
	@param	vptr	Paper size in text representation.
	@return	Success flag.
*/
static
int
set_paper_size DK_P2(dk_fig_conversion *,c, char *,vptr) {
  int back = 0, i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
  char buffer[256], *p1, *p2, *p3, *p4, *p5, *p6;
  p1 = p2 = p3 = p4 = p5 = p6 = NULL;
  c->paper_width = 0; c->paper_height = 0;
  c->paper_xleft = c->paper_xright = 0;
  c->paper_ytop = c->paper_ybottom = 0;
  if(strlen(vptr) < sizeof(buffer)) {
    strcpy(buffer, vptr);
    p1 = dkstr_start(buffer, sp_or_colon);
    if(p1) {
      p2 = dkstr_next(p1, sp_or_colon);
      if(p2) {
        p3 = dkstr_next(p2, sp_or_colon);
        if(sscanf(p1, "%d", &i1) == 1) {
	  if(sscanf(p2, "%d", &i2) == 1) {
	    c->paper_width = i1; c->paper_height = i2;
	    c->paper_xleft = c->paper_ybottom = 0;
	    c->paper_xright = i1;
	    c->paper_ytop = i2;
	    c->opt2 |= DKFIG_OPT_ALIGN_ON_PAPER;
	    if(p3) {
	      p4 = dkstr_next(p3, sp_or_colon);
	      if(p4) {
	        p5 = dkstr_next(p4, sp_or_colon);
	        if(p5) {
	          p6 = dkstr_next(p5, sp_or_colon);
		  if(p6) {
		    if(sscanf(p3, "%d", &i3) == 1) {
		      if(sscanf(p4, "%d", &i4) == 1) {
		        if(sscanf(p5, "%d", &i5) == 1) {
			  if(sscanf(p6, "%d", &i6) == 1) {
			    c->paper_xleft = i3;
			    c->paper_ybottom = i4;
			    c->paper_xright = i5;
			    c->paper_ytop = i6;
			  }
			}
		      }
		    }
		  }
	        }
	      }
	    }
	  }
	}
      }
    }
  }
  return back;
}



/**	Process one special comment (either for the entire
	drawing or before processing an object).
	@param	c	Conversion job structure.
	@param	line	Special comment.
	@param	dr	Driver name.
	@param	atdoclevel	Flag: at document level.
	@return	1 on success, error indicator on error
	(0=key not found, -1=ignored by the driver,
	-2=only allowed at document level, -3=errors
	while processing, -4=driver name not in the list).
*/
int
dkfig_opt_process_special_comment DK_P4(dk_fig_conversion *,c, char *,line, char *,dr, int,atdoclevel)
{
  int back = -1;
  char mybuffer[128], *myline, *parts[32], *lptr, *vptr, *cptr;
  int i;
  size_t xsz;
  
  myline = lptr = vptr = cptr = NULL;
  if((c) && (line) && (dr)) {
    
    if(strlen(line) >= sizeof(mybuffer)) {
      
      myline = dkstr_dup(line); lptr = myline;
    } else {
      
      strcpy(mybuffer, line); lptr = mybuffer;
    }
  }
  if(lptr) {	
    cptr = dkfig_opt_special_comment_contents(lptr, dr);
    if(cptr) {	
      back = 0;
      vptr = dkstr_chr(cptr, '=');
      if(vptr) { *(vptr++) = '\0'; }
      vptr = dkstr_start(vptr, NULL);
      if(vptr) { dkstr_chomp(vptr, NULL); }
      cptr = dkstr_start(cptr, NULL);
      if(cptr) {
        dkstr_chomp(cptr, NULL);
	xsz = sizeof(parts)/sizeof(PCHAR);
	if(dkstr_explode(parts, (xsz), cptr, exploder_pattern)) {
	  i = dkstr_find_multi_part_abbr(parts, cmds, '$', 1);
	  switch(i) {
	    case 0: {
	      if(atdoclevel) {
	        set_tex_command(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 1: {
	      if(atdoclevel) {
	        set_embed_fonts(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 2: {
	      if(atdoclevel) {
	        set_normal_text(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 3: {
	      if(atdoclevel) {
	        set_special_text(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 4: {
	      if(atdoclevel) {
	        set_latex_font_setup(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 5: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_WEB_PALETTE);
	      } else { back = -2; }
	    } break;
	    case 6: {
	      if(atdoclevel) {
	        set_spline_subsegments(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 7: {
	      if(atdoclevel) {
	        set_preamble_file(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 8: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_USE_CS_SETTING);
	      } else { back = -2; }
	    } break;
	    case 9: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_ENLIGHTEN_LOOK);
	      back = 1;
	    } break;
	    case 10: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_VERBOSE_OUTPUT);
	      back = 1;
	    } break;
	    case 11: {
	      set_pattern_line_width(c, vptr);
	      back = 1;
	    } break;
	    case 12: {
	      set_pattern_period(c, vptr);
	      back = 1;
	    } break;
	    case 13: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REMOVE_THIN_BORDERS);
	      back = 1;
	    } break;
	    case 14: {
	      set_arrowhead_linejoin(c, vptr);
	      back = 1;
	    } break;
	    case 15: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_METAPOST_ARROWHEADS);
	      back = 1;
	    } break;
	    case 16: {
	      if(atdoclevel) {
	        set_min_iteration_steps(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 17: {
	      if(atdoclevel) {
	        set_max_iteration_steps(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 18: {
	      set_fill_patterns(c, vptr);
	      back = 1;
	    } break;
	    case 19: {
	      if(atdoclevel) {
	        set_ps_level(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 20: {
	      if(atdoclevel) {
	        set_dsc_level(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 21: {
	      if(atdoclevel) {
	        set_enable_write18(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 22: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_USE_PS_SHOWPAGE);
	      } else { back = -2; }
	    } break;
	    case 23: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_KEEP_TEX_FILES);
	      } else { back = -2; }
	    } break;
	    case 24: {
	      set_font_scale_factor(c, vptr);
	      back = 1;
	    } break;
	    case 25: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_ALLOW_PSRL);
	      } else { back = -2; }
	    } break;
	    case 26: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_SEPARATED_RGB);
	      back = 1;
	    } break;
	    case 27: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REMOVE_BITMAP_BORDER);
	      back = 1;
	    } break;
	    case 28: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_FILL_BITMAP_AREA);
	      back = 1;
	    } break;
	    case 29: {
              c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_KEEP_BITMAP_WH_RATIO);
	      back = 1;
	    } break;
	    case 30: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_BITMAP_DICTIONARY);
	      } else { back = -2; }
	    } break;
	    case 31: {
	      if(atdoclevel) {
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_GARBAGE_COLLECTION);
		back = 1;
	      } else { back = -2; }
	    } break;
	    case 32: {
	      if(atdoclevel) {
	        set_svg_version(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 33: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_USE_CSS);
	      } else { back = -2; }
	    } break;
	    case 34: {
	      if(atdoclevel) {
	        set_svg_viewport_specification(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 35: {
	      if(atdoclevel) {
	        back = 1;
		c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_SVG_EMBEDDED);
	      } else { back = -2; }
	    } break;
	    case 36: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REPORT_MULTIPLE);
	      } else { back = -2; }
	    } break;
	    case 37: {
	      if(atdoclevel) {
	        back = 1;
		c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_IGNORE_UNKNOWN_PAPER);
	      } else { back = -2; }
	    } break;
	    case 38: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_PREPARE_FOR_MODS);
	      } else { back = -2; }
	    } break;
	    case 39: {
	      if(atdoclevel) {
	        set_dashpattern_dot_length(c, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 40: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_WR_TEX_COMMAND);
	      } else { back = -2; }
	    } break;
	    case 41: {
	      if(atdoclevel) {
	        back = 1;
                c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REMOVE_BG_RECTANGLE);
	      } else { back = -2; }
	    } break;
	    case 42: {
	      if(atdoclevel) {
	        back = 1;
                c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_SKIP_ALL_TEXTS);
	      } else { back = -2; }
	    } break;
	    case 43: {
	      if(atdoclevel) {
	        back = 1;
                c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_PLAIN_TEXT_STREAMS);
	      } else { back = -2; }
	    } break;
	    case 44: {
	      if(atdoclevel) {
	        back = 1;
                c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_FULL_SCREEN);
	      } else { back = -2; }
	    } break;
	    case 45: {
	      if(atdoclevel) {
	        unsigned u;
		if(vptr) {
		  if(sscanf(vptr, "%u", &u) == 1) {
		    if(u < 1) u = 1;
		    c->nodcoord = u; back = 1;
		  }
		}
	      } else { back = -2; }
	    } break;
	    case 46: {
	      if(atdoclevel) {
	        unsigned u;
		if(vptr) {
		  if(sscanf(vptr, "%u", &u) == 1) {
		    c->nodtrigo = u; back = 1;
		  }
		}
	      } else { back = -2; }
	    } break;
	    case 47: {
	      if(atdoclevel) {
	        unsigned u;
		if(vptr) {
		  if(sscanf(vptr, "%u", &u) == 1) {
		    if(u < 1) u = 1;
		    c->nodcolor = u; back = 1;
		  }
		}
	      } else { back = -2; }
	    } break;
	    case 48: {
	      if(atdoclevel) {
	        unsigned u;
		if(vptr) {
		  if(sscanf(vptr, "%u", &u) == 1) {
		    if(u < 1) u = 1;
		    c->circlesteps = u; back = 1;
		  }
		}
	      } else { back = -2; }
	    } break;
	    case 49: {
	      c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_PDF_PATTERN_TILE);
	      
	      back = 1;
	    } break;
	    case 50: {
	      if(vptr) {
	        set_flip_style(c, vptr);
		back = 1;
	      }
	    } break;
	    case 51: {
	      if(vptr) {
                c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_INTERPOLATE_IMAGES);
		back = 1;
	      }
	    } break;
	    case 52: {
	      if(atdoclevel) {
	        c->opt2 = set_bool(c->opt2,vptr,DKFIG_OPT_FULL_TEX_FILE);
		back = 1;
	      } else { back = -2; }
	    } break;
	    case 53: {
	      if(atdoclevel) {
	        c->opt2 = set_bg_rect_color(c->opt2, vptr); back = 1;
	      } else { back = -2; }
	    } break;
	    case 54: {
	      if(atdoclevel) {
	        back = 1;
                c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_SETPAGEDEVICE);
	      } else { back = -2; }
	    } break;
	    case 55: {
	      c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_SVG_FONTSIZE_UNIT);
	    } break;
	    case 56: {
	      if(atdoclevel) {
	        if(vptr) {
		  char *newptr, *cp;
		  newptr = dkstr_dup(vptr);
		  if(newptr) {
		    back = 1;
		    if(c->fcfg) {
		      cp = c->fcfg; dk_delete(cp);
		      c->fcfg = NULL;
		    }
		    c->fcfg = newptr;
		  }
		}
	      } else { back = -2; }
	    } break;
	    case 57: {	/* utf-8 */
	      if(vptr) {
	        back = dkfig_tool2_set_utf8(c, vptr, 0);
	      }
	    } break;
	    case 58: {
	      if(atdoclevel) {
	        back = 1;
	        if(vptr) {
		  if(dkstr_is_bool(vptr)) {
		    if(dkstr_is_on(vptr)) {
		       c->opt2 |= DKFIG_OPT_PDF_PAGE_ATTRIBUTES;
		    } else {
		      c->opt2 &= (~(DKFIG_OPT_PDF_PAGE_ATTRIBUTES));
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_PDF_PAGE_ATTRIBUTES;
		  }
		} else {
		  c->opt2 |= DKFIG_OPT_PDF_PAGE_ATTRIBUTES;
		}
	      }
	    } break;
	    case 59: {
	      
	      if(atdoclevel) {
	        back = 1;
	        if(vptr) {
		  if(dkstr_is_bool(vptr)) {
		    if(dkstr_is_on(vptr)) {
		      c->opt2 |= DKFIG_OPT_FILL_BOUNDING_BOX;
		    } else {
		      c->opt2 &= (~(DKFIG_OPT_FILL_BOUNDING_BOX));
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_FILL_BOUNDING_BOX;
		  }
		} else {
		  c->opt2 |= DKFIG_OPT_FILL_BOUNDING_BOX;
		}
	      }
	    } break;
	    case 60: {
	      if(atdoclevel) {
	        back = 1;
		if(vptr) {
		  if(dkstr_is_bool(vptr)) {
		    if(dkstr_is_on(vptr)) {
		      c->opt2 |= DKFIG_OPT_COLOR;
		    } else {
		      c->opt2 &= (~(DKFIG_OPT_COLOR));
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_COLOR;
		  }
		} else {
		  c->opt2 |= DKFIG_OPT_COLOR;
		}
	      }
	    } break;
	    case 61: {
	      if(atdoclevel) {
	        if(vptr) {
		  back = set_paper_size(c, vptr);
		}
	      }
	    } break;
	    case 62: {
	      if(atdoclevel) {
	        if(vptr) {
		  back = set_align(c, vptr);
		}
	      }
	    }
	    case 63: {
	      if(atdoclevel) {
	        if(vptr) {
		  back = set_use_gs_fonts(c, vptr);
		} else {
		  c->opt2 |= DKFIG_OPT_USE_GS_FONTS;
		}
	      }
	    } break;
	    case 64: {
	      if(vptr) {
	        
	        back = set_image_alignment(c, vptr);
	      }
	    } break;
	    case 65: {
	      if(atdoclevel) {
	        if(vptr) {
		  back = set_use_dklibsj(c, vptr);
		} else {
		  c->opt2 |= DKFIG_OPT_DKLIBSJ_LIBRARIES;
		}
	      }
	    } break;
	    case 66: {
	      if(vptr) {
	        if(dkstr_is_bool(vptr)) {
		  if(dkstr_is_on(vptr)) {
		    c->opt2 |= DKFIG_OPT_CORRECT_OPEN_SPLINES;
		  } else {
		    c->opt2 &= (~(DKFIG_OPT_CORRECT_OPEN_SPLINES));
		  }
		} else {
		  /* ERROR: Not a boolean value */
		}
	      } else {
	        c->opt2 |= DKFIG_OPT_CORRECT_OPEN_SPLINES;
	      }
	    } break;
	    case 67: {
	      if(vptr) {
	        if(dkstr_is_bool(vptr)) {
		  if(dkstr_is_on(vptr)) {
		    c->opt2 |= DKFIG_OPT_JAVA_UNICODE;
		  } else {
		    c->opt2 &= (~(DKFIG_OPT_JAVA_UNICODE));
		  }
		} else {
		  /* ERROR: Not a boolean value. */
		}
	      } else {
	        c->opt2 |= DKFIG_OPT_JAVA_UNICODE;
	      }
	    } break;
	  }
	}
      }
    } else {
      back = -4;
    }
  } else {	
    /* ERROR: Memory */
    back = -3;
    if(c->app) {
      dkapp_err_memory(c->app, 1, 1+strlen(line));
    }
  }
  if(myline) {
    
    dk_delete(myline); myline = NULL;
  } 
  return back;
}



/**	Process one option storage.
	@param	c	Conversion job structure.
	@param	b	Buffer to create a copy of the value.
	@param	sz	Size of the buffer.
	@param	i	Chooses the storage to process
	(0=general options, 1=base driver options, 2=driver options,
	3=command line option overrides).
*/
static
void
process_sto DK_P4(dk_fig_conversion *,c,char *,b,size_t,sz,int,i)
{
  dk_storage_t *sto = NULL; dk_storage_iterator_t *it = NULL;
  dk_fig_opt *o;
  char *sptr, *vptr, *parts[32];
  size_t xsz;
  
  switch(i) {
    case 0: {
      sto = c->optg; it = c->optgi;
    } break;
    case 1: {
      sto = c->optb; it = c->optbi;
    } break;
    case 2: {
      sto = c->optd; it = c->optdi;
    } break;
    case 3: {
      sto = c->opt;  it = c->opti ;
    } break;
  }
  if((sto) && (it)) {
    dksto_it_reset(it);
    xsz = sizeof(parts)/sizeof(PCHAR);
    while((o = (dk_fig_opt *)dksto_it_next(it)) != NULL) {
      if(o->name) {
        if(strlen(o->name) < sz) {
	  strcpy(b, o->name);
	  sptr = vptr = NULL;
	  vptr = dkstr_chr(b, '=');
	  if(vptr) {
	    *(vptr++) = '\0';
	    vptr = dkstr_start(vptr, NULL);
	  }
	  if(vptr) { dkstr_chomp(vptr, NULL); }
	  sptr = dkstr_start(b, NULL);
	  
	  if(sptr) {
	    dkstr_chomp(sptr, NULL);
	    if(dkstr_explode(parts, (xsz), sptr, exploder_pattern)) {
	      i = dkstr_find_multi_part_abbr(parts, cmds, '$', 1);
	      
	      switch(i) {
	        case 0: { /* tex command */
		  set_tex_command(c, vptr);
		  o->used = 0x01;
		} break;
		case 1: { /* embed fonts */
		  set_embed_fonts(c, vptr);
		  o->used = 0x01;
		} break;
		case 2: { /* normal text */
		  set_normal_text(c, vptr);
		  o->used = 0x01;
		} break;
		case 3: { /* special text */
		  set_special_text(c, vptr);
		  o->used = 0x01;
		} break;
		case 4: { /* latex font setup */
		  set_latex_font_setup(c, vptr);
		  o->used = 0x01;
		} break;
		case 5: { /* web palette */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_WEB_PALETTE);
		  o->used = 0x01;
		} break;
		case 6: { /* spline segments */
		  set_spline_subsegments(c, vptr);
		  o->used = 0x01;
		} break;
		case 7: { /* preamble file */
		  set_preamble_file(c, vptr);
		  o->used = 0x01;
		} break;
		case 8: { /* use cs setting */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_USE_CS_SETTING);
		  o->used = 0x01;
		} break;
		case 9: { /* enlighten look */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_ENLIGHTEN_LOOK);
		  o->used = 0x01;
		} break;
		case 10: { /* verbose output */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_VERBOSE_OUTPUT);
		  o->used = 0x01;
		} break;
		case 11: { /* pattern line width */
		  set_pattern_line_width(c, vptr);
		  o->used = 0x01;
		} break;
		case 12: { /* pattern period */
		  set_pattern_period(c, vptr);
		  o->used = 0x01;
		} break;
		case 13: { /* remove zero borders */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REMOVE_THIN_BORDERS);
		  o->used = 0x01;
		} break;
		case 14: { /* arrowhead linejoin */
		  set_arrowhead_linejoin(c, vptr);
		  o->used = 0x01;
		} break;
		case 15: { /* use metapost arrowheads */
                  c->opt1 = set_bool(c->opt1,vptr,DKFIG_OPT_METAPOST_ARROWHEADS);
		  o->used = 0x01;
		} break;
		case 16: { /* min iteration steps */
		  set_min_iteration_steps(c, vptr);
		  o->used = 0x01;
		} break;
		case 17: { /* maximum iteration steps */
		  set_max_iteration_steps(c, vptr);
		  o->used = 0x01;
		} break;
		case 18: { /* fill patterns */
		  set_fill_patterns(c, vptr);
		  o->used = 0x01;
		} break;
		case 19: { /* PS level */
		  set_ps_level(c, vptr);
		  o->used = 0x01;
		} break;
		case 20: { /* DSC comment level */
		  set_dsc_level(c, vptr);
		  o->used = 0x01;
		} break;
		case 21: { /* enable write18 */
		  set_enable_write18(c, vptr);
		  o->used = 0x01;
		} break;
		case 22: { /* ps showpage */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_USE_PS_SHOWPAGE);
		  o->used = 0x01;
		} break;
		case 23: { /* keep tex files */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_KEEP_TEX_FILES);
		  o->used = 0x01;
		} break;
		case 24: { /* font scale factor */
		  set_font_scale_factor(c, vptr);
		  o->used = 0x01;
		} break;
		case 25: { /* PS run-length encoding */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_ALLOW_PSRL);
		  o->used = 0x01;
		} break;
		case 26: { /* separated RGB channels */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_SEPARATED_RGB);
		  o->used = 0x01;
		} break;
		case 27: { /* remove bitmap border */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REMOVE_BITMAP_BORDER);
		  o->used = 0x01;
		} break;
		case 28: {	/* fill bitmap background */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_FILL_BITMAP_AREA);
		  o->used = 0x01;
		} break;
		case 29: {	/* keep w-h-ratio */
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_KEEP_BITMAP_WH_RATIO);
		  o->used = 0x01;
		} break;
		case 30: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_BITMAP_DICTIONARY);
		  o->used = 0x01;
		} break;
		case 31: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_GARBAGE_COLLECTION);
		  o->used = 0x01;
		} break;
		case 32: {
		  set_svg_version(c, vptr);
		  o->used = 0x01;
		} break;
		case 33: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_USE_CSS);
		  o->used = 0x01;
		} break;
		case 34: {
		  set_svg_viewport_specification(c, vptr);
		  o->used = 0x01;
		} break;
		case 35: {
		  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_SVG_EMBEDDED);
		  o->used = 0x01;
		} break;
		case 36: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REPORT_MULTIPLE);
		  o->used = 0x01;
		} break;
		case 37: {
		  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_IGNORE_UNKNOWN_PAPER);
		  o->used = 0x01;
		} break;
		case 38: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_PREPARE_FOR_MODS);
		  o->used = 0x01;
		} break;
		case 39: {
		  set_dashpattern_dot_length(c, vptr);
		  o->used = 0x01;
		} break;
		case 40: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_WR_TEX_COMMAND);
		  o->used = 0x01;
		} break;
		case 41: {
                  c->opt1 = set_bool(c->opt1, vptr, DKFIG_OPT_REMOVE_BG_RECTANGLE);
		  o->used = 0x01;
		} break;
	        case 42: {
                  c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_SKIP_ALL_TEXTS);
		  o->used = 0x01;
	        } break;
		case 43: {
                  c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_PLAIN_TEXT_STREAMS);
		  o->used = 0x01;
		} break;
		case 44: {
                  c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_FULL_SCREEN);
		  o->used = 0x01;
		} break;
		case 45: {	/* nodcoord */
		  if(vptr) {
		    unsigned u;
		    if(sscanf(vptr, "%u", &u) == 1) {
		      c->nodcoord = u;
		      o->used = 0x01;
		    }
		  }
		} break;
		case 46: {	/* nodtrigo */
		  if(vptr) {
		    unsigned u;
		    if(sscanf(vptr, "%u", &u) == 1) {
		      c->nodtrigo = u;
		      o->used = 0x01;
		    }
		  }
		} break;
		case 47: {	/* nodcolor */
		  if(vptr) {
		    unsigned u;
		    if(sscanf(vptr, "%u", &u) == 1) {
		      if(u < 1) u = 1;
		      c->nodcolor = u;
		      o->used = 0x01;
		    }
		  }
		} break;
		case 48: {	/* circlesteps */
		  if(vptr) {
		    unsigned u;
		    if(sscanf(vptr, "%u", &u) == 1) {
		      if(u < 1) u = 1;
		      c->circlesteps = u;
		      o->used = 0x01;
		    }
		  }
		} break;
		case 49: {
	          c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_PDF_PATTERN_TILE);
	          
		  o->used = 0x01;
		} break;
		case 50: {
		  if(vptr) {
		    set_flip_style(c, vptr);
		    o->used = 0x01;
		  }
		} break;
		case 51: {
		  if(vptr) {
                    c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_INTERPOLATE_IMAGES);
		    o->used = 0x01;
		  }
		} break;
		case 52: {
		  if(vptr) {
                    c->opt2 = set_bool( c->opt2, vptr, DKFIG_OPT_FULL_TEX_FILE);
		    o->used = 0x01;
		  }
		} break;
		case 53: {
		  if(vptr) {
		    c->opt2 = set_bg_rect_color(c->opt2, vptr);
		  }
		  o->used = 0x01;
		} break;
		case 54: {
                  c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_SETPAGEDEVICE);
		  o->used = 0x01;
		} break;
		case 55: {
		  c->opt2 = set_bool(c->opt2, vptr, DKFIG_OPT_SVG_FONTSIZE_UNIT);
		  o->used = 0x01;
		} break;
		case 56: {
	          if(vptr) {
		    char *newptr, *cp;
		    newptr = dkstr_dup(vptr);
		    o->used = 0x01;
		    if(newptr) {
		      if(c->fcfg) {
		        cp = c->fcfg; dk_delete(cp);
		        c->fcfg = NULL;
		      }
		      c->fcfg = newptr;
		    }
		  }
		} break;
		case 57: {	/* utf-8 */
		  if(vptr) {
		    (void)dkfig_tool2_set_utf8(c, vptr, 1);
		    o->used = 0x01;
		  }
		} break;
		case 58: {
	          if(vptr) {
		    if(dkstr_is_bool(vptr)) {
		      if(dkstr_is_on(vptr)) {
		         c->opt2 |= DKFIG_OPT_PDF_PAGE_ATTRIBUTES;
		      } else {
		        c->opt2 &= (~(DKFIG_OPT_PDF_PAGE_ATTRIBUTES));
		      }
		    } else {
		      c->opt2 |= DKFIG_OPT_PDF_PAGE_ATTRIBUTES;
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_PDF_PAGE_ATTRIBUTES;
		  } o->used = 0x01;
		} break;
		case 59: {
	          if(vptr) {
		    if(dkstr_is_bool(vptr)) {
		      if(dkstr_is_on(vptr)) {
		         c->opt2 |= DKFIG_OPT_FILL_BOUNDING_BOX;
		      } else {
		        c->opt2 &= (~(DKFIG_OPT_FILL_BOUNDING_BOX));
		      }
		    } else {
		      c->opt2 |= DKFIG_OPT_FILL_BOUNDING_BOX;
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_FILL_BOUNDING_BOX;
		  } o->used = 0x01;
		} break;
		case 60: {
		  if(vptr) {
		    if(dkstr_is_bool(vptr)) {
		      if(dkstr_is_on(vptr)) {
		        c->opt2 |= DKFIG_OPT_COLOR;
		      } else {
		        c->opt2 &= (~(DKFIG_OPT_COLOR));
		      }
		    } else {
		      c->opt2 |= DKFIG_OPT_COLOR;
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_COLOR;
		  } o->used = 0x01;
		} break;
	        case 61: {
	          if(vptr) {
		    (void)set_paper_size(c, vptr);
		    o->used = 0x01;
		  }
	        } break;
	        case 62: {
	          if(vptr) {
		    (void)set_align(c, vptr);
		    o->used = 0x01;
		  }
	        }
		case 63 : {
		  if(vptr) {
		    (void)set_use_gs_fonts(c, vptr);
		  } else {
		    c->opt2 |= DKFIG_OPT_USE_GS_FONTS;
		  }
		  o->used = 0x01;
		} break;
		case 64: {
		  o->used = 0x01;
		  if(vptr) {
		    
		    (void)set_image_alignment(c, vptr);
		  }
		} break;
		case 65: {
		  o->used = 0x01;
		  if(vptr) {
		    (void)set_use_dklibsj(c, vptr);
		  } else {
		    c->opt2 |= DKFIG_OPT_DKLIBSJ_LIBRARIES;
		  }
		} break;
		case 67: {
		  o->used = 0x01;
		  if(vptr) {
		    if(dkstr_is_bool(vptr)) {
		      if(dkstr_is_on(vptr)) {
		        c->opt2 |= DKFIG_OPT_JAVA_UNICODE;
		      } else {
		        c->opt2 &= (~(DKFIG_OPT_JAVA_UNICODE));
		      }
		    } else {
		      /* ERROR: Not boolean */
		    }
		  } else {
		    c->opt2 |= DKFIG_OPT_JAVA_UNICODE;
		  }
		} break;
	      }
	    }
	  }
	} else {	
	  /* ERROR: Internal error, option too long */
	  dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 41, 42, o->name);
	}
      }
    }
  }
  
}



/**	Process all stored options.
	Walk through all 4 option storages
	(general defaults, base driver options, driver
	options and command line arguments) and apply
	the settings to the conversion job structure.
	@param	c	Conversion job structure.
	@return	1 on success, 0 on errors.
*/
int
dkfig_opt_process_all DK_P1(dk_fig_conversion *,c)
{
  int back = 1;
  size_t sz;
  char *buffer = NULL;
  int i;
  
  if(c) {
  if(c->lcfge) {
    sz = 1 + c->lcfge;
    buffer = dk_new(char,sz);
    if(buffer) {
      for(i = 0; i < 4; i++) {
        process_sto(c, buffer, sz, i);
      }
      dk_delete(buffer); buffer = NULL;
      if(c->dscl > c->psl) { c->dscl = c->psl; }
    } else {
      back = 0;
      if(c->app) {
        dkapp_err_memory(c->app, sizeof(char), sz);
      }
    }
  }
  }
  
  return back;
}




/**	Show configuration file contents.
	@param	c	Conversion job structure.
	@param	fn	File name.
	@return	1 on success, 0 on error.
*/
int
dkfig_opt_show_config_file DK_P2(dk_fig_conversion *,c, char *,fn)
{
  int back = 0, action = 0, i = 0;
  dk_stream_t *is = NULL;
  char b1[1024], b2[sizeof(b1)], *p1, *p2, *parts[32];
  size_t xsz, nparts;
  
  if((c) && (fn)) {
  if(c->app) {
    is = dkapp_read_file(c->app, fn);
    if(is) {
      back = 1;
      while(dkstream_gets(is, b1, sizeof(b1))) {
        action = i = 0;
        dkstr_delcomm(b1, '#');
	p1 = dkstr_start(b1, NULL);
	if(p1) {
	  if(*p1 == '[') {
	    dkstr_chomp(p1, NULL);
	    printf("%s\n", p1);
	  } else {
	    p2 = dkstr_chr(p1, '=');
	    if(p2) {
	      *(p2++) = '\0';
	      p1 = dkstr_start(p1, NULL);
	      if(p1) {
	        dkstr_chomp(p1, NULL);
		p2 = dkstr_start(p2, NULL);
		if(p2) {
		  dkstr_chomp(p2, NULL);
		  strcpy(b2, p1);
		  xsz = sizeof(parts)/sizeof(PCHAR);
		  nparts = dkstr_explode(parts, xsz, p1, exploder_pattern);
		  if(nparts > 0) {
		    action = dkstr_find_multi_part_abbr(parts, cmds_to_check, '$', 1);
		    if(dkstr_is_bool(p2)) { if(dkstr_is_on(p2)) i = 1; }
		    switch(action) {
		      case 1:
		      case 5:
		      case 8:
		      case 9:
		      case 10:
		      case 13:
		      case 15:
		      case 20:
		      case 21:
		      case 22:
		      case 23:
		      case 25:
		      case 26:
		      case 27:
		      case 28:
		      case 29:
		      case 30:
		      case 31:
		      case 33:
		      case 35:
		      case 36:
		      case 37:
		      case 38:
		      case 40:
		      case 41:
		      case 42:
		      case 43:
		      case 44:
		      case 49:
		      case 51:
		      case 52:
		      case 54:
		      case 61:
		      case 68:
		      case 69:
		      {
		        printf("%s=%d\n", cmds_to_print[action], i);
			
			
			
		      } break;
		      case -1: {
		        
		      } break;
		      default: {
		        printf("%s=%s\n", cmds_to_print[action], p2);
			
			
			
		      } break;
		    }
		  }
		}
	      }
	    }
	  }
	}
      }
      dkstream_close(is); is = NULL;
    }
  }
  } 
  return back;
}



/**	Write standard input to new configuration file.
	@param	c	Conversion job structure.
	@param	fn	File name
	@return	1 on success, 0 on error.
*/
int
dkfig_opt_write_config_file DK_P2(dk_fig_conversion *,c, char *,fn)
{
  int back = 0, action = 0, i = 0;
  int must_eat_up = 1;
  unsigned long sz;
  size_t xsz, nparts;
  char b1[1024], b2[sizeof(b1)], *p1, *p2, *parts[32], **pp;
  FILE *f = NULL;
  dk_stat_t *stp;
  
  xsz = sizeof(parts)/sizeof(PCHAR);
  if((c) && (fn)) {
    if(c->app) {
      if(dkapp_transform_string_ext1(c->app,b1,sizeof(b1),home_pattern,1)) {
        strcpy(b2, b1);
	sz = strlen(b1);
	sz += strlen(default_dir);
	sz += strlen(fn);
	sz += 2;
	if(sz < sizeof(b1)) {
	  strcat(b1, default_dir);
	  strcat(b1, delimiter);
	  strcat(b1, fn);
	  dksf_correct_fnsep(b1);
	  f = dkapp_fopen(c->app, b1, "w");
	  if(f) {
	    while(fgets(b1, sizeof(b1), stdin)) {
	      action = i = 0;
	      p1 = dkstr_start(b1, NULL);
	      if(p1) {
	        dkstr_chomp(p1, NULL);
	        if(*p1 == '[') {
		  fprintf(f, "%s\n", p1);
		} else {
		  p2 = dkstr_chr(p1, '=');
		  if(p2) {
		    *(p2++) = '\0';
		    p1 = dkstr_start(p1, NULL);
		    p2 = dkstr_start(p2, NULL);
		    if((p1) && (p2)) {
		      dkstr_chomp(p1, NULL);
		      dkstr_chomp(p2, NULL);
		      nparts=dkstr_explode(parts,xsz,p1,exploder_pattern);
		      if(nparts > 0) {
		        action = dkstr_find_multi_part_abbr(parts,cmds_to_check,'$',i);
			if(dkstr_is_bool(p2)) { if(dkstr_is_on(p2)) i = 1; }
			switch(action) {
			  case -1: {
			  } break;
		          case 1:
		          case 5:
		          case 8:
		          case 9:
		          case 10:
		          case 13:
		          case 15:
		          case 20:
		          case 21:
		          case 22:
		          case 23:
		          case 25:
		          case 26:
		          case 27:
		          case 28:
		          case 29:
		          case 30:
		          case 31:
		          case 33:
		          case 35:
		          case 36:
		          case 37:
		          case 38:
		          case 40:
		          case 41:
		          case 42:
		          case 43:
		          case 44:
		          case 49:
		          case 51:
		          case 52:
		          case 54:
			  case 61:
		          {
		            fprintf(
			      f, "%s=%s\n", cmds_to_print[action], bool_val[i]
			    );
		          } break;
			  default: {
			    fprintf(f, "%s=%s\n", cmds_to_print[action], p2);
			  } break;
			}
		      }
		    }
		  }
		}
	      }
	    }
	    fclose(f);
	    must_eat_up = 0; back = 1;
	    
	    pp = compression_suffixes;
	    while(*pp) {
	      strcpy(b1, fn);
	      strcat(b1, *pp);
	      
	      stp = dkstat_open(b1);
	      if(stp) {
	        
	        dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 130, 131, b1);
	        dkstat_close(stp); stp = NULL;
	      }
	      pp++;
	    }
	    
	    pp = compression_suffixes;
	    while(*pp) {
	      strcpy(b1, b2);
	      strcat(b1, delimiter);
	      strcat(b1, fn);
	      strcat(b1, *pp);
	      
	      stp = dkstat_open(b1);
	      if(stp) {
	        
	        dkfig_tool2_msg3(c, DK_LOG_LEVEL_WARNING, 130, 131, b1);
	        dkstat_close(stp); stp = NULL;
	      }
	      pp++;
	    }
	  }
	}
      }
    }
  } 
  if(must_eat_up) {
    while(fgets(b1, sizeof(b1), stdin)) {}
  }
  return back;
}


