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