diff --git a/include/gdi.h b/include/gdi.h index b1333553..f1a0d205 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -5802,91 +5802,87 @@ typedef Uint16 Uchar16; typedef Uint32 Uchar32; /** - * \defgroup char_types Character types + * \defgroup achar_types Abstract Character Types * * MiniGUI uses a Uint32 value to store the type information of a character. * - * MiniGUI uses the lower 16-bit integer for the type of a multi-byte character. - * The definition macros have MCHAR_TYPE as the prefix. + * MiniGUI uses the lower 16-bit integer for the basic type of + * an abstract character. The definition macros have ACHAR_BASIC_ + * as the prefix. * * For a UNICODE character, MiniGUI uses the high 16-bit for the - * basic UNICODE character classifications and the possible line break - * classifications. The low byte for the basic type, and the high byte for - * the break type. + * general UNICODE character categories and the possible line break + * classifications. The low byte for the general category, and + * the high byte for the break class. * * @{ */ -/** - * \def CHARTYPE_MCHAR_MASK - * \brief The bits mask of glyph type for multi-byte character - */ -#define CHARTYPE_MCHAR_MASK 0x0000FFFF +#define ACHARTYPE_BASIC_MASK 0x0000FFFF +#define ACHARTYPE_CATEGORY_MASK 0x00FF0000 +#define ACHARTYPE_BREAK_MASK 0xFF000000 /** - * \def EXTRACT_MCHAR_TYPE(t) - * \brief Extracts multi-byte character type + * \def ACHARTYPE_EXTRACT_BASIC + * \brief Extract the basic type from an abstract character type. */ -#define EXTRACT_MCHAR_TYPE(t) ((t) & CHARTYPE_MCHAR_MASK) +#define ACHARTYPE_EXTRACT_BASIC(t) \ + (((t) & ACHARTYPE_BASIC_MASK)) /** - * \def CHARTYPE_BASIC_MASK - * \brief The bits mask of glyph type for unicode charachter + * \def ACHARTYPE_EXTRACT_CATEGORY + * \brief Extract the UNICODE general category from an abstract character type. */ -#define CHARTYPE_BASIC_MASK 0x00FF0000 +#define ACHARTYPE_EXTRACT_CATEGORY(t) \ + (((t) & ACHARTYPE_CATEGORY_MASK) >> 16) /** - * \def EXTRACT_BASIC_TYPE(t) - * \brief Extracts the basic UNICODE character type + * \def ACHARTYPE_EXTRACT_BREAK + * \brief Extract the UNICODE break class from an abstract character type. */ -#define EXTRACT_BASIC_TYPE(t) (((t) & CHARTYPE_BASIC_MASK) >> 16) +#define ACHARTYPE_EXTRACT_BREAK(t) \ + (((t) & ACHARTYPE_BREAK_MASK) >> 24) /** - * \def CHARTYPE_BREAK_MASK - * \brief The bits mask of break type for UNICODE charachter + * \def ACHARTYPE_UNKNOWN + * \breif Unknown abstract character type. */ -#define CHARTYPE_BREAK_MASK 0xFF000000 +#define ACHARTYPE_UNKNOWN 0 -/** - * \def EXTRACT_BREAK_TYPE(t) - * \brief Extracts the break type of a UNICODE character - */ -#define EXTRACT_BREAK_TYPE(t) (((t) & CHARTYPE_BREAK_MASK) >> 24) +#define ACHAR_BASIC_NOSPACING_MARK 0x0001 +#define ACHAR_BASIC_ABOVE_MARK 0x0002 +#define ACHAR_BASIC_BELLOW_MARK 0x0004 -#define MCHAR_TYPE_NOSPACING_MARK 0x0001 -#define MCHAR_TYPE_ABOVE_MARK 0x0002 -#define MCHAR_TYPE_BELLOW_MARK 0x0004 - -#define MCHAR_TYPE_UNKNOWN 0x0000 -#define MCHAR_TYPE_NUL (0x0000 | MCHAR_TYPE_NOSPACING_MARK) +#define ACHAR_BASIC_UNKNOWN 0x0000 +#define ACHAR_BASIC_NUL (0x0000 | ACHAR_BASIC_NOSPACING_MARK) /** Control character (group 1) */ -#define MCHAR_TYPE_CTRL1 0x0100 +#define ACHAR_BASIC_CTRL1 0x0100 /** Bell */ -#define MCHAR_TYPE_BEL 0x0200 +#define ACHAR_BASIC_BEL 0x0200 /** Backspace */ -#define MCHAR_TYPE_BS 0x0300 +#define ACHAR_BASIC_BS 0x0300 /** Horinzontal Tab */ -#define MCHAR_TYPE_HT 0x0400 +#define ACHAR_BASIC_HT 0x0400 /** Line Feed */ -#define MCHAR_TYPE_LF 0x0500 +#define ACHAR_BASIC_LF 0x0500 /** Vertical Tab */ -#define MCHAR_TYPE_VT 0x0600 +#define ACHAR_BASIC_VT 0x0600 /** Form Feed */ -#define MCHAR_TYPE_FF 0x0700 +#define ACHAR_BASIC_FF 0x0700 /** Carriage Return */ -#define MCHAR_TYPE_CR 0x0800 +#define ACHAR_BASIC_CR 0x0800 /** Control character (group 2) */ -#define MCHAR_TYPE_CTRL2 0x0900 +#define ACHAR_BASIC_CTRL2 0x0900 /** Space */ -#define MCHAR_TYPE_SPACE 0x0A00 +#define ACHAR_BASIC_SPACE 0x0A00 /** Zero width character */ -#define MCHAR_TYPE_ZEROWIDTH 0x0B00 -#define MCHAR_TYPE_GENERIC 0x0C00 +#define ACHAR_BASIC_ZEROWIDTH 0x0B00 +#define ACHAR_BASIC_GENERIC 0x0C00 -#define MCHAR_TYPE_LIGATURE (0x0D00 | MCHAR_TYPE_NOSPACING_MARK) -#define MCHAR_TYPE_VOWEL (0x0E00 | MCHAR_TYPE_NOSPACING_MARK) -#define MCHAR_TYPE_VOWEL_ABOVE (MCHAR_TYPE_VOWEL | MCHAR_TYPE_ABOVE_MARK) -#define MCHAR_TYPE_VOWEL_BELLOW (MCHAR_TYPE_VOWEL | MCHAR_TYPE_BELLOW_MARK) +#define ACHAR_BASIC_LIGATURE (0x0D00 | ACHAR_BASIC_NOSPACING_MARK) +#define ACHAR_BASIC_VOWEL (0x0E00 | ACHAR_BASIC_NOSPACING_MARK) +#define ACHAR_BASIC_VOWEL_ABOVE (ACHAR_BASIC_VOWEL | ACHAR_BASIC_ABOVE_MARK) +#define ACHAR_BASIC_VOWEL_BELLOW (ACHAR_BASIC_VOWEL | ACHAR_BASIC_BELLOW_MARK) /** * UCharGeneralCategory: General category of a UNICODE character. @@ -6404,7 +6400,7 @@ typedef enum { UCHAR_SCRIPT_SOGDIAN, /* Sogd */ } UCharScriptType; - /** @} end of char_types */ + /** @} end of achar_types */ struct _FONTOPS; struct _CHARSETOPS; @@ -9650,16 +9646,30 @@ MG_EXPORT BOOL GUIAPI GetMirrorAChar (LOGFONT* logfont, Achar32 chv, /** * \fn Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv) - * \brief Retrieve the basic type and break type of an abtract character. + * \brief Retrieve the basic type, the general cateory of Unicode, and + * the break class of Unicode of an abtract character. * - * This function retrieves the basic type and break type of a glyph. + * This function retrieves the basic type, the general category defined by + * Unicode terms, and the break class defined by Unicode of an abstract + * character. * * \param logfont The logical font. - * \param glyph_value The glyph value. + * \param chv An Achar32 value. * - * \return The type of the specified glyph. + * \return The type of the specified Achar32 value. You can use the following + * macros to extract the basic type, the break type, and the bidi type + * respectively: + * - ACHARTYPE_EXTRACT_BASIC(type)\n + * - ACHARTYPE_EXTRACT_CATEGORY(type)\n + * - ACHARTYPE_EXTRACT_BREAK(type)\n * - * \sa GetACharInfo, GetACharBIDIType, char_types + * \note The basic type is defined by MiniGUI for basic rendering for some + * complex shaping glyphs. + * + * \note The general category and the break class are only available when + * the support for Unicode is enabled. + * + * \sa GetACharBIDIType, achar_types */ MG_EXPORT Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv); @@ -9926,7 +9936,7 @@ MG_EXPORT Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv); (BIDI_IS_NUMBER(p) ? BIDI_TYPE_RTL : (p)) /** - * \fn Uint32 GUIAPI GetACharBIDIType (LOGFONT* logfont, Achar32 chv) + * \fn Uint16 GUIAPI GetACharBIDIType (LOGFONT* logfont, Achar32 chv) * \brief Retrieve the BIDI type of an abstract character. * * This function retrieves the BIDI type of an abstract character. @@ -9936,9 +9946,9 @@ MG_EXPORT Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv); * * \return The BIDI type of the Achar32; BIDI_TYPE_INVALID on failure. * - * \sa GetACharInfo, GetACharType + * \sa GetACharType */ -MG_EXPORT Uint32 GUIAPI GetACharBIDIType (LOGFONT* log_font, Achar32 chv); +MG_EXPORT Uint16 GUIAPI GetACharBIDIType (LOGFONT* log_font, Achar32 chv); /** * \var typedef struct _ACHARMAPINFO ACHARMAPINFO diff --git a/src/font/charset-arabic.c b/src/font/charset-arabic.c index e4700cf4..89449de3 100644 --- a/src/font/charset-arabic.c +++ b/src/font/charset-arabic.c @@ -458,10 +458,10 @@ static int iso8859_6_len_first_char (const unsigned char* mstr, int len) static unsigned int iso8859_6_char_type (Achar32 chv) { - unsigned int ch_type = MCHAR_TYPE_UNKNOWN; + unsigned int ch_type = ACHAR_BASIC_UNKNOWN; if (is_arabic_char_vowel (chv)) { /* is vowel */ - ch_type = MCHAR_TYPE_VOWEL; + ch_type = ACHAR_BASIC_VOWEL; } else{ ch_type = sb_char_type (chv); diff --git a/src/font/charset.c b/src/font/charset.c index 070f6ede..ba8edf26 100644 --- a/src/font/charset.c +++ b/src/font/charset.c @@ -65,45 +65,45 @@ static Achar32 sb_get_char_value (const unsigned char* pre_mchar, int pre_len, static unsigned int sb_char_type (Achar32 chv) { - unsigned int ch_type = MCHAR_TYPE_UNKNOWN; + unsigned int ch_type = ACHAR_BASIC_UNKNOWN; switch (chv) { case '\0': - ch_type = MCHAR_TYPE_NUL; + ch_type = ACHAR_BASIC_NUL; break; case '\a': - ch_type = MCHAR_TYPE_BEL; + ch_type = ACHAR_BASIC_BEL; break; case '\b': - ch_type = MCHAR_TYPE_BS; + ch_type = ACHAR_BASIC_BS; break; case '\t': - ch_type = MCHAR_TYPE_HT; + ch_type = ACHAR_BASIC_HT; break; case '\n': - ch_type = MCHAR_TYPE_LF; + ch_type = ACHAR_BASIC_LF; break; case '\v': - ch_type = MCHAR_TYPE_VT; + ch_type = ACHAR_BASIC_VT; break; case '\f': - ch_type = MCHAR_TYPE_FF; + ch_type = ACHAR_BASIC_FF; break; case '\r': - ch_type = MCHAR_TYPE_CR; + ch_type = ACHAR_BASIC_CR; break; case ' ': - ch_type = MCHAR_TYPE_SPACE; + ch_type = ACHAR_BASIC_SPACE; break; } - if (ch_type == MCHAR_TYPE_UNKNOWN) { + if (ch_type == ACHAR_BASIC_UNKNOWN) { if (chv < '\a') - ch_type = MCHAR_TYPE_CTRL1; + ch_type = ACHAR_BASIC_CTRL1; else if (chv < ' ') - ch_type = MCHAR_TYPE_CTRL2; + ch_type = ACHAR_BASIC_CTRL2; else - ch_type = MCHAR_TYPE_GENERIC; + ch_type = ACHAR_BASIC_GENERIC; } return ch_type; @@ -1972,7 +1972,7 @@ static CHARSETOPS CharsetOps_iso8859_16 = { static unsigned int mb_char_type (Achar32 chv) { /* TODO: get the subtype of the char */ - return MCHAR_TYPE_GENERIC; + return ACHAR_BASIC_GENERIC; } static int db_nr_chars_in_str (const unsigned char* mstr, int mstrlen) @@ -3540,7 +3540,7 @@ static Achar32 utf8_get_char_value (const unsigned char* pre_mchar, int pre_len, static unsigned int unicode_char_type (Achar32 chv) { - unsigned int mchar_type = MCHAR_TYPE_UNKNOWN; + unsigned int mchar_type = ACHAR_BASIC_UNKNOWN; unsigned int basic_type = 0, break_type = 0; chv = REAL_ACHAR(chv); @@ -3550,18 +3550,18 @@ static unsigned int unicode_char_type (Achar32 chv) if (chv < 0x80) mchar_type = sb_char_type(chv); else if (break_type == UCHAR_BREAK_CARRIAGE_RETURN) - mchar_type = MCHAR_TYPE_CR; + mchar_type = ACHAR_BASIC_CR; else if (break_type == UCHAR_BREAK_LINE_FEED) - mchar_type = MCHAR_TYPE_LF; + mchar_type = ACHAR_BASIC_LF; else if (break_type == UCHAR_BREAK_NEXT_LINE) - mchar_type = MCHAR_TYPE_LF; + mchar_type = ACHAR_BASIC_LF; else if (break_type == UCHAR_BREAK_SPACE) - mchar_type = MCHAR_TYPE_SPACE; + mchar_type = ACHAR_BASIC_SPACE; else if (chv != 0x00AD && ISZEROWIDTHTYPE (basic_type)) - mchar_type = MCHAR_TYPE_ZEROWIDTH; + mchar_type = ACHAR_BASIC_ZEROWIDTH; else if ((chv >= 0x1160 && chv < 0x1200) || chv == 0x200B) - mchar_type = MCHAR_TYPE_ZEROWIDTH; + mchar_type = ACHAR_BASIC_ZEROWIDTH; return (break_type << 24) | (basic_type << 16) | mchar_type; } diff --git a/src/include/devfont.h b/src/include/devfont.h index 69f810c1..dd19d078 100644 --- a/src/include/devfont.h +++ b/src/include/devfont.h @@ -147,12 +147,12 @@ void dbg_dumpDevFonts (void); static inline BOOL check_zero_width(unsigned int t) { - return (t & CHARTYPE_MCHAR_MASK) == MCHAR_TYPE_ZEROWIDTH; + return (t & ACHARTYPE_BASIC_MASK) == ACHAR_BASIC_ZEROWIDTH; } static inline BOOL check_vowel(unsigned int t) { - return ((t & CHARTYPE_MCHAR_MASK) == MCHAR_TYPE_VOWEL); + return ((t & ACHARTYPE_BASIC_MASK) == ACHAR_BASIC_VOWEL); } static inline long get_file_size (const char* filename) diff --git a/src/newgdi/achar.c b/src/newgdi/achar.c index e8edeba9..bd048839 100644 --- a/src/newgdi/achar.c +++ b/src/newgdi/achar.c @@ -134,19 +134,52 @@ BOOL GUIAPI GetMirrorAChar (LOGFONT* logfont, Achar32 chv, Achar32* mirrored) Uint32 GUIAPI GetACharType (LOGFONT* logfont, Achar32 chv) { + Uint32 t = ACHARTYPE_UNKNOWN; DEVFONT* devfont = SELECT_DEVFONT_BY_ACHAR(logfont, chv); - return devfont->charset_ops->char_type (REAL_ACHAR (chv)); + + if (devfont) { + t = devfont->charset_ops->char_type (REAL_ACHAR (chv)); + +#ifdef _MGCHARSET_UNICODE + // get general category and break class from Unicode + if (devfont->charset_ops->conv_to_uc32) { + Uchar32 uc; + Uint32 gc, bt; + + uc = devfont->charset_ops->conv_to_uc32(chv); + gc = UCharGetCategory(uc); + bt = UCharGetBreakType(uc); + t = t | (gc << 16) | (bt << 24); + } +#endif /* _MGCHARSET_UNICODE */ + } + + return t; } -Uint32 GUIAPI GetACharBIDIType (LOGFONT* log_font, Achar32 chv) +Uint16 GUIAPI GetACharBIDIType (LOGFONT* log_font, Achar32 chv) { + Uint16 t = BIDI_TYPE_INVALID; DEVFONT* devfont = SELECT_DEVFONT_BY_ACHAR(log_font, chv); - if (devfont == NULL || - devfont->charset_ops->bidi_char_type == NULL) - return BIDI_TYPE_INVALID; + if (devfont) { + if (devfont->charset_ops->bidi_char_type) + t = devfont->charset_ops->bidi_char_type(REAL_ACHAR(chv)); + else { +#ifdef _MGCHARSET_UNICODE + // get Bidi type from Unicode + if (devfont->charset_ops->conv_to_uc32) { + Uchar32 uc; + uc = devfont->charset_ops->conv_to_uc32(chv); + t = UCharGetBIDIType(uc); + } +#else + t = BIDI_TYPE_INVALID; +#endif + } + } - return devfont->charset_ops->bidi_char_type (REAL_ACHAR (chv)); + return t; } #ifdef _MGCHARSET_UNICODE diff --git a/src/newgdi/bidi.c b/src/newgdi/bidi.c index 433cb6c7..3ff41c16 100644 --- a/src/newgdi/bidi.c +++ b/src/newgdi/bidi.c @@ -83,7 +83,7 @@ static Achar32* _gdi_get_achars_string(PDC pdc, const unsigned char* text, logical_achars[i++] = SET_MBCHV(chv); char_type = (*mbc_devfont->charset_ops->char_type) (chv); - if (!(char_type & MCHAR_TYPE_NOSPACING_MARK)){ + if (!(char_type & ACHAR_BASIC_NOSPACING_MARK)){ prev_mchar = text; prev_len = len_cur_char; } @@ -654,7 +654,7 @@ _gdi_get_achars_string_charbreak(PDC pdc, const unsigned char* text, char_type = (*mbc_devfont->charset_ops->char_type) (chv); - if (!(char_type & MCHAR_TYPE_NOSPACING_MARK)){ + if (!(char_type & ACHAR_BASIC_NOSPACING_MARK)){ prev_mchar = text; } else{ diff --git a/src/newgdi/drawtext.c b/src/newgdi/drawtext.c index 16774b0f..02cffbbd 100644 --- a/src/newgdi/drawtext.c +++ b/src/newgdi/drawtext.c @@ -107,13 +107,13 @@ static BOOL cb_drawtextex2 (void* context, Glyph32 glyph_value, BBOX bbox; int bkmode; - switch (char_type & CHARTYPE_MCHAR_MASK) { - case MCHAR_TYPE_ZEROWIDTH: - case MCHAR_TYPE_CR: + switch (char_type & ACHARTYPE_BASIC_MASK) { + case ACHAR_BASIC_ZEROWIDTH: + case ACHAR_BASIC_CR: adv_x = adv_y = 0; break; - case MCHAR_TYPE_HT: + case ACHAR_BASIC_HT: if(!(ctxt->nFormat & DT_EXPANDTABS)) return TRUE; _gdi_start_new_line (ctxt->pdc); @@ -131,7 +131,7 @@ static BOOL cb_drawtextex2 (void* context, Glyph32 glyph_value, } break; - case MCHAR_TYPE_VOWEL: + case ACHAR_BASIC_VOWEL: if (!ctxt->only_extent) { bkmode = ctxt->pdc->bkmode; //ctxt->pdc->bkmode = BM_TRANSPARENT; diff --git a/src/newgdi/tabbedtextout.c b/src/newgdi/tabbedtextout.c index 0915de73..37f2b833 100644 --- a/src/newgdi/tabbedtextout.c +++ b/src/newgdi/tabbedtextout.c @@ -123,12 +123,12 @@ static BOOL cb_tabbedtextout (void* context, Glyph32 glyph_value, BBOX bbox; int bkmode = ctxt->pdc->bkmode; - switch (char_type & CHARTYPE_MCHAR_MASK) { - case MCHAR_TYPE_ZEROWIDTH: + switch (char_type & ACHARTYPE_BASIC_MASK) { + case ACHAR_BASIC_ZEROWIDTH: adv_x = adv_y = 0; break; - case MCHAR_TYPE_HT: + case ACHAR_BASIC_HT: _gdi_start_new_line (ctxt->pdc); if (ctxt->only_extent) { ctxt->advance += _gdi_get_null_glyph_advance (ctxt->pdc, @@ -144,7 +144,7 @@ static BOOL cb_tabbedtextout (void* context, Glyph32 glyph_value, } break; - case MCHAR_TYPE_VOWEL: + case ACHAR_BASIC_VOWEL: if (!ctxt->only_extent) { //ctxt->pdc->bkmode = BM_TRANSPARENT; _gdi_draw_one_glyph (ctxt->pdc, glyph_value, @@ -202,12 +202,12 @@ static BOOL cb_tabbedtextoutex (void* context, Glyph32 glyph_value, int adv_x, adv_y; int tab_pos = ctxt->nTabOrig; - switch (char_type & CHARTYPE_MCHAR_MASK) { - case MCHAR_TYPE_ZEROWIDTH: + switch (char_type & ACHARTYPE_BASIC_MASK) { + case ACHAR_BASIC_ZEROWIDTH: adv_x = adv_y = 0; break; - case MCHAR_TYPE_HT: + case ACHAR_BASIC_HT: _gdi_start_new_line (ctxt->pdc); /* use some tabs to move current x. */ if (ctxt->advance >= tab_pos) { @@ -225,7 +225,7 @@ static BOOL cb_tabbedtextoutex (void* context, Glyph32 glyph_value, ctxt->nTabOrig = tab_pos; break; - case MCHAR_TYPE_VOWEL: + case ACHAR_BASIC_VOWEL: _gdi_draw_one_glyph (ctxt->pdc, glyph_value, (ctxt->pdc->ta_flags & TA_X_MASK) != TA_RIGHT, ctxt->x, ctxt->y, &adv_x, &adv_y); @@ -589,20 +589,20 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text, glyph_value = SET_GLYPH_DFI(glyph_value, dfi); } - switch (char_type & CHARTYPE_MCHAR_MASK) { - case MCHAR_TYPE_ZEROWIDTH: - case MCHAR_TYPE_VOWEL: + switch (char_type & ACHARTYPE_BASIC_MASK) { + case ACHAR_BASIC_ZEROWIDTH: + case ACHAR_BASIC_VOWEL: break; - case MCHAR_TYPE_LF: + case ACHAR_BASIC_LF: size->cy += line_height; - case MCHAR_TYPE_CR: + case ACHAR_BASIC_CR: if (last_line_width > size->cx) size->cx = last_line_width; last_line_width = 0; _gdi_start_new_line (pdc); break; - case MCHAR_TYPE_HT: + case ACHAR_BASIC_HT: last_line_width += tab_width; _gdi_start_new_line (pdc); break;