diff options
-rw-r--r-- | include/xmloff/txtparae.hxx | 6 | ||||
-rw-r--r-- | xmloff/source/text/XMLTextFrameContext.cxx | 17 | ||||
-rw-r--r-- | xmloff/source/text/txtparae.cxx | 57 |
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 |