GodMode9i/arm9/source/font.h
2021-11-22 21:02:13 -06:00

146 lines
4.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef FONT_H
#define FONT_H
#include "tonccpy.h"
#include <nds/arm9/background.h>
#include <nds/dma.h>
#include <nds/ndstypes.h>
#include <string>
#define TILE_MAX_WIDTH 8
#define TILE_MAX_HEIGHT 10
#define SCREEN_COLS (256 / font->width())
#define ENTRIES_PER_SCREEN ((192 - font->height()) / font->height())
enum class Alignment {
left,
center,
right,
};
enum class Palette : u8 {
white = 0,
gray,
red,
green,
greenAlt,
blue,
yellow,
blackRed,
blackGreen,
blackBlue,
};
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 isWeak(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] = {
{0x0000, 0x7FFF}, // White
{0x0000, 0x3DEF}, // Gray
{0x0000, 0x001F}, // Red
{0x0000, 0x03E0}, // Green
{0x0000, 0x02E0}, // Green (alt)
{0x0000, 0x656A}, // Blue
{0x0000, 0x3339}, // Yellow
{0x001F, 0x0000}, // Black on red
{0x03E0, 0x0000}, // Black on green
{0x656A, 0x0000}, // Black on blue
};
static u8 textBuf[2][256 * 192];
static bool mainScreen;
u8 tileWidth = 0, tileHeight = 0;
u16 tileCount = 0;
u16 questionMark = 0;
u8 *fontTiles = nullptr;
u16 *fontMap = nullptr;
bool load(const char *path);
u16 getCharIndex(char16_t c);
public:
static std::u16string utf8to16(std::string_view text);
static void update(bool top) { tonccpy(bgGetGfxPtr(top ? 2 : 6), Font::textBuf[top ^ mainScreen], 256 * 192); }
static void clear(bool top) { dmaFillWords(0, Font::textBuf[top ^ mainScreen], 256 * 192); }
static void mainOnTop(bool top) { mainScreen = !top; }
Font(const char *path);
~Font(void);
bool charExists(char16_t c) { return getCharIndex(c) != questionMark || c == '?'; }
u8 width(void) { return tileWidth; }
u8 height(void) { return tileHeight; }
int calcWidth(std::string_view text) { return utf8to16(text).length(); }
int calcWidth(std::u16string_view text) { return text.length(); };
int calcHeight(std::string_view text, int xPos = 0) { return calcHeight(utf8to16(text)); }
int calcHeight(std::u16string_view text, int xPos = 0);
void printf(int xPos, int yPos, bool top, Alignment align, Palette palette, const char *format, ...);
void print(int xPos, int yPos, bool top, int value, Alignment align = Alignment::left, Palette palette = Palette::white) { print(xPos, yPos, top, std::to_string(value), align, palette); }
void print(int xPos, int yPos, bool top, std::string_view text, Alignment align = Alignment::left, Palette palette = Palette::white) { print(xPos, yPos, top, utf8to16(text), align, palette); }
void print(int xPos, int yPos, bool top, std::u16string_view text, Alignment align = Alignment::left, Palette palette = Palette::white, bool rtl = false);
};
extern Font *font;
#endif // FONT_H