~ubuntu-branches/ubuntu/lucid/graphviz/lucid-security

« back to all changes in this revision

Viewing changes to lefty/ws/x11/gpcanvas.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen M Moraco
  • Date: 2002-02-05 18:52:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020205185212-8i04c70te00rc40y
Tags: upstream-1.7.16
ImportĀ upstreamĀ versionĀ 1.7.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#pragma prototyped
 
2
/* Lefteris Koutsofios - AT&T Bell Laboratories */
 
3
 
 
4
#include "common.h"
 
5
#include "g.h"
 
6
#include "gcommon.h"
 
7
#include "mem.h"
 
8
 
 
9
#define PSDPI 300.0
 
10
#define PSMAXPIXW (8.0  * PSDPI)
 
11
#define PSMAXPIXH (10.5 * PSDPI)
 
12
#define PSPTPI 72.0
 
13
#define PSMAXPTW (8.0  * PSPTPI)
 
14
#define PSMAXPTH (10.5 * PSPTPI)
 
15
#define PSXOFF 18
 
16
#define PSYOFF 18
 
17
 
 
18
static PIXsize_t maxsize = { PSMAXPIXW, PSMAXPIXH };
 
19
static long count;
 
20
 
 
21
#define WPU widget->u.p
 
22
#define FP widget->u.p->fp
 
23
 
 
24
#define RED   WPU->colors[WPU->gattr.color].nr
 
25
#define GREEN WPU->colors[WPU->gattr.color].ng
 
26
#define BLUE  WPU->colors[WPU->gattr.color].nb
 
27
 
 
28
static char *gstyles[5] = {
 
29
    /* G_SOLID */       "16  0",
 
30
    /* G_DASHED */      " 4  4",
 
31
    /* G_DOTTED */      " 2  2",
 
32
    /* G_LONGDASHED */  " 4 12",
 
33
    /* G_SHORTDASHED */ "12  4",
 
34
};
 
35
 
 
36
char *Gpscanvasname = "out.ps";
 
37
 
 
38
static char *findfont (char *);
 
39
static void setgattr (Gwidget_t *, Ggattr_t *);
 
40
 
 
41
static PIXrect_t rdrawtopix (Gwidget_t *, Grect_t);
 
42
static PIXpoint_t pdrawtopix (Gwidget_t *, Gpoint_t);
 
43
static PIXsize_t sdrawtopix (Gwidget_t *, Gsize_t);
 
44
static PIXpoint_t pdrawtobpix (Gbitmap_t *, Gpoint_t);
 
45
 
 
46
int GPcreatewidget (Gwidget_t *parent, Gwidget_t *widget,
 
47
        int attrn, Gwattr_t *attrp) {
 
48
    PIXpoint_t po;
 
49
    PIXsize_t ps;
 
50
    struct Gpwcolor_t *cp;
 
51
    FILE *pfp;
 
52
    char buf[120];
 
53
    char *s, *path;
 
54
    int color, lflag, ai, i, x, y, w, h, r, g, b;
 
55
 
 
56
    if (!(path = buildpath ("lefty.psp", 0)) ||
 
57
            !(pfp = fopen (path, "r"))) {
 
58
        Gerr (POS, G_ERRCANNOTOPENFILE, "lefty.psp");
 
59
        return -1;
 
60
    }
 
61
    s = Gpscanvasname;
 
62
    lflag = FALSE;
 
63
    po.x = po.y = 0;
 
64
    ps.x = ps.y = MINPWSIZE;
 
65
    for (ai = 0; ai < attrn; ai++) {
 
66
        switch (attrp[ai].id) {
 
67
        case G_ATTRORIGIN:
 
68
            GETORIGIN (attrp[ai].u.p, po);
 
69
            break;
 
70
        case G_ATTRSIZE:
 
71
            GETSIZE (attrp[ai].u.s, ps, MINPWSIZE);
 
72
            break;
 
73
        case G_ATTRNAME:
 
74
            if (attrp[ai].u.t && attrp[ai].u.t[0])
 
75
                s = attrp[ai].u.t;
 
76
            break;
 
77
        case G_ATTRMODE:
 
78
            if (Strcmp ("landscape", attrp[ai].u.t) == 0)
 
79
                lflag = TRUE;
 
80
            else if (Strcmp ("portrait", attrp[ai].u.t) == 0)
 
81
                lflag = FALSE;
 
82
            else {
 
83
                Gerr (POS, G_ERRBADATTRVALUE, attrp[ai].u.t);
 
84
                return -1;
 
85
            }
 
86
            break;
 
87
        case G_ATTRCOLOR:
 
88
            /* will do it after the widget is created */
 
89
            break;
 
90
        case G_ATTRVIEWPORT:
 
91
            /* will do it after the widget is created */
 
92
            break;
 
93
        case G_ATTRWINDOW:
 
94
            /* will do it after the widget is created */
 
95
            break;
 
96
        case G_ATTRWINDOWID:
 
97
            Gerr (POS, G_ERRCANNOTSETATTR1, "windowid");
 
98
            return -1;
 
99
        case G_ATTRUSERDATA:
 
100
            widget->udata = attrp[ai].u.u;
 
101
            break;
 
102
        default:
 
103
            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
 
104
            return -1;
 
105
        }
 
106
    }
 
107
    if (!(FP = fopen (s, "w"))) {
 
108
        Gerr (POS, G_ERRCANNOTOPENFILE, s);
 
109
        return -1;
 
110
    }
 
111
    WPU->colors[0].r = WPU->colors[0].g = WPU->colors[0].b = 255;
 
112
    WPU->colors[0].nr = WPU->colors[0].ng = WPU->colors[0].nb = 1.0;
 
113
    WPU->colors[0].inuse = TRUE;
 
114
    WPU->colors[1].r = WPU->colors[1].g = WPU->colors[1].b = 0;
 
115
    WPU->colors[1].nr = WPU->colors[1].ng = WPU->colors[1].nb = 0.0;
 
116
    WPU->colors[1].inuse = TRUE;
 
117
    for (i = 2; i < G_MAXCOLORS; i++)
 
118
        WPU->colors[i].inuse = FALSE;
 
119
    WPU->gattr.color = 1;
 
120
    WPU->gattr.width = 0;
 
121
    WPU->gattr.mode = -1;
 
122
    WPU->gattr.fill = 0;
 
123
    WPU->gattr.style = 0;
 
124
    WPU->wrect.o.x = 0.0, WPU->wrect.o.y = 0.0;
 
125
    WPU->wrect.c.x = 1.0, WPU->wrect.c.y = 1.0;
 
126
    WPU->vsize.x = ps.x, WPU->vsize.y = ps.y;
 
127
    if (lflag)
 
128
        x = po.y, y = po.x, w = ps.y, h = ps.x;
 
129
    else
 
130
        x = po.x, y = po.y, w = ps.x, h = ps.y;
 
131
    fprintf (FP, "%%! LEFTY Output\n");
 
132
    fprintf (FP, "%%%%BoundingBox: %d %d %d %d\n",
 
133
            (int) (PSXOFF + PSMAXPTW * x / maxsize.x + 0.5),
 
134
            (int) (PSYOFF + PSMAXPTH * y / maxsize.y + 0.5),
 
135
            (int) (PSXOFF + PSMAXPTW * w / maxsize.x + 0.5),
 
136
            (int) (PSYOFF + PSMAXPTH * h / maxsize.y + 0.5));
 
137
    fprintf (FP, "%%%%EndComments\n");
 
138
    while (fgets (buf, 120, pfp))
 
139
        fputs (&buf[0], FP);
 
140
    fclose (pfp);
 
141
    fprintf (FP, "/ICP { %d %d %d %d SCP } def\n",
 
142
            (int) po.x, (int) po.y,
 
143
            (int) (po.x + ps.x - 1), (int) (po.y + ps.y - 1));
 
144
    fprintf (FP, "/BB { %d %d %d %d } def\n",
 
145
            (int) po.x, (int) po.y,
 
146
            (int) (po.x + ps.x - 1), (int) (po.y + ps.y - 1));
 
147
    if (!lflag)
 
148
        fprintf (FP, "[%f 0 0 %f %d %d] concat\n",
 
149
                PSPTPI / PSDPI, PSPTPI / PSDPI, PSXOFF, PSYOFF);
 
150
    else
 
151
        fprintf (FP, "[0 %f %f 0 %d %d] concat\n",
 
152
                PSPTPI / PSDPI, - PSPTPI / PSDPI,
 
153
                (int) (PSXOFF + ps.y * PSPTPI / PSDPI), PSYOFF);
 
154
    fprintf (FP, "%d %d translate ICP\n", (int) po.x, (int) po.y);
 
155
    fprintf (FP, "1 setlinecap\n");
 
156
    fprintf (FP, "ICP\n");
 
157
    WPU->gattr.color = 1;
 
158
    fprintf (FP, "%f %f %f CL\n", RED, GREEN, BLUE);
 
159
    WPU->defgattr = WPU->gattr;
 
160
    for (ai = 0; ai < attrn; ai++) {
 
161
        switch (attrp[ai].id) {
 
162
        case G_ATTRCOLOR:
 
163
            color = attrp[ai].u.c.index;
 
164
            if (color < 0 || color > G_MAXCOLORS) {
 
165
                Gerr (POS, G_ERRBADCOLORINDEX, attrp[ai].u.c.index);
 
166
                return -1;
 
167
            }
 
168
            cp = &WPU->colors[color];
 
169
            r = attrp[ai].u.c.r;
 
170
            g = attrp[ai].u.c.g;
 
171
            b = attrp[ai].u.c.b;
 
172
            cp->r = r, cp->g = g, cp->b = b;
 
173
            cp->nr = r / 256.0, cp->ng = g / 256.0, cp->nb = b / 256.0;
 
174
            cp->inuse = TRUE;
 
175
            break;
 
176
        case G_ATTRVIEWPORT:
 
177
            WPU->vsize.x = (int) (attrp[ai].u.s.x + 0.5);
 
178
            WPU->vsize.y = (int) (attrp[ai].u.s.y + 0.5);
 
179
            fprintf (FP, "0 0 %d %d SCP\n",
 
180
                    (int) WPU->vsize.x, (int) WPU->vsize.y);
 
181
            break;
 
182
        case G_ATTRWINDOW:
 
183
            WPU->wrect = attrp[ai].u.r;
 
184
            break;
 
185
        }
 
186
    }
 
187
    return 0;
 
188
}
 
189
 
 
190
int GPsetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
 
191
    struct Gpwcolor_t *cp;
 
192
    int color, ai, r, g, b;
 
193
 
 
194
    for (ai = 0; ai < attrn; ai++) {
 
195
        switch (attrp[ai].id) {
 
196
        case G_ATTRORIGIN:
 
197
            break;
 
198
        case G_ATTRSIZE:
 
199
            break;
 
200
        case G_ATTRNAME:
 
201
            break;
 
202
        case G_ATTRMODE:
 
203
            break;
 
204
        case G_ATTRCOLOR:
 
205
            color = attrp[ai].u.c.index;
 
206
            if (color < 0 || color > G_MAXCOLORS) {
 
207
                Gerr (POS, G_ERRBADCOLORINDEX, attrp[ai].u.c.index);
 
208
                return -1;
 
209
            }
 
210
            cp = &WPU->colors[color];
 
211
            r = attrp[ai].u.c.r;
 
212
            g = attrp[ai].u.c.g;
 
213
            b = attrp[ai].u.c.b;
 
214
            cp->r = r, cp->g = g, cp->b = b;
 
215
            cp->nr = r / 256.0, cp->ng = g / 256.0, cp->nb = b / 256.0;
 
216
            cp->inuse = TRUE;
 
217
            break;
 
218
        case G_ATTRVIEWPORT:
 
219
            WPU->vsize.x = (int) (attrp[ai].u.s.x + 0.5);
 
220
            WPU->vsize.y = (int) (attrp[ai].u.s.y + 0.5);
 
221
            fprintf (FP, "0 0 %d %d SCP\n",
 
222
                    (int) WPU->vsize.x, (int) WPU->vsize.y);
 
223
            break;
 
224
        case G_ATTRWINDOW:
 
225
            WPU->wrect = attrp[ai].u.r;
 
226
            break;
 
227
        case G_ATTRWINDOWID:
 
228
            Gerr (POS, G_ERRCANNOTSETATTR2, "windowid");
 
229
            return -1;
 
230
        case G_ATTRUSERDATA:
 
231
            widget->udata = attrp[ai].u.u;
 
232
            break;
 
233
        default:
 
234
            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
 
235
            return -1;
 
236
        }
 
237
    }
 
238
    return 0;
 
239
}
 
240
 
 
241
int GPgetwidgetattr (Gwidget_t *widget, int attrn, Gwattr_t *attrp) {
 
242
    struct Gpwcolor_t *cp;
 
243
    int color, ai;
 
244
 
 
245
    for (ai = 0; ai < attrn; ai++) {
 
246
        switch (attrp[ai].id) {
 
247
        case G_ATTRORIGIN:
 
248
            break;
 
249
        case G_ATTRSIZE:
 
250
            break;
 
251
        case G_ATTRNAME:
 
252
            break;
 
253
        case G_ATTRMODE:
 
254
            break;
 
255
        case G_ATTRCOLOR:
 
256
            color = attrp[ai].u.c.index;
 
257
            if (color < 0 || color > G_MAXCOLORS || !WPU->colors[color].inuse) {
 
258
                Gerr (POS, G_ERRBADCOLORINDEX, attrp[ai].u.c.index);
 
259
                return -1;
 
260
            }
 
261
            cp = &WPU->colors[color];
 
262
            attrp[ai].u.c.r = cp->r;
 
263
            attrp[ai].u.c.g = cp->g;
 
264
            attrp[ai].u.c.b = cp->b;
 
265
            break;
 
266
        case G_ATTRVIEWPORT:
 
267
            attrp[ai].u.s = WPU->vsize;
 
268
            break;
 
269
        case G_ATTRWINDOW:
 
270
            attrp[ai].u.r = WPU->wrect;
 
271
            break;
 
272
        case G_ATTRWINDOWID:
 
273
            Gerr (POS, G_ERRCANNOTGETATTR, "windowid");
 
274
            break;
 
275
        case G_ATTRUSERDATA:
 
276
            widget->udata = attrp[ai].u.u;
 
277
            break;
 
278
        default:
 
279
            Gerr (POS, G_ERRBADATTRID, attrp[ai].id);
 
280
            return -1;
 
281
        }
 
282
    }
 
283
    return 0;
 
284
}
 
285
 
 
286
int GPdestroywidget (Gwidget_t *widget) {
 
287
    fprintf (FP, "stroke showpage\n");
 
288
    fclose (FP);
 
289
    return 0;
 
290
}
 
291
 
 
292
int GPcanvasclear (Gwidget_t *widget) {
 
293
    fprintf (FP, "ICP DO\n");
 
294
    WPU->gattr.color = 0;
 
295
    fprintf (FP, "%f %f %f CL\n", RED, GREEN, BLUE);
 
296
    fprintf (FP, "BB BOX FI\n");
 
297
    WPU->gattr.color = -1;
 
298
    fprintf (FP, "0 0 %d %d SCP\n", (int) WPU->vsize.x, (int) WPU->vsize.y);
 
299
    return 0;
 
300
}
 
301
 
 
302
int GPsetgfxattr (Gwidget_t *widget, Ggattr_t *ap) {
 
303
    setgattr (widget, ap);
 
304
    WPU->defgattr = WPU->gattr;
 
305
    return 0;
 
306
}
 
307
 
 
308
int GPgetgfxattr (Gwidget_t *widget, Ggattr_t *ap) {
 
309
    if ((ap->flags & G_GATTRCOLOR))
 
310
        ap->color = WPU->gattr.color;
 
311
    if ((ap->flags & G_GATTRWIDTH))
 
312
        ap->width = WPU->gattr.width;
 
313
    if ((ap->flags & G_GATTRMODE))
 
314
        ap->mode = WPU->gattr.mode;
 
315
    if ((ap->flags & G_GATTRFILL))
 
316
        ap->fill = WPU->gattr.fill;
 
317
    if ((ap->flags & G_GATTRSTYLE))
 
318
        ap->style = WPU->gattr.style;
 
319
    return 0;
 
320
}
 
321
 
 
322
int GParrow (Gwidget_t *widget, Gpoint_t gp1, Gpoint_t gp2, Ggattr_t *ap) {
 
323
    PIXpoint_t pp1, pp2, pa, pb, pd;
 
324
    double tangent;
 
325
    int l;
 
326
 
 
327
    pp1 = pdrawtopix (widget, gp1), pp2 = pdrawtopix (widget, gp2);
 
328
    pd.x = pp1.x - pp2.x, pd.y = pp1.y - pp2.y;
 
329
    if (pd.x == 0 && pd.y == 0)
 
330
        return 0;
 
331
    tangent = atan2 ((double) pd.y, (double) pd.x);
 
332
    if ((l = sqrt ((double) (pd.x * pd.x + pd.y * pd.y))) < 30)
 
333
        l = 30;
 
334
    pa.x = l * cos (tangent + M_PI / 7) + pp2.x;
 
335
    pa.y = l * sin (tangent + M_PI / 7) + pp2.y;
 
336
    pb.x = l * cos (tangent - M_PI / 7) + pp2.x;
 
337
    pb.y = l * sin (tangent - M_PI / 7) + pp2.y;
 
338
    setgattr (widget, ap);
 
339
    fprintf (FP, "%d %d %d %d LI\n",
 
340
            (int) pp2.x, (int) pp2.y, (int) pp1.x, (int) pp1.y);
 
341
    fprintf (FP, "%d %d %d %d LI\n",
 
342
            (int) pp2.x, (int) pp2.y, (int) pa.x, (int) pa.y);
 
343
    fprintf (FP, "%d %d %d %d LI\n",
 
344
            (int) pp2.x, (int) pp2.y, (int) pb.x, (int) pb.y);
 
345
    return 0;
 
346
}
 
347
 
 
348
int GPline (Gwidget_t *widget, Gpoint_t gp1, Gpoint_t gp2, Ggattr_t *ap) {
 
349
    PIXpoint_t pp1, pp2;
 
350
 
 
351
    pp1 = pdrawtopix (widget, gp1), pp2 = pdrawtopix (widget, gp2);
 
352
    if (count++ == 100)
 
353
        count = 0, fprintf (FP, "DO\n");
 
354
    setgattr (widget, ap);
 
355
    fprintf (FP, "%d %d %d %d LI\n",
 
356
            (int) pp2.x, (int) pp2.y, (int) pp1.x, (int) pp1.y);
 
357
    return 0;
 
358
}
 
359
 
 
360
int GPbox (Gwidget_t *widget, Grect_t gr, Ggattr_t *ap) {
 
361
    PIXrect_t pr;
 
362
 
 
363
    pr = rdrawtopix (widget, gr);
 
364
    setgattr (widget, ap);
 
365
    if (WPU->gattr.fill)
 
366
        fprintf (FP, "DO %d %d %d %d BOX FI\n",
 
367
                (int) pr.o.x, (int) pr.o.y, (int) pr.c.x, (int) pr.c.y);
 
368
    else
 
369
        fprintf (FP, "DO %d %d %d %d BOX DO\n",
 
370
                (int) pr.o.x, (int) pr.o.y, (int) pr.c.x, (int) pr.c.y);
 
371
    return 0;
 
372
}
 
373
 
 
374
int GPpolygon (Gwidget_t *widget, int gpn, Gpoint_t *gpp, Ggattr_t *ap) {
 
375
    PIXpoint_t pp;
 
376
    int i;
 
377
 
 
378
    if (gpn == 0)
 
379
        return 0;
 
380
 
 
381
    pp = pdrawtopix (widget, gpp[0]);
 
382
    setgattr (widget, ap);
 
383
    fprintf (FP, "DO %d %d moveto\n", (int) pp.x, (int) pp.y);
 
384
    for (i = 1; i < gpn; i++) {
 
385
        pp = pdrawtopix (widget, gpp[i]);
 
386
        fprintf (FP, "%d %d lineto\n", (int) pp.x, (int) pp.y);
 
387
    }
 
388
    if (WPU->gattr.fill)
 
389
        fprintf (FP, "FI\n");
 
390
    else
 
391
        fprintf (FP, "DO\n");
 
392
    return 0;
 
393
}
 
394
 
 
395
int GPsplinegon (Gwidget_t *widget, int gpn, Gpoint_t *gpp, Ggattr_t *ap) {
 
396
    PIXpoint_t p0, p1, p2, p3;
 
397
    int i;
 
398
 
 
399
    if (gpn == 0)
 
400
        return 0;
 
401
 
 
402
    p0 = pdrawtopix (widget, gpp[0]);
 
403
    setgattr (widget, ap);
 
404
    fprintf (FP, "DO %d %d moveto\n", (int) p0.x, (int) p0.y);
 
405
    for (i = 1; i < gpn; i += 3) {
 
406
        p1 = pdrawtopix (widget, gpp[i]);
 
407
        p2 = pdrawtopix (widget, gpp[i + 1]);
 
408
        p3 = pdrawtopix (widget, gpp[i + 2]);
 
409
        fprintf (FP, "%d %d %d %d %d %d CT\n", (int) p1.x, (int) p1.y,
 
410
                (int) p2.x, (int) p2.y, (int) p3.x, (int) p3.y);
 
411
    }
 
412
    if (WPU->gattr.fill)
 
413
        fprintf (FP, "FI\n");
 
414
    else
 
415
        fprintf (FP, "DO\n");
 
416
    return 0;
 
417
}
 
418
 
 
419
int GParc (Gwidget_t *widget, Gpoint_t gc, Gsize_t gs,
 
420
        double ang1, double ang2, Ggattr_t *ap) {
 
421
    PIXpoint_t pc;
 
422
    PIXsize_t ps;
 
423
 
 
424
    pc = pdrawtopix (widget, gc), ps = sdrawtopix (widget, gs);
 
425
    setgattr (widget, ap);
 
426
    if (WPU->gattr.fill)
 
427
        fprintf (FP, "DO %d %d %f %d %f %f ARF\n",
 
428
                pc.x, pc.y, (double) ps.y / (double) ps.x, ps.x, ang1, ang2);
 
429
    else
 
430
        fprintf (FP, "DO %d %d %f %d %f %f AR\n",
 
431
                pc.x, pc.y, (double) ps.y / (double) ps.x, ps.x, ang1, ang2);
 
432
    return 0;
 
433
}
 
434
 
 
435
int GPtext (Gwidget_t *widget, Gtextline_t *tlp, int n, Gpoint_t go, char *fn,
 
436
        double fs, char *justs, Ggattr_t *ap) {
 
437
    Gsize_t gs;
 
438
    PIXpoint_t po;
 
439
    PIXsize_t ps;
 
440
    char *font;
 
441
    char c, *p;
 
442
    int i;
 
443
 
 
444
    po = pdrawtopix (widget, go);
 
445
    gs.x = 0, gs.y = fs;
 
446
    ps = sdrawtopix (widget, gs);
 
447
    font = findfont (fn);
 
448
    setgattr (widget, ap);
 
449
    fprintf (FP, "DO %d (%c) %d (%c) [",
 
450
            (int) po.x, justs[0], (int) po.y, justs[1]);
 
451
    for (i = 0; i < n; i++) {
 
452
        c = tlp[i].p[tlp[i].n], tlp[i].p[tlp[i].n] = '\000';
 
453
        fprintf (FP, "[ (");
 
454
        for (p = tlp[i].p; *p; p++) {   /* generate PS escapes as needed */
 
455
                if ((*p == '(') || (*p == ')') || (*p == '\\')) fputc('\\',FP);
 
456
                fputc(*p,FP);
 
457
        }
 
458
        fprintf (FP,") (%c) ] ", tlp[i].j);
 
459
        tlp[i].p[tlp[i].n] = c;
 
460
    }
 
461
    fprintf (FP, "] %d /%s %d TXT\n", n, font, (int) ps.y);
 
462
    return 0;
 
463
}
 
