void xps_detach_and_free_remainder(xps_context_t *ctx, xps_item_t *root, xps_item_t *item) { if (item->up) item->up->down = NULL; xps_free_item(ctx, item->next); item->next = NULL; xps_free_item(ctx, root); }
void xps_free_item(xps_context_t *ctx, xps_item_t *item) { xps_item_t *next; while (item) { next = item->next; if (item->down) xps_free_item(ctx, item->down); xps_free(ctx, item); item = next; } }
xps_item_t * xps_parse_xml(xps_context_t *ctx, byte *buf, int len) { xps_parser_t parser; XML_Parser xp; int code; parser.ctx = ctx; parser.root = NULL; parser.head = NULL; parser.error = NULL; parser.compat = 0; xp = XML_ParserCreateNS(NULL, ' '); if (!xp) { gs_throw(-1, "xml error: could not create expat parser"); return NULL; } XML_SetUserData(xp, &parser); XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER); XML_SetStartElementHandler(xp, (XML_StartElementHandler)on_open_tag); XML_SetEndElementHandler(xp, (XML_EndElementHandler)on_close_tag); XML_SetCharacterDataHandler(xp, (XML_CharacterDataHandler)on_text); code = XML_Parse(xp, (char*)buf, len, 1); if (code == 0) { if (parser.root) xps_free_item(ctx, parser.root); XML_ParserFree(xp); gs_throw1(-1, "xml error: %s", XML_ErrorString(XML_GetErrorCode(xp))); return NULL; } XML_ParserFree(xp); if (parser.compat) xps_process_compatibility(ctx, parser.root); return parser.root; }
int xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part) { xps_item_t *root, *node; xps_resource_t *dict; char *width_att; char *height_att; char base_uri[1024]; char *s; int code; if_debug1m('|', ctx->memory, "doc: parsing page %s\n", part->name); xps_strlcpy(base_uri, part->name, sizeof base_uri); s = strrchr(base_uri, '/'); if (s) s[1] = 0; root = xps_parse_xml(ctx, part->data, part->size); if (!root) return gs_rethrow(-1, "cannot parse xml"); if (strcmp(xps_tag(root), "FixedPage")) return gs_throw1(-1, "expected FixedPage element (found %s)", xps_tag(root)); width_att = xps_att(root, "Width"); height_att = xps_att(root, "Height"); if (!width_att) return gs_throw(-1, "FixedPage missing required attribute: Width"); if (!height_att) return gs_throw(-1, "FixedPage missing required attribute: Height"); dict = NULL; /* Setup new page */ { gs_memory_t *mem = ctx->memory; gs_state *pgs = ctx->pgs; gx_device *dev = gs_currentdevice(pgs); gs_param_float_array fa; float fv[2]; gs_c_param_list list; gs_c_param_list_write(&list, mem); fv[0] = atoi(width_att) / 96.0 * 72.0; fv[1] = atoi(height_att) / 96.0 * 72.0; fa.persistent = false; fa.data = fv; fa.size = 2; code = param_write_float_array((gs_param_list *)&list, ".MediaSize", &fa); if ( code >= 0 ) { gs_c_param_list_read(&list); code = gs_putdeviceparams(dev, (gs_param_list *)&list); } gs_c_param_list_release(&list); /* nb this is for the demo it is wrong and should be removed */ gs_initgraphics(pgs); /* 96 dpi default - and put the origin at the top of the page */ gs_initmatrix(pgs); code = gs_scale(pgs, 72.0/96.0, -72.0/96.0); if (code < 0) return gs_rethrow(code, "cannot set page transform"); code = gs_translate(pgs, 0.0, -atoi(height_att)); if (code < 0) return gs_rethrow(code, "cannot set page transform"); code = gs_erasepage(pgs); if (code < 0) return gs_rethrow(code, "cannot clear page"); } /* Pre-parse looking for transparency */ ctx->has_transparency = 0; for (node = xps_down(root); node; node = xps_next(node)) { if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node)) if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node))) ctx->has_transparency = 1; if (xps_element_has_transparency(ctx, base_uri, node)) ctx->has_transparency = 1; } /* save the state with the original device before we push */ gs_gsave(ctx->pgs); if (ctx->use_transparency && ctx->has_transparency) { code = gs_push_pdf14trans_device(ctx->pgs, false); if (code < 0) { gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot install transparency device"); } } /* Draw contents */ for (node = xps_down(root); node; node = xps_next(node)) { if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node)) { code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node)); if (code) { gs_pop_pdf14trans_device(ctx->pgs, false); gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot load FixedPage.Resources"); } } code = xps_parse_element(ctx, base_uri, dict, node); if (code) { gs_pop_pdf14trans_device(ctx->pgs, false); gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot parse child of FixedPage"); } } if (ctx->use_transparency && ctx->has_transparency) { code = gs_pop_pdf14trans_device(ctx->pgs, false); if (code < 0) { gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot uninstall transparency device"); } } /* Flush page */ { code = xps_show_page(ctx, 1, true); /* copies, flush */ if (code < 0) { gs_grestore(ctx->pgs); return gs_rethrow(code, "cannot flush page"); } } /* restore the original device, discarding the pdf14 compositor */ gs_grestore(ctx->pgs); if (dict) { xps_free_resource_dictionary(ctx, dict); } xps_free_item(ctx, root); return 0; }