]> git.eshelyaron.com Git - emacs.git/commitdiff
* w32font.c (w32font_text_extents): Fill in lbearing metric.
authorJason Rumney <jasonr@gnu.org>
Wed, 6 Feb 2008 22:35:30 +0000 (22:35 +0000)
committerJason Rumney <jasonr@gnu.org>
Wed, 6 Feb 2008 22:35:30 +0000 (22:35 +0000)
Use cached metrics for ASCII characters.
(w32font_open_internal): Don't set font's owning_frame.  Cache
metrics for ASCII characters.

* w32font.h (struct w32font_info): Add ascii_metrics.
Remove owning_frame.

src/ChangeLog
src/w32font.c
src/w32font.h

index dcdd9a855c6256f0ab08cb5e10e26f03cd6ccaee..637c15e0628c575d975e8a53bb8fe3176791c3cb 100644 (file)
@@ -1,3 +1,13 @@
+2008-02-06  Jason Rumney  <jasonr@gnu.org>
+
+       * w32font.c (w32font_text_extents): Fill in lbearing metric.
+       Use cached metrics for ASCII characters.
+       (w32font_open_internal): Don't set font's owning_frame.  Cache
+       metrics for ASCII characters.
+
+       * w32font.h (struct w32font_info): Add ascii_metrics.
+       Remove owning_frame.
+
 2008-02-06  Kenichi Handa  <handa@ni.aist.go.jp>
 
        * xdisp.c (x_produce_glyphs): Don't set it->ascent and it->descent
index ddb2f43eb57628333a78d5e64ea88c3ab313c82c..5776c95d0a7fcf5ce29dea55383ccf7c041a41ae 100644 (file)
@@ -297,13 +297,10 @@ w32font_text_extents (font, code, nglyphs, metrics)
   WORD *wcode = alloca(nglyphs * sizeof (WORD));
   SIZE size;
 
-#if 0
-  /* Frames can come and go, and their fonts outlive them. This is
-     particularly troublesome with tooltip frames, and causes crashes.  */
-  f = ((struct w32font_info *)font)->owning_frame;
-#else
+  /* 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);
-#endif
 
   dc = get_frame_dc (f);
   old_font = SelectObject (dc, ((W32FontStruct *)(font->font.font))->hfont);
@@ -320,16 +317,36 @@ w32font_text_extents (font, code, nglyphs, metrics)
       metrics->width = 0;
       metrics->ascent = 0;
       metrics->descent = 0;
+      metrics->lbearing = 0;
 
       for (i = 0; i < nglyphs; i++)
         {
-          if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
+          if (*(code + i) < 128 && *(code + i) > 32)
+            {
+              /* Use cached metrics for ASCII.  */
+              struct font_metrics *char_metric
+                = &((struct w32font_info *)font)->ascii_metrics[*(code+i)-32];
+
+              /* If we couldn't get metrics when caching, use fallback.  */
+              if (char_metric->width == 0)
+                break;
+
+              metrics->lbearing = max (metrics->lbearing,
+                                       char_metric->lbearing - metrics->width);
+              metrics->rbearing = max (metrics->rbearing,
+                                       metrics->width + char_metric->rbearing);
+              metrics->width += char_metric->width;
+              metrics->ascent = max (metrics->ascent, char_metric->ascent);
+              metrics->descent = max (metrics->descent, char_metric->descent);
+            }
+          else if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
                                 NULL, &transform) != GDI_ERROR)
             {
               int new_val = metrics->width + gm.gmBlackBoxX
                 + gm.gmptGlyphOrigin.x;
-
               metrics->rbearing = max (metrics->rbearing, new_val);
+              new_val = -gm.gmptGlyphOrigin.x - metrics->width;
+              metrics->lbearing = max (metrics->lbearing, new_val);
               metrics->width += gm.gmCellIncX;
               new_val = -gm.gmptGlyphOrigin.y;
               metrics->ascent = max (metrics->ascent, new_val);
@@ -658,14 +675,39 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
   if (hfont == NULL)
     return 0;
 
-  w32_font->owning_frame = f;
-
   /* Get the metrics for this font.  */
   dc = get_frame_dc (f);
   old_font = SelectObject (dc, hfont);
 
   GetTextMetrics (dc, &w32_font->metrics);
 
+  /* Cache ASCII metrics.  */
+  {
+    GLYPHMETRICS gm;
+    MAT2 transform;
+    int i;
+
+    bzero (&transform, sizeof (transform));
+    transform.eM11.value = 1;
+    transform.eM22.value = 1;
+
+    for (i = 0; i < 96; i++)
+      {
+        struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
+
+        if (GetGlyphOutlineW (dc, i + 32, GGO_METRICS, &gm, 0,
+                              NULL, &transform) != GDI_ERROR)
+          {
+            char_metric->lbearing = -gm.gmptGlyphOrigin.x;
+            char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
+            char_metric->width = gm.gmCellIncX;
+            char_metric->ascent = -gm.gmptGlyphOrigin.y;
+            char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
+          }
+        else
+          char_metric->width = 0;
+      }
+  }
   SelectObject (dc, old_font);
   release_frame_dc (f, dc);
   /* W32FontStruct - we should get rid of this, and use the w32font_info
index dd71405bf0afa05dd51b6d5d15ecbd59970002bb..ba8af67fa5a1a6615d236e7551e0c49d634005f8 100644 (file)
@@ -32,7 +32,7 @@ struct w32font_info
 {
   struct font font;
   TEXTMETRIC metrics;
-  struct frame *owning_frame;
+  struct font_metrics ascii_metrics[96];
 };
 
 Lisp_Object w32font_get_cache P_ ((FRAME_PTR fe));