commit 440540f9caf405888a176c460cffff8669478b9e
parent 314d62ddd8c698b01e5f97dce74189beeee3e010
Author: lumidify <nobody@lumidify.org>
Date: Thu, 14 May 2020 21:31:27 +0200
Well, I guess I can leave it for the night now
Diffstat:
4 files changed, 39 insertions(+), 17 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,4 @@
test
*.o
test1
+*.core
diff --git a/text-hb.c b/text-hb.c
@@ -226,6 +226,10 @@ ltk_create_text_segment(LtkTextManager *tm, uint32_t *text, unsigned int len, ui
hb_buffer_set_direction(buf, dir);
hb_buffer_set_script(buf, script);
hb_buffer_add_utf32(buf, ts->str, len, 0, len);
+ for (int i = 0; i < len; i++) {
+ printf("%d\n", ts->str[i]);
+ }
+ printf("\n");
/* 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);
diff --git a/text_buffer.c b/text_buffer.c
@@ -115,7 +115,7 @@ ltk_render_text_line_new(
XWindowAttributes attrs;
XGetWindowAttributes(dpy, window, &attrs);
int depth = attrs.depth;
- img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, max_width, tl->h * tl->wrap_indeces->len, 32, 0);
+ img = XCreateImage(dpy, CopyFromParent, depth, ZPixmap, 0, NULL, max_width, (tl->h + tl->line_gap) * tl->wrap_indeces->len, 32, 0);
img->data = calloc(img->bytes_per_line, img->height);
XInitImage(img);
@@ -143,7 +143,7 @@ ltk_render_text_line_new(
int index;
while (cur) {
for (int k = 0; k < cur->num_glyphs; k++) {
- index = HB_DIRECTION_IS_BACKWARD(cur->dir) ? cur->num_glyphs - k - 1 : k;
+ index = par_is_rtl ? cur->num_glyphs - k - 1 : k;
glyph = &cur->glyphs[index];
x = par_is_rtl ? max_width - ((tl->w - glyph->x_abs) - cur_line_x) : glyph->x_abs - cur_line_x;
if (par_is_rtl && x < 0) {
@@ -155,7 +155,7 @@ ltk_render_text_line_new(
cur_line_x = glyph->x_abs;
x = glyph->x_abs - cur_line_x;
}
- y = glyph->y_abs + tl->h * cur_line;
+ y = glyph->y_abs + (tl->h + tl->line_gap) * cur_line;
/* FIXME: remove this when everything's fixed */
if (x < 0)
x = 0;
@@ -339,15 +339,21 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
size_t end_index;
hb_direction_t dir;
int par_is_rtl = FRIBIDI_IS_RTL(tl->dir);
+ for (int i = 0; i < tl->len; i++) {
+ printf("%d, %d, %d, %d\n", tl->bidi_levels->buf[i], tl->scripts->buf[i], tl->log2vis->buf[i], tl->vis2log->buf[i]);
+ }
while (start_index < tl->len) {
end_index = start_index;
- cur_level = last_level = tl->bidi_levels->buf[start_index];
- cur_script = last_script = tl->scripts->buf[start_index];
+ cur_level = last_level = tl->bidi_levels->buf[tl->vis2log->buf[start_index]];
+ cur_script = last_script = tl->scripts->buf[tl->vis2log->buf[start_index]];
while (end_index < tl->len &&
cur_level == last_level && cur_script == last_script) {
end_index++;
- cur_level = tl->bidi_levels->buf[end_index];
- cur_script = tl->scripts->buf[end_index];
+ /* I should probably make this nicer at some point */
+ if (end_index < tl->len) {
+ cur_level = tl->bidi_levels->buf[tl->vis2log->buf[end_index]];
+ cur_script = tl->scripts->buf[tl->vis2log->buf[end_index]];
+ }
}
dir = HB_DIRECTION_LTR;
if (FRIBIDI_LEVEL_IS_RTL(last_level))
@@ -365,6 +371,7 @@ ltk_text_line_itemize(struct ltk_text_line *tl) {
}
tl->first_run = first_run;
tl->last_run = cur_run;
+ cur_run = first_run;
}
static void
@@ -375,7 +382,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
tr->font_id = font_id;
tr->font_size = font_size;
- uint32_t attr = font_id << 16 + font_size;
+ uint32_t attr = (uint32_t)font_id << 16 + font_size;
/* FIXME: turn this into ltk_get_glyph_cache */
k = kh_get(glyphcache, tm->glyph_cache, attr);
if (k == kh_end(tm->glyph_cache)) {
@@ -389,12 +396,15 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
tr->num_glyphs = 0;
buf = hb_buffer_create();
- //hb_buffer_set_direction(buf, tr->dir);
- /* I think FriBidi already mirrors everything */
- hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
+ /* Harfbuzz requires the original, non-reversed text.
+ Yes, I know this is a bit hacky */
+ size_t start_index = tl->vis2log->buf[tr->start_index];
+ size_t end_index = tl->vis2log->buf[tr->start_index + tr->len - 1];
+ if (start_index > end_index)
+ start_index = end_index;
+ hb_buffer_add_utf32(buf, tl->log_buf->buf, tl->len, start_index, tr->len);
+ 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_utf32(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);
@@ -402,10 +412,13 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
ginf = hb_buffer_get_glyph_infos(buf, &tr->num_glyphs);
gpos = hb_buffer_get_glyph_positions(buf, &tr->num_glyphs);
float scale = stbtt_ScaleForMappingEmToPixels(&tr->font->info, font_size);
+ for (int i = start_index; i < start_index + tr->len; i++) {
+ printf("%d %d\n", tl->log_buf->buf[i], tr->len);
+ }
+ printf("\n");
int x_min = INT_MAX, x_max = INT_MIN, y_min = INT_MAX, y_max = INT_MIN;
int x_abs = 0, y_abs = 0, x1_abs, y1_abs, x2_abs, y2_abs;
- /* magic, do not touch */
tr->glyphs = malloc(sizeof(LtkGlyph) * tr->num_glyphs);
if (!tr->glyphs) {
(void)fprintf(stderr, "Cannot allocate space for glyphs.\n");
@@ -414,6 +427,7 @@ ltk_text_run_shape(LtkTextManager *tm, struct ltk_text_run *tr,
/* FIXME: should x_max be calculated using glyph->info->w?
The advance might be different and not represent where pixels
will actually have to be drawn. */
+ /* magic, do not touch */
LtkGlyph *glyph;
for (int i = 0; i < tr->num_glyphs; i++) {
gi = &ginf[i];
@@ -562,7 +576,8 @@ ltk_text_line_recalculate(LtkTextManager *tm, struct ltk_text_line *tl) {
/* this needs to be done after shaping so the fonts, etc. aren't
removed if their reference counts drop and then loaded again
right afterwards */
- ltk_text_line_destroy_runs(old_runs);
+ if (old_runs)
+ ltk_text_line_destroy_runs(old_runs);
}
@@ -618,7 +633,8 @@ ltk_text_line_create(void) {
line->len = 0;
line->cursor_pos = 0;
/* FIXME */
- line->font_size = 15;
+ line->font_size = 20;
+ line->line_gap = 5;
return line;
error:
(void)fprintf(stderr, "No memory left while creating text line\n");
diff --git a/text_buffer.h b/text_buffer.h
@@ -44,7 +44,7 @@ struct ltk_text_run {
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 */
+ size_t len;
int start_x;
int start_y;
int w;
@@ -81,6 +81,7 @@ struct ltk_text_line {
int w;
int h;
size_t cursor_pos;
+ unsigned int line_gap;
};
struct ltk_text_buffer {