Fix text jumps during selection dragging on MSW

When selecting the text in wxHtmlWindow by dragging the mouse the text
to the right of the selection sometimes jumps horizontally. This happens
only on MSW and only for TrueType fonts. The reason is that
wxDC::GetPartialTextExtents() and wxDC::GetTextExtent() give different
results if the text contains characters with underhangs or overhangs.

Fix this by caching results of wxDC::GetPartialTextExtents() and using
them instead of calling wxDC::GetTextExtent().
This commit is contained in:
Pavel Kalugin
2019-04-11 08:01:57 +03:00
committed by Vadim Zeitlin
parent bce4bf1c8e
commit a7dc1c0e0f
2 changed files with 32 additions and 13 deletions

View File

@@ -343,7 +343,8 @@ void wxHtmlWordCell::SetPreviousWord(wxHtmlWordCell *cell)
// where s2 and s3 start:
void wxHtmlWordCell::Split(const wxDC& dc,
const wxPoint& selFrom, const wxPoint& selTo,
unsigned& pos1, unsigned& pos2) const
unsigned& pos1, unsigned& pos2,
unsigned& ext1, unsigned& ext2) const
{
wxPoint pt1 = (selFrom == wxDefaultPosition) ?
wxDefaultPosition : selFrom - GetAbsPos();
@@ -400,21 +401,30 @@ void wxHtmlWordCell::Split(const wxDC& dc,
pos2 = j;
wxASSERT( pos2 >= pos1 );
ext1 = pos1 == 0 ? 0 : (pos1 < widths.size() ? widths[pos1-1] : widths.Last());
ext2 = pos2 == 0 ? 0 : (pos2 < widths.size() ? widths[pos2-1] : widths.Last());
}
void wxHtmlWordCell::SetSelectionPrivPos(const wxDC& dc, wxHtmlSelection *s) const
{
unsigned p1, p2;
unsigned p1, p2, ext1, ext2;
Split(dc,
this == s->GetFromCell() ? s->GetFromPos() : wxDefaultPosition,
this == s->GetToCell() ? s->GetToPos() : wxDefaultPosition,
p1, p2);
p1, p2, ext1, ext2);
if ( this == s->GetFromCell() )
s->SetFromCharacterPos (p1); // selection starts here
{
s->SetFromCharacterPos(p1); // selection starts here
s->SetExtentBeforeSelection(ext1);
}
if ( this == s->GetToCell() )
s->SetToCharacterPos (p2); // selection ends here
{
s->SetToCharacterPos(p2); // selection ends here
s->SetExtentBeforeSelectionEnd(ext2);
}
}
@@ -459,7 +469,6 @@ void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
// Selection changing, we must draw the word piecewise:
wxHtmlSelection *s = info.GetSelection();
wxString txt;
int w, h;
int ofs = 0;
// NB: this is quite a hack: in order to compute selection boundaries
@@ -479,8 +488,7 @@ void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
{
txt = m_Word.Mid(0, part1);
dc.DrawText(txt, x + m_PosX, y + m_PosY);
dc.GetTextExtent(txt, &w, &h);
ofs += w;
ofs += s->GetExtentBeforeSelection();
}
SwitchSelState(dc, info, true);
@@ -490,11 +498,9 @@ void wxHtmlWordCell::Draw(wxDC& dc, int x, int y,
if ( (size_t)part2 < m_Word.length() )
{
dc.GetTextExtent(txt, &w, &h);
ofs += w;
SwitchSelState(dc, info, false);
txt = m_Word.Mid(part2);
dc.DrawText(txt, ofs + x + m_PosX, y + m_PosY);
dc.DrawText(txt, x + m_PosX + s->GetExtentBeforeSelectionEnd(), y + m_PosY);
}
else
drawSelectionAfterCell = true;