LibreOffice Module vcl (master)  1
ImplLayoutRuns.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 <ImplLayoutRuns.hxx>
21 
22 void ImplLayoutRuns::AddPos( int nCharPos, bool bRTL )
23 {
24  // check if charpos could extend current run
25  int nIndex = maRuns.size();
26  if( nIndex >= 2 )
27  {
28  int nRunPos0 = maRuns[ nIndex-2 ];
29  int nRunPos1 = maRuns[ nIndex-1 ];
30  if( ((nCharPos + int(bRTL)) == nRunPos1) && ((nRunPos0 > nRunPos1) == bRTL) )
31  {
32  // extend current run by new charpos
33  maRuns[ nIndex-1 ] = nCharPos + int(!bRTL);
34  return;
35  }
36  // ignore new charpos when it is in current run
37  if( (nRunPos0 <= nCharPos) && (nCharPos < nRunPos1) )
38  return;
39  if( (nRunPos1 <= nCharPos) && (nCharPos < nRunPos0) )
40  return;
41  }
42 
43  // else append a new run consisting of the new charpos
44  maRuns.push_back( nCharPos + (bRTL ? 1 : 0) );
45  maRuns.push_back( nCharPos + (bRTL ? 0 : 1) );
46 }
47 
48 void ImplLayoutRuns::AddRun( int nCharPos0, int nCharPos1, bool bRTL )
49 {
50  if( nCharPos0 == nCharPos1 )
51  return;
52 
53  // swap if needed
54  if( bRTL == (nCharPos0 < nCharPos1) )
55  {
56  int nTemp = nCharPos0;
57  nCharPos0 = nCharPos1;
58  nCharPos1 = nTemp;
59  }
60 
61  if (maRuns.size() >= 2 && nCharPos0 == maRuns[maRuns.size() - 2] && nCharPos1 == maRuns[maRuns.size() - 1])
62  {
63  //this run is the same as the last
64  return;
65  }
66 
67  // append new run
68  maRuns.push_back( nCharPos0 );
69  maRuns.push_back( nCharPos1 );
70 }
71 
72 bool ImplLayoutRuns::PosIsInRun( int nCharPos ) const
73 {
74  if( mnRunIndex >= static_cast<int>(maRuns.size()) )
75  return false;
76 
77  int nMinCharPos = maRuns[ mnRunIndex+0 ];
78  int nEndCharPos = maRuns[ mnRunIndex+1 ];
79  if( nMinCharPos > nEndCharPos ) // reversed in RTL case
80  {
81  int nTemp = nMinCharPos;
82  nMinCharPos = nEndCharPos;
83  nEndCharPos = nTemp;
84  }
85 
86  if( nCharPos < nMinCharPos )
87  return false;
88  if( nCharPos >= nEndCharPos )
89  return false;
90  return true;
91 }
92 
93 bool ImplLayoutRuns::PosIsInAnyRun( int nCharPos ) const
94 {
95  bool bRet = false;
96  int nRunIndex = mnRunIndex;
97 
98  ImplLayoutRuns *pThis = const_cast<ImplLayoutRuns*>(this);
99 
100  pThis->ResetPos();
101 
102  for (size_t i = 0; i < maRuns.size(); i+=2)
103  {
104  bRet = PosIsInRun( nCharPos );
105  if( bRet )
106  break;
107  pThis->NextRun();
108  }
109 
110  pThis->mnRunIndex = nRunIndex;
111  return bRet;
112 }
113 
114 bool ImplLayoutRuns::GetNextPos( int* nCharPos, bool* bRightToLeft )
115 {
116  // negative nCharPos => reset to first run
117  if( *nCharPos < 0 )
118  mnRunIndex = 0;
119 
120  // return false when all runs completed
121  if( mnRunIndex >= static_cast<int>(maRuns.size()) )
122  return false;
123 
124  int nRunPos0 = maRuns[ mnRunIndex+0 ];
125  int nRunPos1 = maRuns[ mnRunIndex+1 ];
126  *bRightToLeft = (nRunPos0 > nRunPos1);
127 
128  if( *nCharPos < 0 )
129  {
130  // get first valid nCharPos in run
131  *nCharPos = nRunPos0;
132  }
133  else
134  {
135  // advance to next nCharPos for LTR case
136  if( !*bRightToLeft )
137  ++(*nCharPos);
138 
139  // advance to next run if current run is completed
140  if( *nCharPos == nRunPos1 )
141  {
142  if( (mnRunIndex += 2) >= static_cast<int>(maRuns.size()) )
143  return false;
144  nRunPos0 = maRuns[ mnRunIndex+0 ];
145  nRunPos1 = maRuns[ mnRunIndex+1 ];
146  *bRightToLeft = (nRunPos0 > nRunPos1);
147  *nCharPos = nRunPos0;
148  }
149  }
150 
151  // advance to next nCharPos for RTL case
152  if( *bRightToLeft )
153  --(*nCharPos);
154 
155  return true;
156 }
157 
158 bool ImplLayoutRuns::GetRun( int* nMinRunPos, int* nEndRunPos, bool* bRightToLeft ) const
159 {
160  if( mnRunIndex >= static_cast<int>(maRuns.size()) )
161  return false;
162 
163  int nRunPos0 = maRuns[ mnRunIndex+0 ];
164  int nRunPos1 = maRuns[ mnRunIndex+1 ];
165  *bRightToLeft = (nRunPos1 < nRunPos0) ;
166  if( !*bRightToLeft )
167  {
168  *nMinRunPos = nRunPos0;
169  *nEndRunPos = nRunPos1;
170  }
171  else
172  {
173  *nMinRunPos = nRunPos1;
174  *nEndRunPos = nRunPos0;
175  }
176  return true;
177 }
178 
179 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nIndex
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
std::vector< int > maRuns
void AddPos(int nCharPos, bool bRTL)
int i
bool PosIsInRun(int nCharPos) const
bool GetNextPos(int *nCharPos, bool *bRTL)
bool GetRun(int *nMinRunPos, int *nEndRunPos, bool *bRTL) const
void AddRun(int nMinRunPos, int nEndRunPos, bool bRTL)
bool PosIsInAnyRun(int nCharPos) const