summaryrefslogtreecommitdiff
path: root/editeng
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2021-07-10 12:35:44 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2021-07-12 00:03:38 +0200
commitfb5b05f92e13c064c0af1009d5597d77c949937f (patch)
treeff78e8d99e2b31fca68fb0c378eaaf35bfaa2f0a /editeng
parent73c20715c10049d6203f4c9f8a279af80dd58dd9 (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/+/118732 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
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 00e278316d89..8cee20102c0a 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -570,7 +570,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())
@@ -591,7 +592,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(pTarget, aTmpRect.TopLeft(), aTmpRect.BottomRight(),
pPolyPoly.get());
}
@@ -599,8 +600,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)
{
@@ -618,7 +617,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(pTarget, aTmpRect.TopLeft(), aTmpRect.BottomRight(),
pPolyPoly.get());
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 5a0162e0edd0..0e280835480f 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -1146,6 +1146,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&)>;
@@ -1161,20 +1162,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 ff080b1444dd..7e5ee3832f44 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -567,8 +567,7 @@ void 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);
}
}
@@ -3126,7 +3125,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!");
@@ -3240,6 +3239,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
@@ -3248,8 +3249,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;
@@ -3446,7 +3447,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;
}
@@ -3469,8 +3471,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
@@ -3519,6 +3519,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)
@@ -3528,13 +3530,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;
@@ -3544,7 +3546,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 e74958031a96..4680889423d8 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -2957,22 +2957,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();
@@ -2999,20 +2983,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,
@@ -3039,48 +3023,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
@@ -3099,12 +3061,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)
@@ -3115,7 +3076,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
@@ -3251,7 +3212,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, tools::Rectangle aClipRect, Po
const TextPortion& rTextPortion = pPortion->GetTextPortions()[nPortion];
tools::Long nPortionXOffset = GetPortionXOffset( pPortion, pLine, nPortion );
- setXDirectionAware(aTmpPos, getXDirectionAware(aStartPos));
+ setXDirectionAwareFrom(aTmpPos, aStartPos);
adjustXDirectionAware(aTmpPos, nPortionXOffset);
if (isXOverflowDirectionAware(aTmpPos, aClipRect))
break; // No further output in line necessary
@@ -3373,7 +3334,7 @@ void ImpEditEngine::Paint( OutputDevice* pOutDev, tools::Rectangle aClipRect, Po
const Size aSlashSize = aTmpFont.QuickGetTextSize( pOutDev, 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( pOutDev, aSlashPos, aSlash, 0, 1 );