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