From: Po Lu Date: Sat, 13 Jan 2024 01:51:59 +0000 (+0800) Subject: Properly sort results for partial font specs X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=55ceb4ebcff540ba74417fa281357c528c305ac0;p=emacs.git 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. (cherry picked from commit 4edb77132de731f9d4cb2cffee2f8847eafdcc72) --- 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) return entity; } +/* Return whether fewer fields inside the font entity A are set than + there are set inside the font entity B. */ + +static Lisp_Object +sfntfont_compare_font_entities (Lisp_Object a, Lisp_Object b) +{ + ptrdiff_t count_a, count_b, i; + + count_a = 0; + count_b = 0; + + for (i = 0; i < FONT_ENTITY_MAX; ++i) + { + if (!NILP (AREF (a, i))) + count_a++; + } + + for (i = 0; i < FONT_ENTITY_MAX; ++i) + { + if (!NILP (AREF (b, i))) + count_b++; + } + + return count_a < count_b ? Qt : Qnil; +} + +/* Function that compares two font entities to return whether fewer + fields are set within the first than in the second. */ + +static union Aligned_Lisp_Subr Scompare_font_entities = + { + { + { PSEUDOVECTOR_FLAG | (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS), }, + { .a2 = sfntfont_compare_font_entities, }, + 2, 2, "sfntfont_compare_font_entities", {0}, lisp_h_Qnil, + }, + }; + /* Return a list of font-entities matching the specified FONT_SPEC. */ Lisp_Object sfntfont_list (struct frame *f, Lisp_Object font_spec) { - Lisp_Object matching, tem; + Lisp_Object matching, tem, compare_font_entities; struct sfnt_font_desc *desc; int i, rc, instances[100]; @@ -1982,9 +2020,16 @@ sfntfont_list (struct frame *f, Lisp_Object font_spec) matching); } } - unblock_input (); + /* Sort matching by the number of fields set inside each element, so + that values of FONT_SPECs that leave a number of fields + unspecified will yield a list with the closest matches (that is + to say, those whose fields are precisely as specified by the + caller) ordered first. */ + + XSETSUBR (compare_font_entities, &Scompare_font_entities.s); + matching = Fsort (matching, compare_font_entities); return matching; }