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-3] 4 commits: [ftinspec


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-3] 4 commits: [ftinspect] Add stem darkening.
Date: Tue, 09 Aug 2022 16:34:55 +0000

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

Commits:

  • 06ee1f8d
    by Charlie Jiang at 2022-08-09T21:57:46+08:00
    [ftinspect] Add stem darkening.
    
    Stem darkening should only work when auto-hinting is on and is in light
    mode.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `setStemDarkening` function to apply the setting to the engine.
    
    * src/ftinspect/panels/settingpanel.cpp,
      src/ftinspect/panels/settingpanel.hpp:
      Add necessary controls and rename `applyHintingMode` to
      `applyDelayedSettings`.
    
    * src/ftinspect/panels/comparator.cpp: Rename func.
    
  • a34c63d4
    by Charlie Jiang at 2022-08-09T22:17:03+08:00
    [ftinspect] Improve enabling and disabling of options.
    
    * src/ftinspect/panels/settingpanel.cpp: As described. Stem darkening will
      only be enabled when possible (auto-hinting and light AA mode).
    
  • 03beb1a0
    by Charlie Jiang at 2022-08-09T23:28:08+08:00
    [ftinspect] Add customization for waterfall start and step size.
    
    Also fixed the UI helper's grid layout helper functions.
    
    * src/ftinspect/engine/stringrenderer.cpp,
      src/ftinspect/engine/stringrenderer.hpp:
      Add waterfall start and step properties and honor then when rendering.
    
    * src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
      Add `WaterfallConfigDialog` and open it when clicking the "WF Config"
      button.
    
    * src/ftinspect/uihelper.cpp, src/ftinspect/uihelper.hpp:
      Since the `QGridLayout::rowCount` returns the count of internal allocated
      rows, not the actual occuplied row count, so we have to keep every row's
      index for later customization and can't use any hardcoded row index.
    
    * src/ftinspect/panels/glyphdetails.cpp: Accompanying changes to the helper.
    
  • 66f00589
    by Charlie Jiang at 2022-08-10T00:34:35+08:00
    [ftinspect] Add auxiliary lines to the singular line.
    
    Now aux lines indicating advance width, ascender and descender are
    displayed. The logic rendering those lines are put into `Grid`.
    
    * src/ftinspect/rendering/grid.cpp, src/ftinspect/rendering/grid.hpp:
      Add logic to render the aux lines and properties to hold values.
      Now the visibility of the grid and aux lines are controlled via
      `showGrid_` and `showAuxLines_`, so the grid *QGraphicsItem* will stay
      visible.
      `Grid` no longer use pens passed from the ctor, but directly retrieve
      pens from the `GraphicsDefault` struct.
    
    * src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
      Add `currentSizeAscDescPx` func to retrieve ascender and descender data..
    
    * src/ftinspect/panels/singular.cpp, src/ftinspect/panels/singular.hpp:
      Add checkbox to toggle aux lines on and on. Pass data to the `Grid` object
      about the aux lines.
    
    * src/ftinspect/rendering/graphicsdefault.cpp,
      src/ftinspect/rendering/graphicsdefault.hpp:
      Add `advanceAuxPen` and `ascDescAuxPen`.
    

18 changed files:

Changes:

  • src/ftinspect/engine/engine.cpp
    ... ... @@ -456,6 +456,14 @@ Engine::currentFontKerning(int glyphIndex,
    456 456
     }
    
    457 457
     
    
    458 458
     
    
    459
    +std::pair<int, int>
    
    460
    +Engine::currentSizeAscDescPx()
    
    461
    +{
    
    462
    +  return { ftSize_->metrics.ascender >> 6,
    
    463
    +             ftSize_->metrics.descender >> 6 };
    
    464
    +}
    
    465
    +
    
    466
    +
    
    459 467
     QString
    
    460 468
     Engine::glyphName(int index)
    
    461 469
     {
    
    ... ... @@ -681,6 +689,33 @@ Engine::setTTInterpreterVersion(int version)
    681 689
     }
    
    682 690
     
    
    683 691
     
    
    692
    +void
    
    693
    +Engine::setStemDarkening(bool darkening)
    
    694
    +{
    
    695
    +  // TODO not working
    
    696
    +  FT_Bool noDarkening = !darkening;
    
    697
    +  FT_Property_Set(library_,
    
    698
    +                  "cff",
    
    699
    +                  "no-stem-darkening",
    
    700
    +                  &noDarkening);
    
    701
    +  FT_Property_Set(library_,
    
    702
    +                  "autofitter",
    
    703
    +                  "no-stem-darkening",
    
    704
    +                  &noDarkening);
    
    705
    +  FT_Property_Set(library_,
    
    706
    +                  "type1",
    
    707
    +                  "no-stem-darkening",
    
    708
    +                  &noDarkening);
    
    709
    +  FT_Property_Set(library_,
    
    710
    +                  "t1cid",
    
    711
    +                  "no-stem-darkening",
    
    712
    +                  &noDarkening);
    
    713
    +  // reset the cache
    
    714
    +  FTC_Manager_Reset(cacheManager_);
    
    715
    +  ftSize_ = NULL;
    
    716
    +}
    
    717
    +
    
    718
    +
    
    684 719
     void
    
    685 720
     Engine::setForeground(QRgb foreground)
    
    686 721
     {
    

  • src/ftinspect/engine/engine.hpp
    ... ... @@ -10,6 +10,7 @@
    10 10
     #include "paletteinfo.hpp"
    
    11 11
     
    
    12 12
     #include <vector>
    
    13
    +#include <utility>
    
    13 14
     #include <QString>
    
    14 15
     #include <QMap>
    
    15 16
     #include <QRect>
    
    ... ... @@ -146,6 +147,7 @@ public:
    146 147
       FT_GlyphSlot currentFaceSlot();
    
    147 148
       FT_Pos currentFontTrackingKerning(int degree);
    
    148 149
       FT_Vector currentFontKerning(int glyphIndex, int prevIndex);
    
    150
    +  std::pair<int, int> currentSizeAscDescPx();
    
    149 151
       
    
    150 152
       std::vector<CharMapInfo>& currentFontCharMaps() { return curCharMaps_; }
    
    151 153
       std::vector<PaletteInfo>& currentFontPalettes() { return curPaletteInfos_; }
    
    ... ... @@ -194,6 +196,7 @@ public:
    194 196
       void setLcdFilter(FT_LcdFilter filter);
    
    195 197
       void setCFFHintingMode(int mode);
    
    196 198
       void setTTInterpreterVersion(int version);
    
    199
    +  void setStemDarkening(bool darkening);
    
    197 200
     
    
    198 201
       void setForeground(QRgb foreground);
    
    199 202
       void setBackground(QRgb background);
    

  • src/ftinspect/engine/stringrenderer.cpp
    ... ... @@ -363,8 +363,17 @@ StringRenderer::render(int width,
    363 363
         auto originalSize = static_cast<int>(engine_->pointSize() * 64);
    
    364 364
         auto ptSize = originalSize;
    
    365 365
         auto ptHeight = 64 * 72 * height / engine_->dpi();
    
    366
    -    auto step = (ptSize * ptSize / ptHeight + 64) & ~63;
    
    367
    -    ptSize = ptSize - step * (ptSize / step); // modulo
    
    366
    +    int step;
    
    367
    +
    
    368
    +    if (waterfallStep_ <= 0)
    
    369
    +      step = (originalSize * originalSize / ptHeight + 64) & ~63;
    
    370
    +    else
    
    371
    +      step = static_cast<int>(waterfallStep_ * 64.0) & ~31;
    
    372
    +
    
    373
    +    if (waterfallStart_ < 0)
    
    374
    +      ptSize = ptSize - step * (ptSize / step); // modulo
    
    375
    +    else
    
    376
    +      ptSize = static_cast<int>(waterfallStart_ * 64.0) & ~31;
    
    368 377
     
    
    369 378
         int y = 0;
    
    370 379
         // no position param in "All Glyphs" mode
    

  • src/ftinspect/engine/stringrenderer.hpp
    ... ... @@ -124,6 +124,11 @@ public:
    124 124
       void setVertical(bool vertical) { vertical_ = vertical; }
    
    125 125
       void setRotation(double rotation);
    
    126 126
       void setWaterfall(bool waterfall) { waterfall_ = waterfall; }
    
    127
    +  void setWaterfallParameters(double start, double step)
    
    128
    +  {
    
    129
    +    waterfallStart_ = start;
    
    130
    +    waterfallStep_ = step;
    
    131
    +  }
    
    127 132
       void setPosition(double pos) { position_ = pos; }
    
    128 133
       void setLsbRsbDelta(bool enabled) { lsbRsbDeltaEnabled_ = enabled; }
    
    129 134
       void setKerning(bool kerning);
    
    ... ... @@ -181,7 +186,6 @@ private:
    181 186
       int charMapIndex_ = 0;
    
    182 187
       int limitIndex_ = 0;
    
    183 188
       bool usingString_ = false;
    
    184
    -  bool waterfall_ = false;
    
    185 189
       bool repeated_ = false;
    
    186 190
       bool vertical_ = false;
    
    187 191
       double position_ = 0.5;
    
    ... ... @@ -193,6 +197,10 @@ private:
    193 197
       bool matrixEnabled_ = false;
    
    194 198
       bool lsbRsbDeltaEnabled_ = true;
    
    195 199
     
    
    200
    +  bool waterfall_ = false;
    
    201
    +  double waterfallStart_ = -1;
    
    202
    +  double waterfallStep_ = -1; // -1 = Auto
    
    203
    +
    
    196 204
       RenderCallback renderCallback_;
    
    197 205
       RenderImageCallback renderImageCallback_;
    
    198 206
       PreprocessCallback glyphPreprocessCallback_;
    

  • src/ftinspect/panels/comparator.cpp
    ... ... @@ -242,7 +242,7 @@ ComperatorTab::syncSettings(int index)
    242 242
         return;
    
    243 243
     
    
    244 244
       auto settingPanel = settingPanels_[index];
    
    245
    -  settingPanel->applyHintingMode();
    
    245
    +  settingPanel->applyDelayedSettings();
    
    246 246
       settingPanel->syncSettings();
    
    247 247
     
    
    248 248
       if (static_cast<unsigned>(index) >= canvas_.size())
    

  • src/ftinspect/panels/continuous.cpp
    ... ... @@ -5,6 +5,7 @@
    5 5
     #include "continuous.hpp"
    
    6 6
     
    
    7 7
     #include "glyphdetails.hpp"
    
    8
    +#include "../uihelper.hpp"
    
    8 9
     
    
    9 10
     #include <climits>
    
    10 11
     #include <QVariant>
    
    ... ... @@ -158,6 +159,8 @@ ContinuousTab::checkModeSource()
    158 159
         waterfallCheckBox_->setEnabled(!vert);
    
    159 160
       }
    
    160 161
     
    
    162
    +  waterfallConfigButton_->setEnabled(waterfallCheckBox_->isChecked());
    
    163
    +
    
    161 164
       repaintGlyph();
    
    162 165
     }
    
    163 166
     
    
    ... ... @@ -228,6 +231,20 @@ ContinuousTab::updateGlyphDetails(GlyphCacheEntry* ctxt,
    228 231
     }
    
    229 232
     
    
    230 233
     
    
    234
    +void
    
    235
    +ContinuousTab::openWaterfallConfig()
    
    236
    +{
    
    237
    +  auto result = wfConfigDialog_->exec();
    
    238
    +  if (result != QDialog::Accepted)
    
    239
    +    return;
    
    240
    +
    
    241
    +  auto& sr = canvas_->stringRenderer();
    
    242
    +  sr.setWaterfallParameters(wfConfigDialog_->startSize(),
    
    243
    +                            wfConfigDialog_->stepSize());
    
    244
    +  repaintGlyph();
    
    245
    +}
    
    246
    +
    
    247
    +
    
    231 248
     bool
    
    232 249
     ContinuousTab::eventFilter(QObject* watched,
    
    233 250
                                QEvent* event)
    
    ... ... @@ -308,7 +325,7 @@ ContinuousTab::createLayout()
    308 325
       rotationLabel_ = new QLabel(tr("Rotation:"), this);
    
    309 326
     
    
    310 327
       resetPositionButton_ = new QPushButton(tr("Reset Pos"));
    
    311
    -  configWaterfallButton_ = new QPushButton(tr("WF Config"));
    
    328
    +  waterfallConfigButton_ = new QPushButton(tr("WF Config"));
    
    312 329
     
    
    313 330
       xEmboldeningSpinBox_ = new QDoubleSpinBox(this);
    
    314 331
       yEmboldeningSpinBox_ = new QDoubleSpinBox(this);
    
    ... ... @@ -332,6 +349,8 @@ ContinuousTab::createLayout()
    332 349
       rotationSpinBox_->setMinimum(-180);
    
    333 350
       rotationSpinBox_->setMaximum(180);
    
    334 351
     
    
    352
    +  wfConfigDialog_ = new WaterfallConfigDialog(this);
    
    353
    +
    
    335 354
       canvasFrameLayout_ = new QHBoxLayout;
    
    336 355
       canvasFrameLayout_->addWidget(canvas_);
    
    337 356
       canvasFrame_->setLayout(canvasFrameLayout_);
    
    ... ... @@ -364,7 +383,7 @@ ContinuousTab::createLayout()
    364 383
       bottomLayout_->addWidget(waterfallCheckBox_, 1, 6);
    
    365 384
       bottomLayout_->addWidget(verticalCheckBox_, 2, 6);
    
    366 385
       bottomLayout_->addWidget(kerningCheckBox_, 3, 6);
    
    367
    -  bottomLayout_->addWidget(configWaterfallButton_, 1, 5);
    
    386
    +  bottomLayout_->addWidget(waterfallConfigButton_, 1, 5);
    
    368 387
       bottomLayout_->addWidget(sampleStringSelector_, 2, 5);
    
    369 388
     
    
    370 389
       bottomLayout_->setColumnStretch(4, 1);
    
    ... ... @@ -411,6 +430,8 @@ ContinuousTab::createConnections()
    411 430
     
    
    412 431
       connect(resetPositionButton_, &QPushButton::clicked,
    
    413 432
               canvas_, &GlyphContinuous::resetPositionDelta);
    
    433
    +  connect(waterfallConfigButton_, &QPushButton::clicked,
    
    434
    +          this, &ContinuousTab::openWaterfallConfig);
    
    414 435
     
    
    415 436
       connect(xEmboldeningSpinBox_, 
    
    416 437
               QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    
    ... ... @@ -480,6 +501,100 @@ ContinuousTab::formatIndex(int index)
    480 501
     }
    
    481 502
     
    
    482 503
     
    
    504
    +WaterfallConfigDialog::WaterfallConfigDialog(QWidget* parent)
    
    505
    +: QDialog(parent)
    
    506
    +{
    
    507
    +  setModal(true);
    
    508
    +  setWindowTitle(tr("Waterfall Config"));
    
    509
    +  setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    
    510
    +
    
    511
    +  createLayout();
    
    512
    +  checkAutoStatus();
    
    513
    +  createConnections();
    
    514
    +}
    
    515
    +
    
    516
    +
    
    517
    +double
    
    518
    +WaterfallConfigDialog::startSize()
    
    519
    +{
    
    520
    +  if (startAutoBox_->isChecked())
    
    521
    +    return -1.0;
    
    522
    +  return startSpinBox_->value();
    
    523
    +}
    
    524
    +
    
    525
    +
    
    526
    +double
    
    527
    +WaterfallConfigDialog::stepSize()
    
    528
    +{
    
    529
    +  if (stepAutoBox_->isChecked())
    
    530
    +    return -1.0;
    
    531
    +  return stepSpinBox_->value();
    
    532
    +}
    
    533
    +
    
    534
    +
    
    535
    +void
    
    536
    +WaterfallConfigDialog::createLayout()
    
    537
    +{
    
    538
    +  startLabel_ = new QLabel(tr("Start Size (pt):"), this);
    
    539
    +  stepLabel_ = new QLabel(tr("Size Step (pt):"), this);
    
    540
    +
    
    541
    +  startSpinBox_ = new QDoubleSpinBox(this);
    
    542
    +  stepSpinBox_ = new QDoubleSpinBox(this);
    
    543
    +
    
    544
    +  startSpinBox_->setSingleStep(0.5);
    
    545
    +  startSpinBox_->setMinimum(0.5);
    
    546
    +  startSpinBox_->setValue(1);
    
    547
    +
    
    548
    +  stepSpinBox_->setSingleStep(0.5);
    
    549
    +  stepSpinBox_->setMinimum(0.5);
    
    550
    +  stepSpinBox_->setValue(1);
    
    551
    +
    
    552
    +  startAutoBox_ = new QCheckBox(tr("Auto"), this);
    
    553
    +  stepAutoBox_ = new QCheckBox(tr("Auto"), this);
    
    554
    +
    
    555
    +  okButton_ = new QPushButton(tr("OK"), this);
    
    556
    +  cancelButton_ = new QPushButton(tr("Cancel"), this);
    
    557
    +
    
    558
    +  buttonLayout_ = new QHBoxLayout;
    
    559
    +  buttonLayout_->addWidget(okButton_);
    
    560
    +  buttonLayout_->addWidget(cancelButton_);
    
    561
    +
    
    562
    +  layout_ = new QGridLayout;
    
    563
    +  auto startRow = gridLayout2ColAddWidget(layout_, startLabel_, startSpinBox_);
    
    564
    +  auto stepRow = gridLayout2ColAddWidget(layout_, stepLabel_, stepSpinBox_);
    
    565
    +  layout_->addWidget(startAutoBox_, startRow, 2);
    
    566
    +  layout_->addWidget(stepAutoBox_, stepRow, 2);
    
    567
    +  layout_->addLayout(buttonLayout_, layout_->rowCount(), 0, 1, 3);
    
    568
    +
    
    569
    +  startAutoBox_->setChecked(true);
    
    570
    +  stepAutoBox_->setChecked(true);
    
    571
    +
    
    572
    +  setLayout(layout_);
    
    573
    +}
    
    574
    +
    
    575
    +
    
    576
    +void
    
    577
    +WaterfallConfigDialog::createConnections()
    
    578
    +{
    
    579
    +  connect(startAutoBox_, &QCheckBox::clicked,
    
    580
    +          this, &WaterfallConfigDialog::checkAutoStatus);
    
    581
    +  connect(stepAutoBox_, &QCheckBox::clicked,
    
    582
    +          this, &WaterfallConfigDialog::checkAutoStatus);
    
    583
    +  connect(okButton_, &QPushButton::clicked,
    
    584
    +          this, &QDialog::accept);
    
    585
    +  connect(cancelButton_, &QPushButton::clicked,
    
    586
    +          this, &QDialog::reject);
    
    587
    +}
    
    588
    +
    
    589
    +
    
    590
    +void
    
    591
    +WaterfallConfigDialog::checkAutoStatus()
    
    592
    +{
    
    593
    +  startSpinBox_->setEnabled(!startAutoBox_->isChecked());
    
    594
    +  stepSpinBox_->setEnabled(!stepAutoBox_->isChecked());
    
    595
    +}
    
    596
    +
    
    597
    +
    
    483 598
     const char* StringSamples[] = {
    
    484 599
       "The quick brown fox jumps over the lazy dog",
    
    485 600
     
    

  • src/ftinspect/panels/continuous.hpp
    ... ... @@ -15,6 +15,7 @@
    15 15
     
    
    16 16
     #include <vector>
    
    17 17
     #include <QWidget>
    
    18
    +#include <QDialog>
    
    18 19
     #include <QFrame>
    
    19 20
     #include <QLabel>
    
    20 21
     #include <QComboBox>
    
    ... ... @@ -25,6 +26,7 @@
    25 26
     #include <QCheckBox>
    
    26 27
     
    
    27 28
     class GlyphDetails;
    
    29
    +class WaterfallConfigDialog;
    
    28 30
     class ContinuousTab
    
    29 31
     : public QWidget, public AbstractTab
    
    30 32
     {
    
    ... ... @@ -48,6 +50,8 @@ public:
    48 50
     
    
    49 51
       // This doesn't trigger either.
    
    50 52
       void updateLimitIndex();
    
    53
    +
    
    54
    +  // But they do
    
    51 55
       void checkModeSource();
    
    52 56
       void charMapChanged();
    
    53 57
       void sourceTextChanged();
    
    ... ... @@ -57,6 +61,7 @@ public:
    57 61
       void updateGlyphDetails(GlyphCacheEntry* ctxt, 
    
    58 62
                               int charMapIndex, 
    
    59 63
                               bool open);
    
    64
    +  void openWaterfallConfig();
    
    60 65
     
    
    61 66
     signals:
    
    62 67
       void switchToSingular(int glyphIndex, double sizePoint);
    
    ... ... @@ -85,7 +90,7 @@ private:
    85 90
       QComboBox* sampleStringSelector_;
    
    86 91
     
    
    87 92
       QPushButton* resetPositionButton_;
    
    88
    -  QPushButton* configWaterfallButton_;
    
    93
    +  QPushButton* waterfallConfigButton_;
    
    89 94
     
    
    90 95
       QLabel* modeLabel_;
    
    91 96
       QLabel* sourceLabel_;
    
    ... ... @@ -116,6 +121,8 @@ private:
    116 121
       QDockWidget* glyphDetailsWidget_;
    
    117 122
       GlyphDetails* glyphDetails_;
    
    118 123
     
    
    124
    +  WaterfallConfigDialog* wfConfigDialog_;
    
    125
    +
    
    119 126
       void createLayout();
    
    120 127
       void createConnections();
    
    121 128
     
    
    ... ... @@ -125,4 +132,38 @@ private:
    125 132
     };
    
    126 133
     
    
    127 134
     
    
    135
    +class WaterfallConfigDialog
    
    136
    +: public QDialog
    
    137
    +{
    
    138
    +  Q_OBJECT
    
    139
    +
    
    140
    +public:
    
    141
    +  WaterfallConfigDialog(QWidget* parent);
    
    142
    +
    
    143
    +  double startSize();
    
    144
    +  double stepSize();
    
    145
    +
    
    146
    +private:
    
    147
    +  QLabel* startLabel_;
    
    148
    +  QLabel* stepLabel_;
    
    149
    +
    
    150
    +  QDoubleSpinBox* startSpinBox_;
    
    151
    +  QDoubleSpinBox* stepSpinBox_;
    
    152
    +
    
    153
    +  QCheckBox* startAutoBox_;
    
    154
    +  QCheckBox* stepAutoBox_;
    
    155
    +
    
    156
    +  QPushButton* okButton_;
    
    157
    +  QPushButton* cancelButton_;
    
    158
    +
    
    159
    +  QGridLayout* layout_;
    
    160
    +  QHBoxLayout* buttonLayout_;
    
    161
    +
    
    162
    +  void createLayout();
    
    163
    +  void createConnections();
    
    164
    +
    
    165
    +  void checkAutoStatus();
    
    166
    +};
    
    167
    +
    
    168
    +
    
    128 169
     // end of continuous.hpp

  • src/ftinspect/panels/glyphdetails.cpp
    ... ... @@ -150,10 +150,10 @@ GlyphDetails::createLayout()
    150 150
                                        bitmapOffsetLabel_);
    
    151 151
       gridLayout2ColAddItem(layout_, new QSpacerItem(0, 18));
    
    152 152
     
    
    153
    -  gridLayout2ColAddWidget(layout_, bitmapWidget_);
    
    153
    +  auto bmapRowPos = gridLayout2ColAddWidget(layout_, bitmapWidget_);
    
    154 154
     
    
    155 155
       layout_->setColumnStretch(1, 1);
    
    156
    -  layout_->setRowStretch(layout_->rowCount() - 1, 1);
    
    156
    +  layout_->setRowStretch(bmapRowPos, 1);
    
    157 157
     
    
    158 158
       setLayout(layout_);
    
    159 159
       setContentsMargins(12, 12, 12, 12);
    

  • src/ftinspect/panels/settingpanel.cpp
    ... ... @@ -99,9 +99,11 @@ SettingPanel::onFontChanged()
    99 99
           segmentDrawingCheckBox_->setEnabled(false);
    
    100 100
         }
    
    101 101
     
    
    102
    +    stemDarkeningCheckBox_->setEnabled(false);
    
    102 103
         antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    103
    -    if (antiAliasingComboBox_->currentIndex()
    
    104
    -      == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    104
    +    auto aaMode = antiAliasingComboBox_->currentIndex();
    
    105
    +    if (aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    106
    +        || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel)
    
    105 107
           antiAliasingComboBox_->setCurrentIndex(
    
    106 108
             AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    107 109
         
    
    ... ... @@ -150,6 +152,8 @@ SettingPanel::populatePalettes()
    150 152
             newPalettes[i].name);
    
    151 153
       }
    
    152 154
     
    
    155
    +  paletteComboBox_->setEnabled(paletteComboBox_->count() > 0);
    
    156
    +
    
    153 157
       emit fontReloadNeeded();
    
    154 158
     }
    
    155 159
     
    
    ... ... @@ -197,14 +201,14 @@ void
    197 201
     SettingPanel::checkHintingMode()
    
    198 202
     {
    
    199 203
       if (!comparatorMode_)
    
    200
    -    applyHintingMode();
    
    204
    +    applyDelayedSettings();
    
    201 205
     
    
    202 206
       emit fontReloadNeeded();
    
    203 207
     }
    
    204 208
     
    
    205 209
     
    
    206 210
     void
    
    207
    -SettingPanel::applyHintingMode()
    
    211
    +SettingPanel::applyDelayedSettings()
    
    208 212
     {
    
    209 213
       // This must not be combined into `syncSettings`:
    
    210 214
       // those engine manipulations will reset the whole cache!!
    
    ... ... @@ -227,6 +231,8 @@ SettingPanel::applyHintingMode()
    227 231
         if (index >= 0)
    
    228 232
           currentTTInterpreterVersion_ = index;
    
    229 233
       }
    
    234
    +
    
    235
    +  engine_->setStemDarkening(stemDarkeningCheckBox_->isChecked());
    
    230 236
     }
    
    231 237
     
    
    232 238
     
    
    ... ... @@ -247,6 +253,10 @@ SettingPanel::checkAutoHinting()
    247 253
         }
    
    248 254
     
    
    249 255
         antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(true);
    
    256
    +    auto aaMode = antiAliasingComboBox_->currentIndex();
    
    257
    +    stemDarkeningCheckBox_->setEnabled(
    
    258
    +      aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    259
    +      || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel);
    
    250 260
       }
    
    251 261
       else
    
    252 262
       {
    
    ... ... @@ -266,11 +276,13 @@ SettingPanel::checkAutoHinting()
    266 276
         }
    
    267 277
     
    
    268 278
         antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    279
    +    stemDarkeningCheckBox_->setEnabled(false);
    
    269 280
     
    
    270
    -    if (antiAliasingComboBox_->currentIndex() 
    
    271
    -      == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    281
    +    auto aaMode = antiAliasingComboBox_->currentIndex();
    
    282
    +    if (aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    283
    +        || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel)
    
    272 284
           antiAliasingComboBox_->setCurrentIndex(
    
    273
    -        AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    285
    +          AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    274 286
       }
    
    275 287
       emit repaintNeeded();
    
    276 288
     }
    
    ... ... @@ -280,19 +292,18 @@ void
    280 292
     SettingPanel::checkAntiAliasing()
    
    281 293
     {
    
    282 294
       int index = antiAliasingComboBox_->currentIndex();
    
    283
    -
    
    284
    -  if (index == AntiAliasingComboBoxModel::AntiAliasing_None
    
    295
    +  auto isLight
    
    296
    +    = index == AntiAliasingComboBoxModel::AntiAliasing_Light
    
    297
    +      || index == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel;
    
    298
    +  auto disableLCD
    
    299
    +    = index == AntiAliasingComboBoxModel::AntiAliasing_None
    
    285 300
           || index == AntiAliasingComboBoxModel::AntiAliasing::AntiAliasing_Normal
    
    286
    -      || index == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    287
    -  {
    
    288
    -    lcdFilterLabel_->setEnabled(false);
    
    289
    -    lcdFilterComboBox_->setEnabled(false);
    
    290
    -  }
    
    291
    -  else
    
    292
    -  {
    
    293
    -    lcdFilterLabel_->setEnabled(true);
    
    294
    -    lcdFilterComboBox_->setEnabled(true);
    
    295
    -  }
    
    301
    +      || isLight;
    
    302
    +
    
    303
    +  lcdFilterLabel_->setEnabled(!disableLCD);
    
    304
    +  lcdFilterComboBox_->setEnabled(!disableLCD);
    
    305
    +  stemDarkeningCheckBox_->setEnabled(isLight);
    
    306
    +
    
    296 307
       emit repaintNeeded();
    
    297 308
     }
    
    298 309
     
    
    ... ... @@ -305,6 +316,16 @@ SettingPanel::checkPalette()
    305 316
     }
    
    306 317
     
    
    307 318
     
    
    319
    +void
    
    320
    +SettingPanel::checkStemDarkening()
    
    321
    +{
    
    322
    +  if (!comparatorMode_)
    
    323
    +    applyDelayedSettings();
    
    324
    +
    
    325
    +  emit fontReloadNeeded();
    
    326
    +}
    
    327
    +
    
    328
    +
    
    308 329
     void
    
    309 330
     SettingPanel::syncSettings()
    
    310 331
     {
    
    ... ... @@ -385,6 +406,8 @@ SettingPanel::createConnections()
    385 406
               this, &SettingPanel::checkAutoHinting);
    
    386 407
       connect(embeddedBitmapCheckBox_, &QCheckBox::clicked,
    
    387 408
               this, &SettingPanel::fontReloadNeeded);
    
    409
    +  connect(stemDarkeningCheckBox_, &QCheckBox::clicked,
    
    410
    +          this, &SettingPanel::checkStemDarkening);
    
    388 411
       connect(colorLayerCheckBox_, &QCheckBox::clicked,
    
    389 412
               this, &SettingPanel::checkPalette);
    
    390 413
     
    
    ... ... @@ -420,6 +443,7 @@ SettingPanel::createLayout()
    420 443
       hintingModeLabel_->setBuddy(hintingModeComboBox_);
    
    421 444
     
    
    422 445
       autoHintingCheckBox_ = new QCheckBox(tr("Auto-Hinting"), this);
    
    446
    +  stemDarkeningCheckBox_ = new QCheckBox(tr("Stem Darkening"), this);
    
    423 447
     
    
    424 448
       if (debugMode_)
    
    425 449
       {
    
    ... ... @@ -502,7 +526,6 @@ SettingPanel::createLayout()
    502 526
       tab_->setSizePolicy(QSizePolicy::MinimumExpanding,
    
    503 527
                           QSizePolicy::MinimumExpanding);
    
    504 528
     
    
    505
    -
    
    506 529
       if (debugMode_)
    
    507 530
       {
    
    508 531
         debugLayout_ = new QVBoxLayout;
    
    ... ... @@ -565,6 +588,7 @@ SettingPanel::createLayoutNormal()
    565 588
                                    generalTabLayout_->rowCount(), 0, 1, 2);
    
    566 589
     
    
    567 590
       gridLayout2ColAddLayout(generalTabLayout_, gammaLayout_);
    
    591
    +  gridLayout2ColAddWidget(generalTabLayout_, stemDarkeningCheckBox_);
    
    568 592
       gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
    
    569 593
       gridLayout2ColAddWidget(generalTabLayout_, colorLayerCheckBox_);
    
    570 594
       gridLayout2ColAddWidget(generalTabLayout_, 
    
    ... ... @@ -605,6 +629,7 @@ SettingPanel::createLayoutComperator()
    605 629
                               lcdFilterLabel_, lcdFilterComboBox_);
    
    606 630
     
    
    607 631
       gridLayout2ColAddLayout(hintingRenderingTabLayout_, gammaLayout_);
    
    632
    +  gridLayout2ColAddWidget(hintingRenderingTabLayout_, stemDarkeningCheckBox_);
    
    608 633
     
    
    609 634
       // General
    
    610 635
       gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
    
    ... ... @@ -662,6 +687,7 @@ SettingPanel::setDefaults()
    662 687
       }
    
    663 688
       
    
    664 689
       colorLayerCheckBox_->setChecked(true);
    
    690
    +  paletteComboBox_->setEnabled(false);
    
    665 691
     
    
    666 692
       if (comparatorMode_)
    
    667 693
       {
    

  • src/ftinspect/panels/settingpanel.hpp
    ... ... @@ -30,7 +30,7 @@ public:
    30 30
        * When in comparator mode, this is needed to sync the hinting modes when
    
    31 31
        * reloading the font.
    
    32 32
        */
    
    33
    -  void applyHintingMode();
    
    33
    +  void applyDelayedSettings();
    
    34 34
     
    
    35 35
       //////// Getters/Setters
    
    36 36
     
    
    ... ... @@ -51,6 +51,7 @@ public slots:
    51 51
       void checkAutoHinting();
    
    52 52
       void checkAntiAliasing();
    
    53 53
       void checkPalette();
    
    54
    +  void checkStemDarkening();
    
    54 55
     
    
    55 56
     private:
    
    56 57
       Engine* engine_;
    
    ... ... @@ -90,6 +91,7 @@ private:
    90 91
       QCheckBox* blueZoneHintingCheckBox_;
    
    91 92
       QCheckBox* segmentDrawingCheckBox_;
    
    92 93
       QCheckBox* autoHintingCheckBox_;
    
    94
    +  QCheckBox* stemDarkeningCheckBox_;
    
    93 95
       QCheckBox* embeddedBitmapCheckBox_;
    
    94 96
       QCheckBox* colorLayerCheckBox_;
    
    95 97
       QCheckBox* kerningCheckBox_;
    

  • src/ftinspect/panels/singular.cpp
    ... ... @@ -129,7 +129,14 @@ SingularTab::drawGlyph()
    129 129
             glyphScene_->addItem(currentGlyphPointNumbersItem_);
    
    130 130
           }
    
    131 131
         }
    
    132
    +
    
    133
    +    engine_->reloadFont();
    
    134
    +    auto ascDesc = engine_->currentSizeAscDescPx();
    
    135
    +    gridItem_->updateParameters(ascDesc.first, ascDesc.second,
    
    136
    +                                glyph->advance.x >> 16);
    
    132 137
       }
    
    138
    +  else
    
    139
    +    gridItem_->updateParameters(0, 0, 0);
    
    133 140
     
    
    134 141
       glyphScene_->update();
    
    135 142
     }
    
    ... ... @@ -208,7 +215,8 @@ SingularTab::wheelResize(QWheelEvent* event)
    208 215
     void
    
    209 216
     SingularTab::setGridVisible()
    
    210 217
     {
    
    211
    -  gridItem_->setVisible(showGridCheckBox_->isChecked());
    
    218
    +  gridItem_->setShowGrid(showGridCheckBox_->isChecked(),
    
    219
    +                         showAuxLinesCheckBox_->isChecked());
    
    212 220
     }
    
    213 221
     
    
    214 222
     
    
    ... ... @@ -260,9 +268,7 @@ SingularTab::createLayout()
    260 268
       glyphView_->setScene(glyphScene_);
    
    261 269
       glyphView_->setBackgroundBrush(Qt::white);
    
    262 270
     
    
    263
    -  gridItem_ = new Grid(glyphView_, 
    
    264
    -                       graphicsDefault_->gridPen, 
    
    265
    -                       graphicsDefault_->axisPen);
    
    271
    +  gridItem_ = new Grid(glyphView_);
    
    266 272
       glyphScene_->addItem(gridItem_);
    
    267 273
     
    
    268 274
       // Don't use QGraphicsTextItem: We want this hint to be anchored at the
    
    ... ... @@ -304,6 +310,7 @@ SingularTab::createLayout()
    304 310
       showPointNumbersCheckBox_ = new QCheckBox(tr("Show Point Numbers"), this);
    
    305 311
       showOutlinesCheckBox_ = new QCheckBox(tr("Show Outlines"), this);
    
    306 312
       showGridCheckBox_ = new QCheckBox(tr("Show Grid"), this);
    
    313
    +  showAuxLinesCheckBox_ = new QCheckBox(tr("Show Aux. Lines"), this);
    
    307 314
     
    
    308 315
       indexHelpLayout_ = new QHBoxLayout;
    
    309 316
       indexHelpLayout_->addWidget(indexSelector_, 1);
    
    ... ... @@ -326,6 +333,7 @@ SingularTab::createLayout()
    326 333
       checkBoxesLayout_->addWidget(showPointNumbersCheckBox_);
    
    327 334
       checkBoxesLayout_->addWidget(showOutlinesCheckBox_);
    
    328 335
       checkBoxesLayout_->addWidget(showGridCheckBox_);
    
    336
    +  checkBoxesLayout_->addWidget(showAuxLinesCheckBox_);
    
    329 337
     
    
    330 338
       glyphOverlayIndexLayout_ = new QHBoxLayout;
    
    331 339
       glyphOverlayIndexLayout_->addWidget(glyphIndexLabel_);
    
    ... ... @@ -381,6 +389,8 @@ SingularTab::createConnections()
    381 389
               this, &SingularTab::drawGlyph);
    
    382 390
       connect(showGridCheckBox_, &QCheckBox::clicked,
    
    383 391
               this, &SingularTab::setGridVisible);
    
    392
    +  connect(showAuxLinesCheckBox_, &QCheckBox::clicked,
    
    393
    +          this, &SingularTab::setGridVisible);
    
    384 394
     
    
    385 395
       sizeSelector_->installEventFilterForWidget(glyphView_);
    
    386 396
       sizeSelector_->installEventFilterForWidget(this);
    
    ... ... @@ -428,6 +438,9 @@ SingularTab::setDefaults()
    428 438
       showBitmapCheckBox_->setChecked(true);
    
    429 439
       showOutlinesCheckBox_->setChecked(true);
    
    430 440
       showGridCheckBox_->setChecked(true);
    
    441
    +  showAuxLinesCheckBox_->setChecked(true);
    
    442
    +  gridItem_->setShowGrid(true, true);
    
    443
    +
    
    431 444
       
    
    432 445
       indexSelector_->setCurrentIndex(indexSelector_->currentIndex(), true);
    
    433 446
       zoom();
    

  • src/ftinspect/panels/singular.hpp
    ... ... @@ -89,6 +89,7 @@ private:
    89 89
       QCheckBox* showPointNumbersCheckBox_;
    
    90 90
       QCheckBox* showPointsCheckBox_;
    
    91 91
       QCheckBox* showGridCheckBox_;
    
    92
    +  QCheckBox* showAuxLinesCheckBox_;
    
    92 93
     
    
    93 94
       QVBoxLayout* mainLayout_;
    
    94 95
       QHBoxLayout* checkBoxesLayout_;
    

  • src/ftinspect/rendering/graphicsdefault.cpp
    ... ... @@ -25,6 +25,11 @@ GraphicsDefault::GraphicsDefault()
    25 25
       outlinePen.setWidth(0);
    
    26 26
       segmentPen.setColor(QColor(64, 255, 128, 64)); // light green
    
    27 27
       segmentPen.setWidth(0);
    
    28
    +
    
    29
    +  advanceAuxPen.setColor(QColor(110, 52, 235)); // kind of blue
    
    30
    +  advanceAuxPen.setWidth(0);
    
    31
    +  ascDescAuxPen.setColor(QColor(255, 0, 0)); // red
    
    32
    +  ascDescAuxPen.setWidth(0);
    
    28 33
     }
    
    29 34
     
    
    30 35
     
    

  • src/ftinspect/rendering/graphicsdefault.hpp
    ... ... @@ -19,6 +19,9 @@ struct GraphicsDefault
    19 19
       QPen outlinePen;
    
    20 20
       QPen segmentPen;
    
    21 21
     
    
    22
    +  QPen advanceAuxPen;
    
    23
    +  QPen ascDescAuxPen;
    
    24
    +
    
    22 25
       GraphicsDefault();
    
    23 26
     
    
    24 27
       static GraphicsDefault* deafultInstance();
    

  • src/ftinspect/rendering/grid.cpp
    ... ... @@ -5,18 +5,16 @@
    5 5
     
    
    6 6
     #include "grid.hpp"
    
    7 7
     
    
    8
    +#include "graphicsdefault.hpp"
    
    9
    +
    
    8 10
     #include <QPainter>
    
    9 11
     #include <QStyleOptionGraphicsItem>
    
    10 12
     #include <QGraphicsWidget>
    
    11 13
     #include <QGraphicsView>
    
    12 14
     
    
    13 15
     
    
    14
    -Grid::Grid(QGraphicsView* parentView, 
    
    15
    -           const QPen& gridP,
    
    16
    -           const QPen& axisP)
    
    17
    -: gridPen_(gridP),
    
    18
    -  axisPen_(axisP),
    
    19
    -  parentView_(parentView)
    
    16
    +Grid::Grid(QGraphicsView* parentView)
    
    17
    +:  parentView_(parentView)
    
    20 18
     {
    
    21 19
      // empty
    
    22 20
       updateRect();
    
    ... ... @@ -60,6 +58,7 @@ Grid::paint(QPainter* painter,
    60 58
                 const QStyleOptionGraphicsItem* option,
    
    61 59
                 QWidget* widget)
    
    62 60
     {
    
    61
    +  auto gb = GraphicsDefault::deafultInstance();
    
    63 62
       auto br = boundingRect().toRect();
    
    64 63
       int minX = br.left();
    
    65 64
       int minY = br.top();
    
    ... ... @@ -68,53 +67,92 @@ Grid::paint(QPainter* painter,
    68 67
     
    
    69 68
       const qreal lod = option->levelOfDetailFromTransform(
    
    70 69
                                   painter->worldTransform());
    
    71
    -
    
    72
    -  painter->setPen(gridPen_);
    
    73
    -
    
    74
    -  // don't mark pixel center with a cross if magnification is too small
    
    75
    -  if (lod > 20)
    
    70
    +  if (showGrid_)
    
    76 71
       {
    
    77
    -    int halfLength = 1;
    
    78
    -
    
    79
    -    // cf. QSpinBoxx
    
    80
    -    if (lod > 640)
    
    81
    -      halfLength = 6;
    
    82
    -    else if (lod > 320)
    
    83
    -      halfLength = 5;
    
    84
    -    else if (lod > 160)
    
    85
    -      halfLength = 4;
    
    86
    -    else if (lod > 80)
    
    87
    -      halfLength = 3;
    
    88
    -    else if (lod > 40)
    
    89
    -      halfLength = 2;
    
    90
    -
    
    91
    -    for (qreal x = minX; x < maxX; x++)
    
    92
    -      for (qreal y = minY; y < maxY; y++)
    
    93
    -      {
    
    94
    -        painter->drawLine(QLineF(x + 0.5, y + 0.5 - halfLength / lod,
    
    95
    -                                 x + 0.5, y + 0.5 + halfLength / lod));
    
    96
    -        painter->drawLine(QLineF(x + 0.5 - halfLength / lod, y + 0.5,
    
    97
    -                                 x + 0.5 + halfLength / lod, y + 0.5));
    
    98
    -      }
    
    72
    +    painter->setPen(gb->gridPen);
    
    73
    +    
    
    74
    +    // don't mark pixel center with a cross if magnification is too small
    
    75
    +    if (lod > 20)
    
    76
    +    {
    
    77
    +      int halfLength = 1;
    
    78
    +    
    
    79
    +      // cf. QSpinBoxx
    
    80
    +      if (lod > 640)
    
    81
    +        halfLength = 6;
    
    82
    +      else if (lod > 320)
    
    83
    +        halfLength = 5;
    
    84
    +      else if (lod > 160)
    
    85
    +        halfLength = 4;
    
    86
    +      else if (lod > 80)
    
    87
    +        halfLength = 3;
    
    88
    +      else if (lod > 40)
    
    89
    +        halfLength = 2;
    
    90
    +    
    
    91
    +      for (qreal x = minX; x < maxX; x++)
    
    92
    +        for (qreal y = minY; y < maxY; y++)
    
    93
    +        {
    
    94
    +          painter->drawLine(QLineF(x + 0.5, y + 0.5 - halfLength / lod,
    
    95
    +                                   x + 0.5, y + 0.5 + halfLength / lod));
    
    96
    +          painter->drawLine(QLineF(x + 0.5 - halfLength / lod, y + 0.5,
    
    97
    +                                   x + 0.5 + halfLength / lod, y + 0.5));
    
    98
    +        }
    
    99
    +    }
    
    100
    +    
    
    101
    +    // don't draw grid if magnification is too small
    
    102
    +    if (lod >= 5)
    
    103
    +    {
    
    104
    +      for (int x = minX; x <= maxX; x++)
    
    105
    +        painter->drawLine(x, minY,
    
    106
    +                          x, maxY);
    
    107
    +      for (int y = minY; y <= maxY; y++)
    
    108
    +        painter->drawLine(minX, y,
    
    109
    +                          maxX, y);
    
    110
    +    }
    
    111
    +    
    
    112
    +    painter->setPen(gb->axisPen);
    
    113
    +    
    
    114
    +    painter->drawLine(0, minY,
    
    115
    +                      0, maxY);
    
    116
    +    painter->drawLine(minX, 0,
    
    117
    +                      maxX, 0);
    
    99 118
       }
    
    100 119
     
    
    101
    -  // don't draw grid if magnification is too small
    
    102
    -  if (lod >= 5)
    
    120
    +  if (showAuxLines_)
    
    103 121
       {
    
    104
    -    for (int x = minX; x <= maxX; x++)
    
    105
    -      painter->drawLine(x, minY,
    
    106
    -                        x, maxY);
    
    107
    -    for (int y = minY; y <= maxY; y++)
    
    108
    -      painter->drawLine(minX, y,
    
    109
    -                        maxX, y);
    
    122
    +    painter->setPen(gb->ascDescAuxPen);
    
    123
    +    painter->drawLine(minX, ascender_,
    
    124
    +                      maxX, ascender_);
    
    125
    +    painter->drawLine(minX, descender_,
    
    126
    +                      maxX, descender_);
    
    127
    +
    
    128
    +    painter->setPen(gb->advanceAuxPen);
    
    129
    +    painter->drawLine(advance_, minY,
    
    130
    +                      advance_, maxY);
    
    110 131
       }
    
    132
    +}
    
    133
    +
    
    134
    +
    
    135
    +void
    
    136
    +Grid::setShowGrid(bool showGrid, bool showAuxLines)