Merge remote-tracking branch 'Flakebi/bidi-updown'

This commit is contained in:
Marianne Gagnon 2015-04-08 20:09:15 -04:00
commit 9a905cb579
12 changed files with 125 additions and 61 deletions

View File

@ -229,7 +229,6 @@ if(prop_name != NULL) widget.m_properties[prop_flag] = core::stringc(prop_name).
if (text != NULL)
{
widget.m_text = _(text);
widget.m_is_text_rtl = (translations->isRTLLanguage() && widget.m_text != text);
}
const wchar_t* raw_text = xml->getAttributeValue(L"raw_text");

View File

@ -76,7 +76,6 @@ Widget::Widget(WidgetType type, bool reserve_id)
m_supports_multiplayer = false;
m_is_bounding_box_round = false;
m_has_tooltip = false;
m_is_text_rtl = false;
m_absolute_x = m_absolute_y = m_absolute_w = m_absolute_h = -1;
m_relative_x = m_relative_y = m_relative_w = m_relative_h = -1;

View File

@ -156,9 +156,6 @@ namespace GUIEngine
* go in the map above, which uses narrow strings */
irr::core::stringw m_text;
/** Whether the text in m_text is right-to-left */
bool m_is_text_rtl;
/** When true, this widget shall use a bigger and more colourful font */
bool m_title_font;

View File

@ -53,11 +53,7 @@ void BubbleWidget::add()
false, true /* word wrap */, m_parent,
(m_focusable ? getNewID() : getNewNoFocusID()));
irrwidget->setTextRestrainedInside(false);
#if IRRLICHT_VERSION_MAJOR > 1 || (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8)
irrwidget->setRightToLeft( translations->isRTLLanguage() );
#endif
irrwidget->setRightToLeft(translations->isRTLText(message));
m_element = irrwidget;
replaceText();
@ -120,9 +116,11 @@ void BubbleWidget::replaceText()
void BubbleWidget::setText(const irr::core::stringw &s)
{
Widget::setText(s);
if (m_element != NULL)
{
//If add() has already been called (and thus m_element is set) we need to replace the text.
if(m_element != NULL){
replaceText();
getIrrlichtElement<IGUIStaticText>()->setRightToLeft(translations->isRTLText(getText()));
}
}

View File

@ -196,10 +196,8 @@ void IconButtonWidget::add()
setLabelFont();
#if IRRLICHT_VERSION_MAJOR > 1 || (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8)
m_label->setRightToLeft( translations->isRTLLanguage() );
m_label->setRightToLeft(translations->isRTLText(message));
m_label->setTextRestrainedInside(false);
#endif
}
// ---- IDs

View File

@ -80,13 +80,9 @@ void LabelWidget::add()
{
irrwidget = GUIEngine::getGUIEnv()->addStaticText(message.c_str(), widget_size,
false, word_wrap, m_parent, -1);
#if IRRLICHT_VERSION_MAJOR > 1 || (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8)
irrwidget->setTextRestrainedInside(false);
#endif
}
#if IRRLICHT_VERSION_MAJOR > 1 || (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR >= 8)
irrwidget->setRightToLeft( m_is_text_rtl );
#endif
irrwidget->setRightToLeft(translations->isRTLText(message));
m_element = irrwidget;
irrwidget->setTextAlignment( align, valign );
@ -155,6 +151,8 @@ void LabelWidget::setText(const wchar_t *text, bool expandIfNeeded)
}
Widget::setText(text);
if (m_element)
getIrrlichtElement<IGUIStaticText>()->setRightToLeft(translations->isRTLText(getText()));
} // setText
// ----------------------------------------------------------------------------

View File

@ -262,6 +262,7 @@ void RibbonWidget::add()
label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
label->setTabStop(false);
label->setNotClipped(true);
label->setRightToLeft(translations->isRTLText(message));
m_labels.push_back(label);
subbtn->setTabStop(false);

View File

@ -145,7 +145,8 @@ void SpinnerWidget::add()
else
{
rect<s32> subsize_label = rect<s32>(m_h, 0, m_w - m_h, m_h);
IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText(stringw(m_value).c_str(), subsize_label,
const wchar_t *text = stringw(m_value).c_str();
IGUIStaticText* label = GUIEngine::getGUIEnv()->addStaticText(text, subsize_label,
false /* border */, true /* word wrap */,
btn, getNewNoFocusID());
m_children[1].m_element = label;
@ -155,6 +156,7 @@ void SpinnerWidget::add()
label->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
label->setTabStop(false);
label->setNotClipped(true);
label->setRightToLeft(translations->isRTLText(text));
if (m_labels.size() > 0)

View File

@ -76,7 +76,7 @@ AddDeviceDialog::AddDeviceDialog() : ModalDialog(0.90f, 0.80f)
/*word wrap*/true,
m_irrlicht_window);
b->setTabStop(false);
b->setRightToLeft(translations->isRTLLanguage());
b->setRightToLeft(translations->isRTLText(msg));
// because it looks like 'setRightToLeft' applies next time
// setText is called only
b->setText(msg.c_str());

View File

@ -79,12 +79,14 @@ GPInfoDialog::~GPInfoDialog()
void GPInfoDialog::addTitle()
{
core::rect< s32 > area_top(0, 0, m_area.getWidth(), m_under_title);
const wchar_t *text = translations->fribidize(m_gp.getName());
IGUIStaticText* title = GUIEngine::getGUIEnv()->addStaticText(
translations->fribidize(m_gp.getName()),
text,
area_top, false, true, // border, word wrap
m_irrlicht_window);
title->setTabStop(false);
title->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
title->setRightToLeft(translations->isRTLText(text));
}
// ----------------------------------------------------------------------------

View File

@ -94,6 +94,81 @@ wchar_t* utf8_to_wide(const char* input)
return &utf16line[0];
}
// ----------------------------------------------------------------------------
/** Frees the memory allocated for the result of toFribidiChar(). */
void freeFribidiChar(FriBidiChar *str)
{
#ifdef TEST_BIDI
delete[] str;
#else
if (sizeof(wchar_t) != sizeof(FriBidiChar))
delete[] str;
#endif
}
/** Frees the memory allocated for the result of fromFribidiChar(). */
void freeFribidiChar(wchar_t *str)
{
if (sizeof(wchar_t) != sizeof(FriBidiChar))
delete[] str;
}
// ----------------------------------------------------------------------------
/** Converts a wstring to a FriBidi-string.
The caller must take care to free (or not to free) the result after use.
Freeing should be done with freeFribidiChar().
On linux, the string doesn't need to be converted because wchar_t is
already UTF-32. On windows the string is converted from UTF-16 by this
function. */
FriBidiChar* toFribidiChar(const wchar_t* str)
{
std::size_t length = wcslen(str);
FriBidiChar *result;
if (sizeof(wchar_t) == sizeof(FriBidiChar))
result = (FriBidiChar*) str;
else
{
// On windows FriBidiChar is 4 bytes, but wchar_t is 2 bytes.
// So we simply copy the characters over here (note that this
// is technically incorrect, all characters we use/support fit
// in 16 bits, which is what irrlicht supports atm).
result = new FriBidiChar[length + 1];
for (std::size_t i = 0; i <= length; i++)
result[i] = str[i];
}
#ifdef TEST_BIDI
// Prepend a character that forces RTL style
FriBidiChar *tmp = result;
result = new FriBidiChar[++length + 1];
std::memcpy(result + 1, tmp, length * sizeof(FriBidiChar));
result[0] = L'\u202E';
freeFribidiChar(tmp);
#endif
return result;
}
wchar_t* fromFribidiChar(const FriBidiChar* str)
{
wchar_t *result;
if (sizeof(wchar_t) == sizeof(FriBidiChar))
result = (wchar_t*) str;
else
{
std::size_t length = 0;
while (str[length])
length++;
// Copy back to wchar_t array
result = new wchar_t[length + 1];
for (std::size_t i = 0; i <= length; i++)
result[i] = str[i];
}
return result;
}
// ----------------------------------------------------------------------------
Translations::Translations() //: m_dictionary_manager("UTF-16")
{
@ -288,27 +363,10 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
#if ENABLE_BIDI
if(this->isRTLLanguage())
{
std::size_t length = wcslen(in_ptr);
FriBidiChar *fribidiInput;
if (sizeof(wchar_t) == sizeof(FriBidiChar))
fribidiInput = (FriBidiChar*) in_ptr;
else
{
// On windows FriBidiChar is 4 bytes, but wchar_t is 2 bytes.
// So we simply copy the characters over here (note that this
// 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];
}
#ifdef TEST_BIDI
FriBidiChar *tmp = fribidiInput;
fribidiInput = new FriBidiChar[++length + 1];
std::memcpy(fribidiInput + 1, tmp, length * sizeof(FriBidiChar));
fribidiInput[0] = L'\u202E';
#endif
FriBidiChar *fribidiInput = toFribidiChar(in_ptr);
std::size_t length = 0;
while (fribidiInput[length])
length++;
// Assume right to left as start direction.
#if FRIBIDI_MINOR_VERSION==10
@ -330,13 +388,8 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
/* gint *position_V_to_L_list */ NULL,
/* gint8 *embedding_level_list */ NULL
);
#ifdef TEST_BIDI
delete[] fribidiInput;
fribidiInput = tmp;
#endif
if (sizeof(wchar_t) != sizeof(FriBidiChar))
delete[] fribidiInput;
freeFribidiChar(fribidiInput);
if (!result)
{
@ -346,17 +399,9 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
return m_converted_string.c_str();
}
if (sizeof(wchar_t) == sizeof(FriBidiChar))
m_converted_string = core::stringw((wchar_t*) fribidiOutput);
else
{
// Copy back to wchar_t array
wchar_t *out = new wchar_t[length + 1];
for (std::size_t i = 0; i <= length; i++)
out[i] = fribidiOutput[i];
m_converted_string = core::stringw(out);
delete[] out;
}
wchar_t *convertedString = fromFribidiChar(fribidiOutput);
m_converted_string = core::stringw(convertedString);
freeFribidiChar(convertedString);
delete[] fribidiOutput;
return m_converted_string.c_str();
}
@ -365,6 +410,28 @@ const wchar_t* Translations::fribidize(const wchar_t* in_ptr)
return in_ptr;
}
bool Translations::isRTLText(const wchar_t *in_ptr)
{
#if ENABLE_BIDI
if (this->isRTLLanguage())
{
std::size_t length = wcslen(in_ptr);
FriBidiChar *fribidiInput = toFribidiChar(in_ptr);
FriBidiCharType *types = new FriBidiCharType[length];
fribidi_get_bidi_types(fribidiInput, length, types);
freeFribidiChar(fribidiInput);
FriBidiParType type = fribidi_get_par_direction(types, length);
delete[] types;
return type == FRIBIDI_PAR_RTL;
}
return false;
#else
return false;
#endif
}
/**
* \param original Message to translate
* \param context Optional, can be set to differentiate 2 strings that are identical

View File

@ -64,6 +64,9 @@ public:
const wchar_t* fribidize(const wchar_t* in_ptr);
const wchar_t* fribidize(const irr::core::stringw &str) { return fribidize(str.c_str()); }
bool isRTLText(const wchar_t* in_ptr);
bool isRTLText(const irr::core::stringw &str) { return isRTLText(str.c_str()); }
const std::vector<std::string>* getLanguageList() const;
std::string getCurrentLanguageName();