[Libreoffice-commits] core.git: Branch 'distro/cib/libreoffice-6-1' - 13 commits - connectivity/Library_postgresql-sdbc-impl.mk desktop/CppunitTest_desktop_app.mk desktop/Library_crashreport.mk desktop/Library_sofficeapp.mk external/clucene external/liblangtag external/libmspub external/pdfium jurt/Library_jpipe.mk libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk libreofficekit/Executable_gtktiledviewer.mk libreofficekit/Executable_tilebench.mk onlineupdate/Executable_test_updater_dialog.mk onlineupdate/Executable_updater.mk sal/Library_sal.mk sc/CppunitTest_sc_ucalc.mk sc/Library_sc.mk smoketest/Executable_libtest.mk solenv/gbuild svx/Executable_gengal.mk sw/qa sw/source vcl/Executable_icontest.mk vcl/Executable_lo_kde5filepicker.mk vcl/Executable_mtfdemo.mk vcl/Executable_ui-previewer.mk vcl/Executable_vcldemo.mk vcl/Executable_visualbackendtest.mk vcl/Library_desktop_detector.mk vcl/Library_vcl.mk vcl/Library_vclplug_gen.mk vcl/Library_vclplug_gtk3_kde5.mk vcl/Library_vclplug_gtk3.m k vcl/Library_vclplug_gtk.mk vcl/Library_vclplug_kde5.mk vcl/Library_vclplug_qt5.mk vcl/StaticLibrary_glxtest.mk

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Thu Jun 4 17:02:05 UTC 2020


 connectivity/Library_postgresql-sdbc-impl.mk                |    1 
 desktop/CppunitTest_desktop_app.mk                          |    1 
 desktop/Library_crashreport.mk                              |    1 
 desktop/Library_sofficeapp.mk                               |    3 
 external/clucene/Library_clucene.mk                         |    1 
 external/liblangtag/UnpackedTarball_liblangtag.mk           |    3 
 external/liblangtag/Wformat-overflow.patch                  |   17 
 external/libmspub/UnpackedTarball_libmspub.mk               |    1 
 external/libmspub/stdint.patch                              |   10 
 external/pdfium/Library_pdfium.mk                           |    1 
 jurt/Library_jpipe.mk                                       |    4 
 libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk |    1 
 libreofficekit/Executable_gtktiledviewer.mk                 |    1 
 libreofficekit/Executable_tilebench.mk                      |    1 
 onlineupdate/Executable_test_updater_dialog.mk              |    1 
 onlineupdate/Executable_updater.mk                          |    1 
 sal/Library_sal.mk                                          |    3 
 sc/CppunitTest_sc_ucalc.mk                                  |    6 
 sc/Library_sc.mk                                            |    6 
 smoketest/Executable_libtest.mk                             |    1 
 solenv/gbuild/platform/linux.mk                             |    2 
 solenv/gbuild/platform/unxgcc.mk                            |   10 
 svx/Executable_gengal.mk                                    |    2 
 sw/qa/extras/layout/data/abi11870-2.odt                     |binary
 sw/qa/extras/layout/layout.cxx                              |    8 
 sw/qa/extras/ooxmlimport/ooxmlimport.cxx                    |   10 
 sw/source/core/access/accportions.cxx                       |    3 
 sw/source/core/crsr/bookmrk.cxx                             |   26 +
 sw/source/core/doc/docbm.cxx                                |   17 
 sw/source/core/inc/bookmrk.hxx                              |    4 
 sw/source/core/inc/scriptinfo.hxx                           |   21 
 sw/source/core/inc/txttypes.hxx                             |    1 
 sw/source/core/text/inftxt.cxx                              |   18 
 sw/source/core/text/inftxt.hxx                              |    3 
 sw/source/core/text/itrform2.cxx                            |   55 ++
 sw/source/core/text/porlay.cxx                              |  268 +++++++++++-
 sw/source/core/text/porlin.cxx                              |   47 +-
 sw/source/core/text/porlin.hxx                              |    2 
 sw/source/core/text/pormulti.cxx                            |   20 
 sw/source/core/text/porrst.cxx                              |  130 ++++-
 sw/source/core/text/porrst.hxx                              |   25 +
 sw/source/core/text/xmldump.cxx                             |    1 
 sw/source/core/txtnode/modeltoviewhelper.cxx                |    2 
 vcl/Executable_icontest.mk                                  |    1 
 vcl/Executable_lo_kde5filepicker.mk                         |    1 
 vcl/Executable_mtfdemo.mk                                   |    1 
 vcl/Executable_ui-previewer.mk                              |    1 
 vcl/Executable_vcldemo.mk                                   |    1 
 vcl/Executable_visualbackendtest.mk                         |    1 
 vcl/Library_desktop_detector.mk                             |    1 
 vcl/Library_vcl.mk                                          |    6 
 vcl/Library_vclplug_gen.mk                                  |    1 
 vcl/Library_vclplug_gtk.mk                                  |    1 
 vcl/Library_vclplug_gtk3.mk                                 |    1 
 vcl/Library_vclplug_gtk3_kde5.mk                            |    1 
 vcl/Library_vclplug_kde5.mk                                 |    1 
 vcl/Library_vclplug_qt5.mk                                  |    1 
 vcl/StaticLibrary_glxtest.mk                                |    1 
 58 files changed, 642 insertions(+), 117 deletions(-)

New commits:
commit 5dc4b9b9ce47ecf0ebe4b442c3bcad9f6560f15c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Jun 3 16:03:09 2020 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 18:50:42 2020 +0200

    tdf#130804 sw: fix bookmark portions in line containing only as-char fly
    
    There were 2 problems:
    
    * due to the first bookmark portion, the line got an additional 55 twips
      of its descent added to its height in SwLineLayout::CalcLine().
    
    * when called from SwTextFrame::CalcHeightOfLastLine(),
      SwLineLayout::MaxAscentDescent() is supposed to ignore FlyInCnt
      portions, but it didn't ignore the bookmark portion which had the same
      height, hence the resulting line spacing was 855 instead of 0 and the
      upper margin of the next paragraph increased similarly.
    
    (regression from 4ce8120f1e53f7b81e653b01d141643013bc69ab)
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95438
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 97d77b670d1c2e5dd045130427c42a6b74d55889)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95423
    Tested-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 4927143b6652ce2d19e6f476923112f0ab7fc273)
    
    Change-Id: I52b154a48c5d712b7e3e323d2e3e08f37bf1afd1

diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index ce2b16c74323..226e9e83999a 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -393,7 +393,9 @@ void SwLineLayout::CalcLine( SwTextFormatter &rLine, SwTextFormatInfo &rInf )
                 }
 
                 // Ignore drop portion height
-                if( pPos->IsDropPortion() && static_cast<SwDropPortion*>(pPos)->GetLines() > 1)
+                // tdf#130804 ... and bookmark portions
+                if ((pPos->IsDropPortion() && static_cast<SwDropPortion*>(pPos)->GetLines() > 1)
+                    || pPos->GetWhichPor() == POR_BOOKMARK)
                 {
                     pLast = pPos;
                     pPos = pPos->GetPortion();
@@ -603,6 +605,8 @@ void SwLineLayout::MaxAscentDescent( SwTwips& _orAscent,
     while ( pTmpPortion )
     {
         if ( !pTmpPortion->IsBreakPortion() && !pTmpPortion->IsFlyPortion() &&
+            // tdf#130804 ignore bookmark portions
+             pTmpPortion->GetWhichPor() != POR_BOOKMARK &&
              ( !_bNoFlyCntPorAndLinePor ||
                ( !pTmpPortion->IsFlyCntPortion() &&
                  !(pTmpPortion == this && pTmpPortion->GetPortion() ) ) ) )
commit ad8df544bb72022eb677beb45231d2ac31ff5cf6
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Jun 2 18:16:15 2020 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 18:50:41 2020 +0200

    crashtesting: fix abi11870-2.odt assert in SwBookmarkPortion::Unchain()
    
    This m_pPrevious pointer is a bad idea, should just use
    FindPrevPortion() to find it, which shouldn't take that long to iterate
    all the portions in the current line.
    
    (regression from 4ce8120f1e53f7b81e653b01d141643013bc69ab)
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91622
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    (cherry picked from commit f68749054f36f070310e70e2dbf0a11c496539c0)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95415
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit deee67c566811189ee66d5766d0c9fc644a0120b)
    
    Change-Id: Ibb5f2bb28d959958547ed27c51e5084cc746d642

diff --git a/sw/qa/extras/layout/data/abi11870-2.odt b/sw/qa/extras/layout/data/abi11870-2.odt
new file mode 100644
index 000000000000..b02bb85646aa
Binary files /dev/null and b/sw/qa/extras/layout/data/abi11870-2.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index bdbcc12c9487..cb2e3e705ad7 100755
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -36,6 +36,7 @@ public:
     void testTdf117188();
     void testTdf119875();
     void testTdf116989();
+    void testAbi11870();
     void testStableAtPageAnchoredFlyPosition();
 
     CPPUNIT_TEST_SUITE(SwLayoutWriter);
@@ -54,6 +55,7 @@ public:
     CPPUNIT_TEST(testTdf117188);
     CPPUNIT_TEST(testTdf119875);
     CPPUNIT_TEST(testTdf116989);
+    CPPUNIT_TEST(testAbi11870);
     CPPUNIT_TEST(testStableAtPageAnchoredFlyPosition);
     CPPUNIT_TEST_SUITE_END();
 
@@ -310,6 +312,12 @@ void SwLayoutWriter::testTdf116989()
     }
 }
 
+void SwLayoutWriter::testAbi11870()
+{
+    //just care it doesn't assert
+    createDoc("abi11870-2.odt");
+}
+
 static SwRect lcl_getVisibleFlyObjRect(SwWrtShell* pWrtShell)
 {
     SwRootFrame* pRoot = pWrtShell->GetLayout();
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index e838b8c08289..e21c06c8fd23 100755
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -1187,7 +1187,7 @@ SwLinePortion *SwTextFormatter::WhichFirstPortion(SwTextFormatInfo &rInf)
                 assert(bookmark & SwScriptInfo::MarkKind::Point);
                 mark = '|';
             }
-            pPor = new SwBookmarkPortion(rInf.GetLast(), mark);
+            pPor = new SwBookmarkPortion(mark);
         }
     }
 
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index 5ff1fceb5a92..0239c0d67744 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -2035,7 +2035,13 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf,
         if (rInf.GetLast()->GetWhichPor() == POR_BOOKMARK)
         {
             auto const pBookmark(static_cast<SwBookmarkPortion*>(rInf.GetLast()));
-            rInf.SetLast(pBookmark->Unchain());
+            auto *const pPrevious = pBookmark->FindPrevPortion(rInf.GetRoot());
+            assert(!pPrevious || pPrevious->GetPortion() == pBookmark);
+            if (pPrevious)
+            {
+                pPrevious->SetPortion(nullptr);
+            }
+            rInf.SetLast(pPrevious);
             assert(m_pCurr->GetPortion() == nullptr);
             m_pCurr->SetPortion(pBookmark);
         }
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index 067ae9d477f0..654ddec99fea 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -632,13 +632,4 @@ sal_uInt16 SwControlCharPortion::GetViewWidth( const SwTextSizeInfo& rInf ) cons
     return mnViewWidth;
 }
 
-SwLinePortion * SwBookmarkPortion::Unchain()
-{
-    assert(!m_pPrevious || m_pPrevious->GetPortion() == this);
-    m_pPrevious->SetPortion(nullptr);
-    auto const pTmp(m_pPrevious);
-    m_pPrevious = nullptr;
-    return pTmp;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porrst.hxx b/sw/source/core/text/porrst.hxx
index 6b930d4f0262..3dd55acf3f0d 100644
--- a/sw/source/core/text/porrst.hxx
+++ b/sw/source/core/text/porrst.hxx
@@ -147,13 +147,9 @@ public:
 /// SwControlCharPortion these do not have a character in the text.
 class SwBookmarkPortion : public SwControlCharPortion
 {
-private:
-    SwLinePortion * m_pPrevious;
-
 public:
-    explicit SwBookmarkPortion(SwLinePortion *const pPrevious, sal_Unicode const cChar)
+    explicit SwBookmarkPortion(sal_Unicode const cChar)
         : SwControlCharPortion(cChar)
-        , m_pPrevious(pPrevious)
     {
         SetWhichPor(POR_BOOKMARK);
         SetLen(TextFrameIndex(0));
@@ -162,7 +158,6 @@ public:
     virtual bool DoPaint(SwTextPaintInfo const& rInf,
         OUString & rOutString, SwFont & rTmpFont, int & rDeltaY) const override;
     virtual SwLinePortion * Compress() override { return this; }
-    SwLinePortion * Unchain();
 };
 
 #endif
commit 903c3b365ec8d6db5efdcff90b59204f465a8e56
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Mon Mar 30 16:26:41 2020 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 18:38:13 2020 +0200

    crashtesting: null dereference of reexporting abi12570.odt to odt
    
    FLY_AT_FLY shape is anchored on SwStartNode of fly section.
    
    (regression from ef8427d12a63127a2eb867637699343d630545dd)
    
    Change-Id: I4fe70237c060cc810af82657bc5791e7024db8f5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91336
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 71ed878556422068041025668876fb3300c128df)

diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 0998c1c83644..d65f6f0a783b 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -397,10 +397,12 @@ namespace sw { namespace mark
             " - more than USHRT_MAX marks are not supported correctly");
 
         if (   (!rPaM.GetPoint()->nNode.GetNode().IsTextNode()
-                    // huh, SwXTextRange puts one on table node?
-                && !rPaM.GetPoint()->nNode.GetNode().IsTableNode())
+                && (eType != MarkType::UNO_BOOKMARK
+                // SwXTextRange can be on table node or plain start node (FLY_AT_FLY)
+                    || !rPaM.GetPoint()->nNode.GetNode().IsStartNode()))
             || (!rPaM.GetMark()->nNode.GetNode().IsTextNode()
-                && !rPaM.GetMark()->nNode.GetNode().IsTableNode()))
+                && (eType != MarkType::UNO_BOOKMARK
+                    || !rPaM.GetMark()->nNode.GetNode().IsStartNode())))
         {
             SAL_WARN("sw.core", "MarkManager::makeMark(..)"
                 " - refusing to create mark on non-textnode");
commit 13192264e78ba1c810b3c061893e2ad1f6b3574a
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Feb 5 16:27:53 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 18:37:08 2020 +0200

    tdf#45589 sw: don't paint field shading for bookmarks
    
    Maybe it looks better without.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88039
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit c0b7fe8281319146c4a2e36e203cfd65633ce3bd)
    
    Change-Id: Id603fbef361574cafbe2ec9f625ac54fea27a0f6

diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index bd1c45721bc1..a0b3e24c72dc 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1297,12 +1297,7 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
             }
             break;
         case POR_BOOKMARK:
-            if (!GetOpt().IsPagePreview()
-                 && !GetOpt().IsReadonly()
-                 && GetOpt().IsViewMetaChars())
-            {
-                bDraw = true;
-            }
+            // no shading
             break;
         case POR_INPUTFLD:
             // input field shading also in read-only mode
commit 5a7288901fad8bd833357f1672213bce8273ab3c
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Jan 24 19:05:40 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 18:30:21 2020 +0200

    tdf#45589 sw: create and paint text portions for bookmarks
    
    Add a new SwBookmarkPortion, derived from SwControlCharPortion.
    
    There is no character for the bookmark in the text so the portion has
    length of 0, which makes things quite a bit more tricky.
    
    Formatting:
    
    * SwBookmarkPortion is created last in WhichFirstPortion().
    
    * In an empty paragraph the SwTextFrame::FormatEmpty() must be disabled.
    
    * If there's a bookmark at the end of a paragraph,
      SwTextFormatter::CalcAscent() must use the font of the previous
      character, not the paragraph font, because that could grow the line
      if it's higher.
    
    * The SwMultiPortion complicates matters, because it uses a nested
      SwTextFormatInfo and thus we need some extra steps to prevent
      duplicate SwBookmarkPortions; this is particluarly a problem for
      rotated text portions.
      - SwTextFormatter::BuildPortions() must advance the outer
        SwTextFormatInfo's bookmark position because BuildMultiPortion() has
        already created the SwBookmarkPortion.
      - If a SwBookmarkPortion is at the start of a SwMultiPortion, it will
        be created before the SwMultiPortion but must be painted inside the
        SwMultiPortion because its font is going to be initialised as inside
        the SwMultiPortion (e.g. it will be rotated) so its position must
        also be adapted to be inside, and only
        SwTextPainter::PaintMultiPortion() does the setup for that; add a
        hack to move it in SwTextFormatter::BuildMultiPortion().
    
    Painting:
    
    * Using the original font seems rather difficult, hard to predict what
      some character is going to look like, and how it scales if the size is
      increased; use OpenSymbol instead.  Unfortunately OpenSymbol doesn't
      have a good glyph that could be used for both the end of a bookmark
      and start of another bookmark at the same position.
    
    * SwLinePortion::PrePaint() wants to avoid moving the portion
      half-outside the frame but often it looks better that way (previously
      it was misaligned, now it's half-outside).
    
    * Not sure if it makes sense to draw a field shading in
      SwTextPaintInfo::DrawViewOpt() too; let's try it out, but dependent on
      the same IsViewMetaChars() setting as the bookmark character itself,
      not on the field shading setting.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87364
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    Tested-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 4ce8120f1e53f7b81e653b01d141643013bc69ab)
    
    Change-Id: I1ab94afb417221e278dbb3afd6c978a05fc78497

diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index 4743cbc8afed..300bc3a70499 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -311,8 +311,14 @@ DECLARE_OOXMLIMPORT_TEST(testN758883, "n758883.docx")
      * The problem was that direct formatting of the paragraph was not applied
      * to the numbering. This is easier to test using a layout dump.
      */
