ltkx

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

commit b1250321e3fc95848914e726871bea1a04f1454e
parent 74fc1346f0e2ee3e95c37edc9880890d14f8e747
Author: lumidify <nobody@lumidify.org>
Date:   Sun, 10 May 2020 10:08:05 +0200

Add array; keep blindly messing around with textedit

Diffstat:
Aarray.h | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgap_buffer.h | 6++++++
Mtextedit_wip.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mtextedit_wip.h | 6++++++
4 files changed, 149 insertions(+), 4 deletions(-)

diff --git a/array.h b/array.h @@ -0,0 +1,76 @@ +/* + * This file is part of the Lumidify ToolKit (LTK) + * Copyright (c) 2020 lumidify <nobody@lumidify.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _LTK_ARRAY_H_ +#define _LTK_ARRAY_H_ + +#include <stdio.h> +#include <stdlib.h> + +#define LTK_ARRAY_INIT_DECL(name, type) \ +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); + +#define LTK_ARRAY_INIT_IMPL(name, type) \ +struct ltk_array_##name## * \ +ltk_array_create_##name##(size_t initial_len) { \ + if (initial_len == 0) { \ + (void)fprintf(stderr, "Array length is zero\n"); \ + exit(1); \ + } \ + struct ltk_gap_buffer_##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"); \ + exit(1); \ +} \ + \ +void \ +ltk_array_resize_##name##(struct ltk_array_##name## *ar, size_t size) { \ + type *new = realloc(ar->buf, size); \ + if (!new) { \ + (void)fprintf(stderr, "Cannot realloc array\n"); \ + exit(1); \ + } \ + ar->buf = new; \ + ar->buf_size = size; \ + ar->len = ar->len < size ? ar->len : size; \ +} \ + \ +void \ +ltk_array_destroy_##name##(struct ltk_array_##name## *ar) { \ + free(ar->buf); \ + free(ar); \ +} + +#endif /* _LTK_ARRAY_H_ */ diff --git a/gap_buffer.h b/gap_buffer.h @@ -46,6 +46,7 @@ void ltk_gap_buffer_insert_single_##name##( \ struct ltk_gap_buffer_##name## *gb, type new); \ void ltk_gap_buffer_move_gap_##name##( \ struct ltk_gap_buffer_##name## *gb, size_t pos); \ +void ltk_gap_buffer_clear_##name##(struct ltk_gap_buffer_##name## *gb); \ void ltk_gap_buffer_destroy_##name##(struct ltk_gap_buffer_##name## *gb); #define LTK_GAP_BUFFER_INIT_IMPL(name, type) \ @@ -149,6 +150,11 @@ ltk_gap_buffer_move_gap_##name##( \ gb->gap_left = pos; \ } \ \ +void ltk_gap_buffer_clear_##name##(struct ltk_gap_buffer_##name## *gb) { \ + gb->gap_left = 0; \ + gb->gap_size = gb->buf_size; \ +} \ + \ void \ ltk_gap_buffer_destroy_##name##(struct ltk_gap_buffer_##name## *gb) { \ free(gb->buf); \ diff --git a/textedit_wip.c b/textedit_wip.c @@ -44,6 +44,8 @@ extern Ltk *ltk_global; LTK_GAP_BUFFER_INIT_IMPL(uint32, uint32_t) LTK_GAP_BUFFER_INIT_IMPL(int, int) LTK_GAP_BUFFER_INIT_IMPL(glyph, struct ltk_glyph) +LTK_ARRAY_INIT_IMPL(char_type, FriBidiCharType) +LTK_ARRAY_INIT_IMPL(level, FriBidiLevel) /* FIXME: allow to either use fribidi for basic shaping and don't use harfbuzz then, or just use harfbuzz (then fribidi doesn't need to do any shaping) */ @@ -428,14 +430,69 @@ when reshaping with context, only the text in the current run has to be passed a */ void +ltk_text_line_recalculate(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); +} + +void ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len) { /* check if any characters have a different script, only recalc then */ + /* + hb_unicode_funcs_t *uf= hb_unicode_funcs_get_default(); + struct ltk_text_run *run = tl->cur_run; + int recalc = 0; + hb_script_t script; + for (int i = 0; i < len; i++) { + scr = hb_unicode_script(uf, text[i]); + if (script != run->script && + script != HB_SCRIPT_INHERITED && + script != HB_SCRIPT_COMMON) { + recalc = 1; + } + } + */ + ltk_gap_buffer_insert_uint32(tl->log_buf, text, 0, len); + if (len > tl->vis_buf->gap_size) + ltk_gap_buffer_resize_gap_uint32(tl->vis_buf, len + 8); + if (len > tl->log2vis->gap_size) + ltk_gap_buffer_resize_gap_int(tl->log2vis, len + 8); + if (len > tl->vis2log->gap_size) + ltk_gap_buffer_resize_gap_int(tl->vis2log, len + 8); + if (len + tl->bidi_types->len > tl->bidi_types->buf_size) + ltk_array_resize_char_type(tl->bidi_types, tl->bidi_types->len + 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_text_line_recalculate(tl); } -void -ltk_text_line_delete_text(struct ltk_text_line *tl, size_t len) { +struct ltk_text_line * +ltk_text_line_create(void) { + struct ltk_text_line *line = malloc(sizeof(struct ltk_text_line)); + if (!line) goto error; + line->log_buf = ltk_gap_buffer_create_uint32(); + line->vis_buf = ltk_gap_buffer_create_uint32(); + line->log2vis = ltk_gap_buffer_create_int(); + line->vis2log = ltk_gap_buffer_create_int(); + line->runs = NULL; + line->cur_run = NULL; + line->next = NULL; + line->height = 0; + line->dir = FRIBIDI_TYPE_ON; +error: + (void)fprintf(stderr, "No memory left while creating text line\n"); + exit(1); } -void -ltk_text_line_delete_cur_cluster(struct ltk_text_line *tl) { +struct ltk_text_buffer * +ltk_text_buffer_create(void) { + struct ltk_text_buffer *buf = malloc(sizeof(struct ltk_text_buffer)); + if (!buf) { + (void)fprintf(stderr, "No memory while creating text buffer\n"); + exit(1); + } + buf->head = ltk_text_line_create(); + buf->cur_line = buf->head; + buf->line_gap = 0; } diff --git a/textedit_wip.h b/textedit_wip.h @@ -32,6 +32,7 @@ Requires the following includes: */ #include "gap_buffer.h" +#include "array.h" /* Contains glyph info specific to one run of text */ struct ltk_glyph { @@ -48,6 +49,8 @@ struct ltk_glyph { LTK_GAP_BUFFER_INIT_DECL(uint32, uint32_t) LTK_GAP_BUFFER_INIT_DECL(int, int) LTK_GAP_BUFFER_INIT_DECL(glyph, struct ltk_glyph) +LTK_ARRAY_INIT_DECL(char_type, FriBidiCharType) +LTK_ARRAY_INIT_DECL(level, FriBidiLevel) struct ltk_text_run { struct ltk_gap_buffer_glyph *glyphs; @@ -62,6 +65,7 @@ struct ltk_text_run { int x_max; int y_max; hb_script_t script; + hb_direction_t dir; } struct ltk_text_line { @@ -69,6 +73,8 @@ struct ltk_text_line { struct ltk_gap_buffer_uint32 *vis_buf; /* buffer of visual text */ struct ltk_gap_buffer_int *log2vis; struct ltk_gap_buffer_int *vis2log; + struct ltk_array_char_type *bidi_types; + struct ltk_array_level *bidi_levels; struct ltk_text_run *runs; /* first node in the linked list of runs */ 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 */