Adding a new flag and new text break for support of right-to-left text in StaticText elements. Patch from Auria and STK project.
git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3585 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
658cc28240
commit
777ea0199c
|
@ -97,6 +97,17 @@ namespace gui
|
|||
|
||||
//! Checks if the text in this label should be clipped if it goes outside bounds
|
||||
virtual bool isTextRestrainedInside() const = 0;
|
||||
|
||||
//! Set whether the string should be interpreted as right-to-left (RTL) text
|
||||
/** \note This component does not implement the Unicode bidi standard, the
|
||||
text of the component should be already RTL if you call this. The
|
||||
main difference when RTL is enabled is that the linebreaks for multiline
|
||||
elements are performed starting from the end.
|
||||
*/
|
||||
virtual void setRightToLeft(bool rtl) = 0;
|
||||
|
||||
//! Checks whether the text in this element should be interpreted as right-to-left
|
||||
virtual bool isRightToLeft() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -256,6 +256,18 @@ bool CGUIStaticText::isWordWrapEnabled() const
|
|||
}
|
||||
|
||||
|
||||
void CGUIStaticText::setRightToLeft(bool rtl)
|
||||
{
|
||||
RightToLeft = rtl;
|
||||
}
|
||||
|
||||
|
||||
bool CGUIStaticText::isRightToLeft() const
|
||||
{
|
||||
return RightToLeft;
|
||||
}
|
||||
|
||||
|
||||
//! Breaks the single text line.
|
||||
void CGUIStaticText::breakText()
|
||||
{
|
||||
|
@ -275,87 +287,179 @@ void CGUIStaticText::breakText()
|
|||
|
||||
LastBreakFont = font;
|
||||
|
||||
core::stringw line;
|
||||
core::stringw word;
|
||||
core::stringw whitespace;
|
||||
s32 size = Text.size();
|
||||
s32 length = 0;
|
||||
s32 elWidth = RelativeRect.getWidth() - 6;
|
||||
wchar_t c;
|
||||
|
||||
for (s32 i=0; i<size; ++i)
|
||||
// We have to deal with right-to-left and left-to-right differently
|
||||
// However, most parts of the following code is the same, it's just
|
||||
// some order and boundaries which change.
|
||||
if (!RightToLeft)
|
||||
{
|
||||
c = Text[i];
|
||||
bool lineBreak = false;
|
||||
// regular (left-to-right)
|
||||
core::stringw line;
|
||||
core::stringw word;
|
||||
core::stringw whitespace;
|
||||
s32 size = Text.size();
|
||||
s32 length = 0;
|
||||
s32 elWidth = RelativeRect.getWidth() - 6;
|
||||
wchar_t c;
|
||||
|
||||
if (c == L'\r') // Mac or Windows breaks
|
||||
for (s32 i=0; i<size; ++i)
|
||||
{
|
||||
lineBreak = true;
|
||||
if (Text[i+1] == L'\n') // Windows breaks
|
||||
c = Text[i];
|
||||
bool lineBreak = false;
|
||||
|
||||
if (c == L'\r') // Mac or Windows breaks
|
||||
{
|
||||
Text.erase(i+1);
|
||||
--size;
|
||||
}
|
||||
c = '\0';
|
||||
}
|
||||
else if (c == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
c = '\0';
|
||||
}
|
||||
|
||||
if (c == L' ' || c == 0 || i == (size-1))
|
||||
{
|
||||
if (word.size())
|
||||
{
|
||||
// here comes the next whitespace, look if
|
||||
// we must break the last word to the next line.
|
||||
const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
|
||||
const s32 wordlgth = font->getDimension(word.c_str()).Width;
|
||||
|
||||
if (length && (length + wordlgth + whitelgth > elWidth))
|
||||
lineBreak = true;
|
||||
if (Text[i+1] == L'\n') // Windows breaks
|
||||
{
|
||||
// break to next line
|
||||
BrokenText.push_back(line);
|
||||
length = wordlgth;
|
||||
line = word;
|
||||
Text.erase(i+1);
|
||||
--size;
|
||||
}
|
||||
else
|
||||
c = '\0';
|
||||
}
|
||||
else if (c == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
c = '\0';
|
||||
}
|
||||
|
||||
if (c==L' ' || c==0 || i==(size-1))
|
||||
{
|
||||
if (word.size())
|
||||
{
|
||||
// here comes the next whitespace, look if
|
||||
// we must break the last word to the next line.
|
||||
const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
|
||||
const s32 wordlgth = font->getDimension(word.c_str()).Width;
|
||||
|
||||
if (length && (length + wordlgth + whitelgth > elWidth))
|
||||
{
|
||||
// break to next line
|
||||
BrokenText.push_back(line);
|
||||
length = wordlgth;
|
||||
line = word;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add word to line
|
||||
line += whitespace;
|
||||
line += word;
|
||||
length += whitelgth + wordlgth;
|
||||
}
|
||||
|
||||
word = L"";
|
||||
whitespace = L"";
|
||||
}
|
||||
|
||||
whitespace += c;
|
||||
|
||||
// compute line break
|
||||
if (lineBreak)
|
||||
{
|
||||
// add word to line
|
||||
line += whitespace;
|
||||
line += word;
|
||||
length += whitelgth + wordlgth;
|
||||
BrokenText.push_back(line);
|
||||
line = L"";
|
||||
word = L"";
|
||||
whitespace = L"";
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// yippee this is a word..
|
||||
word += c;
|
||||
}
|
||||
}
|
||||
|
||||
line += whitespace;
|
||||
line += word;
|
||||
BrokenText.push_back(line);
|
||||
}
|
||||
else
|
||||
{
|
||||
// right-to-left
|
||||
core::stringw line;
|
||||
core::stringw word;
|
||||
core::stringw whitespace;
|
||||
s32 size = Text.size();
|
||||
s32 length = 0;
|
||||
s32 elWidth = RelativeRect.getWidth() - 6;
|
||||
wchar_t c;
|
||||
|
||||
for (s32 i=size; i>=0; --i)
|
||||
{
|
||||
c = Text[i];
|
||||
bool lineBreak = false;
|
||||
|
||||
if (c == L'\r') // Mac or Windows breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
if ((i>0) && Text[i-1] == L'\n') // Windows breaks
|
||||
{
|
||||
Text.erase(i-1);
|
||||
--size;
|
||||
}
|
||||
c = '\0';
|
||||
}
|
||||
else if (c == L'\n') // Unix breaks
|
||||
{
|
||||
lineBreak = true;
|
||||
c = '\0';
|
||||
}
|
||||
|
||||
if (c==L' ' || c==0 || i==0)
|
||||
{
|
||||
if (word.size())
|
||||
{
|
||||
// here comes the next whitespace, look if
|
||||
// we must break the last word to the next line.
|
||||
const s32 whitelgth = font->getDimension(whitespace.c_str()).Width;
|
||||
const s32 wordlgth = font->getDimension(word.c_str()).Width;
|
||||
|
||||
if (length && (length + wordlgth + whitelgth > elWidth))
|
||||
{
|
||||
// break to next line
|
||||
BrokenText.push_back(line);
|
||||
length = wordlgth;
|
||||
line = word;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add word to line
|
||||
line = whitespace + line;
|
||||
line = word + line;
|
||||
length += whitelgth + wordlgth;
|
||||
}
|
||||
|
||||
word = L"";
|
||||
whitespace = L"";
|
||||
}
|
||||
|
||||
word = L"";
|
||||
whitespace = L"";
|
||||
whitespace = core::stringw(&c, 1) + whitespace;
|
||||
|
||||
// compute line break
|
||||
if (lineBreak)
|
||||
{
|
||||
line = whitespace + line;
|
||||
line = word + line;
|
||||
BrokenText.push_back(line);
|
||||
line = L"";
|
||||
word = L"";
|
||||
whitespace = L"";
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
whitespace += c;
|
||||
|
||||
// compute line break
|
||||
if (lineBreak)
|
||||
else
|
||||
{
|
||||
line += whitespace;
|
||||
line += word;
|
||||
BrokenText.push_back(line);
|
||||
line = L"";
|
||||
word = L"";
|
||||
whitespace = L"";
|
||||
length = 0;
|
||||
// yippee this is a word..
|
||||
word = core::stringw(&c, 1) + word;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// yippee this is a word..
|
||||
word += c;
|
||||
}
|
||||
}
|
||||
|
||||
line += whitespace;
|
||||
line += word;
|
||||
BrokenText.push_back(line);
|
||||
line = whitespace + line;
|
||||
line = word + line;
|
||||
BrokenText.push_back(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -445,6 +549,7 @@ void CGUIStaticText::serializeAttributes(io::IAttributes* out, io::SAttributeRea
|
|||
out->addBool ("OverrideBGColorEnabled",OverrideBGColorEnabled);
|
||||
out->addBool ("WordWrap", WordWrap);
|
||||
out->addBool ("Background", Background);
|
||||
out->addBool ("RightToLeft", RightToLeft);
|
||||
out->addBool ("RestrainTextInside", RestrainTextInside);
|
||||
out->addColor ("OverrideColor", OverrideColor);
|
||||
out->addColor ("BGColor", BGColor);
|
||||
|
@ -465,6 +570,7 @@ void CGUIStaticText::deserializeAttributes(io::IAttributes* in, io::SAttributeRe
|
|||
OverrideBGColorEnabled = in->getAttributeAsBool("OverrideBGColorEnabled");
|
||||
setWordWrap(in->getAttributeAsBool("WordWrap"));
|
||||
Background = in->getAttributeAsBool("Background");
|
||||
RightToLeft = in->getAttributeAsBool("RightToLeft");
|
||||
RestrainTextInside = in->getAttributeAsBool("RestrainTextInside");
|
||||
OverrideColor = in->getAttributeAsColor("OverrideColor");
|
||||
BGColor = in->getAttributeAsColor("BGColor");
|
||||
|
|
|
@ -86,6 +86,17 @@ namespace gui
|
|||
//! Updates the absolute position, splits text if word wrap is enabled
|
||||
virtual void updateAbsolutePosition();
|
||||
|
||||
//! Set whether the string should be interpreted as right-to-left (RTL) text
|
||||
/** \note This component does not implement the Unicode bidi standard, the
|
||||
text of the component should be already RTL if you call this. The
|
||||
main difference when RTL is enabled is that the linebreaks for multiline
|
||||
elements are performed starting from the end.
|
||||
*/
|
||||
virtual void setRightToLeft(bool rtl);
|
||||
|
||||
//! Checks if the text should be interpreted as right-to-left text
|
||||
virtual bool isRightToLeft() const;
|
||||
|
||||
//! Writes attributes of the element.
|
||||
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
|
||||
|
||||
|
@ -104,6 +115,7 @@ namespace gui
|
|||
bool WordWrap;
|
||||
bool Background;
|
||||
bool RestrainTextInside;
|
||||
bool RightToLeft;
|
||||
|
||||
video::SColor OverrideColor, BGColor;
|
||||
gui::IGUIFont* OverrideFont;
|
||||
|
|
Loading…
Reference in New Issue