comparison src/font.c @ 102415:ccbe1c8ab377

(font_select_entity): New function. (font_find_for_lface): Use font_select_entity to select a font.
author Kenichi Handa <handa@m17n.org>
date Thu, 05 Mar 2009 12:25:07 +0000
parents b666efc8e847
children d25713758c3e
comparison
equal deleted inserted replaced
102414:5988cd89cf0b 102415:ccbe1c8ab377
3159 } 3159 }
3160 } 3160 }
3161 } 3161 }
3162 3162
3163 3163
3164 /* Selecte a font from ENTITIES that supports C and matches best with
3165 ATTRS and PIXEL_SIZE. */
3166
3167 static Lisp_Object
3168 font_select_entity (frame, entities, attrs, pixel_size, c)
3169 Lisp_Object frame, entities, *attrs;
3170 int pixel_size, c;
3171 {
3172 Lisp_Object font_entity;
3173 Lisp_Object prefer;
3174 Lisp_Object props[FONT_REGISTRY_INDEX + 1] ;
3175 int result, i;
3176 FRAME_PTR f = XFRAME (frame);
3177
3178 if (ASIZE (entities) == 1)
3179 {
3180 font_entity = AREF (entities, 0);
3181 if (c < 0
3182 || (result = font_has_char (f, font_entity, c)) > 0)
3183 return font_entity;
3184 return Qnil;
3185 }
3186
3187 /* Sort fonts by properties specified in ATTRS. */
3188 prefer = scratch_font_prefer;
3189
3190 for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
3191 ASET (prefer, i, Qnil);
3192 if (FONTP (attrs[LFACE_FONT_INDEX]))
3193 {
3194 Lisp_Object face_font = attrs[LFACE_FONT_INDEX];
3195
3196 for (i = FONT_WEIGHT_INDEX; i <= FONT_SIZE_INDEX; i++)
3197 ASET (prefer, i, AREF (face_font, i));
3198 }
3199 if (NILP (AREF (prefer, FONT_WEIGHT_INDEX)))
3200 FONT_SET_STYLE (prefer, FONT_WEIGHT_INDEX, attrs[LFACE_WEIGHT_INDEX]);
3201 if (NILP (AREF (prefer, FONT_SLANT_INDEX)))
3202 FONT_SET_STYLE (prefer, FONT_SLANT_INDEX, attrs[LFACE_SLANT_INDEX]);
3203 if (NILP (AREF (prefer, FONT_WIDTH_INDEX)))
3204 FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]);
3205 ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size));
3206 entities = font_sort_entites (entities, prefer, frame, c < 0);
3207
3208 if (c < 0)
3209 return entities;
3210
3211 for (i = 0; i < ASIZE (entities); i++)
3212 {
3213 int j;
3214
3215 font_entity = AREF (entities, i);
3216 if (i > 0)
3217 {
3218 for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++)
3219 if (! EQ (AREF (font_entity, j), props[j]))
3220 break;
3221 if (j > FONT_REGISTRY_INDEX)
3222 continue;
3223 }
3224 for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++)
3225 props[j] = AREF (font_entity, j);
3226 result = font_has_char (f, font_entity, c);
3227 if (result > 0)
3228 return font_entity;
3229 }
3230 return Qnil;
3231 }
3232
3164 /* Return a font-entity satisfying SPEC and best matching with face's 3233 /* Return a font-entity satisfying SPEC and best matching with face's
3165 font related attributes in ATTRS. C, if not negative, is a 3234 font related attributes in ATTRS. C, if not negative, is a
3166 character that the entity must support. */ 3235 character that the entity must support. */
3167 3236
3168 Lisp_Object 3237 Lisp_Object
3306 for (l = 0; SYMBOLP (adstyle[l]); l++) 3375 for (l = 0; SYMBOLP (adstyle[l]); l++)
3307 { 3376 {
3308 ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]); 3377 ASET (work, FONT_ADSTYLE_INDEX, adstyle[l]);
3309 entities = font_list_entities (frame, work); 3378 entities = font_list_entities (frame, work);
3310 if (ASIZE (entities) > 0) 3379 if (ASIZE (entities) > 0)
3311 goto found; 3380 {
3381 val = font_select_entity (frame, entities,
3382 attrs, pixel_size, c);
3383 if (! NILP (val))
3384 return val;
3385 }
3312 } 3386 }
3313 } 3387 }
3314 } 3388 }
3315 }
3316 return Qnil;
3317 found:
3318 if (ASIZE (entities) == 1)
3319 {
3320 if (c < 0)
3321 return AREF (entities, 0);
3322 }
3323 else
3324 {
3325 /* Sort fonts by properties specified in LFACE. */
3326 Lisp_Object prefer = scratch_font_prefer;
3327
3328 for (i = 0; i < FONT_EXTRA_INDEX; i++)
3329 ASET (prefer, i, AREF (work, i));
3330 if (FONTP (attrs[LFACE_FONT_INDEX]))
3331 {
3332 Lisp_Object face_font = attrs[LFACE_FONT_INDEX];
3333
3334 for (i = 0; i < FONT_EXTRA_INDEX; i++)
3335 if (NILP (AREF (prefer, i)))
3336 ASET (prefer, i, AREF (face_font, i));
3337 }
3338 if (NILP (AREF (prefer, FONT_WEIGHT_INDEX)))
3339 FONT_SET_STYLE (prefer, FONT_WEIGHT_INDEX, attrs[LFACE_WEIGHT_INDEX]);
3340 if (NILP (AREF (prefer, FONT_SLANT_INDEX)))
3341 FONT_SET_STYLE (prefer, FONT_SLANT_INDEX, attrs[LFACE_SLANT_INDEX]);
3342 if (NILP (AREF (prefer, FONT_WIDTH_INDEX)))
3343 FONT_SET_STYLE (prefer, FONT_WIDTH_INDEX, attrs[LFACE_SWIDTH_INDEX]);
3344 ASET (prefer, FONT_SIZE_INDEX, make_number (pixel_size));
3345 entities = font_sort_entites (entities, prefer, frame, c < 0);
3346 }
3347 if (c < 0)
3348 return entities;
3349
3350 for (i = 0; i < ASIZE (entities); i++)
3351 {
3352 int j;
3353
3354 val = AREF (entities, i);
3355 if (i > 0)
3356 {
3357 for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++)
3358 if (! EQ (AREF (val, j), props[j]))
3359 break;
3360 if (j > FONT_REGISTRY_INDEX)
3361 continue;
3362 }
3363 for (j = FONT_FOUNDRY_INDEX; j <= FONT_REGISTRY_INDEX; j++)
3364 props[j] = AREF (val, j);
3365 result = font_has_char (f, val, c);
3366 if (result > 0)
3367 return val;
3368 if (result == 0)
3369 return Qnil;
3370 val = font_open_for_lface (f, val, attrs, spec);
3371 if (NILP (val))
3372 continue;
3373 result = font_has_char (f, val, c);
3374 font_close_object (f, val);
3375 if (result > 0)
3376 return AREF (entities, i);
3377 } 3389 }
3378 return Qnil; 3390 return Qnil;
3379 } 3391 }
3380 3392
3381 3393