vdr/font.c
Klaus Schmidinger b81bf2d1c9 Version 1.3.9
- Completed Croatian language texts (thanks to Drazen Dupor).
- New iso8859-2 font to fix the problem with program freezes (thanks to Drazen Dupor).
- Implemented a default cRemote::Initialize() that waits 10 seconds for a keypress
  in order to prevent a "hangup" in case, e.g., the LIRC driver is not loaded (thanks
  to Helmut Auer).
- Updated 'channels.conf.terr' for Hannover (thanks to Peter Waechtler).
- cBitmap::DrawBitmap() now also resets the palette if the entire bitmap area is
  covered (suggested by Sascha Volkenandt).
- Fixed setting the title in the replay display of the "Classic VDR" skin in case
  a shorter title is set after a longer one (thanks to Stefan Huelswitt for
  reporting this one).
- Now using more separate areas in the "ST:TNG Panels" skin to allow a theme to
  use more independent clrMenu* colors.
- Fixed removing the "scanning recordings..." message in case the video directory
  is empty (thanks to Andreas Regel for reporting this one).
- Added SetMessage() functions to the Replay and Channel skin functions. Plugins
  that implement skins will need to implement these functions. This fixes a missing
  "Editing process finished" message (thanks to Oliver Endriss for reporting this
  one).
- Fixed the height of the channel display in the "Classic VDR" skin.
- Fixed handling descriptor loops in 'libsi', which had sometimes caused invalid
  CA ids to be added to the channel definitions (thanks to Wayne Keer for reporting
  this one, and Marcel Wiesweg for fixing it).
- Fixed handling colors in cDvbSpuPalette::yuv2rgb() (thanks to Marco Schlüßler).
- Made some functions of cFont virtual to allow implementing dummy fonts for the
  'curses' skin.
- The new plugin 'skincurses' re-implements the functionality that was previously
  available by compiling VDR with DEBUG_OSD. Some things may not yet work as they
  should, but it's a starting point.
2004-05-31 18:00:00 +02:00

240 lines
5.0 KiB
C

/*
* font.c: Font handling for the DVB On Screen Display
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: font.c 1.8 2004/05/31 09:55:37 kls Exp $
*/
#include "config.h"
#include <ctype.h>
#include "font.h"
#include "tools.h"
#include "fontfix.c"
#include "fontosd.c"
#include "fontsml.c"
#include "fontfix-iso8859-2.c"
#include "fontosd-iso8859-2.c"
#include "fontsml-iso8859-2.c"
#include "fontfix-iso8859-5.c"
#include "fontosd-iso8859-5.c"
#include "fontsml-iso8859-5.c"
#include "fontfix-iso8859-7.c"
#include "fontosd-iso8859-7.c"
#include "fontsml-iso8859-7.c"
// --- cFont -----------------------------------------------------------------
static void *FontData[eDvbCodeSize][eDvbFontSize] = {
{ FontOsd_iso8859_1, FontFix_iso8859_1, FontSml_iso8859_1 },
{ FontOsd_iso8859_2, FontFix_iso8859_2, FontSml_iso8859_2 },
{ FontOsd_iso8859_5, FontFix_iso8859_5, FontSml_iso8859_5 },
{ FontOsd_iso8859_7, FontFix_iso8859_7, FontSml_iso8859_7 },
};
static const char *FontCode[eDvbCodeSize] = {
"iso8859-1",
"iso8859-2",
"iso8859-5",
"iso8859-7",
};
eDvbCode cFont::code = code_iso8859_1;
cFont *cFont::fonts[eDvbFontSize] = { NULL };
cFont::cFont(void *Data)
{
SetData(Data);
}
void cFont::SetData(void *Data)
{
if (Data) {
height = ((tCharData *)Data)->height;
for (int i = 0; i < NUMCHARS; i++)
data[i] = (tCharData *)&((tPixelData *)Data)[(i < 32 ? 0 : i - 32) * (height + 2)];
}
else
height = 0;
}
int cFont::Width(const char *s) const
{
int w = 0;
while (s && *s)
w += Width(*s++);
return w;
}
int cFont::Height(const char *s) const
{
int h = 0;
if (s && *s)
h = height; // all characters have the same height!
return h;
}
bool cFont::SetCode(const char *Code)
{
for (int i = 0; i < eDvbCodeSize; i++) {
if (strcmp(Code, FontCode[i]) == 0) {
SetCode(eDvbCode(i));
return true;
}
}
return false;
}
void cFont::SetCode(eDvbCode Code)
{
if (code != Code) {
code = Code;
for (int i = 0; i < eDvbFontSize; i++) {
if (fonts[i])
fonts[i]->SetData(FontData[code][i]);
}
}
}
void cFont::SetFont(eDvbFont Font, void *Data)
{
delete fonts[Font];
fonts[Font] = new cFont(Data ? Data : FontData[code][Font]);
}
const cFont *cFont::GetFont(eDvbFont Font)
{
if (Setup.UseSmallFont == 0 && Font == fontSml)
Font = fontOsd;
else if (Setup.UseSmallFont == 2 && Font == fontOsd)
Font = fontSml;
if (!fonts[Font])
SetFont(Font);
return fonts[Font];
}
// --- cTextWrapper ----------------------------------------------------------
cTextWrapper::cTextWrapper(void)
{
text = eol = NULL;
lines = 0;
lastLine = -1;
}
cTextWrapper::cTextWrapper(const char *Text, const cFont *Font, int Width)
{
text = NULL;
Set(Text, Font, Width);
}
cTextWrapper::~cTextWrapper()
{
free(text);
}
void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
{
free(text);
text = Text ? strdup(Text) : NULL;
eol = NULL;
lines = 0;
lastLine = -1;
if (!text)
return;
lines = 1;
if (Width <= 0)
return;
char *Blank = NULL;
char *Delim = NULL;
int w = 0;
stripspace(text); // strips trailing newlines
for (char *p = text; *p; ) {
if (*p == '\n') {
lines++;
w = 0;
Blank = Delim = NULL;
p++;
continue;
}
else if (isspace(*p))
Blank = p;
int cw = Font->Width(*p);
if (w + cw > Width) {
if (Blank) {
*Blank = '\n';
p = Blank;
continue;
}
else {
// Here's the ugly part, where we don't have any whitespace to
// punch in a newline, so we need to make room for it:
if (Delim)
p = Delim + 1; // let's fall back to the most recent delimiter
char *s = MALLOC(char, strlen(text) + 2); // The additional '\n' plus the terminating '\0'
int l = p - text;
strncpy(s, text, l);
s[l] = '\n';
strcpy(s + l + 1, p);
free(text);
text = s;
p = text + l;
continue;
}
}
else
w += cw;
if (strchr("-.,:;!?_", *p)) {
Delim = p;
Blank = NULL;
}
p++;
}
}
const char *cTextWrapper::Text(void)
{
if (eol) {
*eol = '\n';
eol = NULL;
}
return text;
}
const char *cTextWrapper::GetLine(int Line)
{
char *s = NULL;
if (Line < lines) {
if (eol) {
*eol = '\n';
if (Line == lastLine + 1)
s = eol + 1;
eol = NULL;
}
if (!s) {
s = text;
for (int i = 0; i < Line; i++) {
s = strchr(s, '\n');
if (s)
s++;
else
break;
}
}
if (s) {
if ((eol = strchr(s, '\n')) != NULL)
*eol = 0;
}
lastLine = Line;
}
return s;
}