~ubuntu-branches/ubuntu/utopic/tcm/utopic

« back to all changes in this revision

Viewing changes to src/ui/psgrafport.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2003-07-03 20:08:21 UTC
  • Revision ID: james.westby@ubuntu.com-20030703200821-se4xtqx25e5miczi
Tags: upstream-2.20
ImportĀ upstreamĀ versionĀ 2.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
////////////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
 
4
// (c) copyright 1995, Vrije Universiteit Amsterdam.
 
5
// Author: Frank Dehne (frank@cs.vu.nl).
 
6
//
 
7
// TCM is free software; you can redistribute it and/or modify
 
8
// it under the terms of the GNU General Public License as published by
 
9
// the Free Software Foundation; either version 2 of the License, or
 
10
// (at your option) any later version.
 
11
//
 
12
// TCM is distributed in the hope that it will be useful,
 
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
// GNU General Public License for more details.
 
16
//
 
17
// You should have received a copy of the GNU General Public License
 
18
// along with TCM; if not, write to the Free Software
 
19
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
20
// 02111-1307, USA.
 
21
////////////////////////////////////////////////////////////////////////////////
 
22
#include "psgrafport.h"
 
23
#include "application.h"
 
24
#include "system.h"
 
25
#include "color.h"
 
26
#include <ctype.h>
 
27
 
 
28
const char PSGrafport::BANNER[] = BANNER_FILE;
 
29
 
 
30
const double PSGrafport::DEFAULT_LINE_WIDTH = 0.750;
 
31
 
 
32
const double PSGrafport::XOFF = 12.90;
 
33
const double PSGrafport::YOFF = 9.50;
 
34
 
 
35
PSGrafport::PSGrafport(const char *fileName): Grafport() {
 
36
        if (equal(fileName, ""))
 
37
                fd = stdout;
 
38
        else
 
39
                fd = fopen(fileName, "w");
 
40
        succes = (fd != 0);
 
41
        isoLatin1Encoding = True;
 
42
        showColors = True;
 
43
        InitColors();
 
44
}
 
45
 
 
46
PSGrafport::~PSGrafport() {
 
47
        if (succes)
 
48
                fclose(fd);
 
49
}
 
50
 
 
51
void PSGrafport::SetBackgroundColor(const char *c) {
 
52
        string s = c;
 
53
        SetBackgroundColor(&s);
 
54
}
 
55
 
 
56
void PSGrafport::SetForegroundColor(const char *c) {
 
57
        string s = c;
 
58
        SetForegroundColor(&s);
 
59
}
 
60
 
 
61
void PSGrafport::SetBackgroundColor(const string *c) {
 
62
        if (*GetBackgroundColor() == *c)
 
63
                return;
 
64
        Grafport::SetBackgroundColor(c);
 
65
}
 
66
 
 
67
void PSGrafport::SetForegroundColor(const string *c) {
 
68
        if (*GetForegroundColor() == *c)
 
69
                return;
 
70
        Grafport::SetForegroundColor(c);
 
71
        if (!showColors)
 
72
                return;
 
73
        Color *color = LookupColor(c);
 
74
        if (color) {
 
75
                fprintf(fd, "%f %f %f setrgbcolor\n", 
 
76
                        color->red, color->green, color->blue);
 
77
                return;
 
78
        }
 
79
        else
 
80
                error("color %s not found\n", c->getstr());
 
81
}
 
82
 
 
83
void PSGrafport::Header(const char *title, const char *creator) {
 
84
        // PostScript Language Ref. Man. page 621
 
85
        char login[MAXNAME];
 
86
        char date[MAXNAME];
 
87
        System::GetLoginName(login);
 
88
        System::GetTime(date);
 
89
        fprintf(fd, "%%!PS-Adobe-1.0\n");
 
90
        fprintf(fd, "%%%%Title: %s\n", title);
 
91
        fprintf(fd, "%%%%Creator: %s\n", creator);
 
92
        fprintf(fd, "%%%%CreationDate: %s\n", date);
 
93
        fprintf(fd, "%%%%For: %s\n", login);
 
94
        fprintf(fd, "%%%%DocumentFonts: (atend)\n");
 
95
        fprintf(fd, "%%%%Pages: (atend)\n");
 
96
        fprintf(fd, "%%%%BoundingBox: (atend)\n");
 
97
        fprintf(fd, "%%%%EndComments\n");
 
98
        FontProlog();
 
99
        fprintf(fd, "%%%%EndProlog\n");
 
100
}
 
101
 
 
102
void PSGrafport::BeginDrawProc() {
 
103
        fprintf(fd, "/drawall {\n");
 
104
}
 
105
 
 
106
void PSGrafport::EndDrawProc() {
 
107
        fprintf(fd, "} def \n");
 
108
}
 
109
 
 
110
void PSGrafport::CallDrawProc() {
 
111
        fprintf(fd, "drawall\n");
 
112
}
 
113
 
 
114
void PSGrafport::Banner(const char *title) {
 
115
        FILE *bn;
 
116
        char bfile[MAXNAME];
 
117
        char toolkit_conf[MAXNAME];
 
118
        System::GetToolkitConfig(toolkit_conf);
 
119
        strcpy(bfile, toolkit_conf);
 
120
        strcat(bfile, BANNER);
 
121
        // Open file banner.ps
 
122
        bn = fopen(bfile, "r");
 
123
        if (bn == 0) {
 
124
                error("Warning: could not open %s\n", bfile);
 
125
                return;
 
126
        }
 
127
        // Copy banner.ps
 
128
        int c;
 
129
        while ((c = getc(bn)) != EOF)
 
130
                putc(c, fd);
 
131
        // Close file banner.ps
 
132
        fclose(bn);
 
133
        char host[MAXNAME];
 
134
        char login[MAXNAME];
 
135
        char time[MAXNAME];
 
136
        System::GetHostName(host);
 
137
        System::GetLoginName(login);
 
138
        System::GetTime(time);
 
139
        // Write sline
 
140
        fprintf(fd, "(%s:%s Job: %s Date: %s)LS\n", host, login, title, time);
 
141
}
 
142
 
 
143
void PSGrafport::EPSHeader(const char *title, const char *creator, 
 
144
                double llx, double lly, double urx, double ury) {
 
145
        // PostScript Language Ref. Man. page 712
 
146
        char login[MAXNAME];
 
147
        char date[MAXNAME];
 
148
        System::GetLoginName(login);
 
149
        System::GetTime(date);
 
150
        fprintf(fd, "%%!PS-Adobe-3.0 EPSF-3.0\n");
 
151
        fprintf(fd, "%%%%Title: %s\n", title);
 
152
        fprintf(fd, "%%%%Creator: %s\n", creator);
 
153
        fprintf(fd, "%%%%CreationDate: %s\n", date);
 
154
        fprintf(fd, "%%%%For: %s\n", login);
 
155
        fprintf(fd, "%%%%DocumentFonts: (atend)\n");
 
156
        fprintf(fd, "%%%%Pages: 0\n");
 
157
        llx = llx * factor;
 
158
        lly = lly * factor;
 
159
        urx = urx * factor;
 
160
        ury = ury * factor;
 
161
        fprintf(fd, "%%%%BoundingBox: %f %f %f %f\n", llx, lly, urx, ury);
 
162
        fprintf(fd, "%%%%EndComments\n");
 
163
}
 
164
 
 
165
void PSGrafport::PageSetup() {
 
166
        // default transformation
 
167
        // move to imagable area
 
168
        fprintf(fd, "%f %f translate\n", XOFF, YOFF);
 
169
        // factor between pixel size and point size
 
170
        fprintf(fd, "%f %f scale\n", factor, factor);
 
171
        if (width < height)  {
 
172
                // Portrait mode: change to X coordinate system
 
173
                fprintf(fd, "0 %f translate\n", height);
 
174
                fprintf(fd, "1 -1 scale\n");
 
175
        }
 
176
        else {
 
177
                // Landscape mode: change to X coordinate system
 
178
                fprintf(fd, "90 rotate\n");
 
179
                fprintf(fd, "1 -1 scale\n");
 
180
        }
 
181
        fprintf(fd, "%f setlinewidth\n", GetLineWidth() * DEFAULT_LINE_WIDTH);
 
182
}
 
183
 
 
184
void PSGrafport::EPSProlog(double lly, double dy) {
 
185
        FontProlog();
 
186
        // default transformation
 
187
        // factor between pixel size and point size
 
188
        fprintf(fd, "%f %f scale\n", factor, factor);
 
189
        lly *= factor;
 
190
        dy *= factor;
 
191
        // change to X coordinate system
 
192
        // look at how EPSF files are used in Ref. Man. page 712
 
193
        fprintf(fd, "0 %f 2 mul %f add %f div translate\n", lly, dy, factor);
 
194
        fprintf(fd, "1 -1 scale\n");
 
195
        fprintf(fd, "%f %f scale\n", GetZoomValue(), GetZoomValue());
 
196
        fprintf(fd, "%f setlinewidth\n", GetLineWidth() * DEFAULT_LINE_WIDTH);
 
197
        fprintf(fd, "%%%%EndProlog\n");
 
198
}
 
199
 
 
200
void PSGrafport::SetLineWidth(unsigned int w) {
 
201
        if (w == GetLineWidth())
 
202
                return;
 
203
        Grafport::SetLineWidth(w);
 
204
        fprintf(fd, "%f setlinewidth\n", GetLineWidth() * DEFAULT_LINE_WIDTH);
 
205
}
 
206
 
 
207
void PSGrafport::SetFont(XFont *f) {
 
208
        Grafport::SetFont(f);
 
209
        char fname[MAXNAME];
 
210
        GetFont()->GetPostScript(fname);
 
211
        if (isoLatin1Encoding && !equal(fname, "/Symbol")) {
 
212
                if (!definedFonts.contains(fname)) {
 
213
                        InstallIsoLatin1Font(fname);
 
214
                        definedFonts.add(fname);
 
215
                }
 
216
                strcat(fname, "-ISOLatin1Encoding");
 
217
        }
 
218
        fprintf(fd, "%s findfont\n", fname);
 
219
        fprintf(fd, "%d scalefont setfont\n", (int) f->GetSize());
 
220
}
 
221
 
 
222
void PSGrafport::BeginPage(int i, int j, int nx, int tot) {
 
223
        fprintf(fd, "%%%%Page: %d %d\n", i+nx*(j-1), tot);
 
224
        // default transformation
 
225
        PageSetup();
 
226
        fprintf(fd, "%%%%BeginPageSetup\n");
 
227
        double dx = (i-1) * width;
 
228
        double dy = (j-1) * height;
 
229
        fprintf(fd, "gsave\n");
 
230
        fprintf(fd, "-%f -%f translate\n", dx, dy);
 
231
        fprintf(fd, "%f %f scale\n", GetZoomValue(), GetZoomValue());
 
232
        fprintf(fd, "%%%%EndPageSetup\n");
 
233
}
 
