| 1 | /* |
|---|
| 2 | * TransFig: Facility for Translating Fig code |
|---|
| 3 | * Copyright (c) 1985 Supoj Sutantavibul |
|---|
| 4 | * Copyright (c) 1991 Micah Beck |
|---|
| 5 | * |
|---|
| 6 | * Permission to use, copy, modify, distribute, and sell this software and its |
|---|
| 7 | * documentation for any purpose is hereby granted without fee, provided that |
|---|
| 8 | * the above copyright notice appear in all copies and that both that |
|---|
| 9 | * copyright notice and this permission notice appear in supporting |
|---|
| 10 | * documentation. The authors make no representations about the suitability |
|---|
| 11 | * of this software for any purpose. It is provided "as is" without express |
|---|
| 12 | * or implied warranty. |
|---|
| 13 | * |
|---|
| 14 | * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
|---|
| 15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
|---|
| 16 | * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
|---|
| 17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
|---|
| 18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
|---|
| 19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|---|
| 20 | * PERFORMANCE OF THIS SOFTWARE. |
|---|
| 21 | * |
|---|
| 22 | */ |
|---|
| 23 | |
|---|
| 24 | /* |
|---|
| 25 | * genps.c: PostScript driver for fig2dev |
|---|
| 26 | * |
|---|
| 27 | * Modified by Herbert Bauer to support ISO-Characters, |
|---|
| 28 | * multiple page output, color mode etc. |
|---|
| 29 | * heb@regent.e-technik.tu-muenchen.de |
|---|
| 30 | * |
|---|
| 31 | * Modified by Eric Picheral to support the whole set of ISO-Latin-1 |
|---|
| 32 | * Modified by Herve Soulard to allow non-iso coding on special fonts |
|---|
| 33 | * Herve.Soulard@inria.fr (8 Apr 1993) |
|---|
| 34 | |
|---|
| 35 | */ |
|---|
| 36 | |
|---|
| 37 | #include <sys/param.h> |
|---|
| 38 | #if defined(hpux) || defined(SYSV) || defined(BSD4_3) |
|---|
| 39 | #include <sys/types.h> |
|---|
| 40 | #endif |
|---|
| 41 | #include <sys/file.h> |
|---|
| 42 | #include <stdio.h> |
|---|
| 43 | #include <math.h> |
|---|
| 44 | #include <pwd.h> |
|---|
| 45 | #include <errno.h> |
|---|
| 46 | |
|---|
| 47 | #if !defined(LINUX) && !defined(linux) |
|---|
| 48 | extern char *sys_errlist[]; |
|---|
| 49 | #endif |
|---|
| 50 | |
|---|
| 51 | #include "pi.h" |
|---|
| 52 | #include "object.h" |
|---|
| 53 | #include "fig2dev.h" |
|---|
| 54 | #include "psfonts.h" |
|---|
| 55 | //#include <string.h> |
|---|
| 56 | #include <time.h> |
|---|
| 57 | |
|---|
| 58 | /* for the version nubmer */ |
|---|
| 59 | #include "../patchlevel.h" |
|---|
| 60 | |
|---|
| 61 | #ifdef A4 |
|---|
| 62 | #define PAGE_WIDTH 595 /* points; 21cm */ |
|---|
| 63 | #define PAGE_HEIGHT 842 /* points; 29.7cm */ |
|---|
| 64 | #else |
|---|
| 65 | #define PAGE_WIDTH 612 /* points; 8.5" */ |
|---|
| 66 | #define PAGE_HEIGHT 792 /* points; 11" */ |
|---|
| 67 | #endif |
|---|
| 68 | #define TRUE 1 |
|---|
| 69 | #define FALSE 0 |
|---|
| 70 | #define POINT_PER_INCH 72 |
|---|
| 71 | #define ULIMIT_FONT_SIZE 300 |
|---|
| 72 | #define MAXCOLORS 16 |
|---|
| 73 | |
|---|
| 74 | int pagewidth = PAGE_WIDTH; |
|---|
| 75 | int pageheight = PAGE_HEIGHT; |
|---|
| 76 | static int coord_system; |
|---|
| 77 | int show_page = 0; |
|---|
| 78 | static int cur_thickness; |
|---|
| 79 | int center = 0; |
|---|
| 80 | int landscape = 0; |
|---|
| 81 | int pages; |
|---|
| 82 | int no_obj = 0; |
|---|
| 83 | int multi_page = FALSE; |
|---|
| 84 | |
|---|
| 85 | extern int v2_flag, v21_flag; |
|---|
| 86 | |
|---|
| 87 | static arc_tangent(); |
|---|
| 88 | static draw_arrow_head(); |
|---|
| 89 | static fill_area(); |
|---|
| 90 | static iso_text_exist(); |
|---|
| 91 | static encode_all_fonts(); |
|---|
| 92 | static ellipse_exist(); |
|---|
| 93 | static normal_spline_exist(); |
|---|
| 94 | |
|---|
| 95 | #define GRAYVAL(F) ((F) <= 21 ? ((F)-1)/20.0 : 1.0) |
|---|
| 96 | |
|---|
| 97 | #define BEGIN_PROLOG "\ |
|---|
| 98 | /$F2psDict 200 dict def \n\ |
|---|
| 99 | $F2psDict begin\n\ |
|---|
| 100 | $F2psDict /mtrx matrix put\n\ |
|---|
| 101 | /l {lineto} bind def\n\ |
|---|
| 102 | /m {moveto} bind def\n\ |
|---|
| 103 | /s {stroke} bind def\n\ |
|---|
| 104 | /n {newpath} bind def\n\ |
|---|
| 105 | /gs {gsave} bind def\n\ |
|---|
| 106 | /gr {grestore} bind def\n\ |
|---|
| 107 | /clp {closepath} bind def\n\ |
|---|
| 108 | /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul\n\ |
|---|
| 109 | 4 -2 roll mul setrgbcolor} bind def\n\ |
|---|
| 110 | /col-1 {} def\n\ |
|---|
| 111 | /col0 {0 0 0 setrgbcolor} bind def\n\ |
|---|
| 112 | /col1 {0 0 1 setrgbcolor} bind def\n\ |
|---|
| 113 | /col2 {0 1 0 setrgbcolor} bind def\n\ |
|---|
| 114 | /col3 {0 1 1 setrgbcolor} bind def\n\ |
|---|
| 115 | /col4 {1 0 0 setrgbcolor} bind def\n\ |
|---|
| 116 | /col5 {1 0 1 setrgbcolor} bind def\n\ |
|---|
| 117 | /col6 {1 1 0 setrgbcolor} bind def\n\ |
|---|
| 118 | /col7 {1 1 1 setrgbcolor} bind def\n\ |
|---|
| 119 | /col8 {.68 .85 .9 setrgbcolor} bind def\n\ |
|---|
| 120 | /col9 {0 .39 0 setrgbcolor} bind def\n\ |
|---|
| 121 | /col10 {.65 .17 .17 setrgbcolor} bind def\n\ |
|---|
| 122 | /col11 {1 .51 0 setrgbcolor} bind def\n\ |
|---|
| 123 | /col12 {.63 .13 .94 setrgbcolor} bind def\n\ |
|---|
| 124 | /col13 {1 .75 .8 setrgbcolor} bind def\n\ |
|---|
| 125 | /col14 {.7 .13 .13 setrgbcolor} bind def\n\ |
|---|
| 126 | /col15 {1 .84 0 setrgbcolor} bind def\n\ |
|---|
| 127 | " |
|---|
| 128 | |
|---|
| 129 | #define SPECIAL_CHAR_1 "\ |
|---|
| 130 | /reencdict 12 dict def /ReEncode { reencdict begin\n\ |
|---|
| 131 | /newcodesandnames exch def /newfontname exch def /basefontname exch def\n\ |
|---|
| 132 | /basefontdict basefontname findfont def /newfont basefontdict maxlength dict def\n\ |
|---|
| 133 | basefontdict { exch dup /FID ne { dup /Encoding eq\n\ |
|---|
| 134 | { exch dup length array copy newfont 3 1 roll put }\n\ |
|---|
| 135 | { exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall\n\ |
|---|
| 136 | newfont /FontName newfontname put newcodesandnames aload pop\n\ |
|---|
| 137 | 128 1 255 { newfont /Encoding get exch /.notdef put } for\n\ |
|---|
| 138 | newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat\n\ |
|---|
| 139 | newfontname newfont definefont pop end } def\n\ |
|---|
| 140 | /isovec [ \n\ |
|---|
| 141 | " |
|---|
| 142 | #define SPECIAL_CHAR_2 "\ |
|---|
| 143 | 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde\n\ |
|---|
| 144 | 8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis\n\ |
|---|
| 145 | 8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron\n\ |
|---|
| 146 | 8#220 /dotlessi 8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling\n\ |
|---|
| 147 | 8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis\n\ |
|---|
| 148 | 8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot\n\ |
|---|
| 149 | 8#255 /endash 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus\n\ |
|---|
| 150 | 8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph\n\ |
|---|
| 151 | 8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine\n\ |
|---|
| 152 | 8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf \n\ |
|---|
| 153 | 8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute\n\ |
|---|
| 154 | 8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring\n\ |
|---|
| 155 | " |
|---|
| 156 | #define SPECIAL_CHAR_3 "\ |
|---|
| 157 | 8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute\n\ |
|---|
| 158 | 8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute\n\ |
|---|
| 159 | 8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve\n\ |
|---|
| 160 | 8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply\n\ |
|---|
| 161 | 8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex\n\ |
|---|
| 162 | 8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave\n\ |
|---|
| 163 | 8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring\n\ |
|---|
| 164 | 8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute\n\ |
|---|
| 165 | 8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute\n\ |
|---|
| 166 | 8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve\n\ |
|---|
| 167 | 8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide\n\ |
|---|
| 168 | 8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex\n\ |
|---|
| 169 | 8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis \ |
|---|
| 170 | ] def\n\ |
|---|
| 171 | " |
|---|
| 172 | |
|---|
| 173 | #define ELLIPSE_PS " \ |
|---|
| 174 | /DrawEllipse {\n\ |
|---|
| 175 | /endangle exch def\n\ |
|---|
| 176 | /startangle exch def\n\ |
|---|
| 177 | /yrad exch def\n\ |
|---|
| 178 | /xrad exch def\n\ |
|---|
| 179 | /y exch def\n\ |
|---|
| 180 | /x exch def\n\ |
|---|
| 181 | /savematrix mtrx currentmatrix def\n\ |
|---|
| 182 | x y translate xrad yrad scale 0 0 1 startangle endangle arc\n\ |
|---|
| 183 | savematrix setmatrix\n\ |
|---|
| 184 | } def\n\ |
|---|
| 185 | " |
|---|
| 186 | /* The original PostScript definition for adding a spline section to the |
|---|
| 187 | * current path uses recursive bisection. The following definition using the |
|---|
| 188 | * curveto operator is more efficient since it executes at compiled rather |
|---|
| 189 | * than interpreted code speed. The Bezier control points are 2/3 of the way |
|---|
| 190 | * from z1 (and z3) to z2. |
|---|
| 191 | * |
|---|
| 192 | * ---Rene Llames, 21 July 1988. |
|---|
| 193 | */ |
|---|
| 194 | #define SPLINE_PS " \ |
|---|
| 195 | /DrawSplineSection {\n\ |
|---|
| 196 | /y3 exch def\n\ |
|---|
| 197 | /x3 exch def\n\ |
|---|
| 198 | /y2 exch def\n\ |
|---|
| 199 | /x2 exch def\n\ |
|---|
| 200 | /y1 exch def\n\ |
|---|
| 201 | /x1 exch def\n\ |
|---|
| 202 | /xa x1 x2 x1 sub 0.666667 mul add def\n\ |
|---|
| 203 | /ya y1 y2 y1 sub 0.666667 mul add def\n\ |
|---|
| 204 | /xb x3 x2 x3 sub 0.666667 mul add def\n\ |
|---|
| 205 | /yb y3 y2 y3 sub 0.666667 mul add def\n\ |
|---|
| 206 | x1 y1 lineto\n\ |
|---|
| 207 | xa ya xb yb x3 y3 curveto\n\ |
|---|
| 208 | } def\n\ |
|---|
| 209 | " |
|---|
| 210 | #define END_PROLOG "\ |
|---|
| 211 | end\n\ |
|---|
| 212 | /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def\n\ |
|---|
| 213 | /$F2psEnd {$F2psEnteredState restore end} def\n\ |
|---|
| 214 | %%EndProlog\n\ |
|---|
| 215 | " |
|---|
| 216 | |
|---|
| 217 | static double tx, scalex, scaley; |
|---|
| 218 | static double dx, dy, origx, origy; |
|---|
| 219 | |
|---|
| 220 | void genps_option(opt, optarg) |
|---|
| 221 | char opt; |
|---|
| 222 | char *optarg; |
|---|
| 223 | { |
|---|
| 224 | int i; |
|---|
| 225 | |
|---|
| 226 | extern char *getenv(); |
|---|
| 227 | char *papersize; |
|---|
| 228 | |
|---|
| 229 | if (papersize = getenv("FIG2DEV_SIZE")) |
|---|
| 230 | { |
|---|
| 231 | if (strcmp(papersize, "A4") == 0) |
|---|
| 232 | { |
|---|
| 233 | pagewidth = 595; |
|---|
| 234 | pageheight = 842; |
|---|
| 235 | } |
|---|
| 236 | else if (strcmp(papersize, "A3") == 0) |
|---|
| 237 | { |
|---|
| 238 | pagewidth = 842; |
|---|
| 239 | pageheight = 1190; |
|---|
| 240 | } |
|---|
| 241 | else if (strcmp(papersize, "A2") == 0) |
|---|
| 242 | { |
|---|
| 243 | pagewidth = 1190; |
|---|
| 244 | pageheight = 1684; |
|---|
| 245 | } |
|---|
| 246 | else if (strcmp(papersize, "A1") == 0) |
|---|
| 247 | { |
|---|
| 248 | pagewidth = 1684; |
|---|
| 249 | pageheight = 2380; |
|---|
| 250 | } |
|---|
| 251 | else if (strcmp(papersize, "A0") == 0) |
|---|
| 252 | { |
|---|
| 253 | pagewidth = 2380; |
|---|
| 254 | pageheight = 3368; |
|---|
| 255 | } |
|---|
| 256 | else if (strcmp(papersize, "A0_LONG") == 0) |
|---|
| 257 | { |
|---|
| 258 | pagewidth = 2380; |
|---|
| 259 | pageheight = 99999; |
|---|
| 260 | } |
|---|
| 261 | } |
|---|
| 262 | |
|---|
| 263 | switch (opt) { |
|---|
| 264 | |
|---|
| 265 | case 'f': |
|---|
| 266 | for ( i = 1; i <= MAX_PSFONT + 1; i++ ) |
|---|
| 267 | if ( !strcmp(optarg, PSfontnames[i]) ) break; |
|---|
| 268 | |
|---|
| 269 | if ( i > MAX_PSFONT + 1 ) |
|---|
| 270 | fprintf(stderr, |
|---|
| 271 | "warning: non-standard font name %s\n", optarg); |
|---|
| 272 | |
|---|
| 273 | psfontnames[0] = psfontnames[1] = optarg; |
|---|
| 274 | PSfontnames[0] = PSfontnames[1] = optarg; |
|---|
| 275 | break; |
|---|
| 276 | |
|---|
| 277 | case 'c': |
|---|
| 278 | center = 1; |
|---|
| 279 | break; |
|---|
| 280 | |
|---|
| 281 | case 's': |
|---|
| 282 | if (font_size <= 0 || font_size > ULIMIT_FONT_SIZE) { |
|---|
| 283 | fprintf(stderr, |
|---|
| 284 | "warning: font size %d out of bounds\n", font_size); |
|---|
| 285 | } |
|---|
| 286 | break; |
|---|
| 287 | |
|---|
| 288 | case 'P': |
|---|
| 289 | show_page = 1; |
|---|
| 290 | break; |
|---|
| 291 | |
|---|
| 292 | case 'm': |
|---|
| 293 | case 'L': |
|---|
| 294 | break; |
|---|
| 295 | |
|---|
| 296 | case 'l': |
|---|
| 297 | landscape = 1; |
|---|
| 298 | break; |
|---|
| 299 | |
|---|
| 300 | default: |
|---|
| 301 | put_msg(Err_badarg, opt, "ps"); |
|---|
| 302 | exit(1); |
|---|
| 303 | break; |
|---|
| 304 | } |
|---|
| 305 | } |
|---|
| 306 | |
|---|
| 307 | void genps_start(objects) |
|---|
| 308 | F_compound *objects; |
|---|
| 309 | { |
|---|
| 310 | char host[256]; |
|---|
| 311 | struct passwd *who; |
|---|
| 312 | time_t when; |
|---|
| 313 | int itmp; |
|---|
| 314 | int resolution; |
|---|
| 315 | |
|---|
| 316 | resolution = objects->nwcorner.x; |
|---|
| 317 | coord_system = objects->nwcorner.y; |
|---|
| 318 | scalex = scaley = mag * POINT_PER_INCH / (double)resolution; |
|---|
| 319 | /* convert to point unit */ |
|---|
| 320 | llx = (int)ceil(llx * scalex); lly = (int)ceil(lly * scaley); |
|---|
| 321 | urx = (int)ceil(urx * scalex); ury = (int)ceil(ury * scaley); |
|---|
| 322 | |
|---|
| 323 | |
|---|
| 324 | if (landscape) |
|---|
| 325 | { |
|---|
| 326 | itmp = pageheight; pageheight = pagewidth; pagewidth = itmp; |
|---|
| 327 | itmp = llx; llx = lly; lly = itmp; |
|---|
| 328 | itmp = urx; urx = ury; ury = itmp; |
|---|
| 329 | } |
|---|
| 330 | if (show_page) |
|---|
| 331 | { |
|---|
| 332 | if (center) |
|---|
| 333 | { |
|---|
| 334 | if (landscape) |
|---|
| 335 | { |
|---|
| 336 | origx = (pageheight - urx - llx)/2.0; |
|---|
| 337 | origy = (pagewidth - ury - lly)/2.0; |
|---|
| 338 | } |
|---|
| 339 | else |
|---|
| 340 | { |
|---|
| 341 | origx = (pagewidth - urx - llx)/2.0; |
|---|
| 342 | origy = (pageheight + ury + lly)/2.0; |
|---|
| 343 | } |
|---|
| 344 | } |
|---|
| 345 | else |
|---|
| 346 | { |
|---|
| 347 | origx = 0.0; |
|---|
| 348 | origy = landscape ? 0.0 : pageheight; |
|---|
| 349 | } |
|---|
| 350 | } |
|---|
| 351 | else |
|---|
| 352 | { |
|---|
| 353 | origx = -llx; |
|---|
| 354 | origy = landscape ? -lly : ury; |
|---|
| 355 | } |
|---|
| 356 | |
|---|
| 357 | if (coord_system == 2) scaley = -scaley; |
|---|
| 358 | |
|---|
| 359 | if (show_page) |
|---|
| 360 | fprintf(tfp, "%%!PS-Adobe-2.0\n"); /* PostScript magic strings */ |
|---|
| 361 | else |
|---|
| 362 | fprintf(tfp, "%%!PS-Adobe-2.0 EPSF-2.0\n"); /* Encapsulated PostScript */ |
|---|
| 363 | who = getpwuid(getuid()); |
|---|
| 364 | if (-1 == gethostname(host, sizeof(host))) |
|---|
| 365 | (void)strcpy(host, "unknown-host!?!?"); |
|---|
| 366 | (void) time(&when); |
|---|
| 367 | fprintf(tfp, "%%%%Title: %s\n", ((from) ? from : "stdin")); |
|---|
| 368 | fprintf(tfp, "%%%%Creator: %s Version %s Patchlevel %s\n", |
|---|
| 369 | prog, VERSION, PATCHLEVEL); |
|---|
| 370 | fprintf(tfp, "%%%%CreationDate: %s", ctime(&when)); |
|---|
| 371 | if (who) |
|---|
| 372 | fprintf(tfp, "%%%%For: %s@%s (%s)\n", |
|---|
| 373 | who->pw_name, host, who->pw_gecos); |
|---|
| 374 | |
|---|
| 375 | if (!center) |
|---|
| 376 | if (landscape) |
|---|
| 377 | pages = (urx/pageheight+1)*(ury/pagewidth+1); |
|---|
| 378 | else |
|---|
| 379 | pages = (urx/pagewidth+1)*(ury/pageheight+1); |
|---|
| 380 | else |
|---|
| 381 | pages = 1; |
|---|
| 382 | if (landscape) { |
|---|
| 383 | fprintf(tfp, "%%%%Orientation: Landscape\n"); |
|---|
| 384 | fprintf(tfp, "%%%%BoundingBox: %d %d %d %d\n", |
|---|
| 385 | (int)origx+llx, (int)origy+lly, (int)origx+urx, (int)origy+ury); |
|---|
| 386 | } else { |
|---|
| 387 | fprintf(tfp, "%%%%Orientation: Portrait\n"); |
|---|
| 388 | fprintf(tfp, "%%%%BoundingBox: %d %d %d %d\n", |
|---|
| 389 | (int)origx+llx, (int)origy-ury, (int)origx+urx, (int)origy-lly); |
|---|
| 390 | } |
|---|
| 391 | fprintf(tfp, "%%%%Pages: %d\n", show_page ? pages : 0 ); |
|---|
| 392 | |
|---|
| 393 | fprintf(tfp, "%%%%EndComments\n"); |
|---|
| 394 | fprintf(tfp, "%s", BEGIN_PROLOG); |
|---|
| 395 | if (iso_text_exist(objects)) |
|---|
| 396 | { |
|---|
| 397 | fprintf(tfp, "%s%s%s", SPECIAL_CHAR_1,SPECIAL_CHAR_2,SPECIAL_CHAR_3); |
|---|
| 398 | encode_all_fonts(objects); |
|---|
| 399 | } |
|---|
| 400 | if (ellipse_exist(objects)) fprintf(tfp, "%s\n", ELLIPSE_PS); |
|---|
| 401 | if (normal_spline_exist(objects)) fprintf(tfp, "%s\n", SPLINE_PS); |
|---|
| 402 | fprintf(tfp, "%s\n", END_PROLOG); |
|---|
| 403 | fprintf(tfp, "$F2psBegin\n"); |
|---|
| 404 | fprintf(tfp, "0 setlinecap 0 setlinejoin\n"); |
|---|
| 405 | |
|---|
| 406 | if ( pages > 1 && show_page && !center ) |
|---|
| 407 | multi_page = TRUE; |
|---|
| 408 | else |
|---|
| 409 | { |
|---|
| 410 | fprintf (tfp, "%.1f %.1f translate", origx, origy); |
|---|
| 411 | if (landscape) |
|---|
| 412 | { |
|---|
| 413 | fprintf (tfp, " 90 rotate"); |
|---|
| 414 | } |
|---|
| 415 | fprintf (tfp, " %.3f %.3f scale\n", scalex, scaley ); |
|---|
| 416 | } |
|---|
| 417 | } |
|---|
| 418 | |
|---|
| 419 | void genps_end() |
|---|
| 420 | { |
|---|
| 421 | double dx,dy; |
|---|
| 422 | int i, page; |
|---|
| 423 | int h,w; |
|---|
| 424 | |
|---|
| 425 | if (multi_page) |
|---|
| 426 | { |
|---|
| 427 | page = 1; |
|---|
| 428 | h = (landscape? pagewidth: pageheight); |
|---|
| 429 | w = (landscape? pageheight: pagewidth); |
|---|
| 430 | for (dy=0; dy < (ury-h*0.1); dy += h*0.9) |
|---|
| 431 | { |
|---|
| 432 | for (dx=0; dx < (urx-w*0.1); dx += w*0.9) |
|---|
| 433 | { |
|---|
| 434 | fprintf (tfp, "%%%%Page: %d %d\n%.1f %.1f translate", |
|---|
| 435 | page,page, |
|---|
| 436 | -(origx+dx), (origy+(landscape?-dy:dy))); |
|---|
| 437 | if (landscape) |
|---|
| 438 | { |
|---|
| 439 | fprintf(tfp, " 90 rotate"); |
|---|
| 440 | } |
|---|
| 441 | fprintf (tfp, " %.3f %.3f scale\n", scalex, scaley); |
|---|
| 442 | for (i=0; i<no_obj; i++) |
|---|
| 443 | { |
|---|
| 444 | fprintf(tfp, "o%d ", i); |
|---|
| 445 | if (!(i%20)) fprintf(tfp, "\n", i); |
|---|
| 446 | } |
|---|
| 447 | fprintf(tfp, "showpage\n"); |
|---|
| 448 | page++; |
|---|
| 449 | } |
|---|
| 450 | } |
|---|
| 451 | } |
|---|
| 452 | else |
|---|
| 453 | if (show_page) fprintf(tfp, "showpage\n"); |
|---|
| 454 | fprintf(tfp, "$F2psEnd\n"); |
|---|
| 455 | } |
|---|
| 456 | |
|---|
| 457 | static set_style(s, v) |
|---|
| 458 | int s; |
|---|
| 459 | double v; |
|---|
| 460 | { |
|---|
| 461 | if (s == DASH_LINE) { |
|---|
| 462 | if (v > 0.0) fprintf(tfp, "\t[%f] 0 setdash\n", v); |
|---|
| 463 | } |
|---|
| 464 | else if (s == DOTTED_LINE) { |
|---|
| 465 | if (v > 0.0) fprintf(tfp, "\t1 setlinecap [1 %f] %f setdash\n", v, v); |
|---|
| 466 | } |
|---|
| 467 | } |
|---|
| 468 | |
|---|
| 469 | static reset_style(s, v) |
|---|
| 470 | int s; |
|---|
| 471 | double v; |
|---|
| 472 | { |
|---|
| 473 | if (s == DASH_LINE) { |
|---|
| 474 | if (v > 0.0) fprintf(tfp, "\t[] 0 setdash\n"); |
|---|
| 475 | } |
|---|
| 476 | else if (s == DOTTED_LINE) { |
|---|
| 477 | if (v > 0.0) fprintf(tfp, "\t[] 0 setdash 0 setlinecap\n"); |
|---|
| 478 | } |
|---|
| 479 | } |
|---|
| 480 | |
|---|
| 481 | static set_linewidth(w) |
|---|
| 482 | int w; |
|---|
| 483 | { |
|---|
| 484 | extern int cur_thickness; |
|---|
| 485 | |
|---|
| 486 | if (w != cur_thickness) { |
|---|
| 487 | cur_thickness = w; |
|---|
| 488 | fprintf(tfp, "%.3f setlinewidth\n", cur_thickness <= 1 ? 0.5* cur_thickness : cur_thickness -1.0); |
|---|
| 489 | } |
|---|
| 490 | } |
|---|
| 491 | |
|---|
| 492 | void genps_line(l) |
|---|
| 493 | F_line *l; |
|---|
| 494 | { |
|---|
| 495 | F_point *p, *q; |
|---|
| 496 | /* JNT */ |
|---|
| 497 | int radius, i = 0; |
|---|
| 498 | FILE *epsf; |
|---|
| 499 | char buf[512]; |
|---|
| 500 | char *cp; |
|---|
| 501 | int xmin,xmax,ymin,ymax; |
|---|
| 502 | int eps_w, eps_h; |
|---|
| 503 | double fllx, flly, furx, fury; |
|---|
| 504 | |
|---|
| 505 | if (multi_page) |
|---|
| 506 | fprintf(tfp, "/o%d {", no_obj++); |
|---|
| 507 | if (l->type != T_EPS_BOX) /* eps object has no line thickness */ |
|---|
| 508 | set_linewidth(l->thickness); |
|---|
| 509 | radius = l->radius; /* radius of rounded-corner boxes */ |
|---|
| 510 | p = l->points; |
|---|
| 511 | q = p->next; |
|---|
| 512 | if (q == NULL) { /* A single point line */ |
|---|
| 513 | fprintf(tfp, "n %d %d m %d %d l gs col%d s gr\n", |
|---|
| 514 | p->x, p->y, p->x, p->y, l->color > MAXCOLORS ? -1 : l->color); |
|---|
| 515 | if (multi_page) |
|---|
| 516 | fprintf(tfp, "} bind def\n"); |
|---|
| 517 | return; |
|---|
| 518 | } |
|---|
| 519 | if (l->back_arrow && l->thickness > 0) |
|---|
| 520 | draw_arrow_head((double)q->x, (double)q->y, (double)p->x, |
|---|
| 521 | (double)p->y, l->back_arrow->ht, l->back_arrow->wid, |
|---|
| 522 | l->color); |
|---|
| 523 | if (l->type != T_EPS_BOX) /* eps object has no line style */ |
|---|
| 524 | set_style(l->style, l->style_val); |
|---|
| 525 | fprintf(tfp, "%% Polyline\n"); |
|---|
| 526 | |
|---|
| 527 | xmin = xmax = p->x; |
|---|
| 528 | ymin = ymax = p->y; |
|---|
| 529 | while (p->next != NULL) /* find lower left and upper right corne |
|---|
| 530 | rs */ |
|---|
| 531 | { |
|---|
| 532 | p=p->next; |
|---|
| 533 | if (xmin > p->x) |
|---|
| 534 | xmin = p->x; |
|---|
| 535 | else if (xmax < p->x) |
|---|
| 536 | xmax = p->x; |
|---|
| 537 | if (ymin > p->y) |
|---|
| 538 | ymin = p->y; |
|---|
| 539 | else if (ymax < p->y) |
|---|
| 540 | ymax = p->y; |
|---|
| 541 | } |
|---|
| 542 | |
|---|
| 543 | if (l->type == T_ARC_BOX) |
|---|
| 544 | { |
|---|
| 545 | fprintf(tfp, "n %d %d m",xmin+radius, ymin); |
|---|
| 546 | fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", |
|---|
| 547 | xmin, ymin, xmin, ymax-radius, radius); |
|---|
| 548 | fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc through bl to br */ |
|---|
| 549 | xmin, ymax, xmax-radius, ymax, radius); |
|---|
| 550 | fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc through br to tr */ |
|---|
| 551 | xmax, ymax, xmax, ymin+radius, radius); |
|---|
| 552 | fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc through tr to tl */ |
|---|
| 553 | xmax, ymin, xmin+radius, ymin, radius); |
|---|
| 554 | } |
|---|
| 555 | else if (l->type == T_EPS_BOX) /* encapsulated postscript (eps) file */ |
|---|
| 556 | { |
|---|
| 557 | int dx, dy, rotation; |
|---|
| 558 | int llx, lly, urx, ury; |
|---|
| 559 | double fllx, flly, furx, fury; |
|---|
| 560 | |
|---|
| 561 | dx = l->points->next->next->x - l->points->x; |
|---|
| 562 | dy = l->points->next->next->y - l->points->y; |
|---|
| 563 | rotation = 0; |
|---|
| 564 | if (dx < 0 && dy < 0) |
|---|
| 565 | rotation = 180; |
|---|
| 566 | else if (dx < 0 && dy >= 0) |
|---|
| 567 | rotation = 270; |
|---|
| 568 | else if (dy < 0 && dx >= 0) |
|---|
| 569 | rotation = 90; |
|---|
| 570 | |
|---|
| 571 | fprintf(tfp, "%%\n"); |
|---|
| 572 | fprintf(tfp, "%% Begin Imported EPS File: %s\n", l->eps->file); |
|---|
| 573 | fprintf(tfp, "%%\n"); |
|---|
| 574 | epsf = fopen(l->eps->file, "r"); |
|---|
| 575 | if (epsf == NULL) { |
|---|
| 576 | fprintf (stderr, "Unable to open eps file: %s, error: (%d)\n", |
|---|
| 577 | l->eps->file, sys_errlist[errno],errno); |
|---|
| 578 | return; |
|---|
| 579 | } |
|---|
| 580 | while (fgets(buf, 512, epsf) != NULL) { |
|---|
| 581 | lower(buf); |
|---|
| 582 | if (!strncmp(buf, "%%boundingbox", 13)) { |
|---|
| 583 | if (sscanf(buf, "%%%%boundingbox: %lf %lf %lf %lf", |
|---|
| 584 | &fllx, &flly, &furx, &fury) < 4) { |
|---|
| 585 | fprintf(stderr,"Bad EPS bitmap file: %s", l->eps->file); |
|---|
| 586 | fclose(epsf); |
|---|
| 587 | return; |
|---|
| 588 | } |
|---|
| 589 | llx= floor(fllx); |
|---|
| 590 | lly= floor(flly); |
|---|
| 591 | urx= ceil(furx); |
|---|
| 592 | ury= ceil(fury); |
|---|
| 593 | break; |
|---|
| 594 | } |
|---|
| 595 | } |
|---|
| 596 | fclose(epsf); |
|---|
| 597 | |
|---|
| 598 | fprintf(tfp, "n gs\n"); |
|---|
| 599 | if (((rotation == 90 || rotation == 270) && !l->eps->flipped) || |
|---|
| 600 | (rotation != 90 && rotation != 270 && l->eps->flipped)) { |
|---|
| 601 | eps_h = urx - llx; |
|---|
| 602 | eps_w = ury - lly; |
|---|
| 603 | } else { |
|---|
| 604 | eps_w = urx - llx; |
|---|
| 605 | eps_h = ury - lly; |
|---|
| 606 | } |
|---|
| 607 | |
|---|
| 608 | /* translate the eps stuff to the right spot on the page */ |
|---|
| 609 | fprintf(tfp, "%d %d translate\n", xmin, ymin); |
|---|
| 610 | |
|---|
| 611 | /* scale the eps stuff to fit into the bounding box */ |
|---|
| 612 | /* Note: the origin for fig is in the upper-right corner; |
|---|
| 613 | * for postscript its in the lower right hand corner. |
|---|
| 614 | * To fix it, we use a "negative"-y scale factor, then |
|---|
| 615 | * translate the image up on the page */ |
|---|
| 616 | fprintf(tfp, "%f %f scale\n", |
|---|
| 617 | fabs((double)(xmax-xmin)/eps_w), -1.0*(double)(ymax-ymin)/eps_h); |
|---|
| 618 | fprintf(tfp, "0 %d translate\n", -eps_h); |
|---|
| 619 | |
|---|
| 620 | /* flip the eps stuff */ |
|---|
| 621 | /* always translate it back so that the lower-left corner is at the origin */ |
|---|
| 622 | if (l->eps->flipped && rotation==90) { |
|---|
| 623 | fprintf(tfp, "0 %d translate\n", eps_h); |
|---|
| 624 | fprintf(tfp, "1 -1 scale\n"); |
|---|
| 625 | } |
|---|
| 626 | if (l->eps->flipped && rotation==270) { |
|---|
| 627 | fprintf(tfp, "%d 0 translate\n", eps_w); |
|---|
| 628 | fprintf(tfp, "-1 1 scale\n"); |
|---|
| 629 | } |
|---|
| 630 | |
|---|
| 631 | /* note: fig measures rotation clockwise; postscript is counter-clockwise */ |
|---|
| 632 | /* always translate it back so that the lower-left corner is at the origin */ |
|---|
| 633 | switch (rotation) { |
|---|
| 634 | case 0: |
|---|
| 635 | break; |
|---|
| 636 | case 90: |
|---|
| 637 | if (l->eps->flipped) break; |
|---|
| 638 | fprintf(tfp, "%d %d translate\n", 0, eps_h); |
|---|
| 639 | fprintf(tfp, "%d rotate\n", 270); |
|---|
| 640 | break; |
|---|
| 641 | case 180: |
|---|
| 642 | fprintf(tfp, "%d %d translate\n", eps_w, eps_h); |
|---|
| 643 | fprintf(tfp, "%d rotate\n", 180); |
|---|
| 644 | break; |
|---|
| 645 | case 270: |
|---|
| 646 | if (l->eps->flipped) break; |
|---|
| 647 | fprintf(tfp, "%d %d translate\n", eps_w, 0); |
|---|
| 648 | fprintf(tfp, "%d rotate\n", 90); |
|---|
| 649 | break; |
|---|
| 650 | } |
|---|
| 651 | |
|---|
| 652 | /* translate the eps stuff so that the lower-left corner is at the origin */ |
|---|
| 653 | fprintf(tfp, "%d %d translate\n", -llx, -lly); |
|---|
| 654 | /* save vm so eps file won't change anything */ |
|---|
| 655 | fprintf(tfp, "save\n"); |
|---|
| 656 | fprintf(tfp, "%% EPS file follows:\n"); |
|---|
| 657 | epsf = fopen(l->eps->file, "r"); |
|---|
| 658 | if (epsf == NULL) { |
|---|
| 659 | fprintf (stderr, "Unable to open eps file: %s, error: (%d)\n", |
|---|
| 660 | l->eps->file, sys_errlist[errno],errno); |
|---|
| 661 | fprintf(tfp, "gr\n"); |
|---|
| 662 | return; |
|---|
| 663 | } |
|---|
| 664 | while (fgets(buf, sizeof(buf), epsf) != NULL) { |
|---|
| 665 | if (*buf == '%') /* skip comment lines */ |
|---|
| 666 | continue; |
|---|
| 667 | if ((cp=strstr(buf, "showpage")) != NULL) |
|---|
| 668 | strcpy (cp, cp+8); /* remove showpage */ |
|---|
| 669 | fputs(buf, tfp); |
|---|
| 670 | } |
|---|
| 671 | fclose (epsf); |
|---|
| 672 | /* restore vm and gsave */ |
|---|
| 673 | fprintf(tfp, "restore gr\n"); |
|---|
| 674 | fprintf(tfp, "%%\n"); |
|---|
| 675 | fprintf(tfp, "%% End Imported EPS File: %s\n", l->eps->file); |
|---|
| 676 | fprintf(tfp, "%%\n"); |
|---|
| 677 | } |
|---|
| 678 | else |
|---|
| 679 | { |
|---|
| 680 | p = l->points; |
|---|
| 681 | q = p->next; |
|---|
| 682 | fprintf(tfp, "n %d %d m", p->x, p->y); |
|---|
| 683 | while (q->next != NULL) { |
|---|
| 684 | p = q; |
|---|
| 685 | q = q->next; |
|---|
| 686 | fprintf(tfp, " %d %d l ", p->x, p->y); |
|---|
| 687 | if (!((++i)%5)) |
|---|
| 688 | fprintf(tfp, "\n"); |
|---|
| 689 | } |
|---|
| 690 | } |
|---|
| 691 | if (l->type != T_EPS_BOX) { |
|---|
| 692 | if (l->type == T_POLYLINE) |
|---|
| 693 | fprintf(tfp, " %d %d l ", q->x, q->y); |
|---|
| 694 | else |
|---|
| 695 | fprintf(tfp, " clp "); |
|---|
| 696 | if (l->area_fill && (int)l->area_fill != DEFAULT) |
|---|
| 697 | fill_area(l->area_fill, l->color); |
|---|
| 698 | if (l->thickness > 0) |
|---|
| 699 | fprintf(tfp, "gs col%d s gr\n", |
|---|
| 700 | l->color > MAXCOLORS ? -1 : l->color); |
|---|
| 701 | |
|---|
| 702 | reset_style(l->style, l->style_val); |
|---|
| 703 | if (l->for_arrow && l->thickness > 0) |
|---|
| 704 | draw_arrow_head((double)p->x, (double)p->y, (double)q->x, |
|---|
| 705 | (double)q->y, l->for_arrow->ht, l->for_arrow->wid, |
|---|
| 706 | l->color); |
|---|
| 707 | } |
|---|
| 708 | if (multi_page) |
|---|
| 709 | fprintf(tfp, "} bind def\n"); |
|---|
| 710 | } |
|---|
| 711 | |
|---|
| 712 | void genps_spline(s) |
|---|
| 713 | F_spline *s; |
|---|
| 714 | { |
|---|
| 715 | if (multi_page) |
|---|
| 716 | fprintf(tfp, "/o%d {", no_obj++); |
|---|
| 717 | if (int_spline(s)) |
|---|
| 718 | genps_itp_spline(s); |
|---|
| 719 | else |
|---|
| 720 | genps_ctl_spline(s); |
|---|
| 721 | if (multi_page) |
|---|
| 722 | fprintf(tfp, "} bind def\n"); |
|---|
| 723 | } |
|---|
| 724 | |
|---|
| 725 | genps_itp_spline(s) |
|---|
| 726 | F_spline *s; |
|---|
| 727 | { |
|---|
| 728 | F_point *p, *q; |
|---|
| 729 | F_control *a, *b; |
|---|
| 730 | |
|---|
| 731 | set_linewidth(s->thickness); |
|---|
| 732 | a = s->controls; |
|---|
| 733 | p = s->points; |
|---|
| 734 | if (s->back_arrow && s->thickness > 0) |
|---|
| 735 | draw_arrow_head(a->rx, a->ry, (double)p->x, |
|---|
| 736 | (double)p->y, s->back_arrow->ht, s->back_arrow->wid, |
|---|
| 737 | s->color); |
|---|
| 738 | |
|---|
| 739 | set_style(s->style, s->style_val); |
|---|
| 740 | fprintf(tfp, "%% Interpolated spline\n"); |
|---|
| 741 | fprintf(tfp, "n %d %d m\n", p->x, p->y); |
|---|
| 742 | for (q = p->next; q != NULL; p = q, q = q->next) { |
|---|
| 743 | b = a->next; |
|---|
| 744 | fprintf(tfp, "\t%.3f %.3f %.3f %.3f %d %d curveto\n", |
|---|
| 745 | a->rx, a->ry, b->lx, b->ly, q->x, q->y); |
|---|
| 746 | a = b; |
|---|
| 747 | } |
|---|
| 748 | if (closed_spline(s)) fprintf(tfp, " clp "); |
|---|
| 749 | if (s->area_fill && (int)s->area_fill != DEFAULT) |
|---|
| 750 | fill_area(s->area_fill, s->color); |
|---|
| 751 | if (s->thickness > 0) |
|---|
| 752 | fprintf(tfp, "gs col%d s gr\n", s->color > MAXCOLORS ? -1 : s->color); |
|---|
| 753 | reset_style(s->style, s->style_val); |
|---|
| 754 | |
|---|
| 755 | if (s->for_arrow && s->thickness > 0) |
|---|
| 756 | draw_arrow_head(a->lx, a->ly, (double)p->x, |
|---|
| 757 | (double)p->y, s->for_arrow->ht, s->for_arrow->wid, |
|---|
| 758 | s->color); |
|---|
| 759 | } |
|---|
| 760 | |
|---|
| 761 | genps_ctl_spline(s) |
|---|
| 762 | F_spline *s; |
|---|
| 763 | { |
|---|
| 764 | double a, b, c, d, x1, y1, x2, y2, x3, y3; |
|---|
| 765 | F_point *p, *q; |
|---|
| 766 | |
|---|
| 767 | /* |
|---|
| 768 | if (first) { |
|---|
| 769 | first = FALSE; |
|---|
| 770 | fprintf(tfp, "%s\n", SPLINE_PS); |
|---|
| 771 | } |
|---|
| 772 | */ |
|---|
| 773 | |
|---|
| 774 | p = s->points; |
|---|
| 775 | x1 = p->x; y1 = p->y; |
|---|
| 776 | p = p->next; |
|---|
| 777 | c = p->x; d = p->y; |
|---|
| 778 | set_linewidth(s->thickness); |
|---|
| 779 | x3 = a = (x1 + c) / 2; |
|---|
| 780 | y3 = b = (y1 + d) / 2; |
|---|
| 781 | if (s->back_arrow && s->thickness > 0) { |
|---|
| 782 | draw_arrow_head(c, d, x1, y1, s->back_arrow->ht, s->back_arrow->wid, |
|---|
| 783 | s->color); |
|---|
| 784 | } |
|---|
| 785 | set_style(s->style, s->style_val); |
|---|
| 786 | if (! closed_spline(s)) { |
|---|
| 787 | fprintf(tfp, "%% Open spline\n"); |
|---|
| 788 | fprintf(tfp, "n %.3f %.3f m %.3f %.3f l\n", |
|---|
| 789 | x1, y1, x3, y3); |
|---|
| 790 | } |
|---|
| 791 | else { |
|---|
| 792 | fprintf(tfp, "%% Closed spline\n"); |
|---|
| 793 | fprintf(tfp, "n %.3f %.3f m\n", a, b); |
|---|
| 794 | } |
|---|
| 795 | for (q = p->next; q != NULL; p = q, q = q->next) { |
|---|
| 796 | x1 = x3; y1 = y3; |
|---|
| 797 | x2 = c; y2 = d; |
|---|
| 798 | c = q->x; d = q->y; |
|---|
| 799 | x3 = (x2 + c) / 2; |
|---|
| 800 | y3 = (y2 + d) / 2; |
|---|
| 801 | fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection\n", |
|---|
| 802 | x1, y1, x2, y2, x3, y3); |
|---|
| 803 | } |
|---|
| 804 | /* |
|---|
| 805 | * At this point, (x2,y2) and (c,d) are the position of the |
|---|
| 806 | * next-to-last and last point respectively, in the point list |
|---|
| 807 | */ |
|---|
| 808 | if (closed_spline(s)) { |
|---|
| 809 | fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection closepath ", |
|---|
| 810 | x3, y3, c, d, a, b); |
|---|
| 811 | } |
|---|
| 812 | else { |
|---|
| 813 | fprintf(tfp, "\t%.3f %.3f l ", c, d); |
|---|
| 814 | } |
|---|
| 815 | if (s->area_fill && (int)s->area_fill != DEFAULT) |
|---|
| 816 | fill_area(s->area_fill, s->color); |
|---|
| 817 | if (s->thickness > 0) |
|---|
| 818 | fprintf(tfp, "gs col%d s gr\n", s->color > MAXCOLORS ? -1 : s->color); |
|---|
| 819 | reset_style(s->style, s->style_val); |
|---|
| 820 | if (s->for_arrow && s->thickness > 0) { |
|---|
| 821 | draw_arrow_head(x2, y2, c, d, s->for_arrow->ht, |
|---|
| 822 | s->for_arrow->wid, s->color); |
|---|
| 823 | } |
|---|
| 824 | } |
|---|
| 825 | |
|---|
| 826 | void genps_ellipse(e) |
|---|
| 827 | F_ellipse *e; |
|---|
| 828 | { |
|---|
| 829 | if (multi_page) |
|---|
| 830 | fprintf(tfp, "/o%d {", no_obj++); |
|---|
| 831 | set_linewidth(e->thickness); |
|---|
| 832 | set_style(e->style, e->style_val); |
|---|
| 833 | if (e->angle == 0) |
|---|
| 834 | { |
|---|
| 835 | fprintf(tfp, "%% Ellipse\n"); |
|---|
| 836 | fprintf(tfp, "n %d %d %d %d 0 360 DrawEllipse ", |
|---|
| 837 | e->center.x, e->center.y, e->radiuses.x, e->radiuses.y); |
|---|
| 838 | } |
|---|
| 839 | else |
|---|
| 840 | { |
|---|
| 841 | fprintf(tfp, "%% Rotated Ellipse\n"); |
|---|
| 842 | fprintf(tfp, "gs\n"); |
|---|
| 843 | fprintf(tfp, "%d %d translate\n",e->center.x, e->center.y); |
|---|
| 844 | fprintf(tfp, "%6.3f rotate\n",-e->angle*180/M_PI); |
|---|
| 845 | fprintf(tfp, "n 0 0 %d %d 0 360 DrawEllipse ", |
|---|
| 846 | e->radiuses.x, e->radiuses.y); |
|---|
| 847 | } |
|---|
| 848 | if (e->area_fill && (int)e->area_fill != DEFAULT) |
|---|
| 849 | fill_area(e->area_fill, e->color); |
|---|
| 850 | if (e->thickness > 0) |
|---|
| 851 | fprintf(tfp, "gs col%d s gr\n", e->color > MAXCOLORS ? -1 : e->color); |
|---|
| 852 | if (e->angle != 0) |
|---|
| 853 | fprintf(tfp, "gr\n"); |
|---|
| 854 | reset_style(e->style, e->style_val); |
|---|
| 855 | if (multi_page) |
|---|
| 856 | fprintf(tfp, "} bind def\n"); |
|---|
| 857 | } |
|---|
| 858 | |
|---|
| 859 | #define TEXT_PS "\ |
|---|
| 860 | /%s%s findfont %.2f scalefont setfont\n\ |
|---|
| 861 | " |
|---|
| 862 | void genps_text(t) |
|---|
| 863 | F_text *t; |
|---|
| 864 | { |
|---|
| 865 | unsigned char *cp; |
|---|
| 866 | |
|---|
| 867 | if (multi_page) |
|---|
| 868 | fprintf(tfp, "/o%d {", no_obj++); |
|---|
| 869 | if (PSisomap[t->font+1] == TRUE) |
|---|
| 870 | fprintf(tfp, TEXT_PS, PSFONT(t), "-iso", PSFONTMAG(t)); |
|---|
| 871 | else |
|---|
| 872 | fprintf(tfp, TEXT_PS, PSFONT(t), "", PSFONTMAG(t)); |
|---|
| 873 | |
|---|
| 874 | fprintf(tfp, "%d %d m \ngs ", t->base_x, t->base_y); |
|---|
| 875 | if (coord_system == 2) fprintf(tfp, "1 -1 scale "); |
|---|
| 876 | |
|---|
| 877 | if (t->angle != 0) |
|---|
| 878 | fprintf(tfp, " %.1f rotate ", t->angle*180/M_PI); |
|---|
| 879 | /* this loop escapes characters '(', ')', and '\' */ |
|---|
| 880 | fputc('(', tfp); |
|---|
| 881 | for(cp = (unsigned char *)t->cstring; *cp; cp++) { |
|---|
| 882 | if (strchr("()\\", *cp)) |
|---|
| 883 | fputc('\\', tfp); |
|---|
| 884 | if (*cp>=0x80) |
|---|
| 885 | fprintf(tfp,"\\%o", *cp); |
|---|
| 886 | else |
|---|
| 887 | fputc(*cp, tfp); |
|---|
| 888 | } |
|---|
| 889 | fputc(')', tfp); |
|---|
| 890 | |
|---|
| 891 | if ((t->type == T_CENTER_JUSTIFIED) || (t->type == T_RIGHT_JUSTIFIED)){ |
|---|
| 892 | |
|---|
| 893 | fprintf(tfp, " dup stringwidth pop "); |
|---|
| 894 | if (t->type == T_CENTER_JUSTIFIED) fprintf(tfp, "2 div "); |
|---|
| 895 | fprintf(tfp, "neg 0 rmoveto "); |
|---|
| 896 | } |
|---|
| 897 | |
|---|
| 898 | else if ((t->type != T_LEFT_JUSTIFIED) && (t->type != DEFAULT)) |
|---|
| 899 | fprintf(stderr, "Text incorrectly positioned\n"); |
|---|
| 900 | |
|---|
| 901 | fprintf(tfp, " col%d show gr\n", t->color > MAXCOLORS ? -1 : t->color); |
|---|
| 902 | |
|---|
| 903 | if (multi_page) |
|---|
| 904 | fprintf(tfp, "} bind def\n"); |
|---|
| 905 | } |
|---|
| 906 | |
|---|
| 907 | void genps_arc(a) |
|---|
| 908 | F_arc *a; |
|---|
| 909 | { |
|---|
| 910 | double angle1, angle2, dx, dy, radius, x, y; |
|---|
| 911 | double cx, cy, sx, sy, ex, ey; |
|---|
| 912 | int direction; |
|---|
| 913 | |
|---|
| 914 | if (multi_page) |
|---|
| 915 | fprintf(tfp, "/o%d {", no_obj++); |
|---|
| 916 | cx = a->center.x; cy = a->center.y; |
|---|
| 917 | sx = a->point[0].x; sy = a->point[0].y; |
|---|
| 918 | ex = a->point[2].x; ey = a->point[2].y; |
|---|
| 919 | |
|---|
| 920 | if (coord_system == 2) |
|---|
| 921 | direction = !a->direction; |
|---|
| 922 | else |
|---|
| 923 | direction = a->direction; |
|---|
| 924 | set_linewidth(a->thickness); |
|---|
| 925 | if (a->for_arrow && a->thickness > 0) { |
|---|
| 926 | arc_tangent(cx, cy, ex, ey, direction, &x, &y); |
|---|
| 927 | draw_arrow_head(x, y, ex, ey, a->for_arrow->ht, a->for_arrow->wid, a->color); |
|---|
| 928 | } |
|---|
| 929 | if (a->back_arrow && a->thickness > 0) { |
|---|
| 930 | arc_tangent(cx, cy, sx, sy, !direction, &x, &y); |
|---|
| 931 | draw_arrow_head(x, y, sx, sy, a->back_arrow->ht, a->back_arrow->wid, a->color); |
|---|
| 932 | } |
|---|
| 933 | dx = cx - sx; |
|---|
| 934 | dy = cy - sy; |
|---|
| 935 | radius = sqrt(dx*dx+dy*dy); |
|---|
| 936 | angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI; |
|---|
| 937 | angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI; |
|---|
| 938 | /* direction = 1 -> Counterclockwise */ |
|---|
| 939 | set_style(a->style, a->style_val); |
|---|
| 940 | fprintf(tfp, "n %.3f %.3f %.3f %.3f %.3f %s\n", |
|---|
| 941 | cx, cy, radius, angle1, angle2, |
|---|
| 942 | ((direction == 1) ? "arc" : "arcn")); |
|---|
| 943 | if (a->area_fill && (int)a->area_fill != DEFAULT) |
|---|
| 944 | fill_area(a->area_fill, a->color); |
|---|
| 945 | if (a->thickness > 0) |
|---|
| 946 | fprintf(tfp, "gs col%d s gr\n", a->color > MAXCOLORS ? -1 : a->color); |
|---|
| 947 | reset_style(a->style, a->style_val); |
|---|
| 948 | if (multi_page) |
|---|
| 949 | fprintf(tfp, "} bind def\n"); |
|---|
| 950 | } |
|---|
| 951 | |
|---|
| 952 | static arc_tangent(x1, y1, x2, y2, direction, x, y) |
|---|
| 953 | double x1, y1, x2, y2, *x, *y; |
|---|
| 954 | int direction; |
|---|
| 955 | { |
|---|
| 956 | if (direction) { /* counter clockwise */ |
|---|
| 957 | *x = x2 + (y2 - y1); |
|---|
| 958 | *y = y2 - (x2 - x1); |
|---|
| 959 | } |
|---|
| 960 | else { |
|---|
| 961 | *x = x2 - (y2 - y1); |
|---|
| 962 | *y = y2 + (x2 - x1); |
|---|
| 963 | } |
|---|
| 964 | } |
|---|
| 965 | |
|---|
| 966 | /* draw arrow heading from (x1, y1) to (x2, y2) */ |
|---|
| 967 | |
|---|
| 968 | static draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid, col) |
|---|
| 969 | double x1, y1, x2, y2, arrowht, arrowwid; |
|---|
| 970 | int col; |
|---|
| 971 | { |
|---|
| 972 | double x, y, xb, yb, dx, dy, l, sina, cosa; |
|---|
| 973 | double xc, yc, xd, yd; |
|---|
| 974 | |
|---|
| 975 | dx = x2 - x1; dy = y1 - y2; |
|---|
| 976 | l = sqrt(dx*dx+dy*dy); |
|---|
| 977 | if (l == 0) { |
|---|
| 978 | return; |
|---|
| 979 | } |
|---|
| 980 | else { |
|---|
| 981 | sina = dy / l; cosa = dx / l; |
|---|
| 982 | } |
|---|
| 983 | xb = x2*cosa - y2*sina; |
|---|
| 984 | yb = x2*sina + y2*cosa; |
|---|
| 985 | x = xb - arrowht; |
|---|
| 986 | y = yb - arrowwid / 2; |
|---|
| 987 | xc = x*cosa + y*sina; |
|---|
| 988 | yc = -x*sina + y*cosa; |
|---|
| 989 | y = yb + arrowwid / 2; |
|---|
| 990 | xd = x*cosa + y*sina; |
|---|
| 991 | yd = -x*sina + y*cosa; |
|---|
| 992 | fprintf(tfp, "n %.3f %.3f m %.3f %.3f l %.3f %.3f l gs 2 setlinejoin col%d s gr\n", xc, yc, x2, y2, xd, yd, col > MAXCOLORS ? -1 : col); |
|---|
| 993 | } |
|---|
| 994 | |
|---|
| 995 | static fill_area(fill, color) |
|---|
| 996 | int fill, color; |
|---|
| 997 | { |
|---|
| 998 | if (color < 1) /* use gray levels for default and black */ |
|---|
| 999 | fprintf(tfp, "gs %.2f setgray fill gr\n", 1.0 - GRAYVAL(fill)); |
|---|
| 1000 | else |
|---|
| 1001 | fprintf(tfp, "gs col%d %.2f graycol fill gr ", |
|---|
| 1002 | color > MAXCOLORS ? -1 : color, GRAYVAL(fill)); |
|---|
| 1003 | } |
|---|
| 1004 | |
|---|
| 1005 | static iso_text_exist(ob) |
|---|
| 1006 | F_compound *ob; |
|---|
| 1007 | { |
|---|
| 1008 | F_compound *c; |
|---|
| 1009 | F_text *t; |
|---|
| 1010 | unsigned char *s; |
|---|
| 1011 | |
|---|
| 1012 | if (ob->texts != NULL) |
|---|
| 1013 | { |
|---|
| 1014 | for (t = ob->texts; t != NULL; t = t->next) |
|---|
| 1015 | { |
|---|
| 1016 | for (s = (unsigned char*)t->cstring; *s != '\0'; s++) |
|---|
| 1017 | { |
|---|
| 1018 | /* look for characters >= 128 */ |
|---|
| 1019 | if (*s>127) return(1); |
|---|
| 1020 | } |
|---|
| 1021 | } |
|---|
| 1022 | } |
|---|
| 1023 | |
|---|
| 1024 | for (c = ob->compounds; c != NULL; c = c->next) { |
|---|
| 1025 | if (iso_text_exist(c)) return(1); |
|---|
| 1026 | } |
|---|
| 1027 | return(0); |
|---|
| 1028 | } |
|---|
| 1029 | |
|---|
| 1030 | static encode_all_fonts(ob) |
|---|
| 1031 | F_compound *ob; |
|---|
| 1032 | { |
|---|
| 1033 | F_compound *c; |
|---|
| 1034 | F_text *t; |
|---|
| 1035 | |
|---|
| 1036 | if (ob->texts != NULL) |
|---|
| 1037 | { |
|---|
| 1038 | for (t = ob->texts; t != NULL; t = t->next) |
|---|
| 1039 | if (PSisomap[t->font+1] == FALSE) |
|---|
| 1040 | { |
|---|
| 1041 | fprintf(tfp, "/%s /%s-iso isovec ReEncode\n", PSFONT(t), PSFONT(t)); |
|---|
| 1042 | PSisomap[t->font+1] = TRUE; |
|---|
| 1043 | } |
|---|
| 1044 | } |
|---|
| 1045 | |
|---|
| 1046 | for (c = ob->compounds; c != NULL; c = c->next) |
|---|
| 1047 | { |
|---|
| 1048 | encode_all_fonts(c); |
|---|
| 1049 | } |
|---|
| 1050 | } |
|---|
| 1051 | |
|---|
| 1052 | static ellipse_exist(ob) |
|---|
| 1053 | F_compound *ob; |
|---|
| 1054 | { |
|---|
| 1055 | F_compound *c; |
|---|
| 1056 | |
|---|
| 1057 | if (NULL != ob->ellipses) return(1); |
|---|
| 1058 | |
|---|
| 1059 | for (c = ob->compounds; c != NULL; c = c->next) { |
|---|
| 1060 | if (ellipse_exist(c)) return(1); |
|---|
| 1061 | } |
|---|
| 1062 | |
|---|
| 1063 | return(0); |
|---|
| 1064 | } |
|---|
| 1065 | |
|---|
| 1066 | static normal_spline_exist(ob) |
|---|
| 1067 | F_compound *ob; |
|---|
| 1068 | { |
|---|
| 1069 | F_spline *s; |
|---|
| 1070 | F_compound *c; |
|---|
| 1071 | |
|---|
| 1072 | for (s = ob->splines; s != NULL; s = s->next) { |
|---|
| 1073 | if (normal_spline(s)) return(1); |
|---|
| 1074 | } |
|---|
| 1075 | |
|---|
| 1076 | for (c = ob->compounds; c != NULL; c = c->next) { |
|---|
| 1077 | if (normal_spline_exist(c)) return(1); |
|---|
| 1078 | } |
|---|
| 1079 | |
|---|
| 1080 | return(0); |
|---|
| 1081 | } |
|---|
| 1082 | |
|---|
| 1083 | struct driver dev_ps = { |
|---|
| 1084 | genps_option, |
|---|
| 1085 | genps_start, |
|---|
| 1086 | genps_arc, |
|---|
| 1087 | genps_ellipse, |
|---|
| 1088 | genps_line, |
|---|
| 1089 | genps_spline, |
|---|
| 1090 | genps_text, |
|---|
| 1091 | genps_end, |
|---|
| 1092 | INCLUDE_TEXT |
|---|
| 1093 | }; |
|---|