RTL fixes from TWiLight

This commit is contained in:
Pk11
2021-01-20 13:55:44 -06:00
parent 3af2a29cfe
commit 1588a4254b
2 changed files with 31 additions and 28 deletions
+7 -7
View File
@@ -57,7 +57,7 @@ private:
u16 charIndex(char16_t c); u16 charIndex(char16_t c);
void print(std::u16string_view text, int x, int y, bool top, int layer, Alignment align, int maxWidth, int color, float scaleX, float scaleY, Sprite *sprite); void print(std::u16string_view text, int x, int y, bool top, int layer, Alignment align, int maxWidth, int color, float scaleX, float scaleY, bool rtl, Sprite *sprite);
public: public:
/** /**
@@ -108,7 +108,7 @@ public:
* @param scaleX (Optional) The scale on the X axis * @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis * @param scaleY (Optional) The scale on the Y axis
*/ */
void print(int value, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(std::to_string(value)), x, y, top, layer, align, maxWidth, scaleX, scaleY, color, nullptr); } void print(int value, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(std::to_string(value)), x, y, top, layer, align, maxWidth, scaleX, scaleY, color, false, nullptr); }
/** /**
* @brief Prints a string to a background layer * @brief Prints a string to a background layer
@@ -123,8 +123,8 @@ public:
* @param scaleY (Optional) The scale on the Y axis * @param scaleY (Optional) The scale on the Y axis
* @param color (Optional) The color to print in * @param color (Optional) The color to print in
*/ */
void print(std::string_view text, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(text), x, y, top, layer, align, maxWidth, color, scaleX, scaleY, nullptr); } void print(std::string_view text, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(text), x, y, top, layer, align, maxWidth, color, scaleX, scaleY, false, nullptr); }
void print(std::u16string_view text, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(text, x, y, top, layer, align, maxWidth, color, scaleX, scaleY, nullptr); } void print(std::u16string_view text, int x, int y, bool top, int layer = 2, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(text, x, y, top, layer, align, maxWidth, color, scaleX, scaleY, false, nullptr); }
/** /**
* @brief Prints an integer value to a sprite * @brief Prints an integer value to a sprite
@@ -138,7 +138,7 @@ public:
* @param scaleX (Optional) The scale on the X axis * @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis * @param scaleY (Optional) The scale on the Y axis
*/ */
void print(int value, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(std::to_string(value)), x, y, false, 0, align, maxWidth, color, scaleX, scaleY, nullptr); } void print(int value, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(std::to_string(value)), x, y, false, 0, align, maxWidth, color, scaleX, scaleY, false, nullptr); }
/** /**
* @brief Prints a string to a sprite * @brief Prints a string to a sprite
@@ -152,8 +152,8 @@ public:
* @param scaleX (Optional) The scale on the X axis * @param scaleX (Optional) The scale on the X axis
* @param scaleY (Optional) The scale on the Y axis * @param scaleY (Optional) The scale on the Y axis
*/ */
void print(std::string_view text, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(text), x, y, false, 0, align, maxWidth, color, scaleX, scaleY, &sprite); } void print(std::string_view text, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(utf8to16(text), x, y, false, 0, align, maxWidth, color, scaleX, scaleY, false, &sprite); }
void print(std::u16string_view text, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(text, x, y, false, 0, align, maxWidth, color, scaleX, scaleY, &sprite); } void print(std::u16string_view text, int x, int y, Sprite &sprite, Alignment align = Alignment::left, int maxWidth = 0, int color = 0, float scaleX = 1.0f, float scaleY = 1.0f) { print(text, x, y, false, 0, align, maxWidth, color, scaleX, scaleY, false, &sprite); }
#ifdef TEXT_BUFFERED #ifdef TEXT_BUFFERED
/** /**
+24 -21
View File
@@ -183,7 +183,16 @@ int Font::calcWidth(std::u16string_view text) {
} }
ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int layer, Alignment align, int maxWidth, ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int layer, Alignment align, int maxWidth,
int color, float scaleX, float scaleY, Sprite *sprite) { int color, float scaleX, float scaleY, bool rtl, Sprite *sprite) {
// If RTL isn't forced, check for RTL text
for(const auto c : text) {
if(c >= 0x0590 && c <= 0x05FF) {
rtl = true;
break;
}
}
auto ltrBegin = text.end(), ltrEnd = text.end();
// Adjust x for alignment // Adjust x for alignment
switch(align) { switch(align) {
case Alignment::left: { case Alignment::left: {
@@ -192,7 +201,7 @@ ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int
case Alignment::center: { case Alignment::center: {
size_t newline = text.find('\n'); size_t newline = text.find('\n');
while(newline != text.npos) { while(newline != text.npos) {
print(text.substr(0, newline), x, y, top, layer, align, maxWidth, color, scaleX, scaleY, sprite); print(text.substr(0, newline), x, y, top, layer, align, maxWidth, color, scaleX, scaleY, rtl, sprite);
text = text.substr(newline + 1); text = text.substr(newline + 1);
newline = text.find('\n'); newline = text.find('\n');
y += tileHeight; y += tileHeight;
@@ -205,7 +214,7 @@ ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int
size_t newline = text.find('\n'); size_t newline = text.find('\n');
while(newline != text.npos) { while(newline != text.npos) {
print(text.substr(0, newline), x - (calcWidth(text.substr(0, newline)) * scaleX), y, top, layer, print(text.substr(0, newline), x - (calcWidth(text.substr(0, newline)) * scaleX), y, top, layer,
Alignment::left, maxWidth, color, scaleX, scaleY, sprite); Alignment::left, maxWidth, color, scaleX, scaleY, rtl, sprite);
text = text.substr(newline + 1); text = text.substr(newline + 1);
newline = text.find('\n'); newline = text.find('\n');
y += tileHeight; y += tileHeight;
@@ -219,21 +228,12 @@ ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int
if(maxWidth != 0) if(maxWidth != 0)
scaleX = std::min(scaleX, (float)maxWidth / (calcWidth(text) * scaleX)); scaleX = std::min(scaleX, (float)maxWidth / (calcWidth(text) * scaleX));
bool rtl = false;
for(const auto c : text) {
if(c >= 0x0590 && c <= 0x05FF) {
rtl = true;
break;
}
}
auto ltrBegin = text.end(), ltrEnd = text.end();
// Loop through string and print it // Loop through string and print it
for(auto it = (rtl ? text.end() - 1 : text.begin()); true; it += (rtl ? -1 : 1)) { for(auto it = (rtl ? text.end() - 1 : text.begin()); true; it += (rtl ? -1 : 1)) {
// If we hit the end of the string in an LTR section of an RTL // If we hit the end of the string in an LTR section of an RTL
// string, it may not be done, if so jump back to printing RTL // string, it may not be done, if so jump back to printing RTL
if(it == (rtl ? text.begin() - 1 : text.end())) { if(it == (rtl ? text.begin() - 1 : text.end())) {
if(ltrBegin == text.end()) { if(ltrBegin == text.end() || (ltrBegin == text.begin() && ltrEnd == text.end())) {
break; break;
} else { } else {
it = ltrBegin; it = ltrBegin;
@@ -242,7 +242,7 @@ ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int
} }
} }
// If at the end of an LRT section within RTL, jump back to the RTL // If at the end of an LTR section within RTL, jump back to the RTL
if(it == ltrEnd && ltrBegin != text.end()) { if(it == ltrEnd && ltrBegin != text.end()) {
if(ltrBegin == text.begin()) if(ltrBegin == text.begin())
break; break;
@@ -257,19 +257,22 @@ ITCM_CODE void Font::print(std::u16string_view text, int x, int y, bool top, int
*it >= 127))) { *it >= 127))) {
// Save where we are as the end of the LTR section // Save where we are as the end of the LTR section
ltrEnd = it + 1; ltrEnd = it + 1;
// Go back until an RTL character or the start of the string // Go back until an RTL character or the start of the string
while((*it < 0x0590 || *it > 0x05FF) && it != text.begin()) while((*it < 0x0590 || *it > 0x05FF) && it != text.begin())
it--; it--;
// Save where we are to return to after printing the LTR section // Save where we are to return to after printing the LTR section
ltrBegin = it; ltrBegin = it;
// If not at the start, then we're on the first RTL right now, so add one
if(it != text.begin()) // If on an RTL char right now, add one
if(*it >= 0x0590 && *it <= 0x05FF) {
it++; it++;
// Skip all punctuation at the end if not at beginning // And skip all punctuation at the end if not at beginning
while(it != text.begin() && while(*it < '0' || (*it > '9' && *it < 'A') || (*it > 'Z' && *it < 'a') || (*it > 'z' && *it < 127)) {
(*it < '0' || (*it > '9' && *it < 'A') || (*it > 'Z' && *it < 'a') || (*it > 'z' && *it < 127))) { it++;
it++; ltrBegin++;
ltrBegin++; }
} }
rtl = false; rtl = false;
} }