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