diff --git a/include/gdi.h b/include/gdi.h index 4b94d00d..37cf9fb2 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -12199,8 +12199,15 @@ MG_EXPORT int GUIAPI UChars2AChars(LOGFONT* logfont, const Uchar32* ucs, /** @} end of glyph_render_flags */ -#define GLYPH_ORIENTATION_UPRIGHT 0 -#define GLYPH_ORIENTATION_SIDEWAYS 1 +#define GLYPH_GRAVITY_NORTH 0 +#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_START 1 @@ -12232,6 +12239,10 @@ typedef struct _GLYPHEXTINFO { * the glyph is in the standard horizontal orientation. * - GLYPH_ORIENTATION_SIDEWAYS\n * 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; } GLYPHEXTINFO; @@ -12262,6 +12273,10 @@ typedef struct _GLYPHPOS { * the glyph is in the standard horizontal orientation. * - GLYPH_ORIENTATION_SIDEWAYS\n * 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; /** @@ -12365,6 +12380,23 @@ MG_EXPORT int GUIAPI GetGlyphsExtentFromUChars(LOGFONT* logfont_upright, struct _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 * scripts of characters. @@ -12372,11 +12404,10 @@ typedef struct _GLYPHRUNINFO GLYPHRUNINFO; * This function also calculates the embedding levels and the * 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, - Uchar32* ucs, int nr_ucs, ParagraphDir base_dir, - Uint8 ctr, Uint8 wbr, Uint8 lbp, - LOGFONT* logfont, RGBCOLOR color); + GlyphRunDir run_dir, GlyphOrient glyph_orient, ParagraphDir base_dir, + Uint8 ctr, Uint8 wbr, Uint8 lbp, LOGFONT* logfont, RGBCOLOR color); /** * 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, 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 * for shapping and layouting the glyphs. diff --git a/src/newgdi/glyphruninfo.c b/src/newgdi/glyphruninfo.c index 688abb4e..09447aca 100644 --- a/src/newgdi/glyphruninfo.c +++ b/src/newgdi/glyphruninfo.c @@ -66,11 +66,10 @@ static BOOL init_glyph_runs(GLYPHRUNINFO* runinfo) return FALSE; } -GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo( +GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo(Uchar32* ucs, int nr_ucs, const char* lang_tag, const char* script_tag, - Uchar32* ucs, int nr_ucs, ParagraphDir base_dir, - Uint8 ctr, Uint8 wbr, Uint8 lbp, - LOGFONT* logfont, RGBCOLOR color) + GlyphRunDir run_dir, GlyphOrient glyph_orient, ParagraphDir base_dir, + Uint8 ctr, Uint8 wbr, Uint8 lbp, LOGFONT* logfont, RGBCOLOR color) { BOOL ok = FALSE; @@ -151,12 +150,16 @@ GLYPHRUNINFO* GUIAPI CreateGlyphRunInfo( 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; + 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. level_or = 0, level_and = 1; j = 0; @@ -206,8 +209,19 @@ out: } 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; } @@ -228,7 +242,7 @@ RGBCOLOR __mg_glyphruns_get_color(const GLYPHRUNINFO* runinfo, int index) } BOOL GUIAPI SetPartColorInGlyphRuns(GLYPHRUNINFO* runinfo, - int start_index, int length, RGBCOLOR color) + int start_index, int length, RGBCOLOR color) { UCHARCOLORMAP* color_entry = NULL; @@ -263,12 +277,12 @@ BOOL GUIAPI ResetFontInGlyphRuns(GLYPHRUNINFO* runinfo, LOGFONT* logfont) 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); + runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs); free(run); } - if (runinfo->se.shaping_engine) { - runinfo->se.cb_destroy_engine(runinfo->se.shaping_engine); + if (runinfo->se.engine) { + runinfo->se.destroy_engine(runinfo->se.engine); } if (runinfo->l2g) { @@ -286,6 +300,49 @@ BOOL GUIAPI ResetFontInGlyphRuns(GLYPHRUNINFO* runinfo, LOGFONT* logfont) 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) { if (runinfo == NULL) @@ -312,7 +369,7 @@ BOOL GUIAPI ResetBreaksInGlyphRuns(GLYPHRUNINFO* runinfo, runinfo->bos = NULL; } - // Calculate the breaking opportunities + // Re-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"); @@ -336,12 +393,12 @@ BOOL GUIAPI DestroyGlyphRunInfo(GLYPHRUNINFO* runinfo) 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); + runinfo->se.destroy_glyphs(runinfo->se.engine, run->gs); free(run); } - if (runinfo->se.shaping_engine) { - runinfo->se.cb_destroy_engine(runinfo->se.shaping_engine); + if (runinfo->se.engine) { + runinfo->se.destroy_engine(runinfo->se.engine); } if (runinfo->l2g) free(runinfo->l2g); diff --git a/src/newgdi/glyphruninfo.h b/src/newgdi/glyphruninfo.h index 1845e92e..4c2e4b85 100644 --- a/src/newgdi/glyphruninfo.h +++ b/src/newgdi/glyphruninfo.h @@ -43,55 +43,47 @@ #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); -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 { /* The pointer to the shaping engine */ - void* shaping_engine; + void* engine; /* the callback reverse the glyphs */ - CB_REVERSE_ARRAY cb_reverse_glyphs; + CB_REVERSE_ARRAY reverse_glyphs; /* The callback returns the glyph value and cluster 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 */ - CB_DESTROY_GLYPHS cb_destroy_glyphs; + CB_DESTROY_GLYPHS destroy_glyphs; /* the callback destroy the shapping engine instance */ - CB_DESTROY_ENGINE cb_destroy_engine; + CB_DESTROY_ENGINE destroy_engine; } 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 { struct list_head list; - LOGFONT* lf; // The logfont for this run. + 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 in the Unicode string + int nr_ucs; // the number of Unicode characters - 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; + Uint32 st:8; // script type + Uint32 level:8; // the bidi level + Uint32 dir:4; // the run direction + Uint32 ort:2; // the glyph orientation + Uint32 all_even:1; // flag indicating all level is even + Uint8 all_odd:1; // flag indicating all level is odd } GLYPHRUN; // NOTE: we arrange the fields carefully to avoid wasting space when