/* parse transform and presentation attributes */ void svg_parse_common(fz_context *ctx, svg_document *doc, fz_xml *node, svg_state *state) { fz_stroke_state *stroke = &state->stroke; fz_matrix *transform = &state->transform; char *transform_att = fz_xml_att(node, "transform"); char *font_size_att = fz_xml_att(node, "font-size"); // TODO: all font stuff // TODO: clip, clip-path, clip-rule char *opacity_att = fz_xml_att(node, "opacity"); char *fill_att = fz_xml_att(node, "fill"); char *fill_rule_att = fz_xml_att(node, "fill-rule"); char *fill_opacity_att = fz_xml_att(node, "fill-opacity"); char *stroke_att = fz_xml_att(node, "stroke"); char *stroke_opacity_att = fz_xml_att(node, "stroke-opacity"); char *stroke_width_att = fz_xml_att(node, "stroke-width"); char *stroke_linecap_att = fz_xml_att(node, "stroke-linecap"); char *stroke_linejoin_att = fz_xml_att(node, "stroke-linejoin"); char *stroke_miterlimit_att = fz_xml_att(node, "stroke-miterlimit"); // TODO: stroke-dasharray, stroke-dashoffset // TODO: marker, marker-start, marker-mid, marker-end // TODO: overflow // TODO: mask if (transform_att) { svg_parse_transform(ctx, doc, transform_att, transform); } if (font_size_att) { state->fontsize = svg_parse_length(font_size_att, state->fontsize, state->fontsize); } if (opacity_att) { state->opacity = svg_parse_number(opacity_att, 0, 1, state->opacity); } if (fill_att) { if (!strcmp(fill_att, "none")) { state->fill_is_set = 0; } else { state->fill_is_set = 1; svg_parse_color(ctx, doc, fill_att, state->fill_color); } } if (fill_opacity_att) state->fill_opacity = svg_parse_number(fill_opacity_att, 0, 1, state->fill_opacity); if (fill_rule_att) { if (!strcmp(fill_rule_att, "nonzero")) state->fill_rule = 1; if (!strcmp(fill_rule_att, "evenodd")) state->fill_rule = 0; } if (stroke_att) { if (!strcmp(stroke_att, "none")) { state->stroke_is_set = 0; } else { state->stroke_is_set = 1; svg_parse_color(ctx, doc, stroke_att, state->stroke_color); } } if (stroke_opacity_att) state->stroke_opacity = svg_parse_number(stroke_opacity_att, 0, 1, state->stroke_opacity); if (stroke_width_att) { if (!strcmp(stroke_width_att, "inherit")) ; else stroke->linewidth = svg_parse_length(stroke_width_att, state->viewbox_size, state->fontsize); } else { stroke->linewidth = 1; } if (stroke_linecap_att) { if (!strcmp(stroke_linecap_att, "butt")) stroke->start_cap = FZ_LINECAP_BUTT; if (!strcmp(stroke_linecap_att, "round")) stroke->start_cap = FZ_LINECAP_ROUND; if (!strcmp(stroke_linecap_att, "square")) stroke->start_cap = FZ_LINECAP_SQUARE; } else { stroke->start_cap = FZ_LINECAP_BUTT; } stroke->dash_cap = stroke->start_cap; stroke->end_cap = stroke->start_cap; if (stroke_linejoin_att) { if (!strcmp(stroke_linejoin_att, "miter")) stroke->linejoin = FZ_LINEJOIN_MITER; if (!strcmp(stroke_linejoin_att, "round")) stroke->linejoin = FZ_LINEJOIN_ROUND; if (!strcmp(stroke_linejoin_att, "bevel")) stroke->linejoin = FZ_LINEJOIN_BEVEL; } else { stroke->linejoin = FZ_LINEJOIN_MITER; } if (stroke_miterlimit_att) { if (!strcmp(stroke_miterlimit_att, "inherit")) ; else stroke->miterlimit = svg_parse_length(stroke_miterlimit_att, state->viewbox_size, state->fontsize); } else { stroke->miterlimit = 4.0; } }
static void svg_parse_element(const svg_state_t *s0, htsmsg_t *element, int (*element_parser)(svg_state_t *s, htsmsg_t *element)) { svg_state_t s = *s0; // FT_Outline ol; // FT_UInt points; // FT_UInt contours; int fill_color = 0xffffffff; int stroke_color = 0xffffffff; int stroke_width = 0; htsmsg_t *a = htsmsg_get_map(element, "attrib"); if(a == NULL) return; const char *st = htsmsg_get_str(a, "style"); if(st != NULL) { char *style, *tmp = NULL, *n, *attr; n = style = strdup(st); while((attr = strtok_r(n, ";", &tmp)) != NULL) { char *value = strchr(attr, ':'); if(value != NULL) { *value++ = 0; while(*value < 33 && *value) value++; if(!strcmp(attr, "fill")) { if(!strcmp(value, "none")) fill_color = 0; else { fill_color = (fill_color & 0xff000000) | html_makecolor(value); } } else if(!strcmp(attr, "stroke")) { if(!strcmp(value, "none")) stroke_color = 0; else { stroke_color = (stroke_color & 0xff000000) | html_makecolor(value); } } else if(!strcmp(attr, "stroke-width")) { stroke_width = atoi(value); } } n = NULL; } free(style); } if(s.pm == NULL) return; const char *transform = htsmsg_get_str(a, "transform"); if(transform != NULL) svg_parse_transform(&s, transform); vec_emit_0(s.pm, VC_BEGIN); if(fill_color) { vec_emit_i1(s.pm, VC_SET_FILL_ENABLE, 1); vec_emit_i1(s.pm, VC_SET_FILL_COLOR, fill_color); } if(stroke_width) { vec_emit_i1(s.pm, VC_SET_STROKE_WIDTH, stroke_width); vec_emit_i1(s.pm, VC_SET_STROKE_COLOR, stroke_color); } s.cur[0] = 0; s.cur[1] = 0; if(element_parser(&s, a)) return; cmd_close(&s); vec_emit_0(s.pm, VC_END); }