fbpdf: retain vertical position after zooming
[fbpdf.git] / mupdf.c
blob9c61bd2ddc86f14078e7751f62ea79e13b64312a
1 #include <stdlib.h>
2 #include <string.h>
3 #include "fitz.h"
4 #include "draw.h"
5 #include "doc.h"
7 struct doc {
8 fz_context *ctx;
9 fz_document *pdf;
12 int doc_draw(struct doc *doc, fbval_t *bitmap, int p, int rows, int cols, int zoom, int rotate)
14 fz_matrix ctm;
15 fz_bbox bbox;
16 fz_pixmap *pix;
17 fz_device *dev;
18 fz_page *page;
19 fz_rect rect;
20 int h, w;
21 int x, y;
23 if (!(page = fz_load_page(doc->pdf, p - 1)))
24 return 1;
25 ctm = fz_scale((float) zoom / 10, (float) -zoom / 10);
26 ctm = fz_concat(ctm, fz_translate(0, -100));
27 if (rotate)
28 ctm = fz_concat(ctm, fz_rotate(rotate));
29 rect = fz_bound_page(doc->pdf, page);
30 rect = fz_transform_rect(ctm, rect);
31 bbox = fz_round_rect(rect);
32 w = MIN(cols, rect.x1 - rect.x0);
33 h = MIN(rows, rect.y1 - rect.y0);
35 pix = fz_new_pixmap_with_bbox(doc->ctx, fz_device_rgb, bbox);
36 fz_clear_pixmap_with_value(doc->ctx, pix, 0xff);
38 dev = fz_new_draw_device(doc->ctx, pix);
39 fz_run_page(doc->pdf, page, dev, fz_identity, NULL);
40 fz_run_page(doc->pdf, page, dev, ctm, NULL);
41 fz_free_device(dev);
43 for (y = 0; y < h; y++) {
44 int xs = (h - y - 1) * cols + (cols - w) / 2;
45 for (x = 0; x < w; x++) {
46 unsigned char *s = fz_pixmap_samples(doc->ctx, pix) +
47 y * fz_pixmap_width(doc->ctx, pix) * 4 + x * 4;
48 bitmap[xs + x] = FB_VAL(s[0], s[1], s[2]);
52 fz_drop_pixmap(doc->ctx, pix);
53 fz_free_page(doc->pdf, page);
54 return 0;
57 int doc_pages(struct doc *doc)
59 return fz_count_pages(doc->pdf);
62 struct doc *doc_open(char *path)
64 struct doc *doc = malloc(sizeof(*doc));
65 doc->ctx = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
66 doc->pdf = fz_open_document(doc->ctx, path);
67 if (!doc->pdf) {
68 free(doc);
69 return NULL;
71 return doc;
74 void doc_close(struct doc *doc)
76 fz_close_document(doc->pdf);
77 fz_free_context(doc->ctx);
78 free(doc);