From: <hez...@us...> - 2011-05-17 22:16:42
|
Revision: 11752 http://plplot.svn.sourceforge.net/plplot/?rev=11752&view=rev Author: hezekiahcarty Date: 2011-05-17 22:16:36 +0000 (Tue, 17 May 2011) Log Message: ----------- Add drawing mode setting/getting support for Cairo output devices There are a few changes in how transparent colors are handled by the xcairo device in order to keep output consistent with the other Cairo devices. This should not affect any of the existing examples, and it may fix/avoid some potential rendering bugs which could come up with the xcairo device. Modified Paths: -------------- trunk/drivers/cairo.c Modified: trunk/drivers/cairo.c =================================================================== --- trunk/drivers/cairo.c 2011-05-17 22:16:30 UTC (rev 11751) +++ trunk/drivers/cairo.c 2011-05-17 22:16:36 UTC (rev 11752) @@ -253,6 +253,9 @@ // Rasterization of plotted material static void start_raster( PLStream* ); static void end_raster( PLStream* ); +// Get/set drawing mode +static void set_mode( PLStream*, PLINT* ); +static void get_mode( PLStream*, PLINT* ); // PLplot interface functions @@ -565,10 +568,76 @@ case PLESC_ARC: // Draw an arc, either filled or outline arc( pls, (arc_struct *) ptr ); break; + case PLESC_MODESET: // Set drawing mode + set_mode( pls, (int *) ptr ); + break; + case PLESC_MODEGET: // Get drawing mode + get_mode( pls, (int *) ptr ); + break; } } + //-------------------------------------------------------------------------- +// set_mode +// +// Set drawing mode. +//-------------------------------------------------------------------------- +void set_mode( PLStream *pls, PLINT *mode ) +{ + PLCairo *aStream; + + aStream = (PLCairo *) pls->dev; + + switch ( *mode ) + { + case PL_MODE_UNKNOWN: // Invalid - do nothing + break; + case PL_MODE_DEFAULT: + cairo_set_operator( aStream->cairoContext, CAIRO_OPERATOR_OVER ); + break; + case PL_MODE_REPLACE: + cairo_set_operator( aStream->cairoContext, CAIRO_OPERATOR_SOURCE ); + break; + case PL_MODE_XOR: + cairo_set_operator( aStream->cairoContext, CAIRO_OPERATOR_XOR ); + break; + } + return; +} + +//-------------------------------------------------------------------------- +// get_mode +// +// Get drawing mode. +//-------------------------------------------------------------------------- +void get_mode( PLStream *pls, PLINT *mode ) +{ + PLCairo *aStream; + cairo_operator_t op; + + aStream = (PLCairo *) pls->dev; + + op = cairo_get_operator( aStream->cairoContext ); + + switch ( op ) + { + case CAIRO_OPERATOR_OVER: + *mode = PL_MODE_DEFAULT; + break; + case CAIRO_OPERATOR_SOURCE: + *mode = PL_MODE_REPLACE; + break; + case CAIRO_OPERATOR_XOR: + *mode = PL_MODE_XOR; + break; + default: + *mode = PL_MODE_UNKNOWN; + } + return; +} + +//-------------------------------------------------------------------------- // text_begin_cairo() // // Begin text. @@ -1147,6 +1216,7 @@ pls->dev_arc = 1; // Supports driver-level arcs pls->plbuf_write = interactive; // Activate plot buffer pls->has_string_length = 1; // Driver supports string length calculations + pls->dev_modeset = 1; // Driver supports drawing mode setting if ( pls->xlength <= 0 || pls->ylength <= 0 ) { @@ -1290,8 +1360,6 @@ // Draw the polygons poly_line( pls, xa, ya, npts ); - cairo_set_operator( aStream->cairoContext, CAIRO_OPERATOR_OVER ); - cairo_set_source_rgba( aStream->cairoContext, (double) pls->curcolor.r / 255.0, (double) pls->curcolor.g / 255.0, @@ -1597,14 +1665,14 @@ // This is the Cairo surface PLplot will actually plot to. if ( aStream->image_buffering == 0 ) { - aStream->cairoSurface = cairo_surface_create_similar( aStream->cairoSurface_X, CAIRO_CONTENT_COLOR, pls->xlength, pls->ylength ); + aStream->cairoSurface = cairo_surface_create_similar( aStream->cairoSurface_X, CAIRO_CONTENT_COLOR_ALPHA, pls->xlength, pls->ylength ); aStream->cairoContext = cairo_create( aStream->cairoSurface ); } else { // Plot to an off-screen image aStream->cairoSurface = - cairo_image_surface_create( CAIRO_FORMAT_RGB24, + cairo_image_surface_create( CAIRO_FORMAT_ARGB32, pls->xlength, pls->ylength ); aStream->cairoContext = cairo_create( aStream->cairoSurface ); } @@ -1690,13 +1758,31 @@ //-------------------------------------------------------------------------- // blit_to_x() // +// // Blit the offscreen image to the X window. //-------------------------------------------------------------------------- -void blit_to_x( PLCairo *aStream, double x, double y, double w, double h ) +void blit_to_x( PLStream *pls, double x, double y, double w, double h ) { + PLCairo *aStream; + + aStream = pls->dev; + + cairo_save( aStream->cairoContext ); + // "Flatten" any transparent regions to look like they were drawn over the + // correct background color + cairo_rectangle( aStream->cairoContext, x, y, w, h ); + cairo_set_operator( aStream->cairoContext, CAIRO_OPERATOR_DEST_OVER ); + cairo_set_source_rgba( aStream->cairoContext, + (double) pls->cmap0[0].r / 255.0, + (double) pls->cmap0[0].g / 255.0, + (double) pls->cmap0[0].b / 255.0, + (double) pls->cmap0[0].a ); + cairo_fill( aStream->cairoContext ); + cairo_restore( aStream->cairoContext ); + + cairo_save( aStream->cairoContext_X ); // Copy a portion of the surface - cairo_save( aStream->cairoContext_X ); cairo_rectangle( aStream->cairoContext_X, x, y, w, h ); cairo_set_operator( aStream->cairoContext_X, CAIRO_OPERATOR_SOURCE ); cairo_set_source_surface( aStream->cairoContext_X, @@ -1753,7 +1839,7 @@ return; // Blit the offscreen image to the X window. - blit_to_x( aStream, 0.0, 0.0, pls->xlength, pls->ylength ); + blit_to_x( pls, 0.0, 0.0, pls->xlength, pls->ylength ); if ( aStream->xdrawable_mode ) return; @@ -1794,7 +1880,7 @@ expose = (XExposeEvent *) &event; if ( expose->count == 0 ) { - blit_to_x( aStream, expose->x, expose->y, + blit_to_x( pls, expose->x, expose->y, expose->width, expose->height ); } break; @@ -1850,11 +1936,11 @@ switch ( op ) { case PLESC_FLUSH: // forced update of the window - blit_to_x( aStream, 0.0, 0.0, pls->xlength, pls->ylength ); + blit_to_x( pls, 0.0, 0.0, pls->xlength, pls->ylength ); XFlush( aStream->XDisplay ); break; case PLESC_GETC: // get cursor position - blit_to_x( aStream, 0.0, 0.0, pls->xlength, pls->ylength ); + blit_to_x( pls, 0.0, 0.0, pls->xlength, pls->ylength ); XFlush( aStream->XDisplay ); xcairo_get_cursor( pls, (PLGraphicsIn*) ptr ); break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |