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

Reply via email to