234
 
 
235
void PSGrafport::EndPage() {
 
236
        fprintf(fd, "grestore\n");
 
237
        fprintf(fd, "showpage\n");
 
238
        fprintf(fd, "%%%%PageTrailer\n");
 
239
}
 
240
 
 
241
void PSGrafport::Trailer() {
 
242
        fprintf(fd, "%%%%Trailer\n");
 
243
        fprintf(fd, "%%%%EOF\n");
 
244
}
 
245
 
 
246
void PSGrafport::DrawRectangle(double x, double y, double wd, double ht) {
 
247
        if (GetLineStyle()==LineStyle::INVISIBLE &&
 
248
            GetFillStyle()==FillStyle::UNFILLED)
 
249
                return;
 
250
        SetPSDashes();
 
251
        DrawPSRectangle(x, y, wd, ht);
 
252
        if (GetLineStyle()==LineStyle::DUAL) {
 
253
                int n = 2*GetLineWidth();
 
254
                if (ht > 2*n && wd > 2*n)
 
255
                        DrawPSRectangle(x+n, y+n, wd-2*n, ht-2*n);
 
256
        }
 
257
        UnsetPSDashes();
 
258
}
 
259
 
 
260
void PSGrafport::DrawPSRectangle(double x, double y, double wd, double ht) {
 
261
        fprintf(fd, "newpath\n");
 
262
        fprintf(fd, "   %f %f moveto\n", x, y);
 
263
        fprintf(fd, "   %f 0  rlineto\n", wd);
 
264
        fprintf(fd, "   0 %f  rlineto\n", ht);
 
265
        fprintf(fd, "   -%f 0 rlineto\n", wd);
 
266
        fprintf(fd, "   closepath\n");
 
267
        if (GetFillStyle()==FillStyle::UNFILLED || 
 
268
            (!showColors && *GetForegroundColor() != "black"))
 
269
                fprintf(fd, "   stroke\n");
 
270
        else
 
271
                fprintf(fd, "   fill\n");
 
272
}
 
273
 
 
274
void PSGrafport::DrawUnzoomedRectangle(double x, double y, double wd, double ht) {
 
275
        fprintf(fd, "gsave\n");
 
276
        fprintf(fd, "%f %f scale\n", 1/GetZoomValue(), 1/GetZoomValue());
 
277
        DrawRectangle(x, y, wd, ht);
 
278
        fprintf(fd, "grestore\n");
 
279
}
 
280
 
 
281
void PSGrafport::FillRectangle(double x, double y, double wd, double ht) {
 
282
        SetFillStyle(FillStyle::FILLED);
 
283
        DrawRectangle(x, y, wd, ht);
 
284
        SetFillStyle(FillStyle::UNFILLED);
 
285
}
 
286
 
 
287
//void PSGrafport::DrawRoundedRectangle(double x, double y, double wd, double ht, double rd) {
 
288
//      if (GetLineStyle()==LineStyle::INVISIBLE &&
 
289
//            GetFillStyle()==FillStyle::UNFILLED)
 
290
//                return;
 
291
//      SetPSDashes();
 
292
//      DrawPSRoundedRectangle(x, y, wd, ht, rd);
 
293
//      if (GetLineStyle()==LineStyle::DUAL) {
 
294
//              int n = 2*GetLineWidth();
 
295
//              if (ht > 2*n && wd > 2*n)
 
296
//                      DrawPSRoundedRectangle(x+n, y+n, wd-2*n, ht-2*n, rd);
 
297
//      }
 
298
//      UnsetPSDashes();
 
299
//}
 
300
//
 
301
//void PSGrafport::DrawPSRoundedRectangle(double x, double y, double wd, double ht, double rd) {
 
302
//      // draw four lines (without the corner parts).
 
303
//      DrawPSLine(x, y+rd, x, y+ht-rd);
 
304
//      DrawPSLine(x+rd, y+ht, x+wd-rd, y+ht);
 
305
//      DrawPSLine(x+wd, y+ht-rd, x+wd, y+rd);
 
306
//      DrawPSLine(x+wd-rd, y, x+rd, y);
 
307
//      // draw four corner arcs.
 
308
//      fprintf(fd, "newpath\n");
 
309
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+rd, y+rd, rd, 180, 270); 
 
310
//      fprintf(fd, "    stroke\n");
 
311
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+rd, y+ht-rd, rd, 90, 180); 
 
312
//      fprintf(fd, "    stroke\n");
 
313
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+wd-rd, y+ht-rd, rd, 0, 90); 
 
314
//      fprintf(fd, "    stroke\n");
 
315
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+wd-rd, y+rd, rd, 270, 360); 
 
316
//      fprintf(fd, "    stroke\n");
 
317
//}
 
318
//
 
319
//void PSGrafport::FillRoundedRectangle(double x, double y, double wd, double ht, double rd) {
 
320
//      if (!showColors && !(*GetForegroundColor() == "black")) {
 
321
//              DrawRoundedRectangle(x, y, wd, ht, rd);
 
322
//              return;
 
323
//      }
 
324
//      FillRectangle(x+rd, y, wd-2*rd, rd);
 
325
//      FillRectangle(x, y+rd, wd, ht-2*rd);
 
326
//      FillRectangle(x+rd, y+ht-rd, wd-2*rd, rd);
 
327
//      fprintf(fd, "newpath\n");
 
328
//      fprintf(fd, "    %f %f moveto\n", x+rd, y+rd);
 
329
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+rd, y+rd, rd, 180, 270); 
 
330
//      fprintf(fd, "    %f %f moveto\n", x+rd, y+ht-rd);
 
331
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+rd, y+ht-rd, rd, 90, 180); 
 
332
//      fprintf(fd, "    %f %f moveto\n", x+wd-rd, y+ht-rd);
 
333
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+wd-rd, y+ht-rd, rd, 0, 90); 
 
334
//      fprintf(fd, "    %f %f moveto\n", x+wd-rd, y+rd);
 
335
//      fprintf(fd, "    %f %f %f %d %d arc\n", x+wd-rd, y+rd, rd, 270, 360); 
 
336
//      fprintf(fd, "    fill\n");
 
337
//}
 
338
//
 
339
//void PSGrafport::DrawEllipsedRectangle(double x, double y, double wd, double ht, double rd) {
 
340
//      if (GetLineStyle()==LineStyle::INVISIBLE &&
 
341
//            GetFillStyle()==FillStyle::UNFILLED)
 
342
//                return;
 
343
//      SetPSDashes();
 
344
//        DrawPSEllipsedRectangle(x, y, wd, ht, rd);
 
345
//        if (GetLineStyle()==LineStyle::DUAL) {
 
346
//                int n = 2*GetLineWidth();
 
347
//              if (ht > 2*n && wd > 2*n)
 
348
//                      DrawPSEllipsedRectangle(x+n, y+n, wd-2*n, ht-2*n, rd-n);
 
349
//        }
 
350
//      UnsetPSDashes();
 
351
//}
 
352
// 
 
353
//void PSGrafport::DrawPSEllipsedRectangle(double x, double y, double wd, double ht, double rd) {
 
354
//        // draw two lines (without the corner parts).
 
355
//        DrawPSLine(x+rd, y, x+wd-rd, y);
 
356
//        DrawPSLine(x+rd, y+ht, x+wd-rd, y+ht);
 
357
//        // draw two half circles.
 
358
//        fprintf(fd, "newpath\n");
 
359
//        fprintf(fd, "    %f %f %f %d %d arc\n", x+rd, y+rd, rd, 90, 270);
 
360
//        fprintf(fd, "    stroke\n");
 
361
//        fprintf(fd, "    %f %f %f %d %d arc\n", x+wd-rd, y+rd, rd, 270, 90);
 
362
//        fprintf(fd, "    stroke\n");
 
363
//}
 
364
// 
 
365
//void PSGrafport::FillEllipsedRectangle(double x, double y, double wd, double ht, double rd) {
 
366
//        if (!showColors && !(*GetForegroundColor() == "black")) {
 
367
//                DrawEllipsedRectangle(x, y, wd, ht, rd);
 
368
//                return;
 
369
//        }
 
370
//        FillRectangle(x+rd, y, wd-2*rd, ht);
 
371
//        fprintf(fd, "newpath\n");
 
372
//        fprintf(fd, "    %f %f moveto\n", x+rd, y+rd);
 
373
//        fprintf(fd, "    %f %f %f %d %d arc\n", x+rd, y+rd, rd, 90, 270);
 
374
//        fprintf(fd, "    %f %f moveto\n", x+wd-rd, y+rd);
 
375
//        fprintf(fd, "    %f %f %f %d %d arc\n", x+wd-rd, y+rd, rd, 270, 90);
 
376
//        fprintf(fd, "    fill\n");
 
377
//}
 
378
// 
 
379
//void PSGrafport::DrawDisk(double x, double y, double wd, double ht, double rd) {
 
380
//      if (GetLineStyle()==LineStyle::INVISIBLE &&
 
381
//            GetFillStyle()==FillStyle::UNFILLED)
 
382
//                return;
 
383
//      SetPSDashes();
 
384
//        DrawPSDisk(x, y, wd, ht, rd);
 
385
//        if (GetLineStyle()==LineStyle::DUAL) {
 
386
//                int n = 2*GetLineWidth();
 
387
//              if (ht > 2*n && wd > 2*n)
 
388
//                      DrawPSDisk(x+n, y+n, wd-2*n, ht-2*n, rd-2*n);
 
389
//        }
 
390
//      UnsetPSDashes();
 
391
//}
 
392
// 
 
393
//void PSGrafport::FillDisk(double x, double y, double wd, double ht, double el) {
 
394
//      SetFillStyle(FillStyle::FILLED);
 
395
//      DrawDisk(x, y, wd, ht, el);
 
396
//      FillRectangle(x, y+el/2, wd, ht-el);
 
397
//      SetFillStyle(FillStyle::UNFILLED);
 
398
//}
 
399
// 
 
400
//void PSGrafport::DrawPSDisk(double x, double y, double wd, double ht, double el) {
 
401
//        LineStyle::Type save = GetLineStyle();
 
402
//        if (save==LineStyle::DUAL)
 
403
//                SetLineStyle(LineStyle::SOLID);
 
404
//        // draw two lines (without the corner points).
 
405
//      double ah = el/2;
 
406
//        DrawPSLine(x, y+ah+1, x, y+ht-ah-1);
 
407
//        DrawPSLine(x+wd, y+ah+1, x+wd, y+ht-ah-1);
 
408
//        if (save==LineStyle::DUAL)
 
409
//                SetLineStyle(LineStyle::DUAL);
 
410
//        // draw 1st ellipse.
 
411
//      DrawPSArc(x, y, wd, el, 0, 360);
 
412
//      // draw half ellipse
 
413
//      DrawPSArc(x, y+ht-el, wd, el, 0, -180);
 
414
//}
 
415
 
 
416
void PSGrafport::DrawStringLeft(double x, double y, const char *str) {
 
417
        string copy = str;
 
418
        MakePSString(&copy);
 
419
        const char *newstr = copy.getstr();
 
420
        fprintf(fd, "%f %f moveto\n", x, y);
 
421
        fprintf(fd, "gsave\n");
 
422
        fprintf(fd, "1 -1 scale\n");
 
423
        fprintf(fd, "(%s) show\n", newstr);
 
424
        fprintf(fd, "grestore\n");
 
425
}
 
426
 
 
427
void PSGrafport::DrawUnzoomedStringLeft(double x, double y, const char *str) {
 
428
        fprintf(fd, "gsave\n");
 
429
        fprintf(fd, "%f %f scale\n", 1/GetZoomValue(), 1/GetZoomValue());
 
430
        DrawStringLeft(x, y, str);
 
431
        fprintf(fd, "grestore\n");
 
432
}
 
433
 
 
434
void PSGrafport::DrawStringRight(double x, double y, const char *str){
 
435
        string copy = str;
 
436
        MakePSString(&copy);
 
437
        const char *newstr = copy.getstr();
 
438
        fprintf(fd, "(%s) stringwidth\n", newstr);
 
439
        fprintf(fd, "pop neg\n");
 
440
        fprintf(fd, "%f add %f moveto\n", x, y);
 
441
        fprintf(fd, "gsave\n");
 
442
        fprintf(fd, "1 -1 scale\n");
 
443
        fprintf(fd, "(%s) show\n", newstr);
 
444
        fprintf(fd, "grestore\n");
 
445
}
 
446
 
 
447
void PSGrafport::DrawStringCentered(double x, double y, const char *str) {
 
448
        string copy = str;
 
449
        MakePSString(&copy);
 
450
        const char *newstr = copy.getstr();
 
451
        double dy = GetFont()->GetHeight() / 2 - GetFont()->GetDescent();
 
452
        fprintf(fd, "(%s) stringwidth\n", newstr);
 
453
        fprintf(fd, "pop 2 div neg\n");
 
454
        fprintf(fd, "%f add %f moveto\n", x, y + dy);
 
455
        fprintf(fd, "gsave\n");
 
456
        fprintf(fd, "1 -1 scale\n");
 
457
        fprintf(fd, "(%s) show\n", newstr);
 
458
        fprintf(fd, "grestore\n");
 
459
}
 
460
 
 
461
 
 
462
//Underlined Strings
 
463
void PSGrafport::DrawStringLeftUnderlined(double x, double y, const char *str){
 
464
        DrawStringLeft(x, y, str);
 
465
        int wd = GetFont()->StringWidth(str);
 
466
        // DrawStringLeft... : Corrected Height for y ( == topLefty + GetAscent()) 
 
467
        int cht = GetFont()->GetHeight() - GetFont()->GetAscent();
 
468
        DrawPSLine(x, y + cht, x + wd, y + cht);
 
469
}
 
470
 
 
471
void PSGrafport::DrawStringRightUnderlined(double x, double y, const char *str){
 
472
        DrawStringRight(x, y, str);
 
473
        int wd = GetFont()->StringWidth(str);
 
474
        // DrawStringRight... : Corrected Height for y ( == topRighty + GetAscent()) 
 
475
        int cht = GetFont()->GetHeight() - GetFont()->GetAscent();
 
476
        DrawPSLine(x - wd, y + cht, x, y + cht);
 
477
}
 
478
 
 
479
void PSGrafport::DrawStringCenteredUnderlined(double x, double y, const char *str) {
 
480
        DrawStringCentered(x, y, str);
 
481
        int wd = GetFont()->StringWidth(str);
 
482
        int ht = GetFont()->GetHeight();
 
483
        DrawPSLine(x - wd/2, y + ht/2, x + wd/2, y + ht/2);
 
484
}
 
485
 
 
486
void PSGrafport::MakePSString(string *str) {
 
487
        FixEscapeChar(str, '\\');
 
488
        FixEscapeChar(str, '(');
 
489
        FixEscapeChar(str, ')');
 
490
        FixEscapeChar(str, '*');
 
491
        FixNonAscii(str);
 
492
}
 
493
 
 
494
void PSGrafport::DrawUnzoomedStringCentered(double x, double y, const char *str) {
 
495
        fprintf(fd, "gsave\n");
 
496
        fprintf(fd, "%f %f scale\n", 1/GetZoomValue(), 1/GetZoomValue());
 
497
        DrawStringCentered(x, y, str);
 
498
        fprintf(fd, "grestore\n");
 
499
}
 
500
 
 
501
//void PSGrafport::DrawLine(double x1, double y1, double x2, double y2) {
 
502
//      if (x1 == x2 && y1 == y2)
 
503
//              return;
 
504
//      if (GetLineStyle()==LineStyle::INVISIBLE)
 
505
//              return;
 
506
//      else if (GetLineStyle()==LineStyle::DASHED)
 
507
//              fprintf(fd, "[4 2] 0 setdash\n");
 
508
//      else if (GetLineStyle()==LineStyle::DOTTED) 
 
509
//              fprintf(fd, "[1 1] 0 setdash\n");
 
510
//      else if (GetLineStyle()==LineStyle::WIDE_DOTTED)
 
511
//              fprintf(fd, "[2 2] 0 setdash\n");
 
512
//      if (GetLineStyle()==LineStyle::DUAL) {
 
513
//              int n = GetLineWidth();
 
514
//              if (y1 == y2) {  // horizontal
 
515
//                      DrawPSLine(x1, y1+n, x2, y2+n);
 
516
//                      DrawPSLine(x1, y1-n, x2, y2-n);
 
517
//              }
 
518
//              else if (x1 == x2) {  // vertical
 
519
//                      DrawPSLine(x1+n, y1, x2+n, y2);
 
520
//                      DrawPSLine(x1-n, y1, x2-n, y2);
 
521
//              }
 
522
//              else {
 
523
//                      DrawPSLine(x1, y1, x2, y2);
 
524
//                      DrawPSLine(x1, y1+2*n, x2, y2+2*n);
 
525
//              }
 
526
//      }
 
527
//      else
 
528
//              DrawPSLine(x1, y1, x2, y2);
 
529
//      UnsetPSDashes();
 
530
//}
 
531
 
 
532
void PSGrafport::DrawPSLine(double x1, double y1, double x2, double y2) {
 
533
        fprintf(fd, "newpath\n");
 
534
        fprintf(fd, "    %f %f moveto\n", x1, y1);
 
535
        fprintf(fd, "    %f %f lineto\n", x2, y2);
 
536
        fprintf(fd, "    stroke\n");
 
537
}
 
538
 
 
539
void PSGrafport::DrawUnzoomedLine(double x1, double y1, double x2, double y2) {
 
540
        fprintf(fd, "gsave\n");
 
541
        fprintf(fd, "%f %f scale\n", 1/GetZoomValue(), 1/GetZoomValue());
 
542
        DrawLine(x1, y1, x2, y2);
 
543
        fprintf(fd, "grestore\n");
 
544
}
 
545
 
 
546
 
 
547
//void PSGrafport::DrawCurve(const Point *p0, const Point *p1, 
 
548
//                         const Point *p2, const Point *p3) {
 
549
//      if (GetLineStyle()==LineStyle::INVISIBLE)
 
550
//              return;
 
551
//      if (GetLineStyle()==LineStyle::DASHED)
 
552
//              fprintf(fd, "[4 2] 0 setdash\n");
 
553
//      if (GetLineStyle()==LineStyle::DOTTED)
 
554
//              fprintf(fd, "[1 1] 0 setdash\n");
 
555
//      if (GetLineStyle()==LineStyle::WIDE_DOTTED)
 
556
//              fprintf(fd, "[2 2] 0 setdash\n");
 
557
//      fprintf(fd, "newpath\n");
 
558
//      fprintf(fd, "    %d %d moveto\n", p0->x, p0->y);
 
559
//      fprintf(fd, "    %d %d %d %d %d %d curveto\n", p1->x, p1->y,
 
560
//              p2->x, p2->y, p3->x, p3->y);
 
561
//      fprintf(fd, "    stroke\n");
 
562
//      UnsetPSDashes();
 
563
//}
 
564
 
 
565
 
 
566
void PSGrafport::DrawSimpleCurve(const DPoint *p) {
 
567
        if (GetLineStyle()==LineStyle::INVISIBLE)
 
568
                return;
 
569
        if (GetLineStyle()==LineStyle::DASHED)
 
570
                fprintf(fd, "[4 2] 0 setdash\n");
 
571
        if (GetLineStyle()==LineStyle::DOTTED)
 
572
                fprintf(fd, "[1 1] 0 setdash\n");
 
573
        if (GetLineStyle()==LineStyle::WIDE_DOTTED)
 
574
                fprintf(fd, "[2 2] 0 setdash\n");
 
575
        fprintf(fd, "newpath\n");
 
576
        fprintf(fd, "    %f %f moveto\n", p[0].x, p[0].y);
 
577
        fprintf(fd, "    %f %f %f %f %f %f curveto\n", p[1].x, p[1].y,
 
578
                p[2].x, p[2].y, p[3].x, p[3].y);
 
579
        fprintf(fd, "    stroke\n");
 
580
        UnsetPSDashes();
 
581
}
 
582
 
 
583
 
 
584
void PSGrafport::DrawPoint(double x, double y) {
 
585
        DrawLine(x, y, x, y);
 
586
}
 
587
 
 
588
void PSGrafport::DrawEllipse(double x, double y, double wd, double ht) {
 
589
        DrawArc(x, y, wd, ht, 0, 360);
 
590
}
 
591
 
 
592
void PSGrafport::FillEllipse(double x, double y, double wd, double ht) {
 
593
        FillSegment(x, y, wd, ht, 0, 360);
 
594
}
 
595
 
 
596
/* virtual */ void PSGrafport::DrawSimpleArc(double x, double y,
 
597
        double wd, double ht, int arc1, int arc2)
 
598
{
 
599
        if (GetLineStyle()==LineStyle::INVISIBLE &&
 
600
            GetFillStyle()==FillStyle::UNFILLED)
 
601
                return;
 
602
        SetPSDashes();
 
603
        fprintf(fd, "/savematrix matrix currentmatrix def\n");
 
604
        fprintf(fd, "gsave\n");
 
605
        fprintf(fd, "%f %f translate\n", x, y);
 
606
        fprintf(fd, "%f %f scale\n", wd, ht);
 
607
        fprintf(fd, "newpath\n");
 
608
        fprintf(fd, "    0.5 0.5 0.5 %d %d arc\n", 359 - arc2, 361 - arc1);
 
609
        // draw a little bit more to avoid hiati in arcs.
 
610
        // fprintf(fd, "    closepath\n");
 
611
        fprintf(fd, "savematrix setmatrix\n");
 
612
        fprintf(fd, "    stroke\n");
 
613
        fprintf(fd, "grestore\n");
 
614
        UnsetPSDashes();
 
615
}
 
