|
Lines 1730-1772
Link Here
|
| 1730 |
RESTORE_GC (gc); |
1730 |
RESTORE_GC (gc); |
| 1731 |
} |
1731 |
} |
| 1732 |
|
1732 |
|
|
|
1733 |
typedef struct { |
| 1734 |
cairo_t *cr; /* if non-null, it means use this cairo context */ |
| 1735 |
GdkGC *gc; /* if non-null, it means use this GC instead */ |
| 1736 |
} BackingRectMethod; |
| 1737 |
|
| 1733 |
static void |
1738 |
static void |
| 1734 |
gdk_window_set_bg_pattern (GdkWindow *window, |
1739 |
setup_backing_rect_method (BackingRectMethod *method, GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo) |
| 1735 |
cairo_t *cr, |
|
|
| 1736 |
int x_offset, |
| 1737 |
int y_offset) |
| 1738 |
{ |
1740 |
{ |
| 1739 |
GdkWindowObject *private = (GdkWindowObject *)window; |
1741 |
GdkWindowObject *private = (GdkWindowObject *)window; |
| 1740 |
|
1742 |
|
| 1741 |
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) |
1743 |
if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) |
| 1742 |
{ |
1744 |
{ |
| 1743 |
x_offset += private->x; |
1745 |
GdkWindowPaint tmp_paint; |
| 1744 |
y_offset += private->y; |
1746 |
|
| 1745 |
gdk_window_set_bg_pattern (GDK_WINDOW (private->parent), cr, |
1747 |
tmp_paint = *paint; |
| 1746 |
x_offset, y_offset); |
1748 |
tmp_paint.x_offset += private->x; |
|
|
1749 |
tmp_paint.y_offset += private->y; |
| 1750 |
|
| 1751 |
x_offset_cairo += private->x; |
| 1752 |
y_offset_cairo += private->y; |
| 1753 |
|
| 1754 |
setup_backing_rect_method (method, GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo); |
| 1747 |
} |
1755 |
} |
| 1748 |
else if (private->bg_pixmap && |
1756 |
else if (private->bg_pixmap && |
| 1749 |
private->bg_pixmap != GDK_PARENT_RELATIVE_BG && |
1757 |
private->bg_pixmap != GDK_PARENT_RELATIVE_BG && |
| 1750 |
private->bg_pixmap != GDK_NO_BG) |
1758 |
private->bg_pixmap != GDK_NO_BG) |
| 1751 |
{ |
1759 |
{ |
|
|
1760 |
/* This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=4320. |
| 1761 |
* In it, using a pixmap as a repeating pattern in Cairo, and painting it to a |
| 1762 |
* pixmap destination surface, can be very slow (on the order of seconds for a |
| 1763 |
* whole-screen copy). The workaround is to use pretty much the same code that |
| 1764 |
* we used in GTK+ 2.6 (pre-Cairo), which clears the double-buffer pixmap with |
| 1765 |
* a tiled GC XFillRectangle(). |
| 1766 |
*/ |
| 1767 |
|
| 1768 |
/* Actually computing this flag is left as an exercise for the reader */ |
| 1769 |
#if defined (G_OS_UNIX) |
| 1770 |
# define GDK_CAIRO_REPEAT_IS_FAST 0 |
| 1771 |
#else |
| 1772 |
# define GDK_CAIRO_REPEAT_IS_FAST 1 |
| 1773 |
#endif |
| 1774 |
|
| 1775 |
#if GDK_CAIRO_REPEAT_IS_FAST |
| 1752 |
cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap); |
1776 |
cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap); |
| 1753 |
cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); |
1777 |
cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); |
| 1754 |
cairo_surface_destroy (surface); |
1778 |
cairo_surface_destroy (surface); |
| 1755 |
|
1779 |
|
| 1756 |
if (x_offset != 0 || y_offset != 0) |
1780 |
if (x_offset_cairo != 0 || y_offset_cairo != 0) |
| 1757 |
{ |
1781 |
{ |
| 1758 |
cairo_matrix_t matrix; |
1782 |
cairo_matrix_t matrix; |
| 1759 |
cairo_matrix_init_translate (&matrix, x_offset, y_offset); |
1783 |
cairo_matrix_init_translate (&matrix, x_offset_cairo, y_offset_cairo); |
| 1760 |
cairo_pattern_set_matrix (pattern, &matrix); |
1784 |
cairo_pattern_set_matrix (pattern, &matrix); |
| 1761 |
} |
1785 |
} |
| 1762 |
|
1786 |
|
| 1763 |
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); |
1787 |
cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); |
| 1764 |
cairo_set_source (cr, pattern); |
1788 |
|
|
|
1789 |
method->cr = cairo_create (paint->surface); |
| 1790 |
method->gc = NULL; |
| 1791 |
|
| 1792 |
cairo_set_source (method->cr, pattern); |
| 1765 |
cairo_pattern_destroy (pattern); |
1793 |
cairo_pattern_destroy (pattern); |
|
|
1794 |
#else |
| 1795 |
guint gc_mask; |
| 1796 |
GdkGCValues gc_values; |
| 1797 |
|
| 1798 |
gc_values.fill = GDK_TILED; |
| 1799 |
gc_values.tile = private->bg_pixmap; |
| 1800 |
gc_values.ts_x_origin = -x_offset_cairo; |
| 1801 |
gc_values.ts_y_origin = -y_offset_cairo; |
| 1802 |
|
| 1803 |
gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; |
| 1804 |
|
| 1805 |
method->gc = gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask); |
| 1806 |
#endif |
| 1766 |
} |
1807 |
} |
| 1767 |
else |
1808 |
else |
| 1768 |
{ |
1809 |
{ |
| 1769 |
gdk_cairo_set_source_color (cr, &private->bg_color); |
1810 |
method->cr = cairo_create (paint->surface); |
|
|
1811 |
|
| 1812 |
gdk_cairo_set_source_color (method->cr, &private->bg_color); |
| 1770 |
} |
1813 |
} |
| 1771 |
} |
1814 |
} |
| 1772 |
|
1815 |
|
|
Lines 1779-1800
Link Here
|
| 1779 |
{ |
1822 |
{ |
| 1780 |
GdkWindowObject *private = (GdkWindowObject *)window; |
1823 |
GdkWindowObject *private = (GdkWindowObject *)window; |
| 1781 |
GdkWindowPaint *paint = private->paint_stack->data; |
1824 |
GdkWindowPaint *paint = private->paint_stack->data; |
| 1782 |
cairo_t *cr; |
1825 |
BackingRectMethod method; |
|
|
1826 |
#if 0 |
| 1827 |
GTimer *timer; |
| 1828 |
double elapsed; |
| 1829 |
#endif |
| 1783 |
|
1830 |
|
| 1784 |
if (GDK_WINDOW_DESTROYED (window)) |
1831 |
if (GDK_WINDOW_DESTROYED (window)) |
| 1785 |
return; |
1832 |
return; |
| 1786 |
|
1833 |
|
| 1787 |
cr = cairo_create (paint->surface); |
1834 |
#if 0 |
|
|
1835 |
timer = g_timer_new (); |
| 1836 |
#endif |
| 1837 |
|
| 1838 |
method.cr = NULL; |
| 1839 |
method.gc = NULL; |
| 1840 |
setup_backing_rect_method (&method, window, paint, 0, 0); |
| 1841 |
|
| 1842 |
if (method.cr) |
| 1843 |
{ |
| 1844 |
g_assert (method.gc == NULL); |
| 1845 |
|
| 1846 |
cairo_rectangle (method.cr, x, y, width, height); |
| 1847 |
cairo_clip (method.cr); |
| 1788 |
|
1848 |
|
| 1789 |
gdk_window_set_bg_pattern (window, cr, 0, 0); |
1849 |
gdk_cairo_region (method.cr, paint->region); |
|
|
1850 |
cairo_fill (method.cr); |
| 1790 |
|
1851 |
|
| 1791 |
cairo_rectangle (cr, x, y, width, height); |
1852 |
cairo_destroy (method.cr); |
| 1792 |
cairo_clip (cr); |
1853 |
#if 0 |
|
|
1854 |
elapsed = g_timer_elapsed (timer, NULL); |
| 1855 |
g_print ("Draw the background with Cairo: %fs\n", elapsed); |
| 1856 |
#endif |
| 1857 |
} |
| 1858 |
else |
| 1859 |
{ |
| 1860 |
g_assert (method.gc != NULL); |
| 1793 |
|
1861 |
|
| 1794 |
gdk_cairo_region (cr, paint->region); |
1862 |
gdk_gc_set_clip_region (method.gc, paint->region); |
| 1795 |
cairo_fill (cr); |
1863 |
gdk_draw_rectangle (window, method.gc, TRUE, x, y, width, height); |
|
|
1864 |
g_object_unref (method.gc); |
| 1865 |
|
| 1866 |
#if 0 |
| 1867 |
elapsed = g_timer_elapsed (timer, NULL); |
| 1868 |
g_print ("Draw the background with GDK: %fs\n", elapsed); |
| 1869 |
#endif |
| 1870 |
} |
| 1796 |
|
1871 |
|
| 1797 |
cairo_destroy (cr); |
1872 |
#if 0 |
|
|
1873 |
g_timer_destroy (timer); |
| 1874 |
#endif |
| 1798 |
} |
1875 |
} |
| 1799 |
|
1876 |
|
| 1800 |
/** |
1877 |
/** |