00001
00002 #include "vul_psfile.h"
00003
00004
00005
00006 #include <vcl_cmath.h>
00007 #include <vcl_iostream.h>
00008 #include <vcl_iomanip.h>
00009 #include <vcl_algorithm.h>
00010 #include <vcl_cassert.h>
00011
00012 #define RANGE(a,b,c) { if (a < b) a = b; if (a > c) a = c; }
00013 #define in_range(a) (a < 0x100)
00014 #define Hex4bit(a) ((char)((a<=9) ? (a+'0') : (a - 10 + 'a')))
00015
00016 static const float PIX2INCH = 72.0f;
00017 static bool debug = true;
00018
00019
00020 static double paper_size[8][2] = {
00021 { 8.500, 11.000},
00022 { 8.268, 11.693},
00023 { 7.205, 10.118},
00024 {11.693, 16.535},
00025 { 8.500, 14.000},
00026 {11.000, 17.000},
00027 { 3.875, 4.875},
00028 { 0.945, 1.417}
00029 };
00030
00031
00032 static double margins[8 ][2] = {
00033 { 1.000, 1.000},
00034 { 1.000, 1.000},
00035 { 1.000, 1.000},
00036 { 1.000, 1.000},
00037 { 1.000, 1.000},
00038 { 1.000, 1.000},
00039 { 0.275, 0.275},
00040 { 0.078, 0.078}
00041 };
00042
00043
00044 static float ps_minimum = 0.1f;
00045 static float ps_maximum = 8.f;
00046
00047 static const vcl_streampos HEADER_START(-1);
00048
00049
00050
00051
00052 vul_psfile::vul_psfile(char const* f, bool dbg)
00053 : output_filestream(f),
00054 fg_r(0), fg_g(0), fg_b(0),
00055 bg_r(1), bg_g(1), bg_b(1),
00056 line_width_(1),
00057 scale_x(1.f), scale_y(1.f),
00058 ox(0), oy(0), iw(0), ih(0),
00059 iwf(1.0), ihf(1.0),
00060 psizex(8.5), psizey(11),
00061 pos_inx(4.25), pos_iny(5.5),
00062 width(0), height(0),
00063 filename(f),
00064 printer_paper_type(vul_psfile::US_NORMAL),
00065 printer_paper_orientation(vul_psfile::PORTRAIT),
00066 printer_paper_layout(vul_psfile::CENTER),
00067 reduction_factor(1),
00068 doneps(false),
00069 min_x(1000), min_y(1000),
00070 max_x(-1000), max_y(-1000),
00071 box_width(0), box_height(0),
00072 translate_pos(-1L),
00073 sobj_t_pos(-1L),
00074 header_pos(HEADER_START),
00075 graphics_prolog_exists(false),
00076 exist_image(false),
00077 exist_objs (false)
00078 {
00079 debug = dbg;
00080 if (debug) vcl_cout << "vul_psfile::vul_psfile\n";
00081 postscript_header();
00082 }
00083
00084
00085
00086
00087 vul_psfile::~vul_psfile()
00088 {
00089 if (debug) vcl_cout << "vul_psfile::~vul_psfile\n";
00090 reset_bounding_box();
00091 if (!doneps)
00092 done();
00093 }
00094
00095
00096
00097
00098
00099 void vul_psfile::reset_bounding_box()
00100 {
00101 vcl_streampos temp_pos;
00102 temp_pos = output_filestream.tellp();
00103
00104 if (exist_image)
00105 {
00106
00107 output_filestream.seekp(translate_pos);
00108 image_translate_and_scale();
00109 }
00110 if (exist_objs)
00111 {
00112
00113 output_filestream.seekp(sobj_t_pos);
00114 object_translate_and_scale();
00115 }
00116
00117
00118 output_filestream.seekp(header_pos);
00119 reset_postscript_header();
00120 output_filestream.seekp(temp_pos);
00121 }
00122
00123
00124
00125
00126 void vul_psfile::compute_bounding_box()
00127 {
00128 box_width = max_x - min_x;
00129 box_height = max_y - min_y;
00130
00131 if (printer_paper_orientation == vul_psfile::LANDSCAPE)
00132 {
00133 psizex = paper_size[printer_paper_type][1];
00134 psizey = paper_size[printer_paper_type][0];
00135 }
00136 else
00137 {
00138 psizex = paper_size[printer_paper_type][0];
00139 psizey = paper_size[printer_paper_type][1];
00140 }
00141
00142 if (printer_paper_layout == vul_psfile::CENTER)
00143 {
00144 double hsx = box_width / PIX2INCH * scale_x * .5;
00145 double hsy = box_height / PIX2INCH * scale_y * .5;
00146
00147
00148 pos_inx = psizex*.5 - hsx;
00149 pos_iny = psizey*.5 - hsy;
00150
00151
00152 RANGE(pos_inx, -hsx, psizex-hsx);
00153 RANGE(pos_iny, -hsy, psizey-hsy);
00154
00155
00156 pos_inx = vcl_floor(pos_inx * 1000.0 + 0.5) * .001;
00157 pos_iny = vcl_floor(pos_iny * 1000.0 + 0.5) * .001;
00158 }
00159 else if (printer_paper_layout == vul_psfile::MAX)
00160 {
00161 double hsx = psizex - margins[printer_paper_type][0];
00162 double hsy = psizey - margins[printer_paper_type][1];
00163
00164
00165 if (box_width == 0) box_width = 1;
00166 if (box_height == 0) box_height = 1;
00167
00168
00169 scale_x = scale_y = (float)vcl_min(hsx/box_width, hsy/box_height) * PIX2INCH;
00170
00171 RANGE(scale_x,ps_minimum,ps_maximum);
00172 RANGE(scale_y,ps_minimum,ps_maximum);
00173
00174 pos_inx = psizex*.5 - box_width / PIX2INCH * scale_x *.5;
00175 pos_iny = psizey*.5 - box_height/ PIX2INCH * scale_y *.5;
00176
00177
00178 pos_inx = vcl_floor(pos_inx * 1000.0 + 0.5) * .001;
00179 pos_iny = vcl_floor(pos_iny * 1000.0 + 0.5) * .001;
00180 }
00181
00182
00183 if (exist_image)
00184 {
00185 iwf = width * scale_x; iw = int(iwf + 0.5);
00186 ihf = height * scale_y; ih = int(ihf + 0.5);
00187 }
00188 if (exist_objs)
00189 {
00190 iw = int(box_width * scale_x + 0.5);
00191 ih = int(box_height * scale_y + 0.5);
00192 }
00193
00194
00195 ox = int(pos_inx*PIX2INCH+0.5);
00196 oy = int(pos_iny*PIX2INCH+0.5);
00197
00198 if (debug) vcl_cout << "vul_psfile::compute_bounding_box, box_width = "
00199 << box_width << ", box_height = " << box_height << '\n';
00200 }
00201
00202
00203
00204
00205 void vul_psfile::set_min_max_xy(float xx, float yy)
00206 {
00207 int x = int(xx + 0.5);
00208 int y = int(yy + 0.5);
00209 if (x < min_x) min_x = x;
00210 if (y < min_y) min_y = y;
00211 if (x > max_x) max_x = x;
00212 if (y > max_y) max_y = y;
00213 }
00214
00215
00216
00217
00218 void vul_psfile::set_min_max_xy(int x, int y)
00219 {
00220 if (x < min_x) min_x = x;
00221 if (y < min_y) min_y = y;
00222 if (x > max_x) max_x = x;
00223 if (y > max_y) max_y = y;
00224 }
00225
00226
00227
00228
00229 void vul_psfile::print_greyscale_image(unsigned char* buffer, int sizex, int sizey)
00230 {
00231 if (debug)
00232 vcl_cout << "vul_psfile::print_greyscale_image, width = " << sizex
00233 << ", height = " << sizey << ", reduction_factor = "
00234 << reduction_factor << '\n';
00235
00236 exist_image = true;
00237 width = sizex;
00238 height = sizey;
00239 set_parameters(sizex,sizey);
00240 compute_bounding_box();
00241
00242 int new_width = (int)vcl_ceil(sizex/(double)reduction_factor);
00243 int new_height= (int)vcl_ceil(sizey/(double)reduction_factor);
00244
00245 output_filestream
00246 << "\n%%Page: 1 1\n\n% remember original state\n/origstate save def\n"
00247 << "\n% build a temporary dictionary\n20 dict begin\n\n"
00248 << "% define string to hold a scanline's worth of data\n"
00249 << "/pix " << new_width << " string def\n";
00250
00251 if (printer_paper_orientation == vul_psfile::LANDSCAPE)
00252 output_filestream
00253 << "% print in landscape mode\n90 rotate 0 " << int(-psizey*PIX2INCH) << " translate\n\n";
00254 output_filestream << "% lower left corner\n";
00255 translate_pos = output_filestream.tellp();
00256 image_translate_and_scale();
00257
00258 output_filestream
00259 << new_width << ' ' << new_height << " 8 % dimensions of data\n"
00260 << '[' << new_width << " 0 0 -" << new_height << " 0 " << new_height
00261 << "] % mapping matrix\n{currentfile pix readhexstring pop}\nimage\n\n";
00262 const int linesize = 72;
00263
00264
00265 for (int j=0; j<new_height; j++)
00266 {
00267 int countrow = 0;
00268 for (int i = 0; i < new_width; i++)
00269 {
00270 int index;
00271
00272 if (reduction_factor == 1)
00273 index = int(*(buffer + width * j + i));
00274 else
00275 {
00276 int pixel_number= (width * j + i) * reduction_factor;
00277 index=0;
00278 int number_of_pixels_sampled=0;
00279 for (int m=0; m < reduction_factor;m++)
00280 for (int n=0; n < reduction_factor;n++)
00281 if (i*reduction_factor+m < width && j*reduction_factor+n < height)
00282 {
00283 index += int(*(buffer + (pixel_number+m+n*width)));
00284 ++number_of_pixels_sampled;
00285 }
00286 index/=number_of_pixels_sampled;
00287 }
00288
00289
00290 if (in_range(index))
00291 {
00292 char pixel[3];
00293 unsigned char low4 = (unsigned char) (index & 0x000f);
00294 unsigned char high4 = (unsigned char) ((index & 0x00f0) >> 4);
00295 pixel[0] = Hex4bit(high4);
00296 pixel[1] = Hex4bit(low4);
00297 pixel[2] = '\0';
00298 output_filestream << pixel;
00299 }
00300 else
00301 vcl_cout << " index out of range: " << index << '\n';
00302
00303 countrow+=2;
00304 if (countrow >= linesize)
00305 {
00306 countrow = 0;
00307 output_filestream << '\n';
00308 }
00309 }
00310 output_filestream << '\n';
00311 }
00312 output_filestream << "% stop using temporary dictionary\nend\n\n"
00313 << "% restore original state\norigstate restore\n\n";
00314 }
00315
00316
00317
00318
00319 void vul_psfile::print_color_image(unsigned char* data, int sizex, int sizey)
00320 {
00321 if (debug)
00322 vcl_cout << "vul_psfile::print_color_image, width = " << sizex
00323 << ", height = " << sizey << ", reduction_factor = "
00324 << reduction_factor << '\n';
00325
00326 const int bytes_per_pixel = 3;
00327 exist_image = true;
00328 width = sizex;
00329 height = sizey;
00330 set_parameters(sizex,sizey);
00331 compute_bounding_box();
00332
00333 int new_width = (int)vcl_ceil(sizex/(double)reduction_factor);
00334 int new_height= (int)vcl_ceil(sizey/(double)reduction_factor);
00335
00336
00337 output_filestream
00338 << "\n%%Page: 1 1\n\n"
00339 << "% remember original state\n"
00340 << "/origstate save def\n\n"
00341 << "% build a temporary dictionary\n"
00342 << "20 dict begin\n\n"
00343 << "% define string to hold a scanline's worth of data\n"
00344 << "/pix " << 3 * new_width << " string def\n\n"
00345 << "% define space for color conversions\n"
00346 << "/grays " << new_width << " string def % space for gray scale line\n"
00347 << "/npixls 0 def\n"
00348 << "/rgbindx 0 def\n\n";
00349
00350 if (printer_paper_orientation == vul_psfile::LANDSCAPE)
00351 output_filestream
00352 << "% print in landscape mode\n90 rotate 0 " << int(-psizey*PIX2INCH) << " translate\n\n";
00353 output_filestream << "% lower left corner\n";
00354 translate_pos = output_filestream.tellp();
00355 image_translate_and_scale();
00356
00357 output_filestream
00358 << "\n% define 'colorimage' if it isn't defined\n"
00359 << "% ('colortogray' and 'mergeprocs' come from xwd2ps via xgrab)\n"
00360 << "/colorimage where % do we know about 'colorimage'?\n"
00361 << " { pop } % yes: pop off the 'dict' returned\n"
00362 << " { % no: define one\n"
00363 << " /colortogray { % define an RGB->I function\n"
00364 << " /rgbdata exch store % call input 'rgbdata'\n"
00365 << " rgbdata length 3 idiv\n"
00366 << " /npixls exch store\n"
00367 << " /rgbindx 0 store\n"
00368 << " 0 1 npixls 1 sub {\n"
00369 << " grays exch\n"
00370 << " rgbdata rgbindx get 20 mul % Red\n"
00371 << " rgbdata rgbindx 1 add get 32 mul % Green\n"
00372 << " rgbdata rgbindx 2 add get 12 mul % Blue\n"
00373 << " add add 64 idiv % I = .3125 R + .5 G + .1875 B\n"
00374 << " put\n"
00375 << " /rgbindx rgbindx 3 add store\n"
00376 << " } for\n"
00377 << " grays 0 npixls getinterval\n"
00378 << " } bind def\n\n"
00379 << " % Utility procedure for colorimage operator.\n"
00380 << " % This procedure takes two procedures off the stack and merges them into a single procedure.\n\n"
00381 << " /mergeprocs {\n"
00382 << " dup length\n"
00383 << " 3 -1 roll\n"
00384 << " dup\n"
00385 << " length\n"
00386 << " dup\n"
00387 << " 5 1 roll\n"
00388 << " 3 -1 roll\n"
00389 << " add\n"
00390 << " array cvx\n"
00391 << " dup\n"
00392 << " 3 -1 roll\n"
00393 << " 0 exch\n"
00394 << " putinterval\n"
00395 << " dup\n"
00396 << " 4 2 roll\n"
00397 << " putinterval\n"
00398 << " } bind def\n\n"
00399 << " /colorimage {\n"
00400 << " pop pop % remove 'false 3' operands\n"
00401 << " {colortogray} mergeprocs\n"
00402 << " image\n"
00403 << " } bind def\n"
00404 << " } ifelse % end of 'false' case\n\n"
00405 << new_width << ' ' << new_height << " 8 % dimensions of data\n"
00406 << '[' << new_width << " 0 0 -" << new_height << " 0 " << new_height << "] % mapping matrix\n"
00407 << "{currentfile pix readhexstring pop}\n"
00408 << "false 3 colorimage\n\n";
00409
00410
00411 const int linesize = 72;
00412
00413
00414 for (int j = 0; j < new_height;j++)
00415 {
00416 int countrow = 0;
00417 for (int i = 0; i < new_width; i++)
00418 {
00419 for (int c = 0; c < bytes_per_pixel; ++c)
00420 {
00421
00422 int index;
00423
00424 if (reduction_factor == 1)
00425 index = int(*(data + (sizex*j+i) * bytes_per_pixel + c));
00426 else
00427 {
00428 int pixel_number= (sizex*j+i) * bytes_per_pixel * reduction_factor + c;
00429 index=0;
00430 int number_of_pixels_sampled=0;
00431 for (int m=0; m < reduction_factor;m++)
00432 for (int n=0; n < reduction_factor;n++)
00433 if (i*reduction_factor+m < sizex && j*reduction_factor+n < sizey)
00434 {
00435 index += int(*(data+(pixel_number+(m+n*sizex)*bytes_per_pixel)));
00436 ++number_of_pixels_sampled;
00437 }
00438 index/=number_of_pixels_sampled;
00439 }
00440
00441
00442 if (in_range(index))
00443 {
00444 char pixel[3];
00445 unsigned char low4 = (unsigned char) (index & 0x000f);
00446 unsigned char high4 = (unsigned char) ((index & 0x00f0) >> 4);
00447 pixel[0] = Hex4bit(high4);
00448 pixel[1] = Hex4bit(low4);
00449 pixel[2] = '\0';
00450 output_filestream << pixel;
00451 }
00452 else
00453 vcl_cout << " index out of range: " << index << '\n';
00454
00455 countrow+=2;
00456 if (countrow >= linesize)
00457 {
00458 countrow = 0;
00459 output_filestream << '\n';
00460 }
00461 }
00462 }
00463 output_filestream << '\n';
00464 }
00465
00466 output_filestream << "% stop using temporary dictionary\nend\n\n"
00467 << "% restore original state\norigstate restore\n\n";
00468 }
00469
00470
00471
00472
00473 void vul_psfile::graphic_header()
00474 {
00475 if (printer_paper_orientation == vul_psfile::LANDSCAPE)
00476 output_filestream << "% print in landscape mode\n90 rotate 0 "
00477 << int(-psizey*PIX2INCH) << " translate\n\n";
00478
00479 output_filestream.flush();
00480
00481 sobj_t_pos = output_filestream.tellp();
00482
00483 object_translate_and_scale();
00484 }
00485
00486
00487
00488
00489 void vul_psfile::image_translate_and_scale()
00490 {
00491 int scale_height = int(height* scale_y);
00492 int scale_min_x = int(min_x * scale_x);
00493 int scale_max_y = int(max_y * scale_y);
00494
00495 if (debug)
00496 vcl_cout << "vul_psfile::image_translate_and_scale, scale_height= "
00497 << scale_height << ", scale_min_x = " << scale_min_x
00498 << ", scale_max_y = " << scale_max_y << '\n';
00499
00500 output_filestream << vcl_setw(6) << ox - scale_min_x << ' '
00501 << vcl_setw(6) << oy + scale_max_y - scale_height << " translate\n"
00502 << "\n% size of image (on paper, in 1/72inch coordinates)\n"
00503 << vcl_setw(9) << iwf << ' '
00504 << vcl_setw(9) << ihf << " scale\n\n";
00505 }
00506
00507
00508
00509
00510 void vul_psfile::object_translate_and_scale()
00511 {
00512 int scale_height = int(box_height * scale_y);
00513 int scale_min_x = int(min_x * scale_x);
00514 int scale_min_y = int(min_y * scale_y);
00515
00516 scale_x = vcl_floor(scale_x * 100.0f + 0.5f) * .01f;
00517 scale_y = vcl_floor(scale_y * 100.0f + 0.5f) * .01f;
00518
00519
00520 output_filestream << vcl_setw(6) << ox - scale_min_x << ' '
00521 << vcl_setw(6) << oy + scale_height + scale_min_y << " translate\n"
00522 << vcl_setw(9) << scale_x << ' ' << vcl_setw(9) << -scale_y << " scale\n\n"
00523 << "/originalCTM matrix currentmatrix def\n";
00524 }
00525
00526
00527
00528
00529 bool vul_psfile::set_parameters(int sizex,int sizey)
00530 {
00531 width = sizex;
00532 height = sizey;
00533
00534 assert (width > 0 && height > 0);
00535
00536 set_min_max_xy(0,0);
00537 set_min_max_xy(width,height);
00538 compute_bounding_box();
00539
00540 return true;
00541 }
00542
00543
00544
00545
00546 void vul_psfile::postscript_header()
00547 {
00548 if (header_pos != HEADER_START)
00549 {
00550 vcl_cerr << "vul_psfile: Header already set to " << long(header_pos) << '\n';
00551 return;
00552 }
00553
00554 output_filestream
00555 << "%!PS-Adobe-2.0 EPSF-2.0\n%%Title: " << filename.c_str()
00556 << "\n%%Creator: vul_psfile\n%%BoundingBox: ";
00557
00558 header_pos = output_filestream.tellp();
00559 reset_postscript_header();
00560 }
00561
00562
00563
00564
00565
00566 void vul_psfile::reset_postscript_header()
00567 {
00568 if (printer_paper_orientation == vul_psfile::LANDSCAPE)
00569 output_filestream
00570 << vcl_setw(6) << int(pos_iny*PIX2INCH+0.5) << ' '
00571 << vcl_setw(6) << int(pos_inx*PIX2INCH+0.5) << ' '
00572 << vcl_setw(6) << int(pos_iny*PIX2INCH+0.5)+ih << ' '
00573 << vcl_setw(6) << int(pos_inx*PIX2INCH+0.5)+iw << '\n';
00574 else
00575 output_filestream
00576 << vcl_setw(6) << ox << ' '
00577 << vcl_setw(6) << oy << ' '
00578 << vcl_setw(6) << ox+iw << ' '
00579 << vcl_setw(6) << oy+ih << '\n';
00580 output_filestream << "%%Pages: 1\n%%DocumentFonts:\n%%EndComments\n";
00581 }
00582
00583
00584
00585
00586 void vul_psfile::sobj_rgb_params(char const* obj_str, bool filled)
00587 {
00588 print_graphics_prolog();
00589 output_filestream
00590 << "\nBegin %I " << obj_str << "\n2 0 0 [] 0 SetB\n"
00591 << fg_r << ' ' << fg_g << ' ' << fg_b << " SetCFg\n"
00592 << bg_r << ' ' << bg_g << ' ' << bg_b << " SetCBg\n"
00593 << line_width_ << " setlinewidth\n"
00594 << (filled ? "0": "none") << " SetP %I p n\n";
00595 }
00596
00597
00598
00599
00600 void vul_psfile::line(float x1, float y1, float x2, float y2)
00601 {
00602
00603 set_min_max_xy(x1,y1);
00604 set_min_max_xy(x2,y2);
00605 compute_bounding_box();
00606
00607 print_graphics_prolog();
00608 sobj_rgb_params("Line", false);
00609
00610 output_filestream << int(x1) << ' ' << int(y1) << ' '
00611 << int(x2) << ' ' << int(y2) << " Line\nEnd\n";
00612 }
00613
00614
00615
00616
00617 void vul_psfile::point(float x, float y, float point_size)
00618 {
00619 print_graphics_prolog();
00620 set_min_max_xy(x,y);
00621 compute_bounding_box();
00622
00623 this->sobj_rgb_params("Point", true);
00624
00625 point_size /= 2;
00626 output_filestream << x << ' ' << y << ' ' << point_size << ' ' << point_size << " Elli\nEnd\n";
00627 }
00628
00629
00630
00631
00632 void vul_psfile::ellipse(float x, float y, float a_axis, float b_axis, int angle)
00633 {
00634 #ifndef PI // should already be defined in math.h - PVR
00635 #define PI 3.14159265358979323846
00636 #endif
00637 const double radsperdeg = PI/180.0;
00638
00639 set_min_max_xy(int(x+a_axis*vcl_cos(angle*radsperdeg) + 0.5),
00640 int(y+a_axis*vcl_sin(angle*radsperdeg) + 0.5) );
00641 set_min_max_xy(int(x-a_axis*vcl_cos(angle*radsperdeg) + 0.5),
00642 int(y-a_axis*vcl_sin(angle*radsperdeg) + 0.5) );
00643 compute_bounding_box();
00644
00645 print_graphics_prolog();
00646 sobj_rgb_params("Ellipse", false);
00647 if (angle)
00648 output_filestream << (int)x << ' ' << (int)y << " translate\n"
00649 << -angle << " rotate\n0 0 " << (int)a_axis << ' '
00650 << (int)b_axis << " Elli\nEnd\n";
00651 else
00652 output_filestream << (int)x << ' ' << (int)y << ' '
00653 << (int)a_axis << ' ' << (int)b_axis << " Elli\nEnd\n";
00654 }
00655
00656
00657
00658
00659 void vul_psfile::circle(float x, float y, float radius)
00660 {
00661
00662 set_min_max_xy(x+radius,y);
00663 set_min_max_xy(x-radius,y);
00664 set_min_max_xy(x,y+radius);
00665 set_min_max_xy(x,y-radius);
00666 compute_bounding_box();
00667
00668 print_graphics_prolog();
00669 sobj_rgb_params("Circle", false);
00670 ellipse(x,y,radius,radius);
00671 output_filestream << "End\n";
00672 }
00673
00674
00675
00676
00677 void vul_psfile::print_graphics_prolog()
00678 {
00679 if (graphics_prolog_exists)
00680 return;
00681 exist_objs = true;
00682 output_filestream
00683 << "\n\n%%BeginTargetjrPrologue\n"
00684 << "/arrowhead {\n"
00685 << " 0 begin\n"
00686 << " transform originalCTM itransform\n"
00687 << " /taily exch def\n"
00688 << " /tailx exch def\n"
00689 << " transform originalCTM itransform\n"
00690 << " /tipy exch def\n"
00691 << " /tipx exch def\n"
00692 << " /dy tipy taily sub def\n"
00693 << " /dx tipx tailx sub def\n"
00694 << " /angle dx 0 ne dy 0 ne or { dy dx atan } { 90 } ifelse def\n"
00695 << " gsave\n"
00696 << " originalCTM setmatrix\n"
00697 << " tipx tipy translate\n"
00698 << " angle rotate\n"
00699 << " newpath\n"
00700 << " arrowHeight neg arrowWidth 2 div moveto\n"
00701 << " 0 0 lineto\n"
00702 << " arrowHeight neg arrowWidth 2 div neg lineto\n"
00703 << " patternNone not {\n"
00704 << " originalCTM setmatrix\n"
00705 << " /padtip arrowHeight 2 exp 0.25 arrowWidth 2 exp mul add sqrt brushWidth mul\n"
00706 << " arrowWidth div def\n"
00707 << " /padtail brushWidth 2 div def\n"
00708 << " tipx tipy translate\n"
00709 << " angle rotate\n"
00710 << " padtip 0 translate\n"
00711 << " arrowHeight padtip add padtail add arrowHeight div dup scale\n"
00712 << " arrowheadpath\n"
00713 << " ifill\n"
00714 << " } if\n"
00715 << " brushNone not {\n"
00716 << " originalCTM setmatrix\n"
00717 << " tipx tipy translate\n"
00718 << " angle rotate\n"
00719 << " arrowheadpath\n"
00720 << " istroke\n"
00721 << " } if\n"
00722 << " grestore\n"
00723 << " end\n"
00724 << "} dup 0 9 dict put def\n\n"
00725 << "/arrowheadpath {\n"
00726 << " newpath\n"
00727 << " arrowHeight neg arrowWidth 2 div moveto\n"
00728 << " 0 0 lineto\n"
00729 << " arrowHeight neg arrowWidth 2 div neg lineto\n"
00730 << "} def\n\n"
00731 << "/leftarrow {\n"
00732 << " 0 begin\n"
00733 << " y exch get /taily exch def\n"
00734 << " x exch get /tailx exch def\n"
00735 << " y exch get /tipy exch def\n"
00736 << " x exch get /tipx exch def\n"
00737 << " brushLeftArrow { tipx tipy tailx taily arrowhead } if\n"
00738 << " end\n"
00739 << "} dup 0 4 dict put def\n\n"
00740 << "/rightarrow {\n"
00741 << " 0 begin\n"
00742 << " y exch get /tipy exch def\n"
00743 << " x exch get /tipx exch def\n"
00744 << " y exch get /taily exch def\n"
00745 << " x exch get /tailx exch def\n"
00746 << " brushRightArrow { tipx tipy tailx taily arrowhead } if\n"
00747 << " end\n"
00748 << "} dup 0 4 dict put def\n\n"
00749 << "%%EndTargetjrPrologue\n\n"
00750 << "/arrowHeight 10 def\n"
00751 << "/arrowWidth 5 def\n\n"
00752 << "/TargetjrDict 50 dict def\n"
00753 << "TargetjrDict begin\n\n"
00754 << "/none null def\n"
00755 << "/numGraphicParameters 17 def\n"
00756 << "/stringLimit 65535 def\n\n"
00757 << "/Begin { save numGraphicParameters dict begin } def\n\n"
00758 << "/End { end restore } def\n\n"
00759 << "/SetB { % width leftarrow rightarrow DashArray DashOffset SetB\n"
00760 << " dup type /nulltype eq {\n"
00761 << " pop\n"
00762 << " false /brushRightArrow idef\n"
00763 << " false /brushLeftArrow idef\n"
00764 << " true /brushNone idef\n"
00765 << " } {\n"
00766 << " /brushDashOffset idef\n"
00767 << " /brushDashArray idef\n"
00768 << " 0 ne /brushRightArrow idef\n"
00769 << " 0 ne /brushLeftArrow idef\n"
00770 << " /brushWidth idef\n"
00771 << " false /brushNone idef\n"
00772 << " } ifelse\n"
00773 << "} def\n\n"
00774 << "/SetCFg { /fgblue idef /fggreen idef /fgred idef } def\n\n"
00775 << "/SetCBg { /bgblue idef /bggreen idef /bgred idef } def\n\n"
00776 << "/SetF { /printSize idef /printFont idef } def\n\n"
00777 << "/SetP { % string -1 SetP OR gray SetP\n"
00778 << " dup type /nulltype eq { pop true /patternNone idef }\n"
00779 << " {\n"
00780 << " dup -1 eq { /patternGrayLevel idef /patternString idef }\n"
00781 << " { /patternGrayLevel idef } ifelse\n"
00782 << " false /patternNone idef\n"
00783 << " } ifelse\n"
00784 << "} def\n\n"
00785 << "/BSpl {\n"
00786 << " 0 begin\n"
00787 << " storexyn\n"
00788 << " newpath\n"
00789 << " n 1 gt {\n"
00790 << " 0 0 0 0 0 0 1 1 true subspline\n"
00791 << " n 2 gt {\n"
00792 << " 0 0 0 0 1 1 2 2 false subspline\n"
00793 << " 1 1 n 3 sub { /i exch def i 1 sub dup i dup i 1 add dup i 2 add dup false subspline } for\n"
00794 << " n 3 sub dup n 2 sub dup n 1 sub dup 2 copy false subspline\n"
00795 << " } if\n"
00796 << " n 2 sub dup n 1 sub dup 2 copy 2 copy false subspline\n"
00797 << " patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if\n"
00798 << " brushNone not { istroke } if\n"
00799 << " 0 0 1 1 leftarrow\n"
00800 << " n 2 sub dup n 1 sub dup rightarrow\n"
00801 << " } if\n"
00802 << " end\n"
00803 << "} dup 0 4 dict put def\n\n"
00804 << "/Circ { newpath 0 360 arc patternNone not { ifill } if brushNone not { istroke } if } def\n\n"
00805 << "/CBSpl {\n"
00806 << " 0 begin\n"
00807 << " dup 2 gt {\n"
00808 << " storexyn\n"
00809 << " newpath\n"
00810 << " n 1 sub dup 0 0 1 1 2 2 true subspline\n"
00811 << " 1 1 n 3 sub { /i exch def i 1 sub dup i dup i 1 add dup i 2 add dup false subspline } for\n"
00812 << " n 3 sub dup n 2 sub dup n 1 sub dup 0 0 false subspline\n"
00813 << " n 2 sub dup n 1 sub dup 0 0 1 1 false subspline\n"
00814 << " patternNone not { ifill } if\n"
00815 << " brushNone not { istroke } if\n"
00816 << " } { Poly } ifelse\n"
00817 << " end\n"
00818 << "} dup 0 4 dict put def\n"
00819 << "/Elli {\n"
00820 << " 0 begin\n"
00821 << " newpath 4 2 roll translate scale\n"
00822 << " 0 0 1 0 360 arc\n"
00823 << " patternNone not { ifill } if\n"
00824 << " brushNone not { istroke } if\n"
00825 << " end\n"
00826 << "} dup 0 1 dict put def\n\n"
00827 << "/Line {\n"
00828 << " 0 begin\n"
00829 << " 2 storexyn\n"
00830 << " newpath\n"
00831 << " x 0 get y 0 get moveto\n"
00832 << " x 1 get y 1 get lineto\n"
00833 << " brushNone not { istroke } if\n"
00834 << " 0 0 1 1 leftarrow\n"
00835 << " 0 0 1 1 rightarrow\n"
00836 << " end\n"
00837 << "} dup 0 4 dict put def\n\n"
00838 << "/MLine {\n"
00839 << " 0 begin\n"
00840 << " storexyn\n"
00841 << " newpath\n"
00842 << " n 1 gt {\n"
00843 << " x 0 get y 0 get moveto\n"
00844 << " 1 1 n 1 sub { /i exch def x i get y i get lineto } for\n"
00845 << " patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if\n"
00846 << " brushNone not { istroke } if\n"
00847 << " 0 0 1 1 leftarrow\n"
00848 << " n 2 sub dup n 1 sub dup rightarrow\n"
00849 << " } if\n"
00850 << " end\n"
00851 << "} dup 0 4 dict put def\n\n"
00852 << "/Poly {\n"
00853 << " 3 1 roll\n"
00854 << " newpath moveto -1 add { lineto } repeat closepath\n"
00855 << " patternNone not { ifill } if\n"
00856 << " brushNone not { istroke } if\n"
00857 << "} def\n\n"
00858 << "/Rect {\n"
00859 << " 0 begin\n"
00860 << " /t exch def\n"
00861 << " /r exch def\n"
00862 << " /b exch def\n"
00863 << " /l exch def\n"
00864 << " newpath\n"
00865 << " l b moveto\n"
00866 << " l t lineto\n"
00867 << " r t lineto\n"
00868 << " r b lineto\n"
00869 << " closepath\n"
00870 << " patternNone not { ifill } if\n"
00871 << " brushNone not { istroke } if\n"
00872 << " end\n"
00873 << "} dup 0 4 dict put def\n\n"
00874 << "/Text { ishow } def\n\n"
00875 << "/idef { dup where { pop pop pop } { exch def } ifelse } def\n\n"
00876 << "/ifill {\n"
00877 << " 0 begin\n"
00878 << " gsave\n"
00879 << " patternGrayLevel -1 ne {\n"
00880 << " fgred bgred fgred sub patternGrayLevel mul add\n"
00881 << " fggreen bggreen fggreen sub patternGrayLevel mul add\n"
00882 << " fgblue bgblue fgblue sub patternGrayLevel mul add setrgbcolor\n"
00883 << " eofill\n"
00884 << " } {\n"
00885 << " eoclip\n"
00886 << " originalCTM setmatrix\n"
00887 << " pathbbox /t exch def /r exch def /b exch def /l exch def\n"
00888 << " /w r l sub ceiling cvi def\n"
00889 << " /h t b sub ceiling cvi def\n"
00890 << " /imageByteWidth w 8 div ceiling cvi def\n"
00891 << " /imageHeight h def\n"
00892 << " bgred bggreen bgblue setrgbcolor\n"
00893 << " eofill\n"
00894 << " fgred fggreen fgblue setrgbcolor\n"
00895 << " w 0 gt h 0 gt and { l w add b translate w neg h scale w h true [w 0 0 h neg 0 h] { patternproc } imagemask } if\n"
00896 << " } ifelse\n"
00897 << " grestore\n"
00898 << " end\n"
00899 << "} dup 0 8 dict put def\n\n"
00900 << "/istroke {\n"
00901 << " gsave\n"
00902 << " brushDashOffset -1 eq { [] 0 setdash 1 setgray }\n"
00903 << " { brushDashArray brushDashOffset setdash fgred fggreen fgblue setrgbcolor } ifelse\n"
00904 << " originalCTM setmatrix\n"
00905 << " stroke\n"
00906 << " grestore\n"
00907 << "} def\n\n"
00908 << "/ishow {\n"
00909 << " 0 begin\n"
00910 << " gsave\n"
00911 << " fgred fggreen fgblue setrgbcolor\n"
00912 << " /fontDict printFont printSize scalefont dup setfont def\n"
00913 << " /descender fontDict begin 0 [FontBBox] 1 get FontMatrix end\n"
00914 << " transform exch pop def\n"
00915 << " /vertoffset 1 printSize sub descender sub def\n"
00916 << " { 0 vertoffset moveto show /vertoffset vertoffset printSize sub def } forall\n"
00917 << " grestore\n"
00918 << " end\n"
00919 << "} dup 0 3 dict put def\n"
00920 << "/patternproc {\n"
00921 << " 0 begin\n"
00922 << " /patternByteLength patternString length def\n"
00923 << " /patternHeight patternByteLength 8 mul sqrt cvi def\n"
00924 << " /patternWidth patternHeight def\n"
00925 << " /patternByteWidth patternWidth 8 idiv def\n"
00926 << " /imageByteMaxLength imageByteWidth imageHeight mul\n"
00927 << " stringLimit patternByteWidth sub min def\n"
00928 << " /imageMaxHeight imageByteMaxLength imageByteWidth idiv patternHeight idiv\n"
00929 << " patternHeight mul patternHeight max def\n"
00930 << " /imageHeight imageHeight imageMaxHeight sub store\n"
00931 << " /imageString imageByteWidth imageMaxHeight mul patternByteWidth add string def\n"
00932 << " 0 1 imageMaxHeight 1 sub {\n"
00933 << " /y exch def\n"
00934 << " /patternRow y patternByteWidth mul patternByteLength mod def\n"
00935 << " /patternRowString patternString patternRow patternByteWidth getinterval def\n"
00936 << " /imageRow y imageByteWidth mul def\n"
00937 << " 0 patternByteWidth imageByteWidth 1 sub { /x exch def imageString imageRow x add patternRowString putinterval } for\n"
00938 << " } for\n"
00939 << " imageString\n"
00940 << " end\n"
00941 << "} dup 0 12 dict put def\n\n"
00942 << "/min { dup 3 2 roll dup 4 3 roll lt { exch } if pop } def\n\n"
00943 << "/max { dup 3 2 roll dup 4 3 roll gt { exch } if pop } def\n\n"
00944 << "/midpoint {\n"
00945 << " 0 begin\n"
00946 << " /y1 exch def\n"
00947 << " /x1 exch def\n"
00948 << " /y0 exch def\n"
00949 << " /x0 exch def\n"
00950 << " x0 x1 add 2 div\n"
00951 << " y0 y1 add 2 div\n"
00952 << " end\n"
00953 << "} dup 0 4 dict put def\n\n"
00954 << "/thirdpoint {\n"
00955 << " 0 begin\n"
00956 << " /y1 exch def\n"
00957 << " /x1 exch def\n"
00958 << " /y0 exch def\n"
00959 << " /x0 exch def\n"
00960 << " x0 2 mul x1 add 3 div\n"
00961 << " y0 2 mul y1 add 3 div\n"
00962 << " end\n"
00963 << "} dup 0 4 dict put def\n\n"
00964 << "/subspline {\n"
00965 << " 0 begin\n"
00966 << " /movetoNeeded exch def\n"
00967 << " y exch get /y3 exch def\n"
00968 << " x exch get /x3 exch def\n"
00969 << " y exch get /y2 exch def\n"
00970 << " x exch get /x2 exch def\n"
00971 << " y exch get /y1 exch def\n"
00972 << " x exch get /x1 exch def\n"
00973 << " y exch get /y0 exch def\n"
00974 << " x exch get /x0 exch def\n"
00975 << " x1 y1 x2 y2 thirdpoint\n"
00976 << " /p1y exch def\n"
00977 << " /p1x exch def\n"
00978 << " x2 y2 x1 y1 thirdpoint\n"
00979 << " /p2y exch def\n"
00980 << " /p2x exch def\n"
00981 << " x1 y1 x0 y0 thirdpoint\n"
00982 << " p1x p1y midpoint\n"
00983 << " /p0y exch def\n"
00984 << " /p0x exch def\n"
00985 << " x2 y2 x3 y3 thirdpoint\n"
00986 << " p2x p2y midpoint\n"
00987 << " /p3y exch def\n"
00988 << " /p3x exch def\n"
00989 << " movetoNeeded { p0x p0y moveto } if\n"
00990 << " p1x p1y p2x p2y p3x p3y curveto\n"
00991 << " end\n"
00992 << "} dup 0 17 dict put def\n\n"
00993 << "/storexyn {\n"
00994 << " /n exch def\n"
00995 << " /y n array def\n"
00996 << " /x n array def\n"
00997 << " n 1 sub -1 0 { /i exch def y i 3 2 roll put x i 3 2 roll put } for\n"
00998 << "} def\n\n"
00999 << "/SSten { fgred fggreen fgblue setrgbcolor dup true exch 1 0 0 -1 0 6 -1 roll matrix astore } def\n\n"
01000 << "/FSten {\n"
01001 << " dup 3 -1 roll dup 4 1 roll exch\n"
01002 << " newpath\n"
01003 << " 0 0 moveto\n"
01004 << " dup 0 exch lineto\n"
01005 << " exch dup 3 1 roll exch lineto\n"
01006 << " 0 lineto\n"
01007 << " closepath\n"
01008 << " bgred bggreen bgblue setrgbcolor\n"
01009 << " eofill\n"
01010 << " SSten\n"
01011 << "} def\n\n"
01012 << "/Rast { exch dup 3 1 roll 1 0 0 -1 0 6 -1 roll matrix astore } def\n\n";
01013
01014
01015 graphic_header();
01016
01017 graphics_prolog_exists = true;
01018 }
01019
01020 void vul_psfile::done()
01021 {
01022 if (debug) vcl_cout << "vul_psfile::done\n";
01023 doneps = true;
01024 if (graphics_prolog_exists)
01025 output_filestream << "end % TargetjrDict\n";
01026
01027 output_filestream << "showpage\n%%Trailer\n";
01028 }