Copy over Arabic support from TWiLight

Currently not really needed, but if we make GM9i translatable (which I'll prolly do after this PR is merged) it'll be needed so might as well just do it now
This commit is contained in:
Pk11 2021-09-02 11:01:49 -05:00
parent d0122e0c12
commit 490b536bf2
2 changed files with 77 additions and 4 deletions

View File

@ -7,14 +7,20 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include<nds.h>
u8 Font::textBuf[2][256 * 192]; u8 Font::textBuf[2][256 * 192];
bool Font::mainScreen = false; bool Font::mainScreen = false;
Font *font = nullptr; Font *font = nullptr;
// Specifically the Arabic letters that have supported presentation forms
bool Font::isArabic(char16_t c) {
return c >= 0x0622 && c <= 0x064A;
}
bool Font::isStrongRTL(char16_t c) { bool Font::isStrongRTL(char16_t c) {
return (c >= 0x0590 && c <= 0x05FF) || c == 0x200F; // Hebrew, Arabic, or RLM
return (c >= 0x0590 && c <= 0x05FF) || (c >= 0x0600 && c <= 0x06FF) || c == 0x200F;
} }
bool Font::isWeak(char16_t c) { bool Font::isWeak(char16_t c) {
@ -25,6 +31,25 @@ bool Font::isNumber(char16_t c) {
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
char16_t Font::arabicForm(char16_t current, char16_t prev, char16_t next) {
if(isArabic(current)) {
// If previous should be connected to
if((prev >= 0x626 && prev <= 0x62E && prev != 0x627 && prev != 0x629) || (prev >= 0x633 && prev <= 0x64A && prev != 0x647)) {
if(isArabic(next)) // If next is arabic, medial
return arabicPresentationForms[current - 0x622][1];
else // If not, final
return arabicPresentationForms[current - 0x622][2];
} else {
if(isArabic(next)) // If next is arabic, initial
return arabicPresentationForms[current - 0x622][0];
else // If not, isolated
return current;
}
}
return current;
}
bool Font::load(const char *path) { bool Font::load(const char *path) {
FILE *file = fopen(path, "rb"); FILE *file = fopen(path, "rb");
@ -395,7 +420,7 @@ ITCM_CODE void Font::print(int xPos, int yPos, bool top, std::u16string_view tex
index = getCharIndex('<'); index = getCharIndex('<');
break; break;
default: default:
index = getCharIndex(*it); index = getCharIndex(arabicForm(*it, *(it - 1), *(it + 1)));
break; break;
} }
} else { } else {
@ -403,7 +428,7 @@ ITCM_CODE void Font::print(int xPos, int yPos, bool top, std::u16string_view tex
} }
// Don't draw off screen chars // Don't draw off screen chars
if(x >= 0 && y >= 0 && y + tileHeight <= 192) { if(x >= 0 && x + tileWidth <= 256 && y >= 0 && y + tileHeight <= 192) {
u8 *dst = textBuf[top] + x; u8 *dst = textBuf[top] + x;
for(int i = 0; i < tileHeight; i++) { for(int i = 0; i < tileHeight; i++) {
u8 px = fontTiles[(index * tileHeight) + i]; u8 px = fontTiles[(index * tileHeight) + i];

View File

@ -34,10 +34,58 @@ enum class Palette : u8 {
}; };
class Font { class Font {
constexpr static char16_t arabicPresentationForms[][3] = {
// Initial, Medial, Final
{u'آ', u'', u''}, // Alef with madda above
{u'أ', u'', u''}, // Alef with hamza above
{u'ؤ', u'', u''}, // Waw with hamza above
{u'إ', u'', u''}, // Alef with hamza below
{u'', u'', u''}, // Yeh with hamza above
{u'ا', u'', u''}, // Alef
{u'', u'', u''}, // Beh
{u'ة', u'', u''}, // Teh marbuta
{u'', u'', u''}, // Teh
{u'', u'', u''}, // Theh
{u'', u'', u''}, // Jeem
{u'', u'', u''}, // Hah
{u'', u'', u''}, // Khah
{u'د', u'', u''}, // Dal
{u'ذ', u'', u''}, // Thal
{u'ر', u'', u''}, // Reh
{u'ز', u'', u''}, // Zain
{u'', u'', u''}, // Seen
{u'', u'', u''}, // Sheen
{u'', u'', u''}, // Sad
{u'ﺿ', u'', u''}, // Dad
{u'', u'', u''}, // Tah
{u'', u'', u''}, // Zah
{u'', u'', u''}, // Ain
{u'', u'', u''}, // Ghain
{u'ػ', u'ػ', u'ػ'}, // Keheh with two dots above
{u'ؼ', u'ؼ', u'ؼ'}, // Keheh with three dots below
{u'ؽ', u'ؽ', u'ؽ'}, // Farsi yeh with inverted v
{u'ؾ', u'ؾ', u'ؾ'}, // Farsi yeh with two dots above
{u'ؿ', u'ؿ', u'ؿ'}, // Farsi yeh with three docs above
{u'ـ', u'ـ', u'ـ'}, // Tatweel
{u'', u'', u''}, // Feh
{u'', u'', u''}, // Qaf
{u'', u'', u''}, // Kaf
{u'', u'', u''}, // Lam
{u'', u'', u''}, // Meem
{u'', u'', u''}, // Noon
{u'', u'', u''}, // Heh
{u'و', u'', u''}, // Waw
{u'', u'', u''}, // Alef maksura
{u'', u'', u''}, // Yeh
};
static bool isArabic(char16_t c);
static bool isStrongRTL(char16_t c); static bool isStrongRTL(char16_t c);
static bool isWeak(char16_t c); static bool isWeak(char16_t c);
static bool isNumber(char16_t c); static bool isNumber(char16_t c);
static char16_t arabicForm(char16_t current, char16_t prev, char16_t next);
static constexpr u16 palette[16][2] = { static constexpr u16 palette[16][2] = {
{0x0000, 0x7FFF}, // White {0x0000, 0x7FFF}, // White
{0x0000, 0x3DEF}, // Gray {0x0000, 0x3DEF}, // Gray