summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-01 16:44:30 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-01 16:44:30 +0200
commita6de4b76903f590c776c112e02e2f2ce0a363010 (patch)
tree397c2c8c925331c93e83303267cced1d22aeeb81
parentd2250034a7e629455b9bfbf735473ea39638a701 (diff)
downloadmupdf-a6de4b76903f590c776c112e02e2f2ce0a363010.tar.xz
apps: Add XPS support to mupdf viewer.
-rw-r--r--Makefile8
-rw-r--r--apps/pdfapp.c176
-rw-r--r--apps/pdfapp.h8
-rw-r--r--apps/x11_main.c1
-rw-r--r--mupdf/mupdf.h2
-rw-r--r--mupdf/pdf_page.c6
-rw-r--r--xps/muxps.h1
-rw-r--r--xps/xpszip.c8
8 files changed, 147 insertions, 63 deletions
diff --git a/Makefile b/Makefile
index 23e0a281..23ce82d1 100644
--- a/Makefile
+++ b/Makefile
@@ -397,8 +397,8 @@ X11VIEW_OBJ=$(X11VIEW_SRC:apps/%.c=$(OBJDIR)/%.o)
X11VIEW_EXE=$(OBJDIR)/mupdf
$(X11VIEW_OBJ): $(MUPDF_HDR) $(PDFAPP_HDR)
-$(X11VIEW_EXE): $(X11VIEW_OBJ) $(MUPDF_LIB) $(THIRD_LIBS)
- $(LD_CMD) $(X11LIBS)
+$(X11VIEW_EXE): $(X11VIEW_OBJ) $(MUPDF_LIB) $(MUXPS_LIB) $(THIRD_LIBS)
+ $(LD_CMD) $(XPSLIBS) $(X11LIBS)
WINVIEW_SRC=apps/win_main.c apps/pdfapp.c
WINVIEW_RES=apps/win_res.rc
@@ -409,8 +409,8 @@ $(OBJDIR)/%.o: apps/%.rc
$(WINDRES) -i $< -o $@ --include-dir=apps
$(WINVIEW_OBJ): $(MUPDF_HDR) $(PDFAPP_HDR)
-$(WINVIEW_EXE): $(WINVIEW_OBJ) $(MUPDF_LIB) $(THIRD_LIBS)
- $(LD_CMD) $(W32LIBS)
+$(WINVIEW_EXE): $(WINVIEW_OBJ) $(MUPDF_LIB) $(MUXPS_LIB) $(THIRD_LIBS)
+ $(LD_CMD) $(XPSLIBS) $(W32LIBS)
#
# Default rules
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 2fca8d0c..aec9ad62 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -1,5 +1,6 @@
-#include <fitz.h>
-#include <mupdf.h>
+#include "fitz.h"
+#include "mupdf.h"
+#include "muxps.h"
#include "pdfapp.h"
#include <ctype.h> /* for tolower() */
@@ -95,15 +96,13 @@ void pdfapp_invert(pdfapp_t *app, fz_bbox rect)
}
}
-void pdfapp_open(pdfapp_t *app, char *filename, int fd)
+static void pdfapp_open_pdf(pdfapp_t *app, char *filename, int fd)
{
fz_error error;
+ fz_stream *file;
+ char *password = "";
fz_obj *obj;
fz_obj *info;
- char *password = "";
- fz_stream *file;
-
- app->cache = fz_newglyphcache();
/*
* Open PDF and load xref table
@@ -161,6 +160,32 @@ void pdfapp_open(pdfapp_t *app, char *filename, int fd)
pdfapp_error(app, fz_rethrow(error, "cannot load page tree"));
app->pagecount = pdf_getpagecount(app->xref);
+}
+
+static void pdfapp_open_xps(pdfapp_t *app, char *filename, int fd)
+{
+ fz_error error;
+
+ close(fd); // TODO: fix this for windows
+
+ app->xps = xps_new_context();
+ error = xps_open_file(app->xps, filename);
+ if (error)
+ pdfapp_error(app, fz_rethrow(error, "cannot open document: '%s'", filename));
+
+ app->doctitle = filename;
+
+ app->pagecount = xps_count_pages(app->xps);
+}
+
+void pdfapp_open(pdfapp_t *app, char *filename, int fd)
+{
+ if (strstr(filename, ".xps") || strstr(filename, ".XPS"))
+ pdfapp_open_xps(app, filename, fd);
+ else
+ pdfapp_open_pdf(app, filename, fd);
+
+ app->cache = fz_newglyphcache();
app->shrinkwrap = 1;
if (app->pageno < 1)
@@ -184,10 +209,6 @@ void pdfapp_close(pdfapp_t *app)
fz_freeglyphcache(app->cache);
app->cache = nil;
- if (app->page)
- pdf_freepage(app->page);
- app->page = nil;
-
if (app->image)
fz_droppixmap(app->image);
app->image = nil;
@@ -206,6 +227,12 @@ void pdfapp_close(pdfapp_t *app)
app->xref = nil;
}
+ if (app->xps)
+ {
+ xps_free_context(app->xps);
+ app->xps = NULL;
+ }
+
fz_flushwarnings();
}
@@ -213,9 +240,12 @@ static fz_matrix pdfapp_viewctm(pdfapp_t *app)
{
fz_matrix ctm;
ctm = fz_identity;
- ctm = fz_concat(ctm, fz_translate(0, -app->page->mediabox.y1));
- ctm = fz_concat(ctm, fz_scale(app->resolution/72.0f, -app->resolution/72.0f));
- ctm = fz_concat(ctm, fz_rotate(app->rotate + app->page->rotate));
+ ctm = fz_concat(ctm, fz_translate(0, -app->page_bbox.y1));
+ if (app->xref)
+ ctm = fz_concat(ctm, fz_scale(app->resolution/72.0f, -app->resolution/72.0f));
+ else
+ ctm = fz_concat(ctm, fz_scale(app->resolution/72.0f, app->resolution/72.0f));
+ ctm = fz_concat(ctm, fz_rotate(app->rotate + app->page_rotate));
return ctm;
}
@@ -243,51 +273,97 @@ static void pdfapp_panview(pdfapp_t *app, int newx, int newy)
app->pany = newy;
}
+static void pdfapp_loadpage_pdf(pdfapp_t *app)
+{
+ pdf_page *page;
+ fz_error error;
+ fz_device *mdev;
+ fz_obj *obj;
+
+ obj = pdf_getpageobject(app->xref, app->pageno);
+ error = pdf_loadpage(&page, app->xref, obj);
+ if (error)
+ pdfapp_error(app, error);
+
+ app->page_bbox = page->mediabox;
+ app->page_rotate = page->rotate;
+ app->page_links = page->links;
+ page->links = NULL;
+
+ /* Create display list */
+ app->page_list = fz_newdisplaylist();
+ mdev = fz_newlistdevice(app->page_list);
+ error = pdf_runpage(app->xref, page, mdev, fz_identity);
+ if (error)
+ {
+ error = fz_rethrow(error, "cannot draw page %d in '%s'", app->pageno, app->doctitle);
+ pdfapp_error(app, error);
+ }
+ fz_freedevice(mdev);
+
+ pdf_freepage(page);
+
+ pdf_agestore(app->xref->store, 3);
+}
+
+static void pdfapp_loadpage_xps(pdfapp_t *app)
+{
+ xps_page *page;
+ fz_device *mdev;
+
+ page = xps_load_page(app->xps, app->pageno - 1);
+ if (!page)
+ pdfapp_error(app, fz_throw("cannot load page %d in file '%s'", app->pageno, app->doctitle));
+
+ app->page_bbox = fz_transformrect(fz_scale(page->width, page->height), fz_unitrect);
+ app->page_rotate = 0;
+ app->page_links = NULL;
+
+ /* Create display list */
+ app->page_list = fz_newdisplaylist();
+ mdev = fz_newlistdevice(app->page_list);
+ app->xps->dev = mdev;
+ xps_parse_fixed_page(app->xps, fz_identity, page);
+ app->xps->dev = nil;
+ fz_freedevice(mdev);
+
+ xps_free_page(app->xps, page);
+}
+
static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repaint)
{
char buf[256];
- fz_error error;
- fz_device *idev, *tdev, *mdev;
+ fz_device *idev;
+ fz_device *tdev;
fz_colorspace *colorspace;
fz_matrix ctm;
fz_bbox bbox;
- fz_obj *obj;
wincursor(app, WAIT);
if (loadpage)
{
- if (app->page)
- pdf_freepage(app->page);
- app->page = nil;
-
- obj = pdf_getpageobject(app->xref, app->pageno);
- error = pdf_loadpage(&app->page, app->xref, obj);
- if (error)
- pdfapp_error(app, error);
-
- /* Create display list */
- app->page->list = fz_newdisplaylist();
- mdev = fz_newlistdevice(app->page->list);
- error = pdf_runpage(app->xref, app->page, mdev, fz_identity);
- if (error)
- {
- error = fz_rethrow(error, "cannot draw page %d in '%s'", app->pageno, app->doctitle);
- pdfapp_error(app, error);
- }
- fz_freedevice(mdev);
+ if (app->page_list)
+ fz_freedisplaylist(app->page_list);
+ if (app->page_text)
+ fz_freetextspan(app->page_text);
+ if (app->page_links)
+ pdf_freelink(app->page_links);
+
+ if (app->xref)
+ pdfapp_loadpage_pdf(app);
+ if (app->xps)
+ pdfapp_loadpage_xps(app);
/* Zero search hit position */
app->hit = -1;
app->hitlen = 0;
/* Extract text */
- app->page->text = fz_newtextspan();
- tdev = fz_newtextdevice(app->page->text);
- fz_executedisplaylist(app->page->list, tdev, fz_identity);
+ app->page_text = fz_newtextspan();
+ tdev = fz_newtextdevice(app->page_text);
+ fz_executedisplaylist(app->page_list, tdev, fz_identity);
fz_freedevice(tdev);
-
- pdf_agestore(app->xref->store, 3);
}
if (drawpage)
@@ -297,7 +373,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
wintitle(app, buf);
ctm = pdfapp_viewctm(app);
- bbox = fz_roundrect(fz_transformrect(ctm, app->page->mediabox));
+ bbox = fz_roundrect(fz_transformrect(ctm, app->page_bbox));
/* Draw */
if (app->image)
@@ -313,7 +389,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
app->image = fz_newpixmapwithrect(colorspace, bbox);
fz_clearpixmapwithcolor(app->image, 255);
idev = fz_newdrawdevice(app->cache, app->image);
- fz_executedisplaylist(app->page->list, idev, ctm);
+ fz_executedisplaylist(app->page_list, idev, ctm);
fz_freedevice(idev);
}
@@ -402,7 +478,7 @@ void pdfapp_inverthit(pdfapp_t *app)
for (i = app->hit; i < app->hit + app->hitlen; i++)
{
- bbox = bboxcharat(app->page->text, i);
+ bbox = bboxcharat(app->page_text, i);
if (fz_isemptyrect(bbox))
{
if (!fz_isemptyrect(hitbox))
@@ -492,7 +568,7 @@ static void pdfapp_searchforward(pdfapp_t *app)
do
{
- len = textlen(app->page->text);
+ len = textlen(app->page_text);
if (app->hit >= 0)
test = app->hit + strlen(app->search);
@@ -501,7 +577,7 @@ static void pdfapp_searchforward(pdfapp_t *app)
while (test < len)
{
- matchlen = match(app->search, app->page->text, test);
+ matchlen = match(app->search, app->page_text, test);
if (matchlen)
{
app->hit = test;
@@ -540,7 +616,7 @@ static void pdfapp_searchbackward(pdfapp_t *app)
do
{
- len = textlen(app->page->text);
+ len = textlen(app->page_text);
if (app->hit >= 0)
test = app->hit - 1;
@@ -549,7 +625,7 @@ static void pdfapp_searchbackward(pdfapp_t *app)
while (test >= 0)
{
- matchlen = match(app->search, app->page->text, test);
+ matchlen = match(app->search, app->page_text, test);
if (matchlen)
{
app->hit = test;
@@ -881,7 +957,7 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
p = fz_transformpoint(ctm, p);
- for (link = app->page->links; link; link = link->next)
+ for (link = app->page_links; link; link = link->next)
{
if (p.x >= link->rect.x0 && p.x <= link->rect.x1)
if (p.y >= link->rect.y0 && p.y <= link->rect.y1)
@@ -1005,7 +1081,7 @@ 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)
+ for (span = app->page_text; span; span = span->next)
{
seen = 0;
diff --git a/apps/pdfapp.h b/apps/pdfapp.h
index 3771485e..dda637db 100644
--- a/apps/pdfapp.h
+++ b/apps/pdfapp.h
@@ -31,6 +31,8 @@ struct pdfapp_s
char *doctitle;
pdf_xref *xref;
pdf_outline *outline;
+ xps_context *xps;
+
int pagecount;
fz_glyphcache *cache;
@@ -42,7 +44,11 @@ struct pdfapp_s
/* current page params */
int pageno;
- pdf_page *page;
+ fz_rect page_bbox;
+ float page_rotate;
+ fz_displaylist *page_list;
+ fz_textspan *page_text;
+ pdf_link *page_links;
/* snapback history */
int hist[256];
diff --git a/apps/x11_main.c b/apps/x11_main.c
index 73c8c568..1e08368e 100644
--- a/apps/x11_main.c
+++ b/apps/x11_main.c
@@ -1,5 +1,6 @@
#include "fitz.h"
#include "mupdf.h"
+#include "muxps.h"
#include "pdfapp.h"
#include <X11/Xlib.h>
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h
index 28fa20c3..a9a2a2ea 100644
--- a/mupdf/mupdf.h
+++ b/mupdf/mupdf.h
@@ -515,8 +515,6 @@ struct pdf_page_s
int transparency;
fz_obj *resources;
fz_buffer *contents;
- fz_displaylist *list;
- fz_textspan *text;
pdf_link *links;
pdf_annot *annots;
};
diff --git a/mupdf/pdf_page.c b/mupdf/pdf_page.c
index e09cafb0..869f7a5c 100644
--- a/mupdf/pdf_page.c
+++ b/mupdf/pdf_page.c
@@ -168,8 +168,6 @@ pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
page->resources = nil;
page->contents = nil;
page->transparency = 0;
- page->list = nil;
- page->text = nil;
page->links = nil;
page->annots = nil;
@@ -240,10 +238,6 @@ pdf_freepage(pdf_page *page)
fz_dropobj(page->resources);
if (page->contents)
fz_dropbuffer(page->contents);
- if (page->list)
- fz_freedisplaylist(page->list);
- if (page->text)
- fz_freetextspan(page->text);
if (page->links)
pdf_freelink(page->links);
if (page->annots)
diff --git a/xps/muxps.h b/xps/muxps.h
index 51c0323e..d0478e7b 100644
--- a/xps/muxps.h
+++ b/xps/muxps.h
@@ -265,6 +265,7 @@ int xps_read_and_process_page_part(xps_context *ctx, fz_matrix ctm, char *name);
int xps_open_file(xps_context *ctx, char *filename);
int xps_count_pages(xps_context *ctx);
xps_page *xps_load_page(xps_context *ctx, int number);
+void xps_free_page(xps_context *ctx, xps_page *page);
xps_context *xps_new_context(void);
int xps_free_context(xps_context *ctx);
diff --git a/xps/xpszip.c b/xps/xpszip.c
index 0646b89f..4905ea37 100644
--- a/xps/xpszip.c
+++ b/xps/xpszip.c
@@ -484,6 +484,14 @@ xps_load_page(xps_context *ctx, int number)
return nil;
}
+void
+xps_free_page(xps_context *ctx, xps_page *page)
+{
+ if (page->root)
+ xps_free_item(ctx, page->root);
+ page->root = NULL;
+}
+
xps_context *
xps_new_context(void)
{