Mercurial > dwindows
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. |