freetype-commit
[Top][All Lists]
Advanced

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

[Git][freetype/freetype-demos][gsoc-2022-chariri-final] 2 commits: [ftin


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-final] 2 commits: [ftinspect] WIP: Rewrite `MainGUI`.
Date: Sat, 03 Sep 2022 14:28:13 +0000

Charlie Jiang pushed to branch gsoc-2022-chariri-final at FreeType / FreeType Demo Programs

Commits:

  • 721eab6f
    by Charlie Jiang at 2022-09-02T21:18:01+08:00
    [ftinspect] WIP: Rewrite `MainGUI`.
    
    Note: This commit doesn't compile. This change is splitted into 2 commits
    to avoid a complicated diff.
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp: Old version removed.
    
  • 665ae2ef
    by Charlie Jiang at 2022-09-03T22:10:51+08:00
    [ftinspect] Rewrite `MainGUI`.
    
    Note: This commit compiles, but the main view is removed, so you will get a
    blank right panel. The singular view will be added back with major changes
    in the next commit.
    
    This commit mainly introduces below changes:
    
    1. The original `MainGUI` contains almost all GUI elements. Most of them are
       taken out to modular components. The current `MainGUI` serves only as
       a skeleton provides coordinate between components, greatly shortened.
       It also provides some auxiliary code such as calling to file chooser.
    2. The left panel is moved to `SettingPanel` class. The current
       `settingpanel.[ch]pp` are directly modified from the latest code, so they
       contains some options not implemented in the `Engine`.
       Structural code that is only added accompanying later change is removed,
       such as the comparator mode. Such code will be added back with the
       related feature. However, code for unimplemented options are simply
       commented out.
    3. The main part is transformed into a tabbed view. The original code is
       removed. Refactored, it will be added back in the next commit.
    4. The navigation buttons (Next/Prev Font/Face/NI) are changed into the new
       triplet-selector, which is a major UI improvement.
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp: As described.
    
    * src/ftinspect/panels/abstracttab.hpp: Add `AbstractTab` which is an
      interface for all tabs listening for font reloading and repainting.
    
    * src/ftinspect/panels/settingpanel.cpp,
      src/ftinspect/panels/settingpanel.hpp:
      As described, this is the left panel. This requires intensive reviewing
      since many bugs had rooted here.
    
    * src/ftinspect/widgets/tripletselector.cpp,
      src/ftinspect/widgets/tripletselector.hpp:
      As described, this is the triplet (Font/Subface/NI) selector.
      This component is also responsible for repopulating triplet information
      and keep up with the font file change (i.e. the
      `FontFileManager::currentFileChanged` event is captured here).
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `fontValid` and `namedInstanceName` since `TripletSelector` requires
      them. However, they'll subject to change later.
    
    * src/ftinspect/ftinspect.cpp: Remove call to `MainGUI::setDefaults`.
    
    * src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
    

12 changed files:

Changes:

  • src/ftinspect/CMakeLists.txt
    ... ... @@ -30,8 +30,11 @@ add_executable(ftinspect
    30 30
       "glyphcomponents/grid.cpp"
    
    31 31
     
    
    32 32
       "widgets/customwidgets.cpp"
    
    33
    +  "widgets/tripletselector.cpp"
    
    33 34
     
    
    34 35
       "models/customcomboboxmodels.cpp"
    
    36
    +
    
    37
    +  "panels/settingpanel.cpp"
    
    35 38
     )
    
    36 39
     target_link_libraries(ftinspect
    
    37 40
       Qt5::Core Qt5::Widgets
    

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -237,6 +237,50 @@ Engine::numberOfNamedInstances(int fontIndex,
    237 237
     }
    
    238 238
     
    
    239 239
     
    
    240
    +QString
    
    241
    +Engine::namedInstanceName(int fontIndex, long faceIndex, int index)
    
    242
    +{
    
    243
    +  if (fontIndex < 0)
    
    244
    +    return {};
    
    245
    +
    
    246
    +  FT_Face face;
    
    247
    +  QString name;
    
    248
    +
    
    249
    +  // search triplet (fontIndex, faceIndex, index)
    
    250
    +  FTC_FaceID ftcFaceID = reinterpret_cast<FTC_FaceID>
    
    251
    +                           (faceIDMap_.value(FaceID(fontIndex,
    
    252
    +                                                    faceIndex,
    
    253
    +                                                    index)));
    
    254
    +  if (ftcFaceID)
    
    255
    +  {
    
    256
    +    // found
    
    257
    +    if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
    
    258
    +      name = QString("%1 %2")
    
    259
    +               .arg(face->family_name)
    
    260
    +               .arg(face->style_name);
    
    261
    +  }
    
    262
    +  else
    
    263
    +  {
    
    264
    +    // not found; try to load triplet (fontIndex, faceIndex, index)
    
    265
    +    ftcFaceID = reinterpret_cast<FTC_FaceID>(faceCounter_);
    
    266
    +    faceIDMap_.insert(FaceID(fontIndex, faceIndex, index),
    
    267
    +                      faceCounter_++);
    
    268
    +
    
    269
    +    if (!FTC_Manager_LookupFace(cacheManager_, ftcFaceID, &face))
    
    270
    +      name = QString("%1 %2")
    
    271
    +               .arg(face->family_name)
    
    272
    +               .arg(face->style_name);
    
    273
    +    else
    
    274
    +    {
    
    275
    +      faceIDMap_.remove(FaceID(fontIndex, faceIndex, 0));
    
    276
    +      faceCounter_--;
    
    277
    +    }
    
    278
    +  }
    
    279
    +
    
    280
    +  return name;
    
    281
    +}
    
    282
    +
    
    283
    +
    
    240 284
     int
    
    241 285
     Engine::loadFont(int fontIndex,
    
    242 286
                      long faceIndex,
    
    ... ... @@ -394,6 +438,14 @@ Engine::numberOfOpenedFonts()
    394 438
     }
    
    395 439
     
    
    396 440
     
    
    441
    +bool
    
    442
    +Engine::fontValid()
    
    443
    +{
    
    444
    +  // TODO: use fallback font
    
    445
    +  return ftSize_ != NULL;
    
    446
    +}
    
    447
    +
    
    448
    +
    
    397 449
     void
    
    398 450
     Engine::openFonts(QStringList fontFileNames)
    
    399 451
     {
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -85,6 +85,7 @@ public:
    85 85
       int numberOfOpenedFonts();
    
    86 86
     
    
    87 87
       // (for current fonts)
    
    88
    +  bool fontValid();
    
    88 89
       int currentFontType() const { return fontType_; }
    
    89 90
       const QString& currentFamilyName() { return curFamilyName_; }
    
    90 91
       const QString& currentStyleName() { return curStyleName_; }
    
    ... ... @@ -92,6 +93,7 @@ public:
    92 93
       long numberOfFaces(int fontIndex);
    
    93 94
       int numberOfNamedInstances(int fontIndex,
    
    94 95
                                  long faceIndex);
    
    96
    +  QString namedInstanceName(int fontIndex, long faceIndex, int index);
    
    95 97
     
    
    96 98
       //////// Setters (direct or indirect)
    
    97 99
     
    

  • src/ftinspect/ftinspect.cpp
    ... ... @@ -23,7 +23,6 @@ main(int argc,
    23 23
     
    
    24 24
       Engine engine;
    
    25 25
       MainGUI gui(&engine);
    
    26
    -  gui.setDefaults();
    
    27 26
     
    
    28 27
       gui.show();
    
    29 28
     
    

  • src/ftinspect/maingui.cpp
    ... ... @@ -4,30 +4,27 @@
    4 4
     
    
    5 5
     
    
    6 6
     #include "maingui.hpp"
    
    7
    -#include "glyphcomponents/grid.hpp"
    
    8
    -#include "uihelper.hpp"
    
    9 7
     
    
    10 8
     #include <QApplication>
    
    11 9
     #include <QFileDialog>
    
    12 10
     #include <QMessageBox>
    
    13 11
     #include <QSettings>
    
    14
    -
    
    15
    -#include <freetype/ftdriver.h>
    
    12
    +#include <QScrollBar>
    
    13
    +#include <QStatusBar>
    
    16 14
     
    
    17 15
     
    
    18 16
     MainGUI::MainGUI(Engine* engine)
    
    19 17
     : engine_(engine)
    
    20 18
     {
    
    21
    -  setGraphicsDefaults();
    
    22 19
       createLayout();
    
    23 20
       createConnections();
    
    24 21
       createActions();
    
    25 22
       createMenus();
    
    26
    -  createStatusBar();
    
    27 23
     
    
    28 24
       readSettings();
    
    29
    -
    
    30 25
       setUnifiedTitleAndToolBarOnMac(true);
    
    26
    +
    
    27
    +  show();
    
    31 28
     }
    
    32 29
     
    
    33 30
     
    
    ... ... @@ -47,6 +44,15 @@ MainGUI::closeEvent(QCloseEvent* event)
    47 44
     }
    
    48 45
     
    
    49 46
     
    
    47
    +void
    
    48
    +MainGUI::keyPressEvent(QKeyEvent* event)
    
    49
    +{
    
    50
    +  // Delegate key events to tabs
    
    51
    +  if (!tabWidget_->currentWidget()->eventFilter(this, event))
    
    52
    +    QMainWindow::keyPressEvent(event);
    
    53
    +}
    
    54
    +
    
    55
    +
    
    50 56
     void
    
    51 57
     MainGUI::about()
    
    52 58
     {
    
    ... ... @@ -81,8 +87,6 @@ MainGUI::aboutQt()
    81 87
     void
    
    82 88
     MainGUI::loadFonts()
    
    83 89
     {
    
    84
    -  int oldSize = engine_->numberOfOpenedFonts();
    
    85
    -
    
    86 90
       QStringList files = QFileDialog::getOpenFileNames(
    
    87 91
                             this,
    
    88 92
                             tr("Load one or more fonts"),
    
    ... ... @@ -90,630 +94,60 @@ MainGUI::loadFonts()
    90 94
                             "",
    
    91 95
                             NULL,
    
    92 96
                             QFileDialog::ReadOnly);
    
    93
    -
    
    94
    -  engine_->openFonts(files);
    
    95
    -
    
    96
    -  // if we have new fonts, set the current index to the first new one
    
    97
    -  if (oldSize < engine_->numberOfOpenedFonts())
    
    98
    -    currentFontIndex_ = oldSize;
    
    99
    -
    
    100
    -  showFont();
    
    101
    -}
    
    102
    -
    
    103
    -
    
    104
    -void
    
    105
    -MainGUI::closeFont()
    
    106
    -{
    
    107
    -  if (currentFontIndex_ < engine_->numberOfOpenedFonts())
    
    108
    -  {
    
    109
    -    engine_->removeFont(currentFontIndex_);
    
    110
    -  }
    
    111
    -
    
    112
    -  // show next font after deletion, i.e., retain index if possible
    
    113
    -  int num = engine_->numberOfOpenedFonts();
    
    114
    -  if (num)
    
    115
    -  {
    
    116
    -    if (currentFontIndex_ >= num)
    
    117
    -      currentFontIndex_ = num - 1;
    
    118
    -  }
    
    119
    -  else
    
    120
    -    currentFontIndex_ = 0;
    
    121
    -
    
    122
    -  showFont();
    
    123
    -}
    
    124
    -
    
    125
    -
    
    126
    -void
    
    127
    -MainGUI::watchCurrentFont()
    
    128
    -{
    
    129
    -  showFont();
    
    130
    -}
    
    131
    -
    
    132
    -
    
    133
    -void
    
    134
    -MainGUI::showFont()
    
    135
    -{
    
    136
    -  // we do lazy computation of FT_Face objects
    
    137
    -
    
    138
    -  if (currentFontIndex_ < engine_->numberOfOpenedFonts())
    
    139
    -  {
    
    140
    -    QFileInfo& fileInfo = engine_->fontFileManager()[currentFontIndex_];
    
    141
    -    QString fontName = fileInfo.fileName();
    
    142
    -
    
    143
    -    engine_->fontFileManager().updateWatching(currentFontIndex_);
    
    144
    -    if (fileInfo.isSymLink())
    
    145
    -    {
    
    146
    -      fontName.prepend("<i>");
    
    147
    -      fontName.append("</i>");
    
    148
    -    }
    
    149
    -
    
    150
    -    if (!fileInfo.exists())
    
    151
    -    {
    
    152
    -      // On Unix-like systems, the symlink's target gets opened; this
    
    153
    -      // implies that deletion of a symlink doesn't make `engine->loadFont'
    
    154
    -      // fail since it operates on a file handle pointing to the target.
    
    155
    -      // For this reason, we remove the font to enforce a reload.
    
    156
    -      // However, we're just removing it from the Engine cache,
    
    157
    -      // not deleting the entry in the font file manager
    
    158
    -      engine_->removeFont(currentFontIndex_, false);
    
    159
    -    }
    
    160
    -
    
    161
    -    fontFilenameLabel_->setText(fontName);
    
    162
    -  }
    
    163
    -  else
    
    164
    -    fontFilenameLabel_->clear();
    
    165
    -
    
    166
    -  applySettings();
    
    167
    -  currentNumberOfFaces_
    
    168
    -    = engine_->numberOfFaces(currentFontIndex_);
    
    169
    -  currentNumberOfNamedInstances_
    
    170
    -    = engine_->numberOfNamedInstances(currentFontIndex_,
    
    171
    -                                     currentFaceIndex_);
    
    172
    -  currentNumberOfGlyphs_
    
    173
    -    = engine_->loadFont(currentFontIndex_,
    
    174
    -                       currentFaceIndex_,
    
    175
    -                       currentNamedInstanceIndex_);
    
    176
    -
    
    177
    -  if (currentNumberOfGlyphs_ < 0)
    
    178
    -  {
    
    179
    -    // there might be various reasons why the current
    
    180
    -    // (file, face, instance) triplet is invalid or missing;
    
    181
    -    // we thus start our timer to periodically test
    
    182
    -    // whether the font starts working
    
    183
    -    if (currentFontIndex_ > 0
    
    184
    -        && currentFontIndex_ < engine_->numberOfOpenedFonts())
    
    185
    -      engine_->fontFileManager().timerStart();
    
    186
    -  }
    
    187
    -
    
    188
    -  fontNameLabel_->setText(QString("%1 %2")
    
    189
    -                         .arg(engine_->currentFamilyName())
    
    190
    -                         .arg(engine_->currentStyleName()));
    
    191
    -
    
    192
    -  checkCurrentFontIndex();
    
    193
    -  checkCurrentFaceIndex();
    
    194
    -  checkCurrentNamedInstanceIndex();
    
    195
    -  checkHinting();
    
    196
    -  adjustGlyphIndex(0);
    
    197
    -
    
    198
    -  drawGlyph();
    
    199
    -}
    
    200
    -
    
    201
    -
    
    202
    -void
    
    203
    -MainGUI::applySettings()
    
    204
    -{
    
    205
    -  // Spinbox value cannot become negative
    
    206
    -  engine_->setDPI(static_cast<unsigned int>(dpiSpinBox_->value()));
    
    207
    -
    
    208
    -  if (unitsComboBox_->currentIndex() == Units_px)
    
    209
    -    engine_->setSizeByPixel(sizeDoubleSpinBox_->value());
    
    210
    -  else
    
    211
    -    engine_->setSizeByPoint(sizeDoubleSpinBox_->value());
    
    212
    -
    
    213
    -  engine_->setHinting(hintingCheckBox_->isChecked());
    
    214
    -  engine_->setAutoHinting(autoHintingCheckBox_->isChecked());
    
    215
    -  engine_->setHorizontalHinting(horizontalHintingCheckBox_->isChecked());
    
    216
    -  engine_->setVerticalHinting(verticalHintingCheckBox_->isChecked());
    
    217
    -  engine_->setBlueZoneHinting(blueZoneHintingCheckBox_->isChecked());
    
    218
    -  engine_->setShowSegments(segmentDrawingCheckBox_->isChecked());
    
    219
    -
    
    220
    -  engine_->setGamma(gammaSlider_->value());
    
    221
    -
    
    222
    -  engine_->setAntiAliasingTarget(
    
    223
    -    antiAliasingComboBoxModel_
    
    224
    -      ->indexToValue(antiAliasingComboBox_->currentIndex())
    
    225
    -      .loadFlag);
    
    226
    -}
    
    227
    -
    
    228
    -
    
    229
    -void
    
    230
    -MainGUI::clearStatusBar()
    
    231
    -{
    
    232
    -  statusBar()->clearMessage();
    
    233
    -  statusBar()->setStyleSheet("");
    
    234
    -}
    
    235
    -
    
    236
    -
    
    237
    -void
    
    238
    -MainGUI::checkHinting()
    
    239
    -{
    
    240
    -  if (hintingCheckBox_->isChecked())
    
    241
    -  {
    
    242
    -    if (engine_->currentFontType() == Engine::FontType_CFF)
    
    243
    -    {
    
    244
    -      hintingModeComboBoxModel_->setCurrentEngineType(
    
    245
    -        HintingModeComboBoxModel::HintingEngineType_CFF, false); // XXX tricky
    
    246
    -      hintingModeComboBox_->setCurrentIndex(currentCFFHintingMode_);
    
    247
    -    }
    
    248
    -    else if (engine_->currentFontType() == Engine::FontType_TrueType)
    
    249
    -    {
    
    250
    -      hintingModeComboBoxModel_->setCurrentEngineType( // XXX tricky
    
    251
    -        HintingModeComboBoxModel::HintingEngineType_TrueType, false);
    
    252
    -      hintingModeComboBox_->setCurrentIndex(currentTTInterpreterVersion_);
    
    253
    -    }
    
    254
    -    else
    
    255
    -    {
    
    256
    -      hintingModeLabel_->setEnabled(false);
    
    257
    -      hintingModeComboBox_->setEnabled(false);
    
    258
    -    }
    
    259
    -
    
    260
    -    autoHintingCheckBox_->setEnabled(true);
    
    261
    -    checkAutoHinting();
    
    262
    -  }
    
    263
    -  else
    
    264
    -  {
    
    265
    -    hintingModeLabel_->setEnabled(false);
    
    266
    -    hintingModeComboBox_->setEnabled(false);
    
    267
    -
    
    268
    -    autoHintingCheckBox_->setEnabled(false);
    
    269
    -    horizontalHintingCheckBox_->setEnabled(false);
    
    270
    -    verticalHintingCheckBox_->setEnabled(false);
    
    271
    -    blueZoneHintingCheckBox_->setEnabled(false);
    
    272
    -    segmentDrawingCheckBox_->setEnabled(false);
    
    273
    -
    
    274
    -    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    275
    -    if (antiAliasingComboBox_->currentIndex()
    
    276
    -      == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    277
    -      antiAliasingComboBox_->setCurrentIndex(
    
    278
    -        AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    279
    -  }
    
    280
    -
    
    281
    -  drawGlyph();
    
    282
    -}
    
    283
    -
    
    284
    -
    
    285
    -void
    
    286
    -MainGUI::checkHintingMode()
    
    287
    -{
    
    288
    -  int index = hintingModeComboBox_->currentIndex();
    
    289
    -
    
    290
    -  if (engine_->currentFontType() == Engine::FontType_CFF)
    
    291
    -  {
    
    292
    -    engine_->setCFFHintingMode(
    
    293
    -      hintingModeComboBoxModel_->indexToCFFMode(index));
    
    294
    -    currentCFFHintingMode_ = index;
    
    295
    -  }
    
    296
    -  else if (engine_->currentFontType() == Engine::FontType_TrueType)
    
    297
    -  {
    
    298
    -    engine_->setTTInterpreterVersion(
    
    299
    -      hintingModeComboBoxModel_->indexToTTInterpreterVersion(index));
    
    300
    -    currentTTInterpreterVersion_ = index;
    
    301
    -  }
    
    302
    -
    
    303
    -  // this enforces reloading of the font
    
    304
    -  showFont();
    
    305
    -}
    
    306
    -
    
    307
    -
    
    308
    -void
    
    309
    -MainGUI::checkAutoHinting()
    
    310
    -{
    
    311
    -  if (autoHintingCheckBox_->isChecked())
    
    312
    -  {
    
    313
    -    hintingModeLabel_->setEnabled(false);
    
    314
    -    hintingModeComboBox_->setEnabled(false);
    
    315
    -
    
    316
    -    horizontalHintingCheckBox_->setEnabled(true);
    
    317
    -    verticalHintingCheckBox_->setEnabled(true);
    
    318
    -    blueZoneHintingCheckBox_->setEnabled(true);
    
    319
    -    segmentDrawingCheckBox_->setEnabled(true);
    
    320
    -
    
    321
    -    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(true);
    
    322
    -  }
    
    323
    -  else
    
    324
    -  {
    
    325
    -    if (engine_->currentFontType() == Engine::FontType_CFF
    
    326
    -        || engine_->currentFontType() == Engine::FontType_TrueType)
    
    327
    -    {
    
    328
    -      hintingModeLabel_->setEnabled(true);
    
    329
    -      hintingModeComboBox_->setEnabled(true);
    
    330
    -    }
    
    331
    -
    
    332
    -    horizontalHintingCheckBox_->setEnabled(false);
    
    333
    -    verticalHintingCheckBox_->setEnabled(false);
    
    334
    -    blueZoneHintingCheckBox_->setEnabled(false);
    
    335
    -    segmentDrawingCheckBox_->setEnabled(false);
    
    336
    -
    
    337
    -    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    338
    -
    
    339
    -    if (antiAliasingComboBox_->currentIndex()
    
    340
    -        == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    341
    -      antiAliasingComboBox_->setCurrentIndex(
    
    342
    -          AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    343
    -  }
    
    344
    -
    
    345
    -  drawGlyph();
    
    346
    -}
    
    347
    -
    
    348
    -
    
    349
    -void
    
    350
    -MainGUI::checkAntiAliasing()
    
    351
    -{
    
    352
    -  int index = antiAliasingComboBox_->currentIndex();
    
    353
    -
    
    354
    -  if (index == AntiAliasingComboBoxModel::AntiAliasing_None
    
    355
    -      || index == AntiAliasingComboBoxModel::AntiAliasing_Normal
    
    356
    -      || index == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    357
    -  {
    
    358
    -    lcdFilterLabel_->setEnabled(false);
    
    359
    -    lcdFilterComboBox_->setEnabled(false);
    
    360
    -  }
    
    361
    -  else
    
    362
    -  {
    
    363
    -    lcdFilterLabel_->setEnabled(true);
    
    364
    -    lcdFilterComboBox_->setEnabled(true);
    
    365
    -  }
    
    366
    -
    
    367
    -  drawGlyph();
    
    368
    -}
    
    369
    -
    
    370
    -
    
    371
    -void
    
    372
    -MainGUI::checkLcdFilter()
    
    373
    -{
    
    374
    -  int index = lcdFilterComboBox_->currentIndex();
    
    375
    -  engine_->setLcdFilter(static_cast<FT_LcdFilter>(
    
    376
    -    lcdFilterComboboxModel_->indexToValue(index)));
    
    377
    -}
    
    378
    -
    
    379
    -
    
    380
    -void
    
    381
    -MainGUI::checkShowPoints()
    
    382
    -{
    
    383
    -  if (showPointsCheckBox_->isChecked())
    
    384
    -    showPointNumbersCheckBox_->setEnabled(true);
    
    385
    -  else
    
    386
    -    showPointNumbersCheckBox_->setEnabled(false);
    
    387
    -
    
    388
    -  drawGlyph();
    
    389
    -}
    
    390
    -
    
    391
    -
    
    392
    -void
    
    393
    -MainGUI::checkUnits()
    
    394
    -{
    
    395
    -  int index = unitsComboBox_->currentIndex();
    
    396
    -
    
    397
    -  if (index == Units_px)
    
    398
    -  {
    
    399
    -    dpiLabel_->setEnabled(false);
    
    400
    -    dpiSpinBox_->setEnabled(false);
    
    401
    -    sizeDoubleSpinBox_->setSingleStep(1);
    
    402
    -    sizeDoubleSpinBox_->setValue(qRound(sizeDoubleSpinBox_->value()));
    
    403
    -  }
    
    404
    -  else
    
    405
    -  {
    
    406
    -    dpiLabel_->setEnabled(true);
    
    407
    -    dpiSpinBox_->setEnabled(true);
    
    408
    -    sizeDoubleSpinBox_->setSingleStep(0.5);
    
    409
    -  }
    
    410
    -
    
    411
    -  drawGlyph();
    
    412
    -}
    
    413
    -
    
    414
    -
    
    415
    -void
    
    416
    -MainGUI::adjustGlyphIndex(int delta)
    
    417
    -{
    
    418
    -  // only adjust current glyph index if we have a valid font
    
    419
    -  if (currentNumberOfGlyphs_ > 0)
    
    420
    -  {
    
    421
    -    currentGlyphIndex_ += delta;
    
    422
    -    currentGlyphIndex_ = qBound(0,
    
    423
    -                               currentGlyphIndex_,
    
    424
    -                               currentNumberOfGlyphs_ - 1);
    
    425
    -  }
    
    426
    -
    
    427
    -  QString upperHex = QString::number(currentGlyphIndex_, 16).toUpper();
    
    428
    -  glyphIndexLabel_->setText(QString("%1 (0x%2)")
    
    429
    -                                   .arg(currentGlyphIndex_)
    
    430
    -                                   .arg(upperHex));
    
    431
    -  glyphNameLabel_->setText(engine_->glyphName(currentGlyphIndex_));
    
    432
    -
    
    433
    -  drawGlyph();
    
    97
    +  openFonts(files);
    
    434 98
     }
    
    435 99
     
    
    436 100
     
    
    437 101
     void
    
    438
    -MainGUI::checkCurrentFontIndex()
    
    102
    +MainGUI::openFonts(QStringList const& fileNames)
    
    439 103
     {
    
    440
    -  if (engine_->numberOfOpenedFonts() < 2)
    
    441
    -  {
    
    442
    -    previousFontButton_->setEnabled(false);
    
    443
    -    nextFontButton_->setEnabled(false);
    
    444
    -  }
    
    445
    -  else if (currentFontIndex_ == 0)
    
    446
    -  {
    
    447
    -    previousFontButton_->setEnabled(false);
    
    448
    -    nextFontButton_->setEnabled(true);
    
    449
    -  }
    
    450
    -  else if (currentFontIndex_ >= engine_->numberOfOpenedFonts() - 1)
    
    451
    -  {
    
    452
    -    previousFontButton_->setEnabled(true);
    
    453
    -    nextFontButton_->setEnabled(false);
    
    454
    -  }
    
    455
    -  else
    
    456
    -  {
    
    457
    -    previousFontButton_->setEnabled(true);
    
    458
    -    nextFontButton_->setEnabled(true);
    
    459
    -  }
    
    104
    +  engine_->openFonts(fileNames);
    
    105
    +  tripletSelector_->repopulateFonts();
    
    460 106
     }
    
    461 107
     
    
    462 108
     
    
    463 109
     void
    
    464
    -MainGUI::checkCurrentFaceIndex()
    
    110
    +MainGUI::onTripletChanged()
    
    465 111
     {
    
    466
    -  if (currentNumberOfFaces_ < 2)
    
    467
    -  {
    
    468
    -    previousFaceButton_->setEnabled(false);
    
    469
    -    nextFaceButton_->setEnabled(false);
    
    470
    -  }
    
    471
    -  else if (currentFaceIndex_ == 0)
    
    472
    -  {
    
    473
    -    previousFaceButton_->setEnabled(false);
    
    474
    -    nextFaceButton_->setEnabled(true);
    
    475
    -  }
    
    476
    -  else if (currentFaceIndex_ >= currentNumberOfFaces_ - 1)
    
    477
    -  {
    
    478
    -    previousFaceButton_->setEnabled(true);
    
    479
    -    nextFaceButton_->setEnabled(false);
    
    480
    -  }
    
    481
    -  else
    
    482
    -  {
    
    483
    -    previousFaceButton_->setEnabled(true);
    
    484
    -    nextFaceButton_->setEnabled(true);
    
    485
    -  }
    
    112
    +  auto state = settingPanel_->blockSignals(true);
    
    113
    +  settingPanel_->onFontChanged();
    
    114
    +  settingPanel_->blockSignals(state);
    
    115
    +  reloadCurrentTabFont();
    
    486 116
     }
    
    487 117
     
    
    488 118
     
    
    489 119
     void
    
    490
    -MainGUI::checkCurrentNamedInstanceIndex()
    
    120
    +MainGUI::switchTab()
    
    491 121
     {
    
    492
    -  if (currentNumberOfNamedInstances_ < 2)
    
    493
    -  {
    
    494
    -    previousNamedInstanceButton_->setEnabled(false);
    
    495
    -    nextNamedInstanceButton_->setEnabled(false);
    
    496
    -  }
    
    497
    -  else if (currentNamedInstanceIndex_ == 0)
    
    498
    -  {
    
    499
    -    previousNamedInstanceButton_->setEnabled(false);
    
    500
    -    nextNamedInstanceButton_->setEnabled(true);
    
    501
    -  }
    
    502
    -  else if (currentNamedInstanceIndex_ >= currentNumberOfNamedInstances_ - 1)
    
    503
    -  {
    
    504
    -    previousNamedInstanceButton_->setEnabled(true);
    
    505
    -    nextNamedInstanceButton_->setEnabled(false);
    
    506
    -  }
    
    507
    -  else
    
    508
    -  {
    
    509
    -    previousNamedInstanceButton_->setEnabled(true);
    
    510
    -    nextNamedInstanceButton_->setEnabled(true);
    
    511
    -  }
    
    122
    +  reloadCurrentTabFont();
    
    123
    +  lastTab_ = tabWidget_->currentWidget();
    
    512 124
     }
    
    513 125
     
    
    514 126
     
    
    515 127
     void
    
    516
    -MainGUI::previousFont()
    
    128
    +MainGUI::repaintCurrentTab()
    
    517 129
     {
    
    518
    -  if (currentFontIndex_ > 0)
    
    519
    -  {
    
    520
    -    currentFontIndex_--;
    
    521
    -    currentFaceIndex_ = 0;
    
    522
    -    currentNamedInstanceIndex_ = 0;
    
    523
    -    showFont();
    
    524
    -  }
    
    525
    -}
    
    526
    -
    
    527
    -
    
    528
    -void
    
    529
    -MainGUI::nextFont()
    
    530
    -{
    
    531
    -  if (currentFontIndex_ < engine_->numberOfOpenedFonts() - 1)
    
    532
    -  {
    
    533
    -    currentFontIndex_++;
    
    534
    -    currentFaceIndex_ = 0;
    
    535
    -    currentNamedInstanceIndex_ = 0;
    
    536
    -    showFont();
    
    537
    -  }
    
    538
    -}
    
    539
    -
    
    540
    -
    
    541
    -void
    
    542
    -MainGUI::previousFace()
    
    543
    -{
    
    544
    -  if (currentFaceIndex_ > 0)
    
    545
    -  {
    
    546
    -    currentFaceIndex_--;
    
    547
    -    currentNamedInstanceIndex_ = 0;
    
    548
    -    showFont();
    
    549
    -  }
    
    550
    -}
    
    551
    -
    
    552
    -
    
    553
    -void
    
    554
    -MainGUI::nextFace()
    
    555
    -{
    
    556
    -  if (currentFaceIndex_ < currentNumberOfFaces_ - 1)
    
    557
    -  {
    
    558
    -    currentFaceIndex_++;
    
    559
    -    currentNamedInstanceIndex_ = 0;
    
    560
    -    showFont();
    
    561
    -  }
    
    562
    -}
    
    563
    -
    
    564
    -
    
    565
    -void
    
    566
    -MainGUI::previousNamedInstance()
    
    567
    -{
    
    568
    -  if (currentNamedInstanceIndex_ > 0)
    
    569
    -  {
    
    570
    -    currentNamedInstanceIndex_--;
    
    571
    -    showFont();
    
    572
    -  }
    
    573
    -}
    
    574
    -
    
    575
    -
    
    576
    -void
    
    577
    -MainGUI::nextNamedInstance()
    
    578
    -{
    
    579
    -  if (currentNamedInstanceIndex_ < currentNumberOfNamedInstances_ - 1)
    
    580
    -  {
    
    581
    -    currentNamedInstanceIndex_++;
    
    582
    -    showFont();
    
    583
    -  }
    
    584
    -}
    
    585
    -
    
    586
    -
    
    587
    -void
    
    588
    -MainGUI::zoom()
    
    589
    -{
    
    590
    -  int scale = static_cast<int>(zoomSpinBox_->value());
    
    591
    -
    
    592
    -  QTransform transform;
    
    593
    -  transform.scale(scale, scale);
    
    594
    -
    
    595
    -  // we want horizontal and vertical 1px lines displayed with full pixels;
    
    596
    -  // we thus have to shift the coordinate system accordingly, using a value
    
    597
    -  // that represents 0.5px (i.e., half the 1px line width) after the scaling
    
    598
    -  qreal shift = 0.5 / scale;
    
    599
    -  transform.translate(shift, shift);
    
    600
    -
    
    601
    -  glyphView_->setTransform(transform);
    
    130
    +  applySettings();
    
    131
    +  tabs_[tabWidget_->currentIndex()]->repaintGlyph();
    
    602 132
     }
    
    603 133
     
    
    604 134
     
    
    605 135
     void
    
    606
    -MainGUI::setGraphicsDefaults()
    
    136
    +MainGUI::reloadCurrentTabFont()
    
    607 137
     {
    
    608
    -  // color tables (with suitable opacity values) for converting
    
    609
    -  // FreeType's pixmaps to something Qt understands
    
    610
    -  monoColorTable_.append(QColor(Qt::transparent).rgba());
    
    611
    -  monoColorTable_.append(QColor(Qt::black).rgba());
    
    612
    -
    
    613
    -  for (int i = 0xFF; i >= 0; i--)
    
    614
    -    grayColorTable_.append(qRgba(i, i, i, 0xFF - i));
    
    615
    -
    
    616
    -  // XXX make this user-configurable
    
    617
    -
    
    618
    -  axisPen_.setColor(Qt::black);
    
    619
    -  axisPen_.setWidth(0);
    
    620
    -  blueZonePen_.setColor(QColor(64, 64, 255, 64)); // light blue
    
    621
    -  blueZonePen_.setWidth(0);
    
    622
    -  gridPen_.setColor(Qt::lightGray);
    
    623
    -  gridPen_.setWidth(0);
    
    624
    -  offPen_.setColor(Qt::darkGreen);
    
    625
    -  offPen_.setWidth(3);
    
    626
    -  onPen_.setColor(Qt::red);
    
    627
    -  onPen_.setWidth(3);
    
    628
    -  outlinePen_.setColor(Qt::red);
    
    629
    -  outlinePen_.setWidth(0);
    
    630
    -  segmentPen_.setColor(QColor(64, 255, 128, 64)); // light green
    
    631
    -  segmentPen_.setWidth(0);
    
    138
    +  engine_->resetCache();
    
    139
    +  applySettings();
    
    140
    +  if (tabWidget_->currentIndex() > 0 
    
    141
    +      && static_cast<size_t>(tabWidget_->currentIndex()) < tabs_.size())
    
    142
    +    tabs_[tabWidget_->currentIndex()]->reloadFont();
    
    632 143
     }
    
    633 144
     
    
    634 145
     
    
    635 146
     void
    
    636
    -MainGUI::drawGlyph()
    
    147
    +MainGUI::applySettings()
    
    637 148
     {
    
    638
    -  // the call to `engine->loadOutline' updates FreeType's load flags
    
    639
    -
    
    640
    -  if (!engine_)
    
    641
    -    return;
    
    642
    -
    
    643
    -  if (currentGlyphBitmapItem_)
    
    644
    -  {
    
    645
    -    glyphScene_->removeItem(currentGlyphBitmapItem_);
    
    646
    -    delete currentGlyphBitmapItem_;
    
    647
    -
    
    648
    -    currentGlyphBitmapItem_ = NULL;
    
    649
    -  }
    
    650
    -
    
    651
    -  if (currentGlyphOutlineItem_)
    
    652
    -  {
    
    653
    -    glyphScene_->removeItem(currentGlyphOutlineItem_);
    
    654
    -    delete currentGlyphOutlineItem_;
    
    655
    -
    
    656
    -    currentGlyphOutlineItem_ = NULL;
    
    657
    -  }
    
    658
    -
    
    659
    -  if (currentGlyphPointsItem_)
    
    660
    -  {
    
    661
    -    glyphScene_->removeItem(currentGlyphPointsItem_);
    
    662
    -    delete currentGlyphPointsItem_;
    
    663
    -
    
    664
    -    currentGlyphPointsItem_ = NULL;
    
    665
    -  }
    
    666
    -
    
    667
    -  if (currentGlyphPointNumbersItem_)
    
    668
    -  {
    
    669
    -    glyphScene_->removeItem(currentGlyphPointNumbersItem_);
    
    670
    -    delete currentGlyphPointNumbersItem_;
    
    671
    -
    
    672
    -    currentGlyphPointNumbersItem_ = NULL;
    
    673
    -  }
    
    674
    -
    
    675
    -  applySettings();
    
    676
    -  FT_Outline* outline = engine_->loadOutline(currentGlyphIndex_);
    
    677
    -  if (outline)
    
    678
    -  {
    
    679
    -    if (showBitmapCheckBox_->isChecked())
    
    680
    -    {
    
    681
    -      // XXX support LCD
    
    682
    -      FT_Pixel_Mode pixelMode = FT_PIXEL_MODE_GRAY;
    
    683
    -      if (antiAliasingComboBox_->currentIndex()
    
    684
    -          == AntiAliasingComboBoxModel::AntiAliasing_None)
    
    685
    -        pixelMode = FT_PIXEL_MODE_MONO;
    
    686
    -
    
    687
    -      currentGlyphBitmapItem_ = new GlyphBitmap(outline,
    
    688
    -                                               engine_->ftLibrary(),
    
    689
    -                                               pixelMode,
    
    690
    -                                               monoColorTable_,
    
    691
    -                                               grayColorTable_);
    
    692
    -      glyphScene_->addItem(currentGlyphBitmapItem_);
    
    693
    -    }
    
    694
    -
    
    695
    -    if (showOutlinesCheckBox_->isChecked())
    
    696
    -    {
    
    697
    -      currentGlyphOutlineItem_ = new GlyphOutline(outlinePen_, outline);
    
    698
    -      glyphScene_->addItem(currentGlyphOutlineItem_);
    
    699
    -    }
    
    700
    -
    
    701
    -    if (showPointsCheckBox_->isChecked())
    
    702
    -    {
    
    703
    -      currentGlyphPointsItem_ = new GlyphPoints(onPen_, offPen_, outline);
    
    704
    -      glyphScene_->addItem(currentGlyphPointsItem_);
    
    705
    -
    
    706
    -      if (showPointNumbersCheckBox_->isChecked())
    
    707
    -      {
    
    708
    -        currentGlyphPointNumbersItem_ = new GlyphPointNumbers(onPen_,
    
    709
    -                                                             offPen_,
    
    710
    -                                                             outline);
    
    711
    -        glyphScene_->addItem(currentGlyphPointNumbersItem_);
    
    712
    -      }
    
    713
    -    }
    
    714
    -  }
    
    715
    -
    
    716
    -  glyphScene_->update();
    
    149
    +  settingPanel_->applySettings();
    
    150
    +  settingPanel_->applyDelayedSettings();
    
    717 151
     }
    
    718 152
     
    
    719 153
     
    
    ... ... @@ -723,299 +157,58 @@ void
    723 157
     MainGUI::createLayout()
    
    724 158
     {
    
    725 159
       // left side
    
    726
    -  fontFilenameLabel_ = new QLabel;
    
    727
    -
    
    728
    -  hintingCheckBox_ = new QCheckBox(tr("Hinting"));
    
    729
    -
    
    730
    -  hintingModeLabel_ = new QLabel(tr("Hinting Mode"));
    
    731
    -  hintingModeLabel_->setAlignment(Qt::AlignRight);
    
    732
    -
    
    733
    -  hintingModeComboBoxModel_ = new HintingModeComboBoxModel(this);
    
    734
    -  hintingModeComboBox_ = new QComboBox;
    
    735
    -  hintingModeComboBox_->setModel(hintingModeComboBoxModel_);
    
    736
    -  hintingModeLabel_->setBuddy(hintingModeComboBox_);
    
    737
    -
    
    738
    -  autoHintingCheckBox_ = new QCheckBox(tr("Auto-Hinting"));
    
    739
    -  horizontalHintingCheckBox_ = new QCheckBox(tr("Horizontal Hinting"));
    
    740
    -  verticalHintingCheckBox_ = new QCheckBox(tr("Vertical Hinting"));
    
    741
    -  blueZoneHintingCheckBox_ = new QCheckBox(tr("Blue-Zone Hinting"));
    
    742
    -  segmentDrawingCheckBox_ = new QCheckBox(tr("Segment Drawing"));
    
    743
    -
    
    744
    -  antiAliasingLabel_ = new QLabel(tr("Anti-Aliasing"));
    
    745
    -  antiAliasingLabel_->setAlignment(Qt::AlignRight);
    
    746
    -
    
    747
    -  antiAliasingComboBoxModel_ = new AntiAliasingComboBoxModel(this);
    
    748
    -  antiAliasingComboBox_ = new QComboBox;
    
    749
    -  antiAliasingComboBox_->setModel(antiAliasingComboBoxModel_);
    
    750
    -  antiAliasingLabel_->setBuddy(antiAliasingComboBox_);
    
    751
    -
    
    752
    -  lcdFilterLabel_ = new QLabel(tr("LCD Filter"));
    
    753
    -  lcdFilterLabel_->setAlignment(Qt::AlignRight);
    
    754
    -
    
    755
    -  lcdFilterComboboxModel_ = new LCDFilterComboBoxModel(this);
    
    756
    -  lcdFilterComboBox_ = new QComboBox;
    
    757
    -  lcdFilterComboBox_->setModel(lcdFilterComboboxModel_);
    
    758
    -  lcdFilterLabel_->setBuddy(lcdFilterComboBox_);
    
    759
    -
    
    760
    -  int width;
    
    761
    -  // make all labels have the same width
    
    762
    -  width = hintingModeLabel_->minimumSizeHint().width();
    
    763
    -  width = qMax(antiAliasingLabel_->minimumSizeHint().width(), width);
    
    764
    -  width = qMax(lcdFilterLabel_->minimumSizeHint().width(), width);
    
    765
    -  hintingModeLabel_->setMinimumWidth(width);
    
    766
    -  antiAliasingLabel_->setMinimumWidth(width);
    
    767
    -  lcdFilterLabel_->setMinimumWidth(width);
    
    768
    -
    
    769
    -  // ensure that all items in combo boxes fit completely;
    
    770
    -  // also make all combo boxes have the same width
    
    771
    -  width = hintingModeComboBox_->minimumSizeHint().width();
    
    772
    -  width = qMax(antiAliasingComboBox_->minimumSizeHint().width(), width);
    
    773
    -  width = qMax(lcdFilterComboBox_->minimumSizeHint().width(), width);
    
    774
    -  hintingModeComboBox_->setMinimumWidth(width);
    
    775
    -  antiAliasingComboBox_->setMinimumWidth(width);
    
    776
    -  lcdFilterComboBox_->setMinimumWidth(width);
    
    777
    -
    
    778
    -  gammaLabel_ = new QLabel(tr("Gamma"));
    
    779
    -  gammaLabel_->setAlignment(Qt::AlignRight);
    
    780
    -  gammaSlider_ = new QSlider(Qt::Horizontal);
    
    781
    -  gammaSlider_->setRange(0, 30); // in 1/10th
    
    782
    -  gammaSlider_->setTickPosition(QSlider::TicksBelow);
    
    783
    -  gammaSlider_->setTickInterval(5);
    
    784
    -  gammaLabel_->setBuddy(gammaSlider_);
    
    785
    -
    
    786
    -  showBitmapCheckBox_ = new QCheckBox(tr("Show Bitmap"));
    
    787
    -  showPointsCheckBox_ = new QCheckBox(tr("Show Points"));
    
    788
    -  showPointNumbersCheckBox_ = new QCheckBox(tr("Show Point Numbers"));
    
    789
    -  showOutlinesCheckBox_ = new QCheckBox(tr("Show Outlines"));
    
    790
    -
    
    791
    -  infoLeftLayout_ = new QHBoxLayout;
    
    792
    -  infoLeftLayout_->addWidget(fontFilenameLabel_);
    
    793
    -
    
    794
    -  hintingModeLayout_ = new QHBoxLayout;
    
    795
    -  hintingModeLayout_->addWidget(hintingModeLabel_);
    
    796
    -  hintingModeLayout_->addWidget(hintingModeComboBox_);
    
    797
    -
    
    798
    -  horizontalHintingLayout_ = new QHBoxLayout;
    
    799
    -  horizontalHintingLayout_->addSpacing(20); // XXX px
    
    800
    -  horizontalHintingLayout_->addWidget(horizontalHintingCheckBox_);
    
    801
    -
    
    802
    -  verticalHintingLayout_ = new QHBoxLayout;
    
    803
    -  verticalHintingLayout_->addSpacing(20); // XXX px
    
    804
    -  verticalHintingLayout_->addWidget(verticalHintingCheckBox_);
    
    805
    -
    
    806
    -  blueZoneHintingLayout_ = new QHBoxLayout;
    
    807
    -  blueZoneHintingLayout_->addSpacing(20); // XXX px
    
    808
    -  blueZoneHintingLayout_->addWidget(blueZoneHintingCheckBox_);
    
    809
    -
    
    810
    -  segmentDrawingLayout_ = new QHBoxLayout;
    
    811
    -  segmentDrawingLayout_->addSpacing(20); // XXX px
    
    812
    -  segmentDrawingLayout_->addWidget(segmentDrawingCheckBox_);
    
    813
    -
    
    814
    -  antiAliasingLayout_ = new QHBoxLayout;
    
    815
    -  antiAliasingLayout_->addWidget(antiAliasingLabel_);
    
    816
    -  antiAliasingLayout_->addWidget(antiAliasingComboBox_);
    
    817
    -
    
    818
    -  lcdFilterLayout_ = new QHBoxLayout;
    
    819
    -  lcdFilterLayout_->addWidget(lcdFilterLabel_);
    
    820
    -  lcdFilterLayout_->addWidget(lcdFilterComboBox_);
    
    821
    -
    
    822
    -  gammaLayout_ = new QHBoxLayout;
    
    823
    -  gammaLayout_->addWidget(gammaLabel_);
    
    824
    -  gammaLayout_->addWidget(gammaSlider_);
    
    825
    -
    
    826
    -  pointNumbersLayout_ = new QHBoxLayout;
    
    827
    -  pointNumbersLayout_->addSpacing(20); // XXX px
    
    828
    -  pointNumbersLayout_->addWidget(showPointNumbersCheckBox_);
    
    829
    -
    
    830
    -  generalTabLayout_ = new QVBoxLayout;
    
    831
    -  generalTabLayout_->addWidget(hintingCheckBox_);
    
    832
    -  generalTabLayout_->addLayout(hintingModeLayout_);
    
    833
    -  generalTabLayout_->addWidget(autoHintingCheckBox_);
    
    834
    -  generalTabLayout_->addLayout(horizontalHintingLayout_);
    
    835
    -  generalTabLayout_->addLayout(verticalHintingLayout_);
    
    836
    -  generalTabLayout_->addLayout(blueZoneHintingLayout_);
    
    837
    -  generalTabLayout_->addLayout(segmentDrawingLayout_);
    
    838
    -  generalTabLayout_->addSpacing(20); // XXX px
    
    839
    -  generalTabLayout_->addStretch(1);
    
    840
    -  generalTabLayout_->addLayout(antiAliasingLayout_);
    
    841
    -  generalTabLayout_->addLayout(lcdFilterLayout_);
    
    842
    -  generalTabLayout_->addSpacing(20); // XXX px
    
    843
    -  generalTabLayout_->addStretch(1);
    
    844
    -  generalTabLayout_->addLayout(gammaLayout_);
    
    845
    -  generalTabLayout_->addSpacing(20); // XXX px
    
    846
    -  generalTabLayout_->addStretch(1);
    
    847
    -  generalTabLayout_->addWidget(showBitmapCheckBox_);
    
    848
    -  generalTabLayout_->addWidget(showPointsCheckBox_);
    
    849
    -  generalTabLayout_->addLayout(pointNumbersLayout_);
    
    850
    -  generalTabLayout_->addWidget(showOutlinesCheckBox_);
    
    851
    -
    
    852
    -  generalTabWidget_ = new QWidget;
    
    853
    -  generalTabWidget_->setLayout(generalTabLayout_);
    
    854
    -
    
    855
    -  mmgxTabWidget_ = new QWidget;
    
    856
    -
    
    857
    -  tabWidget_ = new QTabWidget;
    
    858
    -  tabWidget_->addTab(generalTabWidget_, tr("General"));
    
    859
    -  tabWidget_->addTab(mmgxTabWidget_, tr("MM/GX"));
    
    860
    -
    
    861
    -  leftLayout_ = new QVBoxLayout;
    
    862
    -  leftLayout_->addLayout(infoLeftLayout_);
    
    863
    -  leftLayout_->addWidget(tabWidget_);
    
    160
    +  settingPanel_ = new SettingPanel(this, engine_);
    
    161
    +
    
    162
    +  leftLayout_ = new QVBoxLayout; // The only point is to set a margin->remove?
    
    163
    +  leftLayout_->addWidget(settingPanel_);
    
    164
    +  leftLayout_->setContentsMargins(32, 32, 0, 16);
    
    864 165
     
    
    865 166
       // we don't want to expand the left side horizontally;
    
    866 167
       // to change the policy we have to use a widget wrapper
    
    867
    -  leftWidget_ = new QWidget;
    
    168
    +  leftWidget_ = new QWidget(this);
    
    868 169
       leftWidget_->setLayout(leftLayout_);
    
    170
    +  leftWidget_->setMaximumWidth(400);
    
    869 171
     
    
    870
    -  QSizePolicy leftWidgetPolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
    
    871
    -  leftWidgetPolicy.setHorizontalStretch(0);
    
    872
    -  leftWidgetPolicy.setVerticalPolicy(leftWidget_->sizePolicy().verticalPolicy());
    
    873
    -  leftWidgetPolicy.setHeightForWidth(leftWidget_->sizePolicy().hasHeightForWidth());
    
    172
    +  // right side
    
    173
    +  // TODO: create tabs here
    
    874 174
     
    
    875
    -  leftWidget_->setSizePolicy(leftWidgetPolicy);
    
    175
    +  tabWidget_ = new QTabWidget(this);
    
    176
    +  tabWidget_->setObjectName("mainTab"); // for stylesheet
    
    876 177
     
    
    877
    -  // right side
    
    878
    -  glyphIndexLabel_ = new QLabel;
    
    879
    -  glyphNameLabel_ = new QLabel;
    
    880
    -  fontNameLabel_ = new QLabel;
    
    881
    -
    
    882
    -  glyphScene_ = new QGraphicsScene;
    
    883
    -  glyphScene_->addItem(new Grid(gridPen_, axisPen_));
    
    884
    -
    
    885
    -  currentGlyphBitmapItem_ = NULL;
    
    886
    -  currentGlyphOutlineItem_ = NULL;
    
    887
    -  currentGlyphPointsItem_ = NULL;
    
    888
    -  currentGlyphPointNumbersItem_ = NULL;
    
    889
    -
    
    890
    -  glyphView_ = new QGraphicsViewx(this);
    
    891
    -  glyphView_->setRenderHint(QPainter::Antialiasing, true);
    
    892
    -  glyphView_->setDragMode(QGraphicsView::ScrollHandDrag);
    
    893
    -  glyphView_->setOptimizationFlags(QGraphicsView::DontSavePainterState);
    
    894
    -  glyphView_->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
    
    895
    -  glyphView_->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    
    896
    -  glyphView_->setScene(glyphScene_);
    
    897
    -
    
    898
    -  sizeLabel_ = new QLabel(tr("Size "));
    
    899
    -  sizeLabel_->setAlignment(Qt::AlignRight);
    
    900
    -  sizeDoubleSpinBox_ = new QDoubleSpinBox;
    
    901
    -  sizeDoubleSpinBox_->setAlignment(Qt::AlignRight);
    
    902
    -  sizeDoubleSpinBox_->setDecimals(1);
    
    903
    -  sizeDoubleSpinBox_->setRange(1, 500);
    
    904
    -  sizeLabel_->setBuddy(sizeDoubleSpinBox_);
    
    905
    -
    
    906
    -  unitsComboBox_ = new QComboBox;
    
    907
    -  unitsComboBox_->insertItem(Units_px, "px");
    
    908
    -  unitsComboBox_->insertItem(Units_pt, "pt");
    
    909
    -
    
    910
    -  dpiLabel_ = new QLabel(tr("DPI "));
    
    911
    -  dpiLabel_->setAlignment(Qt::AlignRight);
    
    912
    -  dpiSpinBox_ = new QSpinBox;
    
    913
    -  dpiSpinBox_->setAlignment(Qt::AlignRight);
    
    914
    -  dpiSpinBox_->setRange(10, 600);
    
    915
    -  dpiLabel_->setBuddy(dpiSpinBox_);
    
    916
    -
    
    917
    -  toStartButtonx_ = new QPushButton("|<");
    
    918
    -  toM1000Buttonx_ = new QPushButton("-1000");
    
    919
    -  toM100Buttonx_ = new QPushButton("-100");
    
    920
    -  toM10Buttonx_ = new QPushButton("-10");
    
    921
    -  toM1Buttonx_ = new QPushButton("-1");
    
    922
    -  toP1Buttonx_ = new QPushButton("+1");
    
    923
    -  toP10Buttonx_ = new QPushButton("+10");
    
    924
    -  toP100Buttonx_ = new QPushButton("+100");
    
    925
    -  toP1000Buttonx_ = new QPushButton("+1000");
    
    926
    -  toEndButtonx_ = new QPushButton(">|");
    
    927
    -
    
    928
    -  setButtonNarrowest(toStartButtonx_);
    
    929
    -  setButtonNarrowest(toM1000Buttonx_);
    
    930
    -  setButtonNarrowest(toM100Buttonx_ );
    
    931
    -  setButtonNarrowest(toM10Buttonx_  );
    
    932
    -  setButtonNarrowest(toM1Buttonx_   );
    
    933
    -  setButtonNarrowest(toP1Buttonx_   );
    
    934
    -  setButtonNarrowest(toP10Buttonx_  );
    
    935
    -  setButtonNarrowest(toP100Buttonx_ );
    
    936
    -  setButtonNarrowest(toP1000Buttonx_);
    
    937
    -  setButtonNarrowest(toEndButtonx_  );
    
    938
    -
    
    939
    -  zoomLabel_ = new QLabel(tr("Zoom Factor"));
    
    940
    -  zoomLabel_->setAlignment(Qt::AlignRight);
    
    941
    -  zoomSpinBox_ = new ZoomSpinBox(this, false);
    
    942
    -  zoomSpinBox_->setAlignment(Qt::AlignRight);
    
    943
    -  zoomSpinBox_->setRange(1, 1000 - 1000 % 64);
    
    944
    -  zoomSpinBox_->setKeyboardTracking(false);
    
    945
    -  zoomLabel_->setBuddy(zoomSpinBox_);
    
    946
    -
    
    947
    -  previousFontButton_ = new QPushButton(tr("Previous Font"));
    
    948
    -  nextFontButton_ = new QPushButton(tr("Next Font"));
    
    949
    -  previousFaceButton_ = new QPushButton(tr("Previous Face"));
    
    950
    -  nextFaceButton_ = new QPushButton(tr("Next Face"));
    
    951
    -  previousNamedInstanceButton_ = new QPushButton(tr("Previous Named Instance"));
    
    952
    -  nextNamedInstanceButton_ = new QPushButton(tr("Next Named Instance"));
    
    953
    -
    
    954
    -  infoRightLayout = new QGridLayout;
    
    955
    -  infoRightLayout->addWidget(glyphIndexLabel_, 0, 0);
    
    956
    -  infoRightLayout->addWidget(glyphNameLabel_, 0, 1);
    
    957
    -  infoRightLayout->addWidget(fontNameLabel_, 0, 2);
    
    958
    -
    
    959
    -  navigationLayout_ = new QHBoxLayout;
    
    960
    -  navigationLayout_->setSpacing(0);
    
    961
    -  navigationLayout_->addStretch(1);
    
    962
    -  navigationLayout_->addWidget(toStartButtonx_);
    
    963
    -  navigationLayout_->addWidget(toM1000Buttonx_);
    
    964
    -  navigationLayout_->addWidget(toM100Buttonx_);
    
    965
    -  navigationLayout_->addWidget(toM10Buttonx_);
    
    966
    -  navigationLayout_->addWidget(toM1Buttonx_);
    
    967
    -  navigationLayout_->addWidget(toP1Buttonx_);
    
    968
    -  navigationLayout_->addWidget(toP10Buttonx_);
    
    969
    -  navigationLayout_->addWidget(toP100Buttonx_);
    
    970
    -  navigationLayout_->addWidget(toP1000Buttonx_);
    
    971
    -  navigationLayout_->addWidget(toEndButtonx_);
    
    972
    -  navigationLayout_->addStretch(1);
    
    973
    -
    
    974
    -  sizeLayout_ = new QHBoxLayout;
    
    975
    -  sizeLayout_->addStretch(2);
    
    976
    -  sizeLayout_->addWidget(sizeLabel_);
    
    977
    -  sizeLayout_->addWidget(sizeDoubleSpinBox_);
    
    978
    -  sizeLayout_->addWidget(unitsComboBox_);
    
    979
    -  sizeLayout_->addStretch(1);
    
    980
    -  sizeLayout_->addWidget(dpiLabel_);
    
    981
    -  sizeLayout_->addWidget(dpiSpinBox_);
    
    982
    -  sizeLayout_->addStretch(1);
    
    983
    -  sizeLayout_->addWidget(zoomLabel_);
    
    984
    -  sizeLayout_->addWidget(zoomSpinBox_);
    
    985
    -  sizeLayout_->addStretch(2);
    
    986
    -
    
    987
    -  fontLayout = new QGridLayout;
    
    988
    -  fontLayout->setColumnStretch(0, 2);
    
    989
    -  fontLayout->addWidget(nextFontButton_, 0, 1);
    
    990
    -  fontLayout->addWidget(previousFontButton_, 1, 1);
    
    991
    -  fontLayout->setColumnStretch(2, 1);
    
    992
    -  fontLayout->addWidget(nextFaceButton_, 0, 3);
    
    993
    -  fontLayout->addWidget(previousFaceButton_, 1, 3);
    
    994
    -  fontLayout->setColumnStretch(4, 1);
    
    995
    -  fontLayout->addWidget(nextNamedInstanceButton_, 0, 5);
    
    996
    -  fontLayout->addWidget(previousNamedInstanceButton_, 1, 5);
    
    997
    -  fontLayout->setColumnStretch(6, 2);
    
    178
    +  // Note those two list must be in sync
    
    179
    +  // TODO: add tabs and tooltips here
    
    180
    +  
    
    181
    +  tripletSelector_ = new TripletSelector(this, engine_);
    
    998 182
     
    
    999 183
       rightLayout_ = new QVBoxLayout;
    
    1000
    -  rightLayout_->addLayout(infoRightLayout);
    
    1001
    -  rightLayout_->addWidget(glyphView_);
    
    1002
    -  rightLayout_->addLayout(navigationLayout_);
    
    1003
    -  rightLayout_->addSpacing(10); // XXX px
    
    1004
    -  rightLayout_->addLayout(sizeLayout_);
    
    1005
    -  rightLayout_->addSpacing(10); // XXX px
    
    1006
    -  rightLayout_->addLayout(fontLayout);
    
    184
    +  //rightLayout_->addWidget(fontNameLabel_);
    
    185
    +  rightLayout_->addWidget(tabWidget_); // same for `leftLayout_`: Remove?
    
    186
    +  rightLayout_->setContentsMargins(16, 32, 32, 16);
    
    1007 187
     
    
    1008 188
       // for symmetry with the left side use a widget also
    
    1009
    -  rightWidget_ = new QWidget;
    
    189
    +  rightWidget_ = new QWidget(this);
    
    1010 190
       rightWidget_->setLayout(rightLayout_);
    
    1011 191
     
    
    1012 192
       // the whole thing
    
    1013
    -  ftinspectLayout_ = new QHBoxLayout;
    
    1014
    -  ftinspectLayout_->addWidget(leftWidget_);
    
    1015
    -  ftinspectLayout_->addWidget(rightWidget_);
    
    193
    +  mainPartLayout_ = new QHBoxLayout;
    
    194
    +  mainPartLayout_->addWidget(leftWidget_);
    
    195
    +  mainPartLayout_->addWidget(rightWidget_);
    
    1016 196
     
    
    1017
    -  ftinspectWidget_ = new QWidget;
    
    197
    +  ftinspectLayout_ = new QVBoxLayout;
    
    198
    +  ftinspectLayout_->setSpacing(0);
    
    199
    +  ftinspectLayout_->addLayout(mainPartLayout_);
    
    200
    +  ftinspectLayout_->addWidget(tripletSelector_);
    
    201
    +  ftinspectLayout_->setContentsMargins(0, 0, 0, 0);
    
    202
    +
    
    203
    +  ftinspectWidget_ = new QWidget(this);
    
    1018 204
       ftinspectWidget_->setLayout(ftinspectLayout_);
    
    205
    +
    
    206
    +  ftinspectLayout_->setSizeConstraint(QLayout::SetNoConstraint);
    
    207
    +  layout()->setSizeConstraint(QLayout::SetNoConstraint);
    
    208
    +  resize(ftinspectWidget_->minimumSizeHint().width(),
    
    209
    +         700 * logicalDpiY() / 96);
    
    210
    +
    
    211
    +  statusBar()->hide(); // remove the extra space
    
    1019 212
       setCentralWidget(ftinspectWidget_);
    
    1020 213
       setWindowTitle("ftinspect");
    
    1021 214
     }
    
    ... ... @@ -1024,88 +217,16 @@ MainGUI::createLayout()
    1024 217
     void
    
    1025 218
     MainGUI::createConnections()
    
    1026 219
     {
    
    1027
    -  connect(hintingCheckBox_, SIGNAL(clicked()),
    
    1028
    -          SLOT(checkHinting()));
    
    1029
    -
    
    1030
    -  connect(hintingModeComboBox_, SIGNAL(currentIndexChanged(int)),
    
    1031
    -          SLOT(checkHintingMode()));
    
    1032
    -  connect(antiAliasingComboBox_, SIGNAL(currentIndexChanged(int)),
    
    1033
    -          SLOT(checkAntiAliasing()));
    
    1034
    -  connect(lcdFilterComboBox_, SIGNAL(currentIndexChanged(int)),
    
    1035
    -          SLOT(checkLcdFilter()));
    
    1036
    -
    
    1037
    -  connect(autoHintingCheckBox_, SIGNAL(clicked()),
    
    1038
    -          SLOT(checkAutoHinting()));
    
    1039
    -  connect(showBitmapCheckBox_, SIGNAL(clicked()),
    
    1040
    -          SLOT(drawGlyph()));
    
    1041
    -  connect(showPointsCheckBox_, SIGNAL(clicked()),
    
    1042
    -          SLOT(checkShowPoints()));
    
    1043
    -  connect(showPointNumbersCheckBox_, SIGNAL(clicked()),
    
    1044
    -          SLOT(drawGlyph()));
    
    1045
    -  connect(showOutlinesCheckBox_, SIGNAL(clicked()),
    
    1046
    -          SLOT(drawGlyph()));
    
    1047
    -
    
    1048
    -  connect(sizeDoubleSpinBox_, SIGNAL(valueChanged(double)),
    
    1049
    -          SLOT(drawGlyph()));
    
    1050
    -  connect(unitsComboBox_, SIGNAL(currentIndexChanged(int)),
    
    1051
    -          SLOT(checkUnits()));
    
    1052
    -  connect(dpiSpinBox_, SIGNAL(valueChanged(int)),
    
    1053
    -          SLOT(drawGlyph()));
    
    1054
    -
    
    1055
    -  connect(zoomSpinBox_, SIGNAL(valueChanged(double)),
    
    1056
    -          SLOT(zoom()));
    
    1057
    -
    
    1058
    -  connect(previousFontButton_, SIGNAL(clicked()),
    
    1059
    -          SLOT(previousFont()));
    
    1060
    -  connect(nextFontButton_, SIGNAL(clicked()),
    
    1061
    -          SLOT(nextFont()));
    
    1062
    -  connect(previousFaceButton_, SIGNAL(clicked()),
    
    1063
    -          SLOT(previousFace()));
    
    1064
    -  connect(nextFaceButton_, SIGNAL(clicked()),
    
    1065
    -          SLOT(nextFace()));
    
    1066
    -  connect(previousNamedInstanceButton_, SIGNAL(clicked()),
    
    1067
    -          SLOT(previousNamedInstance()));
    
    1068
    -  connect(nextNamedInstanceButton_, SIGNAL(clicked()),
    
    1069
    -          SLOT(nextNamedInstance()));
    
    1070
    -
    
    1071
    -  glyphNavigationMapper_ = new QSignalMapper;
    
    1072
    -  connect(glyphNavigationMapper_, SIGNAL(mapped(int)),
    
    1073
    -          SLOT(adjustGlyphIndex(int)));
    
    1074
    -
    
    1075
    -  connect(toStartButtonx_, SIGNAL(clicked()),
    
    1076
    -          glyphNavigationMapper_, SLOT(map()));
    
    1077
    -  connect(toM1000Buttonx_, SIGNAL(clicked()),
    
    1078
    -          glyphNavigationMapper_, SLOT(map()));
    
    1079
    -  connect(toM100Buttonx_, SIGNAL(clicked()),
    
    1080
    -          glyphNavigationMapper_, SLOT(map()));
    
    1081
    -  connect(toM10Buttonx_, SIGNAL(clicked()),
    
    1082
    -          glyphNavigationMapper_, SLOT(map()));
    
    1083
    -  connect(toM1Buttonx_, SIGNAL(clicked()),
    
    1084
    -          glyphNavigationMapper_, SLOT(map()));
    
    1085
    -  connect(toP1Buttonx_, SIGNAL(clicked()),
    
    1086
    -          glyphNavigationMapper_, SLOT(map()));
    
    1087
    -  connect(toP10Buttonx_, SIGNAL(clicked()),
    
    1088
    -          glyphNavigationMapper_, SLOT(map()));
    
    1089
    -  connect(toP100Buttonx_, SIGNAL(clicked()),
    
    1090
    -          glyphNavigationMapper_, SLOT(map()));
    
    1091
    -  connect(toP1000Buttonx_, SIGNAL(clicked()),
    
    1092
    -          glyphNavigationMapper_, SLOT(map()));
    
    1093
    -  connect(toEndButtonx_, SIGNAL(clicked()),
    
    1094
    -          glyphNavigationMapper_, SLOT(map()));
    
    1095
    -
    
    1096
    -  glyphNavigationMapper_->setMapping(toStartButtonx_, -0x10000);
    
    1097
    -  glyphNavigationMapper_->setMapping(toM1000Buttonx_, -1000);
    
    1098
    -  glyphNavigationMapper_->setMapping(toM100Buttonx_, -100);
    
    1099
    -  glyphNavigationMapper_->setMapping(toM10Buttonx_, -10);
    
    1100
    -  glyphNavigationMapper_->setMapping(toM1Buttonx_, -1);
    
    1101
    -  glyphNavigationMapper_->setMapping(toP1Buttonx_, 1);
    
    1102
    -  glyphNavigationMapper_->setMapping(toP10Buttonx_, 10);
    
    1103
    -  glyphNavigationMapper_->setMapping(toP100Buttonx_, 100);
    
    1104
    -  glyphNavigationMapper_->setMapping(toP1000Buttonx_, 1000);
    
    1105
    -  glyphNavigationMapper_->setMapping(toEndButtonx_, 0x10000);
    
    1106
    -
    
    1107
    -  connect(&engine_->fontFileManager(), &FontFileManager::currentFileChanged,
    
    1108
    -      this, &MainGUI::watchCurrentFont);
    
    220
    +  connect(settingPanel_, &SettingPanel::fontReloadNeeded,
    
    221
    +          this, &MainGUI::reloadCurrentTabFont);
    
    222
    +  connect(settingPanel_, &SettingPanel::repaintNeeded,
    
    223
    +          this, &MainGUI::repaintCurrentTab);
    
    224
    +
    
    225
    +  connect(tabWidget_, &QTabWidget::currentChanged,
    
    226
    +          this, &MainGUI::switchTab);
    
    227
    +
    
    228
    +  connect(tripletSelector_, &TripletSelector::tripletChanged,
    
    229
    +          this, &MainGUI::onTripletChanged);
    
    1109 230
     }
    
    1110 231
     
    
    1111 232
     
    
    ... ... @@ -1114,21 +235,22 @@ MainGUI::createActions()
    1114 235
     {
    
    1115 236
       loadFontsAct_ = new QAction(tr("&Load Fonts"), this);
    
    1116 237
       loadFontsAct_->setShortcuts(QKeySequence::Open);
    
    1117
    -  connect(loadFontsAct_, SIGNAL(triggered()), SLOT(loadFonts()));
    
    238
    +  connect(loadFontsAct_, &QAction::triggered, this, &MainGUI::loadFonts);
    
    1118 239
     
    
    1119 240
       closeFontAct_ = new QAction(tr("&Close Font"), this);
    
    1120 241
       closeFontAct_->setShortcuts(QKeySequence::Close);
    
    1121
    -  connect(closeFontAct_, SIGNAL(triggered()), SLOT(closeFont()));
    
    242
    +  connect(closeFontAct_, &QAction::triggered,
    
    243
    +          tripletSelector_, &TripletSelector::closeCurrentFont);
    
    1122 244
     
    
    1123 245
       exitAct_ = new QAction(tr("E&xit"), this);
    
    1124 246
       exitAct_->setShortcuts(QKeySequence::Quit);
    
    1125
    -  connect(exitAct_, SIGNAL(triggered()), SLOT(close()));
    
    247
    +  connect(exitAct_, &QAction::triggered, this, &MainGUI::close);
    
    1126 248
     
    
    1127 249
       aboutAct_ = new QAction(tr("&About"), this);
    
    1128
    -  connect(aboutAct_, SIGNAL(triggered()), SLOT(about()));
    
    250
    +  connect(aboutAct_, &QAction::triggered, this, &MainGUI::about);
    
    1129 251
     
    
    1130 252
       aboutQtAct_ = new QAction(tr("About &Qt"), this);
    
    1131
    -  connect(aboutQtAct_, SIGNAL(triggered()), SLOT(aboutQt()));
    
    253
    +  connect(aboutQtAct_, &QAction::triggered, this, &MainGUI::aboutQt);
    
    1132 254
     }
    
    1133 255
     
    
    1134 256
     
    
    ... ... @@ -1146,72 +268,6 @@ MainGUI::createMenus()
    1146 268
     }
    
    1147 269
     
    
    1148 270
     
    
    1149
    -void
    
    1150
    -MainGUI::createStatusBar()
    
    1151
    -{
    
    1152
    -  statusBar()->showMessage("");
    
    1153
    -}
    
    1154
    -
    
    1155
    -
    
    1156
    -void
    
    1157
    -MainGUI::setDefaults()
    
    1158
    -{
    
    1159
    -  Engine::EngineDefaultValues& defaults = engine_->engineDefaults();
    
    1160
    -
    
    1161
    -  hintingModeComboBoxModel_->setSupportedModes(
    
    1162
    -    { defaults.ttInterpreterVersionDefault,
    
    1163
    -      defaults.ttInterpreterVersionOther,
    
    1164
    -      defaults.ttInterpreterVersionOther1 },
    
    1165
    -    { defaults.cffHintingEngineDefault, 
    
    1166
    -      defaults.cffHintingEngineOther });
    
    1167
    -
    
    1168
    -  // the next four values always non-negative
    
    1169
    -  currentFontIndex_ = 0;
    
    1170
    -  currentFaceIndex_ = 0;
    
    1171
    -  currentNamedInstanceIndex_ = 0;
    
    1172
    -  currentGlyphIndex_ = 0;
    
    1173
    -
    
    1174
    -  currentCFFHintingMode_
    
    1175
    -    = hintingModeComboBoxModel_->cffModeToIndex(
    
    1176
    -    defaults.cffHintingEngineDefault);
    
    1177
    -  currentTTInterpreterVersion_
    
    1178
    -    = hintingModeComboBoxModel_->ttInterpreterVersionToIndex(
    
    1179
    -        defaults.ttInterpreterVersionDefault);
    
    1180
    -
    
    1181
    -  hintingCheckBox_->setChecked(true);
    
    1182
    -
    
    1183
    -  antiAliasingComboBox_->setCurrentIndex(
    
    1184
    -    AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    1185
    -  lcdFilterComboBox_->setCurrentIndex(
    
    1186
    -    LCDFilterComboBoxModel::LCDFilter_Light);
    
    1187
    -
    
    1188
    -  horizontalHintingCheckBox_->setChecked(true);
    
    1189
    -  verticalHintingCheckBox_->setChecked(true);
    
    1190
    -  blueZoneHintingCheckBox_->setChecked(true);
    
    1191
    -
    
    1192
    -  showBitmapCheckBox_->setChecked(true);
    
    1193
    -  showOutlinesCheckBox_->setChecked(true);
    
    1194
    -
    
    1195
    -  gammaSlider_->setValue(18); // 1.8
    
    1196
    -  sizeDoubleSpinBox_->setValue(20);
    
    1197
    -  dpiSpinBox_->setValue(96);
    
    1198
    -  zoomSpinBox_->setValue(20);
    
    1199
    -
    
    1200
    -  checkHinting();
    
    1201
    -  checkHintingMode();
    
    1202
    -  checkAutoHinting();
    
    1203
    -  checkAntiAliasing();
    
    1204
    -  checkLcdFilter();
    
    1205
    -  checkShowPoints();
    
    1206
    -  checkUnits();
    
    1207
    -  checkCurrentFontIndex();
    
    1208
    -  checkCurrentFaceIndex();
    
    1209
    -  checkCurrentNamedInstanceIndex();
    
    1210
    -  adjustGlyphIndex(0);
    
    1211
    -  zoom();
    
    1212
    -}
    
    1213
    -
    
    1214
    -
    
    1215 271
     void
    
    1216 272
     MainGUI::readSettings()
    
    1217 273
     {
    

  • src/ftinspect/maingui.hpp
    ... ... @@ -6,42 +6,21 @@
    6 6
     #pragma once
    
    7 7
     
    
    8 8
     #include "engine/engine.hpp"
    
    9
    -#include "glyphcomponents/glyphbitmap.hpp"
    
    10
    -#include "glyphcomponents/glyphoutline.hpp"
    
    11
    -#include "glyphcomponents/glyphpointnumbers.hpp"
    
    12
    -#include "glyphcomponents/glyphpoints.hpp"
    
    13
    -#include "widgets/customwidgets.hpp"
    
    14
    -#include "models/customcomboboxmodels.hpp"
    
    9
    +#include "widgets/tripletselector.hpp"
    
    10
    +#include "panels/settingpanel.hpp"
    
    11
    +#include "panels/abstracttab.hpp"
    
    15 12
     
    
    13
    +#include <vector>
    
    16 14
     #include <QAction>
    
    17
    -#include <QCheckBox>
    
    18 15
     #include <QCloseEvent>
    
    19
    -#include <QComboBox>
    
    20
    -#include <QDoubleSpinBox>
    
    21
    -#include <QFileSystemWatcher>
    
    22 16
     #include <QGridLayout>
    
    23
    -#include <QHash>
    
    24
    -#include <QHBoxLayout>
    
    17
    +#include <QDockWidget>
    
    18
    +#include <QBoxLayout>
    
    25 19
     #include <QLabel>
    
    26
    -#include <QList>
    
    27 20
     #include <QMainWindow>
    
    28
    -#include <QMap>
    
    29 21
     #include <QMenu>
    
    30 22
     #include <QMenuBar>
    
    31
    -#include <QPen>
    
    32
    -#include <QPushButton>
    
    33
    -#include <QScrollBar>
    
    34
    -#include <QSignalMapper>
    
    35
    -#include <QSlider>
    
    36
    -#include <QSpinBox>
    
    37
    -#include <QStatusBar>
    
    38 23
     #include <QTabWidget>
    
    39
    -#include <QTimer>
    
    40
    -#include <QVariant>
    
    41
    -#include <QVBoxLayout>
    
    42
    -
    
    43
    -#include <ft2build.h>
    
    44
    -#include <freetype/ftlcdfil.h>
    
    45 24
     
    
    46 25
     
    
    47 26
     class MainGUI
    
    ... ... @@ -51,9 +30,7 @@ class MainGUI
    51 30
     
    
    52 31
     public:
    
    53 32
       MainGUI(Engine* engine);
    
    54
    -  ~MainGUI();
    
    55
    -
    
    56
    -  void setDefaults();
    
    33
    +  ~MainGUI() override;
    
    57 34
     
    
    58 35
       friend class Engine;
    
    59 36
       friend FT_Error faceRequester(FTC_FaceID,
    
    ... ... @@ -62,186 +39,61 @@ public:
    62 39
                                     FT_Face*);
    
    63 40
     
    
    64 41
     protected:
    
    65
    -  void closeEvent(QCloseEvent*);
    
    42
    +  void closeEvent(QCloseEvent*) override;
    
    43
    +  void keyPressEvent(QKeyEvent* event) override;
    
    66 44
     
    
    67 45
     private slots:
    
    68 46
       void about();
    
    69 47
       void aboutQt();
    
    70
    -  void adjustGlyphIndex(int);
    
    71
    -  void checkAntiAliasing();
    
    72
    -  void checkAutoHinting();
    
    73
    -  void checkCurrentFaceIndex();
    
    74
    -  void checkCurrentFontIndex();
    
    75
    -  void checkCurrentNamedInstanceIndex();
    
    76
    -  void checkHinting();
    
    77
    -  void checkHintingMode();
    
    78
    -  void checkLcdFilter();
    
    79
    -  void checkShowPoints();
    
    80
    -  void checkUnits();
    
    81
    -  void closeFont();
    
    82
    -  void drawGlyph();
    
    48
    +  void repaintCurrentTab();
    
    49
    +  void reloadCurrentTabFont();
    
    83 50
       void loadFonts();
    
    84
    -  void nextFace();
    
    85
    -  void nextFont();
    
    86
    -  void nextNamedInstance();
    
    87
    -  void previousFace();
    
    88
    -  void previousFont();
    
    89
    -  void previousNamedInstance();
    
    90
    -  void watchCurrentFont();
    
    91
    -  void zoom();
    
    51
    +  void onTripletChanged();
    
    52
    +  void switchTab();
    
    92 53
     
    
    93 54
     private:
    
    94 55
       Engine* engine_;
    
    95 56
       
    
    96
    -  int currentFontIndex_;
    
    97
    -
    
    98
    -  long currentNumberOfFaces_;
    
    99
    -  long currentFaceIndex_;
    
    100
    -
    
    101
    -  int currentNumberOfNamedInstances_;
    
    102
    -  int currentNamedInstanceIndex_;
    
    103
    -
    
    104 57
       int currentNumberOfGlyphs_;
    
    105
    -  int currentGlyphIndex_;
    
    106
    -
    
    107
    -  int currentCFFHintingMode_;
    
    108
    -  int currentTTInterpreterVersion_;
    
    109 58
     
    
    110 59
       // layout related stuff
    
    111
    -  GlyphOutline *currentGlyphOutlineItem_;
    
    112
    -  GlyphPoints *currentGlyphPointsItem_;
    
    113
    -  GlyphPointNumbers *currentGlyphPointNumbersItem_;
    
    114
    -  GlyphBitmap *currentGlyphBitmapItem_;
    
    115
    -
    
    116 60
       QAction *aboutAct_;
    
    117 61
       QAction *aboutQtAct_;
    
    118 62
       QAction *closeFontAct_;
    
    119 63
       QAction *exitAct_;
    
    120 64
       QAction *loadFontsAct_;
    
    121 65
     
    
    122
    -  QCheckBox *autoHintingCheckBox_;
    
    123
    -  QCheckBox *blueZoneHintingCheckBox_;
    
    124
    -  QCheckBox *hintingCheckBox_;
    
    125
    -  QCheckBox *horizontalHintingCheckBox_;
    
    126
    -  QCheckBox *segmentDrawingCheckBox_;
    
    127
    -  QCheckBox *showBitmapCheckBox_;
    
    128
    -  QCheckBox *showOutlinesCheckBox_;
    
    129
    -  QCheckBox *showPointNumbersCheckBox_;
    
    130
    -  QCheckBox *showPointsCheckBox_;
    
    131
    -  QCheckBox *verticalHintingCheckBox_;
    
    132
    -
    
    133
    -  AntiAliasingComboBoxModel* antiAliasingComboBoxModel_;
    
    134
    -  HintingModeComboBoxModel* hintingModeComboBoxModel_;
    
    135
    -  LCDFilterComboBoxModel* lcdFilterComboboxModel_;
    
    136
    -
    
    137
    -  QComboBox *antiAliasingComboBox_;
    
    138
    -  QComboBox *hintingModeComboBox_;
    
    139
    -  QComboBox *lcdFilterComboBox_;
    
    140
    -  QComboBox *unitsComboBox_;
    
    141
    -
    
    142
    -  QDoubleSpinBox *sizeDoubleSpinBox_;
    
    143
    -
    
    144
    -  QGraphicsScene *glyphScene_;
    
    145
    -  QGraphicsViewx *glyphView_;
    
    146
    -
    
    147
    -  QGridLayout *fontLayout;
    
    148
    -  QGridLayout *infoRightLayout;
    
    149
    -
    
    150
    -  QHBoxLayout *antiAliasingLayout_;
    
    151
    -  QHBoxLayout *blueZoneHintingLayout_;
    
    152
    -  QHBoxLayout *ftinspectLayout_;
    
    153
    -  QHBoxLayout *gammaLayout_;
    
    154
    -  QHBoxLayout *hintingModeLayout_;
    
    155
    -  QHBoxLayout *horizontalHintingLayout_;
    
    156
    -  QHBoxLayout *infoLeftLayout_;
    
    157
    -  QHBoxLayout *lcdFilterLayout_;
    
    158
    -  QHBoxLayout *navigationLayout_;
    
    159
    -  QHBoxLayout *pointNumbersLayout_;
    
    160
    -  QHBoxLayout *segmentDrawingLayout_;
    
    161
    -  QHBoxLayout *sizeLayout_;
    
    162
    -  QHBoxLayout *verticalHintingLayout_;
    
    163
    -
    
    164
    -  QLabel *antiAliasingLabel_;
    
    165
    -  QLabel *dpiLabel_;
    
    166
    -  QLabel *fontFilenameLabel_;
    
    167
    -  QLabel *fontNameLabel_;
    
    168
    -  QLabel *gammaLabel_;
    
    169
    -  QLabel *glyphIndexLabel_;
    
    170
    -  QLabel *glyphNameLabel_;
    
    171
    -  QLabel *hintingModeLabel_;
    
    172
    -  QLabel *lcdFilterLabel_;
    
    173
    -  QLabel *sizeLabel_;
    
    174
    -  QLabel *zoomLabel_;
    
    66
    +  QVBoxLayout *ftinspectLayout_;
    
    67
    +  QHBoxLayout *mainPartLayout_;
    
    175 68
     
    
    176 69
       QLocale *locale_;
    
    177 70
     
    
    178 71
       QMenu *menuFile_;
    
    179 72
       QMenu *menuHelp_;
    
    180
    -
    
    181
    -  QPen axisPen_;
    
    182
    -  QPen blueZonePen_;
    
    183
    -  QPen gridPen_;
    
    184
    -  QPen offPen_;
    
    185
    -  QPen onPen_;
    
    186
    -  QPen outlinePen_;
    
    187
    -  QPen segmentPen_;
    
    188
    -
    
    189
    -  QPushButton *nextFaceButton_;
    
    190
    -  QPushButton *nextFontButton_;
    
    191
    -  QPushButton *nextNamedInstanceButton_;
    
    192
    -  QPushButton *previousFaceButton_;
    
    193
    -  QPushButton *previousFontButton_;
    
    194
    -  QPushButton *previousNamedInstanceButton_;
    
    195
    -
    
    196
    -  QPushButton *toEndButtonx_;
    
    197
    -  QPushButton *toM1000Buttonx_;
    
    198
    -  QPushButton *toM100Buttonx_;
    
    199
    -  QPushButton *toM10Buttonx_;
    
    200
    -  QPushButton *toM1Buttonx_;
    
    201
    -  QPushButton *toP1000Buttonx_;
    
    202
    -  QPushButton *toP100Buttonx_;
    
    203
    -  QPushButton *toP10Buttonx_;
    
    204
    -  QPushButton *toP1Buttonx_;
    
    205
    -  QPushButton *toStartButtonx_;
    
    206
    -
    
    207
    -  QSignalMapper *glyphNavigationMapper_;
    
    208
    -
    
    209
    -  QSlider *gammaSlider_;
    
    210
    -
    
    211
    -  QSpinBox *dpiSpinBox_;
    
    212
    -  ZoomSpinBox *zoomSpinBox_;
    
    213
    -
    
    214
    -  QTabWidget *tabWidget_;
    
    215
    -
    
    216
    -  QVBoxLayout *generalTabLayout_;
    
    73
    +  
    
    74
    +  TripletSelector* tripletSelector_;
    
    75
    +  
    
    217 76
       QVBoxLayout *leftLayout_;
    
    218 77
       QVBoxLayout *rightLayout_;
    
    219 78
     
    
    220
    -  QVector<QRgb> grayColorTable_;
    
    221
    -  QVector<QRgb> monoColorTable_;
    
    222
    -
    
    223 79
       QWidget *ftinspectWidget_;
    
    224
    -  QWidget *generalTabWidget_;
    
    225 80
       QWidget *leftWidget_;
    
    226 81
       QWidget *rightWidget_;
    
    227
    -  QWidget *mmgxTabWidget_;
    
    228 82
     
    
    229
    -  enum Units
    
    230
    -  {
    
    231
    -    Units_px,
    
    232
    -    Units_pt
    
    233
    -  };
    
    83
    +  SettingPanel* settingPanel_;
    
    84
    +
    
    85
    +  QTabWidget* tabWidget_;
    
    86
    +  std::vector<AbstractTab*> tabs_;
    
    87
    +  QWidget* lastTab_ = NULL;
    
    88
    +
    
    89
    +  void openFonts(QStringList const& fileNames);
    
    234 90
     
    
    235
    -  void showFont();
    
    236 91
       void applySettings();
    
    237
    -  void clearStatusBar();
    
    238 92
     
    
    239 93
       void createActions();
    
    240 94
       void createConnections();
    
    241 95
       void createLayout();
    
    242 96
       void createMenus();
    
    243
    -  void createStatusBar();
    
    244
    -  void setGraphicsDefaults();
    
    245 97
     
    
    246 98
       void readSettings();
    
    247 99
       void writeSettings();
    

  • src/ftinspect/meson.build
    ... ... @@ -31,9 +31,12 @@ if qt5_dep.found()
    31 31
         'glyphcomponents/grid.cpp',
    
    32 32
     
    
    33 33
         'widgets/customwidgets.cpp',
    
    34
    +    'widgets/tripletselector.cpp',
    
    34 35
     
    
    35 36
         'models/customcomboboxmodels.cpp',
    
    36 37
     
    
    38
    +    'panels/settingpanel.cpp',
    
    39
    +
    
    37 40
         'ftinspect.cpp',
    
    38 41
         'maingui.cpp',
    
    39 42
         'uihelper.cpp',
    
    ... ... @@ -43,8 +46,10 @@ if qt5_dep.found()
    43 46
         moc_headers: [
    
    44 47
           'engine/fontfilemanager.hpp',
    
    45 48
           'widgets/customwidgets.hpp',
    
    49
    +      'widgets/tripletselector.hpp',
    
    46 50
           'maingui.hpp',
    
    47 51
           'models/customcomboboxmodels.hpp',
    
    52
    +      'panels/settingpanel.hpp',
    
    48 53
         ],
    
    49 54
         dependencies: qt5_dep)
    
    50 55
     
    

  • src/ftinspect/panels/abstracttab.hpp
    1
    +// abstracttab.hpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#pragma once
    
    6
    +
    
    7
    +// This is an pure abstract interface for a ftinspect "tab".
    
    8
    +// The interface itself does not inherit from `QWidget`, but should be used as
    
    9
    +// the second base class.
    
    10
    +class AbstractTab
    
    11
    +{
    
    12
    +public:
    
    13
    +  virtual ~AbstractTab() = default; // must be `virtual` for `dynamic_cast`
    
    14
    +  
    
    15
    +  virtual void repaintGlyph() = 0;
    
    16
    +  virtual void reloadFont() = 0;
    
    17
    +};
    
    18
    +
    
    19
    +
    
    20
    +// end of abstracttab.hpp

  • src/ftinspect/panels/settingpanel.cpp
    1
    +// settingpanel.cpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#include "settingpanel.hpp"
    
    6
    +
    
    7
    +#include "../uihelper.hpp"
    
    8
    +
    
    9
    +#include <QColorDialog>
    
    10
    +
    
    11
    +// for `FT_DEBUG_AUTOFIT`
    
    12
    +#include <freetype/config/ftoption.h>
    
    13
    +
    
    14
    +SettingPanel::SettingPanel(QWidget* parent,
    
    15
    +                           Engine* engine)
    
    16
    +: QWidget(parent),
    
    17
    +  engine_(engine)
    
    18
    +{
    
    19
    +#ifdef FT_DEBUG_AUTOFIT
    
    20
    +  debugMode_ = !comparatorMode_;
    
    21
    +#else
    
    22
    +  debugMode_ = false;
    
    23
    +#endif
    
    24
    +  createLayout();
    
    25
    +  setDefaults();
    
    26
    +  createConnections();
    
    27
    +  checkAllSettings();
    
    28
    +}
    
    29
    +
    
    30
    +
    
    31
    +int
    
    32
    +SettingPanel::antiAliasingModeIndex()
    
    33
    +{
    
    34
    +  return antiAliasingComboBox_->currentIndex();
    
    35
    +}
    
    36
    +
    
    37
    +
    
    38
    +bool
    
    39
    +SettingPanel::kerningEnabled()
    
    40
    +{
    
    41
    +  return kerningCheckBox_->isChecked();
    
    42
    +}
    
    43
    +
    
    44
    +
    
    45
    +bool
    
    46
    +SettingPanel::lsbRsbDeltaEnabled()
    
    47
    +{
    
    48
    +  return lsbRsbDeltaCheckBox_->isChecked();
    
    49
    +}
    
    50
    +
    
    51
    +
    
    52
    +void
    
    53
    +SettingPanel::populatePalettes()
    
    54
    +{
    
    55
    +  // TODO: Impl
    
    56
    +}
    
    57
    +
    
    58
    +
    
    59
    +void
    
    60
    +SettingPanel::checkAllSettings()
    
    61
    +{
    
    62
    +  onFontChanged();
    
    63
    +  checkAntiAliasing();
    
    64
    +}
    
    65
    +
    
    66
    +
    
    67
    +void
    
    68
    +SettingPanel::checkHinting()
    
    69
    +{
    
    70
    +  if (hintingCheckBox_->isChecked())
    
    71
    +  {
    
    72
    +    // TODO: tricky: disable auto-hinting
    
    73
    +    checkAutoHinting(); // this will emit repaint
    
    74
    +  }
    
    75
    +  else
    
    76
    +  {
    
    77
    +    hintingModeLabel_->setEnabled(false);
    
    78
    +    hintingModeComboBox_->setEnabled(false);
    
    79
    +
    
    80
    +    autoHintingCheckBox_->setEnabled(false);
    
    81
    +    if (debugMode_)
    
    82
    +    {
    
    83
    +      horizontalHintingCheckBox_->setEnabled(false);
    
    84
    +      verticalHintingCheckBox_->setEnabled(false);
    
    85
    +      blueZoneHintingCheckBox_->setEnabled(false);
    
    86
    +      segmentDrawingCheckBox_->setEnabled(false);
    
    87
    +    }
    
    88
    +
    
    89
    +    stemDarkeningCheckBox_->setEnabled(false);
    
    90
    +    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    91
    +    auto aaMode = antiAliasingComboBox_->currentIndex();
    
    92
    +    if (aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    93
    +        || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel)
    
    94
    +      antiAliasingComboBox_->setCurrentIndex(
    
    95
    +        AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    96
    +    
    
    97
    +    emit repaintNeeded();
    
    98
    +  }
    
    99
    +}
    
    100
    +
    
    101
    +
    
    102
    +void
    
    103
    +SettingPanel::checkHintingMode()
    
    104
    +{
    
    105
    +  //if (!comparatorMode_)
    
    106
    +  //  applyDelayedSettings();
    
    107
    +
    
    108
    +  emit fontReloadNeeded();
    
    109
    +}
    
    110
    +
    
    111
    +
    
    112
    +void
    
    113
    +SettingPanel::checkAutoHinting()
    
    114
    +{
    
    115
    +  if (autoHintingCheckBox_->isChecked())
    
    116
    +  {
    
    117
    +    hintingModeLabel_->setEnabled(false);
    
    118
    +    hintingModeComboBox_->setEnabled(false);
    
    119
    +
    
    120
    +    if (debugMode_)
    
    121
    +    {
    
    122
    +      horizontalHintingCheckBox_->setEnabled(true);
    
    123
    +      verticalHintingCheckBox_->setEnabled(true);
    
    124
    +      blueZoneHintingCheckBox_->setEnabled(true);
    
    125
    +      segmentDrawingCheckBox_->setEnabled(true);
    
    126
    +    }
    
    127
    +
    
    128
    +    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(true);
    
    129
    +    auto aaMode = antiAliasingComboBox_->currentIndex();
    
    130
    +    stemDarkeningCheckBox_->setEnabled(
    
    131
    +      aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    132
    +      || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel);
    
    133
    +  }
    
    134
    +  else
    
    135
    +  {
    
    136
    +    if (engine_->currentFontType() == Engine::FontType_CFF
    
    137
    +        || engine_->currentFontType() == Engine::FontType_TrueType)
    
    138
    +    {
    
    139
    +      hintingModeLabel_->setEnabled(true);
    
    140
    +      hintingModeComboBox_->setEnabled(true);
    
    141
    +    }
    
    142
    +
    
    143
    +    if (debugMode_)
    
    144
    +    {
    
    145
    +      horizontalHintingCheckBox_->setEnabled(false);
    
    146
    +      verticalHintingCheckBox_->setEnabled(false);
    
    147
    +      blueZoneHintingCheckBox_->setEnabled(false);
    
    148
    +      segmentDrawingCheckBox_->setEnabled(false);
    
    149
    +    }
    
    150
    +
    
    151
    +    antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    152
    +    stemDarkeningCheckBox_->setEnabled(false);
    
    153
    +
    
    154
    +    auto aaMode = antiAliasingComboBox_->currentIndex();
    
    155
    +    if (aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    156
    +        || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel)
    
    157
    +      antiAliasingComboBox_->setCurrentIndex(
    
    158
    +          AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    159
    +  }
    
    160
    +  emit repaintNeeded();
    
    161
    +}
    
    162
    +
    
    163
    +
    
    164
    +void
    
    165
    +SettingPanel::checkAntiAliasing()
    
    166
    +{
    
    167
    +  int index = antiAliasingComboBox_->currentIndex();
    
    168
    +  auto isMono = index == AntiAliasingComboBoxModel::AntiAliasing_None;
    
    169
    +  auto isLight
    
    170
    +    = index == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    171
    +      || index == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel;
    
    172
    +  auto disableLCD
    
    173
    +    = index == AntiAliasingComboBoxModel::AntiAliasing_None
    
    174
    +      || index == AntiAliasingComboBoxModel::AntiAliasing::AntiAliasing_Normal
    
    175
    +      || isLight;
    
    176
    +
    
    177
    +  lcdFilterLabel_->setEnabled(!disableLCD);
    
    178
    +  lcdFilterComboBox_->setEnabled(!disableLCD);
    
    179
    +  stemDarkeningCheckBox_->setEnabled(isLight);
    
    180
    +  gammaSlider_->setEnabled(!isMono);
    
    181
    +
    
    182
    +  emit repaintNeeded();
    
    183
    +}
    
    184
    +
    
    185
    +
    
    186
    +void
    
    187
    +SettingPanel::checkPalette()
    
    188
    +{
    
    189
    +  paletteComboBox_->setEnabled(colorLayerCheckBox_->isChecked());
    
    190
    +  emit repaintNeeded();
    
    191
    +}
    
    192
    +
    
    193
    +
    
    194
    +void
    
    195
    +SettingPanel::checkStemDarkening()
    
    196
    +{
    
    197
    +  //if (!comparatorMode_)
    
    198
    +  //  applyDelayedSettings();
    
    199
    +
    
    200
    +  emit fontReloadNeeded();
    
    201
    +}
    
    202
    +
    
    203
    +
    
    204
    +void
    
    205
    +SettingPanel::openBackgroundPicker()
    
    206
    +{
    
    207
    +  auto result = QColorDialog::getColor(backgroundColor_, 
    
    208
    +                                       this,
    
    209
    +                                       tr("Background Color"));
    
    210
    +  if (result.isValid())
    
    211
    +  {
    
    212
    +    backgroundColor_ = result;
    
    213
    +    resetColorBlocks();
    
    214
    +    emit repaintNeeded();
    
    215
    +  }
    
    216
    +}
    
    217
    +
    
    218
    +
    
    219
    +void
    
    220
    +SettingPanel::openForegroundPicker()
    
    221
    +{
    
    222
    +  auto result = QColorDialog::getColor(foregroundColor_, 
    
    223
    +                                       this,
    
    224
    +                                       tr("Foreground Color"),
    
    225
    +                                       QColorDialog::ShowAlphaChannel);
    
    226
    +  if (result.isValid())
    
    227
    +  {
    
    228
    +    foregroundColor_ = result;
    
    229
    +    resetColorBlocks();
    
    230
    +    emit repaintNeeded();
    
    231
    +  }
    
    232
    +}
    
    233
    +
    
    234
    +
    
    235
    +void
    
    236
    +SettingPanel::updateGamma()
    
    237
    +{
    
    238
    +  gammaValueLabel_->setText(QString::number(gammaSlider_->value() / 10.0,
    
    239
    +                           'f',
    
    240
    +                           1));
    
    241
    +  emit repaintNeeded();
    
    242
    +}
    
    243
    +
    
    244
    +
    
    245
    +void
    
    246
    +SettingPanel::resetColorBlocks()
    
    247
    +{
    
    248
    +  foregroundBlock_->setStyleSheet(
    
    249
    +    QString("QWidget {background-color: rgba(%1, %2, %3, %4);}")
    
    250
    +      .arg(foregroundColor_.red())
    
    251
    +      .arg(foregroundColor_.green())
    
    252
    +      .arg(foregroundColor_.blue())
    
    253
    +      .arg(foregroundColor_.alpha()));
    
    254
    +  backgroundBlock_->setStyleSheet(
    
    255
    +    QString("QWidget {background-color: rgba(%1, %2, %3, %4);}")
    
    256
    +      .arg(backgroundColor_.red())
    
    257
    +      .arg(backgroundColor_.green())
    
    258
    +      .arg(backgroundColor_.blue())
    
    259
    +      .arg(backgroundColor_.alpha()));
    
    260
    +}
    
    261
    +
    
    262
    +
    
    263
    +void
    
    264
    +SettingPanel::onFontChanged()
    
    265
    +{
    
    266
    +  auto blockState = blockSignals(signalsBlocked());
    
    267
    +  
    
    268
    +  if (engine_->currentFontType() == Engine::FontType_CFF)
    
    269
    +  {
    
    270
    +    hintingModeComboBoxModel_->setCurrentEngineType(
    
    271
    +      HintingModeComboBoxModel::HintingEngineType_CFF, false);
    
    272
    +    hintingModeComboBox_->setCurrentIndex(currentCFFHintingMode_);
    
    273
    +  }
    
    274
    +  else if (engine_->currentFontType() == Engine::FontType_TrueType)
    
    275
    +  {
    
    276
    +    // TODO: tricky
    
    277
    +    hintingModeComboBoxModel_->setCurrentEngineType(
    
    278
    +      HintingModeComboBoxModel::HintingEngineType_TrueType, false);
    
    279
    +    hintingModeComboBox_->setCurrentIndex(currentTTInterpreterVersion_);
    
    280
    +  }
    
    281
    +  else
    
    282
    +  {
    
    283
    +    hintingModeLabel_->setEnabled(false);
    
    284
    +    hintingModeComboBox_->setEnabled(false);
    
    285
    +  }
    
    286
    +
    
    287
    +  checkHinting();
    
    288
    +
    
    289
    +  //engine_->reloadFont();
    
    290
    +  //auto hasColor = engine_->currentFontHasColorLayers();
    
    291
    +  //colorLayerCheckBox_->setEnabled(hasColor);
    
    292
    +  //if (!hasColor)
    
    293
    +  //  colorLayerCheckBox_->setChecked(false);
    
    294
    +  populatePalettes();
    
    295
    +  //mmgxPanel_->reloadFont();
    
    296
    +  blockSignals(blockState);
    
    297
    +
    
    298
    +  // Place this after `blockSignals` to let the signals emitted normally
    
    299
    +  //auto bmapOnly = engine_->currentFontBitmapOnly();
    
    300
    +  //embeddedBitmapCheckBox_->setEnabled(
    
    301
    +  //  !bmapOnly && engine_->currentFontHasEmbeddedBitmap());
    
    302
    +  //if (bmapOnly)
    
    303
    +  //  embeddedBitmapCheckBox_->setChecked(true);
    
    304
    +}
    
    305
    +
    
    306
    +
    
    307
    +void
    
    308
    +SettingPanel::applySettings()
    
    309
    +{
    
    310
    +  engine_->setLcdFilter(
    
    311
    +    static_cast<FT_LcdFilter>(lcdFilterComboboxModel_->indexToValue(
    
    312
    +      lcdFilterComboBox_->currentIndex())));
    
    313
    +
    
    314
    +  auto aaSettings = antiAliasingComboBoxModel_->indexToValue(
    
    315
    +    antiAliasingComboBox_->currentIndex());
    
    316
    +  engine_->setAntiAliasingTarget(aaSettings.loadFlag);
    
    317
    +  //engine_->setRenderMode(aaSettings.renderMode);
    
    318
    +
    
    319
    +  //engine_->setAntiAliasingEnabled(antiAliasingComboBox_->currentIndex()
    
    320
    +  //  != AntiAliasingComboBoxModel::AntiAliasing_None);
    
    321
    +  engine_->setHinting(hintingCheckBox_->isChecked());
    
    322
    +  engine_->setAutoHinting(autoHintingCheckBox_->isChecked());
    
    323
    +
    
    324
    +  if (debugMode_)
    
    325
    +  {
    
    326
    +    engine_->setHorizontalHinting(horizontalHintingCheckBox_->isChecked());
    
    327
    +    engine_->setVerticalHinting(verticalHintingCheckBox_->isChecked());
    
    328
    +    engine_->setBlueZoneHinting(blueZoneHintingCheckBox_->isChecked());
    
    329
    +    engine_->setShowSegments(segmentDrawingCheckBox_->isChecked());
    
    330
    +  }
    
    331
    +
    
    332
    +  engine_->setGamma(gammaSlider_->value() / 10.0);
    
    333
    +
    
    334
    +  //engine_->setEmbeddedBitmap(embeddedBitmapCheckBox_->isChecked());
    
    335
    +  //engine_->setPaletteIndex(paletteComboBox_->currentIndex());
    
    336
    +
    
    337
    +  //engine_->setUseColorLayer(colorLayerCheckBox_->isChecked());
    
    338
    +  //engine_->setLCDUsesBGR(aaSettings.isBGR);
    
    339
    +  //engine_->setLCDSubPixelPositioning(
    
    340
    +  //  antiAliasingComboBox_->currentIndex()
    
    341
    +  //    == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel);
    
    342
    +
    
    343
    +  //engine_->renderingEngine()->setForeground(foregroundColor_.rgba());
    
    344
    +  //engine_->renderingEngine()->setBackground(backgroundColor_.rgba());
    
    345
    +  //mmgxPanel_->applySettings();
    
    346
    +}
    
    347
    +
    
    348
    +
    
    349
    +void
    
    350
    +SettingPanel::applyDelayedSettings()
    
    351
    +{
    
    352
    +  // This must not be combined into `applySettings`:
    
    353
    +  // those engine manipulations will reset the whole cache!!
    
    354
    +  // Therefore must only be called when the selection of the combo box actually
    
    355
    +  // changes a.k.a. QComboBox::activate.
    
    356
    +
    
    357
    +  int index = hintingModeComboBox_->currentIndex();
    
    358
    +
    
    359
    +  if (engine_->currentFontType() == Engine::FontType_CFF)
    
    360
    +  {
    
    361
    +    engine_->setCFFHintingMode(
    
    362
    +      hintingModeComboBoxModel_->indexToCFFMode(index));
    
    363
    +    if (index >= 0)
    
    364
    +      currentCFFHintingMode_ = index;
    
    365
    +  }
    
    366
    +  else if (engine_->currentFontType() == Engine::FontType_TrueType)
    
    367
    +  {
    
    368
    +    engine_->setTTInterpreterVersion(
    
    369
    +      hintingModeComboBoxModel_->indexToTTInterpreterVersion(index));
    
    370
    +    if (index >= 0)
    
    371
    +      currentTTInterpreterVersion_ = index;
    
    372
    +  }
    
    373
    +
    
    374
    +  //engine_->setStemDarkening(stemDarkeningCheckBox_->isChecked());
    
    375
    +}
    
    376
    +
    
    377
    +
    
    378
    +void
    
    379
    +SettingPanel::createLayout()
    
    380
    +{
    
    381
    +  hintingCheckBox_ = new QCheckBox(tr("Hinting"), this);
    
    382
    +
    
    383
    +  hintingModeLabel_ = new QLabel(tr("Hinting Mode"), this);
    
    384
    +  hintingModeLabel_->setAlignment(Qt::AlignRight);
    
    385
    +
    
    386
    +  hintingModeComboBoxModel_ = new HintingModeComboBoxModel(this);
    
    387
    +  hintingModeComboBox_ = new QComboBox(this);
    
    388
    +  hintingModeComboBox_->setModel(hintingModeComboBoxModel_);
    
    389
    +  hintingModeLabel_->setBuddy(hintingModeComboBox_);
    
    390
    +
    
    391
    +  autoHintingCheckBox_ = new QCheckBox(tr("Auto-Hinting"), this);
    
    392
    +  stemDarkeningCheckBox_ = new QCheckBox(tr("Stem Darkening"), this);
    
    393
    +
    
    394
    +  if (debugMode_)
    
    395
    +  {
    
    396
    +    horizontalHintingCheckBox_ = new QCheckBox(tr("Horizontal Hinting"), this);
    
    397
    +    verticalHintingCheckBox_ = new QCheckBox(tr("Vertical Hinting"), this);
    
    398
    +    blueZoneHintingCheckBox_ = new QCheckBox(tr("Blue-Zone Hinting"), this);
    
    399
    +    segmentDrawingCheckBox_ = new QCheckBox(tr("Segment Drawing"), this);
    
    400
    +  }
    
    401
    +  
    
    402
    +  embeddedBitmapCheckBox_ = new QCheckBox(tr("Enable Embedded Bitmap"), this);
    
    403
    +  colorLayerCheckBox_ = new QCheckBox(tr("Enable Color Layer"), this);
    
    404
    +
    
    405
    +  antiAliasingLabel_ = new QLabel(tr("Anti-Aliasing"), this);
    
    406
    +  antiAliasingLabel_->setAlignment(Qt::AlignRight);
    
    407
    +
    
    408
    +  antiAliasingComboBoxModel_ = new AntiAliasingComboBoxModel(this);
    
    409
    +  antiAliasingComboBox_ = new QComboBox(this);
    
    410
    +  antiAliasingComboBox_->setModel(antiAliasingComboBoxModel_);
    
    411
    +  antiAliasingLabel_->setBuddy(antiAliasingComboBox_);
    
    412
    +
    
    413
    +  lcdFilterLabel_ = new QLabel(tr("LCD Filter"), this);
    
    414
    +  lcdFilterLabel_->setAlignment(Qt::AlignRight);
    
    415
    +
    
    416
    +  lcdFilterComboboxModel_ = new LCDFilterComboBoxModel(this);
    
    417
    +  lcdFilterComboBox_ = new QComboBox(this);
    
    418
    +  lcdFilterComboBox_->setModel(lcdFilterComboboxModel_);
    
    419
    +  lcdFilterLabel_->setBuddy(lcdFilterComboBox_);
    
    420
    +
    
    421
    +  paletteLabel_ = new QLabel(tr("Palette: "), this);
    
    422
    +
    
    423
    +  paletteComboBox_ = new QComboBox(this);
    
    424
    +  paletteLabel_->setBuddy(paletteComboBox_);
    
    425
    +
    
    426
    +  gammaLabel_ = new QLabel(tr("Gamma"), this);
    
    427
    +  gammaLabel_->setAlignment(Qt::AlignRight);
    
    428
    +  gammaSlider_ = new QSlider(Qt::Horizontal, this);
    
    429
    +  gammaSlider_->setRange(3, 30); // in 1/10th
    
    430
    +  gammaSlider_->setTickPosition(QSlider::TicksBelow);
    
    431
    +  gammaSlider_->setTickInterval(5);
    
    432
    +  gammaSlider_->setPageStep(1);
    
    433
    +  gammaSlider_->setSingleStep(1);
    
    434
    +  gammaLabel_->setBuddy(gammaSlider_);
    
    435
    +  gammaValueLabel_ = new QLabel(this);
    
    436
    +
    
    437
    +  // TODO: MM/GX
    
    438
    +  mmgxPanel_ = new QWidget(this);
    
    439
    +
    
    440
    +  backgroundButton_ = new QPushButton(tr("Background"), this);
    
    441
    +  foregroundButton_ = new QPushButton(tr("Foreground"), this);
    
    442
    +
    
    443
    +  backgroundBlock_ = new QFrame(this);
    
    444
    +  backgroundBlock_->setFrameStyle(QFrame::Box);
    
    445
    +  backgroundBlock_->setLineWidth(1);
    
    446
    +  backgroundBlock_->setFixedWidth(18);
    
    447
    +
    
    448
    +  foregroundBlock_ = new QFrame(this);
    
    449
    +  foregroundBlock_->setFrameStyle(QFrame::Box);
    
    450
    +  foregroundBlock_->setLineWidth(1);
    
    451
    +  foregroundBlock_->setFixedWidth(18);
    
    452
    +
    
    453
    +  generalTab_ = new QWidget(this);
    
    454
    +
    
    455
    +  generalTab_->setSizePolicy(QSizePolicy::MinimumExpanding,
    
    456
    +                             QSizePolicy::MinimumExpanding);
    
    457
    +
    
    458
    +  tab_ = new QTabWidget(this);
    
    459
    +  tab_->setSizePolicy(QSizePolicy::MinimumExpanding,
    
    460
    +                      QSizePolicy::MinimumExpanding);
    
    461
    +
    
    462
    +  // Tooltips
    
    463
    +  hintingCheckBox_->setToolTip(tr("Enable hinting a.k.a. grid-fitting."));
    
    464
    +  hintingModeComboBox_->setToolTip(
    
    465
    +    tr("Modes not available for current font type will be disabled. No "
    
    466
    +       "effect when auto-hinting is enabled"));
    
    467
    +  autoHintingCheckBox_->setToolTip(tr("Enable FreeType Auto-Hinter."));
    
    468
    +  if (debugMode_)
    
    469
    +  {
    
    470
    +    horizontalHintingCheckBox_->setToolTip(tr("(auto-hinter debug option)"));
    
    471
    +    verticalHintingCheckBox_  ->setToolTip(tr("(auto-hinter debug option)"));
    
    472
    +    blueZoneHintingCheckBox_  ->setToolTip(tr("(auto-hinter debug option)"));
    
    473
    +    segmentDrawingCheckBox_   ->setToolTip(tr("(auto-hinter debug option)"));
    
    474
    +  }
    
    475
    +  antiAliasingComboBox_->setToolTip(tr("Select anti-aliasing mode."));
    
    476
    +  lcdFilterComboBox_->setToolTip(
    
    477
    +    tr("Select LCD filter (only valid when LCD AA is enabled)."));
    
    478
    +  embeddedBitmapCheckBox_->setToolTip(tr(
    
    479
    +    "Enable embedded bitmap strikes (force enabled for bitmap-only fonts)."));
    
    480
    +  stemDarkeningCheckBox_->setToolTip(
    
    481
    +    tr("Enable stem darkening (only valid for auto-hinter with gamma "
    
    482
    +       "correction enabled and with Light AA modes)."));
    
    483
    +  gammaSlider_->setToolTip("Gamma correction value.");
    
    484
    +  colorLayerCheckBox_->setToolTip(tr("Enable color layer rendering."));
    
    485
    +  paletteComboBox_->setToolTip(tr("Select color layer palette (only valid when "
    
    486
    +                                  "any palette exists in the font)."));
    
    487
    +  backgroundButton_->setToolTip(tr("Set canvas background color."));
    
    488
    +  foregroundButton_->setToolTip(tr("Set text color."));
    
    489
    +
    
    490
    +  // Layouting
    
    491
    +  if (debugMode_)
    
    492
    +  {
    
    493
    +    debugLayout_ = new QVBoxLayout;
    
    494
    +    debugLayout_->setContentsMargins(20, 0, 0, 0);
    
    495
    +    debugLayout_->addWidget(horizontalHintingCheckBox_);
    
    496
    +    debugLayout_->addWidget(verticalHintingCheckBox_);
    
    497
    +    debugLayout_->addWidget(blueZoneHintingCheckBox_);
    
    498
    +    debugLayout_->addWidget(segmentDrawingCheckBox_);
    
    499
    +  }
    
    500
    +
    
    501
    +  gammaLayout_ = new QHBoxLayout;
    
    502
    +  gammaLayout_->addWidget(gammaLabel_);
    
    503
    +  gammaLayout_->addWidget(gammaSlider_);
    
    504
    +  gammaLayout_->addWidget(gammaValueLabel_);
    
    505
    +
    
    506
    +  colorPickerLayout_ = new QHBoxLayout;
    
    507
    +  colorPickerLayout_->addWidget(backgroundBlock_);
    
    508
    +  colorPickerLayout_->addWidget(backgroundButton_, 1);
    
    509
    +  colorPickerLayout_->addWidget(foregroundButton_, 1);
    
    510
    +  colorPickerLayout_->addWidget(foregroundBlock_);
    
    511
    +
    
    512
    +  createLayoutNormal();
    
    513
    +  // TODO: Comparator mode.
    
    514
    +
    
    515
    +  mainLayout_ = new QVBoxLayout;
    
    516
    +  mainLayout_->addWidget(tab_);
    
    517
    +  setLayout(mainLayout_);
    
    518
    +  mainLayout_->setContentsMargins(0, 0, 0, 0);
    
    519
    +  setContentsMargins(0, 0, 0, 0);
    
    520
    +}
    
    521
    +
    
    522
    +
    
    523
    +void
    
    524
    +SettingPanel::createLayoutNormal()
    
    525
    +{
    
    526
    +  generalTabLayout_ = new QGridLayout;
    
    527
    +
    
    528
    +  gridLayout2ColAddWidget(generalTabLayout_, hintingCheckBox_);
    
    529
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    530
    +                          hintingModeLabel_, hintingModeComboBox_);
    
    531
    +  gridLayout2ColAddWidget(generalTabLayout_, autoHintingCheckBox_);
    
    532
    +
    
    533
    +  if (debugMode_)
    
    534
    +    gridLayout2ColAddLayout(generalTabLayout_, debugLayout_);
    
    535
    +  
    
    536
    +  gridLayout2ColAddItem(generalTabLayout_,
    
    537
    +                        new QSpacerItem(0, 20, QSizePolicy::Minimum,
    
    538
    +                                        QSizePolicy::MinimumExpanding));
    
    539
    +
    
    540
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    541
    +                          antiAliasingLabel_, antiAliasingComboBox_);
    
    542
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    543
    +                          lcdFilterLabel_, lcdFilterComboBox_);
    
    544
    +  
    
    545
    +  gridLayout2ColAddItem(generalTabLayout_,
    
    546
    +                        new QSpacerItem(0, 20, QSizePolicy::Minimum,
    
    547
    +                                        QSizePolicy::MinimumExpanding));
    
    548
    +
    
    549
    +  gridLayout2ColAddLayout(generalTabLayout_, colorPickerLayout_);
    
    550
    +  gridLayout2ColAddLayout(generalTabLayout_, gammaLayout_);
    
    551
    +  gridLayout2ColAddWidget(generalTabLayout_, stemDarkeningCheckBox_);
    
    552
    +  gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
    
    553
    +  gridLayout2ColAddWidget(generalTabLayout_, colorLayerCheckBox_);
    
    554
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    555
    +                          paletteLabel_, paletteComboBox_);
    
    556
    +  
    
    557
    +  gridLayout2ColAddItem(generalTabLayout_,
    
    558
    +                        new QSpacerItem(0, 20, QSizePolicy::Minimum,
    
    559
    +                                        QSizePolicy::MinimumExpanding));
    
    560
    +
    
    561
    +  generalTabLayout_->setColumnStretch(1, 1);
    
    562
    +  generalTab_->setLayout(generalTabLayout_);
    
    563
    +
    
    564
    +  tab_->addTab(generalTab_, tr("General"));
    
    565
    +  tab_->addTab(mmgxPanel_, tr("MM/GX"));
    
    566
    +
    
    567
    +  tab_->setTabToolTip(0, tr("General settings."));
    
    568
    +  tab_->setTabToolTip(1, tr("MM/GX axis parameters."));
    
    569
    +}
    
    570
    +
    
    571
    +
    
    572
    +void
    
    573
    +SettingPanel::createConnections()
    
    574
    +{
    
    575
    +  // use `qOverload` here to prevent ambiguity.
    
    576
    +  connect(hintingModeComboBox_, 
    
    577
    +          QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    578
    +          this, &SettingPanel::checkHintingMode);
    
    579
    +  connect(antiAliasingComboBox_,
    
    580
    +          QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    581
    +          this, &SettingPanel::checkAntiAliasing);
    
    582
    +  connect(lcdFilterComboBox_, 
    
    583
    +          QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    584
    +          this, &SettingPanel::repaintNeeded);
    
    585
    +  connect(paletteComboBox_,
    
    586
    +          QOverload<int>::of(&QComboBox::currentIndexChanged), 
    
    587
    +          this, &SettingPanel::repaintNeeded);
    
    588
    +
    
    589
    +  connect(gammaSlider_, &QSlider::valueChanged,
    
    590
    +          this, &SettingPanel::updateGamma);
    
    591
    +  
    
    592
    +  connect(hintingCheckBox_, &QCheckBox::clicked,
    
    593
    +          this, &SettingPanel::checkHinting);
    
    594
    +
    
    595
    +  if (debugMode_)
    
    596
    +  {
    
    597
    +    connect(horizontalHintingCheckBox_, &QCheckBox::clicked,
    
    598
    +            this, &SettingPanel::repaintNeeded);
    
    599
    +    connect(verticalHintingCheckBox_, &QCheckBox::clicked,
    
    600
    +            this, &SettingPanel::repaintNeeded);
    
    601
    +    connect(blueZoneHintingCheckBox_, &QCheckBox::clicked,
    
    602
    +            this, &SettingPanel::repaintNeeded);
    
    603
    +    connect(segmentDrawingCheckBox_, &QCheckBox::clicked,
    
    604
    +            this, &SettingPanel::repaintNeeded);
    
    605
    +  }
    
    606
    +
    
    607
    +  connect(autoHintingCheckBox_, &QCheckBox::clicked,
    
    608
    +          this, &SettingPanel::checkAutoHinting);
    
    609
    +  connect(embeddedBitmapCheckBox_, &QCheckBox::clicked,
    
    610
    +          this, &SettingPanel::fontReloadNeeded);
    
    611
    +  connect(stemDarkeningCheckBox_, &QCheckBox::clicked,
    
    612
    +          this, &SettingPanel::checkStemDarkening);
    
    613
    +  connect(colorLayerCheckBox_, &QCheckBox::clicked,
    
    614
    +          this, &SettingPanel::checkPalette);
    
    615
    +
    
    616
    +  connect(backgroundButton_, &QPushButton::clicked,
    
    617
    +          this, &SettingPanel::openBackgroundPicker);
    
    618
    +  connect(foregroundButton_, &QPushButton::clicked,
    
    619
    +          this, &SettingPanel::openForegroundPicker);
    
    620
    +}
    
    621
    +
    
    622
    +
    
    623
    +void
    
    624
    +SettingPanel::setDefaults()
    
    625
    +{
    
    626
    +  Engine::EngineDefaultValues& defaults = engine_->engineDefaults();
    
    627
    +
    
    628
    +  hintingModeComboBoxModel_->setSupportedModes(
    
    629
    +    { defaults.ttInterpreterVersionDefault,
    
    630
    +      defaults.ttInterpreterVersionOther,
    
    631
    +      defaults.ttInterpreterVersionOther1 },
    
    632
    +    { defaults.cffHintingEngineDefault, 
    
    633
    +      defaults.cffHintingEngineOther });
    
    634
    +
    
    635
    +  currentCFFHintingMode_
    
    636
    +    = hintingModeComboBoxModel_->cffModeToIndex(
    
    637
    +    defaults.cffHintingEngineDefault);
    
    638
    +  currentTTInterpreterVersion_
    
    639
    +    = hintingModeComboBoxModel_->ttInterpreterVersionToIndex(
    
    640
    +        defaults.ttInterpreterVersionDefault);
    
    641
    +
    
    642
    +  hintingCheckBox_->setChecked(true);
    
    643
    +
    
    644
    +  antiAliasingComboBox_->setCurrentIndex(
    
    645
    +    AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    646
    +  lcdFilterComboBox_->setCurrentIndex(
    
    647
    +    LCDFilterComboBoxModel::LCDFilter_Light);
    
    648
    +
    
    649
    +  if (debugMode_)
    
    650
    +  {
    
    651
    +    horizontalHintingCheckBox_->setChecked(true);
    
    652
    +    verticalHintingCheckBox_->setChecked(true);
    
    653
    +    blueZoneHintingCheckBox_->setChecked(true);
    
    654
    +    embeddedBitmapCheckBox_->setChecked(false);
    
    655
    +  }
    
    656
    +  
    
    657
    +  colorLayerCheckBox_->setChecked(true);
    
    658
    +  paletteComboBox_->setEnabled(false);
    
    659
    +
    
    660
    +  // These need to be set even in Comperator mode.
    
    661
    +  backgroundColor_ = Qt::white;
    
    662
    +  foregroundColor_ = Qt::black;
    
    663
    +  resetColorBlocks();
    
    664
    +
    
    665
    +  gammaSlider_->setValue(18); // 1.8
    
    666
    +  updateGamma();
    
    667
    +}
    
    668
    +
    
    669
    +
    
    670
    +// end of settingpanel.cpp

  • src/ftinspect/panels/settingpanel.hpp
    1
    +// settingpanel.hpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#pragma once
    
    6
    +
    
    7
    +#include "../engine/engine.hpp"
    
    8
    +#include "../models/customcomboboxmodels.hpp"
    
    9
    +
    
    10
    +#include <QWidget>
    
    11
    +#include <QTabWidget>
    
    12
    +#include <QLabel>
    
    13
    +#include <QComboBox>
    
    14
    +#include <QCheckBox>
    
    15
    +#include <QGridLayout>
    
    16
    +#include <QBoxLayout>
    
    17
    +#include <QPushButton>
    
    18
    +
    
    19
    +class SettingPanel
    
    20
    +: public QWidget
    
    21
    +{
    
    22
    +  Q_OBJECT
    
    23
    +public:
    
    24
    +  SettingPanel(QWidget* parent, Engine* engine);
    
    25
    +  ~SettingPanel() override = default;
    
    26
    +
    
    27
    +  void onFontChanged();
    
    28
    +  void applySettings();
    
    29
    +  /*
    
    30
    +   * When in comparator mode, this is needed to sync the hinting modes when
    
    31
    +   * reloading the font.
    
    32
    +   */
    
    33
    +  void applyDelayedSettings();
    
    34
    +
    
    35
    +  //////// Getters/Setters
    
    36
    +
    
    37
    +  int antiAliasingModeIndex();
    
    38
    +  bool kerningEnabled();
    
    39
    +  bool lsbRsbDeltaEnabled();
    
    40
    +
    
    41
    +signals:
    
    42
    +  void fontReloadNeeded();
    
    43
    +  void repaintNeeded();
    
    44
    +
    
    45
    +private:
    
    46
    +  Engine* engine_;
    
    47
    +
    
    48
    +  int currentCFFHintingMode_;
    
    49
    +  int currentTTInterpreterVersion_;
    
    50
    +  
    
    51
    +  bool debugMode_ = false;
    
    52
    +
    
    53
    +  QTabWidget* tab_;
    
    54
    +
    
    55
    +  QWidget* generalTab_;
    
    56
    +  QWidget* hintingRenderingTab_;
    
    57
    +  //SettingPanelMMGX* mmgxPanel_;
    
    58
    +  QWidget* mmgxPanel_;
    
    59
    +
    
    60
    +  QLabel* gammaLabel_;
    
    61
    +  QLabel* gammaValueLabel_;
    
    62
    +  QLabel* antiAliasingLabel_;
    
    63
    +  QLabel* hintingModeLabel_;
    
    64
    +  QLabel* lcdFilterLabel_;
    
    65
    +  QLabel* paletteLabel_;
    
    66
    +
    
    67
    +  QCheckBox* hintingCheckBox_;
    
    68
    +  QCheckBox* horizontalHintingCheckBox_;
    
    69
    +  QCheckBox* verticalHintingCheckBox_;
    
    70
    +  QCheckBox* blueZoneHintingCheckBox_;
    
    71
    +  QCheckBox* segmentDrawingCheckBox_;
    
    72
    +  QCheckBox* autoHintingCheckBox_;
    
    73
    +  QCheckBox* stemDarkeningCheckBox_;
    
    74
    +  QCheckBox* embeddedBitmapCheckBox_;
    
    75
    +  QCheckBox* colorLayerCheckBox_;
    
    76
    +  QCheckBox* kerningCheckBox_;
    
    77
    +  QCheckBox* lsbRsbDeltaCheckBox_;
    
    78
    +
    
    79
    +  AntiAliasingComboBoxModel* antiAliasingComboBoxModel_;
    
    80
    +  HintingModeComboBoxModel* hintingModeComboBoxModel_;
    
    81
    +  LCDFilterComboBoxModel* lcdFilterComboboxModel_;
    
    82
    +
    
    83
    +  QComboBox* hintingModeComboBox_;
    
    84
    +  QComboBox* antiAliasingComboBox_;
    
    85
    +  QComboBox* lcdFilterComboBox_;
    
    86
    +  QComboBox* paletteComboBox_;
    
    87
    +
    
    88
    +  QSlider* gammaSlider_;
    
    89
    +
    
    90
    +  QPushButton* backgroundButton_;
    
    91
    +  QPushButton* foregroundButton_;
    
    92
    +  QFrame* backgroundBlock_;
    
    93
    +  QFrame* foregroundBlock_;
    
    94
    +
    
    95
    +  QVBoxLayout* mainLayout_;
    
    96
    +  QGridLayout* generalTabLayout_;
    
    97
    +  QGridLayout* hintingRenderingTabLayout_;
    
    98
    +  QVBoxLayout* debugLayout_;
    
    99
    +  QHBoxLayout* gammaLayout_;
    
    100
    +  QHBoxLayout* colorPickerLayout_;
    
    101
    +
    
    102
    +  QColor backgroundColor_;
    
    103
    +  QColor foregroundColor_;
    
    104
    +
    
    105
    +  //////// Initializing funcs
    
    106
    +
    
    107
    +  void createConnections();
    
    108
    +  void createLayout();
    
    109
    +  void createLayoutNormal();
    
    110
    +  void setDefaults();
    
    111
    +
    
    112
    +  //////// Other funcs
    
    113
    +
    
    114
    +  void populatePalettes();
    
    115
    +
    
    116
    +  void checkAllSettings();
    
    117
    +  void checkHinting();
    
    118
    +  void checkHintingMode();
    
    119
    +  void checkAutoHinting();
    
    120
    +  void checkAntiAliasing();
    
    121
    +  void checkPalette();
    
    122
    +  void checkStemDarkening();
    
    123
    +
    
    124
    +  void openBackgroundPicker();
    
    125
    +  void openForegroundPicker();
    
    126
    +  void updateGamma();
    
    127
    +  void resetColorBlocks();
    
    128
    +};
    
    129
    +
    
    130
    +
    
    131
    +// end of settingpanel.hpp

  • src/ftinspect/widgets/tripletselector.cpp
    1
    +// tripletselector.cpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#include "tripletselector.hpp"
    
    6
    +
    
    7
    +#include "../engine/engine.hpp"
    
    8
    +
    
    9
    +#include <functional>
    
    10
    +
    
    11
    +TripletSelector::TripletSelector(QWidget* parent,
    
    12
    +                                 Engine* engine)
    
    13
    +: QWidget(parent),
    
    14
    +  engine_(engine)
    
    15
    +{
    
    16
    +  createLayout();
    
    17
    +  createConnections();
    
    18
    +  checkButtons();
    
    19
    +}
    
    20
    +
    
    21
    +
    
    22
    +TripletSelector::~TripletSelector()
    
    23
    +{
    
    24
    +}
    
    25
    +
    
    26
    +
    
    27
    +void
    
    28
    +TripletSelector::repopulateFonts()
    
    29
    +{
    
    30
    +  auto oldSize = fontComboBox_->count();
    
    31
    +  auto oldIndex = fontComboBox_->currentIndex();
    
    32
    +
    
    33
    +  {
    
    34
    +    QSignalBlocker blk(fontComboBox_);
    
    35
    +    QSignalBlocker blk2(faceComboBox_);
    
    36
    +    QSignalBlocker blk3(niComboBox_);
    
    37
    +    fontComboBox_->clear();
    
    38
    +    
    
    39
    +    auto& ffm = engine_->fontFileManager();
    
    40
    +    auto newSize = ffm.size();
    
    41
    +    for (int i = 0; i < newSize; i++)
    
    42
    +    {
    
    43
    +      auto& info = ffm[i];
    
    44
    +      auto name = info.filePath();
    
    45
    +      auto displayName = info.fileName();
    
    46
    +      if (info.isSymbolicLink())
    
    47
    +        displayName += " [symlink]";
    
    48
    +
    
    49
    +      fontComboBox_->addItem(displayName, name);
    
    50
    +    }
    
    51
    +
    
    52
    +    if (newSize > oldSize)
    
    53
    +    {
    
    54
    +      // if we have new fonts, set the current index to the first new one
    
    55
    +      fontComboBox_->setCurrentIndex(oldSize);
    
    56
    +    }
    
    57
    +    else if (newSize < oldSize)
    
    58
    +    {
    
    59
    +      if (oldIndex >= newSize)
    
    60
    +        oldIndex = newSize - 1;
    
    61
    +      if (oldIndex < 0)
    
    62
    +        oldIndex = -1;
    
    63
    +      fontComboBox_->setCurrentIndex(oldIndex);
    
    64
    +    }
    
    65
    +
    
    66
    +    // Note no signal will be emitted from any combobox until this block ends
    
    67
    +  }
    
    68
    +
    
    69
    +  // This will check buttons & reload the triplet
    
    70
    +  repopulateFaces();
    
    71
    +}
    
    72
    +
    
    73
    +
    
    74
    +void
    
    75
    +TripletSelector::repopulateFaces(bool fontSwitched)
    
    76
    +{
    
    77
    +  // Avoid unnecessary recreating, to reduce interruption of user oper
    
    78
    +  auto needToRecreate = fontSwitched;
    
    79
    +  auto oldSize = faceComboBox_->count();
    
    80
    +
    
    81
    +  auto fontIndex = fontComboBox_->currentIndex();
    
    82
    +  auto newSize = engine_->numberOfFaces(fontIndex);
    
    83
    +
    
    84
    +  if (fontIndex < 0 || newSize < 0)
    
    85
    +  {
    
    86
    +    // Clear and go
    
    87
    +    faceComboBox_->clear();
    
    88
    +    // This will check buttons & reload the triplet
    
    89
    +    repopulateNamedInstances(fontSwitched);
    
    90
    +    return;
    
    91
    +  }
    
    92
    +
    
    93
    +  if (newSize != oldSize)
    
    94
    +    needToRecreate = true;
    
    95
    +
    
    96
    +  std::vector<QString> newFaces;
    
    97
    +  newFaces.reserve(newSize);
    
    98
    +  for (long i = 0; i < newSize; i++)
    
    99
    +  {
    
    100
    +    newFaces.emplace_back(engine_->namedInstanceName(fontIndex, i, 0));
    
    101
    +    if (!needToRecreate && newFaces[i] != faceComboBox_->itemData(i))
    
    102
    +      needToRecreate = true;
    
    103
    +  }
    
    104
    +
    
    105
    +  if (!needToRecreate)
    
    106
    +  {
    
    107
    +    // no need to refersh the combobox
    
    108
    +    // This will check buttons & reload the triplet
    
    109
    +    repopulateNamedInstances(fontSwitched);
    
    110
    +    return;
    
    111
    +  }
    
    112
    +
    
    113
    +  {
    
    114
    +    QSignalBlocker blk2(faceComboBox_);
    
    115
    +    QSignalBlocker blk3(niComboBox_);
    
    116
    +    faceComboBox_->clear();
    
    117
    +
    
    118
    +    for (long i = 0; i < newSize; i++)
    
    119
    +    {
    
    120
    +      auto& name = newFaces[i];
    
    121
    +      auto displayName = QString("%1: %2").arg(i).arg(name);
    
    122
    +      faceComboBox_->addItem(displayName, name);
    
    123
    +    }
    
    124
    +
    
    125
    +    faceComboBox_->setCurrentIndex(0);
    
    126
    +    // Note no signal will be emitted from any combobox until this block ends
    
    127
    +  }
    
    128
    +
    
    129
    +  // This will check buttons & reload the triplet
    
    130
    +  repopulateNamedInstances(true);
    
    131
    +}
    
    132
    +
    
    133
    +
    
    134
    +void
    
    135
    +TripletSelector::repopulateNamedInstances(bool fontSwitched)
    
    136
    +{
    
    137
    +  // Avoid unnecessary recreating, to reduce interruption of user oper
    
    138
    +  // Similar to `repopulateFaces`
    
    139
    +  auto needToRecreate = fontSwitched;
    
    140
    +  auto oldSize = niComboBox_->count();
    
    141
    +
    
    142
    +  auto fontIndex = fontComboBox_->currentIndex();
    
    143
    +  auto faceIndex = faceComboBox_->currentIndex();
    
    144
    +  auto newSize = engine_->numberOfNamedInstances(fontIndex, faceIndex);
    
    145
    +
    
    146
    +  if (fontIndex < 0 || faceIndex < 0 || newSize < 0)
    
    147
    +  {
    
    148
    +    // Clear and go, don't forget checking buttons and loading triplet
    
    149
    +    niComboBox_->clear();
    
    150
    +    checkButtons();
    
    151
    +    loadTriplet();
    
    152
    +    return;
    
    153
    +  }
    
    154
    +
    
    155
    +  if (newSize != oldSize)
    
    156
    +    needToRecreate = true;
    
    157
    +
    
    158
    +  std::vector<QString> newFaces;
    
    159
    +  newFaces.reserve(newSize);
    
    160
    +  for (long i = 0; i < newSize; i++)
    
    161
    +  {
    
    162
    +    newFaces.emplace_back(engine_->namedInstanceName(fontIndex, faceIndex, i));
    
    163
    +    if (!needToRecreate && newFaces[i] != niComboBox_->itemData(i))
    
    164
    +      needToRecreate = true;
    
    165
    +  }
    
    166
    +
    
    167
    +  niComboBox_->setEnabled(newSize > 1);
    
    168
    +
    
    169
    +  if (!needToRecreate)
    
    170
    +  {
    
    171
    +    // no need to refersh the combobox
    
    172
    +    checkButtons();
    
    173
    +    loadTriplet();
    
    174
    +    return;
    
    175
    +  }
    
    176
    +
    
    177
    +  {
    
    178
    +    QSignalBlocker blk3(niComboBox_);
    
    179
    +    niComboBox_->clear();
    
    180
    +
    
    181
    +    for (long i = 0; i < newSize; i++)
    
    182
    +    {
    
    183
    +      auto& name = newFaces[i];
    
    184
    +      auto displayName = QString("%1: %2").arg(i).arg(name);
    
    185
    +      if (i == 0)
    
    186
    +        displayName = "* " + displayName;
    
    187
    +      niComboBox_->addItem(displayName, name);
    
    188
    +    }
    
    189
    +
    
    190
    +    niComboBox_->setCurrentIndex(0);
    
    191
    +    // Note no signal will be emitted from any combobox until this block ends
    
    192
    +  }
    
    193
    +
    
    194
    +  checkButtons();
    
    195
    +  loadTriplet();
    
    196
    +}
    
    197
    +
    
    198
    +
    
    199
    +void
    
    200
    +TripletSelector::closeCurrentFont()
    
    201
    +{
    
    202
    +  auto idx = fontComboBox_->currentIndex();
    
    203
    +  if (idx < 0)
    
    204
    +    return;
    
    205
    +  engine_->fontFileManager().remove(idx);
    
    206
    +
    
    207
    +  // show next font after deletion, i.e., retain index if possible
    
    208
    +  int num = engine_->numberOfOpenedFonts();
    
    209
    +  if (num)
    
    210
    +  {
    
    211
    +    if (idx >= num)
    
    212
    +      idx = num - 1;
    
    213
    +  }
    
    214
    +  else
    
    215
    +    idx = -1;
    
    216
    +
    
    217
    +  {
    
    218
    +    // Shut up when repopulating
    
    219
    +    QSignalBlocker blockerThis(this);
    
    220
    +    QSignalBlocker blockerComboBox(fontComboBox_);
    
    221
    +    repopulateFonts();
    
    222
    +  }
    
    223
    +
    
    224
    +  if (idx != -1)
    
    225
    +    faceComboBox_->setCurrentIndex(idx);
    
    226
    +  updateFont();
    
    227
    +}
    
    228
    +
    
    229
    +
    
    230
    +void
    
    231
    +TripletSelector::updateFont()
    
    232
    +{
    
    233
    +  auto idx = fontComboBox_->currentIndex();
    
    234
    +  auto num = engine_->numberOfOpenedFonts();
    
    235
    +  if (idx < 0)
    
    236
    +  {
    
    237
    +    faceComboBox_->clear();
    
    238
    +    niComboBox_->clear();
    
    239
    +
    
    240
    +    checkButtons();
    
    241
    +    loadTriplet();
    
    242
    +    return;
    
    243
    +  }
    
    244
    +
    
    245
    +  if (num <= 0 || idx >= num)
    
    246
    +  {
    
    247
    +    // out of sync: this shouldn't happen
    
    248
    +    repopulateFonts();
    
    249
    +    return;
    
    250
    +  }
    
    251
    +
    
    252
    +  // This will check buttons & reload the triplet
    
    253
    +  repopulateFaces();
    
    254
    +}
    
    255
    +
    
    256
    +
    
    257
    +void
    
    258
    +TripletSelector::updateFace()
    
    259
    +{
    
    260
    +  auto idx = faceComboBox_->currentIndex();
    
    261
    +  auto num = engine_->numberOfFaces(fontComboBox_->currentIndex());
    
    262
    +  
    
    263
    +  if (idx >= num)
    
    264
    +  {
    
    265
    +    // out of sync
    
    266
    +    repopulateFaces();
    
    267
    +    return;
    
    268
    +  }
    
    269
    +
    
    270
    +  // This will check buttons & reload the triplet
    
    271
    +  repopulateNamedInstances();
    
    272
    +}
    
    273
    +
    
    274
    +
    
    275
    +void
    
    276
    +TripletSelector::updateNI()
    
    277
    +{
    
    278
    +  auto idx = niComboBox_->currentIndex();
    
    279
    +  auto num = engine_->numberOfNamedInstances(fontComboBox_->currentIndex(),
    
    280
    +                                             faceComboBox_->currentIndex());
    
    281
    +  
    
    282
    +  if (idx >= num)
    
    283
    +  {
    
    284
    +    // out of sync
    
    285
    +    repopulateNamedInstances();
    
    286
    +    return;
    
    287
    +  }
    
    288
    +
    
    289
    +  checkButtons();
    
    290
    +  loadTriplet();
    
    291
    +}
    
    292
    +
    
    293
    +
    
    294
    +void
    
    295
    +TripletSelector::checkButtons()
    
    296
    +{
    
    297
    +  fontUpButton_->setEnabled(fontComboBox_->currentIndex() > 0);
    
    298
    +  fontDownButton_->setEnabled(fontComboBox_->currentIndex()
    
    299
    +                              < fontComboBox_->count() - 1);
    
    300
    +  closeFontButton_->setEnabled(faceComboBox_->currentIndex() >= 0);
    
    301
    +
    
    302
    +  faceUpButton_->setEnabled(faceComboBox_->currentIndex() > 0);
    
    303
    +  faceDownButton_->setEnabled(faceComboBox_->currentIndex()
    
    304
    +                              < faceComboBox_->count() - 1);
    
    305
    +
    
    306
    +  niUpButton_->setEnabled(niComboBox_->currentIndex() > 0);
    
    307
    +  niDownButton_->setEnabled(niComboBox_->currentIndex()
    
    308
    +                            < niComboBox_->count() - 1);
    
    309
    +}
    
    310
    +
    
    311
    +
    
    312
    +void
    
    313
    +TripletSelector::watchCurrentFont()
    
    314
    +{
    
    315
    +  repopulateFaces(false);
    
    316
    +}
    
    317
    +
    
    318
    +
    
    319
    +void
    
    320
    +TripletSelector::createLayout()
    
    321
    +{
    
    322
    +  fontComboBox_ = new QComboBox(this);
    
    323
    +  faceComboBox_ = new QComboBox(this);
    
    324
    +  niComboBox_   = new QComboBox(this);
    
    325
    +
    
    326
    +  fontComboBox_->setPlaceholderText(tr("No font open"));
    
    327
    +  faceComboBox_->setPlaceholderText(tr("No face available"));
    
    328
    +  niComboBox_->setPlaceholderText(tr("No named instance available"));
    
    329
    +  
    
    330
    +  closeFontButton_ = new QToolButton(this);
    
    331
    +  fontUpButton_    = new QToolButton(this);
    
    332
    +  faceUpButton_    = new QToolButton(this);
    
    333
    +  niUpButton_      = new QToolButton(this);
    
    334
    +  fontDownButton_  = new QToolButton(this);
    
    335
    +  faceDownButton_  = new QToolButton(this);
    
    336
    +  niDownButton_    = new QToolButton(this);
    
    337
    +
    
    338
    +  closeFontButton_->setText(tr("Close"));
    
    339
    +  fontUpButton_   ->setText(tr("\xE2\x86\x91"));
    
    340
    +  faceUpButton_   ->setText(tr("\xE2\x86\x91"));
    
    341
    +  niUpButton_     ->setText(tr("\xE2\x86\x91"));
    
    342
    +  fontDownButton_ ->setText(tr("\xE2\x86\x93"));
    
    343
    +  faceDownButton_ ->setText(tr("\xE2\x86\x93"));
    
    344
    +  niDownButton_   ->setText(tr("\xE2\x86\x93"));
    
    345
    +  
    
    346
    +  fontComboBox_   ->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
    
    347
    +  faceComboBox_   ->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
    
    348
    +  niComboBox_     ->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
    
    349
    +  closeFontButton_->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
    
    350
    +  fontUpButton_   ->setFixedSize(30, 30);
    
    351
    +  faceUpButton_   ->setFixedSize(30, 30);
    
    352
    +  niUpButton_     ->setFixedSize(30, 30);
    
    353
    +  fontDownButton_ ->setFixedSize(30, 30);
    
    354
    +  faceDownButton_ ->setFixedSize(30, 30);
    
    355
    +  niDownButton_   ->setFixedSize(30, 30);
    
    356
    +
    
    357
    +  // Tooltips
    
    358
    +  fontComboBox_->setToolTip(tr("Current font"));
    
    359
    +  faceComboBox_->setToolTip(tr("Current subfont (face)"));
    
    360
    +  niComboBox_->setToolTip(
    
    361
    +    tr("Current named instance (only available for variable fonts)"));
    
    362
    +  closeFontButton_->setToolTip(tr("Close current font"));
    
    363
    +  fontUpButton_   ->setToolTip(tr("Previous font"));
    
    364
    +  faceUpButton_   ->setToolTip(tr("Previous subfont (face)"));
    
    365
    +  niUpButton_     ->setToolTip(tr("Previous named instance"));
    
    366
    +  fontDownButton_ ->setToolTip(tr("Next font"));
    
    367
    +  faceDownButton_ ->setToolTip(tr("Next subfont (face)"));
    
    368
    +  niDownButton_   ->setToolTip(tr("Next named instance"));
    
    369
    +
    
    370
    +  // Layouting
    
    371
    +  layout_ = new QHBoxLayout;
    
    372
    +  layout_->setSpacing(0);
    
    373
    +  layout_->setContentsMargins(0, 0, 0, 0);
    
    374
    +
    
    375
    +  layout_->addWidget(fontComboBox_);
    
    376
    +  layout_->addWidget(fontUpButton_);
    
    377
    +  layout_->addWidget(fontDownButton_);
    
    378
    +  layout_->addWidget(closeFontButton_);
    
    379
    +  layout_->addWidget(faceComboBox_);
    
    380
    +  layout_->addWidget(faceUpButton_);
    
    381
    +  layout_->addWidget(faceDownButton_);
    
    382
    +  layout_->addWidget(niComboBox_);
    
    383
    +  layout_->addWidget(niUpButton_);
    
    384
    +  layout_->addWidget(niDownButton_);
    
    385
    +
    
    386
    +  setFixedHeight(30);
    
    387
    +  setLayout(layout_);
    
    388
    +  layout_->setContentsMargins(0, 0, 0, 0);
    
    389
    +}
    
    390
    +
    
    391
    +
    
    392
    +void
    
    393
    +TripletSelector::createConnections()
    
    394
    +{
    
    395
    +  connect(fontComboBox_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    396
    +          this, &TripletSelector::updateFont);
    
    397
    +  connect(faceComboBox_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    398
    +          this, &TripletSelector::updateFace);
    
    399
    +  connect(niComboBox_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    400
    +          this, &TripletSelector::updateNI);
    
    401
    +
    
    402
    +  connect(closeFontButton_, &QToolButton::clicked, 
    
    403
    +          this, &TripletSelector::closeCurrentFont);
    
    404
    +  connect(fontUpButton_   , &QToolButton::clicked, 
    
    405
    +          this, 
    
    406
    +          std::bind(&TripletSelector::previousComboBoxItem, fontComboBox_));
    
    407
    +  connect(faceUpButton_   , &QToolButton::clicked, 
    
    408
    +          this, 
    
    409
    +          std::bind(&TripletSelector::previousComboBoxItem, faceComboBox_));
    
    410
    +  connect(niUpButton_     , &QToolButton::clicked, 
    
    411
    +          this, 
    
    412
    +          std::bind(&TripletSelector::previousComboBoxItem, niComboBox_));
    
    413
    +  connect(fontDownButton_ , &QToolButton::clicked, 
    
    414
    +          this, 
    
    415
    +          std::bind(&TripletSelector::nextComboBoxItem, fontComboBox_));
    
    416
    +  connect(faceDownButton_ , &QToolButton::clicked, 
    
    417
    +          this,
    
    418
    +          std::bind(&TripletSelector::nextComboBoxItem, faceComboBox_));
    
    419
    +  connect(niDownButton_   , &QToolButton::clicked, 
    
    420
    +          this, 
    
    421
    +          std::bind(&TripletSelector::nextComboBoxItem, niComboBox_));
    
    422
    +
    
    423
    +  connect(&engine_->fontFileManager(), &FontFileManager::currentFileChanged,
    
    424
    +          this, &TripletSelector::watchCurrentFont);
    
    425
    +}
    
    426
    +
    
    427
    +
    
    428
    +void
    
    429
    +TripletSelector::loadTriplet()
    
    430
    +{
    
    431
    +  // we do lazy computation of FT_Face objects
    
    432
    +
    
    433
    +  // TODO really?
    
    434
    +  auto fontIndex = fontComboBox_->currentIndex();
    
    435
    +  auto faceIndex = faceComboBox_->currentIndex();
    
    436
    +  auto instanceIndex = niComboBox_->currentIndex();
    
    437
    +
    
    438
    +  if (fontIndex >= 0 && fontIndex < engine_->numberOfOpenedFonts())
    
    439
    +  {
    
    440
    +    QFileInfo& fileInfo = engine_->fontFileManager()[fontIndex];
    
    441
    +    engine_->fontFileManager().updateWatching(fontIndex);
    
    442
    +
    
    443
    +    if (!fileInfo.exists())
    
    444
    +    {
    
    445
    +      // On Unix-like systems, the symlink's target gets opened; this
    
    446
    +      // implies that deletion of a symlink doesn't make `engine->loadFont'
    
    447
    +      // fail since it operates on a file handle pointing to the target.
    
    448
    +      // For this reason, we remove the font to enforce a reload.
    
    449
    +      engine_->removeFont(fontIndex, false);
    
    450
    +    }
    
    451
    +  }
    
    452
    +
    
    453
    +  engine_->loadFont(fontIndex, faceIndex, instanceIndex);
    
    454
    +  
    
    455
    +  // TODO: This may messes up with bitmap-only fonts.
    
    456
    +  if (!engine_->fontValid())
    
    457
    +  {
    
    458
    +    // there might be various reasons why the current
    
    459
    +    // (file, face, instance) triplet is invalid or missing;
    
    460
    +    // we thus start our timer to periodically test
    
    461
    +    // whether the font starts working
    
    462
    +    if (faceIndex >= 0 && faceIndex < engine_->numberOfOpenedFonts())
    
    463
    +      engine_->fontFileManager().timerStart();
    
    464
    +  }
    
    465
    +
    
    466
    +  emit tripletChanged();
    
    467
    +}
    
    468
    +
    
    469
    +
    
    470
    +void
    
    471
    +TripletSelector::nextComboBoxItem(QComboBox* c)
    
    472
    +{
    
    473
    +  if (c->currentIndex() < 0 || c->currentIndex() >= c->count() - 1)
    
    474
    +    return;
    
    475
    +  // No need to handle further steps, the event handler will take care of these
    
    476
    +  c->setCurrentIndex(c->currentIndex() + 1);
    
    477
    +}
    
    478
    +
    
    479
    +
    
    480
    +void
    
    481
    +TripletSelector::previousComboBoxItem(QComboBox* c)
    
    482
    +{
    
    483
    +  if (c->currentIndex() <= 0)
    
    484
    +    return;
    
    485
    +  // No need to handle further steps, the event handler will take care of these
    
    486
    +  c->setCurrentIndex(c->currentIndex() - 1);
    
    487
    +}
    
    488
    +
    
    489
    +
    
    490
    +// end of tripletselector.cpp

  • src/ftinspect/widgets/tripletselector.hpp
    1
    +// QPushButton.hpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#pragma once
    
    6
    +
    
    7
    +#include <vector>
    
    8
    +#include <QWidget>
    
    9
    +#include <QComboBox>
    
    10
    +#include <QPushButton>
    
    11
    +#include <QToolButton>
    
    12
    +#include <QBoxLayout>
    
    13
    +
    
    14
    +class Engine;
    
    15
    +class TripletSelector
    
    16
    +: public QWidget
    
    17
    +{
    
    18
    +  Q_OBJECT
    
    19
    +
    
    20
    +public:
    
    21
    +  TripletSelector(QWidget* parent,
    
    22
    +                  Engine* engine);
    
    23
    +  ~TripletSelector() override;
    
    24
    +
    
    25
    +  void repopulateFonts();
    
    26
    +  void closeCurrentFont();
    
    27
    +
    
    28
    +signals:
    
    29
    +  void tripletChanged();
    
    30
    +
    
    31
    +private:
    
    32
    +  Engine* engine_;
    
    33
    +
    
    34
    +  QComboBox* fontComboBox_;
    
    35
    +  QComboBox* faceComboBox_;
    
    36
    +  QComboBox* niComboBox_;
    
    37
    +
    
    38
    +  QToolButton* closeFontButton_;
    
    39
    +
    
    40
    +  QToolButton* fontUpButton_;
    
    41
    +  QToolButton* fontDownButton_;
    
    42
    +  QToolButton* faceUpButton_;
    
    43
    +  QToolButton* faceDownButton_;
    
    44
    +  QToolButton* niUpButton_;
    
    45
    +  QToolButton* niDownButton_;
    
    46
    +
    
    47
    +  QHBoxLayout* layout_;
    
    48
    +
    
    49
    +  void checkButtons();
    
    50
    +  void watchCurrentFont();
    
    51
    +
    
    52
    +  void createLayout();
    
    53
    +  void createConnections();
    
    54
    +
    
    55
    +  void repopulateFaces(bool fontSwitched = true);
    
    56
    +  void repopulateNamedInstances(bool fontSwitched = true);
    
    57
    +  void updateFont();
    
    58
    +  void updateFace();
    
    59
    +  void updateNI();
    
    60
    +  void loadTriplet();
    
    61
    +
    
    62
    +  static void nextComboBoxItem(QComboBox* c);
    
    63
    +  static void previousComboBoxItem(QComboBox* c);
    
    64
    +};
    
    65
    +
    
    66
    +
    
    67
    +// end of QPushButton.hpp


  • reply via email to

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