Add gdk_drawable_set_cairo_target().
2005-02-03 Owen Taylor <otaylor@redhat.com>
* gdk/gdkdrawable.[ch] gdkpixmap.c gdkwindow.c: Add
gdk_drawable_set_cairo_target().
* tests/testtreeflow.c (enum): Use grand not rand as a variable
name because one of the cairo headers is pulling in stdlib.h.
* tests/testcairo.c tests/Makefile.am: Add a simple cairo based
example.
* configure.in: Bump release to 2.7.0, gtk_binary_version to 2.7.0.
* Require libpangocairo for all backends.
This commit is contained in:
parent
8a5d05e253
commit
93344f6dfe
21 changed files with 489 additions and 21 deletions
15
ChangeLog
15
ChangeLog
|
|
@ -1,3 +1,18 @@
|
|||
2005-02-03 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.[ch] gdkpixmap.c gdkwindow.c: Add
|
||||
gdk_drawable_set_cairo_target().
|
||||
|
||||
* tests/testtreeflow.c (enum): Use grand not rand as a variable
|
||||
name because one of the cairo headers is pulling in stdlib.h.
|
||||
|
||||
* tests/testcairo.c tests/Makefile.am: Add a simple cairo based
|
||||
example.
|
||||
|
||||
* configure.in: Bump release to 2.7.0, gtk_binary_version to 2.7.0.
|
||||
|
||||
* Require libpangocairo for all backends.
|
||||
|
||||
2005-02-03 Tor Lillqvist <tml@novell.com>
|
||||
|
||||
* modules/input/gtkimcontextime.c (get_pango_attr_list): Use the
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
2005-02-03 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.[ch] gdkpixmap.c gdkwindow.c: Add
|
||||
gdk_drawable_set_cairo_target().
|
||||
|
||||
* tests/testtreeflow.c (enum): Use grand not rand as a variable
|
||||
name because one of the cairo headers is pulling in stdlib.h.
|
||||
|
||||
* tests/testcairo.c tests/Makefile.am: Add a simple cairo based
|
||||
example.
|
||||
|
||||
* configure.in: Bump release to 2.7.0, gtk_binary_version to 2.7.0.
|
||||
|
||||
* Require libpangocairo for all backends.
|
||||
|
||||
2005-02-03 Tor Lillqvist <tml@novell.com>
|
||||
|
||||
* modules/input/gtkimcontextime.c (get_pango_attr_list): Use the
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
2005-02-03 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gdk/gdkdrawable.[ch] gdkpixmap.c gdkwindow.c: Add
|
||||
gdk_drawable_set_cairo_target().
|
||||
|
||||
* tests/testtreeflow.c (enum): Use grand not rand as a variable
|
||||
name because one of the cairo headers is pulling in stdlib.h.
|
||||
|
||||
* tests/testcairo.c tests/Makefile.am: Add a simple cairo based
|
||||
example.
|
||||
|
||||
* configure.in: Bump release to 2.7.0, gtk_binary_version to 2.7.0.
|
||||
|
||||
* Require libpangocairo for all backends.
|
||||
|
||||
2005-02-03 Tor Lillqvist <tml@novell.com>
|
||||
|
||||
* modules/input/gtkimcontextime.c (get_pango_attr_list): Use the
|
||||
|
|
|
|||
22
configure.in
22
configure.in
|
|
@ -11,11 +11,11 @@ AC_PREREQ(2.54)
|
|||
# set GTK_BINARY_AGE and GTK_INTERFACE_AGE to 0.
|
||||
|
||||
m4_define([gtk_major_version], [2])
|
||||
m4_define([gtk_minor_version], [6])
|
||||
m4_define([gtk_micro_version], [2])
|
||||
m4_define([gtk_minor_version], [7])
|
||||
m4_define([gtk_micro_version], [0])
|
||||
m4_define([gtk_version],
|
||||
[gtk_major_version.gtk_minor_version.gtk_micro_version])
|
||||
m4_define([gtk_interface_age], [2])
|
||||
m4_define([gtk_interface_age], [0])
|
||||
m4_define([gtk_binary_age],
|
||||
[m4_eval(100 * gtk_minor_version + gtk_micro_version)])
|
||||
# This is the X.Y used in -lgtk-FOO-X.Y
|
||||
|
|
@ -26,7 +26,7 @@ m4_define([gtk_api_version], [2.0])
|
|||
# locations. (Should this be backwards-compat instead?)
|
||||
#
|
||||
#GTK_BINARY_VERSION=$GTK_MAJOR_VERSION.$GTK_MINOR_VERSION.$LT_CURRENT
|
||||
m4_define([gtk_binary_version], [2.4.0])
|
||||
m4_define([gtk_binary_version], [2.7.0])
|
||||
|
||||
# required versions of other packages
|
||||
m4_define([glib_required_version], [2.6.0])
|
||||
|
|
@ -1403,7 +1403,7 @@ fi
|
|||
#
|
||||
|
||||
if test "x$gdktarget" = "xx11"; then
|
||||
PANGO_PACKAGES=pangoxft
|
||||
PANGO_PACKAGES="pangoxft pangocairo"
|
||||
|
||||
# We no longer use pangox, but if we find it, we link to it
|
||||
# for binary compatibility.
|
||||
|
|
@ -1411,11 +1411,11 @@ if test "x$gdktarget" = "xx11"; then
|
|||
PANGO_PACKAGES="$PANGO_PACKAGES pangox"
|
||||
fi
|
||||
elif test "x$gdktarget" = "xwin32"; then
|
||||
PANGO_PACKAGES=pangowin32
|
||||
PANGO_PACKAGES="pangowin32 pangocairo"
|
||||
elif test "x$gdktarget" = "xlinux-fb"; then
|
||||
PANGO_PACKAGES=pangoft2
|
||||
PANGO_PACKAGES="pangoft2 pangocairo"
|
||||
else
|
||||
PANGO_PACKAGES=pango
|
||||
PANGO_PACKAGES="pango pangocairo"
|
||||
fi
|
||||
|
||||
# Check for Pango flags
|
||||
|
|
@ -1428,10 +1428,8 @@ if $PKG_CONFIG --exists $PANGO_PACKAGES ; then
|
|||
AC_MSG_RESULT($PANGO_CFLAGS $PANGO_LIBS)
|
||||
else
|
||||
AC_MSG_ERROR([
|
||||
*** Pango not found. Pango is required to build GTK+.
|
||||
*** See http://www.pango.org for Pango information.
|
||||
*** For the framebuffer target, you will need to build
|
||||
*** Pango with freetype support.
|
||||
*** Pango not found. Pango built with Cairo support is required
|
||||
*** to build GTK+. See http://www.pango.org for Pango information.
|
||||
])
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -278,6 +278,17 @@ Applications should never have any reason to use this facility
|
|||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gdk_display_warp_pointer ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@display:
|
||||
@screen:
|
||||
@x:
|
||||
@y:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gdk_display_supports_cursor_color ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -440,6 +440,15 @@ Since: 2.2
|
|||
@timestamp:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gdk_x11_display_get_user_time ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@display:
|
||||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gdk_x11_colormap_foreign_new ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ property is set to a pixbuf, it renders that one.
|
|||
</para>
|
||||
|
||||
|
||||
<!-- ##### ARG GtkCellRendererPixbuf:follow-state ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GtkCellRendererPixbuf:pixbuf ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -237,6 +237,16 @@ the #GtkCellRendererText allows to edit its text using an entry.
|
|||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GtkCellRendererText:wrap-mode ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GtkCellRendererText:wrap-width ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
<!-- ##### FUNCTION gtk_cell_renderer_text_new ##### -->
|
||||
<para>
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,17 @@ used for right-to-left locales.
|
|||
@Returns:
|
||||
|
||||
|
||||
<!-- ##### FUNCTION gtk_stock_set_translate_func ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
@domain:
|
||||
@func:
|
||||
@data:
|
||||
@notify:
|
||||
|
||||
|
||||
<!-- ##### MACRO GTK_STOCK_ABOUT ##### -->
|
||||
<para>
|
||||
The "About" item.
|
||||
|
|
|
|||
|
|
@ -1221,6 +1221,29 @@ gdk_drawable_real_get_visible_region (GdkDrawable *drawable)
|
|||
return gdk_region_rectangle (&rect);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drawable_set_cairo_target:
|
||||
* @drawable: a #GdkDrawable
|
||||
* @cr: a cairo context
|
||||
*
|
||||
* Sets the given drawable as the target surface for a Cairo context.
|
||||
* Note that when @drawable is a window and gdk_window_begin_paint()
|
||||
* has been called, the target surface will be set to the temporary
|
||||
* backing pixmap, so you can only use the Cairo context until
|
||||
* the matching call to gdk_window_end_paint().
|
||||
*
|
||||
* Since: 2.10
|
||||
**/
|
||||
void
|
||||
gdk_drawable_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_DRAWABLE (drawable));
|
||||
g_return_if_fail (cr != NULL);
|
||||
|
||||
return GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_target (drawable, cr);
|
||||
}
|
||||
|
||||
static void
|
||||
composite (guchar *src_buf,
|
||||
gint src_rowstride,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include <gdk/gdkrgb.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
|
@ -168,8 +170,10 @@ struct _GdkDrawableClass
|
|||
GdkTrapezoid *trapezoids,
|
||||
gint n_trapezoids);
|
||||
|
||||
void (*set_cairo_target) (GdkDrawable *drawable,
|
||||
cairo_t *cr);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gdk_reserved3) (void);
|
||||
void (*_gdk_reserved4) (void);
|
||||
void (*_gdk_reserved5) (void);
|
||||
void (*_gdk_reserved6) (void);
|
||||
|
|
@ -388,6 +392,9 @@ GdkImage *gdk_drawable_copy_to_image (GdkDrawable *drawable,
|
|||
GdkRegion *gdk_drawable_get_clip_region (GdkDrawable *drawable);
|
||||
GdkRegion *gdk_drawable_get_visible_region (GdkDrawable *drawable);
|
||||
|
||||
void gdk_drawable_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr);
|
||||
|
||||
gboolean gdk_draw_rectangle_alpha_libgtk_only (GdkDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
|
|
|
|||
|
|
@ -144,6 +144,9 @@ static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable,
|
|||
gint width,
|
||||
gint height);
|
||||
|
||||
static void gdk_pixmap_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr);
|
||||
|
||||
static GdkVisual* gdk_pixmap_real_get_visual (GdkDrawable *drawable);
|
||||
static gint gdk_pixmap_real_get_depth (GdkDrawable *drawable);
|
||||
static void gdk_pixmap_real_set_colormap (GdkDrawable *drawable,
|
||||
|
|
@ -224,6 +227,7 @@ gdk_pixmap_class_init (GdkPixmapObjectClass *klass)
|
|||
drawable_class->get_colormap = gdk_pixmap_real_get_colormap;
|
||||
drawable_class->get_visual = gdk_pixmap_real_get_visual;
|
||||
drawable_class->_copy_to_image = gdk_pixmap_copy_to_image;
|
||||
drawable_class->set_cairo_target = gdk_pixmap_set_cairo_target;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -517,6 +521,14 @@ gdk_pixmap_copy_to_image (GdkDrawable *drawable,
|
|||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixmap_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr)
|
||||
{
|
||||
gdk_drawable_set_cairo_target (((GdkPixmapObject*)drawable)->impl,
|
||||
cr);
|
||||
}
|
||||
|
||||
static GdkBitmap *
|
||||
make_solid_mask (GdkScreen *screen, gint width, gint height)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -157,6 +157,9 @@ static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable,
|
|||
gint width,
|
||||
gint height);
|
||||
|
||||
static void gdk_window_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr);
|
||||
|
||||
static void gdk_window_real_get_size (GdkDrawable *drawable,
|
||||
gint *width,
|
||||
gint *height);
|
||||
|
|
@ -263,6 +266,7 @@ gdk_window_class_init (GdkWindowObjectClass *klass)
|
|||
drawable_class->get_colormap = gdk_window_real_get_colormap;
|
||||
drawable_class->get_visual = gdk_window_real_get_visual;
|
||||
drawable_class->_copy_to_image = gdk_window_copy_to_image;
|
||||
drawable_class->set_cairo_target = gdk_window_set_cairo_target;
|
||||
drawable_class->get_clip_region = gdk_window_get_clip_region;
|
||||
drawable_class->get_visible_region = gdk_window_get_visible_region;
|
||||
drawable_class->get_composite_drawable = gdk_window_get_composite_drawable;
|
||||
|
|
@ -2091,6 +2095,26 @@ gdk_window_copy_to_image (GdkDrawable *drawable,
|
|||
width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_window_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GdkWindowObject *private = (GdkWindowObject*) drawable;
|
||||
gint x_offset, y_offset;
|
||||
|
||||
gdk_window_get_offsets (GDK_WINDOW (drawable), &x_offset, &y_offset);
|
||||
|
||||
if (private->paint_stack)
|
||||
{
|
||||
GdkWindowPaint *paint = private->paint_stack->data;
|
||||
gdk_drawable_set_cairo_target (paint->pixmap, cr);
|
||||
}
|
||||
else
|
||||
gdk_drawable_set_cairo_target (private->impl, cr);
|
||||
|
||||
cairo_translate (cr, - x_offset, - y_offset);
|
||||
}
|
||||
|
||||
/* Code for dirty-region queueing
|
||||
*/
|
||||
static GSList *update_windows = NULL;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,9 @@ static void gdk_x11_draw_trapezoids (GdkDrawable *drawable,
|
|||
GdkTrapezoid *trapezoids,
|
||||
gint n_trapezoids);
|
||||
|
||||
static void gdk_x11_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr);
|
||||
|
||||
static void gdk_x11_set_colormap (GdkDrawable *drawable,
|
||||
GdkColormap *colormap);
|
||||
|
||||
|
|
@ -215,6 +218,8 @@ gdk_drawable_impl_x11_class_init (GdkDrawableImplX11Class *klass)
|
|||
drawable_class->draw_pixbuf = gdk_x11_draw_pixbuf;
|
||||
drawable_class->draw_trapezoids = gdk_x11_draw_trapezoids;
|
||||
|
||||
drawable_class->set_cairo_target = gdk_x11_set_cairo_target;
|
||||
|
||||
drawable_class->set_colormap = gdk_x11_set_colormap;
|
||||
drawable_class->get_colormap = gdk_x11_get_colormap;
|
||||
|
||||
|
|
@ -1558,6 +1563,51 @@ gdk_x11_draw_trapezoids (GdkDrawable *drawable,
|
|||
g_free (xtrapezoids);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_x11_drawable_get_cairo_surface (GdkDrawable *drawable)
|
||||
{
|
||||
GdkDrawableImplX11 *impl = GDK_DRAWABLE_IMPL_X11 (drawable);
|
||||
GdkColormap *colormap;
|
||||
GdkVisual *visual;
|
||||
|
||||
if (GDK_IS_WINDOW_IMPL_X11 (drawable) &&
|
||||
GDK_WINDOW_DESTROYED (impl->wrapper))
|
||||
return NULL;
|
||||
|
||||
colormap = gdk_drawable_get_colormap (drawable);
|
||||
if (!colormap)
|
||||
{
|
||||
g_warning ("Using Cairo rendering requires the drawable argument to\n"
|
||||
"have a specified colormap. All windows have a colormap,\n"
|
||||
"however, pixmaps only have colormap by default if they\n"
|
||||
"were created with a non-NULL window argument. Otherwise\n"
|
||||
"a colormap must be set on them with gdk_drawable_set_colormap");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
visual = gdk_colormap_get_visual (colormap);
|
||||
|
||||
if (!impl->cairo_surface)
|
||||
{
|
||||
impl->cairo_surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (impl->screen),
|
||||
impl->xid,
|
||||
GDK_VISUAL_XVISUAL (visual),
|
||||
CAIRO_FORMAT_RGB24,
|
||||
GDK_COLORMAP_XCOLORMAP (colormap));
|
||||
}
|
||||
|
||||
return impl->cairo_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_x11_set_cairo_target (GdkDrawable *drawable,
|
||||
cairo_t *cr)
|
||||
{
|
||||
cairo_surface_t *surface = gdk_x11_drawable_get_cairo_surface (drawable);
|
||||
if (surface)
|
||||
cairo_set_target_surface (cr, surface);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_draw_rectangle_alpha_libgtk_only:
|
||||
* @drawable: The #GdkDrawable to draw on
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ struct _GdkDrawableImplX11
|
|||
GdkScreen *screen;
|
||||
|
||||
XftDraw *xft_draw;
|
||||
cairo_surface_t *cairo_surface;
|
||||
};
|
||||
|
||||
struct _GdkDrawableImplX11Class
|
||||
|
|
|
|||
|
|
@ -135,6 +135,12 @@ gdk_pixmap_impl_x11_finalize (GObject *object)
|
|||
if (draw_impl->xft_draw)
|
||||
XftDrawDestroy (draw_impl->xft_draw);
|
||||
|
||||
if (draw_impl->cairo_surface)
|
||||
{
|
||||
cairo_surface_destroy (draw_impl->cairo_surface);
|
||||
draw_impl->cairo_surface = NULL;
|
||||
}
|
||||
|
||||
if (!impl->is_foreign)
|
||||
XFreePixmap (GDK_DISPLAY_XDISPLAY (display), GDK_PIXMAP_XID (wrapper));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1144,7 +1144,16 @@ _gdk_windowing_window_destroy (GdkWindow *window,
|
|||
draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
|
||||
|
||||
if (draw_impl->xft_draw)
|
||||
XftDrawDestroy (draw_impl->xft_draw);
|
||||
{
|
||||
XftDrawDestroy (draw_impl->xft_draw);
|
||||
draw_impl->xft_draw = NULL;
|
||||
}
|
||||
|
||||
if (draw_impl->cairo_surface)
|
||||
{
|
||||
cairo_surface_destroy (draw_impl->cairo_surface);
|
||||
draw_impl->cairo_surface = NULL;
|
||||
}
|
||||
|
||||
if (!recursing && !foreign_destroy)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ pixbuf-threads
|
|||
simple
|
||||
stresstest-toolbar
|
||||
testactions
|
||||
testcairo
|
||||
testcalendar
|
||||
testcombo
|
||||
testcombochange
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ endif
|
|||
|
||||
noinst_PROGRAMS = \
|
||||
simple \
|
||||
testcairo \
|
||||
testcalendar \
|
||||
testcombo \
|
||||
testcombochange \
|
||||
|
|
@ -72,6 +73,7 @@ noinst_PROGRAMS = \
|
|||
simple_DEPENDENCIES = $(TEST_DEPS)
|
||||
testicontheme_DEPENDENCIES = $(TEST_DEPS)
|
||||
testiconview_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcairo_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcalendar_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcombo_DEPENDENCIES = $(TEST_DEPS)
|
||||
testcombochange_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
|
@ -106,6 +108,7 @@ testmerge_DEPENDENCIES = $(TEST_DEPS)
|
|||
testactions_DEPENDENCIES = $(TEST_DEPS)
|
||||
|
||||
simple_LDADD = $(LDADDS)
|
||||
testcairo_LDADD = $(LDADDS)
|
||||
testcalendar_LDADD = $(LDADDS)
|
||||
testcombo_LDADD = $(LDADDS)
|
||||
testcombochange_LDADD = $(LDADDS)
|
||||
|
|
|
|||
243
tests/testcairo.c
Normal file
243
tests/testcairo.c
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/* testimage.c
|
||||
* Copyright (C) 2005 Red Hat, Inc.
|
||||
* Based on cairo-demo/X11/cairo-knockout.c
|
||||
*
|
||||
* Author: Owen Taylor
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static void
|
||||
oval_path (cairo_t *cr,
|
||||
double xc, double yc,
|
||||
double xr, double yr)
|
||||
{
|
||||
cairo_matrix_t *matrix;
|
||||
|
||||
matrix = cairo_matrix_create ();
|
||||
cairo_current_matrix (cr, matrix);
|
||||
|
||||
cairo_translate (cr, xc, yc);
|
||||
cairo_scale (cr, 1.0, yr / xr);
|
||||
cairo_move_to (cr, xr, 0.0);
|
||||
cairo_arc (cr,
|
||||
0, 0,
|
||||
xr,
|
||||
0, 2 * G_PI);
|
||||
cairo_close_path (cr);
|
||||
|
||||
cairo_set_matrix (cr, matrix);
|
||||
cairo_matrix_destroy (matrix);
|
||||
}
|
||||
|
||||
/* Create a path that is a circular oval with radii xr, yr at xc,
|
||||
* yc.
|
||||
*/
|
||||
/* Fill the given area with checks in the standard style
|
||||
* for showing compositing effects.
|
||||
*
|
||||
* It would make sense to do this as a repeating surface,
|
||||
* but most implementations of RENDER currently have broken
|
||||
* implementations of repeat + transform, even when the
|
||||
* transform is a translation.
|
||||
*/
|
||||
static void
|
||||
fill_checks (cairo_t *cr,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
#define CHECK_SIZE 32
|
||||
|
||||
cairo_rectangle (cr, x, y, width, height);
|
||||
cairo_set_rgb_color (cr, 0.4, 0.4, 0.4);
|
||||
cairo_fill (cr);
|
||||
|
||||
/* Only works for CHECK_SIZE a power of 2 */
|
||||
j = x & (-CHECK_SIZE);
|
||||
|
||||
for (; j < height; j += CHECK_SIZE)
|
||||
{
|
||||
i = y & (-CHECK_SIZE);
|
||||
for (; i < width; i += CHECK_SIZE)
|
||||
if ((i / CHECK_SIZE + j / CHECK_SIZE) % 2 == 0)
|
||||
cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE);
|
||||
}
|
||||
|
||||
cairo_set_rgb_color (cr, 0.7, 0.7, 0.7);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
/* Draw a red, green, and blue circle equally spaced inside
|
||||
* the larger circle of radius r at (xc, yc)
|
||||
*/
|
||||
static void
|
||||
draw_3circles (cairo_t *cr,
|
||||
double xc, double yc,
|
||||
double radius)
|
||||
{
|
||||
double subradius = radius * (2 / 3. - 0.1);
|
||||
|
||||
cairo_set_rgb_color (cr, 1., 0., 0.);
|
||||
oval_path (cr,
|
||||
xc + radius / 3. * cos (G_PI * (0.5)),
|
||||
yc - radius / 3. * sin (G_PI * (0.5)),
|
||||
subradius, subradius);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_set_rgb_color (cr, 0., 1., 0.);
|
||||
oval_path (cr,
|
||||
xc + radius / 3. * cos (G_PI * (0.5 + 2/.3)),
|
||||
yc - radius / 3. * sin (G_PI * (0.5 + 2/.3)),
|
||||
subradius, subradius);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_set_rgb_color (cr, 0., 0., 1.);
|
||||
oval_path (cr,
|
||||
xc + radius / 3. * cos (G_PI * (0.5 + 4/.3)),
|
||||
yc - radius / 3. * sin (G_PI * (0.5 + 4/.3)),
|
||||
subradius, subradius);
|
||||
cairo_fill (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
draw (cairo_t *cr,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
cairo_surface_t *overlay, *punch, *circles;
|
||||
|
||||
/* Fill the background */
|
||||
double radius = 0.5 * (width < height ? width : height) - 10;
|
||||
double xc = width / 2.;
|
||||
double yc = height / 2.;
|
||||
|
||||
overlay = cairo_surface_create_similar (cairo_current_target_surface (cr),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width, height);
|
||||
if (overlay == NULL)
|
||||
return;
|
||||
|
||||
punch = cairo_surface_create_similar (cairo_current_target_surface (cr),
|
||||
CAIRO_FORMAT_A8,
|
||||
width, height);
|
||||
if (punch == NULL)
|
||||
return;
|
||||
|
||||
circles = cairo_surface_create_similar (cairo_current_target_surface (cr),
|
||||
CAIRO_FORMAT_ARGB32,
|
||||
width, height);
|
||||
if (circles == NULL)
|
||||
return;
|
||||
|
||||
fill_checks (cr, 0, 0, width, height);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_target_surface (cr, overlay);
|
||||
cairo_identity_matrix (cr);
|
||||
|
||||
/* Draw a black circle on the overlay
|
||||
*/
|
||||
cairo_set_rgb_color (cr, 0., 0., 0.);
|
||||
oval_path (cr, xc, yc, radius, radius);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_save (cr);
|
||||
cairo_set_target_surface (cr, punch);
|
||||
|
||||
/* Draw 3 circles to the punch surface, then cut
|
||||
* that out of the main circle in the overlay
|
||||
*/
|
||||
draw_3circles (cr, xc, yc, radius);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OUT_REVERSE);
|
||||
cairo_show_surface (cr, punch, width, height);
|
||||
|
||||
/* Now draw the 3 circles in a subgroup again
|
||||
* at half intensity, and use OperatorAdd to join up
|
||||
* without seams.
|
||||
*/
|
||||
cairo_save (cr);
|
||||
cairo_set_target_surface (cr, circles);
|
||||
|
||||
cairo_set_alpha (cr, 0.5);
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
|
||||
draw_3circles (cr, xc, yc, radius);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_ADD);
|
||||
cairo_show_surface (cr, circles, width, height);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
cairo_show_surface (cr, overlay, width, height);
|
||||
|
||||
cairo_surface_destroy (overlay);
|
||||
cairo_surface_destroy (punch);
|
||||
cairo_surface_destroy (circles);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
on_expose_event (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data)
|
||||
{
|
||||
cairo_t *cr;
|
||||
|
||||
cr = cairo_create ();
|
||||
gdk_drawable_set_cairo_target (GDK_DRAWABLE (widget->window), cr);
|
||||
|
||||
draw (cr, widget->allocation.width, widget->allocation.height);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window, *darea;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
|
||||
gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "cairo: Knockout Groups");
|
||||
|
||||
darea = gtk_drawing_area_new ();
|
||||
gtk_container_add (GTK_CONTAINER (window), darea);
|
||||
|
||||
g_signal_connect (darea, "expose-event",
|
||||
G_CALLBACK (on_expose_event), NULL);
|
||||
g_signal_connect (window, "destroy-event",
|
||||
G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
GtkTreeModel *model = NULL;
|
||||
static GRand *rand = NULL;
|
||||
static GRand *grand = NULL;
|
||||
GtkTreeSelection *selection = NULL;
|
||||
enum
|
||||
{
|
||||
|
|
@ -32,12 +32,12 @@ initialize_model (void)
|
|||
GtkTreeIter iter;
|
||||
|
||||
model = (GtkTreeModel *) gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING);
|
||||
rand = g_rand_new ();
|
||||
grand = g_rand_new ();
|
||||
for (i = 0; i < NUM_ROWS; i++)
|
||||
{
|
||||
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
|
||||
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
|
||||
TEXT_COLUMN, words[g_rand_int_range (rand, 0, NUM_WORDS)],
|
||||
TEXT_COLUMN, words[g_rand_int_range (grand, 0, NUM_WORDS)],
|
||||
-1);
|
||||
}
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ futz_row (void)
|
|||
GtkTreeIter iter;
|
||||
GtkTreeIter iter2;
|
||||
|
||||
i = g_rand_int_range (rand, 0,
|
||||
i = g_rand_int_range (grand, 0,
|
||||
gtk_tree_model_iter_n_children (model, NULL));
|
||||
path = gtk_tree_path_new ();
|
||||
gtk_tree_path_append_index (path, i);
|
||||
|
|
@ -59,14 +59,14 @@ futz_row (void)
|
|||
|
||||
if (gtk_tree_selection_iter_is_selected (selection, &iter))
|
||||
return;
|
||||
switch (g_rand_int_range (rand, 0, 3))
|
||||
switch (g_rand_int_range (grand, 0, 3))
|
||||
{
|
||||
case 0:
|
||||
/* insert */
|
||||
gtk_list_store_insert_after (GTK_LIST_STORE (model),
|
||||
&iter2, &iter);
|
||||
gtk_list_store_set (GTK_LIST_STORE (model), &iter2,
|
||||
TEXT_COLUMN, words[g_rand_int_range (rand, 0, NUM_WORDS)],
|
||||
TEXT_COLUMN, words[g_rand_int_range (grand, 0, NUM_WORDS)],
|
||||
-1);
|
||||
break;
|
||||
case 1:
|
||||
|
|
@ -81,7 +81,7 @@ futz_row (void)
|
|||
if (gtk_tree_model_iter_n_children (model, NULL) == 0)
|
||||
return;
|
||||
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
|
||||
TEXT_COLUMN, words[g_rand_int_range (rand, 0, NUM_WORDS)],
|
||||
TEXT_COLUMN, words[g_rand_int_range (grand, 0, NUM_WORDS)],
|
||||
-1);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue