diff options
| author | Kenichi Handa | 2006-08-01 01:28:43 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-08-01 01:28:43 +0000 |
| commit | e950d6f12fc0171a0b9b464bec1a9b6ab54c01a1 (patch) | |
| tree | b1f10cee7ceb9ac170ce0d0fb1f1c1e13e825712 /src | |
| parent | 8fb9e6757ed669f207f203b21ee0aa94715797d0 (diff) | |
| download | emacs-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.c | 283 |
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 | |||
| 1423 | static int | ||
| 1424 | check_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 | |||
| 1620 | static int | ||
| 1621 | check_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 | ||
| 2378 | static Lisp_Object | ||
| 2379 | font_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 | |||
| 2396 | static int num_fonts; | 2421 | static int num_fonts; |
| 2397 | 2422 | ||
| 2398 | static Lisp_Object | 2423 | static 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 | ||
| 2816 | void | 2846 | A caller must free all realized faces and clear all font caches if |
| 2817 | font_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 | |||
| 2850 | Lisp_Object | ||
| 2851 | font_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 | ||
| 2934 | DEFUN ("font-get", Ffont_get, Sfont_get, 2, 2, 0, | 2950 | DEFUN ("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. |
| 2936 | FONT may be a font-spec or font-entity. | 2952 | FONT is a font-spec, a font-entity, or a font-object. */) |
| 2937 | If 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), |