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