source: Sophya/trunk/SophyaPI/PI/psfile.cc @ 4086

Last change on this file since 4086 was 4086, checked in by garnier, 11 years ago

before moving eventFilter

File size: 46.3 KB
Line 
1/*
2 *   PSFile.cc
3 *   
4 *   19/06/96
5 *
6 *   Modification le 01/03/96
7 *    - fusion psfile.cc - psdict.cc
8 *
9 *
10 *   07/08/99 : Gestion des fontes ; ajout Times/Helvetica/Symbol
11 *             
12 *
13 *
14 *
15 */
16#include <stdlib.h>
17#include <string.h>
18#include <stdio.h>
19#include <time.h>
20
21#include "sopnamsp.h"
22#include "psfile.h"
23
24//++
25// Class        PSFile
26// Lib          PI
27// include      psfile.h
28//
29//      Classe encapsulant un fichier PostScript, fournissant des primitives
30//      graphiques produisant du code PostScript.
31//--
32//++
33// Links        Voir aussi
34// PIGraphicPS
35//--
36
37
38
39/* En cm */
40#define  MIN_SIZE_IN_PAGE  2.
41
42/*
43 *  Dictionnaire PIDict
44 *
45 *  Contient les fonctions suivantes :
46 *
47 *
48 */
49#define PIDICT_PAR   \
50  \
51  PI_Landscape, PI_Portrait,\
52  \
53  PI_ColorFromMap, PI_Black, PI_White, PI_Grey, PI_Red, PI_Blue,\
54  PI_Green, PI_Yellow, PI_Magenta, PI_NotDefColor,\
55  PI_Cyan, PI_Turquoise, PI_NavyBlue,\
56  PI_Orange, PI_SiennaRed, PI_Purple,\
57  PI_LimeGreen, PI_Gold, \
58  PI_Violet, PI_VioletRed, PI_BlueViolet, PI_DarkViolet, \
59  PI_SkyBlue, PI_RoyalBlue, PI_ForestGreen, \
60  PI_OrangeRed, PI_Brown, PI_HighlightBlue, \
61  \
62  PI_RomanFont, PI_BoldFont, PI_ItalicFont, PI_NotDefFontAtt,\
63  PI_SmallSizeFont, PI_NormalSizeFont, PI_LargeSizeFont, PI_NotDefFontSize, \
64  \
65  PI_NormalLine, PI_ThinLine, PI_ThickLine, PI_NotDefLineAtt
66
67#define PIDICT       "\
68/$PIDict 50 dict def\n\
69$PIDict begin $PIDict /mtrx matrix put /Landscape %d def /Portrait %d def\n\
70%% Couleurs et fontes courantes\n\
71/C%-2d  {ur    ug    ub    setrgbcolor} bind def %% PI_ColorFromMap\n\
72/C%-2d  {0.0   0.0   0.0   setrgbcolor} bind def %% PI_Black\n\
73/C%-2d  {1.000 1.000 1.000 setrgbcolor} bind def %% PI_White\n\
74/C%-2d  {0.824 0.824 0.824 setrgbcolor} bind def %% PI_Grey\n\
75/C%-2d  {1.000 0.0   0.0   setrgbcolor} bind def %% PI_Red\n\
76/C%-2d  {0.0   0.0   1.000 setrgbcolor} bind def %% PI_Blue\n\
77/C%-2d  {0.0   1.000 0.0   setrgbcolor} bind def %% PI_Green\n\
78/C%-2d  {1.000 1.000 0.0   setrgbcolor} bind def %% PI_Yellow\n\
79/C%-2d  {1.000 0.0   1.000 setrgbcolor} bind def %% PI_Magenta\n\
80/C%-2d  {}                              bind def %% PI_NotDefColor\n\
81/C%-2d  {0.0   1.000 1.000 setrgbcolor} bind def %% PI_Cyan\n\
82/C%-2d  {0.250 0.875 0.813 setrgbcolor} bind def %% PI_Turquoise\n\
83/C%-2d  {0.0   0.0   0.500 setrgbcolor} bind def %% PI_NavyBlue\n\
84/C%-2d  {1.000 0.644 0.0   setrgbcolor} bind def %% PI_Orange\n\
85/C%-2d  {0.625 0.320 0.176 setrgbcolor} bind def %% PI_SiennaRed\n\
86/C%-2d  {0.625 0.125 0.937 setrgbcolor} bind def %% PI_Purple\n\
87/C%-2d  {0.195 0.800 0.195 setrgbcolor} bind def %% PI_LimeGreen\n\
88/C%-2d  {1.000 0.840 0.0   setrgbcolor} bind def %% PI_Gold\n\
89/C%-2d  {0.933 0.510 0.933 setrgbcolor} bind def %% PI_Violet\n\
90/C%-2d  {0.816 0.125 0.565 setrgbcolor} bind def %% PI_VioletRed\n\
91/C%-2d  {0.541 0.167 0.886 setrgbcolor} bind def %% PI_BlueViolet\n\
92/C%-2d  {0.580 0.000 0.827 setrgbcolor} bind def %% PI_DarkViolet\n\
93/C%-2d  {0.530 0.805 0.920 setrgbcolor} bind def %% PI_SkyBlue\n\
94/C%-2d  {0.255 0.410 0.880 setrgbcolor} bind def %% PI_RoyalBlue\n\
95/C%-2d  {0.135 0.545 0.135 setrgbcolor} bind def %% PI_ForestGreen\n\
96/C%-2d  {1.000 0.270 0.000 setrgbcolor} bind def %% PI_OrangeRed\n\
97/C%-2d  {0.647 0.165 0.165 setrgbcolor} bind def %% PI_Brown\n\
98/C%-2d  {0.600 0.750 1.000 setrgbcolor} bind def %% PI_HighlightBlue\n\
99/F%-2d  {/Courier   findfont} bind def           %% PI_RomanFont\n\
100/F%-2d  {/Courier-Bold    findfont} bind def     %% PI_BoldFont\n\
101/F%-2d  {/Courier-Italic  findfont} bind def     %% PI_ItalicFont\n\
102/F%-2d  {}\
103                        bind def       %% PI_NotDefFontAtt\n\
104/FS {scalefont setfont} bind def\n\
105%%/FS%-2d {8  scalefont setfont} bind def          %% PI_SmallSizeFont\n\
106%%/FS%-2d {12 scalefont setfont} bind def          %% PI_NormalSizeFont\n\
107%%/FS%-2d {16 scalefont setfont} bind def          %% PI_LargeSizeFont\n\
108/FS%-2d {}                     bind def          %% PI_NotDefFontSize\n\
109/L%-2d  {1    slw} bind def                      %% PI_NormalLine\n\
110/L%-2d  {0.5  slw} bind def                      %% PI_ThinLine\n\
111/L%-2d  {3    slw} bind def                      %% PI_ThickLine\n\
112/L%-2d  {}         bind def                      %% PI_NotDefLineAtt\n\
113\
114%% Conversion\n\
115/cm   {28.3 mul}   bind def  %% cm --> points\n\
116/Ux   {$Cvrtx mul} bind def  %% Unites utilisateur /x --> points\n\
117/Uy   {$Cvrty mul} bind def  %% Unites utilisateur /y --> points\n\
118\
119%% Pages et Blocs\n\
120/newref  {%% Dx Dy Tx Ty X0 Y0 newref\n\
121translate 3 -1 roll cm div 28.3 mul /$Cvrty exch def\n\
122exch cm div 28.3 mul /$Cvrtx exch def} bind def\n\
123/NewPage {%% Dx Dy orientation NewPage\n\
124/$PageEnteredState save def 1 -1 scale Portrait eq {w cm h cm 0 h cm neg\n\
125newref} { -90 rotate h cm w cm 0 0 newref} ifelse} bind def\n\
126/EndPage { %% EndPage\n\
127$PageEnteredState restore} bind def\n\
128/NewBloc { %% Dx Dy Tx Ty X0 Y0 NewBloc\n\
129/$BlocEnteredState save def newref} bind def\n\
130/EndBloc { %% EndBloc\n\
131$BlocEnteredState restore} bind def\n\
132\
133%% Trace\n\
134/n  {newpath} bind def    /c  {closepath} bind def\n\
135/gs {gsave}  bind def     /gr {grestore} bind def\n\
136/m  {moveto} bind def     /l  {lineto} bind def\n\
137/s  {stroke} bind def     /f  {fill}   bind def\n\
138/sc {scale}  bind def     /S  {gs 1 -1 sc show gr} bind def \n\
139/slw {setlinewidth} bind def\n\
140/sljoin {setlinejoin} bind def\n\
141/slcap {setlinecap} bind def\n\
142/slsolid {[] 0 setdash} bind def %% Solid-Line \n\
143/sldash {[6 6] 0 setdash} bind def %% Dashed-Line \n\
144/sldott {[2 6] 0 setdash} bind def %% Dotted-Line \n\
145/sldashdott {[2 2 4 6] 0 setdash} bind def %% Dash-Dotted-Line \n\
146/ff {findfont} bind def   /sf {setfont} bind def /scf {scalefont} bind def\n\
147/rl {rlineto} bind def    /tr {translate} bind def\n\
148/rmv {rmoveto} bind def \n\
149%% Trace de chaine avec justification diverse \n\
150%% ------------------------------------------------- \n\
151%% hxshstr  stack: TheString \n\
152%% hx (x=r,c,l) Horizontal-X Right,Center,Left - Vertical: BaseLine \n\
153%% ------------------------------------------------- \n\
154/hlshstr   %% Horizontal-left Vertical-BaseLine justified \n\
155{ gs 1 -1 sc show gr } bind def \n\
156/hcshstr   %% Horizontal-Center Vertical-BaseLine justified \n\
157{ dup stringwidth pop 2 div neg  %% get minus(string length/2)  \n\
158  0 rmoveto gs 1 -1 sc show gr } bind def \n\
159/hrshstr   %% Horizontal-Right Vertical-BaseLine justified \n\
160{ dup stringwidth pop neg  %% get minus(string width)  \n\
161  0 rmoveto gs 1 -1 sc show gr } bind def \n\
162%% ------------------------------------------------- \n\
163%% hxvyshstr  stack: TheString \n\
164%% hx (x=r,c,l) Horizontal-X Right,Center,Left \n\
165%% vy (y=t,c,b) Vertical-Y Top,Center,Bottom \n\
166%% Ces procs (hxvyshstr) utilisent la variable curfntsz que l'on definit par defaut \n\
167%% hxshstr  stack: TheString \n\
168%% hx (x=r,c,l) Horizontal-X Right,Center,Left - Vertical: BaseLine \n\
169%% ------------------------------------------------- \n\
170/curfntsz 10 def \n\
171/hlvbshstr   %% Horizontal-left Vertical-Bottom justified \n\
172{ gs 1 -1 sc show gr } bind def \n\
173/hcvbshstr   %% Horizontal-Center Vertical-Bottom justified \n\
174{ dup stringwidth pop 2 div neg  %% get minus(string length/2)  \n\
175  0 rmoveto gs 1 -1 sc show gr } bind def \n\
176/hrvbshstr   %% Horizontal-Right Vertical-Bottom justified \n\
177{ dup stringwidth pop neg  %% get minus(string width)  \n\
178  0 rmoveto gs 1 -1 sc show gr } bind def \n\
179/hlvcshstr   %% Horizontal-left Vertical-Center justified \n\
180{ 0 curfntsz 2 div   %% get (string height)/2  \n\
181  rmoveto gs 1 -1 sc show gr } bind def \n\
182/hcvcshstr   %% Horizontal-Center Vertical-Center justified \n\
183{ dup stringwidth pop 2 div neg curfntsz 2 div  %% s_wy/2 -s_wx/2  \n\
184  rmoveto gs 1 -1 sc show gr } bind def \n\
185/hrvcshstr   %% Horizontal-Right Vertical-Center justified \n\
186{ dup stringwidth pop neg curfntsz  %% s_wy/2 -s_wx  \n\
187  rmoveto gs 1 -1 sc show gr } bind def \n\
188/hlvtshstr   %% Horizontal-left Vertical-Top justified \n\
189{ 0 curfntsz   %% get s_wy  \n\
190  rmoveto gs 1 -1 sc show gr } bind def \n\
191/hcvtshstr   %% Horizontal-Center Vertical-Top justified \n\
192{ dup stringwidth pop 2 div neg curfntsz  %% s_wy -s_wx/2  \n\
193  rmoveto gs 1 -1 sc show gr } bind def \n\
194/hrvtshstr   %% Horizontal-Right Vertical-Top justified \n\
195{ dup stringwidth pop neg curfntsz  %% s_wy -s_wx  \n\
196  rmoveto gs 1 -1 sc show gr } bind def \n\
197%% Tx Ty X0 Y0 box\n\
198/box {tr 0 3 1 roll neg exch 0 0 3 index neg 0 0 m rl rl rl c} bind def\n\
199%% R X0 Y0 circle\n\
200/circle {tr dup 0 m 0 0 3 -1 roll 0 380 arc} bind def\n\
201%% DrawEllipse pompee sur transfig\n\
202/ellipse {/endangle exch def /startangle exch def /yrad exch def\n\
203/xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def\n\
204x y tr xrad yrad sc 0 0 1 startangle endangle arc\n\
205closepath savematrix setmatrix } def\n\
206\
207%% pipsarc Arc \n\
208/pipsarc {/endangle exch def /startangle exch def /yrad exch def\n\
209/xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def\n\
210x y tr xrad yrad sc 0 0 1 startangle endangle arc\n\
211savematrix setmatrix } def\n\
212\
213%% pipsfarc Arc plein \n\
214/pipsfarc {/endangle exch def /startangle exch def /yrad exch def\n\
215/xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def\n\
216x y tr 0 0 moveto xrad yrad sc 0 0 1 startangle endangle arc 0 0  lineto\n\
217closepath savematrix setmatrix } def\n\
218\
219%% Gestion des images\n\
220%% ColorImage, pompee sur xv (qui les avait pompees sur xgrab)\n\
221/colorimage where   %% do we know about 'colorimage'?\n\
222  { pop }           %% yes: pop off the 'dict' returned\n\
223  {                 %% no:  define one\n\
224    /colortogray {  %% define an RGB->I function\n\
225      /rgbdata exch store    %% call input 'rgbdata'\n\
226      rgbdata length 3 idiv\n\
227      /npixls exch store\n\
228      /rgbindx 0 store\n\
229      0 1 npixls 1 sub {\n\
230        grays exch\n\
231        rgbdata rgbindx       get 20 mul    %% Red\n\
232        rgbdata rgbindx 1 add get 32 mul    %% Green\n\
233        rgbdata rgbindx 2 add get 12 mul    %% Blue\n\
234        add add 64 idiv      %% I = .5G + .31R + .18B\n\
235        put\n\
236        /rgbindx rgbindx 3 add store\n\
237      } for\n\
238      grays 0 npixls getinterval\n\
239    } bind def\n\
240    /mergeprocs { %% def\n\
241      dup length 3 -1 roll dup length dup 5 1 roll 3 -1 roll add\n\
242      array cvx dup 3 -1 roll 0 exch putinterval dup 4 2 roll\n\
243      putinterval } bind def\n\
244    /colorimage {\n\
245      pop pop     %% remove 'false 3' operands\n\
246      {colortogray} mergeprocs image} bind def\n\
247  } ifelse          %% end of 'false' case\n\
248\
249%% GetRGB\n\
250/GetRGB { %% ImageStr --> RGBStr\n\
251  /ImageData exch store\n\
252  %% Pour chaque element de ImageData,\n\
253  %% On va chercher les valeurs RGB correspondantes\n\
254  0 1 Taille 1 sub {\n\
255    /i      exch store  %% On met a jour l'indice de parcours\n\
256    ImageData i get     %% Recupere la Indice e val dans la chaine ImData\n\
257    ColorMap exch get   %% On recupere la valeur RGB Correspondante\n\
258    aload pop           %% On met tout ca dans la pile\n\
259    %% Maintenant, on va mettre tout ca dans la chaine RGBStr\n\
260    RGBStr i 3 mul 2 add 3 -1 roll put\n\
261    RGBStr i 3 mul 1 add 3 -1 roll put\n\
262    RGBStr i 3 mul       3 -1 roll put\n\
263    } for\n\
264  RGBStr 0 Taille 3 mul getinterval %% On renvoie la chaine RGB\n\
265} bind def\n\
266end\n\
267"
268
269
270
271/*
272 *  Les PIMarkers sont definis et geres commes des fontes
273 *
274 *
275 */
276#define PIMARKERS_PAR  PI_DotMarker, PI_PlusMarker, PI_CrossMarker,\
277  PI_CircleMarker, PI_FCircleMarker, PI_BoxMarker, PI_FBoxMarker,\
278  PI_TriangleMarker, PI_FTriangleMarker, PI_StarMarker, PI_FStarMarker
279
280#define PIMARKERS  "\
281%% Definition de la fonte $PIMarkers\n\
282/$PIMarkers 26 dict def\n\
283$PIMarkers begin\n\
284/FontType 3 def\n\
285/FontMatrix [0.001 0 0 0.001 -0.375 -0.375] def\n\
286/FontBBox   [0 0 1000 1000] def\n\
287/Encoding 256 array def\n\
2880 1 255 {Encoding exch /.notdef put} for\n\
289Encoding  %d /PIDot       put %% PI_DotMarker\n\
290Encoding  %d /PIPlus      put %% PI_PlusMarker\n\
291Encoding  %d /PICross     put %% PI_CrossMarker\n\
292Encoding  %d /PICircle    put %% PI_CircleMarker\n\
293Encoding  %d /PIFCircle   put %% PI_FCircleMarker\n\
294Encoding  %d /PIBox       put %% PI_BoxMarker\n\
295Encoding  %d /PIFBox      put %% PI_FBoxMarker\n\
296Encoding  %d /PITriangle  put %% PI_TriangleMarker\n\
297Encoding  %d /PIFTriangle put %% PI_FTriangleMarker\n\
298Encoding  %d /PIStar      put %% PI_StarMarker\n\
299Encoding  %d /PIFStar     put %% PI_FStarMarker\n\
300/CharProcs 26 dict def\n\
301$PIDict begin\n\
302CharProcs begin\n\
303/.notdef     {} def\n\
304/PIDot       {100 375 375 circle f} bind def\n\
305/PIPlus      {0 375 m 750 375 l 375 0 m 375 750 l s} bind def\n\
306/PICross     {0 0 m 750 750 l 750 0 m 0 750 l s} bind def\n\
307/PICircle    {375 375 375 circle s} bind def\n\
308/PIFCircle   {375 375 375 circle f} bind def\n\
309/PIBox       {0 0 m 750 0 l 750 750 l 0 750 l c s} bind def\n\
310/PIFBox      {0 0 m 750 0 l 750 750 l 0 750 l c f} bind def\n\
311/PITriangle  {0 750 m 375 0 l 750 750 l c s} bind def\n\
312/PIFTriangle {0 750 m 375 0 l 750 750 l c f} bind def\n\
313/PIStar      {731 260 m 459 260 l 375 0 l 291 260 l 19 260 l \
314239 419 l 155 678 l 375 518 l 595 678 l 511 419 l c s} def\n\
315/PIFStar     {731 260 m 459 260 l 375 0 l 291 260 l 19 260 l \
316239 419 l 155 678 l 375 518 l 595 678 l 511 419 l c f} def\n\
317end %%$PIDict\n\
318end %%$CharProcs\n\
319/BuildChar {\n\
3201000 0      %% Largeur \n\
3210 0 750 750 %% Bounding Box\n\
322setcachedevice \n\
323exch begin\n\
324Encoding exch get\n\
325CharProcs exch get\n\
326end 75 slw exec} def\n\
327end\n\
328/PIMarkers $PIMarkers definefont pop\n\
329save\n\
330"
331
332/* Dimensions des divers formats */
333  struct PaperSize {
334      double width ;
335      double height ;
336  };
337struct PaperSize PaperSizeTable[] = {
338    { 0.0,  0.0},    /* PI_NotDefFormat */
339    {21.0, 29.7},    /* PI_A4 */
340    {29.7, 42.0},    /* PI_A3 */
341    {14.8, 21.0}     /* PI_A5 ? */
342} ;
343
344
345double cm2pt(double x);
346
347
348/* Fonction WriteHeader */
349#define END_PROLOG_PAR  PAGE_WIDTH, PAGE_HEIGHT
350#define END_PROLOG  "/NewFile { %%%% w h NewFile (--> h et w en cm <--)\n\
351$PIDict begin /PIMarkers ff 14 scf sf /h exch def /w exch def \n\
352/$PIEnteredState save def} bind def\n\
353/EndFile {$PIEnteredState restore end} bind def\n\
354%%%%EndProlog\n\n\
355"
356
357#define HEADER     "\
358%%%%Title: %s\n\
359%%%%Creator: PI-PSFile (N.R. 07/08/99)\n\
360%%%%CreationDate: %s\
361%%%%Pages: (atend)\n\
362%%%%EndComments\n\n\
363"
364
365//++
366// Titre        Constructeurs
367//--
368//++
369// PSFile (const char * FileName, double sc = 1.0)
370//      Créateur pour fichier Encapsulated Postscript
371// PSFile (const char * FileName, PIOrientation orientation, -
372//         PIPaperSize paperSize= PI_A4, -
373//         double marginX = 5.0, double marginY = 5.0 )
374//      Créateur pour fichier Postscript
375//--
376
377/*
378   Utilisation de la resolution coordonnees utilisateur (resolution ecran)
379   pour definir correctement la taille des fontes
380                                      R. Ansari - Juillet 2001
381*/
382/* Definition de la resolution coordonnees user par defaut (point/cm ou pixels/cm) */ 
383
384float PSFile::postscript_resolution = 28.;  /* environ 72 points / pouce  */
385float PSFile::def_user_resol_X = 30.;      /* environ 75 points / pouce  */
386float PSFile::def_user_resol_Y = 30.;
387float PSFile::def_user_resolution = 30.;
388
389void PSFile::SetUserCoordResolution(float resx, float resy)
390{
391  if ((resx < 1.) || (resy < 1.)) return;
392  def_user_resol_X = resx;
393  def_user_resol_Y = resy;
394  def_user_resolution = 0.5*(resx+resy);
395}
396float PSFile::GetUserCoordResolution(float& resx, float& resy)
397{
398  resx = def_user_resol_X;
399  resy = def_user_resol_Y;
400  return (def_user_resolution);
401}
402float PSFile::PSCoordResolution()
403{
404  return (postscript_resolution);
405}
406
407/*
408 *   PostScript encapsule...
409 *
410 *   Attention la bounding Box ne sera specifiee
411 *     qu'au premier NewPage() --> definie dans
412 *     le champ "Trailer"
413 *
414 */
415PSFile::PSFile(const char * FileName, double sc) 
416    : mPSFileName(FileName==NULL? "unnamed.eps" : const_cast<char *>(FileName)),
417      Tw (-1.), Th(-1.),         /* Non specifies pour du eps  */
418      WMargin (-1), HMargin(-1), /* Non specifiees en eps  */ 
419      isEPS(1),
420      scale(sc),                 /* Defaut : 1. */
421      mPaperSize(PI_NotDefPaperSize), /* Non specifiee en eps */
422      PageCounter(0),            /* Fichier vide */
423      FileEmpty(1),              /* Fichier vide */
424      currentPage(NULL),
425      currentBloc(NULL),
426      mDrawColor(PI_Black),
427      mFillColor(PI_Black),
428      mFontAtt(PI_RomanFont),
429      mFontSize(0),
430      mFontName(PI_DefaultFont), 
431      mLineAtt(PI_NormalLine),
432      mMarker(PI_DotMarker),
433      setFontDone(true)
434{
435    char*  date = new (char[64] ) ; 
436    time_t timer ; 
437
438    /* Ouverture du fichier en mode w+ */
439    if ( (mPSFile = fopen(FileName, "w+")) == NULL){
440          perror (FileName);
441          return;
442    }
443
444    /* Ecriture du Header  */
445    fprintf(mPSFile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
446    fprintf(mPSFile, "%%%%BoundingBox: ");
447    /*
448     * Les dimensions de la BB seront notees ici lors du
449     * premier appel a NewPage
450     *
451     * C'est laid... si qqn a une meilleure idee...
452     */
453    boundingBox = ftell(mPSFile) ; 
454    fprintf(mPSFile, "                       \n");
455
456    time(&timer) ; 
457    date = ctime(&timer) ; 
458    fprintf(mPSFile, HEADER, mPSFileName, date) ; /* titre, date etc... */
459    fprintf(mPSFile, PIDICT, PIDICT_PAR) ;        /* Dictionnaire */
460    fprintf(mPSFile, PIMARKERS, PIMARKERS_PAR) ;  /* Fonte "PIMARKERS" */
461    //    fprintf(mPSFile, END_PROLOG) ;
462    /* Aucun format n'est specifie ici ... */
463    fprintf(mPSFile, "$PIDict begin /PIMarkers ff 14 scf sf\n") ;
464    fprintf(mPSFile, "/FState save def\n%%%%EndProlog\n\n") ;
465}
466
467
468
469/*
470 *  PostScript simple...
471 *
472 *
473 */
474PSFile::PSFile(const char *FileName,
475               PIOrientation orientation,
476               PIPaperSize   paperSize,
477               double marginX, double marginY)
478 :  mPSFileName (FileName == NULL ? "unnamed.ps" : const_cast<char *>(FileName)),
479    Tw(PaperSizeTable[paperSize].width),  /* Format papier utilise */
480    Th(PaperSizeTable[paperSize].height), /*                       */
481    WMargin(marginX),
482    HMargin(marginY),
483    isEPS(0),
484    scale(0.),
485    PageCounter(0),  /* Fichier vide */
486    FileEmpty(1),    /*              */
487    currentPage(NULL),
488    currentBloc(NULL),
489    mDrawColor(PI_Black),
490    mFillColor(PI_Black),
491    mFontAtt(PI_RomanFont),
492    mFontSize(0),
493    mFontName(PI_DefaultFont),
494    mLineAtt(PI_NormalLine),
495    mMarker(PI_DotMarker), 
496    setFontDone(true)
497{
498    char * date = new(char[64]) ; 
499    time_t timer ; 
500
501    /* Ouverture du fichier, en mode w+ (tout est ecrase) */
502    if ( (mPSFile = fopen(FileName, "w+")) == NULL){
503          perror (FileName);
504          return;
505    }
506
507    /* Format et orientation */
508
509    /* Ecriture du Header  */
510    fprintf(mPSFile, "%%!PS-Adobe-2.0\n") ;
511    time(&timer) ; 
512    date = ctime(&timer) ; 
513    fprintf(mPSFile, HEADER, mPSFileName, date) ; /* titre, date etc... */
514    fprintf(mPSFile, PIDICT, PIDICT_PAR) ;        /* Dictionnaire */
515    fprintf(mPSFile, PIMARKERS, PIMARKERS_PAR) ;  /* Fonte "PIMARKERS" */
516    fprintf(mPSFile, "$PIDict begin /PIMarkers ff 14 scf sf\n") ;
517    fprintf(mPSFile, "/FState save def\n%%%%EndProlog\n\n") ;
518}
519
520
521/*
522 * Destructeur
523 *
524 */
525PSFile::~PSFile () {
526
527    /* On ferme tout ce qui ne l'est pas */
528    if (currentBloc) PSFile::EndBloc();
529    if (currentPage) PSFile::EndPage();
530
531    /* Si le fichier est vide, on le detruit */
532    if (FileEmpty) remove(mPSFileName);
533
534    /* On ecrit le "Trailer" et on ferme */
535    else {
536        /* On restore l'etat initial */
537        fprintf(mPSFile,"FState restore\n") ;
538        fprintf(mPSFile, "%%%%Trailer\n%%%%Pages: %d\n%%%%EOF\n", 
539                PageCounter) ;
540        fclose (mPSFile);
541    }
542}
543
544
545int   PSFile::IsEPS(){
546
547    return(isEPS);
548}
549
550
551const char* PSFile::GetFileName() {
552
553    return(mPSFileName);
554}
555
556PIColors PSFile::GetDrawColor() {
557
558    return(mDrawColor);
559}
560
561PIColors PSFile::GetFillColor() {
562
563    return(mFillColor);
564}
565
566PIFontAtt PSFile::GetFontAtt() {
567
568    return(mFontAtt);
569}
570
571// N.R. 07/08/99 return val PIFontSize --> int
572int PSFile::GetFontSize() {
573
574    return(mFontSize);
575}
576
577PILineAtt PSFile::GetLineAtt() {
578
579    return(mLineAtt);
580}
581
582PIMarker PSFile::GetMarker() {
583
584    return(mMarker);
585}
586
587//++
588// NewPage(double Dx, double Dy, PIOrientation orientation)
589//      Debut de nouvelle page, (Dx,Dy) indique l'extension
590//      (taille) du systeme de coordonnees utilisees pour la page
591// EndPage()
592//      Fin de page
593//--
594
595void  PSFile::NewPage(double Dx, double Dy, PIOrientation orientation) {
596
597double  tw, th; /* largeur & hauteur corrigees des marges */
598
599    /* On ferme ce qui doit l'etre ... */
600    if (currentPage) PSFile::EndPage();
601
602    currentPage = new (Page) ; 
603
604    /* Initialisations */
605    currentPage->num = ++PageCounter;
606    currentPage->BlocCounter = 0;
607    currentPage->Dx = Dx;
608    currentPage->Dy = Dy;
609    currentPage->orientation = orientation ;
610
611    /* Position du debut AVANT D'ECRIRE! */
612    currentPage->begin  = ftell(mPSFile);
613
614    /* On ecrit dans le fichier */
615    fprintf(mPSFile, "%%%%Page: %d %d\n", PageCounter, PageCounter) ;
616    fprintf(mPSFile, "/PState save def 1 -1 scale\n");
617
618    /*
619     *  Si eps : Portrait || Auto == on laisse tel que
620     *           Landscape == on tourne de -90 degres
621     */
622    if(isEPS) {
623        if( (orientation == PI_Portrait) || (orientation == PI_Auto) )
624            fprintf(mPSFile,
625                    "%.2f %.2f %.2f %.2f %.2f %.2f newref\n",
626                    Dx, Dy, Dx*scale, Dy*scale, 0., -Dy*scale);
627        else
628            if(orientation==PI_Landscape)
629                fprintf(mPSFile, 
630                        "-90 rotate %.2f %.2f %.2f %.2f %.2f %.2f newref\n",
631                        Dx, Dy, Dx*scale, Dy*scale, 0., 0.);
632            else
633                fprintf(stderr, "Orientation Error ; Page : %d\n",
634                        currentPage->num) ; 
635    /*
636     * On specifie la bb
637     * (Si non encore fait par un appel precedent a NewPage() )
638     */
639        if(boundingBox) {
640            currentPage->tmp = ftell(mPSFile) ;
641            fseek(mPSFile,boundingBox,SEEK_SET) ;
642            if( (orientation == PI_Portrait) || (orientation == PI_Auto) )
643                fprintf(mPSFile, "%d %d %d %d", 0, 0, 
644                        (int)(Dx*scale), (int)(Dy*scale) ) ; 
645            else
646                fprintf(mPSFile, "%d %d %d %d", 0, 0, 
647                        (int)(Dy*scale), (int)(Dx*scale) ) ;
648            fseek(mPSFile,currentPage->tmp,SEEK_SET) ;
649            boundingBox = 0 ; 
650        } /* BB */
651        /* facteur d'echelle pour les fontes*/
652        currentPage->FontScaleFactor = scale; 
653        //        postscript_resolution/def_user_resolution*scale;
654        /*
655        cout << " EPS_DBG_FontScaleFactor = " << currentPage->FontScaleFactor
656             << " scale= " << scale << " postscript_resolution= "
657             << postscript_resolution << " def_user_resolution= "
658             << def_user_resolution << endl;
659        */
660    } /* EPS */
661    /*
662     * Si ps :
663     *   - soustraction marges --> rectangle utile.
664     *   - Si PI_Auto : On fait au mieux pour minimiser le
665     *      redimensionnement...
666     *   - Si PI_Portrait, on ne fait rien, sauf
667     *      peut-etre un redimensionnement pour rentrer dans les marges
668     *   - Si PI_Landscape, on tourne de -90 degres.
669     */
670    else {
671        // Si marges <= 0 on les met a 2cm
672        if(WMargin<=0) WMargin = 2. ; 
673        if(HMargin<=0) HMargin = 2. ; 
674        /* Eviter image reduite a un point...ou moins... */
675        if((tw = Tw - 2*WMargin) < (Tw/10)) {
676            WMargin = (0.45)*Tw ;
677            tw = Tw/10;
678        }
679        if((th = Th - 2*HMargin)< (Th/10)) {
680            HMargin = (0.45)*Th ;
681            th = Th/10;
682        }
683        /* Portrait ou Landscape ? */
684        if(orientation == PI_Auto)  {
685            if( ((tw < th) && (Dx < 1.2*Dy)) ||
686                ((tw > th) && (Dx > Dy) )) 
687                currentPage->orientation = PI_Portrait ;
688            else 
689                currentPage->orientation = PI_Landscape ;
690        }
691        if(currentPage->orientation == PI_Portrait) {
692          //        if( (tw/Dx) < (th/Dy) )
693          //            scale = tw/Dx ;
694          //                scale = tw/Tw ;
695          //        else
696          //            scale = th/Dy;
697          //                scale = th/Th;
698          //        fprintf(mPSFile,
699          //                "%.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
700          //                Dx, Dy,
701          //                Dx*scale, Dy*scale,
702          //                Tw*scale, Th*scale,
703          //                0.5*(Tw-tw), -0.5*(Th+th)) ;
704            scale = (tw/Dx)<(th/Dy) ? tw/Dx : th/Dy ; 
705            tw = scale*Dx ; th = scale*Dy ; 
706            fprintf(mPSFile, 
707                    "%.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
708                    Dx, Dy, 
709                    tw, th, 
710                    0.5*(Tw-tw), -0.5*(Th+th)) ;
711        }  /* End if .Portrait  */
712        if(currentPage->orientation == PI_Landscape) {
713            /* Idem avec X<->Y */
714//          if( (th/Dx) < (th/Dy) )
715//              scale = th/Dx;
716//                scale = th/Tw;
717//          else
718//              scale = tw/Dy ;
719//                scale = tw/Th;
720//          fprintf(mPSFile,
721//             "-90 rotate %.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
722//             Dx, Dy,
723//             Dx*scale, Dy*scale,
724//             Th*scale, Tw*scale,
725//             0.5*(Th-th), 0.5*(Tw-tw));
726
727            scale = (th/Dx)<(tw/Dy) ? th/Dx : tw/Dy ; 
728            th = scale*Dx ; tw = scale*Dy ; 
729            fprintf(mPSFile,
730               "-90 rotate %.2f %.2f %.2f cm %.2f cm %.2f cm %.2f cm newref\n",
731               Dx, Dy,
732               th, tw,
733               0.5*(Th-th), 0.5*(Tw-tw));
734        } /* End if .Landscape */
735        /* facteur d'echelle pour les fontes*/
736        currentPage->FontScaleFactor = scale*postscript_resolution;
737        /*
738        cout << " PS_DBG_FontScaleFactor = " << currentPage->FontScaleFactor
739             << " scale= " << scale << " postscript_resolution= "
740             << postscript_resolution << " def_user_resolution= "
741             << def_user_resolution << endl;
742        */
743    } /* End if .ps */
744// On redefint la fonte par defaut - $CHECK$ Reza 11/12/99
745mFontAtt = PI_RomanFont;
746mFontSize = 10;
747mFontName = PI_DefaultFont;
748double scaledFontSize = (double)mFontSize*currentPage->FontScaleFactor;
749fprintf(mPSFile, "/Courier ff %g FS /curfntsz %g def \n", scaledFontSize, scaledFontSize) ; 
750setFontDone = true;
751currentPage->tmp = ftell(mPSFile);
752}
753
754
755
756void  PSFile::EndPage() {
757
758    /* Si rien a fermer, on s'en va */
759    if ( ! currentPage ) return;
760
761    /* Si un bloc non ferme, on appelle EndBloc */
762    if ( currentBloc ) PSFile::EndBloc();
763   
764    /* Si la page est vide, on la detruit */
765    if (currentPage->tmp == ftell(mPSFile)) {
766        fseek(mPSFile, currentPage->begin, SEEK_SET);
767        delete(currentPage) ;
768        PageCounter--;
769    }
770    /* Sinon, fin page + empilage */
771    else {
772        //      it = mPageList.end(); it--;
773        fprintf(mPSFile,"PState restore  showpage\n");
774        fprintf(mPSFile,"%%>EndPage %d\n\n\n", currentPage->num);
775        currentPage->end = ftell(mPSFile);
776        mPageList.push_back(*currentPage); /* Pourquoi PageList ? */
777        FileEmpty = 0;
778    }
779    currentPage = NULL;
780}
781
782
783//++
784// NewBloc(double x0, double y0, double Tx, double Ty, double Dx, double Dy)
785//      Debut de bloc.
786//|     x0,y0 : position du bloc ds la page
787//|     Tx,Ty : Taille du bloc dans la page
788//|     Dx,Dy : Extension (taille) du systeme de coordonnees utilisateur
789//|     dans le bloc
790//
791// EndBloc()
792//      Fin de bloc
793//--
794
795
796void  PSFile::NewBloc(double x0, double y0, double Tx, double Ty,
797                              double Dx, double Dy){
798
799    /* Si pas de page, on s'en va */
800    if ( ! currentPage ) return;
801
802    /* On ferme le bloc precedent (Pas de Bloc-gigognes ! ) */
803    if (currentBloc) PSFile::EndBloc();
804
805    currentBloc = new (Bloc) ; 
806    /* On remplit currentBloc */
807    currentBloc->num = ++(currentPage->BlocCounter);
808    currentBloc->X0 = x0;
809    currentBloc->Y0 = y0;
810    currentBloc->Tx = Tx;
811    currentBloc->Ty = Ty;
812    currentBloc->Dx = Dx;
813    currentBloc->Dy = Dy;
814    currentBloc->begin = ftell(mPSFile);
815
816    /* On met a jour le fichier */
817    fprintf(mPSFile, "%%>BeginBloc %d\n", currentBloc->num);
818    fprintf(mPSFile, "%.2f %.2f %.2f Ux %.2f Uy %.2f Ux %.2f Uy NewBloc\n",
819            currentBloc->Dx, currentBloc->Dy,
820            currentBloc->Tx, currentBloc->Ty,
821            currentBloc->X0, currentBloc->Y0);
822    // On redefinit la zone de clip
823    fprintf(mPSFile, "%% Define clip region to the entire bloc area \n");
824    fprintf(mPSFile, "initclip newpath 0 0 m %.2f Ux 0 rl 0 %.2f Uy rl %2f Ux 0 rl closepath clip newpath\n",
825            currentBloc->Dx, currentBloc->Dy, -currentBloc->Dx); 
826    // On redefint la fonte par defaut - $CHECK$ Reza 11/12/99
827    mFontAtt = PI_RomanFont;
828    mFontSize = 10;
829    mFontName = PI_DefaultFont;
830    double scaledFontSize = (double)mFontSize*currentPage->FontScaleFactor;
831    fprintf(mPSFile, "/Courier ff %g FS /curfntsz %g def \n", 
832            scaledFontSize, scaledFontSize) ;
833    mLineAtt = PI_NotDefLineAtt;
834    SelectLine(PILineAtt(PI_NormalLine));
835    setFontDone = true;
836    currentBloc->tmp = ftell(mPSFile) ;
837}
838
839
840void  PSFile::EndBloc() {
841
842    /* On verifie qu'un bloc ouvert existe bien */
843    if ( ! currentBloc ) return;
844
845    /* Si le bloc est vide, on le detruit */
846    if (currentBloc->tmp == ftell(mPSFile)) {
847        fseek(mPSFile, currentBloc->begin, SEEK_SET) ; 
848        currentPage->BlocCounter-- ; 
849    }
850    /* Sinon, Ok met a jour le fichier */
851    else { 
852        fprintf(mPSFile, "EndBloc\n"); 
853        fprintf(mPSFile, "%%>EndBloc %d\n", currentBloc->num); 
854        currentBloc->end = ftell(mPSFile) ; 
855        currentPage->mBlocList.push_back(*currentBloc) ; 
856        //      PageEmpty = 0;
857    } 
858    /* Flags */
859    currentBloc = NULL ; 
860}
861
862
863void PSFile::SetClipRectangle(double x0, double y0, double dx, double dy)
864{
865  // On redefinit la zone de clip
866  fprintf(mPSFile, "%% SetClipRectangle: Define clip region \n ");
867  fprintf(mPSFile, "newpath %.2f Ux %.2f Uy m %.2f Ux 0 rl 0 %.2f Uy rl %.2f Ux 0 rl closepath clip newpath\n",
868          x0, y0, dx, dy, -dx); 
869}
870
871void PSFile::ClearClipRectangle()
872{
873  // On redefinit la zone de clip a l'ensemble du bloc
874  fprintf(mPSFile, "%% Define clip region to the entire bloc area \n");
875  fprintf(mPSFile, "initclip newpath 0 0 m %.2f Ux 0 rl 0 %.2f Uy rl %2f Ux 0 rl closepath clip \n",
876          currentBloc->Dx, currentBloc->Dy, -currentBloc->Dx); 
877}
878
879void PSFile::SelForeground(PIColorMap& cmap, int cid)
880{
881  mDrawColor = PI_ColorFromMap ; 
882  PIColor tmp = cmap.GetColor(cid) ; 
883  fprintf(mPSFile, "/ur %.3f def /ug %.3f def /ub %.3f def \n", 
884          (double)(tmp.red)/65535., 
885          (double)(tmp.green)/65535., 
886          (double)(tmp.blue)/65535.) ; 
887}
888
889
890void PSFile::SelBackground(PIColorMap& cmap, int cid)
891{
892  mDrawColor = PI_ColorFromMap ; 
893}
894
895
896/* fonction pour rajouter \ devant ( ) et \ pour string postscript */
897static char * EscapePSString(const char *s)
898{
899  int nce = 0;
900  int ls = strlen(s);
901  int j;
902  for(int k=0; k<ls; k++) 
903    if ( (s[k] == '(') || (s[k] == ')') || (s[k] == '\\') ) nce++;
904  if (nce == 0) return NULL;
905  char * es = new char[ls+nce+1];
906  j = 0;
907  for(int k=0; k<ls; k++) {
908    if ( (s[k] == '(') || (s[k] == ')') || (s[k] == '\\') ) {
909      es[j] = '\\';  j++; 
910    }
911    es[j] = s[k];  j++;
912  }
913  es[j] = '\0';
914  return es;
915}
916
917void  PSFile::DrawString  (double x,  double y, const char *s, 
918                           PIColors DrawColor, 
919                           PIFontName FontName, 
920                           PIFontAtt FontAtt, 
921                           int FontSize, 
922                           unsigned long pos) {
923    bool change = false;
924
925    /* Couleurs */
926    if ( (DrawColor != PI_NotDefColor) && (DrawColor != mDrawColor) ) {
927        mDrawColor = DrawColor;
928        fprintf(mPSFile, "C%d ", mDrawColor) ; 
929    }
930    /* Choix des fontes */
931    if ( (FontAtt != PI_NotDefFontAtt) && (FontAtt != mFontAtt) ) {
932//DBG      printf("PSFile::DrawString(%s) : FontAtt a change : %d %d \n", s, mFontAtt, FontAtt) ;
933      mFontAtt = FontAtt;
934      change = true;
935    }
936    if ( (FontSize != PI_NotDefFontSize) && (FontSize != mFontSize) ) {
937//DBG      printf("PSFile::DrawString(%s) : FontSize a change : %d %d \n", s, mFontSize, FontSize) ;
938      mFontSize = FontSize; 
939      change = true;
940    }
941    if( (FontName != mFontName) ) {
942//DBG      printf("PSFile::DrawString(%s) : FontName a change : %d %d \n", s, mFontName, FontName) ;
943      mFontName = (PIFontName) FontName ; 
944      change = true ; 
945    }
946
947    if (change || !setFontDone) { // $CHECK$ setFontDone Reza 11/12/99
948      string fname ; 
949      switch(mFontName) {
950      case PI_DefaultFont:
951      case PI_CourierFont:
952        fprintf(mPSFile, "/Courier") ; 
953        break ; 
954      case PI_HelveticaFont:
955        fprintf(mPSFile, "/Helvetica") ; 
956        break ; 
957      case PI_TimesFont:
958        fprintf(mPSFile, "/Times") ; 
959        break ; 
960      case PI_SymbolFont:
961        fprintf(mPSFile, "/Symbol ") ; 
962        break ; 
963      } // endsw
964     
965      switch(mFontAtt) {
966      case PI_NotDefFontAtt:
967      case PI_RomanFont:
968        fprintf(mPSFile, " ") ; 
969        break ; 
970      case PI_BoldFont:
971        if(mFontName != PI_SymbolFont) fprintf(mPSFile, "-Bold ") ; 
972        break ; 
973      case PI_ItalicFont:
974        if ((mFontName == PI_DefaultFont) || (mFontName == PI_CourierFont) ||
975            (mFontName == PI_HelveticaFont) ) fprintf(mPSFile, "-Oblique ") ;
976        else if (mFontName == PI_TimesFont) fprintf(mPSFile, "-Italic ") ; 
977        break ; 
978      case PI_BoldItalicFont:
979        if ((mFontName == PI_DefaultFont) || (mFontName == PI_CourierFont) ||
980            (mFontName == PI_HelveticaFont) ) fprintf(mPSFile, "-BoldOblique ") ;
981        else if (mFontName == PI_TimesFont) fprintf(mPSFile, "-BoldItalic ") ; 
982        break ;         
983      } // endsw
984      double scaledFontSize = (double)FontSize*currentPage->FontScaleFactor;
985      fprintf(mPSFile, " ff %g FS /curfntsz %g def \n", scaledFontSize, scaledFontSize);
986      setFontDone = true ;   // $CHECK$ - doit etre fait uniquement a ce moment
987    }
988    /* Les () et \ doivent avoir le caractere escape \ dans les chaines postscript */
989    char * es = EscapePSString(s);
990    const char * epss = s;
991    if (es != NULL) epss = es;
992    if (pos == 0) 
993      fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) S gr\n", x, y, epss) ; 
994    else {
995      unsigned long txtdir = pos & PI_TextDirection;
996      int posh = pos & PI_HorizontalPosition;
997      int posv = pos & PI_VerticalPosition;
998      int angle = 0;
999      if (txtdir == PI_TextDirectionVerticalUp) angle = -90;
1000      else if (txtdir == PI_TextDirectionVerticalDown) angle = 90;
1001
1002      if ((posh == PI_HorizontalLeft)  && 
1003          ((posv == PI_VerticalBaseLine) || (posv == 0)) ) {
1004        if (angle == 0) 
1005          fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) hlshstr gr\n", 
1006                  x, y, epss) ;
1007        else 
1008          fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) hlshstr gr\n",
1009                  x, y, angle, epss) ;
1010      }
1011      else {
1012        char ssvp = 'b';
1013        char sshp = 'l';
1014        if (posh != PI_HorizontalLeft) {
1015          if (posh == PI_HorizontalCenter)  sshp = 'c';
1016          else if (posh == PI_HorizontalRight)  sshp = 'r';
1017          else sshp = 'l';
1018        }
1019        if (posv == 0) {
1020          if (angle == 0) 
1021            fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) h%cshstr gr\n", 
1022                    x, y, epss, sshp) ;
1023          else fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) h%cshstr gr\n",
1024                       x, y, angle, epss, sshp) ;
1025        }
1026        else {
1027          if (posv == PI_VerticalCenter)  ssvp = 'c';
1028          else if (posv == PI_VerticalTop)  ssvp = 't';
1029          else ssvp = 'b';
1030        }
1031        if (angle == 0) 
1032          fprintf(mPSFile, "gs %.2f Ux %.2f Uy m (%s) h%cv%cshstr gr\n", 
1033                  x, y, epss, sshp, ssvp) ; 
1034        else 
1035          fprintf(mPSFile, "gs %.2f Ux %.2f Uy m %d rotate (%s) h%cv%cshstr gr\n",
1036                  x, y, angle, epss, sshp, ssvp) ; 
1037      }
1038    }
1039
1040    if (es) delete[] es;  /* chaine modifiee avec des \( \) ou \\ */   
1041    return;
1042}
1043
1044
1045void  PSFile::DrawLine    (double x1, double y1, double x2, double y2, 
1046                           PIColors DrawColor,
1047                           PILineAtt LineAtt) {
1048
1049
1050    /* Line Att */ 
1051    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1052      SelectLine(LineAtt);
1053
1054    /* Couleurs */
1055    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1056        mDrawColor = DrawColor;
1057        fprintf(mPSFile, "C%d ", mDrawColor);
1058    }
1059
1060    /* Dessin */
1061    fprintf(mPSFile, "n %.2f Ux %.2f Uy m %.2f Ux %.2f Uy l s\n",
1062            x1, y1, x2, y2) ;
1063}
1064
1065
1066
1067void  PSFile::DrawBox(double x0, double y0, double Tx, double Ty, 
1068                      PIColors  DrawColor,
1069                      PILineAtt LineAtt) {
1070
1071    /* Line Att */ 
1072    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1073      SelectLine(LineAtt);
1074
1075    /* Changement couleurs ? */
1076    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1077        mDrawColor = DrawColor;
1078        fprintf(mPSFile, "C%d ", mDrawColor) ; 
1079    }
1080
1081
1082    /* On dessine */
1083    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy box s gr\n",
1084            Tx, Ty, x0, y0) ; 
1085}
1086
1087
1088void  PSFile::DrawFBox(double x0, double y0, double Tx, double Ty, 
1089                   PIColors DrawColor,
1090                   PIColors FillColor, 
1091                   PILineAtt LineAtt) {
1092
1093    /* Line Att */ 
1094    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1095      SelectLine(LineAtt);
1096
1097    /* Dessin du fond */
1098    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ) {
1099      mDrawColor = FillColor;
1100      fprintf(mPSFile, "C%d ", mDrawColor) ;
1101    } 
1102    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy box f gr\n",
1103            Tx, Ty, x0, y0) ; 
1104
1105    /* Dessin du contour (s'il y a lieu) */
1106    if ( (DrawColor != PI_NotDefColor) && (FillColor != DrawColor) ) {
1107        mDrawColor = DrawColor;
1108        fprintf(mPSFile, "C%d ", mDrawColor) ; 
1109        fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy box s gr\n",
1110                Tx, Ty, x0, y0) ;
1111    }
1112}
1113
1114
1115void  PSFile::DrawCircle  (double x0, double y0, double r, 
1116                           PIColors DrawColor,
1117                           PILineAtt LineAtt) {
1118
1119    /* Line Att */ 
1120    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1121      SelectLine(LineAtt);
1122
1123    /* Couleurs */
1124    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1125        mDrawColor = DrawColor;
1126        fprintf(mPSFile, "C%d ", mDrawColor); 
1127    }
1128
1129
1130    /* Dessin */
1131    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy 0 360 ellipse s gr\n",
1132            x0, y0, r, r) ;
1133}
1134
1135
1136void  PSFile::DrawFCircle (double x0, double y0, double r,
1137                   PIColors DrawColor,
1138                   PIColors FillColor, 
1139                   PILineAtt LineAtt) {
1140
1141    /* Line Att */ 
1142    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1143      SelectLine(LineAtt);
1144
1145    /* Dessin du fond */
1146    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ){
1147        mDrawColor = FillColor;
1148        fprintf(mPSFile, "C%d ", mDrawColor) ;
1149    }
1150    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy \
1151                      0 360 ellipse f gr\n",
1152            x0, y0, r, r);
1153
1154    /* Dessin du contour (s'il y a lieu) */
1155    if ( (DrawColor != PI_NotDefColor) && (FillColor != DrawColor) ) {
1156        mDrawColor = DrawColor;
1157        fprintf(mPSFile, "C%d ", mDrawColor); 
1158        fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy 0 360 ellipse s gr\n",
1159                x0, y0, r, r) ;
1160    }
1161}
1162
1163void  PSFile::DrawArc (double x0, double y0, double dx, double dy,
1164                       double degdeb, double deltadeg,
1165                       PIColors DrawColor,
1166                       PILineAtt LineAtt) {
1167
1168    /* Line Att */ 
1169    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1170      SelectLine(LineAtt);
1171
1172    /* Couleurs */
1173    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1174        mDrawColor = DrawColor;
1175        fprintf(mPSFile, "C%d ", mDrawColor); 
1176    }
1177   
1178    double degfin = degdeb+deltadeg;
1179    while (degfin > 360.) degfin -= 360.;
1180    while (degfin < 0.)   degfin += 360.;
1181    /* Dessin */
1182    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy %.2f %.2f pipsarc s gr\n",
1183            x0, y0, dx, dy, degdeb, degfin) ;
1184}
1185
1186
1187void  PSFile::DrawFArc (double x0, double y0, double dx, double dy,
1188                        double degdeb, double deltadeg,
1189                        PIColors DrawColor,
1190                        PIColors FillColor, 
1191                        PILineAtt LineAtt) {
1192
1193    /* Line Att */ 
1194    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1195      SelectLine(LineAtt);
1196
1197    double degfin = degdeb+deltadeg;
1198    while (degfin > 360.) degfin -= 360.;
1199    while (degfin < 0.)   degfin += 360.;
1200    /* Dessin du fond */
1201    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ){
1202        mDrawColor = FillColor;
1203        fprintf(mPSFile, "C%d ", mDrawColor) ;
1204    }
1205    fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy %.2f %.2f pipsfarc f gr\n",
1206            x0, y0, dx, dy, degdeb, degfin);
1207
1208    /* Dessin du contour (s'il y a lieu) */
1209    if ( (DrawColor != PI_NotDefColor) && (FillColor != DrawColor) ) {
1210        mDrawColor = DrawColor;
1211        fprintf(mPSFile, "C%d ", mDrawColor); 
1212        fprintf(mPSFile, "gs n %.2f Ux %.2f Uy %.2f Ux %.2f Uy %.2f %.2f pipsfarc s gr\n",
1213                x0, y0, dx, dy, degdeb, degfin) ;
1214    }
1215}
1216
1217
1218// Les coordonnees sont supposees etre en mode incremental .
1219void  PSFile::DrawPolygon (double *x, double *y, int n,
1220                   PIColors DrawColor, 
1221                   PILineAtt LineAtt, bool cinc) {
1222
1223    /* Line Att */ 
1224    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1225      SelectLine(LineAtt);
1226
1227    /* Couleur */
1228    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1229        mDrawColor = DrawColor;
1230        fprintf(mPSFile, "C%d ", mDrawColor) ;
1231    }
1232   
1233    /* On dessine ; ici*/
1234    fprintf(mPSFile, "%.2f Ux %.2f Uy m\n", x[0], y[0]);
1235
1236    const char* cmd ; 
1237    if(cinc == true) cmd = "%.2f Ux %.2f Uy rl\n" ; 
1238    else             cmd = "%.2f Ux %.2f Uy l\n" ; 
1239
1240    for(int i = 1; i<n; i++) 
1241      fprintf(mPSFile, cmd, x[i], y[i]);
1242    fprintf(mPSFile, " s\n");   // On ne ferme pas le path - Reza 02/2002 - fprintf(mPSFile, "c s\n");
1243}
1244
1245
1246void  PSFile::DrawFPolygon(double *x, double *y, int n,
1247                   PIColors DrawColor,
1248                   PIColors FillColor,
1249                   PILineAtt LineAtt, bool cinc) {
1250
1251    /* Line Att */ 
1252    if ( (LineAtt != PI_NotDefLineAtt) && (LineAtt != mLineAtt) ) 
1253      SelectLine(LineAtt);
1254
1255    const char* cmd ; 
1256    if(cinc == true) cmd = "%.2f Ux %.2f Uy rl\n" ; 
1257    else             cmd = "%.2f Ux %.2f Uy l\n" ; 
1258
1259    /* Dessin du fond... */
1260    if ( (FillColor != PI_NotDefColor) || (FillColor != mDrawColor) ) {
1261        mDrawColor = FillColor;
1262        fprintf(mPSFile, "C%d ", mDrawColor) ;
1263    }
1264    fprintf(mPSFile, "%.2f Ux %.2f Uy m\n", x[0], y[0]);
1265    int i;
1266    for(i = 1; i<n; i++) 
1267        fprintf(mPSFile, cmd, x[i], y[i]);
1268    fprintf(mPSFile, "c f\n");
1269
1270    /* ...puis du contour (s'il y a lieu) */
1271    if ( (DrawColor != PI_NotDefColor) && (DrawColor != FillColor) ) {
1272      mDrawColor = DrawColor;
1273      fprintf(mPSFile, "C%d ", mDrawColor) ;
1274      fprintf(mPSFile, "%.2f Ux %.2f Uy m\n", x[0], y[0]);
1275      for(i = 1; i<n; i++) 
1276        fprintf(mPSFile, cmd, x[i], y[i]);
1277      fprintf(mPSFile, "c s\n");
1278    }
1279}
1280
1281
1282
1283void  PSFile::DrawMarker  (double x0, double y0,
1284                           PIMarker MrkType,   
1285                           PIColors DrawColor,
1286                           int MarkerSize) {
1287    /* Couleurs */
1288    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1289        mDrawColor = DrawColor;
1290        fprintf(mPSFile, "C%d ", mDrawColor) ; 
1291    }
1292
1293    /* Marker */
1294    if (MrkType != PI_NotDefMarker)
1295        mMarker = MrkType;
1296    if ((MrkType == PI_DotMarker) && (MarkerSize<3)) MarkerSize=3;
1297    if(MarkerSize != mMarkerSize || setFontDone) {
1298        mMarkerSize = MarkerSize ;
1299        fprintf(mPSFile, "/PIMarkers ff %d scf sf\n", 
1300                (int)(mMarkerSize*currentPage->FontScaleFactor)) ; 
1301        setFontDone = false ; 
1302    }
1303    /* Dessin */
1304    fprintf(mPSFile, "%.2f Ux %.2f Uy m (\\%#o) show\n", x0, y0, mMarker) ;
1305}
1306
1307/*
1308 * Pas d'options pour specifier la taille des Markers ?
1309 *
1310 */
1311void  PSFile::DrawMarkers (double *x0, double *y0, int n,
1312                           PIMarker MrkType,
1313                           PIColors DrawColor,
1314                           int MarkerSize) {
1315    /* Couleurs */
1316    if ( (DrawColor != PI_NotDefColor) || (DrawColor != mDrawColor) ) {
1317        mDrawColor = DrawColor;
1318        fprintf(mPSFile, "C%d ", mDrawColor) ; 
1319    }   
1320
1321    /* Marker */
1322    if (MrkType != PI_NotDefMarker)
1323        mMarker = MrkType;
1324
1325    if(MarkerSize != mMarkerSize || setFontDone) {
1326        mMarkerSize = MarkerSize ;
1327        fprintf(mPSFile, "/PIMarkers ff %d scf sf\n", 
1328                (int)(mMarkerSize*currentPage->FontScaleFactor)) ; 
1329        setFontDone = false ; 
1330    }
1331    /* Dessin */
1332    for(int i = 0; i<n; i++)
1333        fprintf(mPSFile, "%.2f Ux %.2f Uy m (\\%#o) show\n", x0[i], y0[i], mMarker) ; 
1334}
1335
1336void PSFile::Image(double x0, double y0, double Tx, double Ty,
1337                   int Nx, int Ny,
1338                   unsigned char *Pict, 
1339                   PIColorMap *mMap) {
1340
1341    int i, j;
1342
1343    /* Buffers PostScript */
1344    fprintf(mPSFile, "/Taille %d def\n", Nx);
1345    fprintf(mPSFile, "/ImStr Taille string def\n");
1346    fprintf(mPSFile, "/RGBStr Taille 3  mul string def\n");
1347
1348    /* Ecriture ColorMap */
1349    fprintf(mPSFile, "/ColorMap %02d array def\n", mMap->NCol() );
1350    for(i = 0; i < mMap->NCol(); i++) {
1351        fprintf(mPSFile, "ColorMap %d [16#%02X 16#%02X 16#%02X] put\n",
1352                i,
1353                (int)(mMap->GetColor(i).red/256),
1354                (int)(mMap->GetColor(i).green/256),
1355                (int)(mMap->GetColor(i).blue/256));
1356    }
1357    /* Emplacement de l'image */
1358    fprintf(mPSFile, "gs %.2f Ux %.2f Uy tr %.2f Ux %.2f Uy sc\n", x0, y0, Tx, Ty);
1359    /* Nbr pix-X, Nbr pix-Y bits/pixels */
1360    fprintf(mPSFile, "%d %d 8\n", Nx, Ny);
1361    /* Matrice de passage */
1362    fprintf(mPSFile, "[%d 0 0 %d 0 0]", Nx, Ny);
1363    /* Fonction colorimage */
1364    fprintf(mPSFile, "{currentfile ImStr readhexstring pop GetRGB}\
1365false 3 colorimage\n\n");
1366    /* Data */
1367    for(i = 0; i < Ny; i++) {
1368        for(j = 0; j<Nx-1; j++ )
1369            fprintf(mPSFile, "%02X", (int)Pict[i*Nx+j]);
1370    fprintf(mPSFile, "%02X\n", (int)Pict[i*Nx+j]);
1371    }
1372    /* Un petit grestore ...*/
1373    fprintf(mPSFile, "gr\n");
1374}
1375
1376void PSFile::Image(double x0, double y0, double Tx, double Ty,
1377                   int Nx, int Ny,
1378                   unsigned short *Pict, 
1379                   PIColorMap *mMap) {
1380
1381    int i, j;
1382
1383    /* Buffers PostScript */
1384    fprintf(mPSFile, "/Taille %d def\n", Nx);
1385    fprintf(mPSFile, "/ImStr Taille string def\n");
1386    fprintf(mPSFile, "/RGBStr Taille 3  mul string def\n");
1387
1388    /* Ecriture ColorMap */
1389    fprintf(mPSFile, "/ColorMap %05d array def\n", mMap->NCol() );
1390    for(i = 0; i < mMap->NCol(); i++) {
1391        fprintf(mPSFile, "ColorMap %d [16#%02X 16#%02X 16#%02X] put\n",
1392                i,
1393                (int)(mMap->GetColor(i).red/256),
1394                (int)(mMap->GetColor(i).green/256),
1395                (int)(mMap->GetColor(i).blue/256));
1396    }
1397    /* Emplacement de l'image */
1398    fprintf(mPSFile, "gs %.2f Ux %.2f Uy tr %.2f Ux %.2f Uy sc\n", x0, y0, Tx, Ty);
1399    /* Nbr pix-X, Nbr pix-Y bits/pixels */
1400    fprintf(mPSFile, "%d %d 16\n", Nx, Ny);
1401    /* Matrice de passage */
1402    fprintf(mPSFile, "[%d 0 0 %d 0 0]", Nx, Ny);
1403    /* Fonction colorimage */
1404    fprintf(mPSFile, "{currentfile ImStr readhexstring pop GetRGB}\
1405false 3 colorimage\n\n");
1406    /* Data */
1407    for(i = 0; i < Ny; i++) {
1408        for(j = 0; j<Nx-1; j++ )
1409            fprintf(mPSFile, "%04X", (int)Pict[i*Nx+j]);
1410    fprintf(mPSFile, "%04X\n", (int)Pict[i*Nx+j]);
1411    }
1412    /* Un petit grestore ...*/
1413    fprintf(mPSFile, "gr\n");
1414}
1415
1416
1417void  PSFile::SelectLine(PILineAtt att)
1418{
1419   
1420  //  if (att.GetLineWidth() != mLineAtt.GetLineWidth()) {
1421  double scaledLineWidth = att.GetLineWidthD()*currentPage->FontScaleFactor;
1422  fprintf(mPSFile, "%g slw ", scaledLineWidth) ;
1423  if (att.GetLineDash() != mLineAtt.GetLineDash()) {
1424      switch (att.GetLineDash()) {
1425        case PI_LineSolid :
1426          fprintf(mPSFile, "slsolid ");
1427          break;
1428        case PI_LineDashed :
1429          fprintf(mPSFile, "sldash ");
1430          break;
1431        case PI_LineDotted :
1432          fprintf(mPSFile, "sldott ");
1433          break;
1434        case PI_LineDashDotted :
1435          fprintf(mPSFile, "sldashdott ");
1436          break;
1437        default :
1438          fprintf(mPSFile, "slsolid ");
1439          break;
1440      }
1441  }
1442  if (att.GetLineJoin() != mLineAtt.GetLineJoin()) {
1443      switch (att.GetLineJoin()) {
1444        case PI_JoinMiter :
1445          fprintf(mPSFile, "0 sljoin ");
1446          break;
1447        case PI_JoinRound :
1448          fprintf(mPSFile, "1 sljoin ");
1449          break;
1450        case PI_JoinBevel :
1451          fprintf(mPSFile, "2 sljoin ");
1452          break;
1453        default :
1454          fprintf(mPSFile, "0 sljoin ");
1455          break;
1456      }
1457  }
1458  if (att.GetLineCap() != mLineAtt.GetLineCap()) {
1459      switch (att.GetLineCap()) {
1460        case PI_CapButt :
1461          fprintf(mPSFile, "0 slcap \n");
1462          break;
1463        case PI_CapRound :
1464          fprintf(mPSFile, "1 slcap \n");
1465          break;
1466        case PI_CapProjecting :
1467          fprintf(mPSFile, "2 slcap \n");
1468          break;
1469        default :
1470          fprintf(mPSFile, "0 slcap \n");         
1471          break;
1472      }
1473  }
1474      mLineAtt = att;
1475}
1476
1477/*
1478 *  Conversion
1479 *
1480 */
1481
1482double cm2pt(double x) {
1483    return (x*28.35);
1484}
1485
Note: See TracBrowser for help on using the repository browser.