[mapserver-dev] fontconfig patch

thomas bonfort thomas.bonfort at gmail.com
Sat Nov 27 07:47:33 EST 2010


guys,

is there any reason why mapserver isn't using fontconfig to lookup
fonts that aren't configured in the fontset?
I've got a patch of a dozen lines that seems to be working ok and
shouldn't affect backwards compatibility, and was wondering if anyone
would have reasons to oppose to its inclusion before I start
integrating it cleanly.

what it basically does:
when looking up a font by name, we first query the supplied fontset
for the path to the font.
 * if the fontset contains that font, then we proceed as usual.
 * if not, we do a fontconfig lookup for the given font name, and
insert the found font into our fontset (to avoid calling fontconfig
over and over again for the next labels)

pros:
* no need to define and populate a fontset.
* we get access to a "default" truetype font, making mapserver run out
of the box without having to supply a ttf font file.

cons:
* extra dependency, although the feature will be disablable at compile
time, and the dependency already exists (though probably without the
need for header files) through gd and cairo.
* some extra steps for cleaning up some fontconfig structures at exit
* the first time the fontconfig functions are called and there is no
fontconfig cache on the system, the processing time can be *very* long
while waiting for fontconfig to create its cache. This is a one time
operation though, although I should investigate what happens in the
case an unpriviliedged user is running the command.
* the ouptut of a mapfile can be different depending on the systems it
runs on, as fontconfig may return a different font depending on what
fonts are installed on the system.

To me this seems like a nice usability enhancement for mapserver, but
I won't be offended if we decide we don't want this added.

best regards,
thomas


Index: maplabel.c
===================================================================
--- maplabel.c	(revision 10758)
+++ maplabel.c	(working copy)
@@ -35,7 +35,7 @@
 #include <gdfontt.h>
 #include <gdfontmb.h>
 #include <gdfontg.h>
-
+#include <fontconfig/fontconfig.h>
 #include "mapserver.h"

 MS_CVSID("$Id$")
@@ -760,17 +760,35 @@


 char *msFontsetLookupFont(fontSetObj *fontset, char *fontKey) {
-  char *font;
-	if(!fontKey) {
-		msSetError(MS_TTFERR, "Requested font (NULL) not found.",
"msFontsetLookupFont()");
-		return NULL;
-	}
-	font = msLookupHashTable(&(fontset->fonts), fontKey);
-	if(!font) {
-	  msSetError(MS_TTFERR, "Requested font (%s) not found.",
"msGetLabelSize()", fontKey);
-	  return NULL;
-	}
-	return font;
+  char *font = NULL;
+  if(!fontKey) {
+          msSetError(MS_TTFERR, "Requested font (NULL) not found.",
"msFontsetLookupFont()");
+          return NULL;
+  }
+  if(!fontset) {
+          msSetError(MS_TTFERR, "fontset is NULL", "msFontsetLookupFont()");
+          return NULL;
+  }
+
+  font = msLookupHashTable(&(fontset->fonts), fontKey);
+  if(!font) {
+    FcPattern* pattern = FcNameParse ((FcChar8 *) fontKey);
+    FcResult fcresult;
+
+    FcConfigSubstitute (0, pattern, FcMatchPattern);
+    FcDefaultSubstitute (pattern);
+    FcPattern *matched = FcFontMatch (0, pattern, &fcresult);
+    if (FcPatternGetString (matched, FC_FILE, 0, (FcChar8**)&font) !=
FcResultMatch) {
+      font = NULL;
+      msSetError(MS_TTFERR, "Requested font (%s) not found.",
"msGetLabelSize()", fontKey);
+    } else {
+      struct hashObj *entry =
msInsertHashTable(&(fontset->fonts),fontKey,font);
+      //free(font); TODO this segfaults, check who allocated the string.
+      font = entry->data;
+    }
+    FcPatternDestroy(pattern);
+  }
+  return font;
 }


More information about the mapserver-dev mailing list