Modelib: Fichier source de PsFile.cpp

Page principale | Liste des namespaces | Hiérarchie des classes | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de namespace | Membres de classe | Membres de fichier

# PsFile.cpp

Aller à la documentation de ce fichier.

    00001 /*
    00002     Copyright (c) 2005, Quentin Lequy and Romain Gaucher
    00003     All rights reserved.
    00004
    00005     Redistribution and use in source and binary forms, with or
    00006     without modification, are permitted provided that the following
    00007     conditions are met:
    00008
    00009         * Redistributions of source code must retain the above copyright
    00010           notice, this list of conditions and the following disclaimer.
    00011
    00012         * Redistributions in binary form must reproduce the above copyright
    00013           notice, this list of conditions and the following disclaimer in the
    00014           documentation and/or other materials provided with the distribution.
    00015
    00016         * Neither the name of Quentin Lequy or Romain Gaucher nor the names
    00017           of its contributors may be used to endorse or promote products
    00018           derived from this software without specific prior written permission.
    00019
    00020     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    00021     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    00022     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    00023     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    00024     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    00025     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    00026     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
    00027     AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00028     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    00029     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    00030 */
    00031
    00032 #include "PsFile.h"
    00033 #include <cmath>
    00034
    00035 namespace Modelib {
    00036
    00037
    00038 using namespace std;
    00039
    00040
    00041
    00042 void PSFile::begin_figure(
    00043     double _xmin, double _xmax,
    00044     double _ymin, double _ymax,
    00045
    00046     double _hmin, double _hmax,
    00047     double _vmin, double _vmax,
    00048
    00049     int xn, int yn
    00050   )
    00051   {
    00052
    00053     save_scales(
    00054       _xmin, _xmax, _ymin, _ymax,
    00055       _hmin, _hmax, _vmin, _vmax
    00056     );
    00057
    00058     char *date = asctime( localtime( NULL ) );
    00059
    00060     psfile <<  "%%!PS-Adobe-2.0 EPSF-2.0" << endl;
    00061     psfile <<  "%%%%CreationDate: "<< date << endl;
    00062     psfile <<  "%%%%BoundingBox: "<< hmin<<' '<<vmin<<' '<<hmax<<' '<<vmax<<endl;
    00063     psfile <<  "%%%%Pages: 1" << endl;
    00064     psfile <<  "%%%%EndComments" << endl;
    00065
    00066     psfile <<  "/$maindict 6400 dict def " << endl;
    00067     psfile <<  "$maindict begin" << endl;
    00068
    00069     define_procs();
    00070     define_caption_procs();
    00071
    00072     psfile <<  "end" << endl;
    00073     psfile <<  "%%%%EndProlog" << endl;
    00074
    00075     psfile <<  "%%%%Page: 1" << endl;
    00076     psfile <<  "$maindict begin" << endl;
    00077     psfile <<  "/savedstate save def" << endl;
    00078
    00079     setup_page_state(xn, yn);
    00080     setup_caption_data();
    00081
    00082     psfile.flush();
    00083   }
    00084
    00085 void PSFile::end_figure()
    00086   {
    00087     aux_end_page();
    00088     psfile <<  "%%%%Trailer" << endl;
    00089     psfile.flush();
    00090   }
    00091
    00092 void PSFile::begin_document()
    00093   {
    00094     psfile <<  "%%!PS-Adobe-2.0" << endl;
    00095     psfile <<  "%%%%Pages: (atend)" << endl;
    00096     psfile <<  "%%%%EndComments" << endl;
    00097
    00098     psfile <<  "/$maindict 6400 dict def " << endl;
    00099     psfile <<  "$maindict begin" << endl;
    00100
    00101     define_procs();
    00102     define_caption_procs();
    00103
    00104     psfile <<  "end" << endl;
    00105     psfile <<  "%%%%EndProlog" << endl;
    00106
    00107     psfile.flush();
    00108   }
    00109
    00110 void PSFile::end_document(int npages)
    00111   {
    00112     psfile <<  "%%%%Trailer" << endl;
    00113     psfile <<  "%%%%Pages: "<< npages << endl;
    00114     psfile.flush();
    00115   }
    00116
    00117 void PSFile::begin_page(
    00118     int page,
    00119     double _xmin, double _xmax,
    00120     double _ymin, double _ymax,
    00121
    00122     double _hmin, double _hmax,
    00123     double _vmin, double _vmax,
    00124
    00125     int xn, int yn
    00126   )
    00127   {
    00128     char *date = "";
    00129     save_scales(
    00130       _xmin, _xmax, _ymin, _ymax,
    00131       _hmin, _hmax, _vmin, _vmax
    00132     );
    00133
    00134     psfile <<  "%%%%Page: "<< page << ' ' << page << endl;
    00135     psfile <<  "" << endl;
    00136
    00137     psfile <<  "$maindict begin" << endl;
    00138     psfile <<  "/savedstate save def" << endl;
    00139
    00140     psfile <<  "%% Print date:" << endl;
    00141     psfile <<  "gsave" << endl;
    00142     psfile <<  "  /Courier findfont" << endl;
    00143     psfile <<  "  10 scalefont setfont" << endl;
    00144     psfile <<  "  80 18 moveto" << endl;
    00145     psfile <<  "  ("<<date<<"  page "<<page<<") show"<<endl;
    00146     psfile <<  "grestore" << endl;
    00147     psfile <<  "" << endl;
    00148
    00149     setup_page_state(xn, yn);
    00150     setup_caption_data();
    00151   }
    00152
    00153 void PSFile::end_page()
    00154   {
    00155     psfile <<  "showpage" << endl;
    00156     psfile <<  "" << endl;
    00157     aux_end_page();
    00158   }
    00159
    00160 void PSFile::save_scales(
    00161     double _xmin, double _xmax,
    00162     double _ymin, double _ymax,
    00163     double _hmin, double _hmax,
    00164     double _vmin, double _vmax
    00165   )
    00166   {
    00167     hmin = _hmin;
    00168     hmax = _hmax;
    00169     xmin = _xmin;
    00170     xmax = _xmax;
    00171     xscale = (hmax - hmin)/(xmax - xmin);
    00172
    00173     vmin = _vmin;
    00174     vmax = _vmax;
    00175     ymin = _ymin;
    00176     ymax = _ymax;
    00177     yscale = (vmax - vmin)/(ymax - ymin);
    00178
    00179   }
    00180
    00181 void PSFile::define_procs()
    00182   {
    00183     psfile <<  "%% Rectangle draw op:" << endl;
    00184     psfile <<  "%%   /xlo/ /xhi/ /ylo/ /yhi/ recd --> " << endl;
    00185     psfile <<  "/recd" << endl;
    00186     psfile <<  "{" << endl;
    00187     psfile <<  "  gsave" << endl;
    00188     psfile <<  "  newpath" << endl;
    00189     psfile <<  "    3 index 2 index moveto" << endl;
    00190     psfile <<  "    2 index 2 index lineto" << endl;
    00191     psfile <<  "    2 index 1 index lineto" << endl;
    00192     psfile <<  "    3 index 1 index lineto" << endl;
    00193     psfile <<  "    pop pop pop pop" << endl;
    00194     psfile <<  "    closepath" << endl;
    00195     psfile <<  "    stroke" << endl;
    00196     psfile <<  "  grestore" << endl;
    00197     psfile <<  "} def" << endl;
    00198     psfile <<  "" << endl;
    00199
    00200     psfile <<  "%% Rectangle fill op:" << endl;
    00201     psfile <<  "%%   /xlo/ /xhi/ /ylo/ /yhi/ /gray/ recf --> " << endl;
    00202     psfile <<  "/recf" << endl;
    00203     psfile <<  "{" << endl;
    00204     psfile <<  "  gsave" << endl;
    00205     psfile <<  "    setgray" << endl;
    00206     psfile <<  "    newpath" << endl;
    00207     psfile <<  "    3 index 2 index moveto" << endl;
    00208     psfile <<  "    2 index 2 index lineto" << endl;
    00209     psfile <<  "    2 index 1 index lineto" << endl;
    00210     psfile <<  "    3 index 1 index lineto" << endl;
    00211     psfile <<  "    pop pop pop pop" << endl;
    00212     psfile <<  "    closepath" << endl;
    00213     psfile <<  "    fill" << endl;
    00214     psfile <<  "  grestore" << endl;
    00215     psfile <<  "} def" << endl;
    00216     psfile <<  "" << endl;
    00217
    00218     psfile <<  "%% Rectangle fill and stroke op:" << endl;
    00219     psfile <<  "%%   /xlo/ /xhi/ /ylo/ /yhi/ /gray/ recfd --> " << endl;
    00220     psfile <<  "/recfd" << endl;
    00221     psfile <<  "{" << endl;
    00222     psfile <<  "  gsave" << endl;
    00223     psfile <<  "    newpath" << endl;
    00224     psfile <<  "    4 index 3 index moveto" << endl;
    00225     psfile <<  "    3 index 3 index lineto" << endl;
    00226     psfile <<  "    3 index 2 index lineto" << endl;
    00227     psfile <<  "    4 index 2 index lineto" << endl;
    00228     psfile <<  "    closepath" << endl;
    00229     psfile <<  "    gsave setgray fill grestore" << endl;
    00230     psfile <<  "    stroke" << endl;
    00231     psfile <<  "    pop pop pop pop" << endl;
    00232     psfile <<  "  grestore" << endl;
    00233     psfile <<  "} def" << endl;
    00234     psfile <<  "" << endl;
    00235
    00236     psfile <<  "%% Polygon draw op:" << endl;
    00237     psfile <<  "%%   /x1/ /y1/ .. /xn/ /yn/ /n/ pold --> " << endl;
    00238     psfile <<  "/pold" << endl;
    00239     psfile <<  "{" << endl;
    00240     psfile <<  "  gsave" << endl;
    00241     psfile <<  "    newpath" << endl;
    00242     psfile <<  "    3 1 roll moveto" << endl;
    00243     psfile <<  "    1 sub 1 1  3 2 roll { pop lineto } for" << endl;
    00244     psfile <<  "    closepath" << endl;
    00245     psfile <<  "    stroke" << endl;
    00246     psfile <<  "  grestore" << endl;
    00247     psfile <<  "} def" << endl;
    00248     psfile <<  "" << endl;
    00249
    00250     psfile <<  "%% Polygon fill op:" << endl;
    00251     psfile <<  "%%   /x1/ /y1/ .. /xn/ /yn/ /n/ /gray/ polf --> " << endl;
    00252     psfile <<  "/polf" << endl;
    00253     psfile <<  "{" << endl;
    00254     psfile <<  "  gsave" << endl;
    00255     psfile <<  "    setgray" << endl;
    00256     psfile <<  "    newpath" << endl;
    00257     psfile <<  "    3 1 roll moveto" << endl;
    00258     psfile <<  "    1 sub 1 1  3 2 roll { pop lineto } for" << endl;
    00259     psfile <<  "    closepath" << endl;
    00260     psfile <<  "    fill" << endl;
    00261     psfile <<  "  grestore" << endl;
    00262     psfile <<  "} def" << endl;
    00263     psfile <<  "" << endl;
    00264
    00265     psfile <<  "%% Polygon fill and draw op:" << endl;
    00266     psfile <<  "%%   /x1/ /y1/ .. /xn/ /yn/ /n/ /gray/ polfd --> " << endl;
    00267     psfile <<  "/polfd" << endl;
    00268     psfile <<  "{" << endl;
    00269     psfile <<  "  gsave" << endl;
    00270     psfile <<  "    newpath" << endl;
    00271     psfile <<  "    4 2 roll moveto" << endl;
    00272     psfile <<  "    exch 1 sub" << endl;
    00273     psfile <<  "    %% -- /x1/ /y1/ .. /x[n-1]/ /y[n-1]/ /gray/ /n-1/" << endl;
    00274     psfile <<  "    1 1  3 2 roll { pop 3 1 roll lineto } for" << endl;
    00275     psfile <<  "    closepath" << endl;
    00276     psfile <<  "    gsave setgray fill grestore" << endl;
    00277     psfile <<  "    stroke" << endl;
    00278     psfile <<  "  grestore" << endl;
    00279     psfile <<  "} def" << endl;
    00280     psfile <<  "" << endl;
    00281
    00282     psfile <<  "%% Circle fill op:" << endl;
    00283     psfile <<  "%%   /x/ /y/ /radius/ /gray/ cirf --> " << endl;
    00284     psfile <<  "/cirf" << endl;
    00285     psfile <<  "{" << endl;
    00286     psfile <<  "  gsave" << endl;
    00287     psfile <<  "    setgray" << endl;
    00288     psfile <<  "    newpath" << endl;
    00289     psfile <<  "      0 360 arc" << endl;
    00290     psfile <<  "      closepath" << endl;
    00291     psfile <<  "    fill" << endl;
    00292     psfile <<  "  grestore" << endl;
    00293     psfile <<  "} def" << endl;
    00294     psfile <<  "" << endl;
    00295
    00296     psfile <<  "%% Circle draw op:" << endl;
    00297     psfile <<  "%%   /x/ /y/ /radius/ cird --> " << endl;
    00298     psfile <<  "/cird" << endl;
    00299     psfile <<  "{" << endl;
    00300     psfile <<  "  gsave" << endl;
    00301     psfile <<  "    newpath" << endl;
    00302     psfile <<  "      0 360 arc" << endl;
    00303     psfile <<  "      closepath" << endl;
    00304     psfile <<  "    stroke" << endl;
    00305     psfile <<  "  grestore" << endl;
    00306     psfile <<  "} def" << endl;
    00307     psfile <<  "" << endl;
    00308
    00309     psfile <<  "%% Circle fill and draw op:" << endl;
    00310     psfile <<  "%%   /x/ /y/ /radius/ /gray/ cirfd --> " << endl;
    00311     psfile <<  "/cirfd" << endl;
    00312     psfile <<  "{" << endl;
    00313     psfile <<  "  gsave" << endl;
    00314     psfile <<  "    4 1 roll" << endl;
    00315     psfile <<  "    newpath" << endl;
    00316     psfile <<  "      0 360 arc" << endl;
    00317     psfile <<  "      closepath" << endl;
    00318     psfile <<  "      gsave setgray fill grestore" << endl;
    00319     psfile <<  "    stroke" << endl;
    00320     psfile <<  "  grestore" << endl;
    00321     psfile <<  "} def" << endl;
    00322     psfile <<  "" << endl;
    00323
    00324     psfile <<  "%% Lune fill and draw op:" << endl;
    00325     psfile <<  "%%   /xc/ /yc/ /rad/ /tilt/ /gray/ lunefd --> " << endl;
    00326     psfile <<  "/lunefd" << endl;
    00327     psfile <<  "{" << endl;
    00328     psfile <<  "  gsave" << endl;
    00329     psfile <<  "    5 1 roll" << endl;
    00330     psfile <<  "    %% --- gray, xc, yc, rad, tilt" << endl;
    00331     psfile <<  "    4 2 roll" << endl;
    00332     psfile <<  "    %% --- gray, rad, tilt, xc, yc" << endl;
    00333     psfile <<  "    translate" << endl;
    00334     psfile <<  "    %% --- gray, rad, tilt" << endl;
    00335     psfile <<  "    rotate" << endl;
    00336     psfile <<  "    %% --- gray, rad " << endl;
    00337     psfile <<  "    newpath" << endl;
    00338     psfile <<  "      dup" << endl;
    00339     psfile <<  "      %% --- gray, rad, rad" << endl;
    00340     psfile <<  "      dup neg 0" << endl;
    00341     psfile <<  "      %% --- gray, rad, rad, -rad, 0" << endl;
    00342     psfile <<  "      3 2 roll 2 mul" << endl;
    00343     psfile <<  "      %% --- gray, rad, -rad, 0, 2*rad" << endl;
    00344     psfile <<  "      -60 60 arc" << endl;
    00345     psfile <<  "      %% --- gray, rad" << endl;
    00346     psfile <<  "      dup 0" << endl;
    00347     psfile <<  "      %% --- gray, rad, rad, 0" << endl;
    00348     psfile <<  "      3 2 roll 2 mul" << endl;
    00349     psfile <<  "      %% --- gray, rad, 0, 2*rad" << endl;
    00350     psfile <<  "      120 240 arc" << endl;
    00351     psfile <<  "      closepath" << endl;
    00352     psfile <<  "      gsave setgray fill grestore" << endl;
    00353     psfile <<  "    stroke" << endl;
    00354     psfile <<  "  grestore" << endl;
    00355     psfile <<  "} def" << endl;
    00356     psfile <<  "" << endl;
    00357
    00358     psfile <<  "%% Cell fill op:" << endl;
    00359     psfile <<  "%%   /xi/ /yi/ celf --> " << endl;
    00360     psfile <<  "/celf" << endl;
    00361     psfile <<  "{" << endl;
    00362     psfile <<  "  3 1 roll " << endl;
    00363     psfile <<  "  exch dup " << endl;
    00364     psfile <<  "  xstep mul xmin add exch 1 add xstep mul xmin add" << endl;
    00365     psfile <<  "  3 2 roll dup" << endl;
    00366     psfile <<  "  ystep mul ymin add exch 1 add ystep mul ymin add" << endl;
    00367     psfile <<  "  5 4 roll " << endl;
    00368     psfile <<  "  recf" << endl;
    00369     psfile <<  "} def" << endl;
    00370     psfile <<  "" << endl;
    00371
    00372     psfile <<  "%% Triangle fill op:" << endl;
    00373     psfile <<  "%%   /xa/ /ya/ /xb/ /yb/ /xc/ /yc/ /gray/ trif --> " << endl;
    00374     psfile <<  "/trif" << endl;
    00375     psfile <<  "{" << endl;
    00376     psfile <<  "  gsave" << endl;
    00377     psfile <<  "    setgray" << endl;
    00378     psfile <<  "    newpath" << endl;
    00379     psfile <<  "    moveto" << endl;
    00380     psfile <<  "    lineto" << endl;
    00381     psfile <<  "    lineto" << endl;
    00382     psfile <<  "    closepath" << endl;
    00383     psfile <<  "    fill" << endl;
    00384     psfile <<  "  grestore" << endl;
    00385     psfile <<  "} def" << endl;
    00386     psfile <<  "" << endl;
    00387
    00388     psfile <<  "%% Segment draw op:" << endl;
    00389     psfile <<  "%%   /xa/ /ya/ /xb/ /yb/ segd --> " << endl;
    00390     psfile <<  "/segd" << endl;
    00391     psfile <<  "{" << endl;
    00392     psfile <<  "  gsave" << endl;
    00393     psfile <<  "    newpath" << endl;
    00394     psfile <<  "    moveto" << endl;
    00395     psfile <<  "    lineto" << endl;
    00396     psfile <<  "    stroke" << endl;
    00397     psfile <<  "  grestore" << endl;
    00398     psfile <<  "} def" << endl;
    00399     psfile <<  "" << endl;
    00400
    00401     psfile <<  "%% Curve draw op:" << endl;
    00402     psfile <<  "%%   /xa/ /ya/  /xb/ /yb/  /xc/ /yc/  /xd/ /yd/ arcd --> " << endl;
    00403     psfile <<  "/arcd" << endl;
    00404     psfile <<  "{" << endl;
    00405     psfile <<  "  gsave" << endl;
    00406     psfile <<  "    newpath" << endl;
    00407     psfile <<  "      8 -2 roll moveto curveto" << endl;
    00408     psfile <<  "    stroke" << endl;
    00409     psfile <<  "  grestore" << endl;
    00410     psfile <<  "} def" << endl;
    00411     psfile <<  "" << endl;
    00412
    00413     psfile <<  "%% Draw an X-value grid line:" << endl;
    00414     psfile <<  "%%   /x/ xgrd --> " << endl;
    00415     psfile <<  "/xgrd" << endl;
    00416     psfile <<  "{" << endl;
    00417     psfile <<  "  gsave" << endl;
    00418     psfile <<  "  newpath" << endl;
    00419     psfile <<  "    dup ymin moveto" << endl;
    00420     psfile <<  "    ymax lineto" << endl;
    00421     psfile <<  "    stroke" << endl;
    00422     psfile <<  "  grestore" << endl;
    00423     psfile <<  "} def" << endl;
    00424     psfile <<  "" << endl;
    00425
    00426     psfile <<  "%% Draw an Y-value grid line:" << endl;
    00427     psfile <<  "%%   /y/ ygrd --> " << endl;
    00428     psfile <<  "/ygrd" << endl;
    00429     psfile <<  "{" << endl;
    00430     psfile <<  "  gsave" << endl;
    00431     psfile <<  "  newpath" << endl;
    00432     psfile <<  "    dup xmin exch moveto" << endl;
    00433     psfile <<  "    xmax exch lineto" << endl;
    00434     psfile <<  "    stroke" << endl;
    00435     psfile <<  "  grestore" << endl;
    00436     psfile <<  "} def" << endl;
    00437     psfile <<  "" << endl;
    00438
    00439     psfile <<  "%% Label printing op:" << endl;
    00440     psfile <<  "%%   /str/ /xa/ /ya/ /xc/ /yc/ lbsh --> " << endl;
    00441     psfile <<  "/lbsh" << endl;
    00442     psfile <<  "{" << endl;
    00443     psfile <<  "  labelfont setfont" << endl;
    00444     psfile <<  "  newpath moveto" << endl;
    00445     psfile <<  "    %% --- str, xa, ya" << endl;
    00446     psfile <<  "  gsave 2 index false charpath flattenpath pathbbox grestore" << endl;
    00447     psfile <<  "    %% --- str, xa, ya, lox, loy, hix, hiy" << endl;
    00448     psfile <<  "  3 index 3 index currentpoint " << endl;
    00449     psfile <<  "    %% --- str, xa, ya, lox, loy, hix, hiy, lox, loy, cx, cy" << endl;
    00450     psfile <<  "  exch 4 1 roll exch sub" << endl;
    00451     psfile <<  "  3 1 roll sub exch" << endl;
    00452     psfile <<  "    %% --- str, xa, ya, lox, loy, hix, hiy, cx-lox, cy-loy" << endl;
    00453     psfile <<  "  rmoveto" << endl;
    00454     psfile <<  "    %% --- str, xa, ya, lox, loy, hix, hiy" << endl;
    00455     psfile <<  "  exch 4 1 roll exch sub " << endl;
    00456     psfile <<  "  3 1 roll sub exch" << endl;
    00457     psfile <<  "    %% --- str, xa, ya, dx, dy" << endl;
    00458     psfile <<  "  exch 4 1 roll mul -1 mul" << endl;
    00459     psfile <<  "  3 1 roll mul -1 mul exch" << endl;
    00460     psfile <<  "    %% --- str, -dx*xa, -dy*ya" << endl;
    00461     psfile <<  "  rmoveto" << endl;
    00462     psfile <<  "    %% --- str" << endl;
    00463     psfile <<  "  show" << endl;
    00464     psfile <<  "} def" << endl;
    00465     psfile <<  "" << endl;
    00466
    00467     psfile.flush();
    00468   }
    00469
    00470 void PSFile::define_caption_procs()
    00471   {
    00472     psfile <<  "%% op to move to new caption line:" << endl;
    00473     psfile <<  "%%   nl --> " << endl;
    00474     psfile <<  "/nl" << endl;
    00475     psfile <<  "{" << endl;
    00476     psfile <<  "  /ytext ytext dytext sub def" << endl;
    00477     psfile <<  "  xtext ytext moveto" << endl;
    00478     psfile <<  "} def" << endl;
    00479     psfile <<  "" << endl;
    00480
    00481     psfile <<  "%% op to print string at CP without clipping:" << endl;
    00482     psfile <<  "%%   /s/ shw --> " << endl;
    00483     psfile <<  "/shw" << endl;
    00484     psfile <<  "{" << endl;
    00485     psfile <<  "  gsave" << endl;
    00486     psfile <<  "    initclip" << endl;
    00487     psfile <<  "    captionfont setfont show" << endl;
    00488     psfile <<  "  grestore" << endl;
    00489     psfile <<  "} def" << endl;
    00490     psfile <<  "" << endl;
    00491
    00492     psfile.flush();
    00493   }
    00494
    00495 void PSFile::setup_page_state(int xn, int yn)
    00496   {
    00497     double fxn = xn;
    00498     double fyn = yn;
    00499
    00500     psfile <<  "%% Round joints and caps:" << endl;
    00501     psfile <<  "1 setlinecap 1 setlinejoin" << endl;
    00502     psfile <<  "" << endl;
    00503
    00504     psfile <<  "%% Black thin lines:" << endl;
    00505     psfile <<  "0 setlinewidth 0 setgray [ ] 0 setdash" << endl;
    00506     psfile <<  "" << endl;
    00507
    00508     psfile <<  "/xmin "<< hmin <<" def   %% min plottable x" << endl;
    00509     psfile <<  "/xmax "<< hmax <<" def   %% max plottable x" << endl;
    00510     psfile <<  "/xn "<< xn <<" def     %% grid cells along x axis" << endl;
    00511     psfile <<  "/xstep "<< ((hmax-hmin)/fxn) <<" def  %% x-size of grid cell" << endl;
    00512
    00513     psfile <<  "/ymin "<< vmin <<" def   %% min plottable y" << endl;
    00514     psfile <<  "/ymax "<< vmax<<" def   %% max plottable y" << endl;
    00515     psfile <<  "/yn "<< yn<<" def     %% grid cells along y axis" << endl;
    00516     psfile <<  "/ystep "<< ((vmax-vmin)/fyn)<<" def  %% y-size of grid cell" << endl;
    00517
    00518     psfile <<  "%% Units of measure:" << endl;
    00519     psfile <<  "/pt 1.0 def" << endl;
    00520     psfile <<  "/in pt 72.0 mul def " << endl;
    00521     psfile <<  "/mm pt 72.0 25.4 div mul def" << endl;
    00522     psfile <<  "" << endl;
    00523
    00524     set_label_font ("Courier", 8.0);
    00525
    00526     psfile <<  "%% Set clipping path to boundary of plot area:" << endl;
    00527     psfile <<  "newpath" << endl;
    00528     psfile <<  "  xmin ymin moveto" << endl;
    00529     psfile <<  "  xmax ymin lineto" << endl;
    00530     psfile <<  "  xmax ymax lineto" << endl;
    00531     psfile <<  "  xmin ymax lineto" << endl;
    00532     psfile <<  "  xmin ymin lineto" << endl;
    00533     psfile <<  "clip" << endl;
    00534     psfile <<  "" << endl;
    00535
    00536     psfile.flush();
    00537   }
    00538
    00539 void PSFile::setup_caption_data()
    00540   {
    00541     psfile <<  "%% Caption text cursor:" << endl;
    00542     psfile <<  "/xtext xmin def" << endl;
    00543     psfile <<  "/ytext ymin def" << endl;
    00544     psfile <<  "/dytext 10 pt mul def" << endl;
    00545     psfile <<  "" << endl;
    00546
    00547     psfile <<  "%% Caption font setup:" << endl;
    00548     psfile <<  "/captionfont" << endl;
    00549     psfile <<  "  /Courier findfont" << endl;
    00550     psfile <<  "  dytext scalefont" << endl;
    00551     psfile <<  "def" << endl;
    00552     psfile <<  "" << endl;
    00553   }
    00554
    00555 void PSFile::aux_end_page()
    00556   {
    00557     psfile <<  "savedstate restore" << endl;
    00558     psfile <<  "%% Now we are back to the standard coord system." << endl;
    00559     psfile <<  "" << endl;
    00560     psfile <<  "end %% $maindict" << endl;
    00561     psfile <<  "" << endl;
    00562     psfile.flush();
    00563   }
    00564
    00565 void PSFile::begin_section(char *title)
    00566   {
    00567     psfile <<  "%% "<< title << endl;
    00568     psfile.flush();
    00569   }
    00570
    00571 void PSFile::end_section()
    00572   {
    00573     psfile <<  "" << endl;
    00574     psfile.flush();
    00575   }
    00576
    00577 void PSFile::add_caption(char *txt)
    00578   {
    00579     psfile <<  "nl ";
    00580     put_text(txt, ") shw\nnl (");
    00581     psfile <<  " shw" << endl;
    00582     psfile.flush();
    00583   }
    00584
    00585 void PSFile::set_label_font(char *font, float size)
    00586   {
    00587     psfile <<  "%% Label font setup:" << endl;
    00588     psfile <<  "/labelfont" << endl;
    00589     psfile <<  "  /"<< font<<" findfont "<< size<< " pt mul scalefont" << endl;
    00590     psfile <<  "def" << endl;
    00591     psfile <<  "" << endl;
    00592     psfile.flush();
    00593   }
    00594
    00595 void PSFile::put_label(
    00596     char *text,
    00597     double x, double y,
    00598     float xalign, float yalign
    00599   )
    00600   {
    00601     double psx = hmin + xscale * (x - xmin);
    00602     double psy = vmin + yscale * (y - ymin);
    00603     put_text(text, "\\267");
    00604     psfile <<  " ";
    00605     psfile << xalign<<' '<<yalign<<' '<<psx<<' '<<psy << " lbsh"<<endl;
    00606     psfile.flush();
    00607   }
    00608
    00609 void PSFile::draw_frame ()
    00610   {
    00611     begin_section("Draw frame around plot area");
    00612     psfile <<  "gsave" << endl;
    00613     psfile <<  "%% Assumes xmax, xmin, ymax, ymin are defined." << endl;
    00614     psfile <<  "  initclip" << endl;
    00615     psfile <<  "  newpath" << endl;
    00616     psfile <<  "  xmin ymin moveto" << endl;
    00617     psfile <<  "  xmax ymin lineto" << endl;
    00618     psfile <<  "  xmax ymax lineto" << endl;
    00619     psfile <<  "  xmin ymax lineto" << endl;
    00620     psfile <<  "  xmin ymin lineto" << endl;
    00621     psfile <<  "  closepath stroke" << endl;
    00622     psfile <<  "grestore" << endl;
    00623     end_section();
    00624   }
    00625
    00626 void PSFile::set_pen(
    00627
    00628     double gray,
    00629     double width,
    00630     double dashlength,
    00631     double dashspace
    00632   )
    00633   {
    00634     psfile << gray << "setgray" << endl;
    00635     psfile <<  "mm "<<width<<" mul setlinewidth" << endl;
    00636     if ((dashlength == 0.0) | (dashspace == 0.0))
    00637       {
    00638         psfile <<  "[ ] 0 setdash" << endl;
    00639       }
    00640     else
    00641       {
    00642         psfile <<  "[ "<<dashlength<<" mm mul "<<dashspace<<" mm mul ] 0 setdash"<<endl;
    00643       }
    00644     psfile <<  "" << endl;
    00645     psfile.flush();
    00646   }
    00647
    00648 void PSFile::draw_segment(
    00649
    00650     double xa, double ya,
    00651     double xb, double yb
    00652   )
    00653   {
    00654     double psxa = hmin + xscale * (xa - xmin);
    00655     double psya = vmin + yscale * (ya - ymin);
    00656     double psxb = hmin + xscale * (xb - xmin);
    00657     double psyb = vmin + yscale * (yb - ymin);
    00658     psfile << psxa<<' '<<psya<<' '<<psxb<<' '<<psyb << "segd" << endl;
    00659     psfile.flush();
    00660   }
    00661
    00662 void PSFile::draw_curve(
    00663
    00664     double xa, double ya,
    00665     double xb, double yb,
    00666     double xc, double yc,
    00667     double xd, double yd
    00668   )
    00669   {
    00670     double psxa = hmin + xscale * (xa - xmin);
    00671     double psya = vmin + yscale * (ya - ymin);
    00672     double psxb = hmin + xscale * (xb - xmin);
    00673     double psyb = vmin + yscale * (yb - ymin);
    00674     double psxc = hmin + xscale * (xc - xmin);
    00675     double psyc = vmin + yscale * (yc - ymin);
    00676     double psxd = hmin + xscale * (xd - xmin);
    00677     double psyd = vmin + yscale * (yd - ymin);
    00678     psfile << psxa<<' '<<psya<<' '<<psxb<<' '<<psyb<<' '<<psxc<<' '<<psyc<<' '<<psxd<<' '<<psyd<<" arcd"<<endl;
    00679     psfile.flush();
    00680   }
    00681
    00682 void PSFile::aux_rectangle(
    00683
    00684     double xlo, double xhi,
    00685     double ylo, double yhi,
    00686     double gray,
    00687     char *op
    00688   )
    00689   {
    00690     double psxlo = hmin + xscale * (xlo - xmin);
    00691     double psxhi = hmin + xscale * (xhi - xmin);
    00692     double psylo = vmin + yscale * (ylo - ymin);
    00693     double psyhi = vmin + yscale * (yhi - ymin);
    00694     psfile << psxlo<<' '<<psxhi<<' '<<psylo<<' '<<psyhi;
    00695     if (gray >= 0.0) psfile <<  ' '<< gray;
    00696     psfile <<  " "<< op << endl;
    00697     psfile.flush();
    00698   }
    00699
    00700 void PSFile::draw_rectangle(
    00701
    00702     double xlo, double xhi,
    00703     double ylo, double yhi
    00704   )
    00705   {
    00706     aux_rectangle(xlo, xhi, ylo, yhi, -1.0, "recd");
    00707   }
    00708
    00709 void PSFile::fill_rectangle(
    00710
    00711     double xlo, double xhi,
    00712     double ylo, double yhi,
    00713     double gray
    00714   )
    00715   {
    00716     aux_rectangle(xlo, xhi, ylo, yhi, gray, "recf");
    00717   }
    00718
    00719 void PSFile::fill_and_draw_rectangle(
    00720
    00721     double xlo, double xhi,
    00722     double ylo, double yhi,
    00723     double gray
    00724   )
    00725   {
    00726     aux_rectangle(xlo, xhi, ylo, yhi, gray, "recfd");
    00727   }
    00728
    00729 void PSFile::aux_polygon(
    00730     double x[], double y[],
    00731     int npoints,
    00732     double gray,
    00733     char *op
    00734   )
    00735   {
    00736     int i;
    00737     if (npoints>6) psfile <<  "" << endl;
    00738     for (i=0; i<npoints; i++)
    00739       {
    00740         double psxi = hmin + xscale * (x[i] - xmin);
    00741         double psyi = vmin + yscale * (y[i] - ymin);
    00742         if ((i % 6) == 0)
    00743           { if (i>0) psfile <<  "" << endl; }
    00744         else
    00745           { psfile <<  "  "; }
    00746         psfile <<  psxi<<' '<<psyi;
    00747       }
    00748     if (npoints>6) psfile <<  "" << endl;
    00749     psfile <<  "  "<< npoints<<"";
    00750     if (gray >= 0.0) psfile <<  ' ' << gray;
    00751     psfile <<  " "<< op << endl;
    00752     psfile.flush();
    00753   }
    00754
    00755 void PSFile::draw_polygon(
    00756     double x[], double y[],
    00757     int npoints
    00758   )
    00759   {
    00760     aux_polygon(x, y, npoints, -1.0, "pold");
    00761   }
    00762
    00763 void PSFile::fill_polygon(
    00764     double x[], double y[],
    00765     int npoints,
    00766     double gray
    00767   )
    00768   {
    00769     aux_polygon(x, y, npoints, gray, "polf");
    00770   }
    00771
    00772 void PSFile::fill_and_draw_polygon(
    00773     double x[], double y[],
    00774     int npoints,
    00775     double gray
    00776   )
    00777   {
    00778     aux_polygon(x, y, npoints, gray, "polfd");
    00779   }
    00780
    00781 void PSFile::aux_circle(
    00782     double xc, double yc, double radius,
    00783     double gray,
    00784     char *op
    00785   )
    00786   {
    00787     double psxc = hmin + xscale * (xc - xmin);
    00788     double psyc = vmin + yscale * (yc - ymin);
    00789     double psradius = yscale * radius;
    00790     psfile <<  psxc<<' '<<psyc<<' '<<psradius;
    00791     if (gray >= 0.0) psfile <<  ' ' << gray;
    00792     psfile <<  " "<< op <<endl;
    00793     psfile.flush();
    00794   }
    00795
    00796 void PSFile::fill_circle(
    00797     double xc, double yc, double radius,
    00798     double gray
    00799   )
    00800   {
    00801     aux_circle(xc, yc, radius, gray, "cirf");
    00802   }
    00803
    00804 void PSFile::draw_circle(
    00805     double xc, double yc, double radius
    00806   )
    00807   {
    00808     aux_circle(xc, yc, radius, -1.0, "cird");
    00809   }
    00810
    00811 void PSFile::fill_and_draw_circle(
    00812     double xc, double yc, double radius,
    00813     double gray
    00814   )
    00815   {
    00816     aux_circle(xc, yc, radius, gray, "cirfd");
    00817   }
    00818
    00819 void PSFile::aux_lune(
    00820     double xc, double yc, double radius, double tilt,
    00821     double gray,
    00822     char *op
    00823   )
    00824   {
    00825     double psxc = hmin + xscale * (xc - xmin);
    00826     double psyc = vmin + yscale * (yc - ymin);
    00827     double psradius = yscale * radius;
    00828     double pstilt = tilt * 180.0 / 3.1415926;
    00829     psfile << psxc<<' '<< psyc<<' '<<psradius<<' '<<pstilt;
    00830     if (gray >= 0.0) psfile <<  ' ' <<  gray;
    00831     psfile <<  " "<< op <<endl;
    00832     psfile.flush();
    00833   }
    00834
    00835 void PSFile::fill_and_draw_lune(
    00836     double xc, double yc, double radius, double tilt,
    00837     double gray
    00838   )
    00839   {
    00840     aux_lune(xc, yc, radius, tilt, gray, "lunefd");
    00841   }
    00842
    00843 void PSFile::fill_triangle(
    00844     double xa, double ya,
    00845     double xb, double yb,
    00846     double xc, double yc,
    00847     double gray
    00848   )
    00849   {
    00850     double psxa = hmin + xscale * (xa - xmin);
    00851     double psya = vmin + yscale * (ya - ymin);
    00852     double psxb = hmin + xscale * (xb - xmin);
    00853     double psyb = vmin + yscale * (yb - ymin);
    00854     double psxc = hmin + xscale * (xc - xmin);
    00855     double psyc = vmin + yscale * (yc - ymin);
    00856     psfile << psxa<<' '<<psya<<' '<<psxb<<' '<<psyb<<' '<<psxc<<' '<<psyc<<' '<<gray << " trif" << endl;
    00857     psfile.flush();
    00858   }
    00859
    00860 void PSFile::fill_grid_cell(int xi, int yi, double gray)
    00861   {
    00862     psfile <<  xi<<' '<<yi<<' '<<gray<<" celf"<<endl;
    00863     psfile.flush();
    00864   }
    00865
    00866 void PSFile::draw_coord_line (char axis, double coord)
    00867   {
    00868     double pscoord;
    00869     if (axis == 'x')
    00870       { pscoord = hmin + xscale * (coord - xmin); }
    00871     else if (axis == 'y')
    00872       { pscoord = vmin + yscale * (coord - ymin); }
    00873     else
    00874       {
    00875         return;
    00876       }
    00877     psfile <<  pscoord<< axis<< "grd"<<endl;
    00878   }
    00879
    00880 void PSFile::draw_grid_lines()
    00881   {
    00882     psfile <<  "%% Grid lines:" << endl;
    00883     psfile <<  "gsave" << endl;
    00884     psfile <<  "  initclip" << endl;
    00885     psfile <<  "  0 1 xn {" << endl;
    00886     psfile <<  "    xstep mul xmin add xgrd" << endl;
    00887     psfile <<  "  } for" << endl;
    00888     psfile <<  "  0 1 yn {" << endl;
    00889     psfile <<  "    ystep mul ymin add ygrd" << endl;
    00890     psfile <<  "  } for" << endl;
    00891     psfile <<  "grestore" << endl;
    00892     psfile <<  "" << endl;
    00893     psfile.flush();
    00894   }
    00895
    00896 void PSFile::put_text(char *text, char *newline)
    00897   {
    00898     char *p;
    00899     psfile<<'(';
    00900     for (p = text; *p != 0; p++)
    00901       {
    00902         if (*p == '\n')
    00903           { psfile << ""<< newline <<"";}
    00904         else if (*p == '(')
    00905           { psfile<<'\\'; psfile<<'('; }
    00906         else if (*p == ')')
    00907           { psfile<<'\\'; psfile<<')'; }
    00908         else if (*p == '\t')
    00909           { psfile<<' '; psfile<<' '; }
    00910         else if (*p == '\\')
    00911           { psfile<<'\\'; psfile<<'\\'; }
    00912         else if ((*p < ' ') || (*p > '~'))
    00913           { psfile <<  '\\'<< *p << 'o'; }
    00914         else
    00915           { psfile<<*p; }
    00916       }
    00917     psfile <<  ')';
    00918   }
    00919
    00920 PSFile& PSFile::operator<<(const Model& m)
    00921 {
    00922     psfile << m;
    00923     return (*this);
    00924 }
    00925
    00926
    00927 }