+
+/* ========================================================================= */
+/* font functions */
+/* ========================================================================= */
+
+#define NUM_FONTS 2
+#define NUM_FONT_COLORS 4
+#define NUM_FONT_CHARS (FONT_LINES_PER_FONT * FONT_CHARS_PER_LINE)
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+static GC tile_clip_gc = None;
+static Pixmap tile_clipmask[NUM_FONTS][NUM_FONT_COLORS][NUM_FONT_CHARS];
+
+static struct
+{
+ Bitmap **bitmap;
+ int xsize, ysize;
+} font_info[NUM_FONTS] =
+{
+ { &font.bitmap_big, FONT1_XSIZE, FONT1_YSIZE },
+ { &font.bitmap_medium, FONT6_XSIZE, FONT6_YSIZE }
+};
+
+static void InitFontClipmasks()
+{
+ static boolean clipmasks_initialized = FALSE;
+ boolean fonts_initialized = TRUE;
+ XGCValues clip_gc_values;
+ unsigned long clip_gc_valuemask;
+ GC copy_clipmask_gc;
+ int i, j, k;
+
+ for (i=0; i<NUM_FONTS; i++)
+ if (*font_info[i].bitmap == NULL)
+ fonts_initialized = FALSE;
+
+ if (!fonts_initialized)
+ return;
+
+ if (clipmasks_initialized)
+ for (i=0; i<NUM_FONTS; i++)
+ for (j=0; j<NUM_FONT_COLORS; j++)
+ for (k=0; k<NUM_FONT_CHARS; k++)
+ XFreePixmap(display, tile_clipmask[i][j][k]);
+
+ if (tile_clip_gc)
+ XFreeGC(display, tile_clip_gc);
+ tile_clip_gc = None;
+
+ /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is
+ often very slow when preparing a masked XCopyArea() for big Pixmaps.
+ To prevent this, create small (tile-sized) mask Pixmaps which will then
+ be set much faster with XSetClipOrigin() and speed things up a lot. */
+
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_valuemask = GCGraphicsExposures;
+ tile_clip_gc = XCreateGC(display, window->drawable,
+ clip_gc_valuemask, &clip_gc_values);
+
+ /* create graphic context structures needed for clipping */
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_valuemask = GCGraphicsExposures;
+ copy_clipmask_gc = XCreateGC(display, (*font_info[0].bitmap)->clip_mask,
+ clip_gc_valuemask, &clip_gc_values);
+
+ /* create only those clipping Pixmaps we really need */
+ for (i=0; i<NUM_FONTS; i++)
+ for (j=0; j<NUM_FONT_COLORS; j++)
+ for (k=0; k<NUM_FONT_CHARS; k++)
+ {
+ Bitmap *src_bitmap = *font_info[i].bitmap;
+ Pixmap src_pixmap = src_bitmap->clip_mask;
+ int xpos = k % FONT_CHARS_PER_LINE;
+ int ypos = k / FONT_CHARS_PER_LINE;
+ int xsize = font_info[i].xsize;
+ int ysize = font_info[i].ysize;
+ int src_x = xsize * xpos;
+ int src_y = ysize * (ypos + j * FONT_LINES_PER_FONT);
+
+ tile_clipmask[i][j][k] =
+ XCreatePixmap(display, window->drawable, xsize, ysize, 1);
+
+ XCopyArea(display, src_pixmap, tile_clipmask[i][j][k], copy_clipmask_gc,
+ src_x, src_y, xsize, ysize, 0, 0);
+ }
+
+ XFreeGC(display, copy_clipmask_gc);
+
+ clipmasks_initialized = TRUE;
+}
+#endif /* TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND */
+
+void InitFontInfo(Bitmap *bitmap_initial,
+ Bitmap *bitmap_big, Bitmap *bitmap_medium,
+ Bitmap *bitmap_small, Bitmap *bitmap_tile)
+{
+ font.bitmap_initial = bitmap_initial;
+ font.bitmap_big = bitmap_big;
+ font.bitmap_medium = bitmap_medium;
+ font.bitmap_small = bitmap_small;
+ font.bitmap_tile = bitmap_tile;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ InitFontClipmasks();
+#endif
+}