Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <txatritr.hxx>
21 :
22 : #include <com/sun/star/i18n/ScriptType.hpp>
23 : #include <fchrfmt.hxx>
24 : #include <charfmt.hxx>
25 : #include <breakit.hxx>
26 : #include <ndtxt.hxx>
27 : #include <txatbase.hxx>
28 :
29 : using namespace ::com::sun::star;
30 :
31 0 : SwScriptIterator::SwScriptIterator(
32 : const OUString& rStr, sal_Int32 nStt, bool const bFrwrd)
33 : : m_rText(rStr)
34 0 : , m_nChgPos(rStr.getLength())
35 : , nCurScript(i18n::ScriptType::WEAK)
36 0 : , bForward(bFrwrd)
37 : {
38 0 : if( g_pBreakIt->GetBreakIter().is() )
39 : {
40 0 : if ( ! bFrwrd && nStt )
41 0 : --nStt;
42 :
43 0 : sal_Int32 nPos = nStt;
44 0 : nCurScript = g_pBreakIt->GetBreakIter()->getScriptType(m_rText, nPos);
45 0 : if( i18n::ScriptType::WEAK == nCurScript )
46 : {
47 0 : if( nPos )
48 : {
49 0 : nPos = g_pBreakIt->GetBreakIter()->beginOfScript(
50 0 : m_rText, nPos, nCurScript);
51 0 : if (nPos > 0 && nPos < m_rText.getLength())
52 : {
53 0 : nStt = --nPos;
54 : nCurScript =
55 0 : g_pBreakIt->GetBreakIter()->getScriptType(m_rText,nPos);
56 : }
57 : }
58 : }
59 :
60 : m_nChgPos = (bForward)
61 0 : ? g_pBreakIt->GetBreakIter()->endOfScript(
62 0 : m_rText, nStt, nCurScript)
63 0 : : g_pBreakIt->GetBreakIter()->beginOfScript(
64 0 : m_rText, nStt, nCurScript);
65 : }
66 0 : }
67 :
68 0 : bool SwScriptIterator::Next()
69 : {
70 0 : bool bRet = false;
71 0 : if( g_pBreakIt->GetBreakIter().is() )
72 : {
73 0 : if (bForward && m_nChgPos >= 0 && m_nChgPos < m_rText.getLength())
74 : {
75 : nCurScript =
76 0 : g_pBreakIt->GetBreakIter()->getScriptType(m_rText, m_nChgPos);
77 0 : m_nChgPos = g_pBreakIt->GetBreakIter()->endOfScript(
78 0 : m_rText, m_nChgPos, nCurScript);
79 0 : bRet = true;
80 : }
81 0 : else if (!bForward && m_nChgPos > 0)
82 : {
83 0 : --m_nChgPos;
84 : nCurScript =
85 0 : g_pBreakIt->GetBreakIter()->getScriptType(m_rText, m_nChgPos);
86 0 : m_nChgPos = g_pBreakIt->GetBreakIter()->beginOfScript(
87 0 : m_rText, m_nChgPos, nCurScript);
88 0 : bRet = true;
89 : }
90 : }
91 : else
92 0 : m_nChgPos = m_rText.getLength();
93 0 : return bRet;
94 : }
95 :
96 0 : SwTxtAttrIterator::SwTxtAttrIterator( const SwTxtNode& rTNd, sal_uInt16 nWhchId,
97 : sal_Int32 nStt,
98 : bool bUseGetWhichOfScript )
99 0 : : aSIter( rTNd.GetTxt(), nStt ), rTxtNd( rTNd ),
100 : pParaItem( 0 ), nChgPos( nStt ), nAttrPos( 0 ), nWhichId( nWhchId ),
101 0 : bIsUseGetWhichOfScript( bUseGetWhichOfScript )
102 : {
103 0 : SearchNextChg();
104 0 : }
105 :
106 0 : bool SwTxtAttrIterator::Next()
107 : {
108 0 : bool bRet = false;
109 0 : if (nChgPos < aSIter.GetText().getLength())
110 : {
111 0 : bRet = true;
112 0 : if( !aStack.empty() )
113 : {
114 0 : do {
115 0 : const SwTxtAttr* pHt = aStack.front();
116 0 : sal_uInt16 nEndPos = *pHt->End();
117 0 : if( nChgPos >= nEndPos )
118 0 : aStack.pop_front();
119 : else
120 0 : break;
121 0 : } while( !aStack.empty() );
122 : }
123 :
124 0 : if( !aStack.empty() )
125 : {
126 0 : sal_uInt16 nSavePos = nAttrPos;
127 0 : SearchNextChg();
128 0 : if( !aStack.empty() )
129 : {
130 0 : const SwTxtAttr* pHt = aStack.front();
131 0 : const sal_uInt16 nEndPos = *pHt->End();
132 0 : if( nChgPos >= nEndPos )
133 : {
134 0 : nChgPos = nEndPos;
135 0 : nAttrPos = nSavePos;
136 :
137 0 : if( RES_TXTATR_CHARFMT == pHt->Which() )
138 : {
139 : sal_uInt16 nWId = bIsUseGetWhichOfScript ?
140 : GetWhichOfScript( nWhichId,
141 0 : aSIter.GetCurrScript() ) : nWhichId;
142 0 : pCurItem = &pHt->GetCharFmt().GetCharFmt()->GetFmtAttr(nWId);
143 : }
144 : else
145 0 : pCurItem = &pHt->GetAttr();
146 :
147 0 : aStack.pop_front();
148 : }
149 : }
150 : }
151 : else
152 0 : SearchNextChg();
153 : }
154 0 : return bRet;
155 : }
156 :
157 0 : void SwTxtAttrIterator::AddToStack( const SwTxtAttr& rAttr )
158 : {
159 0 : sal_uInt16 nIns = 0, nEndPos = *rAttr.End();
160 0 : for( ; nIns < aStack.size(); ++nIns )
161 0 : if( *aStack[ nIns ]->End() > nEndPos )
162 0 : break;
163 :
164 0 : aStack.insert( aStack.begin() + nIns, &rAttr );
165 0 : }
166 :
167 0 : void SwTxtAttrIterator::SearchNextChg()
168 : {
169 0 : sal_uInt16 nWh = 0;
170 0 : if( nChgPos == aSIter.GetScriptChgPos() )
171 : {
172 0 : aSIter.Next();
173 0 : pParaItem = 0;
174 0 : nAttrPos = 0; // must be restart at the beginning, because
175 : // some attributes can start before or inside
176 : // the current scripttype!
177 0 : aStack.clear();
178 : }
179 0 : if( !pParaItem )
180 : {
181 : nWh = bIsUseGetWhichOfScript ?
182 : GetWhichOfScript( nWhichId,
183 0 : aSIter.GetCurrScript() ) : nWhichId;
184 0 : pParaItem = &rTxtNd.GetSwAttrSet().Get( nWh );
185 : }
186 :
187 0 : sal_Int32 nStt = nChgPos;
188 0 : nChgPos = aSIter.GetScriptChgPos();
189 0 : pCurItem = pParaItem;
190 :
191 0 : const SwpHints* pHts = rTxtNd.GetpSwpHints();
192 0 : if( pHts )
193 : {
194 0 : if( !nWh )
195 : {
196 : nWh = bIsUseGetWhichOfScript ?
197 : GetWhichOfScript( nWhichId,
198 0 : aSIter.GetCurrScript() ) : nWhichId;
199 : }
200 :
201 0 : const SfxPoolItem* pItem = 0;
202 0 : for( ; nAttrPos < pHts->Count(); ++nAttrPos )
203 : {
204 0 : const SwTxtAttr* pHt = (*pHts)[ nAttrPos ];
205 0 : const sal_Int32* pEnd = pHt->End();
206 0 : const sal_Int32 nHtStt = *pHt->GetStart();
207 0 : if( nHtStt < nStt && ( !pEnd || *pEnd <= nStt ))
208 0 : continue;
209 :
210 0 : if( nHtStt >= nChgPos )
211 0 : break;
212 :
213 0 : pItem = CharFmt::GetItem( *pHt, nWh );
214 0 : if ( pItem )
215 : {
216 0 : if( nHtStt > nStt )
217 : {
218 0 : if( nChgPos > nHtStt )
219 0 : nChgPos = nHtStt;
220 0 : break;
221 : }
222 0 : AddToStack( *pHt );
223 0 : pCurItem = pItem;
224 0 : if( *pEnd < nChgPos )
225 0 : nChgPos = *pEnd;
226 : }
227 : }
228 : }
229 0 : }
230 :
231 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|