diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | apps/pdfapp.c | 176 | ||||
-rw-r--r-- | apps/pdfapp.h | 8 | ||||
-rw-r--r-- | apps/x11_main.c | 1 | ||||
-rw-r--r-- | mupdf/mupdf.h | 2 | ||||
-rw-r--r-- | mupdf/pdf_page.c | 6 | ||||
-rw-r--r-- | xps/muxps.h | 1 | ||||
-rw-r--r-- | xps/xpszip.c | 8 |
8 files changed, 147 insertions, 63 deletions
@@ -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) { |