From 04fd53750abc1f792ab6d5bdf7416bd7c42451b2 Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Mon, 25 Jan 2016 08:58:03 +0100 Subject: [PATCH 1/2] Add label-ft plugin This adds a FreeType-based label plugin with minimal dependencies. Is is a replacement for the label plugin, except that it lacks support for Unicode and different fonts families. It's purpose is to be included in the initrd, which isn't easily possible with the label plugin due to it's massive dependency list. Signed-off-by: Fabian Vogt --- configure.ac | 10 + src/libply-splash-graphics/ply-label.c | 5 + src/plugins/controls/Makefile.am | 6 +- src/plugins/controls/label-ft/Makefile.am | 22 ++ src/plugins/controls/label-ft/plugin.c | 501 ++++++++++++++++++++++++++++++ 5 files changed, 543 insertions(+), 1 deletion(-) create mode 100644 src/plugins/controls/label-ft/Makefile.am create mode 100644 src/plugins/controls/label-ft/plugin.c Index: b/configure.ac =================================================================== --- a/configure.ac +++ b/configure.ac @@ -75,6 +75,15 @@ if test x$enable_pango = xyes; then AC_SUBST(PANGO_LIBS) fi +AC_ARG_ENABLE(freetype, AS_HELP_STRING([--enable-freetype],[enable building the FreeType-based label plugin]),enable_freetype=$enableval,enable_freetype=yes) +AM_CONDITIONAL(ENABLE_FREETYPE, [test "$enable_freetype" = yes]) + +if test x$enable_freetype = xyes; then + PKG_CHECK_MODULES(FREETYPE, [freetype2]) + AC_SUBST(FREETYPE_CFLAGS) + AC_SUBST(FREETYPE_LIBS) +fi + AC_ARG_ENABLE(gtk, AS_HELP_STRING([--enable-gtk],[enable building with gtk, disabled there is no x11 renderer]),enable_gtk=$enableval,enable_gtk=yes) AM_CONDITIONAL(ENABLE_GTK, [test "$enable_gtk" = yes]) @@ -315,6 +324,7 @@ AC_CONFIG_FILES([Makefile po/Makefile.in src/plugins/splash/script/Makefile src/plugins/controls/Makefile src/plugins/controls/label/Makefile + src/plugins/controls/label-ft/Makefile src/Makefile src/client/ply-boot-client.pc src/client/Makefile Index: b/src/libply-splash-graphics/ply-label.c =================================================================== --- a/src/libply-splash-graphics/ply-label.c +++ b/src/libply-splash-graphics/ply-label.c @@ -96,8 +96,13 @@ ply_label_load_plugin (ply_label_t *labe get_plugin_interface_function_t get_label_plugin_interface; + /* Try the pango/cairo based label plugin first... */ label->module_handle = ply_open_module (PLYMOUTH_PLUGIN_PATH "label.so"); + /* ...and the FreeType based one after that, it is not a complete substitute (yet). */ + if (label->module_handle == NULL) + label->module_handle = ply_open_module (PLYMOUTH_PLUGIN_PATH "label-ft.so"); + if (label->module_handle == NULL) return false; Index: b/src/plugins/controls/label-ft/Makefile.am =================================================================== --- /dev/null +++ b/src/plugins/controls/label-ft/Makefile.am @@ -0,0 +1,22 @@ +AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir)/../../../libply \ + -I$(srcdir)/../../../libply-splash-core \ + -I$(srcdir)/../../../libply-splash-graphics \ + -I$(srcdir)/../../.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/.. \ + -I$(srcdir) + +plugindir = $(libdir)/plymouth +plugin_LTLIBRARIES = label-ft.la + +label_ft_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(FREETYPE_CFLAGS) + +label_ft_la_LDFLAGS = -module -avoid-version -export-dynamic +label_ft_la_LIBADD = $(PLYMOUTH_LIBS) $(FREETYPE_LIBS) \ + ../../../libply/libply.la \ + ../../../libply-splash-core/libply-splash-core.la \ + ../../../libply-splash-graphics/libply-splash-graphics.la +label_ft_la_SOURCES = $(srcdir)/plugin.c + +MAINTAINERCLEANFILES = Makefile.in Index: b/src/plugins/controls/label-ft/Makefile.in =================================================================== --- /dev/null +++ b/src/plugins/controls/label-ft/Makefile.in @@ -0,0 +1,753 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/plugins/controls/label-ft +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +label_ft_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + ../../../libply/libply.la \ + ../../../libply-splash-core/libply-splash-core.la \ + ../../../libply-splash-graphics/libply-splash-graphics.la +am_label_ft_la_OBJECTS = label_ft_la-plugin.lo +label_ft_la_OBJECTS = $(am_label_ft_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +label_ft_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(label_ft_la_CFLAGS) \ + $(CFLAGS) $(label_ft_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-tools/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/label_ft_la-plugin.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(label_ft_la_SOURCES) +DIST_SOURCES = $(label_ft_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-tools/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CURSES_LIBS = @CURSES_LIBS@ +CYGPATH_W = @CYGPATH_W@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DRM_CFLAGS = @DRM_CFLAGS@ +DRM_LIBS = @DRM_LIBS@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +GTK_CFLAGS = @GTK_CFLAGS@ +GTK_LIBS = @GTK_LIBS@ +IMAGE_CFLAGS = @IMAGE_CFLAGS@ +IMAGE_LIBS = @IMAGE_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_AGE = @LT_AGE@ +LT_CURRENT = @LT_CURRENT@ +LT_REVISION = @LT_REVISION@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGO_CFLAGS = @PANGO_CFLAGS@ +PANGO_LIBS = @PANGO_LIBS@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLYMOUTH_CFLAGS = @PLYMOUTH_CFLAGS@ +PLYMOUTH_CLIENT_DIR = @PLYMOUTH_CLIENT_DIR@ +PLYMOUTH_CONF_DIR = @PLYMOUTH_CONF_DIR@ +PLYMOUTH_DAEMON_DIR = @PLYMOUTH_DAEMON_DIR@ +PLYMOUTH_DATADIR = @PLYMOUTH_DATADIR@ +PLYMOUTH_LIBDIR = @PLYMOUTH_LIBDIR@ +PLYMOUTH_LIBEXECDIR = @PLYMOUTH_LIBEXECDIR@ +PLYMOUTH_LIBS = @PLYMOUTH_LIBS@ +PLYMOUTH_LOGO_FILE = @PLYMOUTH_LOGO_FILE@ +PLYMOUTH_PLUGIN_PATH = @PLYMOUTH_PLUGIN_PATH@ +PLYMOUTH_POLICY_DIR = @PLYMOUTH_POLICY_DIR@ +PLYMOUTH_RUNTIME_DIR = @PLYMOUTH_RUNTIME_DIR@ +PLYMOUTH_RUNTIME_THEME_PATH = @PLYMOUTH_RUNTIME_THEME_PATH@ +PLYMOUTH_THEME_PATH = @PLYMOUTH_THEME_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +RELEASE_FILE = @RELEASE_FILE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYSTEMD_ASK_PASSWORD_AGENT = @SYSTEMD_ASK_PASSWORD_AGENT@ +SYSTEMD_UNIT_DIR = @SYSTEMD_UNIT_DIR@ +UDEVADM = @UDEVADM@ +UDEV_CFLAGS = @UDEV_CFLAGS@ +UDEV_LIBS = @UDEV_LIBS@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +XSLTPROC = @XSLTPROC@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +background_color = @background_color@ +background_end_color = @background_end_color@ +background_start_color = @background_start_color@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logofile = @logofile@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +plymouthclientdir = @plymouthclientdir@ +plymouthdaemondir = @plymouthdaemondir@ +plymouthruntimedir = @plymouthruntimedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir) \ + -I$(srcdir)/../../../libply \ + -I$(srcdir)/../../../libply-splash-core \ + -I$(srcdir)/../../../libply-splash-graphics \ + -I$(srcdir)/../../.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/.. \ + -I$(srcdir) + +plugindir = $(libdir)/plymouth +plugin_LTLIBRARIES = label-ft.la +label_ft_la_CFLAGS = $(PLYMOUTH_CFLAGS) $(FREETYPE_CFLAGS) +label_ft_la_LDFLAGS = -module -avoid-version -export-dynamic +label_ft_la_LIBADD = $(PLYMOUTH_LIBS) $(FREETYPE_LIBS) \ + ../../../libply/libply.la \ + ../../../libply-splash-core/libply-splash-core.la \ + ../../../libply-splash-graphics/libply-splash-graphics.la + +label_ft_la_SOURCES = $(srcdir)/plugin.c +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/plugins/controls/label-ft/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/plugins/controls/label-ft/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +label-ft.la: $(label_ft_la_OBJECTS) $(label_ft_la_DEPENDENCIES) $(EXTRA_label_ft_la_DEPENDENCIES) + $(AM_V_CCLD)$(label_ft_la_LINK) -rpath $(plugindir) $(label_ft_la_OBJECTS) $(label_ft_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/label_ft_la-plugin.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +label_ft_la-plugin.lo: $(srcdir)/plugin.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(label_ft_la_CFLAGS) $(CFLAGS) -MT label_ft_la-plugin.lo -MD -MP -MF $(DEPDIR)/label_ft_la-plugin.Tpo -c -o label_ft_la-plugin.lo `test -f '$(srcdir)/plugin.c' || echo '$(srcdir)/'`$(srcdir)/plugin.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/label_ft_la-plugin.Tpo $(DEPDIR)/label_ft_la-plugin.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/plugin.c' object='label_ft_la-plugin.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(label_ft_la_CFLAGS) $(CFLAGS) -c -o label_ft_la-plugin.lo `test -f '$(srcdir)/plugin.c' || echo '$(srcdir)/'`$(srcdir)/plugin.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/label_ft_la-plugin.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/label_ft_la-plugin.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-pluginLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pluginLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pluginLTLIBRARIES + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: Index: b/src/plugins/controls/label-ft/plugin.c =================================================================== --- /dev/null +++ b/src/plugins/controls/label-ft/plugin.c @@ -0,0 +1,507 @@ +/* ply-label.c - label control + * + * Copyright (C) 2008 Red Hat, Inc. + * Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by: Ray Strode + * Written by: Fabian Vogt + */ +#include "config.h" + +#include +#include +#include +#include + +#include +#include FT_FREETYPE_H + +#include "ply-pixel-buffer.h" +#include "ply-pixel-display.h" +#include "ply-utils.h" + +#include "ply-label-plugin.h" + +/* This is used if fontconfig (fc-match) is not available, like in the initrd. */ +#define FONT_FALLBACK "/usr/share/fonts/Plymouth.ttf" + +struct _ply_label_plugin_control +{ + ply_pixel_display_t *display; + ply_rectangle_t area; + + ply_label_alignment_t alignment; + long width; /* For alignment */ + + FT_Library library; + FT_Face face; + + char *text; + float red; + float green; + float blue; + float alpha; + + bool is_hidden; +}; + +ply_label_plugin_interface_t *ply_label_plugin_get_interface (void); + +/* Query fontconfig, if available, for the default font. */ +static const char * +query_fc_match() +{ + FILE *fp; + static char fc_match_out[PATH_MAX]; + + fp = popen("/usr/bin/fc-match -f %{file}", "r"); + if (!fp) + return NULL; + + fgets(fc_match_out, sizeof(fc_match_out), fp); + + pclose(fp); + + return fc_match_out; +} + +static ply_label_plugin_control_t * +create_control (void) +{ + FT_Error error; + ply_label_plugin_control_t *label; + const char *font_path; + + label = calloc (1, sizeof(ply_label_plugin_control_t)); + if(!label) + return NULL; + + label->is_hidden = true; + label->width = -1; + label->text = NULL; + + error = FT_Init_FreeType (&label->library); + if(error) + { + free(label); + return NULL; + } + + font_path = query_fc_match(); + + if(font_path) + error = FT_New_Face (label->library, font_path, 0, &label->face); + + if(!font_path || error) + { + font_path = FONT_FALLBACK; + error = FT_New_Face (label->library, font_path, 0, &label->face); + + if(error) + { + FT_Done_FreeType (label->library); + free(label); + return NULL; + } + } + + /* 12pt/100dpi as default */ + error = FT_Set_Char_Size (label->face, 12 << 6, 0, 100, 0); + if(error) + { + FT_Done_Face (label->face); + FT_Done_FreeType (label->library); + free(label); + return NULL; + } + + return label; +} + +static void +destroy_control (ply_label_plugin_control_t *label) +{ + if (label == NULL) + return; + + free (label->text); + FT_Done_Face (label->face); + FT_Done_FreeType (label->library); + + free (label); +} + +static long +get_width_of_control (ply_label_plugin_control_t *label) +{ + return label->area.width; +} + +static long +get_height_of_control (ply_label_plugin_control_t *label) +{ + return label->area.height; +} + +static FT_Int width_of_line(ply_label_plugin_control_t *label, + const char *text) +{ + FT_Int width = 0; + FT_Int last_left = 0; + + while(*text != '\0' && *text != '\n') + { + if(FT_Load_Char (label->face, *text, FT_LOAD_RENDER)) + continue; + + width += label->face->glyph->advance.x >> 6; + last_left = label->face->glyph->bitmap_left; + + ++text; + } + + return width + last_left; +} + +static void +size_control (ply_label_plugin_control_t *label) +{ + FT_Int width; + const char *text = label->text; + + if(label->is_hidden) + return; + + label->area.width = 0; + label->area.height = 0; + + /* Go through each line */ + while(text && *text) + { + width = width_of_line (label, text); + if((uint32_t) width > label->area.width) + label->area.width = width; + + label->area.height += (label->face->size->metrics.ascender - label->face->size->metrics.descender) >> 6; + + text = strchr (text, '\n'); + /* skip newline character */ + if (text) + ++text; + } + + /* If centered, area.x is not the origin anymore */ + if((long) label->area.width < label->width) + label->area.width = label->width; +} + +static void trigger_redraw (ply_label_plugin_control_t *label, + bool adjust_size) +{ + ply_rectangle_t dirty_area = label->area; + + if (label->is_hidden || label->display == NULL) + return; + + if(adjust_size) + size_control(label); + + ply_pixel_display_draw_area (label->display, + dirty_area.x, dirty_area.y, + dirty_area.width, dirty_area.height); +} + +static FT_Int +min (FT_Int a, + FT_Int b) +{ + return a < b ? a : b; +} + +static void +draw_bitmap (ply_label_plugin_control_t *label, + uint32_t *target, + ply_rectangle_t target_size, + FT_Bitmap *source, + FT_Int x_start, + FT_Int y_start) +{ + FT_Int x, y, xs, ys; + FT_Int x_end = min (x_start + source->width, target_size.width); + FT_Int y_end = min (y_start + source->rows, target_size.height); + + if((uint32_t) x_start >= target_size.width || (uint32_t) y_start >= target_size.height) + return; + + uint8_t rs, gs, bs, rd, gd, bd, ad; + rs = 255 * label->red; + gs = 255 * label->green; + bs = 255 * label->blue; + + for(y = y_start, ys = 0; y < y_end; ++y, ++ys) + for(x = x_start, xs = 0; x < x_end; ++x, ++xs) + { + float alpha = label->alpha * (source->buffer[xs + source->pitch * ys] / 255.0f); + float invalpha = 1.0f - alpha; + uint32_t dest = target[x + target_size.width * y]; + + /* Separate colors */ + rd = dest >> 16; + gd = dest >> 8; + bd = dest; + + /* Alpha blending */ + rd = invalpha * rd + alpha * rs; + gd = invalpha * gd + alpha * gs; + bd = invalpha * bd + alpha * bs; + /* Semi-correct: Disregard the target alpha */ + ad = alpha * 255; + + target[x + target_size.width * y] = (ad << 24) | (rd << 16) | (gd << 8) | bd; + } +} + +static void +draw_control (ply_label_plugin_control_t *label, + ply_pixel_buffer_t *pixel_buffer, + long x, + long y, + unsigned long width, + unsigned long height) +{ + FT_Error error; + FT_Vector pen; + FT_GlyphSlot slot; + const char *cur_c; + uint32_t *target; + ply_rectangle_t target_size; + + if (label->is_hidden) + return; + + /* Check for overlap. + TODO: Don't redraw everything if only a part should be drawn! */ + if(label->area.x > x + (long) width || label->area.y > y + (long) height + || label->area.x + (long) label->area.width < x + || label->area.y + (long) label->area.height < y) + return; + + slot = label->face->glyph; + + cur_c = label->text; + + target = ply_pixel_buffer_get_argb32_data (pixel_buffer); + ply_pixel_buffer_get_size (pixel_buffer, &target_size); + + if(target_size.height == 0) + return; /* This happens sometimes. */ + + /* 64ths of a pixel */ + pen.y = label->area.y << 6; + + /* Make sure that the first row fits */ + pen.y += label->face->size->metrics.ascender; + + /* Go through each line */ + while(*cur_c) + { + pen.x = label->area.x << 6; + + /* Start at start position (alignment) */ + if(label->alignment == PLY_LABEL_ALIGN_CENTER) + pen.x += (label->width - width_of_line(label, cur_c)) << 5; + else if(label->alignment == PLY_LABEL_ALIGN_RIGHT) + pen.x += (label->width - width_of_line(label, cur_c)) << 6; + + while(*cur_c && *cur_c != '\n') + { + /* TODO: Unicode support. */ + error = FT_Load_Char (label->face, *cur_c, FT_LOAD_RENDER | FT_LOAD_TARGET_LIGHT); + if(error) + continue; + + draw_bitmap (label, target, target_size, &slot->bitmap, + (pen.x >> 6) + slot->bitmap_left, + (pen.y >> 6) - slot->bitmap_top); + + pen.x += slot->advance.x; + pen.y += slot->advance.y; + + ++cur_c; + } + /* skip newline character */ + if (*cur_c) + ++cur_c; + + /* Next line */ + pen.y += label->face->size->metrics.height; + } +} + +static void +set_alignment_for_control (ply_label_plugin_control_t *label, + ply_label_alignment_t alignment) +{ + if (label->alignment != alignment) { + label->alignment = alignment; + trigger_redraw(label, true); + } +} + +static void +set_width_for_control (ply_label_plugin_control_t *label, + long width) +{ + if (label->width != width) { + label->width = width; + trigger_redraw(label, true); + } +} + +static void +set_text_for_control (ply_label_plugin_control_t *label, + const char *text) +{ + if (label->text != text) { + free (label->text); + label->text = strdup (text); + trigger_redraw(label, true); + } +} + +static void +set_font_for_control (ply_label_plugin_control_t *label, + const char *fontdesc) +{ + /* Only able to set size */ + + char *size_str_after; + const char *size_str; + unsigned long size; + bool size_in_pixels; + + size = 25; /* Default, if not set. */ + size_in_pixels = false; + + /* Format is "Family 1[,Family 2[,..]] [25[px]]" . + [] means optional. */ + size_str = strrchr(fontdesc, ' '); + + if(size_str) + { + size = strtoul(size_str, &size_str_after, 10); + if(size_str_after == size_str) + size = 25; /* Not a number */ + else if(strcmp(size_str_after, "px") == 0) + size_in_pixels = true; + } + + if(size_in_pixels) + FT_Set_Pixel_Sizes (label->face, 0, size); + else + FT_Set_Char_Size (label->face, size << 6, 0, 100, 0); + + /* Ignore errors, to keep the current size. */ + + trigger_redraw(label, true); +} + +static void +set_color_for_control (ply_label_plugin_control_t *label, + float red, + float green, + float blue, + float alpha) +{ + label->red = red; + label->green = green; + label->blue = blue; + label->alpha = alpha; + + trigger_redraw(label, false); +} + +static bool +show_control (ply_label_plugin_control_t *label, + ply_pixel_display_t *display, + long x, + long y) +{ + ply_rectangle_t dirty_area; + + dirty_area = label->area; + label->display = display; + label->area.x = x; + label->area.y = y; + + label->is_hidden = false; + + size_control (label); + + if (!label->is_hidden && label->display != NULL) + ply_pixel_display_draw_area (label->display, + dirty_area.x, dirty_area.y, + dirty_area.width, dirty_area.height); + + label->is_hidden = false; + + return true; +} + +static void +hide_control (ply_label_plugin_control_t *label) +{ + label->is_hidden = true; + if (label->display != NULL) + ply_pixel_display_draw_area (label->display, + label->area.x, label->area.y, + label->area.width, label->area.height); + + label->display = NULL; +} + +static bool +is_control_hidden (ply_label_plugin_control_t *label) +{ + return label->is_hidden; +} + +ply_label_plugin_interface_t * +ply_label_plugin_get_interface (void) +{ + static ply_label_plugin_interface_t plugin_interface = + { + .create_control = create_control, + .destroy_control = destroy_control, + .show_control = show_control, + .hide_control = hide_control, + .draw_control = draw_control, + .is_control_hidden = is_control_hidden, + .set_text_for_control = set_text_for_control, + .set_alignment_for_control = set_alignment_for_control, + .set_width_for_control = set_width_for_control, + .set_font_for_control = set_font_for_control, + .set_color_for_control = set_color_for_control, + .get_width_of_control = get_width_of_control, + .get_height_of_control = get_height_of_control + }; + + return &plugin_interface; +} + +/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ Index: b/src/plugins/controls/Makefile.am =================================================================== --- a/src/plugins/controls/Makefile.am +++ b/src/plugins/controls/Makefile.am @@ -1,4 +1,8 @@ +SUBDIRS = if ENABLE_PANGO -SUBDIRS = label +SUBDIRS += label +endif +if ENABLE_FREETYPE +SUBDIRS += label-ft endif MAINTAINERCLEANFILES = Makefile.in