handle whitespace gracefully

This commit is contained in:
Vincent Wei
2019-03-04 18:08:36 +08:00
parent 136a51d9b8
commit 6fdc0281ba
5 changed files with 46 additions and 8 deletions
+4
View File
@@ -10885,6 +10885,10 @@ typedef struct _GLYPHPOS {
* The y coordinate of the glyph position.
*/
int y;
/**
* Whether is a whitespace glyph.
*/
Uint8 whitespace:1;
/**
* Whether suppress the glyph.
*/
+1 -1
View File
@@ -45,7 +45,7 @@
extern "C" {
#endif /* __cplusplus */
Glyph32 _gdi_set_glyph_dfi(LOGFONT* lf, Glyph32 gv);
Glyph32 _gdi_select_glyph_dfi(LOGFONT* lf, Glyph32 gv);
#ifdef __cplusplus
}
+3 -3
View File
@@ -81,7 +81,7 @@ static Glyph32* _gdi_get_glyphs_string(PDC pdc, const unsigned char* text,
(prev_mchar, prev_len, text, left_bytes);
logical_glyphs[i++]
= _gdi_set_glyph_dfi(pdc->pLogFont, glyph_value);
= _gdi_select_glyph_dfi(pdc->pLogFont, glyph_value);
glyph_type = (*mbc_devfont->charset_ops->glyph_type)
(glyph_value);
if (!(glyph_type & MCHAR_TYPE_NOSPACING_MARK)){
@@ -407,7 +407,7 @@ static int _gdi_output_glyphs_direct(PDC pdc, const unsigned char* text,
glyph_value = mbc_devfont->charset_ops->char_glyph_value
(prev_mchar, prev_len, text, left_bytes);
glyph_value = _gdi_set_glyph_dfi(pdc->pLogFont, glyph_value);
glyph_value = _gdi_select_glyph_dfi(pdc->pLogFont, glyph_value);
goto do_glyph;
}
}
@@ -586,7 +586,7 @@ _gdi_get_glyphs_string_charbreak(PDC pdc, const unsigned char* text,
prev_mchar = text;
prev_len = len_cur_char;
logical_glyphs[i++] = _gdi_set_glyph_dfi(pdc->pLogFont, glyph_value);
logical_glyphs[i++] = _gdi_select_glyph_dfi(pdc->pLogFont, glyph_value);
glyph_type = (*mbc_devfont->charset_ops->glyph_type)
(glyph_value);
+29 -2
View File
@@ -318,7 +318,7 @@ static int get_next_glyph(struct glyph_break_ctxt* gbctxt,
if (mclen > 0) {
*gv = gbctxt->mbc_devfont->charset_ops->char_glyph_value
(NULL, 0, (Uint8*)mstr, mclen);
*gv = _gdi_set_glyph_dfi(gbctxt->lf, *gv);
*gv = _gdi_select_glyph_dfi(gbctxt->lf, *gv);
if (gbctxt->mbc_devfont->charset_ops->conv_to_uc32)
*uc = gbctxt->mbc_devfont->charset_ops->conv_to_uc32(*gv);
@@ -3214,6 +3214,7 @@ error:
typedef struct _MYGLYPHINFO {
Uchar32 uc;
Uint8 gc;
Uint8 whitespace:1;
Uint8 ignored:1;
Uint8 hanged:2;
Uint8 ort:2;
@@ -3433,6 +3434,12 @@ static int find_breaking_pos_word(MYGLYPHARGS* args, int n)
return -1;
}
static inline BOOL is_whitespace_glyph(const MYGLYPHARGS* args,
const MYGLYPHINFO* gis, int i)
{
return (args->bos[i] & BOV_WHITESPACE);
}
static inline BOOL is_zero_width_glyph(const MYGLYPHARGS* args,
const MYGLYPHINFO* gis, int i)
{
@@ -3724,6 +3731,7 @@ static void calc_unhanged_glyph_positions(MYGLYPHARGS* args,
for (i = first; i < stop; i++) {
adjust_glyph_position(args, x, y, gis + i, ges + i, pos + i);
pos[i].whitespace = gis[i].whitespace;
pos[i].suppressed = gis[i].ignored;
pos[i].hanged = gis[i].hanged;
pos[i].orientation = gis[i].ort;
@@ -3806,6 +3814,7 @@ static int calc_hanged_glyphs_start(MYGLYPHARGS* args,
for (i = 0; i <= args->hanged_start; i++) {
adjust_glyph_position(args, x, y, gis + i, ges + i, pos + i);
pos[i].whitespace = gis[i].whitespace;
pos[i].suppressed = gis[i].ignored;
pos[i].hanged = gis[i].hanged;
pos[i].orientation = gis[i].ort;
@@ -3862,6 +3871,7 @@ static int calc_hanged_glyphs_end(MYGLYPHARGS* args,
for (i = args->hanged_end; i < n; i++) {
adjust_glyph_position(args, x, y, gis + i, ges + i, pos + i);
pos[i].whitespace = gis[i].whitespace;
pos[i].suppressed = gis[i].ignored;
pos[i].hanged = gis[i].hanged;
pos[i].orientation = gis[i].ort;
@@ -3977,6 +3987,7 @@ static void init_glyph_info(MYGLYPHARGS* args, int i,
else
gi->uc = REAL_GLYPH(args->gvs[i]);
gi->gc = UCharGetCategory(gi->uc);
gi->whitespace = 0;
gi->ignored = 0;
gi->hanged = GLYPH_HANGED_NONE;
gi->ort = GLYPH_ORIENTATION_UPRIGHT;
@@ -4173,12 +4184,28 @@ int GUIAPI GetGlyphsExtentPointEx(LOGFONT* logfont_upright,
ges[n].adv_x = ges[n].line_adv;
break;
}
gis[n].whitespace = 1;
}
else {
gis[n].ignored = 1;
ges[n].line_adv = 0;
}
}
else if (is_whitespace_glyph(&args, gis, n)) {
gis[n].whitespace = 1;
ges[n].line_adv = logfont_upright->size / 6;
switch (render_flags & GRF_WRITING_MODE_MASK) {
case GRF_WRITING_MODE_VERTICAL_RL:
case GRF_WRITING_MODE_VERTICAL_LR:
ges[n].adv_y = ges[n].line_adv;
break;
case GRF_WRITING_MODE_HORIZONTAL_TB:
default:
ges[n].adv_x = ges[n].line_adv;
break;
}
}
else if (is_zero_width_glyph(&args, gis, n)) {
gis[n].ignored = 1;
ges[n].line_adv = 0;
@@ -4459,7 +4486,7 @@ int GUIAPI DrawGlyphStringEx(HDC hdc,
old_lf = GetCurFont(hdc);
for (i = 0; i < nr_glyphs; i++) {
if (glyph_pos[i].suppressed == 0) {
if (glyph_pos[i].suppressed == 0 && glyph_pos[i].whitespace == 0) {
if (glyph_pos[i].orientation == GLYPH_ORIENTATION_UPRIGHT) {
if (logfont_upright)
SelectFont(hdc, logfont_upright);
+9 -2
View File
@@ -2940,9 +2940,9 @@ void _gdi_start_new_line (PDC pdc)
}
}
Glyph32 _gdi_set_glyph_dfi(LOGFONT* lf, Glyph32 gv)
Glyph32 _gdi_select_glyph_dfi(LOGFONT* lf, Glyph32 gv)
{
int i, dfi = 1;
int i, dfi = 0;
DEVFONT* df;
for (i = 1; i < MAXNR_DEVFONTS; i++) {
@@ -2954,6 +2954,13 @@ Glyph32 _gdi_set_glyph_dfi(LOGFONT* lf, Glyph32 gv)
}
}
if (dfi == 0) {
if (REAL_GLYPH(gv) < 0x80)
dfi = 0;
else
dfi = 1;
}
return SET_GLYPH_DFI(gv, dfi);
}