]> git.saurik.com Git - wxWidgets.git/commitdiff
Further performance optimizations
authorJulian Smart <julian@anthemion.co.uk>
Wed, 23 Apr 2008 15:01:33 +0000 (15:01 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Wed, 23 Apr 2008 15:01:33 +0000 (15:01 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53319 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/richtext/richtextbuffer.h
src/richtext/richtextbuffer.cpp

index d8b577b8d1c6fea220752d037ffe80579bba4df9..b702d3999fbdc0434e68b3f8c80e962ec5227c52 100644 (file)
@@ -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 );
index 4a7e45794413275f1f4c507fa6c0a0c873b1065c..91d561a569ec207c52de66c22b744741e2771487 100644 (file)
@@ -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