464
 
 
465
static char *findfont (char *name) {
 
466
    char *font;
 
467
 
 
468
    if (name[0] == '\000' || Strcmp (name, "default") == 0)
 
469
        font = "Times-Roman";
 
470
    else
 
471
        font = name;
 
472
    return font;
 
473
}
 
474
 
 
475
int GPcreatebitmap (Gwidget_t *widget, Gbitmap_t *bitmap, Gsize_t s) {
 
476
    if (!widget) {
 
477
        Gerr (POS, G_ERRNOPARENTWIDGET);
 
478
        return -1;
 
479
    }
 
480
    if (!bitmap) {
 
481
        Gerr (POS, G_ERRNOBITMAP);
 
482
        return -1;
 
483
    }
 
484
    bitmap->u.bits = Marrayalloc ((long) ((int) s.x * (int) s.y * 3));
 
485
    bitmap->ctype = widget->type;
 
486
    bitmap->canvas = widget - &Gwidgets[0];
 
487
    bitmap->size = s;
 
488
    return 0;
 
489
}
 
490
 
 
491
int GPdestroybitmap (Gbitmap_t *bitmap) {
 
492
    if (!bitmap) {
 
493
        Gerr (POS, G_ERRNOBITMAP);
 
494
        return -1;
 
495
    }
 
496
    Marrayfree (bitmap->u.bits);
 
497
    return 0;
 
498
}
 
499
 
 
500
int GPreadbitmap (Gwidget_t *widget, Gbitmap_t *bitmap, FILE *fp) {
 
501
    Gsize_t s;
 
502
    char bufp[2048];
 
503
    char *s1, *s2;
 
504
    char c;
 
505
    int bufn, bufi, step, x, y, k;
 
506
 
 
507
    if (!widget) {
 
508
        Gerr (POS, G_ERRNOPARENTWIDGET);
 
509
        return -1;
 
510
    }
 
511
    if (!bitmap) {
 
512
        Gerr (POS, G_ERRNOBITMAP);
 
513
        return -1;
 
514
    }
 
515
    step = 0;
 
516
    while (step < 3) {
 
517
l1:
 
518
        if (!fgets (bufp, 2048, fp)) {
 
519
            Gerr (POS, G_ERRCANNOTREADBITMAP);
 
520
            return -1;
 
521
        }
 
522
        s1 = &bufp[0];
 
523
l2:
 
524
        for (; *s1 && isspace (*s1); s1++)
 
525
            ;
 
526
        if (!*s1 || *s1 == '#')
 
527
            goto l1;
 
528
        switch (step) {
 
529
        case 0:
 
530
            if (strncmp (s1, "P6", 2) != 0) {
 
531
                Gerr (POS, G_ERRCANNOTREADBITMAP);
 
532
                return -1;
 
533
            }
 
534
            step++, s1 += 2;
 
535
            goto l2;
 
536
        case 1:
 
537
            for (s2 = s1; *s2 && *s2 >= '0' && *s2 <= '9'; s2++)
 
538
                ;
 
539
            c = *s2, *s2 = 0;
 
540
            if (s2 == s1 || (s.x = atoi (s1)) <= 0) {
 
541
                *s2 = c, Gerr (POS, G_ERRCANNOTREADBITMAP);
 
542
                return -1;
 
543
            }
 
544
            *s2 = c, step++, s1 = s2;
 
545
            goto l2;
 
546
        case 2:
 
547
            for (s2 = s1; *s2 && *s2 >= '0' && *s2 <= '9'; s2++)
 
548
                ;
 
549
            c = *s2, *s2 = 0;
 
550
            if (s2 == s1 || (s.y = atoi (s1)) <= 0) {
 
551
                *s2 = c, Gerr (POS, G_ERRCANNOTREADBITMAP);
 
552
                return -1;
 
553
            }
 
554
            *s2 = c, step++, s1 = s2;
 
555
            goto l2;
 
556
        }
 
557
    }
 
558
    bitmap->u.bits = Marrayalloc ((long) ((int) s.x * (int) s.y * 3));
 
559
    bitmap->ctype = widget->type;
 
560
    bitmap->canvas = widget - &Gwidgets[0];
 
561
    bitmap->size = s;
 
562
    bufi = bufn = 0;
 
563
    bufp[bufi] = 0;
 
564
    s1 = (char *) bitmap->u.bits;
 
565
    for (y = 0; y < s.y; y++) {
 
566
        for (x = 0; x < s.x; x++) {
 
567
            for (k = 0; k < 3; k++) {
 
568
                if (bufi == bufn) {
 
569
                    if ((bufn = fread (bufp, 1, 2047, fp)) == 0) {
 
570
                        Marrayfree (bitmap->u.bits);
 
571
                        Gerr (POS, G_ERRCANNOTCREATEBITMAP);
 
572
                        return -1;
 
573
                    }
 
574
                    bufi = 0;
 
575
                }
 
576
                *s1++ = bufp[bufi++];
 
577
            }
 
578
        }
 
579
    }
 
580
    return 0;
 
581
}
 
582
 
 
583
int GPwritebitmap (Gbitmap_t *bitmap, FILE *fp) {
 
584
    return -1;
 
585
}
 
586
 
 
587
int GPbitblt (Gwidget_t *widget, Gpoint_t gp, Grect_t gr, Gbitmap_t *bitmap,
 
588
        char *mode, Ggattr_t *ap) {
 
589
    PIXrect_t pr, br;
 
590
    PIXpoint_t pp;
 
591
    PIXsize_t bs;
 
592
    Gsize_t scale;
 
593
    Gxy_t p;
 
594
    int x, y, hi, lo;
 
595
    double tvx, tvy, twx, twy;
 
596
    char *s;
 
597
 
 
598
    if (gr.o.x > gr.c.x)
 
599
        p.x = gr.o.x, gr.o.x = gr.c.x, gr.c.x = p.x;
 
600
    if (gr.o.y > gr.c.y)
 
601
        p.y = gr.o.y, gr.o.y = gr.c.y, gr.c.y = p.y;
 
602
    tvx = WPU->vsize.x, tvy = WPU->vsize.y;
 
603
    twx = WPU->wrect.c.x - WPU->wrect.o.x;
 
604
    twy = WPU->wrect.c.y - WPU->wrect.o.y;
 
605
    scale.x = tvx / twx, scale.y = tvy / twy;
 
606
    pr = rdrawtopix (widget, gr);
 
607
    pp = pdrawtobpix (bitmap, gp);
 
608
    bs.x = (pr.c.x - pr.o.x + 1) / scale.x;
 
609
    bs.y = (pr.c.y - pr.o.y + 1) / scale.y;
 
610
    br.o.x = pp.x, br.o.y = pp.y - bs.y + 1;
 
611
    br.c.x = br.o.x + bs.x - 1, br.c.y = br.o.y + bs.y - 1;
 
612
    if (br.o.x < 0)
 
613
        pr.o.x -= br.o.x * scale.x, br.o.x = 0;
 
614
    if (br.o.y < 0)
 
615
        pr.o.y -= br.o.y * scale.y, br.o.y = 0;
 
616
    if (br.c.x >= bitmap->size.x) {
 
617
        pr.c.x -= (br.c.x + 1 - bitmap->size.x) * scale.x;
 
618
        br.c.x = bitmap->size.x - 1;
 
619
    }
 
620
    if (br.c.y >= bitmap->size.y) {
 
621
        pr.c.y -= (br.c.y + 1 - bitmap->size.y) * scale.y;
 
622
        br.c.y = bitmap->size.y - 1;
 
623
    }
 
624
    if (pr.o.x < 0)
 
625
        br.o.x -= pr.o.x / scale.x, pr.o.x = 0;
 
626
    if (pr.o.y < 0)
 
627
        br.o.y -= pr.o.y / scale.y, pr.o.y = 0;
 
628
    if (pr.c.x >= tvx)
 
629
        br.c.x -= (pr.c.x + 1 - tvx) / scale.x, pr.c.x = tvx - 1;
 
630
    if (pr.c.y >= tvy)
 
631
        br.c.y -= (pr.c.y + 1 - tvy) / scale.y, pr.c.y = tvy - 1;
 
632
    bs.x = (pr.c.x - pr.o.x + 1) / scale.x;
 
633
    bs.y = (pr.c.y - pr.o.y + 1) / scale.y;
 
634
    setgattr (widget, ap);
 
635
    fprintf (FP, "DO gsave\n");
 
636
    fprintf (FP, "%d %d translate\n", pr.o.x, pr.o.y);
 
637
    fprintf (FP, "%f %f scale\n", scale.x * bs.x, scale.y * bs.y);
 
638
    fprintf (FP, "/mystr %d string def\n", 3 * bs.x);
 
639
    fprintf (FP, "%d %d 8\n", bs.x, bs.y);
 
640
    fprintf (FP, "[%d 0 0 %d 0 %d]\n", bs.x, -bs.y, bs.y);
 
641
    fprintf (FP, "{currentfile mystr readhexstring pop} false 3 colorimage\n");
 
642
    for (y = 0; y < bs.y; y++) {
 
643
        s = (char *) (bitmap->u.bits +
 
644
                3 * ((int) bitmap->size.x * (br.o.y + y) + br.o.x));
 
645
        for (x = 0; x < bs.x; x++) {
 
646
            hi = (*s >> 4) & 15, lo = *s++ && 15;
 
647
            fprintf (FP, "%x%x", hi, lo);
 
648
            hi = (*s >> 4) & 15, lo = *s++ && 15;
 
649
            fprintf (FP, "%x%x", hi, lo);
 
650
            hi = (*s >> 4) & 15, lo = *s++ && 15;
 
651
            fprintf (FP, "%x%x", hi, lo);
 
652
        }
 
653
        fprintf (FP, "\n");
 
654
    }
 
655
    fprintf (FP, "grestore\nNP\n");
 
656
    return 0;
 
657
}
 
658
 
 
659
static void setgattr (Gwidget_t *widget, Ggattr_t *ap) {
 
660
    int color, width, style;
 
661
 
 
662
    if (!(ap->flags & G_GATTRCOLOR))
 
663
        ap->color = WPU->defgattr.color;
 
664
    if (!(ap->flags & G_GATTRWIDTH))
 
665
        ap->width = WPU->defgattr.width;
 
666
    if (!(ap->flags & G_GATTRFILL))
 
667
        ap->fill = WPU->defgattr.fill;
 
668
    if (!(ap->flags & G_GATTRSTYLE))
 
669
    ap->style = WPU->defgattr.style;
 
670
    color = ap->color;
 
671
    if (color >= G_MAXCOLORS || !(WPU->colors[color].inuse))
 
672
        color = 1;
 
673
    if (color != WPU->gattr.color) {
 
674
        WPU->gattr.color = color;
 
675
        fprintf (FP, "%f %f %f CL\n", RED, GREEN, BLUE);
 
676
    }
 
677
    width = ap->width;
 
678
    if (width != WPU->gattr.width) {
 
679
        WPU->gattr.width = width;
 
680
        fprintf (FP, "DO %d setlinewidth NP\n", width);
 
681
    }
 
682
    WPU->gattr.fill = ap->fill;
 
683
    style = ap->style;
 
684
    if (style != WPU->gattr.style) {
 
685
        WPU->gattr.style = style;
 
686
        fprintf (FP, "DO [ %s ] 0 setdash NP\n", gstyles[style]);
 
687
    }
 
688
}
 
689
 
 
690
static PIXrect_t rdrawtopix (Gwidget_t *widget, Grect_t gr) {
 
691
    PIXrect_t pr;
 
692
    double tvx, tvy, twx, twy;
 
693
 
 
694
    tvx = WPU->vsize.x - 1, tvy = WPU->vsize.y - 1;
 
695
    twx = WPU->wrect.c.x - WPU->wrect.o.x;
 
696
    twy = WPU->wrect.c.y - WPU->wrect.o.y;
 
697
    pr.o.x = tvx * (gr.o.x - WPU->wrect.o.x) / twx + 0.5;
 
698
    pr.o.y = tvy * (gr.o.y - WPU->wrect.o.y) / twy + 0.5;
 
699
    pr.c.x = tvx * (gr.c.x - WPU->wrect.o.x) / twx + 0.5;
 
700
    pr.c.y = tvy * (gr.c.y - WPU->wrect.o.y) / twy + 0.5;
 
701
    return pr;
 
702
}
 
703
 
 
704
static PIXpoint_t pdrawtopix (Gwidget_t *widget, Gpoint_t gp) {
 
705
    PIXpoint_t pp;
 
706
    double tvx, tvy, twx, twy;
 
707
 
 
708
    tvx = WPU->vsize.x - 1, tvy = WPU->vsize.y - 1;
 
709
    twx = WPU->wrect.c.x - WPU->wrect.o.x;
 
710
    twy = WPU->wrect.c.y - WPU->wrect.o.y;
 
711
    pp.x = tvx * (gp.x - WPU->wrect.o.x) / twx + 0.5;
 
712
    pp.y = tvy * (gp.y - WPU->wrect.o.y) / twy + 0.5;
 
713
    return pp;
 
714
}
 
715
 
 
716
static PIXsize_t sdrawtopix (Gwidget_t *widget, Gsize_t gs) {
 
717
    PIXsize_t ps;
 
718
    double tvx, tvy, twx, twy;
 
719
 
 
720
    tvx = WPU->vsize.x - 1, tvy = WPU->vsize.y - 1;
 
721
    twx = WPU->wrect.c.x - WPU->wrect.o.x;
 
722
    twy = WPU->wrect.c.y - WPU->wrect.o.y;
 
723
    ps.x = tvx * (gs.x - 1) / twx + 1.5;
 
724
    ps.y = tvy * (gs.y - 1) / twy + 1.5;
 
725
    return ps;
 
726
}
 
727
 
 
728
static PIXpoint_t pdrawtobpix (Gbitmap_t *bitmap, Gpoint_t gp) {
 
729
    PIXpoint_t pp;
 
730
    double tvy;
 
731
 
 
732
    tvy = bitmap->size.y - 1;
 
733
    pp.x = gp.x + 0.5;
 
734
    pp.y = tvy - gp.y + 0.5;
 
735
    return pp;
 
736
}