tune GlyphRunInfo APIs and cleanup

This commit is contained in:
Vincent Wei
2019-03-16 16:21:49 +08:00
parent e7002ad870
commit ac60980bc2
7 changed files with 308 additions and 109 deletions
+33 -6
View File
@@ -12374,14 +12374,41 @@ typedef struct _GLYPHRUNINFO GLYPHRUNINFO;
*/
MG_EXPORT GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(
const char* lang_tag, const char* script_tag,
Uchar32* ucs, int nr_ucs, ParagraphDir base_dir,
Uint8 ctr, Uint8 wbr, Uint8 lbp,
Uchar32* ucs, int nr_ucs, ParagraphDir base_dir);
LOGFONT* logfont, RGBCOLOR color);
/**
* Reset the glyph run information for the next rendering under a
* new LOGFONT and the rendering flags.
* Set font of part characters. Please call this function before
* calling ShapeGlyphRunsBaisc or ShapeGlyphRunsComplex.
*/
MG_EXPORT BOOL GUIAPI ResetGlyphRunInfo(GLYPHRUNINFO* run_info);
MG_EXPORT BOOL GUIAPI SetPartFontInGlyphRuns(GLYPHRUNINFO* run_info,
int start_index, int length, LOGFONT* logfont);
/**
* Set color of part characters.
*/
MG_EXPORT BOOL GUIAPI SetPartColorInGlyphRuns(GLYPHRUNINFO* run_info,
int start_index, int length, RGBCOLOR color);
/**
* Reset the font of glyph runs for the next rendering under a
* new LOGFONT.
*/
MG_EXPORT BOOL GUIAPI ResetFontInGlyphRuns(GLYPHRUNINFO* run_info,
LOGFONT* logfont);
/**
* Reset the color of glyph runs.
*/
MG_EXPORT BOOL GUIAPI ResetColorInGlyphRuns(GLYPHRUNINFO* run_info,
RGBCOLOR color);
/**
* Reset the breaking opportunities of glyph runs.
*/
MG_EXPORT BOOL GUIAPI ResetBreaksInGlyphRuns(GLYPHRUNINFO* run_info,
Uint8 ctr, Uint8 wbr, Uint8 lbp);
/**
* Destroy the glyph run info object. It also frees all data allocated
@@ -12437,7 +12464,7 @@ MG_EXPORT BOOL GUIAPI DestroyGlyphRunInfo(GLYPHRUNINFO* run_info);
* GetGlyphsExtentInfo, GetGlyphsPositionInfo, DrawShapedGlyphString
*/
MG_EXPORT BOOL GUIAPI ShapeGlyphRunsBaisc(GLYPHRUNINFO* run_info,
LOGFONT* logfont, Uint32 render_flags);
Uint32 render_flags);
/**
* \fn int GUIAPI GetShapedGlyphsComplex()
@@ -12506,7 +12533,7 @@ MG_EXPORT BOOL GUIAPI ShapeGlyphRunsBaisc(GLYPHRUNINFO* run_info,
* GetGlyphsExtentInfo, GetGlyphsPositionInfo, DrawShapedGlyphString
*/
MG_EXPORT BOOL GUIAPI ShapeGlyphRunsComplex(GLYPHRUNINFO* run_info,
LOGFONT* logfont, Uint32 render_flags);
Uint32 render_flags);
/**
* \fn int GUIAPI GetGlyphsExtentInfo()
+26 -26
View File
@@ -69,7 +69,7 @@
static void validate_run_list(BidiRun *run_list)
{
register BidiRun *q;
BidiRun *q;
assert (run_list);
assert (run_list->next);
@@ -93,7 +93,7 @@ static inline void validate_run_list(BidiRun *run_list)
static BidiRun* new_run(void)
{
register BidiRun *run;
BidiRun *run;
run = malloc (sizeof (BidiRun));
@@ -107,7 +107,7 @@ static BidiRun* new_run(void)
static BidiRun* new_run_list(void)
{
register BidiRun *run;
BidiRun *run;
run = new_run ();
@@ -130,13 +130,13 @@ static void free_run_list(BidiRun *run_list)
validate_run_list (run_list);
{
register BidiRun *pp;
BidiRun *pp;
pp = run_list;
pp->prev->next = NULL;
while (pp)
{
register BidiRun *p;
BidiRun *p;
p = pp;
pp = pp->next;
@@ -150,7 +150,7 @@ static BidiRun* run_list_encode_bidi_types (const BidiType *bidi_types,
const BidiBracketType *bracket_types, int len)
{
BidiRun *list, *last;
register BidiRun *run = NULL;
BidiRun *run = NULL;
int i;
/* Create the list sentinel */
@@ -161,8 +161,8 @@ static BidiRun* run_list_encode_bidi_types (const BidiType *bidi_types,
/* Scan over the character types */
for (i = 0; i < len; i++)
{
register BidiType char_type = bidi_types[i];
register BidiBracketType bracket_type = BIDI_BRACKET_NONE;
BidiType char_type = bidi_types[i];
BidiBracketType bracket_type = BIDI_BRACKET_NONE;
if (bracket_types)
bracket_type = bracket_types[i];
@@ -220,8 +220,8 @@ static BidiRun* run_list_encode_bidi_types (const BidiType *bidi_types,
*/
static BOOL shadow_run_list(BidiRun *base, BidiRun *over, BOOL preserve_length)
{
register BidiRun *p = base, *q, *r, *s, *t;
register int pos = 0, pos2;
BidiRun *p = base, *q, *r, *s, *t;
int pos = 0, pos2;
BOOL status = FALSE;
validate_run_list (base);
@@ -504,7 +504,7 @@ static void print_resolved_levels(const BidiRun *pp)
{
_DBG_PRINTF (" Res. levels: ");
for_run_list (pp, pp) {
register int i;
int i;
for (i = RL_LEN (pp); i; i--)
_DBG_PRINTF ("%c", unibidi_char_from_level (RL_LEVEL (pp)));
}
@@ -644,7 +644,7 @@ static void print_pairing_nodes(BidiPairingNode *nodes)
BidiType UBidiGetParagraphDir(const BidiType *bidi_types, int len)
{
register int i;
int i;
for (i = 0; i < len; i++) {
if (BIDI_IS_LETTER(bidi_types[i]))
@@ -1054,7 +1054,7 @@ BidiLevel UBidiGetParagraphEmbeddingLevels(const BidiType *bidi_types,
for_run_list (pp, main_run_list)
{
register BidiType prev_type, this_type, next_type;
BidiType prev_type, this_type, next_type;
BidiRun *ppp_prev, *ppp_next;
int iso_level;
@@ -1137,7 +1137,7 @@ BidiLevel UBidiGetParagraphEmbeddingLevels(const BidiType *bidi_types,
/* Each isolate level has its own memory of the last strong character */
for_run_list (pp, main_run_list)
{
register BidiType prev_type, this_type, next_type;
BidiType prev_type, this_type, next_type;
int iso_level;
BidiRun *ppp_prev, *ppp_next;
@@ -1472,8 +1472,8 @@ BidiLevel UBidiGetParagraphEmbeddingLevels(const BidiType *bidi_types,
explicits_list to main_run_list. */
_DBG_PRINTF ("reinserting explicit codes\n");
if (explicits_list->next != explicits_list) {
register BidiRun *p;
register BOOL stat =
BidiRun *p;
BOOL stat =
shadow_run_list (main_run_list, explicits_list, TRUE);
explicits_list = NULL;
if (!stat) goto out;
@@ -1495,9 +1495,9 @@ BidiLevel UBidiGetParagraphEmbeddingLevels(const BidiType *bidi_types,
_DBG_PRINTF ("reset the embedding levels, 1, 2, 3.\n");
{
register int j, state, pos;
register BidiType char_type;
register BidiRun *p, *q, *list;
int j, state, pos;
BidiType char_type;
BidiRun *p, *q, *list;
/* L1. Reset the embedding levels of some chars:
1. segment separators,
@@ -1555,8 +1555,8 @@ BidiLevel UBidiGetParagraphEmbeddingLevels(const BidiType *bidi_types,
int pos = 0;
for_run_list (pp, main_run_list)
{
register int l;
register BidiLevel level = pp->level;
int l;
BidiLevel level = pp->level;
for (l = pp->len; l; l--)
embedding_levels[pos++] = level;
}
@@ -1610,7 +1610,7 @@ BidiLevel UBidiReorderLine(Uint32 flags,
}
{
register int i;
int i;
/* L1. Reset the embedding levels of some chars:
4. any sequence of white space characters at the end of the line. */
@@ -1625,8 +1625,8 @@ BidiLevel UBidiReorderLine(Uint32 flags,
/* 7. Reordering resolved levels */
{
register BidiLevel level;
register int i;
BidiLevel level;
int i;
/* Reorder both the outstring and the order array */
{
@@ -1636,7 +1636,7 @@ BidiLevel UBidiReorderLine(Uint32 flags,
if (BIDI_LEVEL_IS_RTL (embedding_levels[i])
&& bidi_types[i] == BIDI_TYPE_NSM)
{
register int seq_end = i;
int seq_end = i;
level = embedding_levels[i];
for (i--; i >= off &&
@@ -1677,7 +1677,7 @@ BidiLevel UBidiReorderLine(Uint32 flags,
for (i = off + len - 1; i >= off; i--) {
if (embedding_levels[i] >= level) {
/* Find all stretches that are >= level_idx */
register int seq_end = i;
int seq_end = i;
for (i--; i >= off && embedding_levels[i] >= level; i--)
;
+5 -1
View File
@@ -1301,7 +1301,11 @@ static void dbg_dump_ctxt(struct break_ctxt* ctxt,
#define dbg_dump_ctxt(ctxt, func, uc, gwsbo)
#endif
#define LOCAL_ARRAY_SIZE 256
#if SIZEOF_PTR == 8
# define LOCAL_ARRAY_SIZE 256
#else
# define LOCAL_ARRAY_SIZE 128
#endif
static int break_init_spaces(struct break_ctxt* ctxt,
Uchar32* ucs, Uint16* bos, Uint8* local_bts, Uint8* local_ods,
+194 -28
View File
@@ -61,10 +61,16 @@
# define LOCAL_ARRAY_SIZE 128
#endif
static BOOL init_glyph_runs(GLYPHRUNINFO* runinfo)
{
return FALSE;
}
GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(
const char* lang_tag, const char* script_tag,
Uchar32* ucs, int nr_ucs, ParagraphDir base_dir,
Uint8 ctr, Uint8 wbr, Uint8 lbp,
Uchar32* ucs, int nr_ucs, ParagraphDir base_dir)
LOGFONT* logfont, RGBCOLOR color)
{
BOOL ok = FALSE;
@@ -96,8 +102,10 @@ GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(
else
bidi_ts = malloc (nr_ucs * sizeof(BidiType));
if (!bidi_ts)
if (!bidi_ts) {
_DBG_PRINTF("%s: failed to allocate space for bidi types.\n");
goto out;
}
UStrGetBidiTypes(ucs, nr_ucs, bidi_ts);
@@ -106,57 +114,77 @@ GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(
else
brk_ts = (BidiBracketType*)malloc (nr_ucs * sizeof(BidiBracketType));
if (!brk_ts)
if (!brk_ts) {
_DBG_PRINTF("%s: failed to allocate space for bracket types.\n");
goto out;
}
UStrGetBracketTypes (ucs, bidi_ts, nr_ucs, brk_ts);
els = (BidiLevel*)malloc (nr_ucs * sizeof(BidiLevel));
if (!els) {
_DBG_PRINTF("%s: failed to allocate space for embedding levels.\n");
goto out;
}
max_level = UBidiGetParagraphEmbeddingLevels(bidi_ts, brk_ts, nr_ucs,
&base_dir, els) - 1;
if (max_level < 0) {
_DBG_PRINTF("%s: failed to get paragraph embedding levels.\n");
goto out;
}
// remove the bidi marks from embedding levels and original string.
j = 0;
level_or = 0, level_and = 1;
for (i = 0; i < nr_ucs; i++) {
if (!BIDI_IS_EXPLICIT_OR_BN (bidi_ts[i])) {
els[j] = els[i];
ucs[j] = ucs[i];
level_or |= els[j];
level_and &= els[j];
j++;
}
}
nr_ucs = j;
// Calculate the breaking opportunities
if (UStrGetBreaks(script_type, ctr, wbr, lbp,
ucs, nr_ucs, &bos) == 0) {
_DBG_PRINTF("%s: failed to get breaking opportunities.\n");
goto out;
}
// Initialize other fields
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->run_head.list);
runinfo->run_head.lf = logfont;
runinfo->run_head.gs = NULL;
runinfo->run_head.nr_gs = 0;
runinfo->run_head.lt = lang_tag;
runinfo->run_head.st = script_type;
runinfo->run_head.dir = base_dir;
runinfo->run_head.si = 0;
runinfo->run_head.nr_ucs = nr_ucs;
// make the embedding levels of the bidi marks to be -1.
level_or = 0, level_and = 1;
j = 0;
for (i = 0; i < nr_ucs; i++) {
if (BIDI_IS_EXPLICIT_OR_BN (bidi_ts[i])) {
els[i] = -1;
}
else {
level_or |= els[j];
level_and &= els[j];
j++;
}
}
// check for all even or odd
/* If none of the levels had the LSB set, all chars were even. */
runinfo->all_even = (level_or & 0x1) == 0;
runinfo->run_head.all_even = (level_or & 0x1) == 0;
/* If all of the levels had the LSB set, all chars were odd. */
runinfo->all_odd = (level_and & 0x1) == 1;
runinfo->run_head.all_odd = (level_and & 0x1) == 1;
if (!init_glyph_runs(runinfo)) {
_DBG_PRINTF("%s: failed to call init_glyph_runs.\n");
goto out;
}
runinfo->ucs = ucs;
runinfo->nr_ucs = nr_ucs;
runinfo->els = els;
runinfo->bos = bos;
runinfo->base_dir = base_dir;
runinfo->lang_tag = lang_tag;
runinfo->script_tag = script_tag;
ok = TRUE;
out:
@@ -169,7 +197,7 @@ out:
if (ok)
return runinfo;
if (runinfo->runs) free(runinfo->runs);
if (runinfo->l2g) free(runinfo->l2g);
if (els) free(els);
if (bos) free(bos);
free(runinfo);
@@ -177,15 +205,153 @@ out:
return NULL;
}
BOOL GUIAPI ResetGlyphRunInfo(GLYPHRUNINFO* run_info)
BOOL GUIAPI SetPartFontInGlyphRuns(GLYPHRUNINFO* runinfo,
int start_index, int length, LOGFONT* logfont)
{
return FALSE;
}
BOOL GUIAPI DestroyGlyphRunInfo(GLYPHRUNINFO* run_info)
RGBCOLOR __mg_glyphruns_get_color(const GLYPHRUNINFO* runinfo, int index)
{
struct list_head *i;
list_for_each(i, &runinfo->cm_head.list) {
UCHARCOLORMAP* color_entry;
color_entry = (UCHARCOLORMAP*)i;
if (index >= color_entry->si &&
(index < color_entry->si + color_entry->len)) {
return color_entry->color;
}
}
return runinfo->cm_head.color;
}
BOOL GUIAPI SetPartColorInGlyphRuns(GLYPHRUNINFO* runinfo,
int start_index, int length, RGBCOLOR color)
{
UCHARCOLORMAP* color_entry = NULL;
if (runinfo == NULL || start_index < 0 || length < 0 ||
start_index > runinfo->run_head.nr_ucs ||
(start_index + length) > runinfo->run_head.nr_ucs) {
goto error;
}
color_entry = calloc(1, sizeof(UCHARCOLORMAP));
if (color_entry == NULL) {
goto error;
}
color_entry->si = start_index;
color_entry->len = length;
color_entry->color = color;
list_add(&color_entry->list, &runinfo->cm_head.list);
return TRUE;
error:
return FALSE;
}
BOOL GUIAPI ResetFontInGlyphRuns(GLYPHRUNINFO* runinfo, LOGFONT* logfont)
{
if (runinfo == NULL)
return FALSE;
while (!list_empty(&runinfo->run_head.list)) {
GLYPHRUN* run = (GLYPHRUN*)runinfo->run_head.list.prev;
list_del(runinfo->run_head.list.prev);
runinfo->se.cb_destroy_glyphs(runinfo->se.shaping_engine, run->gs);
free(run);
}
if (runinfo->se.shaping_engine) {
runinfo->se.cb_destroy_engine(runinfo->se.shaping_engine);
}
if (runinfo->l2g) {
free(runinfo->l2g);
runinfo->l2g = NULL;
}
if (runinfo->ges) {
free(runinfo->ges);
runinfo->ges = NULL;
}
runinfo->run_head.lf = logfont;
return init_glyph_runs(runinfo);
}
BOOL GUIAPI ResetColorInGlyphRuns(GLYPHRUNINFO* runinfo, RGBCOLOR color)
{
if (runinfo == NULL)
return FALSE;
while (!list_empty(&runinfo->cm_head.list)) {
UCHARCOLORMAP* entry = (UCHARCOLORMAP*)runinfo->cm_head.list.prev;
list_del(runinfo->cm_head.list.prev);
free(entry);
}
runinfo->cm_head.color = color;
return TRUE;
}
BOOL GUIAPI ResetBreaksInGlyphRuns(GLYPHRUNINFO* runinfo,
Uint8 ctr, Uint8 wbr, Uint8 lbp)
{
if (runinfo == NULL)
return FALSE;
if (runinfo->bos) {
free (runinfo->bos);
runinfo->bos = NULL;
}
// Calculate the breaking opportunities
if (UStrGetBreaks(runinfo->run_head.st, ctr, wbr, lbp,
runinfo->ucs, runinfo->run_head.nr_ucs, &runinfo->bos) == 0) {
_DBG_PRINTF("%s: failed to get breaking opportunities.\n");
return FALSE;
}
return TRUE;
}
BOOL GUIAPI DestroyGlyphRunInfo(GLYPHRUNINFO* runinfo)
{
if (runinfo == NULL)
return FALSE;
while (!list_empty(&runinfo->cm_head.list)) {
UCHARCOLORMAP* entry = (UCHARCOLORMAP*)runinfo->cm_head.list.prev;
list_del(runinfo->cm_head.list.prev);
free(entry);
}
while (!list_empty(&runinfo->run_head.list)) {
GLYPHRUN* run = (GLYPHRUN*)runinfo->run_head.list.prev;
list_del(runinfo->run_head.list.prev);
runinfo->se.cb_destroy_glyphs(runinfo->se.shaping_engine, run->gs);
free(run);
}
if (runinfo->se.shaping_engine) {
runinfo->se.cb_destroy_engine(runinfo->se.shaping_engine);
}
if (runinfo->l2g) free(runinfo->l2g);
if (runinfo->ges) free(runinfo->ges);
if (runinfo->els) free(runinfo->els);
if (runinfo->bos) free(runinfo->bos);
free(runinfo);
return TRUE;
}
#endif /* _MGCHARSET_UNICODE */
+48 -44
View File
@@ -41,10 +41,14 @@
#ifndef _MG_NEWGDI_GLYPHRUNINFO_H
#define _MG_NEWGDI_GLYPHRUNINFO_H
typedef Glyph32 (*CB_GET_GLYPH_INFO) (void* shaping_engine,
void* glyph_info, int index, int* cluster);
#include "list.h"
typedef BOOL (*CB_DESTROY_OBJECT) (void* object);
typedef Glyph32 (*CB_GET_GLYPH_INFO) (void* shaping_engine,
void* glyph_infos, int index, int* cluster);
typedef BOOL (*CB_DESTROY_GLYPHS) (void* shaping_engine, void* glyph_infos);
typedef BOOL (*CB_DESTROY_ENGINE) (void* shaping_engine);
typedef struct _SHAPPINGENGINE {
/* The pointer to the shaping engine */
@@ -57,18 +61,13 @@ typedef struct _SHAPPINGENGINE {
from a void glyph information */
CB_GET_GLYPH_INFO cb_get_glyph_info;
/* the callback destroy the shaping engine */
CB_DESTROY_OBJECT cb_destroy_engine;
/* the callback destroy the shaped glyph info */
CB_DESTROY_GLYPHS cb_destroy_glyphs;
/* the callback destroy the shapping engine instance */
CB_DESTROY_ENGINE cb_destroy_engine;
} SHAPPINGENGINE;
typedef struct _SHAPEDGLYPHS {
/* The array contains the glyph information */
void* glyph_infos;
/* The number of glyphs */
int nr_glyphs;
} SHAPEDGLYPHS;
/* same as HarfBuzz */
typedef enum {
GR_DIRECTION_INVALID = 0,
@@ -78,56 +77,61 @@ typedef enum {
GR_DIRECTION_BTT
} GlyphRunDir;
typedef struct _GLYPHRUN {
struct list_head list;
LOGFONT* lf; // The logfont for this run.
const char* lt; // language tag
void* gs; // the shaped glyph information
int nr_gs; // the number of shaped glyphs
int si; // start index
int nr_ucs; // the number of characters
ScriptType st; // script type
GlyphRunDir dir; // The direction
Uint8 all_even;
Uint8 all_odd;
} GLYPHRUN;
// NOTE: we arrange the fields carefully to avoid wasting space when
// we allocate an array of this structure.
// we allocate an array of this structure due to the alignment.
typedef struct _MAPL2G {
// Glyph index in the run; Less than 0 if it is ignored.
Sint32 glyph_index;
// the run index; a 16-bit unsigned number is enough.
Uint16 run_index;
// number of glyphs the uchar maps to.
Sint16 nr_glyphs;
GLYPHRUN* glyph_run; // the glyph run this char belongs to.
int glyph_index; // the index of the glyph in the run.
} MAPL2G;
typedef struct _GLYPHRUN {
LanguageCode lc;
ScriptType st;
GlyphRunDir dir;
int si; // start index
int len;
} GLYPHRUN;
typedef struct _UCHARCOLORMAP {
struct list_head list;
int si;
int len;
RGBCOLOR color;
} UCHARCOLORMAP;
struct _GLYPHRUNINFO {
/* The following fields will be initialized by CreateGlyphRunInfo. */
Uchar32* ucs;
BidiLevel* els;
BreakOppo* bos;
GLYPHRUN* runs;
/* The following fields will be initialized by the Shapping Engine. */
LOGFONT* lfur; // The logfont for upright glyphs
LOGFONT* lfsw; // The logfont for sideways glyphs
SHAPPINGENGINE se;
MAPL2G* u2g;
SHAPEDGLYPHS** sgs;
GLYPHEXTINFO** ges;
UCHARCOLORMAP cm_head; // the head of color map list of the characters.
// change by calling SetPartColorInGlyphRunInfo.
GLYPHRUN run_head; // glyph runs
// change by SetPartFontInGlyphRunInfo.
const char* lang_tag;
const char* script_tag;
Uint32 render_flags;
int nr_ucs;
int nr_runs;
ParagraphDir base_dir;
/* The following fields will be initialized by the shapping engine. */
SHAPPINGENGINE se; // the shapping engine.
MAPL2G* l2g; // the logical character to glyph map.
GLYPHEXTINFO* ges; // the glyph extent information.
/* The following fields will be initialized by CreateGlyphRunInfo. */
Uint8 all_even;
Uint8 all_odd;
Uint32 rf; // the rendering flags.
};
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
RGBCOLOR __mg_glyphruns_get_color(const GLYPHRUNINFO* runinfo, int index);
#ifdef __cplusplus
}
+1 -2
View File
@@ -79,8 +79,7 @@ static void bidi_reverse_shaped_glyphs (void* context, int len, int pos)
# define LOCAL_ARRAY_SIZE 128
#endif
BOOL GUIAPI ShapeGlyphRunsBasic(GLYPHRUNINFO* run_info,
LOGFONT* lf, Uint32 rf)
BOOL GUIAPI ShapeGlyphRunsBasic(GLYPHRUNINFO* run_info, Uint32 rf)
{
#if 0
int ret_value = 0;
+1 -2
View File
@@ -57,8 +57,7 @@
#include "unicode-ops.h"
#include "glyphruninfo.h"
BOOL GUIAPI ShapeGlyphRunsComplex(GLYPHRUNINFO* run_info,
LOGFONT* lf, Uint32 rf)
BOOL GUIAPI ShapeGlyphRunsComplex(GLYPHRUNINFO* run_info, Uint32 rf)
{
return FALSE;
}