From 5e81ff34ecbf364b091aedc0c4044d2aafde6531 Mon Sep 17 00:00:00 2001 From: Sebastian Rasmussen Date: Sun, 7 Aug 2016 14:17:35 +0800 Subject: Handle too big pixmap by printing error message in X11 viewer. --- platform/x11/pdfapp.c | 64 +++++++++++++++++------- platform/x11/x11_main.c | 128 +++++++++++++++++++++++++++--------------------- 2 files changed, 117 insertions(+), 75 deletions(-) (limited to 'platform/x11') diff --git a/platform/x11/pdfapp.c b/platform/x11/pdfapp.c index 23603210..e4b0c13f 100644 --- a/platform/x11/pdfapp.c +++ b/platform/x11/pdfapp.c @@ -597,8 +597,14 @@ static void pdfapp_viewctm(fz_matrix *mat, 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); + int image_w = 0; + int image_h = 0; + + if (app->image) + { + image_w = fz_pixmap_width(app->ctx, app->image); + image_h = fz_pixmap_height(app->ctx, app->image); + } if (newx > 0) newx = 0; @@ -896,20 +902,30 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai colorspace = fz_device_gray(app->ctx); else colorspace = app->colorspace; + app->image = NULL; - app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, 1); - fz_clear_pixmap_with_value(app->ctx, app->image, 255); - if (app->page_list || app->annotations_list) + fz_var(app->image); + + fz_try(app->ctx) + { + app->image = fz_new_pixmap_with_bbox(app->ctx, colorspace, &ibounds, 1); + fz_clear_pixmap_with_value(app->ctx, app->image, 255); + if (app->page_list || app->annotations_list) + { + idev = fz_new_draw_device(app->ctx, NULL, app->image); + pdfapp_runpage(app, idev, &ctm, &bounds, &cookie); + fz_close_device(app->ctx, idev); + fz_drop_device(app->ctx, idev); + } + if (app->invert) + fz_invert_pixmap(app->ctx, app->image); + if (app->tint) + fz_tint_pixmap(app->ctx, app->image, app->tint_r, app->tint_g, app->tint_b); + } + fz_catch(app->ctx) { - idev = fz_new_draw_device(app->ctx, NULL, app->image); - pdfapp_runpage(app, idev, &ctm, &bounds, &cookie); - fz_close_device(app->ctx, idev); - fz_drop_device(app->ctx, idev); + cookie.errors++; } - if (app->invert) - fz_invert_pixmap(app->ctx, app->image); - if (app->tint) - fz_tint_pixmap(app->ctx, app->image, app->tint_r, app->tint_g, app->tint_b); } if (transition) @@ -938,10 +954,16 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai { pdfapp_panview(app, app->panx, app->pany); - if (app->shrinkwrap) + if (!app->image) + { + /* there is no image to blit, but there might be an error message */ + winresize(app, app->layout_w, app->layout_h); + } + else if (app->shrinkwrap) { 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) @@ -1575,13 +1597,14 @@ static void handlescroll(pdfapp_t *app, int modifiers, int dir) void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int state) { fz_context *ctx = app->ctx; - fz_irect irect; + fz_irect irect = { 0, 0, app->layout_w, app->layout_h }; fz_link *link; fz_matrix ctm; fz_point p; int processed = 0; - fz_pixmap_bbox(app->ctx, app->image, &irect); + if (app->image) + fz_pixmap_bbox(app->ctx, app->image, &irect); p.x = x - app->panx + irect.x0; p.y = y - app->pany + irect.y0; @@ -1797,9 +1820,13 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta { int newx = app->panx + x - app->selx; int newy = app->pany + y - app->sely; + int imgh = app->winh; + if (app->image) + imgh = fz_pixmap_height(app->ctx, app->image); + /* Scrolling beyond limits implies flipping pages */ /* Are we requested to scroll beyond limits? */ - if (newy + fz_pixmap_height(app->ctx, app->image) < app->winh || newy > 0) + if (newy + imgh < app->winh || newy > 0) { /* Yes. We can assume that deltay != 0 */ int deltay = y - app->sely; @@ -1821,7 +1848,8 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta { app->pageno--; pdfapp_showpage(app, 1, 1, 1, 0, 0); - newy = -fz_pixmap_height(app->ctx, app->image); + if (app->image) + newy = -fz_pixmap_height(app->ctx, app->image); } app->beyondy = 0; } diff --git a/platform/x11/x11_main.c b/platform/x11/x11_main.c index 21e3e848..c061dc8b 100644 --- a/platform/x11/x11_main.c +++ b/platform/x11/x11_main.c @@ -388,11 +388,17 @@ 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); + int image_w = gapp.layout_w; + int image_h = gapp.layout_h; XWindowChanges values; int mask, width, height; + if (gapp.image) + { + image_w = fz_pixmap_width(gapp.ctx, gapp.image); + image_h = fz_pixmap_height(gapp.ctx, gapp.image); + } + mask = CWWidth | CWHeight; values.width = w; values.height = h; @@ -487,72 +493,80 @@ static void winblitstatusbar(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 + image_w; - int y1 = gapp.pany + image_h; - - XSetForeground(xdpy, xgc, xbgcolor.pixel); - fillrect(0, 0, x0, gapp.winh); - fillrect(x1, 0, gapp.winw - x1, gapp.winh); - fillrect(0, 0, gapp.winw, y0); - fillrect(0, y1, gapp.winw, gapp.winh - y1); - - XSetForeground(xdpy, xgc, xshcolor.pixel); - fillrect(x0+2, y1, image_w, 2); - fillrect(x1, y0+2, 2, image_h); - - if (gapp.iscopying || justcopied) - { - pdfapp_invert(&gapp, &gapp.selr); - justcopied = 1; - } - - pdfapp_inverthit(&gapp); - - if (image_n == 4) - ximage_blit(xwin, xgc, - x0, y0, - image_samples, - 0, 0, - image_w, - image_h, - image_w * image_n); - else if (image_n == 2) + if (gapp.image) { - int i = image_w*image_h; - unsigned char *color = malloc(i*4); - if (color) + 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 + image_w; + int y1 = gapp.pany + image_h; + + XSetForeground(xdpy, xgc, xbgcolor.pixel); + fillrect(0, 0, x0, gapp.winh); + fillrect(x1, 0, gapp.winw - x1, gapp.winh); + fillrect(0, 0, gapp.winw, y0); + fillrect(0, y1, gapp.winw, gapp.winh - y1); + + XSetForeground(xdpy, xgc, xshcolor.pixel); + fillrect(x0+2, y1, image_w, 2); + fillrect(x1, y0+2, 2, image_h); + + if (gapp.iscopying || justcopied) { - unsigned char *s = image_samples; - unsigned char *d = color; - for (; i > 0 ; i--) - { - d[2] = d[1] = d[0] = *s++; - d[3] = *s++; - d += 4; - } + pdfapp_invert(&gapp, &gapp.selr); + justcopied = 1; + } + + pdfapp_inverthit(&gapp); + + if (image_n == 4) ximage_blit(xwin, xgc, x0, y0, - color, + image_samples, 0, 0, image_w, image_h, - image_w * 4); - free(color); + image_w * image_n); + else if (image_n == 2) + { + int i = image_w*image_h; + unsigned char *color = malloc(i*4); + if (color) + { + unsigned char *s = image_samples; + unsigned char *d = color; + for (; i > 0 ; i--) + { + d[2] = d[1] = d[0] = *s++; + d[3] = *s++; + d += 4; + } + ximage_blit(xwin, xgc, + x0, y0, + color, + 0, 0, + image_w, + image_h, + image_w * 4); + free(color); + } } - } - pdfapp_inverthit(&gapp); + pdfapp_inverthit(&gapp); - if (gapp.iscopying || justcopied) + if (gapp.iscopying || justcopied) + { + pdfapp_invert(&gapp, &gapp.selr); + justcopied = 1; + } + } + else { - pdfapp_invert(&gapp, &gapp.selr); - justcopied = 1; + XSetForeground(xdpy, xgc, xbgcolor.pixel); + fillrect(0, 0, gapp.winw, gapp.winh); } winblitstatusbar(app); -- cgit v1.2.3