]> code.delx.au - gnu-emacs/blobdiff - src/w32uniscribe.c
nnimap.el (nnimap-update-info): Refactor slightly.
[gnu-emacs] / src / w32uniscribe.c
index d7aeb7046c87be10824c43cd7cfdb0eed9456f3a..319f934e3bbba509d598552103fe161b5d3b9142 100644 (file)
@@ -1,5 +1,5 @@
 /* Font backend for the Microsoft W32 Uniscribe API.
 /* Font backend for the Microsoft W32 Uniscribe API.
-   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2008-2011 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -97,7 +97,7 @@ uniscribe_list_family (Lisp_Object frame)
   HDC dc;
   FRAME_PTR f = XFRAME (frame);
 
   HDC dc;
   FRAME_PTR f = XFRAME (frame);
 
-  bzero (&font_match_pattern, sizeof (font_match_pattern));
+  memset (&font_match_pattern, 0, sizeof (font_match_pattern));
   /* Limit enumerated fonts to outline fonts to save time.  */
   font_match_pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
 
   /* Limit enumerated fonts to outline fonts to save time.  */
   font_match_pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
 
@@ -165,7 +165,7 @@ uniscribe_otf_capability (struct font *font)
 
   f = XFRAME (selected_frame);
   context = get_frame_dc (f);
 
   f = XFRAME (selected_frame);
   context = get_frame_dc (f);
-  old_font = SelectObject (context, FONT_HANDLE(font));
+  old_font = SelectObject (context, FONT_HANDLE (font));
 
   features = otf_features (context, "GSUB");
   XSETCAR (capability, features);
 
   features = otf_features (context, "GSUB");
   XSETCAR (capability, features);
@@ -180,17 +180,18 @@ uniscribe_otf_capability (struct font *font)
 
 /* Uniscribe implementation of shape for font backend.
 
 
 /* Uniscribe implementation of shape for font backend.
 
-   Shape text in LGSTRING.  See the docstring of `font-make-gstring'
-   for the format of LGSTRING.  If the (N+1)th element of LGSTRING
-   is nil, input of shaping is from the 1st to (N)th elements.  In
-   each input glyph, FROM, TO, CHAR, and CODE are already set.
+   Shape text in LGSTRING.  See the docstring of
+   `composition-get-gstring' for the format of LGSTRING.  If the
+   (N+1)th element of LGSTRING is nil, input of shaping is from the
+   1st to (N)th elements.  In each input glyph, FROM, TO, CHAR, and
+   CODE are already set.
 
    This function updates all fields of the input glyphs.  If the
    output glyphs (M) are more than the input glyphs (N), (N+1)th
    through (M)th elements of LGSTRING are updated possibly by making
    a new glyph object and storing it in LGSTRING.  If (M) is greater
 
    This function updates all fields of the input glyphs.  If the
    output glyphs (M) are more than the input glyphs (N), (N+1)th
    through (M)th elements of LGSTRING are updated possibly by making
    a new glyph object and storing it in LGSTRING.  If (M) is greater
-   than the length of LGSTRING, nil should be return.  In that case,
-   this function is called again with the larger LGSTRING.  */
+   than the length of LGSTRING, nil should be returned.  In that case,
+   this function is called again with a larger LGSTRING.  */
 static Lisp_Object
 uniscribe_shape (Lisp_Object lgstring)
 {
 static Lisp_Object
 uniscribe_shape (Lisp_Object lgstring)
 {
@@ -217,6 +218,9 @@ uniscribe_shape (Lisp_Object lgstring)
   max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring);
   done_glyphs = 0;
   chars = (wchar_t *) alloca (nchars * sizeof (wchar_t));
   max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring);
   done_glyphs = 0;
   chars = (wchar_t *) alloca (nchars * sizeof (wchar_t));
