]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix glyphless glyph display on NS (bug#54970)
authorAlan Third <alan@idiocy.org>
Sun, 17 Apr 2022 20:15:05 +0000 (21:15 +0100)
committerAlan Third <alan@idiocy.org>
Mon, 18 Apr 2022 19:24:51 +0000 (20:24 +0100)
* src/nsterm.m (ns_draw_glyphless_glyph_string_foreground): New
function.
(ns_draw_glyph_string): Use the new function.
* src/nsfont.m (nsfont_draw): Fix the location the glyphs are drawn,
and also which glyphs are drawn.
(ns_glyph_metrics): Reverse ascent and descent.

src/nsfont.m
src/nsterm.m

index f3c8a82930b424473ea59e8938cf596864cddce7..e913a50cb69cfaf5faf4b96b70f3fba2e344d053 100644 (file)
@@ -1176,15 +1176,15 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 
   face = s->face;
 
-  r.origin.x = s->x;
+  r.origin.x = x;
   if (s->face->box != FACE_NO_BOX && s->first_glyph->left_box_line_p)
     r.origin.x += max (s->face->box_vertical_line_width, 0);
 
-  r.origin.y = s->y;
+  r.origin.y = y;
   r.size.height = FONT_HEIGHT (font);
 
-  for (int i = from; i < to; ++i)
-    c[i] = s->char2b[i];
+  for (int i = 0; i < len; ++i)
+    c[i] = s->char2b[i + from];
 
   /* Fill background if requested.  */
   if (with_background && !isComposite)
@@ -1210,8 +1210,6 @@ nsfont_draw (struct glyph_string *s, int from, int to, int x, int y,
     }
 
   /* set up for character rendering */
-  r.origin.y = y;
-
   if (s->hl == DRAW_CURSOR)
     col = FRAME_BACKGROUND_COLOR (s->f);
   else
@@ -1721,8 +1719,8 @@ ns_glyph_metrics (struct nsfont_info *font_info, unsigned int block)
       metrics->rbearing = lrint (rb);
       metrics->lbearing = lrint (lb);
 
-      metrics->descent = NSMinY (r);
-      metrics->ascent = NSMaxY (r);
+      metrics->descent = - NSMaxY (r);
+      metrics->ascent = - NSMinY (r);
     }
   unblock_input ();
 }
index 550f29212e980bd6b59d6fc703a52ea0b35e4e7e..5a6a4d663b95de43993323ca65349d6810f8457a 100644 (file)
@@ -3945,6 +3945,81 @@ ns_draw_composite_glyph_string_foreground (struct glyph_string *s)
     }
 }
 
+/* Draw the foreground of glyph string S for glyphless characters.  */
+static void
+ns_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
+{
+  struct glyph *glyph = s->first_glyph;
+  NSGlyph char2b[8];
+  int x, i, j;
+
+  /* If first glyph of S has a left box line, start drawing the text
+     of S to the right of that box line.  */
+  if (s->face && s->face->box != FACE_NO_BOX
+      && s->first_glyph->left_box_line_p)
+    x = s->x + max (s->face->box_vertical_line_width, 0);
+  else
+    x = s->x;
+
+  s->char2b = char2b;
+
+  for (i = 0; i < s->nchars; i++, glyph++)
+    {
+      char buf[7];
+      char *str = NULL;
+      int len = glyph->u.glyphless.len;
+
+      if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)
+       {
+         if (len > 0
+             && CHAR_TABLE_P (Vglyphless_char_display)
+             && (CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display))
+                 >= 1))
+           {
+             Lisp_Object acronym
+               = (! glyph->u.glyphless.for_no_font
+                  ? CHAR_TABLE_REF (Vglyphless_char_display,
+                                    glyph->u.glyphless.ch)
+                  : XCHAR_TABLE (Vglyphless_char_display)->extras[0]);
+             if (STRINGP (acronym))
+               str = SSDATA (acronym);
+           }
+       }
+      else if (glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE)
+       {
+         unsigned int ch = glyph->u.glyphless.ch;
+         eassume (ch <= MAX_CHAR);
+         sprintf (buf, "%0*X", ch < 0x10000 ? 4 : 6, ch);
+         str = buf;
+       }
+
+      if (str)
+       {
+         int upper_len = (len + 1) / 2;
+
+         /* It is assured that all LEN characters in STR is ASCII.  */
+         for (j = 0; j < len; j++)
+            char2b[j] = s->font->driver->encode_char (s->font, str[j]) & 0xFFFF;
+         s->font->driver->draw (s, 0, upper_len,
+                                x + glyph->slice.glyphless.upper_xoff,
+                                s->ybase + glyph->slice.glyphless.upper_yoff,
+                                false);
+         s->font->driver->draw (s, upper_len, len,
+                                x + glyph->slice.glyphless.lower_xoff,
+                                s->ybase + glyph->slice.glyphless.lower_yoff,
+                                false);
+       }
+      if (glyph->u.glyphless.method != GLYPHLESS_DISPLAY_THIN_SPACE)
+        ns_draw_box (NSMakeRect (x, s->ybase - glyph->ascent,
+                                 glyph->pixel_width - 1,
+                                 glyph->ascent + glyph->descent - 1),
+                     1, 1,
+                     [NSColor colorWithUnsignedLong:NS_FACE_FOREGROUND (s->face)],
+                     YES, YES);
+      x += glyph->pixel_width;
+   }
+}
+
 static void
 ns_draw_glyph_string (struct glyph_string *s)
 /* --------------------------------------------------------------------------
@@ -4058,9 +4133,7 @@ ns_draw_glyph_string (struct glyph_string *s)
       else
         ns_maybe_dumpglyphs_background
           (s, s->first_glyph->type == COMPOSITE_GLYPH);
-      /* ... */
-      /* Not yet implemented.  */
-      /* ... */
+      ns_draw_glyphless_glyph_string_foreground (s);
       break;
 
     default: