summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2009-03-16 16:03:36 -0400
committerBehdad Esfahbod <behdad@behdad.org>2009-03-16 16:03:36 -0400
commita6af36b9c06b81ab8095afff85f68f37c27a4b3b (patch)
tree30b65815bc952511b541b66c7ee7c015a1ffe935
parent2599e265eba6fd27b3f7684c484f3160f9a67595 (diff)
downloadpango-a6af36b9c06b81ab8095afff85f68f37c27a4b3b.tar.gz
Bug 502805 – pango-view option for foreground/background color
-rw-r--r--pango-view/viewer-cairo.c58
-rw-r--r--pango-view/viewer-cairo.h3
-rw-r--r--pango-view/viewer-pangocairo.c13
-rw-r--r--pango-view/viewer-pangoxft.c26
-rw-r--r--pango-view/viewer-render.c97
-rw-r--r--pango-view/viewer-render.h7
-rw-r--r--pango-view/viewer-x.c8
7 files changed, 182 insertions, 30 deletions
diff --git a/pango-view/viewer-cairo.c b/pango-view/viewer-cairo.c
index 5ecfb964..579076e1 100644
--- a/pango-view/viewer-cairo.c
+++ b/pango-view/viewer-cairo.c
@@ -33,33 +33,57 @@
#include "viewer-x.h"
#include <cairo-xlib.h>
+static void
+cairo_view_iface_paint_background_over (gpointer instance G_GNUC_UNUSED,
+ cairo_t *cr)
+{
+ if (opt_bg_set)
+ {
+ cairo_set_source_rgba (cr,
+ opt_bg_color.red / 65535.,
+ opt_bg_color.green / 65535.,
+ opt_bg_color.blue / 65535.,
+ opt_bg_alpha / 65535.);
+ cairo_paint (cr);
+ }
+}
+
+static void
+cairo_view_iface_paint_background_source (gpointer instance G_GNUC_UNUSED,
+ cairo_t *cr)
+{
+ if (opt_bg_set)
+ {
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr,
+ opt_bg_color.red / 65535.,
+ opt_bg_color.green / 65535.,
+ opt_bg_color.blue / 65535.,
+ opt_bg_alpha / 65535.);
+ cairo_paint (cr);
+ }
+}
+
+
+
static cairo_surface_t *
cairo_x_view_iface_create_surface (gpointer instance,
gpointer surface,
int width,
int height)
{
- cairo_t *cr;
- cairo_surface_t *cairo_surface;
-
XViewer *x = (XViewer *)instance;
Drawable drawable = (Drawable) surface;
- cairo_surface = cairo_xlib_surface_create (x->display, drawable,
- DefaultVisual (x->display, x->screen),
- width, height);
-
- cr = cairo_create (cairo_surface);
- cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
- cairo_paint (cr);
- cairo_destroy (cr);
-
- return cairo_surface;
+ return cairo_xlib_surface_create (x->display, drawable,
+ DefaultVisual (x->display, x->screen),
+ width, height);
}
static CairoViewerIface cairo_x_viewer_iface = {
&x_viewer,
- cairo_x_view_iface_create_surface
+ cairo_x_view_iface_create_surface,
+ cairo_view_iface_paint_background_over
};
#endif /* HAVE_CAIRO_XLIB */
@@ -132,7 +156,8 @@ const PangoViewer cairo_image_viewer = {
static CairoViewerIface cairo_image_viewer_iface = {
&cairo_image_viewer,
- cairo_view_iface_create_surface
+ cairo_view_iface_create_surface,
+ cairo_view_iface_paint_background_source
};
@@ -284,7 +309,8 @@ const PangoViewer cairo_vector_viewer = {
static CairoViewerIface cairo_vector_viewer_iface = {
&cairo_vector_viewer,
- cairo_view_iface_create_surface
+ cairo_view_iface_create_surface,
+ cairo_view_iface_paint_background_over
};
diff --git a/pango-view/viewer-cairo.h b/pango-view/viewer-cairo.h
index ecd06760..81d2eeee 100644
--- a/pango-view/viewer-cairo.h
+++ b/pango-view/viewer-cairo.h
@@ -35,6 +35,9 @@ struct _CairoViewerIface
gpointer surface,
int width,
int height);
+
+ void (*paint_background) (gpointer instance,
+ cairo_t *cr);
};
gpointer cairo_viewer_iface_create (const CairoViewerIface **iface_out);
diff --git a/pango-view/viewer-pangocairo.c b/pango-view/viewer-pangocairo.c
index 9631c059..bed0f38f 100644
--- a/pango-view/viewer-pangocairo.c
+++ b/pango-view/viewer-pangocairo.c
@@ -302,13 +302,14 @@ transform_callback (PangoContext *context,
}
static void
-pangocairo_view_render (gpointer instance G_GNUC_UNUSED,
+pangocairo_view_render (gpointer instance,
gpointer surface,
PangoContext *context,
int *width,
int *height,
gpointer state)
{
+ CairoViewer *c = (CairoViewer *) instance;
cairo_t *cr;
CairoSurface *c_surface = (CairoSurface *) surface;
@@ -318,7 +319,15 @@ pangocairo_view_render (gpointer instance G_GNUC_UNUSED,
transform_callback (context, NULL, cr, state);
- cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ c->iface->paint_background (instance, cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+ cairo_set_source_rgba (cr,
+ opt_fg_color.red / 65535.,
+ opt_fg_color.green / 65535.,
+ opt_fg_color.blue / 65535.,
+ opt_fg_alpha / 65535.);
+
do_output (context, render_callback, transform_callback, cr, state, width, height);
cairo_destroy (cr);
diff --git a/pango-view/viewer-pangoxft.c b/pango-view/viewer-pangoxft.c
index 198f9edc..9e2cc89c 100644
--- a/pango-view/viewer-pangoxft.c
+++ b/pango-view/viewer-pangoxft.c
@@ -114,17 +114,23 @@ pangoxft_view_render (gpointer instance,
DefaultVisual (x->display, x->screen),
DefaultColormap (x->display, x->screen));
- color.color.red = 0xffff;
- color.color.blue = 0xffff;
- color.color.green = 0xffff;
- color.color.alpha = 0xffff;
-
- XftDrawRect (draw, &color, 0, 0, *width, *height);
+ if (opt_bg_set)
+ {
+ /* XftDrawRect only fills solid.
+ * Flatten with white.
+ */
+ color.color.red = ((opt_bg_color.red * opt_bg_alpha) >> 16) + (65535 - opt_bg_alpha);
+ color.color.green = ((opt_bg_color.green * opt_bg_alpha) >> 16) + (65535 - opt_bg_alpha);
+ color.color.blue = ((opt_bg_color.blue * opt_bg_alpha) >> 16) + (65535 - opt_bg_alpha);
+ color.color.alpha = 65535;
+
+ XftDrawRect (draw, &color, 0, 0, *width, *height);
+ }
- color.color.red = 0x0;
- color.color.green = 0x0;
- color.color.blue = 0x0;
- color.color.alpha = 0xffff;
+ color.color.red = opt_fg_color.red;
+ color.color.blue = opt_fg_color.green;
+ color.color.green = opt_fg_color.blue;
+ color.color.alpha = opt_fg_alpha;
xft_context.draw = draw;
xft_context.color = color;
diff --git a/pango-view/viewer-render.c b/pango-view/viewer-render.c
index 41bac332..e078dd16 100644
--- a/pango-view/viewer-render.c
+++ b/pango-view/viewer-render.c
@@ -62,6 +62,11 @@ const char *opt_pangorc = NULL;
const PangoViewer *opt_viewer = NULL;
const char *opt_language = NULL;
gboolean opt_single_par = FALSE;
+PangoColor opt_fg_color = {0, 0, 0};
+guint16 opt_fg_alpha = 65535;
+gboolean opt_bg_set = FALSE;
+PangoColor opt_bg_color = {65535, 65535, 65535};
+guint16 opt_bg_alpha = 65535;
/* Text (or markup) to render */
static char *text;
@@ -365,7 +370,6 @@ parse_enum (GType type,
"Argument for %s must be one of %s",
name,
possible_values);
- ret = FALSE;
}
g_free (possible_values);
@@ -454,6 +458,93 @@ parse_wrap (const char *name,
return ret;
}
+static gboolean
+parse_rgba_color (PangoColor *color,
+ guint16 *alpha,
+ const char *name,
+ const char *arg,
+ gpointer data G_GNUC_UNUSED,
+ GError **error)
+{
+ char *possible_values = NULL;
+ gboolean ret;
+ char buf[32];
+ int len;
+
+ len = strlen (arg);
+ /* handle alpha */
+ if (*arg == '#' && (len == 5 || len == 9 || len == 17))
+ {
+ int width, bits;
+ unsigned int a;
+
+ bits = len - 1;
+ width = bits >> 2;
+
+ strcpy (buf, arg);
+ arg = buf;
+
+ if (!sscanf (buf + len - width, "%x", &a))
+ {
+ ret = FALSE;
+ goto err;
+ }
+ buf[len - width] = '\0';
+
+ a <<= (16 - bits);
+ while (bits < 16)
+ {
+ a |= (a >> bits);
+ bits *= 2;
+ }
+ *alpha = a;
+ }
+ else
+ *alpha = 65535;
+
+ ret = pango_color_parse (color, arg);
+
+err:
+ if (!ret && error)
+ {
+ g_set_error(error,
+ G_OPTION_ERROR,
+ G_OPTION_ERROR_BAD_VALUE,
+ "Argument for %s must be a color name like red, or CSS-style #rrggbb / #rrggbbaa",
+ name);
+ }
+
+ return ret;
+}
+
+static gboolean
+parse_foreground (const char *name,
+ const char *arg,
+ gpointer data,
+ GError **error)
+{
+ return parse_rgba_color (&opt_fg_color, &opt_fg_alpha,
+ name, arg, data, error);
+}
+
+static gboolean
+parse_background (const char *name,
+ const char *arg,
+ gpointer data,
+ GError **error)
+{
+ opt_bg_set = TRUE;
+
+ if (0 == strcmp ("transparent", arg))
+ {
+ opt_bg_alpha = 0;
+ return TRUE;
+ }
+
+ return parse_rgba_color (&opt_bg_color, &opt_bg_alpha,
+ name, arg, data, error);
+}
+
static gchar *
backends_to_string (void)
{
@@ -561,6 +652,8 @@ parse_options (int argc, char *argv[])
"No layout direction according to contents", NULL},
{"backend", 0, backend_flag, G_OPTION_ARG_CALLBACK, &parse_backend,
backend_desc, backend_options},
+ {"background", 0, 0, G_OPTION_ARG_CALLBACK, &parse_background,
+ "Set the background color", "red/#rrggbb/#rrggbbaa/transparent/etc"},
{"no-display", 'q', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_display,
"Do not display (just write to file or whatever)", NULL},
{"dpi", 0, 0, G_OPTION_ARG_INT, &opt_dpi,
@@ -571,6 +664,8 @@ parse_options (int argc, char *argv[])
"Ellipsization mode", "start/middle/end"},
{"font", 0, 0, G_OPTION_ARG_STRING, &opt_font,
"Set the font description", "description"},
+ {"foreground", 0, 0, G_OPTION_ARG_CALLBACK, &parse_foreground,
+ "Set the text color", "red/#rrggbb/#rrggbbaa/etc"},
{"gravity", 0, 0, G_OPTION_ARG_CALLBACK, &parse_gravity,
"Base gravity: glyph rotation", "south/east/north/west/auto"},
{"gravity-hint", 0, 0, G_OPTION_ARG_CALLBACK, &parse_gravity_hint,
diff --git a/pango-view/viewer-render.h b/pango-view/viewer-render.h
index 10fb1a13..9598054e 100644
--- a/pango-view/viewer-render.h
+++ b/pango-view/viewer-render.h
@@ -73,7 +73,7 @@ extern int opt_indent;
extern PangoEllipsizeMode opt_ellipsize;
extern const char *opt_pangorc;
-/* handled by view.c */
+/* handled by viewer-main.c */
extern gboolean opt_display;
extern const char *opt_output;
extern int opt_runs;
@@ -82,5 +82,10 @@ extern const PangoViewer *opt_viewer;
/* handled by backend-specific code */
extern int opt_dpi;
extern HintMode opt_hinting;
+extern PangoColor opt_fg_color;
+extern guint16 opt_fg_alpha;
+extern gboolean opt_bg_set;
+extern PangoColor opt_bg_color;
+extern guint16 opt_bg_alpha;
#endif /* VIEWER_RENDER_H */
diff --git a/pango-view/viewer-x.c b/pango-view/viewer-x.c
index 25492f33..89864c08 100644
--- a/pango-view/viewer-x.c
+++ b/pango-view/viewer-x.c
@@ -66,10 +66,18 @@ x_view_create_surface (gpointer instance,
{
XViewer *x = (XViewer *) instance;
Pixmap pixmap;
+ GC gc;
pixmap = XCreatePixmap (x->display, DefaultRootWindow (x->display), width, height,
DefaultDepth (x->display, x->screen));
+ gc = XCreateGC (x->display, pixmap, 0, NULL);
+
+ XSetForeground (x->display, gc, WhitePixel (x->display, x->screen));
+ XFillRectangle (x->display, pixmap, gc, 0, 0, width, height);
+
+ XFreeGC (x->display, gc);
+
return (gpointer) pixmap;
}