summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--Makethird21
-rw-r--r--apps/pdfapp.c2
-rw-r--r--xps/muxps.h80
-rw-r--r--xps/xpsanalyze.c112
-rw-r--r--xps/xpscommon.c26
-rw-r--r--xps/xpsdoc.c120
-rw-r--r--xps/xpsglyphs.c68
-rw-r--r--xps/xpsgradient.c68
-rw-r--r--xps/xpsimage.c8
-rw-r--r--xps/xpsopacity.c12
-rw-r--r--xps/xpspage.c63
-rw-r--r--xps/xpspath.c166
-rw-r--r--xps/xpsresource.c32
-rw-r--r--xps/xpstile.c36
-rw-r--r--xps/xpsvisual.c18
-rw-r--r--xps/xpsxml.c588
-rw-r--r--xps/xpszip.c8
18 files changed, 717 insertions, 718 deletions
diff --git a/Makefile b/Makefile
index 23ce82d1..11fb41c6 100644
--- a/Makefile
+++ b/Makefile
@@ -31,7 +31,6 @@ endif
# directory exists.
LIBS := -lfreetype -ljbig2dec -lopenjpeg -ljpeg -lz -lm
-XPSLIBS := -lexpat
include Makerules
include Makethird
@@ -388,7 +387,7 @@ XPSDRAW_OBJ=$(XPSDRAW_SRC:xps/%.c=$(OBJDIR)/%.o)
XPSDRAW_EXE=$(OBJDIR)/xpsdraw
$(XPSDRAW_OBJ): $(MUXPS_HDR)
$(XPSDRAW_EXE): $(XPSDRAW_OBJ) $(MUXPS_LIB) $(THIRD_LIBS)
- $(LD_CMD) $(XPSLIBS)
+ $(LD_CMD)
PDFAPP_HDR = apps/pdfapp.h
@@ -398,7 +397,7 @@ X11VIEW_EXE=$(OBJDIR)/mupdf
$(X11VIEW_OBJ): $(MUPDF_HDR) $(PDFAPP_HDR)
$(X11VIEW_EXE): $(X11VIEW_OBJ) $(MUPDF_LIB) $(MUXPS_LIB) $(THIRD_LIBS)
- $(LD_CMD) $(XPSLIBS) $(X11LIBS)
+ $(LD_CMD) $(X11LIBS)
WINVIEW_SRC=apps/win_main.c apps/pdfapp.c
WINVIEW_RES=apps/win_res.rc
@@ -410,7 +409,7 @@ $(OBJDIR)/%.o: apps/%.rc
$(WINVIEW_OBJ): $(MUPDF_HDR) $(PDFAPP_HDR)
$(WINVIEW_EXE): $(WINVIEW_OBJ) $(MUPDF_LIB) $(MUXPS_LIB) $(THIRD_LIBS)
- $(LD_CMD) $(XPSLIBS) $(W32LIBS)
+ $(LD_CMD) $(W32LIBS)
#
# Default rules
diff --git a/Makethird b/Makethird
index bef43aea..d74f1176 100644
--- a/Makethird
+++ b/Makethird
@@ -9,27 +9,6 @@ openjpeg_dir := $(wildcard thirdparty/openjpeg*/libopenjpeg)
freetype_dir := $(wildcard thirdparty/freetype*)
jpeg_dir := $(wildcard thirdparty/jpeg*)
zlib_dir := $(wildcard thirdparty/zlib*)
-expat_dir := $(wildcard thirdparty/expat*/lib)
-
-ifneq "$(expat_dir)" ""
-
-THIRD_LIBS += $(EXPAT_LIB)
-THIRD_INCS += -I$(expat_dir)
-LIBS := $(filter-out -lexpat, $(LIBS))
-XPSLIBS := $(filter-out -lexpat, $(XPSLIBS))
-
-EXPAT_SRC=$(addprefix $(expat_dir)/, \
- xmlparse.c \
- xmlrole.c \
- xmltok.c )
-EXPAT_OBJ=$(EXPAT_SRC:$(expat_dir)/%.c=$(OBJDIR)/%.o)
-EXPAT_LIB=$(OBJDIR)/libexpat.a
-$(EXPAT_LIB): $(EXPAT_OBJ)
- $(AR_CMD)
-$(OBJDIR)/%.o: $(expat_dir)/%.c
- $(CC_CMD) -DHAVE_MEMMOVE
-
-endif
ifneq "$(jbig2dec_dir)" ""
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index aec9ad62..332f3bb5 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -313,7 +313,7 @@ static void pdfapp_loadpage_xps(pdfapp_t *app)
page = xps_load_page(app->xps, app->pageno - 1);
if (!page)
- pdfapp_error(app, fz_throw("cannot load page %d in file '%s'", app->pageno, app->doctitle));
+ pdfapp_error(app, fz_rethrow(-1, "cannot load page %d in file '%s'", app->pageno, app->doctitle));
app->page_bbox = fz_transformrect(fz_scale(page->width, page->height), fz_unitrect);
app->page_rotate = 0;
diff --git a/xps/muxps.h b/xps/muxps.h
index d0478e7b..0455ee68 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -49,6 +49,20 @@ void xps_hash_free(xps_context *ctx, xps_hash_table *table,
void xps_hash_debug(xps_hash_table *table);
/*
+ * XML document model
+ */
+
+typedef struct element xml_element;
+
+xml_element *xml_parse_document(byte *buf, int len);
+xml_element *xml_next(xml_element *item);
+xml_element *xml_down(xml_element *item);
+char *xml_tag(xml_element *item);
+char *xml_att(xml_element *item, const char *att);
+void xml_free_element(xml_element *item);
+void xml_print_element(xml_element *item, int level);
+
+/*
* Container parts.
*/
@@ -84,7 +98,7 @@ struct xps_page_s
char *name;
int width;
int height;
- struct xps_item_s *root;
+ struct element *root;
xps_page *next;
};
@@ -144,20 +158,6 @@ void xps_parse_color(xps_context *ctx, char *base_uri, char *hexstring, fz_color
void xps_set_color(xps_context *ctx, fz_colorspace *colorspace, float *samples);
/*
- * XML document model
- */
-
-typedef struct xps_item_s xps_item;
-
-xps_item * xps_parse_xml(xps_context *ctx, byte *buf, int len);
-xps_item * xps_next(xps_item *item);
-xps_item * xps_down(xps_item *item);
-char * xps_tag(xps_item *item);
-char * xps_att(xps_item *item, const char *att);
-void xps_free_item(xps_context *ctx, xps_item *item);
-void xps_debug_item(xps_item *item, int level);
-
-/*
* Resource dictionaries.
*/
@@ -167,15 +167,15 @@ struct xps_resource_s
{
char *name;
char *base_uri; /* only used in the head nodes */
- xps_item *base_xml; /* only used in the head nodes, to free the xml document */
- xps_item *data;
+ xml_element *base_xml; /* only used in the head nodes, to free the xml document */
+ xml_element *data;
xps_resource *next;
xps_resource *parent; /* up to the previous dict in the stack */
};
-int xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, xps_item *root);
+int xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, xml_element *root);
void xps_free_resource_dictionary(xps_context *ctx, xps_resource *dict);
-void xps_resolve_resource_reference(xps_context *ctx, xps_resource *dict, char **attp, xps_item **tagp, char **urip);
+void xps_resolve_resource_reference(xps_context *ctx, xps_resource *dict, char **attp, xml_element **tagp, char **urip);
void xps_debug_resource_dictionary(xps_resource *dict);
@@ -185,34 +185,34 @@ void xps_debug_resource_dictionary(xps_resource *dict);
int xps_load_fixed_page(xps_context *ctx, xps_page *page);
void xps_parse_fixed_page(xps_context *ctx, fz_matrix ctm, xps_page *page);
-void xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_glyphs(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_solid_color_brush(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_image_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_visual_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_linear_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_radial_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node);
-
-void xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *root, void(*func)(xps_context*, fz_matrix, char*, xps_resource*, xps_item*, void*), void *user);
-
-void xps_parse_matrix_transform(xps_context *ctx, xps_item *root, fz_matrix *matrix);
+void xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_glyphs(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_solid_color_brush(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_image_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_visual_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_linear_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_radial_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+
+void xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *root, void(*func)(xps_context*, fz_matrix, char*, xps_resource*, xml_element*, void*), void *user);
+
+void xps_parse_matrix_transform(xps_context *ctx, xml_element *root, fz_matrix *matrix);
void xps_parse_render_transform(xps_context *ctx, char *text, fz_matrix *matrix);
void xps_parse_rectangle(xps_context *ctx, char *text, fz_rect *rect);
fz_path *xps_parse_abbreviated_geometry(xps_context *ctx, char *geom, int *fill_rule);
-fz_path *xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, int stroking, int *fill_rule);
+fz_path *xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xml_element *root, int stroking, int *fill_rule);
-void xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, char *opacity_att, xps_item *opacity_mask_tag);
-void xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict, char *opacity_att, xps_item *opacity_mask_tag);
+void xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, char *opacity_att, xml_element *opacity_mask_tag);
+void xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict, char *opacity_att, xml_element *opacity_mask_tag);
-void xps_parse_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node);
-void xps_parse_element(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node);
+void xps_parse_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_element(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_clip(xps_context *ctx, fz_matrix ctm, xps_resource *dict, char *clip_att, xps_item *clip_tag);
+void xps_clip(xps_context *ctx, fz_matrix ctm, xps_resource *dict, char *clip_att, xml_element *clip_tag);
-int xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node);
-int xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xps_item *node);
-int xps_image_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root);
+int xps_element_has_transparency(xps_context *ctx, char *base_uri, xml_element *node);
+int xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xml_element *node);
+int xps_image_brush_has_transparency(xps_context *ctx, char *base_uri, xml_element *root);
/*
* The interpreter context.
diff --git a/xps/xpsanalyze.c b/xps/xpsanalyze.c
index 9cd29840..86dd4626 100644
--- a/xps/xpsanalyze.c
+++ b/xps/xpsanalyze.c
@@ -14,16 +14,16 @@ xps_remote_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri
}
int
-xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
char *source;
- xps_item *node;
+ xml_element *node;
- source = xps_att(root, "Source");
+ source = xml_att(root, "Source");
if (source)
return xps_remote_resource_dictionary_has_transparency(ctx, base_uri, source);
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
// TODO: ... all kinds of stuff can be here, brushes, elements, whatnot
}
@@ -32,18 +32,18 @@ xps_resource_dictionary_has_transparency(xps_context *ctx, char *base_uri, xps_i
}
static int
-xps_gradient_stops_have_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_gradient_stops_have_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
fz_colorspace *colorspace;
char *color_att;
float samples[32];
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "GradientStop"))
+ if (!strcmp(xml_tag(node), "GradientStop"))
{
- color_att = xps_att(node, "Color");
+ color_att = xml_att(node, "Color");
if (color_att)
{
xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
@@ -60,12 +60,12 @@ xps_gradient_stops_have_transparency(xps_context *ctx, char *base_uri, xps_item
}
static int
-xps_gradient_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_gradient_brush_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
char *opacity_att;
- opacity_att = xps_att(root, "Opacity");
+ opacity_att = xml_att(root, "Opacity");
if (opacity_att)
{
if (atof(opacity_att) < 1.0)
@@ -75,14 +75,14 @@ xps_gradient_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *
}
}
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "RadialGradientBrush.GradientStops"))
+ if (!strcmp(xml_tag(node), "RadialGradientBrush.GradientStops"))
{
if (xps_gradient_stops_have_transparency(ctx, base_uri, node))
return 1;
}
- if (!strcmp(xps_tag(node), "LinearGradientBrush.GradientStops"))
+ if (!strcmp(xml_tag(node), "LinearGradientBrush.GradientStops"))
{
if (xps_gradient_stops_have_transparency(ctx, base_uri, node))
return 1;
@@ -93,18 +93,18 @@ xps_gradient_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *
}
static int
-xps_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_brush_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
char *opacity_att;
char *color_att;
- xps_item *node;
+ xml_element *node;
fz_colorspace *colorspace;
float samples[32];
- if (!strcmp(xps_tag(root), "SolidColorBrush"))
+ if (!strcmp(xml_tag(root), "SolidColorBrush"))
{
- opacity_att = xps_att(root, "Opacity");
+ opacity_att = xml_att(root, "Opacity");
if (opacity_att)
{
if (atof(opacity_att) < 1.0)
@@ -114,7 +114,7 @@ xps_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
}
- color_att = xps_att(root, "Color");
+ color_att = xml_att(root, "Color");
if (color_att)
{
xps_parse_color(ctx, base_uri, color_att, &colorspace, samples);
@@ -126,9 +126,9 @@ xps_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
}
- if (!strcmp(xps_tag(root), "VisualBrush"))
+ if (!strcmp(xml_tag(root), "VisualBrush"))
{
- char *opacity_att = xps_att(root, "Opacity");
+ char *opacity_att = xml_att(root, "Opacity");
if (opacity_att)
{
if (atof(opacity_att) < 1.0)
@@ -138,29 +138,29 @@ xps_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
}
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "VisualBrush.Visual"))
+ if (!strcmp(xml_tag(node), "VisualBrush.Visual"))
{
- if (xps_element_has_transparency(ctx, base_uri, xps_down(node)))
+ if (xps_element_has_transparency(ctx, base_uri, xml_down(node)))
return 1;
}
}
}
- if (!strcmp(xps_tag(root), "ImageBrush"))
+ if (!strcmp(xml_tag(root), "ImageBrush"))
{
if (xps_image_brush_has_transparency(ctx, base_uri, root))
return 1;
}
- if (!strcmp(xps_tag(root), "LinearGradientBrush"))
+ if (!strcmp(xml_tag(root), "LinearGradientBrush"))
{
if (xps_gradient_brush_has_transparency(ctx, base_uri, root))
return 1;
}
- if (!strcmp(xps_tag(root), "RadialGradientBrush"))
+ if (!strcmp(xml_tag(root), "RadialGradientBrush"))
{
if (xps_gradient_brush_has_transparency(ctx, base_uri, root))
return 1;
@@ -170,27 +170,27 @@ xps_brush_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
static int
-xps_path_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_path_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "Path.OpacityMask"))
+ if (!strcmp(xml_tag(node), "Path.OpacityMask"))
{
//dputs("page has transparency: Path.OpacityMask\n");
return 1;
}
- if (!strcmp(xps_tag(node), "Path.Stroke"))
+ if (!strcmp(xml_tag(node), "Path.Stroke"))
{
- if (xps_brush_has_transparency(ctx, base_uri, xps_down(node)))
+ if (xps_brush_has_transparency(ctx, base_uri, xml_down(node)))
return 1;
}
- if (!strcmp(xps_tag(node), "Path.Fill"))
+ if (!strcmp(xml_tag(node), "Path.Fill"))
{
- if (xps_brush_has_transparency(ctx, base_uri, xps_down(node)))
+ if (xps_brush_has_transparency(ctx, base_uri, xml_down(node)))
return 1;
}
}
@@ -199,21 +199,21 @@ xps_path_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
static int
-xps_glyphs_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_glyphs_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "Glyphs.OpacityMask"))
+ if (!strcmp(xml_tag(node), "Glyphs.OpacityMask"))
{
//dputs("page has transparency: Glyphs.OpacityMask\n");
return 1;
}
- if (!strcmp(xps_tag(node), "Glyphs.Fill"))
+ if (!strcmp(xml_tag(node), "Glyphs.Fill"))
{
- if (xps_brush_has_transparency(ctx, base_uri, xps_down(node)))
+ if (xps_brush_has_transparency(ctx, base_uri, xml_down(node)))
return 1;
}
}
@@ -222,19 +222,19 @@ xps_glyphs_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
static int
-xps_canvas_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
+xps_canvas_has_transparency(xps_context *ctx, char *base_uri, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "Canvas.Resources"))
+ if (!strcmp(xml_tag(node), "Canvas.Resources"))
{
- if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node)))
+ if (xps_resource_dictionary_has_transparency(ctx, base_uri, xml_down(node)))
return 1;
}
- if (!strcmp(xps_tag(node), "Canvas.OpacityMask"))
+ if (!strcmp(xml_tag(node), "Canvas.OpacityMask"))
{
//dputs("page has transparency: Canvas.OpacityMask\n");
return 1;
@@ -248,7 +248,7 @@ xps_canvas_has_transparency(xps_context *ctx, char *base_uri, xps_item *root)
}
int
-xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node)
+xps_element_has_transparency(xps_context *ctx, char *base_uri, xml_element *node)
{
char *opacity_att;
char *stroke_att;
@@ -257,7 +257,7 @@ xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node)
fz_colorspace *colorspace;
float samples[32];
- stroke_att = xps_att(node, "Stroke");
+ stroke_att = xml_att(node, "Stroke");
if (stroke_att)
{
xps_parse_color(ctx, base_uri, stroke_att, &colorspace, samples);
@@ -268,7 +268,7 @@ xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node)
}
}
- fill_att = xps_att(node, "Fill");
+ fill_att = xml_att(node, "Fill");
if (fill_att)
{
xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
@@ -279,7 +279,7 @@ xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node)
}
}
- opacity_att = xps_att(node, "Opacity");
+ opacity_att = xml_att(node, "Opacity");
if (opacity_att)
{
if (atof(opacity_att) < 1.0)
@@ -289,19 +289,19 @@ xps_element_has_transparency(xps_context *ctx, char *base_uri, xps_item *node)
}
}
- if (xps_att(node, "OpacityMask"))
+ if (xml_att(node, "OpacityMask"))
{
//dputs("page has transparency: OpacityMask\n");
return 1;
}
- if (!strcmp(xps_tag(node), "Path"))
+ if (!strcmp(xml_tag(node), "Path"))
if (xps_path_has_transparency(ctx, base_uri, node))
return 1;
- if (!strcmp(xps_tag(node), "Glyphs"))
+ if (!strcmp(xml_tag(node), "Glyphs"))
if (xps_glyphs_has_transparency(ctx, base_uri, node))
return 1;
- if (!strcmp(xps_tag(node), "Canvas"))
+ if (!strcmp(xml_tag(node), "Canvas"))
if (xps_canvas_has_transparency(ctx, base_uri, node))
return 1;
diff --git a/xps/xpscommon.c b/xps/xpscommon.c
index 063435c5..77aec58c 100644
--- a/xps/xpscommon.c
+++ b/xps/xpscommon.c
@@ -2,29 +2,29 @@
#include "muxps.h"
void
-xps_parse_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xps_item *node)
+xps_parse_brush(xps_context *ctx, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node)
{
/* SolidColorBrushes are handled in a special case and will never show up here */
- if (!strcmp(xps_tag(node), "ImageBrush"))
+ if (!strcmp(xml_tag(node), "ImageBrush"))
xps_parse_image_brush(ctx, ctm, area, base_uri, dict, node);
- else if (!strcmp(xps_tag(node), "VisualBrush"))
+ else if (!strcmp(xml_tag(node), "VisualBrush"))
xps_parse_visual_brush(ctx, ctm, area, base_uri, dict, node);
- else if (!strcmp(xps_tag(node), "LinearGradientBrush"))
+ else if (!strcmp(xml_tag(node), "LinearGradientBrush"))
xps_parse_linear_gradient_brush(ctx, ctm, area, base_uri, dict, node);
- else if (!strcmp(xps_tag(node), "RadialGradientBrush"))
+ else if (!strcmp(xml_tag(node), "RadialGradientBrush"))
xps_parse_radial_gradient_brush(ctx, ctm, area, base_uri, dict, node);
else
- fz_warn("unknown brush tag: %s", xps_tag(node));
+ fz_warn("unknown brush tag: %s", xml_tag(node));
}
void
-xps_parse_element(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *node)
+xps_parse_element(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node)
{
- if (!strcmp(xps_tag(node), "Path"))
+ if (!strcmp(xml_tag(node), "Path"))
xps_parse_path(ctx, ctm, base_uri, dict, node);
- if (!strcmp(xps_tag(node), "Glyphs"))
+ if (!strcmp(xml_tag(node), "Glyphs"))
xps_parse_glyphs(ctx, ctm, base_uri, dict, node);
- if (!strcmp(xps_tag(node), "Canvas"))
+ if (!strcmp(xml_tag(node), "Canvas"))
xps_parse_canvas(ctx, ctm, base_uri, dict, node);
/* skip unknown tags (like Foo.Resources and similar) */
}
@@ -55,15 +55,15 @@ xps_parse_render_transform(xps_context *ctx, char *transform, fz_matrix *matrix)
}
void
-xps_parse_matrix_transform(xps_context *ctx, xps_item *root, fz_matrix *matrix)
+xps_parse_matrix_transform(xps_context *ctx, xml_element *root, fz_matrix *matrix)
{
char *transform;
*matrix = fz_identity;
- if (!strcmp(xps_tag(root), "MatrixTransform"))
+ if (!strcmp(xml_tag(root), "MatrixTransform"))
{
- transform = xps_att(root, "Matrix");
+ transform = xml_att(root, "Matrix");
if (transform)
xps_parse_render_transform(ctx, transform, matrix);
}
diff --git a/xps/xpsdoc.c b/xps/xpsdoc.c
index a37ed0e9..94fb32d7 100644
--- a/xps/xpsdoc.c
+++ b/xps/xpsdoc.c
@@ -1,8 +1,6 @@
#include "fitz.h"
#include "muxps.h"
-#include <expat.h>
-
xps_part *
xps_new_part(xps_context *ctx, char *name, int size)
{
@@ -11,7 +9,8 @@ xps_new_part(xps_context *ctx, char *name, int size)
part = fz_malloc(sizeof(xps_part));
part->name = fz_strdup(name);
part->size = size;
- part->data = fz_malloc(size);
+ part->data = fz_malloc(size + 1);
+ part->data[size] = 0; /* null-terminate for xml parser */
return part;
}
@@ -137,87 +136,63 @@ xps_free_fixed_pages(xps_context *ctx)
}
/*
- * Parse the fixed document sequence structure and _rels/.rels to find the
- * start part. We hook up unique expat handlers for this, since we don't need
- * the full document model.
+ * Parse the fixed document sequence structure and _rels/.rels to find the start part.
*/
static void
-xps_parse_metadata_imp(void *zp, char *name, char **atts)
+xps_parse_metadata_imp(xps_context *ctx, xml_element *item)
{
- xps_context *ctx = zp;
- int i;
-
- if (!strcmp(name, "Relationship"))
- {
- char tgtbuf[1024];
- char *target = NULL;
- char *type = NULL;
-
- for (i = 0; atts[i]; i += 2)
- {
- if (!strcmp(atts[i], "Target"))
- target = atts[i + 1];
- if (!strcmp(atts[i], "Type"))
- type = atts[i + 1];
- }
-
- if (target && type)
- {
- xps_absolute_path(tgtbuf, ctx->base_uri, target, sizeof tgtbuf);
- if (!strcmp(type, REL_START_PART))
- ctx->start_part = fz_strdup(tgtbuf);
- }
- }
-
- if (!strcmp(name, "DocumentReference"))
+ while (item)
{
- char *source = NULL;
- char srcbuf[1024];
+ xps_parse_metadata_imp(ctx, xml_down(item));
- for (i = 0; atts[i]; i += 2)
+ if (!strcmp(xml_tag(item), "Relationship"))
{
- if (!strcmp(atts[i], "Source"))
- source = atts[i + 1];
+ char *target = xml_att(item, "Target");
+ char *type = xml_att(item, "Type");
+ if (target && type)
+ {
+ char tgtbuf[1024];
+ xps_absolute_path(tgtbuf, ctx->base_uri, target, sizeof tgtbuf);
+ if (!strcmp(type, REL_START_PART))
+ ctx->start_part = fz_strdup(tgtbuf);
+ }
}
- if (source)
+ if (!strcmp(xml_tag(item), "DocumentReference"))
{
- xps_absolute_path(srcbuf, ctx->base_uri, source, sizeof srcbuf);
- xps_add_fixed_document(ctx, srcbuf);
+ char *source = xml_att(item, "Source");
+ if (source)
+ {
+ char srcbuf[1024];
+ xps_absolute_path(srcbuf, ctx->base_uri, source, sizeof srcbuf);
+ xps_add_fixed_document(ctx, srcbuf);
+ }
}
- }
-
- if (!strcmp(name, "PageContent"))
- {
- char *source = NULL;
- char srcbuf[1024];
- int width = 0;
- int height = 0;
- for (i = 0; atts[i]; i += 2)
+ if (!strcmp(xml_tag(item), "PageContent"))
{
- if (!strcmp(atts[i], "Source"))
- source = atts[i + 1];
- if (!strcmp(atts[i], "Width"))
- width = atoi(atts[i + 1]);
- if (!strcmp(atts[i], "Height"))
- height = atoi(atts[i + 1]);
+ char *source = xml_att(item, "Source");
+ char *width_att = xml_att(item, "Width");
+ char *height_att = xml_att(item, "Height");
+ int width = width_att ? atoi(width_att) : 0;
+ int height = height_att ? atoi(height_att) : 0;
+ if (source)
+ {
+ char srcbuf[1024];
+ xps_absolute_path(srcbuf, ctx->base_uri, source, sizeof srcbuf);
+ xps_add_fixed_page(ctx, srcbuf, width, height);
+ }
}
- if (source)
- {
- xps_absolute_path(srcbuf, ctx->base_uri, source, sizeof srcbuf);
- xps_add_fixed_page(ctx, srcbuf, width, height);
- }
+ item = xml_next(item);
}
}
int
xps_parse_metadata(xps_context *ctx, xps_part *part)
{
- XML_Parser xp;
- int code;
+ xml_element *root;
char buf[1024];
char *s;
@@ -238,23 +213,16 @@ xps_parse_metadata(xps_context *ctx, xps_part *part)
ctx->base_uri = buf;
ctx->part_uri = part->name;
- xp = XML_ParserCreate(NULL);
- if (!xp)
- return fz_throw("cannot create XML parser");
+ root = xml_parse_document(part->data, part->size);
+ if (!root)
+ return fz_rethrow(-1, "cannot parse metadata part '%s'", part->name);
- XML_SetUserData(xp, ctx);
- XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER);
- XML_SetStartElementHandler(xp, (XML_StartElementHandler)xps_parse_metadata_imp);
+ xps_parse_metadata_imp(ctx, root);
- code = XML_Parse(xp, (char*)part->data, part->size, 1);
-
- XML_ParserFree(xp);
+ xml_free_element(root);
ctx->base_uri = NULL;
ctx->part_uri = NULL;
- if (code == 0)
- return fz_throw("cannot parse XML in part: %s", part->name);
-
- return 0;
+ return fz_okay;
}
diff --git a/xps/xpsglyphs.c b/xps/xpsglyphs.c
index f62cc928..1936534b 100644
--- a/xps/xpsglyphs.c
+++ b/xps/xpsglyphs.c
@@ -286,9 +286,9 @@ xps_parse_glyphs_imp(xps_context *ctx, fz_matrix ctm, fz_font *font, float size,
void
xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
- char *base_uri, xps_resource *dict, xps_item *root)
+ char *base_uri, xps_resource *dict, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
int code;
char *fill_uri;
@@ -310,10 +310,10 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
char *opacity_att;
char *opacity_mask_att;
- xps_item *transform_tag = NULL;
- xps_item *clip_tag = NULL;
- xps_item *fill_tag = NULL;
- xps_item *opacity_mask_tag = NULL;
+ xml_element *transform_tag = NULL;
+ xml_element *clip_tag = NULL;
+ xml_element *fill_tag = NULL;
+ xml_element *opacity_mask_tag = NULL;
char *fill_opacity_att = NULL;
@@ -335,32 +335,32 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
* Extract attributes and extended attributes.
*/
- bidi_level_att = xps_att(root, "BidiLevel");
- caret_stops_att = xps_att(root, "CaretStops");
- fill_att = xps_att(root, "Fill");
- font_size_att = xps_att(root, "FontRenderingEmSize");
- font_uri_att = xps_att(root, "FontUri");
- origin_x_att = xps_att(root, "OriginX");
- origin_y_att = xps_att(root, "OriginY");
- is_sideways_att = xps_att(root, "IsSideways");
- indices_att = xps_att(root, "Indices");
- unicode_att = xps_att(root, "UnicodeString");
- style_att = xps_att(root, "StyleSimulations");
- transform_att = xps_att(root, "RenderTransform");
- clip_att = xps_att(root, "Clip");
- opacity_att = xps_att(root, "Opacity");
- opacity_mask_att = xps_att(root, "OpacityMask");
-
- for (node = xps_down(root); node; node = xps_next(node))
+ bidi_level_att = xml_att(root, "BidiLevel");
+ caret_stops_att = xml_att(root, "CaretStops");
+ fill_att = xml_att(root, "Fill");
+ font_size_att = xml_att(root, "FontRenderingEmSize");
+ font_uri_att = xml_att(root, "FontUri");
+ origin_x_att = xml_att(root, "OriginX");
+ origin_y_att = xml_att(root, "OriginY");
+ is_sideways_att = xml_att(root, "IsSideways");
+ indices_att = xml_att(root, "Indices");
+ unicode_att = xml_att(root, "UnicodeString");
+ style_att = xml_att(root, "StyleSimulations");
+ transform_att = xml_att(root, "RenderTransform");
+ clip_att = xml_att(root, "Clip");
+ opacity_att = xml_att(root, "Opacity");
+ opacity_mask_att = xml_att(root, "OpacityMask");
+
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "Glyphs.RenderTransform"))
- transform_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Glyphs.OpacityMask"))
- opacity_mask_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Glyphs.Clip"))
- clip_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Glyphs.Fill"))
- fill_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "Glyphs.RenderTransform"))
+ transform_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Glyphs.OpacityMask"))
+ opacity_mask_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Glyphs.Clip"))
+ clip_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Glyphs.Fill"))
+ fill_tag = xml_down(node);
}
fill_uri = base_uri;
@@ -462,10 +462,10 @@ xps_parse_glyphs(xps_context *ctx, fz_matrix ctm,
* If it's a solid color brush fill/stroke do a simple fill
*/
- if (fill_tag && !strcmp(xps_tag(fill_tag), "SolidColorBrush"))
+ if (fill_tag && !strcmp(xml_tag(fill_tag), "SolidColorBrush"))
{
- fill_opacity_att = xps_att(fill_tag, "Opacity");
- fill_att = xps_att(fill_tag, "Color");
+ fill_opacity_att = xml_att(fill_tag, "Opacity");
+ fill_att = xml_att(fill_tag, "Color");
fill_tag = NULL;
}
diff --git a/xps/xpsgradient.c b/xps/xpsgradient.c
index 180224f8..8c877a0b 100644
--- a/xps/xpsgradient.c
+++ b/xps/xpsgradient.c
@@ -35,7 +35,7 @@ static inline float lerp(float a, float b, float x)
}
static int
-xps_parse_gradient_stops(xps_context *ctx, char *base_uri, xps_item *node,
+xps_parse_gradient_stops(xps_context *ctx, char *base_uri, xml_element *node,
struct stop *stops, int maxcount)
{
fz_colorspace *colorspace;
@@ -51,10 +51,10 @@ xps_parse_gradient_stops(xps_context *ctx, char *base_uri, xps_item *node,
count = 0;
while (node && count < maxcount)
{
- if (!strcmp(xps_tag(node), "GradientStop"))
+ if (!strcmp(xml_tag(node), "GradientStop"))
{
- char *offset = xps_att(node, "Offset");
- char *color = xps_att(node, "Color");
+ char *offset = xml_att(node, "Offset");
+ char *color = xml_att(node, "Color");
if (offset && color)
{
stops[count].offset = atof(offset);
@@ -71,7 +71,7 @@ xps_parse_gradient_stops(xps_context *ctx, char *base_uri, xps_item *node,
count ++;
}
}
- node = xps_next(node);
+ node = xml_next(node);
}
if (count == 0)
@@ -299,7 +299,7 @@ static inline float point_inside_circle(float px, float py, float x, float y, fl
static void
xps_draw_radial_gradient(xps_context *ctx, fz_matrix ctm,
struct stop *stops, int count,
- xps_item *root, int spread)
+ xml_element *root, int spread)
{
float x0, y0, r0;
float x1, y1, r1;
@@ -307,10 +307,10 @@ xps_draw_radial_gradient(xps_context *ctx, fz_matrix ctm,
float yrad = 1;
float invscale;
- char *center_att = xps_att(root, "Center");
- char *origin_att = xps_att(root, "GradientOrigin");
- char *radius_x_att = xps_att(root, "RadiusX");
- char *radius_y_att = xps_att(root, "RadiusY");
+ char *center_att = xml_att(root, "Center");
+ char *origin_att = xml_att(root, "GradientOrigin");
+ char *radius_x_att = xml_att(root, "RadiusX");
+ char *radius_y_att = xml_att(root, "RadiusY");
if (origin_att)
sscanf(origin_att, "%g,%g", &x0, &y0);
@@ -342,12 +342,12 @@ xps_draw_radial_gradient(xps_context *ctx, fz_matrix ctm,
static void
xps_draw_linear_gradient(xps_context *ctx, fz_matrix ctm,
struct stop *stops, int count,
- xps_item *root, int spread)
+ xml_element *root, int spread)
{
float x0, y0, x1, y1;
- char *start_point_att = xps_att(root, "StartPoint");
- char *end_point_att = xps_att(root, "EndPoint");
+ char *start_point_att = xml_att(root, "StartPoint");
+ char *end_point_att = xml_att(root, "EndPoint");
x0 = y0 = 0;
x1 = y1 = 1;
@@ -367,10 +367,10 @@ xps_draw_linear_gradient(xps_context *ctx, fz_matrix ctm,
static void
xps_parse_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xps_item *root,
- void (*draw)(xps_context *, fz_matrix, struct stop *, int, xps_item *, int))
+ char *base_uri, xps_resource *dict, xml_element *root,
+ void (*draw)(xps_context *, fz_matrix, struct stop *, int, xml_element *, int))
{
- xps_item *node;
+ xml_element *node;
char *opacity_att;
char *interpolation_att;
@@ -378,30 +378,30 @@ xps_parse_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
char *mapping_att;
char *transform_att;
- xps_item *transform_tag = NULL;
- xps_item *stop_tag = NULL;
+ xml_element *transform_tag = NULL;
+ xml_element *stop_tag = NULL;
struct stop stop_list[MAX_STOPS];
int stop_count;
fz_matrix transform;
int spread_method;
- opacity_att = xps_att(root, "Opacity");
- interpolation_att = xps_att(root, "ColorInterpolationMode");
- spread_att = xps_att(root, "SpreadMethod");
- mapping_att = xps_att(root, "MappingMode");
- transform_att = xps_att(root, "Transform");
+ opacity_att = xml_att(root, "Opacity");
+ interpolation_att = xml_att(root, "ColorInterpolationMode");
+ spread_att = xml_att(root, "SpreadMethod");
+ mapping_att = xml_att(root, "MappingMode");
+ transform_att = xml_att(root, "Transform");
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "LinearGradientBrush.Transform"))
- transform_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "RadialGradientBrush.Transform"))
- transform_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "LinearGradientBrush.GradientStops"))
- stop_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "RadialGradientBrush.GradientStops"))
- stop_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "LinearGradientBrush.Transform"))
+ transform_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "RadialGradientBrush.Transform"))
+ transform_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "LinearGradientBrush.GradientStops"))
+ stop_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "RadialGradientBrush.GradientStops"))
+ stop_tag = xml_down(node);
}
xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
@@ -447,14 +447,14 @@ xps_parse_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
void
xps_parse_linear_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xps_item *root)
+ char *base_uri, xps_resource *dict, xml_element *root)
{
xps_parse_gradient_brush(ctx, ctm, area, base_uri, dict, root, xps_draw_linear_gradient);
}
void
xps_parse_radial_gradient_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xps_item *root)
+ char *base_uri, xps_resource *dict, xml_element *root)
{
xps_parse_gradient_brush(ctx, ctm, area, base_uri, dict, root, xps_draw_radial_gradient);
}
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index 102051cb..c9bf64fd 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -42,7 +42,7 @@ xps_decode_image(xps_image **imagep, xps_context *ctx, xps_part *part)
}
static void
-xps_paint_image_brush(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *root, void *vimage)
+xps_paint_image_brush(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *root, void *vimage)
{
xps_image *image = vimage;
fz_pixmap *pixmap = image->pixmap;
@@ -55,7 +55,7 @@ xps_paint_image_brush(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resou
}
static xps_part *
-xps_find_image_brush_source_part(xps_context *ctx, char *base_uri, xps_item *root)
+xps_find_image_brush_source_part(xps_context *ctx, char *base_uri, xml_element *root)
{
char *image_source_att;
char buf[1024];
@@ -64,7 +64,7 @@ xps_find_image_brush_source_part(xps_context *ctx, char *base_uri, xps_item *roo
char *profile_name;
char *p;
- image_source_att = xps_att(root, "ImageSource");
+ image_source_att = xml_att(root, "ImageSource");
if (!image_source_att)
return NULL;
@@ -106,7 +106,7 @@ xps_find_image_brush_source_part(xps_context *ctx, char *base_uri, xps_item *roo
void
xps_parse_image_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xps_item *root)
+ char *base_uri, xps_resource *dict, xml_element *root)
{
xps_part *part;
xps_image *image;
diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c
index e5b0f787..75064452 100644
--- a/xps/xpsopacity.c
+++ b/xps/xpsopacity.c
@@ -4,7 +4,7 @@
void
xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area,
char *base_uri, xps_resource *dict,
- char *opacity_att, xps_item *opacity_mask_tag)
+ char *opacity_att, xml_element *opacity_mask_tag)
{
float opacity;
@@ -15,10 +15,10 @@ xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area,
if (opacity_att)
opacity = atof(opacity_att);
- if (opacity_mask_tag && !strcmp(xps_tag(opacity_mask_tag), "SolidColorBrush"))
+ if (opacity_mask_tag && !strcmp(xml_tag(opacity_mask_tag), "SolidColorBrush"))
{
- char *scb_opacity_att = xps_att(opacity_mask_tag, "Opacity");
- char *scb_color_att = xps_att(opacity_mask_tag, "Color");
+ char *scb_opacity_att = xml_att(opacity_mask_tag, "Opacity");
+ char *scb_color_att = xml_att(opacity_mask_tag, "Color");
if (scb_opacity_att)
opacity = opacity * atof(scb_opacity_att);
if (scb_color_att)
@@ -47,7 +47,7 @@ xps_begin_opacity(xps_context *ctx, fz_matrix ctm, fz_rect area,
void
xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict,
- char *opacity_att, xps_item *opacity_mask_tag)
+ char *opacity_att, xml_element *opacity_mask_tag)
{
if (!opacity_att && !opacity_mask_tag)
return;
@@ -57,7 +57,7 @@ xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict,
if (opacity_mask_tag)
{
- if (strcmp(xps_tag(opacity_mask_tag), "SolidColorBrush"))
+ if (strcmp(xml_tag(opacity_mask_tag), "SolidColorBrush"))
ctx->dev->popclip(ctx->dev->user);
}
}
diff --git a/xps/xpspage.c b/xps/xpspage.c
index 1854b1fc..7659a1a7 100644
--- a/xps/xpspage.c
+++ b/xps/xpspage.c
@@ -2,10 +2,10 @@
#include "muxps.h"
void
-xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *root)
+xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *root)
{
xps_resource *new_dict = NULL;
- xps_item *node;
+ xml_element *node;
char *opacity_mask_uri;
int code;
@@ -14,22 +14,22 @@ xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *
char *opacity_att;
char *opacity_mask_att;
- xps_item *transform_tag = NULL;
- xps_item *clip_tag = NULL;
- xps_item *opacity_mask_tag = NULL;
+ xml_element *transform_tag = NULL;
+ xml_element *clip_tag = NULL;
+ xml_element *opacity_mask_tag = NULL;
fz_matrix transform;
- transform_att = xps_att(root, "RenderTransform");
- clip_att = xps_att(root, "Clip");
- opacity_att = xps_att(root, "Opacity");
- opacity_mask_att = xps_att(root, "OpacityMask");
+ transform_att = xml_att(root, "RenderTransform");
+ clip_att = xml_att(root, "Clip");
+ opacity_att = xml_att(root, "Opacity");
+ opacity_mask_att = xml_att(root, "OpacityMask");
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "Canvas.Resources") && xps_down(node))
+ if (!strcmp(xml_tag(node), "Canvas.Resources") && xml_down(node))
{
- code = xps_parse_resource_dictionary(ctx, &new_dict, base_uri, xps_down(node));
+ code = xps_parse_resource_dictionary(ctx, &new_dict, base_uri, xml_down(node));
if (code)
fz_catch(code, "cannot load Canvas.Resources");
else
@@ -39,12 +39,12 @@ xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *
}
}
- if (!strcmp(xps_tag(node), "Canvas.RenderTransform"))
- transform_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Canvas.Clip"))
- clip_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Canvas.OpacityMask"))
- opacity_mask_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "Canvas.RenderTransform"))
+ transform_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Canvas.Clip"))
+ clip_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Canvas.OpacityMask"))
+ opacity_mask_tag = xml_down(node);
}
opacity_mask_uri = base_uri;
@@ -64,7 +64,7 @@ xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *
xps_begin_opacity(ctx, ctm, fz_infiniterect, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
xps_parse_element(ctx, ctm, base_uri, dict, node);
}
@@ -81,7 +81,7 @@ xps_parse_canvas(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *
void
xps_parse_fixed_page(xps_context *ctx, fz_matrix ctm, xps_page *page)
{
- xps_item *node;
+ xml_element *node;
xps_resource *dict;
char base_uri[1024];
char *s;
@@ -97,11 +97,14 @@ xps_parse_fixed_page(xps_context *ctx, fz_matrix ctm, xps_page *page)
ctx->opacity_top = 0;
ctx->opacity[0] = 1;
- for (node = xps_down(page->root); node; node = xps_next(node))
+ if (!page->root)
+ return;
+
+ for (node = xml_down(page->root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
+ if (!strcmp(xml_tag(node), "FixedPage.Resources") && xml_down(node))
{
- code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node));
+ code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xml_down(node));
if (code)
fz_catch(code, "cannot load FixedPage.Resources");
}
@@ -118,7 +121,7 @@ int
xps_load_fixed_page(xps_context *ctx, xps_page *page)
{
xps_part *part;
- xps_item *root;
+ xml_element *root;
char *width_att;
char *height_att;
@@ -126,20 +129,20 @@ xps_load_fixed_page(xps_context *ctx, xps_page *page)
if (!part)
return fz_rethrow(-1, "cannot read zip part '%s'", page->name);
- root = xps_parse_xml(ctx, part->data, part->size);
+ root = xml_parse_document(part->data, part->size);
if (!root)
- return fz_rethrow(-1, "cannot parse xml");
+ return fz_rethrow(-1, "cannot parse xml part '%s'", page->name);
xps_free_part(ctx, part);
- if (strcmp(xps_tag(root), "FixedPage"))
- return fz_throw("expected FixedPage element (found %s)", xps_tag(root));
+ if (strcmp(xml_tag(root), "FixedPage"))
+ return fz_throw("expected FixedPage element (found %s)", xml_tag(root));
- width_att = xps_att(root, "Width");
+ width_att = xml_att(root, "Width");
if (!width_att)
return fz_throw("FixedPage missing required attribute: Width");
- height_att = xps_att(root, "Height");
+ height_att = xml_att(root, "Height");
if (!height_att)
return fz_throw("FixedPage missing required attribute: Height");
diff --git a/xps/xpspath.c b/xps/xpspath.c
index ded566ca..00e57bee 100644
--- a/xps/xpspath.c
+++ b/xps/xpspath.c
@@ -36,7 +36,7 @@ fz_currentpoint(fz_path *path)
}
void
-xps_clip(xps_context *ctx, fz_matrix ctm, xps_resource *dict, char *clip_att, xps_item *clip_tag)
+xps_clip(xps_context *ctx, fz_matrix ctm, xps_resource *dict, char *clip_att, xml_element *clip_tag)
{
fz_path *path;
int fill_rule = 0;
@@ -462,7 +462,7 @@ xps_parse_abbreviated_geometry(xps_context *ctx, char *geom, int *fill_rule)
}
static void
-xps_parse_arc_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_arc_segment(fz_path *path, xml_element *root, int stroking, int *skipped_stroke)
{
/* ArcSegment pretty much follows the SVG algorithm for converting an
* arc in endpoint representation to an arc in centerpoint
@@ -475,12 +475,12 @@ xps_parse_arc_segment(fz_path *path, xps_item *root, int stroking, int *skipped_
float size_x, size_y;
int is_stroked;
- char *point_att = xps_att(root, "Point");
- char *size_att = xps_att(root, "Size");
- char *rotation_angle_att = xps_att(root, "RotationAngle");
- char *is_large_arc_att = xps_att(root, "IsLargeArc");
- char *sweep_direction_att = xps_att(root, "SweepDirection");
- char *is_stroked_att = xps_att(root, "IsStroked");
+ char *point_att = xml_att(root, "Point");
+ char *size_att = xml_att(root, "Size");
+ char *rotation_angle_att = xml_att(root, "RotationAngle");
+ char *is_large_arc_att = xml_att(root, "IsLargeArc");
+ char *sweep_direction_att = xml_att(root, "SweepDirection");
+ char *is_stroked_att = xml_att(root, "IsStroked");
if (!point_att || !size_att || !rotation_angle_att || !is_large_arc_att || !sweep_direction_att)
{
@@ -510,10 +510,10 @@ xps_parse_arc_segment(fz_path *path, xps_item *root, int stroking, int *skipped_
}
static void
-xps_parse_poly_quadratic_bezier_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_poly_quadratic_bezier_segment(fz_path *path, xml_element *root, int stroking, int *skipped_stroke)
{
- char *points_att = xps_att(root, "Points");
- char *is_stroked_att = xps_att(root, "IsStroked");
+ char *points_att = xml_att(root, "Points");
+ char *is_stroked_att = xml_att(root, "IsStroked");
float x[2], y[2];
int is_stroked;
fz_point pt;
@@ -560,10 +560,10 @@ xps_parse_poly_quadratic_bezier_segment(fz_path *path, xps_item *root, int strok
}
static void
-xps_parse_poly_bezier_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_poly_bezier_segment(fz_path *path, xml_element *root, int stroking, int *skipped_stroke)
{
- char *points_att = xps_att(root, "Points");
- char *is_stroked_att = xps_att(root, "IsStroked");
+ char *points_att = xml_att(root, "Points");
+ char *is_stroked_att = xml_att(root, "IsStroked");
float x[3], y[3];
int is_stroked;
char *s;
@@ -601,10 +601,10 @@ xps_parse_poly_bezier_segment(fz_path *path, xps_item *root, int stroking, int *
}
static void
-xps_parse_poly_line_segment(fz_path *path, xps_item *root, int stroking, int *skipped_stroke)
+xps_parse_poly_line_segment(fz_path *path, xml_element *root, int stroking, int *skipped_stroke)
{
- char *points_att = xps_att(root, "Points");
- char *is_stroked_att = xps_att(root, "IsStroked");
+ char *points_att = xml_att(root, "Points");
+ char *is_stroked_att = xml_att(root, "IsStroked");
int is_stroked;
float x, y;
char *s;
@@ -635,9 +635,9 @@ xps_parse_poly_line_segment(fz_path *path, xps_item *root, int stroking, int *sk
}
static void
-xps_parse_path_figure(fz_path *path, xps_item *root, int stroking)
+xps_parse_path_figure(fz_path *path, xml_element *root, int stroking)
{
- xps_item *node;
+ xml_element *node;
char *is_closed_att;
char *start_point_att;
@@ -650,9 +650,9 @@ xps_parse_path_figure(fz_path *path, xps_item *root, int stroking)
int skipped_stroke = 0;
- is_closed_att = xps_att(root, "IsClosed");
- start_point_att = xps_att(root, "StartPoint");
- is_filled_att = xps_att(root, "IsFilled");
+ is_closed_att = xml_att(root, "IsClosed");
+ start_point_att = xml_att(root, "StartPoint");
+ is_filled_att = xml_att(root, "IsFilled");
if (is_closed_att)
is_closed = !strcmp(is_closed_att, "true");
@@ -666,15 +666,15 @@ xps_parse_path_figure(fz_path *path, xps_item *root, int stroking)
fz_moveto(path, start_x, start_y);
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "ArcSegment"))
+ if (!strcmp(xml_tag(node), "ArcSegment"))
xps_parse_arc_segment(path, node, stroking, &skipped_stroke);
- if (!strcmp(xps_tag(node), "PolyBezierSegment"))
+ if (!strcmp(xml_tag(node), "PolyBezierSegment"))
xps_parse_poly_bezier_segment(path, node, stroking, &skipped_stroke);
- if (!strcmp(xps_tag(node), "PolyLineSegment"))
+ if (!strcmp(xml_tag(node), "PolyLineSegment"))
xps_parse_poly_line_segment(path, node, stroking, &skipped_stroke);
- if (!strcmp(xps_tag(node), "PolyQuadraticBezierSegment"))
+ if (!strcmp(xml_tag(node), "PolyQuadraticBezierSegment"))
xps_parse_poly_quadratic_bezier_segment(path, node, stroking, &skipped_stroke);
}
@@ -688,28 +688,28 @@ xps_parse_path_figure(fz_path *path, xps_item *root, int stroking)
}
fz_path *
-xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, int stroking, int *fill_rule)
+xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xml_element *root, int stroking, int *fill_rule)
{
- xps_item *node;
+ xml_element *node;
char *figures_att;
char *fill_rule_att;
char *transform_att;
- xps_item *transform_tag = NULL;
- xps_item *figures_tag = NULL; /* only used by resource */
+ xml_element *transform_tag = NULL;
+ xml_element *figures_tag = NULL; /* only used by resource */
fz_matrix transform;
fz_path *path;
- figures_att = xps_att(root, "Figures");
- fill_rule_att = xps_att(root, "FillRule");
- transform_att = xps_att(root, "Transform");
+ figures_att = xml_att(root, "Figures");
+ fill_rule_att = xml_att(root, "FillRule");
+ transform_att = xml_att(root, "Transform");
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "PathGeometry.Transform"))
- transform_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "PathGeometry.Transform"))
+ transform_tag = xml_down(node);
}
xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
@@ -737,9 +737,9 @@ xps_parse_path_geometry(xps_context *ctx, xps_resource *dict, xps_item *root, in
if (figures_tag)
xps_parse_path_figure(path, figures_tag, stroking);
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "PathFigure"))
+ if (!strcmp(xml_tag(node), "PathFigure"))
xps_parse_path_figure(path, node, stroking);
}
@@ -768,9 +768,9 @@ xps_parse_line_cap(char *attr)
*/
void
-xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xps_item *root)
+xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
char *fill_uri;
char *stroke_uri;
@@ -784,12 +784,12 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
char *opacity_att;
char *opacity_mask_att;
- xps_item *transform_tag = NULL;
- xps_item *clip_tag = NULL;
- xps_item *data_tag = NULL;
- xps_item *fill_tag = NULL;
- xps_item *stroke_tag = NULL;
- xps_item *opacity_mask_tag = NULL;
+ xml_element *transform_tag = NULL;
+ xml_element *clip_tag = NULL;
+ xml_element *data_tag = NULL;
+ xml_element *fill_tag = NULL;
+ xml_element *stroke_tag = NULL;
+ xml_element *opacity_mask_tag = NULL;
char *fill_opacity_att = NULL;
char *stroke_opacity_att = NULL;
@@ -815,37 +815,37 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
* Extract attributes and extended attributes.
*/
- transform_att = xps_att(root, "RenderTransform");
- clip_att = xps_att(root, "Clip");
- data_att = xps_att(root, "Data");
- fill_att = xps_att(root, "Fill");
- stroke_att = xps_att(root, "Stroke");
- opacity_att = xps_att(root, "Opacity");
- opacity_mask_att = xps_att(root, "OpacityMask");
-
- stroke_dash_array_att = xps_att(root, "StrokeDashArray");
- stroke_dash_cap_att = xps_att(root, "StrokeDashCap");
- stroke_dash_offset_att = xps_att(root, "StrokeDashOffset");
- stroke_end_line_cap_att = xps_att(root, "StrokeEndLineCap");
- stroke_start_line_cap_att = xps_att(root, "StrokeStartLineCap");
- stroke_line_join_att = xps_att(root, "StrokeLineJoin");
- stroke_miter_limit_att = xps_att(root, "StrokeMiterLimit");
- stroke_thickness_att = xps_att(root, "StrokeThickness");
-
- for (node = xps_down(root); node; node = xps_next(node))
+ transform_att = xml_att(root, "RenderTransform");
+ clip_att = xml_att(root, "Clip");
+ data_att = xml_att(root, "Data");
+ fill_att = xml_att(root, "Fill");
+ stroke_att = xml_att(root, "Stroke");
+ opacity_att = xml_att(root, "Opacity");
+ opacity_mask_att = xml_att(root, "OpacityMask");
+
+ stroke_dash_array_att = xml_att(root, "StrokeDashArray");
+ stroke_dash_cap_att = xml_att(root, "StrokeDashCap");
+ stroke_dash_offset_att = xml_att(root, "StrokeDashOffset");
+ stroke_end_line_cap_att = xml_att(root, "StrokeEndLineCap");
+ stroke_start_line_cap_att = xml_att(root, "StrokeStartLineCap");
+ stroke_line_join_att = xml_att(root, "StrokeLineJoin");
+ stroke_miter_limit_att = xml_att(root, "StrokeMiterLimit");
+ stroke_thickness_att = xml_att(root, "StrokeThickness");
+
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "Path.RenderTransform"))
- transform_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Path.OpacityMask"))
- opacity_mask_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Path.Clip"))
- clip_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Path.Fill"))
- fill_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Path.Stroke"))
- stroke_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "Path.Data"))
- data_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "Path.RenderTransform"))
+ transform_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Path.OpacityMask"))
+ opacity_mask_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Path.Clip"))
+ clip_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Path.Fill"))
+ fill_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Path.Stroke"))
+ stroke_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "Path.Data"))
+ data_tag = xml_down(node);
}
fill_uri = base_uri;
@@ -866,17 +866,17 @@ xps_parse_path(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource *di
if (!data_att && !data_tag)
return;
- if (fill_tag && !strcmp(xps_tag(fill_tag), "SolidColorBrush"))
+ if (fill_tag && !strcmp(xml_tag(fill_tag), "SolidColorBrush"))
{
- fill_opacity_att = xps_att(fill_tag, "Opacity");
- fill_att = xps_att(fill_tag, "Color");
+ fill_opacity_att = xml_att(fill_tag, "Opacity");
+ fill_att = xml_att(fill_tag, "Color");
fill_tag = NULL;
}
- if (stroke_tag && !strcmp(xps_tag(stroke_tag), "SolidColorBrush"))
+ if (stroke_tag && !strcmp(xml_tag(stroke_tag), "SolidColorBrush"))
{
- stroke_opacity_att = xps_att(stroke_tag, "Opacity");
- stroke_att = xps_att(stroke_tag, "Color");
+ stroke_opacity_att = xml_att(stroke_tag, "Opacity");
+ stroke_att = xml_att(stroke_tag, "Color");
stroke_tag = NULL;
}
diff --git a/xps/xpsresource.c b/xps/xpsresource.c
index 28c172bf..59dc3f9d 100644
--- a/xps/xpsresource.c
+++ b/xps/xpsresource.c
@@ -1,7 +1,7 @@
#include "fitz.h"
#include "muxps.h"
-static xps_item *
+static xml_element *
xps_find_resource(xps_context *ctx, xps_resource *dict, char *name, char **urip)
{
xps_resource *head, *node;
@@ -20,7 +20,7 @@ xps_find_resource(xps_context *ctx, xps_resource *dict, char *name, char **urip)
return NULL;
}
-static xps_item *
+static xml_element *
xps_parse_resource_reference(xps_context *ctx, xps_resource *dict, char *att, char **urip)
{
char name[1024];
@@ -39,11 +39,11 @@ xps_parse_resource_reference(xps_context *ctx, xps_resource *dict, char *att, ch
void
xps_resolve_resource_reference(xps_context *ctx, xps_resource *dict,
- char **attp, xps_item **tagp, char **urip)
+ char **attp, xml_element **tagp, char **urip)
{
if (*attp)
{
- xps_item *rsrc = xps_parse_resource_reference(ctx, dict, *attp, urip);
+ xml_element *rsrc = xps_parse_resource_reference(ctx, dict, *attp, urip);
if (rsrc)
{
*attp = NULL;
@@ -59,7 +59,7 @@ xps_parse_remote_resource_dictionary(xps_context *ctx, xps_resource **dictp, cha
char part_uri[1024];
xps_resource *dict;
xps_part *part;
- xps_item *xml;
+ xml_element *xml;
char *s;
int code;
@@ -71,18 +71,18 @@ xps_parse_remote_resource_dictionary(xps_context *ctx, xps_resource **dictp, cha
return fz_throw("cannot find remote resource part '%s'", part_name);
}
- xml = xps_parse_xml(ctx, part->data, part->size);
+ xml = xml_parse_document(part->data, part->size);
if (!xml)
{
xps_free_part(ctx, part);
return fz_rethrow(-1, "cannot parse xml");
}
- if (strcmp(xps_tag(xml), "ResourceDictionary"))
+ if (strcmp(xml_tag(xml), "ResourceDictionary"))
{
- xps_free_item(ctx, xml);
+ xml_free_element(xml);
xps_free_part(ctx, part);
- return fz_throw("expected ResourceDictionary element (found %s)", xps_tag(xml));
+ return fz_throw("expected ResourceDictionary element (found %s)", xml_tag(xml));
}
fz_strlcpy(part_uri, part_name, sizeof part_uri);
@@ -93,7 +93,7 @@ xps_parse_remote_resource_dictionary(xps_context *ctx, xps_resource **dictp, cha
code = xps_parse_resource_dictionary(ctx, &dict, part_uri, xml);
if (code)
{
- xps_free_item(ctx, xml);
+ xml_free_element(xml);
xps_free_part(ctx, part);
return fz_rethrow(code, "cannot parse remote resource dictionary: %s", part_uri);
}
@@ -107,16 +107,16 @@ xps_parse_remote_resource_dictionary(xps_context *ctx, xps_resource **dictp, cha
}
int
-xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, xps_item *root)
+xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base_uri, xml_element *root)
{
xps_resource *head;
xps_resource *entry;
- xps_item *node;
+ xml_element *node;
char *source;
char *key;
int code;
- source = xps_att(root, "Source");
+ source = xml_att(root, "Source");
if (source)
{
code = xps_parse_remote_resource_dictionary(ctx, dictp, base_uri, source);
@@ -127,10 +127,10 @@ xps_parse_resource_dictionary(xps_context *ctx, xps_resource **dictp, char *base
head = NULL;
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
/* Usually "x:Key"; we have already processed and stripped namespace */
- key = xps_att(node, "Key");
+ key = xml_att(node, "Key");
if (key)
{
entry = fz_malloc(sizeof(xps_resource));
@@ -161,7 +161,7 @@ xps_free_resource_dictionary(xps_context *ctx, xps_resource *dict)
{
next = dict->next;
if (dict->base_xml)
- xps_free_item(ctx, dict->base_xml);
+ xml_free_element(dict->base_xml);
if (dict->base_uri)
fz_free(dict->base_uri);
fz_free(dict);
diff --git a/xps/xpstile.c b/xps/xpstile.c
index 1b96a7d3..ecc0af3f 100644
--- a/xps/xpstile.c
+++ b/xps/xpstile.c
@@ -12,9 +12,9 @@ struct closure
{
char *base_uri;
xps_resource *dict;
- xps_item *root;
+ xml_element *root;
void *user;
- void (*func)(xps_context*, fz_matrix, char*, xps_resource*, xps_item*, void*);
+ void (*func)(xps_context*, fz_matrix, char*, xps_resource*, xml_element*, void*);
};
static void
@@ -65,10 +65,10 @@ xps_paint_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect viewbox, int til
void
xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xps_item *root,
- void (*func)(xps_context*, fz_matrix, char*, xps_resource*, xps_item*, void*), void *user)
+ char *base_uri, xps_resource *dict, xml_element *root,
+ void (*func)(xps_context*, fz_matrix, char*, xps_resource*, xml_element*, void*), void *user)
{
- xps_item *node;
+ xml_element *node;
struct closure c;
char *opacity_att;
@@ -79,7 +79,7 @@ xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
char *viewbox_units_att;
char *viewport_units_att;
- xps_item *transform_tag = NULL;
+ xml_element *transform_tag = NULL;
fz_matrix transform;
fz_rect viewbox;
@@ -88,13 +88,13 @@ xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
float xscale, yscale;
int tile_mode;
- opacity_att = xps_att(root, "Opacity");
- transform_att = xps_att(root, "Transform");
- viewbox_att = xps_att(root, "Viewbox");
- viewport_att = xps_att(root, "Viewport");
- tile_mode_att = xps_att(root, "TileMode");
- viewbox_units_att = xps_att(root, "ViewboxUnits");
- viewport_units_att = xps_att(root, "ViewportUnits");
+ opacity_att = xml_att(root, "Opacity");
+ transform_att = xml_att(root, "Transform");
+ viewbox_att = xml_att(root, "Viewbox");
+ viewport_att = xml_att(root, "Viewport");
+ tile_mode_att = xml_att(root, "TileMode");
+ viewbox_units_att = xml_att(root, "ViewboxUnits");
+ viewport_units_att = xml_att(root, "ViewportUnits");
c.base_uri = base_uri;
c.dict = dict;
@@ -102,12 +102,12 @@ xps_parse_tiling_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
c.user = user;
c.func = func;
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "ImageBrush.Transform"))
- transform_tag = xps_down(node);
- if (!strcmp(xps_tag(node), "VisualBrush.Transform"))
- transform_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "ImageBrush.Transform"))
+ transform_tag = xml_down(node);
+ if (!strcmp(xml_tag(node), "VisualBrush.Transform"))
+ transform_tag = xml_down(node);
}
xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
diff --git a/xps/xpsvisual.c b/xps/xpsvisual.c
index ad633708..ac7de23c 100644
--- a/xps/xpsvisual.c
+++ b/xps/xpsvisual.c
@@ -5,27 +5,27 @@ enum { TILE_NONE, TILE_TILE, TILE_FLIP_X, TILE_FLIP_Y, TILE_FLIP_X_Y };
static void
xps_paint_visual_brush(xps_context *ctx, fz_matrix ctm,
- char *base_uri, xps_resource *dict, xps_item *root, void *visual_tag)
+ char *base_uri, xps_resource *dict, xml_element *root, void *visual_tag)
{
- xps_parse_element(ctx, ctm, base_uri, dict, (xps_item *)visual_tag);
+ xps_parse_element(ctx, ctm, base_uri, dict, (xml_element *)visual_tag);
}
void
xps_parse_visual_brush(xps_context *ctx, fz_matrix ctm, fz_rect area,
- char *base_uri, xps_resource *dict, xps_item *root)
+ char *base_uri, xps_resource *dict, xml_element *root)
{
- xps_item *node;
+ xml_element *node;
char *visual_uri;
char *visual_att;
- xps_item *visual_tag = NULL;
+ xml_element *visual_tag = NULL;
- visual_att = xps_att(root, "Visual");
+ visual_att = xml_att(root, "Visual");
- for (node = xps_down(root); node; node = xps_next(node))
+ for (node = xml_down(root); node; node = xml_next(node))
{
- if (!strcmp(xps_tag(node), "VisualBrush.Visual"))
- visual_tag = xps_down(node);
+ if (!strcmp(xml_tag(node), "VisualBrush.Visual"))
+ visual_tag = xml_down(node);
}
visual_uri = base_uri;
diff --git a/xps/xpsxml.c b/xps/xpsxml.c
index c6f41123..397b68ec 100644
--- a/xps/xpsxml.c
+++ b/xps/xpsxml.c
@@ -1,339 +1,387 @@
-/* Simple XML document object model on top of Expat. */
-
#include "fitz.h"
#include "muxps.h"
-#include <expat.h>
-
-#define XMLBUFLEN 4096
-
-#define NS_XPS "http://schemas.microsoft.com/xps/2005/06"
-#define NS_MC "http://schemas.openxmlformats.org/markup-compatibility/2006"
-
-typedef struct xps_parser_s xps_parser;
+struct attribute
+{
+ char name[32];
+ char *value;
+ struct attribute *next;
+};
-struct xps_parser_s
+struct element
{
- xps_context *ctx;
- xps_item *root;
- xps_item *head;
- char *error;
- int compat;
- char *base; /* base of relative URIs */
+ char name[32];
+ struct attribute *atts;
+ struct element *up, *down, *next;
};
-struct xps_item_s
+struct parser
{
- char *name;
- char **atts;
- xps_item *up;
- xps_item *down;
- xps_item *next;
+ struct element *head;
};
-static char *
-skip_namespace(char *s)
+static inline void indent(int n)
{
- char *p = strchr(s, ' ');
- if (p)
- return p + 1;
- return s;
+ while (n--) putchar(' ');
}
-static void
-on_open_tag(void *zp, char *ns_name, char **atts)
+void xml_print_element(struct element *item, int level)
{
- xps_parser *parser = zp;
- xps_item *item;
- xps_item *tail;
- int namelen;
- int attslen;
- int textlen;
- char *name, *p;
- int i;
-
- if (parser->error)
- return;
-
- /* check namespace */
-
- name = NULL;
-
- p = strstr(ns_name, NS_XPS);
- if (p == ns_name)
- {
- name = strchr(ns_name, ' ') + 1;
+ while (item) {
+ struct attribute *att;
+ indent(level);
+ printf("<%s", item->name);
+ for (att = item->atts; att; att = att->next)
+ printf(" %s=\"%s\"", att->name, att->value);
+ if (item->down) {
+ printf(">\n");
+ xml_print_element(item->down, level + 1);
+ indent(level);
+ printf("</%s>\n", item->name);
+ }
+ else {
+ printf("/>\n");
+ }
+ item = item->next;
}
+}
- p = strstr(ns_name, NS_MC);
- if (p == ns_name)
- {
- name = strchr(ns_name, ' ') + 1;
- parser->compat = 1;
- }
+struct element *xml_next(struct element *item)
+{
+ return item->next;
+}
- if (!name)
- {
- fz_warn("unknown namespace: %s", ns_name);
- name = ns_name;
- }
+struct element *xml_down(struct element *item)
+{
+ return item->down;
+}
- /* count size to alloc */
+char *xml_tag(struct element *item)
+{
+ return item->name;
+}
- namelen = strlen(name) + 1; /* zero terminated */
- attslen = sizeof(char*); /* with space for sentinel */
- textlen = 0;
- for (i = 0; atts[i]; i++)
- {
- attslen += sizeof(char*);
- if ((i & 1) == 0)
- textlen += strlen(skip_namespace(atts[i])) + 1;
- else
- textlen += strlen(atts[i]) + 1;
- }
+char *xml_att(struct element *item, const char *name)
+{
+ struct attribute *att;
+ for (att = item->atts; att; att = att->next)
+ if (!strcmp(att->name, name))
+ return att->value;
+ return NULL;
+}
- item = fz_malloc(sizeof(xps_item) + attslen + namelen + textlen);
- if (!item)
- {
- parser->error = "out of memory";
+static void xml_free_attribute(struct attribute *att)
+{
+ while (att) {
+ struct attribute *next = att->next;
+ if (att->value)
+ fz_free(att->value);
+ fz_free(att);
+ att = next;
}
+}
- /* copy strings to new memory */
-
- item->atts = (char**) (((char*)item) + sizeof(xps_item));
- item->name = ((char*)item) + sizeof(xps_item) + attslen;
- p = ((char*)item) + sizeof(xps_item) + attslen + namelen;
+void xml_free_element(struct element *item)
+{
+ while (item) {
+ struct element *next = item->next;
+ if (item->atts)
+ xml_free_attribute(item->atts);
+ if (item->down)
+ xml_free_element(item->down);
+ fz_free(item);
+ item = next;
+ }
+}
- strcpy(item->name, name);
- for (i = 0; atts[i]; i++)
- {
- item->atts[i] = p;
- if ((i & 1) == 0)
- strcpy(item->atts[i], skip_namespace(atts[i]));
+static int xml_parse_entity(int *c, char *a)
+{
+ char *b;
+ if (a[1] == '#') {
+ if (a[2] == 'x')
+ *c = strtol(a + 3, &b, 16);
else
- strcpy(item->atts[i], atts[i]);
- p += strlen(p) + 1;
+ *c = strtol(a + 2, &b, 10);
+ if (*b == ';')
+ return b - a;
}
-
- item->atts[i] = 0;
-
- /* link item into tree */
-
- item->up = parser->head;
- item->down = NULL;
- item->next = NULL;
-
- if (!parser->head)
- {
- parser->root = item;
- parser->head = item;
- return;
+ else if (a[1] == 'l' && a[2] == 't' && a[3] == ';') {
+ *c = '<';
+ return 4;
}
-
- if (!parser->head->down)
- {
- parser->head->down = item;
- parser->head = item;
- return;
+ else if (a[1] == 'g' && a[2] == 't' && a[3] == ';') {
+ *c = '>';
+ return 4;
}
-
- tail = parser->head->down;
- while (tail->next)
- tail = tail->next;
- tail->next = item;
- parser->head = item;
+ else if (a[1] == 'a' && a[2] == 'm' && a[3] == 'p' && a[4] == ';') {
+ *c = '&';
+ return 5;
+ }
+ else if (a[1] == 'a' && a[2] == 'p' && a[3] == 'o' && a[4] == 's' && a[5] == ';') {
+ *c = '\'';
+ return 6;
+ }
+ else if (a[1] == 'q' && a[2] == 'u' && a[3] == 'o' && a[4] == 't' && a[5] == ';') {
+ *c = '"';
+ return 6;
+ }
+ *c = *a++;
+ return 1;
}
-static void
-on_close_tag(void *zp, char *name)
+static void xml_emit_open_tag(struct parser *parser, char *a, char *b)
{
- xps_parser *parser = zp;
+ struct element *head, *tail;
- if (parser->error)
- return;
+ head = fz_malloc(sizeof(struct element));
+ if (b - a > sizeof(head->name))
+ b = a + sizeof(head->name);
+ memcpy(head->name, a, b - a);
+ head->name[b - a] = 0;
- if (parser->head)
- parser->head = parser->head->up;
-}
+ head->atts = NULL;
+ head->up = parser->head;
+ head->down = NULL;
+ head->next = NULL;
-static inline int
-is_xml_space(int c)
-{
- return c == ' ' || c == '\t' || c == '\r' || c == '\n';
-}
-
-static void
-on_text(void *zp, char *buf, int len)
-{
- xps_parser *parser = zp;
- char *atts[3];
- int i;
-
- if (parser->error)
- return;
-
- for (i = 0; i < len; i++)
- {
- if (!is_xml_space(buf[i]))
- {
- char *tmp = fz_malloc(len + 1);
- if (!tmp)
- {
- parser->error = "out of memory";
- return;
- }
-
- atts[0] = "";
- atts[1] = tmp;
- atts[2] = NULL;
-
- memcpy(tmp, buf, len);
- tmp[len] = 0;
- on_open_tag(zp, "", atts);
- on_close_tag(zp, "");
- fz_free(tmp);
- return;
- }
+ if (!parser->head->down) {
+ parser->head->down = head;
+ }
+ else {
+ tail = parser->head->down;
+ while (tail->next)
+ tail = tail->next;
+ tail->next = head;
}
+
+ parser->head = head;
}
-static xps_item *
-xps_process_compatibility(xps_context *ctx, xps_item *root)
+static void xml_emit_att_name(struct parser *parser, char *a, char *b)
{
- fz_warn("XPS document uses markup compatibility tags");
- return root;
+ struct element *head = parser->head;
+ struct attribute *att;
+
+ att = fz_malloc(sizeof(struct attribute));
+ if (b - a > sizeof(att->name))
+ b = a + sizeof(att->name);
+ memcpy(att->name, a, b - a);
+ att->name[b - a] = 0;
+ att->value = NULL;
+ att->next = head->atts;
+ head->atts = att;
}
-xps_item *
-xps_parse_xml(xps_context *ctx, byte *buf, int len)
+static void xml_emit_att_value(struct parser *parser, char *a, char *b)
{
- xps_parser 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)
- {
- fz_throw("xml error: cannot 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);
- fz_throw("xml error: %s", XML_ErrorString(XML_GetErrorCode(xp)));
- return NULL;
+ struct element *head = parser->head;
+ struct attribute *att = head->atts;
+ char *s;
+ int c;
+
+ /* entities are all longer than UTFmax so runetochar is safe */
+ s = att->value = fz_malloc(b - a + 1);
+ while (a < b) {
+ if (*a == '&') {
+ a += xml_parse_entity(&c, a);
+ s += runetochar(s, &c);
+ }
+ else {
+ *s++ = *a++;
+ }
}
-
- XML_ParserFree(xp);
-
- if (parser.compat)
- xps_process_compatibility(ctx, parser.root);
-
- return parser.root;
+ *s = 0;
}
-xps_item *
-xps_next(xps_item *item)
+static void xml_emit_close_tag(struct parser *parser)
{
- return item->next;
+ if (parser->head->up)
+ parser->head = parser->head->up;
}
-xps_item *
-xps_down(xps_item *item)
+static inline int isname(int c)
{
- return item->down;
+ return c == '.' || c == '-' || c == '_' || c == ':' ||
+ (c >= '0' && c <= '9') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z');
}
-char *
-xps_tag(xps_item *item)
+static inline int iswhite(int c)
{
- return item->name;
+ return c == ' ' || c == '\r' || c == '\n' || c == '\t';
}
-char *
-xps_att(xps_item *item, const char *att)
+static char *xml_parse_document_imp(struct parser *x, char *p)
{
- int i;
- for (i = 0; item->atts[i]; i += 2)
- if (!strcmp(item->atts[i], att))
- return item->atts[i + 1];
+ char *mark;
+ int quote;
+
+parse_text:
+ mark = p;
+ while (*p && *p != '<') ++p;
+ if (*p == '<') { ++p; goto parse_element; }
return NULL;
-}
-void
-xps_free_item(xps_context *ctx, xps_item *item)
-{
- xps_item *next;
- while (item)
- {
- next = item->next;
- if (item->down)
- xps_free_item(ctx, item->down);
- fz_free(item);
- item = next;
+parse_element:
+ if (*p == '/') { ++p; goto parse_closing_element; }
+ if (*p == '!') { ++p; goto parse_comment; }
+ if (*p == '?') { ++p; goto parse_processing_instruction; }
+ while (iswhite(*p)) ++p;
+ if (isname(*p))
+ goto parse_element_name;
+ return "syntax error in element";
+
+parse_comment:
+ if (*p == '[') goto parse_cdata;
+ if (*p++ != '-') return "syntax error in comment (<! not followed by --)";
+ if (*p++ != '-') return "syntax error in comment (<!- not followed by -)";
+ mark = p;
+ while (*p) {
+ if (p[0] == '-' && p[1] == '-' && p[2] == '>') {
+ p += 3;
+ goto parse_text;
+ }
+ ++p;
+ }
+ return "end of data in comment";
+
+parse_cdata:
+ if (p[1] != 'C' || p[2] != 'D' || p[3] != 'A' || p[4] != 'T' || p[5] != 'A' || p[6] != '[')
+ return "syntax error in CDATA section";
+ p += 7;
+ mark = p;
+ while (*p) {
+ if (p[0] == ']' && p[1] == ']' && p[2] == '>') {
+ p += 3;
+ goto parse_text;
+ }
+ ++p;
+ }
+ return "end of data in CDATA section";
+
+parse_processing_instruction:
+ while (*p) {
+ if (p[0] == '?' && p[1] == '>') {
+ p += 2;
+ goto parse_text;
+ }
+ ++p;
+ }
+ return "end of data in processing instruction";
+
+parse_closing_element:
+ while (iswhite(*p)) ++p;
+ mark = p;
+ while (isname(*p)) ++p;
+ while (iswhite(*p)) ++p;
+ if (*p != '>')
+ return "syntax error in closing element";
+ xml_emit_close_tag(x);
+ ++p;
+ goto parse_text;
+
+parse_element_name:
+ mark = p;
+ while (isname(*p)) ++p;
+ xml_emit_open_tag(x, mark, p);
+ if (*p == '>') { ++p; goto parse_text; }
+ if (p[0] == '/' && p[1] == '>') {
+ xml_emit_close_tag(x);
+ p += 2;
+ goto parse_text;
+ }
+ if (iswhite(*p))
+ goto parse_attributes;
+ return "syntax error after element name";
+
+parse_attributes:
+ while (iswhite(*p)) ++p;
+ if (isname(*p))
+ goto parse_attribute_name;
+ if (*p == '>') { ++p; goto parse_text; }
+ if (p[0] == '/' && p[1] == '>') {
+ xml_emit_close_tag(x);
+ p += 2;
+ goto parse_text;
}
+ return "syntax error in attributes";
+
+parse_attribute_name:
+ mark = p;
+ while (isname(*p)) ++p;
+ xml_emit_att_name(x, mark, p);
+ while (iswhite(*p)) ++p;
+ if (*p == '=') { ++p; goto parse_attribute_value; }
+ return "syntax error after attribute name";
+
+parse_attribute_value:
+ while (iswhite(*p)) ++p;
+ quote = *p++;
+ if (quote != '"' && quote != '\'')
+ return "missing quote character";
+ mark = p;
+ while (*p && *p != quote) ++p;
+ if (*p == quote) {
+ xml_emit_att_value(x, mark, p++);
+ goto parse_attributes;
+ }
+ return "end of data in attribute value";
}
-static void indent(int n)
+static char *convert_to_utf8(unsigned char *s, int n)
{
- while (n--)
- printf(" ");
+ unsigned char *e = s + n;
+ char *dst, *d;
+ int c;
+
+ if (s[0] == 0xFE && s[1] == 0xFF) {
+ dst = d = fz_malloc(n * 2);
+ while (s + 1 < e) {
+ c = s[0] << 8 | s[1];
+ d += runetochar(d, &c);
+ s += 2;
+ }
+ *d = 0;
+ return dst;
+ }
+
+ if (s[0] == 0xFF && s[1] == 0xFE) {
+ dst = d = fz_malloc(n * 2);
+ while (s + 1 < e) {
+ c = s[0] | s[1] << 8;
+ d += runetochar(d, &c);
+ s += 2;
+ }
+ *d = 0;
+ return dst;
+ }
+
+ return (char*)s;
}
-static void
-xps_debug_item_imp(xps_item *item, int level, int loop)
+struct element *
+xml_parse_document(unsigned char *s, int n)
{
- int i;
+ struct parser parser;
+ struct element root;
+ char *p, *error;
- while (item)
- {
- indent(level);
+ /* s is already null-terminated (see xps_new_part) */
- if (strlen(item->name) == 0)
- printf("%s\n", item->atts[1]);
- else
- {
- printf("<%s", item->name);
-
- for (i = 0; item->atts[i]; i += 2)
- printf(" %s=\"%s\"", item->atts[i], item->atts[i+1]);
-
- if (item->down)
- {
- printf(">\n");
- xps_debug_item_imp(item->down, level + 1, 1);
- indent(level);
- printf("</%s>\n", item->name);
- }
- else
- printf(" />\n");
- }
+ memset(&root, 0, sizeof(root));
+ parser.head = &root;
- item = item->next;
+ p = convert_to_utf8(s, n);
- if (!loop)
- return;
+ error = xml_parse_document_imp(&parser, p);
+ if (error) {
+ fz_throw(error);
+ return NULL;
}
-}
-void
-xps_debug_item(xps_item *item, int level)
-{
- xps_debug_item_imp(item, level, 0);
+ if (p != (char*)s)
+ fz_free(p);
+
+ return root.down;
}
diff --git a/xps/xpszip.c b/xps/xpszip.c
index 4905ea37..ad708bcb 100644
--- a/xps/xpszip.c
+++ b/xps/xpszip.c
@@ -474,8 +474,10 @@ xps_load_page(xps_context *ctx, int number)
if (!page->root)
{
code = xps_load_fixed_page(ctx, page);
- if (code)
- fz_catch(code, "ignoring errors on page");
+ if (code) {
+ fz_rethrow(code, "cannot load page %d", number + 1);
+ return NULL;
+ }
}
return page;
}
@@ -488,7 +490,7 @@ void
xps_free_page(xps_context *ctx, xps_page *page)
{
if (page->root)
- xps_free_item(ctx, page->root);
+ xml_free_element(page->root);
page->root = NULL;
}