diff --git a/include/gdi.h b/include/gdi.h index 96f9ab24..fca451d5 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -12560,37 +12560,40 @@ MG_EXPORT TEXTRUNSINFO* GUIAPI CreateTextRunsInfo(Uchar32* ucs, int nr_ucs, const char* logfont_name, RGBCOLOR color); /** - * Set font of part characters. Please call this function before - * calling InitBasicShapingEngine or InitComplexShapingEngine. + * Set logfont of text runs */ -MG_EXPORT BOOL GUIAPI SetPartFontInTextRuns(TEXTRUNSINFO* run_info, +MG_EXPORT BOOL GUIAPI SetFontInTextRuns(TEXTRUNSINFO* run_info, int start_index, int length, const char* logfont_name); /** - * Set color of part characters. + * Set text olor in text runs. */ -MG_EXPORT BOOL GUIAPI SetPartColorInTextRuns(TEXTRUNSINFO* run_info, +MG_EXPORT BOOL GUIAPI SetTextColorInTextRuns(TEXTRUNSINFO* run_info, int start_index, int length, RGBCOLOR color); /** - * Reset the font of glyph runs for the next rendering under a - * new LOGFONT. + * Set underline color in text runs. */ -MG_EXPORT BOOL GUIAPI ResetFontInTextRuns(TEXTRUNSINFO* run_info, - const char* logfont_name); +MG_EXPORT BOOL GUIAPI SetUnderlineColorInTextRuns(TEXTRUNSINFO* run_info, + int start_index, int length, RGBCOLOR color); /** - * Reset the color of glyph runs. + * Set strikethrough color in text runs. */ -MG_EXPORT BOOL GUIAPI ResetColorInTextRuns(TEXTRUNSINFO* run_info, - RGBCOLOR color); +MG_EXPORT BOOL GUIAPI SetStrikethroughColorInTextRuns(TEXTRUNSINFO* run_info, + int start_index, int length, RGBCOLOR color); /** - * Reset the direction and orientation of glyph runs. + * Set background color in text runs. */ -MG_EXPORT BOOL GUIAPI ResetDirectionInTextRuns(TEXTRUNSINFO* run_info, - GlyphRunDir run_dir, GlyphOrient glyph_orient, - GlyphOrientPolicy orient_policy); +MG_EXPORT BOOL GUIAPI SetBackgroundColorInTextRuns(TEXTRUNSINFO* run_info, + int start_index, int length, RGBCOLOR color); + +/** + * Set outline color in text runs. + */ +MG_EXPORT BOOL GUIAPI SetOutlineColorInTextRuns(TEXTRUNSINFO* run_info, + int start_index, int length, RGBCOLOR color); /** * Destroy the glyph run info object. It also frees all data allocated diff --git a/src/newgdi/glyph-shaped.c b/src/newgdi/glyph-shaped.c index 9123067b..7c4943f7 100644 --- a/src/newgdi/glyph-shaped.c +++ b/src/newgdi/glyph-shaped.c @@ -71,4 +71,54 @@ int DrawShapedGlyphLine(HDC hdc, const LAYOUTLINE* line, return 0; } +#if 0 +int GUIAPI DrawShapedGlyphString(HDC hdc, + LOGFONT* logfont_upright, LOGFONT* logfont_sideways, + const SHAPEDGLYPHS* shaped_glyphs, + const GLYPHPOS* glyph_pos, int nr_glyphs) +{ + int i; + int n = 0; + Uint32 old_ta; + PLOGFONT old_lf; + + if (shaped_glyphs == NULL || glyph_pos == NULL || nr_glyphs <= 0) + return 0; + + old_ta = SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP); + old_lf = GetCurFont(hdc); + + for (i = 0; i < nr_glyphs; i++) { + if (glyph_pos[i].suppressed == 0 && glyph_pos[i].whitespace == 0) { + Glyph32 gv = shaped_glyphs->cb_get_glyph_info( + shaped_glyphs->shaping_engine, shaped_glyphs->glyph_infos, + i, NULL); + if (glyph_pos[i].orientation == GLYPH_ORIENTATION_UPRIGHT) { + if (logfont_upright) + SelectFont(hdc, logfont_upright); + else + goto error; + } + else { + if (logfont_sideways) + SelectFont(hdc, logfont_sideways); + else + goto error; + } + + DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, gv, + NULL, NULL); + + n++; + } + } + +error: + SelectFont(hdc, old_lf); + SetTextAlign(hdc, old_ta); + + return n; +} +#endif + #endif /* _MGCHARSET_UNICODE */ diff --git a/src/newgdi/layoutinfo.c b/src/newgdi/layoutinfo.c index c8b8c9f2..4923c6e7 100644 --- a/src/newgdi/layoutinfo.c +++ b/src/newgdi/layoutinfo.c @@ -105,9 +105,9 @@ static void release_run(GLYPHRUN* run) static void release_line(LAYOUTLINE* line) { - while (!list_empty(&line->grun_head)) { - GLYPHRUN* run = (GLYPHRUN*)line->grun_head.prev; - list_del(line->grun_head.prev); + while (!list_empty(&line->gruns)) { + GLYPHRUN* run = (GLYPHRUN*)line->gruns.prev; + list_del(line->gruns.prev); release_run(run); } @@ -142,7 +142,7 @@ typedef enum { struct _LayoutState { /* maintained per layout */ - /* is last line */ + // is last line Uint32 last_line:1; Uint32 shape_set:1; @@ -150,36 +150,36 @@ struct _LayoutState { /* maintained per paragraph */ - /* Current text run */ - TEXTRUN* item; - - /* Current resolved base direction */ + // Current resolved base direction GlyphRunDir base_dir; - /* Line of the paragraph, starting at 1 for first line */ + // Line of the paragraph, starting at 1 for first line int line_of_par; - /* Glyphs for the current text run */ + // Glyphs for the current glyph run GLYPHSTRING* glyphs; - /* Character offset of first item in state->item in layout->truninfo->ucs */ + // Character offset of first item in state->item in layout->truninfo->ucs int start_offset; - /* Logical widths for the current text run */ + // Logical widths for the current text run */ int *log_widths; /* Offset into log_widths to the point corresponding * to the remaining portion of the first item */ int log_widths_offset; - /* Start index of line in layout->truninfo->ucs */ + // Start index of line in layout->truninfo->ucs */ int line_start_index; /* maintained per line */ - /* Goal width of line currently processing; < 0 is infinite */ + // Current text run + TEXTRUN* item; + // the number of not fit uchars in current text run + int nr_left_ucs; + // Goal width of line currently processing; < 0 is infinite int line_width; - - /* Amount of space remaining on line; < 0 is infinite */ + // Amount of space remaining on line; < 0 is infinite int remaining_width; }; @@ -302,7 +302,7 @@ static GLYPHRUN* insert_run (LAYOUTLINE *line, LayoutState *state, glyph_run->si = si; glyph_run->len = len; - list_add_tail(&glyph_run->list, &line->grun_head); + list_add_tail(&glyph_run->list, &line->gruns); line->len += text_run->len; return glyph_run; @@ -399,7 +399,7 @@ BreakResult process_one_text_run(LAYOUTINFO *layout, } if ((width <= state->remaining_width || - (item->len == 1 && list_empty(&line->grun_head))) && + (item->len == 1 && list_empty(&line->gruns))) && !no_break_at_end) { state->remaining_width -= width; state->remaining_width = MAX (state->remaining_width, 0); @@ -432,7 +432,7 @@ retry_break: /* If there are no previous runs we have to take care to grab at least one char. */ if (can_break_at (layout, state->start_offset + num_chars, retrying_with_char_breaks) && - (num_chars > 0 || !list_empty(&line->grun_head))) + (num_chars > 0 || !list_empty(&line->gruns))) { break_num_chars = num_chars; break_width = width; @@ -514,55 +514,5 @@ LAYOUTLINE* GUIAPI LayoutNextLine( return NULL; } -#if 0 -int GUIAPI DrawShapedGlyphString(HDC hdc, - LOGFONT* logfont_upright, LOGFONT* logfont_sideways, - const SHAPEDGLYPHS* shaped_glyphs, - const GLYPHPOS* glyph_pos, int nr_glyphs) -{ - int i; - int n = 0; - Uint32 old_ta; - PLOGFONT old_lf; - - if (shaped_glyphs == NULL || glyph_pos == NULL || nr_glyphs <= 0) - return 0; - - old_ta = SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_UPDATECP); - old_lf = GetCurFont(hdc); - - for (i = 0; i < nr_glyphs; i++) { - if (glyph_pos[i].suppressed == 0 && glyph_pos[i].whitespace == 0) { - Glyph32 gv = shaped_glyphs->cb_get_glyph_info( - shaped_glyphs->shaping_engine, shaped_glyphs->glyph_infos, - i, NULL); - if (glyph_pos[i].orientation == GLYPH_ORIENTATION_UPRIGHT) { - if (logfont_upright) - SelectFont(hdc, logfont_upright); - else - goto error; - } - else { - if (logfont_sideways) - SelectFont(hdc, logfont_sideways); - else - goto error; - } - - DrawGlyph(hdc, glyph_pos[i].x, glyph_pos[i].y, gv, - NULL, NULL); - - n++; - } - } - -error: - SelectFont(hdc, old_lf); - SetTextAlign(hdc, old_ta); - - return n; -} -#endif - #endif /* _MGCHARSET_UNICODE */ diff --git a/src/newgdi/layoutinfo.h b/src/newgdi/layoutinfo.h index 19c33a49..91be55ed 100644 --- a/src/newgdi/layoutinfo.h +++ b/src/newgdi/layoutinfo.h @@ -77,7 +77,7 @@ struct _LAYOUTLINE { LAYOUTINFO* layout; int* log_widths; // the widths of the logical chars - struct list_head grun_head; // the list head for glyph runs + struct list_head gruns; // the list head for glyph runs int si; // the start index in the uchar string int len; // the length of line (number of uchars) diff --git a/src/newgdi/textrunsinfo.c b/src/newgdi/textrunsinfo.c index 7cbbf04d..19276aa5 100644 --- a/src/newgdi/textrunsinfo.c +++ b/src/newgdi/textrunsinfo.c @@ -295,7 +295,7 @@ static void state_add_character(TEXTRUNSTATE *state, state->run->flags = state->centered_baseline ? GLYPH_FLAG_CENTERED_BASELINE : 0; - list_add_tail(&state->run->list, &state->runinfo->run_head); + list_add_tail(&state->run->list, &state->runinfo->truns); state->runinfo->nr_runs++; } @@ -455,13 +455,13 @@ void* GetNextTextRunInfo(TEXTRUNSINFO* runinfo, TEXTRUN* run = NULL; if (prev == NULL) { - if (list_empty(&runinfo->run_head)) + if (list_empty(&runinfo->truns)) return NULL; - run = (TEXTRUN*)runinfo->run_head.next; + run = (TEXTRUN*)runinfo->truns.next; } else { struct list_head* list_entry = (struct list_head*)prev; - if (list_entry->next == &runinfo->run_head) + if (list_entry->next == &runinfo->truns) return NULL; run = (TEXTRUN*)list_entry->next; @@ -579,12 +579,13 @@ TEXTRUNSINFO* GUIAPI CreateTextRunsInfo(Uchar32* ucs, int nr_ucs, else runinfo->ort_rsv = runinfo->ort_base; - INIT_LIST_HEAD(&runinfo->cm_head.list); - runinfo->cm_head.si = 0; - runinfo->cm_head.len = nr_ucs; - runinfo->cm_head.color = color; + INIT_LIST_HEAD(&runinfo->attrs.list); + runinfo->attrs.si = 0; + runinfo->attrs.len = nr_ucs; + runinfo->attrs.type = TEXT_ATTR_TEXT_COLOR; + runinfo->attrs.value = color; - INIT_LIST_HEAD(&runinfo->run_head); + INIT_LIST_HEAD(&runinfo->truns); runinfo->nr_runs = 0; #if 0 @@ -633,39 +634,40 @@ out: return NULL; } -BOOL GUIAPI SetPartFontInTextRuns(TEXTRUNSINFO* runinfo, +BOOL GUIAPI SetFontInTextRuns(TEXTRUNSINFO* runinfo, int start_index, int length, const char* logfont_name) { if (runinfo == NULL) return FALSE; // can not change font for empty runs - if (list_empty(&runinfo->run_head)) + if (list_empty(&runinfo->truns)) return FALSE; return FALSE; } -RGBCOLOR __mg_textruns_get_color(const TEXTRUNSINFO* runinfo, int index) +RGBCOLOR __mg_textruns_get_text_color(const TEXTRUNSINFO* runinfo, int index) { struct list_head *i; - list_for_each(i, &runinfo->cm_head.list) { - TEXTCOLORMAP* color_entry; - color_entry = (TEXTCOLORMAP*)i; + list_for_each(i, &runinfo->attrs.list) { + TEXTATTRMAP* color_entry; + color_entry = (TEXTATTRMAP*)i; if (index >= color_entry->si && - (index < color_entry->si + color_entry->len)) { - return color_entry->color; + (index < color_entry->si + color_entry->len) && + color_entry->type == TEXT_ATTR_TEXT_COLOR) { + return color_entry->value; } } - return runinfo->cm_head.color; + return runinfo->attrs.value; } -BOOL GUIAPI SetPartColorInTextRuns(TEXTRUNSINFO* runinfo, +BOOL GUIAPI SetTextColorInTextRuns(TEXTRUNSINFO* runinfo, int start_index, int length, RGBCOLOR color) { - TEXTCOLORMAP* color_entry = NULL; + TEXTATTRMAP* color_entry = NULL; if (runinfo == NULL || start_index < 0 || length < 0 || start_index > runinfo->nr_ucs || @@ -673,16 +675,17 @@ BOOL GUIAPI SetPartColorInTextRuns(TEXTRUNSINFO* runinfo, goto error; } - color_entry = calloc(1, sizeof(TEXTCOLORMAP)); + color_entry = calloc(1, sizeof(TEXTATTRMAP)); if (color_entry == NULL) { goto error; } color_entry->si = start_index; color_entry->len = length; - color_entry->color = color; + color_entry->type = TEXT_ATTR_TEXT_COLOR; + color_entry->value = color; - list_add(&color_entry->list, &runinfo->cm_head.list); + list_add(&color_entry->list, &runinfo->attrs.list); return TRUE; @@ -690,102 +693,20 @@ error: return FALSE; } -BOOL GUIAPI ResetFontInTextRuns(TEXTRUNSINFO* runinfo, const char* logfont_name) -{ - if (runinfo == NULL) - return FALSE; - - while (!list_empty(&runinfo->run_head)) { - TEXTRUN* run = (TEXTRUN*)runinfo->run_head.prev; - list_del(runinfo->run_head.prev); - if (run->lf) - release_logfont_for_run(runinfo, run); - free(run); - } - - if (runinfo->sei.inst) { - runinfo->sei.free(runinfo->sei.inst); - } - - free(runinfo->fontname); - runinfo->fontname = strdup(logfont_name); - return create_glyph_runs(runinfo, NULL); -} - -static void set_run_dir(TEXTRUNSINFO* runinfo, TEXTRUN* run, - GlyphRunDir run_dir, GlyphOrient glyph_orient) -{ -} - -BOOL GUIAPI ResetDirectionInTextRuns(TEXTRUNSINFO* runinfo, - GlyphRunDir run_dir, GlyphOrient glyph_orient, - GlyphOrientPolicy orient_policy) -{ - struct list_head *i; - - if (runinfo == NULL) - return FALSE; - - runinfo->run_dir = run_dir; - runinfo->ort_base = glyph_orient; - runinfo->ort_plc = orient_policy; - - list_for_each(i, &runinfo->run_head) { - TEXTRUN* run = (TEXTRUN*)i; - set_run_dir(runinfo, run, run_dir, glyph_orient); - } - - return TRUE; -} - -BOOL GUIAPI ResetColorInTextRuns(TEXTRUNSINFO* runinfo, RGBCOLOR color) -{ - if (runinfo == NULL) - return FALSE; - - while (!list_empty(&runinfo->cm_head.list)) { - TEXTCOLORMAP* entry = (TEXTCOLORMAP*)runinfo->cm_head.list.prev; - list_del(runinfo->cm_head.list.prev); - free(entry); - } - - runinfo->cm_head.color = color; - return TRUE; -} - -#if 0 -BOOL GUIAPI ResetBreaksInTextRuns(TEXTRUNSINFO* runinfo, - Uint8 ctr, Uint8 wbr, Uint8 lbp) -{ - if (runinfo == NULL) - return FALSE; - - // Re-calculate the breaking opportunities - if (UStrGetBreaks(runinfo->run_head.st, ctr, wbr, lbp, - runinfo->ucs, runinfo->run_head.nr_ucs, &runinfo->bos) == 0) { - _ERR_PRINTF("%s: failed to get breaking opportunities.\n", - __FUNCTION__); - return FALSE; - } - - return TRUE; -} -#endif - BOOL GUIAPI DestroyTextRunsInfo(TEXTRUNSINFO* runinfo) { if (runinfo == NULL) return FALSE; - while (!list_empty(&runinfo->cm_head.list)) { - TEXTCOLORMAP* entry = (TEXTCOLORMAP*)runinfo->cm_head.list.prev; - list_del(runinfo->cm_head.list.prev); + while (!list_empty(&runinfo->attrs.list)) { + TEXTATTRMAP* entry = (TEXTATTRMAP*)runinfo->attrs.list.prev; + list_del(runinfo->attrs.list.prev); free(entry); } - while (!list_empty(&runinfo->run_head)) { - TEXTRUN* run = (TEXTRUN*)runinfo->run_head.prev; - list_del(runinfo->run_head.prev); + while (!list_empty(&runinfo->truns)) { + TEXTRUN* run = (TEXTRUN*)runinfo->truns.prev; + list_del(runinfo->truns.prev); if (run->lf) release_logfont_for_run(runinfo, run); free(run); diff --git a/src/newgdi/textrunsinfo.h b/src/newgdi/textrunsinfo.h index fb587a69..a851ed45 100644 --- a/src/newgdi/textrunsinfo.h +++ b/src/newgdi/textrunsinfo.h @@ -46,7 +46,7 @@ typedef struct _TEXTRUN TEXTRUN; typedef struct _GLYPHSTRING GLYPHSTRING; typedef struct _SEINSTANCE SEINSTANCE; -typedef struct _TEXTCOLORMAP TEXTCOLORMAP; +typedef struct _TEXTATTRMAP TEXTATTRMAP; typedef BOOL (*CB_SHAPE_TEXT_RUN)(SEINSTANCE* instance, const TEXTRUNSINFO* info, const TEXTRUN* run, @@ -84,20 +84,28 @@ struct _TEXTRUN { Uint32 flags:2;// other flags }; -struct _TEXTCOLORMAP { +#define TEXT_ATTR_TEXT_COLOR 0x00 +#define TEXT_ATTR_UNDERLINE_COLOR 0x01 +#define TEXT_ATTR_STRIKETHROUGH_COLOR 0x02 +#define TEXT_ATTR_OUTLINE_COLOR 0x03 +#define TEXT_ATTR_BACKGROUND_COLOR 0x04 + + +struct _TEXTATTRMAP { struct list_head list; int si; int len; - RGBCOLOR color; + int type; // attribute type + Uint32 value; // attribute value }; struct _TEXTRUNSINFO { /* The following fields will be initialized by CreateGlyphRunInfo. */ - const Uchar32* ucs; // the uchars - char* fontname;// the logfont name specified + const Uchar32* ucs; // the uchars + char* fontname; // the default logfont name specified - TEXTCOLORMAP cm_head; // the head of color map list of the characters - struct list_head run_head;// glyph runs (list) + TEXTATTRMAP attrs; // the head of color map (list) + struct list_head truns; // the head of text runs (list) int nr_ucs; // number of uchars int nr_runs; // number of runs