summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2008-08-19 08:58:56 +0000
committerVladimir Glazounov <vg@openoffice.org>2008-08-19 08:58:56 +0000
commitacea502ce05285043c2ebc12de6218d7ea59fa7e (patch)
tree77f83f5dfc9dcfb398d82f4bb92e4da5f54d0d9a /vcl
parent6562ed1ea211e5921993a6662ff8feecba4961de (diff)
INTEGRATION: CWS dba31a (1.240.62); FILE MERGED
2008/07/30 12:08:05 fs 1.240.62.3: RESYNC: (1.241-1.242); FILE MERGED 2008/07/16 06:15:45 fs 1.240.62.2: RESYNC: (1.240-1.241); FILE MERGED 2008/06/09 10:20:50 oj 1.240.62.1: #i88506# insert new flag to offer word boundary breaks
Diffstat (limited to 'vcl')
-rw-r--r--vcl/source/gdi/outdev3.cxx115
1 files changed, 113 insertions, 2 deletions
diff --git a/vcl/source/gdi/outdev3.cxx b/vcl/source/gdi/outdev3.cxx
index 6643f0c0f618..355254e3258f 100644
--- a/vcl/source/gdi/outdev3.cxx
+++ b/vcl/source/gdi/outdev3.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: outdev3.cxx,v $
- * $Revision: 1.242 $
+ * $Revision: 1.243 $
*
* This file is part of OpenOffice.org.
*
@@ -78,6 +78,7 @@
#endif
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <com/sun/star/i18n/WordType.hpp>
+#include <com/sun/star/linguistic2/XLinguServiceManager.hpp>
#if defined UNX
#define GLYPH_FONT_HEIGHT 128
@@ -5141,7 +5142,19 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
{
::rtl::OUString aText( rStr );
uno::Reference < i18n::XBreakIterator > xBI;
+ // get service provider
+ uno::Reference< lang::XMultiServiceFactory > xSMgr( unohelper::GetMultiServiceFactory() );
+
uno::Reference< linguistic2::XHyphenator > xHyph;
+ if( xSMgr.is() )
+ {
+ uno::Reference< linguistic2::XLinguServiceManager> xLinguMgr(xSMgr->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.linguistic2.LinguServiceManager"))),uno::UNO_QUERY);
+ if ( xLinguMgr.is() )
+ {
+ xHyph = xLinguMgr->getHyphenator();
+ }
+ }
+
i18n::LineBreakHyphenationOptions aHyphOptions( xHyph, uno::Sequence <beans::PropertyValue>(), 1 );
i18n::LineBreakUserOptions aUserOptions;
@@ -5162,13 +5175,111 @@ long OutputDevice::ImplGetTextLines( ImplMultiTextLineInfo& rLineInfo,
if ( xBI.is() )
{
- static const com::sun::star::lang::Locale aDefLocale;
+ static const com::sun::star::lang::Locale aDefLocale(Application::GetSettings().GetUILocale());
xub_StrLen nSoftBreak = GetTextBreak( rStr, nWidth, nPos, nBreakPos - nPos );
DBG_ASSERT( nSoftBreak < nBreakPos, "Break?!" );
+ //aHyphOptions.hyphenIndex = nSoftBreak;
i18n::LineBreakResults aLBR = xBI->getLineBreak( aText, nSoftBreak, aDefLocale, nPos, aHyphOptions, aUserOptions );
nBreakPos = (xub_StrLen)aLBR.breakIndex;
if ( nBreakPos <= nPos )
nBreakPos = nSoftBreak;
+ if ( nStyle & TEXT_DRAW_WORDBREAK_HYPHENATION )
+ {
+ // Egal ob Trenner oder nicht: Das Wort nach dem Trenner durch
+ // die Silbentrennung jagen...
+ // nMaxBreakPos ist das letzte Zeichen was in die Zeile passt,
+ // nBreakPos ist der Wort-Anfang
+ // Ein Problem gibt es, wenn das Dok so schmal ist, dass ein Wort
+ // auf mehr als Zwei Zeilen gebrochen wird...
+ if ( xHyph.is() )
+ {
+ sal_Unicode cAlternateReplChar = 0;
+ sal_Unicode cAlternateExtraChar = 0;
+ i18n::Boundary aBoundary = xBI->getWordBoundary( aText, nBreakPos, aDefLocale, ::com::sun::star::i18n::WordType::DICTIONARY_WORD, sal_True );
+ // sal_uInt16 nWordStart = nBreakPos;
+ // sal_uInt16 nBreakPos_OLD = nBreakPos;
+ sal_uInt16 nWordStart = nPos;
+ sal_uInt16 nWordEnd = (USHORT) aBoundary.endPos;
+ DBG_ASSERT( nWordEnd > nWordStart, "ImpBreakLine: Start >= End?" );
+
+ USHORT nWordLen = nWordEnd - nWordStart;
+ if ( ( nWordEnd >= nSoftBreak ) && ( nWordLen > 3 ) )
+ {
+ // #104415# May happen, because getLineBreak may differ from getWordBoudary with DICTIONARY_WORD
+ // DBG_ASSERT( nWordEnd >= nMaxBreakPos, "Hyph: Break?" );
+ String aWord( aText, nWordStart, nWordLen );
+ sal_uInt16 nMinTrail = static_cast<sal_uInt16>(nWordEnd-nSoftBreak+1); //+1: Vor dem angeknacksten Buchstaben
+ uno::Reference< linguistic2::XHyphenatedWord > xHyphWord;
+ if (xHyph.is())
+ xHyphWord = xHyph->hyphenate( aWord, aDefLocale, aWord.Len() - nMinTrail, uno::Sequence< beans::PropertyValue >() );
+ if (xHyphWord.is())
+ {
+ sal_Bool bAlternate = xHyphWord->isAlternativeSpelling();
+ sal_uInt16 _nWordLen = 1 + xHyphWord->getHyphenPos();
+
+ if ( ( _nWordLen >= 2 ) && ( (nWordStart+_nWordLen) >= ( 2 ) ) )
+ {
+ if ( !bAlternate )
+ {
+ nBreakPos = nWordStart + _nWordLen;
+ }
+ else
+ {
+ String aAlt( xHyphWord->getHyphenatedWord() );
+
+ // Wir gehen von zwei Faellen aus, die nun
+ // vorliegen koennen:
+ // 1) packen wird zu pak-ken
+ // 2) Schiffahrt wird zu Schiff-fahrt
+ // In Fall 1 muss ein Zeichen ersetzt werden,
+ // in Fall 2 wird ein Zeichen hinzugefuegt.
+ // Die Identifikation wird erschwert durch Worte wie
+ // "Schiffahrtsbrennesseln", da der Hyphenator alle
+ // Position des Wortes auftrennt und "Schifffahrtsbrennnesseln"
+ // ermittelt. Wir koennen also eigentlich nicht unmittelbar vom
+ // Index des AlternativWord auf aWord schliessen.
+
+ // Das ganze geraffel wird durch eine Funktion am
+ // Hyphenator vereinfacht werden, sobald AMA sie einbaut...
+ sal_uInt16 nAltStart = _nWordLen - 1;
+ sal_uInt16 nTxtStart = nAltStart - (aAlt.Len() - aWord.Len());
+ sal_uInt16 nTxtEnd = nTxtStart;
+ sal_uInt16 nAltEnd = nAltStart;
+
+ // Die Bereiche zwischen den nStart und nEnd ist
+ // die Differenz zwischen Alternativ- und OriginalString.
+ while( nTxtEnd < aWord.Len() && nAltEnd < aAlt.Len() &&
+ aWord.GetChar(nTxtEnd) != aAlt.GetChar(nAltEnd) )
+ {
+ ++nTxtEnd;
+ ++nAltEnd;
+ }
+
+ // Wenn ein Zeichen hinzugekommen ist, dann bemerken wir es jetzt:
+ if( nAltEnd > nTxtEnd && nAltStart == nAltEnd &&
+ aWord.GetChar( nTxtEnd ) == aAlt.GetChar(nAltEnd) )
+ {
+ ++nAltEnd;
+ ++nTxtStart;
+ ++nTxtEnd;
+ }
+
+ DBG_ASSERT( ( nAltEnd - nAltStart ) == 1, "Alternate: Falsche Annahme!" );
+
+ if ( nTxtEnd > nTxtStart )
+ cAlternateReplChar = aAlt.GetChar( nAltStart );
+ else
+ cAlternateExtraChar = aAlt.GetChar( nAltStart );
+
+ nBreakPos = nWordStart + nTxtStart;
+ if ( cAlternateReplChar )
+ nBreakPos++;
+ }
+ } // if (xHyphWord.is())
+ } // if ( ( nWordEnd >= nSoftBreak ) && ( nWordLen > 3 ) )
+ } // if ( xHyph.is() )
+ } // if ( nStyle & TEXT_DRAW_WORDBREAK_HYPHENATION )
+ }
nLineWidth = GetTextWidth( rStr, nPos, nBreakPos-nPos );
}
}