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