+  /* FIXME: This loop assumes that characters in the input LGSTRING
+     are all inside the BMP.  Need to encode characters beyond the BMP
+     as UTF-16.  */
   for (i = 0; i < nchars; i++)
     {
       /* lgstring can be bigger than the number of characters in it, in
   for (i = 0; i < nchars; i++)
     {
       /* lgstring can be bigger than the number of characters in it, in
@@ -248,9 +252,6 @@ uniscribe_shape (Lisp_Object lgstring)
       return Qnil;
     }
 
       return Qnil;
     }
 
-  /* TODO: When we get BIDI support, we need to call ScriptLayout here.
-     Requires that we know the surrounding context.  */
-
   glyphs = alloca (max_glyphs * sizeof (WORD));
   clusters = alloca (nchars * sizeof (WORD));
   attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR));
   glyphs = alloca (max_glyphs * sizeof (WORD));
   clusters = alloca (nchars * sizeof (WORD));
   attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR));
@@ -259,8 +260,12 @@ uniscribe_shape (Lisp_Object lgstring)
 
   for (i = 0; i < nitems; i++)
     {
 
   for (i = 0; i < nitems; i++)
     {
-      int nglyphs, nchars_in_run, rtl = items[i].a.fRTL ? -1 : 1;
+      int nglyphs, nchars_in_run;
       nchars_in_run = items[i+1].iCharPos - items[i].iCharPos;
       nchars_in_run = items[i+1].iCharPos - items[i].iCharPos;
+      /* Force ScriptShape to generate glyphs in the same order as
+        they are in the input LGSTRING, which is in the logical
+        order.  */
+      items[i].a.fLogicalOrder = 1;
 
       /* Context may be NULL here, in which case the cache should be
          used without needing to select the font.  */
 
       /* Context may be NULL here, in which case the cache should be
          used without needing to select the font.  */
@@ -276,7 +281,7 @@ uniscribe_shape (Lisp_Object lgstring)
             passed in.  */
          f = XFRAME (selected_frame);
          context = get_frame_dc (f);
             passed in.  */
          f = XFRAME (selected_frame);
          context = get_frame_dc (f);
-         old_font = SelectObject (context, FONT_HANDLE(font));
+         old_font = SelectObject (context, FONT_HANDLE (font));
 
          result = ScriptShape (context, &(uniscribe_font->cache),
                                chars + items[i].iCharPos, nchars_in_run,
 
          result = ScriptShape (context, &(uniscribe_font->cache),
                                chars + items[i].iCharPos, nchars_in_run,
@@ -311,7 +316,7 @@ uniscribe_shape (Lisp_Object lgstring)
              /* Cache not complete...  */
              f = XFRAME (selected_frame);
              context = get_frame_dc (f);
              /* Cache not complete...  */
              f = XFRAME (selected_frame);
              context = get_frame_dc (f);
-             old_font = SelectObject (context, FONT_HANDLE(font));
+             old_font = SelectObject (context, FONT_HANDLE (font));
 
              result = ScriptPlace (context, &(uniscribe_font->cache),
                                    glyphs, nglyphs, attributes, &(items[i].a),
 
              result = ScriptPlace (context, &(uniscribe_font->cache),
                                    glyphs, nglyphs, attributes, &(items[i].a),
@@ -321,7 +326,7 @@ uniscribe_shape (Lisp_Object lgstring)
            {
              int j, nclusters, from, to;
 
            {
              int j, nclusters, from, to;
 
-             from = rtl > 0 ? 0 : nchars_in_run - 1;
+             from = 0;
              to = from;
 
              for (j = 0; j < nglyphs; j++)
              to = from;
 
              for (j = 0; j < nglyphs; j++)
@@ -342,22 +347,19 @@ uniscribe_shape (Lisp_Object lgstring)
                  gl = glyphs[j];
                  LGLYPH_SET_CODE (lglyph, gl);
 
                  gl = glyphs[j];
                  LGLYPH_SET_CODE (lglyph, gl);
 
-                 /* Detect clusters, for linking codes back to characters.  */
+                 /* Detect clusters, for linking codes back to
+                    characters.  */
                  if (attributes[j].fClusterStart)
                    {
                  if (attributes[j].fClusterStart)
                    {
-                     while (from >= 0 && from < nchars_in_run
-                            && clusters[from] < j)
-                       from += rtl;
-                     if (from < 0)
-                       from = to = 0;
-                     else if (from >= nchars_in_run)
+                     while (from < nchars_in_run && clusters[from] < j)
+                       from++;
+                     if (from >= nchars_in_run)
                        from = to = nchars_in_run - 1;
                      else
                        {
                          int k;
                        from = to = nchars_in_run - 1;
                      else
                        {
                          int k;
-                         to = rtl > 0 ? nchars_in_run - 1 : 0;
-                         for (k = from + rtl; k >= 0 && k < nchars_in_run;
-                              k += rtl)
+                         to = nchars_in_run - 1;
+                         for (k = from + 1; k < nchars_in_run; k++)
                            {
                              if (clusters[k] > j)
                                {
                            {
                              if (clusters[k] > j)
                                {
@@ -386,7 +388,7 @@ uniscribe_shape (Lisp_Object lgstring)
                      /* Cache incomplete... */
                      f = XFRAME (selected_frame);
                      context = get_frame_dc (f);
                      /* Cache incomplete... */
                      f = XFRAME (selected_frame);
                      context = get_frame_dc (f);
-                     old_font = SelectObject (context, FONT_HANDLE(font));
+                     old_font = SelectObject (context, FONT_HANDLE (font));
                      result = ScriptGetGlyphABCWidth (context,
                                                       &(uniscribe_font->cache),
                                                       glyphs[j], &char_metric);
                      result = ScriptGetGlyphABCWidth (context,
                                                       &(uniscribe_font->cache),
                                                       glyphs[j], &char_metric);
@@ -437,7 +439,7 @@ uniscribe_shape (Lisp_Object lgstring)
 }
 
 /* Uniscribe implementation of encode_char for font backend.
 }
 
 /* Uniscribe implementation of encode_char for font backend.
-   Return a glyph code of FONT for characer C (Unicode code point).
+   Return a glyph code of FONT for character C (Unicode code point).
    If FONT doesn't have such a glyph, return FONT_INVALID_CODE.  */
 static unsigned
 uniscribe_encode_char (struct font *font, int c)
    If FONT doesn't have such a glyph, return FONT_INVALID_CODE.  */
 static unsigned
 uniscribe_encode_char (struct font *font, int c)
@@ -486,6 +488,10 @@ uniscribe_encode_char (struct font *font, int c)
           SCRIPT_VISATTR attrs[2];
           int nglyphs;
 
           SCRIPT_VISATTR attrs[2];
           int nglyphs;
 
+         /* Force ScriptShape to generate glyphs in the logical
+            order.  */
+         items[0].a.fLogicalOrder = 1;
+
           result = ScriptShape (context, &(uniscribe_font->cache),
                                 ch, len, 2, &(items[0].a),
                                 glyphs, clusters, attrs, &nglyphs);
           result = ScriptShape (context, &(uniscribe_font->cache),
                                 ch, len, 2, &(items[0].a),
                                 glyphs, clusters, attrs, &nglyphs);
@@ -496,7 +502,7 @@ uniscribe_encode_char (struct font *font, int c)
                  the frame.  */
               f = XFRAME (selected_frame);
               context = get_frame_dc (f);
                  the frame.  */
               f = XFRAME (selected_frame);
               context = get_frame_dc (f);
-              old_font = SelectObject (context, FONT_HANDLE(font));
+              old_font = SelectObject (context, FONT_HANDLE (font));
               result = ScriptShape (context, &(uniscribe_font->cache),
                                     ch, len, 2, &(items[0].a),
                                     glyphs, clusters, attrs, &nglyphs);
               result = ScriptShape (context, &(uniscribe_font->cache),
                                     ch, len, 2, &(items[0].a),
                                     glyphs, clusters, attrs, &nglyphs);
@@ -959,5 +965,3 @@ syms_of_w32uniscribe (void)
   register_font_driver (&uniscribe_font_driver, NULL);
 }
 
   register_font_driver (&uniscribe_font_driver, NULL);
 }
 
-/* arch-tag: 9530f0e1-7471-47dd-a780-94330af87ea0
-   (do not change this comment) */