reorder glyph runs according to embedding levels

This commit is contained in:
Vincent Wei
2019-03-25 15:31:03 +08:00
parent 7dfe5954f5
commit d09313407e
6 changed files with 222 additions and 107 deletions
+7 -7
View File
@@ -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;
+35 -35
View File
@@ -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;
+157 -58
View File
@@ -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;
+1 -2
View File
@@ -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 {
+19 -3
View File
@@ -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,
+3 -2
View File
@@ -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
}