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