[cairo] Can cairo generates <text> elements in the svg output ?
Jonathan Marchand
jonathlela at gmail.com
Sun Feb 27 08:42:56 PST 2011
Hi,
I've produced a patch to make cairo use the <text> tag in the SVG
output. It still a very naive patch because I'm new to cairo and I am
not a C expert.
It covers all my needs, and I don't know any bugs. However, it should be
tested thoroughly. Is there a way or a procedure to assure the patch is
usable ?
Jonathan
On Fri, Nov 05, 2010 at 11:18:35AM +0100, Emmanuel Pacaud wrote:
> Hi,
>
> Le vendredi 05 novembre 2010 à 11:03 +0100, Jonathan Marchand a écrit :
> > Currently, cairo generates text in svg by means of path for each glyhs,
> > there is no <text> elements generated. Thus, there is no way to extract
> > the text from an output file. This issue was addressed before[1], but
> > it seems that today cairo still lacks this feature.
> >
> > Is this feature planned ? Are there strong fundamentals motives against
> > it ? Does it present technical difficulties to implement ?
>
> To my knowledge, nobody is working on this feature. I've worked a bit on
> it a couple of years ago, but didn't produce anything usable.
>
> There's no motive against it. It would be nice to have both output
> method available (<text> and <glyph>) though.
>
> It should not be to difficult to implement, as the work for a text
> output was already done for the PDF backend.
>
> Emmanuel.
>
-------------- next part --------------
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index bb5bccf..4d02bc1 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -2130,6 +2130,65 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output,
}
static cairo_int_status_t
+_cairo_svg_surface_emit_font_style (cairo_output_stream_t *output,
+ cairo_svg_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const cairo_scaled_font_t *scaled_font)
+{
+ double font_size;
+ const char *font_family;
+ const char *font_weight;
+ const char *font_slant;
+ cairo_status_t status;
+
+ font_size = scaled_font->font_matrix.xx;
+ _cairo_output_stream_printf (output,
+ "font-size:%f;", font_size);
+
+ font_family = cairo_toy_font_face_get_family(scaled_font->original_font_face);
+ _cairo_output_stream_printf (output,
+ "font-family:%s;", font_family);
+
+ status = _cairo_svg_surface_emit_pattern (surface, source,
+ output, FALSE, NULL);
+ if (unlikely (status))
+ return status;
+ _cairo_svg_surface_emit_operator_for_style (output, surface, op);
+
+ switch (cairo_toy_font_face_get_weight(scaled_font->original_font_face))
+ {
+ case CAIRO_FONT_WEIGHT_BOLD:
+ font_weight = "bold";
+ break;
+ case CAIRO_FONT_WEIGHT_NORMAL:
+ default:
+ font_weight = "normal";
+ break;
+ };
+ _cairo_output_stream_printf (output,
+ "font-weight:%s;", font_weight);
+
+ switch (cairo_toy_font_face_get_slant(scaled_font->original_font_face))
+ {
+ case CAIRO_FONT_SLANT_ITALIC:
+ font_slant = "italic";
+ break;
+ case CAIRO_FONT_SLANT_OBLIQUE:
+ font_slant = "oblique";
+ break;
+ case CAIRO_FONT_SLANT_NORMAL:
+ default:
+ font_slant = "normal";
+ break;
+ }
+ _cairo_output_stream_printf (output,
+ "font-style:%s;", font_slant);
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
_cairo_svg_surface_fill_stroke (void *abstract_surface,
cairo_operator_t fill_op,
const cairo_pattern_t *fill_source,
@@ -2560,6 +2619,81 @@ FALLBACK:
return status;
}
+static cairo_bool_t
+_cairo_svg_surface_has_show_text_glyphs (void *abstract_surface)
+{
+ return TRUE;
+}
+
+static cairo_int_status_t
+_cairo_svg_surface_show_text_glyphs (void *abstract_surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ const char *utf8,
+ int utf8_len,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ const cairo_text_cluster_t *clusters,
+ int num_clusters,
+ cairo_text_cluster_flags_t cluster_flags,
+ cairo_scaled_font_t *scaled_font,
+ cairo_clip_t *clip)
+{
+ cairo_svg_surface_t *surface = abstract_surface;
+ cairo_output_stream_t *output = surface->xml_node;
+ cairo_status_t status;
+ int i;
+ cairo_matrix_t p2u;
+ double x, y;
+
+ if (surface->paginated_mode == CAIRO_PAGINATED_MODE_ANALYZE)
+ return _cairo_svg_surface_analyze_operation (surface, op, source);
+
+ assert (_cairo_svg_surface_operation_supported (surface, op, source));
+
+ if (num_glyphs <= 0)
+ return CAIRO_STATUS_SUCCESS;
+
+ status = _cairo_surface_clipper_set_clip (&surface->clipper, clip);
+ if (unlikely (status))
+ return status;
+
+ _cairo_output_stream_printf (output,
+ "<text");
+
+ p2u = source->matrix;
+ status = cairo_matrix_invert (&p2u);
+ assert (status == CAIRO_STATUS_SUCCESS);
+ _cairo_svg_surface_emit_transform (output, " transform", &p2u, NULL);
+
+ _cairo_output_stream_printf (output,
+ " style=\"");
+
+ _cairo_svg_surface_emit_font_style(output, surface, op, source, scaled_font);
+
+ _cairo_output_stream_printf (output,
+ "\">\n");
+
+ x = glyphs[0].x;
+ y = glyphs[0].y;
+ cairo_matrix_transform_point (&source->matrix, &x, &y);
+ _cairo_output_stream_printf (output,
+ "<tspan x=\"%f\" y=\"%f\">", x, y);
+
+ for (i = 0; i < utf8_len; i++) {
+ _cairo_output_stream_printf (output,
+ "%c", (utf8[i]));
+ }
+
+ _cairo_output_stream_printf (output,
+ "</tspan>\n");
+
+ _cairo_output_stream_printf (output,
+ "</text>\n");
+
+ return _cairo_output_stream_get_status (output);
+}
+
static void
_cairo_svg_surface_get_font_options (void *abstract_surface,
cairo_font_options_t *options)
@@ -2602,7 +2736,11 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
_cairo_svg_surface_show_glyphs,
NULL, /* snapshot */
NULL, /* is_similar */
- _cairo_svg_surface_fill_stroke
+ _cairo_svg_surface_fill_stroke,
+ NULL, /* create_solid_pattern_surface */
+ NULL, /* can_repaint_solid_pattern_surface */
+ _cairo_svg_surface_has_show_text_glyphs,
+ _cairo_svg_surface_show_text_glyphs,
};
static cairo_status_t
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://lists.cairographics.org/archives/cairo/attachments/20110227/4bbb0d3e/attachment-0001.pgp>
More information about the cairo
mailing list