diff options
| author | Kenichi Handa | 2008-07-09 00:30:18 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-07-09 00:30:18 +0000 |
| commit | 51c135107bd997cf3782a64dc94042eabe13c438 (patch) | |
| tree | 4eceb6c5dc3d9334f713271365d76c344911ccdd /src | |
| parent | 9cd7463bcdd03c28d6341c61d96e2fbf2c8299d7 (diff) | |
| download | emacs-51c135107bd997cf3782a64dc94042eabe13c438.tar.gz emacs-51c135107bd997cf3782a64dc94042eabe13c438.zip | |
(font_make_object): New arg entity and pixelsize.
(font_check_otf_features, font_check_otf): New functions.
(font_match_p): Check :lang, :script, and :otf properties.
(font_open_entity): Set the member vertical_centering of struct
font.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 187 |
1 files changed, 165 insertions, 22 deletions
diff --git a/src/font.c b/src/font.c index 9b537296eb1..295be75199a 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -189,15 +189,32 @@ font_make_entity () | |||
| 189 | return font_entity; | 189 | return font_entity; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | /* Create a font-object whose structure size is SIZE. If ENTITY is | ||
| 193 | not nil, copy properties from ENTITY to the font-object. If | ||
| 194 | PIXELSIZE is positive, set the `size' property to PIXELSIZE. */ | ||
| 192 | Lisp_Object | 195 | Lisp_Object |
| 193 | font_make_object (size) | 196 | font_make_object (size, entity, pixelsize) |
| 194 | int size; | 197 | int size; |
| 198 | Lisp_Object entity; | ||
| 199 | int pixelsize; | ||
| 195 | { | 200 | { |
| 196 | Lisp_Object font_object; | 201 | Lisp_Object font_object; |
| 197 | struct font *font | 202 | struct font *font |
| 198 | = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT); | 203 | = (struct font *) allocate_pseudovector (size, FONT_OBJECT_MAX, PVEC_FONT); |
| 204 | int i; | ||
| 205 | |||
| 199 | XSETFONT (font_object, font); | 206 | XSETFONT (font_object, font); |
| 200 | 207 | ||
| 208 | if (! NILP (entity)) | ||
| 209 | { | ||
| 210 | for (i = 1; i < FONT_SPEC_MAX; i++) | ||
| 211 | font->props[i] = AREF (entity, i); | ||
| 212 | if (! NILP (AREF (entity, FONT_EXTRA_INDEX))) | ||
| 213 | font->props[FONT_EXTRA_INDEX] | ||
| 214 | = Fcopy_sequence (AREF (entity, FONT_EXTRA_INDEX)); | ||
| 215 | } | ||
| 216 | if (size > 0) | ||
| 217 | font->props[FONT_SIZE_INDEX] = make_number (pixelsize); | ||
| 201 | return font_object; | 218 | return font_object; |
| 202 | } | 219 | } |
| 203 | 220 | ||
| @@ -2184,10 +2201,7 @@ static int sort_shift_bits[FONT_SIZE_INDEX + 1]; | |||
| 2184 | 2201 | ||
| 2185 | /* Score font-entity ENTITY against properties of font-spec SPEC_PROP. | 2202 | /* Score font-entity ENTITY against properties of font-spec SPEC_PROP. |
| 2186 | The return value indicates how different ENTITY is compared with | 2203 | The return value indicates how different ENTITY is compared with |
| 2187 | SPEC_PROP. | 2204 | SPEC_PROP. */ |
| 2188 | |||
| 2189 | ALTERNATE_FAMILIES, if non-nil, is a pre-calculated list of | ||
| 2190 | alternate family names for AREF (SPEC_PROP, FONT_FAMILY_INDEX). */ | ||
| 2191 | 2205 | ||
| 2192 | static unsigned | 2206 | static unsigned |
| 2193 | font_score (entity, spec_prop) | 2207 | font_score (entity, spec_prop) |
| @@ -2351,32 +2365,155 @@ font_update_sort_order (order) | |||
| 2351 | } | 2365 | } |
| 2352 | } | 2366 | } |
| 2353 | 2367 | ||
| 2368 | static int | ||
| 2369 | font_check_otf_features (script, langsys, features, table) | ||
| 2370 | Lisp_Object script, langsys, features, table; | ||
| 2371 | { | ||
| 2372 | Lisp_Object val; | ||
| 2373 | int negative; | ||
| 2354 | 2374 | ||
| 2355 | /* Check if ENTITY matches with the font specification SPEC. */ | 2375 | table = assq_no_quit (script, table); |
| 2376 | if (NILP (table)) | ||
| 2377 | return 0; | ||
| 2378 | table = XCDR (table); | ||
| 2379 | if (! NILP (langsys)) | ||
| 2380 | { | ||
| 2381 | table = assq_no_quit (langsys, table); | ||
| 2382 | if (NILP (table)) | ||
| 2383 | return 0; | ||
| 2384 | } | ||
| 2385 | else | ||
| 2386 | { | ||
| 2387 | val = assq_no_quit (Qnil, table); | ||
| 2388 | if (NILP (val)) | ||
| 2389 | table = XCAR (table); | ||
| 2390 | else | ||
| 2391 | table = val; | ||
| 2392 | } | ||
| 2393 | table = XCDR (table); | ||
| 2394 | for (negative = 0; CONSP (features); features = XCDR (features)) | ||
| 2395 | { | ||
| 2396 | if (NILP (XCAR (features))) | ||
| 2397 | negative = 1; | ||
| 2398 | if (NILP (Fmemq (XCAR (features), table)) != negative) | ||
| 2399 | return 0; | ||
| 2400 | } | ||
| 2401 | return 1; | ||
| 2402 | } | ||
| 2403 | |||
| 2404 | /* Check if OTF_CAPABILITY satisfies SPEC (otf-spec). */ | ||
| 2405 | |||
| 2406 | static int | ||
| 2407 | font_check_otf (spec, otf_capability) | ||
| 2408 | { | ||
| 2409 | Lisp_Object script, langsys = Qnil, gsub = Qnil, gpos = Qnil; | ||
| 2410 | |||
| 2411 | script = XCAR (spec); | ||
| 2412 | spec = XCDR (spec); | ||
| 2413 | if (! NILP (spec)) | ||
| 2414 | { | ||
| 2415 | langsys = XCAR (spec); | ||
| 2416 | spec = XCDR (spec); | ||
| 2417 | if (! NILP (spec)) | ||
| 2418 | { | ||
| 2419 | gsub = XCAR (spec); | ||
| 2420 | spec = XCDR (spec); | ||
| 2421 | if (! NILP (spec)) | ||
| 2422 | gpos = XCAR (spec); | ||
| 2423 | } | ||
| 2424 | } | ||
| 2425 | |||
| 2426 | if (! NILP (gsub) && ! font_check_otf_features (script, langsys, gsub, | ||
| 2427 | XCAR (otf_capability))) | ||
| 2428 | return 0; | ||
| 2429 | if (! NILP (gpos) && ! font_check_otf_features (script, langsys, gpos, | ||
| 2430 | XCDR (otf_capability))) | ||
| 2431 | return 0; | ||
| 2432 | return 1; | ||
| 2433 | } | ||
| 2434 | |||
| 2435 | |||
| 2436 | |||
| 2437 | /* Check if FONT (font-entity or font-object) matches with the font | ||
| 2438 | specification SPEC. */ | ||
| 2356 | 2439 | ||
| 2357 | int | 2440 | int |
| 2358 | font_match_p (spec, entity) | 2441 | font_match_p (spec, font) |
| 2359 | Lisp_Object spec, entity; | 2442 | Lisp_Object spec, font; |
| 2360 | { | 2443 | { |
| 2361 | Lisp_Object prefer_prop[FONT_SPEC_MAX]; | 2444 | Lisp_Object prop[FONT_SPEC_MAX], *props; |
| 2362 | Lisp_Object alternate_families = Qnil; | 2445 | Lisp_Object extra, font_extra; |
| 2363 | int i; | 2446 | int i; |
| 2364 | 2447 | ||
| 2365 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_SIZE_INDEX; i++) | 2448 | for (i = FONT_FOUNDRY_INDEX; i <= FONT_REGISTRY_INDEX; i++) |
| 2366 | prefer_prop[i] = AREF (spec, i); | 2449 | if (! NILP (AREF (spec, i)) |
| 2367 | if (FLOATP (prefer_prop[FONT_SIZE_INDEX])) | 2450 | && ! NILP (AREF (font, i)) |
| 2368 | prefer_prop[FONT_SIZE_INDEX] | 2451 | && ! EQ (AREF (spec, i), AREF (font, i))) |
| 2369 | = make_number (font_pixel_size (XFRAME (selected_frame), spec)); | 2452 | return 0; |
| 2370 | if (! NILP (prefer_prop[FONT_FAMILY_INDEX])) | 2453 | props = XFONT_SPEC (spec)->props; |
| 2454 | if (FLOATP (props[FONT_SIZE_INDEX])) | ||
| 2371 | { | 2455 | { |
| 2372 | alternate_families | 2456 | for (i = FONT_FOUNDRY_INDEX; i < FONT_SIZE_INDEX; i++) |
| 2373 | = Fassoc_string (prefer_prop[FONT_FAMILY_INDEX], | 2457 | prop[i] = AREF (spec, i); |
| 2374 | Vface_alternative_font_family_alist, Qt); | 2458 | prop[FONT_SIZE_INDEX] |
| 2375 | if (CONSP (alternate_families)) | 2459 | = make_number (font_pixel_size (XFRAME (selected_frame), spec)); |
| 2376 | alternate_families = XCDR (alternate_families); | 2460 | props = prop; |
| 2377 | } | 2461 | } |
| 2378 | 2462 | ||
| 2379 | return (font_score (entity, prefer_prop) == 0); | 2463 | if (font_score (font, props) > 0) |
| 2464 | return 0; | ||
| 2465 | extra = AREF (spec, FONT_EXTRA_INDEX); | ||
| 2466 | font_extra = AREF (font, FONT_EXTRA_INDEX); | ||
| 2467 | for (; CONSP (extra); extra = XCDR (extra)) | ||
| 2468 | { | ||
| 2469 | Lisp_Object key = XCAR (XCAR (extra)); | ||
| 2470 | Lisp_Object val = XCDR (XCAR (extra)), val2; | ||
| 2471 | |||
| 2472 | if (EQ (key, QClang)) | ||
| 2473 | { | ||
| 2474 | val2 = assq_no_quit (key, font_extra); | ||
| 2475 | if (NILP (val2)) | ||
| 2476 | return 0; | ||
| 2477 | val2 = XCDR (val2); | ||
| 2478 | if (CONSP (val)) | ||
| 2479 | { | ||
| 2480 | if (! CONSP (val2)) | ||
| 2481 | return 0; | ||
| 2482 | while (CONSP (val)) | ||
| 2483 | if (NILP (Fmemq (val, val2))) | ||
| 2484 | return 0; | ||
| 2485 | } | ||
| 2486 | else | ||
| 2487 | if (CONSP (val2) | ||
| 2488 | ? NILP (Fmemq (val, XCDR (val2))) | ||
| 2489 | : ! EQ (val, val2)) | ||
| 2490 | return 0; | ||
| 2491 | } | ||
| 2492 | else if (EQ (key, QCscript)) | ||
| 2493 | { | ||
| 2494 | val2 = assq_no_quit (val, Vscript_representative_chars); | ||
| 2495 | if (! NILP (val2)) | ||
| 2496 | for (val2 = XCDR (val2); CONSP (val2); val2 = XCDR (val2)) | ||
| 2497 | if (font_encode_char (font, XINT (XCAR (val2))) | ||
| 2498 | == FONT_INVALID_CODE) | ||
| 2499 | return 0; | ||
| 2500 | } | ||
| 2501 | else if (EQ (key, QCotf)) | ||
| 2502 | { | ||
| 2503 | struct font *fontp; | ||
| 2504 | |||
| 2505 | if (! FONT_OBJECT_P (font)) | ||
| 2506 | return 0; | ||
| 2507 | fontp = XFONT_OBJECT (font); | ||
| 2508 | if (! fontp->driver->otf_capability) | ||
| 2509 | return 0; | ||
| 2510 | val2 = fontp->driver->otf_capability (fontp); | ||
| 2511 | if (NILP (val2) || ! font_check_otf (val, val2)) | ||
| 2512 | return 0; | ||
| 2513 | } | ||
| 2514 | } | ||
| 2515 | |||
| 2516 | return 1; | ||
| 2380 | } | 2517 | } |
| 2381 | 2518 | ||
| 2382 | 2519 | ||
| @@ -2711,6 +2848,12 @@ font_open_entity (f, entity, pixel_size) | |||
| 2711 | return Qnil; | 2848 | return Qnil; |
| 2712 | 2849 | ||
| 2713 | font_object = driver_list->driver->open (f, entity, pixel_size); | 2850 | font_object = driver_list->driver->open (f, entity, pixel_size); |
| 2851 | if (STRINGP (AREF (font_object, FONT_FULLNAME_INDEX)) | ||
| 2852 | && STRINGP (Vvertical_centering_font_regexp)) | ||
| 2853 | XFONT_OBJECT (font_object)->vertical_centering | ||
| 2854 | = (fast_string_match_ignore_case | ||
| 2855 | (Vvertical_centering_font_regexp, | ||
| 2856 | (AREF (font_object, FONT_FULLNAME_INDEX))) >= 0); | ||
| 2714 | font_add_log ("open", entity, font_object); | 2857 | font_add_log ("open", entity, font_object); |
| 2715 | if (NILP (font_object)) | 2858 | if (NILP (font_object)) |
| 2716 | return Qnil; | 2859 | return Qnil; |