LibreOffice Module sw (master) 1
frminf.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <frminf.hxx>
23#include "itrtxt.hxx"
24
26{
27 const OUString &rText = GetInfo().GetText();
28 const TextFrameIndex nEnd = m_nStart + m_pCurr->GetLen();
29
30 for (TextFrameIndex i = m_nStart; i < nEnd; ++i)
31 {
32 const sal_Unicode aChar = rText[sal_Int32(i)];
33 if( CH_TAB != aChar && ' ' != aChar )
34 return i;
35 }
36 return nEnd;
37}
38
40{
41 const OUString &rText = GetInfo().GetText();
42 const TextFrameIndex nEnd = m_nStart + m_pCurr->GetLen();
43 for (TextFrameIndex i = nEnd - TextFrameIndex(1); i >= m_nStart; --i)
44 {
45 const sal_Unicode aChar = rText[sal_Int32(i)];
46 if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
47 return i + TextFrameIndex(1);
48 }
49 return m_nStart;
50}
51
52// Does the paragraph fit into one line?
54{
55 const SwLineLayout *pLay = m_pFrame->GetPara();
56 if( !pLay )
57 return false;
58
59 // For follows false of course
60 if( m_pFrame->GetFollow() )
61 return false;
62
63 pLay = pLay->GetNext();
64 while( pLay )
65 {
66 if( pLay->GetLen() )
67 return false;
68 pLay = pLay->GetNext();
69 }
70 return true;
71}
72
73// Is the line filled for X percent?
74bool SwTextFrameInfo::IsFilled( const sal_uInt8 nPercent ) const
75{
76 const SwLineLayout *pLay = m_pFrame->GetPara();
77 if( !pLay )
78 return false;
79
81 nWidth *= nPercent;
82 nWidth /= 100;
83 return nWidth <= pLay->Width();
84}
85
86// Where does the text start (without whitespace)? (document global)
88{
89 const TextFrameIndex nTextStart = rLine.GetTextStart();
90 if( rLine.GetStart() == nTextStart )
91 return rLine.GetLineStart();
92
93 SwRect aRect;
94 const_cast<SwTextCursor&>(rLine).GetCharRect( &aRect, nTextStart );
95 return aRect.Left();
96}
97
98// Where does the text start (without whitespace)? (relative in the Frame)
100{
101 SwTextSizeInfo aInf( const_cast<SwTextFrame*>(m_pFrame) );
102 SwTextCursor aLine( const_cast<SwTextFrame*>(m_pFrame), &aInf );
104}
105
106// Calculates the character's position and returns the middle position
107SwTwips SwTextFrameInfo::GetCharPos(TextFrameIndex const nChar, bool bCenter) const
108{
109 SwRectFnSet aRectFnSet(m_pFrame);
110 SwFrameSwapper aSwapper( m_pFrame, true );
111
112 SwTextSizeInfo aInf( const_cast<SwTextFrame*>(m_pFrame) );
113 SwTextCursor aLine( const_cast<SwTextFrame*>(m_pFrame), &aInf );
114
115 SwTwips nStt, nNext;
116 SwRect aRect;
117 aLine.GetCharRect( &aRect, nChar );
118 if ( aRectFnSet.IsVert() )
120
121 nStt = aRectFnSet.GetLeft(aRect);
122
123 if( !bCenter )
124 return nStt - aRectFnSet.GetLeft(m_pFrame->getFrameArea());
125
126 aLine.GetCharRect( &aRect, nChar + TextFrameIndex(1) );
127 if ( aRectFnSet.IsVert() )
129
130 nNext = aRectFnSet.GetLeft(aRect);
131
132 return (( nNext + nStt ) / 2 ) - aRectFnSet.GetLeft(m_pFrame->getFrameArea());
133}
134
135static void
136AddRange(std::vector<std::pair<TextFrameIndex, TextFrameIndex>> & rRanges,
137 TextFrameIndex const nPos, TextFrameIndex const nLen)
138{
139 assert(rRanges.empty() || rRanges.back().second <= nPos);
140 if( nLen )
141 {
142 if (!rRanges.empty() && nPos == rRanges.back().second)
143 {
144 rRanges.back().second += nLen;
145 }
146 else
147 {
148 rRanges.emplace_back(nPos, nPos + nLen);
149 }
150 }
151}
152
153// Accumulates the whitespace at line start and end in the vector
155 std::vector<std::pair<TextFrameIndex, TextFrameIndex>> & rRanges,
156 bool const bWithLineBreak) const
157{
158 SwTextSizeInfo aInf( const_cast<SwTextFrame*>(m_pFrame) );
159 SwTextMargin aLine( const_cast<SwTextFrame*>(m_pFrame), &aInf );
160 bool bFirstLine = true;
161 do {
162
163 if( aLine.GetCurr()->GetLen() )
164 {
166 // Do NOT include the blanks/tabs from the first line
167 // in the selection
168 if( !bFirstLine && nPos > aLine.GetStart() )
169 AddRange( rRanges, aLine.GetStart(), nPos - aLine.GetStart() );
170
171 // Do NOT include the blanks/tabs from the last line
172 // in the selection
173 if( aLine.GetNext() )
174 {
175 nPos = aLine.GetTextEnd();
176
177 if( nPos < aLine.GetEnd() )
178 {
179 TextFrameIndex const nOff( !bWithLineBreak && CH_BREAK ==
180 aLine.GetInfo().GetChar(aLine.GetEnd() - TextFrameIndex(1))
181 ? 1 : 0 );
182 AddRange( rRanges, nPos, aLine.GetEnd() - nPos - nOff );
183 }
184 }
185 }
186 bFirstLine = false;
187 }
188 while( aLine.Next() );
189}
190
191// Is there a bullet/symbol etc. at the text position?
192// Fonts: CharSet, SYMBOL and DONTKNOW
193bool SwTextFrameInfo::IsBullet(TextFrameIndex const nTextStart) const
194{
195 SwTextSizeInfo aInf( const_cast<SwTextFrame*>(m_pFrame) );
196 SwTextMargin aLine( const_cast<SwTextFrame*>(m_pFrame), &aInf );
197 aInf.SetIdx( nTextStart );
198 return aLine.IsSymbol( nTextStart );
199}
200
201// Get first line indent
202// The precondition for a positive or negative first line indent:
203// All lines (except for the first one) have the same left margin.
204// We do not want to be so picky and work with a tolerance of TOLERANCE twips.
206{
207 SwTextSizeInfo aInf( const_cast<SwTextFrame*>(m_pFrame) );
208 SwTextCursor aLine( const_cast<SwTextFrame*>(m_pFrame), &aInf );
209 const SwTwips nFirst = GetLineStart( aLine );
210 const SwTwips TOLERANCE = 20;
211
212 if( !aLine.Next() )
213 return 0;
214
215 SwTwips nLeft = GetLineStart( aLine );
216 while( aLine.Next() )
217 {
218 if( aLine.GetCurr()->GetLen() )
219 {
220 const SwTwips nCurrLeft = GetLineStart( aLine );
221 if( nLeft + TOLERANCE < nCurrLeft ||
222 nLeft - TOLERANCE > nCurrLeft )
223 return 0;
224 }
225 }
226
227 // At first we only return +1, -1 and 0
228 if( nLeft == nFirst )
229 return 0;
230
231 if( nLeft > nFirst )
232 return -1;
233
234 return 1;
235}
236
238 const SwTextFrame *pNextFrame ) const
239{
240 SwTextSizeInfo aInf( const_cast<SwTextFrame*>(m_pFrame) );
241 SwTextCursor aLine( const_cast<SwTextFrame*>(m_pFrame), &aInf );
242 SwTwips nNextIndent = 0;
243
244 if( pNextFrame )
245 {
246 // I'm a single line
247 SwTextSizeInfo aNxtInf( const_cast<SwTextFrame*>(pNextFrame) );
248 SwTextCursor aNxtLine( const_cast<SwTextFrame*>(pNextFrame), &aNxtInf );
249 nNextIndent = GetLineStart( aNxtLine );
250 }
251 else
252 {
253 // I'm multi-line
254 if( aLine.Next() )
255 {
256 nNextIndent = GetLineStart( aLine );
257 aLine.Prev();
258 }
259 }
260
261 if( nNextIndent <= GetLineStart( aLine ) )
262 return 0;
263
264 const Point aPoint( nNextIndent, aLine.Y() );
265 rFndPos = aLine.GetModelPositionForViewPoint( nullptr, aPoint, false );
266 if (TextFrameIndex(1) >= rFndPos)
267 return 0;
268
269 // Is on front of a non-space
270 const OUString& rText = aInf.GetText();
271 sal_Unicode aChar = rText[sal_Int32(rFndPos)];
272 if( CH_TAB == aChar || CH_BREAK == aChar || ' ' == aChar ||
273 (( CH_TXTATR_BREAKWORD == aChar || CH_TXTATR_INWORD == aChar ) &&
274 aInf.HasHint( rFndPos ) ) )
275 return 0;
276
277 // and after a space
278 aChar = rText[sal_Int32(rFndPos) - 1];
279 if( CH_TAB != aChar && CH_BREAK != aChar &&
280 ( ( CH_TXTATR_BREAKWORD != aChar && CH_TXTATR_INWORD != aChar ) ||
281 !aInf.HasHint(rFndPos - TextFrameIndex(1))) &&
282 // More than two Blanks!
283 (' ' != aChar || ' ' != rText[sal_Int32(rFndPos) - 2]))
284 return 0;
285
286 SwRect aRect;
287 aLine.GetCharRect( &aRect, rFndPos );
288 return static_cast<sal_Int32>(aRect.Left() - m_pFrame->getFrameArea().Left() - m_pFrame->getFramePrintArea().Left());
289}
290
291/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
bool IsSymbol(TextFrameIndex nPos)
Definition: itratr.cxx:181
const SwRect & getFrameArea() const
Definition: frame.hxx:179
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
Helper class which can be used instead of the macros if a function has too many returns.
Definition: txtfrm.hxx:956
Collection of SwLinePortion instances, representing one line of text.
Definition: porlay.hxx:79
SwLineLayout * GetNext()
Definition: porlay.hxx:159
TextFrameIndex GetLen() const
Definition: porlin.hxx:77
SwTwips Width() const
Definition: possiz.hxx:51
bool IsVert() const
Definition: frame.hxx:1372
tools::Long GetLeft(const SwRect &rRect) const
Definition: frame.hxx:1384
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
void Width(tools::Long nNew)
Definition: swrect.hxx:189
TextFrameIndex GetModelPositionForViewPoint(SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState *=nullptr) const
Definition: itrcrsr.cxx:1322
void GetCharRect(SwRect *, TextFrameIndex, SwCursorMoveState *=nullptr, const tools::Long nMax=0)
Definition: itrcrsr.cxx:1224
bool IsFilled(const sal_uInt8 nPercent) const
Definition: frminf.cxx:74
const SwTextFrame * m_pFrame
Definition: frminf.hxx:34
bool IsOneLine() const
Definition: frminf.cxx:53
SwTwips GetFirstIndent() const
Definition: frminf.cxx:205
void GetSpaces(std::vector< std::pair< TextFrameIndex, TextFrameIndex > > &, bool bWithLineBreak) const
Definition: frminf.cxx:154
SwTwips GetLineStart() const
Definition: frminf.cxx:99
sal_Int32 GetBigIndent(TextFrameIndex &rFndPos, const SwTextFrame *pNextFrame) const
Definition: frminf.cxx:237
SwTwips GetCharPos(TextFrameIndex nChar, bool bCenter=true) const
Definition: frminf.cxx:107
bool IsBullet(TextFrameIndex nTextPos) const
Definition: frminf.cxx:193
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:168
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:889
SwParaPortion * GetPara()
Definition: txtcache.cxx:90
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout.
Definition: txtfrm.cxx:473
TextFrameIndex GetEnd() const
Definition: itrtxt.hxx:89
SwTwips Y() const
Definition: itrtxt.hxx:90
const SwLineLayout * GetNext() const
Definition: itrtxt.hxx:84
TextFrameIndex GetStart() const
Definition: itrtxt.hxx:88
SwLineLayout * m_pCurr
Definition: itrtxt.hxx:36
const SwLineLayout * Next()
Definition: itrtxt.cxx:108
const SwLineLayout * GetCurr() const
Definition: itrtxt.hxx:83
const SwLineLayout * Prev()
Definition: itrtxt.cxx:90
TextFrameIndex m_nStart
Definition: itrtxt.hxx:41
SwTextSizeInfo & GetInfo()
Definition: itrtxt.hxx:216
TextFrameIndex GetTextStart() const
Definition: frminf.cxx:25
TextFrameIndex GetTextEnd() const
Definition: frminf.cxx:39
SwTwips GetLineStart() const
Definition: itrcrsr.cxx:379
void SetIdx(const TextFrameIndex nNew)
Definition: inftxt.hxx:274
sal_Unicode GetChar(TextFrameIndex const nPos) const
Definition: inftxt.hxx:241
const OUString & GetText() const
Definition: inftxt.hxx:240
bool HasHint(TextFrameIndex nPos) const
Definition: inftxt.cxx:488
static void AddRange(std::vector< std::pair< TextFrameIndex, TextFrameIndex > > &rRanges, TextFrameIndex const nPos, TextFrameIndex const nLen)
Definition: frminf.cxx:136
#define CH_TXTATR_INWORD
Definition: hintids.hxx:175
#define CH_TXTATR_BREAKWORD
Definition: hintids.hxx:174
sal_uInt16 nPos
int i
long Long
const sal_Unicode CH_TAB
Definition: swfont.hxx:44
const sal_Unicode CH_BREAK
Definition: swfont.hxx:43
tools::Long SwTwips
Definition: swtypes.hxx:51
unsigned char sal_uInt8
sal_uInt16 sal_Unicode