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 #include "rtl/textcvt.h" 29 #include <tools/debug.hxx> 30 31 namespace { // anonymous namespace 32 33 // ==================================================================== 34 35 #define MAX_CVT_SELECT 6 36 37 class ConverterCache 38 { 39 public: 40 explicit ConverterCache( void ); 41 ~ConverterCache( void ); 42 sal_uInt16 convertOne( int nSelect, sal_Unicode ); 43 void convertStr( int nSelect, const sal_Unicode* pSrc, sal_uInt16* pDst, int nCount ); 44 protected: 45 void ensureConverter( int nSelect ); 46 private: 47 rtl_UnicodeToTextConverter maConverterCache[ MAX_CVT_SELECT+1 ]; 48 rtl_UnicodeToTextContext maContexts[ MAX_CVT_SELECT+1 ]; 49 }; 50 51 // ==================================================================== 52 53 ConverterCache::ConverterCache( void) 54 { 55 for( int i = 0; i <= MAX_CVT_SELECT; ++i) 56 { 57 maConverterCache[i] = NULL; 58 maContexts[i] = NULL; 59 } 60 } 61 62 // -------------------------------------------------------------------- 63 64 ConverterCache::~ConverterCache( void) 65 { 66 for( int i = 0; i <= MAX_CVT_SELECT; ++i) 67 { 68 if( !maContexts[i] ) 69 continue; 70 rtl_destroyUnicodeToTextContext( maConverterCache[i], maContexts[i] ); 71 rtl_destroyUnicodeToTextConverter( maConverterCache[i] ); 72 } 73 } 74 75 // -------------------------------------------------------------------- 76 77 void ConverterCache::ensureConverter( int nSelect ) 78 { 79 // DBG_ASSERT( (2<=nSelect) && (nSelect<=MAX_CVT_SELECT)), "invalid XLAT.Converter requested" ); 80 rtl_UnicodeToTextContext aContext = maContexts[ nSelect ]; 81 if( !aContext ) 82 { 83 rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE; 84 switch( nSelect ) 85 { 86 default: nSelect = 1; // fall through to unicode recoding 87 case 1: eRecodeFrom = RTL_TEXTENCODING_UNICODE; break; 88 case 2: eRecodeFrom = RTL_TEXTENCODING_SHIFT_JIS; break; 89 case 3: eRecodeFrom = RTL_TEXTENCODING_GB_2312; break; 90 case 4: eRecodeFrom = RTL_TEXTENCODING_BIG5; break; 91 case 5: eRecodeFrom = RTL_TEXTENCODING_MS_949; break; 92 case 6: eRecodeFrom = RTL_TEXTENCODING_MS_1361; break; 93 } 94 rtl_UnicodeToTextConverter aRecodeConverter = rtl_createUnicodeToTextConverter( eRecodeFrom ); 95 maConverterCache[ nSelect ] = aRecodeConverter; 96 97 aContext = rtl_createUnicodeToTextContext( aRecodeConverter ); 98 maContexts[ nSelect ] = aContext; 99 } 100 101 rtl_resetUnicodeToTextContext( maConverterCache[ nSelect ], aContext ); 102 } 103 104 // -------------------------------------------------------------------- 105 106 sal_uInt16 ConverterCache::convertOne( int nSelect, sal_Unicode aChar ) 107 { 108 ensureConverter( nSelect ); 109 110 sal_Unicode aUCS2Char = aChar; 111 sal_Char aTempArray[8]; 112 sal_Size nTempSize; 113 sal_uInt32 nCvtInfo; 114 115 // TODO: use direct unicode->mbcs converter should there ever be one 116 int nCodeLen = rtl_convertUnicodeToText( 117 maConverterCache[ nSelect ], maContexts[ nSelect ], 118 &aUCS2Char, 1, aTempArray, sizeof(aTempArray), 119 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0 120 | RTL_UNICODETOTEXT_FLAGS_INVALID_0, 121 &nCvtInfo, &nTempSize ); 122 123 sal_uInt16 aCode = aTempArray[0]; 124 for( int i = 1; i < nCodeLen; ++i ) 125 aCode = (aCode << 8) + (aTempArray[i] & 0xFF); 126 return aCode; 127 } 128 129 // -------------------------------------------------------------------- 130 131 void ConverterCache::convertStr( int nSelect, const sal_Unicode* pSrc, sal_uInt16* pDst, int nCount ) 132 { 133 ensureConverter( nSelect ); 134 135 for( int n = 0; n < nCount; ++n ) 136 { 137 sal_Unicode aUCS2Char = pSrc[n]; 138 139 sal_Char aTempArray[8]; 140 sal_Size nTempSize; 141 sal_uInt32 nCvtInfo; 142 143 // assume that non-unicode-fonts do not support codepoints >U+FFFF 144 // TODO: use direct unicode->mbcs converter should there ever be one 145 int nCodeLen = rtl_convertUnicodeToText( 146 maConverterCache[ nSelect ], maContexts[ nSelect ], 147 &aUCS2Char, 1, aTempArray, sizeof(aTempArray), 148 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0 149 | RTL_UNICODETOTEXT_FLAGS_INVALID_0, 150 &nCvtInfo, &nTempSize ); 151 152 sal_uInt16 aCode = aTempArray[0]; 153 for( int i = 1; i < nCodeLen; ++i ) 154 aCode = (aCode << 8) + (aTempArray[i] & 0xFF); 155 pDst[n] = aCode; 156 } 157 } 158 159 } // anonymous namespace 160 161 // ==================================================================== 162 163 #include "xlat.hxx" 164 165 namespace vcl 166 { 167 168 static ConverterCache aCC; 169 170 sal_uInt16 TranslateChar12(sal_uInt16 src) 171 { 172 return aCC.convertOne( 2, src); 173 } 174 175 sal_uInt16 TranslateChar13(sal_uInt16 src) 176 { 177 return aCC.convertOne( 3, src); 178 } 179 180 sal_uInt16 TranslateChar14(sal_uInt16 src) 181 { 182 return aCC.convertOne( 4, src); 183 } 184 185 sal_uInt16 TranslateChar15(sal_uInt16 src) 186 { 187 return aCC.convertOne( 5, src); 188 } 189 190 sal_uInt16 TranslateChar16(sal_uInt16 src) 191 { 192 return aCC.convertOne( 6, src); 193 } 194 195 void TranslateString12(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n) 196 { 197 aCC.convertStr( 2, src, dst, n); 198 } 199 200 void TranslateString13(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n) 201 { 202 aCC.convertStr( 3, src, dst, n); 203 } 204 205 void TranslateString14(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n) 206 { 207 aCC.convertStr( 4, src, dst, n); 208 } 209 210 void TranslateString15(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n) 211 { 212 aCC.convertStr( 5, src, dst, n); 213 } 214 215 void TranslateString16(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n) 216 { 217 aCC.convertStr( 6, src, dst, n); 218 } 219 220 } // namespace vcl 221 222