[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;
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2-demos] veeki-gsoc-experimental 8e12b4a: Added kerning and fixed cache error,
Veeki Yadav <=