freetype-commit
[Top][All Lists]
Advanced

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

[freetype2-demos] master 440920e 25/41: [ftinspect] Add "Comparator View


From: Werner Lemberg
Subject: [freetype2-demos] master 440920e 25/41: [ftinspect] Add "Comparator View".
Date: Mon, 3 Oct 2022 11:27:03 -0400 (EDT)

branch: master
commit 440920e175fa1df85785d7991932b9dac75ceb0e
Author: Charlie Jiang <w@chariri.moe>
Commit: Werner Lemberg <wl@gnu.org>

    [ftinspect] Add "Comparator View".
    
    * src/ftinspect/panels/comparator.cpp, src/ftinspect/panels/comparator.hpp:
      New files, adding the `ComparatorTab`.
    
    * src/ftinspect/panels/settingpanel.cpp,
      src/ftinspect/panels/settingpanel.hpp: Add comparator mode.
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp:
      Add comparator tab and modify `switchTab` to prevent unwanted window
      resizing, and to fix the tab bar position.
      Modify `applySettings` to skip applying for comparator tab.
    
    * src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
---
 src/ftinspect/CMakeLists.txt          |   1 +
 src/ftinspect/maingui.cpp             |  39 ++++-
 src/ftinspect/maingui.hpp             |   2 +
 src/ftinspect/meson.build             |   2 +
 src/ftinspect/panels/comparator.cpp   | 313 ++++++++++++++++++++++++++++++++++
 src/ftinspect/panels/comparator.hpp   |  73 ++++++++
 src/ftinspect/panels/settingpanel.cpp | 119 ++++++++++++-
 src/ftinspect/panels/settingpanel.hpp |  17 +-
 8 files changed, 556 insertions(+), 10 deletions(-)

diff --git a/src/ftinspect/CMakeLists.txt b/src/ftinspect/CMakeLists.txt
index ace3301..7f271a7 100644
--- a/src/ftinspect/CMakeLists.txt
+++ b/src/ftinspect/CMakeLists.txt
@@ -49,6 +49,7 @@ add_executable(ftinspect
   "panels/settingpanelmmgx.cpp"
   "panels/singular.cpp"
   "panels/continuous.cpp"
+  "panels/comparator.cpp"
   "panels/glyphdetails.cpp"
 )
 target_link_libraries(ftinspect
diff --git a/src/ftinspect/maingui.cpp b/src/ftinspect/maingui.cpp
index c08e01a..3aa7281 100644
--- a/src/ftinspect/maingui.cpp
+++ b/src/ftinspect/maingui.cpp
@@ -165,6 +165,33 @@ void
 MainGUI::switchTab()
 {
   auto current = tabWidget_->currentWidget();
+  auto isComparator = current == comparatorTab_;
+
+  if (isComparator)
+    tabWidget_->setStyleSheet(
+      QString("QTabWidget#mainTab::tab-bar {left: %1 px;}")
+      .arg(leftWidget_->width()));
+  else
+    tabWidget_->setStyleSheet("");
+  
+
+  if (!leftWidget_->isVisible() && !isComparator)
+  {
+    // Dirty approach here: When setting the left panel as visible, the main
+    // window will auto-expand. However, we don't want this behaviour.
+    // Doing `resize` right after the `setVisible` is useless since the
+    // layout updating is delayed, so we have to temporarily fix the main 
window
+    // size, and recover the original min/max size when finished.
+    auto minSize = minimumSize();
+    auto maxSize = maximumSize();
+    setFixedSize(size());
+    leftWidget_->setVisible(true);
+    setMinimumSize(minSize);
+    setMaximumSize(maxSize);
+  }
+  else
+    leftWidget_->setVisible(!isComparator);
+
   reloadCurrentTabFont();
 
   if (current == continuousTab_ && lastTab_ == singularTab_
@@ -202,7 +229,8 @@ MainGUI::repaintCurrentTab()
 void
 MainGUI::reloadCurrentTabFont()
 {
-  settingPanel_->applyDelayedSettings(); // This will reset the cache.
+  if (tabWidget_->currentWidget() != comparatorTab_)
+    settingPanel_->applyDelayedSettings(); // This will reset the cache.
   applySettings();
   auto index = tabWidget_->currentIndex();
   if (index >= 0 && static_cast<size_t>(index) < tabs_.size())
@@ -213,7 +241,8 @@ MainGUI::reloadCurrentTabFont()
 void
 MainGUI::applySettings()
 {
-  settingPanel_->applySettings();
+  if (tabWidget_->currentWidget() != comparatorTab_)
+    settingPanel_->applySettings();
 }
 
 
@@ -246,6 +275,7 @@ MainGUI::createLayout()
   singularTab_ = new SingularTab(this, engine_);
   continuousTab_ = new ContinuousTab(this, engine_,
                                      glyphDetailsDockWidget_, glyphDetails_);
+  comparatorTab_ = new ComparatorTab(this, engine_);
 
   tabWidget_ = new QTabWidget(this);
   tabWidget_->setObjectName("mainTab"); // for stylesheet
@@ -255,6 +285,8 @@ MainGUI::createLayout()
   tabWidget_->addTab(singularTab_, tr("Singular Grid View"));
   tabs_.push_back(continuousTab_);
   tabWidget_->addTab(continuousTab_, tr("Continuous View"));
+  tabs_.push_back(comparatorTab_);
+  tabWidget_->addTab(comparatorTab_, tr("Comparator View"));
   lastTab_ = singularTab_;
   
   tabWidget_->setTabToolTip(0, tr("View single glyph in grid view.\n"
@@ -262,6 +294,9 @@ MainGUI::createLayout()
   tabWidget_->setTabToolTip(1, tr("View a string of glyphs continuously.\n"
                                   "Show all glyphs in the font or render "
                                   "strings."));
+  tabWidget_->setTabToolTip(2, tr("Compare the output of the font "
+                                  "in different rendering settings "
+                                  "(e.g. hintings)."));
   tripletSelector_ = new TripletSelector(this, engine_);
 
   rightLayout_ = new QVBoxLayout;
diff --git a/src/ftinspect/maingui.hpp b/src/ftinspect/maingui.hpp
index d375231..d401382 100644
--- a/src/ftinspect/maingui.hpp
+++ b/src/ftinspect/maingui.hpp
@@ -11,6 +11,7 @@
 #include "panels/abstracttab.hpp"
 #include "panels/singular.hpp"
 #include "panels/continuous.hpp"
+#include "panels/comparator.hpp"
 #include "panels/glyphdetails.hpp"
 
 #include <vector>
@@ -93,6 +94,7 @@ private:
   std::vector<AbstractTab*> tabs_;
   SingularTab* singularTab_;
   ContinuousTab* continuousTab_;
+  ComparatorTab* comparatorTab_;
   QWidget* lastTab_ = NULL;
 
   QDockWidget* glyphDetailsDockWidget_;
diff --git a/src/ftinspect/meson.build b/src/ftinspect/meson.build
index 9167e8b..546ee5d 100644
--- a/src/ftinspect/meson.build
+++ b/src/ftinspect/meson.build
@@ -50,6 +50,7 @@ if qt5_dep.found()
     'panels/settingpanelmmgx.cpp',
     'panels/singular.cpp',
     'panels/continuous.cpp',
+    'panels/comparator.cpp',
     'panels/glyphdetails.cpp',
 
     'ftinspect.cpp',
@@ -73,6 +74,7 @@ if qt5_dep.found()
       'panels/settingpanelmmgx.hpp',
       'panels/singular.hpp',
       'panels/continuous.hpp',
+      'panels/comparator.hpp',
       'panels/glyphdetails.hpp',
     ],
     dependencies: qt5_dep)
diff --git a/src/ftinspect/panels/comparator.cpp 
b/src/ftinspect/panels/comparator.cpp
new file mode 100644
index 0000000..f1fae90
--- /dev/null
+++ b/src/ftinspect/panels/comparator.cpp
@@ -0,0 +1,313 @@
+// comparator.cpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#include "comparator.hpp"
+
+#include <QScrollBar>
+
+namespace
+{
+extern const char* ComparatorDefaultText;
+}
+
+ComparatorTab::ComparatorTab(QWidget* parent, Engine* engine)
+: QWidget(parent),
+  engine_(engine)
+{
+  createLayout();
+  createConnections();
+  setupCanvases();
+}
+
+
+ComparatorTab::~ComparatorTab()
+{
+}
+
+
+void
+ComparatorTab::repaintGlyph()
+{
+  sizeSelector_->applyToEngine(engine_);
+
+  int i = 0;
+  for (auto canvas : canvas_)
+  {
+    applySettings(i);
+    // No cache here, because when switching between columns, the hinting
+    // mode or enabling of embedded bitmaps may differ
+    canvas->stringRenderer().reloadGlyphs();
+    canvas->purgeCache();
+    canvas->repaint();
+    i++;
+  }
+}
+
+
+void
+ComparatorTab::reloadFont()
+{
+  {
+    QSignalBlocker blocker(sizeSelector_);
+    sizeSelector_->reloadFromFont(engine_); 
+  }
+  charMapSelector_->repopulate();
+  for (auto panel : settingPanels_)
+    panel->onFontChanged();
+
+  for (auto canvas : canvas_)
+    canvas->stringRenderer().reloadAll();
+  repaintGlyph();
+}
+
+
+bool
+ComparatorTab::eventFilter(QObject* watched,
+                           QEvent* event)
+{
+  auto ptr = qobject_cast<GlyphContinuous*>(watched);
+  if (ptr && event->type() == QEvent::Resize)
+    return true;
+  return QWidget::eventFilter(watched, event);
+}
+
+
+void
+ComparatorTab::resizeEvent(QResizeEvent* event)
+{
+  QWidget::resizeEvent(event);
+  forceEqualWidths();
+  repaintGlyph();
+}
+
+
+void
+ComparatorTab::createLayout()
+{
+  sizeSelector_ = new FontSizeSelector(this, true, true);
+  charMapLabel_ = new QLabel(tr("Char Map:"), this);
+  charMapSelector_ = new CharMapComboBox(this, engine_, false);
+  sourceTextEdit_ = new QPlainTextEdit(QString(ComparatorDefaultText), this);
+
+  sizeSelector_->installEventFilterForWidget(this);
+
+  for (int i = 0; i < ColumnWidth; ++i)
+  {
+    auto frame = new QFrame(this);
+    auto canvas = new GlyphContinuous(frame, engine_);
+    auto settingPanel = new SettingPanel(this, engine_, true);
+    settingPanel->setDefaultsPreset(i);
+
+    sizeSelector_->installEventFilterForWidget(canvas);
+
+    canvas->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+    settingPanel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
+
+    canvas_.emplace_back(canvas);
+    settingPanels_.emplace_back(settingPanel);
+    frames_.emplace_back(frame);
+
+    auto frameLayout = new QHBoxLayout;
+    frameLayout->addWidget(canvas);
+    frame->setLayout(frameLayout);
+    frame->setContentsMargins(2, 2, 2, 2);
+    frameLayout->setContentsMargins(2, 2, 2, 2);
+    frame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
+  }
+
+  sourceWidget_ = new QWidget(this);
+  sourceWidget_->setMaximumWidth(350);
+
+  // Tooltips
+  sourceTextEdit_->setToolTip(tr("Source text for previewing"));
+
+  // Layouting
+  layout_ = new QGridLayout;
+
+  sourceLayout_ = new QVBoxLayout;
+  sourceLayout_->addWidget(sizeSelector_);
+  sourceLayout_->addWidget(charMapLabel_);
+  sourceLayout_->addWidget(charMapSelector_);
+  sourceLayout_->addWidget(sourceTextEdit_, 1);
+  sourceWidget_->setLayout(sourceLayout_);
+
+  layout_->addWidget(sourceWidget_, 0, 0, 2, 1);
+  for (int i = 0; static_cast<unsigned>(i) < frames_.size(); ++i)
+    layout_->addWidget(frames_[i], 0, i + 1);
+  for (int i = 0; static_cast<unsigned>(i) < settingPanels_.size(); ++i)
+    layout_->addWidget(settingPanels_[i], 1, i + 1);
+
+  layout_->setRowStretch(0, 3);
+  layout_->setRowStretch(1, 2);
+
+  setLayout(layout_);
+
+  forceEqualWidths();
+}
+
+
+void
+ComparatorTab::createConnections()
+{
+  connect(sizeSelector_, &FontSizeSelector::valueChanged,
+          this, &ComparatorTab::reloadGlyphsAndRepaint);
+  connect(sourceTextEdit_, &QPlainTextEdit::textChanged,
+          this, &ComparatorTab::sourceTextChanged);
+  connect(charMapSelector_,
+          QOverload<int>::of(&CharMapComboBox::currentIndexChanged),
+          this, &ComparatorTab::reloadStringAndRepaint);
+
+  for (auto panel : settingPanels_)
+  {
+    // We're treating the two events identically, because we need to do a
+    // complete flush anyway
+    connect(panel, &SettingPanel::repaintNeeded,
+            this, &ComparatorTab::repaintGlyph);
+    connect(panel, &SettingPanel::fontReloadNeeded,
+            this, &ComparatorTab::repaintGlyph);
+  }
+
+  for (auto canvas : canvas_)
+  {
+    connect(canvas, &GlyphContinuous::wheelZoom,
+            this, &ComparatorTab::wheelZoom);
+    connect(canvas, &GlyphContinuous::wheelResize,
+            this, &ComparatorTab::wheelResize);
+  }
+}
+
+
+void
+ComparatorTab::setupCanvases()
+{
+  for (auto canvas : canvas_)
+  {
+    canvas->setMode(GlyphContinuous::M_Normal);
+    canvas->setSource(GlyphContinuous::SRC_TextStringRepeated);
+    canvas->setMouseOperationEnabled(false);
+    canvas->setSourceText(sourceTextEdit_->toPlainText());
+
+    canvas->installEventFilter(this);
+  }
+  sourceTextChanged();
+}
+
+
+void
+ComparatorTab::forceEqualWidths()
+{
+  if (canvas_.empty())
+    return;
+
+  // We need to keep the columns strictly equally wide, so we need to 
compensate
+  // the remainders when the tab width can't be evenly divided.
+  // Since the canvases are contained within QFrames, we can safely set fixed
+  // widths to them without messying up with the QGridLayout layouting.
+  // Using the first canvas as the reference width.
+  auto w = canvas_[0]->size().width();
+  for (int i = 1; static_cast<unsigned>(i) < canvas_.size(); ++i)
+    canvas_[i]->setFixedWidth(w);
+}
+
+
+void
+ComparatorTab::reloadStringAndRepaint()
+{
+  int i = 0;
+  for (auto canvas : canvas_)
+  {
+    applySettings(i);
+
+    auto& sr = canvas->stringRenderer();
+    sr.setCharMapIndex(charMapSelector_->currentCharMapIndex(), -1);
+    sr.reloadAll();
+    i++;
+  }
+  repaintGlyph();
+}
+
+
+void
+ComparatorTab::reloadGlyphsAndRepaint()
+{
+  int i = 0;
+  for (auto canvas : canvas_)
+  {
+    applySettings(i);
+    canvas->stringRenderer().reloadGlyphs();
+    i++;
+  }
+  repaintGlyph();
+}
+
+
+void
+ComparatorTab::sourceTextChanged()
+{
+  for (auto canvas : canvas_)
+    canvas->setSourceText(sourceTextEdit_->toPlainText());
+  reloadStringAndRepaint();
+}
+
+
+void
+ComparatorTab::applySettings(int index)
+{
+  if (index < 0 || static_cast<unsigned>(index) >= settingPanels_.size())
+    return;
+
+  auto settingPanel = settingPanels_[index];
+  settingPanel->applyDelayedSettings();
+  settingPanel->applySettings();
+
+  if (static_cast<unsigned>(index) >= canvas_.size())
+    return;
+
+  auto canvas = canvas_[index];
+  canvas->setScale(sizeSelector_->zoomFactor());
+  canvas->stringRenderer().setKerning(settingPanel->kerningEnabled());
+  canvas->stringRenderer().setLsbRsbDelta(settingPanel->lsbRsbDeltaEnabled());
+}
+
+
+void
+ComparatorTab::wheelResize(int steps)
+{
+  sizeSelector_->handleWheelResizeBySteps(steps);
+}
+
+
+void
+ComparatorTab::wheelZoom(int steps)
+{
+  sizeSelector_->handleWheelZoomBySteps(steps);
+}
+
+
+namespace
+{
+const char* ComparatorDefaultText
+    = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras sit amet"
+      " dui.  Nam sapien. Fusce vestibulum ornare metus. Maecenas ligula orci,"
+      " consequat vitae, dictum nec, lacinia non, elit. Aliquam iaculis"
+      " molestie neque. Maecenas suscipit felis ut pede convallis malesuada."
+      " Aliquam erat volutpat. Nunc pulvinar condimentum nunc. Donec ac sem 
vel"
+      " leo bibendum aliquam. Pellentesque habitant morbi tristique senectus 
et"
+      " netus et malesuada fames ac turpis egestas.\n"
+      "\n"
+      "Sed commodo. Nulla ut libero sit amet justo varius blandit. Mauris 
vitae"
+      " nulla eget lorem pretium ornare. Proin vulputate erat porta risus."
+      " Vestibulum malesuada, odio at vehicula lobortis, nisi metus hendrerit"
+      " est, vitae feugiat quam massa a ligula. Aenean in tellus. Praesent"
+      " convallis. Nullam vel lacus.  Aliquam congue erat non urna mollis"
+      " faucibus. Morbi vitae mauris faucibus quam condimentum ornare. Quisque"
+      " sit amet augue. Morbi ullamcorper mattis enim. Aliquam erat volutpat."
+      " Morbi nec felis non enim pulvinar lobortis.  Ut libero. Nullam id orci"
+      " quis nisl dapibus rutrum. Suspendisse consequat vulputate leo. Aenean"
+      " non orci non tellus iaculis vestibulum. Sed neque.\n"
+      "\n";
+}
+
+
+// end of comparator.cpp
diff --git a/src/ftinspect/panels/comparator.hpp 
b/src/ftinspect/panels/comparator.hpp
new file mode 100644
index 0000000..e3ab7fc
--- /dev/null
+++ b/src/ftinspect/panels/comparator.hpp
@@ -0,0 +1,73 @@
+// comparator.hpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#pragma once
+
+#include "abstracttab.hpp"
+#include "../engine/engine.hpp"
+#include "../widgets/customwidgets.hpp"
+#include "../widgets/charmapcombobox.hpp"
+#include "../widgets/fontsizeselector.hpp"
+#include "../panels/settingpanel.hpp"
+#include "../glyphcomponents/glyphcontinuous.hpp"
+
+#include <vector>
+
+#include <QWidget>
+#include <QFrame>
+#include <QLabel>
+#include <QGridLayout>
+#include <QBoxLayout>
+#include <QPlainTextEdit>
+
+class ComparatorTab
+: public QWidget, public AbstractTab
+{
+  Q_OBJECT
+public:
+  ComparatorTab(QWidget* parent, Engine* engine);
+  ~ComparatorTab() override;
+
+  void repaintGlyph() override;
+  void reloadFont() override;
+
+protected:
+  bool eventFilter(QObject* watched, QEvent* event) override;
+  void resizeEvent(QResizeEvent* event) override;
+
+private:
+  constexpr static int ColumnWidth = 3;
+
+  Engine* engine_;
+
+  FontSizeSelector* sizeSelector_;
+  QLabel* charMapLabel_;
+  CharMapComboBox* charMapSelector_;
+  QPlainTextEdit* sourceTextEdit_;
+
+  std::vector<GlyphContinuous*> canvas_;
+  std::vector<SettingPanel*> settingPanels_;
+  std::vector<QFrame*> frames_;
+
+  QWidget* sourceWidget_;
+
+  QVBoxLayout* sourceLayout_;
+  QGridLayout* layout_;
+
+  void createLayout();
+  void createConnections();
+  void setupCanvases();
+  void forceEqualWidths();
+
+  void reloadStringAndRepaint();
+  void reloadGlyphsAndRepaint();
+  void sourceTextChanged();
+  void applySettings(int index);
+
+  void wheelResize(int steps);
+  void wheelZoom(int steps);
+};
+
+
+// end of comparator.hpp
diff --git a/src/ftinspect/panels/settingpanel.cpp 
b/src/ftinspect/panels/settingpanel.cpp
index 403be29..3db0bde 100644
--- a/src/ftinspect/panels/settingpanel.cpp
+++ b/src/ftinspect/panels/settingpanel.cpp
@@ -12,9 +12,11 @@
 #include <freetype/config/ftoption.h>
 
 SettingPanel::SettingPanel(QWidget* parent,
-                           Engine* engine)
+                           Engine* engine,
+                           bool comparatorMode)
 : QWidget(parent),
-  engine_(engine)
+  engine_(engine),
+  comparatorMode_(comparatorMode)
 {
 #ifdef FT_DEBUG_AUTOFIT
   debugMode_ = !comparatorMode_;
@@ -49,6 +51,30 @@ SettingPanel::lsbRsbDeltaEnabled()
 }
 
 
+void
+SettingPanel::setDefaultsPreset(int preset)
+{
+  if (preset < 0)
+    preset = 0;
+  preset %= 3;
+  switch (preset)
+  {
+  case 0:
+    hintingCheckBox_->setChecked(true);
+    autoHintingCheckBox_->setChecked(false);
+    break;
+  case 1:
+    hintingCheckBox_->setChecked(true);
+    autoHintingCheckBox_->setChecked(true);
+    break;
+  case 2:
+    hintingCheckBox_->setChecked(false);
+    autoHintingCheckBox_->setChecked(false);
+    break;
+  }
+}
+
+
 void
 SettingPanel::checkAllSettings()
 {
@@ -286,8 +312,9 @@ SettingPanel::populatePalettes()
 void
 SettingPanel::onFontChanged()
 {
-  auto blockState = blockSignals(signalsBlocked());
-  
+  auto blockState = blockSignals(signalsBlocked() || comparatorMode_);
+
+  engine_->reloadFont();
   if (engine_->currentFontType() == Engine::FontType_CFF)
   {
     hintingModeComboBoxModel_->setCurrentEngineType(
@@ -429,6 +456,12 @@ SettingPanel::createLayout()
   embeddedBitmapCheckBox_ = new QCheckBox(tr("Enable Embedded Bitmap"), this);
   colorLayerCheckBox_ = new QCheckBox(tr("Enable Color Layer"), this);
 
+  if (comparatorMode_)
+  {
+    kerningCheckBox_ = new QCheckBox(tr("Kerning"), this);
+    lsbRsbDeltaCheckBox_ = new QCheckBox(tr("LSB/RSB Delta"), this);
+  }
+
   antiAliasingLabel_ = new QLabel(tr("Anti-Aliasing"), this);
   antiAliasingLabel_->setAlignment(Qt::AlignRight);
 
@@ -510,6 +543,14 @@ SettingPanel::createLayout()
   colorLayerCheckBox_->setToolTip(tr("Enable color layer rendering."));
   paletteComboBox_->setToolTip(tr("Select color layer palette (only valid when 
"
                                   "any palette exists in the font)."));
+  if (comparatorMode_)
+  {
+    kerningCheckBox_->setToolTip(
+      tr("Enable kerning (GPOS table not supported)."));
+    lsbRsbDeltaCheckBox_->setToolTip(
+      tr("Enable LSB/RSB delta positioning (only valid when hinting is "
+         "enabled)."));
+  }
   backgroundButton_->setToolTip(tr("Set canvas background color."));
   foregroundButton_->setToolTip(tr("Set text color."));
 
@@ -535,8 +576,10 @@ SettingPanel::createLayout()
   colorPickerLayout_->addWidget(foregroundButton_, 1);
   colorPickerLayout_->addWidget(foregroundBlock_);
 
-  createLayoutNormal();
-  // TODO: Comparator mode.
+  if (comparatorMode_)
+    createLayoutComparator();
+  else
+    createLayoutNormal();
 
   mainLayout_ = new QVBoxLayout;
   mainLayout_->addWidget(tab_);
@@ -595,6 +638,56 @@ SettingPanel::createLayoutNormal()
 }
 
 
+void
+SettingPanel::createLayoutComparator()
+{
+  hintingRenderingTab_ = new QWidget(this);
+
+  generalTabLayout_ = new QGridLayout;
+  hintingRenderingTabLayout_ = new QGridLayout;
+
+  // Hinting & Rendering
+  gridLayout2ColAddWidget(hintingRenderingTabLayout_, hintingCheckBox_);
+  gridLayout2ColAddWidget(hintingRenderingTabLayout_, 
+                          hintingModeLabel_, hintingModeComboBox_);
+  gridLayout2ColAddWidget(hintingRenderingTabLayout_, autoHintingCheckBox_);
+
+  if (debugMode_)
+    gridLayout2ColAddLayout(hintingRenderingTabLayout_, debugLayout_);
+
+  gridLayout2ColAddWidget(hintingRenderingTabLayout_, 
+                          antiAliasingLabel_, antiAliasingComboBox_);
+  gridLayout2ColAddWidget(hintingRenderingTabLayout_, 
+                          lcdFilterLabel_, lcdFilterComboBox_);
+
+  gridLayout2ColAddLayout(hintingRenderingTabLayout_, gammaLayout_);
+  gridLayout2ColAddWidget(hintingRenderingTabLayout_, stemDarkeningCheckBox_);
+
+  // General
+  gridLayout2ColAddLayout(generalTabLayout_, colorPickerLayout_);
+  gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
+  gridLayout2ColAddWidget(generalTabLayout_, colorLayerCheckBox_);
+  gridLayout2ColAddWidget(generalTabLayout_, 
+                          paletteLabel_, paletteComboBox_);
+
+  gridLayout2ColAddWidget(generalTabLayout_, kerningCheckBox_);
+  gridLayout2ColAddWidget(generalTabLayout_, lsbRsbDeltaCheckBox_);
+
+  generalTabLayout_->setColumnStretch(1, 1);
+  hintingRenderingTabLayout_->setColumnStretch(1, 1);
+  generalTab_->setLayout(generalTabLayout_);
+  hintingRenderingTab_->setLayout(hintingRenderingTabLayout_);
+
+  tab_->addTab(hintingRenderingTab_, tr("Hinting && Rendering"));
+  tab_->addTab(generalTab_, tr("General"));
+  tab_->addTab(mmgxPanel_, tr("MM/GX"));
+  tab_->setTabToolTip(0, tr("Settings about hinting and rendering."));
+  tab_->setTabToolTip(1, tr("General settings."));
+  tab_->setTabToolTip(2, tr("MM/GX axis parameters."));
+  setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
+}
+
+
 void
 SettingPanel::createConnections()
 {
@@ -639,6 +732,14 @@ SettingPanel::createConnections()
   connect(colorLayerCheckBox_, &QCheckBox::clicked,
           this, &SettingPanel::checkPalette);
 
+  if (comparatorMode_)
+  {
+    connect(kerningCheckBox_, &QCheckBox::clicked,
+            this, &SettingPanel::repaintNeeded);
+    connect(lsbRsbDeltaCheckBox_, &QCheckBox::clicked,
+            this, &SettingPanel::repaintNeeded);
+  }
+
   connect(backgroundButton_, &QPushButton::clicked,
           this, &SettingPanel::openBackgroundPicker);
   connect(foregroundButton_, &QPushButton::clicked,
@@ -686,6 +787,12 @@ SettingPanel::setDefaults()
   colorLayerCheckBox_->setChecked(true);
   paletteComboBox_->setEnabled(false);
 
+  if (comparatorMode_)
+  {
+    kerningCheckBox_->setChecked(true);
+    lsbRsbDeltaCheckBox_->setChecked(true);
+  }
+
   // These need to be set even in Comperator mode.
   backgroundColor_ = Qt::white;
   foregroundColor_ = Qt::black;
diff --git a/src/ftinspect/panels/settingpanel.hpp 
b/src/ftinspect/panels/settingpanel.hpp
index 418958e..12bdf57 100644
--- a/src/ftinspect/panels/settingpanel.hpp
+++ b/src/ftinspect/panels/settingpanel.hpp
@@ -22,7 +22,7 @@ class SettingPanel
 {
   Q_OBJECT
 public:
-  SettingPanel(QWidget* parent, Engine* engine);
+  SettingPanel(QWidget* parent, Engine* engine, bool comparatorMode = false);
   ~SettingPanel() override = default;
 
   void onFontChanged();
@@ -38,6 +38,7 @@ public:
   int antiAliasingModeIndex();
   bool kerningEnabled();
   bool lsbRsbDeltaEnabled();
+  void setDefaultsPreset(int preset);
 
 signals:
   void fontReloadNeeded();
@@ -48,7 +49,18 @@ private:
 
   int currentCFFHintingMode_;
   int currentTTInterpreterVersion_;
-  
+
+  /*
+   * There's two places where `SettingPanel` appears: On the left for most 
tabs,
+   * and on the bottom in the comparator for each column. Therefore,
+   * set `comparatorMode_` to `true` will change the panel for the Comparator
+   * View.
+   *
+   * In comparator view, some updating is suppressed during GUI events.
+   * Instead, updating was strictly passive called from the parent (comparator
+   * view).
+   */
+  bool comparatorMode_ = false;
   bool debugMode_ = false;
 
   QTabWidget* tab_;
@@ -107,6 +119,7 @@ private:
   void createConnections();
   void createLayout();
   void createLayoutNormal();
+  void createLayoutComparator();
   void setDefaults();
 
   //////// Other funcs



reply via email to

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