#include "puzzles.h"
+#if GTK_CHECK_VERSION(2,0,0)
+#define USE_PANGO
+#endif
+
/* ----------------------------------------------------------------------
* Error reporting functions used elsewhere.
*/
*/
struct font {
+#ifdef USE_PANGO
+ PangoFontDescription *desc;
+#else
GdkFont *font;
+#endif
int type;
int size;
};
fe->fonts[i].type = fonttype;
fe->fonts[i].size = fontsize;
-#if GTK_CHECK_VERSION(2,0,0)
+#ifdef USE_PANGO
/*
* Use Pango to find the closest match to the requested
* font.
pango_font_description_set_size(fd, resolution * fontsize);
}
#endif
- fe->fonts[i].font = gdk_font_from_description(fd);
- pango_font_description_free(fd);
+ fe->fonts[i].desc = fd;
}
- if (!fe->fonts[i].font)
+#else
+ /*
+ * In GTK 1.2, I don't know of any plausible way to
+ * pick a suitable font, so I'm just going to be
+ * tedious.
+ */
+ fe->fonts[i].font = gdk_font_load(fonttype == FONT_FIXED ?
+ "fixed" : "variable");
#endif
- /*
- * In GTK 1.2, I don't know of any plausible way to
- * pick a suitable font, so I'm just going to be
- * tedious.
- *
- * This is also fallback code called if the Pango
- * approach fails to find an appropriate font.
- */
- fe->fonts[i].font = gdk_font_load(fonttype == FONT_FIXED ?
- "fixed" : "variable");
+
+ }
+
+ /*
+ * Set the colour.
+ */
+ gdk_gc_set_foreground(fe->gc, &fe->colours[colour]);
+
+#ifdef USE_PANGO
+
+ {
+ PangoLayout *layout;
+ PangoRectangle rect;
+
+ /*
+ * Create a layout.
+ */
+ layout = pango_layout_new(gtk_widget_get_pango_context(fe->area));
+ pango_layout_set_font_description(layout, fe->fonts[i].desc);
+ pango_layout_set_text(layout, text, strlen(text));
+ pango_layout_get_pixel_extents(layout, NULL, &rect);
+
+ if (align & ALIGN_VCENTRE)
+ rect.y -= rect.height / 2;
+
+ if (align & ALIGN_HCENTRE)
+ rect.x -= rect.width / 2;
+ else if (align & ALIGN_HRIGHT)
+ rect.x -= rect.width;
+
+ gdk_draw_layout(fe->pixmap, fe->gc, rect.x + x, rect.y + y, layout);
+
+ g_object_unref(layout);
}
+#else
/*
* Find string dimensions and process alignment.
*/
}
/*
- * Set colour and actually draw text.
+ * Actually draw the text.
*/
- gdk_gc_set_foreground(fe->gc, &fe->colours[colour]);
gdk_draw_string(fe->pixmap, fe->fonts[i].font, fe->gc, x, y, text);
+#endif
+
}
void draw_rect(frontend *fe, int x, int y, int w, int h, int colour)
sfree(points);
}
+void draw_circle(frontend *fe, int cx, int cy, int radius,
+ int fill, int colour)
+{
+ gdk_gc_set_foreground(fe->gc, &fe->colours[colour]);
+ gdk_draw_arc(fe->pixmap, fe->gc, fill,
+ cx - radius, cy - radius,
+ 2 * radius, 2 * radius, 0, 360 * 64);
+}
+
+struct blitter {
+ GdkPixmap *pixmap;
+ int w, h, x, y;
+};
+
+blitter *blitter_new(int w, int h)
+{
+ /*
+ * We can't create the pixmap right now, because fe->window
+ * might not yet exist. So we just cache w and h and create it
+ * during the firs call to blitter_save.
+ */
+ blitter *bl = snew(blitter);
+ bl->pixmap = NULL;
+ bl->w = w;
+ bl->h = h;
+ return bl;
+}
+
+void blitter_free(blitter *bl)
+{
+ if (bl->pixmap)
+ gdk_pixmap_unref(bl->pixmap);
+ sfree(bl);
+}
+
+void blitter_save(frontend *fe, blitter *bl, int x, int y)
+{
+ if (!bl->pixmap)
+ bl->pixmap = gdk_pixmap_new(fe->area->window, bl->w, bl->h, -1);
+ bl->x = x;
+ bl->y = y;
+ gdk_draw_pixmap(bl->pixmap,
+ fe->area->style->fg_gc[GTK_WIDGET_STATE(fe->area)],
+ fe->pixmap,
+ x, y, 0, 0, bl->w, bl->h);
+}
+
+void blitter_load(frontend *fe, blitter *bl, int x, int y)
+{
+ assert(bl->pixmap);
+ if (x == BLITTER_FROMSAVED && y == BLITTER_FROMSAVED) {
+ x = bl->x;
+ y = bl->y;
+ }
+ gdk_draw_pixmap(fe->pixmap,
+ fe->area->style->fg_gc[GTK_WIDGET_STATE(fe->area)],
+ bl->pixmap,
+ 0, 0, x, y, bl->w, bl->h);
+}
+
void draw_update(frontend *fe, int x, int y, int w, int h)
{
if (fe->bbox_l > x ) fe->bbox_l = x ;
*py = y;
}
+#if !GTK_CHECK_VERSION(2,0,0)
+#define gtk_window_resize(win, x, y) \
+ gdk_window_resize(GTK_WIDGET(win)->window, x, y)
+#endif
+
static void menu_preset_event(GtkMenuItem *menuitem, gpointer data)
{
frontend *fe = (frontend *)data;