diff options
Diffstat (limited to 'render')
| -rw-r--r-- | render/font.c | 116 | ||||
| -rw-r--r-- | render/render.c | 31 | ||||
| -rw-r--r-- | render/render.h | 10 | ||||
| -rw-r--r-- | render/theme.c | 4 | ||||
| -rw-r--r-- | render/version.h.in | 15 |
5 files changed, 136 insertions, 40 deletions
diff --git a/render/font.c b/render/font.c index 356b9c6e..5ccfb8fd 100644 --- a/render/font.c +++ b/render/font.c @@ -108,7 +108,7 @@ RrFont *RrFontOpen(const RrInstance *inst, const gchar *name, gint size, /* setup the layout */ pango_layout_set_font_description(out->layout, out->font_desc); - pango_layout_set_single_paragraph_mode(out->layout, TRUE); + pango_layout_set_wrap(out->layout, PANGO_WRAP_WORD_CHAR); /* get the ascent and descent */ measure_font(inst, out); @@ -139,12 +139,23 @@ void RrFontClose(RrFont *f) } static void font_measure_full(const RrFont *f, const gchar *str, - gint *x, gint *y, gint shadow_x, gint shadow_y) + gint *x, gint *y, gint shadow_x, gint shadow_y, + gboolean flow, gint maxwidth) { PangoRectangle rect; pango_layout_set_text(f->layout, str, -1); - pango_layout_set_width(f->layout, -1); + if (flow) { + pango_layout_set_single_paragraph_mode(f->layout, FALSE); + pango_layout_set_width(f->layout, maxwidth * PANGO_SCALE); + pango_layout_set_ellipsize(f->layout, PANGO_ELLIPSIZE_NONE); + } + else { + /* single line mode */ + pango_layout_set_single_paragraph_mode(f->layout, TRUE); + pango_layout_set_width(f->layout, -1); + pango_layout_set_ellipsize(f->layout, PANGO_ELLIPSIZE_MIDDLE); + } /* pango_layout_get_pixel_extents lies! this is the right way to get the size of the text's area */ @@ -163,11 +174,16 @@ static void font_measure_full(const RrFont *f, const gchar *str, } RrSize *RrFontMeasureString(const RrFont *f, const gchar *str, - gint shadow_x, gint shadow_y) + gint shadow_x, gint shadow_y, + gboolean flow, gint maxwidth) { RrSize *size; + + g_assert(!flow || maxwidth > 0); + size = g_new(RrSize, 1); - font_measure_full(f, str, &size->width, &size->height, shadow_x, shadow_y); + font_measure_full(f, str, &size->width, &size->height, shadow_x, shadow_y, + flow, maxwidth); return size; } @@ -208,36 +224,47 @@ void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area) PangoAttrList *attrlist; PangoEllipsizeMode ell; - /* center the text vertically - We do this centering based on the 'baseline' since different fonts have - different top edges. It looks bad when the whole string is moved when 1 - character from a non-default language is included in the string */ - y = area->y + - font_calculate_baseline(t->font, area->height); + g_assert(!t->flow || t->maxwidth > 0); + + y = area->y; + if (!t->flow) + /* center the text vertically + We do this centering based on the 'baseline' since different fonts + have different top edges. It looks bad when the whole string is + moved when 1 character from a non-default language is included in + the string */ + y += font_calculate_baseline(t->font, area->height); /* the +2 and -4 leave a small blank edge on the sides */ x = area->x + 2; - w = area->width - 4; + w = area->width; + if (t->flow) w = MAX(w, t->maxwidth); + w -= 4; h = area->height; - switch (t->ellipsize) { - case RR_ELLIPSIZE_NONE: + if (t->flow) ell = PANGO_ELLIPSIZE_NONE; - break; - case RR_ELLIPSIZE_START: - ell = PANGO_ELLIPSIZE_START; - break; - case RR_ELLIPSIZE_MIDDLE: - ell = PANGO_ELLIPSIZE_MIDDLE; - break; - case RR_ELLIPSIZE_END: - ell = PANGO_ELLIPSIZE_END; - break; + else { + switch (t->ellipsize) { + case RR_ELLIPSIZE_NONE: + ell = PANGO_ELLIPSIZE_NONE; + break; + case RR_ELLIPSIZE_START: + ell = PANGO_ELLIPSIZE_START; + break; + case RR_ELLIPSIZE_MIDDLE: + ell = PANGO_ELLIPSIZE_MIDDLE; + break; + case RR_ELLIPSIZE_END: + ell = PANGO_ELLIPSIZE_END; + break; + } } pango_layout_set_text(t->font->layout, t->string, -1); pango_layout_set_width(t->font->layout, w * PANGO_SCALE); pango_layout_set_ellipsize(t->font->layout, ell); + pango_layout_set_single_paragraph_mode(t->font->layout, !t->flow); /* * * end of setting up the layout * * */ @@ -265,10 +292,23 @@ void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area) c.pixel = t->shadow_color->pixel; /* see below... */ - pango_xft_render_layout_line - (d, &c, pango_layout_get_line(t->font->layout, 0), - (x + t->shadow_offset_x) * PANGO_SCALE, - (y + t->shadow_offset_y) * PANGO_SCALE); + if (!t->flow) { + pango_xft_render_layout_line + (d, &c, +#if PANGO_VERSION_MAJOR > 1 || \ + (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 16) + pango_layout_get_line_readonly(t->font->layout, 0), +#else + pango_layout_get_line(t->font->layout, 0), +#endif + (x + t->shadow_offset_x) * PANGO_SCALE, + (y + t->shadow_offset_y) * PANGO_SCALE); + } + else { + pango_xft_render_layout(d, &c, t->font->layout, + (x + t->shadow_offset_x) * PANGO_SCALE, + (y + t->shadow_offset_y) * PANGO_SCALE); + } } c.color.red = t->color->r | t->color->r << 8; @@ -295,9 +335,23 @@ void RrFontDraw(XftDraw *d, RrTextureText *t, RrRect *area) /* layout_line() uses y to specify the baseline The line doesn't need to be freed, it's a part of the layout */ - pango_xft_render_layout_line - (d, &c, pango_layout_get_line(t->font->layout, 0), - x * PANGO_SCALE, y * PANGO_SCALE); + if (!t->flow) { + pango_xft_render_layout_line + (d, &c, +#if PANGO_VERSION_MAJOR > 1 || \ + (PANGO_VERSION_MAJOR == 1 && PANGO_VERSION_MINOR >= 16) + pango_layout_get_line_readonly(t->font->layout, 0), +#else + pango_layout_get_line(t->font->layout, 0), +#endif + x * PANGO_SCALE, + y * PANGO_SCALE); + } + else { + pango_xft_render_layout(d, &c, t->font->layout, + x * PANGO_SCALE, + y * PANGO_SCALE); + } if (t->shortcut) { t->font->shortcut_underline->start_index = 0; diff --git a/render/render.c b/render/render.c index 7791429a..49485c8a 100644 --- a/render/render.c +++ b/render/render.c @@ -188,6 +188,12 @@ RrAppearance *RrAppearanceNew(const RrInstance *inst, gint numtex) return out; } +void RrAppearanceRemoveTextures(RrAppearance *a) +{ + g_free(a->texture); + a->textures = 0; +} + void RrAppearanceAddTextures(RrAppearance *a, gint numtex) { g_assert(a->textures == 0); @@ -388,7 +394,9 @@ gint RrMinWidth(RrAppearance *a) m = RrFontMeasureString(a->texture[i].data.text.font, a->texture[i].data.text.string, a->texture[i].data.text.shadow_offset_x, - a->texture[i].data.text.shadow_offset_y); + a->texture[i].data.text.shadow_offset_y, + a->texture[i].data.text.flow, + a->texture[i].data.text.maxwidth); w = MAX(w, m->width); g_free(m); break; @@ -414,6 +422,7 @@ gint RrMinHeight(RrAppearance *a) { gint i; gint l, t, r, b; + RrSize *m; gint h = 0; for (i = 0; i < a->textures; ++i) { @@ -424,8 +433,24 @@ gint RrMinHeight(RrAppearance *a) h = MAX(h, a->texture[i].data.mask.mask->height); break; case RR_TEXTURE_TEXT: - h += MAX(h, RrFontHeight(a->texture[i].data.text.font, - a->texture[i].data.text.shadow_offset_y)); + if (a->texture[i].data.text.flow) { + g_assert(a->texture[i].data.text.string != NULL); + + m = RrFontMeasureString + (a->texture[i].data.text.font, + a->texture[i].data.text.string, + a->texture[i].data.text.shadow_offset_x, + a->texture[i].data.text.shadow_offset_y, + a->texture[i].data.text.flow, + a->texture[i].data.text.maxwidth); + h += MAX(h, m->height); + g_free(m); + } + else + h += MAX(h, + RrFontHeight + (a->texture[i].data.text.font, + a->texture[i].data.text.shadow_offset_y)); break; case RR_TEXTURE_RGBA: h += MAX(h, a->texture[i].data.rgba.height); diff --git a/render/render.h b/render/render.h index 7b81e2ff..260ebeb0 100644 --- a/render/render.h +++ b/render/render.h @@ -22,7 +22,7 @@ #define __render_h #include "geom.h" -#include "version.h" +#include "render/version.h" #include <X11/Xlib.h> /* some platforms dont include this as needed for Xft */ #include <pango/pangoxft.h> @@ -141,6 +141,8 @@ struct _RrTextureText { gboolean shortcut; /*!< Underline a character */ guint shortcut_pos; /*!< Position in bytes of the character to underline */ RrEllipsizeMode ellipsize; + gboolean flow; /* allow multiple lines. must set maxwidth below */ + gint maxwidth; }; struct _RrPixmapMask { @@ -249,6 +251,7 @@ GC RrColorGC (RrColor *c); RrAppearance *RrAppearanceNew (const RrInstance *inst, gint numtex); RrAppearance *RrAppearanceCopy (RrAppearance *a); void RrAppearanceFree (RrAppearance *a); +void RrAppearanceRemoveTextures(RrAppearance *a); void RrAppearanceAddTextures(RrAppearance *a, gint numtex); RrFont *RrFontOpen (const RrInstance *inst, const gchar *name, @@ -256,7 +259,8 @@ RrFont *RrFontOpen (const RrInstance *inst, const gchar *name, RrFont *RrFontOpenDefault (const RrInstance *inst); void RrFontClose (RrFont *f); RrSize *RrFontMeasureString (const RrFont *f, const gchar *str, - gint shadow_offset_x, gint shadow_offset_y); + gint shadow_offset_x, gint shadow_offset_y, + gboolean flow, gint maxwidth); gint RrFontHeight (const RrFont *f, gint shadow_offset_y); gint RrFontMaxCharWidth (const RrFont *f); @@ -267,6 +271,8 @@ Pixmap RrPaintPixmap (RrAppearance *a, gint w, gint h); void RrPaint (RrAppearance *a, Window win, gint w, gint h); void RrMinSize (RrAppearance *a, gint *w, gint *h); gint RrMinWidth (RrAppearance *a); +/* For text textures, if flow is TRUE, then the string must be set before + calling this, otherwise it doesn't need to be */ gint RrMinHeight (RrAppearance *a); void RrMargins (RrAppearance *a, gint *l, gint *t, gint *r, gint *b); diff --git a/render/theme.c b/render/theme.c index 6d87cafb..a6931be6 100644 --- a/render/theme.c +++ b/render/theme.c @@ -907,13 +907,9 @@ RrTheme* RrThemeNew(const RrInstance *inst, const gchar *name, j = (i > 0 ? 0 : 255); i = ABS(i*255/100); - theme->title_focused_shadow_color = RrColorNew(inst, j, j, j); - theme->title_focused_shadow_alpha = i; theme->osd_shadow_color = RrColorNew(inst, j, j, j); theme->osd_shadow_alpha = i; } else { - theme->title_focused_shadow_color = RrColorNew(inst, 0, 0, 0); - theme->title_focused_shadow_alpha = 50; theme->osd_shadow_color = RrColorNew(inst, 0, 0, 0); theme->osd_shadow_alpha = 50; } diff --git a/render/version.h.in b/render/version.h.in new file mode 100644 index 00000000..0ff30b57 --- /dev/null +++ b/render/version.h.in @@ -0,0 +1,15 @@ +#ifndef rr__version_h +#define rr__version_h + +#define RR_MAJOR_VERSION @RR_MAJOR_VERSION@ +#define RR_MINOR_VERSION @RR_MINOR_VERSION@ +#define RR_MICRO_VERSION @RR_MICRO_VERSION@ +#define RR_VERSION RR_MAJOR_VERSION.RR_MINOR_VERSION.RR_MICRO_VERSION + +#define RR_CHECK_VERSION(major,minor,micro) \ + (RR_MAJOR_VERSION > (major) || \ + (RR_MAJOR_VERSION == (major) && RR_MINOR_VERSION > (minor)) || \ + (RR_MAJOR_VERSION == (major) && RR_MINOR_VERSION == (minor) && \ + RR_MICRO_VERSION >= (micro))) + +#endif |
