[vdr] [ANNOUNCE] VDR developer version 1.5.3

Anssi Hannula anssi.hannula at gmail.com
Sat Jun 16 18:28:14 CEST 2007


Klaus Schmidinger wrote:
> On 06/16/07 16:29, Anssi Hannula wrote:
>> Klaus Schmidinger wrote:
>>> On 06/15/07 18:07, Anssi Hannula wrote:
>>>> Klaus Schmidinger wrote:
>>>>> On 06/10/07 17:53, Anssi Hannula wrote:
>>>>>> ...
>>>>>> Alternatively, you could use the fontconfig library [1] for managing 
>>>>>> fonts. This would also allow using using the system default fonts via 
>>>>>> aliases like 'sans-serif' etc, and using a font list instead of having 
>>>>>> to manually write the font filename via OSD.
>>>>>>
>>>>>> You can get a quick idea from looking at the patch which added 
>>>>>> fontconfig support for mplayer [2], though of course you should look in 
>>>>>> fontconfig documentation instead of copying conventions from mplayer :)
>>>>>>
>>>>>> [1] http://fontconfig.org/
>>>>>> [2] 
>>>>>> http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2003-November/022218.html
>>>>> When I do
>>>>>
>>>>>      const char *font_name = "sans-serif";
>>>>>      FcInit();
>>>>>      FcPattern *fc_pattern = FcNameParse((FcChar8 *)font_name);
>>>> While fontconfig is usually configured to ignore bitmap fonts anyway, I 
>>>> think you should enforce that by putting this call here:
>>>> FcPatternAddBool(fc_pattern, FC_SCALABLE, FcTrue);
>>> Thanks.
>> Actually, I was wrong here. This won't guarantee anything, as the 
>> preference priorities of parameters is predefined, and the family name 
>> and, apparently, various other parameters (which are actually left at 
>> their defaults) are given a priority over the font being scalable. I was 
>> hit with this when trying to select FC_FAMILY "Utopia", and it kept 
>> returning the non-scalable version, even though a scalable version with 
>> the same name is available.
>>
>> Solution is given here:
>> http://lists.freedesktop.org/archives/fontconfig/2006-March/002165.html
>>
>> So it is doable, but you have to use FcFontSort() ( 
>> http://www.xemacs.org/Documentation/packages/html/fontconfig_3.html#SEC20 
>> ), which returns a similar FcFontSet as the FcFontList() which is used 
>> for the font listing, but this time the fonts are ordered according to 
>> the closeness of match, allowing you to pick the first font with 
>> FC_SCALABLE being true.
>>
>> [...]
>>
>> I don't know if you have noticed / thought of these already, but few tips:
>> - For the fixed-size font list, you can use a match of FC_SPACING being 
>> FC_MONO so that non-monospace fonts are not listed.
>> - Have a "default" (or "system default") font setting in the font list, 
>> which causes VDR to use the default aliases instead of user-specified font
> 
> Since you're apparently getting more and more familiar with this,
> maybe you could provide a complete code sequence that does this:
> 
> - list all available fonts, as in "Arial", "Verdana", "Times New Roman", ...
> 
> - optionally list only monospaced fonts
> 
> - make sure there are only scalable fonts (i.e. ones that freetype can use)
> 
> - if possible, give information on whether a particular font is available
>   as "bold" and/or "italic


This function prints all the fonts in a format which can be fed back to 
FcNameParse(). AFAICS you only need slant+weight or style, use which one 
you prefer.

int printfonts(bool only_monospace, bool slant_and_weight_instead_of_style)
{
         FcInit();
         FcObjectSet *os;
         if (slant_and_weight_instead_of_style)
                 os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT, 
NULL);
         else
                 os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
         FcPattern *pat = FcPatternCreate();
         FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
         if (only_monospace)
                 FcPatternAddInteger(pat, FC_SPACING, FC_MONO);
         FcFontSet* fontset = FcFontList(NULL, pat, os);
         FcObjectSetDestroy(os);
         FcPatternDestroy(pat);
         for (int i = 0; i < fontset->nfont ; i++) {
                 printf("%s\n", FcNameUnparse(fontset->fonts[i]));
         }
         FcFontSetDestroy(fontset);
         FcFini();
}

Here's a function that prints the font name when inputted with a string 
outputted by printfonts(), or NULL if not found:

void getfontfilename(char* identifier, char **filename)
{
         FcPattern *pat = FcNameParse((FcChar8*)identifier);
         FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
         FcConfigSubstitute(NULL, pat, FcMatchPattern);
         FcDefaultSubstitute(pat);
         FcFontSet* fontset = FcFontSort(NULL, pat, FcFalse, NULL, NULL);
         FcPatternDestroy(pat);
         FcBool scalable;
         *filename = NULL;
         for (int i = 0; i < fontset->nfont; i++) {
                 FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, 
&scalable);
                 if (scalable) {
                         FcPatternGetString(fontset->fonts[i], FC_FILE, 
0, (FcChar8**)filename);
                         break;
                 }
         }
         FcFontSetDestroy(fontset);
}


> 
> From the setup menu I'd like to be able to call a function that delivers
> a list of font names (much like it's currently done with the actual font
> file names) that looks like
> 
>   Arial
>   Arial:bold
>   Arial:italic
>   Arial:bold:italic
>   Verdana
>   Verdana:bold
>   Verdana:italic
>   ...
> 
> I would prepend that list with
> 
>   sans-serif:bold
>   sans-serif
>   courier:bold

Probably monospace:bold instead of courier:bold.

> for the three default fonts.
> 
> Finally, such a string should be useable to select an actual font file.

-- 
Anssi Hannula



More information about the vdr mailing list