diff --git a/include/wx/html/htmlcell.h b/include/wx/html/htmlcell.h index d95fe95a2e..0068c8c173 100644 --- a/include/wx/html/htmlcell.h +++ b/include/wx/html/htmlcell.h @@ -35,7 +35,8 @@ public: wxHtmlSelection() : m_fromPos(wxDefaultPosition), m_toPos(wxDefaultPosition), m_fromCharacterPos(-1), m_toCharacterPos(-1), - m_fromCell(NULL), m_toCell(NULL) {} + m_fromCell(NULL), m_toCell(NULL), + m_extBeforeSel(0), m_extBeforeSelEnd(0) {} // this version is used for the user selection defined with the mouse void Set(const wxPoint& fromPos, const wxHtmlCell *fromCell, @@ -58,6 +59,11 @@ public: wxCoord GetFromCharacterPos () const { return m_fromCharacterPos; } wxCoord GetToCharacterPos () const { return m_toCharacterPos; } + void SetExtentBeforeSelection(unsigned ext) { m_extBeforeSel = ext; } + void SetExtentBeforeSelectionEnd(unsigned ext) { m_extBeforeSelEnd = ext; } + unsigned GetExtentBeforeSelection() const { return m_extBeforeSel; } + unsigned GetExtentBeforeSelectionEnd() const { return m_extBeforeSelEnd; } + bool IsEmpty() const { return m_fromPos == wxDefaultPosition && m_toPos == wxDefaultPosition; } @@ -66,6 +72,12 @@ private: wxPoint m_fromPos, m_toPos; wxCoord m_fromCharacterPos, m_toCharacterPos; const wxHtmlCell *m_fromCell, *m_toCell; + + // Extent of the text before selection start. + unsigned m_extBeforeSel; + + // Extent of the text from the beginning to the selection end. + unsigned m_extBeforeSelEnd; }; @@ -431,7 +443,8 @@ protected: void SetSelectionPrivPos(const wxDC& dc, wxHtmlSelection *s) const; void Split(const wxDC& dc, const wxPoint& selFrom, const wxPoint& selTo, - unsigned& pos1, unsigned& pos2) const; + unsigned& pos1, unsigned& pos2, + unsigned& ext1, unsigned& ext2) const; wxString m_Word; bool m_allowLinebreak; diff --git a/src/html/htmlcell.cpp b/src/html/htmlcell.cpp index a559df99f2..a853cc0084 100644 --- a/src/html/htmlcell.cpp +++ b/src/html/htmlcell.cpp @@ -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;