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
This commit is contained in:
Akira TAGOH 2023-05-25 20:12:31 +09:00
parent 1751596768
commit f0612537cb
7 changed files with 82 additions and 11 deletions

View File

@ -215,6 +215,7 @@ convenience for the application's rendering mechanism.
fonthashint FC_FONT_HAS_HINT Bool Whether font has hinting fonthashint FC_FONT_HAS_HINT Bool Whether font has hinting
order FC_ORDER Int Order number of the font order FC_ORDER Int Order number of the font
desktop FC_DESKTOP_NAME String Current desktop name desktop FC_DESKTOP_NAME String Current desktop name
namedinstance FC_NAMED_INSTANCE Bool Whether font is a named-instance
</programlisting> </programlisting>
</sect2> </sect2>
</sect1> </sect1>

View File

@ -147,6 +147,7 @@ variable Bool Wheter font is Variable Font
fonthashint Bool Whether the font has hinting fonthashint Bool Whether the font has hinting
order Int Order number of the font order Int Order number of the font
desktop String Current desktop name desktop String Current desktop name
namedinstance Bool Whether font is a named-instance
</programlisting> </programlisting>
</refsect2> </refsect2>
<refsect2> <refsect2>

View File

@ -129,6 +129,7 @@ typedef int FcBool;
#define FC_FONT_HAS_HINT "fonthashint" /* Bool - true if font has hinting */ #define FC_FONT_HAS_HINT "fonthashint" /* Bool - true if font has hinting */
#define FC_ORDER "order" /* Integer */ #define FC_ORDER "order" /* Integer */
#define FC_DESKTOP_NAME "desktop" /* String */ #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_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION

View File

@ -748,7 +748,7 @@ FcSfntNameTranscode (FT_SfntName *sname)
int ilen, olen; int ilen, olen;
FcChar8 *u8; FcChar8 *u8;
FcChar32 ucs4; FcChar32 ucs4;
/* /*
* Convert Utf16 to Utf8 * Convert Utf16 to Utf8
*/ */
@ -782,7 +782,7 @@ FcSfntNameTranscode (FT_SfntName *sname)
int olen; int olen;
FcChar8 *u8; FcChar8 *u8;
FcChar32 ucs4; FcChar32 ucs4;
/* /*
* Convert Latin1 to Utf8. Freed below * Convert Latin1 to Utf8. Freed below
*/ */
@ -837,17 +837,17 @@ FcSfntNameTranscode (FT_SfntName *sname)
size_t in_bytes_left = sname->string_len; size_t in_bytes_left = sname->string_len;
size_t out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN; size_t out_bytes_left = sname->string_len * FC_UTF8_MAX_LEN;
char *inbuf, *outbuf; char *inbuf, *outbuf;
utf8 = malloc (out_bytes_left + 1); utf8 = malloc (out_bytes_left + 1);
if (!utf8) if (!utf8)
{ {
iconv_close (cd); iconv_close (cd);
return 0; return 0;
} }
outbuf = (char *) utf8; outbuf = (char *) utf8;
inbuf = (char *) sname->string; inbuf = (char *) sname->string;
while (in_bytes_left) while (in_bytes_left)
{ {
size_t did = iconv (cd, size_t did = iconv (cd,
@ -1490,7 +1490,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
case TT_NAME_ID_WWS_FAMILY: case TT_NAME_ID_WWS_FAMILY:
case TT_NAME_ID_TYPOGRAPHIC_FAMILY: case TT_NAME_ID_TYPOGRAPHIC_FAMILY:
case TT_NAME_ID_FONT_FAMILY: case TT_NAME_ID_FONT_FAMILY:
#if 0 #if 0
case TT_NAME_ID_UNIQUE_ID: case TT_NAME_ID_UNIQUE_ID:
#endif #endif
if (FcDebug () & FC_DBG_SCANV) if (FcDebug () & FC_DBG_SCANV)
@ -1650,7 +1650,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
{ {
FcChar8 *start, *end; FcChar8 *start, *end;
FcChar8 *family; FcChar8 *family;
start = (FcChar8 *) strrchr ((char *) file, '/'); start = (FcChar8 *) strrchr ((char *) file, '/');
if (start) if (start)
start++; start++;
@ -1971,7 +1971,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
prop.type == BDF_PROPERTY_TYPE_CARDINAL)) prop.type == BDF_PROPERTY_TYPE_CARDINAL))
{ {
FT_Int32 value; FT_Int32 value;
if (prop.type == BDF_PROPERTY_TYPE_INTEGER) if (prop.type == BDF_PROPERTY_TYPE_INTEGER)
value = prop.u.integer; value = prop.u.integer;
else else
@ -2175,6 +2175,8 @@ FcFreeTypeQueryFaceInternal (const FT_Face face,
goto bail2; goto bail2;
} }
#endif #endif
if (!FcPatternObjectAddBool (pat, FC_NAMED_INSTANCE_OBJECT, !!(id > 0xffff)))
goto bail2;
/* /*
* Drop our reference to the charset * 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 FcIsSpace(x) (040 == (x))
#define FcIsDigit(c) (('0' <= (c) && (c) <= '9')) #define FcIsDigit(c) (('0' <= (c) && (c) <= '9'))
#define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsDigit(x) || FcIsSpace(x)) #define FcIsValidScript(x) (FcIsLower(x) || FcIsUpper (x) || FcIsDigit(x) || FcIsSpace(x))
static void static void
addtag(FcChar8 *complex_, FT_ULong tag) addtag(FcChar8 *complex_, FT_ULong tag)
{ {

View File

@ -324,6 +324,7 @@ typedef enum _FcMatcherPriority {
PRI1(FILE), PRI1(FILE),
PRI1(FONTFORMAT), PRI1(FONTFORMAT),
PRI1(VARIABLE), PRI1(VARIABLE),
PRI1(NAMED_INSTANCE),
PRI1(SCALABLE), PRI1(SCALABLE),
PRI1(COLOR), PRI1(COLOR),
PRI1(FOUNDRY), PRI1(FOUNDRY),
@ -1243,7 +1244,7 @@ FcFontSetSort (FcConfig *config FC_UNUSED,
FcPatternGet (p, FC_LANG, nPatternLang, &patternLang) == FcResultMatch; FcPatternGet (p, FC_LANG, nPatternLang, &patternLang) == FcResultMatch;
nPatternLang++) nPatternLang++)
; ;
/* freed below */ /* freed below */
nodes = malloc (nnodes * sizeof (FcSortNode) + nodes = malloc (nnodes * sizeof (FcSortNode) +
nnodes * sizeof (FcSortNode *) + nnodes * sizeof (FcSortNode *) +
@ -1309,7 +1310,7 @@ FcFontSetSort (FcConfig *config FC_UNUSED,
for (i = 0; i < nPatternLang; i++) for (i = 0; i < nPatternLang; i++)
{ {
FcValue nodeLang; FcValue nodeLang;
if (!patternLangSat[i] && if (!patternLangSat[i] &&
FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch && FcPatternGet (p, FC_LANG, i, &patternLang) == FcResultMatch &&
FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch) FcPatternGet (nodeps[f]->pattern, FC_LANG, 0, &nodeLang) == FcResultMatch)

View File

@ -75,4 +75,5 @@ FC_OBJECT (VARIABLE, FcTypeBool, FcCompareBool)
FC_OBJECT (FONT_HAS_HINT, FcTypeBool, FcCompareBool) FC_OBJECT (FONT_HAS_HINT, FcTypeBool, FcCompareBool)
FC_OBJECT (ORDER, FcTypeInteger, FcCompareNumber) FC_OBJECT (ORDER, FcTypeInteger, FcCompareNumber)
FC_OBJECT (DESKTOP_NAME, FcTypeString, NULL) FC_OBJECT (DESKTOP_NAME, FcTypeString, NULL)
FC_OBJECT (NAMED_INSTANCE, FcTypeBool, FcCompareBool)
/* ^-------------- Add new objects here. */ /* ^-------------- Add new objects here. */

View File

@ -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
}
}
]
}