Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "breakit.hxx"
30 : : #include "swtypes.hxx"
31 : :
32 : : #include <com/sun/star/i18n/ScriptType.hpp>
33 : : #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
34 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 : : #include <editeng/unolingu.hxx>
36 : : #include <editeng/scripttypeitem.hxx>
37 : : #include <unicode/uchar.h>
38 : : #include <unotools/localedatawrapper.hxx>
39 : :
40 : : using namespace com::sun::star;
41 : :
42 : : SwBreakIt* pBreakIt = 0;
43 : :
44 : 73 : void SwBreakIt::_Create( const uno::Reference<lang::XMultiServiceFactory> & rxMSF )
45 : : {
46 [ - + ][ + - ]: 73 : delete pBreakIt, pBreakIt = new SwBreakIt( rxMSF );
47 : 73 : }
48 : :
49 : 73 : void SwBreakIt::_Delete()
50 : : {
51 [ + - ]: 73 : delete pBreakIt, pBreakIt = 0;
52 : 73 : }
53 : :
54 : 4707 : SwBreakIt * SwBreakIt::Get()
55 : : {
56 : 4707 : return pBreakIt;
57 : : }
58 : :
59 : 73 : SwBreakIt::SwBreakIt( const uno::Reference<lang::XMultiServiceFactory> & rxMSF )
60 : : : m_xMSF( rxMSF ),
61 : : m_pLocale( NULL ),
62 : : m_pForbidden( NULL ),
63 : : aLast( LANGUAGE_DONTKNOW ),
64 : 73 : aForbiddenLang( LANGUAGE_DONTKNOW )
65 : : {
66 : : OSL_ENSURE( m_xMSF.is(), "SwBreakIt: no MultiServiceFactory" );
67 : 73 : }
68 : :
69 : 73 : SwBreakIt::~SwBreakIt()
70 : : {
71 [ + + ]: 73 : delete m_pLocale;
72 [ + + ]: 73 : delete m_pForbidden;
73 : 73 : }
74 : :
75 : 1172162 : void SwBreakIt::createBreakIterator() const
76 : : {
77 [ + - ][ + + ]: 1172162 : if ( m_xMSF.is() && !xBreak.is() )
[ + + ]
78 : 69 : xBreak.set(m_xMSF->createInstance(::rtl::OUString(
79 : 69 : RTL_CONSTASCII_USTRINGPARAM("com.sun.star.i18n.BreakIterator"))),
80 [ + - ][ + - ]: 69 : uno::UNO_QUERY);
81 : 1172162 : }
82 : :
83 : 795 : void SwBreakIt::_GetLocale( const LanguageType aLang )
84 : : {
85 : 795 : aLast = aLang;
86 [ + + ]: 795 : delete m_pLocale;
87 [ + - ]: 795 : m_pLocale = new lang::Locale( SvxCreateLocale( aLast ) );
88 : 795 : }
89 : :
90 : 37 : void SwBreakIt::_GetForbidden( const LanguageType aLang )
91 : : {
92 [ + - ][ + - ]: 37 : LocaleDataWrapper aWrap( m_xMSF, GetLocale( aLang ) );
93 : :
94 : 37 : aForbiddenLang = aLang;
95 [ + + ]: 37 : delete m_pForbidden;
96 [ + - ][ + - ]: 37 : m_pForbidden = new i18n::ForbiddenCharacters( aWrap.getForbiddenCharacters() );
[ + - ]
97 : 37 : }
98 : :
99 : 184504 : sal_uInt16 SwBreakIt::GetRealScriptOfText( const rtl::OUString& rTxt, sal_Int32 nPos ) const
100 : : {
101 : 184504 : createBreakIterator();
102 : 184504 : sal_uInt16 nScript = i18n::ScriptType::WEAK;
103 [ + + ][ + + ]: 184504 : if( xBreak.is() && !rTxt.isEmpty() )
[ + - ]
104 : : {
105 [ + + ][ + + ]: 180856 : if( nPos && nPos == rTxt.getLength() )
[ + + ]
106 : 5391 : --nPos;
107 : 180856 : nScript = xBreak->getScriptType( rTxt, nPos );
108 : 180856 : sal_Int32 nChgPos = 0;
109 [ + + ][ + + ]: 180856 : if ( i18n::ScriptType::WEAK == nScript && nPos + 1 < rTxt.getLength() )
[ + + ]
110 : : {
111 : : // A weak character followed by a mark may be meant to combine with
112 : : // the mark, so prefer the following character's script
113 [ - + ]: 14884 : switch (u_charType(rTxt[nPos + 1]))
114 : : {
115 : : case U_NON_SPACING_MARK:
116 : : case U_ENCLOSING_MARK:
117 : : case U_COMBINING_SPACING_MARK:
118 : 0 : nScript = xBreak->getScriptType( rTxt, nPos+1 );
119 : 14884 : break;
120 : : }
121 : : }
122 [ + + ]: 194264 : if( i18n::ScriptType::WEAK == nScript &&
[ + + + + ]
[ + + ]
123 : : nPos &&
124 : 13408 : 0 < ( nChgPos = xBreak->beginOfScript( rTxt, nPos, nScript ) ) )
125 : : {
126 : 12031 : nScript = xBreak->getScriptType( rTxt, nChgPos-1 );
127 : : }
128 : :
129 [ + + + + ]: 188222 : if( i18n::ScriptType::WEAK == nScript &&
[ + - ][ + + ]
130 : 7366 : rTxt.getLength() > ( nChgPos = xBreak->endOfScript( rTxt, nPos, nScript ) ) &&
131 : : 0 <= nChgPos )
132 : : {
133 : 1972 : nScript = xBreak->getScriptType( rTxt, nChgPos );
134 : : }
135 : : }
136 [ + + ]: 184504 : if( i18n::ScriptType::WEAK == nScript )
137 : 9042 : nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() );
138 : 184504 : return nScript;
139 : : }
140 : :
141 : 192 : sal_uInt16 SwBreakIt::GetAllScriptsOfText( const rtl::OUString& rTxt ) const
142 : : {
143 : : const sal_uInt16 coAllScripts = ( SCRIPTTYPE_LATIN |
144 : : SCRIPTTYPE_ASIAN |
145 : 192 : SCRIPTTYPE_COMPLEX );
146 : 192 : createBreakIterator();
147 : 192 : sal_uInt16 nRet = 0, nScript;
148 [ - + ]: 192 : if( !xBreak.is() )
149 : : {
150 : 0 : nRet = coAllScripts;
151 : : }
152 [ + + ]: 192 : else if( !rTxt.isEmpty() )
153 : : {
154 [ + + ]: 330 : for( sal_Int32 n = 0, nEnd = rTxt.getLength(); n < nEnd;
155 : 162 : n = xBreak->endOfScript(rTxt, n, nScript) )
156 : : {
157 [ + - - + : 165 : switch( nScript = xBreak->getScriptType( rTxt, n ) )
- ]
158 : : {
159 : 162 : case i18n::ScriptType::LATIN: nRet |= SCRIPTTYPE_LATIN; break;
160 : 0 : case i18n::ScriptType::ASIAN: nRet |= SCRIPTTYPE_ASIAN; break;
161 : 0 : case i18n::ScriptType::COMPLEX: nRet |= SCRIPTTYPE_COMPLEX; break;
162 : : case i18n::ScriptType::WEAK:
163 [ + - ]: 3 : if( !nRet )
164 : 3 : nRet |= coAllScripts;
165 : 3 : break;
166 : : }
167 [ + + ]: 165 : if( coAllScripts == nRet )
168 : 3 : break;
169 : : }
170 : : }
171 : 192 : return nRet;
172 : : }
173 : :
174 : 70852 : sal_Int32 SwBreakIt::getGraphemeCount(const rtl::OUString& rText,
175 : : sal_Int32 nStart, sal_Int32 nEnd) const
176 : : {
177 : 70852 : sal_Int32 nGraphemeCount = 0;
178 : :
179 : 70852 : sal_Int32 nCurPos = nStart;
180 [ + + ]: 3654961 : while (nCurPos < nEnd)
181 : : {
182 : : // fdo#49208 cheat and assume that nothing can combine with a space
183 : : // to form a single grapheme
184 [ + + ]: 3584109 : if (rText[nCurPos] == ' ')
185 : : {
186 : 67953 : ++nCurPos;
187 : : }
188 : : else
189 : : {
190 : 3516156 : sal_Int32 nCount2 = 1;
191 [ + - ]: 3516156 : nCurPos = xBreak->nextCharacters(rText, nCurPos, lang::Locale(),
192 [ + - ]: 3516156 : i18n::CharacterIteratorMode::SKIPCELL, nCount2, nCount2);
193 : : }
194 : 3584109 : ++nGraphemeCount;
195 : : }
196 : :
197 : 70852 : return nGraphemeCount;
198 : : }
199 : :
200 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|