[pango: 2/2] Bug 502805 – pango-view option for foreground/ba



commit a6af36b9c06b81ab8095afff85f68f37c27a4b3b
Author: Behdad Esfahbod <behdad behdad org>
Date:   Mon Mar 16 16:03:36 2009 -0400

    Bug 502805 â?? pango-view option for foreground/background color
---
 pango-view/viewer-cairo.c      |   58 +++++++++++++++++-------
 pango-view/viewer-cairo.h      |    3 +
 pango-view/viewer-pangocairo.c |   13 +++++-
 pango-view/viewer-pangoxft.c   |   26 +++++++----
 pango-view/viewer-render.c     |   97 +++++++++++++++++++++++++++++++++++++++-
 pango-view/viewer-render.h     |    7 +++-
 pango-view/viewer-x.c          |    8 +++
 7 files changed, 182 insertions(+), 30 deletions(-)

diff --git a/pango-view/viewer-cairo.c b/pango-view/viewer-cairo.c
index 5ecfb96..579076e 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 ecd0676..81d2eee 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 9631c05..bed0f38 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 198f9ed..9e2cc89 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 41bac33..e078dd1 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 10fb1a1..9598054 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 25492f3..89864c0 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;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]