diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 75a58cf3f2..d4cd971fde 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -149,6 +149,7 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer; #define wxRICHTEXT_FORMATTED 0x01 #define wxRICHTEXT_UNFORMATTED 0x02 #define wxRICHTEXT_CACHE_SIZE 0x04 +#define wxRICHTEXT_HEIGHT_ONLY 0x08 /*! * Flags for SetStyle/SetListStyle diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 315a467d97..563de5cb6d 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -3357,6 +3357,22 @@ bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxR return true; } +// Get the range width using partial extents calculated for the whole paragraph. +static int wxRichTextGetRangeWidth(const wxRichTextParagraph& para, const wxRichTextRange& range, const wxArrayInt& partialExtents) +{ + wxASSERT(partialExtents.GetCount() >= (size_t) range.GetLength()); + + int leftMostPos = 0; + if (range.GetStart() - para.GetRange().GetStart() > 0) + leftMostPos = partialExtents[range.GetStart() - para.GetRange().GetStart() - 1]; + + int rightMostPos = partialExtents[range.GetEnd() - para.GetRange().GetStart()]; + + int w = rightMostPos - leftMostPos; + + return w; +} + /// Lay the item out bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) { @@ -3481,7 +3497,15 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) childDescent = child->GetDescent(); } else + { +#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS + // Get height only, then the width using the partial extents + GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY); + childSize.x = wxRichTextGetRangeWidth(*this, wxRichTextRange(lastEndPos+1, lastPosToUse), g_GlobalPartialTextExtents); +#else GetRangeSize(wxRichTextRange(lastEndPos+1, lastPosToUse), childSize, childDescent, dc, wxRICHTEXT_UNFORMATTED, rect.GetPosition()); +#endif + } // Cases: // 1) There was a line break BEFORE the natural break @@ -3510,7 +3534,15 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) // Let's find the actual size of the current line now wxSize actualSize; wxRichTextRange actualRange(lastCompletedEndPos+1, wrapPosition); + +#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS + // Get height only, then the width using the partial extents + GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_HEIGHT_ONLY); + actualSize.x = wxRichTextGetRangeWidth(*this, actualRange, g_GlobalPartialTextExtents); +#else GetRangeSize(actualRange, actualSize, childDescent, dc, wxRICHTEXT_UNFORMATTED); +#endif + currentWidth = actualSize.x; lineHeight = wxMax(lineHeight, actualSize.y); maxDescent = wxMax(childDescent, maxDescent); @@ -3790,7 +3822,18 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz rangeToUse.LimitTo(child->GetRange()); int childDescent = 0; - if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y))) + // At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're already cached the size, + // but it's only going to be used after caching has taken place. + if ((flags & wxRICHTEXT_HEIGHT_ONLY) && child->GetCachedSize().y != 0) + { + childDescent = child->GetDescent(); + childSize = child->GetCachedSize(); + + sz.y = wxMax(sz.y, childSize.y); + sz.x += childSize.x; + descent = wxMax(descent, childDescent); + } + else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, flags, wxPoint(position.x + sz.x, position.y))) { sz.y = wxMax(sz.y, childSize.y); sz.x += childSize.x;