[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - 22 commits - filter/source formula/source include/filter include/formula oox/source sc/source sd/qa sd/source sfx2/source solenv/bin sw/qa sw/source ucb/source vcl/inc vcl/qa vcl/source vcl/unx vcl/win writerfilter/source xmloff/source

Serge Krot Serge.Krot at cib.de
Mon Mar 26 07:01:10 UTC 2018


 filter/source/msfilter/util.cxx                         |    7 
 formula/source/core/api/FormulaCompiler.cxx             |    6 
 formula/source/ui/dlg/formula.cxx                       |   30 +-
 include/filter/msfilter/util.hxx                        |    5 
 include/formula/paramclass.hxx                          |   11 
 oox/source/ppt/animationspersist.cxx                    |   10 
 sc/source/core/tool/interpr1.cxx                        |   15 -
 sc/source/ui/view/viewfun2.cxx                          |   23 +
 sd/qa/unit/data/odp/tdf115005.odp                       |binary
 sd/qa/unit/data/odp/tdf90627.odp                        |binary
 sd/qa/unit/data/pptx/tdf104786.pptx                     |binary
 sd/qa/unit/data/pptx/tdf104789.pptx                     |binary
 sd/qa/unit/data/pptx/tdf104792-smart-art-animation.pptx |binary
 sd/qa/unit/export-tests-ooxml2.cxx                      |   84 ++++++
 sd/source/filter/eppt/epptooxml.hxx                     |    6 
 sd/source/filter/eppt/pptx-epptooxml.cxx                |  112 +++-----
 sd/source/ui/sidebar/SlideBackground.cxx                |    1 
 sfx2/source/dialog/templdlg.cxx                         |    4 
 solenv/bin/modules/installer.pm                         |   31 +-
 solenv/bin/modules/installer/scriptitems.pm             |    9 
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx                |    2 
 sw/qa/extras/ooxmlexport/ooxmlexport11.cxx              |   14 -
 sw/qa/extras/ooxmlexport/ooxmlexport5.cxx               |   16 -
 sw/qa/extras/ooxmlimport/data/tdf113182.docx            |binary
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                |    8 
 sw/qa/extras/rtfexport/rtfexport2.cxx                   |   16 -
 sw/qa/extras/uiwriter/data/tdf112448.odt                |binary
 sw/qa/extras/uiwriter/uiwriter.cxx                      |   15 +
 sw/source/core/frmedt/feshview.cxx                      |   11 
 sw/source/core/text/itrform2.cxx                        |    6 
 sw/source/core/text/xmldump.cxx                         |    3 
 sw/source/filter/ww8/ww8par4.cxx                        |    4 
 ucb/source/ucp/file/filtask.cxx                         |    4 
 vcl/inc/sallayout.hxx                                   |    5 
 vcl/inc/unx/gtk/gtkframe.hxx                            |    1 
 vcl/inc/win/saldata.hxx                                 |    2 
 vcl/inc/win/salframe.h                                  |    4 
 vcl/qa/cppunit/pdfexport/data/tdf115117-1.odt           |binary
 vcl/qa/cppunit/pdfexport/data/tdf115117-2.odt           |binary
 vcl/qa/cppunit/pdfexport/pdfexport.cxx                  |  217 ++++++++++++++++
 vcl/source/app/svmain.cxx                               |    3 
 vcl/source/gdi/CommonSalLayout.cxx                      |   45 +++
 vcl/source/gdi/pdfwriter_impl.cxx                       |   48 ---
 vcl/unx/gtk3/gtk3gtkframe.cxx                           |   32 ++
 vcl/win/app/salinst.cxx                                 |    2 
 vcl/win/window/salframe.cxx                             |   17 -
 writerfilter/source/dmapper/BorderHandler.cxx           |    2 
 writerfilter/source/dmapper/CellColorHandler.cxx        |   10 
 writerfilter/source/dmapper/ConversionHelper.cxx        |    9 
 writerfilter/source/dmapper/DomainMapper.cxx            |    9 
 writerfilter/source/dmapper/TDefTableHandler.cxx        |    2 
 writerfilter/source/ooxml/OOXMLFactory.cxx              |    9 
 writerfilter/source/ooxml/OOXMLFactory.hxx              |    1 
 writerfilter/source/ooxml/OOXMLPropertySet.cxx          |   16 +
 writerfilter/source/ooxml/OOXMLPropertySet.hxx          |    8 
 writerfilter/source/ooxml/factoryimpl.py                |    5 
 writerfilter/source/ooxml/model.xml                     |    2 
 writerfilter/source/rtftok/rtfdocumentimpl.cxx          |    6 
 xmloff/source/core/xmlmultiimagehelper.cxx              |    4 
 59 files changed, 683 insertions(+), 229 deletions(-)

New commits:
commit 9c45822c77f666ca3a7bfac3e53211b9ec1bc05f
Author: Serge Krot <Serge.Krot at cib.de>
Date:   Thu Mar 15 11:17:42 2018 +0100

    tdf#112448: Fix: take correct line height
    
    When line metrics is not calculated we need to call CalcRealHeight()
    before usage of the Height() and GetRealHeight().
    
    Change-Id: I104bbb81ea9d7130dfd728f7114d02e3672afbc3
    Reviewed-on: https://gerrit.libreoffice.org/51319
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit 3c3f10da500967fc6ffecc2f3e076d8ff43e7503)
    Reviewed-on: https://gerrit.libreoffice.org/51350
    Reviewed-by: Serge Krot (CIB) <Serge.Krot at cib.de>
    (cherry picked from commit 169fe61fe32587897188ed5b3619af34f394731d)

diff --git a/sw/qa/extras/uiwriter/data/tdf112448.odt b/sw/qa/extras/uiwriter/data/tdf112448.odt
new file mode 100755
index 000000000000..ffb1ef6b6860
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf112448.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index eb067907f284..2b66c1ee32cb 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -288,6 +288,7 @@ public:
     void testTdf99689TableOfContents();
     void testTdf99689TableOfFigures();
     void testTdf99689TableOfTables();
+    void testTdf112448();
     void testTdf113790();
     void testTdf114306();
     void testTdf114306_2();
@@ -465,6 +466,7 @@ public:
     CPPUNIT_TEST(testTdf99689TableOfContents);
     CPPUNIT_TEST(testTdf99689TableOfFigures);
     CPPUNIT_TEST(testTdf99689TableOfTables);
+    CPPUNIT_TEST(testTdf112448);
     CPPUNIT_TEST(testTdf113790);
     CPPUNIT_TEST(testTdf114306);
     CPPUNIT_TEST(testTdf114306_2);
@@ -5639,6 +5641,19 @@ void SwUiWriterTest::testParagraphOfTextRange()
     CPPUNIT_ASSERT_EQUAL(OUString("In section"), xParagraph->getString());
 }
 
+// tdf#112448: Fix: take correct line height
+//
+// When line metrics is not calculated we need to call CalcRealHeight()
+// before usage of the Height() and GetRealHeight().
+void SwUiWriterTest::testTdf112448()
+{
+    createDoc("tdf112448.odt");
+
+    // check actual number of line breaks in the paragraph
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page/body/txt/LineBreak", 2);
+}
+
 void SwUiWriterTest::testTdf113790()
 {
     SwDoc* pDoc = createDoc("tdf113790.docx");
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 730237e3b4d3..6421eedca0be 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -2294,13 +2294,13 @@ void SwTextFormatter::CalcFlyWidth( SwTextFormatInfo &rInf )
     }
     else
     {
-        nAscent = pLast->GetAscent();
-        nHeight = pLast->Height();
-
         // We make a first guess for the lines real height
         if ( ! m_pCurr->GetRealHeight() )
             CalcRealHeight();
 
+        nAscent = pLast->GetAscent();
+        nHeight = pLast->Height();
+
         if ( m_pCurr->GetRealHeight() > nHeight )
             nTop += m_pCurr->GetRealHeight() - nHeight;
         else
commit c779883414c588d80c31540bbc794080b8e2c1f3
Author: Serge Krot <Serge.Krot at cib.de>
Date:   Fri Mar 16 10:42:50 2018 +0100

    tdf#113182: DOCX filter: new values of wrap property in text box
    
    Added support of "none" and "through" values of the w:wrap
    poroperty in the text box.
    
    Change-Id: I83f0c9e8162e93bf457f228d49d3b426050d4dc6
    Reviewed-on: https://gerrit.libreoffice.org/51396
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    (cherry picked from commit be02ce71f2ee694fa2609a7a630853c24acfbfff)
    Reviewed-on: https://gerrit.libreoffice.org/51431
    Reviewed-by: Serge Krot (CIB) <Serge.Krot at cib.de>
    (cherry picked from commit 133821d1526800a93bb395a91f87dc77d29f0b8d)

diff --git a/sw/qa/extras/ooxmlimport/data/tdf113182.docx b/sw/qa/extras/ooxmlimport/data/tdf113182.docx
new file mode 100755
index 000000000000..9f35ec3d4ebc
Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/tdf113182.docx differ
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index d879dab4495a..e3cdc19701ab 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -1574,6 +1574,14 @@ DECLARE_OOXMLIMPORT_TEST(testTdf112443, "tdf112443.docx")
 
 }
 
+// DOCX: Textbox wrap differs in MSO and LO
+// Both should layout text regardless of existing text box
+// and as result only one page should be generated.
+DECLARE_OOXMLIMPORT_TEST(testTdf113182, "tdf113182.docx")
+{
+    CPPUNIT_ASSERT_EQUAL(getPages(), 1);
+}
+
 DECLARE_OOXMLIMPORT_TEST(testTdf113946, "tdf113946.docx")
 {
     OUString aTop = parseDump("/root/page/body/txt/anchored/SwAnchoredDrawObject/bounds", "top");
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 40134d148ac9..abfc8694535c 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -866,11 +866,16 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
                         //should be either LN_Value_doc_ST_Wrap_notBeside or LN_Value_doc_ST_Wrap_around or LN_Value_doc_ST_Wrap_auto
                         OSL_ENSURE( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
                                     sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_notBeside ||
+                                    sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
+                                    sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none ||
                                     sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto,
-                            "wrap not around, not_Beside or auto?");
+                            "wrap not around, not_Beside, through, none or auto?");
                         if( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_around ||
+                            sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_through ||
                             sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_auto )
                             pParaProperties->SetWrap ( text::WrapTextMode_DYNAMIC ) ;
+                        else if (sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_doc_ST_Wrap_none)
+                            pParaProperties->SetWrap ( text::WrapTextMode_THROUGH ) ;
                         else
                             pParaProperties->SetWrap ( text::WrapTextMode_NONE ) ;
                     }
commit 8c145b8a0392432225d1259064b1bfc7925822a6
Author: Khaled Hosny <khaledhosny at eglug.org>
Date:   Wed Mar 21 16:54:10 2018 +0200

    tdf#115117: Fix PDF ToUnicode CMAP for ligatures
    
    Move the glyph to character(s) mapping to CommonSalLayout where we have
    enough information to do this properly. This correctly handles ligatures
    at end of run that wasn’t handled before, and also fixes a bug in the
    PDF writer code when there is more than one ligature in the run (it
    forgot to clear aCodeUnitsPerGlyph vector after each iteration). Also
    drop the “temporary” fix for rotated glyph from 2009 that does not seem
    to be needed now (the document from that bug exports correctly after this
    change).
    
    Change-Id: I5b5b1f4470bbd0ef05cbbc86dfa29d2ff51249ea
    Reviewed-on: https://gerrit.libreoffice.org/51617
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit b94a66ebc8db6c5ca9c7dcfdfbb06b49deae4939)
    Reviewed-on: https://gerrit.libreoffice.org/51715
    (cherry picked from commit 90fb652ebbc4b16ae5001140076f52209e913345)

