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 fixing handling frequencies in NitFilter::Process()
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>
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
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).
- 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).
- Modified handling invalid characters in VFAT mode.
- 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
"devel" packages to get the necessary header files for compiling VDR:
fontconfig
freetype2
libcap
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
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
and type 'make'. This should produce an executable file
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
# 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:
@ -17,7 +17,7 @@ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
LSIDIR = ./libsi
MANDIR = /usr/local/man
BINDIR = /usr/local/bin
LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype
LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype -lfontconfig
INCLUDES = -I/usr/include/freetype2
PLUGINDIR= ./PLUGINS

76
font.c
View File

@ -4,11 +4,12 @@
* See the main source file 'vdr.c' for copyright information and
* 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 <ctype.h>
#include <fontconfig/fontconfig.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "config.h"
@ -22,7 +23,7 @@
struct tKerning {
uint prevSym;
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 {
@ -293,7 +294,7 @@ cFont *cFont::fonts[eDvbFontSize] = { NULL };
void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight)
{
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)
@ -304,14 +305,77 @@ const cFont *cFont::GetFont(eDvbFont Font)
Font = fontSml;
if (!fonts[Font]) {
switch (Font) {
case fontOsd: SetFont(Font, AddDirectory(FONTDIR, Setup.FontOsd), Setup.FontOsdSize); break;
case fontSml: SetFont(Font, AddDirectory(FONTDIR, Setup.FontSml), Setup.FontSmlSize); break;
case fontFix: SetFont(Font, AddDirectory(FONTDIR, Setup.FontFix), Setup.FontFixSize); break;
case fontOsd: SetFont(Font, Setup.FontOsd, Setup.FontOsdSize); break;
case fontSml: SetFont(Font, Setup.FontSml, Setup.FontSmlSize); break;
case fontFix: SetFont(Font, Setup.FontFix, Setup.FontFixSize); break;
}
}
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(void)

13
font.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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
@ -12,10 +12,10 @@
#include <stdint.h>
#include <stdlib.h>
#include "tools.h"
#define MAXFONTNAME 64
#define MAXFONTSIZE 64
#define FONTDIR "/usr/share/fonts/truetype"
enum eDvbFont {
fontOsd,
@ -53,6 +53,15 @@ public:
///< 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()
///< 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 {

35
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@ -2160,7 +2160,7 @@ private:
cThemes themes;
int originalThemeIndex;
int themeIndex;
cFileNameList fontNames;
cStringList fontOsdNames, fontSmlNames, fontFixNames;
int fontOsdIndex, fontSmlIndex, fontFixIndex;
virtual void Set(void);
public:
@ -2176,12 +2176,15 @@ cMenuSetupOSD::cMenuSetupOSD(void)
skinDescriptions = new const char*[numSkins];
themes.Load(Skins.Current()->Name());
themeIndex = originalThemeIndex = Skins.Current()->Theme() ? themes.GetThemeIndex(Skins.Current()->Theme()->Description()) : 0;
fontNames.Load(FONTDIR);
if (fontNames.Size()) {
fontOsdIndex = max(0, fontNames.Find(Setup.FontOsd));
fontSmlIndex = max(0, fontNames.Find(Setup.FontSml));
fontFixIndex = max(0, fontNames.Find(Setup.FontFix));
}
cFont::GetAvailableFontNames(&fontOsdNames);
cFont::GetAvailableFontNames(&fontSmlNames);
cFont::GetAvailableFontNames(&fontFixNames, true);
fontOsdNames.Insert(strdup("Sans Serif:Bold"));
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();
}
@ -2211,11 +2214,9 @@ void cMenuSetupOSD::Set(void)
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 cMenuEditBoolItem(tr("Setup.OSD$Anti-alias"), &data.AntiAlias));
if (fontNames.Size()) {
Add(new cMenuEditStraItem(tr("Setup.OSD$OSD font name"), &fontOsdIndex, fontNames.Size(), &fontNames[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, fontNames.Size(), &fontNames[0]));
}
Add(new cMenuEditStraItem(tr("Setup.OSD$OSD font name"), &fontOsdIndex, fontOsdNames.Size(), &fontOsdNames[0]));
Add(new cMenuEditStraItem(tr("Setup.OSD$Small font name"), &fontSmlIndex, fontSmlNames.Size(), &fontSmlNames[0]));
Add(new cMenuEditStraItem(tr("Setup.OSD$Fixed font name"), &fontFixIndex, fontFixNames.Size(), &fontFixNames[0]));
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$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)
ModifiedApperance = true;
if (fontNames.Size()) {
Utf8Strn0Cpy(data.FontOsd, fontNames[fontOsdIndex], sizeof(data.FontOsd));
Utf8Strn0Cpy(data.FontSml, fontNames[fontSmlIndex], sizeof(data.FontSml));
Utf8Strn0Cpy(data.FontFix, fontNames[fontFixIndex], sizeof(data.FontFix));
}
Utf8Strn0Cpy(data.FontOsd, fontOsdNames[fontOsdIndex], sizeof(data.FontOsd));
Utf8Strn0Cpy(data.FontSml, fontSmlNames[fontSmlIndex], sizeof(data.FontSml));
Utf8Strn0Cpy(data.FontFix, fontFixNames[fontFixIndex], sizeof(data.FontFix));
if (strcmp(data.FontOsd, Setup.FontOsd) || data.FontOsdSize != Setup.FontOsdSize) {
cFont::SetFont(fontOsd, data.FontOsd, data.FontOsdSize);
ModifiedApperance = true;

39
tools.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* 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"
@ -1136,21 +1136,39 @@ struct dirent *cReadDir::Next(void)
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++)
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)
{
Clear();
if (Directory) {
cReadDir d(Directory);
struct dirent *e;
@ -1159,7 +1177,7 @@ bool cFileNameList::Load(const char *Directory)
if (strcmp(e->d_name, ".") && strcmp(e->d_name, ".."))
Append(strdup(e->d_name));
}
Sort(CompareStrings);
Sort();
return true;
}
else
@ -1168,15 +1186,6 @@ bool cFileNameList::Load(const char *Directory)
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 -----------------------------------------------------------------
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
* 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
@ -402,7 +402,17 @@ private:
mutable int allocated;
mutable int size;
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:
cVector(int Allocated = 10)
{
@ -414,8 +424,9 @@ public:
virtual ~cVector() { free(data); }
T& At(int Index) const
{
Realloc(Index);
if (Index >= size)
Realloc(size = Index + 1);
size = Index + 1;
return data[Index];
}
const T& operator[](int Index) const
@ -427,12 +438,24 @@ public:
return At(Index);
}
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)
{
if (size >= allocated)
Realloc(allocated * 4 / 2); // increase size by 50%
data[size++] = Data;
}
virtual void Clear(void) {}
void Sort(__compar_fn_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);
}
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:
cFileNameList(const char *Directory = NULL);
virtual ~cFileNameList();
bool Load(const char *Directory);
int Find(const char *FileName);
};
class cHashObject : public cListObject {