Don't delete composite objects when defragmenting
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75099 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1430,83 +1430,88 @@ bool wxRichTextCompositeObject::Defragment(wxRichTextDrawingContext& context, co
|
|||||||
{
|
{
|
||||||
wxRichTextCompositeObject* composite = wxDynamicCast(child, wxRichTextCompositeObject);
|
wxRichTextCompositeObject* composite = wxDynamicCast(child, wxRichTextCompositeObject);
|
||||||
if (composite)
|
if (composite)
|
||||||
composite->Defragment(context);
|
|
||||||
|
|
||||||
// Optimization: if there are no virtual attributes, we won't need to
|
|
||||||
// to split objects in order to paint individually attributed chunks.
|
|
||||||
// So only merge in this case.
|
|
||||||
if (!context.GetVirtualAttributesEnabled())
|
|
||||||
{
|
{
|
||||||
if (node->GetNext())
|
composite->Defragment(context);
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Optimization: if there are no virtual attributes, we won't need to
|
||||||
|
// to split objects in order to paint individually attributed chunks.
|
||||||
|
// So only merge in this case.
|
||||||
|
if (!context.GetVirtualAttributesEnabled())
|
||||||
{
|
{
|
||||||
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
if (node->GetNext())
|
||||||
if (child->CanMerge(nextChild, context) && child->Merge(nextChild, context))
|
|
||||||
{
|
{
|
||||||
nextChild->Dereference();
|
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
||||||
m_children.Erase(node->GetNext());
|
if (child->CanMerge(nextChild, context) && child->Merge(nextChild, context))
|
||||||
|
{
|
||||||
|
nextChild->Dereference();
|
||||||
|
m_children.Erase(node->GetNext());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
node = node->GetNext();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node = node->GetNext();
|
node = node->GetNext();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node = node->GetNext();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If we might have virtual attributes, we first see if we have to split
|
|
||||||
// objects so that they may be painted with potential virtual attributes,
|
|
||||||
// since text objects can only draw or measure with a single attributes object
|
|
||||||
// at a time.
|
|
||||||
wxRichTextObject* childAfterSplit = child;
|
|
||||||
if (child->CanSplit(context))
|
|
||||||
{
|
{
|
||||||
childAfterSplit = child->Split(context);
|
// If we might have virtual attributes, we first see if we have to split
|
||||||
node = m_children.Find(childAfterSplit);
|
// objects so that they may be painted with potential virtual attributes,
|
||||||
}
|
// since text objects can only draw or measure with a single attributes object
|
||||||
|
// at a time.
|
||||||
if (node->GetNext())
|
wxRichTextObject* childAfterSplit = child;
|
||||||
{
|
if (child->CanSplit(context))
|
||||||
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
|
||||||
|
|
||||||
// First split child and nextChild so we have smaller fragments to merge.
|
|
||||||
// Then Merge only has to test per-object virtual attributes
|
|
||||||
// because for an object with all the same sub-object attributes,
|
|
||||||
// then any general virtual attributes should be merged with sub-objects by
|
|
||||||
// the implementation.
|
|
||||||
|
|
||||||
wxRichTextObject* nextChildAfterSplit = nextChild;
|
|
||||||
|
|
||||||
if (nextChildAfterSplit->CanSplit(context))
|
|
||||||
nextChildAfterSplit = nextChild->Split(context);
|
|
||||||
|
|
||||||
bool splitNextChild = nextChild != nextChildAfterSplit;
|
|
||||||
|
|
||||||
// See if we can merge this new fragment with (perhaps the first part of) the next object.
|
|
||||||
// Note that we use nextChild because if we had split nextChild, the first object always
|
|
||||||
// remains (and further parts are appended). However we must use childAfterSplit since
|
|
||||||
// it's the last part of a possibly split child.
|
|
||||||
|
|
||||||
if (childAfterSplit->CanMerge(nextChild, context) && childAfterSplit->Merge(nextChild, context))
|
|
||||||
{
|
{
|
||||||
nextChild->Dereference();
|
childAfterSplit = child->Split(context);
|
||||||
m_children.Erase(node->GetNext());
|
node = m_children.Find(childAfterSplit);
|
||||||
|
}
|
||||||
|
|
||||||
// Don't set node -- we'll see if we can merge again with the next
|
if (node->GetNext())
|
||||||
// child. UNLESS we split this or the next child, in which case we know we have to
|
{
|
||||||
// move on to the end of the next child.
|
wxRichTextObject* nextChild = node->GetNext()->GetData();
|
||||||
if (splitNextChild)
|
|
||||||
node = m_children.Find(nextChildAfterSplit);
|
// First split child and nextChild so we have smaller fragments to merge.
|
||||||
|
// Then Merge only has to test per-object virtual attributes
|
||||||
|
// because for an object with all the same sub-object attributes,
|
||||||
|
// then any general virtual attributes should be merged with sub-objects by
|
||||||
|
// the implementation.
|
||||||
|
|
||||||
|
wxRichTextObject* nextChildAfterSplit = nextChild;
|
||||||
|
|
||||||
|
if (nextChildAfterSplit->CanSplit(context))
|
||||||
|
nextChildAfterSplit = nextChild->Split(context);
|
||||||
|
|
||||||
|
bool splitNextChild = nextChild != nextChildAfterSplit;
|
||||||
|
|
||||||
|
// See if we can merge this new fragment with (perhaps the first part of) the next object.
|
||||||
|
// Note that we use nextChild because if we had split nextChild, the first object always
|
||||||
|
// remains (and further parts are appended). However we must use childAfterSplit since
|
||||||
|
// it's the last part of a possibly split child.
|
||||||
|
|
||||||
|
if (childAfterSplit->CanMerge(nextChild, context) && childAfterSplit->Merge(nextChild, context))
|
||||||
|
{
|
||||||
|
nextChild->Dereference();
|
||||||
|
m_children.Erase(node->GetNext());
|
||||||
|
|
||||||
|
// Don't set node -- we'll see if we can merge again with the next
|
||||||
|
// child. UNLESS we split this or the next child, in which case we know we have to
|
||||||
|
// move on to the end of the next child.
|
||||||
|
if (splitNextChild)
|
||||||
|
node = m_children.Find(nextChildAfterSplit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (splitNextChild)
|
||||||
|
node = m_children.Find(nextChildAfterSplit); // start from the last object in the split
|
||||||
|
else
|
||||||
|
node = node->GetNext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
node = node->GetNext();
|
||||||
if (splitNextChild)
|
|
||||||
node = m_children.Find(nextChildAfterSplit); // start from the last object in the split
|
|
||||||
else
|
|
||||||
node = node->GetNext();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
node = node->GetNext();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user