-    OUString aHeight = parseDump("/root/page/body/txt/Special", "nHeight");
-    CPPUNIT_ASSERT_EQUAL(sal_Int32(220), aHeight.toInt32()); // It was 280
+    xmlDocPtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "/root/page/body/txt/Special[1]", "nHeight", "220");
+
+    // check the bookmark portions are of the expected height
+    assertXPath(pXmlDoc, "/root/page/body/txt/Special[2]", "nType", "POR_BOOKMARK");
+    assertXPath(pXmlDoc, "/root/page/body/txt/Special[2]", "nHeight", "253");
+    assertXPath(pXmlDoc, "/root/page/body/txt/Special[3]", "nType", "POR_BOOKMARK");
+    assertXPath(pXmlDoc, "/root/page/body/txt/Special[3]", "nHeight", "253");
 
     /*
      * Next problem was that the page margin contained the width of the page border as well.
diff --git a/sw/source/core/access/accportions.cxx b/sw/source/core/access/accportions.cxx
index 14b00e1b3dd4..32723457d50b 100644
--- a/sw/source/core/access/accportions.cxx
+++ b/sw/source/core/access/accportions.cxx
@@ -180,6 +180,9 @@ void SwAccessiblePortionData::Special(
         case POR_CONTROLCHAR:
             sDisplay = rText + OUStringLiteral1( m_pTextNode->GetText()[m_nModelPosition] );
             break;
+        case POR_BOOKMARK:
+            // TODO
+            break;
         default:
             sDisplay = rText;
             break;
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 124709786e9e..9a408f52abe6 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -25,6 +25,7 @@
 #include <swscanner.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <osl/diagnose.h>
+#include <o3tl/typed_flags_set.hxx>
 #include "TextFrameIndex.hxx"
 
 class SwTextNode;
@@ -43,7 +44,7 @@ class SwScriptInfo
 {
 public:
     enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE, SPECIAL_MIDDLE};
-    enum class MarkKind { Start, End, Point };
+    enum class MarkKind { Start = (1<<0), End = (1<<1), Point = (1<<2) };
 
 private:
     //! Records a single change in script type.
@@ -182,6 +183,7 @@ public:
         return m_HiddenChg[ nCnt ];
     }
     TextFrameIndex NextBookmark(TextFrameIndex nPos) const;
+    MarkKind GetBookmark(TextFrameIndex nPos) const;
     static void CalcHiddenRanges(const SwTextNode& rNode,
             MultiSelection& rHiddenMulti,
             std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
@@ -385,6 +387,13 @@ public:
     static SwFontScript WhichFont(sal_Int32 nIdx, OUString const & rText);
 };
 
+namespace o3tl
+{
+
+template<> struct typed_flags<SwScriptInfo::MarkKind> : is_typed_flags<SwScriptInfo::MarkKind, 0x07> {};
+
+}
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/txttypes.hxx b/sw/source/core/inc/txttypes.hxx
index 1633afc07f69..3925e98796d9 100644
--- a/sw/source/core/inc/txttypes.hxx
+++ b/sw/source/core/inc/txttypes.hxx
@@ -33,6 +33,7 @@
 #define POR_MULTI       0x0085
 #define POR_HIDDEN_TXT  0x0086
 #define POR_CONTROLCHAR 0x0087
+#define POR_BOOKMARK    0x0088
 
 #define POR_TXT         0x8000
 #define POR_LAY         0x8001
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 5c7faa1b8511..bd1c45721bc1 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1296,6 +1296,14 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
                 bDraw = true;
             }
             break;
+        case POR_BOOKMARK:
+            if (!GetOpt().IsPagePreview()
+                 && !GetOpt().IsReadonly()
+                 && GetOpt().IsViewMetaChars())
+            {
+                bDraw = true;
+            }
+            break;
         case POR_INPUTFLD:
             // input field shading also in read-only mode
             if ( !GetOpt().IsPagePreview()
@@ -1484,6 +1492,7 @@ void SwTextFormatInfo::Init()
     m_nForcedLeftMargin = 0;
     m_nSoftHyphPos = TextFrameIndex(0);
     m_nUnderScorePos = TextFrameIndex(COMPLETE_STRING);
+    m_nLastBookmarkPos = TextFrameIndex(-1);
     m_cHookChar = 0;
     SetIdx(TextFrameIndex(0));
     SetLen(TextFrameIndex(GetText().getLength()));
@@ -1895,4 +1904,18 @@ bool SwTextFormatInfo::ChgHyph( const bool bNew )
     return bOld;
 }
 
+
+bool SwTextFormatInfo::CheckCurrentPosBookmark()
+{
+    if (m_nLastBookmarkPos != GetIdx())
+    {
+        m_nLastBookmarkPos = GetIdx();
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/inftxt.hxx b/sw/source/core/text/inftxt.hxx
index 1156e1197c14..2ee460e35a2e 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -484,6 +484,7 @@ class SwTextFormatInfo : public SwTextPaintInfo
     TextFrameIndex m_nSoftHyphPos;   ///< SoftHyphPos for Hyphenation
     TextFrameIndex m_nLineStart;     ///< Current line start in rText
     TextFrameIndex m_nUnderScorePos; ///< enlarge repaint if underscore has been found
+    TextFrameIndex m_nLastBookmarkPos; ///< need to check for bookmarks at every portion
     // #i34348# Changed type from sal_uInt16 to SwTwips
     SwTwips m_nLeft;              // Left margin
     SwTwips m_nRight;             // Right margin
@@ -640,6 +641,8 @@ public:
     bool IsArrowDone() const { return m_bArrowDone; }
     void SetArrowDone( const bool bNew ) { m_bArrowDone = bNew; }
 
+    bool CheckCurrentPosBookmark();
+
     // For SwTextPortion::Hyphenate
     bool ChgHyph( const bool bNew );
 
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index f3fca32c60c7..e838b8c08289 100755
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -705,6 +705,10 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf )
             CalcAscent( rInf, pPor );
 
         InsertPortion( rInf, pPor );
+        if (pPor->IsMultiPortion() && (!pMulti || pMulti->IsBidi()))
+        {
+            (void) rInf.CheckCurrentPosBookmark(); // bookmark was already created inside MultiPortion!
+        }
         pPor = NewPortion( rInf );
     }
 
@@ -767,6 +771,19 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor )
         pPor->Height( pLast->Height() );
         pPor->SetAscent( pLast->GetAscent() );
     }
+    else if (pPor->GetWhichPor() == POR_BOOKMARK
+            && rInf.GetIdx() == TextFrameIndex(rInf.GetText().getLength()))
+    {
+        // bookmark at end of paragraph: *don't* advance iterator, use the
+        // current font instead; it's possible that there's a font size on the
+        // paragraph and it's overridden on the last line of the paragraph and
+        // we don't want to apply it via SwBookmarkPortion and grow the line
+        // height (example: n758883.docx)
+        SwLinePortion const*const pLast = rInf.GetLast();
+        assert(pLast);
+        pPor->Height( pLast->Height() );
+        pPor->SetAscent( pLast->GetAscent() );
+    }
     else
     {
         const SwLinePortion *pLast = rInf.GetLast();
@@ -1008,6 +1025,7 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf )
     return pPor;
 }
 
+// first portions have no length
 SwLinePortion *SwTextFormatter::WhichFirstPortion(SwTextFormatInfo &rInf)
 {
     SwLinePortion *pPor = nullptr;
@@ -1140,6 +1158,39 @@ SwLinePortion *SwTextFormatter::WhichFirstPortion(SwTextFormatInfo &rInf)
             pPor = TryNewNoLengthPortion(rInf);
         }
 
+    // 12. bookmarks
+    // check this *last* so that BuildMultiPortion() can find it!
+    if (!pPor && rInf.CheckCurrentPosBookmark())
+    {
+        auto const bookmark(m_pScriptInfo->GetBookmark(rInf.GetIdx()));
+        if (static_cast<bool>(bookmark))
+        {
+            sal_Unicode mark;
+            if ((bookmark & (SwScriptInfo::MarkKind::Start|SwScriptInfo::MarkKind::End))
+                        == (SwScriptInfo::MarkKind::Start|SwScriptInfo::MarkKind::End))
+            {
+                //mark = u'\u2336'; // not in OpenSymbol :(
+                mark = '|';
+                // hmm ... paint U+2345 over U+2346 should be same width?
+                // and U+237F // or U+2E20/U+2E21
+            }
+            else if (bookmark & SwScriptInfo::MarkKind::Start)
+            {
+                mark = '[';
+            }
+            else if (bookmark & SwScriptInfo::MarkKind::End)
+            {
+                mark = ']';
+            }
+            else
+            {
+                assert(bookmark & SwScriptInfo::MarkKind::Point);
+                mark = '|';
+            }
+            pPor = new SwBookmarkPortion(rInf.GetLast(), mark);
+        }
+    }
+
     return pPor;
 }
 
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index bf9d78c4228a..ce2b16c74323 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1654,6 +1654,23 @@ TextFrameIndex SwScriptInfo::NextBookmark(TextFrameIndex const nPos) const
     return TextFrameIndex(COMPLETE_STRING);
 }
 
+auto SwScriptInfo::GetBookmark(TextFrameIndex const nPos) const -> MarkKind
+{
+    MarkKind ret{0};
+    for (auto const& it : m_Bookmarks)
+    {
+        if (nPos == it.first)
+        {
+            ret |= it.second;
+        }
+        else if (nPos < it.first)
+        {
+            break;
+        }
+    }
+    return ret;
+}
+
 // Takes a string and replaced the hidden ranges with cChar.
 sal_Int32 SwScriptInfo::MaskHiddenRanges( const SwTextNode& rNode, OUStringBuffer & rText,
                                        const sal_Int32 nStt, const sal_Int32 nEnd,
diff --git a/sw/source/core/text/porlin.cxx b/sw/source/core/text/porlin.cxx
index a7a6a09457ea..86e6e5547c2f 100644
--- a/sw/source/core/text/porlin.cxx
+++ b/sw/source/core/text/porlin.cxx
@@ -105,7 +105,9 @@ void SwLinePortion::PrePaint( const SwTextPaintInfo& rInf,
                   1800 :
                   rInf.GetFont()->GetOrientation( rInf.GetTextFrame()->IsVertical() );
 
-    if (nLastWidth > nHalfView)
+    // pLast == this *only* for the 1st portion in the line so nLastWidth is 0;
+    // allow this too, will paint outside the frame but might look better...
+    if (nLastWidth > nHalfView || pLast == this)
     {
         switch (nDir)
         {
diff --git a/sw/source/core/text/porlin.hxx b/sw/source/core/text/porlin.hxx
index 729740024890..0a9ac2fac875 100644
--- a/sw/source/core/text/porlin.hxx
+++ b/sw/source/core/text/porlin.hxx
@@ -135,7 +135,7 @@ public:
     bool IsArrowPortion() const { return nWhichPor == POR_ARROW; }
     bool IsMultiPortion() const { return nWhichPor == POR_MULTI; }
     bool IsNumberPortion() const { return nWhichPor == POR_NUMBER; } // #i23726#
-    bool IsControlCharPortion() const { return nWhichPor == POR_CONTROLCHAR; }
+    bool IsControlCharPortion() const { return nWhichPor == POR_CONTROLCHAR || nWhichPor == POR_BOOKMARK; }
 
     // Positioning
     SwLinePortion *FindPrevPortion( const SwLinePortion *pRoot );
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index 78423e440a6f..5ff1fceb5a92 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -43,6 +43,7 @@
 #include "porfld.hxx"
 #include "porglue.hxx"
 #include <breakit.hxx>
+#include "porrst.hxx"
 #include <pagefrm.hxx>
 #include <rowfrm.hxx>
 #include <pagedesc.hxx>
@@ -2026,6 +2027,19 @@ bool SwTextFormatter::BuildMultiPortion( SwTextFormatInfo &rInf,
         aInf.SetNumDone( rInf.IsNumDone() );
         aInf.SetFootnoteDone( rInf.IsFootnoteDone() );
 
+        // if there's a bookmark at the start of the MultiPortion, it will be
+        // painted with the rotation etc. of the MultiPortion; move it *inside*
+        // so it gets positioned correctly; currently there's no other portion
+        // inserted between the end of WhichFirstPortion() and
+        // BuildMultiPortion()
+        if (rInf.GetLast()->GetWhichPor() == POR_BOOKMARK)
+        {
+            auto const pBookmark(static_cast<SwBookmarkPortion*>(rInf.GetLast()));
+            rInf.SetLast(pBookmark->Unchain());
+            assert(m_pCurr->GetPortion() == nullptr);
+            m_pCurr->SetPortion(pBookmark);
+        }
+
         if( pFirstRest )
         {
             OSL_ENSURE( pFirstRest->InFieldGrp(), "BuildMulti: Fieldrest expected");
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index d52e6ef2fb5e..067ae9d477f0 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -309,6 +309,17 @@ bool SwTextFrame::FormatEmpty()
             aTextFly.IsOn() && aTextFly.IsAnyObj( aRect ) )
         return false;
 
+    // only need to check one node because of early return on GetMerged()
+    for (SwIndex const* pIndex = GetTextNodeFirst()->GetFirstIndex();
+         pIndex; pIndex = pIndex->GetNext())
+    {
+        sw::mark::IMark const*const pMark = pIndex->GetMark();
+        if (dynamic_cast<const sw::mark::IBookmark*>(pMark) != nullptr)
+        {   // need bookmark portions!
+            return false;
+        }
+    }
+
     SwTwips nHeight = EmptyHeight();
 
     if (aSet.GetParaGrid().GetValue() &&
@@ -484,35 +495,92 @@ bool SwHiddenTextPortion::Format( SwTextFormatInfo &rInf )
     return false;
 };
 
+bool SwControlCharPortion::DoPaint(SwTextPaintInfo const&,
+        OUString & rOutString, SwFont & rTmpFont, int &) const
+{
+    if (mcChar == CHAR_ZWNBSP || !SwViewOption::IsFieldShadings())
+    {
+        return false;
+    }
+
+    switch (mcChar)
+    {
+        case CHAR_ZWSP:
+            rOutString = "/"; break;
+//      case CHAR_LRM :
+//          rText = sal_Unicode(0x2514); break;
+//      case CHAR_RLM :
+//          rText = sal_Unicode(0x2518); break;
+        default:
+            assert(false);
+            break;
+    }
+
+    rTmpFont.SetEscapement( CHAR_ZWSP == mcChar ? DFLT_ESC_AUTO_SUB : -25 );
+    const sal_uInt16 nProp = 40;
+    rTmpFont.SetProportion( nProp );  // a smaller font
+
+    return true;
+}
+
+bool SwBookmarkPortion::DoPaint(SwTextPaintInfo const& rInf,
+        OUString & rOutString, SwFont & rTmpFont, int & rDeltaY) const
+{
+    if (!rInf.GetOpt().IsViewMetaChars())
+    {
+        return false;
+    }
+
+    rOutString = OUStringLiteral1(mcChar);
+
+    // init font: we want OpenSymbol to ensure it doesn't look too crazy;
+    // thin and a bit higher than the surrounding text
+    auto const nOrigAscent(rTmpFont.GetAscent(rInf.GetVsh(), *rInf.GetOut()));
+    rTmpFont.SetName("OpenSymbol", rTmpFont.GetActual());
+    Size size(rTmpFont.GetSize(rTmpFont.GetActual()));
+    // use also the external leading (line gap) of the portion, but don't use
+    // 100% of it because i can't figure out how to baseline align that
+    auto const nFactor = (Height() * 95) / size.Height();
+    rTmpFont.SetProportion(nFactor);
+    rTmpFont.SetWeight(WEIGHT_THIN, rTmpFont.GetActual());
+    rTmpFont.SetColor(NON_PRINTING_CHARACTER_COLOR);
+    // reset these to default...
+    rTmpFont.SetAlign(ALIGN_BASELINE);
+    rTmpFont.SetUnderline(LINESTYLE_NONE);
+    rTmpFont.SetOverline(LINESTYLE_NONE);
+    rTmpFont.SetStrikeout(STRIKEOUT_NONE);
+    rTmpFont.SetOutline(false);
+    rTmpFont.SetShadow(false);
+    rTmpFont.SetTransparent(false);
+    rTmpFont.SetEmphasisMark(FontEmphasisMark::NONE);
+    rTmpFont.SetEscapement(0);
+    rTmpFont.SetPitch(PITCH_DONTKNOW, rTmpFont.GetActual());
+    rTmpFont.SetRelief(FontRelief::NONE);
+
+    // adjust Y position to account for different baselines of the fonts
+    auto const nOSAscent(rTmpFont.GetAscent(rInf.GetVsh(), *rInf.GetOut()));
+    rDeltaY = nOSAscent - nOrigAscent;
+
+    return true;
+}
+
 void SwControlCharPortion::Paint( const SwTextPaintInfo &rInf ) const
 {
     if ( Width() )  // is only set during prepaint mode
     {
-        rInf.DrawViewOpt( *this, POR_CONTROLCHAR );
+        rInf.DrawViewOpt(*this, GetWhichPor());
 
-        if ( !rInf.GetOpt().IsPagePreview() &&
-             !rInf.GetOpt().IsReadonly() &&
-              SwViewOption::IsFieldShadings() &&
-              CHAR_ZWNBSP != mcChar )
+        int deltaY(0);
+        SwFont aTmpFont( *rInf.GetFont() );
+        OUString aOutString;
+
+        if (rInf.OnWin()
+            && !rInf.GetOpt().IsPagePreview()
+            && !rInf.GetOpt().IsReadonly()
+            && DoPaint(rInf, aOutString, aTmpFont, deltaY))
         {
-            SwFont aTmpFont( *rInf.GetFont() );
-            aTmpFont.SetEscapement( CHAR_ZWSP == mcChar ? DFLT_ESC_AUTO_SUB : -25 );
-            const sal_uInt16 nProp = 40;
-            aTmpFont.SetProportion( nProp );  // a smaller font
             SwFontSave aFontSave( rInf, &aTmpFont );
 
-            OUString aOutString;
-
-            switch ( mcChar )
-            {
-                case CHAR_ZWSP :
-                    aOutString = "/"; break;
-//                case CHAR_LRM :
-//                    rText = sal_Unicode(0x2514); break;
-//                case CHAR_RLM :
-//                    rText = sal_Unicode(0x2518); break;
-            }
-
             if ( !mnHalfCharWidth )
                 mnHalfCharWidth = rInf.GetTextSize( aOutString ).Width() / 2;
 
@@ -523,12 +591,15 @@ void SwControlCharPortion::Paint( const SwTextPaintInfo &rInf ) const
             {
                 case 0:
                     aNewPos.AdjustX(deltaX);
+                    aNewPos.AdjustY(deltaY);
                     break;
                 case 900:
                     aNewPos.AdjustY(-deltaX);
+                    aNewPos.AdjustX(deltaY);
                     break;
                 case 2700:
                     aNewPos.AdjustY(deltaX);
+                    aNewPos.AdjustX(-deltaY);
                     break;
                 default:
                     assert(false);
@@ -561,4 +632,13 @@ sal_uInt16 SwControlCharPortion::GetViewWidth( const SwTextSizeInfo& rInf ) cons
     return mnViewWidth;
 }
 
+SwLinePortion * SwBookmarkPortion::Unchain()
+{
+    assert(!m_pPrevious || m_pPrevious->GetPortion() == this);
+    m_pPrevious->SetPortion(nullptr);
+    auto const pTmp(m_pPrevious);
+    m_pPrevious = nullptr;
+    return pTmp;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porrst.hxx b/sw/source/core/text/porrst.hxx
index cadd8f871b43..6b930d4f0262 100644
--- a/sw/source/core/text/porrst.hxx
+++ b/sw/source/core/text/porrst.hxx
@@ -18,9 +18,12 @@
  */
 #ifndef INCLUDED_SW_SOURCE_CORE_TEXT_PORRST_HXX
 #define INCLUDED_SW_SOURCE_CORE_TEXT_PORRST_HXX
+
 #include "porlay.hxx"
 #include "porexp.hxx"
 
+class SwFont;
+
 #define LINE_BREAK_WIDTH        150
 #define SPECIAL_FONT_HEIGHT     200
 
@@ -122,7 +125,8 @@ class SwControlCharPortion : public SwLinePortion
 private:
     mutable sal_uInt16 mnViewWidth;            // used to cache a calculated value
     mutable sal_uInt16 mnHalfCharWidth;        // used to cache a calculated value
-    sal_Unicode mcChar;
+protected:
+    sal_Unicode const mcChar;
 
 public:
 
@@ -132,11 +136,35 @@ public:
         SetWhichPor( POR_CONTROLCHAR ); SetLen( TextFrameIndex(1) );
     }
 
+    virtual bool DoPaint(SwTextPaintInfo const& rInf,
+        OUString & rOutString, SwFont & rTmpFont, int & rDeltaY) const;
     virtual void Paint( const SwTextPaintInfo &rInf ) const override;
     virtual bool Format( SwTextFormatInfo &rInf ) override;
     virtual sal_uInt16 GetViewWidth( const SwTextSizeInfo& rInf ) const override;
 };
 
+/// for showing bookmark starts and ends; note that in contrast to
+/// SwControlCharPortion these do not have a character in the text.
+class SwBookmarkPortion : public SwControlCharPortion
+{
+private:
+    SwLinePortion * m_pPrevious;
+
+public:
+    explicit SwBookmarkPortion(SwLinePortion *const pPrevious, sal_Unicode const cChar)
+        : SwControlCharPortion(cChar)
+        , m_pPrevious(pPrevious)
+    {
+        SetWhichPor(POR_BOOKMARK);
+        SetLen(TextFrameIndex(0));
+    }
+
+    virtual bool DoPaint(SwTextPaintInfo const& rInf,
+        OUString & rOutString, SwFont & rTmpFont, int & rDeltaY) const override;
+    virtual SwLinePortion * Compress() override { return this; }
+    SwLinePortion * Unchain();
+};
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx
index d29d7abdbd7a..7c4ac4b4b034 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -48,6 +48,7 @@ class XmlPortionDumper:public SwPortionHandler
             case POR_MULTI: return "POR_MULTI";
             case POR_HIDDEN_TXT: return "POR_HIDDEN_TXT";
             case POR_CONTROLCHAR: return "POR_CONTROLCHAR";
+            case POR_BOOKMARK: return "POR_BOOKMARK";
 
             case POR_TXT: return "POR_TXT";
             case POR_LAY: return "POR_LAY";
commit dcadfae807de0ef81183d4e95126aa140cb707e2
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Jan 29 18:52:07 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 18:00:12 2020 +0200

    sw: fix rotation bugs in SwLinePortion::PrePaint()
    
    The sign was flipped for the 90° case, resulting in painting too far
    up the page, ever since this was added in
    293ed704cf15107049578c2e6e5ed00dcac2d4fb.
    
    In SwControlCharPortion::Paint() rotation wasn't handled at all.
    
    Change-Id: I83a7eef8b2f6126e070d8c48f75378b6cf6d50e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87707
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 8029179e35fcda5867769d4ca6f7ee32bca3e9bc)

diff --git a/sw/source/core/text/porlin.cxx b/sw/source/core/text/porlin.cxx
index 864edd56115c..a7a6a09457ea 100644
--- a/sw/source/core/text/porlin.cxx
+++ b/sw/source/core/text/porlin.cxx
@@ -116,12 +116,12 @@ void SwLinePortion::PrePaint( const SwTextPaintInfo& rInf,
             break;
         case 900:
             nPos = sal_uInt16( rInf.Y() );
-            nPos -= nLastWidth + nHalfView;
+            nPos -= nLastWidth - nHalfView;
             aInf.Y( nPos );
             break;
         case 1800:
             nPos = sal_uInt16( rInf.X() );
-            nPos -= nLastWidth + nHalfView;
+            nPos -= nLastWidth - nHalfView;
             aInf.X( nPos );
             break;
         case 2700:
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index 24778b6ec9d6..d52e6ef2fb5e 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -518,7 +518,22 @@ void SwControlCharPortion::Paint( const SwTextPaintInfo &rInf ) const
 
             Point aOldPos = rInf.GetPos();
             Point aNewPos( aOldPos );
-            aNewPos.setX( aNewPos.X() + ( Width() / 2 ) - mnHalfCharWidth );
+            auto const deltaX((Width() / 2) - mnHalfCharWidth);
+            switch (rInf.GetFont()->GetOrientation(rInf.GetTextFrame()->IsVertical()))
+            {
+                case 0:
+                    aNewPos.AdjustX(deltaX);
+                    break;
+                case 900:
+                    aNewPos.AdjustY(-deltaX);
+                    break;
+                case 2700:
+                    aNewPos.AdjustY(deltaX);
+                    break;
+                default:
+                    assert(false);
+                    break;
+            }
             const_cast< SwTextPaintInfo& >( rInf ).SetPos( aNewPos );
 
             rInf.DrawText( aOutString, *this );
commit fc47ce07c457f6fd252aa768582a902e99222e74
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Jan 28 16:35:03 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 17:59:52 2020 +0200

    sw: reformat bit of SwLinePortion::PrePaint()
    
    Change-Id: Id088e3f73e6bda3c6b11d421a52c59c67446f8a2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87706
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit ac443862c6b9599ae5776767c4a169c37e47477e)

diff --git a/sw/source/core/text/porlin.cxx b/sw/source/core/text/porlin.cxx
index ca4080becbac..864edd56115c 100644
--- a/sw/source/core/text/porlin.cxx
+++ b/sw/source/core/text/porlin.cxx
@@ -105,32 +105,31 @@ void SwLinePortion::PrePaint( const SwTextPaintInfo& rInf,
                   1800 :
                   rInf.GetFont()->GetOrientation( rInf.GetTextFrame()->IsVertical() );
 
-    switch ( nDir )
+    if (nLastWidth > nHalfView)
     {
-    case 0 :
-        nPos = sal_uInt16( rInf.X() );
-        if( nLastWidth > nHalfView )
+        switch (nDir)
+        {
+        case 0:
+            nPos = sal_uInt16( rInf.X() );
             nPos += nLastWidth - nHalfView;
-        aInf.X( nPos );
-        break;
-    case 900 :
-        nPos = sal_uInt16( rInf.Y() );
-        if( nLastWidth > nHalfView )
+            aInf.X( nPos );
+            break;
+        case 900:
+            nPos = sal_uInt16( rInf.Y() );
             nPos -= nLastWidth + nHalfView;
-        aInf.Y( nPos );
-        break;
-    case 1800 :
-        nPos = sal_uInt16( rInf.X() );
-        if( nLastWidth > nHalfView )
+            aInf.Y( nPos );
+            break;
+        case 1800:
+            nPos = sal_uInt16( rInf.X() );
             nPos -= nLastWidth + nHalfView;
-        aInf.X( nPos );
-        break;
-    case 2700 :
-        nPos = sal_uInt16( rInf.Y() );
-        if( nLastWidth > nHalfView )
+            aInf.X( nPos );
+            break;
+        case 2700:
+            nPos = sal_uInt16( rInf.Y() );
             nPos += nLastWidth - nHalfView;
-        aInf.Y( nPos );
-        break;
+            aInf.Y( nPos );
+            break;
+        }
     }
 
     SwLinePortion *pThis = const_cast<SwLinePortion*>(this);
commit 456e3ba435be284a527c3452f0b5eef71c48a09d
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Thu Jan 23 18:36:40 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 17:57:17 2020 +0200

    tdf#45589 sw: split text portions at bookmarks
    
    Always create the portion, not just when the IsViewMetaChars is active.
    
    This has the advantage that nothing has to be invalidated when toggling,
    and the disadvantage that kerning at bookmark positions will never
    happen.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87363
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 2817f07fdd942cea6574043971534bf089b527ce)
    
    Change-Id: I78943f337eef5c64cff33f6df6ff1a10acb1b8bc

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index e1022370c76b..124709786e9e 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -181,6 +181,7 @@ public:
         assert(nCnt < m_HiddenChg.size());
         return m_HiddenChg[ nCnt ];
     }
+    TextFrameIndex NextBookmark(TextFrameIndex nPos) const;
     static void CalcHiddenRanges(const SwTextNode& rNode,
             MultiSelection& rHiddenMulti,
             std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 10aa3be6ff72..f3fca32c60c7 100755
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -958,6 +958,10 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf )
     const TextFrameIndex nNextDir = m_pScriptInfo->NextDirChg(rInf.GetIdx());
     nNextChg = std::min( nNextChg, nNextDir );
 
+    // bookmarks
+    const TextFrameIndex nNextBookmark = m_pScriptInfo->NextBookmark(rInf.GetIdx());
+    nNextChg = std::min(nNextChg, nNextBookmark);
+
     // Turbo boost:
     // We assume that font characters are not larger than twice
     // as wide as height.
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 630ff74a0176..bf9d78c4228a 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1642,6 +1642,18 @@ sal_uInt8 SwScriptInfo::DirType(const TextFrameIndex nPos) const
     return 0;
 }
 
