[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2-demos] master b76a242 4/4: [ftinspect] Display glyph point nu
From: |
Werner LEMBERG |
Subject: |
[freetype2-demos] master b76a242 4/4: [ftinspect] Display glyph point numbers. |
Date: |
Tue, 10 May 2016 03:20:41 +0000 (UTC) |
branch: master
commit b76a242169fc72370434bf6e533312a473273cf5
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>
[ftinspect] Display glyph point numbers.
* src/ftinspect.cpp (GlyphPointNumbers::GlyphPointNumbers,
GlyphPointNumbers::boundRect, GlyphPointNumbers::paint): New methods
for constructing the set of glyph point numbers.
(MainGUI::drawGlyph): Honor `glyph point indices' check box.
(MainGUI::createLayout): Updated.
(MainGUI::createConnections): Handle `showPointIndicesCheckBox'.
* src/ftinspect.h (GlyphPoints): New class, derived from
`QGraphicsItem'.
(MainGUI): Mew member `currentGlyphPointNumbersItem'.
Updated.
---
ChangeLog | 16 +++++
src/ftinspect.cpp | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/ftinspect.h | 28 +++++++-
3 files changed, 247 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f413870..b8af160 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2016-05-10 Werner Lemberg <address@hidden>
+
+ [ftinspect] Display glyph point numbers.
+
+ * src/ftinspect.cpp (GlyphPointNumbers::GlyphPointNumbers,
+ GlyphPointNumbers::boundRect, GlyphPointNumbers::paint): New methods
+ for constructing the set of glyph point numbers.
+ (MainGUI::drawGlyph): Honor `glyph point indices' check box.
+ (MainGUI::createLayout): Updated.
+ (MainGUI::createConnections): Handle `showPointIndicesCheckBox'.
+
+ * src/ftinspect.h (GlyphPoints): New class, derived from
+ `QGraphicsItem'.
+ (MainGUI): Mew member `currentGlyphPointNumbersItem'.
+ Updated.
+
2016-05-09 Werner Lemberg <address@hidden>
[ftinspect] Display glyph points.
diff --git a/src/ftinspect.cpp b/src/ftinspect.cpp
index b47dd9e..8e2853d 100644
--- a/src/ftinspect.cpp
+++ b/src/ftinspect.cpp
@@ -743,6 +743,193 @@ GlyphPoints::paint(QPainter* painter,
}
+GlyphPointNumbers::GlyphPointNumbers(const QPen& onP,
+ const QPen& offP,
+ FT_Outline* outln)
+: onPen(onP),
+ offPen(offP),
+ outline(outln)
+{
+ FT_BBox cbox;
+
+ FT_Outline_Get_CBox(outline, &cbox);
+
+ // XXX fix bRect size
+ bRect.setCoords(qreal(cbox.xMin) / 64,
+ -qreal(cbox.yMax) / 64,
+ qreal(cbox.xMax) / 64,
+ -qreal(cbox.yMin) / 64);
+}
+
+
+QRectF
+GlyphPointNumbers::boundingRect() const
+{
+ return bRect;
+}
+
+
+void
+GlyphPointNumbers::paint(QPainter* painter,
+ const QStyleOptionGraphicsItem* option,
+ QWidget*)
+{
+ const qreal lod = option->levelOfDetailFromTransform(
+ painter->worldTransform());
+
+ // don't draw point numbers if magnification is too small
+ if (lod >= 10)
+ {
+ QFont font = painter->font();
+
+ // the following doesn't work correctly with scaling;
+ // it seems that Qt doesn't allow arbitrarily small font sizes
+ // that get magnified later on
+#if 0
+ // we want the same text size regardless of the scaling
+ font.setPointSizeF(font.pointSizeF() / lod);
+ painter->setFont(font);
+#else
+ font.setPointSizeF(font.pointSizeF() * 3 / 4);
+ painter->setFont(font);
+
+ QBrush onBrush(onPen.color());
+ QBrush offBrush(offPen.color());
+
+ painter->scale(1 / lod, 1 / lod);
+#endif
+
+ FT_Vector* points = outline->points;
+ FT_Short* contours = outline->contours;
+ char* tags = outline->tags;
+
+ QVector2D octants[8] = { QVector2D(1, 0),
+ QVector2D(0.707, -0.707),
+ QVector2D(0, -1),
+ QVector2D(-0.707, -0.707),
+ QVector2D(-1, 0),
+ QVector2D(-0.707, 0.707),
+ QVector2D(0, 1),
+ QVector2D(0.707, 0.707) };
+
+
+ int ptIdx = 0;
+ for (int contIdx = 0; contIdx < outline->n_contours; contIdx++ )
+ {
+ for (;;)
+ {
+ short prevIdx, nextIdx;
+
+ // find previous and next point in outline
+ if (contIdx == 0)
+ {
+ if (contours[contIdx] == 0)
+ {
+ prevIdx = 0;
+ nextIdx = 0;
+ }
+ else
+ {
+ prevIdx = ptIdx > 0 ? ptIdx - 1
+ : contours[contIdx];
+ nextIdx = ptIdx < contours[contIdx] ? ptIdx + 1
+ : 0;
+ }
+ }
+ else
+ {
+ prevIdx = ptIdx > (contours[contIdx - 1] + 1) ? ptIdx - 1
+ : contours[contIdx];
+ nextIdx = ptIdx < contours[contIdx] ? ptIdx + 1
+ : contours[contIdx - 1] + 1;
+ }
+
+ // get vectors to previous and next point and normalize them;
+ QVector2D in(qreal(points[prevIdx].x - points[ptIdx].x) / 64,
+ -qreal(points[prevIdx].y - points[ptIdx].y) / 64);
+ QVector2D out(qreal(points[nextIdx].x - points[ptIdx].x) / 64,
+ -qreal(points[nextIdx].y - points[ptIdx].y) / 64);
+
+ in = in.normalized();
+ out = out.normalized();
+
+ QVector2D middle = in + out;
+ // check whether vector is very small, using a threshold of 1/8px
+ if (qAbs(middle.x()) < 1.0 / 8
+ && qAbs(middle.y()) < 1.0 / 8)
+ {
+ // in case of vectors in almost exactly opposite directions,
+ // use a vector orthogonal to them
+ middle.setX(out.y());
+ middle.setY(-out.x());
+
+ if (qAbs(middle.x()) < 1.0 / 8
+ && qAbs(middle.y()) < 1.0 / 8)
+ {
+ // use direction based on point index for the offset
+ // if we still don't have a good value
+ middle = octants[ptIdx % 8];
+ }
+ }
+
+ // normalize `middle' vector (which is never zero),
+ // then multiply by 8 to get some distance between
+ // the point and the number
+ middle = middle.normalized() * 8;
+
+ // we now position the point number in the opposite
+ // direction of the `middle' vector,
+ QString number = QString::number(ptIdx);
+
+#if 0
+ // this fails, see comment above
+ int size = 10000;
+ qreal x = qreal(points[ptIdx].x) / 64 - middle.x() / lod;
+ qreal y = -qreal(points[ptIdx].y) / 64 - middle.y() / lod;
+ QPointF corner(x, y);
+ int flags = middle.x() > 0 ? Qt::AlignRight
+ : Qt::AlignLeft;
+ if (flags == Qt::AlignRight)
+ corner.rx() -= size;
+ QRectF posRect(corner, QSizeF(size, size));
+
+ if (tags[ptIdx] & FT_CURVE_TAG_ON)
+ painter->setPen(onPen);
+ else
+ painter->setPen(offPen);
+
+ painter->drawText(posRect, flags, number);
+#else
+ // convert text string to a path object
+ QPainterPath path;
+ path.addText(QPointF(0, 0), font, number);
+ QRectF ctrlPtRect = path.controlPointRect();
+
+ qreal x = qreal(points[ptIdx].x) / 64 * lod - middle.x();
+ qreal y = -qreal(points[ptIdx].y) / 64 * lod - middle.y();
+
+ qreal heuristicOffset = 2;
+ if (middle.x() > 0)
+ path.translate(x - ctrlPtRect.width() - heuristicOffset,
+ y + ctrlPtRect.height() / 2);
+ else
+ path.translate(x,
+ y + ctrlPtRect.height() / 2);
+
+ painter->fillPath(path,
+ tags[ptIdx] & FT_CURVE_TAG_ON ? onBrush
+ : offBrush);
+#endif
+
+ ptIdx++;
+ if (ptIdx > contours[contIdx])
+ break;
+ }
+ }
+ }
+}
+
+
MainGUI::MainGUI()
{
engine = NULL;
@@ -1344,6 +1531,14 @@ MainGUI::drawGlyph()
currentGlyphPointsItem = NULL;
}
+ if (currentGlyphPointNumbersItem)
+ {
+ glyphScene->removeItem(currentGlyphPointNumbersItem);
+ delete currentGlyphPointNumbersItem;
+
+ currentGlyphPointNumbersItem = NULL;
+ }
+
if (currentFontIndex >= 0
&& currentFaceIndex >= 0)
{
@@ -1360,6 +1555,14 @@ MainGUI::drawGlyph()
{
currentGlyphPointsItem = new GlyphPoints(onPen, offPen, outline);
glyphScene->addItem(currentGlyphPointsItem);
+
+ if (showPointIndicesCheckBox->isChecked())
+ {
+ currentGlyphPointNumbersItem = new GlyphPointNumbers(onPen,
+ offPen,
+ outline);
+ glyphScene->addItem(currentGlyphPointNumbersItem);
+ }
}
}
}
@@ -1559,6 +1762,7 @@ MainGUI::createLayout()
currentGlyphOutlineItem = NULL;
currentGlyphPointsItem = NULL;
+ currentGlyphPointNumbersItem = NULL;
drawGlyph();
glyphView = new QGraphicsView;
@@ -1696,6 +1900,8 @@ MainGUI::createConnections()
SLOT(checkAutoHinting()));
connect(showPointsCheckBox, SIGNAL(clicked()),
SLOT(checkShowPoints()));
+ connect(showPointIndicesCheckBox, SIGNAL(clicked()),
+ SLOT(drawGlyph()));
connect(showOutlinesCheckBox, SIGNAL(clicked()),
SLOT(drawGlyph()));
diff --git a/src/ftinspect.h b/src/ftinspect.h
index c0034b6..1cadbe6 100644
--- a/src/ftinspect.h
+++ b/src/ftinspect.h
@@ -49,6 +49,7 @@
#include <QTabWidget>
#include <QTransform>
#include <QVariant>
+#include <QVector2D>
#include <QVBoxLayout>
#include <QWidget>
@@ -208,6 +209,26 @@ private:
};
+class GlyphPointNumbers
+: public QGraphicsItem
+{
+public:
+ GlyphPointNumbers(const QPen&,
+ const QPen&,
+ FT_Outline*);
+ QRectF boundingRect() const;
+ void paint(QPainter*,
+ const QStyleOptionGraphicsItem*,
+ QWidget*);
+
+private:
+ QPen onPen;
+ QPen offPen;
+ FT_Outline* outline;
+ QRectF bRect;
+};
+
+
// we want to grey out items in a combo box;
// since Qt doesn't provide a function for this we derive a class
class QComboBoxx
@@ -292,6 +313,10 @@ private:
QHash<FaceID, int> faceIDHash;
// layout related stuff
+ GlyphOutline *currentGlyphOutlineItem;
+ GlyphPoints *currentGlyphPointsItem;
+ GlyphPointNumbers *currentGlyphPointNumbersItem;
+
QAction *aboutAct;
QAction *aboutQtAct;
QAction *closeFontAct;
@@ -317,9 +342,6 @@ private:
QDoubleSpinBox *sizeDoubleSpinBox;
- QGraphicsItem *currentGlyphOutlineItem;
- QGraphicsItem *currentGlyphPointsItem;
-
QGraphicsScene *glyphScene;
QGraphicsView *glyphView;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2-demos] master b76a242 4/4: [ftinspect] Display glyph point numbers.,
Werner LEMBERG <=