7 #include <cairo/cairo.h>
8 #include <glib/poppler.h>
12 #define CTRLKEY(x) ((x) - 96)
15 static PopplerDocument
*doc
;
16 static PopplerPage
*page
;
18 static cairo_t
*cairo
;
19 static cairo_surface_t
*surface
;
27 unsigned char *img
= cairo_image_surface_get_data(surface
);
28 fbval_t slice
[1 << 14];
30 int h
= MIN(fb_rows(), cairo_image_surface_get_height(surface
));
31 int w
= MIN(fb_cols(), cairo_image_surface_get_width(surface
));
32 int cols
= cairo_image_surface_get_width(surface
);
33 for (i
= head
; i
< h
+ head
; i
++) {
34 for (j
= left
; j
< w
+ left
; j
++) {
35 unsigned char *p
= img
+ (i
* cols
+ j
) * 4;
36 slice
[j
- left
] = fb_color(*p
, *(p
+ 1), *(p
+ 2));
38 fb_set(i
- head
, 0, slice
, w
);
42 static int load_document(char *filename
)
44 char abspath
[PATH_MAX
];
45 char uri
[PATH_MAX
+ 16];
46 realpath(filename
, abspath
);
47 snprintf(uri
, sizeof(uri
), "file://%s", abspath
);
48 doc
= poppler_document_new_from_file(uri
, NULL
, NULL
);
52 static void cleanup_page(void)
57 cairo_surface_destroy(surface
);
59 g_object_unref(G_OBJECT(page
));
62 static void showpage(int p
)
64 if (p
< 0 || p
>= poppler_document_get_n_pages(doc
))
67 surface
= cairo_image_surface_create(CAIRO_FORMAT_ARGB32
,
68 fb_cols() * MAXAREA
, fb_rows() * MAXAREA
);
69 cairo
= cairo_create(surface
);
70 cairo_scale(cairo
, (float) zoom
/ 10, (float) zoom
/ 10);
71 cairo_set_source_rgb(cairo
, 1.0, 1.0, 1.0);
74 page
= poppler_document_get_page(doc
, p
);
75 poppler_page_render(page
, cairo
);
80 static int readkey(void)
83 if (read(STDIN_FILENO
, &b
, 1) <= 0)
88 static int getcount(int def
)
90 int result
= count
? count
: def
;
95 static void mainloop()
97 int step
= fb_rows() / PAGESTEPS
;
98 int hstep
= fb_cols() / PAGESTEPS
;
99 struct termios oldtermios
, termios
;
100 int maxhead
, maxleft
;
102 tcgetattr(STDIN_FILENO
, &termios
);
103 oldtermios
= termios
;
105 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &termios
);
107 while ((c
= readkey()) != -1) {
108 maxhead
= cairo_image_surface_get_height(surface
) - fb_rows();
109 maxleft
= cairo_image_surface_get_width(surface
) - fb_cols();
112 head
+= step
* getcount(1);
115 head
-= step
* getcount(1);
118 left
+= hstep
* getcount(1);
121 left
-= hstep
* getcount(1);
133 head
+= fb_rows() * getcount(1) - step
;
136 head
-= fb_rows() * getcount(1) - step
;
140 showpage(num
+ getcount(1));
144 showpage(num
- getcount(1));
147 showpage(getcount(poppler_document_get_n_pages(doc
)) - 1);
154 tcsetattr(STDIN_FILENO
, 0, &oldtermios
);
161 count
= count
* 10 + c
- '0';
163 head
= MAX(0, MIN(maxhead
, head
));
164 left
= MAX(0, MIN(maxleft
, left
));
169 int main(int argc
, char* argv
[])
171 char *clear
= "\x1b[2J\x1b[H";
172 char *msg
= "\t\t\t\t---FBPDF---\n";
173 char *hide
= "\x1b[?25l";
174 char *show
= "\x1b[?25h";
176 printf("usage: fbpdf filename\n");
180 if (load_document(argv
[1])) {
181 printf("cannot open file\n");
184 write(STDIN_FILENO
, clear
, strlen(clear
));
185 write(STDIN_FILENO
, msg
, strlen(msg
));
186 write(STDIN_FILENO
, hide
, strlen(hide
));
192 g_object_unref(G_OBJECT(doc
));
193 write(STDIN_FILENO
, show
, strlen(show
));