# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1615580508 0 # Node ID 4367da529f5aef05d6bc4dbb468ea250a3c201a2 # Parent 7d54728064a36da12639c5fcf4b6c7638619fdaf GTK4: Fix direct drawing onto render widgets. Can't cache the cairo_t. If we never destroy the cairo_t drawing fails, so create it for each drawing function. diff -r 7d54728064a3 -r 4367da529f5a gtk4/dw.c --- a/gtk4/dw.c Fri Mar 12 15:19:40 2021 +0000 +++ b/gtk4/dw.c Fri Mar 12 20:21:48 2021 +0000 @@ -843,17 +843,13 @@ if(height == -1) height = gtk_widget_get_height(widget); - if(!wincr || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_width")) != width || + if(!surface || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_width")) != width || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_height")) != height) { - if(wincr) - cairo_destroy(wincr); if(surface) cairo_surface_destroy(surface); surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - wincr = cairo_create(surface); /* Save the cairo context for use in the drawing functions */ - g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)wincr); g_object_set_data(G_OBJECT(widget), "_dw_cr_surface", (gpointer)surface); g_object_set_data(G_OBJECT(widget), "_dw_width", GINT_TO_POINTER(width)); g_object_set_data(G_OBJECT(widget), "_dw_height", GINT_TO_POINTER(height)); @@ -875,8 +871,14 @@ exp.x = exp.y = 0; exp.width = width; exp.height = height; +#ifdef DW_USE_CACHED_CR + g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)cr); +#endif retval = exposefunc((HWND)widget, &exp, data); - /* Copy the cached image to the outbut surface */ +#ifdef DW_USE_CACHED_CR + g_object_set_data(G_OBJECT(widget), "_dw_cr", NULL); +#endif + /* Copy the cached image to the output surface */ cairo_set_source_surface(cr, g_object_get_data(G_OBJECT(widget), "_dw_cr_surface"), 0, 0); cairo_rectangle(cr, 0, 0, width, height); cairo_fill(cr); @@ -6360,6 +6362,11 @@ /* Make sure the widget is out of the dirty list if it is destroyed */ static void _dw_render_destroy(GtkWidget *widget, gpointer data) { + cairo_surface_t *surface = (cairo_surface_t *)g_object_get_data(G_OBJECT(widget), "_dw_cr_surface"); + + if(surface) + cairo_surface_destroy(surface); + _dw_dirty_list = g_list_remove(_dw_dirty_list, widget); } @@ -6508,8 +6515,12 @@ if(handle) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(handle, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface"))) + cr = cairo_create(surface); } else if(pixmap) cr = cairo_create(pixmap->image); @@ -6549,8 +6560,12 @@ if(handle) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(handle, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface"))) + cr = cairo_create(surface); } else if(pixmap) cr = cairo_create(pixmap->image); @@ -6592,8 +6607,12 @@ if(handle) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(handle, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface"))) + cr = cairo_create(surface); } else if(pixmap) cr = cairo_create(pixmap->image); @@ -6643,8 +6662,12 @@ if(handle) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(handle, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface"))) + cr = cairo_create(surface); } else if(pixmap) cr = cairo_create(pixmap->image); @@ -6696,8 +6719,12 @@ if(handle) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(handle, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface"))) + cr = cairo_create(surface); } else if(pixmap) cr = cairo_create(pixmap->image); @@ -6760,8 +6787,12 @@ if(handle) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(handle, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface"))) + cr = cairo_create(surface); if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) fontname = tmpname; } @@ -7186,8 +7217,12 @@ if(dest) { + cairo_surface_t *surface; + if((cr = _dw_cairo_update(dest, -1, -1))) cached = TRUE; + else if((surface = g_object_get_data(G_OBJECT(dest), "_dw_cr_surface"))) + cr = cairo_create(surface); } else if(destp) cr = cairo_create(destp->image); @@ -7207,10 +7242,10 @@ { cairo_surface_t *surface = g_object_get_data(G_OBJECT(src), "_dw_cr_surface"); if(surface) - cairo_set_source_surface (cr, surface, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); + cairo_set_source_surface(cr, surface, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); } else if(srcp) - cairo_set_source_surface (cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); + cairo_set_source_surface(cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height); cairo_fill(cr);