/*
	WARNING: This file was generated by dkct.
	Changes you make here will be lost if dkct is run again!
	You should modify the original source and run dkct on it.
	Original source: f2lto.ctr
*/

/*
Copyright (C) 2013, Dirk Krause

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 author 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 f2lto.c The f2lto module.
*/


#line 262 "f2lto.ctr"

#include "dk3all.h"
#include "dk3bezcu.h"
#include "fig2lat.h"
#include "f2lud.h"
#include "f2lsvg.h"
#include "dk3figto.h"
#include "dkt-version.h"
#include "dk3font.h"
#include "dk3bm.h"
#include "dk3bmeps.h"




#line 276 "f2lto.ctr"



/**	LaTeX encodings for 0x00-0xFF.
*/
static char const * const f2l_tool_l2l_enc[] = {
/* 000 00 */ "",
/* 001 01 */ "",
/* 002 02 */ "",
/* 003 03 */ "",
/* 004 04 */ "",
/* 005 05 */ "",
/* 006 06 */ "",
/* 007 07 */ "",
/* 008 08 */ "",
/* 009 09 */ "\t",
/* 010 0a */ "\\\\*",
/* 011 0b */ "",
/* 012 0c */ "",
/* 013 0d */ "",
/* 014 0e */ "",
/* 015 0f */ "",
/* 016 10 */ "",
/* 017 11 */ "",
/* 018 12 */ "",
/* 019 13 */ "",
/* 020 14 */ "",
/* 021 15 */ "",
/* 022 16 */ "",
/* 023 17 */ "",
/* 024 18 */ "",
/* 025 19 */ "",
/* 026 1a */ "",
/* 027 1b */ "",
/* 028 1c */ "",
/* 029 1d */ "",
/* 030 1e */ "",
/* 031 1f */ "",
/* 032 20 */ " ",
/* 033 21 */ "!",
/* 034 22 */ "\\textquotedbl{}",
/* 035 23 */ "\\#",
/* 036 24 */ "\\textdollar{}",
/* 037 25 */ "\\%",
/* 038 26 */ "\\&",
/* 039 27 */ "\\textquoteright{}",
/* 040 28 */ "(",
/* 041 29 */ ")",
/* 042 2a */ "\\textasteriskcentered{}",
/* 043 2b */ "+",
/* 044 2c */ ",",
/* 045 2d */ "-",
/* 046 2e */ ".",
/* 047 2f */ "/",
/* 048 30 */ "0",
/* 049 31 */ "1",
/* 050 32 */ "2",
/* 051 33 */ "3",
/* 052 34 */ "4",
/* 053 35 */ "5",
/* 054 36 */ "6",
/* 055 37 */ "7",
/* 056 38 */ "8",
/* 057 39 */ "9",
/* 058 3a */ ":",
/* 059 3b */ ";",
/* 060 3c */ "\\textless{}",
/* 061 3d */ "=",
/* 062 3e */ "\\textgreater{}",
/* 063 3f */ "?",
/* 064 40 */ "@",
/* 065 41 */ "A",
/* 066 42 */ "B",
/* 067 43 */ "C",
/* 068 44 */ "D",
/* 069 45 */ "E",
/* 070 46 */ "F",
/* 071 47 */ "G",
/* 072 48 */ "H",
/* 073 49 */ "I",
/* 074 4a */ "J",
/* 075 4b */ "K",
/* 076 4c */ "L",
/* 077 4d */ "M",
/* 078 4e */ "N",
/* 079 4f */ "O",
/* 080 50 */ "P",
/* 081 51 */ "Q",
/* 082 52 */ "R",
/* 083 53 */ "S",
/* 084 54 */ "T",
/* 085 55 */ "U",
/* 086 56 */ "V",
/* 087 57 */ "W",
/* 088 58 */ "X",
/* 089 59 */ "Y",
/* 090 5a */ "Z",
/* 091 5b */ "[",
/* 092 5c */ "\\textbackslash{}",
/* 093 5d */ "]",
/* 094 5e */ "\\textasciicircum{}",
/* 095 5f */ "\\textunderscore{}",
/* 096 60 */ "\\textasciigrave{}",
/* 097 61 */ "a",
/* 098 62 */ "b",
/* 099 63 */ "c",
/* 100 64 */ "d",
/* 101 65 */ "e",
/* 102 66 */ "f",
/* 103 67 */ "g",
/* 104 68 */ "h",
/* 105 69 */ "i",
/* 106 6a */ "j",
/* 107 6b */ "k",
/* 108 6c */ "l",
/* 109 6d */ "m",
/* 110 6e */ "n",
/* 111 6f */ "o",
/* 112 70 */ "p",
/* 113 71 */ "q",
/* 114 72 */ "r",
/* 115 73 */ "s",
/* 116 74 */ "t",
/* 117 75 */ "u",
/* 118 76 */ "v",
/* 119 77 */ "w",
/* 120 78 */ "x",
/* 121 79 */ "y",
/* 122 7a */ "z",
/* 123 7b */ "\\textbraceleft{}",
/* 124 7c */ "\\textbar{}",
/* 125 7d */ "\\textbraceright{}",
/* 126 7e */ "\\textasciitilde{}",
/* 127 7f */ "",
/* 128 80 */ "",
/* 129 81 */ "",
/* 130 82 */ "",
/* 131 83 */ "",
/* 132 84 */ "",
/* 133 85 */ "",
/* 134 86 */ "",
/* 135 87 */ "",
/* 136 88 */ "",
/* 137 89 */ "",
/* 138 8a */ "",
/* 139 8b */ "",
/* 140 8c */ "",
/* 141 8d */ "",
/* 142 8e */ "",
/* 143 8f */ "",
/* 144 90 */ "",
/* 145 91 */ "",
/* 146 92 */ "",
/* 147 93 */ "",
/* 148 94 */ "",
/* 149 95 */ "",
/* 150 96 */ "",
/* 151 97 */ "",
/* 152 98 */ "",
/* 153 99 */ "",
/* 154 9a */ "",
/* 155 9b */ "",
/* 156 9c */ "",
/* 157 9d */ "",
/* 158 9e */ "",
/* 159 9f */ "",
/* 160 a0 */ "",
/* 161 a1 */ "\\textexclamdown{}",
/* 162 a2 */ "\\textcentoldstyle{}",
/* 163 a3 */ "\\textstirling{}",
/* 164 a4 */ "\\textcurrency{}",
/* 165 a5 */ "\\textyen{}",
/* 166 a6 */ "\\textbrokenbar{}",
/* 167 a7 */ "\\textsection{}",
/* 168 a8 */ "\\textasciidieresis{}",
/* 169 a9 */ "\\textcopyright{}",
/* 170 aa */ "\\textordfeminine{}",
/* 171 ab */ "\\quillemotleft{}",
/* 172 ac */ "\\textlnot{}",
/* 173 ad */ "",
/* 174 ae */ "\\textregistered{}",
/* 175 af */ "\\textasciimacron{}",
/* 176 b0 */ "\\textdegree{}",
/* 177 b1 */ "\\textpm{}",
/* 178 b2 */ "\\texttwosuperior{}",
/* 179 b3 */ "\\textthreesuperior{}",
/* 180 b4 */ "\\textasciiacute{}",
/* 181 b5 */ "\\textmu{}",
/* 182 b6 */ "\\P{}",
/* 183 b7 */ "\\textperiodcentered{}",
/* 184 b8 */ "\\c{}",
/* 185 b9 */ "\\textonesuperior{}",
/* 186 ba */ "\\textordmasculine{}",
/* 187 bb */ "\\quillemotright{}",
/* 188 bc */ "\\textonequarter{}",
/* 189 bd */ "\\textonehalf{}",
/* 190 be */ "\\textthreequarters{}",
/* 191 bf */ "?`",
/* 192 c0 */ "\\`{A}",
/* 193 c1 */ "\\'{A}",
/* 194 c2 */ "\\^{A}",
/* 195 c3 */ "\\~{A}",
/* 196 c4 */ "\\\"{A}",
/* 197 c5 */ "\\AA{}",
/* 198 c6 */ "\\AE{}",
/* 199 c7 */ "\\c{C}",
/* 200 c8 */ "\\`{E}",
/* 201 c9 */ "\\'{E}",
/* 202 ca */ "\\^{E}",
/* 203 cb */ "\\\"{E}",
/* 204 cc */ "\\`{I}",
/* 205 cd */ "\\'{I}",
/* 206 ce */ "\\^{I}",
/* 207 cf */ "\\\"{I}",
/* 208 d0 */ "\\DH{}",
/* 209 d1 */ "\\~{N}",
/* 210 d2 */ "\\`{O}",
/* 211 d3 */ "\\'{O}",
/* 212 d4 */ "\\^{O}",
/* 213 d5 */ "\\~{O}",
/* 214 d6 */ "\\\"{O}",
/* 215 d7 */ "\\texttimes{}",
/* 216 d8 */ "\\O{}",
/* 217 d9 */ "\\`{U}",
/* 218 da */ "\\'{U}",
/* 219 db */ "\\^{U}",
/* 220 dc */ "\\\"{U}",
/* 221 dd */ "\\'{Y}",
/* 222 de */ "\\TH{}",
/* 223 df */ "\\ss{}",
/* 224 e0 */ "\\`{a}",
/* 225 e1 */ "\\'{a}",
/* 226 e2 */ "\\^{a}",
/* 227 e3 */ "\\~{a}",
/* 228 e4 */ "\\\"{a}",
/* 229 e5 */ "\\aa{}",
/* 230 e6 */ "\\ae{}",
/* 231 e7 */ "\\c{c}",
/* 232 e8 */ "\\`{e}",
/* 233 e9 */ "\\'{e}",
/* 234 ea */ "\\^{e}",
/* 235 eb */ "\\\"{e}",
/* 236 ec */ "\\`{i}",
/* 237 ed */ "\\'{i}",
/* 238 ee */ "\\^{i}",
/* 239 ef */ "\\\"{i}",
/* 240 f0 */ "\\dh{}",
/* 241 f1 */ "\\~{n}",
/* 242 f2 */ "\\`{o}",
/* 243 f3 */ "\\'{o}",
/* 244 f4 */ "\\^{o}",
/* 245 f5 */ "\\~{o}",
/* 246 f6 */ "\\\"{o}",
/* 247 f7 */ "\\textdiv{}",
/* 248 f8 */ "\\o{}",
/* 249 f9 */ "\\`{u}",
/* 250 fa */ "\\'{u}",
/* 251 fb */ "\\^{u}",
/* 252 fc */ "\\\"{u}",
/* 253 fd */ "\\'{y}",
/* 254 fe */ "\\th{}",
/* 255 ff */ "\\\"{y}"
};


/**	Keywords used by the module.
*/
static char const * const	f2lto_c8_kw[] = {
/* 0 */
"\\begin{picture}(0,0)\n",

/* 1 */
"\\end{picture}%\n",

/* 2 */
"\\includegraphics{",

/* 3 */
"}\n",

/* 4 */
"\\setlength{\\unitlength}{1bp}%\n",

/* 5 */
"\\begin{picture}(%ld,%ld)\n",

/* 6 */
"\\newfont{",

/* 7 */
"}{",

/* 8 */
"}%\n",

/* 9 */
"\\FigToLatFont",

/* 10 */
"ptmr",

/* 11 */
" at ",

/* 12 */
"pt",

/* 13 */
"\\put(",

/* 14 */
",",

/* 15 */
"){",

/* 16 */
"}",

/* 17 */
"\\rotatebox{",

/* 18 */
"\\makebox(0,0)[",

/* 19 */
"]{",

/* 20 */
"lb",

/* 21 */
"b",

/* 22 */
"rb",

/* 23 */
"\\smash{",

/* 24 */
"\\mbox{",

/* 25 */
"\\color[rgb]{",

/* 26 */
"\n",

/* 27 */
"\\reset@font",

/* 28 */
"\\selectfont",

/* 29 */
"\\fontsize{",

/* 30 */
"\\fontfamily{\\rmdefault}",

/* 31 */
"\\fontfamily{\\sfdefault}",

/* 32 */
"\\fontfamily{\\ttdefault}",

/* 33 */
"\\fontseries{\\mddefault}",

/* 34 */
"\\fontseries{\\bfdefault}",

/* 35 */
"\\fontshape{\\updefault}",

/* 36 */
"\\fontshape{\\itdefault}",

/* 37 */
"\\fontfamily{\\familydefault}",

/* 38 */
"{",

/* 39 */
"\\end{document}\n",

/* 40 */
"\\documentclass[%lgpt]{article}\n",

/* 41 */
"\\setlength{\\paperwidth}{%ldbp}\n",

/* 42 */
"\\setlength{\\paperheight}{%ldbp}\n",

/* 43 */
"\\usepackage{pgfcore}\n",

/* 44 */
"f2lfonts.tex",

/* 45 */
"f2lother.tex",

/* 46 */
"r",

NULL


#line 734 "f2lto.ctr"
};



/**	LaTeX preamble, part 1 (font encoding and font selection packages).
*/
static char const * const f2l_tool_preamble_1[] = {
"% begin font setup",
"\\usepackage[T1]{fontenc}",
"\\usepackage{mathptmx}",
"\\usepackage[scaled=.92]{helvet}",
"\\usepackage{courier}",
"% end font setup",
NULL


#line 749 "f2lto.ctr"
};



/**	LaTex preamble, part 2 (other packages).
*/
static char const * const f2l_tool_preamble_2[] = {
"% begin other packages",
"\\usepackage{textcomp}",
"\\usepackage[intlimits]{amsmath}",
"% end other packages",
NULL


#line 762 "f2lto.ctr"
};



/**	LaTeX preamble, part 3 (graphics and color).
*/
static char const * const f2l_tool_preamble_3[] = {
"\\usepackage{graphicx}",
"\\usepackage{color}",
NULL


#line 773 "f2lto.ctr"
};



/**	LaTeX preamble, part 4 (set borders to 0).
*/
static char const * const f2l_tool_preamble_4[] = {
"\\pagestyle{empty}",
"\\setlength{\\voffset}{-1in}",
"\\setlength{\\topmargin}{0bp}",
"\\setlength{\\headheight}{0bp}",
"\\setlength{\\headsep}{0bp}",
"\\setlength{\\topskip}{0bp}",
"\\setlength{\\hoffset}{-1in}",
"\\setlength{\\oddsidemargin}{0bp}",
"\\setlength{\\evensidemargin}{0bp}",
"\\setlength{\\marginparwidth}{0bp}",
"\\setlength{\\marginparsep}{0bp}",
"\\setlength{\\textwidth}{\\paperwidth}",
"\\setlength{\\textheight}{\\paperheight}",
"\\setlength{\\parskip}{0bp}",
"\\setlength{\\parindent}{0bp}",
"\\setlength{\\pdfpagewidth}{\\paperwidth}",
"\\setlength{\\pdfpageheight}{\\paperheight}",
"\\begin{document}%",
NULL


#line 800 "f2lto.ctr"
};



f2l_text_handling_t *
f2l_tool_register_font(
  dk3_sto_t		*sFonts,
  dk3_sto_it_t		*iFonts,
  unsigned long		*nFonts,
  int			 fontno,
  double		 fontsize,
  dk3_app_t		*app
)
{
  f2l_text_handling_t	 myth;		/* New text handling. */
  f2l_text_handling_t	*back = NULL;
  

#line 817 "f2lto.ctr"
  if((sFonts) && (iFonts) && (nFonts)) {
    myth.fontSize = fontsize;	

#line 819 "f2lto.ctr"
    myth.fontNumber = 0UL;
    myth.psFontNo = fontno;	

#line 821 "f2lto.ctr"
    back = dk3sto_it_find_like(iFonts, (void *)(&myth), 0);
    if(!(back)) {		

#line 823 "f2lto.ctr"
      back = dk3_new_app(f2l_text_handling_t,1,app);
      if(back) {		

#line 825 "f2lto.ctr"
        back->fontSize = fontsize;
	back->fontNumber = *(nFonts);
	back->psFontNo = fontno;
	if(fontno <  0) { back->psFontNo = 0; }
	if(fontno > 34) { back->psFontNo = 34; }
	if(dk3sto_add(sFonts, (void *)back)) {	

#line 831 "f2lto.ctr"
	  *nFonts += 1UL;
	  if(0UL == *nFonts) {
	    back = NULL;	/* Overflow */
	  }
	} else {				

#line 836 "f2lto.ctr"
	  dk3_delete(back);
	  back = NULL;
	}
      } else {			

#line 840 "f2lto.ctr"
      }
    } else {	

#line 842 "f2lto.ctr"
    }
  } 

#line 844 "f2lto.ctr"
  return back;
}



void
f2l_tool_write_font_name(
  FILE			*of,
  unsigned long		 fontno,
  unsigned long		 nFonts
)
{
  char		 buffer[64];	/* Buffer for number converted to string. */
  char		*ptr;		/* Current character in buffer. */
  size_t	 lgt;		/* Length of current number. */
  size_t	 l1;		/* Length of maximum number. */
  size_t	 i;		/* Used to write leading zeros. */

  if(of) {
    fputs(f2lto_c8_kw[9], of);
    sprintf(buffer, "%lu", nFonts);
    lgt = strlen(buffer);
    sprintf(buffer, "%lu", fontno);
    l1  = strlen(buffer);
    for(i = l1; i < lgt; i++) { fputc('A', of); }
    ptr = buffer;
    while(*ptr) {
      switch(*ptr) {
        case '9': { fputc('J', of); } break;
        case '8': { fputc('I', of); } break;
        case '7': { fputc('H', of); } break;
        case '6': { fputc('G', of); } break;
        case '5': { fputc('F', of); } break;
        case '4': { fputc('E', of); } break;
        case '3': { fputc('D', of); } break;
        case '2': { fputc('C', of); } break;
        case '1': { fputc('B', of); } break;
        default:  { fputc('A', of); } break;
      }
      ptr++;
    }
  }
}