616
 
 
617
 
 
618
/* virtual */ void PSGrafport::FillSegment(double x, double y,
 
619
        double wd, double ht, int arc1, int arc2)
 
620
{
 
621
        SetPSDashes();
 
622
        fprintf(fd, "/savematrix matrix currentmatrix def\n");
 
623
        fprintf(fd, "gsave\n");
 
624
        fprintf(fd, "%f %f translate\n", x, y);
 
625
        fprintf(fd, "%f %f scale\n", wd, ht);
 
626
        fprintf(fd, "newpath\n");
 
627
        fprintf(fd, "    0.5 0.5 0.5 %d %d arc\n", 360 - arc2, 360 - arc1);
 
628
        // fprintf(fd, "    closepath\n");
 
629
        fprintf(fd, "savematrix setmatrix\n");
 
630
        if ( ! showColors && *GetForegroundColor() != "black" )
 
631
                fprintf(fd, "    stroke\n");
 
632
        else
 
633
                fprintf(fd, "    fill\n");
 
634
        fprintf(fd, "grestore\n");
 
635
        UnsetPSDashes();
 
636
}
 
637
 
 
638
 
 
639
//void PSGrafport::FillArc(double x, double y, double wd, double ht, int arc1, int arc2) {
 
640
//      SetFillStyle(FillStyle::FILLED);
 
641
//      DrawArc(x, y, wd, ht, arc1, arc2);
 
642
//      SetFillStyle(FillStyle::UNFILLED);
 
643
//}
 
644
//
 
645
//void PSGrafport::DrawPSArc(double x, double y, double wd, double ht, int ang1, int ang2) {
 
646
//      fprintf(fd, "/savematrix matrix currentmatrix def\n");
 
647
//      fprintf(fd, "gsave\n");
 
648
//      fprintf(fd, "%f %f translate\n", x, y);
 
649
//      fprintf(fd, "%f %f scale\n", wd, ht);
 
650
//      fprintf(fd, "newpath\n");
 
651
//      fprintf(fd, "    0.5 0.5 0.5 %d %d arc\n", ang1, ang2);
 
652
//      // fprintf(fd, "    closepath\n");
 
653
//      fprintf(fd, "savematrix setmatrix\n");
 
654
//      if (GetFillStyle()==FillStyle::UNFILLED ||
 
655
//            (!showColors && *GetForegroundColor()!="black"))
 
656
//              fprintf(fd, "    stroke\n");
 
657
//      else
 
658
//              fprintf(fd, "    fill\n");
 
659
//      fprintf(fd, "grestore\n");
 
660
//}
 
661
 
 
662
 
 
663
void PSGrafport::DrawPolygon(const Point *points, int n) {
 
664
        if (GetLineStyle()==LineStyle::INVISIBLE &&
 
665
            GetFillStyle()==FillStyle::UNFILLED)
 
666
                return;
 
667
        SetPSDashes();
 
668
        DrawPSPolygon(points, n);
 
669
        if (GetLineStyle()==LineStyle::DUAL) {
 
670
                int w = 2*GetLineWidth();
 
671
                Point *newPoints = new Point[n];
 
672
                RecalcPolygon(points, n, newPoints, w);
 
673
                DrawPSPolygon(newPoints, n);
 
674
                delete newPoints;
 
675
        }
 
676
        UnsetPSDashes();
 
677
}
 
678
 
 
679
 
 
680
void PSGrafport::DrawPSPolygon(const Point *points, int n) {
 
681
        if (n < 1) 
 
682
                return;
 
683
        fprintf(fd, "newpath\n");
 
684
        fprintf(fd, "    %d %d moveto\n", points[0].x, points[0].y);
 
685
        for (int i=1; i<n; i++) {
 
686
                fprintf(fd, "    %d %d lineto\n", points[i].x, points[i].y);
 
687
        }
 
688
        fprintf(fd, "    %d %d lineto\n", points[0].x, points[0].y);
 
689
        fprintf(fd, "    closepath\n");
 
690
        if (GetFillStyle()==FillStyle::UNFILLED ||
 
691
            (!showColors && *GetForegroundColor()!="black"))
 
692
                fprintf(fd, "    stroke\n");
 
693
        else
 
694
                fprintf(fd, "    fill\n");
 
695
}
 
696
 
 
697
 
 
698
/* virtual */ void PSGrafport::DrawSimplePolygon(const DPoint *points,
 
699
        int n)
 
700
{
 
701
        if (GetLineStyle()==LineStyle::INVISIBLE || n < 2)
 
702
                return;
 
703
        SetPSDashes();
 
704
        if (n < 2)
 
705
                return;
 
706
        fprintf(fd, "newpath\n");
 
707
        fprintf(fd, "    %f %f moveto\n", points[0].x, points[0].y);
 
708
        bool closed = False;
 
709
        if ( points[0] == points[n - 1] ) {
 
710
                n--;
 
711
                closed = True;
 
712
        }
 
713
        for ( int i=1 ; i<n ; i++ )
 
714
                fprintf(fd, "    %f %f lineto\n", points[i].x, points[i].y);
 
715
        if ( closed )
 
716
                fprintf(fd, "    closepath\n");
 
717
        fprintf(fd, "    stroke\n");
 
718
        UnsetPSDashes();
 
719
}
 
720
 
 
721
 
 
722
void PSGrafport::FillPolygon(const Point *points, int n) {
 
723
        SetFillStyle(FillStyle::FILLED);
 
724
        DrawPolygon(points, n);
 
725
        SetFillStyle(FillStyle::UNFILLED);
 
726
}
 
