gdi32: Move bidi text reordering to ExtTextOutW.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-08-19 10:25:33 +02:00 committed by Alexandre Julliard
parent 64df8e975b
commit bf4084b49c
3 changed files with 48 additions and 46 deletions

View File

@ -5855,8 +5855,6 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
const WCHAR *str, UINT count, const INT *lpDx, DWORD cp ) const WCHAR *str, UINT count, const INT *lpDx, DWORD cp )
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
LPWSTR reordered_str = (LPWSTR)str;
WORD *glyphs = NULL;
UINT align; UINT align;
DWORD layout; DWORD layout;
POINT pt; POINT pt;
@ -5903,26 +5901,6 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
align ^= TA_RTLREADING; align ^= TA_RTLREADING;
} }
if( !(flags & (ETO_GLYPH_INDEX | ETO_IGNORELANGUAGE)) && count > 0 )
{
INT cGlyphs;
reordered_str = HeapAlloc(GetProcessHeap(), 0, count*sizeof(WCHAR));
BIDI_Reorder( hdc, str, count, GCP_REORDER,
(align & TA_RTLREADING) ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR,
reordered_str, count, NULL, &glyphs, &cGlyphs);
flags |= ETO_IGNORELANGUAGE;
if (glyphs)
{
flags |= ETO_GLYPH_INDEX;
if (cGlyphs != count)
count = cGlyphs;
}
}
else if(flags & ETO_GLYPH_INDEX)
glyphs = reordered_str;
TRACE("%p, %d, %d, %08x, %s, %s, %d, %p)\n", hdc, x, y, flags, TRACE("%p, %d, %d, %08x, %s, %s, %d, %p)\n", hdc, x, y, flags,
wine_dbgstr_rect(lprect), debugstr_wn(str, count), count, lpDx); wine_dbgstr_rect(lprect), debugstr_wn(str, count), count, lpDx);
TRACE("align = %x bkmode = %x mapmode = %x\n", align, dc->attr->background_mode, TRACE("align = %x bkmode = %x mapmode = %x\n", align, dc->attr->background_mode,
@ -6014,9 +5992,9 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
INT *dx = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*dx) ); INT *dx = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*dx) );
if (flags & ETO_GLYPH_INDEX) if (flags & ETO_GLYPH_INDEX)
GetTextExtentExPointI( hdc, glyphs, count, -1, NULL, dx, &sz ); GetTextExtentExPointI( hdc, str, count, -1, NULL, dx, &sz );
else else
GetTextExtentExPointW( hdc, reordered_str, count, -1, NULL, dx, &sz ); GetTextExtentExPointW( hdc, str, count, -1, NULL, dx, &sz );
deltas[0].x = dx[0]; deltas[0].x = dx[0];
deltas[0].y = 0; deltas[0].y = 0;
@ -6062,9 +6040,9 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
POINT desired[2]; POINT desired[2];
if(flags & ETO_GLYPH_INDEX) if(flags & ETO_GLYPH_INDEX)
GetTextExtentPointI(hdc, glyphs, count, &sz); GetTextExtentPointI(hdc, str, count, &sz);
else else
GetTextExtentPointW(hdc, reordered_str, count, &sz); GetTextExtentPointW(hdc, str, count, &sz);
desired[0].x = desired[0].y = 0; desired[0].x = desired[0].y = 0;
desired[1].x = sz.cx; desired[1].x = sz.cx;
desired[1].y = 0; desired[1].y = 0;
@ -6152,14 +6130,10 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
} }
ret = physdev->funcs->pExtTextOut( physdev, x, y, (flags & ~ETO_OPAQUE), &rc, ret = physdev->funcs->pExtTextOut( physdev, x, y, (flags & ~ETO_OPAQUE), &rc,
glyphs ? glyphs : reordered_str, count, (INT*)deltas ); str, count, (INT*)deltas );
done: done:
HeapFree(GetProcessHeap(), 0, deltas); HeapFree(GetProcessHeap(), 0, deltas);
if(glyphs != reordered_str)
HeapFree(GetProcessHeap(), 0, glyphs);
if(reordered_str != str)
HeapFree(GetProcessHeap(), 0, reordered_str);
if (ret && (lf.lfUnderline || lf.lfStrikeOut)) if (ret && (lf.lfUnderline || lf.lfStrikeOut))
{ {

View File

@ -1350,21 +1350,6 @@ BOOL WINAPI GdiGradientFill( HDC hdc, TRIVERTEX *vert_array, ULONG nvert,
return NtGdiGradientFill( hdc, vert_array, nvert, grad_array, ngrad, mode ); return NtGdiGradientFill( hdc, vert_array, nvert, grad_array, ngrad, mode );
} }
/***********************************************************************
* ExtTextOutW (GDI32.@)
*/
BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *rect,
const WCHAR *str, UINT count, const INT *dx )
{
DC_ATTR *dc_attr;
if (is_meta_dc( hdc )) return METADC_ExtTextOut( hdc, x, y, flags, rect, str, count, dx );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_ExtTextOut( dc_attr, x, y, flags, rect, str, count, dx ))
return FALSE;
return NtGdiExtTextOutW( hdc, x, y, flags, rect, str, count, dx, 0 );
}
/*********************************************************************** /***********************************************************************
* SetTextJustification (GDI32.@) * SetTextJustification (GDI32.@)
*/ */

View File

@ -48,6 +48,7 @@
#include "winnls.h" #include "winnls.h"
#include "usp10.h" #include "usp10.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "gdi_private.h"
#include "ntgdi_private.h" #include "ntgdi_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(bidi); WINE_DEFAULT_DEBUG_CHANNEL(bidi);
@ -654,3 +655,45 @@ cleanup:
ScriptFreeCache(&psc); ScriptFreeCache(&psc);
return ret; return ret;
} }
/***********************************************************************
* ExtTextOutW (GDI32.@)
*/
BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *rect,
const WCHAR *str, UINT count, const INT *dx )
{
WORD *glyphs = NULL;
DC_ATTR *dc_attr;
BOOL ret;
if (count > INT_MAX) return FALSE;
if (is_meta_dc( hdc )) return METADC_ExtTextOut( hdc, x, y, flags, rect, str, count, dx );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_ExtTextOut( dc_attr, x, y, flags, rect, str, count, dx ))
return FALSE;
if (!(flags & (ETO_GLYPH_INDEX | ETO_IGNORELANGUAGE)) && count > 0)
{
UINT bidi_flags;
int glyphs_count;
bidi_flags = (dc_attr->text_align & TA_RTLREADING) || (flags & ETO_RTLREADING)
? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR;
BIDI_Reorder( hdc, str, count, GCP_REORDER, bidi_flags, NULL, 0, NULL,
&glyphs, &glyphs_count );
flags |= ETO_IGNORELANGUAGE;
if (glyphs)
{
flags |= ETO_GLYPH_INDEX;
count = glyphs_count;
str = glyphs;
}
}
ret = NtGdiExtTextOutW( hdc, x, y, flags, rect, str, count, dx, 0 );
HeapFree( GetProcessHeap(), 0, glyphs );
return ret;
}