From 274fdaaa31ba50d8cd7827801ad4859fb8f01f44 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Sun, 24 Mar 2019 19:00:15 +0800 Subject: [PATCH] go on --- src/newgdi/layout-ellipsize.c | 204 +++++++++++---------------- src/newgdi/layout-utils.c | 243 ++++++++++++++++++++++++++++++-- src/newgdi/layoutinfo.c | 96 +++++-------- src/newgdi/layoutinfo.h | 49 ++++++- src/newgdi/shape-glyphs-basic.c | 4 +- src/newgdi/textrunsinfo.c | 168 ++++------------------ src/newgdi/textrunsinfo.h | 29 ++-- 7 files changed, 421 insertions(+), 372 deletions(-) diff --git a/src/newgdi/layout-ellipsize.c b/src/newgdi/layout-ellipsize.c index 0b0584aa..42ddddf5 100644 --- a/src/newgdi/layout-ellipsize.c +++ b/src/newgdi/layout-ellipsize.c @@ -125,30 +125,27 @@ struct _LineIter struct _EllipsizeState { LAYOUTINFO *layout; /* Layout being ellipsized */ - //PangoAttrList *attrs; /* Attributes used for itemization/shaping */ RunInfo *run_info; /* Array of information about each run */ int nr_runs; - int total_width; /* Original width of line in Pango units */ + int total_width; /* Original width of line in pixels */ int gap_center; /* Goal for center of gap */ - TextRun *ellipsis_trun; /* Text run created to hold ellipsis */ + LayoutRun *ellipsis_lrun; /* Layout run created to hold ellipsis */ GlyphRun *ellipsis_grun; /* Glyph run created to hold ellipsis */ - int ellipsis_width; /* Width of ellipsis, in Pango units */ + int ellipsis_width; /* Width of ellipsis, in pixels */ int ellipsis_is_cjk; /* Whether the first character in the ellipsized * is wide; this triggers us to try to use a * mid-line ellipsis instead of a baseline */ - - //PangoAttrIterator *line_start_attr; /* Cached PangoAttrIterator for the start of the run */ + const char* fontname; /* fontname of gap TextRun */ LineIter gap_start_iter; /* Iteratator pointing to the first cluster in gap */ - int gap_start_x; /* x position of start of gap, in Pango units */ - //PangoAttrIterator *gap_start_attr; /* Attribute iterator pointing to a range containing the first character in gap */ + int gap_start_x; /* x position of start of gap, in pixels */ LineIter gap_end_iter; /* Iterator pointing to last cluster in gap */ - int gap_end_x; /* x position of end of gap, in Pango units */ + int gap_end_x; /* x position of end of gap, in pixels */ }; /* Compute global information needed for the itemization process @@ -176,25 +173,20 @@ static void init_state (EllipsizeState *state, LAYOUTLINE *line) state->run_info[i].start_offset = start_offset; state->total_width += width; - start_offset += run->trun->len; + start_offset += run->lrun->len; i++; } - state->ellipsis_trun = NULL; + state->ellipsis_lrun = NULL; state->ellipsis_grun = NULL; state->ellipsis_is_cjk = FALSE; + state->fontname = NULL; } /* Cleanup memory allocation */ static void free_state (EllipsizeState *state) { -#if 0 - if (state->line_start_attr) - pango_attr_iterator_destroy (state->line_start_attr); - if (state->gap_start_attr) - pango_attr_iterator_destroy (state->gap_start_attr); -#endif free (state->run_info); } @@ -207,13 +199,13 @@ static int get_cluster_width (LineIter *iter) int width = 0; int i; - if (run_iter->start_glyph < run_iter->end_glyph) /* LTR */ - { + if (run_iter->start_glyph < run_iter->end_glyph) { + /* LTR */ for (i = run_iter->start_glyph; i < run_iter->end_glyph; i++) width += glyphs->glyphs[i].width; } - else /* RTL */ - { + else { + /* RTL */ for (i = run_iter->start_glyph; i > run_iter->end_glyph; i--) width += glyphs->glyphs[i].width; } @@ -287,7 +279,7 @@ static BOOL ends_at_ellipsization_boundary (EllipsizeState *state, LineIter *ite { RunInfo *run_info = &state->run_info[iter->run_index]; - if (iter->run_iter.end_char == run_info->run->trun->len && iter->run_index == state->nr_runs - 1) + if (iter->run_iter.end_char == run_info->run->lrun->len && iter->run_index == state->nr_runs - 1) return TRUE; return state->layout->bos[run_info->start_offset + iter->run_iter.end_char + 1] & BOV_GB_CURSOR_POS; @@ -296,13 +288,20 @@ static BOOL ends_at_ellipsization_boundary (EllipsizeState *state, LineIter *ite /* Shapes the ellipsis using the font and is_cjk information computed by * update_ellipsis_shape() from the first character in the gap. */ + +/* U+22EF: MIDLINE HORIZONTAL ELLIPSIS, used for CJK: "\342\213\257" */ +static const Uchar32 _ellipsis_midline[1] = {0x22EF}; +/* U+2026: HORIZONTAL ELLIPSIS: "\342\200\246" */ +static const Uchar32 _ellipsis_baseline[1] = {0x2026}; +static const Uchar32 _ellipsis_fallback[3] = {'.', '.', '.'}; + static void shape_ellipsis (EllipsizeState *state) { Glyph32 ellipsis_gv; - TextRun *text_run; + const TextRun* text_run; + LayoutRun *layout_run; GlyphString *glyphs; - Uchar32 ellipsis_ucs[3]; - int nr_ucs = 0; + const Uchar32* ellipsis_ucs; int i; /* Create/reset state->ellipsis_grun @@ -310,55 +309,44 @@ 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->trun = NULL; + state->ellipsis_grun->lrun = NULL; } - if (state->ellipsis_trun) { - __mg_text_run_free (state->ellipsis_trun); - state->ellipsis_trun = NULL; + if (state->ellipsis_lrun) { + __mg_layout_run_free (state->ellipsis_lrun); + state->ellipsis_lrun = NULL; } /* First try using a specific ellipsis character in the best matching font */ if (state->ellipsis_is_cjk) { - /* U+22EF: MIDLINE HORIZONTAL ELLIPSIS, used for CJK */ - ellipsis_ucs[0] = 0x22EF; // "\342\213\257"; - nr_ucs = 1; + ellipsis_ucs = _ellipsis_midline; } else { - /* U+2026: HORIZONTAL ELLIPSIS */ - ellipsis_ucs[0] = 0x2026; // "\342\200\246"; - nr_ucs = 1; + ellipsis_ucs = _ellipsis_baseline; } + text_run = __mg_textruns_get_by_offset(state->layout->truninfo, + state->gap_start_iter.run_iter.start_index, NULL); - text_run = __mg_text_run_new_orphan (state->layout->truninfo, - ellipsis_ucs, nr_ucs); - // TODO: other attributes of the text run. - - text_run->lf = __mg_create_logfont_for_run(state->layout->truninfo, text_run); - ellipsis_gv = GetGlyphValue(text_run->lf, ellipsis_ucs[0]); + layout_run = __mg_layout_run_new_orphan (state->layout, text_run, + ellipsis_ucs, 1); + ellipsis_gv = GetGlyphValue(layout_run->lf, ellipsis_ucs[0]); /* If the devfont of the glyph value of the specific ellipsis character * is SBC devfont, we use "...". */ if (DFI_IN_GLYPH(ellipsis_gv) == 0) { - __mg_text_run_free (text_run); - ellipsis_ucs[0] = '.'; - ellipsis_ucs[1] = '.'; - ellipsis_ucs[2] = '.'; - nr_ucs = 3; - text_run = __mg_text_run_new_orphan (state->layout->truninfo, - ellipsis_ucs, nr_ucs); + __mg_layout_run_free (layout_run); + layout_run = __mg_layout_run_new_orphan (state->layout, + text_run, ellipsis_ucs, 3); } - state->ellipsis_trun = text_run; + state->ellipsis_lrun = layout_run; - /* Now shape - */ + /* Now shape */ glyphs = state->ellipsis_grun->gs; - - __mg_shape_text_run(state->layout->truninfo, text_run, 0, nr_ucs, glyphs); + __mg_shape_layout_run(state->layout->truninfo, layout_run, glyphs); state->ellipsis_width = 0; for (i = 0; i < glyphs->nr_glyphs; i++) @@ -399,42 +387,15 @@ static void update_ellipsis_shape (EllipsizeState *state) BOOL recompute = FALSE; Uchar32 start_wc; BOOL is_cjk; + const TextRun* text_run; -#if 0 - /* Unfortunately, we can only advance PangoAttrIterator forward; so each - * time we back up we need to go forward to find the new position. To make - * this not utterly slow, we cache an iterator at the start of the line - */ - if (!state->line_start_attr) { - state->line_start_attr = pango_attr_list_get_iterator (state->attrs); - advance_iterator_to (state->line_start_attr, state->run_info[0].run->trun->offset); - } - - if (state->gap_start_attr) { - /* See if the current attribute range contains the new start position - */ - int start, end; - - pango_attr_iterator_range (state->gap_start_attr, &start, &end); - - if (state->gap_start_iter.run_iter.start_index < start) - { - pango_attr_iterator_destroy (state->gap_start_attr); - state->gap_start_attr = NULL; - } - } - - /* Check whether we need to recompute the ellipsis because of new font attributes - */ - if (!state->gap_start_attr) - { - state->gap_start_attr = pango_attr_iterator_copy (state->line_start_attr); - advance_iterator_to (state->gap_start_attr, - state->run_info[state->gap_start_iter.run_index].run->trun->offset); + text_run = __mg_textruns_get_by_offset(state->layout->truninfo, + state->gap_start_iter.run_iter.start_index, NULL); + if (state->fontname != text_run->fontname) { + state->fontname = text_run->fontname; recompute = TRUE; } -#endif /* Check whether we need to recompute the ellipsis because we switch * from CJK to not or vice-versa @@ -451,7 +412,8 @@ static void update_ellipsis_shape (EllipsizeState *state) shape_ellipsis (state); } -/* Computes the position of the gap center and finds the smallest span containing it +/* Computes the position of the gap center and finds the smallest span + * containing it */ static void find_initial_span (EllipsizeState *state) { @@ -571,7 +533,8 @@ static BOOL remove_one_span (EllipsizeState *state) while (!ends_at_ellipsization_boundary (state, &new_gap_end_iter) || width == 0); - if (state->gap_end_x == new_gap_end_x && state->gap_start_x == new_gap_start_x) + if (state->gap_end_x == new_gap_end_x && + state->gap_start_x == new_gap_start_x) return FALSE; /* In the case where we could remove a span from either end of the @@ -580,8 +543,8 @@ static BOOL remove_one_span (EllipsizeState *state) */ if (state->gap_end_x == new_gap_end_x || (state->gap_start_x != new_gap_start_x && - state->gap_center - new_gap_start_x < new_gap_end_x - state->gap_center)) - { + state->gap_center - new_gap_start_x < + new_gap_end_x - state->gap_center)) { state->gap_start_iter = new_gap_start_iter; state->gap_start_x = new_gap_start_x; @@ -595,13 +558,13 @@ static BOOL remove_one_span (EllipsizeState *state) return TRUE; } -/* Fixes up the properties of the ellipsis run once we've determined the final extents - * of the gap +/* Fixes up the properties of the ellipsis run once we've determined the + * final extents of the gap */ static void fixup_ellipsis_grun (EllipsizeState *state) { GlyphString *glyphs = state->ellipsis_grun->gs; - TextRun *text_run = state->ellipsis_trun; + LayoutRun *layout_run = state->ellipsis_lrun; int level; int i; @@ -613,28 +576,26 @@ static void fixup_ellipsis_grun (EllipsizeState *state) glyphs->glyphs[0].is_cluster_start = TRUE; - /* Fix up the text_run to point to the entire elided text */ - text_run->si = state->gap_start_iter.run_iter.start_index; - text_run->len = state->gap_end_iter.run_iter.end_index - text_run->si; + /* Fix up the layout_run to point to the entire elided text */ + layout_run->si = state->gap_start_iter.run_iter.start_index; + layout_run->len = state->gap_end_iter.run_iter.end_index - layout_run->si; - /* The level for the text_run is the minimum level of the elided text */ + /* The level for the layout_run is the minimum level of the elided text */ level = INT_MAX; for (i = state->gap_start_iter.run_index; i <= state->gap_end_iter.run_index; i++) - level = MIN (level, state->run_info[i].run->trun->el); + level = MIN (level, state->run_info[i].run->lrun->el); - text_run->el = level; + layout_run->el = level; - text_run->flags |= TextRun_FLAG_IS_ELLIPSIS; + layout_run->flags |= LAYOUTRUN_FLAG_ORPHAN; } -#if 0 /* Computes the new list of runs for the line */ -static GSList * get_run_list (EllipsizeState *state) +static void get_run_list (EllipsizeState *state, LAYOUTLINE* line) { GlyphRun *partial_start_run = NULL; GlyphRun *partial_end_run = NULL; - GSList *result = NULL; RunInfo *run_info; GlyphRunIter *run_iter; int i; @@ -645,45 +606,43 @@ static GSList * get_run_list (EllipsizeState *state) */ run_info = &state->run_info[state->gap_end_iter.run_index]; run_iter = &state->gap_end_iter.run_iter; - if (run_iter->end_char != run_info->run->trun->len) - { + if (run_iter->end_char != run_info->run->lrun->len) { partial_end_run = run_info->run; - run_info->run = pango_glyph_run_split (run_info->run, state->layout->truninfo->ucs, - run_iter->end_index - run_info->run->trun->offset); + run_info->run = __mg_glyph_run_split (run_info->run, + state->layout->truninfo->ucs, + run_iter->end_index - run_info->run->lrun->si); } run_info = &state->run_info[state->gap_start_iter.run_index]; run_iter = &state->gap_start_iter.run_iter; - if (run_iter->start_char != 0) - { - partial_start_run = pango_glyph_run_split (run_info->run, state->layout->truninfo->ucs, - run_iter->start_index - run_info->run->trun->offset); + if (run_iter->start_char != 0) { + partial_start_run = __mg_glyph_run_split (run_info->run, + state->layout->truninfo->ucs, + run_iter->start_index - run_info->run->lrun->si); } /* Now assemble the new list of runs */ for (i = 0; i < state->gap_start_iter.run_index; i++) - result = g_slist_prepend (result, state->run_info[i].run); + list_add_tail(&state->run_info[i].run->list, &line->gruns); if (partial_start_run) - result = g_slist_prepend (result, partial_start_run); + list_add_tail(&partial_start_run->list, &line->gruns); - result = g_slist_prepend (result, state->ellipsis_grun); + list_add_tail(&state->ellipsis_grun->list, &line->gruns); if (partial_end_run) - result = g_slist_prepend (result, partial_end_run); + list_add_tail(&partial_end_run->list, &line->gruns); for (i = state->gap_end_iter.run_index + 1; i < state->nr_runs; i++) - result = g_slist_prepend (result, state->run_info[i].run); + list_add_tail(&state->run_info[i].run->list, &line->gruns); /* And free the ones we didn't use */ - for (i = state->gap_start_iter.run_index; i <= state->gap_end_iter.run_index; i++) - pango_glyph_run_free (state->run_info[i].run); - - return g_slist_reverse (result); + for (i = state->gap_start_iter.run_index; + i <= state->gap_end_iter.run_index; i++) + __mg_glyph_run_free(state->run_info[i].run); } -#endif /* Computes the width of the line as currently ellipsized */ @@ -696,7 +655,6 @@ static int current_width (EllipsizeState *state) /** * _pango_layout_line_ellipsize: * @line: a #LAYOUTLINE - * @attrs: Attributes being used for itemization/shaping * * Given a #LAYOUTLINE with the runs still in logical order, ellipsize * it according the layout's policy to fit within the set width of the layout. @@ -726,8 +684,8 @@ BOOL __mg_layout_line_ellipsize (LAYOUTLINE *line, int goal_width) fixup_ellipsis_grun (&state); - //g_slist_free (line->runs); - //line->runs = get_run_list (&state); + __mg_layout_line_free_runs(line); + get_run_list(&state, line); is_ellipsized = TRUE; out: diff --git a/src/newgdi/layout-utils.c b/src/newgdi/layout-utils.c index 64f69c08..55c8cc09 100644 --- a/src/newgdi/layout-utils.c +++ b/src/newgdi/layout-utils.c @@ -52,6 +52,201 @@ #include "devfont.h" #include "unicode-ops.h" #include "layoutinfo.h" +#include "fontname.h" + +static BOOL fontname_get_from_orient(char* fontname, GlyphOrient ort) +{ + int orient_pos; + + orient_pos = fontGetOrientPosFromName(fontname); + if (orient_pos < 0) + return FALSE; + + switch (ort) { + case GLYPH_ORIENT_UPRIGHT: + fontname[orient_pos] = FONT_ORIENT_UPRIGHT; + break; + case GLYPH_ORIENT_SIDEWAYS: + fontname[orient_pos] = FONT_ORIENT_SIDEWAYS; + break; + case GLYPH_ORIENT_UPSIDE_DOWN: + fontname[orient_pos] = FONT_ORIENT_UPSIDE_DOWN; + break; + case GLYPH_ORIENT_SIDEWAYS_LEFT: + fontname[orient_pos] = FONT_ORIENT_SIDEWAYS_LEFT; + break; + default: + _WRN_PRINTF("bad orientation param: %d", ort); + return FALSE; + } + + return TRUE; +} + +/* Use MiniGUI resource manager to avoid duplicated logfonts */ +LOGFONT* __mg_create_logfont_for_layout(const LAYOUTINFO* layout, + const char* fontname, GlyphOrient ort) +{ + char my_fontname[LEN_LOGFONT_NAME_FULL + 1]; + LOGFONT* lf; + + if (fontname == NULL) + fontname = layout->truninfo->fontname; + + memset (my_fontname, 0, LEN_LOGFONT_NAME_FULL + 1); + strncpy (my_fontname, fontname, LEN_LOGFONT_NAME_FULL); + if (!fontname_get_from_orient(my_fontname, ort)) { + return NULL; + } + + lf = (LOGFONT*)LoadResource(my_fontname, RES_TYPE_FONT, 0); + if (lf == NULL) { + _ERR_PRINTF("%s: failed to create LOGFONT for layout: %p\n", + __FUNCTION__, layout); + } + + return lf; +} + +void __mg_release_logfont_for_layout(const LAYOUTINFO* layout, + const char* fontname, GlyphOrient ort) +{ + char my_fontname[LEN_LOGFONT_NAME_FULL + 1]; + if (fontname == NULL) + fontname = layout->truninfo->fontname; + + memset (my_fontname, 0, LEN_LOGFONT_NAME_FULL + 1); + strncpy (my_fontname, fontname, LEN_LOGFONT_NAME_FULL); + if (!fontname_get_from_orient(my_fontname, ort)) { + return; + } + + ReleaseRes(Str2Key(my_fontname)); +} + +LayoutRun* __mg_layout_run_new_orphan(const LAYOUTINFO* layout, + const TextRun* trun, const Uchar32* ucs, int nr_ucs) +{ + LOGFONT* lf; + LayoutRun* lrun; + + lf = __mg_create_logfont_for_layout(layout, trun->fontname, trun->ort); + if (lf == NULL) + return NULL; + + lrun = malloc(sizeof(LayoutRun)); + lrun->lf = lf; + lrun->ucs = ucs; + lrun->si = 0; + lrun->len = nr_ucs; + lrun->si = trun->si; + lrun->len = trun->len; + lrun->lc = trun->lc; + lrun->st = trun->st; + lrun->el = trun->el; + lrun->dir = trun->dir; + lrun->ort = trun->ort; + lrun->flags |= LAYOUTRUN_FLAG_ORPHAN; + + return lrun; +} + +LayoutRun* __mg_layout_run_new_from(const LAYOUTINFO* layout, + const TextRun* trun) +{ + LOGFONT* lf; + LayoutRun* lrun; + + lf = __mg_create_logfont_for_layout(layout, trun->fontname, trun->ort); + if (lf == NULL) + return NULL; + + lrun = malloc(sizeof(LayoutRun)); + lrun->lf = lf; + lrun->ucs = layout->truninfo->ucs; + lrun->si = trun->si; + lrun->len = trun->len; + lrun->lc = trun->lc; + lrun->st = trun->st; + lrun->el = trun->el; + lrun->dir = trun->dir; + lrun->ort = trun->ort; + lrun->flags = trun->flags; + + return lrun; +} + +LayoutRun* __mg_layout_run_new_from_offset(const LAYOUTINFO* layout, + const TextRun* trun, int offset) +{ + LOGFONT* lf; + LayoutRun* lrun; + + if (offset >= trun->len) + return NULL; + + lf = __mg_create_logfont_for_layout(layout, trun->fontname, trun->ort); + if (lf == NULL) + return NULL; + + lrun = malloc(sizeof(LayoutRun)); + + lrun->lf = lf; + lrun->ucs = layout->truninfo->ucs; + lrun->si = trun->si + offset; + lrun->len = trun->len - offset; + lrun->lc = trun->lc; + lrun->st = trun->st; + lrun->el = trun->el; + lrun->dir = trun->dir; + lrun->ort = trun->ort; + lrun->flags = trun->flags; + + return lrun; +} + +void __mg_layout_run_free(LayoutRun* lrun) +{ + if (lrun->lf) { + FONT_RES* font_res = (FONT_RES*)lrun->lf; + ReleaseRes(font_res->key); + } + + free(lrun); +} + +LayoutRun* __mg_layout_run_copy(const LayoutRun* lrun) +{ + LayoutRun *result; + + if (lrun == NULL) + return NULL; + + result = malloc(sizeof(LayoutRun)); + memcpy(result, lrun, sizeof(LayoutRun)); + + return result; +} + +LayoutRun* __mg_layout_run_split(LayoutRun *orig, int split_index) +{ + LayoutRun *new_run; + + if (orig == NULL) + return NULL; + if (split_index <= 0) + return NULL; + if (split_index >= orig->len) + return NULL; + + new_run = __mg_layout_run_copy(orig); + new_run->len = split_index; + + orig->si += split_index; + orig->len -= split_index; + + return new_run; +} GlyphString* __mg_glyph_string_new (void) { @@ -117,11 +312,33 @@ int __mg_glyph_string_get_width(const GlyphString *glyphs) return width; } -#define LTR(glyph_run) (((glyph_run)->trun->el & 1) == 0) +void __mg_layout_line_free_runs(LAYOUTLINE* line) +{ + while (!list_empty(&line->gruns)) { + GlyphRun* run = (GlyphRun*)line->gruns.prev; + list_del(line->gruns.prev); + __mg_glyph_run_free(run); + } +} + +void __mg_glyph_run_free(GlyphRun* run) +{ + if (run->lrun) { + __mg_layout_run_free(run->lrun); + } + + if (run->gs) { + __mg_glyph_string_free(run->gs); + } + + free(run); +} + +#define LTR(glyph_run) (((glyph_run)->lrun->el & 1) == 0) /** * __mg_glyph_run_split: - * @orig: a #TextRun + * @orig: a #GlyphRun * @text: text to which positions in @orig apply * @split_index: byte index of position to split item, relative to the start of the item * @@ -139,11 +356,9 @@ int __mg_glyph_string_get_width(const GlyphString *glyphs) * Return value: the newly allocated item representing text before * @split_index, which should be freed * with pango_glyph_run_free(). - * - * Since: 1.2 **/ GlyphRun *__mg_glyph_run_split (GlyphRun *orig, - const char *text, int split_index) + const Uchar32 *text, int split_index) { GlyphRun *new_grun; int i; @@ -152,11 +367,11 @@ GlyphRun *__mg_glyph_run_split (GlyphRun *orig, if (orig == NULL) return NULL; - if (orig->trun->len <= 0) + if (orig->lrun->len <= 0) return NULL; if (split_index <= 0) return NULL; - if (split_index >= orig->trun->len) + if (split_index >= orig->lrun->len) return NULL; if (LTR (orig)) { @@ -189,7 +404,7 @@ GlyphRun *__mg_glyph_run_split (GlyphRun *orig, num_remaining = orig->gs->nr_glyphs - nr_glyphs; new_grun = malloc (sizeof(GlyphRun)); - new_grun->trun = __mg_text_run_split (orig->trun, split_index); + 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); @@ -233,7 +448,7 @@ BOOL __mg_glyph_run_iter_next_cluster (GlyphRunIter *iter) int glyph_index = iter->end_glyph; GlyphString *glyphs = iter->glyph_run->gs; int cluster; - const TextRun *item = iter->glyph_run->trun; + const LayoutRun *item = iter->glyph_run->lrun; if (LTR (iter->glyph_run)) { if (glyph_index == glyphs->nr_glyphs) @@ -297,7 +512,7 @@ BOOL __mg_glyph_run_iter_prev_cluster (GlyphRunIter *iter) int glyph_index = iter->start_glyph; GlyphString *glyphs = iter->glyph_run->gs; int cluster; - const TextRun *item = iter->glyph_run->trun; + const LayoutRun *item = iter->glyph_run->lrun; if (LTR (iter->glyph_run)) { if (glyph_index == 0) @@ -372,7 +587,7 @@ BOOL __mg_glyph_run_iter_init_start (GlyphRunIter *iter, else iter->end_glyph = glyph_run->gs->nr_glyphs - 1; - iter->end_index = glyph_run->trun->si; + iter->end_index = glyph_run->lrun->si; iter->end_char = 0; iter->start_glyph = iter->end_glyph; @@ -394,8 +609,8 @@ BOOL __mg_glyph_run_iter_init_end (GlyphRunIter *iter, else iter->start_glyph = -1; - iter->start_index = glyph_run->trun->si + glyph_run->trun->len; - iter->start_char = glyph_run->trun->len; + iter->start_index = glyph_run->lrun->si + glyph_run->lrun->len; + iter->start_char = glyph_run->lrun->len; iter->end_glyph = iter->start_glyph; iter->end_index = iter->start_index; @@ -412,7 +627,7 @@ void __mg_glyph_run_get_logical_widths (const GlyphRun *glyph_run, BOOL has_cluster; int dir; - dir = glyph_run->trun->el % 2 == 0 ? +1 : -1; + dir = glyph_run->lrun->el % 2 == 0 ? +1 : -1; for (has_cluster = __mg_glyph_run_iter_init_start (&iter, glyph_run, text); has_cluster; has_cluster = __mg_glyph_run_iter_next_cluster (&iter)) diff --git a/src/newgdi/layoutinfo.c b/src/newgdi/layoutinfo.c index dc3c7bee..e238e259 100644 --- a/src/newgdi/layoutinfo.c +++ b/src/newgdi/layoutinfo.c @@ -84,43 +84,12 @@ LAYOUTINFO* GUIAPI CreateLayoutInfo( return layout; } -static void release_glyph_string(GlyphString* gs) -{ - if (gs->glyphs) - free (gs->glyphs); - if (gs->log_clusters); - free (gs->log_clusters); - - free(gs); -} - -static void release_run(GlyphRun* run) -{ - if (run->trun) { - __mg_text_run_free(run->trun); - } - - if (run->gs) { - release_glyph_string(run->gs); - } - free(run); -} - -void __mg_layout_line_free_runs(LAYOUTLINE* line) -{ - while (!list_empty(&line->gruns)) { - GlyphRun* run = (GlyphRun*)line->gruns.prev; - list_del(line->gruns.prev); - release_run(run); - } -} - static void release_line(LAYOUTLINE* line) { while (!list_empty(&line->gruns)) { GlyphRun* run = (GlyphRun*)line->gruns.prev; list_del(line->gruns.prev); - release_run(run); + __mg_glyph_run_free(run); } if (line->log_widths) { @@ -180,7 +149,9 @@ struct _LayoutState { // Start index of line in layout->text int line_start_index; // Current text run - TextRun* item; + const TextRun* trun; + // Current layout run + LayoutRun* item; // Start index of line in current item */ int start_index_in_item; // the number of not fit uchars in current text run @@ -230,7 +201,7 @@ static void shape_shape(const Uchar32* ucs, int nr_ucs, static void shape_full(const Uchar32* item_ucs, int nr_item_ucs, const Uchar32* para_ucs, int nr_para_ucs, - const TEXTRUNSINFO* truninfo, TextRun* textrun, + const TEXTRUNSINFO* truninfo, LayoutRun* textrun, GlyphString* glyphs) { } @@ -248,7 +219,7 @@ static void distribute_letter_spacing (int letter_spacing, } static GlyphString* shape_run(LAYOUTLINE *line, LayoutState *state, - TextRun *item) + LayoutRun *item) { LAYOUTINFO *layout = line->layout; GlyphString *glyphs = __mg_glyph_string_new (); @@ -269,7 +240,7 @@ static GlyphString* shape_run(LAYOUTLINE *line, LayoutState *state, GlyphRun glyph_run; int space_left, space_right; - glyph_run.trun = item; + glyph_run.lrun = item; glyph_run.gs = glyphs; __mg_glyph_run_letter_space (&glyph_run, @@ -294,32 +265,32 @@ static void free_run (GlyphRun *run) free(run); } -static TextRun *uninsert_run (LAYOUTLINE *line) +static LayoutRun *uninsert_run (LAYOUTLINE *line) { GlyphRun *run; - TextRun *item; + LayoutRun *item; run = (GlyphRun*)&line->gruns.next; - item = run->trun; + item = run->lrun; list_del(line->gruns.next); - line->len -= run->trun->len; + line->len -= run->lrun->len; free_run(run); return item; } static GlyphRun* insert_run(LAYOUTLINE *line, LayoutState *state, - TextRun *text_run, BOOL last_run) + LayoutRun *layout_run, BOOL last_run) { GlyphRun *glyph_run = malloc(sizeof(GlyphRun)); - glyph_run->trun = text_run; + glyph_run->lrun = layout_run; if (last_run && state->log_widths_offset == 0) glyph_run->gs = state->glyphs; else - glyph_run->gs = shape_run(line, state, text_run); + glyph_run->gs = shape_run(line, state, layout_run); if (last_run) { if (state->log_widths_offset > 0) @@ -330,7 +301,7 @@ static GlyphRun* insert_run(LAYOUTLINE *line, LayoutState *state, } list_add_tail(&glyph_run->list, &line->gruns); - line->len += text_run->len; + line->len += layout_run->len; return glyph_run; } @@ -394,7 +365,7 @@ BreakResult process_text_run(LAYOUTINFO *layout, LAYOUTLINE *line, LayoutState *state, BOOL force_fit, BOOL no_break_at_end) { - TextRun *item = state->item; + LayoutRun *item = state->item; BOOL shape_set = FALSE; int width; int i; @@ -456,7 +427,7 @@ BreakResult process_text_run(LAYOUTINFO *layout, if (processing_new_item) { GlyphRun glyph_run; - glyph_run.trun = item; + glyph_run.lrun = item; glyph_run.gs = state->glyphs; state->log_widths = malloc (sizeof (int) * item->len); @@ -632,8 +603,8 @@ static void layout_line_reorder(LAYOUTLINE *line) list_for_each(i, &line->gruns) { GlyphRun *grun = (GlyphRun*)i; - level_or |= grun->trun->el; - level_and &= grun->trun->el; + level_or |= grun->lrun->el; + level_and &= grun->lrun->el; length++; } @@ -654,7 +625,7 @@ static void zero_line_final_space (LAYOUTLINE *line, LayoutState *state, GlyphRun *run) { LAYOUTINFO *layout = line->layout; - TextRun *item = run->trun; + LayoutRun *item = run->lrun; GlyphString *glyphs = run->gs; int glyph = item->el % 2 ? 0 : glyphs->nr_glyphs - 1; @@ -711,7 +682,7 @@ static void pad_glyphstring_left (GlyphString *glyphs, static inline BOOL is_tab_run(LAYOUTINFO *layout, GlyphRun *grun) { - return (layout->truninfo->ucs[grun->trun->si] == '\t'); + return (layout->truninfo->ucs[grun->lrun->si] == '\t'); } /* When doing shaping, we add the letter spacing value for a @@ -851,18 +822,18 @@ static void justify_clusters (LAYOUTLINE *line, LayoutState *state) int dir; int offset; - dir = run->trun->el % 2 == 0 ? +1 : -1; + dir = run->lrun->el % 2 == 0 ? +1 : -1; /* We need character offset of the start of the run. * We don't have this. * Compute by counting from the beginning of the line. * The naming is confusing. Note that: * - * run->trun->si is the index of start of run. + * run->lrun->si is the index of start of run. * state->line_start_index is the index of start of line. */ - assert(run->trun->si >= state->line_start_index); - offset = state->line_start_index + run->trun->si; + assert(run->lrun->si >= state->line_start_index); + offset = state->line_start_index + run->lrun->si; if ((have_cluster = (dir > 0))) __mg_glyph_run_iter_init_start(&cluster_iter, run, text); @@ -989,8 +960,8 @@ static void justify_words (LAYOUTLINE *line, BOOL have_cluster; int offset; - assert(run->trun->si >= state->line_start_index); - offset = state->line_start_index + run->trun->si; + assert(run->lrun->si >= state->line_start_index); + offset = state->line_start_index + run->lrun->si; for (have_cluster = __mg_glyph_run_iter_init_start (&cluster_iter, run, text); @@ -1149,7 +1120,7 @@ static LAYOUTLINE* check_next_line(LAYOUTINFO* layout, LayoutState* state) state->remaining_width = state->line_width; while (state->item) { - TextRun *item = state->item; + LayoutRun *item = state->item; BreakResult result; int old_num_chars; int old_remaining_width; @@ -1275,24 +1246,27 @@ LAYOUTLINE* GUIAPI LayoutNextLine( goto next_line; } - state.item = (TextRun*)&layout->truninfo->truns.next; + state.trun = (TextRun*)&layout->truninfo->truns.next; + state.item = __mg_layout_run_new_from(layout, state.trun); state.start_index_in_item = 0; state.left_ucs_in_item = state.item->len; } else { state.start_offset = layout->truninfo->nr_ucs - layout->nr_left_ucs; - state.item = __mg_textruns_get_by_offset(layout->truninfo, + state.trun = __mg_textruns_get_by_offset(layout->truninfo, state.start_offset, &state.start_index_in_item); - if (state.item == NULL) { + if (state.trun == NULL) { return NULL; } + state.item = __mg_layout_run_new_from_offset(layout, + state.trun, state.start_index_in_item); state.left_ucs_in_item = state.item->len - state.start_index_in_item; } state.line_width = max_extent; state.remaining_width = max_extent; - next_line = check_next_line (layout, &state); + next_line = check_next_line(layout, &state); next_line: if (next_line) { diff --git a/src/newgdi/layoutinfo.h b/src/newgdi/layoutinfo.h index 39311eaa..7edc85fa 100644 --- a/src/newgdi/layoutinfo.h +++ b/src/newgdi/layoutinfo.h @@ -64,9 +64,26 @@ struct _GlyphString { unsigned int space; }; +#define LAYOUTRUN_FLAG_ORPHAN 0x01 + +struct _LayoutRun { + struct list_head list; + LOGFONT* lf; // the logfont for this run + const Uchar32* ucs; // the uchar string + + int si; // the start index of this run + int len; // the length of the uchar string + Uint32 lc:8; // language code + Uint32 st:8; // script type + Uint32 el:8; // the bidi embedding level + Uint32 dir:4; // the run direction + Uint32 ort:2; // the glyph orientation + Uint32 flags:2;// other flags +}; + struct _GlyphRun { struct list_head list; - TextRun* trun; // the text run corresponding to the glyph run + LayoutRun* lrun; // the layout run corresponding to the glyph run GlyphString* gs; // the glyph string }; @@ -124,7 +141,28 @@ struct _GlyphRunIter { extern "C" { #endif /* __cplusplus */ -void __mg_layout_line_free_gruns(LAYOUTLINE* line); +LOGFONT* __mg_create_logfont_for_layout(const LAYOUTINFO* layout, + const char* fontname, GlyphOrient ort); +void __mg_release_logfont_for_layout(const LAYOUTINFO* layout, + const char* fontname, GlyphOrient ort); + +GlyphRun *__mg_glyph_run_split (GlyphRun *orig, + const Uchar32 *text, int split_index); +void __mg_glyph_run_free(GlyphRun* run); + +LayoutRun* __mg_layout_run_new_orphan(const LAYOUTINFO* layout, + const TextRun* trun, const Uchar32* ucs, int nr_ucs); +LayoutRun* __mg_layout_run_new_from(const LAYOUTINFO* layout, + const TextRun* trun); +LayoutRun* __mg_layout_run_new_from_offset(const LAYOUTINFO* layout, + const TextRun* trun, int offset); + +void __mg_layout_run_free(LayoutRun* run); + +LayoutRun* __mg_layout_run_copy(const LayoutRun* run); +LayoutRun* __mg_layout_run_split(LayoutRun *orig, int split_index); + +void __mg_layout_line_free_runs(LAYOUTLINE* line); GlyphString* __mg_glyph_string_new(void); void __mg_glyph_string_free(GlyphString* string); @@ -148,11 +186,8 @@ void __mg_glyph_run_letter_space (const GlyphRun* glyph_run, BOOL __mg_layout_line_ellipsize(LAYOUTLINE *line, int goal_width); -int __mg_shape_text_run(const TEXTRUNSINFO* info, const TextRun* run, - int so, int len, GlyphString* glyphs); - -void __mg_shape_utf8 (const char* text, int len, - const TextRun* trun, GlyphString* gs); +int __mg_shape_layout_run(const TEXTRUNSINFO* info, const LayoutRun* run, + GlyphString* glyphs); #ifdef __cplusplus } diff --git a/src/newgdi/shape-glyphs-basic.c b/src/newgdi/shape-glyphs-basic.c index 2433a3e0..efee49bc 100644 --- a/src/newgdi/shape-glyphs-basic.c +++ b/src/newgdi/shape-glyphs-basic.c @@ -78,12 +78,12 @@ static void reverse_shaped_glyphs(ShapedGlyph* glyphs, int len) } static BOOL shape_text_run(SEInstance* inst, - const TEXTRUNSINFO* info, const TextRun* run, + const TEXTRUNSINFO* info, const LayoutRun* run, GlyphString* gs) { BOOL ok = FALSE; int i, j; - const Uchar32* logical_ucs = info->ucs + run->si; + const Uchar32* logical_ucs = run->ucs; int nr_ucs = run->len; Uchar32 local_shaped_ucs[LOCAL_ARRAY_SIZE]; diff --git a/src/newgdi/textrunsinfo.c b/src/newgdi/textrunsinfo.c index bea1a631..66b43bbd 100644 --- a/src/newgdi/textrunsinfo.c +++ b/src/newgdi/textrunsinfo.c @@ -71,7 +71,7 @@ enum { EMOJI_CHANGED = 1 << 6, }; -typedef struct _TextRunSTATE { +typedef struct _TextRunState { TEXTRUNSINFO* runinfo; const Uchar32* text; const Uchar32* end; @@ -96,9 +96,9 @@ typedef struct _TextRunSTATE { LanguageCode derived_lang; -} TextRunSTATE; +} TextRunState; -static void update_embedding_end(TextRunSTATE *state) +static void update_embedding_end(TextRunState *state) { state->emb_level = state->els[state->emb_end_offset]; while (state->emb_end < state->end && @@ -111,7 +111,7 @@ static void update_embedding_end(TextRunSTATE *state) state->changed |= EMBEDDING_CHANGED; } -static void update_end (TextRunSTATE *state) +static void update_end (TextRunState *state) { state->run_end = state->emb_end; if (state->script_iter.end < state->run_end) @@ -141,7 +141,7 @@ static LanguageCode compute_derived_language (LanguageCode lang, return derived_lang; } -static void state_update_for_new_run (TextRunSTATE *state) +static void state_update_for_new_run (TextRunState *state) { if (state->changed & (SCRIPT_CHANGED | WIDTH_CHANGED)) { GlyphOrient orient = state->runinfo->ort_base; @@ -164,86 +164,11 @@ static void state_update_for_new_run (TextRunSTATE *state) } } -/* Use MiniGUI resource manager to avoid duplicated logfonts */ -LOGFONT* __mg_create_logfont_for_run(const TEXTRUNSINFO* runinfo, - const TextRun* run) -{ - char fontname[LEN_LOGFONT_NAME_FULL + 1]; - int orient_pos = fontGetOrientPosFromName(runinfo->fontname); - LOGFONT* lf; - - if (orient_pos < 0) - return NULL; - - memset (fontname, 0, LEN_LOGFONT_NAME_FULL + 1); - strncpy (fontname, runinfo->fontname, LEN_LOGFONT_NAME_FULL); - - switch (run->ort) { - case GLYPH_ORIENT_UPRIGHT: - fontname[orient_pos] = FONT_ORIENT_UPRIGHT; - break; - case GLYPH_ORIENT_SIDEWAYS: - fontname[orient_pos] = FONT_ORIENT_SIDEWAYS; - break; - case GLYPH_ORIENT_UPSIDE_DOWN: - fontname[orient_pos] = FONT_ORIENT_UPSIDE_DOWN; - break; - case GLYPH_ORIENT_SIDEWAYS_LEFT: - fontname[orient_pos] = FONT_ORIENT_SIDEWAYS_LEFT; - break; - default: - _WRN_PRINTF("bad orientation param: %d", run->ort); - return NULL; - } - - lf = (LOGFONT*)LoadResource(fontname, RES_TYPE_FONT, 0); - if (lf == NULL) { - _ERR_PRINTF("%s: failed to create LOGFONT for run\n", - __FUNCTION__); - return NULL; - } - - return lf; -} - -void __mg_release_logfont_for_run(const TEXTRUNSINFO* runinfo, - const TextRun* run) -{ - char fontname[LEN_LOGFONT_NAME_FULL + 1]; - int orient_pos = fontGetOrientPosFromName(runinfo->fontname); - - if (orient_pos < 0) - return; - - memset (fontname, 0, LEN_LOGFONT_NAME_FULL + 1); - strncpy (fontname, runinfo->fontname, LEN_LOGFONT_NAME_FULL); - - switch (run->ort) { - case GLYPH_ORIENT_UPRIGHT: - fontname[orient_pos] = FONT_ORIENT_UPRIGHT; - break; - case GLYPH_ORIENT_SIDEWAYS: - fontname[orient_pos] = FONT_ORIENT_SIDEWAYS; - break; - case GLYPH_ORIENT_UPSIDE_DOWN: - fontname[orient_pos] = FONT_ORIENT_UPSIDE_DOWN; - break; - case GLYPH_ORIENT_SIDEWAYS_LEFT: - fontname[orient_pos] = FONT_ORIENT_SIDEWAYS_LEFT; - break; - default: - _WRN_PRINTF("bad orientation param: %d", run->ort); - return; - } - - ReleaseRes(Str2Key(fontname)); -} - -static void state_add_character(TextRunSTATE *state, +static void state_add_character(TextRunState *state, BOOL no_shaping, BOOL force_break, const Uchar32* pos) { if (state->run) { - BOOL without_shaping = (state->run->lf == NULL); + BOOL without_shaping = (state->run->flags & TEXTRUN_FLAG_NOT_SHAPING); if (!force_break && state->run->lc == state->derived_lang && without_shaping == no_shaping) { @@ -253,6 +178,7 @@ static void state_add_character(TextRunSTATE *state, } state->run = malloc(sizeof(TextRun)); + state->run->fontname = NULL; state->run->si = pos - state->text; state->run->len = 1; state->run->lc = state->derived_lang; @@ -260,12 +186,11 @@ static void state_add_character(TextRunSTATE *state, state->run->el = state->emb_level; state->run->dir = state->runinfo->run_dir; state->run->ort = state->ort_rsv; + state->run->flags = 0; - if (no_shaping) - state->run->lf = NULL; - else - state->run->lf = __mg_create_logfont_for_run(state->runinfo, - state->run); + if (no_shaping) { + state->run->flags |= TEXTRUN_FLAG_NOT_SHAPING; + } /* The level vs. gravity dance: * If gravity is SOUTH, leave level untouched. @@ -294,14 +219,14 @@ static void state_add_character(TextRunSTATE *state, break; } - state->run->flags = state->centered_baseline ? - TextRun_FLAG_CENTERED_BASELINE : 0; + state->run->flags |= state->centered_baseline ? + TEXTRUN_FLAG_CENTERED_BASELINE : 0; list_add_tail(&state->run->list, &state->runinfo->truns); state->runinfo->nr_runs++; } -static BOOL state_process_run (TextRunSTATE *state) +static BOOL state_process_run (TextRunState *state) { const Uchar32* p; BOOL last_was_forced_break = FALSE; @@ -332,7 +257,7 @@ static BOOL state_process_run (TextRunSTATE *state) return TRUE; } -static BOOL state_next (TextRunSTATE *state) +static BOOL state_next (TextRunState *state) { if (state->run_end == state->end) return FALSE; @@ -367,7 +292,7 @@ static BOOL state_next (TextRunSTATE *state) static BOOL create_text_runs(TEXTRUNSINFO* runinfo, BidiLevel* els) { BOOL ok = FALSE; - TextRunSTATE state; + TextRunState state; Uint8 local_types_buff[LOCAL_ARRAY_SIZE]; Uint8* types_buff = NULL; @@ -449,10 +374,10 @@ static inline Uint8 get_glyph_orient_from_fontname (const char* fontname) #ifdef _MGDEVEL_MODE void* GetNextTextRunInfo(TEXTRUNSINFO* runinfo, void* prev, - LOGFONT** logfont, int* start_index, int* length, + const char** fontname, int* start_index, int* length, LanguageCode* lang_code, ScriptType* script, BidiLevel* embedding_level, GlyphRunDir* run_dir, - GlyphOrient* orient) + GlyphOrient* orient, Uint8* flags) { TextRun* run = NULL; @@ -469,7 +394,7 @@ void* GetNextTextRunInfo(TEXTRUNSINFO* runinfo, run = (TextRun*)list_entry->next; } - if (logfont) *logfont = run->lf; + if (fontname) *fontname = run->fontname; if (start_index) *start_index = run->si; if (length) *length = run->len; if (lang_code) *lang_code = run->lc; @@ -477,6 +402,7 @@ void* GetNextTextRunInfo(TEXTRUNSINFO* runinfo, if (embedding_level) *embedding_level = run->el; if (run_dir) *run_dir = run->dir; if (orient) *orient = run->ort; + if (flags) *flags = run->flags; return run; } @@ -666,58 +592,12 @@ RGBCOLOR __mg_textruns_get_text_color(const TEXTRUNSINFO* runinfo, int index) return runinfo->attrs.value; } -TextRun* __mg_textruns_get_by_offset(const TEXTRUNSINFO* runinfo, +const TextRun* __mg_textruns_get_by_offset(const TEXTRUNSINFO* runinfo, int offset, int *start_index) { return NULL; } -TextRun* __mg_text_run_new_orphan(const TEXTRUNSINFO* info, - const Uchar32* ucs, int nr_ucs) -{ - TextRun* trun = malloc(sizeof(TextRun)); - - return trun; -} - -void __mg_text_run_free(TextRun* trun) -{ - free(trun); -} - -TextRun* __mg_text_run_copy(const TextRun* trun) -{ - TextRun *result; - - if (trun == NULL) - return NULL; - - result = malloc(sizeof(TextRun)); - memcpy(result, trun, sizeof(TextRun)); - - return result; -} - -TextRun* __mg_text_run_split(TextRun *orig, int split_index) -{ - TextRun *new_run; - - if (orig == NULL) - return NULL; - if (split_index <= 0) - return NULL; - if (split_index >= orig->len) - return NULL; - - new_run = __mg_text_run_copy(orig); - new_run->len = split_index; - - orig->si += split_index; - orig->len -= split_index; - - return new_run; -} - BOOL GUIAPI SetTextColorInTextRuns(TEXTRUNSINFO* runinfo, int start_index, int length, RGBCOLOR color) { @@ -761,8 +641,8 @@ BOOL GUIAPI DestroyTextRunsInfo(TEXTRUNSINFO* runinfo) while (!list_empty(&runinfo->truns)) { TextRun* run = (TextRun*)runinfo->truns.prev; list_del(runinfo->truns.prev); - if (run->lf) - __mg_release_logfont_for_run(runinfo, run); + if (run->fontname) + free(run->fontname); free(run); } diff --git a/src/newgdi/textrunsinfo.h b/src/newgdi/textrunsinfo.h index 339a3e40..0b7b6c90 100644 --- a/src/newgdi/textrunsinfo.h +++ b/src/newgdi/textrunsinfo.h @@ -43,13 +43,14 @@ #include "list.h" +typedef struct _LayoutRun LayoutRun; typedef struct _TextRun TextRun; typedef struct _GlyphString GlyphString; typedef struct _SEInstance SEInstance; typedef struct _TextAttrMap TextAttrMap; typedef BOOL (*CB_SHAPE_TEXT_RUN)(SEInstance* instance, - const TEXTRUNSINFO* info, const TextRun* run, + const TEXTRUNSINFO* info, const LayoutRun* run, GlyphString* gs); typedef BOOL (*CB_DESTROY_INSTANCE)(SEInstance* instance); @@ -67,16 +68,15 @@ struct _ShapingEngineInfo { CB_DESTROY_INSTANCE free; }; -#define TextRun_FLAG_CENTERED_BASELINE 0x01 -#define TextRun_FLAG_IS_ELLIPSIS 0x02 +#define TEXTRUN_FLAG_CENTERED_BASELINE 0x01 +#define TEXTRUN_FLAG_NOT_SHAPING 0x02 struct _TextRun { struct list_head list; - const char* fontname; // the logfont name for this run; NULL for default - LOGFONT* lf; // the logfont for this run + char* fontname; // the logfont name for this run; NULL for default - int si; // start index in the Unicode string - int len; // the number of Unicode characters + int si; // start index in the uchar string + int len; // the length in uchars Uint32 lc:8; // language code Uint32 st:8; // script type @@ -92,7 +92,6 @@ struct _TextRun { #define TEXT_ATTR_OUTLINE_COLOR 0x03 #define TEXT_ATTR_BACKGROUND_COLOR 0x04 - struct _TextAttrMap { struct list_head list; int si; @@ -126,20 +125,8 @@ struct _TEXTRUNSINFO { extern "C" { #endif /* __cplusplus */ -TextRun* __mg_text_run_new_orphan(const TEXTRUNSINFO* info, - const Uchar32* ucs, int nr_ucs); -void __mg_text_run_free(TextRun* trun); - -TextRun* __mg_text_run_copy(const TextRun* trun); -TextRun* __mg_text_run_split(TextRun *orig, int split_index); - -LOGFONT* __mg_create_logfont_for_run(const TEXTRUNSINFO* runinfo, - const TextRun* run); -void __mg_release_logfont_for_run(const TEXTRUNSINFO* runinfo, - const TextRun* run); - RGBCOLOR __mg_textruns_get_color(const TEXTRUNSINFO* runinfo, int index); -TextRun* __mg_textruns_get_by_offset(const TEXTRUNSINFO* runinfo, +const TextRun* __mg_textruns_get_by_offset(const TEXTRUNSINFO* runinfo, int offset, int *start_index); #ifdef __cplusplus