diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2023-02-19 21:10:58 +1030 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2023-04-18 18:27:12 +0930 |
commit | b53b48116e610d61cdf630c24a11b59a18345e16 (patch) | |
tree | 3bc8f3410e795ce81c1408b9d7f3a217033d29ba /test/pdf-tagged-text.c | |
parent | e7ed40a71dac04cb4c608b409b04577d01f08454 (diff) | |
download | cairo-b53b48116e610d61cdf630c24a11b59a18345e16.tar.gz |
Make cairo_tag_begin/end work correctly in groups
Fixes #508
Diffstat (limited to 'test/pdf-tagged-text.c')
-rw-r--r-- | test/pdf-tagged-text.c | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/test/pdf-tagged-text.c b/test/pdf-tagged-text.c index 1a2f62dac..3883d418e 100644 --- a/test/pdf-tagged-text.c +++ b/test/pdf-tagged-text.c @@ -149,7 +149,7 @@ layout_paragraph (cairo_t *cr) *end = ' '; if (text_extents.width + 2*MARGIN > PAGE_WIDTH) { int len = prev_end - begin; - char *s = malloc (len); + char *s = xmalloc (len); memcpy (s, begin, len); s[len-1] = 0; paragraph_text[paragraph_num_lines++] = s; @@ -204,9 +204,9 @@ draw_page_num (cairo_surface_t *surface, cairo_t *cr, const char *prefix, int nu static void draw_contents (cairo_surface_t *surface, cairo_t *cr, const struct section *section) { - char buf[100]; + char *attrib; - sprintf(buf, "dest='%s'", section->heading); + xasprintf (&attrib, "dest='%s'", section->heading); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); switch (section->level) { case 0: @@ -230,25 +230,26 @@ draw_contents (cairo_surface_t *surface, cairo_t *cr, const struct section *sect cairo_set_source_rgb (cr, 0, 0, 1); cairo_tag_begin (cr, "TOCI", NULL); cairo_tag_begin (cr, "Reference", NULL); - cairo_tag_begin (cr, CAIRO_TAG_LINK, buf); + cairo_tag_begin (cr, CAIRO_TAG_LINK, attrib); cairo_show_text (cr, section->heading); cairo_tag_end (cr, CAIRO_TAG_LINK); cairo_tag_end (cr, "Reference"); cairo_tag_end (cr, "TOCI"); cairo_restore (cr); y_pos += HEADING_HEIGHT; + free (attrib); } static void draw_section (cairo_surface_t *surface, cairo_t *cr, const struct section *section) { int flags, i; - char buf[100]; - char buf2[100]; + char *name_attrib; + char *dest_attrib; cairo_tag_begin (cr, "Sect", NULL); - sprintf(buf, "name='%s'", section->heading); - sprintf(buf2, "dest='%s'", section->heading); + xasprintf(&name_attrib, "name='%s'", section->heading); + xasprintf(&dest_attrib, "dest='%s'", section->heading); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); if (section->level == 0) { cairo_show_page (cr); @@ -256,7 +257,7 @@ draw_section (cairo_surface_t *surface, cairo_t *cr, const struct section *secti cairo_set_font_size(cr, HEADING1_SIZE); cairo_move_to (cr, MARGIN, MARGIN); cairo_tag_begin (cr, "H1", NULL); - cairo_tag_begin (cr, CAIRO_TAG_DEST, buf); + cairo_tag_begin (cr, CAIRO_TAG_DEST, name_attrib); cairo_show_text (cr, section->heading); cairo_tag_end (cr, CAIRO_TAG_DEST); cairo_tag_end (cr, "H1"); @@ -265,7 +266,7 @@ draw_section (cairo_surface_t *surface, cairo_t *cr, const struct section *secti outline_parents[0] = cairo_pdf_surface_add_outline (surface, CAIRO_PDF_OUTLINE_ROOT, section->heading, - buf2, + dest_attrib, flags); } else { if (section->level == 1) { @@ -286,7 +287,7 @@ draw_section (cairo_surface_t *surface, cairo_t *cr, const struct section *secti cairo_tag_begin (cr, "H2", NULL); else cairo_tag_begin (cr, "H3", NULL); - cairo_tag_begin (cr, CAIRO_TAG_DEST, buf); + cairo_tag_begin (cr, CAIRO_TAG_DEST, name_attrib); cairo_show_text (cr, section->heading); cairo_tag_end (cr, CAIRO_TAG_DEST); if (section->level == 1) @@ -297,7 +298,7 @@ draw_section (cairo_surface_t *surface, cairo_t *cr, const struct section *secti outline_parents[section->level] = cairo_pdf_surface_add_outline (surface, outline_parents[section->level - 1], section->heading, - buf2, + dest_attrib, flags); } @@ -310,13 +311,15 @@ draw_section (cairo_surface_t *surface, cairo_t *cr, const struct section *secti draw_paragraph (cr); } cairo_tag_end (cr, "Sect"); + free (name_attrib); + free (dest_attrib); } static void draw_cover (cairo_surface_t *surface, cairo_t *cr) { cairo_text_extents_t text_extents; - char buf[200]; + char *attrib; cairo_rectangle_t url_box; const char *cairo_url = "https://www.cairographics.org/"; const double url_box_margin = 20.0; @@ -344,10 +347,11 @@ draw_cover (cairo_surface_t *surface, cairo_t *cr) url_box.height = -text_extents.height + 2*url_box_margin; cairo_rectangle(cr, url_box.x, url_box.y, url_box.width, url_box.height); cairo_stroke(cr); - snprintf(buf, sizeof(buf), "rect=[%f %f %f %f] uri=\'%s\'", + xasprintf(&attrib, "rect=[%f %f %f %f] uri=\'%s\'", url_box.x, url_box.y, url_box.width, url_box.height, cairo_url); - cairo_tag_begin (cr, CAIRO_TAG_LINK, buf); + cairo_tag_begin (cr, CAIRO_TAG_LINK, attrib); cairo_tag_end (cr, CAIRO_TAG_LINK); + free (attrib); /* Create link to not yet emmited page number */ cairo_tag_begin (cr, CAIRO_TAG_LINK, "page=5"); @@ -419,6 +423,32 @@ create_document (cairo_surface_t *surface, cairo_t *cr) cairo_tag_begin (cr, CAIRO_TAG_LINK, "uri='http://127.0.0.1/' rect=[10.0 -10.0 100.0 100.0]"); cairo_tag_end (cr, CAIRO_TAG_LINK); + + /* Distilled from Mozilla bug https://bugzilla.mozilla.org/show_bug.cgi?id=1725743: + * attempting to emit a Destination tag within a pushed group will lead to an + * assertion in _cairo_pdf_interchange_end_structure_tag when processing a + * following LINK tag that is outside the pushed group. + */ + + /* PushLayer */ + cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA); + + /* Destination */ + cairo_tag_begin (cr, CAIRO_TAG_DEST, "name='a' x=42 y=42"); + cairo_tag_end (cr, CAIRO_TAG_DEST); + + /* PopLayer */ + cairo_pop_group_to_source (cr); + cairo_paint_with_alpha (cr, 1); + cairo_set_source_rgb (cr, 0, 0, 0); + + /* Link */ + cairo_tag_begin (cr, CAIRO_TAG_LINK, "rect=[100 200 300 400] uri='http://127.0.0.1/'"); + cairo_tag_end (cr, CAIRO_TAG_LINK); + + /* End of extra Mozilla testcase. */ + + cairo_show_page (cr); page_num = 0; @@ -449,6 +479,8 @@ create_document (cairo_surface_t *surface, cairo_t *cr) cairo_show_page (cr); + cairo_set_source_rgb (cr, 0, 0, 1); + cairo_tag_begin (cr, CAIRO_TAG_LINK, "dest='cover'"); cairo_move_to (cr, PAGE_WIDTH/3, 2*PAGE_HEIGHT/5); cairo_show_text (cr, "link to cover"); |