aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2016-03-14 23:24:00 +0100
committerThomas White <taw@bitwiz.org.uk>2016-03-14 23:24:00 +0100
commit8d69fd3d476179768d9e13d79261c5a1a7cacda4 (patch)
treecc4ab748be126479be943eeb4d1854a045d5a6d8 /src
parentc900972b5752c6fd10ca01a5789dc969f2648811 (diff)
Fix frame creation
Diffstat (limited to 'src')
-rw-r--r--src/frame.c15
-rw-r--r--src/frame.h5
-rw-r--r--src/sc_editor.c21
-rw-r--r--src/sc_interp.c2
-rw-r--r--src/sc_parse.c4
-rw-r--r--src/shape.c71
-rw-r--r--src/shape.h2
-rw-r--r--src/wrap.h1
8 files changed, 91 insertions, 30 deletions
diff --git a/src/frame.c b/src/frame.c
index c1dfd39..5b932e6 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -195,3 +195,18 @@ void delete_subframe(struct frame *top, struct frame *fr)
parent->num_children--;
}
+
+struct frame *find_frame_with_scblocks(struct frame *fr, SCBlock *scblocks)
+{
+ int i;
+
+ if ( fr->scblocks == scblocks ) return fr;
+
+ for ( i=0; i<fr->num_children; i++ ) {
+ struct frame *tt;
+ tt = find_frame_with_scblocks(fr->children[i], scblocks);
+ if ( tt != NULL ) return tt;
+ }
+
+ return NULL;
+}
diff --git a/src/frame.h b/src/frame.h
index 11ad36b..cd1bfa4 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -66,6 +66,9 @@ struct frame
int max_lines;
struct wrap_line *lines;
+ /* The font which will be used by default for this frame */
+ PangoFontDescription *fontdesc;
+
/* The rectangle allocated to this frame, determined by the renderer */
double x;
double y;
@@ -101,5 +104,7 @@ extern void frame_free(struct frame *fr);
extern struct frame *add_subframe(struct frame *fr);
extern void show_hierarchy(struct frame *fr, const char *t);
extern void delete_subframe(struct frame *top, struct frame *fr);
+extern struct frame *find_frame_with_scblocks(struct frame *top,
+ SCBlock *scblocks);
#endif /* FRAME_H */
diff --git a/src/sc_editor.c b/src/sc_editor.c
index ce467f7..c2942f9 100644
--- a/src/sc_editor.c
+++ b/src/sc_editor.c
@@ -876,6 +876,7 @@ static void insert_text(char *t, SCEditor *e)
sbox->col[1] = 0.0;
sbox->col[2] = 0.0;
sbox->col[3] = 0.0;
+ sbox->fontdesc = fr->fontdesc;
sbox->n_segs = 1;
sbox->segs = malloc(sizeof(struct text_seg));
sbox->len_chars = 0;
@@ -896,6 +897,10 @@ static void insert_text(char *t, SCEditor *e)
sc_insert_text(sbox->scblock, sps+sbox->offs_char, t);
+ /* The box must be analysed by Pango again, because the segments
+ * might have changed */
+ itemize_and_shape(sbox, e->pc);
+
text = sc_block_contents(sbox->scblock);
len_bytes = strlen(text);
len_chars = g_utf8_strlen(text, -1);
@@ -907,7 +912,7 @@ static void insert_text(char *t, SCEditor *e)
offs = sbox->offs_char + e->cursor_pos;
- if ( (len_chars > 0) && log_attrs[offs+1].is_line_break ) {
+ if ( (len_chars > 1) && log_attrs[offs+1].is_line_break ) {
struct wrap_box *nbox;
@@ -1360,6 +1365,7 @@ static struct frame *create_frame(SCEditor *e, double x, double y,
{
struct frame *parent;
struct frame *fr;
+ SCBlock *scblocks;
parent = e->top;
@@ -1373,12 +1379,13 @@ static struct frame *create_frame(SCEditor *e, double x, double y,
h = -h;
}
+ /* Add to frame structure */
fr = add_subframe(parent);
/* Add to SC */
- fr->scblocks = sc_block_append_end(e->scblocks,
- "f", NULL, NULL);
- sc_block_append_inside(fr->scblocks, NULL, NULL, strdup(""));
+ scblocks = sc_block_append_end(e->scblocks, "f", NULL, NULL);
+ fr->scblocks = scblocks;
+ sc_block_append_inside(scblocks, NULL, NULL, strdup(""));
fr->x = x;
fr->y = y;
@@ -1388,12 +1395,10 @@ static struct frame *create_frame(SCEditor *e, double x, double y,
fr->empty = 1;
fr->resizable = 1;
- fr->n_lines = 0;
- fr->lines = NULL;
-
update_geom(fr);
- return fr;
+ full_rerender(e);
+ return find_frame_with_scblocks(e->top, scblocks);
}
diff --git a/src/sc_interp.c b/src/sc_interp.c
index 50a582b..9226c76 100644
--- a/src/sc_interp.c
+++ b/src/sc_interp.c
@@ -834,6 +834,8 @@ static int check_outputs(SCBlock *bl, SCInterpreter *scin)
return 1;
}
+ fr->fontdesc = sc_interp_get_fontdesc(scin);
+
parse_frame_options(fr, sc_interp_get_frame(scin),
options);
diff --git a/src/sc_parse.c b/src/sc_parse.c
index ef9f3da..60a03ff 100644
--- a/src/sc_parse.c
+++ b/src/sc_parse.c
@@ -556,6 +556,10 @@ SCBlock *find_last_child(SCBlock *bl)
void sc_insert_text(SCBlock *b1, int o1, const char *t)
{
+ if ( b1->contents == NULL ) {
+ b1->contents = strdup(t);
+ return;
+ }
size_t len = strlen(b1->contents)+1+strlen(t);
char *cnew = realloc(b1->contents, len);
char *tmp = malloc(len);
diff --git a/src/shape.c b/src/shape.c
index 2b6bc7a..bbbea87 100644
--- a/src/shape.c
+++ b/src/shape.c
@@ -42,6 +42,11 @@ static void shape_segment(struct wrap_box *box, struct text_seg *seg)
const char *tp;
const char *ep;
+ if ( seg->len_chars == 0 ) {
+ fprintf(stderr, "Shaping a zero-length segment\n");
+ return;
+ }
+
tp = g_utf8_offset_to_pointer(sc_block_contents(box->scblock),
box->offs_char + seg->offs_char);
ep = g_utf8_offset_to_pointer(sc_block_contents(box->scblock),
@@ -184,19 +189,52 @@ static void add_seg(gpointer vi, gpointer vb)
}
+int itemize_and_shape(struct wrap_box *box, PangoContext *pc)
+{
+ GList *pango_items;
+ PangoAttrList *attrs;
+ PangoAttribute *attr;
+ char *tptr;
+ char *eptr;
+ const char *text;
+ int nseg;
+
+ text = sc_block_contents(box->scblock);
+ tptr = g_utf8_offset_to_pointer(text, box->offs_char);
+ eptr = g_utf8_offset_to_pointer(tptr, box->len_chars);
+
+ /* Fill in the font, needed later for rendering */
+ box->font = pango_font_map_load_font(pango_context_get_font_map(pc),
+ pc, box->fontdesc);
+
+ attrs = pango_attr_list_new();
+ attr = pango_attr_font_desc_new(box->fontdesc);
+ pango_attr_list_insert_before(attrs, attr);
+ pango_items = pango_itemize(pc, tptr, 0, eptr-tptr, attrs, NULL);
+ nseg = g_list_length(pango_items);
+ box->segs = malloc(nseg * sizeof(struct text_seg));
+ if ( box->segs == NULL ) return 1;
+
+ box->n_segs = 0;
+ g_list_foreach(pango_items, add_seg, box);
+ g_list_free(pango_items);
+ pango_attr_list_unref(attrs);
+
+ calc_box_geometry(box);
+
+ return 0;
+}
+
+
/* Add "text", followed by a space of type "space", to "line" */
static int add_text_box(struct boxvec *boxes,
enum wrap_box_space space, PangoContext *pc,
SCInterpreter *scin, SCBlock *bl, size_t offs,
size_t len, int editable)
{
- GList *pango_items;
struct wrap_box *box;
- PangoAttrList *attrs;
- PangoAttribute *attr;
const char *tp;
double *col;
- int nseg;
while ( len==0 ) {
add_nothing_box(boxes, bl, editable, space, scin, offs);
@@ -212,7 +250,7 @@ static int add_text_box(struct boxvec *boxes,
box->type = WRAP_BOX_PANGO;
box->space = space;
- box->font = sc_interp_get_font(scin);
+ box->fontdesc = pango_font_description_copy(sc_interp_get_fontdesc(scin));
box->width = 0;
box->editable = editable;
box->ascent = sc_interp_get_ascent(scin);
@@ -230,23 +268,12 @@ static int add_text_box(struct boxvec *boxes,
box->col[2] = col[2]; /* Blue */
box->col[3] = col[3]; /* Alpha */
- attrs = pango_attr_list_new();
- attr = pango_attr_font_desc_new(sc_interp_get_fontdesc(scin));
- pango_attr_list_insert_before(attrs, attr);
- pango_items = pango_itemize(pc, sc_block_contents(bl)+offs,
- 0, len, attrs, NULL);
- nseg = g_list_length(pango_items);
- box->segs = malloc(nseg * sizeof(struct text_seg));
- if ( box->segs == NULL ) return 1;
-
- box->n_segs = 0;
- g_list_foreach(pango_items, add_seg, box);
- g_list_free(pango_items);
- pango_attr_list_unref(attrs);
-
- calc_box_geometry(box);
-
- bv_add(boxes, box);
+ if ( itemize_and_shape(box, pc) == 0 ) {
+ bv_add(boxes, box);
+ } else {
+ fprintf(stderr, "Shaping error!\n");
+ return 1;
+ }
return 0;
}
diff --git a/src/shape.h b/src/shape.h
index 43775a3..f9e1758 100644
--- a/src/shape.h
+++ b/src/shape.h
@@ -37,6 +37,8 @@ extern int split_words(struct boxvec *boxes, PangoContext *pc,
SCBlock *bl, PangoLanguage *lang,
int editable, SCInterpreter *scin);
+extern int itemize_and_shape(struct wrap_box *box, PangoContext *pc);
+
extern void add_image_box(struct boxvec *line, const char *filename,
int w, int h, int editable);
diff --git a/src/wrap.h b/src/wrap.h
index 0dcc190..f3df4e4 100644
--- a/src/wrap.h
+++ b/src/wrap.h
@@ -92,6 +92,7 @@ struct wrap_box
/* For type == WRAP_BOX_PANGO */
PangoFont *font;
+ PangoFontDescription *fontdesc;
double col[4]; /* rgba colour */
int len_chars;
int n_segs;