summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/vcl/pdfextoutdevdata.hxx2
-rw-r--r--vcl/Module_vcl.mk6
-rw-r--r--vcl/qa/cppunit/pdfexport/data/tdf106702.odtbin0 -> 42158 bytes
-rw-r--r--vcl/qa/cppunit/pdfexport/pdfexport.cxx85
-rw-r--r--vcl/source/gdi/pdfextoutdevdata.cxx25
-rw-r--r--vcl/source/gdi/pdfwriter_impl2.cxx2
6 files changed, 96 insertions, 24 deletions
diff --git a/include/vcl/pdfextoutdevdata.hxx b/include/vcl/pdfextoutdevdata.hxx
index 22079323580c..b8bbe589d491 100644
--- a/include/vcl/pdfextoutdevdata.hxx
+++ b/include/vcl/pdfextoutdevdata.hxx
@@ -97,7 +97,7 @@ public:
PDFExtOutDevData( const OutputDevice& rOutDev );
virtual ~PDFExtOutDevData() override;
- bool PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAction );
+ bool PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAction, const GDIMetaFile& rMtf );
void ResetSyncData();
void PlayGlobalActions( PDFWriter& rWriter );
diff --git a/vcl/Module_vcl.mk b/vcl/Module_vcl.mk
index e27b4db56ab9..40fee27321b4 100644
--- a/vcl/Module_vcl.mk
+++ b/vcl/Module_vcl.mk
@@ -173,10 +173,14 @@ $(eval $(call gb_Module_add_check_targets,vcl,\
CppunitTest_vcl_app_test \
CppunitTest_vcl_jpeg_read_write_test \
CppunitTest_vcl_svm_test \
- CppunitTest_vcl_pdfexport \
CppunitTest_vcl_errorhandler \
))
+ifneq (,$(filter PDFIUM,$(BUILD_TYPE)))
+$(eval $(call gb_Module_add_check_targets,vcl,\
+ CppunitTest_vcl_pdfexport \
+))
+endif
ifeq ($(USING_X11),TRUE)
$(eval $(call gb_Module_add_check_targets,vcl,\
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf106702.odt b/vcl/qa/cppunit/pdfexport/data/tdf106702.odt
new file mode 100644
index 000000000000..da3b7e81456e
--- /dev/null
+++ b/vcl/qa/cppunit/pdfexport/data/tdf106702.odt
Binary files differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index b2ebb23cf6cd..9e6924f2e66a 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -24,11 +24,9 @@
#include <unotools/tempfile.hxx>
#include <vcl/filter/pdfdocument.hxx>
#include <tools/zcodec.hxx>
-#if HAVE_FEATURE_PDFIUM
#include <fpdf_edit.h>
#include <fpdf_text.h>
#include <fpdfview.h>
-#endif
using namespace ::com::sun::star;
@@ -40,15 +38,12 @@ class PdfExportTest : public test::BootstrapFixture, public unotest::MacrosTest
{
uno::Reference<uno::XComponentContext> mxComponentContext;
uno::Reference<lang::XComponent> mxComponent;
-#if HAVE_FEATURE_PDFIUM
FPDF_PAGE mpPdfPage = nullptr;
FPDF_DOCUMENT mpPdfDocument = nullptr;
-#endif
public:
virtual void setUp() override;
virtual void tearDown() override;
-#if HAVE_FEATURE_PDFIUM
void load(const OUString& rFile, vcl::filter::PDFDocument& rDocument);
/// Tests that a pdf image is roundtripped back to PDF as a vector format.
void testTdf106059();
@@ -79,12 +74,11 @@ public:
/// Text extracting RTL text with ligatures.
void testTdf115117_2a();
#endif
- void testTdf105954();
-#endif
void testTdf109143();
+ void testTdf105954();
+ void testTdf106702();
CPPUNIT_TEST_SUITE(PdfExportTest);
-#if HAVE_FEATURE_PDFIUM
CPPUNIT_TEST(testTdf106059);
CPPUNIT_TEST(testTdf105461);
CPPUNIT_TEST(testTdf107868);
@@ -105,9 +99,9 @@ public:
CPPUNIT_TEST(testTdf115117_2);
CPPUNIT_TEST(testTdf115117_2a);
#endif
- CPPUNIT_TEST(testTdf105954);
-#endif
CPPUNIT_TEST(testTdf109143);
+ CPPUNIT_TEST(testTdf105954);
+ CPPUNIT_TEST(testTdf106702);
CPPUNIT_TEST_SUITE_END();
};
@@ -118,23 +112,19 @@ void PdfExportTest::setUp()
mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory()));
mxDesktop.set(frame::Desktop::create(mxComponentContext));
-#if HAVE_FEATURE_PDFIUM
FPDF_LIBRARY_CONFIG config;
config.version = 2;
config.m_pUserFontPaths = nullptr;
config.m_pIsolate = nullptr;
config.m_v8EmbedderSlot = 0;
FPDF_InitLibraryWithConfig(&config);
-#endif
}
void PdfExportTest::tearDown()
{
-#if HAVE_FEATURE_PDFIUM
FPDF_ClosePage(mpPdfPage);
FPDF_CloseDocument(mpPdfDocument);
FPDF_DestroyLibrary();
-#endif
if (mxComponent.is())
mxComponent->dispose();
@@ -142,8 +132,6 @@ void PdfExportTest::tearDown()
test::BootstrapFixture::tearDown();
}
-#if HAVE_FEATURE_PDFIUM
-
char const DATA_DIRECTORY[] = "/vcl/qa/cppunit/pdfexport/data/";
void PdfExportTest::load(const OUString& rFile, vcl::filter::PDFDocument& rDocument)
@@ -1066,7 +1054,70 @@ void PdfExportTest::testTdf105954()
CPPUNIT_ASSERT_LESS(static_cast<unsigned int>(250), aMeta.width);
}
-#endif
+void PdfExportTest::testTdf106702()
+{
+ // Import the bugdoc and export as PDF.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf106702.odt";
+ mxComponent = loadFromDesktop(aURL);
+ CPPUNIT_ASSERT(mxComponent.is());
+
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ utl::TempFile aTempFile;
+ aTempFile.EnableKillingFile();
+ utl::MediaDescriptor aMediaDescriptor;
+ aMediaDescriptor["FilterName"] <<= OUString("writer_pdf_Export");
+ xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
+
+ // Parse the export result with pdfium.
+ SvFileStream aFile(aTempFile.GetURL(), StreamMode::READ);
+ SvMemoryStream aMemory;
+ aMemory.WriteStream(aFile);
+ mpPdfDocument
+ = FPDF_LoadMemDocument(aMemory.GetData(), aMemory.GetSize(), /*password=*/nullptr);
+ CPPUNIT_ASSERT(mpPdfDocument);
+
+ // The document has two pages.
+ CPPUNIT_ASSERT_EQUAL(2, FPDF_GetPageCount(mpPdfDocument));
+
+ // First page already has the correct image position.
+ mpPdfPage = FPDF_LoadPage(mpPdfDocument, /*page_index=*/0);
+ CPPUNIT_ASSERT(mpPdfPage);
+ int nExpected = 0;
+ int nPageObjectCount = FPDFPage_CountObjects(mpPdfPage);
+ for (int i = 0; i < nPageObjectCount; ++i)
+ {
+ FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(mpPdfPage, i);
+ if (FPDFPageObj_GetType(pPageObject) != FPDF_PAGEOBJ_IMAGE)
+ continue;
+
+ float fLeft = 0, fBottom = 0, fRight = 0, fTop = 0;
+ FPDFPageObj_GetBounds(pPageObject, &fLeft, &fBottom, &fRight, &fTop);
+ nExpected = fTop;
+ break;
+ }
+
+ // Second page had an incorrect image position.
+ FPDF_ClosePage(mpPdfPage);
+ mpPdfPage = FPDF_LoadPage(mpPdfDocument, /*page_index=*/1);
+ CPPUNIT_ASSERT(mpPdfPage);
+ int nActual = 0;
+ nPageObjectCount = FPDFPage_CountObjects(mpPdfPage);
+ for (int i = 0; i < nPageObjectCount; ++i)
+ {
+ FPDF_PAGEOBJECT pPageObject = FPDFPage_GetObject(mpPdfPage, i);
+ if (FPDFPageObj_GetType(pPageObject) != FPDF_PAGEOBJ_IMAGE)
+ continue;
+
+ float fLeft = 0, fBottom = 0, fRight = 0, fTop = 0;
+ FPDFPageObj_GetBounds(pPageObject, &fLeft, &fBottom, &fRight, &fTop);
+ nActual = fTop;
+ break;
+ }
+
+ // This failed, vertical pos is 818 points, was 1674 (outside visible page
+ // bounds).
+ CPPUNIT_ASSERT_EQUAL(nExpected, nActual);
+}
CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/vcl/source/gdi/pdfextoutdevdata.cxx b/vcl/source/gdi/pdfextoutdevdata.cxx
index 3c689c3ccce0..a31a7d568201 100644
--- a/vcl/source/gdi/pdfextoutdevdata.cxx
+++ b/vcl/source/gdi/pdfextoutdevdata.cxx
@@ -22,6 +22,7 @@
#include <vcl/outdev.hxx>
#include <vcl/gfxlink.hxx>
#include <vcl/dllapi.h>
+#include <vcl/metaact.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
@@ -301,7 +302,7 @@ struct PageSyncData
{ mpGlobalData = pGlobal; }
void PushAction( const OutputDevice& rOutDev, const PDFExtOutDevDataSync::Action eAct );
- bool PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAction, const PDFExtOutDevData& rOutDevData );
+ bool PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAction, const GDIMetaFile& rMtf, const PDFExtOutDevData& rOutDevData );
};
void PageSyncData::PushAction( const OutputDevice& rOutDev, const PDFExtOutDevDataSync::Action eAct )
@@ -317,7 +318,7 @@ void PageSyncData::PushAction( const OutputDevice& rOutDev, const PDFExtOutDevDa
aSync.nIdx = 0x7fffffff; // sync not possible
mActions.push_back( aSync );
}
-bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAction, const PDFExtOutDevData& rOutDevData )
+bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAction, const GDIMetaFile& rMtf, const PDFExtOutDevData& rOutDevData )
{
bool bRet = false;
if ( mActions.size() && ( mActions.front().nIdx == rCurGDIMtfAction ) )
@@ -463,6 +464,22 @@ bool PageSyncData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rCurGDIMtfAc
if( pData && nBytes )
{
aTmp.WriteBytes( pData, nBytes );
+
+ // Look up the output rectangle from the previous
+ // bitmap scale action if possible. This has the
+ // correct position for images repeated in
+ // Writer headers/footers for non-first pages.
+ if (rCurGDIMtfAction > 0)
+ {
+ const MetaAction* pAction = rMtf.GetAction(rCurGDIMtfAction - 1);
+ if (pAction && pAction->GetType() == MetaActionType::BMPSCALE)
+ {
+ const MetaBmpScaleAction* pA
+ = static_cast<const MetaBmpScaleAction*>(pAction);
+ aOutputRect.SetPos(pA->GetPoint());
+ }
+ }
+
rWriter.DrawJPGBitmap( aTmp, aGraphic.GetBitmap().GetBitCount() > 8, aGraphic.GetSizePixel(), aOutputRect, aMask, aGraphic );
}
@@ -584,9 +601,9 @@ void PDFExtOutDevData::ResetSyncData()
{
*mpPageSyncData = PageSyncData( mpGlobalSyncData );
}
-bool PDFExtOutDevData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rIdx )
+bool PDFExtOutDevData::PlaySyncPageAct( PDFWriter& rWriter, sal_uInt32& rIdx, const GDIMetaFile& rMtf )
{
- return mpPageSyncData->PlaySyncPageAct( rWriter, rIdx, *this );
+ return mpPageSyncData->PlaySyncPageAct( rWriter, rIdx, rMtf, *this );
}
void PDFExtOutDevData::PlayGlobalActions( PDFWriter& rWriter )
{
diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx
index 9bc58989a46c..e4f567d6bfd9 100644
--- a/vcl/source/gdi/pdfwriter_impl2.cxx
+++ b/vcl/source/gdi/pdfwriter_impl2.cxx
@@ -267,7 +267,7 @@ void PDFWriterImpl::playMetafile( const GDIMetaFile& i_rMtf, vcl::PDFExtOutDevDa
for( sal_uInt32 i = 0, nCount = aMtf.GetActionSize(); i < nCount; )
{
- if ( !i_pOutDevData || !i_pOutDevData->PlaySyncPageAct( m_rOuterFace, i ) )
+ if ( !i_pOutDevData || !i_pOutDevData->PlaySyncPageAct( m_rOuterFace, i, aMtf ) )
{
const MetaAction* pAction = aMtf.GetAction( i );
const MetaActionType nType = pAction->GetType();