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