void
f2l_tool_start_tex_part_with_picture(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  char const		*shortOutFile,
  dk3_sto_it_t		*iFonts,
  unsigned long		 nFonts,
  int			 wp
)
{
  f2l_text_handling_t	*th;		/* Current text handling. */
  char const		*psfontname;	/* PS font name. */
  double		 fs;		/* Font size. */

  if(wp) {
    /* begin{picture}(0,0) */
    fputs(f2lto_c8_kw[0], of);
    fputs(f2lto_c8_kw[2], of);
    fputs(shortOutFile, of);
    fputs(f2lto_c8_kw[3], of);
    /* end{picture} */
    fputs(f2lto_c8_kw[1], of);
    fputs(f2lto_c8_kw[4], of);
  }
  if((iFonts) && (nFonts)) {
    dk3sto_it_reset(iFonts);
    while(NULL != (th = (f2l_text_handling_t *)dk3sto_it_next(iFonts))) {
      fputs(f2lto_c8_kw[6], of);
      /* Write font name */
      f2l_tool_write_font_name(of, th->fontNumber, nFonts);
      fputs(f2lto_c8_kw[7], of);
      /* Write font description */
      psfontname = dk3font_get_tex_font_name(th->psFontNo);
      if(!(psfontname)) { psfontname = f2lto_c8_kw[10]; }
      fputs(psfontname, of);
      fputs(f2lto_c8_kw[11], of);
      fs = th->fontSize;
      if(job->nts > 0.0) {
        fs = fs * job->nts;
      }
      fs = dk3ma_restrict_digits(fs, 2);
      dk3ma_print_double_c8_no_sci(of, fs);
      fputs(f2lto_c8_kw[12], of);
      fputs(f2lto_c8_kw[8], of);
    }
  }
  if(wp) {
    fprintf(of, f2lto_c8_kw[5], job->lwidth, job->lheight);
  }
}




void
f2l_tool_start_tex_part(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  char const		*shortOutFile,
  dk3_sto_it_t		*iFonts,
  unsigned long		 nFonts
)
{
  f2l_tool_start_tex_part_with_picture(
    of, job, drw, shortOutFile, iFonts, nFonts, 1
  );
}



void
f2l_tool_end_tex_part(
  FILE			*of
)
{
  fputs(f2lto_c8_kw[1], of);
}



/**	Write font size to output file.
	@param	of	Output file.
	@param	fs	Font size.
	@param	sp	Line base to line base distance.
*/
static
void
f2l_tool_write_font_size(
  FILE		*of,
  double	 fs,
  double	 sp
)
{

  fputs(f2lto_c8_kw[29], of);
  dk3ma_print_double_c8_no_sci(of, fs);
  fputs(f2lto_c8_kw[12], of);
  fputs(f2lto_c8_kw[7], of);
  dk3ma_print_double_c8_no_sci(of, sp);
  fputs(f2lto_c8_kw[12], of);
  fputs(f2lto_c8_kw[16], of);
}



void
f2l_tool_font_select_by_features(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  dk3_fig_obj_t		*obj,
  double		 fontSize,
  int			 fontFeatures,
  int			 useFamily
)
{
  double 		 fs;	/* Font size. */
  double		 sp;	/* Line base to line base distance. */

  fs = fontSize;
  if(job->nts > 0.0) {
    fs = fs * job->nts;
  }
  sp = 1.2 * fs;
  fs = dk3ma_restrict_digits(fs, 2);
  sp = dk3ma_restrict_digits(sp, 2);
  if(useFamily) {
    /*
    	Complete font selection.
    */
    if(job->resfont) {
      fputs(f2lto_c8_kw[27], of);
    }
    /* Font size. */
    f2l_tool_write_font_size(of, fs, sp);
    /* Font family */
    switch(fontFeatures & DK3_FONT_FAMILY) {
      case DK3_FONT_TYPEWRITER: {
        fputs(f2lto_c8_kw[32], of);
      } break;
      case DK3_FONT_SANS_SERIF: {
        fputs(f2lto_c8_kw[31], of);
      } break;
      default: {
        fputs(f2lto_c8_kw[30], of);
      } break;
    }
    /* Font series */
    fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_BOLD) ? 34 : 33], of);
    /* Font shape */
    /*	2013-01-22 Correction to test with DK3_FONT_ITOB.
    */
    fputs(f2lto_c8_kw[(fontFeatures & DK3_FONT_ITOB) ? 36 : 35], of);
  } else {
    /*
    	Adjust the size only.
    */
    f2l_tool_write_font_size(of, fs, sp);
    fputs(f2lto_c8_kw[37], of);
    fputs(f2lto_c8_kw[33], of);
    fputs(f2lto_c8_kw[35], of);
  }
  fputs(f2lto_c8_kw[28], of);
}



void
f2l_tool_font_selection(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  dk3_fig_obj_t		*obj,
  unsigned long		 nFonts
)
{
  f2l_text_handling_t	*th;		/* Text handling. */
  int			 ff;		/* Font flags. */
  int			 fontFeatures;	/* Font features. */

  ff = (obj->dt).txt.ff;
  /*
  	No font selection... for special text.
  */
  if(!(ff & DK3_FIG_FONT_FLAG_SPECIAL)) {
    if((ff & DK3_FIG_FONT_FLAG_PS) && (obj->dsd)) {
      /*
      	Use one of the defined fonts.
      */
      th = (f2l_text_handling_t *)(obj->dsd);
      f2l_tool_write_font_name(of, th->fontNumber, nFonts);
    } else {
      /*
      	Select font by features.
      */
      fontFeatures = DK3_FONT_ROMAN;
      if(ff & DK3_FIG_FONT_FLAG_PS) {
        /*
		Switch from PS font to font with similar features.
	*/
        fontFeatures = dk3font_get_features((obj->dt).txt.fo);
	f2l_tool_font_select_by_features(
	  of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	);
      } else {
        /*
		Use LaTeX font with specified features.
	*/
        switch((obj->dt).txt.fo) {
	  case 0: {
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 0
	    );
	  } break;
	  case 1: {
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	    );
	  } break;
	  case 2: {
	    fontFeatures |= DK3_FONT_BOLD;
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	    );
	  } break;
	  case 3: {
	    fontFeatures |= DK3_FONT_ITALIC;
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	    );
	  } break;
	  case 4: {
	    fontFeatures = DK3_FONT_SANS_SERIF;
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	    );
	  } break;
	  case 5: {
	    fontFeatures = DK3_FONT_TYPEWRITER;
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	    );
	  } break;
	  default: {
	    f2l_tool_font_select_by_features(
	      of, job, drw, obj, (obj->dt).txt.fs, fontFeatures, 1
	    );
	  } break;
	}
      }
    }
  }
}



void
f2l_tool_tex_string(
  FILE			*of,
  char const		*txt
)
{
  char const	*ptr;	/* Current input character to process. */
  char const	*sptr;	/* Output string for current input character. */
  char		 c;	/* Current input character. */
  unsigned char	 uc;	/* Current input character conv to unsigned char. */
  unsigned	 un;	/* Current input character converted to unsigned. */

  ptr = txt;
  while(*ptr) {
    c = *(ptr++);
    uc = (unsigned char)c;
    un = (unsigned)uc;
    while(uc > 255) {
      uc = uc - 256;
    }
    sptr = f2l_tool_l2l_enc[un];
    if(sptr) {
      fputs(sptr, of);
    }
  }
}



void
f2l_tool_inner_text_object(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  dk3_fig_obj_t		*obj,
  unsigned long		 nFonts
)
{
  dk3_rgb_color_t	 rgb;	/* Color cell for text color. */

  rgb.r = rgb.g = rgb.b = 0.0;
  dk3fig_tool_find_color(&rgb, drw, obj->pc, 20);
  if(job->smash) {
    /* \smash{ */
    fputs(f2lto_c8_kw[23], of);
  }
  if(job->mbox) {
    /* \mbox{ */
    fputs(f2lto_c8_kw[24], of);
  }
  fputs(f2lto_c8_kw[38], of); 
  /* font selection */
  f2l_tool_font_selection(of, job, drw, obj, nFonts);
  fputs(f2lto_c8_kw[25], of);
  /* red */
  dk3ma_print_double_c8_no_sci(of, rgb.r);
  fputs(f2lto_c8_kw[14], of);
  /* green */
  dk3ma_print_double_c8_no_sci(of, rgb.g);
  fputs(f2lto_c8_kw[14], of);
  /* blue */
  dk3ma_print_double_c8_no_sci(of, rgb.b);
  fputs(f2lto_c8_kw[16], of);
  /* text */
  if(((obj->dt).txt.ff) & DK3_FIG_FONT_FLAG_SPECIAL) {
    fputs((obj->dt).txt.st, of);
  } else {
    f2l_tool_tex_string(of, (obj->dt).txt.st);
  }
  fputs(f2lto_c8_kw[16], of);
  if(job->mbox) {
    /* } */
    fputs(f2lto_c8_kw[16], of);
  }
  if(job->smash) {
    /* } */
    fputs(f2lto_c8_kw[16], of);
  }
}


void
f2l_tool_text_object(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  dk3_fig_obj_t		*obj,
  double		 x,
  double		 y,
  unsigned long		 nFonts
)
{
  double	 an;			/* Rotation in degree. */
  double	 ian;			/* Rotation as integer. */
  int		 haverotation = 0;	/* Flag: Have rotation. */

  /* \put( */
  fputs(f2lto_c8_kw[13], of);
  /* x position */
  dk3ma_print_double_c8_no_sci(of, x);
  /* , */
  fputs(f2lto_c8_kw[14], of);
  /* y position */
  dk3ma_print_double_c8_no_sci(of, y);
  /* ){ */
  fputs(f2lto_c8_kw[15], of);
  if(fabs((obj->dt).txt.an) > 1.0e-6) {
    haverotation = 1;
    an  = ((obj->dt).txt.an * 180.0) / M_PI;
    ian = dk3ma_rint(an);
    if(fabs(an - ian) < 1.0e-3) {
      an = ian;
    }
    /* \rotatebox{ */
    fputs(f2lto_c8_kw[17], of);
    /* degrees */
    dk3ma_print_double_c8_no_sci(of, an);
    /* }{ */
    fputs(f2lto_c8_kw[7], of);
  }
  /* \makebox(0,0)[ */
  fputs(f2lto_c8_kw[18], of);
  /* justification */
  switch(obj->st) {
    case 2: {
      fputs(f2lto_c8_kw[22], of);
    } break;
    case 1: {
      fputs(f2lto_c8_kw[21], of);
    } break;
    default: {
      fputs(f2lto_c8_kw[20], of);
    } break;
  }
  /* ]{ */
  fputs(f2lto_c8_kw[19], of);
  f2l_tool_inner_text_object(of, job, drw, obj, nFonts);
  /* } */
  fputs(f2lto_c8_kw[16], of);
  if(haverotation) {
    /* } */
    fputs(f2lto_c8_kw[16], of);
  }
  /* } */
  fputs(f2lto_c8_kw[16], of);
  fputs(f2lto_c8_kw[26], of);
}



void
f2l_tool_image_delete(f2l_image_t *im)
{
  

#line 1302 "f2lto.ctr"
  if(im) {	

#line 1303 "f2lto.ctr"
    if(im->filename) {
      dk3_delete(im->filename)
    }
    im->filename = NULL;
    im->xo = NULL;
    im->width = 0UL;
    im->height = 0UL;
    im->xres = 0.0;
    im->yres = 0.0;
    im->imageNumber = 0UL;
    im->lineno = 0UL;
    dk3_delete(im)
  } 

#line 1316 "f2lto.ctr"
}



f2l_image_t *
f2l_tool_image_new(char const *filename, dk3_app_t *app, unsigned long li)
{
  dk3_ufi_t		 ufi;		/* Unique file identifier. */
  f2l_image_t		*back = NULL;
  

#line 1326 "f2lto.ctr"
  if((filename) && (app)) {
    if(dk3ufi_c8_get(&ufi, filename)) {
      back = dk3_new_app(f2l_image_t,1,app);
      if(back) {
        dk3mem_cpy((void *)(&(back->ufi)), (void *)(&ufi), sizeof(dk3_ufi_t));
	back->xo = NULL;
	back->width = 0UL;
	back->height = 0UL;
	back->xres = 0.0;
	back->yres = 0.0;
	back->imageNumber = 0UL;
	back->lineno = li;
	back->filename = dk3str_c8_dup_app(filename, app);
	if(!(back->filename)) {
	  f2l_tool_image_delete(back);
	  back = NULL;
	}
      }
    }
  } 

#line 1346 "f2lto.ctr"
  return back;
}



int
f2l_tool_compare_images(void *l, void *r, int cr)
{
  f2l_image_t		*pl;		/* Left object. */
  f2l_image_t		*pr;		/* Right object. */
  int		 	 back = 0;

  if(l) {
    if(r) {
      pl = (f2l_image_t *)l;
      pr = (f2l_image_t *)r;
      switch(cr) {
        case 1: {
	  back = dk3ufi_compare((void *)(&(pl->ufi)), r, 0);
	} break;
	default: {
	  back = dk3ufi_compare((void *)(&(pl->ufi)), (void *)(&(pr->ufi)), 0);
	} break;
      }
    } else { back = 1; }
  } else {
    if(r) { back = -1; }
  }
  return back;
}



void
f2l_tool_set_exit_status(f2l_job_t *job, int exval)
{
  if(job) {
    if(0 == job->exval) {
      job->exval = exval;
    }
  }
}



/**	Write entire section of text to output file.
	@param	of	Output file.
	@param	txt	Pointer to array of text lines, NULL-finalized.
*/
static
void
f2l_tool_add_text_section_to_file(FILE *of, char const * const *txt)
{
  char const * const	*ptr;	/* Current line to add. */

  ptr = txt;
  while(*ptr) {
    fputs(*ptr, of);
    fputc('\n', of);
    ptr++;
  }
}



/**	Write preamble part to output file, either the contents of a
	file (if found) or a default text.
	@param	of		Output file.
	@param	job		Job structure.
	@param	drw		Drawing structure.
	@param	fileName	Name of file containing the preamble part.
	@param	preamble	Default preamble text if fileName is not found.
*/
static
void
fl2_tool_write_preamble_part_or_file(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  char const		*fileName,
  char const * const	*preamble
)
{
  char 		 line[1024];	/* Line buffer to read input file. */
  FILE		*fipo;		/* Input file. */
  int		 done = 0;	/* Flag: Successfully handled file. */
  

#line 1433 "f2lto.ctr"
  fipo = fopen(fileName, f2lto_c8_kw[46]);
  if(fipo) {		

#line 1435 "f2lto.ctr"
    done = 1;
    while(fgets(line, sizeof(line), fipo)) {	

#line 1437 "f2lto.ctr"
      dk3str_c8_chomp(line, NULL);		

#line 1438 "f2lto.ctr"
      fputs(line, of);				

#line 1439 "f2lto.ctr"
      fputc('\n', of);				

#line 1440 "f2lto.ctr"
    }
    fclose(fipo);
  } else {		

#line 1443 "f2lto.ctr"
  }
  if(!(done)) {			

#line 1445 "f2lto.ctr"
    f2l_tool_add_text_section_to_file(of, preamble);
  }
  

#line 1448 "f2lto.ctr"
}



void
f2l_tool_begin_latex_document(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw
)
{
  fprintf(of, f2lto_c8_kw[40], job->tts);
#if 0
  f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_1);
#else
  fl2_tool_write_preamble_part_or_file(
    of, job, drw, f2lto_c8_kw[44], f2l_tool_preamble_1
  );
#endif
#if 0
  f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_2);
#else
  fl2_tool_write_preamble_part_or_file(
    of, job, drw, f2lto_c8_kw[45], f2l_tool_preamble_2
  );
#endif
  f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_3);
  switch(job->dr) {
    case FIG2LAT_DRIVER_PGF:
    case FIG2LAT_DRIVER_TEX_FULL_PGF: {
      fputs(f2lto_c8_kw[43], of);
    } break;
  }
  fprintf(of, f2lto_c8_kw[41], job->lwidth);
  fprintf(of, f2lto_c8_kw[42], job->lheight);
  f2l_tool_add_text_section_to_file(of, f2l_tool_preamble_4);
}



void
f2l_tool_end_latex_document(
  FILE			*of,
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw
)
{
  fputs(f2lto_c8_kw[39], of);
}



int
f2lto_find_draw_direction(
  f2l_job_t		*job,
  dk3_fig_drawing_t	*drw,
  dk3_fig_obj_t		*obj,
  int			*ec
)
{
  dk3_fig_poly_point_t	*po;	/* Point set. */
  size_t		 np;	/* Number of points. */
  int		 back = 0;
  

#line 1512 "f2lto.ctr"
  if(DK3_FIG_SRCTYPE_JFIG != drw->srctype) {		

#line 1513 "f2lto.ctr"
    po = (obj->dt).pol.po;
    np = (obj->dt).pol.np;
    if(4 <= np) {					

#line 1516 "f2lto.ctr"
      if(po[1].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
        /* 0 on the left, 1 on the right */
	if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
	  back = 0;
	} else {
	  back = 1;
	}
      } else {
        if(po[1].x < (dk3ma_d_sub_ok(po[0].x, 0.5, ec))) {
	  /* 0 on the right, 1 on the left. */
	  if(po[3].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
	    back = 2;
	  } else {
	    back = 3;
	  }
	} else {
	  /* 0 and 1 in one row. */
	  if(po[2].x > (dk3ma_d_add_ok(po[0].x, 0.5, ec))) {
	    /* 0 and 1 left */
	    if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
	      back = 0;
	    } else {
	      back = 1;
	    }
	  } else {
	    /* 0 and 1 right */
	    if(po[1].y > (dk3ma_d_add_ok(po[0].y, 0.5, ec))) {
	      back = 2;
	    } else {
	      back = 3;
	    }
	  }
	}
      }
      if((obj->dt).pol.flf) {		

#line 1551 "f2lto.ctr"
        back += 4;
      } else {				

#line 1553 "f2lto.ctr"
      }
    } else {				

#line 1555 "f2lto.ctr"
    }
  } else {				

#line 1557 "f2lto.ctr"
  } 

#line 1558 "f2lto.ctr"
  return back;
}



double
f2lto_find_gap_length(f2l_job_t *job, double lw, double lsv)
{
  double	back;
  if(job->cols) {
    back = lsv;
  } else {
    back = 0.5 * lw + 0.5 * lsv;
    if((0.5 * back) > lw) {
      back = 2.0 * lw;
    }
  }
  return back;
}

