tune code to handle auto-italic correctly

This commit is contained in:
Vincent Wei
2019-03-05 10:42:16 +08:00
parent cc7441c4dd
commit 94f44890a5
3 changed files with 67 additions and 283 deletions
+1 -1
View File
@@ -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);
}
-214
View File
@@ -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)
{
+66 -68
View File
@@ -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<h; i++)
{
italic_x = x+(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<h; i++) {
italic_x = x+((h-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;