Mercurial > emacs
comparison src/font.c @ 97822:f44734c99365
(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.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Fri, 29 Aug 2008 07:54:44 +0000 |
parents | ec399baa25dd |
children | fa1023e4960c |
comparison
equal
deleted
inserted
replaced
97821:9d12856db185 | 97822:f44734c99365 |
---|---|
64 #ifdef HAVE_NS | 64 #ifdef HAVE_NS |
65 #define DEFAULT_ENCODING Qiso10646_1 | 65 #define DEFAULT_ENCODING Qiso10646_1 |
66 #else | 66 #else |
67 #define DEFAULT_ENCODING Qiso8859_1 | 67 #define DEFAULT_ENCODING Qiso8859_1 |
68 #endif | 68 #endif |
69 | |
70 /* Unicode category `Cf'. */ | |
71 static Lisp_Object QCf; | |
69 | 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; |
73 | 76 |
1891 if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT))) | 1894 if (!NILP (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT))) |
1892 CHECK_NUMBER (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)); | 1895 CHECK_NUMBER (LGSTRING_SLOT (gstring, LGSTRING_IX_ASCENT)); |
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); |
1900 if (ASIZE (val) < LGSTRING_GLYPH_SIZE) | 1903 if (ASIZE (val) < LGSTRING_GLYPH_SIZE) |
1901 goto err; | 1904 goto err; |
2155 } | 2158 } |
2156 return val; | 2159 return val; |
2157 } | 2160 } |
2158 #endif /* HAVE_LIBOTF */ | 2161 #endif /* HAVE_LIBOTF */ |
2159 #endif /* 0 */ | 2162 #endif /* 0 */ |
2160 | |
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 | 2163 |
2189 | 2164 |
2190 /* Font sorting */ | 2165 /* Font sorting */ |
2191 | 2166 |
2192 static unsigned font_score P_ ((Lisp_Object, Lisp_Object *)); | 2167 static unsigned font_score P_ ((Lisp_Object, Lisp_Object *)); |
3146 foundry[0] = AREF (work, FONT_FOUNDRY_INDEX); | 3121 foundry[0] = AREF (work, FONT_FOUNDRY_INDEX); |
3147 if (! NILP (foundry[0])) | 3122 if (! NILP (foundry[0])) |
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 } |
3156 else | 3131 else |
3157 foundry[0] = Qnil, foundry[1] = null_vector; | 3132 foundry[0] = Qnil, foundry[1] = null_vector; |
3176 adstyle[0] = Qnil, adstyle[1] = null_vector; | 3151 adstyle[0] = Qnil, adstyle[1] = null_vector; |
3177 | 3152 |
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); |
3186 family[0] = Qnil; | 3163 family[0] = Qnil; |
3187 family[1] = null_vector; /* terminator. */ | 3164 family[1] = null_vector; /* terminator. */ |
3665 XSETFONT (font_object, face->font); | 3642 XSETFONT (font_object, face->font); |
3666 return font_object; | 3643 return font_object; |
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 |
3674 | 3651 the face selected for the character at POS. If STRING is not nil, |
3675 The return value is the position of the character that is displayed | 3652 it is the string to check instead of the current buffer. In that |
3676 by the differnt font than that of the character as POS. */ | 3653 case, FACE must be not NULL. |
3677 | 3654 |
3678 EMACS_INT | 3655 The return value is the font-object for the character at POS. |
3679 font_range (pos, limit, face, f, string) | 3656 *LIMIT is set to the position where that font can't be used. |
3680 EMACS_INT pos, limit; | 3657 |
3658 It is assured that the current buffer (or STRING) is multibyte. */ | |
3659 | |
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; | 3690 { |
3705 | 3691 Lisp_Object category; |
3706 while (pos < limit) | |
3707 { | |
3708 int face_id; | |
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); | 3698 { |
3716 if (first) | 3699 font_object = font_for_char (face, c, pos - 1, string); |
3717 { | 3700 if (NILP (font_object)) |
3718 font = face->font; | 3701 return Qnil; |
3719 first = 0; | |
3720 continue; | 3702 continue; |
3721 } | 3703 } |
3722 else if (font != face->font) | 3704 |
3723 { | 3705 category = CHAR_TABLE_REF (Vunicode_category_table, c); |
3724 pos--; | 3706 if (! EQ (category, QCf) |
3725 break; | 3707 && font_encode_char (font_object, c) == FONT_INVALID_CODE) |
3726 } | 3708 { |
3727 } | 3709 Lisp_Object f = font_for_char (face, c, pos - 1, string); |
3728 return pos; | 3710 EMACS_INT i, i_byte; |
3729 } | 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; | |
3735 } | |
3736 } | |
3737 return font_object; | |
3738 } | |
3739 #endif | |
3730 | 3740 |
3731 | 3741 |
3732 /* Lisp API */ | 3742 /* Lisp API */ |
3733 | 3743 |
3734 DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0, | 3744 DEFUN ("fontp", Ffontp, Sfontp, 1, 2, 0, |
4177 } | 4187 } |
4178 | 4188 |
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. | 4196 { |
4187 | 4197 struct font *font = XFONT_OBJECT (font_object); |
4188 G-string is sequence of glyphs of a specific font, | 4198 unsigned code = font->driver->encode_char (font, LGLYPH_CHAR (glyph)); |
4189 and is a vector of this form: | 4199 struct font_metrics metrics; |
4190 [ HEADER GLYPH ... ] | 4200 |
4191 HEADER is a vector of this form: | 4201 LGLYPH_SET_CODE (glyph, code); |
4192 [FONT-OBJECT WIDTH LBEARING RBEARING ASCENT DESCENT] | 4202 font->driver->text_extents (font, &code, 1, &metrics); |
4193 where | 4203 LGLYPH_SET_LBEARING (glyph, metrics.lbearing); |
4194 FONT-OBJECT is a font-object for all glyphs in the g-string, | 4204 LGLYPH_SET_RBEARING (glyph, metrics.rbearing); |
4195 WIDTH thru DESCENT are the metrics (in pixels) of the whole G-string. | 4205 LGLYPH_SET_WIDTH (glyph, metrics.width); |
4196 GLYPH is a vector of this form: | 4206 LGLYPH_SET_ASCENT (glyph, metrics.ascent); |
4197 [ FROM-IDX TO-IDX C CODE WIDTH LBEARING RBEARING ASCENT DESCENT | 4207 LGLYPH_SET_DESCENT (glyph, metrics.descent); |
4198 [ [X-OFF Y-OFF WADJUST] | nil] ] | 4208 } |
4199 where | 4209 |
4200 FROM-IDX and TO-IDX are used internally and should not be touched. | 4210 |
4201 C is the character of the glyph. | 4211 DEFUN ("font-shape-gstring", Ffont_shape_gstring, Sfont_shape_gstring, 1, 1, 0, |
4202 CODE is the glyph-code of C in FONT-OBJECT. | 4212 doc: /* Shape the glyph-string GSTRING. |
4203 WIDTH thru DESCENT are the metrics (in pixels) of the glyph. | 4213 Shaping means substituting glyphs and/or adjusting positions of glyphs |
4204 X-OFF and Y-OFF are offests to the base position for the glyph. | 4214 to get the correct visual image of character sequences set in the |
4205 WADJUST is the adjustment to the normal width of the glyph. */) | 4215 header of the glyph-string. |
4206 (font_object, num) | 4216 |
4207 Lisp_Object font_object, num; | 4217 If the shaping was successful, the value is GSTRING itself or a newly |
4208 { | 4218 created glyph-string. Otherwise, the value is nil. */) |
4209 Lisp_Object gstring, g; | 4219 (gstring) |
4210 int len; | 4220 Lisp_Object gstring; |
4221 { | |
4222 struct font *font; | |
4223 Lisp_Object font_object, n, glyph; | |
4211 int i; | 4224 int i; |
4212 | 4225 |
4213 if (! NILP (font_object)) | 4226 if (! composition_gstring_p (gstring)) |
4214 CHECK_FONT_OBJECT (font_object); | 4227 signal_error ("Invalid glyph-string: ", gstring); |
4215 CHECK_NATNUM (num); | 4228 if (! NILP (LGSTRING_ID (gstring))) |
4216 | 4229 return gstring; |
4217 len = XINT (num) + 1; | 4230 font_object = LGSTRING_FONT (gstring); |
4218 gstring = Fmake_vector (make_number (len), Qnil); | 4231 CHECK_FONT_OBJECT (font_object); |
4219 g = Fmake_vector (make_number (6), Qnil); | |
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 } | |
4226 | |
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 | |
4279 if (! NILP (object)) | |
4280 Fset_buffer (object); | |
4281 validate_region (&start, &end); | |
4282 if (XINT (end) - XINT (start) > LGSTRING_LENGTH (gstring)) | |
4283 args_out_of_range (start, end); | |
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 | |
4309 DEFUN ("font-shape-text", Ffont_shape_text, Sfont_shape_text, 3, 4, 0, | |
4310 doc: /* Shape text between FROM and TO by FONT-OBJECT. | |
4311 If optional 4th argument STRING is non-nil, it is a string to shape, | |
4312 and FROM and TO are indices to the string. | |
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 { | |
4318 struct font *font; | |
4319 struct font_metrics metrics; | |
4320 EMACS_INT start, end; | |
4321 Lisp_Object gstring, n; | |
4322 int len, i; | |
4323 | |
4324 if (! FONT_OBJECT_P (font_object)) | |
4325 return Qnil; | |
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); | 4253 |
4370 EMACS_INT this_from = LGLYPH_FROM (g); | 4254 if (NILP (this)) |
4371 EMACS_INT this_to = LGLYPH_TO (g) + 1; | 4255 break; |
4372 int j, k; | 4256 if (NILP (LGLYPH_ADJUSTMENT (this))) |
4373 int need_composition = 0; | 4257 glyph = this; |
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 | 4258 else |
4386 { | 4259 { |
4387 metrics.width = LGLYPH_WADJUST (g); | 4260 int from = LGLYPH_FROM (glyph); |
4388 metrics.lbearing += LGLYPH_XOFF (g); | 4261 int to = LGLYPH_TO (glyph); |
4389 metrics.rbearing += LGLYPH_XOFF (g); | 4262 |
4390 metrics.ascent -= LGLYPH_YOFF (g); | 4263 LGLYPH_SET_FROM (this, from); |
4391 metrics.descent += LGLYPH_YOFF (g); | 4264 LGLYPH_SET_TO (this, to); |
4392 need_composition = 1; | 4265 } |
4393 } | 4266 } |
4394 for (j = i + 1; j < len; j++) | 4267 return composition_gstring_put_cache (gstring, XINT (n)); |
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 | |
4420 if (need_composition) | |
4421 { | |
4422 gstr = Ffont_make_gstring (font_object, make_number (j - i)); | |
4423 LGSTRING_SET_WIDTH (gstr, metrics.width); | |
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 | |
4432 LGLYPH_SET_FROM (g, LGLYPH_FROM (g) - this_from); | |
4433 LGLYPH_SET_TO (g, LGLYPH_TO (g) - this_from); | |
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 } | |
4443 else | |
4444 i = j; | |
4445 } | |
4446 | |
4447 return to; | |
4448 } | 4268 } |
4449 | 4269 |
4450 #if 0 | 4270 #if 0 |
4451 | 4271 |
4452 DEFUN ("font-drive-otf", Ffont_drive_otf, Sfont_drive_otf, 6, 6, 0, | 4272 DEFUN ("font-drive-otf", Ffont_drive_otf, Sfont_drive_otf, 6, 6, 0, |
4936 } | 4756 } |
4937 if (EQ (Vfont_log, Qt)) | 4757 if (EQ (Vfont_log, Qt)) |
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), |
4945 AREF (Vfont_log_deferred, 2)); | 4765 AREF (Vfont_log_deferred, 2)); |
4946 } | 4766 } |
5046 DEFSYM (Qascii_0, "ascii-0"); | 4866 DEFSYM (Qascii_0, "ascii-0"); |
5047 DEFSYM (Qiso8859_1, "iso8859-1"); | 4867 DEFSYM (Qiso8859_1, "iso8859-1"); |
5048 DEFSYM (Qiso10646_1, "iso10646-1"); | 4868 DEFSYM (Qiso10646_1, "iso10646-1"); |
5049 DEFSYM (Qunicode_bmp, "unicode-bmp"); | 4869 DEFSYM (Qunicode_bmp, "unicode-bmp"); |
5050 DEFSYM (Qunicode_sip, "unicode-sip"); | 4870 DEFSYM (Qunicode_sip, "unicode-sip"); |
4871 | |
4872 DEFSYM (QCf, "Cf"); | |
5051 | 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"); |
5055 DEFSYM (QCantialias, ":antialias"); | 4877 DEFSYM (QCantialias, ":antialias"); |
5097 defsubr (&Slist_fonts); | 4919 defsubr (&Slist_fonts); |
5098 defsubr (&Sfont_family_list); | 4920 defsubr (&Sfont_family_list); |
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); |
5108 #endif /* 0 */ | 4928 #endif /* 0 */ |
5109 | 4929 |