diff --git a/vcl/inc/sallayout.hxx b/vcl/inc/sallayout.hxx
index ff008c44dd55..c4a29dc9d0c9 100644
--- a/vcl/inc/sallayout.hxx
+++ b/vcl/inc/sallayout.hxx
@@ -255,6 +255,7 @@ struct GlyphItem
 {
     int     mnFlags;
     int     mnCharPos;      // index in string
+    int     mnCharCount;    // number of characters making up this glyph
 
     int     mnOrigWidth;    // original glyph width
     int     mnNewWidth;     // width after adjustments
@@ -270,6 +271,7 @@ public:
                 long nFlags, int nOrigWidth )
             :   mnFlags(nFlags)
             ,   mnCharPos(nCharPos)
+            ,   mnCharCount(1)
             ,   mnOrigWidth(nOrigWidth)
             ,   mnNewWidth(nOrigWidth)
             ,   mnXOffset(0)
@@ -278,10 +280,11 @@ public:
             ,   mnFallbackLevel(0)
             { }
 
-            GlyphItem( int nCharPos, sal_GlyphId aGlyphId, const Point& rLinearPos,
+            GlyphItem(int nCharPos, int nCharCount, sal_GlyphId aGlyphId, const Point& rLinearPos,
                 long nFlags, int nOrigWidth, int nXOffset )
             :   mnFlags(nFlags)
             ,   mnCharPos(nCharPos)
+            ,   mnCharCount(nCharCount)
             ,   mnOrigWidth(nOrigWidth)
             ,   mnNewWidth(nOrigWidth)
             ,   mnXOffset(nXOffset)
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf115117-1.odt b/vcl/qa/cppunit/pdfexport/data/tdf115117-1.odt
new file mode 100644
index 000000000000..63fe82946ef1
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf115117-1.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/data/tdf115117-2.odt b/vcl/qa/cppunit/pdfexport/data/tdf115117-2.odt
new file mode 100644
index 000000000000..c1e1f6d4392c
Binary files /dev/null and b/vcl/qa/cppunit/pdfexport/data/tdf115117-2.odt differ
diff --git a/vcl/qa/cppunit/pdfexport/pdfexport.cxx b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
index a904a5dc638d..ba8df2f1a616 100644
--- a/vcl/qa/cppunit/pdfexport/pdfexport.cxx
+++ b/vcl/qa/cppunit/pdfexport/pdfexport.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <config_features.h>
+#include <config_test.h>
 
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/frame/XStorable.hpp>
@@ -25,6 +26,7 @@
 #include <tools/zcodec.hxx>
 #if HAVE_FEATURE_PDFIUM
 #include <fpdf_edit.h>
+#include <fpdf_text.h>
 #include <fpdfview.h>
 #endif
 
@@ -67,6 +69,16 @@ public:
     void testTdf99680();
     void testTdf99680_2();
     void testTdf108963();
+#if !TEST_FONTS_MISSING
+    /// Test writing ToUnicode CMAP for LTR ligatures.
+    void testTdf115117_1();
+    /// Text extracting LTR text with ligatures.
+    void testTdf115117_1a();
+    /// Test writing ToUnicode CMAP for RTL ligatures.
+    void testTdf115117_2();
+    /// Text extracting RTL text with ligatures.
+    void testTdf115117_2a();
+#endif
 #endif
 
     CPPUNIT_TEST_SUITE(PdfExportTest);
@@ -85,6 +97,12 @@ public:
     CPPUNIT_TEST(testTdf99680);
     CPPUNIT_TEST(testTdf99680_2);
     CPPUNIT_TEST(testTdf108963);
+#if !TEST_FONTS_MISSING
+    CPPUNIT_TEST(testTdf115117_1);
+    CPPUNIT_TEST(testTdf115117_1a);
+    CPPUNIT_TEST(testTdf115117_2);
+    CPPUNIT_TEST(testTdf115117_2a);
+#endif
 #endif
     CPPUNIT_TEST_SUITE_END();
 };
@@ -760,6 +778,205 @@ void PdfExportTest::testTdf108963()
 
     CPPUNIT_ASSERT_EQUAL(1, nYellowPathCount);
 }
+
+#if !TEST_FONTS_MISSING
+// This requires Carlito font, if it is missing the test will most likely
+// fail.
+void PdfExportTest::testTdf115117_1()
+{
+    vcl::filter::PDFDocument aDocument;
+    load("tdf115117-1.odt", aDocument);
+
+    vcl::filter::PDFObjectElement* pToUnicode = nullptr;
+
+    // Get access to ToUnicode of the first font
+    for (const auto& aElement : aDocument.GetElements())
+    {
+        auto pObject = dynamic_cast<vcl::filter::PDFObjectElement*>(aElement.get());
+        if (!pObject)
+            continue;
+        auto pType = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("Type"));
+        if (pType && pType->GetValue() == "Font")
+        {
+            auto pToUnicodeRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObject->Lookup("ToUnicode"));
+            CPPUNIT_ASSERT(pToUnicodeRef);
+            pToUnicode = pToUnicodeRef->LookupObject();
+            break;
+        }
+    }
+
+    CPPUNIT_ASSERT(pToUnicode);
+    auto pStream = pToUnicode->GetStream();
+    CPPUNIT_ASSERT(pStream);
+    SvMemoryStream aObjectStream;
+    ZCodec aZCodec;
+    aZCodec.BeginCompression();
+    pStream->GetMemory().Seek(0);
+    aZCodec.Decompress(pStream->GetMemory(), aObjectStream);
+    CPPUNIT_ASSERT(aZCodec.EndCompression());
+    aObjectStream.Seek(0);
+    // The first values, <01> <02> etc., are glyph ids, they might change order
+    // if we changed how font subsets are created.
+    // The second values, <00740069> etc., are Unicode code points in hex,
+    // <00740069> is U+0074 and U+0069 i.e. "ti" which is a ligature in
+    // Carlito/Callibri. This test is failing if any of the second values
+    // changed which means we are not detecting ligatures and writing CMAP
+    // entries for them correctly. If glyph order in the subset changes then
+    // the order here will changes and the PDF has to be carefully inspected to
+    // ensure that the new values are correct before updating the string below.
+    OString aCmap("9 beginbfchar\n"
+                  "<01> <00740069>\n"
+                  "<02> <0020>\n"
+                  "<03> <0074>\n"
+                  "<04> <0065>\n"
+                  "<05> <0073>\n"
+                  "<06> <00660069>\n"
+                  "<07> <0066006C>\n"
+                  "<08> <006600660069>\n"
+                  "<09> <00660066006C>\n"
+                  "endbfchar");
+    auto pStart = static_cast<const char*>(aObjectStream.GetData());
+    const char* pEnd = pStart + aObjectStream.GetSize();
+    auto it = std::search(pStart, pEnd, aCmap.getStr(), aCmap.getStr() + aCmap.getLength());
+    CPPUNIT_ASSERT(it != pEnd);
+}
+
+// This requires DejaVu Sans font, if it is missing the test will most likely
+// fail.
+void PdfExportTest::testTdf115117_2()
+{
+    // See the comments in testTdf115117_1() for explanation.
+
+    vcl::filter::PDFDocument aDocument;
+    load("tdf115117-2.odt", aDocument);
+
+    vcl::filter::PDFObjectElement* pToUnicode = nullptr;
+
+    for (const auto& aElement : aDocument.GetElements())
+    {
+        auto pObject = dynamic_cast<vcl::filter::PDFObjectElement*>(aElement.get());
+        if (!pObject)
+            continue;
+        auto pType = dynamic_cast<vcl::filter::PDFNameElement*>(pObject->Lookup("Type"));
+        if (pType && pType->GetValue() == "Font")
+        {
+            auto pToUnicodeRef = dynamic_cast<vcl::filter::PDFReferenceElement*>(pObject->Lookup("ToUnicode"));
+            CPPUNIT_ASSERT(pToUnicodeRef);
+            pToUnicode = pToUnicodeRef->LookupObject();
+            break;
+        }
+    }
+
+    CPPUNIT_ASSERT(pToUnicode);
+    auto pStream = pToUnicode->GetStream();
+    CPPUNIT_ASSERT(pStream);
+    SvMemoryStream aObjectStream;
+    ZCodec aZCodec;
+    aZCodec.BeginCompression();
+    pStream->GetMemory().Seek(0);
+    aZCodec.Decompress(pStream->GetMemory(), aObjectStream);
+    CPPUNIT_ASSERT(aZCodec.EndCompression());
+    aObjectStream.Seek(0);
+    OString aCmap("7 beginbfchar\n"
+                  "<01> <06440627>\n"
+                  "<02> <0020>\n"
+                  "<03> <0641>\n"
+                  "<04> <0642>\n"
+                  "<05> <0648>\n"
+                  "<06> <06440627>\n"
+                  "<07> <0628>\n"
+                  "endbfchar");
+    auto pStart = static_cast<const char*>(aObjectStream.GetData());
+    const char* pEnd = pStart + aObjectStream.GetSize();
+    auto it = std::search(pStart, pEnd, aCmap.getStr(), aCmap.getStr() + aCmap.getLength());
+    CPPUNIT_ASSERT(it != pEnd);
+}
+
+void PdfExportTest::testTdf115117_1a()
+{
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf115117-1.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 one page.
+    CPPUNIT_ASSERT_EQUAL(1, FPDF_GetPageCount(mpPdfDocument));
+    mpPdfPage = FPDF_LoadPage(mpPdfDocument, /*page_index=*/0);
+    CPPUNIT_ASSERT(mpPdfPage);
+
+    auto pPdfTextPage = FPDFText_LoadPage(mpPdfPage);
+    CPPUNIT_ASSERT(pPdfTextPage);
+
+    // Extract the text from the page. This pdfium API is a bit higher level
+    // than we want and might apply heuristic that give false positive, but it
+    // is a good approximation in addition to the check in testTdf115117_1().
+    int nChars = FPDFText_CountChars(pPdfTextPage);
+    CPPUNIT_ASSERT_EQUAL(44, nChars);
+
+    OUString aExpectedText = "ti ti test ti\r\nti test fi fl ffi ffl test fi";
+    std::vector<sal_uInt32> aChars(nChars);
+    for (int i = 0; i < nChars; i++)
+        aChars[i] = FPDFText_GetUnicode(pPdfTextPage, i);
+    OUString aActualText(aChars.data(), aChars.size());
+    CPPUNIT_ASSERT_EQUAL(aExpectedText, aActualText);
+}
+
+void PdfExportTest::testTdf115117_2a()
+{
+    // See the comments in testTdf115117_1a() for explanation.
+
+    // Import the bugdoc and export as PDF.
+    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf115117-2.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 one page.
+    CPPUNIT_ASSERT_EQUAL(1, FPDF_GetPageCount(mpPdfDocument));
+    mpPdfPage = FPDF_LoadPage(mpPdfDocument, /*page_index=*/0);
+    CPPUNIT_ASSERT(mpPdfPage);
+
+    auto pPdfTextPage = FPDFText_LoadPage(mpPdfPage);
+    CPPUNIT_ASSERT(pPdfTextPage);
+
+    int nChars = FPDFText_CountChars(pPdfTextPage);
+    CPPUNIT_ASSERT_EQUAL(13, nChars);
+
+    OUString aExpectedText = u"\u0627\u0644 \u0628\u0627\u0644 \u0648\u0642\u0641 \u0627\u0644";
+    std::vector<sal_uInt32> aChars(nChars);
+    for (int i = 0; i < nChars; i++)
+        aChars[i] = FPDFText_GetUnicode(pPdfTextPage, i);
+    OUString aActualText(aChars.data(), aChars.size());
+    CPPUNIT_ASSERT_EQUAL(aExpectedText, aActualText);
+}
+#endif
 #endif
 
 CPPUNIT_TEST_SUITE_REGISTRATION(PdfExportTest);
diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx
index 2f110b138a8a..cfd86ed27409 100644
--- a/vcl/source/gdi/CommonSalLayout.cxx
+++ b/vcl/source/gdi/CommonSalLayout.cxx
@@ -690,6 +690,49 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
             for (int i = 0; i < nRunGlyphCount; ++i) {
                 int32_t nGlyphIndex = pHbGlyphInfos[i].codepoint;
                 int32_t nCharPos = pHbGlyphInfos[i].cluster;
+                int32_t nCharCount = 0;
+
+                // Find the number of characters that make up this glyph.
+                if (!bRightToLeft)
+                {
+                    // If the cluster is the same as previous glyph, then this
+                    // already consumed, skip.
+                    if (i > 0 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i - 1].cluster)
+                        nCharCount = 0;
+                    else
+                    {
+                        // Find the next glyph with a different cluster, or the
+                        // end of text.
+                        int j = i;
+                        int32_t nNextCharPos = nCharPos;
+                        while (nNextCharPos == nCharPos && j < nRunGlyphCount)
+                            nNextCharPos = pHbGlyphInfos[j++].cluster;
+
+                        if (nNextCharPos == nCharPos)
+                            nNextCharPos = rArgs.mnEndCharPos;
+                        nCharCount = nNextCharPos - nCharPos;
+                    }
+                }
+                else
+                {
+                    // If the cluster is the same as previous glyph, then this
+                    // will be consumed later, skip.
+                    if (i < nRunGlyphCount - 1 && pHbGlyphInfos[i].cluster == pHbGlyphInfos[i + 1].cluster)
+                        nCharCount = 0;
+                    else
+                    {
+                        // Find the previous glyph with a different cluster, or
+                        // the end of text.
+                        int j = i;
+                        int32_t nNextCharPos = nCharPos;
+                        while (nNextCharPos == nCharPos && j >= 0)
+                            nNextCharPos = pHbGlyphInfos[j--].cluster;
+
+                        if (nNextCharPos == nCharPos)
+                            nNextCharPos = rArgs.mnEndCharPos;
+                        nCharCount = nNextCharPos - nCharPos;
+                    }
+                }
 
                 // if needed request glyph fallback by updating LayoutArgs
                 if (!nGlyphIndex)
@@ -756,7 +799,7 @@ bool CommonSalLayout::LayoutText(ImplLayoutArgs& rArgs)
                 nYOffset = std::lround(nYOffset * nYScale);
 
                 Point aNewPos(aCurrPos.X() + nXOffset, aCurrPos.Y() + nYOffset);
-                const GlyphItem aGI(nCharPos, nGlyphIndex, aNewPos, nGlyphFlags,
+                const GlyphItem aGI(nCharPos, nCharCount, nGlyphIndex, aNewPos, nGlyphFlags,
                                     nAdvance, nXOffset);
                 AppendGlyph(aGI);
 
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 03b1a1d9e12d..58711a9d862b 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6598,7 +6598,6 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
     bool bVertical = m_aCurrentPDFState.m_aFont.IsVertical();
     int nGlyphs;
     int nIndex = 0;
-    int nMaxCharPos = rText.getLength()-1;
     double fXScale = 1.0;
     double fSkew = 0.0;
     sal_Int32 nPixelFontHeight = m_pReferenceDevice->mpFontInstance->maFontSelData.mnHeight;
@@ -6717,48 +6716,25 @@ void PDFWriterImpl::drawLayout( SalLayout& rLayout, const OUString& rText, bool
     FontMetric aRefDevFontMetric = m_pReferenceDevice->GetFontMetric();
 
     // collect the glyphs into a single array
-    const int nTmpMaxGlyphs = rLayout.GetOrientation() ? 1 : nMaxGlyphs; // #i97991# temporary workaround for #i87686#
     std::vector< PDFGlyph > aGlyphs;
-    aGlyphs.reserve( nTmpMaxGlyphs );
+    aGlyphs.reserve( nMaxGlyphs );
     // first get all the glyphs and register them; coordinates still in Pixel
     Point aGNGlyphPos;
-    while ((nGlyphs = rLayout.GetNextGlyphs(nTmpMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, pFallbackFonts)) != 0)
+    while ((nGlyphs = rLayout.GetNextGlyphs(nMaxGlyphs, pGlyphs, aGNGlyphPos, nIndex, pFallbackFonts)) != 0)
     {
         aCodeUnits.clear();
+        aCodeUnitsPerGlyph.clear();
         for( int i = 0; i < nGlyphs; i++ )
         {
-            // default case: 1 glyph is one unicode
-            aCodeUnitsPerGlyph.push_back(1);
-            if (pGlyphs[i]->mnCharPos >= 0 && pGlyphs[i]->mnCharPos <= nMaxCharPos)
-            {
-                int nChars = 1;
-                // try to handle ligatures and such
-                if( i < nGlyphs-1 )
-                {
-                    nChars = pGlyphs[i+1]->mnCharPos - pGlyphs[i]->mnCharPos;
-                    int start = pGlyphs[i]->mnCharPos;
-                    // #i115618# fix for simple RTL+CTL cases
-                    // supports RTL ligatures. TODO: more complex CTL, etc.
-                    if( nChars < 0 )
-                    {
-                        nChars = -nChars;
-                        start = pGlyphs[i+1]->mnCharPos + 1;
-                    }
-                    else if (nChars == 0)
-                        nChars = 1;
-                    aCodeUnitsPerGlyph.back() = nChars;
-                    for( int n = 0; n < nChars; n++ )
-                        aCodeUnits.push_back( rText[ start + n ] );
-                }
-                else
-                    aCodeUnits.push_back(rText[pGlyphs[i]->mnCharPos]);
-            }
-            else
-                aCodeUnits.push_back( 0 );
-            // note: in case of ctl one character may result
-            // in multiple glyphs. The current SalLayout
-            // implementations set -1 then to indicate that no direct
-            // mapping is possible
+            // try to handle ligatures and such
+            int nStart = pGlyphs[i]->mnCharPos;
+            int nChars = pGlyphs[i]->mnCharCount;
+            if (nChars < 0)
+                nChars = 0;
+
+            aCodeUnitsPerGlyph.push_back(nChars);
+            for( int n = 0; n < nChars; n++ )
+                aCodeUnits.push_back( rText[ nStart + n ] );
         }
 
         registerGlyphs( nGlyphs, pGlyphs, pGlyphWidths, aCodeUnits.data(), aCodeUnitsPerGlyph.data(), pMappedGlyphs, pMappedFontObjects, pFallbackFonts );
commit 6112d772603e8c63fd39e6cb5dff82910793b35b
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Wed Mar 21 14:08:49 2018 +0000

    Resolves: tdf#116429 unwanted extra step in undo insert shape
    
    Change-Id: I23065275baa60a09f2a3c15513e3f2b8160e2bf0
    Reviewed-on: https://gerrit.libreoffice.org/51706
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit 655d7340536ed2847d1da873b141d8776f791d12)
    Reviewed-on: https://gerrit.libreoffice.org/51711
    (cherry picked from commit deb5db7bf6d45338c9b6f6f4a1d62fba168b7a85)

diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index f6a5d1ee05d3..295671c0a50a 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2005,6 +2005,14 @@ bool SwFEShell::ImpEndCreate()
     }
     else
     {
+        if (rSdrObj.GetName().isEmpty())
+        {
+            bool bRestore = GetDoc()->GetIDocumentUndoRedo().DoesDrawUndo();
+            GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
+            rSdrObj.SetName(GetUniqueShapeName());
+            GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(bRestore);
+        }
+
         Point aRelNullPt;
         if( OBJ_CAPTION == nIdent )
             aRelNullPt = static_cast<SdrCaptionObj&>(rSdrObj).GetTailPos();
@@ -2060,9 +2068,6 @@ bool SwFEShell::ImpEndCreate()
             pAnch = pTmp;
         }
 
-        if (rSdrObj.GetName().isEmpty())
-            rSdrObj.SetName(GetUniqueShapeName());
-
         pContact->ConnectToLayout();
 
         // mark object at frame the object is inserted at.
commit e1a6ce470817744344c541cb13b6ac8376e85b3d
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Mar 20 14:26:35 2018 +0100

    Resolves: tdf#116468 do not check array/matrix context for reportdesign
    
    It doesn't have any, and worse, there's no currently active OpCode
    symbol map that could be used to create strings from tokens.
    
    Regression from
    
        commit bf1ffc64128f5b96d7c2fcc7adc81cbc25e232fd
        Date:   Sun Jul 16 15:18:09 2017 +0200
    
            FormulaDlg_Impl::UpdateValues: evaluate in force-array context if present
    
    Change-Id: I77c2035fdd0926f67fcc85e7090f30485b4e312c
    (cherry picked from commit 3a3a61bce913b564c7b7a98c56b55cbc11ea273a)
    Reviewed-on: https://gerrit.libreoffice.org/51642
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Lionel Elie Mamane <lionel at mamane.lu>
    (cherry picked from commit e722779351bb83af4ca368c143ab9561f1864bcf)

diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx
index c98167ea54bc..d6e39b62341b 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -570,19 +570,28 @@ void FormulaDlg_Impl::UpdateValues( bool bForceRecalcStruct )
     // Only necessary if it's not a matrix formula anyway.
     if (!m_pBtnMatrix->IsChecked())
     {
-        const sal_Int32 nPos = m_aFuncSel.Min();
-        assert( 0 <= nPos && nPos < m_pHelper->getCurrentFormula().getLength());
-        OUStringBuffer aBuf;
+        /* TODO: we probably don't even need to ask a compiler instance if
+         * m_pBtnMatrix is hidden. */
         std::unique_ptr<FormulaCompiler> pCompiler( m_pHelper->createCompiler( *m_pTokenArray.get()));
-        const FormulaToken* pToken = nullptr;
-        for (pToken = m_pTokenArrayIterator->First(); pToken; pToken = m_pTokenArrayIterator->Next())
+        // In the case of the reportdesign dialog there is no currently active
+        // OpCode symbol mapping that could be used to create strings from
+        // tokens, it's all dreaded API mapping. However, in that case there's
+        // no array/matrix support anyway.
+        if (pCompiler->GetCurrentOpCodeMap().get())
         {
-            pCompiler->CreateStringFromToken( aBuf, pToken);
-            if (nPos < aBuf.getLength())
-                break;
+            const sal_Int32 nPos = m_aFuncSel.Min();
+            assert( 0 <= nPos && nPos < m_pHelper->getCurrentFormula().getLength());
+            OUStringBuffer aBuf;
+            const FormulaToken* pToken = nullptr;
+            for (pToken = m_pTokenArrayIterator->First(); pToken; pToken = m_pTokenArrayIterator->Next())
+            {
+                pCompiler->CreateStringFromToken( aBuf, pToken);
+                if (nPos < aBuf.getLength())
+                    break;
+            }
+            if (pToken && nPos < aBuf.getLength())
+                bForceArray = pToken->IsInForceArray();
         }
-        if (pToken && nPos < aBuf.getLength())
-            bForceArray = pToken->IsInForceArray();
     }
 
     OUString aStrResult;
commit 12ef539d954d4a55a77263e93ce351a2f4a6fcc3
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Wed Mar 14 20:05:50 2018 +0100

    tdf#115420 fix DC usecount and drop wrong asserts
    
    For DC initialization we check the thread ID to assign a normal
    or cached DC to the corresponding WinSalGraphics variable.
    The cached DC has a usage count, as there are some limits on
    cached DCs count (DCX_CACHE).
    
    But for the WinSalGraphics DC init and release the variable just
    matters for the accounting, and generally which thread is doing
    the calls: the non-main thread always has to relay them to the
    main application thread.
    
    Since we're releasing all WinSalGraphics in ~WinSalFrame and do
    all release and re-init in ImplSetParentFrame, there is no way
    to correspond the thread ID to the WinSalGraphics variable.
    
    So this drops the wrong assertions based on the WinSalGraphics
    variables and renames the GETDC message to GETCACHEDDC to make
    usage of a cached DC (DCX_CACHE) more obvious.
    As a consequence of the different release DC handling this also
    fixes the accounting of the cached DCs, wich was broken in the
    initial fix; commit c15ea73f960bbd3d2a4b0c43b467ac62eeba3505
    
    Change-Id: I11ce52a1b4005f26567f92588437fa37bf227a2e
    Reviewed-on: https://gerrit.libreoffice.org/51318
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit 8939cb9456ee76a848cc8089747f280751092cf8)
    Reviewed-on: https://gerrit.libreoffice.org/51549
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    (cherry picked from commit 8e870ea9b828166b89a5c3f6c4f060bde6082f26)

diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index 45c402363119..8f5a3b87b415 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -215,7 +215,7 @@ int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 );
 // wParam == 0; lParam == pObject;
 #define SAL_MSG_DESTROYOBJECT       (WM_USER+117)
 // wParam == hWnd; lParam == 0; lResult == hDC
-#define SAL_MSG_GETDC               (WM_USER+120)
+#define SAL_MSG_GETCACHEDDC         (WM_USER+120)
 // wParam == hWnd; lParam == 0
 #define SAL_MSG_RELEASEDC           (WM_USER+121)
 // wParam == newParentHwnd; lParam == oldHwnd; lResult == newhWnd
diff --git a/vcl/inc/win/salframe.h b/vcl/inc/win/salframe.h
index 77902a40034e..36e4a041c955 100644
--- a/vcl/inc/win/salframe.h
+++ b/vcl/inc/win/salframe.h
@@ -33,8 +33,8 @@ public:
     HWND                    mhWnd;                  // Window handle
     HCURSOR                 mhCursor;               // cursor handle
     HIMC                    mhDefIMEContext;        // default IME-Context
-    WinSalGraphics*         mpLocalGraphics;        // current local frame graphics
-    WinSalGraphics*         mpThreadGraphics;       // current frame graphics for other threads
+    WinSalGraphics*         mpLocalGraphics;        // current main thread frame graphics
+    WinSalGraphics*         mpThreadGraphics;       // current frame graphics for other threads (DCX_CACHE)
     WinSalFrame*            mpNextFrame;            // pointer to next frame
     HMENU                   mSelectedhMenu;         // the menu where highlighting is currently going on
     HMENU                   mLastActivatedhMenu;    // the menu that was most recently opened
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index 5671361c987b..b13360f40b16 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -639,7 +639,7 @@ LRESULT CALLBACK SalComWndProc( HWND, UINT nMsg, WPARAM wParam, LPARAM lParam, b
         CASE_NOYIELDLOCK_RESULT( SAL_MSG_CREATEOBJECT, ImplSalCreateObject(
             GetSalData()->mpInstance, reinterpret_cast<WinSalFrame*>(lParam)) )
         CASE_NOYIELDLOCK( SAL_MSG_DESTROYOBJECT, delete reinterpret_cast<SalObject*>(lParam) )
-        CASE_NOYIELDLOCK_RESULT( SAL_MSG_GETDC, GetDCEx(
+        CASE_NOYIELDLOCK_RESULT( SAL_MSG_GETCACHEDDC, GetDCEx(
             reinterpret_cast<HWND>(wParam), nullptr, DCX_CACHE) )
         CASE_NOYIELDLOCK( SAL_MSG_RELEASEDC, ReleaseDC(
             reinterpret_cast<HWND>(wParam), reinterpret_cast<HDC>(lParam)) )
diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx
index dd0c4a521f74..f34c9d0936cc 100644
--- a/vcl/win/window/salframe.cxx
+++ b/vcl/win/window/salframe.cxx
@@ -924,17 +924,12 @@ bool WinSalFrame::ReleaseFrameGraphicsDC( WinSalGraphics* pGraphics )
     // we don't want to run the WinProc in the main thread directly
     // so we don't hit the mbNoYieldLock assert
     if ( !pSalData->mpInstance->IsMainThread() )
-    {
-        assert( pGraphics == mpThreadGraphics );
         SendMessageW( pSalData->mpInstance->mhComWnd, SAL_MSG_RELEASEDC,
             reinterpret_cast<WPARAM>(mhWnd), reinterpret_cast<LPARAM>(hDC) );
-        pSalData->mnCacheDCInUse--;
-    }
     else
-    {
-        assert( pGraphics == mpLocalGraphics );
         ReleaseDC( mhWnd, hDC );
-    }
+    if ( pGraphics == mpThreadGraphics )
+        pSalData->mnCacheDCInUse--;
     pGraphics->setHDC(nullptr);
     return TRUE;
 }
@@ -998,10 +993,6 @@ bool WinSalFrame::InitFrameGraphicsDC( WinSalGraphics *pGraphics, HDC hDC, HWND
 {
     SalData* pSalData = GetSalData();
     assert( pGraphics );
-    if ( !pSalData->mpInstance->IsMainThread() )
-        assert( pGraphics == mpThreadGraphics );
-    else
-        assert( pGraphics == mpLocalGraphics );
     pGraphics->setHWND( hWnd );
 
     HDC hCurrentDC = pGraphics->getHDC();
@@ -1049,7 +1040,7 @@ SalGraphics* WinSalFrame::AcquireGraphics()
         pGraphics = mpThreadGraphics;
         assert( !pGraphics->getHDC() );
         hDC = reinterpret_cast<HDC>(static_cast<sal_IntPtr>(SendMessageW( pSalData->mpInstance->mhComWnd,
-                                    SAL_MSG_GETDC, reinterpret_cast<WPARAM>(mhWnd), 0 )));
+                                    SAL_MSG_GETCACHEDDC, reinterpret_cast<WPARAM>(mhWnd), 0 )));
     }
     else
     {
@@ -1529,7 +1520,7 @@ void WinSalFrame::ImplSetParentFrame( HWND hNewParentWnd, bool bAsChild )
     {
         HDC hDC = reinterpret_cast<HDC>(static_cast<sal_IntPtr>(
                     SendMessageW( pSalData->mpInstance->mhComWnd,
-                        SAL_MSG_GETDC, reinterpret_cast<WPARAM>(hWnd), 0 )));
+                        SAL_MSG_GETCACHEDDC, reinterpret_cast<WPARAM>(hWnd), 0 )));
         InitFrameGraphicsDC( mpThreadGraphics, hDC, hWnd );
         if ( hDC )
         {
commit 96cdbbc93ab11f6e5b5a2c12fddfbf4d1dc07783
Author: Eike Rathke <erack at redhat.com>
Date:   Sat Mar 10 20:34:36 2018 +0100

    Resolves: tdf#116324 treat jump empty path as 0 when nested
    
    Apparently a fallout from
    
        commit 0f45ac20cd2ab2a64c40c7d6850f333cc33feeb0
        AuthorDate: Mon Jun 28 11:40:39 2010 -0400
        CommitDate: Sat Nov 6 23:40:00 2010 -0400
    
            More on fixing build by eliminating use of ScMatrixValue.
    
    or other commits related to ScMatrix handling.
    
    Change-Id: I10e8b58aed51cd707b1503dbbc0b369aea4a2805
    (cherry picked from commit 8930f8f530b4879226a6bac55bfeb551ac9e7489)
    Reviewed-on: https://gerrit.libreoffice.org/51053
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    (cherry picked from commit b0e7b2336d5d5723a9feab124f7c8a152f96dda4)

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 679a165f7e9c..49c7d009f05a 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -130,8 +130,10 @@ void ScInterpreter::ScIfJump()
                             else
                             {
                                 // Treat empty and empty path as 0, but string
-                                // as error.
-                                bIsValue = (!pMat->IsString(nC, nR) || pMat->IsEmpty(nC, nR));
+                                // as error. ScMatrix::IsValueOrEmpty() returns
+                                // true for any empty, empty path, empty cell,
+                                // empty result.
+                                bIsValue = pMat->IsValueOrEmpty(nC, nR);
                                 bTrue = false;
                                 fVal = (bIsValue ? 0.0 : CreateDoubleError( FormulaError::NoValue));
                             }
commit 75d3a15d1187cbbe9f04c18d4f9ed7597fe1b356
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Mar 6 21:26:23 2018 +0100

    Resolves: tdf#116215 separate column sums and row sums, tdf#71339 related
    
    Change-Id: Ifc7ab0c460f521ad3be4aa2785d54a1e4ed304e5
    (cherry picked from commit 9d8dcec608dde63c68b34450a95a3b168121e289)
    Reviewed-on: https://gerrit.libreoffice.org/50845
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    (cherry picked from commit 2f504da556cb091db0ad7c47f1bb90220d890c66)

diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index aaac0138287f..ebf5d9032c88 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -631,7 +631,10 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
     SCCOL nMarkEndCol = nEndCol;
     SCROW nMarkEndRow = nEndRow;
     ScAutoSum eSum = ScAutoSumNone;
-    ScRangeList aSumRangeList;
+    SCROW nColSums = 0;
+    SCCOL nRowSums = 0;
+    SCROW nColSumsStartRow = 0;
+    SCCOL nRowSumsStartCol = 0;
 
     if ( bRow )
     {
@@ -655,12 +658,15 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
         {
             if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
             {
+                ScRangeList aRangeList;
                 // Include the originally selected start row.
                 const ScRange aRange( nCol, rRange.aStart.Row(), nTab, nCol, nSumEndRow, nTab );
-                if ( (eSum = lcl_GetAutoSumForColumnRange( pDoc, aSumRangeList, aRange )) != ScAutoSumNone )
+                if ( (eSum = lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange )) != ScAutoSumNone )
                 {
+                    if (++nRowSums == 1)
+                        nRowSumsStartCol = aRangeList[0]->aStart.Col();
                     const OUString aFormula = GetAutoSumFormula(
-                        aSumRangeList, bSubTotal, ScAddress(nCol, nInsRow, nTab));
+                        aRangeList, bSubTotal, ScAddress(nCol, nInsRow, nTab));
                     EnterData( nCol, nInsRow, nTab, aFormula );
                 }
             }
@@ -689,11 +695,14 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
         {
             if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
             {
+                ScRangeList aRangeList;
                 // Include the originally selected start column.
                 const ScRange aRange( rRange.aStart.Col(), nRow, nTab, nSumEndCol, nRow, nTab );
-                if ( (eSum = lcl_GetAutoSumForRowRange( pDoc, aSumRangeList, aRange )) != ScAutoSumNone )
+                if ( (eSum = lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange )) != ScAutoSumNone )
                 {
-                    const OUString aFormula = GetAutoSumFormula( aSumRangeList, bSubTotal, ScAddress(nInsCol, nRow, nTab) );
+                    if (++nColSums == 1)
+                        nColSumsStartRow = aRangeList[0]->aStart.Row();
+                    const OUString aFormula = GetAutoSumFormula( aRangeList, bSubTotal, ScAddress(nInsCol, nRow, nTab) );
                     EnterData( nInsCol, nRow, nTab, aFormula );
                 }
             }
@@ -706,10 +715,10 @@ bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor
     // original selection. All extended by end column/row where the sum is put.
     const ScRange aMarkRange(
             (eSum == ScAutoSumSum ?
-             (aSumRangeList.size() == 1 ? aSumRangeList[0]->aStart.Col() : nStartCol) :
+             (nRowSums == 1 ? nRowSumsStartCol : nStartCol) :
              rRange.aStart.Col()),
             (eSum == ScAutoSumSum ?
-             (aSumRangeList.size() == 1 ? aSumRangeList[0]->aStart.Row() : nStartRow) :
+             (nColSums == 1 ? nColSumsStartRow : nStartRow) :
              rRange.aStart.Row()),
             nTab, nMarkEndCol, nMarkEndRow, nTab );
     MarkRange( aMarkRange, false, bContinue );
commit f12023c185b0dff258c871b9f026906bb53edee3
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Mar 6 18:41:56 2018 +0100

    Resolves: tdf#116100 fewer array of references cases, tdf#58874 related
    
    In particular if in any ForceArray context use the matrix result
    instead of the array of references list.
    
    (cherry picked from commit cfc6cf5177f8df23af35c4509c0276a19de56cce)
    
    Change-Id: I72328a690760637f6d31fadba447641c64711a67
    Reviewed-on: https://gerrit.libreoffice.org/50842
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
    (cherry picked from commit b52ca1a7cf9e3652ebd433753b6642b6f5124d1f)

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 0ee613dcd8f0..715a2608c7ea 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -2606,9 +2606,11 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
     else if (eType == formula::ParamClass::ReferenceOrForceArray)
     {
         // Inherit further only if the return class of the nested function is
-        // not Reference.
+        // not Reference. Else flag as suppressed.
         if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
             rCurr->SetInForceArray( eType);
+        else
+            rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
         return;
     }
 
@@ -2622,6 +2624,8 @@ void FormulaCompiler::ForceArrayOperator( FormulaTokenRef const & rCurr )
         {
             if (GetForceArrayParameter( rCurr.get(), SAL_MAX_UINT16) != ParamClass::Reference)
                 rCurr->SetInForceArray( eType);
+            else
+                rCurr->SetInForceArray( formula::ParamClass::SuppressedReferenceOrForceArray);
         }
     }
 }
