freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2-demos] master 4594b76 1/4: [ftinspect] Display glyphs outline


From: Werner LEMBERG
Subject: [freetype2-demos] master 4594b76 1/4: [ftinspect] Display glyphs outlines.
Date: Tue, 10 May 2016 03:20:41 +0000 (UTC)

branch: master
commit 4594b76a9e83d8d76b7457e3e9a5bef67d1c08fe
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [ftinspect] Display glyphs outlines.
    
    * src/ftinspect.cpp (Engine::loadGlyph): New method.
    (moveTo, lineTo, conicTo, cubicTo): New wrapper functions for
    `QPainterPath' methods.
    (outlineFuncs): New structure, used as an interface to
    `FT_Outline_Decompose'.
    (Glyph::Glyph, Glyph::boundRect, Glyph::paint): New methods for
    constructing a glyph object.
    (MainGUI::drawGlyphOutline): New method.
    (MainGUI::showFont, MainGUI::checkUnits, MainGUI::adjustGlyphIndex,
    MainGUI::createLayout): Updated.
    (MainGUI::createConnections): Handle `sizeDoubleSpinBox' and
    `dpiSpinBox'.
    
    * src/ftinspect.h (Engine): Updated.
    (Glyph): New class, derived from `QGraphicsItem'.
    (MainGUI): New member `currentGlyphOutlineItem'.
    Updated.
---
 ChangeLog         |   24 ++++++-
 src/ftinspect.cpp |  187 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ftinspect.h   |   24 +++++++
 3 files changed, 234 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index cbc33f5..39976cf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
 2016-05-09  Werner Lemberg  <address@hidden>
 
