Now using 'fontconfig' to determine which fonts to use

This commit is contained in:
Klaus Schmidinger 2007-06-17 11:12:46 +02:00
parent b1e0df2b27
commit 79b1c68ffb
9 changed files with 165 additions and 53 deletions

View File

@ -2024,6 +2024,7 @@ Anssi Hannula <anssi.hannula@gmail.com>
for improving handling Transfer Mode devices when selecting a device to receive for improving handling Transfer Mode devices when selecting a device to receive
for fixing handling frequencies in NitFilter::Process() for fixing handling frequencies in NitFilter::Process()
for making non-primary devices in Transfer mode be also used for recording for making non-primary devices in Transfer mode be also used for recording
for code and hints on how to use 'fontconfig' to determine which fonts to use
Antti Hartikainen <ami+vdr@ah.fi> Antti Hartikainen <ami+vdr@ah.fi>
for updating 'S13E' in 'sources.conf' for updating 'S13E' in 'sources.conf'

View File

@ -5230,7 +5230,7 @@ Video Disk Recorder Revision History
- Changes to the OSD settings in the "Setup/OSD" menu now immediately take effect - Changes to the OSD settings in the "Setup/OSD" menu now immediately take effect
when the "Ok" key is pressed. when the "Ok" key is pressed.
2007-06-16: Version 1.5.4 2007-06-17: Version 1.5.4
- Increased APIVERSION (forgot to do that in 1.5.2 and 1.5.3). - Increased APIVERSION (forgot to do that in 1.5.2 and 1.5.3).
- Fixed a crash in i18n character set conversion (thanks to Alexander Riedel, - Fixed a crash in i18n character set conversion (thanks to Alexander Riedel,
@ -5242,3 +5242,5 @@ Video Disk Recorder Revision History
canonical spelling with '-' (thanks to Ludwig Nussel for pointing this out). canonical spelling with '-' (thanks to Ludwig Nussel for pointing this out).
- Modified handling invalid characters in VFAT mode. - Modified handling invalid characters in VFAT mode.
- Replaced strn0cpy() with Utf8Strn0Cpy() where necessary. - Replaced strn0cpy() with Utf8Strn0Cpy() where necessary.
- Now using 'fontconfig' to determine which fonts to use (thanks to Anssi Hannula
for code and hints on how to do this).

View File

@ -22,6 +22,7 @@ to work properly.
You will also need to install the following libraries, as well as their You will also need to install the following libraries, as well as their
"devel" packages to get the necessary header files for compiling VDR: "devel" packages to get the necessary header files for compiling VDR:
fontconfig
freetype2 freetype2
libcap libcap
libjpeg libjpeg
@ -29,9 +30,6 @@ You will also need to install the following libraries, as well as their
If the "capability" module is not compiled into your kernel, you may If the "capability" module is not compiled into your kernel, you may
need to do "modprobe capability" before running VDR. need to do "modprobe capability" before running VDR.
When running VDR, the Freetype fonts must be installed in the directory
/usr/share/fonts/truetype.
After extracting the package, change into the VDR directory After extracting the package, change into the VDR directory
and type 'make'. This should produce an executable file and type 'make'. This should produce an executable file
named 'vdr', which can be run after the DVB driver has been named 'vdr', which can be run after the DVB driver has been

View File

@ -4,7 +4,7 @@
# See the main source file 'vdr.c' for copyright information and # See the main source file 'vdr.c' for copyright information and
# how to reach the author. # how to reach the author.
# #
# $Id: Makefile 1.100 2007/05/28 11:22:42 kls Exp $ # $Id: Makefile 1.101 2007/06/16 10:48:59 kls Exp $
.DELETE_ON_ERROR: .DELETE_ON_ERROR:
@ -17,7 +17,7 @@ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
LSIDIR = ./libsi LSIDIR = ./libsi
MANDIR = /usr/local/man MANDIR = /usr/local/man
BINDIR = /usr/local/bin BINDIR = /usr/local/bin
LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype -lfontconfig
INCLUDES = -I/usr/include/freetype2 INCLUDES = -I/usr/include/freetype2
PLUGINDIR= ./PLUGINS PLUGINDIR= ./PLUGINS

76
font.c
View File

@ -4,11 +4,12 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: font.c 1.15 2007/06/09 14:41:27 kls Exp $ * $Id: font.c 1.16 2007/06/17 11:03:33 kls Exp $
*/ */
#include "font.h" #include "font.h"
#include <ctype.h> #include <ctype.h>
#include <fontconfig/fontconfig.h>
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include "config.h" #include "config.h"
@ -22,7 +23,7 @@
struct tKerning { struct tKerning {
uint prevSym; uint prevSym;
int kerning; int kerning;
tKerning(uint PrevSym, int Kerning) { prevSym = PrevSym; kerning = Kerning; } tKerning(uint PrevSym, int Kerning = 0) { prevSym = PrevSym; kerning = Kerning; }
}; };
class cGlyph : public cListObject { class cGlyph : public cListObject {
@ -293,7 +294,7 @@ cFont *cFont::fonts[eDvbFontSize] = { NULL };
void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight) void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight)
{ {
delete fonts[Font]; delete fonts[Font];
fonts[Font] = new cFreetypeFont(*Name == '/' ? Name : *AddDirectory(FONTDIR, Name), CharHeight); fonts[Font] = new cFreetypeFont(GetFontFileName(Name), CharHeight);
} }
const cFont *cFont::GetFont(eDvbFont Font) const cFont *cFont::GetFont(eDvbFont Font)
@ -304,14 +305,77 @@ const cFont *cFont::GetFont(eDvbFont Font)
Font = fontSml; Font = fontSml;
if (!fonts[Font]) { if (!fonts[Font]) {
switch (Font) { switch (Font) {
case fontOsd: SetFont(Font, AddDirectory(FONTDIR, Setup.FontOsd), Setup.FontOsdSize); break; case fontOsd: SetFont(Font, Setup.FontOsd, Setup.FontOsdSize); break;
case fontSml: SetFont(Font, AddDirectory(FONTDIR, Setup.FontSml), Setup.FontSmlSize); break; case fontSml: SetFont(Font, Setup.FontSml, Setup.FontSmlSize); break;
case fontFix: SetFont(Font, AddDirectory(FONTDIR, Setup.FontFix), Setup.FontFixSize); break; case fontFix: SetFont(Font, Setup.FontFix, Setup.FontFixSize); break;
} }
} }
return fonts[Font]; return fonts[Font];
} }
bool cFont::GetAvailableFontNames(cStringList *FontNames, bool Monospaced)
{
if (!FontNames->Size()) {
FcInit();
FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
FcPattern *pat = FcPatternCreate();
FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
if (Monospaced)
FcPatternAddInteger(pat, FC_SPACING, FC_MONO);
FcFontSet* fontset = FcFontList(NULL, pat, os);
for (int i = 0; i < fontset->nfont; i++) {
char *s = (char *)FcNameUnparse(fontset->fonts[i]);
if (s) {
// Strip i18n stuff:
char *p = strchr(s, ',');
if (p)
*p = 0;
// Make it user presentable:
s = strreplace(s, "\\", ""); // '-' is escaped
s = strreplace(s, "style=", "");
FontNames->Append(s); // takes ownership of s
}
}
FcFontSetDestroy(fontset);
FcPatternDestroy(pat);
FcObjectSetDestroy(os);
FcFini();
FontNames->Sort();
}
return FontNames->Size() > 0;
}
cString cFont::GetFontFileName(const char *FontName)
{
cString FontFileName;
if (FontName) {
char *fn = strdup(FontName);
fn = strreplace(fn, ":", ":style=");
fn = strreplace(fn, "-", "\\-");
FcInit();
FcPattern *pat = FcNameParse((FcChar8 *)fn);
FcPatternAddBool(pat, FC_SCALABLE, FcTrue);
FcConfigSubstitute(NULL, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
FcFontSet *fontset = FcFontSort(NULL, pat, FcFalse, NULL, NULL);
for (int i = 0; i < fontset->nfont; i++) {
FcBool scalable;
FcPatternGetBool(fontset->fonts[i], FC_SCALABLE, 0, &scalable);
if (scalable) {
FcChar8 *s = NULL;
FcPatternGetString(fontset->fonts[i], FC_FILE, 0, &s);
FontFileName = (char *)s;
break;
}
}
FcFontSetDestroy(fontset);
FcPatternDestroy(pat);
free(fn);
FcFini();
}
return FontFileName;
}
// --- cTextWrapper ---------------------------------------------------------- // --- cTextWrapper ----------------------------------------------------------
cTextWrapper::cTextWrapper(void) cTextWrapper::cTextWrapper(void)

13
font.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: font.h 1.16 2007/06/10 12:58:54 kls Exp $ * $Id: font.h 1.17 2007/06/17 11:07:15 kls Exp $
*/ */
#ifndef __FONT_H #ifndef __FONT_H
@ -12,10 +12,10 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "tools.h"
#define MAXFONTNAME 64 #define MAXFONTNAME 64
#define MAXFONTSIZE 64 #define MAXFONTSIZE 64
#define FONTDIR "/usr/share/fonts/truetype"
enum eDvbFont { enum eDvbFont {
fontOsd, fontOsd,
@ -53,6 +53,15 @@ public:
///< The caller must not use the returned font outside the scope in which ///< The caller must not use the returned font outside the scope in which
///< it was retrieved by the call to GetFont(), because a call to SetFont() ///< it was retrieved by the call to GetFont(), because a call to SetFont()
///< may delete an existing font. ///< may delete an existing font.
static bool GetAvailableFontNames(cStringList *FontNames, bool Monospaced = false);
///< Queries the font configuration for a list of available font names,
///< which is returned in FontNames. If Monospaced is true, only
///< monospaced fonts will be returned. The resulting font names are
///< in a format that can be used with GetFontFileName() to get the name
///< of the actual font file.
///< Returns true if any font names were found.
static cString GetFontFileName(const char *FontName);
///< Retruns the actual font file name for the given FontName.
}; };
class cTextWrapper { class cTextWrapper {

35
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.c 1.452 2007/06/16 09:33:21 kls Exp $ * $Id: menu.c 1.453 2007/06/17 11:01:13 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -2160,7 +2160,7 @@ private:
cThemes themes; cThemes themes;
int originalThemeIndex; int originalThemeIndex;
int themeIndex; int themeIndex;
cFileNameList fontNames; cStringList fontOsdNames, fontSmlNames, fontFixNames;
int fontOsdIndex, fontSmlIndex, fontFixIndex; int fontOsdIndex, fontSmlIndex, fontFixIndex;
virtual void Set(void); virtual void Set(void);
public: public:
@ -2176,12 +2176,15 @@ cMenuSetupOSD::cMenuSetupOSD(void)
skinDescriptions = new const char*[numSkins]; skinDescriptions = new const char*[numSkins];
themes.Load(Skins.Current()->Name()); themes.Load(Skins.Current()->Name());
themeIndex = originalThemeIndex = Skins.Current()->Theme() ? themes.GetThemeIndex(Skins.Current()->Theme()->Description()) : 0; themeIndex = originalThemeIndex = Skins.Current()->Theme() ? themes.GetThemeIndex(Skins.Current()->Theme()->Description()) : 0;
fontNames.Load(FONTDIR); cFont::GetAvailableFontNames(&fontOsdNames);
if (fontNames.Size()) { cFont::GetAvailableFontNames(&fontSmlNames);
fontOsdIndex = max(0, fontNames.Find(Setup.FontOsd)); cFont::GetAvailableFontNames(&fontFixNames, true);
fontSmlIndex = max(0, fontNames.Find(Setup.FontSml)); fontOsdNames.Insert(strdup("Sans Serif:Bold"));
fontFixIndex = max(0, fontNames.Find(Setup.FontFix)); fontSmlNames.Insert(strdup("Sans Serif"));
} fontFixNames.Insert(strdup("Courier:Bold"));
fontOsdIndex = max(0, fontOsdNames.Find(Setup.FontOsd));
fontSmlIndex = max(0, fontSmlNames.Find(Setup.FontSml));
fontFixIndex = max(0, fontFixNames.Find(Setup.FontFix));
Set(); Set();
} }
@ -2211,11 +2214,9 @@ void cMenuSetupOSD::Set(void)
Add(new cMenuEditIntItem( tr("Setup.OSD$Message time (s)"), &data.OSDMessageTime, 1, 60)); Add(new cMenuEditIntItem( tr("Setup.OSD$Message time (s)"), &data.OSDMessageTime, 1, 60));
Add(new cMenuEditStraItem(tr("Setup.OSD$Use small font"), &data.UseSmallFont, 3, useSmallFontTexts)); Add(new cMenuEditStraItem(tr("Setup.OSD$Use small font"), &data.UseSmallFont, 3, useSmallFontTexts));
Add(new cMenuEditBoolItem(tr("Setup.OSD$Anti-alias"), &data.AntiAlias)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Anti-alias"), &data.AntiAlias));
if (fontNames.Size()) { Add(new cMenuEditStraItem(tr("Setup.OSD$OSD font name"), &fontOsdIndex, fontOsdNames.Size(), &fontOsdNames[0]));
Add(new cMenuEditStraItem(tr("Setup.OSD$OSD font name"), &fontOsdIndex, fontNames.Size(), &fontNames[0])); Add(new cMenuEditStraItem(tr("Setup.OSD$Small font name"), &fontSmlIndex, fontSmlNames.Size(), &fontSmlNames[0]));
Add(new cMenuEditStraItem(tr("Setup.OSD$Small font name"), &fontSmlIndex, fontNames.Size(), &fontNames[0])); Add(new cMenuEditStraItem(tr("Setup.OSD$Fixed font name"), &fontFixIndex, fontFixNames.Size(), &fontFixNames[0]));
Add(new cMenuEditStraItem(tr("Setup.OSD$Fixed font name"), &fontFixIndex, fontNames.Size(), &fontNames[0]));
}
Add(new cMenuEditIntItem( tr("Setup.OSD$OSD font size (pixel)"), &data.FontOsdSize, 10, MAXFONTSIZE)); Add(new cMenuEditIntItem( tr("Setup.OSD$OSD font size (pixel)"), &data.FontOsdSize, 10, MAXFONTSIZE));
Add(new cMenuEditIntItem( tr("Setup.OSD$Small font size (pixel)"),&data.FontSmlSize, 10, MAXFONTSIZE)); Add(new cMenuEditIntItem( tr("Setup.OSD$Small font size (pixel)"),&data.FontSmlSize, 10, MAXFONTSIZE));
Add(new cMenuEditIntItem( tr("Setup.OSD$Fixed font size (pixel)"),&data.FontFixSize, 10, MAXFONTSIZE)); Add(new cMenuEditIntItem( tr("Setup.OSD$Fixed font size (pixel)"),&data.FontFixSize, 10, MAXFONTSIZE));
@ -2255,11 +2256,9 @@ eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
} }
if (data.UseSmallFont != Setup.UseSmallFont || data.AntiAlias != Setup.AntiAlias) if (data.UseSmallFont != Setup.UseSmallFont || data.AntiAlias != Setup.AntiAlias)
ModifiedApperance = true; ModifiedApperance = true;
if (fontNames.Size()) { Utf8Strn0Cpy(data.FontOsd, fontOsdNames[fontOsdIndex], sizeof(data.FontOsd));
Utf8Strn0Cpy(data.FontOsd, fontNames[fontOsdIndex], sizeof(data.FontOsd)); Utf8Strn0Cpy(data.FontSml, fontSmlNames[fontSmlIndex], sizeof(data.FontSml));
Utf8Strn0Cpy(data.FontSml, fontNames[fontSmlIndex], sizeof(data.FontSml)); Utf8Strn0Cpy(data.FontFix, fontFixNames[fontFixIndex], sizeof(data.FontFix));
Utf8Strn0Cpy(data.FontFix, fontNames[fontFixIndex], sizeof(data.FontFix));
}
if (strcmp(data.FontOsd, Setup.FontOsd) || data.FontOsdSize != Setup.FontOsdSize) { if (strcmp(data.FontOsd, Setup.FontOsd) || data.FontOsdSize != Setup.FontOsdSize) {
cFont::SetFont(fontOsd, data.FontOsd, data.FontOsdSize); cFont::SetFont(fontOsd, data.FontOsd, data.FontOsdSize);
ModifiedApperance = true; ModifiedApperance = true;

39
tools.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: tools.c 1.128 2007/06/16 09:22:40 kls Exp $ * $Id: tools.c 1.129 2007/06/17 11:02:34 kls Exp $
*/ */
#include "tools.h" #include "tools.h"
@ -1136,21 +1136,39 @@ struct dirent *cReadDir::Next(void)
return directory && readdir_r(directory, &u.d, &result) == 0 ? result : NULL; return directory && readdir_r(directory, &u.d, &result) == 0 ? result : NULL;
} }
// --- cFileNameList --------------------------------------------------------- // --- cStringList -----------------------------------------------------------
cFileNameList::cFileNameList(const char *Directory) cStringList::~cStringList()
{ {
Load(Directory); Clear();
} }
cFileNameList::~cFileNameList() int cStringList::Find(const char *s) const
{
for (int i = 0; i < Size(); i++) {
if (!strcmp(s, At(i)))
return i;
}
return -1;
}
void cStringList::Clear(void)
{ {
for (int i = 0; i < Size(); i++) for (int i = 0; i < Size(); i++)
free(At(i)); free(At(i));
} }
// --- cFileNameList ---------------------------------------------------------
// TODO better GetFileNames(const char *Directory, cStringList *List)?
cFileNameList::cFileNameList(const char *Directory)
{
Load(Directory);
}
bool cFileNameList::Load(const char *Directory) bool cFileNameList::Load(const char *Directory)
{ {
Clear();
if (Directory) { if (Directory) {
cReadDir d(Directory); cReadDir d(Directory);
struct dirent *e; struct dirent *e;
@ -1159,7 +1177,7 @@ bool cFileNameList::Load(const char *Directory)
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) if (strcmp(e->d_name, ".") && strcmp(e->d_name, ".."))
Append(strdup(e->d_name)); Append(strdup(e->d_name));
} }
Sort(CompareStrings); Sort();
return true; return true;
} }
else else
@ -1168,15 +1186,6 @@ bool cFileNameList::Load(const char *Directory)
return false; return false;
} }
int cFileNameList::Find(const char *FileName)
{
for (int i = 0; i < Size(); i++) {
if (!strcmp(FileName, At(i)))
return i;
}
return -1;
}
// --- cFile ----------------------------------------------------------------- // --- cFile -----------------------------------------------------------------
bool cFile::files[FD_SETSIZE] = { false }; bool cFile::files[FD_SETSIZE] = { false };

42
tools.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: tools.h 1.101 2007/06/16 09:15:40 kls Exp $ * $Id: tools.h 1.102 2007/06/17 11:00:20 kls Exp $
*/ */
#ifndef __TOOLS_H #ifndef __TOOLS_H
@ -402,7 +402,17 @@ private:
mutable int allocated; mutable int allocated;
mutable int size; mutable int size;
mutable T *data; mutable T *data;
void Realloc(int NewAllocated) const { data = (T *)realloc(data, (allocated = NewAllocated) * sizeof(T)); } cVector(const cVector &Vector) {} // don't copy...
cVector &operator=(const cVector &Vector) { return *this; } // ...or assign this!
void Realloc(int Index) const
{
if (++Index > allocated) {
data = (T *)realloc(data, Index * sizeof(T));
for (int i = allocated; i < Index; i++)
data[i] = T(0);
allocated = Index;
}
}
public: public:
cVector(int Allocated = 10) cVector(int Allocated = 10)
{ {
@ -414,8 +424,9 @@ public:
virtual ~cVector() { free(data); } virtual ~cVector() { free(data); }
T& At(int Index) const T& At(int Index) const
{ {
Realloc(Index);
if (Index >= size) if (Index >= size)
Realloc(size = Index + 1); size = Index + 1;
return data[Index]; return data[Index];
} }
const T& operator[](int Index) const const T& operator[](int Index) const
@ -427,12 +438,24 @@ public:
return At(Index); return At(Index);
} }
int Size(void) const { return size; } int Size(void) const { return size; }
virtual void Insert(T Data, int Before = 0)
{
if (Before < size) {
Realloc(size);
memmove(&data[Before + 1], &data[Before], (size - Before) * sizeof(T));
size++;
data[Before] = Data;
}
else
Append(Data);
}
virtual void Append(T Data) virtual void Append(T Data)
{ {
if (size >= allocated) if (size >= allocated)
Realloc(allocated * 4 / 2); // increase size by 50% Realloc(allocated * 4 / 2); // increase size by 50%
data[size++] = Data; data[size++] = Data;
} }
virtual void Clear(void) {}
void Sort(__compar_fn_t Compare) void Sort(__compar_fn_t Compare)
{ {
qsort(data, size, sizeof(T), Compare); qsort(data, size, sizeof(T), Compare);
@ -444,12 +467,19 @@ inline int CompareStrings(const void *a, const void *b)
return strcmp(*(const char **)a, *(const char **)b); return strcmp(*(const char **)a, *(const char **)b);
} }
class cFileNameList : public cVector<char *> { class cStringList : public cVector<char *> {
public:
cStringList(int Allocated = 10): cVector<char *>(Allocated) {}
virtual ~cStringList();
int Find(const char *s) const;
void Sort(void) { cVector<char *>::Sort(CompareStrings); }
virtual void Clear(void);
};
class cFileNameList : public cStringList {
public: public:
cFileNameList(const char *Directory = NULL); cFileNameList(const char *Directory = NULL);
virtual ~cFileNameList();
bool Load(const char *Directory); bool Load(const char *Directory);
int Find(const char *FileName);
}; };
class cHashObject : public cListObject { class cHashObject : public cListObject {