📄 cairo-svg-surface.c
字号:
if (info->ctm_inverse) cairo_matrix_transform_point (info->ctm_inverse, &x, &y); _cairo_output_stream_printf (info->output, "L %f %f ", x, y); return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_svg_path_curve_to (void *closure, cairo_point_t *b, cairo_point_t *c, cairo_point_t *d){ svg_path_info_t *info = closure; double bx = _cairo_fixed_to_double (b->x); double by = _cairo_fixed_to_double (b->y); double cx = _cairo_fixed_to_double (c->x); double cy = _cairo_fixed_to_double (c->y); double dx = _cairo_fixed_to_double (d->x); double dy = _cairo_fixed_to_double (d->y); if (info->ctm_inverse) { cairo_matrix_transform_point (info->ctm_inverse, &bx, &by); cairo_matrix_transform_point (info->ctm_inverse, &cx, &cy); cairo_matrix_transform_point (info->ctm_inverse, &dx, &dy); } _cairo_output_stream_printf (info->output, "C %f %f %f %f %f %f ", bx, by, cx, cy, dx, dy); return CAIRO_STATUS_SUCCESS;}static cairo_status_t_cairo_svg_path_close_path (void *closure){ svg_path_info_t *info = closure; _cairo_output_stream_printf (info->output, "Z "); return CAIRO_STATUS_SUCCESS;}static cairo_status_temit_path (cairo_output_stream_t *output, cairo_path_fixed_t *path, cairo_matrix_t *ctm_inverse){ cairo_status_t status; svg_path_info_t info; _cairo_output_stream_printf (output, "d=\""); info.output = output; info.ctm_inverse = ctm_inverse; status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_svg_path_move_to, _cairo_svg_path_line_to, _cairo_svg_path_curve_to, _cairo_svg_path_close_path, &info); _cairo_output_stream_printf (output, "\""); return status;}static cairo_int_status_t_cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document, cairo_scaled_font_t *scaled_font, unsigned long glyph_index){ cairo_scaled_glyph_t *scaled_glyph; cairo_int_status_t status; status = _cairo_scaled_glyph_lookup (scaled_font, glyph_index, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_PATH, &scaled_glyph); if (status) return status; _cairo_output_stream_printf (document->xml_node_glyphs, "<path style=\"stroke: none;\" "); status = emit_path (document->xml_node_glyphs, scaled_glyph->path, NULL); _cairo_output_stream_printf (document->xml_node_glyphs, "/>\n"); return status;}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_image_surface_t *image; cairo_scaled_glyph_t *scaled_glyph; cairo_status_t status; unsigned char *row, *byte; int rows, cols, bytes_per_row; int x, y, bit; status = _cairo_scaled_glyph_lookup (scaled_font, glyph_index, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); if (status) return status; image = scaled_glyph->surface; assert (image->format == CAIRO_FORMAT_A1); _cairo_output_stream_printf (document->xml_node_glyphs, "<g"); emit_transform (document->xml_node_glyphs, " transform", ">/n", &image->base.device_transform); bytes_per_row = (image->width + 7) / 8; 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--) { unsigned char 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"); return CAIRO_STATUS_SUCCESS;}static void_cairo_svg_document_emit_glyph (cairo_svg_document_t *document, cairo_scaled_font_t *scaled_font, unsigned long scaled_font_glyph_index, unsigned int font_id, unsigned int subset_glyph_index){ cairo_status_t status; _cairo_output_stream_printf (document->xml_node_glyphs, "<symbol id=\"glyph%d-%d\">\n", font_id, subset_glyph_index); status = _cairo_svg_document_emit_outline_glyph_data (document, scaled_font, scaled_font_glyph_index); if (status == CAIRO_INT_STATUS_UNSUPPORTED) status = _cairo_svg_document_emit_bitmap_glyph_data (document, scaled_font, scaled_font_glyph_index); _cairo_output_stream_printf (document->xml_node_glyphs, "</symbol>\n");}static void_cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset, void *closure){ cairo_svg_document_t *document = closure; int i; for (i = 0; i < font_subset->num_glyphs; i++) { _cairo_svg_document_emit_glyph (document, font_subset->scaled_font, font_subset->glyphs[i], font_subset->font_id, i); }}static void_cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document){ _cairo_scaled_font_subsets_foreach (document->font_subsets, _cairo_svg_document_emit_font_subset, document); _cairo_scaled_font_subsets_destroy (document->font_subsets); document->font_subsets = NULL;}static cairo_bool_t cairo_svg_force_fallbacks = FALSE;/** * _cairo_svg_test_force_fallbacks * * Force the SVG surface backend to use image fallbacks for every * operation. * * <note> * This function is <emphasis>only</emphasis> intended for internal * testing use within the cairo distribution. It is not installed in * any public header file. * </note> **/void_cairo_svg_test_force_fallbacks (void){ cairo_svg_force_fallbacks = TRUE;}static cairo_int_status_t_operation_supported (cairo_svg_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *pattern){ cairo_svg_document_t *document = surface->document; if (cairo_svg_force_fallbacks) return FALSE; if (document->svg_version < CAIRO_SVG_VERSION_1_2) if (op != CAIRO_OPERATOR_OVER) return FALSE; return TRUE;}static cairo_int_status_t_analyze_operation (cairo_svg_surface_t *surface, cairo_operator_t op, const cairo_pattern_t *pattern){ if (_operation_supported (surface, op, pattern)) return CAIRO_STATUS_SUCCESS; else return CAIRO_INT_STATUS_UNSUPPORTED;}static cairo_surface_t *_cairo_svg_surface_create_similar (void *abstract_src, cairo_content_t content, int width, int height){ return _cairo_meta_surface_create (content, width, height);}static cairo_status_t_cairo_svg_surface_finish (void *abstract_surface){ cairo_status_t status; cairo_svg_surface_t *surface = abstract_surface; cairo_svg_document_t *document = surface->document; if (_cairo_paginated_surface_get_target (document->owner) == &surface->base) status = _cairo_svg_document_finish (document); else status = CAIRO_STATUS_SUCCESS; _cairo_output_stream_destroy (surface->xml_node); _cairo_svg_document_destroy (document); return status;}static voidemit_alpha_filter (cairo_svg_document_t *document){ if (document->alpha_filter) return; _cairo_output_stream_printf (document->xml_node_defs, "<filter id=\"alpha\" " "filterUnits=\"objectBoundingBox\" " "x=\"0%%\" y=\"0%%\" " "width=\"100%%\" height=\"100%%\">\n" " <feColorMatrix type=\"matrix\" " "in=\"SourceGraphic\" " "values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0\"/>\n" "</filter>\n"); document->alpha_filter = TRUE;}typedef struct { cairo_output_stream_t *output; unsigned int in_mem; unsigned char src[3]; unsigned char dst[5]; unsigned int trailing;} base64_write_closure_t;static char const *base64_table ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static cairo_status_tbase64_write_func (void *closure, const unsigned char *data, unsigned int length){ base64_write_closure_t *info = (base64_write_closure_t *) closure; unsigned int i; unsigned char *src, *dst; dst = info->dst; src = info->src; if (info->in_mem + length < 3) { for (i = 0; i < length; i++) { src[i + info->in_mem] = *data; data++; } info->in_mem += length; return CAIRO_STATUS_SUCCESS; } while (info->in_mem + length >= 3) { for (i = 0; i < 3 - info->in_mem; i++) { src[i + info->in_mem] = *data; data++; length--; } dst[0] = base64_table[src[0] >> 2]; dst[1] = base64_table[(src[0] & 0x03) << 4 | src[1] >> 4]; dst[2] = base64_table[(src[1] & 0x0f) << 2 | src[2] >> 6]; dst[3] = base64_table[src[2] & 0xfc >> 2]; /* Special case for the last missing bits */ switch (info->trailing) { case 2: dst[2] = '='; case 1: dst[3] = '='; default: break; } _cairo_output_stream_write (info->output, dst, 4); info->in_mem = 0; } for (i = 0; i < length; i++) { src[i] = *data; data++; } info->in_mem = length; return CAIRO_STATUS_SUCCESS;}static cairo_int_status_t_cairo_surface_base64_encode (cairo_surface_t *surface, cairo_output_stream_t *output){ cairo_status_t status; base64_write_closure_t info; unsigned int i; info.output = output; info.in_mem = 0; info.trailing = 0; memset (info.dst, '\x0', 5); _cairo_output_stream_printf (info.output, "data:image/png;base64,"); status = cairo_surface_write_to_png_stream (surface, base64_write_func, (void *) &info); if (status) return status; if (info.in_mem > 0) { for (i = info.in_mem; i < 3; i++) info.src[i] = '\x0'; info.trailing = 3 - info.in_mem; info.in_mem = 3; base64_write_func (&info, NULL, 0); } return CAIRO_STATUS_SUCCESS;}static cairo_status_temit_composite_image_pattern (cairo_output_stream_t *output, cairo_svg_surface_t *svg_surface, cairo_surface_pattern_t *pattern, int pattern_id, const char *extra_attributes){ cairo_image_surface_t *image; cairo_status_t status; cairo_matrix_t p2u; void *image_extra; status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); if (status) return status; p2u = pattern->base.matrix; cairo_matrix_invert (&p2u); if (pattern_id != invalid_pattern_id) { _cairo_output_stream_printf (output, "<pattern id=\"pattern%d\" " "patternUnits=\"userSpaceOnUse\" " "width=\"%d\" height=\"%d\"", pattern_id, image->width, image->height); emit_transform (output, " patternTransform", ">\n", &p2u); } _cairo_output_stream_printf (output, " <image width=\"%d\" height=\"%d\"", image->width, image->height); if (pattern_id == invalid_pattern_id) emit_transform (output, " transform", "", &p2u); if (extra_attributes) _cairo_output_stream_printf (output, " %s", extra_attributes); _cairo_output_stream_printf (output, " xlink:href=\""); status = _cairo_surface_base64_encode (pattern->surface, output); _cairo_output_stream_printf (output, "\"/>\n"); if (pattern_id != invalid_pattern_id) _cairo_output_stream_printf (output, "</pattern>\n"); _cairo_surface_release_source_image (pattern->surface, image, image_extra); return status;}static intemit_meta_surface (cairo_svg_document_t *document, cairo_meta_surface_t *surface){ cairo_output_stream_t *contents; cairo_meta_surface_t *meta; cairo_meta_snapshot_t *snapshot; int num_elements; unsigned int i, id; num_elements = document->meta_snapshots.num_elements; for (i = 0; i < num_elements; i++) { snapshot = _cairo_array_index (&document->meta_snapshots, i); meta = snapshot->meta; if (meta->commands.num_elements == surface->commands.num_elements && _cairo_array_index (&meta->commands, 0) == _cairo_array_index (&surface->commands, 0)) { id = snapshot->id; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -