Tune GlyphRunInfo

This commit is contained in:
Vincent Wei
2019-03-16 19:12:57 +08:00
parent 349f310148
commit d63fe9849b
3 changed files with 134 additions and 48 deletions
+43 -6
View File
@@ -12199,8 +12199,15 @@ MG_EXPORT int GUIAPI UChars2AChars(LOGFONT* logfont, const Uchar32* ucs,
/** @} end of glyph_render_flags */ /** @} end of glyph_render_flags */
#define GLYPH_ORIENTATION_UPRIGHT 0 #define GLYPH_GRAVITY_NORTH 0
#define GLYPH_ORIENTATION_SIDEWAYS 1 #define GLYPH_GRAVITY_EAST 1
#define GLYPH_GRAVITY_WEST 2
#define GLYPH_GRAVITY_SOUTH 3
#define GLYPH_ORIENTATION_UPRIGHT GLYPH_GRAVITY_NORTH
#define GLYPH_ORIENTATION_SIDEWAYS GLYPH_GRAVITY_EAST
#define GLYPH_ORIENTATION_SIDEWAYS_LEFT GLYPH_GRAVITY_WEST
#define GLYPH_ORIENTATION_INVERTED GLYPH_GRAVITY_SOUTH
#define GLYPH_HANGED_NONE 0 #define GLYPH_HANGED_NONE 0
#define GLYPH_HANGED_START 1 #define GLYPH_HANGED_START 1
@@ -12232,6 +12239,10 @@ typedef struct _GLYPHEXTINFO {
* the glyph is in the standard horizontal orientation. * the glyph is in the standard horizontal orientation.
* - GLYPH_ORIENTATION_SIDEWAYS\n * - GLYPH_ORIENTATION_SIDEWAYS\n
* the glyph rotates 90° clockwise from horizontal. * the glyph rotates 90° clockwise from horizontal.
* - GLYPH_ORIENTATION_SIDEWAYS_LEFT\n
* the glyph rotates 90° counter-clockwise from horizontal.
* - GLYPH_ORIENTATION_INVERTED\n
* the glyph is in the inverted horizontal orientation.
*/ */
Uint8 orientation:2; Uint8 orientation:2;
} GLYPHEXTINFO; } GLYPHEXTINFO;
@@ -12262,6 +12273,10 @@ typedef struct _GLYPHPOS {
* the glyph is in the standard horizontal orientation. * the glyph is in the standard horizontal orientation.
* - GLYPH_ORIENTATION_SIDEWAYS\n * - GLYPH_ORIENTATION_SIDEWAYS\n
* the glyph rotates 90° clockwise from horizontal. * the glyph rotates 90° clockwise from horizontal.
* - GLYPH_ORIENTATION_SIDEWAYS_LEFT\n
* the glyph rotates 90° counter-clockwise from horizontal.
* - GLYPH_ORIENTATION_INVERTED\n
* the glyph is in the inverted horizontal orientation.
*/ */
Uint8 orientation:2; Uint8 orientation:2;
/** /**
@@ -12365,6 +12380,23 @@ MG_EXPORT int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright,
struct _GLYPHRUNINFO; struct _GLYPHRUNINFO;
typedef struct _GLYPHRUNINFO GLYPHRUNINFO; typedef struct _GLYPHRUNINFO GLYPHRUNINFO;
/* same as HarfBuzz */
typedef enum {
GLYPH_RUN_DIR_INVALID = 0,
GLYPH_RUN_DIR_LTR = 4,
GLYPH_RUN_DIR_RTL,
GLYPH_RUN_DIR_TTB,
GLYPH_RUN_DIR_BTT
} GlyphRunDir;
typedef enum {
GLYPH_ORIENT_NORTH = GLYPH_GRAVITY_NORTH,
GLYPH_ORIENT_EAST = GLYPH_GRAVITY_EAST,
GLYPH_ORIENT_WEST = GLYPH_GRAVITY_WEST,
GLYPH_ORIENT_SOUTH = GLYPH_GRAVITY_SOUTH,
GLYPH_ORIENT_MIXED,
} GlyphOrient;
/** /**
* Split a Uchar32 paragraph string into text runs according to the * Split a Uchar32 paragraph string into text runs according to the
* scripts of characters. * scripts of characters.
@@ -12372,11 +12404,10 @@ typedef struct _GLYPHRUNINFO GLYPHRUNINFO;
* This function also calculates the embedding levels and the * This function also calculates the embedding levels and the
* breaking opportunities of the string. * breaking opportunities of the string.
*/ */
MG_EXPORT GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo( MG_EXPORT GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(Uchar32* ucs, int nr_ucs,
const char* lang_tag, const char* script_tag, const char* lang_tag, const char* script_tag,
Uchar32* ucs, int nr_ucs, ParagraphDir base_dir, GlyphRunDir run_dir, GlyphOrient glyph_orient, ParagraphDir base_dir,
Uint8 ctr, Uint8 wbr, Uint8 lbp, Uint8 ctr, Uint8 wbr, Uint8 lbp, LOGFONT* logfont, RGBCOLOR color);
LOGFONT* logfont, RGBCOLOR color);
/** /**
* Set font of part characters. Please call this function before * Set font of part characters. Please call this function before
@@ -12410,6 +12441,12 @@ MG_EXPORT BOOL GUIAPI ResetColorInGlyphRuns(GLYPHRUNINFO* run_info,
MG_EXPORT BOOL GUIAPI ResetBreaksInGlyphRuns(GLYPHRUNINFO* run_info, MG_EXPORT BOOL GUIAPI ResetBreaksInGlyphRuns(GLYPHRUNINFO* run_info,
Uint8 ctr, Uint8 wbr, Uint8 lbp); Uint8 ctr, Uint8 wbr, Uint8 lbp);
/**
* Reset the direction and orientation of glyph runs.
*/
MG_EXPORT BOOL GUIAPI ResetDirectionInGlyphRuns(GLYPHRUNINFO* run_info,
GlyphRunDir run_dir, GlyphOrient glyph_orient);
/** /**
* Destroy the glyph run info object. It also frees all data allocated * Destroy the glyph run info object. It also frees all data allocated
* for shapping and layouting the glyphs. * for shapping and layouting the glyphs.
+73 -16
View File
@@ -66,11 +66,10 @@ static BOOL init_glyph_runs(GLYPHRUNINFO* runinfo)
return FALSE; return FALSE;
} }
GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo( GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(Uchar32* ucs, int nr_ucs,
const char* lang_tag, const char* script_tag, const char* lang_tag, const char* script_tag,
Uchar32* ucs, int nr_ucs, ParagraphDir base_dir, GlyphRunDir run_dir, GlyphOrient glyph_orient, ParagraphDir base_dir,
Uint8 ctr, Uint8 wbr, Uint8 lbp, Uint8 ctr, Uint8 wbr, Uint8 lbp, LOGFONT* logfont, RGBCOLOR color)
LOGFONT* logfont, RGBCOLOR color)
{ {
BOOL ok = FALSE; BOOL ok = FALSE;
@@ -151,12 +150,16 @@ GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(
runinfo->run_head.lf = logfont; runinfo->run_head.lf = logfont;
runinfo->run_head.gs = NULL; runinfo->run_head.gs = NULL;
runinfo->run_head.nr_gs = 0; 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.si = 0;
runinfo->run_head.nr_ucs = nr_ucs; runinfo->run_head.nr_ucs = nr_ucs;
runinfo->run_head.lt = lang_tag;
runinfo->run_head.st = script_type;
runinfo->run_head.level = BIDI_DIR_TO_LEVEL(base_dir);
runinfo->run_head.dir = run_dir;
runinfo->run_head.ort = glyph_orient;
// make the embedding levels of the bidi marks to be -1. // make the embedding levels of the bidi marks to be -1.
level_or = 0, level_and = 1; level_or = 0, level_and = 1;
j = 0; j = 0;
@@ -206,8 +209,19 @@ out:
} }
BOOL GUIAPI SetPartFontInGlyphRuns(GLYPHRUNINFO* runinfo, BOOL GUIAPI SetPartFontInGlyphRuns(GLYPHRUNINFO* runinfo,
int start_index, int length, LOGFONT* logfont) int start_index, int length, LOGFONT* logfont)
{ {
if (runinfo == NULL)
return FALSE;
// can not change font after shaped the glyphs
if (runinfo->se.engine != NULL)
return FALSE;
// can not change font for empty runs
if (list_empty(&runinfo->run_head.list))
return FALSE;
return FALSE; return FALSE;
} }
@@ -228,7 +242,7 @@ RGBCOLOR __mg_glyphruns_get_color(const GLYPHRUNINFO* runinfo, int index)
} }
BOOL GUIAPI SetPartColorInGlyphRuns(GLYPHRUNINFO* runinfo, BOOL GUIAPI SetPartColorInGlyphRuns(GLYPHRUNINFO* runinfo,
int start_index, int length, RGBCOLOR color) int start_index, int length, RGBCOLOR color)
{ {
UCHARCOLORMAP* color_entry = NULL; UCHARCOLORMAP* color_entry = NULL;
@@ -263,12 +277,12 @@ BOOL GUIAPI ResetFontInGlyphRuns(GLYPHRUNINFO* runinfo, LOGFONT* logfont)
while (!list_empty(&runinfo->run_head.list)) { while (!list_empty(&runinfo->run_head.list)) {
GLYPHRUN* run = (GLYPHRUN*)runinfo->run_head.list.prev; GLYPHRUN* run = (GLYPHRUN*)runinfo->run_head.list.prev;
list_del(runinfo->run_head.list.prev); list_del(runinfo->run_head.list.prev);
runinfo->se.cb_destroy_glyphs(runinfo->se.shaping_engine, run->gs); runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs);
free(run); free(run);
} }
if (runinfo->se.shaping_engine) { if (runinfo->se.engine) {
runinfo->se.cb_destroy_engine(runinfo->se.shaping_engine); runinfo->se.destroy_engine(runinfo->se.engine);
} }
if (runinfo->l2g) { if (runinfo->l2g) {
@@ -286,6 +300,49 @@ BOOL GUIAPI ResetFontInGlyphRuns(GLYPHRUNINFO* runinfo, LOGFONT* logfont)
return init_glyph_runs(runinfo); return init_glyph_runs(runinfo);
} }
static void set_run_dir(GLYPHRUNINFO* runinfo, GLYPHRUN* run,
GlyphRunDir run_dir, GlyphOrient glyph_orient)
{
}
BOOL GUIAPI ResetDirectionInGlyphRuns(GLYPHRUNINFO* runinfo,
GlyphRunDir run_dir, GlyphOrient glyph_orient)
{
struct list_head *i;
if (runinfo == NULL)
return FALSE;
runinfo->run_head.dir = run_dir;
runinfo->run_head.ort = glyph_orient;
list_for_each(i, &runinfo->run_head.list) {
GLYPHRUN* run = (GLYPHRUN*)i;
if (runinfo->se.engine && run->gs) {
runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs);
}
set_run_dir(runinfo, run, run_dir, glyph_orient);
}
if (runinfo->l2g) {
free(runinfo->l2g);
runinfo->l2g = NULL;
}
if (runinfo->ges) {
free(runinfo->ges);
runinfo->ges = NULL;
}
if (runinfo->se.engine) {
runinfo->se.destroy_engine(runinfo->se.engine);
runinfo->se.engine = NULL;
}
return TRUE;
}
BOOL GUIAPI ResetColorInGlyphRuns(GLYPHRUNINFO* runinfo, RGBCOLOR color) BOOL GUIAPI ResetColorInGlyphRuns(GLYPHRUNINFO* runinfo, RGBCOLOR color)
{ {
if (runinfo == NULL) if (runinfo == NULL)
@@ -312,7 +369,7 @@ BOOL GUIAPI ResetBreaksInGlyphRuns(GLYPHRUNINFO* runinfo,
runinfo->bos = NULL; runinfo->bos = NULL;
} }
// Calculate the breaking opportunities // Re-calculate the breaking opportunities
if (UStrGetBreaks(runinfo->run_head.st, ctr, wbr, lbp, if (UStrGetBreaks(runinfo->run_head.st, ctr, wbr, lbp,
runinfo->ucs, runinfo->run_head.nr_ucs, &runinfo->bos) == 0) { runinfo->ucs, runinfo->run_head.nr_ucs, &runinfo->bos) == 0) {
_DBG_PRINTF("%s: failed to get breaking opportunities.\n"); _DBG_PRINTF("%s: failed to get breaking opportunities.\n");
@@ -336,12 +393,12 @@ BOOL GUIAPI DestroyGlyphRunInfo(GLYPHRUNINFO* runinfo)
while (!list_empty(&runinfo->run_head.list)) { while (!list_empty(&runinfo->run_head.list)) {
GLYPHRUN* run = (GLYPHRUN*)runinfo->run_head.list.prev; GLYPHRUN* run = (GLYPHRUN*)runinfo->run_head.list.prev;
list_del(runinfo->run_head.list.prev); list_del(runinfo->run_head.list.prev);
runinfo->se.cb_destroy_glyphs(runinfo->se.shaping_engine, run->gs); runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs);
free(run); free(run);
} }
if (runinfo->se.shaping_engine) { if (runinfo->se.engine) {
runinfo->se.cb_destroy_engine(runinfo->se.shaping_engine); runinfo->se.destroy_engine(runinfo->se.engine);
} }
if (runinfo->l2g) free(runinfo->l2g); if (runinfo->l2g) free(runinfo->l2g);
+18 -26
View File
@@ -43,55 +43,47 @@
#include "list.h" #include "list.h"
typedef Glyph32 (*CB_GET_GLYPH_INFO) (void* shaping_engine, typedef Glyph32 (*CB_GET_GLYPH_INFO) (void* engine,
void* glyph_infos, int index, int* cluster); void* glyph_infos, int index, int* cluster);
typedef BOOL (*CB_DESTROY_GLYPHS) (void* shaping_engine, void* glyph_infos); typedef BOOL (*CB_DESTROY_GLYPHS) (void* engine, void* glyph_infos);
typedef BOOL (*CB_DESTROY_ENGINE) (void* shaping_engine); typedef BOOL (*CB_DESTROY_ENGINE) (void* engine);
typedef struct _SHAPPINGENGINE { typedef struct _SHAPPINGENGINE {
/* The pointer to the shaping engine */ /* The pointer to the shaping engine */
void* shaping_engine; void* engine;
/* the callback reverse the glyphs */ /* the callback reverse the glyphs */
CB_REVERSE_ARRAY cb_reverse_glyphs; CB_REVERSE_ARRAY reverse_glyphs;
/* The callback returns the glyph value and cluster /* The callback returns the glyph value and cluster
from a void glyph information */ from a void glyph information */
CB_GET_GLYPH_INFO cb_get_glyph_info; CB_GET_GLYPH_INFO get_glyph_info;
/* the callback destroy the shaped glyph info */ /* the callback destroy the shaped glyph info */
CB_DESTROY_GLYPHS cb_destroy_glyphs; CB_DESTROY_GLYPHS destroy_glyphs;
/* the callback destroy the shapping engine instance */ /* the callback destroy the shapping engine instance */
CB_DESTROY_ENGINE cb_destroy_engine; CB_DESTROY_ENGINE destroy_engine;
} SHAPPINGENGINE; } SHAPPINGENGINE;
/* same as HarfBuzz */
typedef enum {
GR_DIRECTION_INVALID = 0,
GR_DIRECTION_LTR = 4,
GR_DIRECTION_RTL,
GR_DIRECTION_TTB,
GR_DIRECTION_BTT
} GlyphRunDir;
typedef struct _GLYPHRUN { typedef struct _GLYPHRUN {
struct list_head list; struct list_head list;
LOGFONT* lf; // The logfont for this run. LOGFONT* lf; // the logfont for this run.
const char* lt; // language tag const char* lt; // language tag
void* gs; // the shaped glyph information void* gs; // the shaped glyph information
int nr_gs; // the number of shaped glyphs int nr_gs; // the number of shaped glyphs
int si; // start index in the Unicode string
int nr_ucs; // the number of Unicode characters
int si; // start index Uint32 st:8; // script type
int nr_ucs; // the number of characters Uint32 level:8; // the bidi level
Uint32 dir:4; // the run direction
ScriptType st; // script type Uint32 ort:2; // the glyph orientation
GlyphRunDir dir; // The direction Uint32 all_even:1; // flag indicating all level is even
Uint8 all_odd:1; // flag indicating all level is odd
Uint8 all_even;
Uint8 all_odd;
} GLYPHRUN; } GLYPHRUN;
// NOTE: we arrange the fields carefully to avoid wasting space when // NOTE: we arrange the fields carefully to avoid wasting space when