MythTV  master
teletextscreen.cpp
Go to the documentation of this file.
1 #include <QFontMetrics>
2 #include <QPainter>
3 
4 #include "mythlogging.h"
5 #include "mythfontproperties.h"
6 #include "mythuitext.h"
7 #include "mythuishape.h"
8 #include "vbilut.h"
9 #include "mythimage.h"
10 #include "mythuiimage.h"
11 #include "mythpainter.h"
12 #include "teletextscreen.h"
13 #include "subtitlescreen.h"
14 
15 #define LOC QString("TeletextScreen: ")
16 
17 const QColor TeletextScreen::kColorBlack = QColor( 0, 0, 0,255);
18 const QColor TeletextScreen::kColorRed = QColor(255, 0, 0,255);
19 const QColor TeletextScreen::kColorGreen = QColor( 0,255, 0,255);
20 const QColor TeletextScreen::kColorYellow = QColor(255,255, 0,255);
21 const QColor TeletextScreen::kColorBlue = QColor( 0, 0,255,255);
22 const QColor TeletextScreen::kColorMagenta = QColor(255, 0,255,255);
23 const QColor TeletextScreen::kColorCyan = QColor( 0,255,255,255);
24 const QColor TeletextScreen::kColorWhite = QColor(255,255,255,255);
26 const int TeletextScreen::kTeletextRows = 26;
27 
29 static int gTTBackgroundAlpha;
30 
31 static QChar cvt_char(char ch, int lang)
32 {
33  for (int j = 0; j < 14; j++)
34  {
35  int c = ch & 0x7F;
36  if (c == lang_chars[0][j])
37  ch = lang_chars[lang + 1][j];
38  }
39  return QLatin1Char(ch);
40 }
41 
42 TeletextScreen::TeletextScreen(MythPlayer *player, const char * name,
43  int fontStretch) :
44  MythScreenType((MythScreenType*)nullptr, name),
45  m_player(player),
46  m_fontStretch(fontStretch)
47 {
48 }
49 
51 {
52  ClearScreen();
53 }
54 
56 {
57  if (m_player)
59  return m_player && m_teletextReader;
60 }
61 
63 {
65  QHash<int, QImage*>::iterator it = m_rowImages.begin();
66  for (; it != m_rowImages.end(); ++it)
67  {
68  if (*it)
69  delete (*it);
70  }
71  m_rowImages.clear();
72  SetRedraw();
73 }
74 
75 QImage* TeletextScreen::GetRowImage(int row, QRect &rect)
76 {
77  int y = row & ~1;
78  rect.translate(0, -(y * m_rowHeight));
79  if (!m_rowImages.contains(y))
80  {
81  auto* img = new QImage(m_safeArea.width(), m_rowHeight * 2,
82  QImage::Format_ARGB32);
83  if (img)
84  {
85  img->fill(0);
86  m_rowImages.insert(y, img);
87  }
88  else
89  return nullptr;
90  }
91  return m_rowImages.value(y);
92 }
93 
95 {
97  if (!vo)
98  return;
99  MythPainter *osd_painter = vo->GetOSDPainter();
100  if (!osd_painter)
101  return;
102 
103  QHashIterator<int, QImage*> it(m_rowImages);
104  while (it.hasNext())
105  {
106  it.next();
107  MythImage *image = osd_painter->GetFormatImage();
108  if (!image || !it.value())
109  continue;
110 
111  int row = it.key();
112  image->Assign(*(it.value()));
113  auto *uiimage = new MythUIImage(this, QString("ttrow%1").arg(row));
114  if (uiimage)
115  {
116  uiimage->SetImage(image);
117  uiimage->SetArea(MythRect(0, row * m_rowHeight,
118  m_safeArea.width(), m_rowHeight * 2));
119  }
120  image->DecrRef();
121  }
122 
123  QRegion visible;
124  QListIterator<MythUIType *> i(m_ChildrenList);
125  while (i.hasNext())
126  {
127  MythUIType *img = i.next();
128  visible = visible.united(img->GetArea());
129  }
130 
131  if (visible.isEmpty())
132  return;
133 
134  QRect bounding = visible.boundingRect();
135  bounding = bounding.translated(m_safeArea.topLeft());
136  bounding = m_safeArea.intersected(bounding);
137  int left = m_safeArea.left() - bounding.left();
138  int top = m_safeArea.top() - bounding.top();
139  SetArea(MythRect(bounding));
140 
141  i.toFront();;
142  while (i.hasNext())
143  {
144  MythUIType *img = i.next();
145  img->SetArea(img->GetArea().translated(left, top));
146  }
147 }
148 
150 {
151  if (!InitialiseFont() || !m_displaying)
152  return;
153 
154  if (m_player && m_player->GetVideoOutput())
155  {
156  static const float kTextPadding = 0.96F;
157  QRect oldsafe = m_safeArea;
159  m_colWidth = (int)((float)m_safeArea.width() / (float)kTeletextColumns);
160  m_rowHeight = (int)((float)m_safeArea.height() / (float)kTeletextRows);
161 
162  if (oldsafe != m_safeArea)
163  {
165 
166  int max_width = (int)((float)m_colWidth * kTextPadding);
167  m_fontHeight = (int)((float)m_rowHeight * kTextPadding);
168  if (max_width > (m_colWidth - 2))
169  max_width = m_colWidth -2;
170  if (m_fontHeight > (m_rowHeight - 2))
172  gTTFont->GetFace()->setPixelSize(m_fontHeight);
173 
174  m_fontStretch = 200;
175  bool ok = false;
176  while (!ok && m_fontStretch > 50)
177  {
178  gTTFont->GetFace()->setStretch(m_fontStretch);
179  QFontMetrics font(*(gTTFont->GetFace()));
180  if (font.averageCharWidth() <= max_width || m_fontStretch < 50)
181  ok = true;
182  else
183  m_fontStretch -= 10;
184  }
185  }
186  }
187  else
188  {
189  return;
190  }
191 
193  return;
194 
195  ClearScreen();
196 
197  const TeletextSubPage *ttpage = m_teletextReader->FindSubPage();
198 
199  if (!ttpage)
200  {
201  // no page selected so show the header and a list of available pages
202  DrawHeader(nullptr, 0);
205  return;
206  }
207 
209 
210  int a = 0;
211  if ((ttpage->subtitle) ||
213  {
214  a = 1; // when showing subtitles we don't want to see the teletext
215  // header line, so we skip that line...
218  }
219  else
220  {
225  }
226 
227  for (int y = kTeletextRows - a; y >= 2; y--)
228  DrawLine(ttpage->data[y-1], y, ttpage->lang);
229 
232 }
233 
234 bool TeletextScreen::KeyPress(const QString &key)
235 {
236  if (m_teletextReader)
237  return m_teletextReader->KeyPress(key);
238  return false;
239 }
240 
241 void TeletextScreen::SetPage(int page, int subpage)
242 {
243  if (m_teletextReader)
244  m_teletextReader->SetPage(page, subpage);
245 }
246 
248 {
249  m_displaying = display;
250  if (!m_displaying)
251  ClearScreen();
252 }
253 
255 {
256  if (m_teletextReader)
258 }
259 
260 void TeletextScreen::DrawHeader(const uint8_t *page, int lang)
261 {
262  if (!m_displaying)
263  return;
264 
265  if (page != nullptr)
266  DrawLine(page, 1, lang);
267 
268  DrawStatus();
269 }
270 
271 static QColor ttcolortoqcolor(int ttcolor)
272 {
273  QColor color;
274 
275  switch (ttcolor & ~kTTColorTransparent)
276  {
277  case kTTColorBlack: color = TeletextScreen::kColorBlack; break;
278  case kTTColorRed: color = TeletextScreen::kColorRed; break;
279  case kTTColorGreen: color = TeletextScreen::kColorGreen; break;
280  case kTTColorYellow: color = TeletextScreen::kColorYellow; break;
281  case kTTColorBlue: color = TeletextScreen::kColorBlue; break;
282  case kTTColorMagenta: color = TeletextScreen::kColorMagenta; break;
283  case kTTColorCyan: color = TeletextScreen::kColorCyan; break;
284  case kTTColorWhite: color = TeletextScreen::kColorWhite; break;
285  }
286 
287  return color;
288 }
289 
290 static QString TTColorToString(int ttcolor)
291 {
292  switch (ttcolor & ~kTTColorTransparent)
293  {
294  case kTTColorBlack: return "Black";
295  case kTTColorRed: return "Red";
296  case kTTColorGreen: return "Green";
297  case kTTColorYellow: return "Yellow";
298  case kTTColorBlue: return "Blue";
299  case kTTColorMagenta: return "Magenta";
300  case kTTColorCyan: return "Cyan";
301  case kTTColorWhite: return "White";
302  default: return "Unknown";
303  }
304 }
305 
307 {
308  LOG(VB_VBI, LOG_DEBUG, QString("SetForegroundColor(%1)")
309  .arg(TTColorToString(ttcolor)));
310 
311  gTTFont->SetColor(ttcolortoqcolor(ttcolor));
312 }
313 
315 {
316  LOG(VB_VBI, LOG_DEBUG, QString("SetBackgroundColor(%1)")
317  .arg(TTColorToString(ttcolor)));
318 
319  m_bgColor = ttcolortoqcolor(ttcolor);
320  m_bgColor.setAlpha((ttcolor & kTTColorTransparent) ?
321  0x00 : gTTBackgroundAlpha);
322 }
323 
324 void TeletextScreen::DrawLine(const uint8_t *page, uint row, int lang)
325 {
326  bool mosaic;
327  bool conceal;
328  bool seperation;
329  bool flash;
330  bool doubleheight;
331  bool blink;
332  bool hold;
333  bool endbox;
334  bool startbox;
335  bool withinbox;
336 
337  unsigned char last_ch = ' ';
338  unsigned char ch;
339 
340  uint fgcolor = kTTColorWhite;
341  uint bgcolor = kTTColorBlack;
342 
344  {
345  bgcolor = kTTColorTransparent;
346 
347  bool isBlank = true;
348  for (uint i = (row == 1 ? 8 : 0); i < (uint) kTeletextColumns; i++)
349  {
350  ch = page[i] & 0x7F;
351  if (ch != ' ')
352  {
353  isBlank = false;
354  break;
355  }
356  }
357 
358  if (isBlank)
359  return;
360  }
361 
362  SetForegroundColor(fgcolor);
363  SetBackgroundColor(bgcolor);
364 
365  mosaic = false;
366  seperation = false;
367  conceal = false;
368  flash = false;
369  doubleheight = false;
370  blink = false;
371  hold = false;
372  endbox = false;
373  startbox = false;
374  withinbox = false;
375  uint flof_link_count = 0;
376  uint old_bgcolor = bgcolor;
377 
378  if (row == 1)
379  {
380  for (uint x = 0; x < 8; x++)
381  DrawBackground(x, 1);
382  }
383 
384  for (uint x = (row == 1 ? 8 : 0); x < (uint)kTeletextColumns; ++x)
385  {
386  if (startbox)
387  {
388  old_bgcolor = bgcolor;
389  if (kTTColorTransparent & bgcolor)
390  bgcolor = bgcolor & ~kTTColorTransparent;
391  startbox = false;
392  withinbox = true;
393  }
394 
395  if (endbox)
396  {
397  bgcolor = old_bgcolor;
398  endbox = false;
399  withinbox = false;
400  }
401 
402  SetForegroundColor(fgcolor);
403  SetBackgroundColor(bgcolor);
404 
405  ch = page[x] & 0x7F;
406  switch (ch)
407  {
408  case 0x00: case 0x01: case 0x02: case 0x03:
409  case 0x04: case 0x05: case 0x06: case 0x07: // alpha + foreground color
410  fgcolor = ch & 7;
411  mosaic = false;
412  conceal = false;
413  // increment FLOF/FastText count if menu item detected
414  flof_link_count += (row == 25) ? 1 : 0;
415  goto ctrl;
416  case 0x08: // flash
417  // XXX
418  goto ctrl;
419  case 0x09: // steady
420  flash = false;
421  goto ctrl;
422  case 0x0a: // end box
423  endbox = true;
424  goto ctrl;
425  case 0x0b: // start box
426  if (x < kTeletextColumns - 1 && ((page[x + 1] & 0x7F) == 0x0b))
427  startbox = true;
428  goto ctrl;
429  case 0x0c: // normal height
430  doubleheight = false;
431  goto ctrl;
432  case 0x0d: // double height
433  doubleheight = (row < (kTeletextRows-1)) && (x < (kTeletextColumns - 1));
434  goto ctrl;
435 
436  case 0x10: case 0x11: case 0x12: case 0x13:
437  case 0x14: case 0x15: case 0x16: case 0x17: // graphics + foreground color
438  fgcolor = ch & 7;
439  mosaic = true;
440  conceal = false;
441  goto ctrl;
442  case 0x18: // conceal display
443  conceal = true;
444  goto ctrl;
445  case 0x19: // contiguous graphics
446  seperation = false;
447  goto ctrl;
448  case 0x1a: // separate graphics
449  seperation = true;
450  goto ctrl;
451  case 0x1c: // black background
452  bgcolor = kTTColorBlack;
453  goto ctrl;
454  case 0x1d: // new background
455  bgcolor = fgcolor;
456  goto ctrl;
457  case 0x1e: // hold graphics
458  hold = true;
459  goto ctrl;
460  case 0x1f: // release graphics
461  hold = false;
462  goto ctrl;
463  case 0x0e: // SO (reserved, double width)
464  case 0x0f: // SI (reserved, double size)
465  case 0x1b: // ESC (reserved)
466  ch = ' ';
467  break;
468  ctrl:
469  ch = ' ';
470  if (hold && mosaic)
471  ch = last_ch;
472  break;
473 
474  default:
475  if ((ch >= 0x80) && (ch <=0x9f)) // these aren't used
476  ch = ' '; // BAD_CHAR;
477  else
478  {
479  if (conceal && !m_teletextReader->RevealHidden())
480  ch = ' ';
481  }
482  break;
483  }
484 
485  // Hide FastText/FLOF menu characters if not available
486  if (flof_link_count && (flof_link_count <= 6))
487  {
488  const TeletextSubPage *ttpage = m_teletextReader->FindSubPage();
489 
490  if (ttpage)
491  {
492  bool has_flof = ttpage->floflink[flof_link_count - 1] != 0;
493  ch = (has_flof) ? ch : ' ';
494  }
495  }
496 
497  uint newfgcolor = fgcolor;
498  uint newbgcolor = bgcolor;
499 
500  SetForegroundColor(newfgcolor);
501  SetBackgroundColor(newbgcolor);
502  if ((row != 0) || (x > 7))
503  {
506 
507  if (withinbox || !m_teletextReader->IsSubtitle())
508  {
509  DrawBackground(x, row);
510  if (doubleheight && row < (uint)kTeletextRows)
511  DrawBackground(x, row + 1);
512 
513  if ((mosaic) && (ch < 0x40 || ch > 0x5F))
514  {
515  SetBackgroundColor(newfgcolor);
516  DrawMosaic(x, row, ch, doubleheight);
517  }
518  else
519  {
520  QChar c2 = cvt_char(ch, lang);
521  DrawCharacter(x, row, c2, doubleheight);
522  }
523  }
524  }
525  }
526  Q_UNUSED(seperation);
527  Q_UNUSED(flash);
528  Q_UNUSED(blink);
529 }
530 
531 void TeletextScreen::DrawCharacter(int x, int y, QChar ch, bool doubleheight)
532 {
533  QString line = ch;
534  if (line == " ")
535  return;
536 
537  int row = y;
538  x *= m_colWidth;
539  y *= m_rowHeight;
540  int height = m_rowHeight * (doubleheight ? 2 : 1);
541  QRect rect(x, y, m_colWidth, height);
542 
543  if (doubleheight)
544  {
545  gTTFont->GetFace()->setPixelSize(m_fontHeight * 2);
546  gTTFont->GetFace()->setStretch(m_fontStretch / 2);
547  }
548 
549  QImage* image = GetRowImage(row, rect);
550  if (image)
551  {
552  QPainter painter(image);
553  painter.setFont(gTTFont->face());
554  painter.setPen(gTTFont->color());
555  painter.drawText(rect, Qt::AlignCenter, line);
556  painter.end();
557  }
558 
559  if (row & 1)
560  {
561  row++;
562  rect = QRect(x, y + m_rowHeight, m_colWidth, height);
563  rect.translate(0, -m_rowHeight);
564  image = GetRowImage(row, rect);
565  if (image)
566  {
567  QPainter painter(image);
568  painter.setFont(gTTFont->face());
569  painter.setPen(gTTFont->color());
570  painter.drawText(rect, Qt::AlignCenter, line);
571  painter.end();
572  }
573  }
574 
575  if (doubleheight)
576  {
577  gTTFont->GetFace()->setPixelSize(m_fontHeight);
578  gTTFont->GetFace()->setStretch(m_fontStretch);
579  }
580 }
581 
583 {
584  int row = y;
585  x *= m_colWidth;
586  y *= m_rowHeight;
587  DrawRect(row, QRect(x, y, m_colWidth, m_rowHeight));
588 }
589 
590 void TeletextScreen::DrawRect(int row, QRect rect)
591 {
592  QImage* image = GetRowImage(row, rect);
593  if (!image)
594  return;
595 
596  QBrush bgfill = QBrush(m_bgColor, Qt::SolidPattern);
597  QPainter painter(image);
598  painter.setBrush(bgfill);
599  painter.setPen(QPen(Qt::NoPen));
600  painter.drawRect(rect);
601  painter.end();
602 }
603 
604 void TeletextScreen::DrawMosaic(int x, int y, int code, bool doubleheight)
605 {
606  int row = y;
607  x *= m_colWidth;
608  y *= m_rowHeight;
609 
610  int dx = (int)round((double)m_colWidth / 2) + 1;
611  int dy = (int)round((double)m_rowHeight / 3) + 1;
612  dy = (doubleheight) ? (2 * dy) : dy;
613 
614  if (code & 0x10)
615  DrawRect(row, QRect(x, y + 2*dy, dx, dy));
616  if (code & 0x40)
617  DrawRect(row, QRect(x + dx, y + 2*dy, dx, dy));
618  if (code & 0x01)
619  DrawRect(row, QRect(x, y, dx, dy));
620  if (code & 0x02)
621  DrawRect(row, QRect(x + dx, y, dx, dy));
622  if (code & 0x04)
623  DrawRect(row, QRect(x, y + dy, dx, dy));
624  if (code & 0x08)
625  DrawRect(row, QRect(x + dx, y + dy, dx, dy));
626 }
627 
629 {
632 
634  for (int i = 0; i < 40; ++i)
635  DrawBackground(i, 0);
636 
637  DrawCharacter(1, 0, 'P', false);
638  DrawCharacter(2, 0, m_teletextReader->GetPageInput(0), false);
639  DrawCharacter(3, 0, m_teletextReader->GetPageInput(1), false);
640  DrawCharacter(4, 0, m_teletextReader->GetPageInput(2), false);
641 
642  const TeletextSubPage *ttpage = m_teletextReader->FindSubPage();
643 
644  if (!ttpage)
645  {
646  QString str = QObject::tr("Page Not Available",
647  "Requested Teletext page not available");
648  for (int i = 0; (i < 30) && i < str.length(); i++)
649  DrawCharacter(i+10, 0, str[i], false);
650 
651  return;
652  }
653 
654  QString str = m_teletextReader->GetPage();
655  if (str.isEmpty())
656  return;
657 
659  for (int x = 0; x < 11; x++)
660  {
663  else
665 
666  DrawBackground(x * 3 + 7, 0);
667 
668  if (str[x * 3] == '*')
669  {
670  str[x * 3] = ' ';
672  }
673 
674  DrawBackground(x * 3 + 8, 0);
675  DrawBackground(x * 3 + 9, 0);
676 
677  DrawCharacter(x * 3 + 7, 0, str[x * 3], false);
678  DrawCharacter(x * 3 + 8, 0, str[x * 3 + 1], false);
679  DrawCharacter(x * 3 + 9, 0, str[x * 3 + 2], false);
680  }
681 }
682 
684 {
685  static bool s_initialised = false;
686  //QString font = gCoreContext->GetSetting("DefaultSubtitleFont", "FreeMono");
687  if (s_initialised)
688  {
689  return true;
690 #if 0
691  if (gTTFont->face().family() == font)
692  return true;
693  delete gTTFont;
694 #endif // 0
695  }
696 
697  auto *mythfont = new MythFontProperties();
698  QString font = SubtitleScreen::GetTeletextFontName();
699  if (mythfont)
700  {
701  QFont newfont(font);
702  mythfont->SetFace(newfont);
703  gTTFont = mythfont;
704  }
705  else
706  return false;
707 
709 
710  s_initialised = true;
711  LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("Loaded main subtitle font '%1'")
712  .arg(font));
713  return true;
714 }
QColor color(void) const
void DrawRect(int row, const QRect)
bool IsTransparent(void) const
bool KeyPress(const QString &key)
static const int kTeletextColumns
virtual MythPainter * GetOSDPainter(void)
Definition: mythvideoout.h:125
void SetPage(int page, int subpage)
static QColor ttcolortoqcolor(int ttcolor)
#define round(x)
Definition: mythplayer.cpp:65
void SetRedraw(void)
Definition: mythuitype.cpp:295
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:55
bool IsSubtitle(void) const
void SetHeaderChanged(bool changed)
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
static void SetForegroundColor(int color)
TeletextScreen(MythPlayer *player, const char *name, int fontStretch)
bool RevealHidden(void) const
void SetDisplaying(bool display)
virtual ~TeletextScreen()
int GetPageInput(uint num) const
void SetColor(const QColor &color)
void DeleteAllChildren(void)
Delete all child widgets.
Definition: mythuitype.cpp:204
uint8_t data[25][40]
page data
void OptimiseDisplayedArea(void)
static const int kTeletextRows
void SetShowHeader(bool show)
static QChar cvt_char(char ch, int lang)
virtual TeletextReader * GetTeletextReader(uint=0)
Definition: mythplayer.h:301
int floflink[6]
FastText links (FLOF)
QRect GetSafeRect(void)
Returns a QRect describing an area of the screen on which it is 'safe' to render the On Screen Displa...
The base class on which all widgets and screens are based.
Definition: mythuitype.h:63
TeletextSubPage * FindSubPage(void)
int flags
misc flags
QFont face(void) const
static MythFontProperties * gTTFont
MythVideoOutput * GetVideoOutput(void)
Definition: mythplayer.h:252
QString GetPage(void)
void Pulse(void) override
Pulse is called 70 times a second to trigger a single frame of an animation.
virtual MythRect GetArea(void) const
If the object has a minimum area defined, return it, other wise return the default area.
Definition: mythuitype.cpp:866
void SetBackgroundColor(int color)
QHash< int, QImage * > m_rowImages
static int GetTeletextBackgroundAlpha(void)
void DrawLine(const uint8_t *page, uint row, int lang)
bool subtitle
page is subtitle page
uint8_t * GetHeader(void)
static const QColor kColorRed
MythPlayer * m_player
#define TP_SUBTITLE
Wrapper around QRect allowing us to handle percentage and other relative values for areas in mythui.
Definition: mythrect.h:17
static QString GetTeletextFontName(void)
bool PageChanged(void) const
static int gTTBackgroundAlpha
unsigned int uint
Definition: compat.h:140
void SetPage(int page, int subpage)
static const QColor kColorCyan
void SetPageChanged(bool changed)
void DrawStatus(void)
void SetIsSubtitle(bool sub)
#define TP_SUPPRESS_HEADER
static bool InitialiseFont(void)
static const QColor kColorWhite
QImage * GetRowImage(int row, QRect &rect)
void SetSubPage(int subpage)
void ClearScreen(void)
virtual void SetArea(const MythRect &rect)
Definition: mythuitype.cpp:591
bool Create(void) override
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
#define TP_NEWSFLASH
static const QColor kColorYellow
static const QColor kColorMagenta
static const QColor kColorBlue
const unsigned char lang_chars[][16]
Definition: vbilut.cpp:4
static QString TTColorToString(int ttcolor)
void DrawBackground(int x, int y)
int subpagenum
the wanted subpage
static const QColor kColorGreen
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
#define LOC
Screen in which all other widgets are contained and rendered.
void Assign(const QImage &img)
Definition: mythimage.cpp:80
bool KeyPress(const QString &key)
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
TeletextReader * m_teletextReader
QList< MythUIType * > m_ChildrenList
Definition: mythuitype.h:228
int lang
language code
static const QColor kColorBlack
void DrawHeader(const uint8_t *page, int lang)
void DrawMosaic(int x, int y, int code, bool doubleheight)
void DrawCharacter(int x, int y, QChar ch, bool doubleheight=false)