From: Pip Cet <pipcet@gmail.com>
To: "Clément Pit-Claudel" <cpitclaudel@gmail.com>
Cc: Eli Zaretskii <eliz@gnu.org>, Alan Third <alan@idiocy.org>,
emacs-devel@gnu.org
Subject: Re: Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY))
Date: Tue, 19 May 2020 21:43:49 +0000 [thread overview]
Message-ID: <CAOqdjBfevUKGMcoeuG8JPtV5Qs09VMKW-BufHhQFpXq+qbKxTw@mail.gmail.com> (raw)
In-Reply-To: <75a90563-51b4-d3b8-4832-fc0e2542af0d@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1433 bytes --]
On Tue, May 19, 2020 at 2:39 PM Clément Pit-Claudel
<cpitclaudel@gmail.com> wrote:
> On 19/05/2020 09.56, Eli Zaretskii wrote:
> > I don't see anything on or after "a", I see a thin vertical line on
> > the "Z". is that what is actually displayed? If so, how do people
> > know the cursor is after "a"??
>
> They don't: "the seven equal slices that Firefox treats it as for selection/editing purposes don't match up to the visual shapes of the sub-glyphs at all well"
And I'm afraid the difference is much more obvious with box cursors
than it is with carets. I'm attaching a screenshot of a patched Emacs
displaying "ffi", with point on the second f, in the "Linux Libertine
Display O" font (using approximately equal slices).
I think this is a bit of a worst-case scenario, a three-letter
ligature in a font using ligatures and overhangs very
enthusiastically. It might be okay for other fonts.
My remaining idea is to stretch characters so we can break up a
ligature without changing its total width. I'm not sure how to do
that, though.
(I'm also attaching the patch, for the morbidly curious; it isn't
clean, readable, or finished in any way, and contains at least one
obvious bug. It's just good enough to produce the screenshot, and
maybe it can serve as a hint as to which files need changing for
ligatures to work; but such changes would have to be done very
differently from the patch.).
[-- Attachment #2: ffi-box-cursor.png --]
[-- Type: image/png, Size: 1067 bytes --]
[-- Attachment #3: 0001-Ligatures.diff --]
[-- Type: text/x-patch, Size: 21370 bytes --]
diff --git a/src/alloc.c b/src/alloc.c
index ebc55857ea..1395f647f4 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -322,7 +322,7 @@ #define PUREBEG (char *) pure
/* If positive, garbage collection is inhibited. Otherwise, zero. */
-static intptr_t garbage_collection_inhibited;
+static intptr_t garbage_collection_inhibited = 3;
/* The GC threshold in bytes, the last time it was calculated
from gc-cons-threshold and gc-cons-percentage. */
diff --git a/src/composite.c b/src/composite.c
index 518502be49..e2bece40c8 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -836,7 +836,7 @@ fill_gstring_body (Lisp_Object gstring)
LGLYPH_SET_CHAR (g, c);
if (font != NULL)
- code = font->driver->encode_char (font, LGLYPH_CHAR (g));
+ code = font->driver->encode_char (font, LGLYPH_CHAR (g), NULL);
else
code = FONT_INVALID_CODE;
if (code != FONT_INVALID_CODE)
diff --git a/src/dispextern.h b/src/dispextern.h
index 0b1f3d14ae..2f6b33e74c 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -397,6 +397,15 @@ #define SET_GLYPH_FROM_GLYPH_CODE(glyph, gc) \
};
+struct glyph_context
+{
+ union vectorlike_header header;
+ Lisp_Object string;
+ Lisp_Object position;
+ int i;
+ int n;
+};
+
/* Glyphs.
Be extra careful when changing this structure! Esp. make sure that
@@ -567,6 +576,8 @@ #define FACE_ID_BITS 20
/* Used to compare all bit-fields above in one step. */
unsigned val;
} u;
+
+ struct glyph_context *context;
};
diff --git a/src/font.c b/src/font.c
index ab00402b40..8de3c969b9 100644
--- a/src/font.c
+++ b/src/font.c
@@ -3010,7 +3010,7 @@ font_has_char (struct frame *f, Lisp_Object font, int c)
if (result >= 0)
return result;
}
- return (fontp->driver->encode_char (fontp, c) != FONT_INVALID_CODE);
+ return (fontp->driver->encode_char (fontp, c, NULL) != FONT_INVALID_CODE);
}
@@ -3023,7 +3023,7 @@ font_encode_char (Lisp_Object font_object, int c)
eassert (FONT_OBJECT_P (font_object));
font = XFONT_OBJECT (font_object);
- return font->driver->encode_char (font, c);
+ return font->driver->encode_char (font, c, NULL);
}
@@ -4418,7 +4418,7 @@ font_fill_lglyph_metrics (Lisp_Object glyph, struct font *font, unsigned int cod
struct font_metrics metrics;
LGLYPH_SET_CODE (glyph, code);
- font->driver->text_extents (font, &code, 1, &metrics);
+ font->driver->text_extents (font, &code, 1, &metrics, NULL);
LGLYPH_SET_LBEARING (glyph, metrics.lbearing);
LGLYPH_SET_RBEARING (glyph, metrics.rbearing);
LGLYPH_SET_WIDTH (glyph, metrics.width);
@@ -4638,7 +4638,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
struct face *face = FACE_FROM_ID (f, face_id);
if (! face->font)
return Qnil;
- unsigned code = face->font->driver->encode_char (face->font, c);
+ unsigned code = face->font->driver->encode_char (face->font, c, NULL);
if (code == FONT_INVALID_CODE)
return Qnil;
Lisp_Object font_object;
@@ -4965,7 +4965,7 @@ DEFUN ("font-get-glyphs", Ffont_get_glyphs, Sfont_get_glyphs, 3, 4, 0,
unsigned code;
struct font_metrics metrics;
- code = font->driver->encode_char (font, c);
+ code = font->driver->encode_char (font, c, NULL);
if (code == FONT_INVALID_CODE)
{
ASET (vec, i, Qnil);
@@ -4976,7 +4976,7 @@ DEFUN ("font-get-glyphs", Ffont_get_glyphs, Sfont_get_glyphs, 3, 4, 0,
LGLYPH_SET_TO (g, i);
LGLYPH_SET_CHAR (g, c);
LGLYPH_SET_CODE (g, code);
- font->driver->text_extents (font, &code, 1, &metrics);
+ font->driver->text_extents (font, &code, 1, &metrics, NULL);
LGLYPH_SET_WIDTH (g, metrics.width);
LGLYPH_SET_LBEARING (g, metrics.lbearing);
LGLYPH_SET_RBEARING (g, metrics.rbearing);
diff --git a/src/font.h b/src/font.h
index 8614e7fa10..952a9fa4c3 100644
--- a/src/font.h
+++ b/src/font.h
@@ -565,6 +565,8 @@ #define FONT_PIXEL_SIZE_QUANTUM 1
#define FONT_INVALID_CODE 0xFFFFFFFF
+struct glyph_context;
+
/* Font driver. Members specified as "optional" can be NULL. */
struct font_driver
@@ -645,14 +647,15 @@ #define FONT_INVALID_CODE 0xFFFFFFFF
/* Return a glyph code of FONT for character C (Unicode code point).
If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
- unsigned (*encode_char) (struct font *font, int c);
+ unsigned (*encode_char) (struct font *font, int c, struct glyph_context *context);
/* Compute the total metrics of the NGLYPHS glyphs specified by
the font FONT and the sequence of glyph codes CODE, and store the
result in METRICS. */
void (*text_extents) (struct font *font,
const unsigned *code, int nglyphs,
- struct font_metrics *metrics);
+ struct font_metrics *metrics,
+ struct glyph_context *context);
#ifdef HAVE_WINDOW_SYSTEM
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 7832d4f5ce..19c2644285 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -323,7 +323,7 @@ ftcrfont_has_char (Lisp_Object font, int c)
}
static unsigned
-ftcrfont_encode_char (struct font *font, int c)
+ftcrfont_encode_char (struct font *font, int c, struct glyph_context *context)
{
struct font_info *ftcrfont_info = (struct font_info *) font;
unsigned code = FONT_INVALID_CODE;
@@ -331,20 +331,53 @@ ftcrfont_encode_char (struct font *font, int c)
int utf8len = CHAR_STRING (c, utf8);
cairo_glyph_t stack_glyph;
cairo_glyph_t *glyphs = &stack_glyph;
- int num_glyphs = 1;
- if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0,
- (char *) utf8, utf8len,
- &glyphs, &num_glyphs,
- NULL, NULL, NULL)
- == CAIRO_STATUS_SUCCESS)
+ if (context == NULL)
{
- if (glyphs != &stack_glyph)
- cairo_glyph_free (glyphs);
- else if (stack_glyph.index)
- code = stack_glyph.index;
+ context = xmalloc (sizeof *context);
+ context->string = CALLN (Fstring, make_fixnum (c));
+ context->position = make_fixnum (0);
}
+ unsigned int num_glyphs = 0;
+ unsigned int num_clusters = 0;
+ hb_buffer_t *hb_buf = hb_buffer_create ();
+ hb_buffer_set_cluster_level (hb_buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
+ hb_buffer_add_utf8 (hb_buf, SDATA (context->string), -1, 0, -1);
+ hb_buffer_set_direction (hb_buf, HB_DIRECTION_LTR);
+ hb_font_t *hb_font = hb_ft_font_create_referenced
+ (cairo_ft_scaled_font_lock_face (ftcrfont_info->cr_scaled_font));
+ hb_shape (hb_font, hb_buf, NULL, 0);
+ hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos
+ (hb_buf, &num_glyphs);
+ hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions
+ (hb_buf, &num_glyphs);
+ int i0, i1;
+ int c0, c1;
+ i0 = 0;
+ for (int i = num_glyphs - 1; i >= 0; i--)
+ {
+ if (glyph_info[i].cluster <= XFIXNUM (context->position))
+ {
+ i0 = i;
+ c0 = glyph_info[i].cluster;
+ break;
+ }
+ }
+ i1 = num_glyphs;
+ for (int i = 0; i < num_glyphs; i++)
+ {
+ if (glyph_info[i].cluster > c0)
+ {
+ i1 = i;
+ c1 = glyph_info[i].cluster;
+ break;
+ }
+ }
+ context->i = XFIXNUM (context->position) - c0;
+ context->n = c1 - c0;
+ code = glyph_info[i0].codepoint;
+
return code;
}
@@ -352,30 +385,65 @@ ftcrfont_encode_char (struct font *font, int c)
ftcrfont_text_extents (struct font *font,
const unsigned *code,
int nglyphs,
- struct font_metrics *metrics)
+ struct font_metrics *metrics,
+ struct glyph_context *context)
{
+ struct font_info *ftcrfont_info = (struct font_info *) font;
int width, i;
block_input ();
- width = ftcrfont_glyph_extents (font, code[0], metrics);
- for (i = 1; i < nglyphs; i++)
+
+ if (context == NULL)
{
- struct font_metrics m;
- int w = ftcrfont_glyph_extents (font, code[i], metrics ? &m : NULL);
+ context = xmalloc (sizeof *context);
+ context->string = CALLN (Fstring, make_fixnum (code[0]));
+ context->position = make_fixnum (0);
+ }
- if (metrics)
+ unsigned int num_glyphs = 0;
+ unsigned int num_clusters = 0;
+ hb_buffer_t *hb_buf = hb_buffer_create ();
+ hb_buffer_set_cluster_level (hb_buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
+ hb_buffer_set_direction (hb_buf, HB_DIRECTION_LTR);
+ hb_buffer_set_content_type (hb_buf, HB_BUFFER_CONTENT_TYPE_UNICODE);
+ int n = 0;
+ for (const char *p = SDATA (context->string); p <= SDATA (context->string) + SBYTES (context->string);)
+ {
+ int c = string_char_advance (&p);
+ hb_buffer_add (hb_buf, c, n++);
+ }
+ hb_font_t *hb_font = hb_ft_font_create_referenced
+ (cairo_ft_scaled_font_lock_face (ftcrfont_info->cr_scaled_font));
+ hb_shape (hb_font, hb_buf, NULL, 0);
+ hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos
+ (hb_buf, &num_glyphs);
+ hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions
+ (hb_buf, &num_glyphs);
+ int i0, i1;
+ int c0, c1;
+ i0 = 0;
+ for (int i = num_glyphs - 1; i >= 0; i--)
+ {
+ if (glyph_info[i].cluster <= XFIXNUM (context->position))
+ {
+ i0 = i;
+ c0 = glyph_info[i].cluster;
+ break;
+ }
+ }
+ i1 = num_glyphs;
+ for (int i = 0; i < num_glyphs; i++)
+ {
+ if (glyph_info[i].cluster > c0)
{
- if (width + m.lbearing < metrics->lbearing)
- metrics->lbearing = width + m.lbearing;
- if (width + m.rbearing > metrics->rbearing)
- metrics->rbearing = width + m.rbearing;
- if (m.ascent > metrics->ascent)
- metrics->ascent = m.ascent;
- if (m.descent > metrics->descent)
- metrics->descent = m.descent;
+ i1 = i;
+ c1 = glyph_info[i].cluster;
+ break;
}
- width += w;
}
+ context->i = XFIXNUM (context->position) - c0;
+ context->n = c1 - c0;
+ width = glyph_pos[i0].x_advance / (c1 - c0) / 64;
unblock_input ();
if (metrics)
@@ -508,6 +576,8 @@ ftcrfont_draw (struct glyph_string *s,
glyphs[i].index = s->char2b[from + i];
glyphs[i].x = x;
glyphs[i].y = y;
+ struct glyph_context *context = s->first_glyph->context;
+ glyphs[i].x -= (context->i * s->width);
x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
glyphs[i].index,
NULL));
diff --git a/src/hbfont.c b/src/hbfont.c
index 576c5fe7f6..5c3c690281 100644
--- a/src/hbfont.c
+++ b/src/hbfont.c
@@ -578,7 +578,7 @@ hbfont_shape (Lisp_Object lgstring, Lisp_Object direction)
LGLYPH_SET_CODE (lglyph, info[i].codepoint);
unsigned code = info[i].codepoint;
- font->driver->text_extents (font, &code, 1, &metrics);
+ font->driver->text_extents (font, &code, 1, &metrics, NULL);
LGLYPH_SET_WIDTH (lglyph, metrics.width);
LGLYPH_SET_LBEARING (lglyph, metrics.lbearing);
LGLYPH_SET_RBEARING (lglyph, metrics.rbearing);
diff --git a/src/lisp.h b/src/lisp.h
index ad7d67ae69..c4ae954999 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -1103,6 +1103,7 @@ DEFINE_GDB_SYMBOL_END (PSEUDOVECTOR_FLAG)
PVEC_MUTEX,
PVEC_CONDVAR,
PVEC_MODULE_FUNCTION,
+ PVEC_GLYPH_CONTEXT,
/* These should be last, for internal_equal and sxhash_obj. */
PVEC_COMPILED,
diff --git a/src/xdisp.c b/src/xdisp.c
index cf15f579b5..41a7b4235a 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -27499,14 +27499,15 @@ append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
static struct face *
get_char_face_and_encoding (struct frame *f, int c, int face_id,
- unsigned *char2b, bool display_p)
+ unsigned *char2b, bool display_p,
+ struct glyph_context *context)
{
struct face *face = FACE_FROM_ID (f, face_id);
unsigned code = 0;
if (face->font)
{
- code = face->font->driver->encode_char (face->font, c);
+ code = face->font->driver->encode_char (face->font, c, context);
if (code == FONT_INVALID_CODE)
code = 0;
@@ -27533,7 +27534,7 @@ get_char_face_and_encoding (struct frame *f, int c, int face_id,
static struct face *
get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
- unsigned *char2b)
+ unsigned *char2b, struct glyph_context *context)
{
struct face *face;
unsigned code = 0;
@@ -27549,7 +27550,8 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
if (CHAR_BYTE8_P (glyph->u.ch))
code = CHAR_TO_BYTE8 (glyph->u.ch);
else
- code = face->font->driver->encode_char (face->font, glyph->u.ch);
+ code = face->font->driver->encode_char (face->font, glyph->u.ch,
+ context);
if (code == FONT_INVALID_CODE)
code = 0;
@@ -27565,14 +27567,15 @@ get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
Return true iff FONT has a glyph for C. */
static bool
-get_char_glyph_code (int c, struct font *font, unsigned *char2b)
+get_char_glyph_code (int c, struct font *font, unsigned *char2b,
+ struct glyph_context *context)
{
unsigned code;
if (CHAR_BYTE8_P (c))
code = CHAR_TO_BYTE8 (c);
else
- code = font->driver->encode_char (font, c);
+ code = font->driver->encode_char (font, c, context);
if (code == FONT_INVALID_CODE)
return false;
@@ -27620,7 +27623,8 @@ fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
-1, Qnil);
face = get_char_face_and_encoding (s->f, c, face_id,
- s->char2b + i, true);
+ s->char2b + i, true,
+ NULL);
if (face)
{
if (! s->face)
@@ -27777,12 +27781,13 @@ fill_glyph_string (struct glyph_string *s, int face_id,
&& glyph->glyph_not_available_p == glyph_not_available_p)
{
s->face = get_glyph_face_and_encoding (s->f, glyph,
- s->char2b + s->nchars);
+ s->char2b + s->nchars,
+ glyph->context);
++s->nchars;
eassert (s->nchars <= end - start);
s->width += glyph->pixel_width;
- if (glyph++->padding_p != s->padding_p)
- break;
+ glyph++;
+ break;
}
s->font = s->face->font;
@@ -27877,7 +27882,8 @@ fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
}
static struct font_metrics *
-get_per_char_metric (struct font *font, const unsigned *char2b)
+get_per_char_metric (struct font *font, const unsigned *char2b,
+ struct glyph_context *context)
{
static struct font_metrics metrics;
@@ -27886,7 +27892,7 @@ get_per_char_metric (struct font *font, const unsigned *char2b)
if (*char2b == FONT_INVALID_CODE)
return NULL;
- font->driver->text_extents (font, char2b, 1, &metrics);
+ font->driver->text_extents (font, char2b, 1, &metrics, context);
return &metrics;
}
@@ -27908,9 +27914,10 @@ normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
/* Get metrics of C, defaulting to a reasonably sized ASCII
character. */
- if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
+ if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b, NULL))
{
- struct font_metrics *pcm = get_per_char_metric (font, &char2b);
+ struct font_metrics *pcm = get_per_char_metric (font, &char2b,
+ NULL);
if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
{
@@ -27952,10 +27959,12 @@ gui_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *r
if (glyph->type == CHAR_GLYPH)
{
unsigned char2b;
- struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
+ struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b,
+ NULL);
if (face->font)
{
- struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
+ struct font_metrics *pcm = get_per_char_metric (face->font, &char2b,
+ NULL);
if (pcm)
{
if (pcm->rbearing > pcm->width)
@@ -29841,12 +29850,12 @@ produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
str = buf;
}
for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
- code[len] = font->driver->encode_char (font, str[len]);
+ code[len] = font->driver->encode_char (font, str[len], NULL);
upper_len = (len + 1) / 2;
font->driver->text_extents (font, code, upper_len,
- &metrics_upper);
+ &metrics_upper, NULL);
font->driver->text_extents (font, code + upper_len, len - upper_len,
- &metrics_lower);
+ &metrics_lower, NULL);
@@ -29936,6 +29945,40 @@ #define IT_APPLY_FACE_BOX(it, face) \
} \
} while (false)
+static struct glyph_context *
+make_context (struct it *it)
+{
+ struct glyph_context *context = xmalloc (sizeof *context); // XXX GC
+ char *string = xmalloc (128);
+ char *p = string;
+ ptrdiff_t bytepos = it->current.pos.bytepos;
+ ptrdiff_t charpos = it->current.pos.charpos;
+ ptrdiff_t bp5 = bytepos;
+ ptrdiff_t bp0 = bp5;
+ ptrdiff_t bp1 = bp5;
+ while (bytepos > BEG_BYTE && bp5 - bytepos < 32)
+ dec_both (&charpos, &bytepos);
+ bp0 = bytepos;
+ int i = 0;
+ Lisp_Object pos = make_fixnum (0);
+ while (bytepos >= BEG_BYTE && bytepos < Z_BYTE && bytepos - bp0 < 32)
+ {
+ inc_both (&charpos, &bytepos);
+ memcpy (p, BUF_BYTE_ADDRESS (current_buffer, bytepos - prev_char_len (bytepos)), prev_char_len (bytepos));
+ p += prev_char_len (bytepos);
+ ++i;
+ if (bytepos == bp5)
+ pos = make_fixnum (i);
+ }
+ bp1 = bytepos;
+ eassert (strlen (p) == bp1 - bp0);
+ *p++ = it->c;
+ *p++ = 0;
+ context->string = build_string (string);
+ context->position = pos;
+ return context;
+}
+
/* RIF:
Produce glyphs/get display metrics for the display element IT is
loaded with. See the description of struct it in dispextern.h
@@ -29973,6 +30016,7 @@ gui_produce_glyphs (struct it *it)
if (font->vertical_centering)
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+ struct glyph_context *context = NULL;
if (it->char_to_display != '\n' && it->char_to_display != '\t')
{
it->nglyphs = 1;
@@ -29989,9 +30033,11 @@ gui_produce_glyphs (struct it *it)
it->descent = FONT_DESCENT (font) - boff;
}
- if (get_char_glyph_code (it->char_to_display, font, &char2b))
+ context = make_context (it);
+ if (get_char_glyph_code (it->char_to_display, font, &char2b,
+ context))
{
- pcm = get_per_char_metric (font, &char2b);
+ pcm = get_per_char_metric (font, &char2b, context);
if (pcm->width == 0
&& pcm->rbearing == 0 && pcm->lbearing == 0)
pcm = NULL;
@@ -30079,9 +30125,13 @@ gui_produce_glyphs (struct it *it)
/ FONT_HEIGHT (font));
append_stretch_glyph (it, it->object, it->pixel_width,
it->ascent + it->descent, ascent);
+ it->glyph_row->glyphs[it->area][it->glyph_row->used[it->area] - 1].context = NULL;
}
else
- append_glyph (it);
+ {
+ append_glyph (it);
+ it->glyph_row->glyphs[it->area][it->glyph_row->used[it->area] - 1].context = context;
+ }
/* If characters with lbearing or rbearing are displayed
in this line, record that fact in a flag of the
@@ -30233,9 +30283,9 @@ gui_produce_glyphs (struct it *it)
it->nglyphs = 1;
if (FONT_TOO_HIGH (font))
{
- if (get_char_glyph_code (' ', font, &char2b))
+ if (get_char_glyph_code (' ', font, &char2b, NULL))
{
- pcm = get_per_char_metric (font, &char2b);
+ pcm = get_per_char_metric (font, &char2b, NULL);
if (pcm->width == 0
&& pcm->rbearing == 0 && pcm->lbearing == 0)
pcm = NULL;
@@ -30372,8 +30422,8 @@ gui_produce_glyphs (struct it *it)
if (! font_not_found_p)
{
get_char_face_and_encoding (it->f, c, it->face_id,
- &char2b, false);
- pcm = get_per_char_metric (font, &char2b);
+ &char2b, false, NULL);
+ pcm = get_per_char_metric (font, &char2b, NULL);
}
/* Initialize the bounding box. */
@@ -30433,8 +30483,9 @@ gui_produce_glyphs (struct it *it)
else
{
get_char_face_and_encoding (it->f, ch, face_id,
- &char2b, false);
- pcm = get_per_char_metric (font, &char2b);
+ &char2b, false,
+ make_context (it));
+ pcm = get_per_char_metric (font, &char2b, make_context (it));
}
if (! pcm)
cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
diff --git a/src/xterm.c b/src/xterm.c
index 7989cecec7..3b5f0d3524 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1703,7 +1703,8 @@ x_compute_glyph_string_overhangs (struct glyph_string *s)
if (s->first_glyph->type == CHAR_GLYPH)
{
struct font *font = s->font;
- font->driver->text_extents (font, s->char2b, s->nchars, &metrics);
+ font->driver->text_extents (font, s->char2b, s->nchars, &metrics,
+ NULL);
}
else
{
@@ -2047,7 +2048,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
/* 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;
+ char2b[j] = s->font->driver->encode_char (s->font, str[j], NULL) & 0xFFFF;
s->font->driver->draw (s, 0, upper_len,
x + glyph->slice.glyphless.upper_xoff,
s->ybase + glyph->slice.glyphless.upper_yoff,
next prev parent reply other threads:[~2020-05-19 21:43 UTC|newest]
Thread overview: 145+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-17 10:41 Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY) Julius Pfrommer
2020-05-17 14:09 ` Arthur Miller
2020-05-17 14:30 ` Eli Zaretskii
2020-05-17 15:06 ` Arthur Miller
2020-05-17 15:56 ` Eli Zaretskii
2020-05-17 16:50 ` Arthur Miller
2020-05-17 17:06 ` Eli Zaretskii
2020-05-17 14:35 ` Eli Zaretskii
2020-05-17 14:59 ` Julius Pfrommer
2020-05-17 15:55 ` Eli Zaretskii
2020-05-17 16:28 ` Pip Cet
2020-05-17 17:00 ` Eli Zaretskii
2020-05-17 18:50 ` Pip Cet
2020-05-17 19:17 ` Eli Zaretskii
2020-05-18 16:08 ` Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY)) Eli Zaretskii
2020-05-18 16:45 ` tomas
2020-05-18 16:49 ` Eli Zaretskii
2020-05-18 17:05 ` Ligatures Stefan Monnier
2020-05-18 17:18 ` Ligatures Eli Zaretskii
2020-05-18 19:19 ` Ligatures Pip Cet
2020-05-18 19:25 ` Ligatures tomas
2020-05-18 19:41 ` Ligatures Pip Cet
2020-05-18 20:20 ` Ligatures tomas
2020-05-18 19:33 ` Ligatures Eli Zaretskii
2020-05-18 19:44 ` Ligatures Clément Pit-Claudel
2020-05-19 2:25 ` Ligatures Eli Zaretskii
2020-05-19 2:44 ` Ligatures Clément Pit-Claudel
2020-05-19 13:59 ` Ligatures Eli Zaretskii
2020-05-19 14:35 ` Ligatures Clément Pit-Claudel
2020-05-19 15:21 ` Ligatures Eli Zaretskii
2020-05-19 15:44 ` Ligatures Clément Pit-Claudel
2020-05-19 16:15 ` Ligatures Eli Zaretskii
2020-05-19 15:36 ` Ligatures Tassilo Horn
2020-05-19 16:08 ` Ligatures Eli Zaretskii
2020-05-19 16:14 ` Ligatures Stefan Monnier
2020-05-19 3:47 ` Ligatures Stefan Monnier
2020-05-19 4:51 ` Ligatures Clément Pit-Claudel
2020-05-18 19:38 ` Ligatures Clément Pit-Claudel
2020-05-19 14:55 ` Ligatures Pip Cet
2020-05-19 15:30 ` Ligatures Clément Pit-Claudel
2020-05-19 15:52 ` Ligatures Pip Cet
2020-05-18 17:24 ` Ligatures tomas
2020-05-18 17:41 ` Ligatures Eli Zaretskii
2020-05-18 19:07 ` Ligatures tomas
2020-05-18 19:17 ` Ligatures Eli Zaretskii
2020-05-18 20:33 ` Ligatures Stefan Monnier
2020-05-18 17:31 ` Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY)) Clément Pit-Claudel
2020-05-18 17:39 ` Eli Zaretskii
2020-05-18 19:01 ` Clément Pit-Claudel
2020-05-18 19:15 ` Eli Zaretskii
2020-05-18 19:18 ` tomas
2020-05-18 20:37 ` Ligatures Stefan Monnier
2020-05-18 21:59 ` Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY)) Alan Third
2020-05-19 13:56 ` Eli Zaretskii
2020-05-19 14:39 ` Clément Pit-Claudel
2020-05-19 21:43 ` Pip Cet [this message]
2020-05-20 1:41 ` Clément Pit-Claudel
2020-05-20 2:07 ` Ligatures Stefan Monnier
2020-05-20 7:14 ` Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY)) tomas
2020-05-20 15:18 ` Eli Zaretskii
2020-05-20 17:31 ` Clément Pit-Claudel
2020-05-20 18:01 ` Eli Zaretskii
2020-05-20 18:33 ` Clément Pit-Claudel
2020-05-20 18:49 ` Eli Zaretskii
2020-05-20 18:53 ` Clément Pit-Claudel
2020-05-20 19:02 ` Eli Zaretskii
2020-05-20 23:19 ` Ligatures Stefan Monnier
2020-05-21 10:01 ` Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY)) Pip Cet
2020-05-21 14:11 ` Eli Zaretskii
2020-05-21 16:26 ` Pip Cet
2020-05-21 19:08 ` Eli Zaretskii
2020-05-21 20:51 ` Clément Pit-Claudel
2020-05-21 21:16 ` Pip Cet
2020-05-22 6:12 ` Eli Zaretskii
2020-05-22 9:25 ` Pip Cet
2020-05-22 11:23 ` Eli Zaretskii
2020-05-22 12:52 ` Pip Cet
2020-05-22 13:15 ` Eli Zaretskii
2020-05-22 13:29 ` Clément Pit-Claudel
2020-05-22 14:30 ` Eli Zaretskii
2020-05-22 14:34 ` Clément Pit-Claudel
2020-05-22 19:01 ` Eli Zaretskii
2020-05-22 19:33 ` Clément Pit-Claudel
2020-05-22 19:44 ` Eli Zaretskii
2020-05-22 20:02 ` Clément Pit-Claudel
[not found] ` <83mu5z171j.fsf@gnu.org>
2020-05-23 14:34 ` Clément Pit-Claudel
2020-05-23 16:18 ` Eli Zaretskii
2020-05-23 16:37 ` Clément Pit-Claudel
2020-05-22 13:56 ` Pip Cet
[not found] ` <83lflj16jn.fsf@gnu.org>
[not found] ` <AF222EA0-FE05-4224-8459-2BF82CE27266@vasilij.de>
[not found] ` <834ks7110w.fsf@gnu.org>
2020-05-23 11:24 ` Vasilij Schneidermann
2020-05-23 13:04 ` Eli Zaretskii
[not found] ` <83eerb145r.fsf@gnu.org>
[not found] ` <CAOqdjBeef8Fa596raEyBUwv0Zr+41LSiYvHW39EdoaXpyxCXVw@mail.gmail.com>
[not found] ` <831rnb0zld.fsf@gnu.org>
2020-05-23 12:36 ` Pip Cet
2020-05-23 14:08 ` Eli Zaretskii
2020-05-23 15:13 ` Pip Cet
2020-05-23 16:34 ` Eli Zaretskii
2020-05-23 22:38 ` Pip Cet
2020-05-24 15:33 ` Eli Zaretskii
2020-05-26 18:13 ` Pip Cet
2020-05-26 19:46 ` Eli Zaretskii
2020-05-27 9:36 ` Pip Cet
2020-05-27 17:13 ` Eli Zaretskii
2020-05-27 18:42 ` Pip Cet
2020-05-27 19:19 ` Eli Zaretskii
2020-05-23 17:32 ` Eli Zaretskii
2020-05-23 21:29 ` Pip Cet
2020-05-24 15:19 ` Eli Zaretskii
2020-05-23 12:47 ` Ligatures Stefan Monnier
2020-05-23 13:10 ` Ligatures Eli Zaretskii
2020-05-23 13:45 ` Ligatures Stefan Monnier
2020-05-23 14:12 ` Ligatures Eli Zaretskii
2020-05-23 13:36 ` Ligatures 조성빈
2020-05-23 14:15 ` Ligatures Stefan Monnier
2020-05-23 14:37 ` Ligatures Pip Cet
2020-05-22 11:44 ` Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY)) Eli Zaretskii
2020-05-22 13:26 ` Clément Pit-Claudel
2020-05-22 14:29 ` Eli Zaretskii
2020-05-22 14:32 ` Clément Pit-Claudel
2020-05-22 19:00 ` Eli Zaretskii
2020-05-21 21:06 ` Pip Cet
2020-05-22 6:06 ` Eli Zaretskii
2020-05-22 9:34 ` Pip Cet
2020-05-22 11:33 ` Eli Zaretskii
2020-05-19 20:26 ` Alan Third
2020-05-19 10:09 ` Trevor Spiteri
2020-05-19 14:22 ` Eli Zaretskii
2020-05-19 5:43 ` Ligatures ASSI
2020-05-19 7:22 ` Ligatures tomas
2020-05-19 7:55 ` Ligatures Joost Kremers
2020-05-19 8:07 ` Ligatures tomas
2020-05-19 10:17 ` Ligatures Yuri Khan
2020-05-19 14:26 ` Ligatures Eli Zaretskii
2020-05-19 19:00 ` Ligatures Yuri Khan
2020-05-19 10:43 ` Ligatures Werner LEMBERG
2020-05-19 10:48 ` Ligatures tomas
2020-05-19 14:18 ` Ligatures Eli Zaretskii
2020-05-19 14:52 ` Ligatures Eli Zaretskii
2020-05-19 15:11 ` Ligatures Pip Cet
2020-05-19 15:36 ` Ligatures Eli Zaretskii
2020-05-19 16:16 ` Ligatures Pip Cet
2020-05-19 16:41 ` Ligatures Eli Zaretskii
2020-05-19 17:00 ` Ligatures Eli Zaretskii
2020-05-17 18:28 ` Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY) Julius Pfrommer
2020-05-17 18:45 ` Eli Zaretskii
2020-05-17 22:28 ` chad
2020-05-18 22:08 ` Alan Third
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAOqdjBfevUKGMcoeuG8JPtV5Qs09VMKW-BufHhQFpXq+qbKxTw@mail.gmail.com \
--to=pipcet@gmail.com \
--cc=alan@idiocy.org \
--cc=cpitclaudel@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).