PLplot: cgm.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
cgm.c
Go to the documentation of this file.
1 // $Id: cgm.c 11283 2010-10-28 22:38:29Z airwin $
2 //
3 // PLplot cgm device driver.
4 //
5
6 //
7 // This driver generates CGM (computer graphics metafiles) files (bit of a
8 // tautology that... 'computer graphics metaFILES FILES' - oh well).
9 //
10 // The CGM format is vector-based and is widely used as an interchange
11 // format between drawing and plotting programs. Although I have never
12 // looked at them, there are apparently both Java applets and browser
13 // plug-ins for displaying CGM files on web pages.
14 //
15 // This plplot driver supports lines, polylines (they make a difference to
16 // CGM files), fills, and line widths. It is limited to 256 colours, which
17 // should not be a problem. The plplot CGM driver's source (cgm.c) was
18 // derived largely from the gd driver (gd.c).
19 //
20 // The plplot driver requires libcd.a. libcd.a is very similar to libgd.a
21 // and has a similar licencing agreement behind it. Unlike libgd,
22 // development of libcd seems to have crawled to a halt back in 1998 with
23 // V1.3 of the library. The original host site for the library no longer
24 // exists, so probably the best source of the library presently is:
25 //
26 // http://www.pa.msu.edu/reference/cgmdraw_ref.html
27 // http://www.pa.msu.edu/ftp/pub/unix/
28 //
29
30 //
31 // Two options are supported by the driver via the -drvopt command line
32 // toggle.
33 //
34 // By default CGM files don't have a background as such. The driver adds
35 // support for different backgrounds by colouring in a large rectangle
36 // underneath everything else. If for some reason you want the "raw plotted
37 // junk" and aren't really interested in having an obtrusive piece of paper
38 // in the back, use the command line toggle "-drvopt no_paper=1" to turn off
39 // this background paper.
40 //
41 // By default the CGM files generated by this driver try to make edges of
42 // polygons (ie fills) "invisible", which is something CGM files can do.
43 // Some programs (ie CoreDraw) ignore this field and draw edges in anyway.
44 // By setting "-drvopt force_edges=1" the driver will render edges on all
45 // filled polygons, and will set their colour to the same as the polygon.
46 // Most drivers should not need this, but if you see lines that you don't
47 // think you should be seeing in your viewer, try this toggle.
48 //
49
50 //
51 // Driver supports a hack that manipulates the colour palette when
52 // a light background is selected. This is basically to make sure
53 // there are not two "whites" when -bg ffffff is issued at the
54 // command line.
55 //
56 // Related to this change, there is an ability to swap the "new"
57 // black colour (index 15) with the red colour (index 2) by issuing
58 // the command line "-hack" option. I like this for web pages, because
59 // I think that black looks nicer than red (on white) for default
60 // plotting. That is why it can be enabled with -hack, in case you
61 // don't like it working this way.
62 //
63 // For me, these two changes make it easy to switch from a "screen friendly"
64 // black background with red first plotting colour, to a "web friendly"
65 // white background with a black first plotting colour.
66 //
67 // These features are enabled on a driver level by defining
68 // "SWAP_BALCK_WHEN_WHITE". If you wan't the driver to behave 100% like other
69 // drivers, comment out the define
70 //
71
72 #define SWAP_BALCK_WHEN_WHITE
73
74 #include "plDevs.h"
75
76 #ifdef PLD_cgm
77
78 #include "plplotP.h"
79 #include "drivers.h"
80
81 #include <cd.h>
82
83 // Device info
84 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_cgm = "cgm:CGM file:0:cgm:44:cgm\n";
85
86 // Prototypes for functions in this file.
87
88 static void fill_polygon( PLStream *pls );
89 static void setcmap( PLStream *pls );
90 static void plD_init_cgm_Dev( PLStream *pls );
91
92 // top level declarations
93
94 // In an attempt to fix a problem with the hidden line removal functions
95 // that results in hidden lines *not* being removed from "small" plot
96 // pages (ie, like a normal video screen), a "virtual" page of much
97 // greater size is used to trick the algorithm into working correctly.
98 // If, in future, this gets fixed on its own, then don't define
99 // "use_experimental_hidden_line_hack"
100 //
101
102 #define use_experimental_hidden_line_hack
103
104 static int force_edges = 0;
105 static int disable_background = 0;
106
107 static DrvOpt cgm_options[] = { { "force_edges", DRV_INT, &force_edges, "Force edges to be drawn on filled polygongs (0|1)" },
108 { "no_paper", DRV_INT, &disable_background, "Disable background (0|1)" },
109 { NULL, DRV_INT, NULL, NULL } };
110
111
112 // Struct to hold device-specific info.
113
114 typedef struct
115 {
116 cdImagePtr im_out; // Graphics pointer
117 PLINT cgmx;
118 PLINT cgmy;
119
120 // GD does "funny" things with the colour map.
121 // It can't guarantee that the colours will be where you think they are.
122 // So we need this "colour_index" table to store where the colour we
123 // requested happens to be. Messy, but it works.
124 //
125
126 int colour_index[256]; // Colour "index" table
127
128 //
129 // I use two colours for both fill and line drawing - a "last colour" and
130 // "current colour". The driver only switches colours if they have changed
131 // and are used. If no fills are ever done, then the instruction to set the
132 // fill colour is never sent to the CGM file. Should make for smaller and
133 // more efficient files (I guess).
134 //
135
136 int colour; // Current Colour
137 int last_line_colour; // Last line colour used
138 int fill_colour; // Current Fill colour
139 int last_fill_colour; // Last Fill colour used
140
141 int totcol; // Total number of colours
142 int ncol1; // Actual size of ncol1 we got
143 int scale; // scaling factor to "blow up" to
144 // the "virtual" page in removing hidden lines
145 int force_edges; // Forces edges to be drawn in fills
146 int disable_background; // Turns off background rectangle
147 } cgm_Dev;
148
149 void plD_init_cgm( PLStream * );
150 void plD_line_cgm( PLStream *, short, short, short, short );
151 void plD_polyline_cgm( PLStream *, short *, short *, PLINT );
152 void plD_eop_cgm( PLStream * );
153 void plD_bop_cgm( PLStream * );
154 void plD_tidy_cgm( PLStream * );
155 void plD_state_cgm( PLStream *, PLINT );
156 void plD_esc_cgm( PLStream *, PLINT, void * );
157
158
159 void plD_dispatch_init_cgm( PLDispatchTable *pdt )
160 {
161 #ifndef ENABLE_DYNDRIVERS
162 pdt->pl_MenuStr = "CGM (Computer Graphics metafile) file";
163 pdt->pl_DevName = "cgm";
164 #endif
165 pdt->pl_type = plDevType_FileOriented;
166 pdt->pl_seq = 44;
167 pdt->pl_init = (plD_init_fp) plD_init_cgm;
168 pdt->pl_line = (plD_line_fp) plD_line_cgm;
169 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_cgm;
170 pdt->pl_eop = (plD_eop_fp) plD_eop_cgm;
171 pdt->pl_bop = (plD_bop_fp) plD_bop_cgm;
172 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_cgm;
173 pdt->pl_state = (plD_state_fp) plD_state_cgm;
174 pdt->pl_esc = (plD_esc_fp) plD_esc_cgm;
175 }
176
177
178 //--------------------------------------------------------------------------
179 // plD_init_cgm_Dev()
180 //
181 //--------------------------------------------------------------------------
182
183 static void
184 plD_init_cgm_Dev( PLStream *pls )
185 {
186 cgm_Dev *dev;
187
188 // Allocate and initialize device-specific data
189
190 if ( pls->dev != NULL )
191 free( (void *) pls->dev );
192
193 pls->dev = calloc( 1, (size_t) sizeof ( cgm_Dev ) );
194 if ( pls->dev == NULL )
195 plexit( "plD_init_cgm_Dev: Out of memory." );
196
197 dev = (cgm_Dev *) pls->dev;
198
199 // Check for and set up driver options
200
201 plParseDrvOpts( cgm_options );
202 dev->force_edges = force_edges; // force edges (for corel draw etc...)
203 dev->disable_background = disable_background; // Disable background
204
205 dev->colour = 1; // Set a fall back pen colour in case user doesn't
206 dev->fill_colour = dev->colour; // initially set fill and line colour the same
207 dev->last_fill_colour = -1; // set to -1 = unallocated
208 dev->last_line_colour = -1; // set to -1 = unallocated
209 }
210
211 //--------------------------------------------------------------------------
212 // plD_init_cgm()
213 //
214 // Initialize device.
215 //--------------------------------------------------------------------------
216
217 void plD_init_cgm( PLStream *pls )
218 {
219 cgm_Dev *dev = NULL;
220
221 pls->termin = 0; // Not an interactive device
222 pls->icol0 = 1;
223 pls->bytecnt = 0;
224 pls->page = 0;
225 pls->dev_fill0 = 1; // Can do solid fills
226
227 if ( !pls->colorset )
228 pls->color = 1; // Is a color device
229
230 if ( pls->width < 1 )
231 pls->width = 1; // set a legal line width
232
233 // Initialize family file info
234 plFamInit( pls );
235
236 // Prompt for a file name if not already set
237 plOpenFile( pls );
238
239 // Allocate and initialize device-specific data
240 plD_init_cgm_Dev( pls );
241 dev = (cgm_Dev *) pls->dev;
242
243 if ( pls->xlength <= 0 || pls->ylength <= 0 )
244 {
245 // use default width, height of 800x600 if not specifed by -geometry option
246 // or plspage
247 plspage( 0., 0., 800, 600, 0, 0 );
248 }
249
250 pls->graphx = GRAPHICS_MODE;
251
252 dev->cgmx = pls->xlength - 1; // should I use -1 or not???
253 dev->cgmy = pls->ylength - 1;
254
255 #ifdef use_experimental_hidden_line_hack
256
257 if ( dev->cgmx > dev->cgmy ) // Work out the scaling factor for the
258 { // "virtual" (oversized) page
259 dev->scale = ( PIXELS_X - 1 ) / dev->cgmx;
260 }
261 else
262 {
263 dev->scale = PIXELS_Y / dev->cgmy;
264 }
265 #else
266
267 dev->scale = 1;
268
269 #endif
270
271 if ( pls->xdpi <= 0 )
272 {
273 // This corresponds to a typical monitor resolution of 4 pixels/mm.
274 plspage( 4. * 25.4, 4. * 25.4, 0, 0, 0, 0 );
275 }
276 else
277 {
278 pls->ydpi = pls->xdpi; // Set X and Y dpi's to the same value
279 }
280 // Convert DPI to pixels/mm
281 plP_setpxl( dev->scale * pls->xdpi / 25.4, dev->scale * pls->ydpi / 25.4 );
282
283 plP_setphy( 0, dev->scale * dev->cgmx, 0, dev->scale * dev->cgmy );
284 }
285
286 //--------------------------------------------------------------------------
287 // plD_line_cgm()
288 //
289 // Draw a line in the current color from (x1,y1) to (x2,y2).
290 //--------------------------------------------------------------------------
291
292 void
293 plD_line_cgm( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
294 {
295 cgm_Dev *dev = (cgm_Dev *) pls->dev;
296 int x1 = x1a / dev->scale, y1 = y1a / dev->scale, x2 = x2a / dev->scale, y2 = y2a / dev->scale;
297 y1 = y1;
298 y2 = y2;
299
300 //
301 // Determine if the colour has changed since the last time a line was
302 // drawn. If it has, then set the colour NOW otherwise, keep on going like
303 // "nuthin happened".
304 //
305
306 if ( dev->last_line_colour != dev->colour )
307 {
308 cdSetLineColor( dev->im_out, dev->colour );
309 dev->last_line_colour = dev->colour;
310 }
311
312 cdLine( dev->im_out, x1, y1, x2, y2 );
313 }
314
315 //--------------------------------------------------------------------------
316 // plD_polyline_cgm()
317 //
318 // Draw a polyline in the current color.
319 //--------------------------------------------------------------------------
320
321 void
322 plD_polyline_cgm( PLStream *pls, short *xa, short *ya, PLINT npts )
323 {
324 cgm_Dev *dev = (cgm_Dev *) pls->dev;
325 PLINT i;
326 cdPoint *points = NULL;
327
328 if ( ( points = calloc( npts, (size_t) sizeof ( cdPoint ) ) ) == NULL )
329 {
330 plexit( "Memory allocation error in \"plD_polyline_cgm\"" );
331 }
332
333 for ( i = 0; i < npts; i++ )
334 {
335 points[i].x = xa[i] / dev->scale;
336 points[i].y = ( ya[i] / dev->scale );
337 }
338
339 //
340 // Determine if the colour has changed since the last time a line was
341 // drawn. If it has, then set the colour NOW otherwise, keep on going like
342 // "nuthin happened".
343 //
344
345 if ( dev->last_line_colour != dev->colour )
346 {
347 cdSetLineColor( dev->im_out, dev->colour );
348 dev->last_line_colour = dev->colour;
349 }
350
351 cdPolyLine( dev->im_out, points, npts );
352 free( points );
353 }
354
355
356 //--------------------------------------------------------------------------
357 // fill_polygon()
358 //
359 // Fill polygon described in points pls->dev_x[] and pls->dev_y[].
360 //--------------------------------------------------------------------------
361
362 static void
363 fill_polygon( PLStream *pls )
364 {
365 cgm_Dev *dev = (cgm_Dev *) pls->dev;
366
367 PLINT i;
368 cdPoint *points = NULL;
369
370 if ( pls->dev_npts < 1 )
371 return;
372
373 if ( ( points = calloc( pls->dev_npts, (size_t) sizeof ( cdPoint ) ) ) == NULL )
374 {
375 plexit( "Memory allocation error in \"plD_fill_polygon_cgm\"" );
376 }
377
378 for ( i = 0; i < pls->dev_npts; i++ )
379 {
380 points[i].x = pls->dev_x[i] / dev->scale;
381 points[i].y = ( pls->dev_y[i] / dev->scale );
382 }
383
384
385 //
386 // Determine if the fill colour has changed since the last time a fill was
387 // done. If it has, then set the colour NOW otherwise, keep on going like
388 // "nuthin happened". If it's the first time, we will know 'cause the the
389 // "last_fill_colour" will be -1.
390 //
391
392 if ( ( dev->fill_colour != dev->last_fill_colour ) || ( dev->force_edges == 1 ) )
393 {
394 cdSetFillColor( dev->im_out, dev->fill_colour );
395
396 //
397 // Due to a bug in cd V1.3, we have to set the edge colour to the fill
398 // colour. This is despite telling the library edges should be invisible.
399 // Seems the invisible edges only work with rectangles.
400 //
401
402 if ( dev->force_edges == 1 )
403 {
404 cdSetEdgeColor( dev->im_out, dev->fill_colour );
405 cdSetEdgeVis( dev->im_out, 1 );
406 }
407
408 dev->last_fill_colour = dev->fill_colour;
409 }
410
411 cdPolygon( dev->im_out, points, pls->dev_npts );
412
413 if ( dev->force_edges == 1 )
414 cdSetEdgeVis( dev->im_out, 0 ); // Turn edges off now
415
416 free( points );
417 }
418
419 //--------------------------------------------------------------------------
420 // setcmap()
421 //
422 // Sets up color palette.
423 //--------------------------------------------------------------------------
424
425 static void
426 setcmap( PLStream *pls )
427 {
428 int i, ncol1 = pls->ncol1;
429 int ncol0 = pls->ncol0, total_colours;
430 PLColor cmap1col;
431 cgm_Dev *dev = (cgm_Dev *) pls->dev;
432 PLFLT tmp_colour_pos;
433
434 cdImageColorClear( dev->im_out ); // UNDOCUMENTED FUNCTION TO RESET THE
435 // INTERNAL COLOUR TABLE OF THE
436 // CD DRIVER. Seems to work and fix
437 // the errors
438
439 if ( ncol0 > cdMaxColors / 2 ) // Check for ridiculous number of colours
440 { // in ncol0, and appropriately adjust the
441 plwarn( "Too many colours in cmap0." ); // number, issuing a
442 ncol0 = cdMaxColors / 2; // warning if it does
443 pls->ncol0 = ncol0;
444 }
445
446 dev->totcol = 0; // Reset the number of colours counter to zero
447
448 total_colours = ncol0 + ncol1; // Work out how many colours are wanted
449
450 if ( total_colours > cdMaxColors ) // Do some rather modest error
451 { // checking to make sure that
452 total_colours = cdMaxColors; // we are not defining more colours
453 ncol1 = total_colours - ncol0; // than we have room for.
454
455 if ( ncol1 <= 0 )
456 {
457 plexit( "Problem setting colourmap in CGM driver." );
458 }
459 }
460
461 dev->ncol1 = ncol1; // The actual size of ncol1, regardless of what was asked.
462 // This is dependent on colour slots available.
463 // It might well be the same as ncol1.
464 //
465
466 // Initialize cmap 0 colors
467
468 if ( ncol0 > 0 ) // make sure the program actually asked for cmap0 first
469 {
470 #ifdef SWAP_BALCK_WHEN_WHITE
471
472 //
473 // Do a kludge to add a "black" colour back to the palette if the
474 // background is "almost white" (ie changed through -bg).
475 //
476 // Also includes an "optional" change to swap the red colour (1) with the
477 // black colour (15), which is off by default. (I don't like the red being
478 // the 'default' colour "1" on a "white" background, or for that matter
479 // yellow being "2", but I can live more with yellow at number two.)
480 // Just use "-hack" from the command line to make it take effect.
481 //
482 //
483
484 if ( ( pls->ncol0 > 15 ) && ( pls->cmap0[0].r > 227 ) && ( pls->cmap0[0].g > 227 ) && ( pls->cmap0[0].b > 227 ) )
485 {
486 if ( pls->hack != 1 ) // just set colour 15 to black
487 {
488 pls->cmap0[15].r = 0;
489 pls->cmap0[15].g = 0;
490 pls->cmap0[15].b = 0;
491 }
492 else // swap colour 15 and colour 1
493 {
494 pls->cmap0[15].r = pls->cmap0[1].r;
495 pls->cmap0[15].g = pls->cmap0[1].g;
496 pls->cmap0[15].b = pls->cmap0[1].b;
497
498 pls->cmap0[1].r = 0;
499 pls->cmap0[1].g = 0;
500 pls->cmap0[1].b = 0;
501 }
502 }
503
504 #endif
505
506 for ( i = 0; i < ncol0; i++ )
507 {
508 if ( (
509 dev->colour_index[i] = cdImageColorAllocate( dev->im_out,
510 pls->cmap0[i].r, pls->cmap0[i].g, pls->cmap0[i].b )
511 ) == -1 )
512 {
513 plwarn( "Problem setting cmap0 in CGM driver." );
514 }
515 else
516 ++dev->totcol; // count the number of colours we use as we use them
517 }
518 }
519
520 // Initialize any remaining slots for cmap1
521
522
523 if ( ncol1 > 0 ) // make sure that we want to define cmap1 first
524 {
525 for ( i = 0; i < ncol1; i++ )
526 {
527 if ( ncol1 < pls->ncol1 ) // Check the dynamic range of colours
528 {
529 //
530 // Ok, now if we have less colour slots available than are being
531 // defined by pls->ncol1, then we still want to use the full
532 // dynamic range of cmap1 as best we can, so what we do is work
533 // out an approximation to the index in the full dynamic range
534 // in cases when pls->ncol1 exceeds the number of free colours.
535 //
536
537 tmp_colour_pos = i > 0 ? pls->ncol1 * ( (PLFLT) i / ncol1 ) : 0;
538 plcol_interp( pls, &cmap1col, (int) tmp_colour_pos, pls->ncol1 );
539 }
540 else
541 {
542 plcol_interp( pls, &cmap1col, i, ncol1 );
543 }
544
545
546 if ( (
547 dev->colour_index[i + pls->ncol0] = cdImageColorAllocate( dev->im_out,
548 cmap1col.r, cmap1col.g, cmap1col.b )
549 ) == -1 )
550 {
551 plwarn( "Problem setting cmap1 in CGM driver." );
552 }
553 else
554 ++dev->totcol; // count the number of colours we use as we use them
555 }
556 }
557 }
558
559
560 //--------------------------------------------------------------------------
561 // plD_state_cgm()
562 //
563 // Handle change in PLStream state (color, pen width, fill attribute, etc).
564 //--------------------------------------------------------------------------
565
566 void
567 plD_state_cgm( PLStream *pls, PLINT op )
568 {
569 cgm_Dev *dev = (cgm_Dev *) pls->dev;
570 PLFLT tmp_colour_pos;
571
572 switch ( op )
573 {
574 case PLSTATE_WIDTH:
575 cdSetLineWidth( dev->im_out, pls->width );
576 break;
577
578 case PLSTATE_COLOR0:
579 dev->colour = pls->icol0;
580 if ( dev->colour == PL_RGB_COLOR )
581 {
582 int r = pls->curcolor.r;
583 int g = pls->curcolor.g;
584 int b = pls->curcolor.b;
585 if ( dev->totcol < cdMaxColors )
586 {
587 if ( (
588 dev->colour_index[++dev->totcol] = cdImageColorAllocate( dev->im_out, r, g, b )
589 ) == -1 )
590 plwarn( "Problem changing colour in \"PLSTATE_COLOR0\"" );
591 else
592 dev->colour = dev->totcol;
593 }
594 }
595 dev->fill_colour = dev->colour;
596 break;
597
598 case PLSTATE_COLOR1:
599 //
600 // Start by checking to see if we have to compensate for cases where
601 // we don't have the full dynamic range of cmap1 at our disposal
602 //
603 if ( dev->ncol1 < pls->ncol1 )
604 {
605 tmp_colour_pos = dev->ncol1 * ( (PLFLT) pls->icol1 / ( pls->ncol1 > 0 ? pls->ncol1 : 1 ) );
606 dev->colour = pls->ncol0 + (int) tmp_colour_pos;
607 }
608 else
609 dev->colour = pls->ncol0 + pls->icol1;
610
611 dev->fill_colour = dev->colour;
612 break;
613
614
615 case PLSTATE_CMAP0:
616 case PLSTATE_CMAP1:
617 //
618 // Code to redefine the entire palette
619 //
620 if ( pls->color )
621 setcmap( pls );
622 break;
623 }
624 }
625
626
627 //--------------------------------------------------------------------------
628 // plD_esc_cgm()
629 //
630 // Escape function.
631 //--------------------------------------------------------------------------
632
633 void plD_esc_cgm( PLStream *pls, PLINT op, void *ptr )
634 {
635 switch ( op )
636 {
637 case PLESC_FILL: // fill
638 fill_polygon( pls );
639 break;
640 }
641 }
642
643 //--------------------------------------------------------------------------
644 // plD_bop_cgm()
645 //
646 // Set up for the next page.
647 // Advance to next family file if necessary (file output).
648 //--------------------------------------------------------------------------
649
650 void plD_bop_cgm( PLStream *pls )
651 {
652 cgm_Dev *dev;
653
654 plGetFam( pls );
655 // force new file if pls->family set for all subsequent calls to plGetFam
656 // n.b. putting this after plGetFam call is important since plinit calls
657 // bop, and you don't want the familying sequence started until after
658 // that first call to bop.
659
660 pls->famadv = 1;
661
662 pls->page++;
663
664 // n.b. pls->dev can change because of an indirect call to plD_init_cgm
665 // from plGetFam if familying is enabled. Thus, wait to define dev until
666 // now.
667
668 dev = (cgm_Dev *) pls->dev;
669
670 if ( pls->page == 1 )
671 {
672 dev->im_out = cdImageCreate( pls->xlength, pls->ylength );
673 }
674 else if ( pls->family != 1 )
675 {
676 cdCgmNewPic( dev->im_out, 0 );
677 }
678
679 setcmap( pls );
680
681 // Continue to initialise the driver
682
683 cdSetFillStyle( dev->im_out, 1 ); // Set solid fills
684
685 //
686 // Due to a border being drawn around the edge of the image, we also
687 // manually, then turn them off again to make edges turn off. By
688 // default the driver thinks they are off, so when we tell the driver
689 // to turn them off it says "they are already off, I wont do anything"
690 // but in reality they are on by default. So what we do is turn them ON
691 // manually, then turn them OFF later.
692 //
693 // Due to a boarder being drawn around the edge of the image, we also
694 // want the edges turned on so we can lay down a rectangle coloured in
695 // the background colour at the start. Once we have drawn our
696 // background box, we then turn edges off for the rest of the page.
697 //
698
699 cdSetEdgeVis( dev->im_out, 1 ); // turn edges on so we can turn them off!
700
701 if ( dev->disable_background != 1 )
702 {
703 cdSetEdgeWidth( dev->im_out, pls->xlength / 5 ); // set edge to *really* wide so we can cover the edge of the page completelt
704 cdSetEdgeColor( dev->im_out, 0 ); // set the edge colour to the background colour so we can make a coloured page
705 cdSetFillColor( dev->im_out, 0 ); // set fill colour to background colour so we have a coloured page
706 cdRectangle( dev->im_out, 0, 0, pls->xlength - 1, pls->ylength - 1 ); // Draw a coloured rectangle to act as our "paper"
707 }
708
709 cdSetEdgeVis( dev->im_out, 0 ); // Turn edges off now
710 cdSetEdgeWidth( dev->im_out, 0 ); // Just to be 100% sure
711
712 cdSetLineType( dev->im_out, 1 ); // set solid lines
713 cdSetLineWidth( dev->im_out, pls->width ); // set initial line width for each page
714 }
715
716 //--------------------------------------------------------------------------
717 // plD_tidy_cgm()
718 //
719 // Close graphics file or otherwise clean up.
720 //--------------------------------------------------------------------------
721
722 void plD_tidy_cgm( PLStream *pls )
723 {
724 cgm_Dev *dev = (cgm_Dev *) pls->dev;
725
726 if ( pls->family != 1 )
727 {
728 cdImageCgm( dev->im_out, pls->OutFile );
729 }
730
731 cdImageDestroy( dev->im_out );
732 plCloseFile( pls );
733 free_mem( pls->dev );
734 }
735
736 //--------------------------------------------------------------------------
737 // plD_eop_cgm()
738 //
739 // End of page.
740 //--------------------------------------------------------------------------
741
742 void plD_eop_cgm( PLStream *pls )
743 {
744 cgm_Dev *dev = (cgm_Dev *) pls->dev;
745 int i;
746
747 if ( pls->family == 1 )
748 {
749 cdImageCgm( dev->im_out, pls->OutFile );
750 }
751 for ( i = 0; i < cdMaxColors; ++i )
752 dev->colour_index[i] = -1;
753
754 dev->fill_colour = dev->colour; // initially set fill and line colour the same
755 dev->last_fill_colour = -1; // set to -1 = unallocated
756 dev->last_line_colour = -1; // set to -1 = unallocated
757 }
758
759
760 //#endif
761
762
763 #else
764 int
765 pldummy_cgm()
766 {
767 return 0;
768 }
769
770 #endif // cgm