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-12 00:03:38 +0200
commitfb5b05f92e13c064c0af1009d5597d77c949937f (patch)
treeff78e8d99e2b31fca68fb0c378eaaf35bfaa2f0a /svx
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 '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 504862a64229..07a53a0f55d2 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -57,6 +57,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;
@@ -274,39 +340,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 30552b63fa4d..53d180435e9b 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -2600,11 +2600,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 855e07d4c4af..c20417942c0e 100644
--- a/svx/source/svdraw/svdotext.cxx
+++ b/svx/source/svdraw/svdotext.cxx
@@ -584,26 +584,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 (pEdtOutl)
+ return pEdtOutl->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