7 #include <cairo/cairo.h>
8 #include <glib/poppler.h>
12 #define CTRLKEY(x) ((x) - 96)
16 static PopplerDocument
*doc
;
17 static PopplerPage
*page
;
19 static cairo_t
*cairo
;
20 static cairo_surface_t
*surface
;
21 static char filename
[PATH_MAX
];
29 unsigned char *img
= cairo_image_surface_get_data(surface
);
30 fbval_t slice
[1 << 14];
32 int h
= MIN(fb_rows(), cairo_image_surface_get_height(surface
));
33 int w
= MIN(fb_cols(), cairo_image_surface_get_width(surface
));
34 int cols
= cairo_image_surface_get_width(surface
);
35 for (i
= head
; i
< h
+ head
; i
++) {
36 for (j
= left
; j
< w
+ left
; j
++) {
37 unsigned char *p
= img
+ (i
* cols
+ j
) * 4;
38 slice
[j
- left
] = fb_color(*p
, *(p
+ 1), *(p
+ 2));
40 fb_set(i
- head
, 0, slice
, w
);
44 static int load_document(void)
46 char abspath
[PATH_MAX
];
47 char uri
[PATH_MAX
+ 16];
48 realpath(filename
, abspath
);
49 snprintf(uri
, sizeof(uri
), "file://%s", abspath
);
50 doc
= poppler_document_new_from_file(uri
, NULL
, NULL
);
54 static void cleanup_page(void)
59 cairo_surface_destroy(surface
);
61 g_object_unref(G_OBJECT(page
));
64 static void showpage(int p
)
66 if (p
< 0 || p
>= poppler_document_get_n_pages(doc
))
69 surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
,
70 fb_cols() * MAXWIDTH
, fb_rows() * MAXHEIGHT
);
71 cairo
= cairo_create(surface
);
72 cairo_scale(cairo
, (float) zoom
/ 10, (float) zoom
/ 10);
73 cairo_set_source_rgb(cairo
, 1.0, 1.0, 1.0);
76 page
= poppler_document_get_page(doc
, p
);
77 poppler_page_render(page
, cairo
);
82 static int readkey(void)
85 if (read(STDIN_FILENO
, &b
, 1) <= 0)
90 static int getcount(int def
)
92 int result
= count
? count
: def
;
97 static void printinfo(void)
100 printf("FBPDF: file:%s page:%d(%d) zoom:%d%% \x1b[K",
101 filename
, num
+ 1, poppler_document_get_n_pages(doc
), zoom
* 10);
105 static void mainloop()
107 int step
= fb_rows() / PAGESTEPS
;
108 int hstep
= fb_cols() / PAGESTEPS
;
109 struct termios oldtermios
, termios
;
111 tcgetattr(STDIN_FILENO
, &termios
);
112 oldtermios
= termios
;
114 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &termios
);
116 while ((c
= readkey()) != -1) {
117 int maxhead
= cairo_image_surface_get_height(surface
) - fb_rows();
118 int maxleft
= cairo_image_surface_get_width(surface
) - fb_cols();
122 showpage(num
+ getcount(1));
126 showpage(num
- getcount(1));
129 showpage(getcount(poppler_document_get_n_pages(doc
)) - 1);
139 tcsetattr(STDIN_FILENO
, 0, &oldtermios
);
146 count
= count
* 10 + c
- '0';
150 head
+= step
* getcount(1);
153 head
-= step
* getcount(1);
156 left
+= hstep
* getcount(1);
159 left
-= hstep
* getcount(1);
171 head
+= fb_rows() * getcount(1) - step
;
174 head
-= fb_rows() * getcount(1) - step
;
179 /* no need to redraw */
182 head
= MAX(0, MIN(maxhead
, head
));
183 left
= MAX(0, MIN(maxleft
, left
));
188 int main(int argc
, char* argv
[])
190 char *hide
= "\x1b[?25l";
191 char *show
= "\x1b[?25h";
192 char *clear
= "\x1b[2J";
194 printf("usage: fbpdf filename\n");
198 strcpy(filename
, argv
[1]);
199 if (load_document()) {
200 printf("cannot open file\n");
203 write(STDIN_FILENO
, hide
, strlen(hide
));
204 write(STDOUT_FILENO
, clear
, strlen(clear
));
211 g_object_unref(G_OBJECT(doc
));
212 write(STDIN_FILENO
, show
, strlen(show
));