static gboolean idleFillCaches(gpointer dummy) { /* Unused parameters. */ (void)dummy; /* do prerendering of next slides. this will only happen when * there's nothing else to do. */ struct viewport *pp = NULL; GList *it = ports; int mypage_i = -1; while (it) { pp = (struct viewport *)(it->data); mypage_i = pagenumForPort(pp); /* Trigger some prerendering. The pointers are irrelevant for * now -- we just want the cache to be filled with all * previous and next slides. getRenderedPixbuf() will simply * return NULL for invalid page numbers. */ getRenderedPixbuf(pp, mypage_i + 1); getRenderedPixbuf(pp, mypage_i - 1); it = g_list_next(it); } /* save state. */ preQueued = FALSE; /* do not call me again. */ return FALSE; }
static void updatePortPixbuf(struct viewport *pp) { int mypage_i; /* no valid target size? */ if (pp->width <= 0 || pp->height <= 0) return; /* decide which page to render - if any */ mypage_i = pagenumForPort(pp); if (mypage_i < 0 || mypage_i >= doc_n_pages) { /* This port does not show anything right now, so clear its * content and quit. */ gtk_image_clear(GTK_IMAGE(pp->image)); return; } /* if note-control is active, print current page number if on * "main" frame. (don't do this on the beamer because it could be * locked.) * this allows you to attach any kind of other program or script * which can show notes for a specific slide. simply pipe the * output of pdfpres to your other tool. */ if (pp->offset == 0 && !pp->isBeamer) { printNote(doc_page + 1); if (runpref.do_notectrl) { printf("%d\n", doc_page + 1); fflush(stdout); } } /* get a pixbuf for this viewport. caching is behind * getRenderedPixbuf(). */ pp->pixbuf = getRenderedPixbuf(pp, mypage_i); /* display the current page. */ if (pp->pixbuf != NULL) gtk_image_set_from_pixbuf(GTK_IMAGE(pp->image), pp->pixbuf); else fprintf(stderr, "[Cache] Returned empty pixbuf." " You're doing something wrong.\n"); }
static void refreshFrames(void) { struct viewport *pp = NULL; GList *it = ports; int mypage_i; gchar *title = NULL; while (it) { pp = (struct viewport *)(it->data); /* the beamer has no frame */ if (pp->isBeamer == FALSE) { /* reset background color */ gtk_widget_modify_bg(pp->frame->parent, GTK_STATE_NORMAL, NULL); /* lock mode: highlight the saved/current page */ if (beamer_active == FALSE) { if (doc_page + pp->offset == doc_page_mark) { gtk_widget_modify_bg(pp->frame->parent, GTK_STATE_NORMAL, &col_marked); } else if (pp->offset == 0) { gtk_widget_modify_bg(pp->frame->parent, GTK_STATE_NORMAL, &col_dim); } } /* normal mode: highlight the "current" frame */ else { if (pp->offset == 0) { gtk_widget_modify_bg(pp->frame->parent, GTK_STATE_NORMAL, &col_current); } } /* Refresh labels. */ if (pp->frame != NULL) { mypage_i = pagenumForPort(pp); if (mypage_i < 0 || mypage_i >= doc_n_pages) { gtk_frame_set_label(GTK_FRAME(pp->frame), "X"); } else { title = g_strdup_printf("Slide %d / %d", mypage_i + 1, doc_n_pages); gtk_frame_set_label(GTK_FRAME(pp->frame), title); g_free(title); } } } it = g_list_next(it); } }
static gboolean onCanvasDraw(GtkWidget *widget, cairo_t *cr, struct viewport *pp) { (void)widget; int mypage_i, myfitmode = -1; gdouble w = 0, h = 0; gchar *title = NULL; gdouble popwidth, popheight; gdouble tx, ty; gdouble screen_ratio, page_ratio, scale; PopplerPage *page = NULL; /* no valid target size? */ if (pp->width <= 0 || pp->height <= 0) return TRUE; /* decide which page to render - if any */ mypage_i = pagenumForPort(pp); if (mypage_i < 0 || mypage_i >= doc_n_pages) { /* We don't do any drawing and set the frame's title to "X". * Thus, we'll end up with an "empty" frame. */ if (pp->frame != NULL) gtk_frame_set_label(GTK_FRAME(pp->frame), "X"); return TRUE; } else { /* update frame title */ if (pp->frame != NULL) { title = g_strdup_printf("Slide %d / %d", mypage_i + 1, doc_n_pages); gtk_frame_set_label(GTK_FRAME(pp->frame), title); g_free(title); } } /* if note-control is active, print current page number if on * "main" frame. (don't do this on the beamer because it could be * locked.) * this allows you to attach any kind of other program or script * which can show notes for a specific slide. simply pipe the * output of pdfpres to your other tool. */ if (pp->offset == 0 && !pp->isBeamer) { printNote(doc_page + 1); if (runpref.do_notectrl) { printf("%d\n", doc_page + 1); fflush(stdout); } } /* Get the page and it's size from the document. */ page = poppler_document_get_page(doc, mypage_i); poppler_page_get_size(page, &popwidth, &popheight); /* Set page number */ if (pp->isBeamer) { gtk_label_set_text(GTK_LABEL(curPageLabel), g_strdup_printf("%s/%d", poppler_page_get_label(page), doc_last_page)); } /* Select fit mode. */ page_ratio = popwidth / popheight; screen_ratio = (double)pp->width / (double)pp->height; if (runpref.fit_mode == FIT_PAGE) { /* That's it: Compare screen and page ratio. This * will cover all 4 cases that could happen. */ if (screen_ratio > page_ratio) myfitmode = FIT_HEIGHT; else myfitmode = FIT_WIDTH; } else myfitmode = runpref.fit_mode; switch (myfitmode) { case FIT_HEIGHT: /* Fit size. */ h = pp->height; w = h * page_ratio; scale = h / popheight; /* Center page. */ tx = (pp->width - popwidth * scale) * 0.5; ty = 0; break; case FIT_WIDTH: w = pp->width; h = w / page_ratio; scale = w / popwidth; tx = 0; ty = (pp->height - popheight * scale) * 0.5; break; } /* A black background on beamer frame. Push and pop cairo contexts, so we have a * clean state afterwards. */ if (pp->isBeamer) { cairo_save(cr); cairo_set_source_rgb(cr, 0, 0, 0); cairo_rectangle(cr, 0, 0, pp->width, pp->height); cairo_fill(cr); cairo_restore(cr); /* center page on beamer */ cairo_translate(cr, tx, ty); } else { cairo_translate(cr, tx, 0); } /* Render the page */ cairo_scale(cr, scale, scale); poppler_page_render(page, cr); /* We no longer need that page. */ g_object_unref(G_OBJECT(page)); /* Nobody else draws to this widget. */ return TRUE; }