diff options
author | Thomas White <taw@bitwiz.org.uk> | 2016-03-28 18:35:24 +0200 |
---|---|---|
committer | Thomas White <taw@bitwiz.org.uk> | 2016-03-28 18:35:24 +0200 |
commit | 4def920737575625a8336a41a4310cc52052ce01 (patch) | |
tree | 913bc133a0b435918452edcc207af8ce23a8d2bb /src | |
parent | 3bebe8b1c2fec41a9c33b7310f27804bc1062db6 (diff) |
Restore callbacks
Diffstat (limited to 'src')
-rw-r--r-- | src/frame.c | 75 | ||||
-rw-r--r-- | src/render.c | 104 |
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; |