summaryrefslogtreecommitdiff
path: root/src/cairo-svg-surface.c
diff options
context:
space:
mode:
authorAnton Danilkin <afdw@yandex.ru>2021-04-13 02:58:43 +0200
committerAnton Danilkin <afdw@yandex.ru>2021-04-13 04:31:07 +0200
commit1c1bceb581941b304a7ed8ff9fd3519884250633 (patch)
tree41c8556d808b8062bf1c89efb9eca34e93db90b1 /src/cairo-svg-surface.c
parent1fe3c5571253a5b6c7808981babff09af8fbb3ed (diff)
downloadcairo-1c1bceb581941b304a7ed8ff9fd3519884250633.tar.gz
Emit bitmap glyph data as images instead of as a bunch of squares, as this results in smaller file size and better quality, allowing the use of shades of gray
Diffstat (limited to 'src/cairo-svg-surface.c')
-rw-r--r--src/cairo-svg-surface.c85
1 files changed, 49 insertions, 36 deletions
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 043943e91..e1ebbc08e 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -269,6 +269,13 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream,
double height,
cairo_svg_version_t version);
+static cairo_status_t
+_cairo_svg_surface_emit_composite_pattern (cairo_output_stream_t *output,
+ cairo_svg_surface_t *surface,
+ cairo_surface_pattern_t *pattern,
+ unsigned int pattern_id,
+ const cairo_matrix_t *parent_matrix);
+
static const cairo_surface_backend_t cairo_svg_surface_backend;
static const cairo_paginated_surface_backend_t cairo_svg_surface_paginated_backend;
@@ -1122,53 +1129,59 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document,
}
static cairo_int_status_t
-_cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
- cairo_scaled_font_t *scaled_font,
- unsigned long glyph_index)
+_cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
+ cairo_scaled_font_t *scaled_font,
+ unsigned long glyph_index)
{
- cairo_scaled_glyph_t *scaled_glyph;
- cairo_image_surface_t *image;
cairo_status_t status;
- uint8_t *row, *byte;
- int rows, cols;
- int x, y, bit;
+ cairo_scaled_glyph_t *scaled_glyph;
status = _cairo_scaled_glyph_lookup (scaled_font,
glyph_index,
- CAIRO_SCALED_GLYPH_INFO_METRICS |
- CAIRO_SCALED_GLYPH_INFO_SURFACE,
+ CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
- if (unlikely (status))
+ if (unlikely (status)) {
return status;
+ }
- image = _cairo_image_surface_coerce_to_format (scaled_glyph->surface,
- CAIRO_FORMAT_A1);
- status = image->base.status;
- if (unlikely (status))
- return status;
+ cairo_surface_t *paginated_surface = _cairo_svg_surface_create_for_document (document,
+ CAIRO_CONTENT_COLOR_ALPHA,
+ 0,
+ 0,
+ FALSE);
+ cairo_svg_surface_t *svg_surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (paginated_surface);
+ if (unlikely (paginated_surface->status)) {
+ return paginated_surface->status;
+ }
+
+ unsigned int mask_id = document->mask_id++;
+
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<mask id=\"mask-%d\">\n",
+ mask_id);
+
+ cairo_pattern_t *pattern = cairo_pattern_create_for_surface (&scaled_glyph->surface->base);
+ _cairo_svg_surface_emit_composite_pattern (document->xml_node_glyphs,
+ svg_surface,
+ (cairo_surface_pattern_t *) pattern,
+ invalid_pattern_id,
+ NULL);
+ cairo_pattern_destroy (pattern);
+
+ _cairo_output_stream_printf (document->xml_node_defs, "</mask>\n");
- _cairo_output_stream_printf (document->xml_node_glyphs, "<g");
+ _cairo_output_stream_printf (document->xml_node_glyphs,
+ "<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" mask=\"url(#mask-%d)\"",
+ scaled_glyph->surface->width, scaled_glyph->surface->height,
+ mask_id);
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, "transform",
- &image->base.device_transform_inverse, NULL);
- _cairo_output_stream_printf (document->xml_node_glyphs, ">\n");
-
- for (y = 0, row = image->data, rows = image->height; rows; row += image->stride, rows--, y++) {
- for (x = 0, byte = row, cols = (image->width + 7) / 8; cols; byte++, cols--) {
- uint8_t output_byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte);
- for (bit = 7; bit >= 0 && x < image->width; bit--, x++) {
- if (output_byte & (1 << bit)) {
- _cairo_output_stream_printf (document->xml_node_glyphs,
- "<rect x=\"%d\" y=\"%d\" width=\"1\" height=\"1\"/>\n",
- x, y);
- }
- }
- }
- }
- _cairo_output_stream_printf (document->xml_node_glyphs, "</g>\n");
+ &scaled_glyph->surface->base.device_transform_inverse, NULL);
+ _cairo_output_stream_printf (document->xml_node_glyphs, "/>\n");
- cairo_surface_destroy (&image->base);
+ status = cairo_surface_status (paginated_surface);
+ cairo_surface_destroy (paginated_surface);
- return CAIRO_STATUS_SUCCESS;
+ return status;
}
static cairo_int_status_t
@@ -3639,7 +3652,7 @@ _cairo_svg_surface_show_glyphs_impl (cairo_output_stream_t *output,
&path,
CAIRO_FILL_RULE_WINDING,
0.0,
- CAIRO_ANTIALIAS_SUBPIXEL);
+ CAIRO_ANTIALIAS_DEFAULT);
_cairo_path_fixed_fini (&path);