emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/w32uniscribe.c,v


From: Jason Rumney
Subject: [Emacs-diffs] Changes to emacs/src/w32uniscribe.c,v
Date: Fri, 25 Jul 2008 21:53:22 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Jason Rumney <jasonr>   08/07/25 21:53:21

Index: w32uniscribe.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32uniscribe.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- w32uniscribe.c      25 Jul 2008 11:25:43 -0000      1.19
+++ w32uniscribe.c      25 Jul 2008 21:53:21 -0000      1.20
@@ -134,6 +134,7 @@
 
   /* Initialize the cache for this font.  */
   uniscribe_font->cache = NULL;
+
   /* Mark the format as opentype  */
   uniscribe_font->w32_font.font.props[FONT_FORMAT_INDEX] = Qopentype;
   uniscribe_font->w32_font.font.driver = &uniscribe_font_driver;
@@ -150,7 +151,7 @@
     = (struct uniscribe_font_info *) font;
 
   if (uniscribe_font->cache)
-    ScriptFreeCache (&uniscribe_font->cache);
+    ScriptFreeCache (&(uniscribe_font->cache));
 
   w32font_close (f, font);
 }
@@ -206,12 +207,10 @@
   wchar_t *chars;
   WORD *glyphs, *clusters;
   SCRIPT_ITEM *items;
-  SCRIPT_CONTROL control;
   SCRIPT_VISATTR *attributes;
   int *advances;
   GOFFSET *offsets;
   ABC overall_metrics;
-  MAT2 transform;
   HDC context;
   HFONT old_font;
   HRESULT result;
@@ -239,9 +238,8 @@
      can be treated together.  First try a single run.  */
   max_items = 2;
   items = (SCRIPT_ITEM *) xmalloc (sizeof (SCRIPT_ITEM) * max_items + 1);
-  bzero (&control, sizeof (control));
 
-  while ((result = ScriptItemize (chars, nchars, max_items, &control, NULL,
+  while ((result = ScriptItemize (chars, nchars, max_items, NULL, NULL,
                                  items, &nitems)) == E_OUTOFMEMORY)
     {
       /* If that wasn't enough, keep trying with one more run.  */
@@ -250,8 +248,7 @@
                                        sizeof (SCRIPT_ITEM) * max_items + 1);
     }
 
-  /* 0 = success in Microsoft's backwards world.  */
-  if (result)
+  if (!SUCCEEDED (result))
     {
       xfree (items);
       return Qnil;
@@ -269,9 +266,6 @@
   attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR));
   advances = alloca (max_glyphs * sizeof (int));
   offsets = alloca (max_glyphs * sizeof (GOFFSET));
-  bzero (&transform, sizeof (transform));
-  transform.eM11.value = 1;
-  transform.eM22.value = 1;
 
   for (i = 0; i < nitems; i++)
     {
@@ -304,7 +298,7 @@
          result = ScriptPlace (context, &(uniscribe_font->cache),
                                glyphs, nglyphs, attributes, &(items[i].a),
                                advances, offsets, &overall_metrics);
-         if (result == 0) /* Success.  */
+         if (SUCCEEDED (result))
            {
              int j, nclusters, from, to;
 
@@ -364,7 +358,7 @@
                                                   &(uniscribe_font->cache),
                                                   glyphs[j], &char_metric);
 
-                 if (result == 0) /* Success.  */
+                 if (SUCCEEDED (result))
                    {
                      LGLYPH_SET_LBEARING (lglyph, char_metric.abcA);
                      LGLYPH_SET_RBEARING (lglyph, (char_metric.abcA
@@ -411,45 +405,68 @@
      struct font *font;
      int c;
 {
-  wchar_t chars[2];
-  int len;
-  WORD indices[1];
   HDC context;
   struct frame *f;
   HFONT old_font;
-  DWORD retval;
+  unsigned code = FONT_INVALID_CODE;
 
-  if (c > 0xFFFF)
+  /* 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));
+
+  /* There are a number of ways to get glyph indices for BMP characters.
+     The GetGlyphIndices GDI function seems to work best for detecting
+     non-existing glyphs.  */
+  if (c < 0x10000)
+    {
+      wchar_t ch = (wchar_t) c;
+      WORD index;
+      DWORD retval = GetGlyphIndicesW (context, &ch, 1, &index,
+                                       GGI_MARK_NONEXISTING_GLYPHS);
+      if (retval == 1 && index != 0xFFFF)
+        code = index;
+    }
+
+  /* Non BMP characters must be handled by the uniscribe shaping
+     engine as GDI functions (except blindly displaying lines of
+     unicode text) and the promising looking ScriptGetCMap do not
+     convert surrogate pairs to glyph indexes correctly.  */
+  else
     {
+      wchar_t ch[2];
+      SCRIPT_ITEM* items;
+      int nitems;
+      struct uniscribe_font_info *uniscribe_font
+        = (struct uniscribe_font_info *)font;
       DWORD surrogate = c - 0x10000;
 
       /* High surrogate: U+D800 - U+DBFF.  */
-      chars[0] = 0xD800 + ((surrogate >> 10) & 0x03FF);
+      ch[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;
-    }
+      ch[1] = 0xDC00 + (surrogate & 0x03FF);
 
-  /* 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));
+      items = (SCRIPT_ITEM *) alloca (sizeof (SCRIPT_ITEM) * 2 + 1);
+      if (SUCCEEDED (ScriptItemize (ch, 2, 2, NULL, NULL, items, &nitems)))
+        {
+          WORD glyphs[2], clusters[2];
+          SCRIPT_VISATTR attrs[2];
+          int nglyphs;
 
-  retval = GetGlyphIndicesW (context, chars, len, indices,
-                            GGI_MARK_NONEXISTING_GLYPHS);
+          if (SUCCEEDED (ScriptShape (context, &(uniscribe_font->cache),
+                                      ch, 2, 2, &(items[0].a),
+                                      glyphs, clusters, attrs, &nglyphs))
+              && nglyphs == 1)
+            {
+              code = glyphs[0];
+            }
+        }
+    }
 
   SelectObject (context, old_font);
   release_frame_dc (f, context);
 
-  if (retval == 1)
-    return indices[0] == 0xFFFF ? FONT_INVALID_CODE : indices[0];
-  else
-    return FONT_INVALID_CODE;
+  return code;
 }
 
 /*




reply via email to

[Prev in Thread] Current Thread [Next in Thread]