PLplot: cgm.c Source File

PLplot 5.15.0

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