summaryrefslogtreecommitdiff
path: root/apps
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 /apps
parentd2250034a7e629455b9bfbf735473ea39638a701 (diff)
downloadmupdf-a6de4b76903f590c776c112e02e2f2ce0a363010.tar.xz
apps: Add XPS support to mupdf viewer.
Diffstat (limited to 'apps')
-rw-r--r--apps/pdfapp.c176
-rw-r--r--apps/pdfapp.h8
-rw-r--r--apps/x11_main.c1
3 files changed, 134 insertions, 51 deletions
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>