2000-09-18 23:08:29 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* $RCSfile: itratr.cxx,v $
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2006-08-14 15:38:07 +00:00
|
|
|
* $Revision: 1.35 $
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2006-08-14 15:38:07 +00:00
|
|
|
* last change: $Author: hr $ $Date: 2006-08-14 16:38:07 $
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
2005-09-09 03:53:58 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2000-09-18 23:08:29 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
|
|
#ifndef _HINTIDS_HXX
|
|
|
|
#include <hintids.hxx>
|
|
|
|
#endif
|
2001-03-06 15:08:39 +00:00
|
|
|
#ifndef _SVX_CHARSCALEITEM_HXX
|
|
|
|
#include <svx/charscaleitem.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _TXTATR_HXX
|
|
|
|
#include <txtatr.hxx>
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
#ifndef _SFX_PRINTER_HXX //autogen
|
|
|
|
#include <sfx2/printer.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SVX_LRSPITEM_HXX //autogen
|
|
|
|
#include <svx/lrspitem.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _WINDOW_HXX //autogen
|
|
|
|
#include <vcl/window.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SV_SVAPP_HXX
|
|
|
|
#include <vcl/svapp.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTANCHR_HXX //autogen
|
|
|
|
#include <fmtanchr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFSIZE_HXX //autogen
|
|
|
|
#include <fmtfsize.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTORNT_HXX //autogen
|
|
|
|
#include <fmtornt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFLCNT_HXX //autogen
|
|
|
|
#include <fmtflcnt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTCNTNT_HXX //autogen
|
|
|
|
#include <fmtcntnt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFTN_HXX //autogen
|
|
|
|
#include <fmtftn.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTHBSH_HXX //autogen
|
|
|
|
#include <fmthbsh.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FRMATR_HXX
|
|
|
|
#include <frmatr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FRMFMT_HXX //autogen
|
|
|
|
#include <frmfmt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTFLD_HXX
|
|
|
|
#include <fmtfld.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _DOC_HXX
|
|
|
|
#include <doc.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _VIEWSH_HXX
|
|
|
|
#include <viewsh.hxx> // ViewShell
|
|
|
|
#endif
|
|
|
|
#ifndef _ROOTFRM_HXX
|
|
|
|
#include <rootfrm.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _DOCARY_HXX
|
|
|
|
#include <docary.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _NDTXT_HXX
|
|
|
|
#include <ndtxt.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _DCONTACT_HXX
|
|
|
|
#include <dcontact.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FLDBAS_HXX
|
|
|
|
#include <fldbas.hxx> // SwField
|
|
|
|
#endif
|
|
|
|
#ifndef _PAM_HXX
|
|
|
|
#include <pam.hxx> // SwPosition (lcl_MinMaxNode)
|
|
|
|
#endif
|
|
|
|
#ifndef _ITRATR_HXX
|
|
|
|
#include <itratr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _HTMLTBL_HXX
|
|
|
|
#include <htmltbl.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _SWTABLE_HXX
|
|
|
|
#include <swtable.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _REDLNITR_HXX
|
|
|
|
#include <redlnitr.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _FMTSRND_HXX
|
|
|
|
#include <fmtsrnd.hxx>
|
|
|
|
#endif
|
2001-02-23 08:58:03 +00:00
|
|
|
#ifndef _ITRTXT_HXX
|
|
|
|
#include <itrtxt.hxx>
|
|
|
|
#endif
|
2001-03-08 09:53:32 +00:00
|
|
|
#ifndef _BREAKIT_HXX
|
|
|
|
#include <breakit.hxx>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_I18N_WORDTYPE_HPP_
|
|
|
|
#include <com/sun/star/i18n/WordType.hpp>
|
|
|
|
#endif
|
|
|
|
#ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
|
|
|
|
#include <com/sun/star/i18n/ScriptType.hdl>
|
|
|
|
#endif
|
2000-09-18 23:08:29 +00:00
|
|
|
|
2001-03-08 09:53:32 +00:00
|
|
|
using namespace ::com::sun::star::i18n;
|
2000-11-30 10:42:24 +00:00
|
|
|
using namespace ::com::sun::star;
|
2000-09-27 10:53:31 +00:00
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::Chg()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwAttrIter::Chg( SwTxtAttr *pHt )
|
|
|
|
{
|
2001-03-05 11:54:15 +00:00
|
|
|
ASSERT( pHt && pFnt, "No attribute of font available for change");
|
|
|
|
if( pRedln && pRedln->IsOn() )
|
|
|
|
pRedln->ChangeTxtAttr( pFnt, *pHt, sal_True );
|
|
|
|
else
|
|
|
|
aAttrHandler.PushAndChg( *pHt, *pFnt );
|
|
|
|
nChgCnt++;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::Rst()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwAttrIter::Rst( SwTxtAttr *pHt )
|
|
|
|
{
|
2001-03-05 11:54:15 +00:00
|
|
|
ASSERT( pHt && pFnt, "No attribute of font available for reset");
|
|
|
|
// get top from stack after removing pHt
|
|
|
|
if( pRedln && pRedln->IsOn() )
|
|
|
|
pRedln->ChangeTxtAttr( pFnt, *pHt, sal_False );
|
|
|
|
else
|
|
|
|
aAttrHandler.PopAndChg( *pHt, *pFnt );
|
|
|
|
nChgCnt--;
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* virtual SwAttrIter::~SwAttrIter()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
SwAttrIter::~SwAttrIter()
|
|
|
|
{
|
|
|
|
delete pRedln;
|
|
|
|
delete pFnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::GetAttr()
|
|
|
|
*
|
|
|
|
* Liefert fuer eine Position das Attribut, wenn das Attribut genau auf
|
|
|
|
* der Position nPos liegt und kein EndIndex besitzt.
|
|
|
|
* GetAttr() wird fuer Attribute benoetigt, die die Formatierung beeinflussen
|
|
|
|
* sollen, ohne dabei den Inhalt des Strings zu veraendern. Solche "entarteten"
|
|
|
|
* Attribute sind z.B. Felder (die expandierten Text bereit halten) und
|
|
|
|
* zeilengebundene Frames. Um Mehrdeutigkeiten zwischen verschiedenen
|
|
|
|
* solcher Attribute zu vermeiden, werden beim Anlegen eines Attributs
|
|
|
|
* an der Startposition ein Sonderzeichen in den String einfuegt.
|
|
|
|
* Der Formatierer stoesst auf das Sonderzeichen und holt sich per
|
|
|
|
* GetAttr() das entartete Attribut.
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
SwTxtAttr *SwAttrIter::GetAttr( const xub_StrLen nPos ) const
|
|
|
|
{
|
|
|
|
if( pHints )
|
|
|
|
{
|
|
|
|
for( MSHORT i = 0; i < pHints->Count(); ++i )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pPos = pHints->GetHt(i);
|
|
|
|
xub_StrLen nStart = *pPos->GetStart();
|
|
|
|
if( nPos < nStart )
|
|
|
|
return 0;
|
|
|
|
if( nPos == nStart && !pPos->GetEnd() )
|
|
|
|
return pPos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::SeekAndChg()
|
|
|
|
*************************************************************************/
|
|
|
|
|
2003-10-15 08:55:55 +00:00
|
|
|
sal_Bool SwAttrIter::SeekAndChg( const xub_StrLen nNewPos, OutputDevice* pOut )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
sal_Bool bChg = nStartIndex && nNewPos == nPos ? pFnt->IsFntChg() : Seek( nNewPos );
|
|
|
|
if ( pLastOut != pOut )
|
|
|
|
{
|
|
|
|
pLastOut = pOut;
|
|
|
|
pFnt->SetFntChg( sal_True );
|
|
|
|
bChg = sal_True;
|
|
|
|
}
|
|
|
|
if( bChg )
|
|
|
|
{
|
|
|
|
// wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
|
|
|
|
// des gewuenschten Fonts ...
|
2000-12-11 10:05:15 +00:00
|
|
|
if ( !nChgCnt && !nPropFont )
|
2000-09-27 10:53:31 +00:00
|
|
|
pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
|
|
|
|
aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
|
2003-10-15 08:55:55 +00:00
|
|
|
pFnt->ChgPhysFnt( pShell, *pOut );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
return bChg;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool SwAttrIter::IsSymbol( const xub_StrLen nNewPos )
|
|
|
|
{
|
|
|
|
Seek( nNewPos );
|
2000-12-11 10:05:15 +00:00
|
|
|
if ( !nChgCnt && !nPropFont )
|
2000-09-27 10:53:31 +00:00
|
|
|
pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
|
|
|
|
aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
|
2000-09-18 23:08:29 +00:00
|
|
|
return pFnt->IsSymbol( pShell );
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::SeekStartAndChg()
|
|
|
|
*************************************************************************/
|
|
|
|
|
2003-10-15 08:55:55 +00:00
|
|
|
sal_Bool SwAttrIter::SeekStartAndChg( OutputDevice* pOut, const sal_Bool bParaFont )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2001-03-08 07:16:18 +00:00
|
|
|
if ( pRedln && pRedln->ExtOn() )
|
|
|
|
pRedln->LeaveExtend( *pFnt, 0 );
|
|
|
|
|
2001-07-12 10:21:31 +00:00
|
|
|
// reset font to its original state
|
2001-03-19 14:58:50 +00:00
|
|
|
aAttrHandler.Reset();
|
2001-07-12 10:21:31 +00:00
|
|
|
aAttrHandler.ResetFont( *pFnt );
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
nStartIndex = nEndIndex = nPos = nChgCnt = 0;
|
2000-12-11 10:05:15 +00:00
|
|
|
if( nPropFont )
|
|
|
|
pFnt->SetProportion( nPropFont );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pRedln )
|
|
|
|
{
|
|
|
|
pRedln->Clear( pFnt );
|
|
|
|
if( !bParaFont )
|
|
|
|
nChgCnt += pRedln->Seek( *pFnt, 0, STRING_LEN );
|
|
|
|
else
|
|
|
|
pRedln->Reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pHints && !bParaFont )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pTxtAttr;
|
|
|
|
// Solange wir noch nicht am Ende des StartArrays angekommen sind &&
|
|
|
|
// das TextAttribut an Position 0 beginnt ...
|
|
|
|
while ( ( nStartIndex < pHints->GetStartCount() ) &&
|
|
|
|
!(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()) )
|
|
|
|
{
|
|
|
|
// oeffne die TextAttribute
|
|
|
|
Chg( pTxtAttr );
|
|
|
|
nStartIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
register sal_Bool bChg = pFnt->IsFntChg();
|
|
|
|
if ( pLastOut != pOut )
|
|
|
|
{
|
|
|
|
pLastOut = pOut;
|
|
|
|
pFnt->SetFntChg( sal_True );
|
|
|
|
bChg = sal_True;
|
|
|
|
}
|
|
|
|
if( bChg )
|
|
|
|
{
|
|
|
|
// wenn der Aenderungszaehler auf Null ist, kennen wir die MagicNo
|
|
|
|
// des gewuenschten Fonts ...
|
2000-12-11 10:05:15 +00:00
|
|
|
if ( !nChgCnt && !nPropFont )
|
2000-09-27 10:53:31 +00:00
|
|
|
pFnt->SetMagic( aMagicNo[ pFnt->GetActual() ],
|
|
|
|
aFntIdx[ pFnt->GetActual() ], pFnt->GetActual() );
|
2003-10-15 08:55:55 +00:00
|
|
|
pFnt->ChgPhysFnt( pShell, *pOut );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
return bChg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::SeekFwd()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
// AMA: Neuer AttrIter Nov 94
|
|
|
|
|
|
|
|
void SwAttrIter::SeekFwd( const xub_StrLen nNewPos )
|
|
|
|
{
|
|
|
|
SwTxtAttr *pTxtAttr;
|
|
|
|
|
|
|
|
if ( nStartIndex ) // wenn ueberhaupt schon Attribute geoeffnet wurden...
|
|
|
|
{
|
|
|
|
// Schliesse Attr, die z. Z. geoeffnet sind, vor nNewPos+1 aber enden.
|
|
|
|
|
|
|
|
// Solange wir noch nicht am Ende des EndArrays angekommen sind &&
|
|
|
|
// das TextAttribut vor oder an der neuen Position endet ...
|
|
|
|
while ( ( nEndIndex < pHints->GetEndCount() ) &&
|
|
|
|
(*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
|
|
|
|
{
|
|
|
|
// schliesse die TextAttribute, deren StartPos vor
|
|
|
|
// oder an der alten nPos lag, die z.Z. geoeffnet sind.
|
|
|
|
if (*pTxtAttr->GetStart() <= nPos) Rst( pTxtAttr );
|
|
|
|
nEndIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else // ueberlies die nicht geoeffneten Enden
|
|
|
|
{
|
|
|
|
while ( ( nEndIndex < pHints->GetEndCount() ) &&
|
|
|
|
(*(pTxtAttr=pHints->GetEnd(nEndIndex))->GetAnyEnd()<=nNewPos))
|
|
|
|
{
|
|
|
|
nEndIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Solange wir noch nicht am Ende des StartArrays angekommen sind &&
|
|
|
|
// das TextAttribut vor oder an der neuen Position beginnt ...
|
|
|
|
while ( ( nStartIndex < pHints->GetStartCount() ) &&
|
|
|
|
(*(pTxtAttr=pHints->GetStart(nStartIndex))->GetStart()<=nNewPos))
|
|
|
|
{
|
|
|
|
// oeffne die TextAttribute, deren Ende hinter der neuen Position liegt
|
|
|
|
if ( *pTxtAttr->GetAnyEnd() > nNewPos ) Chg( pTxtAttr );
|
|
|
|
nStartIndex++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::Seek()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
sal_Bool SwAttrIter::Seek( const xub_StrLen nNewPos )
|
|
|
|
{
|
2001-03-08 07:16:18 +00:00
|
|
|
if ( pRedln && pRedln->ExtOn() )
|
|
|
|
pRedln->LeaveExtend( *pFnt, nNewPos );
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pHints )
|
|
|
|
{
|
|
|
|
if( !nNewPos || nNewPos < nPos )
|
|
|
|
{
|
|
|
|
if( pRedln )
|
|
|
|
pRedln->Clear( NULL );
|
2001-07-12 10:21:31 +00:00
|
|
|
|
|
|
|
// reset font to its original state
|
2001-03-19 14:58:50 +00:00
|
|
|
aAttrHandler.Reset();
|
2001-07-12 10:21:31 +00:00
|
|
|
aAttrHandler.ResetFont( *pFnt );
|
|
|
|
|
2000-12-11 10:05:15 +00:00
|
|
|
if( nPropFont )
|
|
|
|
pFnt->SetProportion( nPropFont );
|
2000-09-18 23:08:29 +00:00
|
|
|
nStartIndex = nEndIndex = nPos = 0;
|
|
|
|
nChgCnt = 0;
|
2002-04-22 11:35:17 +00:00
|
|
|
|
|
|
|
// Achtung!
|
|
|
|
// resetting the font here makes it necessary to apply any
|
|
|
|
// changes for extended input directly to the font
|
|
|
|
if ( pRedln && pRedln->ExtOn() )
|
|
|
|
{
|
|
|
|
pRedln->UpdateExtFont( *pFnt );
|
|
|
|
++nChgCnt;
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
SeekFwd( nNewPos );
|
|
|
|
}
|
2001-10-22 12:03:21 +00:00
|
|
|
|
2003-10-30 09:19:20 +00:00
|
|
|
pFnt->SetActual( SwScriptInfo::WhichFont( nNewPos, 0, pScriptInfo ) );
|
2001-10-22 12:03:21 +00:00
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pRedln )
|
|
|
|
nChgCnt += pRedln->Seek( *pFnt, nNewPos, nPos );
|
|
|
|
nPos = nNewPos;
|
2001-03-15 14:59:12 +00:00
|
|
|
|
|
|
|
if( nPropFont )
|
|
|
|
pFnt->SetProportion( nPropFont );
|
|
|
|
|
2000-09-18 23:08:29 +00:00
|
|
|
return pFnt->IsFntChg();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::GetNextAttr()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
xub_StrLen SwAttrIter::GetNextAttr( ) const
|
|
|
|
{
|
|
|
|
xub_StrLen nNext = STRING_LEN;
|
|
|
|
if( pHints )
|
|
|
|
{
|
|
|
|
if (pHints->GetStartCount() > nStartIndex) // Gibt es noch Starts?
|
|
|
|
nNext = (*pHints->GetStart(nStartIndex)->GetStart());
|
|
|
|
if (pHints->GetEndCount() > nEndIndex) // Gibt es noch Enden?
|
|
|
|
{
|
|
|
|
xub_StrLen nNextEnd = (*pHints->GetEnd(nEndIndex)->GetAnyEnd());
|
|
|
|
if ( nNextEnd<nNext ) nNext = nNextEnd; // Wer ist naeher?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( pRedln )
|
|
|
|
return pRedln->GetNextRedln( nNext );
|
|
|
|
return nNext;
|
|
|
|
}
|
|
|
|
|
2003-04-15 15:53:50 +00:00
|
|
|
#if OSL_DEBUG_LEVEL > 1
|
2000-09-18 23:08:29 +00:00
|
|
|
/*************************************************************************
|
|
|
|
* SwAttrIter::Dump()
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
void SwAttrIter::Dump( SvStream &rOS ) const
|
|
|
|
{
|
|
|
|
// Noch nicht an den neuen Attributiterator angepasst ...
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class SwMinMaxArgs
|
|
|
|
{
|
|
|
|
public:
|
2003-10-15 08:55:55 +00:00
|
|
|
OutputDevice* pOut;
|
|
|
|
ViewShell* pSh;
|
2000-09-18 23:08:29 +00:00
|
|
|
ULONG &rMin;
|
|
|
|
ULONG &rMax;
|
|
|
|
ULONG &rAbsMin;
|
|
|
|
long nRowWidth;
|
|
|
|
long nWordWidth;
|
|
|
|
long nWordAdd;
|
2001-11-30 12:52:05 +00:00
|
|
|
xub_StrLen nNoLineBreak;
|
2003-10-15 08:55:55 +00:00
|
|
|
SwMinMaxArgs( OutputDevice* pOutI, ViewShell* pShI, ULONG& rMinI, ULONG &rMaxI, ULONG &rAbsI )
|
|
|
|
: pOut( pOutI ), pSh( pShI ), rMin( rMinI ), rMax( rMaxI ), rAbsMin( rAbsI )
|
2001-11-30 12:52:05 +00:00
|
|
|
{ nRowWidth = nWordWidth = nWordAdd = 0; nNoLineBreak = STRING_LEN; }
|
2000-09-18 23:08:29 +00:00
|
|
|
void Minimum( long nNew ) { if( (long)rMin < nNew ) rMin = nNew; }
|
|
|
|
void NewWord() { nWordAdd = nWordWidth = 0; }
|
|
|
|
};
|
|
|
|
|
|
|
|
sal_Bool lcl_MinMaxString( SwMinMaxArgs& rArg, SwFont* pFnt, const XubString &rTxt,
|
|
|
|
xub_StrLen nIdx, xub_StrLen nEnd )
|
|
|
|
{
|
|
|
|
sal_Bool bRet = sal_False;
|
|
|
|
while( nIdx < nEnd )
|
|
|
|
{
|
|
|
|
xub_StrLen nStop = nIdx;
|
2001-09-10 08:55:04 +00:00
|
|
|
sal_Bool bClear;
|
|
|
|
LanguageType eLang = pFnt->GetLanguage();
|
|
|
|
if( pBreakIt->xBreak.is() )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
2001-09-10 08:55:04 +00:00
|
|
|
bClear = CH_BLANK == rTxt.GetChar( nStop );
|
|
|
|
Boundary aBndry( pBreakIt->xBreak->getWordBoundary( rTxt, nIdx,
|
|
|
|
pBreakIt->GetLocale( eLang ),
|
2001-11-30 12:52:05 +00:00
|
|
|
WordType::DICTIONARY_WORD, TRUE ) );
|
2003-04-01 08:56:20 +00:00
|
|
|
nStop = (xub_StrLen)aBndry.endPos;
|
2001-11-30 12:52:05 +00:00
|
|
|
if( nIdx <= aBndry.startPos && nIdx && nIdx-1 != rArg.nNoLineBreak )
|
2001-09-10 08:55:04 +00:00
|
|
|
rArg.NewWord();
|
|
|
|
if( nStop == nIdx )
|
|
|
|
++nStop;
|
|
|
|
if( nStop > nEnd )
|
|
|
|
nStop = nEnd;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
while( nStop < nEnd && CH_BLANK != rTxt.GetChar( nStop ) )
|
2000-09-18 23:08:29 +00:00
|
|
|
++nStop;
|
2001-09-10 08:55:04 +00:00
|
|
|
bClear = nStop == nIdx;
|
|
|
|
if ( bClear )
|
|
|
|
{
|
|
|
|
rArg.NewWord();
|
|
|
|
while( nStop < nEnd && CH_BLANK == rTxt.GetChar( nStop ) )
|
|
|
|
++nStop;
|
|
|
|
}
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
2001-04-09 09:44:17 +00:00
|
|
|
|
2003-10-15 08:55:55 +00:00
|
|
|
SwDrawTextInfo aDrawInf( rArg.pSh, *rArg.pOut, 0, rTxt, nIdx, nStop - nIdx );
|
2001-04-09 09:44:17 +00:00
|
|
|
long nAktWidth = pFnt->_GetTxtSize( aDrawInf ).Width();
|
2000-09-18 23:08:29 +00:00
|
|
|
rArg.nRowWidth += nAktWidth;
|
|
|
|
if( bClear )
|
|
|
|
rArg.NewWord();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
rArg.nWordWidth += nAktWidth;
|
|
|
|
if( (long)rArg.rAbsMin < rArg.nWordWidth )
|
|
|
|
rArg.rAbsMin = rArg.nWordWidth;
|
|
|
|
rArg.Minimum( rArg.nWordWidth + rArg.nWordAdd );
|
|
|
|
bRet = sal_True;
|
|
|
|
}
|
|
|
|
nIdx = nStop;
|
|
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool SwTxtNode::IsSymbol( const xub_StrLen nBegin ) const
|
|
|
|
{
|
2003-04-01 08:56:20 +00:00
|
|
|
SwScriptInfo aScriptInfo;
|
|
|
|
SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
|
|
|
|
aIter.Seek( nBegin );
|
2006-08-14 15:38:07 +00:00
|
|
|
const SwRootFrm* pTmpRootFrm = getIDocumentLayoutAccess()->GetRootFrm();
|
|
|
|
return aIter.GetFnt()->IsSymbol( pTmpRootFrm ?
|
|
|
|
pTmpRootFrm->GetCurrShell() :
|
|
|
|
0 );
|
2000-09-18 23:08:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class SwMinMaxNodeArgs
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ULONG nMaxWidth; // Summe aller Rahmenbreite
|
|
|
|
long nMinWidth; // Breitester Rahmen
|
|
|
|
long nLeftRest; // noch nicht von Rahmen ueberdeckter Platz im l. Rand
|
|
|
|
long nRightRest; // noch nicht von Rahmen ueberdeckter Platz im r. Rand
|
|
|
|
long nLeftDiff; // Min/Max-Differenz des Rahmens im linken Rand
|
|
|
|
long nRightDiff; // Min/Max-Differenz des Rahmens im rechten Rand
|
|
|
|
ULONG nIndx; // Indexnummer des Nodes
|
|
|
|
void Minimum( long nNew ) { if( nNew > nMinWidth ) nMinWidth = nNew; }
|
|
|
|
};
|
|
|
|
|
|
|
|
sal_Bool lcl_MinMaxNode( const SwFrmFmtPtr& rpNd, void* pArgs )
|
|
|
|
{
|
|
|
|
const SwFmtAnchor& rFmtA = ((SwFrmFmt*)rpNd)->GetAnchor();
|
2003-07-14 11:45:42 +00:00
|
|
|
|
|
|
|
bool bCalculate = false;
|
|
|
|
if (
|
|
|
|
(FLY_AT_CNTNT == rFmtA.GetAnchorId()) ||
|
|
|
|
(FLY_AUTO_CNTNT == rFmtA.GetAnchorId())
|
|
|
|
)
|
|
|
|
{
|
|
|
|
bCalculate = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bCalculate)
|
|
|
|
{
|
|
|
|
const SwMinMaxNodeArgs *pIn = (const SwMinMaxNodeArgs*)pArgs;
|
|
|
|
const SwPosition *pPos = rFmtA.GetCntntAnchor();
|
|
|
|
ASSERT(pPos && pIn, "Unexpected NULL arguments");
|
|
|
|
if (!pPos || !pIn || pIn->nIndx != pPos->nNode.GetIndex())
|
|
|
|
bCalculate = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bCalculate)
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
long nMin, nMax;
|
|
|
|
SwHTMLTableLayout *pLayout = 0;
|
|
|
|
MSHORT nWhich = ((SwFrmFmt*)rpNd)->Which();
|
|
|
|
if( RES_DRAWFRMFMT != nWhich )
|
|
|
|
{
|
|
|
|
// Enthaelt der Rahmen zu Beginn oder am Ende eine Tabelle?
|
2006-08-14 15:38:07 +00:00
|
|
|
const SwNodes& rNodes = static_cast<SwFrmFmt*>(rpNd)->GetDoc()->GetNodes();
|
2000-09-18 23:08:29 +00:00
|
|
|
const SwFmtCntnt& rFlyCntnt = ((SwFrmFmt*)rpNd)->GetCntnt();
|
|
|
|
ULONG nStt = rFlyCntnt.GetCntntIdx()->GetIndex();
|
2006-08-14 15:38:07 +00:00
|
|
|
SwTableNode* pTblNd = rNodes[nStt+1]->GetTableNode();
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !pTblNd )
|
|
|
|
{
|
2006-08-14 15:38:07 +00:00
|
|
|
SwNode *pNd = rNodes[nStt];
|
|
|
|
pNd = rNodes[pNd->EndOfSectionIndex()-1];
|
2000-09-18 23:08:29 +00:00
|
|
|
if( pNd->IsEndNode() )
|
|
|
|
pTblNd = pNd->StartOfSectionNode()->GetTableNode();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( pTblNd )
|
|
|
|
pLayout = pTblNd->GetTable().GetHTMLTableLayout();
|
|
|
|
}
|
|
|
|
|
|
|
|
const SwFmtHoriOrient& rOrient = ((SwFrmFmt*)rpNd)->GetHoriOrient();
|
|
|
|
SwHoriOrient eHoriOri = rOrient.GetHoriOrient();
|
|
|
|
|
|
|
|
long nDiff;
|
|
|
|
if( pLayout )
|
|
|
|
{
|
|
|
|
nMin = pLayout->GetMin();
|
|
|
|
nMax = pLayout->GetMax();
|
|
|
|
nDiff = nMax - nMin;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( RES_DRAWFRMFMT == nWhich )
|
|
|
|
{
|
|
|
|
const SdrObject* pSObj = rpNd->FindSdrObject();
|
|
|
|
if( pSObj )
|
2003-11-24 15:09:00 +00:00
|
|
|
nMin = pSObj->GetCurrentBoundRect().GetWidth();
|
2000-09-18 23:08:29 +00:00
|
|
|
else
|
|
|
|
nMin = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const SwFmtFrmSize &rSz = ( (SwFrmFmt*)rpNd )->GetFrmSize();
|
|
|
|
nMin = rSz.GetWidth();
|
|
|
|
}
|
|
|
|
nMax = nMin;
|
|
|
|
nDiff = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const SvxLRSpaceItem &rLR = ( (SwFrmFmt*)rpNd )->GetLRSpace();
|
|
|
|
nMin += rLR.GetLeft();
|
|
|
|
nMin += rLR.GetRight();
|
|
|
|
nMax += rLR.GetLeft();
|
|
|
|
nMax += rLR.GetRight();
|
|
|
|
|
|
|
|
if( SURROUND_THROUGHT == ((SwFrmFmt*)rpNd)->GetSurround().GetSurround() )
|
|
|
|
{
|
|
|
|
( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rahmen, die recht bzw. links ausgerichtet sind, gehen nur
|
|
|
|
// teilweise in die Max-Berechnung ein, da der Rand schon berueck-
|
|
|
|
// sichtigt wird. Nur wenn die Rahmen in den Textkoerper ragen,
|
|
|
|
// wird dieser Teil hinzuaddiert.
|
|
|
|
switch( eHoriOri )
|
|
|
|
{
|
|
|
|
case HORI_RIGHT:
|
|
|
|
{
|
|
|
|
if( nDiff )
|
|
|
|
{
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nRightRest -=
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nRightDiff;
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nRightDiff = nDiff;
|
|
|
|
}
|
|
|
|
if( FRAME!=rOrient.GetRelationOrient() )
|
|
|
|
{
|
|
|
|
if( ((SwMinMaxNodeArgs*)pArgs)->nRightRest > 0 )
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nRightRest = 0;
|
|
|
|
}
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nRightRest -= nMin;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case HORI_LEFT:
|
|
|
|
{
|
|
|
|
if( nDiff )
|
|
|
|
{
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nLeftRest -=
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nLeftDiff;
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nLeftDiff = nDiff;
|
|
|
|
}
|
|
|
|
if( FRAME!=rOrient.GetRelationOrient() &&
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nLeftRest < 0 )
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nLeftRest = 0;
|
|
|
|
((SwMinMaxNodeArgs*)pArgs)->nLeftRest -= nMin;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
( (SwMinMaxNodeArgs*)pArgs )->nMaxWidth += nMax;
|
|
|
|
( (SwMinMaxNodeArgs*)pArgs )->Minimum( nMin );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sal_True;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define FLYINCNT_MIN_WIDTH 284
|
|
|
|
|
2001-03-05 11:54:15 +00:00
|
|
|
// changing this method very likely requires changing of
|
|
|
|
// "GetScalingOfSelectedText"
|
2000-09-18 23:08:29 +00:00
|
|
|
void SwTxtNode::GetMinMaxSize( ULONG nIndex, ULONG& rMin, ULONG &rMax,
|
|
|
|
ULONG& rAbsMin, OutputDevice* pOut ) const
|
|
|
|
{
|
2003-10-15 08:55:55 +00:00
|
|
|
ViewShell* pSh = 0;
|
|
|
|
GetDoc()->GetEditShell( &pSh );
|
2000-09-18 23:08:29 +00:00
|
|
|
if( !pOut )
|
|
|
|
{
|
|
|
|
if( pSh )
|
|
|
|
pOut = pSh->GetWin();
|
|
|
|
if( !pOut )
|
|
|
|
pOut = GetpApp()->GetDefaultDevice();
|
|
|
|
}
|
|
|
|
|
|
|
|
MapMode aOldMap( pOut->GetMapMode() );
|
|
|
|
pOut->SetMapMode( MapMode( MAP_TWIP ) );
|
|
|
|
|
|
|
|
rMin = 0;
|
|
|
|
rMax = 0;
|
|
|
|
rAbsMin = 0;
|
|
|
|
|
|
|
|
const SvxLRSpaceItem &rSpace = GetSwAttrSet().GetLRSpace();
|
|
|
|
long nLROffset = rSpace.GetTxtLeft() + GetLeftMarginWithNum( sal_True );
|
|
|
|
short nFLOffs;
|
|
|
|
// Bei Numerierung ist ein neg. Erstzeileneinzug vermutlich
|
|
|
|
// bereits gefuellt...
|
|
|
|
if( !GetFirstLineOfsWithNum( nFLOffs ) || nFLOffs > nLROffset )
|
|
|
|
nLROffset = nFLOffs;
|
|
|
|
|
|
|
|
SwMinMaxNodeArgs aNodeArgs;
|
|
|
|
aNodeArgs.nMinWidth = 0;
|
|
|
|
aNodeArgs.nMaxWidth = 0;
|
|
|
|
aNodeArgs.nLeftRest = nLROffset;
|
|
|
|
aNodeArgs.nRightRest = rSpace.GetRight();
|
|
|
|
aNodeArgs.nLeftDiff = 0;
|
|
|
|
aNodeArgs.nRightDiff = 0;
|
|
|
|
if( nIndex )
|
|
|
|
{
|
|
|
|
SwSpzFrmFmts* pTmp = (SwSpzFrmFmts*)GetDoc()->GetSpzFrmFmts();
|
|
|
|
if( pTmp )
|
|
|
|
{
|
|
|
|
aNodeArgs.nIndx = nIndex;
|
|
|
|
pTmp->ForEach( &lcl_MinMaxNode, &aNodeArgs );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( aNodeArgs.nLeftRest < 0 )
|
|
|
|
aNodeArgs.Minimum( nLROffset - aNodeArgs.nLeftRest );
|
|
|
|
aNodeArgs.nLeftRest -= aNodeArgs.nLeftDiff;
|
|
|
|
if( aNodeArgs.nLeftRest < 0 )
|
|
|
|
aNodeArgs.nMaxWidth -= aNodeArgs.nLeftRest;
|
|
|
|
|
|
|
|
if( aNodeArgs.nRightRest < 0 )
|
|
|
|
aNodeArgs.Minimum( rSpace.GetRight() - aNodeArgs.nRightRest );
|
|
|
|
aNodeArgs.nRightRest -= aNodeArgs.nRightDiff;
|
|
|
|
if( aNodeArgs.nRightRest < 0 )
|
|
|
|
aNodeArgs.nMaxWidth -= aNodeArgs.nRightRest;
|
|
|
|
|
2001-02-20 09:27:05 +00:00
|
|
|
SwScriptInfo aScriptInfo;
|
2001-03-05 11:54:15 +00:00
|
|
|
SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
|
2000-09-18 23:08:29 +00:00
|
|
|
xub_StrLen nIdx = 0;
|
|
|
|
aIter.SeekAndChg( nIdx, pOut );
|
|
|
|
xub_StrLen nLen = aText.Len();
|
|
|
|
long nAktWidth = 0;
|
|
|
|
MSHORT nAdd = 0;
|
2003-10-15 08:55:55 +00:00
|
|
|
SwMinMaxArgs aArg( pOut, pSh, rMin, rMax, rAbsMin );
|
2000-09-18 23:08:29 +00:00
|
|
|
while( nIdx < nLen )
|
|
|
|
{
|
|
|
|
xub_StrLen nNextChg = aIter.GetNextAttr();
|
2001-02-20 09:27:05 +00:00
|
|
|
xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
|
2000-09-27 10:53:31 +00:00
|
|
|
if( nNextChg > nStop )
|
|
|
|
nNextChg = nStop;
|
2000-09-18 23:08:29 +00:00
|
|
|
SwTxtAttr *pHint = NULL;
|
|
|
|
xub_Unicode cChar = CH_BLANK;
|
2000-09-27 10:53:31 +00:00
|
|
|
nStop = nIdx;
|
2000-09-18 23:08:29 +00:00
|
|
|
while( nStop < nLen && nStop < nNextChg &&
|
|
|
|
CH_TAB != ( cChar = aText.GetChar( nStop ) ) &&
|
2001-11-30 12:52:05 +00:00
|
|
|
CH_BREAK != cChar && CHAR_HARDBLANK != cChar &&
|
|
|
|
CHAR_HARDHYPHEN != cChar && CHAR_SOFTHYPHEN != cChar &&
|
|
|
|
!pHint )
|
2000-09-18 23:08:29 +00:00
|
|
|
{
|
|
|
|
if( ( CH_TXTATR_BREAKWORD != cChar && CH_TXTATR_INWORD != cChar )
|
|
|
|
|| ( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
|
|
|
|
++nStop;
|
|
|
|
}
|
|
|
|
if( lcl_MinMaxString( aArg, aIter.GetFnt(), aText, nIdx, nStop ) )
|
|
|
|
nAdd = 20;
|
|
|
|
nIdx = nStop;
|
|
|
|
aIter.SeekAndChg( nIdx, pOut );
|
|
|
|
switch( cChar )
|
|
|
|
{
|
|
|
|
case CH_BREAK :
|
|
|
|
{
|
|
|
|
if( (long)rMax < aArg.nRowWidth )
|
|
|
|
rMax = aArg.nRowWidth;
|
|
|
|
aArg.nRowWidth = 0;
|
|
|
|
aArg.NewWord();
|
|
|
|
aIter.SeekAndChg( ++nIdx, pOut );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CH_TAB :
|
|
|
|
{
|
|
|
|
aArg.NewWord();
|
|
|
|
aIter.SeekAndChg( ++nIdx, pOut );
|
|
|
|
}
|
|
|
|
break;
|
2001-11-30 12:52:05 +00:00
|
|
|
case CHAR_SOFTHYPHEN:
|
|
|
|
++nIdx;
|
|
|
|
break;
|
|
|
|
case CHAR_HARDBLANK:
|
|
|
|
case CHAR_HARDHYPHEN:
|
|
|
|
{
|
|
|
|
XubString sTmp( cChar );
|
2006-08-14 15:38:07 +00:00
|
|
|
const SwRootFrm* pTmpRootFrm = getIDocumentLayoutAccess()->GetRootFrm();
|
|
|
|
SwDrawTextInfo aDrawInf( pTmpRootFrm ?
|
|
|
|
pTmpRootFrm->GetCurrShell() :
|
|
|
|
0, *pOut, 0, sTmp, 0, 1, 0, sal_False );
|
2001-11-30 12:52:05 +00:00
|
|
|
nAktWidth = aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
|
|
|
|
aArg.nWordWidth += nAktWidth;
|
|
|
|
aArg.nRowWidth += nAktWidth;
|
|
|
|
if( (long)rAbsMin < aArg.nWordWidth )
|
|
|
|
rAbsMin = aArg.nWordWidth;
|
|
|
|
aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
|
|
|
|
aArg.nNoLineBreak = nIdx++;
|
|
|
|
}
|
|
|
|
break;
|
2000-09-18 23:08:29 +00:00
|
|
|
case CH_TXTATR_BREAKWORD:
|
|
|
|
case CH_TXTATR_INWORD:
|
|
|
|
{
|
|
|
|
if( !pHint )
|
|
|
|
break;
|
|
|
|
long nOldWidth = aArg.nWordWidth;
|
|
|
|
long nOldAdd = aArg.nWordAdd;
|
|
|
|
aArg.NewWord();
|
|
|
|
|
|
|
|
switch( pHint->Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_FLYCNT :
|
|
|
|
{
|
|
|
|
SwFrmFmt *pFrmFmt = pHint->GetFlyCnt().GetFrmFmt();
|
|
|
|
const SvxLRSpaceItem &rLR = pFrmFmt->GetLRSpace();
|
|
|
|
if( RES_DRAWFRMFMT == pFrmFmt->Which() )
|
|
|
|
{
|
|
|
|
const SdrObject* pSObj = pFrmFmt->FindSdrObject();
|
|
|
|
if( pSObj )
|
2003-11-24 15:09:00 +00:00
|
|
|
nAktWidth = pSObj->GetCurrentBoundRect().GetWidth();
|
2000-09-18 23:08:29 +00:00
|
|
|
else
|
|
|
|
nAktWidth = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const SwFmtFrmSize& rTmpSize = pFrmFmt->GetFrmSize();
|
|
|
|
if( RES_FLYFRMFMT == pFrmFmt->Which()
|
|
|
|
&& rTmpSize.GetWidthPercent() )
|
|
|
|
{
|
|
|
|
/*-----------------24.01.97 14:09----------------------------------------------
|
|
|
|
* Hier ein HACK fuer folgende Situation: In dem Absatz befindet sich
|
|
|
|
* ein Textrahmen mit relativer Groesse. Dann nehmen wir mal als minimale
|
|
|
|
* Breite 0,5 cm und als maximale KSHRT_MAX.
|
|
|
|
* Sauberer und vielleicht spaeter notwendig waere es, ueber den Inhalt
|
|
|
|
* des Textrahmens zu iterieren und GetMinMaxSize rekursiv zu rufen.
|
|
|
|
* --------------------------------------------------------------------------*/
|
|
|
|
nAktWidth = FLYINCNT_MIN_WIDTH; // 0,5 cm
|
|
|
|
if( (long)rMax < KSHRT_MAX )
|
|
|
|
rMax = KSHRT_MAX;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nAktWidth = pFrmFmt->GetFrmSize().GetWidth();
|
|
|
|
}
|
|
|
|
nAktWidth += rLR.GetLeft();
|
|
|
|
nAktWidth += rLR.GetRight();
|
|
|
|
aArg.nWordAdd = nOldWidth + nOldAdd;
|
|
|
|
aArg.nWordWidth = nAktWidth;
|
|
|
|
aArg.nRowWidth += nAktWidth;
|
|
|
|
if( (long)rAbsMin < aArg.nWordWidth )
|
|
|
|
rAbsMin = aArg.nWordWidth;
|
|
|
|
aArg.Minimum( aArg.nWordWidth + aArg.nWordAdd );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case RES_TXTATR_FTN :
|
|
|
|
{
|
|
|
|
const XubString aTxt = pHint->GetFtn().GetNumStr();
|
|
|
|
if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
|
|
|
|
aTxt.Len() ) )
|
|
|
|
nAdd = 20;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case RES_TXTATR_FIELD :
|
|
|
|
{
|
|
|
|
SwField *pFld = (SwField*)pHint->GetFld().GetFld();
|
|
|
|
const String aTxt = pFld->GetCntnt( FALSE );
|
|
|
|
if( lcl_MinMaxString( aArg, aIter.GetFnt(), aTxt, 0,
|
|
|
|
aTxt.Len() ) )
|
|
|
|
nAdd = 20;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: aArg.nWordWidth = nOldWidth;
|
|
|
|
aArg.nWordAdd = nOldAdd;
|
|
|
|
|
|
|
|
}
|
|
|
|
aIter.SeekAndChg( ++nIdx, pOut );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if( (long)rMax < aArg.nRowWidth )
|
|
|
|
rMax = aArg.nRowWidth;
|
|
|
|
|
|
|
|
nLROffset += rSpace.GetRight();
|
|
|
|
|
|
|
|
rAbsMin += nLROffset;
|
|
|
|
rAbsMin += nAdd;
|
|
|
|
rMin += nLROffset;
|
|
|
|
rMin += nAdd;
|
|
|
|
if( (long)rMin < aNodeArgs.nMinWidth )
|
|
|
|
rMin = aNodeArgs.nMinWidth;
|
|
|
|
if( (long)rAbsMin < aNodeArgs.nMinWidth )
|
|
|
|
rAbsMin = aNodeArgs.nMinWidth;
|
|
|
|
rMax += aNodeArgs.nMaxWidth;
|
|
|
|
rMax += nLROffset;
|
|
|
|
rMax += nAdd;
|
|
|
|
if( rMax < rMin ) // z.B. Rahmen mit Durchlauf gehen zunaechst nur
|
|
|
|
rMax = rMin; // in das Minimum ein
|
|
|
|
pOut->SetMapMode( aOldMap );
|
|
|
|
}
|
|
|
|
|
2001-02-23 08:58:03 +00:00
|
|
|
/*************************************************************************
|
|
|
|
* SwTxtNode::GetScalingOfSelectedText()
|
|
|
|
*
|
|
|
|
* Calculates the width of the text part specified by nStt and nEnd,
|
|
|
|
* the height of the line containing nStt is devided by this width,
|
|
|
|
* indicating the scaling factor, if the text part is rotated.
|
|
|
|
* Having CH_BREAKs in the text part, this method returns the scaling
|
|
|
|
* factor for the longest of the text parts separated by the CH_BREAKs.
|
|
|
|
*
|
|
|
|
* changing this method very likely requires changing of "GetMinMaxSize"
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
USHORT SwTxtNode::GetScalingOfSelectedText( xub_StrLen nStt, xub_StrLen nEnd )
|
|
|
|
const
|
|
|
|
{
|
2003-04-01 08:56:20 +00:00
|
|
|
ViewShell* pSh = NULL;
|
|
|
|
OutputDevice* pOut = NULL;
|
2001-02-23 08:58:03 +00:00
|
|
|
GetDoc()->GetEditShell( &pSh );
|
2003-04-01 08:56:20 +00:00
|
|
|
|
|
|
|
if ( pSh )
|
|
|
|
pOut = &pSh->GetRefDev();
|
|
|
|
else
|
2001-02-23 08:58:03 +00:00
|
|
|
{
|
2003-04-01 08:56:20 +00:00
|
|
|
//Zugriff ueber StarONE, es muss keine Shell existieren oder aktiv sein.
|
2006-08-14 15:38:07 +00:00
|
|
|
if ( getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) )
|
2001-02-23 08:58:03 +00:00
|
|
|
pOut = GetpApp()->GetDefaultDevice();
|
2003-04-01 08:56:20 +00:00
|
|
|
else
|
2006-08-14 15:38:07 +00:00
|
|
|
pOut = getIDocumentDeviceAccess()->getReferenceDevice( true );
|
2001-02-23 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
2003-04-01 08:56:20 +00:00
|
|
|
ASSERT( pOut, "GetScalingOfSelectedText without outdev" )
|
|
|
|
|
2001-02-23 08:58:03 +00:00
|
|
|
MapMode aOldMap( pOut->GetMapMode() );
|
|
|
|
pOut->SetMapMode( MapMode( MAP_TWIP ) );
|
|
|
|
|
2001-03-08 09:53:32 +00:00
|
|
|
if ( nStt == nEnd )
|
|
|
|
{
|
|
|
|
if ( !pBreakIt->xBreak.is() )
|
|
|
|
return 100;
|
|
|
|
|
|
|
|
SwScriptInfo aScriptInfo;
|
|
|
|
SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
|
|
|
|
aIter.SeekAndChg( nStt, pOut );
|
|
|
|
|
|
|
|
Boundary aBound =
|
|
|
|
pBreakIt->xBreak->getWordBoundary( GetTxt(), nStt,
|
|
|
|
pBreakIt->GetLocale( aIter.GetFnt()->GetLanguage() ),
|
|
|
|
WordType::DICTIONARY_WORD, sal_True );
|
|
|
|
|
|
|
|
if ( nStt == aBound.startPos )
|
2004-02-10 13:56:16 +00:00
|
|
|
{
|
2001-03-08 09:53:32 +00:00
|
|
|
// cursor is at left or right border of word
|
2004-02-10 13:56:16 +00:00
|
|
|
pOut->SetMapMode( aOldMap );
|
2001-03-08 09:53:32 +00:00
|
|
|
return 100;
|
2004-02-10 13:56:16 +00:00
|
|
|
}
|
2001-03-08 09:53:32 +00:00
|
|
|
|
2003-04-01 08:56:20 +00:00
|
|
|
nStt = (xub_StrLen)aBound.startPos;
|
|
|
|
nEnd = (xub_StrLen)aBound.endPos;
|
2001-03-08 09:53:32 +00:00
|
|
|
|
|
|
|
if ( nStt == nEnd )
|
2004-02-10 13:56:16 +00:00
|
|
|
{
|
|
|
|
pOut->SetMapMode( aOldMap );
|
2001-03-08 09:53:32 +00:00
|
|
|
return 100;
|
2004-02-10 13:56:16 +00:00
|
|
|
}
|
2001-03-08 09:53:32 +00:00
|
|
|
}
|
|
|
|
|
2001-02-23 08:58:03 +00:00
|
|
|
SwScriptInfo aScriptInfo;
|
2001-03-05 11:54:15 +00:00
|
|
|
SwAttrIter aIter( *(SwTxtNode*)this, aScriptInfo );
|
2001-02-23 08:58:03 +00:00
|
|
|
|
2001-03-06 15:08:39 +00:00
|
|
|
// We do not want scaling attributes to be considered during this
|
|
|
|
// calculation. For this, we push a temporary scaling attribute with
|
|
|
|
// scaling value 100 and priority flag on top of the scaling stack
|
|
|
|
SwAttrHandler& rAH = aIter.GetAttrHandler();
|
|
|
|
SvxCharScaleWidthItem aItem;
|
2001-03-15 14:59:12 +00:00
|
|
|
SwTxtAttrEnd aAttr( aItem, nStt, nEnd );
|
2001-03-06 15:08:39 +00:00
|
|
|
aAttr.SetPriorityAttr( sal_True );
|
|
|
|
rAH.PushAndChg( aAttr, *(aIter.GetFnt()) );
|
|
|
|
|
2001-02-23 08:58:03 +00:00
|
|
|
xub_StrLen nIdx = nStt;
|
|
|
|
|
|
|
|
ULONG nWidth = 0;
|
|
|
|
ULONG nProWidth = 0;
|
|
|
|
|
|
|
|
while( nIdx < nEnd )
|
|
|
|
{
|
|
|
|
aIter.SeekAndChg( nIdx, pOut );
|
|
|
|
|
|
|
|
// scan for end of portion
|
|
|
|
xub_StrLen nNextChg = aIter.GetNextAttr();
|
|
|
|
xub_StrLen nStop = aScriptInfo.NextScriptChg( nIdx );
|
|
|
|
if( nNextChg > nStop )
|
|
|
|
nNextChg = nStop;
|
|
|
|
|
|
|
|
nStop = nIdx;
|
|
|
|
xub_Unicode cChar = CH_BLANK;
|
2001-03-06 15:08:39 +00:00
|
|
|
SwTxtAttr* pHint = NULL;
|
2001-02-23 08:58:03 +00:00
|
|
|
|
|
|
|
// stop at special characters in [ nIdx, nNextChg ]
|
|
|
|
while( nStop < nEnd && nStop < nNextChg )
|
|
|
|
{
|
|
|
|
cChar = aText.GetChar( nStop );
|
|
|
|
if( CH_TAB == cChar || CH_BREAK == cChar ||
|
2001-11-30 12:52:05 +00:00
|
|
|
CHAR_HARDBLANK == cChar || CHAR_HARDHYPHEN == cChar ||
|
|
|
|
CHAR_SOFTHYPHEN == cChar ||
|
2001-02-23 08:58:03 +00:00
|
|
|
( CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar ) &&
|
|
|
|
( 0 == ( pHint = aIter.GetAttr( nStop ) ) ) )
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
++nStop;
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate text widths up to cChar
|
|
|
|
if ( nStop > nIdx )
|
2001-04-09 09:44:17 +00:00
|
|
|
{
|
2003-04-01 08:56:20 +00:00
|
|
|
SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nIdx, nStop - nIdx );
|
2001-04-09 09:44:17 +00:00
|
|
|
nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
|
|
|
|
}
|
2001-02-23 08:58:03 +00:00
|
|
|
|
|
|
|
nIdx = nStop;
|
|
|
|
aIter.SeekAndChg( nIdx, pOut );
|
|
|
|
|
|
|
|
if ( cChar == CH_BREAK )
|
|
|
|
{
|
|
|
|
nWidth = Max( nWidth, nProWidth );
|
|
|
|
nProWidth = 0;
|
|
|
|
nIdx++;
|
|
|
|
}
|
|
|
|
else if ( cChar == CH_TAB )
|
|
|
|
{
|
|
|
|
// tab receives width of one space
|
2001-11-30 12:52:05 +00:00
|
|
|
XubString sTmp( CH_BLANK );
|
2003-04-01 08:56:20 +00:00
|
|
|
SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
|
2001-11-30 12:52:05 +00:00
|
|
|
nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
|
|
|
|
nIdx++;
|
|
|
|
}
|
|
|
|
else if ( cChar == CHAR_SOFTHYPHEN )
|
|
|
|
++nIdx;
|
|
|
|
else if ( cChar == CHAR_HARDBLANK || cChar == CHAR_HARDHYPHEN )
|
|
|
|
{
|
|
|
|
XubString sTmp( cChar );
|
2003-04-01 08:56:20 +00:00
|
|
|
SwDrawTextInfo aDrawInf( pSh, *pOut, 0, sTmp, 0, 1 );
|
2001-04-09 09:44:17 +00:00
|
|
|
nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
|
2001-02-23 08:58:03 +00:00
|
|
|
nIdx++;
|
|
|
|
}
|
|
|
|
else if ( pHint && ( cChar == CH_TXTATR_BREAKWORD || CH_TXTATR_INWORD ) )
|
|
|
|
{
|
|
|
|
switch( pHint->Which() )
|
|
|
|
{
|
|
|
|
case RES_TXTATR_FTN :
|
|
|
|
{
|
|
|
|
const XubString aTxt = pHint->GetFtn().GetNumStr();
|
2003-04-01 08:56:20 +00:00
|
|
|
SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );
|
2001-04-09 09:44:17 +00:00
|
|
|
|
|
|
|
nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
|
2001-02-23 08:58:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case RES_TXTATR_FIELD :
|
|
|
|
{
|
|
|
|
SwField *pFld = (SwField*)pHint->GetFld().GetFld();
|
|
|
|
const String aTxt = pFld->GetCntnt( FALSE );
|
2003-04-01 08:56:20 +00:00
|
|
|
SwDrawTextInfo aDrawInf( pSh, *pOut, 0, aTxt, 0, aTxt.Len() );
|
2001-04-09 09:44:17 +00:00
|
|
|
|
|
|
|
nProWidth += aIter.GetFnt()->_GetTxtSize( aDrawInf ).Width();
|
2001-02-23 08:58:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
// any suggestions for a default action?
|
|
|
|
}
|
|
|
|
} // end of switch
|
|
|
|
nIdx++;
|
|
|
|
} // end of while
|
|
|
|
}
|
|
|
|
|
|
|
|
nWidth = Max( nWidth, nProWidth );
|
|
|
|
|
|
|
|
// search for a text frame this node belongs to
|
|
|
|
SwClientIter aClientIter( *(SwTxtNode*)this );
|
|
|
|
SwClient* pLast = aClientIter.GoStart();
|
2001-07-17 08:11:33 +00:00
|
|
|
SwTxtFrm* pFrm = 0;
|
2001-02-23 08:58:03 +00:00
|
|
|
|
|
|
|
while( pLast )
|
|
|
|
{
|
|
|
|
if ( pLast->ISA( SwTxtFrm ) )
|
|
|
|
{
|
|
|
|
SwTxtFrm* pTmpFrm = ( SwTxtFrm* )pLast;
|
|
|
|
if ( pTmpFrm->GetOfst() <= nStt &&
|
|
|
|
( !pTmpFrm->GetFollow() ||
|
|
|
|
pTmpFrm->GetFollow()->GetOfst() > nStt ) )
|
|
|
|
{
|
|
|
|
pFrm = pTmpFrm;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pLast = ++aClientIter;
|
|
|
|
}
|
|
|
|
|
|
|
|
// search for the line containing nStt
|
|
|
|
if ( pFrm && pFrm->HasPara() )
|
|
|
|
{
|
|
|
|
SwTxtInfo aInf( pFrm );
|
|
|
|
SwTxtIter aLine( pFrm, &aInf );
|
|
|
|
aLine.CharToLine( nStt );
|
|
|
|
pOut->SetMapMode( aOldMap );
|
2001-03-05 11:54:15 +00:00
|
|
|
return (USHORT)( nWidth ?
|
|
|
|
( ( 100 * aLine.GetCurr()->Height() ) / nWidth ) : 0 );
|
2001-02-23 08:58:03 +00:00
|
|
|
}
|
|
|
|
// no frame or no paragraph, we take the height of the character
|
|
|
|
// at nStt as line height
|
|
|
|
|
|
|
|
aIter.SeekAndChg( nStt, pOut );
|
|
|
|
pOut->SetMapMode( aOldMap );
|
2001-04-09 09:44:17 +00:00
|
|
|
|
2003-04-01 08:56:20 +00:00
|
|
|
SwDrawTextInfo aDrawInf( pSh, *pOut, 0, GetTxt(), nStt, 1 );
|
2001-04-09 09:44:17 +00:00
|
|
|
return (USHORT)
|
|
|
|
( nWidth ? ((100 * aIter.GetFnt()->_GetTxtSize( aDrawInf ).Height()) / nWidth ) : 0 );
|
2001-02-23 08:58:03 +00:00
|
|
|
}
|
2004-10-22 07:13:38 +00:00
|
|
|
|
|
|
|
USHORT SwTxtNode::GetWidthOfLeadingTabs() const
|
|
|
|
{
|
|
|
|
USHORT nRet = 0;
|
|
|
|
|
2005-01-21 09:41:03 +00:00
|
|
|
xub_StrLen nIdx = 0;
|
|
|
|
sal_Unicode cCh;
|
2004-10-22 07:13:38 +00:00
|
|
|
|
2005-01-21 09:41:03 +00:00
|
|
|
while ( nIdx < GetTxt().Len() &&
|
|
|
|
( '\t' == ( cCh = GetTxt().GetChar( nIdx ) ) ||
|
|
|
|
' ' == cCh ) )
|
|
|
|
++nIdx;
|
|
|
|
|
|
|
|
if ( nIdx > 0 )
|
2004-10-22 07:13:38 +00:00
|
|
|
{
|
2005-01-21 09:41:03 +00:00
|
|
|
SwPosition aPos( *this );
|
|
|
|
aPos.nContent += nIdx;
|
|
|
|
|
|
|
|
// Find the non-follow text frame:
|
|
|
|
SwClientIter aClientIter( (SwTxtNode&)*this );
|
|
|
|
SwClient* pLast = aClientIter.GoStart();
|
2004-10-22 07:13:38 +00:00
|
|
|
|
2005-01-21 09:41:03 +00:00
|
|
|
while( pLast )
|
|
|
|
{
|
|
|
|
// Only consider master frames:
|
|
|
|
if ( pLast->ISA(SwTxtFrm) &&
|
|
|
|
!static_cast<SwTxtFrm*>(pLast)->IsFollow() )
|
2004-10-22 07:13:38 +00:00
|
|
|
{
|
2005-01-21 09:41:03 +00:00
|
|
|
const SwTxtFrm* pFrm = static_cast<SwTxtFrm*>(pLast);
|
|
|
|
SWRECTFN( pFrm )
|
|
|
|
SwRect aRect;
|
|
|
|
pFrm->GetCharRect( aRect, aPos );
|
|
|
|
nRet = (USHORT)
|
|
|
|
( pFrm->IsRightToLeft() ?
|
|
|
|
(pFrm->*fnRect->fnGetPrtRight)() - (aRect.*fnRect->fnGetRight)() :
|
|
|
|
(aRect.*fnRect->fnGetLeft)() - (pFrm->*fnRect->fnGetPrtLeft)() );
|
|
|
|
break;
|
2004-10-22 07:13:38 +00:00
|
|
|
}
|
2005-01-21 09:41:03 +00:00
|
|
|
pLast = ++aClientIter;
|
2004-10-22 07:13:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nRet;
|
|
|
|
}
|