summaryrefslogtreecommitdiffstats
path: root/sw/source/core/inc/txtfly.hxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /sw/source/core/inc/txtfly.hxx
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/source/core/inc/txtfly.hxx')
-rw-r--r--sw/source/core/inc/txtfly.hxx389
1 files changed, 389 insertions, 0 deletions
diff --git a/sw/source/core/inc/txtfly.hxx b/sw/source/core/inc/txtfly.hxx
new file mode 100644
index 0000000000..9047e127e7
--- /dev/null
+++ b/sw/source/core/inc/txtfly.hxx
@@ -0,0 +1,389 @@
+/* -*- 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 <editeng/txtrange.hxx>
+#include <swtypes.hxx>
+#include <swrect.hxx>
+#include <com/sun/star/text/WrapTextMode.hpp>
+#include <nodeoffset.hxx>
+#include <memory>
+#include <vector>
+
+class OutputDevice;
+class SwPageFrame;
+class SdrObject;
+class SwFormat;
+class SwAnchoredObject;
+class SwTextFrame;
+class SwDrawTextInfo;
+class SwContourCache;
+class SwBreakPortion;
+class SwTextFormatInfo;
+
+typedef std::vector< SwAnchoredObject* > SwAnchoredObjList;
+
+/** Contour-cache global variable, initialized/destroyed in txtinit.cxx
+ and needed in txtfly.cxx by text wrapping.
+ */
+extern SwContourCache *pContourCache;
+
+#define POLY_CNT 20
+#define POLY_MIN 5
+#define POLY_MAX 4000
+
+void ClrContourCache( const SdrObject *pObj );
+
+class SwContourCache
+{
+ friend void ClrContourCache();
+ struct CacheItem
+ {
+ const SdrObject *mpSdrObj;
+ std::unique_ptr<TextRanger> mxTextRanger;
+ };
+ std::vector<CacheItem> mvItems;
+ tools::Long mnPointCount;
+ SwRect ContourRect( const SwFormat* pFormat, const SdrObject* pObj,
+ const SwTextFrame* pFrame, const SwRect &rLine, const tools::Long nXPos,
+ const bool bRight );
+
+public:
+ SwContourCache();
+ ~SwContourCache();
+ const SdrObject* GetObject( sal_uInt16 nPos ) const{ return mvItems[ nPos ].mpSdrObj; }
+ sal_uInt16 GetCount() const { return mvItems.size(); }
+ void ClrObject( sal_uInt16 nPos );
+
+ /**
+ Computes the rectangle that will cover the object in the given line.
+
+ For _non_ contour-flow objects, this is simply the overlap area of
+ BoundRect (including spacing), and the line, for contour-flow,
+ the tools::PolyPolygon of the object gets traversed
+ */
+ static SwRect CalcBoundRect( const SwAnchoredObject* pAnchoredObj,
+ const SwRect &rLine,
+ const SwTextFrame* pFrame,
+ const tools::Long nXPos,
+ const bool bRight );
+};
+
+// MS Word wraps on sides with even less space (value guessed).
+#define TEXT_MIN_SMALL 300
+
+/**
+ The purpose of this class is to be the universal interface between
+ formatting/text output and the possibly overlapping free-flying frames.
+ During formatting the formatter gets the information from SwTextFly, whether
+ a certain area is present by the attributes of an overlapping frame.
+ Such areas are represented by dummy portions.
+
+ The whole text output and touch-up is, again, forwarded to a SwTextFly.
+ This one decides, whether parts of the text need to be clipped and splits
+ the areas for e.g. a DrawRect.
+
+ Please note that all free-flying frames are located in a PtrArray, sorted
+ by TopLeft.
+
+ Internally we always use document-global values. The IN and OUT parameters
+ are, however, adjusted to the needs of the LineIter most of the time. That
+ is: they are converted to frame- and window-local coordinates.
+ If multiple frames with wrap attributes are located on the same line, we get
+ the following settings for the text flow:
+
+ L/R P L R N
+ P -P-P- -P-L -P R- -P N
+ L -L P- -L L -L R- -L N
+ R R-P- R-L R R- R N
+ N N P- N L N R- N N
+
+ (P=parallel, L=left, R=right, N=no wrap)
+
+ We can describe the behaviour as follows:
+ Every frame can push away text, with the restriction that it only has influence
+ until the next frame.
+ */
+class SwTextFly
+{
+ const SwPageFrame * m_pPage;
+ const SwAnchoredObject * mpCurrAnchoredObj;
+ const SwTextFrame * m_pCurrFrame;
+ const SwTextFrame * m_pMaster;
+ std::unique_ptr<SwAnchoredObjList> mpAnchoredObjList;
+
+ tools::Long m_nMinBottom;
+ tools::Long m_nNextTop; /// Stores the upper edge of the "next" frame
+ SwNodeOffset m_nCurrFrameNodeIndex;
+
+ bool m_bOn : 1;
+ bool m_bTopRule: 1;
+ bool mbIgnoreCurrentFrame: 1;
+ bool mbIgnoreContour: 1;
+
+ /** boolean, indicating if objects in page header|footer are considered for
+ text frames not in page header|footer.
+ */
+ bool mbIgnoreObjsInHeaderFooter: 1;
+
+ /**
+ This method will be called during the LineIter formatting
+ \li to compute the position of the next \c FlyPortion
+ \li remember new overlappings after a change of the line height.
+
+ \param[in] rPortion
+ Scope: document global.
+ */
+ SwRect GetFrame_( const SwRect &rPortion ) const;
+
+ SwAnchoredObjList& InitAnchoredObjList();
+
+public:
+ SwAnchoredObjList& GetAnchoredObjList() const;
+private:
+
+ /**
+ Look for the first object which overlaps with the rectangle.
+ Iterates over the anchored object list mpAnchoredObjList.
+ */
+ bool ForEach( const SwRect &rRect, SwRect* pRect, bool bAvoid ) const;
+
+ /**
+ \li There is less than 2cm space on both sides for the text:
+ no surround (css::text::WrapTextMode_NONE)
+
+ \li There is more than 2cm space on only one side:
+ surround on that side (css::text::WrapTextMode_LEFT or css::text::WrapTextMode_RIGHT)
+
+ \li There is more than 2cm space on both sides, the object is
+ larger than 1.5cm: surround on the wider side
+ (css::text::WrapTextMode_LEFT or css::text::WrapTextMode_RIGHT)
+
+ \li There is more than 2cm space on both sides and the object
+ width is less than 1.5cm: both sides surround (css::text::WrapTextMode_PARALLEL)
+ */
+ css::text::WrapTextMode GetSurroundForTextWrap( const SwAnchoredObject* pAnchoredObj ) const;
+
+ /**
+ The right margin is the right margin or it is determined by the
+ next object standing on the line.
+ */
+ void CalcRightMargin( SwRect &rFly,
+ SwAnchoredObjList::size_type nPos,
+ const SwRect &rLine ) const;
+
+ /**
+ The left margin is the left margin of the current PrintArea or
+ it is determined by the last FlyFrame, which stands on the line.
+ */
+ void CalcLeftMargin( SwRect &rFly,
+ SwAnchoredObjList::size_type nPos,
+ const SwRect &rLine ) const;
+
+ /**
+ \return the position in sorted array
+ */
+ SwAnchoredObjList::size_type GetPos( const SwAnchoredObject* pAnchoredObj ) const;
+
+ bool GetTop( const SwAnchoredObject* _pAnchoredObj,
+ const bool bInFootnote,
+ const bool bInFooterOrHeader );
+
+ SwTwips CalcMinBottom() const;
+
+ const SwTextFrame* GetMaster_();
+
+public:
+
+ SwTextFly();
+ SwTextFly( const SwTextFrame *pFrame );
+ SwTextFly( const SwTextFly& rTextFly );
+ ~SwTextFly();
+
+ void CtorInitTextFly( const SwTextFrame *pFrame );
+
+ void SetTopRule();
+
+ SwRect GetFrame( const SwRect &rPortion ) const;
+ bool IsOn() const;
+
+ /**
+ If there is no flying object frame standing in rRect (usually the current row),
+ then we are turning ourself off.
+
+ \param rRect is global to the document!
+ */
+ bool Relax( const SwRect &rRect );
+ bool Relax();
+
+ SwTwips GetMinBottom() const;
+
+ /// Gets the maximum of the fly frame bottoms.
+ SwTwips GetMaxBottom(const SwBreakPortion& rPortion, const SwTextFormatInfo& rInfo) const;
+
+ const SwTextFrame* GetMaster() const;
+
+ // This temporary variable needs to be manipulated in const methods
+ tools::Long GetNextTop() const;
+ void SetNextTop( tools::Long nNew ) const;
+
+ /**
+ Determines the demanded rectangle for an anchored object,
+ considering its surround for text wrapping.
+
+ \param pAnchoredObj the object for which to get the bounds
+ \param rLine the bounds of the line to format
+
+ \return the flying object bounds
+ */
+ SwRect AnchoredObjToRect( const SwAnchoredObject* pAnchoredObj,
+ const SwRect& rRect ) const;
+
+ /**
+ This method is called by DrawText().
+
+ Ensures that the overlapping frames (except the transparent frames) won't
+ be scribbled by setting clip regions so that only the portions that are not
+ in the area of FlyFrames that are opaque and above the current frame will
+ be output.
+
+ DrawText() takes over the on optimization!
+ */
+ void DrawTextOpaque( SwDrawTextInfo &rInf );
+
+ /**
+ Two subtleties needs to be mentioned:
+ \li DrawRect() is allowed over the ClipRects
+ \li FlyToRect() returns bigger values than the frame data
+
+ Ensure that the overlapping frames (except the transparent frames)
+ won't be scribbled
+ */
+ void DrawFlyRect( OutputDevice* pOut, const SwRect &rRect );
+
+ /**
+ Used to switch off the SwTextFly when there is no overlapping object (Relax).
+
+ \param[in] the line area
+ \return whether the line will be overlapped by a frame
+ */
+ bool IsAnyFrame( const SwRect &rLine ) const;
+
+ /**
+ Same as IsAnyFrame(const SwRect&), but uses the current frame print
+ area
+ */
+ bool IsAnyFrame() const;
+
+ /**
+ true when a frame or DrawObj must be taken in account. The optimizations
+ like Paint/FormatEmpty for empty sentences or the virtual OutputDevice can
+ be used only when false is returned.
+
+ \param rRect
+ The rectangle can be empty, the current frame is then used. The value is
+ global to the document.
+ */
+ bool IsAnyObj( const SwRect& rRect ) const;
+
+ void SetIgnoreCurrentFrame( bool bNew );
+ void SetIgnoreContour( bool bNew );
+
+ void SetIgnoreObjsInHeaderFooter( const bool bNew );
+
+ SwRect GetFrameArea() const;
+};
+
+inline SwAnchoredObjList& SwTextFly::GetAnchoredObjList() const
+{
+ return mpAnchoredObjList
+ ? *mpAnchoredObjList
+ : const_cast<SwTextFly*>(this)->InitAnchoredObjList();
+}
+
+inline void SwTextFly::SetTopRule()
+{
+ m_bTopRule = false;
+}
+
+inline bool SwTextFly::IsOn() const
+{
+ return m_bOn;
+}
+
+inline bool SwTextFly::Relax( const SwRect &rRect )
+{
+ if (m_bOn)
+ {
+ m_bOn = IsAnyFrame( rRect );
+ }
+ return m_bOn;
+}
+
+inline bool SwTextFly::Relax()
+{
+ if (m_bOn)
+ {
+ m_bOn = IsAnyFrame();
+ }
+ return m_bOn;
+}
+
+inline SwTwips SwTextFly::GetMinBottom() const
+{
+ return mpAnchoredObjList ? m_nMinBottom : CalcMinBottom();
+}
+
+inline const SwTextFrame* SwTextFly::GetMaster() const
+{
+ return m_pMaster ? m_pMaster : const_cast<SwTextFly*>(this)->GetMaster_();
+}
+
+inline tools::Long SwTextFly::GetNextTop() const
+{
+ return m_nNextTop;
+}
+
+inline void SwTextFly::SetNextTop( tools::Long nNew ) const
+{
+ const_cast<SwTextFly*>(this)->m_nNextTop = nNew;
+}
+
+inline SwRect SwTextFly::GetFrame( const SwRect &rRect ) const
+{
+ return m_bOn ? GetFrame_( rRect ) : SwRect();
+}
+
+inline void SwTextFly::SetIgnoreCurrentFrame( bool bNew )
+{
+ mbIgnoreCurrentFrame = bNew;
+}
+
+inline void SwTextFly::SetIgnoreContour( bool bNew )
+{
+ mbIgnoreContour = bNew;
+}
+
+inline void SwTextFly::SetIgnoreObjsInHeaderFooter( const bool bNew )
+{
+ mbIgnoreObjsInHeaderFooter = bNew;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */