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