summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-10-29 09:31:03 +0100
committerDavid Herrmann <dh.herrmann@gmail.com>2013-10-29 09:31:03 +0100
commit761434ecac7d9a4f1a95e3f3b4eee6e539947d32 (patch)
tree37d61efac50e2f77e3dad2e9a5962970f02c0d17
parent96b28e953de4363736e3dfccbedbf93e9fe70b6c (diff)
Remove freetype2 font backend
The freetype2 font backend lacks support for proper combining marks and I do not intend to ever implement that. Use pango! If you don't want heavy dependencies, you can use the unifont or 8x16 backends. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
-rw-r--r--Makefile.am22
-rw-r--r--README1
-rw-r--r--configure.ac49
-rw-r--r--docs/man/kmscon.xml2
-rw-r--r--src/font.h1
-rw-r--r--src/font_freetype2.c694
-rw-r--r--src/kmscon_mod_freetype2.c58
7 files changed, 2 insertions, 825 deletions
diff --git a/Makefile.am b/Makefile.am
index 4af0d36..52a14eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -451,28 +451,6 @@ mod_unifont_la_LDFLAGS = \
-module \
-avoid-version
-if BUILD_ENABLE_FONT_FREETYPE2
-module_LTLIBRARIES += mod-freetype2.la
-endif
-
-mod_freetype2_la_SOURCES = \
- src/kmscon_module_interface.h \
- src/font_freetype2.c \
- src/kmscon_mod_freetype2.c
-mod_freetype2_la_CPPFLAGS = \
- $(AM_CPPFLAGS) \
- $(FREETYPE2_CFLAGS) \
- $(TSM_CFLAGS)
-mod_freetype2_la_LIBADD = \
- $(FREETYPE2_LIBS) \
- $(TSM_LIBS) \
- -lpthread \
- libshl.la
-mod_freetype2_la_LDFLAGS = \
- $(AM_LDFLAGS) \
- -module \
- -avoid-version
-
if BUILD_ENABLE_FONT_PANGO
module_LTLIBRARIES += mod-pango.la
endif
diff --git a/README b/README
index a3cdb09..7e68498 100644
--- a/README
+++ b/README
@@ -74,7 +74,6 @@ Released tarballs can be found at:
Default is: fbdev,drm2d,drm3d
--with-fonts: Font renderers. Available backends are:
- unifont: Static built-in non-scalable font (Unicode Unifont)
- - freetype2: Freetype2+fontconfig based scalable font renderer
- pango: Pango based scalable font renderer
Default is: unifont,pango
The 8x16 backend is always built-in.
diff --git a/configure.ac b/configure.ac
index dac4bcd..6c975c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,11 +95,6 @@ PKG_CHECK_MODULES([GLES2], [glesv2],
AC_SUBST(GLES2_CFLAGS)
AC_SUBST(GLES2_LIBS)
-PKG_CHECK_MODULES([FREETYPE2], [freetype2 fontconfig],
- [have_freetype2=yes], [have_freetype2=no])
-AC_SUBST(FREETYPE2_CFLAGS)
-AC_SUBST(FREETYPE2_LIBS)
-
PKG_CHECK_MODULES([PANGO], [pango pangoft2],
[have_pango=yes], [have_pango=no])
AC_SUBST(PANGO_CFLAGS)
@@ -341,16 +336,13 @@ AC_ARG_WITH([fonts],
[],
[with_fonts="default"])
enable_font_unifont="no"
-enable_font_freetype2="no"
enable_font_pango="no"
if test "x$enable_all" = "xyes" ; then
enable_font_unifont="yes"
- enable_font_freetype2="yes"
enable_font_pango="yes"
- with_fonts="unifont,freetype2,pango (all)"
+ with_fonts="unifont,pango (all)"
elif test "x$with_fonts" = "xdefault" ; then
enable_font_unifont="yes (default)"
- enable_font_freetype2="no (default)"
enable_font_pango="yes (default)"
with_fonts="unifont,pango (default)"
elif test ! "x$with_fonts" = "x" ; then
@@ -359,8 +351,6 @@ elif test ! "x$with_fonts" = "x" ; then
for i in $with_fonts ; do
if test "x$i" = "xunifont" ; then
enable_font_unifont="yes"
- elif test "x$i" = "xfreetype2" ; then
- enable_font_freetype2="yes"
elif test "x$i" = "xpango" ; then
enable_font_pango="yes"
else
@@ -659,25 +649,6 @@ else
font_unifont_missing="enable-font-unifont"
fi
-# font freetype2
-font_freetype2_avail=no
-font_freetype2_missing=""
-if test ! "x$enable_font_freetype2" = "xno" ; then
- font_freetype2_avail=yes
- if test "x$have_freetype2" = "xno" ; then
- font_freetype2_avail=no
- font_freetype2_missing="libfontconfig,libfreetype2"
- fi
-
- if test "x$font_freetype2_avail" = "xno" ; then
- if test "x$enable_font_freetype2" = "xyes" ; then
- AC_ERROR([missing for font-freetype2: $font_freetype2_missing])
- fi
- fi
-else
- font_freetype2_missing="enable-font-freetype2"
-fi
-
# font pango
font_pango_avail=no
font_pango_missing=""
@@ -796,14 +767,6 @@ if test "x$font_pango_avail" = "xyes" ; then
fi
fi
-# font freetype2
-font_freetype2_enabled=no
-if test "x$font_freetype2_avail" = "xyes" ; then
- if test "x${enable_font_freetype2% *}" = "xyes" ; then
- font_freetype2_enabled=yes
- fi
-fi
-
# font unifont
font_unifont_enabled=no
if test "x$font_unifont_avail" = "xyes" ; then
@@ -1060,15 +1023,6 @@ fi
AM_CONDITIONAL([BUILD_ENABLE_FONT_UNIFONT],
[test "x$font_unifont_enabled" = "xyes"])
-# font freetype2
-if test "x$font_freetype2_enabled" = "xyes" ; then
- AC_DEFINE([BUILD_ENABLE_FONT_FREETYPE2], [1],
- [Build freetype2 font backend])
-fi
-
-AM_CONDITIONAL([BUILD_ENABLE_FONT_FREETYPE2],
- [test "x$font_freetype2_enabled" = "xyes"])
-
# font pango
if test "x$font_pango_enabled" = "xyes" ; then
AC_DEFINE([BUILD_ENABLE_FONT_PANGO], [1],
@@ -1200,7 +1154,6 @@ AC_MSG_NOTICE([Build configuration:
Font Backends:
unifont: $font_unifont_enabled ($font_unifont_avail: $font_unifont_missing)
- freetype2: $font_freetype2_enabled ($font_freetype2_avail: $font_freetype2_missing)
pango: $font_pango_enabled ($font_pango_avail: $font_pango_missing)
Renderers:
diff --git a/docs/man/kmscon.xml b/docs/man/kmscon.xml
index 8f058ff..9686bd8 100644
--- a/docs/man/kmscon.xml
+++ b/docs/man/kmscon.xml
@@ -476,7 +476,7 @@
<varlistentry>
<term><option>--font-engine {engine}</option></term>
<listitem>
- <para>Select font-engine. Available engines are 'pango', 'freetype2',
+ <para>Select font-engine. Available engines are 'pango',
'unifont' and '8x16'. (default: pango)</para>
</listitem>
</varlistentry>
diff --git a/src/font.h b/src/font.h
index cf76424..f7e4b01 100644
--- a/src/font.h
+++ b/src/font.h
@@ -111,7 +111,6 @@ int kmscon_font_render_inval(struct kmscon_font *font,
extern struct kmscon_font_ops kmscon_font_8x16_ops;
extern struct kmscon_font_ops kmscon_font_unifont_ops;
-extern struct kmscon_font_ops kmscon_font_freetype2_ops;
extern struct kmscon_font_ops kmscon_font_pango_ops;
#endif /* KMSCON_FONT_H */
diff --git a/src/font_freetype2.c b/src/font_freetype2.c
deleted file mode 100644
index a9747f6..0000000
--- a/src/font_freetype2.c
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
- * kmscon - Freetype2 font backend
- *
- * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
- * Copyright (c) 2011 University of Tuebingen
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * SECTION:font_freetype2.c
- * @short_description: Freetype2 font backend
- * @include: font.h
- *
- * The freetype2 backend uses freetype2 to render glyphs into memory
- * buffers. It uses a hashmap to cache all rendered glyphs of a single
- * font-face. Therefore, rendering should be very fast. Also, when loading a
- * glyph it pre-renders all common (mostly ASCII) characters, so it can measure
- * the font and return a valid font width.
- */
-
-#include <errno.h>
-#include <fontconfig/fontconfig.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include <libtsm.h>
-#include <pthread.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include "font.h"
-#include "shl_dlist.h"
-#include "shl_hashtable.h"
-#include "shl_log.h"
-#include "uterm_video.h"
-
-#define LOG_SUBSYSTEM "font_freetype2"
-
-struct glyph {
- bool shrinked;
- unsigned int width;
-};
-
-struct face {
- unsigned long ref;
- struct shl_dlist list;
-
- bool shrink;
- struct kmscon_font_attr attr;
- struct kmscon_font_attr real_attr;
- unsigned int baseline;
- FT_Face face;
- pthread_mutex_t glyph_lock;
- struct shl_hashtable *glyphs;
-
- struct kmscon_glyph empty;
- struct kmscon_glyph inval;
-};
-
-static pthread_mutex_t manager_mutex = PTHREAD_MUTEX_INITIALIZER;
-static unsigned long manager__refcnt;
-static FT_Library manager__lib;
-static struct shl_dlist manager__list = SHL_DLIST_INIT(manager__list);
-
-static void manager_lock()
-{
- pthread_mutex_lock(&manager_mutex);
-}
-
-static void manager_unlock()
-{
- pthread_mutex_unlock(&manager_mutex);
-}
-
-/* TODO: We currently load the default font-config configuration on start-up but
- * should probably provide a way to refresh it on SIGHUP or similar. Font-config
- * provides the FcInitBringUptoDate() or FcInitReinitialize() functions. */
-static int manager__ref()
-{
- FT_Error err;
-
- if (!manager__refcnt++) {
- err = FT_Init_FreeType(&manager__lib);
- if (err) {
- log_warn("cannot initialize freetype2");
- --manager__refcnt;
- return -EFAULT;
- }
-
- if (!FcInit()) {
- log_warn("cannot initialize fontconfig library");
- err = FT_Done_FreeType(manager__lib);
- if (err)
- log_warn("cannot deinitialize freetype2");
- --manager__refcnt;
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-static void manager__unref()
-{
- FT_Error err;
-
- if (!--manager__refcnt) {
- /* FcFini() uses assert() to check whether all resources were
- * correctly freed before FcFini() is called. As an emergency
- * console, we cannot risk being killed because we have a small
- * memory leak. Therefore, we rather skip deinitializing
- * fontconfig and blame their authors here.
- * Never ever use assert()/abort()/etc. in critical code paths!
- * Bullshit...
- * TODO: Fix upstream fontconfig to drop all those ugly
- * assertions. */
- // FcFini();
- err = FT_Done_FreeType(manager__lib);
- if (err)
- log_warn("cannot deinitialize freetype2");
- }
-}
-
-static int get_glyph(struct face *face, struct kmscon_glyph **out,
- uint32_t id, const uint32_t *ch, size_t len)
-{
- struct kmscon_glyph *glyph;
- struct glyph *data;
- FT_Error err;
- FT_UInt idx;
- FT_Bitmap *bmap;
- FT_GlyphSlot slot;
- bool res;
- unsigned int i, j, wmax, hmax, idx1, idx2, cwidth;
- int ret, hoff1, hoff2, woff1, woff2;
-
- if (!len)
- return -ERANGE;
- cwidth = tsm_ucs4_get_width(*ch);
- if (!cwidth)
- return -ERANGE;
-
- pthread_mutex_lock(&face->glyph_lock);
- res = shl_hashtable_find(face->glyphs, (void**)&glyph,
- (void*)(long)id);
- pthread_mutex_unlock(&face->glyph_lock);
- if (res) {
- *out = glyph;
- return 0;
- }
-
- manager_lock();
-
- glyph = malloc(sizeof(*glyph) + sizeof(struct glyph));
- if (!glyph) {
- log_error("cannot allocate memory for new glyph");
- ret = -ENOMEM;
- goto out_unlock;
- }
- memset(glyph, 0, sizeof(*glyph) + sizeof(struct glyph));
- glyph->data = (void*)(((uint8_t*)glyph) + sizeof(*glyph));
- data = glyph->data;
- glyph->width = cwidth;
-
- /* We currently ignore composed-symbols. That is, we only use the first
- * UCS-4 code and draw this character. This works great for most simple
- * ASCII characters but composed CJK characters often consist of
- * multiple UCS-4 codes.
- * TODO: Fix this by drawing all related characters into a single glyph
- * and saving it or simply refer to the pango backend which already does
- * that. */
- if (!*ch) {
- ret = -ERANGE;
- goto out_glyph;
- }
-
- idx = FT_Get_Char_Index(face->face, *ch);
- err = FT_Load_Glyph(face->face, idx, FT_LOAD_DEFAULT);
- if (err) {
- ret = -ERANGE;
- goto out_glyph;
- }
-
- err = FT_Render_Glyph(face->face->glyph, FT_RENDER_MODE_NORMAL);
- if (err) {
- ret = -ERANGE;
- goto out_glyph;
- }
-
- slot = face->face->glyph;
- bmap = &slot->bitmap;
- if (slot->format != FT_GLYPH_FORMAT_BITMAP ||
- bmap->pixel_mode != FT_PIXEL_MODE_GRAY ||
- bmap->num_grays != 256 ||
- !bmap->rows ||
- !bmap->width) {
- ret = -ERANGE;
- goto out_glyph;
- }
-
- data->width = bmap->width;
- glyph->buf.width = face->real_attr.width * cwidth;
- glyph->buf.height = face->real_attr.height;
- glyph->buf.stride = glyph->buf.width;
- glyph->buf.format = UTERM_FORMAT_GREY;
- glyph->buf.data = malloc(glyph->buf.stride * glyph->buf.height);
- if (!glyph->buf.data) {
- ret = -ENOMEM;
- goto out_glyph;
- }
-
- memset(glyph->buf.data, 0, glyph->buf.stride * glyph->buf.height);
-
- /* compute width-offsets and relative width-differences */
- if (slot->bitmap_left >= glyph->buf.width) {
- wmax = 0;
- woff1 = 0;
- woff2 = 0;
- } else if (slot->bitmap_left < 0) {
- if (glyph->buf.width > bmap->width)
- wmax = bmap->width;
- else
- wmax = glyph->buf.width;
- woff1 = 0;
- woff2 = 0;
- } else {
- wmax = glyph->buf.width - slot->bitmap_left;
- if (wmax > bmap->width)
- wmax = bmap->width;
- woff1 = slot->bitmap_left;
- woff2 = 0;
- }
-
- /* compute height-offsets and relative height-differences */
- hoff1 = (int)glyph->buf.height - face->baseline;
- if (hoff1 > slot->bitmap_top) {
- hoff1 -= slot->bitmap_top;
- hoff2 = 0;
- } else {
- hoff2 = slot->bitmap_top - hoff1;
- hoff1 = 0;
- }
-
- if (bmap->rows - hoff2 > glyph->buf.height - hoff1)
- hmax = glyph->buf.height - hoff1;
- else
- hmax = bmap->rows - hoff2;
-
- /* copy bitmap into glyph buffer */
- for (i = 0; i < hmax; ++i) {
- for (j = 0; j < wmax; ++j) {
- idx1 = (i + hoff1) * glyph->buf.stride + (j + woff1);
- idx2 = (i + hoff2) * bmap->pitch + (j + woff2);
- glyph->buf.data[idx1] = bmap->buffer[idx2];
- }
- }
-
- pthread_mutex_lock(&face->glyph_lock);
- ret = shl_hashtable_insert(face->glyphs, (void*)(long)id, glyph);
- pthread_mutex_unlock(&face->glyph_lock);
- if (ret) {
- log_error("cannot add glyph to hashtable");
- goto out_buffer;
- }
-
- *out = glyph;
- goto out_unlock;
-
-out_buffer:
- free(glyph->buf.data);
-out_glyph:
- free(glyph);
-out_unlock:
- manager_unlock();
- return ret;
-}
-
-static void free_glyph(void *data)
-{
- struct kmscon_glyph *glyph = data;
-
- free(glyph->buf.data);
- free(glyph);
-}
-
-static int manager_get_face(struct face **out, struct kmscon_font_attr *attr)
-{
- struct shl_dlist *iter;
- struct face *face, *f;
- FcPattern *pat, *mat;
- FcResult res;
- FcChar8 *fname;
- FT_Error err;
- int ret, tmp, idx, weight, slant;
- double s, em, xsc, ysc;
-
- manager_lock();
-
- if (!attr->height) {
- ret = -EINVAL;
- goto out_unlock;
- }
-
- if (!attr->width)
- attr->width = attr->height;
-
- shl_dlist_for_each(iter, &manager__list) {
- face = shl_dlist_entry(iter, struct face, list);
- if (kmscon_font_attr_match(&face->attr, attr)) {
- ++face->ref;
- *out = face;
- ret = 0;
- goto out_unlock;
- }
- }
-
- ret = manager__ref();
- if (ret)
- goto out_unlock;
-
- face = malloc(sizeof(*face));
- if (!face) {
- log_error("cannot allocate memory for new face");
- ret = -ENOMEM;
- goto err_manager;
- }
- memset(face, 0, sizeof(*face));
- face->ref = 1;
- memcpy(&face->attr, attr, sizeof(*attr));
- memcpy(&face->real_attr, attr, sizeof(*attr));
-
- ret = pthread_mutex_init(&face->glyph_lock, NULL);
- if (ret) {
- log_error("cannot initialize glyph lock");
- goto err_free;
- }
-
- ret = shl_hashtable_new(&face->glyphs, shl_direct_hash,
- shl_direct_equal, NULL, free_glyph);
- if (ret) {
- log_error("cannot allocate hashtable");
- goto err_lock;
- }
-
- s = face->attr.height;
- weight = face->attr.bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL;
- slant = face->attr.italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN;
- pat = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, face->attr.name,
- FC_PIXEL_SIZE, FcTypeDouble, s,
- FC_WEIGHT, FcTypeInteger, weight,
- FC_SLANT, FcTypeInteger, slant,
- NULL);
- if (!pat) {
- log_error("cannot create font-config pattern");
- ret = -EFAULT;
- goto err_htable;
- }
-
- if (!FcConfigSubstitute(NULL, pat, FcMatchPattern)) {
- FcPatternDestroy(pat);
- log_error("cannot perform font-config substitutions");
- ret = -ENOMEM;
- goto err_htable;
- }
-
- res = FcResultMatch;
- mat = FcFontMatch(NULL, pat, &res);
- if (res != FcResultMatch) {
- if (mat)
- FcPatternDestroy(mat);
- FcPatternDestroy(pat);
- log_error("font-config cannot find font: %d", res);
- ret = -EFAULT;
- goto err_htable;
- }
-
- res = FcPatternGetString(mat, FC_FILE, 0, &fname);
- if (res != FcResultMatch) {
- FcPatternDestroy(mat);
- FcPatternDestroy(pat);
- log_error("font-config cannot find font (name)");
- ret = -EFAULT;
- goto err_htable;
- }
- res = FcPatternGetInteger(mat, FC_INDEX, 0, &idx);
- if (res != FcResultMatch) {
- FcPatternDestroy(mat);
- FcPatternDestroy(pat);
- log_error("font-config cannot find font (index)");
- ret = -EFAULT;
- goto err_htable;
- }
-
- log_debug("loading font %s:%d", (const char*)fname, idx);
- err = FT_New_Face(manager__lib, (const char*)fname, idx, &face->face);
- FcPatternDestroy(mat);
- FcPatternDestroy(pat);
-
- if (err) {
- if (err == FT_Err_Unknown_File_Format)
- log_error("unknown font file format");
- else
- log_error("cannot load font");
-
- ret = -EFAULT;
- goto err_htable;
- }
-
- if (!face->face->charmap) {
- log_warn("cannot load charmap of new font");
- ret = -EFAULT;
- goto err_face;
- }
-
- if (!FT_IS_SCALABLE(face->face)) {
- log_warn("non-scalable font");
- ret = -EFAULT;
- goto err_face;
- }
-
- err = FT_Set_Pixel_Sizes(face->face, face->attr.width,
- face->attr.height);
- if (err) {
- log_warn("cannot set pixel size of font");
- ret = -EFAULT;
- goto err_face;
- }
-
- /* Every font provides an ascender/descender value which we use to
- * compute glyph-height and the baseline offset. We need monospace fonts
- * as we have the same fixed bounding-box for every glyph. However, if
- * the font is not a monospace font, then the most straight-forward
- * approach would be using the biggest bounding box. This, however, will
- * not work as some characters are extremely wide and the text will look
- * horrible. Therefore, we use the ascender/descender values provided
- * with each font. This guarantees that special characters like
- * line-segments are properly aligned without spacing. If the font does
- * not provide proper asc/desc values, then freetype2 will return proper
- * substitutions. */
-
- em = face->face->units_per_EM;
- xsc = face->face->size->metrics.x_ppem / em;
- ysc = face->face->size->metrics.y_ppem / em;
-
- tmp = face->face->descender * ysc;
- if (tmp > 0)
- tmp = 0;
- face->baseline = -tmp;
-
- tmp = face->face->ascender * ysc + face->baseline;
- if (tmp < 0 || tmp < face->baseline) {
- log_warn("invalid ascender/descender values for font");
- ret = -EFAULT;
- goto err_face;
- }
- face->real_attr.height = tmp;
-
- /* For font-width we use the biggest bounding-box-width. After the font
- * has been loaded, this is cut down by pre-rendering some characters
- * and computing a better average. */
-
- tmp = 1 + (int)(xsc * (face->face->bbox.xMax - face->face->bbox.xMin));
- if (tmp < 0)
- tmp = 0;
- face->real_attr.width = tmp;
-
- kmscon_font_attr_normalize(&face->real_attr);
- if (!face->real_attr.height || !face->real_attr.width) {
- log_warn("invalid scaled font sizes");
- ret = -EFAULT;
- goto err_face;
- }
-
- /* The real metrics probably differ from the requested metrics so try
- * again to find a suitable cached font. */
- shl_dlist_for_each(iter, &manager__list) {
- f = shl_dlist_entry(iter, struct face, list);
- if (kmscon_font_attr_match(&f->real_attr, &face->real_attr)) {
- ++f->ref;
- *out = f;
- ret = 0;
- goto err_face;
- }
- }
-
- shl_dlist_link(&manager__list, &face->list);
- *out = face;
- ret = 0;
- goto out_unlock;
-
-err_face:
- FT_Done_Face(face->face);
-err_htable:
- shl_hashtable_free(face->glyphs);
-err_lock:
- pthread_mutex_destroy(&face->glyph_lock);
-err_free:
- free(face);
-err_manager:
- manager__unref();
-out_unlock:
- manager_unlock();
- return ret;
-}
-
-static void manager_put_face(struct face *face)
-{
- manager_lock();
-
- if (!--face->ref) {
- shl_dlist_unlink(&face->list);
- shl_hashtable_free(face->glyphs);
- pthread_mutex_destroy(&face->glyph_lock);
- FT_Done_Face(face->face);
- free(face);
- manager__unref();
- }
-
- manager_unlock();
-}
-
-static int generate_specials(struct face *face)
-{
- size_t s;
- struct kmscon_glyph *g;
- int ret;
- static const uint32_t question_mark = '?';
-
- face->empty.width = 1;
- face->empty.data = NULL;
- face->empty.buf.width = face->real_attr.width;
- face->empty.buf.height = face->real_attr.height;
- face->empty.buf.stride = face->empty.buf.width;
- face->empty.buf.format = UTERM_FORMAT_GREY;
- s = face->empty.buf.stride * face->empty.buf.height;
- face->empty.buf.data = malloc(s);
- if (!face->empty.buf.data)
- return -ENOMEM;
-
- memset(face->empty.buf.data, 0, s);
-
- ret = get_glyph(face, &g, question_mark, &question_mark, 1);
- if (ret) {
- memcpy(&face->inval, &face->empty, sizeof(face->inval));
- } else {
- memcpy(&face->inval, g, sizeof(face->inval));
- }
-
- return 0;
-}
-
-static int kmscon_font_freetype2_init(struct kmscon_font *out,
- const struct kmscon_font_attr *attr)
-{
- struct face *face = NULL;
- int ret;
- unsigned int width;
- uint32_t i;
- struct kmscon_glyph *glyph;
- struct glyph *data;
-
- memcpy(&out->attr, attr, sizeof(*attr));
- kmscon_font_attr_normalize(&out->attr);
-
- log_debug("loading freetype2 font %s", out->attr.name);
-
- ret = manager_get_face(&face, &out->attr);
- if (ret)
- return ret;
- memcpy(&out->attr, &face->real_attr, sizeof(out->attr));
- out->baseline = face->baseline;
-
- /* Shrinking is done to get a better width-value for fonts. As not all
- * fonts provide monospace-glyphs, we need to calculate a proper width
- * by pre-rendering all ASCII characters and using the widest value.
- * TODO: We should extend this with a better algorithm as there are
- * common non-ASCII glyphs which are much wider.
- * We enable shrinking by default as most fonts have a maximum-width
- * which is about 3 times the size of 'M'.*/
- face->shrink = true;
-
- if (face->shrink) {
- width = 0;
- for (i = 0x20; i < 0x7f; ++i) {
- ret = get_glyph(face, &glyph, i, &i, 1);
- if (ret)
- continue;
- data = glyph->data;
-
- if (data->width > width)
- width = data->width;
- }
-
- if (!width) {
- log_warning("cannot measure font");
- face->shrink = false;
- } else if (width < face->real_attr.width) {
- face->real_attr.width = width;
- kmscon_font_attr_normalize(&face->real_attr);
- memcpy(&out->attr, &face->real_attr, sizeof(out->attr));
- }
- }
-
- /* generate inval/empty glyphs after shrinking */
- ret = generate_specials(face);
- if (ret)
- goto err_face;
-
- out->data = face;
- return 0;
-
-err_face:
- manager_put_face(face);
- return ret;
-}
-
-static void kmscon_font_freetype2_destroy(struct kmscon_font *font)
-{
- struct face *face;
-
- face = font->data;
- log_debug("unloading freetype2 font %s", face->real_attr.name);
- free(face->empty.buf.data);
- manager_put_face(face);
-}
-
-static int kmscon_font_freetype2_render(struct kmscon_font *font, uint32_t id,
- const uint32_t *ch, size_t len,
- const struct kmscon_glyph **out)
-{
- struct kmscon_glyph *glyph;
- struct glyph *data;
- struct face *face;
- int ret;
-
- ret = get_glyph(font->data, &glyph, id, ch, len);
- if (ret)
- return ret;
-
- face = font->data;
- data = glyph->data;
- if (face->shrink && !data->shrinked) {
- data->shrinked = true;
- glyph->buf.width = face->real_attr.width * glyph->width;
- }
-
- *out = glyph;
- return 0;
-}
-
-static int kmscon_font_freetype2_render_empty(struct kmscon_font *font,
- const struct kmscon_glyph **out)
-{
- struct face *face = font->data;
-
- *out = &face->empty;
- return 0;
-}
-
-static int kmscon_font_freetype2_render_inval(struct kmscon_font *font,
- const struct kmscon_glyph **out)
-{
- struct face *face = font->data;
-
- *out = &face->inval;
- return 0;
-}
-
-struct kmscon_font_ops kmscon_font_freetype2_ops = {
- .name = "freetype2",
- .owner = NULL,
- .init = kmscon_font_freetype2_init,
- .destroy = kmscon_font_freetype2_destroy,
- .render = kmscon_font_freetype2_render,
- .render_empty = kmscon_font_freetype2_render_empty,
- .render_inval = kmscon_font_freetype2_render_inval,
-};
diff --git a/src/kmscon_mod_freetype2.c b/src/kmscon_mod_freetype2.c
deleted file mode 100644
index 39e4fe6..0000000
--- a/src/kmscon_mod_freetype2.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * kmscon - Freetype2 font backend module
- *
- * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * Freetype2 font backend module
- * This module registers the freetype2 font backend with kmscon.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include "font.h"
-#include "kmscon_module_interface.h"
-#include "shl_log.h"
-
-#define LOG_SUBSYSTEM "mod_freetype2"
-
-static int kmscon_freetype2_load(void)
-{
- int ret;
-
- kmscon_font_freetype2_ops.owner = KMSCON_THIS_MODULE;
- ret = kmscon_font_register(&kmscon_font_freetype2_ops);
- if (ret) {
- log_error("cannot register pango font");
- return ret;
- }
-
- return 0;
-}
-
-static void kmscon_freetype2_unload(void)
-{
- kmscon_font_unregister(kmscon_font_freetype2_ops.name);
-}
-
-KMSCON_MODULE(NULL, kmscon_freetype2_load, kmscon_freetype2_unload, NULL);