diff options
author | Owen Taylor <otaylor@redhat.com> | 2004-11-23 15:42:44 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2004-11-23 15:42:44 +0000 |
commit | db50679d56c8ded8a23f239b24a8cd9f1f2061c2 (patch) | |
tree | 8c7bc025eff030673c83214ecd410bf092ff3ceb /pango | |
parent | a0bbc6ef8b7dc902f20a2655cc54082e6acdca84 (diff) | |
download | pango-db50679d56c8ded8a23f239b24a8cd9f1f2061c2.tar.gz |
Add underline_color and strikethrough_color attribute types. (#147616,
Tue Nov 23 10:23:43 2004 Owen Taylor <otaylor@redhat.com>
* pango/pango-attributes.[ch]: Add underline_color
and strikethrough_color attribute types. (#147616, Morten
Welinder)
* pango/pango-markup.c docs/pango_markup.sgml: Add
corresponding 'underline_color' and
'strikethrough_color' attributes for <span>.
* pango/pango-renderer.c (pango_renderer_default_prepare_run):
Implement underline and strikethrough colors.
* pango/pango-renderer.c: Fix some bigs with updating
underlines/strikethrough state.
* pango/pango-renderer.c (get_total_matrix): Fix a const
warning.
* docs/pango-sections.txt: Update
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pango-attributes.c | 54 | ||||
-rw-r--r-- | pango/pango-attributes.h | 16 | ||||
-rw-r--r-- | pango/pango-markup.c | 48 | ||||
-rw-r--r-- | pango/pango-renderer.c | 169 |
4 files changed, 204 insertions, 83 deletions
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 276f7acd..f4b9b5e2 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -578,6 +578,33 @@ pango_attr_underline_new (PangoUnderline underline) } /** + * pango_attr_underline_color_new: + * @red: the red value (ranging from 0 to 65535) + * @green: the green value + * @blue: the blue value + * + * Create a new underline color attribute. This attribute + * modifies the color of underlines. If not set, underlines + * will use the foreground color. + * + * Return value: the new #PangoAttribute. + **/ +PangoAttribute * +pango_attr_underline_color_new (guint16 red, + guint16 green, + guint16 blue) +{ + static const PangoAttrClass klass = { + PANGO_ATTR_UNDERLINE_COLOR, + pango_attr_color_copy, + pango_attr_color_destroy, + pango_attr_color_equal + }; + + return pango_attr_color_new (&klass, red, green, blue); +} + +/** * pango_attr_strikethrough_new: * @strikethrough: %TRUE if the text should be struck-through. * @@ -599,6 +626,33 @@ pango_attr_strikethrough_new (gboolean strikethrough) } /** + * pango_attr_strikethrough_color_new: + * @red: the red value (ranging from 0 to 65535) + * @green: the green value + * @blue: the blue value + * + * Create a new strikethrough color attribute. This attribute + * modifies the color of strikethrough lines. If not set, strikethrough + * lines will use the foreground color. + * + * Return value: the new #PangoAttribute. + **/ +PangoAttribute * +pango_attr_strikethrough_color_new (guint16 red, + guint16 green, + guint16 blue) +{ + static const PangoAttrClass klass = { + PANGO_ATTR_STRIKETHROUGH_COLOR, + pango_attr_color_copy, + pango_attr_color_destroy, + pango_attr_color_equal + }; + + return pango_attr_color_new (&klass, red, green, blue); +} + +/** * pango_attr_rise_new: * @rise: the amount that the text should be displaced vertically, * in Pango units. Positive values displace the text upwards. diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 643d15e8..69b63187 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -82,7 +82,9 @@ typedef enum PANGO_ATTR_SHAPE, /* PangoAttrShape */ PANGO_ATTR_SCALE, /* PangoAttrFloat */ PANGO_ATTR_FALLBACK, /* PangoAttrInt */ - PANGO_ATTR_LETTER_SPACING /* PangoAttrInt */ + PANGO_ATTR_LETTER_SPACING, /* PangoAttrInt */ + PANGO_ATTR_UNDERLINE_COLOR, /* PangoAttrColor */ + PANGO_ATTR_STRIKETHROUGH_COLOR /* PangoAttrColor */ } PangoAttrType; typedef enum { @@ -182,8 +184,16 @@ PangoAttribute *pango_attr_weight_new (PangoWeight weight PangoAttribute *pango_attr_variant_new (PangoVariant variant); PangoAttribute *pango_attr_stretch_new (PangoStretch stretch); PangoAttribute *pango_attr_font_desc_new (const PangoFontDescription *desc); -PangoAttribute *pango_attr_underline_new (PangoUnderline underline); -PangoAttribute *pango_attr_strikethrough_new (gboolean strikethrough); + +PangoAttribute *pango_attr_underline_new (PangoUnderline underline); +PangoAttribute *pango_attr_underline_color_new (guint16 red, + guint16 green, + guint16 blue); +PangoAttribute *pango_attr_strikethrough_new (gboolean strikethrough); +PangoAttribute *pango_attr_strikethrough_color_new (guint16 red, + guint16 green, + guint16 blue); + PangoAttribute *pango_attr_rise_new (int rise); PangoAttribute *pango_attr_scale_new (double scale_factor); PangoAttribute *pango_attr_fallback_new (gboolean enable_fallback); diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 3b45cc73..5f68b8cd 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -855,7 +855,9 @@ span_parse_func (MarkupData *md, const char *foreground = NULL; const char *background = NULL; const char *underline = NULL; + const char *underline_color = NULL; const char *strikethrough = NULL; + const char *strikethrough_color = NULL; const char *rise = NULL; const char *letter_spacing = NULL; const char *lang = NULL; @@ -919,11 +921,21 @@ span_parse_func (MarkupData *md, CHECK_DUPLICATE (underline); underline = values[i]; } + else if (strcmp (names[i], "underline_color") == 0) + { + CHECK_DUPLICATE (underline_color); + underline_color = values[i]; + } else if (strcmp (names[i], "strikethrough") == 0) { CHECK_DUPLICATE (strikethrough); strikethrough = values[i]; } + else if (strcmp (names[i], "strikethrough_color") == 0) + { + CHECK_DUPLICATE (strikethrough_color); + strikethrough_color = values[i]; + } else if (strcmp (names[i], "rise") == 0) { CHECK_DUPLICATE (rise); @@ -1177,6 +1189,24 @@ span_parse_func (MarkupData *md, add_attribute (tag, pango_attr_underline_new (ul)); } + if (underline_color) + { + PangoColor color; + + if (!pango_color_parse (&color, underline_color)) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Could not parse underline_color color specification " + "'%s' on line %d"), + underline_color, line_number); + goto error; + } + + add_attribute (tag, pango_attr_underline_color_new (color.red, color.green, color.blue)); + } + if (strikethrough) { if (strcmp (strikethrough, "true") == 0) @@ -1196,6 +1226,24 @@ span_parse_func (MarkupData *md, } } + if (strikethrough_color) + { + PangoColor color; + + if (!pango_color_parse (&color, strikethrough_color)) + { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Could not parse strikethrough_color color specification " + "'%s' on line %d"), + strikethrough_color, line_number); + goto error; + } + + add_attribute (tag, pango_attr_strikethrough_color_new (color.red, color.green, color.blue)); + } + if (fallback) { if (strcmp (fallback, "true") == 0) diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c index bc2d462c..2f0ae3a5 100644 --- a/pango/pango-renderer.c +++ b/pango/pango-renderer.c @@ -273,10 +273,10 @@ handle_line_state_change (PangoRenderer *renderer, state->strikethrough) { PangoRectangle *rect = &state->strikethrough_rect; - + rect->width = state->logical_rect_end - rect->x; - draw_underline (renderer, state); - state->underline = renderer->underline; + draw_strikethrough (renderer, state); + state->strikethrough = renderer->strikethrough; rect->x = state->logical_rect_end; rect->width = 0; } @@ -285,102 +285,88 @@ handle_line_state_change (PangoRenderer *renderer, static void add_underline (PangoRenderer *renderer, LineState *state, - PangoFontMetrics *metrics, /* NULL if no underline */ + PangoFontMetrics *metrics, int base_x, int base_y, PangoRectangle *ink_rect, PangoRectangle *logical_rect) { - if (renderer->underline == PANGO_UNDERLINE_NONE) + PangoRectangle *current_rect = &state->underline_rect; + PangoRectangle new_rect; + + int underline_thickness = pango_font_metrics_get_underline_thickness (metrics); + int underline_position = pango_font_metrics_get_underline_position (metrics); + + new_rect.x = base_x + ink_rect->x; + new_rect.width = ink_rect->width; + new_rect.height = underline_thickness; + + switch (renderer->underline) { - draw_underline (renderer, state); + case PANGO_UNDERLINE_NONE: + g_assert_not_reached (); + break; + case PANGO_UNDERLINE_SINGLE: + case PANGO_UNDERLINE_DOUBLE: + case PANGO_UNDERLINE_ERROR: + new_rect.y = base_y - underline_position; + break; + case PANGO_UNDERLINE_LOW: + new_rect.y = base_y + ink_rect->y + ink_rect->height + underline_thickness; + break; + } + + if (renderer->underline == state->underline && + new_rect.y == current_rect->y && + new_rect.height == current_rect->height) + { + current_rect->y = new_rect.y; + current_rect->width = new_rect.x + new_rect.width - current_rect->x; + current_rect->height = new_rect.height; } else { - PangoRectangle *current_rect = &state->underline_rect; - PangoRectangle new_rect; - - int underline_thickness = pango_font_metrics_get_underline_thickness (metrics); - int underline_position = pango_font_metrics_get_underline_position (metrics); - - new_rect.x = base_x + ink_rect->x; - new_rect.width = ink_rect->width; - new_rect.height = underline_thickness; + draw_underline (renderer, state); - switch (renderer->underline) - { - case PANGO_UNDERLINE_NONE: - g_assert_not_reached (); - break; - case PANGO_UNDERLINE_SINGLE: - case PANGO_UNDERLINE_DOUBLE: - case PANGO_UNDERLINE_ERROR: - new_rect.y = base_y - underline_position; - break; - case PANGO_UNDERLINE_LOW: - new_rect.y = base_y + ink_rect->y + ink_rect->height + underline_thickness; - break; - } - - if (renderer->underline == state->underline && - new_rect.y == current_rect->y && - new_rect.height == current_rect->height) - { - current_rect->y = new_rect.y; - current_rect->width = new_rect.x + new_rect.width - current_rect->x; - current_rect->height = new_rect.height; - } - else - { - draw_underline (renderer, state); - - *current_rect = new_rect; - state->underline = renderer->underline; - } + *current_rect = new_rect; + state->underline = renderer->underline; } } static void add_strikethrough (PangoRenderer *renderer, LineState *state, - PangoFontMetrics *metrics, /* NULL if no strikethrough */ + PangoFontMetrics *metrics, int base_x, int base_y, PangoRectangle *ink_rect, PangoRectangle *logical_rect) { - if (!renderer->strikethrough) + PangoRectangle *current_rect = &state->strikethrough_rect; + PangoRectangle new_rect; + + int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics); + int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics); + + new_rect.x = base_x + ink_rect->x; + new_rect.width = ink_rect->width; + new_rect.y = base_y - strikethrough_position; + new_rect.height = strikethrough_thickness; + + if (state->strikethrough && + new_rect.y == current_rect->y && + new_rect.height == current_rect->height) { - draw_strikethrough (renderer, state); + current_rect->y = new_rect.y; + current_rect->width = new_rect.x + new_rect.width - current_rect->x; + current_rect->height = new_rect.height; } else { - PangoRectangle *current_rect = &state->strikethrough_rect; - PangoRectangle new_rect; - - int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics); - int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics); - - new_rect.x = base_x + ink_rect->x; - new_rect.width = ink_rect->width; - new_rect.y = base_y - strikethrough_position; - new_rect.height = strikethrough_thickness; + draw_strikethrough (renderer, state); - if (state->strikethrough && - new_rect.y == current_rect->y && - new_rect.height == current_rect->height) - { - current_rect->y = new_rect.y; - current_rect->width = new_rect.x + new_rect.width - current_rect->x; - current_rect->height = new_rect.height; - } - else - { - draw_strikethrough (renderer, state); - - *current_rect = new_rect; - state->strikethrough = TRUE; - } + *current_rect = new_rect; + state->strikethrough = TRUE; } } @@ -563,6 +549,13 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer, pango_font_metrics_unref (metrics); } + if (renderer->underline == PANGO_UNDERLINE_NONE && + state.underline != PANGO_UNDERLINE_NONE) + draw_underline (renderer, &state); + + if (!renderer->strikethrough && state.strikethrough) + draw_strikethrough (renderer, &state); + x_off += logical_rect.width; } @@ -837,11 +830,11 @@ pango_renderer_draw_error_underline (PangoRenderer *renderer, #define HEIGHT_SQUARES 2.5 static void -get_total_matrix (PangoMatrix *total, - PangoMatrix *global, - int x, - int y, - int square) +get_total_matrix (PangoMatrix *total, + const PangoMatrix *global, + int x, + int y, + int square) { PangoMatrix local; gdouble scale = 0.5 * square; @@ -1148,6 +1141,8 @@ pango_renderer_default_prepare_run (PangoRenderer *renderer, { PangoColor *fg_color = NULL; PangoColor *bg_color = NULL; + PangoColor *underline_color = NULL; + PangoColor *strikethrough_color = NULL; GSList *l; renderer->underline = PANGO_UNDERLINE_NONE; @@ -1175,15 +1170,29 @@ pango_renderer_default_prepare_run (PangoRenderer *renderer, bg_color = &((PangoAttrColor *)attr)->color; break; + case PANGO_ATTR_UNDERLINE_COLOR: + underline_color = &((PangoAttrColor *)attr)->color; + break; + + case PANGO_ATTR_STRIKETHROUGH_COLOR: + strikethrough_color = &((PangoAttrColor *)attr)->color; + break; + default: break; } } + if (!underline_color) + underline_color = fg_color; + + if (!strikethrough_color) + strikethrough_color = fg_color; + pango_renderer_set_color (renderer, PANGO_RENDER_PART_FOREGROUND, fg_color); pango_renderer_set_color (renderer, PANGO_RENDER_PART_UNDERLINE, fg_color); - pango_renderer_set_color (renderer, PANGO_RENDER_PART_STRIKETHROUGH, fg_color); - pango_renderer_set_color (renderer, PANGO_RENDER_PART_BACKGROUND, bg_color); + pango_renderer_set_color (renderer, PANGO_RENDER_PART_UNDERLINE, underline_color); + pango_renderer_set_color (renderer, PANGO_RENDER_PART_STRIKETHROUGH, strikethrough_color); } /** |