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