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:
Julian Smart 2012-05-07 13:13:30 +00:00
parent 37424888b8
commit a70eb13eb2

View File

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