From 6715a14f138df01c11110488b7edbf514e4076b4 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Fri, 25 Nov 2022 21:15:32 +0900 Subject: [PATCH] Add FC_DESKTOP_NAME property To allow users to have desktop-specific matching rule. --- fontconfig/fontconfig.h | 27 ++++++++++--------- src/fcdefault.c | 58 ++++++++++++++++++++++++++++++++++++++--- src/fcint.h | 7 +++-- src/fcobjs.h | 1 + src/fcxml.c | 14 +++++----- 5 files changed, 82 insertions(+), 25 deletions(-) diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 09292a3..ac5a0b0 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -128,6 +128,7 @@ typedef int FcBool; #define FC_POSTSCRIPT_NAME "postscriptname" /* String */ #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_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION #define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION @@ -285,7 +286,7 @@ typedef struct _FcObjectSet { int sobject; const char **objects; } FcObjectSet; - + typedef enum _FcMatchKind { FcMatchPattern, FcMatchFont, FcMatchScan, FcMatchKindEnd, @@ -400,7 +401,7 @@ FcConfigGetFilename (FcConfig *config, FcPublic FcChar8 * FcConfigFilename (const FcChar8 *url); - + FcPublic FcConfig * FcConfigCreate (void); @@ -418,7 +419,7 @@ FcConfigGetCurrent (void); FcPublic FcBool FcConfigUptoDate (FcConfig *config); - + FcPublic FcBool FcConfigBuildFonts (FcConfig *config); @@ -548,12 +549,12 @@ FcCharSetIsSubset (const FcCharSet *a, const FcCharSet *b); #define FC_CHARSET_DONE ((FcChar32) -1) FcPublic FcChar32 -FcCharSetFirstPage (const FcCharSet *a, +FcCharSetFirstPage (const FcCharSet *a, FcChar32 map[FC_CHARSET_MAP_SIZE], FcChar32 *next); FcPublic FcChar32 -FcCharSetNextPage (const FcCharSet *a, +FcCharSetNextPage (const FcCharSet *a, FcChar32 map[FC_CHARSET_MAP_SIZE], FcChar32 *next); @@ -609,7 +610,7 @@ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file); FcPublic FcCache * FcDirCacheRescan (const FcChar8 *dir, FcConfig *config); - + FcPublic FcCache * FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config); @@ -772,7 +773,7 @@ FcFontSetMatch (FcConfig *config, FcPublic FcPattern * FcFontMatch (FcConfig *config, - FcPattern *p, + FcPattern *p, FcResult *result); FcPublic FcPattern * @@ -890,10 +891,10 @@ FcPatternHash (const FcPattern *p); FcPublic FcBool FcPatternAdd (FcPattern *p, const char *object, FcValue value, FcBool append); - + FcPublic FcBool FcPatternAddWeak (FcPattern *p, const char *object, FcValue value, FcBool append); - + FcPublic FcResult FcPatternGet (const FcPattern *p, const char *object, int id, FcValue *v); @@ -956,7 +957,7 @@ FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r); FcPublic FcPattern * FcPatternVaBuild (FcPattern *p, va_list va); - + FcPublic FcPattern * FcPatternBuild (FcPattern *p, ...) FC_ATTRIBUTE_SENTINEL(0); @@ -1025,10 +1026,10 @@ FcStrCopy (const FcChar8 *s); FcPublic FcChar8 * FcStrCopyFilename (const FcChar8 *s); - + FcPublic FcChar8 * FcStrPlus (const FcChar8 *s1, const FcChar8 *s2); - + FcPublic void FcStrFree (FcChar8 *s); @@ -1145,7 +1146,7 @@ _FCFUNCPROTOEND * Deprecated functions are placed here to help users fix their code without * digging through documentation */ - + #define FcConfigGetRescanInverval FcConfigGetRescanInverval_REPLACE_BY_FcConfigGetRescanInterval #define FcConfigSetRescanInverval FcConfigSetRescanInverval_REPLACE_BY_FcConfigSetRescanInterval diff --git a/src/fcdefault.c b/src/fcdefault.c index a9a3b72..6995216 100644 --- a/src/fcdefault.c +++ b/src/fcdefault.c @@ -211,28 +211,73 @@ retry: return prgname; } +static FcChar8 *default_desktop_name; + +FcChar8 * +FcGetDesktopName (void) +{ + FcChar8 *desktop_name; +retry: + desktop_name = fc_atomic_ptr_get (&default_desktop_name); + if (!desktop_name) + { + char *s = getenv ("XDG_CURRENT_DESKTOP"); + + if (!s) + desktop_name = FcStrdup (""); + else + desktop_name = FcStrdup (s); + if (!desktop_name) + { + fprintf (stderr, "Fontconfig error: out of memory in %s\n", + __FUNCTION__); + return NULL; + } + + if (!fc_atomic_ptr_cmpexch(&default_desktop_name, NULL, desktop_name)) + { + free (desktop_name); + goto retry; + } + } + if (desktop_name && !desktop_name[0]) + return NULL; + + return desktop_name; +} + void FcDefaultFini (void) { FcChar8 *lang; FcStrSet *langs; FcChar8 *prgname; + FcChar8 *desktop; lang = fc_atomic_ptr_get (&default_lang); - if (lang && fc_atomic_ptr_cmpexch (&default_lang, lang, NULL)) { + if (lang && fc_atomic_ptr_cmpexch (&default_lang, lang, NULL)) + { free (lang); } langs = fc_atomic_ptr_get (&default_langs); - if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) { + if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) + { FcRefInit (&langs->ref, 1); FcStrSetDestroy (langs); } prgname = fc_atomic_ptr_get (&default_prgname); - if (prgname && fc_atomic_ptr_cmpexch (&default_prgname, prgname, NULL)) { + if (prgname && fc_atomic_ptr_cmpexch (&default_prgname, prgname, NULL)) + { free (prgname); } + + desktop = fc_atomic_ptr_get (&default_desktop_name); + if (desktop && fc_atomic_ptr_cmpexch(&default_desktop_name, desktop, NULL)) + { + free (desktop); + } } void @@ -336,6 +381,13 @@ FcDefaultSubstitute (FcPattern *pattern) FcPatternObjectAddString (pattern, FC_PRGNAME_OBJECT, prgname); } + if (FcPatternObjectGet (pattern, FC_DESKTOP_NAME_OBJECT, 0, &v) == FcResultNoMatch) + { + FcChar8 *desktop = FcGetDesktopName (); + if (desktop) + FcPatternObjectAddString (pattern, FC_DESKTOP_NAME_OBJECT, desktop); + } + if (!FcPatternFindObjectIter (pattern, &iter, FC_ORDER_OBJECT)) FcPatternObjectAddInteger (pattern, FC_ORDER_OBJECT, 0); } diff --git a/src/fcint.h b/src/fcint.h index c615b66..78cee54 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -199,7 +199,7 @@ typedef struct _FcValueList { } FcValueList; #define FcValueListNext(vl) FcPointerMember(vl,next,FcValueList) - + typedef int FcObject; /* The 1024 is to leave some room for future added internal objects, such @@ -238,7 +238,7 @@ struct _FcPattern { FcFontSetFonts(fs)[i], \ FcPattern) : \ fs->fonts[i]) - + typedef enum _FcOp { FcOpInteger, FcOpDouble, FcOpString, FcOpMatrix, FcOpRange, FcOpBool, FcOpCharSet, FcOpLangSet, FcOpNil, @@ -909,6 +909,9 @@ FcGetDefaultLang (void); FcPrivate FcChar8 * FcGetPrgname (void); +FcPrivate FcChar8 * +FcGetDesktopName (void); + FcPrivate void FcDefaultFini (void); diff --git a/src/fcobjs.h b/src/fcobjs.h index acc0471..1cd8ed3 100644 --- a/src/fcobjs.h +++ b/src/fcobjs.h @@ -74,4 +74,5 @@ FC_OBJECT (FONT_VARIATIONS, FcTypeString, NULL) FC_OBJECT (VARIABLE, FcTypeBool, FcCompareBool) FC_OBJECT (FONT_HAS_HINT, FcTypeBool, FcCompareBool) FC_OBJECT (ORDER, FcTypeInteger, FcCompareNumber) +FC_OBJECT (DESKTOP_NAME, FcTypeString, NULL) /* ^-------------- Add new objects here. */ diff --git a/src/fcxml.c b/src/fcxml.c index 82a46f2..74c892d 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -367,7 +367,7 @@ typedef enum _FcElement { FcElementDescription, FcElementRemapDir, FcElementResetDirs, - + FcElementRescan, FcElementPrefer, @@ -731,7 +731,7 @@ FcTypecheckExpr (FcConfigParse *parse, FcExpr *expr, FcType type) if (o) FcTypecheckValue (parse, o->type, type); } - else + else FcConfigMessage (parse, FcSevereWarning, "invalid constant used : %s", expr->u.constant); @@ -794,7 +794,7 @@ FcTestCreate (FcConfigParse *parse, if (test) { const FcObjectType *o; - + test->kind = kind; test->qual = qual; test->object = FcObjectFromName ((const char *) field); @@ -1533,7 +1533,7 @@ FcStrtod (char *s, char **end) { char buf[128]; int slen = strlen (s); - + if (slen + dlen > (int) sizeof (buf)) { if (end) @@ -3101,7 +3101,7 @@ FcParsePattern (FcConfigParse *parse) FcConfigMessage (parse, FcSevereError, "out of memory"); return; } - + while ((vstack = FcVStackPeek (parse))) { switch ((int) vstack->tag) { @@ -3176,7 +3176,7 @@ FcEndElement(void *userData, const XML_Char *name FC_UNUSED) case FcElementRescan: FcParseRescan (parse); break; - + case FcElementPrefer: FcParseFamilies (parse, FcVStackPrefer); break; @@ -3512,7 +3512,7 @@ FcConfigParseAndLoadFromMemoryInternal (FcConfig *config, XML_SetDoctypeDeclHandler (p, FcStartDoctypeDecl, FcEndDoctypeDecl); XML_SetElementHandler (p, FcStartElement, FcEndElement); XML_SetCharacterDataHandler (p, FcCharacterData); - + #endif /* ENABLE_LIBXML2 */ #ifndef ENABLE_LIBXML2