summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/xmloff/txtparae.hxx6
-rw-r--r--xmloff/source/text/XMLTextFrameContext.cxx17
-rw-r--r--xmloff/source/text/txtparae.cxx57
3 files changed, 68 insertions, 12 deletions
diff --git a/include/xmloff/txtparae.hxx b/include/xmloff/txtparae.hxx
index c62a25d0b6f3..6e65e1082e03 100644
--- a/include/xmloff/txtparae.hxx
+++ b/include/xmloff/txtparae.hxx
@@ -64,6 +64,11 @@ namespace xmloff
}
+namespace basegfx
+{
+ class B2DPoint;
+}
+
enum class TextPNS
{
ODF,
@@ -253,6 +258,7 @@ protected:
XMLShapeExportFlags addTextFrameAttributes(
const css::uno::Reference< css::beans::XPropertySet >& rPropSet,
bool bShape,
+ basegfx::B2DPoint* pCenter = nullptr,
OUString *pMinHeightValue = nullptr,
OUString *pMinWidthValue = nullptr );
diff --git a/xmloff/source/text/XMLTextFrameContext.cxx b/xmloff/source/text/XMLTextFrameContext.cxx
index bad29d974fa3..f286d6468622 100644
--- a/xmloff/source/text/XMLTextFrameContext.cxx
+++ b/xmloff/source/text/XMLTextFrameContext.cxx
@@ -990,7 +990,7 @@ XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
SdXMLImExTransform2D aSdXMLImExTransform2D;
basegfx::B2DHomMatrix aFullTransform;
- // use SdXMLImExTransform2D to convert to transformation
+ // Use SdXMLImExTransform2D to convert to transformation
// Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
// but is not generally available (as it should be, a 'current' UnitConverter should
// be available at GetExport() - and maybe was once). May have to be addressed as soon
@@ -1002,13 +1002,22 @@ XMLTextFrameContext_Impl::XMLTextFrameContext_Impl(
{
const basegfx::utils::B2DHomMatrixBufferedDecompose aDecomposedTransform(aFullTransform);
- // currently we *only* use rotation, so warn if *any* of the other transform parts is used
+ // currently we *only* use rotation (and translation indirectly), so warn if *any*
+ // of the other transform parts is used
SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform.getScale().getX()), "xmloff.text", "draw:transform uses scaleX" );
SAL_WARN_IF(!basegfx::fTools::equal(1.0, aDecomposedTransform.getScale().getY()), "xmloff.text", "draw:transform uses scaleY" );
- SAL_WARN_IF(!basegfx::fTools::equalZero(aDecomposedTransform.getTranslate().getX()), "xmloff.text", "draw:transform uses translateX" );
- SAL_WARN_IF(!basegfx::fTools::equalZero(aDecomposedTransform.getTranslate().getY()), "xmloff.text", "draw:transform uses translateY" );
SAL_WARN_IF(!basegfx::fTools::equalZero(aDecomposedTransform.getShearX()), "xmloff.text", "draw:transform uses shearX" );
+ // Translation comes from the translate to RotCenter, rot and BackTranslate.
+ // This means that it represents the translation between unrotated TopLeft
+ // and rotated TopLeft. This may be checked here now, but currently we only
+ // use rotation around center and assume that this *was* a rotation around
+ // center. The check would compare the object's center with the RotCenter
+ // that can be extracted from the transformation in aFullTransform.
+ // The definition contains implicitely the RotationCenter absolute
+ // to the scaled and translated object, so this may be used if needed (see
+ // _exportTextGraphic how the -trans/rot/trans is composed)
+
if(!basegfx::fTools::equalZero(aDecomposedTransform.getRotate()))
{
// rotation is used, set it. Convert from deg to 10th degree integer
diff --git a/xmloff/source/text/txtparae.cxx b/xmloff/source/text/txtparae.cxx
index 6398990ff5d7..234fb48c2b2d 100644
--- a/xmloff/source/text/txtparae.cxx
+++ b/xmloff/source/text/txtparae.cxx
@@ -2529,8 +2529,9 @@ static bool lcl_txtpara_isBoundAsChar(
XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes(
const Reference < XPropertySet >& rPropSet,
bool bShape,
- OUString *pMinHeightValue,
- OUString *pMinWidthValue)
+ basegfx::B2DPoint* pCenter,
+ OUString* pMinHeightValue,
+ OUString* pMinWidthValue)
{
XMLShapeExportFlags nShapeFeatures = SEF_DEFAULT;
@@ -2592,6 +2593,11 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes(
sValue, nPos );
GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_X,
sValue.makeStringAndClear() );
+ if(nullptr != pCenter)
+ {
+ // add left edge to Center
+ pCenter->setX(pCenter->getX() + nPos);
+ }
}
}
else if( TextContentAnchorType_AS_CHARACTER == eAnchor )
@@ -2610,6 +2616,11 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes(
sValue, nPos );
GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_Y,
sValue.makeStringAndClear() );
+ if(nullptr != pCenter)
+ {
+ // add top edge to Center
+ pCenter->setY(pCenter->getY() + nPos);
+ }
}
if( bShape )
nShapeFeatures = (nShapeFeatures & ~XMLShapeExportFlags::Y);
@@ -2641,8 +2652,15 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes(
}
}
else
+ {
GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_WIDTH,
sValue.makeStringAndClear() );
+ if(nullptr != pCenter)
+ {
+ // add half width to Center
+ pCenter->setX(pCenter->getX() + (0.5 * nWidth));
+ }
+ }
}
bool bSyncWidth = false;
if( xPropSetInfo->hasPropertyByName( sIsSyncWidthToHeight ) )
@@ -2693,10 +2711,19 @@ XMLShapeExportFlags XMLTextParagraphExport::addTextFrameAttributes(
nHeight );
if( SizeType::FIX != nSizeType && 0==nRelHeight && !bSyncHeight &&
pMinHeightValue )
+ {
*pMinHeightValue = sValue.makeStringAndClear();
+ }
else
+ {
GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_HEIGHT,
sValue.makeStringAndClear() );
+ if(nullptr != pCenter)
+ {
+ // add half height to Center
+ pCenter->setY(pCenter->getY() + (0.5 * nHeight));
+ }
+ }
}
if( bSyncHeight )
{
@@ -2869,7 +2896,7 @@ void XMLTextParagraphExport::_exportTextFrame(
if( !sAutoStyle.isEmpty() )
GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_STYLE_NAME,
GetExport().EncodeStyleName( sAutoStyle ) );
- addTextFrameAttributes(rPropSet, false, &aMinHeightValue, &sMinWidthValue);
+ addTextFrameAttributes(rPropSet, false, nullptr, &aMinHeightValue, &sMinWidthValue);
SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_DRAW,
XML_FRAME, false, true );
@@ -3029,12 +3056,19 @@ void XMLTextParagraphExport::_exportTextGraphic(
if( !sAutoStyle.isEmpty() )
GetExport().AddAttribute( XML_NAMESPACE_DRAW, XML_STYLE_NAME,
GetExport().EncodeStyleName( sAutoStyle ) );
- addTextFrameAttributes( rPropSet, false );
+
+ // check if we need to use svg:transform
+ sal_Int16 nRotation(0);
+ rPropSet->getPropertyValue( sGraphicRotation ) >>= nRotation;
+ const bool bUseRotation(0 != nRotation);
+ basegfx::B2DPoint aCenter(0.0, 0.0);
+
+ // add TextFrame attributes like svg:x/y/width/height, also get back
+ // object's center point if rotation is used and has to be exported
+ addTextFrameAttributes(rPropSet, false, bUseRotation ? &aCenter : nullptr);
// svg:transform
- sal_Int16 nVal = 0;
- rPropSet->getPropertyValue( sGraphicRotation ) >>= nVal;
- if( nVal != 0 )
+ if(bUseRotation)
{
// RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling.
// Currently only rotation is used, but combinations with 'draw:transform'
@@ -3047,10 +3081,17 @@ void XMLTextParagraphExport::_exportTextGraphic(
// we have a right-handed coordinate system, so need to correct this by mirroring
// the rotation to get the correct transformation. See also case XML_TOK_TEXT_FRAME_TRANSFORM
// in XMLTextFrameContext_Impl::XMLTextFrameContext_Impl and #i78696#
- const double fRotate(static_cast< double >(-nVal) * (M_PI/1800.0));
+ const double fRotate(static_cast< double >(-nRotation) * (M_PI/1800.0));
+ // transform to rotation center which is the object's center
+ aSdXMLImExTransform2D.AddTranslate(-aCenter);
+
+ // add rotation itself
aSdXMLImExTransform2D.AddRotate(fRotate);
+ // back-transform after rotation
+ aSdXMLImExTransform2D.AddTranslate(aCenter);
+
// Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
// but is not generally available (as it should be, a 'current' UnitConverter should
// be available at GetExport() - and maybe was once). May have to be addressed as soon