forked from AuroraMiddleware/gtk
Added GdkRGBA properties to GtkTextTag.
This now allows text view to render text with alpha values in the text foreground and backgrounds, the work is almost complete, currently the error-underline-color is still a GdkColor style property and since we use only GdkRGBA for rendering it needs to be converted and applied, probably a new rgba version of the style property should also be introduced. This commit adds tests/testtextview that must be run from the tests/ directory to show translucent text in action.
This commit is contained in:
parent
297e739395
commit
d399a4acab
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
@ -121,46 +124,35 @@ 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -233,6 +233,7 @@ struct _GtkTextCursorDisplay
|
||||
guint is_strong : 1;
|
||||
guint is_weak : 1;
|
||||
};
|
||||
|
||||
struct _GtkTextLineDisplay
|
||||
{
|
||||
PangoLayout *layout;
|
||||
|
194
gtk/gtktexttag.c
194
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",
|
||||
@ -230,6 +242,14 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
||||
GDK_TYPE_COLOR,
|
||||
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",
|
||||
@ -531,6 +551,22 @@ gtk_text_tag_class_init (GtkTextTagClass *klass)
|
||||
GDK_TYPE_COLOR,
|
||||
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:
|
||||
*
|
||||
@ -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,13 +861,65 @@ 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
|
||||
get_property_font_set_mask (guint prop_id)
|
||||
{
|
||||
@ -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;
|
||||
|
||||
|
@ -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 \
|
||||
|
151
tests/testtextview.c
Normal file
151
tests/testtextview.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user