diff options
| author | Po Lu | 2024-01-13 09:51:59 +0800 |
|---|---|---|
| committer | Po Lu | 2024-01-13 09:51:59 +0800 |
| commit | 4edb77132de731f9d4cb2cffee2f8847eafdcc72 (patch) | |
| tree | b6ecae97f0c4f6ba762eb3c400445a016c16ee81 | |
| parent | 8b7a6d7b6deca9346092501dbfa679e3e5ea5892 (diff) | |
| download | emacs-4edb77132de731f9d4cb2cffee2f8847eafdcc72.tar.gz emacs-4edb77132de731f9d4cb2cffee2f8847eafdcc72.zip | |
Properly sort results for partial font specs
* src/sfntfont.c (sfntfont_compare_font_entities): New function.
(sfntfont_list): Sort matching font entities by the number of
fields set, and mention why.
| -rw-r--r-- | src/sfntfont.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/src/sfntfont.c b/src/sfntfont.c index 1ad41deac70..860fc446184 100644 --- a/src/sfntfont.c +++ b/src/sfntfont.c | |||
| @@ -1939,13 +1939,51 @@ sfntfont_desc_to_entity (struct sfnt_font_desc *desc, int instance) | |||
| 1939 | return entity; | 1939 | return entity; |
| 1940 | } | 1940 | } |
| 1941 | 1941 | ||
| 1942 | /* Return whether fewer fields inside the font entity A are set than | ||
| 1943 | there are set inside the font entity B. */ | ||
| 1944 | |||
| 1945 | static Lisp_Object | ||
| 1946 | sfntfont_compare_font_entities (Lisp_Object a, Lisp_Object b) | ||
| 1947 | { | ||
| 1948 | ptrdiff_t count_a, count_b, i; | ||
| 1949 | |||
| 1950 | count_a = 0; | ||
| 1951 | count_b = 0; | ||
| 1952 | |||
| 1953 | for (i = 0; i < FONT_ENTITY_MAX; ++i) | ||
| 1954 | { | ||
| 1955 | if (!NILP (AREF (a, i))) | ||
| 1956 | count_a++; | ||
| 1957 | } | ||
| 1958 | |||
| 1959 | for (i = 0; i < FONT_ENTITY_MAX; ++i) | ||
| 1960 | { | ||
| 1961 | if (!NILP (AREF (b, i))) | ||
| 1962 | count_b++; | ||
| 1963 | } | ||
| 1964 | |||
| 1965 | return count_a < count_b ? Qt : Qnil; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | /* Function that compares two font entities to return whether fewer | ||
| 1969 | fields are set within the first than in the second. */ | ||
| 1970 | |||
| 1971 | static union Aligned_Lisp_Subr Scompare_font_entities = | ||
| 1972 | { | ||
| 1973 | { | ||
| 1974 | { PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS), }, | ||
| 1975 | { .a2 = sfntfont_compare_font_entities, }, | ||
| 1976 | 2, 2, "sfntfont_compare_font_entities", {0}, lisp_h_Qnil, | ||
| 1977 | }, | ||
| 1978 | }; | ||
| 1979 | |||
| 1942 | /* Return a list of font-entities matching the specified | 1980 | /* Return a list of font-entities matching the specified |
| 1943 | FONT_SPEC. */ | 1981 | FONT_SPEC. */ |
| 1944 | 1982 | ||
| 1945 | Lisp_Object | 1983 | Lisp_Object |
| 1946 | sfntfont_list (struct frame *f, Lisp_Object font_spec) | 1984 | sfntfont_list (struct frame *f, Lisp_Object font_spec) |
| 1947 | { | 1985 | { |
| 1948 | Lisp_Object matching, tem; | 1986 | Lisp_Object matching, tem, compare_font_entities; |
| 1949 | struct sfnt_font_desc *desc; | 1987 | struct sfnt_font_desc *desc; |
| 1950 | int i, rc, instances[100]; | 1988 | int i, rc, instances[100]; |
| 1951 | 1989 | ||
| @@ -1982,9 +2020,16 @@ sfntfont_list (struct frame *f, Lisp_Object font_spec) | |||
| 1982 | matching); | 2020 | matching); |
| 1983 | } | 2021 | } |
| 1984 | } | 2022 | } |
| 1985 | |||
| 1986 | unblock_input (); | 2023 | unblock_input (); |
| 1987 | 2024 | ||
| 2025 | /* Sort matching by the number of fields set inside each element, so | ||
| 2026 | that values of FONT_SPECs that leave a number of fields | ||
| 2027 | unspecified will yield a list with the closest matches (that is | ||
| 2028 | to say, those whose fields are precisely as specified by the | ||
| 2029 | caller) ordered first. */ | ||
| 2030 | |||
| 2031 | XSETSUBR (compare_font_entities, &Scompare_font_entities.s); | ||
| 2032 | matching = Fsort (matching, compare_font_entities); | ||
| 1988 | return matching; | 2033 | return matching; |
| 1989 | } | 2034 | } |
| 1990 | 2035 | ||