xref: /aoo41x/main/sw/source/core/txtnode/txatritr.cxx (revision 69a74367)
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