freetype-commit
[Top][All Lists]
Advanced

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

[freetype2-demos] veeki-gsoc-experimental 8e12b4a: Added kerning and fix


From: Veeki Yadav
Subject: [freetype2-demos] veeki-gsoc-experimental 8e12b4a: Added kerning and fixed cache error
Date: Thu, 18 Jul 2019 23:51:26 -0400 (EDT)

branch: veeki-gsoc-experimental
commit 8e12b4a2373ad241b1b04317ed4821fed7fcd0d2
Author: gevic <address@hidden>
Commit: gevic <address@hidden>

    Added kerning and fixed cache error
---
 src/ftinspect/engine/engine.cpp        |   2 +
 src/ftinspect/engine/engine.hpp        |   1 +
 src/ftinspect/ftinspect.pro            |   2 -
 src/ftinspect/maingui.cpp              | 124 +++++++++++--
 src/ftinspect/maingui.hpp              |  31 +++-
 src/ftinspect/rendering/comparator.cpp |  86 ---------
 src/ftinspect/rendering/comparator.hpp |  73 --------
 src/ftinspect/rendering/view.cpp       | 330 +++++++++++++++++++++++++++++----
 src/ftinspect/rendering/view.hpp       |   7 +-
 9 files changed, 434 insertions(+), 222 deletions(-)

diff --git a/src/ftinspect/engine/engine.cpp b/src/ftinspect/engine/engine.cpp
index b8c751d..bd2b39c 100644
--- a/src/ftinspect/engine/engine.cpp
+++ b/src/ftinspect/engine/engine.cpp
@@ -160,6 +160,8 @@ Engine::Engine(MainGUI* g)
     // XXX error handling
   }
 
+  error = FTC_CMapCache_New(cacheManager, &cmap_cache );
+
   // query engines and check for alternatives
 
   // CFF
diff --git a/src/ftinspect/engine/engine.hpp b/src/ftinspect/engine/engine.hpp
index adf28b9..eb81939 100644
--- a/src/ftinspect/engine/engine.hpp
+++ b/src/ftinspect/engine/engine.hpp
@@ -100,6 +100,7 @@ private:
 
   FT_Library library;
   FTC_Manager cacheManager;
+  FTC_CMapCache cmap_cache;
   //FTC_ImageCache imageCache;
   FTC_SBitCache sbitsCache;
 
diff --git a/src/ftinspect/ftinspect.pro b/src/ftinspect/ftinspect.pro
index d0e6b44..19c6542 100644
--- a/src/ftinspect/ftinspect.pro
+++ b/src/ftinspect/ftinspect.pro
@@ -29,7 +29,6 @@ SOURCES += \
   rendering/glyphpointnumbers.cpp \
   rendering/glyphpoints.cpp \
   rendering/glyphsegment.cpp \
-  rendering/comparator.cpp \
   rendering/view.cpp \
   rendering/grid.cpp \
   widgets/qcomboboxx.cpp \
@@ -47,7 +46,6 @@ HEADERS += \
   rendering/glyphpoints.hpp \
   rendering/glyphsegment.hpp \
   rendering/view.hpp \
-  rendering/comparator.hpp \
   rendering/grid.hpp \
   widgets/qcomboboxx.hpp \
   widgets/qgraphicsviewx.hpp \
diff --git a/src/ftinspect/maingui.cpp b/src/ftinspect/maingui.cpp
index d115be3..c22e99c 100644
--- a/src/ftinspect/maingui.cpp
+++ b/src/ftinspect/maingui.cpp
@@ -442,13 +442,63 @@ MainGUI::checkRenderingMode()
   } else if (!(renderingModeComboBoxx->itemText(index).compare("Text String")))
   {
     render_mode = 4;
-  } else 
+  } else if (!(renderingModeComboBoxx->itemText(index).compare("Waterfall")))
   {
     render_mode = 5;
     glyphView->setDragMode(QGraphicsView::NoDrag);
-  } 
+  } else
+  {
+    render_mode = 6;
+  }
+  renderAll();
+}
+
+void
+MainGUI::checkKerningMode()
+{
+  int index = kerningModeComboBoxx->currentIndex();
+  kerningModeComboBoxx->setItemEnabled(index, true);
 
+  if (!(kerningModeComboBoxx->itemText(index).compare("No Kerning")))
+  {
+    kerning_mode = 0;
+  } else if (!(kerningModeComboBoxx->itemText(index).compare("Normal")))
+  {
+    kerning_mode = 1;
+  } else if (!(kerningModeComboBoxx->itemText(index).compare("Smart")))
+  {
+    kerning_mode = 2;
+  }
+  
+  render_mode = 6;
   renderAll();
+  renderingModeComboBoxx->setItemEnabled(5, true);
+}
+
+
+void
+MainGUI::checkKerningDegree()
+{
+  int index = kerningDegreeComboBoxx->currentIndex();
+  kerningDegreeComboBoxx->setItemEnabled(index, true);
+
+  if (!(kerningDegreeComboBoxx->itemText(index).compare("None")))
+  {
+    kerning_degree = 0;
+  } else if (!(kerningDegreeComboBoxx->itemText(index).compare("Light")))
+  {
+    kerning_degree = 1;
+  } else if (!(kerningDegreeComboBoxx->itemText(index).compare("Medium")))
+  {
+    kerning_degree = 2;
+  } else if (!(kerningDegreeComboBoxx->itemText(index).compare("Tight")))
+  {
+    kerning_degree = 3;
+  }
+
+  render_mode = 6;
+  renderAll();
+  renderingModeComboBoxx->setItemEnabled(5, true);
 }
 
 
