[GtkGLExt] Pango support
- From: "Kouhei Sutou" <kou cozmixng org>
- To: gtkglext-list gnome org
- Subject: [GtkGLExt] Pango support
- Date: Thu, 1 Jun 2006 12:01:11 +0900
Hi,
This is the same contents of the patch #1496260 on SF.net:
http://sourceforge.net/tracker/index.php?func=detail&aid=1496260&group_id=54333&atid=473436
GTK+ >= 2.6 supports Pango and GdkDrawable has some
pango related interfaces:
* draw_glyphs_transformed()
* draw_trapezoids()
And GTK+ >= 2.8 requires ref_cairo_surface() because
GTK+ >= 2.8 uses cairo as backend.
But current GdkGLWindow and GdkGLPixmap don't provide
the above interfaces.
Thanks,
--
kou
Index: gdk/gdkglwindow.c
===================================================================
RCS file: /cvsroot/gtkglext/gtkglext/gdk/gdkglwindow.c,v
retrieving revision 1.46
diff -u -p -r1.46 gdkglwindow.c
--- gdk/gdkglwindow.c 20 Feb 2004 09:38:12 -0000 1.46
+++ gdk/gdkglwindow.c 28 May 2006 03:50:50 -0000
@@ -104,7 +104,7 @@ static void gdk_gl_window_set_co
GdkColormap *cmap);
static GdkColormap *gdk_gl_window_get_colormap (GdkDrawable *drawable);
static GdkVisual *gdk_gl_window_get_visual (GdkDrawable *drawable);
-#if !(GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0)
+#if GTK_CHECK_VERSION(2,2,0)
static GdkScreen *gdk_gl_window_get_screen (GdkDrawable *drawable);
#endif
static GdkImage *gdk_gl_window_get_image (GdkDrawable *drawable,
@@ -141,6 +141,22 @@ static GdkImage *gdk_gl_window_copy_t
gint dest_y,
gint width,
gint height);
+#if GTK_CHECK_VERSION(2,6,0)
+static void gdk_gl_window_draw_glyphs_transformed (GdkDrawable *drawable,
+ GdkGC *gc,
+ PangoMatrix *matrix,
+ PangoFont *font,
+ gint x,
+ gint y,
+ PangoGlyphString *glyphs);
+static void gdk_gl_window_draw_trapezoids (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkTrapezoid *trapezoids,
+ gint n_trapezoids);
+#endif
+#if GTK_CHECK_VERSION(2,8,0)
+static cairo_surface_t *gdk_gl_window_ref_cairo_surface (GdkDrawable *drawable);
+#endif
static void gdk_gl_window_class_init (GdkGLWindowClass *klass);
static void gdk_gl_window_finalize (GObject *object);
@@ -203,19 +219,26 @@ gdk_gl_window_class_init (GdkGLWindowCla
drawable_class->set_colormap = gdk_gl_window_set_colormap;
drawable_class->get_colormap = gdk_gl_window_get_colormap;
drawable_class->get_visual = gdk_gl_window_get_visual;
-#if !(GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0)
+#if GTK_CHECK_VERSION(2,2,0)
drawable_class->get_screen = gdk_gl_window_get_screen;
#endif
drawable_class->get_image = gdk_gl_window_get_image;
drawable_class->get_clip_region = gdk_gl_window_get_clip_region;
drawable_class->get_visible_region = gdk_gl_window_get_visible_region;
drawable_class->get_composite_drawable = gdk_gl_window_get_composite_drawable;
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0
- drawable_class->_draw_pixbuf = gdk_gl_window_draw_pixbuf;
-#else
+#if GTK_CHECK_VERSION(2,2,0)
drawable_class->draw_pixbuf = gdk_gl_window_draw_pixbuf;
+#else
+ drawable_class->_draw_pixbuf = gdk_gl_window_draw_pixbuf;
#endif
drawable_class->_copy_to_image = gdk_gl_window_copy_to_image;
+#if GTK_CHECK_VERSION(2,6,0)
+ drawable_class->draw_glyphs_transformed = gdk_gl_window_draw_glyphs_transformed;
+ drawable_class->draw_trapezoids = gdk_gl_window_draw_trapezoids;
+#endif
+#if GTK_CHECK_VERSION(2,8,0)
+ drawable_class->ref_cairo_surface = gdk_gl_window_ref_cairo_surface;
+#endif
}
static void
@@ -498,7 +521,7 @@ gdk_gl_window_get_visual (GdkDrawable *d
return GDK_DRAWABLE_GET_CLASS (real_drawable)->get_visual (real_drawable);
}
-#if !(GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0)
+#if GTK_CHECK_VERSION(2,2,0)
static GdkScreen *
gdk_gl_window_get_screen (GdkDrawable *drawable)
@@ -578,20 +601,7 @@ gdk_gl_window_draw_pixbuf (GdkDrawable *
{
GdkDrawable *real_drawable = ((GdkGLWindow *) drawable)->drawable;
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0
- GDK_DRAWABLE_GET_CLASS (real_drawable)->_draw_pixbuf (real_drawable,
- gc,
- pixbuf,
- src_x,
- src_y,
- dest_x,
- dest_y,
- width,
- height,
- dither,
- x_dither,
- y_dither);
-#else
+#if GTK_CHECK_VERSION(2,2,0)
GDK_DRAWABLE_GET_CLASS (real_drawable)->draw_pixbuf (real_drawable,
gc,
pixbuf,
@@ -604,6 +614,19 @@ gdk_gl_window_draw_pixbuf (GdkDrawable *
dither,
x_dither,
y_dither);
+#else
+ GDK_DRAWABLE_GET_CLASS (real_drawable)->_draw_pixbuf (real_drawable,
+ gc,
+ pixbuf,
+ src_x,
+ src_y,
+ dest_x,
+ dest_y,
+ width,
+ height,
+ dither,
+ x_dither,
+ y_dither);
#endif
}
@@ -629,6 +652,53 @@ gdk_gl_window_copy_to_image (GdkDrawable
height);
}
+#if GTK_CHECK_VERSION(2,6,0)
+static void
+gdk_gl_window_draw_glyphs_transformed (GdkDrawable *drawable,
+ GdkGC *gc,
+ PangoMatrix *matrix,
+ PangoFont *font,
+ gint x,
+ gint y,
+ PangoGlyphString *glyphs)
+{
+ GdkDrawable *real_drawable = ((GdkGLWindow *) drawable)->drawable;
+
+ GDK_DRAWABLE_GET_CLASS (real_drawable)->draw_glyphs_transformed (real_drawable,
+ gc,
+ matrix,
+ font,
+ x,
+ y,
+ glyphs);
+}
+
+static void
+gdk_gl_window_draw_trapezoids (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkTrapezoid *trapezoids,
+ gint n_trapezoids)
+{
+ GdkDrawable *real_drawable = ((GdkGLWindow *) drawable)->drawable;
+
+ GDK_DRAWABLE_GET_CLASS (real_drawable)->draw_trapezoids (real_drawable,
+ gc,
+ trapezoids,
+ n_trapezoids);
+}
+#endif
+
+#if GTK_CHECK_VERSION(2,8,0)
+static cairo_surface_t *
+gdk_gl_window_ref_cairo_surface (GdkDrawable *drawable)
+{
+ GdkDrawable *real_drawable = ((GdkGLWindow *) drawable)->drawable;
+
+ return GDK_DRAWABLE_GET_CLASS (real_drawable)->ref_cairo_surface (real_drawable);
+}
+#endif
+
+
/*< private >*/
void
_gdk_gl_window_get_size (GdkGLDrawable *gldrawable,
Index: gdk/gdkglpixmap.c
===================================================================
RCS file: /cvsroot/gtkglext/gtkglext/gdk/gdkglpixmap.c,v
retrieving revision 1.38
diff -u -p -r1.38 gdkglpixmap.c
--- gdk/gdkglpixmap.c 20 Feb 2004 09:38:12 -0000 1.38
+++ gdk/gdkglpixmap.c 28 May 2006 03:50:50 -0000
@@ -104,7 +104,7 @@ static void gdk_gl_pixmap_set_co
GdkColormap *cmap);
static GdkColormap *gdk_gl_pixmap_get_colormap (GdkDrawable *drawable);
static GdkVisual *gdk_gl_pixmap_get_visual (GdkDrawable *drawable);
-#if !(GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0)
+#if GTK_CHECK_VERSION(2,2,0)
static GdkScreen *gdk_gl_pixmap_get_screen (GdkDrawable *drawable);
#endif
static GdkImage *gdk_gl_pixmap_get_image (GdkDrawable *drawable,
@@ -141,6 +141,22 @@ static GdkImage *gdk_gl_pixmap_copy_t
gint dest_y,
gint width,
gint height);
+#if GTK_CHECK_VERSION(2,6,0)
+static void gdk_gl_pixmap_draw_glyphs_transformed (GdkDrawable *drawable,
+ GdkGC *gc,
+ PangoMatrix *matrix,
+ PangoFont *font,
+ gint x,
+ gint y,
+ PangoGlyphString *glyphs);
+static void gdk_gl_pixmap_draw_trapezoids (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkTrapezoid *trapezoids,
+ gint n_trapezoids);
+#endif
+#if GTK_CHECK_VERSION(2,8,0)
+static cairo_surface_t *gdk_gl_pixmap_ref_cairo_surface (GdkDrawable *drawable);
+#endif
static void gdk_gl_pixmap_class_init (GdkGLPixmapClass *klass);
static void gdk_gl_pixmap_finalize (GObject *object);
@@ -203,19 +219,26 @@ gdk_gl_pixmap_class_init (GdkGLPixmapCla
drawable_class->set_colormap = gdk_gl_pixmap_set_colormap;
drawable_class->get_colormap = gdk_gl_pixmap_get_colormap;
drawable_class->get_visual = gdk_gl_pixmap_get_visual;
-#if !(GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0)
+#if GTK_CHECK_VERSION(2,2,0)
drawable_class->get_screen = gdk_gl_pixmap_get_screen;
#endif
drawable_class->get_image = gdk_gl_pixmap_get_image;
drawable_class->get_clip_region = gdk_gl_pixmap_get_clip_region;
drawable_class->get_visible_region = gdk_gl_pixmap_get_visible_region;
drawable_class->get_composite_drawable = gdk_gl_pixmap_get_composite_drawable;
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0
- drawable_class->_draw_pixbuf = gdk_gl_pixmap_draw_pixbuf;
-#else
+#if GTK_CHECK_VERSION(2,2,0)
drawable_class->draw_pixbuf = gdk_gl_pixmap_draw_pixbuf;
+#else
+ drawable_class->_draw_pixbuf = gdk_gl_pixmap_draw_pixbuf;
#endif
drawable_class->_copy_to_image = gdk_gl_pixmap_copy_to_image;
+#if GTK_CHECK_VERSION(2,6,0)
+ drawable_class->draw_glyphs_transformed = gdk_gl_pixmap_draw_glyphs_transformed;
+ drawable_class->draw_trapezoids = gdk_gl_pixmap_draw_trapezoids;
+#endif
+#if GTK_CHECK_VERSION(2,8,0)
+ drawable_class->ref_cairo_surface = gdk_gl_pixmap_ref_cairo_surface;
+#endif
}
static void
@@ -498,7 +521,7 @@ gdk_gl_pixmap_get_visual (GdkDrawable *d
return GDK_DRAWABLE_GET_CLASS (real_drawable)->get_visual (real_drawable);
}
-#if !(GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0)
+#if GTK_CHECK_VERSION(2,2,0)
static GdkScreen *
gdk_gl_pixmap_get_screen (GdkDrawable *drawable)
@@ -578,20 +601,7 @@ gdk_gl_pixmap_draw_pixbuf (GdkDrawable *
{
GdkDrawable *real_drawable = ((GdkGLPixmap *) drawable)->drawable;
-#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION == 0
- GDK_DRAWABLE_GET_CLASS (real_drawable)->_draw_pixbuf (real_drawable,
- gc,
- pixbuf,
- src_x,
- src_y,
- dest_x,
- dest_y,
- width,
- height,
- dither,
- x_dither,
- y_dither);
-#else
+#if GTK_CHECK_VERSION(2,2,0)
GDK_DRAWABLE_GET_CLASS (real_drawable)->draw_pixbuf (real_drawable,
gc,
pixbuf,
@@ -604,6 +614,19 @@ gdk_gl_pixmap_draw_pixbuf (GdkDrawable *
dither,
x_dither,
y_dither);
+#else
+ GDK_DRAWABLE_GET_CLASS (real_drawable)->_draw_pixbuf (real_drawable,
+ gc,
+ pixbuf,
+ src_x,
+ src_y,
+ dest_x,
+ dest_y,
+ width,
+ height,
+ dither,
+ x_dither,
+ y_dither);
#endif
}
@@ -629,6 +652,52 @@ gdk_gl_pixmap_copy_to_image (GdkDrawable
height);
}
+#if GTK_CHECK_VERSION(2,6,0)
+static void
+gdk_gl_pixmap_draw_glyphs_transformed (GdkDrawable *drawable,
+ GdkGC *gc,
+ PangoMatrix *matrix,
+ PangoFont *font,
+ gint x,
+ gint y,
+ PangoGlyphString *glyphs)
+{
+ GdkDrawable *real_drawable = ((GdkGLPixmap *) drawable)->drawable;
+
+ GDK_DRAWABLE_GET_CLASS (real_drawable)->draw_glyphs_transformed (real_drawable,
+ gc,
+ matrix,
+ font,
+ x,
+ y,
+ glyphs);
+}
+
+static void
+gdk_gl_pixmap_draw_trapezoids (GdkDrawable *drawable,
+ GdkGC *gc,
+ GdkTrapezoid *trapezoids,
+ gint n_trapezoids)
+{
+ GdkDrawable *real_drawable = ((GdkGLPixmap *) drawable)->drawable;
+
+ GDK_DRAWABLE_GET_CLASS (real_drawable)->draw_trapezoids (real_drawable,
+ gc,
+ trapezoids,
+ n_trapezoids);
+}
+#endif
+
+#if GTK_CHECK_VERSION(2,8,0)
+static cairo_surface_t *
+gdk_gl_pixmap_ref_cairo_surface (GdkDrawable *drawable)
+{
+ GdkDrawable *real_drawable = ((GdkGLPixmap *) drawable)->drawable;
+
+ return GDK_DRAWABLE_GET_CLASS (real_drawable)->ref_cairo_surface (real_drawable);
+}
+#endif
+
/*< private >*/
void
_gdk_gl_pixmap_get_size (GdkGLDrawable *gldrawable,
/* -*- coding: utf-8 -*- */
/*
* font-pango.c:
* Simple example for text rendering with Pango.
*
* written by Kouhei Sutou <kou cozmixng org>
*/
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#ifdef G_OS_WIN32
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#define FOVY_2 20.0
#define Z_NEAR 3.0
static const char *text = "This text is rendered with Παν�.";
static void
realize (GtkWidget *widget,
gpointer data)
{
PangoContext *pango_context;
PangoFontDescription *font_desc;
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
GLUquadricObj *qobj;
static GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0};
static GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return;
qobj = gluNewQuadric ();
gluQuadricDrawStyle (qobj, GLU_FILL);
glNewList (1, GL_COMPILE);
gluSphere (qobj, 1.0, 20, 20);
glEndList ();
glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv (GL_LIGHT0, GL_POSITION, light_position);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glClearColor (0.0, 0.0, 0.0, 0.0);
glClearDepth (1.0);
gdk_gl_drawable_gl_end (gldrawable);
/*** OpenGL END ***/
pango_context = gtk_widget_get_pango_context (widget);
font_desc = pango_context_get_font_description (pango_context);
pango_font_description_set_size (font_desc, 18 * PANGO_SCALE);
gtk_widget_modify_font (widget, font_desc);
}
static gboolean
configure_event (GtkWidget *widget,
GdkEventConfigure *event,
gpointer data)
{
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
GLsizei w = widget->allocation.width;
GLsizei h = widget->allocation.height;
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return FALSE;
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (2.0 * FOVY_2,
(GLfloat) w / (GLfloat) h,
Z_NEAR,
2.0 * Z_NEAR);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
gluLookAt (0.0, 0.0, Z_NEAR,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glTranslatef (0.0, 0.0, -Z_NEAR);
gdk_gl_drawable_gl_end (gldrawable);
/*** OpenGL END ***/
return TRUE;
}
static gboolean
expose_event (GtkWidget *widget,
GdkEventExpose *event,
gpointer data)
{
GdkGLContext *glcontext = gtk_widget_get_gl_context (widget);
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable (widget);
PangoLayout *layout;
PangoRectangle logical_rect;
GLfloat text_w, text_h;
GLfloat tangent_h;
/* Text layout */
layout = gtk_widget_create_pango_layout (widget, text);
pango_layout_set_width (layout, PANGO_SCALE * widget->allocation.width);
pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
/*** OpenGL BEGIN ***/
if (!gdk_gl_drawable_gl_begin (gldrawable, glcontext))
return FALSE;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glCallList (1);
/* Text color */
glColor3f (1.0, 0.9, 0.0);
/* Text position */
pango_layout_get_extents (layout, NULL, &logical_rect);
text_w = PANGO_PIXELS (logical_rect.width);
text_h = PANGO_PIXELS (logical_rect.height);
/*
* tangent = Z_NEAR * tan (FOVY_2 * G_PI / 180.0)
* w = widget->allocation.width
* h = widget->allocation.height
*
* x = -1.0 * (text_w/w) * tangent * (w/h) = -text_w * tangent / h
* y = -1.0 * (text_h/h) * tangent = -text_h * tangent / h
* z = Z_NEAR
*/
tangent_h = Z_NEAR * tan (FOVY_2 * G_PI / 180.0);
tangent_h /= widget->allocation.height;
glRasterPos3f (-text_w * tangent_h,
-text_h * tangent_h,
Z_NEAR);
/* Render text */
gdk_draw_layout (GDK_DRAWABLE (gldrawable), widget->style->white_gc,
0, (int)((widget->allocation.height - text_h) / 2.0),
layout);
if (gdk_gl_drawable_is_double_buffered (gldrawable))
gdk_gl_drawable_swap_buffers (gldrawable);
else
glFlush ();
gdk_gl_drawable_gl_end (gldrawable);
/*** OpenGL END ***/
g_object_unref (G_OBJECT (layout));
return TRUE;
}
static void
unrealize (GtkWidget *widget,
gpointer data)
{
}
int
main (int argc,
char *argv[])
{
GdkGLConfig *glconfig;
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *drawing_area;
GtkWidget *button;
/*
* Init GTK.
*/
gtk_init (&argc, &argv);
/*
* Init GtkGLExt.
*/
gtk_gl_init (&argc, &argv);
/*
* Configure OpenGL-capable visual.
*/
/* Try double-buffered visual */
glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH |
GDK_GL_MODE_DOUBLE);
if (glconfig == NULL)
{
g_print ("*** Cannot find the double-buffered visual.\n");
g_print ("*** Trying single-buffered visual.\n");
/* Try single-buffered visual */
glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGB |
GDK_GL_MODE_DEPTH);
if (glconfig == NULL)
{
g_print ("*** No appropriate OpenGL-capable visual found.\n");
exit (1);
}
}
/*
* Top-level window.
*/
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "font-pango");
/* Get automatically redrawn if any of their children changed allocation. */
gtk_container_set_reallocate_redraws (GTK_CONTAINER (window), TRUE);
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
/*
* VBox.
*/
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
/*
* Drawing area for drawing OpenGL scene.
*/
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 200, 200);
/* Set OpenGL-capability to the widget. */
gtk_widget_set_gl_capability (drawing_area,
glconfig,
NULL,
TRUE,
GDK_GL_RGBA_TYPE);
g_signal_connect_after (G_OBJECT (drawing_area), "realize",
G_CALLBACK (realize), NULL);
g_signal_connect (G_OBJECT (drawing_area), "configure_event",
G_CALLBACK (configure_event), NULL);
g_signal_connect (G_OBJECT (drawing_area), "expose_event",
G_CALLBACK (expose_event), NULL);
g_signal_connect (G_OBJECT (drawing_area), "unrealize",
G_CALLBACK (unrealize), NULL);
gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
gtk_widget_show (drawing_area);
/*
* Simple quit button.
*/
button = gtk_button_new_with_label ("Quit");
g_signal_connect (G_OBJECT (button), "clicked",
G_CALLBACK (gtk_main_quit), NULL);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
/*
* Show window.
*/
gtk_widget_show (window);
/*
* Main loop.
*/
gtk_main ();
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]