xref: /aoo41x/main/vcl/source/fontsubset/xlat.cxx (revision cdf0e10c)
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