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