aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2016-03-28 18:35:24 +0200
committerThomas White <taw@bitwiz.org.uk>2016-03-28 18:35:24 +0200
commit4def920737575625a8336a41a4310cc52052ce01 (patch)
tree913bc133a0b435918452edcc207af8ce23a8d2bb /src
parent3bebe8b1c2fec41a9c33b7310f27804bc1062db6 (diff)
Restore callbacks
Diffstat (limited to 'src')
-rw-r--r--src/frame.c75
-rw-r--r--src/render.c104
2 files changed, 69 insertions, 110 deletions
diff --git a/src/frame.c b/src/frame.c
index 2a29a2a..a541999 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -28,6 +28,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <math.h>
#include "sc_parse.h"
#include "frame.h"
@@ -53,17 +54,26 @@ enum para_type
struct _paragraph
{
enum para_type type;
+ double height;
+ /* For PARA_TYPE_TEXT */
int n_runs;
struct text_run *runs;
int open;
PangoLayout *layout;
+ /* For PARA_TYPE_IMAGE */
char *filename;
double image_w;
double image_h;
- double height;
+ /* For PARA_TYPE_CALLBACK */
+ double cb_w;
+ double cb_h;
+ SCCallbackDrawFunc draw_func;
+ SCCallbackClickFunc click_func;
+ void *bvp;
+ void *vp;
};
@@ -267,6 +277,8 @@ void wrap_paragraph(Paragraph *para, PangoContext *pc, double w)
PangoRectangle rect;
size_t pos = 0;
+ if ( para->type != PARA_TYPE_TEXT ) return;
+
for ( i=0; i<para->n_runs; i++ ) {
total_len += para->runs[i].len_bytes;
}
@@ -377,7 +389,23 @@ void add_callback_para(struct frame *fr, double w, double h,
SCCallbackClickFunc click_func, void *bvp,
void *vp)
{
- /* FIXME */
+ Paragraph *pnew;
+
+ pnew = create_paragraph(fr);
+ if ( pnew == NULL ) {
+ fprintf(stderr, "Failed to add callback paragraph\n");
+ return;
+ }
+
+ pnew->type = PARA_TYPE_CALLBACK;
+ pnew->cb_w = w;
+ pnew->cb_h = h;
+ pnew->draw_func = draw_func;
+ pnew->click_func = click_func;
+ pnew->bvp = bvp;
+ pnew->vp = vp;
+ pnew->height = h;
+ pnew->open = 0;
}
@@ -387,11 +415,17 @@ void add_image_para(struct frame *fr, const char *filename,
Paragraph *pnew;
pnew = create_paragraph(fr);
+ if ( pnew == NULL ) {
+ fprintf(stderr, "Failed to add image paragraph\n");
+ return;
+ }
pnew->type = PARA_TYPE_IMAGE;
pnew->filename = strdup(filename);
pnew->image_w = w;
pnew->image_h = h;
+ pnew->height = h;
+ pnew->open = 0;
}
@@ -436,6 +470,31 @@ void close_last_paragraph(struct frame *fr)
}
+static void render_from_surf(cairo_surface_t *surf, cairo_t *cr,
+ double w, double h, int border)
+{
+ double x, y;
+
+ x = 0.0; y = 0.0;
+ cairo_user_to_device(cr, &x, &y);
+ x = rint(x); y = rint(y);
+ cairo_device_to_user(cr, &x, &y);
+
+ cairo_new_path(cr);
+ cairo_rectangle(cr, x, y, w, h);
+ cairo_set_source_surface(cr, surf, 0.0, 0.0);
+ cairo_fill(cr);
+
+ if ( border ) {
+ cairo_new_path(cr);
+ cairo_rectangle(cr, x+0.5, y+0.5, w, h);
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ cairo_set_line_width(cr, 1.0);
+ cairo_stroke(cr);
+ }
+}
+
+
void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is,
enum is_size isz)
{
@@ -451,11 +510,15 @@ void render_paragraph(cairo_t *cr, Paragraph *para, ImageStore *is,
break;
case PARA_TYPE_IMAGE :
- cairo_new_path(cr);
- cairo_rectangle(cr, 0.0, 0.0, para->image_w, para->image_h);
surf = lookup_image(is, para->filename, para->image_w, isz);
- cairo_set_source_surface(cr, surf, 0.0, 0.0);
- cairo_fill(cr);
+ render_from_surf(surf, cr, para->image_w, para->image_h, 0);
+ break;
+
+ case PARA_TYPE_CALLBACK :
+ surf = para->draw_func(para->cb_w, para->cb_h,
+ para->bvp, para->vp);
+ render_from_surf(surf, cr, para->cb_w, para->cb_h, 1);
+ cairo_surface_destroy(surf); /* FIXME: Cache like crazy */
break;
}
diff --git a/src/render.c b/src/render.c
index d64c8ed..d3dfa01 100644
--- a/src/render.c
+++ b/src/render.c
@@ -43,110 +43,6 @@
#include "imagestore.h"
-#if 0
-static void render_callback_box(cairo_t *cr, struct wrap_box *box)
-{
- double ascd;
- double x, y, w, h;
-
- cairo_surface_t *surf;
-
- cairo_save(cr);
-
- ascd = pango_units_to_double(box->ascent);
-
- /* This is how wide the image should be in Cairo units */
- w = pango_units_to_double(box->width);
- h = pango_units_to_double(box->height);
- cairo_user_to_device_distance(cr, &w, &h);
- /* w is now how wide the image should be in pixels */
-
- surf = box->draw_func(w, h, box->bvp, box->vp);
-
- cairo_new_path(cr);
- x = 0.0; y = -ascd;
- cairo_user_to_device(cr, &x, &y);
- x = rint(x); y = rint(y);
- cairo_device_to_user(cr, &x, &y);
- cairo_rectangle(cr, x, y, pango_units_to_double(box->width),
- pango_units_to_double(box->height));
- cairo_clip_preserve(cr);
-
- if ( surf == NULL ) {
- cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
- fprintf(stderr, "Null surface box");
- } else {
- cairo_set_source_surface(cr, surf, x, y);
- }
-
- cairo_paint(cr);
- cairo_reset_clip(cr);
-
- cairo_new_path(cr);
- cairo_rectangle(cr, x+0.5, y+0.5, pango_units_to_double(box->width),
- pango_units_to_double(box->height));
- cairo_set_line_width(cr, 1.0);
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
- cairo_stroke(cr);
- cairo_restore(cr);
-
- cairo_surface_destroy(surf);
-}
-#endif
-
-
-#if 0
-static void render_image_box(cairo_t *cr, struct wrap_box *box, ImageStore *is,
- enum is_size isz)
-{
- cairo_surface_t *surf;
- double w, h;
- int wi;
- double ascd;
- double x, y;
-
- cairo_save(cr);
-
- ascd = pango_units_to_double(box->ascent);
-
- x = 0.0;
- y = -ascd;
- cairo_user_to_device(cr, &x, &y);
-
- cairo_new_path(cr);
- cairo_rectangle(cr, 0.0, -ascd,
- pango_units_to_double(box->width),
- pango_units_to_double(box->height));
-
- /* This is how wide the image should be in Cairo units */
- w = pango_units_to_double(box->width);
-
- h = 0.0; /* Dummy */
- cairo_user_to_device_distance(cr, &w, &h);
- /* w is now how wide the image should be in pixels */
-
- wi = lrint(w);
-
- surf = lookup_image(is, box->filename, wi, isz);
- //show_imagestore(is);
-
- if ( surf == NULL ) {
- cairo_set_source_rgba(cr, 1.0, 0.0, 0.0, 1.0);
- fprintf(stderr, "Failed to load '%s' at size %i\n",
- box->filename, wi);
- } else {
- cairo_identity_matrix(cr);
- cairo_set_source_surface(cr, surf, x, y);
- }
-
- cairo_fill(cr);
- cairo_restore(cr);
-}
-#endif
-
-
-
-
static void do_background(cairo_t *cr, struct frame *fr)
{
cairo_pattern_t *patt = NULL;