diff options
-rw-r--r-- | oox/source/vml/vmlshape.cxx | 2 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/data/groupshape-rotation.rtf | 75 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/rtfimport.cxx | 10 | ||||
-rw-r--r-- | writerfilter/Library_writerfilter.mk | 1 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 13 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsdrimport.cxx | 20 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsdrimport.hxx | 2 |
8 files changed, 118 insertions, 8 deletions
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index e1df8e6ac520..0c88d3fa372c 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -493,7 +493,7 @@ void lcl_SetAnchorType(PropertySet& rPropSet, const ShapeTypeModel& rTypeModel) void lcl_SetRotation(PropertySet& rPropSet, const sal_Int32 nRotation) { // See DffPropertyReader::Fix16ToAngle(): in VML, positive rotation angles are clockwise, we have them as counter-clockwise. - // Additionally, VML type is 0..360, our is 0.36000. + // Additionally, VML type is 0..360, our is 0..36000. rPropSet.setAnyProperty(PROP_RotateAngle, makeAny(sal_Int32(NormAngle360(nRotation * -100)))); } diff --git a/sw/qa/extras/rtfimport/data/groupshape-rotation.rtf b/sw/qa/extras/rtfimport/data/groupshape-rotation.rtf new file mode 100644 index 000000000000..bf6b1fb92819 --- /dev/null +++ b/sw/qa/extras/rtfimport/data/groupshape-rotation.rtf @@ -0,0 +1,75 @@ +{\rtf1 +{\shpgrp +{\*\shpinst\shpleft1853\shptop-442\shpright2648\shpbottom1943\shpfhdr0\shpbxcolumn\shpbxignore\shpbypara\shpbyignore\shpwr3\shpwrk0\shpfblwtxt0\shpz0\shplid1028 +{\sp +{\sn groupLeft} +{\sv 2475} +} +{\sp +{\sn groupTop} +{\sv 1770} +} +{\sp +{\sn groupRight} +{\sv 4860} +} +{\sp +{\sn groupBottom} +{\sv 2565} +} +{\sp +{\sn rotation} +{\sv 2949120} +} +{\shp +{\*\shpinst\shplid1026 +{\sp +{\sn relLeft} +{\sv 2475} +} +{\sp +{\sn relTop} +{\sv 1770} +} +{\sp +{\sn relRight} +{\sv 3285} +} +{\sp +{\sn relBottom} +{\sv 2565} +} +{\sp +{\sn shapeType} +{\sv 2} +} +} +} +{\shp +{\*\shpinst\shplid1027 +{\sp +{\sn relLeft} +{\sv 3900} +} +{\sp +{\sn relTop} +{\sv 1770} +} +{\sp +{\sn relRight} +{\sv 4860} +} +{\sp +{\sn relBottom} +{\sv 2565} +} +{\sp +{\sn shapeType} +{\sv 5} +} +} +} +} +} +\par +} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 4e9e8818abc7..e1437c84c3f2 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -163,6 +163,7 @@ public: void testFdo47440(); void testFdo53556(); void testFdo63428(); + void testGroupshapeRotation(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -310,6 +311,7 @@ void Test::run() {"fdo47440.rtf", &Test::testFdo47440}, {"fdo53556.rtf", &Test::testFdo53556}, {"hello.rtf", &Test::testFdo63428}, + {"groupshape-rotation.rtf", &Test::testGroupshapeRotation}, }; header(); for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) @@ -1520,6 +1522,14 @@ void Test::testFdo63428() CPPUNIT_ASSERT_EQUAL(OUString("TextFieldEnd"), getProperty<OUString>(getRun(getParagraph(1), 4), "TextPortionType")); } +void Test::testGroupshapeRotation() +{ + // Rotation on groupshapes wasn't handled correctly, RotateAngle was 4500. + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(sal_Int32(315 * 100), getProperty<sal_Int32>(xDraws->getByIndex(0), "RotateAngle")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk index 0f3bdb13f4f8..58c891aa2a71 100644 --- a/writerfilter/Library_writerfilter.mk +++ b/writerfilter/Library_writerfilter.mk @@ -63,6 +63,7 @@ $(eval $(call gb_Library_use_libraries,writerfilter,\ sfx \ sot \ svt \ + svxcore \ tl \ utl \ vcl \ diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 49fe9649a718..1aa781465815 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -3931,6 +3931,12 @@ int RTFDocumentImpl::popState() aState.aShape.aProperties.back().second = m_aStates.top().aDestinationText.makeStringAndClear(); if (m_aStates.top().bHadShapeText) m_pSdrImport->append(aState.aShape.aProperties.back().first, aState.aShape.aProperties.back().second); + else if (aState.bInShapeGroup && !aState.bInShape && aState.aShape.aProperties.back().first == "rotation") + { + // Rotation should be applied on the groupshape itself, not on each shape. + aState.aShape.aGroupProperties.push_back(aState.aShape.aProperties.back()); + aState.aShape.aProperties.pop_back(); + } } break; case DESTINATION_PICPROP: @@ -3938,6 +3944,13 @@ int RTFDocumentImpl::popState() // Don't trigger a shape import in case we're only leaving the \shpinst of the groupshape itself. if (!m_bObject && !aState.bInListpicture && !aState.bHadShapeText && !(aState.bInShapeGroup && !aState.bInShape)) m_pSdrImport->resolve(m_aStates.top().aShape, true); + else if (aState.bInShapeGroup && !aState.bInShape) + { + // End of a groupshape, as we're in shapegroup, but not in a real shape. + for (std::vector< std::pair<OUString, OUString> >::iterator i = aState.aShape.aGroupProperties.begin(); i != aState.aShape.aGroupProperties.end(); ++i) + m_pSdrImport->appendGroupProperty(i->first, i->second); + aState.aShape.aGroupProperties.clear(); + } break; case DESTINATION_BOOKMARKSTART: { diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 0f5e9d8ed059..276ca933a6c5 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -94,7 +94,8 @@ namespace writerfilter { { public: RTFShape(); - std::vector< std::pair<OUString, OUString> > aProperties; + std::vector< std::pair<OUString, OUString> > aProperties; ///< Properties of a single shape. + std::vector< std::pair<OUString, OUString> > aGroupProperties; ///< Properties applied on the groupshape. sal_Int32 nLeft; sal_Int32 nTop; sal_Int32 nRight; diff --git a/writerfilter/source/rtftok/rtfsdrimport.cxx b/writerfilter/source/rtftok/rtfsdrimport.cxx index 147675eac3af..b51ba64d821b 100644 --- a/writerfilter/source/rtftok/rtfsdrimport.cxx +++ b/writerfilter/source/rtftok/rtfsdrimport.cxx @@ -27,6 +27,7 @@ #include <ooxml/resourceids.hxx> // NS_ooxml namespace #include <filter/msfilter/escherex.hxx> #include <filter/msfilter/util.hxx> +#include <svx/svdtrans.hxx> #include <dmapper/DomainMapper.hxx> #include "../dmapper/GraphicHelpers.hxx" @@ -184,6 +185,13 @@ void RTFSdrImport::applyProperty(uno::Reference<drawing::XShape> xShape, OUStrin obFitShapeToText.reset(aValue.toInt32() == 1); else if (aKey == "fFilled") bFilled = aValue.toInt32() == 1; + else if (aKey == "rotation") + { + // See DffPropertyReader::Fix16ToAngle(): in RTF, positive rotation angles are clockwise, we have them as counter-clockwise. + // Additionally, RTF type is 0..360*2^16, our is 0..360*100. + sal_Int32 nRotation = aValue.toInt32()*100/65536; + xPropertySet->setPropertyValue("RotateAngle", uno::makeAny(sal_Int32(NormAngle360(nRotation * -1)))); + } if (nHoriOrient != 0) xPropertySet->setPropertyValue("HoriOrient", uno::makeAny(nHoriOrient)); @@ -321,11 +329,6 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose) aAny <<= uno::makeAny(sal_uInt32(opacity)); xPropertySet->setPropertyValue("FillTransparence", aAny); } - else if (i->first == "rotation" && xPropertySet.is()) - { - aAny <<= i->second.toInt32()*100/65536; - xPropertySet->setPropertyValue("RotateAngle", aAny); - } else if (i->first == "lineWidth") aLineWidth <<= i->second.toInt32()/360; else if ( i->first == "pVerticies" ) @@ -492,7 +495,7 @@ void RTFSdrImport::resolve(RTFShape& rShape, bool bClose) else if (i->first == "shadowOffsetX") // EMUs to points aShadowModel.moOffset.set(OUString::number(i->second.toDouble() / 12700) + "pt"); - else if (i->first == "posh" || i->first == "posv" || i->first == "fFitShapeToText" || i->first == "fFilled") + else if (i->first == "posh" || i->first == "posv" || i->first == "fFitShapeToText" || i->first == "fFilled" || i->first == "rotation") applyProperty(xShape, i->first, i->second); else if (i->first == "posrelh") { @@ -699,6 +702,11 @@ void RTFSdrImport::append(OUString aKey, OUString aValue) applyProperty(m_xShape, aKey, aValue); } +void RTFSdrImport::appendGroupProperty(OUString aKey, OUString aValue) +{ + applyProperty(uno::Reference<drawing::XShape>(m_aParents.top(), uno::UNO_QUERY), aKey, aValue); +} + } // namespace rtftok } // namespace writerfilter diff --git a/writerfilter/source/rtftok/rtfsdrimport.hxx b/writerfilter/source/rtftok/rtfsdrimport.hxx index 735f24b7e5cf..333927dd827c 100644 --- a/writerfilter/source/rtftok/rtfsdrimport.hxx +++ b/writerfilter/source/rtftok/rtfsdrimport.hxx @@ -26,6 +26,8 @@ namespace writerfilter { void resolve(RTFShape& rShape, bool bClose); void close(); void append(OUString aKey, OUString aValue); + /// Append property on the current parent. + void appendGroupProperty(OUString aKey, OUString aValue); void resolveDhgt(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nZOrder); void resolveFLine(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nFLine); /** |