From f73f0786eed0fdeae11f3ac1b8cd2fae1690ec94 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Thu, 28 Feb 2019 11:50:00 +0800 Subject: [PATCH] remove break_classes argument and add uchars argument for GetGlyphsAndBreaks --- include/gdi.h | 106 +++++++++++-------- src/include/devfont.h | 2 - src/newgdi/Makefile.am | 7 +- src/newgdi/{glyph-css.c => glyph-unicode.c} | 109 +++++++++++++------- 4 files changed, 137 insertions(+), 87 deletions(-) rename src/newgdi/{glyph-css.c => glyph-unicode.c} (98%) diff --git a/include/gdi.h b/include/gdi.h index e8049a69..5bdd2535 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -5748,15 +5748,21 @@ typedef struct _LOGFONT { int ascent; /** The descent of the logical font. */ int descent; - /** The size requested */ + /** The size requested initially. */ int size_request; - /** The scale factor of sbc device font. */ + + /* The devfonts for the logfont */ + DEVFONT* devfonts[4]; + /* The scale factors of devfonts */ + Uint8 df_scales[4]; + + /* To be deprecated. The scale factor of sbc device font. */ unsigned short sbc_scale; - /** The scale factor of mbc device font. */ + /* To be deprecated. The scale factor of mbc device font. */ unsigned short mbc_scale; - /** Device font in single charset set */ + /* To be deprecated. Device font in single charset set */ DEVFONT* sbc_devfont; - /** Device font in multiply charset set */ + /* To be deprecated. Device font in multiply charset set */ DEVFONT* mbc_devfont; } LOGFONT; /** @@ -9527,15 +9533,42 @@ typedef Uint32 Glyph32; /** * \def INV_GLYPH_VALUE */ -#define INV_GLYPH_VALUE -1 +#define INV_GLYPH_VALUE 0xFFFFFFFF + +#define GLYPH_DEVFONT_INDEX_MASK 0xC0000000 +#define GLYPH_DEVFONT_INDEX_SHIFT 30 + +/** + * \def REAL_GLYPH(glyph) + * \brief Get the real (DEVFONT) glyph value from a LOGFONT glyph. + * + * \param glyph The LOGFONT glyph value + */ +#define REAL_GLYPH(glyph) ((glyph) & ~GLYPH_DEVFONT_INDEX_MASK) + +/** + * \def SELECT_DEVFONT_EX(plogfont, glyph) + * \brief Select a DEVFONT according to the LOGFONT glyph value. + * + * \param plogfont The pointer to a logical font. + * \param glyph The logical glyph value. + * + */ +#define SELECT_DEVFONT_EX(plogfont, glyph) \ + (plogfont)->devfonts[((glyph) >> GLYPH_DEVFONT_INDEX_SHIFT) & 0x03] + +/* to be deprecated */ +#define SELECT_DEVFONT(plogfont, glyph) \ + ((glyph) & GLYPH_DEVFONT_INDEX_MASK ? \ + (plogfont)->mbc_devfont : (plogfont)->sbc_devfont) /** * \def IS_MBC_GLYPH(glyph) - * \brief to judge wether the glyph is multibyte glyph + * \brief Determine wether the glyph is multibyte glyph * - * \param glyph glyph value + * \param glyph The logfont glyph value */ -#define IS_MBC_GLYPH(glyph) ((glyph) & 0x80000000) +#define IS_MBC_GLYPH(glyph) ((glyph) & GLYPH_DEVFONT_INDEX_MASK) /** * \def SET_MBC_GLYPH(glyph) @@ -9545,36 +9578,6 @@ typedef Uint32 Glyph32; */ #define SET_MBC_GLYPH(glyph) ((glyph) | 0x80000000) -/** - * \def REAL_GLYPH(glyph) - * \brief get real glyph value from a glyph - * - * \param glyph glyph value - */ -#define REAL_GLYPH(glyph) ((glyph) & 0x7FFFFFFF) - -/** - * \def GLYPH2UCHAR(glyph) - * \brief get real glyph value from a glyph. - * Only valid for UNICODE. - * - * \param glyph glyph value. - */ -#define GLYPH2UCHAR(glyph) ((glyph) & 0x7FFFFFFF) - -/** - * \def SELECT_DEVFONT(plogfont, glyph) - * \brief select a device font acording to the glyph value. - * - * \param plogfont pointer to a logical font. - * \param glyph glyph value. - * - */ -#define SELECT_DEVFONT(plogfont, glyph) \ - ((glyph) & 0x80000000 ? \ - (plogfont)->mbc_devfont : \ - (plogfont)->sbc_devfont) - /** * \var typedef struct _GLYPHMAPINFO GLYPHMAPINFO * \brief Data type of struct _GLYPHMAPINFO. @@ -10546,7 +10549,7 @@ static inline int GUIAPI LanguageCodeFromISO639s1Code (const char* iso639_1) * const char* mstr, unsigned int mstr_len, * LanguageCode content_language, UCharScriptType writing_system, * Uint8 wsr, Uint8 ctr, Uint8 wbr, Uint8 lbp, - * Glyph32** glyphs, Uint16** break_oppos, Uint8** break_classes, + * Glyph32** glyphs, Uchar32** uchars, Uint16** break_oppos, * int* nr_glyphs); * \brief Calculate the glyph string and the breaking opportunities under * the specified rules and line breaking policy. @@ -10590,6 +10593,9 @@ static inline int GUIAPI LanguageCodeFromISO639s1Code (const char* iso639_1) * see \a line_break_policies. * \param glyphs The pointer to a buffer to store the address of the * allocated glyph string. + * \param uchars The pointer to a buffer to store the address of the + * UChar32 array which contains the Unicode character values + * of the glyphs; can be NULL. * \param break_oppos The pointer to a buffer to store the address of the * Uint16 array which contains the break opportunities of the glyphs. * Note that the length of this array is always one longer than @@ -10603,9 +10609,6 @@ static inline int GUIAPI LanguageCodeFromISO639s1Code (const char* iso639_1) * No breaking allowed after the glyph definitely. * - BOV_LB_ALLOWED\n * Breaking allowed after the glyph. - * \param break_classes The pointer to a buffer to store the address of the - * Uint8 array which contains the breaking classes (UCharBreakType) - * of the glyphs; can be NULL. * \param nr_glyphs The buffer to store the number of the allocated glyphs. * * \return The number of the bytes consumed in \a mstr; zero on error. @@ -10618,9 +10621,24 @@ MG_EXPORT int GUIAPI GetGlyphsAndBreaks(LOGFONT* logfont, const char* mstr, int mstr_len, LanguageCode content_language, UCharScriptType writing_system, Uint8 wsr, Uint8 ctr, Uint8 wbr, Uint8 lbp, - Glyph32** glyphs, Uint16** break_oppos, Uint8** break_classes, + Glyph32** glyphs, Uchar32** uchars, Uint16** break_oppos, int* nr_glyphs); +/** + * \fn Glyph2UChar(LOGFONT* logfont, Glyph32 gv) + * \brief Get Uchar32 value (whide character value) from a LOGFONT glyph value. + * + * Only valid for UNICODE. + * + * \param logfont The LOGFONT object + * \param glyph The LOGFONT glyph value. + * + * \return The Uchar32 value (Unicode code point) of the glyph. + * + * \note Only available when support for UNICODE is enabled. + */ +MG_EXPORT Uchar32 GUIAPI Glyph2UChar(LOGFONT* logfont, Glyph32 gv); + /** * \defgroup glyph_render_flags Glyph Rendering Flags * diff --git a/src/include/devfont.h b/src/include/devfont.h index cdf05b9f..480ad9df 100644 --- a/src/include/devfont.h +++ b/src/include/devfont.h @@ -87,8 +87,6 @@ void font_DelMBDevFont (DEVFONT* dev_font); void dbg_dumpDevFonts (void); #endif -#define INV_GLYPH_VALUE -1 - static inline BOOL check_zero_width(unsigned int t) { return (t & GLYPHTYPE_MCHAR_MASK) == MCHAR_TYPE_ZEROWIDTH; diff --git a/src/newgdi/Makefile.am b/src/newgdi/Makefile.am index 62b72911..d6b810da 100644 --- a/src/newgdi/Makefile.am +++ b/src/newgdi/Makefile.am @@ -4,9 +4,8 @@ noinst_LTLIBRARIES = libnewgdi.la if MG_MINIMALGDI SRC_FILES = gdi.c attr.c clip.c coor.c rect.c \ - bitmap.c \ - pixel.c pixel_ops.c \ - region.c polygon.c + bitmap.c pixel.c pixel_ops.c \ + region.c polygon.c else SRC_FILES = gdi.c attr.c clip.c map.c coor.c rect.c \ palette.c readbmp.c icon.c screen.c bitmap.c \ @@ -14,7 +13,7 @@ SRC_FILES = gdi.c attr.c clip.c map.c coor.c rect.c \ region.c generators.c polygon.c flood.c \ advapi.c midash.c mispans.c miwideline.c \ mifillarc.c mifpolycon.c miarc.c rotatebmp.c \ - text.c glyph.c bidi.c glyph-css.c \ + text.c glyph.c bidi.c glyph-unicode.c \ textout.c tabbedtextout.c drawtext.c endif diff --git a/src/newgdi/glyph-css.c b/src/newgdi/glyph-unicode.c similarity index 98% rename from src/newgdi/glyph-css.c rename to src/newgdi/glyph-unicode.c index 0df0dba6..a0d38c86 100644 --- a/src/newgdi/glyph-css.c +++ b/src/newgdi/glyph-unicode.c @@ -160,6 +160,7 @@ struct glyph_break_ctxt { DEVFONT* mbc_devfont; DEVFONT* sbc_devfont; Glyph32* gvs; + Uchar32* ucs; Uint8* bts; Uint16* bos; Uint8* ods; @@ -179,6 +180,7 @@ struct glyph_break_ctxt { Uint8 curr_gc; Uint8 curr_od; + /* UAX#29 boundaries */ Uchar32 prev_uc; Uchar32 base_uc; Uchar32 last_word_letter; @@ -198,30 +200,14 @@ struct glyph_break_ctxt { Uint8 met_extended_pictographic:1; Uint8 is_extended_pictographic:1; - /* UAX#29 boundaries */ Uint8 is_grapheme_boundary:1; Uint8 is_word_boundary:1; Uint8 is_sentence_boundary:1; + + // internal use + Uint8 need_ucs:1; }; -static int gbctxt_init_spaces(struct glyph_break_ctxt* gbctxt, int size) -{ - // pre-allocate buffers - gbctxt->len_buff = size; - if (gbctxt->len_buff < MIN_LEN_GLYPHS) - gbctxt->len_buff = MIN_LEN_GLYPHS; - - gbctxt->gvs = (Glyph32*)malloc(sizeof(Glyph32) * gbctxt->len_buff); - gbctxt->bts = (Uint8*)malloc(sizeof(Uint8) * gbctxt->len_buff); - gbctxt->bos = (Uint16*)malloc(sizeof(Uint16) * gbctxt->len_buff); - gbctxt->ods = (Uint8*)malloc(sizeof(Uint8) * gbctxt->len_buff); - if (gbctxt->gvs == NULL || gbctxt->bts == NULL - || gbctxt->bos == NULL || gbctxt->ods == NULL) - return 0; - - return gbctxt->len_buff; -} - static BOOL gbctxt_change_lbo_last(struct glyph_break_ctxt* gbctxt, Uint16 lbo) { @@ -296,7 +282,7 @@ static BOOL gbctxt_change_lbo_before_last_sp(struct glyph_break_ctxt* gbctxt, return FALSE; } - if (GLYPH2UCHAR(gbctxt->gvs[gbctxt->n - 3]) == UCHAR_SPACE) { + if (REAL_GLYPH(gbctxt->gvs[gbctxt->n - 3]) == UCHAR_SPACE) { _DBG_PRINTF("%s: force changed: curr_od(%d), org_od(%d)\n", __FUNCTION__, gbctxt->curr_od, gbctxt->ods[gbctxt->n - 2]); gbctxt->bos[gbctxt->n - 2] = lbo; @@ -336,7 +322,7 @@ static int get_next_glyph(struct glyph_break_ctxt* gbctxt, if (gbctxt->mbc_devfont->charset_ops->conv_to_uc32) *uc = gbctxt->mbc_devfont->charset_ops->conv_to_uc32(*gv); else - *uc = GLYPH2UCHAR(*gv); + *uc = REAL_GLYPH(*gv); } } @@ -350,7 +336,7 @@ static int get_next_glyph(struct glyph_break_ctxt* gbctxt, if (gbctxt->sbc_devfont->charset_ops->conv_to_uc32) *uc = gbctxt->sbc_devfont->charset_ops->conv_to_uc32(*gv); else - *uc = GLYPH2UCHAR(*gv); + *uc = REAL_GLYPH(*gv); } } @@ -1381,10 +1367,8 @@ static void dbg_dump_gbctxt(struct glyph_break_ctxt* gbctxt, static inline Glyph32 uc2gv(Glyph32 gv, Uchar32 uc) { - if (IS_MBC_GLYPH(gv)) - return SET_MBC_GLYPH(uc); - - return uc; + Glyph32 dfi_mask = (gv & GLYPH_DEVFONT_INDEX_MASK); + return ((Glyph32)uc) | dfi_mask; } static inline BOOL is_glyph_letter(Uchar32 uc, @@ -1405,6 +1389,27 @@ static inline BOOL is_glyph_letter(Uchar32 uc, return FALSE; } +static int gbctxt_init_spaces(struct glyph_break_ctxt* gbctxt, int size) +{ + // pre-allocate buffers + gbctxt->len_buff = size; + if (gbctxt->len_buff < MIN_LEN_GLYPHS) + gbctxt->len_buff = MIN_LEN_GLYPHS; + + gbctxt->gvs = (Glyph32*)malloc(sizeof(Glyph32) * gbctxt->len_buff); + if (gbctxt->need_ucs) + gbctxt->ucs = (Uchar32*)malloc(sizeof(Uchar32) * gbctxt->len_buff); + gbctxt->bts = (Uint8*)malloc(sizeof(Uint8) * gbctxt->len_buff); + gbctxt->bos = (Uint16*)malloc(sizeof(Uint16) * gbctxt->len_buff); + gbctxt->ods = (Uint8*)malloc(sizeof(Uint8) * gbctxt->len_buff); + if (gbctxt->gvs == NULL || gbctxt->bts == NULL || + gbctxt->bos == NULL || gbctxt->ods == NULL || + (gbctxt->need_ucs && gbctxt->ucs == NULL)) + return 0; + + return gbctxt->len_buff; +} + static int gbctxt_push_back(struct glyph_break_ctxt* gbctxt, Glyph32 gv, Uchar32 uc, UCharBreakType bt, Uint16 lbo) { @@ -1413,6 +1418,9 @@ static int gbctxt_push_back(struct glyph_break_ctxt* gbctxt, gbctxt->len_buff += INC_LEN_GLYPHS; gbctxt->gvs = (Glyph32*)realloc(gbctxt->gvs, sizeof(Glyph32) * gbctxt->len_buff); + if (gbctxt->need_ucs) + gbctxt->ucs = (Uchar32*)realloc(gbctxt->ucs, + sizeof(Uchar32) * gbctxt->len_buff); gbctxt->bts = (Uint8*)realloc(gbctxt->bts, sizeof(Uint8) * gbctxt->len_buff); gbctxt->bos = (Uint16*)realloc(gbctxt->bos, @@ -1420,8 +1428,9 @@ static int gbctxt_push_back(struct glyph_break_ctxt* gbctxt, gbctxt->ods = (Uint8*)realloc(gbctxt->ods, sizeof(Uint8) * gbctxt->len_buff); - if (gbctxt->gvs == NULL || gbctxt->bts == NULL - || gbctxt->bos == NULL || gbctxt->ods == NULL) + if (gbctxt->gvs == NULL || gbctxt->bts == NULL || + gbctxt->bos == NULL || gbctxt->ods == NULL || + (gbctxt->need_ucs && gbctxt->ucs == NULL)) return 0; } @@ -1437,6 +1446,8 @@ static int gbctxt_push_back(struct glyph_break_ctxt* gbctxt, // set the after line break opportunity gbctxt->gvs[gbctxt->n - 1] = gv; + if (gbctxt->need_ucs) + gbctxt->ucs[gbctxt->n - 1] = uc; gbctxt->bts[gbctxt->n - 1] = bt; gbctxt->bos[gbctxt->n] = lbo; if (lbo == BOV_UNKNOWN) @@ -2175,7 +2186,7 @@ static int check_subsequent_ri(struct glyph_break_ctxt* gbctxt, int GUIAPI GetGlyphsAndBreaks(LOGFONT* logfont, const char* mstr, int mstr_len, LanguageCode content_language, UCharScriptType writing_system, Uint8 wsr, Uint8 ctr, Uint8 wbr, Uint8 lbp, - Glyph32** glyphs, Uint16** break_oppos, Uint8** break_classes, + Glyph32** glyphs, Uchar32** uchars, Uint16** break_oppos, int* nr_glyphs) { struct glyph_break_ctxt gbctxt; @@ -2190,13 +2201,17 @@ int GUIAPI GetGlyphsAndBreaks(LOGFONT* logfont, const char* mstr, int mstr_len, if (wsr == WSR_NORMAL || wsr == WSR_NOWRAP) col_nl = TRUE; + memset(&gbctxt, 0, sizeof(gbctxt)); gbctxt.mbc_devfont = logfont->mbc_devfont; gbctxt.sbc_devfont = logfont->sbc_devfont; +#if 0 gbctxt.gvs = NULL; + gbctxt.ucs = NULL; gbctxt.bts = NULL; gbctxt.bos = NULL; gbctxt.len_buff = 0; gbctxt.n = 0; +#endif gbctxt.base_bt = UCHAR_BREAK_UNSET; gbctxt.cl = content_language; gbctxt.ws = writing_system; @@ -2205,16 +2220,18 @@ int GUIAPI GetGlyphsAndBreaks(LOGFONT* logfont, const char* mstr, int mstr_len, gbctxt.wbr = wbr; gbctxt.lbp = lbp; +#if 0 gbctxt.prev_uc = 0; gbctxt.base_uc = 0; gbctxt.last_word_letter = 0; +#endif // NOTE: the index 0 of break_oppos is the break opportunity // before the first glyph. gbctxt.last_stc_start = -1; gbctxt.last_non_space = -1; - gbctxt.prev_wb_index = 0; - gbctxt.prev_sb_index = 0; + gbctxt.prev_wb_index = -1; + gbctxt.prev_sb_index = -1; gbctxt.prev_gbt = GB_Other; gbctxt.prev_gbt = GB_Other; @@ -2223,17 +2240,21 @@ int GUIAPI GetGlyphsAndBreaks(LOGFONT* logfont, const char* mstr, int mstr_len, gbctxt.prev_jamo = NO_JAMO; gbctxt.curr_wt = WordNone; +#if 0 gbctxt.makes_hangul_syllable = 0; gbctxt.is_grapheme_boundary = 0; gbctxt.is_word_boundary = 0; gbctxt.is_sentence_boundary = 0; gbctxt.met_extended_pictographic = 0; gbctxt.is_extended_pictographic = 0; +#endif *glyphs = NULL; + if (uchars) { + *uchars = NULL; + gbctxt.need_ucs = 1; + } *break_oppos = NULL; - if (break_classes) - *break_classes = NULL; *nr_glyphs = 0; if (mstr_len == 0) @@ -3166,20 +3187,21 @@ next_glyph: *glyphs = gbctxt.gvs; *break_oppos = gbctxt.bos; - if (break_classes) - *break_classes = gbctxt.bts; + if (uchars) + *uchars = gbctxt.ucs; *nr_glyphs = gbctxt.n - 1; } else goto error; - if (break_classes == NULL && gbctxt.bts) free(gbctxt.bts); + if (uchars == NULL && gbctxt.ucs) free(gbctxt.ucs); if (gbctxt.ods) free(gbctxt.ods); return cosumed; error: if (gbctxt.gvs) free(gbctxt.gvs); + if (gbctxt.ucs) free(gbctxt.ucs); if (gbctxt.bts) free(gbctxt.bts); if (gbctxt.bos) free(gbctxt.bos); if (gbctxt.ods) free(gbctxt.ods); @@ -3951,7 +3973,7 @@ static void init_glyph_info(MYGLYPHARGS* args, int i, if (devfont->charset_ops->conv_to_uc32) gi->uc = devfont->charset_ops->conv_to_uc32(args->gvs[i]); else - gi->uc = GLYPH2UCHAR(args->gvs[i]); + gi->uc = REAL_GLYPH(args->gvs[i]); gi->gc = UCharGetCategory(gi->uc); gi->ignored = 0; gi->hanged = GLYPH_HANGED_NONE; @@ -4403,6 +4425,19 @@ error: return 0; } +Uchar32 GUIAPI Glyph2UChar(LOGFONT* logfont, Glyph32 gv) +{ + Uchar32 uc; + DEVFONT* devfont = SELECT_DEVFONT(logfont, gv); + + if (devfont->charset_ops->conv_to_uc32) + uc = devfont->charset_ops->conv_to_uc32(gv); + else + uc = REAL_GLYPH(gv); + + return uc; +} + #endif /* _MGCHARSET_UNICODE */ int GUIAPI DrawGlyphStringEx(HDC hdc,