filter/qa/pdf.cxx | 45 ++++++++++++++++++++++++++++++++++++++++ filter/source/pdf/pdfexport.cxx | 35 ++++++++++++++++++++++--------- filter/source/pdf/pdfexport.hxx | 1 3 files changed, 71 insertions(+), 10 deletions(-)
New commits: commit 175e514c93b3696faa8c331c8b8f56e832ceb4c1 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Wed Nov 23 09:59:05 2022 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Wed Nov 23 10:42:55 2022 +0100 Related: tdf#54053 PDF export: add UNO API to customize the watermark font size The font height of the watermark text is currently automatic: we start with a value based on the page size and then decrease it till the text fits. The problem is that sometimes you want a smaller value, but specifying this was not possible. Fix the problem by adding a new "WatermarkFontHeight" PDF export filter option to specify the font size explicitly. Example cmdline usage: soffice --convert-to pdf:writer_pdf_Export:'{"Watermark":{"type":"string","value":"draft"}, "WatermarkFontHeight":{"type":"long","value":"100"}}' test.odt Change-Id: Iceab943b7a995badfcdc6b12ecc9264e39e4a3a2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143135 Reviewed-by: Miklos Vajna <vmik...@collabora.com> Tested-by: Jenkins diff --git a/filter/qa/pdf.cxx b/filter/qa/pdf.cxx index 8b9b0d4db788..4c8a9a2dc7dc 100644 --- a/filter/qa/pdf.cxx +++ b/filter/qa/pdf.cxx @@ -187,6 +187,51 @@ CPPUNIT_TEST_FIXTURE(Test, testWatermarkColor) // i.e. the color was the (default) green, not red. CPPUNIT_ASSERT_EQUAL(Color(ColorTransparency, 0xff0000), aFillColor); } + +CPPUNIT_TEST_FIXTURE(Test, testWatermarkFontHeight) +{ + // Given an empty Writer document: + std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); + if (!pPDFium) + return; + mxComponent.set(loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument")); + + // When exporting that as PDF with a red watermark: + uno::Reference<css::lang::XMultiServiceFactory> xFactory = getMultiServiceFactory(); + uno::Reference<document::XFilter> xFilter( + xFactory->createInstance("com.sun.star.document.PDFFilter"), uno::UNO_QUERY); + uno::Reference<document::XExporter> xExporter(xFilter, uno::UNO_QUERY); + xExporter->setSourceDocument(mxComponent); + SvMemoryStream aStream; + uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream)); + sal_Int32 nExpectedFontSize = 100; + uno::Sequence<beans::PropertyValue> aFilterData{ + comphelper::makePropertyValue("Watermark", OUString("X")), + comphelper::makePropertyValue("WatermarkFontHeight", nExpectedFontSize), + }; + uno::Sequence<beans::PropertyValue> aDescriptor{ + comphelper::makePropertyValue("FilterName", OUString("writer_pdf_Export")), + comphelper::makePropertyValue("FilterData", aFilterData), + comphelper::makePropertyValue("OutputStream", xOutputStream), + }; + xFilter->filter(aDescriptor); + + // Then make sure that the watermark color is correct: + std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument + = pPDFium->openDocument(aStream.GetData(), aStream.GetSize(), OString()); + CPPUNIT_ASSERT(pPdfDocument); + std::unique_ptr<vcl::pdf::PDFiumPage> pPage = pPdfDocument->openPage(0); + CPPUNIT_ASSERT_EQUAL(1, pPage->getObjectCount()); + std::unique_ptr<vcl::pdf::PDFiumPageObject> pPageObject = pPage->getObject(0); + CPPUNIT_ASSERT_EQUAL(1, pPageObject->getFormObjectCount()); + std::unique_ptr<vcl::pdf::PDFiumPageObject> pFormObject = pPageObject->getFormObject(0); + sal_Int32 nFontSize = pFormObject->getFontSize(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 100 + // - Actual : 594 + // i.e. the font size was automatic, could not specify an explicit size. + CPPUNIT_ASSERT_EQUAL(nExpectedFontSize, nFontSize); +} } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx index 9633919da14f..df86ab46393d 100644 --- a/filter/source/pdf/pdfexport.cxx +++ b/filter/source/pdf/pdfexport.cxx @@ -568,6 +568,14 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& maWatermarkColor = Color(ColorTransparency, nColor); } } + else if (rProp.Name == "WatermarkFontHeight") + { + sal_Int32 nFontHeight{}; + if (rProp.Value >>= nFontHeight) + { + moWatermarkFontHeight = nFontHeight; + } + } else if ( rProp.Name == "TiledWatermark" ) rProp.Value >>= msTiledWatermark; // now all the security related properties... @@ -1160,7 +1168,7 @@ void PDFExport::ImplExportPage( vcl::PDFWriter& rWriter, vcl::PDFExtOutDevData& void PDFExport::ImplWriteWatermark( vcl::PDFWriter& rWriter, const Size& rPageSize ) { - vcl::Font aFont( "Helvetica", Size( 0, 3*rPageSize.Height()/4 ) ); + vcl::Font aFont( "Helvetica", Size( 0, moWatermarkFontHeight ? *moWatermarkFontHeight : 3*rPageSize.Height()/4 ) ); aFont.SetItalic( ITALIC_NONE ); aFont.SetWidthType( WIDTH_NORMAL ); aFont.SetWeight( WEIGHT_NORMAL ); @@ -1178,19 +1186,26 @@ void PDFExport::ImplWriteWatermark( vcl::PDFWriter& rWriter, const Size& rPageSi pDev->SetFont( aFont ); pDev->SetMapMode( MapMode( MapUnit::MapPoint ) ); int w = 0; - while( ( w = pDev->GetTextWidth( msWatermark ) ) > nTextWidth ) + if (moWatermarkFontHeight) { - if (w == 0) - break; - tools::Long nNewHeight = aFont.GetFontHeight() * nTextWidth / w; - if( nNewHeight == aFont.GetFontHeight() ) + w = pDev->GetTextWidth(msWatermark); + } + else + { + while( ( w = pDev->GetTextWidth( msWatermark ) ) > nTextWidth ) { - nNewHeight--; - if( nNewHeight <= 0 ) + if (w == 0) break; + tools::Long nNewHeight = aFont.GetFontHeight() * nTextWidth / w; + if( nNewHeight == aFont.GetFontHeight() ) + { + nNewHeight--; + if( nNewHeight <= 0 ) + break; + } + aFont.SetFontHeight( nNewHeight ); + pDev->SetFont( aFont ); } - aFont.SetFontHeight( nNewHeight ); - pDev->SetFont( aFont ); } tools::Long nTextHeight = pDev->GetTextHeight(); // leave some maneuvering room for rounding issues, also diff --git a/filter/source/pdf/pdfexport.hxx b/filter/source/pdf/pdfexport.hxx index 50d3b9dbcb72..22f9db1841af 100644 --- a/filter/source/pdf/pdfexport.hxx +++ b/filter/source/pdf/pdfexport.hxx @@ -74,6 +74,7 @@ private: OUString msWatermark; Color maWatermarkColor; + std::optional<sal_Int32> moWatermarkFontHeight; OUString msTiledWatermark; // these variable are here only to have a location in filter/pdf to set the default