This commit is contained in:
Vincent Wei
2019-03-22 10:53:50 +08:00
parent a049e387e0
commit 4fba705082
6 changed files with 136 additions and 204 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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);

View File

@@ -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