a6725e14e97dd365e9ae08bd6de5adbf7395780c
2 * fbpdf - a small framebuffer pdf viewer using mupdf
4 * Copyright (C) 2009-2013 Ali Gholami Rudi <ali at rudi dot ir>
6 * This program is released under the Modified BSD license.
18 #define MIN(a, b) ((a) < (b) ? (a) : (b))
19 #define MAX(a, b) ((a) > (b) ? (a) : (b))
22 #define CTRLKEY(x) ((x) - 96)
25 #define PDFCOLS (1 << 11)
26 #define PDFROWS (1 << 12)
28 static struct doc
*doc
;
29 static fbval_t pbuf
[PDFROWS
* PDFCOLS
]; /* current page */
30 static int prows
, pcols
; /* the dimensions of current page */
33 static struct termios termios
;
34 static char filename
[256];
35 static int mark
[128]; /* mark page number */
36 static int mark_head
[128]; /* mark head position */
43 static void draw(void)
46 for (i
= head
; i
< MIN(head
+ fb_rows(), PDFROWS
); i
++)
47 fb_set(i
- head
, 0, pbuf
+ i
* PDFCOLS
+ left
, fb_cols());
50 static int showpage(int p
, int h
)
52 if (p
< 1 || p
> doc_pages(doc
))
54 memset(pbuf
, 0x00, sizeof(pbuf
));
57 doc_draw(doc
, p
, zoom
, rotate
, pbuf
, &prows
, &pcols
);
64 static void zoom_page(int z
)
68 showpage(num
, MIN(PDFROWS
- fb_rows(), head
* zoom
/ _zoom
));
71 static int readkey(void)
74 if (read(STDIN_FILENO
, &b
, 1) <= 0)
79 static int getcount(int def
)
81 int result
= count
? count
: def
;
86 static void printinfo(void)
89 printf("FBPDF: file:%s page:%d(%d) zoom:%d%% \x1b[K",
90 filename
, num
, doc_pages(doc
), zoom
* 10);
94 static void term_setup(void)
96 struct termios newtermios
;
97 tcgetattr(STDIN_FILENO
, &termios
);
99 newtermios
.c_lflag
&= ~ICANON
;
100 newtermios
.c_lflag
&= ~ECHO
;
101 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &newtermios
);
104 static void term_cleanup(void)
106 tcsetattr(STDIN_FILENO
, 0, &termios
);
109 static void sigcont(int sig
)
114 static void reload(void)
117 doc
= doc_open(filename
);
121 static int rightmost(void)
125 for (i
= 0; i
< prows
; i
++) {
127 while (j
> ret
&& pbuf
[i
* PDFCOLS
+ j
] == FB_VAL(0, 0, 0))
129 while (j
> ret
&& pbuf
[i
* PDFCOLS
+ j
] == FB_VAL(255, 255, 255))
137 static int leftmost(void)
141 for (i
= 0; i
< prows
; i
++) {
143 while (j
< ret
&& pbuf
[i
* PDFCOLS
+ j
] == FB_VAL(0, 0, 0))
145 while (j
< ret
&& pbuf
[i
* PDFCOLS
+ j
] == FB_VAL(255, 255, 255))
153 static void mainloop(void)
155 int step
= fb_rows() / PAGESTEPS
;
156 int hstep
= fb_cols() / PAGESTEPS
;
159 signal(SIGCONT
, sigcont
);
161 while ((c
= readkey()) != -1) {
165 showpage(num
+ getcount(1), 0);
169 showpage(num
- getcount(1), 0);
172 showpage(getcount(doc_pages(doc
)), 0);
175 zoom_page(getcount(15));
178 zoom_page(zoom
* fb_cols() / pcols
);
181 zoom_page(zoom
* fb_rows() / prows
);
184 rotate
= getcount(0);
200 mark_head
[c2
] = head
/ zoom
;
209 if (isalpha(c2
) && mark
[c2
])
210 showpage(mark
[c2
], c
== '`' ? mark_head
[c2
] * zoom
: 0);
214 count
= count
* 10 + c
- '0';
218 head
+= step
* getcount(1);
221 head
-= step
* getcount(1);
224 left
+= hstep
* getcount(1);
227 left
-= hstep
* getcount(1);
233 head
= MAX(0, prows
- fb_rows());
240 head
+= fb_rows() * getcount(1) - step
;
244 head
-= fb_rows() * getcount(1) - step
;
247 left
= leftmost() - hstep
/ 2;
250 left
= rightmost() + hstep
/ 2 - fb_cols();
255 /* no need to redraw */
258 head
= MAX(0, MIN(PDFROWS
- fb_rows(), head
));
259 left
= MAX(0, MIN(PDFCOLS
- fb_cols(), left
));
265 "usage: fbpdf [-r rotation] [-z zoom x10] [-p page] filename\n";
267 int main(int argc
, char *argv
[])
269 char *hide
= "\x1b[?25l";
270 char *show
= "\x1b[?25h";
271 char *clear
= "\x1b[2J";
277 strcpy(filename
, argv
[argc
- 1]);
278 doc
= doc_open(filename
);
280 fprintf(stderr
, "cannot open <%s>\n", filename
);
283 while (i
+ 2 < argc
&& argv
[i
][0] == '-') {
284 if (argv
[i
][1] == 'r')
285 rotate
= atoi(argv
[i
+ 1]);
286 if (argv
[i
][1] == 'z')
287 zoom
= atoi(argv
[i
+ 1]);
288 if (argv
[i
][1] == 'p')
289 num
= atoi(argv
[i
+ 1]);
293 write(STDIN_FILENO
, hide
, strlen(hide
));
294 write(STDOUT_FILENO
, clear
, strlen(clear
));
298 left
= (PDFCOLS
- fb_cols()) / 2;
299 if (FBM_BPP(fb_mode()) != sizeof(fbval_t
))
300 fprintf(stderr
, "fbpdf: fbval_t doesn't match fb depth\n");
304 write(STDIN_FILENO
, show
, strlen(show
));