commit 30f6302a0a754c310140abbb88f467492586be68
parent e6a8ecf9116eb9cec8ed1da33d69c91988f55e86
Author: lumidify <nobody@lumidify.org>
Date: Thu, 14 May 2020 15:35:58 +0200
Fix and add bugs
Diffstat:
7 files changed, 106 insertions(+), 63 deletions(-)
diff --git a/array.h b/array.h
@@ -58,6 +58,7 @@ ltk_array_create_##name(size_t initial_len) { \
if (!ar->buf) goto error; \
ar->buf_size = initial_len; \
ar->len = 0; \
+ return ar; \
error: \
(void)fprintf(stderr, "Out of memory while trying to allocate array\n"); \
exit(1); \
@@ -120,7 +121,7 @@ ltk_array_resize_##name(struct ltk_array_##name *ar, size_t len) { \
} else { \
return; \
} \
- type *new = realloc(ar->buf, new_size); \
+ type *new = realloc(ar->buf, new_size * sizeof(type)); \
if (!new) { \
(void)fprintf(stderr, "Cannot realloc array\n"); \
exit(1); \
@@ -132,7 +133,9 @@ ltk_array_resize_##name(struct ltk_array_##name *ar, size_t len) { \
\
void \
ltk_array_destroy_##name(struct ltk_array_##name *ar) { \
+ printf("%p %p %d\n", ar->buf, ar, ar->buf_size); \
free(ar->buf); \
+ ar->buf = NULL; \
free(ar); \
}
diff --git a/ltkx.h b/ltkx.h
@@ -12,3 +12,5 @@
#include "text-hb.h"
#include "button.h"
#include "grid.h"
+#include "array.h"
+#include "text_edit.h"
diff --git a/test1.c b/test1.c
@@ -25,17 +25,18 @@ int main(int argc, char *argv[])
ltk_set_column_weight(grid1, 0, 1);
ltk_set_column_weight(grid1, 1, 1);
/* Test callback functions */
- LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1);
- ltk_grid_widget(button1, grid1, 0, 0, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_RIGHT);
+ //LtkButton *button1 = ltk_create_button(window1, "I'm a button!", &bob1);
+ //ltk_grid_widget(button1, grid1, 0, 0, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_RIGHT);
/* Test manual callback functions */
- LtkButton *button2 = ltk_create_button(window1, "I'm a button!", NULL);
- button2->widget.mouse_release = &bob2;
- ltk_grid_widget(button2, grid1, 0, 1, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM);
- LtkButton *button3 = ltk_create_button(window1, "I'm a button!", NULL);
- ltk_grid_widget(button3, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT);
+ //LtkButton *button2 = ltk_create_button(window1, "I'm a button!", NULL);
+ //button2->widget.mouse_release = &bob2;
+ //ltk_grid_widget(button2, grid1, 0, 1, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM);
+ //LtkButton *button3 = ltk_create_button(window1, "I'm a button!", NULL);
+ //ltk_grid_widget(button3, grid1, 1, 0, 1, 1, LTK_STICKY_TOP | LTK_STICKY_BOTTOM | LTK_STICKY_RIGHT);
//LtkButton *button4 = ltk_create_button(window1, "I'm a button!", NULL);
- LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", NULL);
+ //LtkButton *button4 = ltk_create_button(window1, "ہمارے بارے میں blablabla", NULL);
//LtkButton *button4 = ltk_create_button(window1, "پَیدایش", NULL);
- ltk_grid_widget(button4, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM);
+ LtkTextEdit *edit = ltk_create_text_edit(window1, "ہمارے بارے میں blablabla");
+ ltk_grid_widget(edit, grid1, 1, 1, 1, 1, LTK_STICKY_LEFT | LTK_STICKY_BOTTOM);
ltk_mainloop();
}
diff --git a/text-hb.c b/text-hb.c
@@ -365,7 +365,6 @@ ltk_render_text_line(
int is_hor = HB_DIRECTION_IS_HORIZONTAL(ts->dir);
do {
if (is_hor) {
- printf("%d\n", ts->start_x);
y = tl->h - tl->y_max;
ltk_render_text_segment(ts, x + ts->start_x, y, img, fg);
x += ts->w;
@@ -396,7 +395,6 @@ ltk_render_text_segment(
do {
x = x_cur + glyph->info->xoff + glyph->x_offset;
y = y_cur + glyph->info->yoff - glyph->y_offset;
- printf("%d %d; %d %d\n", x, y, glyph->x_abs, glyph->y_abs);
for (int i = 0; i < glyph->info->h; i++) {
for (int j = 0; j < glyph->info->w; j++) {
b = (y + i) * img->bytes_per_line + (x + j) * 4;
diff --git a/text_buffer.c b/text_buffer.c
@@ -60,30 +60,53 @@ ltk_render_text_line_new(
XColor bg)
{
XImage *img;
- int cur_x = 0, cur_y = 0;
int par_is_rtl = FRIBIDI_IS_RTL(tl->dir);
+ int cur_y = 0;
+ int cur_x = par_is_rtl ? max_width : 0;
ltk_array_clear_int(tl->wrap_indeces);
ltk_array_append_int(tl->wrap_indeces, 0);
/* FIXME: wrap bidi text properly */
+ /* FIXME: THIS IS UGLY */
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;
- if (cur_x > max_width) {
- int j = 0;
- for (j = i; j >= 0; j--) {
- if (cur->glyphs[j].cluster != cur->glyphs[i].cluster) {
- /* must increase one again so the actual
- next character is used */
- j++;
- break;
+ if (par_is_rtl) {
+ for (int i = cur->num_glyphs - 1; i >= 0; i--) {
+ cur_x -= cur->glyphs[i].x_advance;
+ if (cur_x < 0) {
+ int j = 0;
+ for (j = i; j < cur->num_glyphs; j++) {
+ if (cur->glyphs[j].cluster != cur->glyphs[i].cluster) {
+ /* must decrease one again so the actual
+ last character is used */
+ j--;
+ break;
+ }
}
+ i = j;
+ /* FIXME: handle case that this is the same as the last index */
+ ltk_array_append_int(tl->wrap_indeces, cur->glyphs[i].cluster);
+ cur_x = max_width;
+ }
+ }
+ } else {
+ for (int i = 0; i < cur->num_glyphs; i++) {
+ 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) {
+ /* must increase one again so the actual
+ next character is used */
+ j++;
+ break;
+ }
+ }
+ i = j;
+ /* FIXME: handle case that this is the same as the last index */
+ ltk_array_append_int(tl->wrap_indeces, cur->glyphs[i].cluster);
+ cur_x = 0;
}
- i = j;
- /* FIXME: handle case that this is the same as the last index */
- ltk_array_append_int(tl->wrap_indeces, cur->glyphs[i].cluster);
- cur_x = 0;
}
}
} while (cur = cur->next);
@@ -91,9 +114,11 @@ ltk_render_text_line_new(
XWindowAttributes attrs;
XGetWindowAttributes(dpy, window, &attrs);
int depth = attrs.depth;
+ printf("%d --- %d\n", max_width, tl->h * tl->wrap_indeces->len);
img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, max_width, tl->h * tl->wrap_indeces->len, 32, 0);
img->data = calloc(img->bytes_per_line, img->height);
XInitImage(img);
+ printf("%d +++ %d\n", img->width, img->height);
int b;
for (int i = 0; i < tl->h * tl->wrap_indeces->len; i++) {
@@ -112,20 +137,33 @@ ltk_render_text_line_new(
int cur_line_x = 0;
int cur_line = 0;
LtkGlyph *glyph;
- /* FIXME: Ints are compared with size_t's in various places. Maybe I should fix that. */
+ /* FIXME: ints are compared with size_t's in various places. Maybe I should fix that. */
/* FIXME: how should an empty line be handled? This doesn't use a do-for
loop in case tl->first_run is NULL, but I should probably decide what
to do in that case */
+ int index;
while (cur) {
- for (int k = 0; k < cur->len; k++) {
+ for (int k = 0; k < cur->num_glyphs; k++) {
+ index = par_is_rtl ? cur->num_glyphs - k - 1 : k;
glyph = &cur->glyphs[k];
if (cur_line < tl->wrap_indeces->len - 1 &&
- glyph->cluster >= tl->wrap_indeces->buf[cur_line + 1]) {
+ ((!par_is_rtl && glyph->cluster >= tl->wrap_indeces->buf[cur_line + 1]) ||
+ (par_is_rtl && glyph->cluster <= tl->wrap_indeces->buf[cur_line + 1]))) {
cur_line++;
cur_line_x += glyph->x_abs - cur_line_x;
}
- x = glyph->x_abs - cur_line_x;
+ x = par_is_rtl ? max_width - (glyph->x_abs - cur_line_x) - glyph->info->w: glyph->x_abs - cur_line_x;
y = glyph->y_abs + tl->h * cur_line;
+ printf("%d,%d\n", x, y);
+ fflush(stdout);
+ if (x < 0)
+ x = 0;
+ if (x > max_width - glyph->info->w)
+ x = max_width - glyph->info->w;
+ if (y < 0)
+ y = 0;
+ if (y > img->height - glyph->info->h)
+ y = img->height - glyph->info->h;
for (int i = 0; i < glyph->info->h; i++) {
for (int j = 0; j < glyph->info->w; j++) {
b = (y + i) * img->bytes_per_line + (x + j) * 4;
@@ -138,6 +176,7 @@ ltk_render_text_line_new(
}
cur = cur->next;
}
+ return img;
}
/* Begin stuff stolen from raqm */
@@ -280,8 +319,8 @@ ltk_text_run_create(size_t start_index, size_t len, hb_script_t script, hb_direc
run->len = len;
run->script = script;
run->dir = dir;
- run->last = NULL;
run->next = NULL;
+ return run;
}
static void
@@ -289,6 +328,7 @@ 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;
+ struct ltk_text_run *new = NULL;
FriBidiLevel last_level;
FriBidiLevel cur_level;
hb_script_t last_script;
@@ -310,27 +350,22 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
dir = HB_DIRECTION_LTR;
if (FRIBIDI_LEVEL_IS_RTL(last_level))
dir = HB_DIRECTION_RTL;
- struct ltk_text_run *new = ltk_text_run_create(
+ new = ltk_text_run_create(
start_index, end_index - start_index, last_script, dir);
if (!first_run) {
- first_run = cur_run = new;
+ first_run = new;
} else {
- if (par_is_rtl) {
+ if (par_is_rtl)
new->next = cur_run;
- cur_run->last = new;
- } else {
+ else
cur_run->next = new;
- new->last = cur_run;
- }
- cur_run = new;
}
+ cur_run = new;
start_index = end_index;
}
- tl->first_run = tl->cur_run = first_run;
- tl->last_run = cur_run;
+ tl->first_run = par_is_rtl ? cur_run : first_run;
}
-/* FIXME: return start_x, etc. instead of saving in struct text run */
static void
ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
struct ltk_text_line *tl, uint16_t font_size, uint16_t font_id, int *ret_y_max) {
@@ -338,6 +373,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
khint_t k;
tr->font_id = font_id;
+ tr->font_size = font_size;
uint32_t attr = font_id << 16 + font_size;
/* FIXME: turn this into ltk_get_glyph_cache */
k = kh_get(glyphcache, tm->glyph_cache, attr);
@@ -355,7 +391,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
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->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);
@@ -392,14 +428,6 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
/* Calculate position in order to determine full size of text segment */
x1_abs = x_abs + glyph->info->xoff + glyph->x_offset;
y1_abs = y_abs + glyph->info->yoff - glyph->y_offset;
- /* Okay, wait, so should I check if the script is horizontal, and then add
- x_advance instead of glyph->info->w? It seems that the glyph width is
- usually smaller than x_advance, and spaces etc. are completely lost
- because their glyph width is 0. I have to distinguish between horizontal
- and vertical scripts, though because to calculate the maximum y position
- for horizontal scripts, I still need to use the glyph height since
- y_advance doesn't really do much there. I dunno, at least *something*
- works now... */
/* FIXME: THIS PROBABLY DOESN'T REALLY WORK */
if (HB_DIRECTION_IS_HORIZONTAL(tr->dir)) {
x2_abs = x1_abs + glyph->x_advance;
@@ -434,11 +462,12 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
FcPattern *pat = FcPatternDuplicate(tm->fcpattern);
FcPattern *match;
FcResult result;
+ printf("%p\n", pat);
FcPatternAddBool(pat, FC_SCALABLE, 1);
FcConfigSubstitute(NULL, pat, FcMatchPattern);
FcDefaultSubstitute(pat);
FcCharSet *cs = FcCharSetCreate();
- for (int i = run->start_index; i < run->start_index + run->len; i++) {
+ for (size_t i = run->start_index; i < run->start_index + run->len; i++) {
FcCharSetAddChar(cs, tl->vis_buf->buf[i]);
}
FcPatternAddCharSet(pat, FC_CHARSET, cs);
@@ -448,6 +477,7 @@ ltk_text_line_shape(LtkTextManager *tm, struct ltk_text_line *tl) {
uint16_t font_id = ltk_get_font(tm, file);
khint_t k = kh_get(fontstruct, tm->font_cache, font_id);
run->font = kh_value(tm->font_cache, k);
+ fflush(stdout);
FcPatternDestroy(match);
FcPatternDestroy(pat);
ltk_text_run_shape(tm, run, tl, tl->font_size, font_id, &y_max);
@@ -488,7 +518,7 @@ ltk_text_run_destroy(struct ltk_text_run *tr) {
khint_t k;
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++) {
+ for (int i = 0; i < tr->num_glyphs; i++) {
glyph = &tr->glyphs[i];
if (--glyph->info->refs < 1) {
k = kh_get(glyphinfo, gcache, glyph->info->id);
@@ -508,23 +538,25 @@ ltk_text_run_destroy(struct ltk_text_run *tr) {
void
ltk_text_line_destroy_runs(struct ltk_text_run *runs) {
- struct ltk_text_run *cur, *last;
+ struct ltk_text_run *cur, *next;
cur = runs;
while (cur) {
- last = cur;
+ next = cur->next;
ltk_text_run_destroy(cur);
- cur = last->next;
+ cur = next;
}
}
static void
ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
+ printf("%d,%d,%d,%d,%d\n", tl->log_buf->buf_size, tl->vis_buf->buf_size, tl->log2vis->buf_size, tl->vis2log->buf_size, tl->bidi_levels->buf_size);
fribidi_log2vis(
- tl->log_buf, tl->log_buf->len,
- &tl->dir, tl->vis_buf, tl->log2vis, tl->vis2log, tl->bidi_levels
+ tl->log_buf->buf, tl->log_buf->len,
+ &tl->dir, tl->vis_buf->buf, tl->log2vis->buf, tl->vis2log->buf, tl->bidi_levels->buf
);
struct ltk_text_run *old_runs = tl->first_run;
ltk_text_line_itemize(tl);
+ struct ltk_text_run *cur = tl->first_run;
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
@@ -547,7 +579,7 @@ ltk_text_line_insert_text(struct ltk_text_line *tl, uint32_t *text, size_t len)
tl->len += len;
tl->cursor_pos += len;
/* FIXME: Why am I passing tm? It's global anyways */
- ltk_text_line_recalculate(tl, ltk_global->tm);
+ ltk_text_line_recalculate(ltk_global->tm, tl);
}
/* must be NULL-terminated */
@@ -584,6 +616,9 @@ ltk_text_line_create(void) {
line->dir = FRIBIDI_TYPE_ON;
line->len = 0;
line->cursor_pos = 0;
+ /* FIXME */
+ line->font_size = 15;
+ return line;
error:
(void)fprintf(stderr, "No memory left while creating text line\n");
exit(1);
diff --git a/text_buffer.h b/text_buffer.h
@@ -42,7 +42,6 @@ struct ltk_text_run {
LtkGlyph *glyphs;
unsigned int num_glyphs;
struct ltk_text_run *next;
- struct ltk_text_run *last;
size_t start_index;
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;
diff --git a/text_edit.c b/text_edit.c
@@ -34,6 +34,7 @@
#include "array.h"
#include "text_buffer.h"
#include "text_edit.h"
+#include "grid.h"
extern Ltk *ltk_global;
@@ -44,8 +45,11 @@ ltk_draw_text_edit(LtkTextEdit *te) {
LtkRect rect = te->widget.rect;
LtkWindow *window = te->widget.window;
if (!te->img)
- 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->img, 0, 0, rect.x, rect.y, te->tl->w, te->tl->h);
+ te->img = ltk_render_text_line_new(te->tl, rect.w, ltk_global->display, window->xwindow, window->gc, ltk_global->colormap, fg, bg);
+ printf("%p\n", te->img);
+ fflush(stdout);
+ printf("%d,%d;%d,%d;%d,%d\n", rect.x, rect.y, rect.w, rect.h, te->img->width, te->img->height);
+ XPutImage(ltk_global->display, window->xwindow, window->gc, te->img, 0, 0, rect.x, rect.y, te->img->width, te->img->height);
}
LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text) {
@@ -56,6 +60,7 @@ LtkTextEdit *ltk_create_text_edit(LtkWindow *window, const char *text) {
te->tl = ltk_text_line_create();
ltk_text_line_insert_utf8(te->tl, text);
te->img = NULL;
+ return te;
}
void ltk_destroy_text_edit(LtkTextEdit *te) {
ltk_text_line_destroy(te->tl);