Updating the changelog in the VERSION file, and version_sync.
[shapes.git] / source / charconverters.cc
blob65ee0f74cd6c9c06840fb396fe3f94cbd7a86048
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008 Henrik Tidefelt
19 #include "strrefdup.h"
20 #include "charconverters.h"
21 #include "shapesexceptions.h"
22 #include "glyphlist.h"
23 #include "characterencoding.h"
24 #include "texttypes.h"
27 #include <iconv.h>
28 #include <string>
29 #include <fstream>
30 #include <sstream>
34 using namespace Shapes;
36 const char * Helpers::theUCS4EncodingName = "UCS-4";
38 iconv_t
39 Helpers::requireUTF8ToMacRomanConverter( bool cleanup )
41 static iconv_t converter = (iconv_t)( - 1 );
42 if( cleanup )
44 if( converter != (iconv_t)( -1 ) )
46 iconv_close( converter );
47 converter = (iconv_t)( -1 );
50 else
52 if( converter == (iconv_t)( -1 ) )
54 const char * iconv_Encoding_name = "Macintosh"; // This is meant to be what is called MacRoman in PDF.
55 converter = iconv_open( iconv_Encoding_name, "UTF-8" );
56 if( converter == (iconv_t)( -1 ) )
58 std::ostringstream msg;
59 msg << "iconv_open failed to create converter from UTF-8 to " << iconv_Encoding_name << "." ;
60 throw Exceptions::ExternalError( strrefdup( msg ) );
64 return converter;
67 iconv_t
68 Helpers::requireMacRomanToUTF8Converter( bool cleanup )
70 static iconv_t converter = (iconv_t)( - 1 );
71 if( cleanup )
73 if( converter != (iconv_t)( -1 ) )
75 iconv_close( converter );
76 converter = (iconv_t)( -1 );
79 else
81 if( converter == (iconv_t)( -1 ) )
83 const char * iconv_Encoding_name = "Macintosh"; // This is meant to be what is called MacRoman in PDF.
84 converter = iconv_open( "UTF-8", iconv_Encoding_name );
85 if( converter == (iconv_t)( -1 ) )
87 std::ostringstream msg;
88 msg << "iconv_open failed to create converter to UTF-8 from " << iconv_Encoding_name << "." ;
89 throw Exceptions::ExternalError( strrefdup( msg ) );
93 return converter;
96 iconv_t
97 Helpers::requireUTF8ToASCIIConverter( bool cleanup )
99 static iconv_t converter = (iconv_t)( - 1 );
100 if( cleanup )
102 if( converter != (iconv_t)( -1 ) )
104 iconv_close( converter );
105 converter = (iconv_t)( -1 );
108 else
110 if( converter == (iconv_t)( -1 ) )
112 const char * iconv_Encoding_name = "ASCII"; // This is used for the names of glyphs in a font
113 converter = iconv_open( iconv_Encoding_name, "UTF-8" );
114 if( converter == (iconv_t)( -1 ) )
116 std::ostringstream msg;
117 msg << "iconv_open failed to create converter from UTF-8 to " << iconv_Encoding_name << "." ;
118 throw Exceptions::ExternalError( strrefdup( msg ) );
122 return converter;
125 iconv_t
126 Helpers::requireUTF8ToUCS4Converter( bool cleanup )
128 static iconv_t converter = (iconv_t)( - 1 );
129 if( cleanup )
131 if( converter != (iconv_t)( -1 ) )
133 iconv_close( converter );
134 converter = (iconv_t)( -1 );
137 else
139 if( converter == (iconv_t)( -1 ) )
141 const char * iconv_Encoding_name = Helpers::theUCS4EncodingName; // This is used for the glyph list.
142 converter = iconv_open( iconv_Encoding_name, "UTF-8" );
143 if( converter == (iconv_t)( -1 ) )
145 std::ostringstream msg;
146 msg << "iconv_open failed to create converter from UTF-8 to " << iconv_Encoding_name << "." ;
147 throw Exceptions::ExternalError( strrefdup( msg ) );
151 return converter;
154 iconv_t
155 Helpers::requireUTF16BEToUCS4Converter( bool cleanup )
157 static iconv_t converter = (iconv_t)( - 1 );
158 if( cleanup )
160 if( converter != (iconv_t)( -1 ) )
162 iconv_close( converter );
163 converter = (iconv_t)( -1 );
166 else
168 if( converter == (iconv_t)( -1 ) )
170 const char * iconv_Encoding_name = Helpers::theUCS4EncodingName; // This is used for the glyph list.
171 converter = iconv_open( iconv_Encoding_name, "UTF-16BE" );
172 if( converter == (iconv_t)( -1 ) )
174 std::ostringstream msg;
175 msg << "iconv_open failed to create converter from UTF-8 to " << iconv_Encoding_name << "." ;
176 throw Exceptions::ExternalError( strrefdup( msg ) );
180 return converter;
183 iconv_t
184 Helpers::requireUTF8ToWinANSIConverter( bool cleanup )
186 static iconv_t converter = (iconv_t)( - 1 );
187 if( cleanup )
189 if( converter != (iconv_t)( -1 ) )
191 iconv_close( converter );
192 converter = (iconv_t)( -1 );
195 else
197 if( converter == (iconv_t)( -1 ) )
199 const char * iconv_Encoding_name = "LATIN1"; // This is meant to be what is called WinANSI in PDF.
200 converter = iconv_open( iconv_Encoding_name, "UTF-8" );
201 if( converter == (iconv_t)( -1 ) )
203 std::ostringstream msg;
204 msg << "iconv_open failed to create converter from UTF-8 to " << iconv_Encoding_name << "." ;
205 throw Exceptions::ExternalError( strrefdup( msg ) );
209 return converter;
212 const FontMetrics::GlyphList &
213 Helpers::requireGlyphList( bool cleanup )
215 static const FontMetrics::GlyphList * converter = 0;
216 if( cleanup )
218 if( converter != 0 )
220 delete converter;
221 converter = 0;
224 else
226 if( converter == 0 )
228 std::string filename = Lang::Font::searchGlyphList( );
229 std::ifstream iFile( filename.c_str( ) );
230 if( ! iFile.is_open( ) )
232 std::ostringstream oss;
233 oss << "Could locate, but not open the glyph list " << filename ;
234 throw Exceptions::ExternalError( strrefdup( oss ) );
238 converter = new FontMetrics::GlyphList( iFile );
240 catch( const char * ball )
242 std::ostringstream oss;
243 oss << "Parsing the glyph list " << filename << " resulted in the error: " << ball ;
244 throw Exceptions::ExternalError( strrefdup( oss ) );
246 catch( const std::string ball )
248 std::ostringstream oss;
249 oss << "Parsing the glyph list " << filename << " resulted in the error: " << ball ;
250 throw Exceptions::ExternalError( strrefdup( oss ) );
252 catch( const Shapes::Exceptions::Exception & ball )
254 std::cerr << "Parsing the glyph list " << filename << " resulted an error. Rethrowing." << std::endl ;
255 throw;
257 catch( ... )
259 throw Exceptions::InternalError( "An unrecognized exception was caught from glyph list parsing." );
263 return *converter;
266 const FontMetrics::CharacterEncoding &
267 Helpers::requireMacRomanEncoding( bool cleanup )
269 static const FontMetrics::CharacterEncoding * converter = 0;
270 if( cleanup )
272 if( converter != 0 )
274 delete converter;
275 converter = 0;
278 else
280 if( converter == 0 )
282 std::string filename = Lang::Font::searchCharacterEncoding( "MacRoman" );
283 std::ifstream iFile( filename.c_str( ) );
284 if( ! iFile.is_open( ) )
286 std::ostringstream oss;
287 oss << "Could locate, but not open the character encoding " << filename ;
288 throw Exceptions::ExternalError( strrefdup( oss ) );
292 converter = new FontMetrics::CharacterEncoding( iFile );
294 catch( const char * ball )
296 std::ostringstream oss;
297 oss << "Parsing the character encoding " << filename << " resulted in the error: " << ball ;
298 throw Exceptions::ExternalError( strrefdup( oss ) );
300 catch( const std::string ball )
302 std::ostringstream oss;
303 oss << "Parsing the character encoding " << filename << " resulted in the error: " << ball ;
304 throw Exceptions::ExternalError( strrefdup( oss ) );
306 catch( const Shapes::Exceptions::Exception & ball )
308 std::cerr << "Parsing the character encoding " << filename << " resulted an error. Rethrowing." << std::endl ;
309 throw;
311 catch( ... )
313 throw Exceptions::InternalError( "An unrecognized exception was caught from character encoding parsing." );
317 return *converter;