summaryrefslogtreecommitdiff
path: root/svx/source/editeng
diff options
context:
space:
mode:
authorMathias Bauer <mba@openoffice.org>2009-09-09 11:45:13 +0200
committerMathias Bauer <mba@openoffice.org>2009-09-09 11:45:13 +0200
commitf1dd4efb7b36bd7d26ed92c7ecbbabefe67d8fb0 (patch)
treeeca2eebab12da5554e210a57e5e83353cd2f6454 /svx/source/editeng
parentdcb7e74c448f29b648d9462366b53904eb745836 (diff)
parent6738efb940d042acdeea59738b3610903ebe9a38 (diff)
merge commit to DEV300_m57
Diffstat (limited to 'svx/source/editeng')
-rw-r--r--svx/source/editeng/editdoc.cxx2
-rw-r--r--svx/source/editeng/editdoc.hxx13
-rw-r--r--svx/source/editeng/editdoc2.cxx72
-rw-r--r--svx/source/editeng/editeng.cxx31
-rw-r--r--svx/source/editeng/editobj.cxx76
-rw-r--r--svx/source/editeng/editobj2.hxx13
-rw-r--r--svx/source/editeng/edtspell.cxx25
-rw-r--r--svx/source/editeng/eertfpar.cxx13
-rw-r--r--svx/source/editeng/impedit.cxx2
-rw-r--r--svx/source/editeng/impedit.hxx4
-rw-r--r--svx/source/editeng/impedit2.cxx59
11 files changed, 272 insertions, 38 deletions
diff --git a/svx/source/editeng/editdoc.cxx b/svx/source/editeng/editdoc.cxx
index 45493a700f..7160a4197a 100644
--- a/svx/source/editeng/editdoc.cxx
+++ b/svx/source/editeng/editdoc.cxx
@@ -258,7 +258,7 @@ USHORT aV5Map[] = {
4035, 4036, 4037, 4038
};
-SV_IMPL_PTRARR( ContentList, ContentNode* );
+SV_IMPL_PTRARR( DummyContentList, ContentNode* );
SV_IMPL_VARARR( ScriptTypePosInfos, ScriptTypePosInfo );
SV_IMPL_VARARR( WritingDirectionInfos, WritingDirectionInfo );
// SV_IMPL_VARARR( ExtraCharInfos, ExtraCharInfo );
diff --git a/svx/source/editeng/editdoc.hxx b/svx/source/editeng/editdoc.hxx
index 301883042a..90efe213b6 100644
--- a/svx/source/editeng/editdoc.hxx
+++ b/svx/source/editeng/editdoc.hxx
@@ -285,7 +285,15 @@ public:
};
typedef ContentNode* ContentNodePtr;
-SV_DECL_PTRARR( ContentList, ContentNodePtr, 0, 4 )
+SV_DECL_PTRARR( DummyContentList, ContentNodePtr, 0, 4 )
+
+class ContentList : public DummyContentList
+{
+ USHORT nLastCache;
+public:
+ ContentList() : DummyContentList( 0, 4 ), nLastCache(0) {}
+ USHORT GetPos( const ContentNodePtr &rPtr ) const;
+};
// -------------------------------------------------------------------------
// class EditPaM
@@ -612,6 +620,7 @@ SV_DECL_PTRARR( DummyParaPortionList, ParaPortionPtr, 0, 4 )
// -------------------------------------------------------------------------
class ParaPortionList : public DummyParaPortionList
{
+ USHORT nLastCache;
public:
ParaPortionList();
~ParaPortionList();
@@ -623,6 +632,8 @@ public:
inline ParaPortion* SaveGetObject( USHORT nPos ) const
{ return ( nPos < Count() ) ? GetObject( nPos ) : 0; }
+ USHORT GetPos( const ParaPortionPtr &rPtr ) const;
+
// temporaer:
void DbgCheck( EditDoc& rDoc );
};
diff --git a/svx/source/editeng/editdoc2.cxx b/svx/source/editeng/editdoc2.cxx
index c24910a6ca..e0d5fc27e9 100644
--- a/svx/source/editeng/editdoc2.cxx
+++ b/svx/source/editeng/editdoc2.cxx
@@ -1,7 +1,7 @@
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
+ *
* Copyright 2008 by Sun Microsystems, Inc.
*
* OpenOffice.org - a multi-platform office productivity suite
@@ -151,14 +151,14 @@ USHORT TextPortionList::GetStartPos( USHORT nPortion )
// -------------------------------------------------------------------------
ExtraPortionInfo::ExtraPortionInfo()
-{
- nOrgWidth = 0;
- nWidthFullCompression = 0;
+{
+ nOrgWidth = 0;
+ nWidthFullCompression = 0;
nMaxCompression100thPercent = 0;
- nAsianCompressionTypes = 0;
- nPortionOffsetX = 0;
- bFirstCharIsRightPunktuation = FALSE;
- bCompressed = FALSE;
+ nAsianCompressionTypes = 0;
+ nPortionOffsetX = 0;
+ bFirstCharIsRightPunktuation = FALSE;
+ bCompressed = FALSE;
pOrgDXArray = NULL;
}
@@ -167,7 +167,7 @@ ExtraPortionInfo::~ExtraPortionInfo()
delete[] pOrgDXArray;
}
-void ExtraPortionInfo::SaveOrgDXArray( const sal_Int32* pDXArray, USHORT nLen )
+void ExtraPortionInfo::SaveOrgDXArray( const sal_Int32* pDXArray, USHORT nLen )
{
delete[] pOrgDXArray;
pOrgDXArray = new sal_Int32[nLen];
@@ -324,10 +324,42 @@ void ParaPortion::CorrectValuesBehindLastFormattedLine( USHORT nLastFormattedLin
DBG_ASSERT( aLineList[ aLineList.Count()-1 ]->GetEnd() == pNode->Len(), "CorrectLines: Ende stimmt nicht!" );
}
- // -------------------------------------------------------------------------
+// Shared reverse lookup acceleration pieces ...
+
+static USHORT FastGetPos( const VoidPtr *pPtrArray, USHORT nPtrArrayLen,
+ VoidPtr pPtr, USHORT &rLastPos )
+{
+ // Through certain filter code-paths we do a lot of appends, which in
+ // turn call GetPos - creating some N^2 nightmares. If we have a
+ // non-trivially large list, do a few checks from the end first.
+ if( rLastPos > 16 )
+ {
+ USHORT nEnd;
+ if (rLastPos > nPtrArrayLen - 2)
+ nEnd = nPtrArrayLen;
+ else
+ nEnd = rLastPos + 2;
+
+ for( USHORT nIdx = rLastPos - 2; nIdx < nEnd; nIdx++ )
+ {
+ if( pPtrArray[ nIdx ] == pPtr )
+ {
+ rLastPos = nIdx;
+ return nIdx;
+ }
+ }
+ }
+ // The world's lamest linear search from svarray ...
+ for( USHORT nIdx = 0; nIdx < nPtrArrayLen; nIdx++ )
+ if (pPtrArray[ nIdx ] == pPtr )
+ return rLastPos = nIdx;
+ return USHRT_MAX;
+}
+
+// -------------------------------------------------------------------------
// class ParaPortionList
// -------------------------------------------------------------------------
-ParaPortionList::ParaPortionList()
+ParaPortionList::ParaPortionList() : nLastCache( 0 )
{
}
@@ -336,6 +368,20 @@ ParaPortionList::~ParaPortionList()
Reset();
}
+USHORT ParaPortionList::GetPos( const ParaPortionPtr &rPtr ) const
+{
+ return FastGetPos( reinterpret_cast<const VoidPtr *>( GetData() ),
+ Count(), static_cast<VoidPtr>( rPtr ),
+ ((ParaPortionList *)this)->nLastCache );
+}
+
+USHORT ContentList::GetPos( const ContentNodePtr &rPtr ) const
+{
+ return FastGetPos( reinterpret_cast<const VoidPtr *>( GetData() ),
+ Count(), static_cast<VoidPtr>( rPtr ),
+ ((ContentList *)this)->nLastCache );
+}
+
void ParaPortionList::Reset()
{
for ( USHORT nPortion = 0; nPortion < Count(); nPortion++ )
@@ -369,10 +415,10 @@ USHORT ParaPortionList::FindParagraph( long nYOffset )
return 0xFFFF; // solte mal ueber EE_PARA_NOT_FOUND erreicht werden!
}
-void ParaPortionList::DbgCheck( EditDoc&
+void ParaPortionList::DbgCheck( EditDoc&
#ifdef DBG_UTIL
rDoc
-#endif
+#endif
)
{
#ifdef DBG_UTIL
diff --git a/svx/source/editeng/editeng.cxx b/svx/source/editeng/editeng.cxx
index 05bfdea5bf..80027fff73 100644
--- a/svx/source/editeng/editeng.cxx
+++ b/svx/source/editeng/editeng.cxx
@@ -86,11 +86,9 @@
#include <vcl/help.hxx>
#include <svx/xpoly.hxx>
#include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
-#ifndef _COM_SUN_STAR_I18N_XINPUTSEQUENCECHECKER_HPP_
#include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
-#endif
-#include <srchdlg.hxx>
+#include <sfx2/srchdefs.hxx>
#if OSL_DEBUG_LEVEL > 1
#include <svx/frmdiritem.hxx>
@@ -99,18 +97,11 @@
// Spaeter -> TOOLS\STRING.H (fuer Grep: WS_TARGET)
-//using namespace ::rtl;
-//using namespace ::utl;
using namespace ::com::sun::star;
-//using namespace ::com::sun::star::util;
using namespace ::com::sun::star::uno;
-//using namespace ::com::sun::star::lang;
-//using namespace ::com::sun::star::beans;
-//using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::linguistic2;
-
DBG_NAME( EditEngine )
DBG_NAMEEX( EditView )
@@ -706,14 +697,34 @@ sal_uInt16 EditEngine::GetParagraphCount() const
sal_uInt16 EditEngine::GetLineCount( sal_uInt16 nParagraph ) const
{
DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
return pImpEditEngine->GetLineCount( nParagraph );
}
sal_uInt16 EditEngine::GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const
{
DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
return pImpEditEngine->GetLineLen( nParagraph, nLine );
}
+
+void EditEngine::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineBoundaries( rStart, rEnd, nParagraph, nLine );
+}
+
+USHORT EditEngine::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ DBG_CHKTHIS( EditEngine, 0 );
+ if ( !pImpEditEngine->IsFormatted() )
+ pImpEditEngine->FormatDoc();
+ return pImpEditEngine->GetLineNumberAtIndex( nPara, nIndex );
+}
sal_uInt32 EditEngine::GetLineHeight( sal_uInt16 nParagraph, sal_uInt16 nLine )
{
diff --git a/svx/source/editeng/editobj.cxx b/svx/source/editeng/editobj.cxx
index a9d3bca341..d8f0a332b9 100644
--- a/svx/source/editeng/editobj.cxx
+++ b/svx/source/editeng/editobj.cxx
@@ -253,6 +253,18 @@ void ContentInfo::DestroyLoadStoreTempInfos()
}
*/
+// #i102062#
+bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
+{
+ if(GetWrongList() == rCompare.GetWrongList())
+ return true;
+
+ if(!GetWrongList() || !rCompare.GetWrongList())
+ return false;
+
+ return (*GetWrongList() == *rCompare.GetWrongList());
+}
+
bool ContentInfo::operator==( const ContentInfo& rCompare ) const
{
if( (aText == rCompare.aText) &&
@@ -566,6 +578,12 @@ bool EditTextObject::operator==( const EditTextObject& rCompare ) const
return static_cast< const BinTextObject* >( this )->operator==( static_cast< const BinTextObject& >( rCompare ) );
}
+// #i102062#
+bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
+{
+ return static_cast< const BinTextObject* >(this)->isWrongListEqual(static_cast< const BinTextObject& >(rCompare));
+}
+
// from SfxItemPoolUser
void BinTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
{
@@ -599,6 +617,23 @@ void BinTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
}
}
+EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool)
+{
+ EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
+
+ while(!pRetval && pPool && pPool->GetSecondaryPool())
+ {
+ pPool = pPool->GetSecondaryPool();
+
+ if(pPool)
+ {
+ pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
+ }
+ }
+
+ return pRetval;
+}
+
BinTextObject::BinTextObject( SfxItemPool* pP ) :
EditTextObject( EE_FORMAT_BIN ),
SfxItemPoolUser()
@@ -608,9 +643,17 @@ BinTextObject::BinTextObject( SfxItemPool* pP ) :
nUserType = 0;
nObjSettings = 0;
pPortionInfo = 0;
- if ( pP )
+
+ // #i101239# ensure target is a EditEngineItemPool, else
+ // fallback to pool ownership. This is needed to ensure that at
+ // pool destruction time of an alien pool, the pool is still alive.
+ // When registering would happen at an alien pool which just uses an
+ // EditEngineItemPool as some sub-pool, that pool could already
+ // be decoupled and deleted whcih would lead to crashes.
+ pPool = getEditEngineItemPool(pP);
+
+ if ( pPool )
{
- pPool = pP;
bOwnerOfPool = FALSE;
}
else
@@ -621,6 +664,7 @@ BinTextObject::BinTextObject( SfxItemPool* pP ) :
if(!bOwnerOfPool && pPool)
{
+ // it is sure now that the pool is an EditEngineItemPool
pPool->AddSfxItemPoolUser(*this);
}
@@ -641,9 +685,12 @@ BinTextObject::BinTextObject( const BinTextObject& r ) :
nScriptType = r.nScriptType;
pPortionInfo = NULL; // PortionInfo nicht kopieren
bStoreUnicodeStrings = FALSE;
+
if ( !r.bOwnerOfPool )
{
- // Dann den Pool mitverwenden
+ // reuse alien pool; this must be a EditEngineItemPool
+ // since there is no other way to construct a BinTextObject
+ // than it's regular constructor where that is ensured
pPool = r.pPool;
bOwnerOfPool = FALSE;
}
@@ -656,6 +703,7 @@ BinTextObject::BinTextObject( const BinTextObject& r ) :
if(!bOwnerOfPool && pPool)
{
+ // it is sure now that the pool is an EditEngineItemPool
pPool->AddSfxItemPoolUser(*this);
}
@@ -1589,6 +1637,28 @@ bool BinTextObject::operator==( const BinTextObject& rCompare ) const
return true;
}
+// #i102062#
+bool BinTextObject::isWrongListEqual(const BinTextObject& rCompare) const
+{
+ if(GetContents().Count() != rCompare.GetContents().Count())
+ {
+ return false;
+ }
+
+ for(USHORT a(0); a < GetContents().Count(); a++)
+ {
+ const ContentInfo& rCandA(*GetContents().GetObject(a));
+ const ContentInfo& rCandB(*rCompare.GetContents().GetObject(a));
+
+ if(!rCandA.isWrongListEqual(rCandB))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
#define CHARSETMARKER 0x9999
void __EXPORT BinTextObject::CreateData300( SvStream& rIStream )
diff --git a/svx/source/editeng/editobj2.hxx b/svx/source/editeng/editobj2.hxx
index c61a198f47..b37ceabbd7 100644
--- a/svx/source/editeng/editobj2.hxx
+++ b/svx/source/editeng/editobj2.hxx
@@ -181,13 +181,10 @@ public:
WrongList* GetWrongList() const { return pWrongs; }
void SetWrongList( WrongList* p ) { pWrongs = p; }
-
-/* cl removed because not needed anymore since binfilter
- LoadStoreTempInfos* GetLoadStoreTempInfos() const { return pTempLoadStoreInfos; }
- void CreateLoadStoreTempInfos();
- void DestroyLoadStoreTempInfos();
-*/
bool operator==( const ContentInfo& rCompare ) const;
+
+ // #i102062#
+ bool isWrongListEqual(const ContentInfo& rCompare) const;
};
typedef ContentInfo* ContentInfoPtr;
@@ -198,6 +195,7 @@ SV_DECL_PTRARR( ContentInfoList, ContentInfoPtr, 1, 4 )
class BinTextObject : public EditTextObject, public SfxItemPoolUser
{
using EditTextObject::operator==;
+ using EditTextObject::isWrongListEqual;
private:
ContentInfoList aContents;
@@ -303,6 +301,9 @@ public:
bool operator==( const BinTextObject& rCompare ) const;
+ // #i102062#
+ bool isWrongListEqual(const BinTextObject& rCompare) const;
+
// from SfxItemPoolUser
virtual void ObjectInDestruction(const SfxItemPool& rSfxItemPool);
};
diff --git a/svx/source/editeng/edtspell.cxx b/svx/source/editeng/edtspell.cxx
index cad0602529..2fb92641ef 100644
--- a/svx/source/editeng/edtspell.cxx
+++ b/svx/source/editeng/edtspell.cxx
@@ -476,6 +476,31 @@ WrongList* WrongList::Clone() const
return pNew;
}
+// #i102062#
+bool WrongList::operator==(const WrongList& rCompare) const
+{
+ // cleck direct members
+ if(GetInvalidStart() != rCompare.GetInvalidStart()
+ || GetInvalidEnd() != rCompare.GetInvalidEnd()
+ || Count() != rCompare.Count())
+ {
+ return false;
+ }
+
+ for(USHORT a(0); a < Count(); a++)
+ {
+ const WrongRange& rCandA(GetObject(a));
+ const WrongRange& rCandB(rCompare.GetObject(a));
+
+ if(rCandA.nStart != rCandB.nStart
+ || rCandA.nEnd != rCandB.nEnd)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
#ifdef DBG_UTIL
sal_Bool WrongList::DbgIsBuggy() const
diff --git a/svx/source/editeng/eertfpar.cxx b/svx/source/editeng/eertfpar.cxx
index b4e504b829..65c1b6c516 100644
--- a/svx/source/editeng/eertfpar.cxx
+++ b/svx/source/editeng/eertfpar.cxx
@@ -43,6 +43,19 @@
#include <svtools/rtftoken.h>
+// alle Werte auf default; wird nach einlesen der Bitmap aufgerufen !
+void SvxRTFPictureType::ResetValues()
+{ // setze alle Werte RTF-Defaults
+ eStyle = RTF_BITMAP;
+ nMode = HEX_MODE;
+ nType = nGoalWidth = nGoalHeight = 0;
+ nWidth = nHeight = nWidthBytes = 0;
+ uPicLen = 0;
+ nBitsPerPixel = nPlanes = 1;
+ nScalX = nScalY = 100; // Skalierung in Prozent
+ nCropT = nCropB = nCropL = nCropR = 0;
+}
+
ImportInfo::ImportInfo( ImportState eSt, SvParser* pPrsrs, const ESelection& rSel )
: aSelection( rSel )
{
diff --git a/svx/source/editeng/impedit.cxx b/svx/source/editeng/impedit.cxx
index 72dd53d026..51dff075be 100644
--- a/svx/source/editeng/impedit.cxx
+++ b/svx/source/editeng/impedit.cxx
@@ -670,6 +670,8 @@ void ImpEditView::ShowCursor( sal_Bool bGotoCursor, sal_Bool bForceVisCursor, US
USHORT nTextPortionStart = 0;
USHORT nPara = pEditEngine->pImpEditEngine->aEditDoc.GetPos( aPaM.GetNode() );
+ if (nPara == USHRT_MAX) // #i94322
+ return;
ParaPortion* pParaPortion = pEditEngine->pImpEditEngine->GetParaPortions().GetObject( nPara );
nShowCursorFlags |= nExtraCursorFlags;
diff --git a/svx/source/editeng/impedit.hxx b/svx/source/editeng/impedit.hxx
index 9a1f3002f8..adf6afb7c2 100644
--- a/svx/source/editeng/impedit.hxx
+++ b/svx/source/editeng/impedit.hxx
@@ -812,7 +812,9 @@ public:
sal_uInt32 CalcTextWidth( BOOL bIgnoreExtraSpace );
sal_uInt32 CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, BOOL bIgnoreExtraSpace );
sal_uInt16 GetLineCount( sal_uInt16 nParagraph ) const;
- sal_uInt16 GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const;
+ sal_uInt16 GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const;
+ void GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const;
+ USHORT GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const;
sal_uInt16 GetLineHeight( sal_uInt16 nParagraph, sal_uInt16 nLine );
sal_uInt32 GetParaHeight( sal_uInt16 nParagraph );
diff --git a/svx/source/editeng/impedit2.cxx b/svx/source/editeng/impedit2.cxx
index ed4c843d82..6be5fc0ef0 100644
--- a/svx/source/editeng/impedit2.cxx
+++ b/svx/source/editeng/impedit2.cxx
@@ -1777,7 +1777,7 @@ void ImpEditEngine::InitScriptTypes( USHORT nPara )
::rtl::OUString aOUText( aText );
USHORT nTextLen = (USHORT)aOUText.getLength();
- long nPos = 0;
+ sal_Int32 nPos = 0;
short nScriptType = _xBI->getScriptType( aOUText, nPos );
rTypes.Insert( ScriptTypePosInfo( nScriptType, (USHORT)nPos, nTextLen ), rTypes.Count() );
nPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
@@ -1795,6 +1795,17 @@ void ImpEditEngine::InitScriptTypes( USHORT nPara )
}
else
{
+ if ( _xBI->getScriptType( aOUText, nPos - 1 ) == i18n::ScriptType::WEAK )
+ {
+ switch ( u_charType(aOUText.iterateCodePoints(&nPos, 0) ) ) {
+ case U_NON_SPACING_MARK:
+ case U_ENCLOSING_MARK:
+ case U_COMBINING_SPACING_MARK:
+ --nPos;
+ rTypes[rTypes.Count()-1].nEndPos--;
+ break;
+ }
+ }
rTypes.Insert( ScriptTypePosInfo( nScriptType, (USHORT)nPos, nTextLen ), rTypes.Count() );
}
@@ -3289,9 +3300,9 @@ USHORT ImpEditEngine::GetLineCount( USHORT nParagraph ) const
xub_StrLen ImpEditEngine::GetLineLen( USHORT nParagraph, USHORT nLine ) const
{
- DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
+ DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineLen: Out of range" );
ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
- DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineHeight" );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineLen" );
if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
{
EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
@@ -3302,6 +3313,48 @@ xub_StrLen ImpEditEngine::GetLineLen( USHORT nParagraph, USHORT nLine ) const
return 0xFFFF;
}
+void ImpEditEngine::GetLineBoundaries( /*out*/USHORT &rStart, /*out*/USHORT &rEnd, USHORT nParagraph, USHORT nLine ) const
+{
+ DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
+ ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
+ DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineBoundaries" );
+ rStart = rEnd = 0xFFFF; // default values in case of error
+ if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
+ {
+ EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
+ DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineBoundaries" );
+ rStart = pLine->GetStart();
+ rEnd = pLine->GetEnd();
+ }
+}
+
+USHORT ImpEditEngine::GetLineNumberAtIndex( USHORT nPara, USHORT nIndex ) const
+{
+ USHORT nLineNo = 0xFFFF;
+ ContentNode* pNode = GetEditDoc().SaveGetObject( nPara );
+ DBG_ASSERT( pNode, "GetLineNumberAtIndex: invalid paragraph index" );
+ if (pNode)
+ {
+ // we explicitly allow for the index to point at the character right behind the text
+ const bool bValidIndex = /*0 <= nIndex &&*/ nIndex <= pNode->Len();
+ DBG_ASSERT( bValidIndex, "GetLineNumberAtIndex: invalid index" );
+ const USHORT nLineCount = GetLineCount( nPara );
+ if (nIndex == pNode->Len())
+ nLineNo = nLineCount > 0 ? nLineCount - 1 : 0;
+ else if (bValidIndex) // nIndex < pNode->Len()
+ {
+ USHORT nStart = USHRT_MAX, nEnd = USHRT_MAX;
+ for (USHORT i = 0; i < nLineCount && nLineNo == 0xFFFF; ++i)
+ {
+ GetLineBoundaries( nStart, nEnd, nPara, i );
+ if (nStart <= nIndex && nIndex < nEnd)
+ nLineNo = i;
+ }
+ }
+ }
+ return nLineNo;
+}
+
USHORT ImpEditEngine::GetLineHeight( USHORT nParagraph, USHORT nLine )
{
DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );