Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "rtl/textcvt.h"
21 : #include <tools/debug.hxx>
22 :
23 : namespace {
24 :
25 : #define MAX_CVT_SELECT 6
26 :
27 : class ConverterCache
28 : {
29 : public:
30 : explicit ConverterCache( void );
31 : ~ConverterCache( void );
32 : sal_uInt16 convertOne( int nSelect, sal_Unicode );
33 : void convertStr( int nSelect, const sal_Unicode* pSrc, sal_uInt16* pDst, int nCount );
34 : protected:
35 : void ensureConverter( int nSelect );
36 : private:
37 : rtl_UnicodeToTextConverter maConverterCache[ MAX_CVT_SELECT+1 ];
38 : rtl_UnicodeToTextContext maContexts[ MAX_CVT_SELECT+1 ];
39 : };
40 :
41 1 : ConverterCache::ConverterCache( void)
42 : {
43 8 : for( int i = 0; i <= MAX_CVT_SELECT; ++i)
44 : {
45 7 : maConverterCache[i] = NULL;
46 7 : maContexts[i] = NULL;
47 : }
48 1 : }
49 :
50 1 : ConverterCache::~ConverterCache( void)
51 : {
52 8 : for( int i = 0; i <= MAX_CVT_SELECT; ++i)
53 : {
54 7 : if( !maContexts[i] )
55 7 : continue;
56 0 : rtl_destroyUnicodeToTextContext( maConverterCache[i], maContexts[i] );
57 0 : rtl_destroyUnicodeToTextConverter( maConverterCache[i] );
58 : }
59 1 : }
60 :
61 0 : void ConverterCache::ensureConverter( int nSelect )
62 : {
63 : // DBG_ASSERT( (2<=nSelect) && (nSelect<=MAX_CVT_SELECT)), "invalid XLAT.Converter requested" );
64 0 : rtl_UnicodeToTextContext aContext = maContexts[ nSelect ];
65 0 : if( !aContext )
66 : {
67 0 : rtl_TextEncoding eRecodeFrom = RTL_TEXTENCODING_UNICODE;
68 0 : switch( nSelect )
69 : {
70 0 : default: nSelect = 1; // fall through to unicode recoding
71 0 : case 1: eRecodeFrom = RTL_TEXTENCODING_UNICODE; break;
72 0 : case 2: eRecodeFrom = RTL_TEXTENCODING_SHIFT_JIS; break;
73 0 : case 3: eRecodeFrom = RTL_TEXTENCODING_GB_2312; break;
74 0 : case 4: eRecodeFrom = RTL_TEXTENCODING_BIG5; break;
75 0 : case 5: eRecodeFrom = RTL_TEXTENCODING_MS_949; break;
76 0 : case 6: eRecodeFrom = RTL_TEXTENCODING_MS_1361; break;
77 : }
78 0 : rtl_UnicodeToTextConverter aRecodeConverter = rtl_createUnicodeToTextConverter( eRecodeFrom );
79 0 : maConverterCache[ nSelect ] = aRecodeConverter;
80 :
81 0 : aContext = rtl_createUnicodeToTextContext( aRecodeConverter );
82 0 : maContexts[ nSelect ] = aContext;
83 : }
84 :
85 0 : rtl_resetUnicodeToTextContext( maConverterCache[ nSelect ], aContext );
86 0 : }
87 :
88 0 : sal_uInt16 ConverterCache::convertOne( int nSelect, sal_Unicode aChar )
89 : {
90 0 : ensureConverter( nSelect );
91 :
92 0 : sal_Unicode aUCS2Char = aChar;
93 : sal_Char aTempArray[8];
94 : sal_Size nTempSize;
95 : sal_uInt32 nCvtInfo;
96 :
97 : // TODO: use direct unicode->mbcs converter should there ever be one
98 : int nCodeLen = rtl_convertUnicodeToText(
99 : maConverterCache[ nSelect ], maContexts[ nSelect ],
100 : &aUCS2Char, 1, aTempArray, sizeof(aTempArray),
101 : RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0
102 : | RTL_UNICODETOTEXT_FLAGS_INVALID_0,
103 0 : &nCvtInfo, &nTempSize );
104 :
105 0 : sal_uInt16 aCode = aTempArray[0];
106 0 : for( int i = 1; i < nCodeLen; ++i )
107 0 : aCode = (aCode << 8) + (aTempArray[i] & 0xFF);
108 0 : return aCode;
109 : }
110 :
111 0 : void ConverterCache::convertStr( int nSelect, const sal_Unicode* pSrc, sal_uInt16* pDst, int nCount )
112 : {
113 0 : ensureConverter( nSelect );
114 :
115 0 : for( int n = 0; n < nCount; ++n )
116 : {
117 0 : sal_Unicode aUCS2Char = pSrc[n];
118 :
119 : sal_Char aTempArray[8];
120 : sal_Size nTempSize;
121 : sal_uInt32 nCvtInfo;
122 :
123 : // assume that non-unicode-fonts do not support codepoints >U+FFFF
124 : // TODO: use direct unicode->mbcs converter should there ever be one
125 : int nCodeLen = rtl_convertUnicodeToText(
126 : maConverterCache[ nSelect ], maContexts[ nSelect ],
127 : &aUCS2Char, 1, aTempArray, sizeof(aTempArray),
128 : RTL_UNICODETOTEXT_FLAGS_UNDEFINED_0
129 : | RTL_UNICODETOTEXT_FLAGS_INVALID_0,
130 0 : &nCvtInfo, &nTempSize );
131 :
132 0 : sal_uInt16 aCode = aTempArray[0];
133 0 : for( int i = 1; i < nCodeLen; ++i )
134 0 : aCode = (aCode << 8) + (aTempArray[i] & 0xFF);
135 0 : pDst[n] = aCode;
136 : }
137 0 : }
138 :
139 : } // anonymous namespace
140 :
141 : #include "xlat.hxx"
142 :
143 : namespace vcl
144 : {
145 :
146 1 : static ConverterCache aCC;
147 :
148 0 : sal_uInt16 TranslateChar12(sal_uInt16 src)
149 : {
150 0 : return aCC.convertOne( 2, src);
151 : }
152 :
153 0 : sal_uInt16 TranslateChar13(sal_uInt16 src)
154 : {
155 0 : return aCC.convertOne( 3, src);
156 : }
157 :
158 0 : sal_uInt16 TranslateChar14(sal_uInt16 src)
159 : {
160 0 : return aCC.convertOne( 4, src);
161 : }
162 :
163 0 : sal_uInt16 TranslateChar15(sal_uInt16 src)
164 : {
165 0 : return aCC.convertOne( 5, src);
166 : }
167 :
168 0 : sal_uInt16 TranslateChar16(sal_uInt16 src)
169 : {
170 0 : return aCC.convertOne( 6, src);
171 : }
172 :
173 0 : void TranslateString12(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n)
174 : {
175 0 : aCC.convertStr( 2, src, dst, n);
176 0 : }
177 :
178 0 : void TranslateString13(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n)
179 : {
180 0 : aCC.convertStr( 3, src, dst, n);
181 0 : }
182 :
183 0 : void TranslateString14(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n)
184 : {
185 0 : aCC.convertStr( 4, src, dst, n);
186 0 : }
187 :
188 0 : void TranslateString15(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n)
189 : {
190 0 : aCC.convertStr( 5, src, dst, n);
191 0 : }
192 :
193 0 : void TranslateString16(sal_uInt16 *src, sal_uInt16 *dst, sal_uInt32 n)
194 : {
195 0 : aCC.convertStr( 6, src, dst, n);
196 0 : }
197 :
198 3 : } // namespace vcl
199 :
200 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|