summaryrefslogtreecommitdiff
path: root/txtrender.h
diff options
context:
space:
mode:
authorTobias Grimm <tobias@e-tobi.loc>2008-12-02 21:00:33 +0100
committerTobias Grimm <tobias@e-tobi.loc>2008-12-02 21:00:33 +0100
commitb451fdb5a36c0f749d63d53165cdf4e84a8f476a (patch)
treeaa3b6548ea52ef133028098c8fbaebbe47ed8a5d /txtrender.h
downloadvdr-plugin-osdteletext-b451fdb5a36c0f749d63d53165cdf4e84a8f476a.tar.gz
vdr-plugin-osdteletext-b451fdb5a36c0f749d63d53165cdf4e84a8f476a.tar.bz2
Initial commit of version 0.5.1v0.5.1release/v0.5.1
Diffstat (limited to 'txtrender.h')
-rw-r--r--txtrender.h311
1 files changed, 311 insertions, 0 deletions
diff --git a/txtrender.h b/txtrender.h
new file mode 100644
index 0000000..e7da20d
--- /dev/null
+++ b/txtrender.h
@@ -0,0 +1,311 @@
+/***************************************************************************
+ * *
+ * txtrender.h - Teletext display abstraction and teletext code *
+ * renderer *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Changelog: *
+ * 2005-03 initial version (c) Udo Richter *
+ * *
+ ***************************************************************************/
+
+#ifndef OSDTELETEXT_TXTRENDER_H_
+#define OSDTELETEXT_TXTRENDER_H_
+
+#include <stdio.h>
+
+
+// Teletext character sets
+enum enumCharsets {
+ CHARSET_LATIN_G0 = 0x0000, // native latin (partially todo)
+ CHARSET_LATIN_G0_CZ_SK = 0x0100, // Czech/Slovak (todo)
+ CHARSET_LATIN_G0_EN = 0x0200, // English
+ CHARSET_LATIN_G0_EE = 0x0300, // Estonian (todo)
+ CHARSET_LATIN_G0_FR = 0x0400, // French
+ CHARSET_LATIN_G0_DE = 0x0500, // German
+ CHARSET_LATIN_G0_IT = 0x0600, // Italian
+ CHARSET_LATIN_G0_LV_LT = 0x0700, // Lettish/Lithuanian (todo)
+ CHARSET_LATIN_G0_PL = 0x0800, // Polish (todo)
+ CHARSET_LATIN_G0_PT_ES = 0x0900, // Portugese/Spanish
+ CHARSET_LATIN_G0_RO = 0x0A00, // Romanian (todo)
+ CHARSET_LATIN_G0_SR_HR_SL = 0x0B00, // Serbian/Croatian/Slovenian (todo)
+ CHARSET_LATIN_G0_SV_FI = 0x0C00, // Swedish/Finnish
+ CHARSET_LATIN_G0_TR = 0x0D00, // Turkish (todo)
+ CHARSET_LATIN_G2 = 0x0E00, // Latin G2 supplementary set (todo)
+ CHARSET_CYRILLIC_G0_SR_HR = 0x0F00, // Serbian/Croatian (todo)
+ CHARSET_CYRILLIC_G0_RU_BG = 0x1000, // Russian/Bulgarian (todo)
+ CHARSET_CYRILLIC_G0_UK = 0x1100, // Ukrainian (todo)
+ CHARSET_CYRILLIC_G2 = 0x1200, // Cyrillic G2 Supplementary (todo)
+ CHARSET_GREEK_G0 = 0x1300, // Greek G0 (todo)
+ CHARSET_GREEK_G2 = 0x1400, // Greeek G2 (todo)
+ CHARSET_ARABIC_G0 = 0x1500, // Arabic G0 (todo)
+ CHARSET_ARABIC_G2 = 0x1600, // Arabic G2 (todo)
+ CHARSET_HEBREW_G0 = 0x1700, // Hebrew G0 (todo)
+ CHARSET_GRAPHICS_G1 = 0x1800, // G1 graphics set
+ CHARSET_GRAPHICS_G1_SEP = 0x1900, // G1 graphics set, separated
+ CHARSET_GRAPHICS_G3 = 0x1A00, // G3 graphics set (todo)
+ CHARSET_INVALID = 0x1F00 // no charset defined
+};
+
+// Macro to get the lowest non-0 bit position from a bit mask
+// Should evaluate to const on a const mask
+#define LowestSet2Bit(mask) ((mask)&0x0001?0:1)
+#define LowestSet4Bit(mask) ((mask)&0x0003?LowestSet2Bit(mask):LowestSet2Bit((mask)>>2)+2)
+#define LowestSet8Bit(mask) ((mask)&0x000f?LowestSet4Bit(mask):LowestSet4Bit((mask)>>4)+4)
+#define LowestSet16Bit(mask) ((mask)&0x00ff?LowestSet8Bit(mask):LowestSet8Bit((mask)>>8)+8)
+#define LowestSet32Bit(mask) ((mask)&0xffff?LowestSet16Bit(mask):LowestSet16Bit((mask)>>16)+16)
+
+
+// Character modifcation double height:
+enum enumDblHeight {
+ dblh_Normal=0x00000000, // normal height
+ dblh_Top =0x04000000, // upper half character
+ dblh_Bottom=0x08000000 // lower half character
+};
+// Character modifcation double width:
+enum enumDblWidth {
+ dblw_Normal=0x00000000, // normal width
+ dblw_Left =0x10000000, // left half character
+ dblw_Right =0x20000000 // right half character
+};
+
+// Teletext colors
+enum enumTeletextColor {
+ // level 1:
+ ttcBlack=0,
+ ttcRed=1,
+ ttcGreen=2,
+ ttcYellow=3,
+ ttcBlue=4,
+ ttcMagenta=5,
+ ttcCyan=6,
+ ttcWhite=7,
+ // level 2.5:
+ ttcTransparent=8,
+ ttcHalfRed=9,
+ ttcHalfGreen=10,
+ ttcHalfYellow=11,
+ ttcHalfBlue=12,
+ ttcHalfMagenta=13,
+ ttcHalfCyan=14,
+ ttcGrey=15,
+ // unnamed, level 2.5:
+ ttcColor16=16, ttcColor17=17, ttcColor18=18, ttcColor19=19,
+ ttcColor20=20, ttcColor21=21, ttcColor22=22, ttcColor23=23,
+ ttcColor24=24, ttcColor25=25, ttcColor26=26, ttcColor27=27,
+ ttcColor28=28, ttcColor29=29, ttcColor30=30, ttcColor31=31,
+
+ ttcFirst=0, ttcLast=31
+};
+inline enumTeletextColor& operator++(enumTeletextColor& c) { return c=enumTeletextColor(int(c)+1); }
+inline enumTeletextColor operator++(enumTeletextColor& c, int) { enumTeletextColor tmp(c); ++c; return tmp; }
+
+class cTeletextChar {
+ // Wrapper class that represents a teletext character,
+ // including colors and effects. Should optimize back
+ // to 4 byte unsigned int on compile.
+
+protected:
+ unsigned int c;
+
+ static const unsigned int CHAR = 0x000000FF;
+ // character code
+ static const unsigned int CHARSET = 0x00001F00;
+ // character set code, see below
+ static const unsigned int BOXOUT = 0x00004000;
+ // 'boxed' mode hidden area
+ static const unsigned int DIRTY = 0x00008000;
+ // 'dirty' bit - internal marker only
+ static const unsigned int FGCOLOR = 0x001F0000;
+ // 5-bit foreground color code, 3 bit used for now
+ static const unsigned int BGCOLOR = 0x03E00000;
+ // 5-bit background color code, 3 bit used for now
+ static const unsigned int DBLHEIGHT = 0x0C000000;
+ // show double height
+ static const unsigned int DBLWIDTH = 0x30000000;
+ // show double width (todo)
+ static const unsigned int CONCEAL = 0x40000000;
+ // character concealed
+ static const unsigned int BLINK = 0x80000000;
+ // blinking character
+
+ cTeletextChar(unsigned int cc) { c=cc; }
+
+public:
+ cTeletextChar() { c=0; }
+
+ // inline helper functions:
+ // For each parameter encoded into the 32-bit int, there is
+ // a Get...() to read, a Set...() to write, and a To...() to
+ // return a modified copy
+
+ inline unsigned char GetChar()
+ { return c&CHAR; }
+ inline void SetChar(unsigned char chr)
+ { c=(c&~CHAR)|chr; }
+ inline cTeletextChar ToChar(unsigned char chr)
+ { return cTeletextChar((c&~CHAR)|chr); }
+
+ inline enumCharsets GetCharset()
+ { return (enumCharsets)(c&CHARSET); }
+ inline void SetCharset(enumCharsets charset)
+ { c=(c&~CHARSET)|charset; }
+ inline cTeletextChar ToCharset(enumCharsets charset)
+ { return cTeletextChar((c&~CHARSET)|charset); }
+
+ inline enumTeletextColor GetFGColor()
+ { return (enumTeletextColor)((c&FGCOLOR) >> LowestSet32Bit(FGCOLOR)); }
+ inline void SetFGColor(enumTeletextColor fgc)
+ { c=(c&~FGCOLOR) | (fgc << LowestSet32Bit(FGCOLOR)); }
+ inline cTeletextChar ToFGColor(enumTeletextColor fgc)
+ { return cTeletextChar((c&~FGCOLOR) | (fgc << LowestSet32Bit(FGCOLOR))); }
+
+ inline enumTeletextColor GetBGColor()
+ { return (enumTeletextColor)((c&BGCOLOR) >> LowestSet32Bit(BGCOLOR)); }
+ inline void SetBGColor(enumTeletextColor bgc)
+ { c=(c&~BGCOLOR) | (bgc << LowestSet32Bit(BGCOLOR)); }
+ inline cTeletextChar ToBGColor(enumTeletextColor bgc)
+ { return cTeletextChar((c&~BGCOLOR) | (bgc << LowestSet32Bit(BGCOLOR))); }
+
+ inline bool GetBoxedOut()
+ { return c&BOXOUT; }
+ inline void SetBoxedOut(bool BoxedOut)
+ { c=(BoxedOut)?(c|BOXOUT):(c&~BOXOUT); }
+ inline cTeletextChar ToBoxedOut(bool BoxedOut)
+ { return cTeletextChar((BoxedOut)?(c|BOXOUT):(c&~BOXOUT)); }
+
+ inline bool GetDirty()
+ { return c&DIRTY; }
+ inline void SetDirty(bool Dirty)
+ { c=(Dirty)?(c|DIRTY):(c&~DIRTY); }
+ inline cTeletextChar ToDirty(bool Dirty)
+ { return cTeletextChar((Dirty)?(c|DIRTY):(c&~DIRTY)); }
+
+ inline enumDblHeight GetDblHeight()
+ { return (enumDblHeight)(c&DBLHEIGHT); }
+ inline void SetDblHeight(enumDblHeight dh)
+ { c=(c&~(DBLHEIGHT)) | dh; }
+ inline cTeletextChar ToDblHeight(enumDblHeight dh)
+ { return cTeletextChar((c&~(DBLHEIGHT)) | dh); }
+
+ inline enumDblWidth GetDblWidth()
+ { return (enumDblWidth)(c&DBLWIDTH); }
+ inline void SetDblWidth(enumDblWidth dw)
+ { c=(c&~(DBLWIDTH)) | dw; }
+ inline cTeletextChar ToDblWidth(enumDblWidth dw)
+ { return cTeletextChar((c&~(DBLWIDTH)) | dw); }
+
+ inline bool GetConceal()
+ { return c&CONCEAL; }
+ inline void SetConceal(bool Conceal)
+ { c=(Conceal)?(c|CONCEAL):(c&~CONCEAL); }
+ inline cTeletextChar ToConceal(bool Conceal)
+ { return cTeletextChar((Conceal)?(c|CONCEAL):(c&~CONCEAL)); }
+
+ inline bool GetBlink()
+ { return c&BLINK; }
+ inline void SetBlink(bool Blink)
+ { c=(Blink)?(c|BLINK):(c&~BLINK); }
+ inline cTeletextChar ToBlink(bool Blink)
+ { return cTeletextChar((Blink)?(c|BLINK):(c&~BLINK)); }
+
+ bool operator==(cTeletextChar &chr) { return c==chr.c; }
+ bool operator!=(cTeletextChar &chr) { return c!=chr.c; }
+};
+
+
+class cRenderPage {
+ // Abstraction of a 40x25 teletext character page
+ // with all special attributes and colors
+ // Additionally tracks changes by maintaining a
+ // 'dirty' flag on each character
+
+protected:
+ cTeletextChar Page[40][25];
+
+ int Flags;
+ // 0x80 C4 - Erase page
+ // 0x40 C5 - News flash
+ // 0x20 C6 - Subtitle
+ // 0x10 C7 - Suppress Header
+ // 0x08 C8 - Update
+ // 0x04 C9 - Interrupt Sequence
+ // 0x02 C10 - Inhibit Display
+ // 0x01 C11 - Magazine Serial mode
+
+ int Lang;
+ // 3-bit language number from header
+
+ bool Dirty; // At least one character is dirty
+ bool DirtyAll; // Consider all characters dirty, regardless of flag
+
+ // Font Code pages
+ int FirstG0CodePage; // 7-bit number, lower 3 bits ignored
+ int SecondG0CodePage; // 7-bit number
+
+public:
+ cRenderPage();
+
+ cTeletextChar GetChar(int x, int y) {
+ // Read character content from page
+ if (x<0 || x>=40 || y<0 || y>=25) {
+ printf("Warning: out of bounds read access to teletext page\n");
+ return cTeletextChar();
+ }
+ return Page[x][y].ToDirty(false);
+ }
+
+ bool IsDirty() {
+ // global dirty status
+ return Dirty;
+ }
+
+ bool IsDirty(int x, int y) {
+ // local dirty status
+ if (x<0 || x>=40 || y<0 || y>=25) {
+ printf("Warning: out of bounds read access to teletext page\n");
+ return false;
+ }
+ return Page[x][y].GetDirty() | DirtyAll;
+ }
+
+ void MakeDirty(int x, int y) {
+ // force one character dirty
+ if (x<0 || x>=40 || y<0 || y>=25) {
+ printf("Warning: out of bounds write access to teletext page\n");
+ return;
+ }
+ Page[x][y].SetDirty(true);
+ Dirty=true;
+ }
+
+ void SetChar(int x, int y, cTeletextChar c) {
+ // Set character at given location
+
+ if (x<0 || x>=40 || y<0 || y>=25) {
+ printf("Warning: out of bounds write access to teletext page\n");
+ return;
+ }
+ if (GetChar(x,y) != c) {
+ Page[x][y]=c.ToDirty(true);
+ Dirty=true;
+ }
+ }
+
+ void ReadTeletextHeader(unsigned char *Header);
+ // Read header from teletext page
+ // Header must be a 12 bytes buffer
+
+ void RenderTeletextCode(unsigned char *PageCode);
+ // Interprete teletext code referenced by PageCode
+ // and draw the whole page content into this object
+ // PageCode must be a 40*24 bytes buffer
+};
+
+
+
+#endif