ltkx

GUI toolkit for X11 (WIP)
git clone git://lumidify.org/ltkx.git
Log | Files | Refs | README | LICENSE

commit 1242d3b3fcdb252a60c422b8eb15396e641fd656
parent d992e1c9a4486549c34466de7e54c5a87d5eb6a6
Author: lumidify <nobody@lumidify.org>
Date:   Wed, 13 May 2020 22:14:24 +0200

Fix many syntax errors

Diffstat:
MMakefile | 4++--
Marray.h | 7+++----
Mgap_buffer.h | 32++++++++++++++++++++------------
Mstack.h | 62++++++++++++++++++++++++++++++++++----------------------------
Mtext_buffer.c | 109+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mtext_buffer.h | 19+++++++++----------
Mtext_edit.c | 2+-
7 files changed, 129 insertions(+), 106 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,7 +1,7 @@ LIBS = -lm `pkg-config --libs x11 harfbuzz fontconfig fribidi` STD = -std=c99 CFLAGS = -g -w -fcommon -Wall -Werror -Wextra `pkg-config --cflags x11 harfbuzz fontconfig fribidi` -pedantic -OBJ = stb_truetype.o text-common.o text-hb.o ltk.o ini.o grid.o button.o test1.o +OBJ = stb_truetype.o text-common.o text_buffer.o text-hb.o ltk.o ini.o grid.o button.o test1.o test1: $(OBJ) gcc $(STD) -o $@ $(OBJ) $(LIBS) @@ -12,4 +12,4 @@ test1: $(OBJ) .PHONY: clean clean: - rm -f stb_truetype.o text-common.o text-hb.o ltk.o ini.o grid.o button.o test1.o test1 + rm -f $(OBJ) test1 diff --git a/array.h b/array.h @@ -32,7 +32,7 @@ struct ltk_array_##name { \ type *buf; \ size_t buf_size; \ size_t len; \ -} \ +}; \ struct ltk_array_##name *ltk_array_create_##name(size_t initial_len); \ void ltk_array_resize_##name(struct ltk_array_##name *ar, size_t size); \ void ltk_array_destroy_##name(struct ltk_array_##name *ar); \ @@ -46,14 +46,14 @@ ltk_array_create_##name(size_t initial_len) { \ (void)fprintf(stderr, "Array length is zero\n"); \ exit(1); \ } \ - struct ltk_gap_buffer_##name *ar = malloc(sizeof(struct ltk_array_##name)); \ + struct ltk_array_##name *ar = malloc(sizeof(struct ltk_array_##name)); \ if (!ar) goto error; \ ar->buf = malloc(initial_len * sizeof(type)); \ if (!ar->buf) goto error; \ ar->buf_size = initial_len; \ ar->len = 0; \ error: \ - (void)fprintf("Out of memory while trying to allocate array\n"); \ + (void)fprintf(stderr, "Out of memory while trying to allocate array\n"); \ exit(1); \ } \ \ @@ -76,7 +76,6 @@ ltk_array_resize_##name(struct ltk_array_##name *ar, size_t len) { \ size_t new_size; \ if (4 * len <= ar->buf_size) { \ new_size = 2 * len; \ - } \ } else if (len > ar->buf_size) { \ new_size = 2 * len; \ } else { \ diff --git a/gap_buffer.h b/gap_buffer.h @@ -33,14 +33,18 @@ struct ltk_gap_buffer_##name { \ size_t buf_size; \ size_t gap_left; \ size_t gap_size; \ + size_t len; \ }; \ \ struct ltk_gap_buffer_##name * ltk_gap_buffer_create_##name(void); \ struct ltk_gap_buffer_##name * \ ltk_gap_buffer_create_from_data_##name(type *data, size_t len); \ +type ltk_gap_buffer_get_##name(struct ltk_gap_buffer_##name *gb, size_t index); \ +void ltk_gap_buffer_set_##name( \ + struct ltk_gap_buffer_##name *gb, size_t index, type data); \ void ltk_gap_buffer_resize_gap_##name( \ struct ltk_gap_buffer_##name *gb, int len); \ -void ltk_gap_buffer_insert_##name(struct ltk_gap_buffer_##type *gb, \ +void ltk_gap_buffer_insert_##name(struct ltk_gap_buffer_##name *gb, \ type *new, size_t start, size_t len); \ void ltk_gap_buffer_insert_single_##name( \ struct ltk_gap_buffer_##name *gb, type new); \ @@ -62,6 +66,7 @@ ltk_gap_buffer_create_##name(void) { \ gb->buf_size = 8; \ gb->gap_left = 0; \ gb->gap_size = 8; \ + gb->len = 0; \ return gb; \ error: \ (void)fprintf(stderr, "Out of memory while trying to" \ @@ -80,6 +85,7 @@ ltk_gap_buffer_create_from_data_##name(type *data, size_t len) { \ } \ gb->buf = data; \ gb->buf_size = len; \ + gb->len = len; \ gb->gap_left = 0; \ gb->gap_size = 0; \ return gb; \ @@ -89,20 +95,20 @@ type \ ltk_gap_buffer_get_##name(struct ltk_gap_buffer_##name *gb, size_t index) { \ if (index < gb->gap_left) \ return gb->buf[index]; \ - else if (index < gb->buf_size - gb->gap_size) \ - return gb->buf[index - gb->gap_size]; \ - (void)fprintf("Gap buffer index out of bounds\n"); \ + else if (index + gb->gap_size < gb->len) \ + return gb->buf[index + gb->gap_size]; \ + (void)fprintf(stderr, "Gap buffer index out of bounds\n"); \ exit(1); \ } \ \ void \ -ltk_gap_buffer_get_##name( \ +ltk_gap_buffer_set_##name( \ struct ltk_gap_buffer_##name *gb, size_t index, type data) { \ if (index < gb->gap_left) \ gb->buf[index] = data; \ - else if (index < gb->buf_size - gb->gap_size) \ - gb->buf[index - gb->gap_size] = data; \ - (void)fprintf("Gap buffer index out of bounds\n"); \ + else if (index + gb->gap_size < gb->len) \ + gb->buf[index + gb->gap_size] = data; \ + (void)fprintf(stderr, "Gap buffer index out of bounds\n"); \ exit(1); \ } \ \ @@ -118,8 +124,8 @@ ltk_gap_buffer_resize_gap_##name( \ manually, so it could potentially be copied twice, which really \ wouldn't be good. Maybe use realloc if only a small part is after \ the gap and just regular malloc otherwise? */ \ - int new_size = gb->buf_size - gb->gap-size + len; \ - struct ltk_gap_buffer_##name *new = malloc(new_size * sizeof(type)); \ + int new_size = gb->buf_size - gb->gap_size + len; \ + type *new = malloc(new_size * sizeof(type)); \ if (!new) { \ (void)fprintf(stderr, "Out of memory while trying to" \ "resize gap buffer\n"); \ @@ -128,7 +134,7 @@ ltk_gap_buffer_resize_gap_##name( \ for (int i = 0; i < gb->gap_left; i++) { \ new[i] = gb->buf[i]; \ } \ - for (int i = gb->gap_left + gb->gap_size; i < gb->buf_size) { \ + for (int i = gb->gap_left + gb->gap_size; i < gb->buf_size; i++) { \ new[i - gb->gap_size + len] = gb->buf[i]; \ } \ free(gb->buf); \ @@ -145,6 +151,7 @@ ltk_gap_buffer_insert_##name(struct ltk_gap_buffer_##name *gb, \ } \ gb->gap_left = gb->gap_left + len; \ gb->gap_size -= len; \ + gb->len += len; \ } \ \ void \ @@ -164,7 +171,7 @@ ltk_gap_buffer_move_gap_##name( \ return; \ } \ if (pos >= gb->gap_left) { \ - for (int i = gb->gap_left; i < pos) { \ + for (int i = gb->gap_left; i < pos; i++) { \ gb->buf[i] = gb->buf[i + gb->gap_size]; \ } \ } else { \ @@ -177,6 +184,7 @@ ltk_gap_buffer_move_gap_##name( \ \ void ltk_gap_buffer_clear_##name(struct ltk_gap_buffer_##name *gb) { \ gb->gap_left = 0; \ + gb->len = 0; \ gb->gap_size = gb->buf_size; \ } \ \ diff --git a/stack.h b/stack.h @@ -22,9 +22,12 @@ * SOFTWARE. */ +#ifndef _LTK_STACK_H_ +#define _LTK_STACK_H_ + /* This is a "macro'd" and modified version of raqm's stack */ -#define LTK_INIT_STACK_DECL(name, type1, type2, data1, data2) \ +#define LTK_STACK_INIT_DECL(name, type1, type2, data1, data2) \ struct ltk_stack_##name { \ size_t capacity; \ size_t size; \ @@ -32,24 +35,24 @@ struct ltk_stack_##name { \ type2 *data2; \ }; \ \ -static int ltk_stack_pop_##name(ltk_stack_##name *stack); \ -static data1 ltk_stack_top1_##name(ltk_stack##name *stack); \ -static void ltk_stack_destroy_##name(ltk_stack_##name *stack); \ -static int ltk_stack_push_##name( \ - ltk_stack_##name *stack, type1 data1, type2 data2); \ -static data2 ltk_stack_top2_##name(ltk_stack##name *stack); \ -static ltk_stack_##name *ltk_stack_create_##name (size_t max); +int ltk_stack_pop_##name(struct ltk_stack_##name *stack); \ +type1 ltk_stack_top1_##name(struct ltk_stack_##name *stack, type1 def); \ +void ltk_stack_destroy_##name(struct ltk_stack_##name *stack); \ +int ltk_stack_push_##name( \ + struct ltk_stack_##name *stack, type1 data1, type2 data2); \ +type2 ltk_stack_top2_##name(struct ltk_stack_##name *stack, type2 def); \ +struct ltk_stack_##name *ltk_stack_create_##name(size_t max); -#define LTK_INIT_STACK_IMPL(name, type1, type2, data1, data2) \ -static ltk_stack_##name * \ -ltk_stack_create_##name (size_t max) { \ - ltk_stack_##name *stack; \ - stack = malloc(sizeof(ltk_stack_##name)); \ +#define LTK_STACK_INIT_IMPL(name, type1, type2, data1, data2) \ +struct ltk_stack_##name * \ +ltk_stack_create_##name(size_t max) { \ + struct ltk_stack_##name *stack; \ + stack = malloc(sizeof(struct ltk_stack_##name)); \ if (!stack) goto error; \ \ - stack->data1 = malloc(sizeof(data1) * max); \ + stack->data1 = malloc(sizeof(type1) * max); \ if (!stack->data1) goto error; \ - stack->data2 = malloc(sizeof(data2) * max); \ + stack->data2 = malloc(sizeof(type2) * max); \ if (!stack->data2) goto error; \ \ stack->size = 0; \ @@ -57,12 +60,12 @@ ltk_stack_create_##name (size_t max) { \ \ return stack; \ error: \ - (void)fprintf("Cannot allocate memory for stack\n"); \ + (void)fprintf(stderr, "Cannot allocate memory for stack\n"); \ exit(1); \ } \ \ -static int \ -ltk_stack_pop_##name(ltk_stack_##name *stack) { \ +int \ +ltk_stack_pop_##name(struct ltk_stack_##name *stack) { \ if (!stack->size) \ return 0; \ \ @@ -71,24 +74,25 @@ ltk_stack_pop_##name(ltk_stack_##name *stack) { \ return 1; \ } \ \ -static data1 \ -ltk_stack_top1_##name(ltk_stack##name *stack, type1 default) { \ +type1 \ +ltk_stack_top1_##name(struct ltk_stack_##name *stack, type1 def) { \ if (!stack->size) \ - return default; \ + return def; \ \ return stack->data1[stack->size]; \ } \ \ -static data2 \ -ltk_stack_top2_##name(ltk_stack##name *stack, type2 default) { \ +type2 \ +ltk_stack_top2_##name(struct ltk_stack_##name *stack, type2 def) { \ if (!stack->size) \ - return default; \ + return def; \ \ return stack->data2[stack->size]; \ } \ \ -static int \ -ltk_stack_push_##name(ltk_stack_##name *stack, type1 data1, type2 data2) { \ +int \ +ltk_stack_push_##name(struct ltk_stack_##name *stack, \ + type1 data1, type2 data2) { \ if (stack->size == stack->capacity) \ return 0; \ \ @@ -99,9 +103,11 @@ ltk_stack_push_##name(ltk_stack_##name *stack, type1 data1, type2 data2) { \ return 1; \ } \ \ -static void \ -ltk_stack_destroy_##name(ltk_stack_##name *stack) { \ +void \ +ltk_stack_destroy_##name(struct ltk_stack_##name *stack) { \ free(stack->data1); \ free(stack->data2); \ free(stack); \ } + +#endif /* _LTK_STACK_H_ */ diff --git a/text_buffer.c b/text_buffer.c @@ -21,8 +21,6 @@ * SOFTWARE. */ -/* NOTE: THIS DOESN'T HAVE ANY USABLE CODE YET! */ - #include <stdio.h> #include <stdlib.h> #include <stdint.h> @@ -35,8 +33,11 @@ #include <fribidi.h> #include <harfbuzz/hb.h> #include <harfbuzz/hb-ot.h> -#include "textedit_wip.h" #include "text-common.h" +#include "gap_buffer.h" +#include "array.h" +#include "stack.h" +#include "text_buffer.h" #include "ltk.h" extern Ltk *ltk_global; @@ -46,11 +47,13 @@ LTK_GAP_BUFFER_INIT_IMPL(script, hb_script_t) LTK_GAP_BUFFER_INIT_IMPL(int, int) LTK_ARRAY_INIT_IMPL(level, FriBidiLevel) LTK_ARRAY_INIT_IMPL(int, int) -LTK_STACK_INIT_IMPL(script, int, hb_script_t, pair_index, script); +LTK_STACK_INIT_IMPL(script, int, hb_script_t, pair_index, script) /* based on http://codemadness.org/git/dwm-font/file/drw.c.html#l315 */ +/* FIXME: rename this once everything is cleaned up (currently conflicts with the + old render function */ void -ltk_render_text_line( +ltk_render_text_line_new( struct ltk_text_line *tl, int max_width, Display *dpy, @@ -69,11 +72,11 @@ ltk_render_text_line( struct ltk_text_run *cur = tl->first_run; do { for (int i = 0; i < cur->num_glyphs; i++) { - cur_x += cur->glyphs[i]->x_advance; + cur_x += cur->glyphs[i].x_advance; if (cur_x > max_width) { int j = 0; for (j = i; j >= 0; j--) { - if (cur->glyphs[j]->cluster != cur->glyphs[i]->cluster) { + if (cur->glyphs[j].cluster != cur->glyphs[i].cluster) { /* must increase one again so the actual next character is used */ j++; @@ -93,7 +96,7 @@ ltk_render_text_line( XGetWindowAttributes(dpy, window, &attrs); int depth = attrs.depth; tl->img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, max_width, tl->h * tl->wrap_indeces->len, 32, 0); - tl->img->data = calloc(img->bytes_per_line, img->height); + tl->img->data = calloc(tl->img->bytes_per_line, tl->img->height); XInitImage(tl->img); int b; @@ -109,6 +112,7 @@ ltk_render_text_line( cur = tl->first_run; int x, y; + double a; int cur_line_x = 0; int cur_line = 0; LtkGlyph *glyph; @@ -118,7 +122,7 @@ ltk_render_text_line( to do in that case */ while (cur) { for (int k = 0; k < cur->len; k++) { - glyph = cur->glyphs[k]; + glyph = &cur->glyphs[k]; if (cur_line < tl->wrap_indeces->len - 1 && glyph->cluster >= tl->wrap_indeces->buf[cur_line + 1]) { cur_line++; @@ -221,7 +225,7 @@ ltk_resolve_scripts(struct ltk_text_line *tl) { int last_set_index = -1; hb_script_t last_script = HB_SCRIPT_INVALID; hb_script_t cur_script; - ltk_stack_script *stack = NULL; + struct ltk_stack_script *stack = NULL; hb_unicode_funcs_t* unicode_funcs = hb_unicode_funcs_get_default(); stack = ltk_stack_create_script(tl->len); @@ -272,14 +276,14 @@ ltk_resolve_scripts(struct ltk_text_line *tl) { } /* Loop backwards and change any remaining Common or Inherit characters to - * take the script if the next character. + * take the script of the next character. * https://github.com/HOST-Oman/libraqm/issues/95 */ hb_script_t scr; for (int i = tl->len - 2; i >= 0; --i) { scr = ltk_gap_buffer_get_script(tl->scripts, i); if (scr == HB_SCRIPT_INHERITED || scr == HB_SCRIPT_COMMON) { - ltk_gap_buffer_set_script(tl->scripts, + ltk_gap_buffer_set_script(tl->scripts, i, ltk_gap_buffer_get_script(tl->scripts, i + 1)); } } @@ -292,7 +296,7 @@ ltk_resolve_scripts(struct ltk_text_line *tl) { /* End stuff stolen from raqm */ /* Update: That's a lie; much more is stolen from raqm. */ -static struct +static struct ltk_text_run * ltk_text_run_create(size_t start_index, size_t len, hb_script_t script, hb_direction_t dir) { struct ltk_text_run *run = malloc(sizeof(struct ltk_text_run)); if (!run) { @@ -312,8 +316,8 @@ ltk_text_line_itemize(struct ltk_text_line *tl) { ltk_resolve_scripts(tl); struct ltk_text_run *first_run = NULL; struct ltk_text_run *cur_run = NULL; - FriBidilevel last_level; - FriBidilevel cur_level; + FriBidiLevel last_level; + FriBidiLevel cur_level; hb_script_t last_script; hb_script_t cur_script; size_t start_index = 0; @@ -322,12 +326,12 @@ ltk_text_line_itemize(struct ltk_text_line *tl) { int par_is_rtl = FRIBIDI_IS_RTL(tl->dir); while (start_index < tl->len) { end_index = start_index; - cur_level = last_level = ltk_gap_buffer_get_level(tl->bidi_levels, start_index); + cur_level = last_level = tl->bidi_levels->buf[start_index]; cur_script = last_script = ltk_gap_buffer_get_script(tl->scripts, start_index); while (end_index < tl->len && cur_level == last_level && cur_script == last_script) { end_index++; - cur_level = ltk_gap_buffer_get_level(tl->bidi_levels, end_index); + cur_level = tl->bidi_levels->buf[end_index]; cur_script = ltk_gap_buffer_get_script(tl->scripts, end_index); } dir = HB_DIRECTION_LTR; @@ -375,14 +379,14 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr, tr->num_glyphs = 0; buf = hb_buffer_create(); - hb_buffer_set_direction(buf, run->dir); - hb_buffer_set_script(buf, run->script); + hb_buffer_set_direction(buf, tr->dir); + hb_buffer_set_script(buf, tr->script); /* WARNING: vis_buf has to be normalized (without gap) for this! */ - hb_buffer_add_codepoints(buf, tl->vis-buf, tl->len, tr->start_index, tr->len); + hb_buffer_add_codepoints(buf, tl->vis_buf, tl->len, tr->start_index, tr->len); /* According to https://harfbuzz.github.io/the-distinction-between-levels-0-and-1.html * this should be level 1 clustering instead of level 0 */ hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); - hb_shape(font->hb, buf, NULL, 0); + hb_shape(tr->font->hb, buf, NULL, 0); ginf = hb_buffer_get_glyph_infos(buf, &tr->num_glyphs); gpos = hb_buffer_get_glyph_positions(buf, &tr->num_glyphs); float scale = stbtt_ScaleForMappingEmToPixels(&tr->font->info, font_size); @@ -390,9 +394,9 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr, int x_min = INT_MAX, x_max = INT_MIN, y_min = INT_MAX, y_max = INT_MIN; int x_abs = 0, y_abs = 0, x1_abs, y1_abs, x2_abs, y2_abs; /* magic, do not touch */ - tr->glyphs = malloc(sizeof(LtkGlyph) * num_glyph); + tr->glyphs = malloc(sizeof(LtkGlyph) * tr->num_glyphs); if (!tr->glyphs) { - (void)fprintf("Cannot allocate space for glyphs.\n"); + (void)fprintf(stderr, "Cannot allocate space for glyphs.\n"); exit(1); } /* FIXME: should x_max be calculated using glyph->info->w? @@ -402,7 +406,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr, for (int i = 0; i < tr->num_glyphs; i++) { gi = &ginf[i]; gp = &gpos[i]; - glyph = tr->glyphs[i]; + glyph = &tr->glyphs[i]; glyph->cluster = gi->cluster; glyph->info = ltk_get_glyph_info(tr->font, gi->codepoint, scale, glyph_cache); glyph->info->refs++; @@ -448,7 +452,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr, static void ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) { - struct ltk_text_run *run = tl->runs; + struct ltk_text_run *run = tl->first_run; tl->y_max = INT_MIN; tl->y_min = INT_MAX; tl->w = tl->h = 0; @@ -473,26 +477,26 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) { run->font = kh_value(tm->font_cache, k); FcPatternDestroy(match); FcPatternDestroy(pat); - ltk_text_run_shape(tm, run, tl->font_size, font_id, &y_max); + ltk_text_run_shape(tm, run, tl, tl->font_size, font_id, &y_max); if (tl->y_max < y_max) tl->y_max = y_max; /* tr->start_y is -y_min */ - if (tl->y_min > -tr->start_y) - tl->y_min = -tr->start_y; - tl->w += tr->w; + if (tl->y_min > -run->start_y) + tl->y_min = -run->start_y; + tl->w += run->w; run = run->next; }; tl->h = tl->y_max - tl->y_min; /* calculate the actual position of the characters */ - run = tl->runs; + run = tl->first_run; int x = 0; LtkGlyph *glyph; while (run) { int cur_x = x + run->start_x; int cur_y = tl->h - tl->y_max; /* baseline (I think?) */ for (int i = 0; i < run->len; i++) { - glyph = run->glyphs[i]; + glyph = &run->glyphs[i]; glyph->x_abs = cur_x + glyph->info->xoff + glyph->x_offset; glyph->y_abs = cur_y - glyph->info->yoff - glyph->y_offset; cur_x += glyph->x_advance; @@ -503,21 +507,19 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) { } } -/* FIXME: Don't destroy fonts, etc. every time the line is recalculated */ -/* Maybe decrease font refs but don't destroy until after the runs have been re-shaped */ void -ltk_text_run_destroy(struct ltk_text_line *tl, struct ltk_text_run *tr) { +ltk_text_run_destroy(struct ltk_text_run *tr) { khash_t(glyphinfo) *gcache; LtkFont *font; LtkGlyph *glyph; khint_t k; - k = kh_get(glyphinfo, ltk_global->tm->glyph_cache, tr->font_id << 16 + tl->font_size); + k = kh_get(glyphinfo, ltk_global->tm->glyph_cache, tr->font_id << 16 + tr->font_size); gcache = kh_value(ltk_global->tm->glyph_cache, k); for (int i = 0; i < tr->len; i++) { - glyph = tr->glyphs[i]; + glyph = &tr->glyphs[i]; if (--glyph->info->refs < 1) { - k = kh_get(glyphinfo, cache, glyph->info->id); - kh_del(glyphinfo, cache, k); + k = kh_get(glyphinfo, gcache, glyph->info->id); + kh_del(glyphinfo, gcache, k); ltk_destroy_glyph_info(glyph->info); } } @@ -532,9 +534,9 @@ ltk_text_run_destroy(struct ltk_text_line *tl, struct ltk_text_run *tr) { } void -ltk_text_line_destroy_runs(struct ltk_text_line *tl) { +ltk_text_line_destroy_runs(struct ltk_text_run *runs) { struct ltk_text_run *cur, *last; - cur = tl->first_run; + cur = runs; while (cur) { last = cur; ltk_text_run_destroy(cur); @@ -547,6 +549,10 @@ ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) { ltk_gap_buffer_clear_uint32(tl->vis_buf); ltk_gap_buffer_clear_int(tl->log2vis); ltk_gap_buffer_clear_int(tl->vis2log); + /* yeah, this is hacky */ + tl->vis_buf->len = tl->vis_buf->buf_size; + tl->log2vis->len = tl->log2vis->buf_size; + tl->vis2log->len = tl->vis2log->buf_size; size_t gap_pos = tl->log_buf->gap_left; size_t gap_end = tl->log_buf->buf_size - tl->log_buf->gap_size; ltk_gap_buffer_move_gap_uint32(tl->log_buf, gap_end); @@ -555,9 +561,13 @@ ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) { &tl->dir, tl->vis_buf, tl->log2vis, tl->vis2log, tl->bidi_levels ); ltk_gap_buffer_move_gap_uint32(tl->log_buf, gap_pos); - ltk_text_line_destroy_runs(tl); /* FIXME: IMPLEMENT */ + struct ltk_text_run *old_runs = tl->first_run; ltk_text_line_itemize(tl); ltk_text_line_shape(tm, tl); + /* this needs to be done after shaping so the fonts, etc. aren't + removed if their reference counts drop and then loaded again + right afterwards */ + ltk_text_line_destroy_runs(old_runs); } @@ -579,7 +589,7 @@ ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len) } */ ltk_gap_buffer_insert_uint32(tl->log_buf, text, 0, len); - if (len > tl->scripts->gap-size) + if (len > tl->scripts->gap_size) ltk_gap_buffer_resize_gap_script(tl->scripts, len + 8); hb_unicode_funcs_t *ufuncs = hb_unicode_funcs_get_default(); for (int i = 0; i < len; i++) { @@ -593,9 +603,10 @@ ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len) if (len > tl->vis2log->gap_size) ltk_gap_buffer_resize_gap_int(tl->vis2log, len + 8); if (len + tl->bidi_levels->len > tl->bidi_levels->buf_size) - ltk_array_resize_levels(tl->bidi_levels, tl->bidi_levels->len + len + 8); + ltk_array_resize_level(tl->bidi_levels, tl->bidi_levels->len + len + 8); tl->len += len; - ltk_text_line_recalculate(tl); + /* FIXME: Why am I passing tm? It's global anyways */ + ltk_text_line_recalculate(tl, ltk_global->tm); } /* must be NULL-terminated */ @@ -604,9 +615,9 @@ ltk_text_line_insert_utf8(struct ltk_text_line *tl, char *text) { size_t len = u8_strlen(text); uint32_t *new = malloc(sizeof(uint32_t) * len); if (!new) { - (void)fprintf("Error allocating memory for string\n"); + (void)fprintf(stderr, "Error allocating memory for string\n"); exit(1); - ] + } size_t inc = 0; for (int i = 0; i < len; i++) new[i] = u8_nextmemchar(text, &inc); @@ -623,9 +634,9 @@ ltk_text_line_create(void) { line->vis_buf = ltk_gap_buffer_create_uint32(); line->log2vis = ltk_gap_buffer_create_int(); line->vis2log = ltk_gap_buffer_create_int(); - line->bidi_levels = ltk_array_create_levels(8); + line->bidi_levels = ltk_array_create_level(8); line->wrap_indeces = ltk_array_create_int(1); - line->runs = NULL; + line->first_run = NULL; line->cur_run = NULL; line->next = NULL; line->height = 0; @@ -657,7 +668,7 @@ ltk_text_line_destroy(struct ltk_text_line *tl) { ltk_gap_buffer_destroy_int(tl->vis2log); ltk_array_destroy_level(tl->bidi_levels); ltk_array_destroy_int(tl->wrap_indeces); - ltk_text_line_destroy_runs(tl); + ltk_text_line_destroy_runs(tl->first_run); if (tl->img) XDestroyImage(tl->img); free(tl); } diff --git a/text_buffer.h b/text_buffer.h @@ -21,8 +21,8 @@ * SOFTWARE. */ -#ifndef _TEXT_HB_H_ -#define _TEXT_HB_H_ +#ifndef _TEXT_BUFFER_H_ +#define _TEXT_BUFFER_H_ /* Requires the following includes: @@ -31,10 +31,6 @@ Requires the following includes: <fontconfig/fontconfig.h> */ -#include "gap_buffer.h" -#include "array.h" -#include "stack.h" - /* Note: hb_script_t and FriBidiLevel are really just uint32_t's, but I'm not sure if I should rely on that, so they're separate here */ LTK_GAP_BUFFER_INIT_DECL(uint32, uint32_t) @@ -42,7 +38,7 @@ LTK_GAP_BUFFER_INIT_DECL(script, hb_script_t) LTK_GAP_BUFFER_INIT_DECL(int, int) LTK_ARRAY_INIT_DECL(level, FriBidiLevel) LTK_ARRAY_INIT_DECL(int, int) -LTK_STACK_INIT_DECL(script, int, hb_script_t, pair_index, script); +LTK_STACK_INIT_DECL(script, int, hb_script_t, pair_index, script) struct ltk_text_run { LtkGlyph *glyphs; @@ -50,15 +46,16 @@ struct ltk_text_run { struct ltk_text_run *next; struct ltk_text_run *last; size_t start_index; - size_t len; + size_t len; /* FIXME: THIS IS NOT THE NUMBER OF GLYPHS; IT IS THE ACTUAL NUMBER OF CHARACTERS REPRESENTED BY THIS RUN */ int start_x; int start_y; int w; LtkFont *font; uint16_t font_id; + uint16_t font_size; hb_script_t script; hb_direction_t dir; -} +}; struct ltk_text_line { struct ltk_gap_buffer_uint32 *log_buf; /* buffer of the logical text */ @@ -72,7 +69,7 @@ struct ltk_text_line { struct ltk_text_run *cur_run; /* current node in the linked list of runs */ struct ltk_text_line *next; /* next text line in the buffer */ unsigned int height; /* height of the line (including wrapping) */ - FribidiCharType dir; /* overall paragraph direction */ + FriBidiCharType dir; /* overall paragraph direction */ struct ltk_array_int *wrap_indeces; size_t len; uint16_t font_size; @@ -88,3 +85,5 @@ struct ltk_text_buffer { struct ltk_text_line *cur_line; unsigned int line_gap; }; + +#endif /* _TEXT_BUFFER_H_ */ diff --git a/text_edit.c b/text_edit.c @@ -30,7 +30,7 @@ ltk_draw_text_edit(LtkTextEdit *te) { LtkRect rect = te->widget.rect; LtkWindow *window = te->widget.window; if (!te->tl->img) - ltk_render_text_line(te->tl, rect.w, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg); + ltk_render_text_line_new(te->tl, rect.w, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg); XPutImage(ltk_global->display, window->xwindow, window->gc, te->tl->img, 0, 0, rect.x, rect.y, te->tl->w, te->tl->h); }