summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-07-10 12:35:44 +0300
committerXisco Fauli <xiscofauli@libreoffice.org>2021-07-12 13:04:40 +0200
commite7cd1cc648c6e2d1c52d03a3ea390e21edc1f63b (patch)
treec54b97d8404a2a12b2e36694c9a072fe2c72076f /editeng
parentffeeb78118a887419c5f33bb5311f0e2ddae463c (diff)
editengine-columns: tdf#143258 Fix handling rotated text
This reverts modifications to existing unit tests made in commit d0a1616ccad0dd5f5a02c1b0204f537b57d0b4b5. My idea that those changes were required because of more correct calculations was wrong, and in fact they were caused by off-by-1 error in height calculations. Change-Id: Ib94878a911238c977c35a8f8e3e5694cedc79a89 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118705 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118711 Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'editeng')
-rw-r--r--editeng/source/editeng/impedit.cxx9
-rw-r--r--editeng/source/editeng/impedit.hxx14
-rw-r--r--editeng/source/editeng/impedit2.cxx27
-rw-r--r--editeng/source/editeng/impedit3.cxx79
4 files changed, 45 insertions, 84 deletions
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index 22421c226234..63dd7b78cd44 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -575,7 +575,8 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion,
tools::Rectangle aTmpRect(pEditEngine->pImpEditEngine->GetEditCursor(
&rInfo.rPortion, rInfo.pLine, nStartIndex, GetCursorFlags::NONE));
- aTmpRect.Move(0, pEditEngine->pImpEditEngine->getTopDirectionAware(rInfo.aArea));
+ const Size aLineOffset = pEditEngine->pImpEditEngine->getTopLeftDocOffset(rInfo.aArea);
+ aTmpRect.Move(0, aLineOffset.Height());
// Only paint if in the visible range ...
if (aTmpRect.Top() > GetVisDocBottom())
@@ -596,7 +597,7 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion,
= pEditEngine->GetLineXPosStartEnd(&rInfo.rPortion, rInfo.pLine);
aTmpRect.SetLeft(aLineXPosStartEnd.Min());
aTmpRect.SetRight(aLineXPosStartEnd.Max());
- aTmpRect.Move(pEditEngine->pImpEditEngine->getLeftDirectionAware(rInfo.aArea), 0);
+ aTmpRect.Move(aLineOffset.Width(), 0);
ImplDrawHighlightRect(rTarget, aTmpRect.TopLeft(), aTmpRect.BottomRight(),
pPolyPoly.get());
}
@@ -604,8 +605,6 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion,
{
sal_Int32 nTmpStartIndex = nStartIndex;
sal_Int32 nWritingDirStart, nTmpEndIndex;
- const sal_Int32 nLeftOffset
- = pEditEngine->pImpEditEngine->getLeftDirectionAware(rInfo.aArea);
while (nTmpStartIndex < nEndIndex)
{
@@ -623,7 +622,7 @@ void ImpEditView::DrawSelectionXOR( EditSelection aTmpSel, vcl::Region* pRegion,
aTmpRect.SetLeft(std::min(nX1, nX2));
aTmpRect.SetRight(std::max(nX1, nX2));
- aTmpRect.Move(nLeftOffset, 0);
+ aTmpRect.Move(aLineOffset.Width(), 0);
ImplDrawHighlightRect(rTarget, aTmpRect.TopLeft(), aTmpRect.BottomRight(),
pPolyPoly.get());
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 2c17b0882631..b074117dfd58 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -1143,6 +1143,7 @@ public:
EditLine* pLine; // Current line, or nullptr for paragraph start
sal_Int32 nLine;
tools::Rectangle aArea; // The area for the line (or for rPortion's first line offset)
+ // Bottom coordinate *does not* belong to the area
tools::Long nHeightNeededToNotWrap;
};
using IterateLinesAreasFunc = std::function<CallbackResult(const LineAreaInfo&)>;
@@ -1158,20 +1159,17 @@ public:
Point MoveToNextLine(Point& rMovePos, tools::Long nLineHeight, sal_Int32& nColumn,
Point aOrigin, tools::Long* pnHeightNeededToNotWrap = nullptr) const;
- tools::Long getXDirectionAware(const Point& pt) const;
- tools::Long getYDirectionAware(const Point& pt) const;
tools::Long getWidthDirectionAware(const Size& sz) const;
tools::Long getHeightDirectionAware(const Size& sz) const;
void adjustXDirectionAware(Point& pt, tools::Long x) const;
void adjustYDirectionAware(Point& pt, tools::Long y) const;
- void setXDirectionAware(Point& pt, tools::Long x) const;
- void setYDirectionAware(Point& pt, tools::Long y) const;
+ void setXDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const;
+ void setYDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const;
tools::Long getYOverflowDirectionAware(const Point& pt, const tools::Rectangle& rectMax) const;
bool isXOverflowDirectionAware(const Point& pt, const tools::Rectangle& rectMax) const;
- tools::Long getLeftDirectionAware(const tools::Rectangle& rect) const;
- tools::Long getRightDirectionAware(const tools::Rectangle& rect) const;
- tools::Long getTopDirectionAware(const tools::Rectangle& rect) const;
- tools::Long getBottomDirectionAware(const tools::Rectangle& rect) const;
+ // Offset of the rectangle's direction-aware corners in document coordinates
+ tools::Long getBottomDocOffset(const tools::Rectangle& rect) const;
+ Size getTopLeftDocOffset(const tools::Rectangle& rect) const;
};
inline EPaM ImpEditEngine::CreateEPaM( const EditPaM& rPaM )
diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx
index 4bc8a570b9c3..fdc33305fd23 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -569,8 +569,7 @@ bool ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView )
{
tools::Rectangle aR = GetEditCursor(pParaPortion, rInfo.pLine, n,
GetCursorFlags::NONE);
- aR.Move(getLeftDirectionAware(rInfo.aArea),
- getTopDirectionAware(rInfo.aArea));
+ aR.Move(getTopLeftDocOffset(rInfo.aArea));
aRects[n - nMinPos] = pView->GetImpEditView()->GetWindowPos(aR);
}
}
@@ -3100,7 +3099,7 @@ tools::Rectangle ImpEditEngine::PaMtoEditCursor( EditPaM aPaM, GetCursorFlags nF
if (pLastLine)
{
aEditCursor = GetEditCursor(pPortion, pLastLine, nIndex, nFlags);
- aEditCursor.Move(getLeftDirectionAware(aLineArea), getTopDirectionAware(aLineArea));
+ aEditCursor.Move(getTopLeftDocOffset(aLineArea));
}
else
OSL_FAIL("Line not found!");
@@ -3214,6 +3213,8 @@ ImpEditEngine::GetPortionAndLine(Point aDocPos)
const ParaPortion* pLastPortion = nullptr;
const EditLine* pLastLine = nullptr;
tools::Long nLineStartX = 0;
+ Point aPos;
+ adjustYDirectionAware(aPos, aDocPos.Y());
auto FindLastMatchingPortionAndLine = [&](const LineAreaInfo& rInfo) {
if (rInfo.pLine) // Only handle lines, not ParaPortion starts
@@ -3222,8 +3223,8 @@ ImpEditEngine::GetPortionAndLine(Point aDocPos)
return CallbackResult::Stop;
pLastPortion = &rInfo.rPortion; // Candidate paragraph
pLastLine = rInfo.pLine; // Last visible line not later than click position
- nLineStartX = getLeftDirectionAware(rInfo.aArea);
- if (rInfo.nColumn == nClickColumn && getBottomDirectionAware(rInfo.aArea) > aDocPos.Y())
+ nLineStartX = getTopLeftDocOffset(rInfo.aArea).Width();
+ if (rInfo.nColumn == nClickColumn && getYOverflowDirectionAware(aPos, rInfo.aArea) == 0)
return CallbackResult::Stop; // Found it
}
return CallbackResult::Continue;
@@ -3419,7 +3420,8 @@ tools::Long ImpEditEngine::Calc1ColumnTextHeight(tools::Long* pHeightNTP)
auto FindLastLineBottom = [&](const LineAreaInfo& rInfo) {
if (rInfo.pLine)
{
- nHeight = getBottomDirectionAware(rInfo.aArea) + 1;
+ // bottom coordinate does not belong to area, so no need to do +1
+ nHeight = getBottomDocOffset(rInfo.aArea);
if (pHeightNTP && !rInfo.rPortion.IsEmpty())
*pHeightNTP = nHeight;
}
@@ -3442,8 +3444,6 @@ tools::Long ImpEditEngine::CalcTextHeight(tools::Long* pHeightNTP)
tools::Long nTentativeColHeight = mnMinColumnWrapHeight;
tools::Long nWantedIncrease = 0;
tools::Long nCurrentTextHeight;
- if (pHeightNTP)
- *pHeightNTP = 0;
// This does the necessary column balancing for the case when the text does not fit min height.
// When the height of column (taken from nCurTextHeight) is too small, the last column will
@@ -3492,6 +3492,8 @@ tools::Long ImpEditEngine::CalcTextHeight(tools::Long* pHeightNTP)
nTentativeColHeight += nWantedIncrease;
nWantedIncrease = std::numeric_limits<tools::Long>::max();
nCurrentTextHeight = 0;
+ if (pHeightNTP)
+ *pHeightNTP = 0;
auto GetHeightAndWantedIncrease = [&, minHeight = tools::Long(0), lastCol = sal_Int32(0)](
const LineAreaInfo& rInfo) mutable {
if (rInfo.pLine)
@@ -3501,13 +3503,13 @@ tools::Long ImpEditEngine::CalcTextHeight(tools::Long* pHeightNTP)
minHeight = std::max(nCurrentTextHeight,
minHeight); // total height can't be less than previous columns
nWantedIncrease = std::min(rInfo.nHeightNeededToNotWrap, nWantedIncrease);
+ lastCol = rInfo.nColumn;
}
- lastCol = rInfo.nColumn;
- nCurrentTextHeight = std::max(getBottomDirectionAware(rInfo.aArea) + 1, minHeight);
+ // bottom coordinate does not belong to area, so no need to do +1
+ nCurrentTextHeight = std::max(getBottomDocOffset(rInfo.aArea), minHeight);
if (pHeightNTP)
{
if (rInfo.rPortion.IsEmpty())
-
*pHeightNTP = std::max(*pHeightNTP, minHeight);
else
*pHeightNTP = nCurrentTextHeight;
@@ -3517,7 +3519,8 @@ tools::Long ImpEditEngine::CalcTextHeight(tools::Long* pHeightNTP)
};
comphelper::ValueRestorationGuard aGuard(nCurTextHeight, nTentativeColHeight);
IterateLineAreas(GetHeightAndWantedIncrease, IterFlag::none);
- } while (nCurrentTextHeight > nTentativeColHeight && nWantedIncrease > 0);
+ } while (nCurrentTextHeight > nTentativeColHeight && nWantedIncrease > 0
+ && nWantedIncrease != std::numeric_limits<tools::Long>::max());
return nCurrentTextHeight;
}
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index c33db07b2a6b..6294dbe2a905 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -2956,22 +2956,6 @@ void ImpEditEngine::RecalcFormatterFontMetrics( FormatterFontMetric& rCurMetrics
}
}
-tools::Long ImpEditEngine::getXDirectionAware(const Point& pt) const
-{
- if (!IsVertical())
- return pt.X();
- else
- return pt.Y();
-}
-
-tools::Long ImpEditEngine::getYDirectionAware(const Point& pt) const
-{
- if (!IsVertical())
- return pt.Y();
- else
- return pt.X();
-}
-
tools::Long ImpEditEngine::getWidthDirectionAware(const Size& sz) const
{
return !IsVertical() ? sz.Width() : sz.Height();
@@ -2998,20 +2982,20 @@ void ImpEditEngine::adjustYDirectionAware(Point& pt, tools::Long y) const
pt.AdjustX(IsTopToBottom() ? -y : y);
}
-void ImpEditEngine::setXDirectionAware(Point& pt, tools::Long x) const
+void ImpEditEngine::setXDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const
{
if (!IsVertical())
- pt.setX(x);
+ ptDest.setX(ptSrc.X());
else
- pt.setY(x);
+ ptDest.setY(ptSrc.Y());
}
-void ImpEditEngine::setYDirectionAware(Point& pt, tools::Long y) const
+void ImpEditEngine::setYDirectionAwareFrom(Point& ptDest, const Point& ptSrc) const
{
if (!IsVertical())
- pt.setY(y);
+ ptDest.setY(ptSrc.Y());
else
- pt.setX(y);
+ ptDest.setX(ptSrc.Y());
}
tools::Long ImpEditEngine::getYOverflowDirectionAware(const Point& pt,
@@ -3038,48 +3022,26 @@ bool ImpEditEngine::isXOverflowDirectionAware(const Point& pt, const tools::Rect
return pt.Y() < rectMax.Top();
}
-tools::Long ImpEditEngine::getLeftDirectionAware(const tools::Rectangle& rect) const
+tools::Long ImpEditEngine::getBottomDocOffset(const tools::Rectangle& rect) const
{
if (!IsVertical())
- return rect.Left();
-
- if (IsTopToBottom())
- return rect.Top();
- else
return rect.Bottom();
-}
-
-tools::Long ImpEditEngine::getRightDirectionAware(const tools::Rectangle& rect) const
-{
- if (!IsVertical())
- return rect.Right();
if (IsTopToBottom())
- return rect.Bottom();
+ return -rect.Left();
else
- return rect.Top();
-}
-
-tools::Long ImpEditEngine::getTopDirectionAware(const tools::Rectangle& rect) const
-{
- if (!IsVertical())
- return rect.Top();
-
- if (IsTopToBottom())
return rect.Right();
- else
- return rect.Left();
}
-tools::Long ImpEditEngine::getBottomDirectionAware(const tools::Rectangle& rect) const
+Size ImpEditEngine::getTopLeftDocOffset(const tools::Rectangle& rect) const
{
if (!IsVertical())
- return rect.Bottom();
+ return { rect.Left(), rect.Top() };
if (IsTopToBottom())
- return rect.Left();
+ return { rect.Top(), -rect.Right() };
else
- return rect.Right();
+ return { -rect.Bottom(), rect.Left() };
}
// Returns the resulting shift for the point; allows to apply the same shift to other points
@@ -3098,12 +3060,11 @@ Point ImpEditEngine::MoveToNextLine(
// Check if the resulting position has moved beyond the limits, and more columns left.
// The limits are defined by a rectangle starting from aOrigin with width of aPaperSize
// and height of nCurTextHeight
- Size aActPaperSize(aPaperSize);
- if (IsVertical())
- aActPaperSize.setWidth(nCurTextHeight);
- else
- aActPaperSize.setHeight(nCurTextHeight);
- tools::Long nNeeded = getYOverflowDirectionAware(rMovePos, { aOrigin, aActPaperSize });
+ Point aOtherCorner = aOrigin;
+ adjustXDirectionAware(aOtherCorner, getWidthDirectionAware(aPaperSize));
+ adjustYDirectionAware(aOtherCorner, nCurTextHeight);
+ tools::Long nNeeded
+ = getYOverflowDirectionAware(rMovePos, tools::Rectangle::Justify(aOrigin, aOtherCorner));
if (pnHeightNeededToNotWrap)
*pnHeightNeededToNotWrap = nNeeded;
if (nNeeded && rColumn < mnColumns)
@@ -3114,7 +3075,7 @@ Point ImpEditEngine::MoveToNextLine(
if (rColumn < mnColumns)
{
// Set Y position of the point to that of aOrigin
- setYDirectionAware(rMovePos, getYDirectionAware(aOrigin));
+ setYDirectionAwareFrom(rMovePos, aOrigin);
// Move the point by the requested distance in Y direction
adjustYDirectionAware(rMovePos, nLineHeight);
// Move the point by the column+spacing distance in X direction
@@ -3246,7 +3207,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po
const TextPortion& rTextPortion = rPortion.GetTextPortions()[nPortion];
const tools::Long nPortionXOffset = GetPortionXOffset( &rPortion, pLine, nPortion );
- setXDirectionAware(aTmpPos, getXDirectionAware(aStartPos));
+ setXDirectionAwareFrom(aTmpPos, aStartPos);
adjustXDirectionAware(aTmpPos, nPortionXOffset);
if (isXOverflowDirectionAware(aTmpPos, aClipRect))
break; // No further output in line necessary
@@ -3368,7 +3329,7 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Po
const Size aSlashSize = aTmpFont.QuickGetTextSize( &rOutDev, aSlash, 0, 1 );
Point aSlashPos( aTmpPos );
const tools::Long nAddX = nHalfBlankWidth - aSlashSize.Width() / 2;
- setXDirectionAware(aSlashPos, getXDirectionAware(aTopLeftRectPos));
+ setXDirectionAwareFrom(aSlashPos, aTopLeftRectPos);
adjustXDirectionAware(aSlashPos, nAddX);
aTmpFont.QuickDrawText( &rOutDev, aSlashPos, aSlash, 0, 1 );