Pango! yay. Patch mostly by Mohammed Sameer, fixed some memleaks and ifdeffed by me. May still have some bugs.
This commit is contained in:
parent
d19abac704
commit
e7d1ba6ae3
4 changed files with 161 additions and 0 deletions
|
@ -42,6 +42,7 @@ render_rendertest_LDADD = \
|
|||
render/libobrender.la \
|
||||
$(XFT_LIBS) \
|
||||
$(GLIB_LIBS) \
|
||||
$(PANGO_LIBS) \
|
||||
$(XML_LIBS) \
|
||||
$(X_LIBS)
|
||||
render_rendertest_SOURCES = render/test.c
|
||||
|
@ -51,6 +52,7 @@ render_libobrender_la_CPPFLAGS = \
|
|||
$(XFT_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(XML_CFLAGS) \
|
||||
$(PANGO_CFLAGS) \
|
||||
-DG_LOG_DOMAIN=\"ObRender\" \
|
||||
-DDEFAULT_THEME=\"$(theme)\"
|
||||
render_libobrender_la_LDFLAGS = \
|
||||
|
@ -113,6 +115,7 @@ openbox_openbox_LDADD = \
|
|||
$(VIDMODE_LIBS) \
|
||||
$(XSHAPE_LIBS) \
|
||||
$(GLIB_LIBS) \
|
||||
$(PANGO_LIBS) \
|
||||
$(X_LIBS) \
|
||||
$(LIBSN_LIBS) \
|
||||
$(XML_LIBS) \
|
||||
|
|
12
configure.ac
12
configure.ac
|
@ -73,6 +73,18 @@ fi
|
|||
PKG_CHECK_MODULES([GLIB], [glib-2.0])
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
|
||||
AC_ARG_ENABLE(pango,
|
||||
AC_HELP_STRING([--enable-pango],
|
||||
[enable the pango library for better display of international fonts. (default=no)]),
|
||||
[enable_pango=yes], [enable_pango=no])
|
||||
|
||||
if test "$enable_pango" = yes; then
|
||||
PKG_CHECK_MODULES([PANGO], [pango pangoxft])
|
||||
AC_SUBST(PANGO_CFLAGS)
|
||||
AC_SUBST(PANGO_LIBS)
|
||||
DEFS="$DEFS -DUSE_PANGO"
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(XFT, [xft])
|
||||
AC_SUBST(XFT_CFLAGS)
|
||||
|
|
140
render/font.c
140
render/font.c
|
@ -50,26 +50,44 @@ static void font_startup(void)
|
|||
g_warning(_("Couldn't initialize Xft."));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef USE_PANGO
|
||||
g_type_init();
|
||||
#endif /* USE_PANGO */
|
||||
/* Here we are teaching xft about the shadow, shadowoffset & shadowtint */
|
||||
FcNameRegisterObjectTypes(objs, (sizeof(objs) / sizeof(objs[0])));
|
||||
}
|
||||
|
||||
static void measure_font(RrFont *f)
|
||||
{
|
||||
/* xOff, yOff is the normal spacing to the next glyph. */
|
||||
XGlyphInfo info;
|
||||
|
||||
/* measure an elipses */
|
||||
#ifndef USE_PANGO
|
||||
XftTextExtentsUtf8(RrDisplay(f->inst), f->xftfont,
|
||||
(FcChar8*)ELIPSES, strlen(ELIPSES), &info);
|
||||
f->elipses_length = (signed) info.xOff;
|
||||
#else /* USE_PANGO */
|
||||
XftTextExtentsUtf8(RrDisplay(f->inst), f->xftfont,
|
||||
(FcChar8*)ELIPSES, strlen(ELIPSES), &info);
|
||||
f->elipses_length = (signed) info.xOff;
|
||||
#endif /* USE_PANGO */
|
||||
}
|
||||
|
||||
static RrFont *openfont(const RrInstance *inst, gchar *fontstring)
|
||||
{
|
||||
/* This function is called for each font in the theme file. */
|
||||
/* It returns a pointer to a RrFont struct after filling it. */
|
||||
RrFont *out;
|
||||
FcPattern *pat, *match;
|
||||
XftFont *font;
|
||||
FcResult res;
|
||||
gint tint;
|
||||
#ifdef USE_PANGO
|
||||
gchar *tmp_string = NULL;
|
||||
gint tmp_int;
|
||||
#endif /* USE_PANGO */
|
||||
|
||||
if (!(pat = XftNameParse(fontstring)))
|
||||
return NULL;
|
||||
|
@ -81,6 +99,33 @@ static RrFont *openfont(const RrInstance *inst, gchar *fontstring)
|
|||
|
||||
out = g_new(RrFont, 1);
|
||||
out->inst = inst;
|
||||
#ifdef USE_PANGO
|
||||
/* printf("\n\n%s\n\n",fontstring);
|
||||
FcPatternPrint(match); */
|
||||
|
||||
out->pango_font_description = pango_font_description_new();
|
||||
|
||||
if (FcPatternGetString(match, "family", 0, &tmp_string) != FcResultTypeMismatch) {
|
||||
pango_font_description_set_family(out->pango_font_description, tmp_string);
|
||||
tmp_string = NULL;
|
||||
}
|
||||
if (FcPatternGetString(match, "style", 0, &tmp_string) != FcResultTypeMismatch) {
|
||||
/* Bold ? */
|
||||
if (!strcasecmp("bold", tmp_string)) {
|
||||
pango_font_description_set_weight(out->pango_font_description, PANGO_WEIGHT_BOLD);
|
||||
}
|
||||
/* Italic ? */
|
||||
else if (!strcasecmp("italic", tmp_string)) {
|
||||
pango_font_description_set_style(out->pango_font_description, PANGO_STYLE_ITALIC);
|
||||
}
|
||||
tmp_string = NULL;
|
||||
}
|
||||
|
||||
if (FcPatternGetInteger(match, "pixelsize", 0, &tmp_int) != FcResultTypeMismatch) {
|
||||
/* TODO: is PANGO_SCALE correct ?? */
|
||||
pango_font_description_set_size(out->pango_font_description, tmp_int*PANGO_SCALE);
|
||||
}
|
||||
#endif /* USE_PANGO */
|
||||
|
||||
if (FcPatternGetBool(match, OB_SHADOW, 0, &out->shadow) != FcResultMatch)
|
||||
out->shadow = FALSE;
|
||||
|
@ -103,6 +148,9 @@ static RrFont *openfont(const RrInstance *inst, gchar *fontstring)
|
|||
} else
|
||||
out->xftfont = font;
|
||||
|
||||
#ifdef USE_PANGO
|
||||
/* FcPatternDestroy(match); */
|
||||
#endif /* USE_PANGO */
|
||||
measure_font(out);
|
||||
|
||||
return out;
|
||||
|
@ -140,6 +188,22 @@ void RrFontClose(RrFont *f)
|
|||
static void font_measure_full(const RrFont *f, const gchar *str,
|
||||
gint *x, gint *y)
|
||||
{
|
||||
#ifdef USE_PANGO
|
||||
PangoContext *context;
|
||||
PangoLayout *pl;
|
||||
PangoRectangle rect;
|
||||
context = pango_xft_get_context (RrDisplay(f->inst), RrScreen(f->inst));
|
||||
pl = pango_layout_new (context);
|
||||
pango_layout_set_text(pl, str, -1);
|
||||
pango_layout_set_font_description(pl, f->pango_font_description);
|
||||
pango_layout_set_single_paragraph_mode(pl, TRUE);
|
||||
pango_layout_get_pixel_extents(pl, NULL, &rect);
|
||||
*x = rect.width + (f->shadow ? ABS(f->offset) : 0);
|
||||
*y = rect.height + (f->shadow ? ABS(f->offset) : 0);
|
||||
g_object_unref(pl);
|
||||
g_object_unref(context);
|
||||
|
||||
#else
|
||||
XGlyphInfo info;
|
||||
|
||||
XftTextExtentsUtf8(RrDisplay(f->inst), f->xftfont,
|
||||
|
@ -147,6 +211,7 @@ static void font_measure_full(const RrFont *f, const gchar *str,
|
|||
|
||||
*x = (signed) info.xOff + (f->shadow ? ABS(f->offset) : 0);
|
||||
*y = info.height + (f->shadow ? ABS(f->offset) : 0);
|
||||
#endif /* USE_PANGO */
|
||||
}
|
||||
|
||||
gint RrFontMeasureString(const RrFont *f, const gchar *str)
|
||||
|
@ -158,8 +223,27 @@ gint RrFontMeasureString(const RrFont *f, const gchar *str)
|
|||
|
||||
gint RrFontHeight(const RrFont *f)
|
||||
{
|
||||
#ifndef USE_PANGO
|
||||
return f->xftfont->ascent + f->xftfont->descent +
|
||||
(f->shadow ? f->offset : 0);
|
||||
#else /* USE_PANGO */
|
||||
/*
|
||||
PangoContext *context = pango_context_new ();
|
||||
|
||||
PangoFontMetrics *metrics = pango_context_get_metrics(context, f->pango_font, NULL);
|
||||
|
||||
gint result = pango_font_metrics_get_ascent (metrics) +
|
||||
pango_font_metrics_get_descent(metrics) +
|
||||
(f->shadow ? f->offset : 0);
|
||||
|
||||
pango_font_metrics_unref(metrics);
|
||||
g_object_unref(context);
|
||||
return result;
|
||||
*/
|
||||
return f->xftfont->ascent + f->xftfont->descent +
|
||||
(f->shadow ? f->offset : 0*);
|
||||
|
||||
#endif /* USE_PANGO */
|
||||
}
|
||||
|
||||
gint RrFontMaxCharWidth(const RrFont *f)
|
||||
|
@ -176,6 +260,16 @@ void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area)
|
|||
size_t l;
|
||||
gboolean shortened = FALSE;
|
||||
|
||||
#ifdef USE_PANGO
|
||||
PangoLayout *pl;
|
||||
PangoLayoutLine *pll;
|
||||
PangoContext *context;
|
||||
GSList *p;
|
||||
|
||||
context = pango_xft_get_context (RrDisplay(t->font->inst), RrScreen(t->font->inst));
|
||||
pl = pango_layout_new (context);
|
||||
#endif /* USE_PANGO */
|
||||
|
||||
/* center vertically */
|
||||
y = area->y +
|
||||
(area->height - RrFontHeight(t->font)) / 2;
|
||||
|
@ -216,7 +310,17 @@ void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area)
|
|||
|
||||
l = strlen(text->str); /* number of bytes */
|
||||
|
||||
#ifdef USE_PANGO
|
||||
pango_layout_set_text(pl, text->str, l);
|
||||
pango_layout_set_font_description(pl, t->font->pango_font_description);
|
||||
pango_layout_set_single_paragraph_mode(pl, TRUE);
|
||||
pll = pango_layout_get_line(pl, 0);
|
||||
#endif /* USE_PANGO */
|
||||
|
||||
if (t->font->shadow) {
|
||||
#ifdef USE_PANGO
|
||||
int x2 = x;
|
||||
#endif /* USE_PANGO */
|
||||
if (t->font->tint >= 0) {
|
||||
c.color.red = 0;
|
||||
c.color.green = 0;
|
||||
|
@ -231,20 +335,56 @@ void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area)
|
|||
c.color.alpha = 0xffff * -t->font->tint / 100;
|
||||
c.pixel = WhitePixel(RrDisplay(t->font->inst),
|
||||
RrScreen(t->font->inst));
|
||||
#ifndef USE_PANGO
|
||||
}
|
||||
XftDrawStringUtf8(d, &c, t->font->xftfont, x + t->font->offset,
|
||||
t->font->xftfont->ascent + y + t->font->offset,
|
||||
(FcChar8*)text->str, l);
|
||||
}
|
||||
#else /* USE_PANGO */
|
||||
}
|
||||
|
||||
for (p = pll->runs; p != NULL; p = p->next)
|
||||
{
|
||||
PangoLayoutRun *run = p->data;
|
||||
PangoFont *font = run->item->analysis.font;
|
||||
PangoGlyphString *glyphs = run->glyphs;
|
||||
PangoRectangle rect;
|
||||
|
||||
pango_glyph_string_extents (glyphs, font, NULL, &rect);
|
||||
pango_xft_render (d, &c, font, glyphs, x2 + t->font->offset,
|
||||
t->font->xftfont->ascent + y + t->font->offset);
|
||||
x2 += rect.width / PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
#endif /* USE_PANGO */
|
||||
c.color.red = t->color->r | t->color->r << 8;
|
||||
c.color.green = t->color->g | t->color->g << 8;
|
||||
c.color.blue = t->color->b | t->color->b << 8;
|
||||
c.color.alpha = 0xff | 0xff << 8; /* fully opaque text */
|
||||
c.pixel = t->color->pixel;
|
||||
|
||||
#ifndef USE_PANGO
|
||||
XftDrawStringUtf8(d, &c, t->font->xftfont, x,
|
||||
t->font->xftfont->ascent + y,
|
||||
(FcChar8*)text->str, l);
|
||||
#else /* USE_PANGO */
|
||||
for (p = pll->runs; p != NULL; p = p->next)
|
||||
{
|
||||
PangoLayoutRun *run = p->data;
|
||||
PangoFont *font = run->item->analysis.font;
|
||||
PangoGlyphString *glyphs = run->glyphs;
|
||||
PangoRectangle rect;
|
||||
|
||||
pango_glyph_string_extents (glyphs, font, NULL, &rect);
|
||||
pango_xft_render (d, &c, font, glyphs, x, t->font->xftfont->ascent + y);
|
||||
x += rect.width / PANGO_SCALE;
|
||||
}
|
||||
|
||||
// pango_layout_line_unref(pll);
|
||||
g_object_unref(pl);
|
||||
g_object_unref(context);
|
||||
#endif /* USE_PANGO */
|
||||
|
||||
g_string_free(text, TRUE);
|
||||
return;
|
||||
|
|
|
@ -21,9 +21,15 @@
|
|||
#define __font_h
|
||||
#include "render.h"
|
||||
#include "geom.h"
|
||||
#ifdef USE_PANGO
|
||||
#include <pango/pango.h>
|
||||
#endif /* USE_PANGO */
|
||||
|
||||
struct _RrFont {
|
||||
const RrInstance *inst;
|
||||
#ifdef USE_PANGO
|
||||
PangoFontDescription *pango_font_description;
|
||||
#endif /* USE_PANGO */
|
||||
XftFont *xftfont;
|
||||
gint elipses_length;
|
||||
gint shadow;
|
||||
|
|
Loading…
Reference in a new issue