From 2014da26fcf385df7b364cc2b926de95b8a72a14 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Thu, 8 Sep 2005 12:40:20 +0000 Subject: [PATCH] Have ExtTextOut call into the font linking mechanism. GetCharWidth, GetCharABCWidths and GetTextExtentPoint should return the widths of a linked font's glyphs. --- dlls/gdi/font.c | 80 ++++++++++++++++++++++++++++++++++++++------- dlls/gdi/freetype.c | 27 ++++++++------- 2 files changed, 84 insertions(+), 23 deletions(-) diff --git a/dlls/gdi/font.c b/dlls/gdi/font.c index 04272c95af..ca26ce9260 100644 --- a/dlls/gdi/font.c +++ b/dlls/gdi/font.c @@ -1795,12 +1795,6 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, if(flags & ETO_GLYPH_INDEX) glyphs = (const WORD*)reordered_str; - else if(dc->gdiFont) - { - glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)); - GetGlyphIndicesW(hdc, reordered_str, count, (WORD*)glyphs, 0); - flags |= ETO_GLYPH_INDEX; - } if(lprect) TRACE("rect: %ld,%ld - %ld,%ld\n", lprect->left, lprect->top, lprect->right, @@ -1891,7 +1885,7 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, deltas[i] = tmpsz.cx; } - if (dc->breakExtra && reordered_str[i] == tm.tmBreakChar) + if (!(flags & ETO_GLYPH_INDEX) && dc->breakExtra && reordered_str[i] == tm.tmBreakChar) { deltas[i] = deltas[i] + dc->breakExtra; } @@ -1979,8 +1973,74 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, } } - ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc, - (flags & ETO_GLYPH_INDEX) ? glyphs: reordered_str, count, deltas); + if(FontIsLinked(hdc) && !(flags & ETO_GLYPH_INDEX)) + { + HFONT orig_font = dc->hFont, cur_font; + UINT glyph; + WORD *glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD)); + INT span = 0, *offsets = NULL, i; + + for(i = 0; i < count; i++) + { + WineEngGetLinkedHFont(dc, reordered_str[i], &cur_font, &glyph); + if(cur_font != dc->hFont) + { + if(!offsets) + { + int j; + offsets = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*deltas)); + offsets[0] = 0; + if(!deltas) + { + SIZE tmpsz; + for(j = 1; j < count; j++) + { + GetTextExtentPointW(hdc, reordered_str + j - 1, 1, &tmpsz); + offsets[j] = offsets[j-1] + INTERNAL_XWSTODS(dc, tmpsz.cx); + } + } + else + { + for(j = 1; j < count; j++) + offsets[j] = offsets[j-1] + deltas[j]; + } + } + if(span) + { + dc->funcs->pExtTextOut(dc->physDev, x + offsets[i - span] * cosEsc, y - offsets[i - span] * sinEsc, + (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, + glyphs, span, deltas ? deltas + i - span : NULL); + span = 0; + } + SelectObject(hdc, cur_font); + } + glyphs[span++] = glyph; + + if(i == count - 1) + { + ret = dc->funcs->pExtTextOut(dc->physDev, x + (offsets ? offsets[count - span] * cosEsc : 0), + y - (offsets ? offsets[count - span] * sinEsc : 0), + (flags & ~ETO_OPAQUE) | ETO_GLYPH_INDEX, &rc, + glyphs, span, deltas ? deltas + count - span : NULL); + SelectObject(hdc, orig_font); + HeapFree(GetProcessHeap(), 0, glyphs); + HeapFree(GetProcessHeap(), 0, offsets); + } + } + } + else + { + WORD *glyphs = NULL; + if(!(flags & ETO_GLYPH_INDEX) && dc->gdiFont) + { + glyphs = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WORD)); + GetGlyphIndicesW(hdc, reordered_str, count, glyphs, 0); + flags |= ETO_GLYPH_INDEX; + } + ret = dc->funcs->pExtTextOut(dc->physDev, x, y, (flags & ~ETO_OPAQUE), &rc, + (flags & ETO_GLYPH_INDEX) ? glyphs: reordered_str, count, deltas); + HeapFree(GetProcessHeap(), 0, glyphs); + } if (lf.lfUnderline || lf.lfStrikeOut) { @@ -2045,8 +2105,6 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, done: HeapFree(GetProcessHeap(), 0, deltas); - if(glyphs && glyphs != reordered_str) - HeapFree(GetProcessHeap(), 0, (WORD*)glyphs); if(reordered_str != str) HeapFree(GetProcessHeap(), 0, reordered_str); diff --git a/dlls/gdi/freetype.c b/dlls/gdi/freetype.c index 7f9d973fd4..779aab2174 100644 --- a/dlls/gdi/freetype.c +++ b/dlls/gdi/freetype.c @@ -3346,14 +3346,15 @@ BOOL WineEngGetCharWidth(GdiFont font, UINT firstChar, UINT lastChar, UINT c; GLYPHMETRICS gm; FT_UInt glyph_index; + GdiFont linked_font; TRACE("%p, %d, %d, %p\n", font, firstChar, lastChar, buffer); for(c = firstChar; c <= lastChar; c++) { - glyph_index = get_glyph_index(font, c); - WineEngGetGlyphOutline(font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, + get_glyph_index_linked(font, c, &linked_font, &glyph_index); + WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, NULL); - buffer[c - firstChar] = font->gm[glyph_index].adv; + buffer[c - firstChar] = linked_font->gm[glyph_index].adv; } return TRUE; } @@ -3368,6 +3369,7 @@ BOOL WineEngGetCharABCWidths(GdiFont font, UINT firstChar, UINT lastChar, UINT c; GLYPHMETRICS gm; FT_UInt glyph_index; + GdiFont linked_font; TRACE("%p, %d, %d, %p\n", font, firstChar, lastChar, buffer); @@ -3375,13 +3377,13 @@ BOOL WineEngGetCharABCWidths(GdiFont font, UINT firstChar, UINT lastChar, return FALSE; for(c = firstChar; c <= lastChar; c++) { - glyph_index = get_glyph_index(font, c); - WineEngGetGlyphOutline(font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, + get_glyph_index_linked(font, c, &linked_font, &glyph_index); + WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, NULL); - buffer[c - firstChar].abcA = font->gm[glyph_index].lsb; - buffer[c - firstChar].abcB = font->gm[glyph_index].bbx; - buffer[c - firstChar].abcC = font->gm[glyph_index].adv - font->gm[glyph_index].lsb - - font->gm[glyph_index].bbx; + buffer[c - firstChar].abcA = linked_font->gm[glyph_index].lsb; + buffer[c - firstChar].abcB = linked_font->gm[glyph_index].bbx; + buffer[c - firstChar].abcC = linked_font->gm[glyph_index].adv - linked_font->gm[glyph_index].lsb - + linked_font->gm[glyph_index].bbx; } return TRUE; } @@ -3397,6 +3399,7 @@ BOOL WineEngGetTextExtentPoint(GdiFont font, LPCWSTR wstr, INT count, GLYPHMETRICS gm; TEXTMETRICW tm; FT_UInt glyph_index; + GdiFont linked_font; TRACE("%p, %s, %d, %p\n", font, debugstr_wn(wstr, count), count, size); @@ -3406,10 +3409,10 @@ BOOL WineEngGetTextExtentPoint(GdiFont font, LPCWSTR wstr, INT count, size->cy = tm.tmHeight; for(idx = 0; idx < count; idx++) { - glyph_index = get_glyph_index(font, wstr[idx]); - WineEngGetGlyphOutline(font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, + get_glyph_index_linked(font, wstr[idx], &linked_font, &glyph_index); + WineEngGetGlyphOutline(linked_font, glyph_index, GGO_METRICS | GGO_GLYPH_INDEX, &gm, 0, NULL, NULL); - size->cx += font->gm[glyph_index].adv; + size->cx += linked_font->gm[glyph_index].adv; } TRACE("return %ld,%ld\n", size->cx, size->cy); return TRUE;