]> code.delx.au - gnu-emacs/blobdiff - src/w32font.c
Update copyright year to 2015
[gnu-emacs] / src / w32font.c
index 923c71b1147c77f9e67d029cd716f3c6ce1b49b9..1b0a8a2e7c44bb0e8dcbba94ef241460ace931b8 100644 (file)
@@ -1,5 +1,5 @@
 /* Font backend for the Microsoft Windows API.
-   Copyright (C) 2007-2013 Free Software Foundation, Inc.
+   Copyright (C) 2007-2015 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -33,6 +33,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "fontset.h"
 #include "font.h"
 #include "w32font.h"
+#ifdef WINDOWSNT
+#include "w32.h"
+#endif
 
 /* Cleartype available on Windows XP, cleartype_natural from XP SP1.
    The latter does not try to fit cleartype smoothed fonts into the
@@ -112,15 +115,15 @@ static void compute_metrics (HDC, struct w32font_info *, unsigned int,
 static Lisp_Object w32_registry (LONG, DWORD);
 
 /* EnumFontFamiliesEx callbacks.  */
-static int CALLBACK add_font_entity_to_list (ENUMLOGFONTEX *,
-                                             NEWTEXTMETRICEX *,
-                                             DWORD, LPARAM);
-static int CALLBACK add_one_font_entity_to_list (ENUMLOGFONTEX *,
-                                                 NEWTEXTMETRICEX *,
-                                                 DWORD, LPARAM);
-static int CALLBACK add_font_name_to_list (ENUMLOGFONTEX *,
-                                           NEWTEXTMETRICEX *,
-                                           DWORD, LPARAM);
+static int CALLBACK ALIGN_STACK add_font_entity_to_list (ENUMLOGFONTEX *,
+                                                        NEWTEXTMETRICEX *,
+                                                        DWORD, LPARAM);
+static int CALLBACK ALIGN_STACK add_one_font_entity_to_list (ENUMLOGFONTEX *,
+                                                            NEWTEXTMETRICEX *,
+                                                            DWORD, LPARAM);
+static int CALLBACK ALIGN_STACK add_font_name_to_list (ENUMLOGFONTEX *,
+                                                      NEWTEXTMETRICEX *,
+                                                      DWORD, LPARAM);
 
 /* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
    of what we really want.  */
@@ -144,7 +147,8 @@ struct font_callback_data
    style variations if the font name is not specified.  */
 static void list_all_matching_fonts (struct font_callback_data *);
 
-static BOOL g_b_init_is_w9x;
+#ifdef WINDOWSNT
+
 static BOOL g_b_init_get_outline_metrics_w;
 static BOOL g_b_init_get_text_metrics_w;
 static BOOL g_b_init_get_glyph_outline_w;
@@ -183,45 +187,7 @@ typedef BOOL (WINAPI * GetCharWidth32W_Proc) (
 static HMODULE
 w32_load_unicows_or_gdi32 (void)
 {
-  static BOOL is_9x = 0;
-  OSVERSIONINFO os_ver;
-  HMODULE ret;
-  if (g_b_init_is_w9x == 0)
-    {
-      g_b_init_is_w9x = 1;
-      ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
-      os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
-      if (GetVersionEx (&os_ver))
-       is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
-    }
-  if (is_9x)
-    {
-      ret = LoadLibrary ("Unicows.dll");
-      if (!ret)
-       {
-         int button;
-
-         button = MessageBox (NULL,
-                              "Emacs cannot load the UNICOWS.DLL library.\n"
-                              "This library is essential for using Emacs\n"
-                              "on this system.  You need to install it.\n\n"
-                              "However, you can still use Emacs by invoking\n"
-                              "it with the '-nw' command-line option.\n\n"
-                              "Emacs will exit when you click OK.",
-                              "Emacs cannot load UNICOWS.DLL",
-                              MB_ICONERROR | MB_TASKMODAL
-                              | MB_SETFOREGROUND | MB_OK);
-         switch (button)
-           {
-           case IDOK:
-           default:
-             exit (1);
-           }
-       }
-    }
-  else
-    ret = LoadLibrary ("Gdi32.dll");
-  return ret;
+  return maybe_load_unicows_dll ();
 }
 
 /* The following 3 functions call the problematic "wide" APIs via
@@ -280,8 +246,8 @@ get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
                                   lpvBuffer, lpmat2);
 }
 
-static DWORD WINAPI get_char_width_32_w (HDC hdc, UINT uFirstChar,
-                                        UINT uLastChar, LPINT lpBuffer)
+static DWORD WINAPI
+get_char_width_32_w (HDC hdc, UINT uFirstChar, UINT uLastChar, LPINT lpBuffer)
 {
   static GetCharWidth32W_Proc s_pfn_Get_Char_Width_32W = NULL;
   HMODULE hm_unicows = NULL;
@@ -297,6 +263,18 @@ static DWORD WINAPI get_char_width_32_w (HDC hdc, UINT uFirstChar,
   return s_pfn_Get_Char_Width_32W (hdc, uFirstChar, uLastChar, lpBuffer);
 }
 
+#else  /* Cygwin */
+
+/* Cygwin doesn't support Windows 9X, and links against GDI32.DLL, so
+   it can just call these functions directly.  */
+#define get_outline_metrics_w(h,d,o)   GetOutlineTextMetricsW(h,d,o)
+#define get_text_metrics_w(h,t)        GetTextMetricsW(h,t)
+#define get_glyph_outline_w(h,uc,f,gm,b,v,m) \
+                                       GetGlyphOutlineW(h,uc,f,gm,b,v,m)
+#define get_char_width_32_w(h,fc,lc,b) GetCharWidth32W(h,fc,lc,b)
+
+#endif /* Cygwin */
+
 static int
 memq_no_quit (Lisp_Object elt, Lisp_Object list)
 {
@@ -309,11 +287,11 @@ Lisp_Object
 intern_font_name (char * string)
 {
   Lisp_Object str = DECODE_SYSTEM (build_string (string));
-  int len = SCHARS (str);
+  ptrdiff_t len = SCHARS (str);
   Lisp_Object obarray = check_obarray (Vobarray);
   Lisp_Object tem = oblookup (obarray, SDATA (str), len, len);
   /* This code is similar to intern function from lread.c.  */
-  return SYMBOLP (tem) ? tem : Fintern (str, obarray);
+  return SYMBOLP (tem) ? tem : intern_driver (str, obarray, XINT (tem));
 }
 
 /* w32 implementation of get_cache for font backend.
@@ -495,7 +473,7 @@ w32font_encode_char (struct font *font, int c)
    of METRICS.  The glyphs are specified by their glyph codes in
    CODE (length NGLYPHS).  Apparently metrics can be NULL, in this
    case just return the overall width.  */
-int
+void
 w32font_text_extents (struct font *font, unsigned *code,
                      int nglyphs, struct font_metrics *metrics)
 {
@@ -509,84 +487,80 @@ w32font_text_extents (struct font *font, unsigned *code,
 
   struct w32font_info *w32_font = (struct w32font_info *) font;
 
-  if (metrics)
-    {
-      memset (metrics, 0, sizeof (struct font_metrics));
-      metrics->ascent = font->ascent;
-      metrics->descent = font->descent;
-
-      for (i = 0; i < nglyphs; i++)
-        {
-         struct w32_metric_cache *char_metric;
-         int block = *(code + i) / CACHE_BLOCKSIZE;
-         int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
+  memset (metrics, 0, sizeof (struct font_metrics));
+  metrics->ascent = font->ascent;
+  metrics->descent = font->descent;
 
-         if (block >= w32_font->n_cache_blocks)
-           {
-             if (!w32_font->cached_metrics)
-               w32_font->cached_metrics
-                 = xmalloc ((block + 1)
-                            * sizeof (struct w32_metric_cache *));
-             else
-               w32_font->cached_metrics
-                 = xrealloc (w32_font->cached_metrics,
-                             (block + 1)
-                             * sizeof (struct w32_metric_cache *));
-             memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
-                     ((block + 1 - w32_font->n_cache_blocks)
-                      * sizeof (struct w32_metric_cache *)));
-             w32_font->n_cache_blocks = block + 1;
-           }
+  for (i = 0; i < nglyphs; i++)
+    {
+      struct w32_metric_cache *char_metric;
+      int block = *(code + i) / CACHE_BLOCKSIZE;
+      int pos_in_block = *(code + i) % CACHE_BLOCKSIZE;
 
-         if (!w32_font->cached_metrics[block])
-           {
-             w32_font->cached_metrics[block]
-               = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
-           }
+      if (block >= w32_font->n_cache_blocks)
+       {
+         if (!w32_font->cached_metrics)
+           w32_font->cached_metrics
+             = xmalloc ((block + 1)
+                        * sizeof (struct w32_metric_cache *));
+         else
+           w32_font->cached_metrics
+             = xrealloc (w32_font->cached_metrics,
+                         (block + 1)
+                         * sizeof (struct w32_metric_cache *));
+         memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
+                 ((block + 1 - w32_font->n_cache_blocks)
+                  * sizeof (struct w32_metric_cache *)));
+         w32_font->n_cache_blocks = block + 1;
+       }
 
-         char_metric = w32_font->cached_metrics[block] + pos_in_block;
+      if (!w32_font->cached_metrics[block])
+       {
+         w32_font->cached_metrics[block]
+           = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
+       }
 
-         if (char_metric->status == W32METRIC_NO_ATTEMPT)
-           {
-             if (dc == NULL)
-               {
-                 /* TODO: Frames can come and go, and their fonts
-                    outlive them. So we can't cache the frame in the
-                    font structure.  Use selected_frame until the API
-                    is updated to pass in a frame.  */
-                 f = XFRAME (selected_frame);
-
-                  dc = get_frame_dc (f);
-                  old_font = SelectObject (dc, w32_font->hfont);
-               }
-             compute_metrics (dc, w32_font, *(code + i), char_metric);
-           }
+      char_metric = w32_font->cached_metrics[block] + pos_in_block;
 
-         if (char_metric->status == W32METRIC_SUCCESS)
+      if (char_metric->status == W32METRIC_NO_ATTEMPT)
+       {
+         if (dc == NULL)
            {
-             metrics->lbearing = min (metrics->lbearing,
-                                      metrics->width + char_metric->lbearing);
-             metrics->rbearing = max (metrics->rbearing,
-                                      metrics->width + char_metric->rbearing);
-             metrics->width += char_metric->width;
+             /* TODO: Frames can come and go, and their fonts
+                outlive them. So we can't cache the frame in the
+                font structure.  Use selected_frame until the API
+                is updated to pass in a frame.  */
+             f = XFRAME (selected_frame);
+
+             dc = get_frame_dc (f);
+             old_font = SelectObject (dc, w32_font->hfont);
            }
-         else
-           /* If we couldn't get metrics for a char,
-              use alternative method.  */
-           break;
+         compute_metrics (dc, w32_font, *(code + i), char_metric);
        }
-      /* If we got through everything, return.  */
-      if (i == nglyphs)
-        {
-          if (dc != NULL)
-            {
-              /* Restore state and release DC.  */
-              SelectObject (dc, old_font);
-              release_frame_dc (f, dc);
-            }
 
-          return metrics->width;
-        }
+      if (char_metric->status == W32METRIC_SUCCESS)
+       {
+         metrics->lbearing = min (metrics->lbearing,
+                                  metrics->width + char_metric->lbearing);
+         metrics->rbearing = max (metrics->rbearing,
+                                  metrics->width + char_metric->rbearing);
+         metrics->width += char_metric->width;
+       }
+      else
+       /* If we couldn't get metrics for a char,
+          use alternative method.  */
+       break;
+    }
+  /* If we got through everything, return.  */
+  if (i == nglyphs)
+    {
+      if (dc != NULL)
+       {
+         /* Restore state and release DC.  */
+         SelectObject (dc, old_font);
+         release_frame_dc (f, dc);
+       }
+      return;
     }
 
   /* For non-truetype fonts, GetGlyphOutlineW is not supported, so
@@ -642,18 +616,13 @@ w32font_text_extents (struct font *font, unsigned *code,
     }
 
   /* Give our best estimate of the metrics, based on what we know.  */
-  if (metrics)
-    {
-      metrics->width = total_width - w32_font->metrics.tmOverhang;
-      metrics->lbearing = 0;
-      metrics->rbearing = total_width;
-    }
+  metrics->width = total_width - w32_font->metrics.tmOverhang;
+  metrics->lbearing = 0;
+  metrics->rbearing = total_width;
 
   /* Restore state and release DC.  */
   SelectObject (dc, old_font);
   release_frame_dc (f, dc);
-
-  return total_width;
 }
 
 /* w32 implementation of draw for font backend.
@@ -779,19 +748,6 @@ w32font_get_bitmap (struct font *font, unsigned code,
 static void
 w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap);
   */
-/* w32 implementation of get_outline for font backend.
-   Optional.
-   Return an outline data for glyph-code CODE of FONT.  The format
-   of the outline data depends on the font-driver.
-static void *
-w32font_get_outline (struct font *font, unsigned code);
-  */
-/* w32 implementation of free_outline for font backend.
-   Optional.
-   Free OUTLINE (that is obtained by the above method).
-static void
-w32font_free_outline (struct font *font, void *outline);
-  */
 /* w32 implementation of anchor_point for font backend.
    Optional.
    Get coordinates of the INDEXth anchor point of the glyph whose
@@ -921,7 +877,7 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity,
   LOGFONT logfont;
   HDC dc;
   HFONT hfont, old_font;
-  Lisp_Object val, extra;
+  Lisp_Object val;
   struct w32font_info *w32_font;
   struct font * font;
   OUTLINETEXTMETRICW* metrics = NULL;
@@ -1012,24 +968,8 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity,
   font->baseline_offset = 0;
   font->relative_compose = 0;
   font->default_ascent = w32_font->metrics.tmAscent;
-  font->font_encoder = NULL;
   font->pixel_size = size;
   font->driver = &w32font_driver;
-  /* Use format cached during list, as the information we have access to
-     here is incomplete.  */
-  extra = AREF (font_entity, FONT_EXTRA_INDEX);
-  if (CONSP (extra))
-    {
-      val = assq_no_quit (QCformat, extra);
-      if (CONSP (val))
-        font->props[FONT_FORMAT_INDEX] = XCDR (val);
-      else
-        font->props[FONT_FORMAT_INDEX] = Qunknown;
-    }
-  else
-    font->props[FONT_FORMAT_INDEX] = Qunknown;
-
-  font->props[FONT_FILE_INDEX] = Qnil;
   font->encoding_charset = -1;
   font->repertory_charset = -1;
   /* TODO: do we really want the minimum width here, which could be negative? */
@@ -1060,7 +1000,7 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity,
 
 /* Callback function for EnumFontFamiliesEx.
  * Adds the name of a font to a Lisp list (passed in as the lParam arg).  */
-static int CALLBACK
+static int CALLBACK ALIGN_STACK
 add_font_name_to_list (ENUMLOGFONTEX *logical_font,
                       NEWTEXTMETRICEX *physical_font,
                       DWORD font_type, LPARAM list_object)
@@ -1506,7 +1446,7 @@ check_face_name (LOGFONT *font, char *full_name)
  * and if so, adds it to a list. Both the data we are checking against
  * and the list to which the fonts are added are passed in via the
  * lparam argument, in the form of a font_callback_data struct. */
-static int CALLBACK
+static int CALLBACK ALIGN_STACK
 add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
                         NEWTEXTMETRICEX *physical_font,
                         DWORD font_type, LPARAM lParam)
@@ -1625,7 +1565,7 @@ add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
 
 /* Callback function for EnumFontFamiliesEx.
  * Terminates the search once we have a match. */
-static int CALLBACK
+static int CALLBACK ALIGN_STACK
 add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font,
                             NEWTEXTMETRICEX *physical_font,
                             DWORD font_type, LPARAM lParam)
@@ -2563,7 +2503,7 @@ w32font_filter_properties (Lisp_Object font, Lisp_Object alist)
 
 struct font_driver w32font_driver =
   {
-    0, /* Qgdi */
+    LISP_INITIALLY_ZERO, /* Qgdi */
     0, /* case insensitive */
     w32font_get_cache,
     w32font_list,
@@ -2580,8 +2520,6 @@ struct font_driver w32font_driver =
     w32font_draw,
     NULL, /* get_bitmap */
     NULL, /* free_bitmap */
-    NULL, /* get_outline */
-    NULL, /* free_outline */
     NULL, /* anchor_point */
     NULL, /* otf_capability */
     NULL, /* otf_drive */
@@ -2754,9 +2692,10 @@ versions of Windows) characters.  */);
 void
 globals_of_w32font (void)
 {
-  g_b_init_is_w9x = 0;
+#ifdef WINDOWSNT
   g_b_init_get_outline_metrics_w = 0;
   g_b_init_get_text_metrics_w = 0;
   g_b_init_get_glyph_outline_w = 0;
   g_b_init_get_char_width_32_w = 0;
+#endif
 }