diff options
-rw-r--r-- | src/frame.c | 3 | ||||
-rw-r--r-- | src/frame.h | 3 | ||||
-rw-r--r-- | src/imagestore.c | 112 | ||||
-rw-r--r-- | src/imagestore.h | 12 | ||||
-rw-r--r-- | src/narrative_window.c | 2 | ||||
-rw-r--r-- | src/print.c | 10 | ||||
-rw-r--r-- | src/render.c | 24 | ||||
-rw-r--r-- | src/render.h | 6 | ||||
-rw-r--r-- | src/sc_editor.c | 6 | ||||
-rw-r--r-- | src/slideshow.c | 2 | ||||
-rw-r--r-- | tests/render_test.c | 2 | ||||
-rw-r--r-- | tests/render_test_sc1.c | 2 |
12 files changed, 72 insertions, 112 deletions
diff --git a/src/frame.c b/src/frame.c index cc47208..948bfc3 100644 --- a/src/frame.c +++ b/src/frame.c @@ -602,8 +602,7 @@ static void render_from_surf(cairo_surface_t *surf, cairo_t *cr, } -void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is, - enum is_size isz) +void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is) { cairo_surface_t *surf; diff --git a/src/frame.h b/src/frame.h index 3bc11f3..fd3c151 100644 --- a/src/frame.h +++ b/src/frame.h @@ -128,8 +128,7 @@ extern void show_para(Paragraph *p); extern void set_para_spacing(Paragraph *para, float space[4]); extern double paragraph_height(Paragraph *para); -extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is, - enum is_size isz); +extern void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is); extern SCBlock *get_newline_at_end(Paragraph *para); extern void set_newline_at_end(Paragraph *para, SCBlock *bl); diff --git a/src/imagestore.c b/src/imagestore.c index 6f65962..e84406f 100644 --- a/src/imagestore.c +++ b/src/imagestore.c @@ -1,7 +1,7 @@ /* * imagestore.c * - * Copyright © 2013 Thomas White <taw@bitwiz.org.uk> + * Copyright © 2013-2017 Thomas White <taw@bitwiz.org.uk> * * This file is part of Colloquium. * @@ -35,11 +35,14 @@ #include "imagestore.h" +#define MAX_SIZES (32) + struct image_record { char *filename; - cairo_surface_t *surf[NUM_ISZ_SIZES]; - int w[NUM_ISZ_SIZES]; + cairo_surface_t *surf[MAX_SIZES]; + int w[MAX_SIZES]; + int n_sizes; }; @@ -107,7 +110,7 @@ void imagestore_destroy(ImageStore *is) for ( i=0; i<is->n_images; i++ ) { int j; free(is->images[i].filename); - for ( j=0; j<NUM_ISZ_SIZES; j++ ) { + for ( j=0; j<is->images[i].n_sizes; j++ ) { if ( is->images[i].surf[j] != NULL ) { g_object_unref(is->images[i].surf[j]); } @@ -133,6 +136,9 @@ static cairo_surface_t *pixbuf_to_surface(GdkPixbuf *t) cr = cairo_create(surf); gdk_cairo_set_source_pixbuf(cr, t, 0, 0); + cairo_pattern_t *patt = cairo_get_source(cr); + cairo_pattern_set_extend(patt, CAIRO_EXTEND_PAD); + cairo_pattern_set_filter(patt, CAIRO_FILTER_BEST); cairo_paint(cr); cairo_destroy(cr); @@ -141,65 +147,46 @@ static cairo_surface_t *pixbuf_to_surface(GdkPixbuf *t) } -static cairo_surface_t *try_all_locations(const char *filename, int w, - ImageStore *is) +static cairo_surface_t *try_all_locations(const char *filename, int w) { GError *error = NULL; GdkPixbuf *t; - char *tmp; - const char *image_folder = "/home/taw/Documents/Slides"; /* FIXME ! */ - /* Try the filename as is */ t = gdk_pixbuf_new_from_file_at_size(filename, w, -1, &error); - if ( t != NULL ) return pixbuf_to_surface(t); - - /* Try the file prefixed with the directory the presentation is in */ - if ( is->dname != NULL ) { + if ( t == NULL ) return NULL; - error = NULL; - tmp = malloc(strlen(filename) + strlen(is->dname) + 2); - if ( tmp == NULL ) return NULL; - strcpy(tmp, is->dname); - strcat(tmp, "/"); - strcat(tmp, filename); - t = gdk_pixbuf_new_from_file_at_size(tmp, w, -1, &error); - free(tmp); - if ( t != NULL ) return pixbuf_to_surface(t); - - } + /* FIXME: Restore searching in pre-defined folder, + * hence (or otherwise) providing for relocation of presentation files */ - /* Try prefixed with image pathname */ - error = NULL; - tmp = malloc(strlen(filename) + strlen(image_folder) + 2); - if ( tmp == NULL ) return NULL; - strcpy(tmp, image_folder); - strcat(tmp, "/"); - strcat(tmp, filename); - t = gdk_pixbuf_new_from_file_at_size(tmp, w, -1, &error); - free(tmp); - if ( t != NULL ) return pixbuf_to_surface(t); - - return NULL; + return pixbuf_to_surface(t); } -static cairo_surface_t *add_image(struct image_record *im, const char *filename, - int w, enum is_size isz, ImageStore *is) +static cairo_surface_t *add_image_size(struct image_record *im, + const char *filename, int w) { - im->surf[isz] = try_all_locations(filename, w, is); + cairo_surface_t *surf; + + if ( im->n_sizes == MAX_SIZES ) { + /* FIXME: Nice cache replacement algorithm */ + fprintf(stderr, "Too many image sizes!\n"); + return NULL; + } - if ( im->surf[isz] == NULL ) return NULL; + surf = try_all_locations(filename, w); + if ( surf == NULL ) return NULL; - im->w[isz] = w; + /* Add surface to list */ + im->w[im->n_sizes] = w; + im->surf[im->n_sizes] = surf; + im->n_sizes++; - return im->surf[isz]; + return surf; } -static cairo_surface_t *add_new_image(ImageStore *is, const char *filename, - int w, enum is_size isz) +static cairo_surface_t *add_new_image(ImageStore *is, const char *filename, int w) { - int j; int idx; if ( is->n_images == is->max_images ) { @@ -211,13 +198,10 @@ static cairo_surface_t *add_new_image(ImageStore *is, const char *filename, idx = is->n_images++; + is->images[idx].n_sizes = 0; is->images[idx].filename = strdup(filename); - for ( j=0; j<NUM_ISZ_SIZES; j++ ) { - is->images[idx].surf[j] = NULL; - is->images[idx].w[j] = 0; - } - return add_image(&is->images[idx], filename, w, isz, is); + return add_image_size(&is->images[idx], filename, w); } @@ -230,22 +214,15 @@ void show_imagestore(ImageStore *is) for ( i=0; i<is->n_images; i++ ) { printf("%s :\n", is->images[i].filename); - printf("ss: %p %i ", is->images[i].surf[ISZ_SLIDESHOW], - is->images[i].w[ISZ_SLIDESHOW]); - printf("ed: %p %i ", is->images[i].surf[ISZ_EDITOR], - is->images[i].w[ISZ_EDITOR]); - printf("th: %p %i ", is->images[i].surf[ISZ_THUMBNAIL], - is->images[i].w[ISZ_THUMBNAIL]); printf("\n"); } } -cairo_surface_t *lookup_image(ImageStore *is, const char *filename, int w, - enum is_size isz) +cairo_surface_t *lookup_image(ImageStore *is, const char *filename, int w) { - int i; + int i, j; int found = 0; cairo_surface_t *surf; @@ -256,21 +233,14 @@ cairo_surface_t *lookup_image(ImageStore *is, const char *filename, int w, } } if ( !found ) { - return add_new_image(is, filename, w, isz); + return add_new_image(is, filename, w); } - /* Image already exists, but might not have the right size or - * the right slot filled in */ - - if ( is->images[i].w[isz] == w ) return is->images[i].surf[isz]; - - /* Image is the wrong size or slot is not filled in yet */ - if ( is->images[i].surf[isz] != NULL ) { - cairo_surface_destroy(is->images[i].surf[isz]); - is->images[i].surf[isz] = NULL; + for ( j=0; j<is->images[i].n_sizes; j++ ) { + if ( is->images[i].w[j] == w ) return is->images[i].surf[j]; } - /* Slot is not filled in yet */ - surf = add_image(&is->images[i], filename, w, isz, is); + /* We don't have this size yet */ + surf = add_image_size(&is->images[i], filename, w); return surf; } diff --git a/src/imagestore.h b/src/imagestore.h index 99e7176..d2ab7f7 100644 --- a/src/imagestore.h +++ b/src/imagestore.h @@ -1,7 +1,7 @@ /* * imagestore.h * - * Copyright © 2013-2014 Thomas White <taw@bitwiz.org.uk> + * Copyright © 2013-2017 Thomas White <taw@bitwiz.org.uk> * * This file is part of Colloquium. * @@ -32,13 +32,6 @@ typedef struct _imagestore ImageStore; -enum is_size { - ISZ_SLIDESHOW = 0, - ISZ_EDITOR = 1, - ISZ_THUMBNAIL = 2, - NUM_ISZ_SIZES -}; - extern ImageStore *imagestore_new(void); extern void imagestore_destroy(ImageStore *is); @@ -46,8 +39,7 @@ extern void imagestore_destroy(ImageStore *is); extern void imagestore_set_presentation_file(ImageStore *is, const char *filename); -extern cairo_surface_t *lookup_image(ImageStore *is, const char *filename, - int w, enum is_size isz); +extern cairo_surface_t *lookup_image(ImageStore *is, const char *filename, int w); extern void show_imagestore(ImageStore *is); diff --git a/src/narrative_window.c b/src/narrative_window.c index 7184f53..72968c9 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -629,7 +629,7 @@ static cairo_surface_t *render_thumbnail(int w, int h, void *bvp, void *vp) stylesheets[1] = NULL; /* FIXME: Cache like crazy here */ surf = render_sc(scblocks, w, h, 1024.0, 768.0, stylesheets, NULL, - p->is, ISZ_THUMBNAIL, 0, &top, p->lang); + p->is, 0, &top, p->lang); frame_free(top); return surf; diff --git a/src/print.c b/src/print.c index c440245..2a3ca68 100644 --- a/src/print.c +++ b/src/print.c @@ -118,14 +118,14 @@ static void print_slide_only(GtkPrintOperation *op, GtkPrintContext *ctx, cairo_fill(cr); top = interp_and_shape(sc_block_child(ps->slide), stylesheets, NULL, - ps->p->is, ISZ_SLIDESHOW, + ps->p->is, page+1, cr, ps->p->slide_width, ps->p->slide_height, ps->p->lang); recursive_wrap(top, pc); - recursive_draw(top, cr, ps->p->is, ISZ_SLIDESHOW, + recursive_draw(top, cr, ps->p->is, 0.0, ps->p->slide_height); ps->slide = next_slide(ps->p, ps->slide); @@ -160,7 +160,7 @@ static cairo_surface_t *render_thumbnail(int w, int h, void *bvp, void *vp) stylesheets[1] = NULL; /* FIXME: Cache like crazy here */ surf = render_sc(scblocks, w, h, 1024.0, 768.0, stylesheets, NULL, - p->is, ISZ_THUMBNAIL, 0, &top, p->lang); + p->is, 0, &top, p->lang); frame_free(top); return surf; @@ -200,7 +200,7 @@ static void begin_narrative_print(GtkPrintOperation *op, GtkPrintContext *ctx, } ps->top = interp_and_shape(ps->p->scblocks, stylesheets, cbl, - ps->is, ISZ_SLIDESHOW, 0, + ps->is, 0, gtk_print_context_get_cairo_context(ctx), gtk_print_context_get_width(ctx), gtk_print_context_get_height(ctx), @@ -244,7 +244,7 @@ static void print_narrative(GtkPrintOperation *op, GtkPrintContext *ctx, h += paragraph_height(ps->top->paras[i]); if ( h > page_height ) return; - render_paragraph(cr, ps->top->paras[i], ps->is, ISZ_SLIDESHOW); + render_paragraph(cr, ps->top->paras[i], ps->is); cairo_translate(cr, 0.0, paragraph_height(ps->top->paras[i])); } diff --git a/src/render.c b/src/render.c index b84b11e..74f63a2 100644 --- a/src/render.c +++ b/src/render.c @@ -91,7 +91,7 @@ static void do_background(cairo_t *cr, struct frame *fr) static int draw_frame(cairo_t *cr, struct frame *fr, ImageStore *is, - enum is_size isz, double min_y, double max_y) + double min_y, double max_y) { int i; double hpos = 0.0; @@ -109,7 +109,7 @@ static int draw_frame(cairo_t *cr, struct frame *fr, ImageStore *is, cairo_translate(cr, 0.0, hpos); if ( (hpos + cur_h > min_y) && (hpos < max_y) ) { - render_paragraph(cr, fr->paras[i], is, isz); + render_paragraph(cr, fr->paras[i], is); } /* else paragraph is not visible */ hpos += cur_h; @@ -123,17 +123,17 @@ static int draw_frame(cairo_t *cr, struct frame *fr, ImageStore *is, int recursive_draw(struct frame *fr, cairo_t *cr, - ImageStore *is, enum is_size isz, + ImageStore *is, double min_y, double max_y) { int i; - draw_frame(cr, fr, is, isz, min_y, max_y); + draw_frame(cr, fr, is, min_y, max_y); for ( i=0; i<fr->num_children; i++ ) { cairo_save(cr); cairo_translate(cr, fr->children[i]->x, fr->children[i]->y); - recursive_draw(fr->children[i], cr, is, isz, + recursive_draw(fr->children[i], cr, is, min_y - fr->children[i]->y, max_y - fr->children[i]->y); cairo_restore(cr); @@ -172,7 +172,7 @@ int recursive_wrap(struct frame *fr, PangoContext *pc) struct frame *interp_and_shape(SCBlock *scblocks, SCBlock **stylesheets, SCCallbackList *cbl, ImageStore *is, - enum is_size isz, int slide_number, + int slide_number, cairo_t *cr, double w, double h, PangoLanguage *lang) { @@ -229,7 +229,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock **stylesheets, static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_t *cr, double log_w, double log_h, SCBlock **stylesheets, SCCallbackList *cbl, - ImageStore *is, enum is_size isz, + ImageStore *is, int slide_number, PangoLanguage *lang, PangoContext *pc) { @@ -239,12 +239,12 @@ static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_set_source_rgb(cr, 1.0, 1.0, 1.0); cairo_fill(cr); - top = interp_and_shape(scblocks, stylesheets, cbl, is, isz, + top = interp_and_shape(scblocks, stylesheets, cbl, is, slide_number, cr, log_w, log_h, lang); recursive_wrap(top, pc); - recursive_draw(top, cr, is, isz, 0.0, log_h); + recursive_draw(top, cr, is, 0.0, log_h); return top; } @@ -253,7 +253,7 @@ static struct frame *render_sc_with_context(SCBlock *scblocks, cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, double log_w, double log_h, SCBlock **stylesheets, SCCallbackList *cbl, - ImageStore *is, enum is_size isz, + ImageStore *is, int slide_number, struct frame **ptop, PangoLanguage *lang) { @@ -267,7 +267,7 @@ cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, pc = pango_cairo_create_context(cr); cairo_scale(cr, w/log_w, h/log_h); top = render_sc_with_context(scblocks, cr, log_w, log_h, - stylesheets, cbl, is, isz,slide_number, + stylesheets, cbl, is, slide_number, lang, pc); g_object_unref(pc); cairo_destroy(cr); @@ -333,7 +333,7 @@ int export_pdf(struct presentation *p, const char *filename) render_sc_with_context(sc_block_child(bl), cr, p->slide_width, p->slide_height, stylesheets, NULL, - p->is, ISZ_SLIDESHOW, i, p->lang, pc); + p->is, i, p->lang, pc); cairo_restore(cr); diff --git a/src/render.h b/src/render.h index be9bfd8..aefa238 100644 --- a/src/render.h +++ b/src/render.h @@ -36,7 +36,7 @@ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, double log_w, double log_h, SCBlock **stylesheets, SCCallbackList *cbl, - ImageStore *is, enum is_size isz, + ImageStore *is, int slide_number, struct frame **ptop, PangoLanguage *lang); @@ -46,7 +46,7 @@ extern cairo_surface_t *render_sc(SCBlock *scblocks, int w, int h, */ extern struct frame *interp_and_shape(SCBlock *scblocks, SCBlock **stylesheets, SCCallbackList *cbl, - ImageStore *is, enum is_size isz, + ImageStore *is, int slide_number, cairo_t *cr, double w, double h, PangoLanguage *lang); @@ -56,7 +56,7 @@ extern int recursive_wrap(struct frame *fr, PangoContext *pc); extern int export_pdf(struct presentation *p, const char *filename); extern int recursive_draw(struct frame *fr, cairo_t *cr, - ImageStore *is, enum is_size isz, + ImageStore *is, double min_y, double max_y); #endif /* RENDER_H */ diff --git a/src/sc_editor.c b/src/sc_editor.c index 4d152b1..bd9a7b3 100644 --- a/src/sc_editor.c +++ b/src/sc_editor.c @@ -186,7 +186,7 @@ static gboolean resize_sig(GtkWidget *widget, GdkEventConfigure *event, h = e->log_h; } e->top = interp_and_shape(e->scblocks, e->stylesheets, e->cbl, - e->is, ISZ_EDITOR, e->slidenum, cr, + e->is, e->slidenum, cr, w, h, e->lang); recursive_wrap(e->top, pc); } @@ -388,7 +388,7 @@ static void full_rerender(SCEditor *e) pc = pango_cairo_create_context(cr); e->top = interp_and_shape(e->scblocks, e->stylesheets, e->cbl, - e->is, ISZ_EDITOR, e->slidenum, + e->is, e->slidenum, cr, e->w, 0.0, e->lang); e->top->x = 0.0; @@ -619,7 +619,7 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, SCEditor *e) /* Contents */ cairo_translate(cr, -e->h_scroll_pos, -e->scroll_pos); cairo_translate(cr, e->border_offs_x, e->border_offs_y); - recursive_draw(e->top, cr, e->is, ISZ_EDITOR, + recursive_draw(e->top, cr, e->is, e->scroll_pos, e->scroll_pos + e->visible_height); /* Editing overlay */ diff --git a/src/slideshow.c b/src/slideshow.c index 71e8d9a..86b2426 100644 --- a/src/slideshow.c +++ b/src/slideshow.c @@ -69,7 +69,7 @@ static void slideshow_rerender(SCSlideshow *ss) ss->surface = render_sc(sc_block_child(ss->cur_slide), ss->slide_width, ss->slide_height, ss->p->slide_width, ss->p->slide_height, - stylesheets, NULL, ss->p->is, ISZ_SLIDESHOW, n, + stylesheets, NULL, ss->p->is, n, &ss->top, ss->p->lang); w = gtk_widget_get_allocated_width(GTK_WIDGET(ss->drawingarea)); diff --git a/tests/render_test.c b/tests/render_test.c index 5c99542..a6bf25f 100644 --- a/tests/render_test.c +++ b/tests/render_test.c @@ -58,7 +58,7 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, gpointer data) h = gtk_widget_get_allocated_height(da); surface = render_sc(scblocks, w, h, w, h, NULL, NULL, NULL, - ISZ_EDITOR, 1, &top, lang); + 1, &top, lang); cairo_rectangle(cr, 0.0, 0.0, w, h); cairo_set_source_surface(cr, surface, 0.0, 0.0); cairo_fill(cr); diff --git a/tests/render_test_sc1.c b/tests/render_test_sc1.c index eae8689..f0fdb95 100644 --- a/tests/render_test_sc1.c +++ b/tests/render_test_sc1.c @@ -57,7 +57,7 @@ static gboolean draw_sig(GtkWidget *da, cairo_t *cr, gpointer data) h = gtk_widget_get_allocated_height(da); surface = render_sc(scblocks, w, h, w, h, NULL, NULL, NULL, - ISZ_EDITOR, 1, &top, lang); + 1, &top, lang); cairo_rectangle(cr, 0.0, 0.0, w, h); cairo_set_source_surface(cr, surface, 0.0, 0.0); cairo_fill(cr); |