summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/qa/extras/ooxmlimport/ooxmlimport.cxx10
-rw-r--r--sw/source/core/access/accportions.cxx3
-rw-r--r--sw/source/core/inc/scriptinfo.hxx11
-rw-r--r--sw/source/core/inc/txttypes.hxx1
-rw-r--r--sw/source/core/text/inftxt.cxx23
-rw-r--r--sw/source/core/text/inftxt.hxx3
-rw-r--r--sw/source/core/text/itrform2.cxx51
-rw-r--r--sw/source/core/text/porlay.cxx17
-rw-r--r--sw/source/core/text/porlin.cxx4
-rw-r--r--sw/source/core/text/porlin.hxx2
-rw-r--r--sw/source/core/text/pormulti.cxx14
-rw-r--r--sw/source/core/text/porrst.cxx122
-rw-r--r--sw/source/core/text/porrst.hxx26
-rw-r--r--sw/source/core/text/xmldump.cxx1
14 files changed, 262 insertions, 26 deletions
diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
index a9edd2b66eb1..fb6fbde35536 100644
--- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
+++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx
@@ -318,8 +318,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", "PortionType::Bookmark");
+ assertXPath(pXmlDoc, "/root/page/body/txt/Special[2]", "nHeight", "253");
+ assertXPath(pXmlDoc, "/root/page/body/txt/Special[3]", "nType", "PortionType::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 00cabbe14eba..b929bc54b5ac 100644
--- a/sw/source/core/access/accportions.cxx
+++ b/sw/source/core/access/accportions.cxx
@@ -170,6 +170,9 @@ void SwAccessiblePortionData::Special(
case PortionType::ControlChar:
sDisplay = rText + OUStringChar(m_pTextFrame->GetText()[sal_Int32(m_nViewPosition)]);
break;
+ case PortionType::Bookmark:
+ // TODO
+ break;
default:
sDisplay = rText;
break;
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 6d7ad0f4dfff..bb91dedea1a7 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -24,6 +24,7 @@
#include <deque>
#include <unordered_set>
#include <rtl/ustrbuf.hxx>
+#include <o3tl/typed_flags_set.hxx>
#include <i18nlangtag/lang.h>
#include "TextFrameIndex.hxx"
@@ -42,7 +43,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:
}
TextFrameIndex NextHiddenChg(TextFrameIndex nPos) const;
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 2030fff25cc5..16f433e3b0b2 100644
--- a/sw/source/core/inc/txttypes.hxx
+++ b/sw/source/core/inc/txttypes.hxx
@@ -33,6 +33,7 @@ enum class PortionType
Multi = 0x0085,
HiddenText = 0x0086,
ControlChar = 0x0087,
+ Bookmark = 0x0088,
Text = 0x8000,
Lay = 0x8001,
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 83e8bde03ad3..8538d6ebabd4 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1375,6 +1375,14 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion &rPor,
bDraw = true;
}
break;
+ case PortionType::Bookmark:
+ if (!GetOpt().IsPagePreview()
+ && !GetOpt().IsReadonly()
+ && GetOpt().IsViewMetaChars())
+ {
+ bDraw = true;
+ }
+ break;
case PortionType::InputField:
// input field shading also in read-only mode
if ( !GetOpt().IsPagePreview()
@@ -1582,6 +1590,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()));
@@ -2007,4 +2016,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 30888843626d..63d030e896e9 100644
--- a/sw/source/core/text/inftxt.hxx
+++ b/sw/source/core/text/inftxt.hxx
@@ -477,6 +477,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
@@ -636,6 +637,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 3285f7f5ede9..6edf7e055184 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -691,6 +691,10 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf )
CalcAscent( rInf, pPor );
InsertPortion( rInf, pPor );
+ if (pPor->IsMultiPortion() && (!m_pMulti || m_pMulti->IsBidi()))
+ {
+ (void) rInf.CheckCurrentPosBookmark(); // bookmark was already created inside MultiPortion!
+ }
pPor = NewPortion( rInf );
}
@@ -753,6 +757,19 @@ void SwTextFormatter::CalcAscent( SwTextFormatInfo &rInf, SwLinePortion *pPor )
pPor->Height( pLast->Height() );
pPor->SetAscent( pLast->GetAscent() );
}
+ else if (pPor->GetWhichPor() == PortionType::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();
@@ -1012,6 +1029,7 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf )
return pPor;
}
+// first portions have no length
SwLinePortion *SwTextFormatter::WhichFirstPortion(SwTextFormatInfo &rInf)
{
SwLinePortion *pPor = nullptr;
@@ -1144,6 +1162,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 aa0bbf6860c3..9fa74a0d4833 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1686,6 +1686,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 b5adccb07fba..3d5cb26aa4be 100644
--- a/sw/source/core/text/porlin.cxx
+++ b/sw/source/core/text/porlin.cxx
@@ -103,7 +103,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 3fe08cbacba4..ca7bc1a34fe1 100644
--- a/sw/source/core/text/porlin.hxx
+++ b/sw/source/core/text/porlin.hxx
@@ -133,7 +133,7 @@ public:
bool IsArrowPortion() const { return nWhichPor == PortionType::Arrow; }
bool IsMultiPortion() const { return nWhichPor == PortionType::Multi; }
bool IsNumberPortion() const { return nWhichPor == PortionType::Number; } // #i23726#
- bool IsControlCharPortion() const { return nWhichPor == PortionType::ControlChar; }
+ bool IsControlCharPortion() const { return nWhichPor == PortionType::ControlChar || nWhichPor == PortionType::Bookmark; }
// Positioning
SwLinePortion *FindPrevPortion( const SwLinePortion *pRoot );
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index 1ef0c04efd86..5e991cc4bed3 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -38,6 +38,7 @@
#include "itrform2.hxx"
#include "porfld.hxx"
#include "porglue.hxx"
+#include "porrst.hxx"
#include <pagefrm.hxx>
#include <rowfrm.hxx>
#include <tgrditem.hxx>
@@ -2029,6 +2030,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() == PortionType::Bookmark)
+ {
+ auto const pBookmark(static_cast<SwBookmarkPortion*>(rInf.GetLast()));
+ rInf.SetLast(pBookmark->Unchain());
+ assert(m_pCurr->GetNextPortion() == nullptr);
+ m_pCurr->SetNextPortion(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 686959609cd8..44d2288eaf9c 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -306,6 +306,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() &&
@@ -488,35 +499,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 = OUStringChar(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, PortionType::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;
@@ -527,12 +595,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);
@@ -565,4 +636,13 @@ sal_uInt16 SwControlCharPortion::GetViewWidth( const SwTextSizeInfo& rInf ) cons
return mnViewWidth;
}
+SwLinePortion * SwBookmarkPortion::Unchain()
+{
+ assert(!m_pPrevious || m_pPrevious->GetNextPortion() == this);
+ m_pPrevious->SetNextPortion(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 85e85d1570dd..dcb2cfcae7e9 100644
--- a/sw/source/core/text/porrst.hxx
+++ b/sw/source/core/text/porrst.hxx
@@ -31,6 +31,7 @@
class SwPortionHandler;
class SwTextPaintInfo;
class SwTextSizeInfo;
+class SwFont;
#define LINE_BREAK_WIDTH 150
#define SPECIAL_FONT_HEIGHT 200
@@ -133,6 +134,7 @@ 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
+protected:
sal_Unicode const mcChar;
public:
@@ -143,11 +145,35 @@ public:
SetWhichPor( PortionType::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(PortionType::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 510615b08a1f..3db640cb4774 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -52,6 +52,7 @@ class XmlPortionDumper:public SwPortionHandler
case PortionType::Multi: return "PortionType::Multi";
case PortionType::HiddenText: return "PortionType::HiddenText";
case PortionType::ControlChar: return "PortionType::ControlChar";
+ case PortionType::Bookmark: return "PortionType::Bookmark";
case PortionType::Text: return "PortionType::Text";
case PortionType::Lay: return "PortionType::Lay";