1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <txatritr.hxx>
22 #include <com/sun/star/i18n/ScriptType.hpp>
23 #include <com/sun/star/i18n/XBreakIterator.hpp>
24 #include <fchrfmt.hxx>
25 #include <charfmt.hxx>
26 #include <breakit.hxx>
28 #include <txatbase.hxx>
30 using namespace ::com::sun::star
;
32 SwScriptIterator::SwScriptIterator(
33 const OUString
& rStr
, sal_Int32 nStt
, bool const bFrwrd
)
35 , m_nChgPos(rStr
.getLength())
36 , m_nCurScript(i18n::ScriptType::WEAK
)
39 assert(g_pBreakIt
&& g_pBreakIt
->GetBreakIter().is());
40 if ( ! bFrwrd
&& nStt
)
43 sal_Int32 nPos
= nStt
;
44 m_nCurScript
= g_pBreakIt
->GetBreakIter()->getScriptType(m_rText
, nPos
);
45 if( i18n::ScriptType::WEAK
== m_nCurScript
)
49 nPos
= g_pBreakIt
->GetBreakIter()->beginOfScript(
50 m_rText
, nPos
, m_nCurScript
);
51 if (nPos
> 0 && nPos
< m_rText
.getLength())
55 g_pBreakIt
->GetBreakIter()->getScriptType(m_rText
,nPos
);
60 m_nChgPos
= m_bForward
61 ? g_pBreakIt
->GetBreakIter()->endOfScript(
62 m_rText
, nStt
, m_nCurScript
)
63 : g_pBreakIt
->GetBreakIter()->beginOfScript(
64 m_rText
, nStt
, m_nCurScript
);
67 void SwScriptIterator::Next()
69 assert(g_pBreakIt
&& g_pBreakIt
->GetBreakIter().is());
70 if (m_bForward
&& m_nChgPos
>= 0 && m_nChgPos
< m_rText
.getLength())
73 g_pBreakIt
->GetBreakIter()->getScriptType(m_rText
, m_nChgPos
);
74 m_nChgPos
= g_pBreakIt
->GetBreakIter()->endOfScript(
75 m_rText
, m_nChgPos
, m_nCurScript
);
77 else if (!m_bForward
&& m_nChgPos
> 0)
81 g_pBreakIt
->GetBreakIter()->getScriptType(m_rText
, m_nChgPos
);
82 m_nChgPos
= g_pBreakIt
->GetBreakIter()->beginOfScript(
83 m_rText
, m_nChgPos
, m_nCurScript
);
87 SwLanguageIterator::SwLanguageIterator( const SwTextNode
& rTNd
,
89 : m_aScriptIter( rTNd
.GetText(), nStt
),
91 m_pParaItem( nullptr ),
98 bool SwLanguageIterator::Next()
101 if (m_nChgPos
< m_aScriptIter
.GetText().getLength())
104 if( !m_aStack
.empty() )
107 const SwTextAttr
* pHt
= m_aStack
.front();
108 const sal_Int32 nEndPos
= *pHt
->End();
109 if( m_nChgPos
>= nEndPos
)
110 m_aStack
.pop_front();
113 } while( !m_aStack
.empty() );
116 if( !m_aStack
.empty() )
118 const size_t nSavePos
= m_nAttrPos
;
120 if( !m_aStack
.empty() )
122 const SwTextAttr
* pHt
= m_aStack
.front();
123 const sal_Int32 nEndPos
= *pHt
->End();
124 if( m_nChgPos
>= nEndPos
)
127 m_nAttrPos
= nSavePos
;
129 if( RES_TXTATR_CHARFMT
== pHt
->Which() )
131 const sal_uInt16 nWId
= GetWhichOfScript( RES_CHRATR_LANGUAGE
, m_aScriptIter
.GetCurrScript() );
132 m_pCurrentItem
= &pHt
->GetCharFormat().GetCharFormat()->GetFormatAttr(nWId
);
135 m_pCurrentItem
= &pHt
->GetAttr();
137 m_aStack
.pop_front();
147 void SwLanguageIterator::AddToStack( const SwTextAttr
& rAttr
)
150 const sal_Int32 nEndPos
= *rAttr
.End();
151 for( ; nIns
< m_aStack
.size(); ++nIns
)
152 if( *m_aStack
[ nIns
]->End() > nEndPos
)
155 m_aStack
.insert( m_aStack
.begin() + nIns
, &rAttr
);
158 void SwLanguageIterator::SearchNextChg()
161 if( m_nChgPos
== m_aScriptIter
.GetScriptChgPos() )
163 m_aScriptIter
.Next();
164 m_pParaItem
= nullptr;
165 m_nAttrPos
= 0; // must be restart at the beginning, because
166 // some attributes can start before or inside
167 // the current scripttype!
172 nWh
= GetWhichOfScript( RES_CHRATR_LANGUAGE
, m_aScriptIter
.GetCurrScript() );
173 m_pParaItem
= &m_rTextNode
.GetSwAttrSet().Get( nWh
);
176 sal_Int32 nStt
= m_nChgPos
;
177 m_nChgPos
= m_aScriptIter
.GetScriptChgPos();
178 m_pCurrentItem
= m_pParaItem
;
180 const SwpHints
* pHts
= m_rTextNode
.GetpSwpHints();
186 nWh
= GetWhichOfScript( RES_CHRATR_LANGUAGE
, m_aScriptIter
.GetCurrScript() );
189 const SfxPoolItem
* pItem
= nullptr;
190 for( ; m_nAttrPos
< pHts
->Count(); ++m_nAttrPos
)
192 const SwTextAttr
* pHt
= pHts
->Get( m_nAttrPos
);
193 const sal_Int32
* pEnd
= pHt
->End();
194 const sal_Int32 nHtStt
= pHt
->GetStart();
195 if( nHtStt
< nStt
&& ( !pEnd
|| *pEnd
<= nStt
))
198 if( nHtStt
>= m_nChgPos
)
201 pItem
= CharFormat::GetItem( *pHt
, nWh
);
206 if( m_nChgPos
> nHtStt
)
211 m_pCurrentItem
= pItem
;
212 if( *pEnd
< m_nChgPos
)
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */