summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/font.c116
-rw-r--r--render/render.c31
-rw-r--r--render/render.h10
-rw-r--r--render/theme.c4
-rw-r--r--render/version.h.in15
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