1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

WINGs: Add optional Pango text layout support

Currently WINGs renders text using Xft directly which does not support
any advanced text layout that is needed for scripts like Arabic or Indic
scripts (or even things like automatic ligature support for Latin
script).

With Pango we also get text fallback for free, so no more square boxes
for characters not supported in the current font (unless no font on the
system supports the specified character, of course).

This patch introduces support for using Pango to render the text (though
its Xft backed), to avoid forcing the additional dependency to everyone
it is made off by default.

Signed-off-by: Carlos R. Mafra <crmafra@gmail.com>
This commit is contained in:
Khaled Hosny
2014-10-11 16:45:18 +02:00
committed by Carlos R. Mafra
parent 1485233292
commit e3dcadde30
5 changed files with 98 additions and 3 deletions

View File

@@ -13,7 +13,7 @@ lib_LTLIBRARIES = libWUtil.la libWINGs.la
LDADD= libWUtil.la libWINGs.la $(top_builddir)/wrlib/libwraster.la @INTLIBS@ LDADD= libWUtil.la libWINGs.la $(top_builddir)/wrlib/libwraster.la @INTLIBS@
libWINGs_la_LIBADD = libWUtil.la $(top_builddir)/wrlib/libwraster.la @XLIBS@ @XFTLIBS@ @FCLIBS@ @LIBM@ libWINGs_la_LIBADD = libWUtil.la $(top_builddir)/wrlib/libwraster.la @XLIBS@ @XFTLIBS@ @FCLIBS@ @LIBM@ @PANGOLIBS@
libWUtil_la_LIBADD = @LIBBSD@ libWUtil_la_LIBADD = @LIBBSD@
EXTRA_DIST = BUGS make-rgb Examples Extras Tests get-wings-flags.in get-wutil-flags.in EXTRA_DIST = BUGS make-rgb Examples Extras Tests get-wings-flags.in get-wutil-flags.in
@@ -106,7 +106,7 @@ WINGs.pc: Makefile
@echo 'Version: $(VERSION)' >> $@ @echo 'Version: $(VERSION)' >> $@
@echo 'Requires: wrlib WUtil' >> $@ @echo 'Requires: wrlib WUtil' >> $@
@echo 'Libs: $(lib_search_path) -lWINGs' >> $@ @echo 'Libs: $(lib_search_path) -lWINGs' >> $@
@echo 'Libs.private: $(XFTLIBS) $(XLIBS) -lm $(INTLIBS)' >> $@ @echo 'Libs.private: $(XFTLIBS) $(PANGOLIBS) $(XLIBS) -lm $(INTLIBS)' >> $@
@echo 'Cflags: $(inc_search_path)' >> $@ @echo 'Cflags: $(inc_search_path)' >> $@
get-wings-flags: get-wings-flags.in Makefile get-wings-flags: get-wings-flags.in Makefile
@@ -115,6 +115,7 @@ get-wings-flags: get-wings-flags.in Makefile
-e 's#$${lib_search_path}#$(lib_search_path)#;' \ -e 's#$${lib_search_path}#$(lib_search_path)#;' \
-e 's#$${GFXLIBS}#$(GFXLIBS)#;' \ -e 's#$${GFXLIBS}#$(GFXLIBS)#;' \
-e 's#$${XFTLIBS}#$(XFTLIBS)#;' \ -e 's#$${XFTLIBS}#$(XFTLIBS)#;' \
-e 's#$${PANGOLIBS}#$(PANGOLIBS)#;' \
-e 's#$${INTLIBS}#$(INTLIBS)#;' \ -e 's#$${INTLIBS}#$(INTLIBS)#;' \
-e 's#$${XLIBS}#$(XLIBS)#;' < $(abs_srcdir)/get-wings-flags.in > $@ -e 's#$${XLIBS}#$(XLIBS)#;' < $(abs_srcdir)/get-wings-flags.in > $@
@chmod 755 $@ @chmod 755 $@

View File

@@ -5,6 +5,9 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#ifdef USE_PANGO
#include <pango/pango.h>
#endif
#include <WINGs/WINGs.h> #include <WINGs/WINGs.h>
@@ -445,6 +448,10 @@ typedef struct W_Font {
short y; short y;
short refCount; short refCount;
char *name; char *name;
#ifdef USE_PANGO
PangoLayout *layout;
#endif
} W_Font; } W_Font;
#define W_FONTID(f) (f)->font->fid #define W_FONTID(f) (f)->font->fid

View File

@@ -2,7 +2,7 @@
WCFLAGS="${inc_search_path}" WCFLAGS="${inc_search_path}"
WLFLAGS="${lib_search_path}" WLFLAGS="${lib_search_path}"
WLIBS="-lWINGs -lWUtil -lwraster ${GFXLIBS} ${XFTLIBS} ${XLIBS} -lm ${INTLIBS}" WLIBS="-lWINGs -lWUtil -lwraster ${GFXLIBS} ${XFTLIBS} ${XLIBS} -lm ${INTLIBS} ${PANGOLIBS}"
usage="Usage: get-wings-flags [--cflags] [--ldflags] [--libs]" usage="Usage: get-wings-flags [--cflags] [--ldflags] [--libs]"

View File

@@ -12,6 +12,12 @@
#include <X11/Xft/Xft.h> #include <X11/Xft/Xft.h>
#include <fontconfig/fontconfig.h> #include <fontconfig/fontconfig.h>
#ifdef USE_PANGO
#include <pango/pango.h>
#include <pango/pangofc-fontmap.h>
#include <pango/pangoxft.h>
#endif
#define DEFAULT_FONT "sans serif:pixelsize=12" #define DEFAULT_FONT "sans serif:pixelsize=12"
#define DEFAULT_SIZE WINGsConfiguration.defaultFontSize #define DEFAULT_SIZE WINGsConfiguration.defaultFontSize
@@ -120,6 +126,14 @@ WMFont *WMCreateFont(WMScreen * scrPtr, const char *fontName)
Display *display = scrPtr->display; Display *display = scrPtr->display;
WMFont *font; WMFont *font;
char *fname; char *fname;
#ifdef USE_PANGO
PangoFontMap *fontmap;
PangoContext *context;
PangoLayout *layout;
FcPattern *pattern;
PangoFontDescription *description;
double size;
#endif
if (fontName[0] == '-') { if (fontName[0] == '-') {
fname = xlfdToFcName(fontName); fname = xlfdToFcName(fontName);
@@ -156,6 +170,25 @@ WMFont *WMCreateFont(WMScreen * scrPtr, const char *fontName)
font->name = fname; font->name = fname;
#ifdef USE_PANGO
fontmap = pango_xft_get_font_map(scrPtr->display, scrPtr->screen);
context = pango_font_map_create_context(fontmap);
layout = pango_layout_new(context);
pattern = FcNameParse((FcChar8 *) font->name);
description = pango_fc_font_description_from_pattern(pattern, FALSE);
/* Pango examines FC_SIZE but not FC_PIXEL_SIZE of the patten, but
* font-name has only "pixelsize", so set the size manually here.
*/
if (FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
pango_font_description_set_absolute_size(description, size * PANGO_SCALE);
pango_layout_set_font_description(layout, description);
font->layout = layout;
#endif
assert(WMHashInsert(scrPtr->fontCache, font->name, font) == NULL); assert(WMHashInsert(scrPtr->fontCache, font->name, font) == NULL);
return font; return font;
@@ -252,18 +285,34 @@ WMFont *WMBoldSystemFontOfSize(WMScreen * scrPtr, int size)
int WMWidthOfString(WMFont * font, const char *text, int length) int WMWidthOfString(WMFont * font, const char *text, int length)
{ {
#ifdef USE_PANGO
const char *previous_text;
int width;
#else
XGlyphInfo extents; XGlyphInfo extents;
#endif
wassertrv(font != NULL && text != NULL, 0); wassertrv(font != NULL && text != NULL, 0);
#ifdef USE_PANGO
previous_text = pango_layout_get_text(font->layout);
if ((previous_text == NULL) || (strcmp(text, previous_text) != 0))
pango_layout_set_text(font->layout, text, length);
pango_layout_get_pixel_size(font->layout, &width, NULL);
return width;
#else
XftTextExtentsUtf8(font->screen->display, font->font, (XftChar8 *) text, length, &extents); XftTextExtentsUtf8(font->screen->display, font->font, (XftChar8 *) text, length, &extents);
return extents.xOff; /* don't ask :P */ return extents.xOff; /* don't ask :P */
#endif
} }
void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, int x, int y, const char *text, int length) void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, int x, int y, const char *text, int length)
{ {
XftColor xftcolor; XftColor xftcolor;
#ifdef USE_PANGO
const char *previous_text;
#endif
wassertr(font != NULL); wassertr(font != NULL);
@@ -275,7 +324,14 @@ void WMDrawString(WMScreen * scr, Drawable d, WMColor * color, WMFont * font, in
XftDrawChange(scr->xftdraw, d); XftDrawChange(scr->xftdraw, d);
#ifdef USE_PANGO
previous_text = pango_layout_get_text(font->layout);
if ((previous_text == NULL) || (strcmp(text, previous_text) != 0))
pango_layout_set_text(font->layout, text, length);
pango_xft_render_layout(scr->xftdraw, &xftcolor, font->layout, x * PANGO_SCALE, y * PANGO_SCALE);
#else
XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length); XftDrawStringUtf8(scr->xftdraw, &xftcolor, font->font, x, y + font->y, (XftChar8 *) text, length);
#endif
} }
void void
@@ -284,6 +340,9 @@ WMDrawImageString(WMScreen * scr, Drawable d, WMColor * color, WMColor * backgro
{ {
XftColor textColor; XftColor textColor;
XftColor bgColor; XftColor bgColor;
#ifdef USE_PANGO
const char *previous_text;
#endif
wassertr(font != NULL); wassertr(font != NULL);
@@ -303,7 +362,14 @@ WMDrawImageString(WMScreen * scr, Drawable d, WMColor * color, WMColor * backgro
XftDrawRect(scr->xftdraw, &bgColor, x, y, WMWidthOfString(font, text, length), font->height); XftDrawRect(scr->xftdraw, &bgColor, x, y, WMWidthOfString(font, text, length), font->height);
#ifdef USE_PANGO
previous_text = pango_layout_get_text(font->layout);
if ((previous_text == NULL) || (strcmp(text, previous_text) != 0))
pango_layout_set_text(font->layout, text, length);
pango_xft_render_layout(scr->xftdraw, &textColor, font->layout, x * PANGO_SCALE, y * PANGO_SCALE);
#else
XftDrawStringUtf8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length); XftDrawStringUtf8(scr->xftdraw, &textColor, font->font, x, y + font->y, (XftChar8 *) text, length);
#endif
} }
WMFont *WMCopyFontWithStyle(WMScreen * scrPtr, WMFont * font, WMFontStyle style) WMFont *WMCopyFontWithStyle(WMScreen * scrPtr, WMFont * font, WMFontStyle style)

View File

@@ -625,6 +625,26 @@ fi
AC_SUBST(XFTFLAGS) AC_SUBST(XFTFLAGS)
AC_SUBST(XFTLIBS) AC_SUBST(XFTLIBS)
dnl PANGO support
dnl =============
pango=no
AC_ARG_ENABLE(pango, AS_HELP_STRING([--enable-pango], [enable Pango text layout support]),
pango=$enableval, pango=no)
PANGOFLAGS=
PANGOLIBS=
if test "$pango" = yes; then
PANGOLIBS=`$PKGCONFIG pangoxft --libs`
PANGOFLAGS=`$PKGCONFIG pangoxft --cflags`
if test "x$PANGOLIBS" = "x" ; then
AC_MSG_RESULT([not found])
else
AC_DEFINE(USE_PANGO, 1, [Define if Pango is to be used])
AC_MSG_RESULT([found])
fi
fi
inc_search_path="$inc_search_path $PANGOFLAGS"
AC_SUBST(PANGOLIBS)
dnl ============================================== dnl ==============================================
dnl Graphic Format Libraries dnl Graphic Format Libraries
@@ -869,6 +889,7 @@ echo "Supported X extensions: :$supported_xext"
echo "Supported graphic format libraries :$supported_gfx" echo "Supported graphic format libraries :$supported_gfx"
echo "Unsupported features :$unsupported" echo "Unsupported features :$unsupported"
echo "Antialiased text support in WINGs : $xft" echo "Antialiased text support in WINGs : $xft"
echo "Pango text layout support in WINGs : $pango"
echo "Translated message files to install : $mof" echo "Translated message files to install : $mof"
dnl echo "Supported languages beside English : $languages" dnl echo "Supported languages beside English : $languages"
if test "x$MOFILES" != "x"; then if test "x$MOFILES" != "x"; then