URI: 
       tAdd array; keep blindly messing around with textedit - ltkx - GUI toolkit for X11 (WIP)
  HTML git clone git://lumidify.org/ltkx.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit b1250321e3fc95848914e726871bea1a04f1454e
   DIR parent 74fc1346f0e2ee3e95c37edc9880890d14f8e747
  HTML Author: lumidify <nobody@lumidify.org>
       Date:   Sun, 10 May 2020 10:08:05 +0200
       
       Add array; keep blindly messing around with textedit
       
       Diffstat:
         A array.h                             |      76 +++++++++++++++++++++++++++++++
         M gap_buffer.h                        |       6 ++++++
         M textedit_wip.c                      |      65 +++++++++++++++++++++++++++++--
         M textedit_wip.h                      |       6 ++++++
       
       4 files changed, 149 insertions(+), 4 deletions(-)
       ---
   DIR diff --git a/array.h b/array.h
       t@@ -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_ */
   DIR diff --git a/gap_buffer.h b/gap_buffer.h
       t@@ -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)                                        \
       t@@ -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);                                                                \
   DIR diff --git a/textedit_wip.c b/textedit_wip.c
       t@@ -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) */
       t@@ -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;
        }
   DIR diff --git a/textedit_wip.h b/textedit_wip.h
       t@@ -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 {
       t@@ -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;
       t@@ -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 {
       t@@ -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 */