comparison gtk4/dw.c @ 2362:4367da529f5a

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Fri, 12 Mar 2021 20:21:48 +0000
parents 6f4f7882363c
children d7688c3ec43f
comparison
equal deleted inserted replaced
2361:7d54728064a3 2362:4367da529f5a
841 if(width == -1) 841 if(width == -1)
842 width = gtk_widget_get_width(widget); 842 width = gtk_widget_get_width(widget);
843 if(height == -1) 843 if(height == -1)
844 height = gtk_widget_get_height(widget); 844 height = gtk_widget_get_height(widget);
845 845
846 if(!wincr || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_width")) != width || 846 if(!surface || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_width")) != width ||
847 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_height")) != height) 847 GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_height")) != height)
848 { 848 {
849 if(wincr)
850 cairo_destroy(wincr);
851 if(surface) 849 if(surface)
852 cairo_surface_destroy(surface); 850 cairo_surface_destroy(surface);
853 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); 851 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
854 wincr = cairo_create(surface);
855 /* Save the cairo context for use in the drawing functions */ 852 /* Save the cairo context for use in the drawing functions */
856 g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)wincr);
857 g_object_set_data(G_OBJECT(widget), "_dw_cr_surface", (gpointer)surface); 853 g_object_set_data(G_OBJECT(widget), "_dw_cr_surface", (gpointer)surface);
858 g_object_set_data(G_OBJECT(widget), "_dw_width", GINT_TO_POINTER(width)); 854 g_object_set_data(G_OBJECT(widget), "_dw_width", GINT_TO_POINTER(width));
859 g_object_set_data(G_OBJECT(widget), "_dw_height", GINT_TO_POINTER(height)); 855 g_object_set_data(G_OBJECT(widget), "_dw_height", GINT_TO_POINTER(height));
860 } 856 }
861 return wincr; 857 return wincr;
873 _dw_cairo_update(widget, width, height); 869 _dw_cairo_update(widget, width, height);
874 870
875 exp.x = exp.y = 0; 871 exp.x = exp.y = 0;
876 exp.width = width; 872 exp.width = width;
877 exp.height = height; 873 exp.height = height;
874 #ifdef DW_USE_CACHED_CR
875 g_object_set_data(G_OBJECT(widget), "_dw_cr", (gpointer)cr);
876 #endif
878 retval = exposefunc((HWND)widget, &exp, data); 877 retval = exposefunc((HWND)widget, &exp, data);
879 /* Copy the cached image to the outbut surface */ 878 #ifdef DW_USE_CACHED_CR
879 g_object_set_data(G_OBJECT(widget), "_dw_cr", NULL);
880 #endif
881 /* Copy the cached image to the output surface */
880 cairo_set_source_surface(cr, g_object_get_data(G_OBJECT(widget), "_dw_cr_surface"), 0, 0); 882 cairo_set_source_surface(cr, g_object_get_data(G_OBJECT(widget), "_dw_cr_surface"), 0, 0);
881 cairo_rectangle(cr, 0, 0, width, height); 883 cairo_rectangle(cr, 0, 0, width, height);
882 cairo_fill(cr); 884 cairo_fill(cr);
883 } 885 }
884 return retval; 886 return retval;
6358 } 6360 }
6359 6361
6360 /* Make sure the widget is out of the dirty list if it is destroyed */ 6362 /* Make sure the widget is out of the dirty list if it is destroyed */
6361 static void _dw_render_destroy(GtkWidget *widget, gpointer data) 6363 static void _dw_render_destroy(GtkWidget *widget, gpointer data)
6362 { 6364 {
6365 cairo_surface_t *surface = (cairo_surface_t *)g_object_get_data(G_OBJECT(widget), "_dw_cr_surface");
6366
6367 if(surface)
6368 cairo_surface_destroy(surface);
6369
6363 _dw_dirty_list = g_list_remove(_dw_dirty_list, widget); 6370 _dw_dirty_list = g_list_remove(_dw_dirty_list, widget);
6364 } 6371 }
6365 6372
6366 /* 6373 /*
6367 * Creates a rendering context widget (window) to be packed. 6374 * Creates a rendering context widget (window) to be packed.
6506 cairo_t *cr = NULL; 6513 cairo_t *cr = NULL;
6507 int cached = FALSE; 6514 int cached = FALSE;
6508 6515
6509 if(handle) 6516 if(handle)
6510 { 6517 {
6518 cairo_surface_t *surface;
6519
6511 if((cr = _dw_cairo_update(handle, -1, -1))) 6520 if((cr = _dw_cairo_update(handle, -1, -1)))
6512 cached = TRUE; 6521 cached = TRUE;
6522 else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface")))
6523 cr = cairo_create(surface);
6513 } 6524 }
6514 else if(pixmap) 6525 else if(pixmap)
6515 cr = cairo_create(pixmap->image); 6526 cr = cairo_create(pixmap->image);
6516 if(cr) 6527 if(cr)
6517 { 6528 {
6547 cairo_t *cr = NULL; 6558 cairo_t *cr = NULL;
6548 int cached = FALSE; 6559 int cached = FALSE;
6549 6560
6550 if(handle) 6561 if(handle)
6551 { 6562 {
6563 cairo_surface_t *surface;
6564
6552 if((cr = _dw_cairo_update(handle, -1, -1))) 6565 if((cr = _dw_cairo_update(handle, -1, -1)))
6553 cached = TRUE; 6566 cached = TRUE;
6567 else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface")))
6568 cr = cairo_create(surface);
6554 } 6569 }
6555 else if(pixmap) 6570 else if(pixmap)
6556 cr = cairo_create(pixmap->image); 6571 cr = cairo_create(pixmap->image);
6557 if(cr) 6572 if(cr)
6558 { 6573 {
6590 int z; 6605 int z;
6591 int cached = FALSE; 6606 int cached = FALSE;
6592 6607
6593 if(handle) 6608 if(handle)
6594 { 6609 {
6610 cairo_surface_t *surface;
6611
6595 if((cr = _dw_cairo_update(handle, -1, -1))) 6612 if((cr = _dw_cairo_update(handle, -1, -1)))
6596 cached = TRUE; 6613 cached = TRUE;
6614 else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface")))
6615 cr = cairo_create(surface);
6597 } 6616 }
6598 else if(pixmap) 6617 else if(pixmap)
6599 cr = cairo_create(pixmap->image); 6618 cr = cairo_create(pixmap->image);
6600 if(cr) 6619 if(cr)
6601 { 6620 {
6641 cairo_t *cr = NULL; 6660 cairo_t *cr = NULL;
6642 int cached = FALSE; 6661 int cached = FALSE;
6643 6662
6644 if(handle) 6663 if(handle)
6645 { 6664 {
6665 cairo_surface_t *surface;
6666
6646 if((cr = _dw_cairo_update(handle, -1, -1))) 6667 if((cr = _dw_cairo_update(handle, -1, -1)))
6647 cached = TRUE; 6668 cached = TRUE;
6669 else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface")))
6670 cr = cairo_create(surface);
6648 } 6671 }
6649 else if(pixmap) 6672 else if(pixmap)
6650 cr = cairo_create(pixmap->image); 6673 cr = cairo_create(pixmap->image);
6651 if(cr) 6674 if(cr)
6652 { 6675 {
6694 cairo_t *cr = NULL; 6717 cairo_t *cr = NULL;
6695 int cached = FALSE; 6718 int cached = FALSE;
6696 6719
6697 if(handle) 6720 if(handle)
6698 { 6721 {
6722 cairo_surface_t *surface;
6723
6699 if((cr = _dw_cairo_update(handle, -1, -1))) 6724 if((cr = _dw_cairo_update(handle, -1, -1)))
6700 cached = TRUE; 6725 cached = TRUE;
6726 else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface")))
6727 cr = cairo_create(surface);
6701 } 6728 }
6702 else if(pixmap) 6729 else if(pixmap)
6703 cr = cairo_create(pixmap->image); 6730 cr = cairo_create(pixmap->image);
6704 if(cr) 6731 if(cr)
6705 { 6732 {
6758 char *tmpname, *fontname = "monospace 10"; 6785 char *tmpname, *fontname = "monospace 10";
6759 int cached = FALSE; 6786 int cached = FALSE;
6760 6787
6761 if(handle) 6788 if(handle)
6762 { 6789 {
6790 cairo_surface_t *surface;
6791
6763 if((cr = _dw_cairo_update(handle, -1, -1))) 6792 if((cr = _dw_cairo_update(handle, -1, -1)))
6764 cached = TRUE; 6793 cached = TRUE;
6794 else if((surface = g_object_get_data(G_OBJECT(handle), "_dw_cr_surface")))
6795 cr = cairo_create(surface);
6765 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname"))) 6796 if((tmpname = (char *)g_object_get_data(G_OBJECT(handle), "_dw_fontname")))
6766 fontname = tmpname; 6797 fontname = tmpname;
6767 } 6798 }
6768 else if(pixmap) 6799 else if(pixmap)
6769 { 6800 {
7184 int retval = DW_ERROR_GENERAL; 7215 int retval = DW_ERROR_GENERAL;
7185 int cached = FALSE; 7216 int cached = FALSE;
7186 7217
7187 if(dest) 7218 if(dest)
7188 { 7219 {
7220 cairo_surface_t *surface;
7221
7189 if((cr = _dw_cairo_update(dest, -1, -1))) 7222 if((cr = _dw_cairo_update(dest, -1, -1)))
7190 cached = TRUE; 7223 cached = TRUE;
7224 else if((surface = g_object_get_data(G_OBJECT(dest), "_dw_cr_surface")))
7225 cr = cairo_create(surface);
7191 } 7226 }
7192 else if(destp) 7227 else if(destp)
7193 cr = cairo_create(destp->image); 7228 cr = cairo_create(destp->image);
7194 7229
7195 if(cr) 7230 if(cr)
7205 7240
7206 if(src) 7241 if(src)
7207 { 7242 {
7208 cairo_surface_t *surface = g_object_get_data(G_OBJECT(src), "_dw_cr_surface"); 7243 cairo_surface_t *surface = g_object_get_data(G_OBJECT(src), "_dw_cr_surface");
7209 if(surface) 7244 if(surface)
7210 cairo_set_source_surface (cr, surface, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); 7245 cairo_set_source_surface(cr, surface, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale);
7211 } 7246 }
7212 else if(srcp) 7247 else if(srcp)
7213 cairo_set_source_surface (cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale); 7248 cairo_set_source_surface(cr, srcp->image, (xdest + xsrc) / xscale, (ydest + ysrc) / yscale);
7214 7249
7215 cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height); 7250 cairo_rectangle(cr, xdest / xscale, ydest / yscale, width, height);
7216 cairo_fill(cr); 7251 cairo_fill(cr);
7217 /* If we are using a drawing context... 7252 /* If we are using a drawing context...
7218 * we don't own the cairo context so don't destroy it. 7253 * we don't own the cairo context so don't destroy it.