xref: /AOO41X/main/sw/source/core/bastyp/breakit.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90)
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