diff --git a/mainwidget.cpp b/mainwidget.cpp index fb8e3f3..e6194df 100644 --- a/mainwidget.cpp +++ b/mainwidget.cpp @@ -105,11 +105,11 @@ void TeletextWidget::paintEvent(QPaintEvent *event) QPainter widgetPainter(this); m_pageRender.renderPage(); - widgetPainter.drawPixmap(m_pageDecode.leftSidePanelColumns()*12, 0, *m_pageRender.pagePixmap(m_flashPhase), 0, 0, 480, 250); + widgetPainter.drawImage(m_pageDecode.leftSidePanelColumns()*12, 0, *m_pageRender.image(m_flashPhase), 0, 0, 480, 250); if (m_pageDecode.leftSidePanelColumns()) - widgetPainter.drawPixmap(0, 0, *m_pageRender.pagePixmap(m_flashPhase), 864-m_pageDecode.leftSidePanelColumns()*12, 0, m_pageDecode.leftSidePanelColumns()*12, 250); + widgetPainter.drawImage(0, 0, *m_pageRender.image(m_flashPhase), 864-m_pageDecode.leftSidePanelColumns()*12, 0, m_pageDecode.leftSidePanelColumns()*12, 250); if (m_pageDecode.rightSidePanelColumns()) - widgetPainter.drawPixmap(480+m_pageDecode.leftSidePanelColumns()*12, 0, *m_pageRender.pagePixmap(m_flashPhase), 480, 0, m_pageDecode.rightSidePanelColumns()*12, 250); + widgetPainter.drawImage(480+m_pageDecode.leftSidePanelColumns()*12, 0, *m_pageRender.image(m_flashPhase), 480, 0, m_pageDecode.rightSidePanelColumns()*12, 250); } void TeletextWidget::updateFlashTimer(int newFlashTimer) diff --git a/render.cpp b/render.cpp index bc720d9..2ecbe17 100644 --- a/render.cpp +++ b/render.cpp @@ -18,6 +18,8 @@ */ #include +#include +#include #include #include @@ -28,27 +30,31 @@ int TeletextFontBitmap::s_instances = 0; QBitmap *TeletextFontBitmap::s_fontBitmap = nullptr; +QImage *TeletextFontBitmap::s_fontImage = nullptr; TeletextFontBitmap::TeletextFontBitmap() { - if (s_instances == 0) + if (s_instances == 0) { s_fontBitmap = new QBitmap(":/images/teletextfont.png"); + s_fontImage = new QImage(s_fontBitmap->toImage()); + } s_instances++; } TeletextFontBitmap::~TeletextFontBitmap() { s_instances--; - if (s_instances == 0) + if (s_instances == 0) { + delete s_fontImage; delete s_fontBitmap; + } } TeletextPageRender::TeletextPageRender() { for (int i=0; i<6; i++) - m_pagePixmap[i] = new QPixmap(864, 250); - m_pagePixmap[0]->fill(Qt::transparent); + m_pageImage[i] = new QImage(864, 250, QImage::Format_ARGB32_Premultiplied); m_reveal = false; m_mix = false; @@ -65,7 +71,7 @@ TeletextPageRender::TeletextPageRender() TeletextPageRender::~TeletextPageRender() { for (int i=0; i<6; i++) - delete m_pagePixmap[i]; + delete m_pageImage[i]; } void TeletextPageRender::setDecoder(TeletextPageDecode *decoder) @@ -73,180 +79,146 @@ void TeletextPageRender::setDecoder(TeletextPageDecode *decoder) m_decoder = decoder; } -inline void TeletextPageRender::drawFromBitmap(QPainter &pixmapPainter, int r, int c, const QBitmap bitmap, TeletextPageDecode::CharacterFragment characterFragment) +inline void TeletextPageRender::drawFromBitmap(QPainter &painter, int r, int c, const QImage image, TeletextPageDecode::CharacterFragment characterFragment) { switch (characterFragment) { case TeletextPageDecode::NormalSize: - pixmapPainter.drawPixmap(c*12, r*10, bitmap); + painter.drawImage(c*12, r*10, image); break; case TeletextPageDecode::DoubleHeightTopHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 0, 0, 12, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(0, 0, 12, 5)); break; case TeletextPageDecode::DoubleHeightBottomHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 0, 5, 12, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(0, 5, 12, 5)); break; case TeletextPageDecode::DoubleWidthLeftHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 0, 0, 6, 10); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(0, 0, 6, 10)); break; case TeletextPageDecode::DoubleWidthRightHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 6, 0, 6, 10); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(6, 0, 6, 10)); break; case TeletextPageDecode::DoubleSizeTopLeftQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 0, 0, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(0, 0, 6, 5)); break; case TeletextPageDecode::DoubleSizeTopRightQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 6, 0, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(6, 0, 6, 5)); break; case TeletextPageDecode::DoubleSizeBottomLeftQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 0, 5, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(0, 5, 6, 5)); break; case TeletextPageDecode::DoubleSizeBottomRightQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, bitmap, 6, 5, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), image, QRect(6, 5, 6, 5)); break; } } -inline void TeletextPageRender::drawFromFontBitmap(QPainter &pixmapPainter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment) +inline void TeletextPageRender::drawFromFontBitmap(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment) { switch (characterFragment) { case TeletextPageDecode::NormalSize: - pixmapPainter.drawPixmap(c*12, r*10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10, 12, 10); + painter.drawImage(c*12, r*10, *m_fontBitmap.image(), (characterCode-32)*12, characterSet*10, 12, 10); break; case TeletextPageDecode::DoubleHeightTopHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10, 12, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12, characterSet*10, 12, 5)); break; case TeletextPageDecode::DoubleHeightBottomHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10+5, 12, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12, characterSet*10+5, 12, 5)); break; case TeletextPageDecode::DoubleWidthLeftHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10, 6, 10); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12, characterSet*10, 6, 10)); break; case TeletextPageDecode::DoubleWidthRightHalf: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12+6, characterSet*10, 6, 10); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12+6, characterSet*10, 6, 10)); break; case TeletextPageDecode::DoubleSizeTopLeftQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12, characterSet*10, 6, 5)); break; case TeletextPageDecode::DoubleSizeTopRightQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12+6, characterSet*10, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12+6, characterSet*10, 6, 5)); break; case TeletextPageDecode::DoubleSizeBottomLeftQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10+5, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12, characterSet*10+5, 6, 5)); break; case TeletextPageDecode::DoubleSizeBottomRightQuarter: - pixmapPainter.drawPixmap(c*12, r*10, 12, 10, *m_fontBitmap.rawBitmap(), (characterCode-32)*12+6, characterSet*10+5, 6, 5); + painter.drawImage(QRect(c*12, r*10, 12, 10), *m_fontBitmap.image(), QRect((characterCode-32)*12+6, characterSet*10+5, 6, 5)); break; } } -inline void TeletextPageRender::drawCharacter(QPainter &pixmapPainter, int r, int c, unsigned char characterCode, int characterSet, int characterDiacritical, TeletextPageDecode::CharacterFragment characterFragment) +inline void TeletextPageRender::drawCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, int characterDiacritical, TeletextPageDecode::CharacterFragment characterFragment) { const bool dontUnderline = characterCode == 0x00; if (dontUnderline) characterCode = 0x20; - // If either foreground or background is set to transparent - // tinker with the QPainter settings so we get the desired result - if (!pixmapPainter.background().isOpaque()) { - if (pixmapPainter.pen().color().alpha() == 0) { - // Transparent foreground and background - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Clear); - pixmapPainter.eraseRect(c*12, r*10, 12, 10); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); - - return; - } else - // Transparent background, opaque foreground - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - } else if (pixmapPainter.pen().color().alpha() == 0) { - // Transparent foreground, opaque background - // Deal with optimising G1 solid 7/F blocks and spaces now - // otherwise the same optimisations later on won't work with - // our tinkered QPainter settings - if (characterCode == 0x7f && characterSet == 24) { - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Clear); - pixmapPainter.eraseRect(c*12, r*10, 12, 10); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); - - return; - } - - pixmapPainter.fillRect(c*12, r*10, 12, 10, m_decoder->cellBackgroundQColor(r, c)); - - if (characterCode == 0x20 && characterSet < 25 && characterDiacritical == 0) - return; - - pixmapPainter.setBackground(QColor(0, 0, 0, 0)); - pixmapPainter.setPen(QColor(255, 255, 255, 255)); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_DestinationOut); + if (characterCode == 0x20 && characterSet < 25 && characterDiacritical == 0) + painter.fillRect(c*12, r*10, 12, 10, m_backgroundQColor); + else if (characterCode == 0x7f && characterSet == 24) + painter.fillRect(c*12, r*10, 12, 10, m_foregroundQColor); + else if ((m_decoder->cellBold(r, c) || m_decoder->cellItalic(r, c)) && characterSet < 24) + drawBoldOrItalicCharacter(painter, r, c, characterCode, characterSet, characterFragment); + else { + m_fontBitmap.image()->setColorTable(QVector{m_backgroundQColor.rgba(), m_foregroundQColor.rgba()}); + drawFromFontBitmap(painter, r, c, characterCode, characterSet, characterFragment); } - if (characterCode == 0x20 && characterSet < 25 && characterDiacritical == 0) - pixmapPainter.fillRect(c*12, r*10, 12, 10, pixmapPainter.background().color()); - else if (characterCode == 0x7f && characterSet == 24) - pixmapPainter.fillRect(c*12, r*10, 12, 10, pixmapPainter.pen().color()); - else if ((m_decoder->cellBold(r, c) || m_decoder->cellItalic(r, c)) && characterSet < 24) - drawBoldOrItalicCharacter(pixmapPainter, r, c, characterCode, characterSet, characterFragment); - else - drawFromFontBitmap(pixmapPainter, r, c, characterCode, characterSet, characterFragment); - - if (m_decoder->cellUnderlined(r, c) && !dontUnderline) + if (m_decoder->cellUnderlined(r, c) && !dontUnderline) { + painter.setPen(m_foregroundQColor); switch (characterFragment) { case TeletextPageDecode::NormalSize: case TeletextPageDecode::DoubleWidthLeftHalf: case TeletextPageDecode::DoubleWidthRightHalf: - pixmapPainter.drawLine(c*12, r*10+9, c*12+11, r*10+9); + painter.drawLine(c*12, r*10+9, c*12+11, r*10+9); break; case TeletextPageDecode::DoubleHeightBottomHalf: case TeletextPageDecode::DoubleSizeBottomLeftQuarter: case TeletextPageDecode::DoubleSizeBottomRightQuarter: - pixmapPainter.drawRect(c*12, r*10+8, 11, 1); + painter.drawRect(c*12, r*10+8, 11, 1); break; default: break; } + } if (characterDiacritical != 0) { - pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); - pixmapPainter.setBackgroundMode(Qt::TransparentMode); - drawFromFontBitmap(pixmapPainter, r, c, characterDiacritical+64, 7, characterFragment); - pixmapPainter.setBackgroundMode(Qt::OpaqueMode); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + m_fontBitmap.image()->setColorTable(QVector{0x00000000, m_foregroundQColor.rgba()}); + drawFromFontBitmap(painter, r, c, characterDiacritical+64, 7, characterFragment); + painter.setCompositionMode(QPainter::CompositionMode_Source); } - - if (pixmapPainter.compositionMode() != QPainter::CompositionMode_SourceOver) - pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); } -inline void TeletextPageRender::drawBoldOrItalicCharacter(QPainter &pixmapPainter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment) +inline void TeletextPageRender::drawBoldOrItalicCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment) { - QBitmap bitmap = QBitmap(12, 10); - QPainter bitmapPainter; + QImage styledImage = QImage(12, 10, QImage::Format_Mono); + QPainter styledPainter; + + m_fontBitmap.image()->setColorTable(QVector{m_backgroundQColor.rgba(), m_foregroundQColor.rgba()}); + styledImage.setColorTable(QVector{m_backgroundQColor.rgba(), m_foregroundQColor.rgba()}); - // TODO italic glyph-making is VERY slow! if (m_decoder->cellItalic(r, c)) { - bitmap.clear(); + styledImage.fill(0); - bitmapPainter.begin(&bitmap); - bitmapPainter.setBackgroundMode(Qt::OpaqueMode); - bitmapPainter.drawPixmap(1, 0, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10, 11, 3); - bitmapPainter.drawPixmap(0, 3, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10+3, 12, 3); - bitmapPainter.drawPixmap(0, 6, *m_fontBitmap.rawBitmap(), (characterCode-32)*12+1, characterSet*10+6, 11, 4); - bitmapPainter.end(); + styledPainter.begin(&styledImage); + styledPainter.setCompositionMode(QPainter::CompositionMode_Source); + styledPainter.drawImage(1, 0, *m_fontBitmap.image(), (characterCode-32)*12, characterSet*10, 11, 3); + styledPainter.drawImage(0, 3, *m_fontBitmap.image(), (characterCode-32)*12, characterSet*10+3, 12, 3); + styledPainter.drawImage(0, 6, *m_fontBitmap.image(), (characterCode-32)*12+1, characterSet*10+6, 11, 4); + styledPainter.end(); } else - bitmap = m_fontBitmap.rawBitmap()->copy((characterCode-32)*12, characterSet*10, 12, 10); + styledImage = m_fontBitmap.image()->copy((characterCode-32)*12, characterSet*10, 12, 10); if (m_decoder->cellBold(r, c)) { - QBitmap boldeningBitmap; + QImage boldeningImage; - boldeningBitmap = bitmap.copy(); - bitmapPainter.begin(&bitmap); - // No idea why we need this setPen workaround when character is made italic first?! - if (!m_decoder->cellItalic(r, c)) - bitmapPainter.setPen(Qt::color0); - bitmapPainter.drawPixmap(1, 0, boldeningBitmap); - bitmapPainter.end(); + boldeningImage = styledImage.copy(); + styledPainter.begin(&styledImage); + styledPainter.setCompositionMode(QPainter::CompositionMode_SourceOver); + boldeningImage.setColorTable(QVector{0x00000000, m_foregroundQColor.rgba()}); + styledPainter.drawImage(1, 0, boldeningImage); + styledPainter.end(); } - drawFromBitmap(pixmapPainter, r, c, bitmap, characterFragment); + drawFromBitmap(painter, r, c, styledImage, characterFragment); } void TeletextPageRender::renderPage(bool force) @@ -257,12 +229,12 @@ void TeletextPageRender::renderPage(bool force) void TeletextPageRender::renderRow(int r, int ph, bool force) { - QPainter pixmapPainter; + QPainter painter; int flashingRow = 0; bool rowRefreshed = false; - pixmapPainter.begin(m_pagePixmap[ph]); - pixmapPainter.setBackgroundMode(Qt::OpaqueMode); + painter.begin(m_pageImage[ph]); + painter.setCompositionMode(QPainter::CompositionMode_Source); for (int c=0; c<72; c++) { bool controlCodeChanged = false; @@ -304,7 +276,7 @@ void TeletextPageRender::renderRow(int r, int ph, bool force) } if (m_decoder->cellFlashMode(r, c) == 0) - pixmapPainter.setPen(m_decoder->cellForegroundQColor(r, c)); + m_foregroundQColor = m_decoder->cellForegroundQColor(r, c); else { // Flashing cell, decide if phase in this cycle is on or off bool phaseOn; @@ -316,9 +288,9 @@ void TeletextPageRender::renderRow(int r, int ph, bool force) // If flashing to adjacent CLUT select the appropriate foreground colour if (m_decoder->cellFlashMode(r, c) == 3 && !phaseOn) - pixmapPainter.setPen(m_decoder->cellFlashForegroundQColor(r, c)); + m_foregroundQColor = m_decoder->cellFlashForegroundQColor(r, c); else - pixmapPainter.setPen(m_decoder->cellForegroundQColor(r, c)); + m_foregroundQColor = m_decoder->cellForegroundQColor(r, c); // If flashing mode is Normal or Invert, draw a space instead of a character on phase if ((m_decoder->cellFlashMode(r, c) == 1 || m_decoder->cellFlashMode(r, c) == 2) && !phaseOn) { @@ -330,21 +302,22 @@ void TeletextPageRender::renderRow(int r, int ph, bool force) } if (!m_mix || m_decoder->cellBoxed(r, c)) - pixmapPainter.setBackground(m_decoder->cellBackgroundQColor(r, c)); + m_backgroundQColor = m_decoder->cellBackgroundQColor(r, c); else - pixmapPainter.setBackground(Qt::transparent); + m_backgroundQColor = Qt::transparent; - drawCharacter(pixmapPainter, r, c, characterCode, characterSet, characterDiacritical, m_decoder->cellCharacterFragment(r, c)); + drawCharacter(painter, r, c, characterCode, characterSet, characterDiacritical, m_decoder->cellCharacterFragment(r, c)); if (m_showControlCodes && c < 40 && m_decoder->teletextPage()->character(r, c) < 0x20) { - pixmapPainter.setBackground(QColor(0, 0, 0, 128)); - pixmapPainter.setPen(QColor(255, 255, 255, 224)); - pixmapPainter.drawPixmap(c*12, r*10, *m_fontBitmap.rawBitmap(), (m_decoder->teletextPage()->character(r, c)+32)*12, 250, 12, 10); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + m_fontBitmap.image()->setColorTable(QVector{0x7f000000, 0xe0ffffff}); + painter.drawImage(c*12, r*10, *m_fontBitmap.image(), (m_decoder->teletextPage()->character(r, c)+32)*12, 250, 12, 10); + painter.setCompositionMode(QPainter::CompositionMode_Source); } } } - pixmapPainter.end(); + painter.end(); if (ph != 0) return; @@ -361,30 +334,30 @@ void TeletextPageRender::renderRow(int r, int ph, bool force) // copy this rendered line into the other flash pixmap buffers and then re-render // the flashing cells in those buffers if (rowRefreshed && m_flashBuffersHz > 0) { - pixmapPainter.begin(m_pagePixmap[3]); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[0], 0, r*10, 864, 10); - pixmapPainter.end(); + painter.begin(m_pageImage[3]); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawImage(0, r*10, *m_pageImage[0], 0, r*10, 864, 10); + painter.end(); renderRow(r, 3); if (m_flashBuffersHz == 2) { - pixmapPainter.begin(m_pagePixmap[1]); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[0], 0, r*10, 864, 10); - pixmapPainter.end(); - pixmapPainter.begin(m_pagePixmap[2]); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[0], 0, r*10, 864, 10); - pixmapPainter.end(); - pixmapPainter.begin(m_pagePixmap[4]); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[3], 0, r*10, 864, 10); - pixmapPainter.end(); - pixmapPainter.begin(m_pagePixmap[5]); - pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source); - pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[3], 0, r*10, 864, 10); - pixmapPainter.end(); + painter.begin(m_pageImage[1]); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawImage(0, r*10, *m_pageImage[0], 0, r*10, 864, 10); + painter.end(); + painter.begin(m_pageImage[2]); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawImage(0, r*10, *m_pageImage[0], 0, r*10, 864, 10); + painter.end(); + painter.begin(m_pageImage[4]); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawImage(0, r*10, *m_pageImage[3], 0, r*10, 864, 10); + painter.end(); + painter.begin(m_pageImage[5]); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.drawImage(0, r*10, *m_pageImage[3], 0, r*10, 864, 10); + painter.end(); renderRow(r, 1); renderRow(r, 2); @@ -427,12 +400,12 @@ void TeletextPageRender::setRowFlashStatus(int r, int rowFlashHz) // If we get here, new flash Hz for this row is higher than the entire flash Hz // so prepare the pixmap flash buffers if (m_flashBuffersHz == 0) - *m_pagePixmap[3] = m_pagePixmap[0]->copy(); + *m_pageImage[3] = m_pageImage[0]->copy(); if (rowFlashHz == 2) { - *m_pagePixmap[1] = m_pagePixmap[0]->copy(); - *m_pagePixmap[2] = m_pagePixmap[0]->copy(); - *m_pagePixmap[4] = m_pagePixmap[3]->copy(); - *m_pagePixmap[5] = m_pagePixmap[3]->copy(); + *m_pageImage[1] = m_pageImage[0]->copy(); + *m_pageImage[2] = m_pageImage[0]->copy(); + *m_pageImage[4] = m_pageImage[3]->copy(); + *m_pageImage[5] = m_pageImage[3]->copy(); } m_flashBuffersHz = rowFlashHz; diff --git a/render.h b/render.h index 5f4c9c5..c0b949b 100644 --- a/render.h +++ b/render.h @@ -21,6 +21,8 @@ #define RENDER_H #include +#include +#include #include #include "decode.h" @@ -32,10 +34,12 @@ public: ~TeletextFontBitmap(); QBitmap *rawBitmap() const { return s_fontBitmap; } + QImage *image() const { return s_fontImage; } private: static int s_instances; static QBitmap* s_fontBitmap; + static QImage* s_fontImage; }; class TeletextPageRender : public QObject @@ -46,7 +50,7 @@ public: TeletextPageRender(); ~TeletextPageRender(); - QPixmap* pagePixmap(int i) const { return m_pagePixmap[i]; }; + QImage* image(int i) const { return m_pageImage[i]; }; bool mix() const { return m_mix; }; void setDecoder(TeletextPageDecode *decoder); void renderPage(bool force=false); @@ -63,20 +67,21 @@ signals: protected: TeletextFontBitmap m_fontBitmap; - QPixmap* m_pagePixmap[6]; + QImage* m_pageImage[6]; unsigned char m_controlCodeCache[25][40]; bool m_reveal, m_mix, m_showControlCodes; int m_flashBuffersHz; int m_flashingRow[25]; private: - inline void drawFromBitmap(QPainter &, int, int, const QBitmap, TeletextPageDecode::CharacterFragment); - inline void drawFromFontBitmap(QPainter &, int, int, unsigned char, int, TeletextPageDecode::CharacterFragment); - inline void drawCharacter(QPainter &, int, int, unsigned char, int, int, TeletextPageDecode::CharacterFragment); - inline void drawBoldOrItalicCharacter(QPainter &, int, int, unsigned char, int, TeletextPageDecode::CharacterFragment); - void renderRow(int, int, bool force=false); - void setRowFlashStatus(int, int); + inline void drawFromBitmap(QPainter &, int, int, const QImage, TeletextPageDecode::CharacterFragment); + inline void drawFromFontBitmap(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment); + inline void drawCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, int characterDiacritical, TeletextPageDecode::CharacterFragment characterFragment); + inline void drawBoldOrItalicCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment); + void renderRow(int r, int ph, bool force=false); + void setRowFlashStatus(int r, int rowFlashHz); + QColor m_foregroundQColor, m_backgroundQColor; TeletextPageDecode *m_decoder; };