xref: /trunk/main/sw/source/core/bastyp/breakit.cxx (revision efeef26f)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include "breakit.hxx"
28 #include <unicode/uchar.h>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #ifndef _COM_SUN_STAR_I18N_SCRIPTTYPE_HDL_
31 #include <com/sun/star/i18n/ScriptType.hdl>
32 #endif
33 #include <unotools/localedatawrapper.hxx>
34 
35 #ifndef _SVX_LINGU_HXX
36 #include <editeng/unolingu.hxx>
37 #endif
38 #include <editeng/scripttypeitem.hxx>
39 #include "swtypes.hxx"
40 
41 using namespace com::sun::star;
42 
43 SwBreakIt * pBreakIt = 0;
44 
_Create(const uno::Reference<lang::XMultiServiceFactory> & rxMSF)45 void SwBreakIt::_Create(
46     const uno::Reference< lang::XMultiServiceFactory > & rxMSF)
47 {
48 	delete pBreakIt, pBreakIt = new SwBreakIt( rxMSF );
49 }
50 
_Delete()51 void SwBreakIt::_Delete()
52 {
53 	delete pBreakIt, pBreakIt = 0;
54 }
55 
Get()56 SwBreakIt * SwBreakIt::Get()
57 {
58 	return pBreakIt;
59 }
60 
SwBreakIt(const uno::Reference<lang::XMultiServiceFactory> & rxMSF)61 SwBreakIt::SwBreakIt(
62     const uno::Reference< lang::XMultiServiceFactory > & rxMSF)
63 	: m_xMSF( rxMSF ),
64 	  m_pLocale( NULL ),
65 	  m_pForbidden( NULL ),
66 	  aLast( LANGUAGE_DONTKNOW ),
67 	  aForbiddenLang( LANGUAGE_DONTKNOW)
68 {
69 	DBG_ASSERT( m_xMSF.is(), "SwBreakIt: no MultiServiceFactory" );
70 	//if ( m_xMSF.is() )
71 	//{
72  //       xBreak = uno::Reference< i18n::XBreakIterator >(
73 	//		m_xMSF->createInstance(
74 	//			rtl::OUString::createFromAscii( "com.sun.star.i18n.BreakIterator" ) ),
75  //           uno::UNO_QUERY);
76 
77  //       xCTLDetect = uno::Reference< i18n::XScriptTypeDetector >(
78  //           m_xMSF->createInstance(
79  //                rtl::OUString::createFromAscii( "com.sun.star.i18n.ScriptTypeDetector" ) ),
80  //           uno::UNO_QUERY);
81  //   }
82 }
83 
~SwBreakIt()84 SwBreakIt::~SwBreakIt()
85 {
86 	delete m_pLocale;
87 	delete m_pForbidden;
88 }
createBreakIterator() const89 void SwBreakIt::createBreakIterator() const
90 {
91     if ( m_xMSF.is() && !xBreak.is() )
92         xBreak.set(m_xMSF->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.BreakIterator"))),uno::UNO_QUERY);
93 }
createScriptTypeDetector()94 void SwBreakIt::createScriptTypeDetector()
95 {
96     if ( m_xMSF.is() && !xCTLDetect.is() )
97         xCTLDetect.set(m_xMSF->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.ScriptTypeDetector" ))),uno::UNO_QUERY);
98 }
_GetLocale(const LanguageType aLang)99 void SwBreakIt::_GetLocale( const LanguageType aLang )
100 {
101 	aLast = aLang;
102 	delete m_pLocale;
103     m_pLocale = new lang::Locale( SvxCreateLocale( aLast ) );
104 }
105 
_GetForbidden(const LanguageType aLang)106 void SwBreakIt::_GetForbidden( const LanguageType aLang )
107 {
108 	LocaleDataWrapper aWrap( m_xMSF, GetLocale( aLang ) );
109 
110 	aForbiddenLang = aLang;
111 	delete m_pForbidden;
112     m_pForbidden = new i18n::ForbiddenCharacters( aWrap.getForbiddenCharacters() );
113 }
114 
GetRealScriptOfText(const String & rTxt,xub_StrLen nPos) const115 sal_uInt16 SwBreakIt::GetRealScriptOfText( const String& rTxt,
116 										xub_StrLen nPos ) const
117 {
118     createBreakIterator();
119     sal_uInt16 nScript = i18n::ScriptType::WEAK;
120 	if( xBreak.is() && rTxt.Len() )
121 	{
122 		if( nPos && nPos == rTxt.Len() )
123 			--nPos;
124 		nScript = xBreak->getScriptType( rTxt, nPos );
125 		sal_Int32 nChgPos = 0;
126         if ( i18n::ScriptType::WEAK == nScript && nPos + 1 < rTxt.Len() )
127         {
128             // A weak character followed by a mark may be meant to combine with
129             // the mark, so prefer the following character's script
130             switch ( u_charType(rTxt.GetChar(nPos + 1) ) ) {
131             case U_NON_SPACING_MARK:
132             case U_ENCLOSING_MARK:
133             case U_COMBINING_SPACING_MARK:
134                 nScript = xBreak->getScriptType( rTxt, nPos+1 );
135                 break;
136             }
137         }
138         if( i18n::ScriptType::WEAK == nScript && nPos &&
139 			0 < (nChgPos = xBreak->beginOfScript( rTxt, nPos, nScript )) )
140 			nScript = xBreak->getScriptType( rTxt, nChgPos-1 );
141 
142         if( i18n::ScriptType::WEAK == nScript && rTxt.Len() >
143 			( nChgPos = xBreak->endOfScript( rTxt, nPos, nScript ) ) &&
144 			0 <= nChgPos )
145 			nScript = xBreak->getScriptType( rTxt, nChgPos );
146 	}
147     if( i18n::ScriptType::WEAK == nScript )
148         nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
149 	return nScript;
150 }
151 
GetAllScriptsOfText(const String & rTxt) const152 sal_uInt16 SwBreakIt::GetAllScriptsOfText( const String& rTxt ) const
153 {
154 	const sal_uInt16 coAllScripts = ( SCRIPTTYPE_LATIN |
155 								  SCRIPTTYPE_ASIAN |
156 								  SCRIPTTYPE_COMPLEX );
157     createBreakIterator();
158 	sal_uInt16 nRet = 0, nScript;
159 	if( !xBreak.is() )
160 		nRet = coAllScripts;
161 	else if( rTxt.Len() )
162 	{
163 		for( xub_StrLen n = 0, nEnd = rTxt.Len(); n < nEnd;
164 				n = static_cast<xub_StrLen>(xBreak->endOfScript( rTxt, n, nScript )) )
165 		{
166 			switch( nScript = xBreak->getScriptType( rTxt, n ) )
167 			{
168             case i18n::ScriptType::LATIN:       nRet |= SCRIPTTYPE_LATIN;   break;
169             case i18n::ScriptType::ASIAN:       nRet |= SCRIPTTYPE_ASIAN;   break;
170             case i18n::ScriptType::COMPLEX: nRet |= SCRIPTTYPE_COMPLEX; break;
171             case i18n::ScriptType::WEAK:
172 					if( !nRet )
173 						nRet |= coAllScripts;
174 					break;
175 			}
176 			if( coAllScripts == nRet )
177 				break;
178 		}
179 	}
180 	return nRet;
181 }
182 
183