diff --git a/doc/fcconfig.fncs b/doc/fcconfig.fncs
index 16d1000..3ceab92 100644
--- a/doc/fcconfig.fncs
+++ b/doc/fcconfig.fncs
@@ -29,14 +29,28 @@
Creates an empty configuration.
@@
+@RET@ FcConfig *
+@FUNC@ FcConfigReference
+@TYPE1@ FcConfig * @ARG1@ config
+@PURPOSE@ Increment config reference count
+@DESC@
+Add another reference to config. Configs are freed only
+when the reference count reaches zero.
+If config is NULL, the current configuration is used.
+In that case this function will be similar to FcConfigGetCurrent() except that
+it increments the reference count before returning and the user is responsible
+for destroying the configuration when not needed anymore.
+@@
+
@RET@ void
@FUNC@ FcConfigDestroy
@TYPE1@ FcConfig * @ARG1@ config
@PURPOSE@ Destroy a configuration
@DESC@
-Destroys a configuration and any data associated with it. Note that calling
-this function with the return from FcConfigGetCurrent will place the library
-in an indeterminate state.
+Decrements the config reference count. If all references are gone, destroys
+the configuration and any data associated with it.
+Note that calling this function with the return from FcConfigGetCurrent will
+cause a new configuration to be created for use as current configuration.
@@
@RET@ FcBool
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 55e1763..4149072 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -342,6 +342,9 @@ FcConfigFilename (const FcChar8 *url);
FcPublic FcConfig *
FcConfigCreate (void);
+FcPublic FcConfig *
+FcConfigReference (FcConfig *config);
+
FcPublic void
FcConfigDestroy (FcConfig *config);
diff --git a/src/fccfg.c b/src/fccfg.c
index 85ad0f5..70748c8 100644
--- a/src/fccfg.c
+++ b/src/fccfg.c
@@ -92,6 +92,8 @@ FcConfigCreate (void)
config->rescanTime = time(0);
config->rescanInterval = 30;
+
+ config->ref = 1;
return config;
@@ -191,11 +193,29 @@ FcSubstDestroy (FcSubst *s)
}
}
+FcConfig *
+FcConfigReference (FcConfig *config)
+{
+ if (!config)
+ {
+ config = FcConfigGetCurrent ();
+ if (!config)
+ return 0;
+ }
+
+ config->ref++;
+
+ return config;
+}
+
void
FcConfigDestroy (FcConfig *config)
{
FcSetName set;
+ if (--config->ref > 0)
+ return;
+
if (config == _fcConfig)
_fcConfig = 0;
diff --git a/src/fcint.h b/src/fcint.h
index 5798702..370dd7e 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -483,6 +483,8 @@ struct _FcConfig {
*/
time_t rescanTime; /* last time information was scanned */
int rescanInterval; /* interval between scans */
+
+ int ref; /* reference count */
};
extern FcPrivate FcConfig *_fcConfig;