Remove freetype2 font backend
authorDavid Herrmann <dh.herrmann@gmail.com>
Tue, 29 Oct 2013 08:31:03 +0000 (09:31 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Tue, 29 Oct 2013 08:31:03 +0000 (09:31 +0100)
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>
Makefile.am
README
configure.ac
docs/man/kmscon.xml
src/font.h
src/font_freetype2.c [deleted file]
src/kmscon_mod_freetype2.c [deleted file]

index 4af0d36..52a14eb 100644 (file)
@@ -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 (file)
--- 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.
index dac4bcd..6c975c5 100644 (file)
@@ -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:
index 8f058ff..9686bd8 100644 (file)
       <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>
index cf76424..f7e4b01 100644 (file)
@@ -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 (file)
index a9747f6..0000000
+++ /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 (file)
index 39e4fe6..0000000
+++ /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);