From: <man...@us...> - 2013-09-05 14:21:20
|
Revision: 2634 http://sourceforge.net/p/modplug/code/2634 Author: manxorist Date: 2013-09-05 14:21:11 +0000 (Thu, 05 Sep 2013) Log Message: ----------- [Mod] libopenmpt: All strings are now returned in UTF-8 encoding. [Ref] xmp-openmpt: Adapt coded to always utf8. [Mod] openmpt123: Set console to UTF-8 mode to properly display hopefully all strings from the mod files. This breaks filename display (but non-ansi filenames where broken anyway before, will be fixed later). [Mod] in_openmpt: Strings are now returned in UTF-8. Modified Paths: -------------- trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp trunk/OpenMPT/libopenmpt/libopenmpt_impl.hpp trunk/OpenMPT/libopenmpt/libopenmpt_xmplay.cpp trunk/OpenMPT/openmpt123/openmpt123.cpp Modified: trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp 2013-09-05 14:08:00 UTC (rev 2633) +++ trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp 2013-09-05 14:21:11 UTC (rev 2634) @@ -22,6 +22,10 @@ #include <cstdlib> #include <cstring> +#if !defined(WIN32) +#include <iconv.h> +#endif // !WIN32 + #include "soundlib/Sndfile.h" #include "soundlib/AudioReadTarget.h" #include "soundlib/FileReader.h" @@ -149,6 +153,58 @@ } } +std::string module_impl::mod_string_to_utf8( const std::string & encoded ) const { + std::string charset = m_sndFile->GetCharset().second; + #if defined(WIN32) + std::transform( charset.begin(), charset.end(), charset.begin(), tolower ); + UINT codepage = 0; + if ( charset == "" ) { + codepage = 20127; // us ascii fallback + } else if ( charset == "windows-1252" ) { + codepage = 1252; + } else if ( charset == "iso-8859-1" ) { + codepage = 28591; + } else if ( charset == "utf-8" ) { + codepage = 65001; + } else if ( charset == "us-ascii" ) { + codepage = 20127; + } else if ( charset == "cp437" ) { + codepage = 437; + } else { + codepage = 20127; // us ascii fallback + } + int required_size = 0; + required_size = MultiByteToWideChar( codepage, 0, encoded.c_str(), -1, NULL, 0 ); + if ( required_size <= 0 ) { + return std::string(); + } + std::vector<WCHAR> unicode_string( required_size ); + MultiByteToWideChar( codepage, 0, encoded.data(), -1, &unicode_string[0], unicode_string.size() ); + required_size = WideCharToMultiByte( CP_UTF8, 0, &unicode_string[0], -1, NULL, 0, NULL, NULL ); + if ( required_size <= 0 ) { + return std::string(); + } + std::vector<CHAR> utf8_string( required_size ); + WideCharToMultiByte( CP_UTF8, 0, &unicode_string[0], -1, &utf8_string[0], utf8_string.size(), NULL, NULL ); + return &utf8_string[0]; + #else + iconv_t conv = iconv_t(); + conv = iconv_open( "UTF-8", charset.c_str() ); + std::vector<char> utf8_string( ( encoded.length() + 1 ) * 8 ); // large enough + const char * inbuf = encoded.c_str(); + size_t inbytesleft = encoded.length() + 1; + char * outbuf = &utf8_string[0]; + size_t outbytesleft = utf8_string.size(); + if ( iconv( conv, encoded.c_str(), &inbuf, &inbytesleft, &outbuf, &outbytesleft ) < 0 ) { + iconv_close( conv ); + conv = iconv_t(); + return std::string(); + } + std::string result = &utf8_string[0]; + iconv_close( conv ); + conv = iconv_t(); + #endif +} void module_impl::apply_mixer_settings( std::int32_t samplerate, int channels ) { if ( static_cast<std::int32_t>( m_sndFile->m_MixerSettings.gdwMixingFreq ) != samplerate || @@ -540,7 +596,7 @@ } else if ( key == std::string("tracker") ) { return m_sndFile->madeWithTracker; } else if ( key == std::string("title") ) { - return m_sndFile->GetTitle(); + return mod_string_to_utf8( m_sndFile->GetTitle() ); } else if ( key == std::string("message") ) { std::string retval = m_sndFile->songMessage.GetFormatted( SongMessage::leLF ); if ( retval.empty() ) { @@ -571,7 +627,7 @@ retval = tmp.str(); } } - return retval; + return mod_string_to_utf8( retval ); } else if ( key == std::string("warnings") ) { std::ostringstream retval; bool first = true; @@ -640,14 +696,14 @@ std::vector<std::string> module_impl::get_subsong_names() const { std::vector<std::string> retval; for ( SEQUENCEINDEX i = 0; i < m_sndFile->Order.GetNumSequences(); ++i ) { - retval.push_back( m_sndFile->Order.GetSequence( i ).m_sName ); + retval.push_back( mod_string_to_utf8( m_sndFile->Order.GetSequence( i ).m_sName ) ); } return retval; } std::vector<std::string> module_impl::get_channel_names() const { std::vector<std::string> retval; for ( CHANNELINDEX i = 0; i < m_sndFile->GetNumChannels(); ++i ) { - retval.push_back( m_sndFile->ChnSettings[i].szName ); + retval.push_back( mod_string_to_utf8( m_sndFile->ChnSettings[i].szName ) ); } return retval; } @@ -656,7 +712,7 @@ for ( ORDERINDEX i = 0; i < m_sndFile->Order.GetLengthTailTrimmed(); ++i ) { PATTERNINDEX pat = m_sndFile->Order[i]; if ( m_sndFile->Patterns.IsValidIndex( pat ) ) { - retval.push_back( m_sndFile->Patterns[ m_sndFile->Order[i] ].GetName() ); + retval.push_back( mod_string_to_utf8( m_sndFile->Patterns[ m_sndFile->Order[i] ].GetName() ) ); } else { if ( pat == m_sndFile->Order.GetIgnoreIndex() ) { retval.push_back( "+++ skip" ); @@ -672,21 +728,21 @@ std::vector<std::string> module_impl::get_pattern_names() const { std::vector<std::string> retval; for ( PATTERNINDEX i = 0; i < m_sndFile->Patterns.GetNumPatterns(); ++i ) { - retval.push_back( m_sndFile->Patterns[i].GetName() ); + retval.push_back( mod_string_to_utf8( m_sndFile->Patterns[i].GetName() ) ); } return retval; } std::vector<std::string> module_impl::get_instrument_names() const { std::vector<std::string> retval; for ( INSTRUMENTINDEX i = 1; i <= m_sndFile->GetNumInstruments(); ++i ) { - retval.push_back( m_sndFile->GetInstrumentName( i ) ); + retval.push_back( mod_string_to_utf8( m_sndFile->GetInstrumentName( i ) ) ); } return retval; } std::vector<std::string> module_impl::get_sample_names() const { std::vector<std::string> retval; for ( SAMPLEINDEX i = 1; i <= m_sndFile->GetNumSamples(); ++i ) { - retval.push_back( m_sndFile->GetSampleName( i ) ); + retval.push_back( mod_string_to_utf8( m_sndFile->GetSampleName( i ) ) ); } return retval; } @@ -797,7 +853,10 @@ if ( ctl == "" ) { throw openmpt::exception("unknown ctl"); } else if ( ctl == "charset" ) { + /* return m_sndFile->GetCharset().second; + */ + return "UTF-8"; } throw openmpt::exception("unknown ctl"); } Modified: trunk/OpenMPT/libopenmpt/libopenmpt_impl.hpp =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_impl.hpp 2013-09-05 14:08:00 UTC (rev 2633) +++ trunk/OpenMPT/libopenmpt/libopenmpt_impl.hpp 2013-09-05 14:21:11 UTC (rev 2634) @@ -64,6 +64,7 @@ void PushToCSoundFileLog( const std::string & text ) const; void PushToCSoundFileLog( int loglevel, const std::string & text ) const; private: + std::string mod_string_to_utf8( const std::string & encoded ) const; void apply_mixer_settings( std::int32_t samplerate, int channels ); void apply_libopenmpt_defaults(); void init( const std::map< std::string, std::string > & ctls ); Modified: trunk/OpenMPT/libopenmpt/libopenmpt_xmplay.cpp =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_xmplay.cpp 2013-09-05 14:08:00 UTC (rev 2633) +++ trunk/OpenMPT/libopenmpt/libopenmpt_xmplay.cpp 2013-09-05 14:21:11 UTC (rev 2634) @@ -77,33 +77,7 @@ }; static std::string convert_to_native( const std::string & str, std::string encoding ) { - std::transform( encoding.begin(), encoding.end(), encoding.begin(), tolower ); - UINT codepage = 0; - if ( encoding == "" ) { - codepage = 20127; // us ascii fallback - } else if ( encoding == "windows-1252" ) { - codepage = 1252; - } else if ( encoding == "iso-8859-1" ) { - codepage = 28591; - } else if ( encoding == "utf-8" ) { - codepage = 65001; - } else if ( encoding == "us-ascii" ) { - codepage = 20127; - } else if ( encoding == "cp437" ) { - codepage = 437; - } else { - codepage = 20127; // us ascii fallback - } - std::vector<WCHAR> unicode_string( ( ( str.length() + 1 ) * 8 ) ); // sufficiently large enough; - int mbtowc_result = MultiByteToWideChar( codepage, 0, str.data(), -1, unicode_string.data(), unicode_string.size() ); - if ( mbtowc_result > 0 ) { - unicode_string.resize( mbtowc_result ); - } else { - unicode_string.clear(); - unicode_string.push_back( L' ' ); - unicode_string.push_back( L'\0' ); - } - char * native_string = xmpftext->Unicode( unicode_string.data(), -1 ); + char * native_string = xmpftext->Utf8( str.c_str(), -1 ); std::string result = native_string ? native_string : ""; if ( native_string ) { xmpfmisc->Free( native_string ); Modified: trunk/OpenMPT/openmpt123/openmpt123.cpp =================================================================== --- trunk/OpenMPT/openmpt123/openmpt123.cpp 2013-09-05 14:08:00 UTC (rev 2633) +++ trunk/OpenMPT/openmpt123/openmpt123.cpp 2013-09-05 14:21:11 UTC (rev 2634) @@ -1376,6 +1376,13 @@ static int main( int argc, char * argv [] ) { + #if defined(_MSC_VER) + + SetConsoleCP( 65001 ); // UTF-8 + SetConsoleOutputCP( 65001 ); // UTF-8 + + #endif + textout_dummy dummy_log; #if defined(_MSC_VER) @@ -1433,7 +1440,6 @@ if ( flags.mode == ModeUI ) { set_input_mode(); - } #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |