[mapserver-dev] fontconfig patch

thomas bonfort thomas.bonfort at gmail.com
Sat Nov 27 11:14:08 EST 2010


Steve,
I'm no fontconfig expert, so take the following answers with a grain
of salt, they are based on what I've seen by trial and error.

On Sat, Nov 27, 2010 at 16:23, Stephen Woodbridge
<woodbri at swoodbridge.com> wrote:
> Thomas,
>
> I would be OK with this as long as it is a configure option that is off by
> default.
>
> The fontconfig cache build is only built once on a system when it is first
> initialized?
I suspect your package manager is responsible for updating the font
cache when a new font is installed or removed. The system I've tested
on is rather unusual as fontconfig is not installed as a system
library, and thus had never had the cache built. running fc-cache as
root on it (as is usually done by the package manager and/or a
crontab) fixed the problem.

>As opposed to on the first time mapserver calls fontconfig?
> correct?
if there is no system wide cache available, fontconfig will create one
when first called, and put it in the user's home directory. this is
where trouble can arise as usually the user running apache won't have
write access.

> Is there away that the font cache can be be checked and built at
> configure time rather than when mapserver calls it? I'm a little concerned
> by the first time long time cache building as that might reflect poorly on
> mapserver for new users.
I'm not sure there's much we can do for that, aside from documenting
the fact that fc-cache has to be run by root to initialize the
systemwide cache. it's of no use to have the user compiling the
program run fc-cache, as that will only build the cache for the
current user, not the apache user.

--
thomas

>
> -Steve W
>
> On 11/27/2010 7:47 AM, thomas bonfort wrote:
>>
>> 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;
>>  }
>> _______________________________________________
>> mapserver-dev mailing list
>> mapserver-dev at lists.osgeo.org
>> http://lists.osgeo.org/mailman/listinfo/mapserver-dev
>
> _______________________________________________
> mapserver-dev mailing list
> mapserver-dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/mapserver-dev
>


More information about the mapserver-dev mailing list