summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile15
-rw-r--r--Makethird5
-rw-r--r--android/jni/Core.mk5
-rw-r--r--android/jni/ThirdParty.mk43
-rw-r--r--android/jni/mupdf.c140
-rw-r--r--android/local.properties2
-rw-r--r--apps/mudraw.c112
-rw-r--r--apps/mupdfclean.c318
-rw-r--r--apps/mupdfextract.c89
-rw-r--r--apps/mupdfinfo.c416
-rw-r--r--apps/mupdfshow.c31
-rw-r--r--apps/pdfapp.c257
-rw-r--r--apps/pdfapp.h10
-rw-r--r--apps/win_main.c32
-rw-r--r--apps/x11_image.c8
-rw-r--r--apps/x11_main.c44
-rw-r--r--cbz/mucbz.c75
-rw-r--r--cbz/mucbz.h40
-rw-r--r--doc/example.c100
-rw-r--r--doc/overview.txt212
-rw-r--r--draw/draw_affine.c2
-rw-r--r--draw/draw_blend.c8
-rw-r--r--draw/draw_device.c261
-rw-r--r--draw/draw_edge.c42
-rw-r--r--draw/draw_glyph.c8
-rw-r--r--draw/draw_mesh.c10
-rw-r--r--draw/draw_paint.c16
-rw-r--r--draw/draw_path.c2
-rw-r--r--draw/draw_scale.c12
-rw-r--r--draw/draw_simple_scale.c2
-rw-r--r--draw/draw_unpack.c2
-rw-r--r--fitz/base_context.c14
-rw-r--r--fitz/base_error.c4
-rw-r--r--fitz/base_geometry.c2
-rw-r--r--fitz/base_hash.c111
-rw-r--r--fitz/base_memory.c2
-rw-r--r--fitz/base_string.c29
-rw-r--r--fitz/crypt_aes.c2
-rw-r--r--fitz/crypt_arc4.c2
-rw-r--r--fitz/crypt_md5.c2
-rw-r--r--fitz/crypt_sha2.c2
-rw-r--r--fitz/dev_bbox.c6
-rw-r--r--fitz/dev_list.c18
-rw-r--r--fitz/dev_null.c8
-rw-r--r--fitz/dev_text.c692
-rw-r--r--fitz/dev_trace.c18
-rw-r--r--fitz/doc_document.c2
-rw-r--r--fitz/doc_link.c2
-rw-r--r--fitz/doc_outline.c36
-rw-r--r--fitz/filt_basic.c2
-rw-r--r--fitz/filt_dctd.c13
-rw-r--r--fitz/filt_faxd.c2
-rw-r--r--fitz/filt_flate.c2
-rw-r--r--fitz/filt_jbig2d.c2
-rw-r--r--fitz/filt_lzwd.c2
-rw-r--r--fitz/filt_predict.c2
-rw-r--r--fitz/fitz-internal.h1092
-rw-r--r--fitz/fitz.h2567
-rw-r--r--fitz/image_jpeg.c5
-rw-r--r--fitz/image_jpx.c4
-rw-r--r--fitz/image_md5.c11
-rw-r--r--fitz/image_png.c2
-rw-r--r--fitz/image_save.c32
-rw-r--r--fitz/image_tiff.c4
-rw-r--r--fitz/res_bitmap.c47
-rw-r--r--fitz/res_colorspace.c74
-rw-r--r--fitz/res_font.c34
-rw-r--r--fitz/res_halftone.c13
-rw-r--r--fitz/res_path.c18
-rw-r--r--fitz/res_pixmap.c85
-rw-r--r--fitz/res_shade.c36
-rw-r--r--fitz/res_store.c165
-rw-r--r--fitz/res_text.c19
-rw-r--r--fitz/stm_buffer.c22
-rw-r--r--fitz/stm_open.c2
-rw-r--r--fitz/stm_read.c10
-rw-r--r--ios/main.m4
-rw-r--r--pdf/base_object.c (renamed from fitz/base_object.c)591
-rw-r--r--pdf/mupdf-internal.h535
-rw-r--r--pdf/mupdf.h573
-rw-r--r--pdf/pdf_annot.c190
-rw-r--r--pdf/pdf_cmap.c10
-rw-r--r--pdf/pdf_cmap_load.c40
-rw-r--r--pdf/pdf_cmap_parse.c134
-rw-r--r--pdf/pdf_cmap_table.c4
-rw-r--r--pdf/pdf_colorspace.c128
-rw-r--r--pdf/pdf_crypt.c212
-rw-r--r--pdf/pdf_encoding.c4
-rw-r--r--pdf/pdf_font.c270
-rw-r--r--pdf/pdf_fontfile.c34
-rw-r--r--pdf/pdf_function.c208
-rw-r--r--pdf/pdf_image.c549
-rw-r--r--pdf/pdf_interpret.c394
-rw-r--r--pdf/pdf_lex.c121
-rw-r--r--pdf/pdf_metrics.c10
-rw-r--r--pdf/pdf_nametree.c118
-rw-r--r--pdf/pdf_outline.c40
-rw-r--r--pdf/pdf_page.c199
-rw-r--r--pdf/pdf_parse.c299
-rw-r--r--pdf/pdf_pattern.c34
-rw-r--r--pdf/pdf_repair.c183
-rw-r--r--pdf/pdf_shade.c192
-rw-r--r--pdf/pdf_store.c74
-rw-r--r--pdf/pdf_stream.c270
-rw-r--r--pdf/pdf_type3.c92
-rw-r--r--pdf/pdf_unicode.c10
-rw-r--r--pdf/pdf_xobject.c46
-rw-r--r--pdf/pdf_xref.c317
-rw-r--r--scripts/cmapdump.c10
-rw-r--r--scripts/rename2.sed75
-rw-r--r--scripts/rename3.sed37
-rw-r--r--win32/libmupdf.vcproj34
-rw-r--r--win32/libthirdparty.vcproj62
-rw-r--r--xps/muxps-internal.h242
-rw-r--r--xps/muxps.h267
-rw-r--r--xps/xps_common.c3
-rw-r--r--xps/xps_doc.c7
-rw-r--r--xps/xps_glyphs.c5
-rw-r--r--xps/xps_gradient.c13
-rw-r--r--xps/xps_image.c79
-rw-r--r--xps/xps_outline.c5
-rw-r--r--xps/xps_path.c23
-rw-r--r--xps/xps_resource.c7
-rw-r--r--xps/xps_tile.c3
-rw-r--r--xps/xps_util.c3
-rw-r--r--xps/xps_xml.c9
-rw-r--r--xps/xps_zip.c3
127 files changed, 8872 insertions, 5438 deletions
diff --git a/Makefile b/Makefile
index 41494f33..c443f6e0 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,11 @@ MKDIR_CMD = $(QUIET_MKDIR) mkdir -p $@
# --- Rules ---
+FITZ_HDR := fitz/fitz.h fitz/fitz-internal.h
+MUPDF_HDR := $(FITZ_HDR) pdf/mupdf.h pdf/mupdf-internal.h
+MUXPS_HDR := $(FITZ_HDR) xps/muxps.h xps/muxps-internal.h
+MUCBZ_HDR := $(FITZ_HDR) cbz/mucbz.h
+
$(OUT) $(GEN) :
$(MKDIR_CMD)
@@ -46,15 +51,15 @@ $(OUT)/%.a :
$(OUT)/% : $(OUT)/%.o
$(LINK_CMD)
-$(OUT)/%.o : fitz/%.c fitz/fitz.h | $(OUT)
+$(OUT)/%.o : fitz/%.c $(FITZ_HDR) | $(OUT)
$(CC_CMD)
-$(OUT)/%.o : draw/%.c fitz/fitz.h | $(OUT)
+$(OUT)/%.o : draw/%.c $(FITZ_HDR) | $(OUT)
$(CC_CMD)
-$(OUT)/%.o : pdf/%.c fitz/fitz.h pdf/mupdf.h | $(OUT)
+$(OUT)/%.o : pdf/%.c $(MUPDF_HDR) | $(OUT)
$(CC_CMD)
-$(OUT)/%.o : xps/%.c fitz/fitz.h xps/muxps.h | $(OUT)
+$(OUT)/%.o : xps/%.c $(MUXPS_HDR) | $(OUT)
$(CC_CMD)
-$(OUT)/%.o : cbz/%.c fitz/fitz.h cbz/mucbz.h | $(OUT)
+$(OUT)/%.o : cbz/%.c $(MUCBZ_HDR) | $(OUT)
$(CC_CMD)
$(OUT)/%.o : apps/%.c fitz/fitz.h pdf/mupdf.h xps/muxps.h cbz/mucbz.h | $(OUT)
$(CC_CMD)
diff --git a/Makethird b/Makethird
index 1ce606ca..e53ab01b 100644
--- a/Makethird
+++ b/Makethird
@@ -157,6 +157,7 @@ OPENJPEG_LIB := $(OUT)/libopenjpeg.a
OPENJPEG_SRC := \
bio.c \
cio.c \
+ cidx_manager.c \
dwt.c \
event.c \
image.c \
@@ -167,12 +168,16 @@ OPENJPEG_SRC := \
mct.c \
mqc.c \
openjpeg.c \
+ phix_manager.c \
pi.c \
+ ppix_manager.c \
raw.c \
t1.c \
t2.c \
tcd.c \
tgt.c \
+ thix_manager.c \
+ tpix_manager.c \
$(OPENJPEG_LIB): $(addprefix $(OUT)/opj_, $(OPENJPEG_SRC:%.c=%.o))
$(OUT)/opj_%.o: $(OPENJPEG_DIR)/%.c | $(OUT)
diff --git a/android/jni/Core.mk b/android/jni/Core.mk
index 51908298..a4127c67 100644
--- a/android/jni/Core.mk
+++ b/android/jni/Core.mk
@@ -8,7 +8,7 @@ LOCAL_CFLAGS += -DARCH_ARM -DARCH_THUMB -DARCH_ARM_CAN_LOAD_UNALIGNED
LOCAL_C_INCLUDES := \
../thirdparty/jbig2dec \
- ../thirdparty/openjpeg-1.4/libopenjpeg \
+ ../thirdparty/openjpeg-1.5.0/libopenjpeg \
../thirdparty/jpeg-8d \
../thirdparty/zlib-1.2.5 \
../thirdparty/freetype-2.4.8/include \
@@ -28,7 +28,6 @@ LOCAL_SRC_FILES := \
$(MY_ROOT)/fitz/base_getopt.c \
$(MY_ROOT)/fitz/base_hash.c \
$(MY_ROOT)/fitz/base_memory.c \
- $(MY_ROOT)/fitz/base_object.c \
$(MY_ROOT)/fitz/base_string.c \
$(MY_ROOT)/fitz/base_time.c \
$(MY_ROOT)/fitz/crypt_aes.c \
@@ -74,6 +73,7 @@ LOCAL_SRC_FILES := \
$(MY_ROOT)/draw/draw_path.c \
$(MY_ROOT)/draw/draw_simple_scale.c \
$(MY_ROOT)/draw/draw_unpack.c \
+ $(MY_ROOT)/pdf/base_object.c \
$(MY_ROOT)/pdf/pdf_annot.c \
$(MY_ROOT)/pdf/pdf_cmap.c \
$(MY_ROOT)/pdf/pdf_cmap_load.c \
@@ -97,6 +97,7 @@ LOCAL_SRC_FILES := \
$(MY_ROOT)/pdf/pdf_repair.c \
$(MY_ROOT)/pdf/pdf_shade.c \
$(MY_ROOT)/pdf/pdf_stream.c \
+ $(MY_ROOT)/pdf/pdf_store.c \
$(MY_ROOT)/pdf/pdf_type3.c \
$(MY_ROOT)/pdf/pdf_unicode.c \
$(MY_ROOT)/pdf/pdf_xobject.c \
diff --git a/android/jni/ThirdParty.mk b/android/jni/ThirdParty.mk
index dcb7da2a..20e16cee 100644
--- a/android/jni/ThirdParty.mk
+++ b/android/jni/ThirdParty.mk
@@ -6,7 +6,7 @@ MY_ROOT := ../..
LOCAL_C_INCLUDES := \
../thirdparty/jbig2dec \
- ../thirdparty/openjpeg-1.4/libopenjpeg \
+ ../thirdparty/openjpeg-1.5.0/libopenjpeg \
../thirdparty/jpeg-8d \
../thirdparty/zlib-1.2.5 \
../thirdparty/freetype-2.4.8/include \
@@ -32,24 +32,29 @@ LOCAL_SRC_FILES := \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_mmr.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_image.c \
$(MY_ROOT)/thirdparty/jbig2dec/jbig2_metadata.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/bio.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/cio.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/dwt.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/event.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/image.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/j2k.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/j2k_lib.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/jp2.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/jpt.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/mct.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/mqc.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/openjpeg.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/pi.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/raw.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/t1.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/t2.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/tcd.c \
- $(MY_ROOT)/thirdparty/openjpeg-1.4/libopenjpeg/tgt.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/bio.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/cidx_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/cio.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/dwt.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/event.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/image.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/j2k.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/j2k_lib.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/jp2.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/jpt.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/mct.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/mqc.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/openjpeg.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/phix_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/pi.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/ppix_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/raw.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/t1.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/t2.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/tcd.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/tgt.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/thix_manager.c \
+ $(MY_ROOT)/thirdparty/openjpeg-1.5.0/libopenjpeg/tpix_manager.c \
$(MY_ROOT)/thirdparty/jpeg-8d/jaricom.c \
$(MY_ROOT)/thirdparty/jpeg-8d/jcapimin.c \
$(MY_ROOT)/thirdparty/jpeg-8d/jcapistd.c \
diff --git a/android/jni/mupdf.c b/android/jni/mupdf.c
index ccd10065..822095ec 100644
--- a/android/jni/mupdf.c
+++ b/android/jni/mupdf.c
@@ -209,7 +209,7 @@ Java_com_artifex_mupdf_MuPDFCore_drawPage(JNIEnv *env, jobject thiz, jobject bit
rect.y0 = patchY;
rect.x1 = patchX + patchW;
rect.y1 = patchY + patchH;
- pix = fz_new_pixmap_with_rect_and_data(ctx, colorspace, rect, pixels);
+ pix = fz_new_pixmap_with_bbox_and_data(ctx, colorspace, rect, pixels);
if (currentPageList == NULL)
{
fz_clear_pixmap_with_value(ctx, pix, 0xd0);
@@ -259,71 +259,83 @@ Java_com_artifex_mupdf_MuPDFCore_drawPage(JNIEnv *env, jobject thiz, jobject bit
return 1;
}
-static int
-charat(fz_text_span *span, int idx)
+static fz_text_char textcharat(fz_text_page *page, int idx)
{
+ static fz_text_char emptychar = { {0,0,0,0}, ' ' };
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
int ofs = 0;
- while (span) {
- if (idx < ofs + span->len)
- return span->text[idx - ofs].c;
- if (span->eol) {
- if (idx == ofs + span->len)
- return ' ';
- ofs ++;
+ for (block = page->blocks; block < page->blocks + page->len; block++)
+ {
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ for (span = line->spans; span < line->spans + line->len; span++)
+ {
+ if (idx < ofs + span->len)
+ return span->text[idx - ofs];
+ /* pseudo-newline */
+ if (span + 1 == line->spans + line->len)
+ {
+ if (idx == ofs + span->len)
+ return emptychar;
+ ofs++;
+ }
+ ofs += span->len;
+ }
}
- ofs += span->len;
- span = span->next;
}
- return 0;
+ return emptychar;
+}
+
+static int
+charat(fz_text_page *page, int idx)
+{
+ return textcharat(page, idx).c;
}
static fz_bbox
-bboxat(fz_text_span *span, int idx)
+bboxcharat(fz_text_page *page, int idx)
{
- int ofs = 0;
- while (span) {
- if (idx < ofs + span->len)
- return span->text[idx - ofs].bbox;
- if (span->eol) {
- if (idx == ofs + span->len)
- return fz_empty_bbox;
- ofs ++;
- }
- ofs += span->len;
- span = span->next;
- }
- return fz_empty_bbox;
+ return fz_round_rect(textcharat(page, idx).bbox);
}
static int
-textlen(fz_text_span *span)
+textlen(fz_text_page *page)
{
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
int len = 0;
- while (span) {
- len += span->len;
- if (span->eol)
- len ++;
- span = span->next;
+ for (block = page->blocks; block < page->blocks + page->len; block++)
+ {
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ for (span = line->spans; span < line->spans + line->len; span++)
+ len += span->len;
+ len++; /* pseudo-newline */
+ }
}
return len;
}
static int
-match(fz_text_span *span, const char *s, int n)
+match(fz_text_page *page, const char *s, int n)
{
- int start = n, c;
+ int orig = n;
+ int c;
while (*s) {
- s += chartorune(&c, (char *)s);
- if (c == ' ' && charat(span, n) == ' ') {
- while (charat(span, n) == ' ')
+ s += fz_chartorune(&c, (char *)s);
+ if (c == ' ' && charat(page, n) == ' ') {
+ while (charat(page, n) == ' ')
n++;
} else {
- if (tolower(c) != tolower(charat(span, n)))
+ if (tolower(c) != tolower(charat(page, n)))
return 0;
n++;
}
}
- return n - start;
+ return n - orig;
}
static int
@@ -433,19 +445,20 @@ Java_com_artifex_mupdf_MuPDFCore_getOutlineInternal(JNIEnv * env, jobject thiz)
JNIEXPORT jobjectArray JNICALL
Java_com_artifex_mupdf_MuPDFCore_searchPage(JNIEnv * env, jobject thiz, jstring jtext)
{
- jclass rectClass;
- jmethodID ctor;
- jobjectArray arr;
- jobject rect;
- fz_text_span *text = NULL;
- fz_device *dev = NULL;
- float zoom;
- fz_matrix ctm;
- int pos;
- int len;
- int i, n;
- int hit_count = 0;
- const char *str;
+ jclass rectClass;
+ jmethodID ctor;
+ jobjectArray arr;
+ jobject rect;
+ fz_text_sheet *sheet = NULL;
+ fz_text_page *text = NULL;
+ fz_device *dev = NULL;
+ float zoom;
+ fz_matrix ctm;
+ int pos;
+ int len;
+ int i, n;
+ int hit_count = 0;
+ const char *str;
rectClass = (*env)->FindClass(env, "android/graphics/RectF");
if (rectClass == NULL) return NULL;
@@ -454,18 +467,23 @@ Java_com_artifex_mupdf_MuPDFCore_searchPage(JNIEnv * env, jobject thiz, jstring
str = (*env)->GetStringUTFChars(env, jtext, NULL);
if (str == NULL) return NULL;
+ fz_var(sheet);
fz_var(text);
fz_var(dev);
fz_try(ctx)
{
+ fz_rect rect;
+
if (hit_bbox == NULL)
hit_bbox = fz_malloc_array(ctx, MAX_SEARCH_HITS, sizeof(*hit_bbox));
- text = fz_new_text_span(ctx);
- dev = fz_new_text_device(ctx, text);
zoom = resolution / 72;
ctm = fz_scale(zoom, zoom);
+ rect = fz_transform_rect(ctm, currentMediabox);
+ sheet = fz_new_text_sheet(ctx);
+ text = fz_new_text_page(ctx, rect);
+ dev = fz_new_text_device(ctx, sheet, text);
fz_run_page(doc, currentPage, dev, ctm, NULL);
fz_free_device(dev);
dev = NULL;
@@ -476,19 +494,21 @@ Java_com_artifex_mupdf_MuPDFCore_searchPage(JNIEnv * env, jobject thiz, jstring
fz_bbox rr = fz_empty_bbox;
n = match(text, str, pos);
for (i = 0; i < n; i++)
- rr = fz_union_bbox(rr, bboxat(text, pos + i));
+ rr = fz_union_bbox(rr, bboxcharat(text, pos + i));
if (!fz_is_empty_bbox(rr) && hit_count < MAX_SEARCH_HITS)
hit_bbox[hit_count++] = rr;
}
- fz_free_text_span(ctx, text);
- text = NULL;
+ }
+ fz_always(ctx)
+ {
+ fz_free_text_page(ctx, text);
+ fz_free_text_sheet(ctx, sheet);
+ fz_free_device(dev);
}
fz_catch(ctx)
{
jclass cls;
- fz_free_device(dev);
- fz_free_text_span(ctx, text);
(*env)->ReleaseStringUTFChars(env, jtext, str);
cls = (*env)->FindClass(env, "java/lang/OutOfMemoryError");
if (cls != NULL)
diff --git a/android/local.properties b/android/local.properties
new file mode 100644
index 00000000..d0e1f0e6
--- /dev/null
+++ b/android/local.properties
@@ -0,0 +1,2 @@
+#sdk.dir=/Library/android-sdk-mac_x86
+sdk.dir=C:\\Program Files (x86)\\Android\\android-sdk
diff --git a/apps/mudraw.c b/apps/mudraw.c
index ce59a4e3..29517873 100644
--- a/apps/mudraw.c
+++ b/apps/mudraw.c
@@ -3,7 +3,6 @@
*/
#include "fitz.h"
-#include "mupdf.h"
#ifdef _MSC_VER
#include <winsock2.h>
@@ -11,6 +10,8 @@
#include <sys/time.h>
#endif
+enum { TEXT_PLAIN = 1, TEXT_HTML = 2, TEXT_XML = 3 };
+
static char *output = NULL;
static float resolution = 72;
static float rotation = 0;
@@ -25,7 +26,11 @@ static int uselist = 1;
static int alphabits = 8;
static float gamma_value = 1;
static int invert = 0;
+static int width = 0;
+static int height = 0;
+static int fit = 0;
+static fz_text_sheet *sheet = NULL;
static fz_colorspace *colorspace;
static char *filename;
@@ -43,6 +48,9 @@ static void usage(void)
"\t\tsupported formats: pgm, ppm, pam, png, pbm\n"
"\t-p -\tpassword\n"
"\t-r -\tresolution in dpi (default: 72)\n"
+ "\t-w -\twidth (in pixels)\n"
+ "\t-h -\theight (in pixels)\n"
+ "\t-f -\tif both -w and -h are used then fit exactly\n"
"\t-a\tsave alpha channel (only pam and png)\n"
"\t-b -\tnumber of bits of antialiasing (0 to 8)\n"
"\t-g\trender in grayscale\n"
@@ -152,36 +160,43 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
if (showtext)
{
- fz_text_span *text = NULL;
+ fz_text_page *text = NULL;
fz_var(text);
fz_try(ctx)
{
- text = fz_new_text_span(ctx);
- dev = fz_new_text_device(ctx, text);
+ text = fz_new_text_page(ctx, fz_bound_page(doc, page));
+ dev = fz_new_text_device(ctx, sheet, text);
if (list)
fz_run_display_list(list, dev, fz_identity, fz_infinite_bbox, NULL);
else
fz_run_page(doc, page, dev, fz_identity, NULL);
fz_free_device(dev);
dev = NULL;
- printf("[Page %d]\n", pagenum);
- if (showtext > 1)
- fz_debug_text_span_xml(text);
- else
- fz_debug_text_span(text);
- printf("\n");
+ if (showtext == TEXT_XML)
+ {
+ fz_print_text_page_xml(ctx, stdout, text);
+ }
+ else if (showtext == TEXT_HTML)
+ {
+ fz_print_text_page_html(ctx, stdout, text);
+ }
+ else if (showtext == TEXT_PLAIN)
+ {
+ fz_print_text_page(ctx, stdout, text);
+ printf("\f\n");
+ }
}
fz_catch(ctx)
{
fz_free_device(dev);
- fz_free_text_span(ctx, text);
+ fz_free_text_page(ctx, text);
fz_free_display_list(ctx, list);
fz_free_page(doc, page);
fz_rethrow(ctx);
}
- fz_free_text_span(ctx, text);
+ fz_free_text_page(ctx, text);
}
if (showmd5 || showtime)
@@ -191,7 +206,7 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
{
float zoom;
fz_matrix ctm;
- fz_rect bounds;
+ fz_rect bounds, bounds2;
fz_bbox bbox;
fz_pixmap *pix = NULL;
@@ -201,13 +216,33 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
zoom = resolution / 72;
ctm = fz_scale(zoom, zoom);
ctm = fz_concat(ctm, fz_rotate(rotation));
- bbox = fz_round_rect(fz_transform_rect(ctm, bounds));
+ bounds2 = fz_transform_rect(ctm, bounds);
+ if (width || height)
+ {
+ float scalex = width/(bounds2.x1-bounds2.x0);
+ float scaley = height/(bounds2.y1-bounds2.y0);
+
+ if (width == 0)
+ scalex = scaley;
+ if (height == 0)
+ scaley = scalex;
+ if (!fit)
+ {
+ if (scalex > scaley)
+ scalex = scaley;
+ else
+ scaley = scalex;
+ }
+ ctm = fz_concat(ctm, fz_scale(scalex, scaley));
+ bounds2 = fz_transform_rect(ctm, bounds);
+ }
+ bbox = fz_round_rect(bounds2);
/* TODO: banded rendering and multi-page ppm */
fz_try(ctx)
{
- pix = fz_new_pixmap_with_rect(ctx, colorspace, bbox);
+ pix = fz_new_pixmap_with_bbox(ctx, colorspace, bbox);
if (savealpha)
fz_clear_pixmap(ctx, pix);
@@ -241,24 +276,18 @@ static void drawpage(fz_context *ctx, fz_document *doc, int pagenum)
else if (strstr(output, ".png"))
fz_write_png(ctx, pix, buf, savealpha);
else if (strstr(output, ".pbm")) {
- fz_halftone *ht = fz_get_default_halftone(ctx, 1);
- fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, ht);
+ fz_bitmap *bit = fz_halftone_pixmap(ctx, pix, NULL);
fz_write_pbm(ctx, bit, buf);
fz_drop_bitmap(ctx, bit);
- fz_drop_halftone(ctx, ht);
}
}
if (showmd5)
{
- fz_md5 md5;
unsigned char digest[16];
int i;
- fz_md5_init(&md5);
- fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n);
- fz_md5_final(&md5, digest);
-
+ fz_md5_pixmap(pix, digest);
printf(" ");
for (i = 0; i < 16; i++)
printf("%02x", digest[i]);
@@ -350,9 +379,9 @@ static void drawoutline(fz_context *ctx, fz_document *doc)
{
fz_outline *outline = fz_load_outline(doc);
if (showoutline > 1)
- fz_debug_outline_xml(ctx, outline, 0);
+ fz_print_outline_xml(ctx, stdout, outline);
else
- fz_debug_outline(ctx, outline, 0);
+ fz_print_outline(ctx, stdout, outline);
fz_free_outline(ctx, outline);
}
@@ -370,7 +399,7 @@ int main(int argc, char **argv)
fz_var(doc);
- while ((c = fz_getopt(argc, argv, "lo:p:r:R:ab:dgmtx5G:I")) != -1)
+ while ((c = fz_getopt(argc, argv, "lo:p:r:R:ab:dgmtx5G:Iw:h:f")) != -1)
{
switch (c)
{
@@ -388,6 +417,9 @@ int main(int argc, char **argv)
case 'g': grayscale++; break;
case 'd': uselist = 0; break;
case 'G': gamma_value = atof(fz_optarg); break;
+ case 'w': width = atof(fz_optarg); break;
+ case 'h': height = atof(fz_optarg); break;
+ case 'f': fit = 1; break;
case 'I': invert++; break;
default: usage(); break;
}
@@ -428,9 +460,23 @@ int main(int argc, char **argv)
timing.minpage = 0;
timing.maxpage = 0;
- if (showxml)
+ if (showxml || showtext == TEXT_XML)
printf("<?xml version=\"1.0\"?>\n");
+ if (showtext)
+ sheet = fz_new_text_sheet(ctx);
+
+ if (showtext == TEXT_HTML)
+ {
+ printf("<style>\n");
+ printf("body{background-color:gray;margin:12tp;}\n");
+ printf("div.page{background-color:white;margin:6pt;padding:6pt;}\n");
+ printf("div.block{border:1px solid gray;margin:6pt;padding:6pt;}\n");
+ printf("p{margin:0;padding:0;}\n");
+ printf("</style>\n");
+ printf("<body>\n");
+ }
+
fz_try(ctx)
{
while (fz_optind < argc)
@@ -450,7 +496,7 @@ int main(int argc, char **argv)
if (!fz_authenticate_password(doc, password))
fz_throw(ctx, "cannot authenticate password: %s", filename);
- if (showxml)
+ if (showxml || showtext == TEXT_XML)
printf("<document name=\"%s\">\n", filename);
if (showoutline)
@@ -464,7 +510,7 @@ int main(int argc, char **argv)
drawrange(ctx, doc, argv[fz_optind++]);
}
- if (showxml)
+ if (showxml || showtext == TEXT_XML)
printf("</document>\n");
fz_close_document(doc);
@@ -476,6 +522,14 @@ int main(int argc, char **argv)
fz_close_document(doc);
}
+ if (showtext == TEXT_HTML)
+ {
+ printf("</body>\n");
+ printf("<style>\n");
+ fz_print_text_sheet(ctx, stdout, sheet);
+ printf("</style>\n");
+ }
+
if (showtime)
{
printf("total %dms / %d pages for an average of %dms\n",
diff --git a/apps/mupdfclean.c b/apps/mupdfclean.c
index 3130e3f0..caee8d5b 100644
--- a/apps/mupdfclean.c
+++ b/apps/mupdfclean.c
@@ -10,7 +10,7 @@
*/
#include "fitz.h"
-#include "mupdf.h"
+#include "mupdf-internal.h"
static FILE *out = NULL;
@@ -53,34 +53,34 @@ static void usage(void)
* Garbage collect objects not reachable from the trailer.
*/
-static void sweepref(fz_obj *ref);
+static void sweepref(pdf_obj *ref);
-static void sweepobj(fz_obj *obj)
+static void sweepobj(pdf_obj *obj)
{
int i;
- if (fz_is_indirect(obj))
+ if (pdf_is_indirect(obj))
sweepref(obj);
- else if (fz_is_dict(obj))
+ else if (pdf_is_dict(obj))
{
- int n = fz_dict_len(obj);
+ int n = pdf_dict_len(obj);
for (i = 0; i < n; i++)
- sweepobj(fz_dict_get_val(obj, i));
+ sweepobj(pdf_dict_get_val(obj, i));
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
- int n = fz_array_len(obj);
+ int n = pdf_array_len(obj);
for (i = 0; i < n; i++)
- sweepobj(fz_array_get(obj, i));
+ sweepobj(pdf_array_get(obj, i));
}
}
-static void sweepref(fz_obj *obj)
+static void sweepref(pdf_obj *obj)
{
- int num = fz_to_num(obj);
- int gen = fz_to_gen(obj);
+ int num = pdf_to_num(obj);
+ int gen = pdf_to_gen(obj);
if (num < 0 || num >= xref->len)
return;
@@ -94,12 +94,12 @@ static void sweepref(fz_obj *obj)
{
if (pdf_is_stream(xref, num, gen))
{
- fz_obj *len = fz_dict_gets(obj, "Length");
- if (fz_is_indirect(len))
+ pdf_obj *len = pdf_dict_gets(obj, "Length");
+ if (pdf_is_indirect(len))
{
- uselist[fz_to_num(len)] = 0;
- len = fz_resolve_indirect(len);
- fz_dict_puts(obj, "Length", len);
+ uselist[pdf_to_num(len)] = 0;
+ len = pdf_resolve_indirect(len);
+ pdf_dict_puts(obj, "Length", len);
}
}
}
@@ -108,7 +108,7 @@ static void sweepref(fz_obj *obj)
/* Leave broken */
}
- sweepobj(fz_resolve_indirect(obj));
+ sweepobj(pdf_resolve_indirect(obj));
}
/*
@@ -124,7 +124,7 @@ static void removeduplicateobjs(void)
/* Only compare an object to objects preceding it */
for (other = 1; other < num; other++)
{
- fz_obj *a, *b;
+ pdf_obj *a, *b;
if (num == other || !uselist[num] || !uselist[other])
continue;
@@ -148,10 +148,10 @@ static void removeduplicateobjs(void)
a = xref->table[num].obj;
b = xref->table[other].obj;
- a = fz_resolve_indirect(a);
- b = fz_resolve_indirect(b);
+ a = pdf_resolve_indirect(a);
+ b = pdf_resolve_indirect(b);
- if (fz_objcmp(a, b))
+ if (pdf_objcmp(a, b))
continue;
/* Keep the lowest numbered object */
@@ -195,23 +195,23 @@ static void compactxref(void)
* removing duplicate objects and compacting the xref.
*/
-static void renumberobj(fz_obj *obj)
+static void renumberobj(pdf_obj *obj)
{
int i;
fz_context *ctx = xref->ctx;
- if (fz_is_dict(obj))
+ if (pdf_is_dict(obj))
{
- int n = fz_dict_len(obj);
+ int n = pdf_dict_len(obj);
for (i = 0; i < n; i++)
{
- fz_obj *key = fz_dict_get_key(obj, i);
- fz_obj *val = fz_dict_get_val(obj, i);
- if (fz_is_indirect(val))
+ pdf_obj *key = pdf_dict_get_key(obj, i);
+ pdf_obj *val = pdf_dict_get_val(obj, i);
+ if (pdf_is_indirect(val))
{
- val = fz_new_indirect(ctx, renumbermap[fz_to_num(val)], 0, xref);
+ val = pdf_new_indirect(ctx, renumbermap[pdf_to_num(val)], 0, xref);
fz_dict_put(obj, key, val);
- fz_drop_obj(val);
+ pdf_drop_obj(val);
}
else
{
@@ -220,17 +220,17 @@ static void renumberobj(fz_obj *obj)
}
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
- int n = fz_array_len(obj);
+ int n = pdf_array_len(obj);
for (i = 0; i < n; i++)
{
- fz_obj *val = fz_array_get(obj, i);
- if (fz_is_indirect(val))
+ pdf_obj *val = pdf_array_get(obj, i);
+ if (pdf_is_indirect(val))
{
- val = fz_new_indirect(ctx, renumbermap[fz_to_num(val)], 0, xref);
- fz_array_put(obj, i, val);
- fz_drop_obj(val);
+ val = pdf_new_indirect(ctx, renumbermap[pdf_to_num(val)], 0, xref);
+ pdf_array_put(obj, i, val);
+ pdf_drop_obj(val);
}
else
{
@@ -250,13 +250,13 @@ static void renumberobjs(void)
renumberobj(xref->trailer);
for (num = 0; num < xref->len; num++)
{
- fz_obj *obj = xref->table[num].obj;
+ pdf_obj *obj = xref->table[num].obj;
- if (fz_is_indirect(obj))
+ if (pdf_is_indirect(obj))
{
- obj = fz_new_indirect(ctx, renumbermap[fz_to_num(obj)], 0, xref);
+ obj = pdf_new_indirect(ctx, renumbermap[pdf_to_num(obj)], 0, xref);
pdf_update_object(xref, num, 0, obj);
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
else
{
@@ -282,7 +282,7 @@ static void renumberobjs(void)
else
{
if (oldxref[num].obj)
- fz_drop_obj(oldxref[num].obj);
+ pdf_drop_obj(oldxref[num].obj);
}
}
@@ -302,25 +302,25 @@ static void renumberobjs(void)
static void retainpages(int argc, char **argv)
{
- fz_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests;
+ pdf_obj *oldroot, *root, *pages, *kids, *countobj, *parent, *olddests;
/* Keep only pages/type and (reduced) dest entries to avoid
* references to unretained pages */
- oldroot = fz_dict_gets(xref->trailer, "Root");
- pages = fz_dict_gets(oldroot, "Pages");
+ oldroot = pdf_dict_gets(xref->trailer, "Root");
+ pages = pdf_dict_gets(oldroot, "Pages");
olddests = pdf_load_name_tree(xref, "Dests");
- root = fz_new_dict(ctx, 2);
- fz_dict_puts(root, "Type", fz_dict_gets(oldroot, "Type"));
- fz_dict_puts(root, "Pages", fz_dict_gets(oldroot, "Pages"));
+ root = pdf_new_dict(ctx, 2);
+ pdf_dict_puts(root, "Type", pdf_dict_gets(oldroot, "Type"));
+ pdf_dict_puts(root, "Pages", pdf_dict_gets(oldroot, "Pages"));
- pdf_update_object(xref, fz_to_num(oldroot), fz_to_gen(oldroot), root);
+ pdf_update_object(xref, pdf_to_num(oldroot), pdf_to_gen(oldroot), root);
- fz_drop_obj(root);
+ pdf_drop_obj(root);
/* Create a new kids array with only the pages we want to keep */
- parent = fz_new_indirect(ctx, fz_to_num(pages), fz_to_gen(pages), xref);
- kids = fz_new_array(ctx, 1);
+ parent = pdf_new_indirect(ctx, pdf_to_num(pages), pdf_to_gen(pages), xref);
+ kids = pdf_new_array(ctx, 1);
/* Retain pages specified */
while (argc - fz_optind)
@@ -357,13 +357,13 @@ static void retainpages(int argc, char **argv)
for (page = spage; page <= epage; page++)
{
- fz_obj *pageobj = xref->page_objs[page-1];
- fz_obj *pageref = xref->page_refs[page-1];
+ pdf_obj *pageobj = xref->page_objs[page-1];
+ pdf_obj *pageref = xref->page_refs[page-1];
- fz_dict_puts(pageobj, "Parent", parent);
+ pdf_dict_puts(pageobj, "Parent", parent);
/* Store page object in new kids array */
- fz_array_push(kids, pageref);
+ pdf_array_push(kids, pageref);
}
spec = fz_strsep(&pagelist, ",");
@@ -372,48 +372,48 @@ static void retainpages(int argc, char **argv)
fz_optind++;
}
- fz_drop_obj(parent);
+ pdf_drop_obj(parent);
/* Update page count and kids array */
- countobj = fz_new_int(ctx, fz_array_len(kids));
- fz_dict_puts(pages, "Count", countobj);
- fz_drop_obj(countobj);
- fz_dict_puts(pages, "Kids", kids);
- fz_drop_obj(kids);
+ countobj = pdf_new_int(ctx, pdf_array_len(kids));
+ pdf_dict_puts(pages, "Count", countobj);
+ pdf_drop_obj(countobj);
+ pdf_dict_puts(pages, "Kids", kids);
+ pdf_drop_obj(kids);
/* Also preserve the (partial) Dests name tree */
if (olddests)
{
int i;
- fz_obj *names = fz_new_dict(ctx, 1);
- fz_obj *dests = fz_new_dict(ctx, 1);
- fz_obj *names_list = fz_new_array(ctx, 32);
+ pdf_obj *names = pdf_new_dict(ctx, 1);
+ pdf_obj *dests = pdf_new_dict(ctx, 1);
+ pdf_obj *names_list = pdf_new_array(ctx, 32);
- for (i = 0; i < fz_dict_len(olddests); i++)
+ for (i = 0; i < pdf_dict_len(olddests); i++)
{
- fz_obj *key = fz_dict_get_key(olddests, i);
- fz_obj *val = fz_dict_get_val(olddests, i);
- fz_obj *key_str = fz_new_string(ctx, fz_to_name(key), strlen(fz_to_name(key)));
- fz_obj *dest = fz_dict_gets(val, "D");
+ pdf_obj *key = pdf_dict_get_key(olddests, i);
+ pdf_obj *val = pdf_dict_get_val(olddests, i);
+ pdf_obj *key_str = pdf_new_string(ctx, pdf_to_name(key), strlen(pdf_to_name(key)));
+ pdf_obj *dest = pdf_dict_gets(val, "D");
- dest = fz_array_get(dest ? dest : val, 0);
- if (fz_array_contains(fz_dict_gets(pages, "Kids"), dest))
+ dest = pdf_array_get(dest ? dest : val, 0);
+ if (pdf_array_contains(pdf_dict_gets(pages, "Kids"), dest))
{
- fz_array_push(names_list, key_str);
- fz_array_push(names_list, val);
+ pdf_array_push(names_list, key_str);
+ pdf_array_push(names_list, val);
}
- fz_drop_obj(key_str);
+ pdf_drop_obj(key_str);
}
- root = fz_dict_gets(xref->trailer, "Root");
- fz_dict_puts(dests, "Names", names_list);
- fz_dict_puts(names, "Dests", dests);
- fz_dict_puts(root, "Names", names);
+ root = pdf_dict_gets(xref->trailer, "Root");
+ pdf_dict_puts(dests, "Names", names_list);
+ pdf_dict_puts(names, "Dests", dests);
+ pdf_dict_puts(root, "Names", names);
- fz_drop_obj(names);
- fz_drop_obj(dests);
- fz_drop_obj(names_list);
- fz_drop_obj(olddests);
+ pdf_drop_obj(names);
+ pdf_drop_obj(dests);
+ pdf_drop_obj(names_list);
+ pdf_drop_obj(olddests);
}
}
@@ -423,7 +423,7 @@ static void retainpages(int argc, char **argv)
static void preloadobjstms(void)
{
- fz_obj *obj;
+ pdf_obj *obj;
int num;
for (num = 0; num < xref->len; num++)
@@ -431,7 +431,7 @@ static void preloadobjstms(void)
if (xref->table[num].type == 'o')
{
obj = pdf_load_object(xref, num, 0);
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
}
}
@@ -482,57 +482,57 @@ static fz_buffer *hexbuf(unsigned char *p, int n)
return buf;
}
-static void addhexfilter(fz_obj *dict)
+static void addhexfilter(pdf_obj *dict)
{
- fz_obj *f, *dp, *newf, *newdp;
- fz_obj *ahx, *nullobj;
+ pdf_obj *f, *dp, *newf, *newdp;
+ pdf_obj *ahx, *nullobj;
ahx = fz_new_name(ctx, "ASCIIHexDecode");
- nullobj = fz_new_null(ctx);
+ nullobj = pdf_new_null(ctx);
newf = newdp = NULL;
- f = fz_dict_gets(dict, "Filter");
- dp = fz_dict_gets(dict, "DecodeParms");
+ f = pdf_dict_gets(dict, "Filter");
+ dp = pdf_dict_gets(dict, "DecodeParms");
- if (fz_is_name(f))
+ if (pdf_is_name(f))
{
- newf = fz_new_array(ctx, 2);
- fz_array_push(newf, ahx);
- fz_array_push(newf, f);
+ newf = pdf_new_array(ctx, 2);
+ pdf_array_push(newf, ahx);
+ pdf_array_push(newf, f);
f = newf;
- if (fz_is_dict(dp))
+ if (pdf_is_dict(dp))
{
- newdp = fz_new_array(ctx, 2);
- fz_array_push(newdp, nullobj);
- fz_array_push(newdp, dp);
+ newdp = pdf_new_array(ctx, 2);
+ pdf_array_push(newdp, nullobj);
+ pdf_array_push(newdp, dp);
dp = newdp;
}
}
- else if (fz_is_array(f))
+ else if (pdf_is_array(f))
{
- fz_array_insert(f, ahx);
- if (fz_is_array(dp))
- fz_array_insert(dp, nullobj);
+ pdf_array_insert(f, ahx);
+ if (pdf_is_array(dp))
+ pdf_array_insert(dp, nullobj);
}
else
f = ahx;
- fz_dict_puts(dict, "Filter", f);
+ pdf_dict_puts(dict, "Filter", f);
if (dp)
- fz_dict_puts(dict, "DecodeParms", dp);
+ pdf_dict_puts(dict, "DecodeParms", dp);
- fz_drop_obj(ahx);
- fz_drop_obj(nullobj);
+ pdf_drop_obj(ahx);
+ pdf_drop_obj(nullobj);
if (newf)
- fz_drop_obj(newf);
+ pdf_drop_obj(newf);
if (newdp)
- fz_drop_obj(newdp);
+ pdf_drop_obj(newdp);
}
-static void copystream(fz_obj *obj, int num, int gen)
+static void copystream(pdf_obj *obj, int num, int gen)
{
fz_buffer *buf, *tmp;
- fz_obj *newlen;
+ pdf_obj *newlen;
buf = pdf_load_raw_stream(xref, num, gen);
@@ -544,13 +544,13 @@ static void copystream(fz_obj *obj, int num, int gen)
addhexfilter(obj);
- newlen = fz_new_int(ctx, buf->len);
- fz_dict_puts(obj, "Length", newlen);
- fz_drop_obj(newlen);
+ newlen = pdf_new_int(ctx, buf->len);
+ pdf_dict_puts(obj, "Length", newlen);
+ pdf_drop_obj(newlen);
}
fprintf(out, "%d %d obj\n", num, gen);
- fz_fprint_obj(out, obj, doexpand == 0);
+ pdf_fprint_obj(out, obj, doexpand == 0);
fprintf(out, "stream\n");
fwrite(buf->data, 1, buf->len, out);
fprintf(out, "endstream\nendobj\n\n");
@@ -558,15 +558,15 @@ static void copystream(fz_obj *obj, int num, int gen)
fz_drop_buffer(ctx, buf);
}
-static void expandstream(fz_obj *obj, int num, int gen)
+static void expandstream(pdf_obj *obj, int num, int gen)
{
fz_buffer *buf, *tmp;
- fz_obj *newlen;
+ pdf_obj *newlen;
buf = pdf_load_stream(xref, num, gen);
- fz_dict_dels(obj, "Filter");
- fz_dict_dels(obj, "DecodeParms");
+ pdf_dict_dels(obj, "Filter");
+ pdf_dict_dels(obj, "DecodeParms");
if (doascii && isbinarystream(buf))
{
@@ -577,12 +577,12 @@ static void expandstream(fz_obj *obj, int num, int gen)
addhexfilter(obj);
}
- newlen = fz_new_int(ctx, buf->len);
- fz_dict_puts(obj, "Length", newlen);
- fz_drop_obj(newlen);
+ newlen = pdf_new_int(ctx, buf->len);
+ pdf_dict_puts(obj, "Length", newlen);
+ pdf_drop_obj(newlen);
fprintf(out, "%d %d obj\n", num, gen);
- fz_fprint_obj(out, obj, doexpand == 0);
+ pdf_fprint_obj(out, obj, doexpand == 0);
fprintf(out, "stream\n");
fwrite(buf->data, 1, buf->len, out);
fprintf(out, "endstream\nendobj\n\n");
@@ -592,25 +592,25 @@ static void expandstream(fz_obj *obj, int num, int gen)
static void writeobject(int num, int gen)
{
- fz_obj *obj;
- fz_obj *type;
+ pdf_obj *obj;
+ pdf_obj *type;
obj = pdf_load_object(xref, num, gen);
/* skip ObjStm and XRef objects */
- if (fz_is_dict(obj))
+ if (pdf_is_dict(obj))
{
- type = fz_dict_gets(obj, "Type");
- if (fz_is_name(type) && !strcmp(fz_to_name(type), "ObjStm"))
+ type = pdf_dict_gets(obj, "Type");
+ if (pdf_is_name(type) && !strcmp(pdf_to_name(type), "ObjStm"))
{
uselist[num] = 0;
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
return;
}
- if (fz_is_name(type) && !strcmp(fz_to_name(type), "XRef"))
+ if (pdf_is_name(type) && !strcmp(pdf_to_name(type), "XRef"))
{
uselist[num] = 0;
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
return;
}
}
@@ -618,7 +618,7 @@ static void writeobject(int num, int gen)
if (!pdf_is_stream(xref, num, gen))
{
fprintf(out, "%d %d obj\n", num, gen);
- fz_fprint_obj(out, obj, doexpand == 0);
+ pdf_fprint_obj(out, obj, doexpand == 0);
fprintf(out, "endobj\n\n");
}
else
@@ -626,24 +626,24 @@ static void writeobject(int num, int gen)
int dontexpand = 0;
if (doexpand != 0 && doexpand != expand_all)
{
- fz_obj *o;
+ pdf_obj *o;
- if ((o = fz_dict_gets(obj, "Type"), !strcmp(fz_to_name(o), "XObject")) &&
- (o = fz_dict_gets(obj, "Subtype"), !strcmp(fz_to_name(o), "Image")))
+ if ((o = pdf_dict_gets(obj, "Type"), !strcmp(pdf_to_name(o), "XObject")) &&
+ (o = pdf_dict_gets(obj, "Subtype"), !strcmp(pdf_to_name(o), "Image")))
dontexpand = !(doexpand & expand_images);
- if (o = fz_dict_gets(obj, "Type"), !strcmp(fz_to_name(o), "Font"))
+ if (o = pdf_dict_gets(obj, "Type"), !strcmp(pdf_to_name(o), "Font"))
dontexpand = !(doexpand & expand_fonts);
- if (o = fz_dict_gets(obj, "Type"), !strcmp(fz_to_name(o), "FontDescriptor"))
+ if (o = pdf_dict_gets(obj, "Type"), !strcmp(pdf_to_name(o), "FontDescriptor"))
dontexpand = !(doexpand & expand_fonts);
- if ((o = fz_dict_gets(obj, "Length1")) != NULL)
+ if ((o = pdf_dict_gets(obj, "Length1")) != NULL)
dontexpand = !(doexpand & expand_fonts);
- if ((o = fz_dict_gets(obj, "Length2")) != NULL)
+ if ((o = pdf_dict_gets(obj, "Length2")) != NULL)
dontexpand = !(doexpand & expand_fonts);
- if ((o = fz_dict_gets(obj, "Length3")) != NULL)
+ if ((o = pdf_dict_gets(obj, "Length3")) != NULL)
dontexpand = !(doexpand & expand_fonts);
- if (o = fz_dict_gets(obj, "Subtype"), !strcmp(fz_to_name(o), "Type1C"))
+ if (o = pdf_dict_gets(obj, "Subtype"), !strcmp(pdf_to_name(o), "Type1C"))
dontexpand = !(doexpand & expand_fonts);
- if (o = fz_dict_gets(obj, "Subtype"), !strcmp(fz_to_name(o), "CIDFontType0C"))
+ if (o = pdf_dict_gets(obj, "Subtype"), !strcmp(pdf_to_name(o), "CIDFontType0C"))
dontexpand = !(doexpand & expand_fonts);
}
if (doexpand && !dontexpand && !pdf_is_jpx_image(ctx, obj))
@@ -652,13 +652,13 @@ static void writeobject(int num, int gen)
copystream(obj, num, gen);
}
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
static void writexref(void)
{
- fz_obj *trailer;
- fz_obj *obj;
+ pdf_obj *trailer;
+ pdf_obj *obj;
int startxref;
int num;
@@ -674,29 +674,29 @@ static void writexref(void)
}
fprintf(out, "\n");
- trailer = fz_new_dict(ctx, 5);
+ trailer = pdf_new_dict(ctx, 5);
- obj = fz_new_int(ctx, xref->len);
- fz_dict_puts(trailer, "Size", obj);
- fz_drop_obj(obj);
+ obj = pdf_new_int(ctx, xref->len);
+ pdf_dict_puts(trailer, "Size", obj);
+ pdf_drop_obj(obj);
- obj = fz_dict_gets(xref->trailer, "Info");
+ obj = pdf_dict_gets(xref->trailer, "Info");
if (obj)
- fz_dict_puts(trailer, "Info", obj);
+ pdf_dict_puts(trailer, "Info", obj);
- obj = fz_dict_gets(xref->trailer, "Root");
+ obj = pdf_dict_gets(xref->trailer, "Root");
if (obj)
- fz_dict_puts(trailer, "Root", obj);
+ pdf_dict_puts(trailer, "Root", obj);
- obj = fz_dict_gets(xref->trailer, "ID");
+ obj = pdf_dict_gets(xref->trailer, "ID");
if (obj)
- fz_dict_puts(trailer, "ID", obj);
+ pdf_dict_puts(trailer, "ID", obj);
fprintf(out, "trailer\n");
- fz_fprint_obj(out, trailer, doexpand == 0);
+ pdf_fprint_obj(out, trailer, doexpand == 0);
fprintf(out, "\n");
- fz_drop_obj(trailer);
+ pdf_drop_obj(trailer);
fprintf(out, "startxref\n%d\n%%%%EOF\n", startxref);
}
@@ -792,7 +792,7 @@ int main(int argc, char **argv)
xref = pdf_open_document(ctx, infile);
if (pdf_needs_password(xref))
if (!pdf_authenticate_password(xref, password))
- fz_throw(ctx, "cannot authenticate password: %s\n", infile);
+ fz_throw(ctx, "cannot authenticate password: %s", infile);
out = fopen(outfile, "wb");
if (!out)
diff --git a/apps/mupdfextract.c b/apps/mupdfextract.c
index f309f39a..a6a677cd 100644
--- a/apps/mupdfextract.c
+++ b/apps/mupdfextract.c
@@ -2,7 +2,6 @@
* pdfextract -- the ultimate way to extract images and fonts from pdfs
*/
-#include "fitz.h"
#include "mupdf.h"
static pdf_document *doc = NULL;
@@ -17,96 +16,81 @@ static void usage(void)
exit(1);
}
-static int isimage(fz_obj *obj)
+static int isimage(pdf_obj *obj)
{
- fz_obj *type = fz_dict_gets(obj, "Subtype");
- return fz_is_name(type) && !strcmp(fz_to_name(type), "Image");
+ pdf_obj *type = pdf_dict_gets(obj, "Subtype");
+ return pdf_is_name(type) && !strcmp(pdf_to_name(type), "Image");
}
-static int isfontdesc(fz_obj *obj)
+static int isfontdesc(pdf_obj *obj)
{
- fz_obj *type = fz_dict_gets(obj, "Type");
- return fz_is_name(type) && !strcmp(fz_to_name(type), "FontDescriptor");
+ pdf_obj *type = pdf_dict_gets(obj, "Type");
+ return pdf_is_name(type) && !strcmp(pdf_to_name(type), "FontDescriptor");
}
static void saveimage(int num)
{
+ fz_image *image;
fz_pixmap *img;
- fz_obj *ref;
- char name[1024];
+ pdf_obj *ref;
+ char name[32];
- ref = fz_new_indirect(ctx, num, 0, doc);
+ ref = pdf_new_indirect(ctx, num, 0, doc);
/* TODO: detect DCTD and save as jpeg */
- img = pdf_load_image(doc, ref);
+ image = pdf_load_image(doc, ref);
+ img = fz_image_to_pixmap(ctx, image, 0, 0);
+ fz_drop_image(ctx, image);
- if (dorgb && img->colorspace && img->colorspace != fz_device_rgb)
- {
- fz_pixmap *temp;
- temp = fz_new_pixmap_with_rect(ctx, fz_device_rgb, fz_bound_pixmap(img));
- fz_convert_pixmap(ctx, img, temp);
- fz_drop_pixmap(ctx, img);
- img = temp;
- }
-
- if (img->n <= 4)
- {
- sprintf(name, "img-%04d.png", num);
- printf("extracting image %s\n", name);
- fz_write_png(ctx, img, name, 0);
- }
- else
- {
- sprintf(name, "img-%04d.pam", num);
- printf("extracting image %s\n", name);
- fz_write_pam(ctx, img, name, 0);
- }
+ sprintf(name, "img-%04d", num);
+ fz_write_pixmap(ctx, img, name, dorgb);
fz_drop_pixmap(ctx, img);
- fz_drop_obj(ref);
+ pdf_drop_obj(ref);
}
-static void savefont(fz_obj *dict, int num)
+static void savefont(pdf_obj *dict, int num)
{
char name[1024];
char *subtype;
fz_buffer *buf;
- fz_obj *stream = NULL;
- fz_obj *obj;
+ pdf_obj *stream = NULL;
+ pdf_obj *obj;
char *ext = "";
FILE *f;
char *fontname = "font";
- int n;
+ int n, len;
+ unsigned char *data;
- obj = fz_dict_gets(dict, "FontName");
+ obj = pdf_dict_gets(dict, "FontName");
if (obj)
- fontname = fz_to_name(obj);
+ fontname = pdf_to_name(obj);
- obj = fz_dict_gets(dict, "FontFile");
+ obj = pdf_dict_gets(dict, "FontFile");
if (obj)
{
stream = obj;
ext = "pfa";
}
- obj = fz_dict_gets(dict, "FontFile2");
+ obj = pdf_dict_gets(dict, "FontFile2");
if (obj)
{
stream = obj;
ext = "ttf";
}
- obj = fz_dict_gets(dict, "FontFile3");
+ obj = pdf_dict_gets(dict, "FontFile3");
if (obj)
{
stream = obj;
- obj = fz_dict_gets(obj, "Subtype");
- if (obj && !fz_is_name(obj))
+ obj = pdf_dict_gets(obj, "Subtype");
+ if (obj && !pdf_is_name(obj))
fz_throw(ctx, "Invalid font descriptor subtype");
- subtype = fz_to_name(obj);
+ subtype = pdf_to_name(obj);
if (!strcmp(subtype, "Type1C"))
ext = "cff";
else if (!strcmp(subtype, "CIDFontType0C"))
@@ -121,7 +105,7 @@ static void savefont(fz_obj *dict, int num)
return;
}
- buf = pdf_load_stream(doc, fz_to_num(stream), fz_to_gen(stream));
+ buf = pdf_load_stream(doc, pdf_to_num(stream), pdf_to_gen(stream));
sprintf(name, "%s-%04d.%s", fontname, num, ext);
printf("extracting font %s\n", name);
@@ -130,8 +114,9 @@ static void savefont(fz_obj *dict, int num)
if (!f)
fz_throw(ctx, "Error creating font file");
- n = fwrite(buf->data, 1, buf->len, f);
- if (n < buf->len)
+ len = fz_buffer_storage(ctx, buf, &data);
+ n = fwrite(data, 1, len, f);
+ if (n < len)
fz_throw(ctx, "Error writing font file");
if (fclose(f) < 0)
@@ -142,7 +127,7 @@ static void savefont(fz_obj *dict, int num)
static void showobject(int num)
{
- fz_obj *obj;
+ pdf_obj *obj;
if (!doc)
fz_throw(ctx, "no file specified");
@@ -154,7 +139,7 @@ static void showobject(int num)
else if (isfontdesc(obj))
savefont(obj, num);
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
#ifdef MUPDF_COMBINED_EXE
@@ -192,11 +177,11 @@ int main(int argc, char **argv)
doc = pdf_open_document(ctx, infile);
if (pdf_needs_password(doc))
if (!pdf_authenticate_password(doc, password))
- fz_throw(ctx, "cannot authenticate password: %s\n", infile);
+ fz_throw(ctx, "cannot authenticate password: %s", infile);
if (fz_optind == argc)
{
- for (o = 0; o < doc->len; o++)
+ for (o = 0; o < pdf_count_objects(doc); o++)
showobject(o);
}
else
diff --git a/apps/mupdfinfo.c b/apps/mupdfinfo.c
index 3c98c772..e02d8d1a 100644
--- a/apps/mupdfinfo.c
+++ b/apps/mupdfinfo.c
@@ -4,7 +4,7 @@
*/
#include "fitz.h"
-#include "mupdf.h"
+#include "mupdf-internal.h"
pdf_document *xref;
fz_context *ctx;
@@ -28,48 +28,48 @@ enum
struct info
{
int page;
- fz_obj *pageref;
- fz_obj *pageobj;
+ pdf_obj *pageref;
+ pdf_obj *pageobj;
union {
struct {
- fz_obj *obj;
+ pdf_obj *obj;
} info;
struct {
- fz_obj *obj;
+ pdf_obj *obj;
} crypt;
struct {
- fz_obj *obj;
+ pdf_obj *obj;
fz_rect *bbox;
} dim;
struct {
- fz_obj *obj;
- fz_obj *subtype;
- fz_obj *name;
+ pdf_obj *obj;
+ pdf_obj *subtype;
+ pdf_obj *name;
} font;
struct {
- fz_obj *obj;
- fz_obj *width;
- fz_obj *height;
- fz_obj *bpc;
- fz_obj *filter;
- fz_obj *cs;
- fz_obj *altcs;
+ pdf_obj *obj;
+ pdf_obj *width;
+ pdf_obj *height;
+ pdf_obj *bpc;
+ pdf_obj *filter;
+ pdf_obj *cs;
+ pdf_obj *altcs;
} image;
struct {
- fz_obj *obj;
- fz_obj *type;
+ pdf_obj *obj;
+ pdf_obj *type;
} shading;
struct {
- fz_obj *obj;
- fz_obj *type;
- fz_obj *paint;
- fz_obj *tiling;
- fz_obj *shading;
+ pdf_obj *obj;
+ pdf_obj *type;
+ pdf_obj *paint;
+ pdf_obj *tiling;
+ pdf_obj *shading;
} pattern;
struct {
- fz_obj *obj;
- fz_obj *groupsubtype;
- fz_obj *reference;
+ pdf_obj *obj;
+ pdf_obj *groupsubtype;
+ pdf_obj *reference;
} form;
} u;
};
@@ -168,36 +168,36 @@ infousage(void)
static void
showglobalinfo(void)
{
- fz_obj *obj;
+ pdf_obj *obj;
printf("\nPDF-%d.%d\n", xref->version / 10, xref->version % 10);
- obj = fz_dict_gets(xref->trailer, "Info");
+ obj = pdf_dict_gets(xref->trailer, "Info");
if (obj)
{
- printf("Info object (%d %d R):\n", fz_to_num(obj), fz_to_gen(obj));
- fz_debug_obj(fz_resolve_indirect(obj));
+ printf("Info object (%d %d R):\n", pdf_to_num(obj), pdf_to_gen(obj));
+ pdf_print_obj(pdf_resolve_indirect(obj));
}
- obj = fz_dict_gets(xref->trailer, "Encrypt");
+ obj = pdf_dict_gets(xref->trailer, "Encrypt");
if (obj)
{
- printf("\nEncryption object (%d %d R):\n", fz_to_num(obj), fz_to_gen(obj));
- fz_debug_obj(fz_resolve_indirect(obj));
+ printf("\nEncryption object (%d %d R):\n", pdf_to_num(obj), pdf_to_gen(obj));
+ pdf_print_obj(pdf_resolve_indirect(obj));
}
printf("\nPages: %d\n\n", pagecount);
}
static void
-gatherdimensions(int page, fz_obj *pageref, fz_obj *pageobj)
+gatherdimensions(int page, pdf_obj *pageref, pdf_obj *pageobj)
{
fz_rect bbox;
- fz_obj *obj;
+ pdf_obj *obj;
int j;
- obj = fz_dict_gets(pageobj, "MediaBox");
- if (!fz_is_array(obj))
+ obj = pdf_dict_gets(pageobj, "MediaBox");
+ if (!pdf_is_array(obj))
return;
bbox = pdf_to_rect(ctx, obj);
@@ -222,33 +222,33 @@ gatherdimensions(int page, fz_obj *pageref, fz_obj *pageobj)
}
static void
-gatherfonts(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
+gatherfonts(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
int i, n;
- n = fz_dict_len(dict);
+ n = pdf_dict_len(dict);
for (i = 0; i < n; i++)
{
- fz_obj *fontdict = NULL;
- fz_obj *subtype = NULL;
- fz_obj *basefont = NULL;
- fz_obj *name = NULL;
+ pdf_obj *fontdict = NULL;
+ pdf_obj *subtype = NULL;
+ pdf_obj *basefont = NULL;
+ pdf_obj *name = NULL;
int k;
- fontdict = fz_dict_get_val(dict, i);
- if (!fz_is_dict(fontdict))
+ fontdict = pdf_dict_get_val(dict, i);
+ if (!pdf_is_dict(fontdict))
{
- fz_warn(ctx, "not a font dict (%d %d R)", fz_to_num(fontdict), fz_to_gen(fontdict));
+ fz_warn(ctx, "not a font dict (%d %d R)", pdf_to_num(fontdict), pdf_to_gen(fontdict));
continue;
}
- subtype = fz_dict_gets(fontdict, "Subtype");
- basefont = fz_dict_gets(fontdict, "BaseFont");
- if (!basefont || fz_is_null(basefont))
- name = fz_dict_gets(fontdict, "Name");
+ subtype = pdf_dict_gets(fontdict, "Subtype");
+ basefont = pdf_dict_gets(fontdict, "BaseFont");
+ if (!basefont || pdf_is_null(basefont))
+ name = pdf_dict_gets(fontdict, "Name");
for (k = 0; k < fonts; k++)
- if (!fz_objcmp(font[k].u.font.obj, fontdict))
+ if (!pdf_objcmp(font[k].u.font.obj, fontdict))
break;
if (k < fonts)
@@ -267,57 +267,57 @@ gatherfonts(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
}
static void
-gatherimages(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
+gatherimages(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
int i, n;
- n = fz_dict_len(dict);
+ n = pdf_dict_len(dict);
for (i = 0; i < n; i++)
{
- fz_obj *imagedict;
- fz_obj *type;
- fz_obj *width;
- fz_obj *height;
- fz_obj *bpc = NULL;
- fz_obj *filter = NULL;
- fz_obj *cs = NULL;
- fz_obj *altcs;
+ pdf_obj *imagedict;
+ pdf_obj *type;
+ pdf_obj *width;
+ pdf_obj *height;
+ pdf_obj *bpc = NULL;
+ pdf_obj *filter = NULL;
+ pdf_obj *cs = NULL;
+ pdf_obj *altcs;
int k;
- imagedict = fz_dict_get_val(dict, i);
- if (!fz_is_dict(imagedict))
+ imagedict = pdf_dict_get_val(dict, i);
+ if (!pdf_is_dict(imagedict))
{
- fz_warn(ctx, "not an image dict (%d %d R)", fz_to_num(imagedict), fz_to_gen(imagedict));
+ fz_warn(ctx, "not an image dict (%d %d R)", pdf_to_num(imagedict), pdf_to_gen(imagedict));
continue;
}
- type = fz_dict_gets(imagedict, "Subtype");
- if (strcmp(fz_to_name(type), "Image"))
+ type = pdf_dict_gets(imagedict, "Subtype");
+ if (strcmp(pdf_to_name(type), "Image"))
continue;
- filter = fz_dict_gets(imagedict, "Filter");
+ filter = pdf_dict_gets(imagedict, "Filter");
altcs = NULL;
- cs = fz_dict_gets(imagedict, "ColorSpace");
- if (fz_is_array(cs))
+ cs = pdf_dict_gets(imagedict, "ColorSpace");
+ if (pdf_is_array(cs))
{
- fz_obj *cses = cs;
+ pdf_obj *cses = cs;
- cs = fz_array_get(cses, 0);
- if (fz_is_name(cs) && (!strcmp(fz_to_name(cs), "DeviceN") || !strcmp(fz_to_name(cs), "Separation")))
+ cs = pdf_array_get(cses, 0);
+ if (pdf_is_name(cs) && (!strcmp(pdf_to_name(cs), "DeviceN") || !strcmp(pdf_to_name(cs), "Separation")))
{
- altcs = fz_array_get(cses, 2);
- if (fz_is_array(altcs))
- altcs = fz_array_get(altcs, 0);
+ altcs = pdf_array_get(cses, 2);
+ if (pdf_is_array(altcs))
+ altcs = pdf_array_get(altcs, 0);
}
}
- width = fz_dict_gets(imagedict, "Width");
- height = fz_dict_gets(imagedict, "Height");
- bpc = fz_dict_gets(imagedict, "BitsPerComponent");
+ width = pdf_dict_gets(imagedict, "Width");
+ height = pdf_dict_gets(imagedict, "Height");
+ bpc = pdf_dict_gets(imagedict, "BitsPerComponent");
for (k = 0; k < images; k++)
- if (!fz_objcmp(image[k].u.image.obj, imagedict))
+ if (!pdf_objcmp(image[k].u.image.obj, imagedict))
break;
if (k < images)
@@ -340,42 +340,42 @@ gatherimages(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
}
static void
-gatherforms(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
+gatherforms(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
int i, n;
- n = fz_dict_len(dict);
+ n = pdf_dict_len(dict);
for (i = 0; i < n; i++)
{
- fz_obj *xobjdict;
- fz_obj *type;
- fz_obj *subtype;
- fz_obj *group;
- fz_obj *groupsubtype;
- fz_obj *reference;
+ pdf_obj *xobjdict;
+ pdf_obj *type;
+ pdf_obj *subtype;
+ pdf_obj *group;
+ pdf_obj *groupsubtype;
+ pdf_obj *reference;
int k;
- xobjdict = fz_dict_get_val(dict, i);
- if (!fz_is_dict(xobjdict))
+ xobjdict = pdf_dict_get_val(dict, i);
+ if (!pdf_is_dict(xobjdict))
{
- fz_warn(ctx, "not a xobject dict (%d %d R)", fz_to_num(xobjdict), fz_to_gen(xobjdict));
+ fz_warn(ctx, "not a xobject dict (%d %d R)", pdf_to_num(xobjdict), pdf_to_gen(xobjdict));
continue;
}
- type = fz_dict_gets(xobjdict, "Subtype");
- if (strcmp(fz_to_name(type), "Form"))
+ type = pdf_dict_gets(xobjdict, "Subtype");
+ if (strcmp(pdf_to_name(type), "Form"))
continue;
- subtype = fz_dict_gets(xobjdict, "Subtype2");
- if (!strcmp(fz_to_name(subtype), "PS"))
+ subtype = pdf_dict_gets(xobjdict, "Subtype2");
+ if (!strcmp(pdf_to_name(subtype), "PS"))
continue;
- group = fz_dict_gets(xobjdict, "Group");
- groupsubtype = fz_dict_gets(group, "S");
- reference = fz_dict_gets(xobjdict, "Ref");
+ group = pdf_dict_gets(xobjdict, "Group");
+ groupsubtype = pdf_dict_gets(group, "S");
+ reference = pdf_dict_gets(xobjdict, "Ref");
for (k = 0; k < forms; k++)
- if (!fz_objcmp(form[k].u.form.obj, xobjdict))
+ if (!pdf_objcmp(form[k].u.form.obj, xobjdict))
break;
if (k < forms)
@@ -394,33 +394,33 @@ gatherforms(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
}
static void
-gatherpsobjs(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
+gatherpsobjs(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
int i, n;
- n = fz_dict_len(dict);
+ n = pdf_dict_len(dict);
for (i = 0; i < n; i++)
{
- fz_obj *xobjdict;
- fz_obj *type;
- fz_obj *subtype;
+ pdf_obj *xobjdict;
+ pdf_obj *type;
+ pdf_obj *subtype;
int k;
- xobjdict = fz_dict_get_val(dict, i);
- if (!fz_is_dict(xobjdict))
+ xobjdict = pdf_dict_get_val(dict, i);
+ if (!pdf_is_dict(xobjdict))
{
- fz_warn(ctx, "not a xobject dict (%d %d R)", fz_to_num(xobjdict), fz_to_gen(xobjdict));
+ fz_warn(ctx, "not a xobject dict (%d %d R)", pdf_to_num(xobjdict), pdf_to_gen(xobjdict));
continue;
}
- type = fz_dict_gets(xobjdict, "Subtype");
- subtype = fz_dict_gets(xobjdict, "Subtype2");
- if (strcmp(fz_to_name(type), "PS") &&
- (strcmp(fz_to_name(type), "Form") || strcmp(fz_to_name(subtype), "PS")))
+ type = pdf_dict_gets(xobjdict, "Subtype");
+ subtype = pdf_dict_gets(xobjdict, "Subtype2");
+ if (strcmp(pdf_to_name(type), "PS") &&
+ (strcmp(pdf_to_name(type), "Form") || strcmp(pdf_to_name(subtype), "PS")))
continue;
for (k = 0; k < psobjs; k++)
- if (!fz_objcmp(psobj[k].u.form.obj, xobjdict))
+ if (!pdf_objcmp(psobj[k].u.form.obj, xobjdict))
break;
if (k < psobjs)
@@ -437,33 +437,33 @@ gatherpsobjs(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
}
static void
-gathershadings(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
+gathershadings(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
int i, n;
- n = fz_dict_len(dict);
+ n = pdf_dict_len(dict);
for (i = 0; i < n; i++)
{
- fz_obj *shade;
- fz_obj *type;
+ pdf_obj *shade;
+ pdf_obj *type;
int k;
- shade = fz_dict_get_val(dict, i);
- if (!fz_is_dict(shade))
+ shade = pdf_dict_get_val(dict, i);
+ if (!pdf_is_dict(shade))
{
- fz_warn(ctx, "not a shading dict (%d %d R)", fz_to_num(shade), fz_to_gen(shade));
+ fz_warn(ctx, "not a shading dict (%d %d R)", pdf_to_num(shade), pdf_to_gen(shade));
continue;
}
- type = fz_dict_gets(shade, "ShadingType");
- if (!fz_is_int(type) || fz_to_int(type) < 1 || fz_to_int(type) > 7)
+ type = pdf_dict_gets(shade, "ShadingType");
+ if (!pdf_is_int(type) || pdf_to_int(type) < 1 || pdf_to_int(type) > 7)
{
- fz_warn(ctx, "not a shading type (%d %d R)", fz_to_num(shade), fz_to_gen(shade));
+ fz_warn(ctx, "not a shading type (%d %d R)", pdf_to_num(shade), pdf_to_gen(shade));
type = NULL;
}
for (k = 0; k < shadings; k++)
- if (!fz_objcmp(shading[k].u.shading.obj, shade))
+ if (!pdf_objcmp(shading[k].u.shading.obj, shade))
break;
if (k < shadings)
@@ -481,57 +481,57 @@ gathershadings(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
}
static void
-gatherpatterns(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
+gatherpatterns(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
int i, n;
- n = fz_dict_len(dict);
+ n = pdf_dict_len(dict);
for (i = 0; i < n; i++)
{
- fz_obj *patterndict;
- fz_obj *type;
- fz_obj *paint = NULL;
- fz_obj *tiling = NULL;
- fz_obj *shading = NULL;
+ pdf_obj *patterndict;
+ pdf_obj *type;
+ pdf_obj *paint = NULL;
+ pdf_obj *tiling = NULL;
+ pdf_obj *shading = NULL;
int k;
- patterndict = fz_dict_get_val(dict, i);
- if (!fz_is_dict(patterndict))
+ patterndict = pdf_dict_get_val(dict, i);
+ if (!pdf_is_dict(patterndict))
{
- fz_warn(ctx, "not a pattern dict (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict));
+ fz_warn(ctx, "not a pattern dict (%d %d R)", pdf_to_num(patterndict), pdf_to_gen(patterndict));
continue;
}
- type = fz_dict_gets(patterndict, "PatternType");
- if (!fz_is_int(type) || fz_to_int(type) < 1 || fz_to_int(type) > 2)
+ type = pdf_dict_gets(patterndict, "PatternType");
+ if (!pdf_is_int(type) || pdf_to_int(type) < 1 || pdf_to_int(type) > 2)
{
- fz_warn(ctx, "not a pattern type (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict));
+ fz_warn(ctx, "not a pattern type (%d %d R)", pdf_to_num(patterndict), pdf_to_gen(patterndict));
type = NULL;
}
- if (fz_to_int(type) == 1)
+ if (pdf_to_int(type) == 1)
{
- paint = fz_dict_gets(patterndict, "PaintType");
- if (!fz_is_int(paint) || fz_to_int(paint) < 1 || fz_to_int(paint) > 2)
+ paint = pdf_dict_gets(patterndict, "PaintType");
+ if (!pdf_is_int(paint) || pdf_to_int(paint) < 1 || pdf_to_int(paint) > 2)
{
- fz_warn(ctx, "not a pattern paint type (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict));
+ fz_warn(ctx, "not a pattern paint type (%d %d R)", pdf_to_num(patterndict), pdf_to_gen(patterndict));
paint = NULL;
}
- tiling = fz_dict_gets(patterndict, "TilingType");
- if (!fz_is_int(tiling) || fz_to_int(tiling) < 1 || fz_to_int(tiling) > 3)
+ tiling = pdf_dict_gets(patterndict, "TilingType");
+ if (!pdf_is_int(tiling) || pdf_to_int(tiling) < 1 || pdf_to_int(tiling) > 3)
{
- fz_warn(ctx, "not a pattern tiling type (%d %d R)", fz_to_num(patterndict), fz_to_gen(patterndict));
+ fz_warn(ctx, "not a pattern tiling type (%d %d R)", pdf_to_num(patterndict), pdf_to_gen(patterndict));
tiling = NULL;
}
}
else
{
- shading = fz_dict_gets(patterndict, "Shading");
+ shading = pdf_dict_gets(patterndict, "Shading");
}
for (k = 0; k < patterns; k++)
- if (!fz_objcmp(pattern[k].u.pattern.obj, patterndict))
+ if (!pdf_objcmp(pattern[k].u.pattern.obj, patterndict))
break;
if (k < patterns)
@@ -552,15 +552,15 @@ gatherpatterns(int page, fz_obj *pageref, fz_obj *pageobj, fz_obj *dict)
}
static void
-gatherresourceinfo(int page, fz_obj *rsrc)
+gatherresourceinfo(int page, pdf_obj *rsrc)
{
- fz_obj *pageobj;
- fz_obj *pageref;
- fz_obj *font;
- fz_obj *xobj;
- fz_obj *shade;
- fz_obj *pattern;
- fz_obj *subrsrc;
+ pdf_obj *pageobj;
+ pdf_obj *pageref;
+ pdf_obj *font;
+ pdf_obj *xobj;
+ pdf_obj *shade;
+ pdf_obj *pattern;
+ pdf_obj *subrsrc;
int i;
pageobj = xref->page_objs[page-1];
@@ -569,24 +569,24 @@ gatherresourceinfo(int page, fz_obj *rsrc)
if (!pageobj)
fz_throw(ctx, "cannot retrieve info from page %d", page);
- font = fz_dict_gets(rsrc, "Font");
+ font = pdf_dict_gets(rsrc, "Font");
if (font)
{
int n;
gatherfonts(page, pageref, pageobj, font);
- n = fz_dict_len(font);
+ n = pdf_dict_len(font);
for (i = 0; i < n; i++)
{
- fz_obj *obj = fz_dict_get_val(font, i);
+ pdf_obj *obj = pdf_dict_get_val(font, i);
- subrsrc = fz_dict_gets(obj, "Resources");
- if (subrsrc && fz_objcmp(rsrc, subrsrc))
+ subrsrc = pdf_dict_gets(obj, "Resources");
+ if (subrsrc && pdf_objcmp(rsrc, subrsrc))
gatherresourceinfo(page, subrsrc);
}
}
- xobj = fz_dict_gets(rsrc, "XObject");
+ xobj = pdf_dict_gets(rsrc, "XObject");
if (xobj)
{
int n;
@@ -594,31 +594,31 @@ gatherresourceinfo(int page, fz_obj *rsrc)
gatherimages(page, pageref, pageobj, xobj);
gatherforms(page, pageref, pageobj, xobj);
gatherpsobjs(page, pageref, pageobj, xobj);
- n = fz_dict_len(xobj);
+ n = pdf_dict_len(xobj);
for (i = 0; i < n; i++)
{
- fz_obj *obj = fz_dict_get_val(xobj, i);
- subrsrc = fz_dict_gets(obj, "Resources");
- if (subrsrc && fz_objcmp(rsrc, subrsrc))
+ pdf_obj *obj = pdf_dict_get_val(xobj, i);
+ subrsrc = pdf_dict_gets(obj, "Resources");
+ if (subrsrc && pdf_objcmp(rsrc, subrsrc))
gatherresourceinfo(page, subrsrc);
}
}
- shade = fz_dict_gets(rsrc, "Shading");
+ shade = pdf_dict_gets(rsrc, "Shading");
if (shade)
gathershadings(page, pageref, pageobj, shade);
- pattern = fz_dict_gets(rsrc, "Pattern");
+ pattern = pdf_dict_gets(rsrc, "Pattern");
if (pattern)
{
int n;
gatherpatterns(page, pageref, pageobj, pattern);
- n = fz_dict_len(pattern);
+ n = pdf_dict_len(pattern);
for (i = 0; i < n; i++)
{
- fz_obj *obj = fz_dict_get_val(pattern, i);
- subrsrc = fz_dict_gets(obj, "Resources");
- if (subrsrc && fz_objcmp(rsrc, subrsrc))
+ pdf_obj *obj = pdf_dict_get_val(pattern, i);
+ subrsrc = pdf_dict_gets(obj, "Resources");
+ if (subrsrc && pdf_objcmp(rsrc, subrsrc))
gatherresourceinfo(page, subrsrc);
}
}
@@ -627,9 +627,9 @@ gatherresourceinfo(int page, fz_obj *rsrc)
static void
gatherpageinfo(int page)
{
- fz_obj *pageobj;
- fz_obj *pageref;
- fz_obj *rsrc;
+ pdf_obj *pageobj;
+ pdf_obj *pageref;
+ pdf_obj *rsrc;
pageobj = xref->page_objs[page-1];
pageref = xref->page_refs[page-1];
@@ -639,7 +639,7 @@ gatherpageinfo(int page)
gatherdimensions(page, pageref, pageobj);
- rsrc = fz_dict_gets(pageobj, "Resources");
+ rsrc = pdf_dict_gets(pageobj, "Resources");
gatherresourceinfo(page, rsrc);
}
@@ -658,7 +658,7 @@ printinfo(char *filename, int show, int page)
{
printf(PAGE_FMT "[ %g %g %g %g ]\n",
dim[i].page,
- fz_to_num(dim[i].pageref), fz_to_gen(dim[i].pageref),
+ pdf_to_num(dim[i].pageref), pdf_to_gen(dim[i].pageref),
dim[i].u.dim.bbox->x0,
dim[i].u.dim.bbox->y0,
dim[i].u.dim.bbox->x1,
@@ -674,10 +674,10 @@ printinfo(char *filename, int show, int page)
{
printf(PAGE_FMT "%s '%s' (%d %d R)\n",
font[i].page,
- fz_to_num(font[i].pageref), fz_to_gen(font[i].pageref),
- fz_to_name(font[i].u.font.subtype),
- fz_to_name(font[i].u.font.name),
- fz_to_num(font[i].u.font.obj), fz_to_gen(font[i].u.font.obj));
+ pdf_to_num(font[i].pageref), pdf_to_gen(font[i].pageref),
+ pdf_to_name(font[i].u.font.subtype),
+ pdf_to_name(font[i].u.font.name),
+ pdf_to_num(font[i].u.font.obj), pdf_to_gen(font[i].u.font.obj));
}
printf("\n");
}
@@ -692,29 +692,29 @@ printinfo(char *filename, int show, int page)
printf(PAGE_FMT "[ ",
image[i].page,
- fz_to_num(image[i].pageref), fz_to_gen(image[i].pageref));
+ pdf_to_num(image[i].pageref), pdf_to_gen(image[i].pageref));
- if (fz_is_array(image[i].u.image.filter))
+ if (pdf_is_array(image[i].u.image.filter))
{
- int n = fz_array_len(image[i].u.image.filter);
+ int n = pdf_array_len(image[i].u.image.filter);
for (j = 0; j < n; j++)
{
- fz_obj *obj = fz_array_get(image[i].u.image.filter, j);
- char *filter = fz_strdup(ctx, fz_to_name(obj));
+ pdf_obj *obj = pdf_array_get(image[i].u.image.filter, j);
+ char *filter = fz_strdup(ctx, pdf_to_name(obj));
if (strstr(filter, "Decode"))
*(strstr(filter, "Decode")) = '\0';
printf("%s%s",
filter,
- j == fz_array_len(image[i].u.image.filter) - 1 ? "" : " ");
+ j == pdf_array_len(image[i].u.image.filter) - 1 ? "" : " ");
fz_free(ctx, filter);
}
}
else if (image[i].u.image.filter)
{
- fz_obj *obj = image[i].u.image.filter;
- char *filter = fz_strdup(ctx, fz_to_name(obj));
+ pdf_obj *obj = image[i].u.image.filter;
+ char *filter = fz_strdup(ctx, pdf_to_name(obj));
if (strstr(filter, "Decode"))
*(strstr(filter, "Decode")) = '\0';
@@ -727,7 +727,7 @@ printinfo(char *filename, int show, int page)
if (image[i].u.image.cs)
{
- cs = fz_strdup(ctx, fz_to_name(image[i].u.image.cs));
+ cs = fz_strdup(ctx, pdf_to_name(image[i].u.image.cs));
if (!strncmp(cs, "Device", 6))
{
@@ -746,7 +746,7 @@ printinfo(char *filename, int show, int page)
}
if (image[i].u.image.altcs)
{
- altcs = fz_strdup(ctx, fz_to_name(image[i].u.image.altcs));
+ altcs = fz_strdup(ctx, pdf_to_name(image[i].u.image.altcs));
if (!strncmp(altcs, "Device", 6))
{
@@ -765,13 +765,13 @@ printinfo(char *filename, int show, int page)
}
printf(" ] %dx%d %dbpc %s%s%s (%d %d R)\n",
- fz_to_int(image[i].u.image.width),
- fz_to_int(image[i].u.image.height),
- image[i].u.image.bpc ? fz_to_int(image[i].u.image.bpc) : 1,
+ pdf_to_int(image[i].u.image.width),
+ pdf_to_int(image[i].u.image.height),
+ image[i].u.image.bpc ? pdf_to_int(image[i].u.image.bpc) : 1,
image[i].u.image.cs ? cs : "ImageMask",
image[i].u.image.altcs ? " " : "",
image[i].u.image.altcs ? altcs : "",
- fz_to_num(image[i].u.image.obj), fz_to_gen(image[i].u.image.obj));
+ pdf_to_num(image[i].u.image.obj), pdf_to_gen(image[i].u.image.obj));
fz_free(ctx, cs);
fz_free(ctx, altcs);
@@ -798,9 +798,9 @@ printinfo(char *filename, int show, int page)
printf(PAGE_FMT "%s (%d %d R)\n",
shading[i].page,
- fz_to_num(shading[i].pageref), fz_to_gen(shading[i].pageref),
- shadingtype[fz_to_int(shading[i].u.shading.type)],
- fz_to_num(shading[i].u.shading.obj), fz_to_gen(shading[i].u.shading.obj));
+ pdf_to_num(shading[i].pageref), pdf_to_gen(shading[i].pageref),
+ shadingtype[pdf_to_int(shading[i].u.shading.type)],
+ pdf_to_num(shading[i].u.shading.obj), pdf_to_gen(shading[i].u.shading.obj));
}
printf("\n");
}
@@ -810,7 +810,7 @@ printinfo(char *filename, int show, int page)
printf("Patterns (%d):\n", patterns);
for (i = 0; i < patterns; i++)
{
- if (fz_to_int(pattern[i].u.pattern.type) == 1)
+ if (pdf_to_int(pattern[i].u.pattern.type) == 1)
{
char *painttype[] =
{
@@ -828,18 +828,18 @@ printinfo(char *filename, int show, int page)
printf(PAGE_FMT "Tiling %s %s (%d %d R)\n",
pattern[i].page,
- fz_to_num(pattern[i].pageref), fz_to_gen(pattern[i].pageref),
- painttype[fz_to_int(pattern[i].u.pattern.paint)],
- tilingtype[fz_to_int(pattern[i].u.pattern.tiling)],
- fz_to_num(pattern[i].u.pattern.obj), fz_to_gen(pattern[i].u.pattern.obj));
+ pdf_to_num(pattern[i].pageref), pdf_to_gen(pattern[i].pageref),
+ painttype[pdf_to_int(pattern[i].u.pattern.paint)],
+ tilingtype[pdf_to_int(pattern[i].u.pattern.tiling)],
+ pdf_to_num(pattern[i].u.pattern.obj), pdf_to_gen(pattern[i].u.pattern.obj));
}
else
{
printf(PAGE_FMT "Shading %d %d R (%d %d R)\n",
pattern[i].page,
- fz_to_num(pattern[i].pageref), fz_to_gen(pattern[i].pageref),
- fz_to_num(pattern[i].u.pattern.shading), fz_to_gen(pattern[i].u.pattern.shading),
- fz_to_num(pattern[i].u.pattern.obj), fz_to_gen(pattern[i].u.pattern.obj));
+ pdf_to_num(pattern[i].pageref), pdf_to_gen(pattern[i].pageref),
+ pdf_to_num(pattern[i].u.pattern.shading), pdf_to_gen(pattern[i].u.pattern.shading),
+ pdf_to_num(pattern[i].u.pattern.obj), pdf_to_gen(pattern[i].u.pattern.obj));
}
}
printf("\n");
@@ -852,12 +852,12 @@ printinfo(char *filename, int show, int page)
{
printf(PAGE_FMT "Form%s%s%s%s (%d %d R)\n",
form[i].page,
- fz_to_num(form[i].pageref), fz_to_gen(form[i].pageref),
+ pdf_to_num(form[i].pageref), pdf_to_gen(form[i].pageref),
form[i].u.form.groupsubtype ? " " : "",
- form[i].u.form.groupsubtype ? fz_to_name(form[i].u.form.groupsubtype) : "",
+ form[i].u.form.groupsubtype ? pdf_to_name(form[i].u.form.groupsubtype) : "",
form[i].u.form.groupsubtype ? " Group" : "",
form[i].u.form.reference ? " Reference" : "",
- fz_to_num(form[i].u.form.obj), fz_to_gen(form[i].u.form.obj));
+ pdf_to_num(form[i].u.form.obj), pdf_to_gen(form[i].u.form.obj));
}
printf("\n");
}
@@ -869,8 +869,8 @@ printinfo(char *filename, int show, int page)
{
printf(PAGE_FMT "(%d %d R)\n",
psobj[i].page,
- fz_to_num(psobj[i].pageref), fz_to_gen(psobj[i].pageref),
- fz_to_num(psobj[i].u.form.obj), fz_to_gen(psobj[i].u.form.obj));
+ pdf_to_num(psobj[i].pageref), pdf_to_gen(psobj[i].pageref),
+ pdf_to_num(psobj[i].u.form.obj), pdf_to_gen(psobj[i].u.form.obj));
}
printf("\n");
}
@@ -996,7 +996,7 @@ int main(int argc, char **argv)
xref = pdf_open_document(ctx, filename);
if (pdf_needs_password(xref))
if (!pdf_authenticate_password(xref, password))
- fz_throw(ctx, "cannot authenticate password: %s\n", filename);
+ fz_throw(ctx, "cannot authenticate password: %s", filename);
pagecount = pdf_count_pages(xref);
showglobalinfo();
diff --git a/apps/mupdfshow.c b/apps/mupdfshow.c
index 8dcdd17d..70ca7a62 100644
--- a/apps/mupdfshow.c
+++ b/apps/mupdfshow.c
@@ -2,8 +2,7 @@
* pdfshow -- the ultimate pdf debugging tool
*/
-#include "fitz.h"
-#include "mupdf.h"
+#include "mupdf-internal.h"
static pdf_document *doc = NULL;
static fz_context *ctx = NULL;
@@ -25,7 +24,7 @@ static void showtrailer(void)
if (!doc)
fz_throw(ctx, "no file specified");
printf("trailer\n");
- fz_debug_obj(doc->trailer);
+ pdf_print_obj(doc->trailer);
printf("\n");
}
@@ -33,13 +32,13 @@ static void showxref(void)
{
if (!doc)
fz_throw(ctx, "no file specified");
- pdf_debug_xref(doc);
+ pdf_print_xref(doc);
printf("\n");
}
static void showpagetree(void)
{
- fz_obj *ref;
+ pdf_obj *ref;
int count;
int i;
@@ -50,7 +49,7 @@ static void showpagetree(void)
for (i = 0; i < count; i++)
{
ref = doc->page_refs[i];
- printf("page %d = %d %d R\n", i + 1, fz_to_num(ref), fz_to_gen(ref));
+ printf("page %d = %d %d R\n", i + 1, pdf_to_num(ref), pdf_to_gen(ref));
}
printf("\n");
}
@@ -107,7 +106,7 @@ static void showstream(int num, int gen)
static void showobject(int num, int gen)
{
- fz_obj *obj;
+ pdf_obj *obj;
if (!doc)
fz_throw(ctx, "no file specified");
@@ -123,7 +122,7 @@ static void showobject(int num, int gen)
else
{
printf("%d %d obj\n", num, gen);
- fz_debug_obj(obj);
+ pdf_print_obj(obj);
printf("stream\n");
showstream(num, gen);
printf("endstream\n");
@@ -133,19 +132,19 @@ static void showobject(int num, int gen)
else
{
printf("%d %d obj\n", num, gen);
- fz_debug_obj(obj);
+ pdf_print_obj(obj);
printf("endobj\n\n");
}
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
static void showgrep(char *filename)
{
- fz_obj *obj;
+ pdf_obj *obj;
int i;
- for (i = 0; i < doc->len; i++)
+ for (i = 0; i < pdf_count_objects(doc); i++)
{
if (doc->table[i].type == 'n' || doc->table[i].type == 'o')
{
@@ -159,17 +158,17 @@ static void showgrep(char *filename)
continue;
}
- fz_sort_dict(obj);
+ pdf_sort_dict(obj);
printf("%s:%d: ", filename, i);
- fz_fprint_obj(stdout, obj, 1);
+ pdf_fprint_obj(stdout, obj, 1);
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
}
printf("%s:trailer: ", filename);
- fz_fprint_obj(stdout, doc->trailer, 1);
+ pdf_fprint_obj(stdout, doc->trailer, 1);
}
#ifdef MUPDF_COMBINED_EXE
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 6f2d766d..acad7c9f 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -1,8 +1,7 @@
-#include "fitz.h"
+#include "pdfapp.h"
#include "mupdf.h"
#include "muxps.h"
#include "mucbz.h"
-#include "pdfapp.h"
#include <ctype.h> /* for tolower() */
@@ -80,23 +79,7 @@ void pdfapp_init(fz_context *ctx, pdfapp_t *app)
void pdfapp_invert(pdfapp_t *app, fz_bbox rect)
{
- unsigned char *p;
- int x, y, n;
-
- int x0 = CLAMP(rect.x0 - app->image->x, 0, app->image->w - 1);
- int x1 = CLAMP(rect.x1 - app->image->x, 0, app->image->w - 1);
- int y0 = CLAMP(rect.y0 - app->image->y, 0, app->image->h - 1);
- int y1 = CLAMP(rect.y1 - app->image->y, 0, app->image->h - 1);
-
- for (y = y0; y < y1; y++)
- {
- p = app->image->samples + (y * app->image->w + x0) * app->image->n;
- for (x = x0; x < x1; x++)
- {
- for (n = app->image->n; n > 0; n--, p++)
- *p = 255 - *p;
- }
- }
+ fz_invert_pixmap_rect(app->image, rect);
}
void pdfapp_open(pdfapp_t *app, char *filename, int fd, int reload)
@@ -174,7 +157,7 @@ void pdfapp_close(pdfapp_t *app)
app->page_list = NULL;
if (app->page_text)
- fz_free_text_span(app->ctx, app->page_text);
+ fz_free_text_page(app->ctx, app->page_text);
app->page_text = NULL;
if (app->page_links)
@@ -216,20 +199,23 @@ static fz_matrix pdfapp_viewctm(pdfapp_t *app)
static void pdfapp_panview(pdfapp_t *app, int newx, int newy)
{
+ int image_w = fz_pixmap_width(app->ctx, app->image);
+ int image_h = fz_pixmap_height(app->ctx, app->image);
+
if (newx > 0)
newx = 0;
if (newy > 0)
newy = 0;
- if (newx + app->image->w < app->winw)
- newx = app->winw - app->image->w;
- if (newy + app->image->h < app->winh)
- newy = app->winh - app->image->h;
+ if (newx + image_w < app->winw)
+ newx = app->winw - image_w;
+ if (newy + image_h < app->winh)
+ newy = app->winh - image_h;
- if (app->winw >= app->image->w)
- newx = (app->winw - app->image->w) / 2;
- if (app->winh >= app->image->h)
- newy = (app->winh - app->image->h) / 2;
+ if (app->winw >= image_w)
+ newx = (app->winw - image_w) / 2;
+ if (app->winh >= image_h)
+ newy = (app->winh - image_h) / 2;
if (newx != app->panx || newy != app->pany)
winrepaint(app);
@@ -245,7 +231,7 @@ static void pdfapp_loadpage(pdfapp_t *app)
if (app->page_list)
fz_free_display_list(app->ctx, app->page_list);
if (app->page_text)
- fz_free_text_span(app->ctx, app->page_text);
+ fz_free_text_page(app->ctx, app->page_text);
if (app->page_links)
fz_drop_link(app->ctx, app->page_links);
if (app->page)
@@ -270,9 +256,11 @@ static void pdfapp_loadpage(pdfapp_t *app)
}
}
+#define MAX_TITLE 256
+
static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repaint)
{
- char buf[256];
+ char buf[MAX_TITLE];
fz_device *idev;
fz_device *tdev;
fz_colorspace *colorspace;
@@ -290,16 +278,29 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
app->hitlen = 0;
/* Extract text */
- app->page_text = fz_new_text_span(app->ctx);
- tdev = fz_new_text_device(app->ctx, app->page_text);
+ app->page_sheet = fz_new_text_sheet(app->ctx);
+ app->page_text = fz_new_text_page(app->ctx, app->page_bbox);
+ tdev = fz_new_text_device(app->ctx, app->page_sheet, app->page_text);
fz_run_display_list(app->page_list, tdev, fz_identity, fz_infinite_bbox, NULL);
fz_free_device(tdev);
}
if (drawpage)
{
- sprintf(buf, "%s - %d/%d (%d dpi)", app->doctitle,
+ char buf2[64];
+ int len;
+
+ sprintf(buf2, " - %d/%d (%d dpi)",
app->pageno, app->pagecount, app->resolution);
+ len = MAX_TITLE-strlen(buf2);
+ if (strlen(app->doctitle) > len)
+ {
+ snprintf(buf, len-3, "%s", app->doctitle);
+ strcat(buf, "...");
+ strcat(buf, buf2);
+ }
+ else
+ sprintf(buf, "%s%s", app->doctitle, buf2);
wintitle(app, buf);
ctm = pdfapp_viewctm(app);
@@ -316,7 +317,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
#else
colorspace = fz_device_rgb;
#endif
- app->image = fz_new_pixmap_with_rect(app->ctx, colorspace, bbox);
+ app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, bbox);
fz_clear_pixmap_with_value(app->ctx, app->image, 255);
idev = fz_new_draw_device(app->ctx, app->image);
fz_run_display_list(app->page_list, idev, ctm, bbox, NULL);
@@ -329,8 +330,8 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
if (app->shrinkwrap)
{
- int w = app->image->w;
- int h = app->image->h;
+ int w = fz_pixmap_width(app->ctx, app->image);
+ int h = fz_pixmap_height(app->ctx, app->image);
if (app->winw == w)
app->panx = 0;
if (app->winh == h)
@@ -371,23 +372,61 @@ static void pdfapp_gotopage(pdfapp_t *app, int number)
pdfapp_showpage(app, 1, 1, 1);
}
-static inline fz_bbox bboxcharat(fz_text_span *span, int idx)
+static fz_text_char textcharat(fz_text_page *page, int idx)
{
+ static fz_text_char emptychar = { {0,0,0,0}, ' ' };
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
int ofs = 0;
- while (span)
+ for (block = page->blocks; block < page->blocks + page->len; block++)
+ {
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ for (span = line->spans; span < line->spans + line->len; span++)
+ {
+ if (idx < ofs + span->len)
+ return span->text[idx - ofs];
+ /* pseudo-newline */
+ if (span + 1 == line->spans + line->len)
+ {
+ if (idx == ofs + span->len)
+ return emptychar;
+ ofs++;
+ }
+ ofs += span->len;
+ }
+ }
+ }
+ return emptychar;
+}
+
+static int textlen(fz_text_page *page)
+{
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
+ int len = 0;
+ for (block = page->blocks; block < page->blocks + page->len; block++)
{
- if (idx < ofs + span->len)
- return span->text[idx - ofs].bbox;
- if (span->eol)
+ for (line = block->lines; line < block->lines + block->len; line++)
{
- if (idx == ofs + span->len)
- return fz_empty_bbox;
- ofs ++;
+ for (span = line->spans; span < line->spans + line->len; span++)
+ len += span->len;
+ len++; /* pseudo-newline */
}
- ofs += span->len;
- span = span->next;
}
- return fz_empty_bbox;
+ return len;
+}
+
+static inline int charat(fz_text_page *page, int idx)
+{
+ return textcharat(page, idx).c;
+}
+
+static inline fz_bbox bboxcharat(fz_text_page *page, int idx)
+{
+ return fz_round_rect(textcharat(page, idx).bbox);
}
void pdfapp_inverthit(pdfapp_t *app)
@@ -421,52 +460,20 @@ void pdfapp_inverthit(pdfapp_t *app)
pdfapp_invert(app, fz_transform_bbox(ctm, hitbox));
}
-static inline int charat(fz_text_span *span, int idx)
-{
- int ofs = 0;
- while (span)
- {
- if (idx < ofs + span->len)
- return span->text[idx - ofs].c;
- if (span->eol)
- {
- if (idx == ofs + span->len)
- return ' ';
- ofs ++;
- }
- ofs += span->len;
- span = span->next;
- }
- return 0;
-}
-
-static int textlen(fz_text_span *span)
-{
- int len = 0;
- while (span)
- {
- len += span->len;
- if (span->eol)
- len ++;
- span = span->next;
- }
- return len;
-}
-
-static int match(char *s, fz_text_span *span, int n)
+static int match(char *s, fz_text_page *page, int n)
{
int orig = n;
int c;
while ((c = *s++))
{
- if (c == ' ' && charat(span, n) == ' ')
+ if (c == ' ' && charat(page, n) == ' ')
{
- while (charat(span, n) == ' ')
+ while (charat(page, n) == ' ')
n++;
}
else
{
- if (tolower(c) != tolower(charat(span, n)))
+ if (tolower(c) != tolower(charat(page, n)))
return 0;
n++;
}
@@ -721,22 +728,22 @@ void pdfapp_onkey(pdfapp_t *app, int c)
break;
case 'h':
- app->panx += app->image->w / 10;
+ app->panx += fz_pixmap_width(app->ctx, app->image) / 10;
pdfapp_showpage(app, 0, 0, 1);
break;
case 'j':
- app->pany -= app->image->h / 10;
+ app->pany -= fz_pixmap_height(app->ctx, app->image) / 10;
pdfapp_showpage(app, 0, 0, 1);
break;
case 'k':
- app->pany += app->image->h / 10;
+ app->pany += fz_pixmap_height(app->ctx, app->image) / 10;
pdfapp_showpage(app, 0, 0, 1);
break;
case 'l':
- app->panx -= app->image->w / 10;
+ app->panx -= fz_pixmap_width(app->ctx, app->image) / 10;
pdfapp_showpage(app, 0, 0, 1);
break;
@@ -911,12 +918,13 @@ void pdfapp_onkey(pdfapp_t *app, int c)
void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state)
{
+ fz_bbox rect = fz_pixmap_bbox(app->ctx, app->image);
fz_link *link;
fz_matrix ctm;
fz_point p;
- p.x = x - app->panx + app->image->x;
- p.y = y - app->pany + app->image->y;
+ p.x = x - app->panx + rect.x0;
+ p.y = y - app->pany + rect.y0;
ctm = pdfapp_viewctm(app);
ctm = fz_invert_matrix(ctm);
@@ -1000,10 +1008,10 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
if (app->iscopying)
{
app->iscopying = 0;
- app->selr.x0 = MIN(app->selx, x) - app->panx + app->image->x;
- app->selr.x1 = MAX(app->selx, x) - app->panx + app->image->x;
- app->selr.y0 = MIN(app->sely, y) - app->pany + app->image->y;
- app->selr.y1 = MAX(app->sely, y) - app->pany + app->image->y;
+ app->selr.x0 = MIN(app->selx, x) - app->panx + rect.x0;
+ app->selr.x1 = MAX(app->selx, x) - app->panx + rect.x0;
+ app->selr.y0 = MIN(app->sely, y) - app->pany + rect.y0;
+ app->selr.y1 = MAX(app->sely, y) - app->pany + rect.y0;
winrepaint(app);
if (app->selr.x0 < app->selr.x1 && app->selr.y0 < app->selr.y1)
windocopy(app);
@@ -1018,7 +1026,7 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
int newy = app->pany + y - app->sely;
/* Scrolling beyond limits implies flipping pages */
/* Are we requested to scroll beyond limits? */
- if (newy + app->image->h < app->winh || newy > 0)
+ if (newy + fz_pixmap_height(app->ctx, app->image) < app->winh || newy > 0)
{
/* Yes. We can assume that deltay != 0 */
int deltay = y - app->sely;
@@ -1040,7 +1048,7 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
{
app->pageno--;
pdfapp_showpage(app, 1, 1, 1);
- newy = -app->image->h;
+ newy = -fz_pixmap_height(app->ctx, app->image);
}
app->beyondy = 0;
}
@@ -1071,10 +1079,10 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
else if (app->iscopying)
{
- app->selr.x0 = MIN(app->selx, x) - app->panx + app->image->x;
- app->selr.x1 = MAX(app->selx, x) - app->panx + app->image->x;
- app->selr.y0 = MIN(app->sely, y) - app->pany + app->image->y;
- app->selr.y1 = MAX(app->sely, y) - app->pany + app->image->y;
+ app->selr.x0 = MIN(app->selx, x) - app->panx + rect.x0;
+ app->selr.x1 = MAX(app->selx, x) - app->panx + rect.x0;
+ app->selr.y0 = MIN(app->sely, y) - app->pany + rect.y0;
+ app->selr.y1 = MAX(app->sely, y) - app->pany + rect.y0;
winrepaint(app);
}
@@ -1084,6 +1092,9 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
{
fz_bbox hitbox;
fz_matrix ctm;
+ fz_text_page *page = app->page_text;
+ fz_text_block *block;
+ fz_text_line *line;
fz_text_span *span;
int c, i, p;
int seen;
@@ -1096,32 +1107,40 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
ctm = pdfapp_viewctm(app);
p = 0;
- for (span = app->page_text; span; span = span->next)
- {
- seen = 0;
- for (i = 0; i < span->len; i++)
+ for (block = page->blocks; block < page->blocks + page->len; block++)
+ {
+ for (line = block->lines; line < block->lines + block->len; line++)
{
- hitbox = fz_transform_bbox(ctm, span->text[i].bbox);
- c = span->text[i].c;
- if (c < 32)
- c = '?';
- if (hitbox.x1 >= x0 && hitbox.x0 <= x1 && hitbox.y1 >= y0 && hitbox.y0 <= y1)
+ for (span = line->spans; span < line->spans + line->len; span++)
{
- if (p < ucslen - 1)
- ucsbuf[p++] = c;
- seen = 1;
- }
- }
+ seen = 0;
- if (seen && span->eol)
- {
+ for (i = 0; i < span->len; i++)
+ {
+ hitbox = fz_round_rect(span->text[i].bbox);
+ hitbox = fz_transform_bbox(ctm, hitbox);
+ c = span->text[i].c;
+ if (c < 32)
+ c = '?';
+ if (hitbox.x1 >= x0 && hitbox.x0 <= x1 && hitbox.y1 >= y0 && hitbox.y0 <= y1)
+ {
+ if (p < ucslen - 1)
+ ucsbuf[p++] = c;
+ seen = 1;
+ }
+ }
+
+ if (seen && span + 1 == line->spans + line->len)
+ {
#ifdef _WIN32
- if (p < ucslen - 1)
- ucsbuf[p++] = '\r';
+ if (p < ucslen - 1)
+ ucsbuf[p++] = '\r';
#endif
- if (p < ucslen - 1)
- ucsbuf[p++] = '\n';
+ if (p < ucslen - 1)
+ ucsbuf[p++] = '\n';
+ }
+ }
}
}
diff --git a/apps/pdfapp.h b/apps/pdfapp.h
index bb067bb4..db83335f 100644
--- a/apps/pdfapp.h
+++ b/apps/pdfapp.h
@@ -1,3 +1,8 @@
+#ifndef PDFAPP_H
+#define PDFAPP_H
+
+#include "fitz.h"
+
/*
* Utility object for handling a pdf application / view
* Takes care of PDF loading and displaying and navigation,
@@ -47,7 +52,8 @@ struct pdfapp_s
fz_page *page;
fz_rect page_bbox;
fz_display_list *page_list;
- fz_text_span *page_text;
+ fz_text_page *page_text;
+ fz_text_sheet *page_sheet;
fz_link *page_links;
/* snapback history */
@@ -106,3 +112,5 @@ void pdfapp_onresize(pdfapp_t *app, int w, int h);
void pdfapp_invert(pdfapp_t *app, fz_bbox rect);
void pdfapp_inverthit(pdfapp_t *app);
+
+#endif
diff --git a/apps/win_main.c b/apps/win_main.c
index c87faa97..37864e19 100644
--- a/apps/win_main.c
+++ b/apps/win_main.c
@@ -317,7 +317,7 @@ void wintitle(pdfapp_t *app, char *title)
sp = title;
while (*sp && dp < wide + 255)
{
- sp += chartorune(&rune, sp);
+ sp += fz_chartorune(&rune, sp);
*dp++ = rune;
}
*dp = 0;
@@ -355,10 +355,14 @@ void winblitsearch()
void winblit()
{
+ int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
+ int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
+ int image_n = fz_pixmap_components(context, gapp.image);
+ unsigned char *samples = fz_pixmap_samples(context, gapp.image);
int x0 = gapp.panx;
int y0 = gapp.pany;
- int x1 = gapp.panx + gapp.image->w;
- int y1 = gapp.pany + gapp.image->h;
+ int x1 = gapp.panx + image_w;
+ int y1 = gapp.pany + image_h;
RECT r;
if (gapp.image)
@@ -371,15 +375,15 @@ void winblit()
pdfapp_inverthit(&gapp);
- dibinf->bmiHeader.biWidth = gapp.image->w;
- dibinf->bmiHeader.biHeight = -gapp.image->h;
- dibinf->bmiHeader.biSizeImage = gapp.image->h * 4;
+ dibinf->bmiHeader.biWidth = image_w;
+ dibinf->bmiHeader.biHeight = -image_h;
+ dibinf->bmiHeader.biSizeImage = image_h * 4;
- if (gapp.image->n == 2)
+ if (image_n == 2)
{
- int i = gapp.image->w * gapp.image->h;
+ int i = image_w * image_h;
unsigned char *color = malloc(i*4);
- unsigned char *s = gapp.image->samples;
+ unsigned char *s = samples;
unsigned char *d = color;
for (; i > 0 ; i--)
{
@@ -388,16 +392,16 @@ void winblit()
d += 4;
}
SetDIBitsToDevice(hdc,
- gapp.panx, gapp.pany, gapp.image->w, gapp.image->h,
- 0, 0, 0, gapp.image->h, color,
+ gapp.panx, gapp.pany, image_w, image_h,
+ 0, 0, 0, image_h, color,
dibinf, DIB_RGB_COLORS);
free(color);
}
- if (gapp.image->n == 4)
+ if (image_n == 4)
{
SetDIBitsToDevice(hdc,
- gapp.panx, gapp.pany, gapp.image->w, gapp.image->h,
- 0, 0, 0, gapp.image->h, gapp.image->samples,
+ gapp.panx, gapp.pany, image_w, image_h,
+ 0, 0, 0, image_h, samples,
dibinf, DIB_RGB_COLORS);
}
diff --git a/apps/x11_image.c b/apps/x11_image.c
index 35b32c7e..06764313 100644
--- a/apps/x11_image.c
+++ b/apps/x11_image.c
@@ -22,6 +22,12 @@
extern int ffs(int);
+static int is_big_endian(void)
+{
+ static const int one = 1;
+ return *(char*)&one == 0;
+}
+
typedef void (*ximage_convert_func_t)
(
const unsigned char *src,
@@ -212,7 +218,7 @@ select_mode(void)
unsigned long rs, gs, bs;
byteorder = ImageByteOrder(info.display);
- if (fz_is_big_endian())
+ if (is_big_endian())
byterev = byteorder != MSBFirst;
else
byterev = byteorder != LSBFirst;
diff --git a/apps/x11_main.c b/apps/x11_main.c
index 281618ef..447ebeb2 100644
--- a/apps/x11_main.c
+++ b/apps/x11_main.c
@@ -1,7 +1,3 @@
-#include "fitz.h"
-#include "mupdf.h"
-#include "muxps.h"
-#include "mucbz.h"
#include "pdfapp.h"
#include <X11/Xlib.h>
@@ -253,6 +249,8 @@ void winhelp(pdfapp_t *app)
void winresize(pdfapp_t *app, int w, int h)
{
+ int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
+ int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
XWindowChanges values;
int mask, width, height;
@@ -287,7 +285,7 @@ void winresize(pdfapp_t *app, int w, int h)
}
XSetForeground(xdpy, xgc, WhitePixel(xdpy, xscr));
- XFillRectangle(xdpy, xwin, xgc, 0, 0, gapp.image->w, gapp.image->h);
+ XFillRectangle(xdpy, xwin, xgc, 0, 0, image_w, image_h);
XFlush(xdpy);
if (width != reqw || height != reqh)
@@ -338,10 +336,14 @@ static void winblitsearch(pdfapp_t *app)
static void winblit(pdfapp_t *app)
{
+ int image_w = fz_pixmap_width(gapp.ctx, gapp.image);
+ int image_h = fz_pixmap_height(gapp.ctx, gapp.image);
+ int image_n = fz_pixmap_components(gapp.ctx, gapp.image);
+ unsigned char *image_samples = fz_pixmap_samples(gapp.ctx, gapp.image);
int x0 = gapp.panx;
int y0 = gapp.pany;
- int x1 = gapp.panx + gapp.image->w;
- int y1 = gapp.pany + gapp.image->h;
+ int x1 = gapp.panx + image_w;
+ int y1 = gapp.pany + image_h;
XSetForeground(xdpy, xgc, xbgcolor.pixel);
fillrect(0, 0, x0, gapp.winh);
@@ -350,8 +352,8 @@ static void winblit(pdfapp_t *app)
fillrect(0, y1, gapp.winw, gapp.winh - y1);
XSetForeground(xdpy, xgc, xshcolor.pixel);
- fillrect(x0+2, y1, gapp.image->w, 2);
- fillrect(x1, y0+2, 2, gapp.image->h);
+ fillrect(x0+2, y1, image_w, 2);
+ fillrect(x1, y0+2, 2, image_h);
if (gapp.iscopying || justcopied)
{
@@ -361,21 +363,21 @@ static void winblit(pdfapp_t *app)
pdfapp_inverthit(&gapp);
- if (gapp.image->n == 4)
+ if (image_n == 4)
ximage_blit(xwin, xgc,
x0, y0,
- gapp.image->samples,
+ image_samples,
0, 0,
- gapp.image->w,
- gapp.image->h,
- gapp.image->w * gapp.image->n);
- else if (gapp.image->n == 2)
+ image_w,
+ image_h,
+ image_w * image_n);
+ else if (image_n == 2)
{
- int i = gapp.image->w*gapp.image->h;
+ int i = image_w*image_h;
unsigned char *color = malloc(i*4);
if (color)
{
- unsigned char *s = gapp.image->samples;
+ unsigned char *s = image_samples;
unsigned char *d = color;
for (; i > 0 ; i--)
{
@@ -387,9 +389,9 @@ static void winblit(pdfapp_t *app)
x0, y0,
color,
0, 0,
- gapp.image->w,
- gapp.image->h,
- gapp.image->w * 4);
+ image_w,
+ image_h,
+ image_w * 4);
free(color);
}
}
@@ -462,7 +464,7 @@ void windocopy(pdfapp_t *app)
{
ucs = ucs2[0];
- utf8 += runetochar(utf8, &ucs);
+ utf8 += fz_runetochar(utf8, ucs);
if (ucs < 256)
*latin1++ = ucs;
diff --git a/cbz/mucbz.c b/cbz/mucbz.c
index 83c463bd..08f21bb6 100644
--- a/cbz/mucbz.c
+++ b/cbz/mucbz.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#include "mucbz.h"
#include <zlib.h>
@@ -19,9 +19,18 @@ static const char *cbz_ext_list[] = {
NULL
};
+typedef struct cbz_image_s cbz_image;
+
+struct cbz_image_s
+{
+ fz_image base;
+ int xres, yres;
+ fz_pixmap *pix;
+};
+
struct cbz_page_s
{
- fz_pixmap *image;
+ cbz_image *image;
};
typedef struct cbz_entry_s cbz_entry;
@@ -343,12 +352,34 @@ cbz_count_pages(cbz_document *doc)
return doc->page_count;
}
+static void
+cbz_free_image(fz_context *ctx, fz_storable *image_)
+{
+ cbz_image *image = (cbz_image *)image_;
+
+ if (image == NULL)
+ return;
+ fz_drop_pixmap(ctx, image->pix);
+ fz_free(ctx, image);
+}
+
+static fz_pixmap *
+cbz_image_to_pixmap(fz_context *ctx, fz_image *image_, int x, int w)
+{
+ cbz_image *image = (cbz_image *)image_;
+
+ return fz_keep_pixmap(ctx, image->pix);
+}
+
+
cbz_page *
cbz_load_page(cbz_document *doc, int number)
{
fz_context *ctx = doc->ctx;
unsigned char *data = NULL;
cbz_page *page = NULL;
+ cbz_image *image = NULL;
+ fz_pixmap *pixmap = NULL;
int size;
if (number < 0 || number >= doc->page_count)
@@ -358,19 +389,31 @@ cbz_load_page(cbz_document *doc, int number)
fz_var(data);
fz_var(page);
+ fz_var(image);
+ fz_var(pixmap);
fz_try(ctx)
{
- page = fz_malloc_struct(doc->ctx, cbz_page);
+ page = fz_malloc_struct(ctx, cbz_page);
page->image = NULL;
data = cbz_read_zip_entry(doc, doc->entry[number].offset, &size);
if (data[0] == 0xff && data[1] == 0xd8)
- page->image = fz_load_jpeg(ctx, data, size);
+ pixmap = fz_load_jpeg(ctx, data, size);
else if (memcmp(data, "\211PNG\r\n\032\n", 8) == 0)
- page->image = fz_load_png(ctx, data, size);
+ pixmap = fz_load_png(ctx, data, size);
else
fz_throw(ctx, "unknown image format");
+
+ image = fz_malloc_struct(ctx, cbz_image);
+ FZ_INIT_STORABLE(&image->base, 1, cbz_free_image);
+ image->base.w = pixmap->w;
+ image->base.h = pixmap->h;
+ image->base.get_pixmap = cbz_image_to_pixmap;
+ image->xres = pixmap->xres;
+ image->yres = pixmap->yres;
+ image->pix = pixmap;
+ page->image = image;
}
fz_always(ctx)
{
@@ -378,9 +421,7 @@ cbz_load_page(cbz_document *doc, int number)
}
fz_catch(ctx)
{
- if (page && page->image)
- fz_drop_pixmap(ctx, page->image);
- fz_free(ctx, page);
+ cbz_free_page(doc, page);
fz_rethrow(ctx);
}
@@ -390,29 +431,31 @@ cbz_load_page(cbz_document *doc, int number)
void
cbz_free_page(cbz_document *doc, cbz_page *page)
{
- fz_drop_pixmap(doc->ctx, page->image);
+ if (!page)
+ return;
+ fz_drop_image(doc->ctx, &page->image->base);
fz_free(doc->ctx, page);
}
fz_rect
cbz_bound_page(cbz_document *doc, cbz_page *page)
{
- fz_pixmap *image = page->image;
+ cbz_image *image = page->image;
fz_rect bbox;
bbox.x0 = bbox.y0 = 0;
- bbox.x1 = image->w * DPI / image->xres;
- bbox.y1 = image->h * DPI / image->yres;
+ bbox.x1 = image->base.w * DPI / image->xres;
+ bbox.y1 = image->base.h * DPI / image->yres;
return bbox;
}
void
cbz_run_page(cbz_document *doc, cbz_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie)
{
- fz_pixmap *image = page->image;
- float w = image->w * DPI / image->xres;
- float h = image->h * DPI / image->yres;
+ cbz_image *image = page->image;
+ float w = image->base.w * DPI / image->xres;
+ float h = image->base.h * DPI / image->yres;
ctm = fz_concat(fz_scale(w, h), ctm);
- fz_fill_image(dev, image, ctm, 1);
+ fz_fill_image(dev, &image->base, ctm, 1);
}
/* Document interface wrappers */
diff --git a/cbz/mucbz.h b/cbz/mucbz.h
index e18a7474..080423bf 100644
--- a/cbz/mucbz.h
+++ b/cbz/mucbz.h
@@ -1,15 +1,45 @@
-#ifndef _MUCBZ_H_
-#define _MUCBZ_H_
+#ifndef MUCBZ_H
+#define MUCBZ_H
-#ifndef _FITZ_H_
-#error "fitz.h must be included before mucbz.h"
-#endif
+#include "fitz.h"
typedef struct cbz_document_s cbz_document;
typedef struct cbz_page_s cbz_page;
+/*
+ cbz_open_document: Open a document.
+
+ Open a document for reading so the library is able to locate
+ objects and pages inside the file.
+
+ The returned cbz_document should be used when calling most
+ other functions. Note that it wraps the context, so those
+ functions implicitly get access to the global state in
+ context.
+
+ filename: a path to a file as it would be given to open(2).
+*/
cbz_document *cbz_open_document(fz_context *ctx, char *filename);
+
+/*
+ cbz_open_document_with_stream: Opens a document.
+
+ Same as cbz_open_document, but takes a stream instead of a
+ filename to locate the document to open. Increments the
+ reference count of the stream. See fz_open_file,
+ fz_open_file_w or fz_open_fd for opening a stream, and
+ fz_close for closing an open stream.
+*/
cbz_document *cbz_open_document_with_stream(fz_stream *file);
+
+/*
+ cbz_close_document: Closes and frees an opened document.
+
+ The resource store in the context associated with cbz_document
+ is emptied.
+
+ Does not throw exceptions.
+*/
void cbz_close_document(cbz_document *doc);
int cbz_count_pages(cbz_document *doc);
diff --git a/doc/example.c b/doc/example.c
new file mode 100644
index 00000000..31bf68b8
--- /dev/null
+++ b/doc/example.c
@@ -0,0 +1,100 @@
+// Rendering a page of a PDF document to a PNG image in less than 100 lines.
+
+// Compile a debug build of mupdf, then compile and run this example:
+//
+// gcc -o build/debug/example -I fitz doc/example.c \
+// build/debug/libfitz.a build/debug/libfreetype.a -lpng -ljpeg \
+// -ljbig2dec -lopenjpeg -lm
+//
+// build/debug/example /path/to/document.pdf 1 200 25
+
+// Include MuPDF header files. The order is important!
+
+#include <fitz.h>
+
+void
+render(char *filename, int pagenumber, int zoom, int rotation)
+{
+ // Create a context to hold the exception stack and various caches.
+
+ fz_context *ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
+
+ // Open the PDF, XPS or CBZ document.
+
+ fz_document *doc = fz_open_document(ctx, filename);
+
+ // Retrieve the number of pages (not used in this example).
+
+ int pagecount = fz_count_pages(doc);
+
+ // Load the page we want. Page numbering starts from zero.
+
+ fz_page *page = fz_load_page(doc, pagenumber - 1);
+
+ // Calculate a transform to use when rendering. This transform
+ // contains the scale and rotation. Convert zoom percentage to a
+ // scaling factor. Without scaling the resolution is 72 dpi.
+
+ fz_matrix transform = fz_scale(zoom / 100.0f, zoom / 100.0f);
+ transform = fz_concat(transform, fz_rotate(rotation));
+
+ // Take the page bounds and transform them by the same matrix that
+ // we will use to render the page.
+
+ fz_rect rect = fz_bound_page(doc, page);
+ rect = fz_transform_rect(transform, rect);
+ fz_bbox bbox = fz_round_rect(rect);
+
+ // Create a blank pixmap to hold the result of rendering. The
+ // pixmap bounds used here are the same as the transformed page
+ // bounds, so it will contain the entire page. The page coordinate
+ // space has the origin at the top left corner and the x axis
+ // extends to the right and the y axis extends down.
+
+ fz_pixmap *pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox);
+ fz_clear_pixmap_with_value(ctx, pix, 0xff);
+
+ // A page consists of a series of objects (text, line art, images,
+ // gradients). These objects are passed to a device when the
+ // interpreter runs the page. There are several devices, used for
+ // different purposes:
+ //
+ // draw device -- renders objects to a target pixmap.
+ //
+ // text device -- extracts the text in reading order with styling
+ // information. This text can be used to provide text search.
+ //
+ // list device -- records the graphic objects in a list that can
+ // be played back through another device. This is useful if you
+ // need to run the same page through multiple devices, without
+ // the overhead of parsing the page each time.
+
+ // Create a draw device with the pixmap as its target.
+ // Run the page with the transform.
+
+ fz_device *dev = fz_new_draw_device(ctx, pix);
+ fz_run_page(doc, page, dev, transform, NULL);
+ fz_free_device(dev);
+
+ // Save the pixmap to a file.
+
+ fz_write_png(ctx, pix, "out.png", 0);
+
+ // Clean up.
+
+ fz_drop_pixmap(ctx, pix);
+ fz_free_page(doc, page);
+ fz_close_document(doc);
+ fz_free_context(ctx);
+}
+
+int main(int argc, char **argv)
+{
+ char *filename = argv[1];
+ int pagenumber = argc > 2 ? atoi(argv[2]) : 1;
+ int zoom = argc > 3 ? atoi(argv[3]) : 100;
+ int rotation = argc > 4 ? atoi(argv[4]) : 0;
+
+ render(filename, pagenumber, zoom, rotation);
+ return 0;
+}
diff --git a/doc/overview.txt b/doc/overview.txt
new file mode 100644
index 00000000..25cd0d4b
--- /dev/null
+++ b/doc/overview.txt
@@ -0,0 +1,212 @@
+Contents
+========
+
+* Basic MuPDF usage example
+* Common function arguments
+* Error Handling
+* Multi-threading
+
+Basic MuPDF usage example
+=========================
+
+For an example of how to use MuPDF in the most basic way, see
+doc/example.c. To limit the complexity and give an easier introduction
+this code has no error handling at all, but any serious piece of code
+using MuPDF should use the error handling strategies described below.
+
+Common function arguments
+=========================
+
+Many functions in MuPDFs interface take a context argument.
+
+A context contains global state used by MuPDF inside functions when
+parsing or rendering pages of the document. It contains for example:
+
+ an exception stack (see error handling below),
+
+ a memory allocator (allowing for custom allocators)
+
+ a resource store (for caching of images, fonts, etc.)
+
+ a set of locks and (un-)locking functions (for multi-threading)
+
+Other functions in MuPDF's interface take arguments such as document,
+stream and device which contain state for each type of object. Those
+arguments each have a reference to a context and therefore act as
+proxies for a context.
+
+Without the set of locks and accompanying functions the context and
+its proxies may only be used in a single-threaded application.
+
+Error handling
+==============
+
+MuPDF uses a set of exception handling macros to simplify error return
+and cleanup. Conceptually, they work a lot like C++'s try/catch
+system, but do not require any special compiler support.
+
+The basic formulation is as follows:
+
+ fz_try(ctx)
+ {
+ // Try to perform a task. Never 'return', 'goto' or
+ // 'longjmp' out of here. 'break' may be used to
+ // safely exit (just) the try block scope.
+ }
+ fz_always(ctx)
+ {
+ // Any code here is always executed, regardless of
+ // whether an exception was thrown within the try or
+ // not. Never 'return', 'goto' or longjmp out from
+ // here. 'break' may be used to safely exit (just) the
+ // always block scope.
+ }
+ fz_catch(ctx)
+ {
+ // This code is called (after any always block) only
+ // if something within the fz_try block (including any
+ // functions it called) threw an exception. The code
+ // here is expected to handle the exception (maybe
+ // record/report the error, cleanup any stray state
+ // etc) and can then either exit the block, or pass on
+ // the exception to a higher level (enclosing) fz_try
+ // block (using fz_throw, or fz_rethrow).
+ }
+
+The fz_always block is optional, and can safely be omitted.
+
+The macro based nature of this system has 3 main limitations:
+
+1) Never return from within try (or 'goto' or longjmp out of it).
+ This upsets the internal housekeeping of the macros and will
+ cause problems later on. The code will detect such things
+ happening, but by then it is too late to give a helpful error
+ report as to where the original infraction occurred.
+
+2) The fz_try(ctx) { ... } fz_always(ctx) { ... } fz_catch(ctx) { ... }
+ is not one atomic C statement. That is to say, if you do:
+
+ if (condition)
+ fz_try(ctx) { ... }
+ fz_catch(ctx) { ... }
+
+ then you will not get what you want. Use the following instead:
+
+ if (condition) {
+ fz_try(ctx) { ... }
+ fz_catch(ctx) { ... }
+ }
+
+3) The macros are implemented using setjmp and longjmp, and so
+ the standard C restrictions on the use of those functions
+ apply to fz_try/fz_catch too. In particular, any "truly local"
+ variable that is set between the start of fz_try and something
+ in fz_try throwing an exception may become undefined as part
+ of the process of throwing that exception.
+
+ As a way of mitigating this problem, we provide an fz_var()
+ macro that tells the compiler to ensure that that variable is
+ not unset by the act of throwing the exception.
+
+A model piece of code using these macros then might be:
+
+ house build_house(plans *p)
+ {
+ material m = NULL;
+ walls w = NULL;
+ roof r = NULL;
+ house h = NULL;
+ tiles t = make_tiles();
+
+ fz_var(w);
+ fz_var(r);
+ fz_var(h);
+
+ fz_try(ctx)
+ {
+ fz_try(ctx)
+ {
+ m = make_bricks();
+ }
+ fz_catch(ctx)
+ {
+ // No bricks available, make do with straw?
+ m = make_straw();
+ }
+ w = make_walls(m, p);
+ r = make_roof(m, t);
+ // Note, NOT: return combine(w,r);
+ h = combine(w, r);
+ }
+ fz_always(ctx)
+ {
+ drop_walls(w);
+ drop_roof(r);
+ drop_material(m);
+ drop_tiles(t);
+ }
+ fz_catch(ctx)
+ {
+ fz_throw(ctx, "build_house failed");
+ }
+ return h;
+ }
+
+Things to note about this:
+
+a) If make_tiles throws an exception, this will immediately be
+ handled by some higher level exception handler. If it
+ succeeds, t will be set before fz_try starts, so there is no
+ need to fz_var(t);
+
+b) We try first off to make some bricks as our building material.
+ If this fails, we fall back to straw. If this fails, we'll end
+ up in the fz_catch, and the process will fail neatly.
+
+c) We assume in this code that combine takes new reference to
+ both the walls and the roof it uses, and therefore that w and
+ r need to be cleaned up in all cases.
+
+d) We assume the standard C convention that it is safe to destroy
+ NULL things.
+
+Multi-threading
+===============
+
+First off, study the basic usage example in doc/example.c and make
+sure you understand how it works as it will be the referenced in this
+section too.
+
+There are two variations of how to create multi-threaded applications:
+
+1) lock-less operation -- in which one thread is requesting pages
+ to be drawn and responding to user interface actions, while
+ another thread is dedicated to drawing pages. In this scenario
+ only one thread owns and manipulates the context and document
+ at any one time.
+
+2) using locking -- where one thread is requesting pages to be
+ draw and responding to user interface actions, while several
+ threads may be drawing pages. In this scenario each thread has
+ its own context but they share some global state, for example
+ the resource store. An additional constraint
+
+The usage example starts by getting a context from fz_new_context with
+standard memory allocation functions, default resource store size and,
+crucially, no locking.
+
+In a multi-threaded application every thread must have a context. Or
+more specifically, each context can only be used from one thread at a
+time. When starting another thread, do NOT call fz_new_context again;
+instead call fz_clone_context. This creates a context sharing the
+memory allocator, resource store etc.
+
+
+
+
+så utan lås: en gui-tråd som visa progress, en tråd som renderar
+med lås: en gui-tråd som request:ar och flera trådar som renderar
+
+having fitz level display list objects created in
+one thread, consumed as read-only in multiple threads, with locked access
+around a few shared caches
diff --git a/draw/draw_affine.c b/draw/draw_affine.c
index dc15eaf5..67361faf 100644
--- a/draw/draw_affine.c
+++ b/draw/draw_affine.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
typedef unsigned char byte;
diff --git a/draw/draw_blend.c b/draw/draw_blend.c
index e60c09c5..7c74df79 100644
--- a/draw/draw_blend.c
+++ b/draw/draw_blend.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* PDF 1.4 blend modes. These are slow. */
@@ -24,7 +24,7 @@ static const char *fz_blendmode_names[] =
"Luminosity",
};
-int fz_find_blendmode(char *name)
+int fz_lookup_blendmode(char *name)
{
int i;
for (i = 0; i < nelem(fz_blendmode_names); i++)
@@ -589,8 +589,8 @@ fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int is
}
}
- bbox = fz_bound_pixmap(dst);
- bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(src));
+ bbox = fz_pixmap_bbox_no_ctx(dst);
+ bbox = fz_intersect_bbox(bbox, fz_pixmap_bbox_no_ctx(src));
x = bbox.x0;
y = bbox.y0;
diff --git a/draw/draw_device.c b/draw/draw_device.c
index 279ef64d..76f934bd 100644
--- a/draw/draw_device.c
+++ b/draw/draw_device.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define QUANT(x,a) (((int)((x) * (a))) / (a))
#define HSUBPIX 5.0
@@ -121,9 +121,9 @@ fz_knockout_begin(fz_draw_device *dev)
state = push_stack(dev);
- bbox = fz_bound_pixmap(state->dest);
+ bbox = fz_pixmap_bbox(dev->ctx, state->dest);
bbox = fz_intersect_bbox(bbox, state->scissor);
- dest = fz_new_pixmap_with_rect(dev->ctx, state->dest->colorspace, bbox);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox);
if (isolated)
{
@@ -154,7 +154,7 @@ fz_knockout_begin(fz_draw_device *dev)
}
else
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, shape);
}
#ifdef DUMP_GROUP_BLENDS
@@ -248,7 +248,7 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, fz_matrix ctm,
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(dev);
- fz_convert_color(dev->ctx, colorspace, color, model, colorfv);
+ fz_convert_color(dev->ctx, model, colorfv, colorspace, color);
for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
@@ -302,7 +302,7 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, fz_
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(dev);
- fz_convert_color(dev->ctx, colorspace, color, model, colorfv);
+ fz_convert_color(dev->ctx, model, colorfv, colorspace, color);
for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
@@ -354,13 +354,13 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect *rect, int even_odd, f
return;
}
- state[1].mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, state[1].mask);
- state[1].dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
fz_clear_pixmap(dev->ctx, state[1].dest);
if (state[1].shape)
{
- state[1].shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, state[1].shape);
}
@@ -399,13 +399,13 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect *rect, fz_strok
if (rect)
bbox = fz_intersect_bbox(bbox, fz_round_rect(*rect));
- state[1].mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, state[1].mask);
- state[1].dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
fz_clear_pixmap(dev->ctx, state[1].dest);
if (state->shape)
{
- state[1].shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, state[1].shape);
}
@@ -427,7 +427,7 @@ draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_pixmap *msk,
fz_bbox bbox;
int x, y, w, h;
- bbox = fz_bound_pixmap(msk);
+ bbox = fz_pixmap_bbox_no_ctx(msk);
bbox.x0 += xorig;
bbox.y0 += yorig;
bbox.x1 += xorig;
@@ -472,7 +472,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, fz_matrix ctm,
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(dev);
- fz_convert_color(dev->ctx, colorspace, color, model, colorfv);
+ fz_convert_color(dev->ctx, model, colorfv, colorspace, color);
for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
@@ -532,7 +532,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_
if (state->blendmode & FZ_BLEND_KNOCKOUT)
state = fz_knockout_begin(dev);
- fz_convert_color(dev->ctx, colorspace, color, model, colorfv);
+ fz_convert_color(dev->ctx, model, colorfv, colorspace, color);
for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = alpha * 255;
@@ -600,13 +600,13 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate)
if (accumulate == 0 || accumulate == 1)
{
- mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, mask);
- dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
fz_clear_pixmap(dev->ctx, dest);
if (state->shape)
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, shape);
}
else
@@ -673,13 +673,13 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
bbox = fz_round_rect(fz_bound_text(dev->ctx, text, ctm));
bbox = fz_intersect_bbox(bbox, state->scissor);
- mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, mask);
- dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
fz_clear_pixmap(dev->ctx, dest);
if (state->shape)
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, shape);
}
else
@@ -762,11 +762,11 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha)
if (alpha < 1)
{
- dest = fz_new_pixmap_with_rect(dev->ctx, state->dest->colorspace, bbox);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox);
fz_clear_pixmap(dev->ctx, dest);
if (shape)
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, shape);
}
}
@@ -775,7 +775,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha)
{
unsigned char *s;
int x, y, n, i;
- fz_convert_color(dev->ctx, shade->colorspace, shade->background, model, colorfv);
+ fz_convert_color(dev->ctx, model, colorfv, shade->colorspace, shade->background);
for (i = 0; i < model->n; i++)
colorbv[i] = colorfv[i] * 255;
colorbv[i] = 255;
@@ -878,17 +878,19 @@ fz_transform_pixmap(fz_context *ctx, fz_pixmap *image, fz_matrix *ctm, int x, in
}
static void
-fz_draw_fill_image(fz_device *devp, fz_pixmap *image, fz_matrix ctm, float alpha)
+fz_draw_fill_image(fz_device *devp, fz_image *image, fz_matrix ctm, float alpha)
{
fz_draw_device *dev = devp->user;
fz_pixmap *converted = NULL;
fz_pixmap *scaled = NULL;
+ fz_pixmap *pixmap;
+ fz_pixmap *orig_pixmap;
int after;
int dx, dy;
fz_context *ctx = dev->ctx;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- fz_bbox clip = fz_bound_pixmap(state->dest);
+ fz_bbox clip = fz_pixmap_bbox(ctx, state->dest);
clip = fz_intersect_bbox(clip, state->scissor);
@@ -903,133 +905,153 @@ fz_draw_fill_image(fz_device *devp, fz_pixmap *image, fz_matrix ctm, float alpha
if (image->w == 0 || image->h == 0)
return;
+ dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
+ dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
+
+ pixmap = fz_image_to_pixmap(ctx, image, dx, dy);
+ orig_pixmap = pixmap;
+
/* convert images with more components (cmyk->rgb) before scaling */
/* convert images with fewer components (gray->rgb after scaling */
/* convert images with expensive colorspace transforms after scaling */
- if (state->blendmode & FZ_BLEND_KNOCKOUT)
- state = fz_knockout_begin(dev);
+ fz_try(ctx)
+ {
+ if (state->blendmode & FZ_BLEND_KNOCKOUT)
+ state = fz_knockout_begin(dev);
- after = 0;
- if (image->colorspace == fz_device_gray)
- after = 1;
+ after = 0;
+ if (pixmap->colorspace == fz_device_gray)
+ after = 1;
- if (image->colorspace != model && !after)
- {
- converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(image));
- fz_convert_pixmap(ctx, image, converted);
- image = converted;
- }
+ if (pixmap->colorspace != model && !after)
+ {
+ converted = fz_new_pixmap_with_bbox(ctx, model, fz_pixmap_bbox(ctx, pixmap));
+ fz_convert_pixmap(ctx, converted, pixmap);
+ pixmap = converted;
+ }
- fz_try(ctx)
- {
- dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
- dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w && dy < image->h)
+ if (dx < pixmap->w && dy < pixmap->h)
{
int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
- scaled = fz_transform_pixmap(ctx, image, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip);
+ scaled = fz_transform_pixmap(ctx, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip);
if (!scaled)
{
if (dx < 1)
dx = 1;
if (dy < 1)
dy = 1;
- scaled = fz_scale_pixmap(ctx, image, image->x, image->y, dx, dy, NULL);
+ scaled = fz_scale_pixmap(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL);
}
if (scaled)
- image = scaled;
+ pixmap = scaled;
}
- if (image->colorspace != model)
+ if (pixmap->colorspace != model)
{
- if ((image->colorspace == fz_device_gray && model == fz_device_rgb) ||
- (image->colorspace == fz_device_gray && model == fz_device_bgr))
+ if ((pixmap->colorspace == fz_device_gray && model == fz_device_rgb) ||
+ (pixmap->colorspace == fz_device_gray && model == fz_device_bgr))
{
/* We have special case rendering code for gray -> rgb/bgr */
}
else
{
- converted = fz_new_pixmap_with_rect(ctx, model, fz_bound_pixmap(image));
- fz_convert_pixmap(ctx, image, converted);
- image = converted;
+ converted = fz_new_pixmap_with_bbox(ctx, model, fz_pixmap_bbox(ctx, pixmap));
+ fz_convert_pixmap(ctx, converted, pixmap);
+ pixmap = converted;
}
}
- fz_paint_image(state->dest, state->scissor, state->shape, image, ctm, alpha * 255);
+ fz_paint_image(state->dest, state->scissor, state->shape, pixmap, ctm, alpha * 255);
+
+ if (state->blendmode & FZ_BLEND_KNOCKOUT)
+ fz_knockout_end(dev);
}
- fz_catch(ctx)
+ fz_always(ctx)
{
fz_drop_pixmap(ctx, scaled);
fz_drop_pixmap(ctx, converted);
+ fz_drop_pixmap(ctx, orig_pixmap);
+ }
+ fz_catch(ctx)
+ {
fz_rethrow(ctx);
}
-
- if (scaled)
- fz_drop_pixmap(ctx, scaled);
- if (converted)
- fz_drop_pixmap(ctx, converted);
-
- if (state->blendmode & FZ_BLEND_KNOCKOUT)
- fz_knockout_end(dev);
}
static void
-fz_draw_fill_image_mask(fz_device *devp, fz_pixmap *image, fz_matrix ctm,
+fz_draw_fill_image_mask(fz_device *devp, fz_image *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_draw_device *dev = devp->user;
unsigned char colorbv[FZ_MAX_COLORS + 1];
float colorfv[FZ_MAX_COLORS];
fz_pixmap *scaled = NULL;
+ fz_pixmap *pixmap;
+ fz_pixmap *orig_pixmap;
int dx, dy;
int i;
+ fz_context *ctx = dev->ctx;
fz_draw_state *state = &dev->stack[dev->top];
fz_colorspace *model = state->dest->colorspace;
- fz_bbox clip = fz_bound_pixmap(state->dest);
+ fz_bbox clip = fz_pixmap_bbox(ctx, state->dest);
clip = fz_intersect_bbox(clip, state->scissor);
if (image->w == 0 || image->h == 0)
return;
- if (state->blendmode & FZ_BLEND_KNOCKOUT)
- state = fz_knockout_begin(dev);
-
dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w && dy < image->h)
+ pixmap = fz_image_to_pixmap(ctx, image, dx, dy);
+ orig_pixmap = pixmap;
+
+ fz_try(ctx)
{
- int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
- scaled = fz_transform_pixmap(dev->ctx, image, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip);
- if (!scaled)
+ if (state->blendmode & FZ_BLEND_KNOCKOUT)
+ state = fz_knockout_begin(dev);
+
+ if (dx < pixmap->w && dy < pixmap->h)
{
- if (dx < 1)
- dx = 1;
- if (dy < 1)
- dy = 1;
- scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy, NULL);
+ int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
+ scaled = fz_transform_pixmap(dev->ctx, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip);
+ if (!scaled)
+ {
+ if (dx < 1)
+ dx = 1;
+ if (dy < 1)
+ dy = 1;
+ scaled = fz_scale_pixmap(dev->ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL);
+ }
+ if (scaled)
+ pixmap = scaled;
}
- if (scaled)
- image = scaled;
- }
- fz_convert_color(dev->ctx, colorspace, color, model, colorfv);
- for (i = 0; i < model->n; i++)
- colorbv[i] = colorfv[i] * 255;
- colorbv[i] = alpha * 255;
+ fz_convert_color(dev->ctx, model, colorfv, colorspace, color);
+ for (i = 0; i < model->n; i++)
+ colorbv[i] = colorfv[i] * 255;
+ colorbv[i] = alpha * 255;
- fz_paint_image_with_color(state->dest, state->scissor, state->shape, image, ctm, colorbv);
+ fz_paint_image_with_color(state->dest, state->scissor, state->shape, pixmap, ctm, colorbv);
- if (scaled)
- fz_drop_pixmap(dev->ctx, scaled);
+ if (scaled)
+ fz_drop_pixmap(dev->ctx, scaled);
- if (state->blendmode & FZ_BLEND_KNOCKOUT)
- fz_knockout_end(dev);
+ if (state->blendmode & FZ_BLEND_KNOCKOUT)
+ fz_knockout_end(dev);
+ }
+ fz_always(ctx)
+ {
+ fz_drop_pixmap(dev->ctx, orig_pixmap);
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
}
static void
-fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
+fz_draw_clip_image_mask(fz_device *devp, fz_image *image, fz_rect *rect, fz_matrix ctm)
{
fz_draw_device *dev = devp->user;
fz_context *ctx = dev->ctx;
@@ -1038,10 +1060,12 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat
fz_pixmap *dest = NULL;
fz_pixmap *shape = NULL;
fz_pixmap *scaled = NULL;
+ fz_pixmap *pixmap;
+ fz_pixmap *orig_pixmap;
int dx, dy;
fz_draw_state *state = push_stack(dev);
fz_colorspace *model = state->dest->colorspace;
- fz_bbox clip = fz_bound_pixmap(state->dest);
+ fz_bbox clip = fz_pixmap_bbox(ctx, state->dest);
clip = fz_intersect_bbox(clip, state->scissor);
@@ -1068,35 +1092,46 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat
if (rect)
bbox = fz_intersect_bbox(bbox, fz_round_rect(*rect));
- mask = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
- fz_clear_pixmap(dev->ctx, mask);
+ dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
+ dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
+ pixmap = fz_image_to_pixmap(ctx, image, dx, dy);
+ orig_pixmap = pixmap;
+
fz_try(ctx)
{
- dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
+ fz_clear_pixmap(dev->ctx, mask);
+
+ dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
fz_clear_pixmap(dev->ctx, dest);
if (state->shape)
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, shape);
}
- dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
- dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
- if (dx < image->w && dy < image->h)
+ if (dx < pixmap->w && dy < pixmap->h)
{
int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3);
- scaled = fz_transform_pixmap(dev->ctx, image, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip);
+ scaled = fz_transform_pixmap(dev->ctx, pixmap, &ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip);
if (!scaled)
{
if (dx < 1)
dx = 1;
if (dy < 1)
dy = 1;
- scaled = fz_scale_pixmap(dev->ctx, image, image->x, image->y, dx, dy, NULL);
+ scaled = fz_scale_pixmap(dev->ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL);
}
if (scaled)
- image = scaled;
+ pixmap = scaled;
}
+ fz_paint_image(mask, bbox, state->shape, pixmap, ctm, 255);
+
+ }
+ fz_always(ctx)
+ {
+ fz_drop_pixmap(ctx, scaled);
+ fz_drop_pixmap(ctx, orig_pixmap);
}
fz_catch(ctx)
{
@@ -1106,11 +1141,6 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat
fz_rethrow(ctx);
}
- fz_paint_image(mask, bbox, state->shape, image, ctm, 255);
-
- if (scaled)
- fz_drop_pixmap(dev->ctx, scaled);
-
state[1].blendmode |= FZ_BLEND_ISOLATED;
state[1].scissor = bbox;
state[1].dest = dest;
@@ -1181,12 +1211,12 @@ fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace
bbox = fz_round_rect(rect);
bbox = fz_intersect_bbox(bbox, state->scissor);
- dest = fz_new_pixmap_with_rect(dev->ctx, fz_device_gray, bbox);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, fz_device_gray, bbox);
if (state->shape)
{
/* FIXME: If we ever want to support AIS true, then we
* probably want to create a shape pixmap here, using:
- * shape = fz_new_pixmap_with_rect(NULL, bbox);
+ * shape = fz_new_pixmap_with_bbox(NULL, bbox);
* then, in the end_mask code, we create the mask from this
* rather than dest.
*/
@@ -1198,7 +1228,7 @@ fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace
float bc;
if (!colorspace)
colorspace = fz_device_gray;
- fz_convert_color(dev->ctx, colorspace, colorfv, fz_device_gray, &bc);
+ fz_convert_color(dev->ctx, fz_device_gray, &bc, colorspace, colorfv);
fz_clear_pixmap_with_value(dev->ctx, dest, bc * 255);
if (shape)
fz_clear_pixmap_with_value(dev->ctx, shape, 255);
@@ -1254,8 +1284,8 @@ fz_draw_end_mask(fz_device *devp)
state[1].mask = NULL;
/* create new dest scratch buffer */
- bbox = fz_bound_pixmap(temp);
- dest = fz_new_pixmap_with_rect(dev->ctx, state->dest->colorspace, bbox);
+ bbox = fz_pixmap_bbox(ctx, temp);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox);
fz_clear_pixmap(dev->ctx, dest);
/* push soft mask as clip mask */
@@ -1266,7 +1296,7 @@ fz_draw_end_mask(fz_device *devp)
* clip mask when we pop. So create a new shape now. */
if (state[0].shape)
{
- state[1].shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, state[1].shape);
}
state[1].scissor = bbox;
@@ -1288,7 +1318,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
state = push_stack(dev);
bbox = fz_round_rect(rect);
bbox = fz_intersect_bbox(bbox, state->scissor);
- dest = fz_new_pixmap_with_rect(ctx, model, bbox);
+ dest = fz_new_pixmap_with_bbox(ctx, model, bbox);
#ifndef ATTEMPT_KNOCKOUT_AND_ISOLATED
knockout = 0;
@@ -1314,7 +1344,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
{
fz_try(ctx)
{
- shape = fz_new_pixmap_with_rect(ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(ctx, NULL, bbox);
fz_clear_pixmap(dev->ctx, shape);
}
fz_catch(ctx)
@@ -1421,7 +1451,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo
* assert(bbox.x0 > state->dest->x || bbox.x1 < state->dest->x + state->dest->w ||
* bbox.y0 > state->dest->y || bbox.y1 < state->dest->y + state->dest->h);
*/
- dest = fz_new_pixmap_with_rect(dev->ctx, model, bbox);
+ dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
fz_clear_pixmap(ctx, dest);
shape = state[0].shape;
if (shape)
@@ -1429,7 +1459,7 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo
fz_var(shape);
fz_try(ctx)
{
- shape = fz_new_pixmap_with_rect(dev->ctx, NULL, bbox);
+ shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
fz_clear_pixmap(ctx, shape);
}
fz_catch(ctx)
@@ -1552,9 +1582,6 @@ fz_draw_free_user(fz_device *devp)
state--;
}
while(--dev->top > 0);
- fz_drop_pixmap(ctx, dev->stack[0].mask);
- fz_drop_pixmap(ctx, dev->stack[0].dest);
- fz_drop_pixmap(ctx, dev->stack[0].shape);
}
if (dev->stack != &dev->init_stack[0])
fz_free(ctx, dev->stack);
diff --git a/draw/draw_edge.c b/draw/draw_edge.c
index adb460ac..12ba72fc 100644
--- a/draw/draw_edge.c
+++ b/draw/draw_edge.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define BBOX_MIN -(1<<20)
#define BBOX_MAX (1<<20)
@@ -20,7 +20,7 @@ struct fz_aa_context_s
int hscale;
int vscale;
int scale;
- int level;
+ int bits;
};
void fz_new_aa_context(fz_context *ctx)
@@ -30,17 +30,23 @@ void fz_new_aa_context(fz_context *ctx)
ctx->aa->hscale = 17;
ctx->aa->vscale = 15;
ctx->aa->scale = 256;
- ctx->aa->level = 8;
+ ctx->aa->bits = 8;
#define fz_aa_hscale ((ctxaa)->hscale)
#define fz_aa_vscale ((ctxaa)->vscale)
#define fz_aa_scale ((ctxaa)->scale)
-#define fz_aa_level ((ctxaa)->level)
+#define fz_aa_bits ((ctxaa)->bits)
#define AA_SCALE(x) ((x * fz_aa_scale) >> 8)
#endif
}
+void fz_copy_aa_context(fz_context *dst, fz_context *src)
+{
+ if (dst && dst->aa && src && src->aa)
+ memcpy(dst->aa, src->aa, sizeof(*src->aa));
+}
+
void fz_free_aa_context(fz_context *ctx)
{
#ifndef AA_BITS
@@ -55,40 +61,40 @@ void fz_free_aa_context(fz_context *ctx)
#define AA_SCALE(x) (x)
#define fz_aa_hscale 17
#define fz_aa_vscale 15
-#define fz_aa_level 8
+#define fz_aa_bits 8
#elif AA_BITS > 4
#define AA_SCALE(x) ((x * 255) >> 6)
#define fz_aa_hscale 8
#define fz_aa_vscale 8
-#define fz_aa_level 6
+#define fz_aa_bits 6
#elif AA_BITS > 2
#define AA_SCALE(x) (x * 17)
#define fz_aa_hscale 5
#define fz_aa_vscale 3
-#define fz_aa_level 4
+#define fz_aa_bits 4
#elif AA_BITS > 0
#define AA_SCALE(x) ((x * 255) >> 2)
#define fz_aa_hscale 2
#define fz_aa_vscale 2
-#define fz_aa_level 2
+#define fz_aa_bits 2
#else
#define AA_SCALE(x) (x * 255)
#define fz_aa_hscale 1
#define fz_aa_vscale 1
-#define fz_aa_level 0
+#define fz_aa_bits 0
#endif
#endif
int
-fz_get_aa_level(fz_context *ctx)
+fz_aa_level(fz_context *ctx)
{
fz_aa_context *ctxaa = ctx->aa;
- return fz_aa_level;
+ return fz_aa_bits;
}
void
@@ -96,37 +102,37 @@ fz_set_aa_level(fz_context *ctx, int level)
{
fz_aa_context *ctxaa = ctx->aa;
#ifdef AA_BITS
- fz_warn(ctx, "anti-aliasing was compiled with a fixed precision of %d bits", fz_aa_level);
+ fz_warn(ctx, "anti-aliasing was compiled with a fixed precision of %d bits", fz_aa_bits);
#else
if (level > 6)
{
fz_aa_hscale = 17;
fz_aa_vscale = 15;
- fz_aa_level = 8;
+ fz_aa_bits = 8;
}
else if (level > 4)
{
fz_aa_hscale = 8;
fz_aa_vscale = 8;
- fz_aa_level = 6;
+ fz_aa_bits = 6;
}
else if (level > 2)
{
fz_aa_hscale = 5;
fz_aa_vscale = 3;
- fz_aa_level = 4;
+ fz_aa_bits = 4;
}
else if (level > 0)
{
fz_aa_hscale = 2;
fz_aa_vscale = 2;
- fz_aa_level = 2;
+ fz_aa_bits = 2;
}
else
{
fz_aa_hscale = 1;
fz_aa_vscale = 1;
- fz_aa_level = 0;
+ fz_aa_bits = 0;
}
fz_aa_scale = 0xFF00 / (fz_aa_hscale * fz_aa_vscale);
#endif
@@ -792,7 +798,7 @@ fz_scan_convert(fz_gel *gel, int eofill, fz_bbox clip,
{
fz_aa_context *ctxaa = gel->ctx->aa;
- if (fz_aa_level > 0)
+ if (fz_aa_bits > 0)
fz_scan_convert_aa(gel, eofill, clip, dst, color);
else
fz_scan_convert_sharp(gel, eofill, clip, dst, color);
diff --git a/draw/draw_glyph.c b/draw/draw_glyph.c
index 68ae3b80..cef9d7fa 100644
--- a/draw/draw_glyph.c
+++ b/draw/draw_glyph.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define MAX_FONT_SIZE 1000
#define MAX_GLYPH_SIZE 256
@@ -20,6 +20,7 @@ struct fz_glyph_key_s
int c, d;
unsigned short gid;
unsigned char e, f;
+ int aa;
};
void
@@ -30,7 +31,7 @@ fz_new_glyph_cache_context(fz_context *ctx)
cache = fz_malloc_struct(ctx, fz_glyph_cache);
fz_try(ctx)
{
- cache->hash = fz_new_hash_table(ctx, 509, sizeof(fz_glyph_key));
+ cache->hash = fz_new_hash_table(ctx, 509, sizeof(fz_glyph_key), FZ_LOCK_GLYPHCACHE);
}
fz_catch(ctx)
{
@@ -128,6 +129,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color
key.d = ctm.d * 65536;
key.e = (ctm.e - floorf(ctm.e)) * 256;
key.f = (ctm.f - floorf(ctm.f)) * 256;
+ key.aa = fz_aa_level(ctx);
fz_lock(ctx, FZ_LOCK_GLYPHCACHE);
val = fz_hash_find(ctx, cache->hash, &key);
@@ -145,7 +147,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix ctm, fz_color
{
if (font->ft_face)
{
- val = fz_render_ft_glyph(ctx, font, gid, ctm);
+ val = fz_render_ft_glyph(ctx, font, gid, ctm, key.aa);
}
else if (font->t3procs)
{
diff --git a/draw/draw_mesh.c b/draw/draw_mesh.c
index 79bac732..7579ad60 100644
--- a/draw/draw_mesh.c
+++ b/draw/draw_mesh.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/*
* polygon clipping
@@ -509,7 +509,7 @@ fz_paint_mesh(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest,
tri[k][2] = *mesh++ * 255;
else
{
- fz_convert_color(ctx, shade->colorspace, mesh, dest->colorspace, tri[k] + 2);
+ fz_convert_color(ctx, dest->colorspace, tri[k] + 2, shade->colorspace, mesh);
for (i = 0; i < dest->colorspace->n; i++)
tri[k][i + 2] *= 255;
mesh += shade->colorspace->n;
@@ -539,13 +539,13 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest,
{
for (i = 0; i < 256; i++)
{
- fz_convert_color(ctx, shade->colorspace, shade->function[i], dest->colorspace, color);
+ fz_convert_color(ctx, dest->colorspace, color, shade->colorspace, shade->function[i]);
for (k = 0; k < dest->colorspace->n; k++)
clut[i][k] = color[k] * 255;
clut[i][k] = shade->function[i][shade->colorspace->n] * 255;
}
- conv = fz_new_pixmap_with_rect(ctx, dest->colorspace, bbox);
- temp = fz_new_pixmap_with_rect(ctx, fz_device_gray, bbox);
+ conv = fz_new_pixmap_with_bbox(ctx, dest->colorspace, bbox);
+ temp = fz_new_pixmap_with_bbox(ctx, fz_device_gray, bbox);
fz_clear_pixmap(ctx, temp);
}
else
diff --git a/draw/draw_paint.c b/draw/draw_paint.c
index 3b02b870..2a5f9607 100644
--- a/draw/draw_paint.c
+++ b/draw/draw_paint.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/*
@@ -382,8 +382,8 @@ fz_paint_pixmap_with_rect(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_bbox bbo
assert(dst->n == src->n);
- bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(dst));
- bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(src));
+ bbox = fz_intersect_bbox(bbox, fz_pixmap_bbox_no_ctx(dst));
+ bbox = fz_intersect_bbox(bbox, fz_pixmap_bbox_no_ctx(src));
x = bbox.x0;
y = bbox.y0;
@@ -413,8 +413,8 @@ fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha)
assert(dst->n == src->n);
- bbox = fz_bound_pixmap(dst);
- bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(src));
+ bbox = fz_pixmap_bbox_no_ctx(dst);
+ bbox = fz_intersect_bbox(bbox, fz_pixmap_bbox_no_ctx(src));
x = bbox.x0;
y = bbox.y0;
@@ -445,9 +445,9 @@ fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk)
assert(dst->n == src->n);
assert(msk->n == 1);
- bbox = fz_bound_pixmap(dst);
- bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(src));
- bbox = fz_intersect_bbox(bbox, fz_bound_pixmap(msk));
+ bbox = fz_pixmap_bbox_no_ctx(dst);
+ bbox = fz_intersect_bbox(bbox, fz_pixmap_bbox_no_ctx(src));
+ bbox = fz_intersect_bbox(bbox, fz_pixmap_bbox_no_ctx(msk));
x = bbox.x0;
y = bbox.y0;
diff --git a/draw/draw_path.c b/draw/draw_path.c
index eca7dc08..2ef8cf3a 100644
--- a/draw/draw_path.c
+++ b/draw/draw_path.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define MAX_DEPTH 8
diff --git a/draw/draw_scale.c b/draw/draw_scale.c
index 489a2eb9..aceec939 100644
--- a/draw/draw_scale.c
+++ b/draw/draw_scale.c
@@ -6,7 +6,7 @@ given by taking the source pixmap src, scaling it to width w, and height h,
and then positioning it at (frac(x),frac(y)).
*/
-#include "fitz.h"
+#include "fitz-internal.h"
/* Do we special case handling of single pixel high/wide images? The
* 'purest' handling is given by not special casing them, but certain
@@ -349,16 +349,8 @@ add_weight(fz_weights *weights, int j, int i, fz_scale_filter *filter,
weight = (int)(256*f+0.5f);
/* Ensure i is in range */
- if (i < 0)
- {
- i = 0;
+ if (i < 0 || i >= src_w)
return;
- }
- else if (i >= src_w)
- {
- i = src_w-1;
- return;
- }
if (weight == 0)
{
/* We add a fudge factor here to allow for extreme downscales
diff --git a/draw/draw_simple_scale.c b/draw/draw_simple_scale.c
index 6d0ad481..8143b6fd 100644
--- a/draw/draw_simple_scale.c
+++ b/draw/draw_simple_scale.c
@@ -10,7 +10,7 @@ that return values strictly in the 0..1 range, and uses bytes for
intermediate results rather than ints.
*/
-#include "fitz.h"
+#include "fitz-internal.h"
/* Do we special case handling of single pixel high/wide images? The
* 'purest' handling is given by not special casing them, but certain
diff --git a/draw/draw_unpack.c b/draw/draw_unpack.c
index 6da5e8a3..f988dcf9 100644
--- a/draw/draw_unpack.c
+++ b/draw/draw_unpack.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* Unpack image samples and optionally pad pixels with opaque alpha */
diff --git a/fitz/base_context.c b/fitz/base_context.c
index fe69ff8e..075a3d02 100644
--- a/fitz/base_context.c
+++ b/fitz/base_context.c
@@ -1,12 +1,4 @@
-#include "fitz.h"
-
-static fz_obj *
-fz_resolve_indirect_null(fz_obj *ref)
-{
- return ref;
-}
-
-fz_obj *(*fz_resolve_indirect)(fz_obj*) = fz_resolve_indirect_null;
+#include "fitz-internal.h"
void
fz_free_context(fz_context *ctx)
@@ -130,7 +122,9 @@ fz_clone_context_internal(fz_context *ctx)
if (ctx == NULL || ctx->alloc == NULL)
return NULL;
new_ctx = new_context_phase1(ctx->alloc, ctx->locks);
- new_ctx->store = fz_store_keep(ctx);
+ /* Inherit AA defaults from old context. */
+ fz_copy_aa_context(new_ctx, ctx);
+ new_ctx->store = fz_keep_store_context(ctx);
new_ctx->glyph_cache = fz_keep_glyph_cache(ctx);
new_ctx->font = fz_keep_font_context(ctx);
return new_ctx;
diff --git a/fitz/base_error.c b/fitz/base_error.c
index 6b54fb69..71a32a2e 100644
--- a/fitz/base_error.c
+++ b/fitz/base_error.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* Warning context */
@@ -46,7 +46,7 @@ void fz_warn(fz_context *ctx, char *fmt, ...)
static void throw(fz_error_context *ex)
{
if (ex->top >= 0) {
- longjmp(ex->stack[ex->top].buffer, 1);
+ fz_longjmp(ex->stack[ex->top].buffer, 1);
} else {
fprintf(stderr, "uncaught exception: %s\n", ex->message);
LOGE("uncaught exception: %s\n", ex->message);
diff --git a/fitz/base_geometry.c b/fitz/base_geometry.c
index fc5ce517..84134179 100644
--- a/fitz/base_geometry.c
+++ b/fitz/base_geometry.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define MAX4(a,b,c,d) MAX(MAX(a,b), MAX(c,d))
#define MIN4(a,b,c,d) MIN(MIN(a,b), MIN(c,d))
diff --git a/fitz/base_hash.c b/fitz/base_hash.c
index 630f6b6a..4ba02f4d 100644
--- a/fitz/base_hash.c
+++ b/fitz/base_hash.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/*
Simple hashtable with open addressing linear probe.
@@ -22,6 +22,7 @@ struct fz_hash_table_s
int keylen;
int size;
int load;
+ int lock; /* -1 or the lock used to protect this hash table */
fz_hash_entry *ents;
};
@@ -42,7 +43,7 @@ static unsigned hash(unsigned char *s, int len)
}
fz_hash_table *
-fz_new_hash_table(fz_context *ctx, int initialsize, int keylen)
+fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock)
{
fz_hash_table *table;
@@ -52,6 +53,7 @@ fz_new_hash_table(fz_context *ctx, int initialsize, int keylen)
table->keylen = keylen;
table->size = initialsize;
table->load = 0;
+ table->lock = lock;
fz_try(ctx)
{
table->ents = fz_malloc_array(ctx, table->size, sizeof(fz_hash_entry));
@@ -98,10 +100,45 @@ fz_free_hash(fz_context *ctx, fz_hash_table *table)
fz_free(ctx, table);
}
+static void *
+do_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val)
+{
+ fz_hash_entry *ents;
+ unsigned size;
+ unsigned pos;
+
+ ents = table->ents;
+ size = table->size;
+ pos = hash(key, table->keylen) % size;
+
+ if (table->lock >= 0)
+ fz_assert_lock_held(ctx, table->lock);
+
+ while (1)
+ {
+ if (!ents[pos].val)
+ {
+ memcpy(ents[pos].key, key, table->keylen);
+ ents[pos].val = val;
+ table->load ++;
+ return NULL;
+ }
+
+ if (memcmp(key, ents[pos].key, table->keylen) == 0)
+ {
+ fz_warn(ctx, "assert: overwrite hash slot");
+ return ents[pos].val;
+ }
+
+ pos = (pos + 1) % size;
+ }
+}
+
static void
fz_resize_hash(fz_context *ctx, fz_hash_table *table, int newsize)
{
fz_hash_entry *oldents = table->ents;
+ fz_hash_entry *newents = table->ents;
int oldsize = table->size;
int oldload = table->load;
int i;
@@ -112,7 +149,22 @@ fz_resize_hash(fz_context *ctx, fz_hash_table *table, int newsize)
return;
}
- table->ents = fz_malloc_array(ctx, newsize, sizeof(fz_hash_entry));
+ if (table->lock == FZ_LOCK_ALLOC)
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
+ newents = fz_malloc_array(ctx, newsize, sizeof(fz_hash_entry));
+ if (table->lock == FZ_LOCK_ALLOC)
+ fz_lock(ctx, FZ_LOCK_ALLOC);
+ if (table->lock >= 0)
+ {
+ if (table->size >= newsize)
+ {
+ /* Someone else fixed it before we could lock! */
+ fz_unlock(ctx, table->lock);
+ fz_free(ctx, newents);
+ return;
+ }
+ }
+ table->ents = newents;
memset(table->ents, 0, sizeof(fz_hash_entry) * newsize);
table->size = newsize;
table->load = 0;
@@ -121,11 +173,15 @@ fz_resize_hash(fz_context *ctx, fz_hash_table *table, int newsize)
{
if (oldents[i].val)
{
- fz_hash_insert(ctx, table, oldents[i].key, oldents[i].val);
+ do_hash_insert(ctx, table, oldents[i].key, oldents[i].val);
}
}
+ if (table->lock == FZ_LOCK_ALLOC)
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
fz_free(ctx, oldents);
+ if (table->lock == FZ_LOCK_ALLOC)
+ fz_lock(ctx, FZ_LOCK_ALLOC);
}
void *
@@ -135,6 +191,9 @@ fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key)
unsigned size = table->size;
unsigned pos = hash(key, table->keylen) % size;
+ if (table->lock >= 0)
+ fz_assert_lock_held(ctx, table->lock);
+
while (1)
{
if (!ents[pos].val)
@@ -150,37 +209,12 @@ fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key)
void *
fz_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val)
{
- fz_hash_entry *ents;
- unsigned size;
- unsigned pos;
-
if (table->load > table->size * 8 / 10)
{
fz_resize_hash(ctx, table, table->size * 2);
}
- ents = table->ents;
- size = table->size;
- pos = hash(key, table->keylen) % size;
-
- while (1)
- {
- if (!ents[pos].val)
- {
- memcpy(ents[pos].key, key, table->keylen);
- ents[pos].val = val;
- table->load ++;
- return NULL;
- }
-
- if (memcmp(key, ents[pos].key, table->keylen) == 0)
- {
- fz_warn(ctx, "assert: overwrite hash slot");
- return ents[pos].val;
- }
-
- pos = (pos + 1) % size;
- }
+ return do_hash_insert(ctx, table, key, val);
}
void
@@ -191,11 +225,14 @@ fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key)
unsigned pos = hash(key, table->keylen) % size;
unsigned hole, look, code;
+ if (table->lock >= 0)
+ fz_assert_lock_held(ctx, table->lock);
+
while (1)
{
if (!ents[pos].val)
{
- fz_warn(ctx, "assert: remove inexistent hash entry");
+ fz_warn(ctx, "assert: remove non-existent hash entry");
return;
}
@@ -231,22 +268,22 @@ fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key)
}
void
-fz_debug_hash(fz_context *ctx, fz_hash_table *table)
+fz_print_hash(fz_context *ctx, FILE *out, fz_hash_table *table)
{
int i, k;
- printf("cache load %d / %d\n", table->load, table->size);
+ fprintf(out, "cache load %d / %d\n", table->load, table->size);
for (i = 0; i < table->size; i++)
{
if (!table->ents[i].val)
- printf("table % 4d: empty\n", i);
+ fprintf(out, "table % 4d: empty\n", i);
else
{
- printf("table % 4d: key=", i);
+ fprintf(out, "table % 4d: key=", i);
for (k = 0; k < MAX_KEY_LEN; k++)
- printf("%02x", ((char*)table->ents[i].key)[k]);
- printf(" val=$%p\n", table->ents[i].val);
+ fprintf(out, "%02x", ((char*)table->ents[i].key)[k]);
+ fprintf(out, " val=$%p\n", table->ents[i].val);
}
}
}
diff --git a/fitz/base_memory.c b/fitz/base_memory.c
index c9ec2628..32c7ff84 100644
--- a/fitz/base_memory.c
+++ b/fitz/base_memory.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
static void *
do_scavenging_malloc(fz_context *ctx, unsigned int size)
diff --git a/fitz/base_string.c b/fitz/base_string.c
index dd9f8ea2..8ed08911 100644
--- a/fitz/base_string.c
+++ b/fitz/base_string.c
@@ -1,11 +1,4 @@
-#include "fitz.h"
-
-int
-fz_is_big_endian(void)
-{
- static const int one = 1;
- return *(char*)&one == 0;
-}
+#include "fitz-internal.h"
char *
fz_strsep(char **stringp, const char *delim)
@@ -36,8 +29,8 @@ fz_strlcpy(char *dst, const char *src, int siz)
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
- while (*s++)
- ;
+ while (*s++)
+ ;
}
return(s - src - 1); /* count does not include NUL */
@@ -108,7 +101,7 @@ enum
};
int
-chartorune(int *rune, char *str)
+fz_chartorune(int *rune, char *str)
{
int c, c1, c2, c3;
long l;
@@ -183,16 +176,15 @@ bad:
}
int
-runetochar(char *str, int *rune)
+fz_runetochar(char *str, int rune)
{
/* Runes are signed, so convert to unsigned for range check. */
- unsigned long c;
+ unsigned long c = (unsigned long)rune;
/*
* one character sequence
* 00000-0007F => 00-7F
*/
- c = *rune;
if(c <= Rune1) {
str[0] = c;
return 1;
@@ -240,10 +232,10 @@ runetochar(char *str, int *rune)
}
int
-runelen(int c)
+fz_runelen(int c)
{
char str[10];
- return runetochar(str, &c);
+ return fz_runetochar(str, c);
}
float fz_atof(const char *s)
@@ -256,10 +248,11 @@ float fz_atof(const char *s)
* as we convert to a float. */
errno = 0;
d = strtod(s, NULL);
- if (errno == ERANGE || d > FLT_MAX || d < -FLT_MAX) {
+ if (errno == ERANGE || isnan(d)) {
/* Return 1.0, as it's a small known value that won't cause a
- * divide by 0. */
+ divide by 0. */
return 1.0;
}
+ d = CLAMP(d, -FLT_MAX, FLT_MAX);
return (float)d;
}
diff --git a/fitz/crypt_aes.c b/fitz/crypt_aes.c
index afdff0fe..4d8c4498 100644
--- a/fitz/crypt_aes.c
+++ b/fitz/crypt_aes.c
@@ -36,7 +36,7 @@
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
*/
-#include "fitz.h"
+#include "fitz-internal.h"
#define aes_context fz_aes
diff --git a/fitz/crypt_arc4.c b/fitz/crypt_arc4.c
index 272891ce..596bf652 100644
--- a/fitz/crypt_arc4.c
+++ b/fitz/crypt_arc4.c
@@ -21,7 +21,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "fitz.h"
+#include "fitz-internal.h"
void
fz_arc4_init(fz_arc4 *arc4, const unsigned char *key, unsigned keylen)
diff --git a/fitz/crypt_md5.c b/fitz/crypt_md5.c
index b6e06845..87c0909d 100644
--- a/fitz/crypt_md5.c
+++ b/fitz/crypt_md5.c
@@ -23,7 +23,7 @@ These notices must be retained in any copies of any part of this
documentation and/or software.
*/
-#include "fitz.h"
+#include "fitz-internal.h"
/* Constants for MD5Transform routine */
enum
diff --git a/fitz/crypt_sha2.c b/fitz/crypt_sha2.c
index f17146c6..64284cfa 100644
--- a/fitz/crypt_sha2.c
+++ b/fitz/crypt_sha2.c
@@ -7,7 +7,7 @@ This file has been put into the public domain.
You can do whatever you want with this file.
*/
-#include "fitz.h"
+#include "fitz-internal.h"
static inline int isbigendian(void)
{
diff --git a/fitz/dev_bbox.c b/fitz/dev_bbox.c
index 636ceb94..163780d0 100644
--- a/fitz/dev_bbox.c
+++ b/fitz/dev_bbox.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* TODO: add clip stack and use to intersect bboxes */
@@ -47,7 +47,7 @@ fz_bbox_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
}
static void
-fz_bbox_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
+fz_bbox_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
{
fz_bbox *result = dev->user;
fz_bbox bbox = fz_round_rect(fz_transform_rect(ctm, fz_unit_rect));
@@ -55,7 +55,7 @@ fz_bbox_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
}
static void
-fz_bbox_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
+fz_bbox_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_bbox_fill_image(dev, image, ctm, alpha);
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index adc691d0..d0dfabc5 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
typedef struct fz_display_node_s fz_display_node;
@@ -37,7 +37,7 @@ struct fz_display_node_s
fz_path *path;
fz_text *text;
fz_shade *shade;
- fz_pixmap *image;
+ fz_image *image;
int blendmode;
} item;
fz_stroke_state *stroke;
@@ -207,7 +207,7 @@ fz_free_display_node(fz_context *ctx, fz_display_node *node)
case FZ_CMD_FILL_IMAGE:
case FZ_CMD_FILL_IMAGE_MASK:
case FZ_CMD_CLIP_IMAGE_MASK:
- fz_drop_pixmap(ctx, node->item.image);
+ fz_drop_image(ctx, node->item.image);
break;
case FZ_CMD_POP_CLIP:
case FZ_CMD_BEGIN_MASK:
@@ -435,35 +435,35 @@ fz_list_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
}
static void
-fz_list_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
+fz_list_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(dev->ctx, FZ_CMD_FILL_IMAGE, ctm, NULL, NULL, alpha);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
- node->item.image = fz_keep_pixmap(dev->ctx, image);
+ node->item.image = fz_keep_image(dev->ctx, image);
fz_append_display_node(dev->user, node);
}
static void
-fz_list_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
+fz_list_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_display_node *node;
node = fz_new_display_node(dev->ctx, FZ_CMD_FILL_IMAGE_MASK, ctm, colorspace, color, alpha);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
- node->item.image = fz_keep_pixmap(dev->ctx, image);
+ node->item.image = fz_keep_image(dev->ctx, image);
fz_append_display_node(dev->user, node);
}
static void
-fz_list_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
+fz_list_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(dev->ctx, FZ_CMD_CLIP_IMAGE_MASK, ctm, NULL, NULL, 0);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
if (rect)
node->rect = fz_intersect_rect(node->rect, *rect);
- node->item.image = fz_keep_pixmap(dev->ctx, image);
+ node->item.image = fz_keep_image(dev->ctx, image);
fz_append_display_node(dev->user, node);
}
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index b4ba5cbe..886cebe1 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_device *
fz_new_device(fz_context *ctx, void *user)
@@ -103,14 +103,14 @@ fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
}
void
-fz_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
+fz_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
{
if (dev->fill_image)
dev->fill_image(dev, image, ctm, alpha);
}
void
-fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
+fz_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
if (dev->fill_image_mask)
@@ -118,7 +118,7 @@ fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
}
void
-fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
+fz_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm)
{
if (dev->clip_image_mask)
dev->clip_image_mask(dev, image, rect, ctm);
diff --git a/fitz/dev_text.c b/fitz/dev_text.c
index d38fab21..7a059e5a 100644
--- a/fitz/dev_text.c
+++ b/fitz/dev_text.c
@@ -1,7 +1,8 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define LINE_DIST 0.9f
#define SPACE_DIST 0.2f
+#define PARAGRAPH_DIST 0.5f
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -11,60 +12,211 @@ typedef struct fz_text_device_s fz_text_device;
struct fz_text_device_s
{
+ fz_text_sheet *sheet;
+ fz_text_page *page;
+ fz_text_line cur_line;
+ fz_text_span cur_span;
fz_point point;
- fz_text_span *head;
- fz_text_span *span;
};
-fz_text_span *
-fz_new_text_span(fz_context *ctx)
+fz_text_sheet *
+fz_new_text_sheet(fz_context *ctx)
{
- fz_text_span *span;
- span = fz_malloc_struct(ctx, fz_text_span);
- span->font = NULL;
- span->wmode = 0;
- span->size = 0;
- span->len = 0;
- span->cap = 0;
- span->text = NULL;
- span->next = NULL;
- span->eol = 0;
- return span;
+ fz_text_sheet *sheet = fz_malloc(ctx, sizeof *sheet);
+ sheet->maxid = 0;
+ sheet->style = NULL;
+ return sheet;
}
void
-fz_free_text_span(fz_context *ctx, fz_text_span *span)
+fz_free_text_sheet(fz_context *ctx, fz_text_sheet *sheet)
+{
+ fz_text_style *style = sheet->style;
+ while (style)
+ {
+ fz_text_style *next = style->next;
+ fz_drop_font(ctx, style->font);
+ fz_free(ctx, style);
+ style = next;
+ }
+}
+
+static fz_text_style *
+fz_lookup_text_style_imp(fz_context *ctx, fz_text_sheet *sheet,
+ float size, fz_font *font, int wmode, int script)
+{
+ fz_text_style *style;
+
+ for (style = sheet->style; style; style = style->next)
+ {
+ if (style->font == font &&
+ style->size == size &&
+ style->wmode == wmode &&
+ style->script == script) /* FIXME: others */
+ {
+ return style;
+ }
+ }
+
+ /* Better make a new one and add it to our list */
+ style = fz_malloc(ctx, sizeof *style);
+ style->id = sheet->maxid++;
+ style->font = fz_keep_font(ctx, font);
+ style->size = size;
+ style->wmode = wmode;
+ style->script = script;
+ style->next = sheet->style;
+ sheet->style = style;
+ return style;
+}
+
+static fz_text_style *
+fz_lookup_text_style(fz_context *ctx, fz_text_sheet *sheet, fz_text *text, fz_matrix *ctm,
+ fz_colorspace *colorspace, float *color, float alpha, fz_stroke_state *stroke)
{
- fz_text_span *next;
+ float size = 1.0f;
+ fz_font *font = text ? text->font : NULL;
+ int wmode = text ? text->wmode : 0;
+ if (ctm && text)
+ {
+ fz_matrix tm = text->trm;
+ fz_matrix trm;
+ tm.e = 0;
+ tm.f = 0;
+ trm = fz_concat(tm, *ctm);
+ size = fz_matrix_expansion(trm);
+ }
+ return fz_lookup_text_style_imp(ctx, sheet, size, font, wmode, 0);
+}
- while (span)
+fz_text_page *
+fz_new_text_page(fz_context *ctx, fz_rect mediabox)
+{
+ fz_text_page *page = fz_malloc(ctx, sizeof(*page));
+ page->mediabox = mediabox;
+ page->len = 0;
+ page->cap = 0;
+ page->blocks = NULL;
+ return page;
+}
+
+void
+fz_free_text_page(fz_context *ctx, fz_text_page *page)
+{
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
+ for (block = page->blocks; block < page->blocks + page->len; block++)
{
- if (span->font)
- fz_drop_font(ctx, span->font);
- next = span->next;
- fz_free(ctx, span->text);
- fz_free(ctx, span);
- span = next;
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ for (span = line->spans; span < line->spans + line->len; span++)
+ {
+ fz_free(ctx, span->text);
+ }
+ fz_free(ctx, line->spans);
+ }
+ fz_free(ctx, block->lines);
}
+ fz_free(ctx, page->blocks);
+ fz_free(ctx, page);
}
static void
-fz_add_text_char_imp(fz_context *ctx, fz_text_span *span, int c, fz_bbox bbox)
+append_char(fz_context *ctx, fz_text_span *span, int c, fz_rect bbox)
{
- if (span->len + 1 >= span->cap)
+ if (span->len == span->cap)
{
- span->cap = span->cap > 1 ? (span->cap * 3) / 2 : 80;
- span->text = fz_resize_array(ctx, span->text, span->cap, sizeof(fz_text_char));
+ span->cap = MAX(64, span->cap * 2);
+ span->text = fz_resize_array(ctx, span->text, span->cap, sizeof(*span->text));
}
+ span->bbox = fz_union_rect(span->bbox, bbox);
span->text[span->len].c = c;
span->text[span->len].bbox = bbox;
- span->len ++;
+ span->len++;
+}
+
+static void
+init_span(fz_context *ctx, fz_text_span *span, fz_text_style *style)
+{
+ span->style = style;
+ span->bbox = fz_empty_rect;
+ span->len = span->cap = 0;
+ span->text = NULL;
+}
+
+static void
+append_span(fz_context *ctx, fz_text_line *line, fz_text_span *span)
+{
+ if (line->len == line->cap)
+ {
+ line->cap = MAX(8, line->cap * 2);
+ line->spans = fz_resize_array(ctx, line->spans, line->cap, sizeof(*line->spans));
+ }
+ line->bbox = fz_union_rect(line->bbox, span->bbox);
+ line->spans[line->len++] = *span;
}
-static fz_bbox
-fz_split_bbox(fz_bbox bbox, int i, int n)
+static void
+init_line(fz_context *ctx, fz_text_line *line)
+{
+ line->bbox = fz_empty_rect;
+ line->len = line->cap = 0;
+ line->spans = NULL;
+}
+
+static void
+append_line(fz_context *ctx, fz_text_block *block, fz_text_line *line)
{
- float w = (float)(bbox.x1 - bbox.x0) / n;
+ if (block->len == block->cap)
+ {
+ block->cap = MAX(16, block->cap * 2);
+ block->lines = fz_resize_array(ctx, block->lines, block->cap, sizeof *block->lines);
+ }
+ block->bbox = fz_union_rect(block->bbox, line->bbox);
+ block->lines[block->len++] = *line;
+}
+
+static fz_text_block *
+lookup_block_for_line(fz_context *ctx, fz_text_page *page, fz_text_line *line)
+{
+ float size = line->len > 0 && line->spans[0].len > 0 ? line->spans[0].style->size : 1;
+ int i;
+
+ for (i = 0; i < page->len; i++)
+ {
+ fz_text_block *block = page->blocks + i;
+ int w = block->bbox.x1 - block->bbox.x0;
+ if (block->bbox.y0 - line->bbox.y1 < size * PARAGRAPH_DIST)
+ if (line->bbox.x0 < block->bbox.x1 && line->bbox.x1 > block->bbox.x0)
+ if (ABS(line->bbox.x0 - block->bbox.x0) < w / 4)
+ return block;
+ }
+
+ if (page->len == page->cap)
+ {
+ page->cap = MAX(16, page->cap * 2);
+ page->blocks = fz_resize_array(ctx, page->blocks, page->cap, sizeof(*page->blocks));
+ }
+
+ page->blocks[page->len].bbox = fz_empty_rect;
+ page->blocks[page->len].len = 0;
+ page->blocks[page->len].cap = 0;
+ page->blocks[page->len].lines = NULL;
+
+ return &page->blocks[page->len++];
+}
+
+static void
+insert_line(fz_context *ctx, fz_text_page *page, fz_text_line *line)
+{
+ append_line(ctx, lookup_block_for_line(ctx, page, line), line);
+}
+
+static fz_rect
+fz_split_bbox(fz_rect bbox, int i, int n)
+{
+ float w = (bbox.x1 - bbox.x0) / n;
float x0 = bbox.x0;
bbox.x0 = x0 + i * w;
bbox.x1 = x0 + (i + 1) * w;
@@ -72,154 +224,71 @@ fz_split_bbox(fz_bbox bbox, int i, int n)
}
static void
-fz_add_text_char(fz_context *ctx, fz_text_span **last, fz_font *font, float size, int wmode, int c, fz_bbox bbox)
+fz_flush_text_line(fz_context *ctx, fz_text_device *dev, fz_text_style *style)
{
- fz_text_span *span = *last;
-
- if (!span->font)
- {
- span->font = fz_keep_font(ctx, font);
- span->size = size;
- }
+ append_span(ctx, &dev->cur_line, &dev->cur_span);
+ insert_line(ctx, dev->page, &dev->cur_line);
+ init_span(ctx, &dev->cur_span, style);
+ init_line(ctx, &dev->cur_line);
+}
- if ((span->font != font || span->size != size || span->wmode != wmode) && c != 32)
+static void
+fz_add_text_char_imp(fz_context *ctx, fz_text_device *dev, fz_text_style *style, int c, fz_rect bbox)
+{
+ if (!dev->cur_span.style)
+ dev->cur_span.style = style;
+ if (style != dev->cur_span.style)
{
- span = fz_new_text_span(ctx);
- span->font = fz_keep_font(ctx, font);
- span->size = size;
- span->wmode = wmode;
- (*last)->next = span;
- *last = span;
+ append_span(ctx, &dev->cur_line, &dev->cur_span);
+ init_span(ctx, &dev->cur_span, style);
}
+ append_char(ctx, &dev->cur_span, c, bbox);
+}
+static void
+fz_add_text_char(fz_context *ctx, fz_text_device *dev, fz_text_style *style, int c, fz_rect bbox)
+{
switch (c)
{
case -1: /* ignore when one unicode character maps to multiple glyphs */
break;
case 0xFB00: /* ff */
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 0, 2));
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 1, 2));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 0, 2));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 1, 2));
break;
case 0xFB01: /* fi */
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 0, 2));
- fz_add_text_char_imp(ctx, span, 'i', fz_split_bbox(bbox, 1, 2));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 0, 2));
+ fz_add_text_char_imp(ctx, dev, style, 'i', fz_split_bbox(bbox, 1, 2));
break;
case 0xFB02: /* fl */
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 0, 2));
- fz_add_text_char_imp(ctx, span, 'l', fz_split_bbox(bbox, 1, 2));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 0, 2));
+ fz_add_text_char_imp(ctx, dev, style, 'l', fz_split_bbox(bbox, 1, 2));
break;
case 0xFB03: /* ffi */
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 0, 3));
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 1, 3));
- fz_add_text_char_imp(ctx, span, 'i', fz_split_bbox(bbox, 2, 3));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 0, 3));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 1, 3));
+ fz_add_text_char_imp(ctx, dev, style, 'i', fz_split_bbox(bbox, 2, 3));
break;
case 0xFB04: /* ffl */
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 0, 3));
- fz_add_text_char_imp(ctx, span, 'f', fz_split_bbox(bbox, 1, 3));
- fz_add_text_char_imp(ctx, span, 'l', fz_split_bbox(bbox, 2, 3));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 0, 3));
+ fz_add_text_char_imp(ctx, dev, style, 'f', fz_split_bbox(bbox, 1, 3));
+ fz_add_text_char_imp(ctx, dev, style, 'l', fz_split_bbox(bbox, 2, 3));
break;
case 0xFB05: /* long st */
case 0xFB06: /* st */
- fz_add_text_char_imp(ctx, span, 's', fz_split_bbox(bbox, 0, 2));
- fz_add_text_char_imp(ctx, span, 't', fz_split_bbox(bbox, 1, 2));
+ fz_add_text_char_imp(ctx, dev, style, 's', fz_split_bbox(bbox, 0, 2));
+ fz_add_text_char_imp(ctx, dev, style, 't', fz_split_bbox(bbox, 1, 2));
break;
default:
- fz_add_text_char_imp(ctx, span, c, bbox);
+ fz_add_text_char_imp(ctx, dev, style, c, bbox);
break;
}
}
static void
-fz_divide_text_chars(fz_text_span **last, int n, fz_bbox bbox)
-{
- fz_text_span *span = *last;
- int i, x;
- x = span->len - n;
- if (x >= 0)
- for (i = 0; i < n; i++)
- span->text[x + i].bbox = fz_split_bbox(bbox, i, n);
-}
-
-static void
-fz_add_text_newline(fz_context *ctx, fz_text_span **last, fz_font *font, float size, int wmode)
-{
- fz_text_span *span;
- span = fz_new_text_span(ctx);
- span->font = fz_keep_font(ctx, font);
- span->size = size;
- span->wmode = wmode;
- (*last)->eol = 1;
- (*last)->next = span;
- *last = span;
-}
-
-void
-fz_debug_text_span_xml(fz_text_span *span)
-{
- char buf[10];
- int c, n, k, i;
-
- while (span)
- {
- printf("<span font=\"%s\" size=\"%g\" wmode=\"%d\" eol=\"%d\">\n",
- span->font ? span->font->name : "NULL", span->size, span->wmode, span->eol);
-
- for (i = 0; i < span->len; i++)
- {
- printf("\t<char ucs=\"");
- c = span->text[i].c;
- if (c < 128)
- putchar(c);
- else
- {
- n = runetochar(buf, &c);
- for (k = 0; k < n; k++)
- putchar(buf[k]);
- }
- printf("\" bbox=\"%d %d %d %d\" />\n",
- span->text[i].bbox.x0,
- span->text[i].bbox.y0,
- span->text[i].bbox.x1,
- span->text[i].bbox.y1);
- }
-
- printf("</span>\n");
-
- span = span->next;
- }
-}
-
-void
-fz_debug_text_span(fz_text_span *span)
-{
- char buf[10];
- int c, n, k, i;
-
- while (span)
- {
- for (i = 0; i < span->len; i++)
- {
- c = span->text[i].c;
- if (c < 128)
- putchar(c);
- else
- {
- n = runetochar(buf, &c);
- for (k = 0; k < n; k++)
- putchar(buf[k]);
- }
- }
-
- if (span->eol)
- putchar('\n');
-
- span = span->next;
- }
-}
-
-static void
-fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_matrix ctm, fz_point *pen)
+fz_text_extract(fz_context *ctx, fz_text_device *dev, fz_text *text, fz_matrix ctm, fz_text_style *style)
{
+ fz_point *pen = &dev->point;
fz_font *font = text->font;
FT_Face face = font->ft_face;
fz_matrix tm = text->trm;
@@ -233,19 +302,21 @@ fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_mat
float ascender = 1;
float descender = 0;
int multi;
- int i, err;
+ int i, j, err;
+ int lastchar = ' ';
if (text->len == 0)
return;
- fz_lock(ctx, FZ_LOCK_FREETYPE);
if (font->ft_face)
{
+ fz_lock(ctx, FZ_LOCK_FREETYPE);
err = FT_Set_Char_Size(font->ft_face, 64, 64, 72, 72);
if (err)
fz_warn(ctx, "freetype set character size: %s", ft_error_string(err));
ascender = (float)face->ascender / face->units_per_EM;
descender = (float)face->descender / face->units_per_EM;
+ fz_unlock(ctx, FZ_LOCK_FREETYPE);
}
rect = fz_empty_rect;
@@ -264,6 +335,7 @@ fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_mat
tm.e = 0;
tm.f = 0;
trm = fz_concat(tm, ctm);
+
dir = fz_transform_vector(trm, dir);
dist = sqrtf(dir.x * dir.x + dir.y * dir.y);
ndir.x = dir.x / dist;
@@ -271,19 +343,8 @@ fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_mat
size = fz_matrix_expansion(trm);
- multi = 1;
-
for (i = 0; i < text->len; i++)
{
- if (text->items[i].gid < 0)
- {
- fz_add_text_char(ctx, last, font, size, text->wmode, text->items[i].ucs, fz_round_rect(rect));
- multi ++;
- fz_divide_text_chars(last, multi, fz_round_rect(rect));
- continue;
- }
- multi = 1;
-
/* Calculate new pen location and delta */
tm.e = text->items[i].x;
tm.f = text->items[i].y;
@@ -305,20 +366,19 @@ fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_mat
if (dist > size * LINE_DIST)
{
- fz_add_text_newline(ctx, last, font, size, text->wmode);
+ fz_flush_text_line(ctx, dev, style);
+ lastchar = ' ';
}
- else if (fabsf(dot) > 0.95f && dist > size * SPACE_DIST)
+ else if (fabsf(dot) > 0.95f && dist > size * SPACE_DIST && lastchar != ' ')
{
- if ((*last)->len > 0 && (*last)->text[(*last)->len - 1].c != ' ')
- {
- fz_rect spacerect;
- spacerect.x0 = -0.2f;
- spacerect.y0 = 0;
- spacerect.x1 = 0;
- spacerect.y1 = 1;
- spacerect = fz_transform_rect(trm, spacerect);
- fz_add_text_char(ctx, last, font, size, text->wmode, ' ', fz_round_rect(spacerect));
- }
+ fz_rect spacerect;
+ spacerect.x0 = -0.2f;
+ spacerect.y0 = 0;
+ spacerect.x1 = 0;
+ spacerect.y1 = 1;
+ spacerect = fz_transform_rect(trm, spacerect);
+ fz_add_text_char(ctx, dev, style, ' ', spacerect);
+ lastchar = ' ';
}
}
@@ -331,8 +391,13 @@ fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_mat
/* TODO: freetype returns broken vertical metrics */
/* if (text->wmode) mask |= FT_LOAD_VERTICAL_LAYOUT; */
+ fz_lock(ctx, FZ_LOCK_FREETYPE);
+ err = FT_Set_Char_Size(font->ft_face, 64, 64, 72, 72);
+ if (err)
+ fz_warn(ctx, "freetype set character size: %s", ft_error_string(err));
FT_Get_Advance(font->ft_face, text->items[i].gid, mask, &ftadv);
adv = ftadv / 65536.0f;
+ fz_unlock(ctx, FZ_LOCK_FREETYPE);
rect.x0 = 0;
rect.y0 = descender;
@@ -352,9 +417,27 @@ fz_text_extract_span(fz_context *ctx, fz_text_span **last, fz_text *text, fz_mat
pen->x = trm.e + dir.x * adv;
pen->y = trm.f + dir.y * adv;
- fz_add_text_char(ctx, last, font, size, text->wmode, text->items[i].ucs, fz_round_rect(rect));
+ /* Check for one glyph to many char mapping */
+ for (j = i + 1; j < text->len; j++)
+ if (text->items[j].gid >= 0)
+ break;
+ multi = j - i;
+
+ if (multi == 1)
+ {
+ fz_add_text_char(ctx, dev, style, text->items[i].ucs, rect);
+ }
+ else
+ {
+ for (j = 0; j < multi; j++)
+ {
+ fz_rect part = fz_split_bbox(rect, j, multi);
+ fz_add_text_char(ctx, dev, style, text->items[i].ucs, part);
+ }
+ }
+
+ lastchar = text->items[i].ucs;
}
- fz_unlock(ctx, FZ_LOCK_FREETYPE);
}
static void
@@ -362,7 +445,9 @@ fz_text_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
fz_text_device *tdev = dev->user;
- fz_text_extract_span(dev->ctx, &tdev->span, text, ctm, &tdev->point);
+ fz_text_style *style;
+ style = fz_lookup_text_style(dev->ctx, tdev->sheet, text, &ctm, colorspace, color, alpha, NULL);
+ fz_text_extract(dev->ctx, tdev, text, ctm, style);
}
static void
@@ -370,36 +455,57 @@ fz_text_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_m
fz_colorspace *colorspace, float *color, float alpha)
{
fz_text_device *tdev = dev->user;
- fz_text_extract_span(dev->ctx, &tdev->span, text, ctm, &tdev->point);
+ fz_text_style *style;
+ style = fz_lookup_text_style(dev->ctx, tdev->sheet, text, &ctm, colorspace, color, alpha, stroke);
+ fz_text_extract(dev->ctx, tdev, text, ctm, style);
}
static void
fz_text_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate)
{
fz_text_device *tdev = dev->user;
- fz_text_extract_span(dev->ctx, &tdev->span, text, ctm, &tdev->point);
+ fz_text_style *style;
+ style = fz_lookup_text_style(dev->ctx, tdev->sheet, text, &ctm, NULL, NULL, 0, NULL);
+ fz_text_extract(dev->ctx, tdev, text, ctm, style);
}
static void
fz_text_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
fz_text_device *tdev = dev->user;
- fz_text_extract_span(dev->ctx, &tdev->span, text, ctm, &tdev->point);
+ fz_text_style *style;
+ style = fz_lookup_text_style(dev->ctx, tdev->sheet, text, &ctm, NULL, NULL, 0, stroke);
+ fz_text_extract(dev->ctx, tdev, text, ctm, style);
}
static void
fz_text_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm)
{
fz_text_device *tdev = dev->user;
- fz_text_extract_span(dev->ctx, &tdev->span, text, ctm, &tdev->point);
+ fz_text_style *style;
+ style = fz_lookup_text_style(dev->ctx, tdev->sheet, text, &ctm, NULL, NULL, 0, NULL);
+ fz_text_extract(dev->ctx, tdev, text, ctm, style);
+}
+
+static int cmp_block(const void *av, const void *bv)
+{
+ const fz_text_block *a = av;
+ const fz_text_block *b = bv;
+ int x = a->bbox.x0 - b->bbox.x0;
+ if (x) return x;
+ return -(a->bbox.y0 - b->bbox.y0);
}
static void
fz_text_free_user(fz_device *dev)
{
+ fz_context *ctx = dev->ctx;
fz_text_device *tdev = dev->user;
- tdev->span->eol = 1;
+ append_span(ctx, &tdev->cur_line, &tdev->cur_span);
+ insert_line(ctx, tdev->page, &tdev->cur_line);
+
+ qsort(tdev->page->blocks, tdev->page->len, sizeof *tdev->page->blocks, cmp_block);
/* TODO: unicode NFC normalization */
/* TODO: bidi logical reordering */
@@ -408,15 +514,19 @@ fz_text_free_user(fz_device *dev)
}
fz_device *
-fz_new_text_device(fz_context *ctx, fz_text_span *root)
+fz_new_text_device(fz_context *ctx, fz_text_sheet *sheet, fz_text_page *page)
{
fz_device *dev;
+
fz_text_device *tdev = fz_malloc_struct(ctx, fz_text_device);
- tdev->head = root;
- tdev->span = root;
+ tdev->sheet = sheet;
+ tdev->page = page;
tdev->point.x = -1;
tdev->point.y = -1;
+ init_line(ctx, &tdev->cur_line);
+ init_span(ctx, &tdev->cur_span, NULL);
+
dev = fz_new_device(ctx, tdev);
dev->hints = FZ_IGNORE_IMAGE | FZ_IGNORE_SHADE;
dev->free_user = fz_text_free_user;
@@ -427,3 +537,209 @@ fz_new_text_device(fz_context *ctx, fz_text_span *root)
dev->ignore_text = fz_text_ignore_text;
return dev;
}
+
+/* XML, HTML and plain-text output */
+
+static int font_is_bold(fz_font *font)
+{
+ FT_Face face = font->ft_face;
+ if (face && (face->style_flags & FT_STYLE_FLAG_BOLD))
+ return 1;
+ if (strstr(font->name, "Bold"))
+ return 1;
+ return 0;
+}
+
+static int font_is_italic(fz_font *font)
+{
+ FT_Face face = font->ft_face;
+ if (face && (face->style_flags & FT_STYLE_FLAG_ITALIC))
+ return 1;
+ if (strstr(font->name, "Italic") || strstr(font->name, "Oblique"))
+ return 1;
+ return 0;
+}
+
+static void
+fz_print_style_begin(FILE *out, fz_text_style *style)
+{
+ int script = style->script;
+ fprintf(out, "<span class=\"s%d\">", style->id);
+ while (script-- > 0)
+ fprintf(out, "<sup>");
+ while (++script < 0)
+ fprintf(out, "<sub>");
+}
+
+static void
+fz_print_style_end(FILE *out, fz_text_style *style)
+{
+ int script = style->script;
+ while (script-- > 0)
+ fprintf(out, "</sup>");
+ while (++script < 0)
+ fprintf(out, "</sub>");
+ fprintf(out, "</span>");
+}
+
+static void
+fz_print_style(FILE *out, fz_text_style *style)
+{
+ char *s = strchr(style->font->name, '+');
+ s = s ? s + 1 : style->font->name;
+ fprintf(out, "span.s%d{font-family:\"%s\";font-size:%gpt;",
+ style->id, s, style->size);
+ if (font_is_italic(style->font))
+ fprintf(out, "font-style:italic;");
+ if (font_is_bold(style->font))
+ fprintf(out, "font-weight:bold;");
+ fprintf(out, "}\n");
+}
+
+void
+fz_print_text_sheet(fz_context *ctx, FILE *out, fz_text_sheet *sheet)
+{
+ fz_text_style *style;
+ for (style = sheet->style; style; style = style->next)
+ fz_print_style(out, style);
+}
+
+void
+fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page)
+{
+ int block_n, line_n, span_n, ch_n;
+ fz_text_style *style = NULL;
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
+
+ fprintf(out, "<div class=\"page\">\n");
+
+ for (block_n = 0; block_n < page->len; block_n++)
+ {
+ block = &page->blocks[block_n];
+ fprintf(out, "<div class=\"block\">\n");
+ for (line_n = 0; line_n < block->len; line_n++)
+ {
+ line = &block->lines[line_n];
+ fprintf(out, "<p>");
+ style = NULL;
+
+ for (span_n = 0; span_n < line->len; span_n++)
+ {
+ span = &line->spans[span_n];
+ if (style != span->style)
+ {
+ if (style != NULL)
+ fz_print_style_end(out, style);
+ fz_print_style_begin(out, span->style);
+ style = span->style;
+ }
+
+ for (ch_n = 0; ch_n < span->len; ch_n++)
+ {
+ fz_text_char *ch = &span->text[ch_n];
+ if (ch->c == '<')
+ fprintf(out, "&lt;");
+ else if (ch->c == '>')
+ fprintf(out, "&gt;");
+ else if (ch->c == '&')
+ fprintf(out, "&amp;");
+ else if (ch->c >= 32 && ch->c <= 127)
+ fprintf(out, "%c", ch->c);
+ else
+ fprintf(out, "&#x%x;", ch->c);
+ }
+ }
+ fz_print_style_end(out, style);
+ fprintf(out, "</p>\n");
+ }
+ fprintf(out, "</div>\n");
+ }
+
+ fprintf(out, "</div>\n");
+}
+
+void
+fz_print_text_page_xml(fz_context *ctx, FILE *out, fz_text_page *page)
+{
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
+ fz_text_char *ch;
+ char *s;
+
+ fprintf(out, "<page>\n");
+ for (block = page->blocks; block < page->blocks + page->len; block++)
+ {
+ fprintf(out, "<block bbox=\"%g %g %g %g\">\n",
+ block->bbox.x0, block->bbox.y0, block->bbox.x1, block->bbox.y1);
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ fprintf(out, "<line bbox=\"%g %g %g %g\">\n",
+ line->bbox.x0, line->bbox.y0, line->bbox.x1, line->bbox.y1);
+ for (span = line->spans; span < line->spans + line->len; span++)
+ {
+ fz_text_style *style = span->style;
+ s = strchr(style->font->name, '+');
+ s = s ? s + 1 : style->font->name;
+ fprintf(out, "<span bbox=\"%g %g %g %g\" font=\"%s\" size=\"%g\">\n",
+ span->bbox.x0, span->bbox.y0, span->bbox.x1, span->bbox.y1,
+ s, style->size);
+ for (ch = span->text; ch < span->text + span->len; ch++)
+ {
+ fprintf(out, "<char bbox=\"%g %g %g %g\" c=\"",
+ ch->bbox.x0, ch->bbox.y0, ch->bbox.x1, ch->bbox.y1);
+ switch (ch->c)
+ {
+ case '<': fprintf(out, "&lt;"); break;
+ case '>': fprintf(out, "&gt;"); break;
+ case '&': fprintf(out, "&amp;"); break;
+ case '"': fprintf(out, "&quot;"); break;
+ case '\'': fprintf(out, "&apos;"); break;
+ default:
+ if (ch->c >= 32 && ch->c <= 127)
+ fprintf(out, "%c", ch->c);
+ else
+ fprintf(out, "&#x%x;", ch->c);
+ break;
+ }
+ fprintf(out, "\"/>\n");
+ }
+ fprintf(out, "</span>\n");
+ }
+ fprintf(out, "</line>\n");
+ }
+ fprintf(out, "</block>\n");
+ }
+ fprintf(out, "</page>\n");
+}
+
+void
+fz_print_text_page(fz_context *ctx, FILE *out, fz_text_page *page)
+{
+ fz_text_block *block;
+ fz_text_line *line;
+ fz_text_span *span;
+ fz_text_char *ch;
+ char utf[10];
+ int i, n;
+
+ for (block = page->blocks; block < page->blocks + page->len; block++)
+ {
+ for (line = block->lines; line < block->lines + block->len; line++)
+ {
+ for (span = line->spans; span < line->spans + line->len; span++)
+ {
+ for (ch = span->text; ch < span->text + span->len; ch++)
+ {
+ n = fz_runetochar(utf, ch->c);
+ for (i = 0; i < n; i++)
+ putc(utf[i], out);
+ }
+ }
+ fprintf(out, "\n");
+ }
+ fprintf(out, "\n");
+ }
+}
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index 1c2e1ed1..b3c73ff2 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
static void
fz_trace_matrix(fz_matrix ctm)
@@ -145,7 +145,7 @@ fz_trace_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm,
fz_trace_matrix(ctm);
fz_trace_trm(text->trm);
printf(">\n");
- fz_debug_text(dev->ctx, text, 0);
+ fz_print_text(dev->ctx, stdout, text);
printf("</fill_text>\n");
}
@@ -158,7 +158,7 @@ fz_trace_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_
fz_trace_matrix(ctm);
fz_trace_trm(text->trm);
printf(">\n");
- fz_debug_text(dev->ctx, text, 0);
+ fz_print_text(dev->ctx, stdout, text);
printf("</stroke_text>\n");
}
@@ -170,7 +170,7 @@ fz_trace_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate)
fz_trace_matrix(ctm);
fz_trace_trm(text->trm);
printf(">\n");
- fz_debug_text(dev->ctx, text, 0);
+ fz_print_text(dev->ctx, stdout, text);
printf("</clip_text>\n");
}
@@ -181,7 +181,7 @@ fz_trace_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke
fz_trace_matrix(ctm);
fz_trace_trm(text->trm);
printf(">\n");
- fz_debug_text(dev->ctx, text, 0);
+ fz_print_text(dev->ctx, stdout, text);
printf("</clip_stroke_text>\n");
}
@@ -192,12 +192,12 @@ fz_trace_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm)
fz_trace_matrix(ctm);
fz_trace_trm(text->trm);
printf(">\n");
- fz_debug_text(dev->ctx, text, 0);
+ fz_print_text(dev->ctx, stdout, text);
printf("</ignore_text>\n");
}
static void
-fz_trace_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha)
+fz_trace_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha)
{
printf("<fill_image alpha=\"%g\" ", alpha);
fz_trace_matrix(ctm);
@@ -213,7 +213,7 @@ fz_trace_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha)
}
static void
-fz_trace_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
+fz_trace_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm,
fz_colorspace *colorspace, float *color, float alpha)
{
printf("<fill_image_mask ");
@@ -223,7 +223,7 @@ fz_colorspace *colorspace, float *color, float alpha)
}
static void
-fz_trace_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
+fz_trace_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm)
{
printf("<clip_image_mask ");
fz_trace_matrix(ctm);
diff --git a/fitz/doc_document.c b/fitz/doc_document.c
index ca13af72..2da7a110 100644
--- a/fitz/doc_document.c
+++ b/fitz/doc_document.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* Yuck! Promiscuous we are. */
extern struct pdf_document *pdf_open_document(fz_context *ctx, char *filename);
diff --git a/fitz/doc_link.c b/fitz/doc_link.c
index 71f5dfbf..d558d18a 100644
--- a/fitz/doc_link.c
+++ b/fitz/doc_link.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
void
fz_free_link_dest(fz_context *ctx, fz_link_dest *dest)
diff --git a/fitz/doc_outline.c b/fitz/doc_outline.c
index b69debaf..71694851 100644
--- a/fitz/doc_outline.c
+++ b/fitz/doc_outline.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
void
fz_free_outline(fz_context *ctx, fz_outline *outline)
@@ -14,37 +14,49 @@ fz_free_outline(fz_context *ctx, fz_outline *outline)
}
}
-void
-fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level)
+static void
+do_debug_outline_xml(FILE *out, fz_outline *outline, int level)
{
while (outline)
{
- printf("<outline title=\"%s\" page=\"%d\"", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0);
+ fprintf(out, "<outline title=\"%s\" page=\"%d\"", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0);
if (outline->down)
{
- printf(">\n");
- fz_debug_outline_xml(ctx, outline->down, level + 1);
- printf("</outline>\n");
+ fprintf(out, ">\n");
+ do_debug_outline_xml(out, outline->down, level + 1);
+ fprintf(out, "</outline>\n");
}
else
{
- printf(" />\n");
+ fprintf(out, " />\n");
}
outline = outline->next;
}
}
void
-fz_debug_outline(fz_context *ctx, fz_outline *outline, int level)
+fz_print_outline_xml(fz_context *ctx, FILE *out, fz_outline *outline)
+{
+ do_debug_outline_xml(out, outline, 0);
+}
+
+static void
+do_debug_outline(FILE *out, fz_outline *outline, int level)
{
int i;
while (outline)
{
for (i = 0; i < level; i++)
- putchar('\t');
- printf("%s\t%d\n", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0);
+ fputc('\t', out);
+ fprintf(out, "%s\t%d\n", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0);
if (outline->down)
- fz_debug_outline(ctx, outline->down, level + 1);
+ do_debug_outline(out, outline->down, level + 1);
outline = outline->next;
}
}
+
+void
+fz_print_outline(fz_context *ctx, FILE *out, fz_outline *outline)
+{
+ do_debug_outline(out, outline, 0);
+}
diff --git a/fitz/filt_basic.c b/fitz/filt_basic.c
index ae239fed..09d63402 100644
--- a/fitz/filt_basic.c
+++ b/fitz/filt_basic.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* Pretend we have a filter that just copies data forever */
diff --git a/fitz/filt_dctd.c b/fitz/filt_dctd.c
index 4357f3d7..23744f01 100644
--- a/fitz/filt_dctd.c
+++ b/fitz/filt_dctd.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#include <jpeglib.h>
#include <setjmp.h>
@@ -12,6 +12,7 @@ struct fz_dctd_s
int color_transform;
int init;
int stride;
+ int factor;
unsigned char *scanline;
unsigned char *rp, *wp;
struct jpeg_decompress_struct cinfo;
@@ -150,6 +151,9 @@ read_dctd(fz_stream *stm, unsigned char *buf, int len)
break;
}
+ cinfo->scale_num = 8/state->factor;
+ cinfo->scale_denom = 8;
+
jpeg_start_decompress(cinfo);
state->stride = cinfo->output_width * cinfo->output_components;
@@ -216,6 +220,12 @@ skip:
fz_stream *
fz_open_dctd(fz_stream *chain, int color_transform)
{
+ return fz_open_resized_dctd(chain, color_transform, 1);
+}
+
+fz_stream *
+fz_open_resized_dctd(fz_stream *chain, int color_transform, int factor)
+{
fz_context *ctx = chain->ctx;
fz_dctd *state = NULL;
@@ -228,6 +238,7 @@ fz_open_dctd(fz_stream *chain, int color_transform)
state->chain = chain;
state->color_transform = color_transform;
state->init = 0;
+ state->factor = factor;
}
fz_catch(ctx)
{
diff --git a/fitz/filt_faxd.c b/fitz/filt_faxd.c
index 4e522eb5..ada7e87b 100644
--- a/fitz/filt_faxd.c
+++ b/fitz/filt_faxd.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* Fax G3/G4 decoder */
diff --git a/fitz/filt_flate.c b/fitz/filt_flate.c
index 2eb0c563..24b6c081 100644
--- a/fitz/filt_flate.c
+++ b/fitz/filt_flate.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#include <zlib.h>
diff --git a/fitz/filt_jbig2d.c b/fitz/filt_jbig2d.c
index 3afcbcb0..415534c0 100644
--- a/fitz/filt_jbig2d.c
+++ b/fitz/filt_jbig2d.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#ifdef _WIN32 /* Microsoft Visual C++ */
diff --git a/fitz/filt_lzwd.c b/fitz/filt_lzwd.c
index ac952ccf..3ee4d34c 100644
--- a/fitz/filt_lzwd.c
+++ b/fitz/filt_lzwd.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* TODO: error checking */
diff --git a/fitz/filt_predict.c b/fitz/filt_predict.c
index 8221c251..e68743d3 100644
--- a/fitz/filt_predict.c
+++ b/fitz/filt_predict.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/* TODO: check if this works with 16bpp images */
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
new file mode 100644
index 00000000..0a639b1c
--- /dev/null
+++ b/fitz/fitz-internal.h
@@ -0,0 +1,1092 @@
+#ifndef FITZ_INTERNAL_H
+#define FITZ_INTERNAL_H
+
+#include "fitz.h"
+
+struct fz_warn_context_s
+{
+ char message[256];
+ int count;
+};
+
+
+fz_context *fz_clone_context_internal(fz_context *ctx);
+
+void fz_new_aa_context(fz_context *ctx);
+void fz_free_aa_context(fz_context *ctx);
+void fz_copy_aa_context(fz_context *dst, fz_context *src);
+
+/* Default allocator */
+extern fz_alloc_context fz_alloc_default;
+
+/* Default locks */
+extern fz_locks_context fz_locks_default;
+
+#if defined(MEMENTO) || defined(DEBUG)
+#define FITZ_DEBUG_LOCKING
+#endif
+
+#ifdef FITZ_DEBUG_LOCKING
+
+void fz_assert_lock_held(fz_context *ctx, int lock);
+void fz_assert_lock_not_held(fz_context *ctx, int lock);
+void fz_lock_debug_lock(fz_context *ctx, int lock);
+void fz_lock_debug_unlock(fz_context *ctx, int lock);
+
+#else
+
+#define fz_assert_lock_held(A,B) do { } while (0)
+#define fz_assert_lock_not_held(A,B) do { } while (0)
+#define fz_lock_debug_lock(A,B) do { } while (0)
+#define fz_lock_debug_unlock(A,B) do { } while (0)
+
+#endif /* !FITZ_DEBUG_LOCKING */
+
+static inline void
+fz_lock(fz_context *ctx, int lock)
+{
+ fz_lock_debug_lock(ctx, lock);
+ ctx->locks->lock(ctx->locks->user, lock);
+}
+
+static inline void
+fz_unlock(fz_context *ctx, int lock)
+{
+ fz_lock_debug_unlock(ctx, lock);
+ ctx->locks->unlock(ctx->locks->user, lock);
+}
+
+
+/*
+ * Basic runtime and utility functions
+ */
+
+/*
+ fz_malloc_struct: Allocate storage for a structure (with scavenging),
+ clear it, and (in Memento builds) tag the pointer as belonging to a
+ struct of this type.
+
+ CTX: The context.
+
+ STRUCT: The structure type.
+
+ Returns a pointer to allocated (and cleared) structure. Throws
+ exception on failure to allocate.
+*/
+/* alloc and zero a struct, and tag it for memento */
+#define fz_malloc_struct(CTX, STRUCT) \
+ Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT)
+
+/* Range checking atof */
+float fz_atof(const char *s);
+
+/*
+ * Generic hash-table with fixed-length keys.
+ */
+
+typedef struct fz_hash_table_s fz_hash_table;
+
+fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen, int lock);
+void fz_print_hash(fz_context *ctx, FILE *out, fz_hash_table *table);
+void fz_empty_hash(fz_context *ctx, fz_hash_table *table);
+void fz_free_hash(fz_context *ctx, fz_hash_table *table);
+
+void *fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key);
+void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val);
+void fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key);
+
+int fz_hash_len(fz_context *ctx, fz_hash_table *table);
+void *fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx);
+void *fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx);
+
+/*
+ * Math and geometry
+ */
+
+/* Multiply scaled two integers in the 0..255 range */
+static inline int fz_mul255(int a, int b)
+{
+ /* see Jim Blinn's book "Dirty Pixels" for how this works */
+ int x = a * b + 128;
+ x += x >> 8;
+ return x >> 8;
+}
+
+/* Expand a value A from the 0...255 range to the 0..256 range */
+#define FZ_EXPAND(A) ((A)+((A)>>7))
+
+/* Combine values A (in any range) and B (in the 0..256 range),
+ * to give a single value in the same range as A was. */
+#define FZ_COMBINE(A,B) (((A)*(B))>>8)
+
+/* Combine values A and C (in the same (any) range) and B and D (in the
+ * 0..256 range), to give a single value in the same range as A and C were. */
+#define FZ_COMBINE2(A,B,C,D) (FZ_COMBINE((A), (B)) + FZ_COMBINE((C), (D)))
+
+/* Blend SRC and DST (in the same range) together according to
+ * AMOUNT (in the 0...256 range). */
+#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8)
+
+void fz_gridfit_matrix(fz_matrix *m);
+float fz_matrix_max_expansion(fz_matrix m);
+
+/*
+ * Basic crypto functions.
+ * Independent of the rest of fitz.
+ * For further encapsulation in filters, or not.
+ */
+
+/* md5 digests */
+
+typedef struct fz_md5_s fz_md5;
+
+struct fz_md5_s
+{
+ unsigned int state[4];
+ unsigned int count[2];
+ unsigned char buffer[64];
+};
+
+void fz_md5_init(fz_md5 *state);
+void fz_md5_update(fz_md5 *state, const unsigned char *input, unsigned inlen);
+void fz_md5_final(fz_md5 *state, unsigned char digest[16]);
+
+/* sha-256 digests */
+
+typedef struct fz_sha256_s fz_sha256;
+
+struct fz_sha256_s
+{
+ unsigned int state[8];
+ unsigned int count[2];
+ union {
+ unsigned char u8[64];
+ unsigned int u32[16];
+ } buffer;
+};
+
+void fz_sha256_init(fz_sha256 *state);
+void fz_sha256_update(fz_sha256 *state, const unsigned char *input, unsigned int inlen);
+void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]);
+
+/* arc4 crypto */
+
+typedef struct fz_arc4_s fz_arc4;
+
+struct fz_arc4_s
+{
+ unsigned x;
+ unsigned y;
+ unsigned char state[256];
+};
+
+void fz_arc4_init(fz_arc4 *state, const unsigned char *key, unsigned len);
+void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, unsigned len);
+
+/* AES block cipher implementation from XYSSL */
+
+typedef struct fz_aes_s fz_aes;
+
+#define AES_DECRYPT 0
+#define AES_ENCRYPT 1
+
+struct fz_aes_s
+{
+ int nr; /* number of rounds */
+ unsigned long *rk; /* AES round keys */
+ unsigned long buf[68]; /* unaligned data */
+};
+
+void aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize );
+void aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize );
+void aes_crypt_cbc( fz_aes *ctx, int mode, int length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+
+/*
+ Resource store
+
+ MuPDF stores decoded "objects" into a store for potential reuse.
+ If the size of the store gets too big, objects stored within it can
+ be evicted and freed to recover space. When MuPDF comes to decode
+ such an object, it will check to see if a version of this object is
+ already in the store - if it is, it will simply reuse it. If not, it
+ will decode it and place it into the store.
+
+ All objects that can be placed into the store are derived from the
+ fz_storable type (i.e. this should be the first component of the
+ objects structure). This allows for consistent (thread safe)
+ reference counting, and includes a function that will be called to
+ free the object as soon as the reference count reaches zero.
+
+ Most objects offer fz_keep_XXXX/fz_drop_XXXX functions derived
+ from fz_keep_storable/fz_drop_storable. Creation of such objects
+ includes a call to FZ_INIT_STORABLE to set up the fz_storable header.
+ */
+
+typedef struct fz_storable_s fz_storable;
+
+typedef void (fz_store_free_fn)(fz_context *, fz_storable *);
+
+struct fz_storable_s {
+ int refs;
+ fz_store_free_fn *free;
+};
+
+#define FZ_INIT_STORABLE(S_,RC,FREE) \
+ do { fz_storable *S = &(S_)->storable; S->refs = (RC); \
+ S->free = (FREE); \
+ } while (0)
+
+void *fz_keep_storable(fz_context *, fz_storable *);
+void fz_drop_storable(fz_context *, fz_storable *);
+
+/*
+ The store can be seen as a dictionary that maps keys to fz_storable
+ values. In order to allow keys of different types to be stored, we
+ have a structure full of functions for each key 'type'; this
+ fz_store_type pointer is stored with each key, and tells the store
+ how to perform certain operations (like taking/dropping a reference,
+ comparing two keys, outputting details for debugging etc).
+
+ The store uses a hash table internally for speed where possible. In
+ order for this to work, we need a mechanism for turning a generic
+ 'key' into 'a hashable string'. For this purpose the type structure
+ contains a make_hash_key function pointer that maps from a void *
+ to an fz_store_hash structure. If make_hash_key function returns 0,
+ then the key is determined not to be hashable, and the value is
+ not stored in the hash table.
+*/
+typedef struct fz_store_hash_s fz_store_hash;
+
+struct fz_store_hash_s
+{
+ fz_store_free_fn *free;
+ union
+ {
+ struct
+ {
+ int i0;
+ int i1;
+ } i;
+ struct
+ {
+ void *ptr;
+ int i;
+ } pi;
+ } u;
+};
+
+typedef struct fz_store_type_s fz_store_type;
+
+struct fz_store_type_s
+{
+ int (*make_hash_key)(fz_store_hash *, void *);
+ void *(*keep_key)(fz_context *,void *);
+ void (*drop_key)(fz_context *,void *);
+ int (*cmp_key)(void *, void *);
+ void (*debug)(void *);
+};
+
+/*
+ fz_store_new_context: Create a new store inside the context
+
+ max: The maximum size (in bytes) that the store is allowed to grow
+ to. FZ_STORE_UNLIMITED means no limit.
+*/
+void fz_new_store_context(fz_context *ctx, unsigned int max);
+
+/*
+ fz_drop_store_context: Drop a reference to the store.
+*/
+void fz_drop_store_context(fz_context *ctx);
+
+/*
+ fz_keep_store_context: Take a reference to the store.
+*/
+fz_store *fz_keep_store_context(fz_context *ctx);
+
+/*
+ fz_print_store: Dump the contents of the store for debugging.
+*/
+void fz_print_store(fz_context *ctx, FILE *out);
+
+/*
+ fz_store_item: Add an item to the store.
+
+ Add an item into the store, returning NULL for success. If an item
+ with the same key is found in the store, then our item will not be
+ inserted, and the function will return a pointer to that value
+ instead. This function takes its own reference to val, as required
+ (i.e. the caller maintains ownership of its own reference).
+
+ key: The key to use to index the item.
+
+ val: The value to store.
+
+ itemsize: The size in bytes of the value (as counted towards the
+ store size).
+
+ type: Functions used to manipulate the key.
+*/
+void *fz_store_item(fz_context *ctx, void *key, void *val, unsigned int itemsize, fz_store_type *type);
+
+/*
+ fz_find_item: Find an item within the store.
+
+ free: The function used to free the value (to ensure we get a value
+ of the correct type).
+
+ key: The key to use to index the item.
+
+ type: Functions used to manipulate the key.
+
+ Returns NULL for not found, otherwise returns a pointer to the value
+ indexed by key to which a reference has been taken.
+*/
+void *fz_find_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type);
+
+/*
+ fz_remove_item: Remove an item from the store.
+
+ If an item indexed by the given key exists in the store, remove it.
+
+ free: The function used to free the value (to ensure we get a value
+ of the correct type).
+
+ key: The key to use to find the item to remove.
+
+ type: Functions used to manipulate the key.
+*/
+void fz_remove_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type);
+
+/*
+ fz_empty_store: Evict everything from the store.
+*/
+void fz_empty_store(fz_context *ctx);
+
+/*
+ fz_store_scavenge: Internal function used as part of the scavenging
+ allocator; when we fail to allocate memory, before returning a
+ failure to the caller, we try to scavenge space within the store by
+ evicting at least 'size' bytes. The allocator then retries.
+
+ size: The number of bytes we are trying to have free.
+
+ phase: What phase of the scavenge we are in. Updated on exit.
+
+ Returns non zero if we managed to free any memory.
+*/
+int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase);
+
+struct fz_buffer_s
+{
+ int refs;
+ unsigned char *data;
+ int cap, len;
+};
+
+/*
+ fz_new_buffer: Create a new buffer.
+
+ capacity: Initial capacity.
+
+ Returns pointer to new buffer. Throws exception on allocation
+ failure.
+*/
+fz_buffer *fz_new_buffer(fz_context *ctx, int capacity);
+
+/*
+ fz_resize_buffer: Ensure that a buffer has a given capacity,
+ truncating data if required.
+
+ buf: The buffer to alter.
+
+ capacity: The desired capacity for the buffer. If the current size
+ of the buffer contents is smaller than capacity, it is truncated.
+
+*/
+void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, int capacity);
+
+/*
+ fz_grow_buffer: Make some space within a buffer (i.e. ensure that
+ capacity > size).
+
+ buf: The buffer to grow.
+
+ May throw exception on failure to allocate.
+*/
+void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
+
+/*
+ fz_trim_buffer: Trim wasted capacity from a buffer.
+
+ buf: The buffer to trim.
+*/
+void fz_trim_buffer(fz_context *ctx, fz_buffer *buf);
+
+struct fz_stream_s
+{
+ fz_context *ctx;
+ int refs;
+ int error;
+ int eof;
+ int pos;
+ int avail;
+ int bits;
+ int locked;
+ unsigned char *bp, *rp, *wp, *ep;
+ void *state;
+ int (*read)(fz_stream *stm, unsigned char *buf, int len);
+ void (*close)(fz_context *ctx, void *state);
+ void (*seek)(fz_stream *stm, int offset, int whence);
+ unsigned char buf[4096];
+};
+
+void fz_lock_stream(fz_stream *stm);
+
+fz_stream *fz_new_stream(fz_context *ctx, void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_context *, void *));
+fz_stream *fz_keep_stream(fz_stream *stm);
+void fz_fill_buffer(fz_stream *stm);
+
+void fz_read_line(fz_stream *stm, char *buf, int max);
+
+static inline int fz_read_byte(fz_stream *stm)
+{
+ if (stm->rp == stm->wp)
+ {
+ fz_fill_buffer(stm);
+ return stm->rp < stm->wp ? *stm->rp++ : EOF;
+ }
+ return *stm->rp++;
+}
+
+static inline int fz_peek_byte(fz_stream *stm)
+{
+ if (stm->rp == stm->wp)
+ {
+ fz_fill_buffer(stm);
+ return stm->rp < stm->wp ? *stm->rp : EOF;
+ }
+ return *stm->rp;
+}
+
+static inline void fz_unread_byte(fz_stream *stm)
+{
+ if (stm->rp > stm->bp)
+ stm->rp--;
+}
+
+static inline int fz_is_eof(fz_stream *stm)
+{
+ if (stm->rp == stm->wp)
+ {
+ if (stm->eof)
+ return 1;
+ return fz_peek_byte(stm) == EOF;
+ }
+ return 0;
+}
+
+static inline unsigned int fz_read_bits(fz_stream *stm, int n)
+{
+ unsigned int x;
+
+ if (n <= stm->avail)
+ {
+ stm->avail -= n;
+ x = (stm->bits >> stm->avail) & ((1 << n) - 1);
+ }
+ else
+ {
+ x = stm->bits & ((1 << stm->avail) - 1);
+ n -= stm->avail;
+ stm->avail = 0;
+
+ while (n > 8)
+ {
+ x = (x << 8) | fz_read_byte(stm);
+ n -= 8;
+ }
+
+ if (n > 0)
+ {
+ stm->bits = fz_read_byte(stm);
+ stm->avail = 8 - n;
+ x = (x << n) | (stm->bits >> stm->avail);
+ }
+ }
+
+ return x;
+}
+
+static inline void fz_sync_bits(fz_stream *stm)
+{
+ stm->avail = 0;
+}
+
+static inline int fz_is_eof_bits(fz_stream *stm)
+{
+ return fz_is_eof(stm) && (stm->avail == 0 || stm->bits == EOF);
+}
+
+/*
+ * Data filters.
+ */
+
+fz_stream *fz_open_copy(fz_stream *chain);
+fz_stream *fz_open_null(fz_stream *chain, int len);
+fz_stream *fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen);
+fz_stream *fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen);
+fz_stream *fz_open_a85d(fz_stream *chain);
+fz_stream *fz_open_ahxd(fz_stream *chain);
+fz_stream *fz_open_rld(fz_stream *chain);
+fz_stream *fz_open_dctd(fz_stream *chain, int color_transform);
+fz_stream *fz_open_resized_dctd(fz_stream *chain, int color_transform, int factor);
+fz_stream *fz_open_faxd(fz_stream *chain,
+ int k, int end_of_line, int encoded_byte_align,
+ int columns, int rows, int end_of_block, int black_is_1);
+fz_stream *fz_open_flated(fz_stream *chain);
+fz_stream *fz_open_lzwd(fz_stream *chain, int early_change);
+fz_stream *fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc);
+fz_stream *fz_open_jbig2d(fz_stream *chain, fz_buffer *global);
+
+/*
+ * Resources and other graphics related objects.
+ */
+
+enum { FZ_MAX_COLORS = 32 };
+
+int fz_lookup_blendmode(char *name);
+char *fz_blendmode_name(int blendmode);
+
+struct fz_bitmap_s
+{
+ int refs;
+ int w, h, stride, n;
+ unsigned char *samples;
+};
+
+fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n);
+
+void fz_bitmap_details(fz_bitmap *bitmap, int *w, int *h, int *n, int *stride);
+
+void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit);
+
+/*
+ Pixmaps represent a set of pixels for a 2 dimensional region of a
+ plane. Each pixel has n components per pixel, the last of which is
+ always alpha. The data is in premultiplied alpha when rendering, but
+ non-premultiplied for colorspace conversions and rescaling.
+
+ x, y: The minimum x and y coord of the region in pixels.
+
+ w, h: The width and height of the region in pixels.
+
+ n: The number of color components in the image. Always
+ includes a separate alpha channel. For mask images n=1, for greyscale
+ (plus alpha) images n=2, for rgb (plus alpha) images n=3.
+
+ interpolate: A boolean flag set to non-zero if the image
+ will be drawn using linear interpolation, or set to zero if
+ image will be using nearest neighbour sampling.
+
+ xres, yres: Image resolution in dpi. Default is 96 dpi.
+
+ colorspace: Pointer to a colorspace object describing the colorspace
+ the pixmap is in. If NULL, the image is a mask.
+
+ samples: A simple block of memory w * h * n bytes of memory in which
+ the components are stored. The first n bytes are components 0 to n-1
+ for the pixel at (x,y). Each successive n bytes gives another pixel
+ in scanline order. Subsequent scanlines follow on with no padding.
+
+ free_samples: Is zero when an application has provided its own
+ buffer for pixel data through fz_new_pixmap_with_bbox_and_data.
+ If not zero the buffer will be freed when fz_drop_pixmap is
+ called for the pixmap.
+*/
+struct fz_pixmap_s
+{
+ fz_storable storable;
+ int x, y, w, h, n;
+ int interpolate;
+ int xres, yres;
+ fz_colorspace *colorspace;
+ unsigned char *samples;
+ int free_samples;
+};
+
+void fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix);
+
+void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_bbox r);
+void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r);
+void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
+fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity);
+unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix);
+
+fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_bbox *clip);
+
+fz_bbox fz_pixmap_bbox_no_ctx(fz_pixmap *src);
+
+struct fz_image_s
+{
+ fz_storable storable;
+ int w, h;
+ fz_image *mask;
+ fz_colorspace *colorspace;
+ fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int w, int h);
+};
+
+fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs);
+fz_pixmap *fz_load_jpeg(fz_context *doc, unsigned char *data, int size);
+fz_pixmap *fz_load_png(fz_context *doc, unsigned char *data, int size);
+fz_pixmap *fz_load_tiff(fz_context *doc, unsigned char *data, int size);
+
+struct fz_halftone_s
+{
+ int refs;
+ int n;
+ fz_pixmap *comp[1];
+};
+
+fz_halftone *fz_new_halftone(fz_context *ctx, int num_comps);
+fz_halftone *fz_default_halftone(fz_context *ctx, int num_comps);
+void fz_drop_halftone(fz_context *ctx, fz_halftone *half);
+fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half);
+
+struct fz_colorspace_s
+{
+ fz_storable storable;
+ unsigned int size;
+ char name[16];
+ int n;
+ void (*to_rgb)(fz_context *ctx, fz_colorspace *, float *src, float *rgb);
+ void (*from_rgb)(fz_context *ctx, fz_colorspace *, float *rgb, float *dst);
+ void (*free_data)(fz_context *Ctx, fz_colorspace *);
+ void *data;
+};
+
+fz_colorspace *fz_new_colorspace(fz_context *ctx, char *name, int n);
+fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
+void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
+void fz_free_colorspace_imp(fz_context *ctx, fz_storable *colorspace);
+
+void fz_convert_color(fz_context *ctx, fz_colorspace *dsts, float *dstv, fz_colorspace *srcs, float *srcv);
+
+/*
+ * Fonts come in two variants:
+ * Regular fonts are handled by FreeType.
+ * Type 3 fonts have callbacks to the interpreter.
+ */
+
+char *ft_error_string(int err);
+
+struct fz_font_s
+{
+ int refs;
+ char name[32];
+
+ void *ft_face; /* has an FT_Face if used */
+ int ft_substitute; /* ... substitute metrics */
+ int ft_bold; /* ... synthesize bold */
+ int ft_italic; /* ... synthesize italic */
+ int ft_hint; /* ... force hinting for DynaLab fonts */
+
+ /* origin of font data */
+ char *ft_file;
+ unsigned char *ft_data;
+ int ft_size;
+
+ fz_matrix t3matrix;
+ void *t3resources;
+ fz_buffer **t3procs; /* has 256 entries if used */
+ float *t3widths; /* has 256 entries if used */
+ char *t3flags; /* has 256 entries if used */
+ void *t3doc; /* a pdf_document for the callback */
+ void (*t3run)(void *doc, void *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate);
+ void (*t3freeres)(void *doc, void *resources);
+
+ fz_rect bbox; /* font bbox is used only for t3 fonts */
+
+ /* per glyph bounding box cache */
+ int use_glyph_bbox;
+ int bbox_count;
+ fz_rect *bbox_table;
+
+ /* substitute metrics */
+ int width_count;
+ int *width_table; /* in 1000 units */
+};
+
+void fz_new_font_context(fz_context *ctx);
+fz_font_context *fz_keep_font_context(fz_context *ctx);
+void fz_drop_font_context(fz_context *ctx);
+
+fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix);
+
+fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox);
+fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox);
+
+fz_font *fz_keep_font(fz_context *ctx, fz_font *font);
+void fz_drop_font(fz_context *ctx, fz_font *font);
+
+void fz_print_font(fz_context *ctx, FILE *out, fz_font *font);
+
+void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax);
+fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
+int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid);
+
+/*
+ * Vector path buffer.
+ * It can be stroked and dashed, or be filled.
+ * It has a fill rule (nonzero or even_odd).
+ *
+ * When rendering, they are flattened, stroked and dashed straight
+ * into the Global Edge List.
+ */
+
+typedef struct fz_path_s fz_path;
+typedef struct fz_stroke_state_s fz_stroke_state;
+
+typedef union fz_path_item_s fz_path_item;
+
+typedef enum fz_path_item_kind_e
+{
+ FZ_MOVETO,
+ FZ_LINETO,
+ FZ_CURVETO,
+ FZ_CLOSE_PATH
+} fz_path_item_kind;
+
+typedef enum fz_linecap_e
+{
+ FZ_LINECAP_BUTT = 0,
+ FZ_LINECAP_ROUND = 1,
+ FZ_LINECAP_SQUARE = 2,
+ FZ_LINECAP_TRIANGLE = 3
+} fz_linecap;
+
+typedef enum fz_linejoin_e
+{
+ FZ_LINEJOIN_MITER = 0,
+ FZ_LINEJOIN_ROUND = 1,
+ FZ_LINEJOIN_BEVEL = 2,
+ FZ_LINEJOIN_MITER_XPS = 3
+} fz_linejoin;
+
+union fz_path_item_s
+{
+ fz_path_item_kind k;
+ float v;
+};
+
+struct fz_path_s
+{
+ int len, cap;
+ fz_path_item *items;
+ int last;
+};
+
+struct fz_stroke_state_s
+{
+ fz_linecap start_cap, dash_cap, end_cap;
+ fz_linejoin linejoin;
+ float linewidth;
+ float miterlimit;
+ float dash_phase;
+ int dash_len;
+ float dash_list[32];
+};
+
+fz_path *fz_new_path(fz_context *ctx);
+void fz_moveto(fz_context*, fz_path*, float x, float y);
+void fz_lineto(fz_context*, fz_path*, float x, float y);
+void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float);
+void fz_curvetov(fz_context*,fz_path*, float, float, float, float);
+void fz_curvetoy(fz_context*,fz_path*, float, float, float, float);
+void fz_closepath(fz_context*,fz_path*);
+void fz_free_path(fz_context *ctx, fz_path *path);
+
+void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform);
+
+fz_path *fz_clone_path(fz_context *ctx, fz_path *old);
+
+fz_rect fz_bound_path(fz_context *ctx, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm);
+void fz_print_path(fz_context *ctx, FILE *out, fz_path *, int indent);
+
+/*
+ * Glyph cache
+ */
+
+void fz_new_glyph_cache_context(fz_context *ctx);
+fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx);
+void fz_drop_glyph_cache_context(fz_context *ctx);
+void fz_purge_glyph_cache(fz_context *ctx);
+
+fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, int aa);
+fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model);
+fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state);
+fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model);
+fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke);
+void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate);
+
+/*
+ * Text buffer.
+ *
+ * The trm field contains the a, b, c and d coefficients.
+ * The e and f coefficients come from the individual elements,
+ * together they form the transform matrix for the glyph.
+ *
+ * Glyphs are referenced by glyph ID.
+ * The Unicode text equivalent is kept in a separate array
+ * with indexes into the glyph array.
+ */
+
+typedef struct fz_text_s fz_text;
+typedef struct fz_text_item_s fz_text_item;
+
+struct fz_text_item_s
+{
+ float x, y;
+ int gid; /* -1 for one gid to many ucs mappings */
+ int ucs; /* -1 for one ucs to many gid mappings */
+};
+
+struct fz_text_s
+{
+ fz_font *font;
+ fz_matrix trm;
+ int wmode;
+ int len, cap;
+ fz_text_item *items;
+};
+
+fz_text *fz_new_text(fz_context *ctx, fz_font *face, fz_matrix trm, int wmode);
+void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y);
+void fz_free_text(fz_context *ctx, fz_text *text);
+fz_rect fz_bound_text(fz_context *ctx, fz_text *text, fz_matrix ctm);
+fz_text *fz_clone_text(fz_context *ctx, fz_text *old);
+void fz_print_text(fz_context *ctx, FILE *out, fz_text*);
+
+/*
+ * The shading code uses gouraud shaded triangle meshes.
+ */
+
+enum
+{
+ FZ_LINEAR,
+ FZ_RADIAL,
+ FZ_MESH,
+};
+
+typedef struct fz_shade_s fz_shade;
+
+struct fz_shade_s
+{
+ fz_storable storable;
+
+ fz_rect bbox; /* can be fz_infinite_rect */
+ fz_colorspace *colorspace;
+
+ fz_matrix matrix; /* matrix from pattern dict */
+ int use_background; /* background color for fills but not 'sh' */
+ float background[FZ_MAX_COLORS];
+
+ int use_function;
+ float function[256][FZ_MAX_COLORS + 1];
+
+ int type; /* linear, radial, mesh */
+ int extend[2];
+
+ int mesh_len;
+ int mesh_cap;
+ float *mesh; /* [x y 0], [x y r], [x y t] or [x y c1 ... cn] */
+};
+
+fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade);
+void fz_drop_shade(fz_context *ctx, fz_shade *shade);
+void fz_free_shade_imp(fz_context *ctx, fz_storable *shade);
+void fz_print_shade(fz_context *ctx, FILE *out, fz_shade *shade);
+
+fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm);
+void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox);
+
+/*
+ * Scan converter
+ */
+
+typedef struct fz_gel_s fz_gel;
+
+fz_gel *fz_new_gel(fz_context *ctx);
+void fz_insert_gel(fz_gel *gel, float x0, float y0, float x1, float y1);
+void fz_reset_gel(fz_gel *gel, fz_bbox clip);
+void fz_sort_gel(fz_gel *gel);
+fz_bbox fz_bound_gel(fz_gel *gel);
+void fz_free_gel(fz_gel *gel);
+int fz_is_rect_gel(fz_gel *gel);
+
+void fz_scan_convert(fz_gel *gel, int eofill, fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv);
+
+void fz_flatten_fill_path(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness);
+void fz_flatten_stroke_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth);
+void fz_flatten_dash_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth);
+
+/*
+ * The device interface.
+ */
+
+fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest);
+
+enum
+{
+ /* Hints */
+ FZ_IGNORE_IMAGE = 1,
+ FZ_IGNORE_SHADE = 2,
+
+ /* Flags */
+ FZ_DEVFLAG_MASK = 1,
+ FZ_DEVFLAG_COLOR = 2,
+ FZ_DEVFLAG_UNCACHEABLE = 4,
+ FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8,
+ FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16,
+ FZ_DEVFLAG_STARTCAP_UNDEFINED = 32,
+ FZ_DEVFLAG_DASHCAP_UNDEFINED = 64,
+ FZ_DEVFLAG_ENDCAP_UNDEFINED = 128,
+ FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256,
+ FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512,
+ FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024,
+ /* Arguably we should have a bit for the dash pattern itself being
+ * undefined, but that causes problems; do we assume that it should
+ * always be set to non-dashing at the start of every glyph? */
+};
+
+struct fz_device_s
+{
+ int hints;
+ int flags;
+
+ void *user;
+ void (*free_user)(fz_device *);
+ fz_context *ctx;
+
+ void (*fill_path)(fz_device *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*stroke_path)(fz_device *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*clip_path)(fz_device *, fz_path *, fz_rect *rect, int even_odd, fz_matrix);
+ void (*clip_stroke_path)(fz_device *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix);
+
+ void (*fill_text)(fz_device *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*clip_text)(fz_device *, fz_text *, fz_matrix, int accumulate);
+ void (*clip_stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix);
+ void (*ignore_text)(fz_device *, fz_text *, fz_matrix);
+
+ void (*fill_shade)(fz_device *, fz_shade *shd, fz_matrix ctm, float alpha);
+ void (*fill_image)(fz_device *, fz_image *img, fz_matrix ctm, float alpha);
+ void (*fill_image_mask)(fz_device *, fz_image *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
+ void (*clip_image_mask)(fz_device *, fz_image *img, fz_rect *rect, fz_matrix ctm);
+
+ void (*pop_clip)(fz_device *);
+
+ void (*begin_mask)(fz_device *, fz_rect, int luminosity, fz_colorspace *, float *bc);
+ void (*end_mask)(fz_device *);
+ void (*begin_group)(fz_device *, fz_rect, int isolated, int knockout, int blendmode, float alpha);
+ void (*end_group)(fz_device *);
+
+ void (*begin_tile)(fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
+ void (*end_tile)(fz_device *);
+};
+
+void fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
+void fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
+void fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm);
+void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm);
+void fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
+void fz_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
+void fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate);
+void fz_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm);
+void fz_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm);
+void fz_pop_clip(fz_device *dev);
+void fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha);
+void fz_fill_image(fz_device *dev, fz_image *image, fz_matrix ctm, float alpha);
+void fz_fill_image_mask(fz_device *dev, fz_image *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
+void fz_clip_image_mask(fz_device *dev, fz_image *image, fz_rect *rect, fz_matrix ctm);
+void fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc);
+void fz_end_mask(fz_device *dev);
+void fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha);
+void fz_end_group(fz_device *dev);
+void fz_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
+void fz_end_tile(fz_device *dev);
+
+fz_device *fz_new_device(fz_context *ctx, void *user);
+
+
+
+/*
+ * Plotting functions.
+ */
+
+void fz_decode_tile(fz_pixmap *pix, float *decode);
+void fz_decode_indexed_tile(fz_pixmap *pix, float *decode, int maxval);
+void fz_unpack_tile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale);
+
+void fz_paint_solid_alpha(unsigned char * restrict dp, int w, int alpha);
+void fz_paint_solid_color(unsigned char * restrict dp, int n, int w, unsigned char *color);
+
+void fz_paint_span(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w, int alpha);
+void fz_paint_span_with_color(unsigned char * restrict dp, unsigned char * restrict mp, int n, int w, unsigned char *color);
+
+void fz_paint_image(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha);
+void fz_paint_image_with_color(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv);
+
+void fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha);
+void fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk);
+void fz_paint_pixmap_with_rect(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_bbox bbox);
+
+void fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape);
+void fz_blend_pixel(unsigned char dp[3], unsigned char bp[3], unsigned char sp[3], int blendmode);
+
+enum
+{
+ /* PDF 1.4 -- standard separable */
+ FZ_BLEND_NORMAL,
+ FZ_BLEND_MULTIPLY,
+ FZ_BLEND_SCREEN,
+ FZ_BLEND_OVERLAY,
+ FZ_BLEND_DARKEN,
+ FZ_BLEND_LIGHTEN,
+ FZ_BLEND_COLOR_DODGE,
+ FZ_BLEND_COLOR_BURN,
+ FZ_BLEND_HARD_LIGHT,
+ FZ_BLEND_SOFT_LIGHT,
+ FZ_BLEND_DIFFERENCE,
+ FZ_BLEND_EXCLUSION,
+
+ /* PDF 1.4 -- standard non-separable */
+ FZ_BLEND_HUE,
+ FZ_BLEND_SATURATION,
+ FZ_BLEND_COLOR,
+ FZ_BLEND_LUMINOSITY,
+
+ /* For packing purposes */
+ FZ_BLEND_MODEMASK = 15,
+ FZ_BLEND_ISOLATED = 16,
+ FZ_BLEND_KNOCKOUT = 32
+};
+
+struct fz_document_s
+{
+ void (*close)(fz_document *);
+ int (*needs_password)(fz_document *doc);
+ int (*authenticate_password)(fz_document *doc, char *password);
+ fz_outline *(*load_outline)(fz_document *doc);
+ int (*count_pages)(fz_document *doc);
+ fz_page *(*load_page)(fz_document *doc, int number);
+ fz_link *(*load_links)(fz_document *doc, fz_page *page);
+ fz_rect (*bound_page)(fz_document *doc, fz_page *page);
+ void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
+ void (*free_page)(fz_document *doc, fz_page *page);
+};
+
+#endif
diff --git a/fitz/fitz.h b/fitz/fitz.h
index d2672031..26751824 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -1,9 +1,9 @@
-#ifndef _FITZ_H_
-#define _FITZ_H_
+#ifndef FITZ_H
+#define FITZ_H
/*
- * Include the standard libc headers.
- */
+ Include the standard libc headers.
+*/
#include <stdio.h>
#include <stdlib.h>
@@ -15,13 +15,27 @@
#include <assert.h>
#include <errno.h>
#include <limits.h> /* INT_MAX & co */
-#include <float.h> /* FLT_EPSILON */
+#include <float.h> /* FLT_EPSILON, FLT_MAX & co */
#include <fcntl.h> /* O_RDONLY & co */
#include <setjmp.h>
#include "memento.h"
+/*
+ Some versions of setjmp/longjmp (notably MacOSX and ios) store/restore
+ signal handlers too. We don't alter signal handlers within mupdf, so
+ there is no need for us to store/restore - hence we use the
+ non-restoring variants. This makes a large speed difference.
+*/
+#ifdef __APPLE__
+#define fz_setjmp _setjmp
+#define fz_longjmp _longjmp
+#else
+#define fz_setjmp setjmp
+#define fz_longjmp longjmp
+#endif
+
#ifdef __ANDROID__
#include <android/log.h>
#define LOG_TAG "libmupdf"
@@ -38,10 +52,11 @@
#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
#define CLAMP(x,a,b) ( (x) > (b) ? (b) : ( (x) < (a) ? (a) : (x) ) )
+#define DIV_BY_ZERO(a, b, min, max) (((a) < 0) ^ ((b) < 0) ? (min) : (max))
/*
- * Some differences in libc can be smoothed over
- */
+ Some differences in libc can be smoothed over
+*/
#ifdef _MSC_VER /* Microsoft Visual C */
@@ -54,7 +69,7 @@
int gettimeofday(struct timeval *tv, struct timezone *tz);
#define snprintf _snprintf
-#define strtoll _strtoi64
+#define isnan _isnan
#else /* Unix or close enough */
@@ -75,8 +90,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif
/*
- * Variadic macros, inline and restrict keywords
- */
+ Variadic macros, inline and restrict keywords
+*/
#if __STDC_VERSION__ == 199901L /* C99 */
#elif _MSC_VER >= 1500 /* MSVC 9 or newer */
@@ -91,8 +106,8 @@ int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif
/*
- * GCC can do type checking of printf strings
- */
+ GCC can do type checking of printf strings
+*/
#ifndef __printflike
#if __GNUC__ > 2 || __GNUC__ == 2 && __GNUC_MINOR__ >= 7
@@ -103,7 +118,9 @@ int gettimeofday(struct timeval *tv, struct timezone *tz);
#endif
#endif
-/* Contexts */
+/*
+ Contexts
+*/
typedef struct fz_alloc_context_s fz_alloc_context;
typedef struct fz_error_context_s fz_error_context;
@@ -123,9 +140,6 @@ struct fz_alloc_context_s
void (*free)(void *, void *);
};
-/* Default allocator */
-extern fz_alloc_context fz_alloc_default;
-
struct fz_error_context_s
{
int top;
@@ -140,139 +154,13 @@ void fz_var_imp(void *);
#define fz_var(var) fz_var_imp((void *)&(var))
/*
-
-MuPDF uses a set of exception handling macros to simplify error return
-and cleanup. Conceptually, they work a lot like C++'s try/catch system,
-but do not require any special compiler support.
-
-The basic formulation is as follows:
-
- fz_try(ctx)
- {
- // Try to perform a task. Never 'return', 'goto' or 'longjmp' out
- // of here. 'break' may be used to safely exit (just) the try block
- // scope.
- }
- fz_always(ctx)
- {
- // Any code here is always executed, regardless of whether an
- // exception was thrown within the try or not. Never 'return', 'goto'
- // or longjmp out from here. 'break' may be used to safely exit (just)
- // the always block scope.
- }
- fz_catch(ctx)
- {
- // This code is called (after any always block) only if something
- // within the fz_try block (including any functions it called) threw
- // an exception. The code here is expected to handle the exception
- // (maybe record/report the error, cleanup any stray state etc) and
- // can then either exit the block, or pass on the exception to a
- // higher level (enclosing) fz_try block (using fz_throw, or
- // fz_rethrow).
- }
-
-The fz_always block is optional, and can safely be omitted.
-
-The macro based nature of this system has 3 main limitations:
-
-1) Never return from within try (or 'goto' or longjmp out of it).
- This upsets the internal housekeeping of the macros and will cause
- problems later on. The code will detect such things happening, but
- by then it is too late to give a helpful error report as to where the
- original infraction occurred.
-
-2) The fz_try(ctx) { ... } fz_always(ctx) { ... } fz_catch(ctx) { ... }
- is not one atomic C statement. That is to say, if you do:
-
- if (condition)
- fz_try(ctx) { ... }
- fz_catch(ctx) { ... }
-
- then you will not get what you want. Use the following instead:
-
- if (condition) {
- fz_try(ctx) { ... }
- fz_catch(ctx) { ... }
- }
-
-3) The macros are implemented using setjmp and longjmp, and so the standard
- C restrictions on the use of those functions apply to fz_try/fz_catch
- too. In particular, any "truly local" variable that is set between the
- start of fz_try and something in fz_try throwing an exception may become
- undefined as part of the process of throwing that exception.
-
- As a way of mitigating this problem, we provide an fz_var() macro that
- tells the compiler to ensure that that variable is not unset by the
- act of throwing the exception.
-
-A model piece of code using these macros then might be:
-
- house build_house(plans *p)
- {
- material m = NULL;
- walls w = NULL;
- roof r = NULL;
- house h = NULL;
- tiles t = make_tiles();
-
- fz_var(w);
- fz_var(r);
- fz_var(h);
-
- fz_try(ctx)
- {
- fz_try(ctx)
- {
- m = make_bricks();
- }
- fz_catch(ctx)
- {
- // No bricks available, make do with straw?
- m = make_straw();
- }
- w = make_walls(m, p);
- r = make_roof(m, t);
- h = combine(w, r); // Note, NOT: return combine(w,r);
- }
- fz_always(ctx)
- {
- drop_walls(w);
- drop_roof(r);
- drop_material(m);
- drop_tiles(t);
- }
- fz_catch(ctx)
- {
- fz_throw(ctx, "build_house failed");
- }
- return h;
- }
-
-Things to note about this:
-
-a) If make_tiles throws an exception, this will immediately be handled
- by some higher level exception handler. If it succeeds, t will be
- set before fz_try starts, so there is no need to fz_var(t);
-
-b) We try first off to make some bricks as our building material. If
- this fails, we fall back to straw. If this fails, we'll end up in
- the fz_catch, and the process will fail neatly.
-
-c) We assume in this code that combine takes new reference to both the
- walls and the roof it uses, and therefore that w and r need to be
- cleaned up in all cases.
-
-d) We assume the standard C convention that it is safe to destroy
- NULL things.
-
+ Exception macro definitions. Just treat these as a black box - pay no
+ attention to the man behind the curtain.
*/
-/* Exception macro definitions. Just treat these as a black box - pay no
- * attention to the man behind the curtain. */
-
#define fz_try(ctx) \
if (fz_push_try(ctx->error), \
- (ctx->error->stack[ctx->error->top].code = setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \
+ (ctx->error->stack[ctx->error->top].code = fz_setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \
{ do {
#define fz_always(ctx) \
@@ -285,78 +173,22 @@ d) We assume the standard C convention that it is safe to destroy
} \
if (ctx->error->stack[ctx->error->top--].code)
-/*
-
-We also include a couple of other formulations of the macros, with
-different strengths and weaknesses. These will be removed shortly, but
-I want them in git for at least 1 revision so I have a record of them.
-
-A formulation of try/always/catch that lifts limitation 2 above, but
-has problems when try/catch are nested in the same function; the inner
-nestings need to use fz_always_(ctx, label) and fz_catch_(ctx, label)
-instead. This was held as too high a price to pay to drop limitation 2.
-
-#define fz_try(ctx) \
- if (fz_push_try(ctx->error), \
- (ctx->error->stack[ctx->error->top].code = setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \
- { do {
-
-#define fz_always_(ctx, label) \
- } while (0); \
- goto ALWAYS_LABEL_ ## label ; \
- } \
- else if (ctx->error->stack[ctx->error->top].code) \
- { ALWAYS_LABEL_ ## label : \
- do {
-
-#define fz_catch_(ctx, label) \
- } while(0); \
- if (ctx->error->stack[ctx->error->top--].code) \
- goto CATCH_LABEL_ ## label; \
- } \
- else if (ctx->error->top--, 1) \
- CATCH_LABEL ## label:
-
-#define fz_always(ctx) fz_always_(ctx, TOP)
-#define fz_catch(ctx) fz_catch_(ctx, TOP)
-
-Another alternative formulation, that again removes limitation 2, but at
-the cost of an always block always costing us 1 extra longjmp per
-execution. Again this was felt to be too high a cost to use.
-
-#define fz_try(ctx) \
- if (fz_push_try(ctx->error), \
- (ctx->error->stack[ctx->error->top].code = setjmp(ctx->error->stack[ctx->error->top].buffer)) == 0) \
- { do {
-
-#define fz_always(ctx) \
- } while (0); \
- longjmp(ctx->error->stack[ctx->error->top].buffer, 3); \
- } \
- else if (ctx->error->stack[ctx->error->top].code & 1) \
- { do {
-
-#define fz_catch(ctx) \
- } while(0); \
- if (ctx->error->stack[ctx->error->top].code == 1) \
- longjmp(ctx->error->stack[ctx->error->top].buffer, 2); \
- ctx->error->top--;\
- } \
- else if (ctx->error->top--, 1)
-
-*/
-
void fz_push_try(fz_error_context *ex);
void fz_throw(fz_context *, char *, ...) __printflike(2, 3);
void fz_rethrow(fz_context *);
+void fz_warn(fz_context *ctx, char *fmt, ...) __printflike(2, 3);
-struct fz_warn_context_s
-{
- char message[256];
- int count;
-};
+/*
+ fz_flush_warnings: Flush any repeated warnings.
-void fz_warn(fz_context *ctx, char *fmt, ...) __printflike(2, 3);
+ Repeated warnings are buffered, counted and eventually printed
+ along with the number of repetitions. Call fz_flush_warnings
+ to force printing of the latest buffered warning and the
+ number of repetitions, for example to make sure that all
+ warnings are printed before exiting an application.
+
+ Does not throw exceptions.
+*/
void fz_flush_warnings(fz_context *ctx);
struct fz_context_s
@@ -371,42 +203,118 @@ struct fz_context_s
fz_glyph_cache *glyph_cache;
};
+/*
+ Specifies the maximum size in bytes of the resource store in
+ fz_context. Given as argument to fz_new_context.
+
+ FZ_STORE_UNLIMITED: Let resource store grow unbounded.
+
+ FZ_STORE_DEFAULT: A reasonable upper bound on the size, for
+ devices that are not memory constrained.
+*/
+enum {
+ FZ_STORE_UNLIMITED = 0,
+ FZ_STORE_DEFAULT = 256 << 20,
+};
+
+/*
+ fz_new_context: Allocate context containing global state.
+
+ The global state contains an exception stack, resource store,
+ etc. Most functions in MuPDF take a context argument to be
+ able to reference the global state. See fz_free_context for
+ freeing an allocated context.
+
+ alloc: Supply a custom memory allocator through a set of
+ function pointers. Set to NULL for the standard library
+ allocator. The context will keep the allocator pointer, so the
+ data it points to must not be modified or freed during the
+ lifetime of the context.
+
+ locks: Supply a set of locks and functions to lock/unlock
+ them, intended for multi-threaded applications. Set to NULL
+ when using MuPDF in a single-threaded applications. The
+ context will keep the locks pointer, so the data it points to
+ must not be modified or freed during the lifetime of the
+ context.
+
+ max_store: Maximum size in bytes of the resource store, before
+ it will start evicting cached resources such as fonts and
+ images. FZ_STORE_UNLIMITED can be used if a hard limit is not
+ desired. Use FZ_STORE_DEFAULT to get a reasonable size.
+
+ Does not throw exceptions, but may return NULL.
+*/
fz_context *fz_new_context(fz_alloc_context *alloc, fz_locks_context *locks, unsigned int max_store);
+
+/*
+ fz_clone_context: Make a clone of an existing context.
+
+ This function is meant to be used in multi-threaded
+ applications where each thread requires its own context, yet
+ parts of the global state, for example caching, is shared.
+
+ ctx: Context obtained from fz_new_context to make a copy of.
+ ctx must have had locks and lock/functions setup when created.
+ The two contexts will share the memory allocator, resource
+ store, locks and lock/unlock functions. They will each have
+ their own exception stacks though.
+
+ Does not throw exception, but may return NULL.
+*/
fz_context *fz_clone_context(fz_context *ctx);
-fz_context *fz_clone_context_internal(fz_context *ctx);
+
+/*
+ fz_free_context: Free a context and its global state.
+
+ The context and all of its global state is freed, and any
+ buffered warnings are flushed (see fz_flush_warnings). If NULL
+ is passed in nothing will happen.
+
+ Does not throw exceptions.
+*/
void fz_free_context(fz_context *ctx);
-void fz_new_aa_context(fz_context *ctx);
-void fz_free_aa_context(fz_context *ctx);
-
-/* Locking functions
- *
- * MuPDF is kept deliberately free of any knowledge of particular threading
- * systems. As such, in order for safe multi-threaded operation, we rely on
- * callbacks to client provided functions.
- *
- * A client is expected to provide FZ_LOCK_MAX mutexes, and a function to
- * lock/unlock each of them. These may be recursive mutexes, but do not have
- * to be.
- *
- * If a client does not intend to use multiple threads, then it may pass
- * NULL instead of the address of a lock structure.
- *
- * In order to avoid deadlocks, we have 1 simple rules internally as to how
- * we use locks: We can never take lock n when we already hold any lock i,
- * where 0 <= i <= n. In order to verify this, we have some debugging code
- * built in, that is enabled by defining FITZ_DEBUG_LOCKING.
- */
+/*
+ fz_aa_level: Get the number of bits of antialiasing we are
+ using. Between 0 and 8.
+*/
+int fz_aa_level(fz_context *ctx);
-#if defined(MEMENTO) || defined(DEBUG)
-#define FITZ_DEBUG_LOCKING
-#endif
+/*
+ fz_set_aa_level: Set the number of bits of antialiasing we should use.
+
+ bits: The number of bits of antialiasing to use (values are clamped
+ to within the 0 to 8 range).
+*/
+void fz_set_aa_level(fz_context *ctx, int bits);
+
+/*
+ Locking functions
+
+ MuPDF is kept deliberately free of any knowledge of particular
+ threading systems. As such, in order for safe multi-threaded
+ operation, we rely on callbacks to client provided functions.
+
+ A client is expected to provide FZ_LOCK_MAX number of mutexes,
+ and a function to lock/unlock each of them. These may be
+ recursive mutexes, but do not have to be.
+
+ If a client does not intend to use multiple threads, then it
+ may pass NULL instead of a lock structure.
+
+ In order to avoid deadlocks, we have one simple rule
+ internally as to how we use locks: We can never take lock n
+ when we already hold any lock i, where 0 <= i <= n. In order
+ to verify this, we have some debugging code, that can be
+ enabled by defining FITZ_DEBUG_LOCKING.
+*/
struct fz_locks_context_s
{
void *user;
- void (*lock)(void *, int);
- void (*unlock)(void *, int);
+ void (*lock)(void *user, int lock);
+ void (*unlock)(void *user, int lock);
};
enum {
@@ -417,1076 +325,1257 @@ enum {
FZ_LOCK_MAX
};
-/* Default locks */
-extern fz_locks_context fz_locks_default;
+/*
+ Memory Allocation and Scavenging:
-#ifdef FITZ_DEBUG_LOCKING
+ All calls to MuPDFs allocator functions pass through to the
+ underlying allocators passed in when the initial context is
+ created, after locks are taken (using the supplied locking function)
+ to ensure that only one thread at a time calls through.
-void fz_assert_lock_held(fz_context *ctx, int lock);
-void fz_assert_lock_not_held(fz_context *ctx, int lock);
-void fz_lock_debug_lock(fz_context *ctx, int lock);
-void fz_lock_debug_unlock(fz_context *ctx, int lock);
+ If the underlying allocator fails, MuPDF attempts to make room for
+ the allocation by evicting elements from the store, then retrying.
-#else
+ Any call to allocate may then result in several calls to the underlying
+ allocator, and result in elements that are only referred to by the
+ store being freed.
+*/
-#define fz_assert_lock_held(A,B) do { } while (0)
-#define fz_assert_lock_not_held(A,B) do { } while (0)
-#define fz_lock_debug_lock(A,B) do { } while (0)
-#define fz_lock_debug_unlock(A,B) do { } while (0)
+/*
+ fz_malloc: Allocate a block of memory (with scavenging)
-#endif /* !FITZ_DEBUG_LOCKING */
+ size: The number of bytes to allocate.
-static inline void
-fz_lock(fz_context *ctx, int lock)
-{
- fz_lock_debug_lock(ctx, lock);
- ctx->locks->lock(ctx->locks->user, lock);
-}
+ Returns a pointer to the allocated block. May return NULL if size is
+ 0. Throws exception on failure to allocate.
+*/
+void *fz_malloc(fz_context *ctx, unsigned int size);
-static inline void
-fz_unlock(fz_context *ctx, int lock)
-{
- fz_lock_debug_unlock(ctx, lock);
- ctx->locks->unlock(ctx->locks->user, lock);
-}
+/*
+ fz_calloc: Allocate a zeroed block of memory (with scavenging)
+
+ count: The number of objects to allocate space for.
+ size: The size (in bytes) of each object.
+
+ Returns a pointer to the allocated block. May return NULL if size
+ and/or count are 0. Throws exception on failure to allocate.
+*/
+void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size);
/*
- * Basic runtime and utility functions
- */
+ fz_malloc_array: Allocate a block of (non zeroed) memory (with
+ scavenging). Equivalent to fz_calloc without the memory clearing.
-/* memory allocation */
+ count: The number of objects to allocate space for.
-/* The following throw exceptions on failure to allocate */
-void *fz_malloc(fz_context *ctx, unsigned int size);
-void *fz_calloc(fz_context *ctx, unsigned int count, unsigned int size);
+ size: The size (in bytes) of each object.
+
+ Returns a pointer to the allocated block. May return NULL if size
+ and/or count are 0. Throws exception on failure to allocate.
+*/
void *fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size);
+
+/*
+ fz_resize_array: Resize a block of memory (with scavenging).
+
+ p: The existing block to resize
+
+ count: The number of objects to resize to.
+
+ size: The size (in bytes) of each object.
+
+ Returns a pointer to the resized block. May return NULL if size
+ and/or count are 0. Throws exception on failure to resize (original
+ block is left unchanged).
+*/
void *fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size);
+
+/*
+ fz_strdup: Duplicate a C string (with scavenging)
+
+ s: The string to duplicate.
+
+ Returns a pointer to a duplicated string. Throws exception on failure
+ to allocate.
+*/
char *fz_strdup(fz_context *ctx, char *s);
+/*
+ fz_free: Frees an allocation.
+
+ Does not throw exceptions.
+*/
void fz_free(fz_context *ctx, void *p);
-/* The following returns NULL on failure to allocate */
+/*
+ fz_malloc_no_throw: Allocate a block of memory (with scavenging)
+
+ size: The number of bytes to allocate.
+
+ Returns a pointer to the allocated block. May return NULL if size is
+ 0. Returns NULL on failure to allocate.
+*/
void *fz_malloc_no_throw(fz_context *ctx, unsigned int size);
-void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size);
+
+/*
+ fz_calloc_no_throw: Allocate a zeroed block of memory (with scavenging)
+
+ count: The number of objects to allocate space for.
+
+ size: The size (in bytes) of each object.
+
+ Returns a pointer to the allocated block. May return NULL if size
+ and/or count are 0. Returns NULL on failure to allocate.
+*/
void *fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size);
+
+/*
+ fz_malloc_array_no_throw: Allocate a block of (non zeroed) memory
+ (with scavenging). Equivalent to fz_calloc_no_throw without the
+ memory clearing.
+
+ count: The number of objects to allocate space for.
+
+ size: The size (in bytes) of each object.
+
+ Returns a pointer to the allocated block. May return NULL if size
+ and/or count are 0. Returns NULL on failure to allocate.
+*/
+void *fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size);
+
+/*
+ fz_resize_array_no_throw: Resize a block of memory (with scavenging).
+
+ p: The existing block to resize
+
+ count: The number of objects to resize to.
+
+ size: The size (in bytes) of each object.
+
+ Returns a pointer to the resized block. May return NULL if size
+ and/or count are 0. Returns NULL on failure to resize (original
+ block is left unchanged).
+*/
void *fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned int size);
+
+/*
+ fz_strdup_no_throw: Duplicate a C string (with scavenging)
+
+ s: The string to duplicate.
+
+ Returns a pointer to a duplicated string. Returns NULL on failure
+ to allocate.
+*/
char *fz_strdup_no_throw(fz_context *ctx, char *s);
-/* alloc and zero a struct, and tag it for memento */
-#define fz_malloc_struct(CTX, STRUCT) \
- Memento_label(fz_calloc(CTX,1,sizeof(STRUCT)), #STRUCT)
+/*
+ Safe string functions
+*/
+/*
+ fz_strsep: Given a pointer to a C string (or a pointer to NULL) break
+ it at the first occurence of a delimiter char (from a given set).
-/* runtime (hah!) test for endian-ness */
-int fz_is_big_endian(void);
+ stringp: Pointer to a C string pointer (or NULL). Updated on exit to
+ point to the first char of the string after the delimiter that was
+ found. The string pointed to by stringp will be corrupted by this
+ call (as the found delimiter will be overwritten by 0).
-/* safe string functions */
+ delim: A C string of acceptable delimiter characters.
+
+ Returns a pointer to a C string containing the chars of stringp up
+ to the first delimiter char (or the end of the string), or NULL.
+*/
char *fz_strsep(char **stringp, const char *delim);
-int fz_strlcpy(char *dst, const char *src, int n);
-int fz_strlcat(char *dst, const char *src, int n);
-/* Range checking atof */
-float fz_atof(const char *s);
+/*
+ fz_strlcpy: Copy at most n-1 chars of a string into a destination
+ buffer with null termination, returning the real length of the
+ initial string (excluding terminator).
-/* utf-8 encoding and decoding */
-int chartorune(int *rune, char *str);
-int runetochar(char *str, int *rune);
-int runelen(int c);
+ dst: Destination buffer, at least n bytes long.
-/* getopt */
-extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
-extern int fz_optind;
-extern char *fz_optarg;
+ src: C string (non-NULL).
+
+ n: Size of dst buffer in bytes.
+
+ Returns the length (excluding terminator) of src.
+*/
+int fz_strlcpy(char *dst, const char *src, int n);
/*
- * Generic hash-table with fixed-length keys.
- */
+ fz_strlcat: Concatenate 2 strings, with a maximum length.
-typedef struct fz_hash_table_s fz_hash_table;
+ dst: pointer to first string in a buffer of n bytes.
-fz_hash_table *fz_new_hash_table(fz_context *ctx, int initialsize, int keylen);
-void fz_debug_hash(fz_context *ctx, fz_hash_table *table);
-void fz_empty_hash(fz_context *ctx, fz_hash_table *table);
-void fz_free_hash(fz_context *ctx, fz_hash_table *table);
+ src: pointer to string to concatenate.
-void *fz_hash_find(fz_context *ctx, fz_hash_table *table, void *key);
-void *fz_hash_insert(fz_context *ctx, fz_hash_table *table, void *key, void *val);
-void fz_hash_remove(fz_context *ctx, fz_hash_table *table, void *key);
+ n: Size (in bytes) of buffer that dst is in.
-int fz_hash_len(fz_context *ctx, fz_hash_table *table);
-void *fz_hash_get_key(fz_context *ctx, fz_hash_table *table, int idx);
-void *fz_hash_get_val(fz_context *ctx, fz_hash_table *table, int idx);
+ Returns the real length that a concatenated dst + src would have been
+ (not including terminator).
+*/
+int fz_strlcat(char *dst, const char *src, int n);
/*
- * Math and geometry
- */
+ fz_chartorune: UTF8 decode a string of chars to a rune.
-/* Multiply scaled two integers in the 0..255 range */
-static inline int fz_mul255(int a, int b)
-{
- /* see Jim Blinn's book "Dirty Pixels" for how this works */
- int x = a * b + 128;
- x += x >> 8;
- return x >> 8;
-}
+ rune: Pointer to an int to assign the decoded 'rune' to.
-/* Expand a value A from the 0...255 range to the 0..256 range */
-#define FZ_EXPAND(A) ((A)+((A)>>7))
+ str: Pointer to a UTF8 encoded string
-/* Combine values A (in any range) and B (in the 0..256 range),
- * to give a single value in the same range as A was. */
-#define FZ_COMBINE(A,B) (((A)*(B))>>8)
+ Returns the number of bytes consumed. Does not throw exceptions.
+*/
+int fz_chartorune(int *rune, char *str);
-/* Combine values A and C (in the same (any) range) and B and D (in the
- * 0..256 range), to give a single value in the same range as A and C were. */
-#define FZ_COMBINE2(A,B,C,D) (FZ_COMBINE((A), (B)) + FZ_COMBINE((C), (D)))
+/*
+ runetochar: UTF8 encode a run to a string of chars.
-/* Blend SRC and DST (in the same range) together according to
- * AMOUNT (in the 0...256 range). */
-#define FZ_BLEND(SRC, DST, AMOUNT) ((((SRC)-(DST))*(AMOUNT) + ((DST)<<8))>>8)
+ str: Pointer to a place to put the UTF8 encoded string.
-typedef struct fz_matrix_s fz_matrix;
-typedef struct fz_point_s fz_point;
-typedef struct fz_rect_s fz_rect;
-typedef struct fz_bbox_s fz_bbox;
+ rune: Pointer to a 'rune'.
-extern const fz_rect fz_unit_rect;
-extern const fz_rect fz_empty_rect;
-extern const fz_rect fz_infinite_rect;
+ Returns the number of bytes the rune took to output. Does not throw
+ exceptions.
+*/
+int fz_runetochar(char *str, int rune);
-extern const fz_bbox fz_unit_bbox;
-extern const fz_bbox fz_empty_bbox;
-extern const fz_bbox fz_infinite_bbox;
+/*
+ fz_runelen: Count many chars are required to represent a rune.
-#define fz_is_empty_rect(r) ((r).x0 == (r).x1)
-#define fz_is_infinite_rect(r) ((r).x0 > (r).x1)
-#define fz_is_empty_bbox(b) ((b).x0 == (b).x1)
-#define fz_is_infinite_bbox(b) ((b).x0 > (b).x1)
+ rune: The rune to encode.
-struct fz_matrix_s
-{
- float a, b, c, d, e, f;
-};
+ Returns the number of bytes required to represent this run in UTF8.
+*/
+int fz_runelen(int rune);
+/* getopt */
+extern int fz_getopt(int nargc, char * const *nargv, const char *ostr);
+extern int fz_optind;
+extern char *fz_optarg;
+
+/*
+ fz_point is a point in a two-dimensional space.
+*/
+typedef struct fz_point_s fz_point;
struct fz_point_s
{
float x, y;
};
+/*
+ fz_rect is a rectangle represented by two diagonally opposite
+ corners at arbitrary coordinates.
+
+ Rectangles are always axis-aligned with the X- and Y- axes.
+ The relationship between the coordinates are that x0 <= x1 and
+ y0 <= y1 in all cases except for infinte rectangles. The area
+ of a rectangle is defined as (x1 - x0) * (y1 - y0). If either
+ x0 > x1 or y0 > y1 is true for a given rectangle then it is
+ defined to be infinite.
+
+ To check for empty or infinite rectangles use fz_is_empty_rect
+ and fz_is_infinite_rect. Compare to fz_bbox which has corners
+ at integer coordinates.
+
+ x0, y0: The top left corner.
+
+ x1, y1: The botton right corner.
+*/
+typedef struct fz_rect_s fz_rect;
struct fz_rect_s
{
float x0, y0;
float x1, y1;
};
+/*
+ fz_bbox is a bounding box similar to a fz_rect, except that
+ all corner coordinates are rounded to integer coordinates.
+ To check for empty or infinite bounding boxes use
+ fz_is_empty_bbox and fz_is_infinite_bbox.
+
+ x0, y0: The top left corner.
+
+ x1, y1: The bottom right corner.
+*/
+typedef struct fz_bbox_s fz_bbox;
struct fz_bbox_s
{
int x0, y0;
int x1, y1;
};
+/*
+ A rectangle with sides of length one.
+
+ The bottom left corner is at (0, 0) and the top right corner
+ is at (1, 1).
+*/
+extern const fz_rect fz_unit_rect;
+
+/*
+ A bounding box with sides of length one. See fz_unit_rect.
+*/
+extern const fz_bbox fz_unit_bbox;
+
+/*
+ An empty rectangle with an area equal to zero.
+
+ Both the top left and bottom right corner are at (0, 0).
+*/
+extern const fz_rect fz_empty_rect;
+
+/*
+ An empty bounding box. See fz_empty_rect.
+*/
+extern const fz_bbox fz_empty_bbox;
+
+/*
+ An infinite rectangle with negative area.
+
+ The corner (x0, y0) is at (1, 1) while the corner (x1, y1) is
+ at (-1, -1).
+*/
+extern const fz_rect fz_infinite_rect;
+
+/*
+ An infinite bounding box. See fz_infinite_rect.
+*/
+extern const fz_bbox fz_infinite_bbox;
+
+/*
+ fz_is_empty_rect: Check if rectangle is empty.
+
+ An empty rectangle is defined as one whose area is zero.
+*/
+#define fz_is_empty_rect(r) ((r).x0 == (r).x1 || (r).y0 == (r).y1)
+
+/*
+ fz_is_empty_bbox: Check if bounding box is empty.
+
+ Same definition of empty bounding boxes as for empty
+ rectangles. See fz_is_empty_rect.
+*/
+#define fz_is_empty_bbox(b) ((b).x0 == (b).x1 || (b).y0 == (b).y1)
+
+/*
+ fz_is_infinite: Check if rectangle is infinite.
+
+ An infinite rectangle is defined as one where either of the
+ two relationships between corner coordinates are not true.
+*/
+#define fz_is_infinite_rect(r) ((r).x0 > (r).x1 || (r).y0 > (r).y1)
+
+/*
+ fz_is_infinite_bbox: Check if bounding box is infinite.
+
+ Same definition of infinite bounding boxes as for infinite
+ rectangles. See fz_is_infinite_rect.
+*/
+#define fz_is_infinite_bbox(b) ((b).x0 > (b).x1 || (b).y0 > (b).y1)
+
+/*
+ fz_matrix is a a row-major 3x3 matrix used for representing
+ transformations of coordinates throughout MuPDF.
+
+ Since all points reside in a two-dimensional space, one vector
+ is always a constant unit vector; hence only some elements may
+ vary in a matrix. Below is how the elements map between
+ different representations.
+
+ / a b 0 \
+ | c d 0 | normally represented as [ a b c d e f ].
+ \ e f 1 /
+*/
+typedef struct fz_matrix_s fz_matrix;
+struct fz_matrix_s
+{
+ float a, b, c, d, e, f;
+};
+
+
+/*
+ fz_identity: Identity transform matrix.
+*/
extern const fz_matrix fz_identity;
-fz_matrix fz_concat(fz_matrix one, fz_matrix two);
+/*
+ fz_concat: Multiply two matrices.
+
+ The order of the two matrices are important since matrix
+ multiplication is not commutative.
+
+ Does not throw exceptions.
+*/
+fz_matrix fz_concat(fz_matrix left, fz_matrix right);
+
+/*
+ fz_scale: Create a scaling matrix.
+
+ The returned matrix is of the form [ sx 0 0 sy 0 0 ].
+
+ sx, sy: Scaling factors along the X- and Y-axes. A scaling
+ factor of 1.0 will not cause any scaling along the relevant
+ axis.
+
+ Does not throw exceptions.
+*/
fz_matrix fz_scale(float sx, float sy);
+
+/*
+ fz_shear: Create a shearing matrix.
+
+ The returned matrix is of the form [ 1 sy sx 1 0 0 ].
+
+ sx, sy: Shearing factors. A shearing factor of 0.0 will not
+ cause any shearing along the relevant axis.
+
+ Does not throw exceptions.
+*/
fz_matrix fz_shear(float sx, float sy);
-fz_matrix fz_rotate(float theta);
+
+/*
+ fz_rotate: Create a rotation matrix.
+
+ The returned matrix is of the form
+ [ cos(deg) sin(deg) -sin(deg) cos(deg) 0 0 ].
+
+ degrees: Degrees of counter clockwise rotation. Values less
+ than zero and greater than 360 are handled as expected.
+
+ Does not throw exceptions.
+*/
+fz_matrix fz_rotate(float degrees);
+
+/*
+ fz_translate: Create a translation matrix.
+
+ The returned matrix is of the form [ 1 0 0 1 tx ty ].
+
+ tx, ty: Translation distances along the X- and Y-axes. A
+ translation of 0 will not cause any translation along the
+ relevant axis.
+
+ Does not throw exceptions.
+*/
fz_matrix fz_translate(float tx, float ty);
-fz_matrix fz_invert_matrix(fz_matrix m);
+
+/*
+ fz_invert_matrix: Create an inverse matrix.
+
+ matrix: Matrix to invert. A degenerate matrix, where the
+ determinant is equal to zero, can not be inverted and the
+ original matrix is returned instead.
+
+ Does not throw exceptions.
+*/
+fz_matrix fz_invert_matrix(fz_matrix matrix);
+
+/*
+ fz_is_rectilinear: Check if a transformation is rectilinear.
+
+ Rectilinear means that no shearing is present and that any
+ rotations present are a multiple of 90 degrees. Usually this
+ is used to make sure that axis-aligned rectangles before the
+ transformation are still axis-aligned rectangles afterwards.
+
+ Does not throw exceptions.
+*/
int fz_is_rectilinear(fz_matrix m);
-float fz_matrix_expansion(fz_matrix m);
-float fz_matrix_max_expansion(fz_matrix m);
-fz_bbox fz_round_rect(fz_rect r);
-fz_bbox fz_intersect_bbox(fz_bbox a, fz_bbox b);
-fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
-fz_bbox fz_union_bbox(fz_bbox a, fz_bbox b);
-fz_rect fz_union_rect(fz_rect a, fz_rect b);
+/*
+ fz_matrix_expansion: Calculate average scaling factor of matrix.
+*/
+float fz_matrix_expansion(fz_matrix m); /* sumatrapdf */
+
+/*
+ fz_round_rect: Convert a rect into a bounding box.
-fz_point fz_transform_point(fz_matrix m, fz_point p);
-fz_point fz_transform_vector(fz_matrix m, fz_point p);
-fz_rect fz_transform_rect(fz_matrix m, fz_rect r);
-fz_bbox fz_transform_bbox(fz_matrix m, fz_bbox b);
+ Coordinates in a bounding box are integers, so rounding of the
+ rects coordinates takes place. The top left corner is rounded
+ upwards and left while the bottom right corner is rounded
+ downwards and to the right. Overflows or underflowing
+ coordinates are clamped to INT_MIN/INT_MAX.
-void fz_gridfit_matrix(fz_matrix *m);
+ Does not throw exceptions.
+*/
+fz_bbox fz_round_rect(fz_rect rect);
/*
- * Basic crypto functions.
- * Independent of the rest of fitz.
- * For further encapsulation in filters, or not.
- */
+ fz_intersect_rect: Compute intersection of two rectangles.
-/* md5 digests */
+ Compute the largest axis-aligned rectangle that covers the
+ area covered by both given rectangles. If either rectangle is
+ empty then the intersection is also empty. If either rectangle
+ is infinite then the intersection is simply the non-infinite
+ rectangle. Should both rectangles be infinite, then the
+ intersection is also infinite.
-typedef struct fz_md5_s fz_md5;
+ Does not throw exceptions.
+*/
+fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
-struct fz_md5_s
-{
- unsigned int state[4];
- unsigned int count[2];
- unsigned char buffer[64];
-};
+/*
+ fz_intersect_bbox: Compute intersection of two bounding boxes.
-void fz_md5_init(fz_md5 *state);
-void fz_md5_update(fz_md5 *state, const unsigned char *input, unsigned inlen);
-void fz_md5_final(fz_md5 *state, unsigned char digest[16]);
+ Similar to fz_intersect_rect but operates on two bounding
+ boxes instead of two rectangles.
-/* sha-256 digests */
+ Does not throw exceptions.
+*/
+fz_bbox fz_intersect_bbox(fz_bbox a, fz_bbox b);
-typedef struct fz_sha256_s fz_sha256;
+/*
+ fz_union_rect: Compute union of two rectangles.
-struct fz_sha256_s
-{
- unsigned int state[8];
- unsigned int count[2];
- union {
- unsigned char u8[64];
- unsigned int u32[16];
- } buffer;
-};
+ Compute the smallest axis-aligned rectangle that encompasses
+ both given rectangles. If either rectangle is infinite then
+ the union is also infinite. If either rectangle is empty then
+ the union is simply the non-empty rectangle. Should both
+ rectangles be empty, then the union is also empty.
-void fz_sha256_init(fz_sha256 *state);
-void fz_sha256_update(fz_sha256 *state, const unsigned char *input, unsigned int inlen);
-void fz_sha256_final(fz_sha256 *state, unsigned char digest[32]);
+ Does not throw exceptions.
+*/
+fz_rect fz_union_rect(fz_rect a, fz_rect b);
-/* arc4 crypto */
+/*
+ fz_union_bbox: Compute union of two bounding boxes.
-typedef struct fz_arc4_s fz_arc4;
+ Similar to fz_union_rect but operates on two bounding boxes
+ instead of two rectangles.
-struct fz_arc4_s
-{
- unsigned x;
- unsigned y;
- unsigned char state[256];
-};
+ Does not throw exceptions.
+*/
+fz_bbox fz_union_bbox(fz_bbox a, fz_bbox b);
-void fz_arc4_init(fz_arc4 *state, const unsigned char *key, unsigned len);
-void fz_arc4_encrypt(fz_arc4 *state, unsigned char *dest, const unsigned char *src, unsigned len);
+/*
+ fz_transform_point: Apply a transformation to a point.
-/* AES block cipher implementation from XYSSL */
+ transform: Transformation matrix to apply. See fz_concat,
+ fz_scale, fz_rotate and fz_translate for how to create a
+ matrix.
-typedef struct fz_aes_s fz_aes;
+ Does not throw exceptions.
+*/
+fz_point fz_transform_point(fz_matrix transform, fz_point point);
-#define AES_DECRYPT 0
-#define AES_ENCRYPT 1
+/*
+ fz_transform_vector: Apply a transformation to a vector.
-struct fz_aes_s
-{
- int nr; /* number of rounds */
- unsigned long *rk; /* AES round keys */
- unsigned long buf[68]; /* unaligned data */
-};
+ transform: Transformation matrix to apply. See fz_concat,
+ fz_scale and fz_rotate for how to create a matrix. Any
+ translation will be ignored.
-void aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize );
-void aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize );
-void aes_crypt_cbc( fz_aes *ctx, int mode, int length,
- unsigned char iv[16],
- const unsigned char *input,
- unsigned char *output );
+ Does not throw exceptions.
+*/
+fz_point fz_transform_vector(fz_matrix transform, fz_point vector);
/*
- * Dynamic objects.
- * The same type of objects as found in PDF and PostScript.
- * Used by the filters and the mupdf parser.
- */
+ fz_transform_rect: Apply a transform to a rectangle.
-typedef struct fz_obj_s fz_obj;
-
-extern fz_obj *(*fz_resolve_indirect)(fz_obj *obj);
-
-fz_obj *fz_new_null(fz_context *ctx);
-fz_obj *fz_new_bool(fz_context *ctx, int b);
-fz_obj *fz_new_int(fz_context *ctx, int i);
-fz_obj *fz_new_real(fz_context *ctx, float f);
-fz_obj *fz_new_name(fz_context *ctx, char *str);
-fz_obj *fz_new_string(fz_context *ctx, char *str, int len);
-fz_obj *fz_new_indirect(fz_context *ctx, int num, int gen, void *doc);
-
-fz_obj *fz_new_array(fz_context *ctx, int initialcap);
-fz_obj *fz_new_dict(fz_context *ctx, int initialcap);
-fz_obj *fz_copy_array(fz_context *ctx, fz_obj *array);
-fz_obj *fz_copy_dict(fz_context *ctx, fz_obj *dict);
-
-fz_obj *fz_keep_obj(fz_obj *obj);
-void fz_drop_obj(fz_obj *obj);
-
-/* type queries */
-int fz_is_null(fz_obj *obj);
-int fz_is_bool(fz_obj *obj);
-int fz_is_int(fz_obj *obj);
-int fz_is_real(fz_obj *obj);
-int fz_is_name(fz_obj *obj);
-int fz_is_string(fz_obj *obj);
-int fz_is_array(fz_obj *obj);
-int fz_is_dict(fz_obj *obj);
-int fz_is_indirect(fz_obj *obj);
-
-int fz_objcmp(fz_obj *a, fz_obj *b);
-
-/* dict marking and unmarking functions - to avoid infinite recursions */
-int fz_dict_marked(fz_obj *obj);
-int fz_dict_mark(fz_obj *obj);
-void fz_dict_unmark(fz_obj *obj);
-
-/* safe, silent failure, no error reporting on type mismatches */
-int fz_to_bool(fz_obj *obj);
-int fz_to_int(fz_obj *obj);
-float fz_to_real(fz_obj *obj);
-char *fz_to_name(fz_obj *obj);
-char *fz_to_str_buf(fz_obj *obj);
-fz_obj *fz_to_dict(fz_obj *obj);
-int fz_to_str_len(fz_obj *obj);
-int fz_to_num(fz_obj *obj);
-int fz_to_gen(fz_obj *obj);
-
-int fz_array_len(fz_obj *array);
-fz_obj *fz_array_get(fz_obj *array, int i);
-void fz_array_put(fz_obj *array, int i, fz_obj *obj);
-void fz_array_push(fz_obj *array, fz_obj *obj);
-void fz_array_insert(fz_obj *array, fz_obj *obj);
-int fz_array_contains(fz_obj *array, fz_obj *obj);
-
-int fz_dict_len(fz_obj *dict);
-fz_obj *fz_dict_get_key(fz_obj *dict, int idx);
-fz_obj *fz_dict_get_val(fz_obj *dict, int idx);
-fz_obj *fz_dict_get(fz_obj *dict, fz_obj *key);
-fz_obj *fz_dict_gets(fz_obj *dict, char *key);
-fz_obj *fz_dict_getsa(fz_obj *dict, char *key, char *abbrev);
-void fz_dict_put(fz_obj *dict, fz_obj *key, fz_obj *val);
-void fz_dict_puts(fz_obj *dict, char *key, fz_obj *val);
-void fz_dict_del(fz_obj *dict, fz_obj *key);
-void fz_dict_dels(fz_obj *dict, char *key);
-void fz_sort_dict(fz_obj *dict);
-
-int fz_fprint_obj(FILE *fp, fz_obj *obj, int tight);
-void fz_debug_obj(fz_obj *obj);
-void fz_debug_ref(fz_obj *obj);
-
-void fz_set_str_len(fz_obj *obj, int newlen); /* private */
-void *fz_get_indirect_document(fz_obj *obj); /* private */
-
-/*
- * Data buffers.
- */
+ After the four corner points of the axis-aligned rectangle
+ have been transformed it may not longer be axis-aligned. So a
+ new axis-aligned rectangle is created covering at least the
+ area of the transformed rectangle.
+ transform: Transformation matrix to apply. See fz_concat,
+ fz_scale and fz_rotate for how to create a matrix.
+
+ rect: Rectangle to be transformed. The two special cases
+ fz_empty_rect and fz_infinite_rect, may be used but are
+ returned unchanged as expected.
+
+ Does not throw exceptions.
+*/
+fz_rect fz_transform_rect(fz_matrix transform, fz_rect rect);
+
+/*
+ fz_transform_bbox: Transform a given bounding box.
+
+ Similar to fz_transform_rect, but operates on a bounding box
+ instead of a rectangle.
+
+ Does not throw exceptions.
+*/
+fz_bbox fz_transform_bbox(fz_matrix matrix, fz_bbox bbox);
+
+/*
+ fz_buffer is a wrapper around a dynamically allocated array of bytes.
+
+ Buffers have a capacity (the number of bytes storage immediately
+ available) and a current size.
+*/
typedef struct fz_buffer_s fz_buffer;
-struct fz_buffer_s
-{
- int refs;
- unsigned char *data;
- int cap, len;
-};
+/*
+ fz_keep_buffer: Increment the reference count for a buffer.
-fz_buffer *fz_new_buffer(fz_context *ctx, int size);
+ buf: The buffer to increment the reference count for.
+
+ Returns a pointer to the buffer. Does not throw exceptions.
+*/
fz_buffer *fz_keep_buffer(fz_context *ctx, fz_buffer *buf);
+
+/*
+ fz_drop_buffer: Decrement the reference count for a buffer.
+
+ buf: The buffer to decrement the reference count for.
+*/
void fz_drop_buffer(fz_context *ctx, fz_buffer *buf);
-void fz_resize_buffer(fz_context *ctx, fz_buffer *buf, int size);
-void fz_grow_buffer(fz_context *ctx, fz_buffer *buf);
+/*
+ fz_buffer_storage: Retrieve information on the storage currently used
+ by a buffer.
+
+ data: Pointer to place to retrieve data pointer.
+
+ Returns length of stream.
+*/
+int fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **data);
/*
- * Resource store
- */
+ fz_stream is a buffered reader capable of seeking in both
+ directions.
-typedef struct fz_storable_s fz_storable;
+ Streams are reference counted, so references must be dropped
+ by a call to fz_close.
-typedef struct fz_item_s fz_item;
+ Only the data between rp and wp is valid.
+*/
+typedef struct fz_stream_s fz_stream;
-typedef void (fz_store_free_fn)(fz_context *, fz_storable *);
+/*
+ fz_open_file: Open the named file and wrap it in a stream.
-struct fz_storable_s {
- int refs;
- fz_store_free_fn *free;
-};
+ filename: Path to a file as it would be given to open(2).
+*/
+fz_stream *fz_open_file(fz_context *ctx, const char *filename);
-#define FZ_INIT_STORABLE(S_,RC,FREE) \
- do { fz_storable *S = &(S_)->storable; S->refs = (RC); \
- S->free = (FREE); \
- } while (0)
+/*
+ fz_open_file_w: Open the named file and wrap it in a stream.
-enum {
- FZ_STORE_UNLIMITED = 0,
- FZ_STORE_DEFAULT = 256 << 20,
-};
+ This function is only available when compiling for Win32.
-void fz_new_store_context(fz_context *ctx, unsigned int max);
-void fz_drop_store_context(fz_context *ctx);
-fz_store *fz_store_keep(fz_context *ctx);
-void fz_debug_store(fz_context *ctx);
+ filename: Wide character path to the file as it would be given
+ to _wopen().
+*/
+fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename);
-void *fz_keep_storable(fz_context *, fz_storable *);
-void fz_drop_storable(fz_context *, fz_storable *);
+/*
+ fz_open_fd: Wrap an open file descriptor in a stream.
-void fz_store_item(fz_context *ctx, fz_obj *key, void *val, unsigned int itemsize);
-void *fz_find_item(fz_context *ctx, fz_store_free_fn *freefn, fz_obj *key);
-void fz_remove_item(fz_context *ctx, fz_store_free_fn *freefn, fz_obj *key);
-void fz_empty_store(fz_context *ctx);
-int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase);
+ file: An open file descriptor supporting bidirectional
+ seeking. The stream will take ownership of the file
+ descriptor, so it may not be modified or closed after the call
+ to fz_open_fd. When the stream is closed it will also close
+ the file descriptor.
+*/
+fz_stream *fz_open_fd(fz_context *ctx, int file);
/*
- * Buffered reader.
- * Only the data between rp and wp is valid data.
- */
+ fz_open_memory: Open a block of memory as a stream.
-typedef struct fz_stream_s fz_stream;
+ data: Pointer to start of data block. Ownership of the data block is
+ NOT passed in.
-struct fz_stream_s
-{
- fz_context *ctx;
- int refs;
- int error;
- int eof;
- int pos;
- int avail;
- int bits;
- int locked;
- unsigned char *bp, *rp, *wp, *ep;
- void *state;
- int (*read)(fz_stream *stm, unsigned char *buf, int len);
- void (*close)(fz_context *ctx, void *state);
- void (*seek)(fz_stream *stm, int offset, int whence);
- unsigned char buf[4096];
-};
+ len: Number of bytes in data block.
-fz_stream *fz_open_fd(fz_context *ctx, int file);
-fz_stream *fz_open_file(fz_context *ctx, const char *filename);
-fz_stream *fz_open_file_w(fz_context *ctx, const wchar_t *filename); /* only on win32 */
-fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
+ Returns pointer to newly created stream. May throw exceptions on
+ failure to allocate.
+*/
fz_stream *fz_open_memory(fz_context *ctx, unsigned char *data, int len);
-void fz_close(fz_stream *stm);
-void fz_lock_stream(fz_stream *stm);
-fz_stream *fz_new_stream(fz_context *ctx, void*, int(*)(fz_stream*, unsigned char*, int), void(*)(fz_context *, void *));
-fz_stream *fz_keep_stream(fz_stream *stm);
-void fz_fill_buffer(fz_stream *stm);
+/*
+ fz_open_buffer: Open a buffer as a stream.
+
+ buf: The buffer to open. Ownership of the buffer is NOT passed in
+ (this function takes it's own reference).
+ Returns pointer to newly created stream. May throw exceptions on
+ failure to allocate.
+*/
+fz_stream *fz_open_buffer(fz_context *ctx, fz_buffer *buf);
+
+/*
+ fz_close: Close an open stream.
+
+ Drops a reference for the stream. Once no references remain
+ the stream will be closed, as will any file descriptor the
+ stream is using.
+
+ Does not throw exceptions.
+*/
+void fz_close(fz_stream *stm);
+
+/*
+ fz_tell: return the current reading position within a stream
+*/
int fz_tell(fz_stream *stm);
+
+/*
+ fz_seek: Seek within a stream.
+
+ stm: The stream to seek within.
+
+ offset: The offset to seek to.
+
+ whence: From where the offset is measured (see fseek).
+*/
void fz_seek(fz_stream *stm, int offset, int whence);
-int fz_read(fz_stream *stm, unsigned char *buf, int len);
-void fz_read_line(fz_stream *stm, char *buf, int max);
-fz_buffer *fz_read_all(fz_stream *stm, int initial);
+/*
+ fz_read: Read from a stream into a given data block.
-static inline int fz_read_byte(fz_stream *stm)
-{
- if (stm->rp == stm->wp)
- {
- fz_fill_buffer(stm);
- return stm->rp < stm->wp ? *stm->rp++ : EOF;
- }
- return *stm->rp++;
-}
+ stm: The stream to read from.
-static inline int fz_peek_byte(fz_stream *stm)
-{
- if (stm->rp == stm->wp)
- {
- fz_fill_buffer(stm);
- return stm->rp < stm->wp ? *stm->rp : EOF;
- }
- return *stm->rp;
-}
+ data: The data block to read into.
-static inline void fz_unread_byte(fz_stream *stm)
-{
- if (stm->rp > stm->bp)
- stm->rp--;
-}
+ len: The length of the data block (in bytes).
-static inline int fz_is_eof(fz_stream *stm)
-{
- if (stm->rp == stm->wp)
- {
- if (stm->eof)
- return 1;
- return fz_peek_byte(stm) == EOF;
- }
- return 0;
-}
+ Returns the number of bytes read. May throw exceptions.
+*/
+int fz_read(fz_stream *stm, unsigned char *data, int len);
-static inline unsigned int fz_read_bits(fz_stream *stm, int n)
-{
- unsigned int x;
+/*
+ fz_read_all: Read all of a stream into a buffer.
- if (n <= stm->avail)
- {
- stm->avail -= n;
- x = (stm->bits >> stm->avail) & ((1 << n) - 1);
- }
- else
- {
- x = stm->bits & ((1 << stm->avail) - 1);
- n -= stm->avail;
- stm->avail = 0;
+ stm: The stream to read from
- while (n > 8)
- {
- x = (x << 8) | fz_read_byte(stm);
- n -= 8;
- }
+ initial: Suggested initial size for the buffer.
- if (n > 0)
- {
- stm->bits = fz_read_byte(stm);
- stm->avail = 8 - n;
- x = (x << n) | (stm->bits >> stm->avail);
- }
- }
+ Returns a buffer created from reading from the stream. May throw
+ exceptions on failure to allocate.
+*/
+fz_buffer *fz_read_all(fz_stream *stm, int initial);
- return x;
-}
+/*
+ Bitmaps have 1 bit per component. Only used for creating halftoned
+ versions of contone buffers, and saving out. Samples are stored msb
+ first, akin to pbms.
+*/
+typedef struct fz_bitmap_s fz_bitmap;
-static inline void fz_sync_bits(fz_stream *stm)
-{
- stm->avail = 0;
-}
+/*
+ fz_keep_bitmap: Take a reference to a bitmap.
-static inline int fz_is_eof_bits(fz_stream *stm)
-{
- return fz_is_eof(stm) && (stm->avail == 0 || stm->bits == EOF);
-}
+ bit: The bitmap to increment the reference for.
+
+ Returns bit. Does not throw exceptions.
+*/
+fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit);
/*
- * Data filters.
- */
+ fz_drop_bitmap: Drop a reference and free a bitmap.
-fz_stream *fz_open_copy(fz_stream *chain);
-fz_stream *fz_open_null(fz_stream *chain, int len);
-fz_stream *fz_open_arc4(fz_stream *chain, unsigned char *key, unsigned keylen);
-fz_stream *fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen);
-fz_stream *fz_open_a85d(fz_stream *chain);
-fz_stream *fz_open_ahxd(fz_stream *chain);
-fz_stream *fz_open_rld(fz_stream *chain);
-fz_stream *fz_open_dctd(fz_stream *chain, int color_transform);
-fz_stream *fz_open_faxd(fz_stream *chain,
- int k, int end_of_line, int encoded_byte_align,
- int columns, int rows, int end_of_block, int black_is_1);
-fz_stream *fz_open_flated(fz_stream *chain);
-fz_stream *fz_open_lzwd(fz_stream *chain, int early_change);
-fz_stream *fz_open_predict(fz_stream *chain, int predictor, int columns, int colors, int bpc);
-fz_stream *fz_open_jbig2d(fz_stream *chain, fz_buffer *global);
-
-/*
- * Resources and other graphics related objects.
- */
+ Decrement the reference count for the bitmap. When no
+ references remain the pixmap will be freed.
-enum { FZ_MAX_COLORS = 32 };
+ Does not throw exceptions.
+*/
+void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit);
-int fz_find_blendmode(char *name);
-char *fz_blendmode_name(int blendmode);
+/*
+ An fz_colorspace object represents an abstract colorspace. While
+ this should be treated as a black box by callers of the library at
+ this stage, know that it encapsulates knowledge of how to convert
+ colors to and from the colorspace, any lookup tables generated, the
+ number of components in the colorspace etc.
+*/
+typedef struct fz_colorspace_s fz_colorspace;
/*
- * Pixmaps have n components per pixel. the last is always alpha.
- * premultiplied alpha when rendering, but non-premultiplied for colorspace
- * conversions and rescaling.
- */
+ fz_find_device_colorspace: Find a standard colorspace based upon
+ it's name.
+*/
+fz_colorspace *fz_find_device_colorspace(fz_context *ctx, char *name);
+/*
+ fz_device_gray: Abstract colorspace representing device specific
+ gray.
+*/
+extern fz_colorspace *fz_device_gray;
+
+/*
+ fz_device_rgb: Abstract colorspace representing device specific
+ rgb.
+*/
+extern fz_colorspace *fz_device_rgb;
+
+/*
+ fz_device_bgr: Abstract colorspace representing device specific
+ bgr.
+*/
+extern fz_colorspace *fz_device_bgr;
+
+/*
+ fz_device_cmyk: Abstract colorspace representing device specific
+ CMYK.
+*/
+extern fz_colorspace *fz_device_cmyk;
+
+/*
+ Pixmaps represent a set of pixels for a 2 dimensional region of a
+ plane. Each pixel has n components per pixel, the last of which is
+ always alpha. The data is in premultiplied alpha when rendering, but
+ non-premultiplied for colorspace conversions and rescaling.
+*/
typedef struct fz_pixmap_s fz_pixmap;
-typedef struct fz_colorspace_s fz_colorspace;
-struct fz_pixmap_s
-{
- fz_storable storable;
- int x, y, w, h, n;
- fz_pixmap *mask; /* explicit soft/image mask */
- int interpolate;
- int xres, yres;
- fz_colorspace *colorspace;
- unsigned char *samples;
- int free_samples;
-};
+/*
+ fz_pixmap_bbox: Return a bounding box for a pixmap.
-fz_bbox fz_bound_pixmap(fz_pixmap *pix);
+ Returns an exact bounding box for the supplied pixmap.
+*/
+fz_bbox fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix);
-fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples);
-fz_pixmap *fz_new_pixmap_with_rect(fz_context *ctx, fz_colorspace *, fz_bbox bbox);
-fz_pixmap *fz_new_pixmap_with_rect_and_data(fz_context *ctx, fz_colorspace *, fz_bbox bbox, unsigned char *samples);
-fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *, int w, int h);
-fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix);
-void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix);
-void fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix);
-void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix);
-void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
-void fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *pix, int value, fz_bbox r);
-void fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r);
-void fz_premultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
-void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
-fz_pixmap *fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity);
-void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
-void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma);
-unsigned int fz_pixmap_size(fz_context *ctx, fz_pixmap *pix);
+/*
+ fz_pixmap_width: Return the width of the pixmap in pixels.
+*/
+int fz_pixmap_width(fz_context *ctx, fz_pixmap *pix);
-fz_pixmap *fz_scale_pixmap(fz_context *ctx, fz_pixmap *src, float x, float y, float w, float h, fz_bbox *clip);
+/*
+ fz_pixmap_height: Return the height of the pixmap in pixels.
+*/
+int fz_pixmap_height(fz_context *ctx, fz_pixmap *pix);
-void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename);
-void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha);
-void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha);
+/*
+ fz_new_pixmap: Create a new pixmap, with it's origin at (0,0)
+
+ cs: The colorspace to use for the pixmap, or NULL for an alpha
+ plane/mask.
-fz_pixmap *fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *cs);
-fz_pixmap *fz_load_jpeg(fz_context *doc, unsigned char *data, int size);
-fz_pixmap *fz_load_png(fz_context *doc, unsigned char *data, int size);
-fz_pixmap *fz_load_tiff(fz_context *doc, unsigned char *data, int size);
+ w: The width of the pixmap (in pixels)
+
+ h: The height of the pixmap (in pixels)
+
+ Returns a pointer to the new pixmap. Throws exception on failure to
+ allocate.
+*/
+fz_pixmap *fz_new_pixmap(fz_context *ctx, fz_colorspace *cs, int w, int h);
/*
- * Bitmaps have 1 component per bit. Only used for creating halftoned versions
- * of contone buffers, and saving out. Samples are stored msb first, akin to
- * pbms.
- */
+ fz_new_pixmap_with_bbox: Create a pixmap of a given size,
+ location and pixel format.
-typedef struct fz_bitmap_s fz_bitmap;
+ The bounding box specifies the size of the created pixmap and
+ where it will be located. The colorspace determines the number
+ of components per pixel. Alpha is always present. Pixmaps are
+ reference counted, so drop references using fz_drop_pixmap.
-struct fz_bitmap_s
-{
- int refs;
- int w, h, stride, n;
- unsigned char *samples;
-};
+ colorspace: Colorspace format used for the created pixmap. The
+ pixmap will keep a reference to the colorspace.
-fz_bitmap *fz_new_bitmap(fz_context *ctx, int w, int h, int n);
-fz_bitmap *fz_keep_bitmap(fz_context *ctx, fz_bitmap *bit);
-void fz_clear_bitmap(fz_context *ctx, fz_bitmap *bit);
-void fz_drop_bitmap(fz_context *ctx, fz_bitmap *bit);
+ bbox: Bounding box specifying location/size of created pixmap.
-void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename);
+ Returns a pointer to the new pixmap. Throws exception on failure to
+ allocate.
+*/
+fz_pixmap *fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_bbox bbox);
/*
- * A halftone is a set of threshold tiles, one per component. Each threshold
- * tile is a pixmap, possibly of varying sizes and phases.
- */
+ fz_new_pixmap_with_data: Create a new pixmap, with it's origin at
+ (0,0) using the supplied data block.
-typedef struct fz_halftone_s fz_halftone;
+ cs: The colorspace to use for the pixmap, or NULL for an alpha
+ plane/mask.
-struct fz_halftone_s
-{
- int refs;
- int n;
- fz_pixmap *comp[1];
-};
+ w: The width of the pixmap (in pixels)
-fz_halftone *fz_new_halftone(fz_context *ctx, int num_comps);
-fz_halftone *fz_get_default_halftone(fz_context *ctx, int num_comps);
-fz_halftone *fz_keep_halftone(fz_context *ctx, fz_halftone *half);
-void fz_drop_halftone(fz_context *ctx, fz_halftone *half);
+ h: The height of the pixmap (in pixels)
-fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht);
+ samples: The data block to keep the samples in.
+
+ Returns a pointer to the new pixmap. Throws exception on failure to
+ allocate.
+*/
+fz_pixmap *fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h, unsigned char *samples);
/*
- * Colorspace resources.
- */
+ fz_new_pixmap_with_bbox_and_data: Create a pixmap of a given size,
+ location and pixel format, using the supplied data block.
-extern fz_colorspace *fz_device_gray;
-extern fz_colorspace *fz_device_rgb;
-extern fz_colorspace *fz_device_bgr;
-extern fz_colorspace *fz_device_cmyk;
+ The bounding box specifies the size of the created pixmap and
+ where it will be located. The colorspace determines the number
+ of components per pixel. Alpha is always present. Pixmaps are
+ reference counted, so drop references using fz_drop_pixmap.
-struct fz_colorspace_s
-{
- fz_storable storable;
- unsigned int size;
- char name[16];
- int n;
- void (*to_rgb)(fz_context *ctx, fz_colorspace *, float *src, float *rgb);
- void (*from_rgb)(fz_context *ctx, fz_colorspace *, float *rgb, float *dst);
- void (*free_data)(fz_context *Ctx, fz_colorspace *);
- void *data;
-};
+ colorspace: Colorspace format used for the created pixmap. The
+ pixmap will keep a reference to the colorspace.
-fz_colorspace *fz_new_colorspace(fz_context *ctx, char *name, int n);
-fz_colorspace *fz_keep_colorspace(fz_context *ctx, fz_colorspace *colorspace);
-void fz_drop_colorspace(fz_context *ctx, fz_colorspace *colorspace);
-void fz_free_colorspace_imp(fz_context *ctx, fz_storable *colorspace);
+ bbox: Bounding box specifying location/size of created pixmap.
-void fz_convert_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspace *dsts, float *dstv);
-void fz_convert_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst);
+ samples: The data block to keep the samples in.
-fz_colorspace *fz_find_device_colorspace(char *name);
+ Returns a pointer to the new pixmap. Throws exception on failure to
+ allocate.
+*/
+fz_pixmap *fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_bbox bbox, unsigned char *samples);
/*
- * Fonts come in two variants:
- * Regular fonts are handled by FreeType.
- * Type 3 fonts have callbacks to the interpreter.
- */
+ fz_keep_pixmap: Take a reference to a pixmap.
-typedef struct fz_device_s fz_device;
+ pix: The pixmap to increment the reference for.
-typedef struct fz_font_s fz_font;
-char *ft_error_string(int err);
+ Returns pix. Does not throw exceptions.
+*/
+fz_pixmap *fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix);
-struct fz_font_s
-{
- int refs;
- char name[32];
-
- void *ft_face; /* has an FT_Face if used */
- int ft_substitute; /* ... substitute metrics */
- int ft_bold; /* ... synthesize bold */
- int ft_italic; /* ... synthesize italic */
- int ft_hint; /* ... force hinting for DynaLab fonts */
-
- /* origin of font data */
- char *ft_file;
- unsigned char *ft_data;
- int ft_size;
-
- fz_matrix t3matrix;
- fz_obj *t3resources;
- fz_buffer **t3procs; /* has 256 entries if used */
- float *t3widths; /* has 256 entries if used */
- char *t3flags; /* has 256 entries if used */
- void *t3doc; /* a pdf_document for the callback */
- void (*t3run)(void *doc, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate);
-
- fz_rect bbox; /* font bbox is used only for t3 fonts */
-
- /* per glyph bounding box cache */
- int use_glyph_bbox;
- int bbox_count;
- fz_rect *bbox_table;
-
- /* substitute metrics */
- int width_count;
- int *width_table; /* in 1000 units */
-};
+/*
+ fz_drop_pixmap: Drop a reference and free a pixmap.
-void fz_new_font_context(fz_context *ctx);
-fz_font_context *fz_keep_font_context(fz_context *ctx);
-void fz_drop_font_context(fz_context *ctx);
+ Decrement the reference count for the pixmap. When no
+ references remain the pixmap will be freed.
-fz_font *fz_new_type3_font(fz_context *ctx, char *name, fz_matrix matrix);
+ Does not throw exceptions.
+*/
+void fz_drop_pixmap(fz_context *ctx, fz_pixmap *pix);
-fz_font *fz_new_font_from_memory(fz_context *ctx, unsigned char *data, int len, int index, int use_glyph_bbox);
-fz_font *fz_new_font_from_file(fz_context *ctx, char *path, int index, int use_glyph_bbox);
+/*
+ fz_pixmap_colorspace: Return the colorspace of a pixmap
-fz_font *fz_keep_font(fz_context *ctx, fz_font *font);
-void fz_drop_font(fz_context *ctx, fz_font *font);
+ Returns colorspace. Does not throw exceptions.
+*/
+fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix);
-void fz_debug_font(fz_context *ctx, fz_font *font);
+/*
+ fz_pixmap_components: Return the number of components in a pixmap.
-void fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float xmax, float ymax);
-fz_rect fz_bound_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm);
-int fz_glyph_cacheable(fz_context *ctx, fz_font *font, int gid);
+ Returns the number of components. Does not throw exceptions.
+*/
+int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix);
/*
- * Vector path buffer.
- * It can be stroked and dashed, or be filled.
- * It has a fill rule (nonzero or even_odd).
- *
- * When rendering, they are flattened, stroked and dashed straight
- * into the Global Edge List.
- */
+ fz_pixmap_samples: Returns a pointer to the pixel data of a pixmap.
-typedef struct fz_path_s fz_path;
-typedef struct fz_stroke_state_s fz_stroke_state;
+ Returns the pointer. Does not throw exceptions.
+*/
+unsigned char *fz_pixmap_samples(fz_context *ctx, fz_pixmap *pix);
-typedef union fz_path_item_s fz_path_item;
+/*
+ fz_clear_pixmap_with_value: Clears a pixmap with the given value.
-typedef enum fz_path_item_kind_e
-{
- FZ_MOVETO,
- FZ_LINETO,
- FZ_CURVETO,
- FZ_CLOSE_PATH
-} fz_path_item_kind;
+ pix: The pixmap to clear.
-typedef enum fz_linecap_e
-{
- FZ_LINECAP_BUTT = 0,
- FZ_LINECAP_ROUND = 1,
- FZ_LINECAP_SQUARE = 2,
- FZ_LINECAP_TRIANGLE = 3
-} fz_linecap;
+ value: Values in the range 0 to 255 are valid. Each component
+ sample for each pixel in the pixmap will be set to this value,
+ while alpha will always be set to 255 (non-transparent).
-typedef enum fz_linejoin_e
-{
- FZ_LINEJOIN_MITER = 0,
- FZ_LINEJOIN_ROUND = 1,
- FZ_LINEJOIN_BEVEL = 2,
- FZ_LINEJOIN_MITER_XPS = 3
-} fz_linejoin;
+ Does not throw exceptions.
+*/
+void fz_clear_pixmap_with_value(fz_context *ctx, fz_pixmap *pix, int value);
-union fz_path_item_s
-{
- fz_path_item_kind k;
- float v;
-};
+/*
+ fz_clear_pixmap_with_value: Sets all components (including alpha) of
+ all pixels in a pixmap to 0.
-struct fz_path_s
-{
- int len, cap;
- fz_path_item *items;
- int last;
-};
+ pix: The pixmap to clear.
-struct fz_stroke_state_s
-{
- fz_linecap start_cap, dash_cap, end_cap;
- fz_linejoin linejoin;
- float linewidth;
- float miterlimit;
- float dash_phase;
- int dash_len;
- float dash_list[32];
-};
+ Does not throw exceptions.
+*/
+void fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix);
-fz_path *fz_new_path(fz_context *ctx);
-void fz_moveto(fz_context*, fz_path*, float x, float y);
-void fz_lineto(fz_context*, fz_path*, float x, float y);
-void fz_curveto(fz_context*,fz_path*, float, float, float, float, float, float);
-void fz_curvetov(fz_context*,fz_path*, float, float, float, float);
-void fz_curvetoy(fz_context*,fz_path*, float, float, float, float);
-void fz_closepath(fz_context*,fz_path*);
-void fz_free_path(fz_context *ctx, fz_path *path);
+/*
+ fz_invert_pixmap: Invert all the pixels in a pixmap. All components
+ of all pixels are inverted (except alpha, which is unchanged).
-void fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix transform);
+ Does not throw exceptions.
+*/
+void fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix);
-fz_path *fz_clone_path(fz_context *ctx, fz_path *old);
+/*
+ fz_invert_pixmap: Invert all the pixels in a given rectangle of a
+ pixmap. All components of all pixels in the rectangle are inverted
+ (except alpha, which is unchanged).
-fz_rect fz_bound_path(fz_context *ctx, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm);
-void fz_debug_path(fz_context *ctx, fz_path *, int indent);
+ Does not throw exceptions.
+*/
+void fz_invert_pixmap_rect(fz_pixmap *image, fz_bbox rect);
/*
- * Glyph cache
- */
+ fz_gamma_pixmap: Apply gamma correction to a pixmap. All components
+ of all pixels are modified (except alpha, which is unchanged).
-void fz_new_glyph_cache_context(fz_context *ctx);
-fz_glyph_cache *fz_keep_glyph_cache(fz_context *ctx);
-void fz_drop_glyph_cache_context(fz_context *ctx);
-void fz_purge_glyph_cache(fz_context *ctx);
-
-fz_pixmap *fz_render_ft_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm);
-fz_pixmap *fz_render_t3_glyph(fz_context *ctx, fz_font *font, int cid, fz_matrix trm, fz_colorspace *model);
-fz_pixmap *fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_matrix ctm, fz_stroke_state *state);
-fz_pixmap *fz_render_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_colorspace *model);
-fz_pixmap *fz_render_stroked_glyph(fz_context *ctx, fz_font*, int, fz_matrix, fz_matrix, fz_stroke_state *stroke);
-void fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gid, fz_matrix trm, void *gstate);
-
-/*
- * Text buffer.
- *
- * The trm field contains the a, b, c and d coefficients.
- * The e and f coefficients come from the individual elements,
- * together they form the transform matrix for the glyph.
- *
- * Glyphs are referenced by glyph ID.
- * The Unicode text equivalent is kept in a separate array
- * with indexes into the glyph array.
- */
+ gamma: The gamma value to apply; 1.0 for no change.
-typedef struct fz_text_s fz_text;
-typedef struct fz_text_item_s fz_text_item;
+ Does not throw exceptions.
+*/
+void fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma);
-struct fz_text_item_s
-{
- float x, y;
- int gid; /* -1 for one gid to many ucs mappings */
- int ucs; /* -1 for one ucs to many gid mappings */
-};
+/*
+ fz_unmultiply_pixmap: Convert a pixmap from premultiplied to
+ non-premultiplied format.
-struct fz_text_s
-{
- fz_font *font;
- fz_matrix trm;
- int wmode;
- int len, cap;
- fz_text_item *items;
-};
+ Does not throw exceptions.
+*/
+void fz_unmultiply_pixmap(fz_context *ctx, fz_pixmap *pix);
+
+/*
+ fz_convert_pixmap: Convert from one pixmap to another (assumed to be
+ the same size, but possibly with a different colorspace).
+
+ dst: the source pixmap.
-fz_text *fz_new_text(fz_context *ctx, fz_font *face, fz_matrix trm, int wmode);
-void fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y);
-void fz_free_text(fz_context *ctx, fz_text *text);
-fz_rect fz_bound_text(fz_context *ctx, fz_text *text, fz_matrix ctm);
-fz_text *fz_clone_text(fz_context *ctx, fz_text *old);
-void fz_debug_text(fz_context *ctx, fz_text*, int indent);
+ src: the destination pixmap.
+*/
+void fz_convert_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src);
/*
- * The shading code uses gouraud shaded triangle meshes.
- */
+ fz_write_pixmap: Save a pixmap out.
-enum
-{
- FZ_LINEAR,
- FZ_RADIAL,
- FZ_MESH,
-};
+ name: The prefix for the name of the pixmap. The pixmap will be saved
+ as "name.png" if the pixmap is RGB or Greyscale, "name.pam" otherwise.
-typedef struct fz_shade_s fz_shade;
+ rgb: If non zero, the pixmap is converted to rgb (if possible) before
+ saving.
+*/
+void fz_write_pixmap(fz_context *ctx, fz_pixmap *img, char *name, int rgb);
-struct fz_shade_s
-{
- fz_storable storable;
+/*
+ fz_write_pnm: Save a pixmap as a pnm
- fz_rect bbox; /* can be fz_infinite_rect */
- fz_colorspace *colorspace;
+ filename: The filename to save as (including extension).
+*/
+void fz_write_pnm(fz_context *ctx, fz_pixmap *pixmap, char *filename);
- fz_matrix matrix; /* matrix from pattern dict */
- int use_background; /* background color for fills but not 'sh' */
- float background[FZ_MAX_COLORS];
+/*
+ fz_write_pam: Save a pixmap as a pam
- int use_function;
- float function[256][FZ_MAX_COLORS + 1];
+ filename: The filename to save as (including extension).
+*/
+void fz_write_pam(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha);
- int type; /* linear, radial, mesh */
- int extend[2];
+/*
+ fz_write_png: Save a pixmap as a png
- int mesh_len;
- int mesh_cap;
- float *mesh; /* [x y 0], [x y r], [x y t] or [x y c1 ... cn] */
-};
+ filename: The filename to save as (including extension).
+*/
+void fz_write_png(fz_context *ctx, fz_pixmap *pixmap, char *filename, int savealpha);
+
+/*
+ fz_write_pbm: Save a bitmap as a pbm
+
+ filename: The filename to save as (including extension).
+*/
+void fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename);
-fz_shade *fz_keep_shade(fz_context *ctx, fz_shade *shade);
-void fz_drop_shade(fz_context *ctx, fz_shade *shade);
-void fz_free_shade_imp(fz_context *ctx, fz_storable *shade);
-void fz_debug_shade(fz_context *ctx, fz_shade *shade);
+/*
+ fz_md5_pixmap: Return the md5 digest for a pixmap
-fz_rect fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm);
-void fz_paint_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox);
+ filename: The filename to save as (including extension).
+*/
+void fz_md5_pixmap(fz_pixmap *pixmap, unsigned char digest[16]);
/*
- * Scan converter
+ Images are storable objects from which we can obtain fz_pixmaps.
+ These may be implemented as simple wrappers around a pixmap, or as
+ more complex things that decode at different subsample settings on
+ demand.
*/
+typedef struct fz_image_s fz_image;
-int fz_get_aa_level(fz_context *ctx);
-void fz_set_aa_level(fz_context *ctx, int bits);
+/*
+ fz_image_to_pixmap: Called to get a handle to a pixmap from an image.
-typedef struct fz_gel_s fz_gel;
+ image: The image to retrieve a pixmap from.
-fz_gel *fz_new_gel(fz_context *ctx);
-void fz_insert_gel(fz_gel *gel, float x0, float y0, float x1, float y1);
-void fz_reset_gel(fz_gel *gel, fz_bbox clip);
-void fz_sort_gel(fz_gel *gel);
-fz_bbox fz_bound_gel(fz_gel *gel);
-void fz_free_gel(fz_gel *gel);
-int fz_is_rect_gel(fz_gel *gel);
+ w: The desired width (in pixels). This may be completely ignored, but
+ may serve as an indication of a suitable subsample factor to use for
+ image types that support this.
-void fz_scan_convert(fz_gel *gel, int eofill, fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv);
+ h: The desired height (in pixels). This may be completely ignored, but
+ may serve as an indication of a suitable subsample factor to use for
+ image types that support this.
-void fz_flatten_fill_path(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness);
-void fz_flatten_stroke_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth);
-void fz_flatten_dash_path(fz_gel *gel, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, float flatness, float linewidth);
+ Returns a non NULL pixmap pointer. May throw exceptions.
+*/
+fz_pixmap *fz_image_to_pixmap(fz_context *ctx, fz_image *image, int w, int h);
/*
- * The device interface.
- */
+ fz_drop_image: Drop a reference to an image.
-enum
-{
- /* Hints */
- FZ_IGNORE_IMAGE = 1,
- FZ_IGNORE_SHADE = 2,
-
- /* Flags */
- FZ_DEVFLAG_MASK = 1,
- FZ_DEVFLAG_COLOR = 2,
- FZ_DEVFLAG_UNCACHEABLE = 4,
- FZ_DEVFLAG_FILLCOLOR_UNDEFINED = 8,
- FZ_DEVFLAG_STROKECOLOR_UNDEFINED = 16,
- FZ_DEVFLAG_STARTCAP_UNDEFINED = 32,
- FZ_DEVFLAG_DASHCAP_UNDEFINED = 64,
- FZ_DEVFLAG_ENDCAP_UNDEFINED = 128,
- FZ_DEVFLAG_LINEJOIN_UNDEFINED = 256,
- FZ_DEVFLAG_MITERLIMIT_UNDEFINED = 512,
- FZ_DEVFLAG_LINEWIDTH_UNDEFINED = 1024,
- /* Arguably we should have a bit for the dash pattern itself being
- * undefined, but that causes problems; do we assume that it should
- * always be set to non-dashing at the start of every glyph? */
-};
+ image: The image to drop a reference to.
+*/
+void fz_drop_image(fz_context *ctx, fz_image *image);
-struct fz_device_s
-{
- int hints;
- int flags;
+/*
+ fz_keep_image: Increment the reference count of an image.
- void *user;
- void (*free_user)(fz_device *);
- fz_context *ctx;
-
- void (*fill_path)(fz_device *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*stroke_path)(fz_device *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*clip_path)(fz_device *, fz_path *, fz_rect *rect, int even_odd, fz_matrix);
- void (*clip_stroke_path)(fz_device *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix);
-
- void (*fill_text)(fz_device *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*clip_text)(fz_device *, fz_text *, fz_matrix, int accumulate);
- void (*clip_stroke_text)(fz_device *, fz_text *, fz_stroke_state *, fz_matrix);
- void (*ignore_text)(fz_device *, fz_text *, fz_matrix);
-
- void (*fill_shade)(fz_device *, fz_shade *shd, fz_matrix ctm, float alpha);
- void (*fill_image)(fz_device *, fz_pixmap *img, fz_matrix ctm, float alpha);
- void (*fill_image_mask)(fz_device *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
- void (*clip_image_mask)(fz_device *, fz_pixmap *img, fz_rect *rect, fz_matrix ctm);
-
- void (*pop_clip)(fz_device *);
-
- void (*begin_mask)(fz_device *, fz_rect, int luminosity, fz_colorspace *, float *bc);
- void (*end_mask)(fz_device *);
- void (*begin_group)(fz_device *, fz_rect, int isolated, int knockout, int blendmode, float alpha);
- void (*end_group)(fz_device *);
-
- void (*begin_tile)(fz_device *, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
- void (*end_tile)(fz_device *);
-};
+ image: The image to take a reference to.
-void fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm);
-void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm);
-void fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate);
-void fz_clip_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm);
-void fz_ignore_text(fz_device *dev, fz_text *text, fz_matrix ctm);
-void fz_pop_clip(fz_device *dev);
-void fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha);
-void fz_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha);
-void fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm);
-void fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc);
-void fz_end_mask(fz_device *dev);
-void fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha);
-void fz_end_group(fz_device *dev);
-void fz_begin_tile(fz_device *dev, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm);
-void fz_end_tile(fz_device *dev);
-
-fz_device *fz_new_device(fz_context *ctx, void *user);
+ Returns a pointer to the image.
+*/
+fz_image *fz_keep_image(fz_context *ctx, fz_image *image);
+
+/*
+ A halftone is a set of threshold tiles, one per component. Each
+ threshold tile is a pixmap, possibly of varying sizes and phases.
+ Currently, we only provide one 'default' halftone tile for operating
+ on 1 component plus alpha pixmaps (where the alpha is ignored). This
+ is signified by an fz_halftone pointer to NULL.
+*/
+typedef struct fz_halftone_s fz_halftone;
+
+/*
+ fz_halftone_pixmap: Make a bitmap from a pixmap and a halftone.
+
+ pix: The pixmap to generate from. Currently must be a single color
+ component + alpha (where the alpha is assumed to be solid).
+
+ ht: The halftone to use. NULL implies the default halftone.
+
+ Returns the resultant bitmap. Throws exceptions in the case of
+ failure to allocate.
+*/
+fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht);
+
+/*
+ An abstract font handle. Currently there are no public API functions
+ for handling these.
+*/
+typedef struct fz_font_s fz_font;
+
+/*
+ The different format handlers (pdf, xps etc) interpret pages to a
+ device. These devices can then process the stream of calls they
+ recieve in various ways:
+ The trace device outputs debugging information for the calls.
+ The draw device will render them.
+ The list device stores them in a list to play back later.
+ The text device performs text extraction and searching.
+ The bbox device calculates the bounding box for the page.
+ Other devices can (and will) be written in future.
+*/
+typedef struct fz_device_s fz_device;
+
+/*
+ fz_free_device: Free a devices of any type and its resources.
+*/
void fz_free_device(fz_device *dev);
+/*
+ fz_new_trace_device: Create a device to print a debug trace of
+ all device calls.
+*/
fz_device *fz_new_trace_device(fz_context *ctx);
+
+/*
+ fz_new_bbox_device: Create a device to compute the bounding
+ box of all marks on a page.
+
+ The returned bounding box will be the union of all bounding
+ boxes of all objects on a page.
+*/
fz_device *fz_new_bbox_device(fz_context *ctx, fz_bbox *bboxp);
+
+/*
+ fz_new_draw_device: Create a device to draw on a pixmap.
+
+ dest: Target pixmap for the draw device. See fz_new_pixmap*
+ for how to obtain a pixmap. The pixmap is not cleared by the
+ draw device, see fz_clear_pixmap* for how to clear it prior to
+ calling fz_new_draw_device. Free the device by calling
+ fz_free_device.
+*/
fz_device *fz_new_draw_device(fz_context *ctx, fz_pixmap *dest);
-fz_device *fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest);
/*
- * Text extraction device
+ Text extraction device: Used for searching, format conversion etc.
*/
-typedef struct fz_text_span_s fz_text_span;
+typedef struct fz_text_style_s fz_text_style;
typedef struct fz_text_char_s fz_text_char;
+typedef struct fz_text_span_s fz_text_span;
+typedef struct fz_text_line_s fz_text_line;
+typedef struct fz_text_block_s fz_text_block;
+
+typedef struct fz_text_sheet_s fz_text_sheet;
+typedef struct fz_text_page_s fz_text_page;
+
+struct fz_text_style_s
+{
+ int id;
+ fz_font *font;
+ float size;
+ int wmode;
+ int script;
+ /* etc... */
+ fz_text_style *next;
+};
+
+struct fz_text_sheet_s
+{
+ int maxid;
+ fz_text_style *style;
+};
struct fz_text_char_s
{
+ fz_rect bbox;
int c;
- fz_bbox bbox;
};
struct fz_text_span_s
{
- fz_font *font;
- float size;
- int wmode;
+ fz_rect bbox;
int len, cap;
fz_text_char *text;
- fz_text_span *next;
- int eol;
+ fz_text_style *style;
};
-fz_text_span *fz_new_text_span(fz_context *ctx);
-void fz_free_text_span(fz_context *ctx, fz_text_span *line);
-void fz_debug_text_span(fz_text_span *line);
-void fz_debug_text_span_xml(fz_text_span *span);
+struct fz_text_line_s
+{
+ fz_rect bbox;
+ int len, cap;
+ fz_text_span *spans;
+};
-fz_device *fz_new_text_device(fz_context *ctx, fz_text_span *text);
+struct fz_text_block_s
+{
+ fz_rect bbox;
+ int len, cap;
+ fz_text_line *lines;
+};
+
+struct fz_text_page_s
+{
+ fz_rect mediabox;
+ int len, cap;
+ fz_text_block *blocks;
+};
+
+/*
+ fz_new_text_device: Create a device to extract the text on a page.
+
+ Gather and sort the text on a page into spans of uniform style,
+ arranged into lines and blocks by reading order. The reading order
+ is determined by various heuristics, so may not be accurate.
+*/
+fz_device *fz_new_text_device(fz_context *ctx, fz_text_sheet *sheet, fz_text_page *page);
+
+/*
+ fz_new_text_sheet: Create an empty style sheet.
+
+ The style sheet is filled out by the text device, creating
+ one style for each unique font, color, size combination that
+ is used.
+*/
+fz_text_sheet *fz_new_text_sheet(fz_context *ctx);
+void fz_free_text_sheet(fz_context *ctx, fz_text_sheet *sheet);
+
+/*
+ fz_new_text_page: Create an empty text page.
+
+ The text page is filled out by the text device to contain the blocks,
+ lines and spans of text on the page.
+*/
+fz_text_page *fz_new_text_page(fz_context *ctx, fz_rect mediabox);
+void fz_free_text_page(fz_context *ctx, fz_text_page *page);
+
+void fz_print_text_sheet(fz_context *ctx, FILE *out, fz_text_sheet *sheet);
+void fz_print_text_page_html(fz_context *ctx, FILE *out, fz_text_page *page);
+void fz_print_text_page_xml(fz_context *ctx, FILE *out, fz_text_page *page);
+void fz_print_text_page(fz_context *ctx, FILE *out, fz_text_page *page);
/*
* Cookie support - simple communication channel between app/library.
@@ -1494,6 +1583,40 @@ fz_device *fz_new_text_device(fz_context *ctx, fz_text_span *text);
typedef struct fz_cookie_s fz_cookie;
+/*
+ Provide two-way communication between application and library.
+ Intended for multi-threaded applications where one thread is
+ rendering pages and another thread wants read progress
+ feedback or abort a job that takes a long time to finish. The
+ communication is unsynchronized without locking.
+
+ abort: The appliation should set this field to 0 before
+ calling fz_run_page to render a page. At any point when the
+ page is being rendered the application my set this field to 1
+ which will cause the rendering to finish soon. This field is
+ checked periodically when the page is rendered, but exactly
+ when is not known, therefore there is no upper bound on
+ exactly when the the rendering will abort. If the application
+ did not provide a set of locks to fz_new_context, it must also
+ await the completion of fz_run_page before issuing another
+ call to fz_run_page. Note that once the application has set
+ this field to 1 after it called fz_run_page it may not change
+ the value again.
+
+ progress: Communicates rendering progress back to the
+ application and is read only. Increments as a page is being
+ rendered. The value starts out at 0 and is limited to less
+ than or equal to progress_max, unless progress_max is -1.
+
+ progress_max: Communicates the known upper bound of rendering
+ back to the application and is read only. The maximum value
+ that the progress field may take. If there is no known upper
+ bound on how long the rendering may take this value is -1 and
+ progress is not limited. Note that the value of progress_max
+ may change from -1 to a positive value once an upper bound is
+ known, so take this into consideration when comparing the
+ value of progress to that of progress_max.
+*/
struct fz_cookie_s
{
int abort;
@@ -1502,67 +1625,81 @@ struct fz_cookie_s
};
/*
- * Display list device -- record and play back device commands.
- */
+ Display list device -- record and play back device commands.
+*/
+/*
+ fz_display_list is a list containing drawing commands (text,
+ images, etc.). The intent is two-fold: as a caching-mechanism
+ to reduce parsing of a page, and to be used as a data
+ structure in multi-threading where one thread parses the page
+ and another renders pages.
+
+ Create a displaylist with fz_new_display_list, hand it over to
+ fz_new_list_device to have it populated, and later replay the
+ list (once or many times) by calling fz_run_display_list. When
+ the list is no longer needed free it with fz_free_display_list.
+*/
typedef struct fz_display_list_s fz_display_list;
+/*
+ fz_new_display_list: Create an empty display list.
+
+ A display list contains drawing commands (text, images, etc.).
+ Use fz_new_list_device for populating the list.
+*/
fz_display_list *fz_new_display_list(fz_context *ctx);
-void fz_free_display_list(fz_context *ctx, fz_display_list *list);
+
+/*
+ fz_new_list_device: Create a rendering device for a display list.
+
+ When the device is rendering a page it will populate the
+ display list with drawing commsnds (text, images, etc.). The
+ display list can later be reused to render a page many times
+ without having to re-interpret the page from the document file
+ for each rendering. Once the device is no longer needed, free
+ it with fz_free_device.
+
+ list: A display list that the list device takes ownership of.
+*/
fz_device *fz_new_list_device(fz_context *ctx, fz_display_list *list);
-void fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_bbox area, fz_cookie *cookie);
/*
- * Plotting functions.
- */
+ fz_run_display_list: (Re)-run a display list through a device.
-void fz_decode_tile(fz_pixmap *pix, float *decode);
-void fz_decode_indexed_tile(fz_pixmap *pix, float *decode, int maxval);
-void fz_unpack_tile(fz_pixmap *dst, unsigned char * restrict src, int n, int depth, int stride, int scale);
+ list: A display list, created by fz_new_display_list and
+ populated with objects from a page by running fz_run_page on a
+ device obtained from fz_new_list_device.
-void fz_paint_solid_alpha(unsigned char * restrict dp, int w, int alpha);
-void fz_paint_solid_color(unsigned char * restrict dp, int n, int w, unsigned char *color);
+ dev: Device obtained from fz_new_*_device.
-void fz_paint_span(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w, int alpha);
-void fz_paint_span_with_color(unsigned char * restrict dp, unsigned char * restrict mp, int n, int w, unsigned char *color);
+ ctm: Transform to apply to display list contents. May include
+ for example scaling and rotation, see fz_scale, fz_rotate and
+ fz_concat. Set to fz_identity if no transformation is desired.
-void fz_paint_image(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, int alpha);
-void fz_paint_image_with_color(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *shape, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv);
+ area: Only the part of the contents of the display list
+ visible within this area will be considered when the list is
+ run through the device. This does not imply for tile objects
+ contained in the display list.
-void fz_paint_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha);
-void fz_paint_pixmap_with_mask(fz_pixmap *dst, fz_pixmap *src, fz_pixmap *msk);
-void fz_paint_pixmap_with_rect(fz_pixmap *dst, fz_pixmap *src, int alpha, fz_bbox bbox);
+ cookie: Communication mechanism between caller and library
+ running the page. Intended for multi-threaded applications,
+ while single-threaded applications set cookie to NULL. The
+ caller may abort an ongoing page run. Cookie also communicates
+ progress information back to the caller. The fields inside
+ cookie are continually updated while the page is being run.
+*/
+void fz_run_display_list(fz_display_list *list, fz_device *dev, fz_matrix ctm, fz_bbox area, fz_cookie *cookie);
-void fz_blend_pixmap(fz_pixmap *dst, fz_pixmap *src, int alpha, int blendmode, int isolated, fz_pixmap *shape);
-void fz_blend_pixel(unsigned char dp[3], unsigned char bp[3], unsigned char sp[3], int blendmode);
+/*
+ fz_free_display_list: Frees a display list.
-enum
-{
- /* PDF 1.4 -- standard separable */
- FZ_BLEND_NORMAL,
- FZ_BLEND_MULTIPLY,
- FZ_BLEND_SCREEN,
- FZ_BLEND_OVERLAY,
- FZ_BLEND_DARKEN,
- FZ_BLEND_LIGHTEN,
- FZ_BLEND_COLOR_DODGE,
- FZ_BLEND_COLOR_BURN,
- FZ_BLEND_HARD_LIGHT,
- FZ_BLEND_SOFT_LIGHT,
- FZ_BLEND_DIFFERENCE,
- FZ_BLEND_EXCLUSION,
-
- /* PDF 1.4 -- standard non-separable */
- FZ_BLEND_HUE,
- FZ_BLEND_SATURATION,
- FZ_BLEND_COLOR,
- FZ_BLEND_LUMINOSITY,
-
- /* For packing purposes */
- FZ_BLEND_MODEMASK = 15,
- FZ_BLEND_ISOLATED = 16,
- FZ_BLEND_KNOCKOUT = 32
-};
+ list: Display list to be freed. Any objects put into the
+ display list by a list device will also be freed.
+
+ Does not throw exceptions.
+*/
+void fz_free_display_list(fz_context *ctx, fz_display_list *list);
/* Links */
@@ -1590,6 +1727,35 @@ enum {
fz_link_flag_r_is_zoom = 64 /* rb.x is actually a zoom figure */
};
+/*
+ fz_link_dest: XXX
+
+ kind: Set to one of FZ_LINK_* to tell what what type of link
+ destination this is, and where in the union to look for
+ information. XXX
+
+ gotor.page: Page number, 0 is the first page of the document. XXX
+
+ gotor.flags: A bitfield consisting of fz_link_flag_* telling
+ what parts of gotor.lt and gotor.rb are valid, whether
+ fitting to width/height should be used, or if an arbitrary
+ zoom factor is used. XXX
+
+ gotor.lt: The top left corner of the destination bounding box. XXX
+ gotor.rb: The bottom right corner of the destination bounding box. XXX
+
+ gotor.file_spec: XXX
+
+ gotor.new_window: XXX
+
+ uri.uri: XXX
+ uri.is_map: XXX
+
+ launch.file_spec: XXX
+ launch.new_window: XXX
+
+ named.named: XXX
+*/
struct fz_link_dest_s
{
fz_link_kind kind;
@@ -1626,6 +1792,25 @@ struct fz_link_dest_s
ld;
};
+/*
+ fz_link is a list of interactive links on a page.
+
+ There is no relation between the order of the links in the
+ list and the order they appear on the page. The list of links
+ for a given page can be obtained from fz_load_links.
+
+ A link is reference counted. Dropping a reference to a link is
+ done by calling fz_drop_link.
+
+ rect: The hot zone. The area that can be clicked in
+ untransformed coordinates.
+
+ dest: Link destinations come in two forms: Page and area that
+ an application should display when this link is activated. Or
+ as an URI that can be given to a browser.
+
+ next: A pointer to the next link on the same page.
+*/
struct fz_link_s
{
int refs;
@@ -1636,13 +1821,37 @@ struct fz_link_s
fz_link *fz_new_link(fz_context *ctx, fz_rect bbox, fz_link_dest dest);
fz_link *fz_keep_link(fz_context *ctx, fz_link *link);
+
+/*
+ fz_drop_link: Drop and free a list of links.
+
+ Does not throw exceptions.
+*/
void fz_drop_link(fz_context *ctx, fz_link *link);
+
void fz_free_link_dest(fz_context *ctx, fz_link_dest *dest);
/* Outline */
typedef struct fz_outline_s fz_outline;
+/*
+ fz_outline is a tree of the outline of a document (also known
+ as table of contents).
+
+ title: Title of outline item using UTF-8 encoding. May be NULL
+ if the outline item has no text string.
+
+ dest: Destination in the document to be displayed when this
+ outline item is activated. May be FZ_LINK_NONE if the outline
+ item does not have a destination.
+
+ next: The next outline item at the same level as this outline
+ item. May be NULL if no more outline items exist at this level.
+
+ down: The outline items immediate children in the hierarchy.
+ May be NULL if no children exist.
+*/
struct fz_outline_s
{
char *title;
@@ -1651,43 +1860,155 @@ struct fz_outline_s
fz_outline *down;
};
-void fz_debug_outline_xml(fz_context *ctx, fz_outline *outline, int level);
-void fz_debug_outline(fz_context *ctx, fz_outline *outline, int level);
-void fz_free_outline(fz_context *ctx, fz_outline *outline);
+/*
+ fz_print_outline_xml: Dump the given outlines as (pseudo) XML.
+
+ out: The file handle to output to.
-/* Document interface */
+ outline: The outlines to output.
+*/
+void fz_print_outline_xml(fz_context *ctx, FILE *out, fz_outline *outline);
+/*
+ fz_print_outline: Dump the given outlines to as text.
+
+ out: The file handle to output to.
+
+ outline: The outlines to output.
+*/
+void fz_print_outline(fz_context *ctx, FILE *out, fz_outline *outline);
+
+/*
+ fz_free_outline: Free hierarchical outline.
+
+ Free an outline obtained from fz_load_outline.
+
+ Does not throw exceptions.
+*/
+void fz_free_outline(fz_context *ctx, fz_outline *outline);
+
+/*
+ Document interface
+*/
typedef struct fz_document_s fz_document;
-typedef struct fz_page_s fz_page; /* doesn't have a definition -- always cast to *_page */
+typedef struct fz_page_s fz_page;
-struct fz_document_s
-{
- void (*close)(fz_document *);
- int (*needs_password)(fz_document *doc);
- int (*authenticate_password)(fz_document *doc, char *password);
- fz_outline *(*load_outline)(fz_document *doc);
- int (*count_pages)(fz_document *doc);
- fz_page *(*load_page)(fz_document *doc, int number);
- fz_link *(*load_links)(fz_document *doc, fz_page *page);
- fz_rect (*bound_page)(fz_document *doc, fz_page *page);
- void (*run_page)(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
- void (*free_page)(fz_document *doc, fz_page *page);
-};
+/*
+ fz_open_document: Open a PDF, XPS or CBZ document.
+
+ Open a document file and read its basic structure so pages and
+ objects can be located. MuPDF will try to repair broken
+ documents (without actually changing the file contents).
+ The returned fz_document is used when calling most other
+ document related functions. Note that it wraps the context, so
+ those functions implicitly can access the global state in
+ context.
+
+ filename: a path to a file as it would be given to open(2).
+*/
fz_document *fz_open_document(fz_context *ctx, char *filename);
+/*
+ fz_close_document: Close and free an open document.
+
+ The resource store in the context associated with fz_document
+ is emptied, and any allocations for the document are freed.
+
+ Does not throw exceptions.
+*/
void fz_close_document(fz_document *doc);
+/*
+ fz_needs_password: Check if a document is encrypted with a
+ non-blank password.
+
+ Does not throw exceptions.
+*/
int fz_needs_password(fz_document *doc);
+
+/*
+ fz_authenticate_password: Test if the given password can
+ decrypt the document.
+
+ password: The password string to be checked. Some document
+ specifications do not specify any particular text encoding, so
+ neither do we.
+
+ Does not throw exceptions.
+*/
int fz_authenticate_password(fz_document *doc, char *password);
+/*
+ fz_load_outline: Load the hierarchical document outline.
+
+ Should be freed by fz_free_outline.
+*/
fz_outline *fz_load_outline(fz_document *doc);
+/*
+ fz_count_pages: Return the number of pages in document
+
+ May return 0 for documents with no pages.
+*/
int fz_count_pages(fz_document *doc);
+
+/*
+ fz_load_page: Load a page.
+
+ After fz_load_page is it possible to retrieve the size of the
+ page using fz_bound_page, or to render the page using
+ fz_run_page_*. Free the page by calling fz_free_page.
+
+ number: page number, 0 is the first page of the document.
+*/
fz_page *fz_load_page(fz_document *doc, int number);
+
+/*
+ fz_load_links: Load the list of links for a page.
+
+ Returns a linked list of all the links on the page, each with
+ its clickable region and link destination. Each link is
+ reference counted so drop and free the list of links by
+ calling fz_drop_link on the pointer return from fz_load_links.
+
+ page: Page obtained from fz_load_page.
+*/
fz_link *fz_load_links(fz_document *doc, fz_page *page);
+
+/*
+ fz_bound_page: Determine the size of a page at 72 dpi.
+
+ Does not throw exceptions.
+*/
fz_rect fz_bound_page(fz_document *doc, fz_page *page);
+
+/*
+ fz_run_page: Run a page through a device.
+
+ page: Page obtained from fz_load_page.
+
+ dev: Device obtained from fz_new_*_device.
+
+ transform: Transform to apply to page. May include for example
+ scaling and rotation, see fz_scale, fz_rotate and fz_concat.
+ Set to fz_identity if no transformation is desired.
+
+ cookie: Communication mechanism between caller and library
+ rendering the page. Intended for multi-threaded applications,
+ while single-threaded applications set cookie to NULL. The
+ caller may abort an ongoing rendering of a page. Cookie also
+ communicates progress information back to the caller. The
+ fields inside cookie are continually updated while the page is
+ rendering.
+*/
void fz_run_page(fz_document *doc, fz_page *page, fz_device *dev, fz_matrix transform, fz_cookie *cookie);
+
+/*
+ fz_free_page: Free a loaded page.
+
+ Does not throw exceptions.
+*/
void fz_free_page(fz_document *doc, fz_page *page);
#endif
diff --git a/fitz/image_jpeg.c b/fitz/image_jpeg.c
index f53b6124..2840adbf 100644
--- a/fitz/image_jpeg.c
+++ b/fitz/image_jpeg.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#include <jpeglib.h>
#include <setjmp.h>
@@ -115,6 +115,9 @@ fz_load_jpeg(fz_context *ctx, unsigned char *rbuf, int rlen)
image->yres = cinfo.Y_density * 254 / 100;
}
+ if (image->xres <= 0) image->xres = 72;
+ if (image->yres <= 0) image->yres = 72;
+
fz_clear_pixmap(ctx, image);
row[0] = fz_malloc(ctx, cinfo.output_components * cinfo.output_width);
diff --git a/fitz/image_jpx.c b/fitz/image_jpx.c
index 4d76b4e8..ac1db35a 100644
--- a/fitz/image_jpx.c
+++ b/fitz/image_jpx.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define OPJ_STATIC
#include <openjpeg.h>
@@ -144,7 +144,7 @@ fz_load_jpx(fz_context *ctx, unsigned char *data, int size, fz_colorspace *defcs
if (n == 4)
{
fz_pixmap *tmp = fz_new_pixmap(ctx, fz_device_rgb, w, h);
- fz_convert_pixmap(ctx, img, tmp);
+ fz_convert_pixmap(ctx, tmp, img);
fz_drop_pixmap(ctx, img);
img = tmp;
}
diff --git a/fitz/image_md5.c b/fitz/image_md5.c
new file mode 100644
index 00000000..86ba0a12
--- /dev/null
+++ b/fitz/image_md5.c
@@ -0,0 +1,11 @@
+#include "fitz-internal.h"
+
+void fz_md5_pixmap(fz_pixmap *pix, unsigned char digest[16])
+{
+ fz_md5 md5;
+
+ fz_md5_init(&md5);
+ if (pix)
+ fz_md5_update(&md5, pix->samples, pix->w * pix->h * pix->n);
+ fz_md5_final(&md5, digest);
+}
diff --git a/fitz/image_png.c b/fitz/image_png.c
index b3fe39cc..e2092c10 100644
--- a/fitz/image_png.c
+++ b/fitz/image_png.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#include <zlib.h>
diff --git a/fitz/image_save.c b/fitz/image_save.c
new file mode 100644
index 00000000..95be1cd3
--- /dev/null
+++ b/fitz/image_save.c
@@ -0,0 +1,32 @@
+#include "fitz-internal.h"
+
+void fz_write_pixmap(fz_context *ctx, fz_pixmap *img, char *file, int rgb)
+{
+ char name[1024];
+ fz_pixmap *converted = NULL;
+
+ if (!img)
+ return;
+
+ if (rgb && img->colorspace && img->colorspace != fz_device_rgb)
+ {
+ converted = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, fz_pixmap_bbox(ctx, img));
+ fz_convert_pixmap(ctx, converted, img);
+ img = converted;
+ }
+
+ if (img->n <= 4)
+ {
+ sprintf(name, "%s.png", file);
+ printf("extracting image %s\n", name);
+ fz_write_png(ctx, img, name, 0);
+ }
+ else
+ {
+ sprintf(name, "%s.pam", file);
+ printf("extracting image %s\n", name);
+ fz_write_pam(ctx, img, name, 0);
+ }
+
+ fz_drop_pixmap(ctx, converted);
+}
diff --git a/fitz/image_tiff.c b/fitz/image_tiff.c
index fff91a9e..ffd0ea88 100644
--- a/fitz/image_tiff.c
+++ b/fitz/image_tiff.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
/*
* TIFF image loader. Should be enough to support TIFF files in XPS.
@@ -789,7 +789,7 @@ fz_load_tiff(fz_context *ctx, unsigned char *buf, int len)
if (image->n == 5)
{
fz_pixmap *rgb = fz_new_pixmap(tiff.ctx, fz_device_rgb, image->w, image->h);
- fz_convert_pixmap(tiff.ctx, image, rgb);
+ fz_convert_pixmap(tiff.ctx, rgb, image);
rgb->xres = image->xres;
rgb->yres = image->yres;
fz_drop_pixmap(ctx, image);
diff --git a/fitz/res_bitmap.c b/fitz/res_bitmap.c
index 2aa28b02..1bd2827d 100644
--- a/fitz/res_bitmap.c
+++ b/fitz/res_bitmap.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_bitmap *
fz_new_bitmap(fz_context *ctx, int w, int h, int n)
@@ -74,3 +74,48 @@ fz_write_pbm(fz_context *ctx, fz_bitmap *bitmap, char *filename)
fclose(fp);
}
+
+fz_colorspace *fz_pixmap_colorspace(fz_context *ctx, fz_pixmap *pix)
+{
+ if (!pix)
+ return NULL;
+ return pix->colorspace;
+}
+
+int fz_pixmap_components(fz_context *ctx, fz_pixmap *pix)
+{
+ if (!pix)
+ return 0;
+ return pix->n;
+}
+
+unsigned char *fz_pixmap_samples(fz_context *ctx, fz_pixmap *pix)
+{
+ if (!pix)
+ return NULL;
+ return pix->samples;
+}
+
+void fz_bitmap_details(fz_bitmap *bit, int *w, int *h, int *n, int *stride)
+{
+ if (!bit)
+ {
+ if (w)
+ *w = 0;
+ if (h)
+ *h = 0;
+ if (n)
+ *n = 0;
+ if (stride)
+ *stride = 0;
+ return;
+ }
+ if (w)
+ *w = bit->w;
+ if (h)
+ *h = bit->h;
+ if (n)
+ *n = bit->n;
+ if (stride)
+ *w = bit->stride;
+}
diff --git a/fitz/res_colorspace.c b/fitz/res_colorspace.c
index 413da3ae..587db381 100644
--- a/fitz/res_colorspace.c
+++ b/fitz/res_colorspace.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#define SLOWCMYK
@@ -164,7 +164,7 @@ fz_colorspace *fz_device_bgr = &k_device_bgr;
fz_colorspace *fz_device_cmyk = &k_device_cmyk;
fz_colorspace *
-fz_find_device_colorspace(char *name)
+fz_find_device_colorspace(fz_context *ctx, char *name)
{
if (!strcmp(name, "DeviceGray"))
return fz_device_gray;
@@ -180,7 +180,7 @@ fz_find_device_colorspace(char *name)
/* Fast pixmap color conversions */
-static void fast_gray_to_rgb(fz_pixmap *src, fz_pixmap *dst)
+static void fast_gray_to_rgb(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -196,7 +196,7 @@ static void fast_gray_to_rgb(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_gray_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
+static void fast_gray_to_cmyk(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -213,7 +213,7 @@ static void fast_gray_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_rgb_to_gray(fz_pixmap *src, fz_pixmap *dst)
+static void fast_rgb_to_gray(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -227,7 +227,7 @@ static void fast_rgb_to_gray(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_bgr_to_gray(fz_pixmap *src, fz_pixmap *dst)
+static void fast_bgr_to_gray(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -241,7 +241,7 @@ static void fast_bgr_to_gray(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_rgb_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
+static void fast_rgb_to_cmyk(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -262,7 +262,7 @@ static void fast_rgb_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_bgr_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
+static void fast_bgr_to_cmyk(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -283,7 +283,7 @@ static void fast_bgr_to_cmyk(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_cmyk_to_gray(fz_pixmap *src, fz_pixmap *dst)
+static void fast_cmyk_to_gray(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -300,7 +300,7 @@ static void fast_cmyk_to_gray(fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
+static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -328,7 +328,7 @@ static void fast_cmyk_to_rgb(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
+static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -356,7 +356,7 @@ static void fast_cmyk_to_bgr(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
}
}
-static void fast_rgb_to_bgr(fz_pixmap *src, fz_pixmap *dst)
+static void fast_rgb_to_bgr(fz_pixmap *dst, fz_pixmap *src)
{
unsigned char *s = src->samples;
unsigned char *d = dst->samples;
@@ -373,7 +373,7 @@ static void fast_rgb_to_bgr(fz_pixmap *src, fz_pixmap *dst)
}
static void
-fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
+fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *dst, fz_pixmap *src)
{
float srcv[FZ_MAX_COLORS];
float dstv[FZ_MAX_COLORS];
@@ -404,7 +404,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
srcv[1] = *s++ - 128;
srcv[2] = *s++ - 128;
- fz_convert_color(ctx, ss, srcv, ds, dstv);
+ fz_convert_color(ctx, ds, dstv, ss, srcv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
@@ -424,7 +424,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
for (k = 0; k < srcn; k++)
srcv[k] = *s++ / 255.0f;
- fz_convert_color(ctx, ss, srcv, ds, dstv);
+ fz_convert_color(ctx, ds, dstv, ss, srcv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
@@ -442,7 +442,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
for (i = 0; i < 256; i++)
{
srcv[0] = i / 255.0f;
- fz_convert_color(ctx, ss, srcv, ds, dstv);
+ fz_convert_color(ctx, ds, dstv, ss, srcv);
for (k = 0; k < dstn; k++)
lookup[i * dstn + k] = dstv[k] * 255;
}
@@ -465,7 +465,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
fz_hash_table *lookup;
unsigned char *color;
- lookup = fz_new_hash_table(ctx, 509, srcn);
+ lookup = fz_new_hash_table(ctx, 509, srcn, -1);
for (y = 0; y < src->h; y++)
{
@@ -483,7 +483,7 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
{
for (k = 0; k < srcn; k++)
srcv[k] = *s++ / 255.0f;
- fz_convert_color(ctx, ss, srcv, ds, dstv);
+ fz_convert_color(ctx, ds, dstv, ss, srcv);
for (k = 0; k < dstn; k++)
*d++ = dstv[k] * 255;
@@ -499,50 +499,48 @@ fz_std_conv_pixmap(fz_context *ctx, fz_pixmap *src, fz_pixmap *dst)
}
void
-fz_convert_pixmap(fz_context *ctx, fz_pixmap *sp, fz_pixmap *dp)
+fz_convert_pixmap(fz_context *ctx, fz_pixmap *dp, fz_pixmap *sp)
{
fz_colorspace *ss = sp->colorspace;
fz_colorspace *ds = dp->colorspace;
assert(ss && ds);
- if (sp->mask)
- dp->mask = fz_keep_pixmap(ctx, sp->mask);
dp->interpolate = sp->interpolate;
if (ss == fz_device_gray)
{
- if (ds == fz_device_rgb) fast_gray_to_rgb(sp, dp);
- else if (ds == fz_device_bgr) fast_gray_to_rgb(sp, dp); /* bgr == rgb here */
- else if (ds == fz_device_cmyk) fast_gray_to_cmyk(sp, dp);
- else fz_std_conv_pixmap(ctx, sp, dp);
+ if (ds == fz_device_rgb) fast_gray_to_rgb(dp, sp);
+ else if (ds == fz_device_bgr) fast_gray_to_rgb(dp, sp); /* bgr == rgb here */
+ else if (ds == fz_device_cmyk) fast_gray_to_cmyk(dp, sp);
+ else fz_std_conv_pixmap(ctx, dp, sp);
}
else if (ss == fz_device_rgb)
{
- if (ds == fz_device_gray) fast_rgb_to_gray(sp, dp);
- else if (ds == fz_device_bgr) fast_rgb_to_bgr(sp, dp);
- else if (ds == fz_device_cmyk) fast_rgb_to_cmyk(sp, dp);
- else fz_std_conv_pixmap(ctx, sp, dp);
+ if (ds == fz_device_gray) fast_rgb_to_gray(dp, sp);
+ else if (ds == fz_device_bgr) fast_rgb_to_bgr(dp, sp);
+ else if (ds == fz_device_cmyk) fast_rgb_to_cmyk(dp, sp);
+ else fz_std_conv_pixmap(ctx, dp, sp);
}
else if (ss == fz_device_bgr)
{
- if (ds == fz_device_gray) fast_bgr_to_gray(sp, dp);
- else if (ds == fz_device_rgb) fast_rgb_to_bgr(sp, dp); /* bgr = rgb here */
+ if (ds == fz_device_gray) fast_bgr_to_gray(dp, sp);
+ else if (ds == fz_device_rgb) fast_rgb_to_bgr(dp, sp); /* bgr = rgb here */
else if (ds == fz_device_cmyk) fast_bgr_to_cmyk(sp, dp);
- else fz_std_conv_pixmap(ctx, sp, dp);
+ else fz_std_conv_pixmap(ctx, dp, sp);
}
else if (ss == fz_device_cmyk)
{
- if (ds == fz_device_gray) fast_cmyk_to_gray(sp, dp);
- else if (ds == fz_device_bgr) fast_cmyk_to_bgr(ctx, sp, dp);
- else if (ds == fz_device_rgb) fast_cmyk_to_rgb(ctx, sp, dp);
- else fz_std_conv_pixmap(ctx, sp, dp);
+ if (ds == fz_device_gray) fast_cmyk_to_gray(dp, sp);
+ else if (ds == fz_device_bgr) fast_cmyk_to_bgr(ctx, dp, sp);
+ else if (ds == fz_device_rgb) fast_cmyk_to_rgb(ctx, dp, sp);
+ else fz_std_conv_pixmap(ctx, dp, sp);
}
- else fz_std_conv_pixmap(ctx, sp, dp);
+ else fz_std_conv_pixmap(ctx, dp, sp);
}
/* Convert a single color */
@@ -569,7 +567,7 @@ fz_std_conv_color(fz_context *ctx, fz_colorspace *srcs, float *srcv, fz_colorspa
}
void
-fz_convert_color(fz_context *ctx, fz_colorspace *ss, float *sv, fz_colorspace *ds, float *dv)
+fz_convert_color(fz_context *ctx, fz_colorspace *ds, float *dv, fz_colorspace *ss, float *sv)
{
if (ss == fz_device_gray)
{
diff --git a/fitz/res_font.c b/fitz/res_font.c
index 7a194da6..c1db35d8 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -93,7 +93,7 @@ fz_drop_font(fz_context *ctx, fz_font *font)
if (font->t3procs)
{
if (font->t3resources)
- fz_drop_obj(font->t3resources);
+ font->t3freeres(font->t3doc, font->t3resources);
for (i = 0; i < 256; i++)
if (font->t3procs[i])
fz_drop_buffer(ctx, font->t3procs[i]);
@@ -387,12 +387,13 @@ fz_copy_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap)
/* The glyph cache lock is always taken when this is called. */
fz_pixmap *
-fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm)
+fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, int aa)
{
FT_Face face = font->ft_face;
FT_Matrix m;
FT_Vector v;
FT_Error fterr;
+ fz_pixmap *result;
trm = fz_adjust_ft_glyph_width(ctx, font, gid, trm);
@@ -420,7 +421,7 @@ fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm)
fz_warn(ctx, "freetype setting character size: %s", ft_error_string(fterr));
FT_Set_Transform(face, &m, &v);
- if (fz_get_aa_level(ctx) == 0)
+ if (aa == 0)
{
/* If you really want grid fitting, enable this code. */
float scale = fz_matrix_expansion(trm);
@@ -470,16 +471,17 @@ fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm)
FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32);
}
- fterr = FT_Render_Glyph(face->glyph, fz_get_aa_level(ctx) > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
+ fterr = FT_Render_Glyph(face->glyph, fz_aa_level(ctx) > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
if (fterr)
{
fz_warn(ctx, "freetype render glyph (gid %d): %s", gid, ft_error_string(fterr));
fz_unlock(ctx, FZ_LOCK_FREETYPE);
return NULL;
}
- fz_unlock(ctx, FZ_LOCK_FREETYPE);
- return fz_copy_ft_bitmap(ctx, face->glyph->bitmap_left, face->glyph->bitmap_top, &face->glyph->bitmap);
+ result = fz_copy_ft_bitmap(ctx, face->glyph->bitmap_left, face->glyph->bitmap_top, &face->glyph->bitmap);
+ fz_unlock(ctx, FZ_LOCK_FREETYPE);
+ return result;
}
fz_pixmap *
@@ -573,7 +575,7 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix tr
FT_Stroker_Done(stroker);
- fterr = FT_Glyph_To_Bitmap(&glyph, fz_get_aa_level(ctx) > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
+ fterr = FT_Glyph_To_Bitmap(&glyph, fz_aa_level(ctx) > 0 ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
if (fterr)
{
fz_warn(ctx, "FT_Glyph_To_Bitmap: %s", ft_error_string(fterr));
@@ -754,7 +756,7 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix trm, fz_co
bbox.x1++;
bbox.y1++;
- glyph = fz_new_pixmap_with_rect(ctx, model ? model : fz_device_gray, bbox);
+ glyph = fz_new_pixmap_with_bbox(ctx, model ? model : fz_device_gray, bbox);
fz_clear_pixmap(ctx, glyph);
ctm = fz_concat(font->t3matrix, trm);
@@ -806,29 +808,29 @@ fz_render_t3_glyph_direct(fz_context *ctx, fz_device *dev, fz_font *font, int gi
}
void
-fz_debug_font(fz_context *ctx, fz_font *font)
+fz_print_font(fz_context *ctx, FILE *out, fz_font *font)
{
- printf("font '%s' {\n", font->name);
+ fprintf(out, "font '%s' {\n", font->name);
if (font->ft_face)
{
- printf("\tfreetype face %p\n", font->ft_face);
+ fprintf(out, "\tfreetype face %p\n", font->ft_face);
if (font->ft_substitute)
- printf("\tsubstitute font\n");
+ fprintf(out, "\tsubstitute font\n");
}
if (font->t3procs)
{
- printf("\ttype3 matrix [%g %g %g %g]\n",
+ fprintf(out, "\ttype3 matrix [%g %g %g %g]\n",
font->t3matrix.a, font->t3matrix.b,
font->t3matrix.c, font->t3matrix.d);
- printf("\ttype3 bbox [%g %g %g %g]\n",
+ fprintf(out, "\ttype3 bbox [%g %g %g %g]\n",
font->bbox.x0, font->bbox.y0,
font->bbox.x1, font->bbox.y1);
}
- printf("}\n");
+ fprintf(out, "}\n");
}
fz_rect
diff --git a/fitz/res_halftone.c b/fitz/res_halftone.c
index 7258ad01..daad6e37 100644
--- a/fitz/res_halftone.c
+++ b/fitz/res_halftone.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_halftone *
fz_new_halftone(fz_context *ctx, int comps)
@@ -56,7 +56,7 @@ static unsigned char mono_ht[] =
0xF2, 0x72, 0xD2, 0x52, 0xFA, 0x7A, 0xDA, 0x5A, 0xF0, 0x70, 0xD0, 0x50, 0xF8, 0x78, 0xD8, 0x58
};
-fz_halftone *fz_get_default_halftone(fz_context *ctx, int num_comps)
+fz_halftone *fz_default_halftone(fz_context *ctx, int num_comps)
{
fz_halftone *ht = fz_new_halftone(ctx, num_comps);
assert(num_comps == 1); /* Only support 1 component for now */
@@ -162,13 +162,18 @@ fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht)
fz_bitmap *out;
unsigned char *ht_line, *o, *p;
int w, h, x, y, n, pstride, ostride;
+ fz_halftone *ht_orig = ht;
- if (!pix || !ht)
+ if (!pix)
return NULL;
assert(pix->n == 2); /* Mono + Alpha */
n = pix->n-1; /* Remove alpha */
+ if (ht == NULL)
+ {
+ ht = fz_default_halftone(ctx, n);
+ }
ht_line = fz_malloc(ctx, pix->w * n);
out = fz_new_bitmap(ctx, pix->w, pix->h, n);
o = out->samples;
@@ -187,5 +192,7 @@ fz_bitmap *fz_halftone_pixmap(fz_context *ctx, fz_pixmap *pix, fz_halftone *ht)
o += ostride;
p += pstride;
}
+ if (!ht_orig)
+ fz_drop_halftone(ctx, ht);
return out;
}
diff --git a/fitz/res_path.c b/fitz/res_path.c
index a645f9d5..45ead677 100644
--- a/fitz/res_path.c
+++ b/fitz/res_path.c
@@ -1,5 +1,5 @@
#include <assert.h>
-#include "fitz.h"
+#include "fitz-internal.h"
fz_path *
fz_new_path(fz_context *ctx)
@@ -316,7 +316,7 @@ fz_transform_path(fz_context *ctx, fz_path *path, fz_matrix ctm)
}
void
-fz_debug_path(fz_context *ctx, fz_path *path, int indent)
+fz_print_path(fz_context *ctx, FILE *out, fz_path *path, int indent)
{
float x, y;
int i = 0;
@@ -324,32 +324,32 @@ fz_debug_path(fz_context *ctx, fz_path *path, int indent)
while (i < path->len)
{
for (n = 0; n < indent; n++)
- putchar(' ');
+ fputc(' ', out);
switch (path->items[i++].k)
{
case FZ_MOVETO:
x = path->items[i++].v;
y = path->items[i++].v;
- printf("%g %g m\n", x, y);
+ fprintf(out, "%g %g m\n", x, y);
break;
case FZ_LINETO:
x = path->items[i++].v;
y = path->items[i++].v;
- printf("%g %g l\n", x, y);
+ fprintf(out, "%g %g l\n", x, y);
break;
case FZ_CURVETO:
x = path->items[i++].v;
y = path->items[i++].v;
- printf("%g %g ", x, y);
+ fprintf(out, "%g %g ", x, y);
x = path->items[i++].v;
y = path->items[i++].v;
- printf("%g %g ", x, y);
+ fprintf(out, "%g %g ", x, y);
x = path->items[i++].v;
y = path->items[i++].v;
- printf("%g %g c\n", x, y);
+ fprintf(out, "%g %g c\n", x, y);
break;
case FZ_CLOSE_PATH:
- printf("h\n");
+ fprintf(out, "h\n");
break;
}
}
diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c
index dbed0842..a160b6ca 100644
--- a/fitz/res_pixmap.c
+++ b/fitz/res_pixmap.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_pixmap *
fz_keep_pixmap(fz_context *ctx, fz_pixmap *pix)
@@ -17,8 +17,6 @@ fz_free_pixmap_imp(fz_context *ctx, fz_storable *pix_)
{
fz_pixmap *pix = (fz_pixmap *)pix_;
- if (pix->mask)
- fz_drop_pixmap(ctx, pix->mask);
if (pix->colorspace)
fz_drop_colorspace(ctx, pix->colorspace);
if (pix->free_samples)
@@ -37,7 +35,6 @@ fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h
pix->y = 0;
pix->w = w;
pix->h = h;
- pix->mask = NULL;
pix->interpolate = 1;
pix->xres = 96;
pix->yres = 96;
@@ -65,6 +62,8 @@ fz_new_pixmap_with_data(fz_context *ctx, fz_colorspace *colorspace, int w, int h
}
fz_catch(ctx)
{
+ if (colorspace)
+ fz_drop_colorspace(ctx, colorspace);
fz_free(ctx, pix);
fz_rethrow(ctx);
}
@@ -81,7 +80,7 @@ fz_new_pixmap(fz_context *ctx, fz_colorspace *colorspace, int w, int h)
}
fz_pixmap *
-fz_new_pixmap_with_rect(fz_context *ctx, fz_colorspace *colorspace, fz_bbox r)
+fz_new_pixmap_with_bbox(fz_context *ctx, fz_colorspace *colorspace, fz_bbox r)
{
fz_pixmap *pixmap;
pixmap = fz_new_pixmap(ctx, colorspace, r.x1 - r.x0, r.y1 - r.y0);
@@ -91,7 +90,7 @@ fz_new_pixmap_with_rect(fz_context *ctx, fz_colorspace *colorspace, fz_bbox r)
}
fz_pixmap *
-fz_new_pixmap_with_rect_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_bbox r, unsigned char *samples)
+fz_new_pixmap_with_bbox_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_bbox r, unsigned char *samples)
{
fz_pixmap *pixmap;
pixmap = fz_new_pixmap_with_data(ctx, colorspace, r.x1 - r.x0, r.y1 - r.y0, samples);
@@ -101,7 +100,7 @@ fz_new_pixmap_with_rect_and_data(fz_context *ctx, fz_colorspace *colorspace, fz_
}
fz_bbox
-fz_bound_pixmap(fz_pixmap *pix)
+fz_pixmap_bbox(fz_context *ctx, fz_pixmap *pix)
{
fz_bbox bbox;
bbox.x0 = pix->x;
@@ -111,6 +110,29 @@ fz_bound_pixmap(fz_pixmap *pix)
return bbox;
}
+fz_bbox
+fz_pixmap_bbox_no_ctx(fz_pixmap *pix)
+{
+ fz_bbox bbox;
+ bbox.x0 = pix->x;
+ bbox.y0 = pix->y;
+ bbox.x1 = pix->x + pix->w;
+ bbox.y1 = pix->y + pix->h;
+ return bbox;
+}
+
+int
+fz_pixmap_width(fz_context *ctx, fz_pixmap *pix)
+{
+ return pix->w;
+}
+
+int
+fz_pixmap_height(fz_context *ctx, fz_pixmap *pix)
+{
+ return pix->h;
+}
+
void
fz_clear_pixmap(fz_context *ctx, fz_pixmap *pix)
{
@@ -145,8 +167,8 @@ fz_copy_pixmap_rect(fz_context *ctx, fz_pixmap *dest, fz_pixmap *src, fz_bbox r)
unsigned char *destp;
int y, w, destspan, srcspan;
- r = fz_intersect_bbox(r, fz_bound_pixmap(dest));
- r = fz_intersect_bbox(r, fz_bound_pixmap(src));
+ r = fz_intersect_bbox(r, fz_pixmap_bbox(ctx, dest));
+ r = fz_intersect_bbox(r, fz_pixmap_bbox(ctx, src));
w = r.x1 - r.x0;
y = r.y1 - r.y0;
if (w <= 0 || y <= 0)
@@ -172,7 +194,7 @@ fz_clear_pixmap_rect_with_value(fz_context *ctx, fz_pixmap *dest, int value, fz_
unsigned char *destp;
int x, y, w, k, destspan;
- r = fz_intersect_bbox(r, fz_bound_pixmap(dest));
+ r = fz_intersect_bbox(r, fz_pixmap_bbox(ctx, dest));
w = r.x1 - r.x0;
y = r.y1 - r.y0;
if (w <= 0 || y <= 0)
@@ -250,7 +272,7 @@ fz_alpha_from_gray(fz_context *ctx, fz_pixmap *gray, int luminosity)
assert(gray->n == 2);
- alpha = fz_new_pixmap_with_rect(ctx, NULL, fz_bound_pixmap(gray));
+ alpha = fz_new_pixmap_with_bbox(ctx, NULL, fz_pixmap_bbox(ctx, gray));
dp = alpha->samples;
sp = gray->samples;
if (!luminosity)
@@ -283,6 +305,27 @@ fz_invert_pixmap(fz_context *ctx, fz_pixmap *pix)
}
}
+void fz_invert_pixmap_rect(fz_pixmap *image, fz_bbox rect)
+{
+ unsigned char *p;
+ int x, y, n;
+
+ int x0 = CLAMP(rect.x0 - image->x, 0, image->w - 1);
+ int x1 = CLAMP(rect.x1 - image->x, 0, image->w - 1);
+ int y0 = CLAMP(rect.y0 - image->y, 0, image->h - 1);
+ int y1 = CLAMP(rect.y1 - image->y, 0, image->h - 1);
+
+ for (y = y0; y < y1; y++)
+ {
+ p = image->samples + (y * image->w + x0) * image->n;
+ for (x = x0; x < x1; x++)
+ {
+ for (n = image->n; n > 0; n--, p++)
+ *p = 255 - *p;
+ }
+ }
+}
+
void
fz_gamma_pixmap(fz_context *ctx, fz_pixmap *pix, float gamma)
{
@@ -549,3 +592,23 @@ fz_pixmap_size(fz_context *ctx, fz_pixmap * pix)
return 0;
return sizeof(*pix) + pix->n * pix->w * pix->h;
}
+
+fz_pixmap *
+fz_image_to_pixmap(fz_context *ctx, fz_image *image, int w, int h)
+{
+ if (image == NULL)
+ return NULL;
+ return image->get_pixmap(ctx, image, w, h);
+}
+
+fz_image *
+fz_keep_image(fz_context *ctx, fz_image *image)
+{
+ return (fz_image *)fz_keep_storable(ctx, &image->storable);
+}
+
+void
+fz_drop_image(fz_context *ctx, fz_image *image)
+{
+ fz_drop_storable(ctx, &image->storable);
+}
diff --git a/fitz/res_shade.c b/fitz/res_shade.c
index 3fdf2e15..d2b2f44b 100644
--- a/fitz/res_shade.c
+++ b/fitz/res_shade.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_shade *
fz_keep_shade(fz_context *ctx, fz_shade *shade)
@@ -68,59 +68,59 @@ fz_bound_shade(fz_context *ctx, fz_shade *shade, fz_matrix ctm)
}
void
-fz_debug_shade(fz_context *ctx, fz_shade *shade)
+fz_print_shade(fz_context *ctx, FILE *out, fz_shade *shade)
{
int i, j, n;
float *vertex;
int triangle;
- printf("shading {\n");
+ fprintf(out, "shading {\n");
switch (shade->type)
{
- case FZ_LINEAR: printf("\ttype linear\n"); break;
- case FZ_RADIAL: printf("\ttype radial\n"); break;
- case FZ_MESH: printf("\ttype mesh\n"); break;
+ case FZ_LINEAR: fprintf(out, "\ttype linear\n"); break;
+ case FZ_RADIAL: fprintf(out, "\ttype radial\n"); break;
+ case FZ_MESH: fprintf(out, "\ttype mesh\n"); break;
}
- printf("\tbbox [%g %g %g %g]\n",
+ fprintf(out, "\tbbox [%g %g %g %g]\n",
shade->bbox.x0, shade->bbox.y0,
shade->bbox.x1, shade->bbox.y1);
- printf("\tcolorspace %s\n", shade->colorspace->name);
+ fprintf(out, "\tcolorspace %s\n", shade->colorspace->name);
- printf("\tmatrix [%g %g %g %g %g %g]\n",
+ fprintf(out, "\tmatrix [%g %g %g %g %g %g]\n",
shade->matrix.a, shade->matrix.b, shade->matrix.c,
shade->matrix.d, shade->matrix.e, shade->matrix.f);
if (shade->use_background)
{
- printf("\tbackground [");
+ fprintf(out, "\tbackground [");
for (i = 0; i < shade->colorspace->n; i++)
- printf("%s%g", i == 0 ? "" : " ", shade->background[i]);
- printf("]\n");
+ fprintf(out, "%s%g", i == 0 ? "" : " ", shade->background[i]);
+ fprintf(out, "]\n");
}
if (shade->use_function)
{
- printf("\tfunction\n");
+ fprintf(out, "\tfunction\n");
n = 3;
}
else
n = 2 + shade->colorspace->n;
- printf("\tvertices: %d\n", shade->mesh_len);
+ fprintf(out, "\tvertices: %d\n", shade->mesh_len);
vertex = shade->mesh;
triangle = 0;
i = 0;
while (i < shade->mesh_len)
{
- printf("\t%d:(%g, %g): ", triangle, vertex[0], vertex[1]);
+ fprintf(out, "\t%d:(%g, %g): ", triangle, vertex[0], vertex[1]);
for (j = 2; j < n; j++)
- printf("%s%g", j == 2 ? "" : " ", vertex[j]);
- printf("\n");
+ fprintf(out, "%s%g", j == 2 ? "" : " ", vertex[j]);
+ fprintf(out, "\n");
vertex += n;
i++;
@@ -128,5 +128,5 @@ fz_debug_shade(fz_context *ctx, fz_shade *shade)
triangle++;
}
- printf("}\n");
+ fprintf(out, "}\n");
}
diff --git a/fitz/res_store.c b/fitz/res_store.c
index 5eec1f0d..8e5375d6 100644
--- a/fitz/res_store.c
+++ b/fitz/res_store.c
@@ -1,21 +1,16 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+
+typedef struct fz_item_s fz_item;
struct fz_item_s
{
- fz_obj *key;
+ void *key;
fz_storable *val;
unsigned int size;
fz_item *next;
fz_item *prev;
fz_store *store;
-};
-
-struct refkey
-{
- fz_store_free_fn *free;
- int num;
- int gen;
+ fz_store_type *type;
};
struct fz_store_s
@@ -43,7 +38,7 @@ fz_new_store_context(fz_context *ctx, unsigned int max)
store = fz_malloc_struct(ctx, fz_store);
fz_try(ctx)
{
- store->hash = fz_new_hash_table(ctx, 4096, sizeof(struct refkey));
+ store->hash = fz_new_hash_table(ctx, 4096, sizeof(fz_store_hash), FZ_LOCK_ALLOC);
}
fz_catch(ctx)
{
@@ -114,20 +109,19 @@ evict(fz_context *ctx, fz_item *item)
store->head = item->next;
/* Drop a reference to the value (freeing if required) */
drop = (item->val->refs > 0 && --item->val->refs == 0);
- fz_unlock(ctx, FZ_LOCK_ALLOC);
/* Remove from the hash table */
- if (fz_is_indirect(item->key))
+ if (item->type->make_hash_key)
{
- struct refkey refkey;
- refkey.free = item->val->free;
- refkey.num = fz_to_num(item->key);
- refkey.gen = fz_to_gen(item->key);
- fz_hash_remove(ctx, store->hash, &refkey);
+ fz_store_hash hash = { NULL };
+ hash.free = item->val->free;
+ if (item->type->make_hash_key(&hash, item->key))
+ fz_hash_remove(ctx, store->hash, &hash);
}
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
if (drop)
item->val->free(ctx, item->val);
/* Always drops the key and free the item */
- fz_drop_obj(item->key);
+ item->type->drop_key(ctx, item->key);
fz_free(ctx, item);
fz_lock(ctx, FZ_LOCK_ALLOC);
}
@@ -194,30 +188,21 @@ ensure_space(fz_context *ctx, unsigned int tofree)
return count;
}
-void
-fz_store_item(fz_context *ctx, fz_obj *key, void *val_, unsigned int itemsize)
+void *
+fz_store_item(fz_context *ctx, void *key, void *val_, unsigned int itemsize, fz_store_type *type)
{
fz_item *item = NULL;
unsigned int size;
fz_storable *val = (fz_storable *)val_;
fz_store *store = ctx->store;
- int indirect;
- struct refkey refkey;
+ fz_store_hash hash = { NULL };
+ int use_hash = 0;
if (!store)
- return;
+ return NULL;
fz_var(item);
- /* Form the key before we take the lock */
- indirect = fz_is_indirect(key);
- if (indirect)
- {
- refkey.free = val->free;
- refkey.num = fz_to_num(key);
- refkey.gen = fz_to_gen(key);
- }
-
/* If we fail for any reason, we swallow the exception and continue.
* All that the above program will see is that we failed to store
* the item. */
@@ -227,9 +212,16 @@ fz_store_item(fz_context *ctx, fz_obj *key, void *val_, unsigned int itemsize)
}
fz_catch(ctx)
{
- return;
+ return NULL;
}
+ if (type->make_hash_key)
+ {
+ hash.free = val->free;
+ use_hash = type->make_hash_key(&hash, key);
+ }
+
+ type->keep_key(ctx, key);
fz_lock(ctx, FZ_LOCK_ALLOC);
if (store->max != FZ_STORE_UNLIMITED)
{
@@ -242,34 +234,44 @@ fz_store_item(fz_context *ctx, fz_obj *key, void *val_, unsigned int itemsize)
/* Failed to free any space */
fz_unlock(ctx, FZ_LOCK_ALLOC);
fz_free(ctx, item);
- return;
+ type->drop_key(ctx, key);
+ return NULL;
}
}
}
store->size += itemsize;
- item->key = fz_keep_obj(key);
+ item->key = key;
item->val = val;
item->size = itemsize;
item->next = NULL;
+ item->type = type;
/* If we can index it fast, put it into the hash table */
- if (indirect)
+ if (use_hash)
{
- fz_unlock(ctx, FZ_LOCK_ALLOC);
+ fz_item *existing;
+
fz_try(ctx)
{
- fz_hash_insert(ctx, store->hash, &refkey, item);
+ /* May drop and retake the lock */
+ existing = fz_hash_insert(ctx, store->hash, &hash, item);
}
fz_catch(ctx)
{
- fz_free(ctx, item);
- fz_lock(ctx, FZ_LOCK_ALLOC);
store->size -= itemsize;
fz_unlock(ctx, FZ_LOCK_ALLOC);
- return;
+ fz_free(ctx, item);
+ return NULL;
+ }
+ if (existing)
+ {
+ /* Take a new reference */
+ existing->val->refs++;
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
+ fz_free(ctx, item);
+ return existing->val;
}
- fz_lock(ctx, FZ_LOCK_ALLOC);
}
/* Now we can never fail, bump the ref */
if (val->refs > 0)
@@ -283,15 +285,17 @@ fz_store_item(fz_context *ctx, fz_obj *key, void *val_, unsigned int itemsize)
store->head = item;
item->prev = NULL;
fz_unlock(ctx, FZ_LOCK_ALLOC);
+
+ return NULL;
}
void *
-fz_find_item(fz_context *ctx, fz_store_free_fn *free, fz_obj *key)
+fz_find_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type)
{
- struct refkey refkey;
fz_item *item;
fz_store *store = ctx->store;
- int indirect;
+ fz_store_hash hash = { NULL };
+ int use_hash = 0;
if (!store)
return NULL;
@@ -299,27 +303,24 @@ fz_find_item(fz_context *ctx, fz_store_free_fn *free, fz_obj *key)
if (!key)
return NULL;
- /* Form the key before we take the lock */
- indirect = fz_is_indirect(key);
- if (indirect)
+ if (type->make_hash_key)
{
- refkey.free = free;
- refkey.num = fz_to_num(key);
- refkey.gen = fz_to_gen(key);
+ hash.free = free;
+ use_hash = type->make_hash_key(&hash, key);
}
fz_lock(ctx, FZ_LOCK_ALLOC);
- if (indirect)
+ if (use_hash)
{
/* We can find objects keyed on indirected objects quickly */
- item = fz_hash_find(ctx, store->hash, &refkey);
+ item = fz_hash_find(ctx, store->hash, &hash);
}
else
{
/* Others we have to hunt for slowly */
for (item = store->head; item; item = item->next)
{
- if (item->val->free == free && !fz_objcmp(item->key, key))
+ if (item->val->free == free && !type->cmp_key(item->key, key))
break;
}
}
@@ -355,35 +356,33 @@ fz_find_item(fz_context *ctx, fz_store_free_fn *free, fz_obj *key)
}
void
-fz_remove_item(fz_context *ctx, fz_store_free_fn *free, fz_obj *key)
+fz_remove_item(fz_context *ctx, fz_store_free_fn *free, void *key, fz_store_type *type)
{
- struct refkey refkey;
fz_item *item;
fz_store *store = ctx->store;
- int drop, indirect;
+ int drop;
+ fz_store_hash hash;
+ int use_hash = 0;
- /* Form the key before we take the lock */
- indirect = fz_is_indirect(key);
- if (indirect)
+ if (type->make_hash_key)
{
- refkey.free = free;
- refkey.num = fz_to_num(key);
- refkey.gen = fz_to_gen(key);
+ hash.free = free;
+ use_hash = type->make_hash_key(&hash, key);
}
fz_lock(ctx, FZ_LOCK_ALLOC);
- if (indirect)
+ if (use_hash)
{
/* We can find objects keyed on indirect objects quickly */
- item = fz_hash_find(ctx, store->hash, &refkey);
+ item = fz_hash_find(ctx, store->hash, &hash);
if (item)
- fz_hash_remove(ctx, store->hash, &refkey);
+ fz_hash_remove(ctx, store->hash, &hash);
}
else
{
/* Others we have to hunt for slowly */
for (item = store->head; item; item = item->next)
- if (item->val->free == free && !fz_objcmp(item->key, key))
+ if (item->val->free == free && !type->cmp_key(item->key, key))
break;
}
if (item)
@@ -400,7 +399,7 @@ fz_remove_item(fz_context *ctx, fz_store_free_fn *free, fz_obj *key)
fz_unlock(ctx, FZ_LOCK_ALLOC);
if (drop)
item->val->free(ctx, item->val);
- fz_drop_obj(item->key);
+ type->drop_key(ctx, item->key);
fz_free(ctx, item);
}
else
@@ -425,7 +424,7 @@ fz_empty_store(fz_context *ctx)
}
fz_store *
-fz_store_keep(fz_context *ctx)
+fz_keep_store_context(fz_context *ctx)
{
if (ctx == NULL || ctx->store == NULL)
return NULL;
@@ -454,28 +453,26 @@ fz_drop_store_context(fz_context *ctx)
}
void
-fz_debug_store(fz_context *ctx)
+fz_print_store(fz_context *ctx, FILE *out)
{
fz_item *item, *next;
fz_store *store = ctx->store;
- printf("-- resource store contents --\n");
+ fprintf(out, "-- resource store contents --\n");
fz_lock(ctx, FZ_LOCK_ALLOC);
for (item = store->head; item; item = next)
{
next = item->next;
- next->val->refs++;
- printf("store[*][refs=%d][size=%d] ", item->val->refs, item->size);
+ if (next)
+ next->val->refs++;
+ fprintf(out, "store[*][refs=%d][size=%d] ", item->val->refs, item->size);
fz_unlock(ctx, FZ_LOCK_ALLOC);
- if (fz_is_indirect(item->key))
- {
- printf("(%d %d R) ", fz_to_num(item->key), fz_to_gen(item->key));
- } else
- fz_debug_obj(item->key);
- printf(" = %p\n", item->val);
+ item->type->debug(item->key);
+ fprintf(out, " = %p\n", item->val);
fz_lock(ctx, FZ_LOCK_ALLOC);
- next->val->refs--;
+ if (next)
+ next->val->refs--;
}
fz_unlock(ctx, FZ_LOCK_ALLOC);
}
@@ -524,7 +521,7 @@ int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase)
#ifdef DEBUG_SCAVENGING
printf("Scavenging: store=%d size=%d phase=%d\n", store->size, size, *phase);
- fz_debug_store(ctx);
+ fz_print_store(ctx, stderr);
Memento_stats();
#endif
do
@@ -552,7 +549,7 @@ int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase)
{
#ifdef DEBUG_SCAVENGING
printf("scavenged: store=%d\n", store->size);
- fz_debug_store(ctx);
+ fz_print_store(ctx, stderr);
Memento_stats();
#endif
return 1;
@@ -562,7 +559,7 @@ int fz_store_scavenge(fz_context *ctx, unsigned int size, int *phase)
#ifdef DEBUG_SCAVENGING
printf("scavenging failed\n");
- fz_debug_store(ctx);
+ fz_print_store(ctx, stderr);
Memento_listBlocks();
#endif
return 0;
diff --git a/fitz/res_text.c b/fitz/res_text.c
index cdfaaa98..643b4c9f 100644
--- a/fitz/res_text.c
+++ b/fitz/res_text.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_text *
fz_new_text(fz_context *ctx, fz_font *font, fz_matrix trm, int wmode)
@@ -118,23 +118,30 @@ fz_add_text(fz_context *ctx, fz_text *text, int gid, int ucs, float x, float y)
text->len++;
}
-static int isxmlmeta(int c)
+static int
+isxmlmeta(int c)
{
return c < 32 || c >= 128 || c == '&' || c == '<' || c == '>' || c == '\'' || c == '"';
}
-void fz_debug_text(fz_context *ctx, fz_text *text, int indent)
+static void
+do_print_text(FILE *out, fz_text *text, int indent)
{
int i, n;
for (i = 0; i < text->len; i++)
{
for (n = 0; n < indent; n++)
- putchar(' ');
+ fputc(' ', out);
if (!isxmlmeta(text->items[i].ucs))
- printf("<g ucs=\"%c\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
+ fprintf(out, "<g ucs=\"%c\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
text->items[i].ucs, text->items[i].gid, text->items[i].x, text->items[i].y);
else
- printf("<g ucs=\"U+%04X\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
+ fprintf(out, "<g ucs=\"U+%04X\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n",
text->items[i].ucs, text->items[i].gid, text->items[i].x, text->items[i].y);
}
}
+
+void fz_print_text(fz_context *ctx, FILE *out, fz_text *text)
+{
+ do_print_text(out, text, 0);
+}
diff --git a/fitz/stm_buffer.c b/fitz/stm_buffer.c
index 7f9d521d..4be0165a 100644
--- a/fitz/stm_buffer.c
+++ b/fitz/stm_buffer.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_buffer *
fz_new_buffer(fz_context *ctx, int size)
@@ -28,7 +28,12 @@ fz_buffer *
fz_keep_buffer(fz_context *ctx, fz_buffer *buf)
{
if (buf)
+ {
+ if (buf->refs == 1 && buf->cap > buf->len+1)
+ fz_resize_buffer(ctx, buf, buf->len);
buf->refs ++;
+ }
+
return buf;
}
@@ -58,3 +63,18 @@ fz_grow_buffer(fz_context *ctx, fz_buffer *buf)
{
fz_resize_buffer(ctx, buf, (buf->cap * 3) / 2);
}
+
+void
+fz_trim_buffer(fz_context *ctx, fz_buffer *buf)
+{
+ if (buf->cap > buf->len+1)
+ fz_resize_buffer(ctx, buf, buf->len);
+}
+
+int
+fz_buffer_storage(fz_context *ctx, fz_buffer *buf, unsigned char **datap)
+{
+ if (datap)
+ *datap = (buf ? buf->data : NULL);
+ return (buf ? buf->len : 0);
+}
diff --git a/fitz/stm_open.c b/fitz/stm_open.c
index e634f729..1e303825 100644
--- a/fitz/stm_open.c
+++ b/fitz/stm_open.c
@@ -1,4 +1,4 @@
-#include "fitz.h"
+#include "fitz-internal.h"
fz_stream *
fz_new_stream(fz_context *ctx, void *state,
diff --git a/fitz/stm_read.c b/fitz/stm_read.c
index 2066b14c..216d2207 100644
--- a/fitz/stm_read.c
+++ b/fitz/stm_read.c
@@ -1,4 +1,6 @@
-#include "fitz.h"
+#include "fitz-internal.h"
+
+#define MIN_BOMB (100 << 20)
int
fz_read(fz_stream *stm, unsigned char *buf, int len)
@@ -101,16 +103,15 @@ fz_read_all(fz_stream *stm, int initial)
if (initial < 1024)
initial = 1024;
- buf = fz_new_buffer(ctx, initial);
+ buf = fz_new_buffer(ctx, initial+1);
while (1)
{
if (buf->len == buf->cap)
fz_grow_buffer(ctx, buf);
- if (buf->len / 200 > initial)
+ if (buf->len >= MIN_BOMB && buf->len / 200 > initial)
{
- fz_drop_buffer(ctx, buf);
fz_throw(ctx, "compression bomb detected");
}
@@ -126,6 +127,7 @@ fz_read_all(fz_stream *stm, int initial)
fz_drop_buffer(ctx, buf);
fz_rethrow(ctx);
}
+ fz_trim_buffer(ctx, buf);
return buf;
}
diff --git a/ios/main.m b/ios/main.m
index 6f873ddb..2af4d537 100644
--- a/ios/main.m
+++ b/ios/main.m
@@ -216,7 +216,7 @@ static UIImage *renderPage(struct document *doc, int number, CGSize screenSize)
ctm = fz_scale(scale.width, scale.height);
bbox = (fz_bbox){0, 0, pageSize.width * scale.width, pageSize.height * scale.height};
- pix = fz_new_pixmap_with_rect(ctx, fz_device_rgb, bbox);
+ pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox);
fz_clear_pixmap_with_value(ctx, pix, 255);
dev = fz_new_draw_device(ctx, pix);
@@ -253,7 +253,7 @@ static UIImage *renderTile(struct document *doc, int number, CGSize screenSize,
rect.y1 = tileRect.origin.y + tileRect.size.height;
bbox = fz_round_rect(rect);
- pix = fz_new_pixmap_with_rect(ctx, fz_device_rgb, bbox);
+ pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb, bbox);
fz_clear_pixmap_with_value(ctx, pix, 255);
dev = fz_new_draw_device(ctx, pix);
diff --git a/fitz/base_object.c b/pdf/base_object.c
index 964c5bb4..460b89f2 100644
--- a/fitz/base_object.c
+++ b/pdf/base_object.c
@@ -1,28 +1,29 @@
-#include "fitz.h"
-
-typedef enum fz_objkind_e
-{
- FZ_NULL,
- FZ_BOOL,
- FZ_INT,
- FZ_REAL,
- FZ_STRING,
- FZ_NAME,
- FZ_ARRAY,
- FZ_DICT,
- FZ_INDIRECT
-} fz_objkind;
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
+
+typedef enum pdf_objkind_e
+{
+ PDF_NULL,
+ PDF_BOOL,
+ PDF_INT,
+ PDF_REAL,
+ PDF_STRING,
+ PDF_NAME,
+ PDF_ARRAY,
+ PDF_DICT,
+ PDF_INDIRECT
+} pdf_objkind;
struct keyval
{
- fz_obj *k;
- fz_obj *v;
+ pdf_obj *k;
+ pdf_obj *v;
};
-struct fz_obj_s
+struct pdf_obj_s
{
int refs;
- fz_objkind kind;
+ pdf_objkind kind;
fz_context *ctx;
union
{
@@ -37,7 +38,7 @@ struct fz_obj_s
struct {
int len;
int cap;
- fz_obj **items;
+ pdf_obj **items;
} a;
struct {
char sorted;
@@ -54,259 +55,259 @@ struct fz_obj_s
} u;
};
-fz_obj *
-fz_new_null(fz_context *ctx)
+pdf_obj *
+pdf_new_null(fz_context *ctx)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(null)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(null)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_NULL;
+ obj->kind = PDF_NULL;
return obj;
}
-fz_obj *
-fz_new_bool(fz_context *ctx, int b)
+pdf_obj *
+pdf_new_bool(fz_context *ctx, int b)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(bool)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(bool)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_BOOL;
+ obj->kind = PDF_BOOL;
obj->u.b = b;
return obj;
}
-fz_obj *
-fz_new_int(fz_context *ctx, int i)
+pdf_obj *
+pdf_new_int(fz_context *ctx, int i)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(int)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(int)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_INT;
+ obj->kind = PDF_INT;
obj->u.i = i;
return obj;
}
-fz_obj *
-fz_new_real(fz_context *ctx, float f)
+pdf_obj *
+pdf_new_real(fz_context *ctx, float f)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(real)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(real)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_REAL;
+ obj->kind = PDF_REAL;
obj->u.f = f;
return obj;
}
-fz_obj *
-fz_new_string(fz_context *ctx, char *str, int len)
+pdf_obj *
+pdf_new_string(fz_context *ctx, char *str, int len)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, offsetof(fz_obj, u.s.buf) + len + 1), "fz_obj(string)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj, u.s.buf) + len + 1), "pdf_obj(string)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_STRING;
+ obj->kind = PDF_STRING;
obj->u.s.len = len;
memcpy(obj->u.s.buf, str, len);
obj->u.s.buf[len] = '\0';
return obj;
}
-fz_obj *
+pdf_obj *
fz_new_name(fz_context *ctx, char *str)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, offsetof(fz_obj, u.n) + strlen(str) + 1), "fz_obj(name)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, offsetof(pdf_obj, u.n) + strlen(str) + 1), "pdf_obj(name)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_NAME;
+ obj->kind = PDF_NAME;
strcpy(obj->u.n, str);
return obj;
}
-fz_obj *
-fz_new_indirect(fz_context *ctx, int num, int gen, void *xref)
+pdf_obj *
+pdf_new_indirect(fz_context *ctx, int num, int gen, void *xref)
{
- fz_obj *obj;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(indirect)");
+ pdf_obj *obj;
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(indirect)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_INDIRECT;
+ obj->kind = PDF_INDIRECT;
obj->u.r.num = num;
obj->u.r.gen = gen;
obj->u.r.xref = xref;
return obj;
}
-fz_obj *
-fz_keep_obj(fz_obj *obj)
+pdf_obj *
+pdf_keep_obj(pdf_obj *obj)
{
assert(obj);
obj->refs ++;
return obj;
}
-int fz_is_indirect(fz_obj *obj)
+int pdf_is_indirect(pdf_obj *obj)
{
- return obj ? obj->kind == FZ_INDIRECT : 0;
+ return obj ? obj->kind == PDF_INDIRECT : 0;
}
#define RESOLVE(obj) \
do { \
- if (obj && obj->kind == FZ_INDIRECT) \
+ if (obj && obj->kind == PDF_INDIRECT) \
{\
fz_assert_lock_not_held(obj->ctx, FZ_LOCK_FILE); \
- obj = fz_resolve_indirect(obj); \
+ obj = pdf_resolve_indirect(obj); \
} \
} while (0)
-int fz_is_null(fz_obj *obj)
+int pdf_is_null(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_NULL : 0;
+ return obj ? obj->kind == PDF_NULL : 0;
}
-int fz_is_bool(fz_obj *obj)
+int pdf_is_bool(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_BOOL : 0;
+ return obj ? obj->kind == PDF_BOOL : 0;
}
-int fz_is_int(fz_obj *obj)
+int pdf_is_int(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_INT : 0;
+ return obj ? obj->kind == PDF_INT : 0;
}
-int fz_is_real(fz_obj *obj)
+int pdf_is_real(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_REAL : 0;
+ return obj ? obj->kind == PDF_REAL : 0;
}
-int fz_is_string(fz_obj *obj)
+int pdf_is_string(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_STRING : 0;
+ return obj ? obj->kind == PDF_STRING : 0;
}
-int fz_is_name(fz_obj *obj)
+int pdf_is_name(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_NAME : 0;
+ return obj ? obj->kind == PDF_NAME : 0;
}
-int fz_is_array(fz_obj *obj)
+int pdf_is_array(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_ARRAY : 0;
+ return obj ? obj->kind == PDF_ARRAY : 0;
}
-int fz_is_dict(fz_obj *obj)
+int pdf_is_dict(pdf_obj *obj)
{
RESOLVE(obj);
- return obj ? obj->kind == FZ_DICT : 0;
+ return obj ? obj->kind == PDF_DICT : 0;
}
-int fz_to_bool(fz_obj *obj)
+int pdf_to_bool(pdf_obj *obj)
{
RESOLVE(obj);
if (!obj)
return 0;
- return obj->kind == FZ_BOOL ? obj->u.b : 0;
+ return obj->kind == PDF_BOOL ? obj->u.b : 0;
}
-int fz_to_int(fz_obj *obj)
+int pdf_to_int(pdf_obj *obj)
{
RESOLVE(obj);
if (!obj)
return 0;
- if (obj->kind == FZ_INT)
+ if (obj->kind == PDF_INT)
return obj->u.i;
- if (obj->kind == FZ_REAL)
+ if (obj->kind == PDF_REAL)
return (int)(obj->u.f + 0.5f); /* No roundf in MSVC */
return 0;
}
-float fz_to_real(fz_obj *obj)
+float pdf_to_real(pdf_obj *obj)
{
RESOLVE(obj);
if (!obj)
return 0;
- if (obj->kind == FZ_REAL)
+ if (obj->kind == PDF_REAL)
return obj->u.f;
- if (obj->kind == FZ_INT)
+ if (obj->kind == PDF_INT)
return obj->u.i;
return 0;
}
-char *fz_to_name(fz_obj *obj)
+char *pdf_to_name(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_NAME)
+ if (!obj || obj->kind != PDF_NAME)
return "";
return obj->u.n;
}
-char *fz_to_str_buf(fz_obj *obj)
+char *pdf_to_str_buf(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_STRING)
+ if (!obj || obj->kind != PDF_STRING)
return "";
return obj->u.s.buf;
}
-int fz_to_str_len(fz_obj *obj)
+int pdf_to_str_len(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_STRING)
+ if (!obj || obj->kind != PDF_STRING)
return 0;
return obj->u.s.len;
}
/* for use by pdf_crypt_obj_imp to decrypt AES string in place */
-void fz_set_str_len(fz_obj *obj, int newlen)
+void pdf_set_str_len(pdf_obj *obj, int newlen)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_STRING)
+ if (!obj || obj->kind != PDF_STRING)
return; /* This should never happen */
if (newlen > obj->u.s.len)
return; /* This should never happen */
obj->u.s.len = newlen;
}
-fz_obj *fz_to_dict(fz_obj *obj)
+pdf_obj *pdf_to_dict(pdf_obj *obj)
{
RESOLVE(obj);
- return (obj && obj->kind == FZ_DICT ? obj : NULL);
+ return (obj && obj->kind == PDF_DICT ? obj : NULL);
}
-int fz_to_num(fz_obj *obj)
+int pdf_to_num(pdf_obj *obj)
{
- if (!obj || obj->kind != FZ_INDIRECT)
+ if (!obj || obj->kind != PDF_INDIRECT)
return 0;
return obj->u.r.num;
}
-int fz_to_gen(fz_obj *obj)
+int pdf_to_gen(pdf_obj *obj)
{
- if (!obj || obj->kind != FZ_INDIRECT)
+ if (!obj || obj->kind != PDF_INDIRECT)
return 0;
return obj->u.r.gen;
}
-void *fz_get_indirect_document(fz_obj *obj)
+void *pdf_get_indirect_document(pdf_obj *obj)
{
- if (!obj || obj->kind != FZ_INDIRECT)
+ if (!obj || obj->kind != PDF_INDIRECT)
return NULL;
return obj->u.r.xref;
}
int
-fz_objcmp(fz_obj *a, fz_obj *b)
+pdf_objcmp(pdf_obj *a, pdf_obj *b)
{
int i;
@@ -321,23 +322,23 @@ fz_objcmp(fz_obj *a, fz_obj *b)
switch (a->kind)
{
- case FZ_NULL:
+ case PDF_NULL:
return 0;
- case FZ_BOOL:
+ case PDF_BOOL:
return a->u.b - b->u.b;
- case FZ_INT:
+ case PDF_INT:
return a->u.i - b->u.i;
- case FZ_REAL:
+ case PDF_REAL:
if (a->u.f < b->u.f)
return -1;
if (a->u.f > b->u.f)
return 1;
return 0;
- case FZ_STRING:
+ case PDF_STRING:
if (a->u.s.len < b->u.s.len)
{
if (memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len) <= 0)
@@ -352,30 +353,30 @@ fz_objcmp(fz_obj *a, fz_obj *b)
}
return memcmp(a->u.s.buf, b->u.s.buf, a->u.s.len);
- case FZ_NAME:
+ case PDF_NAME:
return strcmp(a->u.n, b->u.n);
- case FZ_INDIRECT:
+ case PDF_INDIRECT:
if (a->u.r.num == b->u.r.num)
return a->u.r.gen - b->u.r.gen;
return a->u.r.num - b->u.r.num;
- case FZ_ARRAY:
+ case PDF_ARRAY:
if (a->u.a.len != b->u.a.len)
return a->u.a.len - b->u.a.len;
for (i = 0; i < a->u.a.len; i++)
- if (fz_objcmp(a->u.a.items[i], b->u.a.items[i]))
+ if (pdf_objcmp(a->u.a.items[i], b->u.a.items[i]))
return 1;
return 0;
- case FZ_DICT:
+ case PDF_DICT:
if (a->u.d.len != b->u.d.len)
return a->u.d.len - b->u.d.len;
for (i = 0; i < a->u.d.len; i++)
{
- if (fz_objcmp(a->u.d.items[i].k, b->u.d.items[i].k))
+ if (pdf_objcmp(a->u.d.items[i].k, b->u.d.items[i].k))
return 1;
- if (fz_objcmp(a->u.d.items[i].v, b->u.d.items[i].v))
+ if (pdf_objcmp(a->u.d.items[i].v, b->u.d.items[i].v))
return 1;
}
return 0;
@@ -385,42 +386,42 @@ fz_objcmp(fz_obj *a, fz_obj *b)
}
static char *
-fz_objkindstr(fz_obj *obj)
+pdf_objkindstr(pdf_obj *obj)
{
if (!obj)
return "<NULL>";
switch (obj->kind)
{
- case FZ_NULL: return "null";
- case FZ_BOOL: return "boolean";
- case FZ_INT: return "integer";
- case FZ_REAL: return "real";
- case FZ_STRING: return "string";
- case FZ_NAME: return "name";
- case FZ_ARRAY: return "array";
- case FZ_DICT: return "dictionary";
- case FZ_INDIRECT: return "reference";
+ case PDF_NULL: return "null";
+ case PDF_BOOL: return "boolean";
+ case PDF_INT: return "integer";
+ case PDF_REAL: return "real";
+ case PDF_STRING: return "string";
+ case PDF_NAME: return "name";
+ case PDF_ARRAY: return "array";
+ case PDF_DICT: return "dictionary";
+ case PDF_INDIRECT: return "reference";
}
return "<unknown>";
}
-fz_obj *
-fz_new_array(fz_context *ctx, int initialcap)
+pdf_obj *
+pdf_new_array(fz_context *ctx, int initialcap)
{
- fz_obj *obj;
+ pdf_obj *obj;
int i;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(array)");
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(array)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_ARRAY;
+ obj->kind = PDF_ARRAY;
obj->u.a.len = 0;
obj->u.a.cap = initialcap > 1 ? initialcap : 6;
fz_try(ctx)
{
- obj->u.a.items = Memento_label(fz_malloc_array(ctx, obj->u.a.cap, sizeof(fz_obj*)), "fz_obj(array items)");
+ obj->u.a.items = Memento_label(fz_malloc_array(ctx, obj->u.a.cap, sizeof(pdf_obj*)), "pdf_obj(array items)");
}
fz_catch(ctx)
{
@@ -434,51 +435,51 @@ fz_new_array(fz_context *ctx, int initialcap)
}
static void
-fz_array_grow(fz_obj *obj)
+pdf_array_grow(pdf_obj *obj)
{
int i;
obj->u.a.cap = (obj->u.a.cap * 3) / 2;
- obj->u.a.items = fz_resize_array(obj->ctx, obj->u.a.items, obj->u.a.cap, sizeof(fz_obj*));
+ obj->u.a.items = fz_resize_array(obj->ctx, obj->u.a.items, obj->u.a.cap, sizeof(pdf_obj*));
for (i = obj->u.a.len ; i < obj->u.a.cap; i++)
obj->u.a.items[i] = NULL;
}
-fz_obj *
-fz_copy_array(fz_context *ctx, fz_obj *obj)
+pdf_obj *
+pdf_copy_array(fz_context *ctx, pdf_obj *obj)
{
- fz_obj *arr;
+ pdf_obj *arr;
int i;
int n;
RESOLVE(obj);
- if (!obj || obj->kind != FZ_ARRAY)
- fz_warn(ctx, "assert: not an array (%s)", fz_objkindstr(obj));
+ if (!obj || obj->kind != PDF_ARRAY)
+ fz_warn(ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
- arr = fz_new_array(ctx, fz_array_len(obj));
- n = fz_array_len(obj);
+ arr = pdf_new_array(ctx, pdf_array_len(obj));
+ n = pdf_array_len(obj);
for (i = 0; i < n; i++)
- fz_array_push(arr, fz_array_get(obj, i));
+ pdf_array_push(arr, pdf_array_get(obj, i));
return arr;
}
int
-fz_array_len(fz_obj *obj)
+pdf_array_len(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_ARRAY)
+ if (!obj || obj->kind != PDF_ARRAY)
return 0;
return obj->u.a.len;
}
-fz_obj *
-fz_array_get(fz_obj *obj, int i)
+pdf_obj *
+pdf_array_get(pdf_obj *obj, int i)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_ARRAY)
+ if (!obj || obj->kind != PDF_ARRAY)
return NULL;
if (i < 0 || i >= obj->u.a.len)
@@ -488,14 +489,14 @@ fz_array_get(fz_obj *obj, int i)
}
void
-fz_array_put(fz_obj *obj, int i, fz_obj *item)
+pdf_array_put(pdf_obj *obj, int i, pdf_obj *item)
{
RESOLVE(obj);
if (!obj)
return; /* Can't warn :( */
- if (obj->kind != FZ_ARRAY)
- fz_warn(obj->ctx, "assert: not an array (%s)", fz_objkindstr(obj));
+ if (obj->kind != PDF_ARRAY)
+ fz_warn(obj->ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else if (i < 0)
fz_warn(obj->ctx, "assert: index %d < 0", i);
else if (i >= obj->u.a.len)
@@ -503,55 +504,55 @@ fz_array_put(fz_obj *obj, int i, fz_obj *item)
else
{
if (obj->u.a.items[i])
- fz_drop_obj(obj->u.a.items[i]);
- obj->u.a.items[i] = fz_keep_obj(item);
+ pdf_drop_obj(obj->u.a.items[i]);
+ obj->u.a.items[i] = pdf_keep_obj(item);
}
}
void
-fz_array_push(fz_obj *obj, fz_obj *item)
+pdf_array_push(pdf_obj *obj, pdf_obj *item)
{
RESOLVE(obj);
if (!obj)
return; /* Can't warn :( */
- if (obj->kind != FZ_ARRAY)
- fz_warn(obj->ctx, "assert: not an array (%s)", fz_objkindstr(obj));
+ if (obj->kind != PDF_ARRAY)
+ fz_warn(obj->ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else
{
if (obj->u.a.len + 1 > obj->u.a.cap)
- fz_array_grow(obj);
- obj->u.a.items[obj->u.a.len] = fz_keep_obj(item);
+ pdf_array_grow(obj);
+ obj->u.a.items[obj->u.a.len] = pdf_keep_obj(item);
obj->u.a.len++;
}
}
void
-fz_array_insert(fz_obj *obj, fz_obj *item)
+pdf_array_insert(pdf_obj *obj, pdf_obj *item)
{
RESOLVE(obj);
if (!obj)
return; /* Can't warn :( */
- if (obj->kind != FZ_ARRAY)
- fz_warn(obj->ctx, "assert: not an array (%s)", fz_objkindstr(obj));
+ if (obj->kind != PDF_ARRAY)
+ fz_warn(obj->ctx, "assert: not an array (%s)", pdf_objkindstr(obj));
else
{
if (obj->u.a.len + 1 > obj->u.a.cap)
- fz_array_grow(obj);
- memmove(obj->u.a.items + 1, obj->u.a.items, obj->u.a.len * sizeof(fz_obj*));
- obj->u.a.items[0] = fz_keep_obj(item);
+ pdf_array_grow(obj);
+ memmove(obj->u.a.items + 1, obj->u.a.items, obj->u.a.len * sizeof(pdf_obj*));
+ obj->u.a.items[0] = pdf_keep_obj(item);
obj->u.a.len++;
}
}
int
-fz_array_contains(fz_obj *arr, fz_obj *obj)
+pdf_array_contains(pdf_obj *arr, pdf_obj *obj)
{
int i;
- for (i = 0; i < fz_array_len(arr); i++)
- if (!fz_objcmp(fz_array_get(arr, i), obj))
+ for (i = 0; i < pdf_array_len(arr); i++)
+ if (!pdf_objcmp(pdf_array_get(arr, i), obj))
return 1;
return 0;
@@ -563,19 +564,19 @@ static int keyvalcmp(const void *ap, const void *bp)
{
const struct keyval *a = ap;
const struct keyval *b = bp;
- return strcmp(fz_to_name(a->k), fz_to_name(b->k));
+ return strcmp(pdf_to_name(a->k), pdf_to_name(b->k));
}
-fz_obj *
-fz_new_dict(fz_context *ctx, int initialcap)
+pdf_obj *
+pdf_new_dict(fz_context *ctx, int initialcap)
{
- fz_obj *obj;
+ pdf_obj *obj;
int i;
- obj = Memento_label(fz_malloc(ctx, sizeof(fz_obj)), "fz_obj(dict)");
+ obj = Memento_label(fz_malloc(ctx, sizeof(pdf_obj)), "pdf_obj(dict)");
obj->ctx = ctx;
obj->refs = 1;
- obj->kind = FZ_DICT;
+ obj->kind = PDF_DICT;
obj->u.d.sorted = 0;
obj->u.d.marked = 0;
@@ -584,7 +585,7 @@ fz_new_dict(fz_context *ctx, int initialcap)
fz_try(ctx)
{
- obj->u.d.items = Memento_label(fz_malloc_array(ctx, obj->u.d.cap, sizeof(struct keyval)), "fz_obj(dict items)");
+ obj->u.d.items = Memento_label(fz_malloc_array(ctx, obj->u.d.cap, sizeof(struct keyval)), "pdf_obj(dict items)");
}
fz_catch(ctx)
{
@@ -601,7 +602,7 @@ fz_new_dict(fz_context *ctx, int initialcap)
}
static void
-fz_dict_grow(fz_obj *obj)
+pdf_dict_grow(pdf_obj *obj)
{
int i;
@@ -615,38 +616,38 @@ fz_dict_grow(fz_obj *obj)
}
}
-fz_obj *
-fz_copy_dict(fz_context *ctx, fz_obj *obj)
+pdf_obj *
+pdf_copy_dict(fz_context *ctx, pdf_obj *obj)
{
- fz_obj *dict;
+ pdf_obj *dict;
int i, n;
RESOLVE(obj);
- if (obj && obj->kind != FZ_DICT)
- fz_warn(ctx, "assert: not a dict (%s)", fz_objkindstr(obj));
+ if (obj && obj->kind != PDF_DICT)
+ fz_warn(ctx, "assert: not a dict (%s)", pdf_objkindstr(obj));
- n = fz_dict_len(obj);
- dict = fz_new_dict(ctx, n);
+ n = pdf_dict_len(obj);
+ dict = pdf_new_dict(ctx, n);
for (i = 0; i < n; i++)
- fz_dict_put(dict, fz_dict_get_key(obj, i), fz_dict_get_val(obj, i));
+ fz_dict_put(dict, pdf_dict_get_key(obj, i), pdf_dict_get_val(obj, i));
return dict;
}
int
-fz_dict_len(fz_obj *obj)
+pdf_dict_len(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return 0;
return obj->u.d.len;
}
-fz_obj *
-fz_dict_get_key(fz_obj *obj, int i)
+pdf_obj *
+pdf_dict_get_key(pdf_obj *obj, int i)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return NULL;
if (i < 0 || i >= obj->u.d.len)
@@ -655,11 +656,11 @@ fz_dict_get_key(fz_obj *obj, int i)
return obj->u.d.items[i].k;
}
-fz_obj *
-fz_dict_get_val(fz_obj *obj, int i)
+pdf_obj *
+pdf_dict_get_val(pdf_obj *obj, int i)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return NULL;
if (i < 0 || i >= obj->u.d.len)
@@ -669,14 +670,14 @@ fz_dict_get_val(fz_obj *obj, int i)
}
static int
-fz_dict_finds(fz_obj *obj, char *key, int *location)
+pdf_dict_finds(pdf_obj *obj, char *key, int *location)
{
if (obj->u.d.sorted && obj->u.d.len > 0)
{
int l = 0;
int r = obj->u.d.len - 1;
- if (strcmp(fz_to_name(obj->u.d.items[r].k), key) < 0)
+ if (strcmp(pdf_to_name(obj->u.d.items[r].k), key) < 0)
{
if (location)
*location = r + 1;
@@ -686,7 +687,7 @@ fz_dict_finds(fz_obj *obj, char *key, int *location)
while (l <= r)
{
int m = (l + r) >> 1;
- int c = -strcmp(fz_to_name(obj->u.d.items[m].k), key);
+ int c = -strcmp(pdf_to_name(obj->u.d.items[m].k), key);
if (c < 0)
r = m - 1;
else if (c > 0)
@@ -703,7 +704,7 @@ fz_dict_finds(fz_obj *obj, char *key, int *location)
{
int i;
for (i = 0; i < obj->u.d.len; i++)
- if (strcmp(fz_to_name(obj->u.d.items[i].k), key) == 0)
+ if (strcmp(pdf_to_name(obj->u.d.items[i].k), key) == 0)
return i;
if (location)
@@ -713,62 +714,62 @@ fz_dict_finds(fz_obj *obj, char *key, int *location)
return -1;
}
-fz_obj *
-fz_dict_gets(fz_obj *obj, char *key)
+pdf_obj *
+pdf_dict_gets(pdf_obj *obj, char *key)
{
int i;
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return NULL;
- i = fz_dict_finds(obj, key, NULL);
+ i = pdf_dict_finds(obj, key, NULL);
if (i >= 0)
return obj->u.d.items[i].v;
return NULL;
}
-fz_obj *
-fz_dict_get(fz_obj *obj, fz_obj *key)
+pdf_obj *
+pdf_dict_get(pdf_obj *obj, pdf_obj *key)
{
- if (!key || key->kind != FZ_NAME)
+ if (!key || key->kind != PDF_NAME)
return NULL;
- return fz_dict_gets(obj, fz_to_name(key));
+ return pdf_dict_gets(obj, pdf_to_name(key));
}
-fz_obj *
-fz_dict_getsa(fz_obj *obj, char *key, char *abbrev)
+pdf_obj *
+pdf_dict_getsa(pdf_obj *obj, char *key, char *abbrev)
{
- fz_obj *v;
- v = fz_dict_gets(obj, key);
+ pdf_obj *v;
+ v = pdf_dict_gets(obj, key);
if (v)
return v;
- return fz_dict_gets(obj, abbrev);
+ return pdf_dict_gets(obj, abbrev);
}
void
-fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val)
+fz_dict_put(pdf_obj *obj, pdf_obj *key, pdf_obj *val)
{
int location;
char *s;
int i;
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
{
- fz_warn(obj->ctx, "assert: not a dict (%s)", fz_objkindstr(obj));
+ fz_warn(obj->ctx, "assert: not a dict (%s)", pdf_objkindstr(obj));
return;
}
RESOLVE(key);
- if (!key || key->kind != FZ_NAME)
+ if (!key || key->kind != PDF_NAME)
{
- fz_warn(obj->ctx, "assert: key is not a name (%s)", fz_objkindstr(obj));
+ fz_warn(obj->ctx, "assert: key is not a name (%s)", pdf_objkindstr(obj));
return;
}
else
- s = fz_to_name(key);
+ s = pdf_to_name(key);
if (!val)
{
@@ -777,18 +778,18 @@ fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val)
}
if (obj->u.d.len > 100 && !obj->u.d.sorted)
- fz_sort_dict(obj);
+ pdf_sort_dict(obj);
- i = fz_dict_finds(obj, s, &location);
+ i = pdf_dict_finds(obj, s, &location);
if (i >= 0 && i < obj->u.d.len)
{
- fz_drop_obj(obj->u.d.items[i].v);
- obj->u.d.items[i].v = fz_keep_obj(val);
+ pdf_drop_obj(obj->u.d.items[i].v);
+ obj->u.d.items[i].v = pdf_keep_obj(val);
}
else
{
if (obj->u.d.len + 1 > obj->u.d.cap)
- fz_dict_grow(obj);
+ pdf_dict_grow(obj);
i = location;
if (obj->u.d.sorted && obj->u.d.len > 0)
@@ -796,34 +797,34 @@ fz_dict_put(fz_obj *obj, fz_obj *key, fz_obj *val)
&obj->u.d.items[i],
(obj->u.d.len - i) * sizeof(struct keyval));
- obj->u.d.items[i].k = fz_keep_obj(key);
- obj->u.d.items[i].v = fz_keep_obj(val);
+ obj->u.d.items[i].k = pdf_keep_obj(key);
+ obj->u.d.items[i].v = pdf_keep_obj(val);
obj->u.d.len ++;
}
}
void
-fz_dict_puts(fz_obj *obj, char *key, fz_obj *val)
+pdf_dict_puts(pdf_obj *obj, char *key, pdf_obj *val)
{
- fz_obj *keyobj = fz_new_name(obj->ctx, key);
+ pdf_obj *keyobj = fz_new_name(obj->ctx, key);
fz_dict_put(obj, keyobj, val);
- fz_drop_obj(keyobj);
+ pdf_drop_obj(keyobj);
}
void
-fz_dict_dels(fz_obj *obj, char *key)
+pdf_dict_dels(pdf_obj *obj, char *key)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
- fz_warn(obj->ctx, "assert: not a dict (%s)", fz_objkindstr(obj));
+ if (!obj || obj->kind != PDF_DICT)
+ fz_warn(obj->ctx, "assert: not a dict (%s)", pdf_objkindstr(obj));
else
{
- int i = fz_dict_finds(obj, key, NULL);
+ int i = pdf_dict_finds(obj, key, NULL);
if (i >= 0)
{
- fz_drop_obj(obj->u.d.items[i].k);
- fz_drop_obj(obj->u.d.items[i].v);
+ pdf_drop_obj(obj->u.d.items[i].k);
+ pdf_drop_obj(obj->u.d.items[i].v);
obj->u.d.sorted = 0;
obj->u.d.items[i] = obj->u.d.items[obj->u.d.len-1];
obj->u.d.len --;
@@ -832,20 +833,20 @@ fz_dict_dels(fz_obj *obj, char *key)
}
void
-fz_dict_del(fz_obj *obj, fz_obj *key)
+pdf_dict_del(pdf_obj *obj, pdf_obj *key)
{
RESOLVE(key);
- if (!key || key->kind != FZ_NAME)
- fz_warn(obj->ctx, "assert: key is not a name (%s)", fz_objkindstr(obj));
+ if (!key || key->kind != PDF_NAME)
+ fz_warn(obj->ctx, "assert: key is not a name (%s)", pdf_objkindstr(obj));
else
- fz_dict_dels(obj, key->u.n);
+ pdf_dict_dels(obj, key->u.n);
}
void
-fz_sort_dict(fz_obj *obj)
+pdf_sort_dict(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return;
if (!obj->u.d.sorted)
{
@@ -855,20 +856,20 @@ fz_sort_dict(fz_obj *obj)
}
int
-fz_dict_marked(fz_obj *obj)
+pdf_dict_marked(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return 0;
return obj->u.d.marked;
}
int
-fz_dict_mark(fz_obj *obj)
+pdf_dict_mark(pdf_obj *obj)
{
int marked;
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return 0;
marked = obj->u.d.marked;
obj->u.d.marked = 1;
@@ -876,37 +877,37 @@ fz_dict_mark(fz_obj *obj)
}
void
-fz_dict_unmark(fz_obj *obj)
+pdf_dict_unmark(pdf_obj *obj)
{
RESOLVE(obj);
- if (!obj || obj->kind != FZ_DICT)
+ if (!obj || obj->kind != PDF_DICT)
return;
obj->u.d.marked = 0;
}
static void
-fz_free_array(fz_obj *obj)
+pdf_free_array(pdf_obj *obj)
{
int i;
for (i = 0; i < obj->u.a.len; i++)
if (obj->u.a.items[i])
- fz_drop_obj(obj->u.a.items[i]);
+ pdf_drop_obj(obj->u.a.items[i]);
fz_free(obj->ctx, obj->u.a.items);
fz_free(obj->ctx, obj);
}
static void
-fz_free_dict(fz_obj *obj)
+pdf_free_dict(pdf_obj *obj)
{
int i;
for (i = 0; i < obj->u.d.len; i++) {
if (obj->u.d.items[i].k)
- fz_drop_obj(obj->u.d.items[i].k);
+ pdf_drop_obj(obj->u.d.items[i].k);
if (obj->u.d.items[i].v)
- fz_drop_obj(obj->u.d.items[i].v);
+ pdf_drop_obj(obj->u.d.items[i].v);
}
fz_free(obj->ctx, obj->u.d.items);
@@ -914,16 +915,16 @@ fz_free_dict(fz_obj *obj)
}
void
-fz_drop_obj(fz_obj *obj)
+pdf_drop_obj(pdf_obj *obj)
{
if (!obj)
return;
if (--obj->refs)
return;
- if (obj->kind == FZ_ARRAY)
- fz_free_array(obj);
- else if (obj->kind == FZ_DICT)
- fz_free_dict(obj);
+ if (obj->kind == PDF_ARRAY)
+ pdf_free_array(obj);
+ else if (obj->kind == PDF_DICT)
+ pdf_free_dict(obj);
else
fz_free(obj->ctx, obj);
}
@@ -942,7 +943,7 @@ struct fmt
int last;
};
-static void fmt_obj(struct fmt *fmt, fz_obj *obj);
+static void fmt_obj(struct fmt *fmt, pdf_obj *obj);
static inline int iswhite(int ch)
{
@@ -1006,10 +1007,10 @@ static inline void fmt_sep(struct fmt *fmt)
fmt->sep = 1;
}
-static void fmt_str(struct fmt *fmt, fz_obj *obj)
+static void fmt_str(struct fmt *fmt, pdf_obj *obj)
{
- char *s = fz_to_str_buf(obj);
- int n = fz_to_str_len(obj);
+ char *s = pdf_to_str_buf(obj);
+ int n = pdf_to_str_len(obj);
int i, c;
fmt_putc(fmt, '(');
@@ -1042,10 +1043,10 @@ static void fmt_str(struct fmt *fmt, fz_obj *obj)
fmt_putc(fmt, ')');
}
-static void fmt_hex(struct fmt *fmt, fz_obj *obj)
+static void fmt_hex(struct fmt *fmt, pdf_obj *obj)
{
- char *s = fz_to_str_buf(obj);
- int n = fz_to_str_len(obj);
+ char *s = pdf_to_str_buf(obj);
+ int n = pdf_to_str_len(obj);
int i, b, c;
fmt_putc(fmt, '<');
@@ -1059,9 +1060,9 @@ static void fmt_hex(struct fmt *fmt, fz_obj *obj)
fmt_putc(fmt, '>');
}
-static void fmt_name(struct fmt *fmt, fz_obj *obj)
+static void fmt_name(struct fmt *fmt, pdf_obj *obj)
{
- unsigned char *s = (unsigned char *) fz_to_name(obj);
+ unsigned char *s = (unsigned char *) pdf_to_name(obj);
int i, c;
fmt_putc(fmt, '/');
@@ -1084,15 +1085,15 @@ static void fmt_name(struct fmt *fmt, fz_obj *obj)
}
}
-static void fmt_array(struct fmt *fmt, fz_obj *obj)
+static void fmt_array(struct fmt *fmt, pdf_obj *obj)
{
int i, n;
- n = fz_array_len(obj);
+ n = pdf_array_len(obj);
if (fmt->tight) {
fmt_putc(fmt, '[');
for (i = 0; i < n; i++) {
- fmt_obj(fmt, fz_array_get(obj, i));
+ fmt_obj(fmt, pdf_array_get(obj, i));
fmt_sep(fmt);
}
fmt_putc(fmt, ']');
@@ -1104,7 +1105,7 @@ static void fmt_array(struct fmt *fmt, fz_obj *obj)
fmt_putc(fmt, '\n');
fmt_indent(fmt);
}
- fmt_obj(fmt, fz_array_get(obj, i));
+ fmt_obj(fmt, pdf_array_get(obj, i));
fmt_putc(fmt, ' ');
}
fmt_putc(fmt, ']');
@@ -1112,18 +1113,18 @@ static void fmt_array(struct fmt *fmt, fz_obj *obj)
}
}
-static void fmt_dict(struct fmt *fmt, fz_obj *obj)
+static void fmt_dict(struct fmt *fmt, pdf_obj *obj)
{
int i, n;
- fz_obj *key, *val;
+ pdf_obj *key, *val;
- n = fz_dict_len(obj);
+ n = pdf_dict_len(obj);
if (fmt->tight) {
fmt_puts(fmt, "<<");
for (i = 0; i < n; i++) {
- fmt_obj(fmt, fz_dict_get_key(obj, i));
+ fmt_obj(fmt, pdf_dict_get_key(obj, i));
fmt_sep(fmt);
- fmt_obj(fmt, fz_dict_get_val(obj, i));
+ fmt_obj(fmt, pdf_dict_get_val(obj, i));
fmt_sep(fmt);
}
fmt_puts(fmt, ">>");
@@ -1132,16 +1133,16 @@ static void fmt_dict(struct fmt *fmt, fz_obj *obj)
fmt_puts(fmt, "<<\n");
fmt->indent ++;
for (i = 0; i < n; i++) {
- key = fz_dict_get_key(obj, i);
- val = fz_dict_get_val(obj, i);
+ key = pdf_dict_get_key(obj, i);
+ val = pdf_dict_get_val(obj, i);
fmt_indent(fmt);
fmt_obj(fmt, key);
fmt_putc(fmt, ' ');
- if (!fz_is_indirect(val) && fz_is_array(val))
+ if (!pdf_is_indirect(val) && pdf_is_array(val))
fmt->indent ++;
fmt_obj(fmt, val);
fmt_putc(fmt, '\n');
- if (!fz_is_indirect(val) && fz_is_array(val))
+ if (!pdf_is_indirect(val) && pdf_is_array(val))
fmt->indent --;
}
fmt->indent --;
@@ -1150,37 +1151,37 @@ static void fmt_dict(struct fmt *fmt, fz_obj *obj)
}
}
-static void fmt_obj(struct fmt *fmt, fz_obj *obj)
+static void fmt_obj(struct fmt *fmt, pdf_obj *obj)
{
char buf[256];
if (!obj)
fmt_puts(fmt, "<NULL>");
- else if (fz_is_indirect(obj))
+ else if (pdf_is_indirect(obj))
{
- sprintf(buf, "%d %d R", fz_to_num(obj), fz_to_gen(obj));
+ sprintf(buf, "%d %d R", pdf_to_num(obj), pdf_to_gen(obj));
fmt_puts(fmt, buf);
}
- else if (fz_is_null(obj))
+ else if (pdf_is_null(obj))
fmt_puts(fmt, "null");
- else if (fz_is_bool(obj))
- fmt_puts(fmt, fz_to_bool(obj) ? "true" : "false");
- else if (fz_is_int(obj))
+ else if (pdf_is_bool(obj))
+ fmt_puts(fmt, pdf_to_bool(obj) ? "true" : "false");
+ else if (pdf_is_int(obj))
{
- sprintf(buf, "%d", fz_to_int(obj));
+ sprintf(buf, "%d", pdf_to_int(obj));
fmt_puts(fmt, buf);
}
- else if (fz_is_real(obj))
+ else if (pdf_is_real(obj))
{
- sprintf(buf, "%g", fz_to_real(obj));
+ sprintf(buf, "%g", pdf_to_real(obj));
if (strchr(buf, 'e')) /* bad news! */
- sprintf(buf, fabsf(fz_to_real(obj)) > 1 ? "%1.1f" : "%1.8f", fz_to_real(obj));
+ sprintf(buf, fabsf(pdf_to_real(obj)) > 1 ? "%1.1f" : "%1.8f", pdf_to_real(obj));
fmt_puts(fmt, buf);
}
- else if (fz_is_string(obj))
+ else if (pdf_is_string(obj))
{
- char *str = fz_to_str_buf(obj);
- int len = fz_to_str_len(obj);
+ char *str = pdf_to_str_buf(obj);
+ int len = pdf_to_str_len(obj);
int added = 0;
int i, c;
for (i = 0; i < len; i++) {
@@ -1195,18 +1196,18 @@ static void fmt_obj(struct fmt *fmt, fz_obj *obj)
else
fmt_hex(fmt, obj);
}
- else if (fz_is_name(obj))
+ else if (pdf_is_name(obj))
fmt_name(fmt, obj);
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
fmt_array(fmt, obj);
- else if (fz_is_dict(obj))
+ else if (pdf_is_dict(obj))
fmt_dict(fmt, obj);
else
fmt_puts(fmt, "<unknown object>");
}
static int
-fz_sprint_obj(char *s, int n, fz_obj *obj, int tight)
+pdf_sprint_obj(char *s, int n, pdf_obj *obj, int tight)
{
struct fmt fmt;
@@ -1228,23 +1229,23 @@ fz_sprint_obj(char *s, int n, fz_obj *obj, int tight)
}
int
-fz_fprint_obj(FILE *fp, fz_obj *obj, int tight)
+pdf_fprint_obj(FILE *fp, pdf_obj *obj, int tight)
{
char buf[1024];
char *ptr;
int n;
- n = fz_sprint_obj(NULL, 0, obj, tight);
+ n = pdf_sprint_obj(NULL, 0, obj, tight);
if ((n + 1) < sizeof buf)
{
- fz_sprint_obj(buf, sizeof buf, obj, tight);
+ pdf_sprint_obj(buf, sizeof buf, obj, tight);
fputs(buf, fp);
fputc('\n', fp);
}
else
{
ptr = fz_malloc(obj->ctx, n + 1);
- fz_sprint_obj(ptr, n + 1, obj, tight);
+ pdf_sprint_obj(ptr, n + 1, obj, tight);
fputs(ptr, fp);
fputc('\n', fp);
fz_free(obj->ctx, ptr);
@@ -1253,13 +1254,13 @@ fz_fprint_obj(FILE *fp, fz_obj *obj, int tight)
}
void
-fz_debug_obj(fz_obj *obj)
+pdf_print_obj(pdf_obj *obj)
{
- fz_fprint_obj(stdout, obj, 0);
+ pdf_fprint_obj(stdout, obj, 0);
}
void
-fz_debug_ref(fz_obj *ref)
+pdf_print_ref(pdf_obj *ref)
{
- fz_debug_obj(fz_resolve_indirect(ref));
+ pdf_print_obj(pdf_resolve_indirect(ref));
}
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h
new file mode 100644
index 00000000..3e4a4729
--- /dev/null
+++ b/pdf/mupdf-internal.h
@@ -0,0 +1,535 @@
+#ifndef MUPDF_INTERNAL_H
+#define MUPDF_INTERNAL_H
+
+#include "mupdf.h"
+#include "fitz-internal.h"
+
+void pdf_set_str_len(pdf_obj *obj, int newlen);
+void *pdf_get_indirect_document(pdf_obj *obj);
+
+/*
+ * PDF Images
+ */
+
+typedef struct pdf_image_params_s pdf_image_params;
+
+struct pdf_image_params_s
+{
+ int type;
+ fz_colorspace *colorspace;
+ union
+ {
+ struct
+ {
+ int columns;
+ int rows;
+ int k;
+ int eol;
+ int eba;
+ int eob;
+ int bi1;
+ }
+ fax;
+ struct
+ {
+ int ct;
+ }
+ jpeg;
+ struct
+ {
+ int columns;
+ int colors;
+ int predictor;
+ int bpc;
+ }
+ flate;
+ struct
+ {
+ int columns;
+ int colors;
+ int predictor;
+ int bpc;
+ int ec;
+ }
+ lzw;
+ }
+ u;
+};
+
+
+typedef struct pdf_image_s pdf_image;
+
+struct pdf_image_s
+{
+ fz_image base;
+ fz_pixmap *tile;
+ int n, bpc;
+ pdf_image_params params;
+ fz_buffer *buffer;
+ int colorkey[FZ_MAX_COLORS * 2];
+ float decode[FZ_MAX_COLORS * 2];
+ int imagemask;
+ int interpolate;
+ int usecolorkey;
+};
+
+enum
+{
+ PDF_IMAGE_RAW,
+ PDF_IMAGE_FAX,
+ PDF_IMAGE_JPEG,
+ PDF_IMAGE_RLD,
+ PDF_IMAGE_FLATE,
+ PDF_IMAGE_LZW,
+ PDF_IMAGE_JPX
+};
+
+/*
+ * tokenizer and low-level object parser
+ */
+
+enum
+{
+ PDF_TOK_ERROR, PDF_TOK_EOF,
+ PDF_TOK_OPEN_ARRAY, PDF_TOK_CLOSE_ARRAY,
+ PDF_TOK_OPEN_DICT, PDF_TOK_CLOSE_DICT,
+ PDF_TOK_OPEN_BRACE, PDF_TOK_CLOSE_BRACE,
+ PDF_TOK_NAME, PDF_TOK_INT, PDF_TOK_REAL, PDF_TOK_STRING, PDF_TOK_KEYWORD,
+ PDF_TOK_R, PDF_TOK_TRUE, PDF_TOK_FALSE, PDF_TOK_NULL,
+ PDF_TOK_OBJ, PDF_TOK_ENDOBJ,
+ PDF_TOK_STREAM, PDF_TOK_ENDSTREAM,
+ PDF_TOK_XREF, PDF_TOK_TRAILER, PDF_TOK_STARTXREF,
+ PDF_NUM_TOKENS
+};
+
+enum
+{
+ PDF_LEXBUF_SMALL = 256,
+ PDF_LEXBUF_LARGE = 65536
+};
+
+typedef struct pdf_lexbuf_s pdf_lexbuf;
+typedef struct pdf_lexbuf_large_s pdf_lexbuf_large;
+
+struct pdf_lexbuf_s
+{
+ int size;
+ int len;
+ int i;
+ float f;
+ char scratch[PDF_LEXBUF_SMALL];
+};
+
+struct pdf_lexbuf_large_s
+{
+ pdf_lexbuf base;
+ char scratch[PDF_LEXBUF_LARGE - PDF_LEXBUF_SMALL];
+};
+
+int pdf_lex(fz_stream *f, pdf_lexbuf *lexbuf);
+
+pdf_obj *pdf_parse_array(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf);
+pdf_obj *pdf_parse_dict(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf);
+pdf_obj *pdf_parse_stm_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf);
+pdf_obj *pdf_parse_ind_obj(pdf_document *doc, fz_stream *f, pdf_lexbuf *buf, int *num, int *gen, int *stm_ofs);
+
+/*
+ * xref and object / stream api
+ */
+
+typedef struct pdf_xref_entry_s pdf_xref_entry;
+
+struct pdf_xref_entry_s
+{
+ int ofs; /* file offset / objstm object number */
+ int gen; /* generation / objstm index */
+ int stm_ofs; /* on-disk stream */
+ pdf_obj *obj; /* stored/cached object */
+ int type; /* 0=unset (f)ree i(n)use (o)bjstm */
+};
+
+typedef struct pdf_crypt_s pdf_crypt;
+typedef struct pdf_ocg_descriptor_s pdf_ocg_descriptor;
+typedef struct pdf_ocg_entry_s pdf_ocg_entry;
+
+struct pdf_ocg_entry_s
+{
+ int num;
+ int gen;
+ int state;
+};
+
+struct pdf_ocg_descriptor_s
+{
+ int len;
+ pdf_ocg_entry *ocgs;
+ pdf_obj *intent;
+};
+
+struct pdf_document_s
+{
+ fz_document super;
+
+ fz_context *ctx;
+ fz_stream *file;
+
+ int version;
+ int startxref;
+ int file_size;
+ pdf_crypt *crypt;
+ pdf_obj *trailer;
+ pdf_ocg_descriptor *ocg;
+
+ int len;
+ pdf_xref_entry *table;
+
+ int page_len;
+ int page_cap;
+ pdf_obj **page_objs;
+ pdf_obj **page_refs;
+
+ pdf_lexbuf_large lexbuf;
+};
+
+void pdf_cache_object(pdf_document *doc, int num, int gen);
+
+fz_stream *pdf_open_inline_stream(pdf_document *doc, pdf_obj *stmobj, int length, fz_stream *chain, pdf_image_params *params);
+fz_buffer *pdf_load_image_stream(pdf_document *doc, int num, int gen, pdf_image_params *params);
+fz_stream *pdf_open_image_stream(pdf_document *doc, int num, int gen, pdf_image_params *params);
+fz_stream *pdf_open_stream_with_offset(pdf_document *doc, int num, int gen, pdf_obj *dict, int stm_ofs);
+fz_stream *pdf_open_image_decomp_stream(fz_context *ctx, fz_buffer *, pdf_image_params *params, int *factor);
+
+void pdf_repair_xref(pdf_document *doc, pdf_lexbuf *buf);
+void pdf_repair_obj_stms(pdf_document *doc);
+void pdf_print_xref(pdf_document *);
+void pdf_resize_xref(pdf_document *doc, int newcap);
+
+/*
+ * Encryption
+ */
+
+pdf_crypt *pdf_new_crypt(fz_context *ctx, pdf_obj *enc, pdf_obj *id);
+void pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt);
+
+void pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, int num, int gen);
+fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen);
+fz_stream *pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen);
+
+int pdf_crypt_revision(pdf_document *doc);
+char *pdf_crypt_method(pdf_document *doc);
+int pdf_crypt_length(pdf_document *doc);
+unsigned char *pdf_crypt_key(pdf_document *doc);
+
+void pdf_print_crypt(pdf_crypt *crypt);
+
+/*
+ * Functions, Colorspaces, Shadings and Images
+ */
+
+typedef struct pdf_function_s pdf_function;
+
+pdf_function *pdf_load_function(pdf_document *doc, pdf_obj *ref);
+void pdf_eval_function(fz_context *ctx, pdf_function *func, float *in, int inlen, float *out, int outlen);
+pdf_function *pdf_keep_function(fz_context *ctx, pdf_function *func);
+void pdf_drop_function(fz_context *ctx, pdf_function *func);
+unsigned int pdf_function_size(pdf_function *func);
+
+fz_colorspace *pdf_load_colorspace(pdf_document *doc, pdf_obj *obj);
+fz_pixmap *pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src);
+
+fz_shade *pdf_load_shading(pdf_document *doc, pdf_obj *obj);
+
+fz_image *pdf_load_inline_image(pdf_document *doc, pdf_obj *rdb, pdf_obj *dict, fz_stream *file);
+int pdf_is_jpx_image(fz_context *ctx, pdf_obj *dict);
+
+/*
+ * Pattern
+ */
+
+typedef struct pdf_pattern_s pdf_pattern;
+
+struct pdf_pattern_s
+{
+ fz_storable storable;
+ int ismask;
+ float xstep;
+ float ystep;
+ fz_matrix matrix;
+ fz_rect bbox;
+ pdf_obj *resources;
+ fz_buffer *contents;
+};
+
+pdf_pattern *pdf_load_pattern(pdf_document *doc, pdf_obj *obj);
+pdf_pattern *pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat);
+void pdf_drop_pattern(fz_context *ctx, pdf_pattern *pat);
+
+/*
+ * XObject
+ */
+
+typedef struct pdf_xobject_s pdf_xobject;
+
+struct pdf_xobject_s
+{
+ fz_storable storable;
+ fz_matrix matrix;
+ fz_rect bbox;
+ int isolated;
+ int knockout;
+ int transparency;
+ fz_colorspace *colorspace;
+ pdf_obj *resources;
+ fz_buffer *contents;
+ pdf_obj *me;
+};
+
+pdf_xobject *pdf_load_xobject(pdf_document *doc, pdf_obj *obj);
+pdf_xobject *pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj);
+void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj);
+
+/*
+ * CMap
+ */
+
+typedef struct pdf_cmap_s pdf_cmap;
+typedef struct pdf_range_s pdf_range;
+
+enum { PDF_CMAP_SINGLE, PDF_CMAP_RANGE, PDF_CMAP_TABLE, PDF_CMAP_MULTI };
+
+struct pdf_range_s
+{
+ unsigned short low;
+ /* Next, we pack 2 fields into the same unsigned short. Top 14 bits
+ * are the extent, bottom 2 bits are flags: single, range, table,
+ * multi */
+ unsigned short extent_flags;
+ unsigned short offset; /* range-delta or table-index */
+};
+
+struct pdf_cmap_s
+{
+ fz_storable storable;
+ char cmap_name[32];
+
+ char usecmap_name[32];
+ pdf_cmap *usecmap;
+
+ int wmode;
+
+ int codespace_len;
+ struct
+ {
+ unsigned short n;
+ unsigned short low;
+ unsigned short high;
+ } codespace[40];
+
+ int rlen, rcap;
+ pdf_range *ranges;
+
+ int tlen, tcap;
+ unsigned short *table;
+};
+
+pdf_cmap *pdf_new_cmap(fz_context *ctx);
+pdf_cmap *pdf_keep_cmap(fz_context *ctx, pdf_cmap *cmap);
+void pdf_drop_cmap(fz_context *ctx, pdf_cmap *cmap);
+void pdf_free_cmap_imp(fz_context *ctx, fz_storable *cmap);
+unsigned int pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap);
+
+void pdf_print_cmap(fz_context *ctx, pdf_cmap *cmap);
+int pdf_cmap_wmode(fz_context *ctx, pdf_cmap *cmap);
+void pdf_set_cmap_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode);
+void pdf_set_usecmap(fz_context *ctx, pdf_cmap *cmap, pdf_cmap *usecmap);
+
+void pdf_add_codespace(fz_context *ctx, pdf_cmap *cmap, int low, int high, int n);
+void pdf_map_range_to_table(fz_context *ctx, pdf_cmap *cmap, int low, int *map, int len);
+void pdf_map_range_to_range(fz_context *ctx, pdf_cmap *cmap, int srclo, int srchi, int dstlo);
+void pdf_map_one_to_many(fz_context *ctx, pdf_cmap *cmap, int one, int *many, int len);
+void pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap);
+
+int pdf_lookup_cmap(pdf_cmap *cmap, int cpt);
+int pdf_lookup_cmap_full(pdf_cmap *cmap, int cpt, int *out);
+int pdf_decode_cmap(pdf_cmap *cmap, unsigned char *s, int *cpt);
+
+pdf_cmap *pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes);
+pdf_cmap *pdf_load_cmap(fz_context *ctx, fz_stream *file);
+pdf_cmap *pdf_load_system_cmap(fz_context *ctx, char *name);
+pdf_cmap *pdf_load_builtin_cmap(fz_context *ctx, char *name);
+pdf_cmap *pdf_load_embedded_cmap(pdf_document *doc, pdf_obj *ref);
+
+/*
+ * Font
+ */
+
+enum
+{
+ PDF_FD_FIXED_PITCH = 1 << 0,
+ PDF_FD_SERIF = 1 << 1,
+ PDF_FD_SYMBOLIC = 1 << 2,
+ PDF_FD_SCRIPT = 1 << 3,
+ PDF_FD_NONSYMBOLIC = 1 << 5,
+ PDF_FD_ITALIC = 1 << 6,
+ PDF_FD_ALL_CAP = 1 << 16,
+ PDF_FD_SMALL_CAP = 1 << 17,
+ PDF_FD_FORCE_BOLD = 1 << 18
+};
+
+enum { PDF_ROS_CNS, PDF_ROS_GB, PDF_ROS_JAPAN, PDF_ROS_KOREA };
+
+void pdf_load_encoding(char **estrings, char *encoding);
+int pdf_lookup_agl(char *name);
+const char **pdf_lookup_agl_duplicates(int ucs);
+
+extern const unsigned short pdf_doc_encoding[256];
+extern const char * const pdf_mac_roman[256];
+extern const char * const pdf_mac_expert[256];
+extern const char * const pdf_win_ansi[256];
+extern const char * const pdf_standard[256];
+
+typedef struct pdf_font_desc_s pdf_font_desc;
+typedef struct pdf_hmtx_s pdf_hmtx;
+typedef struct pdf_vmtx_s pdf_vmtx;
+
+struct pdf_hmtx_s
+{
+ unsigned short lo;
+ unsigned short hi;
+ int w; /* type3 fonts can be big! */
+};
+
+struct pdf_vmtx_s
+{
+ unsigned short lo;
+ unsigned short hi;
+ short x;
+ short y;
+ short w;
+};
+
+struct pdf_font_desc_s
+{
+ fz_storable storable;
+ unsigned int size;
+
+ fz_font *font;
+
+ /* FontDescriptor */
+ int flags;
+ float italic_angle;
+ float ascent;
+ float descent;
+ float cap_height;
+ float x_height;
+ float missing_width;
+
+ /* Encoding (CMap) */
+ pdf_cmap *encoding;
+ pdf_cmap *to_ttf_cmap;
+ int cid_to_gid_len;
+ unsigned short *cid_to_gid;
+
+ /* ToUnicode */
+ pdf_cmap *to_unicode;
+ int cid_to_ucs_len;
+ unsigned short *cid_to_ucs;
+
+ /* Metrics (given in the PDF file) */
+ int wmode;
+
+ int hmtx_len, hmtx_cap;
+ pdf_hmtx dhmtx;
+ pdf_hmtx *hmtx;
+
+ int vmtx_len, vmtx_cap;
+ pdf_vmtx dvmtx;
+ pdf_vmtx *vmtx;
+
+ int is_embedded;
+};
+
+void pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode);
+void pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w);
+void pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w);
+void pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w);
+void pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w);
+void pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font);
+void pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font);
+pdf_hmtx pdf_lookup_hmtx(fz_context *ctx, pdf_font_desc *font, int cid);
+pdf_vmtx pdf_lookup_vmtx(fz_context *ctx, pdf_font_desc *font, int cid);
+
+void pdf_load_to_unicode(pdf_document *doc, pdf_font_desc *font, char **strings, char *collection, pdf_obj *cmapstm);
+
+int pdf_font_cid_to_gid(fz_context *ctx, pdf_font_desc *fontdesc, int cid);
+
+unsigned char *pdf_lookup_builtin_font(char *name, unsigned int *len);
+unsigned char *pdf_lookup_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len);
+unsigned char *pdf_lookup_substitute_cjk_font(int ros, int serif, unsigned int *len);
+
+pdf_font_desc *pdf_load_type3_font(pdf_document *doc, pdf_obj *rdb, pdf_obj *obj);
+pdf_font_desc *pdf_load_font(pdf_document *doc, pdf_obj *rdb, pdf_obj *obj);
+
+pdf_font_desc *pdf_new_font_desc(fz_context *ctx);
+pdf_font_desc *pdf_keep_font(fz_context *ctx, pdf_font_desc *fontdesc);
+void pdf_drop_font(fz_context *ctx, pdf_font_desc *font);
+
+void pdf_print_font(fz_context *ctx, pdf_font_desc *fontdesc);
+
+/*
+ * Interactive features
+ */
+
+typedef struct pdf_annot_s pdf_annot;
+
+struct pdf_annot_s
+{
+ pdf_obj *obj;
+ fz_rect rect;
+ pdf_xobject *ap;
+ fz_matrix matrix;
+ pdf_annot *next;
+};
+
+fz_link_dest pdf_parse_link_dest(pdf_document *doc, pdf_obj *dest);
+fz_link_dest pdf_parse_action(pdf_document *doc, pdf_obj *action);
+pdf_obj *pdf_lookup_dest(pdf_document *doc, pdf_obj *needle);
+pdf_obj *pdf_lookup_name(pdf_document *doc, char *which, pdf_obj *needle);
+pdf_obj *pdf_load_name_tree(pdf_document *doc, char *which);
+
+fz_link *pdf_load_link_annots(pdf_document *, pdf_obj *annots, fz_matrix page_ctm);
+
+pdf_annot *pdf_load_annots(pdf_document *, pdf_obj *annots);
+void pdf_free_annot(fz_context *ctx, pdf_annot *link);
+
+/*
+ * Page tree, pages and related objects
+ */
+
+struct pdf_page_s
+{
+ fz_matrix ctm; /* calculated from mediabox and rotate */
+ fz_rect mediabox;
+ int rotate;
+ int transparency;
+ pdf_obj *resources;
+ fz_buffer *contents;
+ fz_link *links;
+ pdf_annot *annots;
+};
+
+/*
+ * Content stream parsing
+ */
+
+void pdf_run_glyph(pdf_document *doc, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate);
+
+/*
+ * PDF interface to store
+ */
+
+void pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, unsigned int itemsize);
+void *pdf_find_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key);
+void pdf_remove_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key);
+
+#endif
diff --git a/pdf/mupdf.h b/pdf/mupdf.h
index 39245177..b88f7423 100644
--- a/pdf/mupdf.h
+++ b/pdf/mupdf.h
@@ -1,127 +1,151 @@
-#ifndef _MUPDF_H_
-#define _MUPDF_H_
+#ifndef MUPDF_H
+#define MUPDF_H
-#ifndef _FITZ_H_
-#error "fitz.h must be included before mupdf.h"
-#endif
+#include "fitz.h"
typedef struct pdf_document_s pdf_document;
/*
- * tokenizer and low-level object parser
+ * Dynamic objects.
+ * The same type of objects as found in PDF and PostScript.
+ * Used by the filters and the mupdf parser.
*/
-enum
-{
- PDF_TOK_ERROR, PDF_TOK_EOF,
- PDF_TOK_OPEN_ARRAY, PDF_TOK_CLOSE_ARRAY,
- PDF_TOK_OPEN_DICT, PDF_TOK_CLOSE_DICT,
- PDF_TOK_OPEN_BRACE, PDF_TOK_CLOSE_BRACE,
- PDF_TOK_NAME, PDF_TOK_INT, PDF_TOK_REAL, PDF_TOK_STRING, PDF_TOK_KEYWORD,
- PDF_TOK_R, PDF_TOK_TRUE, PDF_TOK_FALSE, PDF_TOK_NULL,
- PDF_TOK_OBJ, PDF_TOK_ENDOBJ,
- PDF_TOK_STREAM, PDF_TOK_ENDSTREAM,
- PDF_TOK_XREF, PDF_TOK_TRAILER, PDF_TOK_STARTXREF,
- PDF_NUM_TOKENS
-};
-
-int pdf_lex(fz_stream *f, char *buf, int n, int *len);
-
-fz_obj *pdf_parse_array(pdf_document *doc, fz_stream *f, char *buf, int cap);
-fz_obj *pdf_parse_dict(pdf_document *doc, fz_stream *f, char *buf, int cap);
-fz_obj *pdf_parse_stm_obj(pdf_document *doc, fz_stream *f, char *buf, int cap);
-fz_obj *pdf_parse_ind_obj(pdf_document *doc, fz_stream *f, char *buf, int cap, int *num, int *gen, int *stm_ofs);
+typedef struct pdf_obj_s pdf_obj;
+
+pdf_obj *pdf_new_null(fz_context *ctx);
+pdf_obj *pdf_new_bool(fz_context *ctx, int b);
+pdf_obj *pdf_new_int(fz_context *ctx, int i);
+pdf_obj *pdf_new_real(fz_context *ctx, float f);
+pdf_obj *fz_new_name(fz_context *ctx, char *str);
+pdf_obj *pdf_new_string(fz_context *ctx, char *str, int len);
+pdf_obj *pdf_new_indirect(fz_context *ctx, int num, int gen, void *doc);
+
+pdf_obj *pdf_new_array(fz_context *ctx, int initialcap);
+pdf_obj *pdf_new_dict(fz_context *ctx, int initialcap);
+pdf_obj *pdf_copy_array(fz_context *ctx, pdf_obj *array);
+pdf_obj *pdf_copy_dict(fz_context *ctx, pdf_obj *dict);
+
+pdf_obj *pdf_keep_obj(pdf_obj *obj);
+void pdf_drop_obj(pdf_obj *obj);
+
+/* type queries */
+int pdf_is_null(pdf_obj *obj);
+int pdf_is_bool(pdf_obj *obj);
+int pdf_is_int(pdf_obj *obj);
+int pdf_is_real(pdf_obj *obj);
+int pdf_is_name(pdf_obj *obj);
+int pdf_is_string(pdf_obj *obj);
+int pdf_is_array(pdf_obj *obj);
+int pdf_is_dict(pdf_obj *obj);
+int pdf_is_indirect(pdf_obj *obj);
+int pdf_is_stream(pdf_document *doc, int num, int gen);
-fz_rect pdf_to_rect(fz_context *ctx, fz_obj *array);
-fz_matrix pdf_to_matrix(fz_context *ctx, fz_obj *array);
-char *pdf_to_utf8(fz_context *ctx, fz_obj *src);
-unsigned short *pdf_to_ucs2(fz_context *ctx, fz_obj *src);
-fz_obj *pdf_to_utf8_name(fz_context *ctx, fz_obj *src);
+int pdf_objcmp(pdf_obj *a, pdf_obj *b);
+
+/* dict marking and unmarking functions - to avoid infinite recursions */
+int pdf_dict_marked(pdf_obj *obj);
+int pdf_dict_mark(pdf_obj *obj);
+void pdf_dict_unmark(pdf_obj *obj);
+
+/* safe, silent failure, no error reporting on type mismatches */
+int pdf_to_bool(pdf_obj *obj);
+int pdf_to_int(pdf_obj *obj);
+float pdf_to_real(pdf_obj *obj);
+char *pdf_to_name(pdf_obj *obj);
+char *pdf_to_str_buf(pdf_obj *obj);
+pdf_obj *pdf_to_dict(pdf_obj *obj);
+int pdf_to_str_len(pdf_obj *obj);
+int pdf_to_num(pdf_obj *obj);
+int pdf_to_gen(pdf_obj *obj);
+
+int pdf_array_len(pdf_obj *array);
+pdf_obj *pdf_array_get(pdf_obj *array, int i);
+void pdf_array_put(pdf_obj *array, int i, pdf_obj *obj);
+void pdf_array_push(pdf_obj *array, pdf_obj *obj);
+void pdf_array_insert(pdf_obj *array, pdf_obj *obj);
+int pdf_array_contains(pdf_obj *array, pdf_obj *obj);
+
+int pdf_dict_len(pdf_obj *dict);
+pdf_obj *pdf_dict_get_key(pdf_obj *dict, int idx);
+pdf_obj *pdf_dict_get_val(pdf_obj *dict, int idx);
+pdf_obj *pdf_dict_get(pdf_obj *dict, pdf_obj *key);
+pdf_obj *pdf_dict_gets(pdf_obj *dict, char *key);
+pdf_obj *pdf_dict_getsa(pdf_obj *dict, char *key, char *abbrev);
+void fz_dict_put(pdf_obj *dict, pdf_obj *key, pdf_obj *val);
+void pdf_dict_puts(pdf_obj *dict, char *key, pdf_obj *val);
+void pdf_dict_del(pdf_obj *dict, pdf_obj *key);
+void pdf_dict_dels(pdf_obj *dict, char *key);
+void pdf_sort_dict(pdf_obj *dict);
+
+int pdf_fprint_obj(FILE *fp, pdf_obj *obj, int tight);
+void pdf_print_obj(pdf_obj *obj);
+void pdf_print_ref(pdf_obj *obj);
+
+char *pdf_to_utf8(fz_context *ctx, pdf_obj *src);
+unsigned short *pdf_to_ucs2(fz_context *ctx, pdf_obj *src); /* sumatrapdf */
+pdf_obj *pdf_to_utf8_name(fz_context *ctx, pdf_obj *src);
char *pdf_from_ucs2(fz_context *ctx, unsigned short *str);
-/*
- * xref and object / stream api
- */
-
-typedef struct pdf_xref_entry_s pdf_xref_entry;
-typedef struct pdf_crypt_s pdf_crypt;
-typedef struct pdf_ocg_descriptor_s pdf_ocg_descriptor;
-typedef struct pdf_ocg_entry_s pdf_ocg_entry;
-
-struct pdf_xref_entry_s
-{
- int ofs; /* file offset / objstm object number */
- int gen; /* generation / objstm index */
- int stm_ofs; /* on-disk stream */
- fz_obj *obj; /* stored/cached object */
- int type; /* 0=unset (f)ree i(n)use (o)bjstm */
-};
-
-struct pdf_ocg_entry_s
-{
- int num;
- int gen;
- int state;
-};
-
-struct pdf_ocg_descriptor_s
-{
- int len;
- pdf_ocg_entry *ocgs;
- fz_obj *intent;
-};
-
-struct pdf_document_s
-{
- fz_document super;
-
- fz_context *ctx;
- fz_stream *file;
+fz_rect pdf_to_rect(fz_context *ctx, pdf_obj *array);
+fz_matrix pdf_to_matrix(fz_context *ctx, pdf_obj *array);
- int version;
- int startxref;
- int file_size;
- pdf_crypt *crypt;
- fz_obj *trailer;
- pdf_ocg_descriptor *ocg;
-
- int len;
- pdf_xref_entry *table;
-
- int page_len;
- int page_cap;
- fz_obj **page_objs;
- fz_obj **page_refs;
-
- char scratch[65536];
-};
+int pdf_count_objects(pdf_document *doc);
+pdf_obj *pdf_resolve_indirect(pdf_obj *ref);
+pdf_obj *pdf_load_object(pdf_document *doc, int num, int gen);
+void pdf_update_object(pdf_document *doc, int num, int gen, pdf_obj *newobj);
-fz_obj *pdf_resolve_indirect(fz_obj *ref);
-void pdf_cache_object(pdf_document *doc, int num, int gen);
-fz_obj *pdf_load_object(pdf_document *doc, int num, int gen);
-void pdf_update_object(pdf_document *doc, int num, int gen, fz_obj *newobj);
-
-int pdf_is_stream(pdf_document *doc, int num, int gen);
-fz_stream *pdf_open_inline_stream(pdf_document *doc, fz_obj *stmobj, int length, fz_stream *chain);
fz_buffer *pdf_load_raw_stream(pdf_document *doc, int num, int gen);
fz_buffer *pdf_load_stream(pdf_document *doc, int num, int gen);
fz_stream *pdf_open_raw_stream(pdf_document *doc, int num, int gen);
fz_stream *pdf_open_stream(pdf_document *doc, int num, int gen);
-fz_stream *pdf_open_stream_with_offset(pdf_document *doc, int num, int gen, fz_obj *dict, int stm_ofs);
-pdf_document *pdf_open_document_with_stream(fz_stream *file);
+fz_image *pdf_load_image(pdf_document *doc, pdf_obj *obj);
+
+fz_outline *pdf_load_outline(pdf_document *doc);
+
+/*
+ pdf_open_document: Open a PDF document.
+
+ Open a PDF document by reading its cross reference table, so
+ MuPDF can locate PDF objects inside the file. Upon an broken
+ cross reference table or other parse errors MuPDF will restart
+ parsing the file from the beginning to try to rebuild a
+ (hopefully correct) cross reference table to allow further
+ processing of the file.
+
+ The returned pdf_document should be used when calling most
+ other PDF functions. Note that it wraps the context, so those
+ functions implicitly get access to the global state in
+ context.
+
+ filename: a path to a file as it would be given to open(2).
+*/
pdf_document *pdf_open_document(fz_context *ctx, const char *filename);
-void pdf_close_document(pdf_document *doc);
-/* private */
-void pdf_repair_xref(pdf_document *doc, char *buf, int bufsize);
-void pdf_repair_obj_stms(pdf_document *doc);
-void pdf_debug_xref(pdf_document *);
-void pdf_resize_xref(pdf_document *doc, int newcap);
+/*
+ pdf_open_document_with_stream: Opens a PDF document.
+
+ Same as pdf_open_document, but takes a stream instead of a
+ filename to locate the PDF document to open. Increments the
+ reference count of the stream. See fz_open_file,
+ fz_open_file_w or fz_open_fd for opening a stream, and
+ fz_close for closing an open stream.
+*/
+pdf_document *pdf_open_document_with_stream(fz_stream *file);
/*
- * Encryption
- */
+ pdf_close_document: Closes and frees an opened PDF document.
+
+ The resource store in the context associated with pdf_document
+ is emptied.
+
+ Does not throw exceptions.
+*/
+void pdf_close_document(pdf_document *doc);
+
+int pdf_needs_password(pdf_document *doc);
+int pdf_authenticate_password(pdf_document *doc, char *pw);
enum
{
@@ -136,339 +160,58 @@ enum
PDF_DEFAULT_PERM_FLAGS = 0xfffc
};
-pdf_crypt *pdf_new_crypt(fz_context *ctx, fz_obj *enc, fz_obj *id);
-void pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt);
-
-void pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, fz_obj *obj, int num, int gen);
-fz_stream *pdf_open_crypt(fz_stream *chain, pdf_crypt *crypt, int num, int gen);
-fz_stream *pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int num, int gen);
-
-int pdf_needs_password(pdf_document *doc);
-int pdf_authenticate_password(pdf_document *doc, char *pw);
int pdf_has_permission(pdf_document *doc, int p);
-int pdf_get_crypt_revision(pdf_document *doc);
-char *pdf_get_crypt_method(pdf_document *doc);
-int pdf_get_crypt_length(pdf_document *doc);
-unsigned char *pdf_get_crypt_key(pdf_document *doc);
-
-void pdf_debug_crypt(pdf_crypt *crypt);
-
-/*
- * Functions, Colorspaces, Shadings and Images
- */
-
-typedef struct pdf_function_s pdf_function;
-
-pdf_function *pdf_load_function(pdf_document *doc, fz_obj *ref);
-void pdf_eval_function(fz_context *ctx, pdf_function *func, float *in, int inlen, float *out, int outlen);
-pdf_function *pdf_keep_function(fz_context *ctx, pdf_function *func);
-void pdf_drop_function(fz_context *ctx, pdf_function *func);
-unsigned int pdf_function_size(pdf_function *func);
-
-fz_colorspace *pdf_load_colorspace(pdf_document *doc, fz_obj *obj);
-fz_pixmap *pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src);
-
-fz_shade *pdf_load_shading(pdf_document *doc, fz_obj *obj);
-
-fz_pixmap *pdf_load_inline_image(pdf_document *doc, fz_obj *rdb, fz_obj *dict, fz_stream *file);
-fz_pixmap *pdf_load_image(pdf_document *doc, fz_obj *obj);
-int pdf_is_jpx_image(fz_context *ctx, fz_obj *dict);
-
-/*
- * Pattern
- */
-
-typedef struct pdf_pattern_s pdf_pattern;
-
-struct pdf_pattern_s
-{
- fz_storable storable;
- int ismask;
- float xstep;
- float ystep;
- fz_matrix matrix;
- fz_rect bbox;
- fz_obj *resources;
- fz_buffer *contents;
-};
-
-pdf_pattern *pdf_load_pattern(pdf_document *doc, fz_obj *obj);
-pdf_pattern *pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat);
-void pdf_drop_pattern(fz_context *ctx, pdf_pattern *pat);
-
-/*
- * XObject
- */
-
-typedef struct pdf_xobject_s pdf_xobject;
-
-struct pdf_xobject_s
-{
- fz_storable storable;
- fz_matrix matrix;
- fz_rect bbox;
- int isolated;
- int knockout;
- int transparency;
- fz_colorspace *colorspace;
- fz_obj *resources;
- fz_buffer *contents;
- fz_obj *me;
-};
+typedef struct pdf_page_s pdf_page;
-pdf_xobject *pdf_load_xobject(pdf_document *doc, fz_obj *obj);
-pdf_xobject *pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj);
-void pdf_drop_xobject(fz_context *ctx, pdf_xobject *xobj);
+int pdf_lookup_page_number(pdf_document *doc, pdf_obj *pageobj);
+int pdf_count_pages(pdf_document *doc);
/*
- * CMap
- */
-
-typedef struct pdf_cmap_s pdf_cmap;
-typedef struct pdf_range_s pdf_range;
+ pdf_load_page: Load a page and its resources.
-enum { PDF_CMAP_SINGLE, PDF_CMAP_RANGE, PDF_CMAP_TABLE, PDF_CMAP_MULTI };
+ Locates the page in the PDF document and loads the page and its
+ resources. After pdf_load_page is it possible to retrieve the size
+ of the page using pdf_bound_page, or to render the page using
+ pdf_run_page_*.
-struct pdf_range_s
-{
- unsigned short low;
- /* Next, we pack 2 fields into the same unsigned short. Top 14 bits
- * are the extent, bottom 2 bits are flags: single, range, table,
- * multi */
- unsigned short extent_flags;
- unsigned short offset; /* range-delta or table-index */
-};
-
-struct pdf_cmap_s
-{
- fz_storable storable;
- char cmap_name[32];
-
- char usecmap_name[32];
- pdf_cmap *usecmap;
-
- int wmode;
-
- int codespace_len;
- struct
- {
- unsigned short n;
- unsigned short low;
- unsigned short high;
- } codespace[40];
-
- int rlen, rcap;
- pdf_range *ranges;
-
- int tlen, tcap;
- unsigned short *table;
-};
+ number: page number, where 0 is the first page of the document.
+*/
+pdf_page *pdf_load_page(pdf_document *doc, int number);
-pdf_cmap *pdf_new_cmap(fz_context *ctx);
-pdf_cmap *pdf_keep_cmap(fz_context *ctx, pdf_cmap *cmap);
-void pdf_drop_cmap(fz_context *ctx, pdf_cmap *cmap);
-void pdf_free_cmap_imp(fz_context *ctx, fz_storable *cmap);
-unsigned int pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap);
-
-void pdf_debug_cmap(fz_context *ctx, pdf_cmap *cmap);
-int pdf_get_wmode(fz_context *ctx, pdf_cmap *cmap);
-void pdf_set_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode);
-void pdf_set_usecmap(fz_context *ctx, pdf_cmap *cmap, pdf_cmap *usecmap);
-
-void pdf_add_codespace(fz_context *ctx, pdf_cmap *cmap, int low, int high, int n);
-void pdf_map_range_to_table(fz_context *ctx, pdf_cmap *cmap, int low, int *map, int len);
-void pdf_map_range_to_range(fz_context *ctx, pdf_cmap *cmap, int srclo, int srchi, int dstlo);
-void pdf_map_one_to_many(fz_context *ctx, pdf_cmap *cmap, int one, int *many, int len);
-void pdf_sort_cmap(fz_context *ctx, pdf_cmap *cmap);
-
-int pdf_lookup_cmap(pdf_cmap *cmap, int cpt);
-int pdf_lookup_cmap_full(pdf_cmap *cmap, int cpt, int *out);
-int pdf_decode_cmap(pdf_cmap *cmap, unsigned char *s, int *cpt);
-
-pdf_cmap *pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes);
-pdf_cmap *pdf_load_cmap(fz_context *ctx, fz_stream *file);
-pdf_cmap *pdf_load_system_cmap(fz_context *ctx, char *name);
-pdf_cmap *pdf_load_builtin_cmap(fz_context *ctx, char *name);
-pdf_cmap *pdf_load_embedded_cmap(pdf_document *doc, fz_obj *ref);
+fz_link *pdf_load_links(pdf_document *doc, pdf_page *page);
/*
- * Font
- */
-
-enum
-{
- PDF_FD_FIXED_PITCH = 1 << 0,
- PDF_FD_SERIF = 1 << 1,
- PDF_FD_SYMBOLIC = 1 << 2,
- PDF_FD_SCRIPT = 1 << 3,
- PDF_FD_NONSYMBOLIC = 1 << 5,
- PDF_FD_ITALIC = 1 << 6,
- PDF_FD_ALL_CAP = 1 << 16,
- PDF_FD_SMALL_CAP = 1 << 17,
- PDF_FD_FORCE_BOLD = 1 << 18
-};
-
-enum { PDF_ROS_CNS, PDF_ROS_GB, PDF_ROS_JAPAN, PDF_ROS_KOREA };
-
-void pdf_load_encoding(char **estrings, char *encoding);
-int pdf_lookup_agl(char *name);
-const char **pdf_lookup_agl_duplicates(int ucs);
-
-extern const unsigned short pdf_doc_encoding[256];
-extern const char * const pdf_mac_roman[256];
-extern const char * const pdf_mac_expert[256];
-extern const char * const pdf_win_ansi[256];
-extern const char * const pdf_standard[256];
-
-typedef struct pdf_font_desc_s pdf_font_desc;
-typedef struct pdf_hmtx_s pdf_hmtx;
-typedef struct pdf_vmtx_s pdf_vmtx;
-
-struct pdf_hmtx_s
-{
- unsigned short lo;
- unsigned short hi;
- int w; /* type3 fonts can be big! */
-};
-
-struct pdf_vmtx_s
-{
- unsigned short lo;
- unsigned short hi;
- short x;
- short y;
- short w;
-};
+ pdf_bound_page: Determine the size of a page.
-struct pdf_font_desc_s
-{
- fz_storable storable;
- unsigned int size;
-
- fz_font *font;
-
- /* FontDescriptor */
- int flags;
- float italic_angle;
- float ascent;
- float descent;
- float cap_height;
- float x_height;
- float missing_width;
-
- /* Encoding (CMap) */
- pdf_cmap *encoding;
- pdf_cmap *to_ttf_cmap;
- int cid_to_gid_len;
- unsigned short *cid_to_gid;
-
- /* ToUnicode */
- pdf_cmap *to_unicode;
- int cid_to_ucs_len;
- unsigned short *cid_to_ucs;
-
- /* Metrics (given in the PDF file) */
- int wmode;
-
- int hmtx_len, hmtx_cap;
- pdf_hmtx dhmtx;
- pdf_hmtx *hmtx;
-
- int vmtx_len, vmtx_cap;
- pdf_vmtx dvmtx;
- pdf_vmtx *vmtx;
-
- int is_embedded;
-};
-
-void pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode);
-void pdf_set_default_hmtx(fz_context *ctx, pdf_font_desc *font, int w);
-void pdf_set_default_vmtx(fz_context *ctx, pdf_font_desc *font, int y, int w);
-void pdf_add_hmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int w);
-void pdf_add_vmtx(fz_context *ctx, pdf_font_desc *font, int lo, int hi, int x, int y, int w);
-void pdf_end_hmtx(fz_context *ctx, pdf_font_desc *font);
-void pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font);
-pdf_hmtx pdf_get_hmtx(fz_context *ctx, pdf_font_desc *font, int cid);
-pdf_vmtx pdf_get_vmtx(fz_context *ctx, pdf_font_desc *font, int cid);
-
-void pdf_load_to_unicode(pdf_document *doc, pdf_font_desc *font, char **strings, char *collection, fz_obj *cmapstm);
-
-int pdf_font_cid_to_gid(fz_context *ctx, pdf_font_desc *fontdesc, int cid);
+ Determine the page size in user space units, taking page rotation
+ into account. The page size is taken to be the crop box if it
+ exists (visible area after cropping), otherwise the media box will
+ be used (possibly including printing marks).
-unsigned char *pdf_find_builtin_font(char *name, unsigned int *len);
-unsigned char *pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len);
-unsigned char *pdf_find_substitute_cjk_font(int ros, int serif, unsigned int *len);
-
-pdf_font_desc *pdf_load_type3_font(pdf_document *doc, fz_obj *rdb, fz_obj *obj);
-pdf_font_desc *pdf_load_font(pdf_document *doc, fz_obj *rdb, fz_obj *obj);
-
-pdf_font_desc *pdf_new_font_desc(fz_context *ctx);
-pdf_font_desc *pdf_keep_font(fz_context *ctx, pdf_font_desc *fontdesc);
-void pdf_drop_font(fz_context *ctx, pdf_font_desc *font);
-
-void pdf_debug_font(fz_context *ctx, pdf_font_desc *fontdesc);
+ Does not throw exceptions.
+*/
+fz_rect pdf_bound_page(pdf_document *doc, pdf_page *page);
/*
- * Interactive features
- */
-
-typedef struct pdf_annot_s pdf_annot;
-
-struct pdf_annot_s
-{
- fz_obj *obj;
- fz_rect rect;
- pdf_xobject *ap;
- fz_matrix matrix;
- pdf_annot *next;
-};
-
-fz_link_dest pdf_parse_link_dest(pdf_document *doc, fz_obj *dest);
-fz_link_dest pdf_parse_action(pdf_document *doc, fz_obj *action);
-fz_obj *pdf_lookup_dest(pdf_document *doc, fz_obj *needle);
-fz_obj *pdf_lookup_name(pdf_document *doc, char *which, fz_obj *needle);
-fz_obj *pdf_load_name_tree(pdf_document *doc, char *which);
-
-fz_outline *pdf_load_outline(pdf_document *doc);
+ pdf_free_page: Frees a page and its resources.
-fz_link *pdf_load_link_annots(pdf_document *, fz_obj *annots, fz_matrix page_ctm);
-
-pdf_annot *pdf_load_annots(pdf_document *, fz_obj *annots);
-void pdf_free_annot(fz_context *ctx, pdf_annot *link);
+ Does not throw exceptions.
+*/
+void pdf_free_page(pdf_document *doc, pdf_page *page);
/*
- * Page tree, pages and related objects
- */
+ pdf_run_page: Interpret a loaded page and render it on a device.
-typedef struct pdf_page_s pdf_page;
+ page: A page loaded by pdf_load_page.
-struct pdf_page_s
-{
- fz_matrix ctm; /* calculated from mediabox and rotate */
- fz_rect mediabox;
- int rotate;
- int transparency;
- fz_obj *resources;
- fz_buffer *contents;
- fz_link *links;
- pdf_annot *annots;
-};
-
-int pdf_find_page_number(pdf_document *doc, fz_obj *pageobj);
-int pdf_count_pages(pdf_document *doc);
+ dev: Device used for rendering, obtained from fz_new_*_device.
-pdf_page *pdf_load_page(pdf_document *doc, int number);
-fz_link *pdf_load_links(pdf_document *doc, pdf_page *page);
-fz_rect pdf_bound_page(pdf_document *doc, pdf_page *page);
-void pdf_free_page(pdf_document *doc, pdf_page *page);
-
-/*
- * Content stream parsing
- */
+ ctm: A transformation matrix applied to the objects on the page,
+ e.g. to scale or rotate the page contents as desired.
+*/
+void pdf_run_page(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
void pdf_run_page_with_usage(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, char *event, fz_cookie *cookie);
-void pdf_run_page(pdf_document *doc, pdf_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
-void pdf_run_glyph(pdf_document *doc, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate);
#endif
diff --git a/pdf/pdf_annot.c b/pdf/pdf_annot.c
index ae03f2b6..28300c9b 100644
--- a/pdf/pdf_annot.c
+++ b/pdf/pdf_annot.c
@@ -1,46 +1,46 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
-static fz_obj *
-resolve_dest_rec(pdf_document *xref, fz_obj *dest, int depth)
+static pdf_obj *
+resolve_dest_rec(pdf_document *xref, pdf_obj *dest, int depth)
{
if (depth > 10) /* Arbitrary to avoid infinite recursion */
return NULL;
- if (fz_is_name(dest) || fz_is_string(dest))
+ if (pdf_is_name(dest) || pdf_is_string(dest))
{
dest = pdf_lookup_dest(xref, dest);
return resolve_dest_rec(xref, dest, depth+1);
}
- else if (fz_is_array(dest))
+ else if (pdf_is_array(dest))
{
return dest;
}
- else if (fz_is_dict(dest))
+ else if (pdf_is_dict(dest))
{
- dest = fz_dict_gets(dest, "D");
+ dest = pdf_dict_gets(dest, "D");
return resolve_dest_rec(xref, dest, depth+1);
}
- else if (fz_is_indirect(dest))
+ else if (pdf_is_indirect(dest))
return dest;
return NULL;
}
-static fz_obj *
-resolve_dest(pdf_document *xref, fz_obj *dest)
+static pdf_obj *
+resolve_dest(pdf_document *xref, pdf_obj *dest)
{
return resolve_dest_rec(xref, dest, 0);
}
fz_link_dest
-pdf_parse_link_dest(pdf_document *xref, fz_obj *dest)
+pdf_parse_link_dest(pdf_document *xref, pdf_obj *dest)
{
fz_link_dest ld;
- fz_obj *obj;
+ pdf_obj *obj;
int l_from_2 = 0;
int b_from_3 = 0;
@@ -51,16 +51,16 @@ pdf_parse_link_dest(pdf_document *xref, fz_obj *dest)
int z_from_4 = 0;
dest = resolve_dest(xref, dest);
- if (dest == NULL || !fz_is_array(dest))
+ if (dest == NULL || !pdf_is_array(dest))
{
ld.kind = FZ_LINK_NONE;
return ld;
}
- obj = fz_array_get(dest, 0);
- if (fz_is_int(obj))
- ld.ld.gotor.page = fz_to_int(obj);
+ obj = pdf_array_get(dest, 0);
+ if (pdf_is_int(obj))
+ ld.ld.gotor.page = pdf_to_int(obj);
else
- ld.ld.gotor.page = pdf_find_page_number(xref, obj);
+ ld.ld.gotor.page = pdf_lookup_page_number(xref, obj);
ld.kind = FZ_LINK_GOTO;
ld.ld.gotor.flags = 0;
@@ -71,31 +71,31 @@ pdf_parse_link_dest(pdf_document *xref, fz_obj *dest)
ld.ld.gotor.file_spec = NULL;
ld.ld.gotor.new_window = 0;
- obj = fz_array_get(dest, 1);
- if (!fz_is_name(obj))
+ obj = pdf_array_get(dest, 1);
+ if (!pdf_is_name(obj))
return ld;
- if (!strcmp("XYZ", fz_to_name(obj)))
+ if (!strcmp("XYZ", pdf_to_name(obj)))
{
l_from_2 = t_from_3 = z_from_4 = 1;
ld.ld.gotor.flags |= fz_link_flag_r_is_zoom;
}
- else if ((!strcmp("Fit", fz_to_name(obj))) || (!strcmp("FitB", fz_to_name(obj))))
+ else if ((!strcmp("Fit", pdf_to_name(obj))) || (!strcmp("FitB", pdf_to_name(obj))))
{
ld.ld.gotor.flags |= fz_link_flag_fit_h;
ld.ld.gotor.flags |= fz_link_flag_fit_v;
}
- else if ((!strcmp("FitH", fz_to_name(obj))) || (!strcmp("FitBH", fz_to_name(obj))))
+ else if ((!strcmp("FitH", pdf_to_name(obj))) || (!strcmp("FitBH", pdf_to_name(obj))))
{
t_from_2 = 1;
ld.ld.gotor.flags |= fz_link_flag_fit_h;
}
- else if ((!strcmp("FitV", fz_to_name(obj))) || (!strcmp("FitBV", fz_to_name(obj))))
+ else if ((!strcmp("FitV", pdf_to_name(obj))) || (!strcmp("FitBV", pdf_to_name(obj))))
{
l_from_2 = 1;
ld.ld.gotor.flags |= fz_link_flag_fit_v;
}
- else if (!strcmp("FitR", fz_to_name(obj)))
+ else if (!strcmp("FitR", pdf_to_name(obj)))
{
l_from_2 = b_from_3 = r_from_4 = t_from_5 = 1;
ld.ld.gotor.flags |= fz_link_flag_fit_h;
@@ -104,77 +104,77 @@ pdf_parse_link_dest(pdf_document *xref, fz_obj *dest)
if (l_from_2)
{
- obj = fz_array_get(dest, 2);
- if (fz_is_int(obj))
+ obj = pdf_array_get(dest, 2);
+ if (pdf_is_int(obj))
{
ld.ld.gotor.flags |= fz_link_flag_l_valid;
- ld.ld.gotor.lt.x = fz_to_int(obj);
+ ld.ld.gotor.lt.x = pdf_to_int(obj);
}
- else if (fz_is_real(obj))
+ else if (pdf_is_real(obj))
{
ld.ld.gotor.flags |= fz_link_flag_l_valid;
- ld.ld.gotor.lt.x = fz_to_real(obj);
+ ld.ld.gotor.lt.x = pdf_to_real(obj);
}
}
if (b_from_3)
{
- obj = fz_array_get(dest, 3);
- if (fz_is_int(obj))
+ obj = pdf_array_get(dest, 3);
+ if (pdf_is_int(obj))
{
ld.ld.gotor.flags |= fz_link_flag_b_valid;
- ld.ld.gotor.rb.y = fz_to_int(obj);
+ ld.ld.gotor.rb.y = pdf_to_int(obj);
}
- else if (fz_is_real(obj))
+ else if (pdf_is_real(obj))
{
ld.ld.gotor.flags |= fz_link_flag_b_valid;
- ld.ld.gotor.rb.y = fz_to_real(obj);
+ ld.ld.gotor.rb.y = pdf_to_real(obj);
}
}
if (r_from_4)
{
- obj = fz_array_get(dest, 4);
- if (fz_is_int(obj))
+ obj = pdf_array_get(dest, 4);
+ if (pdf_is_int(obj))
{
ld.ld.gotor.flags |= fz_link_flag_r_valid;
- ld.ld.gotor.rb.x = fz_to_int(obj);
+ ld.ld.gotor.rb.x = pdf_to_int(obj);
}
- else if (fz_is_real(obj))
+ else if (pdf_is_real(obj))
{
ld.ld.gotor.flags |= fz_link_flag_r_valid;
- ld.ld.gotor.rb.x = fz_to_real(obj);
+ ld.ld.gotor.rb.x = pdf_to_real(obj);
}
}
if (t_from_5 || t_from_3 || t_from_2)
{
if (t_from_5)
- obj = fz_array_get(dest, 5);
+ obj = pdf_array_get(dest, 5);
else if (t_from_3)
- obj = fz_array_get(dest, 3);
+ obj = pdf_array_get(dest, 3);
else
- obj = fz_array_get(dest, 2);
- if (fz_is_int(obj))
+ obj = pdf_array_get(dest, 2);
+ if (pdf_is_int(obj))
{
ld.ld.gotor.flags |= fz_link_flag_t_valid;
- ld.ld.gotor.lt.y = fz_to_int(obj);
+ ld.ld.gotor.lt.y = pdf_to_int(obj);
}
- else if (fz_is_real(obj))
+ else if (pdf_is_real(obj))
{
ld.ld.gotor.flags |= fz_link_flag_t_valid;
- ld.ld.gotor.lt.y = fz_to_real(obj);
+ ld.ld.gotor.lt.y = pdf_to_real(obj);
}
}
if (z_from_4)
{
- obj = fz_array_get(dest, 4);
- if (fz_is_int(obj))
+ obj = pdf_array_get(dest, 4);
+ if (pdf_is_int(obj))
{
ld.ld.gotor.flags |= fz_link_flag_r_valid;
- ld.ld.gotor.rb.x = fz_to_int(obj);
+ ld.ld.gotor.rb.x = pdf_to_int(obj);
}
- else if (fz_is_real(obj))
+ else if (pdf_is_real(obj))
{
ld.ld.gotor.flags |= fz_link_flag_r_valid;
- ld.ld.gotor.rb.x = fz_to_real(obj);
+ ld.ld.gotor.rb.x = pdf_to_real(obj);
}
}
@@ -192,10 +192,10 @@ pdf_parse_link_dest(pdf_document *xref, fz_obj *dest)
}
fz_link_dest
-pdf_parse_action(pdf_document *xref, fz_obj *action)
+pdf_parse_action(pdf_document *xref, pdf_obj *action)
{
fz_link_dest ld;
- fz_obj *obj, *dest;
+ pdf_obj *obj, *dest;
fz_context *ctx = xref->ctx;
ld.kind = FZ_LINK_NONE;
@@ -203,53 +203,53 @@ pdf_parse_action(pdf_document *xref, fz_obj *action)
if (!action)
return ld;
- obj = fz_dict_gets(action, "S");
- if (!strcmp(fz_to_name(obj), "GoTo"))
+ obj = pdf_dict_gets(action, "S");
+ if (!strcmp(pdf_to_name(obj), "GoTo"))
{
- dest = fz_dict_gets(action, "D");
+ dest = pdf_dict_gets(action, "D");
ld = pdf_parse_link_dest(xref, dest);
}
- else if (!strcmp(fz_to_name(obj), "URI"))
+ else if (!strcmp(pdf_to_name(obj), "URI"))
{
ld.kind = FZ_LINK_URI;
- ld.ld.uri.is_map = fz_to_bool(fz_dict_gets(action, "IsMap"));
- ld.ld.uri.uri = pdf_to_utf8(ctx, fz_dict_gets(action, "URI"));
+ ld.ld.uri.is_map = pdf_to_bool(pdf_dict_gets(action, "IsMap"));
+ ld.ld.uri.uri = pdf_to_utf8(ctx, pdf_dict_gets(action, "URI"));
}
- else if (!strcmp(fz_to_name(obj), "Launch"))
+ else if (!strcmp(pdf_to_name(obj), "Launch"))
{
ld.kind = FZ_LINK_LAUNCH;
- ld.ld.launch.file_spec = pdf_to_utf8(ctx, fz_dict_gets(action, "F"));
- ld.ld.launch.new_window = fz_to_int(fz_dict_gets(action, "NewWindow"));
+ ld.ld.launch.file_spec = pdf_to_utf8(ctx, pdf_dict_gets(action, "F"));
+ ld.ld.launch.new_window = pdf_to_int(pdf_dict_gets(action, "NewWindow"));
}
- else if (!strcmp(fz_to_name(obj), "Named"))
+ else if (!strcmp(pdf_to_name(obj), "Named"))
{
ld.kind = FZ_LINK_NAMED;
- ld.ld.named.named = pdf_to_utf8(ctx, fz_dict_gets(action, "N"));
+ ld.ld.named.named = pdf_to_utf8(ctx, pdf_dict_gets(action, "N"));
}
- else if (!strcmp(fz_to_name(obj), "GoToR"))
+ else if (!strcmp(pdf_to_name(obj), "GoToR"))
{
- dest = fz_dict_gets(action, "D");
+ dest = pdf_dict_gets(action, "D");
ld = pdf_parse_link_dest(xref, dest);
ld.kind = FZ_LINK_GOTOR;
- ld.ld.gotor.file_spec = pdf_to_utf8(ctx, fz_dict_gets(action, "F"));
- ld.ld.gotor.new_window = fz_to_int(fz_dict_gets(action, "NewWindow"));
+ ld.ld.gotor.file_spec = pdf_to_utf8(ctx, pdf_dict_gets(action, "F"));
+ ld.ld.gotor.new_window = pdf_to_int(pdf_dict_gets(action, "NewWindow"));
}
return ld;
}
static fz_link *
-pdf_load_link(pdf_document *xref, fz_obj *dict, fz_matrix page_ctm)
+pdf_load_link(pdf_document *xref, pdf_obj *dict, fz_matrix page_ctm)
{
- fz_obj *dest = NULL;
- fz_obj *action;
- fz_obj *obj;
+ pdf_obj *dest = NULL;
+ pdf_obj *action;
+ pdf_obj *obj;
fz_rect bbox;
fz_context *ctx = xref->ctx;
fz_link_dest ld;
dest = NULL;
- obj = fz_dict_gets(dict, "Rect");
+ obj = pdf_dict_gets(dict, "Rect");
if (obj)
bbox = pdf_to_rect(ctx, obj);
else
@@ -257,7 +257,7 @@ pdf_load_link(pdf_document *xref, fz_obj *dict, fz_matrix page_ctm)
bbox = fz_transform_rect(page_ctm, bbox);
- obj = fz_dict_gets(dict, "Dest");
+ obj = pdf_dict_gets(dict, "Dest");
if (obj)
{
dest = resolve_dest(xref, obj);
@@ -265,10 +265,10 @@ pdf_load_link(pdf_document *xref, fz_obj *dict, fz_matrix page_ctm)
}
else
{
- action = fz_dict_gets(dict, "A");
+ action = pdf_dict_gets(dict, "A");
/* fall back to additional action button's down/up action */
if (!action)
- action = fz_dict_getsa(fz_dict_gets(dict, "AA"), "U", "D");
+ action = pdf_dict_getsa(pdf_dict_gets(dict, "AA"), "U", "D");
ld = pdf_parse_action(xref, action);
}
@@ -278,19 +278,19 @@ pdf_load_link(pdf_document *xref, fz_obj *dict, fz_matrix page_ctm)
}
fz_link *
-pdf_load_link_annots(pdf_document *xref, fz_obj *annots, fz_matrix page_ctm)
+pdf_load_link_annots(pdf_document *xref, pdf_obj *annots, fz_matrix page_ctm)
{
fz_link *link, *head, *tail;
- fz_obj *obj;
+ pdf_obj *obj;
int i, n;
head = tail = NULL;
link = NULL;
- n = fz_array_len(annots);
+ n = pdf_array_len(annots);
for (i = 0; i < n; i++)
{
- obj = fz_array_get(annots, i);
+ obj = pdf_array_get(annots, i);
link = pdf_load_link(xref, obj, page_ctm);
if (link)
{
@@ -318,7 +318,7 @@ pdf_free_annot(fz_context *ctx, pdf_annot *annot)
if (annot->ap)
pdf_drop_xobject(ctx, annot->ap);
if (annot->obj)
- fz_drop_obj(annot->obj);
+ pdf_drop_obj(annot->obj);
fz_free(ctx, annot);
annot = next;
}
@@ -349,10 +349,10 @@ pdf_transform_annot(pdf_annot *annot)
}
pdf_annot *
-pdf_load_annots(pdf_document *xref, fz_obj *annots)
+pdf_load_annots(pdf_document *xref, pdf_obj *annots)
{
pdf_annot *annot, *head, *tail;
- fz_obj *obj, *ap, *as, *n, *rect;
+ pdf_obj *obj, *ap, *as, *n, *rect;
pdf_xobject *form;
int i, len;
fz_context *ctx = xref->ctx;
@@ -360,23 +360,23 @@ pdf_load_annots(pdf_document *xref, fz_obj *annots)
head = tail = NULL;
annot = NULL;
- len = fz_array_len(annots);
+ len = pdf_array_len(annots);
for (i = 0; i < len; i++)
{
- obj = fz_array_get(annots, i);
+ obj = pdf_array_get(annots, i);
- rect = fz_dict_gets(obj, "Rect");
- ap = fz_dict_gets(obj, "AP");
- as = fz_dict_gets(obj, "AS");
- if (fz_is_dict(ap))
+ rect = pdf_dict_gets(obj, "Rect");
+ ap = pdf_dict_gets(obj, "AP");
+ as = pdf_dict_gets(obj, "AS");
+ if (pdf_is_dict(ap))
{
- n = fz_dict_gets(ap, "N"); /* normal state */
+ n = pdf_dict_gets(ap, "N"); /* normal state */
/* lookup current state in sub-dictionary */
- if (!pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n)))
- n = fz_dict_get(n, as);
+ if (!pdf_is_stream(xref, pdf_to_num(n), pdf_to_gen(n)))
+ n = pdf_dict_get(n, as);
- if (pdf_is_stream(xref, fz_to_num(n), fz_to_gen(n)))
+ if (pdf_is_stream(xref, pdf_to_num(n), pdf_to_gen(n)))
{
fz_try(ctx)
{
@@ -389,7 +389,7 @@ pdf_load_annots(pdf_document *xref, fz_obj *annots)
}
annot = fz_malloc_struct(ctx, pdf_annot);
- annot->obj = fz_keep_obj(obj);
+ annot->obj = pdf_keep_obj(obj);
annot->rect = pdf_to_rect(ctx, rect);
annot->ap = form;
annot->next = NULL;
diff --git a/pdf/pdf_cmap.c b/pdf/pdf_cmap.c
index 987da592..3c4d07bc 100644
--- a/pdf/pdf_cmap.c
+++ b/pdf/pdf_cmap.c
@@ -15,8 +15,8 @@
* or can trust the parser to give us optimal mappings.
*/
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
/* Macros for accessing the combined extent_flags field */
#define pdf_range_high(r) ((r)->low + ((r)->extent_flags >> 2))
@@ -98,19 +98,19 @@ pdf_set_usecmap(fz_context *ctx, pdf_cmap *cmap, pdf_cmap *usecmap)
}
int
-pdf_get_wmode(fz_context *ctx, pdf_cmap *cmap)
+pdf_cmap_wmode(fz_context *ctx, pdf_cmap *cmap)
{
return cmap->wmode;
}
void
-pdf_set_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode)
+pdf_set_cmap_wmode(fz_context *ctx, pdf_cmap *cmap, int wmode)
{
cmap->wmode = wmode;
}
void
-pdf_debug_cmap(fz_context *ctx, pdf_cmap *cmap)
+pdf_print_cmap(fz_context *ctx, pdf_cmap *cmap)
{
int i, k, n;
diff --git a/pdf/pdf_cmap_load.c b/pdf/pdf_cmap_load.c
index 3257516c..8ab7e646 100644
--- a/pdf/pdf_cmap_load.c
+++ b/pdf/pdf_cmap_load.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
unsigned int
pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap)
@@ -16,13 +16,13 @@ pdf_cmap_size(fz_context *ctx, pdf_cmap *cmap)
* Load CMap stream in PDF file
*/
pdf_cmap *
-pdf_load_embedded_cmap(pdf_document *xref, fz_obj *stmobj)
+pdf_load_embedded_cmap(pdf_document *xref, pdf_obj *stmobj)
{
fz_stream *file = NULL;
pdf_cmap *cmap = NULL;
pdf_cmap *usecmap;
- fz_obj *wmode;
- fz_obj *obj = NULL;
+ pdf_obj *wmode;
+ pdf_obj *obj = NULL;
fz_context *ctx = xref->ctx;
int phase = 0;
@@ -31,31 +31,31 @@ pdf_load_embedded_cmap(pdf_document *xref, fz_obj *stmobj)
fz_var(file);
fz_var(cmap);
- if ((cmap = fz_find_item(ctx, pdf_free_cmap_imp, stmobj)))
+ if ((cmap = pdf_find_item(ctx, pdf_free_cmap_imp, stmobj)))
{
return cmap;
}
fz_try(ctx)
{
- file = pdf_open_stream(xref, fz_to_num(stmobj), fz_to_gen(stmobj));
+ file = pdf_open_stream(xref, pdf_to_num(stmobj), pdf_to_gen(stmobj));
phase = 1;
cmap = pdf_load_cmap(ctx, file);
phase = 2;
fz_close(file);
file = NULL;
- wmode = fz_dict_gets(stmobj, "WMode");
- if (fz_is_int(wmode))
- pdf_set_wmode(ctx, cmap, fz_to_int(wmode));
- obj = fz_dict_gets(stmobj, "UseCMap");
- if (fz_is_name(obj))
+ wmode = pdf_dict_gets(stmobj, "WMode");
+ if (pdf_is_int(wmode))
+ pdf_set_cmap_wmode(ctx, cmap, pdf_to_int(wmode));
+ obj = pdf_dict_gets(stmobj, "UseCMap");
+ if (pdf_is_name(obj))
{
- usecmap = pdf_load_system_cmap(ctx, fz_to_name(obj));
+ usecmap = pdf_load_system_cmap(ctx, pdf_to_name(obj));
pdf_set_usecmap(ctx, cmap, usecmap);
pdf_drop_cmap(ctx, usecmap);
}
- else if (fz_is_indirect(obj))
+ else if (pdf_is_indirect(obj))
{
phase = 3;
usecmap = pdf_load_embedded_cmap(xref, obj);
@@ -63,7 +63,7 @@ pdf_load_embedded_cmap(pdf_document *xref, fz_obj *stmobj)
pdf_drop_cmap(ctx, usecmap);
}
- fz_store_item(ctx, stmobj, cmap, pdf_cmap_size(ctx, cmap));
+ pdf_store_item(ctx, stmobj, cmap, pdf_cmap_size(ctx, cmap));
}
fz_catch(ctx)
{
@@ -72,13 +72,13 @@ pdf_load_embedded_cmap(pdf_document *xref, fz_obj *stmobj)
if (cmap)
pdf_drop_cmap(ctx, cmap);
if (phase < 1)
- fz_throw(ctx, "cannot open cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj));
+ fz_throw(ctx, "cannot open cmap stream (%d %d R)", pdf_to_num(stmobj), pdf_to_gen(stmobj));
else if (phase < 2)
- fz_throw(ctx, "cannot parse cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj));
+ fz_throw(ctx, "cannot parse cmap stream (%d %d R)", pdf_to_num(stmobj), pdf_to_gen(stmobj));
else if (phase < 3)
- fz_throw(ctx, "cannot load system usecmap '%s'", fz_to_name(obj));
+ fz_throw(ctx, "cannot load system usecmap '%s'", pdf_to_name(obj));
else
- fz_throw(ctx, "cannot load embedded usecmap (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ fz_throw(ctx, "cannot load embedded usecmap (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
}
return cmap;
@@ -97,7 +97,7 @@ pdf_new_identity_cmap(fz_context *ctx, int wmode, int bytes)
pdf_add_codespace(ctx, cmap, 0x0000, 0xffff, bytes);
pdf_map_range_to_range(ctx, cmap, 0x0000, 0xffff, 0);
pdf_sort_cmap(ctx, cmap);
- pdf_set_wmode(ctx, cmap, wmode);
+ pdf_set_cmap_wmode(ctx, cmap, wmode);
}
fz_catch(ctx)
{
diff --git a/pdf/pdf_cmap_parse.c b/pdf/pdf_cmap_parse.c
index fb37c4a9..93dd97c9 100644
--- a/pdf/pdf_cmap_parse.c
+++ b/pdf/pdf_cmap_parse.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
/*
* CMap parser
@@ -49,14 +49,14 @@ pdf_code_from_string(char *buf, int len)
}
static int
-pdf_lex_cmap(fz_stream *file, char *buf, int n, int *sl)
+pdf_lex_cmap(fz_stream *file, pdf_lexbuf *buf)
{
- int tok = pdf_lex(file, buf, n, sl);
+ int tok = pdf_lex(file, buf);
/* RJW: Lost debugging here: "cannot parse cmap token" */
if (tok == PDF_TOK_KEYWORD)
- tok = pdf_cmap_token_from_keyword(buf);
+ tok = pdf_cmap_token_from_keyword(buf->scratch);
return tok;
}
@@ -64,15 +64,15 @@ pdf_lex_cmap(fz_stream *file, char *buf, int n, int *sl)
static void
pdf_parse_cmap_name(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ buf.size = PDF_LEXBUF_SMALL;
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok == PDF_TOK_NAME)
- fz_strlcpy(cmap->cmap_name, buf, sizeof(cmap->cmap_name));
+ fz_strlcpy(cmap->cmap_name, buf.scratch, sizeof(cmap->cmap_name));
else
fz_warn(ctx, "expected name after CMapName in cmap");
}
@@ -80,15 +80,15 @@ pdf_parse_cmap_name(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
static void
pdf_parse_wmode(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ buf.size = PDF_LEXBUF_SMALL;
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok == PDF_TOK_INT)
- pdf_set_wmode(ctx, cmap, atoi(buf));
+ pdf_set_cmap_wmode(ctx, cmap, buf.i);
else
fz_warn(ctx, "expected integer after WMode in cmap");
}
@@ -96,14 +96,14 @@ pdf_parse_wmode(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
static void
pdf_parse_codespace_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
int lo, hi;
+ buf.size = PDF_LEXBUF_SMALL;
while (1)
{
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok == TOK_END_CODESPACE_RANGE)
@@ -111,13 +111,13 @@ pdf_parse_codespace_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
else if (tok == PDF_TOK_STRING)
{
- lo = pdf_code_from_string(buf, len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ lo = pdf_code_from_string(buf.scratch, buf.len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok == PDF_TOK_STRING)
{
- hi = pdf_code_from_string(buf, len);
- pdf_add_codespace(ctx, cmap, lo, hi, len);
+ hi = pdf_code_from_string(buf.scratch, buf.len);
+ pdf_add_codespace(ctx, cmap, lo, hi, buf.len);
}
else break;
}
@@ -131,14 +131,14 @@ pdf_parse_codespace_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
static void
pdf_parse_cid_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
int lo, hi, dst;
+ buf.size = PDF_LEXBUF_SMALL;
while (1)
{
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok == TOK_END_CID_RANGE)
@@ -147,21 +147,21 @@ pdf_parse_cid_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
else if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string or endcidrange");
- lo = pdf_code_from_string(buf, len);
+ lo = pdf_code_from_string(buf.scratch, buf.len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string");
- hi = pdf_code_from_string(buf, len);
+ hi = pdf_code_from_string(buf.scratch, buf.len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: Lost debugging: "syntaxerror in cmap" */
if (tok != PDF_TOK_INT)
fz_throw(ctx, "expected integer");
- dst = atoi(buf);
+ dst = buf.i;
pdf_map_range_to_range(ctx, cmap, lo, hi, dst);
}
@@ -170,14 +170,14 @@ pdf_parse_cid_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
static void
pdf_parse_cid_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
int src, dst;
+ buf.size = PDF_LEXBUF_SMALL;
while (1)
{
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok == TOK_END_CID_CHAR)
@@ -186,15 +186,15 @@ pdf_parse_cid_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
else if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string or endcidchar");
- src = pdf_code_from_string(buf, len);
+ src = pdf_code_from_string(buf.scratch, buf.len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok != PDF_TOK_INT)
fz_throw(ctx, "expected integer");
- dst = atoi(buf);
+ dst = buf.i;
pdf_map_range_to_range(ctx, cmap, src, src, dst);
}
@@ -203,15 +203,15 @@ pdf_parse_cid_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
static void
pdf_parse_bf_range_array(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, int lo, int hi)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
int dst[256];
int i;
+ buf.size = PDF_LEXBUF_SMALL;
while (1)
{
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok == PDF_TOK_CLOSE_ARRAY)
@@ -221,12 +221,12 @@ pdf_parse_bf_range_array(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, int l
else if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string or ]");
- if (len / 2)
+ if (buf.len / 2)
{
- for (i = 0; i < len / 2; i++)
- dst[i] = pdf_code_from_string(buf + i * 2, 2);
+ for (i = 0; i < buf.len / 2; i++)
+ dst[i] = pdf_code_from_string(&buf.scratch[i * 2], 2);
- pdf_map_one_to_many(ctx, cmap, lo, dst, len / 2);
+ pdf_map_one_to_many(ctx, cmap, lo, dst, buf.len / 2);
}
lo ++;
@@ -236,14 +236,14 @@ pdf_parse_bf_range_array(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, int l
static void
pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
int lo, hi, dst;
+ buf.size = PDF_LEXBUF_SMALL;
while (1)
{
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok == TOK_END_BF_RANGE)
@@ -252,23 +252,23 @@ pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
else if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string or endbfrange");
- lo = pdf_code_from_string(buf, len);
+ lo = pdf_code_from_string(buf.scratch, buf.len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string");
- hi = pdf_code_from_string(buf, len);
+ hi = pdf_code_from_string(buf.scratch, buf.len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok == PDF_TOK_STRING)
{
- if (len == 2)
+ if (buf.len == 2)
{
- dst = pdf_code_from_string(buf, len);
+ dst = pdf_code_from_string(buf.scratch, buf.len);
pdf_map_range_to_range(ctx, cmap, lo, hi, dst);
}
else
@@ -276,10 +276,10 @@ pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
int dststr[256];
int i;
- if (len / 2)
+ if (buf.len / 2)
{
- for (i = 0; i < len / 2; i++)
- dststr[i] = pdf_code_from_string(buf + i * 2, 2);
+ for (i = 0; i < buf.len / 2; i++)
+ dststr[i] = pdf_code_from_string(&buf.scratch[i * 2], 2);
while (lo <= hi)
{
@@ -307,16 +307,16 @@ pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
static void
pdf_parse_bf_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
{
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
int dst[256];
int src;
int i;
+ buf.size = PDF_LEXBUF_SMALL;
while (1)
{
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
if (tok == TOK_END_BF_CHAR)
@@ -325,18 +325,18 @@ pdf_parse_bf_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file)
else if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string or endbfchar");
- src = pdf_code_from_string(buf, len);
+ src = pdf_code_from_string(buf.scratch, buf.len);
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
/* RJW: "syntaxerror in cmap" */
/* Note: does not handle /dstName */
if (tok != PDF_TOK_STRING)
fz_throw(ctx, "expected string");
- if (len / 2)
+ if (buf.len / 2)
{
- for (i = 0; i < len / 2; i++)
- dst[i] = pdf_code_from_string(buf + i * 2, 2);
+ for (i = 0; i < buf.len / 2; i++)
+ dst[i] = pdf_code_from_string(&buf.scratch[i * 2], 2);
pdf_map_one_to_many(ctx, cmap, src, dst, i);
}
}
@@ -347,11 +347,11 @@ pdf_load_cmap(fz_context *ctx, fz_stream *file)
{
pdf_cmap *cmap;
char key[64];
- char buf[256];
+ pdf_lexbuf buf;
int tok;
- int len;
const char *where;
+ buf.size = PDF_LEXBUF_SMALL;
cmap = pdf_new_cmap(ctx);
strcpy(key, ".notdef");
@@ -363,25 +363,25 @@ pdf_load_cmap(fz_context *ctx, fz_stream *file)
while (1)
{
where = "";
- tok = pdf_lex_cmap(file, buf, sizeof buf, &len);
+ tok = pdf_lex_cmap(file, &buf);
if (tok == PDF_TOK_EOF || tok == TOK_END_CMAP)
break;
else if (tok == PDF_TOK_NAME)
{
- if (!strcmp(buf, "CMapName"))
+ if (!strcmp(buf.scratch, "CMapName"))
{
where = " after CMapName";
pdf_parse_cmap_name(ctx, cmap, file);
}
- else if (!strcmp(buf, "WMode"))
+ else if (!strcmp(buf.scratch, "WMode"))
{
where = " after WMode";
pdf_parse_wmode(ctx, cmap, file);
}
else
- fz_strlcpy(key, buf, sizeof key);
+ fz_strlcpy(key, buf.scratch, sizeof key);
}
else if (tok == TOK_USECMAP)
diff --git a/pdf/pdf_cmap_table.c b/pdf/pdf_cmap_table.c
index fbe528e0..21dfe5fa 100644
--- a/pdf/pdf_cmap_table.c
+++ b/pdf/pdf_cmap_table.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#ifndef NOCJK
#include "../generated/cmap_cns.h"
diff --git a/pdf/pdf_colorspace.c b/pdf/pdf_colorspace.c
index 7a410df8..ee5bc5fc 100644
--- a/pdf/pdf_colorspace.c
+++ b/pdf/pdf_colorspace.c
@@ -1,14 +1,14 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
/* ICCBased */
static fz_colorspace *
-load_icc_based(pdf_document *xref, fz_obj *dict)
+load_icc_based(pdf_document *xref, pdf_obj *dict)
{
int n;
- n = fz_to_int(fz_dict_gets(dict, "N"));
+ n = pdf_to_int(pdf_dict_gets(dict, "N"));
switch (n)
{
@@ -91,14 +91,14 @@ free_separation(fz_context *ctx, fz_colorspace *cs)
}
static fz_colorspace *
-load_separation(pdf_document *xref, fz_obj *array)
+load_separation(pdf_document *xref, pdf_obj *array)
{
fz_colorspace *cs;
struct separation *sep = NULL;
fz_context *ctx = xref->ctx;
- fz_obj *nameobj = fz_array_get(array, 1);
- fz_obj *baseobj = fz_array_get(array, 2);
- fz_obj *tintobj = fz_array_get(array, 3);
+ pdf_obj *nameobj = pdf_array_get(array, 1);
+ pdf_obj *baseobj = pdf_array_get(array, 2);
+ pdf_obj *tintobj = pdf_array_get(array, 3);
fz_colorspace *base;
pdf_function *tint = NULL;
int n;
@@ -106,8 +106,8 @@ load_separation(pdf_document *xref, fz_obj *array)
fz_var(tint);
fz_var(sep);
- if (fz_is_array(nameobj))
- n = fz_array_len(nameobj);
+ if (pdf_is_array(nameobj))
+ n = pdf_array_len(nameobj);
else
n = 1;
@@ -115,13 +115,13 @@ load_separation(pdf_document *xref, fz_obj *array)
fz_throw(ctx, "too many components in colorspace");
base = pdf_load_colorspace(xref, baseobj);
- /* RJW: "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */
+ /* RJW: "cannot load base colorspace (%d %d R)", pdf_to_num(baseobj), pdf_to_gen(baseobj) */
fz_try(ctx)
{
tint = pdf_load_function(xref, tintobj);
/* RJW: fz_drop_colorspace(ctx, base);
- * "cannot load tint function (%d %d R)", fz_to_num(tintobj), fz_to_gen(tintobj) */
+ * "cannot load tint function (%d %d R)", pdf_to_num(tintobj), pdf_to_gen(tintobj) */
sep = fz_malloc_struct(ctx, struct separation);
sep->base = base;
@@ -193,7 +193,7 @@ pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
lookup = idx->lookup;
n = idx->base->n;
- dst = fz_new_pixmap_with_rect(ctx, idx->base, fz_bound_pixmap(src));
+ dst = fz_new_pixmap_with_bbox(ctx, idx->base, fz_pixmap_bbox(ctx, src));
s = src->samples;
d = dst->samples;
@@ -210,21 +210,19 @@ pdf_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src)
}
}
- if (src->mask)
- dst->mask = fz_keep_pixmap(ctx, src->mask);
dst->interpolate = src->interpolate;
return dst;
}
static fz_colorspace *
-load_indexed(pdf_document *xref, fz_obj *array)
+load_indexed(pdf_document *xref, pdf_obj *array)
{
struct indexed *idx = NULL;
fz_context *ctx = xref->ctx;
- fz_obj *baseobj = fz_array_get(array, 1);
- fz_obj *highobj = fz_array_get(array, 2);
- fz_obj *lookup = fz_array_get(array, 3);
+ pdf_obj *baseobj = pdf_array_get(array, 1);
+ pdf_obj *highobj = pdf_array_get(array, 2);
+ pdf_obj *lookup = pdf_array_get(array, 3);
fz_colorspace *base = NULL;
fz_colorspace *cs = NULL;
int i, n;
@@ -236,12 +234,12 @@ load_indexed(pdf_document *xref, fz_obj *array)
fz_try(ctx)
{
base = pdf_load_colorspace(xref, baseobj);
- /* "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */
+ /* "cannot load base colorspace (%d %d R)", pdf_to_num(baseobj), pdf_to_gen(baseobj) */
idx = fz_malloc_struct(ctx, struct indexed);
idx->lookup = NULL;
idx->base = base;
- idx->high = fz_to_int(highobj);
+ idx->high = pdf_to_int(highobj);
idx->high = CLAMP(idx->high, 0, 255);
n = base->n * (idx->high + 1);
idx->lookup = fz_malloc_array(ctx, 1, n);
@@ -252,30 +250,30 @@ load_indexed(pdf_document *xref, fz_obj *array)
cs->data = idx;
cs->size += sizeof(*idx) + n + (base ? base->size : 0);
- if (fz_is_string(lookup) && fz_to_str_len(lookup) == n)
+ if (pdf_is_string(lookup) && pdf_to_str_len(lookup) == n)
{
- unsigned char *buf = (unsigned char *) fz_to_str_buf(lookup);
+ unsigned char *buf = (unsigned char *) pdf_to_str_buf(lookup);
for (i = 0; i < n; i++)
idx->lookup[i] = buf[i];
}
- else if (fz_is_indirect(lookup))
+ else if (pdf_is_indirect(lookup))
{
fz_stream *file = NULL;
fz_try(ctx)
{
- file = pdf_open_stream(xref, fz_to_num(lookup), fz_to_gen(lookup));
+ file = pdf_open_stream(xref, pdf_to_num(lookup), pdf_to_gen(lookup));
}
fz_catch(ctx)
{
- fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup));
+ fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", pdf_to_num(lookup));
}
i = fz_read(file, idx->lookup, n);
if (i < 0)
{
fz_close(file);
- fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup));
+ fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", pdf_to_num(lookup));
}
fz_close(file);
@@ -304,106 +302,106 @@ load_indexed(pdf_document *xref, fz_obj *array)
/* Parse and create colorspace from PDF object */
static fz_colorspace *
-pdf_load_colorspace_imp(pdf_document *xref, fz_obj *obj)
+pdf_load_colorspace_imp(pdf_document *xref, pdf_obj *obj)
{
- if (fz_is_name(obj))
+ if (pdf_is_name(obj))
{
- if (!strcmp(fz_to_name(obj), "Pattern"))
+ if (!strcmp(pdf_to_name(obj), "Pattern"))
return fz_device_gray;
- else if (!strcmp(fz_to_name(obj), "G"))
+ else if (!strcmp(pdf_to_name(obj), "G"))
return fz_device_gray;
- else if (!strcmp(fz_to_name(obj), "RGB"))
+ else if (!strcmp(pdf_to_name(obj), "RGB"))
return fz_device_rgb;
- else if (!strcmp(fz_to_name(obj), "CMYK"))
+ else if (!strcmp(pdf_to_name(obj), "CMYK"))
return fz_device_cmyk;
- else if (!strcmp(fz_to_name(obj), "DeviceGray"))
+ else if (!strcmp(pdf_to_name(obj), "DeviceGray"))
return fz_device_gray;
- else if (!strcmp(fz_to_name(obj), "DeviceRGB"))
+ else if (!strcmp(pdf_to_name(obj), "DeviceRGB"))
return fz_device_rgb;
- else if (!strcmp(fz_to_name(obj), "DeviceCMYK"))
+ else if (!strcmp(pdf_to_name(obj), "DeviceCMYK"))
return fz_device_cmyk;
else
- fz_throw(xref->ctx, "unknown colorspace: %s", fz_to_name(obj));
+ fz_throw(xref->ctx, "unknown colorspace: %s", pdf_to_name(obj));
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
- fz_obj *name = fz_array_get(obj, 0);
+ pdf_obj *name = pdf_array_get(obj, 0);
- if (fz_is_name(name))
+ if (pdf_is_name(name))
{
/* load base colorspace instead */
- if (!strcmp(fz_to_name(name), "Pattern"))
+ if (!strcmp(pdf_to_name(name), "Pattern"))
{
- obj = fz_array_get(obj, 1);
+ obj = pdf_array_get(obj, 1);
if (!obj)
{
return fz_device_gray;
}
return pdf_load_colorspace(xref, obj);
- /* RJW: "cannot load pattern (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ /* RJW: "cannot load pattern (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
}
- else if (!strcmp(fz_to_name(name), "G"))
+ else if (!strcmp(pdf_to_name(name), "G"))
return fz_device_gray;
- else if (!strcmp(fz_to_name(name), "RGB"))
+ else if (!strcmp(pdf_to_name(name), "RGB"))
return fz_device_rgb;
- else if (!strcmp(fz_to_name(name), "CMYK"))
+ else if (!strcmp(pdf_to_name(name), "CMYK"))
return fz_device_cmyk;
- else if (!strcmp(fz_to_name(name), "DeviceGray"))
+ else if (!strcmp(pdf_to_name(name), "DeviceGray"))
return fz_device_gray;
- else if (!strcmp(fz_to_name(name), "DeviceRGB"))
+ else if (!strcmp(pdf_to_name(name), "DeviceRGB"))
return fz_device_rgb;
- else if (!strcmp(fz_to_name(name), "DeviceCMYK"))
+ else if (!strcmp(pdf_to_name(name), "DeviceCMYK"))
return fz_device_cmyk;
- else if (!strcmp(fz_to_name(name), "CalGray"))
+ else if (!strcmp(pdf_to_name(name), "CalGray"))
return fz_device_gray;
- else if (!strcmp(fz_to_name(name), "CalRGB"))
+ else if (!strcmp(pdf_to_name(name), "CalRGB"))
return fz_device_rgb;
- else if (!strcmp(fz_to_name(name), "CalCMYK"))
+ else if (!strcmp(pdf_to_name(name), "CalCMYK"))
return fz_device_cmyk;
- else if (!strcmp(fz_to_name(name), "Lab"))
+ else if (!strcmp(pdf_to_name(name), "Lab"))
return fz_device_lab;
- else if (!strcmp(fz_to_name(name), "ICCBased"))
- return load_icc_based(xref, fz_array_get(obj, 1));
+ else if (!strcmp(pdf_to_name(name), "ICCBased"))
+ return load_icc_based(xref, pdf_array_get(obj, 1));
- else if (!strcmp(fz_to_name(name), "Indexed"))
+ else if (!strcmp(pdf_to_name(name), "Indexed"))
return load_indexed(xref, obj);
- else if (!strcmp(fz_to_name(name), "I"))
+ else if (!strcmp(pdf_to_name(name), "I"))
return load_indexed(xref, obj);
- else if (!strcmp(fz_to_name(name), "Separation"))
+ else if (!strcmp(pdf_to_name(name), "Separation"))
return load_separation(xref, obj);
- else if (!strcmp(fz_to_name(name), "DeviceN"))
+ else if (!strcmp(pdf_to_name(name), "DeviceN"))
return load_separation(xref, obj);
else
- fz_throw(xref->ctx, "syntaxerror: unknown colorspace %s", fz_to_name(name));
+ fz_throw(xref->ctx, "syntaxerror: unknown colorspace %s", pdf_to_name(name));
}
}
- fz_throw(xref->ctx, "syntaxerror: could not parse color space (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ fz_throw(xref->ctx, "syntaxerror: could not parse color space (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
return NULL; /* Stupid MSVC */
}
fz_colorspace *
-pdf_load_colorspace(pdf_document *xref, fz_obj *obj)
+pdf_load_colorspace(pdf_document *xref, pdf_obj *obj)
{
fz_context *ctx = xref->ctx;
fz_colorspace *cs;
- if ((cs = fz_find_item(ctx, fz_free_colorspace_imp, obj)))
+ if ((cs = pdf_find_item(ctx, fz_free_colorspace_imp, obj)))
{
return cs;
}
cs = pdf_load_colorspace_imp(xref, obj);
- /* RJW: "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ /* RJW: "cannot load colorspace (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
- fz_store_item(ctx, obj, cs, cs->size);
+ pdf_store_item(ctx, obj, cs, cs->size);
return cs;
}
diff --git a/pdf/pdf_crypt.c b/pdf/pdf_crypt.c
index 59423a38..b65786d9 100644
--- a/pdf/pdf_crypt.c
+++ b/pdf/pdf_crypt.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
enum
{
@@ -20,11 +20,11 @@ struct pdf_crypt_filter_s
struct pdf_crypt_s
{
- fz_obj *id;
+ pdf_obj *id;
int v;
int length;
- fz_obj *cf;
+ pdf_obj *cf;
pdf_crypt_filter stmf;
pdf_crypt_filter strf;
@@ -40,7 +40,7 @@ struct pdf_crypt_s
fz_context *ctx;
};
-static void pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, fz_obj *dict, char *name, int defaultlength);
+static void pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, pdf_obj *dict, char *name, int defaultlength);
/*
* Create crypt object for decrypting strings and streams
@@ -48,31 +48,31 @@ static void pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, fz_obj
*/
pdf_crypt *
-pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
+pdf_new_crypt(fz_context *ctx, pdf_obj *dict, pdf_obj *id)
{
pdf_crypt *crypt;
- fz_obj *obj;
+ pdf_obj *obj;
crypt = fz_malloc_struct(ctx, pdf_crypt);
/* Common to all security handlers (PDF 1.7 table 3.18) */
- obj = fz_dict_gets(dict, "Filter");
- if (!fz_is_name(obj))
+ obj = pdf_dict_gets(dict, "Filter");
+ if (!pdf_is_name(obj))
{
pdf_free_crypt(ctx, crypt);
fz_throw(ctx, "unspecified encryption handler");
}
- if (strcmp(fz_to_name(obj), "Standard") != 0)
+ if (strcmp(pdf_to_name(obj), "Standard") != 0)
{
pdf_free_crypt(ctx, crypt);
- fz_throw(ctx, "unknown encryption handler: '%s'", fz_to_name(obj));
+ fz_throw(ctx, "unknown encryption handler: '%s'", pdf_to_name(obj));
}
crypt->v = 0;
- obj = fz_dict_gets(dict, "V");
- if (fz_is_int(obj))
- crypt->v = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "V");
+ if (pdf_is_int(obj))
+ crypt->v = pdf_to_int(obj);
if (crypt->v != 1 && crypt->v != 2 && crypt->v != 4 && crypt->v != 5)
{
pdf_free_crypt(ctx, crypt);
@@ -82,9 +82,9 @@ pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
crypt->length = 40;
if (crypt->v == 2 || crypt->v == 4)
{
- obj = fz_dict_gets(dict, "Length");
- if (fz_is_int(obj))
- crypt->length = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "Length");
+ if (pdf_is_int(obj))
+ crypt->length = pdf_to_int(obj);
/* work-around for pdf generators that assume length is in bytes */
if (crypt->length < 40)
@@ -122,10 +122,10 @@ pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
crypt->strf.method = PDF_CRYPT_NONE;
crypt->strf.length = crypt->length;
- obj = fz_dict_gets(dict, "CF");
- if (fz_is_dict(obj))
+ obj = pdf_dict_gets(dict, "CF");
+ if (pdf_is_dict(obj))
{
- crypt->cf = fz_keep_obj(obj);
+ crypt->cf = pdf_keep_obj(obj);
}
else
{
@@ -134,18 +134,18 @@ pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
fz_try(ctx)
{
- obj = fz_dict_gets(dict, "StmF");
- if (fz_is_name(obj))
- pdf_parse_crypt_filter(ctx, &crypt->stmf, crypt->cf, fz_to_name(obj), crypt->length);
+ obj = pdf_dict_gets(dict, "StmF");
+ if (pdf_is_name(obj))
+ pdf_parse_crypt_filter(ctx, &crypt->stmf, crypt->cf, pdf_to_name(obj), crypt->length);
- obj = fz_dict_gets(dict, "StrF");
- if (fz_is_name(obj))
- pdf_parse_crypt_filter(ctx, &crypt->strf, crypt->cf, fz_to_name(obj), crypt->length);
+ obj = pdf_dict_gets(dict, "StrF");
+ if (pdf_is_name(obj))
+ pdf_parse_crypt_filter(ctx, &crypt->strf, crypt->cf, pdf_to_name(obj), crypt->length);
}
fz_catch(ctx)
{
pdf_free_crypt(ctx, crypt);
- fz_throw(ctx, "cannot parse string crypt filter (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ fz_throw(ctx, "cannot parse string crypt filter (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
}
/* in crypt revision 4, the crypt filter determines the key length */
@@ -155,36 +155,46 @@ pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
/* Standard security handler (PDF 1.7 table 3.19) */
- obj = fz_dict_gets(dict, "R");
- if (fz_is_int(obj))
- crypt->r = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "R");
+ if (pdf_is_int(obj))
+ crypt->r = pdf_to_int(obj);
+ else if (crypt->v <= 4)
+ {
+ fz_warn(ctx, "encryption dictionary missing revision value, guessing...");
+ if (crypt->v < 2)
+ crypt->r = 2;
+ else if (crypt->v == 2 || crypt->v == 3)
+ crypt->r = 3;
+ else if (crypt->v == 4)
+ crypt->r = 4;
+ }
else
{
pdf_free_crypt(ctx, crypt);
- fz_throw(ctx, "encryption dictionary missing revision value");
+ fz_throw(ctx, "encryption dictionary missing version and revision value");
}
- obj = fz_dict_gets(dict, "O");
- if (fz_is_string(obj) && fz_to_str_len(obj) == 32)
- memcpy(crypt->o, fz_to_str_buf(obj), 32);
+ obj = pdf_dict_gets(dict, "O");
+ if (pdf_is_string(obj) && pdf_to_str_len(obj) == 32)
+ memcpy(crypt->o, pdf_to_str_buf(obj), 32);
/* /O and /U are supposed to be 48 bytes long for revision 5, they're often longer, though */
- else if (crypt->r == 5 && fz_is_string(obj) && fz_to_str_len(obj) >= 48)
- memcpy(crypt->o, fz_to_str_buf(obj), 48);
+ else if (crypt->r == 5 && pdf_is_string(obj) && pdf_to_str_len(obj) >= 48)
+ memcpy(crypt->o, pdf_to_str_buf(obj), 48);
else
{
pdf_free_crypt(ctx, crypt);
fz_throw(ctx, "encryption dictionary missing owner password");
}
- obj = fz_dict_gets(dict, "U");
- if (fz_is_string(obj) && fz_to_str_len(obj) == 32)
- memcpy(crypt->u, fz_to_str_buf(obj), 32);
- else if (fz_is_string(obj) && fz_to_str_len(obj) >= 48 && crypt->r == 5)
- memcpy(crypt->u, fz_to_str_buf(obj), 48);
- else if (fz_is_string(obj) && fz_to_str_len(obj) < 32)
+ obj = pdf_dict_gets(dict, "U");
+ if (pdf_is_string(obj) && pdf_to_str_len(obj) == 32)
+ memcpy(crypt->u, pdf_to_str_buf(obj), 32);
+ else if (pdf_is_string(obj) && pdf_to_str_len(obj) >= 48 && crypt->r == 5)
+ memcpy(crypt->u, pdf_to_str_buf(obj), 48);
+ else if (pdf_is_string(obj) && pdf_to_str_len(obj) < 32)
{
- fz_warn(ctx, "encryption password key too short (%d)", fz_to_str_len(obj));
- memcpy(crypt->u, fz_to_str_buf(obj), fz_to_str_len(obj));
+ fz_warn(ctx, "encryption password key too short (%d)", pdf_to_str_len(obj));
+ memcpy(crypt->u, pdf_to_str_buf(obj), pdf_to_str_len(obj));
}
else
{
@@ -192,46 +202,46 @@ pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
fz_throw(ctx, "encryption dictionary missing user password");
}
- obj = fz_dict_gets(dict, "P");
- if (fz_is_int(obj))
- crypt->p = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "P");
+ if (pdf_is_int(obj))
+ crypt->p = pdf_to_int(obj);
else
{
- pdf_free_crypt(ctx, crypt);
- fz_throw(ctx, "encryption dictionary missing permissions value");
+ fz_warn(ctx, "encryption dictionary missing permissions");
+ crypt->p = 0xfffffffc;
}
if (crypt->r == 5)
{
- obj = fz_dict_gets(dict, "OE");
- if (!fz_is_string(obj) || fz_to_str_len(obj) != 32)
+ obj = pdf_dict_gets(dict, "OE");
+ if (!pdf_is_string(obj) || pdf_to_str_len(obj) != 32)
{
pdf_free_crypt(ctx, crypt);
fz_throw(ctx, "encryption dictionary missing owner encryption key");
}
- memcpy(crypt->oe, fz_to_str_buf(obj), 32);
+ memcpy(crypt->oe, pdf_to_str_buf(obj), 32);
- obj = fz_dict_gets(dict, "UE");
- if (!fz_is_string(obj) || fz_to_str_len(obj) != 32)
+ obj = pdf_dict_gets(dict, "UE");
+ if (!pdf_is_string(obj) || pdf_to_str_len(obj) != 32)
{
pdf_free_crypt(ctx, crypt);
fz_throw(ctx, "encryption dictionary missing user encryption key");
}
- memcpy(crypt->ue, fz_to_str_buf(obj), 32);
+ memcpy(crypt->ue, pdf_to_str_buf(obj), 32);
}
crypt->encrypt_metadata = 1;
- obj = fz_dict_gets(dict, "EncryptMetadata");
- if (fz_is_bool(obj))
- crypt->encrypt_metadata = fz_to_bool(obj);
+ obj = pdf_dict_gets(dict, "EncryptMetadata");
+ if (pdf_is_bool(obj))
+ crypt->encrypt_metadata = pdf_to_bool(obj);
/* Extract file identifier string */
- if (fz_is_array(id) && fz_array_len(id) == 2)
+ if (pdf_is_array(id) && pdf_array_len(id) == 2)
{
- obj = fz_array_get(id, 0);
- if (fz_is_string(obj))
- crypt->id = fz_keep_obj(obj);
+ obj = pdf_array_get(id, 0);
+ if (pdf_is_string(obj))
+ crypt->id = pdf_keep_obj(obj);
}
else
fz_warn(ctx, "missing file identifier, may not be able to do decryption");
@@ -242,8 +252,8 @@ pdf_new_crypt(fz_context *ctx, fz_obj *dict, fz_obj *id)
void
pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt)
{
- if (crypt->id) fz_drop_obj(crypt->id);
- if (crypt->cf) fz_drop_obj(crypt->cf);
+ if (crypt->id) pdf_drop_obj(crypt->id);
+ if (crypt->cf) pdf_drop_obj(crypt->cf);
fz_free(ctx, crypt);
}
@@ -252,15 +262,15 @@ pdf_free_crypt(fz_context *ctx, pdf_crypt *crypt)
*/
static void
-pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, fz_obj *cf_obj, char *name, int defaultlength)
+pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, pdf_obj *cf_obj, char *name, int defaultlength)
{
- fz_obj *obj;
- fz_obj *dict;
+ pdf_obj *obj;
+ pdf_obj *dict;
int is_identity = (strcmp(name, "Identity") == 0);
int is_stdcf = (!is_identity && (strcmp(name, "StdCF") == 0));
if (!is_identity && !is_stdcf)
- fz_throw(ctx, "Crypt Filter not Identity or StdCF (%d %d R)", fz_to_num(cf_obj), fz_to_gen(cf_obj));
+ fz_throw(ctx, "Crypt Filter not Identity or StdCF (%d %d R)", pdf_to_num(cf_obj), pdf_to_gen(cf_obj));
cf->method = PDF_CRYPT_NONE;
cf->length = defaultlength;
@@ -271,28 +281,28 @@ pdf_parse_crypt_filter(fz_context *ctx, pdf_crypt_filter *cf, fz_obj *cf_obj, ch
return;
}
- dict = fz_dict_gets(cf_obj, name);
- if (!fz_is_dict(dict))
- fz_throw(ctx, "cannot parse crypt filter (%d %d R)", fz_to_num(cf_obj), fz_to_gen(cf_obj));
+ dict = pdf_dict_gets(cf_obj, name);
+ if (!pdf_is_dict(dict))
+ fz_throw(ctx, "cannot parse crypt filter (%d %d R)", pdf_to_num(cf_obj), pdf_to_gen(cf_obj));
- obj = fz_dict_gets(dict, "CFM");
- if (fz_is_name(obj))
+ obj = pdf_dict_gets(dict, "CFM");
+ if (pdf_is_name(obj))
{
- if (!strcmp(fz_to_name(obj), "None"))
+ if (!strcmp(pdf_to_name(obj), "None"))
cf->method = PDF_CRYPT_NONE;
- else if (!strcmp(fz_to_name(obj), "V2"))
+ else if (!strcmp(pdf_to_name(obj), "V2"))
cf->method = PDF_CRYPT_RC4;
- else if (!strcmp(fz_to_name(obj), "AESV2"))
+ else if (!strcmp(pdf_to_name(obj), "AESV2"))
cf->method = PDF_CRYPT_AESV2;
- else if (!strcmp(fz_to_name(obj), "AESV3"))
+ else if (!strcmp(pdf_to_name(obj), "AESV3"))
cf->method = PDF_CRYPT_AESV3;
else
- fz_warn(ctx, "unknown encryption method: %s", fz_to_name(obj));
+ fz_warn(ctx, "unknown encryption method: %s", pdf_to_name(obj));
}
- obj = fz_dict_gets(dict, "Length");
- if (fz_is_int(obj))
- cf->length = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "Length");
+ if (pdf_is_int(obj))
+ cf->length = pdf_to_int(obj);
/* the length for crypt filters is supposed to be in bytes not bits */
if (cf->length < 40)
@@ -346,7 +356,7 @@ pdf_compute_encryption_key(pdf_crypt *crypt, unsigned char *password, int pwlen,
fz_md5_update(&md5, buf, 4);
/* Step 5 - pass first element of ID array */
- fz_md5_update(&md5, (unsigned char *)fz_to_str_buf(crypt->id), fz_to_str_len(crypt->id));
+ fz_md5_update(&md5, (unsigned char *)pdf_to_str_buf(crypt->id), pdf_to_str_len(crypt->id));
/* Step 6 (revision 4 or greater) - if metadata is not encrypted pass 0xFFFFFFFF */
if (crypt->r >= 4)
@@ -455,7 +465,7 @@ pdf_compute_user_password(pdf_crypt *crypt, unsigned char *password, int pwlen,
fz_md5_init(&md5);
fz_md5_update(&md5, padding, 32);
- fz_md5_update(&md5, (unsigned char*)fz_to_str_buf(crypt->id), fz_to_str_len(crypt->id));
+ fz_md5_update(&md5, (unsigned char*)pdf_to_str_buf(crypt->id), pdf_to_str_len(crypt->id));
fz_md5_final(&md5, digest);
fz_arc4_init(&arc4, crypt->key, n);
@@ -608,7 +618,7 @@ pdf_has_permission(pdf_document *xref, int p)
}
unsigned char *
-pdf_get_crypt_key(pdf_document *xref)
+pdf_crypt_key(pdf_document *xref)
{
if (xref->crypt)
return xref->crypt->key;
@@ -616,7 +626,7 @@ pdf_get_crypt_key(pdf_document *xref)
}
int
-pdf_get_crypt_revision(pdf_document *xref)
+pdf_crypt_revision(pdf_document *xref)
{
if (xref->crypt)
return xref->crypt->v;
@@ -624,7 +634,7 @@ pdf_get_crypt_revision(pdf_document *xref)
}
char *
-pdf_get_crypt_method(pdf_document *xref)
+pdf_crypt_method(pdf_document *xref)
{
if (xref->crypt)
{
@@ -641,7 +651,7 @@ pdf_get_crypt_method(pdf_document *xref)
}
int
-pdf_get_crypt_length(pdf_document *xref)
+pdf_crypt_length(pdf_document *xref)
{
if (xref->crypt)
return xref->crypt->length;
@@ -697,18 +707,18 @@ pdf_compute_object_key(pdf_crypt *crypt, pdf_crypt_filter *cf, int num, int gen,
*/
static void
-pdf_crypt_obj_imp(fz_context *ctx, pdf_crypt *crypt, fz_obj *obj, unsigned char *key, int keylen)
+pdf_crypt_obj_imp(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, unsigned char *key, int keylen)
{
unsigned char *s;
int i, n;
- if (fz_is_indirect(obj))
+ if (pdf_is_indirect(obj))
return;
- if (fz_is_string(obj))
+ if (pdf_is_string(obj))
{
- s = (unsigned char *)fz_to_str_buf(obj);
- n = fz_to_str_len(obj);
+ s = (unsigned char *)pdf_to_str_buf(obj);
+ n = pdf_to_str_len(obj);
if (crypt->strf.method == PDF_CRYPT_RC4)
{
@@ -736,32 +746,32 @@ pdf_crypt_obj_imp(fz_context *ctx, pdf_crypt *crypt, fz_obj *obj, unsigned char
if (s[n - 17] < 1 || s[n - 17] > 16)
fz_warn(ctx, "aes padding out of range");
else
- fz_set_str_len(obj, n - 16 - s[n - 17]);
+ pdf_set_str_len(obj, n - 16 - s[n - 17]);
}
}
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
- n = fz_array_len(obj);
+ n = pdf_array_len(obj);
for (i = 0; i < n; i++)
{
- pdf_crypt_obj_imp(ctx, crypt, fz_array_get(obj, i), key, keylen);
+ pdf_crypt_obj_imp(ctx, crypt, pdf_array_get(obj, i), key, keylen);
}
}
- else if (fz_is_dict(obj))
+ else if (pdf_is_dict(obj))
{
- n = fz_dict_len(obj);
+ n = pdf_dict_len(obj);
for (i = 0; i < n; i++)
{
- pdf_crypt_obj_imp(ctx, crypt, fz_dict_get_val(obj, i), key, keylen);
+ pdf_crypt_obj_imp(ctx, crypt, pdf_dict_get_val(obj, i), key, keylen);
}
}
}
void
-pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, fz_obj *obj, int num, int gen)
+pdf_crypt_obj(fz_context *ctx, pdf_crypt *crypt, pdf_obj *obj, int num, int gen)
{
unsigned char key[32];
int len;
@@ -812,7 +822,7 @@ pdf_open_crypt_with_filter(fz_stream *chain, pdf_crypt *crypt, char *name, int n
return chain;
}
-void pdf_debug_crypt(pdf_crypt *crypt)
+void pdf_print_crypt(pdf_crypt *crypt)
{
int i;
diff --git a/pdf/pdf_encoding.c b/pdf/pdf_encoding.c
index 9a42a1c1..eb36ed96 100644
--- a/pdf/pdf_encoding.c
+++ b/pdf/pdf_encoding.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#include "data_encodings.h"
#include "data_glyphlist.h"
diff --git a/pdf/pdf_font.c b/pdf/pdf_font.c
index 3e30c332..ab60af72 100644
--- a/pdf/pdf_font.c
+++ b/pdf/pdf_font.c
@@ -1,11 +1,11 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_XFREE86_H
-static void pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, fz_obj *dict, char *collection, char *basefont);
+static void pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, pdf_obj *dict, char *collection, char *basefont);
static char *base_font_names[14][7] =
{
@@ -178,7 +178,7 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname)
unsigned char *data;
unsigned int len;
- data = pdf_find_builtin_font(fontname, &len);
+ data = pdf_lookup_builtin_font(fontname, &len);
if (!data)
fz_throw(ctx, "cannot find builtin font: '%s'", fontname);
@@ -195,7 +195,7 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, int mono, int
unsigned char *data;
unsigned int len;
- data = pdf_find_substitute_font(mono, serif, bold, italic, &len);
+ data = pdf_lookup_substitute_font(mono, serif, bold, italic, &len);
if (!data)
fz_throw(ctx, "cannot find substitute font");
@@ -213,7 +213,7 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, int ros,
unsigned char *data;
unsigned int len;
- data = pdf_find_substitute_cjk_font(ros, serif, &len);
+ data = pdf_lookup_substitute_cjk_font(ros, serif, &len);
if (!data)
fz_throw(ctx, "cannot find builtin CJK font");
@@ -268,18 +268,18 @@ pdf_load_system_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, c
}
static void
-pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_document *xref, fz_obj *stmref)
+pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_document *xref, pdf_obj *stmref)
{
fz_buffer *buf;
fz_context *ctx = xref->ctx;
fz_try(ctx)
{
- buf = pdf_load_stream(xref, fz_to_num(stmref), fz_to_gen(stmref));
+ buf = pdf_load_stream(xref, pdf_to_num(stmref), pdf_to_gen(stmref));
}
fz_catch(ctx)
{
- fz_throw(ctx, "cannot load font stream (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref));
+ fz_throw(ctx, "cannot load font stream (%d %d R)", pdf_to_num(stmref), pdf_to_gen(stmref));
}
fz_try(ctx)
@@ -289,7 +289,7 @@ pdf_load_embedded_font(pdf_font_desc *fontdesc, pdf_document *xref, fz_obj *stmr
fz_catch(ctx)
{
fz_drop_buffer(ctx, buf);
- fz_throw(ctx, "cannot load embedded font (%d %d R)", fz_to_num(stmref), fz_to_gen(stmref));
+ fz_throw(ctx, "cannot load embedded font (%d %d R)", pdf_to_num(stmref), pdf_to_gen(stmref));
}
fontdesc->size += buf->len;
@@ -394,11 +394,11 @@ pdf_new_font_desc(fz_context *ctx)
*/
static pdf_font_desc *
-pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
+pdf_load_simple_font(pdf_document *xref, pdf_obj *dict)
{
- fz_obj *descriptor;
- fz_obj *encoding;
- fz_obj *widths;
+ pdf_obj *descriptor;
+ pdf_obj *encoding;
+ pdf_obj *widths;
unsigned short *etable = NULL;
pdf_font_desc *fontdesc = NULL;
FT_Face face;
@@ -417,7 +417,7 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
fz_var(fontdesc);
fz_var(etable);
- basefont = fz_to_name(fz_dict_gets(dict, "BaseFont"));
+ basefont = pdf_to_name(pdf_dict_gets(dict, "BaseFont"));
fontname = clean_font_name(basefont);
/* Load font file */
@@ -425,7 +425,7 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
{
fontdesc = pdf_new_font_desc(ctx);
- descriptor = fz_dict_gets(dict, "FontDescriptor");
+ descriptor = pdf_dict_gets(dict, "FontDescriptor");
if (descriptor)
pdf_load_font_descriptor(fontdesc, xref, descriptor, NULL, basefont);
else
@@ -433,9 +433,9 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
/* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */
if (!*fontdesc->font->name &&
- !fz_dict_gets(dict, "ToUnicode") &&
- !strcmp(fz_to_name(fz_dict_gets(dict, "Encoding")), "WinAnsiEncoding") &&
- fz_to_int(fz_dict_gets(descriptor, "Flags")) == 4)
+ !pdf_dict_gets(dict, "ToUnicode") &&
+ !strcmp(pdf_to_name(pdf_dict_gets(dict, "Encoding")), "WinAnsiEncoding") &&
+ pdf_to_int(pdf_dict_gets(descriptor, "Flags")) == 4)
{
/* note: without the comma, pdf_load_font_descriptor would prefer /FontName over /BaseFont */
char *cp936fonts[] = {
@@ -514,34 +514,34 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
etable[i] = 0;
}
- encoding = fz_dict_gets(dict, "Encoding");
+ encoding = pdf_dict_gets(dict, "Encoding");
if (encoding)
{
- if (fz_is_name(encoding))
- pdf_load_encoding(estrings, fz_to_name(encoding));
+ if (pdf_is_name(encoding))
+ pdf_load_encoding(estrings, pdf_to_name(encoding));
- if (fz_is_dict(encoding))
+ if (pdf_is_dict(encoding))
{
- fz_obj *base, *diff, *item;
+ pdf_obj *base, *diff, *item;
- base = fz_dict_gets(encoding, "BaseEncoding");
- if (fz_is_name(base))
- pdf_load_encoding(estrings, fz_to_name(base));
+ base = pdf_dict_gets(encoding, "BaseEncoding");
+ if (pdf_is_name(base))
+ pdf_load_encoding(estrings, pdf_to_name(base));
else if (!fontdesc->is_embedded && !symbolic)
pdf_load_encoding(estrings, "StandardEncoding");
- diff = fz_dict_gets(encoding, "Differences");
- if (fz_is_array(diff))
+ diff = pdf_dict_gets(encoding, "Differences");
+ if (pdf_is_array(diff))
{
- n = fz_array_len(diff);
+ n = pdf_array_len(diff);
k = 0;
for (i = 0; i < n; i++)
{
- item = fz_array_get(diff, i);
- if (fz_is_int(item))
- k = fz_to_int(item);
- if (fz_is_name(item))
- estrings[k++] = fz_to_name(item);
+ item = pdf_array_get(diff, i);
+ if (pdf_is_int(item))
+ k = pdf_to_int(item);
+ if (pdf_is_name(item))
+ estrings[k++] = pdf_to_name(item);
if (k < 0) k = 0;
if (k > 255) k = 255;
}
@@ -654,7 +654,7 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
fontdesc->cid_to_gid_len = 256;
fontdesc->cid_to_gid = etable;
- pdf_load_to_unicode(xref, fontdesc, estrings, NULL, fz_dict_gets(dict, "ToUnicode"));
+ pdf_load_to_unicode(xref, fontdesc, estrings, NULL, pdf_dict_gets(dict, "ToUnicode"));
/* RJW: "cannot load to_unicode" */
skip_encoding:
@@ -663,20 +663,20 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
pdf_set_default_hmtx(ctx, fontdesc, fontdesc->missing_width);
- widths = fz_dict_gets(dict, "Widths");
+ widths = pdf_dict_gets(dict, "Widths");
if (widths)
{
int first, last;
- first = fz_to_int(fz_dict_gets(dict, "FirstChar"));
- last = fz_to_int(fz_dict_gets(dict, "LastChar"));
+ first = pdf_to_int(pdf_dict_gets(dict, "FirstChar"));
+ last = pdf_to_int(pdf_dict_gets(dict, "LastChar"));
if (first < 0 || last > 255 || first > last)
first = last = 0;
for (i = 0; i < last - first + 1; i++)
{
- int wid = fz_to_int(fz_array_get(widths, i));
+ int wid = pdf_to_int(pdf_array_get(widths, i));
pdf_add_hmtx(ctx, fontdesc, i + first, i + first, wid);
}
}
@@ -700,7 +700,7 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
if (fontdesc && etable != fontdesc->cid_to_gid)
fz_free(ctx, etable);
pdf_drop_font(ctx, fontdesc);
- fz_throw(ctx, "cannot load simple font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "cannot load simple font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
}
return fontdesc;
}
@@ -710,17 +710,17 @@ pdf_load_simple_font(pdf_document *xref, fz_obj *dict)
*/
static pdf_font_desc *
-load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_unicode)
+load_cid_font(pdf_document *xref, pdf_obj *dict, pdf_obj *encoding, pdf_obj *to_unicode)
{
- fz_obj *widths;
- fz_obj *descriptor;
+ pdf_obj *widths;
+ pdf_obj *descriptor;
pdf_font_desc *fontdesc;
FT_Face face;
int kind;
char collection[256];
char *basefont;
int i, k, fterr;
- fz_obj *obj;
+ pdf_obj *obj;
int dw;
fz_context *ctx = xref->ctx;
@@ -730,28 +730,28 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
{
/* Get font name and CID collection */
- basefont = fz_to_name(fz_dict_gets(dict, "BaseFont"));
+ basefont = pdf_to_name(pdf_dict_gets(dict, "BaseFont"));
{
- fz_obj *cidinfo;
+ pdf_obj *cidinfo;
char tmpstr[64];
int tmplen;
- cidinfo = fz_dict_gets(dict, "CIDSystemInfo");
+ cidinfo = pdf_dict_gets(dict, "CIDSystemInfo");
if (!cidinfo)
fz_throw(ctx, "cid font is missing info");
- obj = fz_dict_gets(cidinfo, "Registry");
- tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj));
- memcpy(tmpstr, fz_to_str_buf(obj), tmplen);
+ obj = pdf_dict_gets(cidinfo, "Registry");
+ tmplen = MIN(sizeof tmpstr - 1, pdf_to_str_len(obj));
+ memcpy(tmpstr, pdf_to_str_buf(obj), tmplen);
tmpstr[tmplen] = '\0';
fz_strlcpy(collection, tmpstr, sizeof collection);
fz_strlcat(collection, "-", sizeof collection);
- obj = fz_dict_gets(cidinfo, "Ordering");
- tmplen = MIN(sizeof tmpstr - 1, fz_to_str_len(obj));
- memcpy(tmpstr, fz_to_str_buf(obj), tmplen);
+ obj = pdf_dict_gets(cidinfo, "Ordering");
+ tmplen = MIN(sizeof tmpstr - 1, pdf_to_str_len(obj));
+ memcpy(tmpstr, pdf_to_str_buf(obj), tmplen);
tmpstr[tmplen] = '\0';
fz_strlcat(collection, tmpstr, sizeof collection);
}
@@ -760,7 +760,7 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
fontdesc = pdf_new_font_desc(ctx);
- descriptor = fz_dict_gets(dict, "FontDescriptor");
+ descriptor = pdf_dict_gets(dict, "FontDescriptor");
if (!descriptor)
fz_throw(ctx, "syntaxerror: missing font descriptor");
pdf_load_font_descriptor(fontdesc, xref, descriptor, collection, basefont);
@@ -770,16 +770,16 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
/* Encoding */
- if (fz_is_name(encoding))
+ if (pdf_is_name(encoding))
{
- if (!strcmp(fz_to_name(encoding), "Identity-H"))
+ if (!strcmp(pdf_to_name(encoding), "Identity-H"))
fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 2);
- else if (!strcmp(fz_to_name(encoding), "Identity-V"))
+ else if (!strcmp(pdf_to_name(encoding), "Identity-V"))
fontdesc->encoding = pdf_new_identity_cmap(ctx, 1, 2);
else
- fontdesc->encoding = pdf_load_system_cmap(ctx, fz_to_name(encoding));
+ fontdesc->encoding = pdf_load_system_cmap(ctx, pdf_to_name(encoding));
}
- else if (fz_is_indirect(encoding))
+ else if (pdf_is_indirect(encoding))
{
fontdesc->encoding = pdf_load_embedded_cmap(xref, encoding);
}
@@ -789,18 +789,18 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
}
fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);
- pdf_set_font_wmode(ctx, fontdesc, pdf_get_wmode(ctx, fontdesc->encoding));
+ pdf_set_font_wmode(ctx, fontdesc, pdf_cmap_wmode(ctx, fontdesc->encoding));
if (kind == TRUETYPE)
{
- fz_obj *cidtogidmap;
+ pdf_obj *cidtogidmap;
- cidtogidmap = fz_dict_gets(dict, "CIDToGIDMap");
- if (fz_is_indirect(cidtogidmap))
+ cidtogidmap = pdf_dict_gets(dict, "CIDToGIDMap");
+ if (pdf_is_indirect(cidtogidmap))
{
fz_buffer *buf;
- buf = pdf_load_stream(xref, fz_to_num(cidtogidmap), fz_to_gen(cidtogidmap));
+ buf = pdf_load_stream(xref, pdf_to_num(cidtogidmap), pdf_to_gen(cidtogidmap));
fontdesc->cid_to_gid_len = (buf->len) / 2;
fontdesc->cid_to_gid = fz_malloc_array(ctx, fontdesc->cid_to_gid_len, sizeof(unsigned short));
@@ -842,35 +842,35 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
/* Horizontal */
dw = 1000;
- obj = fz_dict_gets(dict, "DW");
+ obj = pdf_dict_gets(dict, "DW");
if (obj)
- dw = fz_to_int(obj);
+ dw = pdf_to_int(obj);
pdf_set_default_hmtx(ctx, fontdesc, dw);
- widths = fz_dict_gets(dict, "W");
+ widths = pdf_dict_gets(dict, "W");
if (widths)
{
int c0, c1, w, n, m;
- n = fz_array_len(widths);
+ n = pdf_array_len(widths);
for (i = 0; i < n; )
{
- c0 = fz_to_int(fz_array_get(widths, i));
- obj = fz_array_get(widths, i + 1);
- if (fz_is_array(obj))
+ c0 = pdf_to_int(pdf_array_get(widths, i));
+ obj = pdf_array_get(widths, i + 1);
+ if (pdf_is_array(obj))
{
- m = fz_array_len(obj);
+ m = pdf_array_len(obj);
for (k = 0; k < m; k++)
{
- w = fz_to_int(fz_array_get(obj, k));
+ w = pdf_to_int(pdf_array_get(obj, k));
pdf_add_hmtx(ctx, fontdesc, c0 + k, c0 + k, w);
}
i += 2;
}
else
{
- c1 = fz_to_int(obj);
- w = fz_to_int(fz_array_get(widths, i + 2));
+ c1 = pdf_to_int(obj);
+ w = pdf_to_int(pdf_array_get(widths, i + 2));
pdf_add_hmtx(ctx, fontdesc, c0, c1, w);
i += 3;
}
@@ -881,48 +881,48 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
/* Vertical */
- if (pdf_get_wmode(ctx, fontdesc->encoding) == 1)
+ if (pdf_cmap_wmode(ctx, fontdesc->encoding) == 1)
{
int dw2y = 880;
int dw2w = -1000;
- obj = fz_dict_gets(dict, "DW2");
+ obj = pdf_dict_gets(dict, "DW2");
if (obj)
{
- dw2y = fz_to_int(fz_array_get(obj, 0));
- dw2w = fz_to_int(fz_array_get(obj, 1));
+ dw2y = pdf_to_int(pdf_array_get(obj, 0));
+ dw2w = pdf_to_int(pdf_array_get(obj, 1));
}
pdf_set_default_vmtx(ctx, fontdesc, dw2y, dw2w);
- widths = fz_dict_gets(dict, "W2");
+ widths = pdf_dict_gets(dict, "W2");
if (widths)
{
int c0, c1, w, x, y, n;
- n = fz_array_len(widths);
+ n = pdf_array_len(widths);
for (i = 0; i < n; )
{
- c0 = fz_to_int(fz_array_get(widths, i));
- obj = fz_array_get(widths, i + 1);
- if (fz_is_array(obj))
+ c0 = pdf_to_int(pdf_array_get(widths, i));
+ obj = pdf_array_get(widths, i + 1);
+ if (pdf_is_array(obj))
{
- int m = fz_array_len(obj);
+ int m = pdf_array_len(obj);
for (k = 0; k * 3 < m; k ++)
{
- w = fz_to_int(fz_array_get(obj, k * 3 + 0));
- x = fz_to_int(fz_array_get(obj, k * 3 + 1));
- y = fz_to_int(fz_array_get(obj, k * 3 + 2));
+ w = pdf_to_int(pdf_array_get(obj, k * 3 + 0));
+ x = pdf_to_int(pdf_array_get(obj, k * 3 + 1));
+ y = pdf_to_int(pdf_array_get(obj, k * 3 + 2));
pdf_add_vmtx(ctx, fontdesc, c0 + k, c0 + k, x, y, w);
}
i += 2;
}
else
{
- c1 = fz_to_int(obj);
- w = fz_to_int(fz_array_get(widths, i + 2));
- x = fz_to_int(fz_array_get(widths, i + 3));
- y = fz_to_int(fz_array_get(widths, i + 4));
+ c1 = pdf_to_int(obj);
+ w = pdf_to_int(pdf_array_get(widths, i + 2));
+ x = pdf_to_int(pdf_array_get(widths, i + 3));
+ y = pdf_to_int(pdf_array_get(widths, i + 4));
pdf_add_vmtx(ctx, fontdesc, c0, c1, x, y, w);
i += 5;
}
@@ -935,38 +935,38 @@ load_cid_font(pdf_document *xref, fz_obj *dict, fz_obj *encoding, fz_obj *to_uni
fz_catch(ctx)
{
pdf_drop_font(ctx, fontdesc);
- fz_throw(ctx, "cannot load cid font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "cannot load cid font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
}
return fontdesc;
}
static pdf_font_desc *
-pdf_load_type0_font(pdf_document *xref, fz_obj *dict)
+pdf_load_type0_font(pdf_document *xref, pdf_obj *dict)
{
- fz_obj *dfonts;
- fz_obj *dfont;
- fz_obj *subtype;
- fz_obj *encoding;
- fz_obj *to_unicode;
+ pdf_obj *dfonts;
+ pdf_obj *dfont;
+ pdf_obj *subtype;
+ pdf_obj *encoding;
+ pdf_obj *to_unicode;
- dfonts = fz_dict_gets(dict, "DescendantFonts");
+ dfonts = pdf_dict_gets(dict, "DescendantFonts");
if (!dfonts)
fz_throw(xref->ctx, "cid font is missing descendant fonts");
- dfont = fz_array_get(dfonts, 0);
+ dfont = pdf_array_get(dfonts, 0);
- subtype = fz_dict_gets(dfont, "Subtype");
- encoding = fz_dict_gets(dict, "Encoding");
- to_unicode = fz_dict_gets(dict, "ToUnicode");
+ subtype = pdf_dict_gets(dfont, "Subtype");
+ encoding = pdf_dict_gets(dict, "Encoding");
+ to_unicode = pdf_dict_gets(dict, "ToUnicode");
- if (fz_is_name(subtype) && !strcmp(fz_to_name(subtype), "CIDFontType0"))
+ if (pdf_is_name(subtype) && !strcmp(pdf_to_name(subtype), "CIDFontType0"))
return load_cid_font(xref, dfont, encoding, to_unicode);
- else if (fz_is_name(subtype) && !strcmp(fz_to_name(subtype), "CIDFontType2"))
+ else if (pdf_is_name(subtype) && !strcmp(pdf_to_name(subtype), "CIDFontType2"))
return load_cid_font(xref, dfont, encoding, to_unicode);
else
fz_throw(xref->ctx, "syntaxerror: unknown cid font type");
- /* RJW: "cannot load descendant font (%d %d R)", fz_to_num(dfont), fz_to_gen(dfont) */
+ /* RJW: "cannot load descendant font (%d %d R)", pdf_to_num(dfont), pdf_to_gen(dfont) */
return NULL; /* Stupid MSVC */
}
@@ -975,34 +975,34 @@ pdf_load_type0_font(pdf_document *xref, fz_obj *dict)
*/
static void
-pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, fz_obj *dict, char *collection, char *basefont)
+pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, pdf_obj *dict, char *collection, char *basefont)
{
- fz_obj *obj1, *obj2, *obj3, *obj;
+ pdf_obj *obj1, *obj2, *obj3, *obj;
char *fontname;
char *origname;
FT_Face face;
fz_context *ctx = xref->ctx;
if (!strchr(basefont, ',') || strchr(basefont, '+'))
- origname = fz_to_name(fz_dict_gets(dict, "FontName"));
+ origname = pdf_to_name(pdf_dict_gets(dict, "FontName"));
else
origname = basefont;
fontname = clean_font_name(origname);
- fontdesc->flags = fz_to_int(fz_dict_gets(dict, "Flags"));
- fontdesc->italic_angle = fz_to_real(fz_dict_gets(dict, "ItalicAngle"));
- fontdesc->ascent = fz_to_real(fz_dict_gets(dict, "Ascent"));
- fontdesc->descent = fz_to_real(fz_dict_gets(dict, "Descent"));
- fontdesc->cap_height = fz_to_real(fz_dict_gets(dict, "CapHeight"));
- fontdesc->x_height = fz_to_real(fz_dict_gets(dict, "XHeight"));
- fontdesc->missing_width = fz_to_real(fz_dict_gets(dict, "MissingWidth"));
-
- obj1 = fz_dict_gets(dict, "FontFile");
- obj2 = fz_dict_gets(dict, "FontFile2");
- obj3 = fz_dict_gets(dict, "FontFile3");
+ fontdesc->flags = pdf_to_int(pdf_dict_gets(dict, "Flags"));
+ fontdesc->italic_angle = pdf_to_real(pdf_dict_gets(dict, "ItalicAngle"));
+ fontdesc->ascent = pdf_to_real(pdf_dict_gets(dict, "Ascent"));
+ fontdesc->descent = pdf_to_real(pdf_dict_gets(dict, "Descent"));
+ fontdesc->cap_height = pdf_to_real(pdf_dict_gets(dict, "CapHeight"));
+ fontdesc->x_height = pdf_to_real(pdf_dict_gets(dict, "XHeight"));
+ fontdesc->missing_width = pdf_to_real(pdf_dict_gets(dict, "MissingWidth"));
+
+ obj1 = pdf_dict_gets(dict, "FontFile");
+ obj2 = pdf_dict_gets(dict, "FontFile2");
+ obj3 = pdf_dict_gets(dict, "FontFile3");
obj = obj1 ? obj1 : obj2 ? obj2 : obj3;
- if (fz_is_indirect(obj))
+ if (pdf_is_indirect(obj))
{
fz_try(ctx)
{
@@ -1015,7 +1015,7 @@ pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, fz_obj *di
pdf_load_builtin_font(ctx, fontdesc, fontname);
else
pdf_load_system_font(ctx, fontdesc, fontname, collection);
- /* RJW: "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */
+ /* RJW: "cannot load font descriptor (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */
}
}
else
@@ -1024,7 +1024,7 @@ pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, fz_obj *di
pdf_load_builtin_font(ctx, fontdesc, fontname);
else
pdf_load_system_font(ctx, fontdesc, fontname, collection);
- /* RJW: "cannot load font descriptor (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */
+ /* RJW: "cannot load font descriptor (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */
}
fz_strlcpy(fontdesc->font->name, fontname, sizeof fontdesc->font->name);
@@ -1073,22 +1073,22 @@ pdf_make_width_table(fz_context *ctx, pdf_font_desc *fontdesc)
}
pdf_font_desc *
-pdf_load_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
+pdf_load_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict)
{
char *subtype;
- fz_obj *dfonts;
- fz_obj *charprocs;
+ pdf_obj *dfonts;
+ pdf_obj *charprocs;
fz_context *ctx = xref->ctx;
pdf_font_desc *fontdesc;
- if ((fontdesc = fz_find_item(ctx, pdf_free_font_imp, dict)))
+ if ((fontdesc = pdf_find_item(ctx, pdf_free_font_imp, dict)))
{
return fontdesc;
}
- subtype = fz_to_name(fz_dict_gets(dict, "Subtype"));
- dfonts = fz_dict_gets(dict, "DescendantFonts");
- charprocs = fz_dict_gets(dict, "CharProcs");
+ subtype = pdf_to_name(pdf_dict_gets(dict, "Subtype"));
+ dfonts = pdf_dict_gets(dict, "DescendantFonts");
+ charprocs = pdf_dict_gets(dict, "CharProcs");
if (subtype && !strcmp(subtype, "Type0"))
fontdesc = pdf_load_type0_font(xref, dict);
@@ -1115,19 +1115,19 @@ pdf_load_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
fz_warn(ctx, "unknown font format, guessing type1 or truetype.");
fontdesc = pdf_load_simple_font(xref, dict);
}
- /* RJW: "cannot load font (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */
+ /* RJW: "cannot load font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */
/* Save the widths to stretch non-CJK substitute fonts */
if (fontdesc->font->ft_substitute && !fontdesc->to_ttf_cmap)
pdf_make_width_table(ctx, fontdesc);
- fz_store_item(ctx, dict, fontdesc, fontdesc->size);
+ pdf_store_item(ctx, dict, fontdesc, fontdesc->size);
return fontdesc;
}
void
-pdf_debug_font(fz_context *ctx, pdf_font_desc *fontdesc)
+pdf_print_font(fz_context *ctx, pdf_font_desc *fontdesc)
{
int i;
diff --git a/pdf/pdf_fontfile.c b/pdf/pdf_fontfile.c
index 543ce763..b67d8a32 100644
--- a/pdf/pdf_fontfile.c
+++ b/pdf/pdf_fontfile.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#ifdef NOCJK
#define NOCJKFONT
@@ -16,7 +16,7 @@
#endif
unsigned char *
-pdf_find_builtin_font(char *name, unsigned int *len)
+pdf_lookup_builtin_font(char *name, unsigned int *len)
{
if (!strcmp("Courier", name)) {
*len = sizeof pdf_font_NimbusMonL_Regu;
@@ -79,32 +79,32 @@ pdf_find_builtin_font(char *name, unsigned int *len)
}
unsigned char *
-pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len)
+pdf_lookup_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len)
{
#ifdef NODROIDFONT
if (mono) {
if (bold) {
- if (italic) return pdf_find_builtin_font("Courier-BoldOblique", len);
- else return pdf_find_builtin_font("Courier-Bold", len);
+ if (italic) return pdf_lookup_builtin_font("Courier-BoldOblique", len);
+ else return pdf_lookup_builtin_font("Courier-Bold", len);
} else {
- if (italic) return pdf_find_builtin_font("Courier-Oblique", len);
- else return pdf_find_builtin_font("Courier", len);
+ if (italic) return pdf_lookup_builtin_font("Courier-Oblique", len);
+ else return pdf_lookup_builtin_font("Courier", len);
}
} else if (serif) {
if (bold) {
- if (italic) return pdf_find_builtin_font("Times-BoldItalic", len);
- else return pdf_find_builtin_font("Times-Bold", len);
+ if (italic) return pdf_lookup_builtin_font("Times-BoldItalic", len);
+ else return pdf_lookup_builtin_font("Times-Bold", len);
} else {
- if (italic) return pdf_find_builtin_font("Times-Italic", len);
- else return pdf_find_builtin_font("Times-Roman", len);
+ if (italic) return pdf_lookup_builtin_font("Times-Italic", len);
+ else return pdf_lookup_builtin_font("Times-Roman", len);
}
} else {
if (bold) {
- if (italic) return pdf_find_builtin_font("Helvetica-BoldOblique", len);
- else return pdf_find_builtin_font("Helvetica-Bold", len);
+ if (italic) return pdf_lookup_builtin_font("Helvetica-BoldOblique", len);
+ else return pdf_lookup_builtin_font("Helvetica-Bold", len);
} else {
- if (italic) return pdf_find_builtin_font("Helvetica-Oblique", len);
- else return pdf_find_builtin_font("Helvetica", len);
+ if (italic) return pdf_lookup_builtin_font("Helvetica-Oblique", len);
+ else return pdf_lookup_builtin_font("Helvetica", len);
}
}
#else
@@ -119,7 +119,7 @@ pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int
}
unsigned char *
-pdf_find_substitute_cjk_font(int ros, int serif, unsigned int *len)
+pdf_lookup_substitute_cjk_font(int ros, int serif, unsigned int *len)
{
#ifndef NOCJKFONT
*len = sizeof pdf_font_DroidSansFallback;
diff --git a/pdf/pdf_function.c b/pdf/pdf_function.c
index 23acc4db..e1c53beb 100644
--- a/pdf/pdf_function.c
+++ b/pdf/pdf_function.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
enum
{
@@ -203,7 +203,13 @@ ps_push_real(ps_stack *st, float n)
if (!ps_overflow(st, 1))
{
st->stack[st->sp].type = PS_REAL;
- st->stack[st->sp].u.f = n;
+ if (isnan(n))
+ {
+ /* Push 1.0, as it's a small known value that won't
+ cause a divide by 0. Same reason as in fz_atof. */
+ n = 1.0;
+ }
+ st->stack[st->sp].u.f = CLAMP(n, -FLT_MAX, FLT_MAX);
st->sp++;
}
}
@@ -360,10 +366,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc)
case PS_OP_BITSHIFT:
i2 = ps_pop_int(st);
i1 = ps_pop_int(st);
- if (i2 > 0)
+ if (i2 > 0 && i2 < 8 * sizeof (i2))
ps_push_int(st, i1 << i2);
- else if (i2 < 0)
- ps_push_int(st, (int)((unsigned int)i1 >> i2));
+ else if (i2 < 0 && i2 > -8 * (int)sizeof (i2))
+ ps_push_int(st, (int)((unsigned int)i1 >> -i2));
else
ps_push_int(st, i1);
break;
@@ -393,7 +399,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc)
case PS_OP_DIV:
r2 = ps_pop_real(st);
r1 = ps_pop_real(st);
- ps_push_real(st, r1 / r2);
+ if (fabsf(r2) < FLT_EPSILON)
+ ps_push_real(st, r1 / r2);
+ else
+ ps_push_real(st, DIV_BY_ZERO(r1, r2, -FLT_MAX, FLT_MAX));
break;
case PS_OP_DUP:
@@ -466,7 +475,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc)
case PS_OP_IDIV:
i2 = ps_pop_int(st);
i1 = ps_pop_int(st);
- ps_push_int(st, i1 / i2);
+ if (i2 != 0)
+ ps_push_int(st, i1 / i2);
+ else
+ ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX));
break;
case PS_OP_INDEX:
@@ -512,7 +524,10 @@ ps_run(fz_context *ctx, psobj *code, ps_stack *st, int pc)
case PS_OP_MOD:
i2 = ps_pop_int(st);
i1 = ps_pop_int(st);
- ps_push_int(st, i1 % i2);
+ if (i2 != 0)
+ ps_push_int(st, i1 % i2);
+ else
+ ps_push_int(st, DIV_BY_ZERO(i1, i2, INT_MIN, INT_MAX));
break;
case PS_OP_MUL:
@@ -683,18 +698,18 @@ resize_code(fz_context *ctx, pdf_function *func, int newsize)
static void
parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
{
- char buf[64];
- int len;
+ pdf_lexbuf buf;
int tok;
int opptr, elseptr, ifptr;
int a, b, mid, cmp;
fz_context *ctx = stream->ctx;
- memset(buf, 0, sizeof(buf));
+ buf.size = PDF_LEXBUF_SMALL;
+ memset(buf.scratch, 0, sizeof(buf.scratch));
while (1)
{
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
/* RJW: "calculator function lexical error" */
switch(tok)
@@ -705,7 +720,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
case PDF_TOK_INT:
resize_code(ctx, func, *codeptr);
func->u.p.code[*codeptr].type = PS_INT;
- func->u.p.code[*codeptr].u.i = atoi(buf);
+ func->u.p.code[*codeptr].u.i = buf.i;
++*codeptr;
break;
@@ -726,7 +741,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
case PDF_TOK_REAL:
resize_code(ctx, func, *codeptr);
func->u.p.code[*codeptr].type = PS_REAL;
- func->u.p.code[*codeptr].u.f = fz_atof(buf);
+ func->u.p.code[*codeptr].u.f = buf.f;
++*codeptr;
break;
@@ -740,7 +755,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
parse_code(func, stream, codeptr);
/* RJW: "error in 'if' branch" */
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
/* RJW: "calculator function syntax error" */
if (tok == PDF_TOK_OPEN_BRACE)
@@ -749,7 +764,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
parse_code(func, stream, codeptr);
/* RJW: "error in 'else' branch" */
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
/* RJW: "calculator function syntax error" */
}
else
@@ -760,7 +775,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
if (tok != PDF_TOK_KEYWORD)
fz_throw(ctx, "missing keyword in 'if-else' context");
- if (!strcmp(buf, "if"))
+ if (!strcmp(buf.scratch, "if"))
{
if (elseptr >= 0)
fz_throw(ctx, "too many branches for 'if'");
@@ -771,7 +786,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
func->u.p.code[opptr+3].type = PS_BLOCK;
func->u.p.code[opptr+3].u.block = *codeptr;
}
- else if (!strcmp(buf, "ifelse"))
+ else if (!strcmp(buf.scratch, "ifelse"))
{
if (elseptr < 0)
fz_throw(ctx, "not enough branches for 'ifelse'");
@@ -786,7 +801,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
}
else
{
- fz_throw(ctx, "unknown keyword in 'if-else' context: '%s'", buf);
+ fz_throw(ctx, "unknown keyword in 'if-else' context: '%s'", buf.scratch);
}
break;
@@ -804,7 +819,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
while (b - a > 1)
{
mid = (a + b) / 2;
- cmp = strcmp(buf, ps_op_names[mid]);
+ cmp = strcmp(buf.scratch, ps_op_names[mid]);
if (cmp > 0)
a = mid;
else if (cmp < 0)
@@ -813,7 +828,7 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
a = b = mid;
}
if (cmp != 0)
- fz_throw(ctx, "unknown operator: '%s'", buf);
+ fz_throw(ctx, "unknown operator: '%s'", buf.scratch);
resize_code(ctx, func, *codeptr);
func->u.p.code[*codeptr].type = PS_OPERATOR;
@@ -828,16 +843,17 @@ parse_code(pdf_function *func, fz_stream *stream, int *codeptr)
}
static void
-load_postscript_func(pdf_function *func, pdf_document *xref, fz_obj *dict, int num, int gen)
+load_postscript_func(pdf_function *func, pdf_document *xref, pdf_obj *dict, int num, int gen)
{
fz_stream *stream = NULL;
int codeptr;
- char buf[64];
+ pdf_lexbuf buf;
int tok;
- int len;
fz_context *ctx = xref->ctx;
int locked = 0;
+ buf.size = PDF_LEXBUF_SMALL;
+
fz_var(stream);
fz_var(locked);
@@ -846,7 +862,7 @@ load_postscript_func(pdf_function *func, pdf_document *xref, fz_obj *dict, int n
stream = pdf_open_stream(xref, num, gen);
/* RJW: "cannot open calculator function stream" */
- tok = pdf_lex(stream, buf, sizeof buf, &len);
+ tok = pdf_lex(stream, &buf);
if (tok != PDF_TOK_OPEN_BRACE)
{
fz_throw(ctx, "stream is not a calculator function");
@@ -899,37 +915,37 @@ eval_postscript_func(fz_context *ctx, pdf_function *func, float *in, float *out)
*/
static void
-load_sample_func(pdf_function *func, pdf_document *xref, fz_obj *dict, int num, int gen)
+load_sample_func(pdf_function *func, pdf_document *xref, pdf_obj *dict, int num, int gen)
{
fz_context *ctx = xref->ctx;
fz_stream *stream;
- fz_obj *obj;
+ pdf_obj *obj;
int samplecount;
int bps;
int i;
func->u.sa.samples = NULL;
- obj = fz_dict_gets(dict, "Size");
- if (!fz_is_array(obj) || fz_array_len(obj) != func->m)
+ obj = pdf_dict_gets(dict, "Size");
+ if (!pdf_is_array(obj) || pdf_array_len(obj) != func->m)
fz_throw(ctx, "malformed /Size");
for (i = 0; i < func->m; i++)
- func->u.sa.size[i] = fz_to_int(fz_array_get(obj, i));
+ func->u.sa.size[i] = pdf_to_int(pdf_array_get(obj, i));
- obj = fz_dict_gets(dict, "BitsPerSample");
- if (!fz_is_int(obj))
+ obj = pdf_dict_gets(dict, "BitsPerSample");
+ if (!pdf_is_int(obj))
fz_throw(ctx, "malformed /BitsPerSample");
- func->u.sa.bps = bps = fz_to_int(obj);
+ func->u.sa.bps = bps = pdf_to_int(obj);
- obj = fz_dict_gets(dict, "Encode");
- if (fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "Encode");
+ if (pdf_is_array(obj))
{
- if (fz_array_len(obj) != func->m * 2)
+ if (pdf_array_len(obj) != func->m * 2)
fz_throw(ctx, "malformed /Encode");
for (i = 0; i < func->m; i++)
{
- func->u.sa.encode[i][0] = fz_to_real(fz_array_get(obj, i*2+0));
- func->u.sa.encode[i][1] = fz_to_real(fz_array_get(obj, i*2+1));
+ func->u.sa.encode[i][0] = pdf_to_real(pdf_array_get(obj, i*2+0));
+ func->u.sa.encode[i][1] = pdf_to_real(pdf_array_get(obj, i*2+1));
}
}
else
@@ -941,15 +957,15 @@ load_sample_func(pdf_function *func, pdf_document *xref, fz_obj *dict, int num,
}
}
- obj = fz_dict_gets(dict, "Decode");
- if (fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "Decode");
+ if (pdf_is_array(obj))
{
- if (fz_array_len(obj) != func->n * 2)
+ if (pdf_array_len(obj) != func->n * 2)
fz_throw(ctx, "malformed /Decode");
for (i = 0; i < func->n; i++)
{
- func->u.sa.decode[i][0] = fz_to_real(fz_array_get(obj, i*2+0));
- func->u.sa.decode[i][1] = fz_to_real(fz_array_get(obj, i*2+1));
+ func->u.sa.decode[i][0] = pdf_to_real(pdf_array_get(obj, i*2+0));
+ func->u.sa.decode[i][1] = pdf_to_real(pdf_array_get(obj, i*2+1));
}
}
else
@@ -1110,27 +1126,27 @@ eval_sample_func(fz_context *ctx, pdf_function *func, float *in, float *out)
*/
static void
-load_exponential_func(fz_context *ctx, pdf_function *func, fz_obj *dict)
+load_exponential_func(fz_context *ctx, pdf_function *func, pdf_obj *dict)
{
- fz_obj *obj;
+ pdf_obj *obj;
int i;
if (func->m != 1)
fz_throw(ctx, "/Domain must be one dimension (%d)", func->m);
- obj = fz_dict_gets(dict, "N");
- if (!fz_is_int(obj) && !fz_is_real(obj))
+ obj = pdf_dict_gets(dict, "N");
+ if (!pdf_is_int(obj) && !pdf_is_real(obj))
fz_throw(ctx, "malformed /N");
- func->u.e.n = fz_to_real(obj);
+ func->u.e.n = pdf_to_real(obj);
- obj = fz_dict_gets(dict, "C0");
- if (fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "C0");
+ if (pdf_is_array(obj))
{
- func->n = fz_array_len(obj);
+ func->n = pdf_array_len(obj);
if (func->n >= MAXN)
fz_throw(ctx, "exponential function result array out of range");
for (i = 0; i < func->n; i++)
- func->u.e.c0[i] = fz_to_real(fz_array_get(obj, i));
+ func->u.e.c0[i] = pdf_to_real(pdf_array_get(obj, i));
}
else
{
@@ -1138,13 +1154,13 @@ load_exponential_func(fz_context *ctx, pdf_function *func, fz_obj *dict)
func->u.e.c0[0] = 0;
}
- obj = fz_dict_gets(dict, "C1");
- if (fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "C1");
+ if (pdf_is_array(obj))
{
- if (fz_array_len(obj) != func->n)
+ if (pdf_array_len(obj) != func->n)
fz_throw(ctx, "/C1 must match /C0 length");
for (i = 0; i < func->n; i++)
- func->u.e.c1[i] = fz_to_real(fz_array_get(obj, i));
+ func->u.e.c1[i] = pdf_to_real(pdf_array_get(obj, i));
}
else
{
@@ -1184,13 +1200,13 @@ eval_exponential_func(fz_context *ctx, pdf_function *func, float in, float *out)
*/
static void
-load_stitching_func(pdf_function *func, pdf_document *xref, fz_obj *dict)
+load_stitching_func(pdf_function *func, pdf_document *xref, pdf_obj *dict)
{
fz_context *ctx = xref->ctx;
pdf_function **funcs;
- fz_obj *obj;
- fz_obj *sub;
- fz_obj *num;
+ pdf_obj *obj;
+ pdf_obj *sub;
+ pdf_obj *num;
int k;
int i;
@@ -1199,11 +1215,11 @@ load_stitching_func(pdf_function *func, pdf_document *xref, fz_obj *dict)
if (func->m != 1)
fz_throw(ctx, "/Domain must be one dimension (%d)", func->m);
- obj = fz_dict_gets(dict, "Functions");
- if (!fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "Functions");
+ if (!pdf_is_array(obj))
fz_throw(ctx, "stitching function has no input functions");
{
- k = fz_array_len(obj);
+ k = pdf_array_len(obj);
func->u.st.funcs = fz_malloc_array(ctx, k, sizeof(pdf_function*));
func->u.st.bounds = fz_malloc_array(ctx, k - 1, sizeof(float));
@@ -1212,9 +1228,9 @@ load_stitching_func(pdf_function *func, pdf_document *xref, fz_obj *dict)
for (i = 0; i < k; i++)
{
- sub = fz_array_get(obj, i);
+ sub = pdf_array_get(obj, i);
funcs[i] = pdf_load_function(xref, sub);
- /* RJW: "cannot load sub function %d (%d %d R)", i, fz_to_num(sub), fz_to_gen(sub) */
+ /* RJW: "cannot load sub function %d (%d %d R)", i, pdf_to_num(sub), pdf_to_gen(sub) */
if (funcs[i]->m != 1 || funcs[i]->n != funcs[0]->n)
fz_throw(ctx, "sub function %d /Domain or /Range mismatch", i);
func->size += pdf_function_size(funcs[i]);
@@ -1227,19 +1243,19 @@ load_stitching_func(pdf_function *func, pdf_document *xref, fz_obj *dict)
fz_throw(ctx, "sub function /Domain or /Range mismatch");
}
- obj = fz_dict_gets(dict, "Bounds");
- if (!fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "Bounds");
+ if (!pdf_is_array(obj))
fz_throw(ctx, "stitching function has no bounds");
{
- if (fz_array_len(obj) != k - 1)
+ if (pdf_array_len(obj) != k - 1)
fz_throw(ctx, "malformed /Bounds (wrong length)");
for (i = 0; i < k-1; i++)
{
- num = fz_array_get(obj, i);
- if (!fz_is_int(num) && !fz_is_real(num))
+ num = pdf_array_get(obj, i);
+ if (!pdf_is_int(num) && !pdf_is_real(num))
fz_throw(ctx, "malformed /Bounds (item not real)");
- func->u.st.bounds[i] = fz_to_real(num);
+ func->u.st.bounds[i] = pdf_to_real(num);
if (i && func->u.st.bounds[i-1] > func->u.st.bounds[i])
fz_throw(ctx, "malformed /Bounds (item not monotonic)");
}
@@ -1249,16 +1265,16 @@ load_stitching_func(pdf_function *func, pdf_document *xref, fz_obj *dict)
fz_warn(ctx, "malformed shading function bounds (domain mismatch), proceeding anyway.");
}
- obj = fz_dict_gets(dict, "Encode");
- if (!fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "Encode");
+ if (!pdf_is_array(obj))
fz_throw(ctx, "stitching function is missing encoding");
{
- if (fz_array_len(obj) != k * 2)
+ if (pdf_array_len(obj) != k * 2)
fz_throw(ctx, "malformed /Encode");
for (i = 0; i < k; i++)
{
- func->u.st.encode[i*2+0] = fz_to_real(fz_array_get(obj, i*2+0));
- func->u.st.encode[i*2+1] = fz_to_real(fz_array_get(obj, i*2+1));
+ func->u.st.encode[i*2+0] = pdf_to_real(pdf_array_get(obj, i*2+0));
+ func->u.st.encode[i*2+1] = pdf_to_real(pdf_array_get(obj, i*2+1));
}
}
}
@@ -1355,14 +1371,14 @@ pdf_function_size(pdf_function *func)
}
pdf_function *
-pdf_load_function(pdf_document *xref, fz_obj *dict)
+pdf_load_function(pdf_document *xref, pdf_obj *dict)
{
fz_context *ctx = xref->ctx;
pdf_function *func;
- fz_obj *obj;
+ pdf_obj *obj;
int i;
- if ((func = fz_find_item(ctx, pdf_free_function_imp, dict)))
+ if ((func = pdf_find_item(ctx, pdf_free_function_imp, dict)))
{
return func;
}
@@ -1371,28 +1387,28 @@ pdf_load_function(pdf_document *xref, fz_obj *dict)
FZ_INIT_STORABLE(func, 1, pdf_free_function_imp);
func->size = sizeof(*func);
- obj = fz_dict_gets(dict, "FunctionType");
- func->type = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "FunctionType");
+ func->type = pdf_to_int(obj);
/* required for all */
- obj = fz_dict_gets(dict, "Domain");
- func->m = fz_array_len(obj) / 2;
+ obj = pdf_dict_gets(dict, "Domain");
+ func->m = pdf_array_len(obj) / 2;
for (i = 0; i < func->m; i++)
{
- func->domain[i][0] = fz_to_real(fz_array_get(obj, i * 2 + 0));
- func->domain[i][1] = fz_to_real(fz_array_get(obj, i * 2 + 1));
+ func->domain[i][0] = pdf_to_real(pdf_array_get(obj, i * 2 + 0));
+ func->domain[i][1] = pdf_to_real(pdf_array_get(obj, i * 2 + 1));
}
/* required for type0 and type4, optional otherwise */
- obj = fz_dict_gets(dict, "Range");
- if (fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "Range");
+ if (pdf_is_array(obj))
{
func->has_range = 1;
- func->n = fz_array_len(obj) / 2;
+ func->n = pdf_array_len(obj) / 2;
for (i = 0; i < func->n; i++)
{
- func->range[i][0] = fz_to_real(fz_array_get(obj, i * 2 + 0));
- func->range[i][1] = fz_to_real(fz_array_get(obj, i * 2 + 1));
+ func->range[i][0] = pdf_to_real(pdf_array_get(obj, i * 2 + 0));
+ func->range[i][1] = pdf_to_real(pdf_array_get(obj, i * 2 + 1));
}
}
else
@@ -1412,7 +1428,7 @@ pdf_load_function(pdf_document *xref, fz_obj *dict)
switch(func->type)
{
case SAMPLE:
- load_sample_func(func, xref, dict, fz_to_num(dict), fz_to_gen(dict));
+ load_sample_func(func, xref, dict, pdf_to_num(dict), pdf_to_gen(dict));
break;
case EXPONENTIAL:
@@ -1424,15 +1440,15 @@ pdf_load_function(pdf_document *xref, fz_obj *dict)
break;
case POSTSCRIPT:
- load_postscript_func(func, xref, dict, fz_to_num(dict), fz_to_gen(dict));
+ load_postscript_func(func, xref, dict, pdf_to_num(dict), pdf_to_gen(dict));
break;
default:
fz_free(ctx, func);
- fz_throw(ctx, "unknown function type (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "unknown function type (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
}
- fz_store_item(ctx, dict, func, func->size);
+ pdf_store_item(ctx, dict, func, func->size);
}
fz_catch(ctx)
{
@@ -1444,7 +1460,7 @@ pdf_load_function(pdf_document *xref, fz_obj *dict)
type == STITCHING ? "stitching" :
type == POSTSCRIPT ? "calculator" :
"unknown",
- fz_to_num(dict), fz_to_gen(dict));
+ pdf_to_num(dict), pdf_to_gen(dict));
}
return func;
diff --git a/pdf/pdf_image.c b/pdf/pdf_image.c
index 3aa26f08..17996a74 100644
--- a/pdf/pdf_image.c
+++ b/pdf/pdf_image.c
@@ -1,10 +1,15 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
-/* TODO: store JPEG compressed samples */
-/* TODO: store flate compressed samples */
+typedef struct pdf_image_key_s pdf_image_key;
-static fz_pixmap *pdf_load_jpx(pdf_document *xref, fz_obj *dict);
+struct pdf_image_key_s {
+ int refs;
+ fz_image *image;
+ int factor;
+};
+
+static void pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image);
static void
pdf_mask_color_key(fz_pixmap *pix, int n, int *colorkey)
@@ -25,58 +30,304 @@ pdf_mask_color_key(fz_pixmap *pix, int n, int *colorkey)
}
}
+static int
+pdf_make_hash_image_key(fz_store_hash *hash, void *key_)
+{
+ pdf_image_key *key = (pdf_image_key *)key_;
+
+ hash->u.pi.ptr = key->image;
+ hash->u.pi.i = key->factor;
+ return 1;
+}
+
+static void *
+pdf_keep_image_key(fz_context *ctx, void *key_)
+{
+ pdf_image_key *key = (pdf_image_key *)key_;
+
+ fz_lock(ctx, FZ_LOCK_ALLOC);
+ key->refs++;
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
+
+ return (void *)key;
+}
+
+static void
+pdf_drop_image_key(fz_context *ctx, void *key_)
+{
+ pdf_image_key *key = (pdf_image_key *)key_;
+ int drop;
+
+ fz_lock(ctx, FZ_LOCK_ALLOC);
+ drop = --key->refs;
+ fz_unlock(ctx, FZ_LOCK_ALLOC);
+ if (drop == 0)
+ {
+ fz_drop_image(ctx, key->image);
+ fz_free(ctx, key);
+ }
+}
+
+static int
+pdf_cmp_image_key(void *k0_, void *k1_)
+{
+ pdf_image_key *k0 = (pdf_image_key *)k0_;
+ pdf_image_key *k1 = (pdf_image_key *)k1_;
+
+ return k0->image == k1->image && k0->factor == k1->factor;
+}
+
+static void
+pdf_debug_image(void *key_)
+{
+ pdf_image_key *key = (pdf_image_key *)key_;
+
+ printf("(image %d x %d sf=%d) ", key->image->w, key->image->h, key->factor);
+}
+
+static fz_store_type pdf_image_store_type =
+{
+ pdf_make_hash_image_key,
+ pdf_keep_image_key,
+ pdf_drop_image_key,
+ pdf_cmp_image_key,
+ pdf_debug_image
+};
+
static fz_pixmap *
-pdf_load_image_imp(pdf_document *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cstm, int forcemask)
+decomp_image_from_stream(fz_context *ctx, fz_stream *stm, pdf_image *image, int in_line, int indexed, int factor)
{
- fz_stream *stm = NULL;
fz_pixmap *tile = NULL;
- fz_obj *obj, *res;
+ fz_pixmap *existing_tile;
+ int stride, len, i;
+ unsigned char *samples = NULL;
+ int w = (image->base.w + (factor-1)) / factor;
+ int h = (image->base.h + (factor-1)) / factor;
+ pdf_image_key *key;
+
+ fz_var(tile);
+ fz_var(samples);
+
+ fz_try(ctx)
+ {
+ tile = fz_new_pixmap(ctx, image->base.colorspace, w, h);
+ tile->interpolate = image->interpolate;
+
+ stride = (w * image->n * image->bpc + 7) / 8;
+
+ samples = fz_malloc_array(ctx, h, stride);
+
+ len = fz_read(stm, samples, h * stride);
+ if (len < 0)
+ {
+ fz_throw(ctx, "cannot read image data");
+ }
+
+ /* Make sure we read the EOF marker (for inline images only) */
+ if (in_line)
+ {
+ unsigned char tbuf[512];
+ fz_try(ctx)
+ {
+ int tlen = fz_read(stm, tbuf, sizeof tbuf);
+ if (tlen > 0)
+ fz_warn(ctx, "ignoring garbage at end of image");
+ }
+ fz_catch(ctx)
+ {
+ fz_warn(ctx, "ignoring error at end of image");
+ }
+ }
+
+ /* Pad truncated images */
+ if (len < stride * h)
+ {
+ fz_warn(ctx, "padding truncated image");
+ memset(samples + len, 0, stride * h - len);
+ }
+
+ /* Invert 1-bit image masks */
+ if (image->imagemask)
+ {
+ /* 0=opaque and 1=transparent so we need to invert */
+ unsigned char *p = samples;
+ len = h * stride;
+ for (i = 0; i < len; i++)
+ p[i] = ~p[i];
+ }
+
+ fz_unpack_tile(tile, samples, image->n, image->bpc, stride, indexed);
+
+ fz_free(ctx, samples);
+ samples = NULL;
+
+ if (image->usecolorkey)
+ pdf_mask_color_key(tile, image->n, image->colorkey);
+
+ if (indexed)
+ {
+ fz_pixmap *conv;
+ fz_decode_indexed_tile(tile, image->decode, (1 << image->bpc) - 1);
+ conv = pdf_expand_indexed_pixmap(ctx, tile);
+ fz_drop_pixmap(ctx, tile);
+ tile = conv;
+ }
+ else
+ {
+ fz_decode_tile(tile, image->decode);
+ }
+ }
+ fz_always(ctx)
+ {
+ fz_close(stm);
+ }
+ fz_catch(ctx)
+ {
+ if (tile)
+ fz_drop_pixmap(ctx, tile);
+ fz_free(ctx, samples);
+
+ fz_rethrow(ctx);
+ }
+
+ /* Now we try to cache the pixmap. Any failure here will just result
+ * in us not caching. */
+ fz_try(ctx)
+ {
+ key = fz_malloc_struct(ctx, pdf_image_key);
+ key->refs = 1;
+ key->image = fz_keep_image(ctx, &image->base);
+ key->factor = factor;
+ existing_tile = fz_store_item(ctx, key, tile, fz_pixmap_size(ctx, tile), &pdf_image_store_type);
+ if (existing_tile)
+ {
+ /* We already have a tile. This must have been produced by a
+ * racing thread. We'll throw away ours and use that one. */
+ fz_drop_pixmap(ctx, tile);
+ tile = existing_tile;
+ }
+ }
+ fz_always(ctx)
+ {
+ pdf_drop_image_key(ctx, key);
+ }
+ fz_catch(ctx)
+ {
+ /* Do nothing */
+ }
+
+ return tile;
+}
+
+static void
+pdf_free_image(fz_context *ctx, fz_storable *image_)
+{
+ pdf_image *image = (pdf_image *)image_;
+
+ if (image == NULL)
+ return;
+ fz_drop_pixmap(ctx, image->tile);
+ fz_drop_buffer(ctx, image->buffer);
+ fz_drop_colorspace(ctx, image->base.colorspace);
+ fz_drop_image(ctx, image->base.mask);
+ fz_free(ctx, image);
+}
+
+static fz_pixmap *
+pdf_image_get_pixmap(fz_context *ctx, fz_image *image_, int w, int h)
+{
+ pdf_image *image = (pdf_image *)image_;
+ fz_pixmap *tile;
+ fz_stream *stm;
+ int factor;
+ pdf_image_key key;
+
+ /* Check for 'simple' images which are just pixmaps */
+ if (image->buffer == NULL)
+ {
+ tile = image->tile;
+ if (!tile)
+ return NULL;
+ return fz_keep_pixmap(ctx, tile); /* That's all we can give you! */
+ }
+
+ /* Ensure our expectations for tile size are reasonable */
+ if (w > image->base.w)
+ w = image->base.w;
+ if (h > image->base.h)
+ h = image->base.h;
+
+ /* What is our ideal factor? */
+ if (w == 0 || h == 0)
+ factor = 1;
+ else
+ for (factor=1; image->base.w/(2*factor) >= w && image->base.h/(2*factor) >= h && factor < 8; factor *= 2);
+
+ /* Can we find any suitable tiles in the cache? */
+ key.refs = 1;
+ key.image = &image->base;
+ key.factor = factor;
+ do
+ {
+ tile = fz_find_item(ctx, fz_free_pixmap_imp, &key, &pdf_image_store_type);
+ if (tile)
+ return tile;
+ key.factor >>= 1;
+ }
+ while (key.factor > 0);
+
+ /* We need to make a new one. */
+ stm = pdf_open_image_decomp_stream(ctx, image->buffer, &image->params, &factor);
+
+ return decomp_image_from_stream(ctx, stm, image, 0, 0, factor);
+}
+
+static pdf_image *
+pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *cstm, int forcemask)
+{
+ fz_stream *stm = NULL;
+ pdf_image *image = NULL;
+ pdf_obj *obj, *res;
int w, h, bpc, n;
int imagemask;
int interpolate;
int indexed;
- fz_colorspace *colorspace = NULL;
- fz_pixmap *mask = NULL; /* explicit mask/softmask image */
+ fz_image *mask = NULL; /* explicit mask/softmask image */
int usecolorkey;
- int colorkey[FZ_MAX_COLORS * 2];
- float decode[FZ_MAX_COLORS * 2];
- int stride;
- unsigned char *samples = NULL;
- int i, len;
+ int i;
fz_context *ctx = xref->ctx;
fz_var(stm);
- fz_var(tile);
- fz_var(colorspace);
fz_var(mask);
- fz_var(samples);
+
+ image = fz_malloc_struct(ctx, pdf_image);
fz_try(ctx)
{
/* special case for JPEG2000 images */
if (pdf_is_jpx_image(ctx, dict))
{
- tile = pdf_load_jpx(xref, dict);
+ pdf_load_jpx(xref, dict, image);
/* RJW: "cannot load jpx image" */
if (forcemask)
{
- if (tile->n != 2)
+ fz_pixmap *mask_pixmap;
+ if (image->n != 2)
fz_throw(ctx, "softmask must be grayscale");
- mask = fz_alpha_from_gray(ctx, tile, 1);
- fz_drop_pixmap(ctx, tile);
- tile = mask;
- mask = NULL;
+ mask_pixmap = fz_alpha_from_gray(ctx, image->tile, 1);
+ fz_drop_pixmap(ctx, image->tile);
+ image->tile = mask_pixmap;
}
break; /* Out of fz_try */
}
- w = fz_to_int(fz_dict_getsa(dict, "Width", "W"));
- h = fz_to_int(fz_dict_getsa(dict, "Height", "H"));
- bpc = fz_to_int(fz_dict_getsa(dict, "BitsPerComponent", "BPC"));
- imagemask = fz_to_bool(fz_dict_getsa(dict, "ImageMask", "IM"));
- interpolate = fz_to_bool(fz_dict_getsa(dict, "Interpolate", "I"));
+ w = pdf_to_int(pdf_dict_getsa(dict, "Width", "W"));
+ h = pdf_to_int(pdf_dict_getsa(dict, "Height", "H"));
+ bpc = pdf_to_int(pdf_dict_getsa(dict, "BitsPerComponent", "BPC"));
+ imagemask = pdf_to_bool(pdf_dict_getsa(dict, "ImageMask", "IM"));
+ interpolate = pdf_to_bool(pdf_dict_getsa(dict, "Interpolate", "I"));
indexed = 0;
usecolorkey = 0;
@@ -98,212 +349,140 @@ pdf_load_image_imp(pdf_document *xref, fz_obj *rdb, fz_obj *dict, fz_stream *cst
if (h > (1 << 16))
fz_throw(ctx, "image is too high");
- obj = fz_dict_getsa(dict, "ColorSpace", "CS");
+ obj = pdf_dict_getsa(dict, "ColorSpace", "CS");
if (obj && !imagemask && !forcemask)
{
/* colorspace resource lookup is only done for inline images */
- if (fz_is_name(obj))
+ if (pdf_is_name(obj))
{
- res = fz_dict_get(fz_dict_gets(rdb, "ColorSpace"), obj);
+ res = pdf_dict_get(pdf_dict_gets(rdb, "ColorSpace"), obj);
if (res)
obj = res;
}
- colorspace = pdf_load_colorspace(xref, obj);
+ image->base.colorspace = pdf_load_colorspace(xref, obj);
/* RJW: "cannot load image colorspace" */
- if (!strcmp(colorspace->name, "Indexed"))
+ if (!strcmp(image->base.colorspace->name, "Indexed"))
indexed = 1;
- n = colorspace->n;
+ n = image->base.colorspace->n;
}
else
{
n = 1;
}
- obj = fz_dict_getsa(dict, "Decode", "D");
+ obj = pdf_dict_getsa(dict, "Decode", "D");
if (obj)
{
for (i = 0; i < n * 2; i++)
- decode[i] = fz_to_real(fz_array_get(obj, i));
+ image->decode[i] = pdf_to_real(pdf_array_get(obj, i));
}
else
{
float maxval = indexed ? (1 << bpc) - 1 : 1;
for (i = 0; i < n * 2; i++)
- decode[i] = i & 1 ? maxval : 0;
+ image->decode[i] = i & 1 ? maxval : 0;
}
- obj = fz_dict_getsa(dict, "SMask", "Mask");
- if (fz_is_dict(obj))
+ obj = pdf_dict_getsa(dict, "SMask", "Mask");
+ if (pdf_is_dict(obj))
{
/* Not allowed for inline images */
if (!cstm)
{
- mask = pdf_load_image_imp(xref, rdb, obj, NULL, 1);
+ mask = (fz_image *)pdf_load_image_imp(xref, rdb, obj, NULL, 1);
/* RJW: "cannot load image mask/softmask" */
}
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
usecolorkey = 1;
for (i = 0; i < n * 2; i++)
{
- if (!fz_is_int(fz_array_get(obj, i)))
+ if (!pdf_is_int(pdf_array_get(obj, i)))
{
fz_warn(ctx, "invalid value in color key mask");
usecolorkey = 0;
}
- colorkey[i] = fz_to_int(fz_array_get(obj, i));
+ image->colorkey[i] = pdf_to_int(pdf_array_get(obj, i));
}
}
- /* Allocate now, to fail early if we run out of memory */
- fz_try(ctx)
- {
- tile = fz_new_pixmap(ctx, colorspace, w, h);
- }
- fz_catch(ctx)
- {
- fz_drop_colorspace(ctx, colorspace);
- fz_rethrow(ctx);
- }
-
- if (colorspace)
+ /* Now, do we load a ref, or do we load the actual thing? */
+ image->params.type = PDF_IMAGE_RAW;
+ FZ_INIT_STORABLE(&image->base, 1, pdf_free_image);
+ image->base.get_pixmap = pdf_image_get_pixmap;
+ image->base.w = w;
+ image->base.h = h;
+ image->n = n;
+ image->bpc = bpc;
+ image->interpolate = interpolate;
+ image->imagemask = imagemask;
+ image->usecolorkey = usecolorkey;
+ image->base.mask = mask;
+ image->params.colorspace = image->base.colorspace; /* Uses the same ref as for the base one */
+ if (!indexed && !cstm)
{
- fz_drop_colorspace(ctx, colorspace);
- colorspace = NULL;
+ /* Just load the compressed image data now and we can
+ * decode it on demand. */
+ image->buffer = pdf_load_image_stream(xref, pdf_to_num(dict), pdf_to_gen(dict), &image->params);
+ break; /* Out of fz_try */
}
- tile->mask = mask;
- mask = NULL;
- tile->interpolate = interpolate;
-
- stride = (w * n * bpc + 7) / 8;
-
+ /* We need to decompress the image now */
if (cstm)
{
- stm = pdf_open_inline_stream(xref, dict, stride * h, cstm);
+ int stride = (w * image->n * image->bpc + 7) / 8;
+ stm = pdf_open_inline_stream(xref, dict, stride * h, cstm, NULL);
}
else
{
- stm = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict));
- /* RJW: "cannot open image data stream (%d 0 R)", fz_to_num(dict) */
- }
-
- samples = fz_malloc_array(ctx, h, stride);
-
- len = fz_read(stm, samples, h * stride);
- if (len < 0)
- {
- fz_throw(ctx, "cannot read image data");
- }
-
- /* Make sure we read the EOF marker (for inline images only) */
- if (cstm)
- {
- unsigned char tbuf[512];
- fz_try(ctx)
- {
- int tlen = fz_read(stm, tbuf, sizeof tbuf);
- if (tlen > 0)
- fz_warn(ctx, "ignoring garbage at end of image");
- }
- fz_catch(ctx)
- {
- fz_warn(ctx, "ignoring error at end of image");
- }
- }
-
- fz_close(stm);
- stm = NULL;
-
- /* Pad truncated images */
- if (len < stride * h)
- {
- fz_warn(ctx, "padding truncated image (%d 0 R)", fz_to_num(dict));
- memset(samples + len, 0, stride * h - len);
+ stm = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
+ /* RJW: "cannot open image data stream (%d 0 R)", pdf_to_num(dict) */
}
- /* Invert 1-bit image masks */
- if (imagemask)
- {
- /* 0=opaque and 1=transparent so we need to invert */
- unsigned char *p = samples;
- len = h * stride;
- for (i = 0; i < len; i++)
- p[i] = ~p[i];
- }
-
- fz_unpack_tile(tile, samples, n, bpc, stride, indexed);
-
- fz_free(ctx, samples);
- samples = NULL;
-
- if (usecolorkey)
- pdf_mask_color_key(tile, n, colorkey);
-
- if (indexed)
- {
- fz_pixmap *conv;
- fz_decode_indexed_tile(tile, decode, (1 << bpc) - 1);
- conv = pdf_expand_indexed_pixmap(ctx, tile);
- fz_drop_pixmap(ctx, tile);
- tile = conv;
- }
- else
- {
- fz_decode_tile(tile, decode);
- }
+ image->tile = decomp_image_from_stream(ctx, stm, image, cstm != NULL, indexed, 1);
}
fz_catch(ctx)
{
- if (colorspace)
- fz_drop_colorspace(ctx, colorspace);
- if (mask)
- fz_drop_pixmap(ctx, mask);
- if (tile)
- fz_drop_pixmap(ctx, tile);
- fz_close(stm);
- fz_free(ctx, samples);
-
+ fz_drop_image(ctx, &image->base);
fz_rethrow(ctx);
}
-
- return tile;
+ return image;
}
-fz_pixmap *
-pdf_load_inline_image(pdf_document *xref, fz_obj *rdb, fz_obj *dict, fz_stream *file)
+fz_image *
+pdf_load_inline_image(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *file)
{
- return pdf_load_image_imp(xref, rdb, dict, file, 0);
+ return (fz_image *)pdf_load_image_imp(xref, rdb, dict, file, 0);
/* RJW: "cannot load inline image" */
}
int
-pdf_is_jpx_image(fz_context *ctx, fz_obj *dict)
+pdf_is_jpx_image(fz_context *ctx, pdf_obj *dict)
{
- fz_obj *filter;
+ pdf_obj *filter;
int i, n;
- filter = fz_dict_gets(dict, "Filter");
- if (!strcmp(fz_to_name(filter), "JPXDecode"))
+ filter = pdf_dict_gets(dict, "Filter");
+ if (!strcmp(pdf_to_name(filter), "JPXDecode"))
return 1;
- n = fz_array_len(filter);
+ n = pdf_array_len(filter);
for (i = 0; i < n; i++)
- if (!strcmp(fz_to_name(fz_array_get(filter, i)), "JPXDecode"))
+ if (!strcmp(pdf_to_name(pdf_array_get(filter, i)), "JPXDecode"))
return 1;
return 0;
}
-static fz_pixmap *
-pdf_load_jpx(pdf_document *xref, fz_obj *dict)
+static void
+pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image)
{
fz_buffer *buf = NULL;
fz_colorspace *colorspace = NULL;
fz_pixmap *img = NULL;
- fz_obj *obj;
+ pdf_obj *obj;
fz_context *ctx = xref->ctx;
int indexed = 0;
@@ -311,13 +490,13 @@ pdf_load_jpx(pdf_document *xref, fz_obj *dict)
fz_var(buf);
fz_var(colorspace);
- buf = pdf_load_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ buf = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
/* RJW: "cannot load jpx image data" */
/* FIXME: We can't handle decode arrays for indexed images currently */
fz_try(ctx)
{
- obj = fz_dict_gets(dict, "ColorSpace");
+ obj = pdf_dict_gets(dict, "ColorSpace");
if (obj)
{
colorspace = pdf_load_colorspace(xref, obj);
@@ -328,29 +507,27 @@ pdf_load_jpx(pdf_document *xref, fz_obj *dict)
img = fz_load_jpx(ctx, buf->data, buf->len, colorspace);
/* RJW: "cannot load jpx image" */
- if (colorspace)
- {
- fz_drop_colorspace(ctx, colorspace);
- colorspace = NULL;
- }
+ if (img && colorspace == NULL)
+ colorspace = fz_keep_colorspace(ctx, img->colorspace);
+
fz_drop_buffer(ctx, buf);
buf = NULL;
- obj = fz_dict_getsa(dict, "SMask", "Mask");
- if (fz_is_dict(obj))
+ obj = pdf_dict_getsa(dict, "SMask", "Mask");
+ if (pdf_is_dict(obj))
{
- img->mask = pdf_load_image_imp(xref, NULL, obj, NULL, 1);
+ image->base.mask = (fz_image *)pdf_load_image_imp(xref, NULL, obj, NULL, 1);
/* RJW: "cannot load image mask/softmask" */
}
- obj = fz_dict_getsa(dict, "Decode", "D");
+ obj = pdf_dict_getsa(dict, "Decode", "D");
if (obj && !indexed)
{
float decode[FZ_MAX_COLORS * 2];
int i;
for (i = 0; i < img->n * 2; i++)
- decode[i] = fz_to_real(fz_array_get(obj, i));
+ decode[i] = pdf_to_real(pdf_array_get(obj, i));
fz_decode_tile(img, decode);
}
@@ -363,24 +540,44 @@ pdf_load_jpx(pdf_document *xref, fz_obj *dict)
fz_drop_pixmap(ctx, img);
fz_rethrow(ctx);
}
- return img;
+ image->params.type = PDF_IMAGE_RAW;
+ FZ_INIT_STORABLE(&image->base, 1, pdf_free_image);
+ image->base.get_pixmap = pdf_image_get_pixmap;
+ image->base.w = img->w;
+ image->base.h = img->h;
+ image->base.colorspace = colorspace;
+ image->tile = img;
+ image->n = img->n;
+ image->bpc = 8;
+ image->interpolate = 0;
+ image->imagemask = 0;
+ image->usecolorkey = 0;
+ image->params.colorspace = colorspace; /* Uses the same ref as for the base one */
+}
+
+static int
+pdf_image_size(fz_context *ctx, pdf_image *im)
+{
+ if (im == NULL)
+ return 0;
+ return sizeof(*im) + fz_pixmap_size(ctx, im->tile) + (im->buffer ? im->buffer->cap : 0);
}
-fz_pixmap *
-pdf_load_image(pdf_document *xref, fz_obj *dict)
+fz_image *
+pdf_load_image(pdf_document *xref, pdf_obj *dict)
{
fz_context *ctx = xref->ctx;
- fz_pixmap *pix;
+ pdf_image *image;
- if ((pix = fz_find_item(ctx, fz_free_pixmap_imp, dict)))
+ if ((image = pdf_find_item(ctx, pdf_free_image, dict)))
{
- return pix;
+ return (fz_image *)image;
}
- pix = pdf_load_image_imp(xref, NULL, dict, NULL, 0);
- /* RJW: "cannot load image (%d 0 R)", fz_to_num(dict) */
+ image = pdf_load_image_imp(xref, NULL, dict, NULL, 0);
+ /* RJW: "cannot load image (%d 0 R)", pdf_to_num(dict) */
- fz_store_item(ctx, dict, pix, fz_pixmap_size(ctx, pix));
+ pdf_store_item(ctx, dict, image, pdf_image_size(ctx, image));
- return pix;
+ return (fz_image *)image;
}
diff --git a/pdf/pdf_interpret.c b/pdf/pdf_interpret.c
index ea7f7692..3888b35f 100644
--- a/pdf/pdf_interpret.c
+++ b/pdf/pdf_interpret.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#define TILE
@@ -70,7 +70,7 @@ struct pdf_csi_s
char *event; /* "View", "Print", "Export" */
/* interpreter stack */
- fz_obj *obj;
+ pdf_obj *obj;
char name[256];
unsigned char string[256];
int string_len;
@@ -104,8 +104,8 @@ struct pdf_csi_s
fz_cookie *cookie;
};
-static void pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents);
-static void pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform);
+static void pdf_run_buffer(pdf_csi *csi, pdf_obj *rdb, fz_buffer *contents);
+static void pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix transform);
static void pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what);
static int
@@ -120,20 +120,20 @@ ocg_intents_include(pdf_ocg_descriptor *desc, char *name)
if (!desc->intent)
return (strcmp(name, "View") == 0);
- if (fz_is_name(desc->intent))
+ if (pdf_is_name(desc->intent))
{
- char *intent = fz_to_name(desc->intent);
+ char *intent = pdf_to_name(desc->intent);
if (strcmp(intent, "All") == 0)
return 1;
return (strcmp(intent, name) == 0);
}
- if (!fz_is_array(desc->intent))
+ if (!pdf_is_array(desc->intent))
return 0;
- len = fz_array_len(desc->intent);
+ len = pdf_array_len(desc->intent);
for (i=0; i < len; i++)
{
- char *intent = fz_to_name(fz_array_get(desc->intent, i));
+ char *intent = pdf_to_name(pdf_array_get(desc->intent, i));
if (strcmp(intent, "All") == 0)
return 1;
if (strcmp(intent, name) == 0)
@@ -143,10 +143,10 @@ ocg_intents_include(pdf_ocg_descriptor *desc, char *name)
}
static int
-pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
+pdf_is_hidden_ocg(pdf_obj *ocg, pdf_csi *csi, pdf_obj *rdb)
{
char event_state[16];
- fz_obj *obj, *obj2;
+ pdf_obj *obj, *obj2;
char *type;
pdf_ocg_descriptor *desc = csi->xref->ocg;
@@ -155,9 +155,9 @@ pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
return 0;
/* If we've been handed a name, look it up in the properties. */
- if (fz_is_name(ocg))
+ if (pdf_is_name(ocg))
{
- ocg = fz_dict_gets(fz_dict_gets(rdb, "Properties"), fz_to_name(ocg));
+ ocg = pdf_dict_gets(pdf_dict_gets(rdb, "Properties"), pdf_to_name(ocg));
}
/* If we haven't been given an ocg at all, then we're visible */
if (!ocg)
@@ -166,13 +166,13 @@ pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
fz_strlcpy(event_state, csi->event, sizeof event_state);
fz_strlcat(event_state, "State", sizeof event_state);
- type = fz_to_name(fz_dict_gets(ocg, "Type"));
+ type = pdf_to_name(pdf_dict_gets(ocg, "Type"));
if (strcmp(type, "OCG") == 0)
{
/* An Optional Content Group */
- int num = fz_to_num(ocg);
- int gen = fz_to_gen(ocg);
+ int num = pdf_to_num(ocg);
+ int gen = pdf_to_gen(ocg);
int len = desc->len;
int i;
@@ -188,19 +188,19 @@ pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
/* Check Intents; if our intent is not part of the set given
* by the current config, we should ignore it. */
- obj = fz_dict_gets(ocg, "Intent");
- if (fz_is_name(obj))
+ obj = pdf_dict_gets(ocg, "Intent");
+ if (pdf_is_name(obj))
{
/* If it doesn't match, it's hidden */
- if (ocg_intents_include(desc, fz_to_name(obj)) == 0)
+ if (ocg_intents_include(desc, pdf_to_name(obj)) == 0)
return 1;
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
int match = 0;
- len = fz_array_len(obj);
+ len = pdf_array_len(obj);
for (i=0; i<len; i++) {
- match |= ocg_intents_include(desc, fz_to_name(fz_array_get(obj, i)));
+ match |= ocg_intents_include(desc, pdf_to_name(pdf_array_get(obj, i)));
if (match)
break;
}
@@ -224,15 +224,15 @@ pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
* correspond to entries in the AS list in the OCG config.
* Given that we don't handle Zoom or User, or Language
* dicts, this is not really a problem. */
- obj = fz_dict_gets(ocg, "Usage");
- if (!fz_is_dict(obj))
+ obj = pdf_dict_gets(ocg, "Usage");
+ if (!pdf_is_dict(obj))
return 0;
/* FIXME: Should look at Zoom (and return hidden if out of
* max/min range) */
/* FIXME: Could provide hooks to the caller to check if
* User is appropriate - if not return hidden. */
- obj2 = fz_dict_gets(obj, csi->event);
- if (strcmp(fz_to_name(fz_dict_gets(obj2, event_state)), "OFF") == 0)
+ obj2 = pdf_dict_gets(obj, csi->event);
+ if (strcmp(pdf_to_name(pdf_dict_gets(obj2, event_state)), "OFF") == 0)
{
return 1;
}
@@ -244,12 +244,12 @@ pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
char *name;
int combine, on;
- obj = fz_dict_gets(ocg, "VE");
- if (fz_is_array(obj)) {
+ obj = pdf_dict_gets(ocg, "VE");
+ if (pdf_is_array(obj)) {
/* FIXME: Calculate visibility from array */
return 0;
}
- name = fz_to_name(fz_dict_gets(ocg, "P"));
+ name = pdf_to_name(pdf_dict_gets(ocg, "P"));
/* Set combine; Bit 0 set => AND, Bit 1 set => true means
* Off, otherwise true means On */
if (strcmp(name, "AllOn") == 0)
@@ -269,15 +269,15 @@ pdf_is_hidden_ocg(fz_obj *ocg, pdf_csi *csi, fz_obj *rdb)
combine = 0;
}
- obj = fz_dict_gets(ocg, "OCGs");
+ obj = pdf_dict_gets(ocg, "OCGs");
on = combine & 1;
- if (fz_is_array(obj)) {
+ if (pdf_is_array(obj)) {
int i, len;
- len = fz_array_len(obj);
+ len = pdf_array_len(obj);
for (i = 0; i < len; i++)
{
int hidden;
- hidden = pdf_is_hidden_ocg(fz_array_get(obj, i), csi, rdb);
+ hidden = pdf_is_hidden_ocg(pdf_array_get(obj, i), csi, rdb);
if ((combine & 1) == 0)
hidden = !hidden;
if (combine & 2)
@@ -362,7 +362,7 @@ pdf_show_shade(pdf_csi *csi, fz_shade *shd)
}
static void
-pdf_show_image(pdf_csi *csi, fz_pixmap *image)
+pdf_show_image(pdf_csi *csi, fz_image *image)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
fz_matrix image_ctm;
@@ -709,7 +709,7 @@ pdf_show_char(pdf_csi *csi, int cid)
if (fontdesc->wmode == 1)
{
- v = pdf_get_vmtx(ctx, fontdesc, cid);
+ v = pdf_lookup_vmtx(ctx, fontdesc, cid);
tsm.e -= v.x * gstate->size * 0.001f;
tsm.f -= v.y * gstate->size * 0.001f;
}
@@ -767,7 +767,7 @@ pdf_show_char(pdf_csi *csi, int cid)
if (fontdesc->wmode == 0)
{
- h = pdf_get_hmtx(ctx, fontdesc, cid);
+ h = pdf_lookup_hmtx(ctx, fontdesc, cid);
w0 = h.w * 0.001f;
tx = (w0 * gstate->size + gstate->char_space) * gstate->scale;
csi->tm = fz_concat(fz_translate(tx, 0), csi->tm);
@@ -819,6 +819,7 @@ pdf_show_string(pdf_csi *csi, unsigned char *buf, int len)
{
int w = pdf_decode_cmap(fontdesc->encoding, buf, &cpt);
buf += w;
+
cid = pdf_lookup_cmap(fontdesc->encoding, cpt);
if (cid >= 0)
pdf_show_char(csi, cid);
@@ -830,26 +831,26 @@ pdf_show_string(pdf_csi *csi, unsigned char *buf, int len)
}
static void
-pdf_show_text(pdf_csi *csi, fz_obj *text)
+pdf_show_text(pdf_csi *csi, pdf_obj *text)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
int i;
- if (fz_is_array(text))
+ if (pdf_is_array(text))
{
- int n = fz_array_len(text);
+ int n = pdf_array_len(text);
for (i = 0; i < n; i++)
{
- fz_obj *item = fz_array_get(text, i);
- if (fz_is_string(item))
- pdf_show_string(csi, (unsigned char *)fz_to_str_buf(item), fz_to_str_len(item));
+ pdf_obj *item = pdf_array_get(text, i);
+ if (pdf_is_string(item))
+ pdf_show_string(csi, (unsigned char *)pdf_to_str_buf(item), pdf_to_str_len(item));
else
- pdf_show_space(csi, - fz_to_real(item) * gstate->size * 0.001f);
+ pdf_show_space(csi, - pdf_to_real(item) * gstate->size * 0.001f);
}
}
- else if (fz_is_string(text))
+ else if (pdf_is_string(text))
{
- pdf_show_string(csi, (unsigned char *)fz_to_str_buf(text), fz_to_str_len(text));
+ pdf_show_string(csi, (unsigned char *)pdf_to_str_buf(text), pdf_to_str_len(text));
}
}
@@ -1003,7 +1004,7 @@ pdf_clear_stack(pdf_csi *csi)
int i;
if (csi->obj)
- fz_drop_obj(csi->obj);
+ pdf_drop_obj(csi->obj);
csi->obj = NULL;
csi->name[0] = 0;
@@ -1334,7 +1335,7 @@ pdf_show_pattern(pdf_csi *csi, pdf_pattern *pat, fz_rect area, int what)
}
static void
-pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix transform)
+pdf_run_xobject(pdf_csi *csi, pdf_obj *resources, pdf_xobject *xobj, fz_matrix transform)
{
fz_context *ctx = csi->dev->ctx;
pdf_gstate *gstate = NULL;
@@ -1343,7 +1344,7 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
int popmask;
/* Avoid infinite recursion */
- if (xobj == NULL || fz_dict_mark(xobj->me))
+ if (xobj == NULL || pdf_dict_mark(xobj->me))
return;
fz_var(gstate);
@@ -1424,7 +1425,7 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
pdf_grestore(csi);
}
- fz_dict_unmark(xobj->me);
+ pdf_dict_unmark(xobj->me);
}
fz_catch(ctx)
{
@@ -1441,7 +1442,7 @@ pdf_run_xobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj, fz_matrix tr
}
static void
-pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
+pdf_run_extgstate(pdf_csi *csi, pdf_obj *rdb, pdf_obj *extgstate)
{
fz_context *ctx = csi->dev->ctx;
pdf_gstate *gstate = csi->gstate + csi->gtop;
@@ -1450,18 +1451,18 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
pdf_flush_text(csi);
- n = fz_dict_len(extgstate);
+ n = pdf_dict_len(extgstate);
for (i = 0; i < n; i++)
{
- fz_obj *key = fz_dict_get_key(extgstate, i);
- fz_obj *val = fz_dict_get_val(extgstate, i);
- char *s = fz_to_name(key);
+ pdf_obj *key = pdf_dict_get_key(extgstate, i);
+ pdf_obj *val = pdf_dict_get_val(extgstate, i);
+ char *s = pdf_to_name(key);
if (!strcmp(s, "Font"))
{
- if (fz_is_array(val) && fz_array_len(val) == 2)
+ if (pdf_is_array(val) && pdf_array_len(val) == 2)
{
- fz_obj *font = fz_array_get(val, 0);
+ pdf_obj *font = pdf_array_get(val, 0);
if (gstate->font)
{
@@ -1470,10 +1471,10 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
}
gstate->font = pdf_load_font(csi->xref, rdb, font);
- /* RJW: "cannot load font (%d %d R)", fz_to_num(font), fz_to_gen(font) */
+ /* RJW: "cannot load font (%d %d R)", pdf_to_num(font), pdf_to_gen(font) */
if (!gstate->font)
fz_throw(ctx, "cannot find font in store");
- gstate->size = fz_to_real(fz_array_get(val, 1));
+ gstate->size = pdf_to_real(pdf_array_get(val, 1));
}
else
fz_throw(ctx, "malformed /Font dictionary");
@@ -1482,59 +1483,59 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
else if (!strcmp(s, "LC"))
{
csi->dev->flags &= ~(FZ_DEVFLAG_STARTCAP_UNDEFINED | FZ_DEVFLAG_DASHCAP_UNDEFINED | FZ_DEVFLAG_ENDCAP_UNDEFINED);
- gstate->stroke_state.start_cap = fz_to_int(val);
- gstate->stroke_state.dash_cap = fz_to_int(val);
- gstate->stroke_state.end_cap = fz_to_int(val);
+ gstate->stroke_state.start_cap = pdf_to_int(val);
+ gstate->stroke_state.dash_cap = pdf_to_int(val);
+ gstate->stroke_state.end_cap = pdf_to_int(val);
}
else if (!strcmp(s, "LW"))
{
csi->dev->flags &= ~FZ_DEVFLAG_LINEWIDTH_UNDEFINED;
- gstate->stroke_state.linewidth = fz_to_real(val);
+ gstate->stroke_state.linewidth = pdf_to_real(val);
}
else if (!strcmp(s, "LJ"))
{
csi->dev->flags &= ~FZ_DEVFLAG_LINEJOIN_UNDEFINED;
- gstate->stroke_state.linejoin = fz_to_int(val);
+ gstate->stroke_state.linejoin = pdf_to_int(val);
}
else if (!strcmp(s, "ML"))
{
csi->dev->flags &= ~FZ_DEVFLAG_MITERLIMIT_UNDEFINED;
- gstate->stroke_state.miterlimit = fz_to_real(val);
+ gstate->stroke_state.miterlimit = pdf_to_real(val);
}
else if (!strcmp(s, "D"))
{
- if (fz_is_array(val) && fz_array_len(val) == 2)
+ if (pdf_is_array(val) && pdf_array_len(val) == 2)
{
- fz_obj *dashes = fz_array_get(val, 0);
- gstate->stroke_state.dash_len = MAX(fz_array_len(dashes), 32);
+ pdf_obj *dashes = pdf_array_get(val, 0);
+ gstate->stroke_state.dash_len = MAX(pdf_array_len(dashes), 32);
for (k = 0; k < gstate->stroke_state.dash_len; k++)
- gstate->stroke_state.dash_list[k] = fz_to_real(fz_array_get(dashes, k));
- gstate->stroke_state.dash_phase = fz_to_real(fz_array_get(val, 1));
+ gstate->stroke_state.dash_list[k] = pdf_to_real(pdf_array_get(dashes, k));
+ gstate->stroke_state.dash_phase = pdf_to_real(pdf_array_get(val, 1));
}
else
fz_throw(ctx, "malformed /D");
}
else if (!strcmp(s, "CA"))
- gstate->stroke.alpha = fz_to_real(val);
+ gstate->stroke.alpha = pdf_to_real(val);
else if (!strcmp(s, "ca"))
- gstate->fill.alpha = fz_to_real(val);
+ gstate->fill.alpha = pdf_to_real(val);
else if (!strcmp(s, "BM"))
{
- if (fz_is_array(val))
- val = fz_array_get(val, 0);
- gstate->blendmode = fz_find_blendmode(fz_to_name(val));
+ if (pdf_is_array(val))
+ val = pdf_array_get(val, 0);
+ gstate->blendmode = fz_lookup_blendmode(pdf_to_name(val));
}
else if (!strcmp(s, "SMask"))
{
- if (fz_is_dict(val))
+ if (pdf_is_dict(val))
{
pdf_xobject *xobj;
- fz_obj *group, *luminosity, *bc;
+ pdf_obj *group, *luminosity, *bc;
if (gstate->softmask)
{
@@ -1542,11 +1543,11 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
gstate->softmask = NULL;
}
- group = fz_dict_gets(val, "G");
+ group = pdf_dict_gets(val, "G");
if (!group)
- fz_throw(ctx, "cannot load softmask xobject (%d %d R)", fz_to_num(val), fz_to_gen(val));
+ fz_throw(ctx, "cannot load softmask xobject (%d %d R)", pdf_to_num(val), pdf_to_gen(val));
xobj = pdf_load_xobject(csi->xref, group);
- /* RJW: "cannot load xobject (%d %d R)", fz_to_num(val), fz_to_gen(val) */
+ /* RJW: "cannot load xobject (%d %d R)", pdf_to_num(val), pdf_to_gen(val) */
colorspace = xobj->colorspace;
if (!colorspace)
@@ -1557,20 +1558,20 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
for (k = 0; k < colorspace->n; k++)
gstate->softmask_bc[k] = 0;
- bc = fz_dict_gets(val, "BC");
- if (fz_is_array(bc))
+ bc = pdf_dict_gets(val, "BC");
+ if (pdf_is_array(bc))
{
for (k = 0; k < colorspace->n; k++)
- gstate->softmask_bc[k] = fz_to_real(fz_array_get(bc, k));
+ gstate->softmask_bc[k] = pdf_to_real(pdf_array_get(bc, k));
}
- luminosity = fz_dict_gets(val, "S");
- if (fz_is_name(luminosity) && !strcmp(fz_to_name(luminosity), "Luminosity"))
+ luminosity = pdf_dict_gets(val, "S");
+ if (pdf_is_name(luminosity) && !strcmp(pdf_to_name(luminosity), "Luminosity"))
gstate->luminosity = 1;
else
gstate->luminosity = 0;
}
- else if (fz_is_name(val) && !strcmp(fz_to_name(val), "None"))
+ else if (pdf_is_name(val) && !strcmp(pdf_to_name(val), "None"))
{
if (gstate->softmask)
{
@@ -1582,7 +1583,7 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
else if (!strcmp(s, "TR"))
{
- if (!fz_is_name(val) || strcmp(fz_to_name(val), "Identity"))
+ if (!pdf_is_name(val) || strcmp(pdf_to_name(val), "Identity"))
fz_warn(ctx, "ignoring transfer function");
}
}
@@ -1592,9 +1593,9 @@ pdf_run_extgstate(pdf_csi *csi, fz_obj *rdb, fz_obj *extgstate)
* Operators
*/
-static void pdf_run_BDC(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_BDC(pdf_csi *csi, pdf_obj *rdb)
{
- fz_obj *ocg;
+ pdf_obj *ocg;
/* If we are already in a hidden OCG, then we'll still be hidden -
* just increment the depth so we pop back to visibility when we've
@@ -1605,14 +1606,14 @@ static void pdf_run_BDC(pdf_csi *csi, fz_obj *rdb)
return;
}
- ocg = fz_dict_gets(fz_dict_gets(rdb, "Properties"), csi->name);
+ ocg = pdf_dict_gets(pdf_dict_gets(rdb, "Properties"), csi->name);
if (!ocg)
{
/* No Properties array, or name not found in the properties
* means visible. */
return;
}
- if (strcmp(fz_to_name(fz_dict_gets(ocg, "Type")), "OCG") != 0)
+ if (strcmp(pdf_to_name(pdf_dict_gets(ocg, "Type")), "OCG") != 0)
{
/* Wrong type of property */
return;
@@ -1621,16 +1622,14 @@ static void pdf_run_BDC(pdf_csi *csi, fz_obj *rdb)
csi->in_hidden_ocg++;
}
-static void pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file)
+static void pdf_run_BI(pdf_csi *csi, pdf_obj *rdb, fz_stream *file)
{
fz_context *ctx = csi->dev->ctx;
int ch;
- char *buf = csi->xref->scratch;
- int buflen = sizeof(csi->xref->scratch);
- fz_pixmap *img;
- fz_obj *obj;
+ fz_image *img;
+ pdf_obj *obj;
- obj = pdf_parse_dict(csi->xref, file, buf, buflen);
+ obj = pdf_parse_dict(csi->xref, file, &csi->xref->lexbuf.base);
/* RJW: "cannot parse inline image dictionary" */
/* read whitespace after ID keyword */
@@ -1640,12 +1639,12 @@ static void pdf_run_BI(pdf_csi *csi, fz_obj *rdb, fz_stream *file)
fz_read_byte(file);
img = pdf_load_inline_image(csi->xref, rdb, obj, file);
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
/* RJW: "cannot load inline image" */
pdf_show_image(csi, img);
- fz_drop_pixmap(ctx, img);
+ fz_drop_image(ctx, img);
/* find EI */
ch = fz_read_byte(file);
@@ -1689,11 +1688,11 @@ static void pdf_run_Bstar(pdf_csi *csi)
pdf_show_path(csi, 0, 1, 1, 1);
}
-static void pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what)
+static void pdf_run_cs_imp(pdf_csi *csi, pdf_obj *rdb, int what)
{
fz_context *ctx = csi->dev->ctx;
fz_colorspace *colorspace;
- fz_obj *obj, *dict;
+ pdf_obj *obj, *dict;
if (!strcmp(csi->name, "Pattern"))
{
@@ -1709,14 +1708,14 @@ static void pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what)
colorspace = fz_device_cmyk; /* No fz_keep_colorspace as static */
else
{
- dict = fz_dict_gets(rdb, "ColorSpace");
+ dict = pdf_dict_gets(rdb, "ColorSpace");
if (!dict)
fz_throw(ctx, "cannot find ColorSpace dictionary");
- obj = fz_dict_gets(dict, csi->name);
+ obj = pdf_dict_gets(dict, csi->name);
if (!obj)
fz_throw(ctx, "cannot find colorspace resource '%s'", csi->name);
colorspace = pdf_load_colorspace(csi->xref, obj);
- /* RJW: "cannot load colorspace (%d 0 R)", fz_to_num(obj) */
+ /* RJW: "cannot load colorspace (%d 0 R)", pdf_to_num(obj) */
}
pdf_set_colorspace(csi, what, colorspace);
@@ -1725,7 +1724,7 @@ static void pdf_run_cs_imp(pdf_csi *csi, fz_obj *rdb, int what)
}
}
-static void pdf_run_CS(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_CS(pdf_csi *csi, pdf_obj *rdb)
{
csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
@@ -1733,7 +1732,7 @@ static void pdf_run_CS(pdf_csi *csi, fz_obj *rdb)
/* RJW: "cannot set colorspace" */
}
-static void pdf_run_cs(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_cs(pdf_csi *csi, pdf_obj *rdb)
{
csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
@@ -1745,41 +1744,41 @@ static void pdf_run_DP(pdf_csi *csi)
{
}
-static void pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_Do(pdf_csi *csi, pdf_obj *rdb)
{
fz_context *ctx = csi->dev->ctx;
- fz_obj *dict;
- fz_obj *obj;
- fz_obj *subtype;
+ pdf_obj *dict;
+ pdf_obj *obj;
+ pdf_obj *subtype;
- dict = fz_dict_gets(rdb, "XObject");
+ dict = pdf_dict_gets(rdb, "XObject");
if (!dict)
fz_throw(ctx, "cannot find XObject dictionary when looking for: '%s'", csi->name);
- obj = fz_dict_gets(dict, csi->name);
+ obj = pdf_dict_gets(dict, csi->name);
if (!obj)
fz_throw(ctx, "cannot find xobject resource: '%s'", csi->name);
- subtype = fz_dict_gets(obj, "Subtype");
- if (!fz_is_name(subtype))
+ subtype = pdf_dict_gets(obj, "Subtype");
+ if (!pdf_is_name(subtype))
fz_throw(ctx, "no XObject subtype specified");
- if (pdf_is_hidden_ocg(fz_dict_gets(obj, "OC"), csi, rdb))
+ if (pdf_is_hidden_ocg(pdf_dict_gets(obj, "OC"), csi, rdb))
return;
- if (!strcmp(fz_to_name(subtype), "Form") && fz_dict_gets(obj, "Subtype2"))
- subtype = fz_dict_gets(obj, "Subtype2");
+ if (!strcmp(pdf_to_name(subtype), "Form") && pdf_dict_gets(obj, "Subtype2"))
+ subtype = pdf_dict_gets(obj, "Subtype2");
- if (!strcmp(fz_to_name(subtype), "Form"))
+ if (!strcmp(pdf_to_name(subtype), "Form"))
{
pdf_xobject *xobj;
xobj = pdf_load_xobject(csi->xref, obj);
- /* RJW: "cannot load xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ /* RJW: "cannot load xobject (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
/* Inherit parent resources, in case this one was empty XXX check where it's loaded */
if (!xobj->resources)
- xobj->resources = fz_keep_obj(rdb);
+ xobj->resources = pdf_keep_obj(rdb);
fz_try(ctx)
{
@@ -1788,40 +1787,41 @@ static void pdf_run_Do(pdf_csi *csi, fz_obj *rdb)
fz_catch(ctx)
{
pdf_drop_xobject(ctx, xobj);
- fz_throw(ctx, "cannot draw xobject (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ fz_throw(ctx, "cannot draw xobject (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
}
pdf_drop_xobject(ctx, xobj);
}
- else if (!strcmp(fz_to_name(subtype), "Image"))
+ else if (!strcmp(pdf_to_name(subtype), "Image"))
{
if ((csi->dev->hints & FZ_IGNORE_IMAGE) == 0)
{
- fz_pixmap *img;
- img = pdf_load_image(csi->xref, obj);
- /* RJW: "cannot load image (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ fz_image *img = pdf_load_image(csi->xref, obj);
+ /* RJW: "cannot load image (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
fz_try(ctx)
{
pdf_show_image(csi, img);
}
+ fz_always(ctx)
+ {
+ fz_drop_image(ctx, img);
+ }
fz_catch(ctx)
{
- fz_drop_pixmap(ctx, img);
fz_rethrow(ctx);
}
- fz_drop_pixmap(ctx, img);
}
}
- else if (!strcmp(fz_to_name(subtype), "PS"))
+ else if (!strcmp(pdf_to_name(subtype), "PS"))
{
fz_warn(ctx, "ignoring XObject with subtype PS");
}
else
{
- fz_throw(ctx, "unknown XObject subtype: '%s'", fz_to_name(subtype));
+ fz_throw(ctx, "unknown XObject subtype: '%s'", pdf_to_name(subtype));
}
}
@@ -1899,12 +1899,12 @@ static void pdf_run_S(pdf_csi *csi)
pdf_show_path(csi, 0, 0, 1, 0);
}
-static void pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *mat)
+static void pdf_run_SC_imp(pdf_csi *csi, pdf_obj *rdb, int what, pdf_material *mat)
{
fz_context *ctx = csi->dev->ctx;
- fz_obj *patterntype;
- fz_obj *dict;
- fz_obj *obj;
+ pdf_obj *patterntype;
+ pdf_obj *dict;
+ pdf_obj *obj;
int kind;
kind = mat->kind;
@@ -1921,35 +1921,35 @@ static void pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *ma
break;
case PDF_MAT_PATTERN:
- dict = fz_dict_gets(rdb, "Pattern");
+ dict = pdf_dict_gets(rdb, "Pattern");
if (!dict)
fz_throw(ctx, "cannot find Pattern dictionary");
- obj = fz_dict_gets(dict, csi->name);
+ obj = pdf_dict_gets(dict, csi->name);
if (!obj)
fz_throw(ctx, "cannot find pattern resource '%s'", csi->name);
- patterntype = fz_dict_gets(obj, "PatternType");
+ patterntype = pdf_dict_gets(obj, "PatternType");
- if (fz_to_int(patterntype) == 1)
+ if (pdf_to_int(patterntype) == 1)
{
pdf_pattern *pat;
pat = pdf_load_pattern(csi->xref, obj);
- /* RJW: "cannot load pattern (%d 0 R)", fz_to_num(obj) */
+ /* RJW: "cannot load pattern (%d 0 R)", pdf_to_num(obj) */
pdf_set_pattern(csi, what, pat, csi->top > 0 ? csi->stack : NULL);
pdf_drop_pattern(ctx, pat);
}
- else if (fz_to_int(patterntype) == 2)
+ else if (pdf_to_int(patterntype) == 2)
{
fz_shade *shd;
shd = pdf_load_shading(csi->xref, obj);
- /* RJW: "cannot load shading (%d 0 R)", fz_to_num(obj) */
+ /* RJW: "cannot load shading (%d 0 R)", pdf_to_num(obj) */
pdf_set_shade(csi, what, shd);
fz_drop_shade(ctx, shd);
}
else
{
- fz_throw(ctx, "unknown pattern type: %d", fz_to_int(patterntype));
+ fz_throw(ctx, "unknown pattern type: %d", pdf_to_int(patterntype));
}
break;
@@ -1958,7 +1958,7 @@ static void pdf_run_SC_imp(pdf_csi *csi, fz_obj *rdb, int what, pdf_material *ma
}
}
-static void pdf_run_SC(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_SC(pdf_csi *csi, pdf_obj *rdb)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
csi->dev->flags &= ~FZ_DEVFLAG_STROKECOLOR_UNDEFINED;
@@ -1966,7 +1966,7 @@ static void pdf_run_SC(pdf_csi *csi, fz_obj *rdb)
/* RJW: "cannot set color and colorspace" */
}
-static void pdf_run_sc(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_sc(pdf_csi *csi, pdf_obj *rdb)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
csi->dev->flags &= ~FZ_DEVFLAG_FILLCOLOR_UNDEFINED;
@@ -2000,28 +2000,28 @@ static void pdf_run_TL(pdf_csi *csi)
gstate->leading = csi->stack[0];
}
-static void pdf_run_Tf(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_Tf(pdf_csi *csi, pdf_obj *rdb)
{
fz_context *ctx = csi->dev->ctx;
pdf_gstate *gstate = csi->gstate + csi->gtop;
- fz_obj *dict;
- fz_obj *obj;
+ pdf_obj *dict;
+ pdf_obj *obj;
gstate->size = csi->stack[0];
if (gstate->font)
pdf_drop_font(ctx, gstate->font);
gstate->font = NULL;
- dict = fz_dict_gets(rdb, "Font");
+ dict = pdf_dict_gets(rdb, "Font");
if (!dict)
fz_throw(ctx, "cannot find Font dictionary");
- obj = fz_dict_gets(dict, csi->name);
+ obj = pdf_dict_gets(dict, csi->name);
if (!obj)
fz_throw(ctx, "cannot find font resource: '%s'", csi->name);
gstate->font = pdf_load_font(csi->xref, rdb, obj);
- /* RJW: "cannot load font (%d 0 R)", fz_to_num(obj) */
+ /* RJW: "cannot load font (%d 0 R)", pdf_to_num(obj) */
}
static void pdf_run_Tr(pdf_csi *csi)
@@ -2141,13 +2141,13 @@ static void pdf_run_cm(pdf_csi *csi)
static void pdf_run_d(pdf_csi *csi)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- fz_obj *array;
+ pdf_obj *array;
int i;
array = csi->obj;
- gstate->stroke_state.dash_len = MIN(fz_array_len(array), nelem(gstate->stroke_state.dash_list));
+ gstate->stroke_state.dash_len = MIN(pdf_array_len(array), nelem(gstate->stroke_state.dash_list));
for (i = 0; i < gstate->stroke_state.dash_len; i++)
- gstate->stroke_state.dash_list[i] = fz_to_real(fz_array_get(array, i));
+ gstate->stroke_state.dash_list[i] = pdf_to_real(pdf_array_get(array, i));
gstate->stroke_state.dash_phase = csi->stack[0];
}
@@ -2186,22 +2186,22 @@ static void pdf_run_g(pdf_csi *csi)
pdf_set_color(csi, PDF_FILL, csi->stack);
}
-static void pdf_run_gs(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_gs(pdf_csi *csi, pdf_obj *rdb)
{
- fz_obj *dict;
- fz_obj *obj;
+ pdf_obj *dict;
+ pdf_obj *obj;
fz_context *ctx = csi->dev->ctx;
- dict = fz_dict_gets(rdb, "ExtGState");
+ dict = pdf_dict_gets(rdb, "ExtGState");
if (!dict)
fz_throw(ctx, "cannot find ExtGState dictionary");
- obj = fz_dict_gets(dict, csi->name);
+ obj = pdf_dict_gets(dict, csi->name);
if (!obj)
fz_throw(ctx, "cannot find extgstate resource '%s'", csi->name);
pdf_run_extgstate(csi, rdb, obj);
- /* RJW: "cannot set ExtGState (%d 0 R)", fz_to_num(obj) */
+ /* RJW: "cannot set ExtGState (%d 0 R)", pdf_to_num(obj) */
}
static void pdf_run_h(pdf_csi *csi)
@@ -2286,25 +2286,25 @@ static void pdf_run(pdf_csi *csi)
pdf_show_path(csi, 1, 0, 1, 0);
}
-static void pdf_run_sh(pdf_csi *csi, fz_obj *rdb)
+static void pdf_run_sh(pdf_csi *csi, pdf_obj *rdb)
{
fz_context *ctx = csi->dev->ctx;
- fz_obj *dict;
- fz_obj *obj;
+ pdf_obj *dict;
+ pdf_obj *obj;
fz_shade *shd;
- dict = fz_dict_gets(rdb, "Shading");
+ dict = pdf_dict_gets(rdb, "Shading");
if (!dict)
fz_throw(ctx, "cannot find shading dictionary");
- obj = fz_dict_gets(dict, csi->name);
+ obj = pdf_dict_gets(dict, csi->name);
if (!obj)
fz_throw(ctx, "cannot find shading resource: '%s'", csi->name);
if ((csi->dev->hints & FZ_IGNORE_SHADE) == 0)
{
shd = pdf_load_shading(csi->xref, obj);
- /* RJW: "cannot load shading (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ /* RJW: "cannot load shading (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
fz_try(ctx)
{
pdf_show_shade(csi, shd);
@@ -2384,7 +2384,7 @@ static void pdf_run_dquote(pdf_csi *csi)
#define C(a,b,c) (a | b << 8 | c << 16)
static void
-pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf)
+pdf_run_keyword(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, char *buf)
{
fz_context *ctx = csi->dev->ctx;
int key;
@@ -2522,10 +2522,10 @@ pdf_run_keyword(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf)
}
static void
-pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen)
+pdf_run_stream(pdf_csi *csi, pdf_obj *rdb, fz_stream *file, pdf_lexbuf *buf)
{
fz_context *ctx = csi->dev->ctx;
- int tok, len, in_array;
+ int tok, in_array;
/* make sure we have a clean slate if we come here from flush_text */
pdf_clear_stack(csi);
@@ -2550,7 +2550,7 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
csi->cookie->progress++;
}
- tok = pdf_lex(file, buf, buflen, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "lexical error in content stream" */
if (in_array)
@@ -2559,19 +2559,24 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
{
in_array = 0;
}
- else if (tok == PDF_TOK_INT || tok == PDF_TOK_REAL)
+ else if (tok == PDF_TOK_REAL)
+ {
+ pdf_gstate *gstate = csi->gstate + csi->gtop;
+ pdf_show_space(csi, -buf->f * gstate->size * 0.001f);
+ }
+ else if (tok == PDF_TOK_INT)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- pdf_show_space(csi, -fz_atof(buf) * gstate->size * 0.001f);
+ pdf_show_space(csi, -buf->i * gstate->size * 0.001f);
}
else if (tok == PDF_TOK_STRING)
{
- pdf_show_string(csi, (unsigned char *)buf, len);
+ pdf_show_string(csi, (unsigned char *)buf->scratch, buf->len);
}
else if (tok == PDF_TOK_KEYWORD)
{
- if (!strcmp(buf, "Tw") || !strcmp(buf, "Tc"))
- fz_warn(ctx, "ignoring keyword '%s' inside array", buf);
+ if (!strcmp(buf->scratch, "Tw") || !strcmp(buf->scratch, "Tc"))
+ fz_warn(ctx, "ignoring keyword '%s' inside array", buf->scratch);
else
fz_throw(ctx, "syntax error in array");
}
@@ -2590,7 +2595,7 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
case PDF_TOK_OPEN_ARRAY:
if (!csi->in_text)
{
- csi->obj = pdf_parse_array(csi->xref, file, buf, buflen);
+ csi->obj = pdf_parse_array(csi->xref, file, buf);
/* RJW: "cannot parse array" */
}
else
@@ -2600,38 +2605,38 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
break;
case PDF_TOK_OPEN_DICT:
- csi->obj = pdf_parse_dict(csi->xref, file, buf, buflen);
+ csi->obj = pdf_parse_dict(csi->xref, file, buf);
/* RJW: "cannot parse dictionary" */
break;
case PDF_TOK_NAME:
- fz_strlcpy(csi->name, buf, sizeof(csi->name));
+ fz_strlcpy(csi->name, buf->scratch, sizeof(csi->name));
break;
case PDF_TOK_INT:
- csi->stack[csi->top] = atoi(buf);
+ csi->stack[csi->top] = buf->i;
csi->top ++;
break;
case PDF_TOK_REAL:
- csi->stack[csi->top] = fz_atof(buf);
+ csi->stack[csi->top] = buf->f;
csi->top ++;
break;
case PDF_TOK_STRING:
- if (len <= sizeof(csi->string))
+ if (buf->len <= sizeof(csi->string))
{
- memcpy(csi->string, buf, len);
- csi->string_len = len;
+ memcpy(csi->string, buf->scratch, buf->len);
+ csi->string_len = buf->len;
}
else
{
- csi->obj = fz_new_string(ctx, buf, len);
+ csi->obj = pdf_new_string(ctx, buf->scratch, buf->len);
}
break;
case PDF_TOK_KEYWORD:
- pdf_run_keyword(csi, rdb, file, buf);
+ pdf_run_keyword(csi, rdb, file, buf->scratch);
/* RJW: "cannot run keyword" */
pdf_clear_stack(csi);
break;
@@ -2647,11 +2652,10 @@ pdf_run_stream(pdf_csi *csi, fz_obj *rdb, fz_stream *file, char *buf, int buflen
*/
static void
-pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
+pdf_run_buffer(pdf_csi *csi, pdf_obj *rdb, fz_buffer *contents)
{
fz_context *ctx = csi->dev->ctx;
- int len = sizeof csi->xref->scratch;
- char *buf = NULL;
+ pdf_lexbuf_large *buf;
fz_stream * file = NULL;
int save_in_text;
@@ -2663,13 +2667,14 @@ pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
fz_try(ctx)
{
- buf = fz_malloc(ctx, len); /* we must be re-entrant for type3 fonts */
+ buf = fz_malloc(ctx, sizeof(*buf)); /* we must be re-entrant for type3 fonts */
+ buf->base.size = PDF_LEXBUF_LARGE;
file = fz_open_buffer(ctx, contents);
save_in_text = csi->in_text;
csi->in_text = 0;
fz_try(ctx)
{
- pdf_run_stream(csi, rdb, file, buf, len);
+ pdf_run_stream(csi, rdb, file, &buf->base);
}
fz_catch(ctx)
{
@@ -2677,14 +2682,15 @@ pdf_run_buffer(pdf_csi *csi, fz_obj *rdb, fz_buffer *contents)
}
csi->in_text = save_in_text;
}
- fz_catch(ctx)
+ fz_always(ctx)
{
fz_close(file);
fz_free(ctx, buf);
+ }
+ fz_catch(ctx)
+ {
fz_throw(ctx, "cannot parse context stream");
}
- fz_close(file);
- fz_free(ctx, buf);
}
void
@@ -2730,7 +2736,7 @@ pdf_run_page_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, fz_m
cookie->progress++;
}
- flags = fz_to_int(fz_dict_gets(annot->obj, "F"));
+ flags = pdf_to_int(pdf_dict_gets(annot->obj, "F"));
/* TODO: NoZoom and NoRotate */
if (flags & (1 << 0)) /* Invisible */
@@ -2743,7 +2749,7 @@ pdf_run_page_with_usage(pdf_document *xref, pdf_page *page, fz_device *dev, fz_m
continue;
csi = pdf_new_csi(xref, dev, ctm, event, cookie, NULL);
- if (!pdf_is_hidden_ocg(fz_dict_gets(annot->obj, "OC"), csi, page->resources))
+ if (!pdf_is_hidden_ocg(pdf_dict_gets(annot->obj, "OC"), csi, page->resources))
{
fz_try(ctx)
{
@@ -2769,7 +2775,7 @@ pdf_run_page(pdf_document *xref, pdf_page *page, fz_device *dev, fz_matrix ctm,
}
void
-pdf_run_glyph(pdf_document *xref, fz_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate)
+pdf_run_glyph(pdf_document *xref, pdf_obj *resources, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate)
{
pdf_csi *csi = pdf_new_csi(xref, dev, ctm, "View", NULL, gstate);
fz_context *ctx = xref->ctx;
diff --git a/pdf/pdf_lex.c b/pdf/pdf_lex.c
index 24828412..6774167a 100644
--- a/pdf/pdf_lex.c
+++ b/pdf/pdf_lex.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#define IS_NUMBER \
'+':case'-':case'.':case'0':case'1':case'2':case'3':\
@@ -63,87 +63,106 @@ lex_comment(fz_stream *f)
}
static int
-lex_number(fz_stream *f, char *s, int n, int *tok)
+lex_number(fz_stream *f, pdf_lexbuf *buf, int c)
{
- char *buf = s;
- *tok = PDF_TOK_INT;
+ int neg = 0;
+ int i = 0;
+ int n;
+ int d;
+ float v;
/* Initially we might have +, -, . or a digit */
- if (n > 1)
+ switch (c)
+ {
+ case '.':
+ goto loop_after_dot;
+ case '-':
+ neg = 1;
+ break;
+ case '+':
+ break;
+ default: /* Must be a digit */
+ i = c - '0';
+ break;
+ }
+
+ while (1)
{
int c = fz_read_byte(f);
switch (c)
{
case '.':
- *tok = PDF_TOK_REAL;
- *s++ = c;
- n--;
goto loop_after_dot;
- case '+':
- case '-':
case RANGE_0_9:
- *s++ = c;
- n--;
- goto loop_after_sign;
+ i = 10*i + c - '0';
+ /* FIXME: Need overflow check here; do we care? */
+ break;
default:
fz_unread_byte(f);
- goto end;
+ /* Fallthrough */
case EOF:
- goto end;
+ if (neg)
+ i = -i;
+ buf->i = i;
+ return PDF_TOK_INT;
}
}
- /* We can't accept a sign from here on in, just . or a digit */
-loop_after_sign:
- while (n > 1)
+ /* In here, we've seen a dot, so can accept just digits */
+loop_after_dot:
+ n = 0;
+ d = 1;
+ while (1)
{
int c = fz_read_byte(f);
switch (c)
{
- case '.':
- *tok = PDF_TOK_REAL;
- *s++ = c;
- n--;
- goto loop_after_dot;
case RANGE_0_9:
- *s++ = c;
+ if (d >= INT_MAX/10)
+ goto underflow;
+ n = n*10 + (c - '0');
+ d *= 10;
break;
default:
fz_unread_byte(f);
- goto end;
+ /* Fallthrough */
case EOF:
- goto end;
+ v = (float)i + ((float)n / (float)d);
+ if (neg)
+ v = -v;
+ buf->f = v;
+ return PDF_TOK_REAL;
}
- n--;
}
- /* In here, we've seen a dot, so can accept just digits */
-loop_after_dot:
- while (n > 1)
+underflow:
+ /* Ignore any digits after here, because they are too small */
+ while (1)
{
int c = fz_read_byte(f);
switch (c)
{
case RANGE_0_9:
- *s++ = c;
break;
default:
fz_unread_byte(f);
- goto end;
+ /* Fallthrough */
case EOF:
- goto end;
+ v = (float)i + ((float)n / (float)d);
+ if (neg)
+ v = -v;
+ buf->f = v;
+ return PDF_TOK_REAL;
}
- n--;
}
-
-end:
- *s = '\0';
- return s-buf;
}
static void
-lex_name(fz_stream *f, char *s, int n)
+lex_name(fz_stream *f, pdf_lexbuf *buf)
{
+ char *s = buf->scratch;
+ int n = buf->size;
+
while (n > 1)
{
int c = fz_read_byte(f);
@@ -208,6 +227,7 @@ lex_name(fz_stream *f, char *s, int n)
}
end:
*s = '\0';
+ buf->len = s - buf->scratch;
}
static int
@@ -380,7 +400,7 @@ pdf_token_from_keyword(char *key)
}
int
-pdf_lex(fz_stream *f, char *buf, int n, int *sl)
+pdf_lex(fz_stream *f, pdf_lexbuf *buf)
{
while (1)
{
@@ -396,11 +416,10 @@ pdf_lex(fz_stream *f, char *buf, int n, int *sl)
lex_comment(f);
break;
case '/':
- lex_name(f, buf, n);
- *sl = strlen(buf);
+ lex_name(f, buf);
return PDF_TOK_NAME;
case '(':
- *sl = lex_string(f, buf, n);
+ buf->len = lex_string(f, buf->scratch, buf->size);
return PDF_TOK_STRING;
case ')':
fz_warn(f->ctx, "lexical error (unexpected ')')");
@@ -414,7 +433,7 @@ pdf_lex(fz_stream *f, char *buf, int n, int *sl)
else
{
fz_unread_byte(f);
- *sl = lex_hex_string(f, buf, n);
+ buf->len = lex_hex_string(f, buf->scratch, buf->size);
return PDF_TOK_STRING;
}
case '>':
@@ -434,17 +453,11 @@ pdf_lex(fz_stream *f, char *buf, int n, int *sl)
case '}':
return PDF_TOK_CLOSE_BRACE;
case IS_NUMBER:
- {
- int tok;
- fz_unread_byte(f);
- *sl = lex_number(f, buf, n, &tok);
- return tok;
- }
+ return lex_number(f, buf, c);
default: /* isregular: !isdelim && !iswhite && c != EOF */
fz_unread_byte(f);
- lex_name(f, buf, n);
- *sl = strlen(buf);
- return pdf_token_from_keyword(buf);
+ lex_name(f, buf);
+ return pdf_token_from_keyword(buf->scratch);
}
}
}
diff --git a/pdf/pdf_metrics.c b/pdf/pdf_metrics.c
index fc888257..888757c0 100644
--- a/pdf/pdf_metrics.c
+++ b/pdf/pdf_metrics.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
void
pdf_set_font_wmode(fz_context *ctx, pdf_font_desc *font, int wmode)
@@ -85,7 +85,7 @@ pdf_end_vmtx(fz_context *ctx, pdf_font_desc *font)
}
pdf_hmtx
-pdf_get_hmtx(fz_context *ctx, pdf_font_desc *font, int cid)
+pdf_lookup_hmtx(fz_context *ctx, pdf_font_desc *font, int cid)
{
int l = 0;
int r = font->hmtx_len - 1;
@@ -110,7 +110,7 @@ notfound:
}
pdf_vmtx
-pdf_get_vmtx(fz_context *ctx, pdf_font_desc *font, int cid)
+pdf_lookup_vmtx(fz_context *ctx, pdf_font_desc *font, int cid)
{
pdf_hmtx h;
pdf_vmtx v;
@@ -133,7 +133,7 @@ pdf_get_vmtx(fz_context *ctx, pdf_font_desc *font, int cid)
}
notfound:
- h = pdf_get_hmtx(ctx, font, cid);
+ h = pdf_lookup_hmtx(ctx, font, cid);
v = font->dvmtx;
v.x = h.w / 2;
return v;
diff --git a/pdf/pdf_nametree.c b/pdf/pdf_nametree.c
index c78e238d..b24d2c24 100644
--- a/pdf/pdf_nametree.c
+++ b/pdf/pdf_nametree.c
@@ -1,55 +1,55 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
-static fz_obj *
-pdf_lookup_name_imp(fz_context *ctx, fz_obj *node, fz_obj *needle)
+static pdf_obj *
+pdf_lookup_name_imp(fz_context *ctx, pdf_obj *node, pdf_obj *needle)
{
- fz_obj *kids = fz_dict_gets(node, "Kids");
- fz_obj *names = fz_dict_gets(node, "Names");
+ pdf_obj *kids = pdf_dict_gets(node, "Kids");
+ pdf_obj *names = pdf_dict_gets(node, "Names");
- if (fz_is_array(kids))
+ if (pdf_is_array(kids))
{
int l = 0;
- int r = fz_array_len(kids) - 1;
+ int r = pdf_array_len(kids) - 1;
while (l <= r)
{
int m = (l + r) >> 1;
- fz_obj *kid = fz_array_get(kids, m);
- fz_obj *limits = fz_dict_gets(kid, "Limits");
- fz_obj *first = fz_array_get(limits, 0);
- fz_obj *last = fz_array_get(limits, 1);
+ pdf_obj *kid = pdf_array_get(kids, m);
+ pdf_obj *limits = pdf_dict_gets(kid, "Limits");
+ pdf_obj *first = pdf_array_get(limits, 0);
+ pdf_obj *last = pdf_array_get(limits, 1);
- if (fz_objcmp(needle, first) < 0)
+ if (pdf_objcmp(needle, first) < 0)
r = m - 1;
- else if (fz_objcmp(needle, last) > 0)
+ else if (pdf_objcmp(needle, last) > 0)
l = m + 1;
else
{
- fz_obj *obj;
+ pdf_obj *obj;
- if (fz_dict_mark(node))
+ if (pdf_dict_mark(node))
break;
obj = pdf_lookup_name_imp(ctx, kid, needle);
- fz_dict_unmark(node);
+ pdf_dict_unmark(node);
return obj;
}
}
}
- if (fz_is_array(names))
+ if (pdf_is_array(names))
{
int l = 0;
- int r = (fz_array_len(names) / 2) - 1;
+ int r = (pdf_array_len(names) / 2) - 1;
while (l <= r)
{
int m = (l + r) >> 1;
int c;
- fz_obj *key = fz_array_get(names, m * 2);
- fz_obj *val = fz_array_get(names, m * 2 + 1);
+ pdf_obj *key = pdf_array_get(names, m * 2);
+ pdf_obj *val = pdf_array_get(names, m * 2 + 1);
- c = fz_objcmp(needle, key);
+ c = pdf_objcmp(needle, key);
if (c < 0)
r = m - 1;
else if (c > 0)
@@ -61,49 +61,49 @@ pdf_lookup_name_imp(fz_context *ctx, fz_obj *node, fz_obj *needle)
/* Spec says names should be sorted (hence the binary search,
* above), but Acrobat copes with non-sorted. Drop back to a
* simple search if the binary search fails. */
- r = fz_array_len(names)/2;
+ r = pdf_array_len(names)/2;
for (l = 0; l < r; l++)
- if (!fz_objcmp(needle, fz_array_get(names, l * 2)))
- return fz_array_get(names, l * 2 + 1);
+ if (!pdf_objcmp(needle, pdf_array_get(names, l * 2)))
+ return pdf_array_get(names, l * 2 + 1);
}
return NULL;
}
-fz_obj *
-pdf_lookup_name(pdf_document *xref, char *which, fz_obj *needle)
+pdf_obj *
+pdf_lookup_name(pdf_document *xref, char *which, pdf_obj *needle)
{
fz_context *ctx = xref->ctx;
- fz_obj *root = fz_dict_gets(xref->trailer, "Root");
- fz_obj *names = fz_dict_gets(root, "Names");
- fz_obj *tree = fz_dict_gets(names, which);
+ pdf_obj *root = pdf_dict_gets(xref->trailer, "Root");
+ pdf_obj *names = pdf_dict_gets(root, "Names");
+ pdf_obj *tree = pdf_dict_gets(names, which);
return pdf_lookup_name_imp(ctx, tree, needle);
}
-fz_obj *
-pdf_lookup_dest(pdf_document *xref, fz_obj *needle)
+pdf_obj *
+pdf_lookup_dest(pdf_document *xref, pdf_obj *needle)
{
fz_context *ctx = xref->ctx;
- fz_obj *root = fz_dict_gets(xref->trailer, "Root");
- fz_obj *dests = fz_dict_gets(root, "Dests");
- fz_obj *names = fz_dict_gets(root, "Names");
- fz_obj *dest = NULL;
+ pdf_obj *root = pdf_dict_gets(xref->trailer, "Root");
+ pdf_obj *dests = pdf_dict_gets(root, "Dests");
+ pdf_obj *names = pdf_dict_gets(root, "Names");
+ pdf_obj *dest = NULL;
/* PDF 1.1 has destinations in a dictionary */
if (dests)
{
- if (fz_is_name(needle))
- return fz_dict_get(dests, needle);
+ if (pdf_is_name(needle))
+ return pdf_dict_get(dests, needle);
else
- return fz_dict_gets(dests, fz_to_str_buf(needle));
+ return pdf_dict_gets(dests, pdf_to_str_buf(needle));
}
/* PDF 1.2 has destinations in a name tree */
if (names && !dest)
{
- fz_obj *tree = fz_dict_gets(names, "Dests");
+ pdf_obj *tree = pdf_dict_gets(names, "Dests");
return pdf_lookup_name_imp(ctx, tree, needle);
}
@@ -111,33 +111,33 @@ pdf_lookup_dest(pdf_document *xref, fz_obj *needle)
}
static void
-pdf_load_name_tree_imp(fz_obj *dict, pdf_document *xref, fz_obj *node)
+pdf_load_name_tree_imp(pdf_obj *dict, pdf_document *xref, pdf_obj *node)
{
fz_context *ctx = xref->ctx;
- fz_obj *kids = fz_dict_gets(node, "Kids");
- fz_obj *names = fz_dict_gets(node, "Names");
+ pdf_obj *kids = pdf_dict_gets(node, "Kids");
+ pdf_obj *names = pdf_dict_gets(node, "Names");
int i;
- if (kids && !fz_dict_mark(node))
+ if (kids && !pdf_dict_mark(node))
{
- for (i = 0; i < fz_array_len(kids); i++)
- pdf_load_name_tree_imp(dict, xref, fz_array_get(kids, i));
- fz_dict_unmark(node);
+ for (i = 0; i < pdf_array_len(kids); i++)
+ pdf_load_name_tree_imp(dict, xref, pdf_array_get(kids, i));
+ pdf_dict_unmark(node);
}
if (names)
{
- for (i = 0; i + 1 < fz_array_len(names); i += 2)
+ for (i = 0; i + 1 < pdf_array_len(names); i += 2)
{
- fz_obj *key = fz_array_get(names, i);
- fz_obj *val = fz_array_get(names, i + 1);
- if (fz_is_string(key))
+ pdf_obj *key = pdf_array_get(names, i);
+ pdf_obj *val = pdf_array_get(names, i + 1);
+ if (pdf_is_string(key))
{
key = pdf_to_utf8_name(ctx, key);
fz_dict_put(dict, key, val);
- fz_drop_obj(key);
+ pdf_drop_obj(key);
}
- else if (fz_is_name(key))
+ else if (pdf_is_name(key))
{
fz_dict_put(dict, key, val);
}
@@ -145,17 +145,17 @@ pdf_load_name_tree_imp(fz_obj *dict, pdf_document *xref, fz_obj *node)
}
}
-fz_obj *
+pdf_obj *
pdf_load_name_tree(pdf_document *xref, char *which)
{
fz_context *ctx = xref->ctx;
- fz_obj *root = fz_dict_gets(xref->trailer, "Root");
- fz_obj *names = fz_dict_gets(root, "Names");
- fz_obj *tree = fz_dict_gets(names, which);
- if (fz_is_dict(tree))
+ pdf_obj *root = pdf_dict_gets(xref->trailer, "Root");
+ pdf_obj *names = pdf_dict_gets(root, "Names");
+ pdf_obj *tree = pdf_dict_gets(names, which);
+ if (pdf_is_dict(tree))
{
- fz_obj *dict = fz_new_dict(ctx, 100);
+ pdf_obj *dict = pdf_new_dict(ctx, 100);
pdf_load_name_tree_imp(dict, xref, tree);
return dict;
}
diff --git a/pdf/pdf_outline.c b/pdf/pdf_outline.c
index e5c87f8c..d4bea75a 100644
--- a/pdf/pdf_outline.c
+++ b/pdf/pdf_outline.c
@@ -1,13 +1,13 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
static fz_outline *
-pdf_load_outline_imp(pdf_document *xref, fz_obj *dict)
+pdf_load_outline_imp(pdf_document *xref, pdf_obj *dict)
{
fz_context *ctx = xref->ctx;
fz_outline *node, **prev, *first;
- fz_obj *obj;
- fz_obj *odict = dict;
+ pdf_obj *obj;
+ pdf_obj *odict = dict;
fz_var(dict);
@@ -15,9 +15,9 @@ pdf_load_outline_imp(pdf_document *xref, fz_obj *dict)
{
first = NULL;
prev = &first;
- while (dict && fz_is_dict(dict))
+ while (dict && pdf_is_dict(dict))
{
- if (fz_dict_mark(dict))
+ if (pdf_dict_mark(dict))
break;
node = fz_malloc_struct(ctx, fz_outline);
node->title = NULL;
@@ -27,31 +27,31 @@ pdf_load_outline_imp(pdf_document *xref, fz_obj *dict)
*prev = node;
prev = &node->next;
- obj = fz_dict_gets(dict, "Title");
+ obj = pdf_dict_gets(dict, "Title");
if (obj)
node->title = pdf_to_utf8(ctx, obj);
- if ((obj = fz_dict_gets(dict, "Dest")))
+ if ((obj = pdf_dict_gets(dict, "Dest")))
node->dest = pdf_parse_link_dest(xref, obj);
- else if ((obj = fz_dict_gets(dict, "A")))
+ else if ((obj = pdf_dict_gets(dict, "A")))
node->dest = pdf_parse_action(xref, obj);
- obj = fz_dict_gets(dict, "First");
+ obj = pdf_dict_gets(dict, "First");
if (obj)
node->down = pdf_load_outline_imp(xref, obj);
- dict = fz_dict_gets(dict, "Next");
+ dict = pdf_dict_gets(dict, "Next");
}
}
fz_catch(ctx)
{
- for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next"))
- fz_dict_unmark(dict);
+ for (dict = odict; dict && pdf_dict_marked(dict); dict = pdf_dict_gets(dict, "Next"))
+ pdf_dict_unmark(dict);
fz_rethrow(ctx);
}
- for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next"))
- fz_dict_unmark(dict);
+ for (dict = odict; dict && pdf_dict_marked(dict); dict = pdf_dict_gets(dict, "Next"))
+ pdf_dict_unmark(dict);
return first;
}
@@ -59,11 +59,11 @@ pdf_load_outline_imp(pdf_document *xref, fz_obj *dict)
fz_outline *
pdf_load_outline(pdf_document *xref)
{
- fz_obj *root, *obj, *first;
+ pdf_obj *root, *obj, *first;
- root = fz_dict_gets(xref->trailer, "Root");
- obj = fz_dict_gets(root, "Outlines");
- first = fz_dict_gets(obj, "First");
+ root = pdf_dict_gets(xref->trailer, "Root");
+ obj = pdf_dict_gets(root, "Outlines");
+ first = pdf_dict_gets(obj, "First");
if (first)
return pdf_load_outline_imp(xref, first);
diff --git a/pdf/pdf_page.c b/pdf/pdf_page.c
index f2bf713e..c4083d20 100644
--- a/pdf/pdf_page.c
+++ b/pdf/pdf_page.c
@@ -1,128 +1,128 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
struct info
{
- fz_obj *resources;
- fz_obj *mediabox;
- fz_obj *cropbox;
- fz_obj *rotate;
+ pdf_obj *resources;
+ pdf_obj *mediabox;
+ pdf_obj *cropbox;
+ pdf_obj *rotate;
};
static void
-put_marker_bool(fz_context *ctx, fz_obj *rdb, char *marker, int val)
+put_marker_bool(fz_context *ctx, pdf_obj *rdb, char *marker, int val)
{
- fz_obj *tmp;
+ pdf_obj *tmp;
- tmp = fz_new_bool(ctx, val);
+ tmp = pdf_new_bool(ctx, val);
fz_try(ctx)
{
- fz_dict_puts(rdb, marker, tmp);
+ pdf_dict_puts(rdb, marker, tmp);
}
fz_catch(ctx)
{
- fz_drop_obj(tmp);
+ pdf_drop_obj(tmp);
fz_rethrow(ctx);
}
- fz_drop_obj(tmp);
+ pdf_drop_obj(tmp);
}
static void
-pdf_load_page_tree_node(pdf_document *xref, fz_obj *node, struct info info)
+pdf_load_page_tree_node(pdf_document *xref, pdf_obj *node, struct info info)
{
- fz_obj *dict, *kids, *count;
- fz_obj *obj;
+ pdf_obj *dict, *kids, *count;
+ pdf_obj *obj;
int i, n;
fz_context *ctx = xref->ctx;
/* prevent infinite recursion */
- if (!node || fz_dict_mark(node))
+ if (!node || pdf_dict_mark(node))
return;
fz_try(ctx)
{
- kids = fz_dict_gets(node, "Kids");
- count = fz_dict_gets(node, "Count");
+ kids = pdf_dict_gets(node, "Kids");
+ count = pdf_dict_gets(node, "Count");
- if (fz_is_array(kids) && fz_is_int(count))
+ if (pdf_is_array(kids) && pdf_is_int(count))
{
- obj = fz_dict_gets(node, "Resources");
+ obj = pdf_dict_gets(node, "Resources");
if (obj)
info.resources = obj;
- obj = fz_dict_gets(node, "MediaBox");
+ obj = pdf_dict_gets(node, "MediaBox");
if (obj)
info.mediabox = obj;
- obj = fz_dict_gets(node, "CropBox");
+ obj = pdf_dict_gets(node, "CropBox");
if (obj)
info.cropbox = obj;
- obj = fz_dict_gets(node, "Rotate");
+ obj = pdf_dict_gets(node, "Rotate");
if (obj)
info.rotate = obj;
- n = fz_array_len(kids);
+ n = pdf_array_len(kids);
for (i = 0; i < n; i++)
{
- obj = fz_array_get(kids, i);
+ obj = pdf_array_get(kids, i);
pdf_load_page_tree_node(xref, obj, info);
}
}
- else if ((dict = fz_to_dict(node)) != NULL)
+ else if ((dict = pdf_to_dict(node)) != NULL)
{
- if (info.resources && !fz_dict_gets(dict, "Resources"))
- fz_dict_puts(dict, "Resources", info.resources);
- if (info.mediabox && !fz_dict_gets(dict, "MediaBox"))
- fz_dict_puts(dict, "MediaBox", info.mediabox);
- if (info.cropbox && !fz_dict_gets(dict, "CropBox"))
- fz_dict_puts(dict, "CropBox", info.cropbox);
- if (info.rotate && !fz_dict_gets(dict, "Rotate"))
- fz_dict_puts(dict, "Rotate", info.rotate);
+ if (info.resources && !pdf_dict_gets(dict, "Resources"))
+ pdf_dict_puts(dict, "Resources", info.resources);
+ if (info.mediabox && !pdf_dict_gets(dict, "MediaBox"))
+ pdf_dict_puts(dict, "MediaBox", info.mediabox);
+ if (info.cropbox && !pdf_dict_gets(dict, "CropBox"))
+ pdf_dict_puts(dict, "CropBox", info.cropbox);
+ if (info.rotate && !pdf_dict_gets(dict, "Rotate"))
+ pdf_dict_puts(dict, "Rotate", info.rotate);
if (xref->page_len == xref->page_cap)
{
fz_warn(ctx, "found more pages than expected");
xref->page_cap ++;
- xref->page_refs = fz_resize_array(ctx, xref->page_refs, xref->page_cap, sizeof(fz_obj*));
- xref->page_objs = fz_resize_array(ctx, xref->page_objs, xref->page_cap, sizeof(fz_obj*));
+ xref->page_refs = fz_resize_array(ctx, xref->page_refs, xref->page_cap, sizeof(pdf_obj*));
+ xref->page_objs = fz_resize_array(ctx, xref->page_objs, xref->page_cap, sizeof(pdf_obj*));
}
- xref->page_refs[xref->page_len] = fz_keep_obj(node);
- xref->page_objs[xref->page_len] = fz_keep_obj(dict);
+ xref->page_refs[xref->page_len] = pdf_keep_obj(node);
+ xref->page_objs[xref->page_len] = pdf_keep_obj(dict);
xref->page_len ++;
}
}
fz_catch(ctx)
{
- fz_dict_unmark(node);
+ pdf_dict_unmark(node);
fz_rethrow(ctx);
}
- fz_dict_unmark(node);
+ pdf_dict_unmark(node);
}
static void
pdf_load_page_tree(pdf_document *xref)
{
fz_context *ctx = xref->ctx;
- fz_obj *catalog;
- fz_obj *pages;
- fz_obj *count;
+ pdf_obj *catalog;
+ pdf_obj *pages;
+ pdf_obj *count;
struct info info;
if (xref->page_len)
return;
- catalog = fz_dict_gets(xref->trailer, "Root");
- pages = fz_dict_gets(catalog, "Pages");
- count = fz_dict_gets(pages, "Count");
+ catalog = pdf_dict_gets(xref->trailer, "Root");
+ pages = pdf_dict_gets(catalog, "Pages");
+ count = pdf_dict_gets(pages, "Count");
- if (!fz_is_dict(pages))
+ if (!pdf_is_dict(pages))
fz_throw(ctx, "missing page tree");
- if (!fz_is_int(count))
+ if (!pdf_is_int(count))
fz_throw(ctx, "missing page count");
- xref->page_cap = fz_to_int(count);
+ xref->page_cap = pdf_to_int(count);
xref->page_len = 0;
- xref->page_refs = fz_malloc_array(ctx, xref->page_cap, sizeof(fz_obj*));
- xref->page_objs = fz_malloc_array(ctx, xref->page_cap, sizeof(fz_obj*));
+ xref->page_refs = fz_malloc_array(ctx, xref->page_cap, sizeof(pdf_obj*));
+ xref->page_objs = fz_malloc_array(ctx, xref->page_cap, sizeof(pdf_obj*));
info.resources = NULL;
info.mediabox = NULL;
@@ -140,84 +140,84 @@ pdf_count_pages(pdf_document *xref)
}
int
-pdf_find_page_number(pdf_document *xref, fz_obj *page)
+pdf_lookup_page_number(pdf_document *xref, pdf_obj *page)
{
- int i, num = fz_to_num(page);
+ int i, num = pdf_to_num(page);
pdf_load_page_tree(xref);
for (i = 0; i < xref->page_len; i++)
- if (num == fz_to_num(xref->page_refs[i]))
+ if (num == pdf_to_num(xref->page_refs[i]))
return i;
return -1;
}
/* We need to know whether to install a page-level transparency group */
-static int pdf_resources_use_blending(fz_context *ctx, fz_obj *rdb);
+static int pdf_resources_use_blending(fz_context *ctx, pdf_obj *rdb);
static int
-pdf_extgstate_uses_blending(fz_context *ctx, fz_obj *dict)
+pdf_extgstate_uses_blending(fz_context *ctx, pdf_obj *dict)
{
- fz_obj *obj = fz_dict_gets(dict, "BM");
- if (fz_is_name(obj) && strcmp(fz_to_name(obj), "Normal"))
+ pdf_obj *obj = pdf_dict_gets(dict, "BM");
+ if (pdf_is_name(obj) && strcmp(pdf_to_name(obj), "Normal"))
return 1;
return 0;
}
static int
-pdf_pattern_uses_blending(fz_context *ctx, fz_obj *dict)
+pdf_pattern_uses_blending(fz_context *ctx, pdf_obj *dict)
{
- fz_obj *obj;
- obj = fz_dict_gets(dict, "Resources");
+ pdf_obj *obj;
+ obj = pdf_dict_gets(dict, "Resources");
if (pdf_resources_use_blending(ctx, obj))
return 1;
- obj = fz_dict_gets(dict, "ExtGState");
+ obj = pdf_dict_gets(dict, "ExtGState");
return pdf_extgstate_uses_blending(ctx, obj);
}
static int
-pdf_xobject_uses_blending(fz_context *ctx, fz_obj *dict)
+pdf_xobject_uses_blending(fz_context *ctx, pdf_obj *dict)
{
- fz_obj *obj = fz_dict_gets(dict, "Resources");
+ pdf_obj *obj = pdf_dict_gets(dict, "Resources");
return pdf_resources_use_blending(ctx, obj);
}
static int
-pdf_resources_use_blending(fz_context *ctx, fz_obj *rdb)
+pdf_resources_use_blending(fz_context *ctx, pdf_obj *rdb)
{
- fz_obj *obj;
+ pdf_obj *obj;
int i, n, useBM = 0;
if (!rdb)
return 0;
/* Have we been here before and stashed an answer? */
- obj = fz_dict_gets(rdb, ".useBM");
+ obj = pdf_dict_gets(rdb, ".useBM");
if (obj)
- return fz_to_bool(obj);
+ return pdf_to_bool(obj);
/* stop on cyclic resource dependencies */
- if (fz_dict_mark(rdb))
+ if (pdf_dict_mark(rdb))
return 0;
fz_try(ctx)
{
- obj = fz_dict_gets(rdb, "ExtGState");
- n = fz_dict_len(obj);
+ obj = pdf_dict_gets(rdb, "ExtGState");
+ n = pdf_dict_len(obj);
for (i = 0; i < n; i++)
- if (pdf_extgstate_uses_blending(ctx, fz_dict_get_val(obj, i)))
+ if (pdf_extgstate_uses_blending(ctx, pdf_dict_get_val(obj, i)))
goto found;
- obj = fz_dict_gets(rdb, "Pattern");
- n = fz_dict_len(obj);
+ obj = pdf_dict_gets(rdb, "Pattern");
+ n = pdf_dict_len(obj);
for (i = 0; i < n; i++)
- if (pdf_pattern_uses_blending(ctx, fz_dict_get_val(obj, i)))
+ if (pdf_pattern_uses_blending(ctx, pdf_dict_get_val(obj, i)))
goto found;
- obj = fz_dict_gets(rdb, "XObject");
- n = fz_dict_len(obj);
+ obj = pdf_dict_gets(rdb, "XObject");
+ n = pdf_dict_len(obj);
for (i = 0; i < n; i++)
- if (pdf_xobject_uses_blending(ctx, fz_dict_get_val(obj, i)))
+ if (pdf_xobject_uses_blending(ctx, pdf_dict_get_val(obj, i)))
goto found;
if (0)
{
@@ -227,10 +227,10 @@ found:
}
fz_catch(ctx)
{
- fz_dict_unmark(rdb);
+ pdf_dict_unmark(rdb);
fz_rethrow(ctx);
}
- fz_dict_unmark(rdb);
+ pdf_dict_unmark(rdb);
put_marker_bool(ctx, rdb, ".useBM", useBM);
return useBM;
@@ -239,7 +239,7 @@ found:
/* we need to combine all sub-streams into one for the content stream interpreter */
static fz_buffer *
-pdf_load_page_contents_array(pdf_document *xref, fz_obj *list)
+pdf_load_page_contents_array(pdf_document *xref, pdf_obj *list)
{
fz_buffer *big;
fz_buffer *one;
@@ -248,14 +248,14 @@ pdf_load_page_contents_array(pdf_document *xref, fz_obj *list)
big = fz_new_buffer(ctx, 32 * 1024);
- n = fz_array_len(list);
+ n = pdf_array_len(list);
fz_var(i); /* Workaround Mac compiler bug */
for (i = 0; i < n; i++)
{
- fz_obj *stm = fz_array_get(list, i);
+ pdf_obj *stm = pdf_array_get(list, i);
fz_try(ctx)
{
- one = pdf_load_stream(xref, fz_to_num(stm), fz_to_gen(stm));
+ one = pdf_load_stream(xref, pdf_to_num(stm), pdf_to_gen(stm));
}
fz_catch(ctx)
{
@@ -277,24 +277,25 @@ pdf_load_page_contents_array(pdf_document *xref, fz_obj *list)
fz_drop_buffer(ctx, big);
fz_throw(ctx, "cannot load content stream");
}
+ fz_trim_buffer(ctx, big);
return big;
}
static fz_buffer *
-pdf_load_page_contents(pdf_document *xref, fz_obj *obj)
+pdf_load_page_contents(pdf_document *xref, pdf_obj *obj)
{
fz_context *ctx = xref->ctx;
- if (fz_is_array(obj))
+ if (pdf_is_array(obj))
{
return pdf_load_page_contents_array(xref, obj);
/* RJW: "cannot load content stream array" */
}
- else if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj)))
+ else if (pdf_is_stream(xref, pdf_to_num(obj), pdf_to_gen(obj)))
{
- return pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj));
- /* RJW: "cannot load content stream (%d 0 R)", fz_to_num(obj) */
+ return pdf_load_stream(xref, pdf_to_num(obj), pdf_to_gen(obj));
+ /* RJW: "cannot load content stream (%d 0 R)", pdf_to_num(obj) */
}
fz_warn(ctx, "page contents missing, leaving page blank");
@@ -307,7 +308,7 @@ pdf_load_page(pdf_document *xref, int number)
fz_context *ctx = xref->ctx;
pdf_page *page;
pdf_annot *annot;
- fz_obj *pageobj, *pageref, *obj;
+ pdf_obj *pageobj, *pageref, *obj;
fz_rect mediabox, cropbox, realbox;
fz_matrix ctm;
@@ -325,7 +326,7 @@ pdf_load_page(pdf_document *xref, int number)
page->links = NULL;
page->annots = NULL;
- mediabox = pdf_to_rect(ctx, fz_dict_gets(pageobj, "MediaBox"));
+ mediabox = pdf_to_rect(ctx, pdf_dict_gets(pageobj, "MediaBox"));
if (fz_is_empty_rect(mediabox))
{
fz_warn(ctx, "cannot find page size for page %d", number + 1);
@@ -335,7 +336,7 @@ pdf_load_page(pdf_document *xref, int number)
mediabox.y1 = 792;
}
- cropbox = pdf_to_rect(ctx, fz_dict_gets(pageobj, "CropBox"));
+ cropbox = pdf_to_rect(ctx, pdf_dict_gets(pageobj, "CropBox"));
if (!fz_is_empty_rect(cropbox))
mediabox = fz_intersect_rect(mediabox, cropbox);
@@ -350,24 +351,24 @@ pdf_load_page(pdf_document *xref, int number)
page->mediabox = fz_unit_rect;
}
- page->rotate = fz_to_int(fz_dict_gets(pageobj, "Rotate"));
+ page->rotate = pdf_to_int(pdf_dict_gets(pageobj, "Rotate"));
ctm = fz_concat(fz_rotate(-page->rotate), fz_scale(1, -1));
realbox = fz_transform_rect(ctm, page->mediabox);
page->ctm = fz_concat(ctm, fz_translate(-realbox.x0, -realbox.y0));
- obj = fz_dict_gets(pageobj, "Annots");
+ obj = pdf_dict_gets(pageobj, "Annots");
if (obj)
{
page->links = pdf_load_link_annots(xref, obj, page->ctm);
page->annots = pdf_load_annots(xref, obj);
}
- page->resources = fz_dict_gets(pageobj, "Resources");
+ page->resources = pdf_dict_gets(pageobj, "Resources");
if (page->resources)
- fz_keep_obj(page->resources);
+ pdf_keep_obj(page->resources);
- obj = fz_dict_gets(pageobj, "Contents");
+ obj = pdf_dict_gets(pageobj, "Contents");
fz_try(ctx)
{
page->contents = pdf_load_page_contents(xref, obj);
@@ -382,7 +383,7 @@ pdf_load_page(pdf_document *xref, int number)
fz_catch(ctx)
{
pdf_free_page(xref, page);
- fz_throw(ctx, "cannot load page %d contents (%d 0 R)", number + 1, fz_to_num(pageref));
+ fz_throw(ctx, "cannot load page %d contents (%d 0 R)", number + 1, pdf_to_num(pageref));
}
return page;
@@ -408,7 +409,7 @@ void
pdf_free_page(pdf_document *xref, pdf_page *page)
{
if (page->resources)
- fz_drop_obj(page->resources);
+ pdf_drop_obj(page->resources);
if (page->contents)
fz_drop_buffer(xref->ctx, page->contents);
if (page->links)
diff --git a/pdf/pdf_parse.c b/pdf/pdf_parse.c
index 220eb30c..fe9db368 100644
--- a/pdf/pdf_parse.c
+++ b/pdf/pdf_parse.c
@@ -1,14 +1,14 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
fz_rect
-pdf_to_rect(fz_context *ctx, fz_obj *array)
+pdf_to_rect(fz_context *ctx, pdf_obj *array)
{
fz_rect r;
- float a = fz_to_real(fz_array_get(array, 0));
- float b = fz_to_real(fz_array_get(array, 1));
- float c = fz_to_real(fz_array_get(array, 2));
- float d = fz_to_real(fz_array_get(array, 3));
+ float a = pdf_to_real(pdf_array_get(array, 0));
+ float b = pdf_to_real(pdf_array_get(array, 1));
+ float c = pdf_to_real(pdf_array_get(array, 2));
+ float d = pdf_to_real(pdf_array_get(array, 3));
r.x0 = MIN(a, c);
r.y0 = MIN(b, d);
r.x1 = MAX(a, c);
@@ -17,25 +17,25 @@ pdf_to_rect(fz_context *ctx, fz_obj *array)
}
fz_matrix
-pdf_to_matrix(fz_context *ctx, fz_obj *array)
+pdf_to_matrix(fz_context *ctx, pdf_obj *array)
{
fz_matrix m;
- m.a = fz_to_real(fz_array_get(array, 0));
- m.b = fz_to_real(fz_array_get(array, 1));
- m.c = fz_to_real(fz_array_get(array, 2));
- m.d = fz_to_real(fz_array_get(array, 3));
- m.e = fz_to_real(fz_array_get(array, 4));
- m.f = fz_to_real(fz_array_get(array, 5));
+ m.a = pdf_to_real(pdf_array_get(array, 0));
+ m.b = pdf_to_real(pdf_array_get(array, 1));
+ m.c = pdf_to_real(pdf_array_get(array, 2));
+ m.d = pdf_to_real(pdf_array_get(array, 3));
+ m.e = pdf_to_real(pdf_array_get(array, 4));
+ m.f = pdf_to_real(pdf_array_get(array, 5));
return m;
}
/* Convert Unicode/PdfDocEncoding string into utf-8 */
char *
-pdf_to_utf8(fz_context *ctx, fz_obj *src)
+pdf_to_utf8(fz_context *ctx, pdf_obj *src)
{
- unsigned char *srcptr = (unsigned char *) fz_to_str_buf(src);
+ unsigned char *srcptr = (unsigned char *) pdf_to_str_buf(src);
char *dstptr, *dst;
- int srclen = fz_to_str_len(src);
+ int srclen = pdf_to_str_len(src);
int dstlen = 0;
int ucs;
int i;
@@ -45,7 +45,7 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
for (i = 2; i + 1 < srclen; i += 2)
{
ucs = srcptr[i] << 8 | srcptr[i+1];
- dstlen += runelen(ucs);
+ dstlen += fz_runelen(ucs);
}
dstptr = dst = fz_malloc(ctx, dstlen + 1);
@@ -53,7 +53,7 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
for (i = 2; i + 1 < srclen; i += 2)
{
ucs = srcptr[i] << 8 | srcptr[i+1];
- dstptr += runetochar(dstptr, &ucs);
+ dstptr += fz_runetochar(dstptr, ucs);
}
}
else if (srclen >= 2 && srcptr[0] == 255 && srcptr[1] == 254)
@@ -61,7 +61,7 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
for (i = 2; i + 1 < srclen; i += 2)
{
ucs = srcptr[i] | srcptr[i+1] << 8;
- dstlen += runelen(ucs);
+ dstlen += fz_runelen(ucs);
}
dstptr = dst = fz_malloc(ctx, dstlen + 1);
@@ -69,20 +69,20 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
for (i = 2; i + 1 < srclen; i += 2)
{
ucs = srcptr[i] | srcptr[i+1] << 8;
- dstptr += runetochar(dstptr, &ucs);
+ dstptr += fz_runetochar(dstptr, ucs);
}
}
else
{
for (i = 0; i < srclen; i++)
- dstlen += runelen(pdf_doc_encoding[srcptr[i]]);
+ dstlen += fz_runelen(pdf_doc_encoding[srcptr[i]]);
dstptr = dst = fz_malloc(ctx, dstlen + 1);
for (i = 0; i < srclen; i++)
{
ucs = pdf_doc_encoding[srcptr[i]];
- dstptr += runetochar(dstptr, &ucs);
+ dstptr += fz_runetochar(dstptr, ucs);
}
}
@@ -92,11 +92,11 @@ pdf_to_utf8(fz_context *ctx, fz_obj *src)
/* Convert Unicode/PdfDocEncoding string into ucs-2 */
unsigned short *
-pdf_to_ucs2(fz_context *ctx, fz_obj *src)
+pdf_to_ucs2(fz_context *ctx, pdf_obj *src)
{
- unsigned char *srcptr = (unsigned char *) fz_to_str_buf(src);
+ unsigned char *srcptr = (unsigned char *) pdf_to_str_buf(src);
unsigned short *dstptr, *dst;
- int srclen = fz_to_str_len(src);
+ int srclen = pdf_to_str_len(src);
int i;
if (srclen >= 2 && srcptr[0] == 254 && srcptr[1] == 255)
@@ -161,50 +161,49 @@ pdf_from_ucs2(fz_context *ctx, unsigned short *src)
return docstr;
}
-fz_obj *
-pdf_to_utf8_name(fz_context *ctx, fz_obj *src)
+pdf_obj *
+pdf_to_utf8_name(fz_context *ctx, pdf_obj *src)
{
char *buf = pdf_to_utf8(ctx, src);
- fz_obj *dst = fz_new_name(ctx, buf);
+ pdf_obj *dst = fz_new_name(ctx, buf);
fz_free(ctx, buf);
return dst;
}
-fz_obj *
-pdf_parse_array(pdf_document *xref, fz_stream *file, char *buf, int cap)
+pdf_obj *
+pdf_parse_array(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf)
{
- fz_obj *ary = NULL;
- fz_obj *obj = NULL;
+ pdf_obj *ary = NULL;
+ pdf_obj *obj = NULL;
int a = 0, b = 0, n = 0;
int tok;
- int len;
fz_context *ctx = file->ctx;
- fz_obj *op;
+ pdf_obj *op;
fz_var(obj);
- ary = fz_new_array(ctx, 4);
+ ary = pdf_new_array(ctx, 4);
fz_try(ctx)
{
while (1)
{
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
if (tok != PDF_TOK_INT && tok != PDF_TOK_R)
{
if (n > 0)
{
- obj = fz_new_int(ctx, a);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_int(ctx, a);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
}
if (n > 1)
{
- obj = fz_new_int(ctx, b);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_int(ctx, b);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
}
n = 0;
@@ -212,9 +211,9 @@ pdf_parse_array(pdf_document *xref, fz_stream *file, char *buf, int cap)
if (tok == PDF_TOK_INT && n == 2)
{
- obj = fz_new_int(ctx, a);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_int(ctx, a);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
a = b;
n --;
@@ -228,70 +227,70 @@ pdf_parse_array(pdf_document *xref, fz_stream *file, char *buf, int cap)
case PDF_TOK_INT:
if (n == 0)
- a = atoi(buf);
+ a = buf->i;
if (n == 1)
- b = atoi(buf);
+ b = buf->i;
n ++;
break;
case PDF_TOK_R:
if (n != 2)
fz_throw(ctx, "cannot parse indirect reference in array");
- obj = fz_new_indirect(ctx, a, b, xref);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_indirect(ctx, a, b, xref);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
n = 0;
break;
case PDF_TOK_OPEN_ARRAY:
- obj = pdf_parse_array(xref, file, buf, cap);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_parse_array(xref, file, buf);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_OPEN_DICT:
- obj = pdf_parse_dict(xref, file, buf, cap);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_parse_dict(xref, file, buf);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_NAME:
- obj = fz_new_name(ctx, buf);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = fz_new_name(ctx, buf->scratch);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_REAL:
- obj = fz_new_real(ctx, fz_atof(buf));
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_real(ctx, buf->f);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_STRING:
- obj = fz_new_string(ctx, buf, len);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_string(ctx, buf->scratch, buf->len);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_TRUE:
- obj = fz_new_bool(ctx, 1);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_bool(ctx, 1);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_FALSE:
- obj = fz_new_bool(ctx, 0);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_bool(ctx, 0);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
case PDF_TOK_NULL:
- obj = fz_new_null(ctx);
- fz_array_push(ary, obj);
- fz_drop_obj(obj);
+ obj = pdf_new_null(ctx);
+ pdf_array_push(ary, obj);
+ pdf_drop_obj(obj);
obj = NULL;
break;
@@ -304,89 +303,87 @@ end:
}
fz_catch(ctx)
{
- fz_drop_obj(obj);
- fz_drop_obj(ary);
+ pdf_drop_obj(obj);
+ pdf_drop_obj(ary);
fz_throw(ctx, "cannot parse array");
}
return op;
}
-fz_obj *
-pdf_parse_dict(pdf_document *xref, fz_stream *file, char *buf, int cap)
+pdf_obj *
+pdf_parse_dict(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf)
{
- fz_obj *dict = NULL;
- fz_obj *key = NULL;
- fz_obj *val = NULL;
+ pdf_obj *dict;
+ pdf_obj *key = NULL;
+ pdf_obj *val = NULL;
int tok;
- int len;
int a, b;
fz_context *ctx = file->ctx;
- fz_var(dict);
+ dict = pdf_new_dict(ctx, 8);
+
fz_var(key);
fz_var(val);
- dict = fz_new_dict(ctx, 8);
-
fz_try(ctx)
{
while (1)
{
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
skip:
if (tok == PDF_TOK_CLOSE_DICT)
break;
/* for BI .. ID .. EI in content streams */
- if (tok == PDF_TOK_KEYWORD && !strcmp(buf, "ID"))
+ if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "ID"))
break;
if (tok != PDF_TOK_NAME)
fz_throw(ctx, "invalid key in dict");
- key = fz_new_name(ctx, buf);
+ key = fz_new_name(ctx, buf->scratch);
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
switch (tok)
{
case PDF_TOK_OPEN_ARRAY:
- val = pdf_parse_array(xref, file, buf, cap);
+ val = pdf_parse_array(xref, file, buf);
break;
case PDF_TOK_OPEN_DICT:
- val = pdf_parse_dict(xref, file, buf, cap);
+ val = pdf_parse_dict(xref, file, buf);
break;
- case PDF_TOK_NAME: val = fz_new_name(ctx, buf); break;
- case PDF_TOK_REAL: val = fz_new_real(ctx, fz_atof(buf)); break;
- case PDF_TOK_STRING: val = fz_new_string(ctx, buf, len); break;
- case PDF_TOK_TRUE: val = fz_new_bool(ctx, 1); break;
- case PDF_TOK_FALSE: val = fz_new_bool(ctx, 0); break;
- case PDF_TOK_NULL: val = fz_new_null(ctx); break;
+ case PDF_TOK_NAME: val = fz_new_name(ctx, buf->scratch); break;
+ case PDF_TOK_REAL: val = pdf_new_real(ctx, buf->f); break;
+ case PDF_TOK_STRING: val = pdf_new_string(ctx, buf->scratch, buf->len); break;
+ case PDF_TOK_TRUE: val = pdf_new_bool(ctx, 1); break;
+ case PDF_TOK_FALSE: val = pdf_new_bool(ctx, 0); break;
+ case PDF_TOK_NULL: val = pdf_new_null(ctx); break;
case PDF_TOK_INT:
/* 64-bit to allow for numbers > INT_MAX and overflow */
- a = (int) strtoll(buf, 0, 10);
- tok = pdf_lex(file, buf, cap, &len);
+ a = buf->i;
+ tok = pdf_lex(file, buf);
if (tok == PDF_TOK_CLOSE_DICT || tok == PDF_TOK_NAME ||
- (tok == PDF_TOK_KEYWORD && !strcmp(buf, "ID")))
+ (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "ID")))
{
- val = fz_new_int(ctx, a);
+ val = pdf_new_int(ctx, a);
fz_dict_put(dict, key, val);
- fz_drop_obj(val);
+ pdf_drop_obj(val);
val = NULL;
- fz_drop_obj(key);
+ pdf_drop_obj(key);
key = NULL;
goto skip;
}
if (tok == PDF_TOK_INT)
{
- b = atoi(buf);
- tok = pdf_lex(file, buf, cap, &len);
+ b = buf->i;
+ tok = pdf_lex(file, buf);
if (tok == PDF_TOK_R)
{
- val = fz_new_indirect(ctx, a, b, xref);
+ val = pdf_new_indirect(ctx, a, b, xref);
break;
}
}
@@ -397,129 +394,127 @@ pdf_parse_dict(pdf_document *xref, fz_stream *file, char *buf, int cap)
}
fz_dict_put(dict, key, val);
- fz_drop_obj(val);
+ pdf_drop_obj(val);
val = NULL;
- fz_drop_obj(key);
+ pdf_drop_obj(key);
key = NULL;
}
}
fz_catch(ctx)
{
- fz_drop_obj(dict);
- fz_drop_obj(key);
- fz_drop_obj(val);
+ pdf_drop_obj(dict);
+ pdf_drop_obj(key);
+ pdf_drop_obj(val);
fz_throw(ctx, "cannot parse dict");
}
return dict;
}
-fz_obj *
-pdf_parse_stm_obj(pdf_document *xref, fz_stream *file, char *buf, int cap)
+pdf_obj *
+pdf_parse_stm_obj(pdf_document *xref, fz_stream *file, pdf_lexbuf *buf)
{
int tok;
- int len;
fz_context *ctx = file->ctx;
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot parse token in object stream") */
switch (tok)
{
case PDF_TOK_OPEN_ARRAY:
- return pdf_parse_array(xref, file, buf, cap);
+ return pdf_parse_array(xref, file, buf);
/* RJW: "cannot parse object stream" */
case PDF_TOK_OPEN_DICT:
- return pdf_parse_dict(xref, file, buf, cap);
+ return pdf_parse_dict(xref, file, buf);
/* RJW: "cannot parse object stream" */
- case PDF_TOK_NAME: return fz_new_name(ctx, buf); break;
- case PDF_TOK_REAL: return fz_new_real(ctx, fz_atof(buf)); break;
- case PDF_TOK_STRING: return fz_new_string(ctx, buf, len); break;
- case PDF_TOK_TRUE: return fz_new_bool(ctx, 1); break;
- case PDF_TOK_FALSE: return fz_new_bool(ctx, 0); break;
- case PDF_TOK_NULL: return fz_new_null(ctx); break;
- case PDF_TOK_INT: return fz_new_int(ctx, atoi(buf)); break;
+ case PDF_TOK_NAME: return fz_new_name(ctx, buf->scratch); break;
+ case PDF_TOK_REAL: return pdf_new_real(ctx, buf->f); break;
+ case PDF_TOK_STRING: return pdf_new_string(ctx, buf->scratch, buf->len); break;
+ case PDF_TOK_TRUE: return pdf_new_bool(ctx, 1); break;
+ case PDF_TOK_FALSE: return pdf_new_bool(ctx, 0); break;
+ case PDF_TOK_NULL: return pdf_new_null(ctx); break;
+ case PDF_TOK_INT: return pdf_new_int(ctx, buf->i); break;
default: fz_throw(ctx, "unknown token in object stream");
}
return NULL; /* Stupid MSVC */
}
-fz_obj *
+pdf_obj *
pdf_parse_ind_obj(pdf_document *xref,
- fz_stream *file, char *buf, int cap,
+ fz_stream *file, pdf_lexbuf *buf,
int *onum, int *ogen, int *ostmofs)
{
- fz_obj *obj = NULL;
+ pdf_obj *obj = NULL;
int num = 0, gen = 0, stm_ofs;
int tok;
- int len;
int a, b;
fz_context *ctx = file->ctx;
fz_var(obj);
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: cannot parse indirect object (%d %d R)", num, gen */
if (tok != PDF_TOK_INT)
fz_throw(ctx, "expected object number (%d %d R)", num, gen);
- num = atoi(buf);
+ num = buf->i;
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot parse indirect object (%d %d R)", num, gen */
if (tok != PDF_TOK_INT)
fz_throw(ctx, "expected generation number (%d %d R)", num, gen);
- gen = atoi(buf);
+ gen = buf->i;
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot parse indirect object (%d %d R)", num, gen */
if (tok != PDF_TOK_OBJ)
fz_throw(ctx, "expected 'obj' keyword (%d %d R)", num, gen);
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot parse indirect object (%d %d R)", num, gen */
switch (tok)
{
case PDF_TOK_OPEN_ARRAY:
- obj = pdf_parse_array(xref, file, buf, cap);
+ obj = pdf_parse_array(xref, file, buf);
/* RJW: "cannot parse indirect object (%d %d R)", num, gen */
break;
case PDF_TOK_OPEN_DICT:
- obj = pdf_parse_dict(xref, file, buf, cap);
+ obj = pdf_parse_dict(xref, file, buf);
/* RJW: "cannot parse indirect object (%d %d R)", num, gen */
break;
- case PDF_TOK_NAME: obj = fz_new_name(ctx, buf); break;
- case PDF_TOK_REAL: obj = fz_new_real(ctx, fz_atof(buf)); break;
- case PDF_TOK_STRING: obj = fz_new_string(ctx, buf, len); break;
- case PDF_TOK_TRUE: obj = fz_new_bool(ctx, 1); break;
- case PDF_TOK_FALSE: obj = fz_new_bool(ctx, 0); break;
- case PDF_TOK_NULL: obj = fz_new_null(ctx); break;
+ case PDF_TOK_NAME: obj = fz_new_name(ctx, buf->scratch); break;
+ case PDF_TOK_REAL: obj = pdf_new_real(ctx, buf->f); break;
+ case PDF_TOK_STRING: obj = pdf_new_string(ctx, buf->scratch, buf->len); break;
+ case PDF_TOK_TRUE: obj = pdf_new_bool(ctx, 1); break;
+ case PDF_TOK_FALSE: obj = pdf_new_bool(ctx, 0); break;
+ case PDF_TOK_NULL: obj = pdf_new_null(ctx); break;
case PDF_TOK_INT:
- a = atoi(buf);
- tok = pdf_lex(file, buf, cap, &len);
+ a = buf->i;
+ tok = pdf_lex(file, buf);
/* "cannot parse indirect object (%d %d R)", num, gen */
if (tok == PDF_TOK_STREAM || tok == PDF_TOK_ENDOBJ)
{
- obj = fz_new_int(ctx, a);
+ obj = pdf_new_int(ctx, a);
goto skip;
}
if (tok == PDF_TOK_INT)
{
- b = atoi(buf);
- tok = pdf_lex(file, buf, cap, &len);
+ b = buf->i;
+ tok = pdf_lex(file, buf);
/* RJW: "cannot parse indirect object (%d %d R)", num, gen); */
if (tok == PDF_TOK_R)
{
- obj = fz_new_indirect(ctx, a, b, xref);
+ obj = pdf_new_indirect(ctx, a, b, xref);
break;
}
}
fz_throw(ctx, "expected 'R' keyword (%d %d R)", num, gen);
case PDF_TOK_ENDOBJ:
- obj = fz_new_null(ctx);
+ obj = pdf_new_null(ctx);
goto skip;
default:
@@ -528,11 +523,11 @@ pdf_parse_ind_obj(pdf_document *xref,
fz_try(ctx)
{
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
}
fz_catch(ctx)
{
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
fz_throw(ctx, "cannot parse indirect object (%d %d R)", num, gen);
}
diff --git a/pdf/pdf_pattern.c b/pdf/pdf_pattern.c
index 9ffbee02..14175670 100644
--- a/pdf/pdf_pattern.c
+++ b/pdf/pdf_pattern.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
pdf_pattern *
pdf_keep_pattern(fz_context *ctx, pdf_pattern *pat)
@@ -19,7 +19,7 @@ pdf_free_pattern_imp(fz_context *ctx, fz_storable *pat_)
pdf_pattern *pat = (pdf_pattern *)pat_;
if (pat->resources)
- fz_drop_obj(pat->resources);
+ pdf_drop_obj(pat->resources);
if (pat->contents)
fz_drop_buffer(ctx, pat->contents);
fz_free(ctx, pat);
@@ -34,13 +34,13 @@ pdf_pattern_size(pdf_pattern *pat)
}
pdf_pattern *
-pdf_load_pattern(pdf_document *xref, fz_obj *dict)
+pdf_load_pattern(pdf_document *xref, pdf_obj *dict)
{
pdf_pattern *pat;
- fz_obj *obj;
+ pdf_obj *obj;
fz_context *ctx = xref->ctx;
- if ((pat = fz_find_item(ctx, pdf_free_pattern_imp, dict)))
+ if ((pat = pdf_find_item(ctx, pdf_free_pattern_imp, dict)))
{
return pat;
}
@@ -51,34 +51,34 @@ pdf_load_pattern(pdf_document *xref, fz_obj *dict)
pat->contents = NULL;
/* Store pattern now, to avoid possible recursion if objects refer back to this one */
- fz_store_item(ctx, dict, pat, pdf_pattern_size(pat));
+ pdf_store_item(ctx, dict, pat, pdf_pattern_size(pat));
- pat->ismask = fz_to_int(fz_dict_gets(dict, "PaintType")) == 2;
- pat->xstep = fz_to_real(fz_dict_gets(dict, "XStep"));
- pat->ystep = fz_to_real(fz_dict_gets(dict, "YStep"));
+ pat->ismask = pdf_to_int(pdf_dict_gets(dict, "PaintType")) == 2;
+ pat->xstep = pdf_to_real(pdf_dict_gets(dict, "XStep"));
+ pat->ystep = pdf_to_real(pdf_dict_gets(dict, "YStep"));
- obj = fz_dict_gets(dict, "BBox");
+ obj = pdf_dict_gets(dict, "BBox");
pat->bbox = pdf_to_rect(ctx, obj);
- obj = fz_dict_gets(dict, "Matrix");
+ obj = pdf_dict_gets(dict, "Matrix");
if (obj)
pat->matrix = pdf_to_matrix(ctx, obj);
else
pat->matrix = fz_identity;
- pat->resources = fz_dict_gets(dict, "Resources");
+ pat->resources = pdf_dict_gets(dict, "Resources");
if (pat->resources)
- fz_keep_obj(pat->resources);
+ pdf_keep_obj(pat->resources);
fz_try(ctx)
{
- pat->contents = pdf_load_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ pat->contents = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
}
fz_catch(ctx)
{
- fz_remove_item(ctx, pdf_free_pattern_imp, dict);
+ pdf_remove_item(ctx, pdf_free_pattern_imp, dict);
pdf_drop_pattern(ctx, pat);
- fz_throw(ctx, "cannot load pattern stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "cannot load pattern stream (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
}
return pat;
}
diff --git a/pdf/pdf_repair.c b/pdf/pdf_repair.c
index 0dc0e132..fda1e6b5 100644
--- a/pdf/pdf_repair.c
+++ b/pdf/pdf_repair.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
/* Scan file for objects and reconstruct xref table */
@@ -13,11 +13,10 @@ struct entry
};
static void
-pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp, fz_obj **encrypt, fz_obj **id)
+pdf_repair_obj(fz_stream *file, pdf_lexbuf *buf, int *stmofsp, int *stmlenp, pdf_obj **encrypt, pdf_obj **id)
{
int tok;
int stm_len;
- int len;
int n;
fz_context *ctx = file->ctx;
@@ -26,16 +25,16 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp,
stm_len = 0;
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot parse object" */
if (tok == PDF_TOK_OPEN_DICT)
{
- fz_obj *dict, *obj;
+ pdf_obj *dict, *obj;
/* Send NULL xref so we don't try to resolve references */
fz_try(ctx)
{
- dict = pdf_parse_dict(NULL, file, buf, cap);
+ dict = pdf_parse_dict(NULL, file, buf);
}
fz_catch(ctx)
{
@@ -43,34 +42,34 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp,
if (file->eof)
fz_throw(ctx, "broken object at EOF ignored");
/* Silently swallow the error */
- dict = fz_new_dict(ctx, 2);
+ dict = pdf_new_dict(ctx, 2);
}
- obj = fz_dict_gets(dict, "Type");
- if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "XRef"))
+ obj = pdf_dict_gets(dict, "Type");
+ if (pdf_is_name(obj) && !strcmp(pdf_to_name(obj), "XRef"))
{
- obj = fz_dict_gets(dict, "Encrypt");
+ obj = pdf_dict_gets(dict, "Encrypt");
if (obj)
{
if (*encrypt)
- fz_drop_obj(*encrypt);
- *encrypt = fz_keep_obj(obj);
+ pdf_drop_obj(*encrypt);
+ *encrypt = pdf_keep_obj(obj);
}
- obj = fz_dict_gets(dict, "ID");
+ obj = pdf_dict_gets(dict, "ID");
if (obj)
{
if (*id)
- fz_drop_obj(*id);
- *id = fz_keep_obj(obj);
+ pdf_drop_obj(*id);
+ *id = pdf_keep_obj(obj);
}
}
- obj = fz_dict_gets(dict, "Length");
- if (!fz_is_indirect(obj) && fz_is_int(obj))
- stm_len = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "Length");
+ if (!pdf_is_indirect(obj) && pdf_is_int(obj))
+ stm_len = pdf_to_int(obj);
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
}
while ( tok != PDF_TOK_STREAM &&
@@ -79,13 +78,13 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp,
tok != PDF_TOK_EOF &&
tok != PDF_TOK_INT )
{
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot scan for endobj or stream token" */
}
if (tok == PDF_TOK_INT)
{
- while (len-- > 0)
+ while (buf->len-- > 0)
fz_unread_byte(file);
}
else if (tok == PDF_TOK_STREAM)
@@ -106,7 +105,7 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp,
fz_seek(file, *stmofsp + stm_len, 0);
fz_try(ctx)
{
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
}
fz_catch(ctx)
{
@@ -117,23 +116,23 @@ pdf_repair_obj(fz_stream *file, char *buf, int cap, int *stmofsp, int *stmlenp,
fz_seek(file, *stmofsp, 0);
}
- n = fz_read(file, (unsigned char *) buf, 9);
+ n = fz_read(file, (unsigned char *) buf->scratch, 9);
if (n < 0)
fz_throw(ctx, "cannot read from file");
- while (memcmp(buf, "endstream", 9) != 0)
+ while (memcmp(buf->scratch, "endstream", 9) != 0)
{
c = fz_read_byte(file);
if (c == EOF)
break;
- memmove(buf, buf + 1, 8);
- buf[8] = c;
+ memmove(&buf->scratch[0], &buf->scratch[1], 8);
+ buf->scratch[8] = c;
}
*stmlenp = fz_tell(file) - *stmofsp - 9;
atobjend:
- tok = pdf_lex(file, buf, cap, &len);
+ tok = pdf_lex(file, buf);
/* RJW: "cannot scan for endobj token" */
if (tok != PDF_TOK_ENDOBJ)
fz_warn(ctx, "object missing 'endobj' token");
@@ -143,43 +142,45 @@ atobjend:
static void
pdf_repair_obj_stm(pdf_document *xref, int num, int gen)
{
- fz_obj *obj;
+ pdf_obj *obj;
fz_stream *stm = NULL;
int tok;
int i, n, count;
- char buf[256];
fz_context *ctx = xref->ctx;
+ pdf_lexbuf buf;
fz_var(stm);
+ buf.size = PDF_LEXBUF_SMALL;
+
fz_try(ctx)
{
obj = pdf_load_object(xref, num, gen);
- count = fz_to_int(fz_dict_gets(obj, "N"));
+ count = pdf_to_int(pdf_dict_gets(obj, "N"));
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
stm = pdf_open_stream(xref, num, gen);
for (i = 0; i < count; i++)
{
- tok = pdf_lex(stm, buf, sizeof buf, &n);
+ tok = pdf_lex(stm, &buf);
if (tok != PDF_TOK_INT)
fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen);
- n = atoi(buf);
+ n = buf.i;
if (n >= xref->len)
pdf_resize_xref(xref, n + 1);
xref->table[n].ofs = num;
xref->table[n].gen = i;
xref->table[n].stm_ofs = 0;
- fz_drop_obj(xref->table[n].obj);
+ pdf_drop_obj(xref->table[n].obj);
xref->table[n].obj = NULL;
xref->table[n].type = 'o';
- tok = pdf_lex(stm, buf, sizeof buf, &n);
+ tok = pdf_lex(stm, &buf);
if (tok != PDF_TOK_INT)
fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen);
}
@@ -195,15 +196,15 @@ pdf_repair_obj_stm(pdf_document *xref, int num, int gen)
}
void
-pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
+pdf_repair_xref(pdf_document *xref, pdf_lexbuf *buf)
{
- fz_obj *dict, *obj;
- fz_obj *length;
+ pdf_obj *dict, *obj;
+ pdf_obj *length;
- fz_obj *encrypt = NULL;
- fz_obj *id = NULL;
- fz_obj *root = NULL;
- fz_obj *info = NULL;
+ pdf_obj *encrypt = NULL;
+ pdf_obj *id = NULL;
+ pdf_obj *root = NULL;
+ pdf_obj *info = NULL;
struct entry *list = NULL;
int listlen;
@@ -234,14 +235,14 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
list = fz_malloc_array(ctx, listcap, sizeof(struct entry));
/* look for '%PDF' version marker within first kilobyte of file */
- n = fz_read(xref->file, (unsigned char *)buf, MIN(bufsize, 1024));
+ n = fz_read(xref->file, (unsigned char *)buf->scratch, MIN(buf->size, 1024));
if (n < 0)
fz_throw(ctx, "cannot read from file");
fz_seek(xref->file, 0, 0);
for (i = 0; i < n - 4; i++)
{
- if (memcmp(buf + i, "%PDF", 4) == 0)
+ if (memcmp(&buf->scratch[i], "%PDF", 4) == 0)
{
fz_seek(xref->file, i + 8, 0); /* skip "%PDF-X.Y" */
break;
@@ -263,7 +264,7 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
fz_try(ctx)
{
- tok = pdf_lex(xref->file, buf, bufsize, &n);
+ tok = pdf_lex(xref->file, buf);
}
fz_catch(ctx)
{
@@ -276,14 +277,14 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
numofs = genofs;
num = gen;
genofs = tmpofs;
- gen = atoi(buf);
+ gen = buf->i;
}
else if (tok == PDF_TOK_OBJ)
{
fz_try(ctx)
{
- pdf_repair_obj(xref->file, buf, bufsize, &stm_ofs, &stm_len, &encrypt, &id);
+ pdf_repair_obj(xref->file, buf, &stm_ofs, &stm_len, &encrypt, &id);
}
fz_catch(ctx)
{
@@ -318,7 +319,7 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
{
fz_try(ctx)
{
- dict = pdf_parse_dict(xref, xref->file, buf, bufsize);
+ dict = pdf_parse_dict(xref, xref->file, buf);
}
fz_catch(ctx)
{
@@ -331,39 +332,39 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
break;
}
- obj = fz_dict_gets(dict, "Encrypt");
+ obj = pdf_dict_gets(dict, "Encrypt");
if (obj)
{
if (encrypt)
- fz_drop_obj(encrypt);
- encrypt = fz_keep_obj(obj);
+ pdf_drop_obj(encrypt);
+ encrypt = pdf_keep_obj(obj);
}
- obj = fz_dict_gets(dict, "ID");
+ obj = pdf_dict_gets(dict, "ID");
if (obj)
{
if (id)
- fz_drop_obj(id);
- id = fz_keep_obj(obj);
+ pdf_drop_obj(id);
+ id = pdf_keep_obj(obj);
}
- obj = fz_dict_gets(dict, "Root");
+ obj = pdf_dict_gets(dict, "Root");
if (obj)
{
if (root)
- fz_drop_obj(root);
- root = fz_keep_obj(obj);
+ pdf_drop_obj(root);
+ root = pdf_keep_obj(obj);
}
- obj = fz_dict_gets(dict, "Info");
+ obj = pdf_dict_gets(dict, "Info");
if (obj)
{
if (info)
- fz_drop_obj(info);
- info = fz_keep_obj(obj);
+ pdf_drop_obj(info);
+ info = pdf_keep_obj(obj);
}
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
}
else if (tok == PDF_TOK_ERROR)
@@ -393,11 +394,11 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
fz_lock(ctx, FZ_LOCK_FILE);
/* RJW: "cannot load stream object (%d %d R)", list[i].num, list[i].gen */
- length = fz_new_int(ctx, list[i].stm_len);
- fz_dict_puts(dict, "Length", length);
- fz_drop_obj(length);
+ length = pdf_new_int(ctx, list[i].stm_len);
+ pdf_dict_puts(dict, "Length", length);
+ pdf_drop_obj(length);
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
}
}
@@ -422,57 +423,57 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
/* create a repaired trailer, Root will be added later */
- xref->trailer = fz_new_dict(ctx, 5);
+ xref->trailer = pdf_new_dict(ctx, 5);
- obj = fz_new_int(ctx, maxnum + 1);
- fz_dict_puts(xref->trailer, "Size", obj);
- fz_drop_obj(obj);
+ obj = pdf_new_int(ctx, maxnum + 1);
+ pdf_dict_puts(xref->trailer, "Size", obj);
+ pdf_drop_obj(obj);
if (root)
{
- fz_dict_puts(xref->trailer, "Root", root);
- fz_drop_obj(root);
+ pdf_dict_puts(xref->trailer, "Root", root);
+ pdf_drop_obj(root);
}
if (info)
{
- fz_dict_puts(xref->trailer, "Info", info);
- fz_drop_obj(info);
+ pdf_dict_puts(xref->trailer, "Info", info);
+ pdf_drop_obj(info);
}
if (encrypt)
{
- if (fz_is_indirect(encrypt))
+ if (pdf_is_indirect(encrypt))
{
/* create new reference with non-NULL xref pointer */
- obj = fz_new_indirect(ctx, fz_to_num(encrypt), fz_to_gen(encrypt), xref);
- fz_drop_obj(encrypt);
+ obj = pdf_new_indirect(ctx, pdf_to_num(encrypt), pdf_to_gen(encrypt), xref);
+ pdf_drop_obj(encrypt);
encrypt = obj;
}
- fz_dict_puts(xref->trailer, "Encrypt", encrypt);
- fz_drop_obj(encrypt);
+ pdf_dict_puts(xref->trailer, "Encrypt", encrypt);
+ pdf_drop_obj(encrypt);
}
if (id)
{
- if (fz_is_indirect(id))
+ if (pdf_is_indirect(id))
{
/* create new reference with non-NULL xref pointer */
- obj = fz_new_indirect(ctx, fz_to_num(id), fz_to_gen(id), xref);
- fz_drop_obj(id);
+ obj = pdf_new_indirect(ctx, pdf_to_num(id), pdf_to_gen(id), xref);
+ pdf_drop_obj(id);
id = obj;
}
- fz_dict_puts(xref->trailer, "ID", id);
- fz_drop_obj(id);
+ pdf_dict_puts(xref->trailer, "ID", id);
+ pdf_drop_obj(id);
}
fz_free(ctx, list);
}
fz_catch(ctx)
{
- if (encrypt) fz_drop_obj(encrypt);
- if (id) fz_drop_obj(id);
- if (root) fz_drop_obj(root);
- if (info) fz_drop_obj(info);
+ if (encrypt) pdf_drop_obj(encrypt);
+ if (id) pdf_drop_obj(id);
+ if (root) pdf_drop_obj(root);
+ if (info) pdf_drop_obj(info);
fz_free(ctx, list);
fz_rethrow(ctx);
}
@@ -481,7 +482,7 @@ pdf_repair_xref(pdf_document *xref, char *buf, int bufsize)
void
pdf_repair_obj_stms(pdf_document *xref)
{
- fz_obj *dict;
+ pdf_obj *dict;
int i;
for (i = 0; i < xref->len; i++)
@@ -489,9 +490,9 @@ pdf_repair_obj_stms(pdf_document *xref)
if (xref->table[i].stm_ofs)
{
dict = pdf_load_object(xref, i, 0);
- if (!strcmp(fz_to_name(fz_dict_gets(dict, "Type")), "ObjStm"))
+ if (!strcmp(pdf_to_name(pdf_dict_gets(dict, "Type")), "ObjStm"))
pdf_repair_obj_stm(xref, i, 0);
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
}
}
diff --git a/pdf/pdf_shade.c b/pdf/pdf_shade.c
index fb5dd72c..589b7613 100644
--- a/pdf/pdf_shade.c
+++ b/pdf/pdf_shade.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#define HUGENUM 32000 /* how far to extend axial/radial shadings */
#define FUNSEGS 32 /* size of sampled mesh for function-based shadings */
@@ -363,9 +363,9 @@ pdf_sample_shade_function(fz_context *ctx, fz_shade *shade, int funcs, pdf_funct
/* Type 1-3 -- Function-based, axial and radial shadings */
static void
-pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, fz_obj *dict, pdf_function *func)
+pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, pdf_function *func)
{
- fz_obj *obj;
+ pdf_obj *obj;
float x0, y0, x1, y1;
fz_matrix matrix;
struct vertex v[4];
@@ -377,18 +377,18 @@ pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, fz_obj *dic
x0 = y0 = 0;
x1 = y1 = 1;
- obj = fz_dict_gets(dict, "Domain");
- if (fz_array_len(obj) == 4)
+ obj = pdf_dict_gets(dict, "Domain");
+ if (pdf_array_len(obj) == 4)
{
- x0 = fz_to_real(fz_array_get(obj, 0));
- x1 = fz_to_real(fz_array_get(obj, 1));
- y0 = fz_to_real(fz_array_get(obj, 2));
- y1 = fz_to_real(fz_array_get(obj, 3));
+ x0 = pdf_to_real(pdf_array_get(obj, 0));
+ x1 = pdf_to_real(pdf_array_get(obj, 1));
+ y0 = pdf_to_real(pdf_array_get(obj, 2));
+ y1 = pdf_to_real(pdf_array_get(obj, 3));
}
matrix = fz_identity;
- obj = fz_dict_gets(dict, "Matrix");
- if (fz_array_len(obj) == 6)
+ obj = pdf_dict_gets(dict, "Matrix");
+ if (pdf_array_len(obj) == 6)
matrix = pdf_to_matrix(ctx, obj);
for (yy = 0; yy < FUNSEGS; yy++)
@@ -428,36 +428,36 @@ pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, fz_obj *dic
}
static void
-pdf_load_axial_shading(fz_shade *shade, pdf_document *xref, fz_obj *dict, int funcs, pdf_function **func)
+pdf_load_axial_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, int funcs, pdf_function **func)
{
- fz_obj *obj;
+ pdf_obj *obj;
float d0, d1;
int e0, e1;
float x0, y0, x1, y1;
struct vertex p1, p2;
fz_context *ctx = xref->ctx;
- obj = fz_dict_gets(dict, "Coords");
- x0 = fz_to_real(fz_array_get(obj, 0));
- y0 = fz_to_real(fz_array_get(obj, 1));
- x1 = fz_to_real(fz_array_get(obj, 2));
- y1 = fz_to_real(fz_array_get(obj, 3));
+ obj = pdf_dict_gets(dict, "Coords");
+ x0 = pdf_to_real(pdf_array_get(obj, 0));
+ y0 = pdf_to_real(pdf_array_get(obj, 1));
+ x1 = pdf_to_real(pdf_array_get(obj, 2));
+ y1 = pdf_to_real(pdf_array_get(obj, 3));
d0 = 0;
d1 = 1;
- obj = fz_dict_gets(dict, "Domain");
- if (fz_array_len(obj) == 2)
+ obj = pdf_dict_gets(dict, "Domain");
+ if (pdf_array_len(obj) == 2)
{
- d0 = fz_to_real(fz_array_get(obj, 0));
- d1 = fz_to_real(fz_array_get(obj, 1));
+ d0 = pdf_to_real(pdf_array_get(obj, 0));
+ d1 = pdf_to_real(pdf_array_get(obj, 1));
}
e0 = e1 = 0;
- obj = fz_dict_gets(dict, "Extend");
- if (fz_array_len(obj) == 2)
+ obj = pdf_dict_gets(dict, "Extend");
+ if (pdf_array_len(obj) == 2)
{
- e0 = fz_to_bool(fz_array_get(obj, 0));
- e1 = fz_to_bool(fz_array_get(obj, 1));
+ e0 = pdf_to_bool(pdf_array_get(obj, 0));
+ e1 = pdf_to_bool(pdf_array_get(obj, 1));
}
pdf_sample_shade_function(ctx, shade, funcs, func, d0, d1);
@@ -479,38 +479,38 @@ pdf_load_axial_shading(fz_shade *shade, pdf_document *xref, fz_obj *dict, int fu
}
static void
-pdf_load_radial_shading(fz_shade *shade, pdf_document *xref, fz_obj *dict, int funcs, pdf_function **func)
+pdf_load_radial_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, int funcs, pdf_function **func)
{
- fz_obj *obj;
+ pdf_obj *obj;
float d0, d1;
int e0, e1;
float x0, y0, r0, x1, y1, r1;
struct vertex p1, p2;
fz_context *ctx = xref->ctx;
- obj = fz_dict_gets(dict, "Coords");
- x0 = fz_to_real(fz_array_get(obj, 0));
- y0 = fz_to_real(fz_array_get(obj, 1));
- r0 = fz_to_real(fz_array_get(obj, 2));
- x1 = fz_to_real(fz_array_get(obj, 3));
- y1 = fz_to_real(fz_array_get(obj, 4));
- r1 = fz_to_real(fz_array_get(obj, 5));
+ obj = pdf_dict_gets(dict, "Coords");
+ x0 = pdf_to_real(pdf_array_get(obj, 0));
+ y0 = pdf_to_real(pdf_array_get(obj, 1));
+ r0 = pdf_to_real(pdf_array_get(obj, 2));
+ x1 = pdf_to_real(pdf_array_get(obj, 3));
+ y1 = pdf_to_real(pdf_array_get(obj, 4));
+ r1 = pdf_to_real(pdf_array_get(obj, 5));
d0 = 0;
d1 = 1;
- obj = fz_dict_gets(dict, "Domain");
- if (fz_array_len(obj) == 2)
+ obj = pdf_dict_gets(dict, "Domain");
+ if (pdf_array_len(obj) == 2)
{
- d0 = fz_to_real(fz_array_get(obj, 0));
- d1 = fz_to_real(fz_array_get(obj, 1));
+ d0 = pdf_to_real(pdf_array_get(obj, 0));
+ d1 = pdf_to_real(pdf_array_get(obj, 1));
}
e0 = e1 = 0;
- obj = fz_dict_gets(dict, "Extend");
- if (fz_array_len(obj) == 2)
+ obj = pdf_dict_gets(dict, "Extend");
+ if (pdf_array_len(obj) == 2)
{
- e0 = fz_to_bool(fz_array_get(obj, 0));
- e1 = fz_to_bool(fz_array_get(obj, 1));
+ e0 = pdf_to_bool(pdf_array_get(obj, 0));
+ e1 = pdf_to_bool(pdf_array_get(obj, 1));
}
pdf_sample_shade_function(ctx, shade, funcs, func, d0, d1);
@@ -553,9 +553,9 @@ struct mesh_params
};
static void
-pdf_load_mesh_params(pdf_document *xref, fz_obj *dict, struct mesh_params *p)
+pdf_load_mesh_params(pdf_document *xref, pdf_obj *dict, struct mesh_params *p)
{
- fz_obj *obj;
+ pdf_obj *obj;
int i, n;
p->x0 = p->y0 = 0;
@@ -566,23 +566,23 @@ pdf_load_mesh_params(pdf_document *xref, fz_obj *dict, struct mesh_params *p)
p->c1[i] = 1;
}
- p->vprow = fz_to_int(fz_dict_gets(dict, "VerticesPerRow"));
- p->bpflag = fz_to_int(fz_dict_gets(dict, "BitsPerFlag"));
- p->bpcoord = fz_to_int(fz_dict_gets(dict, "BitsPerCoordinate"));
- p->bpcomp = fz_to_int(fz_dict_gets(dict, "BitsPerComponent"));
+ p->vprow = pdf_to_int(pdf_dict_gets(dict, "VerticesPerRow"));
+ p->bpflag = pdf_to_int(pdf_dict_gets(dict, "BitsPerFlag"));
+ p->bpcoord = pdf_to_int(pdf_dict_gets(dict, "BitsPerCoordinate"));
+ p->bpcomp = pdf_to_int(pdf_dict_gets(dict, "BitsPerComponent"));
- obj = fz_dict_gets(dict, "Decode");
- if (fz_array_len(obj) >= 6)
+ obj = pdf_dict_gets(dict, "Decode");
+ if (pdf_array_len(obj) >= 6)
{
- n = (fz_array_len(obj) - 4) / 2;
- p->x0 = fz_to_real(fz_array_get(obj, 0));
- p->x1 = fz_to_real(fz_array_get(obj, 1));
- p->y0 = fz_to_real(fz_array_get(obj, 2));
- p->y1 = fz_to_real(fz_array_get(obj, 3));
+ n = (pdf_array_len(obj) - 4) / 2;
+ p->x0 = pdf_to_real(pdf_array_get(obj, 0));
+ p->x1 = pdf_to_real(pdf_array_get(obj, 1));
+ p->y0 = pdf_to_real(pdf_array_get(obj, 2));
+ p->y1 = pdf_to_real(pdf_array_get(obj, 3));
for (i = 0; i < n; i++)
{
- p->c0[i] = fz_to_real(fz_array_get(obj, 4 + i * 2));
- p->c1[i] = fz_to_real(fz_array_get(obj, 5 + i * 2));
+ p->c0[i] = pdf_to_real(pdf_array_get(obj, 4 + i * 2));
+ p->c1[i] = pdf_to_real(pdf_array_get(obj, 5 + i * 2));
}
}
@@ -603,7 +603,7 @@ pdf_load_mesh_params(pdf_document *xref, fz_obj *dict, struct mesh_params *p)
}
static void
-pdf_load_type4_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
+pdf_load_type4_shade(fz_shade *shade, pdf_document *xref, pdf_obj *dict,
int funcs, pdf_function **func)
{
fz_context *ctx = xref->ctx;
@@ -624,7 +624,7 @@ pdf_load_type4_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
else
ncomp = shade->colorspace->n;
- stream = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ stream = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
while (!fz_is_eof_bits(stream))
{
@@ -672,7 +672,7 @@ pdf_load_type4_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
}
static void
-pdf_load_type5_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
+pdf_load_type5_shade(fz_shade *shade, pdf_document *xref, pdf_obj *dict,
int funcs, pdf_function **func)
{
fz_context *ctx = xref->ctx;
@@ -697,7 +697,7 @@ pdf_load_type5_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
buf = fz_malloc_array(ctx, p.vprow, sizeof(struct vertex));
first = 1;
- stream = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ stream = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
while (!fz_is_eof_bits(stream))
{
@@ -726,7 +726,7 @@ pdf_load_type5_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
/* Type 6 & 7 -- Patch mesh shadings */
static void
-pdf_load_type6_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
+pdf_load_type6_shade(fz_shade *shade, pdf_document *xref, pdf_obj *dict,
int funcs, pdf_function **func)
{
fz_context *ctx = xref->ctx;
@@ -750,7 +750,7 @@ pdf_load_type6_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
hasprevpatch = 0;
- stream = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ stream = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
while (!fz_is_eof_bits(stream))
{
@@ -849,7 +849,7 @@ pdf_load_type6_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
}
static void
-pdf_load_type7_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
+pdf_load_type7_shade(fz_shade *shade, pdf_document *xref, pdf_obj *dict,
int funcs, pdf_function **func)
{
fz_context *ctx = xref->ctx;
@@ -873,7 +873,7 @@ pdf_load_type7_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
hasprevpatch = 0;
- stream = pdf_open_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ stream = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
while (!fz_is_eof_bits(stream))
{
@@ -974,11 +974,11 @@ pdf_load_type7_shade(fz_shade *shade, pdf_document *xref, fz_obj *dict,
/* Load all of the shading dictionary parameters, then switch on the shading type. */
static fz_shade *
-pdf_load_shading_dict(pdf_document *xref, fz_obj *dict, fz_matrix transform)
+pdf_load_shading_dict(pdf_document *xref, pdf_obj *dict, fz_matrix transform)
{
fz_shade *shade = NULL;
pdf_function *func[FZ_MAX_COLORS] = { NULL };
- fz_obj *obj;
+ pdf_obj *obj;
int funcs = 0;
int type = 0;
int i;
@@ -1009,49 +1009,49 @@ pdf_load_shading_dict(pdf_document *xref, fz_obj *dict, fz_matrix transform)
funcs = 0;
- obj = fz_dict_gets(dict, "ShadingType");
- type = fz_to_int(obj);
+ obj = pdf_dict_gets(dict, "ShadingType");
+ type = pdf_to_int(obj);
- obj = fz_dict_gets(dict, "ColorSpace");
+ obj = pdf_dict_gets(dict, "ColorSpace");
if (!obj)
fz_throw(ctx, "shading colorspace is missing");
shade->colorspace = pdf_load_colorspace(xref, obj);
- /* RJW: "cannot load colorspace (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ /* RJW: "cannot load colorspace (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
- obj = fz_dict_gets(dict, "Background");
+ obj = pdf_dict_gets(dict, "Background");
if (obj)
{
shade->use_background = 1;
for (i = 0; i < shade->colorspace->n; i++)
- shade->background[i] = fz_to_real(fz_array_get(obj, i));
+ shade->background[i] = pdf_to_real(pdf_array_get(obj, i));
}
- obj = fz_dict_gets(dict, "BBox");
- if (fz_is_array(obj))
+ obj = pdf_dict_gets(dict, "BBox");
+ if (pdf_is_array(obj))
{
shade->bbox = pdf_to_rect(ctx, obj);
}
- obj = fz_dict_gets(dict, "Function");
- if (fz_is_dict(obj))
+ obj = pdf_dict_gets(dict, "Function");
+ if (pdf_is_dict(obj))
{
funcs = 1;
func[0] = pdf_load_function(xref, obj);
if (!func[0])
- fz_throw(ctx, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
}
- else if (fz_is_array(obj))
+ else if (pdf_is_array(obj))
{
- funcs = fz_array_len(obj);
+ funcs = pdf_array_len(obj);
if (funcs != 1 && funcs != shade->colorspace->n)
fz_throw(ctx, "incorrect number of shading functions");
for (i = 0; i < funcs; i++)
{
- func[i] = pdf_load_function(xref, fz_array_get(obj, i));
+ func[i] = pdf_load_function(xref, pdf_array_get(obj, i));
if (!func[i])
- fz_throw(ctx, "cannot load shading function (%d %d R)", fz_to_num(obj), fz_to_gen(obj));
+ fz_throw(ctx, "cannot load shading function (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj));
}
}
@@ -1079,7 +1079,7 @@ pdf_load_shading_dict(pdf_document *xref, fz_obj *dict, fz_matrix transform)
pdf_drop_function(ctx, func[i]);
fz_drop_shade(ctx, shade);
- fz_throw(ctx, "cannot load shading type %d (%d %d R)", type, fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "cannot load shading type %d (%d %d R)", type, pdf_to_num(dict), pdf_to_gen(dict));
}
return shade;
}
@@ -1093,52 +1093,52 @@ fz_shade_size(fz_shade *s)
}
fz_shade *
-pdf_load_shading(pdf_document *xref, fz_obj *dict)
+pdf_load_shading(pdf_document *xref, pdf_obj *dict)
{
fz_matrix mat;
- fz_obj *obj;
+ pdf_obj *obj;
fz_context *ctx = xref->ctx;
fz_shade *shade;
- if ((shade = fz_find_item(ctx, fz_free_shade_imp, dict)))
+ if ((shade = pdf_find_item(ctx, fz_free_shade_imp, dict)))
{
return shade;
}
/* Type 2 pattern dictionary */
- if (fz_dict_gets(dict, "PatternType"))
+ if (pdf_dict_gets(dict, "PatternType"))
{
- obj = fz_dict_gets(dict, "Matrix");
+ obj = pdf_dict_gets(dict, "Matrix");
if (obj)
mat = pdf_to_matrix(ctx, obj);
else
mat = fz_identity;
- obj = fz_dict_gets(dict, "ExtGState");
+ obj = pdf_dict_gets(dict, "ExtGState");
if (obj)
{
- if (fz_dict_gets(obj, "CA") || fz_dict_gets(obj, "ca"))
+ if (pdf_dict_gets(obj, "CA") || pdf_dict_gets(obj, "ca"))
{
fz_warn(ctx, "shading with alpha not supported");
}
}
- obj = fz_dict_gets(dict, "Shading");
+ obj = pdf_dict_gets(dict, "Shading");
if (!obj)
fz_throw(ctx, "syntaxerror: missing shading dictionary");
shade = pdf_load_shading_dict(xref, obj, mat);
- /* RJW: "cannot load shading dictionary (%d %d R)", fz_to_num(obj), fz_to_gen(obj) */
+ /* RJW: "cannot load shading dictionary (%d %d R)", pdf_to_num(obj), pdf_to_gen(obj) */
}
/* Naked shading dictionary */
else
{
shade = pdf_load_shading_dict(xref, dict, fz_identity);
- /* RJW: "cannot load shading dictionary (%d %d R)", fz_to_num(dict), fz_to_gen(dict) */
+ /* RJW: "cannot load shading dictionary (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */
}
- fz_store_item(ctx, dict, shade, fz_shade_size(shade));
+ pdf_store_item(ctx, dict, shade, fz_shade_size(shade));
return shade;
}
diff --git a/pdf/pdf_store.c b/pdf/pdf_store.c
new file mode 100644
index 00000000..2a3b8b07
--- /dev/null
+++ b/pdf/pdf_store.c
@@ -0,0 +1,74 @@
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
+
+static int
+pdf_make_hash_key(fz_store_hash *hash, void *key_)
+{
+ pdf_obj *key = (pdf_obj *)key_;
+
+ if (!pdf_is_indirect(key))
+ return 0;
+ hash->u.i.i0 = pdf_to_num(key);
+ hash->u.i.i1 = pdf_to_gen(key);
+ return 1;
+}
+
+static void *
+pdf_keep_key(fz_context *ctx, void *key)
+{
+ return (void *)pdf_keep_obj((pdf_obj *)key);
+}
+
+static void
+pdf_drop_key(fz_context *ctx, void *key)
+{
+ pdf_drop_obj((pdf_obj *)key);
+}
+
+static int
+pdf_cmp_key(void *k0, void *k1)
+{
+ return pdf_objcmp((pdf_obj *)k0, (pdf_obj *)k1);
+}
+
+static void
+pdf_debug_key(void *key_)
+{
+ pdf_obj *key = (pdf_obj *)key_;
+
+ if (pdf_is_indirect(key))
+ {
+ printf("(%d %d R) ", pdf_to_num(key), pdf_to_gen(key));
+ } else
+ pdf_print_obj(key);
+}
+
+static fz_store_type pdf_obj_store_type =
+{
+ pdf_make_hash_key,
+ pdf_keep_key,
+ pdf_drop_key,
+ pdf_cmp_key,
+ pdf_debug_key
+};
+
+void
+pdf_store_item(fz_context *ctx, pdf_obj *key, void *val, unsigned int itemsize)
+{
+ void *existing;
+ existing = fz_store_item(ctx, key, val, itemsize, &pdf_obj_store_type);
+ assert(existing == NULL);
+}
+
+void *
+pdf_find_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key)
+{
+ return fz_find_item(ctx, free, key, &pdf_obj_store_type);
+}
+
+void
+pdf_remove_item(fz_context *ctx, fz_store_free_fn *free, pdf_obj *key)
+{
+ fz_remove_item(ctx, free, key, &pdf_obj_store_type);
+}
+
diff --git a/pdf/pdf_stream.c b/pdf/pdf_stream.c
index c66e703e..84f966ec 100644
--- a/pdf/pdf_stream.c
+++ b/pdf/pdf_stream.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
/*
* Check if an object is a stream or not.
@@ -20,24 +20,24 @@ pdf_is_stream(pdf_document *xref, int num, int gen)
* Scan stream dictionary for an explicit /Crypt filter
*/
static int
-pdf_stream_has_crypt(fz_context *ctx, fz_obj *stm)
+pdf_stream_has_crypt(fz_context *ctx, pdf_obj *stm)
{
- fz_obj *filters;
- fz_obj *obj;
+ pdf_obj *filters;
+ pdf_obj *obj;
int i;
- filters = fz_dict_getsa(stm, "Filter", "F");
+ filters = pdf_dict_getsa(stm, "Filter", "F");
if (filters)
{
- if (!strcmp(fz_to_name(filters), "Crypt"))
+ if (!strcmp(pdf_to_name(filters), "Crypt"))
return 1;
- if (fz_is_array(filters))
+ if (pdf_is_array(filters))
{
- int n = fz_array_len(filters);
+ int n = pdf_array_len(filters);
for (i = 0; i < n; i++)
{
- obj = fz_array_get(filters, i);
- if (!strcmp(fz_to_name(obj), "Crypt"))
+ obj = pdf_array_get(filters, i);
+ if (!strcmp(pdf_to_name(obj), "Crypt"))
return 1;
}
}
@@ -49,15 +49,15 @@ pdf_stream_has_crypt(fz_context *ctx, fz_obj *stm)
* Create a filter given a name and param dictionary.
*/
static fz_stream *
-build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int num, int gen)
+build_filter(fz_stream *chain, pdf_document * xref, pdf_obj * f, pdf_obj * p, int num, int gen, pdf_image_params *params)
{
fz_context *ctx = chain->ctx;
- char *s = fz_to_name(f);
+ char *s = pdf_to_name(f);
- int predictor = fz_to_int(fz_dict_gets(p, "Predictor"));
- int columns = fz_to_int(fz_dict_gets(p, "Columns"));
- int colors = fz_to_int(fz_dict_gets(p, "Colors"));
- int bpc = fz_to_int(fz_dict_gets(p, "BitsPerComponent"));
+ int predictor = pdf_to_int(pdf_dict_gets(p, "Predictor"));
+ int columns = pdf_to_int(pdf_dict_gets(p, "Columns"));
+ int colors = pdf_to_int(pdf_dict_gets(p, "Colors"));
+ int bpc = pdf_to_int(pdf_dict_gets(p, "BitsPerComponent"));
if (predictor == 0) predictor = 1;
if (columns == 0) columns = 1;
@@ -72,34 +72,71 @@ build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int
else if (!strcmp(s, "CCITTFaxDecode") || !strcmp(s, "CCF"))
{
- fz_obj *k = fz_dict_gets(p, "K");
- fz_obj *eol = fz_dict_gets(p, "EndOfLine");
- fz_obj *eba = fz_dict_gets(p, "EncodedByteAlign");
- fz_obj *columns = fz_dict_gets(p, "Columns");
- fz_obj *rows = fz_dict_gets(p, "Rows");
- fz_obj *eob = fz_dict_gets(p, "EndOfBlock");
- fz_obj *bi1 = fz_dict_gets(p, "BlackIs1");
+ pdf_obj *k = pdf_dict_gets(p, "K");
+ pdf_obj *eol = pdf_dict_gets(p, "EndOfLine");
+ pdf_obj *eba = pdf_dict_gets(p, "EncodedByteAlign");
+ pdf_obj *columns = pdf_dict_gets(p, "Columns");
+ pdf_obj *rows = pdf_dict_gets(p, "Rows");
+ pdf_obj *eob = pdf_dict_gets(p, "EndOfBlock");
+ pdf_obj *bi1 = pdf_dict_gets(p, "BlackIs1");
+ if (params)
+ {
+ /* We will shortstop here */
+ params->type = PDF_IMAGE_FAX;
+ params->u.fax.k = (k ? pdf_to_int(k) : 0);
+ params->u.fax.eol = (eol ? pdf_to_bool(eol) : 0);
+ params->u.fax.eba = (eba ? pdf_to_bool(eba) : 0);
+ params->u.fax.columns = (columns ? pdf_to_int(columns) : 1728);
+ params->u.fax.rows = (rows ? pdf_to_int(rows) : 0);
+ params->u.fax.eob = (eob ? pdf_to_bool(eob) : 1);
+ params->u.fax.bi1 = (bi1 ? pdf_to_bool(bi1) : 0);
+ return chain;
+ }
return fz_open_faxd(chain,
- k ? fz_to_int(k) : 0,
- eol ? fz_to_bool(eol) : 0,
- eba ? fz_to_bool(eba) : 0,
- columns ? fz_to_int(columns) : 1728,
- rows ? fz_to_int(rows) : 0,
- eob ? fz_to_bool(eob) : 1,
- bi1 ? fz_to_bool(bi1) : 0);
+ k ? pdf_to_int(k) : 0,
+ eol ? pdf_to_bool(eol) : 0,
+ eba ? pdf_to_bool(eba) : 0,
+ columns ? pdf_to_int(columns) : 1728,
+ rows ? pdf_to_int(rows) : 0,
+ eob ? pdf_to_bool(eob) : 1,
+ bi1 ? pdf_to_bool(bi1) : 0);
}
else if (!strcmp(s, "DCTDecode") || !strcmp(s, "DCT"))
{
- fz_obj *ct = fz_dict_gets(p, "ColorTransform");
- return fz_open_dctd(chain, ct ? fz_to_int(ct) : -1);
+ pdf_obj *ct = pdf_dict_gets(p, "ColorTransform");
+ if (params)
+ {
+ /* We will shortstop here */
+ params->type = PDF_IMAGE_JPEG;
+ params->u.jpeg.ct = (ct ? pdf_to_int(ct) : -1);
+ return chain;
+ }
+ return fz_open_dctd(chain, ct ? pdf_to_int(ct) : -1);
}
else if (!strcmp(s, "RunLengthDecode") || !strcmp(s, "RL"))
+ {
+ if (params)
+ {
+ /* We will shortstop here */
+ params->type = PDF_IMAGE_RLD;
+ return chain;
+ }
return fz_open_rld(chain);
-
+ }
else if (!strcmp(s, "FlateDecode") || !strcmp(s, "Fl"))
{
+ if (params)
+ {
+ /* We will shortstop here */
+ params->type = PDF_IMAGE_FLATE;
+ params->u.flate.predictor = predictor;
+ params->u.flate.columns = columns;
+ params->u.flate.colors = colors;
+ params->u.flate.bpc = bpc;
+ return chain;
+ }
chain = fz_open_flated(chain);
if (predictor > 1)
chain = fz_open_predict(chain, predictor, columns, colors, bpc);
@@ -108,8 +145,19 @@ build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int
else if (!strcmp(s, "LZWDecode") || !strcmp(s, "LZW"))
{
- fz_obj *ec = fz_dict_gets(p, "EarlyChange");
- chain = fz_open_lzwd(chain, ec ? fz_to_int(ec) : 1);
+ pdf_obj *ec = pdf_dict_gets(p, "EarlyChange");
+ if (params)
+ {
+ /* We will shortstop here */
+ params->type = PDF_IMAGE_LZW;
+ params->u.lzw.predictor = predictor;
+ params->u.lzw.columns = columns;
+ params->u.lzw.colors = colors;
+ params->u.lzw.bpc = bpc;
+ params->u.lzw.ec = (ec ? pdf_to_int(ec) : 1);
+ return chain;
+ }
+ chain = fz_open_lzwd(chain, ec ? pdf_to_int(ec) : 1);
if (predictor > 1)
chain = fz_open_predict(chain, predictor, columns, colors, bpc);
return chain;
@@ -118,9 +166,9 @@ build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int
else if (!strcmp(s, "JBIG2Decode"))
{
fz_buffer *globals = NULL;
- fz_obj *obj = fz_dict_gets(p, "JBIG2Globals");
+ pdf_obj *obj = pdf_dict_gets(p, "JBIG2Globals");
if (obj)
- globals = pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj));
+ globals = pdf_load_stream(xref, pdf_to_num(obj), pdf_to_gen(obj));
/* fz_open_jbig2d takes possession of globals */
return fz_open_jbig2d(chain, globals);
}
@@ -130,7 +178,7 @@ build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int
else if (!strcmp(s, "Crypt"))
{
- fz_obj *name;
+ pdf_obj *name;
if (!xref->crypt)
{
@@ -138,9 +186,9 @@ build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int
return chain;
}
- name = fz_dict_gets(p, "Name");
- if (fz_is_name(name))
- return pdf_open_crypt_with_filter(chain, xref->crypt, fz_to_name(name), num, gen);
+ name = pdf_dict_gets(p, "Name");
+ if (pdf_is_name(name))
+ return pdf_open_crypt_with_filter(chain, xref->crypt, pdf_to_name(name), num, gen);
return chain;
}
@@ -155,18 +203,18 @@ build_filter(fz_stream *chain, pdf_document * xref, fz_obj * f, fz_obj * p, int
* Assume ownership of head.
*/
static fz_stream *
-build_filter_chain(fz_stream *chain, pdf_document *xref, fz_obj *fs, fz_obj *ps, int num, int gen)
+build_filter_chain(fz_stream *chain, pdf_document *xref, pdf_obj *fs, pdf_obj *ps, int num, int gen, pdf_image_params *params)
{
- fz_obj *f;
- fz_obj *p;
+ pdf_obj *f;
+ pdf_obj *p;
int i, n;
- n = fz_array_len(fs);
+ n = pdf_array_len(fs);
for (i = 0; i < n; i++)
{
- f = fz_array_get(fs, i);
- p = fz_array_get(ps, i);
- chain = build_filter(chain, xref, f, p, num, gen);
+ f = pdf_array_get(fs, i);
+ p = pdf_array_get(ps, i);
+ chain = build_filter(chain, xref, f, p, num, gen, (i == n-1 ? params : NULL));
}
return chain;
@@ -178,7 +226,7 @@ build_filter_chain(fz_stream *chain, pdf_document *xref, fz_obj *fs, fz_obj *ps,
* stream length, followed by a decryption filter.
*/
static fz_stream *
-pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, fz_obj *stmobj, int num, int gen)
+pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, int gen)
{
int hascrypt;
int len;
@@ -187,7 +235,7 @@ pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, fz_obj *stmobj, int nu
/* don't close chain when we close this filter */
fz_keep_stream(chain);
- len = fz_to_int(fz_dict_gets(stmobj, "Length"));
+ len = pdf_to_int(pdf_dict_gets(stmobj, "Length"));
chain = fz_open_null(chain, len);
fz_try(ctx)
@@ -210,20 +258,20 @@ pdf_open_raw_filter(fz_stream *chain, pdf_document *xref, fz_obj *stmobj, int nu
* to stream length and decrypting.
*/
static fz_stream *
-pdf_open_filter(fz_stream *chain, pdf_document *xref, fz_obj *stmobj, int num, int gen)
+pdf_open_filter(fz_stream *chain, pdf_document *xref, pdf_obj *stmobj, int num, int gen, pdf_image_params *imparams)
{
- fz_obj *filters;
- fz_obj *params;
+ pdf_obj *filters;
+ pdf_obj *params;
- filters = fz_dict_getsa(stmobj, "Filter", "F");
- params = fz_dict_getsa(stmobj, "DecodeParms", "DP");
+ filters = pdf_dict_getsa(stmobj, "Filter", "F");
+ params = pdf_dict_getsa(stmobj, "DecodeParms", "DP");
chain = pdf_open_raw_filter(chain, xref, stmobj, num, gen);
- if (fz_is_name(filters))
- chain = build_filter(chain, xref, filters, params, num, gen);
- else if (fz_array_len(filters) > 0)
- chain = build_filter_chain(chain, xref, filters, params, num, gen);
+ if (pdf_is_name(filters))
+ chain = build_filter(chain, xref, filters, params, num, gen, imparams);
+ else if (pdf_array_len(filters) > 0)
+ chain = build_filter_chain(chain, xref, filters, params, num, gen, imparams);
fz_lock_stream(chain);
return chain;
@@ -234,21 +282,21 @@ pdf_open_filter(fz_stream *chain, pdf_document *xref, fz_obj *stmobj, int num, i
* constraining to stream length, and without decryption.
*/
fz_stream *
-pdf_open_inline_stream(pdf_document *xref, fz_obj *stmobj, int length, fz_stream *chain)
+pdf_open_inline_stream(pdf_document *xref, pdf_obj *stmobj, int length, fz_stream *chain, pdf_image_params *imparams)
{
- fz_obj *filters;
- fz_obj *params;
+ pdf_obj *filters;
+ pdf_obj *params;
- filters = fz_dict_getsa(stmobj, "Filter", "F");
- params = fz_dict_getsa(stmobj, "DecodeParms", "DP");
+ filters = pdf_dict_getsa(stmobj, "Filter", "F");
+ params = pdf_dict_getsa(stmobj, "DecodeParms", "DP");
/* don't close chain when we close this filter */
fz_keep_stream(chain);
- if (fz_is_name(filters))
- return build_filter(chain, xref, filters, params, 0, 0);
- if (fz_array_len(filters) > 0)
- return build_filter_chain(chain, xref, filters, params, 0, 0);
+ if (pdf_is_name(filters))
+ return build_filter(chain, xref, filters, params, 0, 0, imparams);
+ if (pdf_array_len(filters) > 0)
+ return build_filter_chain(chain, xref, filters, params, 0, 0, imparams);
return fz_open_null(chain, length);
}
@@ -290,6 +338,12 @@ pdf_open_raw_stream(pdf_document *xref, int num, int gen)
fz_stream *
pdf_open_stream(pdf_document *xref, int num, int gen)
{
+ return pdf_open_image_stream(xref, num, gen, NULL);
+}
+
+fz_stream *
+pdf_open_image_stream(pdf_document *xref, int num, int gen, pdf_image_params *params)
+{
pdf_xref_entry *x;
fz_stream *stm;
@@ -304,20 +358,64 @@ pdf_open_stream(pdf_document *xref, int num, int gen)
if (x->stm_ofs == 0)
fz_throw(xref->ctx, "object is not a stream");
- stm = pdf_open_filter(xref->file, xref, x->obj, num, gen);
+ stm = pdf_open_filter(xref->file, xref, x->obj, num, gen, params);
fz_seek(xref->file, x->stm_ofs, 0);
return stm;
}
fz_stream *
-pdf_open_stream_with_offset(pdf_document *xref, int num, int gen, fz_obj *dict, int stm_ofs)
+pdf_open_image_decomp_stream(fz_context *ctx, fz_buffer *buffer, pdf_image_params *params, int *factor)
+{
+ fz_stream *chain = fz_open_buffer(ctx, buffer);
+
+ switch (params->type)
+ {
+ case PDF_IMAGE_FAX:
+ *factor = 1;
+ return fz_open_faxd(chain,
+ params->u.fax.k,
+ params->u.fax.eol,
+ params->u.fax.eba,
+ params->u.fax.columns,
+ params->u.fax.rows,
+ params->u.fax.eob,
+ params->u.fax.bi1);
+ case PDF_IMAGE_JPEG:
+ if (*factor > 8)
+ *factor = 8;
+ return fz_open_resized_dctd(chain, params->u.jpeg.ct, *factor);
+ case PDF_IMAGE_RLD:
+ *factor = 1;
+ return fz_open_rld(chain);
+ case PDF_IMAGE_FLATE:
+ *factor = 1;
+ chain = fz_open_flated(chain);
+ if (params->u.flate.predictor > 1)
+ chain = fz_open_predict(chain, params->u.flate.predictor, params->u.flate.columns, params->u.flate.colors, params->u.flate.bpc);
+ return chain;
+ case PDF_IMAGE_LZW:
+ *factor = 1;
+ chain = fz_open_lzwd(chain, params->u.lzw.ec);
+ if (params->u.lzw.predictor > 1)
+ chain = fz_open_predict(chain, params->u.lzw.predictor, params->u.lzw.columns, params->u.lzw.colors, params->u.lzw.bpc);
+ return chain;
+ default:
+ *factor = 1;
+ break;
+ }
+
+ return chain;
+}
+
+fz_stream *
+pdf_open_stream_with_offset(pdf_document *xref, int num, int gen, pdf_obj *dict, int stm_ofs)
{
fz_stream *stm;
if (stm_ofs == 0)
fz_throw(xref->ctx, "object is not a stream");
- stm = pdf_open_filter(xref->file, xref, dict, num, gen);
+ stm = pdf_open_filter(xref->file, xref, dict, num, gen, NULL);
fz_seek(xref->file, stm_ofs, 0);
return stm;
}
@@ -329,16 +427,16 @@ fz_buffer *
pdf_load_raw_stream(pdf_document *xref, int num, int gen)
{
fz_stream *stm;
- fz_obj *dict;
+ pdf_obj *dict;
int len;
fz_buffer *buf;
dict = pdf_load_object(xref, num, gen);
/* RJW: "cannot load stream dictionary (%d %d R)", num, gen */
- len = fz_to_int(fz_dict_gets(dict, "Length"));
+ len = pdf_to_int(pdf_dict_gets(dict, "Length"));
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
stm = pdf_open_raw_stream(xref, num, gen);
/* RJW: "cannot open raw stream (%d %d R)", num, gen */
@@ -372,9 +470,15 @@ pdf_guess_filter_length(int len, char *filter)
fz_buffer *
pdf_load_stream(pdf_document *xref, int num, int gen)
{
+ return pdf_load_image_stream(xref, num, gen, NULL);
+}
+
+fz_buffer *
+pdf_load_image_stream(pdf_document *xref, int num, int gen, pdf_image_params *params)
+{
fz_context *ctx = xref->ctx;
fz_stream *stm = NULL;
- fz_obj *dict, *obj;
+ pdf_obj *dict, *obj;
int i, len, n;
fz_buffer *buf;
@@ -383,16 +487,16 @@ pdf_load_stream(pdf_document *xref, int num, int gen)
dict = pdf_load_object(xref, num, gen);
/* RJW: "cannot load stream dictionary (%d %d R)", num, gen */
- len = fz_to_int(fz_dict_gets(dict, "Length"));
- obj = fz_dict_gets(dict, "Filter");
- len = pdf_guess_filter_length(len, fz_to_name(obj));
- n = fz_array_len(obj);
+ len = pdf_to_int(pdf_dict_gets(dict, "Length"));
+ obj = pdf_dict_gets(dict, "Filter");
+ len = pdf_guess_filter_length(len, pdf_to_name(obj));
+ n = pdf_array_len(obj);
for (i = 0; i < n; i++)
- len = pdf_guess_filter_length(len, fz_to_name(fz_array_get(obj, i)));
+ len = pdf_guess_filter_length(len, pdf_to_name(pdf_array_get(obj, i)));
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
- stm = pdf_open_stream(xref, num, gen);
+ stm = pdf_open_image_stream(xref, num, gen, params);
/* RJW: "cannot open stream (%d %d R)", num, gen */
fz_try(ctx)
diff --git a/pdf/pdf_type3.c b/pdf/pdf_type3.c
index 777ff756..6603fc8b 100644
--- a/pdf/pdf_type3.c
+++ b/pdf/pdf_type3.c
@@ -1,22 +1,31 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
static void
-pdf_run_glyph_func(void *doc, fz_obj *rdb, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate)
+pdf_run_glyph_func(void *doc, void *rdb_, fz_buffer *contents, fz_device *dev, fz_matrix ctm, void *gstate)
{
+ pdf_obj *rdb = (pdf_obj *)rdb_;
pdf_run_glyph(doc, rdb, contents, dev, ctm, gstate);
}
+static void
+pdf_t3_free_resources(void *doc, void *rdb_)
+{
+ pdf_obj *rdb = (pdf_obj *)rdb_;
+ pdf_drop_obj(rdb);
+}
+
+
pdf_font_desc *
-pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
+pdf_load_type3_font(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict)
{
char buf[256];
char *estrings[256];
pdf_font_desc *fontdesc = NULL;
- fz_obj *encoding;
- fz_obj *widths;
- fz_obj *charprocs;
- fz_obj *obj;
+ pdf_obj *encoding;
+ pdf_obj *widths;
+ pdf_obj *charprocs;
+ pdf_obj *obj;
int first, last;
int i, k, n;
fz_rect bbox;
@@ -27,18 +36,18 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
fz_try(ctx)
{
- obj = fz_dict_gets(dict, "Name");
- if (fz_is_name(obj))
- fz_strlcpy(buf, fz_to_name(obj), sizeof buf);
+ obj = pdf_dict_gets(dict, "Name");
+ if (pdf_is_name(obj))
+ fz_strlcpy(buf, pdf_to_name(obj), sizeof buf);
else
sprintf(buf, "Unnamed-T3");
fontdesc = pdf_new_font_desc(ctx);
- obj = fz_dict_gets(dict, "FontMatrix");
+ obj = pdf_dict_gets(dict, "FontMatrix");
matrix = pdf_to_matrix(ctx, obj);
- obj = fz_dict_gets(dict, "FontBBox");
+ obj = pdf_dict_gets(dict, "FontBBox");
bbox = pdf_to_rect(ctx, obj);
bbox = fz_transform_rect(matrix, bbox);
@@ -52,35 +61,35 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
for (i = 0; i < 256; i++)
estrings[i] = NULL;
- encoding = fz_dict_gets(dict, "Encoding");
+ encoding = pdf_dict_gets(dict, "Encoding");
if (!encoding)
{
fz_throw(ctx, "syntaxerror: Type3 font missing Encoding");
}
- if (fz_is_name(encoding))
- pdf_load_encoding(estrings, fz_to_name(encoding));
+ if (pdf_is_name(encoding))
+ pdf_load_encoding(estrings, pdf_to_name(encoding));
- if (fz_is_dict(encoding))
+ if (pdf_is_dict(encoding))
{
- fz_obj *base, *diff, *item;
+ pdf_obj *base, *diff, *item;
- base = fz_dict_gets(encoding, "BaseEncoding");
- if (fz_is_name(base))
- pdf_load_encoding(estrings, fz_to_name(base));
+ base = pdf_dict_gets(encoding, "BaseEncoding");
+ if (pdf_is_name(base))
+ pdf_load_encoding(estrings, pdf_to_name(base));
- diff = fz_dict_gets(encoding, "Differences");
- if (fz_is_array(diff))
+ diff = pdf_dict_gets(encoding, "Differences");
+ if (pdf_is_array(diff))
{
- n = fz_array_len(diff);
+ n = pdf_array_len(diff);
k = 0;
for (i = 0; i < n; i++)
{
- item = fz_array_get(diff, i);
- if (fz_is_int(item))
- k = fz_to_int(item);
- if (fz_is_name(item))
- estrings[k++] = fz_to_name(item);
+ item = pdf_array_get(diff, i);
+ if (pdf_is_int(item))
+ k = pdf_to_int(item);
+ if (pdf_is_name(item))
+ estrings[k++] = pdf_to_name(item);
if (k < 0) k = 0;
if (k > 255) k = 255;
}
@@ -90,16 +99,16 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1);
fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);
- pdf_load_to_unicode(xref, fontdesc, estrings, NULL, fz_dict_gets(dict, "ToUnicode"));
+ pdf_load_to_unicode(xref, fontdesc, estrings, NULL, pdf_dict_gets(dict, "ToUnicode"));
/* Widths */
pdf_set_default_hmtx(ctx, fontdesc, 0);
- first = fz_to_int(fz_dict_gets(dict, "FirstChar"));
- last = fz_to_int(fz_dict_gets(dict, "LastChar"));
+ first = pdf_to_int(pdf_dict_gets(dict, "FirstChar"));
+ last = pdf_to_int(pdf_dict_gets(dict, "LastChar"));
- widths = fz_dict_gets(dict, "Widths");
+ widths = pdf_dict_gets(dict, "Widths");
if (!widths)
{
fz_throw(ctx, "syntaxerror: Type3 font missing Widths");
@@ -107,7 +116,7 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
for (i = first; i <= last; i++)
{
- float w = fz_to_real(fz_array_get(widths, i - first));
+ float w = pdf_to_real(pdf_array_get(widths, i - first));
w = fontdesc->font->t3matrix.a * w * 1000;
fontdesc->font->t3widths[i] = w * 0.001f;
pdf_add_hmtx(ctx, fontdesc, i, i, w);
@@ -117,11 +126,12 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
/* Resources -- inherit page resources if the font doesn't have its own */
- fontdesc->font->t3resources = fz_dict_gets(dict, "Resources");
+ fontdesc->font->t3freeres = pdf_t3_free_resources;
+ fontdesc->font->t3resources = pdf_dict_gets(dict, "Resources");
if (!fontdesc->font->t3resources)
fontdesc->font->t3resources = rdb;
if (fontdesc->font->t3resources)
- fz_keep_obj(fontdesc->font->t3resources);
+ pdf_keep_obj(fontdesc->font->t3resources);
if (!fontdesc->font->t3resources)
fz_warn(ctx, "no resource dictionary for type 3 font!");
@@ -130,7 +140,7 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
/* CharProcs */
- charprocs = fz_dict_gets(dict, "CharProcs");
+ charprocs = pdf_dict_gets(dict, "CharProcs");
if (!charprocs)
{
fz_throw(ctx, "syntaxerror: Type3 font missing CharProcs");
@@ -140,10 +150,10 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
{
if (estrings[i])
{
- obj = fz_dict_gets(charprocs, estrings[i]);
- if (pdf_is_stream(xref, fz_to_num(obj), fz_to_gen(obj)))
+ obj = pdf_dict_gets(charprocs, estrings[i]);
+ if (pdf_is_stream(xref, pdf_to_num(obj), pdf_to_gen(obj)))
{
- fontdesc->font->t3procs[i] = pdf_load_stream(xref, fz_to_num(obj), fz_to_gen(obj));
+ fontdesc->font->t3procs[i] = pdf_load_stream(xref, pdf_to_num(obj), pdf_to_gen(obj));
fontdesc->size += fontdesc->font->t3procs[i]->cap;
}
}
@@ -154,7 +164,7 @@ pdf_load_type3_font(pdf_document *xref, fz_obj *rdb, fz_obj *dict)
if (fontdesc)
fz_drop_font(ctx, fontdesc->font);
fz_free(ctx, fontdesc);
- fz_throw(ctx, "cannot load type3 font (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "cannot load type3 font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
}
return fontdesc;
}
diff --git a/pdf/pdf_unicode.c b/pdf/pdf_unicode.c
index d2534612..c94a6683 100644
--- a/pdf/pdf_unicode.c
+++ b/pdf/pdf_unicode.c
@@ -1,11 +1,11 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
/* Load or synthesize ToUnicode map for fonts */
void
pdf_load_to_unicode(pdf_document *xref, pdf_font_desc *font,
- char **strings, char *collection, fz_obj *cmapstm)
+ char **strings, char *collection, pdf_obj *cmapstm)
{
pdf_cmap *cmap;
int cid;
@@ -14,10 +14,10 @@ pdf_load_to_unicode(pdf_document *xref, pdf_font_desc *font,
int i;
fz_context *ctx = xref->ctx;
- if (pdf_is_stream(xref, fz_to_num(cmapstm), fz_to_gen(cmapstm)))
+ if (pdf_is_stream(xref, pdf_to_num(cmapstm), pdf_to_gen(cmapstm)))
{
cmap = pdf_load_embedded_cmap(xref, cmapstm);
- /* RJW: "cannot load embedded cmap (%d %d R)", fz_to_num(cmapstm), fz_to_gen(cmapstm) */
+ /* RJW: "cannot load embedded cmap (%d %d R)", pdf_to_num(cmapstm), pdf_to_gen(cmapstm) */
font->to_unicode = pdf_new_cmap(ctx);
diff --git a/pdf/pdf_xobject.c b/pdf/pdf_xobject.c
index 91bf4db3..ffa86184 100644
--- a/pdf/pdf_xobject.c
+++ b/pdf/pdf_xobject.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
pdf_xobject *
pdf_keep_xobject(fz_context *ctx, pdf_xobject *xobj)
@@ -21,10 +21,10 @@ pdf_free_xobject_imp(fz_context *ctx, fz_storable *xobj_)
if (xobj->colorspace)
fz_drop_colorspace(ctx, xobj->colorspace);
if (xobj->resources)
- fz_drop_obj(xobj->resources);
+ pdf_drop_obj(xobj->resources);
if (xobj->contents)
fz_drop_buffer(ctx, xobj->contents);
- fz_drop_obj(xobj->me);
+ pdf_drop_obj(xobj->me);
fz_free(ctx, xobj);
}
@@ -37,13 +37,13 @@ pdf_xobject_size(pdf_xobject *xobj)
}
pdf_xobject *
-pdf_load_xobject(pdf_document *xref, fz_obj *dict)
+pdf_load_xobject(pdf_document *xref, pdf_obj *dict)
{
pdf_xobject *form;
- fz_obj *obj;
+ pdf_obj *obj;
fz_context *ctx = xref->ctx;
- if ((form = fz_find_item(ctx, pdf_free_xobject_imp, dict)))
+ if ((form = pdf_find_item(ctx, pdf_free_xobject_imp, dict)))
{
return form;
}
@@ -56,12 +56,12 @@ pdf_load_xobject(pdf_document *xref, fz_obj *dict)
form->me = NULL;
/* Store item immediately, to avoid possible recursion if objects refer back to this one */
- fz_store_item(ctx, dict, form, pdf_xobject_size(form));
+ pdf_store_item(ctx, dict, form, pdf_xobject_size(form));
- obj = fz_dict_gets(dict, "BBox");
+ obj = pdf_dict_gets(dict, "BBox");
form->bbox = pdf_to_rect(ctx, obj);
- obj = fz_dict_gets(dict, "Matrix");
+ obj = pdf_dict_gets(dict, "Matrix");
if (obj)
form->matrix = pdf_to_matrix(ctx, obj);
else
@@ -71,19 +71,19 @@ pdf_load_xobject(pdf_document *xref, fz_obj *dict)
form->knockout = 0;
form->transparency = 0;
- obj = fz_dict_gets(dict, "Group");
+ obj = pdf_dict_gets(dict, "Group");
if (obj)
{
- fz_obj *attrs = obj;
+ pdf_obj *attrs = obj;
- form->isolated = fz_to_bool(fz_dict_gets(attrs, "I"));
- form->knockout = fz_to_bool(fz_dict_gets(attrs, "K"));
+ form->isolated = pdf_to_bool(pdf_dict_gets(attrs, "I"));
+ form->knockout = pdf_to_bool(pdf_dict_gets(attrs, "K"));
- obj = fz_dict_gets(attrs, "S");
- if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Transparency"))
+ obj = pdf_dict_gets(attrs, "S");
+ if (pdf_is_name(obj) && !strcmp(pdf_to_name(obj), "Transparency"))
form->transparency = 1;
- obj = fz_dict_gets(attrs, "CS");
+ obj = pdf_dict_gets(attrs, "CS");
if (obj)
{
form->colorspace = pdf_load_colorspace(xref, obj);
@@ -92,21 +92,21 @@ pdf_load_xobject(pdf_document *xref, fz_obj *dict)
}
}
- form->resources = fz_dict_gets(dict, "Resources");
+ form->resources = pdf_dict_gets(dict, "Resources");
if (form->resources)
- fz_keep_obj(form->resources);
+ pdf_keep_obj(form->resources);
fz_try(ctx)
{
- form->contents = pdf_load_stream(xref, fz_to_num(dict), fz_to_gen(dict));
+ form->contents = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
}
fz_catch(ctx)
{
- fz_remove_item(ctx, pdf_free_xobject_imp, dict);
+ pdf_remove_item(ctx, pdf_free_xobject_imp, dict);
pdf_drop_xobject(ctx, form);
- fz_throw(ctx, "cannot load xobject content stream (%d %d R)", fz_to_num(dict), fz_to_gen(dict));
+ fz_throw(ctx, "cannot load xobject content stream (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
}
- form->me = fz_keep_obj(dict);
+ form->me = pdf_keep_obj(dict);
return form;
}
diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c
index 7500ded3..e0e9f190 100644
--- a/pdf/pdf_xref.c
+++ b/pdf/pdf_xref.c
@@ -1,5 +1,5 @@
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
static inline int iswhite(int ch)
{
@@ -51,6 +51,7 @@ pdf_read_start_xref(pdf_document *xref)
while (iswhite(buf[i]) && i < n)
i ++;
xref->startxref = atoi((char*)(buf + i));
+
return;
}
}
@@ -63,17 +64,16 @@ pdf_read_start_xref(pdf_document *xref)
*/
static void
-pdf_read_old_trailer(pdf_document *xref, char *buf, int cap)
+pdf_read_old_trailer(pdf_document *xref, pdf_lexbuf *buf)
{
int len;
char *s;
- int n;
int t;
int tok;
int c;
- fz_read_line(xref->file, buf, cap);
- if (strncmp(buf, "xref", 4) != 0)
+ fz_read_line(xref->file, buf->scratch, buf->size);
+ if (strncmp(buf->scratch, "xref", 4) != 0)
fz_throw(xref->ctx, "cannot find xref marker");
while (1)
@@ -82,8 +82,8 @@ pdf_read_old_trailer(pdf_document *xref, char *buf, int cap)
if (!(c >= '0' && c <= '9'))
break;
- fz_read_line(xref->file, buf, cap);
- s = buf;
+ fz_read_line(xref->file, buf->scratch, buf->size);
+ s = buf->scratch;
fz_strsep(&s, " "); /* ignore ofs */
if (!s)
fz_throw(xref->ctx, "invalid range marker in xref");
@@ -102,15 +102,15 @@ pdf_read_old_trailer(pdf_document *xref, char *buf, int cap)
fz_try(xref->ctx)
{
- tok = pdf_lex(xref->file, buf, cap, &n);
+ tok = pdf_lex(xref->file, buf);
if (tok != PDF_TOK_TRAILER)
fz_throw(xref->ctx, "expected trailer marker");
- tok = pdf_lex(xref->file, buf, cap, &n);
+ tok = pdf_lex(xref->file, buf);
if (tok != PDF_TOK_OPEN_DICT)
fz_throw(xref->ctx, "expected trailer dictionary");
- xref->trailer = pdf_parse_dict(xref, xref->file, buf, cap);
+ xref->trailer = pdf_parse_dict(xref, xref->file, buf);
}
fz_catch(xref->ctx)
{
@@ -119,11 +119,11 @@ pdf_read_old_trailer(pdf_document *xref, char *buf, int cap)
}
static void
-pdf_read_new_trailer(pdf_document *xref, char *buf, int cap)
+pdf_read_new_trailer(pdf_document *xref, pdf_lexbuf *buf)
{
fz_try(xref->ctx)
{
- xref->trailer = pdf_parse_ind_obj(xref, xref->file, buf, cap, NULL, NULL, NULL);
+ xref->trailer = pdf_parse_ind_obj(xref, xref->file, buf, NULL, NULL, NULL);
}
fz_catch(xref->ctx)
{
@@ -132,7 +132,7 @@ pdf_read_new_trailer(pdf_document *xref, char *buf, int cap)
}
static void
-pdf_read_trailer(pdf_document *xref, char *buf, int cap)
+pdf_read_trailer(pdf_document *xref, pdf_lexbuf *buf)
{
int c;
@@ -145,9 +145,9 @@ pdf_read_trailer(pdf_document *xref, char *buf, int cap)
{
c = fz_peek_byte(xref->file);
if (c == 'x')
- pdf_read_old_trailer(xref, buf, cap);
+ pdf_read_old_trailer(xref, buf);
else if (c >= '0' && c <= '9')
- pdf_read_new_trailer(xref, buf, cap);
+ pdf_read_new_trailer(xref, buf);
else
fz_throw(xref->ctx, "cannot recognize xref format: '%c'", c);
}
@@ -178,8 +178,8 @@ pdf_resize_xref(pdf_document *xref, int newlen)
xref->len = newlen;
}
-static fz_obj *
-pdf_read_old_xref(pdf_document *xref, char *buf, int cap)
+static pdf_obj *
+pdf_read_old_xref(pdf_document *xref, pdf_lexbuf *buf)
{
int ofs, len;
char *s;
@@ -187,10 +187,10 @@ pdf_read_old_xref(pdf_document *xref, char *buf, int cap)
int tok;
int i;
int c;
- fz_obj *trailer;
+ pdf_obj *trailer;
- fz_read_line(xref->file, buf, cap);
- if (strncmp(buf, "xref", 4) != 0)
+ fz_read_line(xref->file, buf->scratch, buf->size);
+ if (strncmp(buf->scratch, "xref", 4) != 0)
fz_throw(xref->ctx, "cannot find xref marker");
while (1)
@@ -199,8 +199,8 @@ pdf_read_old_xref(pdf_document *xref, char *buf, int cap)
if (!(c >= '0' && c <= '9'))
break;
- fz_read_line(xref->file, buf, cap);
- s = buf;
+ fz_read_line(xref->file, buf->scratch, buf->size);
+ s = buf->scratch;
ofs = atoi(fz_strsep(&s, " "));
len = atoi(fz_strsep(&s, " "));
@@ -220,12 +220,12 @@ pdf_read_old_xref(pdf_document *xref, char *buf, int cap)
for (i = ofs; i < ofs + len; i++)
{
- n = fz_read(xref->file, (unsigned char *) buf, 20);
+ n = fz_read(xref->file, (unsigned char *) buf->scratch, 20);
if (n < 0)
fz_throw(xref->ctx, "cannot read xref table");
if (!xref->table[i].type)
{
- s = buf;
+ s = buf->scratch;
/* broken pdfs where line start with white space */
while (*s != '\0' && iswhite(*s))
@@ -242,15 +242,15 @@ pdf_read_old_xref(pdf_document *xref, char *buf, int cap)
fz_try(xref->ctx)
{
- tok = pdf_lex(xref->file, buf, cap, &n);
+ tok = pdf_lex(xref->file, buf);
if (tok != PDF_TOK_TRAILER)
fz_throw(xref->ctx, "expected trailer marker");
- tok = pdf_lex(xref->file, buf, cap, &n);
+ tok = pdf_lex(xref->file, buf);
if (tok != PDF_TOK_OPEN_DICT)
fz_throw(xref->ctx, "expected trailer dictionary");
- trailer = pdf_parse_dict(xref, xref->file, buf, cap);
+ trailer = pdf_parse_dict(xref, xref->file, buf);
}
fz_catch(xref->ctx)
{
@@ -295,13 +295,13 @@ pdf_read_new_xref_section(pdf_document *xref, fz_stream *stm, int i0, int i1, in
/* Entered with file locked. Drops the lock in the middle, but then picks
* it up again before exiting. */
-static fz_obj *
-pdf_read_new_xref(pdf_document *xref, char *buf, int cap)
+static pdf_obj *
+pdf_read_new_xref(pdf_document *xref, pdf_lexbuf *buf)
{
fz_stream *stm = NULL;
- fz_obj *trailer = NULL;
- fz_obj *index = NULL;
- fz_obj *obj = NULL;
+ pdf_obj *trailer = NULL;
+ pdf_obj *index = NULL;
+ pdf_obj *obj = NULL;
int num, gen, stm_ofs;
int size, w0, w1, w2;
int t;
@@ -312,7 +312,7 @@ pdf_read_new_xref(pdf_document *xref, char *buf, int cap)
fz_try(ctx)
{
- trailer = pdf_parse_ind_obj(xref, xref->file, buf, cap, &num, &gen, &stm_ofs);
+ trailer = pdf_parse_ind_obj(xref, xref->file, buf, &num, &gen, &stm_ofs);
}
fz_catch(ctx)
{
@@ -322,25 +322,25 @@ pdf_read_new_xref(pdf_document *xref, char *buf, int cap)
fz_try(ctx)
{
fz_unlock(ctx, FZ_LOCK_FILE);
- obj = fz_dict_gets(trailer, "Size");
+ obj = pdf_dict_gets(trailer, "Size");
if (!obj)
fz_throw(ctx, "xref stream missing Size entry (%d %d R)", num, gen);
- size = fz_to_int(obj);
+ size = pdf_to_int(obj);
if (size > xref->len)
pdf_resize_xref(xref, size);
if (num < 0 || num >= xref->len)
fz_throw(ctx, "object id (%d %d R) out of range (0..%d)", num, gen, xref->len - 1);
- obj = fz_dict_gets(trailer, "W");
+ obj = pdf_dict_gets(trailer, "W");
if (!obj)
fz_throw(ctx, "xref stream missing W entry (%d %d R)", num, gen);
- w0 = fz_to_int(fz_array_get(obj, 0));
- w1 = fz_to_int(fz_array_get(obj, 1));
- w2 = fz_to_int(fz_array_get(obj, 2));
+ w0 = pdf_to_int(pdf_array_get(obj, 0));
+ w1 = pdf_to_int(pdf_array_get(obj, 1));
+ w2 = pdf_to_int(pdf_array_get(obj, 2));
- index = fz_dict_gets(trailer, "Index");
+ index = pdf_dict_gets(trailer, "Index");
stm = pdf_open_stream_with_offset(xref, num, gen, trailer, stm_ofs);
/* RJW: Ensure pdf_open_stream does fz_throw(ctx, "cannot open compressed xref stream (%d %d R)", num, gen); */
@@ -352,11 +352,11 @@ pdf_read_new_xref(pdf_document *xref, char *buf, int cap)
}
else
{
- int n = fz_array_len(index);
+ int n = pdf_array_len(index);
for (t = 0; t < n; t += 2)
{
- int i0 = fz_to_int(fz_array_get(index, t + 0));
- int i1 = fz_to_int(fz_array_get(index, t + 1));
+ int i0 = pdf_to_int(pdf_array_get(index, t + 0));
+ int i1 = pdf_to_int(pdf_array_get(index, t + 1));
pdf_read_new_xref_section(xref, stm, i0, i1, w0, w1, w2);
}
}
@@ -367,8 +367,8 @@ pdf_read_new_xref(pdf_document *xref, char *buf, int cap)
}
fz_catch(ctx)
{
- fz_drop_obj(trailer);
- fz_drop_obj(index);
+ pdf_drop_obj(trailer);
+ pdf_drop_obj(index);
fz_rethrow(ctx);
}
fz_lock(ctx, FZ_LOCK_FILE);
@@ -377,12 +377,12 @@ pdf_read_new_xref(pdf_document *xref, char *buf, int cap)
}
/* File is locked on entry, and exit (but may be dropped in the middle) */
-static fz_obj *
-pdf_read_xref(pdf_document *xref, int ofs, char *buf, int cap)
+static pdf_obj *
+pdf_read_xref(pdf_document *xref, int ofs, pdf_lexbuf *buf)
{
int c;
fz_context *ctx = xref->ctx;
- fz_obj *trailer;
+ pdf_obj *trailer;
fz_seek(xref->file, ofs, 0);
@@ -393,9 +393,9 @@ pdf_read_xref(pdf_document *xref, int ofs, char *buf, int cap)
{
c = fz_peek_byte(xref->file);
if (c == 'x')
- trailer = pdf_read_old_xref(xref, buf, cap);
+ trailer = pdf_read_old_xref(xref, buf);
else if (c >= '0' && c <= '9')
- trailer = pdf_read_new_xref(xref, buf, cap);
+ trailer = pdf_read_new_xref(xref, buf);
else
fz_throw(ctx, "cannot recognize xref format");
}
@@ -407,33 +407,33 @@ pdf_read_xref(pdf_document *xref, int ofs, char *buf, int cap)
}
static void
-pdf_read_xref_sections(pdf_document *xref, int ofs, char *buf, int cap)
+pdf_read_xref_sections(pdf_document *xref, int ofs, pdf_lexbuf *buf)
{
- fz_obj *trailer = NULL;
- fz_obj *xrefstm = NULL;
- fz_obj *prev = NULL;
+ pdf_obj *trailer = NULL;
+ pdf_obj *xrefstm = NULL;
+ pdf_obj *prev = NULL;
fz_context *ctx = xref->ctx;
fz_try(ctx)
{
- trailer = pdf_read_xref(xref, ofs, buf, cap);
+ trailer = pdf_read_xref(xref, ofs, buf);
/* FIXME: do we overwrite free entries properly? */
- xrefstm = fz_dict_gets(trailer, "XRefStm");
+ xrefstm = pdf_dict_gets(trailer, "XRefStm");
if (xrefstm)
- pdf_read_xref_sections(xref, fz_to_int(xrefstm), buf, cap);
+ pdf_read_xref_sections(xref, pdf_to_int(xrefstm), buf);
- prev = fz_dict_gets(trailer, "Prev");
+ prev = pdf_dict_gets(trailer, "Prev");
if (prev)
- pdf_read_xref_sections(xref, fz_to_int(prev), buf, cap);
+ pdf_read_xref_sections(xref, pdf_to_int(prev), buf);
}
fz_catch(ctx)
{
- fz_drop_obj(trailer);
+ pdf_drop_obj(trailer);
fz_throw(ctx, "cannot read xref at offset %d", ofs);
}
- fz_drop_obj(trailer);
+ pdf_drop_obj(trailer);
}
/*
@@ -441,9 +441,9 @@ pdf_read_xref_sections(pdf_document *xref, int ofs, char *buf, int cap)
*/
static void
-pdf_load_xref(pdf_document *xref, char *buf, int bufsize)
+pdf_load_xref(pdf_document *xref, pdf_lexbuf *buf)
{
- fz_obj *size;
+ pdf_obj *size;
int i;
fz_context *ctx = xref->ctx;
@@ -451,15 +451,15 @@ pdf_load_xref(pdf_document *xref, char *buf, int bufsize)
pdf_read_start_xref(xref);
- pdf_read_trailer(xref, buf, bufsize);
+ pdf_read_trailer(xref, buf);
- size = fz_dict_gets(xref->trailer, "Size");
+ size = pdf_dict_gets(xref->trailer, "Size");
if (!size)
fz_throw(ctx, "trailer missing Size entry");
- pdf_resize_xref(xref, fz_to_int(size));
+ pdf_resize_xref(xref, pdf_to_int(size));
- pdf_read_xref_sections(xref, xref->startxref, buf, bufsize);
+ pdf_read_xref_sections(xref, xref->startxref, buf);
/* broken pdfs where first object is not free */
if (xref->table[0].type != 'f')
@@ -488,10 +488,10 @@ pdf_ocg_set_config(pdf_document *xref, int config)
{
int i, j, len, len2;
pdf_ocg_descriptor *desc = xref->ocg;
- fz_obj *obj, *cobj;
+ pdf_obj *obj, *cobj;
char *name;
- obj = fz_dict_gets(fz_dict_gets(xref->trailer, "Root"), "OCProperties");
+ obj = pdf_dict_gets(pdf_dict_gets(xref->trailer, "Root"), "OCProperties");
if (!obj)
{
if (config == 0)
@@ -501,25 +501,25 @@ pdf_ocg_set_config(pdf_document *xref, int config)
}
if (config == 0)
{
- cobj = fz_dict_gets(obj, "D");
+ cobj = pdf_dict_gets(obj, "D");
if (!cobj)
fz_throw(xref->ctx, "No default OCG config");
}
else
{
- cobj = fz_array_get(fz_dict_gets(obj, "Configs"), config);
+ cobj = pdf_array_get(pdf_dict_gets(obj, "Configs"), config);
if (!cobj)
fz_throw(xref->ctx, "Illegal OCG config");
}
if (desc->intent)
- fz_drop_obj(desc->intent);
- desc->intent = fz_dict_gets(cobj, "Intent");
+ pdf_drop_obj(desc->intent);
+ desc->intent = pdf_dict_gets(cobj, "Intent");
if (desc->intent)
- fz_keep_obj(desc->intent);
+ pdf_keep_obj(desc->intent);
len = desc->len;
- name = fz_to_name(fz_dict_gets(cobj, "BaseState"));
+ name = pdf_to_name(pdf_dict_gets(cobj, "BaseState"));
if (strcmp(name, "Unchanged") == 0)
{
/* Do nothing */
@@ -539,13 +539,13 @@ pdf_ocg_set_config(pdf_document *xref, int config)
}
}
- obj = fz_dict_gets(cobj, "ON");
- len2 = fz_array_len(obj);
+ obj = pdf_dict_gets(cobj, "ON");
+ len2 = pdf_array_len(obj);
for (i = 0; i < len2; i++)
{
- fz_obj *o = fz_array_get(obj, i);
- int n = fz_to_num(o);
- int g = fz_to_gen(o);
+ pdf_obj *o = pdf_array_get(obj, i);
+ int n = pdf_to_num(o);
+ int g = pdf_to_gen(o);
for (j=0; j < len; j++)
{
if (desc->ocgs[j].num == n && desc->ocgs[j].gen == g)
@@ -556,13 +556,13 @@ pdf_ocg_set_config(pdf_document *xref, int config)
}
}
- obj = fz_dict_gets(cobj, "OFF");
- len2 = fz_array_len(obj);
+ obj = pdf_dict_gets(cobj, "OFF");
+ len2 = pdf_array_len(obj);
for (i = 0; i < len2; i++)
{
- fz_obj *o = fz_array_get(obj, i);
- int n = fz_to_num(o);
- int g = fz_to_gen(o);
+ pdf_obj *o = pdf_array_get(obj, i);
+ int n = pdf_to_num(o);
+ int g = pdf_to_gen(o);
for (j=0; j < len; j++)
{
if (desc->ocgs[j].num == n && desc->ocgs[j].gen == g)
@@ -591,21 +591,21 @@ pdf_ocg_set_config(pdf_document *xref, int config)
static void
pdf_read_ocg(pdf_document *xref)
{
- fz_obj *obj, *ocg;
+ pdf_obj *obj, *ocg;
int len, i;
pdf_ocg_descriptor *desc;
fz_context *ctx = xref->ctx;
fz_var(desc);
- obj = fz_dict_gets(fz_dict_gets(xref->trailer, "Root"), "OCProperties");
+ obj = pdf_dict_gets(pdf_dict_gets(xref->trailer, "Root"), "OCProperties");
if (!obj)
return;
- ocg = fz_dict_gets(obj, "OCGs");
- if (!ocg || !fz_is_array(ocg))
+ ocg = pdf_dict_gets(obj, "OCGs");
+ if (!ocg || !pdf_is_array(ocg))
/* Not ever supposed to happen, but live with it. */
return;
- len = fz_array_len(ocg);
+ len = pdf_array_len(ocg);
fz_try(ctx)
{
desc = fz_calloc(ctx, 1, sizeof(*desc));
@@ -614,9 +614,9 @@ pdf_read_ocg(pdf_document *xref)
desc->intent = NULL;
for (i=0; i < len; i++)
{
- fz_obj *o = fz_array_get(ocg, i);
- desc->ocgs[i].num = fz_to_num(o);
- desc->ocgs[i].gen = fz_to_gen(o);
+ pdf_obj *o = pdf_array_get(ocg, i);
+ desc->ocgs[i].num = pdf_to_num(o);
+ desc->ocgs[i].gen = pdf_to_gen(o);
desc->ocgs[i].state = 0;
}
xref->ocg = desc;
@@ -639,7 +639,7 @@ pdf_free_ocg(fz_context *ctx, pdf_ocg_descriptor *desc)
return;
if (desc->intent)
- fz_drop_obj(desc->intent);
+ pdf_drop_obj(desc->intent);
fz_free(ctx, desc->ocgs);
fz_free(ctx, desc);
}
@@ -655,10 +655,10 @@ pdf_document *
pdf_open_document_with_stream(fz_stream *file)
{
pdf_document *xref;
- fz_obj *encrypt, *id;
- fz_obj *dict = NULL;
- fz_obj *obj;
- fz_obj *nobj = NULL;
+ pdf_obj *encrypt, *id;
+ pdf_obj *dict = NULL;
+ pdf_obj *obj;
+ pdf_obj *nobj = NULL;
int i, repaired = 0;
int locked;
fz_context *ctx = file->ctx;
@@ -667,11 +667,9 @@ pdf_open_document_with_stream(fz_stream *file)
fz_var(nobj);
fz_var(locked);
- /* install pdf specific callback */
- fz_resolve_indirect = pdf_resolve_indirect;
-
xref = fz_malloc_struct(ctx, pdf_document);
pdf_init_document(xref);
+ xref->lexbuf.base.size = PDF_LEXBUF_LARGE;
xref->file = fz_keep_stream(file);
xref->ctx = ctx;
@@ -681,7 +679,7 @@ pdf_open_document_with_stream(fz_stream *file)
fz_try(ctx)
{
- pdf_load_xref(xref, xref->scratch, sizeof xref->scratch);
+ pdf_load_xref(xref, &xref->lexbuf.base);
}
fz_catch(ctx)
{
@@ -693,7 +691,7 @@ pdf_open_document_with_stream(fz_stream *file)
}
if (xref->trailer)
{
- fz_drop_obj(xref->trailer);
+ pdf_drop_obj(xref->trailer);
xref->trailer = NULL;
}
fz_warn(xref->ctx, "trying to repair broken xref");
@@ -705,14 +703,14 @@ pdf_open_document_with_stream(fz_stream *file)
int hasroot, hasinfo;
if (repaired)
- pdf_repair_xref(xref, xref->scratch, sizeof xref->scratch);
+ pdf_repair_xref(xref, &xref->lexbuf.base);
fz_unlock(ctx, FZ_LOCK_FILE);
locked = 0;
- encrypt = fz_dict_gets(xref->trailer, "Encrypt");
- id = fz_dict_gets(xref->trailer, "ID");
- if (fz_is_dict(encrypt))
+ encrypt = pdf_dict_gets(xref->trailer, "Encrypt");
+ id = pdf_dict_gets(xref->trailer, "ID");
+ if (pdf_is_dict(encrypt))
xref->crypt = pdf_new_crypt(ctx, encrypt, id);
/* Allow lazy clients to read encrypted files with a blank password */
@@ -722,8 +720,8 @@ pdf_open_document_with_stream(fz_stream *file)
{
pdf_repair_obj_stms(xref);
- hasroot = (fz_dict_gets(xref->trailer, "Root") != NULL);
- hasinfo = (fz_dict_gets(xref->trailer, "Info") != NULL);
+ hasroot = (pdf_dict_gets(xref->trailer, "Root") != NULL);
+ hasinfo = (pdf_dict_gets(xref->trailer, "Info") != NULL);
for (i = 1; i < xref->len; i++)
{
@@ -742,28 +740,28 @@ pdf_open_document_with_stream(fz_stream *file)
if (!hasroot)
{
- obj = fz_dict_gets(dict, "Type");
- if (fz_is_name(obj) && !strcmp(fz_to_name(obj), "Catalog"))
+ obj = pdf_dict_gets(dict, "Type");
+ if (pdf_is_name(obj) && !strcmp(pdf_to_name(obj), "Catalog"))
{
- nobj = fz_new_indirect(ctx, i, 0, xref);
- fz_dict_puts(xref->trailer, "Root", nobj);
- fz_drop_obj(nobj);
+ nobj = pdf_new_indirect(ctx, i, 0, xref);
+ pdf_dict_puts(xref->trailer, "Root", nobj);
+ pdf_drop_obj(nobj);
nobj = NULL;
}
}
if (!hasinfo)
{
- if (fz_dict_gets(dict, "Creator") || fz_dict_gets(dict, "Producer"))
+ if (pdf_dict_gets(dict, "Creator") || pdf_dict_gets(dict, "Producer"))
{
- nobj = fz_new_indirect(ctx, i, 0, xref);
- fz_dict_puts(xref->trailer, "Info", nobj);
- fz_drop_obj(nobj);
+ nobj = pdf_new_indirect(ctx, i, 0, xref);
+ pdf_dict_puts(xref->trailer, "Info", nobj);
+ pdf_drop_obj(nobj);
nobj = NULL;
}
}
- fz_drop_obj(dict);
+ pdf_drop_obj(dict);
dict = NULL;
}
}
@@ -775,8 +773,8 @@ pdf_open_document_with_stream(fz_stream *file)
}
fz_catch(ctx)
{
- fz_drop_obj(dict);
- fz_drop_obj(nobj);
+ pdf_drop_obj(dict);
+ pdf_drop_obj(nobj);
pdf_close_document(xref);
fz_throw(ctx, "cannot open document");
}
@@ -809,7 +807,7 @@ pdf_close_document(pdf_document *xref)
{
if (xref->table[i].obj)
{
- fz_drop_obj(xref->table[i].obj);
+ pdf_drop_obj(xref->table[i].obj);
xref->table[i].obj = NULL;
}
}
@@ -819,21 +817,21 @@ pdf_close_document(pdf_document *xref)
if (xref->page_objs)
{
for (i = 0; i < xref->page_len; i++)
- fz_drop_obj(xref->page_objs[i]);
+ pdf_drop_obj(xref->page_objs[i]);
fz_free(ctx, xref->page_objs);
}
if (xref->page_refs)
{
for (i = 0; i < xref->page_len; i++)
- fz_drop_obj(xref->page_refs[i]);
+ pdf_drop_obj(xref->page_refs[i]);
fz_free(ctx, xref->page_refs);
}
if (xref->file)
fz_close(xref->file);
if (xref->trailer)
- fz_drop_obj(xref->trailer);
+ pdf_drop_obj(xref->trailer);
if (xref->crypt)
pdf_free_crypt(ctx, xref->crypt);
@@ -845,7 +843,7 @@ pdf_close_document(pdf_document *xref)
}
void
-pdf_debug_xref(pdf_document *xref)
+pdf_print_xref(pdf_document *xref)
{
int i;
printf("xref\n0 %d\n", xref->len);
@@ -864,17 +862,17 @@ pdf_debug_xref(pdf_document *xref)
*/
static void
-pdf_load_obj_stm(pdf_document *xref, int num, int gen, char *buf, int cap)
+pdf_load_obj_stm(pdf_document *xref, int num, int gen, pdf_lexbuf *buf)
{
fz_stream *stm = NULL;
- fz_obj *objstm = NULL;
+ pdf_obj *objstm = NULL;
int *numbuf = NULL;
int *ofsbuf = NULL;
- fz_obj *obj;
+ pdf_obj *obj;
int first;
int count;
- int i, n;
+ int i;
int tok;
fz_context *ctx = xref->ctx;
@@ -887,8 +885,8 @@ pdf_load_obj_stm(pdf_document *xref, int num, int gen, char *buf, int cap)
{
objstm = pdf_load_object(xref, num, gen);
- count = fz_to_int(fz_dict_gets(objstm, "N"));
- first = fz_to_int(fz_dict_gets(objstm, "First"));
+ count = pdf_to_int(pdf_dict_gets(objstm, "N"));
+ first = pdf_to_int(pdf_dict_gets(objstm, "First"));
numbuf = fz_calloc(ctx, count, sizeof(int));
ofsbuf = fz_calloc(ctx, count, sizeof(int));
@@ -896,15 +894,15 @@ pdf_load_obj_stm(pdf_document *xref, int num, int gen, char *buf, int cap)
stm = pdf_open_stream(xref, num, gen);
for (i = 0; i < count; i++)
{
- tok = pdf_lex(stm, buf, cap, &n);
+ tok = pdf_lex(stm, buf);
if (tok != PDF_TOK_INT)
fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen);
- numbuf[i] = atoi(buf);
+ numbuf[i] = buf->i;
- tok = pdf_lex(stm, buf, cap, &n);
+ tok = pdf_lex(stm, buf);
if (tok != PDF_TOK_INT)
fz_throw(ctx, "corrupt object stream (%d %d R)", num, gen);
- ofsbuf[i] = atoi(buf);
+ ofsbuf[i] = buf->i;
}
fz_seek(stm, first, 0);
@@ -913,24 +911,24 @@ pdf_load_obj_stm(pdf_document *xref, int num, int gen, char *buf, int cap)
{
fz_seek(stm, first + ofsbuf[i], 0);
- obj = pdf_parse_stm_obj(xref, stm, buf, cap);
+ obj = pdf_parse_stm_obj(xref, stm, buf);
/* RJW: Ensure above does fz_throw(ctx, "cannot parse object %d in stream (%d %d R)", i, num, gen); */
if (numbuf[i] < 1 || numbuf[i] >= xref->len)
{
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
fz_throw(ctx, "object id (%d 0 R) out of range (0..%d)", numbuf[i], xref->len - 1);
}
if (xref->table[numbuf[i]].type == 'o' && xref->table[numbuf[i]].ofs == num)
{
if (xref->table[numbuf[i]].obj)
- fz_drop_obj(xref->table[numbuf[i]].obj);
+ pdf_drop_obj(xref->table[numbuf[i]].obj);
xref->table[numbuf[i]].obj = obj;
}
else
{
- fz_drop_obj(obj);
+ pdf_drop_obj(obj);
}
}
}
@@ -939,7 +937,7 @@ pdf_load_obj_stm(pdf_document *xref, int num, int gen, char *buf, int cap)
fz_close(stm);
fz_free(xref->ctx, ofsbuf);
fz_free(xref->ctx, numbuf);
- fz_drop_obj(objstm);
+ pdf_drop_obj(objstm);
}
fz_catch(ctx)
{
@@ -968,7 +966,7 @@ pdf_cache_object(pdf_document *xref, int num, int gen)
if (x->type == 'f')
{
- x->obj = fz_new_null(ctx);
+ x->obj = pdf_new_null(ctx);
return;
}
else if (x->type == 'n')
@@ -978,7 +976,7 @@ pdf_cache_object(pdf_document *xref, int num, int gen)
fz_try(ctx)
{
- x->obj = pdf_parse_ind_obj(xref, xref->file, xref->scratch, sizeof xref->scratch,
+ x->obj = pdf_parse_ind_obj(xref, xref->file, &xref->lexbuf.base,
&rnum, &rgen, &x->stm_ofs);
}
fz_catch(ctx)
@@ -989,7 +987,7 @@ pdf_cache_object(pdf_document *xref, int num, int gen)
if (rnum != num)
{
- fz_drop_obj(x->obj);
+ pdf_drop_obj(x->obj);
x->obj = NULL;
fz_unlock(ctx, FZ_LOCK_FILE);
fz_throw(ctx, "found object (%d %d R) instead of (%d %d R)", rnum, rgen, num, gen);
@@ -1005,7 +1003,7 @@ pdf_cache_object(pdf_document *xref, int num, int gen)
{
fz_try(ctx)
{
- pdf_load_obj_stm(xref, x->ofs, 0, xref->scratch, sizeof xref->scratch);
+ pdf_load_obj_stm(xref, x->ofs, 0, &xref->lexbuf.base);
}
fz_catch(ctx)
{
@@ -1021,7 +1019,7 @@ pdf_cache_object(pdf_document *xref, int num, int gen)
}
}
-fz_obj *
+pdf_obj *
pdf_load_object(pdf_document *xref, int num, int gen)
{
fz_context *ctx = xref->ctx;
@@ -1037,11 +1035,11 @@ pdf_load_object(pdf_document *xref, int num, int gen)
assert(xref->table[num].obj);
- return fz_keep_obj(xref->table[num].obj);
+ return pdf_keep_obj(xref->table[num].obj);
}
-fz_obj *
-pdf_resolve_indirect(fz_obj *ref)
+pdf_obj *
+pdf_resolve_indirect(pdf_obj *ref)
{
int sanity = 10;
int num;
@@ -1049,16 +1047,16 @@ pdf_resolve_indirect(fz_obj *ref)
fz_context *ctx = NULL; /* Avoid warning for stupid compilers */
pdf_document *xref;
- while (fz_is_indirect(ref))
+ while (pdf_is_indirect(ref))
{
if (--sanity == 0)
fz_throw(ctx, "Too many indirections (possible indirection cycle involving %d %d R)", num, gen);
- xref = fz_get_indirect_document(ref);
+ xref = pdf_get_indirect_document(ref);
if (!xref)
return NULL;
ctx = xref->ctx;
- num = fz_to_num(ref);
- gen = fz_to_gen(ref);
+ num = pdf_to_num(ref);
+ gen = pdf_to_gen(ref);
fz_try(ctx)
{
pdf_cache_object(xref, num, gen);
@@ -1076,9 +1074,14 @@ pdf_resolve_indirect(fz_obj *ref)
return ref;
}
+int pdf_count_objects(pdf_document *doc)
+{
+ return doc->len;
+}
+
/* Replace numbered object -- for use by pdfclean and similar tools */
void
-pdf_update_object(pdf_document *xref, int num, int gen, fz_obj *newobj)
+pdf_update_object(pdf_document *xref, int num, int gen, pdf_obj *newobj)
{
pdf_xref_entry *x;
@@ -1091,9 +1094,9 @@ pdf_update_object(pdf_document *xref, int num, int gen, fz_obj *newobj)
x = &xref->table[num];
if (x->obj)
- fz_drop_obj(x->obj);
+ pdf_drop_obj(x->obj);
- x->obj = fz_keep_obj(newobj);
+ x->obj = pdf_keep_obj(newobj);
x->type = 'n';
x->ofs = 0;
}
diff --git a/scripts/cmapdump.c b/scripts/cmapdump.c
index 12d6f2af..53247339 100644
--- a/scripts/cmapdump.c
+++ b/scripts/cmapdump.c
@@ -6,8 +6,8 @@
/* We never want to build memento versions of the cmapdump util */
#undef MEMENTO
-#include "fitz.h"
-#include "mupdf.h"
+#include "fitz-internal.h"
+#include "mupdf-internal.h"
#include "../fitz/base_context.c"
#include "../fitz/base_error.c"
@@ -181,6 +181,10 @@ void fz_free_aa_context(fz_context *ctx)
{
}
+void fz_copy_aa_context(fz_context *dst, fz_context *src)
+{
+}
+
void *fz_keep_storable(fz_context *ctx, fz_storable *s)
{
return s;
@@ -198,7 +202,7 @@ void fz_drop_store_context(fz_context *ctx)
{
}
-fz_store *fz_store_keep(fz_context *ctx)
+fz_store *fz_keep_store_context(fz_context *ctx)
{
return NULL;
}
diff --git a/scripts/rename2.sed b/scripts/rename2.sed
new file mode 100644
index 00000000..152d9613
--- /dev/null
+++ b/scripts/rename2.sed
@@ -0,0 +1,75 @@
+s/fz_obj/pdf_obj/g
+s/pdf_resolve_indirect/pdf_resolve_indirect_imp/g
+s/fz_resolve_indirect/pdf_resolve_indirect/g
+s/fz_new_null/pdf_new_null/g
+s/fz_new_bool/pdf_new_bool/g
+s/fz_new_int/pdf_new_int/g
+s/fz_new_real/pdf_new_real/g
+s/fz_new_string/pdf_new_string/g
+s/fz_new_indirect/pdf_new_indirect/g
+s/fz_new_array/pdf_new_array/g
+s/fz_new_dict/pdf_new_dict/g
+s/fz_copy_array/pdf_copy_array/g
+s/fz_copy_dict/pdf_copy_dict/g
+s/fz_keep_obj/pdf_keep_obj/g
+s/fz_drop_obj/pdf_drop_obj/g
+s/fz_is_null/pdf_is_null/g
+s/fz_is_bool/pdf_is_bool/g
+s/fz_is_int/pdf_is_int/g
+s/fz_is_real/pdf_is_real/g
+s/fz_is_name/pdf_is_name/g
+s/fz_is_string/pdf_is_string/g
+s/fz_is_array/pdf_is_array/g
+s/fz_is_dict/pdf_is_dict/g
+s/fz_is_indirect/pdf_is_indirect/g
+s/fz_objcmp/pdf_objcmp/g
+s/fz_dict_marked/pdf_dict_marked/g
+s/fz_dict_mark/pdf_dict_mark/g
+s/fz_dict_unmark/pdf_dict_unmark/g
+s/fz_to_bool/pdf_to_bool/g
+s/fz_to_int/pdf_to_int/g
+s/fz_to_real/pdf_to_real/g
+s/fz_to_name/pdf_to_name/g
+s/fz_to_str_buf/pdf_to_str_buf/g
+s/fz_to_dict/pdf_to_dict/g
+s/fz_to_str_len/pdf_to_str_len/g
+s/fz_to_num/pdf_to_num/g
+s/fz_to_gen/pdf_to_gen/g
+s/fz_array_len/pdf_array_len/g
+s/fz_array_get/pdf_array_get/g
+s/fz_array_put/pdf_array_put/g
+s/fz_array_push/pdf_array_push/g
+s/fz_array_insert/pdf_array_insert/g
+s/fz_array_contains/pdf_array_contains/g
+s/fz_dict_len/pdf_dict_len/g
+s/fz_dict_get_val/pdf_dict_get_val/g
+s/fz_dict_get_key/pdf_dict_get_key/g
+s/fz_dict_get/pdf_dict_get/g
+s/fz_dict_gets/pdf_dict_gets/g
+s/fz_dict_getsa/pdf_dict_getsa/g
+s/fz_dict_put/fz_dict_put/g
+s/fz_dict_puts/pdf_dict_puts/g
+s/fz_dict_del/pdf_dict_del/g
+s/fz_dict_dels/pdf_dict_dels/g
+s/fz_sort_dict/pdf_sort_dict/g
+s/fz_fprint_obj/pdf_fprint_obj/g
+s/fz_debug_obj/pdf_debug_obj/g
+s/fz_debug_ref/pdf_debug_ref/g
+s/fz_set_str_len/pdf_set_str_len/g
+s/fz_get_indirect_document/pdf_get_indirect_document/g
+s/FZ_NULL/PDF_NULL/g
+s/FZ_BOOL/PDF_BOOL/g
+s/FZ_INT/PDF_INT/g
+s/FZ_REAL/PDF_REAL/g
+s/FZ_STRING/PDF_STRING/g
+s/FZ_NAME/PDF_NAME/g
+s/FZ_ARRAY/PDF_ARRAY/g
+s/FZ_DICT/PDF_DICT/g
+s/FZ_INDIRECT/PDF_INDIRECT/g
+s/fz_objkindstr/pdf_objkindstr/g
+s/fz_array_grow/pdf_array_grow/g
+s/fz_dict_grow/pdf_dict_grow/g
+s/fz_dict_finds/pdf_dict_finds/g
+s/fz_free_array/pdf_free_array/g
+s/fz_free_dict/pdf_free_dict/g
+s/fz_sprint_obj/pdf_sprint_obj/g
diff --git a/scripts/rename3.sed b/scripts/rename3.sed
new file mode 100644
index 00000000..41868e01
--- /dev/null
+++ b/scripts/rename3.sed
@@ -0,0 +1,37 @@
+s/\<fz_save_pixmap\>/fz_write_pixmap/g
+s/\<fz_debug_hash\>/fz_print_hash/g
+s/\<fz_debug_store\>/fz_print_store/g
+s/\<fz_debug_font\>/fz_print_font/g
+s/\<fz_debug_path\>/fz_print_path/g
+s/\<fz_debug_text\>/fz_print_text/g
+s/\<fz_debug_shade\>/fz_print_shade/g
+s/\<fz_debug_outline_xml\>/fz_print_outline_xml/g
+s/\<fz_debug_outline\>/fz_print_outline/g
+s/\<pdf_debug_xref\>/pdf_print_xref/g
+s/\<pdf_debug_crypt\>/pdf_print_crypt/g
+s/\<pdf_debug_cmap\>/pdf_print_cmap/g
+s/\<pdf_debug_font\>/pdf_print_font/g
+s/\<pdf_debug_obj\>/pdf_print_obj/g
+s/\<pdf_debug_ref\>/pdf_print_ref/g
+s/\<xps_debug_page_list\>/xps_print_page_list/g
+s/\<xps_debug_path\>/xps_print_path/g
+s/\<xps_debug_resource_dictionary\>/xps_print_resource_dictionary/g
+s/\<fz_get_default_halftone\>/fz_default_halftone/g
+s/\<fz_get_aa_level\>/fz_aa_level/g
+s/\<fz_pixmap_pixels\>/fz_pixmap_samples/g
+s/\<pdf_get_crypt_revision\>/pdf_crypt_revision/g
+s/\<pdf_get_crypt_method\>/pdf_crypt_method/g
+s/\<pdf_get_crypt_length\>/pdf_crypt_length/g
+s/\<pdf_get_crypt_key\>/pdf_crypt_key/g
+s/\<pdf_set_wmode\>/pdf_set_cmap_wmode/g
+s/\<pdf_get_wmode\>/pdf_cmap_wmode/g
+s/\<pdf_get_hmtx\>/pdf_lookup_hmtx/g
+s/\<pdf_get_vmtx\>/pdf_lookup_vmtx/g
+s/\<fz_find_blendmode\>/fz_lookup_blendmode/g
+s/\<pdf_find_page_number\>/pdf_lookup_page_number/g
+s/\<xps_find_link_target\>/xps_lookup_link_target/g
+s/\<pdf_find_builtin_font\>/pdf_lookup_builtin_font/g
+s/\<pdf_find_substitute_font\>/pdf_lookup_substitute_font/g
+s/\<pdf_find_substitute_cjk_font\>/pdf_lookup_substitute_cjk_font/g
+s/\<fz_new_pixmap_with_rect_and_data\>/fz_new_pixmap_with_bbox_and_data/g
+s/\<fz_new_pixmap_with_rect\>/fz_new_pixmap_with_bbox/g
diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj
index 9a8bb6e9..543cac48 100644
--- a/win32/libmupdf.vcproj
+++ b/win32/libmupdf.vcproj
@@ -41,7 +41,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\scripts;..\fitz;..\pdf;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.4\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
+ AdditionalIncludeDirectories="..\scripts;..\fitz;..\pdf;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.5.0\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
PreprocessorDefinitions="DEBUG=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -106,7 +106,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="..\scripts;..\fitz;..\pdf;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.4\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
+ AdditionalIncludeDirectories="..\scripts;..\fitz;..\pdf;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.5.0\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
WarningLevel="3"
@@ -166,7 +166,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\scripts;..\fitz;..\pdf;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.4\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
+ AdditionalIncludeDirectories="..\scripts;..\fitz;..\pdf;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.5.0\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
PreprocessorDefinitions="MEMENTO=1;DEBUG=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -210,6 +210,10 @@
Name="pdf"
>
<File
+ RelativePath="..\pdf\base_object.c"
+ >
+ </File>
+ <File
RelativePath="..\pdf\data_encodings.h"
>
</File>
@@ -218,6 +222,10 @@
>
</File>
<File
+ RelativePath="..\pdf\mupdf-internal.h"
+ >
+ </File>
+ <File
RelativePath="..\pdf\mupdf.h"
>
</File>
@@ -310,6 +318,10 @@
>
</File>
<File
+ RelativePath="..\pdf\pdf_store.c"
+ >
+ </File>
+ <File
RelativePath="..\pdf\pdf_stream.c"
>
</File>
@@ -358,10 +370,6 @@
>
</File>
<File
- RelativePath="..\fitz\base_object.c"
- >
- </File>
- <File
RelativePath="..\fitz\base_string.c"
>
</File>
@@ -446,6 +454,10 @@
>
</File>
<File
+ RelativePath="..\fitz\fitz-internal.h"
+ >
+ </File>
+ <File
RelativePath="..\fitz\fitz.h"
>
</File>
@@ -458,10 +470,18 @@
>
</File>
<File
+ RelativePath="..\fitz\image_md5.c"
+ >
+ </File>
+ <File
RelativePath="..\fitz\image_png.c"
>
</File>
<File
+ RelativePath="..\fitz\image_save.c"
+ >
+ </File>
+ <File
RelativePath="..\fitz\image_tiff.c"
>
</File>
diff --git a/win32/libthirdparty.vcproj b/win32/libthirdparty.vcproj
index 18c08942..e5419564 100644
--- a/win32/libthirdparty.vcproj
+++ b/win32/libthirdparty.vcproj
@@ -39,7 +39,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.4\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
+ AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.5.0\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\&quot;slimftmodules.h\&quot;;FT_CONFIG_OPTIONS_H=\&quot;slimftoptions.h\&quot;;DEBUG=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -102,7 +102,7 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.4\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
+ AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.5.0\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\&quot;slimftmodules.h\&quot;;FT_CONFIG_OPTIONS_H=\&quot;slimftoptions.h\&quot;"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -162,7 +162,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.4\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
+ AdditionalIncludeDirectories="..\scripts;..\thirdparty\jbig2dec;..\thirdparty\jpeg-8d;..\thirdparty\openjpeg-1.5.0\libopenjpeg;..\thirdparty\zlib-1.2.5;..\thirdparty\freetype-2.4.8\include"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;FT2_BUILD_LIBRARY;OPJ_STATIC;FT_CONFIG_MODULES_H=\&quot;slimftmodules.h\&quot;;FT_CONFIG_OPTIONS_H=\&quot;slimftoptions.h\&quot;;MEMENTO=1;DEBUG=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -442,75 +442,95 @@
Name="libopenjpeg"
>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\bio.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\bio.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\cio.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\cidx_manager.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\dwt.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\cio.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\event.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\dwt.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\image.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\event.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\j2k.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\image.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\j2k_lib.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\j2k.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\jp2.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\j2k_lib.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\jpt.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\jp2.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\mct.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\jpt.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\mqc.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\mct.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\openjpeg.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\mqc.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\pi.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\openjpeg.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\raw.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\phix_manager.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\t1.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\pi.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\t2.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\ppix_manager.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\tcd.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\raw.c"
>
</File>
<File
- RelativePath="..\thirdparty\openjpeg-1.4\libopenjpeg\tgt.c"
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\t1.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\t2.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\tcd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\tgt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\thix_manager.c"
+ >
+ </File>
+ <File
+ RelativePath="..\thirdparty\openjpeg-1.5.0\libopenjpeg\tpix_manager.c"
>
</File>
</Filter>
diff --git a/xps/muxps-internal.h b/xps/muxps-internal.h
new file mode 100644
index 00000000..20bab4c1
--- /dev/null
+++ b/xps/muxps-internal.h
@@ -0,0 +1,242 @@
+#ifndef MUXPS_INTERNAL_H
+#define MUXPS_INTERNAL_H
+
+#include "muxps.h"
+#include "fitz-internal.h"
+
+typedef unsigned char byte;
+
+/*
+ * XPS and ZIP constants.
+ */
+
+#define REL_START_PART \
+ "http://schemas.microsoft.com/xps/2005/06/fixedrepresentation"
+#define REL_DOC_STRUCTURE \
+ "http://schemas.microsoft.com/xps/2005/06/documentstructure"
+#define REL_REQUIRED_RESOURCE \
+ "http://schemas.microsoft.com/xps/2005/06/required-resource"
+#define REL_REQUIRED_RESOURCE_RECURSIVE \
+ "http://schemas.microsoft.com/xps/2005/06/required-resource#recursive"
+
+#define ZIP_LOCAL_FILE_SIG 0x04034b50
+#define ZIP_DATA_DESC_SIG 0x08074b50
+#define ZIP_CENTRAL_DIRECTORY_SIG 0x02014b50
+#define ZIP_END_OF_CENTRAL_DIRECTORY_SIG 0x06054b50
+
+/*
+ * Memory, and string functions.
+ */
+
+int xps_strcasecmp(char *a, char *b);
+void xps_resolve_url(char *output, char *base_uri, char *path, int output_size);
+int xps_url_is_remote(char *path);
+char *xps_parse_point(char *s_in, float *x, float *y);
+
+/*
+ * Container parts.
+ */
+
+typedef struct xps_part_s xps_part;
+
+struct xps_part_s
+{
+ char *name;
+ int size;
+ int cap;
+ byte *data;
+};
+
+xps_part *xps_new_part(xps_document *doc, char *name, int size);
+int xps_has_part(xps_document *doc, char *partname);
+xps_part *xps_read_part(xps_document *doc, char *partname);
+void xps_free_part(xps_document *doc, xps_part *part);
+
+/*
+ * Document structure.
+ */
+
+typedef struct xps_fixdoc_s xps_fixdoc;
+typedef struct xps_target_s xps_target;
+
+struct xps_fixdoc_s
+{
+ char *name;
+ char *outline;
+ xps_fixdoc *next;
+};
+
+struct xps_page_s
+{
+ char *name;
+ int number;
+ int width;
+ int height;
+ xml_element *root;
+ int links_resolved;
+ fz_link *links;
+ xps_page *next;
+};
+
+struct xps_target_s
+{
+ char *name;
+ int page;
+ xps_target *next;
+};
+
+void xps_read_page_list(xps_document *doc);
+void xps_print_page_list(xps_document *doc);
+void xps_free_page_list(xps_document *doc);
+
+int xps_count_pages(xps_document *doc);
+xps_page *xps_load_page(xps_document *doc, int number);
+fz_link *xps_load_links(xps_document *doc, xps_page *page);
+fz_rect xps_bound_page(xps_document *doc, xps_page *page);
+void xps_free_page(xps_document *doc, xps_page *page);
+
+fz_outline *xps_load_outline(xps_document *doc);
+
+int xps_lookup_link_target(xps_document *doc, char *target_uri);
+void xps_add_link(xps_document *doc, fz_rect area, char *base_uri, char *target_uri);
+/*
+ * Images, fonts, and colorspaces.
+ */
+
+typedef struct xps_font_cache_s xps_font_cache;
+
+struct xps_font_cache_s
+{
+ char *name;
+ fz_font *font;
+ xps_font_cache *next;
+};
+
+typedef struct xps_glyph_metrics_s xps_glyph_metrics;
+
+struct xps_glyph_metrics_s
+{
+ float hadv, vadv, vorg;
+};
+
+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);
+
+void xps_measure_font_glyph(xps_document *doc, fz_font *font, int gid, xps_glyph_metrics *mtx);
+
+void xps_print_path(xps_document *doc);
+
+void xps_parse_color(xps_document *doc, char *base_uri, char *hexstring, fz_colorspace **csp, float *samples);
+void xps_set_color(xps_document *doc, fz_colorspace *colorspace, float *samples);
+
+/*
+ * Resource dictionaries.
+ */
+
+typedef struct xps_resource_s xps_resource;
+
+struct xps_resource_s
+{
+ char *name;
+ char *base_uri; /* only used in the head nodes */
+ xml_element *base_xml; /* only used in the head nodes, to free the xml document */
+ xml_element *data;
+ xps_resource *next;
+ xps_resource *parent; /* up to the previous dict in the stack */
+};
+
+xps_resource * xps_parse_resource_dictionary(xps_document *doc, char *base_uri, xml_element *root);
+void xps_free_resource_dictionary(xps_document *doc, xps_resource *dict);
+void xps_resolve_resource_reference(xps_document *doc, xps_resource *dict, char **attp, xml_element **tagp, char **urip);
+
+void xps_print_resource_dictionary(xps_resource *dict);
+
+/*
+ * Fixed page/graphics parsing.
+ */
+
+void xps_run_page(xps_document *doc, xps_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
+
+void xps_parse_fixed_page(xps_document *doc, fz_matrix ctm, xps_page *page);
+void xps_parse_canvas(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_glyphs(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_solid_color_brush(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_visual_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_linear_gradient_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_radial_gradient_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+
+void xps_parse_tiling_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *root, void(*func)(xps_document*, fz_matrix, fz_rect, char*, xps_resource*, xml_element*, void*), void *user);
+
+void xps_parse_matrix_transform(xps_document *doc, xml_element *root, fz_matrix *matrix);
+void xps_parse_render_transform(xps_document *doc, char *text, fz_matrix *matrix);
+void xps_parse_rectangle(xps_document *doc, char *text, fz_rect *rect);
+
+void xps_begin_opacity(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, char *opacity_att, xml_element *opacity_mask_tag);
+void xps_end_opacity(xps_document *doc, char *base_uri, xps_resource *dict, char *opacity_att, xml_element *opacity_mask_tag);
+
+void xps_parse_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+void xps_parse_element(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
+
+void xps_clip(xps_document *doc, fz_matrix ctm, xps_resource *dict, char *clip_att, xml_element *clip_tag);
+
+/*
+ * The interpreter context.
+ */
+
+typedef struct xps_entry_s xps_entry;
+
+struct xps_entry_s
+{
+ char *name;
+ int offset;
+ int csize;
+ int usize;
+};
+
+struct xps_document_s
+{
+ fz_document super;
+
+ fz_context *ctx;
+ char *directory;
+ fz_stream *file;
+ int zip_count;
+ xps_entry *zip_table;
+
+ char *start_part; /* fixed document sequence */
+ xps_fixdoc *first_fixdoc; /* first fixed document */
+ xps_fixdoc *last_fixdoc; /* last fixed document */
+ xps_page *first_page; /* first page of document */
+ xps_page *last_page; /* last page of document */
+ int page_count;
+
+ xps_target *target; /* link targets */
+
+ char *base_uri; /* base uri for parsing XML and resolving relative paths */
+ char *part_uri; /* part uri for parsing metadata relations */
+
+ /* We cache font resources */
+ xps_font_cache *font_table;
+
+ /* Opacity attribute stack */
+ float opacity[64];
+ int opacity_top;
+
+ /* Current color */
+ fz_colorspace *colorspace;
+ float color[8];
+ float alpha;
+
+ /* Current device */
+ fz_cookie *cookie;
+ fz_device *dev;
+
+ /* Current page we are loading */
+ xps_page *current_page;
+};
+
+#endif
diff --git a/xps/muxps.h b/xps/muxps.h
index 6037a64e..a485adca 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -1,39 +1,10 @@
-#ifndef _MUXPS_H_
-#define _MUXPS_H_
+#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 constants.
- */
+#include "fitz.h"
typedef struct xps_document_s xps_document;
-
-#define REL_START_PART \
- "http://schemas.microsoft.com/xps/2005/06/fixedrepresentation"
-#define REL_DOC_STRUCTURE \
- "http://schemas.microsoft.com/xps/2005/06/documentstructure"
-#define REL_REQUIRED_RESOURCE \
- "http://schemas.microsoft.com/xps/2005/06/required-resource"
-#define REL_REQUIRED_RESOURCE_RECURSIVE \
- "http://schemas.microsoft.com/xps/2005/06/required-resource#recursive"
-
-#define ZIP_LOCAL_FILE_SIG 0x04034b50
-#define ZIP_DATA_DESC_SIG 0x08074b50
-#define ZIP_CENTRAL_DIRECTORY_SIG 0x02014b50
-#define ZIP_END_OF_CENTRAL_DIRECTORY_SIG 0x06054b50
-
-/*
- * Memory, and string functions.
- */
-
-int xps_strcasecmp(char *a, char *b);
-void xps_resolve_url(char *output, char *base_uri, char *path, int output_size);
-int xps_url_is_remote(char *path);
+typedef struct xps_page_s xps_page;
/*
* XML document model
@@ -41,7 +12,7 @@ int xps_url_is_remote(char *path);
typedef struct element xml_element;
-xml_element *xml_parse_document(fz_context *doc, byte *buf, int len);
+xml_element *xml_parse_document(fz_context *doc, unsigned char *buf, int len);
xml_element *xml_next(xml_element *item);
xml_element *xml_down(xml_element *item);
char *xml_tag(xml_element *item);
@@ -50,220 +21,48 @@ void xml_free_element(fz_context *doc, xml_element *item);
void xml_print_element(xml_element *item, int level);
/*
- * Container parts.
- */
+ xps_open_document: Open a document.
-typedef struct xps_part_s xps_part;
+ Open a document for reading so the library is able to locate
+ objects and pages inside the file.
-struct xps_part_s
-{
- char *name;
- int size;
- int cap;
- byte *data;
-};
+ The returned xps_document should be used when calling most
+ other functions. Note that it wraps the context, so those
+ functions implicitly get access to the global state in
+ context.
-xps_part *xps_new_part(xps_document *doc, char *name, int size);
-int xps_has_part(xps_document *doc, char *partname);
-xps_part *xps_read_part(xps_document *doc, char *partname);
-void xps_free_part(xps_document *doc, xps_part *part);
+ filename: a path to a file as it would be given to open(2).
+*/
+xps_document *xps_open_document(fz_context *ctx, char *filename);
/*
- * Document structure.
- */
-
-typedef struct xps_fixdoc_s xps_fixdoc;
-typedef struct xps_page_s xps_page;
-typedef struct xps_target_s xps_target;
-
-struct xps_fixdoc_s
-{
- char *name;
- char *outline;
- xps_fixdoc *next;
-};
+ xps_open_document_with_stream: Opens a document.
+
+ Same as xps_open_document, but takes a stream instead of a
+ filename to locate the document to open. Increments the
+ reference count of the stream. See fz_open_file,
+ fz_open_file_w or fz_open_fd for opening a stream, and
+ fz_close for closing an open stream.
+*/
+xps_document *xps_open_document_with_stream(fz_stream *file);
-struct xps_page_s
-{
- char *name;
- int number;
- int width;
- int height;
- xml_element *root;
- int links_resolved;
- fz_link *links;
- xps_page *next;
-};
+/*
+ xps_close_document: Closes and frees an opened document.
-struct xps_target_s
-{
- char *name;
- int page;
- xps_target *next;
-};
+ The resource store in the context associated with xps_document
+ is emptied.
-void xps_read_page_list(xps_document *doc);
-void xps_debug_page_list(xps_document *doc);
-void xps_free_page_list(xps_document *doc);
+ Does not throw exceptions.
+*/
+void xps_close_document(xps_document *doc);
int xps_count_pages(xps_document *doc);
xps_page *xps_load_page(xps_document *doc, int number);
-fz_link *xps_load_links(xps_document *doc, xps_page *page);
fz_rect xps_bound_page(xps_document *doc, xps_page *page);
+void xps_run_page(xps_document *doc, xps_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
+fz_link *xps_load_links(xps_document *doc, xps_page *page);
void xps_free_page(xps_document *doc, xps_page *page);
fz_outline *xps_load_outline(xps_document *doc);
-int xps_find_link_target(xps_document *doc, char *target_uri);
-void xps_add_link(xps_document *doc, fz_rect area, char *base_uri, char *target_uri);
-/*
- * Images, fonts, and colorspaces.
- */
-
-typedef struct xps_font_cache_s xps_font_cache;
-
-struct xps_font_cache_s
-{
- char *name;
- fz_font *font;
- xps_font_cache *next;
-};
-
-typedef struct xps_glyph_metrics_s xps_glyph_metrics;
-
-struct xps_glyph_metrics_s
-{
- float hadv, vadv, vorg;
-};
-
-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);
-
-void xps_measure_font_glyph(xps_document *doc, fz_font *font, int gid, xps_glyph_metrics *mtx);
-
-void xps_debug_path(xps_document *doc);
-
-void xps_parse_color(xps_document *doc, char *base_uri, char *hexstring, fz_colorspace **csp, float *samples);
-void xps_set_color(xps_document *doc, fz_colorspace *colorspace, float *samples);
-
-/*
- * Resource dictionaries.
- */
-
-typedef struct xps_resource_s xps_resource;
-
-struct xps_resource_s
-{
- char *name;
- char *base_uri; /* only used in the head nodes */
- xml_element *base_xml; /* only used in the head nodes, to free the xml document */
- xml_element *data;
- xps_resource *next;
- xps_resource *parent; /* up to the previous dict in the stack */
-};
-
-xps_resource * xps_parse_resource_dictionary(xps_document *doc, char *base_uri, xml_element *root);
-void xps_free_resource_dictionary(xps_document *doc, xps_resource *dict);
-void xps_resolve_resource_reference(xps_document *doc, xps_resource *dict, char **attp, xml_element **tagp, char **urip);
-
-void xps_debug_resource_dictionary(xps_resource *dict);
-
-/*
- * Fixed page/graphics parsing.
- */
-
-void xps_run_page(xps_document *doc, xps_page *page, fz_device *dev, fz_matrix ctm, fz_cookie *cookie);
-
-void xps_parse_fixed_page(xps_document *doc, fz_matrix ctm, xps_page *page);
-void xps_parse_canvas(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_path(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_glyphs(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_solid_color_brush(xps_document *doc, fz_matrix ctm, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_visual_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_linear_gradient_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_radial_gradient_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-
-void xps_parse_tiling_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *root, void(*func)(xps_document*, fz_matrix, fz_rect, char*, xps_resource*, xml_element*, void*), void *user);
-
-void xps_parse_matrix_transform(xps_document *doc, xml_element *root, fz_matrix *matrix);
-void xps_parse_render_transform(xps_document *doc, char *text, fz_matrix *matrix);
-void xps_parse_rectangle(xps_document *doc, char *text, fz_rect *rect);
-
-void xps_begin_opacity(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, char *opacity_att, xml_element *opacity_mask_tag);
-void xps_end_opacity(xps_document *doc, char *base_uri, xps_resource *dict, char *opacity_att, xml_element *opacity_mask_tag);
-
-void xps_parse_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-void xps_parse_element(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict, xml_element *node);
-
-void xps_clip(xps_document *doc, fz_matrix ctm, xps_resource *dict, char *clip_att, xml_element *clip_tag);
-
-/*
- * The interpreter context.
- */
-
-typedef struct xps_entry_s xps_entry;
-
-struct xps_entry_s
-{
- char *name;
- int offset;
- int csize;
- int usize;
-};
-
-struct xps_document_s
-{
- fz_document super;
-
- fz_context *ctx;
- char *directory;
- fz_stream *file;
- int zip_count;
- xps_entry *zip_table;
-
- char *start_part; /* fixed document sequence */
- xps_fixdoc *first_fixdoc; /* first fixed document */
- xps_fixdoc *last_fixdoc; /* last fixed document */
- xps_page *first_page; /* first page of document */
- xps_page *last_page; /* last page of document */
- int page_count;
-
- xps_target *target; /* link targets */
-
- char *base_uri; /* base uri for parsing XML and resolving relative paths */
- char *part_uri; /* part uri for parsing metadata relations */
-
- /* We cache font resources */
- xps_font_cache *font_table;
-
- /* Opacity attribute stack */
- float opacity[64];
- int opacity_top;
-
- /* Current color */
- fz_colorspace *colorspace;
- float color[8];
- float alpha;
-
- /* Current device */
- fz_cookie *cookie;
- fz_device *dev;
-
- /* Current page we are loading */
- xps_page *current_page;
-};
-
-xps_document *xps_open_document(fz_context *ctx, char *filename);
-xps_document *xps_open_document_with_stream(fz_stream *file);
-void xps_close_document(xps_document *doc);
-
-/*
- * Parsing helper functions
- */
-char *xps_get_real_params(char *s, int num, float *x);
-char *xps_get_point(char *s_in, float *x, float *y);
-
#endif
diff --git a/xps/xps_common.c b/xps/xps_common.c
index 32ea3fdc..4829ef9c 100644
--- a/xps/xps_common.c
+++ b/xps/xps_common.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
static inline int unhex(int a)
{
diff --git a/xps/xps_doc.c b/xps/xps_doc.c
index d8ab7bf4..a2665f95 100644
--- a/xps/xps_doc.c
+++ b/xps/xps_doc.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
static void
xps_rels_for_part(char *buf, char *name, int buflen)
@@ -21,7 +20,7 @@ xps_rels_for_part(char *buf, char *name, int buflen)
*/
void
-xps_debug_page_list(xps_document *doc)
+xps_print_page_list(xps_document *doc)
{
xps_fixdoc *fixdoc = doc->first_fixdoc;
xps_page *page = doc->first_page;
@@ -193,7 +192,7 @@ xps_add_link_target(xps_document *doc, char *name)
}
int
-xps_find_link_target(xps_document *doc, char *target_uri)
+xps_lookup_link_target(xps_document *doc, char *target_uri)
{
xps_target *target;
char *needle = strrchr(target_uri, '#');
diff --git a/xps/xps_glyphs.c b/xps/xps_glyphs.c
index f7098ed1..94baa918 100644
--- a/xps/xps_glyphs.c
+++ b/xps/xps_glyphs.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
#include <ft2build.h>
#include FT_FREETYPE_H
@@ -307,7 +306,7 @@ xps_parse_glyphs_imp(xps_document *doc, fz_matrix ctm,
{
if (us && un > 0)
{
- int t = chartorune(&char_code, us);
+ int t = fz_chartorune(&char_code, us);
us += t; un -= t;
}
}
diff --git a/xps/xps_gradient.c b/xps/xps_gradient.c
index f0ad0104..fe88b295 100644
--- a/xps/xps_gradient.c
+++ b/xps/xps_gradient.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
#define MAX_STOPS 256
@@ -61,7 +60,7 @@ xps_parse_gradient_stops(xps_document *doc, char *base_uri, xml_element *node,
xps_parse_color(doc, base_uri, color, &colorspace, sample);
- fz_convert_color(doc->ctx, colorspace, sample + 1, fz_device_rgb, rgb);
+ fz_convert_color(doc->ctx, fz_device_rgb, rgb, colorspace, sample + 1);
stops[count].r = rgb[0];
stops[count].g = rgb[1];
@@ -318,9 +317,9 @@ xps_draw_radial_gradient(xps_document *doc, fz_matrix ctm,
yrad = 1.0;
if (origin_att)
- xps_get_point(origin_att, &x0, &y0);
+ xps_parse_point(origin_att, &x0, &y0);
if (center_att)
- xps_get_point(center_att, &x1, &y1);
+ xps_parse_point(center_att, &x1, &y1);
if (radius_x_att)
xrad = fz_atof(radius_x_att);
if (radius_y_att)
@@ -362,9 +361,9 @@ xps_draw_linear_gradient(xps_document *doc, fz_matrix ctm,
x1 = y1 = 1;
if (start_point_att)
- xps_get_point(start_point_att, &x0, &y0);
+ xps_parse_point(start_point_att, &x0, &y0);
if (end_point_att)
- xps_get_point(end_point_att, &x1, &y1);
+ xps_parse_point(end_point_att, &x1, &y1);
xps_draw_one_linear_gradient(doc, ctm, stops, count, 1, x0, y0, x1, y1);
}
diff --git a/xps/xps_image.c b/xps/xps_image.c
index 10d3baee..1f46a756 100644
--- a/xps/xps_image.c
+++ b/xps/xps_image.c
@@ -1,41 +1,92 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
+
+typedef struct xps_image_s xps_image;
+
+struct xps_image_s
+{
+ fz_image base;
+ fz_pixmap *pix;
+ int xres;
+ int yres;
+};
+
+static void
+xps_free_image(fz_context *ctx, fz_storable *image_)
+{
+ xps_image *image = (xps_image *)image_;
+
+ if (image == NULL)
+ return;
+
+ fz_drop_colorspace(ctx, image->base.colorspace);
+ fz_drop_pixmap(ctx, image->pix);
+ fz_free(ctx, image);
+}
static fz_pixmap *
+xps_image_to_pixmap(fz_context *ctx, fz_image *image_, int x, int w)
+{
+ xps_image *image = (xps_image *)image_;
+
+ return fz_keep_pixmap(ctx, image->pix);
+}
+
+static fz_image *
xps_load_image(fz_context *ctx, byte *buf, int len)
{
- fz_pixmap *image;
+ fz_pixmap *pix;
+ xps_image *image;
if (len < 8)
fz_throw(ctx, "unknown image file format");
if (buf[0] == 0xff && buf[1] == 0xd8)
- image = fz_load_jpeg(ctx, buf, len);
+ pix = fz_load_jpeg(ctx, buf, len);
else if (memcmp(buf, "\211PNG\r\n\032\n", 8) == 0)
- image = fz_load_png(ctx, buf, len);
+ pix = fz_load_png(ctx, buf, len);
else if (memcmp(buf, "II", 2) == 0 && buf[2] == 0xBC)
fz_throw(ctx, "JPEG-XR codec is not available");
else if (memcmp(buf, "MM", 2) == 0 || memcmp(buf, "II", 2) == 0)
- image = fz_load_tiff(ctx, buf, len);
+ pix = fz_load_tiff(ctx, buf, len);
else
fz_throw(ctx, "unknown image file format");
- return image;
+ fz_try(ctx)
+ {
+ image = fz_malloc_struct(ctx, xps_image);
+
+ FZ_INIT_STORABLE(&image->base, 1, xps_free_image);
+ image->base.w = pix->w;
+ image->base.h = pix->h;
+ image->base.mask = NULL;
+ image->base.colorspace = pix->colorspace;
+ image->base.get_pixmap = xps_image_to_pixmap;
+ image->xres = pix->xres;
+ image->yres = pix->yres;
+ image->pix = pix;
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_pixmap(ctx, pix);
+ fz_rethrow(ctx);
+ }
+
+ return &image->base;
}
static void
xps_paint_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area, char *base_uri, xps_resource *dict,
xml_element *root, void *vimage)
{
- fz_pixmap *pixmap = vimage;
+ xps_image *image = vimage;
float xs, ys;
- if (pixmap->xres == 0 || pixmap->yres == 0)
+ if (image->xres == 0 || image->yres == 0)
return;
- xs = pixmap->w * 96 / pixmap->xres;
- ys = pixmap->h * 96 / pixmap->yres;
+ xs = image->base.w * 96 / image->xres;
+ ys = image->base.h * 96 / image->yres;
ctm = fz_concat(fz_scale(xs, ys), ctm);
- fz_fill_image(doc->dev, pixmap, ctm, doc->opacity[doc->opacity_top]);
+ fz_fill_image(doc->dev, &image->base, ctm, doc->opacity[doc->opacity_top]);
}
static xps_part *
@@ -93,7 +144,7 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area,
char *base_uri, xps_resource *dict, xml_element *root)
{
xps_part *part;
- fz_pixmap *image;
+ fz_image *image;
fz_try(doc->ctx)
{
@@ -119,5 +170,5 @@ xps_parse_image_brush(xps_document *doc, fz_matrix ctm, fz_rect area,
xps_parse_tiling_brush(doc, ctm, area, base_uri, dict, root, xps_paint_image_brush, image);
- fz_drop_pixmap(doc->ctx, image);
+ fz_drop_image(doc->ctx, image);
}
diff --git a/xps/xps_outline.c b/xps/xps_outline.c
index 30357491..6bf7fd14 100644
--- a/xps/xps_outline.c
+++ b/xps/xps_outline.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
/*
* Parse the document structure / outline parts referenced from fixdoc relationships.
@@ -35,7 +34,7 @@ xps_parse_document_outline(xps_document *doc, xml_element *root)
entry->title = fz_strdup(doc->ctx, description);
entry->dest.kind = FZ_LINK_GOTO;
entry->dest.ld.gotor.flags = 0;
- entry->dest.ld.gotor.page = xps_find_link_target(doc, target);
+ entry->dest.ld.gotor.page = xps_lookup_link_target(doc, target);
entry->down = NULL;
entry->next = NULL;
diff --git a/xps/xps_path.c b/xps/xps_path.c
index 76b9bb21..337f144d 100644
--- a/xps/xps_path.c
+++ b/xps/xps_path.c
@@ -1,8 +1,7 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
-char *
-xps_get_real_params(char *s, int num, float *x)
+static char *
+xps_parse_float_array(char *s, int num, float *x)
{
int k = 0;
@@ -25,12 +24,12 @@ xps_get_real_params(char *s, int num, float *x)
}
char *
-xps_get_point(char *s_in, float *x, float *y)
+xps_parse_point(char *s_in, float *x, float *y)
{
char *s_out = s_in;
float xy[2];
- s_out = xps_get_real_params(s_out, 2, &xy[0]);
+ s_out = xps_parse_float_array(s_out, 2, &xy[0]);
*x = xy[0];
*y = xy[1];
return s_out;
@@ -516,8 +515,8 @@ xps_parse_arc_segment(fz_context *doc, fz_path *path, xml_element *root, int str
if (!is_stroked)
*skipped_stroke = 1;
- xps_get_point(point_att, &point_x, &point_y);
- xps_get_point(size_att, &size_x, &size_y);
+ xps_parse_point(point_att, &point_x, &point_y);
+ xps_parse_point(size_att, &size_x, &size_y);
rotation_angle = fz_atof(rotation_angle_att);
is_large_arc = !strcmp(is_large_arc_att, "true");
is_clockwise = !strcmp(sweep_direction_att, "Clockwise");
@@ -559,7 +558,7 @@ xps_parse_poly_quadratic_bezier_segment(fz_context *doc, fz_path *path, xml_elem
while (*s != 0)
{
while (*s == ' ') s++;
- s = xps_get_point(s, &x[n], &y[n]);
+ s = xps_parse_point(s, &x[n], &y[n]);
n ++;
if (n == 2)
{
@@ -607,7 +606,7 @@ xps_parse_poly_bezier_segment(fz_context *doc, fz_path *path, xml_element *root,
while (*s != 0)
{
while (*s == ' ') s++;
- s = xps_get_point(s, &x[n], &y[n]);
+ s = xps_parse_point(s, &x[n], &y[n]);
n ++;
if (n == 3)
{
@@ -645,7 +644,7 @@ xps_parse_poly_line_segment(fz_context *doc, fz_path *path, xml_element *root, i
while (*s != 0)
{
while (*s == ' ') s++;
- s = xps_get_point(s, &x, &y);
+ s = xps_parse_point(s, &x, &y);
if (stroking && !is_stroked)
fz_moveto(doc, path, x, y);
else
@@ -678,7 +677,7 @@ xps_parse_path_figure(fz_context *doc, fz_path *path, xml_element *root, int str
if (is_filled_att)
is_filled = !strcmp(is_filled_att, "true");
if (start_point_att)
- xps_get_point(start_point_att, &start_x, &start_y);
+ xps_parse_point(start_point_att, &start_x, &start_y);
if (!stroking && !is_filled) /* not filled, when filling */
return;
diff --git a/xps/xps_resource.c b/xps/xps_resource.c
index dcf3717d..aa3cdc75 100644
--- a/xps/xps_resource.c
+++ b/xps/xps_resource.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
static xml_element *
xps_find_resource(xps_document *doc, xps_resource *dict, char *name, char **urip)
@@ -142,7 +141,7 @@ xps_free_resource_dictionary(xps_document *doc, xps_resource *dict)
}
void
-xps_debug_resource_dictionary(xps_resource *dict)
+xps_print_resource_dictionary(xps_resource *dict)
{
while (dict)
{
@@ -152,7 +151,7 @@ xps_debug_resource_dictionary(xps_resource *dict)
if (dict->parent)
{
printf("PARENT = {\n");
- xps_debug_resource_dictionary(dict->parent);
+ xps_print_resource_dictionary(dict->parent);
printf("}\n");
}
dict = dict->next;
diff --git a/xps/xps_tile.c b/xps/xps_tile.c
index e87d76f7..5ec0463f 100644
--- a/xps/xps_tile.c
+++ b/xps/xps_tile.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
#define TILE
diff --git a/xps/xps_util.c b/xps/xps_util.c
index b79927ba..cb84ba71 100644
--- a/xps/xps_util.c
+++ b/xps/xps_util.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
static inline int xps_tolower(int c)
{
diff --git a/xps/xps_xml.c b/xps/xps_xml.c
index 15c510a6..e2e958c8 100644
--- a/xps/xps_xml.c
+++ b/xps/xps_xml.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
struct attribute
{
@@ -185,7 +184,7 @@ static void xml_emit_att_value(struct parser *parser, char *a, char *b)
while (a < b) {
if (*a == '&') {
a += xml_parse_entity(&c, a);
- s += runetochar(s, &c);
+ s += fz_runetochar(s, c);
}
else {
*s++ = *a++;
@@ -340,7 +339,7 @@ static char *convert_to_utf8(fz_context *doc, unsigned char *s, int n)
dst = d = fz_malloc(doc, n * 2);
while (s + 1 < e) {
c = s[0] << 8 | s[1];
- d += runetochar(d, &c);
+ d += fz_runetochar(d, c);
s += 2;
}
*d = 0;
@@ -351,7 +350,7 @@ static char *convert_to_utf8(fz_context *doc, unsigned char *s, int n)
dst = d = fz_malloc(doc, n * 2);
while (s + 1 < e) {
c = s[0] | s[1] << 8;
- d += runetochar(d, &c);
+ d += fz_runetochar(d, c);
s += 2;
}
*d = 0;
diff --git a/xps/xps_zip.c b/xps/xps_zip.c
index 08d9832a..be7ae221 100644
--- a/xps/xps_zip.c
+++ b/xps/xps_zip.c
@@ -1,5 +1,4 @@
-#include "fitz.h"
-#include "muxps.h"
+#include "muxps-internal.h"
#include <zlib.h>