[Libreoffice-commits] core.git: Branch 'distro/vector/vector-5.4' - 2 commits - filter/source include/filter include/vcl sw/qa sw/source vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Jul 5 09:09:40 UTC 2018


 filter/source/msfilter/rtfutil.cxx          |   16 +++++++
 include/filter/msfilter/rtfutil.hxx         |    3 +
 include/vcl/gfxlink.hxx                     |    1 
 sw/qa/extras/htmlexport/htmlexport.cxx      |   14 ++++--
 sw/source/filter/html/htmlflywriter.cxx     |   44 ++++++++++++++++++-
 sw/source/filter/html/htmlreqifreader.cxx   |   64 ++++++++++++++++++++++++++++
 sw/source/filter/html/htmlreqifreader.hxx   |    9 +++
 sw/source/filter/ww8/rtfattributeoutput.cxx |   35 +--------------
 vcl/source/gdi/gfxlink.cxx                  |   16 +++++++
 9 files changed, 165 insertions(+), 37 deletions(-)

New commits:
commit 6285b8bb18462528b0c0e80e5c57106855b77b1d
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jun 7 16:49:58 2018 +0200

    sw HTML export: use PNG fallback + RTF native data for all images for ReqIF
    
    ReqIF says the image should be either PNG or has a PNG fallback and then
    it can be something else. We used to convert images to PNG to avoid
    writing any native data, but results in data loss.
    
    So instead:
    
    1) Write the original image as an RTF fragment, so it's not lost.
    
    2) Some ReqIF parsers expect an RTF fragment even for PNG, so make sure
    we always write the RTF fragment, even if that means a small
    duplication.
    
    Reviewed-on: https://gerrit.libreoffice.org/55430
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins
    (cherry picked from commit 76abcd5f912f1a9e6f86ffc2a489ba7dba1aac56)
    
    Conflicts:
            sw/source/filter/ww8/rtfattributeoutput.cxx
    
    Change-Id: Ida0fcaa58d56b9e11f81992307505599807353b5

diff --git a/filter/source/msfilter/rtfutil.cxx b/filter/source/msfilter/rtfutil.cxx
index 57f7ca7ff14b..cdb3d7d4acce 100644
--- a/filter/source/msfilter/rtfutil.cxx
+++ b/filter/source/msfilter/rtfutil.cxx
@@ -283,6 +283,22 @@ bool ExtractOLE2FromObjdata(const OString& rObjdata, SvStream& rOle2)
 
     return true;
 }
+
+bool StripMetafileHeader(const sal_uInt8*& rpGraphicAry, sal_uInt64& rSize)
+{
+    if (rpGraphicAry && (rSize > 0x22))
+    {
+        if ((rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) && (rpGraphicAry[2] == 0xc6)
+            && (rpGraphicAry[3] == 0x9a))
+        {
+            // we have to get rid of the metafileheader
+            rpGraphicAry += 22;
+            rSize -= 22;
+            return true;
+        }
+    }
+    return false;
+}
 }
 }
 
diff --git a/include/filter/msfilter/rtfutil.hxx b/include/filter/msfilter/rtfutil.hxx
index f4699169143a..a448f7b117bc 100644
--- a/include/filter/msfilter/rtfutil.hxx
+++ b/include/filter/msfilter/rtfutil.hxx
@@ -66,6 +66,9 @@ MSFILTER_DLLPUBLIC OString WriteHex(const sal_uInt8* pData, sal_uInt32 nSize,
  * Extract OLE2 data from an \objdata hex dump.
  */
 MSFILTER_DLLPUBLIC bool ExtractOLE2FromObjdata(const OString& rObjdata, SvStream& rOle2);
+
+/// Strips the header of a WMF file.
+MSFILTER_DLLPUBLIC bool StripMetafileHeader(const sal_uInt8*& rpGraphicAry, sal_uInt64& rSize);
 }
 }
 
diff --git a/sw/qa/extras/htmlexport/htmlexport.cxx b/sw/qa/extras/htmlexport/htmlexport.cxx
index dddf33b945e7..79d5da7875a2 100644
--- a/sw/qa/extras/htmlexport/htmlexport.cxx
+++ b/sw/qa/extras/htmlexport/htmlexport.cxx
@@ -434,11 +434,15 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfPngImg, "reqif-png-img.xhtml")
     uno::Reference<container::XNamed> xShape(getShape(1), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xShape.is());
 
-    // This was Object1, PNG without fallback was imported as OLE object.
-    CPPUNIT_ASSERT_EQUAL(OUString("Image1"), xShape->getName());
-
     if (!mbExported)
+    {
+        // Imported PNG image is not an object.
+        CPPUNIT_ASSERT_EQUAL(OUString("Image1"), xShape->getName());
         return;
+    }
+
+    // All images are exported as objects in ReqIF mode.
+    CPPUNIT_ASSERT_EQUAL(OUString("Object1"), xShape->getName());
 
     // This was <img>, not <object>, which is not valid in the reqif-xhtml
     // subset.
@@ -449,6 +453,10 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfPngImg, "reqif-png-img.xhtml")
     pStream->Seek(0);
     OString aStream(read_uInt8s_ToOString(*pStream, nLength));
     CPPUNIT_ASSERT(aStream.indexOf("<reqif-xhtml:object") != -1);
+
+    // Make sure that both RTF and PNG versions are written.
+    CPPUNIT_ASSERT(aStream.indexOf("text/rtf") != -1);
+    CPPUNIT_ASSERT(aStream.indexOf("image/png") != -1);
 }
 
 DECLARE_HTMLEXPORT_TEST(testReqIfJpgImg, "reqif-jpg-img.xhtml")
diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx
index a4beb20de40d..96492d1b75ab 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -64,6 +64,7 @@
 #include "css1kywd.hxx"
 #include "htmlatr.hxx"
 #include "htmlfly.hxx"
+#include "htmlreqifreader.hxx"
 
 using namespace css;
 
@@ -1425,10 +1426,16 @@ Writer& OutHTML_Image( Writer& rWrt, const SwFrameFormat &rFrameFormat,
         aHtml.attribute(OOO_STRING_SVTOOLS_HTML_O_usemap, "#" + aIMapName);
     }
 
-    if (bReplacement && !rAlternateText.isEmpty())
+    if (bReplacement)
+    {
         // XHTML object replacement image's alternate text doesn't use the
         // "alt" attribute.
-        aHtml.characters(rAlternateText.toUtf8());
+        if (rAlternateText.isEmpty())
+            // Empty alternate text is not valid.
+            aHtml.characters(" ");
+        else
+            aHtml.characters(rAlternateText.toUtf8());
+    }
 
     aHtml.flushStack();
 
@@ -1855,9 +1862,42 @@ static Writer& OutHTML_FrameFormatGrfNode( Writer& rWrt, const SwFrameFormat& rF
     uno::Reference<beans::XPropertySet> xGraphic(aGraphic.GetXGraphic(), uno::UNO_QUERY);
     if (xGraphic.is() && aMimeType.isEmpty())
         xGraphic->getPropertyValue("MimeType") >>= aMimeType;
+
+    if (rHTMLWrt.mbReqIF)
+    {
+        // Write the original image as an RTF fragment.
+        OUString aFileName;
+        if (rHTMLWrt.GetOrigFileName())
+            aFileName = *rHTMLWrt.GetOrigFileName();
+        INetURLObject aURL(aFileName);
+        OUString aName(aURL.getBase());
+        aName += "_";
+        aName += aURL.getExtension();
+        aName += "_";
+        aName += OUString::number(aGraphic.GetChecksum(), 16);
+        aURL.setBase(aName);
+        aURL.setExtension("ole");
+        aFileName = aURL.GetMainURL(INetURLObject::DecodeMechanism::NONE);
+
+        SvFileStream aOutStream(aFileName, StreamMode::WRITE);
+        if (!SwReqIfReader::WrapGraphicInRtf(aGraphic, pGrfNd->GetTwipSize(), aOutStream))
+            SAL_WARN("sw.html", "SwReqIfReader::WrapGraphicInRtf() failed");
+
+        // Refer to this data.
+        aFileName = URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(), aFileName);
+        rWrt.Strm().WriteOString("<" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object);
+        rWrt.Strm().WriteOString(" data=\"" + aFileName.toUtf8() + "\"");
+        rWrt.Strm().WriteOString(" type=\"text/rtf\"");
+        rWrt.Strm().WriteOString(">");
+        rHTMLWrt.OutNewLine();
+    }
+
     OutHTML_Image( rWrt, rFrameFormat, aGraphicURL, aGraphic, pGrfNd->GetTitle(),
                   pGrfNd->GetTwipSize(), nFrameFlags, "graphic", nullptr, aMimeType );
 
+    if (rHTMLWrt.mbReqIF)
+        rWrt.Strm().WriteOString("</" + rHTMLWrt.GetNamespace() + OOO_STRING_SVTOOLS_HTML_object ">");
+
     return rWrt;
 }
 
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index 508ef02bfd36..c39739dfd3b3 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -210,6 +210,70 @@ bool WrapOleInRtf(SvStream& rOle2, SvStream& rRtf)
 
     return true;
 }
+
+bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream& rRtf)
+{
+    rRtf.WriteCharPtr("{" OOO_STRING_SVTOOLS_RTF_PICT);
+
+    GfxLink aLink = rGraphic.GetLink();
+    const sal_uInt8* pGraphicAry = aLink.GetData();
+    sal_uInt64 nSize = aLink.GetDataSize();
+    OString aBlipType;
+    bool bIsWMF = false;
+    switch (aLink.GetType())
+    {
+        case GfxLinkType::NativeBmp:
+            aBlipType = OOO_STRING_SVTOOLS_RTF_WBITMAP;
+            break;
+        case GfxLinkType::NativeJpg:
+            aBlipType = OOO_STRING_SVTOOLS_RTF_JPEGBLIP;
+            break;
+        case GfxLinkType::NativePng:
+            aBlipType = OOO_STRING_SVTOOLS_RTF_PNGBLIP;
+            break;
+        case GfxLinkType::NativeWmf:
+            if (aLink.IsEMF())
+                aBlipType = OOO_STRING_SVTOOLS_RTF_EMFBLIP;
+            else
+            {
+                aBlipType = OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+                bIsWMF = true;
+            }
+            break;
+        default:
+            break;
+    }
+
+    if (aBlipType.isEmpty())
+        return false;
+
+    rRtf.WriteOString(aBlipType);
+
+    Size aMapped(rGraphic.GetPrefSize());
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICW);
+    rRtf.WriteOString(OString::number(aMapped.Width()));
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICH);
+    rRtf.WriteOString(OString::number(aMapped.Height()));
+
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICWGOAL);
+    rRtf.WriteOString(OString::number(rLogicSize.Width()));
+    rRtf.WriteCharPtr(OOO_STRING_SVTOOLS_RTF_PICHGOAL);
+    rRtf.WriteOString(OString::number(rLogicSize.Height()));
+
+    if (bIsWMF)
+    {
+        rRtf.WriteOString(OString::number(8));
+        msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize);
+    }
+    rRtf.WriteOString(SAL_NEWLINE_STRING);
+
+    msfilter::rtfutil::WriteHex(pGraphicAry, nSize, &rRtf);
+    rRtf.WriteOString(SAL_NEWLINE_STRING);
+
+    // End pict.
+    rRtf.WriteCharPtr("}");
+    return true;
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/html/htmlreqifreader.hxx b/sw/source/filter/html/htmlreqifreader.hxx
index 84d470ce4db1..3b24a4f28311 100644
--- a/sw/source/filter/html/htmlreqifreader.hxx
+++ b/sw/source/filter/html/htmlreqifreader.hxx
@@ -9,6 +9,8 @@
 #ifndef INCLUDED_SW_SOURCE_FILTER_HTML_HTMLREQIFREADER_HXX
 #define INCLUDED_SW_SOURCE_FILTER_HTML_HTMLREQIFREADER_HXX
 
+class Graphic;
+class Size;
 class SvStream;
 
 namespace SwReqIfReader
@@ -22,6 +24,13 @@ bool ExtractOleFromRtf(SvStream& rRtf, SvStream& rOle, bool& bOwnFormat);
 
 /// Wraps an OLE2 container binary in an RTF fragment.
 bool WrapOleInRtf(SvStream& rOle, SvStream& rRtf);
+
+/**
+ * Wraps an image in an RTF fragment.
+ *
+ * @param rLogicSize the size used in the document model (not pixel size)
+ */
+bool WrapGraphicInRtf(const Graphic& rGraphic, const Size& rLogicSize, SvStream& rRtf);
 }
 
 #endif // INCLUDED_SW_SOURCE_FILTER_HTML_HTMLREQIFREADER_HXX
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 3b215130386f..14d35fb82aef 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -3652,21 +3652,6 @@ void RtfAttributeOutput::FontPitchType(FontPitch ePitch) const
     m_rExport.OutULong(nVal);
 }
 
-static bool StripMetafileHeader(const sal_uInt8*& rpGraphicAry, unsigned long& rSize)
-{
-    if (rpGraphicAry && (rSize > 0x22))
-    {
-        if ((rpGraphicAry[0] == 0xd7) && (rpGraphicAry[1] == 0xcd) && (rpGraphicAry[2] == 0xc6) && (rpGraphicAry[3] == 0x9a))
-        {
-            // we have to get rid of the metafileheader
-            rpGraphicAry += 22;
-            rSize -= 22;
-            return true;
-        }
-    }
-    return false;
-}
-
 static void lcl_AppendSP(OStringBuffer& rBuffer,
                          const char cName[],
                          const OUString& rValue,
@@ -3683,7 +3668,7 @@ static void lcl_AppendSP(OStringBuffer& rBuffer,
 
 static OString ExportPICT(const SwFlyFrameFormat* pFlyFrameFormat, const Size& rOrig, const Size& rRendered, const Size& rMapped,
                           const SwCropGrf& rCr, const char* pBLIPType, const sal_uInt8* pGraphicAry,
-                          unsigned long nSize, const RtfExport& rExport, SvStream* pStream = nullptr, bool bWritePicProp = true)
+                          sal_uInt64 nSize, const RtfExport& rExport, SvStream* pStream = nullptr, bool bWritePicProp = true)
 {
     OStringBuffer aRet;
     if (pBLIPType && nSize && pGraphicAry)
@@ -3743,7 +3728,7 @@ static OString ExportPICT(const SwFlyFrameFormat* pFlyFrameFormat, const Size& r
         if (bIsWMF)
         {
             aRet.append((sal_Int32)8);
-            StripMetafileHeader(pGraphicAry, nSize);
+            msfilter::rtfutil::StripMetafileHeader(pGraphicAry, nSize);
         }
         aRet.append(SAL_NEWLINE_STRING);
         if (pStream)
commit f533499e7a1bdecbb6db0f97cdaf85d39a7fbaf2
Author: László Németh <nemeth at numbertext.org>
Date:   Mon Jun 18 16:48:02 2018 +0200

    tdf#103913 keep ".emf" file extension and mime type
    
    in documents, don't change them to wmf and image/x-wmf
    silently, resulting for example, dropping or rejecting
    modified documents by firewall packet filtering.
    
    (partially cherry picked from commit 4cb1e86e5217f09e1d98e51e46803a06fb72f5ce)
    
    Conflicts:
            svx/source/xml/xmlgrhlp.cxx
            sw/source/filter/ww8/rtfattributeoutput.cxx
    
    Change-Id: I3b8634ae022c7c026b0ed4ebc345c1c3b3f96337

diff --git a/include/vcl/gfxlink.hxx b/include/vcl/gfxlink.hxx
index 3632b66d23f3..166b5b270e33 100644
--- a/include/vcl/gfxlink.hxx
+++ b/include/vcl/gfxlink.hxx
@@ -111,6 +111,7 @@ public:
     void                SwapIn();
     bool                IsSwappedOut() const { return( bool(mpSwapOutData) ); }
 
+    bool                IsEMF() const; // WMF & EMF stored under the same type (NativeWmf)
 public:
 
     friend VCL_DLLPUBLIC SvStream&  WriteGfxLink( SvStream& rOStream, const GfxLink& rGfxLink );
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 134eb1735d69..3b215130386f 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -3652,20 +3652,6 @@ void RtfAttributeOutput::FontPitchType(FontPitch ePitch) const
     m_rExport.OutULong(nVal);
 }
 
-static bool IsEMF(const sal_uInt8* pGraphicAry, unsigned long nSize)
-{
-    if (pGraphicAry && (nSize > 0x2c))
-    {
-        // check the magic number
-        if ((pGraphicAry[0x28] == 0x20) && (pGraphicAry[0x29] == 0x45) && (pGraphicAry[0x2a] == 0x4d) && (pGraphicAry[0x2b] == 0x46))
-        {
-            //emf detected
-            return true;
-        }
-    }
-    return false;
-}
-
 static bool StripMetafileHeader(const sal_uInt8*& rpGraphicAry, unsigned long& rSize)
 {
     if (rpGraphicAry && (rSize > 0x22))
@@ -3890,7 +3876,7 @@ void RtfAttributeOutput::FlyFrameGraphic(const SwFlyFrameFormat* pFlyFrameFormat
             break;
         case GfxLinkType::NativeWmf:
             pBLIPType =
-                IsEMF(pGraphicAry, nSize) ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
+                aGraphicLink.IsEMF() ? OOO_STRING_SVTOOLS_RTF_EMFBLIP : OOO_STRING_SVTOOLS_RTF_WMETAFILE;
             break;
         case GfxLinkType::NativeGif:
             // GIF is not supported by RTF, but we override default conversion to WMF, PNG seems fits better here.
diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx
index 70e31776c137..3ec63c8fa968 100644
--- a/vcl/source/gdi/gfxlink.cxx
+++ b/vcl/source/gdi/gfxlink.cxx
@@ -277,4 +277,20 @@ std::shared_ptr<sal_uInt8> GfxLink::GetSwapInData() const
     return pData;
 }
 
+bool GfxLink::IsEMF() const
+{
+    const sal_uInt8* pGraphicAry = GetData();
+    if ((GetType() == GfxLinkType::NativeWmf) && pGraphicAry && (GetDataSize() > 0x2c))
+    {
+        // check the magic number
+        if ((pGraphicAry[0x28] == 0x20) && (pGraphicAry[0x29] == 0x45)
+            && (pGraphicAry[0x2a] == 0x4d) && (pGraphicAry[0x2b] == 0x46))
+        {
+            //emf detected
+            return true;
+        }
+    }
+    return false;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list