| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| |
| #include <hintids.hxx> |
| |
| #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_ |
| #include <com/sun/star/i18n/ScriptType.hdl> |
| #endif |
| #include <tools/string.hxx> |
| #include <editeng/langitem.hxx> |
| #include <txatritr.hxx> |
| #include <fchrfmt.hxx> |
| #include <charfmt.hxx> |
| #include <breakit.hxx> |
| #include <ndtxt.hxx> |
| #include <txatbase.hxx> |
| |
| using namespace ::com::sun::star::i18n; |
| |
| |
| SwScriptIterator::SwScriptIterator( const String& rStr, xub_StrLen nStt, sal_Bool bFrwrd ) |
| : rText( rStr ), |
| nChgPos( rStr.Len() ), |
| nCurScript( ScriptType::WEAK ), |
| bForward( bFrwrd ) |
| { |
| if( pBreakIt->GetBreakIter().is() ) |
| { |
| if ( ! bFrwrd && nStt ) |
| --nStt; |
| |
| xub_StrLen nPos = nStt; |
| nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nPos ); |
| if( ScriptType::WEAK == nCurScript ) |
| { |
| if( nPos ) |
| { |
| nPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript( |
| rText, nPos, nCurScript ); |
| if( nPos && nPos < rText.Len() ) |
| { |
| nStt = --nPos; |
| nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText,nPos); |
| } |
| } |
| } |
| |
| nChgPos = bForward ? |
| (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( rText, nStt, nCurScript ) : |
| (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript( rText, nStt, nCurScript ); |
| } |
| } |
| |
| sal_Bool SwScriptIterator::Next() |
| { |
| sal_Bool bRet = sal_False; |
| if( pBreakIt->GetBreakIter().is() ) |
| { |
| if ( bForward && nChgPos < rText.Len() ) |
| { |
| nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nChgPos ); |
| nChgPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( |
| rText, nChgPos, nCurScript ); |
| bRet = sal_True; |
| } |
| else if ( ! bForward && nChgPos ) |
| { |
| --nChgPos; |
| nCurScript = pBreakIt->GetBreakIter()->getScriptType( rText, nChgPos ); |
| nChgPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfScript( |
| rText, nChgPos, nCurScript ); |
| bRet = sal_True; |
| } |
| } |
| else |
| nChgPos = rText.Len(); |
| return bRet; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| SwTxtAttrIterator::SwTxtAttrIterator( const SwTxtNode& rTNd, sal_uInt16 nWhchId, |
| xub_StrLen nStt, |
| sal_Bool bUseGetWhichOfScript ) |
| : aSIter( rTNd.GetTxt(), nStt ), rTxtNd( rTNd ), |
| pParaItem( 0 ), nChgPos( nStt ), nAttrPos( 0 ), nWhichId( nWhchId ), |
| bIsUseGetWhichOfScript( bUseGetWhichOfScript ) |
| { |
| SearchNextChg(); |
| } |
| |
| sal_Bool SwTxtAttrIterator::Next() |
| { |
| sal_Bool bRet = sal_False; |
| if( nChgPos < aSIter.GetText().Len() ) |
| { |
| bRet = sal_True; |
| if( aStack.Count() ) |
| { |
| do { |
| const SwTxtAttr* pHt = (SwTxtAttr*)aStack[ 0 ]; |
| const sal_uInt16 nEndPos = *pHt->End(); |
| if( nChgPos >= nEndPos ) |
| aStack.Remove( 0 ); |
| else |
| break; |
| } while( aStack.Count() ); |
| } |
| |
| if( aStack.Count() ) |
| { |
| sal_uInt16 nSavePos = nAttrPos; |
| SearchNextChg(); |
| if( aStack.Count() ) |
| { |
| const SwTxtAttr* pHt = (SwTxtAttr*)aStack[ 0 ]; |
| const sal_uInt16 nEndPos = *pHt->End(); |
| if( nChgPos >= nEndPos ) |
| { |
| nChgPos = nEndPos; |
| nAttrPos = nSavePos; |
| |
| if( RES_TXTATR_CHARFMT == pHt->Which() ) |
| { |
| sal_uInt16 nWId = bIsUseGetWhichOfScript ? |
| GetWhichOfScript( nWhichId, |
| aSIter.GetCurrScript() ) : nWhichId; |
| pCurItem = &pHt->GetCharFmt().GetCharFmt()->GetFmtAttr(nWId); |
| } |
| else |
| pCurItem = &pHt->GetAttr(); |
| |
| aStack.Remove( 0 ); |
| } |
| } |
| } |
| else |
| SearchNextChg(); |
| } |
| return bRet; |
| } |
| |
| void SwTxtAttrIterator::AddToStack( const SwTxtAttr& rAttr ) |
| { |
| void* pAdd = (void*)&rAttr; |
| sal_uInt16 nIns = 0, nEndPos = *rAttr.End(); |
| for( ; nIns < aStack.Count(); ++nIns ) |
| if( *((SwTxtAttr*)aStack[ nIns ] )->GetEnd() > nEndPos ) |
| break; |
| |
| aStack.Insert( pAdd, nIns ); |
| } |
| |
| void SwTxtAttrIterator::SearchNextChg() |
| { |
| sal_uInt16 nWh = 0; |
| if( nChgPos == aSIter.GetScriptChgPos() ) |
| { |
| aSIter.Next(); |
| pParaItem = 0; |
| nAttrPos = 0; // must be restart at the beginning, because |
| // some attributes can start before or inside |
| // the current scripttype! |
| aStack.Remove( 0, aStack.Count() ); |
| } |
| if( !pParaItem ) |
| { |
| nWh = bIsUseGetWhichOfScript ? |
| GetWhichOfScript( nWhichId, |
| aSIter.GetCurrScript() ) : nWhichId; |
| pParaItem = &rTxtNd.GetSwAttrSet().Get( nWh ); |
| } |
| |
| xub_StrLen nStt = nChgPos; |
| nChgPos = aSIter.GetScriptChgPos(); |
| pCurItem = pParaItem; |
| |
| const SwpHints* pHts = rTxtNd.GetpSwpHints(); |
| if( pHts ) |
| { |
| if( !nWh ) |
| { |
| nWh = bIsUseGetWhichOfScript ? |
| GetWhichOfScript( nWhichId, |
| aSIter.GetCurrScript() ) : nWhichId; |
| } |
| |
| const SfxPoolItem* pItem = 0; |
| for( ; nAttrPos < pHts->Count(); ++nAttrPos ) |
| { |
| const SwTxtAttr* pHt = (*pHts)[ nAttrPos ]; |
| const sal_uInt16* pEnd = pHt->End(); |
| const sal_uInt16 nHtStt = *pHt->GetStart(); |
| if( nHtStt < nStt && ( !pEnd || *pEnd <= nStt )) |
| continue; |
| |
| if( nHtStt >= nChgPos ) |
| break; |
| |
| pItem = CharFmt::GetItem( *pHt, nWh ); |
| if ( pItem ) |
| { |
| if( nHtStt > nStt ) |
| { |
| if( nChgPos > nHtStt ) |
| nChgPos = nHtStt; |
| break; |
| } |
| AddToStack( *pHt ); |
| pCurItem = pItem; |
| if( *pEnd < nChgPos ) |
| nChgPos = *pEnd; |
| } |
| } |
| } |
| } |
| |
| |