changeset 90415:fed91f43ffad

Include "font.h". (x_set_mouse_face_gc, x_set_glyph_string_clipping) (x_set_glyph_string_clipping_exactly) (x_compute_glyph_string_overhangs) (x_draw_glyph_string_foreground) (x_draw_composite_glyph_string_foreground, x_draw_glyph_string) (x_free_frame_resources) [USE_FONT_BACKEND]: If enable_font_backend is nonzero, use font-backend mechanism. (x_new_fontset2) [USE_FONT_BACKEND]: New function.
author Kenichi Handa <handa@m17n.org>
date Tue, 06 Jun 2006 03:52:51 +0000
parents 41626792e297
children 810751854799
files src/xterm.c
diffstat 1 files changed, 250 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/xterm.c	Tue Jun 06 03:52:38 2006 +0000
+++ b/src/xterm.c	Tue Jun 06 03:52:51 2006 +0000
@@ -102,6 +102,10 @@
 #include "gtkutil.h"
 #endif
 
+#ifdef USE_FONT_BACKEND
+#include "font.h"
+#endif	/* USE_FONT_BACKEND */
+
 #ifdef USE_LUCID
 extern int xlwmenu_window_p P_ ((Widget w, Window window));
 extern void xlwmenu_redisplay P_ ((Widget));
@@ -1076,6 +1080,11 @@
   /* If font in this face is same as S->font, use it.  */
   if (s->font == s->face->font)
     s->gc = s->face->gc;
+#ifdef USE_FONT_BACKEND
+  else if (enable_font_backend)
+    /* No need of setting a font for s->gc.  */
+    s->gc = s->face->gc;
+#endif	/* USE_FONT_BACKEND */
   else
     {
       /* Otherwise construct scratch_cursor_gc with values from FACE
@@ -1173,6 +1182,10 @@
   XRectangle r;
   get_glyph_string_clip_rect (s, &r);
   XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted);
+#ifdef USE_FONT_BACKEND
+  s->clip_x = r.x, s->clip_y = r.y;
+  s->clip_width = r.width, s->clip_height = r.height;
+#endif	/* USE_FONT_BACKEND */
 }
 
 
@@ -1185,6 +1198,18 @@
      struct glyph_string *src, *dst;
 {
   XRectangle r;
+
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      r.x = dst->clip_x = src->x;
+      r.width = dst->clip_width = src->clip_width;
+      r.y = dst->clip_y = src->clip_y;
+      r.height = dst->clip_height = src->clip_height;
+    }
+  else
+    {
+#endif	/* USE_FONT_BACKEND */
   struct glyph_string *clip_head = src->clip_head;
   struct glyph_string *clip_tail = src->clip_tail;
 
@@ -1192,6 +1217,9 @@
   src->clip_head = src->clip_tail = src;
   get_glyph_string_clip_rect (src, &r);
   src->clip_head = clip_head, src->clip_tail = clip_tail;
+#ifdef USE_FONT_BACKEND
+    }
+#endif	/* USE_FONT_BACKEND */
   XSetClipRectangles (dst->display, dst->gc, 0, 0, &r, 1, Unsorted);
 }
 
@@ -1208,6 +1236,24 @@
     {
       XCharStruct cs;
       int direction, font_ascent, font_descent;
+
+#ifdef USE_FONT_BACKEND
+      if (enable_font_backend)
+	{
+	  unsigned *code = alloca (sizeof (unsigned) * s->nchars);
+	  struct font *font = (struct font *) s->font_info;
+	  struct font_metrics metrics;
+	  int i;
+
+	  for (i = 0; i < s->nchars; i++)
+	    code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
+	  font->driver->text_extents (font, code, s->nchars, &metrics);
+	  cs.rbearing = metrics.rbearing;
+	  cs.lbearing = metrics.lbearing;
+	  cs.width = metrics.width;
+	}
+      else
+#endif	/* USE_FONT_BACKEND */
       XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
 		      &font_ascent, &font_descent, &cs);
       s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
@@ -1307,6 +1353,30 @@
 	  x += g->pixel_width;
 	}
     }
+#ifdef USE_FONT_BACKEND
+  else if (enable_font_backend)
+    {
+      unsigned *code = alloca (sizeof (unsigned) * s->nchars);
+      int boff = s->font_info->baseline_offset;
+      struct font *font = (struct font *) s->font_info;
+      int y;
+
+      for (i = 0; i < s->nchars; i++)
+	code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
+
+      if (s->font_info->vertical_centering)
+	boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
+
+      y = s->ybase - boff;
+      if (s->for_overlaps
+	  || (s->background_filled_p && s->hl != DRAW_CURSOR))
+	font->driver->draw (s, 0, s->nchars, x, y, 0);
+      else
+	font->driver->draw (s, 0, s->nchars, x, y, 1);
+      if (s->face->overstrike)
+	font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
+    }
+#endif	/* USE_FONT_BACKEND */
   else
     {
       char *char1b = (char *) s->char2b;
@@ -1389,6 +1459,60 @@
 	XDrawRectangle (s->display, s->window, s->gc, x, s->y,
 			s->width - 1, s->height - 1);
     }
+#ifdef USE_FONT_BACKEND
+  else if (enable_font_backend)
+    {
+      struct font *font = (struct font *) s->font_info;
+      int y = s->ybase;
+      int width = 0;
+
+      if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
+	{
+	  Lisp_Object gstring = AREF (XHASH_TABLE (composition_hash_table)
+				      ->key_and_value,
+				      s->cmp->hash_index * 2);
+	  int from;
+
+	  for (i = from = 0; i < s->nchars; i++)
+	    {
+	      Lisp_Object g = LGSTRING_GLYPH (gstring, i);
+
+	      if (XINT (LGLYPH_XOFF (4)) == 0 && XINT (LGLYPH_YOFF (g)) == 0
+		  && XINT (LGLYPH_WADJUST (g)) == 0)
+		{
+		  width += XINT (LGLYPH_WIDTH (g));
+		  continue;
+		}
+	      if (from < i)
+		{
+		  font->driver->draw (s, from, i, x, y, 0);
+		  x += width;
+		}
+	      font->driver->draw (s, i, i + 1,
+				  x + XINT (LGLYPH_XOFF (g)),
+				  y + XINT (LGLYPH_XOFF (g)),
+				  0);
+	      x += XINT (LGLYPH_WIDTH (g)) + XINT (LGLYPH_WADJUST (g));
+	      from = i + 1;
+	      width = 0;
+	    }
+	  if (from < i)
+	    font->driver->draw (s, from, i, x, y, 0);
+	}
+      else
+	{
+	  for (i = 0; i < s->nchars; i++, ++s->gidx)
+	    {
+	      int xx = x + s->cmp->offsets[s->gidx * 2];
+	      int yy = y - s->cmp->offsets[s->gidx * 2 + 1];
+
+	      font->driver->draw (s, i, i + 1, xx, yy, 0);
+	      if (s->face->overstrike)
+		font->driver->draw (s, i, i + 1, xx + 1, yy, 0);
+	    }
+	}
+    }
+#endif	/* USE_FONT_BACKEND */
   else
     {
       for (i = 0; i < s->nchars; i++, ++s->gidx)
@@ -2643,6 +2767,9 @@
 	    x_set_glyph_string_gc (next);
 	    x_set_glyph_string_clipping (next);
 	    x_draw_glyph_string_background (next, 1);
+#ifdef USE_FONT_BACKEND
+	    next->clip_width = 0;
+#endif	/* USE_FONT_BACKEND */
 	  }
     }
 
@@ -2711,6 +2838,12 @@
 	  int y;
 
 	  /* Get the underline thickness.  Default is 1 pixel.  */
+#ifdef USE_FONT_BACKEND
+	  if (enable_font_backend)
+	    /* In the future, we must use information of font.  */
+	    h = 1;
+	  else
+#endif	/* USE_FONT_BACKEND */
 	  if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
 	    h = 1;
 
@@ -2722,6 +2855,12 @@
 	     ROUND ((maximum descent) / 2), with
 	     ROUND(x) = floor (x + 0.5)  */
 
+#ifdef USE_FONT_BACKEND
+	  if (enable_font_backend)
+	    /* In the future, we must use information of font.  */
+	    y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+	  else
+#endif
 	  if (x_use_underline_position_properties
 	      && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
 	    y = s->ybase + (long) tem;
@@ -2802,9 +2941,15 @@
 		prev->hl = s->hl;
 		x_set_glyph_string_gc (prev);
 		x_set_glyph_string_clipping_exactly (s, prev);
-		x_draw_glyph_string_foreground (prev);
+		if (prev->first_glyph->type == CHAR_GLYPH)
+		  x_draw_glyph_string_foreground (prev);
+		else
+		  x_draw_composite_glyph_string_foreground (prev);
 		XSetClipMask (prev->display, prev->gc, None);
 		prev->hl = save;
+#ifdef USE_FONT_BACKEND
+		prev->clip_width = 0;
+#endif	/* USE_FONT_BACKEND */
 	      }
 	}
 
@@ -2814,7 +2959,7 @@
 
 	  for (next = s->next; next; next = next->next)
 	    if (next->hl != s->hl
-		&& next->x - next->left_overhang && s->next->hl != s->hl)
+		&& next->x - next->left_overhang < s->x + s->width)
 	      {
 		/* As next will be drawn while clipped to its own area,
 		   we must draw the left_overhang part using s->hl now.  */
@@ -2823,15 +2968,24 @@
 		next->hl = s->hl;
 		x_set_glyph_string_gc (next);
 		x_set_glyph_string_clipping_exactly (s, next);
-		x_draw_glyph_string_foreground (next);
+		if (next->first_glyph->type == CHAR_GLYPH)
+		  x_draw_glyph_string_foreground (next);
+		else
+		  x_draw_composite_glyph_string_foreground (next);
 		XSetClipMask (next->display, next->gc, None);
 		next->hl = save;
+#ifdef USE_FONT_BACKEND
+		next->clip_width = 0;
+#endif	/* USE_FONT_BACKEND */
 	      }
 	}
     }
 
   /* Reset clipping.  */
   XSetClipMask (s->display, s->gc, None);
+#ifdef USE_FONT_BACKEND
+  s->clip_width = 0;
+#endif	/* USE_FONT_BACKEND */
 }
 
 /* Shift display to make room for inserted glyphs.   */
@@ -8007,6 +8161,90 @@
   return fontset_name (fontset);
 }
 
+#ifdef USE_FONT_BACKEND
+Lisp_Object
+x_new_fontset2 (f, fontsetname)
+     struct frame *f;
+     Lisp_Object fontsetname;
+{
+  int fontset;
+  struct font *font;
+  XFontStruct *xfont;
+
+  if (STRINGP (fontsetname))
+    {
+      fontset = fs_query_fontset (fontsetname, 0);
+      if (fontset > 0 && f->output_data.x->fontset == fontset)
+	/* This fontset is already set in frame F.  There's nothing more
+	   to do.  */
+	return fontset_name (fontset);
+      if (fontset == 0)
+	/* The default fontset can't be the default font.   */
+	return Qt;
+      if (fontset < 0)
+	fontset = new_fontset_from_font_name (fontsetname);
+    }
+  else
+    fontset = new_fontset_from_font (f, fontsetname);
+
+  if (fontset < 0)
+    return Qnil;
+
+  font = fontset_ascii_font (f, fontset);
+  xfont = font->font.font;
+
+  if (FRAME_FONT (f) == xfont)
+    /* This font is already set in frame F.  There's nothing more to
+       do.  */
+    return fontset_name (fontset);
+
+  BLOCK_INPUT;
+
+  FRAME_FONT (f) = xfont;
+  FRAME_BASELINE_OFFSET (f) = font->font.baseline_offset;
+  FRAME_FONTSET (f) = fontset;
+
+  FRAME_COLUMN_WIDTH (f) = font->font.average_width;
+  FRAME_SPACE_WIDTH (f) = font->font.space_width;
+  FRAME_LINE_HEIGHT (f) = font->font.height;
+
+  compute_fringe_widths (f, 1);
+
+  /* Compute the scroll bar width in character columns.  */
+  if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
+    {
+      int wid = FRAME_COLUMN_WIDTH (f);
+      FRAME_CONFIG_SCROLL_BAR_COLS (f)
+	= (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
+    }
+  else
+    {
+      int wid = FRAME_COLUMN_WIDTH (f);
+      FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
+    }
+
+  /* Now make the frame display the given font.  */
+  if (FRAME_X_WINDOW (f) != 0)
+    {
+      /* Don't change the size of a tip frame; there's no point in
+	 doing it because it's done in Fx_show_tip, and it leads to
+	 problems because the tip frame has no widget.  */
+      if (NILP (tip_frame) || XFRAME (tip_frame) != f)
+	x_set_window_size (f, 0, FRAME_COLS (f), FRAME_LINES (f));
+    }
+
+#ifdef HAVE_X_I18N
+  if (FRAME_XIC (f)
+      && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
+    xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
+#endif
+
+  UNBLOCK_INPUT;
+
+  return fontset_name (fontset);
+}
+#endif	/* USE_FONT_BACKEND */
+
 
 /***********************************************************************
 			   X Input Methods
@@ -9008,6 +9246,15 @@
      commands to the X server.  */
   if (dpyinfo->display)
     {
+#ifdef USE_FONT_BACKEND
+      /* We must free faces before destroying windows because some
+	 font-driver (e.g. xft) access a window while finishing a
+	 face.  */
+      if (enable_font_backend
+	  && FRAME_FACE_CACHE (f))
+	free_frame_faces (f);
+#endif	/* USE_FONT_BACKEND */
+
       if (f->output_data.x->icon_desc)
 	XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);