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