Fixed inconsistent calculation of line height in paragraph layout
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71376 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
37424888b8
commit
a70eb13eb2
@ -4729,9 +4729,19 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
|
|||||||
// buffer, so we may have different available line widths with different
|
// buffer, so we may have different available line widths with different
|
||||||
// [startY, endY]. So, we can't determine how wide the available
|
// [startY, endY]. So, we can't determine how wide the available
|
||||||
// space is until we know the exact line height.
|
// space is until we know the exact line height.
|
||||||
lineDescent = wxMax(childDescent, maxDescent);
|
if (childDescent == 0)
|
||||||
lineAscent = wxMax(childSize.y-childDescent, maxAscent);
|
{
|
||||||
lineHeight = lineDescent + lineAscent;
|
lineHeight = wxMax(lineHeight, childSize.y);
|
||||||
|
lineDescent = maxDescent;
|
||||||
|
lineAscent = maxAscent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lineDescent = wxMax(childDescent, maxDescent);
|
||||||
|
lineAscent = wxMax(childSize.y-childDescent, maxAscent);
|
||||||
|
}
|
||||||
|
lineHeight = wxMax(lineHeight, (lineDescent + lineAscent));
|
||||||
|
|
||||||
wxRect floatAvailableRect = collector->GetAvailableRect(rect.y + currentPosition.y, rect.y + currentPosition.y + lineHeight);
|
wxRect floatAvailableRect = collector->GetAvailableRect(rect.y + currentPosition.y, rect.y + currentPosition.y + lineHeight);
|
||||||
|
|
||||||
// Adjust availableRect to the space that is available when taking floating objects into account.
|
// Adjust availableRect to the space that is available when taking floating objects into account.
|
||||||
@ -4833,9 +4843,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
|
|||||||
wxSize actualSize;
|
wxSize actualSize;
|
||||||
wxRichTextRange actualRange(lastCompletedEndPos+1, wrapPosition);
|
wxRichTextRange actualRange(lastCompletedEndPos+1, wrapPosition);
|
||||||
|
|
||||||
/// Use previous descent, not the wrapping descent we just found, since this may be too big
|
childDescent = 0;
|
||||||
/// for the fragment we're about to add.
|
|
||||||
childDescent = maxDescent;
|
|
||||||
|
|
||||||
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
|
#if wxRICHTEXT_USE_PARTIAL_TEXT_EXTENTS
|
||||||
if (!child->IsEmpty())
|
if (!child->IsEmpty())
|
||||||
@ -4849,9 +4857,15 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
|
|||||||
GetRangeSize(actualRange, actualSize, childDescent, dc, context, wxRICHTEXT_UNFORMATTED);
|
GetRangeSize(actualRange, actualSize, childDescent, dc, context, wxRICHTEXT_UNFORMATTED);
|
||||||
|
|
||||||
currentWidth = actualSize.x;
|
currentWidth = actualSize.x;
|
||||||
maxDescent = wxMax(childDescent, maxDescent);
|
|
||||||
maxAscent = wxMax(actualSize.y-childDescent, maxAscent);
|
// The descent for the whole line at this point, is the correct max descent
|
||||||
lineHeight = maxDescent + maxAscent;
|
maxDescent = childDescent;
|
||||||
|
// Maximum ascent
|
||||||
|
maxAscent = actualSize.y-childDescent;
|
||||||
|
|
||||||
|
// lineHeight is given by the height for the whole line, since it will
|
||||||
|
// take into account ascend/descend.
|
||||||
|
lineHeight = actualSize.y;
|
||||||
|
|
||||||
if (lineHeight == 0 && buffer)
|
if (lineHeight == 0 && buffer)
|
||||||
{
|
{
|
||||||
@ -4887,7 +4901,7 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
|
|||||||
|
|
||||||
lineCount ++;
|
lineCount ++;
|
||||||
|
|
||||||
// TODO: account for zero-length objects, such as fields
|
// TODO: account for zero-length objects
|
||||||
// wxASSERT(wrapPosition > lastCompletedEndPos);
|
// wxASSERT(wrapPosition > lastCompletedEndPos);
|
||||||
|
|
||||||
lastEndPos = wrapPosition;
|
lastEndPos = wrapPosition;
|
||||||
@ -4914,9 +4928,20 @@ bool wxRichTextParagraph::Layout(wxDC& dc, wxRichTextDrawingContext& context, co
|
|||||||
{
|
{
|
||||||
// We still fit, so don't add a line, and keep going
|
// We still fit, so don't add a line, and keep going
|
||||||
currentWidth += childSize.x;
|
currentWidth += childSize.x;
|
||||||
maxDescent = wxMax(childDescent, maxDescent);
|
|
||||||
maxAscent = wxMax(childSize.y-childDescent, maxAscent);
|
if (childDescent == 0)
|
||||||
lineHeight = maxDescent + maxAscent;
|
{
|
||||||
|
// An object with a zero descend value wants to take up the whole
|
||||||
|
// height regardless of baseline
|
||||||
|
lineHeight = wxMax(lineHeight, childSize.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxDescent = wxMax(childDescent, maxDescent);
|
||||||
|
maxAscent = wxMax(childSize.y-childDescent, maxAscent);
|
||||||
|
}
|
||||||
|
|
||||||
|
lineHeight = wxMax(lineHeight, (maxDescent + maxAscent));
|
||||||
|
|
||||||
maxWidth = wxMax(maxWidth, currentWidth+startOffset);
|
maxWidth = wxMax(maxWidth, currentWidth+startOffset);
|
||||||
lastEndPos = child->GetRange().GetEnd();
|
lastEndPos = child->GetRange().GetEnd();
|
||||||
@ -5137,8 +5162,6 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
if (flags & wxRICHTEXT_UNFORMATTED)
|
if (flags & wxRICHTEXT_UNFORMATTED)
|
||||||
{
|
{
|
||||||
// Just use unformatted data, assume no line breaks
|
// Just use unformatted data, assume no line breaks
|
||||||
// TODO: take into account line breaks
|
|
||||||
|
|
||||||
wxSize sz;
|
wxSize sz;
|
||||||
|
|
||||||
wxArrayInt childExtents;
|
wxArrayInt childExtents;
|
||||||
@ -5148,6 +5171,10 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
else
|
else
|
||||||
p = NULL;
|
p = NULL;
|
||||||
|
|
||||||
|
int maxDescent = 0;
|
||||||
|
int maxAscent = 0;
|
||||||
|
int maxLineHeight = 0;
|
||||||
|
|
||||||
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
|
wxRichTextObjectList::compatibility_iterator node = m_children.GetFirst();
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
@ -5175,10 +5202,6 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
|
|
||||||
wxRichTextRange rangeToUse = range;
|
wxRichTextRange rangeToUse = range;
|
||||||
rangeToUse.LimitTo(child->GetRange());
|
rangeToUse.LimitTo(child->GetRange());
|
||||||
#if 0
|
|
||||||
if (child->IsTopLevel())
|
|
||||||
rangeToUse = child->GetOwnRange();
|
|
||||||
#endif
|
|
||||||
int childDescent = 0;
|
int childDescent = 0;
|
||||||
|
|
||||||
// At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're already cached the size,
|
// At present wxRICHTEXT_HEIGHT_ONLY is only fast if we're already cached the size,
|
||||||
@ -5188,23 +5211,52 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
childDescent = child->GetDescent();
|
childDescent = child->GetDescent();
|
||||||
childSize = child->GetCachedSize();
|
childSize = child->GetCachedSize();
|
||||||
|
|
||||||
sz.y = wxMax(sz.y, childSize.y);
|
if (childDescent == 0)
|
||||||
|
{
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, childSize.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxDescent = wxMax(maxDescent, childDescent);
|
||||||
|
maxAscent = wxMax(maxAscent, (childSize.y - childDescent));
|
||||||
|
}
|
||||||
|
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent));
|
||||||
|
|
||||||
|
sz.y = wxMax(sz.y, maxLineHeight);
|
||||||
sz.x += childSize.x;
|
sz.x += childSize.x;
|
||||||
descent = wxMax(descent, childDescent);
|
descent = maxDescent;
|
||||||
}
|
}
|
||||||
else if (child->IsTopLevel())
|
else if (child->IsTopLevel())
|
||||||
{
|
{
|
||||||
childDescent = child->GetDescent();
|
childDescent = child->GetDescent();
|
||||||
childSize = child->GetCachedSize();
|
childSize = child->GetCachedSize();
|
||||||
|
|
||||||
sz.y = wxMax(sz.y, childSize.y);
|
if (childDescent == 0)
|
||||||
|
{
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, childSize.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxDescent = wxMax(maxDescent, childDescent);
|
||||||
|
maxAscent = wxMax(maxAscent, (childSize.y - childDescent));
|
||||||
|
}
|
||||||
|
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent));
|
||||||
|
|
||||||
|
sz.y = wxMax(sz.y, maxLineHeight);
|
||||||
sz.x += childSize.x;
|
sz.x += childSize.x;
|
||||||
descent = wxMax(descent, childDescent);
|
descent = maxDescent;
|
||||||
|
|
||||||
|
// FIXME: this won't change the original values.
|
||||||
|
// Should we be calling GetRangeSize above instead of using cached values?
|
||||||
|
#if 0
|
||||||
if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange()))
|
if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange()))
|
||||||
{
|
{
|
||||||
child->SetCachedSize(childSize);
|
child->SetCachedSize(childSize);
|
||||||
child->SetDescent(childDescent);
|
child->SetDescent(childDescent);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (partialExtents)
|
if (partialExtents)
|
||||||
{
|
{
|
||||||
@ -5219,9 +5271,21 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
}
|
}
|
||||||
else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y), p))
|
else if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y), p))
|
||||||
{
|
{
|
||||||
sz.y = wxMax(sz.y, childSize.y);
|
if (childDescent == 0)
|
||||||
|
{
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, childSize.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxDescent = wxMax(maxDescent, childDescent);
|
||||||
|
maxAscent = wxMax(maxAscent, (childSize.y - childDescent));
|
||||||
|
}
|
||||||
|
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent));
|
||||||
|
|
||||||
|
sz.y = wxMax(sz.y, maxLineHeight);
|
||||||
sz.x += childSize.x;
|
sz.x += childSize.x;
|
||||||
descent = wxMax(descent, childDescent);
|
descent = maxDescent;
|
||||||
|
|
||||||
if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange()))
|
if ((flags & wxRICHTEXT_CACHE_SIZE) && (rangeToUse == child->GetRange()))
|
||||||
{
|
{
|
||||||
@ -5273,7 +5337,10 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
wxRichTextRange lineRange = line->GetAbsoluteRange();
|
wxRichTextRange lineRange = line->GetAbsoluteRange();
|
||||||
if (!lineRange.IsOutside(range))
|
if (!lineRange.IsOutside(range))
|
||||||
{
|
{
|
||||||
wxSize lineSize;
|
int maxDescent = 0;
|
||||||
|
int maxAscent = 0;
|
||||||
|
int maxLineHeight = 0;
|
||||||
|
int maxLineWidth = 0;
|
||||||
|
|
||||||
wxRichTextObjectList::compatibility_iterator node2 = m_children.GetFirst();
|
wxRichTextObjectList::compatibility_iterator node2 = m_children.GetFirst();
|
||||||
while (node2)
|
while (node2)
|
||||||
@ -5291,8 +5358,20 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
int childDescent = 0;
|
int childDescent = 0;
|
||||||
if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y)))
|
if (child->GetRangeSize(rangeToUse, childSize, childDescent, dc, context, flags, wxPoint(position.x + sz.x, position.y)))
|
||||||
{
|
{
|
||||||
lineSize.y = wxMax(lineSize.y, childSize.y);
|
if (childDescent == 0)
|
||||||
lineSize.x += childSize.x;
|
{
|
||||||
|
// Assume that if descent is zero, this child can occupy the full line height
|
||||||
|
// and does not need space for the line's maximum descent. So we influence
|
||||||
|
// the overall max line height only.
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, childSize.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxAscent = wxMax(maxAscent, (childSize.y - childDescent));
|
||||||
|
maxDescent = wxMax(maxAscent, childDescent);
|
||||||
|
}
|
||||||
|
maxLineHeight = wxMax(maxLineHeight, (maxAscent + maxDescent));
|
||||||
|
maxLineWidth += childSize.x;
|
||||||
}
|
}
|
||||||
descent = wxMax(descent, childDescent);
|
descent = wxMax(descent, childDescent);
|
||||||
}
|
}
|
||||||
@ -5300,9 +5379,11 @@ bool wxRichTextParagraph::GetRangeSize(const wxRichTextRange& range, wxSize& siz
|
|||||||
node2 = node2->GetNext();
|
node2 = node2->GetNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descent = wxMax(descent, maxDescent);
|
||||||
|
|
||||||
// Increase size by a line (TODO: paragraph spacing)
|
// Increase size by a line (TODO: paragraph spacing)
|
||||||
sz.y += lineSize.y;
|
sz.y += maxLineHeight;
|
||||||
sz.x = wxMax(sz.x, lineSize.x);
|
sz.x = wxMax(sz.x, maxLineWidth);
|
||||||
}
|
}
|
||||||
node = node->GetNext();
|
node = node->GetNext();
|
||||||
}
|
}
|
||||||
@ -10281,7 +10362,7 @@ bool wxRichTextImage::Draw(wxDC& dc, wxRichTextDrawingContext& context, const wx
|
|||||||
|
|
||||||
dc.DrawBitmap(m_imageCache, contentRect.x, contentRect.y, true);
|
dc.DrawBitmap(m_imageCache, contentRect.x, contentRect.y, true);
|
||||||
|
|
||||||
if (selection.WithinSelection(range.GetStart(), this))
|
if (selection.WithinSelection(GetRange().GetStart(), this))
|
||||||
{
|
{
|
||||||
wxCheckSetBrush(dc, *wxBLACK_BRUSH);
|
wxCheckSetBrush(dc, *wxBLACK_BRUSH);
|
||||||
wxCheckSetPen(dc, *wxBLACK_PEN);
|
wxCheckSetPen(dc, *wxBLACK_PEN);
|
||||||
|
Loading…
Reference in New Issue
Block a user