Line data Source code
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 <txatritr.hxx>
21 :
22 : #include <com/sun/star/i18n/ScriptType.hpp>
23 : #include <fchrfmt.hxx>
24 : #include <charfmt.hxx>
25 : #include <breakit.hxx>
26 : #include <ndtxt.hxx>
27 : #include <txatbase.hxx>
28 :
29 : using namespace ::com::sun::star;
30 :
31 8 : SwScriptIterator::SwScriptIterator(
32 : const OUString& rStr, sal_Int32 nStt, bool const bFrwrd)
33 : : m_rText(rStr)
34 8 : , m_nChgPos(rStr.getLength())
35 : , nCurScript(i18n::ScriptType::WEAK)
36 16 : , bForward(bFrwrd)
37 : {
38 8 : if( g_pBreakIt->GetBreakIter().is() )
39 : {
40 8 : if ( ! bFrwrd && nStt )
41 0 : --nStt;
42 :
43 8 : sal_Int32 nPos = nStt;
44 8 : nCurScript = g_pBreakIt->GetBreakIter()->getScriptType(m_rText, nPos);
45 8 : if( i18n::ScriptType::WEAK == nCurScript )
46 : {
47 2 : if( nPos )
48 : {
49 4 : nPos = g_pBreakIt->GetBreakIter()->beginOfScript(
50 2 : m_rText, nPos, nCurScript);
51 2 : if (nPos > 0 && nPos < m_rText.getLength())
52 : {
53 0 : nStt = --nPos;
54 : nCurScript =
55 0 : g_pBreakIt->GetBreakIter()->getScriptType(m_rText,nPos);
56 : }
57 : }
58 : }
59 :
60 : m_nChgPos = (bForward)
61 32 : ? g_pBreakIt->GetBreakIter()->endOfScript(
62 8 : m_rText, nStt, nCurScript)
63 8 : : g_pBreakIt->GetBreakIter()->beginOfScript(
64 24 : m_rText, nStt, nCurScript);
65 : }
66 8 : }
67 :
68 0 : bool SwScriptIterator::Next()
69 : {
70 0 : bool bRet = false;
71 0 : if( g_pBreakIt->GetBreakIter().is() )
72 : {
73 0 : if (bForward && m_nChgPos >= 0 && m_nChgPos < m_rText.getLength())
74 : {
75 : nCurScript =
76 0 : g_pBreakIt->GetBreakIter()->getScriptType(m_rText, m_nChgPos);
77 0 : m_nChgPos = g_pBreakIt->GetBreakIter()->endOfScript(
78 0 : m_rText, m_nChgPos, nCurScript);
79 0 : bRet = true;
80 : }
81 0 : else if (!bForward && m_nChgPos > 0)
82 : {
83 0 : --m_nChgPos;
84 : nCurScript =
85 0 : g_pBreakIt->GetBreakIter()->getScriptType(m_rText, m_nChgPos);
86 0 : m_nChgPos = g_pBreakIt->GetBreakIter()->beginOfScript(
87 0 : m_rText, m_nChgPos, nCurScript);
88 0 : bRet = true;
89 : }
90 : }
91 : else
92 0 : m_nChgPos = m_rText.getLength();
93 0 : return bRet;
94 : }
95 :
96 8 : SwTextAttrIterator::SwTextAttrIterator( const SwTextNode& rTNd, sal_uInt16 nWhchId,
97 : sal_Int32 nStt,
98 : bool bUseGetWhichOfScript )
99 8 : : aSIter( rTNd.GetText(), nStt ), rTextNd( rTNd ),
100 : pParaItem( 0 ), nAttrPos( 0 ), nChgPos( nStt ), nWhichId( nWhchId ),
101 8 : bIsUseGetWhichOfScript( bUseGetWhichOfScript )
102 : {
103 8 : SearchNextChg();
104 8 : }
105 :
106 3 : bool SwTextAttrIterator::Next()
107 : {
108 3 : bool bRet = false;
109 3 : if (nChgPos < aSIter.GetText().getLength())
110 : {
111 0 : bRet = true;
112 0 : if( !aStack.empty() )
113 : {
114 0 : do {
115 0 : const SwTextAttr* pHt = aStack.front();
116 0 : const sal_Int32 nEndPos = *pHt->End();
117 0 : if( nChgPos >= nEndPos )
118 0 : aStack.pop_front();
119 : else
120 0 : break;
121 0 : } while( !aStack.empty() );
122 : }
123 :
124 0 : if( !aStack.empty() )
125 : {
126 0 : const size_t nSavePos = nAttrPos;
127 0 : SearchNextChg();
128 0 : if( !aStack.empty() )
129 : {
130 0 : const SwTextAttr* pHt = aStack.front();
131 0 : const sal_Int32 nEndPos = *pHt->End();
132 0 : if( nChgPos >= nEndPos )
133 : {
134 0 : nChgPos = nEndPos;
135 0 : nAttrPos = nSavePos;
136 :
137 0 : if( RES_TXTATR_CHARFMT == pHt->Which() )
138 : {
139 : const sal_uInt16 nWId = bIsUseGetWhichOfScript
140 0 : ? GetWhichOfScript( nWhichId, aSIter.GetCurrScript() )
141 0 : : nWhichId;
142 0 : pCurItem = &pHt->GetCharFormat().GetCharFormat()->GetFormatAttr(nWId);
143 : }
144 : else
145 0 : pCurItem = &pHt->GetAttr();
146 :
147 0 : aStack.pop_front();
148 : }
149 : }
150 : }
151 : else
152 0 : SearchNextChg();
153 : }
154 3 : return bRet;
155 : }
156 :
157 0 : void SwTextAttrIterator::AddToStack( const SwTextAttr& rAttr )
158 : {
159 0 : size_t nIns = 0;
160 0 : const sal_Int32 nEndPos = *rAttr.End();
161 0 : for( ; nIns < aStack.size(); ++nIns )
162 0 : if( *aStack[ nIns ]->End() > nEndPos )
163 0 : break;
164 :
165 0 : aStack.insert( aStack.begin() + nIns, &rAttr );
166 0 : }
167 :
168 8 : void SwTextAttrIterator::SearchNextChg()
169 : {
170 8 : sal_uInt16 nWh = 0;
171 8 : if( nChgPos == aSIter.GetScriptChgPos() )
172 : {
173 0 : aSIter.Next();
174 0 : pParaItem = 0;
175 0 : nAttrPos = 0; // must be restart at the beginning, because
176 : // some attributes can start before or inside
177 : // the current scripttype!
178 0 : aStack.clear();
179 : }
180 8 : if( !pParaItem )
181 : {
182 : nWh = bIsUseGetWhichOfScript ?
183 : GetWhichOfScript( nWhichId,
184 8 : aSIter.GetCurrScript() ) : nWhichId;
185 8 : pParaItem = &rTextNd.GetSwAttrSet().Get( nWh );
186 : }
187 :
188 8 : sal_Int32 nStt = nChgPos;
189 8 : nChgPos = aSIter.GetScriptChgPos();
190 8 : pCurItem = pParaItem;
191 :
192 8 : const SwpHints* pHts = rTextNd.GetpSwpHints();
193 8 : if( pHts )
194 : {
195 0 : if( !nWh )
196 : {
197 : nWh = bIsUseGetWhichOfScript ?
198 : GetWhichOfScript( nWhichId,
199 0 : aSIter.GetCurrScript() ) : nWhichId;
200 : }
201 :
202 0 : const SfxPoolItem* pItem = 0;
203 0 : for( ; nAttrPos < pHts->Count(); ++nAttrPos )
204 : {
205 0 : const SwTextAttr* pHt = (*pHts)[ nAttrPos ];
206 0 : const sal_Int32* pEnd = pHt->End();
207 0 : const sal_Int32 nHtStt = pHt->GetStart();
208 0 : if( nHtStt < nStt && ( !pEnd || *pEnd <= nStt ))
209 0 : continue;
210 :
211 0 : if( nHtStt >= nChgPos )
212 0 : break;
213 :
214 0 : pItem = CharFormat::GetItem( *pHt, nWh );
215 0 : if ( pItem )
216 : {
217 0 : if( nHtStt > nStt )
218 : {
219 0 : if( nChgPos > nHtStt )
220 0 : nChgPos = nHtStt;
221 0 : break;
222 : }
223 0 : AddToStack( *pHt );
224 0 : pCurItem = pItem;
225 0 : if( *pEnd < nChgPos )
226 0 : nChgPos = *pEnd;
227 : }
228 : }
229 : }
230 185 : }
231 :
232 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|