/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; namespace { /// Gets one child of xShape, which one is specified by nIndex. uno::Reference getChildShape(const uno::Reference& xShape, sal_Int32 nIndex) { uno::Reference xGroup(xShape, uno::UNO_QUERY); CPPUNIT_ASSERT(xGroup.is()); CPPUNIT_ASSERT(xGroup->getCount() > nIndex); uno::Reference xRet(xGroup->getByIndex(nIndex), uno::UNO_QUERY); CPPUNIT_ASSERT(xRet.is()); return xRet; } } /// oox drawingml tests. class OoxDrawingmlTest : public UnoApiTest { public: OoxDrawingmlTest() : UnoApiTest(u"/oox/qa/unit/data/"_ustr) { } }; CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTransparentText) { loadFromFile(u"transparent-text.pptx"); saveAndReload(u"Impress Office Open XML"_ustr); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xParagraph( xShape->createEnumeration()->nextElement(), uno::UNO_QUERY); uno::Reference xPortion(xParagraph->createEnumeration()->nextElement(), uno::UNO_QUERY); sal_Int16 nTransparency = 0; xPortion->getPropertyValue(u"CharTransparence"_ustr) >>= nTransparency; // Without the accompanying fix in place, this test would have failed with: // - Expected: 75 // - Actual : 0 // i.e. the transparency of the character color was lost on import/export. CPPUNIT_ASSERT_EQUAL(static_cast(75), nTransparency); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf131082) { loadFromFile(u"tdf131082.pptx"); saveAndReload(u"Impress Office Open XML"_ustr); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference XPropSet(getChildShape(getChildShape(xShape, 0), 0), uno::UNO_QUERY); drawing::FillStyle eFillStyle = drawing::FillStyle_NONE; XPropSet->getPropertyValue(u"FillStyle"_ustr) >>= eFillStyle; // Without the accompanying fix in place, this test would have failed with: // with drawing::FillStyle_NONE - 0 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, eFillStyle); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testPresetAdjustValue) { loadFromFile(u"preset-adjust-value.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); uno::Sequence aGeoPropSeq; xShapeProps->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aGeoPropSeq; comphelper::SequenceAsHashMap aGeoPropMap(aGeoPropSeq); uno::Sequence aAdjustmentSeq; aGeoPropMap.getValue(u"AdjustmentValues"_ustr) >>= aAdjustmentSeq; CPPUNIT_ASSERT_EQUAL(static_cast(1), aAdjustmentSeq.getLength()); // Without the accompanying fix in place, this test would have failed with: // - Expected: 11587 // - Actual : 10813 // i.e. the adjust value was set from the placeholder, not from the shape. CPPUNIT_ASSERT_EQUAL(static_cast(11587), aAdjustmentSeq[0].Value.get()); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testChartDataLabelCharColor) { loadFromFile(u"chart-data-label-char-color.docx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xModel(xShape->getPropertyValue(u"Model"_ustr), uno::UNO_QUERY); uno::Reference xDiagram(xModel->getFirstDiagram(), uno::UNO_QUERY); uno::Reference xCoordinateSystem( xDiagram->getCoordinateSystems()[0], uno::UNO_QUERY); uno::Reference xChartType(xCoordinateSystem->getChartTypes()[0], uno::UNO_QUERY); uno::Reference xDataSeries = xChartType->getDataSeries()[0]; uno::Reference xDataPoint = xDataSeries->getDataPointByIndex(0); uno::Sequence> aLabels; xDataPoint->getPropertyValue(u"CustomLabelFields"_ustr) >>= aLabels; uno::Reference xLabel = aLabels[0]; Color nCharColor; xLabel->getPropertyValue(u"CharColor"_ustr) >>= nCharColor; // Without the accompanying fix in place, this test would have failed with: // - Expected: 16777215 // - Actual : -1 // i.e. the data label had no explicit (white) color. CPPUNIT_ASSERT_EQUAL(COL_WHITE, nCharColor); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testGradientMultiStepTransparency) { // Load a document with a multi-step gradient. loadFromFile(u"gradient-multistep-transparency.pptx"); // Check the end transparency of the gradient. uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"Rectangle 4"_ustr, xShape->getName()); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); awt::Gradient2 aTransparence; xShapeProps->getPropertyValue(u"FillTransparenceGradient"_ustr) >>= aTransparence; // Without the accompanying fix in place, this test would have failed with: // - Expected: 16777215 (COL_WHITE) // - Actual : 3487029 (0x353535) // i.e. the end transparency was not 100%, but was 21%, leading to an unexpected visible line on // the right of this shape. // MCGR: Use the completely imported transparency gradient to check for correctness const basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aTransparence.ColorStops); CPPUNIT_ASSERT_EQUAL(size_t(5), aColorStops.size()); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00, aColorStops[0].getStopOffset(), 1E-3); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.19, aColorStops[1].getStopOffset(), 1E-3); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.35, aColorStops[2].getStopOffset(), 1E-3); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.58, aColorStops[3].getStopOffset(), 1E-3); CPPUNIT_ASSERT_DOUBLES_EQUAL(1.00, aColorStops[4].getStopOffset(), 1E-3); CPPUNIT_ASSERT_EQUAL(COL_WHITE, Color(aColorStops[0].getStopColor())); CPPUNIT_ASSERT_EQUAL(Color(0x9e9e9e), Color(aColorStops[1].getStopColor())); CPPUNIT_ASSERT_EQUAL(Color(0x363636), Color(aColorStops[2].getStopColor())); CPPUNIT_ASSERT_EQUAL(COL_BLACK, Color(aColorStops[3].getStopColor())); CPPUNIT_ASSERT_EQUAL(COL_BLACK, Color(aColorStops[4].getStopColor())); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testShapeTextAlignment) { loadFromFile(u"shape-text-alignment.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); sal_Int16 nParaAdjust = -1; CPPUNIT_ASSERT(xShape->getPropertyValue(u"ParaAdjust"_ustr) >>= nParaAdjust); // Without the accompanying fix in place, this test would have failed with: // - Expected: 0 // - Actual : 3 // i.e. text which is meant to be left-aligned was centered at a paragraph level. CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_LEFT, static_cast(nParaAdjust)); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testShapeTextAdjustLeft) { loadFromFile(u"shape-text-adjust-left.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); drawing::TextHorizontalAdjust eAdjust; // Without the accompanying fix in place, this test would have failed with: // - Expected: 3 (center) // - Actual : 1 (block) // i.e. text was center-adjusted, not default-adjusted (~left). CPPUNIT_ASSERT(xShape->getPropertyValue(u"TextHorizontalAdjust"_ustr) >>= eAdjust); CPPUNIT_ASSERT_EQUAL(drawing::TextHorizontalAdjust_BLOCK, eAdjust); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testCameraRotationRevolution) { loadFromFile(u"camera-rotation-revolution.docx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape0(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape1(xDrawPage->getByIndex(1), uno::UNO_QUERY); uno::Reference xShapeProps0(xShape0, uno::UNO_QUERY); uno::Reference xShapeProps1(xShape1, uno::UNO_QUERY); sal_Int32 nRotateAngle0; sal_Int32 nRotateAngle1; xShapeProps0->getPropertyValue(u"RotateAngle"_ustr) >>= nRotateAngle0; xShapeProps1->getPropertyValue(u"RotateAngle"_ustr) >>= nRotateAngle1; // Without the accompanying fix in place, this test would have failed with: // - Expected: 8000 // - Actual : 0 // so the camera rotation would not have been factored into how the shape is displayed CPPUNIT_ASSERT_EQUAL(static_cast(8000), nRotateAngle0); CPPUNIT_ASSERT_EQUAL(static_cast(27000), nRotateAngle1); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf146534_CameraRotationRevolutionNonWpsShapes) { loadFromFile(u"camera-rotation-revolution-nonwps.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape0(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape1(xDrawPage->getByIndex(1), uno::UNO_QUERY); uno::Reference xShapeProps0(xShape0, uno::UNO_QUERY); uno::Reference xShapeProps1(xShape1, uno::UNO_QUERY); sal_Int32 nRotateAngle0; sal_Int32 nRotateAngle1; xShapeProps0->getPropertyValue(u"RotateAngle"_ustr) >>= nRotateAngle0; xShapeProps1->getPropertyValue(u"RotateAngle"_ustr) >>= nRotateAngle1; // Without the accompanying fix in place, this test would have failed with: // - Expected: 9000 // - Actual : 0 // so the camera rotation would not have been factored into how the shape is displayed CPPUNIT_ASSERT_EQUAL(static_cast(9000), nRotateAngle0); CPPUNIT_ASSERT_EQUAL(static_cast(30500), nRotateAngle1); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTableShadow) { auto verify = [](const uno::Reference& xComponent) { uno::Reference xDrawPagesSupplier(xComponent, uno::UNO_QUERY); uno::Reference xDrawPage( xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); bool bShadow = false; CPPUNIT_ASSERT(xShape->getPropertyValue(u"Shadow"_ustr) >>= bShadow); CPPUNIT_ASSERT(bShadow); Color nColor; CPPUNIT_ASSERT(xShape->getPropertyValue(u"ShadowColor"_ustr) >>= nColor); CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, nColor); }; loadFromFile(u"table-shadow.pptx"); // Without the accompanying fix in place, this test would have failed, because shadow on a table // was lost on import. verify(mxComponent); saveAndReload(u"Impress Office Open XML"_ustr); // Without the accompanying fix in place, this test would have failed, because shadow on a table // was lost on export. verify(mxComponent); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testGroupShapeSmartArt) { // Given a file with a smartart inside a group shape: loadFromFile(u"smartart-groupshape.pptx"); // Then make sure that the smartart is not just an empty group shape: uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xGroup(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xSmartArt(xGroup->getByIndex(0), uno::UNO_QUERY); // Without the accompanying fix in place, this test would have failed, because we lost all // children of the group shape representing the smartart. CPPUNIT_ASSERT_GREATER(static_cast(0), xSmartArt->getCount()); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf142605_CurveSize) { // The document contains a Bezier curve, where the control points are outside the bounding // rectangle of the shape. Error was, that the export uses a path size which included the // control points. loadFromFile(u"tdf142605_CurveSize.odp"); saveAndReload(u"Impress Office Open XML"_ustr); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); auto xPage = xDrawPagesSupplier->getDrawPages()->getByIndex(0); uno::Reference xDrawPage(xPage, uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT(xShape.is()); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); CPPUNIT_ASSERT(xShapeProps.is()); uno::Reference xShapeNamed(xShape, uno::UNO_QUERY); CPPUNIT_ASSERT(xShapeNamed.is()); CPPUNIT_ASSERT_EQUAL(u"Bézier curve 1"_ustr, xShapeNamed->getName()); css::awt::Rectangle aBoundRect; xShapeProps->getPropertyValue(u"BoundRect"_ustr) >>= aBoundRect; // Without fix, size was 6262 x 3509, and position was 10037|6790. CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(8601), aBoundRect.Width, 1); CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(4601), aBoundRect.Height, 1); CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(7699), aBoundRect.X, 1); CPPUNIT_ASSERT_DOUBLES_EQUAL(sal_Int32(5699), aBoundRect.Y, 1); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testChartThemeOverride) { // Given a document with 2 slides, slide1 has a chart with a theme override and slide2 has a // shape: loadFromFile(u"chart-theme-override.pptx"); // Then make sure that the slide 2 shape's text color is blue, not red: uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(1), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xText(xShape->getText(), uno::UNO_QUERY); uno::Reference xPara(xText->createEnumeration()->nextElement(), uno::UNO_QUERY); uno::Reference xPortion(xPara->createEnumeration()->nextElement(), uno::UNO_QUERY); Color nActual{ 0 }; xPortion->getPropertyValue(u"CharColor"_ustr) >>= nActual; // Without the accompanying fix in place, this test would have failed with: // - Expected: 4485828 (0x4472c4) // - Actual : 16711680 (0xff0000) // i.e. the text color was red, not blue. CPPUNIT_ASSERT_EQUAL(Color(0x4472C4), nActual); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testPptxTheme) { // Given a PPTX file with a slide -> master slide -> theme: loadFromFile(u"theme.pptx"); // Then make sure the theme + referring to that theme is imported: // Check the imported theme of the master page: uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage( xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xMasterpage(xDrawPage->getMasterPage(), uno::UNO_QUERY); uno::Reference xTheme; xMasterpage->getPropertyValue(u"Theme"_ustr) >>= xTheme; // We expect the theme to be set on the master page CPPUNIT_ASSERT(xTheme.is()); auto* pUnoTheme = dynamic_cast(xTheme.get()); CPPUNIT_ASSERT(pUnoTheme); auto pTheme = pUnoTheme->getTheme(); CPPUNIT_ASSERT_EQUAL(u"Office Theme"_ustr, pTheme->GetName()); CPPUNIT_ASSERT_EQUAL(u"Office"_ustr, pTheme->getColorSet()->getName()); CPPUNIT_ASSERT_EQUAL(Color(0x954F72), pTheme->getColorSet()->getColor(model::ThemeColorType::FollowedHyperlink)); // Check the reference to that theme: uno::Reference xDrawPageShapes(xDrawPage, uno::UNO_QUERY); uno::Reference xShape(xDrawPageShapes->getByIndex(0), uno::UNO_QUERY); uno::Reference xText(xShape->getText(), uno::UNO_QUERY); uno::Reference xPara(xText->createEnumeration()->nextElement(), uno::UNO_QUERY); uno::Reference xPortion(xPara->createEnumeration()->nextElement(), uno::UNO_QUERY); // Check the theme colors are as expected { uno::Reference xComplexColor; CPPUNIT_ASSERT(xPortion->getPropertyValue(u"CharComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aComplexColor.getThemeColorType()); CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, aComplexColor.getTransformations()[0].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(6000), aComplexColor.getTransformations()[0].mnValue); CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, aComplexColor.getTransformations()[1].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), aComplexColor.getTransformations()[1].mnValue); } } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf132557_footerCustomShapes) { // slide with date, footer, slide number with custom shapes loadFromFile(u"testTdf132557_footerCustomShapes.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); // Test if we were able to import the footer shapes with CustomShape service. uno::Reference xShapeDateTime(xDrawPage->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"com.sun.star.drawing.CustomShape"_ustr, xShapeDateTime->getShapeType()); // Without the accompanying fix in place, this test would have failed with: // An uncaught exception of type com.sun.star.lang.IndexOutOfBoundsException // i.e. the shape wasn't on the slide there since it was imported as a property, not a shape. uno::Reference xShapeFooter(xDrawPage->getByIndex(1), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"com.sun.star.drawing.CustomShape"_ustr, xShapeFooter->getShapeType()); uno::Reference xShapeSlideNum(xDrawPage->getByIndex(2), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"com.sun.star.drawing.CustomShape"_ustr, xShapeSlideNum->getShapeType()); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf132557_objPlaceholderCustomShape) { // slide with object placeholder with custom shape loadFromFile(u"testTdf157019_objPlaceholderCustomShape.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); // Test if we were able to import the outliner shape with CustomShape service. // Without the fix in place, this test would have failed with // Expected: shape type: "com.sun.star.drawing.CustomShape" // Actual : shape type: "com.sun.star.presentation.OutlinerShape" uno::Reference xObjShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); CPPUNIT_ASSERT_EQUAL(u"com.sun.star.drawing.CustomShape"_ustr, xObjShape->getShapeType()); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testThemeColorTint_Table) { // Given a document with a table style, using theme color with tinting in the A2 cell: loadFromFile(u"theme-tint.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xTable; CPPUNIT_ASSERT(xShape->getPropertyValue(u"Model"_ustr) >>= xTable); uno::Reference xA1(xTable->getCellByPosition(0, 0), uno::UNO_QUERY); // check theme color { uno::Reference xComplexColor; CPPUNIT_ASSERT(xA1->getPropertyValue(u"FillComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aComplexColor.getThemeColorType()); { auto const& rTrans = aComplexColor.getTransformations(); CPPUNIT_ASSERT_EQUAL(size_t(0), rTrans.size()); } } { uno::Reference xA2(xTable->getCellByPosition(0, 1), uno::UNO_QUERY); uno::Reference xComplexColor; CPPUNIT_ASSERT(xA2->getPropertyValue(u"FillComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aComplexColor.getThemeColorType()); { auto const& rTrans = aComplexColor.getTransformations(); CPPUNIT_ASSERT_EQUAL(size_t(1), rTrans.size()); CPPUNIT_ASSERT_EQUAL(model::TransformationType::Tint, rTrans[0].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTrans[0].mnValue); } } } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testThemeColor_Shape) { // Given a document with a table style, using theme color with tinting in the A2 cell: loadFromFile(u"ThemeShapesReference.pptx"); // Then make sure that we only import theming info to the doc model if the effects are limited // to lum mod / off that we can handle (i.e. no tint/shade): uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); // check line and fill theme color of shape1 { uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xComplexColor; CPPUNIT_ASSERT(xShape->getPropertyValue(u"FillComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); { auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent6, aComplexColor.getThemeColorType()); auto const& rTrans = aComplexColor.getTransformations(); CPPUNIT_ASSERT_EQUAL(size_t(2), rTrans.size()); CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans[0].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(4000), rTrans[0].mnValue); CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumOff, rTrans[1].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(6000), rTrans[1].mnValue); } CPPUNIT_ASSERT(xShape->getPropertyValue(u"LineComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); { auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent6, aComplexColor.getThemeColorType()); auto const& rTrans = aComplexColor.getTransformations(); CPPUNIT_ASSERT_EQUAL(size_t(1), rTrans.size()); CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans[0].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(5000), rTrans[0].mnValue); } } // check line and fill theme color of shape2 { uno::Reference xComplexColor; uno::Reference xShape(xDrawPage->getByIndex(1), uno::UNO_QUERY); CPPUNIT_ASSERT(xShape->getPropertyValue(u"FillComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); { auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aComplexColor.getThemeColorType()); auto const& rTrans = aComplexColor.getTransformations(); CPPUNIT_ASSERT_EQUAL(size_t(0), rTrans.size()); } CPPUNIT_ASSERT(xShape->getPropertyValue(u"LineComplexColor"_ustr) >>= xComplexColor); CPPUNIT_ASSERT(xComplexColor.is()); { auto aComplexColor = model::color::getFromXComplexColor(xComplexColor); CPPUNIT_ASSERT_EQUAL(model::ThemeColorType::Accent1, aComplexColor.getThemeColorType()); auto const& rTrans = aComplexColor.getTransformations(); CPPUNIT_ASSERT_EQUAL(size_t(1), rTrans.size()); CPPUNIT_ASSERT_EQUAL(model::TransformationType::LumMod, rTrans[0].meType); CPPUNIT_ASSERT_EQUAL(sal_Int16(7500), rTrans[0].mnValue); } } } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testVert270AndTextRot) { // tdf##149551. The document contains a shape with attributes 'rot="720000"' and 'vert="vert270"' // of the element. Without the fix the simulation of vert270 had overwritten the text // rotation angle and thus 'rot'="720000" was lost. loadFromFile(u"tdf149551_vert270AndTextRot.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); uno::Sequence aGeoPropSeq; xShapeProps->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aGeoPropSeq; comphelper::SequenceAsHashMap aGeoPropMap(aGeoPropSeq); // Without the fix the property "TextRotateAngle" does not exist. comphelper::SequenceAsHashMap::iterator it = aGeoPropMap.find(u"TextRotateAngle"_ustr); CPPUNIT_ASSERT(it != aGeoPropMap.end()); sal_Int32 nAngle; // MS 720000 clockwise -> ODF -12deg counter-clockwise it->second >>= nAngle; CPPUNIT_ASSERT_EQUAL(sal_Int32(-12), nAngle); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTextRot) { // tdf#149551 The document contains a shape with attribute 'rot="720000"' of the element. // Without fix, the text rotation angle was saved in "TextPreRotateAngle" instead of // "TextRotateAngle". That resulted in unrotated but sheared text. loadFromFile(u"tdf149551_TextRot.pptx"); uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); uno::Sequence aGeoPropSeq; xShapeProps->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aGeoPropSeq; comphelper::SequenceAsHashMap aGeoPropMap(aGeoPropSeq); // Without the fix the property "TextRotateAngle" does not exist. comphelper::SequenceAsHashMap::iterator it = aGeoPropMap.find(u"TextRotateAngle"_ustr); CPPUNIT_ASSERT(it != aGeoPropMap.end()); sal_Int32 nAngle; // MS 720000 clockwise -> ODF -12deg counter-clockwise it->second >>= nAngle; CPPUNIT_ASSERT_EQUAL(sal_Int32(-12), nAngle); // Because writing mode is LR_TB, the property "TextPreRotateAngle" may missing, or in case it // exists, its value must be 0. Without fix it had value -12. it = aGeoPropMap.find(u"TextPreRotateAngle"_ustr); if (it != aGeoPropMap.end()) { it->second >>= nAngle; CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nAngle); } } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf113187ConstantArcTo) { loadFromFile(u"tdf113187_arcTo_withoutReferences.pptx"); // Get ViewBox of shape uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); uno::Sequence aGeoPropSeq; xShapeProps->getPropertyValue(u"CustomShapeGeometry"_ustr) >>= aGeoPropSeq; comphelper::SequenceAsHashMap aGeoPropMap(aGeoPropSeq); // Without the fix width and height of the ViewBox were 0 and thus the shape was not shown. auto aViewBox = aGeoPropMap[u"ViewBox"_ustr].get(); CPPUNIT_ASSERT_EQUAL(sal_Int32(3600000), aViewBox.Width); CPPUNIT_ASSERT_EQUAL(sal_Int32(3600000), aViewBox.Height); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf125085WordArtFontTheme) { // The font info for the shape is in the theme, the text run has no font settings. loadFromFile(u"tdf125085_WordArtFontTheme.pptx"); // Get shape and its properties uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); // Make sure shape has correct font and local. // Without the fix some application defaults were used. OUString sFontName; xShapeProps->getPropertyValue(u"CharFontNameComplex"_ustr) >>= sFontName; CPPUNIT_ASSERT_EQUAL(u"Noto Serif Hebrew"_ustr, sFontName); css::lang::Locale aLocal; xShapeProps->getPropertyValue(u"CharLocaleComplex"_ustr) >>= aLocal; CPPUNIT_ASSERT_EQUAL(u"IL"_ustr, aLocal.Country); CPPUNIT_ASSERT_EQUAL(u"he"_ustr, aLocal.Language); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testTdf125085WordArtFontText) { // The font info for the shape is in the text run inside the shape. loadFromFile(u"tdf125085_WordArtFontText.pptx"); // Get shape and its properties uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xShapeProps(xShape, uno::UNO_QUERY); // Make sure shape has correct font and local. // Without the fix some application defaults were used. OUString sFontName; xShapeProps->getPropertyValue(u"CharFontNameComplex"_ustr) >>= sFontName; CPPUNIT_ASSERT_EQUAL(u"Noto Serif Hebrew"_ustr, sFontName); css::lang::Locale aLocal; xShapeProps->getPropertyValue(u"CharLocaleComplex"_ustr) >>= aLocal; CPPUNIT_ASSERT_EQUAL(u"IL"_ustr, aLocal.Country); CPPUNIT_ASSERT_EQUAL(u"he"_ustr, aLocal.Language); } CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testToplevelLineHorOffsetDOCX) { // Given a toplevel line shape from DOCX: loadFromFile(u"toplevel-line-hori-offset.docx"); // When checking the transform and the points of the shape: uno::Reference xDrawPagesSupplier(mxComponent, uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); drawing::HomogenMatrix3 aTransformation; xShape->getPropertyValue(u"Transformation"_ustr) >>= aTransformation; basegfx::B2DHomMatrix aMatrix; aMatrix.set(0, 0, aTransformation.Line1.Column1); aMatrix.set(0, 1, aTransformation.Line1.Column2); aMatrix.set(0, 2, aTransformation.Line1.Column3); aMatrix.set(1, 0, aTransformation.Line2.Column1); aMatrix.set(1, 1, aTransformation.Line2.Column2); aMatrix.set(1, 2, aTransformation.Line2.Column3); drawing::PointSequenceSequence aPolyPoly; xShape->getPropertyValue(u"Geometry"_ustr) >>= aPolyPoly; // Then make sure we get a vertical line, not a horizontal one: basegfx::B2DTuple aScale; basegfx::B2DTuple aTranslate; double fRotate = 0; double fShearX = 0; aMatrix.decompose(aScale, aTranslate, fRotate, fShearX); // Without the accompanying fix in place, this test would have failed with: // - Expected: 1 // - Actual : 4094.76362560479 // i.e. this was a horizontal line, not a vertical one. CPPUNIT_ASSERT_DOUBLES_EQUAL(1, aScale.getX(), 0.01); // 1473682 EMUs in mm100 is 4093.56. CPPUNIT_ASSERT_DOUBLES_EQUAL(4094, aScale.getY(), 0.01); // 343535 EMUs in mm100 is 954.27. CPPUNIT_ASSERT_DOUBLES_EQUAL(954, aTranslate.getX(), 2); CPPUNIT_ASSERT_DOUBLES_EQUAL(0, aTranslate.getY(), 0.01); CPPUNIT_ASSERT_DOUBLES_EQUAL(0, fRotate, 0); CPPUNIT_ASSERT_DOUBLES_EQUAL(0, fShearX, 0); CPPUNIT_ASSERT_EQUAL(static_cast(1), aPolyPoly.getLength()); drawing::PointSequence aPoly = aPolyPoly[0]; CPPUNIT_ASSERT_EQUAL(static_cast(2), aPoly.getLength()); CPPUNIT_ASSERT_EQUAL(static_cast(0), aPoly[0].X); CPPUNIT_ASSERT_EQUAL(static_cast(0), aPoly[0].Y); CPPUNIT_ASSERT_EQUAL(static_cast(1), aPoly[1].X); CPPUNIT_ASSERT_EQUAL(static_cast(4094), aPoly[1].Y); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */