Bugzilla – Bug 148693
fontconfig: FcConfigAppFontAddDir () doesn't work right
Last modified: 2006-02-10 16:09:06 UTC
fontconfig: FcConfigAppFontAddDir () doesn't work right.
The build of "lilypond" fails because of this: /work/built/info/failed/i386/lilypond has: ffective prefix: "/usr/src/packages/BUILD/lilypond-2.6.5/share/lilypond/2.6.5" Initializing FontConfig... error: adding font directory: /usr/src/packages/BUILD/lilypond-2.6.5/share/lilypo nd/2.6.5/fonts/otf/ make[2]: *** [out/lilypond-internals.texi] Error 1 make[2]: Leaving directory `/usr/src/packages/BUILD/lilypond-2.6.5/Documentation/ user'
The regression is somewhere in /work/SAVE/oldpackages/stable/fontconfig/fontconfig-20060203 /.../fontconfig-20060129 works.
Created attachment 66754 [details] ttt.c Test program to reproduce the bug: gcc -g -O0 ttt.c -l fontconfig mfabian@magellan:~/c$ ./a.out /usr/share/fonts mfabian@magellan:~/c$ OK. But: mfabian@magellan:~/c$ ./a.out /usr/share/ error adding dir "/usr/share/" mfabian@magellan:~/c$ I.e. it doesn't work for directories which are not yet sub directories of directories configured in .conf files.
And: mfabian@magellan:/usr/share/fonts$ sudo ln -s /usr/share/fonts ttt mfabian@magellan:/usr/share/fonts$ mfabian@magellan:/usr/share/fonts$ /home/mfabian/c/a.out /usr/share/fonts -> endless loop
Created attachment 66808 [details] fontconfig-bug148693.patch This makes the test program happy (if I understood the code correctly :-)), building lilypond now.
The call of NormalizeDir() became already superfluous by the newer patches, so you can simply remove it, and take FcConfigAddFontDir() back (to be sure). My new patch was already sent to Mike for testing. Stay tuned.
Created attachment 66829 [details] fc-app-dir-fix.diff Takashi's patch.
Created attachment 66830 [details] fc-app-dir-fix.diff Takashi's patch adapted to today's CVS.
Takashi's patch introduces an endless loop again. In fccache.c, Function FcCacheReadDirs (), around line 862, a call to FcStrSetMember () seems to be necessary: + dir = FcConfigNormalizeFontDir (config, dir); + if (! dir) + continue; ++ if (FcStrSetMember (processed_dirs, dir)) ++ continue; + if (! FcStrSetAdd (processed_dirs, dir)) + continue; +
Created attachment 66842 [details] fc-app-dir-fix-new.diff improved patch to avoid the endless loop.
Patrick's comment in http://lists.freedesktop.org/archives/fontconfig/2006-February/002036.html seems to say that the call to FcStrSetMember() is not necessary. Nevertheless it is necessary.
Patrick Lam> The call to FcStrSetMember in FcCacheReadDirs is unneeded (here and Patrick Lam> elsewhere), because FcStrSetAdd calls _FcStrSetAppend, which starts with: Patrick Lam> Patrick Lam> if (FcStrSetMember (set, s)) Patrick Lam> { Patrick Lam> FcStrFree (s); Patrick Lam> return FcTrue; Patrick Lam> } The problem is that it returns FcTrue here, i.e. _FcStrSetAppend () returns FcTrue if the dir is already a member.
Fixed fontconfig package submitted to STABLE. lilypond builds again with that fontconfig package. My test program from comment #3 works as well.
FcConfigAppFontAddDir () does not check the existence of a directory though, i.e. when adding a non-existing directory ./a.out bla it works as well. I guess FcConfigAppFontAddDir () should refuse to add non-existing directories and return FcFalse in that case.
As the behaviour described in comment #14 has been always like this, changing it might have an effect on applications using it. There one might have to be careful with returning FcFalse for non-existing directories.
Closing as FIXED.
FIXED.
Current upstream CVS still runs into an endless loop for the test case in comment #4.
Created attachment 67657 [details] fc-app-dir-fix-new-new.diff The attached hunks of Takashi's patch are still necessary to make it work. Actually the very last hunk: diff -ru fontconfig-2.3.93.20060210.orig/src/fcdir.c fontconfig-2.3.93.20060210/src/fcdir.c --- fontconfig-2.3.93.20060210.orig/src/fcdir.c 2006-02-10 13:06:08.000000000 +0100 +++ fontconfig-2.3.93.20060210/src/fcdir.c 2006-02-10 16:35:30.000000000 +0100 @@ -133,6 +133,8 @@ d_can = FcConfigNormalizeFontDir (config, dir); if (d_can) dir = d_can; + else + FcConfigAddFontDir (config, dir); if (!force) { is not necessary, it works without this hunk. But this hunk seems logical to me, probably it is better to include this as well.
FIXED again.