fz_path * xps_parse_path_geometry(xps_document *doc, xps_resource *dict, fz_xml *root, int stroking, int *fill_rule) { fz_xml *node; char *figures_att; char *fill_rule_att; char *transform_att; fz_xml *transform_tag = NULL; fz_xml *figures_tag = NULL; /* only used by resource */ fz_matrix transform; fz_path *path; figures_att = fz_xml_att(root, "Figures"); fill_rule_att = fz_xml_att(root, "FillRule"); transform_att = fz_xml_att(root, "Transform"); for (node = fz_xml_down(root); node; node = fz_xml_next(node)) { if (!strcmp(fz_xml_tag(node), "PathGeometry.Transform")) transform_tag = fz_xml_down(node); } xps_resolve_resource_reference(doc, dict, &transform_att, &transform_tag, NULL); xps_resolve_resource_reference(doc, dict, &figures_att, &figures_tag, NULL); if (fill_rule_att) { if (!strcmp(fill_rule_att, "NonZero")) *fill_rule = 1; if (!strcmp(fill_rule_att, "EvenOdd")) *fill_rule = 0; } transform = fz_identity; if (transform_att) xps_parse_render_transform(doc, transform_att, &transform); if (transform_tag) xps_parse_matrix_transform(doc, transform_tag, &transform); if (figures_att) path = xps_parse_abbreviated_geometry(doc, figures_att, fill_rule); else path = fz_new_path(doc->ctx); if (figures_tag) xps_parse_path_figure(doc->ctx, path, figures_tag, stroking); for (node = fz_xml_down(root); node; node = fz_xml_next(node)) { if (!strcmp(fz_xml_tag(node), "PathFigure")) xps_parse_path_figure(doc->ctx, path, node, stroking); } if (transform_att || transform_tag) fz_transform_path(doc->ctx, path, &transform); return path; }
static font * svg_dev_text_span_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text_span *span, const fz_matrix *ctm) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; int i, font_idx; font *fnt; fz_matrix shift = fz_identity; for (font_idx = 0; font_idx < sdev->num_fonts; font_idx++) { if (sdev->fonts[font_idx].font == span->font) break; } if (font_idx == sdev->num_fonts) { /* New font */ if (font_idx == sdev->max_fonts) { int newmax = sdev->max_fonts * 2; if (newmax == 0) newmax = 4; sdev->fonts = fz_resize_array(ctx, sdev->fonts, newmax, sizeof(*sdev->fonts)); memset(&sdev->fonts[font_idx], 0, (newmax - font_idx) * sizeof(sdev->fonts[0])); sdev->max_fonts = newmax; } sdev->fonts[font_idx].id = sdev->id++; sdev->fonts[font_idx].font = fz_keep_font(ctx, span->font); sdev->num_fonts++; } fnt = &sdev->fonts[font_idx]; for (i=0; i < span->len; i++) { fz_text_item *it = &span->items[i]; int gid = it->gid; if (gid < 0) continue; if (gid >= fnt->max_sentlist) { int j; fnt->sentlist = fz_resize_array(ctx, fnt->sentlist, gid+1, sizeof(fnt->sentlist[0])); for (j = fnt->max_sentlist; j <= gid; j++) { fnt->sentlist[j].x_off = FLT_MIN; fnt->sentlist[j].y_off = FLT_MIN; } fnt->max_sentlist = gid+1; } if (fnt->sentlist[gid].x_off == FLT_MIN) { /* Need to send this one */ fz_rect rect; fz_path *path; path = fz_outline_glyph(ctx, span->font, gid, &fz_identity); if (path) { fz_bound_path(ctx, path, NULL, &fz_identity, &rect); shift.e = -rect.x0; shift.f = -rect.y0; fz_transform_path(ctx, path, &shift); out = start_def(ctx, sdev); fz_printf(ctx, out, "<symbol id=\"font_%x_%x\">", fnt->id, gid); fz_printf(ctx, out, "<path"); svg_dev_path(ctx, sdev, path); fz_printf(ctx, out, "/>\n"); } else { fz_bound_glyph(ctx, span->font, gid, &fz_identity, &rect); shift.e = -rect.x0; shift.f = -rect.y0; out = start_def(ctx, sdev); fz_printf(ctx, out, "<symbol id=\"font_%x_%x\">", fnt->id, gid); fz_run_t3_glyph(ctx, span->font, gid, &shift, dev); } fz_printf(ctx, out, "</symbol>"); out = end_def(ctx, sdev); fnt->sentlist[gid].x_off = rect.x0; fnt->sentlist[gid].y_off = rect.y0; } } return fnt; }