aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am11
-rw-r--r--src/frame.c29
-rw-r--r--src/frame.h54
-rw-r--r--src/render.c139
-rw-r--r--src/sc_interp.c237
-rw-r--r--src/sc_interp.h13
-rw-r--r--src/sc_parse.c36
-rw-r--r--src/sc_parse.h8
-rw-r--r--src/shape.c234
-rw-r--r--src/shape.h38
-rw-r--r--src/wrap.c494
-rw-r--r--src/wrap.h7
-rw-r--r--tests/render_test.c63
-rw-r--r--tests/storycode_test.c2
14 files changed, 642 insertions, 723 deletions
diff --git a/Makefile.am b/Makefile.am
index 3269346..56e0298 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -15,14 +15,15 @@ src_colloquium_SOURCES = src/colloquium.c src/render.c \
src/frame.c src/sc_parse.c \
src/slideshow.c src/wrap.c src/sc_interp.c \
src/imagestore.c src/notes.c src/pr_clock.c \
- src/inhibit_screensaver.c src/slide_sorter.c
+ src/inhibit_screensaver.c src/slide_sorter.c \
+ src/shape.c
INCLUDES = -Iharfatum/src
EXTRA_DIST += src/presentation.h src/render.h src/wrap.h \
src/slideshow.h src/sc_parse.h src/sc_interp.h \
src/imagestore.h src/notes.h src/pr_clock.h \
- src/inhibit_screensaver.h src/slide_sorter.h
+ src/inhibit_screensaver.h src/slide_sorter.h src/shape.h
src/default_stylesheet.o: src/default_stylesheet.sty
ld -r -b binary -o src/default_stylesheet.o src/default_stylesheet.sty
@@ -39,15 +40,15 @@ desktopdir = $(datadir)/applications
desktop_DATA = colloquium.desktop
EXTRA_DIST += $(desktop_DATA)
-noinst_PROGRAMS = tests/storycode_test
-#tests/render_test tests/render_test_sc1
+noinst_PROGRAMS = tests/storycode_test tests/render_test
+#tests/render_test_sc1
TESTS = tests/storycode_test tests/render_test tests/render_test_sc1
tests_storycode_test_SOURCES = tests/storycode_test.c src/sc_parse.c
tests_render_test_SOURCES = tests/render_test.c src/render.c src/frame.c \
src/wrap.c src/sc_parse.c src/imagestore.c \
- src/loadsave.c
+ src/sc_interp.c src/shape.c
tests_render_test_sc1_SOURCES = tests/render_test_sc1.c src/sc_parse.c \
src/render.c src/frame.c src/wrap.c \
diff --git a/src/frame.c b/src/frame.c
index 8dbbba2..eb0ce7a 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -60,7 +60,7 @@ struct frame *frame_new()
n->num_children = 0;
- n->sc = NULL;
+ n->scblocks = NULL;
return n;
}
@@ -84,6 +84,7 @@ struct frame *add_subframe(struct frame *fr)
}
+#if 0
static LengthUnits get_units(const char *t)
{
size_t len = strlen(t);
@@ -96,7 +97,7 @@ static LengthUnits get_units(const char *t)
}
-static void parse_option(struct frame *fr, const char *opt, StyleSheet *ss)
+static void parse_option(struct frame *fr, const char *opt)
{
if ( (index(opt, 'x') != NULL) && (index(opt, '+') != NULL)
&& (index(opt, '+') != rindex(opt, '+')) )
@@ -152,29 +153,6 @@ static void parse_option(struct frame *fr, const char *opt, StyleSheet *ss)
}
}
-
- if ( strncmp(opt, "style=", 6) == 0 ) {
-
- char *s;
- char *tmp;
-
- tmp = strdup(opt);
-
- if ( opt[strlen(opt)-1] == '*' ) {
- fr->lop_from_style = 1;
- tmp[strlen(tmp)-1] = '\0';
- } else {
- fr->lop_from_style = 0;
- }
-
- s = index(tmp, '=') + 1;
- fr->style = lookup_style(ss, s);
- free(tmp);
- if ( fr->style == NULL ) {
- fprintf(stderr, "Invalid style '%s'\n", opt);
- return;
- }
- }
}
@@ -289,3 +267,4 @@ void show_hierarchy(struct frame *fr, const char *t)
}
}
+#endif
diff --git a/src/frame.h b/src/frame.h
index f183c1b..8431836 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -1,7 +1,7 @@
/*
* frame.h
*
- * Copyright © 2013 Thomas White <taw@bitwiz.org.uk>
+ * Copyright © 2013-2014 Thomas White <taw@bitwiz.org.uk>
*
* This file is part of Colloquium.
*
@@ -30,21 +30,7 @@
#include <pango/pango.h>
#include <cairo.h>
-typedef struct _stylesheet StyleSheet;
-
-
-typedef enum
-{
- DIR_NONE,
- DIR_UL,
- DIR_U,
- DIR_UR,
- DIR_R,
- DIR_DR,
- DIR_D,
- DIR_DL,
- DIR_L
-} Direction;
+#include "sc_parse.h"
typedef enum
@@ -54,36 +40,13 @@ typedef enum
} LengthUnits;
-struct layout_parameters
-{
- double margin_l;
- double margin_r;
- double margin_t;
- double margin_b;
-
- double pad_l;
- double pad_r;
- double pad_t;
- double pad_b;
-
- double x;
- double y;
-
- double w;
- LengthUnits w_units;
- double h;
- LengthUnits h_units;
-};
-
-
struct frame
{
struct frame **children;
int num_children;
int max_children;
- char *sc; /* Storycode */
- size_t sc_len; /* Space allocated for sc */
+ SCBlock *scblocks;
int n_lines;
int max_lines;
@@ -91,28 +54,31 @@ struct frame
size_t pos;
- struct layout_parameters lop;
-
/* The rectangle allocated to this frame, determined by the renderer */
double x;
double y;
double w;
double h;
+ double pad_t;
+ double pad_b;
+ double pad_l;
+ double pad_r;
+
/* True if this frame should be deleted on the next mouse click */
int empty;
/* True if the aspect ratio of this frame should be maintained */
int is_image;
- /* True if wrapping failed for this box */
+ /* True if wrapping failed for this frame */
int trouble;
};
extern struct frame *frame_new(void);
extern struct frame *add_subframe(struct frame *fr);
-extern struct frame *sc_unpack(const char *sc, StyleSheet *ss);
+
extern void show_hierarchy(struct frame *fr, const char *t);
#endif /* FRAME_H */
diff --git a/src/render.c b/src/render.c
index 6ea1afa..ce23f0c 100644
--- a/src/render.c
+++ b/src/render.c
@@ -36,6 +36,7 @@
#include <gdk/gdk.h>
#include "sc_parse.h"
+#include "sc_interp.h"
#include "presentation.h"
#include "frame.h"
#include "render.h"
@@ -185,23 +186,27 @@ static void render_boxes(struct wrap_line *line, cairo_t *cr, ImageStore *is,
static void draw_overfull_marker(cairo_t *cr, struct frame *fr, int i)
{
+#if 0
cairo_move_to(cr, fr->w - fr->lop.pad_l- fr->lop.pad_r, 0.0);
cairo_line_to(cr, fr->w - fr->lop.pad_l - fr->lop.pad_r,
pango_units_to_double(fr->lines[i].height));
cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
cairo_set_line_width(cr, 4.0);
cairo_stroke(cr);
+#endif
}
static void draw_underfull_marker(cairo_t *cr, struct frame *fr, int i)
{
+#if 0
cairo_move_to(cr, fr->w - fr->lop.pad_l- fr->lop.pad_r, 0.0);
cairo_line_to(cr, fr->w - fr->lop.pad_l - fr->lop.pad_r,
pango_units_to_double(fr->lines[i].height));
cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
cairo_set_line_width(cr, 4.0);
cairo_stroke(cr);
+#endif
}
@@ -250,47 +255,22 @@ static void render_lines(struct frame *fr, cairo_t *cr, ImageStore *is,
}
}
+#if 0
+ GdkRGBA col;
-static void run_render_sc(cairo_t *cr, struct frame *fr, const char *sc)
-{
- SCBlockList *bl;
- SCBlockListIterator *iter;
- struct scblock *b;
-
- bl = sc_find_blocks(sc, "bgcol");
- if ( bl == NULL ) return;
-
- for ( b = sc_block_list_first(bl, &iter);
- b != NULL;
- b = sc_block_list_next(bl, iter) )
- {
- GdkRGBA col;
-
- if ( b->contents == NULL ) continue;
- gdk_rgba_parse(&col, b->contents);
- cairo_rectangle(cr, 0, 0, fr->w, fr->h);
- gdk_cairo_set_source_rgba(cr, &col);
- cairo_fill(cr);
-
- }
- sc_block_list_free(bl);
-}
-
+ if ( b->contents == NULL ) continue;
+ gdk_rgba_parse(&col, b->contents);
+ cairo_rectangle(cr, 0, 0, fr->w, fr->h);
+ gdk_cairo_set_source_rgba(cr, &col);
+ cairo_fill(cr);
+#endif
+#if 0
/* Render Level 1 Storycode (no subframes) */
static int render_sc(cairo_t *cr, struct frame *fr, ImageStore *is,
enum is_size isz, struct slide_constants *scc,
struct presentation_constants *pcc, PangoContext *pc)
{
- int i;
-
- for ( i=0; i<fr->n_lines; i++ ) {
- wrap_line_free(&fr->lines[i]);
- }
- free(fr->lines);
- fr->lines = NULL;
- fr->n_lines = 0;
- fr->max_lines = 0;
/* Set up lines */
if ( wrap_contents(fr, pc, scc, pcc) ) {
@@ -313,6 +293,7 @@ static int render_sc(cairo_t *cr, struct frame *fr, ImageStore *is,
return 0;
}
+#endif
static int render_frame(cairo_t *cr, struct frame *fr, ImageStore *is,
@@ -320,73 +301,29 @@ static int render_frame(cairo_t *cr, struct frame *fr, ImageStore *is,
struct presentation_constants *pcc,
PangoContext *pc)
{
+ SCInterpreter *scin;
int i;
+ SCBlock *bl = fr->scblocks;
- /* Render all subframes */
- for ( i=0; i<fr->num_children; i++ ) {
-
- struct frame *ch = fr->children[i];
-#if 0
-/* Frame geometry calculation */
-
- double mtot;
-
- if ( ch->style != NULL ) {
- if ( ch->lop_from_style ) {
- memcpy(&ch->lop, &ch->style->lop,
- sizeof(struct layout_parameters));
- } else {
- double x, y, w, h;
- LengthUnits wu, hu;
- x = ch->lop.x; y = ch->lop.y;
- w = ch->lop.w; h = ch->lop.h;
- wu = ch->lop.w_units; hu = ch->lop.h_units;
- memcpy(&ch->lop, &ch->style->lop,
- sizeof(struct layout_parameters));
- ch->lop.x = x; ch->lop.y = y;
- ch->lop.w = w; ch->lop.h = h;
- ch->lop.w_units = wu; ch->lop.h_units = hu;
- }
- }
-
- mtot = ch->lop.margin_l + ch->lop.margin_r;
- mtot += fr->lop.pad_l + fr->lop.pad_r;
- switch ( ch->lop.w_units ) {
-
- case UNITS_SLIDE :
- ch->w = ch->lop.w;
- break;
-
- case UNITS_FRAC :
- ch->w = fr->w * ch->lop.w - mtot;
- break;
-
- }
-
- mtot = ch->lop.margin_t + ch->lop.margin_b;
- mtot += fr->lop.pad_t + fr->lop.pad_b;
- switch ( ch->lop.h_units ) {
-
- case UNITS_SLIDE :
- ch->h = ch->lop.h;
- break;
-
- case UNITS_FRAC :
- ch->h = fr->h * ch->lop.h - mtot;
- break;
+ scin = sc_interp_new();
+ if ( scin == NULL ) {
+ fprintf(stderr, "Failed to set up interpreter.\n");
+ return 1;
+ }
- }
-#endif
- ch->x = ch->lop.x + fr->lop.pad_l + ch->lop.margin_l;
- ch->y = ch->lop.y + fr->lop.pad_t + ch->lop.margin_t;
- cairo_save(cr);
- cairo_translate(cr, ch->x, ch->y);
- render_frame(cr, ch, is, isz, scc, pcc, pc);
- cairo_restore(cr);
+ for ( i=0; i<fr->n_lines; i++ ) {
+ wrap_line_free(&fr->lines[i]);
+ }
+ free(fr->lines);
+ fr->lines = NULL;
+ fr->n_lines = 0;
+ fr->max_lines = 0;
+ while ( bl != NULL ) {
+ bl = sc_block_next(bl);
}
- render_sc(cr, fr, is, isz, scc, pcc, pc);
+ sc_interp_destroy(scin);
return 0;
}
@@ -448,10 +385,8 @@ cairo_surface_t *render_slide(struct slide *s, int w, double ww, double hh,
h = (hh/ww)*w;
scale = w/ww;
- s->top->lop.x = 0.0;
- s->top->lop.y = 0.0;
- s->top->lop.w = ww;
- s->top->lop.h = hh;
+ s->top->x = 0.0;
+ s->top->y = 0.0;
s->top->w = ww;
s->top->h = hh;
@@ -534,10 +469,8 @@ int export_pdf(struct presentation *p, const char *filename)
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_fill(cr);
- s->top->lop.x = 0.0;
- s->top->lop.y = 0.0;
- s->top->lop.w = w;
- s->top->lop.h = w*r;
+ s->top->x = 0.0;
+ s->top->y = 0.0;
s->top->w = w;
s->top->h = w*r;
diff --git a/src/sc_interp.c b/src/sc_interp.c
index 28182a9..65b113e 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -28,13 +28,246 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <pango/pangocairo.h>
+#include <gdk/gdk.h>
#include "sc_parse.h"
#include "sc_interp.h"
+#include "shape.h"
+#include "wrap.h"
struct _scinterp
{
- int dummy;
+ PangoContext *pc;
+ PangoLanguage *lang;
+
+ struct slide_constants *s_constants;
+ struct presentation_constants *p_constants;
+
+ struct sc_font *fontstack;
+ int n_fonts;
+ int max_fonts;
};
-f \ No newline at end of file
+
+static void set_font(SCInterpreter *scin, const char *font_name)
+{
+ PangoFontMetrics *metrics;
+ struct sc_font *scf;
+
+ scf = &scin->fontstack[scin->n_fonts-1];
+
+ scf->fontdesc = pango_font_description_from_string(font_name);
+ if ( scf->fontdesc == NULL ) {
+ fprintf(stderr, "Couldn't describe font.\n");
+ return;
+ }
+ scf->font = pango_font_map_load_font(pango_context_get_font_map(scin->pc),
+ scin->pc, scf->fontdesc);
+ if ( scf->font == NULL ) {
+ fprintf(stderr, "Couldn't load font.\n");
+ return;
+ }
+
+ /* FIXME: Language for box */
+ metrics = pango_font_get_metrics(scf->font, NULL);
+ scf->ascent = pango_font_metrics_get_ascent(metrics);
+ scf->height = scf->ascent + pango_font_metrics_get_descent(metrics);
+ pango_font_metrics_unref(metrics);
+
+ scf->free_font_on_pop = 1;
+}
+
+
+/* This sets the colour for the font at the top of the stack */
+static void set_colour(SCInterpreter *scin, const char *colour)
+{
+ GdkRGBA col;
+ struct sc_font *scf = &scin->fontstack[scin->n_fonts-1];
+
+ if ( colour == NULL ) {
+ printf("Invalid colour\n");
+ scf->col[0] = 0.0;
+ scf->col[1] = 0.0;
+ scf->col[2] = 0.0;
+ scf->col[3] = 1.0;
+ return;
+ }
+
+ gdk_rgba_parse(&col, colour);
+
+ scf->col[0] = col.red;
+ scf->col[1] = col.green;
+ scf->col[2] = col.blue;
+ scf->col[3] = col.alpha;
+}
+
+
+static void copy_top_font(SCInterpreter *scin)
+{
+ if ( scin->n_fonts == scin->max_fonts ) {
+
+ struct sc_font *stack_new;
+
+ stack_new = realloc(scin->fontstack, sizeof(struct sc_font)
+ * ((scin->max_fonts)+8));
+ if ( stack_new == NULL ) {
+ fprintf(stderr, "Failed to push font or colour.\n");
+ return;
+ }
+
+ scin->fontstack = stack_new;
+ scin->max_fonts += 8;
+
+ }
+
+ /* When n_fonts=0, we leave the first font uninitialised. This allows
+ * the stack to be "bootstrapped", but requires the first caller to do
+ * set_font and set_colour straight away. */
+ if ( scin->n_fonts > 0 ) {
+ scin->fontstack[scin->n_fonts] = scin->fontstack[scin->n_fonts-1];
+ }
+
+ /* This is a copy, so don't free it later */
+ scin->fontstack[scin->n_fonts].free_font_on_pop = 0;
+
+ scin->n_fonts++;
+}
+
+
+static void push_font(SCInterpreter *scin, const char *font_name)
+{
+ copy_top_font(scin);
+ set_font(scin, font_name);
+}
+
+
+static void push_colour(SCInterpreter *scin, const char *colour)
+{
+ copy_top_font(scin);
+ set_colour(scin, colour);
+}
+
+
+static void pop_font_or_colour(SCInterpreter *scin)
+{
+ struct sc_font *scf = &scin->fontstack[scin->n_fonts-1];
+
+ if ( scf->free_font_on_pop ) {
+ pango_font_description_free(scf->fontdesc);
+ }
+
+ scin->n_fonts--;
+}
+
+
+SCInterpreter *sc_interp_new()
+{
+ SCInterpreter *scin;
+
+ scin = malloc(sizeof(SCInterpreter));
+ if ( scin == NULL ) return NULL;
+
+ scin->fontstack = NULL;
+ scin->n_fonts = 0;
+ scin->max_fonts = 0;
+
+ scin->pc = NULL;
+ scin->s_constants = NULL;
+ scin->p_constants = NULL;
+
+ /* FIXME: Determine proper language (somehow...) */
+ scin->lang = pango_language_from_string("en_GB");
+
+ /* The "ultimate" default font */
+ push_font(scin, "Sans 12");
+ set_colour(scin, "#000000");
+
+ return scin;
+}
+
+
+void sc_interp_destroy(SCInterpreter *scin)
+{
+ /* Empty the stack */
+ while ( scin->n_fonts > 0 ) {
+ pop_font_or_colour(scin);
+ }
+
+ free(scin);
+}
+
+
+int sc_interp_add_blocks(SCInterpreter *scin, const SCBlock *bl)
+{
+ struct wrap_line *boxes;
+
+ boxes = malloc(sizeof(struct wrap_line));
+ if ( boxes == NULL ) {
+ fprintf(stderr, "Failed to allocate boxes.\n");
+ return 1;
+ }
+ initialise_line(boxes);
+
+ while ( bl != NULL ) {
+
+ const char *name = sc_block_name(bl);
+ const char *contents = sc_block_contents(bl);
+
+ if ( name == NULL ) {
+ split_words(boxes, scin->pc, contents,
+ scin->lang, 1,
+ &scin->fontstack[scin->n_fonts-1]);
+
+#if 0
+ /* FIXME ... ! */
+
+ } else if ( (strcmp(name, "font")==0) && (contents == NULL) ) {
+ set_font(fonts, b->options, pc);
+
+ } else if ( (strcmp(name, "font")==0) && (contents != NULL) ) {
+ push_font(fonts, b->options, pc);
+ run_sc(b->contents, fonts, pc, boxes, lang, offset,
+ editable, fr, slide_constants,
+ presentation_constants);
+ pop_font_or_colour(fonts);
+
+ } else if ( (strcmp(name, "fgcol")==0)
+ && (contents == NULL) ) {
+ set_colour(fonts, b->options);
+
+ } else if ( (strcmp(name, "fgcol")==0) && (contents != NULL) ) {
+ push_colour(fonts, b->options);
+ run_sc(b->contents, fonts, pc, boxes, lang, offset,
+ editable, fr, slide_constants,
+ presentation_constants);
+ pop_font_or_colour(fonts);
+
+ } else if ( (strcmp(name, "image")==0)
+ && (contents != NULL) && (b->options != NULL) ) {
+ int w, h;
+ if ( get_size(b->options, fr, &w, &h) == 0 ) {
+ add_image_box(boxes, b->contents, offset, w, h,
+ editable);
+ }
+
+ } else if ( strcmp(name, "slidenumber")==0) {
+ char *tmp = malloc(64);
+ if ( tmp != NULL ) {
+ snprintf(tmp, 63, "%i",
+ slide_constants->slide_number);
+ add_wrap_box(boxes, tmp, offset,
+ WRAP_SPACE_NONE, pc,
+ &fonts->stack[fonts->n_fonts-1],
+ 0);
+ } /* else go away and sulk about it */
+#endif
+
+ }
+
+ bl = sc_block_next(bl);
+
+ }
+
+ return 0;
+}
diff --git a/src/sc_interp.h b/src/sc_interp.h
index b5fba5e..ad59193 100644
--- a/src/sc_interp.h
+++ b/src/sc_interp.h
@@ -27,6 +27,17 @@
#include <config.h>
#endif
+
+struct sc_font
+{
+ PangoFontDescription *fontdesc;
+ PangoFont *font;
+ double col[4];
+ int ascent;
+ int height;
+ int free_font_on_pop;
+};
+
typedef struct _scinterp SCInterpreter;
extern SCInterpreter *sc_interp_new(void);
@@ -35,6 +46,6 @@ extern void sc_interp_destroy(SCInterpreter *scin);
extern void sc_interp_save(SCInterpreter *scin);
extern void sc_interp_restore(SCInterpreter *scin);
-extern void sc_interp_run(SCInterpreter *scin, const char *sc);
+extern int sc_interp_add_blocks(SCInterpreter *scin, const SCBlock *bl);
#endif /* SC_INTERP_H */
diff --git a/src/sc_parse.c b/src/sc_parse.c
index bb2a5f5..69755c7 100644
--- a/src/sc_parse.c
+++ b/src/sc_parse.c
@@ -56,6 +56,30 @@ SCBlock *sc_block_new()
}
+SCBlock *sc_block_next(const SCBlock *bl)
+{
+ return bl->next;
+}
+
+
+const char *sc_block_name(const SCBlock *bl)
+{
+ return bl->name;
+}
+
+
+const char *sc_block_options(const SCBlock *bl)
+{
+ return bl->options;
+}
+
+
+const char *sc_block_contents(const SCBlock *bl)
+{
+ return bl->contents;
+}
+
+
/* Insert a new block after "bl". "name", "options" and "contents"
* will not be copied. Returns the block just created, or NULL on error.
* If *blfp points to NULL, it will updated to point at the new block. */
@@ -102,7 +126,7 @@ void sc_block_free(SCBlock *bl)
}
-static void recursive_show_sc_blocks(const char *prefix, SCBlock *bl)
+static void recursive_show_sc_blocks(const char *prefix, const SCBlock *bl)
{
while ( bl != NULL ) {
@@ -125,7 +149,7 @@ static void recursive_show_sc_blocks(const char *prefix, SCBlock *bl)
}
-void show_sc_blocks(SCBlock *bl)
+void show_sc_blocks(const SCBlock *bl)
{
recursive_show_sc_blocks("", bl);
}
@@ -263,6 +287,14 @@ SCBlock *sc_parse(const char *sc)
char *opt = NULL;
char *contents = NULL;
+ /* Is this an escaped backslash? */
+ if ( sc[i+1] == '\\' ) {
+ tbuf[j++] = '\\';
+ i += 2; /* Skip both backslashes */
+ continue;
+ }
+
+ /* No, it's a real block. Dispatch the previous block */
if ( j != 0 ) {
tbuf[j] = '\0';
bl = sc_block_append(bl, NULL, NULL,
diff --git a/src/sc_parse.h b/src/sc_parse.h
index 23bba89..ac4ce35 100644
--- a/src/sc_parse.h
+++ b/src/sc_parse.h
@@ -30,8 +30,14 @@
typedef struct _scblock SCBlock;
extern SCBlock *sc_parse(const char *sc);
+
extern void sc_block_free(SCBlock *bl);
-extern void show_sc_blocks(SCBlock *bl);
+extern SCBlock *sc_block_next(const SCBlock *bl);
+extern const char *sc_block_name(const SCBlock *bl);
+extern const char *sc_block_options(const SCBlock *bl);
+extern const char *sc_block_contents(const SCBlock *bl);
+
+extern void show_sc_blocks(const SCBlock *bl);
#endif /* SC_PARSE_H */
diff --git a/src/shape.c b/src/shape.c
new file mode 100644
index 0000000..93625e0
--- /dev/null
+++ b/src/shape.c
@@ -0,0 +1,234 @@
+/*
+ * shape.c
+ *
+ * Copyright © 2014 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This file is part of Colloquium.
+ *
+ * Colloquium is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pango/pangocairo.h>
+
+#include "wrap.h"
+#include "sc_interp.h"
+#include "shape.h"
+
+
+static void shape_and_measure(gpointer data, gpointer user_data)
+{
+ struct wrap_box *box = user_data;
+ PangoItem *item = data;
+ PangoRectangle rect;
+
+ /* FIXME: Don't assume only one run per wrap box */
+ box->glyphs = pango_glyph_string_new();
+ box->item = item;
+
+ pango_shape(box->text+item->offset, item->length, &item->analysis,
+ box->glyphs);
+
+ pango_glyph_string_extents(box->glyphs, box->font, NULL, &rect);
+
+ box->width += rect.width;
+ if ( rect.height > box->height ) {
+ box->height = rect.height;
+ }
+ if ( PANGO_ASCENT(rect) > box->ascent ) {
+ box->ascent = PANGO_ASCENT(rect);
+ }
+}
+
+
+/* Add "text", followed by a space of type "space", to "line" */
+static int add_wrap_box(struct wrap_line *line, char *text, size_t offset,
+ enum wrap_box_space space, PangoContext *pc,
+ struct sc_font *font, int editable)
+{
+ GList *pango_items;
+ struct wrap_box *box;
+ PangoAttrList *attrs;
+ PangoAttribute *attr;
+
+ if ( line->n_boxes == line->max_boxes ) {
+ line->max_boxes += 32;
+ alloc_boxes(line);
+ if ( line->n_boxes == line->max_boxes ) return 1;
+ }
+
+ box = &line->boxes[line->n_boxes];
+ if ( !editable ) offset = 0;
+ box->sc_offset = offset;
+ box->type = WRAP_BOX_PANGO;
+ box->text = text;
+ box->space = space;
+ box->font = font->font;
+ box->width = 0;
+ box->editable = editable;
+ box->ascent = font->ascent;
+ box->height = font->height;
+ box->col[0] = font->col[0]; /* Red */
+ box->col[1] = font->col[1]; /* Green */
+ box->col[2] = font->col[2]; /* Blue */
+ box->col[3] = font->col[3]; /* Alpha */
+ line->n_boxes++;
+
+ if ( strlen(text) == 0 ) {
+ box->type = WRAP_BOX_NOTHING;
+ return 0;
+ }
+
+ attrs = pango_attr_list_new();
+ attr = pango_attr_font_desc_new(font->fontdesc);
+ pango_attr_list_insert_before(attrs, attr);
+ pango_items = pango_itemize(pc, text, 0, strlen(text), attrs, NULL);
+ g_list_foreach(pango_items, shape_and_measure, box);
+ g_list_free(pango_items);
+ pango_attr_list_unref(attrs);
+
+ return 0;
+}
+
+
+static void add_image_box(struct wrap_line *line, const char *filename,
+ size_t offset, int w, int h, int editable)
+{
+ struct wrap_box *box;
+
+ box = &line->boxes[line->n_boxes];
+ if ( !editable ) offset = 0;
+ box->sc_offset = offset;
+ box->type = WRAP_BOX_IMAGE;
+ box->text = NULL;
+ box->space = WRAP_SPACE_NONE;
+ box->width = pango_units_from_double(w);
+ box->ascent = pango_units_from_double(h);
+ box->height = pango_units_from_double(h);
+ box->filename = strdup(filename);
+ box->editable = editable;
+ line->n_boxes++;
+}
+
+
+int split_words(struct wrap_line *boxes, PangoContext *pc, const char *text,
+ PangoLanguage *lang, int editable, struct sc_font *font)
+{
+ PangoLogAttr *log_attrs;
+ glong len_chars, i;
+ size_t len_bytes, start;
+
+ /* Empty block? */
+ if ( text == NULL ) return 1;
+
+ len_chars = g_utf8_strlen(text, -1);
+ if ( len_chars == 0 ) return 1;
+
+ len_bytes = strlen(text);
+
+ log_attrs = malloc((len_chars+1)*sizeof(PangoLogAttr));
+ if ( log_attrs == NULL ) return 1;
+
+ /* Create glyph string */
+ pango_get_log_attrs(text, len_bytes, -1, lang, log_attrs, len_chars+1);
+
+ start = 0;
+ for ( i=0; i<len_chars; i++ ) {
+
+ if ( log_attrs[i].is_line_break ) {
+
+ char *word;
+ enum wrap_box_space type;
+ size_t len;
+ char *ptr;
+ size_t offs;
+
+ ptr = g_utf8_offset_to_pointer(text, i);
+ offs = ptr - text;
+
+ /* Stuff up to (but not including) sc[i] forms a
+ * wrap box */
+ len = offs - start;
+ if ( log_attrs[i].is_mandatory_break ) {
+ type = WRAP_SPACE_EOP;
+ if ( (offs>0) && (text[offs-1] == '\n') ) len--;
+ if ( (offs>0) && (text[offs-1] == '\r') ) len--;
+ } else if ( (i>0)
+ && log_attrs[i-1].is_expandable_space ) {
+ type = WRAP_SPACE_INTERWORD;
+ len--; /* Not interested in spaces */
+ } else {
+ type = WRAP_SPACE_NONE;
+ }
+
+ word = strndup(text+start, len);
+ if ( word == NULL ) {
+ fprintf(stderr, "strndup() failed.\n");
+ free(log_attrs);
+ return 1;
+ }
+
+ if ( add_wrap_box(boxes, word, start, type,
+ pc, font, editable) ) {
+ fprintf(stderr, "Failed to add wrap box.\n");
+ }
+ start = offs;
+
+ }
+
+ }
+ if ( i > start ) {
+
+ char *word;
+ size_t l;
+
+ word = strdup(text+start); /* to the end */
+ if ( word == NULL ) {
+ fprintf(stderr, "strndup() failed.\n");
+ free(log_attrs);
+ return 1;
+ }
+ l = strlen(word);
+
+ if ( (word[l-1] == '\n') ) {
+
+ /* There is a newline at the end of the SC */
+ char *word2;
+
+ word2 = strndup(word, l-1);
+ add_wrap_box(boxes, word2, start,
+ WRAP_SPACE_EOP, pc, font, editable);
+ add_wrap_box(boxes, strdup(""), len_bytes,
+ WRAP_SPACE_NONE, pc, font, editable);
+
+ } else {
+
+ add_wrap_box(boxes, word, start,
+ WRAP_SPACE_NONE, pc, font, editable);
+
+ }
+
+ }
+
+ free(log_attrs);
+ return 0;
+}
diff --git a/src/shape.h b/src/shape.h
new file mode 100644
index 0000000..3e218f4
--- /dev/null
+++ b/src/shape.h
@@ -0,0 +1,38 @@
+/*
+ * shape.h
+ *
+ * Copyright © 2014 Thomas White <taw@bitwiz.org.uk>
+ *
+ * This file is part of Colloquium.
+ *
+ * Colloquium is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SHAPE_H
+#define SHAPE_H
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pango/pangocairo.h>
+
+#include "wrap.h"
+
+extern int split_words(struct wrap_line *boxes, PangoContext *pc,
+ const char *text, PangoLanguage *lang, int editable,
+ struct sc_font *font);
+
+#endif /* SHAPE_H */
diff --git a/src/wrap.c b/src/wrap.c
index b77769a..25f5d4d 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -3,7 +3,7 @@
*
* Text wrapping, hyphenation, justification and shaping
*
- * Copyright © 2013 Thomas White <taw@bitwiz.org.uk>
+ * Copyright © 2013-2014 Thomas White <taw@bitwiz.org.uk>
*
* This file is part of Colloquium.
*
@@ -35,6 +35,7 @@
#include <gdk/gdk.h>
#include "sc_parse.h"
+#include "sc_interp.h"
#include "wrap.h"
#include "frame.h"
#include "presentation.h"
@@ -54,7 +55,7 @@ static void alloc_lines(struct frame *fr)
}
-static void alloc_boxes(struct wrap_line *l)
+void alloc_boxes(struct wrap_line *l)
{
struct wrap_box *boxes_new;
@@ -68,7 +69,7 @@ static void alloc_boxes(struct wrap_line *l)
}
-static void initialise_line(struct wrap_line *l)
+void initialise_line(struct wrap_line *l)
{
l->n_boxes = 0;
l->max_boxes = 32;
@@ -112,7 +113,7 @@ static struct wrap_line *get_cursor_line(struct frame *fr, size_t pos,
}
*yposd /= PANGO_SCALE;
- *yposd += fr->lop.pad_t;
+ *yposd += fr->pad_t;
return &fr->lines[line];
}
@@ -146,7 +147,7 @@ void get_cursor_pos(struct frame *fr, size_t pos,
}
box--;
- *xposd = fr->lop.pad_l;
+ *xposd = fr->pad_l;
for ( i=0; i<box; i++ ) {
*xposd += pango_units_to_double(l->boxes[i].width);
*xposd += pango_units_to_double(l->boxes[i].sp);
@@ -181,7 +182,7 @@ static struct wrap_line *find_cursor_line(struct frame *fr, double yposd,
int *end)
{
int i;
- double y = fr->lop.pad_t;
+ double y = fr->pad_t;
*end = 0;
@@ -202,7 +203,7 @@ static struct wrap_box *find_cursor_box(struct frame *fr, struct wrap_line *l,
double xposd, double *x_pos, int *end)
{
int i;
- double x = fr->lop.pad_l;
+ double x = fr->pad_l;
*end = 0;
@@ -269,31 +270,6 @@ size_t find_cursor_pos(struct frame *fr, double xposd, double yposd)
}
-static void shape_and_measure(gpointer data, gpointer user_data)
-{
- struct wrap_box *box = user_data;
- PangoItem *item = data;
- PangoRectangle rect;
-
- /* FIXME: Don't assume only one run per wrap box */
- box->glyphs = pango_glyph_string_new();
- box->item = item;
-
- pango_shape(box->text+item->offset, item->length, &item->analysis,
- box->glyphs);
-
- pango_glyph_string_extents(box->glyphs, box->font, NULL, &rect);
-
- box->width += rect.width;
- if ( rect.height > box->height ) {
- box->height = rect.height;
- }
- if ( PANGO_ASCENT(rect) > box->ascent ) {
- box->ascent = PANGO_ASCENT(rect);
- }
-}
-
-
static void calc_line_geometry(struct wrap_line *line)
{
int i;
@@ -313,313 +289,6 @@ static void calc_line_geometry(struct wrap_line *line)
}
-struct sc_font
-{
- PangoFontDescription *fontdesc;
- PangoFont *font;
- double col[4];
- int ascent;
- int height;
- int free_font_on_pop;
-};
-
-
-/* Add "text", followed by a space of type "space", to "line" */
-static int add_wrap_box(struct wrap_line *line, char *text, size_t offset,
- enum wrap_box_space space, PangoContext *pc,
- struct sc_font *font, int editable)
-{
- GList *pango_items;
- struct wrap_box *box;
- PangoAttrList *attrs;
- PangoAttribute *attr;
-
- if ( line->n_boxes == line->max_boxes ) {
- line->max_boxes += 32;
- alloc_boxes(line);
- if ( line->n_boxes == line->max_boxes ) return 1;
- }
-
- box = &line->boxes[line->n_boxes];
- if ( !editable ) offset = 0;
- box->sc_offset = offset;
- box->type = WRAP_BOX_PANGO;
- box->text = text;
- box->space = space;
- box->font = font->font;
- box->width = 0;
- box->editable = editable;
- box->ascent = font->ascent;
- box->height = font->height;
- box->col[0] = font->col[0]; /* Red */
- box->col[1] = font->col[1]; /* Green */
- box->col[2] = font->col[2]; /* Blue */
- box->col[3] = font->col[3]; /* Alpha */
- line->n_boxes++;
-
- if ( strlen(text) == 0 ) {
- box->type = WRAP_BOX_NOTHING;
- return 0;
- }
-
- attrs = pango_attr_list_new();
- attr = pango_attr_font_desc_new(font->fontdesc);
- pango_attr_list_insert_before(attrs, attr);
- pango_items = pango_itemize(pc, text, 0, strlen(text), attrs, NULL);
- g_list_foreach(pango_items, shape_and_measure, box);
- g_list_free(pango_items);
- pango_attr_list_unref(attrs);
-
- return 0;
-}
-
-
-static void add_image_box(struct wrap_line *line, const char *filename,
- size_t offset, int w, int h, int editable)
-{
- struct wrap_box *box;
-
- box = &line->boxes[line->n_boxes];
- if ( !editable ) offset = 0;
- box->sc_offset = offset;
- box->type = WRAP_BOX_IMAGE;
- box->text = NULL;
- box->space = WRAP_SPACE_NONE;
- box->width = pango_units_from_double(w);
- box->ascent = pango_units_from_double(h);
- box->height = pango_units_from_double(h);
- box->filename = strdup(filename);
- box->editable = editable;
- line->n_boxes++;
-}
-
-
-static int split_words(struct wrap_line *boxes, PangoContext *pc, char *sc,
- size_t sc_offset, PangoLanguage *lang, int editable,
- struct sc_font *font)
-{
- PangoLogAttr *log_attrs;
- glong len_chars, i;
- size_t len_bytes, start;
-
- /* Empty block? */
- if ( sc == NULL ) return 1;
-
- len_chars = g_utf8_strlen(sc, -1);
- if ( len_chars == 0 ) return 1;
-
- len_bytes = strlen(sc);
-
- log_attrs = malloc((len_chars+1)*sizeof(PangoLogAttr));
- if ( log_attrs == NULL ) return 1;
-
- /* Create glyph string */
- pango_get_log_attrs(sc, len_bytes, -1, lang, log_attrs, len_chars+1);
-
- start = 0;
- for ( i=0; i<len_chars; i++ ) {
-
- if ( log_attrs[i].is_line_break ) {
-
- char *word;
- enum wrap_box_space type;
- size_t len;
- char *ptr;
- size_t offs;
-
- ptr = g_utf8_offset_to_pointer(sc, i);
- offs = ptr - sc;
-
- /* Stuff up to (but not including) sc[i] forms a
- * wrap box */
- len = offs - start;
- if ( log_attrs[i].is_mandatory_break ) {
- type = WRAP_SPACE_EOP;
- if ( (offs>0) && (sc[offs-1] == '\n') ) len--;
- if ( (offs>0) && (sc[offs-1] == '\r') ) len--;
- } else if ( (i>0)
- && log_attrs[i-1].is_expandable_space ) {
- type = WRAP_SPACE_INTERWORD;
- len--; /* Not interested in spaces */
- } else {
- type = WRAP_SPACE_NONE;
- }
-
- word = strndup(sc+start, len);
- if ( word == NULL ) {
- fprintf(stderr, "strndup() failed.\n");
- free(log_attrs);
- return 1;
- }
-
- if ( add_wrap_box(boxes, word, start+sc_offset, type,
- pc, font, editable) ) {
- fprintf(stderr, "Failed to add wrap box.\n");
- }
- start = offs;
-
- }
-
- }
- if ( i > start ) {
-
- char *word;
- size_t l;
-
- word = strdup(sc+start); /* to the end */
- if ( word == NULL ) {
- fprintf(stderr, "strndup() failed.\n");
- free(log_attrs);
- return 1;
- }
- l = strlen(word);
-
- if ( (word[l-1] == '\n') ) {
-
- /* There is a newline at the end of the SC */
- char *word2;
-
- word2 = strndup(word, l-1);
- add_wrap_box(boxes, word2, start+sc_offset,
- WRAP_SPACE_EOP, pc, font, editable);
- add_wrap_box(boxes, strdup(""), len_bytes+sc_offset,
- WRAP_SPACE_NONE, pc, font, editable);
-
- } else {
-
- add_wrap_box(boxes, word, start+sc_offset,
- WRAP_SPACE_NONE, pc, font, editable);
-
- }
-
- }
-
- free(log_attrs);
- return 0;
-}
-
-
-struct sc_font_stack
-{
- struct sc_font *stack;
- int n_fonts;
- int max_fonts;
-};
-
-
-static void set_font(struct sc_font_stack *stack, const char *font_name,
- PangoContext *pc)
-{
- PangoFontMetrics *metrics;
- struct sc_font *scf;
-
- scf = &stack->stack[stack->n_fonts-1];
-
- scf->fontdesc = pango_font_description_from_string(font_name);
- if ( scf->fontdesc == NULL ) {
- fprintf(stderr, "Couldn't describe font.\n");
- return;
- }
- scf->font = pango_font_map_load_font(pango_context_get_font_map(pc),
- pc, scf->fontdesc);
- if ( scf->font == NULL ) {
- fprintf(stderr, "Couldn't load font.\n");
- return;
- }
-
- /* FIXME: Language for box */
- metrics = pango_font_get_metrics(scf->font, NULL);
- scf->ascent = pango_font_metrics_get_ascent(metrics);
- scf->height = scf->ascent + pango_font_metrics_get_descent(metrics);
- pango_font_metrics_unref(metrics);
-
- scf->free_font_on_pop = 1;
-}
-
-
-/* This sets the colour for the font at the top of the stack */
-static void set_colour(struct sc_font_stack *stack, const char *colour)
-{
- GdkRGBA col;
- struct sc_font *scf = &stack->stack[stack->n_fonts-1];
-
- if ( colour == NULL ) {
- printf("Invalid colour\n");
- scf->col[0] = 0.0;
- scf->col[1] = 0.0;
- scf->col[2] = 0.0;
- scf->col[3] = 1.0;
- return;
- }
-
- gdk_rgba_parse(&col, colour);
-
- scf->col[0] = col.red;
- scf->col[1] = col.green;
- scf->col[2] = col.blue;
- scf->col[3] = col.alpha;
-}
-
-
-static void copy_top_font(struct sc_font_stack *stack)
-{
- if ( stack->n_fonts == stack->max_fonts ) {
-
- struct sc_font *stack_new;
-
- stack_new = realloc(stack->stack, sizeof(struct sc_font)
- * ((stack->max_fonts)+8));
- if ( stack_new == NULL ) {
- fprintf(stderr, "Failed to push font or colour.\n");
- return;
- }
-
- stack->stack = stack_new;
- stack->max_fonts += 8;
-
- }
-
- /* When n_fonts=0, we leave the first font uninitialised. This allows
- * the stack to be "bootstrapped", but requires the first caller to do
- * set_font and set_colour straight away. */
- if ( stack->n_fonts > 0 ) {
- stack->stack[stack->n_fonts] = stack->stack[stack->n_fonts-1];
- }
-
- /* This is a copy, so don't free it later */
- stack->stack[stack->n_fonts].free_font_on_pop = 0;
-
- stack->n_fonts++;
-}
-
-
-static void push_font(struct sc_font_stack *stack, const char *font_name,
- PangoContext *pc)
-{
- copy_top_font(stack);
- set_font(stack, font_name, pc);
-}
-
-
-static void push_colour(struct sc_font_stack *stack, const char *colour)
-{
- copy_top_font(stack);
- set_colour(stack, colour);
-}
-
-
-static void pop_font_or_colour(struct sc_font_stack *stack)
-{
- struct sc_font *scf = &stack->stack[stack->n_fonts-1];
-
- if ( scf->free_font_on_pop ) {
- pango_font_description_free(scf->fontdesc);
- }
-
- stack->n_fonts--;
-}
-
-
static int get_size(const char *a, struct frame *fr, int *wp, int *hp)
{
char *x;
@@ -635,12 +304,12 @@ static int get_size(const char *a, struct frame *fr, int *wp, int *hp)
hs = strdup(x+1);
if ( strcmp(ws, "fit") == 0 ) {
- *wp = fr->w - (fr->lop.pad_l+fr->lop.pad_r);
+ *wp = fr->w - (fr->pad_l+fr->pad_r);
} else {
*wp = strtoul(ws, NULL, 10);
}
if ( strcmp(ws, "fit") == 0 ) {
- *hp = fr->h - (fr->lop.pad_t+fr->lop.pad_b);
+ *hp = fr->h - (fr->pad_t+fr->pad_b);
} else {
*hp = strtoul(hs, NULL, 10);
}
@@ -656,128 +325,6 @@ invalid:
}
-static void run_sc(const char *sc, struct sc_font_stack *fonts,
- PangoContext *pc, struct wrap_line *boxes,
- PangoLanguage *lang, size_t g_offset, int editable,
- struct frame *fr, struct slide_constants *slide_constants,
- struct presentation_constants *presentation_constants)
-{
- SCBlockList *bl;
- SCBlockListIterator *iter;
- struct scblock *b;
-
- bl = sc_find_blocks(sc, NULL);
-
- if ( bl == NULL ) {
- printf("Failed to find blocks.\n");
- return;
- }
-
- for ( b = sc_block_list_first(bl, &iter);
- b != NULL;
- b = sc_block_list_next(bl, iter) )
- {
- size_t offset = b->offset + g_offset;
-
- if ( b->name == NULL ) {
- split_words(boxes, pc, b->contents, offset,
- lang, editable,
- &fonts->stack[fonts->n_fonts-1]);
-
- } else if ( (strcmp(b->name, "font")==0)
- && (b->contents == NULL) ) {
- set_font(fonts, b->options, pc);
-
- } else if ( (strcmp(b->name, "font")==0)
- && (b->contents != NULL) ) {
- push_font(fonts, b->options, pc);
- run_sc(b->contents, fonts, pc, boxes, lang, offset,
- editable, fr, slide_constants,
- presentation_constants);
- pop_font_or_colour(fonts);
-
- } else if ( (strcmp(b->name, "fgcol")==0)
- && (b->contents == NULL) ) {
- set_colour(fonts, b->options);
-
- } else if ( (strcmp(b->name, "fgcol")==0)
- && (b->contents != NULL) ) {
- push_colour(fonts, b->options);
- run_sc(b->contents, fonts, pc, boxes, lang, offset,
- editable, fr, slide_constants,
- presentation_constants);
- pop_font_or_colour(fonts);
-
- } else if ( (strcmp(b->name, "image")==0)
- && (b->contents != NULL) && (b->options != NULL) ) {
- int w, h;
- if ( get_size(b->options, fr, &w, &h) == 0 ) {
- add_image_box(boxes, b->contents, offset, w, h,
- editable);
- }
-
- } else if ( strcmp(b->name, "slidenumber")==0) {
- char *tmp = malloc(64);
- if ( tmp != NULL ) {
- snprintf(tmp, 63, "%i",
- slide_constants->slide_number);
- add_wrap_box(boxes, tmp, offset,
- WRAP_SPACE_NONE, pc,
- &fonts->stack[fonts->n_fonts-1],
- 0);
- } /* else go away and sulk about it */
- }
-
- }
- sc_block_list_free(bl);
-}
-
-
-static struct wrap_line *sc_to_wrap_boxes(const char *sc, const char *prefix,
- PangoContext *pc, struct frame *fr,
- struct slide_constants *s_constants,
- struct presentation_constants *p_constants)
-{
- struct wrap_line *boxes;
- PangoLanguage *lang;
- struct sc_font_stack fonts;
-
- boxes = malloc(sizeof(struct wrap_line));
- if ( boxes == NULL ) {
- fprintf(stderr, "Failed to allocate boxes.\n");
- return NULL;
- }
- initialise_line(boxes);
-
- fonts.stack = NULL;
- fonts.n_fonts = 0;
- fonts.max_fonts = 0;
-
- /* FIXME: Determine proper language (somehow...) */
- lang = pango_language_from_string("en_GB");
-
- /* The "ultimate" default font */
- push_font(&fonts, "Sans 12", pc);
- set_colour(&fonts, "#000000");
-
- if ( prefix != NULL ) {
- run_sc(prefix, &fonts, pc, boxes, lang, 0, 0, fr,
- s_constants, p_constants);
- }
- if ( sc != NULL ) {
- run_sc(sc, &fonts, pc, boxes, lang, 0, 1, fr,
- s_constants, p_constants);
- }
-
- /* Empty the stack */
- while ( fonts.n_fonts > 0 ) {
- pop_font_or_colour(&fonts);
- }
-
- return boxes;
-}
-
-
/* Normal width of space */
static double sp_x(enum wrap_box_space s)
{
@@ -1256,29 +803,12 @@ void show_boxes(struct wrap_line *boxes)
/* Wrap the StoryCode inside "fr->sc" so that it fits within width "fr->w",
* and generate fr->lines */
-int wrap_contents(struct frame *fr, PangoContext *pc,
- struct slide_constants *scc,
- struct presentation_constants *pcc)
+int wrap_contents(struct frame *fr, struct wrap_line *boxes)
{
- struct wrap_line *boxes;
struct wrap_line *para;
int i;
const double rho = 2.0;
- const double wrap_w = fr->w - fr->lop.pad_l - fr->lop.pad_r;
- char *prologue;
-
- if ( fr->style != NULL ) {
- prologue = fr->style->sc_prologue;
- } else {
- prologue = NULL;
- }
-
- /* Turn the StoryCode into wrap boxes, all on one line */
- boxes = sc_to_wrap_boxes(fr->sc, prologue, pc, fr, scc, pcc);
- if ( boxes == NULL ) {
- fprintf(stderr, "Failed to create wrap boxes.\n");
- return 1;
- }
+ const double wrap_w = fr->w - fr->pad_l - fr->pad_r;
/* Clear lines */
fr->n_lines = 0;
diff --git a/src/wrap.h b/src/wrap.h
index 8da2f99..f29e0dc 100644
--- a/src/wrap.h
+++ b/src/wrap.h
@@ -99,15 +99,16 @@ struct wrap_line
};
-extern int wrap_contents(struct frame *fr, PangoContext *pc,
- struct slide_constants *scc,
- struct presentation_constants *pcc);
+extern int wrap_contents(struct frame *fr, struct wrap_line *boxes);
extern void get_cursor_pos(struct frame *fr, size_t pos,
double *xposd, double *yposd, double *line_height);
extern size_t find_cursor_pos(struct frame *fr, double xposd, double yposd);
+extern void alloc_boxes(struct wrap_line *l);
+extern void initialise_line(struct wrap_line *l);
+
extern void wrap_line_free(struct wrap_line *l);
extern void show_boxes(struct wrap_line *boxes);
diff --git a/tests/render_test.c b/tests/render_test.c
index 6d5bcec..e2bf0d7 100644
--- a/tests/render_test.c
+++ b/tests/render_test.c
@@ -34,11 +34,12 @@
#include "../src/sc_parse.h"
#include "../src/render.h"
-#include "../src/stylesheet.h"
#include "../src/frame.h"
#include "../src/presentation.h"
+const char *sc = "\\font[Sorts Mill Goudy 32]Lorem ipsum dolor sit amet, consect-etur adipiscing elit.\n\\font[Serif 17]Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. \\font[Edrip 32]{Nam tincidunt congue enim, ut porta lorem \\font[Edrip Bold 32]{lacinia} consectetur.} Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. \\font[Serif Bold 17]{Cum sociis natoque penatibus et magnis dis parturient} montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.";
+
static gint mw_destroy(GtkWidget *w, void *p)
{
gtk_main_quit();
@@ -73,66 +74,20 @@ int main(int argc, char *argv[])
GtkWidget *window;
GtkWidget *drawingarea;
struct frame *fr;
- struct frame *fr2;
- struct style *sty1;
- struct style *sty2;
struct slide s;
struct presentation p;
gtk_init(&argc, &argv);
- sty1 = calloc(1, sizeof(struct style));
- sty1->lop.pad_l = 0.0;
- sty1->lop.pad_r = 0.0;
- sty1->lop.pad_t = 0.0;
- sty1->lop.pad_b = 0.0;
- sty1->lop.margin_l = 0.0;
- sty1->lop.margin_r = 0.0;
- sty1->lop.margin_t = 0.0;
- sty1->lop.margin_b = 0.0;
- sty1->lop.x = 0.0;
- sty1->lop.y = 0.0;
- sty1->lop.w = 1.0;
- sty1->lop.w_units = UNITS_FRAC;
- sty1->lop.h = 1.0;
- sty1->lop.h_units = UNITS_FRAC;
- sty1->name = strdup("Default");
-
- sty2 = calloc(1, sizeof(struct style));
- sty2->lop.pad_l = 10.0;
- sty2->lop.pad_r = 10.0;
- sty2->lop.pad_t = 10.0;
- sty2->lop.pad_b = 10.0;
- sty2->lop.margin_l = 5.0;
- sty2->lop.margin_r = 5.0;
- sty2->lop.margin_t = 5.0;
- sty2->lop.margin_b = 5.0;
- sty2->lop.x = 0.0;
- sty2->lop.y = 0.0;
- sty2->lop.w = 1.0;
- sty2->lop.w_units = UNITS_FRAC;
- sty2->lop.h = 1.0;
- sty2->lop.h_units = UNITS_FRAC;
- sty2->name = strdup("Text frame");
-
- fr2 = calloc(1, sizeof(struct frame));
- if ( fr2 == NULL ) return 1;
- fr2->sc = "\\font[Sorts Mill Goudy 32]Lorem ipsum dolor sit amet, consect-etur adipiscing elit.\n\\font[Serif 17]Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. \\font[Edrip 32]{Nam tincidunt congue enim, ut porta lorem \\font[Edrip Bold 32]{lacinia} consectetur.} Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. \\font[Serif Bold 17]{Cum sociis natoque penatibus et magnis dis parturient} montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.";
- //fr2->sc = "Lorem ipsum AT";
- fr2->children = NULL;
- fr2->num_children = 0;
- fr2->style = sty2;
- fr2->lop_from_style = 1;
-
fr = calloc(1, sizeof(struct frame));
if ( fr == NULL ) return 1;
- fr->sc = "";
- fr->children = calloc(2, sizeof(struct frame *));
- if ( fr->children == NULL ) return 1;
- fr->children[0] = fr2;
- fr->style = sty1;
- fr->lop_from_style = 1;
- fr->num_children = 1;
+ fr->children = NULL;
+ fr->num_children = 0;
+ fr->scblocks = sc_parse(sc);
+ if ( fr->scblocks == NULL ) {
+ fprintf(stderr, "SC parse failed.\n");
+ return 1;
+ }
s.top = fr;
s.rendered_edit = NULL;
diff --git a/tests/storycode_test.c b/tests/storycode_test.c
index 7d73c41..1cd4d61 100644
--- a/tests/storycode_test.c
+++ b/tests/storycode_test.c
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
"\\wibble{}\\f{wibble \\bg[muhu]{wobble}}\\frib[\\f] f");
if ( r ) v = 1;
- r = test_sc("A B C \\wibble");
+ r = test_sc("A B C \\wibble\\\\w");
if ( r ) v = 1;
return v;