summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2022-02-07 01:17:08 -0500
committerMatthias Clasen <mclasen@redhat.com>2022-02-13 14:28:05 -0600
commit3bd01215723f0c0de9339418c5de762d476b79a4 (patch)
tree0017826061facc0835845b94775723c87bad2cdd
parent3f20d1b8ea1730f0ca6ffeb66b1fc462965a877b (diff)
downloadpango-3bd01215723f0c0de9339418c5de762d476b79a4.tar.gz
Make strikethrough styled
Support single and double styles for strikethrough.
-rw-r--r--pango/pango-attr-list.c3
-rw-r--r--pango/pango-attributes.c6
-rw-r--r--pango/pango-attributes.h7
-rw-r--r--pango/pango-layout.c14
-rw-r--r--pango/pango-markup.c26
-rw-r--r--pango/pango-renderer.c66
-rw-r--r--pango/pango-renderer.h2
-rw-r--r--pango/serializer.c3
8 files changed, 85 insertions, 42 deletions
diff --git a/pango/pango-attr-list.c b/pango/pango-attr-list.c
index 8f31971a..505963f2 100644
--- a/pango/pango-attr-list.c
+++ b/pango/pango-attr-list.c
@@ -766,6 +766,7 @@ get_attr_value_type (PangoAttrType type)
case PANGO_ATTR_GRAVITY: return PANGO_TYPE_GRAVITY;
case PANGO_ATTR_GRAVITY_HINT: return PANGO_TYPE_GRAVITY_HINT;
case PANGO_ATTR_UNDERLINE: return PANGO_TYPE_LINE_STYLE;
+ case PANGO_ATTR_STRIKETHROUGH: return PANGO_TYPE_LINE_STYLE;
case PANGO_ATTR_OVERLINE: return PANGO_TYPE_OVERLINE;
case PANGO_ATTR_BASELINE_SHIFT: return PANGO_TYPE_BASELINE_SHIFT;
case PANGO_ATTR_FONT_SCALE: return PANGO_TYPE_FONT_SCALE;
@@ -1143,7 +1144,7 @@ pango_attr_list_from_string (const char *text)
break;
case PANGO_ATTR_STRIKETHROUGH:
- BOOLEAN_ATTR(strikethrough, gboolean);
+ ENUM_ATTR(strikethrough, PangoLineStyle, PANGO_LINE_STYLE_NONE, PANGO_LINE_STYLE_DOTTED);
break;
case PANGO_ATTR_RISE:
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 7fcf47e0..1e305229 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -367,7 +367,7 @@ pango_attr_underline_position_new (PangoUnderlinePosition position)
}
/**
* pango_attr_strikethrough_new:
- * @strikethrough: %TRUE if the text should be struck-through
+ * @style: the line style
*
* Create a new strike-through attribute.
*
@@ -376,9 +376,9 @@ pango_attr_underline_position_new (PangoUnderlinePosition position)
* [method@Pango.Attribute.destroy]
*/
PangoAttribute *
-pango_attr_strikethrough_new (gboolean strikethrough)
+pango_attr_strikethrough_new (PangoLineStyle style)
{
- return pango_attr_boolean_new (PANGO_ATTR_STRIKETHROUGH, (int)strikethrough);
+ return pango_attr_int_new (PANGO_ATTR_STRIKETHROUGH, (int)style);
}
/**
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index bf309c08..b9b82632 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -42,7 +42,8 @@ G_BEGIN_DECLS
* @PANGO_ATTR_FONT_DESC: font description
* @PANGO_ATTR_FOREGROUND: foreground color
* @PANGO_ATTR_BACKGROUND: background color
- * @PANGO_ATTR_UNDERLINE: whether the text has an underline
+ * @PANGO_ATTR_UNDERLINE: underline style
+ * @PANGO_ATTR_UNDERLINE_POSITION: underline position
* @PANGO_ATTR_STRIKETHROUGH: whether the text is struck-through
* @PANGO_ATTR_RISE: baseline displacement
* @PANGO_ATTR_SCALE: font size scale factor
@@ -89,7 +90,7 @@ typedef enum
PANGO_ATTR_BACKGROUND = PANGO_ATTR_TYPE (COLOR, RENDERING, OVERRIDES),
PANGO_ATTR_UNDERLINE = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
PANGO_ATTR_UNDERLINE_POSITION = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
- PANGO_ATTR_STRIKETHROUGH = PANGO_ATTR_TYPE (BOOLEAN, RENDERING, OVERRIDES),
+ PANGO_ATTR_STRIKETHROUGH = PANGO_ATTR_TYPE (INT, RENDERING, OVERRIDES),
PANGO_ATTR_RISE = PANGO_ATTR_TYPE (INT, ITEMIZATION, OVERRIDES),
PANGO_ATTR_SCALE = PANGO_ATTR_TYPE (FLOAT, ITEMIZATION, OVERRIDES),
PANGO_ATTR_FALLBACK = PANGO_ATTR_TYPE (BOOLEAN, ITEMIZATION, OVERRIDES),
@@ -174,7 +175,7 @@ PANGO_AVAILABLE_IN_1_52
PangoAttribute * pango_attr_underline_position_new (PangoUnderlinePosition position);
PANGO_AVAILABLE_IN_ALL
-PangoAttribute * pango_attr_strikethrough_new (gboolean strikethrough);
+PangoAttribute * pango_attr_strikethrough_new (PangoLineStyle style);
PANGO_AVAILABLE_IN_1_8
PangoAttribute * pango_attr_strikethrough_color_new (PangoColor *color);
PANGO_AVAILABLE_IN_ALL
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 848afab9..cd9d2174 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -108,7 +108,7 @@ struct _ItemProperties
{
PangoLineStyle uline_style;
PangoUnderlinePosition uline_position;
- guint strikethrough : 1;
+ PangoLineStyle strikethrough_style;
guint oline_single : 1;
guint showing_space : 1;
gint letter_spacing;
@@ -5551,6 +5551,7 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
ItemProperties properties;
PangoFontMetrics *metrics = NULL;
gboolean has_underline;
+ gboolean has_strikethrough;
gboolean has_overline;
int y_offset;
@@ -5561,11 +5562,12 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
has_underline = properties.uline_style != PANGO_LINE_STYLE_NONE;
has_overline = properties.oline_single;
+ has_strikethrough = properties.strikethrough_style != PANGO_LINE_STYLE_NONE;
if (!run_logical && (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE))
run_logical = &logical;
- if (!run_logical && (has_underline || has_overline || properties.strikethrough))
+ if (!run_logical && (has_underline || has_overline || has_strikethrough))
run_logical = &logical;
if (!run_logical && line_logical)
@@ -5574,7 +5576,7 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
run_ink, run_logical);
- if (run_ink && (has_underline || has_overline || properties.strikethrough))
+ if (run_ink && (has_underline || has_overline || has_strikethrough))
{
int underline_thickness;
int underline_position;
@@ -5602,7 +5604,7 @@ pango_layout_run_get_extents_and_height (PangoLayoutRun *run,
* If run_ink->height == 0, we should adjust run_ink->y appropriately.
*/
- if (properties.strikethrough)
+ if (has_strikethrough)
{
if (run_ink->height == 0)
{
@@ -6728,8 +6730,8 @@ pango_layout_get_item_properties (PangoItem *item,
properties->uline_style = PANGO_LINE_STYLE_NONE;
properties->uline_position = PANGO_UNDERLINE_POSITION_NORMAL;
+ properties->strikethrough_style = PANGO_LINE_STYLE_NONE;
properties->oline_single = FALSE;
- properties->strikethrough = FALSE;
properties->showing_space = FALSE;
properties->letter_spacing = 0;
properties->line_height = 0.0;
@@ -6762,7 +6764,7 @@ pango_layout_get_item_properties (PangoItem *item,
break;
case PANGO_ATTR_STRIKETHROUGH:
- properties->strikethrough = attr->int_value;
+ properties->strikethrough_style = attr->int_value;
break;
case PANGO_ATTR_LETTER_SPACING:
diff --git a/pango/pango-markup.c b/pango/pango-markup.c
index 3802fa5e..b2da8e49 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -1218,6 +1218,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
const char *foreground = NULL;
const char *background = NULL;
const char *underline = NULL;
+ const char *underline_position = NULL;
const char *underline_color = NULL;
const char *overline = NULL;
const char *overline_color = NULL;
@@ -1332,6 +1333,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
break;
case 'u':
CHECK_ATTRIBUTE (underline);
+ CHECK_ATTRIBUTE (underline_position);
CHECK_ATTRIBUTE (underline_color);
break;
case 'r':
@@ -1546,12 +1548,22 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
if (G_UNLIKELY (underline))
{
- PangoLineStyle ul = PANGO_LINE_STYLE_NONE;
+ PangoLineStyle style = PANGO_LINE_STYLE_NONE;
- if (!span_parse_enum ("underline", underline, PANGO_TYPE_LINE_STYLE, (int*)(void*)&ul, line_number, error))
+ if (!span_parse_enum ("underline", underline, PANGO_TYPE_LINE_STYLE, (int*)(void*)&style, line_number, error))
goto error;
- add_attribute (tag, pango_attr_underline_new (ul));
+ add_attribute (tag, pango_attr_underline_new (style));
+ }
+
+ if (G_UNLIKELY (underline_position))
+ {
+ PangoUnderlinePosition pos = PANGO_UNDERLINE_POSITION_NORMAL;
+
+ if (!span_parse_enum ("underline_position", underline_position, PANGO_TYPE_UNDERLINE_POSITION, (int*)(void*)&pos, line_number, error))
+ goto error;
+
+ add_attribute (tag, pango_attr_underline_position_new (pos));
}
if (G_UNLIKELY (underline_color))
@@ -1619,12 +1631,12 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
if (G_UNLIKELY (strikethrough))
{
- gboolean b = FALSE;
+ PangoLineStyle style = PANGO_LINE_STYLE_NONE;
- if (!span_parse_boolean ("strikethrough", strikethrough, &b, line_number, error))
- goto error;
+ if (!span_parse_enum ("strikethrough", strikethrough, PANGO_TYPE_LINE_STYLE, (int*)(void*)&style, line_number, error))
+ goto error;
- add_attribute (tag, pango_attr_strikethrough_new (b));
+ add_attribute (tag, pango_attr_strikethrough_new (style));
}
if (G_UNLIKELY (strikethrough_color))
diff --git a/pango/pango-renderer.c b/pango/pango-renderer.c
index a246bb73..9fb10a42 100644
--- a/pango/pango-renderer.c
+++ b/pango/pango-renderer.c
@@ -45,7 +45,7 @@ struct _LineState
PangoUnderlinePosition underline_position;
PangoRectangle underline_rect;
- gboolean strikethrough;
+ PangoLineStyle strikethrough;
PangoRectangle strikethrough_rect;
int strikethrough_glyphs;
@@ -284,17 +284,40 @@ draw_strikethrough (PangoRenderer *renderer,
LineState *state)
{
PangoRectangle *rect = &state->strikethrough_rect;
- int num_glyphs = state->strikethrough_glyphs;
- if (state->strikethrough && num_glyphs > 0)
- pango_renderer_draw_rectangle (renderer,
- PANGO_RENDER_PART_STRIKETHROUGH,
- rect->x,
- rect->y / num_glyphs,
- rect->width,
- rect->height / num_glyphs);
+ if (state->strikethrough_glyphs > 0)
+ {
+ rect->y /= state->strikethrough_glyphs;
+ rect->height /= state->strikethrough_glyphs;
+
+ switch (state->strikethrough)
+ {
+ case PANGO_LINE_STYLE_NONE:
+ break;
+ case PANGO_LINE_STYLE_DOUBLE:
+ pango_renderer_draw_rectangle (renderer,
+ PANGO_RENDER_PART_STRIKETHROUGH,
+ rect->x,
+ rect->y - rect->height,
+ rect->width,
+ rect->height);
+ rect->y += rect->height;
+ G_GNUC_FALLTHROUGH;
+ case PANGO_LINE_STYLE_SINGLE:
+ case PANGO_LINE_STYLE_DOTTED:
+ pango_renderer_draw_rectangle (renderer,
+ PANGO_RENDER_PART_STRIKETHROUGH,
+ rect->x,
+ rect->y,
+ rect->width,
+ rect->height);
+ break;
+ default:
+ break;
+ }
+ }
- state->strikethrough = FALSE;
+ state->strikethrough = PANGO_LINE_STYLE_NONE;
state->strikethrough_glyphs = 0;
rect->x += rect->width;
rect->width = 0;
@@ -336,7 +359,7 @@ handle_line_state_change (PangoRenderer *renderer,
}
if (part == PANGO_RENDER_PART_STRIKETHROUGH &&
- state->strikethrough)
+ state->strikethrough != PANGO_LINE_STYLE_NONE)
{
PangoRectangle *rect = &state->strikethrough_rect;
@@ -372,7 +395,7 @@ add_underline (PangoRenderer *renderer,
g_assert_not_reached ();
break;
case PANGO_LINE_STYLE_SINGLE:
- if (state->underline_position == PANGO_UNDERLINE_POSITION_UNDER)
+ if (renderer->underline_position == PANGO_UNDERLINE_POSITION_UNDER)
{
new_rect.y += ink_rect->y + ink_rect->height + underline_thickness;
break;
@@ -484,7 +507,7 @@ add_strikethrough (PangoRenderer *renderer,
new_rect.y = (base_y - strikethrough_position) * num_glyphs;
new_rect.height = strikethrough_thickness * num_glyphs;
- if (state->strikethrough)
+ if (state->strikethrough == renderer->strikethrough)
{
current_rect->width = new_rect.x + new_rect.width - current_rect->x;
current_rect->y += new_rect.y;
@@ -493,8 +516,10 @@ add_strikethrough (PangoRenderer *renderer,
}
else
{
+ draw_strikethrough (renderer, state);
+
*current_rect = new_rect;
- state->strikethrough = TRUE;
+ state->strikethrough = renderer->strikethrough;
state->strikethrough_glyphs = num_glyphs;
}
}
@@ -550,7 +575,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
state.underline = PANGO_LINE_STYLE_NONE;
state.underline_position = PANGO_UNDERLINE_POSITION_NORMAL;
state.overline = PANGO_OVERLINE_NONE;
- state.strikethrough = FALSE;
+ state.strikethrough = PANGO_LINE_STYLE_NONE;
text = G_LIKELY (line->layout) ? pango_layout_get_text (line->layout) : NULL;
@@ -569,7 +594,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
if (renderer->underline != PANGO_LINE_STYLE_NONE ||
renderer->priv->overline != PANGO_OVERLINE_NONE ||
- renderer->strikethrough)
+ renderer->strikethrough != PANGO_LINE_STYLE_NONE)
{
ink = &ink_rect;
logical = &logical_rect;
@@ -622,7 +647,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
if (renderer->underline != PANGO_LINE_STYLE_NONE ||
renderer->priv->overline != PANGO_OVERLINE_NONE ||
- renderer->strikethrough)
+ renderer->strikethrough != PANGO_LINE_STYLE_NONE)
{
metrics = pango_font_get_metrics (run->item->analysis.font,
run->item->analysis.language);
@@ -637,7 +662,7 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
x + x_off, y - y_off,
ink, logical);
- if (renderer->strikethrough)
+ if (renderer->strikethrough != PANGO_LINE_STYLE_NONE)
add_strikethrough (renderer, &state, metrics,
x + x_off, y - y_off,
ink, logical, run->glyphs->num_glyphs);
@@ -653,7 +678,8 @@ pango_renderer_draw_layout_line (PangoRenderer *renderer,
state.overline != PANGO_OVERLINE_NONE)
draw_overline (renderer, &state);
- if (!renderer->strikethrough && state.strikethrough)
+ if (renderer->strikethrough == PANGO_LINE_STYLE_NONE &&
+ state.strikethrough != PANGO_LINE_STYLE_NONE)
draw_strikethrough (renderer, &state);
x_off += glyph_string_width;
@@ -1406,7 +1432,7 @@ pango_renderer_default_prepare_run (PangoRenderer *renderer,
renderer->underline = PANGO_LINE_STYLE_NONE;
renderer->underline_position = PANGO_UNDERLINE_POSITION_NORMAL;
renderer->priv->overline = PANGO_OVERLINE_NONE;
- renderer->strikethrough = FALSE;
+ renderer->strikethrough = PANGO_LINE_STYLE_NONE;
for (l = run->item->analysis.extra_attrs; l; l = l->next)
{
diff --git a/pango/pango-renderer.h b/pango/pango-renderer.h
index 6be251cd..6848f749 100644
--- a/pango/pango-renderer.h
+++ b/pango/pango-renderer.h
@@ -81,7 +81,7 @@ struct _PangoRenderer
PangoLineStyle underline;
PangoUnderlinePosition underline_position;
- gboolean strikethrough;
+ PangoLineStyle strikethrough;
int active_count;
/*< public >*/
diff --git a/pango/serializer.c b/pango/serializer.c
index 6ff7a3a4..61650b22 100644
--- a/pango/serializer.c
+++ b/pango/serializer.c
@@ -324,6 +324,7 @@ add_attribute (GtkJsonPrinter *printer,
break;
case PANGO_ATTR_UNDERLINE:
+ case PANGO_ATTR_STRIKETHROUGH:
gtk_json_printer_add_string (printer, "value", line_style_names[attr->int_value]);
break;
@@ -1020,7 +1021,7 @@ attr_for_type (GtkJsonParser *parser,
break;
case PANGO_ATTR_STRIKETHROUGH:
- attr = pango_attr_strikethrough_new (gtk_json_parser_get_boolean (parser));
+ attr = pango_attr_strikethrough_new ((PangoLineStyle) parser_select_string (parser, line_style_names));
break;
case PANGO_ATTR_RISE: