Added support for Hebrew (and, more generally, RTL languages). fribidi must be available and ENABLE_BIDI must be defined (however the autotools build system currently does not check for fribidi presence so if you build with autotools it will always be off)
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5457 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
4917872611
commit
a2825c4b36
BIN
data/fonts/Rahel.png
Normal file
BIN
data/fonts/Rahel.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
@ -12,6 +12,7 @@
|
||||
#include <iostream>
|
||||
#include "guiengine/engine.hpp"
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/translation.hpp"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
@ -27,7 +28,8 @@ ScalableFont::ScalableFont(IGUIEnvironment *env, const io::path& filename)
|
||||
m_fallback_font_scale = 1.0f;
|
||||
m_fallback_kerning_width = 0;
|
||||
m_is_hollow_copy = false;
|
||||
|
||||
m_rtl = translations->isRTLLanguage();
|
||||
|
||||
m_black_border = false;
|
||||
|
||||
#ifdef _DEBUG
|
||||
@ -107,7 +109,7 @@ bool ScalableFont::load(io::IXMLReader* xml)
|
||||
|
||||
TextureInfo info;
|
||||
info.m_file_name = fn;
|
||||
info.m_has_alpha = (alpha == core::stringw("false"));
|
||||
info.m_has_alpha = (alpha == core::stringw("true"));
|
||||
info.m_scale = scale;
|
||||
|
||||
// disable mipmaps+filtering
|
||||
@ -197,7 +199,8 @@ bool ScalableFont::load(io::IXMLReader* xml)
|
||||
rectangle.LowerRightCorner.Y = val;
|
||||
|
||||
CharacterMap[ch] = Areas.size();
|
||||
//std::cout << "Inserting character '" << ch << "' with area " << Areas.size() << std::endl;
|
||||
|
||||
//std::cout << "Inserting character '" << (int)ch << "' with area " << Areas.size() << std::endl;
|
||||
|
||||
// make frame
|
||||
f.rectNumber = SpriteBank->getPositions().size();
|
||||
@ -252,24 +255,27 @@ void ScalableFont::setMaxHeight()
|
||||
|
||||
|
||||
//! loads a font file, native file needed, for texture parsing
|
||||
/*
|
||||
bool ScalableFont::load(io::IReadFile* file)
|
||||
{
|
||||
if (!Driver) return false;
|
||||
|
||||
return loadTexture(Driver->createImageFromFile(file), file->getFileName());
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//! loads a font file, native file needed, for texture parsing
|
||||
/*
|
||||
bool ScalableFont::load(const io::path& filename)
|
||||
{
|
||||
if (!Driver) return false;
|
||||
|
||||
return loadTexture(Driver->createImageFromFile( filename ), filename);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//! load & prepare font from ITexture
|
||||
#if 0
|
||||
bool ScalableFont::loadTexture(video::IImage* image, const io::path& name)
|
||||
{
|
||||
if (!image) return false;
|
||||
@ -313,7 +319,7 @@ bool ScalableFont::loadTexture(video::IImage* image, const io::path& name)
|
||||
flag[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS );
|
||||
|
||||
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true);
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false );
|
||||
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true );
|
||||
|
||||
SpriteBank->addTexture(Driver->addTexture(name, tmpImage));
|
||||
|
||||
@ -328,9 +334,10 @@ bool ScalableFont::loadTexture(video::IImage* image, const io::path& name)
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void ScalableFont::readPositions(video::IImage* image, s32& lowerRightPositions)
|
||||
/*
|
||||
void ScalableFont::readPositions(video::IImage* image, s32& spriteID)
|
||||
{
|
||||
const core::dimension2d<u32> size = image->getDimension();
|
||||
|
||||
@ -360,17 +367,17 @@ void ScalableFont::readPositions(video::IImage* image, s32& lowerRightPositions)
|
||||
if (c == colorLowerRight)
|
||||
{
|
||||
// too many lower right points
|
||||
if (SpriteBank->getPositions().size()<=(u32)lowerRightPositions)
|
||||
if (SpriteBank->getPositions().size()<=(u32)spriteID)
|
||||
{
|
||||
lowerRightPositions = 0;
|
||||
spriteID = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
image->setPixel(pos.X, pos.Y, colorBackGroundTransparent);
|
||||
SpriteBank->getPositions()[lowerRightPositions].LowerRightCorner = pos;
|
||||
SpriteBank->getPositions()[spriteID].LowerRightCorner = pos;
|
||||
// add frame to sprite bank
|
||||
SGUISpriteFrame f;
|
||||
f.rectNumber = lowerRightPositions;
|
||||
f.rectNumber = spriteID;
|
||||
f.textureNumber = 0;
|
||||
SGUISprite s;
|
||||
s.Frames.push_back(f);
|
||||
@ -380,14 +387,14 @@ void ScalableFont::readPositions(video::IImage* image, s32& lowerRightPositions)
|
||||
SFontArea a;
|
||||
a.overhang = 0;
|
||||
a.underhang = 0;
|
||||
a.spriteno = lowerRightPositions;
|
||||
a.width = SpriteBank->getPositions()[lowerRightPositions].getWidth();
|
||||
a.spriteno = spriteID;
|
||||
a.width = SpriteBank->getPositions()[spriteID].getWidth();
|
||||
Areas.push_back(a);
|
||||
// map letter to character
|
||||
wchar_t ch = (wchar_t)(lowerRightPositions + 32);
|
||||
CharacterMap[ch] = lowerRightPositions;
|
||||
wchar_t ch = (wchar_t)(spriteID + 32);
|
||||
CharacterMap[ch] = spriteID;
|
||||
|
||||
++lowerRightPositions;
|
||||
++spriteID;
|
||||
}
|
||||
else
|
||||
if (c == colorBackGround)
|
||||
@ -395,7 +402,7 @@ void ScalableFont::readPositions(video::IImage* image, s32& lowerRightPositions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//! set an Pixel Offset on Drawing ( scale position on width )
|
||||
void ScalableFont::setKerningWidth(s32 kerning)
|
||||
@ -460,7 +467,7 @@ s32 ScalableFont::getAreaFromCharacter(const wchar_t c, bool* fallback_font) con
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::wcout << L"This font does not have this character : <" << c << L">" << std::endl;
|
||||
std::cout << "The font does not have this character : <" << (int)c << L">" << std::endl;
|
||||
if (fallback_font != NULL) *fallback_font = false;
|
||||
return WrongCharacter;
|
||||
}
|
||||
@ -556,12 +563,16 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
|
||||
core::dimension2d<s32> textDimension;
|
||||
core::position2d<s32> offset = position.UpperLeftCorner;
|
||||
|
||||
if (hcenter || vcenter || clip) textDimension = getDimension(text.c_str());
|
||||
if (m_rtl || hcenter || vcenter || clip) textDimension = getDimension(text.c_str());
|
||||
|
||||
if (hcenter)
|
||||
{
|
||||
offset.X += (position.getWidth() - textDimension.Width) / 2;
|
||||
}
|
||||
else if (m_rtl)
|
||||
{
|
||||
offset.X += (position.getWidth() - textDimension.Width);
|
||||
}
|
||||
|
||||
if (vcenter)
|
||||
{
|
||||
@ -776,12 +787,27 @@ void ScalableFont::draw(const core::stringw& text, const core::rect<s32>& positi
|
||||
title_colors, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
driver->draw2DImage(texture,
|
||||
dest,
|
||||
source,
|
||||
clip,
|
||||
colors, true);
|
||||
|
||||
#ifdef FONT_DEBUG
|
||||
driver->draw2DLine(core::position2d<s32>(dest.UpperLeftCorner.X, dest.UpperLeftCorner.Y),
|
||||
core::position2d<s32>(dest.UpperLeftCorner.X, dest.LowerRightCorner.Y),
|
||||
video::SColor(255, 255,0,0));
|
||||
driver->draw2DLine(core::position2d<s32>(dest.LowerRightCorner.X, dest.LowerRightCorner.Y),
|
||||
core::position2d<s32>(dest.LowerRightCorner.X, dest.UpperLeftCorner.Y),
|
||||
video::SColor(255, 255,0,0));
|
||||
driver->draw2DLine(core::position2d<s32>(dest.LowerRightCorner.X, dest.LowerRightCorner.Y),
|
||||
core::position2d<s32>(dest.UpperLeftCorner.X, dest.LowerRightCorner.Y),
|
||||
video::SColor(255, 255,0,0));
|
||||
driver->draw2DLine(core::position2d<s32>(dest.UpperLeftCorner.X, dest.UpperLeftCorner.Y),
|
||||
core::position2d<s32>(dest.LowerRightCorner.X, dest.UpperLeftCorner.Y),
|
||||
video::SColor(255, 255,0,0));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ class ScalableFont : public IGUIFontBitmap
|
||||
void lazyLoadTexture(int texID);
|
||||
|
||||
bool m_is_hollow_copy;
|
||||
bool m_rtl;
|
||||
public:
|
||||
|
||||
bool m_black_border;
|
||||
@ -84,10 +85,10 @@ public:
|
||||
virtual ~ScalableFont();
|
||||
|
||||
//! loads a font from a texture file
|
||||
bool load(const io::path& filename);
|
||||
//bool load(const io::path& filename);
|
||||
|
||||
//! loads a font from a texture file
|
||||
bool load(io::IReadFile* file);
|
||||
//bool load(io::IReadFile* file);
|
||||
|
||||
//! loads a font from an XML file
|
||||
bool load(io::IXMLReader* xml);
|
||||
@ -141,9 +142,9 @@ private:
|
||||
int getCharWidth(const SFontArea& area, const bool fallback) const;
|
||||
|
||||
//! load & prepare font from ITexture
|
||||
bool loadTexture(video::IImage * image, const io::path& name);
|
||||
//bool loadTexture(video::IImage * image, const io::path& name);
|
||||
|
||||
void readPositions(video::IImage* texture, s32& lowerRightPositions);
|
||||
//void readPositions(video::IImage* texture, s32& lowerRightPositions);
|
||||
|
||||
s32 getAreaFromCharacter (const wchar_t c, bool* fallback_font) const;
|
||||
void setMaxHeight();
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Xcode build configuration
|
||||
|
||||
HEADER_SEARCH_PATHS = /usr/local/include /usr/include /usr/local/include/irrlicht/ $(PROJECT_DIR)/../../ $(PROJECT_DIR)/../../bullet/src $(PROJECT_DIR)/../../enet/include
|
||||
HEADER_SEARCH_PATHS = /usr/local/include /usr/include /usr/local/include/irrlicht/ $(PROJECT_DIR)/../../ $(PROJECT_DIR)/../../bullet/src $(PROJECT_DIR)/../../enet/include /Library/Frameworks/fribidi.framework/Headers
|
||||
|
||||
OTHER_CFLAGS = -Wall -DHAVE_OGGVORBIS=1 -DHAS_SOCKLEN_T -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAS_POLL=1 -DHAS_FCNTL=1 -DHAS_INET_PTON=1 -DHAS_INET_NTOP=1 -DHAS_MSGHDR_FLAGS=1 -DENABLE_NLS=1 -DHAVE_GETTEXT=1 -DHAVE_GLUT=1 -DHAVE_IRRLICHT=1 -DPACKAGE="\"supertuxkart\"" -D__MACOSX__=1 -DHAVE_RTT=1
|
||||
OTHER_CFLAGS = -Wall -DHAVE_OGGVORBIS=1 -DHAS_SOCKLEN_T -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAS_POLL=1 -DHAS_FCNTL=1 -DHAS_INET_PTON=1 -DHAS_INET_NTOP=1 -DHAS_MSGHDR_FLAGS=1 -DENABLE_NLS=1 -DHAVE_GETTEXT=1 -DHAVE_GLUT=1 -DHAVE_IRRLICHT=1 -DPACKAGE="\"supertuxkart\"" -D__MACOSX__=1 -DHAVE_RTT=1 -DENABLE_BIDI=1
|
||||
|
||||
OTHER_LDFLAGS = -lirrlicht -lintl
|
||||
LIBRARY_SEARCH_PATHS = /usr/local/lib /usr/lib
|
||||
|
@ -47,6 +47,7 @@
|
||||
953789820FC7831400DD1F8E /* quad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 953789810FC7831400DD1F8E /* quad.cpp */; };
|
||||
953C3CCA10CAF3EE0025F78A /* CGUIFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 953C3CC910CAF3EE0025F78A /* CGUIFont.cpp */; };
|
||||
95453ACA11808B8700A155B9 /* emergency_animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95453AC811808B8700A155B9 /* emergency_animation.cpp */; };
|
||||
954E486A11B19C4100B1DF63 /* fribidi.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 954E486911B19C4100B1DF63 /* fribidi.framework */; };
|
||||
954E4C2D0FF98B6F0047FE3E /* animation_base.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 954E4C250FF98B6E0047FE3E /* animation_base.cpp */; };
|
||||
954E4C2E0FF98B6F0047FE3E /* animation_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 954E4C270FF98B6E0047FE3E /* animation_manager.cpp */; };
|
||||
954E4C2F0FF98B6F0047FE3E /* billboard_animation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 954E4C290FF98B6E0047FE3E /* billboard_animation.cpp */; };
|
||||
@ -257,11 +258,12 @@
|
||||
95833240101243ED00C5137E /* player_info_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95833239101243ED00C5137E /* player_info_dialog.cpp */; };
|
||||
95833241101243ED00C5137E /* press_a_key_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9583323B101243ED00C5137E /* press_a_key_dialog.cpp */; };
|
||||
95833242101243ED00C5137E /* track_info_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9583323D101243ED00C5137E /* track_info_dialog.cpp */; };
|
||||
9586318411B1EC9F00B8B4AF /* grand_prix_lose.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9586318011B1EC9F00B8B4AF /* grand_prix_lose.cpp */; };
|
||||
9586318511B1EC9F00B8B4AF /* grand_prix_win.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9586318211B1EC9F00B8B4AF /* grand_prix_win.cpp */; };
|
||||
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 958BD76E117F6AE90095B483 /* music_manager.cpp */; };
|
||||
958D8C54104F523000A81934 /* race_paused_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 958D8C53104F523000A81934 /* race_paused_dialog.cpp */; };
|
||||
959482D310EBC0790031BADF /* track_object_manager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959482CF10EBC0790031BADF /* track_object_manager.cpp */; };
|
||||
959482D410EBC0790031BADF /* track_object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959482D110EBC0790031BADF /* track_object.cpp */; };
|
||||
959D42FD1130C4F2005077E2 /* grand_prix_over.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 959D42FB1130C4F2005077E2 /* grand_prix_over.cpp */; };
|
||||
95B5CD14102DE08F00EF2001 /* device_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95B5CD13102DE08F00EF2001 /* device_config.cpp */; };
|
||||
95C77D631069589B0080838E /* ambient_light_sphere.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95C77D621069589B0080838E /* ambient_light_sphere.cpp */; };
|
||||
95C77D66106958A50080838E /* check_line.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 95C77D65106958A50080838E /* check_line.cpp */; };
|
||||
@ -393,6 +395,7 @@
|
||||
9540E2570FD5F8FD002985B8 /* no_copy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = no_copy.hpp; path = ../../utils/no_copy.hpp; sourceTree = SOURCE_ROOT; };
|
||||
95453AC811808B8700A155B9 /* emergency_animation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = emergency_animation.cpp; path = ../../karts/emergency_animation.cpp; sourceTree = SOURCE_ROOT; };
|
||||
95453AC911808B8700A155B9 /* emergency_animation.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = emergency_animation.hpp; path = ../../karts/emergency_animation.hpp; sourceTree = SOURCE_ROOT; };
|
||||
954E486911B19C4100B1DF63 /* fribidi.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = fribidi.framework; path = /Library/Frameworks/fribidi.framework; sourceTree = "<absolute>"; };
|
||||
954E4C250FF98B6E0047FE3E /* animation_base.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = animation_base.cpp; path = ../../animations/animation_base.cpp; sourceTree = SOURCE_ROOT; };
|
||||
954E4C260FF98B6E0047FE3E /* animation_base.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = animation_base.hpp; path = ../../animations/animation_base.hpp; sourceTree = SOURCE_ROOT; };
|
||||
954E4C270FF98B6E0047FE3E /* animation_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = animation_manager.cpp; path = ../../animations/animation_manager.cpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -473,6 +476,10 @@
|
||||
9583323C101243ED00C5137E /* press_a_key_dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = press_a_key_dialog.hpp; path = ../../states_screens/dialogs/press_a_key_dialog.hpp; sourceTree = SOURCE_ROOT; };
|
||||
9583323D101243ED00C5137E /* track_info_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = track_info_dialog.cpp; path = ../../states_screens/dialogs/track_info_dialog.cpp; sourceTree = SOURCE_ROOT; };
|
||||
9583323E101243ED00C5137E /* track_info_dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = track_info_dialog.hpp; path = ../../states_screens/dialogs/track_info_dialog.hpp; sourceTree = SOURCE_ROOT; };
|
||||
9586318011B1EC9F00B8B4AF /* grand_prix_lose.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = grand_prix_lose.cpp; path = ../../states_screens/grand_prix_lose.cpp; sourceTree = SOURCE_ROOT; };
|
||||
9586318111B1EC9F00B8B4AF /* grand_prix_lose.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = grand_prix_lose.hpp; path = ../../states_screens/grand_prix_lose.hpp; sourceTree = SOURCE_ROOT; };
|
||||
9586318211B1EC9F00B8B4AF /* grand_prix_win.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = grand_prix_win.cpp; path = ../../states_screens/grand_prix_win.cpp; sourceTree = SOURCE_ROOT; };
|
||||
9586318311B1EC9F00B8B4AF /* grand_prix_win.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = grand_prix_win.hpp; path = ../../states_screens/grand_prix_win.hpp; sourceTree = SOURCE_ROOT; };
|
||||
958BD76E117F6AE90095B483 /* music_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = music_manager.cpp; path = ../../audio/music_manager.cpp; sourceTree = SOURCE_ROOT; };
|
||||
958BD76F117F6AE90095B483 /* music_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = music_manager.hpp; path = ../../audio/music_manager.hpp; sourceTree = SOURCE_ROOT; };
|
||||
958D8C52104F523000A81934 /* race_paused_dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = race_paused_dialog.hpp; path = ../../states_screens/dialogs/race_paused_dialog.hpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -481,8 +488,6 @@
|
||||
959482D010EBC0790031BADF /* track_object_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = track_object_manager.hpp; path = ../../tracks/track_object_manager.hpp; sourceTree = SOURCE_ROOT; };
|
||||
959482D110EBC0790031BADF /* track_object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = track_object.cpp; path = ../../tracks/track_object.cpp; sourceTree = SOURCE_ROOT; };
|
||||
959482D210EBC0790031BADF /* track_object.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = track_object.hpp; path = ../../tracks/track_object.hpp; sourceTree = SOURCE_ROOT; };
|
||||
959D42FB1130C4F2005077E2 /* grand_prix_over.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = grand_prix_over.cpp; path = ../../states_screens/grand_prix_over.cpp; sourceTree = SOURCE_ROOT; };
|
||||
959D42FC1130C4F2005077E2 /* grand_prix_over.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = grand_prix_over.hpp; path = ../../states_screens/grand_prix_over.hpp; sourceTree = SOURCE_ROOT; };
|
||||
95A118290F77EA3100B18B3D /* input.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = input.hpp; path = ../../input/input.hpp; sourceTree = SOURCE_ROOT; };
|
||||
95A1182A0F77EA3100B18B3D /* input_manager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = input_manager.cpp; path = ../../input/input_manager.cpp; sourceTree = SOURCE_ROOT; };
|
||||
95A1182B0F77EA3100B18B3D /* input_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = input_manager.hpp; path = ../../input/input_manager.hpp; sourceTree = SOURCE_ROOT; };
|
||||
@ -1082,6 +1087,7 @@
|
||||
9551C9F10FC1B7EE00DB481B /* Ogg.framework in Frameworks */,
|
||||
9551C9F20FC1B7EE00DB481B /* OpenAL.framework in Frameworks */,
|
||||
9551C9F30FC1B7EE00DB481B /* Vorbis.framework in Frameworks */,
|
||||
954E486A11B19C4100B1DF63 /* fribidi.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1114,6 +1120,7 @@
|
||||
9513B40E0F0EDE80005D29F6 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
954E486911B19C4100B1DF63 /* fribidi.framework */,
|
||||
9551CBD90FC1BB9200DB481B /* AGL.framework */,
|
||||
9551C7F90FC1B63C00DB481B /* Ogg.framework */,
|
||||
9551C7FA0FC1B63C00DB481B /* OpenAL.framework */,
|
||||
@ -1265,8 +1272,10 @@
|
||||
958330C310122B4A00C5137E /* credits.hpp */,
|
||||
95D2343E1078227A00625256 /* feature_unlocked.cpp */,
|
||||
95D2343D1078227A00625256 /* feature_unlocked.hpp */,
|
||||
959D42FB1130C4F2005077E2 /* grand_prix_over.cpp */,
|
||||
959D42FC1130C4F2005077E2 /* grand_prix_over.hpp */,
|
||||
9586318011B1EC9F00B8B4AF /* grand_prix_lose.cpp */,
|
||||
9586318111B1EC9F00B8B4AF /* grand_prix_lose.hpp */,
|
||||
9586318211B1EC9F00B8B4AF /* grand_prix_win.cpp */,
|
||||
9586318311B1EC9F00B8B4AF /* grand_prix_win.hpp */,
|
||||
9522F1DE10795E8A0067ECF5 /* help_screen_1.cpp */,
|
||||
9522F1DF10795E8A0067ECF5 /* help_screen_1.hpp */,
|
||||
9522F1E210795EFF0067ECF5 /* help_screen_2.cpp */,
|
||||
@ -2540,7 +2549,6 @@
|
||||
956C6ED51128D3FB004336C8 /* end_controller.cpp in Sources */,
|
||||
956C6ED61128D3FB004336C8 /* new_ai_controller.cpp in Sources */,
|
||||
956C6ED71128D3FB004336C8 /* player_controller.cpp in Sources */,
|
||||
959D42FD1130C4F2005077E2 /* grand_prix_over.cpp in Sources */,
|
||||
956830E01132EC9E00088D14 /* irr_debug_drawer.cpp in Sources */,
|
||||
957ED4801163FF18002AB42C /* ai_base_controller.cpp in Sources */,
|
||||
958BD770117F6AE90095B483 /* music_manager.cpp in Sources */,
|
||||
@ -2549,6 +2557,8 @@
|
||||
950D45D1118E040E006CFC41 /* options_screen_input2.cpp in Sources */,
|
||||
9556A880119EF976009C558F /* options_screen_audio.cpp in Sources */,
|
||||
9556A881119EF976009C558F /* options_screen_video.cpp in Sources */,
|
||||
9586318411B1EC9F00B8B4AF /* grand_prix_lose.cpp in Sources */,
|
||||
9586318511B1EC9F00B8B4AF /* grand_prix_win.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -39,6 +39,10 @@
|
||||
#include "io/file_manager.hpp"
|
||||
#include "utils/constants.hpp"
|
||||
|
||||
#if ENABLE_BIDI
|
||||
#include <fribidi.h>
|
||||
#endif
|
||||
|
||||
// set to 1 to debug i18n
|
||||
#define TRANSLATE_VERBOSE 0
|
||||
|
||||
@ -49,6 +53,7 @@ bool remove_bom = false;
|
||||
Translations::Translations()
|
||||
{
|
||||
#ifdef ENABLE_NLS
|
||||
|
||||
// LC_ALL does not work, sscanf will then not always be able
|
||||
// to scan for example: s=-1.1,-2.3,-3.3 correctly, which is
|
||||
// used in driveline files.
|
||||
@ -58,7 +63,45 @@ Translations::Translations()
|
||||
#else
|
||||
setlocale(LC_MESSAGES, "");
|
||||
#endif
|
||||
|
||||
// FIXME: I couldn't find a way to ask gettext what language it currently uses xD that's the closest I found
|
||||
const char* language = getenv("LANGUAGE");
|
||||
const char* lc_all = getenv("LC_ALL");
|
||||
const char* lc_type = getenv("LC_CTYPE");
|
||||
const char* lc_msg = getenv("LC_MESSAGES");
|
||||
const char* lang = getenv("LANG");
|
||||
|
||||
const char* firstNonNull = NULL;
|
||||
if (language != NULL) firstNonNull = language;
|
||||
else if (lc_all != NULL) firstNonNull = lc_all;
|
||||
else if (lc_type != NULL) firstNonNull = lc_type;
|
||||
else if (lc_msg != NULL) firstNonNull = lc_msg;
|
||||
else if (lang != NULL) firstNonNull = lang;
|
||||
|
||||
if (firstNonNull != NULL)
|
||||
{
|
||||
if (strcmp(firstNonNull, "he") == 0 || strcmp(firstNonNull, "yi") == 0)
|
||||
{
|
||||
// Hebrew
|
||||
m_rtl = true;
|
||||
}
|
||||
else if (strcmp(firstNonNull, "ar") == 0 || strcmp(firstNonNull, "az") == 0)
|
||||
{
|
||||
// Arabic
|
||||
m_rtl = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rtl = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rtl = false;
|
||||
}
|
||||
|
||||
bindtextdomain (PACKAGE, file_manager->getTranslationDir().c_str());
|
||||
|
||||
if (sizeof(wchar_t) == 4)
|
||||
{
|
||||
// FIXME: will probably not work on PPC maccs
|
||||
@ -131,9 +174,73 @@ const wchar_t* Translations::w_gettext(const char* original)
|
||||
|
||||
wchar_t* out_ptr = (wchar_t*)original_t;
|
||||
if (remove_bom) out_ptr++;
|
||||
|
||||
#if TRANSLATE_VERBOSE
|
||||
std::wcout << L" translation : " << out_ptr << std::endl;
|
||||
#endif
|
||||
return out_ptr;
|
||||
|
||||
|
||||
#if ENABLE_BIDI
|
||||
|
||||
const int FRIBIDI_BUFFER_SIZE = 512;
|
||||
FriBidiChar fribidiInput[FRIBIDI_BUFFER_SIZE];
|
||||
|
||||
int len = 0;
|
||||
int n = 0;
|
||||
//std::cout << "fribidi input : ";
|
||||
for (n = 0; ; n++)
|
||||
{
|
||||
fribidiInput[n] = out_ptr[n];
|
||||
//std::cout << (int)fribidiInput[n] << " ";
|
||||
len++;
|
||||
|
||||
if (n == FRIBIDI_BUFFER_SIZE-1) // prevent buffeoverflows
|
||||
{
|
||||
std::cerr << "WARNING : translated stirng too long, truncating!\n";
|
||||
fribidiInput[n] = 0;
|
||||
break;
|
||||
}
|
||||
if (fribidiInput[n] == 0) break; // stop on '\0'
|
||||
}
|
||||
//std::cout << " (len=" << len << ")\n";
|
||||
|
||||
FriBidiCharType pbase_dir = FRIBIDI_TYPE_ON; //FIXME: what's that?
|
||||
|
||||
static FriBidiChar fribidiOutput[FRIBIDI_BUFFER_SIZE];
|
||||
|
||||
fribidi_boolean result = fribidi_log2vis(fribidiInput,
|
||||
len-1,
|
||||
&pbase_dir,
|
||||
fribidiOutput,
|
||||
/* gint *position_L_to_V_list */ NULL,
|
||||
/* gint *position_V_to_L_list */ NULL,
|
||||
/* gint8 *embedding_level_list */ NULL
|
||||
);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
std::cerr << "Fribidi failed in 'fribidi_log2vis' =(\n";
|
||||
}
|
||||
|
||||
//std::cout << "fribidi output : ";
|
||||
//for (FriBidiChar* c=fribidiOutput; *c != 0; c++)
|
||||
//{
|
||||
// std::cout << (int)fribidiOutput[n] << " ";
|
||||
//}
|
||||
//std::cout << "\n";
|
||||
|
||||
|
||||
return (const wchar_t*)fribidiOutput;
|
||||
|
||||
#else
|
||||
|
||||
return out_ptr;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Translations::isRTLLanguage() const
|
||||
{
|
||||
return m_rtl;
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,11 @@ class Translations
|
||||
{
|
||||
private:
|
||||
irr::core::stringw m_converted_string;
|
||||
bool m_rtl;
|
||||
public:
|
||||
Translations();
|
||||
const wchar_t *w_gettext(const char* original);
|
||||
bool isRTLLanguage() const;
|
||||
}; // Translations
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user