@@ -550,8 +600,6 @@ MainGUI::renderAll()
   // Basic definition
   FT_Size size;
   FT_Face face;
-  FT_Color* palette;
-  FTC_CMapCache cmap_cache;
   FT_Error error;
 
   // Basic Initialization
@@ -561,10 +609,11 @@ MainGUI::renderAll()
   //error = FT_Set_Charmap( size->face, size->face->charmaps[0]);
   // chache manager
   FTC_Manager cacheManager = engine->cacheManager;
+  FTC_CMapCache cmap_cache = engine->cmap_cache;
   FTC_FaceID  face_id = engine->scaler.face_id;
   //face = size->face;
 
-  error = FTC_CMapCache_New(cacheManager, &cmap_cache );
+  
 
   if (currentGridItem)
   {
@@ -595,7 +644,9 @@ MainGUI::renderAll()
                                   x_factor,
                                   y_factor,
                                   slant_factor,
-                                  stroke_factor);
+                                  stroke_factor,
+                                  kerning_mode,
+                                  kerning_degree);
   glyphScene->addItem(currentRenderAllItem);
   zoomSpinBox->setValue(1);
 }
@@ -1058,28 +1109,45 @@ MainGUI::createLayout()
   renderingModeLabel = new QLabel(tr("Render Mode"));
   renderingModeLabel->setAlignment(Qt::AlignTop);
   renderingModeComboBoxx = new QComboBoxx;
-  renderingModeComboBoxx->insertItem(Normal,
-                                   tr("Normal"));
-  renderingModeComboBoxx->insertItem(Fancy,
-                                   tr("Fancy"));
-  renderingModeComboBoxx->insertItem(Stroked,
-                                   tr("Stroked"));
-  renderingModeComboBoxx->insertItem(Text_String,
-                                   tr("Text String"));
-  renderingModeComboBoxx->insertItem(Waterfall,
-                                   tr("Waterfall"));
+  renderingModeComboBoxx->insertItem(Normal, tr("Normal"));
+  renderingModeComboBoxx->insertItem(Fancy, tr("Fancy"));
+  renderingModeComboBoxx->insertItem(Stroked, tr("Stroked"));
+  renderingModeComboBoxx->insertItem(Text_String, tr("Text String"));
+  renderingModeComboBoxx->insertItem(Waterfall, tr("Waterfall"));
+  renderingModeComboBoxx->insertItem(Kerning_Comparison, tr("Kerning 
Comparison"));
   renderingModeLabel->setBuddy(renderingModeComboBoxx);
 
+  kerningModeLabel = new QLabel(tr("Kerning Mode"));
+  kerningModeLabel->setAlignment(Qt::AlignTop);
+  kerningModeComboBoxx = new QComboBoxx;
+  kerningModeComboBoxx->insertItem(KERNING_MODE_NONE, tr("No Kerning"));
+  kerningModeComboBoxx->insertItem(KERNING_MODE_NORMAL, tr("Normal"));
+  kerningModeComboBoxx->insertItem(KERNING_MODE_SMART, tr("Smart"));
+  kerningModeLabel->setBuddy(kerningModeComboBoxx);
+
+  kerningDegreeLabel = new QLabel(tr("Kerning Degree"));
+  kerningDegreeLabel->setAlignment(Qt::AlignTop);
+  kerningDegreeComboBoxx = new QComboBoxx;
+  kerningDegreeComboBoxx->insertItem(KERNING_DEGREE_NONE, tr("None"));
+  kerningDegreeComboBoxx->insertItem(KERNING_DEGREE_LIGHT, tr("Light"));
+  kerningDegreeComboBoxx->insertItem(KERNING_DEGREE_MEDIUM, tr("Medium"));
+  kerningDegreeComboBoxx->insertItem(KERNING_DEGREE_TIGHT, tr("Tight"));
+  kerningDegreeLabel->setBuddy(kerningDegreeComboBoxx);
+
   int width;
   // make all labels have the same width
   width = hintingModeLabel->minimumSizeHint().width();
   width = qMax(antiAliasingLabel->minimumSizeHint().width(), width);
   width = qMax(lcdFilterLabel->minimumSizeHint().width(), width);
   width = qMax(renderingModeLabel->minimumSizeHint().width(), width);
+  width = qMax(kerningModeLabel->minimumSizeHint().width(), width);
+  width = qMax(kerningDegreeLabel->minimumSizeHint().width(), width);
   hintingModeLabel->setMinimumWidth(width);
   antiAliasingLabel->setMinimumWidth(width);
   lcdFilterLabel->setMinimumWidth(width);
   renderingModeLabel->setMinimumWidth(width);
+  kerningModeLabel->setMinimumWidth(width);
+  kerningDegreeLabel->setMinimumWidth(width);
 
   // ensure that all items in combo boxes fit completely;
   // also make all combo boxes have the same width
@@ -1087,10 +1155,14 @@ MainGUI::createLayout()
   width = qMax(antiAliasingComboBoxx->minimumSizeHint().width(), width);
   width = qMax(lcdFilterComboBox->minimumSizeHint().width(), width);
   width = qMax(renderingModeComboBoxx->minimumSizeHint().width(), width);
+  width = qMax(kerningModeComboBoxx->minimumSizeHint().width(), width);
+  width = qMax(kerningDegreeComboBoxx->minimumSizeHint().width(), width);
   hintingModeComboBoxx->setMinimumWidth(width);
   antiAliasingComboBoxx->setMinimumWidth(width);
   lcdFilterComboBox->setMinimumWidth(width);
   renderingModeComboBoxx->setMinimumWidth(width);
+  kerningModeComboBoxx->setMinimumWidth(width);
+  kerningDegreeComboBoxx->setMinimumWidth(width);
 
   gammaLabel = new QLabel(tr("Gamma"));
   gammaLabel->setAlignment(Qt::AlignRight);
@@ -1122,11 +1194,9 @@ MainGUI::createLayout()
   strokeLabel->setAlignment(Qt::AlignRight);
   slant_Slider = new QSlider(Qt::Horizontal);
   stroke_Slider = new QSlider(Qt::Horizontal);
-  slant_Slider->setRange(0, 100); // 5 = 0.05
-  stroke_Slider->setRange(0, 100);
-  slant_Slider->setTickPosition(QSlider::TicksBelow);
+  slant_Slider->setRange(1, 100); // 5 = 0.05
+  stroke_Slider->setRange(1, 100);
   slant_Slider->setTickInterval(2);
-  stroke_Slider->setTickPosition(QSlider::TicksBelow);
   stroke_Slider->setTickInterval(5);
   slantLabel->setBuddy(slant_Slider);
   strokeLabel->setBuddy(stroke_Slider);
@@ -1222,8 +1292,18 @@ MainGUI::createLayout()
   renderLayout->addWidget(renderingModeLabel);
   renderLayout->addWidget(renderingModeComboBoxx);
 
+  kerningLayout = new QHBoxLayout;
+  kerningLayout->addWidget(kerningModeLabel);
+  kerningLayout->addWidget(kerningModeComboBoxx);
+
+  degreeLayout = new QHBoxLayout;
+  degreeLayout->addWidget(kerningDegreeLabel);
+  degreeLayout->addWidget(kerningDegreeComboBoxx);
+
   viewTabLayout = new QVBoxLayout;
   viewTabLayout->addLayout(renderLayout);
+  viewTabLayout->addLayout(kerningLayout);
+  viewTabLayout->addLayout(degreeLayout);
   viewTabLayout->addLayout(emboldenVertLayout);
   viewTabLayout->addLayout(emboldenHorzLayout);
   viewTabLayout->addLayout(slantLayout);
@@ -1426,6 +1506,10 @@ MainGUI::createConnections()
           SLOT(checkLcdFilter()));
   connect(renderingModeComboBoxx, SIGNAL(currentIndexChanged(int)),
           SLOT(checkRenderingMode()));
+  connect(kerningModeComboBoxx, SIGNAL(currentIndexChanged(int)),
+          SLOT(checkKerningMode()));
+  connect(kerningDegreeComboBoxx, SIGNAL(currentIndexChanged(int)),
+          SLOT(checkKerningDegree()));
 
   connect(allGlyphs, SIGNAL(clicked()),
           SLOT(renderAll()));
diff --git a/src/ftinspect/maingui.hpp b/src/ftinspect/maingui.hpp
index a3cc19a..afb836b 100644
--- a/src/ftinspect/maingui.hpp
+++ b/src/ftinspect/maingui.hpp
@@ -87,6 +87,8 @@ private slots:
   void checkHinting();
   void checkHintingMode();
   void checkRenderingMode();
+  void checkKerningMode();
+  void checkKerningDegree();
   void checkLcdFilter();
   void checkShowPoints();
   void checkUnits();
@@ -107,6 +109,11 @@ private slots:
 private:
   Engine* engine;
 
+  
+  int render_mode = 1;
+  int kerning_mode = 0;
+  int kerning_degree = 0;
+
   QStringList fontList;
   int currentFontIndex;
 
@@ -122,7 +129,7 @@ private:
   int currentCFFHintingMode;
   int currentTTInterpreterVersion;
 
-  int render_mode = 1;
+
 
   // layout related stuff
   GlyphOutline *currentGlyphOutlineItem;
@@ -158,6 +165,8 @@ private:
   QComboBoxx *antiAliasingComboBoxx;
   QComboBoxx *hintingModeComboBoxx;
   QComboBoxx *renderingModeComboBoxx;
+  QComboBoxx *kerningModeComboBoxx;
+  QComboBoxx *kerningDegreeComboBoxx;
   QComboBox *lcdFilterComboBox;
   QComboBox *unitsComboBox;
 
@@ -191,6 +200,8 @@ private:
   QHBoxLayout *warpingLayout;
   QHBoxLayout *programNavigationLayout;
   QHBoxLayout *renderLayout;
+  QHBoxLayout *kerningLayout;
+  QHBoxLayout *degreeLayout;
   QHBoxLayout *emboldenVertLayout;
   QHBoxLayout *emboldenHorzLayout;
   QHBoxLayout *slantLayout;
@@ -205,6 +216,8 @@ private:
   QLabel *glyphNameLabel;
   QLabel *hintingModeLabel;
   QLabel *renderingModeLabel;
+  QLabel *kerningModeLabel;
+  QLabel *kerningDegreeLabel;
   QLabel *lcdFilterLabel;
   QLabel *sizeLabel;
   QLabel *zoomLabel;
@@ -318,7 +331,21 @@ private:
     Fancy,
     Stroked,
     Text_String,
-    Waterfall
+    Waterfall,
+    Kerning_Comparison
+  };
+  enum KerningMode
+  {
+    KERNING_MODE_NONE,      /* 0: no kerning;                  */
+    KERNING_MODE_NORMAL,        /* 1: `kern' values                */
+    KERNING_MODE_SMART         /* 2: `kern' + side bearing errors */
+  };
+  enum KerningDegree
+  {
+    KERNING_DEGREE_NONE,
+    KERNING_DEGREE_LIGHT,
+    KERNING_DEGREE_MEDIUM,
+    KERNING_DEGREE_TIGHT
   };
 
   void createActions();
diff --git a/src/ftinspect/rendering/comparator.cpp 
b/src/ftinspect/rendering/comparator.cpp
deleted file mode 100644
index d77a71a..0000000
--- a/src/ftinspect/rendering/comparator.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "comparator.hpp"
-
-#include <cmath>
-#include <QPainter>
-#include <QStyleOptionGraphicsItem>
-#include <QWidget>
-#include <QFile>
-#include <QImage>
-#include <iostream>
-#include <QtDebug>
-
-
-static const char*  default_text =
-  "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras sit amet"
-  " dui.  Nam sapien. Fusce vestibulum ornare metus. Maecenas ligula orci,"
-  " consequat vitae, dictum nec, lacinia non, elit. Aliquam iaculis"
-  " molestie neque. Maecenas suscipit felis ut pede convallis malesuada."
-  " Aliquam erat volutpat. Nunc pulvinar condimentum nunc. Donec ac sem vel"
-  " leo bibendum aliquam. Pellentesque habitant morbi tristique senectus et"
-  " netus et malesuada fames ac turpis egestas.\n"
-  "\n"
-  "Sed commodo. Nulla ut libero sit amet justo varius blandit. Mauris vitae"
-  " nulla eget lorem pretium ornare. Proin vulputate erat porta risus."
-  " Vestibulum malesuada, odio at vehicula lobortis, nisi metus hendrerit"
-  " est, vitae feugiat quam massa a ligula. Aenean in tellus. Praesent"
-  " convallis. Nullam vel lacus.  Aliquam congue erat non urna mollis"
-  " faucibus. Morbi vitae mauris faucibus quam condimentum ornare. Quisque"
-  " sit amet augue. Morbi ullamcorper mattis enim. Aliquam erat volutpat."
-  " Morbi nec felis non enim pulvinar lobortis.  Ut libero. Nullam id orci"
-  " quis nisl dapibus rutrum. Suspendisse consequat vulputate leo. Aenean"
-  " non orci non tellus iaculis vestibulum. Sed neque.\n"
-  "\n";
-
-
-RenderAll::RenderAll(FT_Face face,
-          FT_Size  size,
-          FTC_Manager cacheManager,
-          FTC_FaceID  face_id,
-          FTC_CMapCache  cmap_cache,
-          FT_Library lib,
-          int render_mode,
-          FTC_ScalerRec scaler,
-          FTC_ImageCache imageCache,
-          double x,
-          double y,
-          double slant_factor,
-          double stroke_factor)
-:face(face),
-size(size),
-cacheManager(cacheManager),
-face_id(face_id),
-cmap_cache(cmap_cache),
-library(lib),
-mode(render_mode),
-scaler(scaler),
-imageCache(imageCache),
-x_factor(x),
-y_factor(y),
-slant_factor(slant_factor),
-stroke_factor(stroke_factor)
-{
-}
-
-
-RenderAll::~RenderAll()
-{
-  //FT_Stroker_Done(stroker);
-  //FTC_Manager_Done(cacheManager);
-}
-
-QRectF
-RenderAll::boundingRect() const
-{
-  return QRectF(-320, -200,
-                640, 400);
-}
-
-
-void
-RenderAll::paint(QPainter* painter,
-                   const QStyleOptionGraphicsItem* option,
-                   QWidget*)
-{
-}
-
-// end of RenderAll.cpp
diff --git a/src/ftinspect/rendering/comparator.hpp 
b/src/ftinspect/rendering/comparator.hpp
deleted file mode 100644
index 49af748..0000000
--- a/src/ftinspect/rendering/comparator.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#pragma once
-
-#include <QGraphicsItem>
-#include <QPen>
-
-#include <ft2build.h>
-#include "../engine/engine.hpp"
-#include FT_FREETYPE_H
-#include FT_OUTLINE_H
-#include FT_GLYPH_H
-#include FT_TYPES_H
-#include FT_RENDER_H
-#include FT_STROKER_H
-
-#include FT_INTERNAL_DEBUG_H
-
-  /* showing driver name */
-#include FT_MODULE_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_INTERNAL_DRIVER_H
-
-#include FT_SYNTHESIS_H
-#include FT_LCD_FILTER_H
-#include FT_DRIVER_H
-
-#include FT_COLOR_H
-#include FT_BITMAP_H
-
-
-class RenderAll
-: public QGraphicsItem
-{
-public:
-  RenderAll(FT_Face face,
-       FT_Size  size,
-       FTC_Manager cacheManager,
-       FTC_FaceID  face_id,
-       FTC_CMapCache  cmap_cache,
-       FT_Library library,
-       int mode,
-       FTC_ScalerRec scaler,
-       FTC_ImageCache imageCache,
-       double x_factor,
-       double y_factor,
-       double slant_factor,
-       double stroke_factor);
-  ~RenderAll();
-  QRectF boundingRect() const;
-  void paint(QPainter* painter,
-             const QStyleOptionGraphicsItem* option,
-             QWidget* widget);
-
-private:
-  FT_Face face;
-  FT_Library library;
-  QRectF m_glyphRect;
-  FT_Error error;
-  FTC_Manager cacheManager;
-  FTC_FaceID face_id;
-  FTC_CMapCache cmap_cache;
-  FT_Size size;
-  int mode;
-  Engine* engine;
-  FTC_ScalerRec scaler;
-  FTC_ImageCache imageCache;
-  double x_factor;
-  double y_factor;
-  double slant_factor;
-  double stroke_factor;
-};
-
-
-// end of glyphbitmap.hpp
diff --git a/src/ftinspect/rendering/view.cpp b/src/ftinspect/rendering/view.cpp
index e9d78a4..2c74ae8 100644
--- a/src/ftinspect/rendering/view.cpp
+++ b/src/ftinspect/rendering/view.cpp
@@ -18,8 +18,131 @@
 
 #define TRUNC(x) ((x) >> 6)
 
+extern "C" {
 
-static const char*  Text =
+// 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"
+
+static const char*  Sample[] =
+  {
+    "The quick brown fox jumps over the lazy dog",
+
+    /* Luís argüia à Júlia que «brações, fé, chá, óxido, pôr, zângão» */
+    /* eram palavras do português */
+    "Lu\u00EDs arg\u00FCia \u00E0 J\u00FAlia que \u00ABbra\u00E7\u00F5es, "
+    "f\u00E9, ch\u00E1, \u00F3xido, p\u00F4r, z\u00E2ng\u00E3o\u00BB eram "
+    "palavras do portugu\u00EAs",
+
+    /* Ο καλύμνιος σφουγγαράς ψιθύρισε πως θα βουτήξει χωρίς να διστάζει */
+    "\u039F \u03BA\u03B1\u03BB\u03CD\u03BC\u03BD\u03B9\u03BF\u03C2 \u03C3"
+    "\u03C6\u03BF\u03C5\u03B3\u03B3\u03B1\u03C1\u03AC\u03C2 \u03C8\u03B9"
+    "\u03B8\u03CD\u03C1\u03B9\u03C3\u03B5 \u03C0\u03C9\u03C2 \u03B8\u03B1 "
+    "\u03B2\u03BF\u03C5\u03C4\u03AE\u03BE\u03B5\u03B9 \u03C7\u03C9\u03C1"
+    "\u03AF\u03C2 \u03BD\u03B1 \u03B4\u03B9\u03C3\u03C4\u03AC\u03B6\u03B5"
+    "\u03B9",
+
+    /* Съешь ещё этих мягких французских булок да выпей же чаю */
+    "\u0421\u044A\u0435\u0448\u044C \u0435\u0449\u0451 \u044D\u0442\u0438"
+    "\u0445 \u043C\u044F\u0433\u043A\u0438\u0445 \u0444\u0440\u0430\u043D"
+    "\u0446\u0443\u0437\u0441\u043A\u0438\u0445 \u0431\u0443\u043B\u043E"
+    "\u043A \u0434\u0430 \u0432\u044B\u043F\u0435\u0439 \u0436\u0435 "
+    "\u0447\u0430\u044E",
+
+    /* 天地玄黃,宇宙洪荒。日月盈昃,辰宿列張。寒來暑往,秋收冬藏。*/
+    "\u5929\u5730\u7384\u9EC3\uFF0C\u5B87\u5B99\u6D2A\u8352\u3002\u65E5"
+    "\u6708\u76C8\u6603\uFF0C\u8FB0\u5BBF\u5217\u5F35\u3002\u5BD2\u4F86"
+    "\u6691\u5F80\uFF0C\u79CB\u6536\u51AC\u85CF\u3002",
+
+    /* いろはにほへと ちりぬるを わかよたれそ つねならむ */
+    /* うゐのおくやま けふこえて あさきゆめみし ゑひもせす */
+    "\u3044\u308D\u306F\u306B\u307B\u3078\u3068 \u3061\u308A\u306C\u308B"
+    "\u3092 \u308F\u304B\u3088\u305F\u308C\u305D \u3064\u306D\u306A\u3089"
+    "\u3080 \u3046\u3090\u306E\u304A\u304F\u3084\u307E \u3051\u3075\u3053"
+    "\u3048\u3066 \u3042\u3055\u304D\u3086\u3081\u307F\u3057 \u3091\u3072"
+    "\u3082\u305B\u3059",
+
+    /* 키스의 고유조건은 입술끼리 만나야 하고 특별한 기술은 필요치 않다 */
+    "\uD0A4\uC2A4\uC758 \uACE0\uC720\uC870\uAC74\uC740 \uC785\uC220\uB07C"
+    "\uB9AC \uB9CC\uB098\uC57C \uD558\uACE0 \uD2B9\uBCC4\uD55C \uAE30"
+    "\uC220\uC740 \uD544\uC694\uCE58 \uC54A\uB2E4"
+  };
+
+
+
+/* static const char*  Sample[0] =
       "The quick brown fox jumps over the lazy dog"
       " 0123456789"
       " \303\242\303\252\303\256\303\273\303\264"
@@ -27,7 +150,7 @@ static const char*  Text =
       "\303\240\303\271\303\251\303\250\303\247"
       " &#~\"\'(-`_^@)=+\302\260"
       " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-      " $\302\243^\302\250*\302\265\303\271%!\302\247:/;.,?<> ";
+      " $\302\243^\302\250*\302\265\303\271%!\302\247:/;.,?<> ";*/
 
 
 RenderAll::RenderAll(FT_Face face,
@@ -42,7 +165,9 @@ RenderAll::RenderAll(FT_Face face,
           double x,
           double y,
           double slant_factor,
-          double stroke_factor)
+          double stroke_factor,
+          int kern_mode,
+          int kern_degree)
 :face(face),
 size(size),
 cacheManager(cacheManager),
@@ -55,7 +180,9 @@ imageCache(imageCache),
 x_factor(x),
 y_factor(y),
 slant_factor(slant_factor),
-stroke_factor(stroke_factor)
+stroke_factor(stroke_factor),
+kerning_mode(kern_mode),
+kerning_degree(kern_degree)
 {
 }
 
@@ -269,15 +396,14 @@ RenderAll::paint(QPainter* painter,
     FT_Fixed radius;
     FT_Stroker stroker;
 
-    FT_Stroker_New( library, &stroker );
-    radius = (FT_Fixed)( size->metrics.y_ppem * 64 * stroke_factor );
+      FT_Stroker_New( library, &stroker );
+      radius = (FT_Fixed)( size->metrics.y_ppem * 64 * stroke_factor );
 
-    FT_Stroker_Set( stroker, radius,
-                    FT_STROKER_LINECAP_ROUND,
-                    FT_STROKER_LINEJOIN_ROUND,
-                    0 );
+      
+      FT_Stroker_Set( stroker, 32, FT_STROKER_LINECAP_BUTT,
+                  FT_STROKER_LINEJOIN_BEVEL, 0x20000 );
 
-    for ( int i = 0; i < face->num_glyphs; i++ )
+    for ( int i = 0; i <2; i++ )
     {
       // get char index 
       //glyph_idx = FT_Get_Char_Index( face , (FT_ULong)i );
@@ -291,29 +417,62 @@ RenderAll::paint(QPainter* painter,
         glyph_idx = (FT_UInt32)i;
       }
 
-      /* load glyph image into the slot (erase previous one) */
-      error = FT_Load_Glyph( face, glyph_idx, FT_LOAD_DEFAULT );
-      if ( error )
+      
+      FT_Glyph glyph;
+
+      // XXX handle bitmap fonts
+
+      // the `scaler' object is set up by the
+      // `update' and `loadFont' methods
+      error = FTC_ImageCache_LookupScaler(imageCache,
+                                &scaler,
+                                FT_LOAD_NO_BITMAP,
+                                glyph_idx,
+                                &glyph,
+                                NULL);
       {
-        break;  /* ignore errors */
       }
 
+      FT_OutlineGlyph outlineGlyph = reinterpret_cast<FT_OutlineGlyph>(glyph);
+
+      FT_Outline* outline = &outlineGlyph->outline;
+
+      FT_BBox cbox;
+
+      FT_Outline_Get_CBox(outline, &cbox);
+
+      QPainterPath path;
+      FT_Outline_Decompose(outline, &outlineFuncs, &path);
+
+      painter->drawPath(path);
+
+
+
+/* 
       if ( !error && slot->format == FT_GLYPH_FORMAT_OUTLINE )
       {
-        FT_Glyph  glyph;
+        
+        
 
-        error = FT_Get_Glyph( slot, &glyph );
-        if ( error )
-          break;
 
-        error = FT_Glyph_Stroke( &glyph, stroker, 1 );
+        FT_Glyph_StrokeBorder(&glyph, stroker, 0, 1);
+
+        FT_Outline* outline = engine->loadOutline(glyph_idx); */
+
+       /*  error = FT_Glyph_Stroke( &glyph, stroker, 1 );
         if ( error )
         {
           //FT_Done_Glyph( glyph );
           break;
-        }
-        error = FT_Render_Glyph(slot,
-                                FT_RENDER_MODE_NORMAL);
+        } */
+
+        /* error = FT_Get_Glyph( slot, &glyph );
+        if ( error )
+          break;
+
+        FT_Glyph_Stroke( &glyph, stroker, 1 );
+
+        error = FT_Render_Glyph(slot, FT_RENDER_MODE_NORMAL);
 
         QImage glyphImage(slot->bitmap.buffer,
                             slot->bitmap.width,
@@ -321,8 +480,6 @@ RenderAll::paint(QPainter* painter,
                             slot->bitmap.pitch,
                             QImage::Format_Indexed8);
 
-        
-
         QVector<QRgb> colorTable;
         for (int i = 0; i < 256; ++i)
         {
@@ -343,16 +500,13 @@ RenderAll::paint(QPainter* painter,
         y += (size->metrics.height + 4)/64;
         x = -350;
       }
-      }
+      //}*/
     }
   }
   
   // Render String mode
   if (mode == 4)
   {
-    int offset = -1;
-    int num_indices = 0;
-
     /*
      In UTF-8 encoding:
 
@@ -363,7 +517,7 @@ RenderAll::paint(QPainter* painter,
        ABCDEFGHIJKLMNOPQRSTUVWXYZ
        $£^¨*µù%!§:/;.,?<>
 
-     The trailing space is for `looping' in case `Text' gets displayed more
+     The trailing space is for `looping' in case `Sample[0]' gets displayed 
more
      than once.
    */
     
@@ -371,14 +525,14 @@ RenderAll::paint(QPainter* painter,
     const char*  pEnd;
     int          ch;
 
-    p    = Text;
-    pEnd = p + strlen( Text ); 
+    p    = Sample[0];
+    pEnd = p + strlen( Sample[0] ); 
 
-    int length = strlen(Text);
+    int length = strlen(Sample[0]);
 
     for ( int i = 0; i < length; i++ )
     {
-      QChar ch = Text[i];
+      QChar ch = Sample[0][i];
 
       // get char index 
       glyph_idx = FT_Get_Char_Index( face , ch.unicode());
@@ -423,8 +577,6 @@ RenderAll::paint(QPainter* painter,
                         glyphImage, 0, 0, -1, -1);
 
       x += face->glyph->advance.x/64;
-      // extra space between the glyphs
-      x++;
       if (x >= 350)
       { 
         y += (size->metrics.height + 4)/64;
@@ -437,7 +589,7 @@ RenderAll::paint(QPainter* painter,
   if (mode == 5)
   {
     
-    int length = strlen(Text);
+    int length = strlen(Sample[0]);
     while (y <= 200)
     { 
       int m = 0;
@@ -445,7 +597,7 @@ RenderAll::paint(QPainter* painter,
       {
 
         FT_Glyph  glyph;
-        QChar ch = Text[m];
+        QChar ch = Sample[0][m];
         m += 1;
 
           
@@ -503,6 +655,108 @@ RenderAll::paint(QPainter* painter,
       x = -350;
     }
   }
+
+  // Kerning comparison
+  if (mode == 6)
+  {
+    /* 1. Print text without kerning
+    2. Print text with kerning mode 1
+    3. Print text with kerning mode 2 */
+    FT_Pos     lsb_delta = 0; /* delta caused by hinting */
+    FT_Pos     rsb_delta = 0; /* delta caused by hinting */
+    const char*  p;
+    const char*  pEnd;
+    int          ch;
+    FT_Pos   track_kern   = 0;
+    FT_Bool use_kerning;
+    FT_UInt previous;
+
+    use_kerning = FT_HAS_KERNING( face );
+    previous = 0;
+
+    p    = Sample[0];
+    pEnd = p + strlen( Sample[0] ); 
+
+    int length = strlen(Sample[0]);
+
+    // if kerning degree > 0
+    if ( kerning_degree )
+    {
+      /* this function needs and returns points, not pixels */
+      if ( !FT_Get_Track_Kerning( face,
+                                  (FT_Fixed)scaler.width << 10,
+                                  -kerning_degree,
+                                  &track_kern ) )
+      track_kern = (FT_Pos)(
+                    ( track_kern / 1024.0 * scaler.x_res ) /
+                    72.0 );
+    }
+
+    for ( int i = 0; i < length; i++ )
+    {
+      QChar ch = Sample[0][i];
+
+      // get char index 
+      glyph_idx = FT_Get_Char_Index( face , ch.unicode());
+
+      x += track_kern;
+
+      if (previous && glyph_idx )
+      {
+        FT_Vector delta;
+
+        FT_Get_Kerning( face, previous, glyph_idx,
+                        FT_KERNING_UNFITTED, &delta );
+
+        x += delta.x;
+        
+        if ( kerning_mode > 1 )
+        {   
+            if ( rsb_delta && rsb_delta - face->glyph->lsb_delta > 32 )
+              x -= 1;
+            else if ( rsb_delta && rsb_delta - face->glyph->lsb_delta < -31 )
+              x += 1;
+        }
+      }
+
+      /* load glyph image into the slot (erase previous one) */
+      error = FT_Load_Glyph( face, glyph_idx, FT_LOAD_DEFAULT );
+      if ( error )
+      {
+        break;  /* ignore errors */
+      }
+
+      error = FT_Render_Glyph(face->glyph,
+                                FT_RENDER_MODE_NORMAL);
+
+      QImage glyphImage(face->glyph->bitmap.buffer,
+                          face->glyph->bitmap.width,
+                          face->glyph->bitmap.rows,
+                          face->glyph->bitmap.pitch,
+                          QImage::Format_Indexed8);
+
+
+      QVector<QRgb> colorTable;
+      for (int i = 0; i < 256; ++i)
+      {
+        colorTable << qRgba(0, 0, 0, i);
+      }
+        
+      glyphImage.setColorTable(colorTable);
+      painter->drawImage(x, y,
+                        glyphImage, 0, 0, -1, -1);
+
+      if (previous)
+      {
+        lsb_delta = face->glyph->lsb_delta;
+        rsb_delta = face->glyph->rsb_delta;
+      }
+      // space between the glyphs
+      x += face->glyph->advance.x/64;
+
+      previous = glyph_idx;
+    }
+  }
 }
 
 // end of RenderAll.cpp
diff --git a/src/ftinspect/rendering/view.hpp b/src/ftinspect/rendering/view.hpp
index 49af748..7ce8d50 100644
--- a/src/ftinspect/rendering/view.hpp
+++ b/src/ftinspect/rendering/view.hpp
@@ -43,7 +43,9 @@ public:
        double x_factor,
        double y_factor,
        double slant_factor,
-       double stroke_factor);
+       double stroke_factor,
+       int kerning_mode,
+       int kerning_degree);
   ~RenderAll();
   QRectF boundingRect() const;
   void paint(QPainter* painter,
@@ -61,12 +63,15 @@ private:
   FT_Size size;
   int mode;
   Engine* engine;
+  MainGUI* gui;
   FTC_ScalerRec scaler;
   FTC_ImageCache imageCache;
   double x_factor;
   double y_factor;
   double slant_factor;
   double stroke_factor;
+  int kerning_mode;
+  int kerning_degree;
 };
 
 



reply via email to

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