Merge remote-tracking branch 'Flakebi/fribidi-text'

This commit is contained in:
Marianne Gagnon 2015-03-29 20:06:21 -04:00
commit 2d2624f71c
15 changed files with 82 additions and 70 deletions

View File

@ -200,7 +200,7 @@ void Achievement::check()
{ {
//show achievement //show achievement
core::stringw s = _("Completed achievement \"%s\".", core::stringw s = _("Completed achievement \"%s\".",
m_achievement_info->getName().c_str()); m_achievement_info->getName());
MessageQueue::add(MessageQueue::MT_ACHIEVEMENT, s); MessageQueue::add(MessageQueue::MT_ACHIEVEMENT, s);
// Sends a confirmation to the server that an achievement has been // Sends a confirmation to the server that an achievement has been

View File

@ -483,8 +483,7 @@ const irr::core::stringw
// shouldn't happen but let's avoid crashes as much as possible... // shouldn't happen but let's avoid crashes as much as possible...
if (track == NULL) return irr::core::stringw( L"????" ); if (track == NULL) return irr::core::stringw( L"????" );
return _("New track '%s' now available", return _("New track '%s' now available", track->getName());
core::stringw(track->getName()));
break; break;
} }
case UNLOCK_MODE: case UNLOCK_MODE:
@ -513,8 +512,7 @@ const irr::core::stringw
// shouldn't happen but let's avoid crashes as much as possible... // shouldn't happen but let's avoid crashes as much as possible...
if (kp == NULL) return irr::core::stringw( L"????" ); if (kp == NULL) return irr::core::stringw( L"????" );
return _("New kart '%s' now available", return _("New kart '%s' now available", kp->getName());
core::stringw(kp->getName()));
} }
default: default:
assert(false); assert(false);

View File

@ -1745,15 +1745,13 @@ video::SColorf IrrDriver::getAmbientLight() const
void IrrDriver::displayFPS() void IrrDriver::displayFPS()
{ {
gui::IGUIFont* font = GUIEngine::getSmallFont(); gui::IGUIFont* font = GUIEngine::getSmallFont();
core::rect<s32> position;
if(UserConfigParams::m_artist_debug_mode) if (UserConfigParams::m_artist_debug_mode)
{ position = core::rect<s32>(75, 0, 1100, 40);
GL32_draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,1100,40),NULL);
}
else else
{ position = core::rect<s32>(75, 0, 900, 40);
GL32_draw2DRectangle(video::SColor(150, 96, 74, 196),core::rect< s32 >(75,0,900,40),NULL); GL32_draw2DRectangle(video::SColor(150, 96, 74, 196), position, NULL);
}
// We will let pass some time to let things settle before trusting FPS counter // We will let pass some time to let things settle before trusting FPS counter
// even if we also ignore fps = 1, which tends to happen in first checks // even if we also ignore fps = 1, which tends to happen in first checks
const int NO_TRUST_COUNT = 200; const int NO_TRUST_COUNT = 200;
@ -1805,7 +1803,7 @@ void IrrDriver::displayFPS()
if (UserConfigParams::m_artist_debug_mode) if (UserConfigParams::m_artist_debug_mode)
{ {
fpsString = StringUtils::insertValues(_("FPS: %d/%d/%d - PolyCount: %d Solid, %d Shadows - LightDist : %d"), fpsString = _("FPS: %d/%d/%d - PolyCount: %d Solid, %d Shadows - LightDist : %d",
min, fps, max, poly_count[SOLID_NORMAL_AND_DEPTH_PASS], poly_count[SHADOW_PASS], m_last_light_bucket_distance); min, fps, max, poly_count[SOLID_NORMAL_AND_DEPTH_PASS], poly_count[SHADOW_PASS], m_last_light_bucket_distance);
poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0; poly_count[SOLID_NORMAL_AND_DEPTH_PASS] = 0;
poly_count[SHADOW_PASS] = 0; poly_count[SHADOW_PASS] = 0;
@ -1814,11 +1812,11 @@ void IrrDriver::displayFPS()
object_count[TRANSPARENT_PASS] = 0; object_count[TRANSPARENT_PASS] = 0;
} }
else else
fpsString = StringUtils::insertValues(_("FPS: %d/%d/%d - %d KTris"), min, fps, max, (int)roundf(kilotris)); fpsString = _("FPS: %d/%d/%d - %d KTris", min, fps, max, (int)roundf(kilotris));
static video::SColor fpsColor = video::SColor(255, 0, 0, 0); static video::SColor fpsColor = video::SColor(255, 0, 0, 0);
font->draw( fpsString.c_str(), core::rect< s32 >(100,0,400,50), fpsColor, false ); font->draw( fpsString.c_str(), position, fpsColor, false );
} // updateFPS } // updateFPS
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -46,7 +46,8 @@ void STKTextBillboard::updateAbsolutePosition()
scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFont* font) scene::IMesh* STKTextBillboard::getTextMesh(core::stringw text, gui::ScalableFont* font)
{ {
font->doDraw(text, core::rect<s32>(0, 0, 1000, 1000), video::SColor(255,255,255,255), core::dimension2du size = font->getDimension(text.c_str());
font->doDraw(text, core::rect<s32>(0, 0, size.Width, size.Height), video::SColor(255,255,255,255),
false, false, NULL, this); false, false, NULL, this);
const float scale = 0.018f; const float scale = 0.018f;

View File

@ -749,7 +749,7 @@ void InputManager::dispatchInput(Input::InputType type, int deviceID,
// is not associated to any player // is not associated to any player
GUIEngine::showMessage( GUIEngine::showMessage(
_("Ignoring '%s', you needed to join earlier to play!", _("Ignoring '%s', you needed to join earlier to play!",
irr::core::stringw(gp->getName().c_str()).c_str()) ); core::stringw(gp->getName().c_str())));
} }
} }
return; return;

View File

@ -1145,7 +1145,7 @@ void World::eliminateKart(int kart_id, bool notify_of_elimination)
2.0f); 2.0f);
else else
m_race_gui->addMessage(_("'%s' has been eliminated.", m_race_gui->addMessage(_("'%s' has been eliminated.",
core::stringw(kart->getName())), kart->getName()),
camera->getKart(), camera->getKart(),
2.0f); 2.0f);
} // for i < number of cameras } // for i < number of cameras

View File

@ -131,13 +131,13 @@ SelectChallengeDialog::SelectChallengeDialog(const float percentWidth,
if (c->getData()->isGrandPrix()) if (c->getData()->isGrandPrix())
{ {
const GrandPrixData* gp = grand_prix_manager->getGrandPrix(c->getData()->getGPId()); const GrandPrixData* gp = grand_prix_manager->getGrandPrix(c->getData()->getGPId());
getWidget<LabelWidget>("title")->setText( gp->getName(), true ); getWidget<LabelWidget>("title")->setText(translations->fribidize(gp->getName()), true);
} }
else else
{ {
const core::stringw track_name = const core::stringw track_name =
track_manager->getTrack(c->getData()->getTrackId())->getName(); track_manager->getTrack(c->getData()->getTrackId())->getName();
getWidget<LabelWidget>("title")->setText( track_name, true ); getWidget<LabelWidget>("title")->setText(translations->fribidize(track_name), true);
} }
LabelWidget* typeLbl = getWidget<LabelWidget>("race_type_val"); LabelWidget* typeLbl = getWidget<LabelWidget>("race_type_val");

View File

@ -155,7 +155,7 @@ void EditGPScreen::init()
{ {
LabelWidget* header = getWidget<LabelWidget>("title"); LabelWidget* header = getWidget<LabelWidget>("title");
assert(header != NULL); assert(header != NULL);
header->setText(m_gp->getName(), true); header->setText(translations->fribidize(m_gp->getName()), true);
IconButtonWidget* button = getWidget<IconButtonWidget>("save"); IconButtonWidget* button = getWidget<IconButtonWidget>("save");
assert(button != NULL); assert(button != NULL);
@ -281,7 +281,8 @@ void EditGPScreen::setModified(const bool modified)
LabelWidget* header = getWidget<LabelWidget>("title"); LabelWidget* header = getWidget<LabelWidget>("title");
assert(header != NULL); assert(header != NULL);
header->setText(m_gp->getName() + (modified ? L" (+)" : L""), true); //I18N: Indicate that the grand prix is modified and not saved
header->setText(modified ? _(L"%s (+)", m_gp->getName()) : L"", true);
enableButtons(); enableButtons();
} }

View File

@ -223,7 +223,7 @@ void EditTrackScreen::selectTrack(const std::string& id)
if (m_track != NULL) if (m_track != NULL)
{ {
tracks->setSelection(m_track->getIdent(), PLAYER_ID_GAME_MASTER, true); tracks->setSelection(m_track->getIdent(), PLAYER_ID_GAME_MASTER, true);
selected_track->setText(m_track->getName(), true); selected_track->setText(translations->fribidize(m_track->getName()), true);
laps->setValue(m_laps); laps->setValue(m_laps);

View File

@ -215,11 +215,11 @@ void GPInfoScreen::init()
m_gp.createRandomGP(m_num_tracks_spinner->getValue(), m_gp.createRandomGP(m_num_tracks_spinner->getValue(),
m_group_name, getReverse(), true); m_group_name, getReverse(), true);
getWidget<LabelWidget>("name")->setText(m_gp.getName(), false); getWidget<LabelWidget>("name")->setText(translations->fribidize(m_gp.getName()), false);
} }
else else
{ {
getWidget<LabelWidget>("name")->setText(m_gp.getName(), false); getWidget<LabelWidget>("name")->setText(translations->fribidize(m_gp.getName()), false);
m_gp.checkConsistency(); m_gp.checkConsistency();
} }

View File

@ -168,7 +168,7 @@ void GrandPrixEditorScreen::setSelection (const GrandPrixData* gpdata)
else else
{ {
m_selection = grand_prix_manager->editGrandPrix(gpdata->getId()); m_selection = grand_prix_manager->editGrandPrix(gpdata->getId());
gpname_widget->setText (gpdata->getName(), true); gpname_widget->setText(translations->fribidize(gpdata->getName()), true);
gplist_widget->setSelection(m_selection->getId(), PLAYER_ID_GAME_MASTER, true); gplist_widget->setSelection(m_selection->getId(), PLAYER_ID_GAME_MASTER, true);
loadTrackList (gpdata->getId()); loadTrackList (gpdata->getId());
} }

View File

@ -435,7 +435,7 @@ void RaceGUIOverworld::drawGlobalMiniMap()
// ---- Draw nearby challenge if any // ---- Draw nearby challenge if any
core::rect<s32> pos(15, core::rect<s32> pos(15,
10, 10,
15 + irr_driver->getActualScreenSize().Width/2, irr_driver->getActualScreenSize().Width - 200,
10 + GUIEngine::getTitleFontHeight()); 10 + GUIEngine::getTitleFontHeight());
m_close_to_a_challenge = false; m_close_to_a_challenge = false;
@ -490,16 +490,15 @@ void RaceGUIOverworld::drawGlobalMiniMap()
} }
gui::ScalableFont* font = GUIEngine::getTitleFont(); gui::ScalableFont* font = GUIEngine::getTitleFont();
font->draw(gp->getName(), pos, video::SColor(255,255,255,255), font->draw(translations->fribidize(gp->getName()), pos, video::SColor(255,255,255,255),
false, true /* vcenter */, NULL); false, true /* vcenter */, NULL);
core::rect<s32> pos(15, core::rect<s32> pos2(pos);
20 + GUIEngine::getTitleFontHeight(), pos2.UpperLeftCorner.Y += 10 + GUIEngine::getTitleFontHeight();
15 + irr_driver->getActualScreenSize().Width/2, pos2.LowerRightCorner.Y += 10 + GUIEngine::getTitleFontHeight();
20 + 2*GUIEngine::getTitleFontHeight());
//just below GP name //just below GP name
font->draw(_("Type: Grand Prix"), pos, video::SColor(255,255,255,255), font->draw(_("Type: Grand Prix"), pos2, video::SColor(255,255,255,255),
false, true /* vcenter */, NULL); false, true /* vcenter */, NULL);
} }
else else
@ -515,7 +514,8 @@ void RaceGUIOverworld::drawGlobalMiniMap()
} }
gui::ScalableFont* font = GUIEngine::getTitleFont(); gui::ScalableFont* font = GUIEngine::getTitleFont();
font->draw(track->getName(), pos, video::SColor(255,255,255,255), font->draw(translations->fribidize(track->getName()),
pos, video::SColor(255, 255, 255, 255),
false, true /* vcenter */, NULL); false, true /* vcenter */, NULL);
} }

View File

@ -100,7 +100,7 @@ void TrackInfoScreen::init()
const bool has_laps = race_manager->modeHasLaps(); const bool has_laps = race_manager->modeHasLaps();
const bool has_highscores = race_manager->modeHasHighscores(); const bool has_highscores = race_manager->modeHasHighscores();
getWidget<LabelWidget>("name")->setText(m_track->getName(), false); getWidget<LabelWidget>("name")->setText(translations->fribidize(m_track->getName()), false);
//I18N: when showing who is the author of track '%s' //I18N: when showing who is the author of track '%s'
//I18N: (place %s where the name of the author should appear) //I18N: (place %s where the name of the author should appear)

View File

@ -182,7 +182,7 @@ bool Track::operator<(const Track &other) const
\note this is the LTR name, invoke fribidi as needed. */ \note this is the LTR name, invoke fribidi as needed. */
core::stringw Track::getName() const core::stringw Track::getName() const
{ {
core::stringw translated = translations->w_gettext(m_name.c_str()); core::stringw translated = _LTR(m_name.c_str());
int index = translated.find("|"); int index = translated.find("|");
if(index>-1) if(index>-1)
{ {

View File

@ -47,6 +47,8 @@
// set to 1 to debug i18n // set to 1 to debug i18n
#define TRANSLATE_VERBOSE 0 #define TRANSLATE_VERBOSE 0
// Define TEST_BIDI to force right-to-left style for all languages
//#define TEST_BIDI
using namespace tinygettext; using namespace tinygettext;
@ -274,6 +276,9 @@ Translations::Translations() //: m_dictionary_manager("UTF-16")
break; break;
} }
} }
#ifdef TEST_BIDI
m_rtl = true;
#endif
} // Translations } // Translations
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -283,26 +288,27 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
#if ENABLE_BIDI #if ENABLE_BIDI
if(this->isRTLLanguage()) if(this->isRTLLanguage())
{ {
const int FRIBIDI_BUFFER_SIZE = 512; std::size_t length = wcslen(in_ptr);
FriBidiChar fribidiInput[FRIBIDI_BUFFER_SIZE]; FriBidiChar *fribidiInput;
int len = 0;
int n = 0;
//std::cout << "fribidi input : ";
for (n = 0; ; n++)
{
fribidiInput[n] = in_ptr[n];
//std::cout << (int)fribidiInput[n] << " ";
len++;
if (n == FRIBIDI_BUFFER_SIZE-1) // prevent buffeoverflows if (sizeof(wchar_t) == sizeof(FriBidiChar))
{ fribidiInput = (FriBidiChar*) in_ptr;
Log::warn("Translations::fribidize", "translated string too long, truncating"); else
fribidiInput[n] = 0; {
break; // On windows FriBidiChar is 4 bytes, but wchar_t is 2 bytes.
} // So we simply copy the characters over here (note that this
if (fribidiInput[n] == 0) break; // stop on '\0' // is technically incorrect, all characters we use/support fit
// in 16 bits, which is what irrlicht supports atm).
fribidiInput = new FriBidiChar[length + 1];
for (std::size_t i = 0; i <= length; i++)
fribidiInput[i] = in_ptr[i];
} }
//std::cout << " (len=" << len << ")\n"; #ifdef TEST_BIDI
FriBidiChar *tmp = fribidiInput;
fribidiInput = new FriBidiChar[++length + 1];
std::memcpy(fribidiInput + 1, tmp, length * sizeof(FriBidiChar));
fribidiInput[0] = L'\u202E';
#endif
// Assume right to left as start direction. // Assume right to left as start direction.
#if FRIBIDI_MINOR_VERSION==10 #if FRIBIDI_MINOR_VERSION==10
@ -314,37 +320,45 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
FriBidiCharType pbase_dir = FRIBIDI_PAR_ON; FriBidiCharType pbase_dir = FRIBIDI_PAR_ON;
#endif #endif
static FriBidiChar fribidiOutput[FRIBIDI_BUFFER_SIZE]; FriBidiChar *fribidiOutput = new FriBidiChar[length + 1];
for (n = 0; n < 512 ; n++) { fribidiOutput[n] = 0; } std::memset(fribidiOutput, 0, (length + 1) * sizeof(FriBidiChar));
fribidi_boolean result = fribidi_log2vis(fribidiInput, fribidi_boolean result = fribidi_log2vis(fribidiInput,
len-1, length,
&pbase_dir, &pbase_dir,
fribidiOutput, fribidiOutput,
/* gint *position_L_to_V_list */ NULL, /* gint *position_L_to_V_list */ NULL,
/* gint *position_V_to_L_list */ NULL, /* gint *position_V_to_L_list */ NULL,
/* gint8 *embedding_level_list */ NULL /* gint8 *embedding_level_list */ NULL
); );
#ifdef TEST_BIDI
delete[] fribidiInput;
fribidiInput = tmp;
#endif
if (sizeof(wchar_t) != sizeof(FriBidiChar))
delete[] fribidiInput;
if (!result) if (!result)
{ {
delete[] fribidiOutput;
Log::error("Translations::fribidize", "Fribidi failed in 'fribidi_log2vis' =("); Log::error("Translations::fribidize", "Fribidi failed in 'fribidi_log2vis' =(");
m_converted_string = core::stringw(in_ptr); m_converted_string = core::stringw(in_ptr);
return m_converted_string.c_str(); return m_converted_string.c_str();
} }
#ifdef WIN32 if (sizeof(wchar_t) == sizeof(FriBidiChar))
// On windows FriBidiChar is 4 bytes, but wchar_t is 2 bytes. m_converted_string = core::stringw((wchar_t*) fribidiOutput);
// So we simply copy the characters over here (note that this else
// is technically incorrect, all characters we use/support fit {
// in 16 bits, which is what irrlicht supports atm). // Copy back to wchar_t array
static wchar_t out[FRIBIDI_BUFFER_SIZE]; wchar_t *out = new wchar_t[length + 1];
for(int i=0; i<len; i++) for (std::size_t i = 0; i <= length; i++)
out[i]=fribidiOutput[i]; out[i] = fribidiOutput[i];
out[len]=0; m_converted_string = core::stringw(out);
return out; delete[] out;
#else }
return (const wchar_t*)fribidiOutput; delete[] fribidiOutput;
#endif //WIND32 return m_converted_string.c_str();
} }
#endif // ENABLE_BIDI #endif // ENABLE_BIDI