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