+       [ftinspect] Display glyphs outlines.
+
+       * src/ftinspect.cpp (Engine::loadGlyph): New method.
+       (moveTo, lineTo, conicTo, cubicTo): New wrapper functions for
+       `QPainterPath' methods.
+       (outlineFuncs): New structure, used as an interface to
+       `FT_Outline_Decompose'.
+       (Glyph::Glyph, Glyph::boundRect, Glyph::paint): New methods for
+       constructing a glyph object.
+       (MainGUI::drawGlyphOutline): New method.
+       (MainGUI::showFont, MainGUI::checkUnits, MainGUI::adjustGlyphIndex,
+       MainGUI::createLayout): Updated.
+       (MainGUI::createConnections): Handle `sizeDoubleSpinBox' and
+       `dpiSpinBox'.
+
+       * src/ftinspect.h (Engine): Updated.
+       (Glyph): New class, derived from `QGraphicsItem'.
+       (MainGUI): New member `currentGlyphOutlineItem'.
+       Updated.
+
+2016-05-09  Werner Lemberg  <address@hidden>
+
        [ftinspect] Fix a bunch of glitches.
 
        * src/ftinspect.cpp (FaceID::FaceID): Initialize members with `-1'.
@@ -21,7 +43,7 @@
 
        [ftinspect] Display axes.
 
-       & src/ftinspect.cpp (Grid::Grid): Add second parameter to pass axis
+       * src/ftinspect.cpp (Grid::Grid): Add second parameter to pass axis
        pen.
        (Grid::paint): Add axes.
        Increase grid size.
diff --git a/src/ftinspect.cpp b/src/ftinspect.cpp
index b0caa62..184fbe3 100644
--- a/src/ftinspect.cpp
+++ b/src/ftinspect.cpp
@@ -348,6 +348,37 @@ Engine::removeFont(int fontIndex,
 }
 
 
+FT_Outline*
+Engine::loadGlyph(int glyphIndex)
+{
+  update();
+
+  FT_Glyph glyph;
+
+  // XXX handle bitmap fonts
+
+  // the `scaler' object is set up by the
+  // `update' and `loadFont' methods
+  if (FTC_ImageCache_LookupScaler(imageCache,
+                                  &scaler,
+                                  loadFlags | FT_LOAD_NO_BITMAP,
+                                  glyphIndex,
+                                  &glyph,
+                                  NULL))
+  {
+    // XXX error handling?
+    return NULL;
+  }
+
+  if (glyph->format != FT_GLYPH_FORMAT_OUTLINE)
+    return NULL;
+
+  FT_OutlineGlyph outlineGlyph = reinterpret_cast<FT_OutlineGlyph>(glyph);
+
+  return &outlineGlyph->outline;
+}
+
+
 void
 Engine::update()
 {
@@ -504,6 +535,120 @@ Grid::paint(QPainter* painter,
 }
 
 
+extern "C" {
+
+// vertical font coordinates are bottom-up,
+// while Qt uses top-down
+
+static int
+moveTo(const FT_Vector* to,
+       void* user)
+{
+  QPainterPath* path = static_cast<QPainterPath*>(user);
+
+  path->moveTo(qreal(to->x) / 64,
+               -qreal(to->y) / 64);
+
+  return 0;
+}
+
+
+static int
+lineTo(const FT_Vector* to,
+       void* user)
+{
+  QPainterPath* path = static_cast<QPainterPath*>(user);
+
+  path->lineTo(qreal(to->x) / 64,
+               -qreal(to->y) / 64);
+
+  return 0;
+}
+
+
+static int
+conicTo(const FT_Vector* control,
+        const FT_Vector* to,
+        void* user)
+{
+  QPainterPath* path = static_cast<QPainterPath*>(user);
+
+  path->quadTo(qreal(control->x) / 64,
+               -qreal(control->y) / 64,
+               qreal(to->x) / 64,
+               -qreal(to->y) / 64);
+
+  return 0;
+}
+
+
+static int
+cubicTo(const FT_Vector* control1,
+        const FT_Vector* control2,
+        const FT_Vector* to,
+        void* user)
+{
+  QPainterPath* path = static_cast<QPainterPath*>(user);
+
+  path->cubicTo(qreal(control1->x) / 64,
+                -qreal(control1->y) / 64,
+                qreal(control2->x) / 64,
+                -qreal(control2->y) / 64,
+                qreal(to->x) / 64,
+                -qreal(to->y) / 64);
+
+  return 0;
+}
+
+
+static FT_Outline_Funcs outlineFuncs =
+{
+  moveTo,
+  lineTo,
+  conicTo,
+  cubicTo,
+  0, // no shift
+  0  // no delta
+};
+
+} // extern "C"
+
+
+Glyph::Glyph(const QPen& outlineP,
+             FT_Outline* outln)
+: outlinePen(outlineP),
+  outline(outln)
+{
+  FT_BBox cbox;
+
+  FT_Outline_Get_CBox(outline, &cbox);
+
+  bRect.setCoords(qreal(cbox.xMin) / 64, -qreal(cbox.yMax) / 64,
+                  qreal(cbox.xMax) / 64, -qreal(cbox.yMin) / 64);
+}
+
+
+QRectF
+Glyph::boundingRect() const
+{
+  return bRect;
+}
+
+
+void
+Glyph::paint(QPainter* painter,
+             const QStyleOptionGraphicsItem*,
+             QWidget*)
+{
+  painter->setPen(outlinePen);
+
+  QPainterPath path;
+  FT_Outline_Decompose(outline, &outlineFuncs, &path);
+
+  painter->drawPath(path);
+}
+
+
 MainGUI::MainGUI()
 {
   engine = NULL;
@@ -716,6 +861,8 @@ MainGUI::showFont()
   checkCurrentFontIndex();
   checkCurrentFaceIndex();
   checkCurrentInstanceIndex();
+
+  drawGlyphOutline();
 }
 
 
@@ -842,6 +989,8 @@ MainGUI::checkUnits()
     dpiLabel->setEnabled(true);
     dpiSpinBox->setEnabled(true);
   }
+
+  drawGlyphOutline();
 }
 
 
@@ -857,6 +1006,8 @@ MainGUI::adjustGlyphIndex(int delta)
     currentGlyphIndex = 0;
   else if (currentGlyphIndex >= currentNumGlyphs)
     currentGlyphIndex = currentNumGlyphs - 1;
+
+  drawGlyphOutline();
 }
 
 
@@ -1073,6 +1224,35 @@ MainGUI::setGraphicsDefaults()
 }
 
 
+void
+MainGUI::drawGlyphOutline()
+{
+  if (!engine)
+    return;
+
+  if (currentGlyphOutlineItem)
+  {
+    glyphScene->removeItem(currentGlyphOutlineItem);
+    delete currentGlyphOutlineItem;
+
+    currentGlyphOutlineItem = NULL;
+  }
+
+  if (currentFontIndex >= 0
+      && currentFaceIndex >= 0)
+  {
+    FT_Outline* outline = engine->loadGlyph(currentGlyphIndex);
+    if (outline)
+    {
+      currentGlyphOutlineItem = new Glyph(outlinePen, outline);
+      glyphScene->addItem(currentGlyphOutlineItem);
+    }
+  }
+
+  glyphScene->update();
+}
+
+
 // XXX distances are specified in pixels,
 //     making the layout dependent on the output device resolution
 void
@@ -1262,6 +1442,9 @@ MainGUI::createLayout()
   glyphScene = new QGraphicsScene;
   glyphScene->addItem(new Grid(gridPen, axisPen));
 
+  currentGlyphOutlineItem = NULL;
+  drawGlyphOutline();
+
   glyphView = new QGraphicsView;
   glyphView->setRenderHint(QPainter::Antialiasing, true);
   glyphView->setDragMode(QGraphicsView::ScrollHandDrag);
@@ -1398,8 +1581,12 @@ MainGUI::createConnections()
   connect(showPointsCheckBox, SIGNAL(clicked()),
           SLOT(checkShowPoints()));
 
+  connect(sizeDoubleSpinBox, SIGNAL(valueChanged(double)),
+          SLOT(drawGlyphOutline()));
   connect(unitsComboBox, SIGNAL(currentIndexChanged(int)),
           SLOT(checkUnits()));
+  connect(dpiSpinBox, SIGNAL(valueChanged(int)),
+          SLOT(drawGlyphOutline()));
 
   connect(zoomSpinBox, SIGNAL(valueChanged(int)),
           SLOT(zoom()));
diff --git a/src/ftinspect.h b/src/ftinspect.h
index e401700..36164cc 100644
--- a/src/ftinspect.h
+++ b/src/ftinspect.h
@@ -9,6 +9,7 @@
 #include FT_CFF_DRIVER_H
 #include FT_LCD_FILTER_H
 #include FT_MODULE_H
+#include FT_OUTLINE_H
 #include FT_TRUETYPE_DRIVER_H
 
 #include <QAction>
@@ -34,6 +35,7 @@
 #include <QMenu>
 #include <QMenuBar>
 #include <QMessageBox>
+#include <QPainterPath>
 #include <QPen>
 #include <QPushButton>
 #include <QSettings>
@@ -105,6 +107,7 @@ public:
   int numFaces(int);
   int numInstances(int, int);
   int loadFont(int, int, int); // returns number of glyphs
+  FT_Outline* loadGlyph(int);
   void removeFont(int, int, int);
   void update();
 
@@ -170,6 +173,24 @@ private:
 };
 
 
+class Glyph
+: public QGraphicsItem
+{
+public:
+  Glyph(const QPen&,
+        FT_Outline*);
+  QRectF boundingRect() const;
+  void paint(QPainter*,
+             const QStyleOptionGraphicsItem*,
+             QWidget*);
+
+private:
+  QPen outlinePen;
+  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
@@ -229,6 +250,7 @@ private slots:
   void checkShowPoints();
   void checkUnits();
   void closeFont();
+  void drawGlyphOutline();
   void loadFonts();
   void nextFace();
   void nextFont();
@@ -278,6 +300,8 @@ private:
 
   QDoubleSpinBox *sizeDoubleSpinBox;
 
+  QGraphicsItem *currentGlyphOutlineItem;
+
   QGraphicsScene *glyphScene;
   QGraphicsView *glyphView;
 



reply via email to

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