+TextFrameIndex SwScriptInfo::NextBookmark(TextFrameIndex const nPos) const
+{
+    for (auto const& it : m_Bookmarks)
+    {
+        if (nPos < it.first)
+        {
+            return it.first;
+        }
+    }
+    return TextFrameIndex(COMPLETE_STRING);
+}
+
 // Takes a string and replaced the hidden ranges with cChar.
 sal_Int32 SwScriptInfo::MaskHiddenRanges( const SwTextNode& rNode, OUStringBuffer & rText,
                                        const sal_Int32 nStt, const sal_Int32 nEnd,
commit b93b2b974e003a2e6b8cf9852b7e7e4fb126fff0
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Wed Jan 22 15:18:19 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 17:50:10 2020 +0200

    tdf#45589 sw: add bookmarks to SwScriptInfo
    
    Add a list of bookmark positions in the text frame to SwScriptInfo.
    Initialising this turned out to be more complicated than expected.
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87202
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit 46e04a712e97f9095ef4da7f0e52f50cf2bfbb32)
    
    Change-Id: I1738186b057b0eece80177097a03826365107589

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index e3d64b1627f3..e1022370c76b 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -34,6 +34,7 @@ class MultiSelection;
 typedef std::vector< sal_Int32 > PositionList;
 enum class SwFontScript;
 namespace sw { struct MergedPara; }
+namespace sw::mark { class IBookmark; }
 
 #define SPACING_PRECISION_FACTOR 100
 
@@ -42,6 +43,7 @@ class SwScriptInfo
 {
 public:
     enum CompType { KANA, SPECIAL_LEFT, SPECIAL_RIGHT, NONE, SPECIAL_MIDDLE};
+    enum class MarkKind { Start, End, Point };
 
 private:
     //! Records a single change in script type.
@@ -68,6 +70,7 @@ private:
     std::deque<TextFrameIndex> m_NoKashidaLine;
     std::deque<TextFrameIndex> m_NoKashidaLineEnd;
     std::deque<TextFrameIndex> m_HiddenChg;
+    std::vector<std::pair<TextFrameIndex, MarkKind>> m_Bookmarks;
     //! Records a single change in compression.
     struct CompressionChangeInfo
     {
@@ -178,8 +181,12 @@ public:
         assert(nCnt < m_HiddenChg.size());
         return m_HiddenChg[ nCnt ];
     }
-    static void CalcHiddenRanges(const SwTextNode& rNode, MultiSelection& rHiddenMulti);
-    static void selectHiddenTextProperty(const SwTextNode& rNode, MultiSelection &rHiddenMulti);
+    static void CalcHiddenRanges(const SwTextNode& rNode,
+            MultiSelection& rHiddenMulti,
+            std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
+    static void selectHiddenTextProperty(const SwTextNode& rNode,
+            MultiSelection &rHiddenMulti,
+            std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> * pBookmarks);
     static void selectRedLineDeleted(const SwTextNode& rNode, MultiSelection &rHiddenMulti, bool bSelect=true);
 
     // "high" level operations, nPos refers to string position
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 11e78a915433..630ff74a0176 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -35,6 +35,9 @@
 #include <com/sun/star/i18n/WordType.hpp>
 #include <com/sun/star/i18n/XBreakIterator.hpp>
 #include <paratr.hxx>
+#include <sal/log.hxx>
+#include <boost/optional.hpp>
+#include <IMark.hxx>
 #include <editeng/adjustitem.hxx>
 #include <editeng/scripttypeitem.hxx>
 #include <editeng/charhiddenitem.hxx>
@@ -706,6 +709,173 @@ SwFontScript SwScriptInfo::WhichFont(sal_Int32 nIdx, OUString const& rText)
     return lcl_ScriptToFont(nScript);
 }
 
+static void InitBookmarks(
+    boost::optional<std::vector<sw::Extent>::const_iterator> oPrevIter,
+    std::vector<sw::Extent>::const_iterator iter,
+    std::vector<sw::Extent>::const_iterator const end,
+    TextFrameIndex nOffset,
+    std::vector<std::pair<sw::mark::IBookmark const*, SwScriptInfo::MarkKind>> & rBookmarks,
+    std::vector<std::pair<TextFrameIndex, SwScriptInfo::MarkKind>> & o_rBookmarks)
+{
+    SwTextNode const*const pNode(iter->pNode);
+    for (auto const& it : rBookmarks)
+    {
+        assert(iter->pNode == pNode || pNode->GetIndex() < iter->pNode->GetIndex());
+        assert(!oPrevIter || (*oPrevIter)->pNode->GetIndex() <= pNode->GetIndex());
+        switch (it.second)
+        {
+            case SwScriptInfo::MarkKind::Start:
+            {
+                // SwUndoSaveContent::DelContentIndex() is rather messy but
+                // apparently bookmarks "on the edge" are deleted if
+                // * point: equals start-of-selection (not end-of-selection)
+                // * expanded: one position equals edge of selection
+                //             and other does not (is inside)
+                // interesting case: if end[/start] of the mark is on the
+                // start of first[/end of last] extent, and the other one
+                // is outside this merged paragraph, is it deleted or not?
+                // assume "no" because the line break it contains isn't deleted.
+                SwPosition const& rStart(it.first->GetMarkStart());
+                SwPosition const& rEnd(it.first->GetMarkEnd());
+                assert(&rStart.nNode.GetNode() == pNode);
+                while (iter != end)
+                {
+                    if (&rStart.nNode.GetNode() != iter->pNode // iter moved to next node
+                        || rStart.nContent.GetIndex() < iter->nStart)
+                    {
+                        if (rEnd.nNode.GetIndex() < iter->pNode->GetIndex()
+                            || (&rEnd.nNode.GetNode() == iter->pNode && rEnd.nContent.GetIndex() <= iter->nStart))
+                        {
+                            break; // deleted - skip it
+                        }
+                        else
+                        {
+                            o_rBookmarks.emplace_back(nOffset, it.second);
+                            break;
+                        }
+                    }
+                    else if (rStart.nContent.GetIndex() <= iter->nEnd)
+                    {
+                        auto const iterNext(iter + 1);
+                        if (rStart.nContent.GetIndex() == iter->nEnd
+                            && (iterNext == end
+                                ?   &rEnd.nNode.GetNode() == iter->pNode
+                                :  (rEnd.nNode.GetIndex() < iterNext->pNode->GetIndex()
+                                    || (&rEnd.nNode.GetNode() == iterNext->pNode && rEnd.nContent.GetIndex() < iterNext->nStart))))
+                        {
+                            break; // deleted - skip it
+                        }
+                        else
+                        {
+                            o_rBookmarks.emplace_back(
+                                nOffset + TextFrameIndex(rStart.nContent.GetIndex() - iter->nStart),
+                                it.second);
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        nOffset += TextFrameIndex(iter->nEnd - iter->nStart);
+                        oPrevIter = iter;
+                        ++iter; // bookmarks are sorted...
+                    }
+                }
+                if (iter == end)
+                {
+                    if (pNode->GetIndex() < rEnd.nNode.GetIndex()) // pNode is last node of merged
+                    {
+                        break; // deleted - skip it
+                    }
+                    else
+                    {
+                        o_rBookmarks.emplace_back(nOffset, it.second);
+                    }
+                }
+                break;
+            }
+            case SwScriptInfo::MarkKind::End:
+            {
+                SwPosition const& rEnd(it.first->GetMarkEnd());
+                assert(&rEnd.nNode.GetNode() == pNode);
+                while (true)
+                {
+                    if (iter == end
+                        || &rEnd.nNode.GetNode() != iter->pNode // iter moved to next node
+                        || rEnd.nContent.GetIndex() <= iter->nStart)
+                    {
+                        SwPosition const& rStart(it.first->GetMarkStart());
+                        // oPrevIter may point to pNode or a preceding node
+                        if (oPrevIter
+                            ? ((*oPrevIter)->pNode->GetIndex() < rStart.nNode.GetIndex()
+                                || ((*oPrevIter)->pNode == &rStart.nNode.GetNode()
+                                    && ((iter != end && &rEnd.nNode.GetNode() == iter->pNode && rEnd.nContent.GetIndex() == iter->nStart)
+                                        ? (*oPrevIter)->nEnd < rStart.nContent.GetIndex()
+                                        : (*oPrevIter)->nEnd <= rStart.nContent.GetIndex())))
+                            : rStart.nNode == rEnd.nNode)
+                        {
+                            break; // deleted - skip it
+                        }
+                        else
+                        {
+                            o_rBookmarks.emplace_back(nOffset, it.second);
+                            break;
+                        }
+                    }
+                    else if (rEnd.nContent.GetIndex() <= iter->nEnd)
+                    {
+                        o_rBookmarks.emplace_back(
+                            nOffset + TextFrameIndex(rEnd.nContent.GetIndex() - iter->nStart),
+                            it.second);
+                        break;
+                    }
+                    else
+                    {
+                        nOffset += TextFrameIndex(iter->nEnd - iter->nStart);
+                        oPrevIter = iter;
+                        ++iter;
+                    }
+                }
+                break;
+            }
+            case SwScriptInfo::MarkKind::Point:
+            {
+                SwPosition const& rPos(it.first->GetMarkPos());
+                assert(&rPos.nNode.GetNode() == pNode);
+                while (iter != end)
+                {
+                    if (&rPos.nNode.GetNode() != iter->pNode // iter moved to next node
+                        || rPos.nContent.GetIndex() < iter->nStart)
+                    {
+                        break; // deleted - skip it
+                    }
+                    else if (rPos.nContent.GetIndex() <= iter->nEnd)
+                    {
+                        if (rPos.nContent.GetIndex() == iter->nEnd
+                            && rPos.nContent.GetIndex() != iter->pNode->Len())
+                        {
+                            break; // deleted - skip it
+                        }
+                        else
+                        {
+                            o_rBookmarks.emplace_back(
+                                nOffset + TextFrameIndex(rPos.nContent.GetIndex() - iter->nStart),
+                                it.second);
+                        }
+                        break;
+                    }
+                    else
+                    {
+                        nOffset += TextFrameIndex(iter->nEnd - iter->nStart);
+                        oPrevIter = iter;
+                        ++iter;
+                    }
+                }
+                break;
+            }
+        }
+    }
+}
+
 // searches for script changes in rText and stores them
 void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
         sw::MergedPara const*const pMerged)
@@ -722,12 +892,15 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
 
     // HIDDEN TEXT INFORMATION
 
+    m_Bookmarks.clear();
     m_HiddenChg.clear();
     if (pMerged)
     {
         SwTextNode const* pNode(nullptr);
         TextFrameIndex nOffset(0);
-        for (auto iter = pMerged->extents.begin(); iter != pMerged->extents.end(); ++iter)
+        boost::optional<std::vector<sw::Extent>::const_iterator> oPrevIter;
+        for (auto iter = pMerged->extents.begin(); iter != pMerged->extents.end();
+             oPrevIter = iter, ++iter)
         {
             if (iter->pNode == pNode)
             {
@@ -737,7 +910,10 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
             pNode = iter->pNode;
             Range aRange( 0, pNode->Len() > 0 ? pNode->Len() - 1 : 0 );
             MultiSelection aHiddenMulti( aRange );
-            CalcHiddenRanges( *pNode, aHiddenMulti );
+            std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> bookmarks;
+            CalcHiddenRanges(*pNode, aHiddenMulti, &bookmarks);
+
+            InitBookmarks(oPrevIter, iter, pMerged->extents.end(), nOffset, bookmarks, m_Bookmarks);
 
             for (sal_Int32 i = 0; i < aHiddenMulti.GetRangeCount(); ++i)
             {
@@ -782,7 +958,24 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
     {
         Range aRange( 0, !rText.isEmpty() ? rText.getLength() - 1 : 0 );
         MultiSelection aHiddenMulti( aRange );
-        CalcHiddenRanges( rNode, aHiddenMulti );
+        std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> bookmarks;
+        CalcHiddenRanges(rNode, aHiddenMulti, &bookmarks);
+
+        for (auto const& it : bookmarks)
+        {
+            switch (it.second)
+            {
+                case MarkKind::Start:
+                    m_Bookmarks.emplace_back(TextFrameIndex(it.first->GetMarkStart().nContent.GetIndex()), it.second);
+                    break;
+                case MarkKind::End:
+                    m_Bookmarks.emplace_back(TextFrameIndex(it.first->GetMarkEnd().nContent.GetIndex()), it.second);
+                    break;
+                case MarkKind::Point:
+                    m_Bookmarks.emplace_back(TextFrameIndex(it.first->GetMarkPos().nContent.GetIndex()), it.second);
+                    break;
+            }
+        }
 
         for (sal_Int32 i = 0; i < aHiddenMulti.GetRangeCount(); ++i)
         {
@@ -1559,7 +1752,7 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( const SwTextNode& rNode, sal_Int32 nP
                             ? rNode.GetText().getLength() - 1
                             : 0);
         MultiSelection aHiddenMulti( aRange );
-        SwScriptInfo::CalcHiddenRanges( rNode, aHiddenMulti );
+        SwScriptInfo::CalcHiddenRanges(rNode, aHiddenMulti, nullptr);
         for( sal_Int32 i = 0; i < aHiddenMulti.GetRangeCount(); ++i )
         {
             const Range& rRange = aHiddenMulti.GetRange( i );
@@ -2219,7 +2412,9 @@ SwTwips SwTextFrame::HangingMargin() const
     return nRet;
 }
 
-void SwScriptInfo::selectHiddenTextProperty(const SwTextNode& rNode, MultiSelection &rHiddenMulti)
+void SwScriptInfo::selectHiddenTextProperty(const SwTextNode& rNode,
+    MultiSelection & rHiddenMulti,
+    std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> *const pBookmarks)
 {
     assert((rNode.GetText().isEmpty() && rHiddenMulti.GetTotalRange().Len() == 1)
         || (rNode.GetText().getLength() == rHiddenMulti.GetTotalRange().Len()));
@@ -2251,6 +2446,28 @@ void SwScriptInfo::selectHiddenTextProperty(const SwTextNode& rNode, MultiSelect
             }
         }
     }
+
+    for (const SwIndex* pIndex = rNode.GetFirstIndex(); pIndex; pIndex = pIndex->GetNext())
+    {
+        const sw::mark::IMark* pMark = pIndex->GetMark();
+        const sw::mark::IBookmark* pBookmark = dynamic_cast<const sw::mark::IBookmark*>(pMark);
+        if (pBookmarks && pBookmark)
+        {
+            if (!pBookmark->IsExpanded())
+            {
+                pBookmarks->emplace_back(pBookmark, MarkKind::Point);
+            }
+            else if (pIndex == &pBookmark->GetMarkStart().nContent)
+            {
+                pBookmarks->emplace_back(pBookmark, MarkKind::Start);
+            }
+            else
+            {
+                assert(pIndex == &pBookmark->GetMarkEnd().nContent);
+                pBookmarks->emplace_back(pBookmark, MarkKind::End);
+            }
+        }
+    }
 }
 
 void SwScriptInfo::selectRedLineDeleted(const SwTextNode& rNode, MultiSelection &rHiddenMulti, bool bSelect)
@@ -2288,9 +2505,11 @@ void SwScriptInfo::selectRedLineDeleted(const SwTextNode& rNode, MultiSelection
 }
 
 // Returns a MultiSection indicating the hidden ranges.
-void SwScriptInfo::CalcHiddenRanges( const SwTextNode& rNode, MultiSelection& rHiddenMulti )
+void SwScriptInfo::CalcHiddenRanges( const SwTextNode& rNode,
+    MultiSelection & rHiddenMulti,
+    std::vector<std::pair<sw::mark::IBookmark const*, MarkKind>> *const pBookmarks)
 {
-    selectHiddenTextProperty(rNode, rHiddenMulti);
+    selectHiddenTextProperty(rNode, rHiddenMulti, pBookmarks);
 
     // If there are any hidden ranges in the current text node, we have
     // to unhide the redlining ranges:
diff --git a/sw/source/core/txtnode/modeltoviewhelper.cxx b/sw/source/core/txtnode/modeltoviewhelper.cxx
index e6f5b1885f56..91c70599754e 100644
--- a/sw/source/core/txtnode/modeltoviewhelper.cxx
+++ b/sw/source/core/txtnode/modeltoviewhelper.cxx
@@ -92,7 +92,7 @@ ModelToViewHelper::ModelToViewHelper(const SwTextNode &rNode, ExpandMode eMode)
     MultiSelection aHiddenMulti(aRange);
 
     if (eMode & ExpandMode::HideInvisible)
-        SwScriptInfo::selectHiddenTextProperty(rNode, aHiddenMulti);
+        SwScriptInfo::selectHiddenTextProperty(rNode, aHiddenMulti, nullptr);
 
     if (eMode & ExpandMode::HideDeletions)
         SwScriptInfo::selectRedLineDeleted(rNode, aHiddenMulti);
commit a0e1983427439031b3228187f61fe60f92520ae8
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Tue Jan 21 13:15:50 2020 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 17:29:53 2020 +0200

    tdf#45589 sw: invalidate on bookmark insertion/deletion
    
    Invalidate the text frames when a bookmark is inserted or deleted; also
    when MarkManager::repositionMark() changes the positions.
    
    The other calls of SetMarkPos()/SetOtherMarkPos() look like they're all
    from code that corrects positions after text insertions or deletions so
    no additional invalidate should be necessary there.
    
    It turns out that one WW8 document in sw_filters_test wants to insert
    a bookmark on a SwGrfNode; check for that in makeMark().
    
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87157
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit ef8427d12a63127a2eb867637699343d630545dd)
    
    Change-Id: I293e6da9042bea5992cb27091b9cff77e5c7961d

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 8ea7445ea676..91e480592b0e 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -26,6 +26,7 @@
 #include <doc.hxx>
 #include <ndtxt.hxx>
 #include <pam.hxx>
+#include <hints.hxx>
 #include <swserv.hxx>
 #include <sfx2/linkmgr.hxx>
 #include <swtypes.hxx>
@@ -143,6 +144,12 @@ namespace
 
         io_pDoc->GetIDocumentUndoRedo().EndUndo(SwUndoId::UI_REPLACE, nullptr);
     };
+
+    auto InvalidatePosition(SwPosition const& rPos) -> void
+    {
+        SwUpdateAttr const hint(rPos.nContent.GetIndex(), rPos.nContent.GetIndex(), 0);
+        rPos.nNode.GetNode().GetTextNode()->NotifyClients(nullptr, &hint);
+    }
 }
 
 namespace sw { namespace mark
@@ -244,6 +251,11 @@ namespace sw { namespace mark
     }
 
     // TODO: everything else uses MarkBase::GenerateNewName ?
+
+    auto MarkBase::InvalidateFrames() -> void
+    {
+    }
+
     NavigatorReminder::NavigatorReminder(const SwPaM& rPaM)
         : MarkBase(rPaM, "__NavigatorReminder__")
     { }
@@ -299,6 +311,7 @@ namespace sw { namespace mark
                     new SwUndoInsBookmark(*this));
         }
         io_pDoc->getIDocumentState().SetModified();
+        InvalidateFrames();
     }
 
     void Bookmark::DeregisterFromDoc(SwDoc* const io_pDoc)
@@ -311,6 +324,17 @@ namespace sw { namespace mark
                     new SwUndoDeleteBookmark(*this));
         }
         io_pDoc->getIDocumentState().SetModified();
+        InvalidateFrames();
+    }
+
+    // invalidate text frames in case it's hidden or Formatting Marks enabled
+    auto Bookmark::InvalidateFrames() -> void
+    {
+        InvalidatePosition(GetMarkPos());
+        if (IsExpanded())
+        {
+            InvalidatePosition(GetOtherMarkPos());
+        }
     }
 
     ::sfx2::IXmlIdRegistry& Bookmark::GetRegistry()
@@ -415,6 +439,8 @@ namespace sw { namespace mark
         if (eMode == sw::mark::InsertMode::New)
         {
             lcl_SetFieldMarks(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
+            // no need to invalidate text frames here, the insertion of the
+            // CH_TXT_ATR already invalidates
         }
         else
         {
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 77dfdd976c1b..0998c1c83644 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -395,6 +395,17 @@ namespace sw { namespace mark
         OSL_PRECOND(m_vAllMarks.size() < USHRT_MAX,
             "MarkManager::makeMark(..)"
             " - more than USHRT_MAX marks are not supported correctly");
+
+        if (   (!rPaM.GetPoint()->nNode.GetNode().IsTextNode()
+                    // huh, SwXTextRange puts one on table node?
+                && !rPaM.GetPoint()->nNode.GetNode().IsTableNode())
+            || (!rPaM.GetMark()->nNode.GetNode().IsTextNode()
+                && !rPaM.GetMark()->nNode.GetNode().IsTableNode()))
+        {
+            SAL_WARN("sw.core", "MarkManager::makeMark(..)"
+                " - refusing to create mark on non-textnode");
+            return nullptr;
+        }
         // There should only be one CrossRefBookmark per Textnode per Type
         if ((eType == MarkType::CROSSREF_NUMITEM_BOOKMARK || eType == MarkType::CROSSREF_HEADING_BOOKMARK)
             && (lcl_FindMarkAtPos(m_vBookmarks, *rPaM.Start(), eType) != m_vBookmarks.end()))
@@ -548,6 +559,8 @@ namespace sw { namespace mark
         if (!pMarkBase)
             return;
 
+        pMarkBase->InvalidateFrames();
+
         pMarkBase->SetMarkPos(*(rPaM.GetPoint()));
         if(rPaM.HasMark())
             pMarkBase->SetOtherMarkPos(*(rPaM.GetMark()));
@@ -557,6 +570,8 @@ namespace sw { namespace mark
         if(pMarkBase->GetMarkPos() != pMarkBase->GetMarkStart())
             pMarkBase->Swap();
 
+        pMarkBase->InvalidateFrames();
+
         sortMarks();
     }
 
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 4fa2ef87c772..5d9752501e2c 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -87,6 +87,8 @@ namespace sw {
             virtual void ClearOtherMarkPos()
                 { m_pPos2.reset(); }
 
+            virtual auto InvalidateFrames() -> void;
+
             virtual OUString ToString( ) const override;
             virtual void dumpAsXml(struct _xmlTextWriter* pWriter) const override;
 
@@ -167,6 +169,8 @@ namespace sw {
 
             virtual void DeregisterFromDoc(SwDoc* const io_pDoc) override;
 
+            virtual auto InvalidateFrames() -> void override;
+
             virtual const OUString& GetShortName() const override
                 { return m_sShortName; }
             virtual const vcl::KeyCode& GetKeyCode() const override
commit 3a1186a1896c4c898ea86fe936e9a555a26a7f14
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Wed Nov 27 10:28:52 2019 +0100
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 14:33:02 2020 +0200

    external/liblangtag: Avoid null pointer deref in lt_warning call
    
    Recent GCC 10 trunk warns (when LO is configured with --enable-optimized):
    
    > In file included from lt-script-db.c:24:
    > lt-script-db.c: In function ‘lt_script_db_parse.constprop’:
    > lt-messages.h:105:2: error: ‘%s’ directive argument is null [-Werror=format-overflow=]
    >   105 |  lt_message_printf(LT_MSG_WARNING, \
    >       |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >   106 |      LT_MSG_FLAG_NONE, \
    >       |      ~~~~~~~~~~~~~~~~~~~
    >   107 |      0,   \
    >       |      ~~~~~~
    >   108 |      __VA_ARGS__)
    >       |      ~~~~~~~~~~~~
    > lt-script-db.c:137:4: note: in expansion of macro ‘lt_warning’
    >   137 |    lt_warning("No subtag node: description = '%s'",
    >       |    ^~~~~~~~~~
    > lt-script-db.c:137:47: note: format string is defined here
    >   137 |    lt_warning("No subtag node: description = '%s'",
    >       |                                               ^~
    
    Change-Id: I2924f7aab84f4f2640f277ee5c2689753627ae78
    Reviewed-on: https://gerrit.libreoffice.org/83869
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
    (cherry picked from commit 047e8ae5d189f030d565b13f97a4d6a45b00e6be)

diff --git a/external/liblangtag/UnpackedTarball_liblangtag.mk b/external/liblangtag/UnpackedTarball_liblangtag.mk
index cd52b169fa57..66b8051782d0 100644
--- a/external/liblangtag/UnpackedTarball_liblangtag.mk
+++ b/external/liblangtag/UnpackedTarball_liblangtag.mk
@@ -17,6 +17,8 @@ $(eval $(call gb_UnpackedTarball_set_pre_action,liblangtag,\
 
 $(eval $(call gb_UnpackedTarball_update_autoconf_configs,liblangtag))
 
+$(eval $(call gb_UnpackedTarball_set_patchlevel,liblangtag,0))
+
 ifneq ($(OS),MACOSX)
 ifneq ($(OS),WNT)
 $(eval $(call gb_UnpackedTarball_add_patches,liblangtag,\
@@ -29,6 +31,7 @@ $(eval $(call gb_UnpackedTarball_add_patches,liblangtag, \
 	$(if $(SYSTEM_LIBXML),,external/liblangtag/langtag-libtool-rpath.patch.0) \
     external/liblangtag/clang-cl.patch.0 \
     external/liblangtag/langtag-valencia.patch.0 \
+    external/liblangtag/Wformat-overflow.patch \
 ))
 
 # vim: set noet sw=4 ts=4:
diff --git a/external/liblangtag/Wformat-overflow.patch b/external/liblangtag/Wformat-overflow.patch
new file mode 100644
index 000000000000..f2d017e4b395
--- /dev/null
+++ b/external/liblangtag/Wformat-overflow.patch
@@ -0,0 +1,17 @@
+--- liblangtag/lt-script-db.c
++++ liblangtag/lt-script-db.c
+@@ -134,8 +134,12 @@
+ 			cnode = cnode->next;
+ 		}
+ 		if (!subtag) {
+-			lt_warning("No subtag node: description = '%s'",
+-				   desc);
++			if (!desc) {
++				lt_warning("No subtag nor description node");
++			} else {
++				lt_warning("No subtag node: description = '%s'",
++					   desc);
++			}
+ 			goto bail1;
+ 		}
+ 		if (!desc) {
commit fda7f14cb5e4d5f93b2ee706b7ec6ad35a988ae5
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Thu Apr 25 11:48:39 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 14:04:23 2020 +0200

    Cut down on -pthread/-lpthread proliferation
    
    Building against libstdc++ effectively always requires -pthread anyway (as
    various standard C++ headers require it, see the comment added to
    solenv/gbuild/platform/unxgcc.mk), so many explicit uses of -pthread/-lpthread
    can be removed.
    
    Doing a (partial) test build on Linux with Clang -stdlib=libc++ suggests that
    libc++ indeed doesn't need -pthread as libstdc++ does.
    
    The remaining uses of -pthread/-lpthread are mostly in configure.ac for the
    various BSDs (which somebody else might want to clean up now), and related to
    external projects.  I tried to be careful to remove -pthread/-lpthread from
    makefiles only when C++ object files are involved (so -pthread will now be
    included on the link command line by default).
    
    Reviewed-on: https://gerrit.libreoffice.org/71291
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
    (cherry picked from commit b1141fa61073b3f24e1a3574afa55a954e5a153d)
    
    Change-Id: I936e082839cb9a434bd273ce5a1f187a4245dfa1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95130
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/connectivity/Library_postgresql-sdbc-impl.mk b/connectivity/Library_postgresql-sdbc-impl.mk
index 53cebd01a242..80c746f802dc 100644
--- a/connectivity/Library_postgresql-sdbc-impl.mk
+++ b/connectivity/Library_postgresql-sdbc-impl.mk
@@ -61,7 +61,6 @@ $(eval $(call gb_Library_add_libs,postgresql-sdbc-impl,\
 	$(if $(WITH_GSSAPI),$(GSSAPI_LIBS)) \
 	$(if $(WITH_KRB5),$(KRB5_LIBS)) \
 	$(if $(filter-out MACOSX,$(OS)),-ldl) \
-	$(if $(filter-out MACOSX,$(OS)),-lpthread) \
 ))
 
 endif
diff --git a/desktop/CppunitTest_desktop_app.mk b/desktop/CppunitTest_desktop_app.mk
index cd698aceee5e..adb57add6e7a 100644
--- a/desktop/CppunitTest_desktop_app.mk
+++ b/desktop/CppunitTest_desktop_app.mk
@@ -66,7 +66,6 @@ endif
 
 $(eval $(call gb_CppunitTest_add_libs,desktop_app,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 endif
diff --git a/desktop/Library_crashreport.mk b/desktop/Library_crashreport.mk
index 3b9d6dd34fdc..a2cef785f370 100644
--- a/desktop/Library_crashreport.mk
+++ b/desktop/Library_crashreport.mk
@@ -26,7 +26,6 @@ $(eval $(call gb_Library_add_defs,crashreport,\
 $(eval $(call gb_Library_add_libs,crashreport,\
     $(if $(filter LINUX %BSD SOLARIS, $(OS)), \
         $(DLOPEN_LIBS) \
-        -lpthread \
     ) \
 ))
 
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index 288e26d47726..29deeb707e3a 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -19,7 +19,6 @@ $(eval $(call gb_Library_set_include,sofficeapp,\
 $(eval $(call gb_Library_add_libs,sofficeapp,\
     $(if $(filter LINUX %BSD SOLARIS, $(OS)), \
         $(DLOPEN_LIBS) \
-        -lpthread \
     ) \
 ))
 
@@ -126,7 +125,6 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
 ifeq ($(ENABLE_HEADLESS),TRUE)
 $(eval $(call gb_Library_add_libs,sofficeapp,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
 ))
 else
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
@@ -138,7 +136,6 @@ endif
 
 $(eval $(call gb_Library_add_libs,sofficeapp,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 endif
diff --git a/external/clucene/Library_clucene.mk b/external/clucene/Library_clucene.mk
index abc14d903f46..f04961398797 100644
--- a/external/clucene/Library_clucene.mk
+++ b/external/clucene/Library_clucene.mk
@@ -48,7 +48,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,clucene,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/external/pdfium/Library_pdfium.mk b/external/pdfium/Library_pdfium.mk
index 0019535857a6..1f90b2b3b415 100644
--- a/external/pdfium/Library_pdfium.mk
+++ b/external/pdfium/Library_pdfium.mk
@@ -559,7 +559,6 @@ ifneq (,$(filter LINUX ANDROID,$(OS)))
 $(eval $(call gb_Library_add_libs,pdfium,\
     -ldl \
     -lrt \
-    -lpthread \
 ))
 
 $(eval $(call gb_Library_use_external,pdfium,freetype))
diff --git a/jurt/Library_jpipe.mk b/jurt/Library_jpipe.mk
index 5759baed5175..204da654c553 100644
--- a/jurt/Library_jpipe.mk
+++ b/jurt/Library_jpipe.mk
@@ -74,10 +74,6 @@ $(eval $(call gb_Library_use_system_darwin_frameworks,jpipe, \
 ))
 endif
 
-$(eval $(call gb_Library_add_libs,jpipe, \
-    $(if $(filter-out $(OS),ANDROID),-lpthread) \
-))
-
 $(call gb_LinkTarget_get_target,$(call gb_Library_get_linktarget,jpipe)): \
     gb_CC := $(filter-out -fsanitize%,$(gb_CC))
 $(call gb_LinkTarget_get_target,$(call gb_Library_get_linktarget,jpipe)): \
diff --git a/libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk b/libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk
index d58923f45194..da3be044e853 100644
--- a/libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk
+++ b/libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk
@@ -28,7 +28,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_CppunitTest_add_libs,libreofficekit_tiledrendering,\
     -lm \
     -ldl \
-    -lpthread \
 ))
 endif
 
diff --git a/libreofficekit/Executable_gtktiledviewer.mk b/libreofficekit/Executable_gtktiledviewer.mk
index 5dd89e6065f6..99ef51af8975 100644
--- a/libreofficekit/Executable_gtktiledviewer.mk
+++ b/libreofficekit/Executable_gtktiledviewer.mk
@@ -43,7 +43,6 @@ $(eval $(call gb_Executable_use_libraries,gtktiledviewer,\
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Executable_add_libs,gtktiledviewer,\
     -lm $(DLOPEN_LIBS) \
-    -lpthread \
 ))
 endif
 
diff --git a/libreofficekit/Executable_tilebench.mk b/libreofficekit/Executable_tilebench.mk
index 9d8b2a134f99..0b512a83e466 100644
--- a/libreofficekit/Executable_tilebench.mk
+++ b/libreofficekit/Executable_tilebench.mk
@@ -20,7 +20,6 @@ $(eval $(call gb_Executable_use_libraries,tilebench,\
 
 $(eval $(call gb_Executable_add_libs,tilebench,\
     -lm $(DLOPEN_LIBS) \
-    -lpthread \
 ))
 
 $(eval $(call gb_Executable_add_exception_objects,tilebench,\
diff --git a/onlineupdate/Executable_test_updater_dialog.mk b/onlineupdate/Executable_test_updater_dialog.mk
index 92e70dfae337..cae8e02df141 100644
--- a/onlineupdate/Executable_test_updater_dialog.mk
+++ b/onlineupdate/Executable_test_updater_dialog.mk
@@ -61,7 +61,6 @@ $(eval $(call gb_Executable_add_libs,test_updater_dialog,\
 	-lXrender \
 	-lSM \
 	-lICE \
-	-lpthread \
 ))
 endif
 
diff --git a/onlineupdate/Executable_updater.mk b/onlineupdate/Executable_updater.mk
index a4ceacee6bc1..5f83c13eb9ec 100644
--- a/onlineupdate/Executable_updater.mk
+++ b/onlineupdate/Executable_updater.mk
@@ -71,7 +71,6 @@ $(eval $(call gb_Executable_add_libs,updater,\
 	-lXrender \
 	-lSM \
 	-lICE \
-	-lpthread \
 ))
 endif
 
diff --git a/sal/Library_sal.mk b/sal/Library_sal.mk
index 42e9287f30ac..33ba836d6066 100644
--- a/sal/Library_sal.mk
+++ b/sal/Library_sal.mk
@@ -57,9 +57,6 @@ $(eval $(call gb_Library_use_system_win32_libs,sal,\
 ))
 
 $(eval $(call gb_Library_add_libs,sal,\
-	$(if $(filter-out ANDROID HAIKU WNT,$(OS)), \
-		-lpthread \
-	) \
 	$(if $(filter LINUX,$(OS)), \
 		-ldl \
 		-lrt \
diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk
index 48fb912c4335..4cad9547f3e6 100644
--- a/sc/CppunitTest_sc_ucalc.mk
+++ b/sc/CppunitTest_sc_ucalc.mk
@@ -114,12 +114,6 @@ $(eval $(call gb_CppunitTest_add_libs,sc_ucalc,\
 ))
 endif
 
-ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
-$(eval $(call gb_CppunitTest_add_libs,sc_ucalc,\
-    -lpthread \
-))
-endif
-
 $(eval $(call gb_CppunitTest_use_configuration,sc_ucalc))
 
 # vim: set noet sw=4 ts=4:
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 00db6e4a44c0..0ce26b5ba699 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -710,12 +710,6 @@ $(eval $(call gb_Library_add_libs,sc,\
 ))
 endif
 
-ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
-$(eval $(call gb_Library_add_libs,sc,\
-    -lpthread \
-))
-endif
-
 $(eval $(call gb_SdiTarget_SdiTarget,sc/sdi/scslots,sc/sdi/scalc))
 
 $(eval $(call gb_SdiTarget_set_include,sc/sdi/scslots,\
diff --git a/smoketest/Executable_libtest.mk b/smoketest/Executable_libtest.mk
index e16c95073976..c1e33d35e10e 100644
--- a/smoketest/Executable_libtest.mk
+++ b/smoketest/Executable_libtest.mk
@@ -16,7 +16,6 @@ $(eval $(call gb_Executable_set_include,libtest,\
 ifeq ($(OS),LINUX)
 $(eval $(call gb_Executable_add_libs,libtest,\
 	-ldl \
-	-pthread \
 ))
 endif
 
diff --git a/solenv/gbuild/platform/linux.mk b/solenv/gbuild/platform/linux.mk
index 727418b8ea61..77d4dbe679e8 100644
--- a/solenv/gbuild/platform/linux.mk
+++ b/solenv/gbuild/platform/linux.mk
@@ -18,7 +18,7 @@ gb_LinkTarget_LDFLAGS += $(gb__LinkTarget_LDFLAGS_zdefs)
 include $(GBUILDDIR)/platform/unxgcc.mk
 
 ifeq ($(DISABLE_DYNLOADING),TRUE)
-gb_STDLIBS := -lpthread -ldl
+gb_STDLIBS := -ldl
 endif
 
 # vim: set noet sw=4 ts=4:
diff --git a/solenv/gbuild/platform/unxgcc.mk b/solenv/gbuild/platform/unxgcc.mk
index 8505f9638a19..a6a361e6ee53 100644
--- a/solenv/gbuild/platform/unxgcc.mk
+++ b/solenv/gbuild/platform/unxgcc.mk
@@ -42,12 +42,20 @@ gb_CFLAGS := \
 	-Wdeclaration-after-statement \
 	-Wshadow \
 
+# At least libstdc++ (which is approximated here with !HAVE_LIBCXX) needs -pthread when including
+# various C++ headers like <thread>, see <https://gcc.gnu.org/onlinedocs/gcc-8.3.0/libstdc++/manual/
+# manual/using.html#manual.intro.using.flags>:
+ifeq ($(HAVE_LIBCXX),)
+gb_CXX_LINKFLAGS := -pthread
+endif
+
 gb_CXXFLAGS := \
 	$(gb_CXXFLAGS_COMMON) \
 	-fPIC \
 	-Wshadow \
 	-Woverloaded-virtual \
 	$(CXXFLAGS_CXX11) \
+	$(gb_CXX_LINKFLAGS) \
 
 
 # enable debug STL
@@ -120,7 +128,7 @@ gb_LinkTarget_CXXFLAGS := $(gb_CXXFLAGS)
 # contains .c sources:
 define gb_LinkTarget__command_dynamiclink
 $(call gb_Helper_abbreviate_dirs,\
-	$(if $(CXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS)$(filter-out XTRUE,X$(ENABLE_RUNTIME_OPTIMIZATIONS)),$(gb_CXX),$(gb_CC)) \
+	$(if $(CXXOBJECTS)$(GENCXXOBJECTS)$(EXTRAOBJECTLISTS)$(filter-out XTRUE,X$(ENABLE_RUNTIME_OPTIMIZATIONS)),$(gb_CXX) $(gb_CXX_LINKFLAGS),$(gb_CC)) \
 		$(if $(filter Library CppunitTest,$(TARGETTYPE)),$(gb_Library_TARGETTYPEFLAGS)) \
 		$(gb_LTOFLAGS) \
 		$(if $(SOVERSIONSCRIPT),-Wl$(COMMA)--soname=$(notdir $(1)) \
diff --git a/svx/Executable_gengal.mk b/svx/Executable_gengal.mk
index 844ab0b45e16..7316f6de2a20 100644
--- a/svx/Executable_gengal.mk
+++ b/svx/Executable_gengal.mk
@@ -64,13 +64,11 @@ endif
 ifeq ($(ENABLE_HEADLESS),TRUE)
 $(eval $(call gb_Executable_add_libs,gengal,\
 	$(DLOPEN_LIBS) \
-	-lpthread \
 ))
 else
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Executable_add_libs,gengal,\
 	$(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 
diff --git a/vcl/Executable_icontest.mk b/vcl/Executable_icontest.mk
index 8c917b71cd0e..223cfa840f9b 100644
--- a/vcl/Executable_icontest.mk
+++ b/vcl/Executable_icontest.mk
@@ -37,7 +37,6 @@ $(eval $(call gb_Executable_use_static_libraries,icontest,\
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Executable_add_libs,icontest,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 
diff --git a/vcl/Executable_lo_kde5filepicker.mk b/vcl/Executable_lo_kde5filepicker.mk
index 2eee2cd8711b..f3e940953601 100644
--- a/vcl/Executable_lo_kde5filepicker.mk
+++ b/vcl/Executable_lo_kde5filepicker.mk
@@ -92,7 +92,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Executable_add_libs,lo_kde5filepicker,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Executable_mtfdemo.mk b/vcl/Executable_mtfdemo.mk
index d637439a17ba..5c4c45165535 100644
--- a/vcl/Executable_mtfdemo.mk
+++ b/vcl/Executable_mtfdemo.mk
@@ -43,7 +43,6 @@ $(eval $(call gb_Executable_use_static_libraries,mtfdemo,\
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Executable_add_libs,mtfdemo,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 
diff --git a/vcl/Executable_ui-previewer.mk b/vcl/Executable_ui-previewer.mk
index 0925e575ee67..cf6a2d3de6c7 100644
--- a/vcl/Executable_ui-previewer.mk
+++ b/vcl/Executable_ui-previewer.mk
@@ -37,7 +37,6 @@ $(eval $(call gb_Executable_add_exception_objects,ui-previewer,\
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Executable_add_libs,ui-previewer,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 
diff --git a/vcl/Executable_vcldemo.mk b/vcl/Executable_vcldemo.mk
index c06725c297cf..35fcd27ffd51 100644
--- a/vcl/Executable_vcldemo.mk
+++ b/vcl/Executable_vcldemo.mk
@@ -53,7 +53,6 @@ $(eval $(call gb_Executable_use_static_libraries,vcldemo,\
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Executable_add_libs,vcldemo,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 
diff --git a/vcl/Executable_visualbackendtest.mk b/vcl/Executable_visualbackendtest.mk
index 87044535f03e..41c641a5ff14 100644
--- a/vcl/Executable_visualbackendtest.mk
+++ b/vcl/Executable_visualbackendtest.mk
@@ -45,7 +45,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Executable_add_libs,visualbackendtest,\
 	-lm \
 	-ldl \
-	-lpthread \
     -lX11 \
 ))
 
diff --git a/vcl/Library_desktop_detector.mk b/vcl/Library_desktop_detector.mk
index 3edd0015e243..f28ff9078e64 100644
--- a/vcl/Library_desktop_detector.mk
+++ b/vcl/Library_desktop_detector.mk
@@ -66,7 +66,6 @@ $(eval $(call gb_Library_add_exception_objects,desktop_detector,\
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Library_add_libs,desktop_detector,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index ae7622dacae3..5f8bcd3af059 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -624,11 +624,6 @@ $(eval $(call gb_Library_use_externals,vcl,\
     freetype \
     fontconfig \
 ))
-ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
-$(eval $(call gb_Library_add_libs,vcl,\
-    -lpthread \
-))
-endif
 else
  $(eval $(call gb_Library_add_exception_objects,vcl,\
     vcl/opengl/DeviceInfo \
@@ -649,7 +644,6 @@ else
 ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
 $(eval $(call gb_Library_add_libs,vcl,\
     -lm $(DLOPEN_LIBS) \
-    -lpthread \
     -lX11 \
     -lXext \
 ))
diff --git a/vcl/Library_vclplug_gen.mk b/vcl/Library_vclplug_gen.mk
index 0e1c39c15766..ba02a3f57ba7 100644
--- a/vcl/Library_vclplug_gen.mk
+++ b/vcl/Library_vclplug_gen.mk
@@ -147,7 +147,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,vclplug_gen,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Library_vclplug_gtk.mk b/vcl/Library_vclplug_gtk.mk
index 67d405d4c8fa..360eabf46020 100644
--- a/vcl/Library_vclplug_gtk.mk
+++ b/vcl/Library_vclplug_gtk.mk
@@ -126,7 +126,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,vclplug_gtk,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Library_vclplug_gtk3.mk b/vcl/Library_vclplug_gtk3.mk
index 5ecf70bb4d0f..867903fd4f8e 100644
--- a/vcl/Library_vclplug_gtk3.mk
+++ b/vcl/Library_vclplug_gtk3.mk
@@ -119,7 +119,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,vclplug_gtk3,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Library_vclplug_gtk3_kde5.mk b/vcl/Library_vclplug_gtk3_kde5.mk
index e2e7bf8a9616..c96cb672db2d 100644
--- a/vcl/Library_vclplug_gtk3_kde5.mk
+++ b/vcl/Library_vclplug_gtk3_kde5.mk
@@ -123,7 +123,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,vclplug_gtk3_kde5,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Library_vclplug_kde5.mk b/vcl/Library_vclplug_kde5.mk
index a1816c6ec143..e08d8fadae75 100644
--- a/vcl/Library_vclplug_kde5.mk
+++ b/vcl/Library_vclplug_kde5.mk
@@ -99,7 +99,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,vclplug_kde5,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/Library_vclplug_qt5.mk b/vcl/Library_vclplug_qt5.mk
index 5245d8a0149b..c4bc311fbcaf 100644
--- a/vcl/Library_vclplug_qt5.mk
+++ b/vcl/Library_vclplug_qt5.mk
@@ -102,7 +102,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,vclplug_qt5,\
 	-lm \
 	-ldl \
-	-lpthread \
 ))
 endif
 
diff --git a/vcl/StaticLibrary_glxtest.mk b/vcl/StaticLibrary_glxtest.mk
index 227cbaa574c1..1a285875c828 100644
--- a/vcl/StaticLibrary_glxtest.mk
+++ b/vcl/StaticLibrary_glxtest.mk
@@ -31,7 +31,6 @@ $(eval $(call gb_StaticLibrary_use_api,glxtest,\
 
 $(eval $(call gb_StaticLibrary_add_libs,glxtest,\
 	-lm $(DLOPEN_LIBS) \
-	-lpthread \
     -lX11 \
 ))
 
commit 968fbfb4c987c1366c8a2ad435e5fdd9e281d397
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Tue Jun 11 11:56:33 2019 +0200
Commit:     Michael Stahl <Michael.Stahl at cib.de>
CommitDate: Thu Jun 4 14:04:23 2020 +0200

    external/libmspub: missing include
    
    Change-Id: I446b26b3c0ffd0d62178f374b570c9fbd1885dd4
    Reviewed-on: https://gerrit.libreoffice.org/73813
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>
    (cherry picked from commit d0e38b8f1efc6a0b2b519ce1f82a83c5766f5633)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95109
    Tested-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/external/libmspub/UnpackedTarball_libmspub.mk b/external/libmspub/UnpackedTarball_libmspub.mk
index 5e5bedb27d83..89b06437a399 100644
--- a/external/libmspub/UnpackedTarball_libmspub.mk
+++ b/external/libmspub/UnpackedTarball_libmspub.mk
@@ -15,6 +15,7 @@ $(eval $(call gb_UnpackedTarball_set_patchlevel,libmspub,0))
 
 $(eval $(call gb_UnpackedTarball_add_patches,libmspub,\
     external/libmspub/ubsan.patch \
+    external/libmspub/stdint.patch \
 ))
 
 $(eval $(call gb_UnpackedTarball_update_autoconf_configs,libmspub))
diff --git a/external/libmspub/stdint.patch b/external/libmspub/stdint.patch
new file mode 100644
index 000000000000..61f1dd122904
--- /dev/null
+++ b/external/libmspub/stdint.patch
@@ -0,0 +1,10 @@
+--- src/lib/MSPUBMetaData.h
++++ src/lib/MSPUBMetaData.h
+@@ -13,6 +13,7 @@
+ #include <map>
+ #include <utility>
+ #include <vector>
++#include <stdint.h>
+ 
+ #include <librevenge/librevenge.h>
+ 


More information about the Libreoffice-commits mailing list