update dev300-m58
[ooovba.git] / sw / source / core / txtnode / txatritr.cxx
blobcb3c9e4666aa04fc9950d2376607aa4899375ca1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: txatritr.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
37 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
38 #include <com/sun/star/i18n/ScriptType.hdl>
39 #endif
40 #include <tools/string.hxx>
41 #include <svx/langitem.hxx>
42 #include <txatritr.hxx>
43 #include <fchrfmt.hxx>
44 #include <charfmt.hxx>
45 #include <breakit.hxx>
46 #include <ndtxt.hxx>
47 #include <txatbase.hxx>
49 using namespace ::com::sun::star::i18n;
52 SwScriptIterator::SwScriptIterator( const String& rStr, xub_StrLen nStt, sal_Bool bFrwrd )
53 : rText( rStr ),
54 nChgPos( rStr.Len() ),
55 nCurScript( ScriptType::WEAK ),
56 bForward( bFrwrd )
58 if( pBreakIt->GetBreakIter().is() )
60 if ( ! bFrwrd && nStt )
61 --nStt;
63 xub_StrLen nPos = nStt;
64 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nPos );
65 if( ScriptType::WEAK == nCurScript )
67 if( nPos )
69 nPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript(
70 rText, nPos, nCurScript );
71 if( nPos && nPos < rText.Len() )
73 nStt = --nPos;
74 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText,nPos);
79 nChgPos = bForward ?
80 (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( rText, nStt, nCurScript ) :
81 (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript( rText, nStt, nCurScript );
85 sal_Bool SwScriptIterator::Next()
87 sal_Bool bRet = sal_False;
88 if( pBreakIt->GetBreakIter().is() )
90 if ( bForward && nChgPos < rText.Len() )
92 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nChgPos );
93 nChgPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript(
94 rText, nChgPos, nCurScript );
95 bRet = sal_True;
97 else if ( ! bForward && nChgPos )
99 --nChgPos;
100 nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nChgPos );
101 nChgPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript(
102 rText, nChgPos, nCurScript );
103 bRet = sal_True;
106 else
107 nChgPos = rText.Len();
108 return bRet;
111 // --------------------------------------------------------------------
113 SwTxtAttrIterator::SwTxtAttrIterator( const SwTxtNode& rTNd, USHORT nWhchId,
114 xub_StrLen nStt,
115 sal_Bool bUseGetWhichOfScript )
116 : aSIter( rTNd.GetTxt(), nStt ), rTxtNd( rTNd ),
117 pParaItem( 0 ), nChgPos( nStt ), nAttrPos( 0 ), nWhichId( nWhchId ),
118 bIsUseGetWhichOfScript( bUseGetWhichOfScript )
120 SearchNextChg();
123 sal_Bool SwTxtAttrIterator::Next()
125 sal_Bool bRet = sal_False;
126 if( nChgPos < aSIter.GetText().Len() )
128 bRet = sal_True;
129 if( aStack.Count() )
131 do {
132 const SwTxtAttr* pHt = (SwTxtAttr*)aStack[ 0 ];
133 USHORT nEndPos = *pHt->GetEnd();
134 if( nChgPos >= nEndPos )
135 aStack.Remove( 0 );
136 else
137 break;
138 } while( aStack.Count() );
141 if( aStack.Count() )
143 sal_uInt16 nSavePos = nAttrPos;
144 SearchNextChg();
145 if( aStack.Count() )
147 const SwTxtAttr* pHt = (SwTxtAttr*)aStack[ 0 ];
148 USHORT nEndPos = *pHt->GetEnd();
149 if( nChgPos >= nEndPos )
151 nChgPos = nEndPos;
152 nAttrPos = nSavePos;
154 if( RES_TXTATR_CHARFMT == pHt->Which() )
156 sal_uInt16 nWId = bIsUseGetWhichOfScript ?
157 GetWhichOfScript( nWhichId,
158 aSIter.GetCurrScript() ) : nWhichId;
159 pCurItem = &pHt->GetCharFmt().GetCharFmt()->GetFmtAttr(nWId);
161 else
162 pCurItem = &pHt->GetAttr();
164 aStack.Remove( 0 );
168 else
169 SearchNextChg();
171 return bRet;
174 void SwTxtAttrIterator::AddToStack( const SwTxtAttr& rAttr )
176 void* pAdd = (void*)&rAttr;
177 USHORT nIns = 0, nEndPos = *rAttr.GetEnd();
178 for( ; nIns < aStack.Count(); ++nIns )
179 if( *((SwTxtAttr*)aStack[ nIns ] )->GetEnd() > nEndPos )
180 break;
182 aStack.Insert( pAdd, nIns );
185 void SwTxtAttrIterator::SearchNextChg()
187 USHORT nWh = 0;
188 if( nChgPos == aSIter.GetScriptChgPos() )
190 aSIter.Next();
191 pParaItem = 0;
192 nAttrPos = 0; // must be restart at the beginning, because
193 // some attributes can start before or inside
194 // the current scripttype!
195 aStack.Remove( 0, aStack.Count() );
197 if( !pParaItem )
199 nWh = bIsUseGetWhichOfScript ?
200 GetWhichOfScript( nWhichId,
201 aSIter.GetCurrScript() ) : nWhichId;
202 pParaItem = &rTxtNd.GetSwAttrSet().Get( nWh );
205 xub_StrLen nStt = nChgPos;
206 nChgPos = aSIter.GetScriptChgPos();
207 pCurItem = pParaItem;
209 const SwpHints* pHts = rTxtNd.GetpSwpHints();
210 if( pHts )
212 if( !nWh )
214 nWh = bIsUseGetWhichOfScript ?
215 GetWhichOfScript( nWhichId,
216 aSIter.GetCurrScript() ) : nWhichId;
219 const SfxPoolItem* pItem = 0;
220 for( ; nAttrPos < pHts->Count(); ++nAttrPos )
222 const SwTxtAttr* pHt = (*pHts)[ nAttrPos ];
223 const USHORT* pEnd = pHt->GetEnd();
224 const USHORT nHtStt = *pHt->GetStart();
225 if( nHtStt < nStt && ( !pEnd || *pEnd <= nStt ))
226 continue;
228 if( nHtStt >= nChgPos )
229 break;
231 pItem = CharFmt::GetItem( *pHt, nWh );
232 if ( pItem )
234 if( nHtStt > nStt )
236 if( nChgPos > nHtStt )
237 nChgPos = nHtStt;
238 break;
240 AddToStack( *pHt );
241 pCurItem = pItem;
242 if( *pEnd < nChgPos )
243 nChgPos = *pEnd;