From fd05a0f9ccebaee6f0175281fdeb6fe3f3168fd2 Mon Sep 17 00:00:00 2001 From: Xisco Fauli Date: Fri, 25 Nov 2022 09:55:37 +0100 Subject: CppunitTest_sdext_pdfimport: move it to 'qa' folder like the rest of folders in the project Change-Id: Ifb833aa8acedc8549c74383b2d76737d4f425c09 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143277 Tested-by: Jenkins Reviewed-by: Xisco Fauli --- sdext/CppunitTest_sdext_pdfimport.mk | 3 +- sdext/qa/unit/data/tdf104597_textrun.pdf | Bin 0 -> 21042 bytes .../data/tdf78427-MyraidPro-Semibold-Light.pdf | Bin 0 -> 13199 bytes sdext/qa/unit/data/tdf78427-testFontFeatures.pdf | Bin 0 -> 81012 bytes sdext/qa/unit/data/testSpace.pdf | Bin 0 -> 8140 bytes sdext/qa/unit/data/testTdf141709_chinesechar.pdf | Bin 0 -> 11119 bytes sdext/qa/unit/data/testTdf143959.pdf | Bin 0 -> 63999 bytes sdext/qa/unit/pdfimport.cxx | 904 +++++++++++++++++++++ .../pdfimport/test/testdocs/tdf104597_textrun.pdf | Bin 21042 -> 0 bytes .../testdocs/tdf78427-MyraidPro-Semibold-Light.pdf | Bin 13199 -> 0 bytes .../test/testdocs/tdf78427-testFontFeatures.pdf | Bin 81012 -> 0 bytes sdext/source/pdfimport/test/testdocs/testSpace.pdf | Bin 8140 -> 0 bytes .../test/testdocs/testTdf141709_chinesechar.pdf | Bin 11119 -> 0 bytes .../pdfimport/test/testdocs/testTdf143959.pdf | Bin 63999 -> 0 bytes sdext/source/pdfimport/test/tests.cxx | 904 --------------------- 15 files changed, 906 insertions(+), 905 deletions(-) create mode 100644 sdext/qa/unit/data/tdf104597_textrun.pdf create mode 100644 sdext/qa/unit/data/tdf78427-MyraidPro-Semibold-Light.pdf create mode 100644 sdext/qa/unit/data/tdf78427-testFontFeatures.pdf create mode 100644 sdext/qa/unit/data/testSpace.pdf create mode 100644 sdext/qa/unit/data/testTdf141709_chinesechar.pdf create mode 100644 sdext/qa/unit/data/testTdf143959.pdf create mode 100644 sdext/qa/unit/pdfimport.cxx delete mode 100644 sdext/source/pdfimport/test/testdocs/tdf104597_textrun.pdf delete mode 100644 sdext/source/pdfimport/test/testdocs/tdf78427-MyraidPro-Semibold-Light.pdf delete mode 100644 sdext/source/pdfimport/test/testdocs/tdf78427-testFontFeatures.pdf delete mode 100644 sdext/source/pdfimport/test/testdocs/testSpace.pdf delete mode 100644 sdext/source/pdfimport/test/testdocs/testTdf141709_chinesechar.pdf delete mode 100644 sdext/source/pdfimport/test/testdocs/testTdf143959.pdf delete mode 100644 sdext/source/pdfimport/test/tests.cxx (limited to 'sdext') diff --git a/sdext/CppunitTest_sdext_pdfimport.mk b/sdext/CppunitTest_sdext_pdfimport.mk index b2676d32002b..864fb7084c88 100644 --- a/sdext/CppunitTest_sdext_pdfimport.mk +++ b/sdext/CppunitTest_sdext_pdfimport.mk @@ -13,6 +13,7 @@ $(eval $(call gb_CppunitTest_use_sdk_api,sdext_pdfimport)) $(eval $(call gb_CppunitTest_set_include,sdext_pdfimport,\ -I$(SRCDIR)/sdext/source/pdfimport/inc \ + -I$(SRCDIR)/sdext/source/pdfimport/test \ $$(INCLUDE) \ )) @@ -38,7 +39,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sdext_pdfimport,\ $(eval $(call gb_CppunitTest_use_library_objects,sdext_pdfimport,pdfimport)) $(eval $(call gb_CppunitTest_add_exception_objects,sdext_pdfimport,\ - sdext/source/pdfimport/test/tests \ + sdext/qa/unit/pdfimport \ )) $(eval $(call gb_CppunitTest_use_executable,sdext_pdfimport,xpdfimport)) diff --git a/sdext/qa/unit/data/tdf104597_textrun.pdf b/sdext/qa/unit/data/tdf104597_textrun.pdf new file mode 100644 index 000000000000..dcee96aa3169 Binary files /dev/null and b/sdext/qa/unit/data/tdf104597_textrun.pdf differ diff --git a/sdext/qa/unit/data/tdf78427-MyraidPro-Semibold-Light.pdf b/sdext/qa/unit/data/tdf78427-MyraidPro-Semibold-Light.pdf new file mode 100644 index 000000000000..685da5db956c Binary files /dev/null and b/sdext/qa/unit/data/tdf78427-MyraidPro-Semibold-Light.pdf differ diff --git a/sdext/qa/unit/data/tdf78427-testFontFeatures.pdf b/sdext/qa/unit/data/tdf78427-testFontFeatures.pdf new file mode 100644 index 000000000000..0405d95f8425 Binary files /dev/null and b/sdext/qa/unit/data/tdf78427-testFontFeatures.pdf differ diff --git a/sdext/qa/unit/data/testSpace.pdf b/sdext/qa/unit/data/testSpace.pdf new file mode 100644 index 000000000000..3c94f31ea15b Binary files /dev/null and b/sdext/qa/unit/data/testSpace.pdf differ diff --git a/sdext/qa/unit/data/testTdf141709_chinesechar.pdf b/sdext/qa/unit/data/testTdf141709_chinesechar.pdf new file mode 100644 index 000000000000..3198782faa73 Binary files /dev/null and b/sdext/qa/unit/data/testTdf141709_chinesechar.pdf differ diff --git a/sdext/qa/unit/data/testTdf143959.pdf b/sdext/qa/unit/data/testTdf143959.pdf new file mode 100644 index 000000000000..594e734a5629 Binary files /dev/null and b/sdext/qa/unit/data/testTdf143959.pdf differ diff --git a/sdext/qa/unit/pdfimport.cxx b/sdext/qa/unit/pdfimport.cxx new file mode 100644 index 000000000000..bb09202897ec --- /dev/null +++ b/sdext/qa/unit/pdfimport.cxx @@ -0,0 +1,904 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include +#include +#include +#include +#include +#include <../pdfiadaptor.hxx> + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include + +using namespace ::pdfparse; +using namespace ::pdfi; +using namespace ::com::sun::star; + +namespace +{ + + class TestSink : public ContentSink + { + public: + TestSink() : + m_nNextFontId( 1 ), + m_aIdToFont(), + m_aFontToId(), + m_aGCStack(1), + m_aPageSize(), + m_aHyperlinkBounds(), + m_aURI(), + m_aTextOut(), + m_nNumPages(0), + m_bPageEnded(false), + m_bRedCircleSeen(false), + m_bGreenStrokeSeen(false), + m_bDashedLineSeen(false), + m_bImageSeen(false) + {} + + void check() + { + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Width", 79400, m_aPageSize.Width, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Height", 59500, m_aPageSize.Height, 0.0000001 ); + CPPUNIT_ASSERT_MESSAGE( "endPage() called", m_bPageEnded ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Num pages equal one", sal_Int32(1), m_nNumPages ); + CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", + rtl::math::approxEqual(m_aHyperlinkBounds.X1,34.7 ) ); + CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", + rtl::math::approxEqual(m_aHyperlinkBounds.Y1,386.0) ); + CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", + rtl::math::approxEqual(m_aHyperlinkBounds.X2,166.7) ); + CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", + rtl::math::approxEqual(m_aHyperlinkBounds.Y2,406.2) ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Correct hyperlink URI", OUString("http://download.openoffice.org/"), m_aURI ); + + const char* const sText = " \n \nThis is a testtext\nNew paragraph,\nnew line\n" + "Hyperlink, this is\n?\nThis is more text\noutline mode\n?\nNew paragraph\n"; + OString aTmp; + m_aTextOut.makeStringAndClear().convertToString( &aTmp, + RTL_TEXTENCODING_ASCII_US, + OUSTRING_TO_OSTRING_CVTFLAGS ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Imported text is \"This is a testtext New paragraph, new line" + " Hyperlink, this is * This is more text outline mode * New paragraph\"", + aTmp, OString(sText) ); + + CPPUNIT_ASSERT_MESSAGE( "red circle seen in input", m_bRedCircleSeen ); + CPPUNIT_ASSERT_MESSAGE( "green stroke seen in input", m_bGreenStrokeSeen ); + CPPUNIT_ASSERT_MESSAGE( "dashed line seen in input", m_bDashedLineSeen ); + CPPUNIT_ASSERT_MESSAGE( "image seen in input", m_bImageSeen ); + } + + private: + GraphicsContext& getCurrentContext() { return m_aGCStack.back(); } + + // ContentSink interface implementation + virtual void setPageNum( sal_Int32 nNumPages ) override + { + m_nNumPages = nNumPages; + } + + virtual void startPage( const geometry::RealSize2D& rSize ) override + { + m_aPageSize = rSize; + } + + virtual void endPage() override + { + m_bPageEnded = true; + } + + virtual void hyperLink( const geometry::RealRectangle2D& rBounds, + const OUString& rURI ) override + { + m_aHyperlinkBounds = rBounds; + m_aURI = rURI; + } + + virtual void pushState() override + { + GraphicsContextStack::value_type const a(m_aGCStack.back()); + m_aGCStack.push_back(a); + } + + virtual void popState() override + { + m_aGCStack.pop_back(); + } + + virtual void setTransformation( const geometry::AffineMatrix2D& rMatrix ) override + { + basegfx::unotools::homMatrixFromAffineMatrix( + getCurrentContext().Transformation, + rMatrix ); + } + + virtual void setLineDash( const uno::Sequence& dashes, + double start ) override + { + GraphicsContext& rContext( getCurrentContext() ); + if( dashes.hasElements() ) + comphelper::sequenceToContainer(rContext.DashArray,dashes); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "line dashing start offset", 0.0, start, 0.000000001 ); + } + + virtual void setFlatness( double nFlatness ) override + { + getCurrentContext().Flatness = nFlatness; + } + + virtual void setLineJoin(sal_Int8 nJoin) override + { + getCurrentContext().LineJoin = nJoin; + } + + virtual void setLineCap(sal_Int8 nCap) override + { + getCurrentContext().LineCap = nCap; + } + + virtual void setMiterLimit(double nVal) override + { + getCurrentContext().MiterLimit = nVal; + } + + virtual void setLineWidth(double nVal) override + { + getCurrentContext().LineWidth = nVal; + } + + virtual void setFillColor( const rendering::ARGBColor& rColor ) override + { + getCurrentContext().FillColor = rColor; + } + + virtual void setStrokeColor( const rendering::ARGBColor& rColor ) override + { + getCurrentContext().LineColor = rColor; + } + + virtual void setFont( const FontAttributes& rFont ) override + { + FontToIdMap::const_iterator it = m_aFontToId.find( rFont ); + if( it != m_aFontToId.end() ) + getCurrentContext().FontId = it->second; + else + { + m_aFontToId[ rFont ] = m_nNextFontId; + m_aIdToFont[ m_nNextFontId ] = rFont; + getCurrentContext().FontId = m_nNextFontId; + m_nNextFontId++; + } + } + + virtual void strokePath( const uno::Reference& rPath ) override + { + GraphicsContext& rContext( getCurrentContext() ); + basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); + aPath.transform( rContext.Transformation ); + + if( rContext.DashArray.empty() ) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Alpha, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Blue, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Green, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Red, 0.00000001); + + CPPUNIT_ASSERT_MESSAGE( "Line width is 0", + rtl::math::approxEqual(rContext.LineWidth, 28.3) ); + + static constexpr OUStringLiteral sExportString = u"m53570 7650-35430 24100"; + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is m535.7 518.5-354.3-241", + OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); + + m_bGreenStrokeSeen = true; + } + else + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Dash array consists of four entries", std::vector::size_type(4), rContext.DashArray.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 14.3764, rContext.DashArray[0], 1E-12 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[0], rContext.DashArray[1], 1E-12 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[1], rContext.DashArray[2], 1E-12 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[2], rContext.DashArray[3], 1E-12 ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); + + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line width is 0", + 0, rContext.LineWidth, 0.0000001 ); + + static constexpr OUStringLiteral sExportString = u"m49890 5670.00000000001-35430 24090"; + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is m49890 5670.00000000001-35430 24090", + OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); + + m_bDashedLineSeen = true; + } + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", + rendering::BlendMode::NORMAL, rContext.BlendMode ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Join type is round", + rendering::PathJoinType::ROUND, rContext.LineJoin ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Cap type is butt", + rendering::PathCapType::BUTT, rContext.LineCap ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line miter limit is 10", + 10, rContext.MiterLimit, 0.0000001 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0", + 1, rContext.Flatness, 0.00000001 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", + sal_Int32(0), rContext.FontId ); + } + + virtual void fillPath( const uno::Reference& rPath ) override + { + GraphicsContext& rContext( getCurrentContext() ); + basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); + aPath.transform( rContext.Transformation ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", + rendering::BlendMode::NORMAL, rContext.BlendMode ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 10", + 10, rContext.Flatness, 0.00000001 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", + sal_Int32(0), rContext.FontId ); + } + + virtual void eoFillPath( const uno::Reference& rPath ) override + { + GraphicsContext& rContext( getCurrentContext() ); + basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); + aPath.transform( rContext.Transformation ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", + rendering::BlendMode::NORMAL, rContext.BlendMode ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0", + 1, rContext.Flatness, 0.00000001 ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", + sal_Int32(0), rContext.FontId ); + + static constexpr OUStringLiteral sExportString + = u"m12050 49610c-4310 0-7800-3490-7800-7800 0-4300 " + "3490-7790 7800-7790 4300 0 7790 3490 7790 7790 0 4310-3490 7800-7790 7800z"; + CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is a 4-bezier circle", + OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); + + m_bRedCircleSeen = true; + } + + virtual void intersectClip(const uno::Reference& rPath) override + { + basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); + basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; + + if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) + aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); + + getCurrentContext().Clip = aNewClip; + } + + virtual void intersectEoClip(const uno::Reference& rPath) override + { + basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); + basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; + + if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) + aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); + + getCurrentContext().Clip = aNewClip; + } + + virtual void drawGlyphs( const OUString& rGlyphs, + const geometry::RealRectangle2D& /*rRect*/, + const geometry::Matrix2D& /*rFontMatrix*/, + double /*fontSize*/) override + { + m_aTextOut.append(rGlyphs); + } + + virtual void endText() override + { + m_aTextOut.append( "\n" ); + } + + virtual void drawMask(const uno::Sequence& xBitmap, + bool /*bInvert*/ ) override + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask received two properties", + sal_Int32(3), xBitmap.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask got URL param", + OUString("URL"), xBitmap[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask got InputStream param", + OUString("InputStream"), xBitmap[1].Name ); + } + + virtual void drawImage(const uno::Sequence& xBitmap ) override + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage received two properties", + sal_Int32(3), xBitmap.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage got URL param", + OUString("URL"), xBitmap[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage got InputStream param", + OUString("InputStream"), xBitmap[1].Name ); + m_bImageSeen = true; + } + + virtual void drawColorMaskedImage(const uno::Sequence& xBitmap, + const uno::Sequence& /*xMaskColors*/ ) override + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage received two properties", + sal_Int32(3), xBitmap.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage got URL param", + OUString("URL"), xBitmap[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage got InputStream param", + OUString("InputStream"), xBitmap[1].Name ); + } + + virtual void drawMaskedImage(const uno::Sequence& xBitmap, + const uno::Sequence& xMask, + bool /*bInvertMask*/) override + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #1", + sal_Int32(3), xBitmap.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got URL param #1", + OUString("URL"), xBitmap[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got InputStream param #1", + OUString("InputStream"), xBitmap[1].Name ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #2", + sal_Int32(3), xMask.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got URL param #2", + OUString("URL"), xMask[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got InputStream param #2", + OUString("InputStream"), xMask[1].Name ); + } + + virtual void drawAlphaMaskedImage(const uno::Sequence& xBitmap, + const uno::Sequence& xMask) override + { + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #1", + sal_Int32(3), xBitmap.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got URL param #1", + OUString("URL"), xBitmap[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got InputStream param #1", + OUString("InputStream"), xBitmap[1].Name ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #2", + sal_Int32(3), xMask.getLength() ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got URL param #2", + OUString("URL"), xMask[0].Name ); + CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got InputStream param #2", + OUString("InputStream"), xMask[1].Name ); + } + + virtual void setTextRenderMode( sal_Int32 ) override + { + } + + typedef std::unordered_map IdToFontMap; + typedef std::unordered_map FontToIdMap; + + typedef std::vector GraphicsContextStack; + + sal_Int32 m_nNextFontId; + IdToFontMap m_aIdToFont; + FontToIdMap m_aFontToId; + + GraphicsContextStack m_aGCStack; + geometry::RealSize2D m_aPageSize; + geometry::RealRectangle2D m_aHyperlinkBounds; + OUString m_aURI; + OUStringBuffer m_aTextOut; + sal_Int32 m_nNumPages; + bool m_bPageEnded; + bool m_bRedCircleSeen; + bool m_bGreenStrokeSeen; + bool m_bDashedLineSeen; + bool m_bImageSeen; + }; + + class PDFITest : public test::BootstrapFixture, public XmlTestTools + { + protected: + virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override + { + XmlTestTools::registerODFNamespaces(pXmlXPathCtx); + }; + public: + void testXPDFParser() + { +#if HAVE_FEATURE_POPPLER + auto pSink = std::make_shared(); + CPPUNIT_ASSERT( + pdfi::xpdf_ImportFromFile( + m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), + pSink, + uno::Reference< task::XInteractionHandler >(), + OUString(), + getComponentContext(), "" ) ); + pSink->check(); +#endif + } + + void testOdfDrawExport() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor( new pdfi::PDFIRawAdaptor(OUString(), getComponentContext()) ); + xAdaptor->setTreeVisitorFactory( createDrawTreeVisitorFactory() ); + + OUString tempFileURL; + CPPUNIT_ASSERT_EQUAL( osl::File::E_None, osl::File::createTempFile( nullptr, nullptr, &tempFileURL ) ); + osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists + CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", + xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), + new OutputWrap(tempFileURL), + nullptr )); + osl::File::remove( tempFileURL ); +#endif + } + + void testOdfWriterExport() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor( new pdfi::PDFIRawAdaptor(OUString(), getComponentContext()) ); + xAdaptor->setTreeVisitorFactory( createWriterTreeVisitorFactory() ); + + OUString tempFileURL; + CPPUNIT_ASSERT_EQUAL( osl::File::E_None, osl::File::createTempFile( nullptr, nullptr, &tempFileURL ) ); + osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists + CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", + xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), + new OutputWrap(tempFileURL), + nullptr )); + osl::File::remove( tempFileURL ); +#endif + } + + void testTdf96993() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf96993.pdf"), + new OutputWrapString(aOutput), + nullptr)); + // This ensures that the imported image arrives properly flipped + CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"matrix(18520.8333333333 0 0 26281.9444444444 0 0)\"") != -1); +#endif + } + + void testTdf98421() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf96993.pdf"), + new OutputWrapString(aOutput), + nullptr)); + // This ensures that the imported image arrives properly flipped + CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"scale( 1.0 -1.0 ) translate( 0mm 0mm )\"") != -1); + CPPUNIT_ASSERT(aOutput.indexOf("svg:height=\"-262.82mm\"") != -1); +#endif + } + + void testTdf105536() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf105536.pdf"), + new OutputWrapString(aOutput), + nullptr)); + // This ensures that the imported image arrives properly flipped + CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"matrix(-21488.4 0 0 -27978.1 21488.4 27978.1)\"") != -1); +#endif + } + + void testTdf141709_chinesechar() + { +// this test crashes on the windows jenkins boxes, but no-one can catch it locally +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/qa/unit/data/testTdf141709_chinesechar.pdf"), + new OutputWrapString(aOutput), + nullptr)); + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); + // This ensures that the imported text contains all of the characters + OString xpath = "//draw:frame[@draw:z-index='3'][1]/draw:text-box/text:p/text:span[1]"; + OUString sContent = getXPathContent(pXmlDoc, xpath).replaceAll("\n", ""); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"敏捷的狐狸跨过慵懒的"), sContent); + xpath = "//draw:frame[@draw:z-index='4'][1]/draw:text-box/text:p/text:span[1]"; + sContent = getXPathContent(pXmlDoc, xpath).replaceAll("\n", ""); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"狗。"), sContent); +#endif + } + + void testTdf78427_FontFeatures() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", + xAdaptor->odfConvert( m_directories.getURLFromSrc( + u"/sdext/qa/unit/data/tdf78427-testFontFeatures.pdf"), + new OutputWrapString(aOutput), + nullptr )); + // Un-comment the following debug line to see the content of generated XML content in + // workdir/CppunitTest/sdext_pdfimport.test.log after running "make CppunitTest_sdext_pdfimport". + //std::cout << aOutput << std::endl; + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); + //CPPUNIT_ASSERT(pXmlDoc); + + /* Test for the 1st paragraph */ + OUString styleName = getXPath(pXmlDoc, "//draw:frame[1]//text:span[1]", "style-name"); + OString xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font-weight and font-style should be normal + assertXPath(pXmlDoc, xpath, "font-weight", "normal"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + + /* Test for the 2nd paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[2]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // there should be a font-weight="bold", but no font-style italic + assertXPath(pXmlDoc, xpath, "font-weight", "bold"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + + /* Test for the 3rd paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[3]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // there should be a font-style="italic", but no font-weight bold + assertXPath(pXmlDoc, xpath, "font-weight", "normal"); + assertXPath(pXmlDoc, xpath, "font-style", "italic"); + + /* Test for the 4th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[4]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // there should be both font-style="italic" and font-weight="bold" + assertXPath(pXmlDoc, xpath, "font-weight", "bold"); + assertXPath(pXmlDoc, xpath, "font-style", "italic"); + + /* Test for the 5th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[5]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be Arial and font-weight="bold", no font-style + assertXPath(pXmlDoc, xpath, "font-family", "Arial"); + assertXPath(pXmlDoc, xpath, "font-weight", "bold"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + + /* Test for the 6th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[6]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be Arial without font-weight and font-style + assertXPath(pXmlDoc, xpath, "font-family", "Arial"); + assertXPath(pXmlDoc, xpath, "font-weight", "normal"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + + /* Test for the 7th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[7]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be SimSun without font-weight and font-style + assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); // TODO: tdf#143095 use localized font name rather than PS name + assertXPath(pXmlDoc, xpath, "font-weight", "normal"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + + /* Test for the 8th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[8]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be SimSun and font-weight="bold", no font-style italic + assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); + assertXPath(pXmlDoc, xpath, "font-weight", "bold"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + + /* Test for the 9th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[9]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be SimSun, font-weight should be "normal", font-style="italic" + assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); + assertXPath(pXmlDoc, xpath, "font-weight", "normal"); + // FIXME and remove the below comment: + // the chinese chars are shown in pdf as faux italic (fake italic). It is currencly imported wrongly as normal font style. + // See tdf#78427 for how the faux bold problem was handled. Faux italic may be handled using the transformation pattern. + // assertXPath(pXmlDoc, xpath, "font-style", "italic"); + + /* Test for the 10th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[10]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be SimSun font-weight="bold" and font-style="italic" + assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); + assertXPath(pXmlDoc, xpath, "font-weight", "bold"); + // FIXME: faux italic, see above + // assertXPath(pXmlDoc, xpath, "font-style", "italic"); + + /* Test for the 11th paragraph */ + styleName = getXPath(pXmlDoc, "//draw:frame[11]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font should be SimSun and there should be style:text-outline="true" + // (i.e., the real "outline" font rather than faux bold / fake bold) + assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); + assertXPath(pXmlDoc, xpath, "font-weight", "normal"); + assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); + assertXPath(pXmlDoc, xpath, "text-outline", "true"); +#endif + } + + void testTdf78427_FontWeight_MyraidProSemibold() // Related to attachment 155937. + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", + xAdaptor->odfConvert( m_directories.getURLFromSrc( + u"/sdext/qa/unit/data/tdf78427-MyraidPro-Semibold-Light.pdf"), + new OutputWrapString(aOutput), + nullptr )); + //std::cout << aOutput << std::endl; + + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); + //CPPUNIT_ASSERT(pXmlDoc); + + // The for the 1st frame */ + OUString styleName = getXPath(pXmlDoc, "//draw:frame[1]//text:span[1]", "style-name"); + OString xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font-weight and font-style should be 600 (Semibold) + assertXPath(pXmlDoc, xpath, "font-weight", "600"); + + // The for the 2nd frame */ + styleName = getXPath(pXmlDoc, "//draw:frame[2]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + // the font-weight and font-style should be 300 (Light) + assertXPath(pXmlDoc, xpath, "font-weight", "300"); +#endif + } + + void testTdf143959_nameFromFontFile() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", + xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/qa/unit/data/testTdf143959.pdf"), + new OutputWrapString(aOutput), + nullptr )); + + //std::cout << aOutput << std::endl; + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); + + /* Test for the 1st text paragraph */ + OUString styleName = getXPath(pXmlDoc, "//draw:frame[2]//text:span[1]", "style-name"); + OString xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + CPPUNIT_ASSERT_EQUAL(OUString("TimesNewRoman"), + getXPath(pXmlDoc, xpath, "font-family").replaceAll(u" ", u"")); + + /* Test for the "TOTAL ESTA HOJA USD" paragraph" */ + styleName = getXPath(pXmlDoc, "//draw:frame[last()-1]//text:span[1]", "style-name"); + xpath = "//office:automatic-styles/style:style[@style:name=\"" + + OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + + "\"]/style:text-properties"; + CPPUNIT_ASSERT_EQUAL(OUString("TimesNewRoman"), + getXPath(pXmlDoc, xpath, "font-family").replaceAll(u" ", u"")); + CPPUNIT_ASSERT_EQUAL(OUString("bold"), + getXPath(pXmlDoc, xpath, "font-weight")); +#endif + } + + void testTdf104597_textrun() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); + + OString aOutput; + CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/qa/unit/data/tdf104597_textrun.pdf"), + new OutputWrapString(aOutput), + nullptr)); + + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); + + // Test for امُ عَلَيْكَ + OString xpath = "string(//draw:frame[@draw:transform='matrix(917.222222222222 0 0 917.222222222222 14821.9583333333 2159.23861112778)']/draw:text-box/text:p/text:span)"; + OUString sContent = getXPathContent(pXmlDoc, xpath); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"امُ عَلَيَْك"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); + + // Test for ٱلسََّل . It appears in the 3rd frame, i.e. after the امُ عَلَيَْك which is in the 2nd frame (from left to right) + // thus these two frames together appear as ٱلسََّل امُ عَلَيْكَ in Draw‬. + // FIXME: Should be ٱلسَّلَامُ عَلَيْكَ (i.e. the two text frames should be merged into one so that the ل and the ا will show as لَا rather than ل ا) + xpath = "string(//draw:frame[@draw:transform='matrix(917.222222222222 0 0 917.222222222222 17420.1666666667 2159.23861112778)']/draw:text-box/text:p/text:span)"; + sContent = getXPathContent(pXmlDoc, xpath); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"ٱلسََّل"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); + + // Test for "LibreOffice RTL" + xpath = "string(//draw:frame[@draw:transform='matrix(917.222222222222 0 0 917.222222222222 12779.375 5121.79583335)']/draw:text-box/text:p/text:span)"; + sContent = getXPathContent(pXmlDoc, xpath); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"LibreOffice RTL"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); + + // Test for "LibreOffice LTR (test)" + xpath = "string(//draw:frame[last()-1]/draw:text-box/text:p/text:span[last()])"; + sContent = getXPathContent(pXmlDoc, xpath); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"LibreOffice LTR (test)"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); + + /* Test for Chinese characters */ + // Use last() instead of matrix below, because the matrix may be different on different OS due to fallback of Chinese fonts. + xpath = "string(//draw:frame[last()]/draw:text-box/text:p/text:span)"; + sContent = getXPathContent(pXmlDoc, xpath); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"中文测试,中文"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); + + // Test pdf text run in the Writer PDF import filter + xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); + OString aOutput2; + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/qa/unit/data/tdf104597_textrun.pdf"), + new OutputWrapString(aOutput2), + nullptr); + xmlDocUniquePtr pXmlDoc2(xmlParseDoc(reinterpret_cast(aOutput2.getStr()))); + xpath = "string(//draw:frame[@draw:z-index='3'][1]/draw:text-box/text:p/text:span)"; + sContent = getXPathContent(pXmlDoc2, xpath).replaceAll("\n\n", " ").replaceAll("\n", ""); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput2.getStr(), OUString(u"ٱلَّسَل"), sContent); + xpath = "string(//draw:frame[@draw:z-index='2'][1]/draw:text-box/text:p/text:span)"; + sContent = getXPathContent(pXmlDoc2, xpath).replaceAll("\n\n", " ").replaceAll("\n", ""); + CPPUNIT_ASSERT_EQUAL(true, sContent.match(u"اُم َعَلْيَك")); + xpath = "string(//draw:frame[last()]/draw:text-box/text:p/text:span)"; + sContent = getXPathContent(pXmlDoc2, xpath).replaceAll("\n\n", " ").replaceAll("\n", ""); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput2.getStr(), OUString(u"中文测试,中文"), sContent); +#endif + } + + void testSpaces() + { +#if HAVE_FEATURE_POPPLER + rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); + xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); + + OString aOutput; + xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/qa/unit/data/testSpace.pdf"), + new OutputWrapString(aOutput), + nullptr); + xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); + + // Space test: there are 10 spaces, each space is expressed as a , + // thus the 10th text:s should exist and the attribute "text:c" should be "1". + OString xpath = "//draw:frame[@draw:z-index='1'][1]/draw:text-box/text:p/text:span/text:s[10]"; + OUString sContent = getXPath(pXmlDoc, xpath, "c"); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("1"), sContent); + + // Tab test: there are 10 tabs. Text before and after the tabs are shown in different draw frames. + // With the Liberation Serif font, the horizontal position of the first frame is 20.03mm and the + // second frame is 94.12mm. + xpath = "//draw:frame[@draw:z-index='2'][1]"; + sContent = getXPath(pXmlDoc, xpath, "transform"); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("translate( 20.03mm 25.05mm )"), sContent); + xpath = "//draw:frame[@draw:z-index='3'][1]"; + sContent = getXPath(pXmlDoc, xpath, "transform"); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("translate( 94.12mm 25.05mm )"), sContent); + + // Non-breaking space test: there are 10 NBSpaces, which are treated as the same as normal space in PDF, + // thus each is expressed as a . + // The 10th text:s should exist and the attribute "text:c" should be "1". + xpath = "//draw:frame[@draw:z-index='4'][1]/draw:text-box/text:p/text:span/text:s[10]"; + sContent = getXPath(pXmlDoc, xpath, "c"); + CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("1"), sContent); +#endif + } + + CPPUNIT_TEST_SUITE(PDFITest); + CPPUNIT_TEST(testXPDFParser); + CPPUNIT_TEST(testOdfWriterExport); + CPPUNIT_TEST(testOdfDrawExport); + CPPUNIT_TEST(testTdf96993); + CPPUNIT_TEST(testTdf98421); + CPPUNIT_TEST(testTdf105536); + CPPUNIT_TEST(testTdf141709_chinesechar); + CPPUNIT_TEST(testTdf78427_FontFeatures); + CPPUNIT_TEST(testTdf78427_FontWeight_MyraidProSemibold); + CPPUNIT_TEST(testTdf143959_nameFromFontFile); + CPPUNIT_TEST(testTdf104597_textrun); + CPPUNIT_TEST(testSpaces); + CPPUNIT_TEST_SUITE_END(); + }; + +} + +CPPUNIT_TEST_SUITE_REGISTRATION(PDFITest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sdext/source/pdfimport/test/testdocs/tdf104597_textrun.pdf b/sdext/source/pdfimport/test/testdocs/tdf104597_textrun.pdf deleted file mode 100644 index dcee96aa3169..000000000000 Binary files a/sdext/source/pdfimport/test/testdocs/tdf104597_textrun.pdf and /dev/null differ diff --git a/sdext/source/pdfimport/test/testdocs/tdf78427-MyraidPro-Semibold-Light.pdf b/sdext/source/pdfimport/test/testdocs/tdf78427-MyraidPro-Semibold-Light.pdf deleted file mode 100644 index 685da5db956c..000000000000 Binary files a/sdext/source/pdfimport/test/testdocs/tdf78427-MyraidPro-Semibold-Light.pdf and /dev/null differ diff --git a/sdext/source/pdfimport/test/testdocs/tdf78427-testFontFeatures.pdf b/sdext/source/pdfimport/test/testdocs/tdf78427-testFontFeatures.pdf deleted file mode 100644 index 0405d95f8425..000000000000 Binary files a/sdext/source/pdfimport/test/testdocs/tdf78427-testFontFeatures.pdf and /dev/null differ diff --git a/sdext/source/pdfimport/test/testdocs/testSpace.pdf b/sdext/source/pdfimport/test/testdocs/testSpace.pdf deleted file mode 100644 index 3c94f31ea15b..000000000000 Binary files a/sdext/source/pdfimport/test/testdocs/testSpace.pdf and /dev/null differ diff --git a/sdext/source/pdfimport/test/testdocs/testTdf141709_chinesechar.pdf b/sdext/source/pdfimport/test/testdocs/testTdf141709_chinesechar.pdf deleted file mode 100644 index 3198782faa73..000000000000 Binary files a/sdext/source/pdfimport/test/testdocs/testTdf141709_chinesechar.pdf and /dev/null differ diff --git a/sdext/source/pdfimport/test/testdocs/testTdf143959.pdf b/sdext/source/pdfimport/test/testdocs/testTdf143959.pdf deleted file mode 100644 index 594e734a5629..000000000000 Binary files a/sdext/source/pdfimport/test/testdocs/testTdf143959.pdf and /dev/null differ diff --git a/sdext/source/pdfimport/test/tests.cxx b/sdext/source/pdfimport/test/tests.cxx deleted file mode 100644 index 7c10c85b29a5..000000000000 --- a/sdext/source/pdfimport/test/tests.cxx +++ /dev/null @@ -1,904 +0,0 @@ -/* -*- 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/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include - -#include "outputwrap.hxx" -#include -#include -#include -#include -#include "../pdfiadaptor.hxx" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include -#include - -using namespace ::pdfparse; -using namespace ::pdfi; -using namespace ::com::sun::star; - -namespace -{ - - class TestSink : public ContentSink - { - public: - TestSink() : - m_nNextFontId( 1 ), - m_aIdToFont(), - m_aFontToId(), - m_aGCStack(1), - m_aPageSize(), - m_aHyperlinkBounds(), - m_aURI(), - m_aTextOut(), - m_nNumPages(0), - m_bPageEnded(false), - m_bRedCircleSeen(false), - m_bGreenStrokeSeen(false), - m_bDashedLineSeen(false), - m_bImageSeen(false) - {} - - void check() - { - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Width", 79400, m_aPageSize.Width, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "A4 page size (in 100th of points): Height", 59500, m_aPageSize.Height, 0.0000001 ); - CPPUNIT_ASSERT_MESSAGE( "endPage() called", m_bPageEnded ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Num pages equal one", sal_Int32(1), m_nNumPages ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.X1,34.7 ) ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.Y1,386.0) ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.X2,166.7) ); - CPPUNIT_ASSERT_MESSAGE( "Correct hyperlink bounding box", - rtl::math::approxEqual(m_aHyperlinkBounds.Y2,406.2) ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Correct hyperlink URI", OUString("http://download.openoffice.org/"), m_aURI ); - - const char* const sText = " \n \nThis is a testtext\nNew paragraph,\nnew line\n" - "Hyperlink, this is\n?\nThis is more text\noutline mode\n?\nNew paragraph\n"; - OString aTmp; - m_aTextOut.makeStringAndClear().convertToString( &aTmp, - RTL_TEXTENCODING_ASCII_US, - OUSTRING_TO_OSTRING_CVTFLAGS ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Imported text is \"This is a testtext New paragraph, new line" - " Hyperlink, this is * This is more text outline mode * New paragraph\"", - aTmp, OString(sText) ); - - CPPUNIT_ASSERT_MESSAGE( "red circle seen in input", m_bRedCircleSeen ); - CPPUNIT_ASSERT_MESSAGE( "green stroke seen in input", m_bGreenStrokeSeen ); - CPPUNIT_ASSERT_MESSAGE( "dashed line seen in input", m_bDashedLineSeen ); - CPPUNIT_ASSERT_MESSAGE( "image seen in input", m_bImageSeen ); - } - - private: - GraphicsContext& getCurrentContext() { return m_aGCStack.back(); } - - // ContentSink interface implementation - virtual void setPageNum( sal_Int32 nNumPages ) override - { - m_nNumPages = nNumPages; - } - - virtual void startPage( const geometry::RealSize2D& rSize ) override - { - m_aPageSize = rSize; - } - - virtual void endPage() override - { - m_bPageEnded = true; - } - - virtual void hyperLink( const geometry::RealRectangle2D& rBounds, - const OUString& rURI ) override - { - m_aHyperlinkBounds = rBounds; - m_aURI = rURI; - } - - virtual void pushState() override - { - GraphicsContextStack::value_type const a(m_aGCStack.back()); - m_aGCStack.push_back(a); - } - - virtual void popState() override - { - m_aGCStack.pop_back(); - } - - virtual void setTransformation( const geometry::AffineMatrix2D& rMatrix ) override - { - basegfx::unotools::homMatrixFromAffineMatrix( - getCurrentContext().Transformation, - rMatrix ); - } - - virtual void setLineDash( const uno::Sequence& dashes, - double start ) override - { - GraphicsContext& rContext( getCurrentContext() ); - if( dashes.hasElements() ) - comphelper::sequenceToContainer(rContext.DashArray,dashes); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "line dashing start offset", 0.0, start, 0.000000001 ); - } - - virtual void setFlatness( double nFlatness ) override - { - getCurrentContext().Flatness = nFlatness; - } - - virtual void setLineJoin(sal_Int8 nJoin) override - { - getCurrentContext().LineJoin = nJoin; - } - - virtual void setLineCap(sal_Int8 nCap) override - { - getCurrentContext().LineCap = nCap; - } - - virtual void setMiterLimit(double nVal) override - { - getCurrentContext().MiterLimit = nVal; - } - - virtual void setLineWidth(double nVal) override - { - getCurrentContext().LineWidth = nVal; - } - - virtual void setFillColor( const rendering::ARGBColor& rColor ) override - { - getCurrentContext().FillColor = rColor; - } - - virtual void setStrokeColor( const rendering::ARGBColor& rColor ) override - { - getCurrentContext().LineColor = rColor; - } - - virtual void setFont( const FontAttributes& rFont ) override - { - FontToIdMap::const_iterator it = m_aFontToId.find( rFont ); - if( it != m_aFontToId.end() ) - getCurrentContext().FontId = it->second; - else - { - m_aFontToId[ rFont ] = m_nNextFontId; - m_aIdToFont[ m_nNextFontId ] = rFont; - getCurrentContext().FontId = m_nNextFontId; - m_nNextFontId++; - } - } - - virtual void strokePath( const uno::Reference& rPath ) override - { - GraphicsContext& rContext( getCurrentContext() ); - basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aPath.transform( rContext.Transformation ); - - if( rContext.DashArray.empty() ) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 1.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is green", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_MESSAGE( "Line width is 0", - rtl::math::approxEqual(rContext.LineWidth, 28.3) ); - - static constexpr OUStringLiteral sExportString = u"m53570 7650-35430 24100"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is m535.7 518.5-354.3-241", - OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); - - m_bGreenStrokeSeen = true; - } - else - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Dash array consists of four entries", std::vector::size_type(4), rContext.DashArray.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 14.3764, rContext.DashArray[0], 1E-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[0], rContext.DashArray[1], 1E-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[1], rContext.DashArray[2], 1E-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( rContext.DashArray[2], rContext.DashArray[3], 1E-12 ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line width is 0", - 0, rContext.LineWidth, 0.0000001 ); - - static constexpr OUStringLiteral sExportString = u"m49890 5670.00000000001-35430 24090"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is m49890 5670.00000000001-35430 24090", - OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); - - m_bDashedLineSeen = true; - } - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", - rendering::BlendMode::NORMAL, rContext.BlendMode ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Join type is round", - rendering::PathJoinType::ROUND, rContext.LineJoin ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Cap type is butt", - rendering::PathCapType::BUTT, rContext.LineCap ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line miter limit is 10", - 10, rContext.MiterLimit, 0.0000001 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0", - 1, rContext.Flatness, 0.00000001 ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", - sal_Int32(0), rContext.FontId ); - } - - virtual void fillPath( const uno::Reference& rPath ) override - { - GraphicsContext& rContext( getCurrentContext() ); - basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aPath.transform( rContext.Transformation ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", - rendering::BlendMode::NORMAL, rContext.BlendMode ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 10", - 10, rContext.Flatness, 0.00000001 ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", - sal_Int32(0), rContext.FontId ); - } - - virtual void eoFillPath( const uno::Reference& rPath ) override - { - GraphicsContext& rContext( getCurrentContext() ); - basegfx::B2DPolyPolygon aPath = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - aPath.transform( rContext.Transformation ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 1.0, rContext.LineColor.Alpha, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Blue, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Green, 0.00000001); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Line color is black", 0.0, rContext.LineColor.Red, 0.00000001); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Blend mode is normal", - rendering::BlendMode::NORMAL, rContext.BlendMode ); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "Flatness is 0", - 1, rContext.Flatness, 0.00000001 ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Font id is 0", - sal_Int32(0), rContext.FontId ); - - static constexpr OUStringLiteral sExportString - = u"m12050 49610c-4310 0-7800-3490-7800-7800 0-4300 " - "3490-7790 7800-7790 4300 0 7790 3490 7790 7790 0 4310-3490 7800-7790 7800z"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( "Stroke is a 4-bezier circle", - OUString(sExportString), basegfx::utils::exportToSvgD( aPath, true, true, false ) ); - - m_bRedCircleSeen = true; - } - - virtual void intersectClip(const uno::Reference& rPath) override - { - basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; - - if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) - aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); - - getCurrentContext().Clip = aNewClip; - } - - virtual void intersectEoClip(const uno::Reference& rPath) override - { - basegfx::B2DPolyPolygon aNewClip = basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(rPath); - basegfx::B2DPolyPolygon aCurClip = getCurrentContext().Clip; - - if( aCurClip.count() ) // #i92985# adapted API from (..., false, false) to (..., true, false) - aNewClip = basegfx::utils::clipPolyPolygonOnPolyPolygon( aCurClip, aNewClip, true, false ); - - getCurrentContext().Clip = aNewClip; - } - - virtual void drawGlyphs( const OUString& rGlyphs, - const geometry::RealRectangle2D& /*rRect*/, - const geometry::Matrix2D& /*rFontMatrix*/, - double /*fontSize*/) override - { - m_aTextOut.append(rGlyphs); - } - - virtual void endText() override - { - m_aTextOut.append( "\n" ); - } - - virtual void drawMask(const uno::Sequence& xBitmap, - bool /*bInvert*/ ) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask received two properties", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask got URL param", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMask got InputStream param", - OUString("InputStream"), xBitmap[1].Name ); - } - - virtual void drawImage(const uno::Sequence& xBitmap ) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage received two properties", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage got URL param", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawImage got InputStream param", - OUString("InputStream"), xBitmap[1].Name ); - m_bImageSeen = true; - } - - virtual void drawColorMaskedImage(const uno::Sequence& xBitmap, - const uno::Sequence& /*xMaskColors*/ ) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage received two properties", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage got URL param", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawColorMaskedImage got InputStream param", - OUString("InputStream"), xBitmap[1].Name ); - } - - virtual void drawMaskedImage(const uno::Sequence& xBitmap, - const uno::Sequence& xMask, - bool /*bInvertMask*/) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #1", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got URL param #1", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got InputStream param #1", - OUString("InputStream"), xBitmap[1].Name ); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage received two properties #2", - sal_Int32(3), xMask.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got URL param #2", - OUString("URL"), xMask[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawMaskedImage got InputStream param #2", - OUString("InputStream"), xMask[1].Name ); - } - - virtual void drawAlphaMaskedImage(const uno::Sequence& xBitmap, - const uno::Sequence& xMask) override - { - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #1", - sal_Int32(3), xBitmap.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got URL param #1", - OUString("URL"), xBitmap[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got InputStream param #1", - OUString("InputStream"), xBitmap[1].Name ); - - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage received two properties #2", - sal_Int32(3), xMask.getLength() ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got URL param #2", - OUString("URL"), xMask[0].Name ); - CPPUNIT_ASSERT_EQUAL_MESSAGE( "drawAlphaMaskedImage got InputStream param #2", - OUString("InputStream"), xMask[1].Name ); - } - - virtual void setTextRenderMode( sal_Int32 ) override - { - } - - typedef std::unordered_map IdToFontMap; - typedef std::unordered_map FontToIdMap; - - typedef std::vector GraphicsContextStack; - - sal_Int32 m_nNextFontId; - IdToFontMap m_aIdToFont; - FontToIdMap m_aFontToId; - - GraphicsContextStack m_aGCStack; - geometry::RealSize2D m_aPageSize; - geometry::RealRectangle2D m_aHyperlinkBounds; - OUString m_aURI; - OUStringBuffer m_aTextOut; - sal_Int32 m_nNumPages; - bool m_bPageEnded; - bool m_bRedCircleSeen; - bool m_bGreenStrokeSeen; - bool m_bDashedLineSeen; - bool m_bImageSeen; - }; - - class PDFITest : public test::BootstrapFixture, public XmlTestTools - { - protected: - virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override - { - XmlTestTools::registerODFNamespaces(pXmlXPathCtx); - }; - public: - void testXPDFParser() - { -#if HAVE_FEATURE_POPPLER - auto pSink = std::make_shared(); - CPPUNIT_ASSERT( - pdfi::xpdf_ImportFromFile( - m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), - pSink, - uno::Reference< task::XInteractionHandler >(), - OUString(), - getComponentContext(), "" ) ); - pSink->check(); -#endif - } - - void testOdfDrawExport() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor( new pdfi::PDFIRawAdaptor(OUString(), getComponentContext()) ); - xAdaptor->setTreeVisitorFactory( createDrawTreeVisitorFactory() ); - - OUString tempFileURL; - CPPUNIT_ASSERT_EQUAL( osl::File::E_None, osl::File::createTempFile( nullptr, nullptr, &tempFileURL ) ); - osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), - new OutputWrap(tempFileURL), - nullptr )); - osl::File::remove( tempFileURL ); -#endif - } - - void testOdfWriterExport() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor( new pdfi::PDFIRawAdaptor(OUString(), getComponentContext()) ); - xAdaptor->setTreeVisitorFactory( createWriterTreeVisitorFactory() ); - - OUString tempFileURL; - CPPUNIT_ASSERT_EQUAL( osl::File::E_None, osl::File::createTempFile( nullptr, nullptr, &tempFileURL ) ); - osl::File::remove( tempFileURL ); // FIXME the below apparently fails silently if the file already exists - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testinput.pdf"), - new OutputWrap(tempFileURL), - nullptr )); - osl::File::remove( tempFileURL ); -#endif - } - - void testTdf96993() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf96993.pdf"), - new OutputWrapString(aOutput), - nullptr)); - // This ensures that the imported image arrives properly flipped - CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"matrix(18520.8333333333 0 0 26281.9444444444 0 0)\"") != -1); -#endif - } - - void testTdf98421() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf96993.pdf"), - new OutputWrapString(aOutput), - nullptr)); - // This ensures that the imported image arrives properly flipped - CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"scale( 1.0 -1.0 ) translate( 0mm 0mm )\"") != -1); - CPPUNIT_ASSERT(aOutput.indexOf("svg:height=\"-262.82mm\"") != -1); -#endif - } - - void testTdf105536() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testTdf105536.pdf"), - new OutputWrapString(aOutput), - nullptr)); - // This ensures that the imported image arrives properly flipped - CPPUNIT_ASSERT(aOutput.indexOf("draw:transform=\"matrix(-21488.4 0 0 -27978.1 21488.4 27978.1)\"") != -1); -#endif - } - - void testTdf141709_chinesechar() - { -// this test crashes on the windows jenkins boxes, but no-one can catch it locally -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Exporting to ODF", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testdocs/testTdf141709_chinesechar.pdf"), - new OutputWrapString(aOutput), - nullptr)); - xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); - // This ensures that the imported text contains all of the characters - OString xpath = "//draw:frame[@draw:z-index='3'][1]/draw:text-box/text:p/text:span[1]"; - OUString sContent = getXPathContent(pXmlDoc, xpath).replaceAll("\n", ""); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"敏捷的狐狸跨过慵懒的"), sContent); - xpath = "//draw:frame[@draw:z-index='4'][1]/draw:text-box/text:p/text:span[1]"; - sContent = getXPathContent(pXmlDoc, xpath).replaceAll("\n", ""); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"狗。"), sContent); -#endif - } - - void testTdf78427_FontFeatures() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", - xAdaptor->odfConvert( m_directories.getURLFromSrc( - u"/sdext/source/pdfimport/test/testdocs/tdf78427-testFontFeatures.pdf"), - new OutputWrapString(aOutput), - nullptr )); - // Un-comment the following debug line to see the content of generated XML content in - // workdir/CppunitTest/sdext_pdfimport.test.log after running "make CppunitTest_sdext_pdfimport". - //std::cout << aOutput << std::endl; - xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); - //CPPUNIT_ASSERT(pXmlDoc); - - /* Test for the 1st paragraph */ - OUString styleName = getXPath(pXmlDoc, "//draw:frame[1]//text:span[1]", "style-name"); - OString xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font-weight and font-style should be normal - assertXPath(pXmlDoc, xpath, "font-weight", "normal"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - - /* Test for the 2nd paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[2]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // there should be a font-weight="bold", but no font-style italic - assertXPath(pXmlDoc, xpath, "font-weight", "bold"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - - /* Test for the 3rd paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[3]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // there should be a font-style="italic", but no font-weight bold - assertXPath(pXmlDoc, xpath, "font-weight", "normal"); - assertXPath(pXmlDoc, xpath, "font-style", "italic"); - - /* Test for the 4th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[4]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // there should be both font-style="italic" and font-weight="bold" - assertXPath(pXmlDoc, xpath, "font-weight", "bold"); - assertXPath(pXmlDoc, xpath, "font-style", "italic"); - - /* Test for the 5th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[5]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be Arial and font-weight="bold", no font-style - assertXPath(pXmlDoc, xpath, "font-family", "Arial"); - assertXPath(pXmlDoc, xpath, "font-weight", "bold"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - - /* Test for the 6th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[6]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be Arial without font-weight and font-style - assertXPath(pXmlDoc, xpath, "font-family", "Arial"); - assertXPath(pXmlDoc, xpath, "font-weight", "normal"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - - /* Test for the 7th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[7]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be SimSun without font-weight and font-style - assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); // TODO: tdf#143095 use localized font name rather than PS name - assertXPath(pXmlDoc, xpath, "font-weight", "normal"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - - /* Test for the 8th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[8]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be SimSun and font-weight="bold", no font-style italic - assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); - assertXPath(pXmlDoc, xpath, "font-weight", "bold"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - - /* Test for the 9th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[9]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be SimSun, font-weight should be "normal", font-style="italic" - assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); - assertXPath(pXmlDoc, xpath, "font-weight", "normal"); - // FIXME and remove the below comment: - // the chinese chars are shown in pdf as faux italic (fake italic). It is currencly imported wrongly as normal font style. - // See tdf#78427 for how the faux bold problem was handled. Faux italic may be handled using the transformation pattern. - // assertXPath(pXmlDoc, xpath, "font-style", "italic"); - - /* Test for the 10th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[10]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be SimSun font-weight="bold" and font-style="italic" - assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); - assertXPath(pXmlDoc, xpath, "font-weight", "bold"); - // FIXME: faux italic, see above - // assertXPath(pXmlDoc, xpath, "font-style", "italic"); - - /* Test for the 11th paragraph */ - styleName = getXPath(pXmlDoc, "//draw:frame[11]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font should be SimSun and there should be style:text-outline="true" - // (i.e., the real "outline" font rather than faux bold / fake bold) - assertXPath(pXmlDoc, xpath, "font-family", "SimSun"); - assertXPath(pXmlDoc, xpath, "font-weight", "normal"); - assertXPathNoAttribute(pXmlDoc, xpath, "font-style"); - assertXPath(pXmlDoc, xpath, "text-outline", "true"); -#endif - } - - void testTdf78427_FontWeight_MyraidProSemibold() // Related to attachment 155937. - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", - xAdaptor->odfConvert( m_directories.getURLFromSrc( - u"/sdext/source/pdfimport/test/testdocs/tdf78427-MyraidPro-Semibold-Light.pdf"), - new OutputWrapString(aOutput), - nullptr )); - //std::cout << aOutput << std::endl; - - xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); - //CPPUNIT_ASSERT(pXmlDoc); - - // The for the 1st frame */ - OUString styleName = getXPath(pXmlDoc, "//draw:frame[1]//text:span[1]", "style-name"); - OString xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font-weight and font-style should be 600 (Semibold) - assertXPath(pXmlDoc, xpath, "font-weight", "600"); - - // The for the 2nd frame */ - styleName = getXPath(pXmlDoc, "//draw:frame[2]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - // the font-weight and font-style should be 300 (Light) - assertXPath(pXmlDoc, xpath, "font-weight", "300"); -#endif - } - - void testTdf143959_nameFromFontFile() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", - xAdaptor->odfConvert( m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testdocs/testTdf143959.pdf"), - new OutputWrapString(aOutput), - nullptr )); - - //std::cout << aOutput << std::endl; - xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); - - /* Test for the 1st text paragraph */ - OUString styleName = getXPath(pXmlDoc, "//draw:frame[2]//text:span[1]", "style-name"); - OString xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - CPPUNIT_ASSERT_EQUAL(OUString("TimesNewRoman"), - getXPath(pXmlDoc, xpath, "font-family").replaceAll(u" ", u"")); - - /* Test for the "TOTAL ESTA HOJA USD" paragraph" */ - styleName = getXPath(pXmlDoc, "//draw:frame[last()-1]//text:span[1]", "style-name"); - xpath = "//office:automatic-styles/style:style[@style:name=\"" + - OUStringToOString(styleName, RTL_TEXTENCODING_UTF8) + - "\"]/style:text-properties"; - CPPUNIT_ASSERT_EQUAL(OUString("TimesNewRoman"), - getXPath(pXmlDoc, xpath, "font-family").replaceAll(u" ", u"")); - CPPUNIT_ASSERT_EQUAL(OUString("bold"), - getXPath(pXmlDoc, xpath, "font-weight")); -#endif - } - - void testTdf104597_textrun() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createDrawTreeVisitorFactory()); - - OString aOutput; - CPPUNIT_ASSERT_MESSAGE("Converting PDF to ODF XML", - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testdocs/tdf104597_textrun.pdf"), - new OutputWrapString(aOutput), - nullptr)); - - xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); - - // Test for امُ عَلَيْكَ - OString xpath = "string(//draw:frame[@draw:transform='matrix(917.222222222222 0 0 917.222222222222 14821.9583333333 2159.23861112778)']/draw:text-box/text:p/text:span)"; - OUString sContent = getXPathContent(pXmlDoc, xpath); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"امُ عَلَيَْك"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); - - // Test for ٱلسََّل . It appears in the 3rd frame, i.e. after the امُ عَلَيَْك which is in the 2nd frame (from left to right) - // thus these two frames together appear as ٱلسََّل امُ عَلَيْكَ in Draw‬. - // FIXME: Should be ٱلسَّلَامُ عَلَيْكَ (i.e. the two text frames should be merged into one so that the ل and the ا will show as لَا rather than ل ا) - xpath = "string(//draw:frame[@draw:transform='matrix(917.222222222222 0 0 917.222222222222 17420.1666666667 2159.23861112778)']/draw:text-box/text:p/text:span)"; - sContent = getXPathContent(pXmlDoc, xpath); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"ٱلسََّل"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); - - // Test for "LibreOffice RTL" - xpath = "string(//draw:frame[@draw:transform='matrix(917.222222222222 0 0 917.222222222222 12779.375 5121.79583335)']/draw:text-box/text:p/text:span)"; - sContent = getXPathContent(pXmlDoc, xpath); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"LibreOffice RTL"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); - - // Test for "LibreOffice LTR (test)" - xpath = "string(//draw:frame[last()-1]/draw:text-box/text:p/text:span[last()])"; - sContent = getXPathContent(pXmlDoc, xpath); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"LibreOffice LTR (test)"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); - - /* Test for Chinese characters */ - // Use last() instead of matrix below, because the matrix may be different on different OS due to fallback of Chinese fonts. - xpath = "string(//draw:frame[last()]/draw:text-box/text:p/text:span)"; - sContent = getXPathContent(pXmlDoc, xpath); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString(u"中文测试,中文"), sContent.replaceAll("\n\n", " ").replaceAll("\n", "")); - - // Test pdf text run in the Writer PDF import filter - xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); - OString aOutput2; - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testdocs/tdf104597_textrun.pdf"), - new OutputWrapString(aOutput2), - nullptr); - xmlDocUniquePtr pXmlDoc2(xmlParseDoc(reinterpret_cast(aOutput2.getStr()))); - xpath = "string(//draw:frame[@draw:z-index='3'][1]/draw:text-box/text:p/text:span)"; - sContent = getXPathContent(pXmlDoc2, xpath).replaceAll("\n\n", " ").replaceAll("\n", ""); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput2.getStr(), OUString(u"ٱلَّسَل"), sContent); - xpath = "string(//draw:frame[@draw:z-index='2'][1]/draw:text-box/text:p/text:span)"; - sContent = getXPathContent(pXmlDoc2, xpath).replaceAll("\n\n", " ").replaceAll("\n", ""); - CPPUNIT_ASSERT_EQUAL(true, sContent.match(u"اُم َعَلْيَك")); - xpath = "string(//draw:frame[last()]/draw:text-box/text:p/text:span)"; - sContent = getXPathContent(pXmlDoc2, xpath).replaceAll("\n\n", " ").replaceAll("\n", ""); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput2.getStr(), OUString(u"中文测试,中文"), sContent); -#endif - } - - void testSpaces() - { -#if HAVE_FEATURE_POPPLER - rtl::Reference xAdaptor(new pdfi::PDFIRawAdaptor(OUString(), getComponentContext())); - xAdaptor->setTreeVisitorFactory(createWriterTreeVisitorFactory()); - - OString aOutput; - xAdaptor->odfConvert(m_directories.getURLFromSrc(u"/sdext/source/pdfimport/test/testdocs/testSpace.pdf"), - new OutputWrapString(aOutput), - nullptr); - xmlDocUniquePtr pXmlDoc(xmlParseDoc(reinterpret_cast(aOutput.getStr()))); - - // Space test: there are 10 spaces, each space is expressed as a , - // thus the 10th text:s should exist and the attribute "text:c" should be "1". - OString xpath = "//draw:frame[@draw:z-index='1'][1]/draw:text-box/text:p/text:span/text:s[10]"; - OUString sContent = getXPath(pXmlDoc, xpath, "c"); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("1"), sContent); - - // Tab test: there are 10 tabs. Text before and after the tabs are shown in different draw frames. - // With the Liberation Serif font, the horizontal position of the first frame is 20.03mm and the - // second frame is 94.12mm. - xpath = "//draw:frame[@draw:z-index='2'][1]"; - sContent = getXPath(pXmlDoc, xpath, "transform"); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("translate( 20.03mm 25.05mm )"), sContent); - xpath = "//draw:frame[@draw:z-index='3'][1]"; - sContent = getXPath(pXmlDoc, xpath, "transform"); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("translate( 94.12mm 25.05mm )"), sContent); - - // Non-breaking space test: there are 10 NBSpaces, which are treated as the same as normal space in PDF, - // thus each is expressed as a . - // The 10th text:s should exist and the attribute "text:c" should be "1". - xpath = "//draw:frame[@draw:z-index='4'][1]/draw:text-box/text:p/text:span/text:s[10]"; - sContent = getXPath(pXmlDoc, xpath, "c"); - CPPUNIT_ASSERT_EQUAL_MESSAGE(aOutput.getStr(), OUString("1"), sContent); -#endif - } - - CPPUNIT_TEST_SUITE(PDFITest); - CPPUNIT_TEST(testXPDFParser); - CPPUNIT_TEST(testOdfWriterExport); - CPPUNIT_TEST(testOdfDrawExport); - CPPUNIT_TEST(testTdf96993); - CPPUNIT_TEST(testTdf98421); - CPPUNIT_TEST(testTdf105536); - CPPUNIT_TEST(testTdf141709_chinesechar); - CPPUNIT_TEST(testTdf78427_FontFeatures); - CPPUNIT_TEST(testTdf78427_FontWeight_MyraidProSemibold); - CPPUNIT_TEST(testTdf143959_nameFromFontFile); - CPPUNIT_TEST(testTdf104597_textrun); - CPPUNIT_TEST(testSpaces); - CPPUNIT_TEST_SUITE_END(); - }; - -} - -CPPUNIT_TEST_SUITE_REGISTRATION(PDFITest); - -CPPUNIT_PLUGIN_IMPLEMENT(); - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit