mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Freetype font support; full UTF-8 support; dropped pixel fonts
This commit is contained in:
parent
32dd727d05
commit
c6f8a14957
@ -2083,3 +2083,7 @@ Oktay Yolge
|
||||
|
||||
Krzysztof Parma <krzycho@zoz.wodzislaw.pl>
|
||||
for suggesting to implement the SVDRP command REMO
|
||||
|
||||
Alexander Riedel <alexander-riedel@t-online.de>
|
||||
for a patch that was used as a base to implement support for Freetype fonts and
|
||||
UTF-8 handling
|
||||
|
30
HISTORY
30
HISTORY
@ -5180,7 +5180,7 @@ Video Disk Recorder Revision History
|
||||
|
||||
- Official release.
|
||||
|
||||
2007-05-12: Version 1.5.3
|
||||
2007-06-10: Version 1.5.3
|
||||
|
||||
- Fixed some spelling errors in 'newplugin' (thanks to Ville Skyttä).
|
||||
- Fixed a busy loop in fast forward if the next video data file is missing
|
||||
@ -5198,3 +5198,31 @@ Video Disk Recorder Revision History
|
||||
- Increased the maximum number of CA system ids to cope with the AlphaCrypt
|
||||
CAM's version 3.11 firmware.
|
||||
- Fixed getting the code setting from the locale (thanks to Matthias Schwarzott).
|
||||
- Implemented support for Freetype fonts (based on a patch from Alexander Riedel).
|
||||
- If the OSD device in use has at least 8bpp bitmap depth and this is also
|
||||
used by the current skin, Freetype fonts are displayed "anti-aliased".
|
||||
The new setup parameter "OSD/Anti-alias" can be used to turn this off.
|
||||
- The new function cOsd::SetAntiAliasGranularity() can be used to help the OSD
|
||||
in managing the available color palette entries when doing anti-aliasing.
|
||||
Skins that use 8bpp bitmaps can call this function with the maximum number
|
||||
of colors used, and the maximum number of color combinations. The OSD will
|
||||
then evenly split the available palette entries between the various colors
|
||||
combinations, so that fonts can be "anti-aliased". By default a total of
|
||||
10 colors and 10 combinations is assumed.
|
||||
- The pixel fonts have been completely removed from the VDR source.
|
||||
- VDR is now "UTF-8 aware". It handles strings according to the character
|
||||
encoding used on the user's system. All internationalization strings and
|
||||
incoming SI data are converted to the system encoding.
|
||||
- Plugins that handle strings need to be aware that on systems with UTF-8
|
||||
encoding a "character symbol" may consist of more than a single byte in
|
||||
memory. The functions and macros named Utf8...() can be used to handle
|
||||
strings without needing to care about the underlying character encoding
|
||||
(see tools.h for details).
|
||||
- Even though the weekdays of repeating timers are presented to the user as UTF-8
|
||||
characters in the OSD, the timers.conf file and the SVDRP timer commands still
|
||||
use single byte characters ("MTWTFSS") to make sure this information is handled
|
||||
correctly between systems with different character encodings.
|
||||
- Added a missing i18n string for "CAM" in the Turkish OSD texts.
|
||||
- Improved editing strings that are too long to fit into the editable area.
|
||||
- Changes to the OSD settings in the "Setup/OSD" menu now immediately take effect
|
||||
when the "Ok" key is pressed.
|
||||
|
17
INSTALL
17
INSTALL
@ -35,11 +35,18 @@ Refer to http://linuxtv.org for more information about the Linux-DVB driver.
|
||||
VDR requires the Linux-DVB driver version dated 2003-08-23 or higher
|
||||
to work properly.
|
||||
|
||||
You will also need to install the "libjpeg" and "libcap" libraries,
|
||||
as well as their "devel" packages to get the necessary header files
|
||||
for compiling VDR. If the "capability" module is not compiled into
|
||||
your kernel, you may need to do "modprobe capability" before running
|
||||
VDR.
|
||||
You will also need to install the following libraries, as well as their
|
||||
"devel" packages to get the necessary header files for compiling VDR:
|
||||
|
||||
freetype2
|
||||
libcap
|
||||
libjpeg
|
||||
|
||||
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
|
||||
|
17
MANUAL
17
MANUAL
@ -503,6 +503,23 @@ Version 1.4
|
||||
current skin wants to, and 2 means always use the small
|
||||
font.
|
||||
|
||||
Anti-alias = 1 Controls whether the OSD uses "anti-aliasing" to improve
|
||||
font rendering. To make this work, the OSD must support
|
||||
at least 256 colors, and the skin in use has to
|
||||
utilize these. If either of these conditions is not met,
|
||||
rendering will be done without anti-aliasing.
|
||||
|
||||
OSD font name = arialbd.ttf
|
||||
Small font name = arial.ttf
|
||||
Fixed font name = courbd.ttf
|
||||
The file names of the various fonts to use.
|
||||
|
||||
OSD font size = 22
|
||||
Small font size = 18
|
||||
Fixed font size = 20
|
||||
The sizes (in pixel) of the various fonts. Valid range is
|
||||
10...64.
|
||||
|
||||
Channel info position = bottom
|
||||
The position of the channel info window in the OSD
|
||||
(either 'bottom' or 'top').
|
||||
|
105
Makefile
105
Makefile
@ -4,7 +4,7 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Makefile 1.99 2007/03/11 10:22:18 kls Exp $
|
||||
# $Id: Makefile 1.100 2007/05/28 11:22:42 kls Exp $
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
@ -17,8 +17,8 @@ CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual
|
||||
LSIDIR = ./libsi
|
||||
MANDIR = /usr/local/man
|
||||
BINDIR = /usr/local/bin
|
||||
LIBS = -ljpeg -lpthread -ldl -lcap
|
||||
INCLUDES =
|
||||
LIBS = -ljpeg -lpthread -ldl -lcap -lfreetype
|
||||
INCLUDES = -I/usr/include/freetype2
|
||||
|
||||
PLUGINDIR= ./PLUGINS
|
||||
PLUGINLIBDIR= $(PLUGINDIR)/lib
|
||||
@ -39,34 +39,6 @@ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o d
|
||||
skinclassic.o skins.o skinsttng.o sources.o spu.o status.o svdrp.o themes.o thread.o\
|
||||
timers.o tools.o transfer.o vdr.o videodir.o
|
||||
|
||||
FIXFONT_ISO8859_1 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-1
|
||||
OSDFONT_ISO8859_1 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
|
||||
SMLFONT_ISO8859_1 = -adobe-helvetica-medium-r-normal--18-*-100-100-p-*-iso8859-1
|
||||
|
||||
FIXFONT_ISO8859_2 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-2
|
||||
OSDFONT_ISO8859_2 = -adobe-helvetica-medium-r-normal--24-*-75-75-p-*-iso8859-2
|
||||
SMLFONT_ISO8859_2 = -adobe-helvetica-medium-r-normal--18-*-75-75-p-*-iso8859-2
|
||||
|
||||
FIXFONT_ISO8859_5 = -rfx-courier-bold-r-normal--24-*-75-75-m-*-iso8859-5
|
||||
OSDFONT_ISO8859_5 = -rfx-helvetica-medium-r-normal--24-*-75-75-p-*-iso8859-5
|
||||
SMLFONT_ISO8859_5 = -rfx-helvetica-medium-r-normal--18-*-75-75-p-*-iso8859-5
|
||||
|
||||
FIXFONT_ISO8859_7 = --user-medium-r-normal--26-171-110-110-m-140-iso8859-7
|
||||
OSDFONT_ISO8859_7 = --user-medium-r-normal--23-179-85-85-m-120-iso8859-7
|
||||
SMLFONT_ISO8859_7 = --user-medium-r-normal--19-160-72-72-m-110-iso8859-7
|
||||
|
||||
FIXFONT_ISO8859_9 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-9
|
||||
OSDFONT_ISO8859_9 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-9
|
||||
SMLFONT_ISO8859_9 = -adobe-helvetica-medium-r-normal--18-*-100-100-p-*-iso8859-9
|
||||
|
||||
FIXFONT_ISO8859_13 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-13
|
||||
OSDFONT_ISO8859_13 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-13
|
||||
SMLFONT_ISO8859_13 = -adobe-helvetica-medium-r-normal--18-*-100-100-p-*-iso8859-13
|
||||
|
||||
FIXFONT_ISO8859_15 = -adobe-courier-bold-r-normal--25-*-100-100-m-*-iso8859-15
|
||||
OSDFONT_ISO8859_15 = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-15
|
||||
SMLFONT_ISO8859_15 = -adobe-helvetica-medium-r-normal--18-*-100-100-p-*-iso8859-15
|
||||
|
||||
ifndef NO_KBD
|
||||
DEFINES += -DREMOTE_KBD
|
||||
endif
|
||||
@ -98,15 +70,6 @@ DEFINES += -DVFAT
|
||||
endif
|
||||
|
||||
all: vdr
|
||||
font: genfontfile\
|
||||
fontfix-iso8859-1.c fontosd-iso8859-1.c fontsml-iso8859-1.c\
|
||||
fontfix-iso8859-2.c fontosd-iso8859-2.c fontsml-iso8859-2.c\
|
||||
fontfix-iso8859-5.c fontosd-iso8859-5.c fontsml-iso8859-5.c\
|
||||
fontfix-iso8859-7.c fontosd-iso8859-7.c fontsml-iso8859-7.c\
|
||||
fontfix-iso8859-9.c fontosd-iso8859-9.c fontsml-iso8859-9.c\
|
||||
fontfix-iso8859-13.c fontosd-iso8859-13.c fontsml-iso8859-13.c\
|
||||
fontfix-iso8859-15.c fontosd-iso8859-15.c fontsml-iso8859-15.c
|
||||
@echo "font files created."
|
||||
|
||||
# Implicit rules:
|
||||
|
||||
@ -127,62 +90,6 @@ $(DEPFILE): Makefile
|
||||
vdr: $(OBJS) $(SILIB)
|
||||
$(CXX) $(CXXFLAGS) -rdynamic $(OBJS) $(NCURSESLIB) $(LIBS) $(LIBDIRS) $(SILIB) -o vdr
|
||||
|
||||
# The font files:
|
||||
|
||||
fontfix-iso8859-1.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_1" "$(FIXFONT_ISO8859_1)" > $@
|
||||
fontosd-iso8859-1.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_1" "$(OSDFONT_ISO8859_1)" > $@
|
||||
fontsml-iso8859-1.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_1" "$(SMLFONT_ISO8859_1)" > $@
|
||||
|
||||
fontfix-iso8859-2.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_2" "$(FIXFONT_ISO8859_2)" > $@
|
||||
fontosd-iso8859-2.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_2" "$(OSDFONT_ISO8859_2)" > $@
|
||||
fontsml-iso8859-2.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_2" "$(SMLFONT_ISO8859_2)" > $@
|
||||
|
||||
fontfix-iso8859-5.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_5" "$(FIXFONT_ISO8859_5)" > $@
|
||||
fontosd-iso8859-5.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_5" "$(OSDFONT_ISO8859_5)" > $@
|
||||
fontsml-iso8859-5.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_5" "$(SMLFONT_ISO8859_5)" > $@
|
||||
|
||||
fontfix-iso8859-7.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_7" "$(FIXFONT_ISO8859_7)" > $@
|
||||
fontosd-iso8859-7.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_7" "$(OSDFONT_ISO8859_7)" > $@
|
||||
fontsml-iso8859-7.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_7" "$(SMLFONT_ISO8859_7)" > $@
|
||||
|
||||
fontfix-iso8859-9.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_9" "$(FIXFONT_ISO8859_9)" > $@
|
||||
fontosd-iso8859-9.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_9" "$(OSDFONT_ISO8859_9)" > $@
|
||||
fontsml-iso8859-9.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_9" "$(SMLFONT_ISO8859_9)" > $@
|
||||
|
||||
fontfix-iso8859-13.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_13" "$(FIXFONT_ISO8859_13)" > $@
|
||||
fontosd-iso8859-13.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_13" "$(OSDFONT_ISO8859_13)" > $@
|
||||
fontsml-iso8859-13.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_13" "$(SMLFONT_ISO8859_13)" > $@
|
||||
|
||||
fontfix-iso8859-15.c:
|
||||
./genfontfile "cFont::tPixelData FontFix_iso8859_15" "$(FIXFONT_ISO8859_15)" > $@
|
||||
fontosd-iso8859-15.c:
|
||||
./genfontfile "cFont::tPixelData FontOsd_iso8859_15" "$(OSDFONT_ISO8859_15)" > $@
|
||||
fontsml-iso8859-15.c:
|
||||
./genfontfile "cFont::tPixelData FontSml_iso8859_15" "$(SMLFONT_ISO8859_15)" > $@
|
||||
|
||||
# The font file generator:
|
||||
|
||||
genfontfile: genfontfile.c
|
||||
$(CC) $(CFLAGS) -o $@ -L/usr/X11R6/lib $< -lX11
|
||||
|
||||
# The libsi library:
|
||||
|
||||
$(SILIB):
|
||||
@ -261,10 +168,8 @@ srcdoc:
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(LSIDIR) clean
|
||||
-rm -f $(OBJS) $(DEPFILE) vdr genfontfile genfontfile.o core* *~
|
||||
-rm -f $(OBJS) $(DEPFILE) vdr core* *~
|
||||
-rm -rf include
|
||||
-rm -rf srcdoc
|
||||
fontclean:
|
||||
-rm -f fontfix*.c fontosd*.c fontsml*.c
|
||||
CLEAN: clean fontclean
|
||||
CLEAN: clean
|
||||
|
||||
|
45
PLUGINS.html
45
PLUGINS.html
@ -6,7 +6,7 @@
|
||||
|
||||
<center><h1>The VDR Plugin System</h1></center>
|
||||
|
||||
<center><b>Version 1.5.1</b></center>
|
||||
<center><b>Version 1.5.3</b></center>
|
||||
<p>
|
||||
<center>
|
||||
Copyright © 2006 Klaus Schmidinger<br>
|
||||
@ -14,12 +14,15 @@ Copyright © 2006 Klaus Schmidinger<br>
|
||||
<a href="http://www.cadsoft.de/vdr">www.cadsoft.de/vdr</a>
|
||||
</center>
|
||||
<p>
|
||||
<!--X1.5.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||
<!--X1.5.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||
Important modifications introduced in version 1.5.0 are marked like this.
|
||||
<!--X1.5.0--></td></tr></table>
|
||||
<!--X1.5.1--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
<!--X1.5.1--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||
Important modifications introduced in version 1.5.1 are marked like this.
|
||||
<!--X1.5.1--></td></tr></table>
|
||||
<!--X1.5.3--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
Important modifications introduced in version 1.5.3 are marked like this.
|
||||
<!--X1.5.3--></td></tr></table>
|
||||
<p>
|
||||
VDR provides an easy to use plugin interface that allows additional functionality
|
||||
to be added to the program by implementing a dynamically loadable library file.
|
||||
@ -58,7 +61,7 @@ structures and allows it to hook itself into specific areas to perform special a
|
||||
<li><a href="#Housekeeping">Housekeeping</a>
|
||||
<li><a href="#Main thread hook">Main thread hook</a>
|
||||
<li><a href="#Activity">Activity</a>
|
||||
<!--X1.5.1--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
<!--X1.5.1--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||
<li><a href="#Wakeup">Wakeup</a>
|
||||
<!--X1.5.1--></td></tr></table>
|
||||
<li><a href="#Setup parameters">Setup parameters</a>
|
||||
@ -82,7 +85,7 @@ structures and allows it to hook itself into specific areas to perform special a
|
||||
<li><a href="#Devices">Devices</a>
|
||||
<li><a href="#Audio">Audio</a>
|
||||
<li><a href="#Remote Control">Remote Control</a>
|
||||
<!--X1.5.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||
<!--X1.5.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||
<li><a href="#Conditional Access">Conditional Access</a>
|
||||
<!--X1.5.0--></td></tr></table>
|
||||
</ul>
|
||||
@ -681,7 +684,7 @@ be queried, and further prompts may show up. If all prompts have been confirmed,
|
||||
the shutdown will take place. As soon as one prompt is not confirmed, no
|
||||
further plugins will be queried and no shutdown will be done.
|
||||
|
||||
<!--X1.5.1--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
<!--X1.5.1--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||
<a name="Wakeup"><hr><h2>Wakeup</h2>
|
||||
|
||||
<center><i><b>Wake me up before you go-go</b></i></center><p>
|
||||
@ -970,6 +973,19 @@ written to the log file, indicating that a translation is missing.
|
||||
Texts are first searched for in the <i>Phrases</i> registered for this plugin (if any)
|
||||
and then in the global VDR texts. So a plugin can make use of texts defined by the
|
||||
core VDR code.
|
||||
<p>
|
||||
<!--X1.5.3--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
The system VDR is running on may use a character encoding where a single character
|
||||
(or <i>symbol</i>) consists of more than one byte (UTF-8, as opposed to, for instance,
|
||||
ISO8859-1, where every character is represented by a single byte in memory).
|
||||
In order to make sure a plugin works regardless of the character encoding the current
|
||||
system uses, the VDR core code provides several functions and macros that allow accessing
|
||||
text strings transparently without knowing whether this is a single or multi byte
|
||||
character set. The names of these functions and macros are all of the form <tt>Utf8...()</tt>,
|
||||
and are defined in <tt>VDR/tools.h</tt>.
|
||||
Most of the time a plugin doesn't need to care about this, but when it comes to
|
||||
handling individual characters these functions may come in handy.
|
||||
<!--X1.5.3--></td></tr></table>
|
||||
|
||||
<a name="Custom services"><hr><h2>Custom services</h2>
|
||||
|
||||
@ -1618,7 +1634,22 @@ Note that a plugin should always at first request a single drawing area
|
||||
with the full required resolution. Only if this fails shall it use alternate
|
||||
areas. Drawing areas are always rectangular and may not overlap (but do not need
|
||||
to be adjacent).
|
||||
<p>
|
||||
<!--X1.5.3--><table width=100%><tr><td bgcolor=#FF0000> </td><td width=100%>
|
||||
Special consideration may have to be given to color usage if the OSD provides
|
||||
8bpp (256 colors). In that case, fonts may be drawn using <i>anti-aliasing</i>,
|
||||
which requires several blended color values between the foreground and background
|
||||
color. In order to not use up the whole color palette for a single color
|
||||
combination (and thus be unable to draw any other colors at all), it may be
|
||||
useful to call
|
||||
|
||||
<p><table><tr><td bgcolor=#F0F0F0><pre>
|
||||
osd->SetAntiAliasGranularity();
|
||||
</pre></td></tr></table><p>
|
||||
|
||||
which allows the system to evenly distribute the palette entries to the various
|
||||
color combinations (see <tt>VDR/osd.h</tt> for details).
|
||||
<!--X1.5.3--></td></tr></table>
|
||||
<p>
|
||||
Directly accessing the OSD is only allowed from the foreground thread, which
|
||||
restricts this to a <tt>cOsdObject</tt> returned from the plugin's <tt>MainMenuAction()</tt>
|
||||
@ -2087,7 +2118,7 @@ Put(uint64 Code, bool Repeat = false, bool Release = false);
|
||||
|
||||
The other parameters have the same meaning as in the first version of this function.
|
||||
|
||||
<!--X1.5.0--><table width=100%><tr><td bgcolor=#AA0000> </td><td width=100%>
|
||||
<!--X1.5.0--><table width=100%><tr><td bgcolor=#00AA00> </td><td width=100%>
|
||||
<a name="Conditional Access"><hr><h2>Conditional Access</h2>
|
||||
|
||||
<center><i><b>Members only!</b></i></center><p>
|
||||
|
23
config.c
23
config.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.c 1.150 2007/02/25 13:58:45 kls Exp $
|
||||
* $Id: config.c 1.151 2007/06/02 11:21:40 kls Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@ -264,6 +264,13 @@ cSetup::cSetup(void)
|
||||
OSDHeight = 486;
|
||||
OSDMessageTime = 1;
|
||||
UseSmallFont = 1;
|
||||
AntiAlias = 1;
|
||||
strcpy(FontOsd, "arialbd.ttf");
|
||||
strcpy(FontSml, "arial.ttf");
|
||||
strcpy(FontFix, "courbd.ttf");
|
||||
FontOsdSize = 22;
|
||||
FontSmlSize = 18;
|
||||
FontFixSize = 20;
|
||||
MaxVideoFileSize = MAXVIDEOFILESIZE;
|
||||
SplitEditedFiles = 0;
|
||||
MinEventTimeout = 30;
|
||||
@ -427,6 +434,13 @@ bool cSetup::Parse(const char *Name, const char *Value)
|
||||
else if (!strcasecmp(Name, "OSDHeight")) { OSDHeight = atoi(Value); if (OSDHeight < 100) OSDHeight *= 27; }
|
||||
else if (!strcasecmp(Name, "OSDMessageTime")) OSDMessageTime = atoi(Value);
|
||||
else if (!strcasecmp(Name, "UseSmallFont")) UseSmallFont = atoi(Value);
|
||||
else if (!strcasecmp(Name, "AntiAlias")) AntiAlias = atoi(Value);
|
||||
else if (!strcasecmp(Name, "FontOsd")) strn0cpy(FontOsd, Value, MAXFONTNAME);
|
||||
else if (!strcasecmp(Name, "FontSml")) strn0cpy(FontSml, Value, MAXFONTNAME);
|
||||
else if (!strcasecmp(Name, "FontFix")) strn0cpy(FontFix, Value, MAXFONTNAME);
|
||||
else if (!strcasecmp(Name, "FontOsdSize")) FontOsdSize = atoi(Value);
|
||||
else if (!strcasecmp(Name, "FontSmlSize")) FontSmlSize = atoi(Value);
|
||||
else if (!strcasecmp(Name, "FontFixSize")) FontFixSize = atoi(Value);
|
||||
else if (!strcasecmp(Name, "MaxVideoFileSize")) MaxVideoFileSize = atoi(Value);
|
||||
else if (!strcasecmp(Name, "SplitEditedFiles")) SplitEditedFiles = atoi(Value);
|
||||
else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value);
|
||||
@ -497,6 +511,13 @@ bool cSetup::Save(void)
|
||||
Store("OSDHeight", OSDHeight);
|
||||
Store("OSDMessageTime", OSDMessageTime);
|
||||
Store("UseSmallFont", UseSmallFont);
|
||||
Store("AntiAlias", AntiAlias);
|
||||
Store("FontOsd", FontOsd);
|
||||
Store("FontSml", FontSml);
|
||||
Store("FontFix", FontFix);
|
||||
Store("FontOsdSize", FontOsdSize);
|
||||
Store("FontSmlSize", FontSmlSize);
|
||||
Store("FontFixSize", FontFixSize);
|
||||
Store("MaxVideoFileSize", MaxVideoFileSize);
|
||||
Store("SplitEditedFiles", SplitEditedFiles);
|
||||
Store("MinEventTimeout", MinEventTimeout);
|
||||
|
10
config.h
10
config.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.h 1.289 2007/04/28 14:47:24 kls Exp $
|
||||
* $Id: config.h 1.290 2007/06/02 11:22:17 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
@ -17,6 +17,7 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "i18n.h"
|
||||
#include "font.h"
|
||||
#include "tools.h"
|
||||
|
||||
// VDR's own version number:
|
||||
@ -242,6 +243,13 @@ public:
|
||||
int OSDLeft, OSDTop, OSDWidth, OSDHeight;
|
||||
int OSDMessageTime;
|
||||
int UseSmallFont;
|
||||
int AntiAlias;
|
||||
char FontOsd[MAXFONTNAME];
|
||||
char FontSml[MAXFONTNAME];
|
||||
char FontFix[MAXFONTNAME];
|
||||
int FontOsdSize;
|
||||
int FontSmlSize;
|
||||
int FontFixSize;
|
||||
int MaxVideoFileSize;
|
||||
int SplitEditedFiles;
|
||||
int MinEventTimeout, MinUserInactivity;
|
||||
|
9
eit.c
9
eit.c
@ -8,7 +8,7 @@
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
|
||||
*
|
||||
* $Id: eit.c 1.122 2006/10/09 16:14:36 kls Exp $
|
||||
* $Id: eit.c 1.123 2007/06/10 12:51:05 kls Exp $
|
||||
*/
|
||||
|
||||
#include "eit.h"
|
||||
@ -188,6 +188,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
|
||||
if (hit) {
|
||||
char linkName[ld->privateData.getLength() + 1];
|
||||
strn0cpy(linkName, (const char *)ld->privateData.getData(), sizeof(linkName));
|
||||
// TODO is there a standard way to determine the character set of this string?
|
||||
cChannel *link = Channels.GetByChannelID(linkID);
|
||||
if (link != channel) { // only link to other channels, not the same one
|
||||
//fprintf(stderr, "Linkage %s %4d %4d %5d %5d %5d %5d %02X '%s'\n", hit ? "*" : "", channel->Number(), link ? link->Number() : -1, SiEitEvent.getEventId(), ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId(), ld->getLinkageType(), linkName);//XXX
|
||||
@ -218,7 +219,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
|
||||
if (1 <= Stream && Stream <= 2 && Type != 0) {
|
||||
if (!Components)
|
||||
Components = new cComponents;
|
||||
char buffer[256];
|
||||
char buffer[Utf8BufSize(256)];
|
||||
Components->SetComponent(Components->NumComponents(), cd->getStreamContent(), cd->getComponentType(), I18nNormalizeLanguageCode(cd->languageCode), cd->description.getText(buffer, sizeof(buffer)));
|
||||
}
|
||||
}
|
||||
@ -230,7 +231,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
|
||||
|
||||
if (!rEvent) {
|
||||
if (ShortEventDescriptor) {
|
||||
char buffer[256];
|
||||
char buffer[Utf8BufSize(256)];
|
||||
pEvent->SetTitle(ShortEventDescriptor->name.getText(buffer, sizeof(buffer)));
|
||||
pEvent->SetShortText(ShortEventDescriptor->text.getText(buffer, sizeof(buffer)));
|
||||
}
|
||||
@ -239,7 +240,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo
|
||||
pEvent->SetShortText(NULL);
|
||||
}
|
||||
if (ExtendedEventDescriptors) {
|
||||
char buffer[ExtendedEventDescriptors->getMaximumTextLength(": ") + 1];
|
||||
char buffer[Utf8BufSize(ExtendedEventDescriptors->getMaximumTextLength(": ")) + 1];
|
||||
pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, sizeof(buffer), ": "));
|
||||
}
|
||||
else if (!HasExternalData)
|
||||
|
4
epg.c
4
epg.c
@ -7,7 +7,7 @@
|
||||
* Original version (as used in VDR before 1.3.0) written by
|
||||
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
|
||||
*
|
||||
* $Id: epg.c 1.81 2006/10/28 09:12:42 kls Exp $
|
||||
* $Id: epg.c 1.82 2007/06/10 12:52:19 kls Exp $
|
||||
*/
|
||||
|
||||
#include "epg.h"
|
||||
@ -634,6 +634,7 @@ Final:
|
||||
// data, so let's always convert them to blanks (independent of the setting of EPGBugfixLevel):
|
||||
strreplace(title, '\n', ' ');
|
||||
strreplace(shortText, '\n', ' ');
|
||||
/* TODO adapt to UTF-8
|
||||
// Same for control characters:
|
||||
strreplace(title, '\x86', ' ');
|
||||
strreplace(title, '\x87', ' ');
|
||||
@ -641,6 +642,7 @@ Final:
|
||||
strreplace(shortText, '\x87', ' ');
|
||||
strreplace(description, '\x86', ' ');
|
||||
strreplace(description, '\x87', ' ');
|
||||
XXX*/
|
||||
}
|
||||
|
||||
// --- cSchedule -------------------------------------------------------------
|
||||
|
368
font.c
368
font.c
@ -4,125 +4,296 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: font.c 1.14 2007/03/11 09:51:44 kls Exp $
|
||||
* $Id: font.c 1.15 2007/06/09 14:41:27 kls Exp $
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include "font.h"
|
||||
#include <ctype.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "config.h"
|
||||
#include "osd.h"
|
||||
#include "tools.h"
|
||||
|
||||
#include "fontfix-iso8859-1.c"
|
||||
#include "fontosd-iso8859-1.c"
|
||||
#include "fontsml-iso8859-1.c"
|
||||
// --- cFreetypeFont ---------------------------------------------------------
|
||||
|
||||
#include "fontfix-iso8859-2.c"
|
||||
#include "fontosd-iso8859-2.c"
|
||||
#include "fontsml-iso8859-2.c"
|
||||
#define KERNING_UNKNOWN (-10000)
|
||||
|
||||
#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"
|
||||
|
||||
#include "fontfix-iso8859-9.c"
|
||||
#include "fontosd-iso8859-9.c"
|
||||
#include "fontsml-iso8859-9.c"
|
||||
|
||||
#include "fontfix-iso8859-13.c"
|
||||
#include "fontosd-iso8859-13.c"
|
||||
#include "fontsml-iso8859-13.c"
|
||||
|
||||
#include "fontfix-iso8859-15.c"
|
||||
#include "fontosd-iso8859-15.c"
|
||||
#include "fontsml-iso8859-15.c"
|
||||
|
||||
// --- cFont -----------------------------------------------------------------
|
||||
|
||||
static const void *const 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 },
|
||||
{ FontOsd_iso8859_9, FontFix_iso8859_9, FontSml_iso8859_9 },
|
||||
{ FontOsd_iso8859_13, FontFix_iso8859_13, FontSml_iso8859_13 },
|
||||
{ FontOsd_iso8859_15, FontFix_iso8859_15, FontSml_iso8859_15 },
|
||||
struct tKerning {
|
||||
uint prevSym;
|
||||
int kerning;
|
||||
tKerning(uint PrevSym, int Kerning) { prevSym = PrevSym; kerning = Kerning; }
|
||||
};
|
||||
|
||||
static const char *FontCode[eDvbCodeSize] = {
|
||||
"iso8859-1",
|
||||
"iso8859-2",
|
||||
"iso8859-5",
|
||||
"iso8859-7",
|
||||
"iso8859-9",
|
||||
"iso8859-13",
|
||||
"iso8859-15",
|
||||
class cGlyph : public cListObject {
|
||||
private:
|
||||
uint charCode;
|
||||
uchar *bitmap;
|
||||
int advanceX;
|
||||
int advanceY;
|
||||
int left; ///< The bitmap's left bearing expressed in integer pixels.
|
||||
int top; ///< The bitmap's top bearing expressed in integer pixels.
|
||||
int width; ///< The number of pixels per bitmap row.
|
||||
int rows; ///< The number of bitmap rows.
|
||||
int pitch; ///< The pitch's absolute value is the number of bytes taken by one bitmap row, including padding.
|
||||
cVector<tKerning> kerningCache;
|
||||
public:
|
||||
cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData);
|
||||
virtual ~cGlyph();
|
||||
uint CharCode(void) const { return charCode; }
|
||||
uchar *Bitmap(void) const { return bitmap; }
|
||||
int AdvanceX(void) const { return advanceX; }
|
||||
int AdvanceY(void) const { return advanceY; }
|
||||
int Left(void) const { return left; }
|
||||
int Top(void) const { return top; }
|
||||
int Width(void) const { return width; }
|
||||
int Rows(void) const { return rows; }
|
||||
int Pitch(void) const { return pitch; }
|
||||
int GetKerningCache(uint PrevSym) const;
|
||||
void SetKerningCache(uint PrevSym, int Kerning);
|
||||
};
|
||||
|
||||
eDvbCode cFont::code = code_iso8859_1;
|
||||
cFont *cFont::fonts[eDvbFontSize] = { NULL };
|
||||
|
||||
cFont::cFont(const void *Data)
|
||||
cGlyph::cGlyph(uint CharCode, FT_GlyphSlotRec_ *GlyphData)
|
||||
{
|
||||
SetData(Data);
|
||||
charCode = CharCode;
|
||||
advanceX = GlyphData->advance.x >> 6;
|
||||
advanceY = GlyphData->advance.y >> 6;
|
||||
left = GlyphData->bitmap_left;
|
||||
top = GlyphData->bitmap_top;
|
||||
width = GlyphData->bitmap.width;
|
||||
rows = GlyphData->bitmap.rows;
|
||||
pitch = GlyphData->bitmap.pitch;
|
||||
bitmap = MALLOC(uchar, rows * pitch);
|
||||
memcpy(bitmap, GlyphData->bitmap.buffer, rows * pitch);
|
||||
}
|
||||
|
||||
void cFont::SetData(const void *Data)
|
||||
cGlyph::~cGlyph()
|
||||
{
|
||||
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)];
|
||||
free(bitmap);
|
||||
}
|
||||
|
||||
int cGlyph::GetKerningCache(uint PrevSym) const
|
||||
{
|
||||
for (int i = kerningCache.Size(); --i > 0; ) {
|
||||
if (kerningCache[i].prevSym == PrevSym)
|
||||
return kerningCache[i].kerning;
|
||||
}
|
||||
return KERNING_UNKNOWN;
|
||||
}
|
||||
|
||||
void cGlyph::SetKerningCache(uint PrevSym, int Kerning)
|
||||
{
|
||||
kerningCache.Append(tKerning(PrevSym, Kerning));
|
||||
}
|
||||
|
||||
class cFreetypeFont : public cFont {
|
||||
private:
|
||||
int height;
|
||||
int bottom;
|
||||
FT_Library library; ///< Handle to library
|
||||
FT_Face face; ///< Handle to face object
|
||||
mutable cList<cGlyph> glyphCacheMonochrome;
|
||||
mutable cList<cGlyph> glyphCacheAntiAliased;
|
||||
int Bottom(void) const { return bottom; }
|
||||
int Kerning(cGlyph *Glyph, uint PrevSym) const;
|
||||
cGlyph* Glyph(uint CharCode, bool AntiAliased = false) const;
|
||||
public:
|
||||
cFreetypeFont(const char *Name, int CharHeight);
|
||||
virtual ~cFreetypeFont();
|
||||
virtual int Width(uint c) const;
|
||||
virtual int Width(const char *s) const;
|
||||
virtual int Height(void) const { return height; }
|
||||
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const;
|
||||
};
|
||||
|
||||
cFreetypeFont::cFreetypeFont(const char *Name, int CharHeight)
|
||||
{
|
||||
height = 0;
|
||||
bottom = 0;
|
||||
int error = FT_Init_FreeType(&library);
|
||||
if (!error) {
|
||||
error = FT_New_Face(library, Name, 0, &face);
|
||||
if (!error) {
|
||||
if (face->num_fixed_sizes && face->available_sizes) { // fixed font
|
||||
// TODO what exactly does all this mean?
|
||||
height = face->available_sizes->height;
|
||||
for (uint sym ='A'; sym < 'z'; sym++) { // search for descender for fixed font FIXME
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(face, sym);
|
||||
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||
if (!error) {
|
||||
error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
|
||||
if (!error) {
|
||||
if (face->glyph->bitmap.rows-face->glyph->bitmap_top > bottom)
|
||||
bottom = face->glyph->bitmap.rows-face->glyph->bitmap_top;
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: FreeType: error %d in FT_Render_Glyph", error);
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: FreeType: error %d in FT_Load_Glyph", error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error = FT_Set_Char_Size(face, // handle to face object
|
||||
0, // char_width in 1/64th of points
|
||||
CharHeight * 64, // CharHeight in 1/64th of points
|
||||
0, // horizontal device resolution
|
||||
0); // vertical device resolution
|
||||
if (!error) {
|
||||
height = ((face->size->metrics.ascender-face->size->metrics.descender) + 63) / 64;
|
||||
bottom = abs((face->size->metrics.descender - 63) / 64);
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: FreeType: error %d during FT_Set_Char_Size (font = %s)\n", error, Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
esyslog("ERROR: FreeType: load error %d (font = %s)", error, Name);
|
||||
}
|
||||
else
|
||||
height = 0;
|
||||
esyslog("ERROR: FreeType: initialization error %d (font = %s)", error, Name);
|
||||
}
|
||||
|
||||
int cFont::Width(const char *s) const
|
||||
cFreetypeFont::~cFreetypeFont()
|
||||
{
|
||||
FT_Done_Face(face);
|
||||
FT_Done_FreeType(library);
|
||||
}
|
||||
|
||||
int cFreetypeFont::Kerning(cGlyph *Glyph, uint PrevSym) const
|
||||
{
|
||||
int kerning = 0;
|
||||
if (Glyph && PrevSym) {
|
||||
kerning = Glyph->GetKerningCache(PrevSym);
|
||||
if (kerning == KERNING_UNKNOWN) {
|
||||
FT_Vector delta;
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(face, Glyph->CharCode());
|
||||
FT_UInt glyph_index_prev = FT_Get_Char_Index(face, PrevSym);
|
||||
FT_Get_Kerning(face, glyph_index_prev, glyph_index, FT_KERNING_DEFAULT, &delta);
|
||||
kerning = delta.x / 64;
|
||||
Glyph->SetKerningCache(PrevSym, kerning);
|
||||
}
|
||||
}
|
||||
return kerning;
|
||||
}
|
||||
|
||||
cGlyph* cFreetypeFont::Glyph(uint CharCode, bool AntiAliased) const
|
||||
{
|
||||
// Lookup in cache:
|
||||
cList<cGlyph> *glyphCache = AntiAliased ? &glyphCacheAntiAliased : &glyphCacheMonochrome;
|
||||
for (cGlyph *g = glyphCache->First(); g; g = glyphCache->Next(g)) {
|
||||
if (g->CharCode() == CharCode)
|
||||
return g;
|
||||
}
|
||||
|
||||
FT_UInt glyph_index = FT_Get_Char_Index(face, CharCode);
|
||||
|
||||
// Load glyph image into the slot (erase previous one):
|
||||
int error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||
if (error)
|
||||
esyslog("ERROR: FreeType: error during FT_Load_Glyph");
|
||||
else {
|
||||
#if ((FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 7) || (FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 2 && FREETYPE_PATCH <= 1))// TODO workaround for bug? which one?
|
||||
if (AntiAliased || CharCode == 32)
|
||||
#else
|
||||
if (AntiAliased)
|
||||
#endif
|
||||
error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
|
||||
else
|
||||
error = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_MONO);
|
||||
if (error)
|
||||
esyslog("ERROR: FreeType: error during FT_Render_Glyph %d, %d\n", CharCode, glyph_index);
|
||||
else { //new bitmap
|
||||
cGlyph *Glyph = new cGlyph(CharCode, face->glyph);
|
||||
glyphCache->Add(Glyph);
|
||||
return Glyph;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int cFreetypeFont::Width(uint c) const
|
||||
{
|
||||
cGlyph *g = Glyph(c, Setup.AntiAlias);
|
||||
return g ? g->AdvanceX() : 0;
|
||||
}
|
||||
|
||||
int cFreetypeFont::Width(const char *s) const
|
||||
{
|
||||
int w = 0;
|
||||
while (s && *s)
|
||||
w += Width(*s++);
|
||||
if (s) {
|
||||
uint prevSym = 0;
|
||||
while (*s) {
|
||||
int sl = Utf8CharLen(s);
|
||||
uint sym = Utf8CharGet(s, sl);
|
||||
s += sl;
|
||||
cGlyph *g = Glyph(sym, Setup.AntiAlias);
|
||||
if (g)
|
||||
w += g->AdvanceX() + Kerning(g, prevSym);
|
||||
prevSym = sym;
|
||||
}
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
int cFont::Height(const char *s) const
|
||||
void cFreetypeFont::DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) 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]);
|
||||
}
|
||||
if (s && height) { // checking height to make sure we actually have a valid font
|
||||
bool AntiAliased = Setup.AntiAlias && Bitmap->Bpp() >= 8;
|
||||
tIndex fg = Bitmap->Index(ColorFg);
|
||||
uint prevSym = 0;
|
||||
while (*s) {
|
||||
int sl = Utf8CharLen(s);
|
||||
uint sym = Utf8CharGet(s, sl);
|
||||
s += sl;
|
||||
cGlyph *g = Glyph(sym, AntiAliased);
|
||||
int kerning = Kerning(g, prevSym);
|
||||
prevSym = sym;
|
||||
uchar *buffer = g->Bitmap();
|
||||
int symWidth = g->Width();
|
||||
if (Width && x + symWidth + g->Left() + kerning - 1 > Width)
|
||||
break; // we don't draw partial characters
|
||||
if (x + symWidth + g->Left() + kerning > 0) {
|
||||
for (int row = 0; row < g->Rows(); row++) {
|
||||
for (int pitch = 0; pitch < g->Pitch(); pitch++) {
|
||||
uchar bt = *(buffer + (row * g->Pitch() + pitch));
|
||||
if (AntiAliased) {
|
||||
if (bt > 0x00) {
|
||||
int px = x + pitch + g->Left() + kerning;
|
||||
int py = y + row + (height - Bottom() - g->Top());
|
||||
if (bt == 0xFF)
|
||||
Bitmap->SetIndex(px, py, fg);
|
||||
else {
|
||||
tColor bg = (ColorBg != clrTransparent) ? ColorBg : Bitmap->GetColor(px, py);
|
||||
Bitmap->SetIndex(px, py, Bitmap->Index(Bitmap->Blend(ColorFg, bg, bt)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else { //monochrome rendering
|
||||
for (int col = 0; col < 8 && col + pitch * 8 <= symWidth; col++) {
|
||||
if (bt & 0x80)
|
||||
Bitmap->SetIndex(x + col + pitch * 8 + g->Left() + kerning, y + row + (height - Bottom() - g->Top()), fg);
|
||||
bt <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
x += g->AdvanceX() + kerning;
|
||||
if (x > Bitmap->Width() - 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cFont::SetFont(eDvbFont Font, const void *Data)
|
||||
// --- cFont -----------------------------------------------------------------
|
||||
|
||||
cFont *cFont::fonts[eDvbFontSize] = { NULL };
|
||||
|
||||
void cFont::SetFont(eDvbFont Font, const char *Name, int CharHeight)
|
||||
{
|
||||
delete fonts[Font];
|
||||
fonts[Font] = new cFont(Data ? Data : FontData[code][Font]);
|
||||
fonts[Font] = new cFreetypeFont(*Name == '/' ? Name : *AddDirectory(FONTDIR, Name), CharHeight);
|
||||
}
|
||||
|
||||
const cFont *cFont::GetFont(eDvbFont Font)
|
||||
@ -131,8 +302,13 @@ const cFont *cFont::GetFont(eDvbFont Font)
|
||||
Font = fontOsd;
|
||||
else if (Setup.UseSmallFont == 2)
|
||||
Font = fontSml;
|
||||
if (!fonts[Font])
|
||||
SetFont(Font);
|
||||
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;
|
||||
}
|
||||
}
|
||||
return fonts[Font];
|
||||
}
|
||||
|
||||
@ -176,16 +352,18 @@ void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
|
||||
stripspace(text); // strips trailing newlines
|
||||
|
||||
for (char *p = text; *p; ) {
|
||||
if (*p == '\n') {
|
||||
int sl = Utf8CharLen(p);
|
||||
uint sym = Utf8CharGet(p, sl);
|
||||
if (sym == '\n') {
|
||||
lines++;
|
||||
w = 0;
|
||||
Blank = Delim = NULL;
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
else if (isspace(*p))
|
||||
else if (sl == 1 && isspace(sym))
|
||||
Blank = p;
|
||||
int cw = Font->Width(*p);
|
||||
int cw = Font->Width(sym);
|
||||
if (w + cw > Width) {
|
||||
if (Blank) {
|
||||
*Blank = '\n';
|
||||
@ -214,7 +392,7 @@ void cTextWrapper::Set(const char *Text, const cFont *Font, int Width)
|
||||
Delim = p;
|
||||
Blank = NULL;
|
||||
}
|
||||
p++;
|
||||
p += sl;
|
||||
}
|
||||
}
|
||||
|
||||
|
64
font.h
64
font.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: font.h 1.15 2007/03/11 09:50:42 kls Exp $
|
||||
* $Id: font.h 1.16 2007/06/10 12:58:54 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __FONT_H
|
||||
@ -13,6 +13,10 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAXFONTNAME 64
|
||||
#define MAXFONTSIZE 64
|
||||
#define FONTDIR "/usr/share/fonts/truetype"
|
||||
|
||||
enum eDvbFont {
|
||||
fontOsd,
|
||||
fontFix,
|
||||
@ -20,49 +24,35 @@ enum eDvbFont {
|
||||
#define eDvbFontSize (fontSml + 1)
|
||||
};
|
||||
|
||||
enum eDvbCode {
|
||||
code_iso8859_1,
|
||||
code_iso8859_2,
|
||||
code_iso8859_5,
|
||||
code_iso8859_7,
|
||||
code_iso8859_9,
|
||||
code_iso8859_13,
|
||||
code_iso8859_15,
|
||||
#define eDvbCodeSize (code_iso8859_15 + 1)
|
||||
};
|
||||
class cBitmap;
|
||||
typedef uint32_t tColor; // see also osd.h
|
||||
typedef uint8_t tIndex;
|
||||
|
||||
class cFont {
|
||||
public:
|
||||
enum { NUMCHARS = 256 };
|
||||
typedef uint32_t tPixelData;
|
||||
struct tCharData {
|
||||
tPixelData width, height;
|
||||
tPixelData lines[1];
|
||||
};
|
||||
private:
|
||||
static eDvbCode code;
|
||||
static cFont *fonts[];
|
||||
const tCharData *data[NUMCHARS];
|
||||
int height;
|
||||
public:
|
||||
cFont(const void *Data);
|
||||
virtual ~cFont() {}
|
||||
void SetData(const void *Data);
|
||||
virtual int Width(unsigned char c) const { return data[c]->width; }
|
||||
///< Returns the width of the given character.
|
||||
virtual int Width(const char *s) const;
|
||||
///< Returns the width of the given string.
|
||||
virtual int Height(unsigned char c) const { return data[c]->height; }
|
||||
///< Returns the height of the given character.
|
||||
virtual int Height(const char *s) const;
|
||||
///< Returns the height of the given string.
|
||||
virtual int Height(void) const { return height; }
|
||||
///< Returns the height of this font (all characters have the same height).
|
||||
const tCharData *CharData(unsigned char c) const { return data[c]; }
|
||||
static bool SetCode(const char *Code);
|
||||
static void SetCode(eDvbCode Code);
|
||||
static void SetFont(eDvbFont Font, const void *Data = NULL);
|
||||
virtual int Width(uint c) const = 0;
|
||||
///< Returns the width of the given character in pixel.
|
||||
virtual int Width(const char *s) const = 0;
|
||||
///< Returns the width of the given string in pixel.
|
||||
virtual int Height(void) const = 0;
|
||||
///< Returns the height of this font in pixel (all characters have the same height).
|
||||
int Height(const char *s) const { return Height(); }
|
||||
///< Returns the height of this font in pixel (obsolete, just for backwards compatibilty).
|
||||
virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const = 0;
|
||||
///< Draws the given text into the Bitmap at position (x, y) with the given colors.
|
||||
///< The text will not exceed the given Width (if > 0), and will end with a complete character.
|
||||
static void SetFont(eDvbFont Font, const char *Name, int CharHeight);
|
||||
///< Sets the given Font to use the font data from the file Name and make its characters
|
||||
///< CharHeight pixels high.
|
||||
static const cFont *GetFont(eDvbFont Font);
|
||||
///< Gets the given Font, which was previously set by a call to SetFont().
|
||||
///< If no SetFont() call has been made, the font as defined in the setup is returned.
|
||||
///< 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.
|
||||
};
|
||||
|
||||
class cTextWrapper {
|
||||
|
6498
fontfix-iso8859-1.c
6498
fontfix-iso8859-1.c
File diff suppressed because it is too large
Load Diff
6498
fontfix-iso8859-13.c
6498
fontfix-iso8859-13.c
File diff suppressed because it is too large
Load Diff
6498
fontfix-iso8859-15.c
6498
fontfix-iso8859-15.c
File diff suppressed because it is too large
Load Diff
6498
fontfix-iso8859-2.c
6498
fontfix-iso8859-2.c
File diff suppressed because it is too large
Load Diff
6050
fontfix-iso8859-5.c
6050
fontfix-iso8859-5.c
File diff suppressed because it is too large
Load Diff
6050
fontfix-iso8859-7.c
6050
fontfix-iso8859-7.c
File diff suppressed because it is too large
Load Diff
6498
fontfix-iso8859-9.c
6498
fontfix-iso8859-9.c
File diff suppressed because it is too large
Load Diff
6722
fontosd-iso8859-1.c
6722
fontosd-iso8859-1.c
File diff suppressed because it is too large
Load Diff
6722
fontosd-iso8859-13.c
6722
fontosd-iso8859-13.c
File diff suppressed because it is too large
Load Diff
6722
fontosd-iso8859-15.c
6722
fontosd-iso8859-15.c
File diff suppressed because it is too large
Load Diff
6733
fontosd-iso8859-2.c
6733
fontosd-iso8859-2.c
File diff suppressed because it is too large
Load Diff
5602
fontosd-iso8859-5.c
5602
fontosd-iso8859-5.c
File diff suppressed because it is too large
Load Diff
6274
fontosd-iso8859-7.c
6274
fontosd-iso8859-7.c
File diff suppressed because it is too large
Load Diff
6722
fontosd-iso8859-9.c
6722
fontosd-iso8859-9.c
File diff suppressed because it is too large
Load Diff
5602
fontsml-iso8859-1.c
5602
fontsml-iso8859-1.c
File diff suppressed because it is too large
Load Diff
5602
fontsml-iso8859-13.c
5602
fontsml-iso8859-13.c
File diff suppressed because it is too large
Load Diff
5602
fontsml-iso8859-15.c
5602
fontsml-iso8859-15.c
File diff suppressed because it is too large
Load Diff
5826
fontsml-iso8859-2.c
5826
fontsml-iso8859-2.c
File diff suppressed because it is too large
Load Diff
6274
fontsml-iso8859-5.c
6274
fontsml-iso8859-5.c
File diff suppressed because it is too large
Load Diff
5154
fontsml-iso8859-7.c
5154
fontsml-iso8859-7.c
File diff suppressed because it is too large
Load Diff
5602
fontsml-iso8859-9.c
5602
fontsml-iso8859-9.c
File diff suppressed because it is too large
Load Diff
381
genfontfile.c
381
genfontfile.c
@ -1,381 +0,0 @@
|
||||
/* Copyright (c) Mark J. Kilgard, 1997. */
|
||||
|
||||
/* This program is freely distributable without licensing fees and is
|
||||
provided without guarantee or warrantee expressed or implied. This
|
||||
program is -not- in the public domain. */
|
||||
|
||||
/* X compile line: cc -o gentexfont gentexfont.c -lX11 */
|
||||
|
||||
/* 2000-10-01: Stripped down the original code to get a simple bitmap C-code generator */
|
||||
/* for use with the VDR project (see http://www.cadsoft.de/vdr) */
|
||||
/* Renamed the file 'genfontfile.c' since it no longer generates 'tex' data */
|
||||
/* Klaus Schmidinger (kls@cadsoft.de) */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef struct {
|
||||
unsigned short c; /* Potentially support 16-bit glyphs. */
|
||||
unsigned char width;
|
||||
unsigned char height;
|
||||
signed char xoffset;
|
||||
signed char yoffset;
|
||||
signed char advance;
|
||||
char dummy; /* Space holder for alignment reasons. */
|
||||
short x;
|
||||
short y;
|
||||
} TexGlyphInfo;
|
||||
|
||||
typedef struct {
|
||||
short width;
|
||||
short height;
|
||||
short xoffset;
|
||||
short yoffset;
|
||||
short advance;
|
||||
unsigned char *bitmap;
|
||||
} PerGlyphInfo, *PerGlyphInfoPtr;
|
||||
|
||||
typedef struct {
|
||||
int min_char;
|
||||
int max_char;
|
||||
int max_ascent;
|
||||
int max_descent;
|
||||
PerGlyphInfo glyph[1];
|
||||
} FontInfo, *FontInfoPtr;
|
||||
|
||||
Display *dpy;
|
||||
FontInfoPtr fontinfo;
|
||||
|
||||
/* #define REPORT_GLYPHS */
|
||||
#ifdef REPORT_GLYPHS
|
||||
#define DEBUG_GLYPH4(msg,a,b,c,d) printf(msg,a,b,c,d)
|
||||
#define DEBUG_GLYPH(msg) printf(msg)
|
||||
#else
|
||||
#define DEBUG_GLYPH4(msg,a,b,c,d) { /* nothing */ }
|
||||
#define DEBUG_GLYPH(msg) { /* nothing */ }
|
||||
#endif
|
||||
|
||||
#define MAX_GLYPHS_PER_GRAB 512 /* this is big enough for 2^9 glyph
|
||||
character sets */
|
||||
|
||||
FontInfoPtr
|
||||
SuckGlyphsFromServer(Display * dpy, Font font)
|
||||
{
|
||||
Pixmap offscreen;
|
||||
XFontStruct *fontinfo;
|
||||
XImage *image;
|
||||
GC xgc;
|
||||
XGCValues values;
|
||||
int numchars;
|
||||
int width, height, pixwidth;
|
||||
int i, j;
|
||||
XCharStruct *charinfo;
|
||||
XChar2b character;
|
||||
unsigned char *bitmapData;
|
||||
int x, y;
|
||||
int spanLength;
|
||||
int charWidth, charHeight, maxSpanLength;
|
||||
int grabList[MAX_GLYPHS_PER_GRAB];
|
||||
int glyphsPerGrab = MAX_GLYPHS_PER_GRAB;
|
||||
int numToGrab, thisglyph;
|
||||
FontInfoPtr myfontinfo;
|
||||
|
||||
fontinfo = XQueryFont(dpy, font);
|
||||
if (!fontinfo)
|
||||
return NULL;
|
||||
|
||||
numchars = fontinfo->max_char_or_byte2 - fontinfo->min_char_or_byte2 + 1;
|
||||
if (numchars < 1)
|
||||
return NULL;
|
||||
|
||||
myfontinfo = (FontInfoPtr) malloc(sizeof(FontInfo) + (numchars - 1) * sizeof(PerGlyphInfo));
|
||||
if (!myfontinfo)
|
||||
return NULL;
|
||||
|
||||
myfontinfo->min_char = fontinfo->min_char_or_byte2;
|
||||
myfontinfo->max_char = fontinfo->max_char_or_byte2;
|
||||
myfontinfo->max_ascent = fontinfo->max_bounds.ascent;
|
||||
myfontinfo->max_descent = fontinfo->max_bounds.descent;
|
||||
|
||||
width = fontinfo->max_bounds.rbearing - fontinfo->min_bounds.lbearing;
|
||||
height = fontinfo->max_bounds.ascent + fontinfo->max_bounds.descent;
|
||||
|
||||
maxSpanLength = (width + 7) / 8;
|
||||
/* Be careful determining the width of the pixmap; the X protocol allows
|
||||
pixmaps of width 2^16-1 (unsigned short size) but drawing coordinates
|
||||
max out at 2^15-1 (signed short size). If the width is too large, we
|
||||
need to limit the glyphs per grab. */
|
||||
if ((glyphsPerGrab * 8 * maxSpanLength) >= (1 << 15)) {
|
||||
glyphsPerGrab = (1 << 15) / (8 * maxSpanLength);
|
||||
}
|
||||
pixwidth = glyphsPerGrab * 8 * maxSpanLength;
|
||||
offscreen = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
|
||||
pixwidth, height, 1);
|
||||
|
||||
values.font = font;
|
||||
values.background = 0;
|
||||
values.foreground = 0;
|
||||
xgc = XCreateGC(dpy, offscreen, GCFont | GCBackground | GCForeground, &values);
|
||||
|
||||
XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height);
|
||||
XSetForeground(dpy, xgc, 1);
|
||||
|
||||
numToGrab = 0;
|
||||
if (fontinfo->per_char == NULL) {
|
||||
charinfo = &(fontinfo->min_bounds);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
spanLength = (charWidth + 7) / 8;
|
||||
}
|
||||
for (i = 0; i < numchars; i++) {
|
||||
if (fontinfo->per_char != NULL) {
|
||||
charinfo = &(fontinfo->per_char[i]);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
if (charWidth == 0 || charHeight == 0) {
|
||||
/* Still must move raster pos even if empty character */
|
||||
myfontinfo->glyph[i].width = 0;
|
||||
myfontinfo->glyph[i].height = 0;
|
||||
myfontinfo->glyph[i].xoffset = 0;
|
||||
myfontinfo->glyph[i].yoffset = 0;
|
||||
myfontinfo->glyph[i].advance = charinfo->width;
|
||||
myfontinfo->glyph[i].bitmap = NULL;
|
||||
goto PossiblyDoGrab;
|
||||
}
|
||||
}
|
||||
grabList[numToGrab] = i;
|
||||
|
||||
/* XXX is this right for large fonts? */
|
||||
character.byte2 = (i + fontinfo->min_char_or_byte2) & 255;
|
||||
character.byte1 = (i + fontinfo->min_char_or_byte2) >> 8;
|
||||
|
||||
/* XXX we could use XDrawImageString16 which would also paint the backing
|
||||
|
||||
rectangle but X server bugs in some scalable font rasterizers makes it
|
||||
|
||||
more effective to do XFillRectangles to clear the pixmap and
|
||||
XDrawImage16 for the text. */
|
||||
XDrawString16(dpy, offscreen, xgc,
|
||||
-charinfo->lbearing + 8 * maxSpanLength * numToGrab,
|
||||
charinfo->ascent, &character, 1);
|
||||
|
||||
numToGrab++;
|
||||
|
||||
PossiblyDoGrab:
|
||||
|
||||
if (numToGrab >= glyphsPerGrab || i == numchars - 1) {
|
||||
image = XGetImage(dpy, offscreen,
|
||||
0, 0, pixwidth, height, 1, XYPixmap);
|
||||
for (j = 0; j < numToGrab; j++) {
|
||||
thisglyph = grabList[j];
|
||||
if (fontinfo->per_char != NULL) {
|
||||
charinfo = &(fontinfo->per_char[thisglyph]);
|
||||
charWidth = charinfo->rbearing - charinfo->lbearing;
|
||||
charHeight = charinfo->ascent + charinfo->descent;
|
||||
spanLength = (charWidth + 7) / 8;
|
||||
}
|
||||
bitmapData = (unsigned char *)calloc(height * spanLength, sizeof(char));
|
||||
if (!bitmapData)
|
||||
goto FreeFontAndReturn;
|
||||
DEBUG_GLYPH4("index %d, glyph %d (%d by %d)\n",
|
||||
j, thisglyph + fontinfo->min_char_or_byte2, charWidth, charHeight);
|
||||
for (y = 0; y < charHeight; y++) {
|
||||
for (x = 0; x < charWidth; x++) {
|
||||
/* XXX The algorithm used to suck across the font ensures that
|
||||
each glyph begins on a byte boundary. In theory this would
|
||||
make it convienent to copy the glyph into a byte oriented
|
||||
bitmap. We actually use the XGetPixel function to extract
|
||||
each pixel from the image which is not that efficient. We
|
||||
could either do tighter packing in the pixmap or more
|
||||
efficient extraction from the image. Oh well. */
|
||||
if (XGetPixel(image, j * maxSpanLength * 8 + x, charHeight - 1 - y)) {
|
||||
DEBUG_GLYPH("x");
|
||||
bitmapData[y * spanLength + x / 8] |= (1 << (x & 7));
|
||||
} else {
|
||||
DEBUG_GLYPH(" ");
|
||||
}
|
||||
}
|
||||
DEBUG_GLYPH("\n");
|
||||
}
|
||||
myfontinfo->glyph[thisglyph].width = charWidth;
|
||||
myfontinfo->glyph[thisglyph].height = charHeight;
|
||||
myfontinfo->glyph[thisglyph].xoffset = charinfo->lbearing;
|
||||
myfontinfo->glyph[thisglyph].yoffset = -charinfo->descent;
|
||||
myfontinfo->glyph[thisglyph].advance = charinfo->width;
|
||||
myfontinfo->glyph[thisglyph].bitmap = bitmapData;
|
||||
}
|
||||
XDestroyImage(image);
|
||||
numToGrab = 0;
|
||||
/* do we need to clear the offscreen pixmap to get more? */
|
||||
if (i < numchars - 1) {
|
||||
XSetForeground(dpy, xgc, 0);
|
||||
XFillRectangle(dpy, offscreen, xgc, 0, 0, 8 * maxSpanLength * glyphsPerGrab, height);
|
||||
XSetForeground(dpy, xgc, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
XFreeGC(dpy, xgc);
|
||||
XFreePixmap(dpy, offscreen);
|
||||
return myfontinfo;
|
||||
|
||||
FreeFontAndReturn:
|
||||
XDestroyImage(image);
|
||||
XFreeGC(dpy, xgc);
|
||||
XFreePixmap(dpy, offscreen);
|
||||
for (j = i - 1; j >= 0; j--) {
|
||||
if (myfontinfo->glyph[j].bitmap)
|
||||
free(myfontinfo->glyph[j].bitmap);
|
||||
}
|
||||
free(myfontinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
printGlyph(FontInfoPtr font, int c)
|
||||
{
|
||||
PerGlyphInfoPtr glyph;
|
||||
unsigned char *bitmapData;
|
||||
int width, height, spanLength, charWidth;
|
||||
int x, y, l;
|
||||
char buf[1000], *b;
|
||||
|
||||
if (c < font->min_char || c > font->max_char) {
|
||||
fprintf(stderr, "out of range glyph\n");
|
||||
exit(1);
|
||||
}
|
||||
glyph = &font->glyph[c - font->min_char];
|
||||
bitmapData = glyph->bitmap;
|
||||
width = glyph->width;
|
||||
spanLength = (width + 7) / 8;
|
||||
height = glyph->height;
|
||||
charWidth = glyph->xoffset + width;
|
||||
if (charWidth < glyph->advance)
|
||||
charWidth = glyph->advance;
|
||||
|
||||
printf(" { // %d\n", c);
|
||||
printf(" %d, %d,\n", charWidth, font->max_ascent + font->max_descent);
|
||||
for (y = 0; y < font->max_ascent - glyph->yoffset - height; y++) {
|
||||
printf(" 0x%08X, // ", 0);
|
||||
for (x = 0; x < charWidth; x++)
|
||||
putchar('.');
|
||||
putchar('\n');
|
||||
}
|
||||
for (y = height; y-- > 0;) {
|
||||
l = 0;
|
||||
b = buf;
|
||||
for (x = 0; x < glyph->xoffset; x++)
|
||||
*b++ = '.';
|
||||
if (bitmapData) {
|
||||
for (x = 0; x < width; x++) {
|
||||
l <<= 1;
|
||||
if (bitmapData[y * spanLength + x / 8] & (1 << (x & 7))) {
|
||||
*b++ = '*';
|
||||
l |= 1;
|
||||
}
|
||||
else
|
||||
*b++ = '.';
|
||||
}
|
||||
for (x = 0; x < glyph->advance - width - glyph->xoffset; x++) {
|
||||
*b++ = '.';
|
||||
l <<= 1;
|
||||
}
|
||||
}
|
||||
*b = 0;
|
||||
printf(" 0x%08X, // %s\n", l, buf);
|
||||
}
|
||||
for (y = 0; y < font->max_descent + glyph->yoffset; y++) {
|
||||
printf(" 0x%08X, // ", 0);
|
||||
for (x = 0; x < glyph->xoffset + width || x < glyph->advance; x++)
|
||||
putchar('.');
|
||||
putchar('\n');
|
||||
}
|
||||
printf(" },\n");
|
||||
}
|
||||
|
||||
void
|
||||
getMetric(FontInfoPtr font, int c, TexGlyphInfo * tgi)
|
||||
{
|
||||
PerGlyphInfoPtr glyph;
|
||||
unsigned char *bitmapData;
|
||||
|
||||
tgi->c = c;
|
||||
if (c < font->min_char || c > font->max_char) {
|
||||
tgi->width = 0;
|
||||
tgi->height = 0;
|
||||
tgi->xoffset = 0;
|
||||
tgi->yoffset = 0;
|
||||
tgi->dummy = 0;
|
||||
tgi->advance = 0;
|
||||
return;
|
||||
}
|
||||
glyph = &font->glyph[c - font->min_char];
|
||||
bitmapData = glyph->bitmap;
|
||||
if (bitmapData) {
|
||||
tgi->width = glyph->width;
|
||||
tgi->height = glyph->height;
|
||||
tgi->xoffset = glyph->xoffset;
|
||||
tgi->yoffset = glyph->yoffset;
|
||||
} else {
|
||||
tgi->width = 0;
|
||||
tgi->height = 0;
|
||||
tgi->xoffset = 0;
|
||||
tgi->yoffset = 0;
|
||||
}
|
||||
tgi->dummy = 0;
|
||||
tgi->advance = glyph->advance;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
TexGlyphInfo tgi;
|
||||
int usageError = 0;
|
||||
char *varname, *fontname;
|
||||
XFontStruct *xfont;
|
||||
int i;
|
||||
|
||||
if (argc == 3) {
|
||||
varname = argv[1];
|
||||
fontname = argv[2];
|
||||
}
|
||||
else
|
||||
usageError = 1;
|
||||
|
||||
if (usageError) {
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "usage: genfontfile variable_name X_font_name\n");
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dpy = XOpenDisplay(NULL);
|
||||
if (!dpy) {
|
||||
fprintf(stderr, "could not open display\n");
|
||||
exit(1);
|
||||
}
|
||||
/* find an OpenGL-capable RGB visual with depth buffer */
|
||||
xfont = XLoadQueryFont(dpy, fontname);
|
||||
if (!xfont) {
|
||||
fprintf(stderr, "could not get load X font: %s\n", fontname);
|
||||
exit(1);
|
||||
}
|
||||
fontinfo = SuckGlyphsFromServer(dpy, xfont->fid);
|
||||
if (!fontinfo) {
|
||||
fprintf(stderr, "could not get font glyphs\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("static const %s[][%d] = {\n", varname, fontinfo->max_ascent + fontinfo->max_descent + 2);
|
||||
for (c = 32; c < 256; c++) {
|
||||
getMetric(fontinfo, c, &tgi);
|
||||
printGlyph(fontinfo, c);
|
||||
}
|
||||
printf(" };\n");
|
||||
return 0;
|
||||
}
|
215
i18n.c
215
i18n.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: i18n.c 1.293 2007/03/11 10:05:36 kls Exp $
|
||||
* $Id: i18n.c 1.294 2007/06/09 08:44:54 kls Exp $
|
||||
*
|
||||
* Translations provided by:
|
||||
*
|
||||
@ -3138,6 +3138,7 @@ const tI18nPhrase Phrases[] = {
|
||||
"CAM",
|
||||
"CAM",
|
||||
"CAM",
|
||||
"CAM",
|
||||
},
|
||||
{ "Recording",
|
||||
"Aufnahme",
|
||||
@ -3554,6 +3555,167 @@ const tI18nPhrase Phrases[] = {
|
||||
"v¾dy",
|
||||
"hep",
|
||||
},
|
||||
{ "Setup.OSD$Anti-alias",
|
||||
"Kantenglättung",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$OSD font name",
|
||||
"OSD Schriftart",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$Small font name",
|
||||
"Kleine Schriftart",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$Fixed font name",
|
||||
"Festbreiten-Schriftart",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$OSD font size (pixel)",
|
||||
"OSD Schriftgröße (pixel)",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$Small font size (pixel)",
|
||||
"Kleine Schriftgröße (pixel)",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$Fixed font size (pixel)",
|
||||
"Festbreiten-Schriftgröße (pixel)",
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
"",// TODO
|
||||
},
|
||||
{ "Setup.OSD$Channel info position",
|
||||
"Kanalinfo-Position",
|
||||
"Pozicija informacije o kanalu",
|
||||
@ -5021,7 +5183,7 @@ const tI18nPhrase Phrases[] = {
|
||||
" 0\t-.#~,/_@1\taãâbc2\tdef3\tghiî4\tjkl5\tmno6\tpqrsº7\ttþuv8\twxyz9",
|
||||
" 0\t-.#~,/_@1\taábc2\tdeéf3\tghií4\tjkl5\tmnoóöõ6\tpqrs7\ttuúüûv8\twxyz9",
|
||||
"",//TODO
|
||||
"",//TODO
|
||||
" 0\t-.#~,/_@1\tabcÐÑÒÓ2\tdefÔÕñÖ×3\tghiØÙÚÛ4\tjklÜÝÞ5\tmnoßàá6\tpqrsâãäå7\ttuvæçèéê8\twxyzëìíîï9",
|
||||
"",//TODO
|
||||
" 0\t-.#~,/_@1\tabcäå2\tdef3\tghi4\tjkl5\tmnoõö6\tpqrsð7\ttuvü8\twxyzþ9",
|
||||
" 0\t-.#~,/_@1\tabcæå2\tdef3\tghi4\tjkl5\tmnoø6\tpqrs7\ttuv8\twxyz9",
|
||||
@ -6603,25 +6765,33 @@ const tI18nPhrase Phrases[] = {
|
||||
class cI18nEntry : public cListObject {
|
||||
private:
|
||||
const tI18nPhrase *phrases;
|
||||
tI18nPhrase *converted;
|
||||
const char *plugin;
|
||||
public:
|
||||
cI18nEntry(const tI18nPhrase * const Phrases, const char *Plugin);
|
||||
virtual ~cI18nEntry();
|
||||
const tI18nPhrase *Phrases(void) { return phrases; }
|
||||
tI18nPhrase **Converted(void) { return &converted; }
|
||||
const char *Plugin(void) { return plugin; }
|
||||
};
|
||||
|
||||
cI18nEntry::cI18nEntry(const tI18nPhrase * const Phrases, const char *Plugin)
|
||||
{
|
||||
phrases = Phrases;
|
||||
converted = NULL;
|
||||
plugin = Plugin;
|
||||
}
|
||||
|
||||
cI18nEntry::~cI18nEntry()
|
||||
{
|
||||
delete converted;
|
||||
}
|
||||
|
||||
// --- cI18nList -------------------------------------------------------------
|
||||
|
||||
class cI18nList : public cList<cI18nEntry> {
|
||||
public:
|
||||
cI18nEntry *Get(const char *Plugin);
|
||||
const tI18nPhrase *GetPhrases(const char *Plugin);
|
||||
};
|
||||
|
||||
cI18nEntry *cI18nList::Get(const char *Plugin)
|
||||
@ -6635,16 +6805,28 @@ cI18nEntry *cI18nList::Get(const char *Plugin)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const tI18nPhrase *cI18nList::GetPhrases(const char *Plugin)
|
||||
{
|
||||
cI18nEntry *p = Get(Plugin);
|
||||
return p ? p->Phrases() : NULL;
|
||||
}
|
||||
|
||||
cI18nList I18nList;
|
||||
|
||||
// ---
|
||||
|
||||
static tI18nPhrase *Converted = NULL;
|
||||
|
||||
static const char *ConvertPhrase(const tI18nPhrase *Original, tI18nPhrase **Converted, int NrPhrase, int NrLanguage)
|
||||
{
|
||||
if (!*Converted) {
|
||||
int NumPhrases = 0;
|
||||
for (const tI18nPhrase *p = Original; **p; p++)
|
||||
NumPhrases++;
|
||||
*Converted = new tI18nPhrase[NumPhrases + 1];
|
||||
memset(*Converted, 0, sizeof(tI18nPhrase) * (NumPhrases + 1));
|
||||
}
|
||||
if (!(*Converted)[NrPhrase][NrLanguage]) {
|
||||
cCharSetConv csc(Phrases[1][NrLanguage], cCharSetConv::SystemCharacterTable());
|
||||
(*Converted)[NrPhrase][NrLanguage] = strdup(csc.Convert(Original[NrPhrase][NrLanguage]));
|
||||
}
|
||||
return (*Converted)[NrPhrase][NrLanguage];
|
||||
}
|
||||
|
||||
void I18nRegister(const tI18nPhrase * const Phrases, const char *Plugin)
|
||||
{
|
||||
cI18nEntry *p = I18nList.Get(Plugin);
|
||||
@ -6657,13 +6839,14 @@ void I18nRegister(const tI18nPhrase * const Phrases, const char *Plugin)
|
||||
const char *I18nTranslate(const char *s, const char *Plugin)
|
||||
{
|
||||
if (Setup.OSDLanguage) {
|
||||
const tI18nPhrase *p = Plugin ? I18nList.GetPhrases(Plugin) : Phrases;
|
||||
if (!p)
|
||||
p = Phrases;
|
||||
cI18nEntry *e = Plugin ? I18nList.Get(Plugin) : NULL;
|
||||
const tI18nPhrase *OriginalPhrases = e ? e->Phrases() : Phrases;
|
||||
tI18nPhrase **ConvertedPhrases = e ? e->Converted() : &Converted;
|
||||
const tI18nPhrase *p = OriginalPhrases;
|
||||
for (int i = ((p == Phrases) ? 1 : 2); i--; ) {
|
||||
for (; **p; p++) {
|
||||
if (strcmp(s, **p) == 0) {
|
||||
const char *t = (*p)[Setup.OSDLanguage];
|
||||
const char *t = ConvertPhrase(OriginalPhrases, ConvertedPhrases, p - OriginalPhrases, Setup.OSDLanguage);
|
||||
if (t && *t)
|
||||
return t;
|
||||
}
|
||||
@ -6678,7 +6861,11 @@ const char *I18nTranslate(const char *s, const char *Plugin)
|
||||
|
||||
const char * const * I18nLanguages(void)
|
||||
{
|
||||
return &Phrases[0][0];
|
||||
if (!Converted || !(Converted)[0][0]) {
|
||||
for (int i = 0; i < I18nNumLanguages; i++)
|
||||
ConvertPhrase(Phrases, &Converted, 0, i);
|
||||
}
|
||||
return &Converted[0][0];
|
||||
}
|
||||
|
||||
const char * const * I18nCharSets(void)
|
||||
|
3
i18n.h
3
i18n.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: i18n.h 1.19 2007/03/11 09:52:16 kls Exp $
|
||||
* $Id: i18n.h 1.20 2007/05/28 11:43:14 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __I18N_H
|
||||
@ -21,7 +21,6 @@ void I18nRegister(const tI18nPhrase * const Phrases, const char *Plugin);
|
||||
const char *I18nTranslate(const char *s, const char *Plugin = NULL) __attribute_format_arg__(1);
|
||||
|
||||
const char * const * I18nLanguages(void);
|
||||
const char * const * I18nCharSets(void);
|
||||
const char *I18nLanguageCode(int Index);
|
||||
int I18nLanguageIndex(const char *Code);
|
||||
const char *I18nNormalizeLanguageCode(const char *Code);
|
||||
|
12
libsi/si.c
12
libsi/si.c
@ -6,7 +6,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: si.c 1.19 2007/05/28 10:22:42 kls Exp $
|
||||
* $Id: si.c 1.20 2007/06/10 09:31:34 kls Exp $
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
@ -219,7 +219,9 @@ char *String::getText() {
|
||||
int len=getLength();
|
||||
if (len < 0 || len > 4095)
|
||||
return strdup("text error"); // caller will delete it!
|
||||
char *data=new char(len+1);
|
||||
char *data=new char(len+1); // FIXME If this function is ever actually used, this buffer might
|
||||
// need to be bigger in order to hold the string as UTF-8.
|
||||
// Maybe decodeText should dynamically handle this? kls 2007-06-10
|
||||
decodeText(data, len+1);
|
||||
return data;
|
||||
}
|
||||
@ -404,6 +406,9 @@ void String::decodeText(char *buffer, int size) {
|
||||
}
|
||||
bool singleByte;
|
||||
const char *cs = getCharacterTable(from, len, &singleByte);
|
||||
// FIXME Need to make this UTF-8 aware (different control codes).
|
||||
// However, there's yet to be found a broadcaster that actually
|
||||
// uses UTF-8 for the SI data... (kls 2007-06-10)
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (*from == 0)
|
||||
break;
|
||||
@ -440,6 +445,9 @@ void String::decodeText(char *buffer, char *shortVersion, int sizeBuffer, int si
|
||||
}
|
||||
bool singleByte;
|
||||
const char *cs = getCharacterTable(from, len, &singleByte);
|
||||
// FIXME Need to make this UTF-8 aware (different control codes).
|
||||
// However, there's yet to be found a broadcaster that actually
|
||||
// uses UTF-8 for the SI data... (kls 2007-06-10)
|
||||
for (int i = 0; i < len; i++) {
|
||||
if ( ((' ' <= *from) && (*from <= '~'))
|
||||
|| (*from == '\n')
|
||||
|
66
menu.c
66
menu.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menu.c 1.450 2007/02/25 14:04:33 kls Exp $
|
||||
* $Id: menu.c 1.451 2007/06/09 14:36:46 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -761,7 +761,7 @@ void cMenuTimerItem::Set(void)
|
||||
{
|
||||
cString day, name("");
|
||||
if (timer->WeekDays())
|
||||
day = timer->PrintDay(0, timer->WeekDays());
|
||||
day = timer->PrintDay(0, timer->WeekDays(), false);
|
||||
else if (timer->Day() - time(NULL) < 28 * SECSINDAY) {
|
||||
day = itoa(timer->GetMDay(timer->Day()));
|
||||
name = WeekDayName(timer->Day());
|
||||
@ -1052,10 +1052,11 @@ bool cMenuScheduleItem::Update(bool Force)
|
||||
char t = TimerMatchChars[timerMatch];
|
||||
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
|
||||
char r = event->SeenWithin(30) && event->IsRunning() ? '*' : ' ';
|
||||
const char *csn = channel ? channel->ShortName(true) : NULL;
|
||||
if (channel && withDate)
|
||||
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title());
|
||||
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title());
|
||||
else if (channel)
|
||||
asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), 6, channel->ShortName(true), *event->GetTimeString(), t, v, r, event->Title());
|
||||
asprintf(&buffer, "%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title());
|
||||
else
|
||||
asprintf(&buffer, "%.*s\t%s\t%c%c%c\t%s", 6, *event->GetDateString(), *event->GetTimeString(), t, v, r, event->Title());
|
||||
SetText(buffer, false);
|
||||
@ -2157,7 +2158,10 @@ private:
|
||||
int skinIndex;
|
||||
const char **skinDescriptions;
|
||||
cThemes themes;
|
||||
int originalThemeIndex;
|
||||
int themeIndex;
|
||||
cFileNameList fontNames;
|
||||
int fontOsdIndex, fontSmlIndex, fontFixIndex;
|
||||
virtual void Set(void);
|
||||
public:
|
||||
cMenuSetupOSD(void);
|
||||
@ -2171,13 +2175,18 @@ cMenuSetupOSD::cMenuSetupOSD(void)
|
||||
skinIndex = originalSkinIndex = Skins.Current()->Index();
|
||||
skinDescriptions = new const char*[numSkins];
|
||||
themes.Load(Skins.Current()->Name());
|
||||
themeIndex = 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);
|
||||
if (fontNames.Size()) {
|
||||
fontOsdIndex = max(0, fontNames.Find(Setup.FontOsd));
|
||||
fontSmlIndex = max(0, fontNames.Find(Setup.FontSml));
|
||||
fontFixIndex = max(0, fontNames.Find(Setup.FontFix));
|
||||
}
|
||||
Set();
|
||||
}
|
||||
|
||||
cMenuSetupOSD::~cMenuSetupOSD()
|
||||
{
|
||||
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
||||
delete[] skinDescriptions;
|
||||
}
|
||||
|
||||
@ -2201,6 +2210,15 @@ void cMenuSetupOSD::Set(void)
|
||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Height"), &data.OSDHeight, MINOSDHEIGHT, MAXOSDHEIGHT));
|
||||
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 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));
|
||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Channel info position"), &data.ChannelInfoPos, tr("bottom"), tr("top")));
|
||||
Add(new cMenuEditIntItem( tr("Setup.OSD$Channel info time (s)"), &data.ChannelInfoTime, 1, 60));
|
||||
Add(new cMenuEditBoolItem(tr("Setup.OSD$Info on channel switch"), &data.ShowInfoOnChSwitch));
|
||||
@ -2215,29 +2233,57 @@ void cMenuSetupOSD::Set(void)
|
||||
|
||||
eOSState cMenuSetupOSD::ProcessKey(eKeys Key)
|
||||
{
|
||||
bool ModifiedApperance = false;
|
||||
|
||||
if (Key == kOk) {
|
||||
if (skinIndex != originalSkinIndex) {
|
||||
cSkin *Skin = Skins.Get(skinIndex);
|
||||
if (Skin) {
|
||||
strn0cpy(data.OSDSkin, Skin->Name(), sizeof(data.OSDSkin));
|
||||
Skins.SetCurrent(Skin->Name());
|
||||
ModifiedApperance = true;
|
||||
}
|
||||
}
|
||||
if (themes.NumThemes() && Skins.Current()->Theme()) {
|
||||
Skins.Current()->Theme()->Load(themes.FileName(themeIndex));
|
||||
strn0cpy(data.OSDTheme, themes.Name(themeIndex), sizeof(data.OSDTheme));
|
||||
ModifiedApperance |= themeIndex != originalThemeIndex;
|
||||
}
|
||||
if (data.OSDLeft != Setup.OSDLeft || data.OSDTop != Setup.OSDTop || data.OSDWidth != Setup.OSDWidth || data.OSDHeight != Setup.OSDHeight) {
|
||||
data.OSDWidth &= ~0x07; // OSD width must be a multiple of 8
|
||||
ModifiedApperance = true;
|
||||
}
|
||||
if (data.UseSmallFont != Setup.UseSmallFont || data.AntiAlias != Setup.AntiAlias)
|
||||
ModifiedApperance = true;
|
||||
if (fontNames.Size()) {
|
||||
strn0cpy(data.FontOsd, fontNames[fontOsdIndex], sizeof(data.FontOsd));
|
||||
strn0cpy(data.FontSml, fontNames[fontSmlIndex], sizeof(data.FontSml));
|
||||
strn0cpy(data.FontFix, fontNames[fontFixIndex], sizeof(data.FontFix));
|
||||
}
|
||||
if (strcmp(data.FontOsd, Setup.FontOsd) || data.FontOsdSize != Setup.FontOsdSize) {
|
||||
cFont::SetFont(fontOsd, data.FontOsd, data.FontOsdSize);
|
||||
ModifiedApperance = true;
|
||||
}
|
||||
if (strcmp(data.FontSml, Setup.FontSml) || data.FontSmlSize != Setup.FontSmlSize) {
|
||||
cFont::SetFont(fontSml, data.FontSml, data.FontSmlSize);
|
||||
ModifiedApperance = true;
|
||||
}
|
||||
if (strcmp(data.FontFix, Setup.FontFix) || data.FontFixSize != Setup.FontFixSize) {
|
||||
cFont::SetFont(fontFix, data.FontFix, data.FontFixSize);
|
||||
ModifiedApperance = true;
|
||||
}
|
||||
data.OSDWidth &= ~0x07; // OSD width must be a multiple of 8
|
||||
}
|
||||
|
||||
int osdLanguage = data.OSDLanguage;
|
||||
int oldSkinIndex = skinIndex;
|
||||
eOSState state = cMenuSetupBase::ProcessKey(Key);
|
||||
|
||||
if (ModifiedApperance)
|
||||
SetDisplayMenu();
|
||||
|
||||
if (data.OSDLanguage != osdLanguage || skinIndex != oldSkinIndex) {
|
||||
int OriginalOSDLanguage = Setup.OSDLanguage;
|
||||
Setup.OSDLanguage = data.OSDLanguage;
|
||||
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
||||
|
||||
cSkin *Skin = Skins.Get(skinIndex);
|
||||
if (Skin) {
|
||||
@ -2910,10 +2956,8 @@ bool cMenuMain::Update(bool Force)
|
||||
int Minutes = int(double(FreeMB) / MB_PER_MINUTE);
|
||||
int Hours = Minutes / 60;
|
||||
Minutes %= 60;
|
||||
char buffer[40];
|
||||
snprintf(buffer, sizeof(buffer), "%s - %s %d%% - %2d:%02d %s", tr("VDR"), tr("Disk"), Percent, Hours, Minutes, tr("free"));
|
||||
//XXX -> skin function!!!
|
||||
SetTitle(buffer);
|
||||
SetTitle(cString::sprintf("%s - %s %d%% - %2d:%02d %s", tr("VDR"), tr("Disk"), Percent, Hours, Minutes, tr("free")));
|
||||
result = true;
|
||||
}
|
||||
lastDiskSpaceCheck = time(NULL);
|
||||
|
302
menuitems.c
302
menuitems.c
@ -4,11 +4,12 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menuitems.c 1.48 2007/01/04 13:30:37 kls Exp $
|
||||
* $Id: menuitems.c 1.49 2007/06/08 15:16:38 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menuitems.h"
|
||||
#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
#include "i18n.h"
|
||||
#include "plugin.h"
|
||||
#include "remote.h"
|
||||
@ -252,23 +253,64 @@ eOSState cMenuEditChrItem::ProcessKey(eKeys Key)
|
||||
cMenuEditStrItem::cMenuEditStrItem(const char *Name, char *Value, int Length, const char *Allowed)
|
||||
:cMenuEditItem(Name)
|
||||
{
|
||||
orgValue = NULL;
|
||||
value = Value;
|
||||
length = Length;
|
||||
allowed = strdup(Allowed ? Allowed : "");
|
||||
allowed = Allowed;
|
||||
pos = -1;
|
||||
offset = 0;
|
||||
insert = uppercase = false;
|
||||
newchar = true;
|
||||
charMap = tr(" 0\t-.#~,/_@1\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9");
|
||||
currentChar = NULL;
|
||||
lengthUtf8 = 0;
|
||||
valueUtf8 = NULL;
|
||||
allowedUtf8 = NULL;
|
||||
charMapUtf8 = NULL;
|
||||
currentCharUtf8 = NULL;
|
||||
lastKey = kNone;
|
||||
Set();
|
||||
}
|
||||
|
||||
cMenuEditStrItem::~cMenuEditStrItem()
|
||||
{
|
||||
free(orgValue);
|
||||
free(allowed);
|
||||
delete valueUtf8;
|
||||
delete allowedUtf8;
|
||||
delete charMapUtf8;
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::EnterEditMode(void)
|
||||
{
|
||||
if (!valueUtf8) {
|
||||
valueUtf8 = new uint[length];
|
||||
lengthUtf8 = Utf8ToArray(value, valueUtf8, length);
|
||||
int l = strlen(allowed) + 1;
|
||||
allowedUtf8 = new uint[l];
|
||||
Utf8ToArray(allowed, allowedUtf8, l);
|
||||
const char *charMap = tr(" 0\t-.#~,/_@1\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9");
|
||||
l = strlen(charMap) + 1;
|
||||
charMapUtf8 = new uint[l];
|
||||
Utf8ToArray(charMap, charMapUtf8, l);
|
||||
currentCharUtf8 = charMapUtf8;
|
||||
AdvancePos();
|
||||
}
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::LeaveEditMode(bool SaveValue)
|
||||
{
|
||||
if (valueUtf8) {
|
||||
if (SaveValue) {
|
||||
Utf8FromArray(valueUtf8, value, length);
|
||||
stripspace(value);
|
||||
}
|
||||
lengthUtf8 = 0;
|
||||
delete valueUtf8;
|
||||
valueUtf8 = NULL;
|
||||
delete allowedUtf8;
|
||||
allowedUtf8 = NULL;
|
||||
delete charMapUtf8;
|
||||
charMapUtf8 = NULL;
|
||||
pos = -1;
|
||||
offset = 0;
|
||||
newchar = true;
|
||||
}
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::SetHelpKeys(void)
|
||||
@ -279,84 +321,120 @@ void cMenuEditStrItem::SetHelpKeys(void)
|
||||
cSkinDisplay::Current()->SetButtons(NULL);
|
||||
}
|
||||
|
||||
uint *cMenuEditStrItem::IsAllowed(uint c)
|
||||
{
|
||||
if (allowedUtf8) {
|
||||
for (uint *a = allowedUtf8; *a; a++) {
|
||||
if (c == *a)
|
||||
return a;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::AdvancePos(void)
|
||||
{
|
||||
if (pos < length - 2 && pos < int(strlen(value)) ) {
|
||||
if (++pos >= int(strlen(value))) {
|
||||
if (pos >= 2 && value[pos - 1] == ' ' && value[pos - 2] == ' ')
|
||||
if (pos < length - 2 && pos < lengthUtf8) {
|
||||
if (++pos >= lengthUtf8) {
|
||||
if (pos >= 2 && valueUtf8[pos - 1] == ' ' && valueUtf8[pos - 2] == ' ')
|
||||
pos--; // allow only two blanks at the end
|
||||
else {
|
||||
value[pos] = ' ';
|
||||
value[pos + 1] = 0;
|
||||
valueUtf8[pos] = ' ';
|
||||
valueUtf8[pos + 1] = 0;
|
||||
lengthUtf8++;
|
||||
}
|
||||
}
|
||||
}
|
||||
newchar = true;
|
||||
if (!insert && isalpha(value[pos]))
|
||||
uppercase = isupper(value[pos]);
|
||||
if (!insert && Utf8is(alpha, valueUtf8[pos]))
|
||||
uppercase = Utf8is(upper, valueUtf8[pos]);
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::Set(void)
|
||||
{
|
||||
char buf[1000];
|
||||
|
||||
if (InEditMode()) {
|
||||
// This is an ugly hack to make editing strings work with the 'skincurses' plugin.
|
||||
const cFont *font = dynamic_cast<cSkinDisplayMenu *>(cSkinDisplay::Current())->GetTextAreaFont(false);
|
||||
if (!font || font->Width("W") != 1) // all characters have with == 1 in the font used by 'skincurses'
|
||||
font = cFont::GetFont(fontOsd);
|
||||
strncpy(buf, value, pos);
|
||||
snprintf(buf + pos, sizeof(buf) - pos - 2, insert && newchar ? "[]%c%s" : "[%c]%s", *(value + pos), value + pos + 1);
|
||||
|
||||
int width = cSkinDisplay::Current()->EditableWidth();
|
||||
if (font->Width(buf) <= width) {
|
||||
// the whole buffer fits on the screen
|
||||
SetValue(buf);
|
||||
return;
|
||||
}
|
||||
width -= font->Width('>'); // assuming '<' and '>' have the same width
|
||||
int w = 0;
|
||||
int i = 0;
|
||||
int l = strlen(buf);
|
||||
while (i < l && w <= width)
|
||||
w += font->Width(buf[i++]);
|
||||
if (i >= pos + 4) {
|
||||
// the cursor fits on the screen
|
||||
buf[i - 1] = '>';
|
||||
buf[i] = 0;
|
||||
SetValue(buf);
|
||||
return;
|
||||
}
|
||||
// the cursor doesn't fit on the screen
|
||||
w = 0;
|
||||
if (buf[i = pos + 3]) {
|
||||
buf[i] = '>';
|
||||
buf[i + 1] = 0;
|
||||
}
|
||||
else
|
||||
i--;
|
||||
while (i >= 0 && w <= width)
|
||||
w += font->Width(buf[i--]);
|
||||
buf[++i] = '<';
|
||||
SetValue(buf + i);
|
||||
width -= font->Width("[]");
|
||||
width -= font->Width("<>"); // reserving this anyway make the whole thing simpler
|
||||
|
||||
if (pos < offset)
|
||||
offset = pos;
|
||||
int WidthFromOffset = 0;
|
||||
int EndPos = lengthUtf8;
|
||||
for (int i = offset; i < lengthUtf8; i++) {
|
||||
WidthFromOffset += font->Width(valueUtf8[i]);
|
||||
if (WidthFromOffset > width) {
|
||||
if (pos >= i) {
|
||||
do {
|
||||
WidthFromOffset -= font->Width(valueUtf8[offset]);
|
||||
offset++;
|
||||
} while (WidthFromOffset > width && offset < pos);
|
||||
EndPos = pos + 1;
|
||||
}
|
||||
else {
|
||||
EndPos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char buf[1000];
|
||||
char *p = buf;
|
||||
if (offset)
|
||||
*p++ = '<';
|
||||
p += Utf8FromArray(valueUtf8 + offset, p, sizeof(buf) - (p - buf), pos - offset);
|
||||
*p++ = '[';
|
||||
if (insert && newchar)
|
||||
*p++ = ']';
|
||||
p += Utf8FromArray(&valueUtf8[pos], p, sizeof(buf) - (p - buf), 1);
|
||||
if (!(insert && newchar))
|
||||
*p++ = ']';
|
||||
p += Utf8FromArray(&valueUtf8[pos + 1], p, sizeof(buf) - (p - buf), EndPos - pos - 1);
|
||||
if (EndPos != lengthUtf8)
|
||||
*p++ = '>';
|
||||
*p = 0;
|
||||
|
||||
SetValue(buf);
|
||||
}
|
||||
else
|
||||
SetValue(value);
|
||||
}
|
||||
|
||||
char cMenuEditStrItem::Inc(char c, bool Up)
|
||||
uint cMenuEditStrItem::Inc(uint c, bool Up)
|
||||
{
|
||||
const char *p = strchr(allowed, c);
|
||||
uint *p = IsAllowed(c);
|
||||
if (!p)
|
||||
p = allowed;
|
||||
p = allowedUtf8;
|
||||
if (Up) {
|
||||
if (!*++p)
|
||||
p = allowed;
|
||||
p = allowedUtf8;
|
||||
}
|
||||
else if (--p < allowedUtf8) {
|
||||
p = allowedUtf8;
|
||||
while (*p && *(p + 1))
|
||||
p++;
|
||||
}
|
||||
else if (--p < allowed)
|
||||
p = allowed + strlen(allowed) - 1;
|
||||
return *p;
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::Insert(void)
|
||||
{
|
||||
memmove(valueUtf8 + pos + 1, valueUtf8 + pos, (lengthUtf8 - pos + 1) * sizeof(*valueUtf8));
|
||||
lengthUtf8++;
|
||||
valueUtf8[pos] = ' ';
|
||||
}
|
||||
|
||||
void cMenuEditStrItem::Delete(void)
|
||||
{
|
||||
memmove(valueUtf8 + pos, valueUtf8 + pos + 1, (lengthUtf8 - pos) * sizeof(*valueUtf8));
|
||||
lengthUtf8--;
|
||||
}
|
||||
|
||||
eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
{
|
||||
bool SameKey = NORMALKEY(Key) == lastKey;
|
||||
@ -365,7 +443,7 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
else if (!newchar && k0 <= lastKey && lastKey <= k9 && autoAdvanceTimeout.TimedOut()) {
|
||||
AdvancePos();
|
||||
newchar = true;
|
||||
currentChar = NULL;
|
||||
currentCharUtf8 = NULL;
|
||||
Set();
|
||||
return osContinue;
|
||||
}
|
||||
@ -374,7 +452,7 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
if (InEditMode()) {
|
||||
if (!insert || !newchar) {
|
||||
uppercase = !uppercase;
|
||||
value[pos] = uppercase ? toupper(value[pos]) : tolower(value[pos]);
|
||||
valueUtf8[pos] = uppercase ? Utf8to(upper, valueUtf8[pos]) : Utf8to(lower, valueUtf8[pos]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -390,21 +468,21 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
return osUnknown;
|
||||
break;
|
||||
case kYellow|k_Repeat:
|
||||
case kYellow: // Remove the character at current position; in insert mode it is the character to the right of cursor
|
||||
case kYellow: // Remove the character at the current position; in insert mode it is the character to the right of the cursor
|
||||
if (InEditMode()) {
|
||||
if (strlen(value) > 1) {
|
||||
if (!insert || pos < int(strlen(value)) - 1)
|
||||
memmove(value + pos, value + pos + 1, strlen(value) - pos);
|
||||
else if (insert && pos == int(strlen(value)) - 1)
|
||||
value[pos] = ' '; // in insert mode, deleting the last character replaces it with a blank to keep the cursor position
|
||||
if (lengthUtf8 > 1) {
|
||||
if (!insert || pos < lengthUtf8 - 1)
|
||||
Delete();
|
||||
else if (insert && pos == lengthUtf8 - 1)
|
||||
valueUtf8[pos] = ' '; // in insert mode, deleting the last character replaces it with a blank to keep the cursor position
|
||||
// reduce position, if we removed the last character
|
||||
if (pos == int(strlen(value)))
|
||||
if (pos == lengthUtf8)
|
||||
pos--;
|
||||
}
|
||||
else if (strlen(value) == 1)
|
||||
value[0] = ' '; // This is the last character in the string, replace it with a blank
|
||||
if (isalpha(value[pos]))
|
||||
uppercase = isupper(value[pos]);
|
||||
else if (lengthUtf8 == 1)
|
||||
valueUtf8[0] = ' '; // This is the last character in the string, replace it with a blank
|
||||
if (Utf8is(alpha, valueUtf8[pos]))
|
||||
uppercase = Utf8is(upper, valueUtf8[pos]);
|
||||
newchar = true;
|
||||
}
|
||||
else
|
||||
@ -423,13 +501,14 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
pos--;
|
||||
newchar = true;
|
||||
}
|
||||
if (!insert && isalpha(value[pos]))
|
||||
uppercase = isupper(value[pos]);
|
||||
if (!insert && Utf8is(alpha, valueUtf8[pos]))
|
||||
uppercase = Utf8is(upper, valueUtf8[pos]);
|
||||
break;
|
||||
case kRight|k_Repeat:
|
||||
case kRight: AdvancePos();
|
||||
if (pos == 0) {
|
||||
orgValue = strdup(value);
|
||||
case kRight: if (InEditMode())
|
||||
AdvancePos();
|
||||
else {
|
||||
EnterEditMode();
|
||||
SetHelpKeys();
|
||||
}
|
||||
break;
|
||||
@ -439,15 +518,13 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
case kDown: if (InEditMode()) {
|
||||
if (insert && newchar) {
|
||||
// create a new character in insert mode
|
||||
if (int(strlen(value)) < length - 1) {
|
||||
memmove(value + pos + 1, value + pos, strlen(value) - pos + 1);
|
||||
value[pos] = ' ';
|
||||
}
|
||||
if (lengthUtf8 < length - 1)
|
||||
Insert();
|
||||
}
|
||||
if (uppercase)
|
||||
value[pos] = toupper(Inc(tolower(value[pos]), NORMALKEY(Key) == kUp));
|
||||
valueUtf8[pos] = Utf8to(upper, Inc(Utf8to(lower, valueUtf8[pos]), NORMALKEY(Key) == kUp));
|
||||
else
|
||||
value[pos] = Inc( value[pos], NORMALKEY(Key) == kUp);
|
||||
valueUtf8[pos] = Inc( valueUtf8[pos], NORMALKEY(Key) == kUp);
|
||||
newchar = false;
|
||||
}
|
||||
else
|
||||
@ -459,35 +536,33 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
if (!SameKey) {
|
||||
if (!newchar)
|
||||
AdvancePos();
|
||||
currentChar = NULL;
|
||||
currentCharUtf8 = NULL;
|
||||
}
|
||||
if (!currentChar || !*currentChar || *currentChar == '\t') {
|
||||
if (!currentCharUtf8 || !*currentCharUtf8 || *currentCharUtf8 == '\t') {
|
||||
// find the beginning of the character map entry for Key
|
||||
int n = NORMALKEY(Key) - k0;
|
||||
currentChar = charMap;
|
||||
while (n > 0 && *currentChar) {
|
||||
if (*currentChar++ == '\t')
|
||||
currentCharUtf8 = charMapUtf8;
|
||||
while (n > 0 && *currentCharUtf8) {
|
||||
if (*currentCharUtf8++ == '\t')
|
||||
n--;
|
||||
}
|
||||
// find first allowed character
|
||||
while (*currentChar && *currentChar != '\t' && !strchr(allowed, *currentChar))
|
||||
currentChar++;
|
||||
while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8))
|
||||
currentCharUtf8++;
|
||||
}
|
||||
if (*currentChar && *currentChar != '\t') {
|
||||
if (*currentCharUtf8 && *currentCharUtf8 != '\t') {
|
||||
if (insert && newchar) {
|
||||
// create a new character in insert mode
|
||||
if (int(strlen(value)) < length - 1) {
|
||||
memmove(value + pos + 1, value + pos, strlen(value) - pos + 1);
|
||||
value[pos] = ' ';
|
||||
}
|
||||
if (lengthUtf8 < length - 1)
|
||||
Insert();
|
||||
}
|
||||
value[pos] = *currentChar;
|
||||
valueUtf8[pos] = *currentCharUtf8;
|
||||
if (uppercase)
|
||||
value[pos] = toupper(value[pos]);
|
||||
valueUtf8[pos] = Utf8to(upper, valueUtf8[pos]);
|
||||
// find next allowed character
|
||||
do {
|
||||
currentChar++;
|
||||
} while (*currentChar && *currentChar != '\t' && !strchr(allowed, *currentChar));
|
||||
currentCharUtf8++;
|
||||
} while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8));
|
||||
newchar = false;
|
||||
autoAdvanceTimeout.Set(AUTO_ADVANCE_TIMEOUT);
|
||||
}
|
||||
@ -498,32 +573,25 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
break;
|
||||
case kBack:
|
||||
case kOk: if (InEditMode()) {
|
||||
if (Key == kBack && orgValue) {
|
||||
strcpy(value, orgValue);
|
||||
free(orgValue);
|
||||
orgValue = NULL;
|
||||
}
|
||||
pos = -1;
|
||||
newchar = true;
|
||||
stripspace(value);
|
||||
LeaveEditMode(Key == kOk);
|
||||
SetHelpKeys();
|
||||
break;
|
||||
}
|
||||
// run into default
|
||||
default: if (InEditMode() && BASICKEY(Key) == kKbd) {
|
||||
int c = KEYKBD(Key);
|
||||
if (c <= 0xFF) {
|
||||
const char *p = strchr(allowed, tolower(c));
|
||||
if (c <= 0xFF) { // FIXME what about other UTF-8 characters?
|
||||
uint *p = IsAllowed(Utf8to(lower, c));
|
||||
if (p) {
|
||||
int l = strlen(value);
|
||||
if (insert && l < length - 1)
|
||||
memmove(value + pos + 1, value + pos, l - pos + 1);
|
||||
value[pos] = c;
|
||||
if (insert && lengthUtf8 < length - 1)
|
||||
Insert();
|
||||
valueUtf8[pos] = c;
|
||||
if (pos < length - 2)
|
||||
pos++;
|
||||
if (pos >= l) {
|
||||
value[pos] = ' ';
|
||||
value[pos + 1] = 0;
|
||||
if (pos >= lengthUtf8) {
|
||||
valueUtf8[pos] = ' ';
|
||||
valueUtf8[pos + 1] = 0;
|
||||
lengthUtf8 = pos + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -540,7 +608,7 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||
else {
|
||||
switch (c) {
|
||||
case kfHome: pos = 0; break;
|
||||
case kfEnd: pos = strlen(value) - 1; break;
|
||||
case kfEnd: pos = lengthUtf8 - 1; break;
|
||||
case kfIns: return ProcessKey(kGreen);
|
||||
case kfDel: return ProcessKey(kYellow);
|
||||
}
|
||||
@ -690,7 +758,7 @@ void cMenuEditDateItem::Set(void)
|
||||
#define DATEBUFFERSIZE 32
|
||||
char buf[DATEBUFFERSIZE];
|
||||
if (weekdays && *weekdays) {
|
||||
SetValue(cTimer::PrintDay(0, *weekdays));
|
||||
SetValue(cTimer::PrintDay(0, *weekdays, false));
|
||||
return;
|
||||
}
|
||||
else if (*value) {
|
||||
@ -880,9 +948,7 @@ cMenuSetupPage::cMenuSetupPage(void)
|
||||
|
||||
void cMenuSetupPage::SetSection(const char *Section)
|
||||
{
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "%s - %s", tr("Setup"), Section);
|
||||
SetTitle(buf);
|
||||
SetTitle(cString::sprintf("%s - %s", tr("Setup"), Section));
|
||||
}
|
||||
|
||||
eOSState cMenuSetupPage::ProcessKey(eKeys Key)
|
||||
@ -903,9 +969,7 @@ eOSState cMenuSetupPage::ProcessKey(eKeys Key)
|
||||
void cMenuSetupPage::SetPlugin(cPlugin *Plugin)
|
||||
{
|
||||
plugin = Plugin;
|
||||
char buf[40];
|
||||
snprintf(buf, sizeof(buf), "%s '%s'", tr("Plugin"), plugin->Name());
|
||||
SetSection(buf);
|
||||
SetSection(cString::sprintf("%s '%s'", tr("Plugin"), plugin->Name()));
|
||||
}
|
||||
|
||||
void cMenuSetupPage::SetupStore(const char *Name, const char *Value)
|
||||
|
23
menuitems.h
23
menuitems.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menuitems.h 1.20 2006/04/14 10:01:47 kls Exp $
|
||||
* $Id: menuitems.h 1.21 2007/06/08 11:53:37 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MENUITEMS_H
|
||||
@ -77,22 +77,29 @@ public:
|
||||
|
||||
class cMenuEditStrItem : public cMenuEditItem {
|
||||
private:
|
||||
char *orgValue;
|
||||
char *value;
|
||||
int length;
|
||||
char *allowed;
|
||||
int pos;
|
||||
const char *allowed;
|
||||
int pos, offset;
|
||||
bool insert, newchar, uppercase;
|
||||
const char *charMap;
|
||||
const char *currentChar;
|
||||
int lengthUtf8;
|
||||
uint *valueUtf8;
|
||||
uint *allowedUtf8;
|
||||
uint *charMapUtf8;
|
||||
uint *currentCharUtf8;
|
||||
eKeys lastKey;
|
||||
cTimeMs autoAdvanceTimeout;
|
||||
void SetHelpKeys(void);
|
||||
uint *IsAllowed(uint c);
|
||||
void AdvancePos(void);
|
||||
virtual void Set(void);
|
||||
char Inc(char c, bool Up);
|
||||
uint Inc(uint c, bool Up);
|
||||
void Insert(void);
|
||||
void Delete(void);
|
||||
protected:
|
||||
bool InEditMode(void) { return pos >= 0; }
|
||||
void EnterEditMode(void);
|
||||
void LeaveEditMode(bool SaveValue = false);
|
||||
bool InEditMode(void) { return valueUtf8 != NULL; }
|
||||
public:
|
||||
cMenuEditStrItem(const char *Name, char *Value, int Length, const char *Allowed);
|
||||
~cMenuEditStrItem();
|
||||
|
4
nit.h
4
nit.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: nit.h 1.2 2004/01/18 16:31:08 kls Exp $
|
||||
* $Id: nit.h 1.3 2007/06/10 08:50:21 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __NIT_H
|
||||
@ -13,7 +13,7 @@
|
||||
#include "filter.h"
|
||||
|
||||
#define MAXNITS 16
|
||||
#define MAXNETWORKNAME 256
|
||||
#define MAXNETWORKNAME Utf8BufSize(256)
|
||||
|
||||
class cNitFilter : public cFilter {
|
||||
private:
|
||||
|
95
osd.c
95
osd.c
@ -4,11 +4,12 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osd.c 1.68 2007/02/17 16:05:52 kls Exp $
|
||||
* $Id: osd.c 1.69 2007/06/10 12:16:36 kls Exp $
|
||||
*/
|
||||
|
||||
#include "osd.h"
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
@ -20,6 +21,18 @@
|
||||
cPalette::cPalette(int Bpp)
|
||||
{
|
||||
SetBpp(Bpp);
|
||||
SetAntiAliasGranularity(10, 10);
|
||||
}
|
||||
|
||||
void cPalette::SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
|
||||
{
|
||||
if (FixedColors >= MAXNUMCOLORS || BlendColors == 0)
|
||||
antiAliasGranularity = MAXNUMCOLORS - 1;
|
||||
else {
|
||||
int ColorsForBlending = MAXNUMCOLORS - FixedColors;
|
||||
int ColorsPerBlend = ColorsForBlending / BlendColors + 2; // +2 = the full foreground and background colors, which are amoung the fixed colors
|
||||
antiAliasGranularity = double(MAXNUMCOLORS - 1) / (ColorsPerBlend - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cPalette::Reset(void)
|
||||
@ -30,18 +43,23 @@ void cPalette::Reset(void)
|
||||
|
||||
int cPalette::Index(tColor Color)
|
||||
{
|
||||
// Check if color is already defined:
|
||||
for (int i = 0; i < numColors; i++) {
|
||||
if (color[i] == Color)
|
||||
return i;
|
||||
}
|
||||
// No exact color, try a close one:
|
||||
int i = ClosestColor(Color, 4);
|
||||
if (i >= 0)
|
||||
return i;
|
||||
// No close one, try to define a new one:
|
||||
if (numColors < maxColors) {
|
||||
color[numColors++] = Color;
|
||||
modified = true;
|
||||
return numColors - 1;
|
||||
}
|
||||
dsyslog("too many different colors used in palette");
|
||||
//TODO: return the index of the "closest" color?
|
||||
return 0;
|
||||
// Out of colors, so any close color must do:
|
||||
return ClosestColor(Color);
|
||||
}
|
||||
|
||||
void cPalette::SetBpp(int Bpp)
|
||||
@ -91,6 +109,48 @@ void cPalette::Replace(const cPalette &Palette)
|
||||
for (int i = 0; i < Palette.numColors; i++)
|
||||
SetColor(i, Palette.color[i]);
|
||||
numColors = Palette.numColors;
|
||||
antiAliasGranularity = Palette.antiAliasGranularity;
|
||||
}
|
||||
|
||||
tColor cPalette::Blend(tColor ColorFg, tColor ColorBg, uint8_t Level)
|
||||
{
|
||||
if (antiAliasGranularity > 0)
|
||||
Level = uint8_t(int(Level / antiAliasGranularity + 0.5) * antiAliasGranularity);
|
||||
int Af = (ColorFg & 0xFF000000) >> 24;
|
||||
int Rf = (ColorFg & 0x00FF0000) >> 16;
|
||||
int Gf = (ColorFg & 0x0000FF00) >> 8;
|
||||
int Bf = (ColorFg & 0x000000FF);
|
||||
int Ab = (ColorBg & 0xFF000000) >> 24;
|
||||
int Rb = (ColorBg & 0x00FF0000) >> 16;
|
||||
int Gb = (ColorBg & 0x0000FF00) >> 8;
|
||||
int Bb = (ColorBg & 0x000000FF);
|
||||
int A = (Ab + (Af - Ab) * Level / 0xFF) & 0xFF;
|
||||
int R = (Rb + (Rf - Rb) * Level / 0xFF) & 0xFF;
|
||||
int G = (Gb + (Gf - Gb) * Level / 0xFF) & 0xFF;
|
||||
int B = (Bb + (Bf - Bb) * Level / 0xFF) & 0xFF;
|
||||
return (A << 24) | (R << 16) | (G << 8) | B;
|
||||
}
|
||||
|
||||
int cPalette::ClosestColor(tColor Color, int MaxDiff)
|
||||
{
|
||||
int n = 0;
|
||||
int d = INT_MAX;
|
||||
int A1 = (Color & 0xFF000000) >> 24;
|
||||
int R1 = (Color & 0x00FF0000) >> 16;
|
||||
int G1 = (Color & 0x0000FF00) >> 8;
|
||||
int B1 = (Color & 0x000000FF);
|
||||
for (int i = 0; i < numColors; i++) {
|
||||
int A2 = (color[i] & 0xFF000000) >> 24;
|
||||
int R2 = (color[i] & 0x00FF0000) >> 16;
|
||||
int G2 = (color[i] & 0x0000FF00) >> 8;
|
||||
int B2 = (color[i] & 0x000000FF);
|
||||
int diff = (abs(A1 - A2) << 1) + (abs(R1 - R2) << 1) + (abs(G1 - G2) << 1) + (abs(B1 - B2) << 1);
|
||||
if (diff < d) {
|
||||
d = diff;
|
||||
n = i;
|
||||
}
|
||||
}
|
||||
return d <= MaxDiff ? n : -1;
|
||||
}
|
||||
|
||||
// --- cBitmap ---------------------------------------------------------------
|
||||
@ -424,26 +484,7 @@ void cBitmap::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Color
|
||||
return;
|
||||
x -= x0;
|
||||
y -= y0;
|
||||
tIndex fg = Index(ColorFg);
|
||||
tIndex bg = (ColorBg != clrTransparent) ? Index(ColorBg) : 0;
|
||||
while (s && *s) {
|
||||
const cFont::tCharData *CharData = Font->CharData(*s++);
|
||||
if (limit && int(x + CharData->width) > limit)
|
||||
break; // we don't draw partial characters
|
||||
if (int(x + CharData->width) > 0) {
|
||||
for (int row = 0; row < h; row++) {
|
||||
cFont::tPixelData PixelData = CharData->lines[row];
|
||||
for (int col = CharData->width; col-- > 0; ) {
|
||||
if (ColorBg != clrTransparent || (PixelData & 1))
|
||||
SetIndex(x + col, y + row, (PixelData & 1) ? fg : bg);
|
||||
PixelData >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
x += CharData->width;
|
||||
if (x > width - 1)
|
||||
break;
|
||||
}
|
||||
Font->DrawText(this, x, y, s, ColorFg, ColorBg, limit);
|
||||
}
|
||||
}
|
||||
|
||||
@ -623,6 +664,12 @@ cOsd::~cOsd()
|
||||
isOpen--;
|
||||
}
|
||||
|
||||
void cOsd::SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
|
||||
{
|
||||
for (int i = 0; i < numBitmaps; i++)
|
||||
bitmaps[i]->SetAntiAliasGranularity(FixedColors, BlendColors);
|
||||
}
|
||||
|
||||
cBitmap *cOsd::GetBitmap(int Area)
|
||||
{
|
||||
return Area < numBitmaps ? bitmaps[Area] : NULL;
|
||||
|
44
osd.h
44
osd.h
@ -4,12 +4,13 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osd.h 1.53 2006/02/26 14:45:05 kls Exp $
|
||||
* $Id: osd.h 1.54 2007/06/10 12:15:52 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __OSD_H
|
||||
#define __OSD_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "font.h"
|
||||
@ -41,7 +42,7 @@ enum eOsdError { oeOk,
|
||||
oeUnknown,
|
||||
};
|
||||
|
||||
typedef uint32_t tColor;
|
||||
typedef uint32_t tColor; // see also font.h
|
||||
typedef uint8_t tIndex;
|
||||
|
||||
class cPalette {
|
||||
@ -50,11 +51,22 @@ private:
|
||||
int bpp;
|
||||
int maxColors, numColors;
|
||||
bool modified;
|
||||
double antiAliasGranularity;
|
||||
protected:
|
||||
typedef tIndex tIndexes[MAXNUMCOLORS];
|
||||
public:
|
||||
cPalette(int Bpp = 8);
|
||||
///< Initializes the palette with the given color depth.
|
||||
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors);
|
||||
///< Allows the system to optimize utilization of the limited color
|
||||
///< palette entries when generating blended colors for anti-aliasing.
|
||||
///< FixedColors is the maximum number of colors used, and BlendColors
|
||||
///< is the maximum number of foreground/background color combinations
|
||||
///< used with anti-aliasing. If this function is not called with
|
||||
///< useful values, the palette may be filled up with many shades of
|
||||
///< a single color combination, and may not be able to serve all
|
||||
///< requested colors. By default the palette assumes there will be
|
||||
///< 10 fixed colors and 10 color combinations.
|
||||
int Bpp(void) { return bpp; }
|
||||
void Reset(void);
|
||||
///< Resets the palette, making it contain no colors.
|
||||
@ -62,7 +74,7 @@ public:
|
||||
///< Returns the index of the given Color (the first color has index 0).
|
||||
///< If Color is not yet contained in this palette, it will be added if
|
||||
///< there is a free slot. If the color can't be added to this palette,
|
||||
///< 0 will be returned.
|
||||
///< the closest existing color will be returned.
|
||||
tColor Color(int Index) { return Index < maxColors ? color[Index] : 0; }
|
||||
///< Returns the color at the given Index. If Index is outside the valid
|
||||
///< range, 0 will be returned.
|
||||
@ -88,6 +100,18 @@ public:
|
||||
void Replace(const cPalette &Palette);
|
||||
///< Replaces the colors of this palette with the colors from the given
|
||||
///< palette.
|
||||
tColor Blend(tColor ColorFg, tColor ColorBg, uint8_t Level);
|
||||
///< Determines a color that consists of a linear blend between ColorFg
|
||||
///< and ColorBg. If Level is 0, the result is ColorBg, if it is 255,
|
||||
///< the result is ColorFg. If SetAntiAliasGranularity() has been called previously,
|
||||
///< Level will be mapped to a limited range of levels that allow to make best
|
||||
///< use of the palette entries.
|
||||
int ClosestColor(tColor Color, int MaxDiff = INT_MAX);
|
||||
///< Returns the index of a color in this paltte that is closest to the given
|
||||
///< Color. MaxDiff can be used to control the maximum allowed color difference.
|
||||
///< If no color with a maximum difference of MaxDiff can be found, -1 will
|
||||
///< be returned. With the default value of INT_MAX, there will always be
|
||||
///< a valid color index returned, but the color may be completely different.
|
||||
};
|
||||
|
||||
enum eTextAlignment { taCenter = 0x00,
|
||||
@ -98,6 +122,8 @@ enum eTextAlignment { taCenter = 0x00,
|
||||
taDefault = taTop | taLeft
|
||||
};
|
||||
|
||||
class cFont;
|
||||
|
||||
class cBitmap : public cPalette {
|
||||
private:
|
||||
tIndex *bitmap;
|
||||
@ -202,6 +228,8 @@ public:
|
||||
///< 7: vertical, falling, upper
|
||||
const tIndex *Data(int x, int y);
|
||||
///< Returns the address of the index byte at the given coordinates.
|
||||
tColor GetColor(int x, int y) { return Color(*Data(x, y)); }
|
||||
///< Returns the color at the given coordinates.
|
||||
};
|
||||
|
||||
struct tArea {
|
||||
@ -247,6 +275,16 @@ public:
|
||||
int Top(void) { return top; }
|
||||
int Width(void) { return width; }
|
||||
int Height(void) { return height; }
|
||||
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors);
|
||||
///< Allows the system to optimize utilization of the limited color
|
||||
///< palette entries when generating blended colors for anti-aliasing.
|
||||
///< FixedColors is the maximum number of colors used, and BlendColors
|
||||
///< is the maximum number of foreground/background color combinations
|
||||
///< used with anti-aliasing. If this function is not called with
|
||||
///< useful values, the palette may be filled up with many shades of
|
||||
///< a single color combination, and may not be able to serve all
|
||||
///< requested colors. By default the palette assumes there will be
|
||||
///< 10 fixed colors and 10 color combinations.
|
||||
cBitmap *GetBitmap(int Area);
|
||||
///< Returns a pointer to the bitmap for the given Area, or NULL if no
|
||||
///< such bitmap exists.
|
||||
|
22
osdbase.c
22
osdbase.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osdbase.c 1.30 2007/01/07 14:41:16 kls Exp $
|
||||
* $Id: osdbase.c 1.31 2007/06/09 10:07:46 kls Exp $
|
||||
*/
|
||||
|
||||
#include "osdbase.h"
|
||||
@ -86,10 +86,8 @@ cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
|
||||
subMenu = NULL;
|
||||
helpRed = helpGreen = helpYellow = helpBlue = NULL;
|
||||
status = NULL;
|
||||
if (!displayMenuCount++) {
|
||||
displayMenu = Skins.Current()->DisplayMenu();
|
||||
displayMenuItems = displayMenu->MaxItems();
|
||||
}
|
||||
if (!displayMenuCount++)
|
||||
SetDisplayMenu();
|
||||
}
|
||||
|
||||
cOsdMenu::~cOsdMenu()
|
||||
@ -103,15 +101,25 @@ cOsdMenu::~cOsdMenu()
|
||||
DELETENULL(displayMenu);
|
||||
}
|
||||
|
||||
void cOsdMenu::SetDisplayMenu(void)
|
||||
{
|
||||
if (displayMenu) {
|
||||
displayMenu->Clear();
|
||||
delete displayMenu;
|
||||
}
|
||||
displayMenu = Skins.Current()->DisplayMenu();
|
||||
displayMenuItems = displayMenu->MaxItems();
|
||||
}
|
||||
|
||||
const char *cOsdMenu::hk(const char *s)
|
||||
{
|
||||
static char buffer[64];
|
||||
static cString buffer;
|
||||
if (s && hasHotkeys) {
|
||||
if (digit == 0 && '1' <= *s && *s <= '9' && *(s + 1) == ' ')
|
||||
digit = -1; // prevents automatic hotkeys - input already has them
|
||||
if (digit >= 0) {
|
||||
digit++;
|
||||
snprintf(buffer, sizeof(buffer), " %c %s", (digit < 10) ? '0' + digit : ' ' , s);
|
||||
buffer = cString::sprintf(" %c %s", (digit < 10) ? '0' + digit : ' ' , s);
|
||||
s = buffer;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: osdbase.h 1.15 2007/01/07 14:41:32 kls Exp $
|
||||
* $Id: osdbase.h 1.16 2007/06/09 11:49:00 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __OSDBASE_H
|
||||
@ -96,6 +96,7 @@ private:
|
||||
int digit;
|
||||
bool hasHotkeys;
|
||||
protected:
|
||||
void SetDisplayMenu(void);
|
||||
cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; }
|
||||
const char *hk(const char *s);
|
||||
void SetCols(int c0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
|
||||
|
8
sdt.c
8
sdt.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: sdt.c 1.16 2006/04/15 14:12:21 kls Exp $
|
||||
* $Id: sdt.c 1.17 2007/06/10 08:50:49 kls Exp $
|
||||
*/
|
||||
|
||||
#include "sdt.h"
|
||||
@ -56,9 +56,9 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
|
||||
case 0x04: // NVOD reference service
|
||||
case 0x05: // NVOD time-shifted service
|
||||
{
|
||||
char NameBuf[1024];
|
||||
char ShortNameBuf[1024];
|
||||
char ProviderNameBuf[1024];
|
||||
char NameBuf[Utf8BufSize(1024)];
|
||||
char ShortNameBuf[Utf8BufSize(1024)];
|
||||
char ProviderNameBuf[Utf8BufSize(1024)];
|
||||
sd->serviceName.getText(NameBuf, ShortNameBuf, sizeof(NameBuf), sizeof(ShortNameBuf));
|
||||
char *pn = compactspace(NameBuf);
|
||||
char *ps = compactspace(ShortNameBuf);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinclassic.c 1.15 2006/03/31 13:59:50 kls Exp $
|
||||
* $Id: skinclassic.c 1.16 2007/06/10 12:42:02 kls Exp $
|
||||
*/
|
||||
|
||||
#include "skinclassic.h"
|
||||
@ -94,8 +94,13 @@ cSkinClassicDisplayChannel::cSkinClassicDisplayChannel(bool WithInfo)
|
||||
message = false;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - Lines * lineHeight));
|
||||
timeWidth = font->Width("00:00") + 4;
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, Lines * lineHeight - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, Lines * lineHeight - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, Lines * lineHeight - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(0, 0, osd->Width() - 1, osd->Height() - 1, Theme.Color(clrBackground));
|
||||
}
|
||||
|
||||
@ -142,7 +147,9 @@ void cSkinClassicDisplayChannel::Flush(void)
|
||||
{
|
||||
if (!message) {
|
||||
cString date = DayDateTime();
|
||||
osd->DrawText(osd->Width() - cFont::GetFont(fontSml)->Width(date) - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml));
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
int w = font->Width(date);
|
||||
osd->DrawText(osd->Width() - w - 2, 0, date, Theme.Color(clrChannelDate), Theme.Color(clrBackground), cFont::GetFont(fontSml), w);
|
||||
}
|
||||
osd->Flush();
|
||||
}
|
||||
@ -155,6 +162,7 @@ private:
|
||||
int x0, x1;
|
||||
int y0, y1, y2, y3, y4, y5;
|
||||
int lineHeight;
|
||||
cString lastDate;
|
||||
void SetScrollbar(void);
|
||||
public:
|
||||
cSkinClassicDisplayMenu(void);
|
||||
@ -187,15 +195,20 @@ cSkinClassicDisplayMenu::cSkinClassicDisplayMenu(void)
|
||||
y4 = y5 - lineHeight;
|
||||
y3 = y4 - lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop);
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y1 - 1, 2 },
|
||||
{ x0, y1, x1 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x1 - 1, y5 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y5 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y1 - 1, 2 },
|
||||
{ x0, y1, x1 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x1 - 1, y5 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y5 - 1, Theme.Color(clrBackground));
|
||||
}
|
||||
@ -305,9 +318,10 @@ void cSkinClassicDisplayMenu::SetEvent(const cEvent *Event)
|
||||
ts.Set(osd, xl, y, x1 - xl, y3 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||
char *buffer;
|
||||
asprintf(&buffer, " VPS: %s", *Event->GetVpsString());
|
||||
asprintf(&buffer, " VPS: %s ", *Event->GetVpsString());
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
osd->DrawText(x1 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font);
|
||||
int w = font->Width(buffer);
|
||||
osd->DrawText(x1 - w, y, buffer, Theme.Color(clrMenuEventVpsFg), Theme.Color(clrMenuEventVpsBg), font, w);
|
||||
free(buffer);
|
||||
}
|
||||
y += ts.Height();
|
||||
@ -376,8 +390,12 @@ const cFont *cSkinClassicDisplayMenu::GetTextAreaFont(bool FixedFont) const
|
||||
void cSkinClassicDisplayMenu::Flush(void)
|
||||
{
|
||||
cString date = DayDateTime();
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
osd->DrawText(x1 - font->Width(date) - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font);
|
||||
if (!lastDate || strcmp(date, lastDate)) {
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
int w = font->Width(date);
|
||||
osd->DrawText(x1 - w - 2, y0, date, Theme.Color(clrMenuDate), Theme.Color(clrMenuTitleBg), font, w);
|
||||
lastDate = date;
|
||||
}
|
||||
osd->Flush();
|
||||
}
|
||||
|
||||
@ -414,8 +432,13 @@ cSkinClassicDisplayReplay::cSkinClassicDisplayReplay(bool ModeOnly)
|
||||
y2 = 2 * lineHeight;
|
||||
y3 = 3 * lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y3);
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y3 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y3 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
|
||||
}
|
||||
|
||||
@ -455,14 +478,15 @@ void cSkinClassicDisplayReplay::SetCurrent(const char *Current)
|
||||
{
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
int w = font->Width(Current);
|
||||
osd->DrawText(x0, y2, Current, Theme.Color(clrReplayCurrent), Theme.Color(clrBackground), font, lastCurrentWidth > w ? lastCurrentWidth : 0);
|
||||
osd->DrawText(x0, y2, Current, Theme.Color(clrReplayCurrent), Theme.Color(clrBackground), font, lastCurrentWidth > w ? lastCurrentWidth : w);
|
||||
lastCurrentWidth = w;
|
||||
}
|
||||
|
||||
void cSkinClassicDisplayReplay::SetTotal(const char *Total)
|
||||
{
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
osd->DrawText(x1 - font->Width(Total), y2, Total, Theme.Color(clrReplayTotal), Theme.Color(clrBackground), font);
|
||||
int w = font->Width(Total);
|
||||
osd->DrawText(x1 - font->Width(Total), y2, Total, Theme.Color(clrReplayTotal), Theme.Color(clrBackground), font, w);
|
||||
}
|
||||
|
||||
void cSkinClassicDisplayReplay::SetJump(const char *Jump)
|
||||
@ -503,8 +527,13 @@ cSkinClassicDisplayVolume::cSkinClassicDisplayVolume(void)
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
int lineHeight = font->Height();
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - lineHeight);
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
}
|
||||
|
||||
cSkinClassicDisplayVolume::~cSkinClassicDisplayVolume()
|
||||
@ -572,8 +601,13 @@ cSkinClassicDisplayTracks::cSkinClassicDisplayTracks(const char *Title, int NumT
|
||||
y1 = lineHeight;
|
||||
y2 = y1 + NumTracks * lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y2);
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x1 - 1, y2 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawText(x0, y0, Title, Theme.Color(clrMenuTitleFg), Theme.Color(clrMenuTitleBg), font, x1 - x0);
|
||||
for (int i = 0; i < NumTracks; i++)
|
||||
SetItem(Tracks[i], i, false);
|
||||
@ -630,8 +664,13 @@ cSkinClassicDisplayMessage::cSkinClassicDisplayMessage(void)
|
||||
const cFont *font = cFont::GetFont(fontOsd);
|
||||
int lineHeight = font->Height();
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - lineHeight);
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 2 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { 0, 0, Setup.OSDWidth - 1, lineHeight - 1, 2 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
}
|
||||
|
||||
cSkinClassicDisplayMessage::~cSkinClassicDisplayMessage()
|
||||
|
116
skinsttng.c
116
skinsttng.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: skinsttng.c 1.19 2006/02/17 15:57:37 kls Exp $
|
||||
* $Id: skinsttng.c 1.20 2007/06/10 12:40:43 kls Exp $
|
||||
*/
|
||||
|
||||
// Star Trek: The Next Generation® is a registered trademark of Paramount Pictures
|
||||
@ -178,8 +178,13 @@ cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo)
|
||||
int yt = (y0 + y1) / 2;
|
||||
int yb = (y6 + y7) / 2;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - y7));
|
||||
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||
osd->DrawRectangle(x0, y6, x1 - 1, y7 - 1, clrTransparent);
|
||||
@ -211,8 +216,13 @@ cSkinSTTNGDisplayChannel::cSkinSTTNGDisplayChannel(bool WithInfo)
|
||||
y0 = 0;
|
||||
y1 = lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + (Setup.ChannelInfoPos ? 0 : Setup.OSDHeight - y1));
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
|
||||
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
|
||||
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||
@ -297,7 +307,7 @@ void cSkinSTTNGDisplayChannel::Flush(void)
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
cString date = DayDateTime();
|
||||
int w = font->Width(date);
|
||||
osd->DrawText(x4 - w - 2, y7 - font->Height(date), date, Theme.Color(clrChannelDate), frameColor, font);
|
||||
osd->DrawText(x4 - w - 2, y7 - font->Height(), date, Theme.Color(clrChannelDate), frameColor, font, w);
|
||||
cDevice *Device = cDevice::PrimaryDevice();
|
||||
const tTrackId *Track = Device->GetTrack(Device->GetCurrentAudioTrack());
|
||||
if (!Track && *lastTrackId.description || Track && strcmp(lastTrackId.description, Track->description)) {
|
||||
@ -333,6 +343,7 @@ private:
|
||||
tColor frameColor;
|
||||
int currentIndex;
|
||||
bool message;
|
||||
cString lastDate;
|
||||
void SetScrollbar(void);
|
||||
public:
|
||||
cSkinSTTNGDisplayMenu(void);
|
||||
@ -378,17 +389,22 @@ cSkinSTTNGDisplayMenu::cSkinSTTNGDisplayMenu(void)
|
||||
int yt = (y0 + y1) / 2;
|
||||
int yb = (y6 + y7) / 2;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop);
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x3 - 1, y4 - 1, 1 },
|
||||
{ x3, y3, x4 - 1, y4 - 1, 2 },
|
||||
{ x4, y3, x7 - 1, y4 - 1, 2 },
|
||||
{ x0, y4, x7 - 1, y7 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x3 - 1, y4 - 1, 1 },
|
||||
{ x3, y3, x4 - 1, y4 - 1, 2 },
|
||||
{ x4, y3, x7 - 1, y4 - 1, 2 },
|
||||
{ x0, y4, x7 - 1, y7 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||
@ -465,7 +481,7 @@ void cSkinSTTNGDisplayMenu::SetTitle(const char *Title)
|
||||
const char *VDR = " VDR";
|
||||
int w = font->Width(VDR);
|
||||
osd->DrawText(x3 + 5, y0, Title, Theme.Color(clrMenuTitle), frameColor, font, x4 - w - x3 - 5);
|
||||
osd->DrawText(x4 - w, y0, VDR, frameColor, clrBlack, font);
|
||||
osd->DrawText(x4 - w, y0, VDR, frameColor, clrBlack, font, w, lineHeight);
|
||||
}
|
||||
|
||||
void cSkinSTTNGDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||
@ -551,9 +567,10 @@ void cSkinSTTNGDisplayMenu::SetEvent(const cEvent *Event)
|
||||
ts.Set(osd, xl, y, x4 - xl, y4 - y, t, font, Theme.Color(clrMenuEventTime), Theme.Color(clrBackground));
|
||||
if (Event->Vps() && Event->Vps() != Event->StartTime()) {
|
||||
char *buffer;
|
||||
asprintf(&buffer, " VPS: %s", *Event->GetVpsString());
|
||||
asprintf(&buffer, " VPS: %s ", *Event->GetVpsString());
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
osd->DrawText(x4 - font->Width(buffer), y, buffer, Theme.Color(clrMenuEventVps), frameColor, font);
|
||||
int w = font->Width(buffer);
|
||||
osd->DrawText(x4 - w, y, buffer, Theme.Color(clrMenuEventVps), frameColor, font, w);
|
||||
int yb = y + font->Height();
|
||||
osd->DrawRectangle(x5, y, x6 - 1, yb - 1, frameColor);
|
||||
osd->DrawEllipse (x6, y, x7 - 1, yb - 1, frameColor, 5);
|
||||
@ -640,8 +657,12 @@ void cSkinSTTNGDisplayMenu::Flush(void)
|
||||
{
|
||||
if (!message) {
|
||||
cString date = DayDateTime();
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
osd->DrawText(x4 - font->Width(date) - 2, y7 - font->Height(date), date, Theme.Color(clrMenuDate), frameColor, font);
|
||||
if (!lastDate || strcmp(date, lastDate)) {
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
int w = font->Width(date);
|
||||
osd->DrawText(x4 - w - 2, y7 - font->Height(), date, Theme.Color(clrMenuDate), frameColor, font, w);
|
||||
lastDate = date;
|
||||
}
|
||||
}
|
||||
osd->Flush();
|
||||
}
|
||||
@ -697,8 +718,13 @@ cSkinSTTNGDisplayReplay::cSkinSTTNGDisplayReplay(bool ModeOnly)
|
||||
int yt = (y0 + y1) / 2;
|
||||
int yb = (y6 + y7) / 2;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y7);
|
||||
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { 0, 0, x7 - 1, y7 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, ModeOnly ? clrTransparent : Theme.Color(clrBackground));
|
||||
if (!ModeOnly) {
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||
@ -760,14 +786,15 @@ void cSkinSTTNGDisplayReplay::SetCurrent(const char *Current)
|
||||
{
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
int w = font->Width(Current);
|
||||
osd->DrawText(x3, y6, Current, Theme.Color(clrReplayCurrent), frameColor, font, lastCurrentWidth > w ? lastCurrentWidth : 0);
|
||||
osd->DrawText(x3, y6, Current, Theme.Color(clrReplayCurrent), frameColor, font, lastCurrentWidth > w ? lastCurrentWidth : w);
|
||||
lastCurrentWidth = w;
|
||||
}
|
||||
|
||||
void cSkinSTTNGDisplayReplay::SetTotal(const char *Total)
|
||||
{
|
||||
const cFont *font = cFont::GetFont(fontSml);
|
||||
osd->DrawText(x4 - font->Width(Total) - 5, y6, Total, Theme.Color(clrReplayTotal), frameColor, font);
|
||||
int w = font->Width(Total);
|
||||
osd->DrawText(x4 - w - 5, y6, Total, Theme.Color(clrReplayTotal), frameColor, font, w);
|
||||
}
|
||||
|
||||
void cSkinSTTNGDisplayReplay::SetJump(const char *Jump)
|
||||
@ -825,8 +852,13 @@ cSkinSTTNGDisplayVolume::cSkinSTTNGDisplayVolume(void)
|
||||
y0 = 0;
|
||||
y1 = lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y1);
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 4 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
|
||||
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
|
||||
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||
@ -935,17 +967,22 @@ cSkinSTTNGDisplayTracks::cSkinSTTNGDisplayTracks(const char *Title, int NumTrack
|
||||
int yt = (y0 + y1) / 2;
|
||||
int yb = (y6 + y7) / 2;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y7);
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x3 - 1, y4 - 1, 1 },
|
||||
{ x3, y3, x4 - 1, y4 - 1, 2 },
|
||||
{ x4, y3, x7 - 1, y4 - 1, 2 },
|
||||
{ x0, y4, x7 - 1, y7 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y7 - 1, 4 } };
|
||||
if (osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y3 - 1, 2 },
|
||||
{ x0, y3, x3 - 1, y4 - 1, 1 },
|
||||
{ x3, y3, x4 - 1, y4 - 1, 2 },
|
||||
{ x4, y3, x7 - 1, y4 - 1, 2 },
|
||||
{ x0, y4, x7 - 1, y7 - 1, 4 }
|
||||
};
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y7 - 1, Theme.Color(clrBackground));
|
||||
osd->DrawRectangle(x0, y0, x1 - 1, y1 - 1, clrTransparent);
|
||||
@ -1057,8 +1094,13 @@ cSkinSTTNGDisplayMessage::cSkinSTTNGDisplayMessage(void)
|
||||
y0 = 0;
|
||||
y1 = lineHeight;
|
||||
osd = cOsdProvider::NewOsd(Setup.OSDLeft, Setup.OSDTop + Setup.OSDHeight - y1);
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 8 } };
|
||||
if (Setup.AntiAlias && osd->CanHandleAreas(Areas, sizeof(Areas) / sizeof(tArea)) == oeOk)
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
else {
|
||||
tArea Areas[] = { { x0, y0, x7 - 1, y1 - 1, 2 } };
|
||||
osd->SetAreas(Areas, sizeof(Areas) / sizeof(tArea));
|
||||
}
|
||||
osd->DrawRectangle(x0, y0, x7 - 1, y1 - 1, clrTransparent);
|
||||
osd->DrawEllipse (x0, y0, x1 - 1, y1 - 1, frameColor, 7);
|
||||
osd->DrawRectangle(x1, y0, x2 - 1, y1 - 1, frameColor);
|
||||
|
25
timers.c
25
timers.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: timers.c 1.65 2006/09/15 14:15:53 kls Exp $
|
||||
* $Id: timers.c 1.66 2007/06/03 13:48:57 kls Exp $
|
||||
*/
|
||||
|
||||
#include "timers.h"
|
||||
@ -136,7 +136,7 @@ cString cTimer::ToText(bool UseChannelID)
|
||||
{
|
||||
char *buffer;
|
||||
strreplace(file, ':', '|');
|
||||
asprintf(&buffer, "%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays), start, stop, priority, lifetime, file, aux ? aux : "");
|
||||
asprintf(&buffer, "%u:%s:%s:%04d:%04d:%d:%d:%s:%s\n", flags, UseChannelID ? *Channel()->GetChannelID().ToString() : *itoa(Channel()->Number()), *PrintDay(day, weekdays, true), start, stop, priority, lifetime, file, aux ? aux : "");
|
||||
strreplace(file, '|', ':');
|
||||
return cString(buffer, true);
|
||||
}
|
||||
@ -212,17 +212,26 @@ bool cTimer::ParseDay(const char *s, time_t &Day, int &WeekDays)
|
||||
return true;
|
||||
}
|
||||
|
||||
cString cTimer::PrintDay(time_t Day, int WeekDays)
|
||||
cString cTimer::PrintDay(time_t Day, int WeekDays, bool SingleByteChars)
|
||||
{
|
||||
#define DAYBUFFERSIZE 32
|
||||
#define DAYBUFFERSIZE 64
|
||||
char buffer[DAYBUFFERSIZE];
|
||||
char *b = buffer;
|
||||
if (WeekDays) {
|
||||
const char *w = tr("MTWTFSS");
|
||||
const char *w = "MTWTFSS";
|
||||
if (!SingleByteChars)
|
||||
w = tr(w);
|
||||
while (*w) {
|
||||
*b++ = (WeekDays & 1) ? *w : '-';
|
||||
int sl = Utf8CharLen(w);
|
||||
if (WeekDays & 1) {
|
||||
for (int i = 0; i < sl; i++)
|
||||
b[i] = w[i];
|
||||
b += sl;
|
||||
}
|
||||
else
|
||||
*b++ = '-';
|
||||
WeekDays >>= 1;
|
||||
w++;
|
||||
w += sl;
|
||||
}
|
||||
if (Day)
|
||||
*b++ = '@';
|
||||
@ -239,7 +248,7 @@ cString cTimer::PrintDay(time_t Day, int WeekDays)
|
||||
cString cTimer::PrintFirstDay(void) const
|
||||
{
|
||||
if (weekdays) {
|
||||
cString s = PrintDay(day, weekdays);
|
||||
cString s = PrintDay(day, weekdays, true);
|
||||
if (strlen(s) == 18)
|
||||
return *s + 8;
|
||||
}
|
||||
|
4
timers.h
4
timers.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: timers.h 1.29 2006/09/04 17:07:39 kls Exp $
|
||||
* $Id: timers.h 1.30 2007/06/03 13:24:58 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TIMERS_H
|
||||
@ -94,7 +94,7 @@ public:
|
||||
cString PrintFirstDay(void) const;
|
||||
static int TimeToInt(int t);
|
||||
static bool ParseDay(const char *s, time_t &Day, int &WeekDays);
|
||||
static cString PrintDay(time_t Day, int WeekDays);
|
||||
static cString PrintDay(time_t Day, int WeekDays, bool SingleByteChars);
|
||||
};
|
||||
|
||||
class cTimers : public cConfig<cTimer> {
|
||||
|
264
tools.c
264
tools.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.c 1.122 2007/01/07 14:44:57 kls Exp $
|
||||
* $Id: tools.c 1.123 2007/06/09 14:21:21 kls Exp $
|
||||
*/
|
||||
|
||||
#include "tools.h"
|
||||
@ -570,6 +570,221 @@ uint64_t cTimeMs::Elapsed(void)
|
||||
return Now() - begin;
|
||||
}
|
||||
|
||||
// --- UTF-8 support ---------------------------------------------------------
|
||||
|
||||
static uint SystemToUtf8[128] = { 0 };
|
||||
|
||||
int Utf8CharLen(const char *s)
|
||||
{
|
||||
if (cCharSetConv::SystemCharacterTable())
|
||||
return 1;
|
||||
#define MT(s, m, v) ((*(s) & (m)) == (v)) // Mask Test
|
||||
if (MT(s, 0xE0, 0xC0) && MT(s + 1, 0xC0, 0x80))
|
||||
return 2;
|
||||
if (MT(s, 0xF0, 0xE0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80))
|
||||
return 3;
|
||||
if (MT(s, 0xF8, 0xF0) && MT(s + 1, 0xC0, 0x80) && MT(s + 2, 0xC0, 0x80) && MT(s + 3, 0xC0, 0x80))
|
||||
return 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint Utf8CharGet(const char *s, int Length)
|
||||
{
|
||||
if (cCharSetConv::SystemCharacterTable())
|
||||
return (uchar)*s < 128 ? *s : SystemToUtf8[(uchar)*s - 128];
|
||||
if (!Length)
|
||||
Length = Utf8CharLen(s);
|
||||
switch (Length) {
|
||||
case 2: return ((*s & 0x1F) << 6) | (*(s + 1) & 0x3F);
|
||||
case 3: return ((*s & 0x0F) << 4) | ((*(s + 1) & 0x3F) << 6) | (*(s + 2) & 0x3F);
|
||||
case 4: return ((*s & 0x07) << 2) | ((*(s + 1) & 0x3F) << 4) | ((*(s + 2) & 0x3F) << 6) | (*(s + 3) & 0x3F);
|
||||
}
|
||||
return *s;
|
||||
}
|
||||
|
||||
int Utf8CharSet(uint c, char *s)
|
||||
{
|
||||
if (c < 0x80 || cCharSetConv::SystemCharacterTable()) {
|
||||
if (s)
|
||||
*s = c;
|
||||
return 1;
|
||||
}
|
||||
if (c < 0x800) {
|
||||
if (s) {
|
||||
*s++ = ((c >> 6) & 0x1F) | 0xC0;
|
||||
*s = (c & 0x3F) | 0x80;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if (c < 0x10000) {
|
||||
if (s) {
|
||||
*s++ = ((c >> 12) & 0x0F) | 0xE0;
|
||||
*s++ = ((c >> 6) & 0x3F) | 0x80;
|
||||
*s = (c & 0x3F) | 0x80;
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
if (c < 0x110000) {
|
||||
if (s) {
|
||||
*s++ = ((c >> 18) & 0x07) | 0xF0;
|
||||
*s++ = ((c >> 12) & 0x3F) | 0x80;
|
||||
*s++ = ((c >> 6) & 0x3F) | 0x80;
|
||||
*s = (c & 0x3F) | 0x80;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
return 0; // can't convert to UTF-8
|
||||
}
|
||||
|
||||
int Utf8SymChars(const char *s, int Symbols)
|
||||
{
|
||||
if (cCharSetConv::SystemCharacterTable())
|
||||
return Symbols;
|
||||
int n = 0;
|
||||
while (*s && Symbols--) {
|
||||
int sl = Utf8CharLen(s);
|
||||
s += sl;
|
||||
n += sl;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int Utf8ToArray(const char *s, uint *a, int Size)
|
||||
{
|
||||
int n = 0;
|
||||
while (*s && --Size > 0) {
|
||||
if (cCharSetConv::SystemCharacterTable())
|
||||
*a++ = *s++;
|
||||
else {
|
||||
int sl = Utf8CharLen(s);
|
||||
*a++ = Utf8CharGet(s, sl);
|
||||
s += sl;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
if (Size > 0)
|
||||
*a = 0;
|
||||
return n;
|
||||
}
|
||||
|
||||
int Utf8FromArray(const uint *a, char *s, int Size, int Max)
|
||||
{
|
||||
int NumChars = 0;
|
||||
int NumSyms = 0;
|
||||
while (*a && NumChars < Size) {
|
||||
if (Max >= 0 && NumSyms++ >= Max)
|
||||
break;
|
||||
if (cCharSetConv::SystemCharacterTable()) {
|
||||
*s++ = *a++;
|
||||
NumChars++;
|
||||
}
|
||||
else {
|
||||
int sl = Utf8CharSet(*a);
|
||||
if (NumChars + sl <= Size) {
|
||||
Utf8CharSet(*a, s);
|
||||
a++;
|
||||
s += sl;
|
||||
NumChars += sl;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NumChars < Size)
|
||||
*s = 0;
|
||||
return NumChars;
|
||||
}
|
||||
|
||||
// --- cCharSetConv ----------------------------------------------------------
|
||||
|
||||
char *cCharSetConv::systemCharacterTable = NULL;
|
||||
|
||||
cCharSetConv::cCharSetConv(const char *FromCode, const char *ToCode)
|
||||
{
|
||||
if (!FromCode)
|
||||
FromCode = systemCharacterTable;
|
||||
if (!ToCode)
|
||||
ToCode = "UTF-8";
|
||||
cd = (FromCode && ToCode) ? iconv_open(ToCode, FromCode) : (iconv_t)-1;
|
||||
result = NULL;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
cCharSetConv::~cCharSetConv()
|
||||
{
|
||||
free(result);
|
||||
iconv_close(cd);
|
||||
}
|
||||
|
||||
void cCharSetConv::SetSystemCharacterTable(const char *CharacterTable)
|
||||
{
|
||||
free(systemCharacterTable);
|
||||
systemCharacterTable = NULL;
|
||||
if (!strcasestr(CharacterTable, "UTF")) {
|
||||
// Set up a map for the character values 128...255:
|
||||
char buf[129];
|
||||
for (int i = 0; i < 128; i++)
|
||||
buf[i] = i + 128;
|
||||
buf[129] = 0;
|
||||
cCharSetConv csc(CharacterTable);
|
||||
const char *s = csc.Convert(buf);
|
||||
int i = 0;
|
||||
while (*s) {
|
||||
int sl = Utf8CharLen(s);
|
||||
SystemToUtf8[i] = Utf8CharGet(s, sl);
|
||||
s += sl;
|
||||
i++;
|
||||
}
|
||||
systemCharacterTable = strdup(CharacterTable);
|
||||
}
|
||||
}
|
||||
|
||||
const char *cCharSetConv::Convert(const char *From, char *To, size_t ToLength)
|
||||
{
|
||||
if (cd != (iconv_t)-1) {
|
||||
char *FromPtr = (char *)From;
|
||||
size_t FromLength = strlen(From);
|
||||
char *ToPtr = To;
|
||||
if (!ToPtr) {
|
||||
length = max(length, FromLength * 2); // some reserve to avoid later reallocations
|
||||
result = (char *)realloc(result, length);
|
||||
ToPtr = result;
|
||||
ToLength = length;
|
||||
}
|
||||
else if (!ToLength)
|
||||
return From; // can't convert into a zero sized buffer
|
||||
ToLength--; // save space for terminating 0
|
||||
char *Converted = ToPtr;
|
||||
while (FromLength > 0) {
|
||||
if (iconv(cd, &FromPtr, &FromLength, &ToPtr, &ToLength) == size_t(-1)) {
|
||||
if (errno == E2BIG || errno == EILSEQ && ToLength < 1) {
|
||||
if (To)
|
||||
break; // caller provided a fixed size buffer, but it was too small
|
||||
// The result buffer is too small, so increase it:
|
||||
size_t d = ToPtr - result;
|
||||
size_t r = length / 2;
|
||||
length += r;
|
||||
result = (char *)realloc(result, length);
|
||||
ToLength += r;
|
||||
ToPtr = result + d;
|
||||
}
|
||||
if (errno == EILSEQ) {
|
||||
// A character can't be converted, so mark it with '?' and proceed:
|
||||
FromPtr++;
|
||||
FromLength--;
|
||||
*ToPtr++ = '?';
|
||||
ToLength--;
|
||||
}
|
||||
else if (errno != E2BIG)
|
||||
return From; // unknown error, return original string
|
||||
}
|
||||
}
|
||||
*ToPtr = 0;
|
||||
return Converted;
|
||||
}
|
||||
return From;
|
||||
}
|
||||
|
||||
// --- cString ---------------------------------------------------------------
|
||||
|
||||
cString::cString(const char *S, bool TakePointer)
|
||||
@ -607,12 +822,12 @@ cString cString::sprintf(const char *fmt, ...)
|
||||
|
||||
cString WeekDayName(int WeekDay)
|
||||
{
|
||||
char buffer[4];
|
||||
char buffer[16];
|
||||
WeekDay = WeekDay == 0 ? 6 : WeekDay - 1; // we start with Monday==0!
|
||||
if (0 <= WeekDay && WeekDay <= 6) {
|
||||
const char *day = tr("MonTueWedThuFriSatSun");
|
||||
day += WeekDay * 3;
|
||||
strn0cpy(buffer, day, sizeof(buffer));
|
||||
day += Utf8SymChars(day, WeekDay * 3);
|
||||
strn0cpy(buffer, day, min(Utf8SymChars(day, 3) + 1, int(sizeof(buffer))));
|
||||
return buffer;
|
||||
}
|
||||
else
|
||||
@ -890,6 +1105,47 @@ struct dirent *cReadDir::Next(void)
|
||||
return directory && readdir_r(directory, &u.d, &result) == 0 ? result : NULL;
|
||||
}
|
||||
|
||||
// --- cFileNameList ---------------------------------------------------------
|
||||
|
||||
cFileNameList::cFileNameList(const char *Directory)
|
||||
{
|
||||
Load(Directory);
|
||||
}
|
||||
|
||||
cFileNameList::~cFileNameList()
|
||||
{
|
||||
for (int i = 0; i < Size(); i++)
|
||||
free(At(i));
|
||||
}
|
||||
|
||||
bool cFileNameList::Load(const char *Directory)
|
||||
{
|
||||
if (Directory) {
|
||||
cReadDir d(Directory);
|
||||
struct dirent *e;
|
||||
if (d.Ok()) {
|
||||
while ((e = d.Next()) != NULL) {
|
||||
if (strcmp(e->d_name, ".") && strcmp(e->d_name, ".."))
|
||||
Append(strdup(e->d_name));
|
||||
}
|
||||
Sort(CompareStrings);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
LOG_ERROR_STR(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 };
|
||||
|
126
tools.h
126
tools.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.h 1.97 2007/01/07 14:45:11 kls Exp $
|
||||
* $Id: tools.h 1.98 2007/06/10 08:46:23 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TOOLS_H
|
||||
@ -13,10 +13,12 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <iconv.h>
|
||||
#include <poll.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/stat.h>
|
||||
@ -72,6 +74,73 @@ template<class T> inline void put_unaligned(unsigned int v, T* p)
|
||||
((s *)p)->v = v;
|
||||
}
|
||||
|
||||
// When handling strings that might contain UTF-8 characters, it may be necessary
|
||||
// to process a "symbol" that consists of several actual character bytes. The
|
||||
// following functions allow transparently accessing a "char *" string without
|
||||
// having to worry about what character set is actually used.
|
||||
|
||||
int Utf8CharLen(const char *s);
|
||||
///< Returns the number of character bytes at the beginning of the given
|
||||
///< string that form a UTF-8 symbol.
|
||||
uint Utf8CharGet(const char *s, int Length = 0);
|
||||
///< Returns the UTF-8 symbol at the beginning of the given string.
|
||||
///< Length can be given from a previous call to Utf8CharLen() to avoid calculating
|
||||
///< it again. If no Length is given, Utf8CharLen() will be called.
|
||||
int Utf8CharSet(uint c, char *s = NULL);
|
||||
///< Converts the given UTF-8 symbol to a sequence of character bytes and copies
|
||||
///< them to the given string. Returns the number of bytes written. If no string
|
||||
///< is given, only the number of bytes is returned and nothing is copied.
|
||||
int Utf8SymChars(const char *s, int Symbols);
|
||||
///< Returns the number of character bytes at the beginning of the given
|
||||
///< string that form at most the given number of UTF-8 Symbols.
|
||||
int Utf8ToArray(const char *s, uint *a, int Size);
|
||||
///< Converts the given character bytes (including the terminating 0) into an
|
||||
///< array of UTF-8 symbols of the given Size. Returns the number of symbols
|
||||
///< in the array (without the terminating 0).
|
||||
int Utf8FromArray(const uint *a, char *s, int Size, int Max = -1);
|
||||
///< Converts the given array of UTF-8 symbols (including the terminating 0)
|
||||
///< into a sequence of character bytes of at most Size length. Returns the
|
||||
///< number of character bytes written (without the terminating 0).
|
||||
///< If Max is given, only that many symbols will be converted.
|
||||
///< The resulting string is always zero-terminated if Size is big enough.
|
||||
|
||||
// When allocating buffer space, make sure we reserve enough space to hold
|
||||
// a string in UTF-8 representation:
|
||||
|
||||
#define Utf8BufSize(s) ((s) * 4)
|
||||
|
||||
// The following macros automatically use the correct versions of the character
|
||||
// class functions:
|
||||
|
||||
#define Utf8to(conv, c) (cCharSetConv::SystemCharacterTable() ? to##conv(c) : tow##conv(c))
|
||||
#define Utf8is(ccls, c) (cCharSetConv::SystemCharacterTable() ? is##ccls(c) : isw##ccls(c))
|
||||
|
||||
class cCharSetConv {
|
||||
private:
|
||||
iconv_t cd;
|
||||
char *result;
|
||||
size_t length;
|
||||
static char *systemCharacterTable;
|
||||
public:
|
||||
cCharSetConv(const char *FromCode = NULL, const char *ToCode = NULL);
|
||||
///< Sets up a character set converter to convert from FromCode to ToCode.
|
||||
///< If FromCode is NULL, the previously set systemCharacterTable is used.
|
||||
///< If ToCode is NULL, "UTF-8" is used.
|
||||
~cCharSetConv();
|
||||
const char *Convert(const char *From, char *To = NULL, size_t ToLength = 0);
|
||||
///< Converts the given Text from FromCode to ToCode (as set in the cosntructor).
|
||||
///< If To is given, it is used to copy at most ToLength bytes of the result
|
||||
///< (including the terminating 0) into that buffer. If To is not given,
|
||||
///< the result is copied into a dynamically allocated buffer and is valid as
|
||||
///< long as this object lives, or until the next call to Convert(). The
|
||||
///< return value always points to the result if the conversion was successful
|
||||
///< (even if a fixed size To buffer was given and the result didn't fit into
|
||||
///< it). If the string could not be converted, the result points to the
|
||||
///< original From string.
|
||||
static const char *SystemCharacterTable(void) { return systemCharacterTable; }
|
||||
static void SetSystemCharacterTable(const char *CharacterTable);
|
||||
};
|
||||
|
||||
class cString {
|
||||
private:
|
||||
char *s;
|
||||
@ -320,6 +389,61 @@ public:
|
||||
T *Next(const T *object) const { return (T *)object->cListObject::Next(); } // avoid ambiguities in case of a "list of lists"
|
||||
};
|
||||
|
||||
template<class T> class cVector {
|
||||
private:
|
||||
mutable int allocated;
|
||||
mutable int size;
|
||||
mutable T *data;
|
||||
void Realloc(int NewAllocated) const { data = (T *)realloc(data, (allocated = NewAllocated) * sizeof(T)); }
|
||||
public:
|
||||
cVector(int Allocated = 10)
|
||||
{
|
||||
allocated = 0;
|
||||
size = 0;
|
||||
data = NULL;
|
||||
Realloc(Allocated);
|
||||
}
|
||||
virtual ~cVector() { free(data); }
|
||||
T& At(int Index) const
|
||||
{
|
||||
if (Index >= size)
|
||||
Realloc(size = Index + 1);
|
||||
return data[Index];
|
||||
}
|
||||
const T& operator[](int Index) const
|
||||
{
|
||||
return At(Index);
|
||||
}
|
||||
T& operator[](int Index)
|
||||
{
|
||||
return At(Index);
|
||||
}
|
||||
int Size(void) const { return size; }
|
||||
virtual void Append(T Data)
|
||||
{
|
||||
if (size >= allocated)
|
||||
Realloc(allocated * 4 / 2); // increase size by 50%
|
||||
data[size++] = Data;
|
||||
}
|
||||
void Sort(__compar_fn_t Compare)
|
||||
{
|
||||
qsort(data, size, sizeof(T), Compare);
|
||||
}
|
||||
};
|
||||
|
||||
inline int CompareStrings(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
class cFileNameList : public cVector<char *> {
|
||||
public:
|
||||
cFileNameList(const char *Directory = NULL);
|
||||
virtual ~cFileNameList();
|
||||
bool Load(const char *Directory);
|
||||
int Find(const char *FileName);
|
||||
};
|
||||
|
||||
class cHashObject : public cListObject {
|
||||
friend class cHashBase;
|
||||
private:
|
||||
|
11
vdr.5
11
vdr.5
@ -8,7 +8,7 @@
|
||||
.\" License as specified in the file COPYING that comes with the
|
||||
.\" vdr distribution.
|
||||
.\"
|
||||
.\" $Id: vdr.5 1.61 2007/01/07 14:04:12 kls Exp $
|
||||
.\" $Id: vdr.5 1.62 2007/06/03 13:21:34 kls Exp $
|
||||
.\"
|
||||
.TH vdr 5 "07 Jan 2007" "1.4.5" "Video Disk Recorder Files"
|
||||
.SH NAME
|
||||
@ -249,9 +249,14 @@ cause the timer to record on that day. Example:
|
||||
.B MTWTF\-\-
|
||||
|
||||
will define a timer that records on Monday through Friday and does not record
|
||||
on weekends. The same result could be achieved with \fBABCDE\-\-\fR (this is
|
||||
used to allow setting the days with language specific characters).
|
||||
on weekends.
|
||||
Note that only letters may be used here, no digits.
|
||||
For compatibility with timers created with earlier versions of VDR,
|
||||
the same result could be achieved with \fBABCDE\-\-\fR (which was
|
||||
used to allow setting the days with language specific characters).
|
||||
Since version 1.5.3 VDR can use UTF-8 characters to present data to
|
||||
the user, but the weekday encoding in the \fItimers.conf\fR file
|
||||
always uses single byte characters.
|
||||
|
||||
The day definition of a `repeating' timer may be followed by the date when that
|
||||
timer shall hit for the first time. The format for this is \fB@YYYY\-MM\-DD\fR,
|
||||
|
5
vdr.c
5
vdr.c
@ -22,7 +22,7 @@
|
||||
*
|
||||
* The project's page is at http://www.cadsoft.de/vdr
|
||||
*
|
||||
* $Id: vdr.c 1.290 2007/05/12 09:35:07 kls Exp $
|
||||
* $Id: vdr.c 1.291 2007/06/09 12:33:53 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -502,6 +502,7 @@ int main(int argc, char *argv[])
|
||||
CodeSet++; // skip the dot
|
||||
bool known = SI::SetSystemCharacterTable(CodeSet);
|
||||
isyslog("codeset is '%s' - %s", CodeSet, known ? "known" : "unknown");
|
||||
cCharSetConv::SetSystemCharacterTable(CodeSet);
|
||||
}
|
||||
}
|
||||
|
||||
@ -544,8 +545,6 @@ int main(int argc, char *argv[])
|
||||
))
|
||||
EXIT(2);
|
||||
|
||||
cFont::SetCode(I18nCharSets()[Setup.OSDLanguage]);
|
||||
|
||||
// Recordings:
|
||||
|
||||
Recordings.Update();
|
||||
|
Loading…
Reference in New Issue
Block a user