rnd-20030417-1-src
[rocksndiamonds.git] / src / libgame / text.c
index e440d2172031c9d33a4c424c719169bc367314d6..5558fc1c2b8efb471a4f994dfdc050fead8b6118 100644 (file)
@@ -27,41 +27,11 @@ static GC   font_clip_gc = None;
 
 static void InitFontClipmasks()
 {
-  static boolean clipmasks_initialized = FALSE;
   XGCValues clip_gc_values;
   unsigned long clip_gc_valuemask;
   GC copy_clipmask_gc;
   int i, j;
 
-  if (gfx.num_fonts == 0 || gfx.font_bitmap_info[0].bitmap == NULL)
-    return;
-
-  if (!clipmasks_initialized)
-  {
-    for (i=0; i < gfx.num_fonts; i++)
-    {
-      gfx.font_bitmap_info[i].clip_mask = NULL;
-      gfx.font_bitmap_info[i].last_num_chars = 0;
-    }
-
-    clipmasks_initialized = TRUE;
-  }
-
-  for (i=0; i < gfx.num_fonts; i++)
-  {
-    if (gfx.font_bitmap_info[i].clip_mask)
-      for (j=0; j < gfx.font_bitmap_info[i].last_num_chars; j++)
-       XFreePixmap(display, gfx.font_bitmap_info[i].clip_mask[j]);
-    free(gfx.font_bitmap_info[i].clip_mask);
-
-    gfx.font_bitmap_info[i].clip_mask = NULL;
-    gfx.font_bitmap_info[i].last_num_chars = 0;
-  }
-
-  if (font_clip_gc)
-    XFreeGC(display, font_clip_gc);
-  font_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
@@ -87,7 +57,6 @@ static void InitFontClipmasks()
 
     gfx.font_bitmap_info[i].clip_mask =
       checked_calloc(gfx.font_bitmap_info[i].num_chars * sizeof(Pixmap));
-    gfx.font_bitmap_info[i].last_num_chars = gfx.font_bitmap_info[i].num_chars;
 
     for (j=0; j < gfx.font_bitmap_info[i].num_chars; j++)
     {
@@ -110,6 +79,31 @@ static void InitFontClipmasks()
 
   XFreeGC(display, copy_clipmask_gc);
 }
+
+static void FreeFontClipmasks()
+{
+  int i, j;
+
+  if (gfx.num_fonts == 0 || gfx.font_bitmap_info[0].bitmap == NULL)
+    return;
+
+  for (i=0; i < gfx.num_fonts; i++)
+  {
+    if (gfx.font_bitmap_info[i].clip_mask)
+    {
+      for (j=0; j < gfx.font_bitmap_info[i].num_chars; j++)
+       XFreePixmap(display, gfx.font_bitmap_info[i].clip_mask[j]);
+      free(gfx.font_bitmap_info[i].clip_mask);
+    }
+
+    gfx.font_bitmap_info[i].clip_mask = NULL;
+    gfx.font_bitmap_info[i].num_chars = 0;
+  }
+
+  if (font_clip_gc)
+    XFreeGC(display, font_clip_gc);
+  font_clip_gc = None;
+}
 #endif /* TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND */
 
 void InitFontInfo(struct FontBitmapInfo *font_bitmap_info, int num_fonts,
@@ -118,16 +112,22 @@ void InitFontInfo(struct FontBitmapInfo *font_bitmap_info, int num_fonts,
   gfx.num_fonts = num_fonts;
   gfx.font_bitmap_info = font_bitmap_info;
   gfx.select_font_function = select_font_function;
-  gfx.inverse_text_color = WHITE_PIXEL;
 
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
   InitFontClipmasks();
 #endif
 }
 
-void SetInverseTextColor(Pixel inverse_text_color)
+void FreeFontInfo(struct FontBitmapInfo *font_bitmap_info)
 {
-  gfx.inverse_text_color = inverse_text_color;
+  if (font_bitmap_info == NULL)
+    return;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+  FreeFontClipmasks();
+#endif
+
+  free(font_bitmap_info);
 }
 
 int getFontWidth(int font_nr)
@@ -224,7 +224,7 @@ void DrawText(int x, int y, char *text, int font_nr)
   int mask_mode = BLIT_OPAQUE;
 
   if (DrawingOnBackground(x, y))
-    mask_mode = BLIT_MASKED;
+    mask_mode = BLIT_ON_BACKGROUND;
 
   DrawTextExt(drawto, x, y, text, font_nr, mask_mode);
 
@@ -241,10 +241,9 @@ void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text,
   struct FontBitmapInfo *font = &gfx.font_bitmap_info[font_bitmap_id];
   int font_width = getFontWidth(font_nr);
   int font_height = getFontHeight(font_nr);
-  boolean print_inverse = FALSE;
-  boolean print_inverse_cursor = FALSE;
   Bitmap *src_bitmap;
   int src_x, src_y;
+  char *text_ptr = text;
 
   if (font->bitmap == NULL)
     return;
@@ -253,34 +252,16 @@ void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text,
   dst_x += font->draw_x;
   dst_y += font->draw_y;
 
-  while (*text)
+  while (*text_ptr)
   {
-    char c = *text++;
-
-    if (c == '~')
-    {
-      print_inverse = TRUE;
-      if (strlen(text) == 1)
-       print_inverse_cursor = TRUE;
-
-      continue;
-    }
+    char c = *text_ptr++;
 
     getFontCharSource(font_nr, c, &src_bitmap, &src_x, &src_y);
 
-    if (print_inverse)         /* special mode for text gadgets */
+    if (mask_mode == BLIT_INVERSE)     /* special mode for text gadgets */
     {
-#if defined(TARGET_SDL)
-      /* blit normally (non-masked) */
-      BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y,
-                font_width, font_height, dst_x, dst_y);
-
-      /* invert character */
-      SDLInvertArea(dst_bitmap, dst_x, dst_y, font_width, font_height,
-                   gfx.inverse_text_color);
-#else
       /* first step: draw solid colored rectangle (use "cursor" character) */
-      if (print_inverse_cursor)
+      if (strlen(text) == 1)   /* only one char inverted => draw cursor */
       {
        Bitmap *cursor_bitmap;
        int cursor_x, cursor_y;
@@ -292,6 +273,11 @@ void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text,
                   font_width, font_height, dst_x, dst_y);
       }
 
+#if defined(TARGET_SDL)
+      /* second step: draw masked inverted character */
+      SDLCopyInverseMasked(src_bitmap, dst_bitmap, src_x, src_y,
+                          font_width, font_height, dst_x, dst_y);
+#else
       /* second step: draw masked black rectangle (use "space" character) */
       SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
                    dst_x - src_x, dst_y - src_y);
@@ -299,11 +285,14 @@ void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text,
                       font_width, font_height, dst_x, dst_y);
 #endif
     }
-    else if (mask_mode == BLIT_MASKED)
+    else if (mask_mode == BLIT_MASKED || mask_mode == BLIT_ON_BACKGROUND)
     {
-      /* clear font character background */
-      ClearRectangleOnBackground(dst_bitmap, dst_x, dst_y,
-                                font_width, font_height);
+      if (mask_mode == BLIT_ON_BACKGROUND)
+      {
+       /* clear font character background */
+       ClearRectangleOnBackground(dst_bitmap, dst_x, dst_y,
+                                  font_width, font_height);
+      }
 
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
       /* use special font tile clipmasks */