summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-05 20:56:02 -0400
committerMatthias Clasen <mclasen@redhat.com>2019-07-11 11:42:38 -0400
commitf41932c5c5155a1ac3bedebdceb95603de95c919 (patch)
treeb04bd5ae9c0cdd44389a3325bbad431368929e87
parent482c7d75ec0b228dffc4c8522a3b8666cc5aff61 (diff)
downloadpango-markup-percentage.tar.gz
Support size as percentage in markupmarkup-percentage
Test included. Closes https://gitlab.gnome.org/GNOME/pango/issues/23
-rw-r--r--docs/pango_markup.sgml3
-rw-r--r--pango/pango-attributes.c10
-rw-r--r--pango/pango-markup.c76
-rw-r--r--tests/markups/valid-12.expected20
-rw-r--r--tests/markups/valid-12.markup1
5 files changed, 84 insertions, 26 deletions
diff --git a/docs/pango_markup.sgml b/docs/pango_markup.sgml
index c2ba377c..8bbdaad8 100644
--- a/docs/pango_markup.sgml
+++ b/docs/pango_markup.sgml
@@ -79,7 +79,8 @@ A font family name
<listitem><para>
Font size in 1024ths of a point, or one of the absolute sizes
'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',
-'xx-large', or one of the relative sizes 'smaller' or 'larger'.
+'xx-large', or one of the relative sizes 'smaller' or 'larger',
+or a percentage like '150%'.
If you want to specify a absolute size, it's usually easier
to take advantage of the ability to specify a partial
font description using 'font'; you can use
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 85e5a240..af4289ee 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -1901,8 +1901,7 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator,
PangoFontMask mask = 0;
gboolean have_language = FALSE;
- gdouble scale = 0;
- gboolean have_scale = FALSE;
+ double scale = 1.0;
g_return_if_fail (iterator != NULL);
g_return_if_fail (desc != NULL);
@@ -1980,10 +1979,9 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator,
}
break;
case PANGO_ATTR_SCALE:
- if (!have_scale)
+ if (!(mask & PANGO_FONT_MASK_SIZE))
{
- have_scale = TRUE;
- scale = ((PangoAttrFloat *)attr)->value;
+ scale *= ((PangoAttrFloat *)attr)->value;
}
break;
case PANGO_ATTR_LANGUAGE:
@@ -2024,7 +2022,7 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator,
}
}
- if (have_scale)
+ if (scale != 1.0)
{
if (pango_font_description_get_size_is_absolute (desc))
pango_font_description_set_absolute_size (desc, scale * pango_font_description_get_size (desc));
diff --git a/pango/pango-markup.c b/pango/pango-markup.c
index 7420fa85..2d24eda3 100644
--- a/pango/pango-markup.c
+++ b/pango/pango-markup.c
@@ -64,15 +64,19 @@ struct _OpenTag
{
GSList *attrs;
gsize start_index;
+ /* Our impact on scale_factor, so we know whether we
+ * need to create an attribute ourselves on close
+ */
+ gboolean has_scale;
/* Current total scale level; reset whenever
* an absolute size is set.
* Each "larger" ups it 1, each "smaller" decrements it 1
*/
gint scale_level;
- /* Our impact on scale_level, so we know whether we
- * need to create an attribute ourselves on close
+ /* Current scale factor; reset whenever
+ * an absolute size is set.
*/
- gint scale_level_delta;
+ gint scale_factor;
/* Base scale factor currently in effect
* or size that this tag
* forces, or parent's scale factor or size.
@@ -203,7 +207,8 @@ open_tag_set_absolute_font_size (OpenTag *ot,
ot->base_font_size = font_size;
ot->has_base_font_size = TRUE;
ot->scale_level = 0;
- ot->scale_level_delta = 0;
+ ot->scale_factor = 1.0;
+ ot->has_scale = FALSE;
}
static void
@@ -213,7 +218,8 @@ open_tag_set_absolute_font_scale (OpenTag *ot,
ot->base_scale_factor = scale;
ot->has_base_font_size = FALSE;
ot->scale_level = 0;
- ot->scale_level_delta = 0;
+ ot->scale_factor = 1.0;
+ ot->has_scale = FALSE;
}
static OpenTag*
@@ -231,7 +237,7 @@ markup_data_open_tag (MarkupData *md)
ot = g_slice_new (OpenTag);
ot->attrs = NULL;
ot->start_index = md->index;
- ot->scale_level_delta = 0;
+ ot->has_scale = FALSE;
if (parent == NULL)
{
@@ -239,6 +245,7 @@ markup_data_open_tag (MarkupData *md)
ot->base_font_size = 0;
ot->has_base_font_size = FALSE;
ot->scale_level = 0;
+ ot->scale_factor = 1.0;
}
else
{
@@ -246,6 +253,7 @@ markup_data_open_tag (MarkupData *md)
ot->base_font_size = parent->base_font_size;
ot->has_base_font_size = parent->has_base_font_size;
ot->scale_level = parent->scale_level;
+ ot->scale_factor = parent->scale_factor;
}
md->tag_stack = g_slist_prepend (md->tag_stack, ot);
@@ -285,7 +293,7 @@ markup_data_close_tag (MarkupData *md)
tmp_list = g_slist_next (tmp_list);
}
- if (ot->scale_level_delta != 0)
+ if (ot->has_scale)
{
/* We affected relative font size; create an appropriate
* attribute and reverse our effects on the current level
@@ -298,7 +306,7 @@ markup_data_close_tag (MarkupData *md)
* as the base size to be scaled from
*/
a = pango_attr_size_new (scale_factor (ot->scale_level,
- 1.0) *
+ ot->scale_factor) *
ot->base_font_size);
}
else
@@ -307,7 +315,8 @@ markup_data_close_tag (MarkupData *md)
* as the base size to be scaled from
*/
a = pango_attr_scale_new (scale_factor (ot->scale_level,
- ot->base_scale_factor));
+ ot->scale_factor *
+ ot->base_scale_factor));
}
a->start_index = ot->start_index;
@@ -870,7 +879,7 @@ big_parse_func (MarkupData *md G_GNUC_UNUSED,
/* Grow text one level */
if (tag)
{
- tag->scale_level_delta += 1;
+ tag->has_scale = TRUE;
tag->scale_level += 1;
}
@@ -1257,27 +1266,56 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
const char *end;
gint n;
- if ((end = size, !_pango_scan_int (&end, &n)) || *end != '\0' || n < 0)
+ end = size;
+
+ if (_pango_scan_int (&end, &n) && n > 0)
+ {
+ if (*end == '\0')
+ {
+ add_attribute (tag, pango_attr_size_new (n));
+ if (tag)
+ open_tag_set_absolute_font_size (tag, n);
+ }
+ else if (*end == '%' && *(end + 1) == '\0')
+ {
+ if (tag)
+ {
+ tag->has_scale = TRUE;
+ tag->base_scale_factor = ((double)n) / 100;
+ }
+ }
+ else
+ {
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Value of 'size' attribute on <span> tag on line %d "
+ "could not be parsed; should be an integer no more than %d,"
+ " a percentage, "
+ " or a string such as 'small', not '%s'"),
+ line_number, INT_MAX, size);
+ goto error;
+ }
+ }
+ else
{
g_set_error (error,
G_MARKUP_ERROR,
G_MARKUP_ERROR_INVALID_CONTENT,
_("Value of 'size' attribute on <span> tag on line %d "
"could not be parsed; should be an integer no more than %d,"
+ " a percentage,"
" or a string such as 'small', not '%s'"),
line_number, INT_MAX, size);
goto error;
}
- add_attribute (tag, pango_attr_size_new (n));
- if (tag)
- open_tag_set_absolute_font_size (tag, n);
}
else if (strcmp (size, "smaller") == 0)
{
if (tag)
{
- tag->scale_level_delta -= 1;
+ tag->has_scale = TRUE;
tag->scale_level -= 1;
}
}
@@ -1285,7 +1323,7 @@ span_parse_func (MarkupData *md G_GNUC_UNUSED,
{
if (tag)
{
- tag->scale_level_delta += 1;
+ tag->has_scale = TRUE;
tag->scale_level += 1;
}
}
@@ -1605,7 +1643,7 @@ sub_parse_func (MarkupData *md G_GNUC_UNUSED,
/* Shrink font, and set a negative rise */
if (tag)
{
- tag->scale_level_delta -= 1;
+ tag->has_scale = TRUE;
tag->scale_level -= 1;
}
@@ -1627,7 +1665,7 @@ sup_parse_func (MarkupData *md G_GNUC_UNUSED,
/* Shrink font, and set a positive rise */
if (tag)
{
- tag->scale_level_delta -= 1;
+ tag->has_scale = TRUE;
tag->scale_level -= 1;
}
@@ -1649,7 +1687,7 @@ small_parse_func (MarkupData *md G_GNUC_UNUSED,
/* Shrink text one level */
if (tag)
{
- tag->scale_level_delta -= 1;
+ tag->has_scale = TRUE;
tag->scale_level -= 1;
}
diff --git a/tests/markups/valid-12.expected b/tests/markups/valid-12.expected
new file mode 100644
index 00000000..83239d1e
--- /dev/null
+++ b/tests/markups/valid-12.expected
@@ -0,0 +1,20 @@
+Blue text is cool!
+
+
+---
+
+range 0 9
+[0 9] scale 2.000000
+[0 9] foreground #00000000ffff
+range 9 13
+range 13 17
+[13 17] style 2
+range 17 2147483647
+
+
+---
+
+[0:9] (null) Normal 0
+[9:13] (null) Normal 0
+[13:17] (null) Italic 0
+[17:2147483647] (null) Italic 0
diff --git a/tests/markups/valid-12.markup b/tests/markups/valid-12.markup
new file mode 100644
index 00000000..9a95ec32
--- /dev/null
+++ b/tests/markups/valid-12.markup
@@ -0,0 +1 @@
+<span foreground="blue" size="200%">Blue text</span> is <span style="italic">cool</span>!