1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26
27
28 #include <hintids.hxx>
29
30 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
31 #include <com/sun/star/i18n/ScriptType.hdl>
32 #endif
33 #include <tools/string.hxx>
34 #include <editeng/langitem.hxx>
35 #include <txatritr.hxx>
36 #include <fchrfmt.hxx>
37 #include <charfmt.hxx>
38 #include <breakit.hxx>
39 #include <ndtxt.hxx>
40 #include <txatbase.hxx>
41
42 using namespace ::com::sun::star::i18n;
43
44
SwScriptIterator(const String & rStr,xub_StrLen nStt,sal_Bool bFrwrd)45 SwScriptIterator::SwScriptIterator( const String& rStr, xub_StrLen nStt, sal_Bool bFrwrd )
46 : rText( rStr ),
47 nChgPos( rStr.Len() ),
48 nCurScript( ScriptType::WEAK ),
49 bForward( bFrwrd )
50 {
51 if( pBreakIt->GetBreakIter().is() )
52 {
53 if ( ! bFrwrd && nStt )
54 --nStt;
55
56 xub_StrLen nPos = nStt;
57 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nPos );
58 if( ScriptType::WEAK == nCurScript )
59 {
60 if( nPos )
61 {
62 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript(
63 rText, nPos, nCurScript );
64 if( nPos && nPos < rText.Len() )
65 {
66 nStt = --nPos;
67 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText,nPos);
68 }
69 }
70 }
71
72 nChgPos = bForward ?
73 (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( rText, nStt, nCurScript ) :
74 (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript( rText, nStt, nCurScript );
75 }
76 }
77
Next()78 sal_Bool SwScriptIterator::Next()
79 {
80 sal_Bool bRet = sal_False;
81 if( pBreakIt->GetBreakIter().is() )
82 {
83 if ( bForward && nChgPos < rText.Len() )
84 {
85 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nChgPos );
86 nChgPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript(
87 rText, nChgPos, nCurScript );
88 bRet = sal_True;
89 }
90 else if ( ! bForward && nChgPos )
91 {
92 --nChgPos;
93 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nChgPos );
94 nChgPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript(
95 rText, nChgPos, nCurScript );
96 bRet = sal_True;
97 }
98 }
99 else
100 nChgPos = rText.Len();
101 return bRet;
102 }
103
104 // --------------------------------------------------------------------
105
SwTxtAttrIterator(const SwTxtNode & rTNd,sal_uInt16 nWhchId,xub_StrLen nStt,sal_Bool bUseGetWhichOfScript)106 SwTxtAttrIterator::SwTxtAttrIterator( const SwTxtNode& rTNd, sal_uInt16 nWhchId,
107 xub_StrLen nStt,
108 sal_Bool bUseGetWhichOfScript )
109 : aSIter( rTNd.GetTxt(), nStt ), rTxtNd( rTNd ),
110 pParaItem( 0 ), nChgPos( nStt ), nAttrPos( 0 ), nWhichId( nWhchId ),
111 bIsUseGetWhichOfScript( bUseGetWhichOfScript )
112 {
113 SearchNextChg();
114 }
115
Next()116 sal_Bool SwTxtAttrIterator::Next()
117 {
118 sal_Bool bRet = sal_False;
119 if( nChgPos < aSIter.GetText().Len() )
120 {
121 bRet = sal_True;
122 if( aStack.Count() )
123 {
124 do {
125 const SwTxtAttr* pHt = (SwTxtAttr*)aStack[ 0 ];
126 const sal_uInt16 nEndPos = *pHt->End();
127 if( nChgPos >= nEndPos )
128 aStack.Remove( 0 );
129 else
130 break;
131 } while( aStack.Count() );
132 }
133
134 if( aStack.Count() )
135 {
136 sal_uInt16 nSavePos = nAttrPos;
137 SearchNextChg();
138 if( aStack.Count() )
139 {
140 const SwTxtAttr* pHt = (SwTxtAttr*)aStack[ 0 ];
141 const sal_uInt16 nEndPos = *pHt->End();
142 if( nChgPos >= nEndPos )
143 {
144 nChgPos = nEndPos;
145 nAttrPos = nSavePos;
146
147 if( RES_TXTATR_CHARFMT == pHt->Which() )
148 {
149 sal_uInt16 nWId = bIsUseGetWhichOfScript ?
150 GetWhichOfScript( nWhichId,
151 aSIter.GetCurrScript() ) : nWhichId;
152 pCurItem = &pHt->GetCharFmt().GetCharFmt()->GetFmtAttr(nWId);
153 }
154 else
155 pCurItem = &pHt->GetAttr();
156
157 aStack.Remove( 0 );
158 }
159 }
160 }
161 else
162 SearchNextChg();
163 }
164 return bRet;
165 }
166
AddToStack(const SwTxtAttr & rAttr)167 void SwTxtAttrIterator::AddToStack( const SwTxtAttr& rAttr )
168 {
169 void* pAdd = (void*)&rAttr;
170 sal_uInt16 nIns = 0, nEndPos = *rAttr.End();
171 for( ; nIns < aStack.Count(); ++nIns )
172 if( *((SwTxtAttr*)aStack[ nIns ] )->GetEnd() > nEndPos )
173 break;
174
175 aStack.Insert( pAdd, nIns );
176 }
177
SearchNextChg()178 void SwTxtAttrIterator::SearchNextChg()
179 {
180 sal_uInt16 nWh = 0;
181 if( nChgPos == aSIter.GetScriptChgPos() )
182 {
183 aSIter.Next();
184 pParaItem = 0;
185 nAttrPos = 0; // must be restart at the beginning, because
186 // some attributes can start before or inside
187 // the current scripttype!
188 aStack.Remove( 0, aStack.Count() );
189 }
190 if( !pParaItem )
191 {
192 nWh = bIsUseGetWhichOfScript ?
193 GetWhichOfScript( nWhichId,
194 aSIter.GetCurrScript() ) : nWhichId;
195 pParaItem = &rTxtNd.GetSwAttrSet().Get( nWh );
196 }
197
198 xub_StrLen nStt = nChgPos;
199 nChgPos = aSIter.GetScriptChgPos();
200 pCurItem = pParaItem;
201
202 const SwpHints* pHts = rTxtNd.GetpSwpHints();
203 if( pHts )
204 {
205 if( !nWh )
206 {
207 nWh = bIsUseGetWhichOfScript ?
208 GetWhichOfScript( nWhichId,
209 aSIter.GetCurrScript() ) : nWhichId;
210 }
211
212 const SfxPoolItem* pItem = 0;
213 for( ; nAttrPos < pHts->Count(); ++nAttrPos )
214 {
215 const SwTxtAttr* pHt = (*pHts)[ nAttrPos ];
216 const sal_uInt16* pEnd = pHt->End();
217 const sal_uInt16 nHtStt = *pHt->GetStart();
218 if( nHtStt < nStt && ( !pEnd || *pEnd <= nStt ))
219 continue;
220
221 if( nHtStt >= nChgPos )
222 break;
223
224 pItem = CharFmt::GetItem( *pHt, nWh );
225 if ( pItem )
226 {
227 if( nHtStt > nStt )
228 {
229 if( nChgPos > nHtStt )
230 nChgPos = nHtStt;
231 break;
232 }
233 AddToStack( *pHt );
234 pCurItem = pItem;
235 if( *pEnd < nChgPos )
236 nChgPos = *pEnd;
237 }
238 }
239 }
240 }
241
242
243