35 #include <pango/pangocairo.h>
44 #if defined ( PLD_wincairo )
47 #if defined ( PLD_xcairo )
48 #include <cairo-xlib.h>
51 #include <X11/Xutil.h>
52 #include <X11/cursorfont.h>
53 #include <X11/keysym.h>
55 #if defined ( PLD_pdfcairo )
56 #include <cairo-pdf.h>
58 #if defined ( PLD_pscairo )
61 #if defined ( PLD_svgcairo )
62 #include <cairo-svg.h>
71 #define PLCAIRO_DEFAULT_X 720
72 #define PLCAIRO_DEFAULT_Y 540
74 #define MAX_STRING_LEN 500
75 #define MAX_MARKUP_LEN MAX_STRING_LEN * 10
87 {
"text_anti_aliasing",
DRV_INT, &
text_anti_aliasing,
"Set desired text anti-aliasing (text_anti_aliasing=0|1|2|3). The numbers are in the same order as the cairo_antialias_t enumeration documented at http://cairographics.org/manual/cairo-cairo-t.html#cairo-antialias-t)" },
88 {
"graphics_anti_aliasing",
DRV_INT, &
graphics_anti_aliasing,
"Set desired graphics anti-aliasing (graphics_anti_aliasing=0|1|2|3). The numbers are in the same order as the cairo_antialias_t enumeration documented at http://cairographics.org/manual/cairo-cairo-t.html#cairo-antialias-t" },
90 {
"rasterize_image",
DRV_INT, &
rasterize_image,
"Raster or vector image rendering (rasterize_image=0|1)" },
91 {
"set_background",
DRV_INT, &
set_background,
"Set the background for the extcairo device (set_background=0|1). If 1 then the plot background will set by PLplot" },
92 {
"image_buffering",
DRV_INT, &
image_buffering,
"Buffered offscreen rendering for the xcairo device (image_buffering=0|1)." },
93 { NULL,
DRV_INT, NULL, NULL } };
122 #if defined ( PLD_xcairo )
123 cairo_surface_t *cairoSurface_X;
124 cairo_t *cairoContext_X;
125 short exit_event_loop;
128 unsigned int xdrawable_mode;
130 #if defined ( PLD_memcairo )
131 unsigned char *memory;
132 unsigned char *cairo_format_memory;
135 #if defined ( PLD_wincairo )
136 cairo_surface_t *cairoSurface_win;
137 cairo_t *cairoContext_win;
149 #if defined ( PLD_xcairo )
150 "xcairo:Cairo X Windows Driver:1:cairo:100:xcairo\n"
152 #if defined ( PLD_pdfcairo )
153 "pdfcairo:Cairo PDF Driver:0:cairo:101:pdfcairo\n"
155 #if defined ( PLD_pscairo )
156 "pscairo:Cairo PS Driver:0:cairo:102:pscairo\n"
158 #if defined ( PLD_epscairo )
159 "epscairo:Cairo EPS Driver:0:cairo:103:epscairo\n"
161 #if defined ( PLD_svgcairo )
162 "svgcairo:Cairo SVG Driver:0:cairo:104:svgcairo\n"
164 #if defined ( PLD_pngcairo )
165 "pngcairo:Cairo PNG Driver:0:cairo:105:pngcairo\n"
167 #if defined ( PLD_memcairo )
168 "memcairo:Cairo Memory Driver:0:cairo:106:memcairo\n"
170 #if defined ( PLD_extcairo )
171 "extcairo:Cairo External Context Driver:0:cairo:107:extcairo\n"
173 #if defined ( PLD_wincairo )
174 "wincairo:Cairo Microscoft Windows Driver:0:cairo:108:wincairo\n"
182 #if defined ( PLD_xcairo )
187 } PLXcairoDrawableInfo;
195 #define NPANGOLOOKUP 5
206 "PLPLOT_FREETYPE_SANS_FAMILY",
207 "PLPLOT_FREETYPE_SERIF_FAMILY",
208 "PLPLOT_FREETYPE_MONO_FAMILY",
209 "PLPLOT_FREETYPE_SCRIPT_FAMILY",
210 "PLPLOT_FREETYPE_SYMBOL_FAMILY"
213 #define FAMILY_LOOKUP_LEN 1024
244 cairo_status_t
write_to_stream(
void *,
unsigned char *,
unsigned int );
300 cairo_surface_t *tmp_sfc;
301 cairo_t *tmp_context;
316 cairo_image_surface_create( CAIRO_FORMAT_ARGB32,
344 cairo_surface_t *tmp_sfc;
345 cairo_t *tmp_context;
359 plexit(
"Can not plot to a Cairo device with no context" );
397 if ( (
double) pls->
cmap0[0].
a < 1.0 )
399 cairo_set_source_rgba( aStream->
cairoContext, 1.0, 1.0, 1.0, 1.0 );
403 (
double) pls->
cmap0[0].
r / 255.0,
404 (
double) pls->
cmap0[0].
g / 255.0,
405 (
double) pls->
cmap0[0].
b / 255.0,
406 (
double) pls->
cmap0[0].
a );
596 cairo_set_operator( aStream->
cairoContext, CAIRO_OPERATOR_OVER );
599 cairo_set_operator( aStream->
cairoContext, CAIRO_OPERATOR_SOURCE );
602 cairo_set_operator( aStream->
cairoContext, CAIRO_OPERATOR_XOR );
624 case CAIRO_OPERATOR_OVER:
627 case CAIRO_OPERATOR_SOURCE:
630 case CAIRO_OPERATOR_XOR:
715 if ( aStream->
upDown < 0 )
731 if ( aStream->
upDown > 0 )
747 if ( aStream->
uline == 1 )
761 plwarn(
"'-', and 'b/B' text escape sequences not processed." );
774 int textXExtent, textYExtent, baseline;
775 PLFLT rotation, shear, stride, cos_rot, sin_rot, cos_shear, sin_shear;
776 cairo_matrix_t *cairoTransformMatrix;
777 cairo_font_options_t *cairoFontOptions;
778 PangoContext *context;
792 layout = pango_cairo_create_layout( aStream->
cairoContext );
794 pango_layout_get_pixel_size( layout, &textXExtent, &textYExtent );
795 baseline = pango_layout_get_baseline( layout );
805 context = pango_layout_get_context( layout );
806 cairoFontOptions = cairo_font_options_create();
808 pango_cairo_context_set_font_options( context, cairoFontOptions );
809 pango_layout_context_changed( layout );
810 cairo_font_options_destroy( cairoFontOptions );
825 cairoTransformMatrix = (cairo_matrix_t *) malloc(
sizeof ( cairo_matrix_t ) );
826 cairo_matrix_init( cairoTransformMatrix, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0 );
827 cairo_transform( aStream->
cairoContext, cairoTransformMatrix );
833 cos_rot = cos( rotation );
834 sin_rot = sin( rotation );
835 cos_shear = cos( shear );
836 sin_shear = sin( shear );
839 cairo_matrix_init( cairoTransformMatrix,
842 cos_rot * sin_shear + sin_rot * cos_shear,
843 -sin_rot * sin_shear + cos_rot * cos_shear,
845 cairo_transform( aStream->
cairoContext, cairoTransformMatrix );
846 free( cairoTransformMatrix );
851 (
double) ( -1.0 * args->
just * (
double) textXExtent ),
852 (
double) 0.5 * aStream->
fontSize - baseline / 1024.0 );
855 pango_cairo_show_layout( aStream->
cairoContext, layout );
862 g_object_unref( layout );
875 int textXExtent, textYExtent, baseline;
876 char *textWithPangoMarkup;
877 PLFLT rotation, shear, stride, cos_rot, sin_rot, cos_shear, sin_shear;
878 cairo_matrix_t *cairoTransformMatrix;
879 cairo_font_options_t *cairoFontOptions;
880 PangoContext *context;
891 printf(
"Non unicode string passed to a cairo driver, ignoring\n" );
898 printf(
"Sorry, the cairo drivers only handles strings of length < %d\n",
MAX_STRING_LEN );
903 fontSize = (float) ( pls->
chrht *
DPI / 25.4 );
909 layout = pango_cairo_create_layout( aStream->
cairoContext );
910 pango_layout_set_markup( layout, textWithPangoMarkup, -1 );
911 pango_layout_get_pixel_size( layout, &textXExtent, &textYExtent );
912 baseline = pango_layout_get_baseline( layout );
922 context = pango_layout_get_context( layout );
923 cairoFontOptions = cairo_font_options_create();
925 pango_cairo_context_set_font_options( context, cairoFontOptions );
926 pango_layout_context_changed( layout );
927 cairo_font_options_destroy( cairoFontOptions );
942 cairoTransformMatrix = (cairo_matrix_t *) malloc(
sizeof ( cairo_matrix_t ) );
943 cairo_matrix_init( cairoTransformMatrix, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0 );
944 cairo_transform( aStream->
cairoContext, cairoTransformMatrix );
950 cos_rot = cos( rotation );
951 sin_rot = sin( rotation );
952 cos_shear = cos( shear );
953 sin_shear = sin( shear );
956 cairo_matrix_init( cairoTransformMatrix,
959 cos_rot * sin_shear + sin_rot * cos_shear,
960 -sin_rot * sin_shear + cos_rot * cos_shear,
962 cairo_transform( aStream->
cairoContext, cairoTransformMatrix );
963 free( cairoTransformMatrix );
968 (
double) ( -1.0 * args->
just * (
double) textXExtent ),
969 (
double) 0.5 * fontSize - baseline / 1024.0 );
972 pango_cairo_show_layout( aStream->
cairoContext, layout );
978 g_object_unref( layout );
979 free( textWithPangoMarkup );
998 char *pangoMarkupString;
999 PLFLT old_sscale, sscale, old_soffset, soffset;
1004 pangoMarkupString = (
char *) malloc(
sizeof (
char ) *
MAX_MARKUP_LEN );
1007 pangoMarkupString[i] = 0;
1019 while ( i < ucs4Len )
1022 if ( strlen( pangoMarkupString ) > ( MAX_MARKUP_LEN - 50 ) )
1033 strncat( pangoMarkupString,
"&", MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1036 strncat( pangoMarkupString,
"<", MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1039 strncat( pangoMarkupString,
">", MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1043 strncat( pangoMarkupString, utf8, MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1053 strncat( pangoMarkupString, utf8, MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1063 strncat( pangoMarkupString,
"</span>", MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1069 &old_sscale, &sscale, &old_soffset, &soffset );
1070 strncat( pangoMarkupString,
1072 MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1080 strncat( pangoMarkupString,
"</span>", MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1086 &old_sscale, &sscale, &old_soffset, &soffset );
1087 strncat( pangoMarkupString,
1089 MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1097 strncat( pangoMarkupString,
"</span>", MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1102 strncat( pangoMarkupString,
1103 "<span underline=\"single\">",
1104 MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1114 open_span_tag( pangoMarkupString, ucs4[i], fontSize, upDown );
1124 return pangoMarkupString;
1138 unsigned char fontFamily, fontStyle, fontWeight;
1141 PLFLT old_sscale, sscale, old_soffset, soffset;
1151 if ( fontStyle >= 3 )
1153 plwarn(
"cairo: Unknown font style specified, forcing normal\n" );
1156 if ( fontWeight >= 2 )
1158 plwarn(
"cairo: Unknown font weight specified, forcing normal\n" );
1165 strncat( pangoMarkupString, openTag,
MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1168 strncat( pangoMarkupString, openTag,
MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1171 strncat( pangoMarkupString, openTag,
MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1174 for ( upDown_level = 0; upDown_level < upDown; upDown_level++ )
1177 &old_sscale, &sscale, &old_soffset, &soffset );
1178 strncat( pangoMarkupString,
1182 for ( upDown_level = 0; upDown_level > upDown; upDown_level-- )
1185 &old_sscale, &sscale, &old_soffset, &soffset );
1186 strncat( pangoMarkupString,
1202 while ( upDown > 0 )
1204 strncat( pangoMarkupString,
"</span>",
MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1210 while ( upDown < 0 )
1212 strncat( pangoMarkupString,
"</span>",
MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1217 strncat( pangoMarkupString,
"</span>",
MAX_MARKUP_LEN - 1 - strlen( pangoMarkupString ) );
1225 # define RISE_FACTOR 0.8
1238 char *
rise_span_tag(
int ifsuperscript,
float fontSize,
float multiplier,
float rise )
1241 static char tag[100];
1248 rise = 1024.f * fontSize * (float)
RISE_FACTOR * rise;
1253 offset = 1024.f * 0.5f * fontSize * ( 1.0f - multiplier );
1255 if ( ifsuperscript )
1257 sprintf( tag,
"<span rise=\"%d\" size=\"%d\">",
1258 (
int) ( rise + offset ), (
int) ( fontSize * 1024. * multiplier ) );
1262 sprintf( tag,
"<span rise=\"%d\" size=\"%d\">",
1263 (
int) -( rise - offset ), (
int) ( fontSize * 1024. * multiplier ) );
1276 cairo_status_t
write_to_stream(
void *filePointer,
unsigned char *data,
unsigned int length )
1278 unsigned int bytes_written;
1280 bytes_written = (
unsigned int) fwrite( data, 1, (
size_t) length, (FILE *) filePointer );
1281 if ( bytes_written == length )
1283 return CAIRO_STATUS_SUCCESS;
1287 return CAIRO_STATUS_WRITE_ERROR;
1309 pls->
termin = interactive;
1355 aStream = malloc(
sizeof (
PLCairo ) );
1356 #if defined ( PLD_xcairo )
1357 aStream->XDisplay = NULL;
1358 aStream->XWindow = 0;
1411 if ( pls->
width <= 0. )
1439 for ( i = 1; i < npts; i++ )
1468 if ( cairo_get_antialias( aStream->
cairoContext ) != CAIRO_ANTIALIAS_NONE )
1502 cairo_pattern_t *linear_gradient;
1509 linear_gradient = cairo_pattern_create_linear(
1515 cairo_pattern_reference( linear_gradient );
1516 for ( i = 0; i < pls->
ncol1; i++ )
1518 cairo_pattern_add_color_stop_rgba( linear_gradient,
1519 (
double) i / (
double) ( pls->
ncol1 - 1 ),
1520 (
double) pls->
cmap1[i].
r / 255.,
1521 (
double) pls->
cmap1[i].
g / 255.,
1522 (
double) pls->
cmap1[i].
b / 255.,
1523 (
double) pls->
cmap1[i].
a );
1529 cairo_set_source( aStream->
cairoContext, linear_gradient );
1531 cairo_pattern_destroy( linear_gradient );
1544 PLINT rcx[4], rcy[4];
1595 plwarn(
"All pages after the first skipped because family file output not specified.\n" );
1611 double angle1, angle2, rotate;
1638 cairo_arc( aStream->
cairoContext, 0.0, 0.0, 1.0, angle1, angle2 );
1639 if ( arc_info->
fill )
1648 if ( arc_info->
fill )
1667 cairo_matrix_t *matrix;
1672 matrix = (cairo_matrix_t *) malloc(
sizeof ( cairo_matrix_t ) );
1673 cairo_matrix_init( matrix, x11, x12, x21, x22, x0, y0 );
1674 #if defined ( PLD_xcairo )
1677 cairo_transform( aStream->cairoContext_X, matrix );
1696 #if defined ( PLD_pngcairo ) || defined ( PLD_svgcairo ) || defined ( PLD_epscairo )
1698 void plD_bop_cairo_fam(
PLStream * );
1699 void plD_eop_cairo_fam(
PLStream * );
1702 void plD_tidy_cairo_fam(
PLStream * );
1703 void plD_line_cairo_fam(
PLStream *,
short,
short,
short,
short );
1704 void plD_polyline_cairo_fam(
PLStream *,
short *,
short *,
PLINT );
1712 void plD_bop_cairo_fam(
PLStream *pls )
1734 (
double) pls->
cmap0[0].
r / 255.0,
1735 (
double) pls->
cmap0[0].
g / 255.0,
1736 (
double) pls->
cmap0[0].
b / 255.0,
1737 (
double) pls->
cmap0[0].
a );
1747 void plD_eop_cairo_fam(
PLStream *pls )
1779 void plD_esc_cairo_fam(
PLStream *pls,
PLINT op,
void *ptr )
1795 void plD_tidy_cairo_fam(
PLStream *pls )
1806 void plD_line_cairo_fam(
PLStream *pls,
short x1a,
short y1a,
short x2a,
short y2a )
1822 void plD_polyline_cairo_fam(
PLStream *pls,
short *xa,
short *ya,
PLINT npts )
1841 #if defined ( PLD_xcairo )
1844 static Window rootWindow;
1847 void plD_init_xcairo(
PLStream * );
1850 void plD_tidy_xcairo(
PLStream * );
1862 #ifndef ENABLE_DYNDRIVERS
1890 static signed int xcairo_init_cairo(
PLStream *pls )
1893 Visual *defaultVisual;
1898 defaultVisual = DefaultVisual( aStream->XDisplay, 0 );
1902 aStream->cairoSurface_X = cairo_xlib_surface_create(
1909 aStream->cairoContext_X = cairo_create( aStream->cairoSurface_X );
1915 aStream->cairoSurface_X,
1916 CAIRO_CONTENT_COLOR_ALPHA,
1926 cairo_image_surface_create(
1927 CAIRO_FORMAT_ARGB32,
1941 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
1943 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
1947 cairo_rectangle( aStream->cairoContext_X, 0.0, 0.0, pls->
xlength, pls->
ylength );
1948 cairo_set_source_rgba( aStream->cairoContext_X,
1949 (
double) pls->
cmap0[0].
r / 255.0,
1950 (
double) pls->
cmap0[0].
g / 255.0,
1951 (
double) pls->
cmap0[0].
b / 255.0,
1952 (
double) pls->
cmap0[0].
a );
1953 cairo_fill( aStream->cairoContext_X );
1955 XFlush( aStream->XDisplay );
1966 void plD_init_xcairo(
PLStream *pls )
1980 aStream->xdrawable_mode = 1;
1985 aStream->XDisplay = NULL;
1987 aStream->XDisplay = XOpenDisplay( pls->
FileName );
1989 aStream->XDisplay = XOpenDisplay( NULL );
1990 if ( aStream->XDisplay == NULL )
1992 plexit(
"Failed to open X Windows display\n" );
1995 XScreen = DefaultScreen( aStream->XDisplay );
1996 rootWindow = RootWindow( aStream->XDisplay, XScreen );
1998 aStream->XWindow = XCreateSimpleWindow(
2004 BlackPixel( aStream->XDisplay, XScreen ),
2005 BlackPixel( aStream->XDisplay, XScreen ) );
2007 XStoreName( aStream->XDisplay, aStream->XWindow, pls->
plwindow );
2008 XSelectInput( aStream->XDisplay, aStream->XWindow, NoEventMask );
2009 XMapWindow( aStream->XDisplay, aStream->XWindow );
2010 aStream->xdrawable_mode = 0;
2012 wmDelete = XInternAtom( aStream->XDisplay,
"WM_DELETE_WINDOW", True );
2013 XSetWMProtocols( aStream->XDisplay, aStream->XWindow, &wmDelete, 1 );
2015 xcairo_init_cairo( pls );
2018 aStream->exit_event_loop = 0;
2038 cairo_set_operator( aStream->
cairoContext, CAIRO_OPERATOR_DEST_OVER );
2040 (
double) pls->
cmap0[0].
r / 255.0,
2041 (
double) pls->
cmap0[0].
g / 255.0,
2042 (
double) pls->
cmap0[0].
b / 255.0,
2043 (
double) pls->
cmap0[0].
a );
2047 cairo_save( aStream->cairoContext_X );
2049 cairo_rectangle( aStream->cairoContext_X, x, y, w, h );
2050 cairo_set_operator( aStream->cairoContext_X, CAIRO_OPERATOR_SOURCE );
2051 cairo_set_source_surface( aStream->cairoContext_X,
2053 cairo_fill( aStream->cairoContext_X );
2054 cairo_restore( aStream->cairoContext_X );
2063 void plD_bop_xcairo(
PLStream *pls )
2071 if ( aStream->xdrawable_mode )
2074 XFlush( aStream->XDisplay );
2083 void plD_eop_xcairo(
PLStream *pls )
2087 char event_string[10];
2091 XExposeEvent *expose;
2099 if ( aStream->xdrawable_mode )
2104 aStream->exit_event_loop = 1;
2107 event_mask = ButtonPressMask | KeyPressMask | ExposureMask;
2108 XSelectInput( aStream->XDisplay, aStream->XWindow, event_mask );
2109 while ( !aStream->exit_event_loop )
2112 XNextEvent( aStream->XDisplay, &event );
2113 switch ( event.type )
2116 number_chars = XLookupString( (XKeyEvent *) &event, event_string, 10, &keysym, &cs );
2117 event_string[number_chars] =
'\0';
2118 if ( keysym == XK_Return )
2120 aStream->exit_event_loop = 1;
2124 if ( ( (XButtonEvent *) &event )->button == Button3 )
2125 aStream->exit_event_loop = 1;
2130 aStream->exit_event_loop = 1;
2135 expose = (XExposeEvent *) &event;
2136 if ( expose->count == 0 )
2139 expose->
width, expose->height );
2144 aStream->exit_event_loop = 0;
2153 void plD_tidy_xcairo(
PLStream *pls )
2162 cairo_destroy( aStream->cairoContext_X );
2163 cairo_surface_destroy( aStream->cairoSurface_X );
2165 if ( aStream->xdrawable_mode )
2169 XFlush( aStream->XDisplay );
2171 XDestroyWindow( aStream->XDisplay, aStream->XWindow );
2173 XCloseDisplay( aStream->XDisplay );
2192 XFlush( aStream->XDisplay );
2196 XFlush( aStream->XDisplay );
2201 PLXcairoDrawableInfo *xinfo = (PLXcairoDrawableInfo *) ptr;
2203 unsigned int w, h, b, d;
2204 if ( xinfo == NULL )
2206 printf(
"xcairo: PLESC_DEVINIT ignored, no drawable info provided\n" );
2209 if ( aStream->xdrawable_mode == 0 )
2211 printf(
"xcairo: PLESC_DEVINIT called with drawable but stream not in xdrawable mode\n" );
2214 aStream->XDisplay = xinfo->display;
2215 aStream->XWindow = xinfo->drawable;
2218 XGetGeometry( aStream->XDisplay, aStream->XWindow, &rootwin,
2219 &x, &y, &w, &h, &b, &d );
2232 xcairo_init_cairo( pls );
2257 XButtonEvent *xButtonEvent;
2267 xHairCursor = XCreateFontCursor( aStream->XDisplay, XC_crosshair );
2268 XDefineCursor( aStream->XDisplay, aStream->XWindow, xHairCursor );
2271 XSelectInput( aStream->XDisplay, aStream->XWindow, ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | ButtonMotionMask );
2272 XMaskEvent( aStream->XDisplay, ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask | ButtonMotionMask, &event );
2273 XSelectInput( aStream->XDisplay, aStream->XWindow, NoEventMask );
2276 xButtonEvent = (XButtonEvent *) &event;
2277 gin->
state = xButtonEvent->state;
2278 gin->
button = xButtonEvent->button;
2279 gin->
pX =
event.xbutton.x;
2280 gin->
pY = pls->
ylength -
event.xbutton.y;
2285 if ( event.type == KeyPress || event.type == KeyRelease )
2287 XLookupString( (XKeyEvent *) &event, str, 100, &keysym, NULL );
2288 if ( keysym == NoSymbol )
2289 ksname =
"NoSymbol";
2290 else if ( !( ksname = XKeysymToString( keysym ) ) )
2291 ksname =
"(no name)";
2292 strcpy( gin->
string, ksname );
2302 gin->
keysym = 0xFF & keysym;
2305 gin->
keysym = (
unsigned int) keysym;
2315 XUndefineCursor( aStream->XDisplay, aStream->XWindow );
2316 XFlush( aStream->XDisplay );
2330 #if defined ( PLD_pdfcairo )
2333 void plD_init_pdfcairo(
PLStream * );
2344 #ifndef ENABLE_DYNDRIVERS
2366 void plD_init_pdfcairo(
PLStream *pls )
2392 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
2394 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
2408 #if defined ( PLD_pscairo )
2411 void plD_init_pscairo(
PLStream * );
2422 #ifndef ENABLE_DYNDRIVERS
2444 void plD_init_pscairo(
PLStream *pls )
2472 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
2474 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
2488 #if defined ( PLD_epscairo )
2491 void plD_init_epscairo(
PLStream * );
2502 #ifndef ENABLE_DYNDRIVERS
2524 void plD_init_epscairo(
PLStream *pls )
2539 if ( pls->
dev == NULL )
2576 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
2578 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
2592 #if defined ( PLD_svgcairo )
2595 void plD_init_svgcairo(
PLStream * );
2606 #ifndef ENABLE_DYNDRIVERS
2628 void plD_init_svgcairo(
PLStream *pls )
2643 if ( pls->
dev == NULL )
2675 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
2677 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
2691 #if defined ( PLD_pngcairo )
2694 void plD_init_pngcairo(
PLStream * );
2695 void plD_eop_pngcairo(
PLStream * );
2706 #ifndef ENABLE_DYNDRIVERS
2728 void plD_init_pngcairo(
PLStream *pls )
2743 if ( pls->
dev == NULL )
2775 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
2777 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
2786 void plD_eop_pngcairo(
PLStream *pls )
2810 #if defined ( PLD_memcairo )
2813 void plD_init_memcairo(
PLStream * );
2814 void plD_eop_memcairo(
PLStream * );
2815 void plD_bop_memcairo(
PLStream * );
2826 #ifndef ENABLE_DYNDRIVERS
2859 void plD_init_memcairo(
PLStream *pls )
2863 unsigned char *cairo_mem;
2864 unsigned char *input_mem;
2870 char testByte[
sizeof ( int )];
2872 endianTest.testWord = 1;
2884 if ( endianTest.testByte[0] == 1 )
2885 aStream->bigendian = 0;
2887 aStream->bigendian = 1;
2890 if ( pls->
dev == NULL )
2892 plexit(
"Must call plsmem first to set user plotting area!" );
2896 aStream->memory = pls->
dev;
2906 aStream->cairo_format_memory = (
unsigned char *) calloc( (
size_t) ( stride * pls->
ylength ), 1 );
2909 cairo_mem = aStream->cairo_format_memory;
2910 input_mem = aStream->memory;
2916 if ( aStream->bigendian )
2920 cairo_mem[1] = input_mem[0];
2921 cairo_mem[2] = input_mem[1];
2922 cairo_mem[3] = input_mem[2];
2925 cairo_mem[0] = input_mem[3];
2939 cairo_mem[2] = input_mem[0];
2940 cairo_mem[1] = input_mem[1];
2941 cairo_mem[0] = input_mem[2];
2944 cairo_mem[3] = input_mem[3];
2959 cairo_image_surface_create_for_data( aStream->cairo_format_memory, CAIRO_FORMAT_RGB24, pls->
xlength, pls->
ylength, stride );
2974 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
2976 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
2986 void plD_eop_memcairo(
PLStream *pls )
2989 unsigned char *memory;
2990 unsigned char *cairo_surface_data;
2994 memory = aStream->memory;
2995 cairo_surface_data = cairo_image_surface_get_data( aStream->
cairoSurface );
2999 if ( aStream->bigendian )
3003 memory[0] = cairo_surface_data[1];
3004 memory[1] = cairo_surface_data[2];
3005 memory[2] = cairo_surface_data[3];
3008 memory[3] = cairo_surface_data[0];
3015 cairo_surface_data += 4;
3022 memory[0] = cairo_surface_data[2];
3023 memory[1] = cairo_surface_data[1];
3024 memory[2] = cairo_surface_data[0];
3027 memory[3] = cairo_surface_data[3];
3034 cairo_surface_data += 4;
3039 free( aStream->cairo_format_memory );
3052 #if defined ( PLD_extcairo )
3054 void extcairo_setbackground(
PLStream * );
3056 void plD_init_extcairo(
PLStream * );
3057 void plD_bop_extcairo(
PLStream * );
3058 void plD_eop_extcairo(
PLStream * );
3060 void plD_tidy_extcairo(
PLStream * );
3068 void extcairo_setbackground(
PLStream *pls )
3079 (
double) pls->
cmap0[0].
r / 255.0,
3080 (
double) pls->
cmap0[0].
g / 255.0,
3081 (
double) pls->
cmap0[0].
b / 255.0,
3082 (
double) pls->
cmap0[0].
a );
3096 #ifndef ENABLE_DYNDRIVERS
3097 pdt->
pl_MenuStr =
"Cairo external context driver";
3118 void plD_init_extcairo(
PLStream *pls )
3135 void plD_bop_extcairo(
PLStream *pls )
3144 extcairo_setbackground( pls );
3189 extcairo_setbackground( pls );
3194 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
3196 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
3229 #if defined ( PLD_wincairo )
3231 static char* szWndClass =
"PLplot WinCairo";
3234 void plD_init_wincairo(
PLStream * );
3236 void plD_eop_wincairo(
PLStream * );
3238 void plD_tidy_wincairo(
PLStream * );
3246 void blit_to_win(
PLCairo *aStream )
3248 cairo_set_source_surface( aStream->cairoContext_win, aStream->
cairoSurface, 0.0, 0.0 );
3249 cairo_paint( aStream->cairoContext_win );
3258 LRESULT CALLBACK PlplotCairoWndProc( HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam )
3273 if ( nMsg == WM_CREATE )
3279 pls = (
PLStream *) GetWindowLong( hwnd, GWL_USERDATA );
3301 PostQuitMessage( 0 );
3311 GetClientRect( dev->hwnd, &dev->rect );
3315 case WM_ENTERSIZEMOVE:
3319 case WM_EXITSIZEMOVE:
3326 dev->oldcolour = SetBkColor( dev->hdc, RGB( pls->
cmap0[0].
r, pls->
cmap0[0].
g, pls->
cmap0[0].
b ) );
3327 ExtTextOut( dev->hdc, 0, 0, ETO_OPAQUE, &dev->rect,
"", 0, 0 );
3328 SetBkColor( dev->hdc, dev->oldcolour );
3340 return DefWindowProc( hwnd, nMsg, wParam, lParam );
3358 while ( GetMessage( &aStream->msg, NULL, 0, 0 ) && !located )
3360 TranslateMessage( &aStream->msg );
3362 switch ( (
int) aStream->msg.message )
3365 case WM_LBUTTONDOWN:
3368 gin->
pX = LOWORD( aStream->msg.lParam );
3369 gin->
pY = pls->
ylength - HIWORD( aStream->msg.lParam );
3374 gin->
keysym = aStream->msg.wParam;
3379 DispatchMessage( &aStream->msg );
3394 #ifndef ENABLE_DYNDRIVERS
3395 pdt->
pl_MenuStr =
"Cairo Microsoft Windows driver";
3416 void plD_init_wincairo(
PLStream *pls )
3427 memset( &aStream->wndclass, 0, sizeof ( WNDCLASSEX ) );
3430 aStream->wndclass.lpszClassName = szWndClass;
3433 aStream->wndclass.cbSize =
sizeof ( WNDCLASSEX );
3436 aStream->wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC | CS_PARENTDC;
3439 aStream->wndclass.lpfnWndProc = PlplotCairoWndProc;
3443 aStream->wndclass.hInstance = GetModuleHandle( NULL );
3446 aStream->wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
3447 aStream->wndclass.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
3448 aStream->wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
3450 aStream->wndclass.hbrBackground = NULL;
3452 aStream->wndclass.cbWndExtra =
sizeof ( pls );
3459 RegisterClassEx( &aStream->wndclass );
3464 aStream->hwnd = CreateWindowEx( WS_EX_WINDOWEDGE + WS_EX_LEFT,
3467 WS_OVERLAPPEDWINDOW,
3475 aStream->wndclass.hInstance,
3486 SetWindowLong( aStream->hwnd, GWL_USERDATA, (
long) pls );
3487 aStream->SCRN_hdc = aStream->hdc = GetDC( aStream->hwnd );
3506 ShowWindow( aStream->hwnd, SW_SHOWDEFAULT );
3507 SetForegroundWindow( aStream->hwnd );
3527 aStream->cairoSurface_win = (cairo_surface_t *) cairo_win32_surface_create( aStream->hdc );
3528 aStream->cairoContext_win = cairo_create( aStream->cairoSurface_win );
3542 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_EVEN_ODD );
3544 cairo_set_fill_rule( aStream->
cairoContext, CAIRO_FILL_RULE_WINDING );
3560 while ( GetMessage( &aStream->msg, NULL, 0, 0 ) )
3562 TranslateMessage( &aStream->msg );
3563 switch ( (
int) aStream->msg.message )
3566 if ( ( (TCHAR) ( aStream->msg.wParam ) == 13 ) ||
3567 ( (TCHAR) ( aStream->msg.wParam ) ==
'q' ) ||
3568 ( (TCHAR) ( aStream->msg.wParam ) ==
'Q' ) )
3570 PostQuitMessage( 0 );
3575 DispatchMessage( &aStream->msg );
3588 void plD_tidy_wincairo(
PLStream *pls )
3595 cairo_destroy( aStream->cairoContext_win );
3596 cairo_surface_destroy( aStream->cairoSurface_win );
3598 if ( aStream != NULL )
3600 if ( aStream->hdc != NULL )
3601 ReleaseDC( aStream->hwnd, aStream->hdc );
3621 InvalidateRect( aStream->hwnd, NULL,
TRUE );