From 41effbc5a868ad156417bbb62e722ce0806aba26 Mon Sep 17 00:00:00 2001 From: SilentException Date: Thu, 24 Nov 2011 21:31:01 +0100 Subject: [PATCH] Support for more languages in Teletext (patch from arion_p) --- .../TvPlugin/teletext/TeletextPageRenderer.cs | 1061 +++++++++++++---- .../TvPlugin/teletext/TvFullscreenTeletext.cs | 90 ++ .../TvPlugin/TvPlugin/teletext/TvTeletext.cs | 67 ++ .../TvPlugin/teletext/TvTeletextBase.cs | 113 +- .../Configuration/Sections/TVTeletext.cs | 147 ++- .../MediaPortal.Base/language/strings_el.xml | 11 + .../MediaPortal.Base/language/strings_en.xml | 11 + .../skin/Default/myteletext.xml | 14 +- .../skin/DefaultWide/myteletext.xml | 13 +- 9 files changed, 1309 insertions(+), 218 deletions(-) diff --git a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TeletextPageRenderer.cs b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TeletextPageRenderer.cs index 623fc28cea5..dd368b72547 100644 --- a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TeletextPageRenderer.cs +++ b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TeletextPageRenderer.cs @@ -20,6 +20,7 @@ using System; using System.Drawing; +using System.Drawing.Text; using System.Globalization; using System.Text; @@ -33,8 +34,7 @@ public TeletextPageRenderer() { _isRegionalDKorNO = (RegionInfo.CurrentRegion.TwoLetterISORegionName.Equals("DK", StringComparison.InvariantCultureIgnoreCase)) - || (RegionInfo.CurrentRegion.TwoLetterISORegionName.Equals("NO", StringComparison.InvariantCultureIgnoreCase)); - Transparent = Color.FromArgb(0, 0, 0, 0); + || (RegionInfo.CurrentRegion.TwoLetterISORegionName.Equals("NO", StringComparison.InvariantCultureIgnoreCase)); } #endregion @@ -55,6 +55,7 @@ public TeletextPageRenderer() private bool _hiddenMode = true; private bool _transparentMode; private bool _fullscreenMode; + private TextRenderingHint _textRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit; private string _selectedPageText = ""; private string _selectedSubPageText = ""; @@ -63,7 +64,19 @@ public TeletextPageRenderer() private int _pageRenderHeight = 540; private int _percentageOfMaximumHeight = 100; - private Color Transparent = new Color(); + private int _defaultCharSetDesignation = 0; // Dafault character set designation code (4-bit) + private int _secondCharSetDesignation = 0; // Second character set designation code (7-bit). Contains the subset code + private G0CharSets _G0CharSet = G0CharSets.Latin; // Default G0 character set + private G2CharSets _G2CharSet = G2CharSets.Latin; // Default G2 character set + private SubSets _charSubSet = SubSets.English; // Default national option subset + private G0CharSets _altG0CharSet = G0CharSets.Latin; // Alternate G0 character set + private SubSets _altCharSubSet = SubSets.English; // Alternate national option subset + + // Active character maps + private char[] _G0CharMap; + private char[] _G2CharMap; + private char[] _altG0CharMap; + #endregion @@ -125,7 +138,44 @@ public enum Attributes HoldMosaic, ReleaseMosaic } + enum G0CharSets + { + Latin = 0, + Cyrillic1, + Cyrillic2, + Cyrillic3, + Greek, + Arabic, + Hebrew + } + enum G2CharSets + { + Latin = 0, + Cyrillic, + Greek, + Arabic, + Hebrew + } + enum SubSets + { + CzechSlovak = 0, + English, + Estonian, + French, + German, + Italian, + LettishLithuanian, + Polish, + PortugueseSpanish, + Romanian, + SerbianCroatianSlovenian, + SwedishFinnish, + Turkish, + DanishNorwegian, + + NA = English + } #endregion #region character and other tables for multi-language support. Referring the bits C12-C14 in the header @@ -189,6 +239,90 @@ public enum Attributes '\u2190' }; + + private readonly char[] m_cyrillicG0SetOpt1 = new char[] { // Serbian/Croatian + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '\u0427', '\u0410', '\u0411', '\u0426', '\u0414', '\u0415', '\u0424', '\u0413', '\u0425', '\u0418', '\u0408', '\u041A', '\u041B', '\u041C', '\u041D', '\u041E', + '\u041F', '\u040C', '\u0420', '\u0421', '\u0422', '\u0423', '\u0412', '\u0403', '\u0409', '\u040A', '\u0417', '\u040B', '\u0416', '\u0402', '\u0428', '\u040F', + '\u0447', '\u0430', '\u0431', '\u0446', '\u0434', '\u0435', '\u0444', '\u0433', '\u0445', '\u0438', '\u0458', '\u043A', '\u043B', '\u043C', '\u043D', '\u043E', + '\u043F', '\u045C', '\u0440', '\u0441', '\u0442', '\u0443', '\u0432', '\u0453', '\u0459', '\u045A', '\u0437', '\u045B', '\u0436', '\u0452', '\u0448', '\u25A0' + }; + + private readonly char[] m_cyrillicG0SetOpt2 = new char[] { // Russian/Bulgarian + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '\u042E', '\u0410', '\u0411', '\u0426', '\u0414', '\u0415', '\u0424', '\u0413', '\u0425', '\u0418', '\u0419', '\u041A', '\u041B', '\u041C', '\u041D', '\u041E', + '\u041F', '\u042F', '\u0420', '\u0421', '\u0422', '\u0423', '\u0416', '\u0412', '\u042C', '\u042A', '\u0417', '\u0428', '\u042D', '\u0429', '\u0427', '\u042B', + '\u044E', '\u0430', '\u0431', '\u0446', '\u0434', '\u0435', '\u0444', '\u0433', '\u0445', '\u0438', '\u0439', '\u043A', '\u043B', '\u043C', '\u043D', '\u043E', + '\u043F', '\u044F', '\u0440', '\u0441', '\u0442', '\u0443', '\u0436', '\u0432', '\u044C', '\u044A', '\u0437', '\u0448', '\u044D', '\u0449', '\u0447', '\u25A0' + }; + + private readonly char[] m_cyrillicG0SetOpt3 = new char[] { // Ukranian + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', + '\u042E', '\u0410', '\u0411', '\u0426', '\u0414', '\u0415', '\u0424', '\u0413', '\u0425', '\u0418', '\u0419', '\u041A', '\u041B', '\u041C', '\u041D', '\u041E', + '\u041F', '\u042F', '\u0420', '\u0421', '\u0422', '\u0423', '\u0416', '\u0412', '\u042C', '\u0406', '\u0417', '\u0428', '\u0404', '\u0429', '\u0427', '\u0407', + '\u044E', '\u0430', '\u0431', '\u0446', '\u0434', '\u0435', '\u0444', '\u0433', '\u0445', '\u0438', '\u0439', '\u043A', '\u043B', '\u043C', '\u043D', '\u043E', + '\u043F', '\u044F', '\u0440', '\u0441', '\u0442', '\u0443', '\u0436', '\u0432', '\u044C', '\u0456', '\u0437', '\u0448', '\u0454', '\u0449', '\u0447', '\u25A0' + }; + + private readonly char[] m_cyrillicG2Set = new char[] { // + ' ', '\u00A1', '\u00A2', '\u00A3', '$', '\u00A5', ' ', '\u00A7', ' ', '\u2018', '\u201C', '\u00AB', '\u2190', '\u2191', '\u2192', '\u2193', + '\u00B0', '\u00B1', '\u00B2', '\u00B3', '\u00D7', '\u03BC', '\u00B6', '\u00B7', '\u00F7', '\u2019', '\u201D', '\u00BB', '\u00BC', '\u00BD', '\u00BE', '\u00BF', + '\u0020', '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0306', '\u0307', '\u0308', '\u0323', '\u030A', '\u0318', '\u0331', '\u030B', '\u0319', '\u030C', + '\u2014', '\u00B9', '\u00AE', '\u00A9', '\u2122', '\u266A', '\u20A0', '\u2030', '\u221D', '\u0141', '\u0142', '\u03B2', '\u215B', '\u215C', '\u215D', '\u215E', + 'D', 'E', 'F', 'G', 'I', 'J', 'K', 'L', 'N', 'Q', 'R', 'S', 'U', 'V', 'W', 'Z', + 'd', 'e', 'f', 'g', 'i', 'j', 'k', 'l', 'n', 'q', 'r', 's', 'u', 'v', 'w', 'z' + }; + + private readonly char[] m_greekG0Set = new char[] { + ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '\u00AB', '=', '\u00BB', '?', + '\u0390', '\u0391', '\u0392', '\u0393', '\u0394', '\u0395', '\u0396', '\u0397', '\u0398', '\u0399', '\u039A', '\u039B', '\u039C', '\u039D', '\u039E', '\u039F', + '\u03A0', '\u03A1', '\u0384', '\u03A3', '\u03A4', '\u03A5', '\u03A6', '\u03A7', '\u03A8', '\u03A9', '\u03AA', '\u03AB', '\u03AC', '\u03AD', '\u03AE', '\u03AF', + '\u03B0', '\u03B1', '\u03B2', '\u03B3', '\u03B4', '\u03B5', '\u03B6', '\u03B7', '\u03B8', '\u03B9', '\u03BA', '\u03BB', '\u03BC', '\u03BD', '\u03BE', '\u03BF', + '\u03C0', '\u03C1', '\u03C2', '\u03C3', '\u03C4', '\u03C5', '\u03C6', '\u03C7', '\u03C8', '\u03C9', '\u03CA', '\u03CB', '\u03CC', '\u03CD', '\u03CE', ' ' + }; + + private readonly char[] m_greekG2Set = new char[] { + ' ', 'a', 'b', '\u00A3', 'e', 'h', 'i', '\u00A7', ':', '\u2018', '\u201C', 'k', '\u2190', '\u2191', '\u2192', '\u2193', + '\u00B0', '\u00B1', '\u00B2', '\u00B3', 'x', 'm', 'n', 'p', '\u00F7', '\u2019', '\u201D', 't', '\u00BC', '\u00BD', '\u00BE', 'x', + ' ', '\u0300', '\u0301', '\u0302', '\u0303', '\u0304', '\u0306', '\u0307', '\u0308', '\u0323', '\u030A', '\u0318', '\u0331', '\u030B', '\u0319', '\u030C', + '?', '\u00B9', '\u00AE', '\u00A9', '\u2122', '\u266A', '\u20AC', '\u2030', '\u221D', '\u038A', '\u038E', '\u038F', '\u215B', '\u215C', '\u215D', '\u215E', + 'C', 'D', 'F', 'G', 'J', 'L', 'Q', 'R', 'S', 'U', 'V', 'W', 'Y', 'Z', '\u0386', '\u0389', + 'c', 'd', 'f', 'g', 'j', 'l', 'q', 'r', 's', 'u', 'v', 'w', 'y', 'z', '\u0388', ' ' + }; + + // TODO: Build Arabic charset tables + //private readonly char[] m_arabicG0Set = new char[] { + //}; + //private readonly char[] m_arabicG2Set = new char[] { + //}; + + // TODO: Build Hebrew charset tables + //private readonly char[] m_hebrewG0Set = new char[] { + //}; + +/* + readonly char[][] m_G0Sets = new char[][] { + null, + m_cyrillicG0SetOpt1, + m_cyrillicG0SetOpt2, + m_cyrillicG0SetOpt3, + m_greekG0Set, + null, + null + }; + + readonly char[][] m_G2Sets = new char[][] { + null, + m_cyrillicG2Set, + m_greekG2Set, + null, + null + }; + */ #endregion #region properties @@ -275,9 +409,463 @@ public int PercentageOfMaximumHeight get { return _percentageOfMaximumHeight; } set { _percentageOfMaximumHeight = value; } } + /// + /// Selects the default (primary) character set designation + /// + public int DefaultCharSetDesignation + { + get + { + return _defaultCharSetDesignation; + } + set + { + _defaultCharSetDesignation = value; + } + } + /// + /// Selects the secondary (alternate) character set designation + /// Each time ESC is encountered in the data stream, the renderer + /// switches the default and secondary character sets. + /// + public int SecondCharSetDesignation + { + get + { + return _secondCharSetDesignation; + } + set + { + _secondCharSetDesignation = value; + } + } + + /// + /// Determines the font quality (font smoothing and hinting) + /// + public TextRenderingHint TextRenderingHint + { + get { return _textRenderingHint; } + set { _textRenderingHint = value; } + } #endregion + /// + /// Return the G0 character map specified in charSet + /// + /// The requested G0 character set + /// The character map + private char[] GetG0CharMap(G0CharSets charSet) + { + switch (charSet) + { + case G0CharSets.Cyrillic1: + return m_cyrillicG0SetOpt1; + case G0CharSets.Cyrillic2: + return m_cyrillicG0SetOpt2; + case G0CharSets.Cyrillic3: + return m_cyrillicG0SetOpt3; + case G0CharSets.Greek: + return m_greekG0Set; + default: + return null; + } + } + + /// + /// Return the G2 character map specified in charSet + /// + /// The requested G2 character set + /// The character map + private char[] GetG2CharMap(G2CharSets charSet) + { + switch (charSet) + { + case G2CharSets.Cyrillic: + return m_cyrillicG2Set; + case G2CharSets.Greek: + return m_greekG2Set; + case G2CharSets.Arabic: + return null; + case G2CharSets.Hebrew: + return null; + default: + return null; + } + } + + /// + /// Select the appropriate default character sets based on the + /// national subset code in the page control bits and the + /// character set designation code (supplied by the user + /// for level 1 decoders, or transmitted in X/28 and/or + /// M/29 packets for levels 1.5 and up) + /// + /// the default G0 and G2 character set designation code (7-bit) + /// the national subset code (3-bit) + protected void SetupDefaultCharSets(int defaultSetDesignation, int subSetSelector) + { + switch (defaultSetDesignation) + { + case 0: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch(subSetSelector) + { + case 0: + _charSubSet = SubSets.English; + break; + case 1: + _charSubSet = SubSets.German; + break; + case 2: + _charSubSet = _isRegionalDKorNO? SubSets.DanishNorwegian : SubSets.SwedishFinnish; + break; + case 3: + _charSubSet = SubSets.Italian; + break; + case 4: + _charSubSet = SubSets.French; + break; + case 5: + _charSubSet = SubSets.PortugueseSpanish; + break; + case 6: + _charSubSet = SubSets.CzechSlovak; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 1: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch (subSetSelector) + { + case 0: + _charSubSet = SubSets.Polish; + break; + case 1: + _charSubSet = SubSets.German; + break; + case 2: + _charSubSet = _isRegionalDKorNO ? SubSets.DanishNorwegian : SubSets.SwedishFinnish; + break; + case 3: + _charSubSet = SubSets.Italian; + break; + case 4: + _charSubSet = SubSets.French; + break; + case 6: + _charSubSet = SubSets.CzechSlovak; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 2: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch (subSetSelector) + { + case 0: + _charSubSet = SubSets.English; + break; + case 1: + _charSubSet = SubSets.German; + break; + case 2: + _charSubSet = _isRegionalDKorNO ? SubSets.DanishNorwegian : SubSets.SwedishFinnish; + break; + case 3: + _charSubSet = SubSets.Italian; + break; + case 4: + _charSubSet = SubSets.French; + break; + case 5: + _charSubSet = SubSets.PortugueseSpanish; + break; + case 6: + _charSubSet = SubSets.Turkish; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 3: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch (subSetSelector) + { + case 5: + _charSubSet = SubSets.SerbianCroatianSlovenian; + break; + case 7: + _charSubSet = SubSets.Romanian; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 4: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch (subSetSelector) + { + case 0: + _G0CharSet = G0CharSets.Cyrillic1; + _G2CharSet = G2CharSets.Cyrillic; + _charSubSet = SubSets.NA; + break; + case 1: + _charSubSet = SubSets.German; + break; + case 2: + _charSubSet = SubSets.Estonian; + break; + case 3: + _charSubSet = SubSets.LettishLithuanian; + break; + case 4: + _G0CharSet = G0CharSets.Cyrillic2; + _G2CharSet = G2CharSets.Cyrillic; + _charSubSet = SubSets.NA; + break; + case 5: + _G0CharSet = G0CharSets.Cyrillic3; + _G2CharSet = G2CharSets.Cyrillic; + _charSubSet = SubSets.NA; + break; + case 6: + _charSubSet = SubSets.CzechSlovak; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 6: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch (subSetSelector) + { + case 6: + _charSubSet = SubSets.Turkish; + break; + case 7: + _G0CharSet = G0CharSets.Greek; + _G2CharSet = G2CharSets.Greek; + _charSubSet = SubSets.NA; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 8: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Arabic; + switch (subSetSelector) + { + case 0: + _charSubSet = SubSets.English; + break; + case 4: + _charSubSet = SubSets.French; + break; + case 7: + _G0CharSet = G0CharSets.Arabic; + _charSubSet = SubSets.NA; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + case 10: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + switch (subSetSelector) + { + case 5: + _G0CharSet = G0CharSets.Hebrew; + _G2CharSet = G2CharSets.Arabic; + _charSubSet = SubSets.NA; + break; + case 7: + _G0CharSet = G0CharSets.Arabic; + _G2CharSet = G2CharSets.Arabic; + _charSubSet = SubSets.NA; + break; + default: + _charSubSet = SubSets.NA; + break; + } + break; + + default: + _G0CharSet = G0CharSets.Latin; + _G2CharSet = G2CharSets.Latin; + _charSubSet = SubSets.NA; + break; + } + + _G0CharMap = GetG0CharMap(_G0CharSet); + _G2CharMap = GetG2CharMap(_G2CharSet); + } + + /// + /// Select the appropriate second G0 character set based on the + /// character set designation code (supplied by the user + /// for level 1 decoders, or transmitted in X/28 and/or + /// M/29 packets for levels 1.5 and up) + /// + /// the second G0 character set designation code (7-bit) + protected void SetupSecondG0CharSet(int secondSetDesignation) + { + _altG0CharSet = G0CharSets.Latin; + _altCharSubSet = SubSets.English; + + switch (secondSetDesignation) + { + case 0x00: + _altCharSubSet = SubSets.English; + break; + case 0x01: + _altCharSubSet = SubSets.German; + break; + case 0x02: + _altCharSubSet = SubSets.SwedishFinnish; + break; + case 0x03: + _altCharSubSet = SubSets.Italian; + break; + case 0x04: + _altCharSubSet = SubSets.French; + break; + case 0x05: + _altCharSubSet = SubSets.PortugueseSpanish; + break; + case 0x06: + _altCharSubSet = SubSets.CzechSlovak; + break; + case 0x08: + _altCharSubSet = SubSets.Polish; + break; + case 0x09: + _altCharSubSet = SubSets.German; + break; + case 0x0a: + _altCharSubSet = SubSets.SwedishFinnish; + break; + case 0x0b: + _altCharSubSet = SubSets.Italian; + break; + case 0x0c: + _altCharSubSet = SubSets.French; + break; + case 0x0e: + _altCharSubSet = SubSets.CzechSlovak; + break; + case 0x10: + _altCharSubSet = SubSets.English; + break; + case 0x11: + _altCharSubSet = SubSets.German; + break; + case 0x12: + _altCharSubSet = SubSets.SwedishFinnish; + break; + case 0x13: + _altCharSubSet = SubSets.Italian; + break; + case 0x14: + _altCharSubSet = SubSets.French; + break; + case 0x15: + _altCharSubSet = SubSets.PortugueseSpanish; + break; + case 0x16: + _altCharSubSet = SubSets.Turkish; + break; + case 0x1d: + _altCharSubSet = SubSets.SerbianCroatianSlovenian; + break; + case 0x1f: + _altCharSubSet = SubSets.Romanian; + break; + case 0x20: + _altG0CharSet = G0CharSets.Cyrillic1; + _altCharSubSet = SubSets.NA; + break; + case 0x21: + _altCharSubSet = SubSets.German; + break; + case 0x22: + _altCharSubSet = SubSets.Estonian; + break; + case 0x23: + _altCharSubSet = SubSets.LettishLithuanian; + break; + case 0x24: + _altG0CharSet = G0CharSets.Cyrillic2; + _altCharSubSet = SubSets.NA; + break; + case 0x25: + _altG0CharSet = G0CharSets.Cyrillic3; + _altCharSubSet = SubSets.NA; + break; + case 0x26: + _altCharSubSet = SubSets.CzechSlovak; + break; + case 0x36: + _altCharSubSet = SubSets.Turkish; + break; + case 0x37: + _altG0CharSet = G0CharSets.Greek; + _altCharSubSet = SubSets.NA; + break; + case 0x40: + _altCharSubSet = SubSets.English; + break; + case 0x44: + _altCharSubSet = SubSets.French; + break; + case 0x47: + _altG0CharSet = G0CharSets.Arabic; + _altCharSubSet = SubSets.NA; + break; + case 0x55: + _altG0CharSet = G0CharSets.Hebrew; + _altCharSubSet = SubSets.NA; + break; + case 0x57: + _altG0CharSet = G0CharSets.Arabic; + _altCharSubSet = SubSets.NA; + break; + + default: + _altG0CharSet = G0CharSets.Latin; + _altCharSubSet = SubSets.NA; + break; + } + _altG0CharMap = GetG0CharMap(_altG0CharSet); + } + #region private methods /// @@ -291,11 +879,12 @@ public int PercentageOfMaximumHeight /// width of the font /// height of the font /// Teletext language - private void Render(ref Graphics graph, ref Bitmap pageBitmap, byte chr, int attrib, ref int x, ref int y, int w, - int h, int txtLanguage) + private void Render(ref Graphics graph, ref Bitmap pageBitmap, byte chr, int attrib, ref int x, ref int y, int w, int h) { bool charReady; char chr2 = '?'; + G0CharSets G0CharacterSet = ((attrib & 1 << 11) == 0 ? _G0CharSet : _altG0CharSet); + SubSets subSet = ((attrib & 1 << 11) == 0 ? _charSubSet : _altCharSubSet); // Skip the character if 0xFF if (chr == 0xFF) @@ -317,7 +906,7 @@ public int PercentageOfMaximumHeight // We are in transparent mode and fullscreen. Make beckground transparent if (_transparentMode && _fullscreenMode) { - bgColor = Transparent; + bgColor = Color.Transparent; } Brush backBrush = new SolidBrush(bgColor); Brush foreBrush = new SolidBrush(GetColor(fColor)); @@ -384,149 +973,183 @@ public int PercentageOfMaximumHeight charReady = false; // If character is still not drawn, then we analyse it again - switch (chr) + if (G0CharacterSet == G0CharSets.Latin || chr >= 0x80) { - case 0x00: - case 0x20: - graph.FillRectangle(backBrush, x, y, w, h); - if (factor == 2) - { - graph.FillRectangle(backBrush, x, y + h, w, h); - } - x += w; - charReady = true; - break; - case 0x23: - case 0x24: - chr2 = m_charTableA[txtLanguage, chr - 0x23]; - break; - case 0x40: - chr2 = m_charTableB[txtLanguage]; - break; - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - case 0x60: - chr2 = m_charTableC[txtLanguage, chr - 0x5B]; - break; - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - chr2 = m_charTableD[txtLanguage, chr - 0x7B]; - break; - case 0x7F: + switch (chr) + { + case 0x00: + case 0x20: + graph.FillRectangle(backBrush, x, y, w, h); + if (factor == 2) + { + graph.FillRectangle(backBrush, x, y + h, w, h); + } + x += w; + charReady = true; + break; + case 0x23: + case 0x24: + chr2 = m_charTableA[(int)subSet, chr - 0x23]; + break; + case 0x40: + chr2 = m_charTableB[(int)subSet]; + break; + case 0x5B: + case 0x5C: + case 0x5D: + case 0x5E: + case 0x5F: + case 0x60: + chr2 = m_charTableC[(int)subSet, chr - 0x5B]; + break; + case 0x7B: + case 0x7C: + case 0x7D: + case 0x7E: + chr2 = m_charTableD[(int)subSet, chr - 0x7B]; + break; + case 0x7F: graph.FillRectangle(backBrush, x, y, w, factor * h); graph.FillRectangle(foreBrush, x + (w / 12), y + factor * (h * 5 / 20), w * 10 / 12, factor * (h * 11 / 20)); - x += w; - charReady = true; - break; - case 0xE0: - graph.FillRectangle(backBrush, x + 1, y + 1, w - 1, h - 1); - graph.DrawLine(forePen, x, y, x + w, y); - graph.DrawLine(forePen, x, y, x, y + h); - x += w; - charReady = true; - break; - case 0xE1: - graph.FillRectangle(backBrush, x, y + 1, w, h - 1); - graph.DrawLine(forePen, x, y, x + w, y); - x += w; - charReady = true; - break; - case 0xE2: - graph.FillRectangle(backBrush, x, y + 1, w - 1, h - 1); - graph.DrawLine(forePen, x, y, x + w, y); - graph.DrawLine(forePen, x + w - 1, y + 1, x + w - 1, y + h - 1); - x += w; - charReady = true; - break; - case 0xE3: - graph.FillRectangle(backBrush, x + 1, y, w - 1, h); - graph.DrawLine(forePen, x, y, x, y + h); - x += w; - charReady = true; - break; - case 0xE4: - graph.FillRectangle(backBrush, x, y, w - 1, h); - graph.DrawLine(forePen, x + w - 1, y, x + w - 1, y + h); - x += w; - charReady = true; - break; - case 0xE5: - graph.FillRectangle(backBrush, x + 1, y, w - 1, h - 1); - graph.DrawLine(forePen, x, y + h - 1, x + w, y + h - 1); - graph.DrawLine(forePen, x, y, x, y + h - 1); - x += w; - charReady = true; - break; - case 0xE6: - graph.FillRectangle(backBrush, x, y, w, h - 1); - graph.DrawLine(forePen, x, y + h - 1, x + w, y + h - 1); - x += w; - charReady = true; - break; - case 0xE7: - graph.FillRectangle(backBrush, x, y, w - 1, h - 1); - graph.DrawLine(forePen, x, y + h - 1, x + w, y + h - 1); - graph.DrawLine(forePen, x + w - 1, y, x + w - 1, y + h - 1); - x += w; - charReady = true; - break; - case 0xE8: - graph.FillRectangle(backBrush, x + 1, y, w - 1, h); + x += w; + charReady = true; + break; + case 0xE0: + graph.FillRectangle(backBrush, x + 1, y + 1, w - 1, h - 1); + graph.DrawLine(forePen, x, y, x + w, y); + graph.DrawLine(forePen, x, y, x, y + h); + x += w; + charReady = true; + break; + case 0xE1: + graph.FillRectangle(backBrush, x, y + 1, w, h - 1); + graph.DrawLine(forePen, x, y, x + w, y); + x += w; + charReady = true; + break; + case 0xE2: + graph.FillRectangle(backBrush, x, y + 1, w - 1, h - 1); + graph.DrawLine(forePen, x, y, x + w, y); + graph.DrawLine(forePen, x + w - 1, y + 1, x + w - 1, y + h - 1); + x += w; + charReady = true; + break; + case 0xE3: + graph.FillRectangle(backBrush, x + 1, y, w - 1, h); + graph.DrawLine(forePen, x, y, x, y + h); + x += w; + charReady = true; + break; + case 0xE4: + graph.FillRectangle(backBrush, x, y, w - 1, h); + graph.DrawLine(forePen, x + w - 1, y, x + w - 1, y + h); + x += w; + charReady = true; + break; + case 0xE5: + graph.FillRectangle(backBrush, x + 1, y, w - 1, h - 1); + graph.DrawLine(forePen, x, y + h - 1, x + w, y + h - 1); + graph.DrawLine(forePen, x, y, x, y + h - 1); + x += w; + charReady = true; + break; + case 0xE6: + graph.FillRectangle(backBrush, x, y, w, h - 1); + graph.DrawLine(forePen, x, y + h - 1, x + w, y + h - 1); + x += w; + charReady = true; + break; + case 0xE7: + graph.FillRectangle(backBrush, x, y, w - 1, h - 1); + graph.DrawLine(forePen, x, y + h - 1, x + w, y + h - 1); + graph.DrawLine(forePen, x + w - 1, y, x + w - 1, y + h - 1); + x += w; + charReady = true; + break; + case 0xE8: + graph.FillRectangle(backBrush, x + 1, y, w - 1, h); for (int r = 0; r < w / 2; r++) { - graph.DrawLine(forePen, x + r, y + r, x + r, y + h - r); + graph.DrawLine(forePen, x + r, y + r, x + r, y + h - r); } - x += w; - charReady = true; - break; - case 0xE9: + x += w; + charReady = true; + break; + case 0xE9: graph.FillRectangle(backBrush, x + w / 2, y, (w + 1) / 2, h); graph.FillRectangle(foreBrush, x, y, w / 2, h); - x += w; - charReady = true; - break; - case 0xEA: - graph.FillRectangle(backBrush, x, y, w, h); + x += w; + charReady = true; + break; + case 0xEA: + graph.FillRectangle(backBrush, x, y, w, h); graph.FillRectangle(foreBrush, x, y, w / 2, h / 2); - x += w; - charReady = true; - break; - case 0xEB: - graph.FillRectangle(backBrush, x, y + 1, w, h - 1); + x += w; + charReady = true; + break; + case 0xEB: + graph.FillRectangle(backBrush, x, y + 1, w, h - 1); for (int r = 0; r < w / 2; r++) { - graph.DrawLine(forePen, x + r, y + r, x + w - r, y + r); + graph.DrawLine(forePen, x + r, y + r, x + w - r, y + r); } - x += w; - charReady = true; - break; - case 0xEC: + x += w; + charReady = true; + break; + case 0xEC: graph.FillRectangle(backBrush, x, y + (w / 2), w, h - (w / 2)); graph.FillRectangle(foreBrush, x, y, w, h / 2); + x += w; + charReady = true; + break; + case 0xED: + case 0xEE: + case 0xEF: + case 0xF0: + case 0xF1: + case 0xF2: + case 0xF3: + case 0xF4: + case 0xF5: + case 0xF6: + chr2 = m_charTableE[chr - 0xED]; + break; + default: + chr2 = (char)chr; + break; + } + } + else // otherwise process international characters + { + if (chr == 0x00 || chr == 0x20) + { + graph.FillRectangle(backBrush, x, y, w, h); + if (factor == 2) + graph.FillRectangle(backBrush, x, y + h, w, h); x += w; charReady = true; - break; - case 0xED: - case 0xEE: - case 0xEF: - case 0xF0: - case 0xF1: - case 0xF2: - case 0xF3: - case 0xF4: - case 0xF5: - case 0xF6: - chr2 = m_charTableE[chr - 0xED]; - break; - default: - chr2 = (char)chr; - break; + } + else if (chr == 0x7f) + { + graph.FillRectangle(backBrush, x, y, w, factor * h); + graph.FillRectangle(foreBrush, x + (w / 12), y + factor * (h * 5 / 20), w * 10 / 12, factor * (h * 11 / 20)); + x += w; + charReady = true; + } + else // use the selected charset mapping table + { + char[] map = ((attrib & (1 << 11)) == 0 ? _G0CharMap : _altG0CharMap); + if (map == null || chr < 0x20) + { + chr2 = (char)chr; + } + else + { + chr2 = map[chr - 0x20]; + } + } } + // If still not drawn than it's a text and we draw the string if (charReady == false) { @@ -561,9 +1184,9 @@ public int PercentageOfMaximumHeight } } catch {} + } } } - } x += w; } } @@ -582,7 +1205,7 @@ public int PercentageOfMaximumHeight /// /// Number of the teletext color, referring to the enumeration TextColors /// Corresponding System Color, or black if the value is not defined - private Color GetColor(int colorNumber) + private static Color GetColor(int colorNumber) { switch (colorNumber) { @@ -603,9 +1226,11 @@ private Color GetColor(int colorNumber) case (int)TextColors.Cyan: return Color.Cyan; case (int)TextColors.Trans1: - return Transparent; + return Color.Transparent; + //return Color.HotPink; case (int)TextColors.Trans2: - return Transparent; + return Color.Transparent; + //return Color.HotPink; } return Color.Black; } @@ -620,12 +1245,49 @@ private static bool IsDecimalPage(int i) return ((i & 0x00F) <= 9) && ((i & 0x0F0) <= 0x90); } + + private int GetLanguageCode(byte code) + { + int languageCode; + + if (code == 0xff) + { + languageCode = 0; + } + else + { + languageCode = ((code >> 3) & 0x01) | (((code >> 2) & 0x01) << 1) | (((code >> 1) & 0x01) << 2); + } + + //switch (languageCode) + //{ + // case 0: + // return 1; + // case 1: + // return 4; + // case 2: + // return 11; + // case 3: + // return 5; + // case 4: + // return 3; + // case 5: + // return 8; + // case 6: + // return 0; + // default: + // return 1; + //} + return languageCode; + } + #endregion #region public methods /// - /// Renders a teletext page to a bitmap + /// Renders a teletext page to a bitmap using the preselected + /// default charset and second G0 charset designation. /// /// The bitmap to render to /// Teletext page data @@ -633,7 +1295,12 @@ private static bool IsDecimalPage(int i) /// Subpagenumber public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPage) { - RenderPage(ref pageBitmap, byPage, mPage, sPage, false); + RenderPage(ref pageBitmap, byPage, mPage, sPage, false, -1, -1); + } + + public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPage, bool waiting) + { + RenderPage(ref pageBitmap, byPage, mPage, sPage, waiting, -1, -1); } /// @@ -645,12 +1312,14 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag /// Teletext page data /// Pagenumber /// Subpagenumber + /// The default charset designation + /// The second G0 charset designation /// Rendered teletext page as bitmap - public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPage, bool waiting) + public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPage, bool waiting, int defaultCharSet, int secondCharSet) { int col; int hold; - int foreground, background, doubleheight, charset, mosaictype; + int foreground, background, doubleheight, charset, mosaictype, alternateSet; byte held_mosaic; bool flag = false; bool isBoxed = false; @@ -706,46 +1375,13 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag } } int row; - int txtLanguage; + //int txtLanguage; // language detection. Extract the bit C12-C14 from the teletext header and set the language code - int languageCode; - byte byte1 = Hamming.Decode[byPage[9]]; - if (byte1 == 0xFF) - { - languageCode = 0; - } - else - { - languageCode = ((byte1 >> 3) & 0x01) | (((byte1 >> 2) & 0x01) << 1) | (((byte1 >> 1) & 0x01) << 2); - } + int languageCode = GetLanguageCode(Hamming.Decode[byPage[9]]); - switch (languageCode) - { - case 0: - txtLanguage = 1; - break; - case 1: - txtLanguage = 4; - break; - case 2: - txtLanguage = _isRegionalDKorNO ? 13 : 11; - break; - case 3: - txtLanguage = 5; - break; - case 4: - txtLanguage = 3; - break; - case 5: - txtLanguage = 8; - break; - case 6: - txtLanguage = 0; - break; - default: - txtLanguage = 1; - break; - } + // Setup character sets + SetupDefaultCharSets(defaultCharSet == -1? _defaultCharSetDesignation : defaultCharSet, languageCode); + SetupSecondG0CharSet(secondCharSet == -1? _secondCharSetDesignation : secondCharSet); // Detect if it's a boxed page. Boxed Page = subtitle and/or newsflash bit is set bool isSubtitlePage = Hamming.IsSubtitleBitSet(0, ref byPage); bool isNewsflash = Hamming.IsNewsflash(0, ref byPage); @@ -798,6 +1434,7 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag mosaictype = 0; hold = 0; held_mosaic = 32; + alternateSet = 0; // Iterate over all columns in the row and check if a box starts for (int loop1 = 0; loop1 < 40; loop1++) { @@ -831,7 +1468,7 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag int index = row * 40 + col; // Set the attributes - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); // Boxed and no flag and not row 24 than delete the characters if (isBoxed && !flag && row != 24) { @@ -920,13 +1557,13 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag { if (_fullscreenMode) { - pageAttribs[row * 40 + clear] = doubleheight << 10 | charset << 8 | (int)TextColors.Trans1 << 4 | - (int)TextColors.Trans1; + pageAttribs[row * 40 + clear] = alternateSet << 11 | doubleheight << 10 | charset << 8 | + (int)TextColors.Trans1 << 4 | (int)TextColors.Trans1; } else { - pageAttribs[row * 40 + clear] = doubleheight << 10 | charset << 8 | (int)TextColors.Black << 4 | - (int)TextColors.Black; + pageAttribs[row * 40 + clear] = alternateSet << 11 | doubleheight << 10 | charset << 8 | + (int)TextColors.Black << 4 | (int)TextColors.Black; } } // Set the standard background color @@ -939,7 +1576,7 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag case (int)Attributes.NormalSize: doubleheight = 0; - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); break; case (int)Attributes.DoubleHeight: @@ -993,7 +1630,7 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag if (_hiddenMode == false) { foreground = background; - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); } break; @@ -1002,7 +1639,7 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag if (charset > 0) { charset = 1; - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); } break; @@ -1011,21 +1648,23 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag if (charset > 0) { charset = 2; - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); } break; case (int)Attributes.Esc: + alternateSet ^= 1; + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); break; case (int)Attributes.BlackBackground: background = (int)TextColors.Black; - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); break; case (int)Attributes.NewBackground: background = foreground; - pageAttribs[index] = (doubleheight << 10 | charset << 8 | background << 4 | foreground); + pageAttribs[index] = (alternateSet << 11 | doubleheight << 10 | charset << 8 | background << 4 | foreground); break; case (int)Attributes.HoldMosaic: @@ -1114,13 +1753,18 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag headline += new string((char)32, 32 - headline.Length); byte[] mpText = Encoding.ASCII.GetBytes(headline); Array.Copy(mpText, 0, pageChars, 0, mpText.Length); + alternateSet = _G0CharSet == G0CharSets.Latin ? 0 : 1 << 11; for (i = 0; i < 11; i++) { - pageAttribs[i] = ((int)TextColors.Black << 4) | lineColor; + pageAttribs[i] = alternateSet | ((int)TextColors.Black << 4) | lineColor; + } + for (i = 11; i < 14; i++) + { + pageAttribs[i] = alternateSet | ((int)TextColors.Black << 4) | ((int)TextColors.White); } - for (i = 12; i < 40; i++) + for (i = 14; i < 40; i++) { - pageAttribs[i] = ((int)TextColors.Black << 4) | ((int)TextColors.White); + pageAttribs[i] = ((int) TextColors.Black << 4) | ((int) TextColors.White); } } @@ -1147,33 +1791,32 @@ public void RenderPage(ref Bitmap pageBitmap, byte[] byPage, int mPage, int sPag // Draw the base rectangle if ((isBoxed || _transparentMode) && _fullscreenMode) { - renderGraphics.Clear(Transparent); + renderGraphics.Clear(Color.Transparent); } else { renderGraphics.FillRectangle(new SolidBrush(Color.Black), 0, 0, _pageRenderWidth, _pageRenderHeight); } + renderGraphics.TextRenderingHint = _textRenderingHint; // Fill the rectangle with the teletext page informations - for (row = 0; row < 25; row++) - { - // If not display a toptext line than abort - if (!displayHeaderAndTopText && row == 24) - { - break; - } - x = 0; - // Draw a single point - for (col = 0; col < 40; col++) + for (row = 0; row < 25; row++) { - Render(ref renderGraphics, ref pageBitmap, pageChars[row * 40 + col], pageAttribs[row * 40 + col], ref x, - ref y, width, height, - txtLanguage); - } + // If not display a toptext line than abort + if (!displayHeaderAndTopText && row == 24) + { + break; + } + x = 0; + // Draw a single point + for (col = 0; col < 40; col++) + { + Render(ref renderGraphics, ref pageBitmap, pageChars[row * 40 + col], pageAttribs[row * 40 + col], ref x, ref y, width, height); + } - y += height + (row == 23 ? 2 : 0); + y += height + (row == 23 ? 2 : 0); + } } - } finally { _fontTeletext.Dispose(); diff --git a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvFullscreenTeletext.cs b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvFullscreenTeletext.cs index 74aa688b110..6584ac9a1e1 100644 --- a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvFullscreenTeletext.cs +++ b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvFullscreenTeletext.cs @@ -19,6 +19,7 @@ #endregion using MediaPortal.GUI.Library; +using MediaPortal.Dialogs; namespace TvPlugin { @@ -82,12 +83,101 @@ public override void OnAction(Action action) // Rerender the image RequestUpdate(false); break; + case Action.ActionType.ACTION_CONTEXT_MENU: + ShowContextMenu(); + return; } base.OnAction(action); } #endregion + #region Context Menu + private void ShowContextMenu() + { + GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); + if (dlg == null || _renderer == null) + { + GUIWindowManager.ShowPreviousWindow(); + return; + } + + dlg.Reset(); + dlg.SetHeading(1441); // Teletext + + dlg.AddLocalizedString(1439); // Change default language + dlg.AddLocalizedString(970); // Previous window + + dlg.DoModal(GetID); + + if (dlg.SelectedId == -1) + return; + switch (dlg.SelectedId) + { + case 1439: // Change default language + { + dlg.Reset(); + dlg.SetHeading(1438); // Change default Teletext language + + dlg.AddLocalizedString(1400); // Latin + dlg.AddLocalizedString(1401); // Latin / Polish + dlg.AddLocalizedString(1402); // Latin / Turkish + dlg.AddLocalizedString(1403); // Latin: sb/cr/sl/ro + dlg.AddLocalizedString(1404); // Cyrilic + dlg.AddLocalizedString(1405); // Greek / Turkish + dlg.AddLocalizedString(1406); // Arabic + dlg.AddLocalizedString(1407); // Hebrew / Arabic + + if (DefaultCharSetDesignation <= 4 && DefaultCharSetDesignation >= 0) + dlg.SelectedLabel = DefaultCharSetDesignation; + else if (DefaultCharSetDesignation == 6) + dlg.SelectedLabel = 5; + else if (DefaultCharSetDesignation == 8) + dlg.SelectedLabel = 6; + else if (DefaultCharSetDesignation == 10) + dlg.SelectedLabel = 7; + + dlg.DoModal(GetID); + + if (dlg.SelectedId == -1) + return; + switch (dlg.SelectedId) + { + case 1400: + DefaultCharSetDesignation = 0; + break; + case 1401: + DefaultCharSetDesignation = 1; + break; + case 1402: + DefaultCharSetDesignation = 2; + break; + case 1403: + DefaultCharSetDesignation = 3; + break; + case 1404: + DefaultCharSetDesignation = 4; + break; + case 1405: + DefaultCharSetDesignation = 6; + break; + case 1406: + DefaultCharSetDesignation = 8; + break; + case 1407: + DefaultCharSetDesignation = 10; + break; + } + //SaveSettings(); + return; + } + case 970: // Previous window + GUIWindowManager.ShowPreviousWindow(); + return; + } + } + #endregion + #region Rendering method public override void Render(float timePassed) diff --git a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletext.cs b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletext.cs index be203afaa91..a5876e4e940 100644 --- a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletext.cs +++ b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletext.cs @@ -21,6 +21,7 @@ using System; using MediaPortal.GUI.Library; using Action = MediaPortal.GUI.Library.Action; +using MediaPortal.Dialogs; namespace TvPlugin.teletext { @@ -37,6 +38,7 @@ public class TVTeletext : TvTeletextBase [SkinControl(505)] protected GUIToggleButtonControl btnHidden = null; [SkinControl(506)] protected GUISelectButtonControl btnSubPage = null; [SkinControl(507)] protected GUIButtonControl btnFullscreen = null; + [SkinControl(508)] protected GUIButtonControl btnLanguage = null; #endregion @@ -153,9 +155,74 @@ protected override void OnClicked(int controlId, GUIControl control, Action.Acti GUIGraphicsContext.IsFullScreenVideo = true; GUIWindowManager.ActivateWindow((int)Window.WINDOW_FULLSCREEN_TELETEXT); } + if (control == btnLanguage) + { + SelectLanguage(); + } base.OnClicked(controlId, control, actionType); } + private void SelectLanguage() + { + GUIDialogMenu dlg = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); + if (dlg == null || _renderer == null) + return; + + dlg.Reset(); + dlg.SetHeading(1438); // Change default Teletext language + + dlg.AddLocalizedString(1400); // Latin + dlg.AddLocalizedString(1401); // Latin / Polish + dlg.AddLocalizedString(1402); // Latin / Turkish + dlg.AddLocalizedString(1403); // Latin: sb/cr/sl/ro + dlg.AddLocalizedString(1404); // Cyrilic + dlg.AddLocalizedString(1405); // Greek / Turkish + dlg.AddLocalizedString(1406); // Arabic + dlg.AddLocalizedString(1407); // Hebrew / Arabic + + if (DefaultCharSetDesignation <= 4 && DefaultCharSetDesignation >= 0) + dlg.SelectedLabel = DefaultCharSetDesignation; + else if (DefaultCharSetDesignation == 6) + dlg.SelectedLabel = 5; + else if (DefaultCharSetDesignation == 8) + dlg.SelectedLabel = 6; + else if (DefaultCharSetDesignation == 10) + dlg.SelectedLabel = 7; + + dlg.DoModal(GetID); + + if (dlg.SelectedId == -1) + return; + switch (dlg.SelectedId) + { + case 1400: + DefaultCharSetDesignation = 0; + break; + case 1401: + DefaultCharSetDesignation = 1; + break; + case 1402: + DefaultCharSetDesignation = 2; + break; + case 1403: + DefaultCharSetDesignation = 3; + break; + case 1404: + DefaultCharSetDesignation = 4; + break; + case 1405: + DefaultCharSetDesignation = 6; + break; + case 1406: + DefaultCharSetDesignation = 8; + break; + case 1407: + DefaultCharSetDesignation = 10; + break; + } + //SaveSettings(); + return; + } #endregion public override void Render(float timePassed) diff --git a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletextBase.cs b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletextBase.cs index 2912d514051..256b2ef79cb 100644 --- a/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletextBase.cs +++ b/TvEngine3/TVLibrary/TvPlugin/TvPlugin/teletext/TvTeletextBase.cs @@ -80,7 +80,8 @@ public class TvTeletextBase : GUIInternalWindow protected bool _redrawForeground = true; protected bool _showFirstAvailableSubPage = false; protected DateTime _trottling = DateTime.MinValue; - + protected int _defaultCharSetDesignation = 0; + protected System.Drawing.Text.TextRenderingHint _textRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; #endregion #region Properties @@ -91,6 +92,26 @@ public override bool IsTv { return true; } + } + + public int DefaultCharSetDesignation + { + get + { + return _defaultCharSetDesignation; + } + set + { + if (_defaultCharSetDesignation != value) + { + _defaultCharSetDesignation = value; + if (_renderer != null) + { + _renderer.DefaultCharSetDesignation = _defaultCharSetDesignation; + } + _numberOfRequestedUpdates++; + } + } } public bool Waiting @@ -142,6 +163,10 @@ protected void InitializeWindow(bool fullscreenMode) _renderer.HiddenMode = _hiddenMode; _renderer.PageSelectText = Convert.ToString(currentPageNumber, 16); _renderer.PercentageOfMaximumHeight = _percentageOfMaximumHeight; + _renderer.DefaultCharSetDesignation = _defaultCharSetDesignation; + _renderer.TextRenderingHint = _textRenderingHint; + // For now second G0 charset designation is always Latin + _renderer.SecondCharSetDesignation = 0; _waiting = false; @@ -587,6 +612,7 @@ protected void UpdatePage() Log.Error(ex); } }*/ + protected void Redraw() { Bitmap bitmap; @@ -730,10 +756,63 @@ protected void LoadSettings() { using (Settings xmlreader = new MPSettings()) { + string strValue; _hiddenMode = xmlreader.GetValueAsBool("mytv", "teletextHidden", false); _transparentMode = xmlreader.GetValueAsBool("mytv", "teletextTransparent", false); _rememberLastValues = xmlreader.GetValueAsBool("mytv", "teletextRemember", true); _percentageOfMaximumHeight = xmlreader.GetValueAsInt("mytv", "teletextMaxFontSize", 100); + + // Read language setting + strValue = xmlreader.GetValueAsString("myteletext", "defaultLanguage", "latin1"); + switch (strValue.ToLower()) + { + case "latin1": + _defaultCharSetDesignation = 0; + break; + case "latin2": + _defaultCharSetDesignation = 1; + break; + case "latin3": + _defaultCharSetDesignation = 2; + break; + case "latin4": + _defaultCharSetDesignation = 3; + break; + case "cyrillic": + _defaultCharSetDesignation = 4; + break; + case "greek": + _defaultCharSetDesignation = 6; + break; + case "arabic": + _defaultCharSetDesignation = 8; + break; + case "hebrew": + _defaultCharSetDesignation = 10; + break; + default: + _defaultCharSetDesignation = 0; + break; + } + strValue = xmlreader.GetValueAsString("myteletext", "fontQuality", "normal-gridfit"); + switch (strValue.ToLower()) + { + case "normal": + _textRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel; + break; + case "normal-gridfit": + _textRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; + break; + case "smooth": + _textRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; + break; + case "smooth-gridfit": + _textRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; + break; + default: + _textRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit; + break; + } } } @@ -742,12 +821,40 @@ protected void LoadSettings() /// protected void SaveSettings() { + using (Settings xmlwriter = new MPSettings()) + { if (_rememberLastValues) { using (Settings xmlreader = new MPSettings()) + xmlwriter.SetValueAsBool("mytv", "teletextHidden", _hiddenMode); + xmlwriter.SetValueAsBool("mytv", "teletextTransparent", _transparentMode); + } + switch (_defaultCharSetDesignation) { - xmlreader.SetValueAsBool("mytv", "teletextHidden", _hiddenMode); - xmlreader.SetValueAsBool("mytv", "teletextTransparent", _transparentMode); + case 0: + xmlwriter.SetValue("myteletext", "defaultLanguage", "latin1"); + break; + case 1: + xmlwriter.SetValue("myteletext", "defaultLanguage", "latin2"); + break; + case 2: + xmlwriter.SetValue("myteletext", "defaultLanguage", "latin3"); + break; + case 3: + xmlwriter.SetValue("myteletext", "defaultLanguage", "latin4"); + break; + case 4: + xmlwriter.SetValue("myteletext", "defaultLanguage", "cyrillic"); + break; + case 6: + xmlwriter.SetValue("myteletext", "defaultLanguage", "greek"); + break; + case 8: + xmlwriter.SetValue("myteletext", "defaultLanguage", "arabic"); + break; + case 10: + xmlwriter.SetValue("myteletext", "defaultLanguage", "hebrew"); + break; } } } diff --git a/mediaportal/Configuration/Sections/TVTeletext.cs b/mediaportal/Configuration/Sections/TVTeletext.cs index 50ab3bf3437..c37c20b1fef 100644 --- a/mediaportal/Configuration/Sections/TVTeletext.cs +++ b/mediaportal/Configuration/Sections/TVTeletext.cs @@ -19,6 +19,7 @@ #endregion using System.ComponentModel; +using System.Collections.Generic; using MediaPortal.Profile; using MediaPortal.UserInterface.Controls; @@ -38,6 +39,42 @@ public class TVTeletext : SectionSettings private MPLabel FontSizeLbl; private MPLabel FontSizeValueLbl; private MPNumericUpDown nudFontSize; + public class ValueTextPair + { + public string _value; + public string _displayText; + + public ValueTextPair(string newValue, string newDisplayText) + { + _value = newValue; + _displayText = newDisplayText; + } + + public string Value + { + get + { + return _value; + } + } + public string DislpayText + { + get + { + return _displayText; + } + } + + public override string ToString() + { + return _displayText; + } + } + + private MediaPortal.UserInterface.Controls.MPComboBox LanguageComboBox; + private MediaPortal.UserInterface.Controls.MPLabel LanguageLabel; + private MediaPortal.UserInterface.Controls.MPComboBox FontQualityComboBox; + private MediaPortal.UserInterface.Controls.MPLabel FontQualityLabel; public int pluginVersion; public TVTeletext() @@ -48,6 +85,13 @@ public TVTeletext(string name) { // This call is required by the Windows Form Designer. InitializeComponent(); + LanguageComboBox.DisplayMember = "DisplayText"; + LanguageComboBox.ValueMember = "Value"; + LanguageComboBox.DataSource = GetLanguageOptions(); + + FontQualityComboBox.DisplayMember = "DisplayText"; + FontQualityComboBox.ValueMember = "Value"; + FontQualityComboBox.DataSource = GetFontQualityOptions(); } public override void OnSectionActivated() @@ -91,6 +135,10 @@ private void InitializeComponent() this.cbRememberValue = new MediaPortal.UserInterface.Controls.MPCheckBox(); this.cbTransparentMode = new MediaPortal.UserInterface.Controls.MPCheckBox(); this.radioButton1 = new MediaPortal.UserInterface.Controls.MPRadioButton(); + this.FontQualityLabel = new MediaPortal.UserInterface.Controls.MPLabel(); + this.FontQualityComboBox = new MediaPortal.UserInterface.Controls.MPComboBox(); + this.LanguageLabel = new MediaPortal.UserInterface.Controls.MPLabel(); + this.LanguageComboBox = new MediaPortal.UserInterface.Controls.MPComboBox(); this.groupBox1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudFontSize)).BeginInit(); this.SuspendLayout(); @@ -107,17 +155,21 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.cbHiddenMode); this.groupBox1.Controls.Add(this.cbRememberValue); this.groupBox1.Controls.Add(this.cbTransparentMode); + this.groupBox1.Controls.Add(this.FontQualityComboBox); + this.groupBox1.Controls.Add(this.FontQualityLabel); + this.groupBox1.Controls.Add(this.LanguageLabel); + this.groupBox1.Controls.Add(this.LanguageComboBox); this.groupBox1.FlatStyle = System.Windows.Forms.FlatStyle.Popup; this.groupBox1.Location = new System.Drawing.Point(6, 0); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(462, 127); + this.groupBox1.Size = new System.Drawing.Size(472, 188); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; this.groupBox1.Text = "Settings"; // // nudFontSize // - this.nudFontSize.Location = new System.Drawing.Point(72, 97); + this.nudFontSize.Location = new System.Drawing.Point(114, 97); this.nudFontSize.Minimum = new decimal(new int[] { 50, @@ -142,7 +194,7 @@ private void InitializeComponent() this.FontSizeValueLbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.FontSizeValueLbl.Location = new System.Drawing.Point(134, 99); + this.FontSizeValueLbl.Location = new System.Drawing.Point(176, 99); this.FontSizeValueLbl.Name = "FontSizeValueLbl"; this.FontSizeValueLbl.Size = new System.Drawing.Size(105, 13); this.FontSizeValueLbl.TabIndex = 3; @@ -201,6 +253,46 @@ private void InitializeComponent() this.radioButton1.TabIndex = 0; this.radioButton1.UseVisualStyleBackColor = true; // + // FontQualityComboBox + // + this.FontQualityComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.FontQualityComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.FontQualityComboBox.FormattingEnabled = true; + this.FontQualityComboBox.Location = new System.Drawing.Point(114, 148); + this.FontQualityComboBox.Name = "FontQualityComboBox"; + this.FontQualityComboBox.Size = new System.Drawing.Size(325, 21); + this.FontQualityComboBox.TabIndex = 6; + // + // FontQualityLabel + // + this.FontQualityLabel.AutoSize = true; + this.FontQualityLabel.Location = new System.Drawing.Point(14, 151); + this.FontQualityLabel.Name = "FontQualityLabel"; + this.FontQualityLabel.Size = new System.Drawing.Size(63, 13); + this.FontQualityLabel.TabIndex = 5; + this.FontQualityLabel.Text = "Font Quality"; + // + // LanguageLabel + // + this.LanguageLabel.AutoSize = true; + this.LanguageLabel.Location = new System.Drawing.Point(14, 126); + this.LanguageLabel.Name = "LanguageLabel"; + this.LanguageLabel.Size = new System.Drawing.Size(88, 13); + this.LanguageLabel.TabIndex = 4; + this.LanguageLabel.Text = "Default language"; + // + // LanguageComboBox + // + this.LanguageComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.LanguageComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.LanguageComboBox.FormattingEnabled = true; + this.LanguageComboBox.Location = new System.Drawing.Point(114, 123); + this.LanguageComboBox.Name = "LanguageComboBox"; + this.LanguageComboBox.Size = new System.Drawing.Size(325, 21); + this.LanguageComboBox.TabIndex = 3; + // // TVTeletext // this.Controls.Add(this.groupBox1); @@ -224,14 +316,34 @@ public override void LoadSettings() using (Settings xmlreader = new MPSettings()) { + string strValue; + cbHiddenMode.Checked = xmlreader.GetValueAsBool("mytv", "teletextHidden", false); cbTransparentMode.Checked = xmlreader.GetValueAsBool("mytv", "teletextTransparent", false); cbRememberValue.Checked = xmlreader.GetValueAsBool("mytv", "teletextRemember", true); nudFontSize.Value = xmlreader.GetValueAsInt("mytv", "teletextMaxFontSize", 100); + + // Read the language setting + strValue = xmlreader.GetValueAsString("myteletext", "defaultLanguage", "latin1"); + try + { + LanguageComboBox.SelectedValue = strValue.ToLower(); + } + catch + { + } + strValue = xmlreader.GetValueAsString("myteletext", "fontQuality", "normal-gridfit"); + try + { + FontQualityComboBox.SelectedValue = strValue.ToLower(); + } + catch + { + } + } } - public override void SaveSettings() { if (_init == false) @@ -244,7 +356,34 @@ public override void SaveSettings() xmlwriter.SetValueAsBool("mytv", "teletextTransparent", cbTransparentMode.Checked); xmlwriter.SetValueAsBool("mytv", "teletextRemember", cbRememberValue.Checked); xmlwriter.SetValue("mytv", "teletextMaxFontSize", nudFontSize.Value); + xmlwriter.SetValue("myteletext", "defaultLanguage", LanguageComboBox.SelectedValue); + xmlwriter.SetValue("myteletext", "fontQuality", FontQualityComboBox.SelectedValue); } } + protected List GetLanguageOptions() + { + List al = new List(); + + + al.Add(new ValueTextPair("latin1", "Latin")); + al.Add(new ValueTextPair("latin2", "Latin / Polish")); + al.Add(new ValueTextPair("latin3", "Latin / Turkish")); + al.Add(new ValueTextPair("latin4", "Latin: Serbian / Croatian / Slovenian / Romanian")); + al.Add(new ValueTextPair("cyrilic", "Cyrilic")); + al.Add(new ValueTextPair("greek", "Greek / Turkish")); + al.Add(new ValueTextPair("arabic", "Arabic")); + al.Add(new ValueTextPair("hebrew", "Hebrew / Arabic")); + return al; + } + + protected List GetFontQualityOptions() + { + List al = new List(); + al.Add(new ValueTextPair("normal", "Normal (Fastest)")); + al.Add(new ValueTextPair("normal-gridfit", "Normal with hinting (Faster)")); + al.Add(new ValueTextPair("smooth", "Smooth (Slower)")); + al.Add(new ValueTextPair("smooth-gridfit", "Smooth with hinting (Slowest)")); + return al; + } } } \ No newline at end of file diff --git a/mediaportal/MediaPortal.Base/language/strings_el.xml b/mediaportal/MediaPortal.Base/language/strings_el.xml index 859928c9532..b69f0328a37 100644 --- a/mediaportal/MediaPortal.Base/language/strings_el.xml +++ b/mediaportal/MediaPortal.Base/language/strings_el.xml @@ -507,6 +507,7 @@ Υποσελίδα Πλήρης σελίδα Αναμονή για σελίδα {0}/{1}... + Γλώσσα Καταιγίδα Οδηγός TV Εγγραφή Τώρα @@ -966,6 +967,16 @@ DVD Navigator Οδηγός ρυθμίσεων TV Εκπομπές + Latin + Latin / Polish + Latin / Turkish + Latin: sb/cr/sl/ro + Cyrillic + Ελληνικά / Turkish + Arabic + Hebrew / Arabic + Αλλαγή γλώσσας Teletext + Αλλαγή γλώσσας Teletext Teletext Ταχύτητα κύλισης (οριζόντια) diff --git a/mediaportal/MediaPortal.Base/language/strings_en.xml b/mediaportal/MediaPortal.Base/language/strings_en.xml index d77ee9124e8..5ce3274b5a4 100644 --- a/mediaportal/MediaPortal.Base/language/strings_en.xml +++ b/mediaportal/MediaPortal.Base/language/strings_en.xml @@ -530,6 +530,7 @@ Subpage Fullscreen Waiting for Page {0}/{1}... + Language Storm TV Guide Record Now @@ -1017,6 +1018,16 @@ Lock content Unlock content TV Shows + Latin + Latin / Polish + Latin / Turkish + Latin: sb/cr/sl/ro + Cyrillic + Greek / Turkish + Arabic + Hebrew / Arabic + Change Teletext language + Change language Teletext Teletext Scroll speed (horizontal) diff --git a/mediaportal/MediaPortal.Base/skin/Default/myteletext.xml b/mediaportal/MediaPortal.Base/skin/Default/myteletext.xml index 6087c7b478c..322c01537e3 100644 --- a/mediaportal/MediaPortal.Base/skin/Default/myteletext.xml +++ b/mediaportal/MediaPortal.Base/skin/Default/myteletext.xml @@ -198,9 +198,21 @@ 266 506 - 502 + 508 507 + + Language + button + 508 + 60 + 301 + + 170 + 507 + 502 + 508 + video rectangle diff --git a/mediaportal/MediaPortal.Base/skin/DefaultWide/myteletext.xml b/mediaportal/MediaPortal.Base/skin/DefaultWide/myteletext.xml index 01b22b137b0..4b5eddda63c 100644 --- a/mediaportal/MediaPortal.Base/skin/DefaultWide/myteletext.xml +++ b/mediaportal/MediaPortal.Base/skin/DefaultWide/myteletext.xml @@ -197,9 +197,20 @@ 333 506 - 502 + 508 507 + + Language + button + 508 + 106 + 376 + + 507 + 502 + 508 + video rectangle