Render the page with QImage instead of QPixmap
This commit is contained in:
@@ -105,11 +105,11 @@ void TeletextWidget::paintEvent(QPaintEvent *event)
|
|||||||
QPainter widgetPainter(this);
|
QPainter widgetPainter(this);
|
||||||
|
|
||||||
m_pageRender.renderPage();
|
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())
|
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())
|
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)
|
void TeletextWidget::updateFlashTimer(int newFlashTimer)
|
||||||
|
|||||||
247
render.cpp
247
render.cpp
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QBitmap>
|
#include <QBitmap>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QImage>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
@@ -28,27 +30,31 @@
|
|||||||
int TeletextFontBitmap::s_instances = 0;
|
int TeletextFontBitmap::s_instances = 0;
|
||||||
|
|
||||||
QBitmap *TeletextFontBitmap::s_fontBitmap = nullptr;
|
QBitmap *TeletextFontBitmap::s_fontBitmap = nullptr;
|
||||||
|
QImage *TeletextFontBitmap::s_fontImage = nullptr;
|
||||||
|
|
||||||
TeletextFontBitmap::TeletextFontBitmap()
|
TeletextFontBitmap::TeletextFontBitmap()
|
||||||
{
|
{
|
||||||
if (s_instances == 0)
|
if (s_instances == 0) {
|
||||||
s_fontBitmap = new QBitmap(":/images/teletextfont.png");
|
s_fontBitmap = new QBitmap(":/images/teletextfont.png");
|
||||||
|
s_fontImage = new QImage(s_fontBitmap->toImage());
|
||||||
|
}
|
||||||
s_instances++;
|
s_instances++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TeletextFontBitmap::~TeletextFontBitmap()
|
TeletextFontBitmap::~TeletextFontBitmap()
|
||||||
{
|
{
|
||||||
s_instances--;
|
s_instances--;
|
||||||
if (s_instances == 0)
|
if (s_instances == 0) {
|
||||||
|
delete s_fontImage;
|
||||||
delete s_fontBitmap;
|
delete s_fontBitmap;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TeletextPageRender::TeletextPageRender()
|
TeletextPageRender::TeletextPageRender()
|
||||||
{
|
{
|
||||||
for (int i=0; i<6; i++)
|
for (int i=0; i<6; i++)
|
||||||
m_pagePixmap[i] = new QPixmap(864, 250);
|
m_pageImage[i] = new QImage(864, 250, QImage::Format_ARGB32_Premultiplied);
|
||||||
m_pagePixmap[0]->fill(Qt::transparent);
|
|
||||||
|
|
||||||
m_reveal = false;
|
m_reveal = false;
|
||||||
m_mix = false;
|
m_mix = false;
|
||||||
@@ -65,7 +71,7 @@ TeletextPageRender::TeletextPageRender()
|
|||||||
TeletextPageRender::~TeletextPageRender()
|
TeletextPageRender::~TeletextPageRender()
|
||||||
{
|
{
|
||||||
for (int i=0; i<6; i++)
|
for (int i=0; i<6; i++)
|
||||||
delete m_pagePixmap[i];
|
delete m_pageImage[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextPageRender::setDecoder(TeletextPageDecode *decoder)
|
void TeletextPageRender::setDecoder(TeletextPageDecode *decoder)
|
||||||
@@ -73,180 +79,146 @@ void TeletextPageRender::setDecoder(TeletextPageDecode *decoder)
|
|||||||
m_decoder = 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) {
|
switch (characterFragment) {
|
||||||
case TeletextPageDecode::NormalSize:
|
case TeletextPageDecode::NormalSize:
|
||||||
pixmapPainter.drawPixmap(c*12, r*10, bitmap);
|
painter.drawImage(c*12, r*10, image);
|
||||||
break;
|
break;
|
||||||
case TeletextPageDecode::DoubleHeightTopHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleHeightBottomHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleWidthLeftHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleWidthRightHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeTopLeftQuarter:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeTopRightQuarter:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeBottomLeftQuarter:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeBottomRightQuarter:
|
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;
|
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) {
|
switch (characterFragment) {
|
||||||
case TeletextPageDecode::NormalSize:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleHeightTopHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleHeightBottomHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleWidthLeftHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleWidthRightHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeTopLeftQuarter:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeTopRightQuarter:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeBottomLeftQuarter:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleSizeBottomRightQuarter:
|
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;
|
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;
|
const bool dontUnderline = characterCode == 0x00;
|
||||||
if (dontUnderline)
|
if (dontUnderline)
|
||||||
characterCode = 0x20;
|
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)
|
if (characterCode == 0x20 && characterSet < 25 && characterDiacritical == 0)
|
||||||
return;
|
painter.fillRect(c*12, r*10, 12, 10, m_backgroundQColor);
|
||||||
|
|
||||||
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)
|
|
||||||
pixmapPainter.fillRect(c*12, r*10, 12, 10, pixmapPainter.background().color());
|
|
||||||
else if (characterCode == 0x7f && characterSet == 24)
|
else if (characterCode == 0x7f && characterSet == 24)
|
||||||
pixmapPainter.fillRect(c*12, r*10, 12, 10, pixmapPainter.pen().color());
|
painter.fillRect(c*12, r*10, 12, 10, m_foregroundQColor);
|
||||||
else if ((m_decoder->cellBold(r, c) || m_decoder->cellItalic(r, c)) && characterSet < 24)
|
else if ((m_decoder->cellBold(r, c) || m_decoder->cellItalic(r, c)) && characterSet < 24)
|
||||||
drawBoldOrItalicCharacter(pixmapPainter, r, c, characterCode, characterSet, characterFragment);
|
drawBoldOrItalicCharacter(painter, r, c, characterCode, characterSet, characterFragment);
|
||||||
else
|
else {
|
||||||
drawFromFontBitmap(pixmapPainter, r, c, characterCode, characterSet, characterFragment);
|
m_fontBitmap.image()->setColorTable(QVector<QRgb>{m_backgroundQColor.rgba(), m_foregroundQColor.rgba()});
|
||||||
|
drawFromFontBitmap(painter, 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) {
|
switch (characterFragment) {
|
||||||
case TeletextPageDecode::NormalSize:
|
case TeletextPageDecode::NormalSize:
|
||||||
case TeletextPageDecode::DoubleWidthLeftHalf:
|
case TeletextPageDecode::DoubleWidthLeftHalf:
|
||||||
case TeletextPageDecode::DoubleWidthRightHalf:
|
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;
|
break;
|
||||||
case TeletextPageDecode::DoubleHeightBottomHalf:
|
case TeletextPageDecode::DoubleHeightBottomHalf:
|
||||||
case TeletextPageDecode::DoubleSizeBottomLeftQuarter:
|
case TeletextPageDecode::DoubleSizeBottomLeftQuarter:
|
||||||
case TeletextPageDecode::DoubleSizeBottomRightQuarter:
|
case TeletextPageDecode::DoubleSizeBottomRightQuarter:
|
||||||
pixmapPainter.drawRect(c*12, r*10+8, 11, 1);
|
painter.drawRect(c*12, r*10+8, 11, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (characterDiacritical != 0) {
|
if (characterDiacritical != 0) {
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
pixmapPainter.setBackgroundMode(Qt::TransparentMode);
|
m_fontBitmap.image()->setColorTable(QVector<QRgb>{0x00000000, m_foregroundQColor.rgba()});
|
||||||
drawFromFontBitmap(pixmapPainter, r, c, characterDiacritical+64, 7, characterFragment);
|
drawFromFontBitmap(painter, r, c, characterDiacritical+64, 7, characterFragment);
|
||||||
pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pixmapPainter.compositionMode() != QPainter::CompositionMode_SourceOver)
|
inline void TeletextPageRender::drawBoldOrItalicCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment)
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void TeletextPageRender::drawBoldOrItalicCharacter(QPainter &pixmapPainter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment)
|
|
||||||
{
|
{
|
||||||
QBitmap bitmap = QBitmap(12, 10);
|
QImage styledImage = QImage(12, 10, QImage::Format_Mono);
|
||||||
QPainter bitmapPainter;
|
QPainter styledPainter;
|
||||||
|
|
||||||
|
m_fontBitmap.image()->setColorTable(QVector<QRgb>{m_backgroundQColor.rgba(), m_foregroundQColor.rgba()});
|
||||||
|
styledImage.setColorTable(QVector<QRgb>{m_backgroundQColor.rgba(), m_foregroundQColor.rgba()});
|
||||||
|
|
||||||
// TODO italic glyph-making is VERY slow!
|
|
||||||
if (m_decoder->cellItalic(r, c)) {
|
if (m_decoder->cellItalic(r, c)) {
|
||||||
bitmap.clear();
|
styledImage.fill(0);
|
||||||
|
|
||||||
bitmapPainter.begin(&bitmap);
|
styledPainter.begin(&styledImage);
|
||||||
bitmapPainter.setBackgroundMode(Qt::OpaqueMode);
|
styledPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
bitmapPainter.drawPixmap(1, 0, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10, 11, 3);
|
styledPainter.drawImage(1, 0, *m_fontBitmap.image(), (characterCode-32)*12, characterSet*10, 11, 3);
|
||||||
bitmapPainter.drawPixmap(0, 3, *m_fontBitmap.rawBitmap(), (characterCode-32)*12, characterSet*10+3, 12, 3);
|
styledPainter.drawImage(0, 3, *m_fontBitmap.image(), (characterCode-32)*12, characterSet*10+3, 12, 3);
|
||||||
bitmapPainter.drawPixmap(0, 6, *m_fontBitmap.rawBitmap(), (characterCode-32)*12+1, characterSet*10+6, 11, 4);
|
styledPainter.drawImage(0, 6, *m_fontBitmap.image(), (characterCode-32)*12+1, characterSet*10+6, 11, 4);
|
||||||
bitmapPainter.end();
|
styledPainter.end();
|
||||||
} else
|
} 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)) {
|
if (m_decoder->cellBold(r, c)) {
|
||||||
QBitmap boldeningBitmap;
|
QImage boldeningImage;
|
||||||
|
|
||||||
boldeningBitmap = bitmap.copy();
|
boldeningImage = styledImage.copy();
|
||||||
bitmapPainter.begin(&bitmap);
|
styledPainter.begin(&styledImage);
|
||||||
// No idea why we need this setPen workaround when character is made italic first?!
|
styledPainter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
if (!m_decoder->cellItalic(r, c))
|
boldeningImage.setColorTable(QVector<QRgb>{0x00000000, m_foregroundQColor.rgba()});
|
||||||
bitmapPainter.setPen(Qt::color0);
|
styledPainter.drawImage(1, 0, boldeningImage);
|
||||||
bitmapPainter.drawPixmap(1, 0, boldeningBitmap);
|
styledPainter.end();
|
||||||
bitmapPainter.end();
|
|
||||||
}
|
}
|
||||||
drawFromBitmap(pixmapPainter, r, c, bitmap, characterFragment);
|
drawFromBitmap(painter, r, c, styledImage, characterFragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TeletextPageRender::renderPage(bool force)
|
void TeletextPageRender::renderPage(bool force)
|
||||||
@@ -257,12 +229,12 @@ void TeletextPageRender::renderPage(bool force)
|
|||||||
|
|
||||||
void TeletextPageRender::renderRow(int r, int ph, bool force)
|
void TeletextPageRender::renderRow(int r, int ph, bool force)
|
||||||
{
|
{
|
||||||
QPainter pixmapPainter;
|
QPainter painter;
|
||||||
int flashingRow = 0;
|
int flashingRow = 0;
|
||||||
bool rowRefreshed = false;
|
bool rowRefreshed = false;
|
||||||
|
|
||||||
pixmapPainter.begin(m_pagePixmap[ph]);
|
painter.begin(m_pageImage[ph]);
|
||||||
pixmapPainter.setBackgroundMode(Qt::OpaqueMode);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
|
||||||
for (int c=0; c<72; c++) {
|
for (int c=0; c<72; c++) {
|
||||||
bool controlCodeChanged = false;
|
bool controlCodeChanged = false;
|
||||||
@@ -304,7 +276,7 @@ void TeletextPageRender::renderRow(int r, int ph, bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_decoder->cellFlashMode(r, c) == 0)
|
if (m_decoder->cellFlashMode(r, c) == 0)
|
||||||
pixmapPainter.setPen(m_decoder->cellForegroundQColor(r, c));
|
m_foregroundQColor = m_decoder->cellForegroundQColor(r, c);
|
||||||
else {
|
else {
|
||||||
// Flashing cell, decide if phase in this cycle is on or off
|
// Flashing cell, decide if phase in this cycle is on or off
|
||||||
bool phaseOn;
|
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 flashing to adjacent CLUT select the appropriate foreground colour
|
||||||
if (m_decoder->cellFlashMode(r, c) == 3 && !phaseOn)
|
if (m_decoder->cellFlashMode(r, c) == 3 && !phaseOn)
|
||||||
pixmapPainter.setPen(m_decoder->cellFlashForegroundQColor(r, c));
|
m_foregroundQColor = m_decoder->cellFlashForegroundQColor(r, c);
|
||||||
else
|
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 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) {
|
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))
|
if (!m_mix || m_decoder->cellBoxed(r, c))
|
||||||
pixmapPainter.setBackground(m_decoder->cellBackgroundQColor(r, c));
|
m_backgroundQColor = m_decoder->cellBackgroundQColor(r, c);
|
||||||
else
|
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) {
|
if (m_showControlCodes && c < 40 && m_decoder->teletextPage()->character(r, c) < 0x20) {
|
||||||
pixmapPainter.setBackground(QColor(0, 0, 0, 128));
|
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
pixmapPainter.setPen(QColor(255, 255, 255, 224));
|
m_fontBitmap.image()->setColorTable(QVector<QRgb>{0x7f000000, 0xe0ffffff});
|
||||||
pixmapPainter.drawPixmap(c*12, r*10, *m_fontBitmap.rawBitmap(), (m_decoder->teletextPage()->character(r, c)+32)*12, 250, 12, 10);
|
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)
|
if (ph != 0)
|
||||||
return;
|
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
|
// copy this rendered line into the other flash pixmap buffers and then re-render
|
||||||
// the flashing cells in those buffers
|
// the flashing cells in those buffers
|
||||||
if (rowRefreshed && m_flashBuffersHz > 0) {
|
if (rowRefreshed && m_flashBuffersHz > 0) {
|
||||||
pixmapPainter.begin(m_pagePixmap[3]);
|
painter.begin(m_pageImage[3]);
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[0], 0, r*10, 864, 10);
|
painter.drawImage(0, r*10, *m_pageImage[0], 0, r*10, 864, 10);
|
||||||
pixmapPainter.end();
|
painter.end();
|
||||||
|
|
||||||
renderRow(r, 3);
|
renderRow(r, 3);
|
||||||
|
|
||||||
if (m_flashBuffersHz == 2) {
|
if (m_flashBuffersHz == 2) {
|
||||||
pixmapPainter.begin(m_pagePixmap[1]);
|
painter.begin(m_pageImage[1]);
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[0], 0, r*10, 864, 10);
|
painter.drawImage(0, r*10, *m_pageImage[0], 0, r*10, 864, 10);
|
||||||
pixmapPainter.end();
|
painter.end();
|
||||||
pixmapPainter.begin(m_pagePixmap[2]);
|
painter.begin(m_pageImage[2]);
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[0], 0, r*10, 864, 10);
|
painter.drawImage(0, r*10, *m_pageImage[0], 0, r*10, 864, 10);
|
||||||
pixmapPainter.end();
|
painter.end();
|
||||||
pixmapPainter.begin(m_pagePixmap[4]);
|
painter.begin(m_pageImage[4]);
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[3], 0, r*10, 864, 10);
|
painter.drawImage(0, r*10, *m_pageImage[3], 0, r*10, 864, 10);
|
||||||
pixmapPainter.end();
|
painter.end();
|
||||||
pixmapPainter.begin(m_pagePixmap[5]);
|
painter.begin(m_pageImage[5]);
|
||||||
pixmapPainter.setCompositionMode(QPainter::CompositionMode_Source);
|
painter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
pixmapPainter.drawPixmap(0, r*10, *m_pagePixmap[3], 0, r*10, 864, 10);
|
painter.drawImage(0, r*10, *m_pageImage[3], 0, r*10, 864, 10);
|
||||||
pixmapPainter.end();
|
painter.end();
|
||||||
|
|
||||||
renderRow(r, 1);
|
renderRow(r, 1);
|
||||||
renderRow(r, 2);
|
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
|
// If we get here, new flash Hz for this row is higher than the entire flash Hz
|
||||||
// so prepare the pixmap flash buffers
|
// so prepare the pixmap flash buffers
|
||||||
if (m_flashBuffersHz == 0)
|
if (m_flashBuffersHz == 0)
|
||||||
*m_pagePixmap[3] = m_pagePixmap[0]->copy();
|
*m_pageImage[3] = m_pageImage[0]->copy();
|
||||||
if (rowFlashHz == 2) {
|
if (rowFlashHz == 2) {
|
||||||
*m_pagePixmap[1] = m_pagePixmap[0]->copy();
|
*m_pageImage[1] = m_pageImage[0]->copy();
|
||||||
*m_pagePixmap[2] = m_pagePixmap[0]->copy();
|
*m_pageImage[2] = m_pageImage[0]->copy();
|
||||||
*m_pagePixmap[4] = m_pagePixmap[3]->copy();
|
*m_pageImage[4] = m_pageImage[3]->copy();
|
||||||
*m_pagePixmap[5] = m_pagePixmap[3]->copy();
|
*m_pageImage[5] = m_pageImage[3]->copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_flashBuffersHz = rowFlashHz;
|
m_flashBuffersHz = rowFlashHz;
|
||||||
|
|||||||
21
render.h
21
render.h
@@ -21,6 +21,8 @@
|
|||||||
#define RENDER_H
|
#define RENDER_H
|
||||||
|
|
||||||
#include <QBitmap>
|
#include <QBitmap>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QImage>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
|
|
||||||
#include "decode.h"
|
#include "decode.h"
|
||||||
@@ -32,10 +34,12 @@ public:
|
|||||||
~TeletextFontBitmap();
|
~TeletextFontBitmap();
|
||||||
|
|
||||||
QBitmap *rawBitmap() const { return s_fontBitmap; }
|
QBitmap *rawBitmap() const { return s_fontBitmap; }
|
||||||
|
QImage *image() const { return s_fontImage; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int s_instances;
|
static int s_instances;
|
||||||
static QBitmap* s_fontBitmap;
|
static QBitmap* s_fontBitmap;
|
||||||
|
static QImage* s_fontImage;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TeletextPageRender : public QObject
|
class TeletextPageRender : public QObject
|
||||||
@@ -46,7 +50,7 @@ public:
|
|||||||
TeletextPageRender();
|
TeletextPageRender();
|
||||||
~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; };
|
bool mix() const { return m_mix; };
|
||||||
void setDecoder(TeletextPageDecode *decoder);
|
void setDecoder(TeletextPageDecode *decoder);
|
||||||
void renderPage(bool force=false);
|
void renderPage(bool force=false);
|
||||||
@@ -63,20 +67,21 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
TeletextFontBitmap m_fontBitmap;
|
TeletextFontBitmap m_fontBitmap;
|
||||||
QPixmap* m_pagePixmap[6];
|
QImage* m_pageImage[6];
|
||||||
unsigned char m_controlCodeCache[25][40];
|
unsigned char m_controlCodeCache[25][40];
|
||||||
bool m_reveal, m_mix, m_showControlCodes;
|
bool m_reveal, m_mix, m_showControlCodes;
|
||||||
int m_flashBuffersHz;
|
int m_flashBuffersHz;
|
||||||
int m_flashingRow[25];
|
int m_flashingRow[25];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void drawFromBitmap(QPainter &, int, int, const QBitmap, TeletextPageDecode::CharacterFragment);
|
inline void drawFromBitmap(QPainter &, int, int, const QImage, TeletextPageDecode::CharacterFragment);
|
||||||
inline void drawFromFontBitmap(QPainter &, int, int, unsigned char, int, TeletextPageDecode::CharacterFragment);
|
inline void drawFromFontBitmap(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment);
|
||||||
inline void drawCharacter(QPainter &, int, int, unsigned char, int, int, TeletextPageDecode::CharacterFragment);
|
inline void drawCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, int characterDiacritical, TeletextPageDecode::CharacterFragment characterFragment);
|
||||||
inline void drawBoldOrItalicCharacter(QPainter &, int, int, unsigned char, int, TeletextPageDecode::CharacterFragment);
|
inline void drawBoldOrItalicCharacter(QPainter &painter, int r, int c, unsigned char characterCode, int characterSet, TeletextPageDecode::CharacterFragment characterFragment);
|
||||||
void renderRow(int, int, bool force=false);
|
void renderRow(int r, int ph, bool force=false);
|
||||||
void setRowFlashStatus(int, int);
|
void setRowFlashStatus(int r, int rowFlashHz);
|
||||||
|
|
||||||
|
QColor m_foregroundQColor, m_backgroundQColor;
|
||||||
TeletextPageDecode *m_decoder;
|
TeletextPageDecode *m_decoder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user