summaryrefslogtreecommitdiffstats
path: root/sw/source/core/text/pormulti.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/text/pormulti.hxx')
-rw-r--r--sw/source/core/text/pormulti.hxx256
1 files changed, 256 insertions, 0 deletions
diff --git a/sw/source/core/text/pormulti.hxx b/sw/source/core/text/pormulti.hxx
new file mode 100644
index 0000000000..e5a3da2b32
--- /dev/null
+++ b/sw/source/core/text/pormulti.hxx
@@ -0,0 +1,256 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include "porlay.hxx"
+#include <com/sun/star/text/RubyAdjust.hpp>
+
+class IDocumentSettingAccess;
+class SwTextFormatInfo;
+class SwTextCursor;
+class SwTextPaintInfo;
+class SwTextAttr;
+class SfxPoolItem;
+class SwFont;
+
+// SwMultiCreator is a small structure to create a multiportion.
+// It contains the kind of multiportion and a textattribute
+// or a poolitem.
+// The GetMultiCreator-function fills this structure and
+// the Ctor of the SwMultiPortion uses it.
+enum class SwMultiCreatorId
+{
+ Double, Ruby, Rotate, Bidi
+};
+
+enum class RubyPosition : sal_uInt16
+{
+ ABOVE = 0,
+ BELOW = 1,
+ RIGHT = 2
+};
+
+struct SwMultiCreator
+{
+ TextFrameIndex nStartOfAttr;
+ const SwTextAttr* pAttr;
+ const SfxPoolItem* pItem;
+ SwMultiCreatorId nId;
+ sal_uInt8 nLevel;
+};
+
+// A two-line-portion (SwMultiPortion) could have surrounding brackets,
+// in this case the structure SwBracket will be used.
+struct SwBracket
+{
+ TextFrameIndex nStart; // Start of text attribute determines the font
+ sal_uInt16 nAscent; // Ascent of the brackets
+ sal_uInt16 nHeight; // Height of them
+ sal_uInt16 nPreWidth; // Width of the opening bracket
+ sal_uInt16 nPostWidth; // Width of the closing bracket
+ sal_Unicode cPre; // Initial character, e.g. '('
+ sal_Unicode cPost; // Final character, e.g. ')'
+ SwFontScript nPreScript; // Script of the initial character
+ SwFontScript nPostScript; // Script of the final character
+};
+
+// The SwMultiPortion is line portion inside a line portion,
+// it's a group of portions,
+// e.g. a double line portion in a line
+// or phonetics (ruby)
+// or combined characters
+// or a rotated portion.
+class SAL_DLLPUBLIC_RTTI SwMultiPortion : public SwLinePortion
+{
+ SwLineLayout m_aRoot; // One or more lines
+ bool m_bTab1 :1; // First line tabulator
+ bool m_bTab2 :1; // Second line includes tabulator
+ bool m_bDouble :1; // Double line
+ bool m_bRuby :1; // Phonetics
+ bool m_bBidi :1;
+ bool m_bFormatted :1; // Already formatted
+ bool m_bFollowField :1; // Field follow inside
+ bool m_bFlyInContent:1; // Fly as character inside
+ RubyPosition m_eRubyPosition; // Phonetic position
+ sal_uInt8 m_nDirection:2; // Direction (0/90/180/270 degrees)
+protected:
+ explicit SwMultiPortion(TextFrameIndex const nEnd)
+ : m_bTab1(false)
+ , m_bTab2(false)
+ , m_bDouble(false)
+ , m_bRuby(false)
+ , m_bBidi(false)
+ , m_bFormatted(false)
+ , m_bFollowField(false)
+ , m_bFlyInContent(false)
+ , m_eRubyPosition( RubyPosition::ABOVE )
+ , m_nDirection(0)
+ {
+ SetWhichPor(PortionType::Multi);
+ SetLen(nEnd);
+ }
+ void SetDouble() { m_bDouble = true; }
+ void SetRuby() { m_bRuby = true; }
+ void SetBidi() { m_bBidi = true; }
+ void SetRubyPosition( RubyPosition eNew ) { m_eRubyPosition = eNew; }
+ void SetTab1( bool bNew ) { m_bTab1 = bNew; }
+ void SetTab2( bool bNew ) { m_bTab2 = bNew; }
+ void SetDirection( sal_uInt8 nNew ) { m_nDirection = nNew; }
+ bool GetTab1() const { return m_bTab1; }
+ bool GetTab2() const { return m_bTab2; }
+public:
+ virtual ~SwMultiPortion() override;
+ const SwLineLayout& GetRoot() const { return m_aRoot; }
+ SwLineLayout& GetRoot() { return m_aRoot; }
+
+ bool HasTabulator() const { return m_bTab1 || m_bTab2; }
+ bool IsFormatted() const { return m_bFormatted; }
+ void SetFormatted() { m_bFormatted = true; }
+ bool IsFollowField() const { return m_bFollowField; }
+ void SetFollowField() { m_bFollowField = true; }
+ bool HasFlyInContent() const { return m_bFlyInContent; }
+ void SetFlyInContent( bool bNew ) { m_bFlyInContent = bNew; }
+ bool IsDouble() const { return m_bDouble; }
+ bool IsRuby() const { return m_bRuby; }
+ bool IsBidi() const { return m_bBidi; }
+ bool OnTop() const { return m_eRubyPosition == RubyPosition::ABOVE; }
+ bool OnRight() const { return m_eRubyPosition == RubyPosition::RIGHT; }
+ RubyPosition GetRubyPosition() const { return m_eRubyPosition; }
+ void ActualizeTabulator();
+
+ virtual void Paint( const SwTextPaintInfo &rInf ) const override;
+ virtual SwTwips CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo &rInf ) const override;
+ virtual bool ChgSpaceAdd( SwLineLayout* pCurr, tools::Long nSpaceAdd ) const;
+
+ // Summarize the internal lines to calculate the (external) size
+ void CalcSize( SwTextFormatter& rLine, SwTextFormatInfo &rInf );
+
+ inline bool HasBrackets() const;
+ bool HasRotation() const { return 0 != (1 & m_nDirection); }
+ bool IsRevers() const { return 0 != (2 & m_nDirection); }
+ sal_uInt8 GetDirection() const { return m_nDirection; }
+
+ // Accessibility: pass information about this portion to the PortionHandler
+ virtual void HandlePortion( SwPortionHandler& rPH ) const override;
+
+ void dumpAsXml(xmlTextWriterPtr pWriter, const OUString& rText,
+ TextFrameIndex& nOffset) const override;
+};
+
+class SwDoubleLinePortion : public SwMultiPortion
+{
+ std::unique_ptr<SwBracket> m_pBracket; // Surrounding brackets
+ SwTwips m_nLineDiff; // Difference of the width of the both lines
+ TextFrameIndex m_nBlank1; ///< Number of blanks in the first line
+ TextFrameIndex m_nBlank2; ///< Number of blanks in the second line
+public:
+ SwDoubleLinePortion(SwDoubleLinePortion& rDouble, TextFrameIndex nEnd);
+ SwDoubleLinePortion(const SwMultiCreator& rCreate, TextFrameIndex nEnd);
+ virtual ~SwDoubleLinePortion() override;
+
+ SwBracket* GetBrackets() const { return m_pBracket.get(); }
+ void SetBrackets( const SwDoubleLinePortion& rDouble );
+ void PaintBracket( SwTextPaintInfo& rInf, tools::Long nSpaceAdd, bool bOpen ) const;
+ void FormatBrackets( SwTextFormatInfo &rInf, SwTwips& nMaxWidth );
+ sal_uInt16 PreWidth() const { return m_pBracket->nPreWidth; };
+ sal_uInt16 PostWidth() const { return m_pBracket->nPostWidth; }
+ void ClearBrackets()
+ { m_pBracket->nPreWidth = m_pBracket->nPostWidth=0; Width( 0 ); }
+ sal_uInt16 BracketWidth(){ return PreWidth() + PostWidth(); }
+
+ void CalcBlanks( SwTextFormatInfo &rInf );
+ static void ResetSpaceAdd( SwLineLayout* pCurr );
+ SwTwips GetLineDiff() const { return m_nLineDiff; }
+ TextFrameIndex GetSpaceCnt() const
+ { return ( m_nLineDiff < 0 ) ? m_nBlank2 : m_nBlank1; }
+ TextFrameIndex GetSmallerSpaceCnt() const
+ { return ( m_nLineDiff < 0 ) ? m_nBlank1 : m_nBlank2; }
+
+ virtual SwTwips CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo &rInf ) const override;
+ virtual bool ChgSpaceAdd( SwLineLayout* pCurr, tools::Long nSpaceAdd ) const override;
+};
+
+class SwRubyPortion : public SwMultiPortion
+{
+ TextFrameIndex m_nRubyOffset;
+ css::text::RubyAdjust m_nAdjustment;
+ void Adjust_( SwTextFormatInfo &rInf);
+public:
+ SwRubyPortion(const SwRubyPortion& rRuby, TextFrameIndex nEnd);
+
+ SwRubyPortion( const SwMultiCreator& rCreate, const SwFont& rFnt,
+ const IDocumentSettingAccess& rIDocumentSettingAccess,
+ TextFrameIndex nEnd, TextFrameIndex nOffs,
+ const SwTextSizeInfo &rInf );
+
+ void CalcRubyOffset();
+ void Adjust( SwTextFormatInfo &rInf )
+ { if(m_nAdjustment != css::text::RubyAdjust_LEFT && GetRoot().GetNext()) Adjust_(rInf); }
+ css::text::RubyAdjust GetAdjustment() const { return m_nAdjustment; }
+ TextFrameIndex GetRubyOffset() const { return m_nRubyOffset; }
+};
+
+class SwRotatedPortion : public SwMultiPortion
+{
+public:
+ SwRotatedPortion(TextFrameIndex const nEnd, sal_uInt8 nDir)
+ : SwMultiPortion( nEnd ) { SetDirection( nDir ); }
+ SwRotatedPortion( const SwMultiCreator& rCreate, TextFrameIndex nEnd,
+ bool bRTL );
+};
+
+class SwBidiPortion : public SwMultiPortion
+{
+ sal_uInt8 m_nLevel;
+
+public:
+ SwBidiPortion(TextFrameIndex nEnd, sal_uInt8 nLv);
+
+ sal_uInt8 GetLevel() const { return m_nLevel; }
+ // Get number of blanks for justified alignment
+ TextFrameIndex GetSpaceCnt(const SwTextSizeInfo &rInf) const;
+ // Calculates extra spacing based on number of blanks
+ virtual SwTwips CalcSpacing( tools::Long nSpaceAdd, const SwTextSizeInfo &rInf ) const override;
+ // Manipulate the spacing array at pCurr
+ virtual bool ChgSpaceAdd( SwLineLayout* pCurr, tools::Long nSpaceAdd ) const override;
+};
+
+// For cursor travelling in multiportions
+
+class SwTextCursorSave
+{
+ SwTextCursor* pTextCursor;
+ SwLineLayout* pCurr;
+ TextFrameIndex nStart;
+ sal_uInt16 nWidth;
+ sal_uInt8 nOldProp;
+ bool bSpaceChg;
+public:
+ SwTextCursorSave( SwTextCursor* pTextCursor, SwMultiPortion* pMulti,
+ SwTwips nY, SwTwips& nX, TextFrameIndex nCurrStart, tools::Long nSpaceAdd);
+ ~SwTextCursorSave();
+};
+
+inline bool SwMultiPortion::HasBrackets() const
+{
+ return IsDouble() && nullptr != static_cast<const SwDoubleLinePortion*>(this)->GetBrackets();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */