From: Julian Smart Date: Wed, 23 Apr 2008 15:01:33 +0000 (+0000) Subject: Further performance optimizations X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/2f45f5545f8f0c422e7d320f00e2ce068bd671b0?ds=sidebyside Further performance optimizations git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53319 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index d8b577b8d1..b702d3999f 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -151,6 +151,7 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer; #define wxRICHTEXT_FORMATTED 0x01 #define wxRICHTEXT_UNFORMATTED 0x02 +#define wxRICHTEXT_CACHE_SIZE 0x04 /*! * Flags for SetStyle/SetListStyle @@ -208,6 +209,9 @@ class WXDLLIMPEXP_FWD_RICHTEXT wxRichTextBuffer; #define wxSCRIPT_MUL_FACTOR 1.5 +// Leave on for faster drawing, by storing the length of each object in a line +#define wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING 1 + /*! * wxRichTextFontTable * Manages quick access to a pool of fonts for rendering rich text @@ -864,6 +868,11 @@ public: void SetDescent(int descent) { m_descent = descent; } int GetDescent() const { return m_descent; } +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING + wxArrayInt& GetObjectSizes() { return m_objectSizes; } + const wxArrayInt& GetObjectSizes() const { return m_objectSizes; } +#endif + // Operations /// Initialisation @@ -890,6 +899,10 @@ protected: // The parent object wxRichTextParagraph* m_parent; + +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING + wxArrayInt m_objectSizes; +#endif }; WX_DECLARE_LIST_WITH_DECL( wxRichTextLine, wxRichTextLineList , class WXDLLIMPEXP_RICHTEXT ); diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 4a7e457944..91d561a569 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -3188,6 +3188,8 @@ bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxR // Loop through objects until we get to the one within range wxRichTextObjectList::compatibility_iterator node2 = m_children.GetFirst(); + + int i = 0; while (node2) { wxRichTextObject* child = node2->GetData(); @@ -3199,14 +3201,24 @@ bool wxRichTextParagraph::Draw(wxDC& dc, const wxRichTextRange& range, const wxR objectRange.LimitTo(lineRange); wxSize objectSize; - int descent = 0; - child->GetRangeSize(objectRange, objectSize, descent, dc, wxRICHTEXT_UNFORMATTED, objectPosition); +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING && wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS + if (i < (int) line->GetObjectSizes().GetCount()) + { + objectSize.x = line->GetObjectSizes()[(size_t) i]; + } + else +#endif + { + int descent = 0; + child->GetRangeSize(objectRange, objectSize, descent, dc, wxRICHTEXT_UNFORMATTED, objectPosition); + } // Use the child object's width, but the whole line's height wxRect childRect(objectPosition, wxSize(objectSize.x, line->GetSize().y)); child->Draw(dc, objectRange, selectionRange, childRect, maxDescent, style); objectPosition.x += objectSize.x; + i ++; } else if (child->GetRange().GetStart() > lineRange.GetEnd()) // Can break out of inner loop now since we've passed this line's range @@ -3276,7 +3288,19 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) int lineCount = 0; - wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst(); + wxRichTextObjectList::compatibility_iterator node; + +#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS + wxUnusedVar(style); + wxArrayInt partialExtents; + + wxSize paraSize; + int paraDescent; + + // This calculates the partial text extents + GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED|wxRICHTEXT_CACHE_SIZE, wxPoint(0,0), & partialExtents); +#else + node = m_children.GetFirst(); while (node) { wxRichTextObject* child = node->GetData(); @@ -3287,14 +3311,6 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) node = node->GetNext(); } -#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS - wxArrayInt partialExtents; - - wxSize paraSize; - int paraDescent; - - // This calculates the partial text extents - GetRangeSize(GetRange(), paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED, wxPoint(0,0), & partialExtents); #endif // Split up lines @@ -3465,6 +3481,48 @@ bool wxRichTextParagraph::Layout(wxDC& dc, const wxRect& rect, int style) m_dirty = false; +#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING + // Use the text extents to calculate the size of each fragment in each line + wxRichTextLineList::compatibility_iterator lineNode = m_cachedLines.GetFirst(); + while (lineNode) + { + wxRichTextLine* line = lineNode->GetData(); + wxRichTextRange lineRange = line->GetAbsoluteRange(); + + // Loop through objects until we get to the one within range + wxRichTextObjectList::compatibility_iterator node2 = m_children.GetFirst(); + + while (node2) + { + wxRichTextObject* child = node2->GetData(); + + if (!child->GetRange().IsOutside(lineRange)) + { + wxRichTextRange rangeToUse = lineRange; + rangeToUse.LimitTo(child->GetRange()); + + // Find the size of the child from the text extents, and store in an array + // for drawing later + int left = 0; + if (rangeToUse.GetStart() > GetRange().GetStart()) + left = partialExtents[(rangeToUse.GetStart()-1) - GetRange().GetStart()]; + int right = partialExtents[rangeToUse.GetEnd() - GetRange().GetStart()]; + int sz = right - left; + line->GetObjectSizes().Add(sz); + } + else if (child->GetRange().GetStart() > lineRange.GetEnd()) + // Can break out of inner loop now since we've passed this line's range + break; + + node2 = node2->GetNext(); + } + + lineNode = lineNode->GetNext(); + } +#endif +#endif + return true; } @@ -3619,6 +3677,12 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz sz.x += childSize.x; descent = wxMax(descent, childDescent); + if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange())) + { + child->SetCachedSize(childSize); + child->SetDescent(childDescent); + } + if (partialExtents) { int lastSize; @@ -3819,6 +3883,39 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition } else { +#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS + wxArrayInt partialExtents; + + wxSize paraSize; + int paraDescent; + + // This calculates the partial text extents + GetRangeSize(lineRange, paraSize, paraDescent, dc, wxRICHTEXT_UNFORMATTED, wxPoint(0,0), & partialExtents); + + int lastX = linePos.x; + size_t i; + for (i = 0; i < partialExtents.GetCount(); i++) + { + int nextX = partialExtents[i] + linePos.x; + + if (pt.x >= lastX && pt.x <= nextX) + { + textPosition = i + lineRange.GetStart(); // minus 1? + + // So now we know it's between i-1 and i. + // Let's see if we can be more precise about + // which side of the position it's on. + + int midPoint = (nextX - lastX)/2 + lastX; + if (pt.x >= midPoint) + return wxRICHTEXT_HITTEST_AFTER; + else + return wxRICHTEXT_HITTEST_BEFORE; + } + + lastX = nextX; + } +#else long i; int lastX = linePos.x; for (i = lineRange.GetStart(); i <= lineRange.GetEnd(); i++) @@ -3851,6 +3948,7 @@ int wxRichTextParagraph::HitTest(wxDC& dc, const wxPoint& pt, long& textPosition lastX = nextX; } } +#endif } } @@ -4322,12 +4420,18 @@ void wxRichTextLine::Init(wxRichTextParagraph* parent) m_pos = wxPoint(0, 0); m_size = wxSize(0, 0); m_descent = 0; +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING + m_objectSizes.Clear(); +#endif } /// Copy void wxRichTextLine::Copy(const wxRichTextLine& obj) { m_range = obj.m_range; +#if wxRICHTEXT_USE_OPTIMIZED_LINE_DRAWING + m_objectSizes = obj.m_objectSizes; +#endif } /// Get the absolute object position