From e851a106735a5498b3607a029a3091fd74879f3e Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 27 Nov 2017 00:12:46 +0100 Subject: Use ImageStore to get image size --- src/frame.c | 4 ++-- src/frame.h | 2 +- src/imagestore.c | 55 +++++++++++++++++++++++++++++++++++--------------- src/imagestore.h | 3 +++ src/narrative_window.c | 2 +- src/render.c | 2 +- src/sc_interp.c | 9 ++++++--- src/sc_interp.h | 5 +++-- 8 files changed, 56 insertions(+), 26 deletions(-) diff --git a/src/frame.c b/src/frame.c index 86e2733..318ff69 100644 --- a/src/frame.c +++ b/src/frame.c @@ -487,7 +487,7 @@ void add_callback_para(struct frame *fr, SCBlock *bl, SCBlock *mr, void add_image_para(struct frame *fr, SCBlock *scblock, const char *filename, - double w, double h, int editable) + ImageStore *is, double w, double h, int editable) { Paragraph *pnew; int wi, hi; @@ -498,7 +498,7 @@ void add_image_para(struct frame *fr, SCBlock *scblock, const char *filename, return; } - if ( gdk_pixbuf_get_file_info(filename, &wi, &hi) == NULL ) { + if ( imagestore_get_size(is, filename, &wi, &hi) ) { fprintf(stderr, "Couldn't get size for %s\n", filename); wi = 100; hi = 100; diff --git a/src/frame.h b/src/frame.h index fd3c151..4c9265a 100644 --- a/src/frame.h +++ b/src/frame.h @@ -147,7 +147,7 @@ extern void add_callback_para(struct frame *fr, SCBlock *scblock, SCBlock *mr, extern void add_image_para(struct frame *fr, SCBlock *scblock, const char *filename, - double w, double h, int editable); + ImageStore *is, double w, double h, int editable); extern void wrap_paragraph(Paragraph *para, PangoContext *pc, double w, size_t sel_start, size_t sel_end); diff --git a/src/imagestore.c b/src/imagestore.c index 2831d38..63d41b7 100644 --- a/src/imagestore.c +++ b/src/imagestore.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -151,42 +152,55 @@ static cairo_surface_t *pixbuf_to_surface(GdkPixbuf *t) } -static cairo_surface_t *try_all_locations(const char *filename, - const char *dname, const char *iname, - int w) +static char *try_all_locations(const char *filename, + const char *dname, const char *iname) { - GError *error = NULL; - GdkPixbuf *t; - - t = gdk_pixbuf_new_from_file_at_size(filename, w, -1, &error); + if ( g_file_test(filename, G_FILE_TEST_EXISTS) ) { + return strdup(filename); + } /* Try the file prefixed with the directory the presentation is in */ - if ( (t == NULL) && (dname != NULL) ) { + if ( dname != NULL ) { char *tmp; - error = NULL; tmp = malloc(strlen(filename) + strlen(dname) + 2); if ( tmp == NULL ) return NULL; strcpy(tmp, dname); strcat(tmp, "/"); strcat(tmp, filename); - t = gdk_pixbuf_new_from_file_at_size(tmp, w, -1, &error); + if ( g_file_test(tmp, G_FILE_TEST_EXISTS) ) { + return tmp; + } free(tmp); } /* Try prefixing with imagestore folder */ - if ( (t == NULL) && (iname != NULL) ) { + if ( iname != NULL ) { char *tmp; - error = NULL; tmp = malloc(strlen(filename) + strlen(iname) + 2); if ( tmp == NULL ) return NULL; strcpy(tmp, iname); strcat(tmp, "/"); strcat(tmp, filename); - t = gdk_pixbuf_new_from_file_at_size(tmp, w, -1, &error); + if ( g_file_test(tmp, G_FILE_TEST_EXISTS) ) { + return tmp; + } free(tmp); } - return pixbuf_to_surface(t); + return NULL; +} + + +int imagestore_get_size(ImageStore *is, const char *filename, + int *w, int *h) +{ + char *fullfn; + + fullfn = try_all_locations(filename, is->dname, is->storename); + if ( gdk_pixbuf_get_file_info(fullfn, w, h) == NULL ) { + return 1; + } + return 0; } @@ -195,7 +209,10 @@ static cairo_surface_t *add_image_size(struct image_record *im, const char *dname, const char *iname, int w) { + char *fullfn; cairo_surface_t *surf; + GdkPixbuf *t; + GError *error = NULL; if ( im->n_sizes == MAX_SIZES ) { /* FIXME: Nice cache replacement algorithm */ @@ -203,8 +220,14 @@ static cairo_surface_t *add_image_size(struct image_record *im, return NULL; } - surf = try_all_locations(filename, dname, iname, w); - if ( surf == NULL ) return NULL; + fullfn = try_all_locations(filename, dname, iname); + if ( fullfn == NULL ) return NULL; + + t = gdk_pixbuf_new_from_file_at_size(fullfn, w, -1, &error); + free(fullfn); + + surf = pixbuf_to_surface(t); + g_object_unref(t); /* Add surface to list */ im->w[im->n_sizes] = w; diff --git a/src/imagestore.h b/src/imagestore.h index 016b2e3..1c5f219 100644 --- a/src/imagestore.h +++ b/src/imagestore.h @@ -41,6 +41,9 @@ extern void imagestore_set_presentation_file(ImageStore *is, extern cairo_surface_t *lookup_image(ImageStore *is, const char *filename, int w); +extern int imagestore_get_size(ImageStore *is, const char *filename, + int *w, int *h); + extern void show_imagestore(ImageStore *is); #endif /* IMAGESTORE_H */ diff --git a/src/narrative_window.c b/src/narrative_window.c index 1552845..c93cba9 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -169,7 +169,7 @@ static struct template_id *get_templates(SCBlock *ss, int *n) struct template_id *list; SCInterpreter *scin; - scin = sc_interp_new(NULL, NULL, NULL); + scin = sc_interp_new(NULL, NULL, NULL, NULL); sc_interp_run_stylesheet(scin, ss); /* ss == NULL is OK */ list = sc_interp_get_templates(scin, n); sc_interp_destroy(scin); diff --git a/src/render.c b/src/render.c index 74f63a2..7fe789c 100644 --- a/src/render.c +++ b/src/render.c @@ -191,7 +191,7 @@ struct frame *interp_and_shape(SCBlock *scblocks, SCBlock **stylesheets, top->h = h; top->scblocks = scblocks; - scin = sc_interp_new(pc, lang, top); + scin = sc_interp_new(pc, lang, is, top); if ( scin == NULL ) { fprintf(stderr, "Failed to set up interpreter.\n"); frame_free(top); diff --git a/src/sc_interp.c b/src/sc_interp.c index b530941..e3b584f 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -1,7 +1,7 @@ /* * sc_interp.c * - * Copyright © 2014-2015 Thomas White + * Copyright © 2014-2017 Thomas White * * This file is part of Colloquium. * @@ -31,6 +31,7 @@ #include #include +#include "imagestore.h" #include "sc_parse.h" #include "sc_interp.h" #include "presentation.h" @@ -79,6 +80,7 @@ struct _scinterp { PangoContext *pc; PangoLanguage *lang; + ImageStore *is; struct slide_constants *s_constants; struct presentation_constants *p_constants; @@ -552,7 +554,7 @@ static void set_frame(SCInterpreter *scin, struct frame *fr) SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, - struct frame *top) + ImageStore *is, struct frame *top) { SCInterpreter *scin; struct sc_state *st; @@ -569,6 +571,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, scin->max_state = 8; scin->pc = pc; + scin->is = is; scin->s_constants = NULL; scin->p_constants = NULL; scin->cbl = NULL; @@ -957,7 +960,7 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin) &w, &h, &filename) == 0 ) { add_image_para(sc_interp_get_frame(scin), bl, - filename, w, h, 1); + filename, scin->is, w, h, 1); free(filename); } else { fprintf(stderr, "Invalid image options '%s'\n", diff --git a/src/sc_interp.h b/src/sc_interp.h index fe38a39..2ae7ee4 100644 --- a/src/sc_interp.h +++ b/src/sc_interp.h @@ -1,7 +1,7 @@ /* * sc_interp.h * - * Copyright © 2014-2016 Thomas White + * Copyright © 2014-2017 Thomas White * * This file is part of Colloquium. * @@ -40,9 +40,10 @@ typedef cairo_surface_t *(*SCCallbackDrawFunc)(int w, int h, void *, void *); typedef int (*SCCallbackClickFunc)(double x, double y, void *, void *); #include "frame.h" +#include "imagestore.h" extern SCInterpreter *sc_interp_new(PangoContext *pc, PangoLanguage *lang, - struct frame *top); + ImageStore *is, struct frame *top); extern void sc_interp_destroy(SCInterpreter *scin); extern void sc_interp_save(SCInterpreter *scin); -- cgit v1.2.3