summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wildemann <metalstrolch@users.noreply.github.com>2017-05-13 19:28:40 +0200
committerPierre GRANDIN <pgrandin@users.noreply.github.com>2017-05-13 10:28:40 -0700
commitfb38c9c988517a07a702e778261f86fb2451c902 (patch)
tree51339b19abf00ec461cc2e99f723a2c5ba9c3d21
parente91a4ca20da321be1131e004d5703a84b5496947 (diff)
downloadnavit-fb38c9c988517a07a702e778261f86fb2451c902.tar.gz
Remove Qt5 fonts dependency on Freetype (#253)R7542
* Fix: Have nice font shadow as freetype has If using QT font rendering, a white (or black) outline as if rendered with freetype is shown. * qt5: Port font guessing and matrix transformation Select font using the same algorithm than in freetype. Transform font using the same matrix than in freetype. * Sailfish: switch to QT font rendering * Fix: remove SubPxelAntiAliasing hint, Sailfish's QT version is too old for this * Fix: fix bbox calculation for qt5 fonts
-rwxr-xr-xcontrib/sailfish/navit-sailfish.spec22
-rw-r--r--navit/graphics/qt5/CMakeLists.txt8
-rw-r--r--navit/graphics/qt5/graphics_qt5.cpp163
-rw-r--r--navit/graphics/qt5/graphics_qt5.h8
4 files changed, 159 insertions, 42 deletions
diff --git a/contrib/sailfish/navit-sailfish.spec b/contrib/sailfish/navit-sailfish.spec
index 9c7a79b9b..4ed226967 100755
--- a/contrib/sailfish/navit-sailfish.spec
+++ b/contrib/sailfish/navit-sailfish.spec
@@ -10,7 +10,7 @@ Name: harbour-navit
Summary: Open Source car navigation system
#Version: %{navit_version}_%{git_version}
Version: 0.5.1
-Release: 2
+Release: 3
License: GPL
Group: Applications/Productivity
URL: http://navit-projet.org/
@@ -19,7 +19,7 @@ BuildRequires: gcc
BuildRequires: cmake
BuildRequires: glib2-devel
BuildRequires: gettext-devel
-BuildRequires: freetype-devel
+#BuildRequires: freetype-devel
BuildRequires: zlib-devel
BuildRequires: qt5-qtcore-devel
BuildRequires: qt5-qtdeclarative-devel
@@ -30,7 +30,7 @@ BuildRequires: qt5-qtsvg-devel
#Requires: glib2
#Requires: gettext-libs
-Requires: freetype
+#Requires: freetype
#Requires: zlib
#Requires: qt5-qtcore
#Requires: qt5-qtdeclarative
@@ -71,6 +71,7 @@ cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
-DIMAGE_DIR:PATH=share/harbour-navit/xpm \
-DLIB_DIR:PATH=share/harbour-navit/lib \
-DBUILD_MAPTOOL:BOOL=FALSE \
+ -Dfont/freetype:BOOL=FALSE \
-Dbinding/dbus:BOOL=FALSE \
-Dgraphics/gtk_drawing_area:BOOL=FALSE \
-Dgraphics/null:BOOL=FALSE \
@@ -110,7 +111,16 @@ cp %{navit_real_source}/contrib/sailfish/navit.xml %{buildroot}/usr/share/harbou
%changelog
-*Wed May 03 2017 Use qt5_espeak
-*Mon Apr 10 2017 Almost harbour valid
-*Mon Dec 14 2015 Initial sailfish release
+*Wed May 11 2017 metalstrolch 0.5.1-3
+- Switch to QT font rendering. Remove freetype dep.
+
+*Wed May 03 2017 metalstrolch 0.5.1-2
+- Use qt5_espeak
+
+*Mon Apr 10 2017 metalstrolch 0.5.1-1
+- Almost harbour valid
+
+*Mon Dec 14 2015 metalstrolch 0.5.1-0
+- Initial sailfish release
- Initial package.
+
diff --git a/navit/graphics/qt5/CMakeLists.txt b/navit/graphics/qt5/CMakeLists.txt
index 0f5e19c6c..ff359e88f 100644
--- a/navit/graphics/qt5/CMakeLists.txt
+++ b/navit/graphics/qt5/CMakeLists.txt
@@ -11,6 +11,12 @@ set (GRAPHICS_QT5_ADDITIONAL "")
# initialize QML and QWIDGET usage to not use
set(QML 0)
set(QWIDGET 0)
+set(HAVE_FREETYPE 0)
+
+# check if we have FREETYPE
+if(font/freetype)
+ set(HAVE_FREETYPE 1)
+endif()
# check if we have QML
if(USE_QML)
@@ -27,5 +33,5 @@ endif ()
module_add_library(graphics_qt5 graphics_qt5.cpp event_qt5.cpp ${GRAPHICS_QT5_ADDITIONAL})
# pass QML and QWIDGET preference to source
-target_compile_definitions(graphics_qt5 PRIVATE USE_QML=${QML} USE_QWIDGET=${QWIDGET})
+target_compile_definitions(graphics_qt5 PRIVATE USE_QML=${QML} USE_QWIDGET=${QWIDGET} HAVE_FREETYPE=${HAVE_FREETYPE})
diff --git a/navit/graphics/qt5/graphics_qt5.cpp b/navit/graphics/qt5/graphics_qt5.cpp
index ddafd406a..c25944ee5 100644
--- a/navit/graphics/qt5/graphics_qt5.cpp
+++ b/navit/graphics/qt5/graphics_qt5.cpp
@@ -93,7 +93,7 @@ static void
graphics_destroy(struct graphics_priv* gr)
{
// dbg(lvl_debug,"enter\n");
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
gr->freetype_methods.destroy();
#endif
/* destroy painter */
@@ -152,20 +152,74 @@ static void font_destroy(struct graphics_font_priv* font)
g_free(font);
}
+/**
+ * @brief font interface structure
+ * This structure is preset with all function pointers provided by this implemention
+ * to be returned as interface.
+ */
static struct graphics_font_methods font_methods = {
font_destroy
};
+/**
+ * List of font families to use, in order of preference
+ */
+static const char* fontfamilies[] = {
+ "Liberation Sans",
+ "Arial",
+ "NcrBI4nh",
+ "luximbi",
+ "FreeSans",
+ "DejaVu Sans",
+ NULL,
+};
+
+/**
+ * @brief Allocate a font context
+ * @param gr own private context
+ * @param meth fill this structure with correct functions to be called with handle as interface to font
+ * @param font font family e.g. "Arial"
+ * @param size Font size in ???
+ * @param flags Font flags (currently 1 if bold and 0 if not)
+ *
+ * @return font handle
+ *
+ * Allocates a font handle and returnes filled interface stucture
+ */
static struct graphics_font_priv* font_new(struct graphics_priv* gr, struct graphics_font_methods* meth, char* font, int size, int flags)
{
+ int a = 0;
struct graphics_font_priv* font_priv;
- // dbg(lvl_debug,"enter (font %s, %d)\n", font, size);
+ dbg(lvl_debug, "enter (font %s, %d, 0x%x)\n", font, size, flags);
font_priv = g_new0(struct graphics_font_priv, 1);
+ font_priv->font = new QFont(fontfamilies[0]);
if (font != NULL)
- font_priv->font = new QFont(font, size / 16);
- else
- font_priv->font = new QFont("Arial", size / 16);
- font_priv->font->setStyleStrategy(QFont::NoAntialias);
+ font_priv->font->setFamily(font);
+ /* search for exact font match */
+ while ((!font_priv->font->exactMatch()) && (fontfamilies[a] != NULL)) {
+ font_priv->font->setFamily(fontfamilies[a]);
+ a++;
+ }
+ if (font_priv->font->exactMatch()) {
+ dbg(lvl_debug, "Exactly matching font: %s\n", font_priv->font->family().toUtf8().data());
+ } else {
+ /* set any font*/
+ if (font != NULL) {
+ font_priv->font->setFamily(font);
+ } else {
+ font_priv->font->setFamily(fontfamilies[0]);
+ }
+ dbg(lvl_debug, "No matching font. Resort to: %s\n", font_priv->font->family().toUtf8().data());
+ }
+
+ /* No clue why factor 20. Found this by comparing to Freetype rendering. */
+ font_priv->font->setPointSize(size / 20);
+ //font_priv->font->setStyleStrategy(QFont::NoSubpixelAntialias);
+ /* Check for bold font */
+ if (flags) {
+ font_priv->font->setBold(true);
+ }
+
*meth = font_methods;
return font_priv;
}
@@ -405,14 +459,27 @@ draw_circle(struct graphics_priv* gr, struct graphics_gc_priv* gc, struct point*
gr->painter->drawArc(p->x - r / 2, p->y - r / 2, r, r, 0, 360 * 16);
}
+/**
+ * @brief Render given text
+ * @param gr own private context
+ * @param fg foreground drawing context (for color)
+ * @param bg background drawing context (for color)
+ * @param font font context to use (allocated by font_new)
+ * @param text String to calculate bbox for
+ * @param p offset on gr context to place this text.
+ * @param dx transformation matrix (16.16 fixpoint)
+ * @param dy transformation matrix (16.16 fixpoint)
+ *
+ * Renders given text on gr surface. Draws nice contrast outline around text.
+ */
static void
draw_text(struct graphics_priv* gr, struct graphics_gc_priv* fg, struct graphics_gc_priv* bg, struct graphics_font_priv* font, char* text, struct point* p, int dx, int dy)
{
- dbg(lvl_debug, "enter gc=%p, fg=%p, bg=%p pos(%d,%d) %s\n", gr, fg, bg, p->x, p->y, text);
+ dbg(lvl_debug, "enter gc=%p, fg=%p, bg=%p pos(%d,%d) d(%d, %d) %s\n", gr, fg, bg, p->x, p->y, dx, dy, text);
QPainter* painter = gr->painter;
if (painter == NULL)
return;
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
struct font_freetype_text* t;
struct font_freetype_glyph *g, **gp;
struct color transparent = { 0x0000, 0x0000, 0x0000, 0x0000 };
@@ -477,11 +544,22 @@ draw_text(struct graphics_priv* gr, struct graphics_gc_priv* fg, struct graphics
gr->freetype_methods.text_destroy(t);
#else
QString tmp = QString::fromUtf8(text);
- QMatrix sav = gr->painter->worldMatrix();
- QMatrix m(dx / 65535.0, dy / 65535.0, -dy / 65535.0, dx / 65535.0, p->x, p->y);
+ qreal m_dx = ((qreal)dx) / 65536.0;
+ qreal m_dy = ((qreal)dy) / 65536.0;
+ QMatrix sav = painter->worldMatrix();
+ QMatrix m(m_dx, m_dy, -m_dy, m_dx, p->x, p->y);
painter->setWorldMatrix(m, TRUE);
- painter->setPen(*fg->pen);
painter->setFont(*font->font);
+ if (bg) {
+ QPen shadow;
+ QPainterPath path;
+ shadow.setColor(bg->pen->color());
+ shadow.setWidth(3);
+ painter->setPen(shadow);
+ path.addText(0, 0, *font->font, tmp);
+ painter->drawPath(path);
+ }
+ painter->setPen(*fg->pen);
painter->drawText(0, 0, tmp);
painter->setWorldMatrix(sav);
#endif
@@ -645,27 +723,50 @@ static void image_free(struct graphics_priv* gr, struct graphics_image_priv* pri
g_free(priv);
}
+/**
+ * @brief Calculate pixel space required for font display.
+ * @param gr own private context
+ * @param font font context to use (allocated by font_new)
+ * @param text String to calculate bbox for
+ * @param dx transformation matrix (16.16 fixpoint)
+ * @param dy transformation matrix (16.16 fixpoint)
+ * @param ret point array to fill. (low left, top left, top right, low right)
+ * @param estimate ???
+ *
+ * Calculates the bounding box around the given text.
+ */
static void get_text_bbox(struct graphics_priv* gr, struct graphics_font_priv* font, char* text, int dx, int dy, struct point* ret, int estimate)
{
- // dbg(lvl_debug,"enter %s %d %d\n", text, dx, dy);
+ int i;
+ struct point pt;
QPainter* painter = gr->painter;
QString tmp = QString::fromUtf8(text);
- if (gr->painter != NULL) {
- gr->painter->setFont(*font->font);
- QRect r = painter->boundingRect(0, 0, gr->pixmap->width(), gr->pixmap->height(), 0, tmp);
- // dbg (lvl_debug, "Text bbox: %d %d (%d,%d),(%d,%d)\n",dx, dy, r.left(), r.top(), r.right(), r.bottom());
- /* low left */
- ret[0].x = r.left();
- ret[0].y = r.bottom();
- /* top left */
- ret[1].x = r.left();
- ret[1].y = r.top();
- /* top right */
- ret[2].x = r.right();
- ret[2].y = r.top();
- /* low right */
- ret[3].x = r.right();
- ret[3].y = r.bottom();
+ QRect r;
+ // dbg(lvl_debug,"enter %s %d %d\n", text, dx, dy);
+
+ /* use QFontMetrix for bbox calculation as we do not always have a painter */
+ QFontMetrics fm(*font->font);
+ r = fm.boundingRect(tmp);
+
+ /* low left */
+ ret[0].x = r.left();
+ ret[0].y = r.bottom();
+ /* top left */
+ ret[1].x = r.left();
+ ret[1].y = r.top();
+ /* top right */
+ ret[2].x = r.right();
+ ret[2].y = r.top();
+ /* low right */
+ ret[3].x = r.right();
+ ret[3].y = r.bottom();
+ /* transform bbox if rotated */
+ if (dy != 0 || dx != 0x10000) {
+ for (i = 0; i < 4; i++) {
+ pt = ret[i];
+ ret[i].x = (pt.x * dx - pt.y * dy) / 0x10000;
+ ret[i].y = (pt.y * dx + pt.x * dy) / 0x10000;
+ }
}
}
@@ -727,7 +828,7 @@ overlay_new(struct graphics_priv* gr, struct graphics_methods* meth, struct poin
struct graphics_priv* graphics_priv = NULL;
graphics_priv = g_new0(struct graphics_priv, 1);
*meth = graphics_methods;
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
if (gr->font_freetype_new) {
graphics_priv->font_freetype_new = gr->font_freetype_new;
gr->font_freetype_new(&graphics_priv->freetype_methods);
@@ -807,7 +908,7 @@ graphics_qt5_new(struct navit* nav, struct graphics_methods* meth, struct attr**
return NULL;
}
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
struct font_priv* (*font_freetype_new)(void* meth);
/* get font plugin if present */
font_freetype_new = (struct font_priv * (*)(void*))plugin_get_category_font("freetype");
@@ -839,7 +940,7 @@ graphics_qt5_new(struct navit* nav, struct graphics_methods* meth, struct attr**
navit_app = new QGuiApplication(graphics_priv->argc, graphics_priv->argv);
#endif
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
graphics_priv->font_freetype_new = font_freetype_new;
font_freetype_new(&graphics_priv->freetype_methods);
meth->font_new = (struct graphics_font_priv * (*)(struct graphics_priv*, struct graphics_font_methods*, char*, int, int))graphics_priv->freetype_methods.font_new;
diff --git a/navit/graphics/qt5/graphics_qt5.h b/navit/graphics/qt5/graphics_qt5.h
index cebbc6d67..bf54ef45c 100644
--- a/navit/graphics/qt5/graphics_qt5.h
+++ b/navit/graphics/qt5/graphics_qt5.h
@@ -44,15 +44,15 @@
#include "QNavitWidget.h"
#endif
-#ifndef QT_QPAINTER_USE_FREETYPE
-#define QT_QPAINTER_USE_FREETYPE 1
+#ifndef HAVE_FREETYPE
+#define HAVE_FREETYPE 0
#endif
#ifndef SAILFISH_OS
#define SAILFISH_OS 1
#endif
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
#include "navit/font/freetype/font_freetype.h"
#endif
@@ -90,7 +90,7 @@ struct graphics_priv {
int x;
int y;
struct graphics_gc_priv* background_graphics_gc_priv;
-#ifdef QT_QPAINTER_USE_FREETYPE
+#if HAVE_FREETYPE
struct font_priv* (*font_freetype_new)(void* meth);
struct font_freetype_methods freetype_methods;
#endif