Further performance optimizations

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53319 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
2008-04-23 15:01:33 +00:00
parent 145c0c86ce
commit 2f45f5545f
2 changed files with 128 additions and 11 deletions

View 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 );

View 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;
#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