[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2-demos] gsoc-2022-chariri-2 e76572b 20/30: [ftinspect] Move ou
From: |
Werner Lemberg |
Subject: |
[freetype2-demos] gsoc-2022-chariri-2 e76572b 20/30: [ftinspect] Move out `ftgrid` out from `MainGUI` to a new tabbed pane. |
Date: |
Mon, 11 Jul 2022 07:17:40 -0400 (EDT) |
branch: gsoc-2022-chariri-2
commit e76572bb17a3dce1f1e8fc5adbd68cf47d27ce88
Author: Charlie Jiang <w@chariri.moe>
Commit: Charlie Jiang <w@chariri.moe>
[ftinspect] Move out `ftgrid` out from `MainGUI` to a new tabbed pane.
For further addition of other FreeType demo programs, we will use a tabbed
pane to organize all views, and the original `ftgrid` view will be the first
one, named "Singular Grid View".
An `AbstractTab` is added for helping the `MainGUI` to notify all sub-views
when settings change. The `AbstractTab` is a pure-virtual class itself.
Settings dedicate to singular grid view are moved to their tab, and the
labels
showing current glyph name/index are moved too. These overlay labels are
made
transparent to mouse click so it don't block in the way.
* src/ftinspect/maingui.cpp, src/ftinspect/maingui.hpp: Move out all
`ftgrid`-
specific code, and the whole grid section is replaced with a tab view.
Tabs are maintained using a separate `QVector` so we can easily access the
"current tab". New singal `reloadCurrentTabFont`, `repaintCurrentTab` and
the old `syncSettings` made use of this.
* src/ftinspect/panels/singular.hpp, src/ftinspect/panels/singular.cpp: New
file, as described above.
* src/ftinspect/panels/abstracttab.hpp: New file, as described above.
* src/ftinspect/engine/engine.cpp, src/ftinspect/engine/engine.hpp: Save
current font's glyph count so no need to pass it down from `MainGUI` to
all
tabs when a font reload happens.
Add a dedicate `antiAliasingEnabled` property, which is set when anti-
aliasing is set to "None".
* src/ftinspect/panels/settingpanel.cpp,
src/ftinspect/panels/settingpanel.hpp: Move out all `ftgrid`-specific
items.
* src/ftinspect/widgets/customwidgets.cpp,
src/ftinspect/widgets/customwidgets.hpp: Renamed `QSpinBoxx` to
`ZoomSpinBox` because "Zoom" box is its only usage and such name is much
more descriptive.
* src/ftinspect/CMakeLists.txt, src/ftinspect/meson.build: Updated.
---
src/ftinspect/CMakeLists.txt | 1 +
src/ftinspect/engine/engine.cpp | 3 +-
src/ftinspect/engine/engine.hpp | 5 +
src/ftinspect/maingui.cpp | 374 ++-----------------------
src/ftinspect/maingui.hpp | 63 +----
src/ftinspect/meson.build | 2 +
src/ftinspect/panels/abstracttab.hpp | 22 ++
src/ftinspect/panels/settingpanel.cpp | 66 +----
src/ftinspect/panels/settingpanel.hpp | 12 -
src/ftinspect/panels/singular.cpp | 470 ++++++++++++++++++++++++++++++++
src/ftinspect/panels/singular.hpp | 121 ++++++++
src/ftinspect/widgets/customwidgets.cpp | 6 +-
src/ftinspect/widgets/customwidgets.hpp | 4 +-
13 files changed, 661 insertions(+), 488 deletions(-)
diff --git a/src/ftinspect/CMakeLists.txt b/src/ftinspect/CMakeLists.txt
index a3ca49b..c0b1340 100644
--- a/src/ftinspect/CMakeLists.txt
+++ b/src/ftinspect/CMakeLists.txt
@@ -35,6 +35,7 @@ add_executable(ftinspect
"models/ttsettingscomboboxmodel.cpp"
"panels/settingpanel.cpp"
+ "panels/singular.cpp"
)
target_link_libraries(ftinspect
Qt5::Core Qt5::Widgets
diff --git a/src/ftinspect/engine/engine.cpp b/src/ftinspect/engine/engine.cpp
index a635d2c..4d0f8c2 100644
--- a/src/ftinspect/engine/engine.cpp
+++ b/src/ftinspect/engine/engine.cpp
@@ -298,6 +298,7 @@ Engine::loadFont(int fontIndex,
fontType_ = FontType_TrueType;
}
+ curNumGlyphs_ = numGlyphs;
return numGlyphs;
}
@@ -474,7 +475,7 @@ Engine::update()
{
loadFlags_ |= FT_LOAD_NO_HINTING;
- if (antiAliasingTarget_ | FT_LOAD_TARGET_MONO) // XXX does this hold?
+ if (!antiAliasingEnabled_) // XXX does this hold?
loadFlags_ |= FT_LOAD_MONOCHROME;
}
diff --git a/src/ftinspect/engine/engine.hpp b/src/ftinspect/engine/engine.hpp
index 1ba09a8..7a45094 100644
--- a/src/ftinspect/engine/engine.hpp
+++ b/src/ftinspect/engine/engine.hpp
@@ -81,6 +81,7 @@ public:
int currentFontType() const { return fontType_; }
const QString& currentFamilyName() { return curFamilyName_; }
const QString& currentStyleName() { return curStyleName_; }
+ int currentFontNumberOfGlyphs() { return curNumGlyphs_; }
int numberOfOpenedFonts();
QString glyphName(int glyphIndex);
long numberOfFaces(int fontIndex);
@@ -92,6 +93,7 @@ public:
// getter named fontFileManager
FontFileManager& fontFileManager() { return fontFileManager_; }
EngineDefaultValues& engineDefaults() { return engineDefaults_; }
+ bool antiAliasingEnabled() { return antiAliasingEnabled_; }
//////// Setters (direct or indirect)
@@ -115,6 +117,7 @@ public:
void setShowSegments(bool showSegments) { showSegments_ = showSegments; }
void setGamma(double gamma) { gamma_ = gamma; }
void setAntiAliasingTarget(int target) { antiAliasingTarget_ = target; }
+ void setAntiAliasingEnabled(bool enabled) { antiAliasingEnabled_ = enabled; }
// Note: These 3 functions now takes actual mode/version from FreeType,
// instead of values from enum in MainGUI!
@@ -138,6 +141,7 @@ private:
QString curFamilyName_;
QString curStyleName_;
+ int curNumGlyphs_ = -1;
FT_Library library_;
FTC_Manager cacheManager_;
@@ -151,6 +155,7 @@ private:
int fontType_;
+ bool antiAliasingEnabled_ = true;
bool usingPixelSize_ = false;
double pointSize_;
double pixelSize_;
diff --git a/src/ftinspect/maingui.cpp b/src/ftinspect/maingui.cpp
index 5f4a6d4..54f5a36 100644
--- a/src/ftinspect/maingui.cpp
+++ b/src/ftinspect/maingui.cpp
@@ -19,7 +19,6 @@
MainGUI::MainGUI(Engine* engine)
: engine_(engine)
{
- setGraphicsDefaults();
createLayout();
createConnections();
createActions();
@@ -35,8 +34,7 @@ MainGUI::MainGUI(Engine* engine)
MainGUI::~MainGUI()
{
- delete gridItem_;
- gridItem_ = NULL;
+ // empty
}
@@ -232,73 +230,38 @@ MainGUI::showFont()
auto state = settingPanel_->blockSignals(true);
settingPanel_->checkHinting();
settingPanel_->blockSignals(state);
- indexSelector_->setMin(0);
- indexSelector_->setMax(currentNumberOfGlyphs_ - 1);
- indexSelector_->setCurrentIndex(indexSelector_->getCurrentIndex(), true);
+ reloadCurrentTabFont();
}
void
-MainGUI::syncSettings()
+MainGUI::repaintCurrentTab()
{
- // Spinbox value cannot become negative
- engine_->setDPI(static_cast<unsigned int>(dpiSpinBox_->value()));
-
- if (unitsComboBox_->currentIndex() == Units_px)
- engine_->setSizeByPixel(sizeDoubleSpinBox_->value());
- else
- engine_->setSizeByPoint(sizeDoubleSpinBox_->value());
-
- settingPanel_->syncSettings();
+ syncSettings();
+ tabs_[tabWidget_->currentIndex()]->repaint();
}
void
-MainGUI::clearStatusBar()
+MainGUI::reloadCurrentTabFont()
{
- statusBar()->clearMessage();
- statusBar()->setStyleSheet("");
+ tabs_[tabWidget_->currentIndex()]->reloadFont();
}
void
-MainGUI::checkUnits()
+MainGUI::syncSettings()
{
- int index = unitsComboBox_->currentIndex();
-
- if (index == Units_px)
- {
- dpiLabel_->setEnabled(false);
- dpiSpinBox_->setEnabled(false);
- sizeDoubleSpinBox_->setSingleStep(1);
- sizeDoubleSpinBox_->setValue(qRound(sizeDoubleSpinBox_->value()));
- }
- else
- {
- dpiLabel_->setEnabled(true);
- dpiSpinBox_->setEnabled(true);
- sizeDoubleSpinBox_->setSingleStep(0.5);
- }
-
- drawGlyph();
+ settingPanel_->syncSettings();
+ tabs_[tabWidget_->currentIndex()]->syncSettings();
}
void
-MainGUI::setGlyphIndex(int index)
+MainGUI::clearStatusBar()
{
- // only adjust current glyph index if we have a valid font
- if (currentNumberOfGlyphs_ > 0)
- {
- currentGlyphIndex_ = qBound(0, index, currentNumberOfGlyphs_ - 1);
- }
-
- QString upperHex = QString::number(currentGlyphIndex_, 16).toUpper();
- glyphIndexLabel_->setText(
- QString("%1 (0x%2)").arg(currentGlyphIndex_).arg(upperHex));
- glyphNameLabel_->setText(engine_->glyphName(currentGlyphIndex_));
-
- drawGlyph();
+ statusBar()->clearMessage();
+ statusBar()->setStyleSheet("");
}
@@ -452,184 +415,6 @@ MainGUI::nextNamedInstance()
}
-void
-MainGUI::zoom()
-{
- int scale = zoomSpinBox_->value();
-
- QTransform transform;
- transform.scale(scale, scale);
-
- // we want horizontal and vertical 1px lines displayed with full pixels;
- // we thus have to shift the coordinate system accordingly, using a value
- // that represents 0.5px (i.e., half the 1px line width) after the scaling
- qreal shift = 0.5 / scale;
- transform.translate(shift, shift);
-
- glyphView_->setTransform(transform);
- updateGrid();
-}
-
-
-void
-MainGUI::backToCenter()
-{
- glyphView_->centerOn(0, 0);
- if (currentGlyphBitmapItem_)
- glyphView_->ensureVisible(currentGlyphBitmapItem_);
- else if (currentGlyphPointsItem_)
- glyphView_->ensureVisible(currentGlyphPointsItem_);
-
- updateGrid();
-}
-
-
-void
-MainGUI::updateGrid()
-{
- if (gridItem_)
- gridItem_->updateRect();
-}
-
-
-void
-MainGUI::wheelZoom(QWheelEvent* event)
-{
- int numSteps = event->angleDelta().y() / 120;
- int zoomAfter = zoomSpinBox_->value() + numSteps;
- zoomAfter = std::max(zoomSpinBox_->minimum(),
- std::min(zoomAfter, zoomSpinBox_->maximum()));
- zoomSpinBox_->setValue(zoomAfter);
- // TODO: Zoom relative to viewport left-bottom?
-}
-
-
-void
-MainGUI::wheelResize(QWheelEvent* event)
-{
- int numSteps = event->angleDelta().y() / 120;
- double sizeAfter = sizeDoubleSpinBox_->value() + numSteps * 0.5;
- sizeAfter = std::max(sizeDoubleSpinBox_->minimum(),
- std::min(sizeAfter, sizeDoubleSpinBox_->maximum()));
- sizeDoubleSpinBox_->setValue(sizeAfter);
-}
-
-
-void
-MainGUI::setGraphicsDefaults()
-{
- // color tables (with suitable opacity values) for converting
- // FreeType's pixmaps to something Qt understands
- monoColorTable_.append(QColor(Qt::transparent).rgba());
- monoColorTable_.append(QColor(Qt::black).rgba());
-
- for (int i = 0xFF; i >= 0; i--)
- grayColorTable_.append(qRgba(i, i, i, 0xFF - i));
-
- // XXX make this user-configurable
-
- axisPen_.setColor(Qt::black);
- axisPen_.setWidth(0);
- blueZonePen_.setColor(QColor(64, 64, 255, 64)); // light blue
- blueZonePen_.setWidth(0);
- gridPen_.setColor(Qt::lightGray);
- gridPen_.setWidth(0);
- offPen_.setColor(Qt::darkGreen);
- offPen_.setWidth(3);
- onPen_.setColor(Qt::red);
- onPen_.setWidth(3);
- outlinePen_.setColor(Qt::red);
- outlinePen_.setWidth(0);
- segmentPen_.setColor(QColor(64, 255, 128, 64)); // light green
- segmentPen_.setWidth(0);
-}
-
-
-void
-MainGUI::drawGlyph()
-{
- // the call to `engine->loadOutline' updates FreeType's load flags
-
- if (!engine_)
- return;
-
- if (currentGlyphBitmapItem_)
- {
- glyphScene_->removeItem(currentGlyphBitmapItem_);
- delete currentGlyphBitmapItem_;
-
- currentGlyphBitmapItem_ = NULL;
- }
-
- if (currentGlyphOutlineItem_)
- {
- glyphScene_->removeItem(currentGlyphOutlineItem_);
- delete currentGlyphOutlineItem_;
-
- currentGlyphOutlineItem_ = NULL;
- }
-
- if (currentGlyphPointsItem_)
- {
- glyphScene_->removeItem(currentGlyphPointsItem_);
- delete currentGlyphPointsItem_;
-
- currentGlyphPointsItem_ = NULL;
- }
-
- if (currentGlyphPointNumbersItem_)
- {
- glyphScene_->removeItem(currentGlyphPointNumbersItem_);
- delete currentGlyphPointNumbersItem_;
-
- currentGlyphPointNumbersItem_ = NULL;
- }
-
- syncSettings();
- FT_Outline* outline = engine_->loadOutline(currentGlyphIndex_);
- if (outline)
- {
- if (settingPanel_->showBitmapChecked())
- {
- // XXX support LCD
- FT_Pixel_Mode pixelMode = FT_PIXEL_MODE_GRAY;
- if (settingPanel_->antiAliasingModeIndex()
- == AntiAliasingComboBoxModel::AntiAliasing_None)
- pixelMode = FT_PIXEL_MODE_MONO;
-
- currentGlyphBitmapItem_ = new GlyphBitmap(outline,
- engine_->ftLibrary(),
- pixelMode,
- monoColorTable_,
- grayColorTable_);
- glyphScene_->addItem(currentGlyphBitmapItem_);
- }
-
- if (settingPanel_->showOutLinesChecked())
- {
- currentGlyphOutlineItem_ = new GlyphOutline(outlinePen_, outline);
- glyphScene_->addItem(currentGlyphOutlineItem_);
- }
-
- if (settingPanel_->showPointsChecked())
- {
- currentGlyphPointsItem_ = new GlyphPoints(onPen_, offPen_, outline);
- glyphScene_->addItem(currentGlyphPointsItem_);
-
- if (settingPanel_->showPointNumbersChecked())
- {
- currentGlyphPointNumbersItem_ = new GlyphPointNumbers(onPen_,
- offPen_,
- outline);
- glyphScene_->addItem(currentGlyphPointNumbersItem_);
- }
- }
- }
-
- glyphScene_->update();
-}
-
-
// XXX distances are specified in pixels,
// making the layout dependent on the output device resolution
void
@@ -660,70 +445,15 @@ MainGUI::createLayout()
leftWidget_->setSizePolicy(leftWidgetPolicy);
// right side
- glyphIndexLabel_ = new QLabel(this);
- glyphNameLabel_ = new QLabel(this);
fontNameLabel_ = new QLabel(this);
- glyphScene_ = new QGraphicsScene(this);
-
- currentGlyphBitmapItem_ = NULL;
- currentGlyphOutlineItem_ = NULL;
- currentGlyphPointsItem_ = NULL;
- currentGlyphPointNumbersItem_ = NULL;
-
- glyphView_ = new QGraphicsViewx(this);
- glyphView_->setRenderHint(QPainter::Antialiasing, true);
- glyphView_->setDragMode(QGraphicsView::ScrollHandDrag);
- glyphView_->setOptimizationFlags(QGraphicsView::DontSavePainterState);
- glyphView_->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
- glyphView_->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
- glyphView_->setScene(glyphScene_);
-
- gridItem_ = new Grid(glyphView_, gridPen_, axisPen_);
- glyphScene_->addItem(gridItem_);
-
- // Don't use QGraphicsTextItem: We want this hint to be anchored at the
- // top-left corner.
- mouseUsageHint_ = new QLabel(tr("Scroll: Grid Up/Down\n"
- "Alt + Scroll: Grid Left/Right\n"
- "Ctrl + Scroll: Adjust Zoom (Relative to cursor)\n"
- "Shift + Scroll: Adjust Font Size"), glyphView_);
- mouseUsageHint_->setMargin(10);
- auto hintFont = font();
- hintFont.setPixelSize(24);
- mouseUsageHint_->setFont(hintFont);
-
- sizeLabel_ = new QLabel(tr("Size "), this);
- sizeLabel_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
- sizeDoubleSpinBox_ = new QDoubleSpinBox;
- sizeDoubleSpinBox_->setAlignment(Qt::AlignRight);
- sizeDoubleSpinBox_->setDecimals(1);
- sizeDoubleSpinBox_->setRange(1, 500);
- sizeLabel_->setBuddy(sizeDoubleSpinBox_);
-
- indexSelector_ = new GlyphIndexSelector(this);
- indexSelector_->setSingleMode(true);
-
- unitsComboBox_ = new QComboBox(this);
- unitsComboBox_->insertItem(Units_px, "px");
- unitsComboBox_->insertItem(Units_pt, "pt");
-
- dpiLabel_ = new QLabel(tr("DPI "), this);
- dpiLabel_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
- dpiSpinBox_ = new QSpinBox(this);
- dpiSpinBox_->setAlignment(Qt::AlignRight);
- dpiSpinBox_->setRange(10, 600);
- dpiLabel_->setBuddy(dpiSpinBox_);
-
- zoomLabel_ = new QLabel(tr("Zoom Factor"), this);
- zoomLabel_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
- zoomSpinBox_ = new QSpinBoxx(this);
- zoomSpinBox_->setAlignment(Qt::AlignRight);
- zoomSpinBox_->setRange(1, 1000 - 1000 % 64);
- zoomSpinBox_->setKeyboardTracking(false);
- zoomLabel_->setBuddy(zoomSpinBox_);
-
- centerGridButton_ = new QPushButton("Go Back to Grid Center", this);
+ singularTab_ = new SingularTab(this, engine_);
+
+ tabWidget_ = new QTabWidget(this);
+
+ // Note those two list must be in sync
+ tabs_.append(singularTab_);
+ tabWidget_->addTab(singularTab_, tr("Singular Grid View"));
previousFontButton_ = new QPushButton(tr("Previous Font"), this);
nextFontButton_ = new QPushButton(tr("Next Font"), this);
@@ -733,26 +463,6 @@ MainGUI::createLayout()
= new QPushButton(tr("Previous Named Instance"), this);
nextNamedInstanceButton_ = new QPushButton(tr("Next Named Instance"), this);
- infoRightLayout = new QGridLayout;
- infoRightLayout->addWidget(glyphIndexLabel_, 0, 0);
- infoRightLayout->addWidget(glyphNameLabel_, 0, 1);
- infoRightLayout->addWidget(fontNameLabel_, 0, 2);
-
- sizeLayout_ = new QHBoxLayout;
- sizeLayout_->addStretch(2);
- sizeLayout_->addWidget(sizeLabel_);
- sizeLayout_->addWidget(sizeDoubleSpinBox_);
- sizeLayout_->addWidget(unitsComboBox_);
- sizeLayout_->addStretch(1);
- sizeLayout_->addWidget(dpiLabel_);
- sizeLayout_->addWidget(dpiSpinBox_);
- sizeLayout_->addStretch(1);
- sizeLayout_->addWidget(zoomLabel_);
- sizeLayout_->addWidget(zoomSpinBox_);
- sizeLayout_->addStretch(1);
- sizeLayout_->addWidget(centerGridButton_);
- sizeLayout_->addStretch(2);
-
fontLayout = new QGridLayout;
fontLayout->setColumnStretch(0, 2);
fontLayout->addWidget(nextFontButton_, 0, 1);
@@ -766,12 +476,8 @@ MainGUI::createLayout()
fontLayout->setColumnStretch(6, 2);
rightLayout_ = new QVBoxLayout;
- rightLayout_->addLayout(infoRightLayout);
- rightLayout_->addWidget(glyphView_);
- rightLayout_->addWidget(indexSelector_);
- rightLayout_->addSpacing(10); // XXX px
- rightLayout_->addLayout(sizeLayout_);
- rightLayout_->addSpacing(10); // XXX px
+ rightLayout_->addWidget(fontNameLabel_);
+ rightLayout_->addWidget(tabWidget_);
rightLayout_->addLayout(fontLayout);
// for symmetry with the left side use a widget also
@@ -796,29 +502,7 @@ MainGUI::createConnections()
connect(settingPanel_, &SettingPanel::fontReloadNeeded,
this, &MainGUI::showFont);
connect(settingPanel_, &SettingPanel::repaintNeeded,
- this, &MainGUI::drawGlyph);
- connect(indexSelector_, &GlyphIndexSelector::currentIndexChanged,
- this, &MainGUI::setGlyphIndex);
- connect(sizeDoubleSpinBox_,
QOverload<double>::of(&QDoubleSpinBox::valueChanged),
- this, &MainGUI::drawGlyph);
- connect(unitsComboBox_, QOverload<int>::of(&QComboBox::currentIndexChanged),
- this, &MainGUI::checkUnits);
- connect(dpiSpinBox_, QOverload<int>::of(&QSpinBox::valueChanged),
- this, &MainGUI::drawGlyph);
-
- connect(zoomSpinBox_, QOverload<int>::of(&QSpinBox::valueChanged),
- this, &MainGUI::zoom);
- connect(glyphView_, &QGraphicsViewx::shiftWheelEvent,
- this, &MainGUI::wheelResize);
- connect(glyphView_, &QGraphicsViewx::ctrlWheelEvent,
- this, &MainGUI::wheelZoom);
- connect(glyphView_->horizontalScrollBar(), &QScrollBar::valueChanged,
- this, &MainGUI::updateGrid);
- connect(glyphView_->verticalScrollBar(), &QScrollBar::valueChanged,
- this, &MainGUI::updateGrid);
-
- connect(centerGridButton_, &QPushButton::clicked,
- this, &MainGUI::backToCenter);
+ this, &MainGUI::repaintCurrentTab);
connect(previousFontButton_, &QPushButton::clicked,
this, &MainGUI::previousFont);
@@ -886,7 +570,6 @@ void
MainGUI::setupDragDrop()
{
setAcceptDrops(true);
- glyphView_->setAcceptDrops(false);
}
@@ -897,19 +580,12 @@ MainGUI::setDefaults()
currentFontIndex_ = 0;
currentFaceIndex_ = 0;
currentNamedInstanceIndex_ = 0;
- currentGlyphIndex_ = 0;
-
- sizeDoubleSpinBox_->setValue(20);
- dpiSpinBox_->setValue(96);
- zoomSpinBox_->setValue(20);
- // todo run check for settingpanel
- checkUnits();
+ for (auto tab : tabs_)
+ tab->setDefaults();
checkCurrentFontIndex();
checkCurrentFaceIndex();
checkCurrentNamedInstanceIndex();
- indexSelector_->setCurrentIndex(indexSelector_->getCurrentIndex(), true);
- zoom();
}
diff --git a/src/ftinspect/maingui.hpp b/src/ftinspect/maingui.hpp
index 6172fd7..0e1126a 100644
--- a/src/ftinspect/maingui.hpp
+++ b/src/ftinspect/maingui.hpp
@@ -6,15 +6,11 @@
#pragma once
#include "engine/engine.hpp"
-#include "rendering/glyphbitmap.hpp"
-#include "rendering/glyphoutline.hpp"
-#include "rendering/glyphpointnumbers.hpp"
-#include "rendering/glyphpoints.hpp"
-#include "rendering/grid.hpp"
#include "widgets/customwidgets.hpp"
#include "widgets/glyphindexselector.hpp"
#include "models/ttsettingscomboboxmodel.hpp"
#include "panels/settingpanel.hpp"
+#include "panels/singular.hpp"
#include <QAction>
#include <QCheckBox>
@@ -72,14 +68,13 @@ protected:
private slots:
void about();
void aboutQt();
- void setGlyphIndex(int);
void checkCurrentFaceIndex();
void checkCurrentFontIndex();
void checkCurrentNamedInstanceIndex();
- void checkUnits();
void closeFont();
void showFont();
- void drawGlyph();
+ void repaintCurrentTab();
+ void reloadCurrentTabFont();
void loadFonts();
void nextFace();
void nextFont();
@@ -88,11 +83,6 @@ private slots:
void previousFont();
void previousNamedInstance();
void watchCurrentFont();
- void zoom();
- void backToCenter();
- void updateGrid();
- void wheelZoom(QWheelEvent* event);
- void wheelResize(QWheelEvent* event);
private:
Engine* engine_;
@@ -106,86 +96,46 @@ private:
int currentNamedInstanceIndex_;
int currentNumberOfGlyphs_;
- int currentGlyphIndex_;
// layout related stuff
- GlyphOutline *currentGlyphOutlineItem_;
- GlyphPoints *currentGlyphPointsItem_;
- GlyphPointNumbers *currentGlyphPointNumbersItem_;
- GlyphBitmap *currentGlyphBitmapItem_;
- Grid *gridItem_ = NULL;
- QLabel* mouseUsageHint_;
-
QAction *aboutAct_;
QAction *aboutQtAct_;
QAction *closeFontAct_;
QAction *exitAct_;
QAction *loadFontsAct_;
- GlyphIndexSelector* indexSelector_;
- QComboBox *unitsComboBox_;
-
- QDoubleSpinBox *sizeDoubleSpinBox_;
-
- QGraphicsScene *glyphScene_;
- QGraphicsViewx *glyphView_;
-
QGridLayout *fontLayout;
- QGridLayout *infoRightLayout;
QHBoxLayout *ftinspectLayout_;
QHBoxLayout *infoLeftLayout_;
- QHBoxLayout *sizeLayout_;
- QLabel *dpiLabel_;
QLabel *fontFilenameLabel_;
QLabel *fontNameLabel_;
- QLabel *glyphIndexLabel_;
- QLabel *glyphNameLabel_;
- QLabel *sizeLabel_;
- QLabel *zoomLabel_;
QLocale *locale_;
QMenu *menuFile_;
QMenu *menuHelp_;
- QPen axisPen_;
- QPen blueZonePen_;
- QPen gridPen_;
- QPen offPen_;
- QPen onPen_;
- QPen outlinePen_;
- QPen segmentPen_;
-
- QPushButton *centerGridButton_;
QPushButton *nextFaceButton_;
QPushButton *nextFontButton_;
QPushButton *nextNamedInstanceButton_;
QPushButton *previousFaceButton_;
QPushButton *previousFontButton_;
QPushButton *previousNamedInstanceButton_;
-
- QSpinBox *dpiSpinBox_;
- QSpinBoxx *zoomSpinBox_;
QVBoxLayout *leftLayout_;
QVBoxLayout *rightLayout_;
- QVector<QRgb> grayColorTable_;
- QVector<QRgb> monoColorTable_;
-
QWidget *ftinspectWidget_;
QWidget *leftWidget_;
QWidget *rightWidget_;
SettingPanel* settingPanel_;
- enum Units
- {
- Units_px,
- Units_pt
- };
+ QTabWidget* tabWidget_;
+ QVector<AbstractTab*> tabs_;
+ SingularTab* singularTab_;
void openFonts(QStringList const& fileNames);
@@ -197,7 +147,6 @@ private:
void createLayout();
void createMenus();
void createStatusBar();
- void setGraphicsDefaults();
void setupDragDrop();
void readSettings();
diff --git a/src/ftinspect/meson.build b/src/ftinspect/meson.build
index a3c71d0..de0e7e9 100644
--- a/src/ftinspect/meson.build
+++ b/src/ftinspect/meson.build
@@ -34,6 +34,7 @@ if qt5_dep.found()
'models/ttsettingscomboboxmodel.cpp',
'panels/settingpanel.cpp',
+ 'panels/singular.cpp',
'ftinspect.cpp',
'maingui.cpp',
@@ -47,6 +48,7 @@ if qt5_dep.found()
'widgets/glyphindexselector.hpp',
'models/ttsettingscomboboxmodel.hpp',
'panels/settingpanel.hpp',
+ 'panels/singular.hpp',
'maingui.hpp',
],
dependencies: qt5_dep)
diff --git a/src/ftinspect/panels/abstracttab.hpp
b/src/ftinspect/panels/abstracttab.hpp
new file mode 100644
index 0000000..270e907
--- /dev/null
+++ b/src/ftinspect/panels/abstracttab.hpp
@@ -0,0 +1,22 @@
+// abstracttab.hpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#pragma once
+
+// This is an pure abstract interface for a ftinspect "tab".
+// The interface itself does not inherit from `QWidget`, but should be used as
+// the second base class.
+class AbstractTab
+{
+public:
+ virtual ~AbstractTab() = default; // must be `virtual` for `dynamic_cast`
+
+ virtual void syncSettings() = 0;
+ virtual void setDefaults() = 0;
+ virtual void repaint() = 0;
+ virtual void reloadFont() = 0;
+};
+
+
+// end of abstracttab.hpp
diff --git a/src/ftinspect/panels/settingpanel.cpp
b/src/ftinspect/panels/settingpanel.cpp
index c459481..5781865 100644
--- a/src/ftinspect/panels/settingpanel.cpp
+++ b/src/ftinspect/panels/settingpanel.cpp
@@ -22,34 +22,6 @@ SettingPanel::antiAliasingModeIndex()
}
-bool
-SettingPanel::showBitmapChecked()
-{
- return showBitmapCheckBox_->isChecked();
-}
-
-
-bool
-SettingPanel::showOutLinesChecked()
-{
- return showOutlinesCheckBox_->isChecked();
-}
-
-
-bool
-SettingPanel::showPointNumbersChecked()
-{
- return showPointNumbersCheckBox_->isChecked();
-}
-
-
-bool
-SettingPanel::showPointsChecked()
-{
- return showPointsCheckBox_->isChecked();
-}
-
-
void
SettingPanel::checkAllSettings()
{
@@ -57,7 +29,6 @@ SettingPanel::checkAllSettings()
checkAutoHinting();
checkAntiAliasing();
checkLCDFilter();
- checkShowPoints();
}
@@ -196,17 +167,6 @@ SettingPanel::checkAntiAliasing()
}
-void
-SettingPanel::checkShowPoints()
-{
- if (showPointsCheckBox_->isChecked())
- showPointNumbersCheckBox_->setEnabled(true);
- else
- showPointNumbersCheckBox_->setEnabled(false);
- emit repaintNeeded();
-}
-
-
void
SettingPanel::checkLCDFilter()
{
@@ -222,6 +182,8 @@ SettingPanel::syncSettings()
lcdFilterComboBox_->currentIndex())));
engine_->setAntiAliasingTarget(antiAliasingComboBoxModel_->indexToValue(
antiAliasingComboBox_->currentIndex()));
+ engine_->setAntiAliasingEnabled(antiAliasingComboBox_->currentIndex()
+ != AntiAliasingComboBoxModel::AntiAliasing_None);
engine_->setHinting(hintingCheckBox_->isChecked());
engine_->setAutoHinting(autoHintingCheckBox_->isChecked());
engine_->setHorizontalHinting(horizontalHintingCheckBox_->isChecked());
@@ -264,14 +226,6 @@ SettingPanel::createConnections()
connect(autoHintingCheckBox_, &QCheckBox::clicked,
this, &SettingPanel::checkAutoHinting);
- connect(showBitmapCheckBox_, &QCheckBox::clicked,
- this, &SettingPanel::repaintNeeded);
- connect(showPointsCheckBox_, &QCheckBox::clicked,
- this, &SettingPanel::repaintNeeded);
- connect(showPointNumbersCheckBox_, &QCheckBox::clicked,
- this, &SettingPanel::repaintNeeded);
- connect(showOutlinesCheckBox_, &QCheckBox::clicked,
- this, &SettingPanel::repaintNeeded);
}
@@ -336,11 +290,6 @@ SettingPanel::createLayout()
gammaSlider_->setTickInterval(5);
gammaLabel_->setBuddy(gammaSlider_);
- showBitmapCheckBox_ = new QCheckBox(tr("Show Bitmap"), this);
- showPointsCheckBox_ = new QCheckBox(tr("Show Points"), this);
- showPointNumbersCheckBox_ = new QCheckBox(tr("Show Point Numbers"), this);
- showOutlinesCheckBox_ = new QCheckBox(tr("Show Outlines"), this);
-
hintingModeLayout_ = new QHBoxLayout;
hintingModeLayout_->addWidget(hintingModeLabel_);
hintingModeLayout_->addWidget(hintingModeComboBox_);
@@ -373,10 +322,6 @@ SettingPanel::createLayout()
gammaLayout_->addWidget(gammaLabel_);
gammaLayout_->addWidget(gammaSlider_);
- pointNumbersLayout_ = new QHBoxLayout;
- pointNumbersLayout_->addSpacing(20); // XXX px
- pointNumbersLayout_->addWidget(showPointNumbersCheckBox_);
-
generalTabLayout_ = new QVBoxLayout;
generalTabLayout_->addWidget(hintingCheckBox_);
generalTabLayout_->addLayout(hintingModeLayout_);
@@ -394,10 +339,6 @@ SettingPanel::createLayout()
generalTabLayout_->addLayout(gammaLayout_);
generalTabLayout_->addSpacing(20); // XXX px
generalTabLayout_->addStretch(1);
- generalTabLayout_->addWidget(showBitmapCheckBox_);
- generalTabLayout_->addWidget(showPointsCheckBox_);
- generalTabLayout_->addLayout(pointNumbersLayout_);
- generalTabLayout_->addWidget(showOutlinesCheckBox_);
generalTab_ = new QWidget(this);
generalTab_->setLayout(generalTabLayout_);
@@ -444,9 +385,6 @@ SettingPanel::setDefaults()
verticalHintingCheckBox_->setChecked(true);
blueZoneHintingCheckBox_->setChecked(true);
- showBitmapCheckBox_->setChecked(true);
- showOutlinesCheckBox_->setChecked(true);
-
gammaSlider_->setValue(18); // 1.8
}
diff --git a/src/ftinspect/panels/settingpanel.hpp
b/src/ftinspect/panels/settingpanel.hpp
index ba133c7..562af3f 100644
--- a/src/ftinspect/panels/settingpanel.hpp
+++ b/src/ftinspect/panels/settingpanel.hpp
@@ -28,12 +28,6 @@ public:
int antiAliasingModeIndex();
- // TODO This would eventually go to separate panel for ftglyph (Singular
View)
- bool showBitmapChecked();
- bool showOutLinesChecked();
- bool showPointNumbersChecked();
- bool showPointsChecked();
-
signals:
void fontReloadNeeded();
void repaintNeeded();
@@ -46,7 +40,6 @@ public slots:
void checkHintingMode();
void checkAutoHinting();
void checkAntiAliasing();
- void checkShowPoints();
void checkLCDFilter();
private:
@@ -71,10 +64,6 @@ private:
QCheckBox* blueZoneHintingCheckBox_;
QCheckBox* segmentDrawingCheckBox_;
QCheckBox* autoHintingCheckBox_;
- QCheckBox* showBitmapCheckBox_;
- QCheckBox* showOutlinesCheckBox_;
- QCheckBox* showPointNumbersCheckBox_;
- QCheckBox* showPointsCheckBox_;
AntiAliasingComboBoxModel* antiAliasingComboBoxModel_;
HintingModeComboBoxModel* hintingModeComboBoxModel_;
@@ -95,7 +84,6 @@ private:
QHBoxLayout* antiAliasingLayout_;
QHBoxLayout* lcdFilterLayout_;
QHBoxLayout* gammaLayout_;
- QHBoxLayout* pointNumbersLayout_;
QVBoxLayout* generalTabLayout_;
diff --git a/src/ftinspect/panels/singular.cpp
b/src/ftinspect/panels/singular.cpp
new file mode 100644
index 0000000..6d95f75
--- /dev/null
+++ b/src/ftinspect/panels/singular.cpp
@@ -0,0 +1,470 @@
+// singular.cpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#include "singular.hpp"
+
+#include <QSizePolicy>
+#include <QWheelEvent>
+
+
+SingularTab::SingularTab(QWidget* parent, Engine* engine)
+: QWidget(parent), engine_(engine)
+{
+ setGraphicsDefaults();
+ createLayout();
+ createConnections();
+
+ currentGlyphIndex_ = 0;
+ checkShowPoints();
+ checkUnits();
+}
+
+
+SingularTab::~SingularTab()
+{
+ delete gridItem_;
+ gridItem_ = NULL;
+}
+
+
+void
+SingularTab::setGlyphIndex(int index)
+{
+ // only adjust current glyph index if we have a valid font
+ if (currentGlyphCount_ > 0)
+ {
+ currentGlyphIndex_ = qBound(0, index, currentGlyphCount_ - 1);
+ }
+
+ QString upperHex = QString::number(currentGlyphIndex_, 16).toUpper();
+ glyphIndexLabel_->setText(
+ QString("%1 (0x%2)").arg(currentGlyphIndex_).arg(upperHex));
+ glyphNameLabel_->setText(engine_->glyphName(currentGlyphIndex_));
+
+ drawGlyph();
+}
+
+
+void
+SingularTab::drawGlyph()
+{
+ // the call to `engine->loadOutline' updates FreeType's load flags
+
+ if (!engine_)
+ return;
+
+ if (currentGlyphBitmapItem_)
+ {
+ glyphScene_->removeItem(currentGlyphBitmapItem_);
+ delete currentGlyphBitmapItem_;
+
+ currentGlyphBitmapItem_ = NULL;
+ }
+
+ if (currentGlyphOutlineItem_)
+ {
+ glyphScene_->removeItem(currentGlyphOutlineItem_);
+ delete currentGlyphOutlineItem_;
+
+ currentGlyphOutlineItem_ = NULL;
+ }
+
+ if (currentGlyphPointsItem_)
+ {
+ glyphScene_->removeItem(currentGlyphPointsItem_);
+ delete currentGlyphPointsItem_;
+
+ currentGlyphPointsItem_ = NULL;
+ }
+
+ if (currentGlyphPointNumbersItem_)
+ {
+ glyphScene_->removeItem(currentGlyphPointNumbersItem_);
+ delete currentGlyphPointNumbersItem_;
+
+ currentGlyphPointNumbersItem_ = NULL;
+ }
+
+ syncSettings();
+ FT_Outline* outline = engine_->loadOutline(currentGlyphIndex_);
+ if (outline)
+ {
+ if (showBitmapCheckBox_->isChecked())
+ {
+ // XXX support LCD
+ FT_Pixel_Mode pixelMode = FT_PIXEL_MODE_GRAY;
+ if (!engine_->antiAliasingEnabled())
+ pixelMode = FT_PIXEL_MODE_MONO;
+
+ currentGlyphBitmapItem_ = new GlyphBitmap(outline,
+ engine_->ftLibrary(),
+ pixelMode,
+ monoColorTable_,
+ grayColorTable_);
+ glyphScene_->addItem(currentGlyphBitmapItem_);
+ }
+
+ if (showOutlinesCheckBox_->isChecked())
+ {
+ currentGlyphOutlineItem_ = new GlyphOutline(outlinePen_, outline);
+ glyphScene_->addItem(currentGlyphOutlineItem_);
+ }
+
+ if (showPointsCheckBox_->isChecked())
+ {
+ currentGlyphPointsItem_ = new GlyphPoints(onPen_, offPen_, outline);
+ glyphScene_->addItem(currentGlyphPointsItem_);
+
+ if (showPointNumbersCheckBox_->isChecked())
+ {
+ currentGlyphPointNumbersItem_ = new GlyphPointNumbers(onPen_,
+ offPen_,
+ outline);
+ glyphScene_->addItem(currentGlyphPointNumbersItem_);
+ }
+ }
+ }
+
+ glyphScene_->update();
+}
+
+
+void
+SingularTab::checkUnits()
+{
+ int index = unitsComboBox_->currentIndex();
+
+ if (index == Units_px)
+ {
+ dpiLabel_->setEnabled(false);
+ dpiSpinBox_->setEnabled(false);
+ sizeDoubleSpinBox_->setSingleStep(1);
+ sizeDoubleSpinBox_->setValue(qRound(sizeDoubleSpinBox_->value()));
+ }
+ else
+ {
+ dpiLabel_->setEnabled(true);
+ dpiSpinBox_->setEnabled(true);
+ sizeDoubleSpinBox_->setSingleStep(0.5);
+ }
+
+ drawGlyph();
+}
+
+
+void
+SingularTab::checkShowPoints()
+{
+ if (showPointsCheckBox_->isChecked())
+ showPointNumbersCheckBox_->setEnabled(true);
+ else
+ showPointNumbersCheckBox_->setEnabled(false);
+ drawGlyph();
+}
+
+
+void
+SingularTab::zoom()
+{
+ int scale = zoomSpinBox_->value();
+
+ QTransform transform;
+ transform.scale(scale, scale);
+
+ // we want horizontal and vertical 1px lines displayed with full pixels;
+ // we thus have to shift the coordinate system accordingly, using a value
+ // that represents 0.5px (i.e., half the 1px line width) after the scaling
+ qreal shift = 0.5 / scale;
+ transform.translate(shift, shift);
+
+ glyphView_->setTransform(transform);
+ updateGrid();
+}
+
+
+void
+SingularTab::backToCenter()
+{
+ glyphView_->centerOn(0, 0);
+ if (currentGlyphBitmapItem_)
+ glyphView_->ensureVisible(currentGlyphBitmapItem_);
+ else if (currentGlyphPointsItem_)
+ glyphView_->ensureVisible(currentGlyphPointsItem_);
+
+ updateGrid();
+}
+
+
+void
+SingularTab::updateGrid()
+{
+ if (gridItem_)
+ gridItem_->updateRect();
+}
+
+
+void
+SingularTab::wheelZoom(QWheelEvent* event)
+{
+ int numSteps = event->angleDelta().y() / 120;
+ int zoomAfter = zoomSpinBox_->value() + numSteps;
+ zoomAfter = std::max(zoomSpinBox_->minimum(),
+ std::min(zoomAfter, zoomSpinBox_->maximum()));
+ zoomSpinBox_->setValue(zoomAfter);
+ // TODO: Zoom relative to viewport left-bottom?
+}
+
+
+void
+SingularTab::wheelResize(QWheelEvent* event)
+{
+ int numSteps = event->angleDelta().y() / 120;
+ double sizeAfter = sizeDoubleSpinBox_->value() + numSteps * 0.5;
+ sizeAfter = std::max(sizeDoubleSpinBox_->minimum(),
+ std::min(sizeAfter, sizeDoubleSpinBox_->maximum()));
+ sizeDoubleSpinBox_->setValue(sizeAfter);
+}
+
+
+void
+SingularTab::createLayout()
+{
+ glyphScene_ = new QGraphicsScene(this);
+
+ currentGlyphBitmapItem_ = NULL;
+ currentGlyphOutlineItem_ = NULL;
+ currentGlyphPointsItem_ = NULL;
+ currentGlyphPointNumbersItem_ = NULL;
+
+ glyphView_ = new QGraphicsViewx(this);
+ glyphView_->setRenderHint(QPainter::Antialiasing, true);
+ glyphView_->setAcceptDrops(false);
+ glyphView_->setDragMode(QGraphicsView::ScrollHandDrag);
+ glyphView_->setOptimizationFlags(QGraphicsView::DontSavePainterState);
+ glyphView_->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
+ glyphView_->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
+ glyphView_->setScene(glyphScene_);
+
+ gridItem_ = new Grid(glyphView_, gridPen_, axisPen_);
+ glyphScene_->addItem(gridItem_);
+
+ // Don't use QGraphicsTextItem: We want this hint to be anchored at the
+ // top-left corner.
+ mouseUsageHint_ = new QLabel(tr(
+ "Scroll: Grid Up/Down\n"
+ "Alt + Scroll: Grid Left/Right\n"
+ "Ctrl + Scroll: Adjust Zoom (Relative to cursor)\n"
+ "Shift + Scroll: Adjust Font Size"),
+ glyphView_);
+ auto hintFont = font();
+ hintFont.setPixelSize(24);
+ mouseUsageHint_->setFont(hintFont);
+ mouseUsageHint_->setAttribute(Qt::WA_TransparentForMouseEvents, true);
+
+ glyphIndexLabel_ = new QLabel(glyphView_);
+ glyphNameLabel_ = new QLabel(glyphView_);
+ glyphIndexLabel_->setFont(hintFont);
+ glyphNameLabel_->setFont(hintFont);
+ glyphIndexLabel_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ glyphNameLabel_->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+ glyphIndexLabel_->setAttribute(Qt::WA_TransparentForMouseEvents, true);
+ glyphNameLabel_->setAttribute(Qt::WA_TransparentForMouseEvents, true);
+
+ sizeLabel_ = new QLabel(tr("Size "), this);
+ sizeLabel_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ sizeDoubleSpinBox_ = new QDoubleSpinBox;
+ sizeDoubleSpinBox_->setAlignment(Qt::AlignRight);
+ sizeDoubleSpinBox_->setDecimals(1);
+ sizeDoubleSpinBox_->setRange(1, 500);
+ sizeLabel_->setBuddy(sizeDoubleSpinBox_);
+
+ indexSelector_ = new GlyphIndexSelector(this);
+ indexSelector_->setSingleMode(true);
+
+ unitsComboBox_ = new QComboBox(this);
+ unitsComboBox_->insertItem(Units_px, "px");
+ unitsComboBox_->insertItem(Units_pt, "pt");
+
+ dpiLabel_ = new QLabel(tr("DPI "), this);
+ dpiLabel_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ dpiSpinBox_ = new QSpinBox(this);
+ dpiSpinBox_->setAlignment(Qt::AlignRight);
+ dpiSpinBox_->setRange(10, 600);
+ dpiLabel_->setBuddy(dpiSpinBox_);
+
+ zoomLabel_ = new QLabel(tr("Zoom Factor"), this);
+ zoomLabel_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
+ zoomSpinBox_ = new ZoomSpinBox(this);
+ zoomSpinBox_->setAlignment(Qt::AlignRight);
+ zoomSpinBox_->setRange(1, 1000 - 1000 % 64);
+ zoomSpinBox_->setKeyboardTracking(false);
+ zoomLabel_->setBuddy(zoomSpinBox_);
+
+ centerGridButton_ = new QPushButton("Go Back to Grid Center", this);
+
+ showBitmapCheckBox_ = new QCheckBox(tr("Show Bitmap"), this);
+ showPointsCheckBox_ = new QCheckBox(tr("Show Points"), this);
+ showPointNumbersCheckBox_ = new QCheckBox(tr("Show Point Numbers"), this);
+ showOutlinesCheckBox_ = new QCheckBox(tr("Show Outlines"), this);
+
+ sizeLayout_ = new QHBoxLayout;
+ sizeLayout_->addStretch(2);
+ sizeLayout_->addWidget(sizeLabel_);
+ sizeLayout_->addWidget(sizeDoubleSpinBox_);
+ sizeLayout_->addWidget(unitsComboBox_);
+ sizeLayout_->addStretch(1);
+ sizeLayout_->addWidget(dpiLabel_);
+ sizeLayout_->addWidget(dpiSpinBox_);
+ sizeLayout_->addStretch(1);
+ sizeLayout_->addWidget(zoomLabel_);
+ sizeLayout_->addWidget(zoomSpinBox_);
+ sizeLayout_->addStretch(1);
+ sizeLayout_->addWidget(centerGridButton_);
+ sizeLayout_->addStretch(2);
+
+ checkBoxesLayout_ = new QHBoxLayout;
+ checkBoxesLayout_->setSpacing(10);
+ checkBoxesLayout_->addWidget(showBitmapCheckBox_);
+ checkBoxesLayout_->addWidget(showPointsCheckBox_);
+ checkBoxesLayout_->addWidget(showPointNumbersCheckBox_);
+ checkBoxesLayout_->addWidget(showOutlinesCheckBox_);
+
+ glyphOverlayIndexLayout_ = new QHBoxLayout;
+ glyphOverlayIndexLayout_->addWidget(glyphIndexLabel_);
+ glyphOverlayIndexLayout_->addWidget(glyphNameLabel_);
+ glyphOverlayLayout_ = new QGridLayout;
+ glyphOverlayLayout_->addWidget(mouseUsageHint_, 0, 0,
+ Qt::AlignTop | Qt::AlignLeft);
+ glyphOverlayLayout_->addLayout(glyphOverlayIndexLayout_, 0, 1,
+ Qt::AlignTop | Qt::AlignRight);
+ glyphView_->setLayout(glyphOverlayLayout_);
+
+ mainLayout_ = new QVBoxLayout;
+ mainLayout_->addWidget(glyphView_);
+ mainLayout_->addWidget(indexSelector_);
+ mainLayout_->addSpacing(10); // XXX px
+ mainLayout_->addLayout(sizeLayout_);
+ mainLayout_->addLayout(checkBoxesLayout_);
+ mainLayout_->addSpacing(10); // XXX px
+
+ setLayout(mainLayout_);
+}
+
+
+void
+SingularTab::createConnections()
+{
+ connect(indexSelector_, &GlyphIndexSelector::currentIndexChanged,
+ this, &SingularTab::setGlyphIndex);
+ connect(sizeDoubleSpinBox_,
QOverload<double>::of(&QDoubleSpinBox::valueChanged),
+ this, &SingularTab::drawGlyph);
+ connect(unitsComboBox_, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, &SingularTab::checkUnits);
+ connect(dpiSpinBox_, QOverload<int>::of(&QSpinBox::valueChanged),
+ this, &SingularTab::drawGlyph);
+
+ connect(zoomSpinBox_, QOverload<int>::of(&QSpinBox::valueChanged),
+ this, &SingularTab::zoom);
+ connect(glyphView_, &QGraphicsViewx::shiftWheelEvent,
+ this, &SingularTab::wheelResize);
+ connect(glyphView_, &QGraphicsViewx::ctrlWheelEvent,
+ this, &SingularTab::wheelZoom);
+ connect(glyphView_->horizontalScrollBar(), &QScrollBar::valueChanged,
+ this, &SingularTab::updateGrid);
+ connect(glyphView_->verticalScrollBar(), &QScrollBar::valueChanged,
+ this, &SingularTab::updateGrid);
+
+ connect(centerGridButton_, &QPushButton::clicked,
+ this, &SingularTab::backToCenter);
+
+ connect(showBitmapCheckBox_, &QCheckBox::clicked,
+ this, &SingularTab::drawGlyph);
+ connect(showPointsCheckBox_, &QCheckBox::clicked,
+ this, &SingularTab::checkShowPoints);
+ connect(showPointNumbersCheckBox_, &QCheckBox::clicked,
+ this, &SingularTab::drawGlyph);
+ connect(showOutlinesCheckBox_, &QCheckBox::clicked,
+ this, &SingularTab::drawGlyph);
+}
+
+
+void
+SingularTab::setGraphicsDefaults()
+{
+ // color tables (with suitable opacity values) for converting
+ // FreeType's pixmaps to something Qt understands
+ monoColorTable_.append(QColor(Qt::transparent).rgba());
+ monoColorTable_.append(QColor(Qt::black).rgba());
+
+ for (int i = 0xFF; i >= 0; i--)
+ grayColorTable_.append(qRgba(i, i, i, 0xFF - i));
+
+ // XXX make this user-configurable
+
+ axisPen_.setColor(Qt::black);
+ axisPen_.setWidth(0);
+ blueZonePen_.setColor(QColor(64, 64, 255, 64)); // light blue
+ blueZonePen_.setWidth(0);
+ gridPen_.setColor(Qt::lightGray);
+ gridPen_.setWidth(0);
+ offPen_.setColor(Qt::darkGreen);
+ offPen_.setWidth(3);
+ onPen_.setColor(Qt::red);
+ onPen_.setWidth(3);
+ outlinePen_.setColor(Qt::red);
+ outlinePen_.setWidth(0);
+ segmentPen_.setColor(QColor(64, 255, 128, 64)); // light green
+ segmentPen_.setWidth(0);
+}
+
+
+void
+SingularTab::repaint()
+{
+ drawGlyph();
+}
+
+
+void
+SingularTab::reloadFont()
+{
+ currentGlyphCount_ = engine_->currentFontNumberOfGlyphs();
+ indexSelector_->setMin(0);
+ indexSelector_->setMax(currentGlyphCount_);
+ indexSelector_->setCurrentIndex(indexSelector_->getCurrentIndex(), true);
+ drawGlyph();
+}
+
+
+void
+SingularTab::syncSettings()
+{
+ // Spinbox value cannot become negative
+ engine_->setDPI(static_cast<unsigned int>(dpiSpinBox_->value()));
+
+ if (unitsComboBox_->currentIndex() == Units_px)
+ engine_->setSizeByPixel(sizeDoubleSpinBox_->value());
+ else
+ engine_->setSizeByPoint(sizeDoubleSpinBox_->value());
+}
+
+
+void
+SingularTab::setDefaults()
+{
+ currentGlyphIndex_ = 0;
+
+ sizeDoubleSpinBox_->setValue(20);
+ dpiSpinBox_->setValue(96);
+ zoomSpinBox_->setValue(20);
+ showBitmapCheckBox_->setChecked(true);
+ showOutlinesCheckBox_->setChecked(true);
+
+ checkUnits();
+ indexSelector_->setCurrentIndex(indexSelector_->getCurrentIndex(), true);
+ zoom();
+}
+
+
+// end of singular.cpp
diff --git a/src/ftinspect/panels/singular.hpp
b/src/ftinspect/panels/singular.hpp
new file mode 100644
index 0000000..e1b1c80
--- /dev/null
+++ b/src/ftinspect/panels/singular.hpp
@@ -0,0 +1,121 @@
+// singular.hpp
+
+// Copyright (C) 2022 by Charlie Jiang.
+
+#pragma once
+
+#include "abstracttab.hpp"
+#include "../widgets/customwidgets.hpp"
+#include "../widgets/glyphindexselector.hpp"
+#include "../rendering/glyphbitmap.hpp"
+#include "../rendering/glyphoutline.hpp"
+#include "../rendering/glyphpointnumbers.hpp"
+#include "../rendering/glyphpoints.hpp"
+#include "../rendering/grid.hpp"
+#include "../engine/engine.hpp"
+#include "../models/ttsettingscomboboxmodel.hpp"
+
+#include <QWidget>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QGraphicsScene>
+#include <QGraphicsView>
+#include <QScrollBar>
+#include <QLabel>
+#include <QComboBox>
+#include <QPen>
+#include <QCheckBox>
+#include <QVector>
+#include <QGridLayout>
+#include <QBoxLayout>
+
+class SingularTab
+: public QWidget, public AbstractTab
+{
+ Q_OBJECT
+public:
+ SingularTab(QWidget* parent, Engine* engine);
+ virtual ~SingularTab();
+
+ void repaint();
+ void reloadFont();
+ void syncSettings();
+ void setDefaults();
+
+private slots:
+ void setGlyphIndex(int);
+ void drawGlyph();
+
+ void checkUnits();
+ void checkShowPoints();
+
+ void zoom();
+ void backToCenter();
+ void wheelZoom(QWheelEvent* event);
+ void wheelResize(QWheelEvent* event);
+
+private:
+ int currentGlyphIndex_;
+ int currentGlyphCount_;
+
+ Engine* engine_;
+
+ QGraphicsScene* glyphScene_;
+ QGraphicsViewx* glyphView_;
+
+ GlyphOutline* currentGlyphOutlineItem_;
+ GlyphPoints* currentGlyphPointsItem_;
+ GlyphPointNumbers* currentGlyphPointNumbersItem_;
+ GlyphBitmap* currentGlyphBitmapItem_;
+ Grid* gridItem_ = NULL;
+ QLabel* mouseUsageHint_;
+
+ GlyphIndexSelector* indexSelector_;
+ QLabel* dpiLabel_;
+ QLabel* sizeLabel_;
+ QLabel* zoomLabel_;
+ QSpinBox* dpiSpinBox_;
+ ZoomSpinBox* zoomSpinBox_;
+ QComboBox* unitsComboBox_;
+ QDoubleSpinBox* sizeDoubleSpinBox_;
+ QPushButton* centerGridButton_;
+
+ QLabel* glyphIndexLabel_;
+ QLabel* glyphNameLabel_;
+
+ QCheckBox* showBitmapCheckBox_;
+ QCheckBox* showOutlinesCheckBox_;
+ QCheckBox* showPointNumbersCheckBox_;
+ QCheckBox* showPointsCheckBox_;
+
+ QVBoxLayout* mainLayout_;
+ QHBoxLayout* checkBoxesLayout_;
+ QHBoxLayout* sizeLayout_;
+ QGridLayout* glyphOverlayLayout_;
+ QHBoxLayout* glyphOverlayIndexLayout_;
+
+ QPen axisPen_;
+ QPen blueZonePen_;
+ QPen gridPen_;
+ QPen offPen_;
+ QPen onPen_;
+ QPen outlinePen_;
+ QPen segmentPen_;
+
+ QVector<QRgb> grayColorTable_;
+ QVector<QRgb> monoColorTable_;
+
+ enum Units
+ {
+ Units_px,
+ Units_pt
+ };
+
+ void createLayout();
+ void createConnections();
+ void setGraphicsDefaults();
+
+ void updateGrid();
+};
+
+// end of singular.hpp
diff --git a/src/ftinspect/widgets/customwidgets.cpp
b/src/ftinspect/widgets/customwidgets.cpp
index 893fe0d..85d0f32 100644
--- a/src/ftinspect/widgets/customwidgets.cpp
+++ b/src/ftinspect/widgets/customwidgets.cpp
@@ -71,7 +71,7 @@ QGraphicsViewx::resizeEvent(QResizeEvent* event)
// so that we can do that symmetrically
int
-QSpinBoxx::valueFromText(const QString& text) const
+ZoomSpinBox::valueFromText(const QString& text) const
{
int val = QSpinBox::valueFromText(text);
@@ -92,14 +92,14 @@ QSpinBoxx::valueFromText(const QString& text) const
}
-QSpinBoxx::QSpinBoxx(QWidget* parent)
+ZoomSpinBox::ZoomSpinBox(QWidget* parent)
: QSpinBox(parent)
{
}
void
-QSpinBoxx::stepBy(int steps)
+ZoomSpinBox::stepBy(int steps)
{
int val = value();
diff --git a/src/ftinspect/widgets/customwidgets.hpp
b/src/ftinspect/widgets/customwidgets.hpp
index 4c51f63..87296b8 100644
--- a/src/ftinspect/widgets/customwidgets.hpp
+++ b/src/ftinspect/widgets/customwidgets.hpp
@@ -43,13 +43,13 @@ private:
// we want to have our own `stepBy' function for the zoom spin box
-class QSpinBoxx
+class ZoomSpinBox
: public QSpinBox
{
Q_OBJECT
public:
- QSpinBoxx(QWidget* parent);
+ ZoomSpinBox(QWidget* parent);
void stepBy(int val);
int valueFromText(const QString& text) const;
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2-demos] gsoc-2022-chariri-2 e76572b 20/30: [ftinspect] Move out `ftgrid` out from `MainGUI` to a new tabbed pane.,
Werner Lemberg <=