From 94f44890a5e4b1d8fa4a940718ad2e018d97c7b2 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 5 Mar 2019 10:42:16 +0800 Subject: [PATCH] tune code to handle auto-italic correctly --- src/newgdi/bidi.c | 2 +- src/newgdi/drawtext.c | 214 ------------------------------------------ src/newgdi/glyph.c | 134 +++++++++++++------------- 3 files changed, 67 insertions(+), 283 deletions(-) diff --git a/src/newgdi/bidi.c b/src/newgdi/bidi.c index 8bd7ca8c..2913bc50 100644 --- a/src/newgdi/bidi.c +++ b/src/newgdi/bidi.c @@ -670,7 +670,7 @@ static int _gdi_get_nextword_width (PDC pdc, const unsigned char* pText, *nChars = word_info.len; - /* Fixed bug of italic font */ + /* Fixed bug of italic font */ return size.cx - _gdi_get_italic_added_width (pdc->pLogFont); } diff --git a/src/newgdi/drawtext.c b/src/newgdi/drawtext.c index 5eb2f05c..f24a6b3e 100644 --- a/src/newgdi/drawtext.c +++ b/src/newgdi/drawtext.c @@ -99,220 +99,6 @@ static inline BOOL is_utf16_logfont (PDC pdc) #endif -#if 0 -static void txtDrawOneLine (PDC pdc, const unsigned char* pText, int nLen, - int x, int y, const RECT* prcOutput, UINT nFormat, int nTabWidth) -{ - /* set rc_output to the possible clipping rect */ - pdc->rc_output = *prcOutput; - - if (nFormat & DT_EXPANDTABS) { - const unsigned char* sub = pText; - const unsigned char* left; - int nSubLen = nLen; - int nOutputLen; - int nTabLen; - - while ((left = (unsigned char*) __mg_strnchr (pdc->pLogFont, - (const char*)sub, nSubLen, '\t', &nTabLen))) { - - nOutputLen = left - sub; - x += _gdi_text_out (pdc, x, y, sub, nOutputLen, NULL); - - nSubLen -= (nOutputLen + nTabLen); - sub = left + nTabLen; - x += nTabWidth; - } - - if (nSubLen > 0) - _gdi_text_out (pdc, x, y, sub, nSubLen, NULL); - } - else - _gdi_text_out (pdc, x, y, pText, nLen, NULL); -} - -static int txtGetWidthOfNextWord (PDC pdc, const unsigned char* pText, - int nCount, int* nChars) -{ - SIZE size; - DEVFONT* sbc_devfont = pdc->pLogFont->devfonts[0]; - DEVFONT* mbc_devfont = pdc->pLogFont->devfonts[1]; - WORDINFO word_info = {0}; - - *nChars = 0; - if (nCount == 0) return 0; - - if (mbc_devfont) { - int mbc_pos, sub_len; - - mbc_pos = (*mbc_devfont->charset_ops->pos_first_char) - ((const unsigned char*)pText, nCount); - if (mbc_pos == 0) { - sub_len = (*mbc_devfont->charset_ops->len_first_substr) - ((const unsigned char*)pText, nCount); - - (*mbc_devfont->charset_ops->get_next_word) - ((const unsigned char*)pText, sub_len, &word_info); - - if (word_info.len == 0) { - *nChars = 0; - return 0; - } - } - else if (mbc_pos > 0) - nCount = mbc_pos; - } - - if (word_info.len == 0) - (*sbc_devfont->charset_ops->get_next_word) - ((const unsigned char*)pText, nCount, &word_info); - - _gdi_get_text_extent (pdc, pText, word_info.len, &size); - - *nChars = word_info.len; - - /* Fixed bug of italic font */ - return size.cx - _gdi_get_italic_added_width (pdc->pLogFont); -} - -/* -** This function return the normal characters' number (reference) -** and output width of the line (return value). -*/ -static int txtGetOneLine (PDC pdc, const unsigned char* pText, int nCount, - int nTabWidth, int maxwidth, UINT uFormat, int* nChar) -{ - int word_len, char_len; - int word_width, char_width; - int line_width; - SIZE size; - int italic_width = 0; - - *nChar = 0; - - if (uFormat & DT_SINGLELINE) { - - if (uFormat & DT_EXPANDTABS) - _gdi_tabbed_text_out (pdc, 0, 0, pText, nCount, nTabWidth, - TRUE, NULL, &size); - else - _gdi_get_text_extent (pdc, pText, nCount, &size); - - *nChar = nCount; - return size.cx; - } - - italic_width = _gdi_get_italic_added_width(pdc->pLogFont); - /* Fixed bug of italic font */ - maxwidth -= italic_width; - - word_len = 0; word_width = 0; - char_len = 0; char_width = 0; - line_width = 0; - while (TRUE) { - if (uFormat & DT_CHARBREAK) { - if (line_width > maxwidth) { - *nChar -= char_len; - if (*nChar <= 0) /* ensure to eat at least one char */ - *nChar += char_len; - break; - } - word_len = 0; - } - else if (uFormat & DT_WORDBREAK) { - word_width = txtGetWidthOfNextWord (pdc, pText, nCount, - &word_len); - - if (word_width > maxwidth) { - word_len = GetTextExtentPoint ((HDC)pdc, - (const char*)pText, word_len, - maxwidth - line_width, NULL, NULL, NULL, &size); - word_width = size.cx; - - if (word_len == 0) { /* eat at least one char */ - word_len = GetFirstMCharLen (GetCurFont ((HDC)pdc), - (const char*)pText, nCount); - _gdi_get_text_extent (pdc, pText, word_len, &size); - - /* Fixed bug of italic font */ - word_width = size.cx - italic_width; - } - *nChar += word_len; - - /* Fixed bug of italic font */ - line_width += word_width + italic_width; - break; - } - else if (line_width + word_width > maxwidth) - break; - } - else { - word_width = txtGetWidthOfNextWord (pdc, pText, nCount, &word_len); - } - - if (word_len > 0) { - pText += word_len; - nCount -= word_len; - - *nChar += word_len; - line_width += word_width; - } - - if (nCount <= 0) - break; - - char_len = 0; - char_width = 0; - if (*pText == '\t') { - char_len = 1; - - if (uFormat & DT_EXPANDTABS) { - char_width = nTabWidth; - _gdi_start_new_line (pdc); - } - else { - _gdi_get_text_extent (pdc, pText, 1, &size); - /* Fixed bug of italic font */ - char_width = size.cx - italic_width; - } - } - else if (*pText == '\n' || *pText == '\r') { - (*nChar) ++; - break; - } - else if (*pText == ' ') { - char_len = 1; - _gdi_get_text_extent (pdc, pText, 1, &size); - /* Fixed bug of italic font */ - char_width = size.cx - italic_width; - } - - if ((word_len + char_len) == 0) { /* ensure to eat at least one char */ - char_len = GetFirstMCharLen (GetCurFont ((HDC)pdc), - (const char*)pText, nCount); - _gdi_get_text_extent (pdc, pText, char_len, &size); - - char_width = size.cx - italic_width; - } - - if (char_len > 0) { - pText += char_len; - nCount -= char_len; - - *nChar += char_len; - line_width += char_width; - } - - if (line_width > maxwidth) - break; - } - - /* Fixed bug of italic font */ - return line_width + italic_width; -} - -#endif - static BOOL cb_drawtextex2 (void* context, Glyph32 glyph_value, unsigned int glyph_type) { diff --git a/src/newgdi/glyph.c b/src/newgdi/glyph.c index 545ab1cb..2a5c2d9a 100644 --- a/src/newgdi/glyph.c +++ b/src/newgdi/glyph.c @@ -2504,37 +2504,36 @@ int _gdi_get_null_glyph_advance (PDC pdc, int advance, BOOL direction, #define ROTATE_RECT 2 static void make_back_area(PDC pdc, int x0, int y0, int x1, int y1, - POINT* area, GAL_Rect* gal_rc, int* flag) + POINT* area, GAL_Rect* gal_rc, int italic, int bold, int* flag) { int h = pdc->pLogFont->size; int ascent = pdc->pLogFont->ascent; if (pdc->pLogFont->rotation) *flag = ROTATE_RECT; - else if (pdc->pLogFont->style & FS_SLANT_ITALIC && - !(pdc->pLogFont->devfonts[0]->style & FS_SLANT_ITALIC)) + else if (italic > 0) *flag = ITALIC_RECT; else *flag = ROMAN_RECT; - switch (*flag) - { - case ROMAN_RECT: - case ITALIC_RECT: - gal_rc->x = x0; - gal_rc->y = y0 - ascent; - gal_rc->w = x1 - x0; - gal_rc->h = h; - break; + switch (*flag) { + case ROMAN_RECT: + case ITALIC_RECT: + gal_rc->x = x0; + gal_rc->y = y0 - ascent; + gal_rc->w = x1 - x0; + gal_rc->h = h; + break; - case ROTATE_RECT: - _gdi_get_glyph_box_vertices (x0, y0, x1, y1, - area, pdc); - break; + case ROTATE_RECT: + _gdi_get_glyph_box_vertices (x0, y0, x1, y1, + area, pdc); + break; } } -static void draw_back_area (PDC pdc, POINT* area, GAL_Rect* gal_rc, int flag) +static void draw_back_area (PDC pdc, POINT* area, GAL_Rect* gal_rc, + int italic, int bold, int flag) { int x = gal_rc->x; int y = gal_rc->y; @@ -2553,18 +2552,18 @@ static void draw_back_area (PDC pdc, POINT* area, GAL_Rect* gal_rc, int flag) switch (font_style & FS_FLIP_MASK) { case FS_FLIP_HORZ: case FS_FLIP_VERT: - for (i=0; i>1); + for (i = 0; i < h; i++) { + italic_x = x + (i >> 1); _dc_draw_hline_clip (pdc, italic_x, - italic_x+w-1, y+i); + italic_x + w - 1, y + i); } break; + default: - for (i=0; i>1); + for (i = 0; i < h; i++) { + italic_x = x + ((h - i) >> 1); _dc_draw_hline_clip (pdc, italic_x, - italic_x+w-1, y+i); + italic_x + w - 1, y + i); } } break; @@ -2581,46 +2580,45 @@ static void draw_back_area (PDC pdc, POINT* area, GAL_Rect* gal_rc, int flag) } } -static void make_back_rect(RECT* rc_back, POINT* area, GAL_Rect* gal_rc, int flag) +static void make_back_rect(RECT* rc_back, POINT* area, GAL_Rect* gal_rc, + int italic, int bold, int flag) { int i; - switch (flag) - { - case ROMAN_RECT: - rc_back->left = gal_rc->x; - rc_back->right = gal_rc->x + gal_rc->w; - rc_back->top = gal_rc->y; - rc_back->bottom = gal_rc->y + gal_rc->h; - break; + switch (flag) { + case ROMAN_RECT: + rc_back->left = gal_rc->x; + rc_back->right = gal_rc->x + gal_rc->w; + rc_back->top = gal_rc->y; + rc_back->bottom = gal_rc->y + gal_rc->h; + break; - case ITALIC_RECT: - rc_back->left = gal_rc->x; - rc_back->right = gal_rc->x + gal_rc->w + (gal_rc->h >>1); - rc_back->top = gal_rc->y; - rc_back->bottom = gal_rc->y + gal_rc->h; - break; + case ITALIC_RECT: + rc_back->left = gal_rc->x; + rc_back->right = gal_rc->x + gal_rc->w; + rc_back->top = gal_rc->y; + rc_back->bottom = gal_rc->y + gal_rc->h; + break; - case ROTATE_RECT: - rc_back->left = area[0].x; - rc_back->right = area[0].x; - rc_back->top = area[0].y; - rc_back->bottom = area[0].y; - for (i=0; i<4; i++) - { - if (rc_back->left > area[i].x) - rc_back->left = area[i].x; + case ROTATE_RECT: + rc_back->left = area[0].x; + rc_back->right = area[0].x; + rc_back->top = area[0].y; + rc_back->bottom = area[0].y; - if (rc_back->right < area[i].x) - rc_back->right = area[i].x; + for (i=0; i<4; i++) { + if (rc_back->left > area[i].x) + rc_back->left = area[i].x; - if (rc_back->top > area[i].y) - rc_back->top = area[i].y; + if (rc_back->right < area[i].x) + rc_back->right = area[i].x; - if (rc_back->bottom < area[i].y) - rc_back->bottom = area[i].y; - } + if (rc_back->top > area[i].y) + rc_back->top = area[i].y; + + if (rc_back->bottom < area[i].y) + rc_back->bottom = area[i].y; + } } - } void _gdi_calc_glyphs_size_from_two_points (PDC pdc, int x0, int y0, @@ -2631,8 +2629,8 @@ void _gdi_calc_glyphs_size_from_two_points (PDC pdc, int x0, int y0, int flag; RECT rc; - make_back_area(pdc, x0, y0, x1, y1, area, &gal_rc, &flag); - make_back_rect(&rc, area, &gal_rc, flag); + make_back_area(pdc, x0, y0, x1, y1, area, &gal_rc, 0, 0, &flag); + make_back_rect(&rc, area, &gal_rc, 0, 0, flag); size->cx = RECTW (rc); size->cy = RECTH (rc); @@ -2654,12 +2652,12 @@ int _gdi_draw_null_glyph (PDC pdc, int advance, BOOL direction, if (direction) make_back_area(pdc, x, y, x+*adv_x, y+*adv_y, - area, &gal_rc, &flag); + area, &gal_rc, 0, 0, &flag); else make_back_area(pdc, x+*adv_x, y+*adv_y, x, y, - area, &gal_rc, &flag); + area, &gal_rc, 0, 0, &flag); - make_back_rect(&rc_back, area, &gal_rc, flag); + make_back_rect(&rc_back, area, &gal_rc, 0, 0, flag); if (!(pdc = __mg_check_ecrgn ((HDC)pdc))) { return advance; @@ -2678,7 +2676,7 @@ int _gdi_draw_null_glyph (PDC pdc, int advance, BOOL direction, ENTER_DRAWING(pdc); - draw_back_area (pdc, area, &gal_rc, flag); + draw_back_area (pdc, area, &gal_rc, 0, 0, flag); LEAVE_DRAWING (pdc); end: @@ -2764,8 +2762,7 @@ static void draw_glyph_lines (PDC pdc, int x1, int y1, int x2, int y2) &draw_x1, &draw_y1, &draw_x2, &draw_y2, pdc); } - if (logfont->rotation == 0 && (logfont->style & FS_SLANT_ITALIC)) - { + if (logfont->rotation == 0 && (logfont->style & FS_SLANT_ITALIC)) { draw_x1 += h>>2; draw_x2 += h>>2; } @@ -2853,17 +2850,17 @@ int _gdi_draw_one_glyph (PDC pdc, Glyph32 glyph_value, BOOL direction, if (need_rc_back) { if (direction) make_back_area(pdc, x, y, x+*adv_x, y+*adv_y, - area, &bg_gal_rc, &flag); + area, &bg_gal_rc, italic, bold, &flag); else make_back_area(pdc, x+*adv_x, y+*adv_y, x, y, - area, &bg_gal_rc, &flag); + area, &bg_gal_rc, italic, bold, &flag); if (glyph_bmptype == DEVFONTGLYPHTYPE_MONOBMP && (logfont->style & FS_DECORATE_OUTLINE)) { bg_gal_rc.x--; bg_gal_rc.y--; bg_gal_rc.w += 2; bg_gal_rc.h += 2; } - make_back_rect(&rc_back, area, &bg_gal_rc, flag); + make_back_rect(&rc_back, area, &bg_gal_rc, italic, bold, flag); } rc_front.left = fg_gal_rc.x; @@ -2896,7 +2893,7 @@ int _gdi_draw_one_glyph (PDC pdc, Glyph32 glyph_value, BOOL direction, /* draw back ground */ if (pdc->bkmode != BM_TRANSPARENT) { pdc->cur_pixel = pdc->bkcolor; - draw_back_area (pdc, area, &bg_gal_rc, flag); + draw_back_area (pdc, area, &bg_gal_rc, italic, bold, flag); } /* bbox is the real glyph pixels on one scan-line. */ @@ -2917,6 +2914,7 @@ end: int _gdi_get_italic_added_width (LOGFONT* logfont) { + /* FIXME: use the correct devfont for auto-italic */ if (logfont->style & FS_SLANT_ITALIC && !(logfont->devfonts[0]->style & FS_SLANT_ITALIC)) { return (logfont->size + 1) >> 1;