mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-25 02:33:59 +08:00
part implementation of GetGlyphsByRules
This commit is contained in:
+104
-97
@@ -5974,18 +5974,18 @@ typedef enum {
|
||||
* @UCHAR_BREAK_HANGUL_T_JAMO: Hangul T Jamo (JT)
|
||||
* @UCHAR_BREAK_HANGUL_LV_SYLLABLE: Hangul LV Syllable (H2)
|
||||
* @UCHAR_BREAK_HANGUL_LVT_SYLLABLE: Hangul LVT Syllable (H3)
|
||||
* @UCHAR_BREAK_CLOSE_PARANTHESIS: Closing Parenthesis (CP). Since 2.28
|
||||
* @UCHAR_BREAK_CONDITIONAL_JAPANESE_STARTER: Conditional Japanese Starter (CJ). Since: 2.32
|
||||
* @UCHAR_BREAK_HEBREW_LETTER: Hebrew Letter (HL). Since: 2.32
|
||||
* @UCHAR_BREAK_REGIONAL_INDICATOR: Regional Indicator (RI). Since: 2.36
|
||||
* @UCHAR_BREAK_EMOJI_BASE: Emoji Base (EB). Since: 2.50
|
||||
* @UCHAR_BREAK_EMOJI_MODIFIER: Emoji Modifier (EM). Since: 2.50
|
||||
* @UCHAR_BREAK_ZERO_WIDTH_JOINER: Zero Width Joiner (ZWJ). Since: 2.50
|
||||
* @UCHAR_BREAK_CLOSE_PARANTHESIS: Closing Parenthesis (CP).
|
||||
* @UCHAR_BREAK_CONDITIONAL_JAPANESE_STARTER: Conditional Japanese Starter (CJ).
|
||||
* @UCHAR_BREAK_HEBREW_LETTER: Hebrew Letter (HL).
|
||||
* @UCHAR_BREAK_REGIONAL_INDICATOR: Regional Indicator (RI).
|
||||
* @UCHAR_BREAK_EMOJI_BASE: Emoji Base (EB).
|
||||
* @UCHAR_BREAK_EMOJI_MODIFIER: Emoji Modifier (EM).
|
||||
* @UCHAR_BREAK_ZERO_WIDTH_JOINER: Zero Width Joiner (ZWJ).
|
||||
*
|
||||
* These are the possible line break classifications.
|
||||
*
|
||||
* Since new unicode versions may add new types here, applications should be ready
|
||||
* to handle unknown values. They may be regarded as %UCHAR_BREAK_UNKNOWN.
|
||||
* Since new unicode versions may add new types here, applications should be
|
||||
* ready to handle unknown values. They may be regarded as %UCHAR_BREAK_UNKNOWN.
|
||||
*
|
||||
* See [Unicode Line Breaking Algorithm](http://www.unicode.org/unicode/reports/tr14/).
|
||||
*/
|
||||
@@ -6112,94 +6112,88 @@ typedef enum {
|
||||
* @UCHAR_SCRIPT_PHOENICIAN: Phoenician
|
||||
* @UCHAR_SCRIPT_PHAGS_PA: Phags-pa
|
||||
* @UCHAR_SCRIPT_NKO: N'Ko
|
||||
* @UCHAR_SCRIPT_KAYAH_LI: Kayah Li. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_LEPCHA: Lepcha. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_REJANG: Rejang. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_SUNDANESE: Sundanese. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_SAURASHTRA: Saurashtra. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_CHAM: Cham. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_OL_CHIKI: Ol Chiki. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_VAI: Vai. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_CARIAN: Carian. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_LYCIAN: Lycian. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_LYDIAN: Lydian. Since 2.16.3
|
||||
* @UCHAR_SCRIPT_AVESTAN: Avestan. Since 2.26
|
||||
* @UCHAR_SCRIPT_BAMUM: Bamum. Since 2.26
|
||||
* @UCHAR_SCRIPT_EGYPTIAN_HIEROGLYPHS:
|
||||
* Egyptian Hieroglpyhs. Since 2.26
|
||||
* @UCHAR_SCRIPT_IMPERIAL_ARAMAIC:
|
||||
* Imperial Aramaic. Since 2.26
|
||||
* @UCHAR_SCRIPT_INSCRIPTIONAL_PAHLAVI:
|
||||
* Inscriptional Pahlavi. Since 2.26
|
||||
* @UCHAR_SCRIPT_INSCRIPTIONAL_PARTHIAN:
|
||||
* Inscriptional Parthian. Since 2.26
|
||||
* @UCHAR_SCRIPT_JAVANESE: Javanese. Since 2.26
|
||||
* @UCHAR_SCRIPT_KAITHI: Kaithi. Since 2.26
|
||||
* @UCHAR_SCRIPT_LISU: Lisu. Since 2.26
|
||||
* @UCHAR_SCRIPT_MEETEI_MAYEK:
|
||||
* Meetei Mayek. Since 2.26
|
||||
* @UCHAR_SCRIPT_OLD_SOUTH_ARABIAN:
|
||||
* Old South Arabian. Since 2.26
|
||||
* @UCHAR_SCRIPT_OLD_TURKIC: Old Turkic. Since 2.28
|
||||
* @UCHAR_SCRIPT_SAMARITAN: Samaritan. Since 2.26
|
||||
* @UCHAR_SCRIPT_TAI_THAM: Tai Tham. Since 2.26
|
||||
* @UCHAR_SCRIPT_TAI_VIET: Tai Viet. Since 2.26
|
||||
* @UCHAR_SCRIPT_BATAK: Batak. Since 2.28
|
||||
* @UCHAR_SCRIPT_BRAHMI: Brahmi. Since 2.28
|
||||
* @UCHAR_SCRIPT_MANDAIC: Mandaic. Since 2.28
|
||||
* @UCHAR_SCRIPT_CHAKMA: Chakma. Since: 2.32
|
||||
* @UCHAR_SCRIPT_MEROITIC_CURSIVE: Meroitic Cursive. Since: 2.32
|
||||
* @UCHAR_SCRIPT_MEROITIC_HIEROGLYPHS: Meroitic Hieroglyphs. Since: 2.32
|
||||
* @UCHAR_SCRIPT_MIAO: Miao. Since: 2.32
|
||||
* @UCHAR_SCRIPT_SHARADA: Sharada. Since: 2.32
|
||||
* @UCHAR_SCRIPT_SORA_SOMPENG: Sora Sompeng. Since: 2.32
|
||||
* @UCHAR_SCRIPT_TAKRI: Takri. Since: 2.32
|
||||
* @UCHAR_SCRIPT_BASSA_VAH: Bassa. Since: 2.42
|
||||
* @UCHAR_SCRIPT_CAUCASIAN_ALBANIAN: Caucasian Albanian. Since: 2.42
|
||||
* @UCHAR_SCRIPT_DUPLOYAN: Duployan. Since: 2.42
|
||||
* @UCHAR_SCRIPT_ELBASAN: Elbasan. Since: 2.42
|
||||
* @UCHAR_SCRIPT_GRANTHA: Grantha. Since: 2.42
|
||||
* @UCHAR_SCRIPT_KHOJKI: Kjohki. Since: 2.42
|
||||
* @UCHAR_SCRIPT_KHUDAWADI: Khudawadi, Sindhi. Since: 2.42
|
||||
* @UCHAR_SCRIPT_LINEAR_A: Linear A. Since: 2.42
|
||||
* @UCHAR_SCRIPT_MAHAJANI: Mahajani. Since: 2.42
|
||||
* @UCHAR_SCRIPT_MANICHAEAN: Manichaean. Since: 2.42
|
||||
* @UCHAR_SCRIPT_MENDE_KIKAKUI: Mende Kikakui. Since: 2.42
|
||||
* @UCHAR_SCRIPT_MODI: Modi. Since: 2.42
|
||||
* @UCHAR_SCRIPT_MRO: Mro. Since: 2.42
|
||||
* @UCHAR_SCRIPT_NABATAEAN: Nabataean. Since: 2.42
|
||||
* @UCHAR_SCRIPT_OLD_NORTH_ARABIAN: Old North Arabian. Since: 2.42
|
||||
* @UCHAR_SCRIPT_OLD_PERMIC: Old Permic. Since: 2.42
|
||||
* @UCHAR_SCRIPT_PAHAWH_HMONG: Pahawh Hmong. Since: 2.42
|
||||
* @UCHAR_SCRIPT_PALMYRENE: Palmyrene. Since: 2.42
|
||||
* @UCHAR_SCRIPT_PAU_CIN_HAU: Pau Cin Hau. Since: 2.42
|
||||
* @UCHAR_SCRIPT_PSALTER_PAHLAVI: Psalter Pahlavi. Since: 2.42
|
||||
* @UCHAR_SCRIPT_SIDDHAM: Siddham. Since: 2.42
|
||||
* @UCHAR_SCRIPT_TIRHUTA: Tirhuta. Since: 2.42
|
||||
* @UCHAR_SCRIPT_WARANG_CITI: Warang Citi. Since: 2.42
|
||||
* @UCHAR_SCRIPT_AHOM: Ahom. Since: 2.48
|
||||
* @UCHAR_SCRIPT_ANATOLIAN_HIEROGLYPHS: Anatolian Hieroglyphs. Since: 2.48
|
||||
* @UCHAR_SCRIPT_HATRAN: Hatran. Since: 2.48
|
||||
* @UCHAR_SCRIPT_MULTANI: Multani. Since: 2.48
|
||||
* @UCHAR_SCRIPT_OLD_HUNGARIAN: Old Hungarian. Since: 2.48
|
||||
* @UCHAR_SCRIPT_SIGNWRITING: Signwriting. Since: 2.48
|
||||
* @UCHAR_SCRIPT_ADLAM: Adlam. Since: 2.50
|
||||
* @UCHAR_SCRIPT_BHAIKSUKI: Bhaiksuki. Since: 2.50
|
||||
* @UCHAR_SCRIPT_MARCHEN: Marchen. Since: 2.50
|
||||
* @UCHAR_SCRIPT_NEWA: Newa. Since: 2.50
|
||||
* @UCHAR_SCRIPT_OSAGE: Osage. Since: 2.50
|
||||
* @UCHAR_SCRIPT_TANGUT: Tangut. Since: 2.50
|
||||
* @UCHAR_SCRIPT_MASARAM_GONDI: Masaram Gondi. Since: 2.54
|
||||
* @UCHAR_SCRIPT_NUSHU: Nushu. Since: 2.54
|
||||
* @UCHAR_SCRIPT_SOYOMBO: Soyombo. Since: 2.54
|
||||
* @UCHAR_SCRIPT_ZANABAZAR_SQUARE: Zanabazar Square. Since: 2.54
|
||||
* @UCHAR_SCRIPT_DOGRA: Dogra. Since: 2.58
|
||||
* @UCHAR_SCRIPT_GUNJALA_GONDI: Gunjala Gondi. Since: 2.58
|
||||
* @UCHAR_SCRIPT_HANIFI_ROHINGYA: Hanifi Rohingya. Since: 2.58
|
||||
* @UCHAR_SCRIPT_MAKASAR: Makasar. Since: 2.58
|
||||
* @UCHAR_SCRIPT_MEDEFAIDRIN: Medefaidrin. Since: 2.58
|
||||
* @UCHAR_SCRIPT_OLD_SOGDIAN: Old Sogdian. Since: 2.58
|
||||
* @UCHAR_SCRIPT_SOGDIAN: Sogdian. Since: 2.58
|
||||
* @UCHAR_SCRIPT_KAYAH_LI: Kayah Li.
|
||||
* @UCHAR_SCRIPT_LEPCHA: Lepcha.
|
||||
* @UCHAR_SCRIPT_REJANG: Rejang.
|
||||
* @UCHAR_SCRIPT_SUNDANESE: Sundanese.
|
||||
* @UCHAR_SCRIPT_SAURASHTRA: Saurashtra.
|
||||
* @UCHAR_SCRIPT_CHAM: Cham.
|
||||
* @UCHAR_SCRIPT_OL_CHIKI: Ol Chiki.
|
||||
* @UCHAR_SCRIPT_VAI: Vai.
|
||||
* @UCHAR_SCRIPT_CARIAN: Carian.
|
||||
* @UCHAR_SCRIPT_LYCIAN: Lycian.
|
||||
* @UCHAR_SCRIPT_LYDIAN: Lydian.
|
||||
* @UCHAR_SCRIPT_AVESTAN: Avestan.
|
||||
* @UCHAR_SCRIPT_BAMUM: Bamum.
|
||||
* @UCHAR_SCRIPT_EGYPTIAN_HIEROGLYPHS: Egyptian Hieroglpyhs.
|
||||
* @UCHAR_SCRIPT_IMPERIAL_ARAMAIC: Imperial Aramaic.
|
||||
* @UCHAR_SCRIPT_INSCRIPTIONAL_PAHLAVI: Inscriptional Pahlavi.
|
||||
* @UCHAR_SCRIPT_INSCRIPTIONAL_PARTHIAN: Inscriptional Parthian.
|
||||
* @UCHAR_SCRIPT_JAVANESE: Javanese.
|
||||
* @UCHAR_SCRIPT_KAITHI: Kaithi.
|
||||
* @UCHAR_SCRIPT_LISU: Lisu.
|
||||
* @UCHAR_SCRIPT_MEETEI_MAYEK: Meetei Mayek.
|
||||
* @UCHAR_SCRIPT_OLD_SOUTH_ARABIAN: Old South Arabian.
|
||||
* @UCHAR_SCRIPT_OLD_TURKIC: Old Turkic.
|
||||
* @UCHAR_SCRIPT_SAMARITAN: Samaritan.
|
||||
* @UCHAR_SCRIPT_TAI_THAM: Tai Tham.
|
||||
* @UCHAR_SCRIPT_TAI_VIET: Tai Viet.
|
||||
* @UCHAR_SCRIPT_BATAK: Batak.
|
||||
* @UCHAR_SCRIPT_BRAHMI: Brahmi.
|
||||
* @UCHAR_SCRIPT_MANDAIC: Mandaic.
|
||||
* @UCHAR_SCRIPT_CHAKMA: Chakma.
|
||||
* @UCHAR_SCRIPT_MEROITIC_CURSIVE: Meroitic Cursive.
|
||||
* @UCHAR_SCRIPT_MEROITIC_HIEROGLYPHS: Meroitic Hieroglyphs.
|
||||
* @UCHAR_SCRIPT_MIAO: Miao.
|
||||
* @UCHAR_SCRIPT_SHARADA: Sharada.
|
||||
* @UCHAR_SCRIPT_SORA_SOMPENG: Sora Sompeng.
|
||||
* @UCHAR_SCRIPT_TAKRI: Takri.
|
||||
* @UCHAR_SCRIPT_BASSA_VAH: Bassa.
|
||||
* @UCHAR_SCRIPT_CAUCASIAN_ALBANIAN: Caucasian Albanian.
|
||||
* @UCHAR_SCRIPT_DUPLOYAN: Duployan.
|
||||
* @UCHAR_SCRIPT_ELBASAN: Elbasan.
|
||||
* @UCHAR_SCRIPT_GRANTHA: Grantha.
|
||||
* @UCHAR_SCRIPT_KHOJKI: Kjohki.
|
||||
* @UCHAR_SCRIPT_KHUDAWADI: Khudawadi, Sindhi.
|
||||
* @UCHAR_SCRIPT_LINEAR_A: Linear A.
|
||||
* @UCHAR_SCRIPT_MAHAJANI: Mahajani.
|
||||
* @UCHAR_SCRIPT_MANICHAEAN: Manichaean.
|
||||
* @UCHAR_SCRIPT_MENDE_KIKAKUI: Mende Kikakui.
|
||||
* @UCHAR_SCRIPT_MODI: Modi.
|
||||
* @UCHAR_SCRIPT_MRO: Mro.
|
||||
* @UCHAR_SCRIPT_NABATAEAN: Nabataean.
|
||||
* @UCHAR_SCRIPT_OLD_NORTH_ARABIAN: Old North Arabian.
|
||||
* @UCHAR_SCRIPT_OLD_PERMIC: Old Permic.
|
||||
* @UCHAR_SCRIPT_PAHAWH_HMONG: Pahawh Hmong.
|
||||
* @UCHAR_SCRIPT_PALMYRENE: Palmyrene.
|
||||
* @UCHAR_SCRIPT_PAU_CIN_HAU: Pau Cin Hau.
|
||||
* @UCHAR_SCRIPT_PSALTER_PAHLAVI: Psalter Pahlavi.
|
||||
* @UCHAR_SCRIPT_SIDDHAM: Siddham.
|
||||
* @UCHAR_SCRIPT_TIRHUTA: Tirhuta.
|
||||
* @UCHAR_SCRIPT_WARANG_CITI: Warang Citi.
|
||||
* @UCHAR_SCRIPT_AHOM: Ahom.
|
||||
* @UCHAR_SCRIPT_ANATOLIAN_HIEROGLYPHS: Anatolian Hieroglyphs.
|
||||
* @UCHAR_SCRIPT_HATRAN: Hatran.
|
||||
* @UCHAR_SCRIPT_MULTANI: Multani.
|
||||
* @UCHAR_SCRIPT_OLD_HUNGARIAN: Old Hungarian.
|
||||
* @UCHAR_SCRIPT_SIGNWRITING: Signwriting.
|
||||
* @UCHAR_SCRIPT_ADLAM: Adlam.
|
||||
* @UCHAR_SCRIPT_BHAIKSUKI: Bhaiksuki.
|
||||
* @UCHAR_SCRIPT_MARCHEN: Marchen.
|
||||
* @UCHAR_SCRIPT_NEWA: Newa.
|
||||
* @UCHAR_SCRIPT_OSAGE: Osage.
|
||||
* @UCHAR_SCRIPT_TANGUT: Tangut.
|
||||
* @UCHAR_SCRIPT_MASARAM_GONDI: Masaram Gondi.
|
||||
* @UCHAR_SCRIPT_NUSHU: Nushu.
|
||||
* @UCHAR_SCRIPT_SOYOMBO: Soyombo.
|
||||
* @UCHAR_SCRIPT_ZANABAZAR_SQUARE: Zanabazar Square.
|
||||
* @UCHAR_SCRIPT_DOGRA: Dogra.
|
||||
* @UCHAR_SCRIPT_GUNJALA_GONDI: Gunjala Gondi.
|
||||
* @UCHAR_SCRIPT_HANIFI_ROHINGYA: Hanifi Rohingya.
|
||||
* @UCHAR_SCRIPT_MAKASAR: Makasar.
|
||||
* @UCHAR_SCRIPT_MEDEFAIDRIN: Medefaidrin.
|
||||
* @UCHAR_SCRIPT_OLD_SOGDIAN: Old Sogdian.
|
||||
* @UCHAR_SCRIPT_SOGDIAN: Sogdian.
|
||||
*
|
||||
* This enumeration identifies different writing
|
||||
* systems. The values correspond to the names as defined in the
|
||||
@@ -10360,14 +10354,27 @@ static inline int GUIAPI LanguageCodeFromISO639s1Code (const char* iso639_1)
|
||||
/**
|
||||
* The break opportunity code
|
||||
*/
|
||||
#define BOV_BEFORE_MASK 0xF0
|
||||
#define BOV_AFTER_MASK 0x0F
|
||||
|
||||
#define BOV_BEFORE_NOTALLOWED 0x00
|
||||
#define BOV_BEFORE_MANDATORY 0x10
|
||||
#define BOV_BEFORE_ALLOWED 0x20
|
||||
|
||||
#define BOV_AFTER_NOTALLOWED 0x00
|
||||
#define BOV_AFTER_MANDATORY 0x10
|
||||
#define BOV_AFTER_ALLOWED 0x20
|
||||
|
||||
typedef enum {
|
||||
BOV_UNKNOWN,
|
||||
BOV_MANDATORY_AFTER,
|
||||
BOV_MANDATORY_BEFORE,
|
||||
BOV_ALLOWED_AFTER,
|
||||
BOV_ALLOWED_BEFORE,
|
||||
BOV_ALLOWED_BOTH,
|
||||
BOV_NOT_ALLOWED_AFTER,
|
||||
BOV_NOT_ALLOWED_BEFORE,
|
||||
BOV_NOT_ALLOWED_BOTH,
|
||||
} BreakOpportunityCode;
|
||||
|
||||
/**
|
||||
|
||||
+311
-86
@@ -66,45 +66,45 @@
|
||||
|
||||
#ifdef _MGCHARSET_UNICODE
|
||||
|
||||
#define MIN_LEN_GLYPHS 4
|
||||
#define INC_LEN_GLYPHS 4
|
||||
|
||||
static int get_next_glyph(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
const char* mstr, int mstr_len, Glyph32* g, Uchar32* uc)
|
||||
const char* mstr, int mstr_len, Glyph32* gv, Uchar32* uc)
|
||||
{
|
||||
int mchar_len = 0;
|
||||
int mclen = 0;
|
||||
|
||||
if (mstr_len <= 0)
|
||||
return 0;
|
||||
|
||||
if (mbc_devfont) {
|
||||
mchar_len = mbc_devfont->charset_ops->len_first_char
|
||||
mclen = mbc_devfont->charset_ops->len_first_char
|
||||
((const unsigned char*)mstr, mstr_len);
|
||||
|
||||
if (mchar_len > 0) {
|
||||
*g = mbc_devfont->charset_ops->char_glyph_value
|
||||
(NULL, 0, (Uint8*)mstr, mchar_len);
|
||||
*g = SET_MBC_GLYPH(*g);
|
||||
if (mclen > 0) {
|
||||
*gv = mbc_devfont->charset_ops->char_glyph_value
|
||||
(NULL, 0, (Uint8*)mstr, mclen);
|
||||
*gv = SET_MBC_GLYPH(*gv);
|
||||
|
||||
if (mbc_devfont->charset_ops->conv_to_uc32)
|
||||
*uc = mbc_devfont->charset_ops->conv_to_uc32(*g);
|
||||
*uc = mbc_devfont->charset_ops->conv_to_uc32(*gv);
|
||||
else
|
||||
*uc = GLYPH2UCHAR(*g);
|
||||
*uc = GLYPH2UCHAR(*gv);
|
||||
}
|
||||
}
|
||||
|
||||
if (*g == INV_GLYPH_VALUE) {
|
||||
mchar_len = sbc_devfont->charset_ops->len_first_char
|
||||
if (*gv == INV_GLYPH_VALUE) {
|
||||
mclen = sbc_devfont->charset_ops->len_first_char
|
||||
((const unsigned char*)mstr, mstr_len);
|
||||
|
||||
if (mchar_len > 0) {
|
||||
*g = sbc_devfont->charset_ops->char_glyph_value
|
||||
(NULL, 0, (Uint8*)mstr, mchar_len);
|
||||
if (mclen > 0) {
|
||||
*gv = sbc_devfont->charset_ops->char_glyph_value
|
||||
(NULL, 0, (Uint8*)mstr, mclen);
|
||||
if (sbc_devfont->charset_ops->conv_to_uc32)
|
||||
*uc = sbc_devfont->charset_ops->conv_to_uc32(*g);
|
||||
*uc = sbc_devfont->charset_ops->conv_to_uc32(*gv);
|
||||
else
|
||||
*uc = GLYPH2UCHAR(*g);
|
||||
*uc = GLYPH2UCHAR(*gv);
|
||||
}
|
||||
}
|
||||
|
||||
return mchar_len;
|
||||
return mclen;
|
||||
}
|
||||
|
||||
static UCharBreakType resolve_line_breaking_class(
|
||||
@@ -152,18 +152,18 @@ static int collapse_space(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
int cosumed = 0;
|
||||
|
||||
do {
|
||||
int mchar_len;
|
||||
Glyph32 g;
|
||||
int mclen;
|
||||
Glyph32 gv;
|
||||
Uchar32 uc;
|
||||
|
||||
mchar_len = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
&g, &uc);
|
||||
if (mchar_len == 0)
|
||||
mclen = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
&gv, &uc);
|
||||
if (mclen == 0)
|
||||
break;
|
||||
|
||||
mstr += mchar_len;
|
||||
mstr_len -= mchar_len;
|
||||
cosumed += mchar_len;
|
||||
mstr += mclen;
|
||||
mstr_len -= mclen;
|
||||
cosumed += mclen;
|
||||
|
||||
bt = UCharGetBreak(uc);
|
||||
} while (bt == UCHAR_BREAK_SPACE);
|
||||
@@ -171,17 +171,124 @@ static int collapse_space(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
return cosumed;
|
||||
}
|
||||
|
||||
static int collapse_line_feed(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
const char* mstr, int mstr_len)
|
||||
{
|
||||
int cosumed = 0;
|
||||
int mclen;
|
||||
Glyph32 gv;
|
||||
Uchar32 uc;
|
||||
|
||||
mclen = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
&gv, &uc);
|
||||
if (mclen > 0 && UCharGetBreak(uc) == UCHAR_BREAK_LINE_FEED)
|
||||
cosumed = mclen;
|
||||
|
||||
return cosumed;
|
||||
}
|
||||
|
||||
static BOOL is_next_glyph_zw(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
const char* mstr, int mstr_len)
|
||||
{
|
||||
int mclen;
|
||||
Glyph32 gv;
|
||||
Uchar32 uc;
|
||||
|
||||
mclen = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
&gv, &uc);
|
||||
if (mclen > 0 && UCharGetBreak(uc) == UCHAR_BREAK_ZERO_WIDTH_SPACE)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int is_next_glyph_cm_or_zwj(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
const char* mstr, int mstr_len, Glyph32* gv, Uchar32* uc)
|
||||
{
|
||||
int mclen;
|
||||
|
||||
mclen = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
gv, uc);
|
||||
if (mclen > 0) {
|
||||
UCharBreakType bt = UCharGetBreak(*uc);
|
||||
if (bt == UCHAR_BREAK_COMBINING_MARK
|
||||
|| bt == UCHAR_BREAK_ZERO_WIDTH_JOINER)
|
||||
return mclen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MIN_LEN_GLYPHS 4
|
||||
#define INC_LEN_GLYPHS 4
|
||||
|
||||
struct glyph_break_info {
|
||||
int len_buff;
|
||||
int n;
|
||||
Glyph32* gs;
|
||||
Uint8* bs;
|
||||
};
|
||||
|
||||
static int gbinfo_init(struct glyph_break_info* gbinfo, int size)
|
||||
{
|
||||
// pre-allocate buffers
|
||||
gbinfo->len_buff = size;
|
||||
if (gbinfo->len_buff < MIN_LEN_GLYPHS)
|
||||
gbinfo->len_buff = MIN_LEN_GLYPHS;
|
||||
|
||||
gbinfo->gs = (Glyph32*)malloc(sizeof(Glyph32) * gbinfo->len_buff);
|
||||
gbinfo->bs = (Uint8*)malloc(sizeof(Uint8) * gbinfo->len_buff);
|
||||
if (gbinfo->gs == NULL || gbinfo->bs == NULL)
|
||||
return 0;
|
||||
|
||||
return gbinfo->len_buff;
|
||||
}
|
||||
|
||||
static int gbinfo_push_back(struct glyph_break_info* gbinfo, Glyph32 gv, Uint8 bt)
|
||||
{
|
||||
/* realloc buffers if it needs */
|
||||
if ((gbinfo->n + 2) >= gbinfo->len_buff) {
|
||||
gbinfo->len_buff += INC_LEN_GLYPHS;
|
||||
gbinfo->gs = (Glyph32*)realloc(gbinfo->gs, sizeof(Glyph32) * gbinfo->len_buff);
|
||||
gbinfo->bs = (Uint8*)realloc(gbinfo->bs, sizeof(Uint8) * gbinfo->len_buff);
|
||||
if (gbinfo->gs == NULL || gbinfo->bs == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gbinfo->gs[gbinfo->n] = gv;
|
||||
gbinfo->bs[gbinfo->n] = bt;
|
||||
gbinfo->n++;
|
||||
return gbinfo->n;
|
||||
}
|
||||
|
||||
static int check_subsequent_cm_or_zwj(DEVFONT* mbc_devfont, DEVFONT* sbc_devfont,
|
||||
const char* mstr, int mstr_len, struct glyph_break_info* gbinfo)
|
||||
{
|
||||
int cosumed = 0;
|
||||
int mclen;
|
||||
Glyph32 gv;
|
||||
Uchar32 uc;
|
||||
|
||||
while ((mclen = is_next_glyph_cm_or_zwj(mbc_devfont, sbc_devfont,
|
||||
mstr, mstr_len, &gv, &uc)) > 0) {
|
||||
|
||||
// FIXME: CM/ZWJ should have the same break class as
|
||||
// its base character.
|
||||
gbinfo_push_back(gbinfo, gv, BOV_NOT_ALLOWED_BEFORE);
|
||||
|
||||
cosumed += mclen;
|
||||
}
|
||||
|
||||
return cosumed;
|
||||
}
|
||||
|
||||
int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
LanguageCode content_language, UCharScriptType writing_system,
|
||||
Uint32 space_rule, Uint32 trans_rule,
|
||||
Glyph32** glyphs, Uint8** break_oppos, int* nr_glyphs)
|
||||
{
|
||||
Glyph32* gs = NULL;
|
||||
Uint8* bs = NULL;
|
||||
int len_buff;
|
||||
int n = 0;
|
||||
struct glyph_break_info gbinfo = {0, 0, NULL, NULL};
|
||||
int cosumed = 0;
|
||||
|
||||
DEVFONT* sbc_devfont = logfont->sbc_devfont;
|
||||
DEVFONT* mbc_devfont = logfont->mbc_devfont;
|
||||
|
||||
@@ -191,85 +298,203 @@ int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
if (mstr_len == 0)
|
||||
return 0;
|
||||
|
||||
// pre-allocate buffers
|
||||
len_buff = mstr_len >> 1;
|
||||
if (len_buff < MIN_LEN_GLYPHS)
|
||||
len_buff = MIN_LEN_GLYPHS;
|
||||
|
||||
gs = (Glyph32*)malloc(sizeof(Glyph32) * len_buff);
|
||||
bs = (Uint8*)malloc(sizeof(Uint8) * len_buff);
|
||||
if (gs == NULL || bs == NULL)
|
||||
if (gbinfo_init(&gbinfo, mstr_len >> 1) <= 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (mstr_len > 0 && *mstr != '\0') {
|
||||
Glyph32 g = INV_GLYPH_VALUE;
|
||||
Uchar32 uc = 0;
|
||||
int mchar_len;
|
||||
while (mstr_len > 0) {
|
||||
Glyph32 gv;
|
||||
Uchar32 uc;
|
||||
int mclen;
|
||||
UCharBasicType gc;
|
||||
UCharBreakType bt;
|
||||
|
||||
mchar_len = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
&g, &uc);
|
||||
if (mchar_len == 0)
|
||||
Glyph32 next_gv;
|
||||
Uchar32 next_uc;
|
||||
UCharBasicType next_gc;
|
||||
UCharBreakType next_bt;
|
||||
int next_mclen;
|
||||
|
||||
mclen = get_next_glyph(mbc_devfont, sbc_devfont, mstr, mstr_len,
|
||||
&gv, &uc);
|
||||
if (mclen == 0) {
|
||||
// badly encoded or end of text
|
||||
break;
|
||||
|
||||
gc = UCharGetType(uc);
|
||||
bt = UCharGetBreak(uc);
|
||||
|
||||
// CSS: collapses space acoording to space rule
|
||||
if ((space_rule == WSR_NORMAL || space_rule == WSR_NOWRAP)
|
||||
&& bt == UCHAR_BREAK_SPACE) {
|
||||
mchar_len += collapse_space(mbc_devfont, sbc_devfont, mstr,
|
||||
mstr_len);
|
||||
}
|
||||
|
||||
mstr_len -= mchar_len;
|
||||
mstr += mchar_len;
|
||||
cosumed += mchar_len;
|
||||
|
||||
gs[n] = g;
|
||||
bs[n] = BOV_UNKNOWN;
|
||||
|
||||
if (space_rule == WSR_PRE || space_rule == WSR_NOWRAP) {
|
||||
// only break at forced line breaks.
|
||||
// TODO: only break at forced line breaks.
|
||||
}
|
||||
else {
|
||||
/* Complete Line Breaking Algorithm goes here */
|
||||
|
||||
// LB1: Resolve line breaking classes
|
||||
bt = resolve_line_breaking_class(content_language, writing_system,
|
||||
gc, bt);
|
||||
|
||||
// mark all breaking opportunities
|
||||
}
|
||||
|
||||
/* check and realloc buffers */
|
||||
n++;
|
||||
if (n == len_buff) {
|
||||
len_buff += INC_LEN_GLYPHS;
|
||||
gs = (Glyph32*)realloc(gs, sizeof(Glyph32) * len_buff);
|
||||
bs = (Uint8*)realloc(bs, sizeof(Uint8) * len_buff);
|
||||
if (gs == NULL || bs == NULL)
|
||||
// LB1 Resolve line breaking class
|
||||
gc = UCharGetType(uc);
|
||||
bt = UCharGetBreak(uc);
|
||||
bt = resolve_line_breaking_class(content_language, writing_system,
|
||||
gc, bt);
|
||||
|
||||
// LB2 Never break at the start of text.
|
||||
if (gbinfo.n == 0) {
|
||||
Uint8 bo = BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
// LB3 Always break at the end of text.
|
||||
else if (*mstr == '\0') {
|
||||
break;
|
||||
}
|
||||
// LB4 Always break after hard line breaks
|
||||
// LB6 Do not break before hard line breaks.
|
||||
else if (bt == UCHAR_BREAK_MANDATORY) {
|
||||
Uint8 bo = BOV_AFTER_MANDATORY | BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
// LB5 Treat CR followed by LF, as well as CR, LF,
|
||||
// and NL as hard line breaks.
|
||||
// LB6 Do not break before hard line breaks.
|
||||
else if (bt == UCHAR_BREAK_CARRIAGE_RETURN) {
|
||||
mclen += collapse_line_feed(mbc_devfont, sbc_devfont, mstr,
|
||||
mstr_len);
|
||||
Uint8 bo = BOV_AFTER_MANDATORY | BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
// LB5 Treat CR followed by LF, as well as CR, LF,
|
||||
// and NL as hard line breaks.
|
||||
// LB6 Do not break before hard line breaks.
|
||||
else if (bt == UCHAR_BREAK_LINE_FEED
|
||||
|| bt == UCHAR_BREAK_NEXT_LINE) {
|
||||
Uint8 bo = BOV_AFTER_MANDATORY | BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
// LB7: Do not break before spaces or zero width space.
|
||||
else if (bt == UCHAR_BREAK_SPACE) {
|
||||
Uint8 bo = BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
|
||||
if (space_rule == WSR_NORMAL || space_rule == WSR_NOWRAP) {
|
||||
// CSS: collapses space according to space rule
|
||||
mclen += collapse_space(mbc_devfont, sbc_devfont, mstr,
|
||||
mstr_len);
|
||||
}
|
||||
}
|
||||
// LB7: Do not break before spaces or zero width space.
|
||||
else if (bt == UCHAR_BREAK_ZERO_WIDTH_SPACE) {
|
||||
Uint8 bo = BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
// LB8: Break before any character following a zero-width space,
|
||||
// even if one or more spaces intervene.
|
||||
else if (is_next_glyph_zw(mbc_devfont, sbc_devfont, mstr, mstr_len)) {
|
||||
Uint8 bo = BOV_BEFORE_MANDATORY;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
// LB8a Do not break between a zero width joiner and an ideograph,
|
||||
// emoji base or emoji modifier.
|
||||
else if (bt == UCHAR_BREAK_ZERO_WIDTH_JOINER) {
|
||||
next_mclen = get_next_glyph(mbc_devfont, sbc_devfont,
|
||||
mstr, mstr_len, &next_gv, &next_uc);
|
||||
Uint8 bo;
|
||||
|
||||
if (next_mclen > 0) {
|
||||
next_gc = UCharGetType(next_uc);
|
||||
next_bt = UCharGetBreak(next_uc);
|
||||
next_bt = resolve_line_breaking_class(content_language,
|
||||
writing_system, next_gc, next_bt);
|
||||
if (next_bt == UCHAR_BREAK_IDEOGRAPHIC
|
||||
|| next_bt == UCHAR_BREAK_EMOJI_BASE
|
||||
|| next_bt == UCHAR_BREAK_EMOJI_MODIFIER) {
|
||||
|
||||
mclen += next_mclen;
|
||||
|
||||
bo = BOV_AFTER_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
|
||||
bo = BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, next_gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
// LB9: Do not break a combining character sequence;
|
||||
// treat it as if it has the line breaking class of
|
||||
// the base character in all of the following rules.
|
||||
// Treat ZWJ as if it were CM.
|
||||
else if (bt != UCHAR_BREAK_MANDATORY
|
||||
&& bt != UCHAR_BREAK_CARRIAGE_RETURN
|
||||
&& bt != UCHAR_BREAK_LINE_FEED
|
||||
&& bt != UCHAR_BREAK_NEXT_LINE
|
||||
&& bt != UCHAR_BREAK_SPACE
|
||||
&& bt != UCHAR_BREAK_ZERO_WIDTH_SPACE
|
||||
&& (next_mclen = is_next_glyph_cm_or_zwj(mbc_devfont,
|
||||
sbc_devfont, mstr, mstr_len, &next_gv, &next_uc)) > 0) {
|
||||
Uint8 bo;
|
||||
|
||||
mclen += next_mclen;
|
||||
|
||||
bo = BOV_AFTER_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
|
||||
// FIXME: CM/ZWJ should have the same break class as
|
||||
// its base character.
|
||||
bo = BOV_BEFORE_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, next_gv, bo) == 0)
|
||||
goto error;
|
||||
|
||||
// For any possible subsequent CM/ZWJ characters.
|
||||
mclen += check_subsequent_cm_or_zwj(mbc_devfont,
|
||||
sbc_devfont, mstr + next_mclen, mstr_len - next_mclen,
|
||||
&gbinfo);
|
||||
|
||||
}
|
||||
// LB10 Treat any remaining combining mark or ZWJ as AL.
|
||||
else if (bt == UCHAR_BREAK_COMBINING_MARK
|
||||
|| bt == UCHAR_BREAK_ZERO_WIDTH_JOINER) {
|
||||
bt = UCHAR_BREAK_ALPHABETIC;
|
||||
}
|
||||
// LB11 Do not break before or after Word joiner
|
||||
// and related characters.
|
||||
else if (bt == UCHAR_BREAK_WORD_JOINER) {
|
||||
Uint8 bo = BOV_BEFORE_NOTALLOWED | BOV_AFTER_NOTALLOWED;
|
||||
if (gbinfo_push_back(&gbinfo, gv, bo) == 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
mstr_len -= mclen;
|
||||
mstr += mclen;
|
||||
cosumed += mclen;
|
||||
|
||||
// Return if we got any BK!
|
||||
if ((gbinfo.bs[gbinfo.n] & BOV_AFTER_MASK) == BOV_AFTER_MANDATORY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
if (gs) free(gs);
|
||||
if (bs) free(bs);
|
||||
if (gbinfo.n == 0) {
|
||||
if (gbinfo.gs) free(gbinfo.gs);
|
||||
if (gbinfo.bs) free(gbinfo.bs);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*glyphs = gs;
|
||||
*break_oppos = bs;
|
||||
*nr_glyphs = n;
|
||||
*glyphs = gbinfo.gs;
|
||||
*break_oppos = gbinfo.bs;
|
||||
*nr_glyphs = gbinfo.n;
|
||||
}
|
||||
|
||||
return cosumed;
|
||||
|
||||
error:
|
||||
if (gs) free(gs);
|
||||
if (bs) free(bs);
|
||||
if (gbinfo.gs) free(gbinfo.gs);
|
||||
if (gbinfo.bs) free(gbinfo.bs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user