diff --git a/docs/changes.txt b/docs/changes.txt index 90d0ae353c..071a3d6c24 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -31,6 +31,7 @@ All (GUI): - Add default ctor and Create() to wxContextHelpButton (Hanmac). - Send events when toggling wxPropertyGrid nodes from keyboard (Armel Asselin). - Fix wxRearrangeList::Check() which asserted and misbehaved before. +- Optimized wxRTC insertion and deletion when floating objects are present. wxGTK: diff --git a/include/wx/richtext/richtextbuffer.h b/include/wx/richtext/richtextbuffer.h index 32bb8a2076..a7b5bc6cad 100644 --- a/include/wx/richtext/richtextbuffer.h +++ b/include/wx/richtext/richtextbuffer.h @@ -4283,6 +4283,8 @@ public: virtual ~wxRichTextParagraph(); wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextCompositeObject() { Copy(obj); } + void Init(); + // Overridables virtual bool Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); @@ -4416,10 +4418,23 @@ public: */ void LayoutFloat(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style, wxRichTextFloatCollector* floatCollector); + /** + Whether the paragraph is impacted by floating objects from above. + */ + int GetImpactedByFloatingObjects() const { return m_impactedByFloatingObjects; } + + /** + Sets whether the paragraph is impacted by floating objects from above. + */ + void SetImpactedByFloatingObjects(int i) { m_impactedByFloatingObjects = i; } + protected: // The lines that make up the wrapped paragraph - wxRichTextLineList m_cachedLines; + wxRichTextLineList m_cachedLines; + + // Whether the paragraph is impacted by floating objects from above + int m_impactedByFloatingObjects; // Default tabstops static wxArrayInt sm_defaultTabs; @@ -6163,7 +6178,9 @@ public: Updates the control appearance, optimizing if possible given information from the call to Layout. */ void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false, - wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, bool isDoCmd = true); + const wxRect& oldFloatRect = wxRect(), + wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, + bool isDoCmd = true); /** Replaces the buffer paragraphs with the given fragment. @@ -6216,7 +6233,8 @@ public: /** Calculate arrays for refresh optimization. */ - void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions); + void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions, + wxRect& oldFloatRect); /** Sets the position used for e.g. insertion. diff --git a/interface/wx/richtext/richtextbuffer.h b/interface/wx/richtext/richtextbuffer.h index eebde53142..95a1076cf7 100644 --- a/interface/wx/richtext/richtextbuffer.h +++ b/interface/wx/richtext/richtextbuffer.h @@ -4124,6 +4124,8 @@ public: virtual ~wxRichTextParagraph(); wxRichTextParagraph(const wxRichTextParagraph& obj): wxRichTextCompositeObject() { Copy(obj); } + void Init(); + // Overridables virtual bool Draw(wxDC& dc, wxRichTextDrawingContext& context, const wxRichTextRange& range, const wxRichTextSelection& selection, const wxRect& rect, int descent, int style); @@ -4257,11 +4259,24 @@ public: */ void LayoutFloat(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int style, wxRichTextFloatCollector* floatCollector); + /** + Whether the paragraph is impacted by floating objects from above. + */ + int GetImpactedByFloatingObjects() const { return m_impactedByFloatingObjects; } + + /** + Sets whether the paragraph is impacted by floating objects from above. + */ + void SetImpactedByFloatingObjects(int i) { m_impactedByFloatingObjects = i; } + protected: // The lines that make up the wrapped paragraph - wxRichTextLineList m_cachedLines; + wxRichTextLineList m_cachedLines; + // Whether the paragraph is impacted by floating objects from above + int m_impactedByFloatingObjects; + // Default tabstops static wxArrayInt sm_defaultTabs; @@ -5971,7 +5986,9 @@ public: Updates the control appearance, optimizing if possible given information from the call to Layout. */ void UpdateAppearance(long caretPosition, bool sendUpdateEvent = false, - wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, bool isDoCmd = true); + const wxRect& oldFloatRect = wxRect(), + wxArrayInt* optimizationLineCharPositions = NULL, wxArrayInt* optimizationLineYPositions = NULL, + bool isDoCmd = true); /** Replaces the buffer paragraphs with the given fragment. @@ -6026,7 +6043,8 @@ public: /** Calculate arrays for refresh optimization. */ - void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions); + void CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions, + wxRect& oldFloatRect); /** Sets the position used for e.g. insertion. diff --git a/src/richtext/richtextbuffer.cpp b/src/richtext/richtextbuffer.cpp index 7b46f44496..d7289bcdde 100644 --- a/src/richtext/richtextbuffer.cpp +++ b/src/richtext/richtextbuffer.cpp @@ -2207,10 +2207,8 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& co maxMaxWidth = wxMax(maxMaxWidth, child->GetMaxSize().x); // If we're just formatting the visible part of the buffer, - // and we're now past the bottom of the window, and we don't have any - // floating objects (since they may cause wrapping to change for the rest of the - // the buffer), start quick layout. - if (!hasVerticalAlignment && formatRect && child->GetPosition().y > rect.GetBottom() && GetFloatingObjectCount() == 0) + // and we're now past the bottom of the window, start quick layout. + if (!hasVerticalAlignment && formatRect && child->GetPosition().y > rect.GetBottom()) forceQuickLayout = true; } else @@ -2220,7 +2218,47 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& co // been laid out and have wrapped line lists associated with them. // TODO: check all paragraphs before the affected range. - int inc = availableSpace.y - child->GetPosition().y; + // Lay out paragraphs until they are (and were) not affected + // by floating objects from above the paragraphs. + if (wxRichTextBuffer::GetFloatingLayoutMode()) + { + while (node) + { + child = wxDynamicCast(node->GetData(), wxRichTextParagraph); + if (child) + { + int oldImpactedByFloats = child->GetImpactedByFloatingObjects(); + + child->SetImpactedByFloatingObjects(-1); + + child->LayoutToBestSize(dc, context, GetBuffer(), + attr, child->GetAttributes(), availableSpace, rect, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT); + + availableSpace.y += child->GetCachedSize().y; + maxWidth = wxMax(maxWidth, child->GetCachedSize().x); + maxMinWidth = wxMax(maxMinWidth, child->GetMinSize().x); + maxMaxWidth = wxMax(maxMaxWidth, child->GetMaxSize().x); + + int newImpactedByFloats = child->GetImpactedByFloatingObjects(); + + // We can stop laying out if this paragraph is unaffected by floating + // objects, and was previously too. + if (oldImpactedByFloats == 0 && newImpactedByFloats == 0) + { + node = node->GetNext(); + break; + } + } + node = node->GetNext(); + } + } + + int inc = 0; + if (node) + { + child = wxDynamicCast(node->GetData(), wxRichTextParagraph); + inc = availableSpace.y - child->GetPosition().y; + } while (node) { @@ -2229,15 +2267,19 @@ bool wxRichTextParagraphLayoutBox::Layout(wxDC& dc, wxRichTextDrawingContext& co { if (child->GetLines().GetCount() == 0) { + child->SetImpactedByFloatingObjects(-1); + // Lays out the object first with a given amount of space, and then if no width was specified in attr, // lays out the object again using the minimum size child->LayoutToBestSize(dc, context, GetBuffer(), attr, child->GetAttributes(), availableSpace, rect, style&~wxRICHTEXT_LAYOUT_SPECIFIED_RECT); - - //child->Layout(dc, availableChildRect, style); } else + { + if (wxRichTextBuffer::GetFloatingLayoutMode() && GetFloatCollector()) + GetFloatCollector()->CollectFloat(child); child->Move(wxPoint(child->GetPosition().x, child->GetPosition().y + inc)); + } availableSpace.y += child->GetCachedSize().y; maxWidth = wxMax(maxWidth, child->GetCachedSize().x); @@ -4047,20 +4089,9 @@ wxRichTextRange wxRichTextParagraphLayoutBox::GetInvalidRange(bool wholeParagrap if (para1) range.SetStart(para1->GetRange().GetStart()); - // FIXME: be more intelligent about this. Check if we have floating objects - // before the end of the range. But it's not clear how we can in general - // tell where it's safe to stop laying out. - // Anyway, this code is central to efficiency when laying in floating mode. - if (!wxRichTextBuffer::GetFloatingLayoutMode()) - { - wxRichTextParagraph* para2 = GetParagraphAtPosition(range.GetEnd()); - if (para2) - range.SetEnd(para2->GetRange().GetEnd()); - } - else - // Floating layout means that all children should be laid out, - // because we can't tell how the whole buffer will be affected. - range.SetEnd(GetOwnRange().GetEnd()); + wxRichTextParagraph* para2 = GetParagraphAtPosition(range.GetEnd()); + if (para2) + range.SetEnd(para2->GetRange().GetEnd()); } return range; } @@ -4643,6 +4674,8 @@ wxArrayInt wxRichTextParagraph::sm_defaultTabs; wxRichTextParagraph::wxRichTextParagraph(wxRichTextObject* parent, wxRichTextAttr* style): wxRichTextCompositeObject(parent) { + Init(); + if (style) SetAttributes(*style); } @@ -4650,12 +4683,19 @@ wxRichTextParagraph::wxRichTextParagraph(wxRichTextObject* parent, wxRichTextAtt wxRichTextParagraph::wxRichTextParagraph(const wxString& text, wxRichTextObject* parent, wxRichTextAttr* paraStyle, wxRichTextAttr* charStyle): wxRichTextCompositeObject(parent) { + Init(); + if (paraStyle) SetAttributes(*paraStyle); AppendChild(new wxRichTextPlainText(text, this, charStyle)); } +void wxRichTextParagraph::Init() +{ + m_impactedByFloatingObjects = -1; +} + wxRichTextParagraph::~wxRichTextParagraph() { ClearLines(); @@ -4850,14 +4890,22 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co { wxASSERT(collector != NULL); if (collector) + { + if (m_impactedByFloatingObjects == -1) + { + if (collector->GetLastRectBottom() >= rect.GetTop()) + m_impactedByFloatingObjects = 1; + else + m_impactedByFloatingObjects = 0; + } + LayoutFloat(dc, context, rect, parentRect, style, collector); + } } wxRichTextAttr attr = GetCombinedAttributes(); AdjustAttributes(attr, context); - // ClearLines(); - // Increase the size of the paragraph due to spacing int spaceBeforePara = ConvertTenthsMMToPixels(dc, attr.GetParagraphSpacingBefore()); int spaceAfterPara = ConvertTenthsMMToPixels(dc, attr.GetParagraphSpacingAfter()); @@ -11448,7 +11496,8 @@ wxRichTextParagraphLayoutBox* wxRichTextAction::GetContainer() const } -void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions) +void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLineCharPositions, wxArrayInt& optimizationLineYPositions, + wxRect& oldFloatRect) { // Store a list of line start character and y positions so we can figure out which area // we need to refresh @@ -11472,7 +11521,8 @@ void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLin int lastY = firstVisiblePt.y + clientSize.y; wxRichTextParagraph* para = container->GetParagraphAtPosition(GetRange().GetStart()); - wxRichTextObjectList::compatibility_iterator node = container->GetChildren().Find(para); + wxRichTextObjectList::compatibility_iterator firstNode = container->GetChildren().Find(para); + wxRichTextObjectList::compatibility_iterator node = firstNode; while (node) { wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); @@ -11501,6 +11551,26 @@ void wxRichTextAction::CalculateRefreshOptimizations(wxArrayInt& optimizationLin if (node) node = node->GetNext(); } + + if (wxRichTextBuffer::GetFloatingLayoutMode() && container->GetFloatingObjectCount() > 0) + { + // We will use a simple criterion - if any of the paragraphs following the + // modification point are affected by floats in other paragraphs, + // then we will simply update the rest of the screen. + wxRichTextObjectList::compatibility_iterator node = firstNode; + while (node) + { + wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); + if (child->GetRect().GetTop() > lastY) + break; + else if (child->GetImpactedByFloatingObjects() == 1) + { + oldFloatRect = wxRect(0, 0, clientSize.x, lastY); + break; + } + node = node->GetNext(); + } + } } #endif } @@ -11522,9 +11592,10 @@ bool wxRichTextAction::Do() // we need to refresh wxArrayInt optimizationLineCharPositions; wxArrayInt optimizationLineYPositions; + wxRect oldFloatRect; #if wxRICHTEXT_USE_OPTIMIZED_DRAWING - CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); + CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions, oldFloatRect); #endif container->InsertFragment(GetRange().GetStart(), m_newParagraphs); @@ -11552,7 +11623,7 @@ bool wxRichTextAction::Do() newCaretPosition = wxMin(newCaretPosition, (container->GetOwnRange().GetEnd()-1)); - UpdateAppearance(newCaretPosition, true /* send update event */, & optimizationLineCharPositions, & optimizationLineYPositions, true /* do */); + UpdateAppearance(newCaretPosition, true /* send update event */, oldFloatRect, & optimizationLineCharPositions, & optimizationLineYPositions, true /* do */); wxRichTextEvent cmdEvent( wxEVT_RICHTEXT_CONTENT_INSERTED, @@ -11570,9 +11641,10 @@ bool wxRichTextAction::Do() { wxArrayInt optimizationLineCharPositions; wxArrayInt optimizationLineYPositions; + wxRect oldFloatRect; #if wxRICHTEXT_USE_OPTIMIZED_DRAWING - CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); + CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions, oldFloatRect); #endif // Check if the current object focus needs to be changed before deletion of content @@ -11600,7 +11672,7 @@ bool wxRichTextAction::Do() if (caretPos >= container->GetOwnRange().GetEnd()) caretPos --; - UpdateAppearance(caretPos, true /* send update event */, & optimizationLineCharPositions, & optimizationLineYPositions, true /* do */); + UpdateAppearance(caretPos, true /* send update event */, oldFloatRect, & optimizationLineCharPositions, & optimizationLineYPositions, true /* do */); wxRichTextEvent cmdEvent( wxEVT_RICHTEXT_CONTENT_DELETED, @@ -11750,9 +11822,10 @@ bool wxRichTextAction::Undo() { wxArrayInt optimizationLineCharPositions; wxArrayInt optimizationLineYPositions; + wxRect oldFloatRect; #if wxRICHTEXT_USE_OPTIMIZED_DRAWING - CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); + CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions, oldFloatRect); #endif // Check if the current object focus needs to be changed before deletion of content @@ -11779,7 +11852,7 @@ bool wxRichTextAction::Undo() long newCaretPosition = GetPosition() - 1; - UpdateAppearance(newCaretPosition, true, /* send update event */ & optimizationLineCharPositions, & optimizationLineYPositions, false /* undo */); + UpdateAppearance(newCaretPosition, true, /* send update event */ oldFloatRect, & optimizationLineCharPositions, & optimizationLineYPositions, false /* undo */); wxRichTextEvent cmdEvent( wxEVT_RICHTEXT_CONTENT_DELETED, @@ -11797,9 +11870,10 @@ bool wxRichTextAction::Undo() { wxArrayInt optimizationLineCharPositions; wxArrayInt optimizationLineYPositions; + wxRect oldFloatRect; #if wxRICHTEXT_USE_OPTIMIZED_DRAWING - CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions); + CalculateRefreshOptimizations(optimizationLineCharPositions, optimizationLineYPositions, oldFloatRect); #endif container->InsertFragment(GetRange().GetStart(), m_oldParagraphs); @@ -11809,7 +11883,7 @@ bool wxRichTextAction::Undo() // Layout() would stop prematurely at the top level. container->InvalidateHierarchy(GetRange()); - UpdateAppearance(GetPosition(), true, /* send update event */ & optimizationLineCharPositions, & optimizationLineYPositions, false /* undo */); + UpdateAppearance(GetPosition(), true, /* send update event */ oldFloatRect, & optimizationLineCharPositions, & optimizationLineYPositions, false /* undo */); wxRichTextEvent cmdEvent( wxEVT_RICHTEXT_CONTENT_INSERTED, @@ -11858,7 +11932,7 @@ bool wxRichTextAction::Undo() } /// Update the control appearance -void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent, wxArrayInt* optimizationLineCharPositions, wxArrayInt* optimizationLineYPositions, bool isDoCmd) +void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent, const wxRect& oldFloatRect, wxArrayInt* optimizationLineCharPositions, wxArrayInt* optimizationLineYPositions, bool isDoCmd) { wxRichTextParagraphLayoutBox* container = GetContainer(); wxASSERT(container != NULL); @@ -11878,7 +11952,8 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent // Refresh everything if there were floating objects or the container changed size // (we can't yet optimize in these cases, since more complex interaction with other content occurs) - if ((wxRichTextBuffer::GetFloatingLayoutMode() && container->GetFloatingObjectCount() > 0) || (container->GetParent() && containerRect != container->GetRect())) + // Refresh everything if container changed size. + if (container->GetParent() && containerRect != container->GetRect()) { m_ctrl->Refresh(false); } @@ -11892,6 +11967,7 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent wxSize clientSize = m_ctrl->GetUnscaledSize(m_ctrl->GetClientSize()); wxPoint firstVisiblePt = m_ctrl->GetUnscaledPoint(m_ctrl->GetFirstVisiblePoint()); + int lastPossibleY = firstVisiblePt.y + clientSize.y; // Start/end positions int firstY = 0; @@ -11921,7 +11997,9 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent firstY = para->GetPosition().y - 4; } - wxRichTextObjectList::compatibility_iterator node = container->GetChildren().Find(para); + wxRichTextObjectList::compatibility_iterator firstNode = container->GetChildren().Find(para); + wxRichTextObjectList::compatibility_iterator node = firstNode; + wxRichTextObjectList::compatibility_iterator lastNode = NULL; while (node) { wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); @@ -11950,6 +12028,8 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent lastY = pt.y + line->GetSize().y; } + lastNode = node; + node2 = wxRichTextLineList::compatibility_iterator(); node = wxRichTextObjectList::compatibility_iterator(); @@ -11968,6 +12048,8 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent lastY = pt.y + line->GetSize().y; + lastNode = node; + node2 = wxRichTextLineList::compatibility_iterator(); node = wxRichTextObjectList::compatibility_iterator(); @@ -11988,6 +12070,32 @@ void wxRichTextAction::UpdateAppearance(long caretPosition, bool sendUpdateEvent if (!foundEnd) lastY = firstVisiblePt.y + clientSize.y; + if (wxRichTextBuffer::GetFloatingLayoutMode()) + { + if (oldFloatRect.GetBottom() > 0) + lastY = wxMax(lastY, oldFloatRect.GetBottom()); + + // Now find the first paragraph that isn't affected by any floating objects, + // which means the reformatting stopped at this point. + if (lastNode && (container->GetFloatingObjectCount() > 0) && (lastY < lastPossibleY)) + { + wxRichTextObjectList::compatibility_iterator node = lastNode; + while (node) + { + wxRichTextParagraph* child = (wxRichTextParagraph*) node->GetData(); + if (child->GetImpactedByFloatingObjects() == 0) + { + wxRect childRect = child->GetRect(); + if (childRect.GetBottom() > lastY) + lastY = wxMin(childRect.GetBottom(), lastPossibleY); + break; + } + + node = node->GetNext(); + } + } + } + // Convert to device coordinates wxRect rect(m_ctrl->GetPhysicalPoint(m_ctrl->GetScaledPoint(wxPoint(firstVisiblePt.x, firstY))), m_ctrl->GetScaledSize(wxSize(clientSize.x, lastY - firstY))); m_ctrl->RefreshRect(rect); @@ -12127,7 +12235,12 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context m_imageBlock.Load(image); if (!image.IsOk()) + { + wxBitmap bitmap(image_placeholder24x24_xpm); + m_imageCache = bitmap; + m_originalImageSize = wxSize(bitmap.GetWidth(), bitmap.GetHeight()); return false; + } m_originalImageSize = wxSize(image.GetWidth(), image.GetHeight()); } @@ -12154,6 +12267,8 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context { if (buffer) { + // Surely margins will already be accounted for? +#if 0 // Find the actual space available when margin is taken into account wxRect marginRect, borderRect, contentRect, paddingRect, outlineRect; marginRect = wxRect(0, 0, sz.x, sz.y); @@ -12162,7 +12277,7 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context buffer->GetBoxRects(dc, buffer, GetParent()->GetParent()->GetAttributes(), marginRect, borderRect, contentRect, paddingRect, outlineRect); sz = contentRect.GetSize(); } - +#endif // Use a minimum size to stop images becoming very small parentWidth = wxMax(100, sz.GetWidth()); parentHeight = wxMax(100, sz.GetHeight()); @@ -12245,7 +12360,12 @@ bool wxRichTextImage::LoadImageCache(wxDC& dc, wxRichTextDrawingContext& context { m_imageBlock.Load(image); if (!image.IsOk()) + { + wxBitmap bitmap(image_placeholder24x24_xpm); + m_imageCache = bitmap; + m_originalImageSize = wxSize(bitmap.GetWidth(), bitmap.GetHeight()); return false; + } } if (image.GetWidth() == width && image.GetHeight() == height) @@ -12277,7 +12397,7 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx if (!IsShown()) return true; - if (!LoadImageCache(dc, context)) + if (!m_imageCache.IsOk()) return false; wxRichTextAttr attr(GetAttributes()); @@ -12305,9 +12425,9 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx } /// Lay the item out -bool wxRichTextImage::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& WXUNUSED(parentRect), int WXUNUSED(style)) +bool wxRichTextImage::Layout(wxDC& dc, wxRichTextDrawingContext& context, const wxRect& rect, const wxRect& parentRect, int WXUNUSED(style)) { - if (!LoadImageCache(dc, context)) + if (!LoadImageCache(dc, context, false, parentRect.GetSize())) return false; wxSize imageSize(m_imageCache.GetWidth(), m_imageCache.GetHeight());