From f0612537cb55ef97835914b0c64497034c60b8c9 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Thu, 25 May 2023 20:12:31 +0900 Subject: [PATCH] Add namedinstance property This change allows applications to detect if a font is a variable font and a named-instance. If they are, namedinstance property is set to true, otherwise false. Fixes https://gitlab.freedesktop.org/fontconfig/fontconfig/-/issues/362 --- doc/fontconfig-devel.sgml | 1 + doc/fontconfig-user.sgml | 1 + fontconfig/fontconfig.h | 1 + src/fcfreetype.c | 20 ++++++----- src/fcmatch.c | 5 +-- src/fcobjs.h | 1 + test/test-namedinstance.json | 64 ++++++++++++++++++++++++++++++++++++ 7 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 test/test-namedinstance.json diff --git a/doc/fontconfig-devel.sgml b/doc/fontconfig-devel.sgml index f39f2ed..c2b1e2d 100644 --- a/doc/fontconfig-devel.sgml +++ b/doc/fontconfig-devel.sgml @@ -215,6 +215,7 @@ convenience for the application's rendering mechanism. fonthashint FC_FONT_HAS_HINT Bool Whether font has hinting order FC_ORDER Int Order number of the font desktop FC_DESKTOP_NAME String Current desktop name + namedinstance FC_NAMED_INSTANCE Bool Whether font is a named-instance diff --git a/doc/fontconfig-user.sgml b/doc/fontconfig-user.sgml index 389f713..7dbf9f2 100644 --- a/doc/fontconfig-user.sgml +++ b/doc/fontconfig-user.sgml @@ -147,6 +147,7 @@ variable Bool Wheter font is Variable Font fonthashint Bool Whether the font has hinting order Int Order number of the font desktop String Current desktop name +namedinstance Bool Whether font is a named-instance diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index bd2daff..6f83811 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -129,6 +129,7 @@ typedef int FcBool; #define FC_FONT_HAS_HINT "fonthashint" /* Bool - true if font has hinting */ #define FC_ORDER "order" /* Integer */ #define FC_DESKTOP_NAME "desktop" /* String */ +#define FC_NAMED_INSTANCE "namedinstance" /* Bool - true if font is namedinstance */ #define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 636ee4f..2104cfe 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -748,7 +748,7 @@ FcSfntNameTranscode (FT_SfntName *sname) int ilen, olen; FcChar8 *u8; FcChar32 ucs4; - + /* * Convert Utf16 to Utf8 */ @@ -782,7 +782,7 @@ FcSfntNameTranscode (FT_SfntName *sname) int olen; FcChar8 *u8; FcChar32 ucs4; - + /* * Convert Latin1 to Utf8. Freed below */ @@ -837,17 +837,17 @@ FcSfntNameTranscode (FT_SfntName *sname) size_t in_bytes_left = sname->string_len; size_t out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN; char *inbuf, *outbuf; - + utf8 = malloc (out_bytes_left + 1); if (!utf8) { iconv_close (cd); return 0; } - + outbuf = (char *) utf8; inbuf = (char *) sname->string; - + while (in_bytes_left) { size_t did = iconv (cd, @@ -1490,7 +1490,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, case TT_NAME_ID_WWS_FAMILY: case TT_NAME_ID_TYPOGRAPHIC_FAMILY: case TT_NAME_ID_FONT_FAMILY: -#if 0 +#if 0 case TT_NAME_ID_UNIQUE_ID: #endif if (FcDebug () & FC_DBG_SCANV) @@ -1650,7 +1650,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, { FcChar8 *start, *end; FcChar8 *family; - + start = (FcChar8 *) strrchr ((char *) file, '/'); if (start) start++; @@ -1971,7 +1971,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, prop.type == BDF_PROPERTY_TYPE_CARDINAL)) { FT_Int32 value; - + if (prop.type == BDF_PROPERTY_TYPE_INTEGER) value = prop.u.integer; else @@ -2175,6 +2175,8 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, goto bail2; } #endif + if (!FcPatternObjectAddBool (pat, FC_NAMED_INSTANCE_OBJECT, !!(id > 0xffff))) + goto bail2; /* * Drop our reference to the charset @@ -2657,7 +2659,7 @@ FcFreeTypeCharSetAndSpacing (FT_Face face, FcBlanks *blanks FC_UNUSED, int *spac #define FcIsSpace(x) (040 == (x)) #define FcIsDigit(c) (('0' <= (c) && (c) <= '9')) #define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsDigit(x) || FcIsSpace(x)) - + static void addtag(FcChar8 *complex_, FT_ULong tag) { diff --git a/src/fcmatch.c b/src/fcmatch.c index cf0876c..a1a40c8 100644 --- a/src/fcmatch.c +++ b/src/fcmatch.c @@ -324,6 +324,7 @@ typedef enum _FcMatcherPriority { PRI1(FILE), PRI1(FONTFORMAT), PRI1(VARIABLE), + PRI1(NAMED_INSTANCE), PRI1(SCALABLE), PRI1(COLOR), PRI1(FOUNDRY), @@ -1243,7 +1244,7 @@ FcFontSetSort (FcConfig *config FC_UNUSED, FcPatternGet (p, FC_LANG, nPatternLang, &patternLang) == FcResultMatch; nPatternLang++) ; - + /* freed below */ nodes = malloc (nnodes * sizeof (FcSortNode) + nnodes * sizeof (FcSortNode *) + @@ -1309,7 +1310,7 @@ FcFontSetSort (FcConfig *config FC_UNUSED, for (i = 0; i < nPatternLang; i++) { FcValue nodeLang; - + if (!patternLangSat[i] && FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch && FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch) diff --git a/src/fcobjs.h b/src/fcobjs.h index 1cd8ed3..833a68f 100644 --- a/src/fcobjs.h +++ b/src/fcobjs.h @@ -75,4 +75,5 @@ FC_OBJECT (VARIABLE, FcTypeBool, FcCompareBool) FC_OBJECT (FONT_HAS_HINT, FcTypeBool, FcCompareBool) FC_OBJECT (ORDER, FcTypeInteger, FcCompareNumber) FC_OBJECT (DESKTOP_NAME, FcTypeString, NULL) +FC_OBJECT (NAMED_INSTANCE, FcTypeBool, FcCompareBool) /* ^-------------- Add new objects here. */ diff --git a/test/test-namedinstance.json b/test/test-namedinstance.json new file mode 100644 index 0000000..78efde6 --- /dev/null +++ b/test/test-namedinstance.json @@ -0,0 +1,64 @@ +{ + "fonts": [ + { + "family": [ + "Foo" + ], + "style": [ + "Regular" + ], + "file": "/path/to/Foo-VF.otf", + "index": 1, + "namedinstance": false, + "fontversion": 1 + }, + { + "family": [ + "Foo", + "Foo Bold" + ], + "style": [ + "Bold", + "Regular" + ], + "file": "/path/to/Foo-VF.otf", + "index": 65537, + "namedinstance": true, + "fontversion": 1 + } + ], + "tests": [ + { + "method": "match", + "query": { + "family": "Foo", + "style": "Bold", + "namedinstance": false + }, + "result": { + "family": "Foo", + "style": "Regular", + "file": "/path/to/Foo-VF.otf", + "index": 1, + "namedinstance": false, + "fontversion": 1 + } + }, + { + "method": "match", + "query": { + "family": "Foo", + "style": "Bold", + "namedinstance": true + }, + "result": { + "family": "Foo", + "style": "Bold", + "file": "/path/to/Foo-VF.otf", + "index": 65537, + "namedinstance": true, + "fontversion": 1 + } + } + ] +}