filter/source/pdf/impdialog.cxx   |   42 ++++++--
 filter/source/pdf/impdialog.hxx   |    1 
 vcl/source/gdi/pdfwriter_impl.cxx |    3 
 vcl/source/pdf/PDFiumLibrary.cxx  |  181 +++++++++++---------------------------
 4 files changed, 89 insertions(+), 138 deletions(-)

New commits:
commit a1bc9e9d6663b4d0828dd0057968738268bd4181
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Tue Dec 17 11:58:59 2024 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Dec 26 07:52:16 2024 +0100

    pdfium: remove duplication of converting a unicode string
    
    This adds a universal getUnicodeString function that takes a
    function call as a parameter, which is only a wrapped PDFium
    function call that returns a unicode string. The rest of conversion
    magic to OUString is then done by the function in one place.
    
    This reduces a lot of duplication as we had to copy the way how
    to convert the unicode string to OUString to every method.
    
    Change-Id: Id951e2dd0c8b98837ca096cd5f800b8df0449fa0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178628
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178774
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/vcl/source/pdf/PDFiumLibrary.cxx b/vcl/source/pdf/PDFiumLibrary.cxx
index c665ce006d9e..a1552e9ca1bf 100644
--- a/vcl/source/pdf/PDFiumLibrary.cxx
+++ b/vcl/source/pdf/PDFiumLibrary.cxx
@@ -31,6 +31,7 @@
 #include <vcl/BitmapWriteAccess.hxx>
 #include <vcl/bitmapex.hxx>
 #include <vcl/dibtools.hxx>
+#include <functional>
 
 using namespace com::sun::star;
 
@@ -220,6 +221,35 @@ int CompatibleWriterCallback(FPDF_FILEWRITE* pFileWrite, 
const void* pData, unsi
     pImpl->m_rStream.WriteBytes(pData, nSize);
     return 1;
 }
+
+OUString getUnicodeString(std::function<int(FPDF_WCHAR*, unsigned long)> 
aPDFiumFunctionCall)
+{
+    OUString sReturnText;
+
+    int nBytes = aPDFiumFunctionCall(nullptr, 0);
+    if (nBytes == 0)
+        return sReturnText;
+    assert(nBytes % 2 == 0);
+    nBytes /= 2;
+
+    std::vector<sal_Unicode> pText(nBytes, 0);
+
+    int nActualBytes = 
aPDFiumFunctionCall(reinterpret_cast<FPDF_WCHAR*>(pText.data()), nBytes * 2);
+    assert(nActualBytes % 2 == 0);
+    nActualBytes /= 2;
+    if (nActualBytes > 1)
+    {
+#ifdef OSL_BIGENDIAN
+        for (int i = 0; i != nActualBytes; ++i)
+        {
+            pText[i] = OSL_SWAPWORD(pText[i]);
+        }
+#endif
+        sReturnText = OUString(pText.data());
+    }
+
+    return sReturnText;
+}
 }
 
 namespace vcl::pdf
@@ -910,32 +940,10 @@ 
PDFiumPageObjectImpl::PDFiumPageObjectImpl(FPDF_PAGEOBJECT pPageObject)
 
 OUString PDFiumPageObjectImpl::getText(std::unique_ptr<PDFiumTextPage> const& 
rTextPage)
 {
-    OUString sReturnText;
-
     auto pTextPage = static_cast<PDFiumTextPageImpl*>(rTextPage.get());
-    int nBytes = FPDFTextObj_GetText(mpPageObject, pTextPage->getPointer(), 
nullptr, 0);
-    assert(nBytes % 2 == 0);
-    nBytes /= 2;
-
-    std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nBytes]);
-
-    int nActualBytes = FPDFTextObj_GetText(mpPageObject, 
pTextPage->getPointer(),
-                                           
reinterpret_cast<FPDF_WCHAR*>(pText.get()), nBytes * 2);
-    assert(nActualBytes % 2 == 0);
-    nActualBytes /= 2;
-    if (nActualBytes > 1)
-    {
-#if defined OSL_BIGENDIAN
-        // The data returned by FPDFTextObj_GetText is documented to always be 
UTF-16LE:
-        for (int i = 0; i != nActualBytes; ++i)
-        {
-            pText[i] = OSL_SWAPWORD(pText[i]);
-        }
-#endif
-        sReturnText = OUString(pText.get());
-    }
-
-    return sReturnText;
+    return getUnicodeString([this, pTextPage](FPDF_WCHAR* buffer, unsigned 
long length) {
+        return FPDFTextObj_GetText(mpPageObject, pTextPage->getPointer(), 
buffer, length);
+    });
 }
 
 PDFPageObjectType PDFiumPageObjectImpl::getType()
@@ -1390,98 +1398,36 @@ Color 
PDFiumAnnotationImpl::getFontColor(PDFiumDocument* pDoc)
 
 OUString PDFiumAnnotationImpl::getFormFieldAlternateName(PDFiumDocument* pDoc)
 {
-    auto pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
-    OUString aString;
-    unsigned long nSize = 
FPDFAnnot_GetFormFieldAlternateName(pDocImpl->getFormHandlePointer(),
-                                                              mpAnnotation, 
nullptr, 0);
-    assert(nSize % 2 == 0);
-    nSize /= 2;
-    if (nSize > 1)
-    {
-        std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nSize]);
-        unsigned long nStringSize = FPDFAnnot_GetFormFieldAlternateName(
-            pDocImpl->getFormHandlePointer(), mpAnnotation,
-            reinterpret_cast<FPDF_WCHAR*>(pText.get()), nSize * 2);
-        assert(nStringSize % 2 == 0);
-        nStringSize /= 2;
-        if (nStringSize > 0)
-        {
-#if defined OSL_BIGENDIAN
-            for (unsigned long i = 0; i != nStringSize; ++i)
-            {
-                pText[i] = OSL_SWAPWORD(pText[i]);
-            }
-#endif
-            aString = OUString(pText.get());
-        }
-    }
-    return aString;
+    auto* pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
+    return getUnicodeString([this, pDocImpl](FPDF_WCHAR* buffer, unsigned long 
length) {
+        return 
FPDFAnnot_GetFormFieldAlternateName(pDocImpl->getFormHandlePointer(), 
mpAnnotation,
+                                                   buffer, length);
+    });
 }
 
 OUString PDFiumAnnotationImpl::getFormFieldValue(PDFiumDocument* pDoc)
 {
-    auto pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
-    OUString aString;
-    unsigned long nSize
-        = FPDFAnnot_GetFormFieldValue(pDocImpl->getFormHandlePointer(), 
mpAnnotation, nullptr, 0);
-    assert(nSize % 2 == 0);
-    nSize /= 2;
-    if (nSize > 1)
-    {
-        std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nSize]);
-        unsigned long nStringSize
-            = FPDFAnnot_GetFormFieldValue(pDocImpl->getFormHandlePointer(), 
mpAnnotation,
-                                          
reinterpret_cast<FPDF_WCHAR*>(pText.get()), nSize * 2);
-        assert(nStringSize % 2 == 0);
-        nStringSize /= 2;
-        if (nStringSize > 0)
-        {
-#if defined OSL_BIGENDIAN
-            for (unsigned long i = 0; i != nStringSize; ++i)
-            {
-                pText[i] = OSL_SWAPWORD(pText[i]);
-            }
-#endif
-            aString = OUString(pText.get());
-        }
-    }
-    return aString;
+    auto* pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
+    return getUnicodeString([this, pDocImpl](FPDF_WCHAR* buffer, unsigned long 
length) {
+        return FPDFAnnot_GetFormFieldValue(pDocImpl->getFormHandlePointer(), 
mpAnnotation, buffer,
+                                           length);
+    });
 }
 int PDFiumAnnotationImpl::getOptionCount(PDFiumDocument* pDoc)
 {
-    auto pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
+    auto* pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
     return FPDFAnnot_GetOptionCount(pDocImpl->getFormHandlePointer(), 
mpAnnotation);
 }
 
 OUString 
PDFiumAnnotationImpl::getFormAdditionalActionJavaScript(PDFiumDocument* pDoc,
                                                                  
PDFAnnotAActionType eEvent)
 {
-    auto pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
-    OUString aString;
-    unsigned long nSize = FPDFAnnot_GetFormAdditionalActionJavaScript(
-        pDocImpl->getFormHandlePointer(), mpAnnotation, 
static_cast<int>(eEvent), nullptr, 0);
-    assert(nSize % 2 == 0);
-    nSize /= 2;
-    if (nSize > 1)
-    {
-        std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nSize]);
-        unsigned long nStringSize = 
FPDFAnnot_GetFormAdditionalActionJavaScript(
-            pDocImpl->getFormHandlePointer(), mpAnnotation, 
static_cast<int>(eEvent),
-            reinterpret_cast<FPDF_WCHAR*>(pText.get()), nSize * 2);
-        assert(nStringSize % 2 == 0);
-        nStringSize /= 2;
-        if (nStringSize > 0)
-        {
-#if defined OSL_BIGENDIAN
-            for (unsigned long i = 0; i != nStringSize; ++i)
-            {
-                pText[i] = OSL_SWAPWORD(pText[i]);
-            }
-#endif
-            aString = OUString(pText.get());
-        }
-    }
-    return aString;
+    auto* pDocImpl = static_cast<PDFiumDocumentImpl*>(pDoc);
+    return getUnicodeString([this, pDocImpl, eEvent](FPDF_WCHAR* buffer, 
unsigned long length) {
+        return 
FPDFAnnot_GetFormAdditionalActionJavaScript(pDocImpl->getFormHandlePointer(),
+                                                           mpAnnotation, 
static_cast<int>(eEvent),
+                                                           buffer, length);
+    });
 }
 
 namespace
@@ -1539,30 +1485,9 @@ PDFObjectType PDFiumAnnotationImpl::getValueType(OString 
const& rKey)
 
 OUString PDFiumAnnotationImpl::getString(OString const& rKey)
 {
-    OUString rString;
-    unsigned long nSize = FPDFAnnot_GetStringValue(mpAnnotation, 
rKey.getStr(), nullptr, 0);
-    assert(nSize % 2 == 0);
-    nSize /= 2;
-    if (nSize > 1)
-    {
-        std::unique_ptr<sal_Unicode[]> pText(new sal_Unicode[nSize]);
-        unsigned long nStringSize = FPDFAnnot_GetStringValue(
-            mpAnnotation, rKey.getStr(), 
reinterpret_cast<FPDF_WCHAR*>(pText.get()), nSize * 2);
-        assert(nStringSize % 2 == 0);
-        nStringSize /= 2;
-        if (nStringSize > 0)
-        {
-#if defined OSL_BIGENDIAN
-            // The data returned by FPDFAnnot_GetStringValue is documented to 
always be UTF-16LE:
-            for (unsigned long i = 0; i != nStringSize; ++i)
-            {
-                pText[i] = OSL_SWAPWORD(pText[i]);
-            }
-#endif
-            rString = OUString(pText.get());
-        }
-    }
-    return rString;
+    return getUnicodeString([this, rKey](FPDF_WCHAR* buffer, unsigned long 
length) {
+        return FPDFAnnot_GetStringValue(mpAnnotation, rKey.getStr(), buffer, 
length);
+    });
 }
 
 std::vector<std::vector<basegfx::B2DPoint>> 
PDFiumAnnotationImpl::getInkStrokes()
commit 5364b7b663b2be30d802474618dea3db14a2182a
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Thu Dec 12 23:56:29 2024 +0900
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Dec 26 07:52:05 2024 +0100

    tdf#160196 Embedded files are not allowed in PDF/A-1 and PDF/A-2
    
    This disables embedded/attached files in the UI as well as in the
    export filter for PDF/A-1 and 2. PDF/A-3 is almost identical to
    PDF/A-2 with the difference that it allows embedded/attached files.
    
    Change-Id: If8c3af6ab08ad320cf15618ead9c69fbd490d4f0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178413
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178769
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    Tested-by: Jenkins

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 03250388c5d6..fa1d634d6192 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -535,6 +535,13 @@ bool ImpPDFTabGeneralPage::IsPdfaSelected() const
         aVersion == u"4"_ustr;
 }
 
+bool ImpPDFTabGeneralPage::IsPDFAVersionSelected(sal_Int32 nInputVersion) const
+{
+    OUString aVersion = mxRbPDFVersion->get_active_id();
+    sal_Int32 nSelectedVersion = aVersion.toInt32();
+    return nSelectedVersion == nInputVersion;
+}
+
 void ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent)
 {
     mpParent = pParent;
@@ -626,6 +633,12 @@ void 
ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent)
         mbUseTaggedPDFUserSelection = pParent->mbUseTaggedPDFUserSelection;
 
     mxCbExportBookmarks->set_active(pParent->mbExportBookmarksUserSelection);
+
+    mxCbAddStream->show();
+    mxCbAddStream->set_active(pParent->mbAddStream);
+    mxCbAddStream->connect_toggled(LINK(this, ImpPDFTabGeneralPage, 
ToggleAddStreamHdl));
+    ToggleAddStreamHdl(*mxCbAddStream); // init addstream dependencies
+
     thePDFVersionChanged();
 
     mxCbExportFormFields->set_active(pParent->mbExportFormFields);
@@ -718,13 +731,6 @@ void 
ImpPDFTabGeneralPage::SetFilterConfigItem(ImpPDFTabDialog* pParent)
     mxCbExportPlaceholders->set_active(pParent->mbIsExportPlaceholders);
     mxCbExportPlaceholders->set_sensitive(
         mbIsWriter && 
!pParent->maConfigItem.IsReadOnly(u"ExportPlaceholders"_ustr));
-
-    mxCbAddStream->show();
-    mxCbAddStream->set_active(pParent->mbAddStream);
-    
mxCbAddStream->set_sensitive(!pParent->maConfigItem.IsReadOnly(u"IsAddStream"_ustr));
-
-    mxCbAddStream->connect_toggled(LINK(this, ImpPDFTabGeneralPage, 
ToggleAddStreamHdl));
-    ToggleAddStreamHdl(*mxCbAddStream); // init addstream dependencies
 }
 
 void ImpPDFTabGeneralPage::GetFilterConfigItem( ImpPDFTabDialog* pParent )
@@ -940,9 +946,6 @@ void ImpPDFTabGeneralPage::thePDFVersionChanged()
     if (pSecPage)
         pSecPage->ImplPDFASecurityControl();
 
-    mxCbTaggedPDF->set_sensitive(
-        !bIsPDFA && !bIsPDFUA && !IsReadOnlyProperty(u"UseTaggedPDF"_ustr));
-
     
mxRbPDFVersion->set_sensitive(!IsReadOnlyProperty(u"SelectPdfVersion"_ustr));
 
     if (bIsPDFA || bIsPDFUA)
@@ -950,6 +953,7 @@ void ImpPDFTabGeneralPage::thePDFVersionChanged()
         // store the users selection of subordinate controls and set required 
PDF/A values
         mbUseTaggedPDFUserSelection = mxCbTaggedPDF->get_active();
         mxCbTaggedPDF->set_active(true);
+        mxCbTaggedPDF->set_sensitive(false);
 
         // if a password was set, inform the user that this will not be used
         if (bIsPDFA && pSecPage && pSecPage->hasPassword())
@@ -965,6 +969,24 @@ void ImpPDFTabGeneralPage::thePDFVersionChanged()
     {
         // restore the users values of subordinate controls
         mxCbTaggedPDF->set_active(mbUseTaggedPDFUserSelection);
+        
mxCbTaggedPDF->set_sensitive(!IsReadOnlyProperty(u"UseTaggedPDF"_ustr));
+    }
+
+    if (IsPDFAVersionSelected(1) || IsPDFAVersionSelected(2))
+    {
+        if (mxCbAddStream->get_sensitive())
+        {
+            if (mpParent)
+                mpParent->mbAddStream = mxCbAddStream->get_active();
+
+            mxCbAddStream->set_active(false);
+            mxCbAddStream->set_sensitive(false);
+        }
+    }
+    else if (mpParent && !mxCbAddStream->get_sensitive())
+    {
+        mxCbAddStream->set_active(mpParent->mbAddStream);
+        
mxCbAddStream->set_sensitive(!mpParent->maConfigItem.IsReadOnly(u"IsAddStream"_ustr));
     }
 
     if (bIsPDFUA)
diff --git a/filter/source/pdf/impdialog.hxx b/filter/source/pdf/impdialog.hxx
index 1b697b257ece..fba49c8f0301 100644
--- a/filter/source/pdf/impdialog.hxx
+++ b/filter/source/pdf/impdialog.hxx
@@ -259,6 +259,7 @@ public:
     void                        GetFilterConfigItem(ImpPDFTabDialog* paParent);
     void                        SetFilterConfigItem(ImpPDFTabDialog* paParent);
     bool IsPdfaSelected() const;
+    bool IsPDFAVersionSelected(sal_Int32 nVersion) const;
     bool IsPdfUaSelected() const { return mxCbPDFUA->get_active(); }
 };
 
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx 
b/vcl/source/gdi/pdfwriter_impl.cxx
index 387edb5e2594..6816fca77bd5 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -3510,6 +3510,9 @@ bool PDFWriterImpl::appendDest( sal_Int32 nDestID, 
OStringBuffer& rBuffer )
 
 void PDFWriterImpl::addDocumentAttachedFile(OUString const& rFileName, 
OUString const& rMimeType, OUString const& rDescription, 
std::unique_ptr<PDFOutputStream> rStream)
 {
+    if (m_nPDFA_Version == 1 || m_nPDFA_Version == 2)
+        return;
+
     sal_Int32 nObjectID = addEmbeddedFile(std::move(rStream), rMimeType);
     auto& rAttachedFile = m_aDocumentAttachedFiles.emplace_back();
     rAttachedFile.maFilename = rFileName;

Reply via email to