mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-24 00:54:18 +08:00
implementation of WBR_BREAK_ALL and WBR_KEEP_ALL
This commit is contained in:
+81
-9
@@ -92,10 +92,15 @@ struct glyph_break_ctxt {
|
||||
int len_buff;
|
||||
int n;
|
||||
int base_bt;
|
||||
Uint8 curr_od;
|
||||
|
||||
LanguageCode cl;
|
||||
UCharScriptType ws;
|
||||
|
||||
Uint8 curr_od;
|
||||
Uint8 wsr;
|
||||
Uint8 ctr;
|
||||
Uint8 wbr;
|
||||
Uint8 lbp;
|
||||
};
|
||||
|
||||
static int gbctxt_init(struct glyph_break_ctxt* gbctxt, int size)
|
||||
@@ -340,6 +345,19 @@ static UCharBreakType resolve_lbc(struct glyph_break_ctxt* gbctxt, Uchar32 uc,
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Breaking is allowed within “words”: specifically, in addition to
|
||||
* soft wrap opportunities allowed for normal, any typographic character
|
||||
* units resolving to the NU (“numeric”), AL (“alphabetic”), or
|
||||
* SA (“Southeast Asian”) line breaking classes are instead treated
|
||||
* as ID (“ideographic characters”) for the purpose of line-breaking.
|
||||
*/
|
||||
if (gbctxt->wbr == WBR_BREAK_ALL &&
|
||||
(bt == UCHAR_BREAK_NUMERIC || bt == UCHAR_BREAK_ALPHABETIC
|
||||
|| bt == UCHAR_BREAK_COMPLEX_CONTEXT)) {
|
||||
bt = UCHAR_BREAK_IDEOGRAPHIC;
|
||||
}
|
||||
|
||||
if (pgc)
|
||||
*pgc = gc;
|
||||
|
||||
@@ -419,6 +437,40 @@ static int is_next_glyph_bt(struct glyph_break_ctxt* gbctxt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL is_glyph_letter(UCharBasicType gc, UCharBreakType bt)
|
||||
{
|
||||
if ((gc >= UCHAR_TYPE_LOWERCASE_LETTER
|
||||
&& gc <= UCHAR_TYPE_UPPERCASE_LETTER)
|
||||
|| (gc >= UCHAR_TYPE_DECIMAL_NUMBER
|
||||
&& gc <= UCHAR_TYPE_OTHER_NUMBER))
|
||||
return TRUE;
|
||||
|
||||
if (bt == UCHAR_BREAK_NUMERIC
|
||||
|| bt == UCHAR_BREAK_ALPHABETIC
|
||||
|| bt == UCHAR_BREAK_IDEOGRAPHIC
|
||||
|| bt == UCHAR_BREAK_AMBIGUOUS)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int is_next_glyph_letter(struct glyph_break_ctxt* gbctxt,
|
||||
const char* mstr, int mstr_len, Glyph32* gv, Uchar32* uc)
|
||||
{
|
||||
int mclen;
|
||||
UCharBasicType gc;
|
||||
UCharBreakType bt;
|
||||
|
||||
mclen = get_next_glyph(gbctxt, mstr, mstr_len, gv, uc);
|
||||
if (mclen > 0) {
|
||||
bt = resolve_lbc(gbctxt, *uc, &gc);
|
||||
if (is_glyph_letter(gc, bt))
|
||||
return mclen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int is_next_glyph_lf(struct glyph_break_ctxt* gbctxt,
|
||||
const char* mstr, int mstr_len, Glyph32* gv, Uchar32* uc)
|
||||
{
|
||||
@@ -877,6 +929,10 @@ int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
gbctxt.base_bt = UCHAR_BREAK_UNSET;
|
||||
gbctxt.cl = content_language;
|
||||
gbctxt.ws = writing_system;
|
||||
gbctxt.wsr = wsr;
|
||||
gbctxt.ctr = ctr;
|
||||
gbctxt.wbr = wbr;
|
||||
gbctxt.lbp = lbp;
|
||||
|
||||
*glyphs = NULL;
|
||||
*break_oppos = NULL;
|
||||
@@ -894,6 +950,7 @@ int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
Uchar32 uc;
|
||||
int mclen = 0;
|
||||
UCharBreakType bt;
|
||||
UCharBasicType gc;
|
||||
Uint8 bo;
|
||||
|
||||
Glyph32 next_gv;
|
||||
@@ -931,7 +988,7 @@ int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
|
||||
// LB1 Resolve line breaking class
|
||||
gbctxt.curr_od = LB1;
|
||||
bt = resolve_lbc(&gbctxt, uc, NULL);
|
||||
bt = resolve_lbc(&gbctxt, uc, &gc);
|
||||
|
||||
/* Start and end of text */
|
||||
// LB2 Never break at the start of text.
|
||||
@@ -1056,13 +1113,7 @@ int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
// ignore the following breaking rules.
|
||||
goto next_glyph;
|
||||
}
|
||||
|
||||
if (lbp == LBP_ANYWHERE) {
|
||||
_DBG_PRINTF ("LBP_ANYWHERE\n");
|
||||
bo = BOV_ALLOWED;
|
||||
gbctxt.curr_od = LB8a;
|
||||
gbctxt_change_bt_last(&gbctxt, bo);
|
||||
|
||||
else if (lbp == LBP_ANYWHERE) {
|
||||
// ignore the following breaking rules.
|
||||
goto next_glyph;
|
||||
}
|
||||
@@ -1146,6 +1197,27 @@ int GUIAPI GetGlyphsByRules(LOGFONT* logfont, const char* mstr, int mstr_len,
|
||||
gbctxt_change_bt_last(&gbctxt, BOV_NOTALLOWED_DEFINITELY);
|
||||
}
|
||||
|
||||
/* Breaking is forbidden within “words”: implicit soft wrap
|
||||
* opportunities between typographic letter units (or other
|
||||
* typographic character units belonging to the NU, AL, AI, or ID
|
||||
* Unicode line breaking classes) are suppressed, i.e. breaks are
|
||||
* prohibited between pairs of such characters (regardless of
|
||||
* line-break settings other than anywhere) except where opportunities
|
||||
* exist due to dictionary-based breaking.
|
||||
*/
|
||||
if (wbr == WBR_KEEP_ALL && is_glyph_letter(gc, bt)
|
||||
&& (next_mclen = is_next_glyph_letter(&gbctxt,
|
||||
mstr, mstr_len, &next_gv, &next_uc)) > 0) {
|
||||
_DBG_PRINTF ("WBR_KEEP_ALL.\n");
|
||||
gbctxt.curr_od = LB12a;
|
||||
gbctxt_change_bt_last(&gbctxt, BOV_NOTALLOWED_UNCERTAINLY);
|
||||
if (gbctxt_push_back(&gbctxt, next_gv, BOV_UNKNOWN) == 0)
|
||||
goto error;
|
||||
|
||||
cosumed_one_loop += next_mclen;
|
||||
goto next_glyph;
|
||||
}
|
||||
|
||||
/* Non-breaking characters */
|
||||
// LB12a Do not break before NBSP and related characters,
|
||||
// except after spaces and hyphens.
|
||||
|
||||
Reference in New Issue
Block a user