summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtktextattributes.c98
-rw-r--r--gtk/gtktextattributes.h12
-rw-r--r--gtk/gtktextdisplay.c100
-rw-r--r--gtk/gtktextlayout.c28
-rw-r--r--gtk/gtktextlayout.h1
-rw-r--r--gtk/gtktexttag.c192
-rw-r--r--tests/Makefile.am8
-rw-r--r--tests/testtextview.c151
8 files changed, 477 insertions, 113 deletions
diff --git a/gtk/gtktextattributes.c b/gtk/gtktextattributes.c
index d2a9c6c3d5..67c3db392a 100644
--- a/gtk/gtktextattributes.c
+++ b/gtk/gtktextattributes.c
@@ -61,17 +61,17 @@
* Creates a #GtkTextAttributes, which describes
* a set of properties on some text.
*
- * Return value: a new #GtkTextAttributes
- **/
+ * Return value: a new #GtkTextAttributes,
+ * free with gtk_text_attributes_unref().
+ */
GtkTextAttributes*
gtk_text_attributes_new (void)
{
GtkTextAttributes *values;
- values = g_new0 (GtkTextAttributes, 1);
+ values = g_slice_new0 (GtkTextAttributes);
/* 0 is a valid value for most of the struct */
-
values->refcount = 1;
values->language = gtk_get_default_language ();
@@ -79,18 +79,19 @@ gtk_text_attributes_new (void)
values->font_scale = 1.0;
values->editable = TRUE;
-
+
return values;
}
/**
* gtk_text_attributes_copy:
* @src: a #GtkTextAttributes to be copied
- *
+ *
* Copies @src and returns a new #GtkTextAttributes.
- *
- * Return value: a copy of @src
- **/
+ *
+ * Return value: a copy of @src,
+ * free with gtk_text_attributes_unref()
+ */
GtkTextAttributes*
gtk_text_attributes_copy (GtkTextAttributes *src)
{
@@ -110,10 +111,10 @@ G_DEFINE_BOXED_TYPE (GtkTextAttributes, gtk_text_attributes,
* gtk_text_attributes_copy_values:
* @src: a #GtkTextAttributes
* @dest: another #GtkTextAttributes
- *
- * Copies the values from @src to @dest so that @dest has the same values
- * as @src. Frees existing values in @dest.
- **/
+ *
+ * Copies the values from @src to @dest so that @dest has
+ * the same values as @src. Frees existing values in @dest.
+ */
void
gtk_text_attributes_copy_values (GtkTextAttributes *src,
GtkTextAttributes *dest)
@@ -124,10 +125,24 @@ gtk_text_attributes_copy_values (GtkTextAttributes *src,
return;
/* Remove refs */
+ if (dest->tabs)
+ pango_tab_array_free (dest->tabs);
if (dest->font)
pango_font_description_free (dest->font);
-
+
+ if (dest->pg_bg_color)
+ gdk_color_free (dest->pg_bg_color);
+
+ if (dest->pg_bg_rgba)
+ gdk_rgba_free (dest->pg_bg_rgba);
+
+ if (dest->appearance.rgba[0])
+ gdk_rgba_free (dest->appearance.rgba[0]);
+
+ if (dest->appearance.rgba[1])
+ gdk_rgba_free (dest->appearance.rgba[1]);
+
/* Copy */
orig_refcount = dest->refcount;
@@ -138,12 +153,21 @@ gtk_text_attributes_copy_values (GtkTextAttributes *src,
dest->language = src->language;
- if (dest->font)
+ if (src->font)
dest->font = pango_font_description_copy (src->font);
-
+
if (src->pg_bg_color)
dest->pg_bg_color = gdk_color_copy (src->pg_bg_color);
+ if (src->pg_bg_rgba)
+ dest->pg_bg_rgba = gdk_rgba_copy (src->pg_bg_rgba);
+
+ if (src->appearance.rgba[0])
+ dest->appearance.rgba[0] = gdk_rgba_copy (src->appearance.rgba[0]);
+
+ if (src->appearance.rgba[1])
+ dest->appearance.rgba[1] = gdk_rgba_copy (src->appearance.rgba[1]);
+
dest->refcount = orig_refcount;
}
@@ -191,7 +215,16 @@ gtk_text_attributes_unref (GtkTextAttributes *values)
if (values->pg_bg_color)
gdk_color_free (values->pg_bg_color);
- g_free (values);
+ if (values->pg_bg_rgba)
+ gdk_rgba_free (values->pg_bg_rgba);
+
+ if (values->appearance.rgba[0])
+ gdk_rgba_free (values->appearance.rgba[0]);
+
+ if (values->appearance.rgba[1])
+ gdk_rgba_free (values->appearance.rgba[1]);
+
+ g_slice_free (GtkTextAttributes, values);
}
}
@@ -216,16 +249,41 @@ _gtk_text_attributes_fill_from_tags (GtkTextAttributes *dest,
if (tag->priv->bg_color_set)
{
- dest->appearance.bg_color = vals->appearance.bg_color;
+ if (dest->appearance.rgba[0])
+ {
+ gdk_rgba_free (dest->appearance.rgba[0]);
+ dest->appearance.rgba[0] = NULL;
+ }
+
+ if (vals->appearance.rgba[0])
+ dest->appearance.rgba[0] = gdk_rgba_copy (vals->appearance.rgba[0]);
dest->appearance.draw_bg = TRUE;
}
+
if (tag->priv->fg_color_set)
- dest->appearance.fg_color = vals->appearance.fg_color;
+ {
+ if (dest->appearance.rgba[1])
+ {
+ gdk_rgba_free (dest->appearance.rgba[1]);
+ dest->appearance.rgba[1] = NULL;
+ }
+
+ if (vals->appearance.rgba[1])
+ dest->appearance.rgba[1] = gdk_rgba_copy (vals->appearance.rgba[1]);
+ }
if (tag->priv->pg_bg_color_set)
{
- dest->pg_bg_color = gdk_color_copy (vals->pg_bg_color);
+ if (dest->pg_bg_rgba)
+ {
+ gdk_rgba_free (dest->pg_bg_rgba);
+ dest->pg_bg_rgba = NULL;
+
+ }
+
+ if (vals->pg_bg_rgba)
+ dest->pg_bg_rgba = gdk_rgba_copy (vals->pg_bg_rgba);
}
if (vals->font)
diff --git a/gtk/gtktextattributes.h b/gtk/gtktextattributes.h
index aa7d6f8aa8..12c1af7063 100644
--- a/gtk/gtktextattributes.h
+++ b/gtk/gtktextattributes.h
@@ -102,8 +102,12 @@ struct _GtkTextAppearance
guint inside_selection : 1;
guint is_text : 1;
- /*< private >*/
- guint padding[4];
+ GdkRGBA *rgba[2];
+
+#if __SIZEOF_INT__ == __SIZEOF_POINTER__
+ /* unusable, just for ABI compat */
+ guint padding[2];
+#endif
};
struct _GtkTextAttributes
@@ -155,7 +159,9 @@ struct _GtkTextAttributes
guint editable : 1;
/*< private >*/
- guint padding[4];
+ GdkRGBA *pg_bg_rgba;
+
+ guint padding[3];
};
GtkTextAttributes* gtk_text_attributes_new (void);
diff --git a/gtk/gtktextdisplay.c b/gtk/gtktextdisplay.c
index e9a24bc5f3..e3ec766dcb 100644
--- a/gtk/gtktextdisplay.c
+++ b/gtk/gtktextdisplay.c
@@ -110,8 +110,11 @@ struct _GtkTextRenderer
GdkColor *error_color; /* Error underline color for this widget */
GList *widgets; /* widgets encountered when drawing */
-
- int state;
+
+ GdkRGBA rgba[4];
+ guint8 rgba_set[4];
+
+ guint state : 2;
};
struct _GtkTextRendererClass
@@ -122,45 +125,34 @@ struct _GtkTextRendererClass
G_DEFINE_TYPE (GtkTextRenderer, _gtk_text_renderer, PANGO_TYPE_RENDERER)
static void
-text_renderer_set_gdk_color (GtkTextRenderer *text_renderer,
- PangoRenderPart part,
- GdkColor *gdk_color)
-{
- PangoRenderer *renderer = PANGO_RENDERER (text_renderer);
-
- if (gdk_color)
- {
- PangoColor color;
-
- color.red = gdk_color->red;
- color.green = gdk_color->green;
- color.blue = gdk_color->blue;
-
- pango_renderer_set_color (renderer, part, &color);
- }
- else
- pango_renderer_set_color (renderer, part, NULL);
-}
-
-static void
text_renderer_set_rgba (GtkTextRenderer *text_renderer,
PangoRenderPart part,
- GdkRGBA *rgba)
+ const GdkRGBA *rgba)
{
PangoRenderer *renderer = PANGO_RENDERER (text_renderer);
+ PangoColor dummy = { 0, };
+
+ if ((!rgba && !text_renderer->rgba_set[part]) ||
+ (rgba && text_renderer->rgba_set[part] &&
+ text_renderer->rgba[part].red == rgba->red &&
+ text_renderer->rgba[part].green == rgba->green &&
+ text_renderer->rgba[part].blue == rgba->blue &&
+ text_renderer->rgba[part].alpha == rgba->alpha))
+ return;
if (rgba)
{
- PangoColor color;
+ text_renderer->rgba_set[part] = TRUE;
+ text_renderer->rgba[part] = *rgba;
- color.red = CLAMP (rgba->red * 65535. + 0.5, 0, 65535);
- color.green = CLAMP (rgba->green * 65535. + 0.5, 0, 65535);
- color.blue = CLAMP (rgba->blue * 65535. + 0.5, 0, 65535);
-
- pango_renderer_set_color (renderer, part, &color);
+ pango_renderer_set_color (renderer, part, &dummy);
}
else
- pango_renderer_set_color (renderer, part, NULL);
+ {
+ text_renderer->rgba_set[part] = FALSE;
+
+ pango_renderer_set_color (renderer, part, NULL);
+ }
}
static GtkTextAppearance *
@@ -188,9 +180,8 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer,
GtkStyleContext *context;
GtkStateFlags state;
GtkTextRenderer *text_renderer = GTK_TEXT_RENDERER (renderer);
- GdkColor *bg_color = NULL;
+ GdkRGBA *bg_rgba = NULL;
GdkRGBA *fg_rgba = NULL;
- GdkColor *fg_color = NULL;
GtkTextAppearance *appearance;
PANGO_RENDERER_CLASS (_gtk_text_renderer_parent_class)->prepare_run (renderer, run);
@@ -199,15 +190,14 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer,
g_assert (appearance != NULL);
context = gtk_widget_get_style_context (text_renderer->widget);
-
- state = gtk_widget_get_state_flags (text_renderer->widget);
+ state = gtk_widget_get_state_flags (text_renderer->widget);
if (appearance->draw_bg && text_renderer->state == NORMAL)
- bg_color = &appearance->bg_color;
+ bg_rgba = appearance->rgba[0];
else
- bg_color = NULL;
+ bg_rgba = NULL;
- text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_color);
+ text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_BACKGROUND, bg_rgba);
if (text_renderer->state == SELECTED)
{
@@ -224,18 +214,10 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer,
NULL);
}
else
- fg_color = &appearance->fg_color;
+ fg_rgba = appearance->rgba[1];
- if (fg_rgba)
- {
- text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba);
- text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH,fg_rgba);
- }
- else
- {
- text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_color);
- text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_color);
- }
+ text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_FOREGROUND, fg_rgba);
+ text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_STRIKETHROUGH,fg_rgba);
if (appearance->underline == PANGO_UNDERLINE_ERROR)
{
@@ -252,28 +234,24 @@ gtk_text_renderer_prepare_run (PangoRenderer *renderer,
}
}
- text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_UNDERLINE, text_renderer->error_color);
+ // XXX Transform the gdk color to an gdk rgba here
+ //text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_UNDERLINE, text_renderer->error_color);
}
- else if (fg_rgba)
- text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba);
else
- text_renderer_set_gdk_color (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_color);
+ text_renderer_set_rgba (text_renderer, PANGO_RENDER_PART_UNDERLINE, fg_rgba);
+
+ if (fg_rgba != appearance->rgba[1])
+ gdk_rgba_free (fg_rgba);
}
static void
set_color (GtkTextRenderer *text_renderer,
PangoRenderPart part)
{
- PangoColor *color;
-
cairo_save (text_renderer->cr);
- color = pango_renderer_get_color (PANGO_RENDERER (text_renderer), part);
- if (color)
- cairo_set_source_rgb (text_renderer->cr,
- color->red / 65535.,
- color->green / 65535.,
- color->blue / 65535.);
+ if (text_renderer->rgba_set[part])
+ gdk_cairo_set_source_rgba (text_renderer->cr, &text_renderer->rgba[part]);
}
static void
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 35809873d5..f19ab618d2 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -1424,9 +1424,27 @@ gtk_text_attr_appearance_destroy (PangoAttribute *attr)
{
GtkTextAttrAppearance *appearance_attr = (GtkTextAttrAppearance *)attr;
+ if (appearance_attr->appearance.rgba[0])
+ gdk_rgba_free (appearance_attr->appearance.rgba[0]);
+
+ if (appearance_attr->appearance.rgba[1])
+ gdk_rgba_free (appearance_attr->appearance.rgba[1]);
+
g_slice_free (GtkTextAttrAppearance, appearance_attr);
}
+static gboolean
+rgba_equal (const GdkRGBA *rgba1, const GdkRGBA *rgba2)
+{
+ if (rgba1 && rgba2)
+ return gdk_rgba_equal (rgba1, rgba2);
+
+ if (rgba1 || rgba2)
+ return FALSE;
+
+ return TRUE;
+}
+
static gboolean
gtk_text_attr_appearance_compare (const PangoAttribute *attr1,
const PangoAttribute *attr2)
@@ -1434,8 +1452,8 @@ gtk_text_attr_appearance_compare (const PangoAttribute *attr1,
const GtkTextAppearance *appearance1 = &((const GtkTextAttrAppearance *)attr1)->appearance;
const GtkTextAppearance *appearance2 = &((const GtkTextAttrAppearance *)attr2)->appearance;
- return (gdk_color_equal (&appearance1->fg_color, &appearance2->fg_color) &&
- gdk_color_equal (&appearance1->bg_color, &appearance2->bg_color) &&
+ return (rgba_equal (appearance1->rgba[0], appearance2->rgba[0]) &&
+ rgba_equal (appearance1->rgba[1], appearance2->rgba[1]) &&
appearance1->underline == appearance2->underline &&
appearance1->strikethrough == appearance2->strikethrough &&
appearance1->draw_bg == appearance2->draw_bg);
@@ -1472,6 +1490,12 @@ gtk_text_attr_appearance_new (const GtkTextAppearance *appearance)
result->appearance = *appearance;
+ if (appearance->rgba[0])
+ result->appearance.rgba[0] = gdk_rgba_copy (appearance->rgba[0]);
+
+ if (appearance->rgba[1])
+ result->appearance.rgba[1] = gdk_rgba_copy (appearance->rgba[1]);
+
return (PangoAttribute *)result;
}
diff --git a/gtk/gtktextlayout.h b/gtk/gtktextlayout.h
index 4e9533d0eb..09ca01c5b0 100644
--- a/gtk/gtktextlayout.h
+++ b/gtk/gtktextlayout.h
@@ -233,6 +233,7 @@ struct _GtkTextCursorDisplay
guint is_strong : 1;
guint is_weak : 1;
};
+
struct _GtkTextLineDisplay
{
PangoLayout *layout;
diff --git a/gtk/gtktexttag.c b/gtk/gtktexttag.c
index 1a653b3b53..dbfb5aea36 100644
--- a/gtk/gtktexttag.c
+++ b/gtk/gtktexttag.c
@@ -92,6 +92,8 @@ enum {
PROP_FOREGROUND,
PROP_BACKGROUND_GDK,
PROP_FOREGROUND_GDK,
+ PROP_BACKGROUND_RGBA,
+ PROP_FOREGROUND_RGBA,
PROP_FONT,
PROP_FONT_DESC,
PROP_FAMILY,
@@ -121,6 +123,7 @@ enum {
PROP_INVISIBLE,
PROP_PARAGRAPH_BACKGROUND,
PROP_PARAGRAPH_BACKGROUND_GDK,
+ PROP_PARAGRAPH_BACKGROUND_RGBA,
/* Behavior args */
PROP_ACCUMULATIVE_MARGIN,
@@ -206,6 +209,15 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
GDK_TYPE_COLOR,
GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
+ PROP_BACKGROUND_RGBA,
+ g_param_spec_boxed ("background-rgba",
+ P_("Background rgba"),
+ P_("Background rgba as a (possibly unallocated) GdkRGBA"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READWRITE));
+
g_object_class_install_property (object_class,
PROP_BACKGROUND_FULL_HEIGHT,
g_param_spec_boolean ("background-full-height",
@@ -231,6 +243,14 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
GTK_PARAM_READWRITE));
g_object_class_install_property (object_class,
+ PROP_FOREGROUND_RGBA,
+ g_param_spec_boxed ("foreground-rgba",
+ P_("Foreground rgba"),
+ P_("Foreground rgba as a (possibly unallocated) GdkRGBA"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class,
PROP_DIRECTION,
g_param_spec_enum ("direction",
P_("Text direction"),
@@ -532,6 +552,22 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
GTK_PARAM_READWRITE));
/**
+ * GtkTextTag:paragraph-background-rgba:
+ *
+ * The paragraph background color as a as a (possibly unallocated)
+ * #GdkRGBA.
+ *
+ * Since: 3.2
+ */
+ g_object_class_install_property (object_class,
+ PROP_PARAGRAPH_BACKGROUND_RGBA,
+ g_param_spec_boxed ("paragraph-background-rgba",
+ P_("Paragraph background rgba"),
+ P_("Paragraph background rgba as a (possibly unallocated) GdkRGBA"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READWRITE));
+
+ /**
* GtkTextTag:accumulative-margin:
*
* Whether the margins accumulate or override each other.
@@ -740,11 +776,16 @@ gtk_text_tag_finalize (GObject *object)
}
static void
-set_bg_color (GtkTextTag *tag, GdkColor *color)
+set_bg_rgba (GtkTextTag *tag, GdkRGBA *rgba)
{
GtkTextTagPrivate *priv = tag->priv;
- if (color)
+ if (priv->values->appearance.rgba[0])
+ gdk_rgba_free (priv->values->appearance.rgba[0]);
+
+ priv->values->appearance.rgba[0] = NULL;
+
+ if (rgba)
{
if (!priv->bg_color_set)
{
@@ -752,7 +793,7 @@ set_bg_color (GtkTextTag *tag, GdkColor *color)
g_object_notify (G_OBJECT (tag), "background-set");
}
- priv->values->appearance.bg_color = *color;
+ priv->values->appearance.rgba[0] = gdk_rgba_copy (rgba);
}
else
{
@@ -765,18 +806,24 @@ set_bg_color (GtkTextTag *tag, GdkColor *color)
}
static void
-set_fg_color (GtkTextTag *tag, GdkColor *color)
+set_fg_rgba (GtkTextTag *tag, GdkRGBA *rgba)
{
GtkTextTagPrivate *priv = tag->priv;
- if (color)
+ if (priv->values->appearance.rgba[1])
+ gdk_rgba_free (priv->values->appearance.rgba[1]);
+
+ priv->values->appearance.rgba[1] = NULL;
+
+ if (rgba)
{
if (!priv->fg_color_set)
{
priv->fg_color_set = TRUE;
g_object_notify (G_OBJECT (tag), "foreground-set");
}
- priv->values->appearance.fg_color = *color;
+
+ priv->values->appearance.rgba[1] = gdk_rgba_copy (rgba);
}
else
{
@@ -789,21 +836,24 @@ set_fg_color (GtkTextTag *tag, GdkColor *color)
}
static void
-set_pg_bg_color (GtkTextTag *tag, GdkColor *color)
+set_pg_bg_rgba (GtkTextTag *tag, GdkRGBA *rgba)
{
GtkTextTagPrivate *priv = tag->priv;
- if (color)
+ if (priv->values->pg_bg_rgba)
+ gdk_rgba_free (priv->values->pg_bg_rgba);
+
+ priv->values->pg_bg_rgba = NULL;
+
+ if (rgba)
{
if (!priv->pg_bg_color_set)
{
priv->pg_bg_color_set = TRUE;
g_object_notify (G_OBJECT (tag), "paragraph-background-set");
}
- else
- gdk_color_free (priv->values->pg_bg_color);
- priv->values->pg_bg_color = gdk_color_copy (color);
+ priv->values->pg_bg_rgba = gdk_rgba_copy (rgba);
}
else
{
@@ -811,11 +861,63 @@ set_pg_bg_color (GtkTextTag *tag, GdkColor *color)
{
priv->pg_bg_color_set = FALSE;
g_object_notify (G_OBJECT (tag), "paragraph-background-set");
- gdk_color_free (priv->values->pg_bg_color);
}
+ }
+}
- priv->values->pg_bg_color = NULL;
+
+static void
+set_bg_color (GtkTextTag *tag, GdkColor *color)
+{
+ if (color)
+ {
+ gchar *str;
+ GdkRGBA rgba;
+
+ str = gdk_color_to_string (color);
+ gdk_rgba_parse (&rgba, str);
+ g_free (str);
+
+ set_bg_rgba (tag, &rgba);
}
+ else
+ set_bg_rgba (tag, NULL);
+}
+
+static void
+set_fg_color (GtkTextTag *tag, GdkColor *color)
+{
+ if (color)
+ {
+ gchar *str;
+ GdkRGBA rgba;
+
+ str = gdk_color_to_string (color);
+ gdk_rgba_parse (&rgba, str);
+ g_free (str);
+
+ set_fg_rgba (tag, &rgba);
+ }
+ else
+ set_fg_rgba (tag, NULL);
+}
+
+static void
+set_pg_bg_color (GtkTextTag *tag, GdkColor *color)
+{
+ if (color)
+ {
+ gchar *str;
+ GdkRGBA rgba;
+
+ str = gdk_color_to_string (color);
+ gdk_rgba_parse (&rgba, str);
+ g_free (str);
+
+ set_pg_bg_rgba (tag, &rgba);
+ }
+ else
+ set_pg_bg_rgba (tag, NULL);
}
static PangoFontMask
@@ -998,12 +1100,12 @@ gtk_text_tag_set_property (GObject *object,
case PROP_BACKGROUND:
{
- GdkColor color;
+ GdkRGBA rgba;
if (!g_value_get_string (value))
- set_bg_color (text_tag, NULL); /* reset to background_set to FALSE */
- else if (gdk_color_parse (g_value_get_string (value), &color))
- set_bg_color (text_tag, &color);
+ set_bg_rgba (text_tag, NULL); /* reset background_set to FALSE */
+ else if (gdk_rgba_parse (&rgba, g_value_get_string (value)))
+ set_bg_rgba (text_tag, &rgba);
else
g_warning ("Don't know color `%s'", g_value_get_string (value));
@@ -1013,12 +1115,12 @@ gtk_text_tag_set_property (GObject *object,
case PROP_FOREGROUND:
{
- GdkColor color;
+ GdkRGBA rgba;
if (!g_value_get_string (value))
- set_fg_color (text_tag, NULL); /* reset to foreground_set to FALSE */
- else if (gdk_color_parse (g_value_get_string (value), &color))
- set_fg_color (text_tag, &color);
+ set_fg_rgba (text_tag, NULL); /* reset to foreground_set to FALSE */
+ else if (gdk_rgba_parse (&rgba, g_value_get_string (value)))
+ set_fg_rgba (text_tag, &rgba);
else
g_warning ("Don't know color `%s'", g_value_get_string (value));
@@ -1042,6 +1144,22 @@ gtk_text_tag_set_property (GObject *object,
}
break;
+ case PROP_BACKGROUND_RGBA:
+ {
+ GdkRGBA *color = g_value_get_boxed (value);
+
+ set_bg_rgba (text_tag, color);
+ }
+ break;
+
+ case PROP_FOREGROUND_RGBA:
+ {
+ GdkRGBA *color = g_value_get_boxed (value);
+
+ set_fg_rgba (text_tag, color);
+ }
+ break;
+
case PROP_FONT:
{
PangoFontDescription *font_desc = NULL;
@@ -1255,12 +1373,12 @@ gtk_text_tag_set_property (GObject *object,
case PROP_PARAGRAPH_BACKGROUND:
{
- GdkColor color;
+ GdkRGBA rgba;
if (!g_value_get_string (value))
- set_pg_bg_color (text_tag, NULL); /* reset to paragraph_background_set to FALSE */
- else if (gdk_color_parse (g_value_get_string (value), &color))
- set_pg_bg_color (text_tag, &color);
+ set_pg_bg_rgba (text_tag, NULL); /* reset paragraph_background_set to FALSE */
+ else if (gdk_rgba_parse (&rgba, g_value_get_string (value)))
+ set_pg_bg_rgba (text_tag, &rgba);
else
g_warning ("Don't know color `%s'", g_value_get_string (value));
@@ -1276,6 +1394,14 @@ gtk_text_tag_set_property (GObject *object,
}
break;
+ case PROP_PARAGRAPH_BACKGROUND_RGBA:
+ {
+ GdkRGBA *color = g_value_get_boxed (value);
+
+ set_pg_bg_rgba (text_tag, color);
+ }
+ break;
+
case PROP_ACCUMULATIVE_MARGIN:
priv->accumulative_margin = g_value_get_boolean (value);
g_object_notify (object, "accumulative-margin");
@@ -1429,6 +1555,7 @@ gtk_text_tag_get_property (GObject *object,
{
GtkTextTag *tag = GTK_TEXT_TAG (object);
GtkTextTagPrivate *priv = tag->priv;
+ GdkColor color = { 0, };
switch (prop_id)
{
@@ -1437,10 +1564,22 @@ gtk_text_tag_get_property (GObject *object,
break;
case PROP_BACKGROUND_GDK:
- g_value_set_boxed (value, &priv->values->appearance.bg_color);
+ if (priv->values->appearance.rgba[0])
+ {
+ color.red = CLAMP (priv->values->appearance.rgba[0]->red, 0.0, 1.0) * 65535.0;
+ color.green = CLAMP (priv->values->appearance.rgba[0]->green, 0.0, 1.0) * 65535.0;
+ color.blue = CLAMP (priv->values->appearance.rgba[0]->blue, 0.0, 1.0) * 65535.0;
+ }
+ g_value_set_boxed (value, &color);
break;
case PROP_FOREGROUND_GDK:
+ if (priv->values->appearance.rgba[1])
+ {
+ color.red = CLAMP (priv->values->appearance.rgba[1]->red, 0.0, 1.0) * 65535.0;
+ color.green = CLAMP (priv->values->appearance.rgba[1]->green, 0.0, 1.0) * 65535.0;
+ color.blue = CLAMP (priv->values->appearance.rgba[1]->blue, 0.0, 1.0) * 65535.0;
+ }
g_value_set_boxed (value, &priv->values->appearance.fg_color);
break;
@@ -1574,6 +1713,7 @@ gtk_text_tag_get_property (GObject *object,
break;
case PROP_PARAGRAPH_BACKGROUND_GDK:
+ /* XXX Transform the GdkRGBA here */
g_value_set_boxed (value, priv->values->pg_bg_color);
break;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f4029a9884..3ea7981cc0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -108,7 +108,8 @@ noinst_PROGRAMS = $(TEST_PROGS) \
testtoplevelembed \
testnoscreen \
testtreepos \
- testsensitive
+ testsensitive \
+ testtextview
if USE_X11
noinst_PROGRAMS += testerrors
@@ -207,6 +208,7 @@ testtoplevelembed_DEPENDENCIES = $(TEST_DEPS)
testnoscreen_DEPENDENCIES = $(TEST_DEPS)
testtreepos_DEPENDENCIES = $(TEST_DEPS)
testsensitive_DEPENDENCIES = $(TEST_DEPS)
+testtextview_DEPENDENCIES = $(TEST_DEPS)
flicker_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
@@ -291,6 +293,7 @@ testtoplevelembed_LDADD = $(LDADDS)
testnoscreen_LDADD = $(LDADDS)
testtreepos_LDADD = $(LDADDS)
testsensitive_LDADD = $(LDADDS)
+testtextview_LDADD = $(LDADDS)
testentrycompletion_SOURCES = \
@@ -436,6 +439,9 @@ styleexamples_SOURCES = styleexamples.c
testtoplevelembed_SOURCES = testtoplevelembed.c
+testtextview_SOURCES = testtextview.c
+
+
EXTRA_DIST += \
gradient1.png \
prop-editor.h \
diff --git a/tests/testtextview.c b/tests/testtextview.c
new file mode 100644
index 0000000000..2a7701f5b3
--- /dev/null
+++ b/tests/testtextview.c
@@ -0,0 +1,151 @@
+
+
+#include "config.h"
+#include <gtk/gtk.h>
+
+
+static void
+create_tags (GtkTextBuffer *buffer)
+{
+
+ gtk_text_buffer_create_tag (buffer, "italic",
+ "style", PANGO_STYLE_ITALIC, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "bold",
+ "weight", PANGO_WEIGHT_BOLD, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "x-large",
+ "scale", PANGO_SCALE_X_LARGE, NULL);
+
+ gtk_text_buffer_create_tag (buffer, "semi_blue_foreground",
+ "foreground", "rgba(0,0,255,0.5)", NULL);
+
+ gtk_text_buffer_create_tag (buffer, "semi_red_background",
+ "background", "rgba(255,0,0,0.5)", NULL);
+
+ gtk_text_buffer_create_tag (buffer, "word_wrap",
+ "wrap_mode", GTK_WRAP_WORD, NULL);
+}
+
+
+static void
+insert_text (GtkTextBuffer *buffer)
+{
+ GtkTextIter iter;
+ GtkTextIter start, end;
+
+ /* get start of buffer; each insertion will revalidate the
+ * iterator to point to just after the inserted text.
+ */
+ gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
+
+ gtk_text_buffer_insert (buffer, &iter,
+ "This test shows text view rendering some text with rgba colors.\n\n", -1);
+
+ gtk_text_buffer_insert (buffer, &iter, "For example, you can have ", -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ "italic translucent blue text", -1,
+ "italic",
+ "semi_blue_foreground",
+ "x-large",
+ NULL);
+
+ gtk_text_buffer_insert (buffer, &iter, ", or ", -1);
+
+ gtk_text_buffer_insert (buffer, &iter, ", ", -1);
+ gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
+ "bold text with translucent red background", -1,
+ "bold",
+ "semi_red_background",
+ "x-large",
+ NULL);
+ gtk_text_buffer_insert (buffer, &iter, ".", -1);
+
+ /* Apply word_wrap tag to whole buffer */
+ gtk_text_buffer_get_bounds (buffer, &start, &end);
+ gtk_text_buffer_apply_tag_by_name (buffer, "word_wrap", &start, &end);
+}
+
+
+static cairo_pattern_t *
+get_pattern (void)
+{
+ static cairo_pattern_t *static_pattern = NULL;
+
+ if (!static_pattern)
+ {
+ cairo_surface_t *surface =
+ cairo_image_surface_create_from_png ("gradient1.png");
+
+ if (surface)
+ {
+ static_pattern = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_extend (static_pattern, CAIRO_EXTEND_REFLECT);
+ }
+ else
+ g_warning ("Failed to create surface for gradient1.png\n");
+ }
+ return static_pattern;
+}
+
+static void
+draw_background (GtkWidget *widget, cairo_t *cr)
+{
+ GtkAllocation allocation;
+ cairo_pattern_t *pat;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ cairo_save (cr);
+
+#if 0
+ pat = cairo_pattern_create_linear (0.0, 0.0, 30.0, 30.0);
+ cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 0, 1);
+ cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1);
+ cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
+ cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
+ cairo_set_source (cr, pat);
+ cairo_fill (cr);
+ cairo_pattern_destroy (pat);
+
+#else
+
+ if (get_pattern ())
+ {
+ cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
+ cairo_set_source (cr, get_pattern ());
+ cairo_fill (cr);
+ }
+#endif
+
+ cairo_restore (cr);
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window, *textview;
+ GtkTextBuffer *buffer;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ textview = gtk_text_view_new ();
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
+
+ create_tags (buffer);
+ insert_text (buffer);
+
+ gtk_widget_show (textview);
+ gtk_container_add (GTK_CONTAINER (window), textview);
+
+ g_signal_connect (textview, "draw",
+ G_CALLBACK (draw_background), NULL);
+
+
+ gtk_widget_show (window);
+
+ gtk_main ();
+
+ return 0;
+}