• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

cgm.c

Go to the documentation of this file.
00001 // $Id: cgm.c 11283 2010-10-28 22:38:29Z airwin $
00002 //
00003 //      PLplot cgm device driver.
00004 //
00005 
00006 //
00007 // This driver generates CGM (computer graphics metafiles) files (bit of a
00008 // tautology that... 'computer graphics metaFILES FILES' - oh well).
00009 //
00010 // The CGM format is vector-based and is widely used as an interchange
00011 // format between drawing and plotting programs. Although I have never
00012 // looked at them, there are apparently both Java applets and browser
00013 // plug-ins for displaying CGM files on web pages.
00014 //
00015 // This plplot driver supports lines, polylines (they make a difference to
00016 // CGM files), fills, and line widths. It is limited to 256 colours, which
00017 // should not be a problem. The plplot CGM driver's source (cgm.c) was
00018 // derived largely from the gd driver (gd.c).
00019 //
00020 // The plplot driver requires libcd.a. libcd.a is very similar to libgd.a
00021 // and has a similar licencing agreement behind it. Unlike libgd,
00022 // development of libcd seems to have crawled to a halt back in 1998 with
00023 // V1.3 of the library. The original host site for the library no longer
00024 // exists, so probably the best source of the library presently is:
00025 //
00026 // http://www.pa.msu.edu/reference/cgmdraw_ref.html
00027 // http://www.pa.msu.edu/ftp/pub/unix/
00028 //
00029 
00030 //
00031 // Two options are supported by the driver via the -drvopt command line
00032 // toggle.
00033 //
00034 // By default CGM files don't have a background as such. The driver adds
00035 // support for different backgrounds by colouring in a large rectangle
00036 // underneath everything else. If for some reason you want the "raw plotted
00037 // junk" and aren't really interested in having an obtrusive piece of paper
00038 // in the back, use the command line toggle "-drvopt no_paper=1" to turn off
00039 // this background paper.
00040 //
00041 // By default the CGM files generated by this driver try to make edges of
00042 // polygons (ie fills) "invisible", which is something CGM files can do.
00043 // Some programs (ie CoreDraw) ignore this field and draw edges in anyway.
00044 // By setting "-drvopt force_edges=1" the driver will render edges on all
00045 // filled polygons, and will set their colour to the same as the polygon.
00046 // Most drivers should not need this, but if you see lines that you don't
00047 // think you should be seeing in your viewer, try this toggle.
00048 //
00049 
00050 //
00051 // Driver supports a hack that manipulates the colour palette when
00052 // a light background is selected. This is basically to make sure
00053 // there are not two "whites" when -bg ffffff is issued at the
00054 // command line.
00055 //
00056 // Related to this change, there is an ability to swap the "new"
00057 // black colour (index 15) with the red colour (index 2) by issuing
00058 // the command line "-hack" option. I like this for web pages, because
00059 // I think that black looks nicer than red (on white) for default
00060 // plotting. That is why it can be enabled with -hack, in case you
00061 // don't like it working this way.
00062 //
00063 // For me, these two changes make it easy to switch from a "screen friendly"
00064 // black background with red first plotting colour, to a "web friendly"
00065 // white background with a black first plotting colour.
00066 //
00067 // These features are enabled on a driver level by defining
00068 // "SWAP_BALCK_WHEN_WHITE". If you wan't the driver to behave 100% like other
00069 // drivers, comment out the define
00070 //
00071 
00072 #define SWAP_BALCK_WHEN_WHITE
00073 
00074 #include "plDevs.h"
00075 
00076 #ifdef PLD_cgm
00077 
00078 #include "plplotP.h"
00079 #include "drivers.h"
00080 
00081 #include <cd.h>
00082 
00083 // Device info
00084 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_cgm = "cgm:CGM file:0:cgm:44:cgm\n";
00085 
00086 // Prototypes for functions in this file.
00087 
00088 static void     fill_polygon( PLStream *pls );
00089 static void     setcmap( PLStream *pls );
00090 static void     plD_init_cgm_Dev( PLStream *pls );
00091 
00092 // top level declarations
00093 
00094 // In an attempt to fix a problem with the hidden line removal functions
00095 // that results in hidden lines *not* being removed from "small" plot
00096 // pages (ie, like a normal video screen), a "virtual" page of much
00097 // greater size is used to trick the algorithm into working correctly.
00098 // If, in future, this gets fixed on its own, then don't define
00099 // "use_experimental_hidden_line_hack"
00100 //
00101 
00102 #define use_experimental_hidden_line_hack
00103 
00104 static int    force_edges        = 0;
00105 static int    disable_background = 0;
00106 
00107 static DrvOpt cgm_options[] = { { "force_edges", DRV_INT, &force_edges,        "Force edges to be drawn on filled polygongs (0|1)" },
00108                                 { "no_paper",    DRV_INT, &disable_background, "Disable background (0|1)"                          },
00109                                 { NULL,          DRV_INT, NULL,                NULL                                                } };
00110 
00111 
00112 // Struct to hold device-specific info.
00113 
00114 typedef struct
00115 {
00116     cdImagePtr im_out;                          // Graphics pointer
00117     PLINT      cgmx;
00118     PLINT      cgmy;
00119 
00120 // GD does "funny" things with the colour map.
00121 // It can't guarantee that the colours will be where you think they are.
00122 // So we need this "colour_index" table to store where the colour we
00123 // requested happens to be. Messy, but it works.
00124 //
00125 
00126     int colour_index[256];                      // Colour "index" table
00127 
00128 //
00129 // I use two colours for both fill and line drawing - a "last colour" and
00130 // "current colour". The driver only switches colours if they have changed
00131 // and are used. If no fills are ever done, then the instruction to set the
00132 // fill colour is never sent to the CGM file. Should make for smaller and
00133 // more efficient files (I guess).
00134 //
00135 
00136     int colour;                                 // Current Colour
00137     int last_line_colour;                       // Last line colour used
00138     int fill_colour;                            // Current Fill colour
00139     int last_fill_colour;                       // Last Fill colour used
00140 
00141     int totcol;                                 // Total number of colours
00142     int ncol1;                                  // Actual size of ncol1 we got
00143     int scale;                                  // scaling factor to "blow up" to
00144                                                 // the "virtual" page in removing hidden lines
00145     int force_edges;                            // Forces edges to be drawn in fills
00146     int disable_background;                     // Turns off background rectangle
00147 } cgm_Dev;
00148 
00149 void plD_init_cgm( PLStream * );
00150 void plD_line_cgm( PLStream *, short, short, short, short );
00151 void plD_polyline_cgm( PLStream *, short *, short *, PLINT );
00152 void plD_eop_cgm( PLStream * );
00153 void plD_bop_cgm( PLStream * );
00154 void plD_tidy_cgm( PLStream * );
00155 void plD_state_cgm( PLStream *, PLINT );
00156 void plD_esc_cgm( PLStream *, PLINT, void * );
00157 
00158 
00159 void plD_dispatch_init_cgm( PLDispatchTable *pdt )
00160 {
00161 #ifndef ENABLE_DYNDRIVERS
00162     pdt->pl_MenuStr = "CGM (Computer Graphics metafile) file";
00163     pdt->pl_DevName = "cgm";
00164 #endif
00165     pdt->pl_type     = plDevType_FileOriented;
00166     pdt->pl_seq      = 44;
00167     pdt->pl_init     = (plD_init_fp) plD_init_cgm;
00168     pdt->pl_line     = (plD_line_fp) plD_line_cgm;
00169     pdt->pl_polyline = (plD_polyline_fp) plD_polyline_cgm;
00170     pdt->pl_eop      = (plD_eop_fp) plD_eop_cgm;
00171     pdt->pl_bop      = (plD_bop_fp) plD_bop_cgm;
00172     pdt->pl_tidy     = (plD_tidy_fp) plD_tidy_cgm;
00173     pdt->pl_state    = (plD_state_fp) plD_state_cgm;
00174     pdt->pl_esc      = (plD_esc_fp) plD_esc_cgm;
00175 }
00176 
00177 
00178 //--------------------------------------------------------------------------
00179 // plD_init_cgm_Dev()
00180 //
00181 //--------------------------------------------------------------------------
00182 
00183 static void
00184 plD_init_cgm_Dev( PLStream *pls )
00185 {
00186     cgm_Dev *dev;
00187 
00188 // Allocate and initialize device-specific data
00189 
00190     if ( pls->dev != NULL )
00191         free( (void *) pls->dev );
00192 
00193     pls->dev = calloc( 1, (size_t) sizeof ( cgm_Dev ) );
00194     if ( pls->dev == NULL )
00195         plexit( "plD_init_cgm_Dev: Out of memory." );
00196 
00197     dev = (cgm_Dev *) pls->dev;
00198 
00199 // Check for and set up driver options
00200 
00201     plParseDrvOpts( cgm_options );
00202     dev->force_edges        = force_edges;        // force edges (for corel draw etc...)
00203     dev->disable_background = disable_background; // Disable background
00204 
00205     dev->colour           = 1;                    // Set a fall back pen colour in case user doesn't
00206     dev->fill_colour      = dev->colour;          // initially set fill and line colour the same
00207     dev->last_fill_colour = -1;                   // set to -1 = unallocated
00208     dev->last_line_colour = -1;                   // set to -1 = unallocated
00209 }
00210 
00211 //--------------------------------------------------------------------------
00212 // plD_init_cgm()
00213 //
00214 // Initialize device.
00215 //--------------------------------------------------------------------------
00216 
00217 void plD_init_cgm( PLStream *pls )
00218 {
00219     cgm_Dev *dev = NULL;
00220 
00221     pls->termin    = 0;         // Not an interactive device
00222     pls->icol0     = 1;
00223     pls->bytecnt   = 0;
00224     pls->page      = 0;
00225     pls->dev_fill0 = 1;         // Can do solid fills
00226 
00227     if ( !pls->colorset )
00228         pls->color = 1;                       // Is a color device
00229 
00230     if ( pls->width < 1 )
00231         pls->width = 1;                       // set a legal line width
00232 
00233 // Initialize family file info
00234     plFamInit( pls );
00235 
00236 // Prompt for a file name if not already set
00237     plOpenFile( pls );
00238 
00239 // Allocate and initialize device-specific data
00240     plD_init_cgm_Dev( pls );
00241     dev = (cgm_Dev *) pls->dev;
00242 
00243     if ( pls->xlength <= 0 || pls->ylength <= 0 )
00244     {
00245 // use default width, height of 800x600 if not specifed by -geometry option
00246 // or plspage
00247         plspage( 0., 0., 800, 600, 0, 0 );
00248     }
00249 
00250     pls->graphx = GRAPHICS_MODE;
00251 
00252     dev->cgmx = pls->xlength - 1;       // should I use -1 or not???
00253     dev->cgmy = pls->ylength - 1;
00254 
00255 #ifdef use_experimental_hidden_line_hack
00256 
00257     if ( dev->cgmx > dev->cgmy ) // Work out the scaling factor for the
00258     {                            // "virtual" (oversized) page
00259         dev->scale = ( PIXELS_X - 1 ) / dev->cgmx;
00260     }
00261     else
00262     {
00263         dev->scale = PIXELS_Y / dev->cgmy;
00264     }
00265 #else
00266 
00267     dev->scale = 1;
00268 
00269 #endif
00270 
00271     if ( pls->xdpi <= 0 )
00272     {
00273 // This corresponds to a typical monitor resolution of 4 pixels/mm.
00274         plspage( 4. * 25.4, 4. * 25.4, 0, 0, 0, 0 );
00275     }
00276     else
00277     {
00278         pls->ydpi = pls->xdpi;        // Set X and Y dpi's to the same value
00279     }
00280 // Convert DPI to pixels/mm
00281     plP_setpxl( dev->scale * pls->xdpi / 25.4, dev->scale * pls->ydpi / 25.4 );
00282 
00283     plP_setphy( 0, dev->scale * dev->cgmx, 0, dev->scale * dev->cgmy );
00284 }
00285 
00286 //--------------------------------------------------------------------------
00287 // plD_line_cgm()
00288 //
00289 // Draw a line in the current color from (x1,y1) to (x2,y2).
00290 //--------------------------------------------------------------------------
00291 
00292 void
00293 plD_line_cgm( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
00294 {
00295     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00296     int     x1   = x1a / dev->scale, y1 = y1a / dev->scale, x2 = x2a / dev->scale, y2 = y2a / dev->scale;
00297     y1 = y1;
00298     y2 = y2;
00299 
00300 //
00301 // Determine if the colour has changed since the last time a line was
00302 // drawn. If it has, then set the colour NOW otherwise, keep on going like
00303 // "nuthin happened".
00304 //
00305 
00306     if ( dev->last_line_colour != dev->colour )
00307     {
00308         cdSetLineColor( dev->im_out, dev->colour );
00309         dev->last_line_colour = dev->colour;
00310     }
00311 
00312     cdLine( dev->im_out, x1, y1, x2, y2 );
00313 }
00314 
00315 //--------------------------------------------------------------------------
00316 // plD_polyline_cgm()
00317 //
00318 // Draw a polyline in the current color.
00319 //--------------------------------------------------------------------------
00320 
00321 void
00322 plD_polyline_cgm( PLStream *pls, short *xa, short *ya, PLINT npts )
00323 {
00324     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00325     PLINT   i;
00326     cdPoint *points = NULL;
00327 
00328     if ( ( points = calloc( npts, (size_t) sizeof ( cdPoint ) ) ) == NULL )
00329     {
00330         plexit( "Memory allocation error in \"plD_polyline_cgm\"" );
00331     }
00332 
00333     for ( i = 0; i < npts; i++ )
00334     {
00335         points[i].x = xa[i] / dev->scale;
00336         points[i].y = ( ya[i] / dev->scale );
00337     }
00338 
00339 //
00340 // Determine if the colour has changed since the last time a line was
00341 // drawn. If it has, then set the colour NOW otherwise, keep on going like
00342 // "nuthin happened".
00343 //
00344 
00345     if ( dev->last_line_colour != dev->colour )
00346     {
00347         cdSetLineColor( dev->im_out, dev->colour );
00348         dev->last_line_colour = dev->colour;
00349     }
00350 
00351     cdPolyLine( dev->im_out, points, npts );
00352     free( points );
00353 }
00354 
00355 
00356 //--------------------------------------------------------------------------
00357 // fill_polygon()
00358 //
00359 // Fill polygon described in points pls->dev_x[] and pls->dev_y[].
00360 //--------------------------------------------------------------------------
00361 
00362 static void
00363 fill_polygon( PLStream *pls )
00364 {
00365     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00366 
00367     PLINT   i;
00368     cdPoint *points = NULL;
00369 
00370     if ( pls->dev_npts < 1 )
00371         return;
00372 
00373     if ( ( points = calloc( pls->dev_npts, (size_t) sizeof ( cdPoint ) ) ) == NULL )
00374     {
00375         plexit( "Memory allocation error in \"plD_fill_polygon_cgm\"" );
00376     }
00377 
00378     for ( i = 0; i < pls->dev_npts; i++ )
00379     {
00380         points[i].x = pls->dev_x[i] / dev->scale;
00381         points[i].y = ( pls->dev_y[i] / dev->scale );
00382     }
00383 
00384 
00385 //
00386 // Determine if the fill colour has changed since the last time a fill was
00387 // done. If it has, then set the colour NOW otherwise, keep on going like
00388 // "nuthin happened". If it's the first time, we will know 'cause the the
00389 // "last_fill_colour" will be -1.
00390 //
00391 
00392     if ( ( dev->fill_colour != dev->last_fill_colour ) || ( dev->force_edges == 1 ) )
00393     {
00394         cdSetFillColor( dev->im_out, dev->fill_colour );
00395 
00396 //
00397 // Due to a bug in cd V1.3, we have to set the edge colour to the fill
00398 // colour. This is despite telling the library edges should be invisible.
00399 // Seems the invisible edges only work with rectangles.
00400 //
00401 
00402         if ( dev->force_edges == 1 )
00403         {
00404             cdSetEdgeColor( dev->im_out, dev->fill_colour );
00405             cdSetEdgeVis( dev->im_out, 1 );
00406         }
00407 
00408         dev->last_fill_colour = dev->fill_colour;
00409     }
00410 
00411     cdPolygon( dev->im_out, points, pls->dev_npts );
00412 
00413     if ( dev->force_edges == 1 )
00414         cdSetEdgeVis( dev->im_out, 0 );                          // Turn edges off now
00415 
00416     free( points );
00417 }
00418 
00419 //--------------------------------------------------------------------------
00420 // setcmap()
00421 //
00422 // Sets up color palette.
00423 //--------------------------------------------------------------------------
00424 
00425 static void
00426 setcmap( PLStream *pls )
00427 {
00428     int     i, ncol1 = pls->ncol1;
00429     int     ncol0 = pls->ncol0, total_colours;
00430     PLColor cmap1col;
00431     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00432     PLFLT   tmp_colour_pos;
00433 
00434     cdImageColorClear( dev->im_out );           // UNDOCUMENTED FUNCTION TO RESET THE
00435     // INTERNAL COLOUR TABLE OF THE
00436     // CD DRIVER. Seems to work and fix
00437     // the errors
00438 
00439     if ( ncol0 > cdMaxColors / 2 )              // Check for ridiculous number of colours
00440     {                                           // in ncol0, and appropriately adjust the
00441         plwarn( "Too many colours in cmap0." ); // number, issuing a
00442         ncol0      = cdMaxColors / 2;           // warning if it does
00443         pls->ncol0 = ncol0;
00444     }
00445 
00446     dev->totcol = 0;                           // Reset the number of colours counter to zero
00447 
00448     total_colours = ncol0 + ncol1;             // Work out how many colours are wanted
00449 
00450     if ( total_colours > cdMaxColors )         // Do some rather modest error
00451     {                                          // checking to make sure that
00452         total_colours = cdMaxColors;           // we are not defining more colours
00453         ncol1         = total_colours - ncol0; // than we have room for.
00454 
00455         if ( ncol1 <= 0 )
00456         {
00457             plexit( "Problem setting colourmap in CGM driver." );
00458         }
00459     }
00460 
00461     dev->ncol1 = ncol1; // The actual size of ncol1, regardless of what was asked.
00462                         // This is dependent on colour slots available.
00463                         // It might well be the same as ncol1.
00464                         //
00465 
00466 // Initialize cmap 0 colors
00467 
00468     if ( ncol0 > 0 ) // make sure the program actually asked for cmap0 first
00469     {
00470 #ifdef SWAP_BALCK_WHEN_WHITE
00471 
00472 //
00473 // Do a kludge to add a "black" colour back to the palette if the
00474 // background is "almost white" (ie changed through -bg).
00475 //
00476 // Also includes an "optional" change to swap the red colour (1) with the
00477 // black colour (15), which is off by default. (I don't like the red being
00478 // the 'default' colour "1" on a "white" background, or for that matter
00479 // yellow being "2", but I can live more with yellow at number two.)
00480 // Just use "-hack" from the command line to make it take effect.
00481 //
00482 //
00483 
00484         if ( ( pls->ncol0 > 15 ) && ( pls->cmap0[0].r > 227 ) && ( pls->cmap0[0].g > 227 ) && ( pls->cmap0[0].b > 227 ) )
00485         {
00486             if ( pls->hack != 1 ) // just set colour 15 to black
00487             {
00488                 pls->cmap0[15].r = 0;
00489                 pls->cmap0[15].g = 0;
00490                 pls->cmap0[15].b = 0;
00491             }
00492             else // swap colour 15 and colour 1
00493             {
00494                 pls->cmap0[15].r = pls->cmap0[1].r;
00495                 pls->cmap0[15].g = pls->cmap0[1].g;
00496                 pls->cmap0[15].b = pls->cmap0[1].b;
00497 
00498                 pls->cmap0[1].r = 0;
00499                 pls->cmap0[1].g = 0;
00500                 pls->cmap0[1].b = 0;
00501             }
00502         }
00503 
00504 #endif
00505 
00506         for ( i = 0; i < ncol0; i++ )
00507         {
00508             if ( (
00509                      dev->colour_index[i] = cdImageColorAllocate( dev->im_out,
00510                          pls->cmap0[i].r, pls->cmap0[i].g, pls->cmap0[i].b )
00511                      ) == -1 )
00512             {
00513                 plwarn( "Problem setting cmap0 in CGM driver." );
00514             }
00515             else
00516                 ++dev->totcol; // count the number of colours we use as we use them
00517         }
00518     }
00519 
00520 // Initialize any remaining slots for cmap1
00521 
00522 
00523     if ( ncol1 > 0 ) // make sure that we want to define cmap1 first
00524     {
00525         for ( i = 0; i < ncol1; i++ )
00526         {
00527             if ( ncol1 < pls->ncol1 ) // Check the dynamic range of colours
00528             {
00529                 //
00530                 // Ok, now if we have less colour slots available than are being
00531                 // defined by pls->ncol1, then we still want to use the full
00532                 // dynamic range of cmap1 as best we can, so what we do is work
00533                 // out an approximation to the index in the full dynamic range
00534                 // in cases when pls->ncol1 exceeds the number of free colours.
00535                 //
00536 
00537                 tmp_colour_pos = i > 0 ? pls->ncol1 * ( (PLFLT) i / ncol1 ) : 0;
00538                 plcol_interp( pls, &cmap1col, (int) tmp_colour_pos, pls->ncol1 );
00539             }
00540             else
00541             {
00542                 plcol_interp( pls, &cmap1col, i, ncol1 );
00543             }
00544 
00545 
00546             if ( (
00547                      dev->colour_index[i + pls->ncol0] = cdImageColorAllocate( dev->im_out,
00548                          cmap1col.r, cmap1col.g, cmap1col.b )
00549                      ) == -1 )
00550             {
00551                 plwarn( "Problem setting cmap1 in CGM driver." );
00552             }
00553             else
00554                 ++dev->totcol; // count the number of colours we use as we use them
00555         }
00556     }
00557 }
00558 
00559 
00560 //--------------------------------------------------------------------------
00561 // plD_state_cgm()
00562 //
00563 // Handle change in PLStream state (color, pen width, fill attribute, etc).
00564 //--------------------------------------------------------------------------
00565 
00566 void
00567 plD_state_cgm( PLStream *pls, PLINT op )
00568 {
00569     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00570     PLFLT   tmp_colour_pos;
00571 
00572     switch ( op )
00573     {
00574     case PLSTATE_WIDTH:
00575         cdSetLineWidth( dev->im_out, pls->width );
00576         break;
00577 
00578     case PLSTATE_COLOR0:
00579         dev->colour = pls->icol0;
00580         if ( dev->colour == PL_RGB_COLOR )
00581         {
00582             int r = pls->curcolor.r;
00583             int g = pls->curcolor.g;
00584             int b = pls->curcolor.b;
00585             if ( dev->totcol < cdMaxColors )
00586             {
00587                 if ( (
00588                          dev->colour_index[++dev->totcol] = cdImageColorAllocate( dev->im_out, r, g, b )
00589                          ) == -1 )
00590                     plwarn( "Problem changing colour in \"PLSTATE_COLOR0\"" );
00591                 else
00592                     dev->colour = dev->totcol;
00593             }
00594         }
00595         dev->fill_colour = dev->colour;
00596         break;
00597 
00598     case PLSTATE_COLOR1:
00599         //
00600         // Start by checking to see if we have to compensate for cases where
00601         // we don't have the full dynamic range of cmap1 at our disposal
00602         //
00603         if ( dev->ncol1 < pls->ncol1 )
00604         {
00605             tmp_colour_pos = dev->ncol1 * ( (PLFLT) pls->icol1 / ( pls->ncol1 > 0 ? pls->ncol1 : 1 ) );
00606             dev->colour    = pls->ncol0 + (int) tmp_colour_pos;
00607         }
00608         else
00609             dev->colour = pls->ncol0 + pls->icol1;
00610 
00611         dev->fill_colour = dev->colour;
00612         break;
00613 
00614 
00615     case PLSTATE_CMAP0:
00616     case PLSTATE_CMAP1:
00617         //
00618         //  Code to redefine the entire palette
00619         //
00620         if ( pls->color )
00621             setcmap( pls );
00622         break;
00623     }
00624 }
00625 
00626 
00627 //--------------------------------------------------------------------------
00628 // plD_esc_cgm()
00629 //
00630 // Escape function.
00631 //--------------------------------------------------------------------------
00632 
00633 void plD_esc_cgm( PLStream *pls, PLINT op, void *ptr )
00634 {
00635     switch ( op )
00636     {
00637     case PLESC_FILL:    // fill
00638         fill_polygon( pls );
00639         break;
00640     }
00641 }
00642 
00643 //--------------------------------------------------------------------------
00644 // plD_bop_cgm()
00645 //
00646 // Set up for the next page.
00647 // Advance to next family file if necessary (file output).
00648 //--------------------------------------------------------------------------
00649 
00650 void plD_bop_cgm( PLStream *pls )
00651 {
00652     cgm_Dev *dev;
00653 
00654     plGetFam( pls );
00655 // force new file if pls->family set for all subsequent calls to plGetFam
00656 // n.b. putting this after plGetFam call is important since plinit calls
00657 // bop, and you don't want the familying sequence started until after
00658 // that first call to bop.
00659 
00660     pls->famadv = 1;
00661 
00662     pls->page++;
00663 
00664 // n.b. pls->dev can change because of an indirect call to plD_init_cgm
00665 // from plGetFam if familying is enabled.  Thus, wait to define dev until
00666 // now.
00667 
00668     dev = (cgm_Dev *) pls->dev;
00669 
00670     if ( pls->page == 1 )
00671     {
00672         dev->im_out = cdImageCreate( pls->xlength, pls->ylength );
00673     }
00674     else if ( pls->family != 1 )
00675     {
00676         cdCgmNewPic( dev->im_out, 0 );
00677     }
00678 
00679     setcmap( pls );
00680 
00681 // Continue to initialise the driver
00682 
00683     cdSetFillStyle( dev->im_out, 1 ); // Set solid fills
00684 
00685 //
00686 // Due to a border being drawn around the edge of the image, we also
00687 // manually, then turn them off again to make edges turn off. By
00688 // default the driver thinks they are off, so when we tell the driver
00689 // to turn them off it says "they are already off, I wont do anything"
00690 // but in reality they are on by default. So what we do is turn them ON
00691 // manually, then turn them OFF later.
00692 //
00693 // Due to a boarder being drawn around the edge of the image, we also
00694 // want the edges turned on so we can lay down a rectangle coloured in
00695 // the background colour at the start. Once we have drawn our
00696 // background box, we then turn edges off for the rest of the page.
00697 //
00698 
00699     cdSetEdgeVis( dev->im_out, 1 ); // turn edges on so we can turn them off!
00700 
00701     if ( dev->disable_background != 1 )
00702     {
00703         cdSetEdgeWidth( dev->im_out, pls->xlength / 5 );                      // set edge to *really* wide so we can cover the edge of the page completelt
00704         cdSetEdgeColor( dev->im_out, 0 );                                     // set the edge colour to the background colour so we can make a coloured page
00705         cdSetFillColor( dev->im_out, 0 );                                     // set fill colour to background colour so we have a coloured page
00706         cdRectangle( dev->im_out, 0, 0, pls->xlength - 1, pls->ylength - 1 ); // Draw a coloured rectangle to act as our "paper"
00707     }
00708 
00709     cdSetEdgeVis( dev->im_out, 0 );            // Turn edges off now
00710     cdSetEdgeWidth( dev->im_out, 0 );          // Just to be 100% sure
00711 
00712     cdSetLineType( dev->im_out, 1 );           // set solid lines
00713     cdSetLineWidth( dev->im_out, pls->width ); // set initial line width for each page
00714 }
00715 
00716 //--------------------------------------------------------------------------
00717 // plD_tidy_cgm()
00718 //
00719 // Close graphics file or otherwise clean up.
00720 //--------------------------------------------------------------------------
00721 
00722 void plD_tidy_cgm( PLStream *pls )
00723 {
00724     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00725 
00726     if ( pls->family != 1 )
00727     {
00728         cdImageCgm( dev->im_out, pls->OutFile );
00729     }
00730 
00731     cdImageDestroy( dev->im_out );
00732     plCloseFile( pls );
00733     free_mem( pls->dev );
00734 }
00735 
00736 //--------------------------------------------------------------------------
00737 // plD_eop_cgm()
00738 //
00739 // End of page.
00740 //--------------------------------------------------------------------------
00741 
00742 void plD_eop_cgm( PLStream *pls )
00743 {
00744     cgm_Dev *dev = (cgm_Dev *) pls->dev;
00745     int     i;
00746 
00747     if ( pls->family == 1 )
00748     {
00749         cdImageCgm( dev->im_out, pls->OutFile );
00750     }
00751     for ( i = 0; i < cdMaxColors; ++i )
00752         dev->colour_index[i] = -1;
00753 
00754     dev->fill_colour      = dev->colour; // initially set fill and line colour the same
00755     dev->last_fill_colour = -1;          // set to -1 = unallocated
00756     dev->last_line_colour = -1;          // set to -1 = unallocated
00757 }
00758 
00759 
00760 //#endif
00761 
00762 
00763 #else
00764 int
00765 pldummy_cgm()
00766 {
00767     return 0;
00768 }
00769 
00770 #endif                          // cgm

Generated on Wed Oct 12 2011 20:42:21 for PLplot by  doxygen 1.7.1