Reject Language**.txt with a non-UTF-8 charset

This allows some simplifications:
- CStdFont does not have to convert to Unicode for Freetype
- the developer mode does not have to convert to Unicode for GTK+
- The EnsureUnicode function can be called unconditionally

This also switches the IRC charset fixup code to convert to UTF-8, not from
UTF-8.
stable-5.2
Günther Brammer 2009-06-28 22:53:32 +02:00
parent 1ce653fd40
commit e65f337dfd
20 changed files with 84 additions and 209 deletions

View File

@ -82,7 +82,6 @@ class C4ConfigGeneral
void AdoptOldSettings();
void DeterminePaths(BOOL forceWorkingDirectory);
void CompileFunc(StdCompiler *pComp);
bool IsUTF8() { return SEqual(LoadResStr("IDS_LANG_CHARSET"), "UTF-8"); }
void AddAdditionalDataPath(const char *szPath);
void ClearAdditionalDataPaths();
~C4ConfigGeneral() { ClearAdditionalDataPaths(); }

View File

@ -61,7 +61,7 @@ class C4VectorFont
~C4VectorFont(); // dtor - releases font and deletes temp file
bool Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg); // load font from group
bool Init(const char *szFacename, int32_t iSize, uint32_t dwWeight, const char *szCharSet); // load system font specified by face name
bool Init(const char *szFacename, int32_t iSize, uint32_t dwWeight); // load system font specified by face name
void Init(const char *szName, CStdVectorFont *pFont); // init from a font that has been laoded already
friend class C4FontLoader;
};

View File

@ -41,7 +41,6 @@ class C4LanguageInfo
char Name[C4MaxLanguageInfo + 1];
char Info[C4MaxLanguageInfo + 1];
char Fallback[C4MaxLanguageInfo + 1];
char Charset[C4MaxLanguageInfo + 1];
//char Location[C4MaxLanguageInfo + 1]; ...store group name here
protected:
C4LanguageInfo* Next;
@ -76,7 +75,6 @@ class C4Language
// Encoding conversion functions
static StdStrBuf IconvClonk(const char * string);
static StdStrBuf IconvSystem(const char * string);
static StdStrBuf IconvUtf8(const char * string);
protected:
// Handling of language info loaded from string tables
void InitInfos();
@ -87,15 +85,10 @@ class C4Language
#ifdef HAVE_ICONV
static iconv_t local_to_host;
static iconv_t host_to_local;
static iconv_t local_to_utf_8;
static StdStrBuf Iconv(const char * string, iconv_t cd);
#endif
};
extern C4Language Languages;
static inline StdStrBuf LoadResStrUtf8(const char* ident)
{
return Languages.IconvUtf8(LoadResStr(ident));
}
#endif

View File

@ -27,16 +27,16 @@
#include "C4Network2IRC.h"
#include "C4MessageInput.h"
void convUTF8toWindows(StdStrBuf &sText)
void ConvWindowsToUTF8(StdStrBuf &sText)
{
// workaround until we have UTF-8 support: convert German umlauts and ß
sText.Replace("\xc3\x84", "Ä");
sText.Replace("\xc3\x96", "Ö");
sText.Replace("\xc3\x9c", "Ü");
sText.Replace("\xc3\xa4", "ä");
sText.Replace("\xc3\xb6", "ö");
sText.Replace("\xc3\xbc", "ü");
sText.Replace("\xc3\x9f", "ß");
// work around (German) legacy clients using windows-1252
sText.Replace("Ä", "\xc3\x84");
sText.Replace("Ö", "\xc3\x96");
sText.Replace("Ü", "\xc3\x9c");
sText.Replace("ä", "\xc3\xa4");
sText.Replace("ö", "\xc3\xb6");
sText.Replace("ü", "\xc3\xbc");
sText.Replace("ß", "\xc3\x9f");
}
/* C4ChatControl::ChatSheet::NickItem */
@ -219,8 +219,8 @@ void C4ChatControl::ChatSheet::AddTextLine(const char *szText, uint32_t dwClr)
StdStrBuf sText; sText.Copy(szText);
for (char c='\x01'; c<' '; ++c)
sText.ReplaceChar(c, ' ');
// convert incoming UTF-8
convUTF8toWindows(sText);
// convert incoming Windows-1252
ConvWindowsToUTF8(sText);
// add text line to chat box
CStdFont *pUseFont = &C4GUI::GetRes()->TextFont;
pChatBox->AddTextLine(sText.getData(), pUseFont, dwClr, true, false);
@ -272,7 +272,7 @@ void C4ChatControl::ChatSheet::Update(bool fLock)
// update topic
const char *szTopic = pIRCChan->getTopic();
sChatTitle.Format("%s%s%s", sIdent.getData(), szTopic ? ": " : "", szTopic ? szTopic : "");
convUTF8toWindows(sChatTitle);
ConvWindowsToUTF8(sChatTitle);
}
}
}

