@@ -5911,11 +5911,12 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
59115911 INT char_extra ;
59125912 SIZE sz ;
59135913 RECT rc ;
5914- POINT * deltas = NULL , width = {0 , 0 };
5914+ POINT * deltas = NULL , width = {0 , 0 }, text_box_dim [ 2 ] = {{ 0 }} ;
59155915 DC * dc = get_dc_ptr ( hdc );
59165916 PHYSDEV physdev ;
59175917 INT breakRem ;
59185918 static int quietfixme = 0 ;
5919+ INT fill_extra_left = 0 , fill_extra_right = 0 ;
59195920
59205921 if (!dc ) return FALSE;
59215922 if (count > INT_MAX ) return FALSE;
@@ -6068,12 +6069,22 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
60686069 deltas [i ].y = desired [1 ].y - width .y ;
60696070
60706071 width = desired [1 ];
6072+ text_box_dim [1 ] = width ;
60716073 }
60726074 flags |= ETO_PDY ;
60736075 }
60746076 else
60756077 {
60766078 POINT desired [2 ];
6079+ ULONG abc_flags = NTGDI_GETCHARABCWIDTHS_INT ;
6080+ BOOL mirror_x = FALSE, mirror_y = FALSE;
6081+ ABC abc ;
6082+
6083+ if (dc -> attr -> graphics_mode == GM_COMPATIBLE && dc -> vport2WorldValid )
6084+ {
6085+ mirror_x = dc -> xformWorld2Vport .eM11 < 0 ;
6086+ mirror_y = dc -> xformWorld2Vport .eM22 < 0 ;
6087+ }
60776088
60786089 NtGdiGetTextExtentExW ( hdc , str , count , 0 , NULL , NULL , & sz , !!(flags & ETO_GLYPH_INDEX ) );
60796090 desired [0 ].x = desired [0 ].y = 0 ;
@@ -6083,13 +6094,31 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
60836094 desired [1 ].x -= desired [0 ].x ;
60846095 desired [1 ].y -= desired [0 ].y ;
60856096
6086- if (dc -> attr -> graphics_mode == GM_COMPATIBLE )
6097+ text_box_dim [1 ].x = sz .cx ;
6098+ if (flags & ETO_GLYPH_INDEX )
6099+ abc_flags |= NTGDI_GETCHARABCWIDTHS_INDICES ;
6100+
6101+ memset ( & abc , 0 , sizeof (abc ) );
6102+ NtGdiGetCharABCWidthsW ( hdc , 0 , 1 , (WCHAR * )str , abc_flags , & abc );
6103+ if (mirror_x && abc .abcC < 0 ) text_box_dim [0 ].x += abc .abcC ;
6104+ else if (!mirror_x && abc .abcA < 0 ) text_box_dim [0 ].x += abc .abcA ;
6105+
6106+ memset ( & abc , 0 , sizeof (abc ) );
6107+ NtGdiGetCharABCWidthsW ( hdc , 0 , 1 , (WCHAR * )(str + count - 1 ), abc_flags , & abc );
6108+ if (mirror_x && abc .abcA < 0 ) text_box_dim [1 ].x -= abc .abcA ;
6109+ else if (!mirror_x && abc .abcC < 0 ) text_box_dim [1 ].x -= abc .abcC ;
6110+
6111+ lp_to_dp (dc , text_box_dim , 2 );
6112+
6113+ text_box_dim [0 ].x -= desired [0 ].x ;
6114+ text_box_dim [1 ].x -= desired [0 ].x ;
6115+ if (mirror_x )
60876116 {
6088- if (dc -> vport2WorldValid && dc -> xformWorld2Vport .eM11 < 0 )
6089- desired [1 ].x = - desired [1 ].x ;
6090- if (dc -> vport2WorldValid && dc -> xformWorld2Vport .eM22 < 0 )
6091- desired [1 ].y = - desired [1 ].y ;
6117+ desired [1 ].x = - desired [1 ].x ;
6118+ text_box_dim [0 ].x = - text_box_dim [0 ].x ;
6119+ text_box_dim [1 ].x = - text_box_dim [1 ].x ;
60926120 }
6121+ if (mirror_y ) desired [1 ].y = - desired [1 ].y ;
60936122 width = desired [1 ];
60946123 }
60956124
@@ -6146,12 +6175,12 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
61466175 if (!((flags & ETO_CLIPPED ) && (flags & ETO_OPAQUE )))
61476176 {
61486177 if (!(flags & ETO_OPAQUE ) || !lprect ||
6149- x < rc .left || x + width .x >= rc .right ||
6178+ x - fill_extra_left < rc .left || x + width .x + fill_extra_right >= rc .right ||
61506179 y - tm .tmAscent < rc .top || y + tm .tmDescent >= rc .bottom )
61516180 {
61526181 RECT text_box ;
6153- text_box .left = x ;
6154- text_box .right = x + width .x ;
6182+ text_box .left = x + text_box_dim [ 0 ]. x ;
6183+ text_box .right = x + text_box_dim [ 1 ] .x ;
61556184 text_box .top = y - tm .tmAscent ;
61566185 text_box .bottom = y + tm .tmDescent ;
61576186
0 commit comments