]> git.eshelyaron.com Git - emacs.git/commitdiff
* w32font.c (w32font_encode_char): Encode characters outside BMP as
authorJason Rumney <jasonr@gnu.org>
Fri, 25 Jul 2008 11:25:43 +0000 (11:25 +0000)
committerJason Rumney <jasonr@gnu.org>
Fri, 25 Jul 2008 11:25:43 +0000 (11:25 +0000)
surrogates before looking up glyph index.
(w32font_text_extents): Encode as surrogates if falling back to
functions that need UTF-16 wide chars.

* w32uniscribe.c (uniscribe_encode_char): Encode characters outside
BMP as surrogates before looking up glyph index.

src/ChangeLog
src/w32font.c
src/w32uniscribe.c

index d0daa9412acf6f11456d83e6be590d1326250de4..d8583efd9155b37a76a1a00666dba1bb9c4ecd29 100644 (file)
@@ -1,3 +1,13 @@
+2008-07-25  Jason Rumney  <jasonr@gnu.org>
+
+        * w32font.c (w32font_encode_char): Encode characters outside BMP as
+        surrogates before looking up glyph index.
+        (w32font_text_extents): Encode as surrogates if falling back to
+        functions that need UTF-16 wide chars.
+
+        * w32uniscribe.c (uniscribe_encode_char): Encode characters outside
+        BMP as surrogates before looking up glyph index.
+
 2008-07-25  Chong Yidong  <cyd@stupidchicken.com>
 
        * image.c (svg_load_image): Check for failure in return value of
index 4a4c7625787b3b99ddb0ffefe54b86add0dd4ee6..380bead2e74719292ff76fc59d43bef0436ae9bd 100644 (file)
@@ -327,8 +327,13 @@ w32font_encode_char (font, c)
 
   if (c > 0xFFFF)
     {
-      /* TODO: Encode as surrogate pair and lookup the glyph.  */
-      return FONT_INVALID_CODE;
+      DWORD surrogate = c - 0x10000;
+
+      /* High surrogate: U+D800 - U+DBFF.  */
+      in[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
+      /* Low surrogate: U+DC00 - U+DFFF.  */
+      in[1] = 0xDC00 + (surrogate & 0x03FF);
+      len = 2;
     }
   else
     {
@@ -394,7 +399,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
   HDC dc = NULL;
   struct frame * f;
   int total_width = 0;
-  WORD *wcode = NULL;
+  WORD *wcode;
   SIZE size;
 
   struct w32font_info *w32_font = (struct w32font_info *) font;
@@ -484,19 +489,27 @@ w32font_text_extents (font, code, nglyphs, metrics)
   /* For non-truetype fonts, GetGlyphOutlineW is not supported, so
      fallback on other methods that will at least give some of the metric
      information.  */
-  if (!wcode) {
-    wcode = alloca (nglyphs * sizeof (WORD));
-    for (i = 0; i < nglyphs; i++)
-      {
-       if (code[i] < 0x10000)
-         wcode[i] = code[i];
-       else
-         {
-           /* TODO: Convert to surrogate, reallocating array if needed */
-           wcode[i] = 0xffff;
-         }
-      }
-  }
+  
+  /* Make array big enough to hold surrogates.  */
+  wcode = alloca (nglyphs * sizeof (WORD) * 2);
+  for (i = 0; i < nglyphs; i++)
+    {
+      if (code[i] < 0x10000)
+        wcode[i] = code[i];
+      else
+        {
+          DWORD surrogate = code[i] - 0x10000;
+
+          /* High surrogate: U+D800 - U+DBFF.  */
+          wcode[i++] = 0xD800 + ((surrogate >> 10) & 0x03FF);
+          /* Low surrogate: U+DC00 - U+DFFF.  */
+          wcode[i] = 0xDC00 + (surrogate & 0x03FF);
+          /* An extra glyph. wcode is already double the size of code to
+             cope with this.  */
+          nglyphs++;
+        }
+    }
+
   if (dc == NULL)
     {
       /* TODO: Frames can come and go, and their fonts outlive
index 0e0a4e8d1436b2f61a52cb9947636bbac9d6ec9a..fc9f48b3a179be614f973d530bd47528881b5ae7 100644 (file)
@@ -411,25 +411,36 @@ uniscribe_encode_char (font, c)
      struct font *font;
      int c;
 {
-  wchar_t chars[1];
+  wchar_t chars[2];
+  int len;
   WORD indices[1];
   HDC context;
   struct frame *f;
   HFONT old_font;
   DWORD retval;
 
-  /* TODO: surrogates.  */
   if (c > 0xFFFF)
-    return FONT_INVALID_CODE;
+    {
+      DWORD surrogate = c - 0x10000;
 
-  chars[0] = (wchar_t) c;
+      /* High surrogate: U+D800 - U+DBFF.  */
+      chars[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
+      /* Low surrogate: U+DC00 - U+DFFF.  */
+      chars[1] = 0xDC00 + (surrogate & 0x03FF);
+      len = 2;
+    }
+  else
+    {
+      chars[0] = (wchar_t) c;
+      len = 1;
+    }
 
   /* Use selected frame until API is updated to pass the frame.  */
   f = XFRAME (selected_frame);
   context = get_frame_dc (f);
   old_font = SelectObject (context, FONT_HANDLE(font));
 
-  retval = GetGlyphIndicesW (context, chars, 1, indices,
+  retval = GetGlyphIndicesW (context, chars, len, indices,
                             GGI_MARK_NONEXISTING_GLYPHS);
 
   SelectObject (context, old_font);