summaryrefslogtreecommitdiff
path: root/binfilter/bf_sw/source/core/text/sw_guess.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sw/source/core/text/sw_guess.cxx')
-rw-r--r--binfilter/bf_sw/source/core/text/sw_guess.cxx578
1 files changed, 578 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/text/sw_guess.cxx b/binfilter/bf_sw/source/core/text/sw_guess.cxx
new file mode 100644
index 000000000000..d23547d77649
--- /dev/null
+++ b/binfilter/bf_sw/source/core/text/sw_guess.cxx
@@ -0,0 +1,578 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#include <ctype.h>
+
+#include <tools/shl.hxx> // needed for SW_MOD() macro
+
+#include <swmodule.hxx>
+#include <guess.hxx>
+#include <inftxt.hxx> // SwTxtSizeInfo, SwTxtFormatInfo
+
+#include <horiornt.hxx>
+
+#include <doc.hxx>
+#include <pagefrm.hxx>
+#include <pagedesc.hxx> // SwPageDesc
+#include <tgrditem.hxx>
+
+#include <com/sun/star/i18n/BreakType.hpp>
+#include <com/sun/star/i18n/WordType.hpp>
+#include <unotools/charclass.hxx>
+#include <porfld.hxx>
+namespace binfilter {
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::i18n;
+using namespace ::com::sun::star::beans;
+
+using rtl::OUString;
+
+#ifdef VERTICAL_LAYOUT
+#define CH_FULL_BLANK 0x3000
+#endif
+
+/*************************************************************************
+ * SwTxtGuess::Guess
+ *
+ * provides information for line break calculation
+ * returns true if no line break has to be performed
+ * otherwise possible break or hyphenation position is determined
+ *************************************************************************/
+
+/*M*/ sal_Bool SwTxtGuess::Guess( const SwTxtPortion& rPor, SwTxtFormatInfo &rInf,
+/*M*/ const KSHORT nPorHeight )
+/*M*/ {
+/*M*/ nCutPos = rInf.GetIdx();
+/*M*/
+/*M*/ // Leere Strings sind immer 0
+/*M*/ if( !rInf.GetLen() || !rInf.GetTxt().Len() )
+/*M*/ return sal_False;
+/*M*/
+/*M*/ ASSERT( rInf.GetIdx() < rInf.GetTxt().Len(),
+/*M*/ "+SwTxtGuess::Guess: invalid SwTxtFormatInfo" );
+/*M*/
+/*M*/ ASSERT( nPorHeight, "+SwTxtGuess::Guess: no height" );
+/*M*/
+/*M*/ USHORT nMinSize;
+/*M*/ USHORT nMaxSizeDiff;
+/*M*/
+/*M*/ const SwScriptInfo& rSI =
+/*M*/ ((SwParaPortion*)rInf.GetParaPortion())->GetScriptInfo();
+/*M*/
+/*M*/ USHORT nMaxComp = ( SW_CJK == rInf.GetFont()->GetActual() ) &&
+/*M*/ rSI.CountCompChg() &&
+/*M*/ ! rInf.IsMulti() &&
+/*M*/ ! rPor.InFldGrp() &&
+/*M*/ ! rPor.IsDropPortion() ?
+/*M*/ 10000 :
+/*M*/ 0 ;
+/*M*/
+/*M*/ SwTwips nLineWidth = rInf.Width() - rInf.X();
+/*M*/ const xub_StrLen nMaxLen = Min( xub_StrLen(rInf.GetTxt().Len() - rInf.GetIdx()),
+/*M*/ rInf.GetLen() );
+/*M*/ // special case: char width > line width
+/*M*/ if( !nMaxLen || !nLineWidth )
+/*M*/ return sal_False;
+/*M*/
+/*M*/ KSHORT nItalic = 0;
+/*M*/ if( ITALIC_NONE != rInf.GetFont()->GetItalic() && !rInf.NotEOL() )
+/*M*/ {
+/*M*/ sal_Bool bAddItalic = sal_True;
+/*M*/
+/*M*/ // do not add extra italic value if we have an active character grid
+/*M*/ if ( rInf.SnapToGrid() )
+/*M*/ {
+/*M*/ GETGRID( rInf.GetTxtFrm()->FindPageFrm() )
+/*M*/ bAddItalic = ! pGrid || GRID_LINES_CHARS != pGrid->GetGridType();
+/*M*/ }
+/*M*/
+/*M*/ #ifdef MAC
+/*M*/ nItalic = bAddItalic ? nPorHeight / 4 : 0;
+/*M*/ #else
+/*M*/ nItalic = bAddItalic ? nPorHeight / 12 : 0;
+/*M*/ #endif
+/*M*/ if( nItalic >= nLineWidth )
+/*M*/ {
+/*M*/ nBreakWidth = nItalic;
+/*M*/ nCutPos = rInf.GetIdx();
+/*M*/ return sal_False;
+/*M*/ }
+/*M*/ else
+/*M*/ nLineWidth -= nItalic;
+/*M*/ }
+/*M*/
+/*M*/ // first check if everything fits to line
+/*M*/ if ( long ( nLineWidth ) * 2 > long ( nMaxLen ) * nPorHeight )
+/*M*/ {
+/*M*/ // call GetTxtSize with maximum compression (for kanas)
+/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nMaxLen,
+/*M*/ nMaxComp, nMinSize, nMaxSizeDiff );
+/*M*/
+/*M*/ nBreakWidth = nMinSize;
+/*M*/
+/*M*/ if ( nBreakWidth <= nLineWidth )
+/*M*/ {
+/*M*/ // portion fits to line
+/*M*/ nCutPos = rInf.GetIdx() + nMaxLen - 1;
+/*M*/ if( nItalic && ( nCutPos + 1 ) >= rInf.GetTxt().Len() )
+/*M*/ nBreakWidth += nItalic;
+/*M*/
+/*M*/ // save maximum width for later use
+/*M*/ if ( nMaxSizeDiff )
+/*M*/ rInf.SetMaxWidthDiff( (ULONG)&rPor, nMaxSizeDiff );
+/*M*/
+/*M*/ return sal_True;
+/*M*/ }
+/*M*/ }
+/*M*/
+/*M*/ sal_Bool bHyph = rInf.IsHyphenate() && !rInf.IsHyphForbud();
+/*M*/ xub_StrLen nHyphPos = 0;
+/*M*/
+/*M*/ // nCutPos is the first character not fitting to the current line
+/*M*/ // nHyphPos is the first character not fitting to the current line,
+/*M*/ // considering an additional "-" for hyphenation
+/*M*/ if( bHyph )
+/*M*/ {
+/*M*/ nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp, nHyphPos );
+/*M*/
+/*M*/ if ( !nHyphPos && rInf.GetIdx() )
+/*M*/ nHyphPos = rInf.GetIdx() - 1;
+/*M*/ }
+/*M*/ else
+/*M*/ {
+/*M*/ nCutPos = rInf.GetTxtBreak( nLineWidth, nMaxLen, nMaxComp );
+/*M*/
+/*M*/ #ifdef DBG_UTIL
+/*M*/ if ( STRING_LEN != nCutPos )
+/*M*/ {
+/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nCutPos - rInf.GetIdx(),
+/*M*/ nMaxComp, nMinSize, nMaxSizeDiff );
+/*M*/ ASSERT( nMinSize <= nLineWidth, "What a Guess!!!" );
+/*M*/ }
+/*M*/ #endif
+/*M*/ }
+/*M*/
+/*M*/ if( nCutPos > rInf.GetIdx() + nMaxLen )
+/*M*/ {
+/*M*/ // second check if everything fits to line
+/*M*/ nCutPos = nBreakPos = rInf.GetIdx() + nMaxLen - 1;
+/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nMaxLen, nMaxComp,
+/*M*/ nMinSize, nMaxSizeDiff );
+/*M*/
+/*M*/ nBreakWidth = nMinSize;
+/*M*/
+/*M*/ // Der folgende Vergleich sollte eigenlich immer sal_True ergeben, sonst
+/*M*/ // hat es wohl bei GetTxtBreak einen Pixel-Rundungsfehler gegeben...
+/*M*/ if ( nBreakWidth <= nLineWidth )
+/*M*/ {
+/*M*/ if( nItalic && ( nBreakPos + 1 ) >= rInf.GetTxt().Len() )
+/*M*/ nBreakWidth += nItalic;
+/*M*/
+/*M*/ // save maximum width for later use
+/*M*/ if ( nMaxSizeDiff )
+/*M*/ rInf.SetMaxWidthDiff( (ULONG)&rPor, nMaxSizeDiff );
+/*M*/
+/*M*/ return sal_True;
+/*M*/ }
+/*M*/ }
+/*M*/
+/*M*/ // we have to trigger an underflow for a footnote portion
+/*M*/ // which does not fit to the current line
+/*M*/ if ( rPor.IsFtnPortion() )
+/*M*/ {
+/*M*/ nBreakPos = rInf.GetIdx();
+/*M*/ nCutPos = rInf.GetLen();
+/*M*/ return sal_False;
+/*M*/ }
+/*M*/
+/*M*/ xub_StrLen nPorLen = 0;
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ // do not call the break iterator nCutPos is a blank
+/*M*/ xub_Unicode cCutChar = rInf.GetTxt().GetChar( nCutPos );
+/*M*/ if( CH_BLANK == cCutChar || CH_FULL_BLANK == cCutChar )
+/*M*/ #else
+/*M*/ if( CH_BLANK == rInf.GetTxt().GetChar( nCutPos ) )
+/*M*/ #endif
+/*M*/ {
+/*M*/ nBreakPos = nCutPos;
+/*M*/ xub_StrLen nX = nBreakPos;
+/*M*/
+/*M*/ // we step back until a non blank character has been found
+/*M*/ // or there is only one more character left
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ while( nX && nBreakPos > rInf.GetLineStart() + 1 &&
+/*M*/ ( CH_BLANK == ( cCutChar = rInf.GetChar( --nX ) ) ||
+/*M*/ CH_FULL_BLANK == cCutChar ) )
+/*M*/ --nBreakPos;
+/*M*/ #else
+/*M*/ while( nX && nBreakPos > rInf.GetLineStart() + 1 &&
+/*M*/ CH_BLANK == rInf.GetChar( --nX ) )
+/*M*/ --nBreakPos;
+/*M*/ #endif
+/*M*/
+/*M*/ if( nBreakPos > rInf.GetIdx() )
+/*M*/ nPorLen = nBreakPos - rInf.GetIdx();
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ while( ++nCutPos < rInf.GetTxt().Len() &&
+/*M*/ ( CH_BLANK == ( cCutChar = rInf.GetChar( nCutPos ) ) ||
+/*M*/ CH_FULL_BLANK == cCutChar ) )
+/*M*/ ; // nothing
+/*M*/ #else
+/*M*/ while( ++nCutPos < rInf.GetTxt().Len() &&
+/*M*/ CH_BLANK == rInf.GetChar( nCutPos ) )
+/*M*/ ; // nothing
+/*M*/ #endif
+/*M*/
+/*M*/ nBreakStart = nCutPos;
+/*M*/ }
+/*M*/ else if( pBreakIt->xBreak.is() )
+/*M*/ {
+/*M*/ // New: We should have a look into the last portion, if it was a
+/*M*/ // field portion. For this, we expand the text of the field portion
+/*M*/ // into our string. If the line break position is inside of before
+/*M*/ // the field portion, we trigger an underflow.
+/*M*/
+/*M*/ xub_StrLen nOldIdx = rInf.GetIdx();
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ xub_Unicode cFldChr = 0;
+/*M*/ #else
+/*M*/ sal_Char cFldChr = 0;
+/*M*/ #endif
+/*M*/
+/*N*/ #if OSL_DEBUG_LEVEL > 1
+/*M*/ XubString aDebugString;
+/*M*/ #endif
+/*M*/
+/*M*/ // be careful: a field portion can be both: 0x01 (common field)
+/*M*/ // or 0x02 (the follow of a footnode)
+/*M*/ if ( rInf.GetLast() && rInf.GetLast()->InFldGrp() &&
+/*M*/ ! rInf.GetLast()->IsFtnPortion() &&
+/*M*/ rInf.GetIdx() > rInf.GetLineStart() &&
+/*M*/ CH_TXTATR_BREAKWORD ==
+/*M*/ ( cFldChr = rInf.GetTxt().GetChar( rInf.GetIdx() - 1 ) ) )
+/*M*/ {
+/*M*/ SwFldPortion* pFld = (SwFldPortion*)rInf.GetLast();
+/*M*/ XubString aTxt;
+/*M*/ pFld->GetExpTxt( rInf, aTxt );
+/*M*/
+/*M*/ if ( aTxt.Len() )
+/*M*/ {
+/*M*/ nFieldDiff = aTxt.Len() - 1;
+/*M*/ nCutPos += nFieldDiff;
+/*M*/ nHyphPos += nFieldDiff;
+/*M*/
+/*N*/ #if OSL_DEBUG_LEVEL > 1
+/*M*/ aDebugString = rInf.GetTxt();
+/*M*/ #endif
+/*M*/
+/*M*/ XubString& rOldTxt = (XubString&)rInf.GetTxt();
+/*M*/ rOldTxt.Erase( rInf.GetIdx() - 1, 1 );
+/*M*/ rOldTxt.Insert( aTxt, rInf.GetIdx() - 1 );
+/*M*/ rInf.SetIdx( rInf.GetIdx() + nFieldDiff );
+/*M*/ }
+/*M*/ else
+/*M*/ cFldChr = 0;
+/*M*/ }
+/*M*/
+/*M*/ LineBreakHyphenationOptions aHyphOpt;
+/*M*/ Reference< XHyphenator > xHyph;
+/*M*/ if( bHyph )
+/*M*/ {
+/*M*/ xHyph = ::binfilter::GetHyphenator();
+/*M*/ aHyphOpt = LineBreakHyphenationOptions( xHyph,
+/*M*/ rInf.GetHyphValues(), nHyphPos );
+/*M*/ }
+/*M*/
+/*N*/ // Get Language for break iterator.
+/*N*/ // We have to switch the current language if we have a script
+/*N*/ // change at nCutPos. Otherwise LATIN punctuation would never
+/*N*/ // be allowed to be hanging punctuation.
+/*N*/ // NEVER call GetLang if the string has been modified!!!
+/*N*/ LanguageType aLang = rInf.GetFont()->GetLanguage();
+/*N*/
+/*N*/ // If we are inside a field portion, we use a temporar string which
+/*N*/ // differs from the string at the textnode. Therefore we are not allowed
+/*N*/ // to call the GetLang function.
+/*N*/ if ( nCutPos && ! rPor.InFldGrp() )
+/*N*/ {
+/*N*/ const CharClass& rCC = GetAppCharClass();
+/*N*/
+/*N*/ // step back until a non-punctuation character is reached
+/*N*/ xub_StrLen nLangIndex = nCutPos;
+/*N*/
+/*N*/ // If a field has been expanded right in front of us we do not
+/*N*/ // step further than the beginning of the expanded field
+/*N*/ // (which is the position of the field placeholder in our
+/*N*/ // original string).
+/*N*/ const xub_StrLen nDoNotStepOver = CH_TXTATR_BREAKWORD == cFldChr ?
+/*N*/ rInf.GetIdx() - nFieldDiff - 1:
+/*N*/ 0;
+/*N*/
+/*N*/ while ( nLangIndex > nDoNotStepOver &&
+/*N*/ ! rCC.isLetterNumeric( rInf.GetTxt(), nLangIndex ) )
+/*N*/ --nLangIndex;
+/*N*/
+/*N*/ // last "real" character is not inside our current portion
+/*N*/ // we have to check the script type of the last "real" character
+/*N*/ if ( nLangIndex < rInf.GetIdx() )
+/*N*/ {
+/*N*/ USHORT nScript = pBreakIt->GetRealScriptOfText( rInf.GetTxt(),
+/*N*/ nLangIndex );
+/*N*/ ASSERT( nScript, "Script is not between 1 and 4" );
+/*N*/
+/*N*/ // compare current script with script from last "real" character
+/*N*/ if ( nScript - 1 != rInf.GetFont()->GetActual() )
+/*N*/ aLang = rInf.GetTxtFrm()->GetTxtNode()->GetLang(
+/*N*/ CH_TXTATR_BREAKWORD == cFldChr ?
+/*N*/ nDoNotStepOver :
+/*N*/ nLangIndex, 0, nScript );
+/*N*/ }
+/*N*/ }
+/*N*/
+/*M*/ const ForbiddenCharacters aForbidden(
+/*M*/ *rInf.GetTxtFrm()->GetNode()->GetDoc()->
+/*M*/ GetForbiddenCharacters( aLang, TRUE ));
+/*M*/
+/*M*/ const sal_Bool bAllowHanging = rInf.IsHanging() && ! rInf.IsMulti() &&
+/*M*/ ! rPor.InFldGrp();
+/*M*/
+/*M*/ LineBreakUserOptions aUserOpt(
+/*M*/ aForbidden.beginLine, aForbidden.endLine,
+/*M*/ rInf.HasForbiddenChars(), bAllowHanging, sal_False );
+/*M*/
+/*M*/ // !!! We must have a local copy of the locale, because inside
+/*M*/ // getLineBreak the LinguEventListener can trigger a new formatting,
+/*M*/ // which can corrupt the locale pointer inside pBreakIt.
+/*M*/ const ::com::sun::star::lang::Locale aLocale = pBreakIt->GetLocale( aLang );
+/*M*/
+/*M*/ // determines first possible line break from nRightPos to
+/*M*/ // start index of current line
+/*M*/ LineBreakResults aResult = pBreakIt->xBreak->getLineBreak(
+/*M*/ rInf.GetTxt(), nCutPos, aLocale,
+/*M*/ rInf.GetLineStart(), aHyphOpt, aUserOpt );
+/*M*/
+/*M*/ nBreakPos = (xub_StrLen)aResult.breakIndex;
+/*M*/
+/*M*/ // if we are formatting multi portions we want to allow line breaks
+/*M*/ // at the border between single line and multi line portion
+/*M*/ // we have to be carefull with footnote portions, they always come in
+/*M*/ // with an index 0
+/*M*/ if ( nBreakPos < rInf.GetLineStart() && rInf.IsFirstMulti() &&
+/*M*/ ! rInf.IsFtnInside() )
+/*M*/ nBreakPos = rInf.GetLineStart();
+/*M*/
+/*M*/ nBreakStart = nBreakPos;
+/*M*/
+/*M*/ bHyph = BreakType::HYPHENATION == aResult.breakType;
+/*M*/
+/*M*/ if ( bHyph && nBreakPos != STRING_LEN)
+/*M*/ {
+/*M*/ // found hyphenation position within line
+/*M*/ // nBreakPos is set to the hyphenation position
+/*M*/ xHyphWord = aResult.rHyphenatedWord;
+/*M*/ nBreakPos += xHyphWord->getHyphenationPos() + 1;
+/*M*/
+/*N*/ #if OSL_DEBUG_LEVEL > 1
+/*M*/ // e.g., Schif-fahrt, referes to our string
+/*M*/ const String aWord = xHyphWord->getWord();
+/*M*/ // e.g., Schiff-fahrt, referes to the word after hyphenation
+/*M*/ const String aHyphenatedWord = xHyphWord->getHyphenatedWord();
+/*M*/ // e.g., Schif-fahrt: 5, referes to our string
+/*M*/ const USHORT nHyphenationPos = xHyphWord->getHyphenationPos();
+/*M*/ // e.g., Schiff-fahrt: 6, referes to the word after hyphenation
+/*M*/ const USHORT nHyphenPos = xHyphWord->getHyphenPos();
+/*M*/ #endif
+/*M*/
+/*M*/ // if not in interactive mode, we have to break behind a soft hyphen
+/*M*/ if ( ! rInf.IsInterHyph() && rInf.GetIdx() )
+/*M*/ {
+/*M*/ const long nSoftHyphPos =
+/*M*/ xHyphWord->getWord().indexOf( CHAR_SOFTHYPHEN );
+/*M*/
+/*M*/ if ( nSoftHyphPos >= 0 &&
+/*M*/ nBreakStart + nSoftHyphPos <= nBreakPos &&
+/*M*/ nBreakPos > rInf.GetLineStart() )
+/*M*/ nBreakPos = rInf.GetIdx() - 1;
+/*M*/ }
+/*M*/
+/*M*/ if( nBreakPos >= rInf.GetIdx() )
+/*M*/ {
+/*M*/ nPorLen = nBreakPos - rInf.GetIdx();
+/*M*/ if( '-' == rInf.GetTxt().GetChar( nBreakPos - 1 ) )
+/*M*/ xHyphWord = NULL;
+/*M*/ }
+/*M*/ }
+/*M*/ else if ( !bHyph && nBreakPos >= rInf.GetLineStart() )
+/*M*/ {
+/*M*/ ASSERT( nBreakPos != STRING_LEN, "we should have found a break pos" );
+/*M*/
+/*M*/ // found break position within line
+/*M*/ xHyphWord = NULL;
+/*M*/
+/*M*/ // check, if break position is soft hyphen and an underflow
+/*M*/ // has to be triggered
+/*M*/ if( nBreakPos > rInf.GetLineStart() && rInf.GetIdx() &&
+/*M*/ CHAR_SOFTHYPHEN == rInf.GetTxt().GetChar( nBreakPos - 1 ) )
+/*M*/ nBreakPos = rInf.GetIdx() - 1;
+/*M*/
+/*M*/ // Delete any blanks at the end of a line, but be careful:
+/*M*/ // If a field has been expanded, we do not want to delete any
+/*M*/ // blanks inside the field portion. This would cause an unwanted
+/*M*/ // underflow
+/*M*/ xub_StrLen nX = nBreakPos;
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ while( nX > rInf.GetLineStart() &&
+/*M*/ ( CH_TXTATR_BREAKWORD != cFldChr || nX > rInf.GetIdx() ) &&
+/*M*/ ( CH_BLANK == rInf.GetChar( --nX ) ||
+/*M*/ CH_FULL_BLANK == rInf.GetChar( nX ) ) )
+/*M*/ nBreakPos = nX;
+/*M*/ #else
+/*M*/ while( nX > rInf.GetLineStart() &&
+/*M*/ ( CH_TXTATR_BREAKWORD != cFldChr || nX > rInf.GetIdx() ) &&
+/*M*/ CH_BLANK == rInf.GetChar(--nX) )
+/*M*/ nBreakPos = nX;
+/*M*/ #endif
+/*M*/ if( nBreakPos > rInf.GetIdx() )
+/*M*/ nPorLen = nBreakPos - rInf.GetIdx();
+/*M*/ }
+/*M*/ else
+/*M*/ {
+/*M*/ // no line break found, setting nBreakPos to STRING_LEN
+/*M*/ // causes a break cut
+/*M*/ nBreakPos = STRING_LEN;
+/*M*/ ASSERT( nCutPos >= rInf.GetIdx(), "Deep cut" );
+/*M*/ nPorLen = nCutPos - rInf.GetIdx();
+/*M*/ }
+/*M*/
+/*M*/ if( nBreakPos > nCutPos && nBreakPos != STRING_LEN )
+/*M*/ {
+/*M*/ const xub_StrLen nHangingLen = nBreakPos - nCutPos;
+/*M*/ SwPosSize aTmpSize = rInf.GetTxtSize( &rSI, nCutPos,
+/*M*/ nHangingLen, 0 );
+/*M*/ ASSERT( !pHanging, "A hanging portion is hanging around" );
+/*M*/ pHanging = new SwHangingPortion( aTmpSize );
+/*M*/ pHanging->SetLen( nHangingLen );
+/*M*/ nPorLen = nCutPos - rInf.GetIdx();
+/*M*/ }
+/*M*/
+/*M*/ // If we expanded a field, we must repair the original string.
+/*M*/ // In case we do not trigger an underflow, we correct the nBreakPos
+/*M*/ // value, but we cannot correct the nBreakStart value:
+/*M*/ // If we have found a hyphenation position, nBreakStart can lie before
+/*M*/ // the field.
+/*M*/ if ( CH_TXTATR_BREAKWORD == cFldChr )
+/*M*/ {
+/*M*/ if ( nBreakPos < rInf.GetIdx() )
+/*M*/ nBreakPos = nOldIdx - 1;
+/*M*/ else if ( STRING_LEN != nBreakPos )
+/*M*/ {
+/*M*/ ASSERT( nBreakPos >= nFieldDiff, "I've got field trouble!" );
+/*M*/ nBreakPos -= nFieldDiff;
+/*M*/ }
+/*M*/
+/*M*/ ASSERT( nCutPos >= rInf.GetIdx() && nCutPos >= nFieldDiff,
+/*M*/ "I've got field trouble, part2!" );
+/*M*/ nCutPos -= nFieldDiff;
+/*M*/
+/*M*/ XubString& rOldTxt = (XubString&)rInf.GetTxt();
+/*M*/ rOldTxt.Erase( nOldIdx - 1, nFieldDiff + 1 );
+/*M*/ rOldTxt.Insert( cFldChr, nOldIdx - 1 );
+/*M*/ rInf.SetIdx( nOldIdx );
+/*M*/
+/*N*/ #if OSL_DEBUG_LEVEL > 1
+/*M*/ ASSERT( aDebugString == rInf.GetTxt(),
+/*M*/ "Somebody, somebody, somebody put something in my string" );
+/*M*/ #endif
+/*M*/ }
+/*M*/ }
+/*M*/
+/*M*/ if( nPorLen )
+/*M*/ {
+/*M*/ rInf.GetTxtSize( &rSI, rInf.GetIdx(), nPorLen,
+/*M*/ nMaxComp, nMinSize, nMaxSizeDiff );
+/*M*/
+/*M*/ // save maximum width for later use
+/*M*/ if ( nMaxSizeDiff )
+/*M*/ rInf.SetMaxWidthDiff( (ULONG)&rPor, nMaxSizeDiff );
+/*M*/
+/*M*/ nBreakWidth = nItalic + nMinSize;
+/*M*/ }
+/*M*/ else
+/*M*/ nBreakWidth = 0;
+/*M*/
+/*M*/ if( pHanging )
+/*M*/ nBreakPos = nCutPos;
+/*M*/
+/*M*/ return sal_False;
+/*M*/ }
+
+/*************************************************************************
+ * SwTxtGuess::AlternativeSpelling
+ *************************************************************************/
+
+// returns true if word at position nPos has a diffenrent spelling
+// if hyphenated at this position (old german spelling)
+
+/*N*/ sal_Bool SwTxtGuess::AlternativeSpelling( const SwTxtFormatInfo &rInf,
+/*N*/ const xub_StrLen nPos )
+/*N*/ {
+/*N*/ // get word boundaries
+/*N*/ xub_StrLen nWordLen;
+/*N*/
+/*N*/ Boundary aBound =
+/*N*/ pBreakIt->xBreak->getWordBoundary( rInf.GetTxt(), nPos,
+/*N*/ pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ),
+/*N*/ WordType::DICTIONARY_WORD, sal_True );
+/*N*/ nBreakStart = (xub_StrLen)aBound.startPos;
+/*N*/ nWordLen = aBound.endPos - nBreakStart;
+/*N*/
+/*N*/ // if everything else fails, we want to cut at nPos
+/*N*/ nCutPos = nPos;
+/*N*/
+/*N*/ XubString aTxt( rInf.GetTxt().Copy( nBreakStart, nWordLen ) );
+/*N*/
+/*N*/ // check, if word has alternative spelling
+/*N*/ Reference< XHyphenator > xHyph( ::binfilter::GetHyphenator() );
+/*N*/ ASSERT( xHyph.is(), "Hyphenator is missing");
+/*N*/ //! subtract 1 since the UNO-interface is 0 based
+/*N*/ xHyphWord = xHyph->queryAlternativeSpelling( OUString(aTxt),
+/*N*/ pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ),
+/*N*/ nPos - nBreakStart, rInf.GetHyphValues() );
+/*N*/ return xHyphWord.is() && xHyphWord->isAlternativeSpelling();
+/*N*/ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */