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


From: Charlie Jiang (@cqjjjzr)
Subject: [Git][freetype/freetype-demos][gsoc-2022-chariri-3] 5 commits: [ftinspect] Formatting and minor refactoring.
Date: Fri, 05 Aug 2022 15:58:44 +0000

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

Commits:

  • cb7b9578
    by Charlie Jiang at 2022-08-03T21:47:16+08:00
    [ftinspect] Formatting and minor refactoring.
    
    * src/ftinspect/**: Refactored.
    
  • 6186fdb8
    by Charlie Jiang at 2022-08-03T23:56:15+08:00
    [ftinspect] Extract `CharMapComboBox` from `ContinousView`.
    
    The comparator view also need the charmap selector, so we extract it out.
    
    * src/ftinspect/widgets/charmapcombobox.cpp,
      src/ftinspect/widgets/charmapcombobox.cpp: New files.
    
    * src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
      Move out charmap related code.
    
    * src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
    
  • bf48dcab
    by Charlie Jiang at 2022-08-04T23:24:07+08:00
    [ftinspect] Add background and border to the bitmap in the details pane.
    
    * src/ftinspect/rendering/glyphbitmap.cpp: As described.
    
  • 5771ab06
    by Charlie Jiang at 2022-08-05T23:46:41+08:00
    [ftinspect] Add Comparator View.
    
    The layout and performance aren't quite ideal now.
    
    * src/ftinspect/panels/comparator.cpp, src/ftinspect/panels/comparator.hpp:
      New files.
    
    * src/ftinspect/rendering/glyphcontinuous.cpp,
      src/ftinspect/rendering/glyphcontinuous.hpp:
      Add `mouseOperationEnabled_` to disable mouse operations for the
      comparator view. Use `QPainter` ctor with a `QPaintDevice*` as the arg.
    
    * src/ftinspect/panels/settingpanel.cpp,
      src/ftinspect/panels/settingpanel.hpp
      Add `comparatorMode_`. When in comparator, the layout will be tighter, the
      hinting debug checkboxes will be absent and two comparator-only checkboxes
      will be shown.
      Rewrite the layouting part using the helpers introduced.
    
    * src/ftinspect/engine/stringrenderer.cpp,
      src/ftinspect/engine/stringrenderer.hpp:
      Add `lsbRsbDeltaEnabled_` field and properly handle LSB/RSB deltas.
      Allow the `limitIndex_` to be unset in string mode.
    
    * src/ftinspect/widgets/charmapcombobox.cpp,
      src/ftinspect/widgets/charmapcombobox.hpp:
      Add `haveGlyphOrder_` to remove Glyph Order because we don't need it in
      the comparator view.
    
    * src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp:
      Integrate `ComparatorTab` and hide the left panel when in comparator tab.
    
    * src/ftinspect/widgets/customwidgets.cpp,
      src/ftinspect/widgets/customwidgets.hpp:
      Add `UnboundScrollArea` to fix a Qt issue.
    
    * src/ftinspect/uihelper.cpp, src/ftinspect/uihelper.hpp:
      Add a series of helper functions for layouting using `QGridLayout`.
    
    * src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
    
  • 5242979d
    by Charlie Jiang at 2022-08-05T23:57:22+08:00
    [ftinspect] Add frames to the continuous canvases.
    
    * src/ftinspect/panels/comparator.cpp, src/ftinspect/panels/comparator.hpp,
      src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
      Use `QFrame` to provide frames.
    

23 changed files:

Changes:

  • src/ftinspect/CMakeLists.txt
    ... ... @@ -39,12 +39,14 @@ add_executable(ftinspect
    39 39
       "widgets/glyphindexselector.cpp"
    
    40 40
       "widgets/fontsizeselector.cpp"
    
    41 41
       "widgets/tripletselector.cpp"
    
    42
    +  "widgets/charmapcombobox.cpp"
    
    42 43
     
    
    43 44
       "models/customcomboboxmodels.cpp"
    
    44 45
     
    
    45 46
       "panels/settingpanel.cpp"
    
    46 47
       "panels/singular.cpp"
    
    47 48
       "panels/continuous.cpp"
    
    49
    +  "panels/comparator.cpp"
    
    48 50
       "panels/glyphdetails.cpp"
    
    49 51
     )
    
    50 52
     target_link_libraries(ftinspect
    

  • src/ftinspect/engine/stringrenderer.cpp
    ... ... @@ -67,7 +67,7 @@ StringRenderer::setKerning(bool kerning)
    67 67
     {
    
    68 68
       if (kerning)
    
    69 69
       {
    
    70
    -    kerningMode_ = KM_Normal;
    
    70
    +    kerningMode_ = KM_Smart;
    
    71 71
         kerningDegree_ = KD_Medium;
    
    72 72
       }
    
    73 73
       else
    
    ... ... @@ -203,7 +203,7 @@ StringRenderer::loadSingleContext(GlyphContext* ctx,
    203 203
       ctx->hadvance.x = metrics.horiAdvance;
    
    204 204
       ctx->hadvance.y = 0;
    
    205 205
     
    
    206
    -  if (engine_->lcdUsingSubPixelPositioning())
    
    206
    +  if (lsbRsbDeltaEnabled_ && engine_->lcdUsingSubPixelPositioning())
    
    207 207
         ctx->hadvance.x += ctx->lsbDelta - ctx->rsbDelta;
    
    208 208
       prev->hadvance.x += trackingKerning_;
    
    209 209
     
    
    ... ... @@ -214,14 +214,15 @@ StringRenderer::loadSingleContext(GlyphContext* ctx,
    214 214
     
    
    215 215
         prev->hadvance.x += kern.x;
    
    216 216
         prev->hadvance.y += kern.y;
    
    217
    +  }
    
    217 218
     
    
    218
    -    if (!engine_->lcdUsingSubPixelPositioning() && kerningMode_ > KM_Normal)
    
    219
    -    {
    
    220
    -      if (prev->rsbDelta - ctx->lsbDelta > 32)
    
    221
    -        prev->hadvance.x -= 64;
    
    222
    -      else if (prev->rsbDelta - ctx->lsbDelta < -31)
    
    223
    -        prev->hadvance.x += 64;
    
    224
    -    }
    
    219
    +  if (!engine_->lcdUsingSubPixelPositioning()
    
    220
    +      && lsbRsbDeltaEnabled_)
    
    221
    +  {
    
    222
    +    if (prev->rsbDelta - ctx->lsbDelta > 32)
    
    223
    +      prev->hadvance.x -= 64;
    
    224
    +    else if (prev->rsbDelta - ctx->lsbDelta < -31)
    
    225
    +      prev->hadvance.x += 64;
    
    225 226
       }
    
    226 227
     
    
    227 228
       if (!engine_->lcdUsingSubPixelPositioning() && engine_->doHinting())
    
    ... ... @@ -347,7 +348,9 @@ StringRenderer::render(int width,
    347 348
     {
    
    348 349
       if (usingString_)
    
    349 350
         offset = 0;
    
    350
    -  if (limitIndex_ <= 0)
    
    351
    +  if (!usingString_ && limitIndex_ <= 0)
    
    352
    +    return 0;
    
    353
    +  if (engine_->currentFontNumberOfGlyphs() <= 0)
    
    351 354
         return 0;
    
    352 355
     
    
    353 356
       // Separated into 3 modes:
    

  • src/ftinspect/engine/stringrenderer.hpp
    ... ... @@ -125,6 +125,7 @@ public:
    125 125
       void setRotation(double rotation);
    
    126 126
       void setWaterfall(bool waterfall) { waterfall_ = waterfall; }
    
    127 127
       void setPosition(double pos) { position_ = pos; }
    
    128
    +  void setLsbRsbDelta(bool enabled) { lsbRsbDeltaEnabled_ = enabled; }
    
    128 129
       void setKerning(bool kerning);
    
    129 130
     
    
    130 131
       // Need to be called when font or charMap changes
    
    ... ... @@ -190,6 +191,7 @@ private:
    190 191
       FT_Pos trackingKerning_ = 0;
    
    191 192
       FT_Matrix matrix_ = {};
    
    192 193
       bool matrixEnabled_ = false;
    
    194
    +  bool lsbRsbDeltaEnabled_ = true;
    
    193 195
     
    
    194 196
       RenderCallback renderCallback_;
    
    195 197
       RenderImageCallback renderImageCallback_;
    

  • src/ftinspect/maingui.cpp
    ... ... @@ -161,6 +161,16 @@ MainGUI::onTripletChanged()
    161 161
     }
    
    162 162
     
    
    163 163
     
    
    164
    +void
    
    165
    +MainGUI::switchTab()
    
    166
    +{
    
    167
    +  auto isComparator = tabWidget_->currentWidget() == comparatorTab_;
    
    168
    +  leftWidget_->setVisible(!isComparator);
    
    169
    +
    
    170
    +  reloadCurrentTabFont();
    
    171
    +}
    
    172
    +
    
    173
    +
    
    164 174
     void
    
    165 175
     MainGUI::switchToSingular(int glyphIndex,
    
    166 176
                               double sizePoint)
    
    ... ... @@ -189,7 +199,8 @@ MainGUI::reloadCurrentTabFont()
    189 199
     void
    
    190 200
     MainGUI::syncSettings()
    
    191 201
     {
    
    192
    -  settingPanel_->syncSettings();
    
    202
    +  if (tabWidget_->currentWidget() != comparatorTab_)
    
    203
    +    settingPanel_->syncSettings();
    
    193 204
     }
    
    194 205
     
    
    195 206
     
    
    ... ... @@ -210,7 +221,7 @@ MainGUI::createLayout()
    210 221
     
    
    211 222
       leftLayout_ = new QVBoxLayout; // The only point is to set a margin->remove?
    
    212 223
       leftLayout_->addWidget(settingPanel_);
    
    213
    -  leftLayout_->setContentsMargins(32, 32, 8, 16);
    
    224
    +  leftLayout_->setContentsMargins(32, 32, 0, 16);
    
    214 225
     
    
    215 226
       // we don't want to expand the left side horizontally;
    
    216 227
       // to change the policy we have to use a widget wrapper
    
    ... ... @@ -228,6 +239,7 @@ MainGUI::createLayout()
    228 239
       singularTab_ = new SingularTab(this, engine_);
    
    229 240
       continuousTab_ = new ContinuousTab(this, engine_,
    
    230 241
                                          glyphDetailsDockWidget_, glyphDetails_);
    
    242
    +  comparatorTab_ = new ComperatorTab(this, engine_);
    
    231 243
     
    
    232 244
       tabWidget_ = new QTabWidget(this);
    
    233 245
     
    
    ... ... @@ -236,13 +248,15 @@ MainGUI::createLayout()
    236 248
       tabWidget_->addTab(singularTab_, tr("Singular Grid View"));
    
    237 249
       tabs_.append(continuousTab_);
    
    238 250
       tabWidget_->addTab(continuousTab_, tr("Continuous View"));
    
    251
    +  tabs_.append(comparatorTab_);
    
    252
    +  tabWidget_->addTab(comparatorTab_, tr("Comparator View"));
    
    239 253
       
    
    240 254
       tripletSelector_ = new TripletSelector(this, engine_);
    
    241 255
     
    
    242 256
       rightLayout_ = new QVBoxLayout;
    
    243 257
       //rightLayout_->addWidget(fontNameLabel_);
    
    244 258
       rightLayout_->addWidget(tabWidget_); // same for `leftLayout_`: Remove?
    
    245
    -  rightLayout_->setContentsMargins(8, 32, 32, 16);
    
    259
    +  rightLayout_->setContentsMargins(16, 32, 32, 16);
    
    246 260
     
    
    247 261
       // for symmetry with the left side use a widget also
    
    248 262
       rightWidget_ = new QWidget(this);
    
    ... ... @@ -277,7 +291,7 @@ MainGUI::createConnections()
    277 291
               this, &MainGUI::repaintCurrentTab);
    
    278 292
     
    
    279 293
       connect(tabWidget_, &QTabWidget::currentChanged,
    
    280
    -          this, &MainGUI::reloadCurrentTabFont);
    
    294
    +          this, &MainGUI::switchTab);
    
    281 295
     
    
    282 296
       connect(tripletSelector_, &TripletSelector::tripletChanged,
    
    283 297
               this, &MainGUI::onTripletChanged);
    

  • src/ftinspect/maingui.hpp
    ... ... @@ -10,6 +10,7 @@
    10 10
     #include "panels/settingpanel.hpp"
    
    11 11
     #include "panels/singular.hpp"
    
    12 12
     #include "panels/continuous.hpp"
    
    13
    +#include "panels/comparator.hpp"
    
    13 14
     #include "panels/glyphdetails.hpp"
    
    14 15
     
    
    15 16
     #include <QAction>
    
    ... ... @@ -72,6 +73,7 @@ private slots:
    72 73
       void reloadCurrentTabFont();
    
    73 74
       void loadFonts();
    
    74 75
       void onTripletChanged();
    
    76
    +  void switchTab();
    
    75 77
       void switchToSingular(int glyphIndex, double sizePoint);
    
    76 78
     
    
    77 79
     private:
    
    ... ... @@ -109,6 +111,7 @@ private:
    109 111
       QVector<AbstractTab*> tabs_;
    
    110 112
       SingularTab* singularTab_;
    
    111 113
       ContinuousTab* continuousTab_;
    
    114
    +  ComperatorTab* comparatorTab_;
    
    112 115
     
    
    113 116
       QDockWidget* glyphDetailsDockWidget_;
    
    114 117
       GlyphDetails* glyphDetails_;
    

  • src/ftinspect/meson.build
    ... ... @@ -39,12 +39,14 @@ if qt5_dep.found()
    39 39
         'widgets/glyphindexselector.cpp',
    
    40 40
         'widgets/fontsizeselector.cpp',
    
    41 41
         'widgets/tripletselector.cpp',
    
    42
    +    'widgets/charmapcombobox.cpp',
    
    42 43
     
    
    43 44
         'models/customcomboboxmodels.cpp',
    
    44 45
     
    
    45 46
         'panels/settingpanel.cpp',
    
    46 47
         'panels/singular.cpp',
    
    47 48
         'panels/continuous.cpp',
    
    49
    +    'panels/comparator.cpp',
    
    48 50
         'panels/glyphdetails.cpp',
    
    49 51
     
    
    50 52
         'ftinspect.cpp',
    
    ... ... @@ -59,11 +61,13 @@ if qt5_dep.found()
    59 61
           'widgets/glyphindexselector.hpp',
    
    60 62
           'widgets/fontsizeselector.hpp',
    
    61 63
           'widgets/tripletselector.hpp',
    
    64
    +      'widgets/charmapcombobox.hpp',
    
    62 65
           'rendering/glyphcontinuous.hpp',
    
    63 66
           'models/customcomboboxmodels.hpp',
    
    64 67
           'panels/settingpanel.hpp',
    
    65 68
           'panels/singular.hpp',
    
    66 69
           'panels/continuous.hpp',
    
    70
    +      'panels/comparator.hpp',
    
    67 71
           'panels/glyphdetails.hpp',
    
    68 72
           'maingui.hpp',
    
    69 73
         ],
    

  • src/ftinspect/panels/comparator.cpp
    1
    +// comparator.cpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#include "comparator.hpp"
    
    6
    +
    
    7
    +#include <QScrollBar>
    
    8
    +
    
    9
    +namespace
    
    10
    +{
    
    11
    +// No C++17 :-(
    
    12
    +extern const char* ComparatorDefaultText;
    
    13
    +}
    
    14
    +
    
    15
    +ComperatorTab::ComperatorTab(QWidget* parent, Engine* engine)
    
    16
    +: QWidget(parent),
    
    17
    +  engine_(engine)
    
    18
    +{
    
    19
    +  createLayout();
    
    20
    +  createConnections();
    
    21
    +  setupCanvases();
    
    22
    +}
    
    23
    +
    
    24
    +
    
    25
    +ComperatorTab::~ComperatorTab()
    
    26
    +{
    
    27
    +}
    
    28
    +
    
    29
    +
    
    30
    +void
    
    31
    +ComperatorTab::repaintGlyph()
    
    32
    +{
    
    33
    +  sizeSelector_->applyToEngine(engine_);
    
    34
    +
    
    35
    +  int i = 0;
    
    36
    +  for (auto canvas : canvas_)
    
    37
    +  {
    
    38
    +    syncSettings(i);
    
    39
    +    // No cache here, sry, because when switching between columns, the hinting
    
    40
    +    // mode or enabling of embedded bitmaps may differ
    
    41
    +    canvas->stringRenderer().reloadGlyphs();
    
    42
    +    canvas->purgeCache();
    
    43
    +    canvas->repaint();
    
    44
    +    i++;
    
    45
    +  }
    
    46
    +}
    
    47
    +
    
    48
    +
    
    49
    +void
    
    50
    +ComperatorTab::reloadFont()
    
    51
    +{
    
    52
    +  charMapSelector_->repopulate();
    
    53
    +  for (auto panel : settingPanels_)
    
    54
    +    panel->onFontChanged();
    
    55
    +
    
    56
    +  for (auto canvas : canvas_)
    
    57
    +    canvas->stringRenderer().reloadAll();
    
    58
    +  repaintGlyph();
    
    59
    +}
    
    60
    +
    
    61
    +
    
    62
    +bool
    
    63
    +ComperatorTab::eventFilter(QObject* watched,
    
    64
    +                           QEvent* event)
    
    65
    +{
    
    66
    +  auto ptr = qobject_cast<GlyphContinuous*>(watched);
    
    67
    +  if (ptr && event->type() == QEvent::Resize)
    
    68
    +    return true;
    
    69
    +  return QWidget::eventFilter(watched, event);
    
    70
    +}
    
    71
    +
    
    72
    +
    
    73
    +void
    
    74
    +ComperatorTab::resizeEvent(QResizeEvent* event)
    
    75
    +{
    
    76
    +  QWidget::resizeEvent(event);
    
    77
    +  repaintGlyph();
    
    78
    +}
    
    79
    +
    
    80
    +
    
    81
    +void
    
    82
    +ComperatorTab::createLayout()
    
    83
    +{
    
    84
    +  sizeSelector_ = new FontSizeSelector(this);
    
    85
    +  charMapLabel_ = new QLabel(tr("Char Map:"), this);
    
    86
    +  charMapSelector_ = new CharMapComboBox(this, engine_, false);
    
    87
    +
    
    88
    +  sourceTextEdit_ = new QPlainTextEdit(QString(ComparatorDefaultText), this);
    
    89
    +
    
    90
    +  for (int i = 0; i < ColumnWidth; ++i)
    
    91
    +  {
    
    92
    +    auto frame = new QFrame(this);
    
    93
    +    auto canvas = new GlyphContinuous(frame, engine_);
    
    94
    +    auto settingPanel = new SettingPanel(this, engine_, true);
    
    95
    +    auto area = new UnboundScrollArea(this);
    
    96
    +
    
    97
    +    area->setWidget(settingPanel);
    
    98
    +    area->setWidgetResizable(true);
    
    99
    +    area->horizontalScrollBar()->setEnabled(false);
    
    100
    +    
    
    101
    +    canvas->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
    
    102
    +    area->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
    
    103
    +
    
    104
    +    canvas_.emplace_back(canvas);
    
    105
    +    settingPanelAreas_.emplace_back(area);
    
    106
    +    settingPanels_.emplace_back(settingPanel);
    
    107
    +    frames_.emplace_back(frame);
    
    108
    +
    
    109
    +    auto frameLayout = new QHBoxLayout;
    
    110
    +    frameLayout->addWidget(canvas);
    
    111
    +    frame->setLayout(frameLayout);
    
    112
    +    frame->setContentsMargins(2, 2, 2, 2);
    
    113
    +    frameLayout->setContentsMargins(2, 2, 2, 2);
    
    114
    +    frame->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
    
    115
    +  }
    
    116
    +
    
    117
    +  sourceWidget_ = new QWidget(this);
    
    118
    +  sourceWidget_->setMaximumWidth(350);
    
    119
    +
    
    120
    +  layout_ = new QGridLayout;
    
    121
    +
    
    122
    +  charMapLayout_ = new QHBoxLayout;
    
    123
    +  charMapLayout_->addWidget(charMapLabel_);
    
    124
    +  charMapLayout_->addWidget(charMapSelector_);
    
    125
    +
    
    126
    +  sourceLayout_ = new QVBoxLayout;
    
    127
    +  sourceLayout_->addWidget(sizeSelector_);
    
    128
    +  sourceLayout_->addLayout(charMapLayout_);
    
    129
    +  sourceLayout_->addWidget(sourceTextEdit_, 1);
    
    130
    +  sourceWidget_->setLayout(sourceLayout_);
    
    131
    +
    
    132
    +  layout_->addWidget(sourceWidget_, 0, 0, 2, 1);
    
    133
    +  for (int i = 0; static_cast<unsigned>(i) < frames_.size(); ++i)
    
    134
    +    layout_->addWidget(frames_[i], 0, i + 1);
    
    135
    +  for (int i = 0; static_cast<unsigned>(i) < settingPanelAreas_.size(); ++i)
    
    136
    +    layout_->addWidget(settingPanelAreas_[i], 1, i + 1);
    
    137
    +
    
    138
    +  layout_->setRowStretch(0, 3);
    
    139
    +  layout_->setRowStretch(1, 2);
    
    140
    +
    
    141
    +  setLayout(layout_);
    
    142
    +}
    
    143
    +
    
    144
    +
    
    145
    +void
    
    146
    +ComperatorTab::createConnections()
    
    147
    +{
    
    148
    +  connect(sizeSelector_, &FontSizeSelector::valueChanged,
    
    149
    +          this, &ComperatorTab::reloadGlyphsAndRepaint);
    
    150
    +  connect(sourceTextEdit_, &QPlainTextEdit::textChanged,
    
    151
    +          this, &ComperatorTab::sourceTextChanged);
    
    152
    +  connect(charMapSelector_,
    
    153
    +          QOverload<int>::of(&CharMapComboBox::currentIndexChanged),
    
    154
    +          this, &ComperatorTab::reloadStringAndRepaint);
    
    155
    +
    
    156
    +  for (auto panel : settingPanels_)
    
    157
    +  {
    
    158
    +    // We're treating the two events identically, because we need to do a
    
    159
    +    // complete flush anyway
    
    160
    +    connect(panel, &SettingPanel::repaintNeeded,
    
    161
    +            this, &ComperatorTab::repaintGlyph);
    
    162
    +    connect(panel, &SettingPanel::fontReloadNeeded,
    
    163
    +            this, &ComperatorTab::repaintGlyph);
    
    164
    +  }
    
    165
    +}
    
    166
    +
    
    167
    +
    
    168
    +void
    
    169
    +ComperatorTab::setupCanvases()
    
    170
    +{
    
    171
    +  for (auto canvas : canvas_)
    
    172
    +  {
    
    173
    +    canvas->setMode(GlyphContinuous::M_Normal);
    
    174
    +    canvas->setSource(GlyphContinuous::SRC_TextStringRepeated);
    
    175
    +    canvas->setMouseOperationEnabled(false);
    
    176
    +    canvas->setSourceText(sourceTextEdit_->toPlainText());
    
    177
    +
    
    178
    +    canvas->installEventFilter(this);
    
    179
    +  }
    
    180
    +  sourceTextChanged();
    
    181
    +}
    
    182
    +
    
    183
    +
    
    184
    +void
    
    185
    +ComperatorTab::reloadStringAndRepaint()
    
    186
    +{
    
    187
    +  int i = 0;
    
    188
    +  for (auto canvas : canvas_)
    
    189
    +  {
    
    190
    +    syncSettings(i);
    
    191
    +
    
    192
    +    auto& sr = canvas->stringRenderer();
    
    193
    +    sr.setCharMapIndex(charMapSelector_->currentCharMapIndex(), -1);
    
    194
    +    sr.reloadAll();
    
    195
    +    i++;
    
    196
    +  }
    
    197
    +  repaintGlyph();
    
    198
    +}
    
    199
    +
    
    200
    +
    
    201
    +void
    
    202
    +ComperatorTab::reloadGlyphsAndRepaint()
    
    203
    +{
    
    204
    +  int i = 0;
    
    205
    +  for (auto canvas : canvas_)
    
    206
    +  {
    
    207
    +    syncSettings(i);
    
    208
    +    canvas->stringRenderer().reloadGlyphs();
    
    209
    +    i++;
    
    210
    +  }
    
    211
    +  repaintGlyph();
    
    212
    +}
    
    213
    +
    
    214
    +
    
    215
    +void
    
    216
    +ComperatorTab::sourceTextChanged()
    
    217
    +{
    
    218
    +  for (auto canvas : canvas_)
    
    219
    +    canvas->setSourceText(sourceTextEdit_->toPlainText());
    
    220
    +  reloadStringAndRepaint();
    
    221
    +}
    
    222
    +
    
    223
    +
    
    224
    +void
    
    225
    +ComperatorTab::syncSettings(int index)
    
    226
    +{
    
    227
    +  if (index < 0 || static_cast<unsigned>(index) >= settingPanels_.size())
    
    228
    +    return;
    
    229
    +
    
    230
    +  auto settingPanel = settingPanels_[index];
    
    231
    +  settingPanel->applyHintingMode();
    
    232
    +  settingPanel->syncSettings();
    
    233
    +
    
    234
    +  if (static_cast<unsigned>(index) >= canvas_.size())
    
    235
    +    return;
    
    236
    +
    
    237
    +  auto canvas = canvas_[index];
    
    238
    +  canvas->stringRenderer().setKerning(settingPanel->kerningEnabled());
    
    239
    +  canvas->stringRenderer().setLsbRsbDelta(settingPanel->lsbRsbDeltaEnabled());
    
    240
    +}
    
    241
    +
    
    242
    +
    
    243
    +namespace
    
    244
    +{
    
    245
    +const char* ComparatorDefaultText
    
    246
    +    = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras sit amet"
    
    247
    +      " dui.  Nam sapien. Fusce vestibulum ornare metus. Maecenas ligula orci,"
    
    248
    +      " consequat vitae, dictum nec, lacinia non, elit. Aliquam iaculis"
    
    249
    +      " molestie neque. Maecenas suscipit felis ut pede convallis malesuada."
    
    250
    +      " Aliquam erat volutpat. Nunc pulvinar condimentum nunc. Donec ac sem vel"
    
    251
    +      " leo bibendum aliquam. Pellentesque habitant morbi tristique senectus et"
    
    252
    +      " netus et malesuada fames ac turpis egestas.\n"
    
    253
    +      "\n"
    
    254
    +      "Sed commodo. Nulla ut libero sit amet justo varius blandit. Mauris vitae"
    
    255
    +      " nulla eget lorem pretium ornare. Proin vulputate erat porta risus."
    
    256
    +      " Vestibulum malesuada, odio at vehicula lobortis, nisi metus hendrerit"
    
    257
    +      " est, vitae feugiat quam massa a ligula. Aenean in tellus. Praesent"
    
    258
    +      " convallis. Nullam vel lacus.  Aliquam congue erat non urna mollis"
    
    259
    +      " faucibus. Morbi vitae mauris faucibus quam condimentum ornare. Quisque"
    
    260
    +      " sit amet augue. Morbi ullamcorper mattis enim. Aliquam erat volutpat."
    
    261
    +      " Morbi nec felis non enim pulvinar lobortis.  Ut libero. Nullam id orci"
    
    262
    +      " quis nisl dapibus rutrum. Suspendisse consequat vulputate leo. Aenean"
    
    263
    +      " non orci non tellus iaculis vestibulum. Sed neque.\n"
    
    264
    +      "\n";
    
    265
    +}
    
    266
    +
    
    267
    +
    
    268
    +// end of comparator.cpp

  • src/ftinspect/panels/comparator.hpp
    1
    +// comparator.hpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#pragma once
    
    6
    +
    
    7
    +#include "abstracttab.hpp"
    
    8
    +#include "../engine/engine.hpp"
    
    9
    +#include "../widgets/customwidgets.hpp"
    
    10
    +#include "../widgets/charmapcombobox.hpp"
    
    11
    +#include "../widgets/fontsizeselector.hpp"
    
    12
    +#include "../panels/settingpanel.hpp"
    
    13
    +#include "../rendering/glyphcontinuous.hpp"
    
    14
    +
    
    15
    +#include <vector>
    
    16
    +
    
    17
    +#include <QWidget>
    
    18
    +#include <QFrame>
    
    19
    +#include <QLabel>
    
    20
    +#include <QGridLayout>
    
    21
    +#include <QBoxLayout>
    
    22
    +#include <QPlainTextEdit>
    
    23
    +
    
    24
    +class ComperatorTab
    
    25
    +: public QWidget, public AbstractTab
    
    26
    +{
    
    27
    +  Q_OBJECT
    
    28
    +public:
    
    29
    +  ComperatorTab(QWidget* parent, Engine* engine);
    
    30
    +  ~ComperatorTab() override;
    
    31
    +
    
    32
    +  void repaintGlyph() override;
    
    33
    +  void reloadFont() override;
    
    34
    +
    
    35
    +protected:
    
    36
    +  bool eventFilter(QObject* watched, QEvent* event) override;
    
    37
    +  void resizeEvent(QResizeEvent* event) override;
    
    38
    +
    
    39
    +private:
    
    40
    +  constexpr static int ColumnWidth = 3;
    
    41
    +
    
    42
    +  Engine* engine_;
    
    43
    +
    
    44
    +  FontSizeSelector* sizeSelector_;
    
    45
    +  QLabel* charMapLabel_;
    
    46
    +  CharMapComboBox* charMapSelector_;
    
    47
    +  QPlainTextEdit* sourceTextEdit_;
    
    48
    +
    
    49
    +  std::vector<GlyphContinuous*> canvas_;
    
    50
    +  std::vector<SettingPanel*> settingPanels_;
    
    51
    +  std::vector<QFrame*> frames_;
    
    52
    +  std::vector<UnboundScrollArea*> settingPanelAreas_;
    
    53
    +
    
    54
    +  QWidget* sourceWidget_;
    
    55
    +
    
    56
    +  QVBoxLayout* sourceLayout_;
    
    57
    +  QHBoxLayout* charMapLayout_;
    
    58
    +  QGridLayout* layout_;
    
    59
    +
    
    60
    +  void createLayout();
    
    61
    +  void createConnections();
    
    62
    +  void setupCanvases();
    
    63
    +
    
    64
    +  void reloadStringAndRepaint();
    
    65
    +  void reloadGlyphsAndRepaint();
    
    66
    +  void sourceTextChanged();
    
    67
    +  void syncSettings(int index);
    
    68
    +};
    
    69
    +
    
    70
    +
    
    71
    +// end of comparator.hpp

  • src/ftinspect/panels/continuous.cpp
    ... ... @@ -22,7 +22,7 @@ ContinuousTab::ContinuousTab(QWidget* parent,
    22 22
       createLayout();
    
    23 23
     
    
    24 24
       std::vector<CharMapInfo> tempCharMaps;
    
    25
    -  setCharMaps(tempCharMaps); // pass in an empty one
    
    25
    +  charMapSelector_->repopulate(tempCharMaps); // pass in an empty one
    
    26 26
     
    
    27 27
       checkModeSource();
    
    28 28
       setDefaults();
    
    ... ... @@ -47,7 +47,7 @@ ContinuousTab::reloadFont()
    47 47
     {
    
    48 48
       currentGlyphCount_ = engine_->currentFontNumberOfGlyphs();
    
    49 49
       setGlyphCount(qBound(0, currentGlyphCount_, INT_MAX));
    
    50
    -  setCharMaps(engine_->currentFontCharMaps());
    
    50
    +  charMapSelector_->repopulate();
    
    51 51
       canvas_->stringRenderer().reloadAll();
    
    52 52
       canvas_->purgeCache();
    
    53 53
       repaintGlyph();
    
    ... ... @@ -84,12 +84,7 @@ ContinuousTab::syncSettings()
    84 84
     int
    
    85 85
     ContinuousTab::charMapIndex()
    
    86 86
     {
    
    87
    -  auto index = charMapSelector_->currentIndex() - 1;
    
    88
    -  if (index <= -1)
    
    89
    -    return -1;
    
    90
    -  if (static_cast<unsigned>(index) >= charMaps_.size())
    
    91
    -    return -1;
    
    92
    -  return index;
    
    87
    +  return charMapSelector_->currentCharMapIndex();
    
    93 88
     }
    
    94 89
     
    
    95 90
     
    
    ... ... @@ -115,69 +110,14 @@ ContinuousTab::setGlyphBeginindex(int index)
    115 110
     }
    
    116 111
     
    
    117 112
     
    
    118
    -#define EncodingRole (Qt::UserRole + 10)
    
    119
    -void
    
    120
    -ContinuousTab::setCharMaps(std::vector<CharMapInfo>& charMaps)
    
    121
    -{
    
    122
    -  if (charMaps_ == charMaps)
    
    123
    -  {
    
    124
    -    charMaps_ = charMaps; // Still need to substitute because ptr may differ
    
    125
    -    return;
    
    126
    -  }
    
    127
    -  charMaps_ = charMaps;
    
    128
    -  int oldIndex = charMapSelector_->currentIndex();
    
    129
    -  unsigned oldEncoding = 0u;
    
    130
    -
    
    131
    -  // Using additional UserRole to store encoding id
    
    132
    -  auto oldEncodingV = charMapSelector_->itemData(oldIndex, EncodingRole);
    
    133
    -  if (oldEncodingV.isValid() && oldEncodingV.canConvert<unsigned>())
    
    134
    -  {
    
    135
    -    oldEncoding = oldEncodingV.value<unsigned>();
    
    136
    -  }
    
    137
    -
    
    138
    -  {
    
    139
    -    // suppress events during updating
    
    140
    -    QSignalBlocker selectorBlocker(charMapSelector_);
    
    141
    -
    
    142
    -    charMapSelector_->clear();
    
    143
    -    charMapSelector_->addItem(tr("Glyph Order"));
    
    144
    -    charMapSelector_->setItemData(0, 0u, EncodingRole);
    
    145
    -
    
    146
    -    int i = 0;
    
    147
    -    int newIndex = 0;
    
    148
    -    for (auto& map : charMaps)
    
    149
    -    {
    
    150
    -      charMapSelector_->addItem(tr("%1: %2 (platform %3, encoding %4)")
    
    151
    -                                .arg(i)
    
    152
    -                                .arg(*map.encodingName)
    
    153
    -                                .arg(map.platformID)
    
    154
    -                                .arg(map.encodingID));
    
    155
    -      auto encoding = static_cast<unsigned>(map.encoding);
    
    156
    -      charMapSelector_->setItemData(i, encoding, EncodingRole);
    
    157
    -
    
    158
    -      if (encoding == oldEncoding && i == oldIndex)
    
    159
    -        newIndex = i;
    
    160
    -    
    
    161
    -      i++;
    
    162
    -    }
    
    163
    -
    
    164
    -    // this shouldn't emit any event either, because force repainting
    
    165
    -    // will happen later, so embrace it into blocker block
    
    166
    -    charMapSelector_->setCurrentIndex(newIndex);
    
    167
    -  }
    
    168
    -
    
    169
    -  updateLimitIndex();
    
    170
    -}
    
    171
    -
    
    172
    -
    
    173 113
     void
    
    174 114
     ContinuousTab::updateLimitIndex()
    
    175 115
     {
    
    176
    -  if (charMapSelector_->currentIndex() <= 0)
    
    116
    +  auto cMap = charMapSelector_->currentCharMapIndex();
    
    117
    +  if (cMap < 0)
    
    177 118
         glyphLimitIndex_ = currentGlyphCount_;
    
    178 119
       else
    
    179
    -    glyphLimitIndex_
    
    180
    -      = charMaps_[charMapSelector_->currentIndex() - 1].maxIndex + 1;
    
    120
    +    glyphLimitIndex_ = charMapSelector_->charMaps()[cMap].maxIndex + 1;
    
    181 121
       indexSelector_->setMinMax(0, glyphLimitIndex_ - 1);
    
    182 122
     }
    
    183 123
     
    
    ... ... @@ -224,17 +164,9 @@ ContinuousTab::checkModeSource()
    224 164
     void
    
    225 165
     ContinuousTab::charMapChanged()
    
    226 166
     {
    
    227
    -  int newIndex = charMapSelector_->currentIndex();
    
    167
    +  int newIndex = charMapSelector_->currentCharMapIndex();
    
    228 168
       if (newIndex != lastCharMapIndex_)
    
    229
    -  {
    
    230
    -    if (newIndex <= 0
    
    231
    -        || charMaps_.size() <= static_cast<unsigned>(newIndex - 1))
    
    232
    -      setGlyphBeginindex(0);
    
    233
    -    else if (charMaps_[newIndex - 1].maxIndex <= 20)
    
    234
    -      setGlyphBeginindex(charMaps_[newIndex - 1].maxIndex - 1);
    
    235
    -    else
    
    236
    -      setGlyphBeginindex(0x20);
    
    237
    -  }
    
    169
    +    setGlyphBeginindex(charMapSelector_->defaultFirstGlyphIndex());
    
    238 170
       updateLimitIndex();
    
    239 171
     
    
    240 172
       syncSettings();
    
    ... ... @@ -310,7 +242,10 @@ ContinuousTab::wheelResize(int steps)
    310 242
     void
    
    311 243
     ContinuousTab::createLayout()
    
    312 244
     {
    
    313
    -  canvas_ = new GlyphContinuous(this, engine_);
    
    245
    +  canvasFrame_ = new QFrame(this);
    
    246
    +  canvasFrame_->setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
    
    247
    +
    
    248
    +  canvas_ = new GlyphContinuous(canvasFrame_, engine_);
    
    314 249
       sizeSelector_ = new FontSizeSelector(this);
    
    315 250
     
    
    316 251
       indexSelector_ = new GlyphIndexSelector(this);
    
    ... ... @@ -321,7 +256,7 @@ ContinuousTab::createLayout()
    321 256
           tr("The quick brown fox jumps over the lazy dog."), this);
    
    322 257
     
    
    323 258
       modeSelector_ = new QComboBox(this);
    
    324
    -  charMapSelector_ = new QComboBox(this);
    
    259
    +  charMapSelector_ = new CharMapComboBox(this, engine_);
    
    325 260
       sourceSelector_ = new QComboBox(this);
    
    326 261
     
    
    327 262
       charMapSelector_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
    
    ... ... @@ -377,6 +312,12 @@ ContinuousTab::createLayout()
    377 312
       rotationSpinBox_->setMinimum(-180);
    
    378 313
       rotationSpinBox_->setMaximum(180);
    
    379 314
     
    
    315
    +  canvasFrameLayout_ = new QHBoxLayout;
    
    316
    +  canvasFrameLayout_->addWidget(canvas_);
    
    317
    +  canvasFrame_->setLayout(canvasFrameLayout_);
    
    318
    +  canvasFrameLayout_->setContentsMargins(2, 2, 2, 2);
    
    319
    +  canvasFrame_->setContentsMargins(2, 2, 2, 2);
    
    320
    +
    
    380 321
       bottomLayout_ = new QGridLayout;
    
    381 322
       bottomLayout_->addWidget(sourceLabel_, 0, 0);
    
    382 323
       bottomLayout_->addWidget(modeLabel_, 1, 0);
    
    ... ... @@ -407,7 +348,7 @@ ContinuousTab::createLayout()
    407 348
       bottomLayout_->setColumnStretch(4, 1);
    
    408 349
     
    
    409 350
       mainLayout_ = new QVBoxLayout;
    
    410
    -  mainLayout_->addWidget(canvas_);
    
    351
    +  mainLayout_->addWidget(canvasFrame_);
    
    411 352
       mainLayout_->addWidget(sizeSelector_);
    
    412 353
       mainLayout_->addLayout(bottomLayout_);
    
    413 354
     
    
    ... ... @@ -438,8 +379,11 @@ ContinuousTab::createConnections()
    438 379
               this, &ContinuousTab::repaintGlyph);
    
    439 380
       connect(modeSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    440 381
               this, &ContinuousTab::checkModeSource);
    
    441
    -  connect(charMapSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    382
    +  connect(charMapSelector_,
    
    383
    +          QOverload<int>::of(&CharMapComboBox::currentIndexChanged),
    
    442 384
               this, &ContinuousTab::charMapChanged);
    
    385
    +  connect(charMapSelector_, &CharMapComboBox::forceUpdateLimitIndex,
    
    386
    +          this, &ContinuousTab::updateLimitIndex);
    
    443 387
       connect(sourceSelector_, QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    444 388
               this, &ContinuousTab::checkModeSource);
    
    445 389
     
    
    ... ... @@ -493,10 +437,10 @@ ContinuousTab::setDefaults()
    493 437
     QString
    
    494 438
     ContinuousTab::formatIndex(int index)
    
    495 439
     {
    
    496
    -  if (charMapSelector_->currentIndex() <= 0) // glyph order
    
    440
    +  auto idx = charMapSelector_->currentCharMapIndex();
    
    441
    +  if (idx < 0) // glyph order
    
    497 442
         return QString::number(index);
    
    498
    -  return charMaps_[charMapSelector_->currentIndex() - 1].stringifyIndexShort(
    
    499
    -      index);
    
    443
    +  return charMapSelector_->charMaps()[idx].stringifyIndexShort(index);
    
    500 444
     }
    
    501 445
     
    
    502 446
     
    

  • src/ftinspect/panels/continuous.hpp
    ... ... @@ -8,12 +8,14 @@
    8 8
     #include "../widgets/customwidgets.hpp"
    
    9 9
     #include "../widgets/glyphindexselector.hpp"
    
    10 10
     #include "../widgets/fontsizeselector.hpp"
    
    11
    +#include "../widgets/charmapcombobox.hpp"
    
    11 12
     #include "../rendering/graphicsdefault.hpp"
    
    12 13
     #include "../rendering/glyphcontinuous.hpp"
    
    13 14
     #include "../engine/engine.hpp"
    
    14 15
     
    
    15 16
     #include <vector>
    
    16 17
     #include <QWidget>
    
    18
    +#include <QFrame>
    
    17 19
     #include <QLabel>
    
    18 20
     #include <QComboBox>
    
    19 21
     #include <QGridLayout>
    
    ... ... @@ -44,7 +46,6 @@ public:
    44 46
       void setDisplayingCount(int count);
    
    45 47
       void setGlyphBeginindex(int index);
    
    46 48
     
    
    47
    -  void setCharMaps(std::vector<CharMapInfo>& charMaps);
    
    48 49
       // This doesn't trigger either.
    
    49 50
       void updateLimitIndex();
    
    50 51
       void checkModeSource();
    
    ... ... @@ -74,11 +75,12 @@ private:
    74 75
       int glyphLimitIndex_ = 0;
    
    75 76
     
    
    76 77
       GlyphContinuous* canvas_;
    
    78
    +  QFrame* canvasFrame_;
    
    77 79
       FontSizeSelector* sizeSelector_;
    
    78 80
     
    
    79 81
       QComboBox* modeSelector_;
    
    80 82
       QComboBox* sourceSelector_;
    
    81
    -  QComboBox* charMapSelector_;
    
    83
    +  CharMapComboBox* charMapSelector_ = NULL;
    
    82 84
     
    
    83 85
       QPushButton* resetPositionButton_;
    
    84 86
     
    
    ... ... @@ -103,9 +105,8 @@ private:
    103 105
     
    
    104 106
       GlyphIndexSelector* indexSelector_;
    
    105 107
       QPlainTextEdit* sourceTextEdit_;
    
    106
    -
    
    107
    -  std::vector<CharMapInfo> charMaps_;
    
    108 108
       
    
    109
    +  QHBoxLayout* canvasFrameLayout_;
    
    109 110
       QGridLayout* bottomLayout_;
    
    110 111
       QVBoxLayout* mainLayout_;
    
    111 112
     
    

  • src/ftinspect/panels/glyphdetails.cpp
    ... ... @@ -28,10 +28,10 @@ GlyphDetails::~GlyphDetails()
    28 28
     void
    
    29 29
     GlyphDetails::updateGlyph(GlyphCacheEntry& ctxt, int charMapIndex)
    
    30 30
     {
    
    31
    -  auto& cmaps = engine_->currentFontCharMaps();
    
    31
    +  auto& cMaps = engine_->currentFontCharMaps();
    
    32 32
     
    
    33 33
       glyphIndexLabel_->setText(QString::number(ctxt.glyphIndex));
    
    34
    -  if (charMapIndex < 0 || charMapIndex >= static_cast<int>(cmaps.size()))
    
    34
    +  if (charMapIndex < 0 || static_cast<unsigned>(charMapIndex) >= cMaps.size())
    
    35 35
       {
    
    36 36
         charCodePromptLabel_->setVisible(false);
    
    37 37
         charCodeLabel_->setVisible(false);
    
    ... ... @@ -41,7 +41,7 @@ GlyphDetails::updateGlyph(GlyphCacheEntry& ctxt, int charMapIndex)
    41 41
         charCodePromptLabel_->setVisible(true);
    
    42 42
         charCodeLabel_->setVisible(true);
    
    43 43
         charCodeLabel_->setText(
    
    44
    -        cmaps[charMapIndex].stringifyIndexShort(ctxt.charCode));
    
    44
    +        cMaps[charMapIndex].stringifyIndexShort(ctxt.charCode));
    
    45 45
       }
    
    46 46
     
    
    47 47
       auto glyphName = engine_->glyphName(ctxt.glyphIndex);
    

  • src/ftinspect/panels/settingpanel.cpp
    ... ... @@ -2,11 +2,16 @@
    2 2
     
    
    3 3
     // Copyright (C) 2022 by Charlie Jiang.
    
    4 4
     
    
    5
    -
    
    6 5
     #include "settingpanel.hpp"
    
    7 6
     
    
    8
    -SettingPanel::SettingPanel(QWidget* parent, Engine* engine)
    
    9
    -: QWidget(parent), engine_(engine)
    
    7
    +#include "../uihelper.hpp"
    
    8
    +
    
    9
    +SettingPanel::SettingPanel(QWidget* parent,
    
    10
    +                           Engine* engine,
    
    11
    +                           bool comparatorMode)
    
    12
    +: QWidget(parent),
    
    13
    +  engine_(engine),
    
    14
    +  comparatorMode_(comparatorMode)
    
    10 15
     {
    
    11 16
       createLayout();
    
    12 17
       setDefaults();
    
    ... ... @@ -22,6 +27,20 @@ SettingPanel::antiAliasingModeIndex()
    22 27
     }
    
    23 28
     
    
    24 29
     
    
    30
    +bool
    
    31
    +SettingPanel::kerningEnabled()
    
    32
    +{
    
    33
    +  return kerningCheckBox_->isChecked();
    
    34
    +}
    
    35
    +
    
    36
    +
    
    37
    +bool
    
    38
    +SettingPanel::lsbRsbDeltaEnabled()
    
    39
    +{
    
    40
    +  return lsbRsbDeltaCheckBox_->isChecked();
    
    41
    +}
    
    42
    +
    
    43
    +
    
    25 44
     void
    
    26 45
     SettingPanel::checkAllSettings()
    
    27 46
     {
    
    ... ... @@ -34,6 +53,7 @@ SettingPanel::checkAllSettings()
    34 53
     void
    
    35 54
     SettingPanel::onFontChanged()
    
    36 55
     {
    
    56
    +  auto blockState = blockSignals(signalsBlocked() || comparatorMode_);
    
    37 57
       if (hintingCheckBox_->isChecked())
    
    38 58
       {
    
    39 59
         if (engine_->currentFontType() == Engine::FontType_CFF)
    
    ... ... @@ -73,11 +93,12 @@ SettingPanel::onFontChanged()
    73 93
           == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    74 94
           antiAliasingComboBox_->setCurrentIndex(
    
    75 95
             AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    76
    -
    
    96
    +    
    
    77 97
         emit repaintNeeded();
    
    78 98
       }
    
    79 99
     
    
    80 100
       populatePalettes();
    
    101
    +  blockSignals(blockState);
    
    81 102
     }
    
    82 103
     
    
    83 104
     
    
    ... ... @@ -124,27 +145,38 @@ SettingPanel::populatePalettes()
    124 145
     
    
    125 146
     void
    
    126 147
     SettingPanel::checkHintingMode()
    
    148
    +{
    
    149
    +  if (!comparatorMode_)
    
    150
    +    applyHintingMode();
    
    151
    +
    
    152
    +  emit fontReloadNeeded();
    
    153
    +}
    
    154
    +
    
    155
    +
    
    156
    +void
    
    157
    +SettingPanel::applyHintingMode()
    
    127 158
     {
    
    128 159
       // This must not be combined into `syncSettings`:
    
    129 160
       // those engine manipulations will reset the whole cache!!
    
    130 161
       // Therefore must only be called when the selection of the combo box actually
    
    131 162
       // changes a.k.a. QComboBox::activate.
    
    163
    +
    
    132 164
       int index = hintingModeComboBox_->currentIndex();
    
    133 165
     
    
    134 166
       if (engine_->currentFontType() == Engine::FontType_CFF)
    
    135 167
       {
    
    136 168
         engine_->setCFFHintingMode(
    
    137
    -        hintingModeComboBoxModel_->indexToCFFMode(index));
    
    138
    -    currentCFFHintingMode_ = index;
    
    169
    +      hintingModeComboBoxModel_->indexToCFFMode(index));
    
    170
    +    if (index >= 0)
    
    171
    +      currentCFFHintingMode_ = index;
    
    139 172
       }
    
    140 173
       else if (engine_->currentFontType() == Engine::FontType_TrueType)
    
    141 174
       {
    
    142 175
         engine_->setTTInterpreterVersion(
    
    143
    -        hintingModeComboBoxModel_->indexToTTInterpreterVersion(index));
    
    144
    -    currentTTInterpreterVersion_ = index;
    
    176
    +      hintingModeComboBoxModel_->indexToTTInterpreterVersion(index));
    
    177
    +    if (index >= 0)
    
    178
    +      currentTTInterpreterVersion_ = index;
    
    145 179
       }
    
    146
    -
    
    147
    -  emit fontReloadNeeded();
    
    148 180
     }
    
    149 181
     
    
    150 182
     
    
    ... ... @@ -179,10 +211,10 @@ SettingPanel::checkAutoHinting()
    179 211
     
    
    180 212
         antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
    
    181 213
     
    
    182
    -    if (antiAliasingComboBox_->currentIndex()
    
    183
    -        == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    214
    +    if (antiAliasingComboBox_->currentIndex() 
    
    215
    +      == AntiAliasingComboBoxModel::AntiAliasing_Light)
    
    184 216
           antiAliasingComboBox_->setCurrentIndex(
    
    185
    -          AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    217
    +        AntiAliasingComboBoxModel::AntiAliasing_Normal);
    
    186 218
       }
    
    187 219
       emit repaintNeeded();
    
    188 220
     }
    
    ... ... @@ -247,7 +279,7 @@ SettingPanel::syncSettings()
    247 279
       engine_->setLCDUsesBGR(aaSettings.isBGR);
    
    248 280
       engine_->setLCDSubPixelPositioning(
    
    249 281
         antiAliasingComboBox_->currentIndex()
    
    250
    -    == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel);
    
    282
    +      == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel);
    
    251 283
     }
    
    252 284
     
    
    253 285
     
    
    ... ... @@ -265,23 +297,26 @@ SettingPanel::createConnections()
    265 297
               QOverload<int>::of(&QComboBox::currentIndexChanged),
    
    266 298
               this, &SettingPanel::repaintNeeded);
    
    267 299
       connect(paletteComboBox_,
    
    268
    -          QOverload<int>::of(&QComboBox::currentIndexChanged), this,
    
    269
    -          &SettingPanel::repaintNeeded);
    
    300
    +          QOverload<int>::of(&QComboBox::currentIndexChanged), 
    
    301
    +          this, &SettingPanel::repaintNeeded);
    
    270 302
     
    
    271 303
       connect(gammaSlider_, &QSlider::valueChanged,
    
    272 304
               this, &SettingPanel::repaintNeeded);
    
    273 305
       
    
    274 306
       connect(hintingCheckBox_, &QCheckBox::clicked,
    
    275
    -          this, &SettingPanel::onFontChanged);
    
    276
    -
    
    277
    -  connect(horizontalHintingCheckBox_, &QCheckBox::clicked,
    
    278 307
               this, &SettingPanel::repaintNeeded);
    
    279
    -  connect(verticalHintingCheckBox_, &QCheckBox::clicked,
    
    280
    -          this, &SettingPanel::repaintNeeded);
    
    281
    -  connect(blueZoneHintingCheckBox_, &QCheckBox::clicked,
    
    308
    +
    
    309
    +  if (!comparatorMode_)
    
    310
    +  {
    
    311
    +    connect(horizontalHintingCheckBox_, &QCheckBox::clicked,
    
    282 312
               this, &SettingPanel::repaintNeeded);
    
    283
    -  connect(segmentDrawingCheckBox_, &QCheckBox::clicked,
    
    313
    +    connect(verticalHintingCheckBox_, &QCheckBox::clicked,
    
    314
    +            this, &SettingPanel::repaintNeeded);
    
    315
    +    connect(blueZoneHintingCheckBox_, &QCheckBox::clicked,
    
    316
    +            this, &SettingPanel::repaintNeeded);
    
    317
    +    connect(segmentDrawingCheckBox_, &QCheckBox::clicked,
    
    284 318
               this, &SettingPanel::repaintNeeded);
    
    319
    +  }
    
    285 320
     
    
    286 321
       connect(autoHintingCheckBox_, &QCheckBox::clicked,
    
    287 322
               this, &SettingPanel::checkAutoHinting);
    
    ... ... @@ -289,6 +324,14 @@ SettingPanel::createConnections()
    289 324
               this, &SettingPanel::fontReloadNeeded);
    
    290 325
       connect(colorLayerCheckBox_, &QCheckBox::clicked,
    
    291 326
               this, &SettingPanel::checkPalette);
    
    327
    +
    
    328
    +  if (comparatorMode_)
    
    329
    +  {
    
    330
    +    connect(kerningCheckBox_, &QCheckBox::clicked,
    
    331
    +            this, &SettingPanel::repaintNeeded);
    
    332
    +    connect(lsbRsbDeltaCheckBox_, &QCheckBox::clicked,
    
    333
    +            this, &SettingPanel::repaintNeeded);
    
    334
    +  }
    
    292 335
     }
    
    293 336
     
    
    294 337
     
    
    ... ... @@ -313,6 +356,12 @@ SettingPanel::createLayout()
    313 356
       embeddedBitmapCheckBox_ = new QCheckBox(tr("Enable Embedded Bitmap"), this);
    
    314 357
       colorLayerCheckBox_ = new QCheckBox(tr("Enable Color Layer"), this);
    
    315 358
     
    
    359
    +  if (comparatorMode_)
    
    360
    +  {
    
    361
    +    kerningCheckBox_ = new QCheckBox(tr("Kerning"), this);
    
    362
    +    lsbRsbDeltaCheckBox_ = new QCheckBox(tr("LSB/RSB Delta"), this);
    
    363
    +  }
    
    364
    +
    
    316 365
       antiAliasingLabel_ = new QLabel(tr("Anti-Aliasing"), this);
    
    317 366
       antiAliasingLabel_->setAlignment(Qt::AlignRight);
    
    318 367
     
    
    ... ... @@ -360,77 +409,82 @@ SettingPanel::createLayout()
    360 409
       gammaSlider_->setTickInterval(5);
    
    361 410
       gammaLabel_->setBuddy(gammaSlider_);
    
    362 411
     
    
    363
    -  hintingModeLayout_ = new QHBoxLayout;
    
    364
    -  hintingModeLayout_->addWidget(hintingModeLabel_);
    
    365
    -  hintingModeLayout_->addWidget(hintingModeComboBox_);
    
    412
    +  debugLayout_ = new QVBoxLayout;
    
    413
    +  debugLayout_->setContentsMargins(20, 0, 0, 0);
    
    414
    +  debugLayout_->addWidget(horizontalHintingCheckBox_);
    
    415
    +  debugLayout_->addWidget(verticalHintingCheckBox_);
    
    416
    +  debugLayout_->addWidget(blueZoneHintingCheckBox_);
    
    417
    +  debugLayout_->addWidget(segmentDrawingCheckBox_);
    
    366 418
     
    
    367
    -  horizontalHintingLayout_ = new QHBoxLayout;
    
    368
    -  horizontalHintingLayout_->addSpacing(20); // XXX px
    
    369
    -  horizontalHintingLayout_->addWidget(horizontalHintingCheckBox_);
    
    419
    +  gammaLayout_ = new QHBoxLayout;
    
    420
    +  gammaLayout_->addWidget(gammaLabel_);
    
    421
    +  gammaLayout_->addWidget(gammaSlider_);
    
    370 422
     
    
    371
    -  verticalHintingLayout_ = new QHBoxLayout;
    
    372
    -  verticalHintingLayout_->addSpacing(20); // XXX px
    
    373
    -  verticalHintingLayout_->addWidget(verticalHintingCheckBox_);
    
    423
    +  generalTabLayout_ = new QGridLayout;
    
    374 424
     
    
    375
    -  blueZoneHintingLayout_ = new QHBoxLayout;
    
    376
    -  blueZoneHintingLayout_->addSpacing(20); // XXX px
    
    377
    -  blueZoneHintingLayout_->addWidget(blueZoneHintingCheckBox_);
    
    425
    +  gridLayout2ColAddWidget(generalTabLayout_, hintingCheckBox_);
    
    426
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    427
    +                          hintingModeLabel_, hintingModeComboBox_);
    
    428
    +  gridLayout2ColAddWidget(generalTabLayout_, autoHintingCheckBox_);
    
    378 429
     
    
    379
    -  segmentDrawingLayout_ = new QHBoxLayout;
    
    380
    -  segmentDrawingLayout_->addSpacing(20); // XXX px
    
    381
    -  segmentDrawingLayout_->addWidget(segmentDrawingCheckBox_);
    
    430
    +  if (!comparatorMode_)
    
    431
    +    gridLayout2ColAddLayout(generalTabLayout_, debugLayout_);
    
    382 432
     
    
    383
    -  antiAliasingLayout_ = new QHBoxLayout;
    
    384
    -  antiAliasingLayout_->addWidget(antiAliasingLabel_);
    
    385
    -  antiAliasingLayout_->addWidget(antiAliasingComboBox_);
    
    433
    +  if (!comparatorMode_)
    
    434
    +    gridLayout2ColAddItem(generalTabLayout_,
    
    435
    +                          new QSpacerItem(0, 20, QSizePolicy::Minimum,
    
    436
    +                                          QSizePolicy::MinimumExpanding));
    
    386 437
     
    
    387
    -  lcdFilterLayout_ = new QHBoxLayout;
    
    388
    -  lcdFilterLayout_->addWidget(lcdFilterLabel_);
    
    389
    -  lcdFilterLayout_->addWidget(lcdFilterComboBox_);
    
    438
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    439
    +                          antiAliasingLabel_, antiAliasingComboBox_);
    
    440
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    441
    +                          lcdFilterLabel_, lcdFilterComboBox_);
    
    390 442
     
    
    391
    -  gammaLayout_ = new QHBoxLayout;
    
    392
    -  gammaLayout_->addWidget(gammaLabel_);
    
    393
    -  gammaLayout_->addWidget(gammaSlider_);
    
    443
    +  if (!comparatorMode_)
    
    444
    +    gridLayout2ColAddItem(generalTabLayout_,
    
    445
    +                          new QSpacerItem(0, 20, QSizePolicy::Minimum,
    
    446
    +                                          QSizePolicy::MinimumExpanding));
    
    447
    +
    
    448
    +  gridLayout2ColAddLayout(generalTabLayout_, gammaLayout_);
    
    449
    +  gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
    
    450
    +  gridLayout2ColAddWidget(generalTabLayout_, colorLayerCheckBox_);
    
    451
    +  gridLayout2ColAddWidget(generalTabLayout_, 
    
    452
    +                          paletteLabel_, paletteComboBox_);
    
    453
    +
    
    454
    +  if (comparatorMode_)
    
    455
    +  {
    
    456
    +    gridLayout2ColAddWidget(generalTabLayout_, kerningCheckBox_);
    
    457
    +    gridLayout2ColAddWidget(generalTabLayout_, lsbRsbDeltaCheckBox_);
    
    458
    +  }
    
    459
    +
    
    460
    +  if (!comparatorMode_)
    
    461
    +    gridLayout2ColAddItem(generalTabLayout_,
    
    462
    +                          new QSpacerItem(0, 20, QSizePolicy::Minimum,
    
    463
    +                                          QSizePolicy::MinimumExpanding));
    
    394 464
     
    
    395
    -  paletteLayout_ = new QHBoxLayout;
    
    396
    -  paletteLayout_->addWidget(paletteLabel_);
    
    397
    -  paletteLayout_->addWidget(paletteComboBox_);
    
    398
    -
    
    399
    -  generalTabLayout_ = new QVBoxLayout;
    
    400
    -  generalTabLayout_->addWidget(hintingCheckBox_);
    
    401
    -  generalTabLayout_->addLayout(hintingModeLayout_);
    
    402
    -  generalTabLayout_->addWidget(autoHintingCheckBox_);
    
    403
    -  generalTabLayout_->addLayout(horizontalHintingLayout_);
    
    404
    -  generalTabLayout_->addLayout(verticalHintingLayout_);
    
    405
    -  generalTabLayout_->addLayout(blueZoneHintingLayout_);
    
    406
    -  generalTabLayout_->addLayout(segmentDrawingLayout_);
    
    407
    -  generalTabLayout_->addSpacing(20); // XXX px
    
    408
    -  generalTabLayout_->addStretch(1);
    
    409
    -  generalTabLayout_->addLayout(antiAliasingLayout_);
    
    410
    -  generalTabLayout_->addLayout(lcdFilterLayout_);
    
    411
    -  generalTabLayout_->addSpacing(20); // XXX px
    
    412
    -  generalTabLayout_->addStretch(1);
    
    413
    -  generalTabLayout_->addLayout(gammaLayout_);
    
    414
    -  generalTabLayout_->addWidget(embeddedBitmapCheckBox_);
    
    415
    -  generalTabLayout_->addWidget(colorLayerCheckBox_);
    
    416
    -  generalTabLayout_->addLayout(paletteLayout_);
    
    417
    -  generalTabLayout_->addSpacing(20); // XXX px
    
    418
    -  generalTabLayout_->addStretch(1);
    
    465
    +  generalTabLayout_->setColumnStretch(1, 1);
    
    419 466
     
    
    420 467
       generalTab_ = new QWidget(this);
    
    421 468
       generalTab_->setLayout(generalTabLayout_);
    
    469
    +  generalTab_->setSizePolicy(QSizePolicy::MinimumExpanding,
    
    470
    +                             QSizePolicy::MinimumExpanding);
    
    422 471
     
    
    423 472
       mmgxTab_ = new QWidget(this);
    
    424 473
     
    
    425 474
       tab_ = new QTabWidget(this);
    
    426 475
       tab_->addTab(generalTab_, tr("General"));
    
    427 476
       tab_->addTab(mmgxTab_, tr("MM/GX"));
    
    477
    +  tab_->setSizePolicy(QSizePolicy::MinimumExpanding,
    
    478
    +                      QSizePolicy::MinimumExpanding);
    
    428 479
     
    
    429 480
       mainLayout_ = new QVBoxLayout;
    
    430 481
       mainLayout_->addWidget(tab_);
    
    431 482
       setLayout(mainLayout_);
    
    432 483
       mainLayout_->setContentsMargins(0, 0, 0, 0);
    
    433 484
       setContentsMargins(0, 0, 0, 0);
    
    485
    +
    
    486
    +  if (comparatorMode_)
    
    487
    +    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
    
    434 488
     }
    
    435 489
     
    
    436 490
     
    
    ... ... @@ -466,6 +520,12 @@ SettingPanel::setDefaults()
    466 520
       embeddedBitmapCheckBox_->setChecked(false);
    
    467 521
       colorLayerCheckBox_->setChecked(true);
    
    468 522
     
    
    523
    +  if (comparatorMode_)
    
    524
    +  {
    
    525
    +    kerningCheckBox_->setChecked(true);
    
    526
    +    lsbRsbDeltaCheckBox_->setChecked(true);
    
    527
    +  }
    
    528
    +
    
    469 529
       gammaSlider_->setValue(18); // 1.8
    
    470 530
     }
    
    471 531
     
    

  • src/ftinspect/panels/settingpanel.hpp
    ... ... @@ -12,6 +12,7 @@
    12 12
     #include <QLabel>
    
    13 13
     #include <QComboBox>
    
    14 14
     #include <QCheckBox>
    
    15
    +#include <QGridLayout>
    
    15 16
     #include <QBoxLayout>
    
    16 17
     
    
    17 18
     class SettingPanel
    
    ... ... @@ -19,14 +20,21 @@ class SettingPanel
    19 20
     {
    
    20 21
       Q_OBJECT
    
    21 22
     public:
    
    22
    -  SettingPanel(QWidget* parent, Engine* engine);
    
    23
    +  SettingPanel(QWidget* parent, Engine* engine, bool comparatorMode = false);
    
    23 24
       ~SettingPanel() override = default;
    
    24 25
     
    
    25 26
       void syncSettings();
    
    27
    +  /*
    
    28
    +   * When in comparator mode, this is needed to sync the hinting modes when
    
    29
    +   * reloading the font.
    
    30
    +   */
    
    31
    +  void applyHintingMode();
    
    26 32
     
    
    27 33
       //////// Getters/Setters
    
    28 34
     
    
    29 35
       int antiAliasingModeIndex();
    
    36
    +  bool kerningEnabled();
    
    37
    +  bool lsbRsbDeltaEnabled();
    
    30 38
     
    
    31 39
     signals:
    
    32 40
       void fontReloadNeeded();
    
    ... ... @@ -48,6 +56,18 @@ private:
    48 56
       int currentCFFHintingMode_;
    
    49 57
       int currentTTInterpreterVersion_;
    
    50 58
     
    
    59
    +  /*
    
    60
    +   * There's two places where `SettingPanel` appears: On the left for most tabs,
    
    61
    +   * and on the bottom in the comparator for each column. Therefore,
    
    62
    +   * set `comparatorMode_` to `true` will change the panel for the Comparator
    
    63
    +   * View.
    
    64
    +   *
    
    65
    +   * In comparator view, some updating is suppressed during GUI events.
    
    66
    +   * Instead, updating was strictly passive called from the parent (comparator
    
    67
    +   * view).
    
    68
    +   */
    
    69
    +  bool comparatorMode_ = false;
    
    70
    +
    
    51 71
       QTabWidget* tab_;
    
    52 72
     
    
    53 73
       QWidget* generalTab_;
    
    ... ... @@ -67,6 +87,8 @@ private:
    67 87
       QCheckBox* autoHintingCheckBox_;
    
    68 88
       QCheckBox* embeddedBitmapCheckBox_;
    
    69 89
       QCheckBox* colorLayerCheckBox_;
    
    90
    +  QCheckBox* kerningCheckBox_;
    
    91
    +  QCheckBox* lsbRsbDeltaCheckBox_;
    
    70 92
     
    
    71 93
       AntiAliasingComboBoxModel* antiAliasingComboBoxModel_;
    
    72 94
       HintingModeComboBoxModel* hintingModeComboBoxModel_;
    
    ... ... @@ -80,17 +102,9 @@ private:
    80 102
       QSlider* gammaSlider_;
    
    81 103
     
    
    82 104
       QVBoxLayout* mainLayout_;
    
    83
    -  QHBoxLayout* hintingModeLayout_;
    
    84
    -  QHBoxLayout* horizontalHintingLayout_;
    
    85
    -  QHBoxLayout* verticalHintingLayout_;
    
    86
    -  QHBoxLayout* blueZoneHintingLayout_;
    
    87
    -  QHBoxLayout* segmentDrawingLayout_;
    
    88
    -  QHBoxLayout* antiAliasingLayout_;
    
    89
    -  QHBoxLayout* lcdFilterLayout_;
    
    105
    +  QGridLayout* generalTabLayout_;
    
    106
    +  QVBoxLayout* debugLayout_;
    
    90 107
       QHBoxLayout* gammaLayout_;
    
    91
    -  QHBoxLayout* paletteLayout_;
    
    92
    -
    
    93
    -  QVBoxLayout* generalTabLayout_;
    
    94 108
     
    
    95 109
       //////// Initializing funcs
    
    96 110
     
    

  • src/ftinspect/panels/singular.cpp
    ... ... @@ -33,10 +33,10 @@ void
    33 33
     SingularTab::setGlyphIndex(int index)
    
    34 34
     {
    
    35 35
       // only adjust current glyph index if we have a valid font
    
    36
    -  if (currentGlyphCount_ > 0)
    
    37
    -  {
    
    38
    -    currentGlyphIndex_ = qBound(0, index, currentGlyphCount_ - 1);
    
    39
    -  }
    
    36
    +  if (currentGlyphCount_ <= 0)
    
    37
    +    return;
    
    38
    +
    
    39
    +  currentGlyphIndex_ = qBound(0, index, currentGlyphCount_ - 1);
    
    40 40
     
    
    41 41
       QString upperHex = QString::number(currentGlyphIndex_, 16).toUpper();
    
    42 42
       glyphIndexLabel_->setText(
    

  • src/ftinspect/rendering/glyphbitmap.cpp
    ... ... @@ -67,7 +67,7 @@ GlyphBitmap::paint(QPainter* painter,
    67 67
                            QImage::Format_ARGB32_Premultiplied));
    
    68 68
     #else
    
    69 69
       const qreal lod = QStyleOptionGraphicsItem::levelOfDetailFromTransform(
    
    70
    -      painter->worldTransform());
    
    70
    +    painter->worldTransform());
    
    71 71
     
    
    72 72
       painter->setPen(Qt::NoPen);
    
    73 73
     
    
    ... ... @@ -141,6 +141,10 @@ GlyphBitmapWidget::paintEvent(QPaintEvent* event)
    141 141
       auto scale = std::min(xScale, yScale);
    
    142 142
     
    
    143 143
       QPainter painter(this);
    
    144
    +  painter.fillRect(rect(), Qt::white);
    
    145
    +  painter.setPen(QPen(Qt::black, 4));
    
    146
    +  painter.drawRect(rect());
    
    147
    +
    
    144 148
       painter.scale(scale, scale);
    
    145 149
     
    
    146 150
       QStyleOptionGraphicsItem ogi;
    

  • src/ftinspect/rendering/glyphcontinuous.cpp
    ... ... @@ -108,15 +108,12 @@ GlyphContinuous::resetPositionDelta()
    108 108
     void
    
    109 109
     GlyphContinuous::paintEvent(QPaintEvent* event)
    
    110 110
     {
    
    111
    -  QPainter painter;
    
    112
    -  painter.begin(this);
    
    111
    +  QPainter painter(this);
    
    113 112
       painter.fillRect(rect(), Qt::white);
    
    114 113
     
    
    115 114
       if (glyphCache_.empty())
    
    116 115
         fillCache();
    
    117 116
       paintCache(&painter);
    
    118
    -
    
    119
    -  painter.end();
    
    120 117
     }
    
    121 118
     
    
    122 119
     
    
    ... ... @@ -143,6 +140,8 @@ void
    143 140
     GlyphContinuous::mousePressEvent(QMouseEvent* event)
    
    144 141
     {
    
    145 142
       QWidget::mousePressEvent(event);
    
    143
    +  if (!mouseOperationEnabled_)
    
    144
    +    return;
    
    146 145
       if (event->button() == Qt::LeftButton)
    
    147 146
       {
    
    148 147
         prevPositionDelta_ = positionDelta_;
    
    ... ... @@ -162,13 +161,15 @@ void
    162 161
     GlyphContinuous::mouseMoveEvent(QMouseEvent* event)
    
    163 162
     {
    
    164 163
       QWidget::mouseMoveEvent(event);
    
    164
    +  if (!mouseOperationEnabled_)
    
    165
    +    return;
    
    165 166
       if (event->buttons() != Qt::LeftButton)
    
    166 167
         return;
    
    167 168
       auto delta = event->pos() - mouseDownPostition_;
    
    168 169
       if (source_ == SRC_AllGlyphs)
    
    169 170
       {
    
    170 171
         auto deltaIndex = -delta.x() / HorizontalUnitLength
    
    171
    -                        - delta.y() / VerticalUnitLength * averageLineCount_;
    
    172
    +                          - delta.y() / VerticalUnitLength * averageLineCount_;
    
    172 173
         if (prevIndex_ + deltaIndex != beginIndex_)
    
    173 174
           emit beginIndexChangeRequest(beginIndex_ + deltaIndex);
    
    174 175
       }
    
    ... ... @@ -193,6 +194,8 @@ void
    193 194
     GlyphContinuous::mouseReleaseEvent(QMouseEvent* event)
    
    194 195
     {
    
    195 196
       QWidget::mouseReleaseEvent(event);
    
    197
    +  if (!mouseOperationEnabled_)
    
    198
    +    return;
    
    196 199
       if (event->button() == Qt::LeftButton)
    
    197 200
       {
    
    198 201
         auto dist = event->pos() - mouseDownPostition_;
    

  • src/ftinspect/rendering/glyphcontinuous.hpp
    ... ... @@ -85,6 +85,10 @@ public:
    85 85
       }
    
    86 86
       void setStrokeRadius(double radius) { strokeRadius_ = radius; }
    
    87 87
       void setSourceText(QString text);
    
    88
    +  void setMouseOperationEnabled(bool enabled)
    
    89
    +  {
    
    90
    +    mouseOperationEnabled_ = enabled;
    
    91
    +  }
    
    88 92
     
    
    89 93
       void purgeCache();
    
    90 94
       void resetPositionDelta();
    
    ... ... @@ -117,6 +121,7 @@ private:
    117 121
       QString text_;
    
    118 122
       int sizeIndicatorOffset_ = 0; // For Waterfall Rendering...
    
    119 123
     
    
    124
    +  bool mouseOperationEnabled_ = true;
    
    120 125
       int displayingCount_ = 0;
    
    121 126
       FT_Size_Metrics metrics_;
    
    122 127
       int x_ = 0, y_ = 0;
    

  • src/ftinspect/uihelper.cpp
    ... ... @@ -36,4 +36,38 @@ setLabelSelectable(QLabel* label)
    36 36
     }
    
    37 37
     
    
    38 38
     
    
    39
    +void
    
    40
    +gridLayout2ColAddLayout(QGridLayout* layout,
    
    41
    +                        QLayout* layoutSingle)
    
    42
    +{
    
    43
    +  layout->addLayout(layoutSingle, layout->rowCount(), 0, 1, 2);
    
    44
    +}
    
    45
    +
    
    46
    +
    
    47
    +void
    
    48
    +gridLayout2ColAddWidget(QGridLayout* layout,
    
    49
    +                        QWidget* widgetSingle)
    
    50
    +{
    
    51
    +  layout->addWidget(widgetSingle, layout->rowCount(), 0, 1, 2);
    
    52
    +}
    
    53
    +
    
    54
    +
    
    55
    +void
    
    56
    +gridLayout2ColAddWidget(QGridLayout* layout,
    
    57
    +                        QWidget* widgetL, QWidget* widgetR)
    
    58
    +{
    
    59
    +  auto r = layout->rowCount();
    
    60
    +  layout->addWidget(widgetL, r, 0);
    
    61
    +  layout->addWidget(widgetR, r, 1);
    
    62
    +}
    
    63
    +
    
    64
    +
    
    65
    +void
    
    66
    +gridLayout2ColAddItem(QGridLayout* layout,
    
    67
    +                      QLayoutItem* item)
    
    68
    +{
    
    69
    +  layout->addItem(item, layout->rowCount(), 0, 1, 2);
    
    70
    +}
    
    71
    +
    
    72
    +
    
    39 73
     // end of uihelper.cpp

  • src/ftinspect/uihelper.hpp
    ... ... @@ -6,10 +6,18 @@
    6 6
     
    
    7 7
     #include <QPushButton>
    
    8 8
     #include <QLabel>
    
    9
    +#include <QLayoutItem>
    
    10
    +#include <QWidget>
    
    11
    +#include <QGridLayout>
    
    9 12
     
    
    10 13
     // we want buttons that are horizontally as small as possible
    
    11 14
     void setButtonNarrowest(QPushButton* btn);
    
    12 15
     void setLabelSelectable(QLabel* label);
    
    16
    +void gridLayout2ColAddLayout(QGridLayout* layout, QLayout* layoutSingle);
    
    17
    +void gridLayout2ColAddWidget(QGridLayout* layout, QWidget* widgetSingle);
    
    18
    +void gridLayout2ColAddWidget(QGridLayout* layout, 
    
    19
    +                             QWidget* widgetL, QWidget* widgetR);
    
    20
    +void gridLayout2ColAddItem(QGridLayout* layout, QLayoutItem* item);
    
    13 21
     
    
    14 22
     
    
    15 23
     // end of uihelper.hpp

  • src/ftinspect/widgets/charmapcombobox.cpp
    1
    +// charmapcombobox.cpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#include "charmapcombobox.hpp"
    
    6
    +
    
    7
    +#include "../engine/engine.hpp"
    
    8
    +
    
    9
    +
    
    10
    +CharMapComboBox::CharMapComboBox(QWidget* parent,
    
    11
    +                                 Engine* engine,
    
    12
    +                                 bool haveGlyphOrder)
    
    13
    +: QComboBox(parent),
    
    14
    +  engine_(engine),
    
    15
    +  haveGlyphOrder_(haveGlyphOrder)
    
    16
    +{
    
    17
    +}
    
    18
    +
    
    19
    +
    
    20
    +CharMapComboBox::~CharMapComboBox()
    
    21
    +{
    
    22
    +  
    
    23
    +}
    
    24
    +
    
    25
    +
    
    26
    +int
    
    27
    +CharMapComboBox::currentCharMapIndex()
    
    28
    +{
    
    29
    +  auto index = haveGlyphOrder_ ? currentIndex() - 1 : currentIndex();
    
    30
    +  if (index < 0 || charMaps_.size() <= static_cast<unsigned>(index))
    
    31
    +    return -1;
    
    32
    +  return index;
    
    33
    +}
    
    34
    +
    
    35
    +
    
    36
    +int
    
    37
    +CharMapComboBox::defaultFirstGlyphIndex()
    
    38
    +{
    
    39
    +  auto newIndex = currentCharMapIndex();
    
    40
    +  if (newIndex < 0)
    
    41
    +    return 0;
    
    42
    +  if (charMaps_[newIndex].maxIndex <= 20)
    
    43
    +    return charMaps_[newIndex].maxIndex - 1;
    
    44
    +  return 0x20;
    
    45
    +}
    
    46
    +
    
    47
    +
    
    48
    +void
    
    49
    +CharMapComboBox::repopulate()
    
    50
    +{
    
    51
    +  repopulate(engine_->currentFontCharMaps());
    
    52
    +}
    
    53
    +
    
    54
    +
    
    55
    +#define EncodingRole (Qt::UserRole + 10)
    
    56
    +void
    
    57
    +CharMapComboBox::repopulate(std::vector<CharMapInfo>& charMaps)
    
    58
    +{
    
    59
    +  if (charMaps_ == charMaps)
    
    60
    +  {
    
    61
    +    charMaps_ = charMaps; // Still need to substitute because ptr may differ
    
    62
    +    return;
    
    63
    +  }
    
    64
    +  charMaps_ = charMaps;
    
    65
    +  int oldIndex = currentIndex();
    
    66
    +  unsigned oldEncoding = 0u;
    
    67
    +
    
    68
    +  // Using additional UserRole to store encoding id
    
    69
    +  auto oldEncodingV = itemData(oldIndex, EncodingRole);
    
    70
    +  if (oldEncodingV.isValid() && oldEncodingV.canConvert<unsigned>())
    
    71
    +    oldEncoding = oldEncodingV.value<unsigned>();
    
    72
    +
    
    73
    +  {
    
    74
    +    // suppress events during updating
    
    75
    +    QSignalBlocker selectorBlocker(this);
    
    76
    +
    
    77
    +    clear();
    
    78
    +    if (haveGlyphOrder_)
    
    79
    +    {
    
    80
    +      addItem(tr("Glyph Order"));
    
    81
    +      setItemData(0, 0u, EncodingRole);
    
    82
    +    }
    
    83
    +
    
    84
    +    int i = 0;
    
    85
    +    int newIndex = 0;
    
    86
    +    for (auto& map : charMaps)
    
    87
    +    {
    
    88
    +      addItem(tr("%1: %2 (platform %3, encoding %4)")
    
    89
    +                .arg(i)
    
    90
    +                .arg(*map.encodingName)
    
    91
    +                .arg(map.platformID)
    
    92
    +                .arg(map.encodingID));
    
    93
    +      auto encoding = static_cast<unsigned>(map.encoding);
    
    94
    +      setItemData(haveGlyphOrder_ ? i + 1 : i, encoding, EncodingRole);
    
    95
    +
    
    96
    +      if (encoding == oldEncoding && i == oldIndex)
    
    97
    +        newIndex = i;
    
    98
    +    
    
    99
    +      i++;
    
    100
    +    }
    
    101
    +
    
    102
    +    // this shouldn't emit any event either, because force repainting
    
    103
    +    // will happen later, so embrace it into blocker block
    
    104
    +    setCurrentIndex(newIndex);
    
    105
    +  }
    
    106
    +
    
    107
    +  emit forceUpdateLimitIndex();
    
    108
    +}
    
    109
    +
    
    110
    +
    
    111
    +// end of charmapcombobox.cpp

  • src/ftinspect/widgets/charmapcombobox.hpp
    1
    +// charmapcombobox.hpp
    
    2
    +
    
    3
    +// Copyright (C) 2022 by Charlie Jiang.
    
    4
    +
    
    5
    +#pragma once
    
    6
    +
    
    7
    +#include "../engine/charmap.hpp"
    
    8
    +
    
    9
    +#include <vector>
    
    10
    +#include <QComboBox>
    
    11
    +
    
    12
    +class Engine;
    
    13
    +class CharMapComboBox
    
    14
    +: public QComboBox
    
    15
    +{
    
    16
    +  Q_OBJECT
    
    17
    +public:
    
    18
    +  CharMapComboBox(QWidget* parent, Engine* engine, bool haveGlyphOrder = true);
    
    19
    +  ~CharMapComboBox() override;
    
    20
    +
    
    21
    +  bool haveGlyphOrder_;
    
    22
    +
    
    23
    +  std::vector<CharMapInfo>& charMaps() { return charMaps_; }
    
    24
    +  int currentCharMapIndex();
    
    25
    +  int defaultFirstGlyphIndex();
    
    26
    +  void repopulate();
    
    27
    +  void repopulate(std::vector<CharMapInfo>& charMaps);
    
    28
    +
    
    29
    +signals:
    
    30
    +  void forceUpdateLimitIndex();
    
    31
    +
    
    32
    +private:
    
    33
    +  Engine* engine_;
    
    34
    +  std::vector<CharMapInfo> charMaps_;
    
    35
    +};
    
    36
    +
    
    37
    +
    
    38
    +// charmapcombobox.hpp

  • src/ftinspect/widgets/customwidgets.cpp
    ... ... @@ -148,4 +148,32 @@ ZoomSpinBox::stepBy(int steps)
    148 148
     }
    
    149 149
     
    
    150 150
     
    
    151
    +UnboundScrollArea::UnboundScrollArea(QWidget* parent)
    
    152
    +: QScrollArea(parent)
    
    153
    +{
    
    154
    +}
    
    155
    +
    
    156
    +
    
    157
    +QSize
    
    158
    +UnboundScrollArea::sizeHint() const
    
    159
    +{
    
    160
    +  int fw = 2 * frameWidth();
    
    161
    +  QSize sz(fw, fw);
    
    162
    +
    
    163
    +  int h = fontMetrics().height();
    
    164
    +
    
    165
    +  auto w = widget();
    
    166
    +  if (w)
    
    167
    +    sz += widgetResizable() ? w->sizeHint() : w->size();
    
    168
    +  else
    
    169
    +    sz += QSize(12 * h, 8 * h);
    
    170
    +
    
    171
    +  if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
    
    172
    +    sz.setWidth(sz.width() + verticalScrollBar()->sizeHint().width());
    
    173
    +  if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
    
    174
    +    sz.setHeight(sz.height() + horizontalScrollBar()->sizeHint().height());
    
    175
    +  return sz;
    
    176
    +}
    
    177
    +
    
    178
    +
    
    151 179
     // end of custom_widgets.cpp

  • src/ftinspect/widgets/customwidgets.hpp
    ... ... @@ -8,6 +8,7 @@
    8 8
     #include <QGraphicsView>
    
    9 9
     #include <QPushButton>
    
    10 10
     #include <QSpinBox>
    
    11
    +#include <QScrollArea>
    
    11 12
     #include <QString>
    
    12 13
     
    
    13 14
     // We need to define a series of custom Qt widgets to satisfy.
    
    ... ... @@ -55,4 +56,17 @@ public:
    55 56
     };
    
    56 57
     
    
    57 58
     
    
    59
    +// https://bugreports.qt.io/browse/QTBUG-10459
    
    60
    +// https://phabricator.kde.org/D14692
    
    61
    +class UnboundScrollArea
    
    62
    +: public QScrollArea
    
    63
    +{
    
    64
    +  Q_OBJECT
    
    65
    +
    
    66
    +public:
    
    67
    +  UnboundScrollArea(QWidget* parent);
    
    68
    +  QSize sizeHint() const override;
    
    69
    +};
    
    70
    +
    
    71
    +
    
    58 72
     // end of custom_widgets.hpp


  • reply via email to

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