summaryrefslogtreecommitdiff
path: root/svx
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-11 08:49:31 +0200
commite09f22aa2626267e01b9e759c152f3a0d70ddc68 (patch)
tree0761a9acb878c12e30d3747f56dcaab2ffdc2af3 /svx
parent4450137924eb8626a57283e1ab4f4ad62dd2d595 (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>
Diffstat (limited to 'svx')
-rw-r--r--svx/source/sdr/primitive2d/sdrdecompositiontools.cxx101
-rw-r--r--svx/source/svdraw/svdoashp.cxx6
-rw-r--r--svx/source/svdraw/svdotext.cxx58
3 files changed, 115 insertions, 50 deletions
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 35e410b8fbfd..dcff748ea60f 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -56,6 +56,72 @@ using namespace com::sun::star;
namespace drawinglayer::primitive2d
{
+namespace
+{
+// See also: SdrTextObj::AdjustRectToTextDistance
+basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText,
+ const basegfx::B2DRange& rSnapRange)
+{
+ // Take vertical text orientation into account when deciding
+ // which dimension is its width, and which is its height
+ const OutlinerParaObject& rOutlinerParaObj = rText.getOutlinerParaObject();
+ const bool bVerticalWriting(rOutlinerParaObj.IsVertical());
+ const double fWidthForText = bVerticalWriting ? rSnapRange.getHeight() : rSnapRange.getWidth();
+ // create a range describing the wanted text position and size (aTextAnchorRange). This
+ // means to use the text distance values here
+ // If the margin is larger than the entire width of the text area, then limit the
+ // margin.
+ const double fTextLeftDistance
+ = std::min(static_cast<double>(rText.getTextLeftDistance()), fWidthForText);
+ const double nTextRightDistance
+ = std::min(static_cast<double>(rText.getTextRightDistance()), fWidthForText);
+ double fDistanceForTextL, fDistanceForTextT, fDistanceForTextR, fDistanceForTextB;
+ if (!bVerticalWriting)
+ {
+ fDistanceForTextL = fTextLeftDistance;
+ fDistanceForTextT = rText.getTextUpperDistance();
+ fDistanceForTextR = nTextRightDistance;
+ fDistanceForTextB = rText.getTextLowerDistance();
+ }
+ else if (rOutlinerParaObj.IsTopToBottom())
+ {
+ fDistanceForTextL = rText.getTextLowerDistance();
+ fDistanceForTextT = fTextLeftDistance;
+ fDistanceForTextR = rText.getTextUpperDistance();
+ fDistanceForTextB = nTextRightDistance;
+ }
+ else
+ {
+ fDistanceForTextL = rText.getTextUpperDistance();
+ fDistanceForTextT = nTextRightDistance;
+ fDistanceForTextR = rText.getTextLowerDistance();
+ fDistanceForTextB = fTextLeftDistance;
+ }
+ const basegfx::B2DPoint aTopLeft(rSnapRange.getMinX() + fDistanceForTextL,
+ rSnapRange.getMinY() + fDistanceForTextT);
+ const basegfx::B2DPoint aBottomRight(rSnapRange.getMaxX() - fDistanceForTextR,
+ rSnapRange.getMaxY() - fDistanceForTextB);
+ basegfx::B2DRange aAnchorRange;
+ aAnchorRange.expand(aTopLeft);
+ aAnchorRange.expand(aBottomRight);
+
+ // If the shape has no width, then don't attempt to break the text into multiple
+ // lines, not a single character would satisfy a zero width requirement.
+ // SdrTextObj::impDecomposeBlockTextPrimitive() uses the same constant to
+ // effectively set no limits.
+ if (!bVerticalWriting && aAnchorRange.getWidth() == 0)
+ {
+ aAnchorRange.expand(basegfx::B2DPoint(aTopLeft.getX() - 1000000, aTopLeft.getY()));
+ aAnchorRange.expand(basegfx::B2DPoint(aBottomRight.getX() + 1000000, aBottomRight.getY()));
+ }
+ else if (bVerticalWriting && aAnchorRange.getHeight() == 0)
+ {
+ aAnchorRange.expand(basegfx::B2DPoint(aTopLeft.getX(), aTopLeft.getY() - 1000000));
+ aAnchorRange.expand(basegfx::B2DPoint(aBottomRight.getX(), aBottomRight.getY() + 1000000));
+ }
+ return aAnchorRange;
+}
+};
class TransparencePrimitive2D;
@@ -270,39 +336,8 @@ namespace drawinglayer::primitive2d
aJustScaleTransform.set(1, 1, aScale.getY());
basegfx::B2DPolyPolygon aScaledUnitPolyPolygon(rUnitPolyPolygon);
aScaledUnitPolyPolygon.transform(aJustScaleTransform);
- const basegfx::B2DRange aSnapRange(basegfx::utils::getRange(aScaledUnitPolyPolygon));
-
- // create a range describing the wanted text position and size (aTextAnchorRange). This
- // means to use the text distance values here
- sal_Int32 nTextLeftDistance = rText.getTextLeftDistance();
- // If the margin is larger than the entire width of the text area, then limit the
- // margin.
- if (nTextLeftDistance > aSnapRange.getWidth())
- nTextLeftDistance = aSnapRange.getWidth();
- sal_Int32 nTextRightDistance = rText.getTextRightDistance();
- if (nTextRightDistance > aSnapRange.getWidth())
- nTextRightDistance = aSnapRange.getWidth();
- const basegfx::B2DPoint aTopLeft(aSnapRange.getMinX() + nTextLeftDistance,
- aSnapRange.getMinY()
- + rText.getTextUpperDistance());
- const basegfx::B2DPoint aBottomRight(aSnapRange.getMaxX() - nTextRightDistance,
- aSnapRange.getMaxY()
- - rText.getTextLowerDistance());
- basegfx::B2DRange aTextAnchorRange;
- aTextAnchorRange.expand(aTopLeft);
- aTextAnchorRange.expand(aBottomRight);
-
- if (aTextAnchorRange.getWidth() == 0)
- {
- // If the shape has no width, then don't attempt to break the text into multiple
- // lines, not a single character would satisfy a zero width requirement.
- // SdrTextObj::impDecomposeBlockTextPrimitive() uses the same constant to
- // effectively set no limits.
- aTextAnchorRange.expand(
- basegfx::B2DPoint(aTopLeft.getX() - 1000000, aTopLeft.getY()));
- aTextAnchorRange.expand(
- basegfx::B2DPoint(aBottomRight.getX() + 1000000, aBottomRight.getY()));
- }
+ const basegfx::B2DRange aTextAnchorRange
+ = getTextAnchorRange(rText, basegfx::utils::getRange(aScaledUnitPolyPolygon));
// now create a transformation from this basic range (aTextAnchorRange)
// #i121494# if we have no scale use at least 1.0 to have a carrier e.g. for
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 259855c09935..b5d028b7315f 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -2609,11 +2609,7 @@ void SdrObjCustomShape::TakeTextAnchorRect( tools::Rectangle& rAnchorRect ) cons
if ( GetTextBounds( rAnchorRect ) )
{
Point aRotateRef( maSnapRect.Center() );
- rAnchorRect.AdjustLeft(GetTextLeftDistance() );
- rAnchorRect.AdjustTop(GetTextUpperDistance() );
- rAnchorRect.AdjustRight( -(GetTextRightDistance()) );
- rAnchorRect.AdjustBottom( -(GetTextLowerDistance()) );
- ImpJustifyRect( rAnchorRect );
+ AdjustRectToTextDistance(rAnchorRect);
if ( rAnchorRect.GetWidth() < 2 )
rAnchorRect.SetRight( rAnchorRect.Left() + 1 ); // minimal width is 2
diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx
index d3377570398e..41dbe69be174 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -634,26 +634,49 @@ void SdrTextObj::TakeUnrotatedSnapRect(tools::Rectangle& rRect) const
rRect=maRect;
}
+// See also: <unnamed>::getTextAnchorRange in svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+void SdrTextObj::AdjustRectToTextDistance(tools::Rectangle& rAnchorRect) const
+{
+ const tools::Long nLeftDist = GetTextLeftDistance();
+ const tools::Long nRightDist = GetTextRightDistance();
+ const tools::Long nUpperDist = GetTextUpperDistance();
+ const tools::Long nLowerDist = GetTextLowerDistance();
+ if (!IsVerticalWriting())
+ {
+ rAnchorRect.AdjustLeft(nLeftDist);
+ rAnchorRect.AdjustTop(nUpperDist);
+ rAnchorRect.AdjustRight(-nRightDist);
+ rAnchorRect.AdjustBottom(-nLowerDist);
+ }
+ else if (IsTopToBottom())
+ {
+ rAnchorRect.AdjustLeft(nLowerDist);
+ rAnchorRect.AdjustTop(nLeftDist);
+ rAnchorRect.AdjustRight(-nUpperDist);
+ rAnchorRect.AdjustBottom(-nRightDist);
+ }
+ else
+ {
+ rAnchorRect.AdjustLeft(nUpperDist);
+ rAnchorRect.AdjustTop(nRightDist);
+ rAnchorRect.AdjustRight(-nLowerDist);
+ rAnchorRect.AdjustBottom(-nLeftDist);
+ }
+
+ // Since sizes may be bigger than the object bounds it is necessary to
+ // justify the rect now.
+ ImpJustifyRect(rAnchorRect);
+}
+
void SdrTextObj::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const
{
- tools::Long nLeftDist=GetTextLeftDistance();
- tools::Long nRightDist=GetTextRightDistance();
- tools::Long nUpperDist=GetTextUpperDistance();
- tools::Long nLowerDist=GetTextLowerDistance();
tools::Rectangle aAnkRect(maRect); // the rectangle in which we anchor
bool bFrame=IsTextFrame();
if (!bFrame) {
TakeUnrotatedSnapRect(aAnkRect);
}
Point aRotateRef(aAnkRect.TopLeft());
- aAnkRect.AdjustLeft(nLeftDist );
- aAnkRect.AdjustTop(nUpperDist );
- aAnkRect.AdjustRight( -nRightDist );
- aAnkRect.AdjustBottom( -nLowerDist );
-
- // Since sizes may be bigger than the object bounds it is necessary to
- // justify the rect now.
- ImpJustifyRect(aAnkRect);
+ AdjustRectToTextDistance(aAnkRect);
if (bFrame) {
// TODO: Optimize this.
@@ -1525,6 +1548,17 @@ void SdrTextObj::SetVerticalWriting(bool bVertical)
SetSnapRect(aObjectRect);
}
+bool SdrTextObj::IsTopToBottom() const
+{
+ if (mpEdtOutl)
+ return mpEdtOutl->IsTopToBottom();
+
+ if (OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject())
+ return pOutlinerParaObject->IsTopToBottom();
+
+ return false;
+}
+
// transformation interface for StarOfficeAPI. This implements support for
// homogeneous 3x3 matrices containing the transformation of the SdrObject. At the
// moment it contains a shearX, rotation and translation, but for setting all linear