/* -*- 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 namespace { using namespace css; using namespace css::uno; using namespace css::io; using namespace css::graphic; using drawinglayer::primitive2d::Primitive2DSequence; using drawinglayer::primitive2d::Primitive2DContainer; class Test : public test::BootstrapFixture, public XmlTestTools, public unotest::MacrosTest { uno::Reference mxComponent; void checkRectPrimitive(Primitive2DSequence const & rPrimitive); void testWorking(); void TestDrawString(); void TestDrawStringTransparent(); void TestDrawLine(); void TestLinearGradient(); void TestPdfInEmf(); Primitive2DSequence parseEmf(const OUString& aSource); public: void setUp() override; void tearDown() override; uno::Reference& getComponent() { return mxComponent; } CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST(testWorking); CPPUNIT_TEST(TestDrawString); CPPUNIT_TEST(TestDrawStringTransparent); CPPUNIT_TEST(TestDrawLine); CPPUNIT_TEST(TestLinearGradient); CPPUNIT_TEST(TestPdfInEmf); CPPUNIT_TEST_SUITE_END(); }; void Test::setUp() { test::BootstrapFixture::setUp(); mxDesktop.set(frame::Desktop::create(mxComponentContext)); } void Test::tearDown() { if (mxComponent.is()) mxComponent->dispose(); test::BootstrapFixture::tearDown(); } Primitive2DSequence Test::parseEmf(const OUString& aSource) { const Reference xEmfParser = EmfTools::create(m_xContext); OUString aUrl = m_directories.getURLFromSrc(aSource); OUString aPath = m_directories.getPathFromSrc(aSource); SvFileStream aFileStream(aUrl, StreamMode::READ); std::size_t nSize = aFileStream.remainingSize(); std::unique_ptr pBuffer(new sal_Int8[nSize + 1]); aFileStream.ReadBytes(pBuffer.get(), nSize); pBuffer[nSize] = 0; Sequence aData(pBuffer.get(), nSize + 1); Reference aInputStream(new comphelper::SequenceInputStream(aData)); css::uno::Sequence< css::beans::PropertyValue > aEmptyValues; return xEmfParser->getDecomposition(aInputStream, aPath, aEmptyValues); } void Test::checkRectPrimitive(Primitive2DSequence const & rPrimitive) { drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer(rPrimitive)); CPPUNIT_ASSERT (pDocument); // emfio: add examples (later) // assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "color", "#00cc00"); // rect background color // assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "height", "100"); // rect background height // assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor", "width", "100"); // rect background width } void Test::testWorking() { Primitive2DSequence aSequenceRect = parseEmf("/emfio/qa/cppunit/emf/data/fdo79679-2.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast(aSequenceRect.getLength())); checkRectPrimitive(aSequenceRect); } void Test::TestDrawString() { #if HAVE_MORE_FONTS // This unit checks for a correct import of an EMF+ file with only one DrawString Record // Since the text is undecorated the optimal choice is a simpletextportion primitive // first, get the sequence of primitives and dump it Primitive2DSequence aSequence = parseEmf("/emfio/qa/cppunit/emf/data/TestDrawString.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer(aSequence)); CPPUNIT_ASSERT (pDocument); // check correct import of the DrawString: height, position, text, color and font assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "height", "120"); assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "x", "817"); assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "y", "1137"); assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "text", "TEST"); assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "fontcolor", "#000000"); assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "familyname", "CALIBRI"); #endif } void Test::TestDrawStringTransparent() { #if HAVE_MORE_FONTS // This unit checks for a correct import of an EMF+ file with one DrawString Record with transparency // first, get the sequence of primitives and dump it Primitive2DSequence aSequence = parseEmf("/emfio/qa/cppunit/emf/data/TestDrawStringTransparent.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer(aSequence)); CPPUNIT_ASSERT (pDocument); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence", "transparence", "0.498039215686275"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "height", "24"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "x", "66"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "y", "74"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "text", "Transparent Text"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "fontcolor", "#0000ff"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "familyname", "ARIAL"); #endif } void Test::TestDrawLine() { // This unit checks for a correct import of an EMF+ file with only one DrawLine Record // The line is colored and has a specified width, therefore a polypolygonstroke primitive is the optimal choice // first, get the sequence of primitives and dump it Primitive2DSequence aSequence = parseEmf("/emfio/qa/cppunit/emf/data/TestDrawLine.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer(aSequence)); CPPUNIT_ASSERT (pDocument); // check correct import of the DrawLine: color and width of the line assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygonstroke/line", "color", "#000000"); assertXPath(pDocument, "/primitive2D/metafile/transform/polypolygonstroke/line", "width", "33"); } void Test::TestLinearGradient() { // This unit checks for a correct import of an EMF+ file with LinearGradient brush Primitive2DSequence aSequence = parseEmf("/emfio/qa/cppunit/emf/data/TestLinearGradient.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer(aSequence)); CPPUNIT_ASSERT (pDocument); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy11", "1.0000656512605"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy12", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy13", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy21", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy22", "1.00013140604468"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy23", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygon", "height", "7610"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygon", "width", "15232"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygon", "path", "m0 0h15232v7610h-15232z"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[1]", "startx", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[1]", "starty", "-1"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[1]", "endx", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[1]", "endy", "-1"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[1]", "opacity", "0.392156862745098"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[1]/polypolygon", "path", "m0 0.216110019646294h7615.75822989746v7610.21611001965h-7615.75822989746z"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]", "startx", "-1"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]", "starty", "-1"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]", "endx", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]", "endy", "-1"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]", "opacity", "1"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/svglineargradient[2]/polypolygon", "path", "m7615.75822989746 0.216110019646294h7615.75822989746v7610.21611001965h-7615.75822989746z"); } void Test::TestPdfInEmf() { // Load a PPTX file, which has a shape, with a bitmap fill, which is an EMF, containing a PDF. OUString aURL = m_directories.getURLFromSrc("emfio/qa/cppunit/emf/data/pdf-in-emf.pptx"); getComponent() = loadFromDesktop(aURL); // Get the EMF. uno::Reference xDrawPagesSupplier(getComponent(), uno::UNO_QUERY); uno::Reference xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY); uno::Reference xShape(xDrawPage->getByIndex(0), uno::UNO_QUERY); uno::Reference xGraphic; xShape->getPropertyValue("FillBitmap") >>= xGraphic; Graphic aGraphic(xGraphic); // Check the size hint of the EMF, which influences the bitmap generated from the PDF. const std::shared_ptr& pVectorGraphicData = aGraphic.getVectorGraphicData(); // Without the accompanying fix in place, this test would have failed with: // - Expected: 14321 // - Actual : 0 // i.e. there was no size hint, the shape with 14cm height had a bitmap-from-PDF fill, the PDF // height was only 5cm, so it looked blurry. CPPUNIT_ASSERT_EQUAL(14321.0, pVectorGraphicData->getSizeHint().getY()); #if !defined(WNT) && !defined(MACOSX) // Hmm, manual testing on Windows looks OK. BitmapEx aBitmapEx = aGraphic.GetBitmapEx(); AlphaMask aMask = aBitmapEx.GetAlpha(); Bitmap::ScopedReadAccess pAccess(aMask); Color aColor(pAccess->GetPixel(0, 0)); // Without the accompanying fix in place, this test would have failed with: // - Expected: 220 // - Actual : 0 // i.e. the pixel at the top left corner was entirely opaque, while it should be mostly // transparent. CPPUNIT_ASSERT_EQUAL(static_cast(220), aColor.GetBlue()); #endif } CPPUNIT_TEST_SUITE_REGISTRATION(Test); } CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */