2 * fbpdf - a small framebuffer pdf viewer using mupdf
4 * Copyright (C) 2009-2010 Ali Gholami Rudi
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License, as published by the
8 * Free Software Foundation.
22 #define CTRLKEY(x) ((x) - 96)
25 #define PDFCOLS (1 << 11)
26 #define PDFROWS (1 << 12)
28 static fbval_t pbuf
[PDFROWS
* PDFCOLS
];
31 static struct termios termios
;
32 static char filename
[256];
38 static fz_glyphcache
*glyphcache
;
39 static pdf_xref
*xref
;
42 static void draw(void)
45 for (i
= head
; i
< MIN(head
+ fb_rows(), PDFROWS
); i
++)
46 fb_set(i
- head
, 0, pbuf
+ i
* PDFCOLS
+ left
, fb_cols());
49 static int showpage(int p
)
59 if (p
< 1 || p
> pagecount
)
62 memset(pbuf
, 0x00, sizeof(pbuf
));
64 pageobj
= pdf_getpageobject(xref
, p
);
65 if (pdf_loadpage(&page
, xref
, pageobj
))
67 list
= fz_newdisplaylist();
68 dev
= fz_newlistdevice(list
);
69 if (pdf_runpage(xref
, page
, dev
, fz_identity
))
73 ctm
= fz_translate(0, -page
->mediabox
.y1
);
74 ctm
= fz_concat(ctm
, fz_scale((float) zoom
/ 10, (float) -zoom
/ 10));
75 bbox
= fz_roundrect(fz_transformrect(ctm
, page
->mediabox
));
76 w
= bbox
.x1
- bbox
.x0
;
77 h
= bbox
.y1
- bbox
.y0
;
79 pix
= fz_newpixmapwithrect(fz_devicergb
, bbox
);
80 fz_clearpixmap(pix
, 0xff);
82 dev
= fz_newdrawdevice(glyphcache
, pix
);
83 fz_executedisplaylist(list
, dev
, ctm
);
86 for (y
= 0; y
< MIN(pix
->h
, PDFROWS
); y
++) {
87 for (x
= 0; x
< MIN(pix
->w
, PDFCOLS
); x
++) {
88 unsigned char *s
= pix
->samples
+ y
* pix
->w
* 4 + x
* 4;
89 pbuf
[y
* PDFCOLS
+ x
] = fb_color(s
[0], s
[1], s
[2]);
94 fz_freedisplaylist(list
);
96 pdf_agestore(xref
->store
, 3);
103 static int readkey(void)
106 if (read(STDIN_FILENO
, &b
, 1) <= 0)
111 static int getcount(int def
)
113 int result
= count
? count
: def
;
118 static void printinfo(void)
121 printf("FBPDF: file:%s page:%d(%d) zoom:%d%% \x1b[K",
122 filename
, num
, pagecount
, zoom
* 10);
126 static void term_setup(void)
128 struct termios newtermios
;
129 tcgetattr(STDIN_FILENO
, &termios
);
130 newtermios
= termios
;
131 newtermios
.c_lflag
&= ~ICANON
;
132 newtermios
.c_lflag
&= ~ECHO
;
133 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &newtermios
);
136 static void term_cleanup(void)
138 tcsetattr(STDIN_FILENO
, 0, &termios
);
141 static void sigcont(int sig
)
146 static void mainloop()
148 int step
= fb_rows() / PAGESTEPS
;
149 int hstep
= fb_cols() / PAGESTEPS
;
152 signal(SIGCONT
, sigcont
);
154 while ((c
= readkey()) != -1) {
155 int maxhead
= PDFROWS
- fb_rows();
156 int maxleft
= PDFCOLS
- fb_cols();
160 showpage(num
+ getcount(1));
164 showpage(num
- getcount(1));
167 showpage(getcount(pagecount
));
184 count
= count
* 10 + c
- '0';
188 head
+= step
* getcount(1);
191 head
-= step
* getcount(1);
194 left
+= hstep
* getcount(1);
197 left
-= hstep
* getcount(1);
210 head
+= fb_rows() * getcount(1) - step
;
214 head
-= fb_rows() * getcount(1) - step
;
219 /* no need to redraw */
222 head
= MAX(0, MIN(maxhead
, head
));
223 left
= MAX(0, MIN(maxleft
, left
));
228 int main(int argc
, char *argv
[])
230 char *hide
= "\x1b[?25l";
231 char *show
= "\x1b[?25h";
232 char *clear
= "\x1b[2J";
234 printf("usage: fbpdf filename\n");
237 strcpy(filename
, argv
[1]);
239 glyphcache
= fz_newglyphcache();
240 if (pdf_openxref(&xref
, filename
, NULL
)) {
241 printf("cannot open file\n");
244 if (pdf_loadpagetree(xref
))
246 pagecount
= pdf_getpagecount(xref
);
248 write(STDIN_FILENO
, hide
, strlen(hide
));
249 write(STDOUT_FILENO
, clear
, strlen(clear
));
254 write(STDIN_FILENO
, show
, strlen(show
));
258 fz_freeglyphcache(glyphcache
);