727
 
 
728
 
 
729
void PSGrafport::FillPolygon(const DPoint *points, int n) {
 
730
        if (n < 2)
 
731
                return;
 
732
        fprintf(fd, "newpath\n");
 
733
        fprintf(fd, "    %f %f moveto\n", points[0].x, points[0].y);
 
734
        for ( int i=1 ; i<n ; i++ )
 
735
                fprintf(fd, "    %f %f lineto\n", points[i].x, points[i].y);
 
736
        fprintf(fd, "    closepath\n");
 
737
        fprintf(fd, "    fill\n");
 
738
}
 
739
 
 
740
 
 
741
void PSGrafport::FixEscapeChar(string *str, char c) {
 
742
        string pat = c;
 
743
        string repl = "\\" + pat;
 
744
        str->replace(pat, repl);
 
745
}
 
746
 
 
747
 
 
748
void PSGrafport::FixNonAscii(string *str) {
 
749
        char buf[8];
 
750
        string newstr;
 
751
        for (unsigned i=0; i<str->length(); i++) {
 
752
                unsigned char c = (*str)[i];
 
753
                if (!isascii(c)) {
 
754
                        sprintf(buf, "\\%o", c);
 
755
                        newstr += buf;
 
756
                }
 
757
                else
 
758
                        newstr.add(c);
 
759
        }
 
760
        *str = newstr;
 
761
}
 
762
 
 
763
void PSGrafport::FontProlog() {
 
764
        if (!isoLatin1Encoding)
 
765
                return;
 
766
        fprintf(fd, "/ISOLatin1Encoding[\n");
 
767
        fprintf(fd, "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n");
 
768
        fprintf(fd, "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n");
 
769
        fprintf(fd, "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n");
 
770
        fprintf(fd, "/.notdef/.notdef/.notdef/.notdef/.notdef/space/exclam/quotedbl/numbersign\n");
 
771
        fprintf(fd, "/dollar/percent/ampersand/quoteright/parenleft/parenright/asterisk/plus/comma\n");
 
772
        fprintf(fd, "/minus/period/slash/zero/one/two/three/four/five/six/seven/eight/nine/colon\n");
 
773
        fprintf(fd, "/semicolon/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S\n");
 
774
        fprintf(fd, "/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright/asciicircum/underscore\n");
 
775
        fprintf(fd, "/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar\n");
 
776
        fprintf(fd, "/braceright/asciitilde/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef\n");
 
777
        fprintf(fd, "/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/space\n");
 
778
        fprintf(fd, "/dotlessi/grave/acute/circumflex/tilde/macron/breve/dotaccent/dieresis/.notdef\n");
 
779
        fprintf(fd, "/ring/cedilla/.notdef/hungarumlaut/ogonek/caron/.notdef/exclamdown/cent\n");
 
780
        fprintf(fd, "/sterling/currency/yen/brokenbar/section/dieresis/copyright/ordfeminine\n");
 
781
        fprintf(fd, "/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior\n");
 
782
        fprintf(fd, "/threesuperior/acute/mu/paragraph/periodcentered/cedilla/onesuperior\n");
 
783
        fprintf(fd, "/ordmasculine/guillemotright/onequarter/onehalf/threequarters/questiondown\n");
 
784
        fprintf(fd, "/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute\n");
 
785
        fprintf(fd, "/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/Ograve\n");
 
786
        fprintf(fd, "/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/Ugrave/Uacute/Ucircumflex\n");
 
787
        fprintf(fd, "/Udieresis/Yacute/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis\n");
 
788
        fprintf(fd, "/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave/iacute\n");
 
789
        fprintf(fd, "/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odieresis\n");
 
790
        fprintf(fd, "/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacute/thorn/ydieresis\n");
 
791
        fprintf(fd, "] def\n");
 
792
}
 
793
 
 
794
void PSGrafport::InstallIsoLatin1Font(const char *psFont) {
 
795
        fprintf(fd, "%s findfont\n", psFont);
 
796
        fprintf(fd, "dup length dict begin\n");
 
797
        fprintf(fd, "   {1 index /FID ne {def} {pop pop} ifelse} forall\n");
 
798
        fprintf(fd, "   /Encoding ISOLatin1Encoding def\n");
 
799
        fprintf(fd, "   currentdict\n");
 
800
        fprintf(fd, "end\n");
 
801
        fprintf(fd, "%s-ISOLatin1Encoding exch definefont pop\n", psFont);
 
802
}
 
803
 
 
804
void PSGrafport::SetPSDashes() {
 
805
        if (GetLineStyle()==LineStyle::INVISIBLE &&
 
806
            GetFillStyle()==FillStyle::UNFILLED)
 
807
                return;
 
808
        else if (GetLineStyle()==LineStyle::DASHED)
 
809
                fprintf(fd, "[4 2] 0 setdash\n");
 
810
        else if (GetLineStyle()==LineStyle::DOTTED)
 
811
                fprintf(fd, "[1 1] 0 setdash\n");
 
812
        else if (GetLineStyle()==LineStyle::WIDE_DOTTED)
 
813
                fprintf(fd, "[2 2] 0 setdash\n");
 
814
}
 
815
 
 
816
void PSGrafport::UnsetPSDashes() {
 
817
        if (GetLineStyle()==LineStyle::DASHED || 
 
818
            GetLineStyle()==LineStyle::DOTTED ||
 
819
            GetLineStyle()==LineStyle::WIDE_DOTTED)
 
820
                fprintf(fd, "[] 0 setdash\n");
 
821
}