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:
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 */