| 1 | /* maia (this was written by my daughter in emacs at 3 and an half :)) */ |
|---|
| 2 | |
|---|
| 3 | #include <cmath> |
|---|
| 4 | #include <pgm/pgm.h> |
|---|
| 5 | #include <poppler.h> |
|---|
| 6 | #include <gdk-pixbuf/gdk-pixbuf.h> |
|---|
| 7 | #include <libintl.h> |
|---|
| 8 | #define _(String) gettext(String) |
|---|
| 9 | |
|---|
| 10 | #include "page.hh" |
|---|
| 11 | #include "document.hh" |
|---|
| 12 | #include "slides_canvas.hh" |
|---|
| 13 | #include "slides_viewport.hh" |
|---|
| 14 | |
|---|
| 15 | /* |
|---|
| 16 | * An array of drawables |
|---|
| 17 | */ |
|---|
| 18 | PgmDrawable** drawable; |
|---|
| 19 | |
|---|
| 20 | static void |
|---|
| 21 | key_press_event_cb (PgmViewport *viewport, |
|---|
| 22 | PgmEventKey *event, |
|---|
| 23 | gpointer data) |
|---|
| 24 | { |
|---|
| 25 | gchar buffer[7]; |
|---|
| 26 | gint len; |
|---|
| 27 | guint32 unicode; |
|---|
| 28 | static double bias = 0.0; |
|---|
| 29 | |
|---|
| 30 | unicode = pgm_keyval_to_unicode (event->keyval); |
|---|
| 31 | len = g_unichar_to_utf8 (unicode, buffer); |
|---|
| 32 | buffer[len] = '\0'; |
|---|
| 33 | g_print ("keyval:0x%x ucs:%d char:'%s'\n", event->keyval, unicode, buffer); |
|---|
| 34 | |
|---|
| 35 | int slides = 31; |
|---|
| 36 | for(int i = 0; i < slides; i++) |
|---|
| 37 | { |
|---|
| 38 | int idx = -slides/2+i; |
|---|
| 39 | double speed = std::sqrt(std::sqrt(std::abs((double)idx))); |
|---|
| 40 | double position = bias; |
|---|
| 41 | if(idx < 0) |
|---|
| 42 | position = (-550.0f+bias)*speed; |
|---|
| 43 | else if (idx > 0) |
|---|
| 44 | position = (550.0f+bias)*speed; |
|---|
| 45 | bias += 1.0; |
|---|
| 46 | double distance = std::min(0.3+pow(27.0, position/1000.0-0.1), |
|---|
| 47 | 0.3+pow(27.0, -position/1000.0-0.1)); |
|---|
| 48 | pgm_drawable_set_position(drawable[i], |
|---|
| 49 | position, |
|---|
| 50 | 0.0f, |
|---|
| 51 | -((2.0-distance)*1200.0)); |
|---|
| 52 | pgm_drawable_set_bg_color(drawable[i], 255, 255, 0, 255); |
|---|
| 53 | pgm_drawable_set_opacity(drawable[i], 255); |
|---|
| 54 | double angle = 0.0f; |
|---|
| 55 | if(position < 0.0) |
|---|
| 56 | angle = M_PI/2 - 3.295836866*pow(27, position/100.0-0.1); |
|---|
| 57 | else if(position > 0.0) |
|---|
| 58 | angle = -M_PI/2 + 3.295836866*pow(27, -position/100.0-0.1); |
|---|
| 59 | |
|---|
| 60 | pgm_drawable_set_rotation_y(drawable[i], angle); |
|---|
| 61 | } |
|---|
| 62 | |
|---|
| 63 | |
|---|
| 64 | } |
|---|
| 65 | |
|---|
| 66 | /* |
|---|
| 67 | * GList enumerating function |
|---|
| 68 | */ |
|---|
| 69 | void link_function(gpointer data, gpointer user_data) |
|---|
| 70 | { |
|---|
| 71 | PopplerLinkMapping* link = (PopplerLinkMapping*)data; |
|---|
| 72 | g_print("Link area (%f,%f)x(%f,%f)\n", |
|---|
| 73 | link->area.x1, |
|---|
| 74 | link->area.y1, |
|---|
| 75 | link->area.x2, |
|---|
| 76 | link->area.y2); |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | /* |
|---|
| 80 | * Main program for the new bread PDFCube. Get rid of plain (and pain) |
|---|
| 81 | * OpenGL and let's use the great pigment library. |
|---|
| 82 | */ |
|---|
| 83 | int main(int argc, char* argv[]) |
|---|
| 84 | { |
|---|
| 85 | /* |
|---|
| 86 | * The viewport where the rendering actually takes place |
|---|
| 87 | */ |
|---|
| 88 | PgmViewport* viewport; |
|---|
| 89 | /* |
|---|
| 90 | * The canvas where the drawables are arranged |
|---|
| 91 | */ |
|---|
| 92 | PgmCanvas* canvas; |
|---|
| 93 | /* |
|---|
| 94 | * A buffer to render pdf pages |
|---|
| 95 | */ |
|---|
| 96 | GdkPixbuf* buffer = NULL; |
|---|
| 97 | /* |
|---|
| 98 | * A poppler page |
|---|
| 99 | */ |
|---|
| 100 | PopplerPage *page; |
|---|
| 101 | /* |
|---|
| 102 | * The poppler document |
|---|
| 103 | */ |
|---|
| 104 | PopplerDocument* document; |
|---|
| 105 | |
|---|
| 106 | int N; |
|---|
| 107 | |
|---|
| 108 | /* |
|---|
| 109 | * Initialize pigment |
|---|
| 110 | */ |
|---|
| 111 | pgm_init(&argc, &argv); |
|---|
| 112 | |
|---|
| 113 | pgm_viewport_factory_make("opengl", &viewport); |
|---|
| 114 | if(!viewport) |
|---|
| 115 | { |
|---|
| 116 | g_print(_("Cannot create the 'OpenGL' viewport\n")); |
|---|
| 117 | return -1; |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | /* |
|---|
| 121 | * Open the PDF document using poppler |
|---|
| 122 | */ |
|---|
| 123 | document = poppler_document_new_from_file(argv[1], NULL, NULL); |
|---|
| 124 | if(document == NULL) |
|---|
| 125 | { |
|---|
| 126 | g_print(_("PDF file %s cannot be opened, check it exists, permissions" |
|---|
| 127 | " and that is \nnot encrypted.\n"), argv[1]); |
|---|
| 128 | return -1; |
|---|
| 129 | } |
|---|
| 130 | N = poppler_document_get_n_pages(document); |
|---|
| 131 | g_print(_("Found a PDF document with %d pages.\n"), N); |
|---|
| 132 | |
|---|
| 133 | /* |
|---|
| 134 | * Initialize the viewport window and its size |
|---|
| 135 | */ |
|---|
| 136 | pgm_viewport_set_title(viewport, "PDFCube 0.1.0"); |
|---|
| 137 | pgm_viewport_set_size(viewport, 1024, 768); |
|---|
| 138 | |
|---|
| 139 | canvas = pgm_canvas_new(); |
|---|
| 140 | pgm_canvas_set_size(canvas, 640, 480); |
|---|
| 141 | |
|---|
| 142 | pgm_viewport_set_canvas(viewport, canvas); |
|---|
| 143 | |
|---|
| 144 | drawable = (PgmDrawable**)alloca(N * sizeof(PgmDrawable*)); |
|---|
| 145 | |
|---|
| 146 | char* transition_name[] = |
|---|
| 147 | { |
|---|
| 148 | "replace", |
|---|
| 149 | "split", |
|---|
| 150 | "blinds", |
|---|
| 151 | "box", |
|---|
| 152 | "wipe", |
|---|
| 153 | "dissolve", |
|---|
| 154 | "glitter", |
|---|
| 155 | "fly", |
|---|
| 156 | "push", |
|---|
| 157 | "cover", |
|---|
| 158 | "uncover", |
|---|
| 159 | "fade", |
|---|
| 160 | "unknown", |
|---|
| 161 | "unknown" |
|---|
| 162 | }; |
|---|
| 163 | int slides = N > 31 ? 31 : N; |
|---|
| 164 | for(int i = 0; i < slides; i++) |
|---|
| 165 | { |
|---|
| 166 | |
|---|
| 167 | PopplerPageTransition* transition; |
|---|
| 168 | GList* link; |
|---|
| 169 | page = poppler_document_get_page(document, i); |
|---|
| 170 | g_print("Page %d has duration %f\n", |
|---|
| 171 | i, |
|---|
| 172 | poppler_page_get_duration(page)); |
|---|
| 173 | transition = poppler_page_get_transition(page); |
|---|
| 174 | g_print("Page %d has transition %s\n", i, |
|---|
| 175 | transition_name[transition->type]); |
|---|
| 176 | link = poppler_page_get_link_mapping(page); |
|---|
| 177 | g_print("Page %d has %d links\n", i, g_list_length(link)); |
|---|
| 178 | g_list_foreach(link, link_function, NULL); |
|---|
| 179 | |
|---|
| 180 | double w, h; |
|---|
| 181 | poppler_page_get_size(page, &w, &h); |
|---|
| 182 | g_print("Page %d is %f by %f\n", i, w, h); |
|---|
| 183 | buffer = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, 320, 240); |
|---|
| 184 | poppler_page_render_to_pixbuf(page, |
|---|
| 185 | 0, |
|---|
| 186 | 0, |
|---|
| 187 | 320, |
|---|
| 188 | 240, |
|---|
| 189 | 240.0f/h, |
|---|
| 190 | 0, |
|---|
| 191 | buffer); |
|---|
| 192 | drawable[i] = pgm_image_new_from_pixbuf(buffer); |
|---|
| 193 | pgm_drawable_set_size(drawable[i], 640.0, 480.0); |
|---|
| 194 | int idx = -slides/2+i; |
|---|
| 195 | double speed = std::pow(std::abs((double)idx), 0.28); |
|---|
| 196 | double position = 0.0; |
|---|
| 197 | if(idx < 0) |
|---|
| 198 | position = -450.0f*speed; |
|---|
| 199 | else if (idx > 0) |
|---|
| 200 | position = 450.0f*speed; |
|---|
| 201 | // position += 0.001; |
|---|
| 202 | double distance = std::min(0.3+pow(27.0, position/1000-0.1), |
|---|
| 203 | 0.3+pow(27.0, -position/1000-0.1)); |
|---|
| 204 | pgm_drawable_set_position(drawable[i], |
|---|
| 205 | position, |
|---|
| 206 | 0.0f, |
|---|
| 207 | -((2.0-distance)*1200.0)); |
|---|
| 208 | pgm_drawable_set_bg_color(drawable[i], 255, 255, 0, 255); |
|---|
| 209 | pgm_drawable_set_opacity(drawable[i], 255); |
|---|
| 210 | double angle = 0.0f; |
|---|
| 211 | if(position < 0.0) |
|---|
| 212 | angle = M_PI/2 - 3.295836866*pow(27, position/1000-0.1); |
|---|
| 213 | else if(position > 0.0) |
|---|
| 214 | angle = -M_PI/2 + 3.295836866*pow(27, -position/1000-0.1); |
|---|
| 215 | |
|---|
| 216 | pgm_drawable_set_rotation_y(drawable[i], angle); |
|---|
| 217 | pgm_drawable_show(drawable[i]); |
|---|
| 218 | pgm_canvas_add(canvas, PGM_DRAWABLE_MIDDLE, drawable[i]); |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | |
|---|
| 222 | pgm_viewport_show(viewport); |
|---|
| 223 | |
|---|
| 224 | // g_signal_connect (G_OBJECT(viewport), "key-press-event", |
|---|
| 225 | // G_CALLBACK(key_press_event_cb), NULL); |
|---|
| 226 | g_signal_connect (G_OBJECT (viewport), "delete-event", |
|---|
| 227 | G_CALLBACK (pgm_main_quit), NULL); |
|---|
| 228 | pgm_main(); |
|---|
| 229 | |
|---|
| 230 | g_object_unref(buffer); |
|---|
| 231 | gst_object_unref(canvas); |
|---|
| 232 | gst_object_unref(viewport); |
|---|
| 233 | |
|---|
| 234 | pgm_deinit(); |
|---|
| 235 | |
|---|
| 236 | return 0; |
|---|
| 237 | } |
|---|