aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2006-08-01 01:28:43 +0000
committerKenichi Handa2006-08-01 01:28:43 +0000
commite950d6f12fc0171a0b9b464bec1a9b6ab54c01a1 (patch)
treeb1f10cee7ceb9ac170ce0d0fb1f1c1e13e825712 /src
parent8fb9e6757ed669f207f203b21ee0aa94715797d0 (diff)
downloademacs-e950d6f12fc0171a0b9b464bec1a9b6ab54c01a1.tar.gz
emacs-e950d6f12fc0171a0b9b464bec1a9b6ab54c01a1.zip
(font_parse_fcname): Don't change :name property of FONT.
(font_parse_name): Likewise. (LGSTRING_HEADER_SIZE, LGSTRING_GLYPH_SIZE, check_gstring): Define them unconditionally. (font_matching_entity): New function. (font_open_by_name): Try font_matching_entity if exact match is not found. (font_update_drivers): Delete the arg FONT. Return a list of actually used backends. Don't free faces, font caches here. Don't store data in frame parameters. Don't call x_set_font. (Ffont_spec): Store :name property as is. (Ffont_get): Check HAVE_LIBOTF before calling font_otf_capability. (Ffont_otf_gsub): Call font->driver->otf_gsub instead of font_otf_gsub. (Ffont_otf_gpos): Call font->driver->otf_gpos instead of font_otf_gpos. (Ffont_otf_alternates): Check if the driver has otf_gsub function. Call font->driver->otf_gsub instead of font_otf_gsub.
Diffstat (limited to 'src')
-rw-r--r--src/font.c283
1 files changed, 154 insertions, 129 deletions
diff --git a/src/font.c b/src/font.c
index d6f1b642429..b5d814b1dc6 100644
--- a/src/font.c
+++ b/src/font.c
@@ -1188,8 +1188,6 @@ font_parse_fcname (name, font)
1188 } 1188 }
1189 else 1189 else
1190 { 1190 {
1191 char *pbeg = p0;
1192
1193 if (memcmp (p0 + 1, "pixelsize=", 10) == 0) 1191 if (memcmp (p0 + 1, "pixelsize=", 10) == 0)
1194 prop = FONT_SIZE_INDEX; 1192 prop = FONT_SIZE_INDEX;
1195 else 1193 else
@@ -1206,22 +1204,13 @@ font_parse_fcname (name, font)
1206 { 1204 {
1207 ASET (font, prop, val); 1205 ASET (font, prop, val);
1208 } 1206 }
1209 else if (prop > 0)
1210 font_put_extra (font, key, val);
1211 else 1207 else
1212 { 1208 font_put_extra (font, key, val);
1213 /* Unknown attribute, keep it in name. */
1214 bcopy (pbeg, copy, p1 - pbeg);
1215 copy += p1 - pbeg;
1216 }
1217 } 1209 }
1218 } 1210 }
1219 p0 = p1; 1211 p0 = p1;
1220 } 1212 }
1221 1213
1222 if (name < copy)
1223 font_put_extra (font, QCname, make_unibyte_string (name, copy - name));
1224
1225 return 0; 1214 return 0;
1226} 1215}
1227 1216
@@ -1363,13 +1352,7 @@ font_parse_name (name, font)
1363 Lisp_Object font; 1352 Lisp_Object font;
1364{ 1353{
1365 if (name[0] == '-' || index (name, '*')) 1354 if (name[0] == '-' || index (name, '*'))
1366 { 1355 return font_parse_xlfd (name, font);
1367 if (font_parse_xlfd (name, font) == 0)
1368 return 0;
1369 font_put_extra (font, QCname, make_unibyte_string (name, strlen (name)));
1370 return -1;
1371 }
1372 font_put_extra (font, QCname, make_unibyte_string (name, strlen (name)));
1373 return font_parse_fcname (name, font); 1356 return font_parse_fcname (name, font);
1374} 1357}
1375 1358
@@ -1434,6 +1417,64 @@ font_lispy_object (font)
1434 return XCAR (objlist); 1417 return XCAR (objlist);
1435} 1418}
1436 1419
1420#define LGSTRING_HEADER_SIZE 6
1421#define LGSTRING_GLYPH_SIZE 8
1422
1423static int
1424check_gstring (gstring)
1425 Lisp_Object gstring;
1426{
1427 Lisp_Object val;
1428 int i, j;
1429
1430 CHECK_VECTOR (gstring);
1431 val = AREF (gstring, 0);
1432 CHECK_VECTOR (val);
1433 if (ASIZE (val) < LGSTRING_HEADER_SIZE)
1434 goto err;
1435 CHECK_FONT_OBJECT (LGSTRING_FONT (gstring));
1436 if (! NILP (LGSTRING_LBEARING (gstring)))
1437 CHECK_NUMBER (LGSTRING_LBEARING (gstring));
1438 if (! NILP (LGSTRING_RBEARING (gstring)))
1439 CHECK_NUMBER (LGSTRING_RBEARING (gstring));
1440 if (! NILP (LGSTRING_WIDTH (gstring)))
1441 CHECK_NATNUM (LGSTRING_WIDTH (gstring));
1442 if (! NILP (LGSTRING_ASCENT (gstring)))
1443 CHECK_NUMBER (LGSTRING_ASCENT (gstring));
1444 if (! NILP (LGSTRING_DESCENT (gstring)))
1445 CHECK_NUMBER (LGSTRING_DESCENT(gstring));
1446
1447 for (i = 0; i < LGSTRING_LENGTH (gstring); i++)
1448 {
1449 val = LGSTRING_GLYPH (gstring, i);
1450 CHECK_VECTOR (val);
1451 if (ASIZE (val) < LGSTRING_GLYPH_SIZE)
1452 goto err;
1453 if (NILP (LGLYPH_CHAR (val)))
1454 break;
1455 CHECK_NATNUM (LGLYPH_FROM (val));
1456 CHECK_NATNUM (LGLYPH_TO (val));
1457 CHECK_CHARACTER (LGLYPH_CHAR (val));
1458 if (! NILP (LGLYPH_CODE (val)))
1459 CHECK_NATNUM (LGLYPH_CODE (val));
1460 if (! NILP (LGLYPH_WIDTH (val)))
1461 CHECK_NATNUM (LGLYPH_WIDTH (val));
1462 if (! NILP (LGLYPH_ADJUSTMENT (val)))
1463 {
1464 val = LGLYPH_ADJUSTMENT (val);
1465 CHECK_VECTOR (val);
1466 if (ASIZE (val) < 3)
1467 goto err;
1468 for (j = 0; j < 3; j++)
1469 CHECK_NUMBER (AREF (val, j));
1470 }
1471 }
1472 return i;
1473 err:
1474 error ("Invalid glyph-string format");
1475 return -1;
1476}
1477
1437 1478
1438/* OTF handler */ 1479/* OTF handler */
1439 1480
@@ -1561,7 +1602,6 @@ parse_gsub_gpos_spec (spec, script, langsys, features, nbytes)
1561 int nbytes; 1602 int nbytes;
1562{ 1603{
1563 Lisp_Object val; 1604 Lisp_Object val;
1564 int len;
1565 char *p, *pend; 1605 char *p, *pend;
1566 int asterisk; 1606 int asterisk;
1567 1607
@@ -1614,64 +1654,6 @@ parse_gsub_gpos_spec (spec, script, langsys, features, nbytes)
1614 error ("OTF spec too long"); 1654 error ("OTF spec too long");
1615} 1655}
1616 1656
1617#define LGSTRING_HEADER_SIZE 6
1618#define LGSTRING_GLYPH_SIZE 8
1619
1620static int
1621check_gstring (gstring)
1622 Lisp_Object gstring;
1623{
1624 Lisp_Object val;
1625 int i, j;
1626
1627 CHECK_VECTOR (gstring);
1628 val = AREF (gstring, 0);
1629 CHECK_VECTOR (val);
1630 if (ASIZE (val) < LGSTRING_HEADER_SIZE)
1631 goto err;
1632 CHECK_FONT_OBJECT (LGSTRING_FONT (gstring));
1633 if (! NILP (LGSTRING_LBEARING (gstring)))
1634 CHECK_NUMBER (LGSTRING_LBEARING (gstring));
1635 if (! NILP (LGSTRING_RBEARING (gstring)))
1636 CHECK_NUMBER (LGSTRING_RBEARING (gstring));
1637 if (! NILP (LGSTRING_WIDTH (gstring)))
1638 CHECK_NATNUM (LGSTRING_WIDTH (gstring));
1639 if (! NILP (LGSTRING_ASCENT (gstring)))
1640 CHECK_NUMBER (LGSTRING_ASCENT (gstring));
1641 if (! NILP (LGSTRING_DESCENT (gstring)))
1642 CHECK_NUMBER (LGSTRING_DESCENT(gstring));
1643
1644 for (i = 0; i < LGSTRING_LENGTH (gstring); i++)
1645 {
1646 val = LGSTRING_GLYPH (gstring, i);
1647 CHECK_VECTOR (val);
1648 if (ASIZE (val) < LGSTRING_GLYPH_SIZE)
1649 goto err;
1650 if (NILP (LGLYPH_CHAR (val)))
1651 break;
1652 CHECK_NATNUM (LGLYPH_FROM (val));
1653 CHECK_NATNUM (LGLYPH_TO (val));
1654 CHECK_CHARACTER (LGLYPH_CHAR (val));
1655 if (! NILP (LGLYPH_CODE (val)))
1656 CHECK_NATNUM (LGLYPH_CODE (val));
1657 if (! NILP (LGLYPH_WIDTH (val)))
1658 CHECK_NATNUM (LGLYPH_WIDTH (val));
1659 if (! NILP (LGLYPH_ADJUSTMENT (val)))
1660 {
1661 val = LGLYPH_ADJUSTMENT (val);
1662 CHECK_VECTOR (val);
1663 if (ASIZE (val) < 3)
1664 goto err;
1665 for (j = 0; j < 3; j++)
1666 CHECK_NUMBER (AREF (val, j));
1667 }
1668 }
1669 return i;
1670 err:
1671 error ("Invalid glyph-string format");
1672 return -1;
1673}
1674
1675#define DEVICE_DELTA(table, size) \ 1657#define DEVICE_DELTA(table, size) \
1676 (((size) >= (table).StartSize && (size) <= (table).EndSize) \ 1658 (((size) >= (table).StartSize && (size) <= (table).EndSize) \
1677 ? (table).DeltaValue[(size) - (table).StartSize] \ 1659 ? (table).DeltaValue[(size) - (table).StartSize] \
@@ -2393,6 +2375,49 @@ font_list_entities (frame, spec)
2393 return (i > 0 ? Fvconcat (i, vec) : null_vector); 2375 return (i > 0 ? Fvconcat (i, vec) : null_vector);
2394} 2376}
2395 2377
2378static Lisp_Object
2379font_matching_entity (frame, spec)
2380 Lisp_Object frame, spec;
2381{
2382 FRAME_PTR f = XFRAME (frame);
2383 struct font_driver_list *driver_list = f->font_driver_list;
2384 Lisp_Object ftype, size, entity;
2385
2386 ftype = AREF (spec, FONT_TYPE_INDEX);
2387 size = AREF (spec, FONT_SIZE_INDEX);
2388 if (FLOATP (size))
2389 ASET (spec, FONT_SIZE_INDEX, make_number (font_pixel_size (f, spec)));
2390 entity = Qnil;
2391 for (; driver_list; driver_list = driver_list->next)
2392 if (driver_list->on
2393 && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
2394 {
2395 Lisp_Object cache = driver_list->driver->get_cache (frame);
2396 Lisp_Object val, key;
2397
2398 xassert (CONSP (cache));
2399 ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type);
2400 key = Fcons (spec, Qnil);
2401 entity = assoc_no_quit (key, XCDR (cache));
2402 if (CONSP (entity))
2403 entity = XCDR (entity);
2404 else
2405 {
2406 entity = driver_list->driver->match (frame, spec);
2407 if (! NILP (entity))
2408 {
2409 XSETCAR (key, Fcopy_sequence (spec));
2410 XSETCDR (cache, Fcons (Fcons (key, entity), XCDR (cache)));
2411 }
2412 }
2413 if (! NILP (entity))
2414 break;
2415 }
2416 ASET (spec, FONT_TYPE_INDEX, ftype);
2417 ASET (spec, FONT_SIZE_INDEX, size);
2418 return entity;
2419}
2420
2396static int num_fonts; 2421static int num_fonts;
2397 2422
2398static Lisp_Object 2423static Lisp_Object
@@ -2709,7 +2734,7 @@ font_open_by_name (f, name)
2709 char *name; 2734 char *name;
2710{ 2735{
2711 Lisp_Object args[2]; 2736 Lisp_Object args[2];
2712 Lisp_Object spec, prefer, size, entities; 2737 Lisp_Object spec, prefer, size, entity, entity_list;
2713 Lisp_Object frame; 2738 Lisp_Object frame;
2714 int i; 2739 int i;
2715 int pixel_size; 2740 int pixel_size;
@@ -2745,10 +2770,14 @@ font_open_by_name (f, name)
2745 if (NILP (AREF (spec, FONT_REGISTRY_INDEX))) 2770 if (NILP (AREF (spec, FONT_REGISTRY_INDEX)))
2746 ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1); 2771 ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1);
2747 2772
2748 entities = Flist_fonts (spec, frame, make_number (1), prefer); 2773 entity_list = Flist_fonts (spec, frame, make_number (1), prefer);
2749 return (NILP (entities) 2774 if (NILP (entity_list))
2775 entity = font_matching_entity (frame, spec);
2776 else
2777 entity = XCAR (entity_list);
2778 return (NILP (entity)
2750 ? Qnil 2779 ? Qnil
2751 : font_open_entity (f, XCAR (entities), pixel_size)); 2780 : font_open_entity (f, entity, pixel_size));
2752} 2781}
2753 2782
2754 2783
@@ -2809,50 +2838,38 @@ free_font_driver_list (f)
2809 } 2838 }
2810} 2839}
2811 2840
2812/* Make all font drivers listed in NEW_DRIVERS be used on F. If 2841/* Make the frame F use font backends listed in NEW_BACKENDS (list of
2813 NEW_DRIVERS is nil, make all available font drivers be used. 2842 symbols). If NEW_BACKENDS is nil, make F use all available font
2814 FONT is the current default font of F, it may be NULL. */ 2843 drivers. If no backend is available, dont't alter
2844 f->font_driver_list.
2815 2845
2816void 2846 A caller must free all realized faces and clear all font caches if
2817font_update_drivers (f, new_drivers, font) 2847 any in advance. The return value is a list of font backends
2848 actually made used for on F. */
2849
2850Lisp_Object
2851font_update_drivers (f, new_drivers)
2818 FRAME_PTR f; 2852 FRAME_PTR f;
2819 Lisp_Object new_drivers; 2853 Lisp_Object new_drivers;
2820 struct font *font;
2821{ 2854{
2822 Lisp_Object active_drivers = Qnil; 2855 Lisp_Object active_drivers = Qnil;
2823 Lisp_Object old_spec;
2824 struct font_driver_list *list; 2856 struct font_driver_list *list;
2825 2857
2826 if (font) 2858 /* At first check which font backends are available. */
2827 {
2828 old_spec = font_get_spec (font_find_object (font));
2829 free_all_realized_faces (Qnil);
2830 Fclear_font_cache ();
2831 }
2832
2833 for (list = f->font_driver_list; list; list = list->next) 2859 for (list = f->font_driver_list; list; list = list->next)
2834 { 2860 if (NILP (new_drivers)
2835 if (NILP (new_drivers) 2861 || ! NILP (Fmemq (list->driver->type, new_drivers)))
2836 || ! NILP (Fmemq (list->driver->type, new_drivers))) 2862 {
2837 { 2863 list->on = 2;
2838 list->on = 1; 2864 active_drivers = nconc2 (active_drivers,
2839 active_drivers = Fcons (list->driver->type, active_drivers); 2865 Fcons (list->driver->type, Qnil));
2840 } 2866 }
2841 else 2867 /* If at least one backend is available, update all list->on. */
2842 list->on = 0; 2868 if (! NILP (active_drivers))
2843 } 2869 for (list = f->font_driver_list; list; list = list->next)
2844 2870 list->on = (list->on == 2);
2845 store_frame_param (f, Qfont_backend, active_drivers);
2846
2847 if (font)
2848 {
2849 Lisp_Object frame;
2850 2871
2851 XSETFRAME (frame, f); 2872 return active_drivers;
2852 x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
2853 ++face_change_count;
2854 ++windows_or_buffers_changed;
2855 }
2856} 2873}
2857 2874
2858 2875
@@ -2922,10 +2939,9 @@ usage: (font-spec &rest properties) */)
2922 CHECK_STRING (val); 2939 CHECK_STRING (val);
2923 font_parse_name ((char *) SDATA (val), spec); 2940 font_parse_name ((char *) SDATA (val), spec);
2924 } 2941 }
2925 else 2942 font_put_extra (spec, key, val);
2926 font_put_extra (spec, key, val);
2927 } 2943 }
2928 } 2944 }
2929 CHECK_VALIDATE_FONT_SPEC (spec); 2945 CHECK_VALIDATE_FONT_SPEC (spec);
2930 return spec; 2946 return spec;
2931} 2947}
@@ -2933,8 +2949,7 @@ usage: (font-spec &rest properties) */)
2933 2949
2934DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0, 2950DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0,
2935 doc: /* Return the value of FONT's PROP property. 2951 doc: /* Return the value of FONT's PROP property.
2936FONT may be a font-spec or font-entity. 2952FONT is a font-spec, a font-entity, or a font-object. */)
2937If FONT is font-entity and PROP is :extra, always nil is returned. */)
2938 (font, prop) 2953 (font, prop)
2939 Lisp_Object font, prop; 2954 Lisp_Object font, prop;
2940{ 2955{
@@ -2945,7 +2960,13 @@ If FONT is font-entity and PROP is :extra, always nil is returned. */)
2945 struct font *fontp = XSAVE_VALUE (font)->pointer; 2960 struct font *fontp = XSAVE_VALUE (font)->pointer;
2946 2961
2947 if (EQ (prop, QCotf)) 2962 if (EQ (prop, QCotf))
2948 return font_otf_capability (fontp); 2963 {
2964#ifdef HAVE_LIBOTF
2965 return font_otf_capability (fontp);
2966#else /* not HAVE_LIBOTF */
2967 return Qnil;
2968#endif /* not HAVE_LIBOTF */
2969 }
2949 font = fontp->entity; 2970 font = fontp->entity;
2950 } 2971 }
2951 else 2972 else
@@ -3379,8 +3400,9 @@ glyph-string. */)
3379 args_out_of_range_3 (from, to, make_number (len)); 3400 args_out_of_range_3 (from, to, make_number (len));
3380 if (XINT (index) >= ASIZE (gstring_out)) 3401 if (XINT (index) >= ASIZE (gstring_out))
3381 args_out_of_range (index, make_number (ASIZE (gstring_out))); 3402 args_out_of_range (index, make_number (ASIZE (gstring_out)));
3382 num = font_otf_gsub (font, feature_spec, gstring_in, XINT (from), XINT (to), 3403 num = font->driver->otf_gsub (font, feature_spec,
3383 gstring_out, XINT (index), 0); 3404 gstring_in, XINT (from), XINT (to),
3405 gstring_out, XINT (index), 0);
3384 if (num < 0) 3406 if (num < 0)
3385 return Qnil; 3407 return Qnil;
3386 return make_number (num); 3408 return make_number (num);
@@ -3413,7 +3435,8 @@ GSTRING. */)
3413 3435
3414 if (XINT (from) >= XINT (to) || XINT (to) > len) 3436 if (XINT (from) >= XINT (to) || XINT (to) > len)
3415 args_out_of_range_3 (from, to, make_number (len)); 3437 args_out_of_range_3 (from, to, make_number (len));
3416 num = font_otf_gpos (font, gpos_spec, gstring, XINT (from), XINT (to)); 3438 num = font->driver->otf_gpos (font, gpos_spec,
3439 gstring, XINT (from), XINT (to));
3417 return (num <= 0 ? Qnil : Qt); 3440 return (num <= 0 ? Qnil : Qt);
3418} 3441}
3419 3442
@@ -3439,6 +3462,9 @@ corresponding character. */)
3439 int i, num; 3462 int i, num;
3440 3463
3441 CHECK_FONT_GET_OBJECT (font_object, font); 3464 CHECK_FONT_GET_OBJECT (font_object, font);
3465 if (! font->driver->otf_gsub)
3466 error ("Font backend %s can't drive OpenType GSUB table",
3467 SDATA (SYMBOL_NAME (font->driver->type)));
3442 CHECK_CHARACTER (character); 3468 CHECK_CHARACTER (character);
3443 CHECK_CONS (feature_spec); 3469 CHECK_CONS (feature_spec);
3444 3470
@@ -3446,8 +3472,8 @@ corresponding character. */)
3446 g = LGSTRING_GLYPH (gstring_in, 0); 3472 g = LGSTRING_GLYPH (gstring_in, 0);
3447 LGLYPH_SET_CHAR (g, character); 3473 LGLYPH_SET_CHAR (g, character);
3448 gstring_out = Ffont_make_gstring (font_object, make_number (10)); 3474 gstring_out = Ffont_make_gstring (font_object, make_number (10));
3449 while ((num = font_otf_gsub (font, feature_spec, gstring_in, 0, 1, 3475 while ((num = font->driver->otf_gsub (font, feature_spec, gstring_in, 0, 1,
3450 gstring_out, 0, 1)) < 0) 3476 gstring_out, 0, 1)) < 0)
3451 gstring_out = Ffont_make_gstring (font_object, 3477 gstring_out = Ffont_make_gstring (font_object,
3452 make_number (ASIZE (gstring_out) * 2)); 3478 make_number (ASIZE (gstring_out) * 2));
3453 alternates = Qnil; 3479 alternates = Qnil;
@@ -3456,7 +3482,6 @@ corresponding character. */)
3456 Lisp_Object g = LGSTRING_GLYPH (gstring_out, i); 3482 Lisp_Object g = LGSTRING_GLYPH (gstring_out, i);
3457 int c = XINT (LGLYPH_CHAR (g)); 3483 int c = XINT (LGLYPH_CHAR (g));
3458 unsigned code = XUINT (LGLYPH_CODE (g)); 3484 unsigned code = XUINT (LGLYPH_CODE (g));
3459 Lisp_Object elt;
3460 3485
3461 alternates = Fcons (Fcons (make_number (code), 3486 alternates = Fcons (Fcons (make_number (code),
3462 c > 0 ? make_number (c) : Qnil), 3487 c > 0 ? make_number (c) : Qnil),