From 426052f57359a9045974b788688cc2b05e2100b2 Mon Sep 17 00:00:00 2001 From: "G.K.MacGregor" Date: Tue, 12 Sep 2023 16:45:55 +0100 Subject: [PATCH] Port away from GNU case range extension Hopefully this should now compile with MSVC and other compilers --- decode.cpp | 70 ++++++++++++++++++++++++-------------- levelonepage.cpp | 26 ++++++++++---- x26dockwidget.cpp | 26 ++++++++++++-- x26model.cpp | 87 +++++++++++++++++++++++++++++++---------------- x26triplets.cpp | 45 ++++++++++++++++-------- 5 files changed, 176 insertions(+), 78 deletions(-) diff --git a/decode.cpp b/decode.cpp index 303c2cd..eb662cf 100644 --- a/decode.cpp +++ b/decode.cpp @@ -98,26 +98,6 @@ void TeletextPageDecode::Invocation::buildMap(int level) continue; switch (triplet.modeExt()) { - case 0x21: // G1 character - case 0x22: // G3 character at Level 1.5 - case 0x29: // G0 character - case 0x2b: // G3 character at Level 2.5 - case 0x2f: // G2 character - case 0x30 ... 0x3f: // G0 character with diacritical - m_characterMap.insert(qMakePair(targetRow, targetColumn), triplet); - // Store rightmost column in this row for Adaptive Object attribute tracking - // QMap stores one value per key, QMap::insert will replace the value if the key already exists - m_rightMostColumn.insert(targetRow, targetColumn); - break; - case 0x20: // Foreground colour - case 0x23: // Background colour - case 0x27: // Additional flash functions - case 0x28: // Modified G0 and G2 character set designation - case 0x2c: // Display attributes - case 0x2e: // Font style - m_attributeMap.insert(qMakePair(targetRow, targetColumn), triplet); - m_rightMostColumn.insert(targetRow, targetColumn); - break; case 0x00: // Full screen colour if ((triplet.data() & 0x60) != 0x00) break; @@ -133,6 +113,31 @@ void TeletextPageDecode::Invocation::buildMap(int level) if (targetRow == 0) m_fullRowCLUTMap.insert(targetRow, triplet); break; + case 0x20: // Foreground colour + case 0x23: // Background colour + case 0x27: // Additional flash functions + case 0x28: // Modified G0 and G2 character set designation + case 0x2c: // Display attributes + case 0x2e: // Font style + m_attributeMap.insert(qMakePair(targetRow, targetColumn), triplet); + // Store rightmost column in this row for Adaptive Object attribute tracking + // QMap stores one value per key, QMap::insert will replace the value if the key already exists + m_rightMostColumn.insert(targetRow, targetColumn); + break; + case 0x21: // G1 character + case 0x22: // G3 character at Level 1.5 + case 0x29: // G0 character + case 0x2b: // G3 character at Level 2.5 + case 0x2f: // G2 character + m_characterMap.insert(qMakePair(targetRow, targetColumn), triplet); + m_rightMostColumn.insert(targetRow, targetColumn); + break; + default: + if (triplet.modeExt() >= 0x30 && triplet.modeExt() <= 0x3f) { + // G0 character with diacritical + m_characterMap.insert(qMakePair(targetRow, targetColumn), triplet); + m_rightMostColumn.insert(targetRow, targetColumn); + } } } } @@ -322,9 +327,10 @@ TeletextPageDecode::textCharacter TeletextPageDecode::characterFromTriplets(cons case 0x2f: // G2 character result = { charCode, 2, 0 }; break; - case 0x30 ... 0x3f: // G0 character with diacritical - result = { charCode, 0, triplet.mode() & 0xf }; - break; + default: + if (triplet.modeExt() >= 0x30 && triplet.modeExt() <= 0x3f) + // G0 character with diacritical + result = { charCode, 0, triplet.mode() & 0xf }; } if (m_level == 1) @@ -945,7 +951,14 @@ void TeletextPageDecode::decodeRow(int r) // Level 1 set-after spacing attributes if (c < 40 && m_rowHeight[r] != BottomHalf) switch (m_levelOnePage->character(r, c)) { - case 0x00 ... 0x07: // Alphanumeric and foreground colour + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: // Alphanumeric and foreground colour level1Mosaics = false; level1ForegroundCLUT = m_levelOnePage->character(r, c); if (m_level >= 2) @@ -957,7 +970,14 @@ void TeletextPageDecode::decodeRow(int r) level1HoldMosaicCharacter = 0x20; level1HoldMosaicSeparated = false; break; - case 0x10 ... 0x17: // Mosaic and foreground colour + case 0x10: + case 0x11: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: // Mosaic and foreground colour level1Mosaics = true; level1ForegroundCLUT = m_levelOnePage->character(r, c) & 0x07; if (m_level >= 2) diff --git a/levelonepage.cpp b/levelonepage.cpp index 635c3fd..5eba60a 100644 --- a/levelonepage.cpp +++ b/levelonepage.cpp @@ -433,9 +433,12 @@ int LevelOnePage::levelRequired() const case 0x1f: // Termination case 0x22: // G3 character @ Level 1.5 case 0x2f: // G2 character - case 0x30 ... 0x3f: // G0 character with diacritical levelSeen = 1; break; + default: + if (m_enhancements.at(i).modeExt() >= 0x30 && m_enhancements.at(i).modeExt() <= 0x3f) + // G0 character with diacritical + levelSeen = 1; } if (levelSeen < 2) @@ -443,14 +446,23 @@ int LevelOnePage::levelRequired() const // Check for Level 2.5 triplets case 0x00: // Full screen colour case 0x01: // Full row colour - case 0x10 ... 0x13: // Origin Modifer and Object Invocation - case 0x15 ... 0x17: // Object Definition + case 0x10: // Origin Modifier + case 0x11: // Invoke Active Object + case 0x12: // Invoke Adaptive Object + case 0x13: // Invoke Passive Object + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object case 0x18: // DRCS Mode case 0x20: // Foreground colour case 0x21: // G1 character case 0x23: // Background colour - case 0x27 ... 0x29: // Flash functions, G0 and G2 charset designation, G0 character @ Level 2.5 - case 0x2b ... 0x2d: // G3 character @ Level 2.5, display attributes, DRCS character + case 0x27: // Flash functions + case 0x28: // G0 and G2 charset designation + case 0x29: // G0 character @ Level 2.5 + case 0x2b: // G3 character @ Level 2.5 + case 0x2c: // Display attributes + case 0x2d: // DRCS character levelSeen = 2; break; } @@ -458,7 +470,9 @@ int LevelOnePage::levelRequired() const if (levelSeen == 2) switch (m_enhancements.at(i).modeExt()) { // Check for triplets with "required at Level 3.5 only" parameters - case 0x15 ... 0x17: // Object Definition + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object if ((m_enhancements.at(i).address() & 0x18) == 0x10) return 3; break; diff --git a/x26dockwidget.cpp b/x26dockwidget.cpp index 7fda6d5..d1a2e76 100644 --- a/x26dockwidget.cpp +++ b/x26dockwidget.cpp @@ -748,7 +748,23 @@ void X26DockWidget::updateAllCookedTripletWidgets(const QModelIndex &index) case 0x22: // G3 character at Level 1.5 case 0x29: // G0 character case 0x2b: // G3 character at Level 2.5 - case 0x2f ... 0x3f: // G2 character, G0 character with diacritical + case 0x2f: // G2 character + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: // G0 character with diacritical m_characterCodeComboBox->blockSignals(true); if (modeExt == 0x21) m_characterListModel.setCharacterSet(24); @@ -788,8 +804,12 @@ void X26DockWidget::updateAllCookedTripletWidgets(const QModelIndex &index) m_displayAttributeUnderlineCheckBox->blockSignals(false); m_tripletParameterStackedLayout->setCurrentIndex(4); break; - case 0x11 ... 0x13: // Invoke object - case 0x15 ... 0x17: // Define object + case 0x11: // Invoke Active Object + case 0x12: // Invoke Adaptive Object + case 0x13: // Invoke Passive Object + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object if (index.model()->data(index.model()->index(index.row(), 1), Qt::UserRole).toInt() & 0x04) { // Define object m_objectSourceComboBox->setVisible(false); diff --git a/x26model.cpp b/x26model.cpp index 942b913..c2e5b1d 100644 --- a/x26model.cpp +++ b/x26model.cpp @@ -134,7 +134,9 @@ QVariant X26Model::data(const QModelIndex &index, int role) const case 0x10: // Origin Modifier // For Set Active Position and Origin Modifier, data is the column, so return blank return QVariant(); - case 0x11 ... 0x13: // Invoke object + case 0x11: // Invoke Active Object + case 0x12: // Invoke Adaptive Object + case 0x13: // Invoke Passive Object switch (triplet.address() & 0x18) { case 0x08: return QString("Local: d%1 t%2").arg((triplet.data() >> 4) | ((triplet.address() & 0x01) << 3)).arg(triplet.data() & 0x0f); @@ -152,7 +154,9 @@ QVariant X26Model::data(const QModelIndex &index, int role) const else result.append("1-9"); return result; - case 0x15 ... 0x17: // Define object + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object switch (triplet.address() & 0x18) { case 0x08: return "Local: L2.5 only"; @@ -212,7 +216,12 @@ QVariant X26Model::data(const QModelIndex &index, int role) const break; } break; - case 0x08 ... 0x0d: // PDC + case 0x08: // PDC country of origin & programme source + case 0x09: // PDC month & day + case 0x0a: // PDC cursor row & announced start hour + case 0x0b: // PDC cursor row & announced finish hour + case 0x0c: // PDC cursor row & local time offset + case 0x0d: // PDC series ID & series code return QString("0x%1").arg(triplet.data(), 2, 16, QChar('0')); case 0x20: // Foreground colour case 0x23: // Background colour @@ -223,7 +232,7 @@ QVariant X26Model::data(const QModelIndex &index, int role) const case 0x22: // G3 mosaic character at level 1.5 case 0x29: // G0 character case 0x2b: // G3 mosaic character at level >=2.5 - case 0x2f ... 0x3f: // G2 character or G0 diacritical mark + case 0x2f: // G2 character if (triplet.data() >= 0x20) return QString("0x%1").arg(triplet.data(), 2, 16); break; @@ -339,8 +348,13 @@ QVariant X26Model::data(const QModelIndex &index, int role) const return result; case 0x26: // PDC return QString("0x%1").arg(triplet.data(), 2, 16, QChar('0')); - default: // Reserved - return QString("Reserved 0x%1").arg(triplet.data(), 2, 16, QChar('0')); + default: + if (triplet.modeExt() >= 0x30 && triplet.modeExt() <= 0x3f && triplet.data() >= 0x20) + // G0 with diacritical + return QString("0x%1").arg(triplet.data(), 2, 16); + else + // Reserved + return QString("Reserved 0x%1").arg(triplet.data(), 2, 16, QChar('0')); } // Reserved mode or data return QString("Reserved 0x%1").arg(triplet.data(), 2, 16, QChar('0')); @@ -372,11 +386,11 @@ QVariant X26Model::data(const QModelIndex &index, int role) const if (triplet.data() >= 0x20) return m_fontBitmap.rawBitmap()->copy((triplet.data()-32)*12, m_parentMainWidget->pageDecode()->cellG2CharacterSet(triplet.activePositionRow(), triplet.activePositionColumn())*10, 12, 10); break; - case 0x29: // G0 character - case 0x30 ... 0x3f: // G0 diacritical mark - if (triplet.data() >= 0x20) - return m_fontBitmap.rawBitmap()->copy((triplet.data()-32)*12, m_parentMainWidget->pageDecode()->cellG0CharacterSet(triplet.activePositionRow(), triplet.activePositionColumn())*10, 12, 10); - break; + default: + if (triplet.modeExt() == 0x29 || (triplet.modeExt() >= 0x30 && triplet.modeExt() <= 0x3f)) + // G0 character or G0 diacritical mark + if (triplet.data() >= 0x20) + return m_fontBitmap.rawBitmap()->copy((triplet.data()-32)*12, m_parentMainWidget->pageDecode()->cellG0CharacterSet(triplet.activePositionRow(), triplet.activePositionColumn())*10, 12, 10); } if (role == Qt::EditRole && index.column() == 2) @@ -397,7 +411,9 @@ QVariant X26Model::data(const QModelIndex &index, int role) const if (role == Qt::UserRole+1) // Colour index return triplet.data() & 0x1f; break; - case 0x11 ... 0x13: // Invoke object + case 0x11: // Invoke Active Object + case 0x12: // Invoke Adaptive Object + case 0x13: // Invoke Passive Object switch (role) { case Qt::UserRole+1: // Object source: Local, POP or GPOP return ((triplet.address() & 0x18) >> 3) - 1; @@ -421,7 +437,9 @@ QVariant X26Model::data(const QModelIndex &index, int role) const return (triplet.data() & 0x10) >> 4; } break; - case 0x15 ... 0x17: // Define object + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object switch (role) { case Qt::UserRole+1: // Required at which levels return ((triplet.address() & 0x18) >> 3) - 1; @@ -496,12 +514,12 @@ QVariant X26Model::data(const QModelIndex &index, int role) const if (role == Qt::UserRole+2) // Character set return m_parentMainWidget->pageDecode()->cellG2CharacterSet(triplet.activePositionRow(), triplet.activePositionColumn()); break; - case 0x29: // G0 character - case 0x30 ... 0x3f: // G0 diacritical mark - // Qt::UserRole+1 is character number, returned by default below - if (role == Qt::UserRole+2) // Character set - return m_parentMainWidget->pageDecode()->cellG0CharacterSet(triplet.activePositionRow(), triplet.activePositionColumn()); - break; + default: + if (triplet.modeExt() == 0x29 || (triplet.modeExt() >= 0x30 && triplet.modeExt() <= 0x3f)) + // G0 character or G0 diacritical mark + // Qt::UserRole+1 is character number, returned by default below + if (role == Qt::UserRole+2) // Character set + return m_parentMainWidget->pageDecode()->cellG0CharacterSet(triplet.activePositionRow(), triplet.activePositionColumn()); }; // For characters and other triplet modes, return the complete data value @@ -635,15 +653,6 @@ bool X26Model::setData(const QModelIndex &index, const QVariant &value, int role if (triplet.data() & 0x78) m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x07, 0x00, role)); break; - case 0x21: // G1 mosaic character - case 0x22: // G3 mosaic character at level 1.5 - case 0x29: // G0 character - case 0x2b: // G3 mosaic character at level >=2.5 - case 0x2f ... 0x3f: // G2 character or G0 diacritical mark - // Data range 0x20-0x7f - if (triplet.data() < 0x20) - m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0x20, role)); - break; case 0x27: // Additional flash functions // D6 and D5 must be clear, D4 and D3 set is reserved phase if (triplet.data() >= 0x18) @@ -660,6 +669,20 @@ bool X26Model::setData(const QModelIndex &index, const QVariant &value, int role if ((triplet.data() & 0x3f) >= 48) m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x40, 0x77, role)); break; + case 0x21: // G1 mosaic character + case 0x22: // G3 mosaic character at level 1.5 + case 0x29: // G0 character + case 0x2b: // G3 mosaic character at level >=2.5 + case 0x2f: // G2 character + // Data range 0x20-0x7f + if (triplet.data() < 0x20) + m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0x20, role)); + break; + default: + if (intValue >= 0x30 && intValue <= 0x3f && triplet.data() < 0x20) + // G0 diacritical mark + // Data range 0x20-0x7f + m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETdata, 0x00, 0x20, role)); } return true; } @@ -681,7 +704,9 @@ bool X26Model::setData(const QModelIndex &index, const QVariant &value, int role break; } break; - case 0x11 ... 0x13: // Invoke object + case 0x11: // Invoke Active Object + case 0x12: // Invoke Adaptive Object + case 0x13: // Invoke Passive Object switch (role) { case Qt::UserRole+1: // Object source: Local, POP or GPOP m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x27, (intValue+1) << 3, role)); @@ -711,7 +736,9 @@ bool X26Model::setData(const QModelIndex &index, const QVariant &value, int role return true; } break; - case 0x15 ... 0x17: // Define object + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object switch (role) { case Qt::UserRole+1: // Required at which levels m_parentMainWidget->document()->undoStack()->push(new EditTripletCommand(m_parentMainWidget->document(), this, index.row(), EditTripletCommand::ETaddress, 0x27, (intValue+1) << 3, role)); diff --git a/x26triplets.cpp b/x26triplets.cpp index 8713253..3244474 100644 --- a/x26triplets.cpp +++ b/x26triplets.cpp @@ -124,7 +124,9 @@ void X26TripletList::updateInternalData() m_list.at(i+1).modeExt() > 0x13) triplet->m_error = X26Triplet::OriginModifierAlone; break; - case 0x11 ... 0x13: // Invoke Object + case 0x11: // Invoke Active Object + case 0x12: // Invoke Adaptive Object + case 0x13: // Invoke Passive Object if (triplet->objectSource() == X26Triplet::LocalObject) { if (triplet->objectLocalTripletNumber() > 12 || triplet->objectLocalIndex() > (m_list.size()-1) || @@ -135,7 +137,9 @@ void X26TripletList::updateInternalData() triplet->m_error = X26Triplet::InvokeTypeMismatch; } break; - case 0x15 ... 0x17: // Define Object + case 0x15: // Define Active Object + case 0x16: // Define Adaptive Object + case 0x17: // Define Passive Object activePosition.reset(); // Make sure data field holds correct place of triplet // otherwise the object won't appear @@ -145,7 +149,12 @@ void X26TripletList::updateInternalData() if ((triplet->m_data & 0x30) == 0x00) triplet->m_reservedData = true; case 0x1f: // Termination marker - case 0x08 ... 0x0d: // PDC + case 0x08: // PDC country of origin & programme source + case 0x09: // PDC month & day + case 0x0a: // PDC cursor row & announced start hour + case 0x0b: // PDC cursor row & announced finish hour + case 0x0c: // PDC cursor row & local time offset + case 0x0d: // PDC series ID & series code break; default: triplet->m_reservedMode = true; @@ -158,18 +167,10 @@ void X26TripletList::updateInternalData() else switch (triplet->modeExt()) { case 0x20: // Foreground colour - case 0x23: // Foreground colour + case 0x23: // Background colour if (triplet->m_data & 0x60) triplet->m_reservedData = true; break; - case 0x21: // G1 mosaic character - case 0x22: // G3 mosaic character at level 1.5 - case 0x29: // G0 character - case 0x2b: // G3 mosaic character at level >=2.5 - case 0x2f ... 0x3f: // G2 character or G0 diacritical mark - if (triplet->m_data < 0x20) - triplet->m_reservedData = true; - break; case 0x27: // Additional flash functions if (triplet->m_data >= 0x18) triplet->m_reservedData = true; @@ -193,6 +194,19 @@ void X26TripletList::updateInternalData() if ((triplet->m_data & 0x3f) >= 48) // Should really be an error? triplet->m_reservedData = true; + break; + case 0x21: // G1 mosaic character + case 0x22: // G3 mosaic character at level 1.5 + case 0x29: // G0 character + case 0x2b: // G3 mosaic character at level >=2.5 + case 0x2f: // G2 character + if (triplet->m_data < 0x20) + triplet->m_reservedData = true; + break; + default: + if (triplet->modeExt() >= 0x30 && triplet->modeExt() <= 0x3f && triplet->m_data < 0x20) + // G0 diacritical mark + triplet->m_reservedData = true; } triplet->m_activePositionRow = activePosition.row(); @@ -217,15 +231,18 @@ void X26TripletList::updateInternalData() activePosition.setColumn(8); break; case 0x22: // G3 mosaic character at level 1.5 - case 0x2f ... 0x3f: // G2 character or G0 diacritical mark + case 0x2f: // G2 character activePosition.setColumn(triplet->addressColumn()); break; + default: + if (triplet->modeExt() >= 0x30 && triplet->modeExt() <= 0x3f) + // G0 diacritical mark + activePosition.setColumn(triplet->addressColumn()); } triplet->m_activePositionRow1p5 = activePosition.row(); triplet->m_activePositionColumn1p5 = activePosition.column(); } - } void X26TripletList::append(const X26Triplet &value)