diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/src/font.c b/src/font.c index 10dce4764a2..8347a0d5b23 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -3496,8 +3496,8 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3496 | 3496 | ||
| 3497 | c = STRING_CHAR_ADVANCE (p); | 3497 | c = STRING_CHAR_ADVANCE (p); |
| 3498 | code = font->driver->encode_char (font, c); | 3498 | code = font->driver->encode_char (font, c); |
| 3499 | if (code > MOST_POSITIVE_FIXNUM) | 3499 | if (code > MOST_POSITIVE_FIXNUM || code == FONT_INVALID_CODE) |
| 3500 | error ("Glyph code 0x%X is too large", code); | 3500 | break; |
| 3501 | LGLYPH_SET_FROM (g, i); | 3501 | LGLYPH_SET_FROM (g, i); |
| 3502 | LGLYPH_SET_TO (g, i); | 3502 | LGLYPH_SET_TO (g, i); |
| 3503 | LGLYPH_SET_CHAR (g, c); | 3503 | LGLYPH_SET_CHAR (g, c); |
| @@ -3522,15 +3522,15 @@ FONT-OBJECT may be nil if GSTRING already already contains one. */) | |||
| 3522 | 3522 | ||
| 3523 | FETCH_CHAR_ADVANCE (c, pos, pos_byte); | 3523 | FETCH_CHAR_ADVANCE (c, pos, pos_byte); |
| 3524 | code = font->driver->encode_char (font, c); | 3524 | code = font->driver->encode_char (font, c); |
| 3525 | if (code > MOST_POSITIVE_FIXNUM) | 3525 | if (code > MOST_POSITIVE_FIXNUM || code == FONT_INVALID_CODE) |
| 3526 | error ("Glyph code 0x%X is too large", code); | 3526 | break; |
| 3527 | LGLYPH_SET_FROM (g, i); | 3527 | LGLYPH_SET_FROM (g, i); |
| 3528 | LGLYPH_SET_TO (g, i); | 3528 | LGLYPH_SET_TO (g, i); |
| 3529 | LGLYPH_SET_CHAR (g, c); | 3529 | LGLYPH_SET_CHAR (g, c); |
| 3530 | LGLYPH_SET_CODE (g, code); | 3530 | LGLYPH_SET_CODE (g, code); |
| 3531 | } | 3531 | } |
| 3532 | } | 3532 | } |
| 3533 | for (i = LGSTRING_LENGTH (gstring) - 1; i >= len; i--) | 3533 | for (; i < LGSTRING_LENGTH (gstring); i++) |
| 3534 | LGSTRING_SET_GLYPH (gstring, i, Qnil); | 3534 | LGSTRING_SET_GLYPH (gstring, i, Qnil); |
| 3535 | return Qnil; | 3535 | return Qnil; |
| 3536 | } | 3536 | } |
| @@ -3539,7 +3539,8 @@ DEFUN ("font-shape-text", Ffont_shape_text, Sfont_shape_text, 3, 4, 0, | |||
| 3539 | doc: /* Shape text between FROM and TO by FONT-OBJECT. | 3539 | doc: /* Shape text between FROM and TO by FONT-OBJECT. |
| 3540 | If optional 4th argument STRING is non-nil, it is a string to shape, | 3540 | If optional 4th argument STRING is non-nil, it is a string to shape, |
| 3541 | and FROM and TO are indices to the string. | 3541 | and FROM and TO are indices to the string. |
| 3542 | The value is the end position of the shaped text. */) | 3542 | The value is the end position of the text that can be shaped by |
| 3543 | FONT-OBJECT. */) | ||
| 3543 | (from, to, font_object, string) | 3544 | (from, to, font_object, string) |
| 3544 | Lisp_Object from, to, font_object, string; | 3545 | Lisp_Object from, to, font_object, string; |
| 3545 | { | 3546 | { |
| @@ -3547,7 +3548,7 @@ The value is the end position of the shaped text. */) | |||
| 3547 | struct font_metrics metrics; | 3548 | struct font_metrics metrics; |
| 3548 | EMACS_INT start, end; | 3549 | EMACS_INT start, end; |
| 3549 | Lisp_Object gstring, n; | 3550 | Lisp_Object gstring, n; |
| 3550 | int i; | 3551 | int len, i, j; |
| 3551 | 3552 | ||
| 3552 | if (NILP (string)) | 3553 | if (NILP (string)) |
| 3553 | { | 3554 | { |
| @@ -3569,12 +3570,27 @@ The value is the end position of the shaped text. */) | |||
| 3569 | if (! font->driver->shape) | 3570 | if (! font->driver->shape) |
| 3570 | return from; | 3571 | return from; |
| 3571 | 3572 | ||
| 3572 | gstring = Ffont_make_gstring (font_object, make_number (end - start)); | 3573 | len = end - start; |
| 3574 | gstring = Ffont_make_gstring (font_object, make_number (len)); | ||
| 3573 | Ffont_fill_gstring (gstring, font_object, from, to, string); | 3575 | Ffont_fill_gstring (gstring, font_object, from, to, string); |
| 3574 | n = font->driver->shape (gstring); | 3576 | |
| 3575 | if (NILP (n)) | 3577 | /* Try at most three times with larger gstring each time. */ |
| 3578 | for (i = 0; i < 3; i++) | ||
| 3579 | { | ||
| 3580 | Lisp_Object args[2]; | ||
| 3581 | |||
| 3582 | n = font->driver->shape (gstring); | ||
| 3583 | if (INTEGERP (n)) | ||
| 3584 | break; | ||
| 3585 | args[0] = gstring; | ||
| 3586 | args[1] = Fmake_vector (make_number (len), Qnil); | ||
| 3587 | gstring = Fvconcat (2, args); | ||
| 3588 | } | ||
| 3589 | if (! INTEGERP (n) || XINT (n) == 0) | ||
| 3576 | return Qnil; | 3590 | return Qnil; |
| 3577 | for (i = 0; i < XINT (n);) | 3591 | len = XINT (n); |
| 3592 | |||
| 3593 | for (i = 0; i < len;) | ||
| 3578 | { | 3594 | { |
| 3579 | Lisp_Object gstr; | 3595 | Lisp_Object gstr; |
| 3580 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | 3596 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); |
| @@ -3602,7 +3618,7 @@ The value is the end position of the shaped text. */) | |||
| 3602 | metrics.descent += LGLYPH_YOFF (g); | 3618 | metrics.descent += LGLYPH_YOFF (g); |
| 3603 | need_composition = 1; | 3619 | need_composition = 1; |
| 3604 | } | 3620 | } |
| 3605 | for (j = i + 1; j < XINT (n); j++) | 3621 | for (j = i + 1; j < len; j++) |
| 3606 | { | 3622 | { |
| 3607 | int x; | 3623 | int x; |
| 3608 | 3624 | ||
| @@ -3970,9 +3986,9 @@ the current buffer. It defaults to the currently selected window. */) | |||
| 3970 | if (NILP (window)) | 3986 | if (NILP (window)) |
| 3971 | window = selected_window; | 3987 | window = selected_window; |
| 3972 | CHECK_LIVE_WINDOW (window); | 3988 | CHECK_LIVE_WINDOW (window); |
| 3973 | w = XWINDOW (selected_window); | 3989 | w = XWINDOW (window); |
| 3974 | 3990 | ||
| 3975 | return font_at (-1, pos, NULL, w, Qnil); | 3991 | return font_at (-1, pos, NULL, w, string); |
| 3976 | } | 3992 | } |
| 3977 | 3993 | ||
| 3978 | #if 0 | 3994 | #if 0 |