1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_i18npool.hxx" 30 31 #include <com/sun/star/i18n/CharacterIteratorMode.hpp> 32 #include <breakiterator_ctl.hxx> 33 34 #include <string.h> // for memset 35 36 using namespace ::com::sun::star::uno; 37 using namespace ::com::sun::star::lang; 38 using namespace ::rtl; 39 40 namespace com { namespace sun { namespace star { namespace i18n { 41 42 /** 43 * Constructor. 44 */ 45 BreakIterator_CTL::BreakIterator_CTL() : 46 cachedText(), 47 nextCellIndex( NULL ), 48 previousCellIndex( NULL ), 49 cellIndexSize( 512 ) 50 { 51 cBreakIterator = "com.sun.star.i18n.BreakIterator_CTL"; 52 // to improve performance, alloc big enough memory in construct. 53 nextCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32)); 54 previousCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32)); 55 memset(nextCellIndex, 0, cellIndexSize * sizeof(sal_Int32)); 56 } 57 58 /** 59 * Deconstructor. 60 */ 61 BreakIterator_CTL::~BreakIterator_CTL() 62 { 63 free(nextCellIndex); 64 free(previousCellIndex); 65 } 66 67 sal_Int32 SAL_CALL BreakIterator_CTL::previousCharacters( const OUString& Text, 68 sal_Int32 nStartPos, const lang::Locale& rLocale, 69 sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone ) 70 throw(RuntimeException) 71 { 72 if (nCharacterIteratorMode == CharacterIteratorMode::SKIPCELL ) { 73 nDone = 0; 74 if (nStartPos > 0) { // for others to skip cell. 75 makeIndex(Text, nStartPos); 76 77 if (nextCellIndex[nStartPos-1] == 0) // not a CTL character 78 return BreakIterator_Unicode::previousCharacters(Text, nStartPos, rLocale, 79 nCharacterIteratorMode, nCount, nDone); 80 else while (nCount > 0 && nextCellIndex[nStartPos - 1] > 0) { 81 nCount--; nDone++; 82 nStartPos = previousCellIndex[nStartPos - 1]; 83 } 84 } else 85 nStartPos = 0; 86 } else { // for BS to delete one char. 87 nDone = (nStartPos > nCount) ? nCount : nStartPos; 88 nStartPos -= nDone; 89 } 90 91 return nStartPos; 92 } 93 94 sal_Int32 SAL_CALL BreakIterator_CTL::nextCharacters(const OUString& Text, 95 sal_Int32 nStartPos, const lang::Locale& rLocale, 96 sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone) 97 throw(RuntimeException) 98 { 99 sal_Int32 len = Text.getLength(); 100 if (nCharacterIteratorMode == CharacterIteratorMode::SKIPCELL ) { 101 nDone = 0; 102 if (nStartPos < len) { 103 makeIndex(Text, nStartPos); 104 105 if (nextCellIndex[nStartPos] == 0) // not a CTL character 106 return BreakIterator_Unicode::nextCharacters(Text, nStartPos, rLocale, 107 nCharacterIteratorMode, nCount, nDone); 108 else while (nCount > 0 && nextCellIndex[nStartPos] > 0) { 109 nCount--; nDone++; 110 nStartPos = nextCellIndex[nStartPos]; 111 } 112 } else 113 nStartPos = len; 114 } else { 115 nDone = (len - nStartPos > nCount) ? nCount : len - nStartPos; 116 nStartPos += nDone; 117 } 118 119 return nStartPos; 120 } 121 122 // This method should be overwritten by derived language specific class. 123 void SAL_CALL BreakIterator_CTL::makeIndex(const OUString& /*text*/, sal_Int32 /*pos*/) 124 throw(RuntimeException) 125 { 126 throw RuntimeException(); 127 } 128 129 // Make sure line is broken on cell boundary if we implement cell iterator. 130 LineBreakResults SAL_CALL BreakIterator_CTL::getLineBreak( 131 const OUString& Text, sal_Int32 nStartPos, 132 const lang::Locale& rLocale, sal_Int32 nMinBreakPos, 133 const LineBreakHyphenationOptions& hOptions, 134 const LineBreakUserOptions& bOptions ) throw(RuntimeException) 135 { 136 LineBreakResults lbr = BreakIterator_Unicode::getLineBreak(Text, nStartPos, 137 rLocale, nMinBreakPos, hOptions, bOptions ); 138 if (lbr.breakIndex < Text.getLength()) { 139 makeIndex(Text, lbr.breakIndex); 140 lbr.breakIndex = previousCellIndex[ lbr.breakIndex ]; 141 } 142 return lbr; 143 } 144 145 } } } } 146