Work around text extent differences resulting in clipped text
Under at least some versions of Windows 10 with wxDVC themed text can be clipped horizontally because of discrepancies between the text extent as drawn by DrawThemeTextEx() and calculated with GetTextExtent() earlier. Work around the issue by always trying to use GetThemeTextExtent() in DrawItemText(), not just for alignment of multi-line strings, and adjust for any width differences similar to the existing adjustment for height. See #18487.
This commit is contained in:
parent
ebf1141db2
commit
90ba137f20
@ -1104,13 +1104,16 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
||||
such alignment use DT_TOP (0), which does work for multi-lines,
|
||||
and deal with the actual desired vertical alignment ourselves with
|
||||
the help of GetThemeTextExtent().
|
||||
*/
|
||||
bool useTopDrawing =
|
||||
s_GetThemeTextExtent
|
||||
&& ( align & (wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL) ) != 0
|
||||
&& text.Contains(wxS('\n'));
|
||||
|
||||
if ( useTopDrawing )
|
||||
[TODO] Ideally text measurement should only be needed for the above
|
||||
mentioned situations but because there can be a difference between
|
||||
the extent from GetThemeTextExtent() and the rect received by this
|
||||
function could have involved other text measurements (e.g. with wxDVC,
|
||||
see #18487), use it in all cases for now.
|
||||
*/
|
||||
bool useTopDrawing = false;
|
||||
|
||||
if ( s_GetThemeTextExtent != NULL )
|
||||
{
|
||||
/*
|
||||
Get the actual text extent using GetThemeTextExtent() and adjust
|
||||
@ -1151,6 +1154,30 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
||||
defTextFlags, NULL, &rcExtent);
|
||||
if ( SUCCEEDED(hr) )
|
||||
{
|
||||
/*
|
||||
Compensate for rare cases where the horizontal extents differ
|
||||
slightly. Don't use the width of the passed rect here to deal
|
||||
with horizontal alignment as it results in the text always
|
||||
fitting and ellipsization then can't occur. Instead check for
|
||||
width differences by comparing with the extent as calculated
|
||||
by wxDC.
|
||||
*/
|
||||
const int textWidthDc = dc.GetMultiLineTextExtent(text).x;
|
||||
const int widthDiff = textWidthDc - rcExtent.right;
|
||||
if ( widthDiff )
|
||||
{
|
||||
if ( align & wxALIGN_CENTRE_HORIZONTAL )
|
||||
{
|
||||
const int widthOffset = widthDiff / 2;
|
||||
rc.left += widthOffset;
|
||||
rc.right -= widthOffset;
|
||||
}
|
||||
else if ( align & wxALIGN_RIGHT )
|
||||
rc.left += widthDiff;
|
||||
else // left aligned
|
||||
rc.right -= widthDiff;
|
||||
}
|
||||
|
||||
/*
|
||||
For height compare with the height of the passed rect and use
|
||||
the difference for handling vertical alignment. This has
|
||||
@ -1163,8 +1190,12 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
||||
necessity) confines rendering to a cell's bounds.
|
||||
*/
|
||||
const int heightDiff = rect.GetHeight() - rcExtent.bottom;
|
||||
if ( heightDiff )
|
||||
if ( heightDiff
|
||||
&& (align & (wxALIGN_BOTTOM | wxALIGN_CENTRE_VERTICAL))
|
||||
&& text.Contains(wxS('\n')) )
|
||||
{
|
||||
useTopDrawing = true;
|
||||
|
||||
if ( align & wxALIGN_CENTRE_VERTICAL )
|
||||
{
|
||||
const int heightOffset = heightDiff / 2;
|
||||
@ -1177,10 +1208,6 @@ void wxRendererXP::DrawItemText(wxWindow* win,
|
||||
rc.bottom -= heightDiff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
useTopDrawing = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !useTopDrawing )
|
||||
|
Loading…
Reference in New Issue
Block a user