Commits:
-
06ee1f8d
by Charlie Jiang
at 2022-08-09T21:57:46+08:00
[ftinspect] Add stem darkening.
Stem darkening should only work when auto-hinting is on and is in light
mode.
* src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
Add `setStemDarkening` function to apply the setting to the engine.
* src/ftinspect/panels/settingpanel.cpp,
src/ftinspect/panels/settingpanel.hpp:
Add necessary controls and rename `applyHintingMode` to
`applyDelayedSettings`.
* src/ftinspect/panels/comparator.cpp: Rename func.
-
a34c63d4
by Charlie Jiang
at 2022-08-09T22:17:03+08:00
[ftinspect] Improve enabling and disabling of options.
* src/ftinspect/panels/settingpanel.cpp: As described. Stem darkening will
only be enabled when possible (auto-hinting and light AA mode).
-
03beb1a0
by Charlie Jiang
at 2022-08-09T23:28:08+08:00
[ftinspect] Add customization for waterfall start and step size.
Also fixed the UI helper's grid layout helper functions.
* src/ftinspect/engine/stringrenderer.cpp,
src/ftinspect/engine/stringrenderer.hpp:
Add waterfall start and step properties and honor then when rendering.
* src/ftinspect/panels/continuous.cpp, src/ftinspect/panels/continuous.hpp:
Add `WaterfallConfigDialog` and open it when clicking the "WF Config"
button.
* src/ftinspect/uihelper.cpp, src/ftinspect/uihelper.hpp:
Since the `QGridLayout::rowCount` returns the count of internal allocated
rows, not the actual occuplied row count, so we have to keep every row's
index for later customization and can't use any hardcoded row index.
* src/ftinspect/panels/glyphdetails.cpp: Accompanying changes to the helper.
-
66f00589
by Charlie Jiang
at 2022-08-10T00:34:35+08:00
[ftinspect] Add auxiliary lines to the singular line.
Now aux lines indicating advance width, ascender and descender are
displayed. The logic rendering those lines are put into `Grid`.
* src/ftinspect/rendering/grid.cpp, src/ftinspect/rendering/grid.hpp:
Add logic to render the aux lines and properties to hold values.
Now the visibility of the grid and aux lines are controlled via
`showGrid_` and `showAuxLines_`, so the grid *QGraphicsItem* will stay
visible.
`Grid` no longer use pens passed from the ctor, but directly retrieve
pens from the `GraphicsDefault` struct.
* src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp:
Add `currentSizeAscDescPx` func to retrieve ascender and descender data..
* src/ftinspect/panels/singular.cpp, src/ftinspect/panels/singular.hpp:
Add checkbox to toggle aux lines on and on. Pass data to the `Grid` object
about the aux lines.
* src/ftinspect/rendering/graphicsdefault.cpp,
src/ftinspect/rendering/graphicsdefault.hpp:
Add `advanceAuxPen` and `ascDescAuxPen`.
18 changed files:
Changes:
src/ftinspect/engine/engine.cpp
... |
... |
@@ -456,6 +456,14 @@ Engine::currentFontKerning(int glyphIndex, |
456
|
456
|
}
|
457
|
457
|
|
458
|
458
|
|
|
459
|
+std::pair<int, int>
|
|
460
|
+Engine::currentSizeAscDescPx()
|
|
461
|
+{
|
|
462
|
+ return { ftSize_->metrics.ascender >> 6,
|
|
463
|
+ ftSize_->metrics.descender >> 6 };
|
|
464
|
+}
|
|
465
|
+
|
|
466
|
+
|
459
|
467
|
QString
|
460
|
468
|
Engine::glyphName(int index)
|
461
|
469
|
{
|
... |
... |
@@ -681,6 +689,33 @@ Engine::setTTInterpreterVersion(int version) |
681
|
689
|
}
|
682
|
690
|
|
683
|
691
|
|
|
692
|
+void
|
|
693
|
+Engine::setStemDarkening(bool darkening)
|
|
694
|
+{
|
|
695
|
+ // TODO not working
|
|
696
|
+ FT_Bool noDarkening = !darkening;
|
|
697
|
+ FT_Property_Set(library_,
|
|
698
|
+ "cff",
|
|
699
|
+ "no-stem-darkening",
|
|
700
|
+ &noDarkening);
|
|
701
|
+ FT_Property_Set(library_,
|
|
702
|
+ "autofitter",
|
|
703
|
+ "no-stem-darkening",
|
|
704
|
+ &noDarkening);
|
|
705
|
+ FT_Property_Set(library_,
|
|
706
|
+ "type1",
|
|
707
|
+ "no-stem-darkening",
|
|
708
|
+ &noDarkening);
|
|
709
|
+ FT_Property_Set(library_,
|
|
710
|
+ "t1cid",
|
|
711
|
+ "no-stem-darkening",
|
|
712
|
+ &noDarkening);
|
|
713
|
+ // reset the cache
|
|
714
|
+ FTC_Manager_Reset(cacheManager_);
|
|
715
|
+ ftSize_ = NULL;
|
|
716
|
+}
|
|
717
|
+
|
|
718
|
+
|
684
|
719
|
void
|
685
|
720
|
Engine::setForeground(QRgb foreground)
|
686
|
721
|
{
|
src/ftinspect/engine/engine.hpp
... |
... |
@@ -10,6 +10,7 @@ |
10
|
10
|
#include "paletteinfo.hpp"
|
11
|
11
|
|
12
|
12
|
#include <vector>
|
|
13
|
+#include <utility>
|
13
|
14
|
#include <QString>
|
14
|
15
|
#include <QMap>
|
15
|
16
|
#include <QRect>
|
... |
... |
@@ -146,6 +147,7 @@ public: |
146
|
147
|
FT_GlyphSlot currentFaceSlot();
|
147
|
148
|
FT_Pos currentFontTrackingKerning(int degree);
|
148
|
149
|
FT_Vector currentFontKerning(int glyphIndex, int prevIndex);
|
|
150
|
+ std::pair<int, int> currentSizeAscDescPx();
|
149
|
151
|
|
150
|
152
|
std::vector<CharMapInfo>& currentFontCharMaps() { return curCharMaps_; }
|
151
|
153
|
std::vector<PaletteInfo>& currentFontPalettes() { return curPaletteInfos_; }
|
... |
... |
@@ -194,6 +196,7 @@ public: |
194
|
196
|
void setLcdFilter(FT_LcdFilter filter);
|
195
|
197
|
void setCFFHintingMode(int mode);
|
196
|
198
|
void setTTInterpreterVersion(int version);
|
|
199
|
+ void setStemDarkening(bool darkening);
|
197
|
200
|
|
198
|
201
|
void setForeground(QRgb foreground);
|
199
|
202
|
void setBackground(QRgb background);
|
src/ftinspect/engine/stringrenderer.cpp
... |
... |
@@ -363,8 +363,17 @@ StringRenderer::render(int width, |
363
|
363
|
auto originalSize = static_cast<int>(engine_->pointSize() * 64);
|
364
|
364
|
auto ptSize = originalSize;
|
365
|
365
|
auto ptHeight = 64 * 72 * height / engine_->dpi();
|
366
|
|
- auto step = (ptSize * ptSize / ptHeight + 64) & ~63;
|
367
|
|
- ptSize = ptSize - step * (ptSize / step); // modulo
|
|
366
|
+ int step;
|
|
367
|
+
|
|
368
|
+ if (waterfallStep_ <= 0)
|
|
369
|
+ step = (originalSize * originalSize / ptHeight + 64) & ~63;
|
|
370
|
+ else
|
|
371
|
+ step = static_cast<int>(waterfallStep_ * 64.0) & ~31;
|
|
372
|
+
|
|
373
|
+ if (waterfallStart_ < 0)
|
|
374
|
+ ptSize = ptSize - step * (ptSize / step); // modulo
|
|
375
|
+ else
|
|
376
|
+ ptSize = static_cast<int>(waterfallStart_ * 64.0) & ~31;
|
368
|
377
|
|
369
|
378
|
int y = 0;
|
370
|
379
|
// no position param in "All Glyphs" mode
|
src/ftinspect/engine/stringrenderer.hpp
... |
... |
@@ -124,6 +124,11 @@ public: |
124
|
124
|
void setVertical(bool vertical) { vertical_ = vertical; }
|
125
|
125
|
void setRotation(double rotation);
|
126
|
126
|
void setWaterfall(bool waterfall) { waterfall_ = waterfall; }
|
|
127
|
+ void setWaterfallParameters(double start, double step)
|
|
128
|
+ {
|
|
129
|
+ waterfallStart_ = start;
|
|
130
|
+ waterfallStep_ = step;
|
|
131
|
+ }
|
127
|
132
|
void setPosition(double pos) { position_ = pos; }
|
128
|
133
|
void setLsbRsbDelta(bool enabled) { lsbRsbDeltaEnabled_ = enabled; }
|
129
|
134
|
void setKerning(bool kerning);
|
... |
... |
@@ -181,7 +186,6 @@ private: |
181
|
186
|
int charMapIndex_ = 0;
|
182
|
187
|
int limitIndex_ = 0;
|
183
|
188
|
bool usingString_ = false;
|
184
|
|
- bool waterfall_ = false;
|
185
|
189
|
bool repeated_ = false;
|
186
|
190
|
bool vertical_ = false;
|
187
|
191
|
double position_ = 0.5;
|
... |
... |
@@ -193,6 +197,10 @@ private: |
193
|
197
|
bool matrixEnabled_ = false;
|
194
|
198
|
bool lsbRsbDeltaEnabled_ = true;
|
195
|
199
|
|
|
200
|
+ bool waterfall_ = false;
|
|
201
|
+ double waterfallStart_ = -1;
|
|
202
|
+ double waterfallStep_ = -1; // -1 = Auto
|
|
203
|
+
|
196
|
204
|
RenderCallback renderCallback_;
|
197
|
205
|
RenderImageCallback renderImageCallback_;
|
198
|
206
|
PreprocessCallback glyphPreprocessCallback_;
|
src/ftinspect/panels/comparator.cpp
... |
... |
@@ -242,7 +242,7 @@ ComperatorTab::syncSettings(int index) |
242
|
242
|
return;
|
243
|
243
|
|
244
|
244
|
auto settingPanel = settingPanels_[index];
|
245
|
|
- settingPanel->applyHintingMode();
|
|
245
|
+ settingPanel->applyDelayedSettings();
|
246
|
246
|
settingPanel->syncSettings();
|
247
|
247
|
|
248
|
248
|
if (static_cast<unsigned>(index) >= canvas_.size())
|
src/ftinspect/panels/continuous.cpp
... |
... |
@@ -5,6 +5,7 @@ |
5
|
5
|
#include "continuous.hpp"
|
6
|
6
|
|
7
|
7
|
#include "glyphdetails.hpp"
|
|
8
|
+#include "../uihelper.hpp"
|
8
|
9
|
|
9
|
10
|
#include <climits>
|
10
|
11
|
#include <QVariant>
|
... |
... |
@@ -158,6 +159,8 @@ ContinuousTab::checkModeSource() |
158
|
159
|
waterfallCheckBox_->setEnabled(!vert);
|
159
|
160
|
}
|
160
|
161
|
|
|
162
|
+ waterfallConfigButton_->setEnabled(waterfallCheckBox_->isChecked());
|
|
163
|
+
|
161
|
164
|
repaintGlyph();
|
162
|
165
|
}
|
163
|
166
|
|
... |
... |
@@ -228,6 +231,20 @@ ContinuousTab::updateGlyphDetails(GlyphCacheEntry* ctxt, |
228
|
231
|
}
|
229
|
232
|
|
230
|
233
|
|
|
234
|
+void
|
|
235
|
+ContinuousTab::openWaterfallConfig()
|
|
236
|
+{
|
|
237
|
+ auto result = wfConfigDialog_->exec();
|
|
238
|
+ if (result != QDialog::Accepted)
|
|
239
|
+ return;
|
|
240
|
+
|
|
241
|
+ auto& sr = canvas_->stringRenderer();
|
|
242
|
+ sr.setWaterfallParameters(wfConfigDialog_->startSize(),
|
|
243
|
+ wfConfigDialog_->stepSize());
|
|
244
|
+ repaintGlyph();
|
|
245
|
+}
|
|
246
|
+
|
|
247
|
+
|
231
|
248
|
bool
|
232
|
249
|
ContinuousTab::eventFilter(QObject* watched,
|
233
|
250
|
QEvent* event)
|
... |
... |
@@ -308,7 +325,7 @@ ContinuousTab::createLayout() |
308
|
325
|
rotationLabel_ = new QLabel(tr("Rotation:"), this);
|
309
|
326
|
|
310
|
327
|
resetPositionButton_ = new QPushButton(tr("Reset Pos"));
|
311
|
|
- configWaterfallButton_ = new QPushButton(tr("WF Config"));
|
|
328
|
+ waterfallConfigButton_ = new QPushButton(tr("WF Config"));
|
312
|
329
|
|
313
|
330
|
xEmboldeningSpinBox_ = new QDoubleSpinBox(this);
|
314
|
331
|
yEmboldeningSpinBox_ = new QDoubleSpinBox(this);
|
... |
... |
@@ -332,6 +349,8 @@ ContinuousTab::createLayout() |
332
|
349
|
rotationSpinBox_->setMinimum(-180);
|
333
|
350
|
rotationSpinBox_->setMaximum(180);
|
334
|
351
|
|
|
352
|
+ wfConfigDialog_ = new WaterfallConfigDialog(this);
|
|
353
|
+
|
335
|
354
|
canvasFrameLayout_ = new QHBoxLayout;
|
336
|
355
|
canvasFrameLayout_->addWidget(canvas_);
|
337
|
356
|
canvasFrame_->setLayout(canvasFrameLayout_);
|
... |
... |
@@ -364,7 +383,7 @@ ContinuousTab::createLayout() |
364
|
383
|
bottomLayout_->addWidget(waterfallCheckBox_, 1, 6);
|
365
|
384
|
bottomLayout_->addWidget(verticalCheckBox_, 2, 6);
|
366
|
385
|
bottomLayout_->addWidget(kerningCheckBox_, 3, 6);
|
367
|
|
- bottomLayout_->addWidget(configWaterfallButton_, 1, 5);
|
|
386
|
+ bottomLayout_->addWidget(waterfallConfigButton_, 1, 5);
|
368
|
387
|
bottomLayout_->addWidget(sampleStringSelector_, 2, 5);
|
369
|
388
|
|
370
|
389
|
bottomLayout_->setColumnStretch(4, 1);
|
... |
... |
@@ -411,6 +430,8 @@ ContinuousTab::createConnections() |
411
|
430
|
|
412
|
431
|
connect(resetPositionButton_, &QPushButton::clicked,
|
413
|
432
|
canvas_, &GlyphContinuous::resetPositionDelta);
|
|
433
|
+ connect(waterfallConfigButton_, &QPushButton::clicked,
|
|
434
|
+ this, &ContinuousTab::openWaterfallConfig);
|
414
|
435
|
|
415
|
436
|
connect(xEmboldeningSpinBox_,
|
416
|
437
|
QOverload<double>::of(&QDoubleSpinBox::valueChanged),
|
... |
... |
@@ -480,6 +501,100 @@ ContinuousTab::formatIndex(int index) |
480
|
501
|
}
|
481
|
502
|
|
482
|
503
|
|
|
504
|
+WaterfallConfigDialog::WaterfallConfigDialog(QWidget* parent)
|
|
505
|
+: QDialog(parent)
|
|
506
|
+{
|
|
507
|
+ setModal(true);
|
|
508
|
+ setWindowTitle(tr("Waterfall Config"));
|
|
509
|
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
510
|
+
|
|
511
|
+ createLayout();
|
|
512
|
+ checkAutoStatus();
|
|
513
|
+ createConnections();
|
|
514
|
+}
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+double
|
|
518
|
+WaterfallConfigDialog::startSize()
|
|
519
|
+{
|
|
520
|
+ if (startAutoBox_->isChecked())
|
|
521
|
+ return -1.0;
|
|
522
|
+ return startSpinBox_->value();
|
|
523
|
+}
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+double
|
|
527
|
+WaterfallConfigDialog::stepSize()
|
|
528
|
+{
|
|
529
|
+ if (stepAutoBox_->isChecked())
|
|
530
|
+ return -1.0;
|
|
531
|
+ return stepSpinBox_->value();
|
|
532
|
+}
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+void
|
|
536
|
+WaterfallConfigDialog::createLayout()
|
|
537
|
+{
|
|
538
|
+ startLabel_ = new QLabel(tr("Start Size (pt):"), this);
|
|
539
|
+ stepLabel_ = new QLabel(tr("Size Step (pt):"), this);
|
|
540
|
+
|
|
541
|
+ startSpinBox_ = new QDoubleSpinBox(this);
|
|
542
|
+ stepSpinBox_ = new QDoubleSpinBox(this);
|
|
543
|
+
|
|
544
|
+ startSpinBox_->setSingleStep(0.5);
|
|
545
|
+ startSpinBox_->setMinimum(0.5);
|
|
546
|
+ startSpinBox_->setValue(1);
|
|
547
|
+
|
|
548
|
+ stepSpinBox_->setSingleStep(0.5);
|
|
549
|
+ stepSpinBox_->setMinimum(0.5);
|
|
550
|
+ stepSpinBox_->setValue(1);
|
|
551
|
+
|
|
552
|
+ startAutoBox_ = new QCheckBox(tr("Auto"), this);
|
|
553
|
+ stepAutoBox_ = new QCheckBox(tr("Auto"), this);
|
|
554
|
+
|
|
555
|
+ okButton_ = new QPushButton(tr("OK"), this);
|
|
556
|
+ cancelButton_ = new QPushButton(tr("Cancel"), this);
|
|
557
|
+
|
|
558
|
+ buttonLayout_ = new QHBoxLayout;
|
|
559
|
+ buttonLayout_->addWidget(okButton_);
|
|
560
|
+ buttonLayout_->addWidget(cancelButton_);
|
|
561
|
+
|
|
562
|
+ layout_ = new QGridLayout;
|
|
563
|
+ auto startRow = gridLayout2ColAddWidget(layout_, startLabel_, startSpinBox_);
|
|
564
|
+ auto stepRow = gridLayout2ColAddWidget(layout_, stepLabel_, stepSpinBox_);
|
|
565
|
+ layout_->addWidget(startAutoBox_, startRow, 2);
|
|
566
|
+ layout_->addWidget(stepAutoBox_, stepRow, 2);
|
|
567
|
+ layout_->addLayout(buttonLayout_, layout_->rowCount(), 0, 1, 3);
|
|
568
|
+
|
|
569
|
+ startAutoBox_->setChecked(true);
|
|
570
|
+ stepAutoBox_->setChecked(true);
|
|
571
|
+
|
|
572
|
+ setLayout(layout_);
|
|
573
|
+}
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+void
|
|
577
|
+WaterfallConfigDialog::createConnections()
|
|
578
|
+{
|
|
579
|
+ connect(startAutoBox_, &QCheckBox::clicked,
|
|
580
|
+ this, &WaterfallConfigDialog::checkAutoStatus);
|
|
581
|
+ connect(stepAutoBox_, &QCheckBox::clicked,
|
|
582
|
+ this, &WaterfallConfigDialog::checkAutoStatus);
|
|
583
|
+ connect(okButton_, &QPushButton::clicked,
|
|
584
|
+ this, &QDialog::accept);
|
|
585
|
+ connect(cancelButton_, &QPushButton::clicked,
|
|
586
|
+ this, &QDialog::reject);
|
|
587
|
+}
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+void
|
|
591
|
+WaterfallConfigDialog::checkAutoStatus()
|
|
592
|
+{
|
|
593
|
+ startSpinBox_->setEnabled(!startAutoBox_->isChecked());
|
|
594
|
+ stepSpinBox_->setEnabled(!stepAutoBox_->isChecked());
|
|
595
|
+}
|
|
596
|
+
|
|
597
|
+
|
483
|
598
|
const char* StringSamples[] = {
|
484
|
599
|
"The quick brown fox jumps over the lazy dog",
|
485
|
600
|
|
src/ftinspect/panels/continuous.hpp
... |
... |
@@ -15,6 +15,7 @@ |
15
|
15
|
|
16
|
16
|
#include <vector>
|
17
|
17
|
#include <QWidget>
|
|
18
|
+#include <QDialog>
|
18
|
19
|
#include <QFrame>
|
19
|
20
|
#include <QLabel>
|
20
|
21
|
#include <QComboBox>
|
... |
... |
@@ -25,6 +26,7 @@ |
25
|
26
|
#include <QCheckBox>
|
26
|
27
|
|
27
|
28
|
class GlyphDetails;
|
|
29
|
+class WaterfallConfigDialog;
|
28
|
30
|
class ContinuousTab
|
29
|
31
|
: public QWidget, public AbstractTab
|
30
|
32
|
{
|
... |
... |
@@ -48,6 +50,8 @@ public: |
48
|
50
|
|
49
|
51
|
// This doesn't trigger either.
|
50
|
52
|
void updateLimitIndex();
|
|
53
|
+
|
|
54
|
+ // But they do
|
51
|
55
|
void checkModeSource();
|
52
|
56
|
void charMapChanged();
|
53
|
57
|
void sourceTextChanged();
|
... |
... |
@@ -57,6 +61,7 @@ public: |
57
|
61
|
void updateGlyphDetails(GlyphCacheEntry* ctxt,
|
58
|
62
|
int charMapIndex,
|
59
|
63
|
bool open);
|
|
64
|
+ void openWaterfallConfig();
|
60
|
65
|
|
61
|
66
|
signals:
|
62
|
67
|
void switchToSingular(int glyphIndex, double sizePoint);
|
... |
... |
@@ -85,7 +90,7 @@ private: |
85
|
90
|
QComboBox* sampleStringSelector_;
|
86
|
91
|
|
87
|
92
|
QPushButton* resetPositionButton_;
|
88
|
|
- QPushButton* configWaterfallButton_;
|
|
93
|
+ QPushButton* waterfallConfigButton_;
|
89
|
94
|
|
90
|
95
|
QLabel* modeLabel_;
|
91
|
96
|
QLabel* sourceLabel_;
|
... |
... |
@@ -116,6 +121,8 @@ private: |
116
|
121
|
QDockWidget* glyphDetailsWidget_;
|
117
|
122
|
GlyphDetails* glyphDetails_;
|
118
|
123
|
|
|
124
|
+ WaterfallConfigDialog* wfConfigDialog_;
|
|
125
|
+
|
119
|
126
|
void createLayout();
|
120
|
127
|
void createConnections();
|
121
|
128
|
|
... |
... |
@@ -125,4 +132,38 @@ private: |
125
|
132
|
};
|
126
|
133
|
|
127
|
134
|
|
|
135
|
+class WaterfallConfigDialog
|
|
136
|
+: public QDialog
|
|
137
|
+{
|
|
138
|
+ Q_OBJECT
|
|
139
|
+
|
|
140
|
+public:
|
|
141
|
+ WaterfallConfigDialog(QWidget* parent);
|
|
142
|
+
|
|
143
|
+ double startSize();
|
|
144
|
+ double stepSize();
|
|
145
|
+
|
|
146
|
+private:
|
|
147
|
+ QLabel* startLabel_;
|
|
148
|
+ QLabel* stepLabel_;
|
|
149
|
+
|
|
150
|
+ QDoubleSpinBox* startSpinBox_;
|
|
151
|
+ QDoubleSpinBox* stepSpinBox_;
|
|
152
|
+
|
|
153
|
+ QCheckBox* startAutoBox_;
|
|
154
|
+ QCheckBox* stepAutoBox_;
|
|
155
|
+
|
|
156
|
+ QPushButton* okButton_;
|
|
157
|
+ QPushButton* cancelButton_;
|
|
158
|
+
|
|
159
|
+ QGridLayout* layout_;
|
|
160
|
+ QHBoxLayout* buttonLayout_;
|
|
161
|
+
|
|
162
|
+ void createLayout();
|
|
163
|
+ void createConnections();
|
|
164
|
+
|
|
165
|
+ void checkAutoStatus();
|
|
166
|
+};
|
|
167
|
+
|
|
168
|
+
|
128
|
169
|
// end of continuous.hpp |
src/ftinspect/panels/glyphdetails.cpp
... |
... |
@@ -150,10 +150,10 @@ GlyphDetails::createLayout() |
150
|
150
|
bitmapOffsetLabel_);
|
151
|
151
|
gridLayout2ColAddItem(layout_, new QSpacerItem(0, 18));
|
152
|
152
|
|
153
|
|
- gridLayout2ColAddWidget(layout_, bitmapWidget_);
|
|
153
|
+ auto bmapRowPos = gridLayout2ColAddWidget(layout_, bitmapWidget_);
|
154
|
154
|
|
155
|
155
|
layout_->setColumnStretch(1, 1);
|
156
|
|
- layout_->setRowStretch(layout_->rowCount() - 1, 1);
|
|
156
|
+ layout_->setRowStretch(bmapRowPos, 1);
|
157
|
157
|
|
158
|
158
|
setLayout(layout_);
|
159
|
159
|
setContentsMargins(12, 12, 12, 12);
|
src/ftinspect/panels/settingpanel.cpp
... |
... |
@@ -99,9 +99,11 @@ SettingPanel::onFontChanged() |
99
|
99
|
segmentDrawingCheckBox_->setEnabled(false);
|
100
|
100
|
}
|
101
|
101
|
|
|
102
|
+ stemDarkeningCheckBox_->setEnabled(false);
|
102
|
103
|
antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
|
103
|
|
- if (antiAliasingComboBox_->currentIndex()
|
104
|
|
- == AntiAliasingComboBoxModel::AntiAliasing_Light)
|
|
104
|
+ auto aaMode = antiAliasingComboBox_->currentIndex();
|
|
105
|
+ if (aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
|
|
106
|
+ || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel)
|
105
|
107
|
antiAliasingComboBox_->setCurrentIndex(
|
106
|
108
|
AntiAliasingComboBoxModel::AntiAliasing_Normal);
|
107
|
109
|
|
... |
... |
@@ -150,6 +152,8 @@ SettingPanel::populatePalettes() |
150
|
152
|
newPalettes[i].name);
|
151
|
153
|
}
|
152
|
154
|
|
|
155
|
+ paletteComboBox_->setEnabled(paletteComboBox_->count() > 0);
|
|
156
|
+
|
153
|
157
|
emit fontReloadNeeded();
|
154
|
158
|
}
|
155
|
159
|
|
... |
... |
@@ -197,14 +201,14 @@ void |
197
|
201
|
SettingPanel::checkHintingMode()
|
198
|
202
|
{
|
199
|
203
|
if (!comparatorMode_)
|
200
|
|
- applyHintingMode();
|
|
204
|
+ applyDelayedSettings();
|
201
|
205
|
|
202
|
206
|
emit fontReloadNeeded();
|
203
|
207
|
}
|
204
|
208
|
|
205
|
209
|
|
206
|
210
|
void
|
207
|
|
-SettingPanel::applyHintingMode()
|
|
211
|
+SettingPanel::applyDelayedSettings()
|
208
|
212
|
{
|
209
|
213
|
// This must not be combined into `syncSettings`:
|
210
|
214
|
// those engine manipulations will reset the whole cache!!
|
... |
... |
@@ -227,6 +231,8 @@ SettingPanel::applyHintingMode() |
227
|
231
|
if (index >= 0)
|
228
|
232
|
currentTTInterpreterVersion_ = index;
|
229
|
233
|
}
|
|
234
|
+
|
|
235
|
+ engine_->setStemDarkening(stemDarkeningCheckBox_->isChecked());
|
230
|
236
|
}
|
231
|
237
|
|
232
|
238
|
|
... |
... |
@@ -247,6 +253,10 @@ SettingPanel::checkAutoHinting() |
247
|
253
|
}
|
248
|
254
|
|
249
|
255
|
antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(true);
|
|
256
|
+ auto aaMode = antiAliasingComboBox_->currentIndex();
|
|
257
|
+ stemDarkeningCheckBox_->setEnabled(
|
|
258
|
+ aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
|
|
259
|
+ || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel);
|
250
|
260
|
}
|
251
|
261
|
else
|
252
|
262
|
{
|
... |
... |
@@ -266,11 +276,13 @@ SettingPanel::checkAutoHinting() |
266
|
276
|
}
|
267
|
277
|
|
268
|
278
|
antiAliasingComboBoxModel_->setLightAntiAliasingEnabled(false);
|
|
279
|
+ stemDarkeningCheckBox_->setEnabled(false);
|
269
|
280
|
|
270
|
|
- if (antiAliasingComboBox_->currentIndex()
|
271
|
|
- == AntiAliasingComboBoxModel::AntiAliasing_Light)
|
|
281
|
+ auto aaMode = antiAliasingComboBox_->currentIndex();
|
|
282
|
+ if (aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light
|
|
283
|
+ || aaMode == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel)
|
272
|
284
|
antiAliasingComboBox_->setCurrentIndex(
|
273
|
|
- AntiAliasingComboBoxModel::AntiAliasing_Normal);
|
|
285
|
+ AntiAliasingComboBoxModel::AntiAliasing_Normal);
|
274
|
286
|
}
|
275
|
287
|
emit repaintNeeded();
|
276
|
288
|
}
|
... |
... |
@@ -280,19 +292,18 @@ void |
280
|
292
|
SettingPanel::checkAntiAliasing()
|
281
|
293
|
{
|
282
|
294
|
int index = antiAliasingComboBox_->currentIndex();
|
283
|
|
-
|
284
|
|
- if (index == AntiAliasingComboBoxModel::AntiAliasing_None
|
|
295
|
+ auto isLight
|
|
296
|
+ = index == AntiAliasingComboBoxModel::AntiAliasing_Light
|
|
297
|
+ || index == AntiAliasingComboBoxModel::AntiAliasing_Light_SubPixel;
|
|
298
|
+ auto disableLCD
|
|
299
|
+ = index == AntiAliasingComboBoxModel::AntiAliasing_None
|
285
|
300
|
|| index == AntiAliasingComboBoxModel::AntiAliasing::AntiAliasing_Normal
|
286
|
|
- || index == AntiAliasingComboBoxModel::AntiAliasing_Light)
|
287
|
|
- {
|
288
|
|
- lcdFilterLabel_->setEnabled(false);
|
289
|
|
- lcdFilterComboBox_->setEnabled(false);
|
290
|
|
- }
|
291
|
|
- else
|
292
|
|
- {
|
293
|
|
- lcdFilterLabel_->setEnabled(true);
|
294
|
|
- lcdFilterComboBox_->setEnabled(true);
|
295
|
|
- }
|
|
301
|
+ || isLight;
|
|
302
|
+
|
|
303
|
+ lcdFilterLabel_->setEnabled(!disableLCD);
|
|
304
|
+ lcdFilterComboBox_->setEnabled(!disableLCD);
|
|
305
|
+ stemDarkeningCheckBox_->setEnabled(isLight);
|
|
306
|
+
|
296
|
307
|
emit repaintNeeded();
|
297
|
308
|
}
|
298
|
309
|
|
... |
... |
@@ -305,6 +316,16 @@ SettingPanel::checkPalette() |
305
|
316
|
}
|
306
|
317
|
|
307
|
318
|
|
|
319
|
+void
|
|
320
|
+SettingPanel::checkStemDarkening()
|
|
321
|
+{
|
|
322
|
+ if (!comparatorMode_)
|
|
323
|
+ applyDelayedSettings();
|
|
324
|
+
|
|
325
|
+ emit fontReloadNeeded();
|
|
326
|
+}
|
|
327
|
+
|
|
328
|
+
|
308
|
329
|
void
|
309
|
330
|
SettingPanel::syncSettings()
|
310
|
331
|
{
|
... |
... |
@@ -385,6 +406,8 @@ SettingPanel::createConnections() |
385
|
406
|
this, &SettingPanel::checkAutoHinting);
|
386
|
407
|
connect(embeddedBitmapCheckBox_, &QCheckBox::clicked,
|
387
|
408
|
this, &SettingPanel::fontReloadNeeded);
|
|
409
|
+ connect(stemDarkeningCheckBox_, &QCheckBox::clicked,
|
|
410
|
+ this, &SettingPanel::checkStemDarkening);
|
388
|
411
|
connect(colorLayerCheckBox_, &QCheckBox::clicked,
|
389
|
412
|
this, &SettingPanel::checkPalette);
|
390
|
413
|
|
... |
... |
@@ -420,6 +443,7 @@ SettingPanel::createLayout() |
420
|
443
|
hintingModeLabel_->setBuddy(hintingModeComboBox_);
|
421
|
444
|
|
422
|
445
|
autoHintingCheckBox_ = new QCheckBox(tr("Auto-Hinting"), this);
|
|
446
|
+ stemDarkeningCheckBox_ = new QCheckBox(tr("Stem Darkening"), this);
|
423
|
447
|
|
424
|
448
|
if (debugMode_)
|
425
|
449
|
{
|
... |
... |
@@ -502,7 +526,6 @@ SettingPanel::createLayout() |
502
|
526
|
tab_->setSizePolicy(QSizePolicy::MinimumExpanding,
|
503
|
527
|
QSizePolicy::MinimumExpanding);
|
504
|
528
|
|
505
|
|
-
|
506
|
529
|
if (debugMode_)
|
507
|
530
|
{
|
508
|
531
|
debugLayout_ = new QVBoxLayout;
|
... |
... |
@@ -565,6 +588,7 @@ SettingPanel::createLayoutNormal() |
565
|
588
|
generalTabLayout_->rowCount(), 0, 1, 2);
|
566
|
589
|
|
567
|
590
|
gridLayout2ColAddLayout(generalTabLayout_, gammaLayout_);
|
|
591
|
+ gridLayout2ColAddWidget(generalTabLayout_, stemDarkeningCheckBox_);
|
568
|
592
|
gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
|
569
|
593
|
gridLayout2ColAddWidget(generalTabLayout_, colorLayerCheckBox_);
|
570
|
594
|
gridLayout2ColAddWidget(generalTabLayout_,
|
... |
... |
@@ -605,6 +629,7 @@ SettingPanel::createLayoutComperator() |
605
|
629
|
lcdFilterLabel_, lcdFilterComboBox_);
|
606
|
630
|
|
607
|
631
|
gridLayout2ColAddLayout(hintingRenderingTabLayout_, gammaLayout_);
|
|
632
|
+ gridLayout2ColAddWidget(hintingRenderingTabLayout_, stemDarkeningCheckBox_);
|
608
|
633
|
|
609
|
634
|
// General
|
610
|
635
|
gridLayout2ColAddWidget(generalTabLayout_, embeddedBitmapCheckBox_);
|
... |
... |
@@ -662,6 +687,7 @@ SettingPanel::setDefaults() |
662
|
687
|
}
|
663
|
688
|
|
664
|
689
|
colorLayerCheckBox_->setChecked(true);
|
|
690
|
+ paletteComboBox_->setEnabled(false);
|
665
|
691
|
|
666
|
692
|
if (comparatorMode_)
|
667
|
693
|
{
|
src/ftinspect/panels/settingpanel.hpp
... |
... |
@@ -30,7 +30,7 @@ public: |
30
|
30
|
* When in comparator mode, this is needed to sync the hinting modes when
|
31
|
31
|
* reloading the font.
|
32
|
32
|
*/
|
33
|
|
- void applyHintingMode();
|
|
33
|
+ void applyDelayedSettings();
|
34
|
34
|
|
35
|
35
|
//////// Getters/Setters
|
36
|
36
|
|
... |
... |
@@ -51,6 +51,7 @@ public slots: |
51
|
51
|
void checkAutoHinting();
|
52
|
52
|
void checkAntiAliasing();
|
53
|
53
|
void checkPalette();
|
|
54
|
+ void checkStemDarkening();
|
54
|
55
|
|
55
|
56
|
private:
|
56
|
57
|
Engine* engine_;
|
... |
... |
@@ -90,6 +91,7 @@ private: |
90
|
91
|
QCheckBox* blueZoneHintingCheckBox_;
|
91
|
92
|
QCheckBox* segmentDrawingCheckBox_;
|
92
|
93
|
QCheckBox* autoHintingCheckBox_;
|
|
94
|
+ QCheckBox* stemDarkeningCheckBox_;
|
93
|
95
|
QCheckBox* embeddedBitmapCheckBox_;
|
94
|
96
|
QCheckBox* colorLayerCheckBox_;
|
95
|
97
|
QCheckBox* kerningCheckBox_;
|
src/ftinspect/panels/singular.cpp
... |
... |
@@ -129,7 +129,14 @@ SingularTab::drawGlyph() |
129
|
129
|
glyphScene_->addItem(currentGlyphPointNumbersItem_);
|
130
|
130
|
}
|
131
|
131
|
}
|
|
132
|
+
|
|
133
|
+ engine_->reloadFont();
|
|
134
|
+ auto ascDesc = engine_->currentSizeAscDescPx();
|
|
135
|
+ gridItem_->updateParameters(ascDesc.first, ascDesc.second,
|
|
136
|
+ glyph->advance.x >> 16);
|
132
|
137
|
}
|
|
138
|
+ else
|
|
139
|
+ gridItem_->updateParameters(0, 0, 0);
|
133
|
140
|
|
134
|
141
|
glyphScene_->update();
|
135
|
142
|
}
|
... |
... |
@@ -208,7 +215,8 @@ SingularTab::wheelResize(QWheelEvent* event) |
208
|
215
|
void
|
209
|
216
|
SingularTab::setGridVisible()
|
210
|
217
|
{
|
211
|
|
- gridItem_->setVisible(showGridCheckBox_->isChecked());
|
|
218
|
+ gridItem_->setShowGrid(showGridCheckBox_->isChecked(),
|
|
219
|
+ showAuxLinesCheckBox_->isChecked());
|
212
|
220
|
}
|
213
|
221
|
|
214
|
222
|
|
... |
... |
@@ -260,9 +268,7 @@ SingularTab::createLayout() |
260
|
268
|
glyphView_->setScene(glyphScene_);
|
261
|
269
|
glyphView_->setBackgroundBrush(Qt::white);
|
262
|
270
|
|
263
|
|
- gridItem_ = new Grid(glyphView_,
|
264
|
|
- graphicsDefault_->gridPen,
|
265
|
|
- graphicsDefault_->axisPen);
|
|
271
|
+ gridItem_ = new Grid(glyphView_);
|
266
|
272
|
glyphScene_->addItem(gridItem_);
|
267
|
273
|
|
268
|
274
|
// Don't use QGraphicsTextItem: We want this hint to be anchored at the
|
... |
... |
@@ -304,6 +310,7 @@ SingularTab::createLayout() |
304
|
310
|
showPointNumbersCheckBox_ = new QCheckBox(tr("Show Point Numbers"), this);
|
305
|
311
|
showOutlinesCheckBox_ = new QCheckBox(tr("Show Outlines"), this);
|
306
|
312
|
showGridCheckBox_ = new QCheckBox(tr("Show Grid"), this);
|
|
313
|
+ showAuxLinesCheckBox_ = new QCheckBox(tr("Show Aux. Lines"), this);
|
307
|
314
|
|
308
|
315
|
indexHelpLayout_ = new QHBoxLayout;
|
309
|
316
|
indexHelpLayout_->addWidget(indexSelector_, 1);
|
... |
... |
@@ -326,6 +333,7 @@ SingularTab::createLayout() |
326
|
333
|
checkBoxesLayout_->addWidget(showPointNumbersCheckBox_);
|
327
|
334
|
checkBoxesLayout_->addWidget(showOutlinesCheckBox_);
|
328
|
335
|
checkBoxesLayout_->addWidget(showGridCheckBox_);
|
|
336
|
+ checkBoxesLayout_->addWidget(showAuxLinesCheckBox_);
|
329
|
337
|
|
330
|
338
|
glyphOverlayIndexLayout_ = new QHBoxLayout;
|
331
|
339
|
glyphOverlayIndexLayout_->addWidget(glyphIndexLabel_);
|
... |
... |
@@ -381,6 +389,8 @@ SingularTab::createConnections() |
381
|
389
|
this, &SingularTab::drawGlyph);
|
382
|
390
|
connect(showGridCheckBox_, &QCheckBox::clicked,
|
383
|
391
|
this, &SingularTab::setGridVisible);
|
|
392
|
+ connect(showAuxLinesCheckBox_, &QCheckBox::clicked,
|
|
393
|
+ this, &SingularTab::setGridVisible);
|
384
|
394
|
|
385
|
395
|
sizeSelector_->installEventFilterForWidget(glyphView_);
|
386
|
396
|
sizeSelector_->installEventFilterForWidget(this);
|
... |
... |
@@ -428,6 +438,9 @@ SingularTab::setDefaults() |
428
|
438
|
showBitmapCheckBox_->setChecked(true);
|
429
|
439
|
showOutlinesCheckBox_->setChecked(true);
|
430
|
440
|
showGridCheckBox_->setChecked(true);
|
|
441
|
+ showAuxLinesCheckBox_->setChecked(true);
|
|
442
|
+ gridItem_->setShowGrid(true, true);
|
|
443
|
+
|
431
|
444
|
|
432
|
445
|
indexSelector_->setCurrentIndex(indexSelector_->currentIndex(), true);
|
433
|
446
|
zoom();
|
src/ftinspect/panels/singular.hpp
... |
... |
@@ -89,6 +89,7 @@ private: |
89
|
89
|
QCheckBox* showPointNumbersCheckBox_;
|
90
|
90
|
QCheckBox* showPointsCheckBox_;
|
91
|
91
|
QCheckBox* showGridCheckBox_;
|
|
92
|
+ QCheckBox* showAuxLinesCheckBox_;
|
92
|
93
|
|
93
|
94
|
QVBoxLayout* mainLayout_;
|
94
|
95
|
QHBoxLayout* checkBoxesLayout_;
|
src/ftinspect/rendering/graphicsdefault.cpp
... |
... |
@@ -25,6 +25,11 @@ GraphicsDefault::GraphicsDefault() |
25
|
25
|
outlinePen.setWidth(0);
|
26
|
26
|
segmentPen.setColor(QColor(64, 255, 128, 64)); // light green
|
27
|
27
|
segmentPen.setWidth(0);
|
|
28
|
+
|
|
29
|
+ advanceAuxPen.setColor(QColor(110, 52, 235)); // kind of blue
|
|
30
|
+ advanceAuxPen.setWidth(0);
|
|
31
|
+ ascDescAuxPen.setColor(QColor(255, 0, 0)); // red
|
|
32
|
+ ascDescAuxPen.setWidth(0);
|
28
|
33
|
}
|
29
|
34
|
|
30
|
35
|
|
src/ftinspect/rendering/graphicsdefault.hpp
... |
... |
@@ -19,6 +19,9 @@ struct GraphicsDefault |
19
|
19
|
QPen outlinePen;
|
20
|
20
|
QPen segmentPen;
|
21
|
21
|
|
|
22
|
+ QPen advanceAuxPen;
|
|
23
|
+ QPen ascDescAuxPen;
|
|
24
|
+
|
22
|
25
|
GraphicsDefault();
|
23
|
26
|
|
24
|
27
|
static GraphicsDefault* deafultInstance();
|
src/ftinspect/rendering/grid.cpp
... |
... |
@@ -5,18 +5,16 @@ |
5
|
5
|
|
6
|
6
|
#include "grid.hpp"
|
7
|
7
|
|
|
8
|
+#include "graphicsdefault.hpp"
|
|
9
|
+
|
8
|
10
|
#include <QPainter>
|
9
|
11
|
#include <QStyleOptionGraphicsItem>
|
10
|
12
|
#include <QGraphicsWidget>
|
11
|
13
|
#include <QGraphicsView>
|
12
|
14
|
|
13
|
15
|
|
14
|
|
-Grid::Grid(QGraphicsView* parentView,
|
15
|
|
- const QPen& gridP,
|
16
|
|
- const QPen& axisP)
|
17
|
|
-: gridPen_(gridP),
|
18
|
|
- axisPen_(axisP),
|
19
|
|
- parentView_(parentView)
|
|
16
|
+Grid::Grid(QGraphicsView* parentView)
|
|
17
|
+: parentView_(parentView)
|
20
|
18
|
{
|
21
|
19
|
// empty
|
22
|
20
|
updateRect();
|
... |
... |
@@ -60,6 +58,7 @@ Grid::paint(QPainter* painter, |
60
|
58
|
const QStyleOptionGraphicsItem* option,
|
61
|
59
|
QWidget* widget)
|
62
|
60
|
{
|
|
61
|
+ auto gb = GraphicsDefault::deafultInstance();
|
63
|
62
|
auto br = boundingRect().toRect();
|
64
|
63
|
int minX = br.left();
|
65
|
64
|
int minY = br.top();
|
... |
... |
@@ -68,53 +67,92 @@ Grid::paint(QPainter* painter, |
68
|
67
|
|
69
|
68
|
const qreal lod = option->levelOfDetailFromTransform(
|
70
|
69
|
painter->worldTransform());
|
71
|
|
-
|
72
|
|
- painter->setPen(gridPen_);
|
73
|
|
-
|
74
|
|
- // don't mark pixel center with a cross if magnification is too small
|
75
|
|
- if (lod > 20)
|
|
70
|
+ if (showGrid_)
|
76
|
71
|
{
|
77
|
|
- int halfLength = 1;
|
78
|
|
-
|
79
|
|
- // cf. QSpinBoxx
|
80
|
|
- if (lod > 640)
|
81
|
|
- halfLength = 6;
|
82
|
|
- else if (lod > 320)
|
83
|
|
- halfLength = 5;
|
84
|
|
- else if (lod > 160)
|
85
|
|
- halfLength = 4;
|
86
|
|
- else if (lod > 80)
|
87
|
|
- halfLength = 3;
|
88
|
|
- else if (lod > 40)
|
89
|
|
- halfLength = 2;
|
90
|
|
-
|
91
|
|
- for (qreal x = minX; x < maxX; x++)
|
92
|
|
- for (qreal y = minY; y < maxY; y++)
|
93
|
|
- {
|
94
|
|
- painter->drawLine(QLineF(x + 0.5, y + 0.5 - halfLength / lod,
|
95
|
|
- x + 0.5, y + 0.5 + halfLength / lod));
|
96
|
|
- painter->drawLine(QLineF(x + 0.5 - halfLength / lod, y + 0.5,
|
97
|
|
- x + 0.5 + halfLength / lod, y + 0.5));
|
98
|
|
- }
|
|
72
|
+ painter->setPen(gb->gridPen);
|
|
73
|
+
|
|
74
|
+ // don't mark pixel center with a cross if magnification is too small
|
|
75
|
+ if (lod > 20)
|
|
76
|
+ {
|
|
77
|
+ int halfLength = 1;
|
|
78
|
+
|
|
79
|
+ // cf. QSpinBoxx
|
|
80
|
+ if (lod > 640)
|
|
81
|
+ halfLength = 6;
|
|
82
|
+ else if (lod > 320)
|
|
83
|
+ halfLength = 5;
|
|
84
|
+ else if (lod > 160)
|
|
85
|
+ halfLength = 4;
|
|
86
|
+ else if (lod > 80)
|
|
87
|
+ halfLength = 3;
|
|
88
|
+ else if (lod > 40)
|
|
89
|
+ halfLength = 2;
|
|
90
|
+
|
|
91
|
+ for (qreal x = minX; x < maxX; x++)
|
|
92
|
+ for (qreal y = minY; y < maxY; y++)
|
|
93
|
+ {
|
|
94
|
+ painter->drawLine(QLineF(x + 0.5, y + 0.5 - halfLength / lod,
|
|
95
|
+ x + 0.5, y + 0.5 + halfLength / lod));
|
|
96
|
+ painter->drawLine(QLineF(x + 0.5 - halfLength / lod, y + 0.5,
|
|
97
|
+ x + 0.5 + halfLength / lod, y + 0.5));
|
|
98
|
+ }
|
|
99
|
+ }
|
|
100
|
+
|
|
101
|
+ // don't draw grid if magnification is too small
|
|
102
|
+ if (lod >= 5)
|
|
103
|
+ {
|
|
104
|
+ for (int x = minX; x <= maxX; x++)
|
|
105
|
+ painter->drawLine(x, minY,
|
|
106
|
+ x, maxY);
|
|
107
|
+ for (int y = minY; y <= maxY; y++)
|
|
108
|
+ painter->drawLine(minX, y,
|
|
109
|
+ maxX, y);
|
|
110
|
+ }
|
|
111
|
+
|
|
112
|
+ painter->setPen(gb->axisPen);
|
|
113
|
+
|
|
114
|
+ painter->drawLine(0, minY,
|
|
115
|
+ 0, maxY);
|
|
116
|
+ painter->drawLine(minX, 0,
|
|
117
|
+ maxX, 0);
|
99
|
118
|
}
|
100
|
119
|
|
101
|
|
- // don't draw grid if magnification is too small
|
102
|
|
- if (lod >= 5)
|
|
120
|
+ if (showAuxLines_)
|
103
|
121
|
{
|
104
|
|
- for (int x = minX; x <= maxX; x++)
|
105
|
|
- painter->drawLine(x, minY,
|
106
|
|
- x, maxY);
|
107
|
|
- for (int y = minY; y <= maxY; y++)
|
108
|
|
- painter->drawLine(minX, y,
|
109
|
|
- maxX, y);
|
|
122
|
+ painter->setPen(gb->ascDescAuxPen);
|
|
123
|
+ painter->drawLine(minX, ascender_,
|
|
124
|
+ maxX, ascender_);
|
|
125
|
+ painter->drawLine(minX, descender_,
|
|
126
|
+ maxX, descender_);
|
|
127
|
+
|
|
128
|
+ painter->setPen(gb->advanceAuxPen);
|
|
129
|
+ painter->drawLine(advance_, minY,
|
|
130
|
+ advance_, maxY);
|
110
|
131
|
}
|
|
132
|
+}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+void
|
|
136
|
+Grid::setShowGrid(bool showGrid, bool showAuxLines)
|
|
137
|
+{
|
|
138
|
+ showGrid_ = showGrid;
|
|
139
|
+ showAuxLines_ = showAuxLines;
|
|
140
|
+ update();
|
|
141
|
+}
|
111
|
142
|
|
112
|
|
- painter->setPen(axisPen_);
|
113
|
143
|
|
114
|
|
- painter->drawLine(0, minY,
|
115
|
|
- 0, maxY);
|
116
|
|
- painter->drawLine(minX, 0,
|
117
|
|
- maxX, 0);
|
|
144
|
+void
|
|
145
|
+Grid::updateParameters(int ascenderPx,
|
|
146
|
+ int descenderPx,
|
|
147
|
+ int advancePx)
|
|
148
|
+{
|
|
149
|
+ // Need to flip the Y coord (originally Cartesian)
|
|
150
|
+ ascender_ = -ascenderPx;
|
|
151
|
+ descender_ = -descenderPx;
|
|
152
|
+ advance_ = advancePx;
|
|
153
|
+
|
|
154
|
+ if (showAuxLines_)
|
|
155
|
+ update();
|
118
|
156
|
}
|
119
|
157
|
|
120
|
158
|
|
src/ftinspect/rendering/grid.hpp
... |
... |
@@ -13,23 +13,27 @@ class Grid |
13
|
13
|
: public QGraphicsItem
|
14
|
14
|
{
|
15
|
15
|
public:
|
16
|
|
- Grid(QGraphicsView* parentView,
|
17
|
|
- const QPen& gridPen,
|
18
|
|
- const QPen& axisPen);
|
|
16
|
+ Grid(QGraphicsView* parentView);
|
19
|
17
|
QRectF boundingRect() const override;
|
20
|
18
|
void paint(QPainter* painter,
|
21
|
19
|
const QStyleOptionGraphicsItem* option,
|
22
|
20
|
QWidget* widget) override;
|
23
|
21
|
|
|
22
|
+ void setShowGrid(bool showGrid, bool showAuxLines);
|
|
23
|
+ void updateParameters(int ascenderPx, int descenderPx, int advancePx);
|
|
24
|
+
|
24
|
25
|
void updateRect(); // there's no signal/slots for QGraphicsItem.
|
25
|
26
|
|
26
|
27
|
private:
|
27
|
|
- QPen gridPen_;
|
28
|
|
- QPen axisPen_;
|
29
|
|
-
|
30
|
28
|
QGraphicsView* parentView_;
|
31
|
29
|
QRectF rect_;
|
32
|
30
|
QRectF sceneRect_;
|
|
31
|
+
|
|
32
|
+ bool showGrid_ = true;
|
|
33
|
+ bool showAuxLines_ = false;
|
|
34
|
+
|
|
35
|
+ int ascender_ = 0, descender_ = 0;
|
|
36
|
+ int advance_ = 0;
|
33
|
37
|
};
|
34
|
38
|
|
35
|
39
|
|
src/ftinspect/uihelper.cpp
... |
... |
@@ -36,37 +36,44 @@ setLabelSelectable(QLabel* label) |
36
|
36
|
}
|
37
|
37
|
|
38
|
38
|
|
39
|
|
-void
|
|
39
|
+int
|
40
|
40
|
gridLayout2ColAddLayout(QGridLayout* layout,
|
41
|
41
|
QLayout* layoutSingle)
|
42
|
42
|
{
|
43
|
|
- layout->addLayout(layoutSingle, layout->rowCount(), 0, 1, 2);
|
|
43
|
+ auto r = layout->rowCount();
|
|
44
|
+ layout->addLayout(layoutSingle, r, 0, 1, 2);
|
|
45
|
+ return r;
|
44
|
46
|
}
|
45
|
47
|
|
46
|
48
|
|
47
|
|
-void
|
|
49
|
+int
|
48
|
50
|
gridLayout2ColAddWidget(QGridLayout* layout,
|
49
|
51
|
QWidget* widgetSingle)
|
50
|
52
|
{
|
51
|
|
- layout->addWidget(widgetSingle, layout->rowCount(), 0, 1, 2);
|
|
53
|
+ auto r = layout->rowCount();
|
|
54
|
+ layout->addWidget(widgetSingle, r, 0, 1, 2);
|
|
55
|
+ return r;
|
52
|
56
|
}
|
53
|
57
|
|
54
|
58
|
|
55
|
|
-void
|
|
59
|
+int
|
56
|
60
|
gridLayout2ColAddWidget(QGridLayout* layout,
|
57
|
61
|
QWidget* widgetL, QWidget* widgetR)
|
58
|
62
|
{
|
59
|
63
|
auto r = layout->rowCount();
|
60
|
64
|
layout->addWidget(widgetL, r, 0);
|
61
|
65
|
layout->addWidget(widgetR, r, 1);
|
|
66
|
+ return r;
|
62
|
67
|
}
|
63
|
68
|
|
64
|
69
|
|
65
|
|
-void
|
|
70
|
+int
|
66
|
71
|
gridLayout2ColAddItem(QGridLayout* layout,
|
67
|
72
|
QLayoutItem* item)
|
68
|
73
|
{
|
69
|
|
- layout->addItem(item, layout->rowCount(), 0, 1, 2);
|
|
74
|
+ auto r = layout->rowCount();
|
|
75
|
+ layout->addItem(item, r, 0, 1, 2);
|
|
76
|
+ return r;
|
70
|
77
|
}
|
71
|
78
|
|
72
|
79
|
|
src/ftinspect/uihelper.hpp
... |
... |
@@ -13,11 +13,21 @@ |
13
|
13
|
// we want buttons that are horizontally as small as possible
|
14
|
14
|
void setButtonNarrowest(QPushButton* btn);
|
15
|
15
|
void setLabelSelectable(QLabel* label);
|
16
|
|
-void gridLayout2ColAddLayout(QGridLayout* layout, QLayout* layoutSingle);
|
17
|
|
-void gridLayout2ColAddWidget(QGridLayout* layout, QWidget* widgetSingle);
|
18
|
|
-void gridLayout2ColAddWidget(QGridLayout* layout,
|
|
16
|
+
|
|
17
|
+/*
|
|
18
|
+ * All those grid layout functions rely on `QGridLayout::rowCount`, which isn't
|
|
19
|
+ * so reliable since it returns the count of rows *allocated internally* inside
|
|
20
|
+ * the layout, but not the actual number of rows occupied by layout items.
|
|
21
|
+ * Always use the returned value to refer to the row position, and never mix
|
|
22
|
+ * code using hard-coded row index with these functions.
|
|
23
|
+ * If you need to add your own rows, use `rowCount` func as well or you can
|
|
24
|
+ * increment the last returned row position.
|
|
25
|
+ */
|
|
26
|
+int gridLayout2ColAddLayout(QGridLayout* layout, QLayout* layoutSingle);
|
|
27
|
+int gridLayout2ColAddWidget(QGridLayout* layout, QWidget* widgetSingle);
|
|
28
|
+int gridLayout2ColAddWidget(QGridLayout* layout,
|
19
|
29
|
QWidget* widgetL, QWidget* widgetR);
|
20
|
|
-void gridLayout2ColAddItem(QGridLayout* layout, QLayoutItem* item);
|
|
30
|
+int gridLayout2ColAddItem(QGridLayout* layout, QLayoutItem* item);
|
21
|
31
|
|
22
|
32
|
|
23
|
33
|
// end of uihelper.hpp |
|