/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 .
*/
// Not reentrant !!! // is set in GetCharRect and is interpreted in UnitUp/Down. bool SwTextCursor::s_bRightMargin = false;
// After calculating the position of a character during GetCharRect // this function allows to find the coordinates of a position (defined // in pCMS->pSpecialPos) inside a special portion (e.g., a field) staticvoid lcl_GetCharRectInsideField( SwTextSizeInfo& rInf, SwRect& rOrig, const SwCursorMoveState& rCMS, const SwLinePortion& rPor )
{
assert(rCMS.m_pSpecialPos && "Information about special pos missing");
// This whole area desperately needs some rework. There are // quite a couple of values that need to be considered: // 1. paragraph indent // 2. paragraph first line indent // 3. numbering indent // 4. numbering spacing to text // 5. paragraph border // Note: These values have already been used during calculation // of the printing area of the paragraph. constint nLMWithNum = pNode->GetLeftMarginWithNum( true ); if ( m_pFrame->IsRightToLeft() )
{ // this calculation is identical this the calculation for L2R layout - see below
mnLeft = m_pFrame->getFrameArea().Left() + m_pFrame->getFramePrintArea().Left() + nLMWithNum
- pNode->GetLeftMarginWithNum() - // #i95907# // #i111284# // rSpace.GetLeft() + rSpace.GetTextLeft();
(rTextLeftMargin.ResolveLeft(rFirstLine, stMetrics)
- rTextLeftMargin.ResolveTextLeft(stMetrics));
} else
{ // #i95907# // #i111284# if ( bListLevelIndentsApplicableAndLabelAlignmentActive ||
!pNode->getIDocumentSettingAccess()->get(DocumentSettingId::IGNORE_FIRST_LINE_INDENT_IN_NUMBERING) )
{ // this calculation is identical this the calculation for R2L layout - see above
mnLeft = m_pFrame->getFrameArea().Left() + m_pFrame->getFramePrintArea().Left()
+ nLMWithNum - pNode->GetLeftMarginWithNum() - // #i95907# // #i111284#
(rTextLeftMargin.ResolveLeft(rFirstLine, stMetrics)
- rTextLeftMargin.ResolveTextLeft(stMetrics));
} else
{
mnLeft
= m_pFrame->getFrameArea().Left()
+ std::max(tools::Long(rTextLeftMargin.ResolveTextLeft(stMetrics) + nLMWithNum),
m_pFrame->getFramePrintArea().Left());
}
}
// tdf#129448: Auto first-line indent should not be effected by line space. // Below is for compatibility with old documents. if (!pNode->getIDocumentSettingAccess()->get(DocumentSettingId::AUTO_FIRST_LINE_INDENT_DISREGARD_LINE_SPACE))
{ const SvxLineSpacingItem *pSpace = m_aLineInf.GetLineSpacing(); if( pSpace )
{ switch( pSpace->GetLineSpaceRule() )
{ case SvxLineSpaceRule::Auto: break; case SvxLineSpaceRule::Min:
{ if( nFirstLineOfs < pSpace->GetLineHeight() )
nFirstLineOfs = pSpace->GetLineHeight(); break;
} case SvxLineSpaceRule::Fix:
nFirstLineOfs = pSpace->GetLineHeight(); break; default: OSL_FAIL( ": unknown LineSpaceRule" );
} switch( pSpace->GetInterLineSpaceRule() )
{ case SvxInterLineSpaceRule::Off: break; case SvxInterLineSpaceRule::Prop:
{
tools::Long nTmp = pSpace->GetPropLineSpace(); // 50% is the minimum, at 0% we switch to // the default value 100%... if( nTmp < 50 )
nTmp = nTmp ? 50 : 100;
// Note: <SwTextFrame::GetAdditionalFirstLineOffset()> returns a negative // value for the new list label position and space mode LABEL_ALIGNMENT // and label alignment CENTER and RIGHT in L2R layout respectively // label alignment LEFT and CENTER in R2L layout
mnFirst += m_pFrame->GetAdditionalFirstLineOffset();
// left is left and right is right if ( m_pFrame->IsRightToLeft() )
{ if ( SvxAdjust::Left == mnAdjust )
mnAdjust = SvxAdjust::Right; elseif ( SvxAdjust::Right == mnAdjust )
mnAdjust = SvxAdjust::Left;
}
// The function is interpreting / observing / evaluating / keeping / respecting the first line indention and the specified width.
SwTwips SwTextMargin::GetLineStart() const
{
SwTwips nRet = GetLeftMargin(); if( GetAdjust() != SvxAdjust::Left &&
!m_pCurr->GetFirstPortion()->IsMarginPortion() )
{ // If the first portion is a Margin, then the // adjustment is expressed by the portions. if( GetAdjust() == SvxAdjust::Right )
nRet = Right() - CurrWidth(); elseif( GetAdjust() == SvxAdjust::Center )
nRet += (GetLineWidth() - CurrWidth()) / 2;
} return nRet;
}
staticbool isTrailingDecoration(SwLinePortion* p)
{ // Optional no-width portion, followed only by no-width portions and/or terminating portions? for (; p; p = p->GetNextPortion())
{ if (p->IsMarginPortion() || p->IsBreakPortion()) returntrue; if (p->Width()) returnfalse;
} returntrue; // no more portions
}
// tdf#120715 tdf#43100: Make width for some HolePortions, so cursor will be able to move into it. // It should not change the layout, so this should be called after the layout is calculated. void SwTextCursor::AddExtraBlankWidth()
{
SwLinePortion* pPos = m_pCurr->GetNextPortion(); while (pPos)
{
SwLinePortion* pNextPos = pPos->GetNextPortion(); // Do it only if it is the last portion that able to handle the cursor, // else the next portion would miscalculate the cursor position if (pPos->ExtraBlankWidth() && isTrailingDecoration(pNextPos))
{
pPos->Width(pPos->Width() + pPos->ExtraBlankWidth());
pPos->ExtraBlankWidth(0);
}
pPos = pNextPos;
}
}
// 1170: Ancient bug: Shift-End forgets the last character ... void SwTextCursor::GetEndCharRect(SwRect* pOrig, const TextFrameIndex nOfst,
SwCursorMoveState* pCMS, const tools::Long nMax )
{ // 1170: Ambiguity of document positions
s_bRightMargin = true;
CharCursorToLine(nOfst);
// Somehow twisted: nOfst names the position behind the last // character of the last line == This is the position in front of the first character // of the line, in which we are situated: if( nOfst != GetStart() || !m_pCurr->GetLen() )
{ // 8810: Master line RightMargin, after that LeftMargin
GetCharRect( pOrig, nOfst, pCMS, nMax );
s_bRightMargin = nOfst >= GetEnd() && nOfst < TextFrameIndex(GetInfo().GetText().getLength()); return;
}
// internal function, called by SwTextCursor::GetCharRect() to calculate // the relative character position in the current line. // pOrig refers to x and y coordinates, width and height of the cursor // pCMS is used for restricting the cursor, if there are different font // heights in one line ( first value = offset to y of pOrig, second // value = real height of (shortened) cursor void SwTextCursor::GetCharRect_( SwRect* pOrig, TextFrameIndex const nOfst,
SwCursorMoveState* pCMS )
{ const OUString aText = GetInfo().GetText();
SwTextSizeInfo aInf( GetInfo(), &aText, m_nStart ); if( GetPropFont() )
aInf.GetFont()->SetProportion( GetPropFont() );
SwTwips nTmpAscent, nTmpHeight; // Line height
CalcAscentAndHeight( nTmpAscent, nTmpHeight ); const Size aCharSize( 1, nTmpHeight ); const Point aCharPos;
pOrig->Pos( aCharPos );
pOrig->SSize( aCharSize );
// If we are looking for a position inside a field which covers // more than one line we may not skip any "empty portions" at the // beginning of a line constbool bInsideFirstField = pCMS && pCMS->m_pSpecialPos &&
( pCMS->m_pSpecialPos->nLineOfst ||
SwSPExtendRange::BEFORE ==
pCMS->m_pSpecialPos->nExtendRange );
// First all portions without Len at beginning of line are skipped. // Exceptions are the mean special portions from WhichFirstPortion: // Num, ErgoSum, FootnoteNum, FieldRests // 8477: but also the only Textportion of an empty line with // Right/Center-Adjustment! So not just pPor->GetExpandPortion() ... while( pPor && !pPor->GetLen() && ! bInsideFirstField )
{
nX += pPor->Width(); if ( pPor->InSpaceGrp() && nSpaceAdd )
nX += pPor->CalcSpacing( nSpaceAdd, aInf ); if( bNoText )
nTmpFirst = nX; // 8670: EndPortions count once as TextPortions. // if( pPor->InTextGrp() || pPor->IsBreakPortion() ) if( pPor->InTextGrp() || pPor->IsBreakPortion() || pPor->InTabGrp() )
{
bNoText = false;
nTmpFirst = nX;
} if( pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
{ if ( m_pCurr->IsSpaceAdd() )
{ if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx ); else
nSpaceAdd = 0;
}
// If we are behind the portion, we add the portion width to // nX. Special case: nOfst = aInf.GetIdx() + pPor->GetLen(). // For common portions (including BidiPortions) we want to add // the portion width to nX. For MultiPortions, nExtra = 0, // therefore we go to the 'else' branch and start a recursion. const TextFrameIndex nExtra( (pPor->IsMultiPortion()
&& !static_cast<SwMultiPortion*>(pPor)->IsBidi()
&& !bWidth)
? 0 : 1 ); if ( aInf.GetIdx() + pPor->GetLen() < nOfst + nExtra )
{ if ( pPor->InSpaceGrp() && nSpaceAdd ) // tdf#163042 In the case of shrunk lines with a single portion, // adjust the line width to show the cursor in the correct position
nX += ( ( std::abs( m_pCurr->Width() - pPor->PrtWidth() ) <= 1 &&
m_pCurr->ExtraShrunkWidth() > 0 )
? m_pCurr->ExtraShrunkWidth()
: pPor->PrtWidth() ) +
pPor->CalcSpacing( nSpaceAdd, aInf ); else
{ if( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() )
{ // update to current SpaceAdd, KanaComp values if ( m_pCurr->IsSpaceAdd() )
{ if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx ); else
nSpaceAdd = 0;
}
// if we are right behind a BidiPortion, we have to // hold a pointer to the BidiPortion in order to // find the correct cursor position, depending on the // cursor level if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() &&
aInf.GetIdx() + pPor->GetLen() == nOfst )
{
pLastBidiPor = static_cast<SwBidiPortion*>(pPor);
nLastBidiIdx = aInf.GetIdx();
nLastBidiPorWidth = pLastBidiPor->Width() +
pLastBidiPor->CalcSpacing( nSpaceAdd, aInf );
}
}
if( m_nStart + m_pCurr->GetLen() <= nOfst && GetNext() &&
( ! static_cast<SwMultiPortion*>(pPor)->IsRuby() || static_cast<SwMultiPortion*>(pPor)->OnTop() ) )
{
sal_uInt16 nOffset; // in grid mode we may only add the height of the // ruby line if ruby line is on top if ( bHasGrid && static_cast<SwMultiPortion*>(pPor)->IsRuby() && static_cast<SwMultiPortion*>(pPor)->OnTop() )
nOffset = nRubyHeight; else
nOffset = GetLineHeight();
// Ok, for ruby portions in grid mode we have to // temporarily set the inner line height to the // outer line height because that value is needed // for the adjustment inside the recursion const sal_uInt16 nOldRubyHeight = m_pCurr->Height(); const sal_uInt16 nOldRubyRealHeight = m_pCurr->GetRealHeight(); constbool bChgHeight = static_cast<SwMultiPortion*>(pPor)->IsRuby() && bHasGrid;
// if we are still in the first row of // our 2 line multiportion, we use the FirstMulti flag // to indicate this if ( static_cast<SwMultiPortion*>(pPor)->IsDouble() )
{ // the recursion may have damaged our font size
SetPropFont( nOldProp );
GetInfo().GetFont()->SetProportion( 100 );
if ( m_pCurr == &static_cast<SwMultiPortion*>(pPor)->GetRoot() )
{
GetInfo().SetFirstMulti( true );
// we want to treat a double line portion like a // single line portion, if there is no text in // the second line if ( !m_pCurr->GetNext() ||
!m_pCurr->GetNext()->GetLen() )
GetInfo().SetMulti( false );
}
} // ruby portions are treated like single line portions elseif( static_cast<SwMultiPortion*>(pPor)->IsRuby() || static_cast<SwMultiPortion*>(pPor)->IsBidi() )
GetInfo().SetMulti( false );
// if we travel into our rotated portion from // a line below, we have to take care, that the // y coord in pOrig is less than line height: if ( nTmp )
nTmp--;
pOrig->Pos().setX( nX + aOldPos.X() ); if( static_cast<SwMultiPortion*>(pPor)->IsRevers() )
pOrig->Pos().setY( aOldPos.Y() + nTmp ); else
pOrig->Pos().setY( aOldPos.Y()
+ pPor->Height() - nTmp - pOrig->Height() ); if ( pCMS && pCMS->m_bRealHeight )
{
pCMS->m_aRealHeight.setY( -pCMS->m_aRealHeight.Y() ); // result for rotated multi portion is not // correct for reverse (270 degree) portions if( static_cast<SwMultiPortion*>(pPor)->IsRevers() )
{ if ( SvxParaVertAlignItem::Align::Automatic ==
GetLineInfo().GetVertAlign() ) // if vertical alignment is set to auto, // we switch from base line alignment // to centered alignment
pCMS->m_aRealHeight.setX(
( pOrig->Width() +
pCMS->m_aRealHeight.Y() ) / 2 ); else
pCMS->m_aRealHeight.setX(
pOrig->Width() -
pCMS->m_aRealHeight.X() +
pCMS->m_aRealHeight.Y() );
}
}
} else
{
pOrig->Pos().AdjustY(aOldPos.Y() ); if ( static_cast<SwMultiPortion*>(pPor)->IsBidi() )
{ const SwTwips nPorWidth = pPor->Width() +
pPor->CalcSpacing( nSpaceAdd, aInf ); const SwTwips nInsideOfst = pOrig->Pos().X();
pOrig->Pos().setX( nX + nPorWidth -
nInsideOfst - pOrig->Width() );
} else
pOrig->Pos().AdjustX(nX );
if( aInf.GetIdx() == nOfst && pPor && pPor->InHyphGrp() &&
pPor->GetNextPortion() && pPor->GetNextPortion()->InFixGrp() )
{ // All special portions have to be skipped // Taking the German word "zusammen" as example: zu-[FLY]sammen, 'u' == 19, 's' == 20; Right() // Without the adjustment we end up in front of '-', with the // adjustment in front of the 's'. while( pPor && !pPor->GetLen() )
{
nX += pPor->Width(); if( !pPor->IsMarginPortion() )
{
nPorHeight = pPor->Height();
nPorAscent = pPor->GetAscent();
}
pPor = pPor->GetNextPortion();
}
} if( pPor && pCMS )
{ if( pCMS->m_bFieldInfo && pPor->InFieldGrp() && pPor->Width() )
pOrig->Width( pPor->Width() ); if( pPor->IsDropPortion() )
{
nPorAscent = static_cast<SwDropPortion*>(pPor)->GetDropHeight(); // The drop height is only calculated, if we have more than // one line. Otherwise it is 0. if ( ! nPorAscent)
nPorAscent = pPor->Height();
nPorHeight = nPorAscent;
pOrig->Height( nPorHeight + static_cast<SwDropPortion*>(pPor)->GetDropDescent() ); if( nTmpHeight < pOrig->Height() )
{
nTmpAscent = nPorAscent;
nTmpHeight = sal_uInt16( pOrig->Height() );
}
} if( bWidth && pPor->PrtWidth() && pPor->GetLen() &&
aInf.GetIdx() == nOfst )
{ if( !pPor->IsFlyPortion() && pPor->Height() &&
pPor->GetAscent() )
{
nPorHeight = pPor->Height();
nPorAscent = pPor->GetAscent();
}
SwTwips nTmp; if (TextFrameIndex(2) > pPor->GetLen())
{
nTmp = pPor->Width(); if ( pPor->InSpaceGrp() && nSpaceAdd )
nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
} else
{ constbool bOldOnWin = aInf.OnWin();
TextFrameIndex const nOldLen = pPor->GetLen();
aInf.SetLen( pPor->GetLen() );
pPor->SetLen( TextFrameIndex(1) );
aInf.SetMeasureLen(pPor->GetLen()); if (aInf.GetLen() < aInf.GetMeasureLen())
{
pPor->SetLen(aInf.GetMeasureLen());
aInf.SetLen(pPor->GetLen());
}
SeekAndChg( aInf );
aInf.SetOnWin( false ); // no BULLETs!
aInf.SetKanaComp( pKanaComp );
aInf.SetKanaIdx( nKanaIdx );
nTmp = pPor->GetTextSize( aInf ).Width();
aInf.SetOnWin( bOldOnWin ); if ( pPor->InSpaceGrp() && nSpaceAdd )
nTmp += pPor->CalcSpacing( nSpaceAdd, aInf );
pPor->SetLen( nOldLen );
}
pOrig->Width( nTmp );
}
// travel inside field portion? if ( pCMS->m_pSpecialPos )
{ // apply attributes to font
Seek( nOfst );
lcl_GetCharRectInsideField( aInf, *pOrig, *pCMS, *pPor );
}
}
}
// special case: We are at the beginning of a BidiPortion or // directly behind a BidiPortion if ( pCMS &&
( pLastBidiPor ||
( pPor &&
pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->IsBidi() ) ) )
{ // we determine if the cursor has to blink before or behind // the bidi portion if ( pLastBidiPor )
{ const sal_uInt8 nPortionLevel = pLastBidiPor->GetLevel();
if ( pCMS->m_nCursorBidiLevel >= nPortionLevel )
{ // we came from inside the bidi portion, we want to blink // behind the portion
pOrig->Pos().AdjustX( -nLastBidiPorWidth );
// Again, there is a special case: logically behind // the portion can actually mean that the cursor is inside // the portion. This can happen is the last portion // inside the bidi portion is a nested bidi portion
SwLineLayout& rLineLayout = static_cast<SwMultiPortion*>(pLastBidiPor)->GetRoot();
const SwLinePortion *pLast = rLineLayout.FindLastPortion(); if ( pLast->IsMultiPortion() )
{
OSL_ENSURE( static_cast<const SwMultiPortion*>(pLast)->IsBidi(), "Non-BidiPortion inside BidiPortion" );
TextFrameIndex const nIdx = aInf.GetIdx(); // correct the index before using CalcSpacing.
aInf.SetIdx(nLastBidiIdx);
pOrig->Pos().AdjustX(pLast->Width() +
pLast->CalcSpacing( nSpaceAdd, aInf ) );
aInf.SetIdx(nIdx);
}
}
} else
{ const sal_uInt8 nPortionLevel = static_cast<SwBidiPortion*>(pPor)->GetLevel();
if ( pCMS->m_nCursorBidiLevel >= nPortionLevel )
{ // we came from inside the bidi portion, we want to blink // behind the portion
pOrig->Pos().AdjustX(pPor->Width() +
pPor->CalcSpacing( nSpaceAdd, aInf ) );
}
}
}
// Indicates that a position inside a special portion (field, number portion) // is requested. constbool bSpecialPos = pCMS && pCMS->m_pSpecialPos;
TextFrameIndex nFindOfst = nOfst;
if ( bSpecialPos )
{ const SwSPExtendRange nExtendRange = pCMS->m_pSpecialPos->nExtendRange;
OSL_ENSURE( ! pCMS->m_pSpecialPos->nLineOfst || SwSPExtendRange::BEFORE != nExtendRange, "LineOffset AND Number Portion?" );
// portions which are behind the string if ( SwSPExtendRange::BEHIND == nExtendRange )
++nFindOfst;
// skip lines for fields which cover more than one line for ( sal_Int32 i = 0; i < pCMS->m_pSpecialPos->nLineOfst; i++ )
Next();
}
// If necessary, as catch up, do the adjustment
GetAdjusted();
AddExtraBlankWidth();
/** * Determines if SwTextCursor::GetModelPositionForViewPoint() should consider the next portion when calculating the * doc model position from a Point.
*/ staticbool ConsiderNextPortionForCursorOffset(const SwLinePortion* pPor, SwTwips nWidth30, sal_uInt16 nX)
{ if (!pPor->GetNextPortion() || pPor->IsBreakPortion())
{ returnfalse;
}
// tdf#138592: consider all following zero-width text portions of current text portion, // like combining characters. if (nWidth30 == nX && pPor->IsTextPortion() && pPor->GetNextPortion()->IsTextPortion()
&& pPor->GetNextPortion()->Width() == 0) returntrue;
// If we're past the target position, stop the iteration in general. // Exception: don't stop the iteration between as-char fly portions and their comments. if (nWidth30 >= nX && (!pPor->IsFlyCntPortion() || !pPor->GetNextPortion()->IsPostItsPortion()))
{ // Normally returns false.
// Another exception: If the cursor is at the very end of the portion, and the next portion is a comment, // then place the cursor after the zero-width comment. This is primarily to benefit the very end of a line. return nWidth30 == nX && pPor->GetNextPortion()->IsPostItsPortion();
}
// Return: Offset in String
TextFrameIndex SwTextCursor::GetModelPositionForViewPoint( SwPosition *pPos, const Point &rPoint, bool bChgNode, SwCursorMoveState* pCMS ) const
{ // If necessary, as catch up, do the adjustment
GetAdjusted();
// x is the horizontal offset within the line.
SwTwips x = rPoint.X(); const SwTwips nLeftMargin = GetLineStart();
SwTwips nRightMargin = GetLineEnd() +
( GetCurr()->IsHanging() ? GetCurr()->GetHangingMargin() : 0 ); if( nRightMargin == nLeftMargin )
nRightMargin += 30;
constbool bLeftOver = x < nLeftMargin; if( bLeftOver )
x = nLeftMargin; constbool bRightOver = x > nRightMargin; constbool bRightAllowed = pCMS && ( pCMS->m_eState == CursorMoveState::NONE );
// Until here everything in document coordinates.
x -= nLeftMargin;
SwTwips nX = x;
// If there are attribute changes in the line, search for the paragraph, // in which nX is situated.
SwLinePortion *pPor = m_pCurr->GetFirstPortion();
TextFrameIndex nCurrStart = m_nStart; bool bLastHyph = false;
// nWidth is the width of the line, or the width of // the paragraph with the font change, in which nX is situated. // tdf#16342 In the case of shrunk lines with a single portion, // adjust the line width to move the cursor to the click position
SwTwips nWidth =
( std::abs( m_pCurr->Width() - pPor->Width() ) <= 1 && m_pCurr->ExtraShrunkWidth() > 0 )
? m_pCurr->ExtraShrunkWidth()
: pPor->Width(); if ( m_pCurr->IsSpaceAdd() || pKanaComp )
{ if ( pPor->InSpaceGrp() && nSpaceAdd )
{ const_cast<SwTextSizeInfo&>(GetInfo()).SetIdx( nCurrStart );
nWidth += pPor->CalcSpacing( nSpaceAdd, GetInfo() );
} if( ( pPor->InFixMargGrp() && ! pPor->IsMarginPortion() ) ||
( pPor->IsMultiPortion() && static_cast<SwMultiPortion*>(pPor)->HasTabulator() )
)
{ if ( m_pCurr->IsSpaceAdd() )
{ if ( ++nSpaceIdx < m_pCurr->GetLLSpaceAddCount() )
nSpaceAdd = m_pCurr->GetLLSpaceAdd( nSpaceIdx ); else
nSpaceAdd = 0;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.