freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2-demos] gsoc-2022-chariri-2 0eae8eb 04/30: [ftinspect] Use cus


From: Werner Lemberg
Subject: [freetype2-demos] gsoc-2022-chariri-2 0eae8eb 04/30: [ftinspect] Use custom `QAbstractListModel` instead of manually mapping.
Date: Mon, 11 Jul 2022 07:17:36 -0400 (EDT)

branch: gsoc-2022-chariri-2
commit 0eae8eb0e72c2db9f5cd53a1bd17e0c349d84131
Author: Charlie Jiang <w@chariri.moe>
Commit: Charlie Jiang <w@chariri.moe>

    [ftinspect] Use custom `QAbstractListModel` instead of manually mapping.
    
    In `maingui.cpp`, mapping between `QComboBox` indices and actual FreeType
    values was done manually. The enabled statuses of individual ComboBox items
    were also maintained in `maingui.cpp`.
    
    In this commit, those code was moved to seperate custom classes 
implementating
    `QAbstractListModel`. All mapping was done there. Statuses was maintained
    in the classes as well. By doing this, the reason why some items were 
disabled
    was made more clear and explicit, and adding more items is more easy.
    
    The `QComboBoxx` custom widget was no longer needed since disable flag can 
be
    provided by the custom model by overriding the `flags` function.
    
    `SimpleComboBoxModel` is a basic class for Key-Value-DisplayName mapping.
    Other models could extend this class if no complicated mapping (e.g.
    `HintingModeComboBoxModel`) is needed.
    
    * src/ftinspect/models/ttsettingscomboboxmodel.cpp,
      src/ftinspect/models/ttsettingscomboboxmodel.cpp: New files.
      `HintingModeComboBoxModel`, `SimpleComboBoxModel`, 
`LCDFilterComboBoxModel`
      and `AntiAliasingComboBoxModel` is defined here.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      `Engine` now accepts "load target" value of certain anti-aliasing mode
      instead of the anti-aliasing enum value. The mapping was moved into
      `AntiAliasingComboBoxModel`.
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp: Move all mappings
      and enabled/disabled statuses to separate models.
      Remove mapping `QHash`es. Use `QComboBox` instead of `QComboBoxx`.
    
    * src/ftinspect/meson.build, src/ftinspect/CMakeLists.txt: Updated.
---
 src/ftinspect/CMakeLists.txt                     |   2 +
 src/ftinspect/engine/engine.cpp                  |  31 +--
 src/ftinspect/engine/engine.hpp                  |  18 +-
 src/ftinspect/maingui.cpp                        | 192 +++++---------
 src/ftinspect/maingui.hpp                        |  32 +--
 src/ftinspect/meson.build                        |   5 +-
 src/ftinspect/models/ttsettingscomboboxmodel.cpp | 319 +++++++++++++++++++++++
 src/ftinspect/models/ttsettingscomboboxmodel.hpp | 159 +++++++++++
 8 files changed, 568 insertions(+), 190 deletions(-)

diff --git a/src/ftinspect/CMakeLists.txt b/src/ftinspect/CMakeLists.txt
index e3520ea..2d8096e 100644
--- a/src/ftinspect/CMakeLists.txt
+++ b/src/ftinspect/CMakeLists.txt
@@ -32,6 +32,8 @@ add_executable(ftinspect
   "widgets/qgraphicsviewx.cpp"
   "widgets/qpushbuttonx.cpp"
   "widgets/qspinboxx.cpp"
+
+  "models/ttsettingscomboboxmodel.cpp"
 )
 target_link_libraries(ftinspect
   Qt5::Core Qt5::Widgets
diff --git a/src/ftinspect/engine/engine.cpp b/src/ftinspect/engine/engine.cpp
index 68a19de..8084d72 100644
--- a/src/ftinspect/engine/engine.cpp
+++ b/src/ftinspect/engine/engine.cpp
@@ -464,40 +464,15 @@ Engine::update()
 
   if (doHinting_)
   {
-    unsigned long target;
-
-    if (antiAliasingMode_ == AntiAliasing_None)
-      target = FT_LOAD_TARGET_MONO;
-    else
-    {
-      switch (antiAliasingMode_)
-      {
-      case AntiAliasing_Light:
-        target = FT_LOAD_TARGET_LIGHT;
-        break;
-
-      case AntiAliasing_LCD:
-      case AntiAliasing_LCD_BGR: // TODO Differenate RGB/BGR here?
-        target = FT_LOAD_TARGET_LCD;
-        break;
-
-      case AntiAliasing_LCD_Vertical:
-      case AntiAliasing_LCD_Vertical_BGR:
-        target = FT_LOAD_TARGET_LCD_V;
-        break;
-
-      default:
-        target = FT_LOAD_TARGET_NORMAL;
-      }
-    }
-
+    // TODO Differentiate RGB/BGR here?
+    unsigned long target = antiAliasingTarget_;
     loadFlags_ |= target;
   }
   else
   {
     loadFlags_ |= FT_LOAD_NO_HINTING;
 
-    if (antiAliasingMode_ == AntiAliasing_None)
+    if (antiAliasingTarget_ | FT_LOAD_TARGET_MONO) // XXX does this hold?
       loadFlags_ |= FT_LOAD_MONOCHROME;
   }
 
diff --git a/src/ftinspect/engine/engine.hpp b/src/ftinspect/engine/engine.hpp
index af1690f..4231ca8 100644
--- a/src/ftinspect/engine/engine.hpp
+++ b/src/ftinspect/engine/engine.hpp
@@ -42,9 +42,6 @@ class Engine
 {
 public:
   //////// Nested definitions (forward decl)
-
-  // TODO these would be dropped with custom QAbstractItemModel
-  enum AntiAliasing : int;
   enum FontType : int;
 
   struct EngineDefaultValues
@@ -117,7 +114,7 @@ public:
   }
   void setShowSegments(bool showSegments) { showSegments_ = showSegments; }
   void setGamma(double gamma) { gamma_ = gamma; }
-  void setAntiAliasingMode(AntiAliasing mode) { antiAliasingMode_ = mode; }
+  void setAntiAliasingTarget(int target) { antiAliasingTarget_ = target; }
 
   // Note: These 3 functions now takes actual mode/version from FreeType,
   // instead of values from enum in MainGUI!
@@ -165,7 +162,7 @@ private:
   bool doVerticalHinting_;
   bool doBlueZoneHinting_;
   bool showSegments_;
-  AntiAliasing antiAliasingMode_;
+  int antiAliasingTarget_;
 
   double gamma_;
 
@@ -176,17 +173,6 @@ private:
 public:
 
   /// Actual definition
-  
-  enum AntiAliasing
-  {
-    AntiAliasing_None,
-    AntiAliasing_Normal,
-    AntiAliasing_Light,
-    AntiAliasing_LCD,
-    AntiAliasing_LCD_BGR,
-    AntiAliasing_LCD_Vertical,
-    AntiAliasing_LCD_Vertical_BGR
-  };
 
   // XXX cover all available modules
   enum FontType
diff --git a/src/ftinspect/maingui.cpp b/src/ftinspect/maingui.cpp
index f650550..6a902e4 100644
--- a/src/ftinspect/maingui.cpp
+++ b/src/ftinspect/maingui.cpp
@@ -230,8 +230,8 @@ MainGUI::syncSettings()
 
   engine_->setGamma(gammaSlider_->value());
 
-  engine_->setAntiAliasingMode(static_cast<Engine::AntiAliasing>(
-      antiAliasingComboBoxx_->currentIndex()));
+  engine_->setAntiAliasingTarget(antiAliasingComboBoxModel_->indexToValue(
+    antiAliasingComboBox_->currentIndex()));
 }
 
 
@@ -250,45 +250,29 @@ MainGUI::checkHinting()
   {
     if (engine_->currentFontType() == Engine::FontType_CFF)
     {
-      for (int i = 0; i < hintingModeComboBoxx_->count(); i++)
-      {
-        if (hintingModesCFFHash_.key(i, -1) != -1)
-          hintingModeComboBoxx_->setItemEnabled(i, true);
-        else
-          hintingModeComboBoxx_->setItemEnabled(i, false);
-      }
-
-      hintingModeComboBoxx_->setCurrentIndex(currentCFFHintingMode_);
+      hintingModeComboBoxModel_->setCurrentEngineType(
+        HintingModeComboBoxModel::HintingEngineType_CFF);
+      hintingModeComboBox_->setCurrentIndex(currentCFFHintingMode_);
     }
     else if (engine_->currentFontType() == Engine::FontType_TrueType)
     {
-      for (int i = 0; i < hintingModeComboBoxx_->count(); i++)
-      {
-        if (hintingModesTrueTypeHash_.key(i, -1) != -1)
-          hintingModeComboBoxx_->setItemEnabled(i, true);
-        else
-          hintingModeComboBoxx_->setItemEnabled(i, false);
-      }
-
-      hintingModeComboBoxx_->setCurrentIndex(currentTTInterpreterVersion_);
+      hintingModeComboBoxModel_->setCurrentEngineType(
+        HintingModeComboBoxModel::HintingEngineType_TrueType);
+      hintingModeComboBox_->setCurrentIndex(currentTTInterpreterVersion_);
     }
     else
     {
       hintingModeLabel_->setEnabled(false);
-      hintingModeComboBoxx_->setEnabled(false);
+      hintingModeComboBox_->setEnabled(false);
     }
 
-    for (int i = 0; i < hintingModesAlwaysDisabled_.size(); i++)
-      hintingModeComboBoxx_->setItemEnabled(hintingModesAlwaysDisabled_[i],
-                                           false);
-
     autoHintingCheckBox_->setEnabled(true);
     checkAutoHinting();
   }
   else
   {
     hintingModeLabel_->setEnabled(false);
-    hintingModeComboBoxx_->setEnabled(false);
+    hintingModeComboBox_->setEnabled(false);
 
     autoHintingCheckBox_->setEnabled(false);
     horizontalHintingCheckBox_->setEnabled(false);
@@ -296,7 +280,11 @@ MainGUI::checkHinting()
     blueZoneHintingCheckBox_->setEnabled(false);
     segmentDrawingCheckBox_->setEnabled(false);
 
-    antiAliasingComboBoxx_->setItemEnabled(Engine::AntiAliasing_Light, false);
+    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
+    if (antiAliasingComboBox_->currentIndex()
+      == AntiAliasingComboBoxModel::AntiAliasing_Light)
+      antiAliasingComboBox_->setCurrentIndex(
+        AntiAliasingComboBoxModel::AntiAliasing_Normal);
   }
 
   drawGlyph();
@@ -306,16 +294,18 @@ MainGUI::checkHinting()
 void
 MainGUI::checkHintingMode()
 {
-  int index = hintingModeComboBoxx_->currentIndex();
+  int index = hintingModeComboBox_->currentIndex();
 
   if (engine_->currentFontType() == Engine::FontType_CFF)
   {
-    engine_->setCFFHintingMode(hintingModesCFFHash_.key(index));
+    engine_->setCFFHintingMode(
+      hintingModeComboBoxModel_->indexToCFFMode(index));
     currentCFFHintingMode_ = index;
   }
   else if (engine_->currentFontType() == Engine::FontType_TrueType)
   {
-    engine_->setTTInterpreterVersion(hintingModesTrueTypeHash_.key(index));
+    engine_->setTTInterpreterVersion(
+      hintingModeComboBoxModel_->indexToTTInterpreterVersion(index));
     currentTTInterpreterVersion_ = index;
   }
 
@@ -330,14 +320,14 @@ MainGUI::checkAutoHinting()
   if (autoHintingCheckBox_->isChecked())
   {
     hintingModeLabel_->setEnabled(false);
-    hintingModeComboBoxx_->setEnabled(false);
+    hintingModeComboBox_->setEnabled(false);
 
     horizontalHintingCheckBox_->setEnabled(true);
     verticalHintingCheckBox_->setEnabled(true);
     blueZoneHintingCheckBox_->setEnabled(true);
     segmentDrawingCheckBox_->setEnabled(true);
 
-    antiAliasingComboBoxx_->setItemEnabled(Engine::AntiAliasing_Light, true);
+    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(true);
   }
   else
   {
@@ -345,7 +335,7 @@ MainGUI::checkAutoHinting()
         || engine_->currentFontType() == Engine::FontType_TrueType)
     {
       hintingModeLabel_->setEnabled(true);
-      hintingModeComboBoxx_->setEnabled(true);
+      hintingModeComboBox_->setEnabled(true);
     }
 
     horizontalHintingCheckBox_->setEnabled(false);
@@ -353,10 +343,12 @@ MainGUI::checkAutoHinting()
     blueZoneHintingCheckBox_->setEnabled(false);
     segmentDrawingCheckBox_->setEnabled(false);
 
-    antiAliasingComboBoxx_->setItemEnabled(Engine::AntiAliasing_Light, false);
+    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
 
-    if (antiAliasingComboBoxx_->currentIndex() == Engine::AntiAliasing_Light)
-      antiAliasingComboBoxx_->setCurrentIndex(Engine::AntiAliasing_Normal);
+    if (antiAliasingComboBox_->currentIndex()
+        == AntiAliasingComboBoxModel::AntiAliasing_Light)
+      antiAliasingComboBox_->setCurrentIndex(
+          AntiAliasingComboBoxModel::AntiAliasing_Normal);
   }
 
   drawGlyph();
@@ -366,11 +358,11 @@ MainGUI::checkAutoHinting()
 void
 MainGUI::checkAntiAliasing()
 {
-  int index = antiAliasingComboBoxx_->currentIndex();
+  int index = antiAliasingComboBox_->currentIndex();
 
-  if (index == Engine::AntiAliasing_None
-      || index == Engine::AntiAliasing::AntiAliasing_Normal
-      || index == Engine::AntiAliasing_Light)
+  if (index == AntiAliasingComboBoxModel::AntiAliasing_None
+      || index == AntiAliasingComboBoxModel::AntiAliasing::AntiAliasing_Normal
+      || index == AntiAliasingComboBoxModel::AntiAliasing_Light)
   {
     lcdFilterLabel_->setEnabled(false);
     lcdFilterComboBox_->setEnabled(false);
@@ -389,7 +381,8 @@ void
 MainGUI::checkLcdFilter()
 {
   int index = lcdFilterComboBox_->currentIndex();
-  engine_->setLcdFilter(lcdFilterHash_.key(index));
+  engine_->setLcdFilter(static_cast<FT_LcdFilter>(
+    lcdFilterComboboxModel_->indexToValue(index)));
 }
 
 
@@ -696,7 +689,8 @@ MainGUI::drawGlyph()
     {
       // XXX support LCD
       FT_Pixel_Mode pixelMode = FT_PIXEL_MODE_GRAY;
-      if (antiAliasingComboBoxx_->currentIndex() == Engine::AntiAliasing_None)
+      if (antiAliasingComboBox_->currentIndex()
+          == AntiAliasingComboBoxModel::AntiAliasing_None)
         pixelMode = FT_PIXEL_MODE_MONO;
 
       currentGlyphBitmapItem_ = new GlyphBitmap(outline,
@@ -744,18 +738,11 @@ MainGUI::createLayout()
 
   hintingModeLabel_ = new QLabel(tr("Hinting Mode"));
   hintingModeLabel_->setAlignment(Qt::AlignRight);
-  hintingModeComboBoxx_ = new QComboBoxx;
-  hintingModeComboBoxx_->insertItem(HintingMode_TrueType_v35,
-                                   tr("TrueType v35"));
-  hintingModeComboBoxx_->insertItem(HintingMode_TrueType_v38,
-                                   tr("TrueType v38"));
-  hintingModeComboBoxx_->insertItem(HintingMode_TrueType_v40,
-                                   tr("TrueType v40"));
-  hintingModeComboBoxx_->insertItem(HintingMode_CFF_FreeType,
-                                   tr("CFF (FreeType)"));
-  hintingModeComboBoxx_->insertItem(HintingMode_CFF_Adobe,
-                                   tr("CFF (Adobe)"));
-  hintingModeLabel_->setBuddy(hintingModeComboBoxx_);
+
+  hintingModeComboBoxModel_ = new HintingModeComboBoxModel;
+  hintingModeComboBox_ = new QComboBox;
+  hintingModeComboBox_->setModel(hintingModeComboBoxModel_);
+  hintingModeLabel_->setBuddy(hintingModeComboBox_);
 
   autoHintingCheckBox_ = new QCheckBox(tr("Auto-Hinting"));
   horizontalHintingCheckBox_ = new QCheckBox(tr("Horizontal Hinting"));
@@ -765,30 +752,18 @@ MainGUI::createLayout()
 
   antiAliasingLabel_ = new QLabel(tr("Anti-Aliasing"));
   antiAliasingLabel_->setAlignment(Qt::AlignRight);
-  antiAliasingComboBoxx_ = new QComboBoxx;
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_None,
-                                    tr("None"));
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_Normal,
-                                    tr("Normal"));
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_Light,
-                                    tr("Light"));
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_LCD,
-                                    tr("LCD (RGB)"));
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_LCD_BGR,
-                                    tr("LCD (BGR)"));
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_LCD_Vertical,
-                                    tr("LCD (vert. RGB)"));
-  antiAliasingComboBoxx_->insertItem(Engine::AntiAliasing_LCD_Vertical_BGR,
-                                    tr("LCD (vert. BGR)"));
-  antiAliasingLabel_->setBuddy(antiAliasingComboBoxx_);
+
+  antiAliasingComboBoxModel_ = new AntiAliasingComboBoxModel;
+  antiAliasingComboBox_ = new QComboBox;
+  antiAliasingComboBox_->setModel(antiAliasingComboBoxModel_);
+  antiAliasingLabel_->setBuddy(antiAliasingComboBox_);
 
   lcdFilterLabel_ = new QLabel(tr("LCD Filter"));
   lcdFilterLabel_->setAlignment(Qt::AlignRight);
+
+  lcdFilterComboboxModel_ = new LCDFilterComboBoxModel;
   lcdFilterComboBox_ = new QComboBox;
-  lcdFilterComboBox_->insertItem(LCDFilter_Default, tr("Default"));
-  lcdFilterComboBox_->insertItem(LCDFilter_Light, tr("Light"));
-  lcdFilterComboBox_->insertItem(LCDFilter_None, tr("None"));
-  lcdFilterComboBox_->insertItem(LCDFilter_Legacy, tr("Legacy"));
+  lcdFilterComboBox_->setModel(lcdFilterComboboxModel_);
   lcdFilterLabel_->setBuddy(lcdFilterComboBox_);
 
   int width;
@@ -802,11 +777,11 @@ MainGUI::createLayout()
 
   // ensure that all items in combo boxes fit completely;
   // also make all combo boxes have the same width
-  width = hintingModeComboBoxx_->minimumSizeHint().width();
-  width = qMax(antiAliasingComboBoxx_->minimumSizeHint().width(), width);
+  width = hintingModeComboBox_->minimumSizeHint().width();
+  width = qMax(antiAliasingComboBox_->minimumSizeHint().width(), width);
   width = qMax(lcdFilterComboBox_->minimumSizeHint().width(), width);
-  hintingModeComboBoxx_->setMinimumWidth(width);
-  antiAliasingComboBoxx_->setMinimumWidth(width);
+  hintingModeComboBox_->setMinimumWidth(width);
+  antiAliasingComboBox_->setMinimumWidth(width);
   lcdFilterComboBox_->setMinimumWidth(width);
 
   gammaLabel_ = new QLabel(tr("Gamma"));
@@ -827,7 +802,7 @@ MainGUI::createLayout()
 
   hintingModeLayout_ = new QHBoxLayout;
   hintingModeLayout_->addWidget(hintingModeLabel_);
-  hintingModeLayout_->addWidget(hintingModeComboBoxx_);
+  hintingModeLayout_->addWidget(hintingModeComboBox_);
 
   horizontalHintingLayout_ = new QHBoxLayout;
   horizontalHintingLayout_->addSpacing(20); // XXX px
@@ -847,7 +822,7 @@ MainGUI::createLayout()
 
   antiAliasingLayout_ = new QHBoxLayout;
   antiAliasingLayout_->addWidget(antiAliasingLabel_);
-  antiAliasingLayout_->addWidget(antiAliasingComboBoxx_);
+  antiAliasingLayout_->addWidget(antiAliasingComboBox_);
 
   lcdFilterLayout_ = new QHBoxLayout;
   lcdFilterLayout_->addWidget(lcdFilterLabel_);
@@ -1051,9 +1026,9 @@ MainGUI::createConnections()
   connect(hintingCheckBox_, SIGNAL(clicked()),
           SLOT(checkHinting()));
 
-  connect(hintingModeComboBoxx_, SIGNAL(currentIndexChanged(int)),
+  connect(hintingModeComboBox_, SIGNAL(currentIndexChanged(int)),
           SLOT(checkHintingMode()));
-  connect(antiAliasingComboBoxx_, SIGNAL(currentIndexChanged(int)),
+  connect(antiAliasingComboBox_, SIGNAL(currentIndexChanged(int)),
           SLOT(checkAntiAliasing()));
   connect(lcdFilterComboBox_, SIGNAL(currentIndexChanged(int)),
           SLOT(checkLcdFilter()));
@@ -1177,43 +1152,14 @@ MainGUI::createStatusBar()
 void
 MainGUI::setDefaults()
 {
-  // set up mappings between property values and combo box indices
-  hintingModesTrueTypeHash_[TT_INTERPRETER_VERSION_35] = 
HintingMode_TrueType_v35;
-  hintingModesTrueTypeHash_[TT_INTERPRETER_VERSION_38] = 
HintingMode_TrueType_v38;
-  hintingModesTrueTypeHash_[TT_INTERPRETER_VERSION_40] = 
HintingMode_TrueType_v40;
-
-  hintingModesCFFHash_[FT_HINTING_FREETYPE] = HintingMode_CFF_FreeType;
-  hintingModesCFFHash_[FT_HINTING_ADOBE] = HintingMode_CFF_Adobe;
-
-  lcdFilterHash_[FT_LCD_FILTER_DEFAULT] = LCDFilter_Default;
-  lcdFilterHash_[FT_LCD_FILTER_LIGHT] = LCDFilter_Light;
-  lcdFilterHash_[FT_LCD_FILTER_NONE] = LCDFilter_None;
-  lcdFilterHash_[FT_LCD_FILTER_LEGACY] = LCDFilter_Legacy;
-
   Engine::EngineDefaultValues& defaults = engine_->engineDefaults();
 
-  // make copies and remove existing elements...
-  QHash<int, int> hmTTHash = hintingModesTrueTypeHash_;
-  if (hmTTHash.contains(defaults.ttInterpreterVersionDefault))
-    hmTTHash.remove(defaults.ttInterpreterVersionDefault);
-  if (hmTTHash.contains(defaults.ttInterpreterVersionOther))
-    hmTTHash.remove(defaults.ttInterpreterVersionOther);
-  if (hmTTHash.contains(defaults.ttInterpreterVersionOther1))
-    hmTTHash.remove(defaults.ttInterpreterVersionOther1);
-
-  QHash<int, int> hmCFFHash = hintingModesCFFHash_;
-  if (hmCFFHash.contains(defaults.cffHintingEngineDefault))
-    hmCFFHash.remove(defaults.cffHintingEngineDefault);
-  if (hmCFFHash.contains(defaults.cffHintingEngineOther))
-    hmCFFHash.remove(defaults.cffHintingEngineOther);
-
-  // ... to construct a list of always disabled hinting mode combo box items
-  hintingModesAlwaysDisabled_ = hmTTHash.values();
-  hintingModesAlwaysDisabled_ += hmCFFHash.values();
-
-  for (int i = 0; i < hintingModesAlwaysDisabled_.size(); i++)
-    hintingModeComboBoxx_->setItemEnabled(hintingModesAlwaysDisabled_[i],
-                                         false);
+  hintingModeComboBoxModel_->setSupportedModes(
+    { defaults.ttInterpreterVersionDefault,
+      defaults.ttInterpreterVersionOther,
+      defaults.ttInterpreterVersionOther1 },
+    { defaults.cffHintingEngineDefault, 
+      defaults.cffHintingEngineOther });
 
   // the next four values always non-negative
   currentFontIndex_ = 0;
@@ -1222,14 +1168,18 @@ MainGUI::setDefaults()
   currentGlyphIndex_ = 0;
 
   currentCFFHintingMode_
-    = hintingModesCFFHash_[defaults.cffHintingEngineDefault];
+    = hintingModeComboBoxModel_->cffModeToIndex(
+    defaults.cffHintingEngineDefault);
   currentTTInterpreterVersion_
-    = hintingModesTrueTypeHash_[defaults.ttInterpreterVersionDefault];
+    = hintingModeComboBoxModel_->ttInterpreterVersionToIndex(
+        defaults.ttInterpreterVersionDefault);
 
   hintingCheckBox_->setChecked(true);
 
-  antiAliasingComboBoxx_->setCurrentIndex(Engine::AntiAliasing_Normal);
-  lcdFilterComboBox_->setCurrentIndex(LCDFilter_Light);
+  antiAliasingComboBox_->setCurrentIndex(
+    AntiAliasingComboBoxModel::AntiAliasing_Normal);
+  lcdFilterComboBox_->setCurrentIndex(
+    LCDFilterComboBoxModel::LCDFilter_Light);
 
   horizontalHintingCheckBox_->setChecked(true);
   verticalHintingCheckBox_->setChecked(true);
diff --git a/src/ftinspect/maingui.hpp b/src/ftinspect/maingui.hpp
index fd930b3..aea9b0c 100644
--- a/src/ftinspect/maingui.hpp
+++ b/src/ftinspect/maingui.hpp
@@ -14,6 +14,7 @@
 #include "widgets/qgraphicsviewx.hpp"
 #include "widgets/qpushbuttonx.hpp"
 #include "widgets/qspinboxx.hpp"
+#include "models/ttsettingscomboboxmodel.hpp"
 
 #include <QAction>
 #include <QCheckBox>
@@ -133,8 +134,12 @@ private:
   QCheckBox *showPointsCheckBox_;
   QCheckBox *verticalHintingCheckBox_;
 
-  QComboBoxx *antiAliasingComboBoxx_;
-  QComboBoxx *hintingModeComboBoxx_;
+  AntiAliasingComboBoxModel* antiAliasingComboBoxModel_;
+  HintingModeComboBoxModel* hintingModeComboBoxModel_;
+  LCDFilterComboBoxModel* lcdFilterComboboxModel_;
+
+  QComboBox *antiAliasingComboBox_;
+  QComboBox *hintingModeComboBox_;
   QComboBox *lcdFilterComboBox_;
   QComboBox *unitsComboBox_;
 
@@ -146,10 +151,6 @@ private:
   QGridLayout *fontLayout;
   QGridLayout *infoRightLayout;
 
-  QHash<int, int> hintingModesTrueTypeHash_;
-  QHash<int, int> hintingModesCFFHash_;
-  QHash<FT_LcdFilter, int> lcdFilterHash_;
-
   QHBoxLayout *antiAliasingLayout_;
   QHBoxLayout *blueZoneHintingLayout_;
   QHBoxLayout *ftinspectLayout_;
@@ -176,8 +177,6 @@ private:
   QLabel *sizeLabel_;
   QLabel *zoomLabel_;
 
-  QList<int> hintingModesAlwaysDisabled_;
-
   QLocale *locale_;
 
   QMenu *menuFile_;
@@ -230,22 +229,7 @@ private:
   QWidget *leftWidget_;
   QWidget *rightWidget_;
   QWidget *mmgxTabWidget_;
-  
-  enum HintingMode
-  {
-    HintingMode_TrueType_v35,
-    HintingMode_TrueType_v38,
-    HintingMode_TrueType_v40,
-    HintingMode_CFF_FreeType,
-    HintingMode_CFF_Adobe
-  };
-  enum LCDFilter
-  {
-    LCDFilter_Default,
-    LCDFilter_Light,
-    LCDFilter_None,
-    LCDFilter_Legacy
-  };
+
   enum Units
   {
     Units_px,
diff --git a/src/ftinspect/meson.build b/src/ftinspect/meson.build
index 3993144..f02d104 100644
--- a/src/ftinspect/meson.build
+++ b/src/ftinspect/meson.build
@@ -34,9 +34,11 @@ if qt5_dep.found()
     'widgets/qpushbuttonx.cpp',
     'widgets/qspinboxx.cpp',
 
+    'models/ttsettingscomboboxmodel.cpp',
+
     'ftinspect.cpp',
     'maingui.cpp',
-  ])
+])
 
   moc_files = qt5.preprocess(
     moc_headers: [
@@ -45,6 +47,7 @@ if qt5_dep.found()
       'widgets/qpushbuttonx.hpp',
       'widgets/qspinboxx.hpp',
       'maingui.hpp',
+      'models/ttsettingscomboboxmodel.cpp',
     ],
     dependencies: qt5_dep)
 
diff --git a/src/ftinspect/models/ttsettingscomboboxmodel.cpp 
b/src/ftinspect/models/ttsettingscomboboxmodel.cpp
new file mode 100644
index 0000000..750c629
--- /dev/null
+++ b/src/ftinspect/models/ttsettingscomboboxmodel.cpp
@@ -0,0 +1,319 @@
+// ttsettingscomboboxmodel.cpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+
+#include "ttsettingscomboboxmodel.hpp"
+
+#include <QApplication>
+#include <QPalette>
+#include <freetype/ftdriver.h>
+#include <freetype/ftlcdfil.h>
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// HintingModeComboBoxModel
+//
+/////////////////////////////////////////////////////////////////////////////
+
+HintingModeComboBoxModel::HintingModeComboBoxModel()
+{
+  items_[HintingMode_TrueType_v35] = {
+    HintingEngineType_TrueType,
+    HintingMode_TrueType_v35,
+    TT_INTERPRETER_VERSION_35,
+    false, false,
+    "TrueType v35"
+  };
+  items_[HintingMode_TrueType_v38] = {
+    HintingEngineType_TrueType,
+    HintingMode_TrueType_v38,
+    TT_INTERPRETER_VERSION_38,
+    false, false,
+    "TrueType v38"
+  };
+  items_[HintingMode_TrueType_v40] = {
+    HintingEngineType_TrueType,
+    HintingMode_TrueType_v40,
+    TT_INTERPRETER_VERSION_40,
+    false, false,
+    "TrueType v40"
+  };
+
+  items_[HintingMode_CFF_FreeType] = {
+    HintingEngineType_CFF,
+    HintingMode_CFF_FreeType,
+    FT_HINTING_FREETYPE,
+    false, false,
+    "CFF (FreeType)"
+  };
+  items_[HintingMode_CFF_Adobe] = {
+    HintingEngineType_CFF,
+    HintingMode_CFF_Adobe,
+    FT_HINTING_ADOBE,
+    false, false,
+    "CFF (Adobe)"
+  };
+}
+
+
+int
+HintingModeComboBoxModel::rowCount(const QModelIndex& parent) const
+{
+  return items_.size();
+}
+
+
+QVariant
+HintingModeComboBoxModel::data(const QModelIndex& index,
+  int role) const
+{
+  int r = index.row();
+  if (r < 0 || r >= items_.size())
+    return QVariant {};
+  HintingModeItem const& item = items_[r];
+
+  switch (role)
+  {
+  case Qt::DisplayRole:
+    return item.displayName;
+  case Qt::ForegroundRole:
+    if (item.enabled && item.supported)
+      return QVariant {};
+    else
+      return QApplication::palette().color(QPalette::Disabled, 
+                                           QPalette::Text);
+  default:
+    return QVariant {};
+  }
+}
+
+
+Qt::ItemFlags
+HintingModeComboBoxModel::flags(const QModelIndex& index) const
+{
+  int r = index.row();
+  if (r < 0 || r >= items_.size())
+    return Qt::ItemFlags {}; // not selectable, not enabled
+  HintingModeItem const& item = items_[r];
+
+  if (item.enabled && item.supported)
+    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+
+  return Qt::ItemFlags {};
+}
+
+
+int
+HintingModeComboBoxModel::indexToValueForType(int index,
+                                              HintingEngineType type) const
+{
+  if (index < 0 || index >= items_.size())
+    return -1;
+  HintingModeItem const& item = items_[index];
+  if (!item.supported || !item.enabled || item.type != type)
+    return -1;
+  return item.value;
+}
+
+
+int
+HintingModeComboBoxModel::valueToIndexForType(int value,
+                                              HintingEngineType type) const
+{
+  for (auto it = items_.begin();
+       it != items_.end();
+       ++it)
+  {
+    if (it->type == type && it->value == value)
+      return it->key;
+  }
+  return -1;
+}
+
+
+int
+HintingModeComboBoxModel::indexToTTInterpreterVersion(int index) const
+{
+  return indexToValueForType(index, HintingEngineType_TrueType);
+}
+
+
+int
+HintingModeComboBoxModel::indexToCFFMode(int index) const
+{
+  return indexToValueForType(index, HintingEngineType_CFF);
+}
+
+
+int
+HintingModeComboBoxModel::cffModeToIndex(int mode) const
+{
+  return valueToIndexForType(mode, HintingEngineType_CFF);
+}
+
+
+int
+HintingModeComboBoxModel::ttInterpreterVersionToIndex(int version) const
+{
+  return valueToIndexForType(version, HintingEngineType_TrueType);
+}
+
+
+void
+HintingModeComboBoxModel::setSupportedModes(QList<int> supportedTTIVersions,
+                                            QList<int> supportedCFFModes)
+{
+  for (auto it = items_.begin();
+       it != items_.end();
+       ++it)
+  {
+    if (it->type == HintingEngineType_TrueType)
+      it->supported = supportedTTIVersions.contains(it->value);
+    else if (it->type == HintingEngineType_CFF)
+      it->supported = supportedCFFModes.contains(it->value);
+    else
+      it->supported = false;
+  }
+}
+
+
+void
+HintingModeComboBoxModel::setCurrentEngineType(HintingEngineType type)
+{
+  for (auto it = items_.begin(); 
+       it != items_.end(); 
+       ++it)
+    it->enabled = it->supported && it->type == type;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// SimpleComboBoxModel
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+int
+SimpleComboBoxModel::rowCount(const QModelIndex& parent) const
+{
+  return items_.size();
+}
+
+
+QVariant
+SimpleComboBoxModel::data(const QModelIndex& index, int role) const
+{
+  if (role != Qt::DisplayRole)
+    return QVariant {};
+
+  int r = index.row();
+  if (r < 0 || r >= items_.size())
+    return QVariant {};
+  return items_[r].displayName;
+}
+
+
+int
+SimpleComboBoxModel::indexToValue(int index)
+{
+  if (index < 0 || index >= items_.size())
+    return -1;
+  return items_[index].value;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// LCDFilterComboBoxModel
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+LCDFilterComboBoxModel::LCDFilterComboBoxModel()
+{
+  items_[LCDFilter_Default] = {
+    FT_LCD_FILTER_DEFAULT,
+    "Default"
+  };
+  items_[LCDFilter_Light] = {
+    FT_LCD_FILTER_LIGHT,
+    "Light"
+  };
+  items_[LCDFilter_None] = {
+    FT_LCD_FILTER_NONE,
+    "None"
+  };
+  items_[LCDFilter_Legacy] = {
+    FT_LCD_FILTER_LEGACY,
+    "Legacy"
+  };
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AntiAliasingComboBoxModel
+//
+/////////////////////////////////////////////////////////////////////////////
+
+
+AntiAliasingComboBoxModel::AntiAliasingComboBoxModel()
+{
+  items_[AntiAliasing_None] = {
+    FT_LOAD_TARGET_MONO,
+    "None"
+  };
+  items_[AntiAliasing_Normal] = {
+    FT_LOAD_TARGET_NORMAL,
+    "Normal"
+  };
+  items_[AntiAliasing_Light] = {
+    FT_LOAD_TARGET_LIGHT,
+    "Light"
+  };
+  items_[AntiAliasing_LCD] = {
+    FT_LOAD_TARGET_LCD,
+    "LCD (RGB)"
+  };
+  items_[AntiAliasing_LCD_BGR] = {
+    FT_LOAD_TARGET_LCD,
+    "LCD (BGR)"
+  };
+  items_[AntiAliasing_LCD_Vertical] = {
+    FT_LOAD_TARGET_LCD_V,
+    "LCD (vert. RGB)"
+  };
+  items_[AntiAliasing_LCD_Vertical_BGR] = {
+    FT_LOAD_TARGET_LCD_V, // XXX Bug: No difference between RGB and BGR?
+    "LCD (vert. BGR)"
+  };
+
+  lightAntiAliasingEnabled_ = true;
+}
+
+
+QVariant
+AntiAliasingComboBoxModel::data(const QModelIndex& index,
+                                int role) const
+{
+  if (role == Qt::ForegroundRole)
+    if (index.row() == AntiAliasing_Light && !lightAntiAliasingEnabled_)
+      return QApplication::palette().color(QPalette::Disabled, 
+                                           QPalette::Text);
+  return SimpleComboBoxModel::data(index, role);
+}
+
+
+Qt::ItemFlags
+AntiAliasingComboBoxModel::flags(const QModelIndex& index) const
+{
+  if (index.row() == AntiAliasing_Light && !lightAntiAliasingEnabled_)
+    return Qt::ItemFlags {};
+  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
+
+// end of ttsettingscomboboxmodel.cpp
diff --git a/src/ftinspect/models/ttsettingscomboboxmodel.hpp 
b/src/ftinspect/models/ttsettingscomboboxmodel.hpp
new file mode 100644
index 0000000..0298ac4
--- /dev/null
+++ b/src/ftinspect/models/ttsettingscomboboxmodel.hpp
@@ -0,0 +1,159 @@
+// ttsettingscomboboxmodel.hpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+
+#pragma once
+
+#include <QAbstractListModel>
+#include <QHash>
+
+class HintingModeComboBoxModel
+: public QAbstractListModel
+{
+  Q_OBJECT
+public:
+  enum HintingEngineType : int;
+  enum HintingMode : int;
+  struct HintingModeItem
+  {
+    HintingEngineType type;
+    HintingMode key;
+    int value;
+    bool enabled;
+    bool supported;
+    QString displayName;
+  };
+
+  HintingModeComboBoxModel();
+  ~HintingModeComboBoxModel() = default;
+
+  int rowCount(const QModelIndex& parent) const;
+  QVariant data(const QModelIndex& index,
+                int role) const;
+  Qt::ItemFlags flags(const QModelIndex& index) const;
+
+  int indexToTTInterpreterVersion(int index) const;
+  int indexToCFFMode(int index) const;
+  int cffModeToIndex(int mode) const;
+  int ttInterpreterVersionToIndex(int version) const;
+
+  void setSupportedModes(QList<int> supportedTTIVersions,
+                         QList<int> supportedCFFModes);
+  void setCurrentEngineType(HintingEngineType type);
+
+private:
+  QHash<int, HintingModeItem> items_;
+
+  int indexToValueForType(int index,
+                          HintingEngineType type) const;
+  int valueToIndexForType(int value,
+                          HintingEngineType type) const;
+
+public:
+  // Note: Ensure related funcs are also changed when
+  // these enums are changed!
+  enum HintingEngineType
+  {
+    HintingEngineType_TrueType,
+    HintingEngineType_CFF
+  };
+
+  enum HintingMode
+  {
+    HintingMode_TrueType_v35 = 0,
+    HintingMode_TrueType_v38,
+    HintingMode_TrueType_v40,
+    HintingMode_CFF_FreeType,
+    HintingMode_CFF_Adobe
+  };
+};
+
+
+// A simple key-displayName-value model for QComboBox.
+class SimpleComboBoxModel
+: public QAbstractListModel
+{
+  Q_OBJECT
+public:
+  struct ComboBoxItem
+  {
+    int value;
+    QString displayName;
+  };
+
+  SimpleComboBoxModel() {}
+  ~SimpleComboBoxModel() = default;
+
+  int rowCount(const QModelIndex& parent) const;
+  QVariant data(const QModelIndex& index,
+                int role) const;
+
+  int indexToValue(int index);
+
+protected:
+  QHash<int, ComboBoxItem> items_;
+};
+
+
+class LCDFilterComboBoxModel
+: public SimpleComboBoxModel
+{
+public:
+  enum LCDFilter : int;
+  struct LCDFilterItem
+  {
+    int value;
+    QString displayName;
+  };
+
+  LCDFilterComboBoxModel();
+  ~LCDFilterComboBoxModel() = default;
+
+public:
+  enum LCDFilter
+  {
+    LCDFilter_Default,
+    LCDFilter_Light,
+    LCDFilter_None,
+    LCDFilter_Legacy
+  };
+};
+
+
+class AntiAliasingComboBoxModel
+: public SimpleComboBoxModel
+{
+public:
+  enum AntiAliasing : int;
+
+  AntiAliasingComboBoxModel();
+  ~AntiAliasingComboBoxModel() = default;
+  
+  QVariant data(const QModelIndex& index,
+                int role) const;
+  Qt::ItemFlags flags(const QModelIndex& index) const;
+
+  void setLightAntiAliasingEnabled(bool enabled)
+  {
+    lightAntiAliasingEnabled_ = enabled;
+  }
+
+private:
+  bool lightAntiAliasingEnabled_;
+
+public:
+  enum AntiAliasing
+  {
+    AntiAliasing_None,
+    AntiAliasing_Normal,
+    AntiAliasing_Light,
+    AntiAliasing_LCD,
+    AntiAliasing_LCD_BGR,
+    AntiAliasing_LCD_Vertical,
+    AntiAliasing_LCD_Vertical_BGR
+  };
+};
+
+
+// end of ttsettingscomboboxmodel.hpp



reply via email to

[Prev in Thread] Current Thread [Next in Thread]