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