diff options
| author | Kenichi Handa | 2008-08-29 07:54:44 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-08-29 07:54:44 +0000 |
| commit | 071132a958b5c4e4673cdf6e5057db1bc65837fe (patch) | |
| tree | 04f2dbc0c43df94650664cedc57e9b92a48257d6 /src | |
| parent | a88c7fcdd3a25d78472d87794b3d690776624d94 (diff) | |
| download | emacs-071132a958b5c4e4673cdf6e5057db1bc65837fe.tar.gz emacs-071132a958b5c4e4673cdf6e5057db1bc65837fe.zip | |
(QCf): New variable.
(check_gstring): Use LGSTRING_GLYPH_LEN, not LGSTRING_LENGTH.
(font_prepare_composition): Delete this function.
(font_range): Type and arguments changed.
(Ffont_make_gstring, Ffont_fill_gstring): Delete them.
(font_fill_lglyph_metrics): New function.
(Ffont_shape_text): Renamed to Ffont_shape_gstring and arguments
changed.
(syms_of_font): DEFSYM QCf. Delete defsubr for
Sfont_make_gstring, Sfont_fill_gstring, Sfont_shape_text. Defsubr
Sfont_shape_gstring.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 438 |
1 files changed, 129 insertions, 309 deletions
diff --git a/src/font.c b/src/font.c index 120d616db1d..037a92a33a8 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -67,6 +67,9 @@ Lisp_Object Qascii_0, Qiso8859_1, Qiso10646_1, Qunicode_bmp, Qunicode_sip; | |||
| 67 | #define DEFAULT_ENCODING Qiso8859_1 | 67 | #define DEFAULT_ENCODING Qiso8859_1 |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | /* Unicode category `Cf'. */ | ||
| 71 | static Lisp_Object QCf; | ||
| 72 | |||
| 70 | /* Special vector of zero length. This is repeatedly used by (struct | 73 | /* Special vector of zero length. This is repeatedly used by (struct |
| 71 | font_driver *)->list when a specified font is not found. */ | 74 | font_driver *)->list when a specified font is not found. */ |
| 72 | static Lisp_Object null_vector; | 75 | static Lisp_Object null_vector; |
| @@ -1893,7 +1896,7 @@ check_gstring (gstring) | |||
| 1893 | if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT))) | 1896 | if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT))) |
| 1894 | CHECK_NUMBER (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)); | 1897 | CHECK_NUMBER (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)); |
| 1895 | 1898 | ||
| 1896 | for (i = 0; i < LGSTRING_LENGTH (gstring); i++) | 1899 | for (i = 0; i < LGSTRING_GLYPH_LEN (gstring); i++) |
| 1897 | { | 1900 | { |
| 1898 | val = LGSTRING_GLYPH (gstring, i); | 1901 | val = LGSTRING_GLYPH (gstring, i); |
| 1899 | CHECK_VECTOR (val); | 1902 | CHECK_VECTOR (val); |
| @@ -2158,34 +2161,6 @@ font_otf_Anchor (anchor) | |||
| 2158 | #endif /* HAVE_LIBOTF */ | 2161 | #endif /* HAVE_LIBOTF */ |
| 2159 | #endif /* 0 */ | 2162 | #endif /* 0 */ |
| 2160 | 2163 | ||
| 2161 | /* G-string (glyph string) handler */ | ||
| 2162 | |||
| 2163 | /* G-string is a vector of the form [HEADER GLYPH ...]. | ||
| 2164 | See the docstring of `font-make-gstring' for more detail. */ | ||
| 2165 | |||
| 2166 | struct font * | ||
| 2167 | font_prepare_composition (cmp, f) | ||
| 2168 | struct composition *cmp; | ||
| 2169 | FRAME_PTR f; | ||
| 2170 | { | ||
| 2171 | Lisp_Object gstring | ||
| 2172 | = AREF (XHASH_TABLE (composition_hash_table)->key_and_value, | ||
| 2173 | cmp->hash_index * 2); | ||
| 2174 | |||
| 2175 | cmp->font = XFONT_OBJECT (LGSTRING_FONT (gstring)); | ||
| 2176 | cmp->glyph_len = LGSTRING_LENGTH (gstring); | ||
| 2177 | cmp->pixel_width = LGSTRING_WIDTH (gstring); | ||
| 2178 | cmp->lbearing = LGSTRING_LBEARING (gstring); | ||
| 2179 | cmp->rbearing = LGSTRING_RBEARING (gstring); | ||
| 2180 | cmp->ascent = LGSTRING_ASCENT (gstring); | ||
| 2181 | cmp->descent = LGSTRING_DESCENT (gstring); | ||
| 2182 | cmp->width = cmp->pixel_width / FRAME_COLUMN_WIDTH (f); | ||
| 2183 | if (cmp->width == 0) | ||
| 2184 | cmp->width = 1; | ||
| 2185 | |||
| 2186 | return cmp->font; | ||
| 2187 | } | ||
| 2188 | |||
| 2189 | 2164 | ||
| 2190 | /* Font sorting */ | 2165 | /* Font sorting */ |
| 2191 | 2166 | ||
| @@ -3148,8 +3123,8 @@ font_find_for_lface (f, attrs, spec, c) | |||
| 3148 | foundry[1] = null_vector; | 3123 | foundry[1] = null_vector; |
| 3149 | else if (STRINGP (attrs[LFACE_FOUNDRY_INDEX])) | 3124 | else if (STRINGP (attrs[LFACE_FOUNDRY_INDEX])) |
| 3150 | { | 3125 | { |
| 3151 | foundry[0] = font_intern_prop (SDATA (attrs[LFACE_FOUNDRY_INDEX]), | 3126 | val = attrs[LFACE_FOUNDRY_INDEX]; |
| 3152 | SBYTES (attrs[LFACE_FOUNDRY_INDEX]), 1); | 3127 | foundry[0] = font_intern_prop ((char *) SDATA (val), SBYTES (val), 1); |
| 3153 | foundry[1] = Qnil; | 3128 | foundry[1] = Qnil; |
| 3154 | foundry[2] = null_vector; | 3129 | foundry[2] = null_vector; |
| 3155 | } | 3130 | } |
| @@ -3178,8 +3153,10 @@ font_find_for_lface (f, attrs, spec, c) | |||
| 3178 | 3153 | ||
| 3179 | val = AREF (work, FONT_FAMILY_INDEX); | 3154 | val = AREF (work, FONT_FAMILY_INDEX); |
| 3180 | if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX])) | 3155 | if (NILP (val) && STRINGP (attrs[LFACE_FAMILY_INDEX])) |
| 3181 | val = font_intern_prop (SDATA (attrs[LFACE_FAMILY_INDEX]), | 3156 | { |
| 3182 | SBYTES (attrs[LFACE_FAMILY_INDEX]), 1); | 3157 | val = attrs[LFACE_FAMILY_INDEX]; |
| 3158 | val = font_intern_prop ((char *) SDATA (val), SBYTES (val), 1); | ||
| 3159 | } | ||
| 3183 | if (NILP (val)) | 3160 | if (NILP (val)) |
| 3184 | { | 3161 | { |
| 3185 | family = alloca ((sizeof family[0]) * 2); | 3162 | family = alloca ((sizeof family[0]) * 2); |
| @@ -3667,66 +3644,99 @@ font_at (c, pos, face, w, string) | |||
| 3667 | } | 3644 | } |
| 3668 | 3645 | ||
| 3669 | 3646 | ||
| 3670 | /* Check how many characters after POS (at most to LIMIT) can be | 3647 | #ifdef HAVE_WINDOW_SYSTEM |
| 3671 | displayed by the same font. FACE is the face selected for the | 3648 | |
| 3672 | character as POS on frame F. STRING, if not nil, is the string to | 3649 | /* Check how many characters after POS (at most to *LIMIT) can be |
| 3673 | check instead of the current buffer. | 3650 | displayed by the same font on the window W. FACE, if non-NULL, is |
| 3651 | the face selected for the character at POS. If STRING is not nil, | ||
| 3652 | it is the string to check instead of the current buffer. In that | ||
| 3653 | case, FACE must be not NULL. | ||
| 3674 | 3654 | ||
| 3675 | The return value is the position of the character that is displayed | 3655 | The return value is the font-object for the character at POS. |
| 3676 | by the differnt font than that of the character as POS. */ | 3656 | *LIMIT is set to the position where that font can't be used. |
| 3677 | 3657 | ||
| 3678 | EMACS_INT | 3658 | It is assured that the current buffer (or STRING) is multibyte. */ |
| 3679 | font_range (pos, limit, face, f, string) | 3659 | |
| 3680 | EMACS_INT pos, limit; | 3660 | Lisp_Object |
| 3661 | font_range (pos, limit, w, face, string) | ||
| 3662 | EMACS_INT pos, *limit; | ||
| 3663 | struct window *w; | ||
| 3681 | struct face *face; | 3664 | struct face *face; |
| 3682 | FRAME_PTR f; | ||
| 3683 | Lisp_Object string; | 3665 | Lisp_Object string; |
| 3684 | { | 3666 | { |
| 3685 | int multibyte; | 3667 | EMACS_INT pos_byte, ignore, start, start_byte; |
| 3686 | EMACS_INT pos_byte; | ||
| 3687 | int c; | 3668 | int c; |
| 3688 | struct font *font; | 3669 | Lisp_Object font_object = Qnil; |
| 3689 | int first = 1; | ||
| 3690 | 3670 | ||
| 3691 | if (NILP (string)) | 3671 | if (NILP (string)) |
| 3692 | { | 3672 | { |
| 3693 | multibyte = ! NILP (current_buffer->enable_multibyte_characters); | ||
| 3694 | pos_byte = CHAR_TO_BYTE (pos); | 3673 | pos_byte = CHAR_TO_BYTE (pos); |
| 3674 | if (! face) | ||
| 3675 | { | ||
| 3676 | int face_id; | ||
| 3677 | |||
| 3678 | face_id = face_at_buffer_position (w, pos, 0, 0, &ignore, *limit, 0); | ||
| 3679 | face = FACE_FROM_ID (XFRAME (w->frame), face_id); | ||
| 3680 | } | ||
| 3695 | } | 3681 | } |
| 3696 | else | 3682 | else |
| 3697 | { | 3683 | { |
| 3698 | multibyte = STRING_MULTIBYTE (string); | 3684 | font_assert (face); |
| 3699 | pos_byte = string_char_to_byte (string, pos); | 3685 | pos_byte = string_char_to_byte (string, pos); |
| 3700 | } | 3686 | } |
| 3701 | 3687 | ||
| 3702 | if (! multibyte) | 3688 | start = pos, start_byte = pos_byte; |
| 3703 | /* All unibyte character are displayed by the same font. */ | 3689 | while (pos < *limit) |
| 3704 | return limit; | ||
| 3705 | |||
| 3706 | while (pos < limit) | ||
| 3707 | { | 3690 | { |
| 3708 | int face_id; | 3691 | Lisp_Object category; |
| 3709 | 3692 | ||
| 3710 | if (NILP (string)) | 3693 | if (NILP (string)) |
| 3711 | FETCH_CHAR_ADVANCE_NO_CHECK (c, pos, pos_byte); | 3694 | FETCH_CHAR_ADVANCE_NO_CHECK (c, pos, pos_byte); |
| 3712 | else | 3695 | else |
| 3713 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte); | 3696 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, pos, pos_byte); |
| 3714 | face_id = FACE_FOR_CHAR (f, face, c, pos, string); | 3697 | if (NILP (font_object)) |
| 3715 | face = FACE_FROM_ID (f, face_id); | ||
| 3716 | if (first) | ||
| 3717 | { | 3698 | { |
| 3718 | font = face->font; | 3699 | font_object = font_for_char (face, c, pos - 1, string); |
| 3719 | first = 0; | 3700 | if (NILP (font_object)) |
| 3701 | return Qnil; | ||
| 3720 | continue; | 3702 | continue; |
| 3721 | } | 3703 | } |
| 3722 | else if (font != face->font) | 3704 | |
| 3705 | category = CHAR_TABLE_REF (Vunicode_category_table, c); | ||
| 3706 | if (! EQ (category, QCf) | ||
| 3707 | && font_encode_char (font_object, c) == FONT_INVALID_CODE) | ||
| 3723 | { | 3708 | { |
| 3724 | pos--; | 3709 | Lisp_Object f = font_for_char (face, c, pos - 1, string); |
| 3725 | break; | 3710 | EMACS_INT i, i_byte; |
| 3711 | |||
| 3712 | |||
| 3713 | if (NILP (f)) | ||
| 3714 | { | ||
| 3715 | *limit = pos - 1; | ||
| 3716 | return font_object; | ||
| 3717 | } | ||
| 3718 | i = start, i_byte = start_byte; | ||
| 3719 | while (i < pos - 1) | ||
| 3720 | { | ||
| 3721 | |||
| 3722 | if (NILP (string)) | ||
| 3723 | FETCH_CHAR_ADVANCE_NO_CHECK (c, i, i_byte); | ||
| 3724 | else | ||
| 3725 | FETCH_STRING_CHAR_ADVANCE_NO_CHECK (c, string, i, i_byte); | ||
| 3726 | category = CHAR_TABLE_REF (Vunicode_category_table, c); | ||
| 3727 | if (! EQ (category, QCf) | ||
| 3728 | && font_encode_char (f, c) == FONT_INVALID_CODE) | ||
| 3729 | { | ||
| 3730 | *limit = pos - 1; | ||
| 3731 | return font_object; | ||
| 3732 | } | ||
| 3733 | } | ||
| 3734 | font_object = f; | ||
| 3726 | } | 3735 | } |
| 3727 | } | 3736 | } |
| 3728 | return pos; | 3737 | return font_object; |
| 3729 | } | 3738 | } |
| 3739 | #endif | ||
| 3730 | 3740 | ||
| 3731 | 3741 | ||
| 3732 | /* Lisp API */ | 3742 | /* Lisp API */ |
| @@ -4179,272 +4189,82 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0, | |||
| 4179 | return Qnil; | 4189 | return Qnil; |
| 4180 | } | 4190 | } |
| 4181 | 4191 | ||
| 4182 | /* The following three functions are still experimental. */ | 4192 | |
| 4183 | 4193 | void | |
| 4184 | DEFUN ("font-make-gstring", Ffont_make_gstring, Sfont_make_gstring, 2, 2, 0, | 4194 | font_fill_lglyph_metrics (glyph, font_object) |
| 4185 | doc: /* Return a newly created g-string for FONT-OBJECT with NUM glyphs. | 4195 | Lisp_Object glyph, font_object; |
| 4186 | FONT-OBJECT may be nil if it is not yet known. | ||
| 4187 | |||
| 4188 | G-string is sequence of glyphs of a specific font, | ||
| 4189 | and is a vector of this form: | ||
| 4190 | [ HEADER GLYPH ... ] | ||
| 4191 | HEADER is a vector of this form: | ||
| 4192 | [FONT-OBJECT WIDTH LBEARING RBEARING ASCENT DESCENT] | ||
| 4193 | where | ||
| 4194 | FONT-OBJECT is a font-object for all glyphs in the g-string, | ||
| 4195 | WIDTH thru DESCENT are the metrics (in pixels) of the whole G-string. | ||
| 4196 | GLYPH is a vector of this form: | ||
| 4197 | [ FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT | ||
| 4198 | [ [X-OFF Y-OFF WADJUST] | nil] ] | ||
| 4199 | where | ||
| 4200 | FROM-IDX and TO-IDX are used internally and should not be touched. | ||
| 4201 | C is the character of the glyph. | ||
| 4202 | CODE is the glyph-code of C in FONT-OBJECT. | ||
| 4203 | WIDTH thru DESCENT are the metrics (in pixels) of the glyph. | ||
| 4204 | X-OFF and Y-OFF are offests to the base position for the glyph. | ||
| 4205 | WADJUST is the adjustment to the normal width of the glyph. */) | ||
| 4206 | (font_object, num) | ||
| 4207 | Lisp_Object font_object, num; | ||
| 4208 | { | 4196 | { |
| 4209 | Lisp_Object gstring, g; | 4197 | struct font *font = XFONT_OBJECT (font_object); |
| 4210 | int len; | 4198 | unsigned code = font->driver->encode_char (font, LGLYPH_CHAR (glyph)); |
| 4211 | int i; | 4199 | struct font_metrics metrics; |
| 4212 | 4200 | ||
| 4213 | if (! NILP (font_object)) | 4201 | LGLYPH_SET_CODE (glyph, code); |
| 4214 | CHECK_FONT_OBJECT (font_object); | 4202 | font->driver->text_extents (font, &code, 1, &metrics); |
| 4215 | CHECK_NATNUM (num); | 4203 | LGLYPH_SET_LBEARING (glyph, metrics.lbearing); |
| 4216 | 4204 | LGLYPH_SET_RBEARING (glyph, metrics.rbearing); | |
| 4217 | len = XINT (num) + 1; | 4205 | LGLYPH_SET_WIDTH (glyph, metrics.width); |
| 4218 | gstring = Fmake_vector (make_number (len), Qnil); | 4206 | LGLYPH_SET_ASCENT (glyph, metrics.ascent); |
| 4219 | g = Fmake_vector (make_number (6), Qnil); | 4207 | LGLYPH_SET_DESCENT (glyph, metrics.descent); |
| 4220 | ASET (g, 0, font_object); | ||
| 4221 | ASET (gstring, 0, g); | ||
| 4222 | for (i = 1; i < len; i++) | ||
| 4223 | ASET (gstring, i, Fmake_vector (make_number (10), Qnil)); | ||
| 4224 | return gstring; | ||
| 4225 | } | 4208 | } |
| 4226 | 4209 | ||
| 4227 | DEFUN ("font-fill-gstring", Ffont_fill_gstring, Sfont_fill_gstring, 4, 5, 0, | ||
| 4228 | doc: /* Fill in glyph-string GSTRING by characters for FONT-OBJECT. | ||
| 4229 | START and END specify the region to extract characters. | ||
| 4230 | If optional 5rd argument OBJECT is non-nil, it is a buffer or a string from | ||
| 4231 | where to extract characters. | ||
| 4232 | FONT-OBJECT may be nil if GSTRING already contains one. */) | ||
| 4233 | (gstring, font_object, start, end, object) | ||
| 4234 | Lisp_Object gstring, font_object, start, end, object; | ||
| 4235 | { | ||
| 4236 | int len, i, c; | ||
| 4237 | unsigned code; | ||
| 4238 | struct font *font; | ||
| 4239 | |||
| 4240 | CHECK_VECTOR (gstring); | ||
| 4241 | if (NILP (font_object)) | ||
| 4242 | font_object = LGSTRING_FONT (gstring); | ||
| 4243 | font = XFONT_OBJECT (font_object); | ||
| 4244 | |||
| 4245 | if (STRINGP (object)) | ||
| 4246 | { | ||
| 4247 | const unsigned char *p; | ||
| 4248 | |||
| 4249 | CHECK_NATNUM (start); | ||
| 4250 | CHECK_NATNUM (end); | ||
| 4251 | if (XINT (start) > XINT (end) | ||
| 4252 | || XINT (end) > ASIZE (object) | ||
| 4253 | || XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring)) | ||
| 4254 | args_out_of_range_3 (object, start, end); | ||
| 4255 | |||
| 4256 | len = XINT (end) - XINT (start); | ||
| 4257 | p = SDATA (object) + string_char_to_byte (object, XINT (start)); | ||
| 4258 | for (i = 0; i < len; i++) | ||
| 4259 | { | ||
| 4260 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | ||
| 4261 | /* Shut up GCC warning in comparison with | ||
| 4262 | MOST_POSITIVE_FIXNUM below. */ | ||
| 4263 | EMACS_INT cod; | ||
| 4264 | |||
| 4265 | c = STRING_CHAR_ADVANCE (p); | ||
| 4266 | cod = code = font->driver->encode_char (font, c); | ||
| 4267 | if (cod > MOST_POSITIVE_FIXNUM || code == FONT_INVALID_CODE) | ||
| 4268 | break; | ||
| 4269 | LGLYPH_SET_FROM (g, i); | ||
| 4270 | LGLYPH_SET_TO (g, i); | ||
| 4271 | LGLYPH_SET_CHAR (g, c); | ||
| 4272 | LGLYPH_SET_CODE (g, code); | ||
| 4273 | } | ||
| 4274 | } | ||
| 4275 | else | ||
| 4276 | { | ||
| 4277 | int pos, pos_byte; | ||
| 4278 | 4210 | ||
| 4279 | if (! NILP (object)) | 4211 | DEFUN ("font-shape-gstring", Ffont_shape_gstring, Sfont_shape_gstring, 1, 1, 0, |
| 4280 | Fset_buffer (object); | 4212 | doc: /* Shape the glyph-string GSTRING. |
| 4281 | validate_region (&start, &end); | 4213 | Shaping means substituting glyphs and/or adjusting positions of glyphs |
| 4282 | if (XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring)) | 4214 | to get the correct visual image of character sequences set in the |
| 4283 | args_out_of_range (start, end); | 4215 | header of the glyph-string. |
| 4284 | len = XINT (end) - XINT (start); | ||
| 4285 | pos = XINT (start); | ||
| 4286 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 4287 | for (i = 0; i < len; i++) | ||
| 4288 | { | ||
| 4289 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | ||
| 4290 | /* Shut up GCC warning in comparison with | ||
| 4291 | MOST_POSITIVE_FIXNUM below. */ | ||
| 4292 | EMACS_INT cod; | ||
| 4293 | |||
| 4294 | FETCH_CHAR_ADVANCE (c, pos, pos_byte); | ||
| 4295 | cod = code = font->driver->encode_char (font, c); | ||
| 4296 | if (cod > MOST_POSITIVE_FIXNUM || code == FONT_INVALID_CODE) | ||
| 4297 | break; | ||
| 4298 | LGLYPH_SET_FROM (g, i); | ||
| 4299 | LGLYPH_SET_TO (g, i); | ||
| 4300 | LGLYPH_SET_CHAR (g, c); | ||
| 4301 | LGLYPH_SET_CODE (g, code); | ||
| 4302 | } | ||
| 4303 | } | ||
| 4304 | for (; i < LGSTRING_LENGTH (gstring); i++) | ||
| 4305 | LGSTRING_SET_GLYPH (gstring, i, Qnil); | ||
| 4306 | return Qnil; | ||
| 4307 | } | ||
| 4308 | 4216 | ||
| 4309 | DEFUN ("font-shape-text", Ffont_shape_text, Sfont_shape_text, 3, 4, 0, | 4217 | If the shaping was successful, the value is GSTRING itself or a newly |
| 4310 | doc: /* Shape text between FROM and TO by FONT-OBJECT. | 4218 | created glyph-string. Otherwise, the value is nil. */) |
| 4311 | If optional 4th argument STRING is non-nil, it is a string to shape, | 4219 | (gstring) |
| 4312 | and FROM and TO are indices to the string. | 4220 | Lisp_Object gstring; |
| 4313 | The value is the end position of the text that can be shaped by | ||
| 4314 | FONT-OBJECT. */) | ||
| 4315 | (from, to, font_object, string) | ||
| 4316 | Lisp_Object from, to, font_object, string; | ||
| 4317 | { | 4221 | { |
| 4318 | struct font *font; | 4222 | struct font *font; |
| 4319 | struct font_metrics metrics; | 4223 | Lisp_Object font_object, n, glyph; |
| 4320 | EMACS_INT start, end; | 4224 | int i; |
| 4321 | Lisp_Object gstring, n; | 4225 | |
| 4322 | int len, i; | 4226 | if (! composition_gstring_p (gstring)) |
| 4323 | 4227 | signal_error ("Invalid glyph-string: ", gstring); | |
| 4324 | if (! FONT_OBJECT_P (font_object)) | 4228 | if (! NILP (LGSTRING_ID (gstring))) |
| 4325 | return Qnil; | 4229 | return gstring; |
| 4230 | font_object = LGSTRING_FONT (gstring); | ||
| 4231 | CHECK_FONT_OBJECT (font_object); | ||
| 4326 | font = XFONT_OBJECT (font_object); | 4232 | font = XFONT_OBJECT (font_object); |
| 4327 | if (! font->driver->shape) | 4233 | if (! font->driver->shape) |
| 4328 | return Qnil; | 4234 | return Qnil; |
| 4329 | 4235 | ||
| 4330 | if (NILP (string)) | ||
| 4331 | { | ||
| 4332 | validate_region (&from, &to); | ||
| 4333 | start = XFASTINT (from); | ||
| 4334 | end = XFASTINT (to); | ||
| 4335 | modify_region (current_buffer, start, end, 0); | ||
| 4336 | } | ||
| 4337 | else | ||
| 4338 | { | ||
| 4339 | CHECK_STRING (string); | ||
| 4340 | start = XINT (from); | ||
| 4341 | end = XINT (to); | ||
| 4342 | if (start < 0 || start > end || end > SCHARS (string)) | ||
| 4343 | args_out_of_range_3 (string, from, to); | ||
| 4344 | } | ||
| 4345 | |||
| 4346 | len = end - start; | ||
| 4347 | gstring = Ffont_make_gstring (font_object, make_number (len)); | ||
| 4348 | Ffont_fill_gstring (gstring, font_object, from, to, string); | ||
| 4349 | |||
| 4350 | /* Try at most three times with larger gstring each time. */ | 4236 | /* Try at most three times with larger gstring each time. */ |
| 4351 | for (i = 0; i < 3; i++) | 4237 | for (i = 0; i < 3; i++) |
| 4352 | { | 4238 | { |
| 4353 | Lisp_Object args[2]; | ||
| 4354 | |||
| 4355 | n = font->driver->shape (gstring); | 4239 | n = font->driver->shape (gstring); |
| 4356 | if (INTEGERP (n)) | 4240 | if (INTEGERP (n)) |
| 4357 | break; | 4241 | break; |
| 4358 | args[0] = gstring; | 4242 | gstring = larger_vector (gstring, |
| 4359 | args[1] = Fmake_vector (make_number (len), Qnil); | 4243 | ASIZE (gstring) + LGSTRING_GLYPH_LEN (gstring), |
| 4360 | gstring = Fvconcat (2, args); | 4244 | Qnil); |
| 4361 | } | 4245 | } |
| 4362 | if (! INTEGERP (n) || XINT (n) == 0) | 4246 | if (i == 3 || XINT (n) == 0) |
| 4363 | return Qnil; | 4247 | return Qnil; |
| 4364 | len = XINT (n); | 4248 | |
| 4365 | 4249 | glyph = LGSTRING_GLYPH (gstring, 0); | |
| 4366 | for (i = 0; i < len;) | 4250 | for (i = 1; i < LGSTRING_GLYPH_LEN (gstring); i++) |
| 4367 | { | 4251 | { |
| 4368 | Lisp_Object gstr; | 4252 | Lisp_Object this = LGSTRING_GLYPH (gstring, i); |
| 4369 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | ||
| 4370 | EMACS_INT this_from = LGLYPH_FROM (g); | ||
| 4371 | EMACS_INT this_to = LGLYPH_TO (g) + 1; | ||
| 4372 | int j, k; | ||
| 4373 | int need_composition = 0; | ||
| 4374 | |||
| 4375 | metrics.lbearing = LGLYPH_LBEARING (g); | ||
| 4376 | metrics.rbearing = LGLYPH_RBEARING (g); | ||
| 4377 | metrics.ascent = LGLYPH_ASCENT (g); | ||
| 4378 | metrics.descent = LGLYPH_DESCENT (g); | ||
| 4379 | if (NILP (LGLYPH_ADJUSTMENT (g))) | ||
| 4380 | { | ||
| 4381 | metrics.width = LGLYPH_WIDTH (g); | ||
| 4382 | if (LGLYPH_CHAR (g) == 0 || metrics.width == 0) | ||
| 4383 | need_composition = 1; | ||
| 4384 | } | ||
| 4385 | else | ||
| 4386 | { | ||
| 4387 | metrics.width = LGLYPH_WADJUST (g); | ||
| 4388 | metrics.lbearing += LGLYPH_XOFF (g); | ||
| 4389 | metrics.rbearing += LGLYPH_XOFF (g); | ||
| 4390 | metrics.ascent -= LGLYPH_YOFF (g); | ||
| 4391 | metrics.descent += LGLYPH_YOFF (g); | ||
| 4392 | need_composition = 1; | ||
| 4393 | } | ||
| 4394 | for (j = i + 1; j < len; j++) | ||
| 4395 | { | ||
| 4396 | int x; | ||
| 4397 | |||
| 4398 | g = LGSTRING_GLYPH (gstring, j); | ||
| 4399 | if (this_from != LGLYPH_FROM (g)) | ||
| 4400 | break; | ||
| 4401 | need_composition = 1; | ||
| 4402 | x = metrics.width + LGLYPH_LBEARING (g) + LGLYPH_XOFF (g); | ||
| 4403 | if (metrics.lbearing > x) | ||
| 4404 | metrics.lbearing = x; | ||
| 4405 | x = metrics.width + LGLYPH_RBEARING (g) + LGLYPH_XOFF (g); | ||
| 4406 | if (metrics.rbearing < x) | ||
| 4407 | metrics.rbearing = x; | ||
| 4408 | x = LGLYPH_ASCENT (g) - LGLYPH_YOFF (g); | ||
| 4409 | if (metrics.ascent < x) | ||
| 4410 | metrics.ascent = x; | ||
| 4411 | x = LGLYPH_DESCENT (g) - LGLYPH_YOFF (g); | ||
| 4412 | if (metrics.descent < x) | ||
| 4413 | metrics.descent = x; | ||
| 4414 | if (NILP (LGLYPH_ADJUSTMENT (g))) | ||
| 4415 | metrics.width += LGLYPH_WIDTH (g); | ||
| 4416 | else | ||
| 4417 | metrics.width += LGLYPH_WADJUST (g); | ||
| 4418 | } | ||
| 4419 | 4253 | ||
| 4420 | if (need_composition) | 4254 | if (NILP (this)) |
| 4255 | break; | ||
| 4256 | if (NILP (LGLYPH_ADJUSTMENT (this))) | ||
| 4257 | glyph = this; | ||
| 4258 | else | ||
| 4421 | { | 4259 | { |
| 4422 | gstr = Ffont_make_gstring (font_object, make_number (j - i)); | 4260 | int from = LGLYPH_FROM (glyph); |
| 4423 | LGSTRING_SET_WIDTH (gstr, metrics.width); | 4261 | int to = LGLYPH_TO (glyph); |
| 4424 | LGSTRING_SET_LBEARING (gstr, metrics.lbearing); | ||
| 4425 | LGSTRING_SET_RBEARING (gstr, metrics.rbearing); | ||
| 4426 | LGSTRING_SET_ASCENT (gstr, metrics.ascent); | ||
| 4427 | LGSTRING_SET_DESCENT (gstr, metrics.descent); | ||
| 4428 | for (k = i; i < j; i++) | ||
| 4429 | { | ||
| 4430 | Lisp_Object g = LGSTRING_GLYPH (gstring, i); | ||
| 4431 | 4262 | ||
| 4432 | LGLYPH_SET_FROM (g, LGLYPH_FROM (g) - this_from); | 4263 | LGLYPH_SET_FROM (this, from); |
| 4433 | LGLYPH_SET_TO (g, LGLYPH_TO (g) - this_from); | 4264 | LGLYPH_SET_TO (this, to); |
| 4434 | LGSTRING_SET_GLYPH (gstr, i - k, LGSTRING_GLYPH (gstring, i)); | ||
| 4435 | } | ||
| 4436 | from = make_number (start + this_from); | ||
| 4437 | to = make_number (start + this_to); | ||
| 4438 | if (NILP (string)) | ||
| 4439 | Fcompose_region_internal (from, to, gstr, Qnil); | ||
| 4440 | else | ||
| 4441 | Fcompose_string_internal (string, from, to, gstr, Qnil); | ||
| 4442 | } | 4265 | } |
| 4443 | else | ||
| 4444 | i = j; | ||
| 4445 | } | 4266 | } |
| 4446 | 4267 | return composition_gstring_put_cache (gstring, XINT (n)); | |
| 4447 | return to; | ||
| 4448 | } | 4268 | } |
| 4449 | 4269 | ||
| 4450 | #if 0 | 4270 | #if 0 |
| @@ -4938,7 +4758,7 @@ font_add_log (action, arg, result) | |||
| 4938 | return; | 4758 | return; |
| 4939 | if (STRINGP (AREF (Vfont_log_deferred, 0))) | 4759 | if (STRINGP (AREF (Vfont_log_deferred, 0))) |
| 4940 | { | 4760 | { |
| 4941 | char *str = SDATA (AREF (Vfont_log_deferred, 0)); | 4761 | char *str = (char *) SDATA (AREF (Vfont_log_deferred, 0)); |
| 4942 | 4762 | ||
| 4943 | ASET (Vfont_log_deferred, 0, Qnil); | 4763 | ASET (Vfont_log_deferred, 0, Qnil); |
| 4944 | font_add_log (str, AREF (Vfont_log_deferred, 1), | 4764 | font_add_log (str, AREF (Vfont_log_deferred, 1), |
| @@ -5049,6 +4869,8 @@ syms_of_font () | |||
| 5049 | DEFSYM (Qunicode_bmp, "unicode-bmp"); | 4869 | DEFSYM (Qunicode_bmp, "unicode-bmp"); |
| 5050 | DEFSYM (Qunicode_sip, "unicode-sip"); | 4870 | DEFSYM (Qunicode_sip, "unicode-sip"); |
| 5051 | 4871 | ||
| 4872 | DEFSYM (QCf, "Cf"); | ||
| 4873 | |||
| 5052 | DEFSYM (QCotf, ":otf"); | 4874 | DEFSYM (QCotf, ":otf"); |
| 5053 | DEFSYM (QClang, ":lang"); | 4875 | DEFSYM (QClang, ":lang"); |
| 5054 | DEFSYM (QCscript, ":script"); | 4876 | DEFSYM (QCscript, ":script"); |
| @@ -5099,9 +4921,7 @@ syms_of_font () | |||
| 5099 | defsubr (&Sfind_font); | 4921 | defsubr (&Sfind_font); |
| 5100 | defsubr (&Sfont_xlfd_name); | 4922 | defsubr (&Sfont_xlfd_name); |
| 5101 | defsubr (&Sclear_font_cache); | 4923 | defsubr (&Sclear_font_cache); |
| 5102 | defsubr (&Sfont_make_gstring); | 4924 | defsubr (&Sfont_shape_gstring); |
| 5103 | defsubr (&Sfont_fill_gstring); | ||
| 5104 | defsubr (&Sfont_shape_text); | ||
| 5105 | #if 0 | 4925 | #if 0 |
| 5106 | defsubr (&Sfont_drive_otf); | 4926 | defsubr (&Sfont_drive_otf); |
| 5107 | defsubr (&Sfont_otf_alternates); | 4927 | defsubr (&Sfont_otf_alternates); |