font: add unfinished freetype backend
authorDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 1 Jan 2012 22:11:48 +0000 (23:11 +0100)
committerDavid Herrmann <dh.herrmann@googlemail.com>
Sun, 1 Jan 2012 22:11:48 +0000 (23:11 +0100)
This is a first attempt of a freetype2 backend for the font drawing functions.
This avoids the heavy pango/cairo dependencies, although, we might lose
important font handling that pango does for us like correctly drawing combined
characters.

This is still a stub implementation. The drawing operations are not supported,
yet. Use --enable-pango during configure to enable the still working pango
backend.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Makefile.am
configure.ac
src/font_freetype.c [new file with mode: 0644]

index 37d6f65..1140600 100644 (file)
@@ -24,7 +24,6 @@ libkmscon_core_la_SOURCES = \
        src/output.c src/output.h \
        src/console_cell.c \
        src/unicode.c src/unicode.h \
-       src/font_pango.c src/font.h \
        src/log.c src/log.h \
        src/eloop.c src/eloop.h \
        src/vt.c src/vt.h \
@@ -34,25 +33,35 @@ libkmscon_core_la_SOURCES = \
        src/vte.c src/vte.h \
        src/terminal.c src/terminal.h
 
+if USE_PANGO
+libkmscon_core_la_SOURCES += \
+       src/font_pango.c src/font.h
+else
+libkmscon_core_la_SOURCES += \
+       src/font_freetype.c src/font.h
+endif
+
 libkmscon_core_la_CPPFLAGS = \
        $(AM_CPPFLAGS) \
        $(DRM_CFLAGS) \
        $(EGL_CFLAGS) \
        $(GBM_CFLAGS) \
        $(OPENGL_CFLAGS) \
-       $(CAIRO_CFLAGS) \
        $(PANGO_CFLAGS) \
        $(UDEV_CFLAGS) \
-       $(XKBCOMMON_CFLAGS)
+       $(FREETYPE2_CFLAGS) \
+       $(XKBCOMMON_CFLAGS) \
+       $(GLIB_CFLAGS)
 libkmscon_core_la_LIBADD = \
        $(DRM_LIBS) \
        $(EGL_LIBS) \
        $(GBM_LIBS) \
        $(OPENGL_LIBS) \
-       $(CAIRO_LIBS) \
        $(PANGO_LIBS) \
        $(UDEV_LIBS) \
-       $(XKBCOMMON_LIBS)
+       $(FREETYPE2_LIBS) \
+       $(XKBCOMMON_LIBS) \
+       $(GLIB_LIBS)
 
 kmscon_SOURCES = src/main.c
 kmscon_LDADD = libkmscon-core.la
@@ -63,8 +72,7 @@ test_console_LDADD = \
        $(OPENGL_LIBS)
 test_console_CPPFLAGS = \
        $(AM_CPPFLAGS) \
-       $(OPENGL_CFLAGS) \
-       $(CAIRO_CFLAGS)
+       $(OPENGL_CFLAGS)
 
 test_output_SOURCES = tests/test_output.c
 test_output_LDADD = \
index a193bb6..d8f28a8 100644 (file)
@@ -37,14 +37,6 @@ PKG_CHECK_MODULES([OPENGL], [gl])
 AC_SUBST(OPENGL_CFLAGS)
 AC_SUBST(OPENGL_LIBS)
 
-PKG_CHECK_MODULES([CAIRO], [cairo])
-AC_SUBST(CAIRO_CFLAGS)
-AC_SUBST(CAIRI_LIBS)
-
-PKG_CHECK_MODULES([PANGO], [pango pangocairo])
-AC_SUBST(PANGO_CFLAGS)
-AC_SUBST(PANGO_LIBS)
-
 PKG_CHECK_MODULES([UDEV], [libudev])
 AC_SUBST(UDEV_CFLAGS)
 AC_SUBST(UDEV_LIBS)
@@ -53,6 +45,33 @@ PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon])
 AC_SUBST(XKBCOMMON_CFLAGS)
 AC_SUBST(XKBCOMMON_LIBS)
 
+PKG_CHECK_MODULES([GLIB], [glib-2.0])
+AC_SUBST(GLIB_CFLAGS)
+AC_SUBST(GLIB_LIBS)
+
+PKG_CHECK_MODULES([FREETYPE2], [freetype2])
+AC_SUBST(FREETYPE2_CFLAGS)
+AC_SUBST(FREETYPE2_LIBS)
+
+PKG_CHECK_MODULES([PANGO], [pango pangocairo cairo],
+                  [have_pango=yes], [have_pango=no])
+AC_SUBST(PANGO_CFLAGS)
+AC_SUBST(PANGO_LIBS)
+
+AC_MSG_CHECKING([whether to use pango font backend])
+AC_ARG_ENABLE([pango],
+              [AS_HELP_STRING([--enable-pango], [whether to use pango font backend])],
+              [force_pango="$enableval";
+               AC_DEFINE([USE_PANGO], [1], [Define if pango should be used])],
+              [force_pango=no])
+AC_MSG_RESULT([$force_pango])
+
+if test x$force_pango = xyes -a $have_pango = xno ; then
+       AC_ERROR([Pango library not found])
+fi
+
+AM_CONDITIONAL([USE_PANGO], [test x$force_pango = xyes])
+
 AC_MSG_CHECKING([whether to build with debugging on])
 AC_ARG_ENABLE([debug],
               [AS_HELP_STRING([--enable-debug], [whether to build with debugging on)])],
diff --git a/src/font_freetype.c b/src/font_freetype.c
new file mode 100644 (file)
index 0000000..afbee22
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * kmscon - Font Handling
+ *
+ * Copyright (c) 2011 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.
+ */
+
+/*
+ * Font Handling
+ * TODO
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "font.h"
+#include "log.h"
+#include "unicode.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+struct kmscon_font_factory {
+       unsigned long ref;
+       struct kmscon_symbol_table *st;
+       FT_Library lib;
+};
+
+struct kmscon_font {
+       unsigned long ref;
+
+       struct kmscon_font_factory *ff;
+       FT_Face face;
+       unsigned int width;
+       unsigned int height;
+};
+
+struct kmscon_glyph {
+       unsigned long ref;
+};
+
+int kmscon_font_factory_new(struct kmscon_font_factory **out,
+                                       struct kmscon_symbol_table *st)
+{
+       struct kmscon_font_factory *ff;
+       FT_Error err;
+       int ret;
+
+       if (!out)
+               return -EINVAL;
+
+       ff = malloc(sizeof(*ff));
+       if (!ff)
+               return -ENOMEM;
+
+       memset(ff, 0, sizeof(*ff));
+       ff->ref = 1;
+       ff->st = st;
+
+       err = FT_Init_FreeType(&ff->lib);
+       if (err) {
+               log_warning("font: cannot initialize FreeType library\n");
+               ret = -EFAULT;
+               goto err_free;
+       }
+
+       kmscon_symbol_table_ref(ff->st);
+       *out = ff;
+
+       return 0;
+
+err_free:
+       free(ff);
+       return ret;
+}
+
+void kmscon_font_factory_ref(struct kmscon_font_factory *ff)
+{
+       if (!ff)
+               return;
+
+       ++ff->ref;
+}
+
+void kmscon_font_factory_unref(struct kmscon_font_factory *ff)
+{
+       FT_Error err;
+
+       if (!ff || !ff->ref)
+               return;
+
+       if (--ff->ref)
+               return;
+
+       err = FT_Done_FreeType(ff->lib);
+       if (err)
+               log_warning("font: cannot deinitialize FreeType library\n");
+
+       free(ff);
+}
+
+int kmscon_font_factory_load(struct kmscon_font_factory *ff,
+       struct kmscon_font **out, unsigned int width, unsigned int height)
+{
+       struct kmscon_font *font;
+       FT_Error err;
+       const char *estr = "unknown error";
+       int ret;
+
+       if (!ff || !out)
+               return -EINVAL;
+
+       font = malloc(sizeof(*font));
+       if (!font)
+               return -ENOMEM;
+
+       memset(font, 0, sizeof(*font));
+       font->ref = 1;
+       font->width = width;
+       font->height = height;
+
+       err = FT_New_Face(ff->lib, "/usr/share/fonts/TTF/DejaVuSansMono.ttf",
+                                                       0, &font->face);
+       if (err) {
+               if (err == FT_Err_Unknown_File_Format)
+                       estr = "unknown file format";
+
+               log_warning("font: cannot load font: %s\n", estr);
+               ret = -EFAULT;
+               goto err_free;
+       }
+
+       if (!font->face->charmap) {
+               log_warning("font: cannot load charmap of new font\n");
+               ret = -EFAULT;
+               goto err_face;
+       }
+
+       err = FT_Set_Pixel_Sizes(font->face, width, height);
+       if (err) {
+               log_warning("font: cannot set pixel size of font\n");
+               ret = -EFAULT;
+               goto err_face;
+       }
+
+       kmscon_font_factory_ref(ff);
+       font->ff = ff;
+       *out = font;
+
+       return 0;
+
+err_face:
+       FT_Done_Face(font->face);
+err_free:
+       free(font);
+       return ret;
+}
+
+void kmscon_font_ref(struct kmscon_font *font)
+{
+       if (!font)
+               return;
+
+       ++font->ref;
+}
+
+void kmscon_font_unref(struct kmscon_font *font)
+{
+       if (!font || !font->ref)
+               return;
+
+       if (--font->ref)
+               return;
+
+       FT_Done_Face(font->face);
+       kmscon_font_factory_unref(font->ff);
+       free(font);
+}
+
+unsigned int kmscon_font_get_height(struct kmscon_font *font)
+{
+       if (!font)
+               return 0;
+
+       return font->height;
+}
+
+unsigned int kmscon_font_get_width(struct kmscon_font *font)
+{
+       if (!font)
+               return 0;
+
+       return font->width;
+}
+
+int kmscon_font_draw(struct kmscon_font *font, kmscon_symbol_t ch,
+                                       void *dcr, uint32_t x, uint32_t y)
+{
+       if (!font)
+               return -EINVAL;
+
+       /* still TODO */
+
+       return 0;
+}