diff --git a/formula/source/ui/dlg/formula.cxx b/formula/source/ui/dlg/formula.cxx
index 1a7505ac06f8..c98167ea54bc 100644
--- a/formula/source/ui/dlg/formula.cxx
+++ b/formula/source/ui/dlg/formula.cxx
@@ -762,6 +762,7 @@ void FormulaDlg_Impl::MakeTree( StructPage* _pTree, SvTreeListEntry* pParent, co
                             case ParamClass::Array:
                             case ParamClass::ForceArray:
                             case ParamClass::ReferenceOrForceArray:
+                            case ParamClass::SuppressedReferenceOrForceArray:
                                 ;   // nothing, only as array/matrix
                             // no default to get compiler warning
                         }
diff --git a/include/formula/paramclass.hxx b/include/formula/paramclass.hxx
index e8d411088061..a22854fc890c 100644
--- a/include/formula/paramclass.hxx
+++ b/include/formula/paramclass.hxx
@@ -51,8 +51,15 @@ namespace formula
             propagated to subsequent operators and functions being part of a
             parameter of this function. Used with functions that treat
             references separately from arrays, but need the forced array
-            calculation of parameters that are not references.*/
-        ReferenceOrForceArray
+            calculation of parameters that are not references. */
+        ReferenceOrForceArray,
+
+        /** Same as ReferenceOrForceArray but suppressed / not inherited in the
+            compiler's ForceArray context to indicate that a result of
+            Reference in JumpMatrix context should use the result matrix
+            instead of the array of references. Never used as initial parameter
+            classification. */
+        SuppressedReferenceOrForceArray
     };
 }
 
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 18a93676fa4a..679a165f7e9c 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -800,12 +800,19 @@ bool ScInterpreter::JumpMatrix( short nStackLevel )
     }
     if ( !bCont )
     {   // We're done with it, throw away jump matrix, keep result.
-        // For an intermediate result of Reference use the array of references,
+        // For an intermediate result of Reference use the array of references
+        // if there are more than one reference and the current ForceArray
+        // context is not ForceArray or related, suppressed, ...,
         // else (also for a final result of Reference) use the matrix.
         // Treat the result of a jump command as final and use the matrix (see
         // tdf#115493 for why).
+        ParamClass eParamClass;
         if (!FormulaCompiler::IsOpCodeJumpCommand( pJumpMatrix->GetOpCode()) &&
+                pJumpMatrix->GetRefList().size() > 1 &&
                 ScParameterClassification::GetParameterType( pCur, SAL_MAX_UINT16) == ParamClass::Reference &&
+                (eParamClass = pCur->GetInForceArray()) != ParamClass::ForceArray &&
+                eParamClass != ParamClass::ReferenceOrForceArray &&
+                eParamClass != ParamClass::SuppressedReferenceOrForceArray &&
                 aCode.PeekNextOperator())
         {
             FormulaTokenRef xRef = new ScRefListToken(true);
commit 4e136b5d0d8fb5bf4712cffbda71979b8c02c3a4
Author: Serge Krot <Serge.Krot at cib.de>
Date:   Mon Mar 19 22:19:38 2018 +0100

    tdf#115005 Do not remove original vector images from slides
    
    During calculation of the quality index of the image, we should
    take into account also SVM vector image type.
    Its mime type is image/x-vclgraphic.
    
    Reviewed-on: https://gerrit.libreoffice.org/51599
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
    
    Conflicts:
            sd/qa/unit/export-tests-ooxml2.cxx
            xmloff/source/core/xmlmultiimagehelper.cxx
    
    Reviewed-on: https://gerrit.libreoffice.org/51655
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
    (cherry picked from commit 070f3db51da48c70cde12050c18fb03de2192c0f)
    
    Change-Id: I7c723e99995f73258bb59d976a6c7670c51f7a25

diff --git a/sd/qa/unit/data/odp/tdf115005.odp b/sd/qa/unit/data/odp/tdf115005.odp
new file mode 100755
index 000000000000..764a862feda7
Binary files /dev/null and b/sd/qa/unit/data/odp/tdf115005.odp differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx b/sd/qa/unit/export-tests-ooxml2.cxx
index 972e60949eaa..606e931c0c1f 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -130,6 +130,7 @@ public:
     void testTdf115394();
     void testTdf115394Zero();
     void testTdf111789();
+    void testTdf115005();
     /// SmartArt animated elements
     void testTdf104792();
     void testTdf90627();
@@ -185,6 +186,7 @@ public:
     CPPUNIT_TEST(testGroupsRotatedPosition);
     CPPUNIT_TEST(testAccentColor);
     CPPUNIT_TEST(testTdf114848);
+    CPPUNIT_TEST(testTdf115005);
     CPPUNIT_TEST(testTdf107608);
     CPPUNIT_TEST(testTdf111786);
     CPPUNIT_TEST(testFontScale);
@@ -1482,6 +1484,26 @@ void SdOOXMLExportTest2::testTdf111789()
     xDocShRef->DoClose();
 }
 
+void SdOOXMLExportTest2::testTdf115005()
+{
+    sd::DrawDocShellRef xDocShRefOriginal = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/odp/tdf115005.odp"), ODP);
+    utl::TempFile tempFile;
+    sd::DrawDocShellRef xDocShRefResaved = saveAndReload(xDocShRefOriginal.get(), ODP, &tempFile);
+
+    // additional checks of the output file
+    uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), tempFile.GetURL());
+
+    // check that the document contains original vector images
+    const uno::Sequence<OUString> names = xNameAccess->getElementNames();
+    int nSVMFiles = 0;
+    for (int i=0; i<names.getLength(); i++)
+    {
+        if(names[i].endsWith(".svm"))
+            nSVMFiles++;
+    }
+    CPPUNIT_ASSERT_EQUAL(3, nSVMFiles);
+}
+
 void SdOOXMLExportTest2::testTdf104792()
 {
     ::sd::DrawDocShellRef xDocShRef = loadURL(
diff --git a/xmloff/source/core/xmlmultiimagehelper.cxx b/xmloff/source/core/xmlmultiimagehelper.cxx
index 3d7725a3b24f..c0e437c1f370 100644
--- a/xmloff/source/core/xmlmultiimagehelper.cxx
+++ b/xmloff/source/core/xmlmultiimagehelper.cxx
@@ -64,6 +64,10 @@ namespace
         }
 
         // vector formats, prefer always
+        if(sMimeType == "image/x-vclgraphic") // MIMETYPE_VCLGRAPHIC
+        {
+            return 990;
+        }
         if(sMimeType == "image/x-svm")
         {
             return 1000;
commit 2564d17e117b2489cd06c476dbdc61360cc512c7
Author: Mike Kaganski <mike.kaganski at collabora.com>
Date:   Mon Mar 19 00:11:33 2018 +0300

    tdf#116472: import "auto" border color as black
    
    Since commit fe6da2feb57c3d5e355a36f6b8ac09b48412ff39, "auto" color is
    supported in OOXML import.
    
    Since ODF doesn't support "auto" color as border color, just convert
    "auto" border color to black on import, like is done in GetLineIndex
    in ww8par6.cxx.
    
    Incidentally, this also fixes a problem in RTF import, where we used to
    import black borders ("\red0\green0\blue0;" entries in color table) as
    0x000001 ("\red0\green0\blue1;") - see fixed tests in rtfexport2.cxx.
    
    Change-Id: I4f5e720d215b51c8a43dc7c58f338741bd608efc
    Reviewed-on: https://gerrit.libreoffice.org/51519
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/51585
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 88e22b92bce612f349f8aa38adf69a8806361da3)

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index 1fa183ca174a..11401fe20323 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -650,43 +650,43 @@ DECLARE_OOXMLEXPORT_TEST(testfdo80097, "fdo80097.docx")
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:color = '000000']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:color = '000000']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:color = '000000']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:color = '000000']", 1);
 
     //Table Cell Borders
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:color = '000000']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:color = '000000']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:color = '000000']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:color = 'auto']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:color = '000000']", 1);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFdo77129, "fdo77129.docx")
diff --git a/sw/qa/extras/rtfexport/rtfexport2.cxx b/sw/qa/extras/rtfexport/rtfexport2.cxx
index 60032e92a145..731ab53e8de8 100644
--- a/sw/qa/extras/rtfexport/rtfexport2.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport2.cxx
@@ -1293,7 +1293,8 @@ DECLARE_RTFEXPORT_TEST(testNestedTable, "rhbz1065629.rtf")
     xTable.set(xTables->getByIndex(2), uno::UNO_QUERY);
     xCell.set(xTable->getCellByName("A1"), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xCell.is());
-    table::BorderLine2 fullPtSolid(1, 0, 35, 0, table::BorderLineStyle::SOLID, 35);
+    table::BorderLine2 fullPtSolid(sal_Int32(COL_BLACK), 0, 35, 0, table::BorderLineStyle::SOLID,
+                                   35);
     CPPUNIT_ASSERT_BORDER_EQUAL(fullPtSolid, getProperty<table::BorderLine2>(xCell, "LeftBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(fullPtSolid, getProperty<table::BorderLine2>(xCell, "RightBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(fullPtSolid, getProperty<table::BorderLine2>(xCell, "TopBorder"));
@@ -1302,7 +1303,8 @@ DECLARE_RTFEXPORT_TEST(testNestedTable, "rhbz1065629.rtf")
     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xCC0000), getProperty<sal_Int32>(xCell, "BackColor"));
     xCell.set(xTable->getCellByName("A2"), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xCell.is());
-    table::BorderLine2 halfPtSolid(/*0*/ 1, 0, 18, 0, table::BorderLineStyle::SOLID, 18);
+    table::BorderLine2 halfPtSolid(sal_Int32(COL_BLACK), 0, 18, 0, table::BorderLineStyle::SOLID,
+                                   18);
     CPPUNIT_ASSERT_BORDER_EQUAL(halfPtSolid, getProperty<table::BorderLine2>(xCell, "LeftBorder"));
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xffffffff),
                          getProperty<sal_Int32>(xCell, "BackColor"));
@@ -1367,7 +1369,7 @@ DECLARE_RTFEXPORT_TEST(testTableBorderDefaults, "fdo68779.rtf")
     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xCell.is());
-    table::BorderLine2 solid(1, 0, 26, 0, table::BorderLineStyle::SOLID, 26);
+    table::BorderLine2 solid(sal_Int32(COL_BLACK), 0, 26, 0, table::BorderLineStyle::SOLID, 26);
     CPPUNIT_ASSERT_BORDER_EQUAL(solid, getProperty<table::BorderLine2>(xCell, "LeftBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(solid, getProperty<table::BorderLine2>(xCell, "RightBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(solid, getProperty<table::BorderLine2>(xCell, "TopBorder"));
@@ -1376,7 +1378,7 @@ DECLARE_RTFEXPORT_TEST(testTableBorderDefaults, "fdo68779.rtf")
     xTable.set(xTables->getByIndex(1), uno::UNO_QUERY);
     xCell.set(xTable->getCellByName("A1"), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xCell.is());
-    table::BorderLine2 dotted(1, 0, 26, 0, table::BorderLineStyle::DOTTED, 26);
+    table::BorderLine2 dotted(sal_Int32(COL_BLACK), 0, 26, 0, table::BorderLineStyle::DOTTED, 26);
     CPPUNIT_ASSERT_BORDER_EQUAL(dotted, getProperty<table::BorderLine2>(xCell, "LeftBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(dotted, getProperty<table::BorderLine2>(xCell, "RightBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(dotted, getProperty<table::BorderLine2>(xCell, "TopBorder"));
@@ -1385,7 +1387,8 @@ DECLARE_RTFEXPORT_TEST(testTableBorderDefaults, "fdo68779.rtf")
     xTable.set(xTables->getByIndex(2), uno::UNO_QUERY);
     xCell.set(xTable->getCellByName("A1"), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xCell.is());
-    table::BorderLine2 doubled(1, 26, 26, 26, table::BorderLineStyle::DOUBLE, 79);
+    table::BorderLine2 doubled(sal_Int32(COL_BLACK), 26, 26, 26, table::BorderLineStyle::DOUBLE,
+                               79);
     CPPUNIT_ASSERT_BORDER_EQUAL(doubled, getProperty<table::BorderLine2>(xCell, "LeftBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(doubled, getProperty<table::BorderLine2>(xCell, "RightBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(doubled, getProperty<table::BorderLine2>(xCell, "TopBorder"));
@@ -1394,7 +1397,8 @@ DECLARE_RTFEXPORT_TEST(testTableBorderDefaults, "fdo68779.rtf")
     xTable.set(xTables->getByIndex(3), uno::UNO_QUERY);
     xCell.set(xTable->getCellByName("A1"), uno::UNO_QUERY);
     CPPUNIT_ASSERT(xCell.is());
-    table::BorderLine2 thinThickMG(1, 14, 26, 14, table::BorderLineStyle::THINTHICK_MEDIUMGAP, 53);
+    table::BorderLine2 thinThickMG(sal_Int32(COL_BLACK), 14, 26, 14,
+                                   table::BorderLineStyle::THINTHICK_MEDIUMGAP, 53);
     CPPUNIT_ASSERT_BORDER_EQUAL(thinThickMG, getProperty<table::BorderLine2>(xCell, "LeftBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(thinThickMG, getProperty<table::BorderLine2>(xCell, "RightBorder"));
     CPPUNIT_ASSERT_BORDER_EQUAL(thinThickMG, getProperty<table::BorderLine2>(xCell, "TopBorder"));
diff --git a/writerfilter/source/dmapper/ConversionHelper.cxx b/writerfilter/source/dmapper/ConversionHelper.cxx
index 777fbf9b83da..28f934a6716f 100644
--- a/writerfilter/source/dmapper/ConversionHelper.cxx
+++ b/writerfilter/source/dmapper/ConversionHelper.cxx
@@ -245,16 +245,17 @@ void MakeBorderLine( sal_Int32 nLineThickness,   sal_Int32 nLineToken,
     {
         // The first item means automatic color (COL_AUTO), but we
         // do not use it anyway (see the next statement) .-)
-        0, COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
+        // See also GetLineIndex in sw/source/filter/ww8/ww8par6.cxx
+        sal_Int32(COL_AUTO), COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
         COL_LIGHTMAGENTA, COL_LIGHTRED, COL_YELLOW, COL_WHITE, COL_BLUE,
         COL_CYAN, COL_GREEN, COL_MAGENTA, COL_RED, COL_BROWN, COL_GRAY,
         COL_LIGHTGRAY
     };
-    //no auto color for borders
-    if(!nLineColor)
-        ++nLineColor;
     if(!bIsOOXML && sal::static_int_cast<sal_uInt32>(nLineColor) < SAL_N_ELEMENTS(aBorderDefColor))
         nLineColor = aBorderDefColor[nLineColor];
+    //no auto color for borders
+    if (nLineColor == sal_Int32(COL_AUTO))
+        nLineColor = sal_Int32(COL_BLACK);
 
     sal_Int32 nLineType = lcl_convertBorderStyleFromToken(nLineToken);
 
commit 6edaa34ce5b2b2b2ae1cf38d491d66025a78a0c6
Author: Luke Deller <luke at deller.id.au>
Date:   Thu Mar 8 01:11:40 2018 +1100

    tdf#116179 Support reading "auto" colour from docx
    
    In docx a colour value is represented as a 6-digit hex RGB value, or
    alternatively the word "auto" to represent automatic colour.
    
     - Add support for reading the value "auto" as COL_AUTO.  Previously
       this would be read as if it were a hex value, stopping at the
       letter 'u' which is not a valid hex digit, resulting in the colour
       0x00000A - a very dark blue, which looks close enough to black that
       it went unnoticed for a long time :-)
    
     - Remove code which tried to handle this wrong 0x00000A value,
       including the constant OOXML_COLOR_AUTO, as it is no longer needed
       and will cause surprises for anyone who really wanted this exact
       shade of dark blue
    
     - Fix unit tests that were checking for 0x00000A
    
    Change-Id: I6000070341931147ff9341ad6281cd3b53c02b46
    Reviewed-on: https://gerrit.libreoffice.org/50995
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Reviewed-on: https://gerrit.libreoffice.org/51461
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    (cherry picked from commit 3967aebca94be9ceea3e36b43f7f53589473ad4e)

diff --git a/filter/source/msfilter/util.cxx b/filter/source/msfilter/util.cxx
index 9cf01a0929a3..c563b0a54095 100644
--- a/filter/source/msfilter/util.cxx
+++ b/filter/source/msfilter/util.cxx
@@ -126,14 +126,11 @@ sal_Unicode bestFitOpenSymbolToMSFont(sal_Unicode cChar,
 }
 
 
-OString ConvertColor( const Color &rColor, bool bAutoColor )
+OString ConvertColor( const Color &rColor )
 {
     OString color( "auto" );
 
-    if (bAutoColor && rColor.GetColor() == OOXML_COLOR_AUTO)
-        return color;
-
-    if ( rColor.GetColor() != COL_AUTO )
+    if ( rColor != COL_AUTO )
     {
         const char pHexDigits[] = "0123456789ABCDEF";
         char pBuffer[] = "000000";
diff --git a/include/filter/msfilter/util.hxx b/include/filter/msfilter/util.hxx
index 8895a4181bec..623f1cfe84db 100644
--- a/include/filter/msfilter/util.hxx
+++ b/include/filter/msfilter/util.hxx
@@ -59,15 +59,12 @@ MSFILTER_DLLPUBLIC sal_Unicode bestFitOpenSymbolToMSFont(sal_Unicode cBullet,
     rtl_TextEncoding& r_ioChrSet, OUString& r_ioFontName);
 
 
-#define OOXML_COLOR_AUTO 0x0a
-
 /**
  * Converts tools Color to HTML color (without leading hashmark).
  *
  * @param rColor color to convert
- * @param bAutoColor if OOXML_COLOR_AUTO should be recognized as an auto color
  */
-MSFILTER_DLLPUBLIC OString ConvertColor( const Color &rColor, bool bAutoColor = false );
+MSFILTER_DLLPUBLIC OString ConvertColor( const Color &rColor );
 
 
 /** Paper size in 1/100 millimeters. */
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index 536eea8c6d07..ce981644f5e1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
@@ -699,7 +699,7 @@ DECLARE_OOXMLEXPORT_TEST(testNumOverrideLvltext, "num-override-lvltext.docx")
     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), comphelper::SequenceAsHashMap(xRules->getByIndex(1))["ParentNumbering"].get<sal_Int16>());
 
     // The paragraph marker's red font color was inherited by the number portion, this was ff0000.
-    CPPUNIT_ASSERT_EQUAL(OUString("00000a"), parseDump("//Special[@nType='POR_NUMBER']/SwFont", "color"));
+    CPPUNIT_ASSERT_EQUAL(OUString("ffffffff"), parseDump("//Special[@nType='POR_NUMBER']/SwFont", "color"));
 }
 
 DECLARE_OOXMLEXPORT_TEST(testNumOverrideStart, "num-override-start.docx")
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
index c396ed6b4b72..7ce8b025bd5a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx
@@ -215,21 +215,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf107035, "tdf107035.docx")
 
     // Check that the page number field colour is set to "automatic".
     sal_Int32 nPgNumColour = getProperty<sal_Int32>(xPgNumRun, "CharColor");
-#if 0
-    // TODO Enable this once tdf#116179 is fixed
     CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_AUTO), nPgNumColour);
-
-#else
-    // Meanwhile just check that the page number field colour is different
-    // from the green text before it:
-
-    // Select the first run containing the green text
-    auto xTextRun = getRun(getParagraph(1), 1);
-
-    // Check that the page number field colour is different from the green text
-    CPPUNIT_ASSERT(getProperty<sal_Int32>(xTextRun, "CharColor") != nPgNumColour);
-#endif
-
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
index fc98eb98243d..1fa183ca174a 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport5.cxx
@@ -650,43 +650,43 @@ DECLARE_OOXMLEXPORT_TEST(testfdo80097, "fdo80097.docx")
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:top[@w:color = 'auto']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:bottom[@w:color = 'auto']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideH[@w:color = 'auto']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tblPr/w:tblBorders/w:insideV[@w:color = 'auto']", 1);
 
     //Table Cell Borders
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:top[@w:color = 'auto']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom[@w:color = 'auto']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideH[@w:color = 'auto']", 1);
 
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:val = 'single']",1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:sz = 4]", 1);
     assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:space = 0]", 1);
-    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:color = '00000A']", 1);
+    assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/w:insideV[@w:color = 'auto']", 1);
 }
 
 DECLARE_OOXMLEXPORT_TEST(testFdo77129, "fdo77129.docx")
diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx
index 794458141e01..379a8bc46e3e 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -465,7 +465,8 @@ void SwFont::dumpAsXml(xmlTextWriterPtr writer) const
 {
     xmlTextWriterStartElement(writer, BAD_CAST("SwFont"));
     xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("ptr"), "%p", this);
-    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("color"), "%s", GetColor().AsRGBHexString().toUtf8().getStr());
+    // do not use Color::AsRGBHexString() as that omits the transparency
+    xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("color"), "%08x", GetColor().GetColor());
     xmlTextWriterEndElement(writer);
 }
 
