*** empty log message ***
[bpt/emacs.git] / src / w32font.c
index 9f3f4ae..5c3f6b7 100644 (file)
@@ -39,7 +39,7 @@ struct w32font_info
 
 extern struct font_driver w32font_driver;
 
-Lisp_Object Qw32, QCfamily;
+Lisp_Object Qgdi, QCfamily;
 static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
 static Lisp_Object Qscript, Qdecorative, Qraster, Qoutline, Qunknown;
 
@@ -295,7 +295,7 @@ w32font_open (f, font_entity, pixel_size)
   font->entity = font_entity;
   font->pixel_size = size;
   font->driver = &w32font_driver;
-  font->format = Qw32;
+  font->format = Qgdi;
   font->file_name = NULL;
   font->encoding_charset = -1;
   font->repertory_charset = -1;
@@ -371,7 +371,7 @@ w32font_encode_char (font, c)
 /* w32 implementation of text_extents for font backend.
    Perform the size computation of glyphs of FONT and fillin members
    of METRICS.  The glyphs are specified by their glyph codes in
-   CODE (length NGLYPHS).  Apparently medtrics can be NULL, in this
+   CODE (length NGLYPHS).  Apparently metrics can be NULL, in this
    case just return the overall width.  */
 static int
 w32font_text_extents (font, code, nglyphs, metrics)
@@ -386,8 +386,6 @@ w32font_text_extents (font, code, nglyphs, metrics)
      device context to measure against... */
   HDC dc = GetDC (NULL);
   int total_width = 0;
-
-  /* TODO: Allow some extra room for surrogates. */
   WORD *wcode = alloca(nglyphs * sizeof (WORD));
   SIZE size;
 
@@ -397,66 +395,57 @@ w32font_text_extents (font, code, nglyphs, metrics)
     {
       GLYPHMETRICS gm;
       MAT2 transform;
-      int i, width;
-      UINT format = GGO_METRICS;
 
       /* Set transform to the identity matrix.  */
       bzero (&transform, sizeof (transform));
       transform.eM11.value = 1;
       transform.eM22.value = 1;
+      metrics->width = 0;
+      metrics->ascent = 0;
+      metrics->descent = 0;
 
       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;
-           }
-
-          if (GetGlyphOutlineW (dc, *(code + i), format, &gm, 0,
+          if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
                                 NULL, &transform) != GDI_ERROR)
             {
-              metrics[i].lbearing = gm.gmptGlyphOrigin.x;
-              metrics[i].rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
-              metrics[i].width = gm.gmCellIncX;
-              metrics[i].ascent = -gm.gmptGlyphOrigin.y;
-              metrics[i].descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
-            }
-          else if (GetTextExtentPoint32W (dc, wcode + i, 1, &size)
-                   != GDI_ERROR)
-            {
-              metrics[i].lbearing = 0;
-              metrics[i].rbearing = size.cx
-                + ((struct w32font_info *) font)->metrics.tmOverhang;
-              metrics[i].width = size.cx;
-              metrics[i].ascent = font->ascent;
-              metrics[i].descent = font->descent;
+              int new_val = metrics->width + gm.gmBlackBoxX
+                + gm.gmptGlyphOrigin.x;
+
+              metrics->rbearing = max (metrics->rbearing, new_val);
+              metrics->width += gm.gmCellIncX;
+              new_val = -gm.gmptGlyphOrigin.y;
+              metrics->ascent = max (metrics->ascent, new_val);
+              new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
+              metrics->descent = max (metrics->descent, new_val);
             }
           else
             {
-              metrics[i].lbearing = 0;
-              metrics[i].rbearing = font->font.size
-                + ((struct w32font_info *) font)->metrics.tmOverhang;
-              metrics[i].width = font->font.size;
-              metrics[i].ascent = font->ascent;
-              metrics[i].descent = font->descent;
+              /* Rely on an estimate based on the overall font metrics.  */
+              break;
             }
         }
+
+      /* If we got through everything, return.  */
+      if (i == nglyphs)
+        {
+          /* Restore state and release DC.  */
+          SelectObject (dc, old_font);
+          ReleaseDC (NULL, dc);
+
+          return metrics->width;
+        }
     }
-  else
+
+  for (i = 0; i < nglyphs; i++)
     {
-      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;
-           }
-       }
+      if (code[i] < 0x10000)
+        wcode[i] = code[i];
+      else
+        {
+          /* TODO: Convert to surrogate, reallocating array if needed */
+          wcode[i] = 0xffff;
+        }
     }
 
   if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
@@ -473,6 +462,16 @@ w32font_text_extents (font, code, nglyphs, metrics)
       total_width = rect.right;
     }
 
+  if (metrics)
+    {
+      metrics->width = total_width;
+      metrics->ascent = font->ascent;
+      metrics->descent = font->descent;
+      metrics->lbearing = 0;
+      metrics->rbearing = total_width
+        + ((struct w32font_info *) font)->metrics.tmOverhang;
+    }
+
   /* Restore state and release DC.  */
   SelectObject (dc, old_font);
   ReleaseDC (NULL, dc);
@@ -492,9 +491,32 @@ w32font_draw (s, from, to, x, y, with_background)
      int from, to, x, y, with_background;
 {
   UINT options = 0;
+  HRGN orig_clip;
+
+  /* Save clip region for later restoration.  */
+  GetClipRgn(s->hdc, orig_clip);
+
+  if (s->num_clips > 0)
+    {
+      HRGN new_clip = CreateRectRgnIndirect (s->clip);
+
+      if (s->num_clips > 1)
+        {
+          HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
+
+          CombineRgn (new_clip, new_clip, clip2, RGN_OR);
+          DeleteObject (clip2);
+        }
+
+      SelectClipRgn (s->hdc, new_clip);
+      DeleteObject (new_clip);
+    }
 
   if (with_background)
     {
+      SetBkColor (s->hdc, s->gc->background);
+      SetBkMode (s->hdc, OPAQUE);
+#if 0
       HBRUSH brush;
       RECT rect;
 
@@ -505,11 +527,18 @@ w32font_draw (s, from, to, x, y, with_background)
       rect.bottom = y + ((struct font *) (s->font_info->font))->descent;
       FillRect (s->hdc, &rect, brush);
       DeleteObject (brush);
+#endif
     }
   else
     SetBkMode (s->hdc, TRANSPARENT);
 
   ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
+
+  /* Restore clip region.  */
+  if (s->num_clips > 0)
+    {
+      SelectClipRgn (s->hdc, orig_clip);
+    }
 }
 
 /* w32 implementation of free_entity for font backend.
@@ -610,8 +639,14 @@ add_font_name_to_list (logical_font, physical_font, font_type, list_object)
      LPARAM list_object;
 {
   Lisp_Object* list = (Lisp_Object *) list_object;
-  Lisp_Object family = intern_downcase (logical_font->elfLogFont.lfFaceName,
-                                        strlen (logical_font->elfLogFont.lfFaceName));
+  Lisp_Object family;
+
+  /* Skip vertical fonts (intended only for printing)  */
+  if (logical_font->elfLogFont.lfFaceName[0] == '@')
+    return 1;
+
+  family = intern_downcase (logical_font->elfLogFont.lfFaceName,
+                            strlen (logical_font->elfLogFont.lfFaceName));
   if (! memq_no_quit (family, *list))
     *list = Fcons (family, *list);
 
@@ -632,7 +667,7 @@ w32_enumfont_pattern_entity (frame, logical_font, physical_font, font_type)
 
   entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
 
-  ASET (entity, FONT_TYPE_INDEX, Qw32);
+  ASET (entity, FONT_TYPE_INDEX, Qgdi);
   ASET (entity, FONT_FRAME_INDEX, frame);
   ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet));
   ASET (entity, FONT_OBJLIST_INDEX, Qnil);
@@ -756,10 +791,7 @@ font_matches_spec (type, font, spec)
       int slant = XINT (val);
       if ((slant > 150 && !font->ntmTm.tmItalic)
           || (slant <= 150 && font->ntmTm.tmItalic))
-        {
-          OutputDebugString ("italic mismatch");
         return 0;
-        }
     }
 
   /* Check extra parameters.  */
@@ -915,7 +947,11 @@ add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
 
   if (logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
       && font_matches_spec (font_type, physical_font,
-                            match_data->orig_font_spec))
+                            match_data->orig_font_spec)
+      /* Avoid Windows substitution so we can control substitution with
+         alternate-fontname-alist.  */
+      && !strnicmp (&logical_font->elfFullName,
+                    &match_data->pattern.lfFaceName, LF_FACESIZE))
     {
       Lisp_Object entity
         = w32_enumfont_pattern_entity (match_data->frame, logical_font,
@@ -1248,7 +1284,7 @@ font_supported_scripts (FONTSIGNATURE * sig)
 
 struct font_driver w32font_driver =
   {
-    0, /* Qw32 */
+    0, /* Qgdi */
     w32font_get_cache,
     w32font_list,
     w32font_match,
@@ -1277,7 +1313,7 @@ struct font_driver w32font_driver =
 void
 syms_of_w32font ()
 {
-  DEFSYM (Qw32, "w32");
+  DEFSYM (Qgdi, "gdi");
 
   /* Generic font families.  */
   DEFSYM (Qmonospace, "monospace");
@@ -1345,7 +1381,7 @@ syms_of_w32font ()
   DEFSYM (Qmusical_symbol, "musical-symbol");
   DEFSYM (Qmathematical, "mathematical");
 
-  w32font_driver.type = Qw32;
+  w32font_driver.type = Qgdi;
   register_font_driver (&w32font_driver, NULL);
 }