oox/inc/drawingml/textbodyproperties.hxx | 1 oox/source/drawingml/shape.cxx | 24 +++++++++-- oox/source/drawingml/textbodypropertiescontext.cxx | 5 +- oox/source/export/drawingml.cxx | 37 ++++++++--------- sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx |binary sc/qa/unit/subsequent_filters-test.cxx | 45 +++++++++++++++++++++ 6 files changed, 89 insertions(+), 23 deletions(-)
New commits: commit 2967aae06af4c6c56da53db67e2e6fb297b4881e Author: Szabolcs Toth <toth.szabo...@nisz.hu> AuthorDate: Wed Sep 16 14:41:24 2020 +0200 Commit: Gabor Kelemen <kelemen.gab...@nisz.hu> CommitDate: Thu Feb 18 16:18:53 2021 +0100 tdf#106197 XLSX shape import: keep text upright Handle and grab-bag attribute upright to keep text upright regardless of shape rotation, fixing the text direction after import and after a round-trip. Co-authored-by: Balázs Regényi Change-Id: If4c73aeaebad55af967cea894a94756068ca3766 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102870 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> (cherry picked from commit 8c23be49fb5a9044989532e6e20feb1e3ff64f2b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111143 Tested-by: Gabor Kelemen <kelemen.gab...@nisz.hu> Reviewed-by: Gabor Kelemen <kelemen.gab...@nisz.hu> diff --git a/oox/inc/drawingml/textbodyproperties.hxx b/oox/inc/drawingml/textbodyproperties.hxx index eddf78a5f97f..27ca26fabc67 100644 --- a/oox/inc/drawingml/textbodyproperties.hxx +++ b/oox/inc/drawingml/textbodyproperties.hxx @@ -35,6 +35,7 @@ struct TextBodyProperties OptValue< sal_Int32 > moRotation; bool mbAnchorCtr; OptValue< sal_Int32 > moVert; + bool moUpright = false; std::optional< sal_Int32 > moInsets[4]; std::optional< sal_Int32 > moTextOffUpper; std::optional< sal_Int32 > moTextOffLeft; diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 567564479846..173095b37df2 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -1429,10 +1429,26 @@ Reference< XShape > const & Shape::createAndInsert( sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) ); nTextRotateAngle -= mnDiagramRotation; - /* OOX measures text rotation clockwise in 1/60000th degrees, - relative to the containing shape. setTextRotateAngle wants - degrees anticlockwise. */ - mpCustomShapePropertiesPtr->setTextRotateAngle( -1 * nTextRotateAngle / 60000 ); + + bool isUpright = getTextBody()->getTextProperties().moUpright; + if (isUpright) + { + // When upright is set, we want the text without any rotation. + // But if we set 0 here, the text is still rotated if the + // shape containing it is rotated. + // Hence, we rotate the text into the the opposite direction of + // the rotation of the shape, by as much as the shape was rotated. + mpCustomShapePropertiesPtr->setTextRotateAngle(mnRotation / 60000); + // Also put this away in a Gabbag. + putPropertyToGrabBag("Upright", Any(isUpright)); + } + else + { + /* OOX measures text rotation clockwise in 1/60000th degrees, + relative to the containing shape. setTextRotateAngle wants + degrees anticlockwise. */ + mpCustomShapePropertiesPtr->setTextRotateAngle(-1 * nTextRotateAngle / 60000); + } } // Note that the script oox/source/drawingml/customshapes/generatePresetsData.pl looks diff --git a/oox/source/drawingml/textbodypropertiescontext.cxx b/oox/source/drawingml/textbodypropertiescontext.cxx index 14f23c935b34..699c15ec2632 100644 --- a/oox/source/drawingml/textbodypropertiescontext.cxx +++ b/oox/source/drawingml/textbodypropertiescontext.cxx @@ -94,7 +94,10 @@ TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper cons // ST_PositiveCoordinate // sal_Int32 nSpcCol = rAttribs.getInteger( XML_spcCol, 0 ); // bool bSpcFirstLastPara = rAttribs.getBool( XML_spcFirstLastPara, 0 ); -// bool bUpRight = rAttribs.getBool( XML_upright, 0 ); + + bool bUpright = rAttribs.getBool(XML_upright, false); + if (bUpright) + mrTextBodyProp.moUpright = true; // ST_TextVerticalType if( rAttribs.hasAttribute( XML_vert ) ) { diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 70ecafec02f9..0728a131550f 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2813,24 +2813,6 @@ void DrawingML::WriteText( const Reference< XInterface >& rXIface, const OUStrin else if( bVertical && eHorizontalAlignment == TextHorizontalAdjust_LEFT ) sVerticalAlignment = "b"; - bool isUpright = false; - if (GetProperty(rXPropSet, "InteropGrabBag")) - { - if (rXPropSet->getPropertySetInfo()->hasPropertyByName("InteropGrabBag")) - { - uno::Sequence<beans::PropertyValue> aGrabBag; - rXPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag; - for (auto& aProp : aGrabBag) - { - if (aProp.Name == "Upright") - { - aProp.Value >>= isUpright; - break; - } - } - } - } - bool bHasWrap = false; bool bWrap = false; // Only custom shapes obey the TextWordWrap option, normal text always wraps. @@ -2852,6 +2834,25 @@ void DrawingML::WriteText( const Reference< XInterface >& rXIface, const OUStrin if (xServiceInfo.is() && xServiceInfo->supportsService("com.sun.star.drawing.TextShape")) pWrap = "square"; } + + bool isUpright = false; + if (GetProperty(rXPropSet, "InteropGrabBag")) + { + if (rXPropSet->getPropertySetInfo()->hasPropertyByName("InteropGrabBag")) + { + uno::Sequence<beans::PropertyValue> aGrabBag; + rXPropSet->getPropertyValue("InteropGrabBag") >>= aGrabBag; + for (auto& aProp : aGrabBag) + { + if (aProp.Name == "Upright") + { + aProp.Value >>= isUpright; + break; + } + } + } + } + mpFS->startElementNS( (nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr, XML_wrap, pWrap, XML_fromWordArt, bFromWordArt ? "1" : nullptr, diff --git a/sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx b/sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx new file mode 100644 index 000000000000..5ac0a75eabb6 Binary files /dev/null and b/sc/qa/unit/data/xlsx/tdf106197_import_upright.xlsx differ diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 16a38a862121..f548a9b8e21b 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -263,6 +263,7 @@ public: void testPreviewMissingObjLink(); void testShapeRotationImport(); void testShapeDisplacementOnRotationImport(); + void testTextBoxBodyUpright(); CPPUNIT_TEST_SUITE(ScFiltersTest); CPPUNIT_TEST(testBooleanFormatXLSX); @@ -414,6 +415,7 @@ public: CPPUNIT_TEST(testPreviewMissingObjLink); CPPUNIT_TEST(testShapeRotationImport); CPPUNIT_TEST(testShapeDisplacementOnRotationImport); + CPPUNIT_TEST(testTextBoxBodyUpright); CPPUNIT_TEST_SUITE_END(); @@ -4539,6 +4541,49 @@ void ScFiltersTest::testShapeDisplacementOnRotationImport() CPPUNIT_ASSERT_EQUAL(sal_Int32(1), aRectangle.Y); } +void ScFiltersTest::testTextBoxBodyUpright() +{ + // tdf#106197 We should import the "upright" attribute of txBody. + ScDocShellRef xDocSh = loadDoc("tdf106197_import_upright.", FORMAT_XLSX); + CPPUNIT_ASSERT_MESSAGE("Failed to load testTextBoxBodyUpright.xlsx", xDocSh.is()); + + uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocSh->GetModel(), uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW); + uno::Reference<drawing::XShape> xShape(xPage->getByIndex(0), uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> xShapeProperties(xShape, uno::UNO_QUERY_THROW); + + // Check that we imported "Upright". + bool isUpright = false; + if (xShapeProperties->getPropertySetInfo()->hasPropertyByName("InteropGrabBag")) + { + uno::Sequence<beans::PropertyValue> aGrabBag; + xShapeProperties->getPropertyValue("InteropGrabBag") >>= aGrabBag; + for (auto& aProp : aGrabBag) + { + if (aProp.Name == "Upright") + { + aProp.Value >>= isUpright; + break; + } + } + } + CPPUNIT_ASSERT_EQUAL(true, isUpright); + + // Check the new textRotateAngle. + sal_Int32 nAngle; + uno::Any aGeom = xShapeProperties->getPropertyValue("CustomShapeGeometry"); + auto aGeomSeq = aGeom.get<Sequence<beans::PropertyValue>>(); + for (const auto& aProp : std::as_const(aGeomSeq)) + { + if (aProp.Name == "TextPreRotateAngle") + { + aProp.Value >>= nAngle; + break; + } + } + CPPUNIT_ASSERT_EQUAL(sal_Int32(90), nAngle); +} + ScFiltersTest::ScFiltersTest() : ScBootstrapFixture( "sc/qa/unit/data" ) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits