summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile45
-rw-r--r--Makerules2
-rw-r--r--Makethird21
-rw-r--r--xps/muxps.h (renamed from xps/ghostxps.h)227
-rw-r--r--xps/xpsanalyze.c22
-rw-r--r--xps/xpscolor.c85
-rw-r--r--xps/xpscommon.c67
-rw-r--r--xps/xpscrc.c18
-rw-r--r--xps/xpsdoc.c33
-rw-r--r--xps/xpsfont.c519
-rw-r--r--xps/xpsglyphs.c126
-rw-r--r--xps/xpsgradient.c440
-rw-r--r--xps/xpshash.c24
-rw-r--r--xps/xpsimage.c308
-rw-r--r--xps/xpsjpeg.c142
-rw-r--r--xps/xpsjxr.c34
-rw-r--r--xps/xpsmem.c51
-rw-r--r--xps/xpsopacity.c60
-rw-r--r--xps/xpspage.c225
-rw-r--r--xps/xpspath.c440
-rw-r--r--xps/xpspng.c64
-rw-r--r--xps/xpsresource.c44
-rw-r--r--xps/xpstiff.c87
-rw-r--r--xps/xpstile.c172
-rw-r--r--xps/xpstop.c780
-rw-r--r--xps/xpsutf.c18
-rw-r--r--xps/xpsvisual.c29
-rw-r--r--xps/xpsxml.c24
-rw-r--r--xps/xpszip.c242
29 files changed, 1258 insertions, 3091 deletions
diff --git a/Makefile b/Makefile
index 9479ffad..1e6135bb 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,7 @@ endif
# directory exists.
LIBS := -lfreetype -ljbig2dec -lopenjpeg -ljpeg -lz -lm
+XPSLIBS := -lexpat -lpng
include Makerules
include Makethird
@@ -170,6 +171,35 @@ MUPDF_SRC := \
MUPDF_OBJ := $(MUPDF_SRC:mupdf/%.c=$(OBJDIR)/%.o)
$(MUPDF_OBJ): $(MUPDF_HDR)
+MUXPS_HDR := $(FITZ_HDR) xps/muxps.h
+MUXPS_SRC := \
+ xps/xpsanalyze.c \
+ xps/xpscolor.c \
+ xps/xpscommon.c \
+ xps/xpscrc.c \
+ xps/xpsdoc.c \
+ xps/xpsfont.c \
+ xps/xpsglyphs.c \
+ xps/xpsgradient.c \
+ xps/xpshash.c \
+ xps/xpsjxr.c \
+ xps/xpsimage.c \
+ xps/xpsjpeg.c \
+ xps/xpsmem.c \
+ xps/xpsopacity.c \
+ xps/xpspage.c \
+ xps/xpspath.c \
+ xps/xpspng.c \
+ xps/xpsresource.c \
+ xps/xpstiff.c \
+ xps/xpstile.c \
+ xps/xpsutf.c \
+ xps/xpsvisual.c \
+ xps/xpsxml.c \
+ xps/xpszip.c
+MUXPS_OBJ := $(MUXPS_SRC:xps/%.c=$(OBJDIR)/%.o)
+$(MUXPS_OBJ): $(MUXPS_HDR)
+
$(OBJDIR)/%.o: fitz/%.c
$(CC_CMD)
$(OBJDIR)/%.o: draw/%.c
@@ -178,6 +208,8 @@ $(OBJDIR)/%.o: draw/%.s
$(CC_CMD)
$(OBJDIR)/%.o: mupdf/%.c
$(CC_CMD)
+$(OBJDIR)/%.o: xps/%.c
+ $(CC_CMD)
$(OBJDIR)/%.o: $(GENDIR)/%.c
$(CC_CMD)
@@ -298,11 +330,15 @@ MUPDF_LIB = $(OBJDIR)/libmupdf.a
$(MUPDF_LIB): $(FITZ_OBJ) $(DRAW_OBJ) $(MUPDF_OBJ) $(CMAP_OBJ) $(FONT_OBJ)
$(AR_CMD)
+MUXPS_LIB = $(OBJDIR)/libmuxps.a
+$(MUXPS_LIB): $(FITZ_OBJ) $(DRAW_OBJ) $(MUXPS_OBJ)
+ $(AR_CMD)
+
#
# Applications
#
-APPS = $(PDFSHOW_EXE) $(PDFCLEAN_EXE) $(PDFDRAW_EXE) $(PDFEXTRACT_EXE) $(PDFINFO_EXE) $(PDFVIEW_EXE)
+APPS = $(PDFSHOW_EXE) $(PDFCLEAN_EXE) $(PDFDRAW_EXE) $(PDFEXTRACT_EXE) $(PDFINFO_EXE) $(PDFVIEW_EXE) $(XPSDRAW_EXE)
APPS_MAN = \
apps/man/mupdf.1 \
@@ -348,6 +384,13 @@ $(PDFINFO_OBJ): $(MUPDF_HDR)
$(PDFINFO_EXE): $(PDFINFO_OBJ) $(MUPDF_LIB) $(THIRD_LIBS)
$(LD_CMD)
+XPSDRAW_SRC=xps/xpstop.c
+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)
+
PDFAPP_HDR = apps/pdfapp.h
X11VIEW_SRC=apps/x11_main.c apps/x11_image.c apps/pdfapp.c
diff --git a/Makerules b/Makerules
index 34bf6ea6..e3e5a987 100644
--- a/Makerules
+++ b/Makerules
@@ -7,7 +7,7 @@ CC ?=
CFLAGS ?=
LDFLAGS ?=
-CFLAGS += -Ifitz -Imupdf -Wall
+CFLAGS += -Ifitz -Imupdf -Ixps -Wall
ifeq "$(build)" "debug"
CFLAGS += -pipe -g
diff --git a/Makethird b/Makethird
index d74f1176..bef43aea 100644
--- a/Makethird
+++ b/Makethird
@@ -9,6 +9,27 @@ 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/xps/ghostxps.h b/xps/muxps.h
index 3f06a80d..f2145d2f 100644
--- a/xps/ghostxps.h
+++ b/xps/muxps.h
@@ -1,88 +1,14 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* combined internal header for the XPS interpreter */
-
-#include "memory_.h"
-#include "math_.h"
-
-#include <stdlib.h>
-#include <ctype.h> /* for toupper() */
-
-#include "gp.h"
-
-#include "gsgc.h"
-#include "gstypes.h"
-#include "gsstate.h"
-#include "gsmatrix.h"
-#include "gscoord.h"
-#include "gsmemory.h"
-#include "gsparam.h"
-#include "gsdevice.h"
-#include "scommon.h"
-#include "gdebug.h"
-#include "gserror.h"
-#include "gserrors.h"
-#include "gspaint.h"
-#include "gspath.h"
-#include "gsimage.h"
-#include "gscspace.h"
-#include "gsptype1.h"
-#include "gscolor2.h"
-#include "gscolor3.h"
-#include "gsutil.h"
-#include "gsicc.h"
-
-#include "gstrans.h"
-
-#include "gxpath.h" /* gsshade.h depends on it */
-#include "gxfixed.h" /* gsshade.h depends on it */
-#include "gxmatrix.h" /* gxtype1.h depends on it */
-#include "gsshade.h"
-#include "gsfunc.h"
-#include "gsfunc3.h" /* we use stitching and exponential interp */
-
-#include "gxfont.h"
-#include "gxchar.h"
-#include "gxcolor2.h" /* Required for definition of gs_pattern1_instance_t */
-#include "gxtype1.h"
-#include "gxfont1.h"
-#include "gxfont42.h"
-#include "gxfcache.h"
-#include "gxistate.h"
-
-#include "gzstate.h"
-#include "gzpath.h"
-#include "gzcpath.h"
-
-#include "gsicc_manage.h"
-#include "gscms.h"
-#include "gsicc_cache.h"
-
-#include "zlib.h"
-
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a) < (b) ? (b) : (a))
-#endif
-#ifndef ABS
-#define ABS(a) ((a) < 0 ? -(a) : (a))
+#ifndef _MUXPS_H_
+#define _MUXPS_H_
+
+#ifndef _FITZ_H_
+#error "fitz.h must be included before muxps.h"
#endif
+typedef unsigned char byte;
+
/*
- * XPS and ZIP contants.
+ * XPS and ZIP constants.
*/
typedef struct xps_context_s xps_context_t;
@@ -103,16 +29,10 @@ typedef struct xps_context_s xps_context_t;
* Memory, and string functions.
*/
-void * xps_realloc_imp(xps_context_t *ctx, void *ptr, int size, const char *func);
-
-#define xps_alloc(ctx, size) \
- ((void*)gs_alloc_bytes(ctx->memory, size, __func__))
-#define xps_realloc(ctx, ptr, size) \
- xps_realloc_imp(ctx, ptr, size, __func__)
-#define xps_strdup(ctx, str) \
- xps_strdup_imp(ctx, str, __func__)
-#define xps_free(ctx, ptr) \
- gs_free_object(ctx->memory, ptr, __func__)
+#define xps_alloc(ctx, size) fz_malloc(size)
+#define xps_realloc(ctx, ptr, size) fz_realloc(ptr, size, 1)
+#define xps_strdup(ctx, str) fz_strdup(str)
+#define xps_free(ctx, ptr) fz_free(ptr)
size_t xps_strlcpy(char *destination, const char *source, size_t size);
size_t xps_strlcat(char *destination, const char *source, size_t size);
@@ -172,6 +92,7 @@ struct xps_page_s
char *name;
int width;
int height;
+ struct xps_item_s *root;
xps_page_t *next;
};
@@ -193,14 +114,13 @@ struct xps_image_s
int width;
int height;
int stride;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
int comps;
int hasalpha; /* chunky alpha */
int bits;
int xres;
int yres;
byte *samples;
- byte *alpha; /* isolated alpha plane */
byte *profile;
int profilesize;
};
@@ -220,48 +140,19 @@ void xps_free_image(xps_context_t *ctx, xps_image_t *image);
* Fonts.
*/
-typedef struct xps_font_s xps_font_t;
typedef struct xps_glyph_metrics_s xps_glyph_metrics_t;
-struct xps_font_s
-{
- byte *data;
- int length;
- gs_font *font;
-
- int subfontid;
- int cmaptable;
- int cmapsubcount;
- int cmapsubtable;
- int usepua;
-
- /* these are for CFF opentypes only */
- byte *cffdata;
- byte *cffend;
- byte *gsubrs;
- byte *subrs;
- byte *charstrings;
-};
-
struct xps_glyph_metrics_s
{
float hadv, vadv, vorg;
};
-xps_font_t *xps_new_font(xps_context_t *ctx, byte *buf, int buflen, int index);
-void xps_free_font(xps_context_t *ctx, xps_font_t *font);
+int xps_count_font_encodings(fz_font *font);
+void xps_identify_font_encoding(fz_font *font, int idx, int *pid, int *eid);
+void xps_select_font_encoding(fz_font *font, int idx);
+int xps_encode_font_char(fz_font *font, int key);
-int xps_count_font_encodings(xps_font_t *font);
-void xps_identify_font_encoding(xps_font_t *font, int idx, int *pid, int *eid);
-void xps_select_font_encoding(xps_font_t *font, int idx);
-int xps_encode_font_char(xps_font_t *font, int key);
-
-void xps_measure_font_glyph(xps_context_t *ctx, xps_font_t *font, int gid, xps_glyph_metrics_t *mtx);
-
-int xps_find_sfnt_table(xps_font_t *font, const char *name, int *lengthp);
-void xps_load_sfnt_name(xps_font_t *font, char *namep);
-int xps_init_truetype_font(xps_context_t *ctx, xps_font_t *font);
-int xps_init_postscript_font(xps_context_t *ctx, xps_font_t *font);
+void xps_measure_font_glyph(xps_context_t *ctx, fz_font *font, int gid, xps_glyph_metrics_t *mtx);
void xps_debug_path(xps_context_t *ctx);
@@ -269,9 +160,9 @@ void xps_debug_path(xps_context_t *ctx);
* Colorspaces and colors.
*/
-gs_color_space *xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profile);
-void xps_parse_color(xps_context_t *ctx, char *base_uri, char *hexstring, gs_color_space **csp, float *samples);
-void xps_set_color(xps_context_t *ctx, gs_color_space *colorspace, float *samples);
+fz_colorspace *xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profile);
+void xps_parse_color(xps_context_t *ctx, char *base_uri, char *hexstring, fz_colorspace **csp, float *samples);
+void xps_set_color(xps_context_t *ctx, fz_colorspace *colorspace, float *samples);
/*
* XML document model
@@ -313,33 +204,34 @@ void xps_debug_resource_dictionary(xps_resource_t *dict);
* Fixed page/graphics parsing.
*/
-int xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part);
-int xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_glyphs(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_solid_color_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_linear_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_radial_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-
-int xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root, int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*), void *user);
-
-void xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, gs_matrix *matrix);
-void xps_parse_render_transform(xps_context_t *ctx, char *text, gs_matrix *matrix);
-void xps_parse_rectangle(xps_context_t *ctx, char *text, gs_rect *rect);
+int xps_load_fixed_page(xps_context_t *ctx, xps_page_t *page);
+int xps_parse_fixed_page(xps_context_t *ctx, fz_matrix ctm, xps_page_t *page);
+int xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_path(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_solid_color_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_linear_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_radial_gradient_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+
+int xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, int (*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*), void *user);
+
+void xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, fz_matrix *matrix);
+void xps_parse_render_transform(xps_context_t *ctx, char *text, fz_matrix *matrix);
+void xps_parse_rectangle(xps_context_t *ctx, char *text, fz_rect *rect);
void xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom);
void xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *root, int stroking);
-int xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
+int xps_begin_opacity(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
void xps_end_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, char *opacity_att, xps_item_t *opacity_mask_tag);
-int xps_parse_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-int xps_parse_element(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
+int xps_parse_element(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node);
-void xps_clip(xps_context_t *ctx);
-void xps_fill(xps_context_t *ctx);
-void xps_bounds_in_user_space(xps_context_t *ctx, gs_rect *user);
+void xps_fill(xps_context_t *ctx, fz_matrix ctm);
+void xps_clip(xps_context_t *ctx, fz_matrix ctm);
+void xps_bounds_in_user_space(xps_context_t *ctx, fz_rect *user);
int xps_element_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *node);
int xps_resource_dictionary_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *node);
@@ -361,16 +253,6 @@ struct xps_entry_s
struct xps_context_s
{
- void *instance;
- gs_memory_t *memory;
- gs_state *pgs;
- gs_font_dir *fontdir;
-
- gs_color_space *gray;
- gs_color_space *srgb;
- gs_color_space *scrgb;
- gs_color_space *cmyk;
-
char *directory;
FILE *file;
int zip_count;
@@ -404,9 +286,24 @@ struct xps_context_s
* 1=nonzero, 0=evenodd
*/
int fill_rule;
+
+ /* Current path being accumulated */
+ fz_path *path;
+
+ /* Current color */
+ fz_colorspace *colorspace;
+ float color[8];
+ float alpha;
+
+ /* Current device */
+ fz_device *dev;
};
-int xps_process_file(xps_context_t *ctx, char *filename);
+int xps_read_and_process_page_part(xps_context_t *ctx, fz_matrix ctm, char *name);
+int xps_open_file(xps_context_t *ctx, char *filename);
+int xps_count_pages(xps_context_t *ctx);
+xps_page_t *xps_load_page(xps_context_t *ctx, int number);
+xps_context_t *xps_new_context(void);
+int xps_free_context(xps_context_t *ctx);
-/* end of page device callback foo */
-int xps_show_page(xps_context_t *ctx, int num_copies, int flush);
+#endif
diff --git a/xps/xpsanalyze.c b/xps/xpsanalyze.c
index 6e2f9d3e..41dc28c6 100644
--- a/xps/xpsanalyze.c
+++ b/xps/xpsanalyze.c
@@ -1,22 +1,10 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
/* XPS interpreter - analyze page checking for transparency.
* This is a stripped down parser that looks for alpha values < 1.0 in
* any part of the page.
*/
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
static int
xps_remote_resource_dictionary_has_transparency(xps_context_t *ctx, char *base_uri, char *source_att)
@@ -47,7 +35,7 @@ static int
xps_gradient_stops_have_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
{
xps_item_t *node;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
char *color_att;
float samples[32];
@@ -111,7 +99,7 @@ xps_brush_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
char *color_att;
xps_item_t *node;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
float samples[32];
if (!strcmp(xps_tag(root), "SolidColorBrush"))
@@ -266,7 +254,7 @@ xps_element_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *nod
char *stroke_att;
char *fill_att;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
float samples[32];
stroke_att = xps_att(node, "Stroke");
diff --git a/xps/xpscolor.c b/xps/xpscolor.c
index dcc7b0ca..2c701c4a 100644
--- a/xps/xpscolor.c
+++ b/xps/xpscolor.c
@@ -1,43 +1,25 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - color functions */
-
-#include "ghostxps.h"
-
-#include "stream.h" /* for sizeof(stream) to work */
+#include <ctype.h> /* for toupper() */
void
-xps_set_color(xps_context_t *ctx, gs_color_space *cs, float *samples)
+xps_set_color(xps_context_t *ctx, fz_colorspace *colorspace, float *samples)
{
- gs_client_color cc;
- int i, n;
+ int i;
if (ctx->opacity_only)
{
- gs_setopacityalpha(ctx->pgs, 1.0);
- gs_setgray(ctx->pgs, samples[0]);
+ ctx->colorspace = fz_devicegray;
+ ctx->color[0] = samples[0];
+ ctx->alpha = 1.0;
}
else
{
- n = cs_num_components(cs);
- cc.pattern = 0;
- for (i = 0; i < n; i++)
- cc.paint.values[i] = samples[i + 1];
-
- gs_setopacityalpha(ctx->pgs, samples[0]);
- gs_setcolorspace(ctx->pgs, cs);
- gs_setcolor(ctx->pgs, &cc);
+ ctx->colorspace = colorspace;
+ for (i = 0; i < colorspace->n; i++)
+ ctx->color[i] = samples[i + 1];
+ ctx->alpha = samples[0];
}
}
@@ -61,14 +43,14 @@ static int count_commas(char *s)
void
xps_parse_color(xps_context_t *ctx, char *base_uri, char *string,
- gs_color_space **csp, float *samples)
+ fz_colorspace **csp, float *samples)
{
char *p;
int i, n;
char buf[1024];
char *profile;
- *csp = ctx->srgb;
+ *csp = fz_devicergb;
samples[0] = 1.0;
samples[1] = 0.0;
@@ -100,8 +82,6 @@ xps_parse_color(xps_context_t *ctx, char *base_uri, char *string,
else if (string[0] == 's' && string[1] == 'c' && string[2] == '#')
{
- *csp = ctx->scrgb;
-
if (count_commas(string) == 2)
sscanf(string, "sc#%g,%g,%g", samples + 1, samples + 2, samples + 3);
if (count_commas(string) == 3)
@@ -116,7 +96,7 @@ xps_parse_color(xps_context_t *ctx, char *base_uri, char *string,
profile = strchr(buf, ' ');
if (!profile)
{
- gs_warn1("cannot find icc profile uri in '%s'", string);
+ fz_warn("cannot find icc profile uri in '%s'", string);
return;
}
@@ -124,7 +104,7 @@ xps_parse_color(xps_context_t *ctx, char *base_uri, char *string,
p = strchr(profile, ' ');
if (!p)
{
- gs_warn1("cannot find component values in '%s'", profile);
+ fz_warn("cannot find component values in '%s'", profile);
return;
}
@@ -152,20 +132,20 @@ xps_parse_color(xps_context_t *ctx, char *base_uri, char *string,
/* Default fallbacks if the ICC stuff fails */
switch (n)
{
- case 2: *csp = ctx->gray; break; /* alpha + tint */
- case 4: *csp = ctx->srgb; break; /* alpha + RGB */
- case 5: *csp = ctx->cmyk; break; /* alpha + CMYK */
- default: *csp = ctx->gray; break;
+ case 2: *csp = fz_devicegray; break; /* alpha + tint */
+ case 4: *csp = fz_devicergb; break; /* alpha + RGB */
+ case 5: *csp = fz_devicecmyk; break; /* alpha + CMYK */
+ default: *csp = fz_devicegray; break;
}
}
}
}
-gs_color_space *
+fz_colorspace *
xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename)
{
- gs_color_space *space;
- cmm_profile_t *profile;
+#if 0
+ fz_colorspace *space;
xps_part_t *part;
char partname[1024];
@@ -178,9 +158,9 @@ xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename)
{
part = xps_read_part(ctx, partname);
- /* Problem finding profile. Don't fail, just use default */
+ /* Problem finding profile. Don't fail, just use default */
if (!part) {
- gs_warn1("cannot find icc profile part: %s", partname);
+ fz_warn("cannot find icc profile part: %s", partname);
return NULL;
}
@@ -194,11 +174,11 @@ xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename)
/* Parse */
gsicc_init_profile_info(profile);
- /* Problem with profile. Don't fail, just use the default */
+ /* Problem with profile. Don't fail, just use the default */
if (profile->profile_handle == NULL)
{
gsicc_profile_reference(profile, -1);
- gs_warn1("there was a problem with the profile: %s", partname);
+ fz_warn("there was a problem with the profile: %s", partname);
return NULL;
}
@@ -215,20 +195,23 @@ xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename)
}
return space;
+#else
+ return NULL;
+#endif
}
int
-xps_parse_solid_color_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
+xps_parse_solid_color_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node)
{
char *opacity_att;
char *color_att;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
float samples[32];
color_att = xps_att(node, "Color");
opacity_att = xps_att(node, "Opacity");
- colorspace = ctx->srgb;
+ colorspace = fz_devicergb;
samples[0] = 1.0;
samples[1] = 0.0;
samples[2] = 0.0;
@@ -242,7 +225,7 @@ xps_parse_solid_color_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *
xps_set_color(ctx, colorspace, samples);
- xps_fill(ctx);
+ xps_fill(ctx, ctm);
return 0;
}
diff --git a/xps/xpscommon.c b/xps/xpscommon.c
index 6908b3c5..4ba38f7c 100644
--- a/xps/xpscommon.c
+++ b/xps/xpscommon.c
@@ -1,56 +1,37 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - common parse functions */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
int
-xps_parse_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
+xps_parse_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node)
{
if (!strcmp(xps_tag(node), "SolidColorBrush"))
- return xps_parse_solid_color_brush(ctx, base_uri, dict, node);
+ return xps_parse_solid_color_brush(ctx, ctm, base_uri, dict, node);
if (!strcmp(xps_tag(node), "ImageBrush"))
- {
- int code = xps_parse_image_brush(ctx, base_uri, dict, node);
- if (code)
- gs_catch(code, "ignoring error in image brush");
- return gs_okay;
- }
+ return xps_parse_image_brush(ctx, ctm, base_uri, dict, node);
if (!strcmp(xps_tag(node), "VisualBrush"))
- return xps_parse_visual_brush(ctx, base_uri, dict, node);
+ return xps_parse_visual_brush(ctx, ctm, base_uri, dict, node);
if (!strcmp(xps_tag(node), "LinearGradientBrush"))
- return xps_parse_linear_gradient_brush(ctx, base_uri, dict, node);
+ return xps_parse_linear_gradient_brush(ctx, ctm, base_uri, dict, node);
if (!strcmp(xps_tag(node), "RadialGradientBrush"))
- return xps_parse_radial_gradient_brush(ctx, base_uri, dict, node);
- return gs_throw1(-1, "unknown brush tag: %s", xps_tag(node));
+ return xps_parse_radial_gradient_brush(ctx, ctm, base_uri, dict, node);
+ return fz_throw("unknown brush tag: %s", xps_tag(node));
}
int
-xps_parse_element(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *node)
+xps_parse_element(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *node)
{
if (!strcmp(xps_tag(node), "Path"))
- return xps_parse_path(ctx, base_uri, dict, node);
+ return xps_parse_path(ctx, ctm, base_uri, dict, node);
if (!strcmp(xps_tag(node), "Glyphs"))
- return xps_parse_glyphs(ctx, base_uri, dict, node);
+ return xps_parse_glyphs(ctx, ctm, base_uri, dict, node);
if (!strcmp(xps_tag(node), "Canvas"))
- return xps_parse_canvas(ctx, base_uri, dict, node);
+ return xps_parse_canvas(ctx, ctm, base_uri, dict, node);
/* skip unknown tags (like Foo.Resources and similar) */
return 0;
}
void
-xps_parse_render_transform(xps_context_t *ctx, char *transform, gs_matrix *matrix)
+xps_parse_render_transform(xps_context_t *ctx, char *transform, fz_matrix *matrix)
{
float args[6];
char *s = transform;
@@ -69,17 +50,17 @@ xps_parse_render_transform(xps_context_t *ctx, char *transform, gs_matrix *matri
s++;
}
- matrix->xx = args[0]; matrix->xy = args[1];
- matrix->yx = args[2]; matrix->yy = args[3];
- matrix->tx = args[4]; matrix->ty = args[5];
+ matrix->a = args[0]; matrix->b = args[1];
+ matrix->c = args[2]; matrix->d = args[3];
+ matrix->e = args[4]; matrix->f = args[5];
}
void
-xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, gs_matrix *matrix)
+xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, fz_matrix *matrix)
{
char *transform;
- gs_make_identity(matrix);
+ *matrix = fz_identity;
if (!strcmp(xps_tag(root), "MatrixTransform"))
{
@@ -90,7 +71,7 @@ xps_parse_matrix_transform(xps_context_t *ctx, xps_item_t *root, gs_matrix *matr
}
void
-xps_parse_rectangle(xps_context_t *ctx, char *text, gs_rect *rect)
+xps_parse_rectangle(xps_context_t *ctx, char *text, fz_rect *rect)
{
float args[4];
char *s = text;
@@ -108,8 +89,8 @@ xps_parse_rectangle(xps_context_t *ctx, char *text, gs_rect *rect)
s++;
}
- rect->p.x = args[0];
- rect->p.y = args[1];
- rect->q.x = args[0] + args[2];
- rect->q.y = args[1] + args[3];
+ rect->x0 = args[0];
+ rect->y0 = args[1];
+ rect->x1 = args[0] + args[2];
+ rect->y1 = args[1] + args[3];
}
diff --git a/xps/xpscrc.c b/xps/xpscrc.c
index 7dea3c32..d5d4acd8 100644
--- a/xps/xpscrc.c
+++ b/xps/xpscrc.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - CRC-32 implementation */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
static const unsigned long crctab[256] =
{
diff --git a/xps/xpsdoc.c b/xps/xpsdoc.c
index 3e9f7c96..c0e83e4a 100644
--- a/xps/xpsdoc.c
+++ b/xps/xpsdoc.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - document parsing */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
#include <expat.h>
@@ -50,17 +36,17 @@ xps_debug_fixdocseq(xps_context_t *ctx)
xps_page_t *page = ctx->first_page;
if (ctx->start_part)
- dprintf1("start part %s\n", ctx->start_part);
+ printf("start part %s\n", ctx->start_part);
while (fixdoc)
{
- dprintf1("fixdoc %s\n", fixdoc->name);
+ printf("fixdoc %s\n", fixdoc->name);
fixdoc = fixdoc->next;
}
while (page)
{
- dprintf3("page %s w=%d h=%d\n", page->name, page->width, page->height);
+ printf("page %s w=%d h=%d\n", page->name, page->width, page->height);
page = page->next;
}
}
@@ -75,8 +61,6 @@ xps_add_fixed_document(xps_context_t *ctx, char *name)
if (!strcmp(fixdoc->name, name))
return;
- if_debug1('|', "doc: adding fixdoc %s\n", name);
-
fixdoc = xps_alloc(ctx, sizeof(xps_document_t));
fixdoc->name = xps_strdup(ctx, name);
fixdoc->next = NULL;
@@ -118,12 +102,11 @@ xps_add_fixed_page(xps_context_t *ctx, char *name, int width, int height)
if (!strcmp(page->name, name))
return;
- if_debug1('|', "doc: adding page %s\n", name);
-
page = xps_alloc(ctx, sizeof(xps_page_t));
page->name = xps_strdup(ctx, name);
page->width = width;
page->height = height;
+ page->root = NULL;
page->next = NULL;
if (!ctx->first_page)
@@ -257,7 +240,7 @@ xps_parse_metadata(xps_context_t *ctx, xps_part_t *part)
xp = XML_ParserCreate(NULL);
if (!xp)
- return gs_throw(-1, "cannot create XML parser");
+ return fz_throw("cannot create XML parser");
XML_SetUserData(xp, ctx);
XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER);
@@ -271,7 +254,7 @@ xps_parse_metadata(xps_context_t *ctx, xps_part_t *part)
ctx->part_uri = NULL;
if (code == 0)
- return gs_throw1(-1, "cannot parse XML in part: %s", part->name);
+ return fz_throw("cannot parse XML in part: %s", part->name);
return 0;
}
diff --git a/xps/xpsfont.c b/xps/xpsfont.c
index 93adf71d..ecedfabb 100644
--- a/xps/xpsfont.c
+++ b/xps/xpsfont.c
@@ -1,532 +1,53 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - general font functions */
-
-#include "ghostxps.h"
-
-static void xps_load_sfnt_cmap(xps_font_t *font);
-
-/*
- * Big-endian memory accessor functions
- */
-
-static inline int s16(byte *p)
-{
- return (signed short)( (p[0] << 8) | p[1] );
-}
-
-static inline int u16(byte *p)
-{
- return (p[0] << 8) | p[1];
-}
-
-static inline int u24(byte *p)
-{
- return (p[0] << 16) | (p[1] << 8) | p[2];
-}
-
-static inline int u32(byte *p)
-{
- return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-}
-
-xps_font_t *
-xps_new_font(xps_context_t *ctx, byte *buf, int buflen, int index)
-{
- xps_font_t *font;
- int code;
-
- font = xps_alloc(ctx, sizeof(xps_font_t));
- if (!font)
- {
- gs_throw(-1, "out of memory");
- return NULL;
- }
-
- font->data = buf;
- font->length = buflen;
- font->font = NULL;
-
- font->subfontid = index;
- font->cmaptable = 0;
- font->cmapsubcount = 0;
- font->cmapsubtable = 0;
- font->usepua = 0;
-
- font->cffdata = 0;
- font->cffend = 0;
- font->gsubrs = 0;
- font->subrs = 0;
- font->charstrings = 0;
-
- if (memcmp(font->data, "OTTO", 4) == 0)
- code = xps_init_postscript_font(ctx, font);
- else if (memcmp(font->data, "\0\1\0\0", 4) == 0)
- code = xps_init_truetype_font(ctx, font);
- else if (memcmp(font->data, "true", 4) == 0)
- code = xps_init_truetype_font(ctx, font);
- else if (memcmp(font->data, "ttcf", 4) == 0)
- code = xps_init_truetype_font(ctx, font);
- else
- {
- xps_free_font(ctx, font);
- gs_throw(-1, "not an opentype font");
- return NULL;
- }
-
- if (code < 0)
- {
- xps_free_font(ctx, font);
- gs_rethrow(-1, "cannot init font");
- return NULL;
- }
-
- xps_load_sfnt_cmap(font);
-
- return font;
-}
-
-void
-xps_free_font(xps_context_t *ctx, xps_font_t *font)
-{
- if (font->font)
- {
- gs_font_finalize(font->font);
- gs_free_object(ctx->memory, font->font, "font object");
- }
- xps_free(ctx, font);
-}
-
-/*
- * Find the offset and length of an SFNT table.
- * Return -1 if no table by the specified name is found.
- */
-
-int
-xps_find_sfnt_table(xps_font_t *font, const char *name, int *lengthp)
-{
- int offset;
- int ntables;
- int i;
-
- if (font->length < 12)
- return -1;
-
- if (!memcmp(font->data, "ttcf", 4))
- {
- int nfonts = u32(font->data + 8);
- if (font->subfontid < 0 || font->subfontid >= nfonts)
- {
- gs_warn("Invalid subfont ID");
- return -1;
- }
- offset = u32(font->data + 12 + font->subfontid * 4);
- }
- else
- {
- offset = 0;
- }
-
- ntables = u16(font->data + offset + 4);
- if (font->length < offset + 12 + ntables * 16)
- return -1;
-
- for (i = 0; i < ntables; i++)
- {
- byte *entry = font->data + offset + 12 + i * 16;
- if (!memcmp(entry, name, 4))
- {
- if (lengthp)
- *lengthp = u32(entry + 12);
- return u32(entry + 8);
- }
- }
-
- return -1;
-}
-
-/*
- * Get the windows truetype font file name - position 4 in the name table.
- */
-void
-xps_load_sfnt_name(xps_font_t *font, char *namep)
-{
- byte *namedata;
- int offset, length;
- int format, count, stringoffset;
- int i;
-
- strcpy(namep, "Unknown");
-
- offset = xps_find_sfnt_table(font, "name", &length);
- if (offset < 0 || length < 6)
- {
- gs_warn("cannot find name table");
- return;
- }
-
- namedata = font->data + offset;
-
- format = u16(namedata + 0);
- count = u16(namedata + 2);
- stringoffset = u16(namedata + 4);
-
- for (i = 0; i < count; i++)
- {
- byte *record = namedata + 6 + i * 12;
- int pid = u16(record + 0);
- int eid = u16(record + 2);
- int langid = u16(record + 4);
- int nameid = u16(record + 6);
- length = u16(record + 8);
- offset = u16(record + 10);
-
- /* Mac Roman English */
- if (pid == 1 && eid == 0 && langid == 0)
- {
- /* Full font name or postscript name */
- if (nameid == 4 || nameid == 6)
- {
- memcpy(namep, namedata + stringoffset + offset, length);
- namep[length] = 0;
- }
- }
- }
-}
-
-/*
- * Locate the 'cmap' table and count the number of subtables.
- */
-
-static void
-xps_load_sfnt_cmap(xps_font_t *font)
-{
- byte *cmapdata;
- int offset, length;
- int nsubtables;
-
- offset = xps_find_sfnt_table(font, "cmap", &length);
- if (offset < 0 || length < 4)
- {
- gs_warn("cannot find cmap table");
- return;
- }
-
- cmapdata = font->data + offset;
-
- nsubtables = u16(cmapdata + 2);
- if (nsubtables < 0 || length < 4 + nsubtables * 8)
- {
- gs_warn("cannot find cmap sub-tables");
- return;
- }
-
- font->cmaptable = offset;
- font->cmapsubcount = nsubtables;
- font->cmapsubtable = 0;
-}
-
-/*
- * Return the number of cmap subtables.
- */
+#include <ft2build.h>
+#include FT_FREETYPE_H
int
-xps_count_font_encodings(xps_font_t *font)
+xps_count_font_encodings(fz_font *font)
{
- return font->cmapsubcount;
+ FT_Face face = font->ftface;
+ return face->num_charmaps;
}
-/*
- * Extract PlatformID and EncodingID for a cmap subtable.
- */
-
void
-xps_identify_font_encoding(xps_font_t *font, int idx, int *pid, int *eid)
+xps_identify_font_encoding(fz_font *font, int idx, int *pid, int *eid)
{
- byte *cmapdata, *entry;
- if (idx < 0 || idx >= font->cmapsubcount)
- return;
- cmapdata = font->data + font->cmaptable;
- entry = cmapdata + 4 + idx * 8;
- *pid = u16(entry + 0);
- *eid = u16(entry + 2);
+ FT_Face face = font->ftface;
+ *pid = face->charmaps[idx]->platform_id;
+ *eid = face->charmaps[idx]->encoding_id;
}
-/*
- * Select a cmap subtable for use with encoding functions.
- */
-
void
-xps_select_font_encoding(xps_font_t *font, int idx)
+xps_select_font_encoding(fz_font *font, int idx)
{
- byte *cmapdata, *entry;
- int pid, eid;
- if (idx < 0 || idx >= font->cmapsubcount)
- return;
- cmapdata = font->data + font->cmaptable;
- entry = cmapdata + 4 + idx * 8;
- pid = u16(entry + 0);
- eid = u16(entry + 2);
- font->cmapsubtable = font->cmaptable + u32(entry + 4);
- font->usepua = (pid == 3 && eid == 0);
-}
-
-/*
- * Encode a character using the selected cmap subtable.
- * TODO: extend this to cover more cmap formats.
- */
-
-static int
-xps_encode_font_char_imp(xps_font_t *font, int code)
-{
- byte *table;
-
- /* no cmap selected: return identity */
- if (font->cmapsubtable <= 0)
- return code;
-
- table = font->data + font->cmapsubtable;
-
- switch (u16(table))
- {
- case 0: /* Apple standard 1-to-1 mapping. */
- return table[code + 6];
-
- case 4: /* Microsoft/Adobe segmented mapping. */
- {
- int segCount2 = u16(table + 6);
- byte *endCount = table + 14;
- byte *startCount = endCount + segCount2 + 2;
- byte *idDelta = startCount + segCount2;
- byte *idRangeOffset = idDelta + segCount2;
- int i2;
-
- for (i2 = 0; i2 < segCount2 - 3; i2 += 2)
- {
- int delta, roff;
- int start = u16(startCount + i2);
- int glyph;
-
- if ( code < start )
- return 0;
- if ( code > u16(endCount + i2) )
- continue;
- delta = s16(idDelta + i2);
- roff = s16(idRangeOffset + i2);
- if ( roff == 0 )
- {
- return ( code + delta ) & 0xffff; /* mod 65536 */
- return 0;
- }
- glyph = u16(idRangeOffset + i2 + roff + ((code - start) << 1));
- return (glyph == 0 ? 0 : glyph + delta);
- }
-
- /*
- * The TrueType documentation says that the last range is
- * always supposed to end with 0xffff, so this shouldn't
- * happen; however, in some real fonts, it does.
- */
- return 0;
- }
-
- case 6: /* Single interval lookup. */
- {
- int firstCode = u16(table + 6);
- int entryCount = u16(table + 8);
- if ( code < firstCode || code >= firstCode + entryCount )
- return 0;
- return u16(table + 10 + ((code - firstCode) << 1));
- }
-
- case 10: /* Trimmed array (like 6) */
- {
- int startCharCode = u32(table + 12);
- int numChars = u32(table + 16);
- if ( code < startCharCode || code >= startCharCode + numChars )
- return 0;
- return u32(table + 20 + (code - startCharCode) * 4);
- }
-
- case 12: /* Segmented coverage. (like 4) */
- {
- int nGroups = u32(table + 12);
- byte *group = table + 16;
- int i;
-
- for (i = 0; i < nGroups; i++)
- {
- int startCharCode = u32(group + 0);
- int endCharCode = u32(group + 4);
- int startGlyphID = u32(group + 8);
- if ( code < startCharCode )
- return 0;
- if ( code <= endCharCode )
- return startGlyphID + (code - startCharCode);
- group += 12;
- }
-
- return 0;
- }
-
- case 2: /* High-byte mapping through table. */
- case 8: /* Mixed 16-bit and 32-bit coverage (like 2) */
- default:
- gs_warn1("unknown cmap format: %d\n", u16(table));
- return 0;
- }
-
- return 0;
+ FT_Face face = font->ftface;
+ FT_Set_Charmap(face, face->charmaps[idx]);
}
int
-xps_encode_font_char(xps_font_t *font, int code)
+xps_encode_font_char(fz_font *font, int code)
{
- int gid = xps_encode_font_char_imp(font, code);
- if (gid == 0 && font->usepua)
- gid = xps_encode_font_char_imp(font, 0xF000 | code);
+ FT_Face face = font->ftface;
+ int gid = FT_Get_Char_Index(face, code);
+ if (gid == 0 && face->charmap->platform_id == 3 && face->charmap->encoding_id == 0)
+ gid = FT_Get_Char_Index(face, 0xF000 | code);
return gid;
}
-/*
- * Get glyph metrics by parsing TTF tables manually.
- * XPS needs more and different metrics than postscript/ghostscript
- * use so the native ghostscript functions are not adequate.
- */
-
void
-xps_measure_font_glyph(xps_context_t *ctx, xps_font_t *font, int gid, xps_glyph_metrics_t *mtx)
+xps_measure_font_glyph(xps_context_t *ctx, fz_font *font, int gid, xps_glyph_metrics_t *mtx)
{
- int head, format, loca, glyf;
- int ofs, len;
- int idx, i, n;
int hadv, vadv, vorg;
- int vtop, ymax, desc;
int scale;
- /* some insane defaults */
-
scale = 1000; /* units-per-em */
hadv = 500;
vadv = -1000;
vorg = 1000;
- /*
- * Horizontal metrics are easy.
- */
-
- ofs = xps_find_sfnt_table(font, "hhea", &len);
- if (ofs < 0 || len < 2 * 18)
- {
- gs_warn("hhea table is too short");
- return;
- }
-
- vorg = s16(font->data + ofs + 4); /* ascender is default vorg */
- desc = s16(font->data + ofs + 6); /* descender */
- if (desc < 0)
- desc = -desc;
- n = u16(font->data + ofs + 17 * 2);
-
- ofs = xps_find_sfnt_table(font, "hmtx", &len);
- if (ofs < 0)
- {
- gs_warn("cannot find hmtx table");
- return;
- }
-
- idx = gid;
- if (idx > n - 1)
- idx = n - 1;
-
- hadv = u16(font->data + ofs + idx * 4);
- vadv = 0;
-
- /*
- * Vertical metrics are hairy (with missing tables).
- */
-
- head = xps_find_sfnt_table(font, "head", &len);
- if (head > 0)
- {
- scale = u16(font->data + head + 18); /* units per em */
- }
-
- ofs = xps_find_sfnt_table(font, "OS/2", &len);
- if (ofs > 0 && len > 70)
- {
- vorg = s16(font->data + ofs + 68); /* sTypoAscender */
- desc = s16(font->data + ofs + 70); /* sTypoDescender */
- if (desc < 0)
- desc = -desc;
- }
-
- ofs = xps_find_sfnt_table(font, "vhea", &len);
- if (ofs > 0 && len >= 2 * 18)
- {
- n = u16(font->data + ofs + 17 * 2);
-
- ofs = xps_find_sfnt_table(font, "vmtx", &len);
- if (ofs < 0)
- {
- gs_warn("cannot find vmtx table");
- return;
- }
-
- idx = gid;
- if (idx > n - 1)
- idx = n - 1;
-
- vadv = u16(font->data + ofs + idx * 4);
- vtop = u16(font->data + ofs + idx * 4 + 2);
-
- glyf = xps_find_sfnt_table(font, "glyf", &len);
- loca = xps_find_sfnt_table(font, "loca", &len);
- if (head > 0 && glyf > 0 && loca > 0)
- {
- format = u16(font->data + head + 50); /* indexToLocaFormat */
-
- if (format == 0)
- ofs = u16(font->data + loca + gid * 2) * 2;
- else
- ofs = u32(font->data + loca + gid * 4);
-
- ymax = u16(font->data + glyf + ofs + 8); /* yMax */
-
- vorg = ymax + vtop;
- }
- }
-
- ofs = xps_find_sfnt_table(font, "VORG", &len);
- if (ofs > 0)
- {
- vorg = u16(font->data + ofs + 6);
- n = u16(font->data + ofs + 6);
- for (i = 0; i < n; i++)
- {
- if (u16(font->data + ofs + 8 + 4 * i) == gid)
- {
- vorg = s16(font->data + ofs + 8 + 4 * i + 2);
- break;
- }
- }
- }
-
- if (vadv == 0)
- vadv = vorg + desc;
-
mtx->hadv = hadv / (float) scale;
mtx->vadv = vadv / (float) scale;
mtx->vorg = vorg / (float) scale;
diff --git a/xps/xpsglyphs.c b/xps/xpsglyphs.c
index 4709c94b..76da97b1 100644
--- a/xps/xpsglyphs.c
+++ b/xps/xpsglyphs.c
@@ -1,21 +1,7 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - text drawing support */
-
-#include "ghostxps.h"
-
-#include <ctype.h>
+#include <ctype.h> /* for tolower() */
#define XPS_TEXT_BUFFER_SIZE 300
@@ -26,7 +12,7 @@ struct xps_text_buffer_s
int count;
float x[XPS_TEXT_BUFFER_SIZE + 1];
float y[XPS_TEXT_BUFFER_SIZE + 1];
- gs_glyph g[XPS_TEXT_BUFFER_SIZE];
+ int g[XPS_TEXT_BUFFER_SIZE];
};
static inline int unhex(int i)
@@ -36,45 +22,6 @@ static inline int unhex(int i)
return tolower(i) - 'a' + 10;
}
-void
-xps_debug_path(xps_context_t *ctx)
-{
- segment *seg;
- curve_segment *cseg;
-
- seg = (segment*)ctx->pgs->path->first_subpath;
- while (seg)
- {
- switch (seg->type)
- {
- case s_start:
- dprintf2("%g %g moveto\n",
- fixed2float(seg->pt.x) * 0.001,
- fixed2float(seg->pt.y) * 0.001);
- break;
- case s_line:
- dprintf2("%g %g lineto\n",
- fixed2float(seg->pt.x) * 0.001,
- fixed2float(seg->pt.y) * 0.001);
- break;
- case s_line_close:
- dputs("closepath\n");
- break;
- case s_curve:
- cseg = (curve_segment*)seg;
- dprintf6("%g %g %g %g %g %g curveto\n",
- fixed2float(cseg->p1.x) * 0.001,
- fixed2float(cseg->p1.y) * 0.001,
- fixed2float(cseg->p2.x) * 0.001,
- fixed2float(cseg->p2.y) * 0.001,
- fixed2float(seg->pt.x) * 0.001,
- fixed2float(seg->pt.y) * 0.001);
- break;
- }
- seg = seg->next;
- }
-}
-
/*
* Some fonts in XPS are obfuscated by XOR:ing the first 32 bytes of the
* data with the GUID in the fontname.
@@ -100,7 +47,7 @@ xps_deobfuscate_font_resource(xps_context_t *ctx, xps_part_t *part)
if (i != 32)
{
- gs_warn("cannot extract GUID from obfuscated font part name");
+ fz_warn("cannot extract GUID from obfuscated font part name");
return;
}
@@ -115,7 +62,7 @@ xps_deobfuscate_font_resource(xps_context_t *ctx, xps_part_t *part)
}
static void
-xps_select_best_font_encoding(xps_font_t *font)
+xps_select_best_font_encoding(fz_font *font)
{
static struct { int pid, eid; } xps_cmap_list[] =
{
@@ -147,7 +94,7 @@ xps_select_best_font_encoding(xps_font_t *font)
}
}
- gs_warn("could not find a suitable cmap");
+ fz_warn("could not find a suitable cmap");
}
/*
@@ -155,9 +102,10 @@ xps_select_best_font_encoding(xps_font_t *font)
*/
static int
-xps_flush_text_buffer(xps_context_t *ctx, xps_font_t *font,
+xps_flush_text_buffer(xps_context_t *ctx, fz_font *font,
xps_text_buffer_t *buf, int is_charpath)
{
+#if 0
gs_text_params_t params;
gs_text_enum_t *textenum;
float x = buf->x[0];
@@ -166,7 +114,6 @@ xps_flush_text_buffer(xps_context_t *ctx, xps_font_t *font,
int i;
// dprintf1("flushing text buffer (%d glyphs)\n", buf->count);
-
gs_moveto(ctx->pgs, x, y);
params.operation = TEXT_FROM_GLYPHS | TEXT_REPLACE_WIDTHS;
@@ -192,15 +139,15 @@ xps_flush_text_buffer(xps_context_t *ctx, xps_font_t *font,
code = gs_text_begin(ctx->pgs, &params, ctx->memory, &textenum);
if (code != 0)
- return gs_throw1(-1, "cannot gs_text_begin() (%d)", code);
+ return fz_throw("cannot gs_text_begin() (%d)", code);
code = gs_text_process(textenum);
if (code != 0)
- return gs_throw1(-1, "cannot gs_text_process() (%d)", code);
+ return fz_throw("cannot gs_text_process() (%d)", code);
gs_text_release(textenum, "gslt font render");
-
+#endif
buf->count = 0;
return 0;
@@ -293,7 +240,7 @@ xps_parse_glyph_metrics(char *s, float *advance, float *uofs, float *vofs)
* Calculate metrics for positioning.
*/
static int
-xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
+xps_parse_glyphs_imp(xps_context_t *ctx, fz_font *font, float size,
float originx, float originy, int is_sideways, int bidi_level,
char *indices, char *unicode, int is_charpath)
{
@@ -309,7 +256,7 @@ xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
buf.count = 0;
if (!unicode && !indices)
- return gs_throw(-1, "no text in glyphs element");
+ return fz_throw("no text in glyphs element");
if (us)
{
@@ -354,7 +301,7 @@ xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
{
int t = xps_utf8_to_ucs(&char_code, us, un);
if (t < 0)
- return gs_rethrow(-1, "error decoding UTF-8 string");
+ return fz_rethrow(-1, "error decoding UTF-8 string");
us += t; un -= t;
}
code_count --;
@@ -379,7 +326,7 @@ xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
}
#if 0
- dprintf6("glyph mapping (%d:%d)%d,%g,%g,%g\n",
+ printf("glyph mapping (%d:%d)%d,%g,%g,%g\n",
code_count, glyph_count, glyph_index,
advance, u_offset, v_offset);
#endif
@@ -394,7 +341,7 @@ xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
{
code = xps_flush_text_buffer(ctx, font, &buf, is_charpath);
if (code)
- return gs_rethrow(code, "cannot flush buffered text");
+ return fz_rethrow(code, "cannot flush buffered text");
}
if (is_sideways)
@@ -418,14 +365,14 @@ xps_parse_glyphs_imp(xps_context_t *ctx, xps_font_t *font, float size,
{
code = xps_flush_text_buffer(ctx, font, &buf, is_charpath);
if (code)
- return gs_rethrow(code, "cannot flush buffered text");
+ return fz_rethrow(code, "cannot flush buffered text");
}
return 0;
}
int
-xps_parse_glyphs(xps_context_t *ctx,
+xps_parse_glyphs(xps_context_t *ctx, fz_matrix ctm,
char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_item_t *node;
@@ -458,12 +405,12 @@ xps_parse_glyphs(xps_context_t *ctx,
char *fill_opacity_att = NULL;
xps_part_t *part;
- xps_font_t *font;
+ fz_font *font;
char partname[1024];
char *subfont;
- gs_matrix matrix;
+ fz_matrix matrix;
float font_size = 10.0;
int subfontid = 0;
int is_sideways = 0;
@@ -517,7 +464,7 @@ xps_parse_glyphs(xps_context_t *ctx,
*/
if (!font_size_att || !font_uri_att || !origin_x_att || !origin_y_att)
- return gs_throw(-1, "missing attributes in glyphs element");
+ return fz_throw("missing attributes in glyphs element");
if (!indices_att && !unicode_att)
return 0; /* nothing to draw */
@@ -545,7 +492,7 @@ xps_parse_glyphs(xps_context_t *ctx,
{
part = xps_read_part(ctx, partname);
if (!part)
- return gs_throw1(-1, "cannot find font resource part '%s'", partname);
+ return fz_throw("cannot find font resource part '%s'", partname);
/* deobfuscate if necessary */
if (strstr(part->name, ".odttf"))
@@ -553,9 +500,9 @@ xps_parse_glyphs(xps_context_t *ctx,
if (strstr(part->name, ".ODTTF"))
xps_deobfuscate_font_resource(ctx, part);
- font = xps_new_font(ctx, part->data, part->size, subfontid);
- if (!font)
- return gs_rethrow1(-1, "cannot load font resource '%s'", partname);
+ code = fz_newfontfrombuffer(&font, part->data, part->size, subfontid);
+ if (code)
+ return fz_rethrow(code, "cannot load font resource '%s'", partname);
xps_select_best_font_encoding(font);
@@ -568,12 +515,12 @@ xps_parse_glyphs(xps_context_t *ctx,
/*
* Set up graphics state.
*/
-
+#if 0
gs_gsave(ctx->pgs);
if (transform_att || transform_tag)
{
- gs_matrix transform;
+ fz_matrix transform;
if (transform_att)
xps_parse_render_transform(ctx, transform_att, &transform);
@@ -585,6 +532,7 @@ xps_parse_glyphs(xps_context_t *ctx,
if (clip_att || clip_tag)
{
+ ctx->path = fz_newpath();
if (clip_att)
xps_parse_abbreviated_geometry(ctx, clip_att);
if (clip_tag)
@@ -597,17 +545,17 @@ xps_parse_glyphs(xps_context_t *ctx,
gs_setfont(ctx->pgs, font->font);
gs_make_scaling(font_size, -font_size, &matrix);
if (is_sideways)
- gs_matrix_rotate(&matrix, 90.0, &matrix);
+ fz_matrix_rotate(&matrix, 90.0, &matrix);
gs_setcharmatrix(ctx->pgs, &matrix);
- gs_matrix_multiply(&matrix, &font->font->orig_FontMatrix, &font->font->FontMatrix);
+ fz_matrix_multiply(&matrix, &font->font->orig_FontMatrix, &font->font->FontMatrix);
code = xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
if (code)
{
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot create transparency group");
+ return fz_rethrow(code, "cannot create transparency group");
}
/*
@@ -624,7 +572,7 @@ xps_parse_glyphs(xps_context_t *ctx,
if (fill_att)
{
float samples[32];
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
if (fill_opacity_att)
samples[0] = atof(fill_opacity_att);
@@ -637,7 +585,7 @@ xps_parse_glyphs(xps_context_t *ctx,
{
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse glyphs data");
+ return fz_rethrow(code, "cannot parse glyphs data");
}
}
@@ -655,7 +603,7 @@ xps_parse_glyphs(xps_context_t *ctx,
{
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse glyphs data");
+ return fz_rethrow(code, "cannot parse glyphs data");
}
code = xps_parse_brush(ctx, fill_uri, dict, fill_tag);
@@ -663,13 +611,13 @@ xps_parse_glyphs(xps_context_t *ctx,
{
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse fill brush");
+ return fz_rethrow(code, "cannot parse fill brush");
}
}
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
gs_grestore(ctx->pgs);
-
+#endif
return 0;
}
diff --git a/xps/xpsgradient.c b/xps/xpsgradient.c
index 0c6bcf60..3bb95824 100644
--- a/xps/xpsgradient.c
+++ b/xps/xpsgradient.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - gradient support */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
#define MAX_STOPS 256
@@ -52,11 +38,9 @@ static int
xps_parse_gradient_stops(xps_context_t *ctx, char *base_uri, xps_item_t *node,
struct stop *stops, int maxcount)
{
- unsigned short sample_in[8], sample_out[8]; /* XPS allows up to 8 bands */
- gsicc_rendering_param_t rendering_params;
- gsicc_link_t *icclink;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
float sample[8];
+ float rgb[3];
int before, after;
int count;
int i, k;
@@ -77,53 +61,22 @@ xps_parse_gradient_stops(xps_context_t *ctx, char *base_uri, xps_item_t *node,
xps_parse_color(ctx, base_uri, color, &colorspace, sample);
- /* Set the rendering parameters */
- rendering_params.black_point_comp = BP_ON;
- rendering_params.object_type = GS_PATH_TAG;
- rendering_params.rendering_intent = gsPERCEPTUAL;
-
- /* Get link to map from source to sRGB */
- icclink = gsicc_get_link((gs_imager_state*) ctx->pgs,
- NULL, colorspace, ctx->srgb,
- &rendering_params, ctx->memory, false);
-
- if (icclink != NULL && !icclink->is_identity)
- {
- /* Transform the color */
- int num_colors = gsicc_getsrc_channel_count(colorspace->cmm_icc_profile_data);
- for (i = 0; i < num_colors; i++)
- {
- sample_in[i] = sample[i+1]*65535;
- }
- gscms_transform_color(icclink, sample_in, sample_out, 2, NULL);
-
- stops[count].color[0] = sample[0]; /* Alpha */
- stops[count].color[1] = (float) sample_out[0] / 65535.0; /* sRGB */
- stops[count].color[2] = (float) sample_out[1] / 65535.0;
- stops[count].color[3] = (float) sample_out[2] / 65535.0;
- }
- else
- {
- stops[count].color[0] = sample[0];
- stops[count].color[1] = sample[1];
- stops[count].color[2] = sample[2];
- stops[count].color[3] = sample[3];
- }
+ fz_convertcolor(colorspace, sample + 1, fz_devicergb, rgb);
+
+ stops[count].color[0] = sample[0];
+ stops[count].color[1] = rgb[0];
+ stops[count].color[2] = rgb[1];
+ stops[count].color[3] = rgb[2];
count ++;
}
}
-
- if (icclink != NULL)
- gsicc_release_link(icclink);
- icclink = NULL;
node = xps_next(node);
-
}
if (count == 0)
{
- gs_warn("gradient brush has no gradient stops");
+ fz_warn("gradient brush has no gradient stops");
stops[0].offset = 0;
stops[0].color[0] = 1;
stops[0].color[1] = 0;
@@ -138,7 +91,7 @@ xps_parse_gradient_stops(xps_context_t *ctx, char *base_uri, xps_item_t *node,
}
if (count == maxcount)
- gs_warn("gradient brush exceeded maximum number of gradient stops");
+ fz_warn("gradient brush exceeded maximum number of gradient stops");
/* Postprocess to make sure the range of offsets is 0.0 to 1.0 */
@@ -227,219 +180,6 @@ xps_gradient_has_transparent_colors(struct stop *stops, int count)
}
/*
- * Create a Function object to map [0..1] to RGB colors
- * based on the gradient stop arrays.
- *
- * We do this by creating a stitching function that joins
- * a series of linear functions (one linear function
- * for each gradient stop-pair).
- */
-
-static gs_function_t *
-xps_create_gradient_stop_function(xps_context_t *ctx, struct stop *stops, int count, int opacity_only)
-{
- gs_function_1ItSg_params_t sparams;
- gs_function_ElIn_params_t lparams;
- gs_function_t *sfunc;
- gs_function_t *lfunc;
-
- float *domain, *range, *c0, *c1, *bounds, *encode;
- const gs_function_t **functions;
-
- int code;
- int k;
- int i;
-
- k = count - 1; /* number of intervals / functions */
-
- domain = xps_alloc(ctx, 2 * sizeof(float));
- domain[0] = 0.0;
- domain[1] = 1.0;
- sparams.m = 1;
- sparams.Domain = domain;
-
- range = xps_alloc(ctx, 6 * sizeof(float));
- range[0] = 0.0;
- range[1] = 1.0;
- range[2] = 0.0;
- range[3] = 1.0;
- range[4] = 0.0;
- range[5] = 1.0;
- sparams.n = 3;
- sparams.Range = range;
-
- functions = xps_alloc(ctx, k * sizeof(void*));
- bounds = xps_alloc(ctx, (k - 1) * sizeof(float));
- encode = xps_alloc(ctx, (k * 2) * sizeof(float));
-
- sparams.k = k;
- sparams.Functions = functions;
- sparams.Bounds = bounds;
- sparams.Encode = encode;
-
- for (i = 0; i < k; i++)
- {
- domain = xps_alloc(ctx, 2 * sizeof(float));
- domain[0] = 0.0;
- domain[1] = 1.0;
- lparams.m = 1;
- lparams.Domain = domain;
-
- range = xps_alloc(ctx, 6 * sizeof(float));
- range[0] = 0.0;
- range[1] = 1.0;
- range[2] = 0.0;
- range[3] = 1.0;
- range[4] = 0.0;
- range[5] = 1.0;
- lparams.n = 3;
- lparams.Range = range;
-
- c0 = xps_alloc(ctx, 3 * sizeof(float));
- lparams.C0 = c0;
-
- c1 = xps_alloc(ctx, 3 * sizeof(float));
- lparams.C1 = c1;
-
- if (opacity_only)
- {
- c0[0] = stops[i].color[0];
- c0[1] = stops[i].color[0];
- c0[2] = stops[i].color[0];
-
- c1[0] = stops[i+1].color[0];
- c1[1] = stops[i+1].color[0];
- c1[2] = stops[i+1].color[0];
- }
- else
- {
- c0[0] = stops[i].color[1];
- c0[1] = stops[i].color[2];
- c0[2] = stops[i].color[3];
-
- c1[0] = stops[i+1].color[1];
- c1[1] = stops[i+1].color[2];
- c1[2] = stops[i+1].color[3];
- }
-
- lparams.N = 1;
-
- code = gs_function_ElIn_init(&lfunc, &lparams, ctx->memory);
- if (code < 0)
- {
- gs_rethrow(code, "gs_function_ElIn_init failed");
- return NULL;
- }
-
- functions[i] = lfunc;
-
- if (i > 0)
- bounds[i - 1] = stops[i].offset;
-
- encode[i * 2 + 0] = 0.0;
- encode[i * 2 + 1] = 1.0;
- }
-
- code = gs_function_1ItSg_init(&sfunc, &sparams, ctx->memory);
- if (code < 0)
- {
- gs_rethrow(code, "gs_function_1ItSg_init failed");
- return NULL;
- }
-
- return sfunc;
-}
-
-/*
- * Shadings and functions are ghostscript type objects,
- * and as such rely on the garbage collector for cleanup.
- * We can't have none of that here, so we have to
- * write our own destructors.
- */
-
-static void
-xps_free_gradient_stop_function(xps_context_t *ctx, gs_function_t *func)
-{
- gs_function_t *lfunc;
- gs_function_1ItSg_params_t *sparams;
- gs_function_ElIn_params_t *lparams;
- int i;
-
- sparams = (gs_function_1ItSg_params_t*) &func->params;
- xps_free(ctx, (void*)sparams->Domain);
- xps_free(ctx, (void*)sparams->Range);
-
- for (i = 0; i < sparams->k; i++)
- {
- lfunc = (gs_function_t*) sparams->Functions[i]; /* discard const */
- lparams = (gs_function_ElIn_params_t*) &lfunc->params;
- xps_free(ctx, (void*)lparams->Domain);
- xps_free(ctx, (void*)lparams->Range);
- xps_free(ctx, (void*)lparams->C0);
- xps_free(ctx, (void*)lparams->C1);
- xps_free(ctx, lfunc);
- }
-
- xps_free(ctx, (void*)sparams->Bounds);
- xps_free(ctx, (void*)sparams->Encode);
- xps_free(ctx, (void*)sparams->Functions);
- xps_free(ctx, func);
-}
-
-/*
- * For radial gradients that have a cone drawing we have to
- * reverse the direction of the gradient because we draw
- * the shading in the opposite direction with the
- * big circle first.
- */
-static gs_function_t *
-xps_reverse_function(xps_context_t *ctx, gs_function_t *func, float *fary, void *vary)
-{
- gs_function_1ItSg_params_t sparams;
- gs_function_t *sfunc;
- int code;
-
- /* take from stack allocated arrays that the caller provides */
- float *domain = fary + 0;
- float *range = fary + 2;
- float *encode = fary + 2 + 6;
- const gs_function_t **functions = vary;
-
- domain[0] = 0.0;
- domain[1] = 1.0;
-
- range[0] = 0.0;
- range[1] = 1.0;
- range[2] = 0.0;
- range[3] = 1.0;
- range[4] = 0.0;
- range[5] = 1.0;
-
- functions[0] = func;
-
- encode[0] = 1.0;
- encode[1] = 0.0;
-
- sparams.m = 1;
- sparams.Domain = domain;
- sparams.n = 3;
- sparams.Range = range;
- sparams.k = 1;
- sparams.Functions = functions;
- sparams.Bounds = NULL;
- sparams.Encode = encode;
-
- code = gs_function_1ItSg_init(&sfunc, &sparams, ctx->memory);
- if (code < 0)
- {
- gs_rethrow(code, "gs_function_1ItSg_init failed");
- return NULL;
- }
-
- return sfunc;
-}
-
-/*
* Radial gradients map more or less to Radial shadings.
* The inner circle is always a point.
* The outer circle is actually an ellipse,
@@ -448,10 +188,11 @@ xps_reverse_function(xps_context_t *ctx, gs_function_t *func, float *fary, void
static int
xps_draw_one_radial_gradient(xps_context_t *ctx,
- gs_function_t *func, int extend,
+ int extend,
float x0, float y0, float r0,
float x1, float y1, float r1)
{
+#if 0
gs_memory_t *mem = ctx->memory;
gs_shading_t *shading;
gs_shading_R_params_t params;
@@ -476,7 +217,7 @@ xps_draw_one_radial_gradient(xps_context_t *ctx,
code = gs_shading_R_init(&shading, &params, mem);
if (code < 0)
- return gs_rethrow(code, "gs_shading_R_init failed");
+ return fz_rethrow(code, "gs_shading_R_init failed");
gs_setsmoothness(ctx->pgs, 0.02);
@@ -484,11 +225,11 @@ xps_draw_one_radial_gradient(xps_context_t *ctx,
if (code < 0)
{
gs_free_object(mem, shading, "gs_shading_R");
- return gs_rethrow(code, "gs_shfill failed");
+ return fz_rethrow(code, "gs_shfill failed");
}
gs_free_object(mem, shading, "gs_shading_R");
-
+#endif
return 0;
}
@@ -498,9 +239,10 @@ xps_draw_one_radial_gradient(xps_context_t *ctx,
static int
xps_draw_one_linear_gradient(xps_context_t *ctx,
- gs_function_t *func, int extend,
+ int extend,
float x0, float y0, float x1, float y1)
{
+#if 0
gs_memory_t *mem = ctx->memory;
gs_shading_t *shading;
gs_shading_A_params_t params;
@@ -523,7 +265,7 @@ xps_draw_one_linear_gradient(xps_context_t *ctx,
code = gs_shading_A_init(&shading, &params, mem);
if (code < 0)
- return gs_rethrow(code, "gs_shading_A_init failed");
+ return fz_rethrow(code, "gs_shading_A_init failed");
gs_setsmoothness(ctx->pgs, 0.02);
@@ -531,11 +273,11 @@ xps_draw_one_linear_gradient(xps_context_t *ctx,
if (code < 0)
{
gs_free_object(mem, shading, "gs_shading_A");
- return gs_rethrow(code, "gs_shfill failed");
+ return fz_rethrow(code, "gs_shfill failed");
}
gs_free_object(mem, shading, "gs_shading_A");
-
+#endif
return 0;
}
@@ -555,9 +297,9 @@ static inline float point_inside_circle(float px, float py, float x, float y, fl
}
static int
-xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_function_t *func)
+xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread)
{
- gs_rect bbox;
+ fz_rect bbox;
float x0, y0, r0;
float x1, y1, r1;
float xrad = 1;
@@ -583,8 +325,8 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
yrad = atof(radius_y_att);
/* scale the ctm to make ellipses */
- gs_gsave(ctx->pgs);
- gs_scale(ctx->pgs, 1.0, yrad / xrad);
+// gs_gsave(ctx->pgs);
+// gs_scale(ctx->pgs, 1.0, yrad / xrad);
invscale = xrad / yrad;
y0 = y0 * invscale;
@@ -602,7 +344,7 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
{
if (!point_inside_circle(x0, y0, x1, y1, r1))
{
- gs_function_t *reverse;
+#if 0
float in[1];
float out[4];
float fary[10];
@@ -612,7 +354,6 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
* gradients when the radial shading is a cone. In this case
* we fill the background ourselves.
*/
-
in[0] = 1.0;
out[0] = 1.0;
out[1] = 0.0;
@@ -637,30 +378,25 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
* have to reverse the direction of the function to compensate.
*/
- reverse = xps_reverse_function(ctx, func, fary, vary);
- if (!reverse)
- {
- gs_grestore(ctx->pgs);
- return gs_rethrow(-1, "could not create the reversed function");
- }
+// reverse = xps_reverse_function(ctx, func, fary, vary);
code = xps_draw_one_radial_gradient(ctx, reverse, 1, x1, y1, r1, x0, y0, r0);
if (code < 0)
{
xps_free(ctx, reverse);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "could not draw radial gradient");
+ return fz_rethrow(code, "could not draw radial gradient");
}
- xps_free(ctx, reverse);
+#endif
}
else
{
- code = xps_draw_one_radial_gradient(ctx, func, 1, x0, y0, r0, x1, y1, r1);
+ code = xps_draw_one_radial_gradient(ctx, 1, x0, y0, r0, x1, y1, r1);
if (code < 0)
{
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "could not draw radial gradient");
+// gs_grestore(ctx->pgs);
+ return fz_rethrow(code, "could not draw radial gradient");
}
}
}
@@ -671,25 +407,25 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
/* Draw current circle */
if (!point_inside_circle(x0, y0, x1, y1, r1))
- dputs("xps: we should reverse gradient here too\n");
+ printf("xps: we should reverse gradient here too\n");
if (spread == SPREAD_REFLECT && (i & 1))
- code = xps_draw_one_radial_gradient(ctx, func, 0, x1, y1, r1, x0, y0, r0);
+ code = xps_draw_one_radial_gradient(ctx, 0, x1, y1, r1, x0, y0, r0);
else
- code = xps_draw_one_radial_gradient(ctx, func, 0, x0, y0, r0, x1, y1, r1);
+ code = xps_draw_one_radial_gradient(ctx, 0, x0, y0, r0, x1, y1, r1);
if (code < 0)
{
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "could not draw axial gradient");
+// gs_grestore(ctx->pgs);
+ return fz_rethrow(code, "could not draw axial gradient");
}
/* Check if circle encompassed the entire bounding box (break loop if we do) */
done = 1;
- if (!point_inside_circle(bbox.p.x, bbox.p.y, x1, y1, r1)) done = 0;
- if (!point_inside_circle(bbox.p.x, bbox.q.y, x1, y1, r1)) done = 0;
- if (!point_inside_circle(bbox.q.x, bbox.q.y, x1, y1, r1)) done = 0;
- if (!point_inside_circle(bbox.q.x, bbox.p.y, x1, y1, r1)) done = 0;
+ if (!point_inside_circle(bbox.x0, bbox.y0, x1, y1, r1)) done = 0;
+ if (!point_inside_circle(bbox.x0, bbox.y1, x1, y1, r1)) done = 0;
+ if (!point_inside_circle(bbox.x1, bbox.y1, x1, y1, r1)) done = 0;
+ if (!point_inside_circle(bbox.x1, bbox.y0, x1, y1, r1)) done = 0;
if (done)
break;
@@ -705,7 +441,7 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
}
}
- gs_grestore(ctx->pgs);
+// gs_grestore(ctx->pgs);
return 0;
}
@@ -716,9 +452,9 @@ xps_draw_radial_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
*/
static int
-xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_function_t *func)
+xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread)
{
- gs_rect bbox;
+ fz_rect bbox;
float x0, y0, x1, y1;
float dx, dy;
int code;
@@ -744,9 +480,9 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
if (spread == SPREAD_PAD)
{
- code = xps_draw_one_linear_gradient(ctx, func, 1, x0, y0, x1, y1);
+ code = xps_draw_one_linear_gradient(ctx, 1, x0, y0, x1, y1);
if (code < 0)
- return gs_rethrow(code, "could not draw axial gradient");
+ return fz_rethrow(code, "could not draw axial gradient");
}
else
{
@@ -760,10 +496,10 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
a = dx / len;
b = dy / len;
- dist[0] = a * (bbox.p.x - x0) + b * (bbox.p.y - y0);
- dist[1] = a * (bbox.p.x - x0) + b * (bbox.q.y - y0);
- dist[2] = a * (bbox.q.x - x0) + b * (bbox.q.y - y0);
- dist[3] = a * (bbox.q.x - x0) + b * (bbox.p.y - y0);
+ dist[0] = a * (bbox.x0 - x0) + b * (bbox.y0 - y0);
+ dist[1] = a * (bbox.x0 - x0) + b * (bbox.y1 - y0);
+ dist[2] = a * (bbox.x1 - x0) + b * (bbox.y1 - y0);
+ dist[3] = a * (bbox.x1 - x0) + b * (bbox.y0 - y0);
d0 = dist[0];
d1 = dist[0];
@@ -780,18 +516,18 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
{
if (spread == SPREAD_REFLECT && (i & 1))
{
- code = xps_draw_one_linear_gradient(ctx, func, 0,
+ code = xps_draw_one_linear_gradient(ctx, 0,
x1 + dx * i, y1 + dy * i,
x0 + dx * i, y0 + dy * i);
}
else
{
- code = xps_draw_one_linear_gradient(ctx, func, 0,
+ code = xps_draw_one_linear_gradient(ctx, 0,
x0 + dx * i, y0 + dy * i,
x1 + dx * i, y1 + dy * i);
}
if (code < 0)
- return gs_rethrow(code, "could not draw axial gradient");
+ return fz_rethrow(code, "could not draw axial gradient");
}
}
@@ -804,8 +540,9 @@ xps_draw_linear_gradient(xps_context_t *ctx, xps_item_t *root, int spread, gs_fu
*/
static int
-xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
- int (*draw)(xps_context_t *, xps_item_t *, int, gs_function_t *))
+xps_parse_gradient_brush(xps_context_t *ctx, fz_matrix ctm,
+ char *base_uri, xps_resource_t *dict, xps_item_t *root,
+ int (*draw)(xps_context_t *, xps_item_t *, int))
{
xps_item_t *node;
@@ -820,14 +557,11 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
struct stop stop_list[MAX_STOPS];
int stop_count;
- gs_matrix transform;
+ fz_matrix transform;
int spread_method;
- int code;
- gs_rect bbox;
+ fz_rect bbox;
- gs_function_t *color_func;
- gs_function_t *opacity_func;
int has_opacity = 0;
opacity_att = xps_att(root, "Opacity");
@@ -861,41 +595,42 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
spread_method = SPREAD_REPEAT;
}
- gs_make_identity(&transform);
+ xps_clip(ctx, ctm);
+
+ transform = fz_identity;
if (transform_att)
xps_parse_render_transform(ctx, transform_att, &transform);
if (transform_tag)
xps_parse_matrix_transform(ctx, transform_tag, &transform);
+ ctm = fz_concat(ctm, transform);
if (!stop_tag)
- return gs_throw(-1, "missing gradient stops tag");
+ return fz_throw("missing gradient stops tag");
stop_count = xps_parse_gradient_stops(ctx, base_uri, stop_tag, stop_list, MAX_STOPS);
if (stop_count == 0)
- return gs_throw(-1, "no gradient stops found");
+ return fz_throw("no gradient stops found");
+/*
color_func = xps_create_gradient_stop_function(ctx, stop_list, stop_count, 0);
if (!color_func)
- return gs_rethrow(-1, "could not create color gradient function");
+ return fz_rethrow(-1, "could not create color gradient function");
opacity_func = xps_create_gradient_stop_function(ctx, stop_list, stop_count, 1);
if (!opacity_func)
- return gs_rethrow(-1, "could not create opacity gradient function");
+ return fz_rethrow(-1, "could not create opacity gradient function");
+*/
has_opacity = xps_gradient_has_transparent_colors(stop_list, stop_count);
- xps_clip(ctx);
-
- gs_gsave(ctx->pgs);
- gs_concat(ctx->pgs, &transform);
-
xps_bounds_in_user_space(ctx, &bbox);
+#if 0
code = xps_begin_opacity(ctx, base_uri, dict, opacity_att, NULL);
if (code)
{
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot create transparency group");
+ return fz_rethrow(code, "cannot create transparency group");
}
if (ctx->opacity_only)
@@ -904,7 +639,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
if (code)
{
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw gradient opacity");
+ return fz_rethrow(code, "cannot draw gradient opacity");
}
}
else
@@ -921,7 +656,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
{
gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw gradient opacity");
+ return fz_rethrow(code, "cannot draw gradient opacity");
}
gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
@@ -932,7 +667,7 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
{
gs_end_transparency_group(ctx->pgs);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw gradient color");
+ return fz_rethrow(code, "cannot draw gradient color");
}
gs_end_transparency_group(ctx->pgs);
}
@@ -942,37 +677,40 @@ xps_parse_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dic
if (code)
{
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw gradient color");
+ return fz_rethrow(code, "cannot draw gradient color");
}
}
}
+#endif
xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
- gs_grestore(ctx->pgs);
+// gs_grestore(ctx->pgs);
- xps_free_gradient_stop_function(ctx, opacity_func);
- xps_free_gradient_stop_function(ctx, color_func);
+// xps_free_gradient_stop_function(ctx, opacity_func);
+// xps_free_gradient_stop_function(ctx, color_func);
return 0;
}
int
-xps_parse_linear_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
+xps_parse_linear_gradient_brush(xps_context_t *ctx, fz_matrix ctm,
+ char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
int code;
- code = xps_parse_gradient_brush(ctx, base_uri, dict, root, xps_draw_linear_gradient);
+ code = xps_parse_gradient_brush(ctx, ctm, base_uri, dict, root, xps_draw_linear_gradient);
if (code < 0)
- return gs_rethrow(code, "cannot parse linear gradient brush");
- return gs_okay;
+ return fz_rethrow(code, "cannot parse linear gradient brush");
+ return fz_okay;
}
int
-xps_parse_radial_gradient_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
+xps_parse_radial_gradient_brush(xps_context_t *ctx, fz_matrix ctm,
+ char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
int code;
- code = xps_parse_gradient_brush(ctx, base_uri, dict, root, xps_draw_radial_gradient);
+ code = xps_parse_gradient_brush(ctx, ctm, base_uri, dict, root, xps_draw_radial_gradient);
if (code < 0)
- return gs_rethrow(code, "cannot parse radial gradient brush");
- return gs_okay;
+ return fz_rethrow(code, "cannot parse radial gradient brush");
+ return fz_okay;
}
diff --git a/xps/xpshash.c b/xps/xpshash.c
index 459566c9..1e562ff3 100644
--- a/xps/xpshash.c
+++ b/xps/xpshash.c
@@ -1,16 +1,3 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
/* Linear probe hash table.
*
* Simple hashtable with open adressing linear probe.
@@ -18,7 +5,8 @@
* Does not support deleting entries.
*/
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
static const unsigned primes[] =
{
@@ -67,7 +55,7 @@ xps_hash_new(xps_context_t *ctx)
table = xps_alloc(ctx, sizeof(xps_hash_table_t));
if (!table)
{
- gs_throw(-1, "out of memory: hash table struct");
+ fz_throw("out of memory: hash table struct");
return NULL;
}
@@ -78,7 +66,7 @@ xps_hash_new(xps_context_t *ctx)
if (!table->entries)
{
xps_free(ctx, table);
- gs_throw(-1, "out of memory: hash table entries array");
+ fz_throw("out of memory: hash table entries array");
return NULL;
}
@@ -108,7 +96,7 @@ xps_hash_double(xps_context_t *ctx, xps_hash_table_t *table)
old_entries = table->entries;
new_entries = xps_alloc(ctx, sizeof(xps_hash_entry_t) * new_size);
if (!new_entries)
- return gs_throw(-1, "out of memory: hash table entries array");
+ return fz_throw("out of memory: hash table entries array");
table->size = new_size;
table->entries = new_entries;
@@ -173,7 +161,7 @@ xps_hash_insert(xps_context_t *ctx, xps_hash_table_t *table, char *key, void *va
if (table->load > table->size * 8 / 10)
{
if (xps_hash_double(ctx, table) < 0)
- return gs_rethrow(-1, "cannot grow hash table");
+ return fz_rethrow(-1, "cannot grow hash table");
}
entries = table->entries;
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index 7a69ba09..15257594 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -1,274 +1,68 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - image support */
-
-/* TODO: we should be smarter here and do incremental decoding
- * and rendering instead of uncompressing the whole image to
- * memory before drawing.
- */
-
-#include "ghostxps.h"
-
-/*
- * Un-interleave the alpha channel.
- */
-
-static void
-xps_isolate_alpha_channel_8(xps_context_t *ctx, xps_image_t *image)
-{
- int n = image->comps;
- int y, x, k;
- byte *sp, *dp, *ap;
-
- image->alpha = xps_alloc(ctx, image->width * image->height);
-
- for (y = 0; y < image->height; y++)
- {
- sp = image->samples + image->width * n * y;
- dp = image->samples + image->width * (n - 1) * y;
- ap = image->alpha + image->width * y;
- for (x = 0; x < image->width; x++)
- {
- for (k = 0; k < n - 1; k++)
- *dp++ = *sp++;
- *ap++ = *sp++;
- }
- }
-
- image->hasalpha = 0;
- image->comps --;
- image->stride = image->width * image->comps;
-}
-
-static void
-xps_isolate_alpha_channel_16(xps_context_t *ctx, xps_image_t *image)
-{
- int n = image->comps;
- int y, x, k;
- unsigned short *sp, *dp, *ap;
-
- image->alpha = xps_alloc(ctx, image->width * image->height * 2);
-
- for (y = 0; y < image->height; y++)
- {
- sp = ((unsigned short*)image->samples) + (image->width * n * y);
- dp = ((unsigned short*)image->samples) + (image->width * (n - 1) * y);
- ap = ((unsigned short*)image->alpha) + (image->width * y);
- for (x = 0; x < image->width; x++)
- {
- for (k = 0; k < n - 1; k++)
- *dp++ = *sp++;
- *ap++ = *sp++;
- }
- }
-
- image->hasalpha = 0;
- image->comps --;
- image->stride = image->width * image->comps * 2;
-}
-
-static int
-xps_image_has_alpha(xps_context_t *ctx, xps_part_t *part)
-{
- byte *buf = part->data;
- int len = part->size;
-
- if (len < 8)
- {
- gs_warn("unknown image file format");
- return 0;
- }
-
- if (buf[0] == 0xff && buf[1] == 0xd8)
- return 0; /* JPEG never has an alpha channel */
- else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0)
- return xps_png_has_alpha(ctx, buf, len);
- else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC)
- return xps_jpegxr_has_alpha(ctx, buf, len);
- else if (memcmp(buf, "MM", 2) == 0)
- return xps_tiff_has_alpha(ctx, buf, len);
- else if (memcmp(buf, "II", 2) == 0)
- return xps_tiff_has_alpha(ctx, buf, len);
-
- return 0;
-}
+#include "fitz.h"
+#include "muxps.h"
static int
xps_decode_image(xps_context_t *ctx, xps_part_t *part, xps_image_t *image)
{
byte *buf = part->data;
int len = part->size;
- cmm_profile_t *profile;
int error;
if (len < 8)
- return gs_throw(-1, "unknown image file format");
+ return fz_throw("unknown image file format");
memset(image, 0, sizeof(xps_image_t));
- image->samples = NULL;
- image->alpha = NULL;
if (buf[0] == 0xff && buf[1] == 0xd8)
{
error = xps_decode_jpeg(ctx, buf, len, image);
if (error)
- return gs_rethrow(error, "could not decode jpeg image");
+ return fz_rethrow(error, "could not decode image");
}
else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0)
{
error = xps_decode_png(ctx, buf, len, image);
if (error)
- return gs_rethrow(error, "could not decode png image");
+ return fz_rethrow(error, "could not decode image");
}
else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC)
{
error = xps_decode_jpegxr(ctx, buf, len, image);
if (error)
- return gs_rethrow(error, "could not decode jpeg-xr image");
+ return fz_rethrow(error, "could not decode image");
}
else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0)
{
error = xps_decode_tiff(ctx, buf, len, image);
if (error)
- return gs_rethrow(error, "could not decode tiff image");
+ return fz_rethrow(error, "could not decode image");
}
else
- return gs_throw(-1, "unknown image file format");
-
- // TODO: refcount image->colorspace
-
- /* See if we need to use the embedded profile. */
- if (image->profile)
- {
- /*
- See if we can set up to use the embedded profile.
- Note these profiles are NOT added to the xps color cache.
- As such, they must be destroyed when the image brush ends.
- */
+ return fz_throw("unknown image file format");
- /* Create the profile */
- profile = gsicc_profile_new(NULL, ctx->memory, NULL, 0);
-
- /* Set buffer */
- profile->buffer = image->profile;
- profile->buffer_size = image->profilesize;
-
- /* Parse */
- gsicc_init_profile_info(profile);
-
- if (profile->profile_handle == NULL)
- {
- /* Problem with profile. Just ignore it */
- gs_warn("ignoring problem with icc profile embedded in an image");
- gsicc_profile_reference(profile, -1);
- }
- else
- {
- /* Check the profile is OK for channel data count.
- * Need to be careful here since alpha is put into comps */
- if ((image->comps - image->hasalpha) == gsicc_getsrc_channel_count(profile))
- {
- /* Create a new colorspace and associate with the profile */
- // TODO: refcount image->colorspace
- gs_cspace_build_ICC(&image->colorspace, NULL, ctx->memory);
- image->colorspace->cmm_icc_profile_data = profile;
- }
- else
- {
- /* Problem with profile. Just ignore it */
- gs_warn("ignoring icc profile embedded in an image with wrong number of components");
- gsicc_profile_reference(profile, -1);
- }
- }
- }
-
- if (image->hasalpha)
- {
- if (image->bits < 8)
- dprintf1("cannot isolate alpha channel in %d bpc images\n", image->bits);
- if (image->bits == 8)
- xps_isolate_alpha_channel_8(ctx, image);
- if (image->bits == 16)
- xps_isolate_alpha_channel_16(ctx, image);
- }
-
- return gs_okay;
+ return fz_okay;
}
static int
-xps_paint_image_brush_imp(xps_context_t *ctx, xps_image_t *image, int alpha)
+xps_paint_image_brush_imp(xps_context_t *ctx, fz_matrix ctm, xps_image_t *image)
{
- gs_image_enum *penum;
- gs_color_space *colorspace;
- gs_image_t gsimage;
- int code;
-
+ fz_colorspace *colorspace;
unsigned int count;
- unsigned int used;
byte *samples;
- if (alpha)
- {
- colorspace = ctx->gray;
- samples = image->alpha;
- count = (image->width * image->bits + 7) / 8 * image->height;
- used = 0;
- }
- else
- {
- colorspace = image->colorspace;
- samples = image->samples;
- count = image->stride * image->height;
- used = 0;
- }
-
- memset(&gsimage, 0, sizeof(gsimage));
- gs_image_t_init(&gsimage, colorspace);
- gsimage.ColorSpace = colorspace;
- gsimage.BitsPerComponent = image->bits;
- gsimage.Width = image->width;
- gsimage.Height = image->height;
+ colorspace = image->colorspace;
+ samples = image->samples;
+ count = image->stride * image->height;
- gsimage.ImageMatrix.xx = image->xres / 96.0;
- gsimage.ImageMatrix.yy = image->yres / 96.0;
-
- gsimage.Interpolate = 1;
-
- penum = gs_image_enum_alloc(ctx->memory, "xps_parse_image_brush (gs_image_enum_alloc)");
- if (!penum)
- return gs_throw(-1, "gs_enum_allocate failed");
-
- if ((code = gs_image_init(penum, &gsimage, false, ctx->pgs)) < 0)
- return gs_throw(code, "gs_image_init failed");
-
- if ((code = gs_image_next(penum, samples, count, &used)) < 0)
- return gs_throw(code, "gs_image_next failed");
-
- if (count < used)
- return gs_throw2(-1, "not enough image data (image=%d used=%d)", count, used);
-
- if (count > used)
- return gs_throw2(0, "too much image data (image=%d used=%d)", count, used);
-
- gs_image_cleanup_and_free_enum(penum, ctx->pgs);
+ // xxx
return 0;
}
static int
-xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *vimage)
+xps_paint_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *vimage)
{
+#if 0
xps_image_t *image = vimage;
int code;
@@ -278,7 +72,7 @@ xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
{
code = xps_paint_image_brush_imp(ctx, image, 1);
if (code < 0)
- return gs_rethrow(code, "cannot draw alpha channel image");
+ return fz_rethrow(code, "cannot draw alpha channel image");
}
return 0;
}
@@ -287,13 +81,13 @@ xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
{
gs_transparency_mask_params_t params;
gs_transparency_group_params_t tgp;
- gs_rect bbox;
+ fz_rect bbox;
xps_bounds_in_user_space(ctx, &bbox);
code = gs_gsave(ctx->pgs);
if (code < 0)
- return gs_rethrow(code, "cannot gsave before transparency group");
+ return fz_rethrow(code, "cannot gsave before transparency group");
gs_setcolorspace(ctx->pgs, ctx->gray);
gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
@@ -303,7 +97,7 @@ xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
{
gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw alpha channel image");
+ return fz_rethrow(code, "cannot draw alpha channel image");
}
gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
@@ -315,20 +109,21 @@ xps_paint_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
{
gs_end_transparency_group(ctx->pgs);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw color channel image");
+ return fz_rethrow(code, "cannot draw color channel image");
}
gs_end_transparency_group(ctx->pgs);
code = gs_grestore(ctx->pgs);
if (code < 0)
- return gs_rethrow(code, "cannot grestore after transparency group");
+ return fz_rethrow(code, "cannot grestore after transparency group");
}
else
{
code = xps_paint_image_brush_imp(ctx, image, 0);
if (code < 0)
- return gs_rethrow(code, "cannot draw image");
+ return fz_rethrow(code, "cannot draw image");
}
+#endif
return 0;
}
@@ -346,7 +141,7 @@ xps_find_image_brush_source_part(xps_context_t *ctx, char *base_uri, xps_item_t
image_source_att = xps_att(root, "ImageSource");
if (!image_source_att)
- return gs_throw(-1, "missing ImageSource attribute");
+ return fz_throw("missing ImageSource attribute");
/* "{ColorConvertedBitmap /Resources/Image.tiff /Resources/Profile.icc}" */
if (strstr(image_source_att, "{ColorConvertedBitmap") == image_source_att)
@@ -377,54 +172,59 @@ xps_find_image_brush_source_part(xps_context_t *ctx, char *base_uri, xps_item_t
}
if (!image_name)
- return gs_throw1(-1, "cannot parse image resource name '%s'", image_source_att);
+ return fz_throw("cannot parse image resource name '%s'", image_source_att);
xps_absolute_path(partname, base_uri, image_name, sizeof partname);
part = xps_read_part(ctx, partname);
if (!part)
- return gs_throw1(-1, "cannot find image resource part '%s'", partname);
+ return fz_throw("cannot find image resource part '%s'", partname);
*partp = part;
- *profilep = xps_strdup(ctx, profile_name);
+ if (profile_name)
+ *profilep = xps_strdup(ctx, profile_name);
return 0;
}
int
-xps_parse_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
+xps_parse_image_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_part_t *part;
xps_image_t *image;
- gs_color_space *colorspace;
+ fz_colorspace *colorspace;
char *profilename;
int code;
+ profilename = NULL;
+
code = xps_find_image_brush_source_part(ctx, base_uri, root, &part, &profilename);
if (code < 0)
- return gs_rethrow(code, "cannot find image source");
+ return fz_rethrow(code, "cannot find image source");
image = xps_alloc(ctx, sizeof(xps_image_t));
if (!image)
- return gs_throw(-1, "out of memory: image struct");
+ return fz_throw("out of memory: image struct");
+
+return 0;
code = xps_decode_image(ctx, part, image);
if (code < 0)
- return gs_rethrow1(code, "cannot decode image '%s'", part->name);
+ return fz_rethrow(-1, "cannot decode image resource");
/* Override any embedded colorspace profiles if the external one matches. */
if (profilename)
{
colorspace = xps_read_icc_colorspace(ctx, base_uri, profilename);
- if (colorspace && cs_num_components(colorspace) == cs_num_components(image->colorspace))
+ if (colorspace && colorspace->n == image->colorspace->n)
{
// TODO: refcount image->colorspace
image->colorspace = colorspace;
}
}
- code = xps_parse_tiling_brush(ctx, base_uri, dict, root, xps_paint_image_brush, image);
+ code = xps_parse_tiling_brush(ctx, ctm, base_uri, dict, root, xps_paint_image_brush, image);
if (code < 0)
- return gs_rethrow(-1, "cannot parse tiling brush");
+ return fz_rethrow(-1, "cannot parse tiling brush");
if (profilename)
xps_free(ctx, profilename);
@@ -434,36 +234,12 @@ xps_parse_image_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
return 0;
}
-int
-xps_image_brush_has_transparency(xps_context_t *ctx, char *base_uri, xps_item_t *root)
-{
- xps_part_t *imagepart;
- int code;
- int has_alpha;
- char *profilename;
-
- code = xps_find_image_brush_source_part(ctx, base_uri, root, &imagepart, &profilename);
- if (code < 0)
- {
- gs_catch(code, "cannot find image source");
- return 0;
- }
-
- has_alpha = xps_image_has_alpha(ctx, imagepart);
-
- xps_free_part(ctx, imagepart);
-
- return has_alpha;
-}
-
void
xps_free_image(xps_context_t *ctx, xps_image_t *image)
{
// TODO: refcount image->colorspace
if (image->samples)
xps_free(ctx, image->samples);
- if (image->alpha)
- xps_free(ctx, image->alpha);
if (image->profile)
xps_free(ctx, image->profile);
xps_free(ctx, image);
diff --git a/xps/xpsjpeg.c b/xps/xpsjpeg.c
index 878fd85a..937ac4f0 100644
--- a/xps/xpsjpeg.c
+++ b/xps/xpsjpeg.c
@@ -1,143 +1,11 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - JPEG image support */
-
-#include "ghostxps.h"
-
-#include "stream.h"
-#include "strimpl.h"
-#include "gsstate.h"
-#include "jpeglib_.h"
-#include "sdct.h"
-#include "sjpeg.h"
-
-static int
-xps_report_error(stream_state * st, const char *str)
-{
- (void) gs_throw1(-1, "%s", str);
- return 0;
-}
+#include <jpeglib.h>
+#include <setjmp.h>
int
xps_decode_jpeg(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
{
- jpeg_decompress_data jddp;
- stream_DCT_state state;
- stream_cursor_read rp;
- stream_cursor_write wp;
- int code;
- int wlen;
- byte *wbuf;
- jpeg_saved_marker_ptr curr_marker;
-
- s_init_state((stream_state*)&state, &s_DCTD_template, ctx->memory);
- state.report_error = xps_report_error;
-
- s_DCTD_template.set_defaults((stream_state*)&state);
-
- state.jpeg_memory = ctx->memory;
- state.data.decompress = &jddp;
-
- jddp.template = s_DCTD_template;
- jddp.memory = ctx->memory;
- jddp.scanline_buffer = NULL;
-
- if ((code = gs_jpeg_create_decompress(&state)) < 0)
- return gs_throw(-1, "cannot gs_jpeg_create_decompress");
-
- s_DCTD_template.init((stream_state*)&state);
-
- rp.ptr = rbuf - 1;
- rp.limit = rbuf + rlen - 1;
-
- /* read the header only by not having a write buffer */
- wp.ptr = 0;
- wp.limit = 0;
-
- /* Set up to save the ICC marker APP2.
- * According to the spec we should be getting APP1 APP2 and APP13.
- * Library gets APP0 and APP14. */
- jpeg_save_markers(&(jddp.dinfo), 0xe2, 0xFFFF);
-
- code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
- if (code != 1)
- return gs_throw(-1, "premature EOF or error in jpeg");
-
- /* Check if we had an ICC profile */
- curr_marker = jddp.dinfo.marker_list;
- while (curr_marker != NULL)
- {
- if (curr_marker->marker == 0xe2)
- {
- /* Found ICC profile. Create a buffer and copy over now.
- * Strip JPEG APP2 14 byte header */
- image->profilesize = curr_marker->data_length - 14;
- image->profile = xps_alloc(ctx, image->profilesize);
- if (image->profile)
- {
- /* If we can't create it, just ignore */
- memcpy(image->profile, &(curr_marker->data[14]), image->profilesize);
- }
- break;
- }
- curr_marker = curr_marker->next;
- }
-
- image->width = jddp.dinfo.output_width;
- image->height = jddp.dinfo.output_height;
- image->comps = jddp.dinfo.output_components;
- image->bits = 8;
- image->stride = image->width * image->comps;
-
- if (image->comps == 1)
- image->colorspace = ctx->gray;
- if (image->comps == 3)
- image->colorspace = ctx->srgb;
- if (image->comps == 4)
- image->colorspace = ctx->cmyk;
-
- if (jddp.dinfo.density_unit == 1)
- {
- image->xres = jddp.dinfo.X_density;
- image->yres = jddp.dinfo.Y_density;
- }
- else if (jddp.dinfo.density_unit == 2)
- {
- image->xres = jddp.dinfo.X_density * 2.54;
- image->yres = jddp.dinfo.Y_density * 2.54;
- }
- else
- {
- image->xres = 96;
- image->yres = 96;
- }
-
- wlen = image->stride * image->height;
- wbuf = xps_alloc(ctx, wlen);
- if (!wbuf)
- return gs_throw1(-1, "out of memory allocating samples: %d", wlen);
-
- image->samples = wbuf;
-
- wp.ptr = wbuf - 1;
- wp.limit = wbuf + wlen - 1;
-
- code = s_DCTD_template.process((stream_state*)&state, &rp, &wp, true);
- if (code != EOFC)
- return gs_throw1(-1, "error in jpeg (code = %d)", code);
-
- gs_jpeg_destroy(&state);
-
- return gs_okay;
+ return fz_throw("jpeg not available");
}
diff --git a/xps/xpsjxr.c b/xps/xpsjxr.c
index 1e9b0e73..f2f78ce0 100644
--- a/xps/xpsjxr.c
+++ b/xps/xpsjxr.c
@@ -1,19 +1,9 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
/* JPEG-XR (formerly HD-Photo (formerly Windows Media Photo)) support */
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
+
+#ifdef HAVE_JPEGXR
#ifdef _MSC_VER
#undef _MSC_VER
@@ -257,3 +247,19 @@ xps_jpegxr_has_alpha(xps_context_t *ctx, byte *buf, int len)
{
return 1;
}
+
+#else
+
+int
+xps_decode_jpegxr(xps_context_t *ctx, byte *buf, int len, xps_image_t *image)
+{
+ return fz_throw("JPEG-XR codec is not available");
+}
+
+int
+xps_jpegxr_has_alpha(xps_context_t *ctx, byte *buf, int len)
+{
+ return 0;
+}
+
+#endif
diff --git a/xps/xpsmem.c b/xps/xpsmem.c
index 95199f07..3af3b3f6 100644
--- a/xps/xpsmem.c
+++ b/xps/xpsmem.c
@@ -1,27 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - string manipulation functions */
-
-#include "ghostxps.h"
-
-void *
-xps_realloc_imp(xps_context_t *ctx, void *ptr, int size, const char *func)
-{
- if (!ptr)
- return gs_alloc_bytes(ctx->memory, size, func);
- return gs_resize_object(ctx->memory, ptr, size, func);
-}
+#include "fitz.h"
+#include "muxps.h"
static inline int
xps_tolower(int c)
@@ -34,24 +12,13 @@ xps_tolower(int c)
int
xps_strcasecmp(char *a, char *b)
{
- while (xps_tolower(*a) == xps_tolower(*b))
- {
- if (*a++ == 0)
- return 0;
- b++;
- }
- return xps_tolower(*a) - xps_tolower(*b);
-}
-
-char *
-xps_strdup_imp(xps_context_t *ctx, const char *str, const char *cname)
-{
- char *cpy = NULL;
- if (str)
- cpy = (char*) gs_alloc_bytes(ctx->memory, strlen(str) + 1, cname);
- if (cpy)
- strcpy(cpy, str);
- return cpy;
+ while (xps_tolower(*a) == xps_tolower(*b))
+ {
+ if (*a++ == 0)
+ return 0;
+ b++;
+ }
+ return xps_tolower(*a) - xps_tolower(*b);
}
size_t
diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c
index bd845efb..e4923f14 100644
--- a/xps/xpsopacity.c
+++ b/xps/xpsopacity.c
@@ -1,45 +1,31 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - transparency support */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
void
-xps_bounds_in_user_space(xps_context_t *ctx, gs_rect *ubox)
+xps_bounds_in_user_space(xps_context_t *ctx, fz_rect *ubox)
{
+#if 0
gx_clip_path *clip_path;
- gs_rect dbox;
+ fz_rect dbox;
int code;
code = gx_effective_clip_path(ctx->pgs, &clip_path);
if (code < 0)
- gs_warn("gx_effective_clip_path failed");
+ fz_warn("gx_effective_clip_path failed");
dbox.p.x = fixed2float(clip_path->outer_box.p.x);
dbox.p.y = fixed2float(clip_path->outer_box.p.y);
dbox.q.x = fixed2float(clip_path->outer_box.q.x);
dbox.q.y = fixed2float(clip_path->outer_box.q.y);
gs_bbox_transform_inverse(&dbox, &ctm_only(ctx->pgs), ubox);
+#endif
}
int
-xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
+xps_begin_opacity(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict,
char *opacity_att, xps_item_t *opacity_mask_tag)
{
- gs_transparency_group_params_t tgp;
- gs_transparency_mask_params_t tmp;
- gs_rect bbox;
+ fz_rect bbox;
float opacity;
int save;
int code;
@@ -50,44 +36,28 @@ xps_begin_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
opacity = 1.0;
if (opacity_att)
opacity = atof(opacity_att);
- gs_setopacityalpha(ctx->pgs, opacity);
+// gs_setopacityalpha(ctx->pgs, opacity);
xps_bounds_in_user_space(ctx, &bbox);
if (opacity_mask_tag)
{
- gs_trans_mask_params_init(&tmp, TRANSPARENCY_MASK_Luminosity);
- gs_begin_transparency_mask(ctx->pgs, &tmp, &bbox, 0);
-
- gs_gsave(ctx->pgs);
-
- /* Need a path to fill/clip for the brush */
- gs_moveto(ctx->pgs, bbox.p.x, bbox.p.y);
- gs_lineto(ctx->pgs, bbox.p.x, bbox.q.y);
- gs_lineto(ctx->pgs, bbox.q.x, bbox.q.y);
- gs_lineto(ctx->pgs, bbox.q.x, bbox.p.y);
- gs_closepath(ctx->pgs);
-
/* opacity-only mode: use alpha value as gray color to create luminosity mask */
save = ctx->opacity_only;
ctx->opacity_only = 1;
- code = xps_parse_brush(ctx, base_uri, dict, opacity_mask_tag);
+ // begin mask
+ code = xps_parse_brush(ctx, ctm, base_uri, dict, opacity_mask_tag);
if (code)
{
- gs_grestore(ctx->pgs);
- gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
ctx->opacity_only = save;
- return gs_rethrow(code, "cannot parse opacity mask brush");
+ return fz_rethrow(code, "cannot parse opacity mask brush");
}
- gs_grestore(ctx->pgs);
- gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
ctx->opacity_only = save;
}
- gs_trans_group_params_init(&tgp);
- gs_begin_transparency_group(ctx->pgs, &tgp, &bbox);
+ // begin group
return 0;
}
@@ -98,5 +68,5 @@ xps_end_opacity(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
{
if (!opacity_att && !opacity_mask_tag)
return;
- gs_end_transparency_group(ctx->pgs);
+ // end mask+group
}
diff --git a/xps/xpspage.c b/xps/xpspage.c
index c6424d7c..858f327f 100644
--- a/xps/xpspage.c
+++ b/xps/xpspage.c
@@ -1,22 +1,8 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - page parsing */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
int
-xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
+xps_parse_canvas(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_resource_t *new_dict = NULL;
xps_item_t *node;
@@ -32,7 +18,7 @@ xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_i
xps_item_t *clip_tag = NULL;
xps_item_t *opacity_mask_tag = NULL;
- gs_matrix transform;
+ fz_matrix transform;
transform_att = xps_att(root, "RenderTransform");
clip_att = xps_att(root, "Clip");
@@ -45,7 +31,7 @@ xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_i
{
code = xps_parse_resource_dictionary(ctx, &new_dict, base_uri, xps_down(node));
if (code)
- return gs_rethrow(code, "cannot load Canvas.Resources");
+ return fz_rethrow(code, "cannot load Canvas.Resources");
new_dict->parent = dict;
dict = new_dict;
}
@@ -63,45 +49,46 @@ xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_i
xps_resolve_resource_reference(ctx, dict, &clip_att, &clip_tag, NULL);
xps_resolve_resource_reference(ctx, dict, &opacity_mask_att, &opacity_mask_tag, &opacity_mask_uri);
- gs_gsave(ctx->pgs);
+// gs_gsave(ctx->pgs);
- gs_make_identity(&transform);
+ transform = fz_identity;
if (transform_att)
xps_parse_render_transform(ctx, transform_att, &transform);
if (transform_tag)
xps_parse_matrix_transform(ctx, transform_tag, &transform);
- gs_concat(ctx->pgs, &transform);
+ ctm = fz_concat(ctm, transform);
if (clip_att || clip_tag)
{
+ ctx->path = fz_newpath();
if (clip_att)
xps_parse_abbreviated_geometry(ctx, clip_att);
if (clip_tag)
xps_parse_path_geometry(ctx, dict, clip_tag, 0);
- xps_clip(ctx);
+ xps_clip(ctx, ctm);
}
- code = xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
+ code = xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
if (code)
{
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot create transparency group");
+// gs_grestore(ctx->pgs);
+ return fz_rethrow(code, "cannot create transparency group");
}
for (node = xps_down(root); node; node = xps_next(node))
{
- code = xps_parse_element(ctx, base_uri, dict, node);
+ code = xps_parse_element(ctx, ctm, base_uri, dict, node);
if (code)
{
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse child of Canvas");
+// gs_grestore(ctx->pgs);
+ return fz_rethrow(code, "cannot parse child of Canvas");
}
}
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- gs_grestore(ctx->pgs);
+// gs_grestore(ctx->pgs);
if (new_dict)
xps_free_resource_dictionary(ctx, new_dict);
@@ -110,172 +97,74 @@ xps_parse_canvas(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_i
}
int
-xps_parse_fixed_page(xps_context_t *ctx, xps_part_t *part)
+xps_parse_fixed_page(xps_context_t *ctx, fz_matrix ctm, xps_page_t *page)
{
- xps_item_t *root, *node;
+ xps_item_t *node;
xps_resource_t *dict;
- char *width_att;
- char *height_att;
- int has_transparency;
char base_uri[1024];
char *s;
int code;
- if_debug1('|', "doc: parsing page %s\n", part->name);
-
- xps_strlcpy(base_uri, part->name, sizeof base_uri);
+ xps_strlcpy(base_uri, page->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 */
+ for (node = xps_down(page->root); node; node = xps_next(node))
{
- 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 )
+ if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
{
- gs_c_param_list_read(&list);
- code = gs_putdeviceparams(dev, (gs_param_list *)&list);
+ code = xps_parse_resource_dictionary(ctx, &dict, base_uri, xps_down(node));
+ if (code)
+ return fz_rethrow(code, "cannot load FixedPage.Resources");
}
- 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");
+ code = xps_parse_element(ctx, ctm, base_uri, dict, node);
+ if (code)
+ return fz_rethrow(code, "cannot parse child of FixedPage");
}
- /* Pre-parse looking for transparency */
-
- has_transparency = 0;
-
- for (node = xps_down(root); node; node = xps_next(node))
+ if (dict)
{
- if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node))
- if (xps_resource_dictionary_has_transparency(ctx, base_uri, xps_down(node)))
- has_transparency = 1;
- if (xps_element_has_transparency(ctx, base_uri, node))
- has_transparency = 1;
+ xps_free_resource_dictionary(ctx, dict);
}
- /* save the state with the original device before we push */
- gs_gsave(ctx->pgs);
-
- if (ctx->use_transparency && has_transparency)
- {
- code = gs_push_pdf14trans_device(ctx->pgs);
- if (code < 0)
- {
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot install transparency device");
- }
- }
+ return fz_okay;
+}
- /* Initialize the default profiles in the ctx to what is in the manager */
- ctx->gray->cmm_icc_profile_data = ctx->pgs->icc_manager->default_gray;
- ctx->srgb->cmm_icc_profile_data = ctx->pgs->icc_manager->default_rgb;
- /* scrgb really needs to be a bit different.
- * Unless we are handling nonlinearity before conversion from float. ToDo. */
- ctx->scrgb->cmm_icc_profile_data = ctx->pgs->icc_manager->default_rgb;
- ctx->cmyk->cmm_icc_profile_data = ctx->pgs->icc_manager->default_cmyk;
+int
+xps_load_fixed_page(xps_context_t *ctx, xps_page_t *page)
+{
+ xps_part_t *part;
+ xps_item_t *root;
+ char *width_att;
+ char *height_att;
- /* Draw contents */
+ part = xps_read_part(ctx, page->name);
+ if (!part)
+ return fz_rethrow(-1, "cannot read zip part '%s'", page->name);
- 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);
- 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);
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse child of FixedPage");
- }
- }
+ root = xps_parse_xml(ctx, part->data, part->size);
+ if (!root)
+ return fz_rethrow(-1, "cannot parse xml");
- if (ctx->use_transparency && has_transparency)
- {
- code = gs_pop_pdf14trans_device(ctx->pgs);
- if (code < 0)
- {
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot uninstall transparency device");
- }
- }
+ xps_free_part(ctx, part);
- /* 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");
- }
- }
+ if (strcmp(xps_tag(root), "FixedPage"))
+ return fz_throw("expected FixedPage element (found %s)", xps_tag(root));
- /* restore the original device, discarding the pdf14 compositor */
- gs_grestore(ctx->pgs);
+ width_att = xps_att(root, "Width");
+ if (!width_att)
+ return fz_throw("FixedPage missing required attribute: Width");
- if (dict)
- {
- xps_free_resource_dictionary(ctx, dict);
- }
+ height_att = xps_att(root, "Height");
+ if (!height_att)
+ return fz_throw("FixedPage missing required attribute: Height");
- xps_free_item(ctx, root);
+ page->width = atoi(width_att);
+ page->height = atoi(height_att);
+ page->root = root;
return 0;
}
diff --git a/xps/xpspath.c b/xps/xpspath.c
index 89e9716a..12377501 100644
--- a/xps/xpspath.c
+++ b/xps/xpspath.c
@@ -1,58 +1,88 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
+static fz_point
+fz_currentpoint(fz_path *path)
+{
+ fz_point c, m;
+ int i;
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
+ c.x = c.y = m.x = m.y = 0;
+ i = 0;
-/* XPS interpreter - path (vector drawing) support */
+ while (i < path->len)
+ {
+ switch (path->els[i++].k)
+ {
+ case FZ_MOVETO:
+ m.x = c.x = path->els[i++].v;
+ m.y = c.y = path->els[i++].v;
+ break;
+ case FZ_LINETO:
+ c.x = path->els[i++].v;
+ c.y = path->els[i++].v;
+ break;
+ case FZ_CURVETO:
+ i += 4;
+ c.x = path->els[i++].v;
+ c.y = path->els[i++].v;
+ break;
+ case FZ_CLOSEPATH:
+ c = m;
+ }
+ }
-#include "ghostxps.h"
+ return c;
+}
void
-xps_clip(xps_context_t *ctx)
+xps_clip(xps_context_t *ctx, fz_matrix ctm)
{
- if (ctx->fill_rule == 0)
- gs_eoclip(ctx->pgs);
- else
- gs_clip(ctx->pgs);
- gs_newpath(ctx->pgs);
+printf("xps_clip\n");
+ assert(ctx->path);
+// ctx->dev->clippath(ctx->dev, ctx->path, ctx->fill_rule == 0, ctm);
+ fz_freepath(ctx->path);
+ ctx->path = NULL;
}
void
-xps_fill(xps_context_t *ctx)
+xps_fill(xps_context_t *ctx, fz_matrix ctm)
{
- if (gs_currentopacityalpha(ctx->pgs) < 0.001)
- gs_newpath(ctx->pgs);
- else if (ctx->fill_rule == 0) {
- if (gs_eofill(ctx->pgs) == gs_error_Remap_Color)
- xps_high_level_pattern(ctx);
- gs_eofill(ctx->pgs);
- }
- else {
- if (gs_fill(ctx->pgs) == gs_error_Remap_Color)
- xps_high_level_pattern(ctx);
- gs_fill(ctx->pgs);
- }
+printf("xps_fill!\n");
+ ctx->dev->fillpath(ctx->dev, ctx->path, ctx->fill_rule == 0, ctm,
+ ctx->colorspace, ctx->color, ctx->alpha);
+ fz_freepath(ctx->path);
+ ctx->path = NULL;
+}
+
+static void
+xps_stroke(xps_context_t *ctx, fz_matrix ctm, fz_strokestate *stroke)
+{
+ ctx->dev->strokepath(ctx->dev, ctx->path, stroke, ctm,
+ ctx->colorspace, ctx->color, ctx->alpha);
+ fz_freepath(ctx->path);
+ ctx->path = NULL;
+}
+
+static void
+xps_clipstroke(xps_context_t *ctx, fz_matrix ctm, fz_strokestate *stroke)
+{
+ ctx->dev->clipstrokepath(ctx->dev, ctx->path, stroke, ctm);
+ fz_freepath(ctx->path);
+ ctx->path = NULL;
}
/* Draw an arc segment transformed by the matrix, we approximate with straight
- * line segments. We cannot use the gs_arc function because they only draw
+ * line segments. We cannot use the fz_arc function because they only draw
* circular arcs, we need to transform the line to make them elliptical but
* without transforming the line width.
*/
static inline void
-xps_draw_arc_segment(xps_context_t *ctx, gs_matrix *mtx, float th0, float th1, int iscw)
+xps_draw_arc_segment(xps_context_t *ctx, fz_matrix mtx, float th0, float th1, int iscw)
{
float t, d;
- gs_point p;
-
+ fz_point p;
+return; // XXX broken
while (th1 < th0)
th1 += M_PI * 2.0;
@@ -60,34 +90,46 @@ xps_draw_arc_segment(xps_context_t *ctx, gs_matrix *mtx, float th0, float th1, i
if (iscw)
{
- gs_point_transform(cos(th0), sin(th0), mtx, &p);
- gs_lineto(ctx->pgs, p.x, p.y);
+ p.x = cos(th0);
+ p.y = sin(th0);
+ p = fz_transformpoint(mtx, p);
+ fz_lineto(ctx->path, p.x, p.y);
for (t = th0; t < th1; t += d)
{
- gs_point_transform(cos(t), sin(t), mtx, &p);
- gs_lineto(ctx->pgs, p.x, p.y);
+ p.x = cos(t);
+ p.y = sin(t);
+ p = fz_transformpoint(mtx, p);
+ fz_lineto(ctx->path, p.x, p.y);
}
- gs_point_transform(cos(th1), sin(th1), mtx, &p);
- gs_lineto(ctx->pgs, p.x, p.y);
+ p.x = cos(th1);
+ p.y = sin(th1);
+ p = fz_transformpoint(mtx, p);
+ fz_lineto(ctx->path, p.x, p.y);
}
else
{
th0 += M_PI * 2;
- gs_point_transform(cos(th0), sin(th0), mtx, &p);
- gs_lineto(ctx->pgs, p.x, p.y);
+ p.x = cos(th0);
+ p.y = sin(th0);
+ p = fz_transformpoint(mtx, p);
+ fz_lineto(ctx->path, p.x, p.y);
for (t = th0; t > th1; t -= d)
{
- gs_point_transform(cos(t), sin(t), mtx, &p);
- gs_lineto(ctx->pgs, p.x, p.y);
+ p.x = cos(t);
+ p.y = sin(t);
+ p = fz_transformpoint(mtx, p);
+ fz_lineto(ctx->path, p.x, p.y);
}
- gs_point_transform(cos(th1), sin(th1), mtx, &p);
- gs_lineto(ctx->pgs, p.x, p.y);
+ p.x = cos(th1);
+ p.y = sin(th1);
+ p = fz_transformpoint(mtx, p);
+ fz_lineto(ctx->path, p.x, p.y);
}
}
/* Given two vectors find the angle between them. */
static inline double
-angle_between(const gs_point u, const gs_point v)
+angle_between(const fz_point u, const fz_point v)
{
double det = u.x * v.y - u.y * v.x;
double sign = (det < 0 ? -1.0 : 1.0);
@@ -107,9 +149,9 @@ xps_draw_arc(xps_context_t *ctx,
int is_large_arc, int is_clockwise,
float point_x, float point_y)
{
- gs_matrix rotmat, revmat;
- gs_matrix mtx;
- gs_point pt;
+ fz_matrix rotmat, revmat;
+ fz_matrix mtx;
+ fz_point pt;
double rx, ry;
double x1, y1, x2, y2;
double x1t, y1t;
@@ -118,7 +160,7 @@ xps_draw_arc(xps_context_t *ctx,
double sign;
double th1, dth;
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
x1 = pt.x;
y1 = pt.y;
x2 = point_x;
@@ -131,8 +173,8 @@ xps_draw_arc(xps_context_t *ctx,
else
sign = -1;
- gs_make_rotation(rotation_angle, &rotmat);
- gs_make_rotation(-rotation_angle, &revmat);
+ rotmat = fz_rotate(rotation_angle);
+ revmat = fz_rotate(-rotation_angle);
/* http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes */
/* Conversion from endpoint to center parameterization */
@@ -142,12 +184,14 @@ xps_draw_arc(xps_context_t *ctx,
ry = fabsf(ry);
if (rx < 0.001 || ry < 0.001)
{
- gs_lineto(ctx->pgs, x2, y2);
+ fz_lineto(ctx->path, x2, y2);
return;
}
/* F.6.5.1 */
- gs_distance_transform((x1 - x2) / 2.0, (y1 - y2) / 2.0, &revmat, &pt);
+ pt.x = (x1 - x2) / 2;
+ pt.y = (y1 - y2) / 2;
+ pt = fz_transformvector(revmat, pt);
x1t = pt.x;
y1t = pt.y;
@@ -171,13 +215,15 @@ xps_draw_arc(xps_context_t *ctx,
cyt = sign * t3 * -(ry * x1t) / rx;
/* F.6.5.3 */
- gs_distance_transform(cxt, cyt, &rotmat, &pt);
+ pt.x = cxt;
+ pt.y = cyt;
+ pt = fz_transformvector(rotmat, pt);
cx = pt.x + (x1 + x2) / 2;
cy = pt.y + (y1 + y2) / 2;
/* F.6.5.4 */
{
- gs_point coord1, coord2, coord3, coord4;
+ fz_point coord1, coord2, coord3, coord4;
coord1.x = 1;
coord1.y = 0;
coord2.x = (x1t - cxt) / rx;
@@ -189,18 +235,18 @@ xps_draw_arc(xps_context_t *ctx,
th1 = angle_between(coord1, coord2);
dth = angle_between(coord3, coord4);
if (dth < 0 && !is_clockwise)
- dth += (degrees_to_radians * 360);
+ dth += ((M_PI / 180.0) * 360);
if (dth > 0 && is_clockwise)
- dth -= (degrees_to_radians * 360);
+ dth -= ((M_PI / 180.0) * 360);
}
- gs_make_identity(&mtx);
- gs_matrix_translate(&mtx, cx, cy, &mtx);
- gs_matrix_rotate(&mtx, rotation_angle, &mtx);
- gs_matrix_scale(&mtx, rx, ry, &mtx);
- xps_draw_arc_segment(ctx, &mtx, th1, th1 + dth, is_clockwise);
+ mtx = fz_identity;
+ mtx = fz_concat(mtx, fz_translate(cx, cy));
+ mtx = fz_concat(mtx, fz_rotate(rotation_angle));
+ mtx = fz_concat(mtx, fz_scale(rx, ry));
+ xps_draw_arc_segment(ctx, mtx, th1, th1 + dth, is_clockwise);
- gs_lineto(ctx->pgs, point_x, point_y);
+ fz_lineto(ctx->path, point_x, point_y);
}
/*
@@ -215,18 +261,17 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
char **args;
char **pargs;
char *s = geom;
- gs_point pt;
+ fz_point pt;
int i, n;
int cmd, old;
float x1, y1, x2, y2, x3, y3;
float smooth_x, smooth_y; /* saved cubic bezier control point for smooth curves */
int reset_smooth;
- args = xps_alloc(ctx, sizeof(char*) * (strlen(geom) + 1));
- pargs = args;
+printf("xps_parse_abbreviated_geometry: %s\n", geom);
- //dprintf1("new path (%.70s)\n", geom);
- gs_newpath(ctx->pgs);
+ args = fz_calloc(strlen(geom) + 1, sizeof(char*));
+ pargs = args;
while (*s)
{
@@ -282,48 +327,44 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
break;
case 'M':
- gs_moveto(ctx->pgs, atof(args[i]), atof(args[i+1]));
- //dprintf2("moveto %g %g\n", atof(args[i]), atof(args[i+1]));
+ fz_moveto(ctx->path, atof(args[i]), atof(args[i+1]));
i += 2;
break;
case 'm':
- gs_rmoveto(ctx->pgs, atof(args[i]), atof(args[i+1]));
- //dprintf2("rmoveto %g %g\n", atof(args[i]), atof(args[i+1]));
+ pt = fz_currentpoint(ctx->path);
+ fz_moveto(ctx->path, pt.x + atof(args[i]), pt.y + atof(args[i+1]));
i += 2;
break;
case 'L':
- gs_lineto(ctx->pgs, atof(args[i]), atof(args[i+1]));
- //dprintf2("lineto %g %g\n", atof(args[i]), atof(args[i+1]));
+ fz_lineto(ctx->path, atof(args[i]), atof(args[i+1]));
i += 2;
break;
case 'l':
- gs_rlineto(ctx->pgs, atof(args[i]), atof(args[i+1]));
- //dprintf2("rlineto %g %g\n", atof(args[i]), atof(args[i+1]));
+ pt = fz_currentpoint(ctx->path);
+ fz_lineto(ctx->path, pt.x + atof(args[i]), pt.y + atof(args[i+1]));
i += 2;
break;
case 'H':
- gs_currentpoint(ctx->pgs, &pt);
- gs_lineto(ctx->pgs, atof(args[i]), pt.y);
- //dprintf1("hlineto %g\n", atof(args[i]));
+ pt = fz_currentpoint(ctx->path);
+ fz_lineto(ctx->path, atof(args[i]), pt.y);
i += 1;
break;
case 'h':
- gs_rlineto(ctx->pgs, atof(args[i]), 0.0);
- //dprintf1("rhlineto %g\n", atof(args[i]));
+ pt = fz_currentpoint(ctx->path);
+ fz_lineto(ctx->path, pt.x + atof(args[i]), pt.y);
i += 1;
break;
case 'V':
- gs_currentpoint(ctx->pgs, &pt);
- gs_lineto(ctx->pgs, pt.x, atof(args[i]));
- //dprintf1("vlineto %g\n", atof(args[i]));
+ pt = fz_currentpoint(ctx->path);
+ fz_lineto(ctx->path, pt.x, atof(args[i]));
i += 1;
break;
case 'v':
- gs_rlineto(ctx->pgs, 0.0, atof(args[i]));
- //dprintf1("rvlineto %g\n", atof(args[i]));
+ pt = fz_currentpoint(ctx->path);
+ fz_lineto(ctx->path, pt.x, pt.y + atof(args[i]));
i += 1;
break;
@@ -334,7 +375,7 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
y2 = atof(args[i+3]);
x3 = atof(args[i+4]);
y3 = atof(args[i+5]);
- gs_curveto(ctx->pgs, x1, y1, x2, y2, x3, y3);
+ fz_curveto(ctx->path, x1, y1, x2, y2, x3, y3);
i += 6;
reset_smooth = 0;
smooth_x = x3 - x2;
@@ -342,14 +383,14 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
break;
case 'c':
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
x1 = atof(args[i+0]) + pt.x;
y1 = atof(args[i+1]) + pt.y;
x2 = atof(args[i+2]) + pt.x;
y2 = atof(args[i+3]) + pt.y;
x3 = atof(args[i+4]) + pt.x;
y3 = atof(args[i+5]) + pt.y;
- gs_curveto(ctx->pgs, x1, y1, x2, y2, x3, y3);
+ fz_curveto(ctx->path, x1, y1, x2, y2, x3, y3);
i += 6;
reset_smooth = 0;
smooth_x = x3 - x2;
@@ -357,13 +398,12 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
break;
case 'S':
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
x1 = atof(args[i+0]);
y1 = atof(args[i+1]);
x2 = atof(args[i+2]);
y2 = atof(args[i+3]);
- //dprintf2("smooth %g %g\n", smooth_x, smooth_y);
- gs_curveto(ctx->pgs, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
+ fz_curveto(ctx->path, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
i += 4;
reset_smooth = 0;
smooth_x = x2 - x1;
@@ -371,13 +411,12 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
break;
case 's':
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
x1 = atof(args[i+0]) + pt.x;
y1 = atof(args[i+1]) + pt.y;
x2 = atof(args[i+2]) + pt.x;
y2 = atof(args[i+3]) + pt.y;
- //dprintf2("smooth %g %g\n", smooth_x, smooth_y);
- gs_curveto(ctx->pgs, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
+ fz_curveto(ctx->path, pt.x + smooth_x, pt.y + smooth_y, x1, y1, x2, y2);
i += 4;
reset_smooth = 0;
smooth_x = x2 - x1;
@@ -385,26 +424,24 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
break;
case 'Q':
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
x1 = atof(args[i+0]);
y1 = atof(args[i+1]);
x2 = atof(args[i+2]);
y2 = atof(args[i+3]);
- //dprintf4("conicto %g %g %g %g\n", x1, y1, x2, y2);
- gs_curveto(ctx->pgs,
+ fz_curveto(ctx->path,
(pt.x + 2 * x1) / 3, (pt.y + 2 * y1) / 3,
(x2 + 2 * x1) / 3, (y2 + 2 * y1) / 3,
x2, y2);
i += 4;
break;
case 'q':
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
x1 = atof(args[i+0]) + pt.x;
y1 = atof(args[i+1]) + pt.y;
x2 = atof(args[i+2]) + pt.x;
y2 = atof(args[i+3]) + pt.y;
- //dprintf4("conicto %g %g %g %g\n", x1, y1, x2, y2);
- gs_curveto(ctx->pgs,
+ fz_curveto(ctx->path,
(pt.x + 2 * x1) / 3, (pt.y + 2 * y1) / 3,
(x2 + 2 * x1) / 3, (y2 + 2 * y1) / 3,
x2, y2);
@@ -419,7 +456,7 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
i += 7;
break;
case 'a':
- gs_currentpoint(ctx->pgs, &pt);
+ pt = fz_currentpoint(ctx->path);
xps_draw_arc(ctx,
atof(args[i+0]), atof(args[i+1]), atof(args[i+2]),
atoi(args[i+3]), atoi(args[i+4]),
@@ -429,8 +466,7 @@ xps_parse_abbreviated_geometry(xps_context_t *ctx, char *geom)
case 'Z':
case 'z':
- gs_closepath(ctx->pgs);
- //dputs("closepath\n");
+ fz_closepath(ctx->path);
break;
default:
@@ -467,7 +503,7 @@ xps_parse_arc_segment(xps_context_t *ctx, xps_item_t *root, int stroking, int *s
if (!point_att || !size_att || !rotation_angle_att || !is_large_arc_att || !sweep_direction_att)
{
- gs_warn("ArcSegment element is missing attributes");
+ fz_warn("ArcSegment element is missing attributes");
return;
}
@@ -485,7 +521,7 @@ xps_parse_arc_segment(xps_context_t *ctx, xps_item_t *root, int stroking, int *s
if (stroking && !is_stroked)
{
- gs_moveto(ctx->pgs, point_x, point_y);
+ fz_moveto(ctx->path, point_x, point_y);
return;
}
@@ -499,13 +535,13 @@ xps_parse_poly_quadratic_bezier_segment(xps_context_t *ctx, xps_item_t *root, in
char *is_stroked_att = xps_att(root, "IsStroked");
float x[2], y[2];
int is_stroked;
- gs_point pt;
+ fz_point pt;
char *s;
int n;
if (!points_att)
{
- gs_warn("PolyQuadraticBezierSegment element has no points");
+ fz_warn("PolyQuadraticBezierSegment element has no points");
return;
}
@@ -527,12 +563,12 @@ xps_parse_poly_quadratic_bezier_segment(xps_context_t *ctx, xps_item_t *root, in
{
if (stroking && !is_stroked)
{
- gs_moveto(ctx->pgs, x[1], y[1]);
+ fz_moveto(ctx->path, x[1], y[1]);
}
else
{
- gs_currentpoint(ctx->pgs, &pt);
- gs_curveto(ctx->pgs,
+ pt = fz_currentpoint(ctx->path);
+ fz_curveto(ctx->path,
(pt.x + 2 * x[0]) / 3, (pt.y + 2 * y[0]) / 3,
(x[1] + 2 * x[0]) / 3, (y[1] + 2 * y[0]) / 3,
x[1], y[1]);
@@ -554,7 +590,7 @@ xps_parse_poly_bezier_segment(xps_context_t *ctx, xps_item_t *root, int stroking
if (!points_att)
{
- gs_warn("PolyBezierSegment element has no points");
+ fz_warn("PolyBezierSegment element has no points");
return;
}
@@ -575,9 +611,9 @@ xps_parse_poly_bezier_segment(xps_context_t *ctx, xps_item_t *root, int stroking
if (n == 3)
{
if (stroking && !is_stroked)
- gs_moveto(ctx->pgs, x[2], y[2]);
+ fz_moveto(ctx->path, x[2], y[2]);
else
- gs_curveto(ctx->pgs, x[0], y[0], x[1], y[1], x[2], y[2]);
+ fz_curveto(ctx->path, x[0], y[0], x[1], y[1], x[2], y[2]);
n = 0;
}
}
@@ -594,7 +630,7 @@ xps_parse_poly_line_segment(xps_context_t *ctx, xps_item_t *root, int stroking,
if (!points_att)
{
- gs_warn("PolyLineSegment element has no points");
+ fz_warn("PolyLineSegment element has no points");
return;
}
@@ -610,9 +646,9 @@ xps_parse_poly_line_segment(xps_context_t *ctx, xps_item_t *root, int stroking,
while (*s == ' ') s++;
sscanf(s, "%g,%g", &x, &y);
if (stroking && !is_stroked)
- gs_moveto(ctx->pgs, x, y);
+ fz_moveto(ctx->path, x, y);
else
- gs_lineto(ctx->pgs, x, y);
+ fz_lineto(ctx->path, x, y);
while (*s != ' ' && *s != 0) s++;
}
}
@@ -647,7 +683,7 @@ xps_parse_path_figure(xps_context_t *ctx, xps_item_t *root, int stroking)
if (!stroking && !is_filled) /* not filled, when filling */
return;
- gs_moveto(ctx->pgs, start_x, start_y);
+ fz_moveto(ctx->path, start_x, start_y);
for (node = xps_down(root); node; node = xps_next(node))
{
@@ -664,9 +700,9 @@ xps_parse_path_figure(xps_context_t *ctx, xps_item_t *root, int stroking)
if (is_closed)
{
if (stroking && skipped_stroke)
- gs_lineto(ctx->pgs, start_x, start_y); /* we've skipped using gs_moveto... */
+ fz_lineto(ctx->path, start_x, start_y); /* we've skipped using fz_moveto... */
else
- gs_closepath(ctx->pgs); /* no skipped segments, safe to closepath properly */
+ fz_closepath(ctx->path); /* no skipped segments, safe to closepath properly */
}
}
@@ -682,10 +718,7 @@ xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *ro
xps_item_t *transform_tag = NULL;
xps_item_t *figures_tag = NULL; /* only used by resource */
- gs_matrix transform;
- gs_matrix saved_transform;
-
- gs_newpath(ctx->pgs);
+ fz_matrix transform;
figures_att = xps_att(root, "Figures");
fill_rule_att = xps_att(root, "FillRule");
@@ -708,17 +741,12 @@ xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *ro
ctx->fill_rule = 0;
}
- gs_make_identity(&transform);
- if (transform_att || transform_tag)
- {
- if (transform_att)
- xps_parse_render_transform(ctx, transform_att, &transform);
- if (transform_tag)
- xps_parse_matrix_transform(ctx, transform_tag, &transform);
- }
-
- gs_currentmatrix(ctx->pgs, &saved_transform);
- gs_concat(ctx->pgs, &transform);
+ transform = fz_identity;
+ if (transform_att)
+ xps_parse_render_transform(ctx, transform_att, &transform);
+ if (transform_tag)
+ xps_parse_matrix_transform(ctx, transform_tag, &transform);
+ // TODO: apply matrix
if (figures_att)
{
@@ -735,8 +763,6 @@ xps_parse_path_geometry(xps_context_t *ctx, xps_resource_t *dict, xps_item_t *ro
if (!strcmp(xps_tag(node), "PathFigure"))
xps_parse_path_figure(ctx, node, stroking);
}
-
- gs_setmatrix(ctx->pgs, &saved_transform);
}
static int
@@ -744,12 +770,12 @@ xps_parse_line_cap(char *attr)
{
if (attr)
{
- if (!strcmp(attr, "Flat")) return gs_cap_butt;
- if (!strcmp(attr, "Square")) return gs_cap_square;
- if (!strcmp(attr, "Round")) return gs_cap_round;
- if (!strcmp(attr, "Triangle")) return gs_cap_triangle;
+ if (!strcmp(attr, "Flat")) return 0;
+ if (!strcmp(attr, "Round")) return 1;
+ if (!strcmp(attr, "Square")) return 2;
+ if (!strcmp(attr, "Triangle")) return 3; /* FIXME add triangle caps */
}
- return gs_cap_butt;
+ return 0;
}
/*
@@ -758,7 +784,7 @@ xps_parse_line_cap(char *attr)
*/
int
-xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
+xps_parse_path(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_item_t *node;
int code;
@@ -794,16 +820,15 @@ xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_ite
char *stroke_miter_limit_att;
char *stroke_thickness_att;
- gs_line_join linejoin;
- float linewidth;
- float miterlimit;
+ fz_strokestate stroke;
+ fz_matrix transform;
float samples[32];
- gs_color_space *colorspace;
-
- gs_gsave(ctx->pgs);
+ fz_colorspace *colorspace;
ctx->fill_rule = 0;
+printf("xps_parse_path\n");
+
/*
* Extract attributes and extended attributes.
*/
@@ -875,162 +900,145 @@ xps_parse_path(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_ite
stroke_tag = NULL;
}
- gs_setlinestartcap(ctx->pgs, xps_parse_line_cap(stroke_start_line_cap_att));
- gs_setlineendcap(ctx->pgs, xps_parse_line_cap(stroke_end_line_cap_att));
- gs_setlinedashcap(ctx->pgs, xps_parse_line_cap(stroke_dash_cap_att));
+ stroke.linecap = xps_parse_line_cap(stroke_start_line_cap_att);
+// fz_setlineendcap(ctx->pgs, xps_parse_line_cap(stroke_end_line_cap_att));
+// fz_setlinedashcap(ctx->pgs, xps_parse_line_cap(stroke_dash_cap_att));
- linejoin = gs_join_miter;
+ stroke.linejoin = 0;
if (stroke_line_join_att)
{
- if (!strcmp(stroke_line_join_att, "Miter")) linejoin = gs_join_miter;
- if (!strcmp(stroke_line_join_att, "Bevel")) linejoin = gs_join_bevel;
- if (!strcmp(stroke_line_join_att, "Round")) linejoin = gs_join_round;
+ if (!strcmp(stroke_line_join_att, "Miter")) stroke.linejoin = 0;
+ if (!strcmp(stroke_line_join_att, "Round")) stroke.linejoin = 1;
+ if (!strcmp(stroke_line_join_att, "Bevel")) stroke.linejoin = 2;
}
- gs_setlinejoin(ctx->pgs, linejoin);
- miterlimit = 10.0;
+ stroke.miterlimit = 10.0;
if (stroke_miter_limit_att)
- miterlimit = atof(stroke_miter_limit_att);
- gs_setmiterlimit(ctx->pgs, miterlimit);
+ stroke.miterlimit = atof(stroke_miter_limit_att);
- linewidth = 1.0;
+ stroke.linewidth = 1.0;
if (stroke_thickness_att)
- linewidth = atof(stroke_thickness_att);
- gs_setlinewidth(ctx->pgs, linewidth);
+ stroke.linewidth = atof(stroke_thickness_att);
+ stroke.dashphase = 0;
+ stroke.dashlen = 0;
if (stroke_dash_array_att)
{
char *s = stroke_dash_array_att;
- float dash_array[100];
- float dash_offset = 0.0;
- int dash_count = 0;
if (stroke_dash_offset_att)
- dash_offset = atof(stroke_dash_offset_att) * linewidth;
+ stroke.dashphase = atof(stroke_dash_offset_att) * stroke.linewidth;
- while (*s)
+ while (*s && stroke.dashlen < nelem(stroke.dashlist))
{
while (*s == ' ')
s++;
- dash_array[dash_count++] = atof(s) * linewidth;
+ stroke.dashlist[stroke.dashlen++] = atof(s) * stroke.linewidth;
while (*s && *s != ' ')
s++;
}
-
- gs_setdash(ctx->pgs, dash_array, dash_count, dash_offset);
- }
- else
- {
- gs_setdash(ctx->pgs, NULL, 0, 0.0);
}
- if (transform_att || transform_tag)
- {
- gs_matrix transform;
-
- if (transform_att)
- xps_parse_render_transform(ctx, transform_att, &transform);
- if (transform_tag)
- xps_parse_matrix_transform(ctx, transform_tag, &transform);
-
- gs_concat(ctx->pgs, &transform);
- }
+ transform = fz_identity;
+ if (transform_att)
+ xps_parse_render_transform(ctx, transform_att, &transform);
+ if (transform_tag)
+ xps_parse_matrix_transform(ctx, transform_tag, &transform);
+ ctm = fz_concat(ctm, transform);
if (clip_att || clip_tag)
{
+ ctx->path = fz_newpath();
if (clip_att)
xps_parse_abbreviated_geometry(ctx, clip_att);
if (clip_tag)
xps_parse_path_geometry(ctx, dict, clip_tag, 0);
- xps_clip(ctx);
- }
-
-#if 0 // XXX
- if (opacity_att || opacity_mask_tag)
- {
- /* clip the bounds with the actual path */
- if (data_att)
- xps_parse_abbreviated_geometry(ctx, data_att);
- if (data_tag)
- xps_parse_path_geometry(ctx, dict, data_tag, 0);
- xps_update_bounds(ctx, &saved_bounds_opacity);
- gs_newpath(ctx->pgs);
+ xps_clip(ctx, ctm);
}
-#endif
- code = xps_begin_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
+ code = xps_begin_opacity(ctx, ctm, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
if (code)
{
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot create transparency group");
+// fz_grestore(ctx->pgs);
+ return fz_rethrow(code, "cannot create transparency group");
}
if (fill_att)
{
+printf(" fill-att\n");
xps_parse_color(ctx, base_uri, fill_att, &colorspace, samples);
if (fill_opacity_att)
samples[0] = atof(fill_opacity_att);
xps_set_color(ctx, colorspace, samples);
+ ctx->path = fz_newpath();
if (data_att)
xps_parse_abbreviated_geometry(ctx, data_att);
if (data_tag)
xps_parse_path_geometry(ctx, dict, data_tag, 0);
- xps_fill(ctx);
+ xps_fill(ctx, ctm);
}
if (fill_tag)
{
+printf(" fill-tag\n");
+ ctx->path = fz_newpath();
if (data_att)
xps_parse_abbreviated_geometry(ctx, data_att);
if (data_tag)
xps_parse_path_geometry(ctx, dict, data_tag, 0);
- code = xps_parse_brush(ctx, fill_uri, dict, fill_tag);
+ code = xps_parse_brush(ctx, ctm, fill_uri, dict, fill_tag);
if (code < 0)
{
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse fill brush");
+// fz_grestore(ctx->pgs);
+ return fz_rethrow(code, "cannot parse fill brush");
}
}
if (stroke_att)
{
+printf(" stroke_att\n");
xps_parse_color(ctx, base_uri, stroke_att, &colorspace, samples);
if (stroke_opacity_att)
samples[0] = atof(stroke_opacity_att);
xps_set_color(ctx, colorspace, samples);
+ ctx->path = fz_newpath();
if (data_att)
xps_parse_abbreviated_geometry(ctx, data_att);
if (data_tag)
xps_parse_path_geometry(ctx, dict, data_tag, 1);
- gs_stroke(ctx->pgs);
+ xps_stroke(ctx, ctm, &stroke);
}
if (stroke_tag)
{
+printf(" stroke_tag\n");
+ ctx->path = fz_newpath();
if (data_att)
xps_parse_abbreviated_geometry(ctx, data_att);
if (data_tag)
xps_parse_path_geometry(ctx, dict, data_tag, 1);
ctx->fill_rule = 1; /* over-ride fill rule when converting outline to stroked */
- gs_strokepath2(ctx->pgs);
+ xps_clipstroke(ctx, ctm, &stroke);
- code = xps_parse_brush(ctx, stroke_uri, dict, stroke_tag);
+ code = xps_parse_brush(ctx, ctm, stroke_uri, dict, stroke_tag);
if (code < 0)
{
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot parse stroke brush");
+// fz_grestore(ctx->pgs);
+ return fz_rethrow(code, "cannot parse stroke brush");
}
+
+ ctx->dev->popclip(ctx->dev);
}
xps_end_opacity(ctx, opacity_mask_uri, dict, opacity_att, opacity_mask_tag);
- gs_grestore(ctx->pgs);
+// fz_grestore(ctx->pgs);
return 0;
}
diff --git a/xps/xpspng.c b/xps/xpspng.c
index d88461cc..c7ed90bc 100644
--- a/xps/xpspng.c
+++ b/xps/xpspng.c
@@ -1,29 +1,7 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - PNG image support */
-
-#include "ghostxps.h"
-
-#include "stream.h"
-#include "strimpl.h"
-#include "gsstate.h"
-
-/* silence a warning where #if SHARE_LIBPNG is used when it's undefined */
-#ifndef SHARE_LIBPNG
-#define SHARE_LIBPNG 0
-#endif
-#include "png_.h"
+#include "png.h"
/*
* PNG using libpng directly (no gs wrappers)
@@ -48,15 +26,13 @@ xps_png_read(png_structp png, png_bytep data, png_size_t length)
static png_voidp
xps_png_malloc(png_structp png, png_size_t size)
{
- gs_memory_t *mem = png_get_mem_ptr(png);
- return gs_alloc_bytes(mem, size, "libpng");
+ return fz_malloc(size);
}
static void
xps_png_free(png_structp png, png_voidp ptr)
{
- gs_memory_t *mem = png_get_mem_ptr(png);
- gs_free_object(mem, ptr, "libpng");
+ fz_free(ptr);
}
/* This only determines if we have an alpha value */
@@ -77,15 +53,15 @@ xps_png_has_alpha(xps_context_t *ctx, byte *rbuf, int rlen)
png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL,
- ctx->memory, xps_png_malloc, xps_png_free);
+ ctx, xps_png_malloc, xps_png_free);
if (!png) {
- gs_warn("png_create_read_struct");
+ fz_warn("png_create_read_struct");
return 0;
}
info = png_create_info_struct(png);
if (!info) {
- gs_warn("png_create_info_struct");
+ fz_warn("png_create_info_struct");
return 0;
}
@@ -99,7 +75,7 @@ xps_png_has_alpha(xps_context_t *ctx, byte *rbuf, int rlen)
if (setjmp(png_jmpbuf(png)))
{
png_destroy_read_struct(&png, &info, NULL);
- gs_warn("png reading failed");
+ fz_warn("png reading failed");
return 0;
}
@@ -123,7 +99,7 @@ xps_png_has_alpha(xps_context_t *ctx, byte *rbuf, int rlen)
break;
default:
- gs_warn("cannot handle this png color type");
+ fz_warn("cannot handle this png color type");
has_alpha = 0;
break;
}
@@ -156,13 +132,13 @@ xps_decode_png(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
png = png_create_read_struct_2(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL,
- ctx->memory, xps_png_malloc, xps_png_free);
+ ctx, xps_png_malloc, xps_png_free);
if (!png)
- return gs_throw(-1, "png_create_read_struct");
+ return fz_throw("png_create_read_struct");
info = png_create_info_struct(png);
if (!info)
- return gs_throw(-1, "png_create_info_struct");
+ return fz_throw("png_create_info_struct");
png_set_read_fn(png, &io, xps_png_read);
png_set_crc_action(png, PNG_CRC_WARN_USE, PNG_CRC_WARN_USE);
@@ -174,7 +150,7 @@ xps_decode_png(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
if (setjmp(png_jmpbuf(png)))
{
png_destroy_read_struct(&png, &info, NULL);
- return gs_throw(-1, "png reading failed");
+ return fz_throw("png reading failed");
}
/*
@@ -225,27 +201,27 @@ xps_decode_png(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
switch (png_get_color_type(png, info))
{
case PNG_COLOR_TYPE_GRAY:
- image->colorspace = ctx->gray;
+ image->colorspace = fz_devicegray;
image->hasalpha = 0;
break;
case PNG_COLOR_TYPE_RGB:
- image->colorspace = ctx->srgb;
+ image->colorspace = fz_devicergb;
image->hasalpha = 0;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
- image->colorspace = ctx->gray;
+ image->colorspace = fz_devicegray;
image->hasalpha = 1;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
- image->colorspace = ctx->srgb;
+ image->colorspace = fz_devicergb;
image->hasalpha = 1;
break;
default:
- return gs_throw(-1, "cannot handle this png color type");
+ return fz_throw("cannot handle this png color type");
}
/*
@@ -289,5 +265,5 @@ xps_decode_png(xps_context_t *ctx, byte *rbuf, int rlen, xps_image_t *image)
png_destroy_read_struct(&png, &info, NULL);
- return gs_okay;
+ return fz_okay;
}
diff --git a/xps/xpsresource.c b/xps/xpsresource.c
index a21d6bed..399c067a 100644
--- a/xps/xpsresource.c
+++ b/xps/xpsresource.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - resource functions */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
static xps_item_t *
xps_find_resource(xps_context_t *ctx, xps_resource_t *dict, char *name, char **urip)
@@ -82,21 +68,21 @@ xps_parse_remote_resource_dictionary(xps_context_t *ctx, xps_resource_t **dictp,
part = xps_read_part(ctx, part_name);
if (!part)
{
- return gs_throw1(-1, "cannot find remote resource part '%s'", part_name);
+ return fz_throw("cannot find remote resource part '%s'", part_name);
}
xml = xps_parse_xml(ctx, part->data, part->size);
if (!xml)
{
xps_free_part(ctx, part);
- return gs_rethrow(-1, "cannot parse xml");
+ return fz_rethrow(-1, "cannot parse xml");
}
if (strcmp(xps_tag(xml), "ResourceDictionary"))
{
xps_free_item(ctx, xml);
xps_free_part(ctx, part);
- return gs_throw1(-1, "expected ResourceDictionary element (found %s)", xps_tag(xml));
+ return fz_throw("expected ResourceDictionary element (found %s)", xps_tag(xml));
}
xps_strlcpy(part_uri, part_name, sizeof part_uri);
@@ -109,7 +95,7 @@ xps_parse_remote_resource_dictionary(xps_context_t *ctx, xps_resource_t **dictp,
{
xps_free_item(ctx, xml);
xps_free_part(ctx, part);
- return gs_rethrow1(code, "cannot parse remote resource dictionary: %s", part_uri);
+ return fz_rethrow(code, "cannot parse remote resource dictionary: %s", part_uri);
}
dict->base_xml = xml; /* pass on ownership */
@@ -117,7 +103,7 @@ xps_parse_remote_resource_dictionary(xps_context_t *ctx, xps_resource_t **dictp,
xps_free_part(ctx, part);
*dictp = dict;
- return gs_okay;
+ return fz_okay;
}
int
@@ -135,8 +121,8 @@ xps_parse_resource_dictionary(xps_context_t *ctx, xps_resource_t **dictp, char *
{
code = xps_parse_remote_resource_dictionary(ctx, dictp, base_uri, source);
if (code)
- return gs_rethrow(code, "cannot parse remote resource dictionary");
- return gs_okay;
+ return fz_rethrow(code, "cannot parse remote resource dictionary");
+ return fz_okay;
}
head = NULL;
@@ -149,7 +135,7 @@ xps_parse_resource_dictionary(xps_context_t *ctx, xps_resource_t **dictp, char *
{
entry = xps_alloc(ctx, sizeof(xps_resource_t));
if (!entry)
- return gs_throw(-1, "cannot allocate resource entry");
+ return fz_throw("cannot allocate resource entry");
entry->name = key;
entry->base_uri = NULL;
entry->base_xml = NULL;
@@ -166,7 +152,7 @@ xps_parse_resource_dictionary(xps_context_t *ctx, xps_resource_t **dictp, char *
}
*dictp = head;
- return gs_okay;
+ return fz_okay;
}
void
@@ -191,13 +177,13 @@ xps_debug_resource_dictionary(xps_resource_t *dict)
while (dict)
{
if (dict->base_uri)
- dprintf1("URI = '%s'\n", dict->base_uri);
- dprintf2("KEY = '%s' VAL = %p\n", dict->name, dict->data);
+ printf("URI = '%s'\n", dict->base_uri);
+ printf("KEY = '%s' VAL = %p\n", dict->name, dict->data);
if (dict->parent)
{
- dputs("PARENT = {\n");
+ printf("PARENT = {\n");
xps_debug_resource_dictionary(dict->parent);
- dputs("}\n");
+ printf("}\n");
}
dict = dict->next;
}
diff --git a/xps/xpstiff.c b/xps/xpstiff.c
index 3e2627ef..27e5ac2b 100644
--- a/xps/xpstiff.c
+++ b/xps/xpstiff.c
@@ -1,19 +1,13 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - TIFF image support */
+int
+xps_decode_tiff(xps_context_t *ctx, byte *buf, int len, xps_image_t *image)
+{
+ return fz_throw("TIFF codec is not available");
+}
-#include "ghostxps.h"
+#if 0
#include "stream.h"
#include "strimpl.h"
@@ -159,7 +153,7 @@ static const byte bitrev[256] =
static int
xps_report_error(stream_state * st, const char *str)
{
- (void) gs_throw1(-1, "%s", str);
+ (void) fz_throw("%s", str);
return 0;
}
@@ -221,7 +215,7 @@ xps_decode_tiff_packbits(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *r
code = s_RLD_template.process((stream_state*)&state, &scr, &scw, true);
if (code == ERRC)
- return gs_throw1(-1, "error in packbits data (code = %d)", code);
+ return fz_throw("error in packbits data (code = %d)", code);
return gs_okay;
}
@@ -264,7 +258,7 @@ xps_decode_tiff_lzw(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl, by
if (code == ERRC)
{
s_LZWD_template.release((stream_state*)&state);
- return gs_throw1(-1, "error in lzw data (code = %d)", code);
+ return fz_throw("error in lzw data (code = %d)", code);
}
s_LZWD_template.release((stream_state*)&state);
@@ -296,7 +290,7 @@ xps_decode_tiff_flate(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl,
if (code == ERRC)
{
s_zlibD_template.release((stream_state*)&state);
- return gs_throw1(-1, "error in flate data (code = %d)", code);
+ return fz_throw("error in flate data (code = %d)", code);
}
s_zlibD_template.release((stream_state*)&state);
@@ -339,7 +333,7 @@ xps_decode_tiff_fax(xps_context_t *ctx, xps_tiff_t *tiff, int comp, byte *rp, by
if (code == ERRC)
{
s_CFD_template.release((stream_state*)&state);
- return gs_throw1(-1, "error in fax data (code = %d)", code);
+ return fz_throw("error in fax data (code = %d)", code);
}
s_CFD_template.release((stream_state*)&state);
@@ -380,7 +374,7 @@ xps_decode_tiff_jpeg(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl, b
jddp.scanline_buffer = NULL;
if ((code = gs_jpeg_create_decompress(&state)) < 0)
- return gs_throw(-1, "error in gs_jpeg_create_decompress");
+ return fz_throw("error in gs_jpeg_create_decompress");
s_DCTD_template.init((stream_state*)&state);
@@ -397,7 +391,7 @@ xps_decode_tiff_jpeg(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl, b
code = gs_jpeg_read_header(&state, FALSE);
if (code != JPEG_HEADER_TABLES_ONLY)
- return gs_throw(-1, "error in jpeg table data");
+ return fz_throw("error in jpeg table data");
}
/*
@@ -408,7 +402,7 @@ xps_decode_tiff_jpeg(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl, b
srcmgr->bytes_in_buffer = rl - rp;
if ((code = gs_jpeg_read_header(&state, TRUE)) < 0)
- return gs_throw(-1, "error in jpeg_read_header");
+ return fz_throw("error in jpeg_read_header");
/* when TIFF says RGB and libjpeg says YCbCr, libjpeg is wrong */
if (tiff->photometric == 2 && jddp.dinfo.jpeg_color_space == JCS_YCbCr)
@@ -421,7 +415,7 @@ xps_decode_tiff_jpeg(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl, b
*/
if ((code = gs_jpeg_start_decompress(&state)) < 0)
- return gs_throw(-1, "error in jpeg_start_decompress");
+ return fz_throw("error in jpeg_start_decompress");
stride = jddp.dinfo.output_width * jddp.dinfo.output_components;
@@ -439,7 +433,7 @@ xps_decode_tiff_jpeg(xps_context_t *ctx, xps_tiff_t *tiff, byte *rp, byte *rl, b
*/
if ((code = gs_jpeg_finish_decompress(&state)) < 0)
- return gs_throw(-1, "error in jpeg_finish_decompress");
+ return fz_throw("error in jpeg_finish_decompress");
gs_jpeg_destroy(&state);
@@ -537,16 +531,16 @@ xps_expand_colormap(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
/* image can be with or without extrasamples: comps is 1 or 2 */
if (image->comps != 1 && image->comps != 2)
- return gs_throw(-1, "invalid number of samples for RGBPal");
+ return fz_throw("invalid number of samples for RGBPal");
if (image->bits != 4 && image->bits != 8)
- return gs_throw(-1, "invalid number of bits for RGBPal");
+ return fz_throw("invalid number of bits for RGBPal");
stride = image->width * (image->comps + 2);
samples = xps_alloc(ctx, stride * image->height);
if (!samples)
- return gs_throw(-1, "out of memory: samples");
+ return fz_throw("out of memory: samples");
for (y = 0; y < image->height; y++)
{
@@ -601,10 +595,10 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
unsigned i;
if (!tiff->rowsperstrip || !tiff->stripoffsets || !tiff->rowsperstrip)
- return gs_throw(-1, "no image data in tiff; maybe it is tiled");
+ return fz_throw("no image data in tiff; maybe it is tiled");
if (tiff->planar != 1)
- return gs_throw(-1, "image data is not in chunky format");
+ return fz_throw("image data is not in chunky format");
image->width = tiff->imagewidth;
image->height = tiff->imagelength;
@@ -634,7 +628,7 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
image->colorspace = ctx->srgb;
break;
default:
- return gs_throw1(-1, "unknown photometric: %d", tiff->photometric);
+ return fz_throw("unknown photometric: %d", tiff->photometric);
}
switch (tiff->resolutionunit)
@@ -663,7 +657,7 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
image->samples = xps_alloc(ctx, image->stride * image->height);
if (!image->samples)
- return gs_throw(-1, "could not allocate image samples");
+ return fz_throw("could not allocate image samples");
memset(image->samples, 0x55, image->stride * image->height);
@@ -681,7 +675,7 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
wlen = image->samples + image->stride * image->height - wp;
if (rp + rlen > tiff->ep)
- return gs_throw(-1, "strip extends beyond the end of the file");
+ return fz_throw("strip extends beyond the end of the file");
/* the bits are in un-natural order */
if (tiff->fillorder == 2)
@@ -706,7 +700,7 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
error = xps_decode_tiff_lzw(ctx, tiff, rp, rp + rlen, wp, wp + wlen);
break;
case 6:
- error = gs_throw(-1, "deprecated JPEG in TIFF compression not supported");
+ error = fz_throw("deprecated JPEG in TIFF compression not supported");
break;
case 7:
error = xps_decode_tiff_jpeg(ctx, tiff, rp, rp + rlen, wp, wp + wlen);
@@ -718,11 +712,11 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
error = xps_decode_tiff_packbits(ctx, tiff, rp, rp + rlen, wp, wp + wlen);
break;
default:
- error = gs_throw1(-1, "unknown TIFF compression: %d", tiff->compression);
+ error = fz_throw("unknown TIFF compression: %d", tiff->compression);
}
if (error)
- return gs_rethrow1(error, "could not decode strip %d", row / tiff->rowsperstrip);
+ return fz_rethrow(error, "could not decode strip %d", row / tiff->rowsperstrip);
/* scramble the bits back into original order */
if (tiff->fillorder == 2)
@@ -749,7 +743,7 @@ xps_decode_tiff_strips(xps_context_t *ctx, xps_tiff_t *tiff, xps_image_t *image)
{
error = xps_expand_colormap(ctx, tiff, image);
if (error)
- return gs_rethrow(error, "could not expand colormap");
+ return fz_rethrow(error, "could not expand colormap");
}
/* WhiteIsZero .. invert */
@@ -895,7 +889,7 @@ xps_read_tiff_tag(xps_context_t *ctx, xps_tiff_t *tiff, unsigned offset)
case ICCProfile:
tiff->profile = xps_alloc(ctx, count);
if (!tiff->profile)
- return gs_throw(-1, "could not allocate embedded icc profile");
+ return fz_throw("could not allocate embedded icc profile");
/* ICC profile data type is set to UNDEFINED.
* TBYTE reading not correct in xps_read_tiff_tag_value */
xps_read_tiff_bytes(tiff->profile, tiff, value, count);
@@ -910,21 +904,21 @@ xps_read_tiff_tag(xps_context_t *ctx, xps_tiff_t *tiff, unsigned offset)
case StripOffsets:
tiff->stripoffsets = (unsigned*) xps_alloc(ctx, count * sizeof(unsigned));
if (!tiff->stripoffsets)
- return gs_throw(-1, "could not allocate strip offsets");
+ return fz_throw("could not allocate strip offsets");
xps_read_tiff_tag_value(tiff->stripoffsets, tiff, type, value, count);
break;
case StripByteCounts:
tiff->stripbytecounts = (unsigned*) xps_alloc(ctx, count * sizeof(unsigned));
if (!tiff->stripbytecounts)
- return gs_throw(-1, "could not allocate strip byte counts");
+ return fz_throw("could not allocate strip byte counts");
xps_read_tiff_tag_value(tiff->stripbytecounts, tiff, type, value, count);
break;
case ColorMap:
tiff->colormap = (unsigned*) xps_alloc(ctx, count * sizeof(unsigned));
if (!tiff->colormap)
- return gs_throw(-1, "could not allocate color map");
+ return fz_throw("could not allocate color map");
xps_read_tiff_tag_value(tiff->colormap, tiff, type, value, count);
break;
@@ -932,7 +926,7 @@ xps_read_tiff_tag(xps_context_t *ctx, xps_tiff_t *tiff, unsigned offset)
case TileLength:
case TileOffsets:
case TileByteCounts:
- return gs_throw(-1, "tiled tiffs not supported");
+ return fz_throw("tiled tiffs not supported");
default:
/* printf("unknown tag: %d t=%d n=%d\n", tag, type, count); */
@@ -990,12 +984,12 @@ xps_decode_tiff_header(xps_context_t *ctx, xps_tiff_t *tiff, byte *buf, int len)
tiff->order = TII;
tiff->order = readshort(tiff);
if (tiff->order != TII && tiff->order != TMM)
- return gs_throw(-1, "not a TIFF file, wrong magic marker");
+ return fz_throw("not a TIFF file, wrong magic marker");
/* check version */
version = readshort(tiff);
if (version != 42)
- return gs_throw(-1, "not a TIFF file, wrong version marker");
+ return fz_throw("not a TIFF file, wrong version marker");
/* get offset of IFD */
offset = readlong(tiff);
@@ -1013,7 +1007,7 @@ xps_decode_tiff_header(xps_context_t *ctx, xps_tiff_t *tiff, byte *buf, int len)
{
error = xps_read_tiff_tag(ctx, tiff, offset);
if (error)
- return gs_rethrow(error, "could not read TIFF header tag");
+ return fz_rethrow(error, "could not read TIFF header tag");
offset += 12;
}
@@ -1029,7 +1023,7 @@ xps_decode_tiff(xps_context_t *ctx, byte *buf, int len, xps_image_t *image)
error = xps_decode_tiff_header(ctx, tiff, buf, len);
if (error)
- return gs_rethrow(error, "cannot decode tiff header");
+ return fz_rethrow(error, "cannot decode tiff header");
/*
* Decode the image strips
@@ -1040,7 +1034,7 @@ xps_decode_tiff(xps_context_t *ctx, byte *buf, int len, xps_image_t *image)
error = xps_decode_tiff_strips(ctx, tiff, image);
if (error)
- return gs_rethrow(error, "could not decode image data");
+ return fz_rethrow(error, "could not decode image data");
/*
* Byte swap 16-bit images to big endian if necessary.
@@ -1089,3 +1083,4 @@ xps_tiff_has_alpha(xps_context_t *ctx, byte *buf, int len)
return tiff->extrasamples == 2 || tiff->extrasamples == 1;
}
+#endif
diff --git a/xps/xpstile.c b/xps/xpstile.c
index d7118b52..4f2f57ec 100644
--- a/xps/xpstile.c
+++ b/xps/xpstile.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - tiles for pattern rendering */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
/*
* Parse a tiling brush (visual and image brushes at this time) common
@@ -28,7 +14,7 @@ struct tile_closure_s
char *base_uri;
xps_resource_t *dict;
xps_item_t *tag;
- gs_rect viewbox;
+ fz_rect viewbox;
int tile_mode;
void *user;
int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*);
@@ -40,6 +26,7 @@ xps_paint_tiling_brush_clipped(struct tile_closure_s *c)
xps_context_t *ctx = c->ctx;
int code;
+#if 0
gs_moveto(ctx->pgs, c->viewbox.p.x, c->viewbox.p.y);
gs_lineto(ctx->pgs, c->viewbox.p.x, c->viewbox.q.y);
gs_lineto(ctx->pgs, c->viewbox.q.x, c->viewbox.q.y);
@@ -47,14 +34,16 @@ xps_paint_tiling_brush_clipped(struct tile_closure_s *c)
gs_closepath(ctx->pgs);
gs_clip(ctx->pgs);
gs_newpath(ctx->pgs);
+#endif
code = c->func(c->ctx, c->base_uri, c->dict, c->tag, c->user);
if (code < 0)
- return gs_rethrow(code, "cannot draw clipped tile");
+ return fz_rethrow(code, "cannot draw clipped tile");
return 0;
}
+#if 0
static int
xps_paint_tiling_brush(const gs_client_color *pcc, gs_state *pgs)
{
@@ -113,103 +102,14 @@ xps_paint_tiling_brush(const gs_client_color *pcc, gs_state *pgs)
cleanup:
gs_grestore(ctx->pgs);
ctx->pgs = saved_pgs;
- return gs_rethrow(code, "cannot draw tile");
-}
-
-int
-xps_high_level_pattern(xps_context_t *ctx)
-{
- gs_matrix m;
- gs_rect bbox;
- gs_fixed_rect clip_box;
- int code;
- gx_device_color *pdc = gs_currentdevicecolor_inline(ctx->pgs);
- const gs_client_pattern *ppat = gs_getpattern(&pdc->ccolor);
- gs_pattern1_instance_t *pinst =
- (gs_pattern1_instance_t *)gs_currentcolor(ctx->pgs)->pattern;
-
- code = gx_pattern_cache_add_dummy_entry((gs_imager_state *)ctx->pgs,
- pinst, ctx->pgs->device->color_info.depth);
- if (code < 0)
- return code;
-
- code = gs_gsave(ctx->pgs);
- if (code < 0)
- return code;
-
- dev_proc(ctx->pgs->device, get_initial_matrix)(ctx->pgs->device, &m);
- gs_setmatrix(ctx->pgs, &m);
- code = gs_bbox_transform(&ppat->BBox, &ctm_only(ctx->pgs), &bbox);
- if (code < 0) {
- gs_grestore(ctx->pgs);
- return code;
- }
- clip_box.p.x = float2fixed(bbox.p.x);
- clip_box.p.y = float2fixed(bbox.p.y);
- clip_box.q.x = float2fixed(bbox.q.x);
- clip_box.q.y = float2fixed(bbox.q.y);
- code = gx_clip_to_rectangle(ctx->pgs, &clip_box);
- if (code < 0) {
- gs_grestore(ctx->pgs);
- return code;
- }
- code = dev_proc(ctx->pgs->device, pattern_manage)(ctx->pgs->device, pinst->id, pinst,
- pattern_manage__start_accum);
- if (code < 0) {
- gs_grestore(ctx->pgs);
- return code;
- }
-
- code = xps_paint_tiling_brush(&pdc->ccolor, ctx->pgs);
- if (code) {
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "high level pattern brush function failed");
- }
-
- code = gs_grestore(ctx->pgs);
- if (code < 0)
- return code;
-
- code = dev_proc(ctx->pgs->device, pattern_manage)(ctx->pgs->device, gx_no_bitmap_id, NULL,
- pattern_manage__finish_accum);
-
- return code;
-}
-
-static int
-xps_remap_pattern(const gs_client_color *pcc, gs_state *pgs)
-{
- const gs_client_pattern *ppat = gs_getpattern(pcc);
- struct tile_closure_s *c = ppat->client_data;
- xps_context_t *ctx = c->ctx;
- int code;
-
- /* pgs->device is the newly created pattern accumulator, but we want to test the device
- * that is 'behind' that, the actual output device, so we use the one from
- * the saved XPS graphics state.
- */
- code = dev_proc(ctx->pgs->device, pattern_manage)(ctx->pgs->device, ppat->uid.id, ppat,
- pattern_manage__can_accum);
-
- if (code == 1) {
- /* Device handles high-level patterns, so return 'remap'.
- * This closes the internal accumulator device, as we no longer need
- * it, and the error trickles back up to the PDL client. The client
- * must then take action to start the device's accumulator, draw the
- * pattern, close the device's accumulator and generate a cache entry.
- */
- return gs_error_Remap_Color;
- } else {
- code = xps_paint_tiling_brush(pcc, pgs);
- if (code)
- return gs_rethrow(code, "remap pattern brush function failed");
- return 0;
- }
+ return fz_rethrow(code, "cannot draw tile");
}
+#endif
int
-xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root,
- int (*func)(xps_context_t*, char*, xps_resource_t*, xps_item_t*, void*), void *user)
+xps_parse_tiling_brush(xps_context_t *ctx, fz_matrix ctm,
+ char *base_uri, xps_resource_t *dict, xps_item_t *root,
+ int (*func)(xps_context_t*, fz_matrix, char*, xps_resource_t*, xps_item_t*, void*), void *user)
{
xps_item_t *node;
int code;
@@ -224,9 +124,9 @@ xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
xps_item_t *transform_tag = NULL;
- gs_matrix transform;
- gs_rect viewbox;
- gs_rect viewport;
+ fz_matrix transform;
+ fz_rect viewbox;
+ fz_rect viewport;
float scalex, scaley;
int tile_mode;
@@ -248,30 +148,28 @@ xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
xps_resolve_resource_reference(ctx, dict, &transform_att, &transform_tag, NULL);
- gs_make_identity(&transform);
+ transform = fz_identity;
if (transform_att)
xps_parse_render_transform(ctx, transform_att, &transform);
if (transform_tag)
xps_parse_matrix_transform(ctx, transform_tag, &transform);
- viewbox.p.x = 0.0; viewbox.p.y = 0.0;
- viewbox.q.x = 1.0; viewbox.q.y = 1.0;
+ viewbox = fz_unitrect;
if (viewbox_att)
xps_parse_rectangle(ctx, viewbox_att, &viewbox);
- viewport.p.x = 0.0; viewport.p.y = 0.0;
- viewport.q.x = 1.0; viewport.q.y = 1.0;
+ viewport = fz_unitrect;
if (viewport_att)
xps_parse_rectangle(ctx, viewport_att, &viewport);
/* some sanity checks on the viewport/viewbox size */
- if (fabs(viewport.q.x - viewport.p.x) < 0.01) return 0;
- if (fabs(viewport.q.y - viewport.p.y) < 0.01) return 0;
- if (fabs(viewbox.q.x - viewbox.p.x) < 0.01) return 0;
- if (fabs(viewbox.q.y - viewbox.p.y) < 0.01) return 0;
+ if (fabs(viewport.x1 - viewport.x0) < 0.01) return 0;
+ if (fabs(viewport.y1 - viewport.y0) < 0.01) return 0;
+ if (fabs(viewbox.x1 - viewbox.x0) < 0.01) return 0;
+ if (fabs(viewbox.y1 - viewbox.y0) < 0.01) return 0;
- scalex = (viewport.q.x - viewport.p.x) / (viewbox.q.x - viewbox.p.x);
- scaley = (viewport.q.y - viewport.p.y) / (viewbox.q.y - viewbox.p.y);
+ scalex = (viewport.x1 - viewport.x0) / (viewbox.x1 - viewbox.x0);
+ scaley = (viewport.y1 - viewport.y0) / (viewbox.y1 - viewbox.y0);
tile_mode = TILE_NONE;
if (tile_mode_att)
@@ -288,24 +186,25 @@ xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
tile_mode = TILE_FLIP_X_Y;
}
- gs_gsave(ctx->pgs);
+// gs_gsave(ctx->pgs);
- code = xps_begin_opacity(ctx, base_uri, dict, opacity_att, NULL);
+ code = xps_begin_opacity(ctx, ctm, base_uri, dict, opacity_att, NULL);
if (code)
{
- gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot create transparency group");
+// gs_grestore(ctx->pgs);
+ return fz_rethrow(code, "cannot create transparency group");
}
/* TODO(tor): check viewport and tiling to see if we can set it to TILE_NONE */
+#if 0
if (tile_mode != TILE_NONE)
{
struct tile_closure_s closure;
gs_client_pattern gspat;
gs_client_color gscolor;
- gs_color_space *cs;
+ fz_colorspace *cs;
closure.ctx = ctx;
closure.base_uri = base_uri;
@@ -346,9 +245,9 @@ xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
gspat.YStep *= 2;
}
- gs_matrix_translate(&transform, viewport.p.x, viewport.p.y, &transform);
- gs_matrix_scale(&transform, scalex, scaley, &transform);
- gs_matrix_translate(&transform, -viewbox.p.x, -viewbox.p.y, &transform);
+ fz_matrix_translate(&transform, viewport.p.x, viewport.p.y, &transform);
+ fz_matrix_scale(&transform, scalex, scaley, &transform);
+ fz_matrix_translate(&transform, -viewbox.p.x, -viewbox.p.y, &transform);
cs = ctx->srgb;
gs_setcolorspace(ctx->pgs, cs);
@@ -387,13 +286,14 @@ xps_parse_tiling_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
{
xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
gs_grestore(ctx->pgs);
- return gs_rethrow(code, "cannot draw tile");
+ return fz_rethrow(code, "cannot draw tile");
}
}
+#endif
xps_end_opacity(ctx, base_uri, dict, opacity_att, NULL);
- gs_grestore(ctx->pgs);
+// gs_grestore(ctx->pgs);
return 0;
}
diff --git a/xps/xpstop.c b/xps/xpstop.c
index 13149da6..afc64569 100644
--- a/xps/xpstop.c
+++ b/xps/xpstop.c
@@ -1,576 +1,384 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* Top-level API implementation of XML Paper Specification */
-
-/* Language wrapper implementation (see pltop.h) */
-
-#include "ghostxps.h"
-
-#include "pltop.h"
-#include "plparse.h" /* for e_ExitLanguage */
-
-#include "gxdevice.h" /* so we can include gxht.h below */
-#include "gxht.h" /* gsht1.h is incomplete, we need storage size of gs_halftone */
-#include "gsht1.h"
-
-int xps_zip_trace = 0;
-int xps_doc_trace = 0;
-
-static int xps_install_halftone(xps_context_t *ctx, gx_device *pdevice);
+#ifdef _MSC_VER
+#include <winsock2.h>
+#else
+#include <sys/time.h>
+#endif
-#define XPS_PARSER_MIN_INPUT_SIZE (8192 * 4)
+char *output = NULL;
+float resolution = 72;
-/*
- * The XPS interpeter is identical to pl_interp_t.
- * The XPS interpreter instance is derived from pl_interp_instance_t.
- */
+int showxml = 0;
+int showtext = 0;
+int showtime = 0;
+int showmd5 = 0;
+int savealpha = 0;
+int uselist = 1;
-typedef struct xps_interp_instance_s xps_interp_instance_t;
+fz_colorspace *colorspace;
+fz_glyphcache *glyphcache;
+char *filename;
-struct xps_interp_instance_s
+/* stub function for automatic resolution of indirect objects in obj_simple.c */
+int pdf_cacheobject(struct pdf_xref_s *xref, int num, int gen)
{
- pl_interp_instance_t pl; /* common part: must be first */
-
- pl_page_action_t pre_page_action; /* action before page out */
- void *pre_page_closure; /* closure to call pre_page_action with */
- pl_page_action_t post_page_action; /* action before page out */
- void *post_page_closure; /* closure to call post_page_action with */
-
- xps_context_t *ctx;
- FILE *scratch_file;
- char scratch_name[gp_file_name_sizeof];
-};
+ return fz_throw("not a pdf");
+}
-/* version and build date are not currently used */
-#define XPS_VERSION NULL
-#define XPS_BUILD_DATE NULL
+struct {
+ int count, total;
+ int min, max;
+ int minpage, maxpage;
+} timing;
-static const pl_interp_characteristics_t *
-xps_imp_characteristics(const pl_interp_implementation_t *pimpl)
+static void die(fz_error error)
{
- static pl_interp_characteristics_t xps_characteristics =
- {
- "XPS",
- "PK", /* string to recognize XPS files */
- "Artifex",
- XPS_VERSION,
- XPS_BUILD_DATE,
- XPS_PARSER_MIN_INPUT_SIZE, /* Minimum input size */
- };
- return &xps_characteristics;
+ fz_catch(error, "aborting");
+ exit(1);
}
-static int
-xps_imp_allocate_interp(pl_interp_t **ppinterp,
- const pl_interp_implementation_t *pimpl,
- gs_memory_t *pmem)
+static void usage(void)
{
- static pl_interp_t interp; /* there's only one interpreter */
- *ppinterp = &interp;
- return 0;
+ fprintf(stderr,
+ "usage: xpsdraw [options] input.xps [pages]\n"
+ "\t-o -\toutput filename (%%d for page number)\n"
+ "\t\tsupported formats: pgm, ppm, pam, png\n"
+ "\t-r -\tresolution in dpi (default: 72)\n"
+ "\t-a\tsave alpha channel (only pam and png)\n"
+ "\t-g\trender in grayscale\n"
+ "\t-m\tshow timing information\n"
+ "\t-t\tshow text (-tt for xml)\n"
+ "\t-x\tshow display list\n"
+ "\t-d\tdisable use of display list\n"
+ "\t-5\tshow md5 checksums\n"
+ "\tpages\tcomma separated list of ranges\n");
+ exit(1);
}
-/* Do per-instance interpreter allocation/init. No device is set yet */
-static int
-xps_imp_allocate_interp_instance(pl_interp_instance_t **ppinstance,
- pl_interp_t *pinterp,
- gs_memory_t *pmem)
+static int gettime(void)
{
- xps_interp_instance_t *instance;
- xps_context_t *ctx;
- gs_state *pgs;
- int code;
-
- instance = (xps_interp_instance_t *) gs_alloc_bytes(pmem,
- sizeof(xps_interp_instance_t), "xps_imp_allocate_interp_instance");
-
- ctx = (xps_context_t *) gs_alloc_bytes(pmem,
- sizeof(xps_context_t), "xps_imp_allocate_interp_instance");
-
- pgs = gs_state_alloc(pmem);
-#ifdef ICCBRANCH
- gsicc_init_iccmanager(pgs);
-#endif
- memset(ctx, 0, sizeof(xps_context_t));
-
- if (!instance || !ctx || !pgs)
+ static struct timeval first;
+ static int once = 1;
+ struct timeval now;
+ if (once)
{
- if (instance)
- gs_free_object(pmem, instance, "xps_imp_allocate_interp_instance");
- if (ctx)
- gs_free_object(pmem, ctx, "xps_imp_allocate_interp_instance");
- if (pgs)
- gs_state_free(pgs);
- return gs_error_VMerror;
+ gettimeofday(&first, NULL);
+ once = 0;
}
-
- ctx->instance = instance;
- ctx->memory = pmem;
- ctx->pgs = pgs;
- /* Declare PDL client support for high level patterns, for the benefit
- * of pdfwrite and other high-level devices
- */
- ctx->pgs->have_pattern_streams = true;
- ctx->fontdir = NULL;
- ctx->file = NULL;
- ctx->zip_count = 0;
- ctx->zip_table = NULL;
-
- /* Gray, RGB and CMYK profiles set when color spaces installed in graphics lib */
- ctx->gray = gs_cspace_new_DeviceGray(ctx->memory);
- ctx->cmyk = gs_cspace_new_DeviceCMYK(ctx->memory);
- ctx->srgb = gs_cspace_new_DeviceRGB(ctx->memory);
- ctx->scrgb = gs_cspace_new_DeviceRGB(ctx->memory); /* This needs a different profile */
-
- instance->pre_page_action = 0;
- instance->pre_page_closure = 0;
- instance->post_page_action = 0;
- instance->post_page_closure = 0;
-
- instance->ctx = ctx;
- instance->scratch_file = NULL;
- instance->scratch_name[0] = 0;
-
- ctx->fontdir = gs_font_dir_alloc(ctx->memory);
- gs_setaligntopixels(ctx->fontdir, 1); /* no subpixels */
- gs_setgridfittt(ctx->fontdir, 1); /* see gx_ttf_outline in gxttfn.c for values */
-
- *ppinstance = (pl_interp_instance_t *)instance;
-
- return 0;
-}
-
-/* Set a client language into an interperter instance */
-static int
-xps_imp_set_client_instance(pl_interp_instance_t *pinstance,
- pl_interp_instance_t *pclient,
- pl_interp_instance_clients_t which_client)
-{
- /* ignore */
- return 0;
+ gettimeofday(&now, NULL);
+ return (now.tv_sec - first.tv_sec) * 1000 + (now.tv_usec - first.tv_usec) / 1000;
}
-static int
-xps_imp_set_pre_page_action(pl_interp_instance_t *pinstance,
- pl_page_action_t action, void *closure)
+static int isrange(char *s)
{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- instance->pre_page_action = action;
- instance->pre_page_closure = closure;
- return 0;
-}
-
-static int
-xps_imp_set_post_page_action(pl_interp_instance_t *pinstance,
- pl_page_action_t action, void *closure)
-{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- instance->post_page_action = action;
- instance->post_page_closure = closure;
- return 0;
+ while (*s)
+ {
+ if ((*s < '0' || *s > '9') && *s != '-' && *s != ',')
+ return 0;
+ s++;
+ }
+ return 1;
}
static int
-xps_imp_set_device(pl_interp_instance_t *pinstance, gx_device *pdevice)
+xps_run_page(xps_context_t *ctx, xps_page_t *page, fz_device *dev, fz_matrix ctm)
{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
int code;
- gs_opendevice(pdevice);
-
-#ifdef ICCBRANCH
- code = gsicc_init_device_profile(ctx->pgs, pdevice);
- if (code < 0)
- return code;
-#endif
-
- code = gs_setdevice_no_erase(ctx->pgs, pdevice);
- if (code < 0)
- goto cleanup_setdevice;
-
- gs_setaccuratecurves(ctx->pgs, true); /* NB not sure */
- gs_setfilladjust(ctx->pgs, 0, 0);
-
- /* gsave and grestore (among other places) assume that */
- /* there are at least 2 gstates on the graphics stack. */
- /* Ensure that now. */
- code = gs_gsave(ctx->pgs);
- if (code < 0)
- goto cleanup_gsave;
+ ctx->dev = dev;
- code = gs_erasepage(ctx->pgs);
- if (code < 0)
- goto cleanup_erase;
-
- code = xps_install_halftone(ctx, pdevice);
- if (code < 0)
- goto cleanup_halftone;
-
- return 0;
-
-cleanup_halftone:
-cleanup_erase:
- /* undo gsave */
- gs_grestore_only(ctx->pgs); /* destroys gs_save stack */
-
-cleanup_gsave:
- /* undo setdevice */
- gs_nulldevice(ctx->pgs);
+ code = xps_parse_fixed_page(ctx, ctm, page);
+ if (code)
+ return fz_rethrow(code, "cannot draw page part %s", page->name);
-cleanup_setdevice:
- /* nothing to undo */
- return code;
-}
+ ctx->dev = nil;
-static int
-xps_imp_get_device_memory(pl_interp_instance_t *pinstance, gs_memory_t **ppmem)
-{
- /* huh? we do nothing here */
- return 0;
+ return fz_okay;
}
-/* Parse an entire random access file */
-static int
-xps_imp_process_file(pl_interp_instance_t *pinstance, char *filename)
+static void drawpage(xps_context_t *ctx, int pagenum)
{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
- int code;
+ fz_error error;
+ xps_page_t *page;
+ fz_displaylist *list;
+ fz_device *dev;
+ int start;
- code = xps_process_file(ctx, filename);
- if (code)
- gs_catch1(code, "cannot process xps file '%s'", filename);
+ if (showtime)
+ {
+ start = gettime();
+ }
- return code;
-}
+ page = xps_load_page(ctx, pagenum - 1);
+ if (!page)
+ die(fz_throw("cannot load page %d in file '%s'", pagenum, filename));
-/* Parse a cursor-full of data */
-static int
-xps_imp_process(pl_interp_instance_t *pinstance, stream_cursor_read *cursor)
-{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
- int avail, n;
+ list = nil;
- if (!instance->scratch_file)
+ if (uselist)
{
- instance->scratch_file = gp_open_scratch_file(ctx->memory,
- "ghostxps-scratch-", instance->scratch_name, "wb");
- if (!instance->scratch_file)
- {
- gs_catch(gs_error_invalidfileaccess, "cannot open scratch file");
- return e_ExitLanguage;
- }
- if_debug1('|', "xps: open scratch file '%s'\n", instance->scratch_name);
+ list = fz_newdisplaylist();
+ dev = fz_newlistdevice(list);
+ error = xps_run_page(ctx, page, dev, fz_identity);
+ if (error)
+ die(fz_rethrow(error, "cannot draw page %d in file '%s'", pagenum, filename));
+ fz_freedevice(dev);
}
- avail = cursor->limit - cursor->ptr;
- n = fwrite(cursor->ptr + 1, 1, avail, instance->scratch_file);
- if (n != avail)
+ if (showxml)
{
- gs_catch(gs_error_invalidfileaccess, "cannot write to scratch file");
- return e_ExitLanguage;
+ dev = fz_newtracedevice();
+ printf("<page number=\"%d\">\n", pagenum);
+ if (list)
+ fz_executedisplaylist(list, dev, fz_identity);
+ else
+ xps_run_page(ctx, page, dev, fz_identity);
+ printf("</page>\n");
+ fz_freedevice(dev);
}
- cursor->ptr = cursor->limit;
-
- return 0;
-}
-/* Skip to end of job.
- * Return 1 if done, 0 ok but EOJ not found, else negative error code.
- */
-static int
-xps_imp_flush_to_eoj(pl_interp_instance_t *pinstance, stream_cursor_read *pcursor)
-{
- /* assume XPS cannot be pjl embedded */
- pcursor->ptr = pcursor->limit;
- return 0;
-}
+ if (showtext)
+ {
+ fz_textspan *text = fz_newtextspan();
+ dev = fz_newtextdevice(text);
+ if (list)
+ fz_executedisplaylist(list, dev, fz_identity);
+ else
+ xps_run_page(ctx, page, dev, fz_identity);
+ fz_freedevice(dev);
+ printf("[Page %d]\n", pagenum);
+ if (showtext > 1)
+ fz_debugtextspanxml(text);
+ else
+ fz_debugtextspan(text);
+ printf("\n");
+ fz_freetextspan(text);
+ }
-/* Parser action for end-of-file */
-static int
-xps_imp_process_eof(pl_interp_instance_t *pinstance)
-{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
- int code;
+ if (showmd5 || showtime)
+ printf("page %s %d", filename, pagenum);
- if (instance->scratch_file)
+ if (output || showmd5 || showtime)
{
- if_debug0('|', "xps: executing scratch file\n");
- fclose(instance->scratch_file);
- instance->scratch_file = NULL;
- code = xps_process_file(ctx, instance->scratch_name);
- unlink(instance->scratch_name);
- if (code < 0)
+ float zoom;
+ fz_matrix ctm;
+ fz_rect rect;
+ fz_bbox bbox;
+ fz_pixmap *pix;
+
+ rect.x0 = rect.y0 = 0;
+ rect.x1 = page->width;
+ rect.y1 = page->height;
+
+ zoom = resolution / 72;
+ ctm = fz_translate(0, -page->height);
+ ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
+ bbox = fz_roundrect(fz_transformrect(ctm, rect));
+
+ /* TODO: banded rendering and multi-page ppm */
+
+ pix = fz_newpixmapwithrect(colorspace, bbox);
+
+ if (savealpha)
+ fz_clearpixmap(pix);
+ else
+ fz_clearpixmapwithcolor(pix, 255);
+
+ dev = fz_newdrawdevice(glyphcache, pix);
+ if (list)
+ fz_executedisplaylist(list, dev, ctm);
+ else
+ xps_run_page(ctx, page, dev, ctm);
+ fz_freedevice(dev);
+
+ if (output)
{
- gs_catch(code, "cannot process XPS file");
- return e_ExitLanguage;
+ char buf[512];
+ sprintf(buf, output, pagenum);
+ if (strstr(output, ".pgm") || strstr(output, ".ppm") || strstr(output, ".pnm"))
+ fz_writepnm(pix, buf);
+ else if (strstr(output, ".pam"))
+ fz_writepam(pix, buf, savealpha);
+ else if (strstr(output, ".png"))
+ fz_writepng(pix, buf, savealpha);
}
- }
-
- return 0;
-}
-/* Report any errors after running a job */
-static int
-xps_imp_report_errors(pl_interp_instance_t *pinstance,
- int code, /* prev termination status */
- long file_position, /* file position of error, -1 if unknown */
- bool force_to_cout /* force errors to cout */
- )
-{
- return 0;
-}
+ if (showmd5)
+ {
+ fz_md5 md5;
+ unsigned char digest[16];
+ int i;
-/* Prepare interp instance for the next "job" */
-static int
-xps_imp_init_job(pl_interp_instance_t *pinstance)
-{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
+ fz_md5init(&md5);
+ fz_md5update(&md5, pix->samples, pix->w * pix->h * pix->n);
+ fz_md5final(&md5, digest);
- if (gs_debug_c('|'))
- xps_zip_trace = 1;
- if (gs_debug_c('|'))
- xps_doc_trace = 1;
+ printf(" ");
+ for (i = 0; i < 16; i++)
+ printf("%02x", digest[i]);
+ }
- ctx->font_table = xps_hash_new(ctx);
- ctx->colorspace_table = xps_hash_new(ctx);
+ fz_droppixmap(pix);
+ }
- ctx->start_part = NULL;
+ if (list)
+ fz_freedisplaylist(list);
- ctx->use_transparency = 1;
- if (getenv("XPS_DISABLE_TRANSPARENCY"))
- ctx->use_transparency = 0;
+ if (showtime)
+ {
+ int end = gettime();
+ int diff = end - start;
- ctx->opacity_only = 0;
- ctx->fill_rule = 0;
+ if (diff < timing.min)
+ {
+ timing.min = diff;
+ timing.minpage = pagenum;
+ }
+ if (diff > timing.max)
+ {
+ timing.max = diff;
+ timing.maxpage = pagenum;
+ }
+ timing.total += diff;
+ timing.count ++;
- return 0;
-}
+ printf(" %dms", diff);
+ }
-static void xps_free_key_func(xps_context_t *ctx, void *ptr)
-{
- xps_free(ctx, ptr);
+ if (showmd5 || showtime)
+ printf("\n");
}
-static void xps_free_font_func(xps_context_t *ctx, void *ptr)
-{
- xps_free_font(ctx, ptr);
-}
-/* Wrap up interp instance after a "job" */
-static int
-xps_imp_dnit_job(pl_interp_instance_t *pinstance)
+static void drawrange(xps_context_t *ctx, char *range)
{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
- int i;
-
- if (gs_debug_c('|'))
- xps_debug_fixdocseq(ctx);
-
- for (i = 0; i < ctx->zip_count; i++)
- xps_free(ctx, ctx->zip_table[i].name);
- xps_free(ctx, ctx->zip_table);
+ int page, spage, epage;
+ char *spec, *dash;
- /* TODO: free resources too */
- xps_hash_free(ctx, ctx->font_table, xps_free_key_func, xps_free_font_func);
- xps_hash_free(ctx, ctx->colorspace_table, xps_free_key_func, NULL);
-
- xps_free_fixed_pages(ctx);
- xps_free_fixed_documents(ctx);
-
- return 0;
-}
+ spec = fz_strsep(&range, ",");
+ while (spec)
+ {
+ dash = strchr(spec, '-');
-/* Remove a device from an interperter instance */
-static int
-xps_imp_remove_device(pl_interp_instance_t *pinstance)
-{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
+ if (dash == spec)
+ spage = epage = xps_count_pages(ctx);
+ else
+ spage = epage = atoi(spec);
- int code = 0; /* first error status encountered */
- int error;
+ if (dash)
+ {
+ if (strlen(dash) > 1)
+ epage = atoi(dash + 1);
+ else
+ epage = xps_count_pages(ctx);
+ }
- /* return to original gstate */
- gs_grestore_only(ctx->pgs); /* destroys gs_save stack */
+ spage = CLAMP(spage, 1, xps_count_pages(ctx));
+ epage = CLAMP(epage, 1, xps_count_pages(ctx));
- /* Deselect device */
- /* NB */
- error = gs_nulldevice(ctx->pgs);
- if (code >= 0)
- code = error;
+ if (spage < epage)
+ for (page = spage; page <= epage; page++)
+ drawpage(ctx, page);
+ else
+ for (page = spage; page >= epage; page--)
+ drawpage(ctx, page);
- return code;
+ spec = fz_strsep(&range, ",");
+ }
}
-/* Deallocate a interpreter instance */
-static int
-xps_imp_deallocate_interp_instance(pl_interp_instance_t *pinstance)
+int main(int argc, char **argv)
{
- xps_interp_instance_t *instance = (xps_interp_instance_t *)pinstance;
- xps_context_t *ctx = instance->ctx;
- gs_memory_t *mem = ctx->memory;
+ int grayscale = 0;
+ int accelerate = 1;
+ xps_context_t *ctx;
+ int code;
+ int c;
- /* language clients don't free the font cache machinery */
+ while ((c = fz_getopt(argc, argv, "o:p:r:Aadgmtx5")) != -1)
+ {
+ switch (c)
+ {
+ case 'o': output = fz_optarg; break;
+ case 'r': resolution = atof(fz_optarg); break;
+ case 'A': accelerate = 0; break;
+ case 'a': savealpha = 1; break;
+ case 'm': showtime++; break;
+ case 't': showtext++; break;
+ case 'x': showxml++; break;
+ case '5': showmd5++; break;
+ case 'g': grayscale++; break;
+ case 'd': uselist = 0; break;
+ default: usage(); break;
+ }
+ }
- // free gstate?
- gs_free_object(mem, ctx, "xps_imp_deallocate_interp_instance");
- gs_free_object(mem, instance, "xps_imp_deallocate_interp_instance");
+ if (fz_optind == argc)
+ usage();
- return 0;
-}
+ if (!showtext && !showxml && !showtime && !showmd5 && !output)
+ {
+ printf("nothing to do\n");
+ exit(0);
+ }
-/* Do static deinit of XPS interpreter */
-static int
-xps_imp_deallocate_interp(pl_interp_t *pinterp)
-{
- /* nothing to do */
- return 0;
-}
+ if (accelerate)
+ fz_accelerate();
-/* Parser implementation descriptor */
-const pl_interp_implementation_t xps_implementation =
-{
- xps_imp_characteristics,
- xps_imp_allocate_interp,
- xps_imp_allocate_interp_instance,
- xps_imp_set_client_instance,
- xps_imp_set_pre_page_action,
- xps_imp_set_post_page_action,
- xps_imp_set_device,
- xps_imp_init_job,
- xps_imp_process_file,
- xps_imp_process,
- xps_imp_flush_to_eoj,
- xps_imp_process_eof,
- xps_imp_report_errors,
- xps_imp_dnit_job,
- xps_imp_remove_device,
- xps_imp_deallocate_interp_instance,
- xps_imp_deallocate_interp,
- xps_imp_get_device_memory,
-};
-
-/*
- * End-of-page function called by XPS parser.
- */
-int
-xps_show_page(xps_context_t *ctx, int num_copies, int flush)
-{
- pl_interp_instance_t *pinstance = ctx->instance;
- xps_interp_instance_t *instance = ctx->instance;
+ glyphcache = fz_newglyphcache();
- int code = 0;
+ colorspace = fz_devicergb;
+ if (grayscale)
+ colorspace = fz_devicegray;
+ if (output && strstr(output, ".pgm"))
+ colorspace = fz_devicegray;
+ if (output && strstr(output, ".ppm"))
+ colorspace = fz_devicergb;
- /* do pre-page action */
- if (instance->pre_page_action)
- {
- code = instance->pre_page_action(pinstance, instance->pre_page_closure);
- if (code < 0)
- return code;
- if (code != 0)
- return 0; /* code > 0 means abort w/no error */
- }
+ timing.count = 0;
+ timing.total = 0;
+ timing.min = 1 << 30;
+ timing.max = 0;
+ timing.minpage = 0;
+ timing.maxpage = 0;
- /* output the page */
- code = gs_output_page(ctx->pgs, num_copies, flush);
- if (code < 0)
- return code;
+ if (showxml)
+ printf("<?xml version=\"1.0\"?>\n");
- /* do post-page action */
- if (instance->post_page_action)
+ while (fz_optind < argc)
{
- code = instance->post_page_action(pinstance, instance->post_page_closure);
- if (code < 0)
- return code;
- }
-
- return 0;
-}
+ filename = argv[fz_optind++];
-/*
- * We need to install a halftone ourselves, this is not
- * done automatically.
- */
+ ctx = xps_new_context();
+ code = xps_open_file(ctx, filename);
+ if (code)
+ die(fz_rethrow(code, "cannot open document: %s", filename));
-static float
-identity_transfer(floatp tint, const gx_transfer_map *ignore_map)
-{
- return tint;
-}
+ if (showxml)
+ printf("<document name=\"%s\">\n", filename);
-/* The following is a 45 degree spot screen with the spots enumerated
- * in a defined order. */
-static byte order16x16[256] = {
- 38, 11, 14, 32, 165, 105, 90, 171, 38, 12, 14, 33, 161, 101, 88, 167,
- 30, 6, 0, 16, 61, 225, 231, 125, 30, 6, 1, 17, 63, 222, 227, 122,
- 27, 3, 8, 19, 71, 242, 205, 110, 28, 4, 9, 20, 74, 246, 208, 106,
- 35, 24, 22, 40, 182, 46, 56, 144, 36, 25, 22, 41, 186, 48, 58, 148,
- 152, 91, 81, 174, 39, 12, 15, 34, 156, 95, 84, 178, 40, 13, 16, 34,
- 69, 212, 235, 129, 31, 7, 2, 18, 66, 216, 239, 133, 32, 8, 2, 18,
- 79, 254, 203, 114, 28, 4, 10, 20, 76, 250, 199, 118, 29, 5, 10, 21,
- 193, 44, 54, 142, 36, 26, 23, 42, 189, 43, 52, 139, 37, 26, 24, 42,
- 39, 12, 15, 33, 159, 99, 87, 169, 38, 11, 14, 33, 163, 103, 89, 172,
- 31, 7, 1, 17, 65, 220, 229, 123, 30, 6, 1, 17, 62, 223, 233, 127,
- 28, 4, 9, 20, 75, 248, 210, 108, 27, 3, 9, 19, 72, 244, 206, 112,
- 36, 25, 23, 41, 188, 49, 60, 150, 35, 25, 22, 41, 184, 47, 57, 146,
- 157, 97, 85, 180, 40, 13, 16, 35, 154, 93, 83, 176, 39, 13, 15, 34,
- 67, 218, 240, 135, 32, 8, 3, 19, 70, 214, 237, 131, 31, 7, 2, 18,
- 78, 252, 197, 120, 29, 5, 11, 21, 80, 255, 201, 116, 29, 5, 10, 21,
- 191, 43, 51, 137, 37, 27, 24, 43, 195, 44, 53, 140, 37, 26, 23, 42
-};
-
-#define source_phase_x 4
-#define source_phase_y 0
+ if (fz_optind == argc || !isrange(argv[fz_optind]))
+ drawrange(ctx, "1-");
+ if (fz_optind < argc && isrange(argv[fz_optind]))
+ drawrange(ctx, argv[fz_optind++]);
-static int
-xps_install_halftone(xps_context_t *ctx, gx_device *pdevice)
-{
- gs_halftone ht;
- gs_string thresh;
- int code;
+ if (showxml)
+ printf("</document>\n");
- int width = 16;
- int height = 16;
- thresh.data = order16x16;
- thresh.size = width * height;
+ xps_free_context(ctx);
+ }
- if (gx_device_must_halftone(pdevice))
+ if (showtime)
{
- ht.type = ht_type_threshold;
- ht.params.threshold.width = width;
- ht.params.threshold.height = height;
- ht.params.threshold.thresholds.data = thresh.data;
- ht.params.threshold.thresholds.size = thresh.size;
- ht.params.threshold.transfer = 0;
- ht.params.threshold.transfer_closure.proc = 0;
-
- gs_settransfer(ctx->pgs, identity_transfer);
-
- code = gs_sethalftone(ctx->pgs, &ht);
- if (code < 0)
- return gs_throw(code, "could not install halftone");
-
- code = gs_sethalftonephase(ctx->pgs, 0, 0);
- if (code < 0)
- return gs_throw(code, "could not set halftone phase");
+ printf("total %dms / %d pages for an average of %dms\n",
+ timing.total, timing.count, timing.total / timing.count);
+ printf("fastest page %d: %dms\n", timing.minpage, timing.min);
+ printf("slowest page %d: %dms\n", timing.maxpage, timing.max);
}
+ fz_freeglyphcache(glyphcache);
+
return 0;
}
diff --git a/xps/xpsutf.c b/xps/xpsutf.c
index 3e1c05c9..d5c1974e 100644
--- a/xps/xpsutf.c
+++ b/xps/xpsutf.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - unicode text functions */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
/*
* http://tools.ietf.org/html/rfc3629
diff --git a/xps/xpsvisual.c b/xps/xpsvisual.c
index f23ef991..0b6fb4da 100644
--- a/xps/xpsvisual.c
+++ b/xps/xpsvisual.c
@@ -1,19 +1,5 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - visual brush functions */
-
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
enum { TILE_NONE, TILE_TILE, TILE_FLIP_X, TILE_FLIP_Y, TILE_FLIP_X_Y };
@@ -25,13 +11,14 @@ struct userdata
};
static int
-xps_paint_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root, void *visual_tag)
+xps_paint_visual_brush(xps_context_t *ctx, fz_matrix ctm,
+ char *base_uri, xps_resource_t *dict, xps_item_t *root, void *visual_tag)
{
- return xps_parse_element(ctx, base_uri, dict, (xps_item_t *)visual_tag);
+ return xps_parse_element(ctx, ctm, base_uri, dict, (xps_item_t *)visual_tag);
}
int
-xps_parse_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict, xps_item_t *root)
+xps_parse_visual_brush(xps_context_t *ctx, fz_matrix ctm, char *base_uri, xps_resource_t *dict, xps_item_t *root)
{
xps_item_t *node;
int code;
@@ -53,9 +40,9 @@ xps_parse_visual_brush(xps_context_t *ctx, char *base_uri, xps_resource_t *dict,
if (visual_tag)
{
- code = xps_parse_tiling_brush(ctx, visual_uri, dict, root, xps_paint_visual_brush, visual_tag);
+ code = xps_parse_tiling_brush(ctx, ctm, visual_uri, dict, root, xps_paint_visual_brush, visual_tag);
if (code)
- return gs_rethrow(code, "cannot parse tiling brush");
+ return fz_rethrow(code, "cannot parse tiling brush");
}
return 0;
diff --git a/xps/xpsxml.c b/xps/xpsxml.c
index ce93bcfe..2295e08c 100644
--- a/xps/xpsxml.c
+++ b/xps/xpsxml.c
@@ -1,19 +1,7 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
-
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
/* Simple XML document object model on top of Expat. */
-#include "ghostxps.h"
+#include "fitz.h"
+#include "muxps.h"
#include <expat.h>
@@ -87,7 +75,7 @@ on_open_tag(void *zp, char *ns_name, char **atts)
if (!name)
{
- dprintf1("unknown namespace: %s\n", ns_name);
+ fz_warn("unknown namespace: %s", ns_name);
name = ns_name;
}
@@ -214,7 +202,7 @@ on_text(void *zp, char *buf, int len)
static xps_item_t *
xps_process_compatibility(xps_context_t *ctx, xps_item_t *root)
{
- gs_warn("XPS document uses markup compatibility tags");
+ fz_warn("XPS document uses markup compatibility tags");
return root;
}
@@ -234,7 +222,7 @@ xps_parse_xml(xps_context_t *ctx, byte *buf, int len)
xp = XML_ParserCreateNS(NULL, ' ');
if (!xp)
{
- gs_throw(-1, "xml error: could not create expat parser");
+ fz_throw("xml error: could not create expat parser");
return NULL;
}
@@ -250,7 +238,7 @@ xps_parse_xml(xps_context_t *ctx, byte *buf, int len)
if (parser.root)
xps_free_item(ctx, parser.root);
XML_ParserFree(xp);
- gs_throw1(-1, "xml error: %s", XML_ErrorString(XML_GetErrorCode(xp)));
+ fz_throw("xml error: %s", XML_ErrorString(XML_GetErrorCode(xp)));
return NULL;
}
diff --git a/xps/xpszip.c b/xps/xpszip.c
index 1aac7349..639134cf 100644
--- a/xps/xpszip.c
+++ b/xps/xpszip.c
@@ -1,30 +1,7 @@
-/* Copyright (C) 2006-2010 Artifex Software, Inc.
- All Rights Reserved.
+#include "fitz.h"
+#include "muxps.h"
- This software is provided AS-IS with no warranty, either express or
- implied.
-
- This software is distributed under license and may not be copied, modified
- or distributed except as expressly authorized under the terms of that
- license. Refer to licensing information at http://www.artifex.com/
- or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
- San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
-*/
-
-/* XPS interpreter - zip container parsing */
-
-#include "ghostxps.h"
-
-static int isfile(char *path)
-{
- FILE *file = fopen(path, "rb");
- if (file)
- {
- fclose(file);
- return 1;
- }
- return 0;
-}
+#include <zlib.h>
static inline int getshort(FILE *file)
{
@@ -95,13 +72,11 @@ xps_read_zip_entry(xps_context_t *ctx, xps_entry_t *ent, unsigned char *outbuf)
int namelength, extralength;
int code;
- if_debug1('|', "zip: inflating entry '%s'\n", ent->name);
-
fseek(ctx->file, ent->offset, 0);
sig = getlong(ctx->file);
if (sig != ZIP_LOCAL_FILE_SIG)
- return gs_throw1(-1, "wrong zip local file signature (0x%x)", sig);
+ return fz_throw("wrong zip local file signature (0x%x)", sig);
version = getshort(ctx->file);
general = getshort(ctx->file);
@@ -137,25 +112,25 @@ xps_read_zip_entry(xps_context_t *ctx, xps_entry_t *ent, unsigned char *outbuf)
code = inflateInit2(&stream, -15);
if (code != Z_OK)
- return gs_throw1(-1, "zlib inflateInit2 error: %s", stream.msg);
+ return fz_throw("zlib inflateInit2 error: %s", stream.msg);
code = inflate(&stream, Z_FINISH);
if (code != Z_STREAM_END)
{
inflateEnd(&stream);
- return gs_throw1(-1, "zlib inflate error: %s", stream.msg);
+ return fz_throw("zlib inflate error: %s", stream.msg);
}
code = inflateEnd(&stream);
if (code != Z_OK)
- return gs_throw1(-1, "zlib inflateEnd error: %s", stream.msg);
+ return fz_throw("zlib inflateEnd error: %s", stream.msg);
xps_free(ctx, inbuf);
}
else
{
- return gs_throw1(-1, "unknown compression method (%d)", method);
+ return fz_throw("unknown compression method (%d)", method);
}
- return gs_okay;
+ return fz_okay;
}
/*
@@ -174,7 +149,7 @@ xps_read_zip_dir(xps_context_t *ctx, int start_offset)
sig = getlong(ctx->file);
if (sig != ZIP_END_OF_CENTRAL_DIRECTORY_SIG)
- return gs_throw1(-1, "wrong zip end of central directory signature (0x%x)", sig);
+ return fz_throw("wrong zip end of central directory signature (0x%x)", sig);
(void) getshort(ctx->file); /* this disk */
(void) getshort(ctx->file); /* start disk */
@@ -186,7 +161,7 @@ xps_read_zip_dir(xps_context_t *ctx, int start_offset)
ctx->zip_count = count;
ctx->zip_table = xps_alloc(ctx, sizeof(xps_entry_t) * count);
if (!ctx->zip_table)
- return gs_throw(-1, "cannot allocate zip entry table");
+ return fz_throw("cannot allocate zip entry table");
memset(ctx->zip_table, 0, sizeof(xps_entry_t) * count);
@@ -196,7 +171,7 @@ xps_read_zip_dir(xps_context_t *ctx, int start_offset)
{
sig = getlong(ctx->file);
if (sig != ZIP_CENTRAL_DIRECTORY_SIG)
- return gs_throw1(-1, "wrong zip central directory signature (0x%x)", sig);
+ return fz_throw("wrong zip central directory signature (0x%x)", sig);
(void) getshort(ctx->file); /* version made by */
(void) getshort(ctx->file); /* version to extract */
@@ -217,7 +192,7 @@ xps_read_zip_dir(xps_context_t *ctx, int start_offset)
ctx->zip_table[i].name = xps_alloc(ctx, namesize + 1);
if (!ctx->zip_table[i].name)
- return gs_throw(-1, "cannot allocate zip entry name");
+ return fz_throw("cannot allocate zip entry name");
fread(ctx->zip_table[i].name, 1, namesize, ctx->file);
ctx->zip_table[i].name[namesize] = 0;
@@ -228,15 +203,7 @@ xps_read_zip_dir(xps_context_t *ctx, int start_offset)
qsort(ctx->zip_table, count, sizeof(xps_entry_t), xps_compare_entries);
- for (i = 0; i < ctx->zip_count; i++)
- {
- if_debug3('|', "zip entry '%s' csize=%d usize=%d\n",
- ctx->zip_table[i].name,
- ctx->zip_table[i].csize,
- ctx->zip_table[i].usize);
- }
-
- return gs_okay;
+ return fz_okay;
}
static int
@@ -258,7 +225,7 @@ xps_find_and_read_zip_dir(xps_context_t *ctx)
n = fread(buf, 1, sizeof buf, ctx->file);
if (n < 0)
- return gs_throw(-1, "cannot read end of central directory");
+ return fz_throw("cannot read end of central directory");
for (i = n - 4; i > 0; i--)
if (!memcmp(buf + i, "PK\5\6", 4))
@@ -267,7 +234,7 @@ xps_find_and_read_zip_dir(xps_context_t *ctx)
back += sizeof buf - 4;
}
- return gs_throw(-1, "cannot find end of central directory");
+ return fz_throw("cannot find end of central directory");
}
/*
@@ -425,34 +392,15 @@ xps_read_and_process_metadata_part(xps_context_t *ctx, char *name)
part = xps_read_part(ctx, name);
if (!part)
- return gs_rethrow1(-1, "cannot read zip part '%s'", name);
+ return fz_rethrow(-1, "cannot read zip part '%s'", name);
code = xps_parse_metadata(ctx, part);
if (code)
- return gs_rethrow1(code, "cannot process metadata part '%s'", name);
-
- xps_free_part(ctx, part);
-
- return gs_okay;
-}
-
-static int
-xps_read_and_process_page_part(xps_context_t *ctx, char *name)
-{
- xps_part_t *part;
- int code;
-
- part = xps_read_part(ctx, name);
- if (!part)
- return gs_rethrow1(-1, "cannot read zip part '%s'", name);
-
- code = xps_parse_fixed_page(ctx, part);
- if (code)
- return gs_rethrow1(code, "cannot parse fixed page part '%s'", name);
+ return fz_rethrow(code, "cannot process metadata part '%s'", name);
xps_free_part(ctx, part);
- return gs_okay;
+ return fz_okay;
}
/*
@@ -460,62 +408,16 @@ xps_read_and_process_page_part(xps_context_t *ctx, char *name)
*/
int
-xps_process_file(xps_context_t *ctx, char *filename)
+xps_open_file(xps_context_t *ctx, char *filename)
{
char buf[2048];
xps_document_t *doc;
- xps_page_t *page;
int code;
char *p;
ctx->file = fopen(filename, "rb");
if (!ctx->file)
- return gs_throw1(-1, "cannot open file: '%s'", filename);
-
- if (strstr(filename, ".fpage"))
- {
- xps_part_t *part;
- int size;
-
- if_debug0('|', "zip: single page mode\n");
- xps_strlcpy(buf, filename, sizeof buf);
- while (1)
- {
- p = strrchr(buf, '/');
- if (!p)
- p = strrchr(buf, '\\');
- if (!p)
- break;
- xps_strlcpy(p, "/_rels/.rels", buf + sizeof buf - p);
- if_debug1('|', "zip: testing if '%s' exists\n", buf);
- if (isfile(buf))
- {
- *p = 0;
- ctx->directory = xps_strdup(ctx, buf);
- if_debug1('|', "zip: using '%s' as root directory\n", ctx->directory);
- break;
- }
- *p = 0;
- }
- if (!ctx->directory)
- {
- if_debug0('|', "zip: no /_rels/.rels found; assuming absolute paths\n");
- ctx->directory = xps_strdup(ctx, "");
- }
-
- fseek(ctx->file, 0, SEEK_END);
- size = ftell(ctx->file);
- fseek(ctx->file, 0, SEEK_SET);
- part = xps_new_part(ctx, filename, size);
- fread(part->data, 1, size, ctx->file);
-
- code = xps_parse_fixed_page(ctx, part);
- if (code)
- return gs_rethrow1(code, "cannot parse fixed page part '%s'", part->name);
-
- xps_free_part(ctx, part);
- return gs_okay;
- }
+ return fz_throw("cannot open file: '%s'", filename);
if (strstr(filename, "/_rels/.rels") || strstr(filename, "\\_rels\\.rels"))
{
@@ -525,44 +427,122 @@ xps_process_file(xps_context_t *ctx, char *filename)
p = strstr(buf, "\\_rels\\.rels");
*p = 0;
ctx->directory = xps_strdup(ctx, buf);
- if_debug1('|', "zip: using '%s' as root directory\n", ctx->directory);
}
else
{
code = xps_find_and_read_zip_dir(ctx);
if (code < 0)
- return gs_rethrow(code, "cannot read zip central directory");
+ return fz_rethrow(code, "cannot read zip central directory");
}
code = xps_read_and_process_metadata_part(ctx, "/_rels/.rels");
if (code)
- return gs_rethrow(code, "cannot process root relationship part");
+ return fz_rethrow(code, "cannot process root relationship part");
if (!ctx->start_part)
- return gs_throw(-1, "cannot find fixed document sequence start part");
+ return fz_throw("cannot find fixed document sequence start part");
code = xps_read_and_process_metadata_part(ctx, ctx->start_part);
if (code)
- return gs_rethrow(code, "cannot process FixedDocumentSequence part");
+ return fz_rethrow(code, "cannot process FixedDocumentSequence part");
for (doc = ctx->first_fixdoc; doc; doc = doc->next)
{
code = xps_read_and_process_metadata_part(ctx, doc->name);
if (code)
- return gs_rethrow(code, "cannot process FixedDocument part");
+ return fz_rethrow(code, "cannot process FixedDocument part");
}
+ return fz_okay;
+}
+
+int
+xps_count_pages(xps_context_t *ctx)
+{
+ xps_page_t *page;
+ int n = 0;
+ for (page = ctx->first_page; page; page = page->next)
+ n ++;
+ return n;
+}
+
+xps_page_t *
+xps_load_page(xps_context_t *ctx, int number)
+{
+ xps_page_t *page;
+ int code;
+ int n = 0;
+
for (page = ctx->first_page; page; page = page->next)
{
- code = xps_read_and_process_page_part(ctx, page->name);
- if (code)
- return gs_rethrow(code, "cannot process FixedPage part");
+ if (n == number)
+ {
+ if (!page->root)
+ {
+ code = xps_load_fixed_page(ctx, page);
+ if (code)
+ fz_catch(code, "ignoring errors on page");
+ }
+ return page;
+ }
+ n ++;
}
+ return nil;
+}
+
+xps_context_t *
+xps_new_context(void)
+{
+ xps_context_t *ctx;
+
+ ctx = fz_malloc(sizeof(xps_context_t));
+
+ memset(ctx, 0, sizeof(xps_context_t));
+
+ ctx->font_table = xps_hash_new(ctx);
+ ctx->colorspace_table = xps_hash_new(ctx);
+
+ ctx->start_part = NULL;
+
+ ctx->use_transparency = 1;
+ if (getenv("XPS_DISABLE_TRANSPARENCY"))
+ ctx->use_transparency = 0;
+
+ ctx->opacity_only = 0;
+ ctx->fill_rule = 0;
+
+ return ctx;
+}
+
+static void xps_free_key_func(xps_context_t *ctx, void *ptr)
+{
+ xps_free(ctx, ptr);
+}
+
+static void xps_free_font_func(xps_context_t *ctx, void *ptr)
+{
+ fz_dropfont(ptr);
+}
+
+/* Wrap up interp instance after a "job" */
+int
+xps_free_context(xps_context_t *ctx)
+{
+ int i;
- if (ctx->directory)
- xps_free(ctx, ctx->directory);
if (ctx->file)
fclose(ctx->file);
- return gs_okay;
+ for (i = 0; i < ctx->zip_count; i++)
+ xps_free(ctx, ctx->zip_table[i].name);
+ xps_free(ctx, ctx->zip_table);
+
+ /* TODO: free resources too */
+ xps_hash_free(ctx, ctx->font_table, xps_free_key_func, xps_free_font_func);
+ xps_hash_free(ctx, ctx->colorspace_table, xps_free_key_func, NULL);
+
+ xps_free_fixed_pages(ctx);
+ xps_free_fixed_documents(ctx);
+
+ return 0;
}