View File

@ -140,15 +140,12 @@ BOOL C4ComponentHost::Load(const char *szName,
sprintf(strEntryWithLanguage, strEntry, strCode);
if (hGroup.LoadEntryString(strEntryWithLanguage, Data))
{
if (pConfig->General.IsUTF8())
Data.EnsureUnicode();
// Skip those stupid "zero width no-break spaces" (also known as Byte Order Marks)
if (Data[0] == '\xEF' && Data[1] == '\xBB' && Data[2] == '\xBF')
{
Data.EnsureUnicode();
// Skip those stupid "zero width no-break spaces" (also known as Byte Order Marks)
if (Data[0] == '\xEF' && Data[1] == '\xBB' && Data[2] == '\xBF')
{
Data.Move(3,Data.getSize()-3);
Data.Shrink(3);
}
Data.Move(3,Data.getSize()-3);
Data.Shrink(3);
}
// Store actual filename
hGroup.FindEntry(strEntryWithLanguage, Filename);
@ -189,7 +186,7 @@ BOOL C4ComponentHost::Load(const char *szName,
sprintf(strEntryWithLanguage, strEntry, strCode);
if (hGroupSet.LoadEntryString(strEntryWithLanguage, Data))
{
if (pConfig->General.IsUTF8()) Data.EnsureUnicode();
Data.EnsureUnicode();
// Store actual filename
C4Group *pGroup = hGroupSet.FindEntry(strEntryWithLanguage);
pGroup->FindEntry(strEntryWithLanguage, Filename);

View File

@ -833,7 +833,6 @@ const char* C4Config::AtDataReadPath(const char *szFilename, bool fPreferWorkdir
const char* C4Config::AtDataReadPathCore(const char *szFilename, bool fPreferWorkdir)
{
const char *szPath;
if (fPreferWorkdir && FileExists(szFilename))
{
SCopy(GetWorkingDirectory(),AtPathFilename,_MAX_PATH-1);

View File

@ -97,22 +97,6 @@ namespace {
gdk_pixbuf_unref(pixbuf);
return image;
}
class ImplicitStrBuf: public StdStrBuf {
public:
ImplicitStrBuf(StdStrBuf RREF Buf2): StdStrBuf(static_cast<StdStrBuf RREF>(Buf2)) { }
#ifdef HAVE_RVALUE_REF
ImplicitStrBuf(const StdStrBuf & Buf2): StdStrBuf(Buf2) { }
#endif
ImplicitStrBuf(ImplicitStrBuf RREF Buf2): StdStrBuf(static_cast<ImplicitStrBuf RREF>(Buf2)) { }
ImplicitStrBuf(const ImplicitStrBuf & Buf2): StdStrBuf(Buf2) { }
operator const char *() const { return getData(); }
};
inline ImplicitStrBuf LoadResStrUtf8I(const char * ident)
{
return ImplicitStrBuf(Languages.IconvUtf8(LoadResStr(ident)));
}
}
#endif
@ -470,10 +454,10 @@ GtkWidget* C4Console::InitGUI()
// ------------ Menu -------------------
menuBar = gtk_menu_bar_new();
GtkWidget* itemFile = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_FILE"));
GtkWidget* itemComponents = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_COMPONENTS"));
GtkWidget* itemPlayer = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_PLAYER"));
GtkWidget* itemViewport = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_VIEWPORT"));
GtkWidget* itemFile = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_FILE"));
GtkWidget* itemComponents = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_COMPONENTS"));
GtkWidget* itemPlayer = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_PLAYER"));
GtkWidget* itemViewport = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_VIEWPORT"));
GtkWidget* itemHelp = gtk_menu_item_new_with_label("?");
gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), itemFile);
@ -495,58 +479,58 @@ GtkWidget* C4Console::InitGUI()
gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemViewport), menuViewport);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemHelp), menuHelp);
fileOpen = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_OPEN"));
fileOpen = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_OPEN"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileOpen);
fileOpenWithPlayers = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_OPENWPLRS"));
fileOpenWithPlayers = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_OPENWPLRS"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileOpenWithPlayers);
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new()));
fileSave = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_SAVESCENARIO"));
fileSave = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVESCENARIO"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSave);
fileSaveAs = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_SAVESCENARIOAS"));
fileSaveAs = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVESCENARIOAS"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveAs);
fileSaveGame = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_SAVEGAME"));
fileSaveGame = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVEGAME"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveGame);
fileSaveGameAs = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_SAVEGAMEAS"));
fileSaveGameAs = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SAVEGAMEAS"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileSaveGameAs);
fileRecord = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_RECORD"));
fileRecord = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_RECORD"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileRecord);
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new()));
fileClose = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_CLOSE"));
fileClose = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_CLOSE"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileClose);
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), GTK_WIDGET(gtk_separator_menu_item_new()));
fileQuit = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_QUIT"));
fileQuit = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_QUIT"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuFile), fileQuit);
compObjects = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_BTN_OBJECTS"));
compObjects = gtk_menu_item_new_with_label(LoadResStr("IDS_BTN_OBJECTS"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compObjects);
compScript = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_SCRIPT"));
compScript = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_SCRIPT"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compScript);
compTitle = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_TITLE"));
compTitle = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_TITLE"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compTitle);
compInfo = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_INFO"));
compInfo = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_INFO"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuComponents), compInfo);
plrJoin = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_JOIN"));
plrJoin = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_JOIN"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuPlayer), plrJoin);
viewNew = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_NEW"));
viewNew = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_NEW"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuViewport), viewNew);
helpAbout = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MENU_ABOUT"));
helpAbout = gtk_menu_item_new_with_label(LoadResStr("IDS_MENU_ABOUT"));
gtk_menu_shell_append(GTK_MENU_SHELL(menuHelp), helpAbout);
// ------------ Window ---------------------
@ -644,7 +628,7 @@ bool C4Console::Out(const char *szText)
GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtLog));
gtk_text_buffer_get_end_iter(buffer, &end);
gtk_text_buffer_insert(buffer, &end, C4Language::IconvUtf8(szText).getData(), -1);
gtk_text_buffer_insert(buffer, &end, szText, -1);
gtk_text_buffer_insert(buffer, &end, "\n", 1);
gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(txtLog), gtk_text_buffer_get_insert(buffer), 0.0, FALSE, 0.0, 0.0);
@ -1245,7 +1229,7 @@ bool C4Console::UpdateCursorBar(const char *szCursor)
SetDlgItemText(hWindow,IDC_STATICCURSOR,szCursor);
UpdateWindow(GetDlgItem(hWindow,IDC_STATICCURSOR));
#elif defined(WITH_DEVELOPER_MODE)
gtk_label_set_label(GTK_LABEL(lblCursor), Languages.IconvUtf8(szCursor).getData());
gtk_label_set_label(GTK_LABEL(lblCursor), szCursor);
#endif
return TRUE;
}
@ -1264,7 +1248,7 @@ bool C4Console::UpdateViewportMenu()
#ifdef _WIN32
AddMenuItem(hMenu,IDM_VIEWPORT_NEW1+pPlr->Number,sText.getData());
#elif defined(WITH_DEVELOPER_MODE)
GtkWidget* menuItem = gtk_menu_item_new_with_label(Languages.IconvUtf8(sText.getData()).getData());
GtkWidget* menuItem = gtk_menu_item_new_with_label(sText.getData());
gtk_menu_shell_append(GTK_MENU_SHELL(menuViewport), menuItem);
g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(OnViewNewPlr), GINT_TO_POINTER(pPlr->Number));
gtk_widget_show(menuItem);
@ -1432,7 +1416,7 @@ bool C4Console::UpdatePlayerMenu()
AddMenuItem(hMenu,IDM_PLAYER_QUIT1+pPlr->Number,sText.getData(),(!::Network.isEnabled() || ::Network.isHost()) && Editing);
#elif defined(WITH_DEVELOPER_MODE)
// TODO: Implement AddMenuItem...
GtkWidget* menuItem = gtk_menu_item_new_with_label(Languages.IconvUtf8(sText.getData()).getData());
GtkWidget* menuItem = gtk_menu_item_new_with_label(sText.getData());
gtk_menu_shell_append(GTK_MENU_SHELL(menuPlayer), menuItem);
g_signal_connect(G_OBJECT(menuItem), "activate", G_CALLBACK(OnPlrQuit), GINT_TO_POINTER(pPlr->Number));
gtk_widget_show(menuItem);
@ -1557,7 +1541,7 @@ void C4Console::UpdateNetMenu()
#ifdef _WIN32
if (!InsertMenu(GetMenu(hWindow),MenuIndexHelp,MF_BYPOSITION | MF_POPUP,(UINT)CreateMenu(),LoadResStr("IDS_MNU_NET"))) return;
#elif defined(WITH_DEVELOPER_MODE)
itemNet = gtk_menu_item_new_with_label(LoadResStrUtf8I("IDS_MNU_NET"));
itemNet = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_NET"));
GtkWidget* menuNet = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(itemNet), menuNet);
gtk_menu_shell_insert(GTK_MENU_SHELL(menuBar), itemNet, MenuIndexHelp);

View File

@ -105,9 +105,9 @@ BOOL C4EditCursor::Init()
#ifdef WITH_DEVELOPER_MODE
menuContext = gtk_menu_new();
itemDelete = gtk_menu_item_new_with_label(LoadResStrUtf8("IDS_MNU_DELETE").getData());
itemDuplicate = gtk_menu_item_new_with_label(LoadResStrUtf8("IDS_MNU_DUPLICATE").getData());
itemGrabContents = gtk_menu_item_new_with_label(LoadResStrUtf8("IDS_MNU_CONTENTS").getData());
itemDelete = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_DELETE"));
itemDuplicate = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_DUPLICATE"));
itemGrabContents = gtk_menu_item_new_with_label(LoadResStr("IDS_MNU_CONTENTS"));
itemProperties = gtk_menu_item_new_with_label(""); // Set dynamically in DoContextMenu
gtk_menu_shell_append(GTK_MENU_SHELL(menuContext), itemDelete);
@ -635,7 +635,7 @@ BOOL C4EditCursor::DoContextMenu()
gtk_widget_set_sensitive(itemProperties, Mode!=C4CNS_ModePlay);
GtkLabel* label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(itemProperties)));
gtk_label_set_text(label, LoadResStrUtf8((Mode==C4CNS_ModeEdit) ? "IDS_CNS_PROPERTIES" : "IDS_CNS_TOOLS").getData());
gtk_label_set_text(label, LoadResStr((Mode==C4CNS_ModeEdit) ? "IDS_CNS_PROPERTIES" : "IDS_CNS_TOOLS"));
gtk_menu_popup(GTK_MENU(menuContext), NULL, NULL, NULL, NULL, 3, 0);
#endif

View File

@ -111,7 +111,7 @@ bool C4VectorFont::Init(C4Group &hGrp, const char *szFilename, C4Config &rCfg)
return true;
}
bool C4VectorFont::Init(const char *szFacename, int32_t iSize, uint32_t dwWeight, const char *szCharSet)
bool C4VectorFont::Init(const char *szFacename, int32_t iSize, uint32_t dwWeight)
{
// name by face
Name.Copy(szFacename);
@ -122,7 +122,7 @@ bool C4VectorFont::Init(const char *szFacename, int32_t iSize, uint32_t dwWeight
if (hDC)
{
HFONT hFont = ::CreateFont(iSize, 0, 0, 0, dwWeight, FALSE,
FALSE, FALSE, GetCharsetCode(szCharSet), OUT_DEFAULT_PRECIS,
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, 5,
VARIABLE_PITCH, szFacename);
if (hFont)
@ -292,7 +292,7 @@ bool C4FontLoader::InitFont(CStdFont &rFont, C4VectorFont * pFont, int32_t iSize
if (!pFont->pFont) pFont->pFont = CStdFont::CreateFont(pFont->Name.getData());
if (!pFont->pFont) return false; // this font can't be used
}
rFont.Init(*(pFont->pFont), iSize, dwWeight, LoadResStr("IDS_LANG_CHARSET"), fDoShadow); // throws exception on error
rFont.Init(*(pFont->pFont), iSize, dwWeight, fDoShadow); // throws exception on error
return true;
}
@ -455,7 +455,7 @@ bool C4FontLoader::InitFont(CStdFont &rFont, const char *szFontName, FontType eT
if (!pFont)
{
pFont = new C4VectorFont();
if (pFont->Init(FontFaceName, iDefFontSize, dwDefWeight, LoadResStr("IDS_LANG_CHARSET")))
if (pFont->Init(FontFaceName, iDefFontSize, dwDefWeight))
{
AddVectorFont(pFont);
if (!InitFont(rFont, pFont, iDefFontSize, dwDefWeight, fDoShadow))

View File

@ -266,7 +266,7 @@ bool C4GameSave::SaveDesc(C4Group &hToGroup)
StdStrBuf sBuffer;
// Header
sBuffer.AppendFormat("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl {\\f0\\fnil\\fcharset%d Times New Roman;}}", GetCharsetCode(LoadResStr("IDS_LANG_CHARSET")));
sBuffer.AppendFormat("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1031{\\fonttbl {\\f0\\fnil\\fcharset%d Times New Roman;}}", 0 /*FIXME: a number for UTF-8 here*/);
sBuffer.Append(LineFeed);
// Scenario title

View File

@ -777,7 +777,7 @@ bool C4Group::OpenRealGrpFile()
if (!StdFile.Read((BYTE*)&corebuf,sizeof(C4GroupEntryCore))) return Error("OpenRealGrpFile: Error reading entries");
// New C4Groups have filenames in UTF-8
StdStrBuf entryname(corebuf.FileName);
if (pConfig->General.IsUTF8()) entryname.EnsureUnicode();
entryname.EnsureUnicode();
// Prevent overwriting of user stuff by malicuous groups
C4InVal::ValidateFilename(const_cast<char *>(entryname.getData()),entryname.getLength());
EntryOffset+=sizeof(C4GroupEntryCore);

View File

@ -42,7 +42,6 @@
#endif
#include <errno.h>
iconv_t C4Language::host_to_local = iconv_t(-1);
iconv_t C4Language::local_to_utf_8 = iconv_t(-1);
iconv_t C4Language::local_to_host = iconv_t(-1);
#endif
@ -147,8 +146,6 @@ void C4Language::Clear()
#ifdef HAVE_ICONV
if (local_to_host != iconv_t(-1))
{
if (local_to_host == local_to_utf_8)
local_to_utf_8 = iconv_t(-1);
iconv_close(local_to_host);
local_to_host = iconv_t(-1);
}
@ -157,12 +154,6 @@ void C4Language::Clear()
iconv_close(host_to_local);
host_to_local = iconv_t(-1);
}
if (local_to_utf_8 != iconv_t(-1))
{
iconv_close(local_to_utf_8);
local_to_utf_8 = iconv_t(-1);
}
#endif
}
@ -220,10 +211,6 @@ StdStrBuf C4Language::IconvClonk(const char * string)
{
return Iconv(string, host_to_local);
}
StdStrBuf C4Language::IconvUtf8(const char * string)
{
return Iconv(string, local_to_utf_8);
}
#else
StdStrBuf C4Language::IconvSystem(const char * string)
{
@ -383,16 +370,20 @@ void C4Language::LoadInfos(C4Group &hGroup)
// Load language string table
if (hGroup.LoadEntry(strEntry, &strTable, 0, 1))
{
if (!SEqual(GetResStr("IDS_LANG_CHARSET", strTable), "UTF-8"))
{
LogF("Translation %s is not in UTF-8, skipped", GetResStr("IDS_LANG_NAME", strTable));
continue;
}
// New language info
C4LanguageInfo *pInfo = new C4LanguageInfo;
// Get language code by entry name
SCopy(GetFilenameOnly(strEntry) + SLen(GetFilenameOnly(strEntry)) - 2, pInfo->Code, 2);
SCapitalize(pInfo->Code);
// Get language name, info, fallback from table
SCopy(GetResStr("IDS_LANG_NAME", (char*)strTable), pInfo->Name, C4MaxLanguageInfo);
SCopy(GetResStr("IDS_LANG_INFO", (char*)strTable), pInfo->Info, C4MaxLanguageInfo);
SCopy(GetResStr("IDS_LANG_FALLBACK", (char*)strTable), pInfo->Fallback, C4MaxLanguageInfo);
SCopy(GetResStr("IDS_LANG_CHARSET", (char*)strTable), pInfo->Charset, C4MaxLanguageInfo);
SCopy(GetResStr("IDS_LANG_NAME", strTable), pInfo->Name, C4MaxLanguageInfo);
SCopy(GetResStr("IDS_LANG_INFO", strTable), pInfo->Info, C4MaxLanguageInfo);
SCopy(GetResStr("IDS_LANG_FALLBACK", strTable), pInfo->Fallback, C4MaxLanguageInfo);
// Safety: pipe character is not allowed in any language info string
SReplaceChar(pInfo->Name, '|', ' ');
SReplaceChar(pInfo->Info, '|', ' ');
@ -483,22 +474,13 @@ bool C4Language::LoadStringTable(C4Group &hGroup, const char *strCode)
#ifdef HAVE_LANGINFO_H
const char * const to_set = nl_langinfo(CODESET);
if (local_to_host == iconv_t(-1))
local_to_host = iconv_open (to_set ? to_set : "ASCII",
GetCharsetCodeName(LoadResStr("IDS_LANG_CHARSET")));
local_to_host = iconv_open (to_set ? to_set : "ASCII", "UTF-8");
if (host_to_local == iconv_t(-1))
host_to_local = iconv_open (GetCharsetCodeName(LoadResStr("IDS_LANG_CHARSET")),
host_to_local = iconv_open ("UTF-8",
to_set ? to_set : "ASCII");
#else
const char * const to_set = "";
#endif
if (local_to_utf_8 == iconv_t(-1))
{
if (SEqual(to_set, "UTF-8"))
local_to_utf_8 = local_to_host;
else
local_to_utf_8 = iconv_open ("UTF-8",
GetCharsetCodeName(LoadResStr("IDS_LANG_CHARSET")));
}
#endif
// Success
return true;

View File

@ -206,15 +206,13 @@ void C4Network2RefServer::RespondReference(const C4NetIO::addr_t &addr)
// Pack
StdStrBuf PacketData = DecompileToBuf<StdCompilerINIWrite>(mkNamingPtrAdapt(pReference, "Reference"));
// Create header
const char *szCharset = GetCharsetCodeName(LoadResStr("IDS_LANG_CHARSET"));
StdStrBuf Header = FormatString(
"HTTP/1.1 200 Found\r\n"
"Content-Length: %d\r\n"
"Content-Type: text/plain; charset=%s\r\n"
"Content-Type: text/plain; charset=UTF-8\r\n"
"Server: " C4ENGINENAME "/" C4VERSION "\r\n"
"\r\n",
PacketData.getLength(),
szCharset);
PacketData.getLength());
// Send back
Send(C4NetIOPacket(Header, Header.getLength(), false, addr));
Send(C4NetIOPacket(PacketData, PacketData.getLength(), false, addr));

View File

@ -424,7 +424,7 @@ c4_list_get_value (GtkTreeModel * tree_model, GtkTreeIter * iter, gint column, G
g_value_init (value, G_TYPE_POINTER);
g_value_set_pointer(value, pObj);
// g_value_set_string(value, C4Language::IconvUtf8(pObj->GetName()).getData());
// g_value_set_string(value, pObj->GetName());
}
// Wrapper around g_object_new.
@ -695,7 +695,7 @@ static void name_cell_data_func(GtkTreeViewColumn* column, GtkCellRenderer* rend
{
C4Object* object = c4_list_iter_get_C4Object(model, iter);
g_object_set(G_OBJECT(renderer), "text", C4Language::IconvUtf8(object->GetName()).getData(), (gpointer)NULL);
g_object_set(G_OBJECT(renderer), "text", object->GetName(), (gpointer)NULL);
}
#define ICON_SIZE 24

View File

@ -151,7 +151,7 @@ BOOL C4PropertyDlg::Open()
gtk_widget_show_all(vbox);
C4DevmodeDlg::AddPage(vbox, GTK_WINDOW(Console.window), LoadResStrUtf8("IDS_DLG_PROPERTIES").getData());
C4DevmodeDlg::AddPage(vbox, GTK_WINDOW(Console.window), LoadResStr("IDS_DLG_PROPERTIES"));
g_signal_connect(G_OBJECT(entry), "activate", G_CALLBACK(OnScriptActivate), this);
@ -281,7 +281,7 @@ BOOL C4PropertyDlg::Update()
#else
#ifdef WITH_DEVELOPER_MODE
GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
gtk_text_buffer_set_text(buffer, C4Language::IconvUtf8(Output.getData()).getData(), -1);
gtk_text_buffer_set_text(buffer, Output.getData(), -1);
#endif
#endif
return TRUE;

View File

@ -310,7 +310,7 @@ StdStrBuf C4RTFFile::GetPlainText()
// cleanup
ClearState();
// FIXME: This is wrong, RTF contains charset information which should be used
if (Config.General.IsUTF8()) sResult.EnsureUnicode();
sResult.EnsureUnicode();
// return result
return sResult;
}

View File

@ -379,7 +379,7 @@ BOOL C4ToolsDlg::Open()
gtk_box_pack_start(GTK_BOX(local_hbox), vbox, TRUE, TRUE, 0); // ???
gtk_widget_show_all(hbox);
C4DevmodeDlg::AddPage(hbox, GTK_WINDOW(Console.window), LoadResStrUtf8("IDS_DLG_TOOLS").getData());
C4DevmodeDlg::AddPage(hbox, GTK_WINDOW(Console.window), LoadResStr("IDS_DLG_TOOLS"));
//g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(OnDestroy), this);
handlerDynamic = g_signal_connect(G_OBJECT(landscape_dynamic), "toggled", G_CALLBACK(OnButtonModeDynamic), this);
@ -877,7 +877,7 @@ void C4ToolsDlg::UpdateLandscapeModeCtrls()
g_signal_handler_unblock(landscape_static, handlerStatic);
g_signal_handler_unblock(landscape_exact, handlerExact);
C4DevmodeDlg::SetTitle(hbox, LoadResStrUtf8(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT").getData());
C4DevmodeDlg::SetTitle(hbox, LoadResStr(iMode==C4LSC_Dynamic ? "IDS_DLG_DYNAMIC" : iMode==C4LSC_Static ? "IDS_DLG_STATIC" : "IDS_DLG_EXACT"));
#endif
#endif
}

View File

@ -44,7 +44,6 @@
#define FW_MEDIUM 500
#define FW_SEMIBOLD 600
#define FW_BOLD 700
#define DEFAULT_CHARSET 1
#endif
class CMarkup;
@ -80,8 +79,6 @@ class CStdFont
int iSfcSizes; // size for font surfaces
int iFontZoom; // zoom of font in texture
bool fUTF8; // if set, UTF8-characters are decoded
CSurface *sfcCurrent; // current surface font data can be written to at runtime
int32_t iCurrentSfcX, iCurrentSfcY; // current character rendering position
@ -112,12 +109,12 @@ class CStdFont
inline uint32_t GetNextCharacter(const char **pszString)
{
unsigned char c=**pszString;
if (!fUTF8 || c<128) { ++*pszString; return c; } else return GetNextUTF8Character(pszString);
if (c<128) { ++*pszString; return c; } else return GetNextUTF8Character(pszString);
}
uint32_t GetNextUTF8Character(const char **pszString);
CFacet &GetCharacterFacet(uint32_t c)
{
if (!fUTF8 || c<128) return fctAsciiTexCoords[c-' ']; else return GetUnicodeCharacterFacet(c);
if (c<128) return fctAsciiTexCoords[c-' ']; else return GetUnicodeCharacterFacet(c);
}
CFacet &GetUnicodeCharacterFacet(uint32_t c);
@ -144,7 +141,7 @@ class CStdFont
// function throws std::runtime_error in case of failure
// font initialization - writes the surface data
void Init(CStdVectorFont & VectorFont, DWORD dwHeight, DWORD dwFontWeight=FW_NORMAL, const char * szCharset="", bool fDoShadow=true);
void Init(CStdVectorFont & VectorFont, DWORD dwHeight, DWORD dwFontWeight=FW_NORMAL, bool fDoShadow=true);
// font initialization - grabs the given surface data and extracts character sizes from it
void Init(const char *szFontName, CSurface *psfcFontSfc, int iIndent);

View File

@ -28,24 +28,19 @@
#include <StdMarkup.h>
#include <stdexcept>
#include <string>
/*
#ifdef _WIN32
#include <tchar.h>
#include <stdio.h>
#else
#define _T(x) x
#endif // _WIN32
*/
#ifdef HAVE_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#endif // HAVE_FREETYPE
#ifdef HAVE_ICONV
#include <iconv.h>
#endif // HAVE_ICONV
/* Initialization */
#ifdef HAVE_FREETYPE
@ -139,7 +134,6 @@ CStdFont::CStdFont()
iGfxLineHgt=iLineHgt+1;
dwWeight=FW_NORMAL;
fDoShadow=false;
fUTF8 = false;
// font not yet initialized
*szFontName=0;
id=0;
@ -372,7 +366,7 @@ CFacet &CStdFont::GetUnicodeCharacterFacet(uint32_t c)
return rFacet;
}
void CStdFont::Init(CStdVectorFont & VectorFont, DWORD dwHeight, DWORD dwFontWeight, const char * szCharset, bool fDoShadow)
void CStdFont::Init(CStdVectorFont & VectorFont, DWORD dwHeight, DWORD dwFontWeight, bool fDoShadow)
{
// clear previous
Clear();
@ -380,7 +374,6 @@ void CStdFont::Init(CStdVectorFont & VectorFont, DWORD dwHeight, DWORD dwFontWei
iHSpace=fDoShadow ? -1 : 0; // horizontal shadow
dwWeight=dwFontWeight;
this->fDoShadow = fDoShadow;
if (SEqual(szCharset, "UTF-8")) fUTF8 = true;
// determine needed texture size
if (dwHeight * iFontZoom > 40)
iSfcSizes = 512;
@ -467,67 +460,10 @@ void CStdFont::Init(CStdVectorFont & VectorFont, DWORD dwHeight, DWORD dwFontWei
// in case of UTF8, unicode characters will be created on the fly and extended ASCII characters (128-255) are not needed
// now render all characters!
#if defined HAVE_ICONV
// Initialize iconv
struct iconv_t_wrapper {
iconv_t i;
iconv_t_wrapper (const char * to, const char * from) {
i = iconv_open(to, from);
if (i == iconv_t(-1))
throw std::runtime_error(std::string("Cannot open iconv (") + to + ", " + from + ")");
}
~iconv_t_wrapper () { iconv_close (i); }
operator iconv_t () { return i; }
};
#ifdef __BIG_ENDIAN__
iconv_t_wrapper iconv_handle("UCS-4BE",GetCharsetCodeName(szCharset));
#else
iconv_t_wrapper iconv_handle("UCS-4LE",GetCharsetCodeName(szCharset));
#endif
#elif defined (_WIN32)
int32_t iCodePage = GetCharsetCodePage(szCharset);
#endif
int cMax = fUTF8 ? 127 : 255;
int cMax = 127;
for (int c=' '; c <= cMax; ++c)
{
uint32_t dwChar = c;
#if defined HAVE_ICONV
// convert from whatever legacy encoding in use to unicode
if (!fUTF8)
{
// Convert to unicode
char chr = dwChar;
char * in = &chr;
char * out = reinterpret_cast<char *>(&dwChar);
size_t insize = 1;
size_t outsize = 4;
iconv(iconv_handle, const_cast<ICONV_CONST char * * >(&in), &insize, &out, &outsize);
}
#elif defined (_WIN32)
// convert using Win32 API
if (!fUTF8 && c>=128)
{
char cc[2] = { char(c), '\0' };
wchar_t outbuf[4];
if (MultiByteToWideChar(iCodePage, 0, cc, -1, outbuf, 4)) // 2do: Convert using proper codepage
{
// now convert from UTF-16 to UCS-4
if (((outbuf[0] & 0xfc00) == 0xd800) && ((outbuf[1] & 0xfc00) == 0xdc00))
{
dwChar = 0x10000 + (((outbuf[0] & 0x3ff) << 10) | (outbuf[1] & 0x3ff));
}
else
dwChar = outbuf[0];
}
else
{
// conversion error. Shouldn't be fatal; just pretend it were a Unicode character
}
}
#else
// no conversion available? Just break for non-iso8859-1.
#endif // defined HAVE_ICONV
if (!AddRenderedChar(dwChar, &(fctAsciiTexCoords[c-' '])))
if (!AddRenderedChar(c, &(fctAsciiTexCoords[c-' '])))
{
Clear();
throw std::runtime_error(std::string("Cannot render characters for Font (") + szFontName + ")");
@ -663,7 +599,6 @@ void CStdFont::Clear()
dwWeight=FW_NORMAL;
fDoShadow=false;
fPrerenderedFont = false;
fUTF8 = false;
// font not yet initialized
*szFontName=0;
id=0;
@ -692,9 +627,9 @@ bool CStdFont::GetTextExtent(const char *szText, int32_t &rsx, int32_t &rsy, boo
// done? (must check here, because markup-skip may have led to text end)
if (!c) break;
// line break?
if( c == _T('\n') || (fCheckMarkup && c == _T('|'))) { iRowWdt=0; iHgt+=iLineHgt; continue; }
if(c == '\n' || (fCheckMarkup && c == '|')) { iRowWdt=0; iHgt+=iLineHgt; continue; }
// ignore system characters
if( c < _T(' ') ) continue;
if(c < ' ') continue;
// image?
int iImgLgt;
if (fCheckMarkup && c=='{' && szText[0]=='{' && szText[1]!='{' && (iImgLgt=SCharPos('}', szText+1))>0 && szText[iImgLgt+2]=='}')
@ -1127,7 +1062,7 @@ void CStdFont::DrawText(SURFACE sfcDest, float iX, float iY, DWORD dwColor, cons
while (c = GetNextCharacter(&szText))
{
// ignore system characters
if (c < _T(' ')) continue;
if (c < ' ') continue;
// apply markup
if (c=='<' && (~dwFlags & STDFONT_NOMARKUP))
{

View File

@ -166,15 +166,6 @@ char *GetResStr(const char *id, const char *strTable)
if ((pos = SSearch(strTable, idExt)))
// Get string until end of line
SCopyUntil(pos, strResult, "\r\n", ResStrMaxLen);
#ifdef _DEBUG
#ifdef _MSC_VER
if (SEqual2(strResult, "[Undefined:"))
if (!SEqual(id, "IDS_LANG_CHARSET"))
{
/* __asm int 3 */
}
#endif
#endif
// Return string
return strResult;
}