xref: /trunk/main/i18npool/source/breakiterator/breakiterator_ctl.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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_i18npool.hxx"
26 
27 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
28 #include <breakiterator_ctl.hxx>
29 
30 #include <string.h> // for memset
31 
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::lang;
34 using namespace ::rtl;
35 
36 namespace com { namespace sun { namespace star { namespace i18n {
37 
38 /**
39  * Constructor.
40  */
BreakIterator_CTL()41 BreakIterator_CTL::BreakIterator_CTL() :
42     cachedText(),
43     nextCellIndex( NULL ),
44     previousCellIndex( NULL ),
45     cellIndexSize( 512 )
46 {
47     cBreakIterator = "com.sun.star.i18n.BreakIterator_CTL";
48     // to improve performance, alloc big enough memory in construct.
49     nextCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32));
50     previousCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32));
51     memset(nextCellIndex, 0, cellIndexSize * sizeof(sal_Int32));
52 }
53 
54 /**
55  * Deconstructor.
56  */
~BreakIterator_CTL()57 BreakIterator_CTL::~BreakIterator_CTL()
58 {
59     free(nextCellIndex);
60     free(previousCellIndex);
61 }
62 
previousCharacters(const OUString & Text,sal_Int32 nStartPos,const lang::Locale & rLocale,sal_Int16 nCharacterIteratorMode,sal_Int32 nCount,sal_Int32 & nDone)63 sal_Int32 SAL_CALL BreakIterator_CTL::previousCharacters( const OUString& Text,
64     sal_Int32 nStartPos, const lang::Locale& rLocale,
65     sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone )
66 {
67     if (nCharacterIteratorMode == CharacterIteratorMode::SKIPCELL ) {
68         nDone = 0;
69         if (nStartPos > 0) {    // for others to skip cell.
70         makeIndex(Text, nStartPos);
71 
72         if (nextCellIndex[nStartPos-1] == 0) // not a CTL character
73             return BreakIterator_Unicode::previousCharacters(Text, nStartPos, rLocale,
74                 nCharacterIteratorMode, nCount, nDone);
75         else while (nCount > 0 && nextCellIndex[nStartPos - 1] > 0) {
76             nCount--; nDone++;
77             nStartPos = previousCellIndex[nStartPos - 1];
78         }
79         } else
80         nStartPos = 0;
81     } else { // for BS to delete one char.
82         nDone = (nStartPos > nCount) ? nCount : nStartPos;
83         nStartPos -= nDone;
84     }
85 
86     return nStartPos;
87 }
88 
nextCharacters(const OUString & Text,sal_Int32 nStartPos,const lang::Locale & rLocale,sal_Int16 nCharacterIteratorMode,sal_Int32 nCount,sal_Int32 & nDone)89 sal_Int32 SAL_CALL BreakIterator_CTL::nextCharacters(const OUString& Text,
90     sal_Int32 nStartPos, const lang::Locale& rLocale,
91     sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone)
92 {
93     sal_Int32 len = Text.getLength();
94     if (nCharacterIteratorMode == CharacterIteratorMode::SKIPCELL ) {
95         nDone = 0;
96         if (nStartPos < len) {
97         makeIndex(Text, nStartPos);
98 
99         if (nextCellIndex[nStartPos] == 0) // not a CTL character
100             return BreakIterator_Unicode::nextCharacters(Text, nStartPos, rLocale,
101                 nCharacterIteratorMode, nCount, nDone);
102         else while (nCount > 0 && nextCellIndex[nStartPos] > 0) {
103             nCount--; nDone++;
104             nStartPos = nextCellIndex[nStartPos];
105         }
106         } else
107         nStartPos = len;
108     } else {
109         nDone = (len - nStartPos > nCount) ? nCount : len - nStartPos;
110         nStartPos += nDone;
111     }
112 
113     return nStartPos;
114 }
115 
116 // This method should be overwritten by derived language specific class.
makeIndex(const OUString &,sal_Int32)117 void SAL_CALL BreakIterator_CTL::makeIndex(const OUString& /*text*/, sal_Int32 /*pos*/)
118 {
119     throw RuntimeException();
120 }
121 
122 // Make sure line is broken on cell boundary if we implement cell iterator.
getLineBreak(const OUString & Text,sal_Int32 nStartPos,const lang::Locale & rLocale,sal_Int32 nMinBreakPos,const LineBreakHyphenationOptions & hOptions,const LineBreakUserOptions & bOptions)123 LineBreakResults SAL_CALL BreakIterator_CTL::getLineBreak(
124     const OUString& Text, sal_Int32 nStartPos,
125     const lang::Locale& rLocale, sal_Int32 nMinBreakPos,
126     const LineBreakHyphenationOptions& hOptions,
127     const LineBreakUserOptions& bOptions )
128 {
129     LineBreakResults lbr = BreakIterator_Unicode::getLineBreak(Text, nStartPos,
130                     rLocale, nMinBreakPos, hOptions, bOptions );
131     if (lbr.breakIndex < Text.getLength()) {
132         makeIndex(Text, lbr.breakIndex);
133         lbr.breakIndex = previousCellIndex[ lbr.breakIndex ];
134     }
135     return lbr;
136 }
137 
138 } } } }
139