aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/frame.c4
-rw-r--r--src/frame.h2
-rw-r--r--src/imagestore.c55
-rw-r--r--src/imagestore.h3
-rw-r--r--src/narrative_window.c2
-rw-r--r--src/render.c2
-rw-r--r--src/sc_interp.c9
-rw-r--r--src/sc_interp.h5
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 <assert.h>
#include <libgen.h>
#include <cairo.h>
+#include <glib.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
@@ -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 <taw@bitwiz.org.uk>
+ * Copyright © 2014-2017 Thomas White <taw@bitwiz.org.uk>
*
* This file is part of Colloquium.
*
@@ -31,6 +31,7 @@
#include <pango/pangocairo.h>
#include <gdk/gdk.h>
+#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 <taw@bitwiz.org.uk>
+ * Copyright © 2014-2017 Thomas White <taw@bitwiz.org.uk>
*
* 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);