aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2007-12-25 10:36:06 +0000
committerKenichi Handa2007-12-25 10:36:06 +0000
commit40fb53d66732a8fb4fd2e7d05b57ea3fa92a9c7c (patch)
tree228cdfd547c71f21b1e6ed56f423bcd42618ad81
parentc1f156b73be210f7dae123d0cacc48fd11d9ccec (diff)
downloademacs-40fb53d66732a8fb4fd2e7d05b57ea3fa92a9c7c.tar.gz
emacs-40fb53d66732a8fb4fd2e7d05b57ea3fa92a9c7c.zip
(Ffont_fill_gstring): Stop filling when a character not
supported by the font is found. (Ffont_shape_text): When a shape callback function returns nil, try at most two more times with larger gstring. (Ffont_at): Fix getting of w. Call font_at with correct 5th argument.
-rw-r--r--src/font.c44
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.
3540If optional 4th argument STRING is non-nil, it is a string to shape, 3540If optional 4th argument STRING is non-nil, it is a string to shape,
3541and FROM and TO are indices to the string. 3541and FROM and TO are indices to the string.
3542The value is the end position of the shaped text. */) 3542The value is the end position of the text that can be shaped by
3543FONT-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