diff --git a/src/newgdi/layout-ellipsize.c b/src/newgdi/layout-ellipsize.c index 524af21e..2abe20ba 100644 --- a/src/newgdi/layout-ellipsize.c +++ b/src/newgdi/layout-ellipsize.c @@ -167,7 +167,7 @@ static void init_state (EllipsizeState *state, LAYOUTLINE *line) i = 0; list_for_each (l, &line->gruns) { GlyphRun *run = (GlyphRun*)l; - int width = __mg_glyph_string_get_width (run->gs); + int width = __mg_glyph_string_get_width (run->gstr); state->run_info[i].run = run; state->run_info[i].width = width; state->run_info[i].start_offset = start_offset; @@ -195,7 +195,7 @@ static void free_state (EllipsizeState *state) static int get_cluster_width (LineIter *iter) { GlyphRunIter *run_iter = &iter->run_iter; - GlyphString *glyphs = run_iter->glyph_run->gs; + GlyphString *glyphs = run_iter->glyph_run->gstr; int width = 0; int i; @@ -308,7 +308,7 @@ static void shape_ellipsis (EllipsizeState *state) */ if (!state->ellipsis_grun) { state->ellipsis_grun = malloc (sizeof(GlyphRun)); - state->ellipsis_grun->gs = __mg_glyph_string_new (); + state->ellipsis_grun->gstr = __mg_glyph_string_new (); state->ellipsis_grun->lrun = NULL; } @@ -326,7 +326,7 @@ static void shape_ellipsis (EllipsizeState *state) ellipsis_ucs = _ellipsis_baseline; } - text_run = __mg_textruns_get_by_offset(state->layout->truninfo, + text_run = __mg_text_run_get_by_offset(state->layout->truninfo, state->gap_start_iter.run_iter.start_index, NULL); layout_run = __mg_layout_run_new_orphan (state->layout, text_run, @@ -345,7 +345,7 @@ static void shape_ellipsis (EllipsizeState *state) state->ellipsis_lrun = layout_run; /* Now shape */ - glyphs = state->ellipsis_grun->gs; + glyphs = state->ellipsis_grun->gstr; __mg_shape_layout_run(state->layout->truninfo, layout_run, glyphs); state->ellipsis_width = 0; @@ -371,7 +371,7 @@ static void update_ellipsis_shape (EllipsizeState *state) BOOL is_cjk; const TextRun* text_run; - text_run = __mg_textruns_get_by_offset(state->layout->truninfo, + text_run = __mg_text_run_get_by_offset(state->layout->truninfo, state->gap_start_iter.run_iter.start_index, NULL); if (state->fontname != text_run->fontname) { @@ -545,7 +545,7 @@ static BOOL remove_one_span (EllipsizeState *state) */ static void fixup_ellipsis_grun (EllipsizeState *state) { - GlyphString *glyphs = state->ellipsis_grun->gs; + GlyphString *glyphs = state->ellipsis_grun->gstr; LayoutRun *layout_run = state->ellipsis_lrun; int level; int i; diff --git a/src/newgdi/layout-utils.c b/src/newgdi/layout-utils.c index fd3efb64..f8bf0d1d 100644 --- a/src/newgdi/layout-utils.c +++ b/src/newgdi/layout-utils.c @@ -336,8 +336,8 @@ void __mg_glyph_run_free(GlyphRun* run) __mg_layout_run_free(run->lrun); } - if (run->gs) { - __mg_glyph_string_free(run->gs); + if (run->gstr) { + __mg_glyph_string_free(run->gstr); } free(run); @@ -382,21 +382,21 @@ GlyphRun *__mg_glyph_run_split (GlyphRun *orig, int split_index) return NULL; if (LTR (orig)) { - for (i = 0; i < orig->gs->nr_glyphs; i++) { - if (orig->gs->log_clusters[i] >= split_index) + for (i = 0; i < orig->gstr->nr_glyphs; i++) { + if (orig->gstr->log_clusters[i] >= split_index) break; } - if (i == orig->gs->nr_glyphs) + if (i == orig->gstr->nr_glyphs) // No splitting necessary return NULL; - split_index = orig->gs->log_clusters[i]; + split_index = orig->gstr->log_clusters[i]; nr_glyphs = i; } else { - for (i = orig->gs->nr_glyphs - 1; i >= 0; i--) { - if (orig->gs->log_clusters[i] >= split_index) + for (i = orig->gstr->nr_glyphs - 1; i >= 0; i--) { + if (orig->gstr->log_clusters[i] >= split_index) break; } @@ -404,48 +404,48 @@ GlyphRun *__mg_glyph_run_split (GlyphRun *orig, int split_index) // No splitting necessary return NULL; - split_index = orig->gs->log_clusters[i]; - nr_glyphs = orig->gs->nr_glyphs - 1 - i; + split_index = orig->gstr->log_clusters[i]; + nr_glyphs = orig->gstr->nr_glyphs - 1 - i; } - num_remaining = orig->gs->nr_glyphs - nr_glyphs; + num_remaining = orig->gstr->nr_glyphs - nr_glyphs; new_grun = malloc (sizeof(GlyphRun)); new_grun->lrun = __mg_layout_run_split(orig->lrun, split_index); - new_grun->gs = __mg_glyph_string_new (); - __mg_glyph_string_set_size (new_grun->gs, nr_glyphs); + new_grun->gstr = __mg_glyph_string_new (); + __mg_glyph_string_set_size (new_grun->gstr, nr_glyphs); if (LTR (orig)) { - memcpy(new_grun->gs->glyphs, - orig->gs->glyphs, + memcpy(new_grun->gstr->glyphs, + orig->gstr->glyphs, nr_glyphs * sizeof(ShapedGlyph)); - memcpy(new_grun->gs->log_clusters, - orig->gs->log_clusters, + memcpy(new_grun->gstr->log_clusters, + orig->gstr->log_clusters, nr_glyphs * sizeof(int)); - memmove (orig->gs->glyphs, - orig->gs->glyphs + nr_glyphs, + memmove (orig->gstr->glyphs, + orig->gstr->glyphs + nr_glyphs, num_remaining * sizeof(ShapedGlyph)); - for (i = nr_glyphs; i < orig->gs->nr_glyphs; i++) - orig->gs->log_clusters[i - nr_glyphs] = - orig->gs->log_clusters[i] - split_index; + for (i = nr_glyphs; i < orig->gstr->nr_glyphs; i++) + orig->gstr->log_clusters[i - nr_glyphs] = + orig->gstr->log_clusters[i] - split_index; } else { - memcpy (new_grun->gs->glyphs, - orig->gs->glyphs + num_remaining, + memcpy (new_grun->gstr->glyphs, + orig->gstr->glyphs + num_remaining, nr_glyphs * sizeof(ShapedGlyph)); - memcpy (new_grun->gs->log_clusters, - orig->gs->log_clusters + num_remaining, + memcpy (new_grun->gstr->log_clusters, + orig->gstr->log_clusters + num_remaining, nr_glyphs * sizeof(int)); for (i = 0; i < num_remaining; i++) - orig->gs->log_clusters[i] = - orig->gs->log_clusters[i] - split_index; + orig->gstr->log_clusters[i] = + orig->gstr->log_clusters[i] - split_index; } - __mg_glyph_string_set_size (orig->gs, - orig->gs->nr_glyphs - nr_glyphs); + __mg_glyph_string_set_size (orig->gstr, + orig->gstr->nr_glyphs - nr_glyphs); return new_grun; } @@ -453,7 +453,7 @@ GlyphRun *__mg_glyph_run_split (GlyphRun *orig, int split_index) BOOL __mg_glyph_run_iter_next_cluster (GlyphRunIter *iter) { int glyph_index = iter->end_glyph; - GlyphString *glyphs = iter->glyph_run->gs; + GlyphString *glyphs = iter->glyph_run->gstr; int cluster; const LayoutRun *item = iter->glyph_run->lrun; @@ -517,7 +517,7 @@ BOOL __mg_glyph_run_iter_next_cluster (GlyphRunIter *iter) BOOL __mg_glyph_run_iter_prev_cluster (GlyphRunIter *iter) { int glyph_index = iter->start_glyph; - GlyphString *glyphs = iter->glyph_run->gs; + GlyphString *glyphs = iter->glyph_run->gstr; int cluster; const LayoutRun *item = iter->glyph_run->lrun; @@ -592,7 +592,7 @@ BOOL __mg_glyph_run_iter_init_start (GlyphRunIter *iter, if (LTR (glyph_run)) iter->end_glyph = 0; else - iter->end_glyph = glyph_run->gs->nr_glyphs - 1; + iter->end_glyph = glyph_run->gstr->nr_glyphs - 1; iter->end_index = glyph_run->lrun->si; iter->end_char = 0; @@ -612,7 +612,7 @@ BOOL __mg_glyph_run_iter_init_end (GlyphRunIter *iter, iter->text = text; if (LTR (glyph_run)) - iter->start_glyph = glyph_run->gs->nr_glyphs; + iter->start_glyph = glyph_run->gstr->nr_glyphs; else iter->start_glyph = -1; @@ -644,7 +644,7 @@ void __mg_glyph_run_get_logical_widths (const GlyphRun *glyph_run, for (glyph_index = iter.start_glyph; glyph_index != iter.end_glyph; glyph_index += dir) { - cluster_width += glyph_run->gs->glyphs[glyph_index].width; + cluster_width += glyph_run->gstr->glyphs[glyph_index].width; } num_chars = iter.end_char - iter.start_char; diff --git a/src/newgdi/layoutinfo.c b/src/newgdi/layoutinfo.c index 8e4b074e..29e01b3c 100644 --- a/src/newgdi/layoutinfo.c +++ b/src/newgdi/layoutinfo.c @@ -270,8 +270,8 @@ static int get_line_width(LAYOUTLINE *line) list_for_each(l, &line->gruns) { GlyphRun *run = (GlyphRun*)l; - for (i = 0; i < run->gs->nr_glyphs; i++) - width += run->gs->glyphs[i].width; + for (i = 0; i < run->gstr->nr_glyphs; i++) + width += run->gstr->glyphs[i].width; } return width; @@ -373,7 +373,7 @@ static GlyphString* shape_run(LAYOUTLINE *line, LayoutState *state, int space_left, space_right; glyph_run.lrun = lrun; - glyph_run.gs = glyphs; + glyph_run.gstr = glyphs; __mg_glyph_run_letter_space (&glyph_run, layout->truninfo->ucs, @@ -391,25 +391,26 @@ static GlyphString* shape_run(LAYOUTLINE *line, LayoutState *state, return glyphs; } -static void free_run (GlyphRun *run) +static void free_glyph_run (GlyphRun *grun) { - __mg_glyph_string_free(run->gs); - free(run); + if (grun->lrun) { + __mg_layout_run_free(grun->lrun); + grun->lrun = NULL; + } + + __mg_glyph_string_free(grun->gstr); + free(grun); } -static LayoutRun *uninsert_run (LAYOUTLINE *line) +static void uninsert_run (LAYOUTLINE *line) { - GlyphRun *run; - LayoutRun *lrun; - - run = (GlyphRun*)&line->gruns.next; - lrun = run->lrun; + GlyphRun *grun; + grun = (GlyphRun*)&line->gruns.next; list_del(line->gruns.next); - line->len -= run->lrun->len; + line->len -= grun->lrun->len; - free_run(run); - return lrun; + free_glyph_run(grun); } static GlyphRun* insert_run(LAYOUTLINE *line, LayoutState *state, @@ -420,9 +421,9 @@ static GlyphRun* insert_run(LAYOUTLINE *line, LayoutState *state, glyph_run->lrun = layout_run; if (last_run && state->log_widths_offset == 0) - glyph_run->gs = state->glyphs; + glyph_run->gstr = state->glyphs; else - glyph_run->gs = shape_run(line, state, layout_run); + glyph_run->gstr = shape_run(line, state, layout_run); if (last_run) { if (state->log_widths_offset > 0) @@ -474,8 +475,8 @@ static inline BOOL can_break_in (LAYOUTINFO *layout, } /* - * Tries to insert as much as possible of the text runs at the head of - * state->lruns onto @line. Five results are possible: + * Tries to insert as much as possible of the current layout run onto @line. + * Five results are possible: * * %BREAK_NONE_FIT: Couldn't fit anything. * %BREAK_SOME_FIT: The lrun was broken in the middle. @@ -493,7 +494,7 @@ static inline BOOL can_break_in (LAYOUTINFO *layout, * or %BREAK_NONE_FIT returned. This is used when the end of the * run is not a break position. */ -BreakResult process_text_run(LAYOUTINFO *layout, +BreakResult process_layout_run(LAYOUTINFO *layout, LAYOUTLINE *line, LayoutState *state, BOOL force_fit, BOOL no_break_at_end) { @@ -555,7 +556,7 @@ BreakResult process_text_run(LAYOUTINFO *layout, GlyphRun glyph_run; glyph_run.lrun = lrun; - glyph_run.gs = state->glyphs; + glyph_run.gstr = state->glyphs; state->log_widths = malloc (sizeof (int) * lrun->len); __mg_glyph_run_get_logical_widths(&glyph_run, layout->truninfo->ucs, @@ -631,7 +632,7 @@ retry_break: subtract the new width */ state->remaining_width += break_width; grun = insert_run (line, state, new_lrun, FALSE); - break_width = __mg_glyph_string_get_width(grun->gs); + break_width = __mg_glyph_string_get_width(grun->gstr); state->remaining_width -= break_width; state->log_widths_offset += break_num_chars; @@ -713,12 +714,104 @@ static void line_set_resolved_dir(LAYOUTLINE *line, GlyphRunDir direction) } } -static void reorder_runs(LAYOUTLINE *line, int nr_runs) +static struct list_head reorder_runs_recurse (struct list_head* entry, + int n_items) { + struct list_head *tmp, *level_start_node; + int i, level_start_i; + int min_level = INT_MAX; + struct list_head result; + + INIT_LIST_HEAD(&result); + + if (n_items == 0) + return result; + + tmp = entry; + for (i = 0; i < n_items; i++) { + GlyphRun *run = (GlyphRun*)tmp; + min_level = MIN (min_level, run->lrun->el); + tmp = tmp->next; + } + + level_start_i = 0; + level_start_node = entry; + tmp = entry; + for (i = 0; i < n_items; i++) { + GlyphRun *run = (GlyphRun*)tmp; + + if (run->lrun->el == min_level) { + if (min_level % 2) { + if (i > level_start_i) { + struct list_head sub_result; + sub_result = reorder_runs_recurse (level_start_node, + i - level_start_i); + + if (!list_empty(&result)) { + list_add_tail(result.next, &sub_result); + } + result = sub_result; + } + list_add(&run->list, &result); + } + else { + if (i > level_start_i) { + struct list_head sub_result; + sub_result = reorder_runs_recurse (level_start_node, + i - level_start_i); + if (!list_empty(&sub_result)) { + list_add_tail(sub_result.next, &result); + } + } + list_add(&run->list, &result); + } + + level_start_i = i + 1; + level_start_node = tmp->next; + } + + tmp = tmp->next; + } + + if (min_level % 2) { + if (i > level_start_i) { + struct list_head sub_result; + sub_result = reorder_runs_recurse (level_start_node, + i - level_start_i); + if (!list_empty(&result)) { + list_add_tail(result.next, &sub_result); + } + result = sub_result; + } + } + else { + if (i > level_start_i) { + struct list_head sub_result; + sub_result = reorder_runs_recurse (level_start_node, + i - level_start_i); + if (!list_empty(&sub_result)) { + list_add_tail(sub_result.next, &result); + } + } + } + + return result; } static void reverse_runs(LAYOUTLINE *line) { + struct list_head tmp_head; + + INIT_LIST_HEAD(&tmp_head); + + while (!list_empty(&line->gruns)) { + GlyphRun* run = (GlyphRun*)line->gruns.prev; + list_del(line->gruns.prev); + + list_add_tail(&run->list, &tmp_head); + } + + line->gruns = tmp_head; } static void layout_line_reorder(LAYOUTLINE *line) @@ -728,7 +821,7 @@ static void layout_line_reorder(LAYOUTLINE *line) Uint8 level_or = 0, level_and = 1; int length = 0; - /* Check if all lruns are in the same direction, in that case, the + /* Check if all gruns are in the same direction, in that case, the * line does not need modification and we can avoid the expensive * reorder runs recurse procedure. */ @@ -748,7 +841,7 @@ static void layout_line_reorder(LAYOUTLINE *line) all_odd = (level_and & 0x1) == 1; if (!all_even && !all_odd) { - reorder_runs(line, length); + line->gruns = reorder_runs_recurse(line->gruns.next, length); } else if (all_odd) reverse_runs(line); @@ -759,7 +852,7 @@ static void zero_line_final_space (LAYOUTLINE *line, { LAYOUTINFO *layout = line->layout; LayoutRun *lrun = run->lrun; - GlyphString *glyphs = run->gs; + GlyphString *glyphs = run->gstr; int glyph = lrun->el % 2 ? 0 : glyphs->nr_glyphs - 1; /* if the final char of line forms a cluster, and it's @@ -878,7 +971,7 @@ static void adjust_line_letter_spacing(LAYOUTLINE *line, LayoutState *state) } if (is_tab_run (layout, run)) { - pad_glyphstring_right (run->gs, state, tab_adjustment); + pad_glyphstring_right (run->gstr, state, tab_adjustment); tab_adjustment = 0; } else { @@ -889,23 +982,23 @@ static void adjust_line_letter_spacing(LAYOUTLINE *line, LayoutState *state) distribute_letter_spacing (run_spacing, &space_left, &space_right); - if (run->gs->glyphs[0].width == 0) { + if (run->gstr->glyphs[0].width == 0) { /* we've zeroed this space glyph at the end of line, now remove * the letter spacing added to its adjacent glyph */ - pad_glyphstring_left (run->gs, state, -space_left); + pad_glyphstring_left (run->gstr, state, -space_left); } else if (!visual_last_run || is_tab_run(layout, visual_last_run)) { - pad_glyphstring_left(run->gs, state, -space_left); + pad_glyphstring_left(run->gstr, state, -space_left); tab_adjustment += space_left; } - if (run->gs->glyphs[run->gs->nr_glyphs - 1].width == 0) { + if (run->gstr->glyphs[run->gstr->nr_glyphs - 1].width == 0) { /* we've zeroed this space glyph at the end of line, now remove * the letter spacing added to its adjacent glyph */ - pad_glyphstring_right (run->gs, state, -space_right); + pad_glyphstring_right (run->gstr, state, -space_right); } else if (!visual_next_run || is_tab_run(layout, visual_next_run)) { - pad_glyphstring_right(run->gs, state, - space_right); + pad_glyphstring_right(run->gstr, state, - space_right); tab_adjustment += space_right; } } @@ -949,7 +1042,7 @@ static void justify_clusters (LAYOUTLINE *line, LayoutState *state) list_for_each(run_iter, &line->gruns) { GlyphRun *run = (GlyphRun*)run_iter; - GlyphString *glyphs = run->gs; + GlyphString *glyphs = run->gstr; GlyphRunIter cluster_iter; BOOL have_cluster; int dir; @@ -1088,7 +1181,7 @@ static void justify_words (LAYOUTLINE *line, list_for_each(run_iter, &line->gruns) { GlyphRun *run = (GlyphRun *)run_iter; - GlyphString *glyphs = run->gs; + GlyphString *glyphs = run->gstr; GlyphRunIter cluster_iter; BOOL have_cluster; int offset; @@ -1158,7 +1251,7 @@ static int layout_line_get_width (LAYOUTLINE *line) list_for_each(i, &line->gruns) { GlyphRun *run = (GlyphRun*)i; - width += __mg_glyph_string_get_width (run->gs); + width += __mg_glyph_string_get_width (run->gstr); } return width; @@ -1216,7 +1309,6 @@ static void layout_line_postprocess (LAYOUTLINE *line, static LAYOUTLINE* check_next_line(LAYOUTINFO* layout, LayoutState* state) { LAYOUTLINE *line; - struct list_head* t; BOOL have_break = FALSE; // If we've seen a possible break yet int break_remaining_width = 0;// Left width before adding run with break @@ -1234,8 +1326,7 @@ static LAYOUTLINE* check_next_line(LAYOUTINFO* layout, LayoutState* state) else state->remaining_width = state->line_width; - list_for_each_ex(t, &layout->truninfo->truns, &state->trun->list) { - state->trun = (const TextRun*)t; + while (state->trun) { LayoutRun *lrun; BreakResult result; int old_num_chars; @@ -1243,34 +1334,33 @@ static LAYOUTLINE* check_next_line(LAYOUTINFO* layout, LayoutState* state) BOOL first_lrun_in_line; if (state->start_index_in_trun > 0) { - lrun = __mg_layout_run_new_from_offset(layout, + state->lrun = __mg_layout_run_new_from_offset(layout, state->trun, state->start_index_in_trun); } else { - lrun = __mg_layout_run_new_from(layout, state->trun); + state->lrun = __mg_layout_run_new_from(layout, state->trun); } - state->lrun = lrun; + lrun = state->lrun; old_num_chars = lrun->len; old_remaining_width = state->remaining_width; first_lrun_in_line = list_empty(&line->gruns); - result = process_text_run(layout, line, state, !have_break, FALSE); + result = process_layout_run(layout, line, state, !have_break, FALSE); switch (result) { case BREAK_ALL_FIT: if (can_break_in (layout, state->start_offset, - old_num_chars, first_lrun_in_line)) - { + old_num_chars, first_lrun_in_line)) { have_break = TRUE; break_remaining_width = old_remaining_width; break_start_offset = state->start_offset; break_link = line->gruns.next; } - // FIXME - // state->lruns = g_list_delete_link (state->lruns, state->lruns); + state->trun = (const TextRun*)state->trun->list.next; + if (&state->trun->list == &layout->truninfo->truns) + state->trun = NULL; state->start_offset += old_num_chars; - break; case BREAK_EMPTY_FIT: @@ -1284,30 +1374,39 @@ static LAYOUTLINE* check_next_line(LAYOUTINFO* layout, LayoutState* state) case BREAK_NONE_FIT: /* Back up over unused runs to run where there is a break */ - while (!list_empty(&line->gruns) && line->gruns.next != break_link) - { - state->lrun = uninsert_run (line); + while (!list_empty(&line->gruns) && + line->gruns.next != break_link) { + uninsert_run(line); } state->start_offset = break_start_offset; state->remaining_width = break_remaining_width; + /* determine start text run again */ + state->trun = __mg_text_run_get_by_offset(layout->truninfo, + state->start_offset, &state->start_index_in_trun); + if (state->start_index_in_trun > 0) { + state->lrun = __mg_layout_run_new_from_offset(layout, + state->trun, state->start_index_in_trun); + } + else { + state->lrun = __mg_layout_run_new_from(layout, state->trun); + } + /* Reshape run to break */ lrun = state->lrun; - old_num_chars = lrun->len; - result = process_text_run (layout, line, state, TRUE, TRUE); + result = process_layout_run(layout, line, state, TRUE, TRUE); assert(result == BREAK_SOME_FIT || result == BREAK_EMPTY_FIT); state->start_offset += old_num_chars - lrun->len; - wrapped = TRUE; goto done; case BREAK_LINE_SEPARATOR: - // FIXME: - // state->lruns = g_list_delete_link (state->lruns, state->lruns); - + state->trun = (const TextRun*)state->trun->list.next; + if (&state->trun->list == &layout->truninfo->truns) + state->trun = NULL; state->start_offset += old_num_chars; /* A line-separate is just a forced break. Set wrapped, so we do * justification */ @@ -1381,7 +1480,7 @@ LAYOUTLINE* GUIAPI LayoutNextLine( } else { state.line_start_index = layout->truninfo->nr_ucs - layout->nr_left_ucs; - state.trun = __mg_textruns_get_by_offset(layout->truninfo, + state.trun = __mg_text_run_get_by_offset(layout->truninfo, state.start_offset, &state.start_index_in_trun); if (state.trun == NULL) { next_line = NULL; diff --git a/src/newgdi/layoutinfo.h b/src/newgdi/layoutinfo.h index 4aa86f0d..51fcea4d 100644 --- a/src/newgdi/layoutinfo.h +++ b/src/newgdi/layoutinfo.h @@ -67,7 +67,6 @@ struct _GlyphString { #define LAYOUTRUN_FLAG_ORPHAN 0x01 struct _LayoutRun { - struct list_head list; LOGFONT* lf; // the logfont for this run const Uchar32* ucs; // the uchar string @@ -84,7 +83,7 @@ struct _LayoutRun { struct _GlyphRun { struct list_head list; LayoutRun* lrun; // the layout run corresponding to the glyph run - GlyphString* gs; // the glyph string + GlyphString* gstr; // the glyph string }; struct _LAYOUTLINE { diff --git a/src/newgdi/textrunsinfo.c b/src/newgdi/textrunsinfo.c index 8adf7d33..15a42d8b 100644 --- a/src/newgdi/textrunsinfo.c +++ b/src/newgdi/textrunsinfo.c @@ -563,10 +563,26 @@ RGBCOLOR __mg_textruns_get_text_color(const TEXTRUNSINFO* runinfo, int index) return runinfo->attrs.value; } -const TextRun* __mg_textruns_get_by_offset(const TEXTRUNSINFO* runinfo, - int offset, int *start_index) +const TextRun* __mg_text_run_get_by_offset(const TEXTRUNSINFO* runinfo, + int index, int *start_offset) { - return NULL; + struct list_head *i; + TextRun* found = NULL; + + list_for_each(i, &runinfo->truns) { + TextRun* trun = (TextRun*)i; + if (index >= trun->si && + (index < trun->si + trun->len)) { + found = trun; + if (start_offset) { + *start_offset = index - trun->si; + } + + break; + } + } + + return found; } BOOL GUIAPI SetTextColorInTextRuns(TEXTRUNSINFO* runinfo, diff --git a/src/newgdi/textrunsinfo.h b/src/newgdi/textrunsinfo.h index 3dae2250..034ff98b 100644 --- a/src/newgdi/textrunsinfo.h +++ b/src/newgdi/textrunsinfo.h @@ -126,8 +126,9 @@ extern "C" { #endif /* __cplusplus */ RGBCOLOR __mg_textruns_get_color(const TEXTRUNSINFO* runinfo, int index); -const TextRun* __mg_textruns_get_by_offset(const TEXTRUNSINFO* runinfo, - int offset, int *start_index); + +const TextRun* __mg_text_run_get_by_offset(const TEXTRUNSINFO* runinfo, + int index, int *start_offset); #ifdef __cplusplus }