diff src/redisplay-x.c @ 3659:98af8a976fc3

[xemacs-hg @ 2006-11-05 22:31:31 by aidan] Support specifying fonts for particular character sets in Mule; support translation to ISO 10646-1 for Mule character sets without an otherwise matching font; move to a vector of X11-charset-X11-registry instead of a regex for the charset-registry property.
author aidan
date Sun, 05 Nov 2006 22:31:46 +0000
parents 2b84dd8eb906
children ec0171167c5d
line wrap: on
line diff
--- a/src/redisplay-x.c	Sat Nov 04 22:51:03 2006 +0000
+++ b/src/redisplay-x.c	Sun Nov 05 22:31:46 2006 +0000
@@ -41,9 +41,8 @@
 #include "sysdep.h"
 #include "window.h"
 
-#ifdef MULE
 #include "mule-ccl.h"
-#endif
+#include "charset.h"
 
 #include "console-x-impl.h"
 #include "glyphs-x.h"
@@ -154,138 +153,148 @@
 static int
 separate_textual_runs (unsigned char *text_storage,
 		       struct textual_run *run_storage,
-		       const Ichar *str, Charcount len)
+		       const Ichar *str, Charcount len,
+		       struct face_cachel *cachel)
 {
   Lisp_Object prev_charset = Qunbound; /* not Qnil because that is a
 					  possible valid charset when
 					  MULE is not defined */
-  int runs_so_far = 0;
-  int i;
-#ifdef MULE
+  int runs_so_far = 0, i;
+  Ibyte charset_leading_byte = LEADING_BYTE_ASCII;
+  int dimension = 1, graphic = 0, need_ccl_conversion = 0;
+  Lisp_Object ccl_prog;
   struct ccl_program char_converter;
-  int need_ccl_conversion = 0;
-#endif
+
+#ifdef	USE_XFT
+#define translate_to_ucs_2 1	/* Translate to UTF-16 unconditionally. */
+#define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) (void)(arg) /* Empty, 
+							      may avoid some 
+							      warnings. */
+#else	/* USE_XFT */
+#ifndef MULE
+#define translate_to_ucs_2 0	/* We don't support falling back to
+				   iso10646-1 without MULE */
+#define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) (void)(arg)
+#else	/* if MULE */
+  int translate_to_ucs_2 = 0;
+#define MAYBE_ASSIGN_TRANSLATE_TO_UCS_2(arg) translate_to_ucs_2 = (arg)
+#endif	/* MULE */
+#endif	/* !USE_XFT */
 
   for (i = 0; i < len; i++)
     {
       Ichar ch = str[i];
       Lisp_Object charset;
-      int byte1, byte2;		/* #### why aren't these UExtbytes? */
-      int dimension;
-      int graphic;
-
+      int byte1, byte2;		/* Not UExbytes because BREAKUP_ICHAR takes
+				   the addresses of its arguments and
+				   dereferences those addresses as integer
+				   pointers. */
       BREAKUP_ICHAR (ch, charset, byte1, byte2);
-      dimension = XCHARSET_DIMENSION (charset);
-      graphic   = XCHARSET_GRAPHIC   (charset);
 
       if (!EQ (charset, prev_charset))
 	{
 	  run_storage[runs_so_far].ptr       = text_storage;
 	  run_storage[runs_so_far].charset   = charset;
-#ifdef USE_XFT
-	  run_storage[runs_so_far].dimension = 2;
-#else
-	  run_storage[runs_so_far].dimension = dimension;
-#endif
 
 	  if (runs_so_far)
 	    {
 	      run_storage[runs_so_far - 1].len =
 		text_storage - run_storage[runs_so_far - 1].ptr;
-	      if (run_storage[runs_so_far - 1].dimension == 2)
-		run_storage[runs_so_far - 1].len >>= 1;
+	      /* Checks the value for dimension from the previous run. */
+	      if (2 == dimension) run_storage[runs_so_far - 1].len >>= 1;
 	    }
-	  runs_so_far++;
-	  prev_charset = charset;
+
+	  charset_leading_byte = XCHARSET_LEADING_BYTE(charset);
+
+	  MAYBE_ASSIGN_TRANSLATE_TO_UCS_2
+	    (bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE
+			    (cachel), 
+			    charset_leading_byte - MIN_LEADING_BYTE));
+
+	  if (translate_to_ucs_2)
+	    {
+	      dimension = 2;
+	      run_storage[runs_so_far].dimension = 2;
+	    }
+	  else
+	    {
+	      dimension = XCHARSET_DIMENSION (charset);
+	      run_storage[runs_so_far].dimension = dimension;
 #ifdef MULE
-	  {
-	    Lisp_Object ccl_prog = XCHARSET_CCL_PROGRAM (charset);
-	    if ((!NILP (ccl_prog))
+	      ccl_prog = XCHARSET_CCL_PROGRAM (charset);
+	      if ((!NILP (ccl_prog))
 		  && (setup_ccl_program (&char_converter, ccl_prog) >= 0))
-	      need_ccl_conversion = 1;
-	  }
-#endif
-	}
+		{
+		  need_ccl_conversion = 1;
+		}
+	      else 
+		{
+		  /* The graphic property is only relevant if we're neither
+		     doing the CCL conversion nor doing the UTF-16
+		     conversion; it's irrelevant otherwise. */
+		  graphic   = XCHARSET_GRAPHIC (charset);
+		  need_ccl_conversion = 0;
+		}
+#endif /* MULE */
+	    }
+	  prev_charset = charset;
 
-#ifndef USE_XFT
-      if (graphic == 0)
+	  runs_so_far++;
+	} 
+
+      if (translate_to_ucs_2)
 	{
-	  byte1 &= 0x7F;
-	  byte2 &= 0x7F;
-	}
-      else if (graphic == 1)
-	{
-	  byte1 |= 0x80;
-	  byte2 |= 0x80;
+	  UINT_16_BIT ucs2;
+	  int ucs = ichar_to_unicode(ch);
+
+	  /* If UCS is less than zero or greater than 0xFFFF, set ucs2 to
+	     REPLACMENT CHARACTER. */
+	  ucs2 = (ucs & ~0xFFFF) ? 0xFFFD : ucs;
+
+	  /* Ignoring the "graphic" handling. */
+#ifdef USE_XFT
+	  byte1 = ((unsigned char *) (&ucs2))[0];
+	  byte2 = ((unsigned char *) (&ucs2))[1];
+#else
+	  byte1 = ((unsigned char *) (&ucs2))[1];
+	  byte2 = ((unsigned char *) (&ucs2))[0];
+#endif /* USE_XFT */
 	}
 #ifdef MULE
-      if (need_ccl_conversion)
+      else if (need_ccl_conversion)
 	{
-	  char_converter.reg[0] = XCHARSET_ID (charset);
+	  char_converter.reg[0] = charset_leading_byte;
 	  char_converter.reg[1] = byte1;
 	  char_converter.reg[2] = byte2;
 	  ccl_driver (&char_converter, 0, 0, 0, 0, CCL_MODE_ENCODING);
 	  byte1 = char_converter.reg[1];
 	  byte2 = char_converter.reg[2];
 	}
+      else if (graphic == 0)
+	{
+	  byte1 &= 0x7F;
+	  byte2 &= 0x7F;
+	}
+      else
+	{
+	  byte1 |= 0x80;
+	  byte2 |= 0x80;
+	}
 #endif /* MULE */
-      *text_storage++ = (unsigned char) byte1;
-      /* This dimension stuff is broken if you want to use a two-dimensional
-	 X11 font to display a single-dimensional character set, as is
-	 appropriate for the IPA (use one of the -iso10646-1 fonts) or some
-	 of the other non-standard character sets. */
-      if (dimension == 2)
-	*text_storage++ = (unsigned char) byte2;
-#else /* USE_XFT */
-      /* #### This is bogus as hell.  XftChar16, aka FcChar16, is actually
-	 unsigned short, and therefore is not suitable for indexing matrix
-	 fonts such as the JIS fonts supplied with X11.  But if this were
-	 consistent, the XftDraw*8 and XftDraw*16 functions are pretty
-	 incoherent, as then we not should allow anything but ISO 8859/1
-	 (ie, the first 256 code points of Unicode) in XftDraw*8.  So it
-	 looks like this depends on the font, not the charset. */
-      {
-	XftChar16 xftchar16 = 0xFFFD; /* unsigned short */
-#ifndef MULE
-	int unicode = ch;
-#else
-	int unicode = ichar_to_unicode (ch);
-	if (unicode < 0)
-	  /* abort(); */	  /* #### serious error, tables are corrupt
-	     Unfortunately, not a valid assumption; this can happen with
-	     composite characters.  Fake it. */
-	  unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */
-	else if (need_ccl_conversion)
-	  /* #### maybe we should just ignore this and hope the font wins? */
-	  unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */
-	else if (unicode > 65535)
-	  unicode = 0xFFFD; /* REPLACEMENT CHARACTER, can't represent */
-	else
-#endif
-	  xftchar16 = (XftChar16) unicode;
-	/* #### endianness dependency?  No,
-	   apparently xft handles endianness for us;
-	   the "big-endian" code works on Intel and PPC */
-#if 1
-	/* big-endian or auto-endian */
-	byte1 = ((unsigned char *) (&xftchar16))[0];
-	byte2 = ((unsigned char *) (&xftchar16))[1];
-#else
-	/* little-endian */
-	byte1 = ((unsigned char *) (&xftchar16))[1];
-	byte2 = ((unsigned char *) (&xftchar16))[0];
-#endif
-      }
-      *text_storage++ = (unsigned char) byte1;
-      *text_storage++ = (unsigned char) byte2;      
-#endif /* USE_XFT */
+
+      *text_storage++ = (unsigned char)byte1;
+
+      /* dimension can be two in non-Mule if we're translating to
+	 Unicode.  */
+      if (2 == dimension) *text_storage++ = (unsigned char)byte2;
     }
 
   if (runs_so_far)
     {
       run_storage[runs_so_far - 1].len =
 	text_storage - run_storage[runs_so_far - 1].ptr;
-      if (run_storage[runs_so_far - 1].dimension == 2)
+      /* Dimension retains the relevant value for the run before it. */
+      if (2 == dimension)
 	run_storage[runs_so_far - 1].len >>= 1;
     }
 
@@ -361,7 +370,8 @@
   int nruns;
   int i;
 
-  nruns = separate_textual_runs (text_storage, runs, str, len);
+  nruns = separate_textual_runs (text_storage, runs, str, len, 
+				 cachel);
 
   for (i = 0; i < nruns; i++)
     width_so_far += x_text_width_single_run (f, cachel, runs + i);
@@ -1014,7 +1024,7 @@
     }
 
   nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0),
-				 Dynarr_length (buf));
+				 Dynarr_length (buf), cachel);
 
   for (i = 0; i < nruns; i++)
     {