diff --git a/writerfilter/source/dmapper/BorderHandler.cxx b/writerfilter/source/dmapper/BorderHandler.cxx
index e2528c28d50e..0a07c9753393 100644
--- a/writerfilter/source/dmapper/BorderHandler.cxx
+++ b/writerfilter/source/dmapper/BorderHandler.cxx
@@ -67,7 +67,7 @@ void BorderHandler::lcl_attribute(Id rName, Value & rVal)
         break;
         case NS_ooxml::LN_CT_Border_color:
             m_nLineColor = nIntValue;
-            appendGrabBag("color", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true)));
+            appendGrabBag("color", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue)));
         break;
         case NS_ooxml::LN_CT_Border_space: // border distance in points
             m_nLineDistance = ConversionHelper::convertTwipToMM100( nIntValue * 20 );
diff --git a/writerfilter/source/dmapper/CellColorHandler.cxx b/writerfilter/source/dmapper/CellColorHandler.cxx
index cb8fccac1f71..968c1b1f553f 100644
--- a/writerfilter/source/dmapper/CellColorHandler.cxx
+++ b/writerfilter/source/dmapper/CellColorHandler.cxx
@@ -109,8 +109,8 @@ void CellColorHandler::lcl_attribute(Id rName, Value & rVal)
         }
         break;
         case NS_ooxml::LN_CT_Shd_fill:
-            createGrabBag("fill", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true))));
-            if( nIntValue == OOXML_COLOR_AUTO )
+            createGrabBag("fill", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue))));
+            if( nIntValue == sal_Int32(COL_AUTO) )
                 nIntValue = 0xffffff; //fill color auto means white
             else
                 m_bAutoFillColor = false;
@@ -118,8 +118,8 @@ void CellColorHandler::lcl_attribute(Id rName, Value & rVal)
             m_nFillColor = nIntValue;
         break;
         case NS_ooxml::LN_CT_Shd_color:
-            createGrabBag("color", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true))));
-            if( nIntValue == OOXML_COLOR_AUTO )
+            createGrabBag("color", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue))));
+            if( nIntValue == sal_Int32(COL_AUTO) )
                 nIntValue = 0; //shading color auto means black
             //color of the shading
             m_nColor = nIntValue;
@@ -283,7 +283,7 @@ TablePropertyMapPtr  CellColorHandler::getProperties()
         pPropertyMap->Insert( m_OutputFormat == Form ? PROP_BACK_COLOR
                             : PROP_CHAR_BACK_COLOR, uno::makeAny( nApplyColor ));
 
-    createGrabBag("originalColor", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nApplyColor, true))));
+    createGrabBag("originalColor", uno::makeAny(OUString::fromUtf8(msfilter::util::ConvertColor(nApplyColor))));
 
     return pPropertyMap;
 }
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index 5569f91a23de..40134d148ac9 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -302,7 +302,7 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
         case NS_ooxml::LN_CT_Color_val:
             if (m_pImpl->GetTopContext())
                 m_pImpl->GetTopContext()->Insert(PROP_CHAR_COLOR, uno::makeAny( nIntValue ) );
-            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true)));
+            m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "val", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue)));
             break;
         case NS_ooxml::LN_CT_Underline_color:
             if (m_pImpl->GetTopContext())
diff --git a/writerfilter/source/dmapper/TDefTableHandler.cxx b/writerfilter/source/dmapper/TDefTableHandler.cxx
index bd594fc510cb..b86f37ed8bf3 100644
--- a/writerfilter/source/dmapper/TDefTableHandler.cxx
+++ b/writerfilter/source/dmapper/TDefTableHandler.cxx
@@ -287,7 +287,7 @@ void TDefTableHandler::lcl_attribute(Id rName, Value & rVal)
             appendGrabBag("val", TDefTableHandler::getBorderTypeString(nIntValue));
         break;
         case NS_ooxml::LN_CT_Border_color:
-            appendGrabBag("color", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue, /*bAutoColor=*/true)));
+            appendGrabBag("color", OUString::fromUtf8(msfilter::util::ConvertColor(nIntValue)));
             m_nLineColor = nIntValue;
         break;
         case NS_ooxml::LN_CT_Border_space:
diff --git a/writerfilter/source/ooxml/OOXMLFactory.cxx b/writerfilter/source/ooxml/OOXMLFactory.cxx
index c164ff949757..91eb7b0e4c96 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.cxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.cxx
@@ -96,6 +96,15 @@ void OOXMLFactory::attributes(OOXMLFastContextHandler * pHandler,
                 pFactory->attributeAction(pHandler, nToken, xValue);
             }
             break;
+        case ResourceType::HexColor:
+            {
+                const char *pValue = "";
+                pAttribs->getAsChar(nToken, pValue);
+                OOXMLValue::Pointer_t xValue(new OOXMLHexColorValue(pValue));
+                pHandler->newProperty(nId, xValue);
+                pFactory->attributeAction(pHandler, nToken, xValue);
+            }
+            break;
         case ResourceType::TwipsMeasure:
             {
                 const char *pValue = "";
diff --git a/writerfilter/source/ooxml/OOXMLFactory.hxx b/writerfilter/source/ooxml/OOXMLFactory.hxx
index dce03696185c..fcf89155ae7c 100644
--- a/writerfilter/source/ooxml/OOXMLFactory.hxx
+++ b/writerfilter/source/ooxml/OOXMLFactory.hxx
@@ -40,6 +40,7 @@ enum class ResourceType {
     Integer,
     Properties,
     Hex,
+    HexColor,
     String,
     Shape,
     Boolean,
diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.cxx b/writerfilter/source/ooxml/OOXMLPropertySet.cxx
index 286da4fb040e..916c1b9a4902 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySet.cxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySet.cxx
@@ -23,6 +23,7 @@
 #include <ooxml/QNameToString.hxx>
 #include <com/sun/star/drawing/XShape.hpp>
 #include <oox/token/tokens.hxx>
+#include <tools/color.hxx>
 
 namespace writerfilter {
 namespace ooxml
@@ -577,6 +578,21 @@ string OOXMLHexValue::toString() const
 }
 #endif
 
+/*
+  class OOXMLHexColorValue
+*/
+OOXMLHexColorValue::OOXMLHexColorValue(const char * pValue)
+{
+    if (!strcmp(pValue, "auto"))
+    {
+        mnValue = sal_uInt32(COL_AUTO);
+    }
+    else
+    {
+        mnValue = rtl_str_toUInt32(pValue, 16);
+    }
+}
+
 // OOXMLUniversalMeasureValue
 // ECMA-376 5th ed. Part 1 , 22.9.2.15
 OOXMLUniversalMeasureValue::OOXMLUniversalMeasureValue(const char * pValue, sal_uInt32 npPt)
diff --git a/writerfilter/source/ooxml/OOXMLPropertySet.hxx b/writerfilter/source/ooxml/OOXMLPropertySet.hxx
index c6b664f59b90..f6aaa3ac4686 100644
--- a/writerfilter/source/ooxml/OOXMLPropertySet.hxx
+++ b/writerfilter/source/ooxml/OOXMLPropertySet.hxx
@@ -211,7 +211,9 @@ public:
 
 class OOXMLHexValue : public OOXMLValue
 {
+protected:
     sal_uInt32 mnValue;
+    OOXMLHexValue() {}
 public:
     explicit OOXMLHexValue(sal_uInt32 nValue);
     explicit OOXMLHexValue(const char * pValue);
@@ -224,6 +226,12 @@ public:
     virtual OOXMLValue * clone() const override;
 };
 
+class OOXMLHexColorValue : public OOXMLHexValue
+{
+public:
+    explicit OOXMLHexColorValue(const char * pValue);
+};
+
 class OOXMLUniversalMeasureValue : public OOXMLValue
 {
 private:
diff --git a/writerfilter/source/ooxml/factoryimpl.py b/writerfilter/source/ooxml/factoryimpl.py
index 3605892fe71f..acbaf4234261 100644
--- a/writerfilter/source/ooxml/factoryimpl.py
+++ b/writerfilter/source/ooxml/factoryimpl.py
@@ -37,7 +37,10 @@ def createFastChildContextFromFactory(model):
 
             switch (nResource)
             {""")
-    resources = ["List", "Integer", "Hex", "String", "TwipsMeasure", "HpsMeasure", "Boolean", "MeasurementOrPercent"]
+    resources = [
+        "List", "Integer", "Hex", "HexColor", "String", "TwipsMeasure",
+        "HpsMeasure", "Boolean", "MeasurementOrPercent",
+    ]
     for resource in [r.getAttribute("resource") for r in model.getElementsByTagName("resource")]:
         if resource not in resources:
             resources.append(resource)
diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml
index a9ffbdfa6c65..25f8a267bb8a 100644
--- a/writerfilter/source/ooxml/model.xml
+++ b/writerfilter/source/ooxml/model.xml
@@ -16710,7 +16710,7 @@
       <value tokenid="ooxml:Value_ST_HexColorAuto_auto">auto</value>
     </resource>
     <resource name="ST_HexColorRGB" resource="Hex"/>
-    <resource name="ST_HexColor" resource="Hex"/>
+    <resource name="ST_HexColor" resource="HexColor"/>
     <resource name="CT_Color" resource="Properties">
       <attribute name="val" tokenid="ooxml:CT_Color_val"/>
       <attribute name="themeColor" tokenid="ooxml:CT_Color_themeColor"/>
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 8fffb36f966b..4e7b2f73fe74 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -97,8 +97,10 @@ void putNestedAttribute(RTFSprms& rSprms, Id nParent, Id nId, const RTFValue::Po
         if (nParent == NS_ooxml::LN_CT_TcPrBase_shd)
         {
             // RTF default is 'auto', see writerfilter::dmapper::CellColorHandler
-            aAttributes.set(NS_ooxml::LN_CT_Shd_color, std::make_shared<RTFValue>(0x0a));
-            aAttributes.set(NS_ooxml::LN_CT_Shd_fill, std::make_shared<RTFValue>(0x0a));
+            aAttributes.set(NS_ooxml::LN_CT_Shd_color,
+                            std::make_shared<RTFValue>(sal_uInt32(COL_AUTO)));
+            aAttributes.set(NS_ooxml::LN_CT_Shd_fill,
+                            std::make_shared<RTFValue>(sal_uInt32(COL_AUTO)));
         }
         auto pParentValue = std::make_shared<RTFValue>(aAttributes);
         rSprms.set(nParent, pParentValue, eOverwrite);
commit 250ef06baadbc85ab6884f2a1938e22286eae75c
Author: Caolán McNamara <caolanm at redhat.com>
Date:   Fri Mar 16 16:50:42 2018 +0000

    rhbz#1392145 ensure titlebar close button matches 'outside' direction
    
    Change-Id: I20e925c58adb56acd4d1a63720d330c8b6613441
    Reviewed-on: https://gerrit.libreoffice.org/51434
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 029ba7ac94d517143af5166df4e2dcb58b350443)

diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx
index 0c9b002cb264..bf0ade47db2a 100644
--- a/vcl/inc/unx/gtk/gtkframe.hxx
+++ b/vcl/inc/unx/gtk/gtkframe.hxx
@@ -173,6 +173,7 @@ class GtkSalFrame : public SalFrame
     SalX11Screen                    m_nXScreen;
     GtkWidget*                      m_pWindow;
 #if GTK_CHECK_VERSION(3,0,0)
+    GtkHeaderBar*                   m_pHeaderBar;
     GtkGrid*                        m_pTopLevelGrid;
 #endif
     GtkEventBox*                    m_pEventBox;
diff --git a/vcl/source/app/svmain.cxx b/vcl/source/app/svmain.cxx
index 1dfede46fc94..f7d24d09079a 100644
--- a/vcl/source/app/svmain.cxx
+++ b/vcl/source/app/svmain.cxx
@@ -31,7 +31,7 @@
 
 #include <comphelper/processfactory.hxx>
 #include <comphelper/asyncnotification.hxx>
-
+#include <i18nlangtag/mslangid.hxx>
 #include <unotools/syslocaleoptions.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/vclmain.hxx>
@@ -335,6 +335,7 @@ bool InitVCL()
         OUString aLocaleString(SvtSysLocaleOptions().GetRealUILanguageTag().getGlibcLocaleString(".UTF-8"));
         if (!aLocaleString.isEmpty())
         {
+            MsLangId::getSystemUILanguage(); //call this now to pin what the system UI really was
             OUString envVar("LANGUAGE");
             osl_setEnvironment(envVar.pData, aLocaleString.pData);
         }
diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx
index 27a65caa3612..c8c98f5c5255 100644
--- a/vcl/unx/gtk3/gtk3gtkframe.cxx
+++ b/vcl/unx/gtk3/gtk3gtkframe.cxx
@@ -74,6 +74,8 @@
 #  include <cstdio>
 #endif
 
+#include <i18nlangtag/mslangid.hxx>
+
 #include <cstdlib>
 #include <cmath>
 
@@ -477,6 +479,7 @@ bool GtkSalFrame::doKeyCallback( guint state,
 
 GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
+    , m_pHeaderBar(nullptr)
     , m_pGraphics(nullptr)
     , m_bGraphics(false)
 {
@@ -489,6 +492,7 @@ GtkSalFrame::GtkSalFrame( SalFrame* pParent, SalFrameStyleFlags nStyle )
 
 GtkSalFrame::GtkSalFrame( SystemParentData* pSysData )
     : m_nXScreen( getDisplay()->GetDefaultXScreen() )
+    , m_pHeaderBar(nullptr)
     , m_pGraphics(nullptr)
     , m_bGraphics(false)
 {
@@ -1241,6 +1245,27 @@ void GtkSalFrame::Init( SalFrame* pParent, SalFrameStyleFlags nStyle )
         gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), eType );
         gtk_window_set_gravity( GTK_WINDOW(m_pWindow), GDK_GRAVITY_STATIC );
         gtk_window_set_resizable( GTK_WINDOW(m_pWindow), bool(nStyle & SalFrameStyleFlags::SIZEABLE) );
+
+#if defined(GDK_WINDOWING_WAYLAND)
+        //rhbz#1392145 under wayland/csd if we've overridden the default widget direction in order to set LibreOffice's
+        //UI to the configured ui language but the system ui locale is a different text direction, then the toplevel
+        //built-in close button of the titlebar follows the overridden direction rather than continue in the same
+        //direction as every other titlebar on the user's desktop. So if they don't match set an explicit
+        //header bar with the desired 'outside' direction
+        if ((eType == GDK_WINDOW_TYPE_HINT_NORMAL || eType == GDK_WINDOW_TYPE_HINT_DIALOG) && GDK_IS_WAYLAND_DISPLAY(GtkSalFrame::getGdkDisplay()))
+        {
+            const bool bDesktopIsRTL = MsLangId::isRightToLeft(MsLangId::getSystemUILanguage());
+            const bool bAppIsRTL = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
+            if (bDesktopIsRTL != bAppIsRTL)
+            {
+                m_pHeaderBar = GTK_HEADER_BAR(gtk_header_bar_new());
+                gtk_widget_set_direction(GTK_WIDGET(m_pHeaderBar), bDesktopIsRTL ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR);
+                gtk_header_bar_set_show_close_button(m_pHeaderBar, true);
+                gtk_window_set_titlebar(GTK_WINDOW(m_pWindow), GTK_WIDGET(m_pHeaderBar));
+                gtk_widget_show(GTK_WIDGET(m_pHeaderBar));
+            }
+        }
+#endif
     }
     else if( nStyle & SalFrameStyleFlags::FLOAT )
         gtk_window_set_type_hint( GTK_WINDOW(m_pWindow), GDK_WINDOW_TYPE_HINT_POPUP_MENU );
@@ -1332,7 +1357,12 @@ void GtkSalFrame::SetTitle( const OUString& rTitle )
 {
     m_aTitle = rTitle;
     if( m_pWindow && ! isChild() )
-        gtk_window_set_title( GTK_WINDOW(m_pWindow), OUStringToOString( rTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
+    {
+        OString sTitle(OUStringToOString(rTitle, RTL_TEXTENCODING_UTF8));
+        gtk_window_set_title(GTK_WINDOW(m_pWindow), sTitle.getStr());
+        if (m_pHeaderBar)
+            gtk_header_bar_set_title(m_pHeaderBar, sTitle.getStr());
+    }
 }
 
 void GtkSalFrame::SetIcon( sal_uInt16 nIcon )
commit 6e1f363ed2212c42d75445168389a64bcddc05cc
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Fri Mar 16 14:21:01 2018 +0100

    sdk/lib dir missing from Linux installation sets
    
    ...after cfd2691e5bf398304d7816227b933e53907b6204 "[API CHANGE] Remove salcpprt
    static library" had removed the sole regular File item from gid_Dir_Lib_Sdk,
    leaving only Unixlink items.  But the solenv/bin/modules/installer.pm code used
    to only auto-create any directories that contain regular Files.  Changed that to
    also consider Unixlinks in addition to regular Files.
    
    And to add insult to injury, the code in
    solenv/bin/modules/installer/simplepackage.pm creating the actual symlinks
    represented by the Unixlink items silently does nothing when a symlink cannot be
    created (because the partent dir is missing).  To be fixed in another follow-up
    commit.
    
    Change-Id: Ic7a682a17ac59c789c85c56c825dd623bc59428c
    (cherry picked from commit f07e2496963baf8f7c0fecc79e7a420544075d98)
    Reviewed-on: https://gerrit.libreoffice.org/51419
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    (cherry picked from commit 10e959e6e35421d802d8f6a3904ff96f36f7124c)

diff --git a/solenv/bin/modules/installer.pm b/solenv/bin/modules/installer.pm
index 3d88b9986e14..151462f94ffc 100644
--- a/solenv/bin/modules/installer.pm
+++ b/solenv/bin/modules/installer.pm
@@ -636,6 +636,18 @@ sub run {
 
         installer::scpzipfiles::resolving_scpzip_replace_flag($filesinproductlanguageresolvedarrayref, $allvariableshashref, "File", $languagestringref);
 
+        #########################################################
+        # language dependent unix links part
+        #########################################################
+
+        installer::logger::print_message( "... analyzing unix links ...\n" );
+
+        my $unixlinksinproductlanguageresolvedarrayref = installer::scriptitems::resolving_all_languages_in_productlists($unixlinksinproductarrayref, $languagesarrayref);
+
+        installer::scriptitems::changing_name_of_language_dependent_keys($unixlinksinproductlanguageresolvedarrayref);
+
+        installer::scriptitems::get_Destination_Directory_For_Item_From_Directorylist($unixlinksinproductlanguageresolvedarrayref, $dirsinproductarrayref);
+
         ############################################
         # Collecting directories for epm list file
         ############################################
@@ -649,8 +661,7 @@ sub run {
         # It will be possible, that in the setup script only those directoies have to be defined,
         # that have a CREATE flag. All other directories are created, if they contain at least one file.
 
-        my ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_from_filesarray($filesinproductlanguageresolvedarrayref);
-
+        my ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_from_filesarray($filesinproductlanguageresolvedarrayref, $unixlinksinproductlanguageresolvedarrayref);
         ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_with_create_flag_from_directoryarray($dirsinproductlanguageresolvedarrayref, $alldirectoryhash);
 
         #########################################################
@@ -690,18 +701,6 @@ sub run {
         installer::scriptitems::resolve_links_with_flag_relative($linksinproductlanguageresolvedarrayref);
 
         #########################################################
-        # language dependent unix links part
-        #########################################################
-
-        installer::logger::print_message( "... analyzing unix links ...\n" );
-
-        my $unixlinksinproductlanguageresolvedarrayref = installer::scriptitems::resolving_all_languages_in_productlists($unixlinksinproductarrayref, $languagesarrayref);
-
-        installer::scriptitems::changing_name_of_language_dependent_keys($unixlinksinproductlanguageresolvedarrayref);
-
-        installer::scriptitems::get_Destination_Directory_For_Item_From_Directorylist($unixlinksinproductlanguageresolvedarrayref, $dirsinproductarrayref);
-
-        #########################################################
         # language dependent part for profiles and profileitems
         #########################################################
 
@@ -814,7 +813,7 @@ sub run {
             @{$folderitemsinproductlanguageresolvedarrayref} = (); # no folderitems in languagepacks
 
             # Collecting the directories again, to include only the language specific directories
-            ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_from_filesarray($filesinproductlanguageresolvedarrayref);
+            ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_from_filesarray($filesinproductlanguageresolvedarrayref, $unixlinksinproductlanguageresolvedarrayref);
             ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_with_create_flag_from_directoryarray($dirsinproductlanguageresolvedarrayref, $alldirectoryhash);
             @$directoriesforepmarrayref = sort { $a->{"HostName"} cmp $b->{"HostName"} } @$directoriesforepmarrayref;
 
@@ -835,7 +834,7 @@ sub run {
             @{$folderitemsinproductlanguageresolvedarrayref} = (); # no folderitems in helppacks
 
             # Collecting the directories again, to include only the language specific directories
-            ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_from_filesarray($filesinproductlanguageresolvedarrayref);
+            ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_from_filesarray($filesinproductlanguageresolvedarrayref, $unixlinksinproductlanguageresolvedarrayref);
             ($directoriesforepmarrayref, $alldirectoryhash) = installer::scriptitems::collect_directories_with_create_flag_from_directoryarray($dirsinproductlanguageresolvedarrayref, $alldirectoryhash);
             @$directoriesforepmarrayref = sort { $a->{"HostName"} cmp $b->{"HostName"} } @$directoriesforepmarrayref;
 
diff --git a/solenv/bin/modules/installer/scriptitems.pm b/solenv/bin/modules/installer/scriptitems.pm
index db2b67c5c9bb..774578d8f9f9 100644
--- a/solenv/bin/modules/installer/scriptitems.pm
+++ b/solenv/bin/modules/installer/scriptitems.pm
@@ -1590,7 +1590,10 @@ sub optimize_list
 
 sub collect_directories_from_filesarray
 {
-    my ($filesarrayref) = @_;
+    my ($filesarrayref, $unixlinksarrayref) = @_;
+    my @allfiles;
+    push @allfiles, @{$filesarrayref};
+    push @allfiles, @{$unixlinksarrayref};
 
     my @alldirectories = ();
     my %alldirectoryhash = ();
@@ -1600,9 +1603,9 @@ sub collect_directories_from_filesarray
     # Preparing this already as hash, although the only needed value at the moment is the HostName
     # But also adding: "specificlanguage" and "Dir" (for instance gid_Dir_Program)
 
-    for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ )
+    for ( my $i = 0; $i <= $#allfiles; $i++ )
     {
-        my $onefile = ${$filesarrayref}[$i];
+        my $onefile = $allfiles[$i];
         my $destinationpath = $onefile->{'destination'};
         installer::pathanalyzer::get_path_from_fullqualifiedname(\$destinationpath);
         $destinationpath =~ s/\Q$installer::globals::separator\E\s*$//;     # removing ending slashes or backslashes
commit f0cd86ec917b9818108748ba3ea43af6a420c3f1
Author: Szymon Kłos <szymon.klos at collabora.com>
Date:   Thu Mar 15 19:23:20 2018 +0100

    tdf#104789 Export opacity attribute name
    
    Change-Id: Id47ab6b3cb20fbcebb2d7fa589f3b0d7552e2cce
    Reviewed-on: https://gerrit.libreoffice.org/51369

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list