diff options
Diffstat (limited to 'src/text.cxx')
-rw-r--r-- | src/text.cxx | 257 |
1 files changed, 172 insertions, 85 deletions
diff --git a/src/text.cxx b/src/text.cxx index 222c165..18cbbf4 100644 --- a/src/text.cxx +++ b/src/text.cxx @@ -1,7 +1,7 @@ /* * This file is part of the planetblupi source code * Copyright (C) 1997, Daniel Roux & EPSITEC SA - * Copyright (C) 2017-2018, Mathieu Schroeter + * Copyright (C) 2017-2019, Mathieu Schroeter * http://epsitec.ch; http://www.blupi.org; http://github.com/blupi-games * * This program is free software: you can redistribute it and/or modify @@ -34,56 +34,82 @@ * \param[in] c - The character (incremented if 0xC3 or 0xC4 or 0xC5 UTF-8). * \returns the offset. */ -static Sint32 +static Uint8 GetOffset (const char *& c) { /* clang-format off */ - static const unsigned char table_accents[] = { - /* ü à â é è ë ê ï */ - 0xBC, 0xA0, 0xA2, 0xA9, 0xA8, 0xAB, 0xAA, 0xAF, /* UTF-8 */ - /* î ô ù û ä ö ç */ - 0xAE, 0xB4, 0xB9, 0xBB, 0xA4, 0xB6, 0xA7, /* UTF-8 */ + static const unsigned char table_c3[] = { + /* ü à â é è ë ê ï */ + 0xBC, 0xA0, 0xA2, 0xA9, 0xA8, 0xAB, 0xAA, 0xAF, + /* î ô ù û ä ö ç ò */ + 0xAE, 0xB4, 0xB9, 0xBB, 0xA4, 0xB6, 0xA7, 0xB2, + /* ì ó Ç Ö Ü õ ã */ + 0xAC, 0xB3, 0x87, 0x96, 0x9C, 0xB5, 0xA3 }; - static const unsigned char table_extended[] = { - /* Italian */ - /* ò ì */ - 0xB2, 0xAC, /* UTF-8 */ - /* Polish */ - /* ń ó ę ć ź ż */ - 0x84, 0xB3, 0x99, 0x87, 0xBA, 0xBC, /* UTF-8 */ - /* ą ł ś */ - 0x85, 0x82, 0x9B, /* UTF-8 */ + static const unsigned char table_c4[] = { + /* ę ć ą Ğ ğ İ ı */ + 0x99, 0x87, 0x85, 0x9E, 0x9F, 0xB0, 0xB1, + }; + + static const unsigned char table_c5[] = { + /* ń ź ż ł ś Ş ş */ + 0x84, 0xBA, 0xBC, 0x82, 0x9B, 0x9E, 0x9F, + }; + + static const unsigned char table_d7[] = { + /*a ז ו ה ד ג ב א */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, + /*a מ ל ך כ י ט ח */ + 0x97, 0x98, 0x99, 0x9B, 0x9A, 0x9C, 0x9E, + /*a ף פ ע ס ן נ ם */ + 0x9D, 0xA0, 0x9F, 0xA1, 0xA2, 0xA4, 0xA3, + /*a ת ש ר ק ץ צ */ + 0xA6, 0xA5, 0xA7, 0xA8, 0xA9, 0xAA, }; /* clang-format on */ - if (static_cast<unsigned char> (*c) == 0xC3) - c++; - if (static_cast<unsigned char> (*c) == 0xC4) - c++; - if (static_cast<unsigned char> (*c) == 0xC5) - c++; + int offset = 0; + int inc = 0; + size_t size = 0; + const unsigned char * table = nullptr; - if (GetLocale () != "pl") + switch (static_cast<unsigned char> (*c)) { - // Do not use the 'standard' accents table with Polish locale - // This is required because we check only last byte of UTF-8 and some - // characters overlap - // TODO: In the future, this ugly hack should be replaced with proper UTF-8 - // parsing - for (unsigned int i = 0; i < countof (table_accents); ++i) - if ((unsigned char) *c == table_accents[i]) - return 15 + i; + case 0xC3: + offset = 128; + table = table_c3; + size = countof (table_c3); + inc = 1; + break; + case 0xC4: + offset = 128 + 32; + table = table_c4; + size = countof (table_c4); + inc = 1; + break; + case 0xC5: + offset = 128 + 64; + table = table_c5; + size = countof (table_c5); + inc = 1; + break; + case 0xD7: + offset = 128 + 96; + table = table_d7; + size = countof (table_d7); + inc = 1; + break; } - for (unsigned int i = 0; i < countof (table_extended); ++i) - if ((unsigned char) *c == table_extended[i]) - return 127 + i; + for (size_t i = 0; i < size; ++i) + if (static_cast<unsigned char> (*(c + inc)) == table[i]) + return offset + i; - if (*c < 0) + if (*(c + inc) < 0) return 1; // square - return *c; + return *(c + inc); } /** @@ -93,41 +119,54 @@ GetOffset (const char *& c) * \param[in] font - The font used (little or normal). * \returns the length. */ -Sint32 +Uint8 GetCharWidth (const char *& c, Sint32 font) { // clang-format off - static const unsigned char table_width[] = + static const Uint8 table_width[] = { - 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 8, - 9, 9, 8, 8, 8, 8, 5, 5, 8, 8, 8, 9, 8, 8, 10, 10, + 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 5, 6, 9, 13, 11, 12, 12, 6, 6, 6, 12, 12, 5, 9, 6, 9, 8, 8, 9, 9, 8, 9, 8, 8, 9, 9, 6, 6, 8, 9, 10, 11, 12, 8, 9, 9, 9, 8, 8, 8, 9, 4, 8, 9, 8, 10, 9, 9, 8, 9, 8, 9, 10, 8, 9, 11, 9, 8, 10, 7, 10, 7, 13, 13, 9, 9, 8, 8, 8, 8, 6, 8, 8, 4, 6, 8, 4, 12, 8, 8, - 8, 8, 7, 6, 7, 8, 8, 10, 8, 8, 7, 6, 6, 6, 10, 8, - 5, 8, 8, 8, 8, 8, 7, 9, 6, 7 + 8, 8, 7, 6, 7, 8, 8, 10, 8, 8, 7, 6, 6, 6, 10, 0, + 8, 9, 9, 8, 8, 8, 8, 5, 5, 8, 8, 8, 9, 8, 8, 8, + 5, 8, 9, 9, 8, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 9, 8, 8, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 8, 7, 6, 7, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 8, 8, 9, 5, 7, 9, 10, 6, 8, 8, 9, 10, 9, 6, + 7, 9, 9, 8, 9, 9, 10, 9, 8, 12, 10, 0, 0, 0, 0, 0, }; - static const unsigned char table_width_little[] = + static const Uint8 table_width_little[] = { - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 7, - 6, 6, 6, 6, 6, 6, 3, 3, 6, 6, 6, 6, 6, 6, 5, 5, - 3, 3, 5, 8, 5, 11, 9, 3, 4, 4, 6, 6, 3, 4, 3, 6, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 7, 6, 7, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, + 3, 2, 5, 8, 5, 11, 9, 2, 4, 4, 6, 6, 2, 4, 2, 6, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 7, 6, 7, 6, 9, 8, 6, 7, 7, 5, 5, 8, 7, 2, 4, 7, 5, 10, 7, 8, 6, 8, 7, 6, 6, 6, 8, 12, 7, 6, 6, 3, 5, 3, 6, 8, 4, 6, 6, 6, 6, 6, 4, 6, 6, 2, 3, 5, 2, 10, 6, 6, - 6, 6, 3, 5, 3, 6, 6, 8, 6, 6, 5, 4, 6, 4, 7, 6, - 3, 6, 6, 6, 5, 5, 5, 7, 4, 5 + 6, 6, 3, 5, 3, 6, 6, 8, 6, 6, 5, 4, 6, 4, 7, 0, + 7, 6, 6, 6, 6, 6, 6, 3, 3, 6, 6, 6, 6, 6, 6, 6, + 3, 6, 7, 8, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 5, 7, 8, 6, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 5, 5, 4, 5, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 7, 5, 6, 7, 2, 4, 7, 7, 3, 5, 7, 6, 7, 7, 4, + 3, 7, 7, 7, 8, 7, 6, 7, 7, 9, 8, 0, 0, 0, 0, 0, }; // clang-format on if (font == FONTLITTLE) return table_width_little[GetOffset (c)]; - else - return table_width[GetOffset (c)] - 1; + return table_width[GetOffset (c)] - 1; } /** @@ -137,50 +176,92 @@ GetCharWidth (const char *& c, Sint32 font) * \param[in] pos - The coordinates for the text. * \param[in] pText - The text. * \param[in] font - The font style (little or normal). + * \param[in] slope - Text slope. */ void -DrawText (CPixmap * pPixmap, Point pos, const char * pText, Sint32 font) +DrawText ( + CPixmap * pPixmap, Point pos, const char * pText, Sint32 font, Sint32 slope) { - Sint32 rank; - - while (*pText != '\0') + Sint32 rank; + bool isLatin = false; + int numberSize = 0; + const char * it = nullptr; + int skip = 0; + Sint32 start = pos.y; + Sint32 rel = 0; + + auto useD7 = strchr (pText, 0xD7) != nullptr; + auto isRightReading = useD7 && IsRightReading (); + auto length = strlen (pText); + + if (length >= 1 && !useD7 && IsRightReading ()) + pos.x -= GetTextWidth (pText, font); + + while (*pText != '\0' || skip) { + if (isRightReading && numberSize == 0) + { + const auto test = [](const char * text) -> bool { + return *text > ' ' && *text <= '~'; + }; + it = pText; + isLatin = test (pText); + if (isLatin) + { + while (test (pText)) + ++pText; + + numberSize = pText - it; + skip = numberSize - 1; + } + } + + if (numberSize) + { + pText = it + numberSize - 1; + numberSize--; + } + rank = GetOffset (pText); + if (isRightReading) + { + if (rank == '(') + rank = ')'; + else if (rank == ')') + rank = '('; + } + + auto inc = rank > 127; + auto lg = GetCharWidth (pText, font); + + if (isRightReading) + pos.x += -lg; + + rel += lg; + if (slope) + pos.y = start + rel / slope; + if (font != FONTLITTLE) { - rank += (128 + 16) * font; + rank += 256 * font; pPixmap->DrawIcon (-1, CHTEXT, rank, pos); } else pPixmap->DrawIcon (-1, CHLITTLE, rank, pos); - pos.x += GetCharWidth (pText, font); - pText++; - } -} - -// Affiche un texte penché. + if (!isRightReading) + pos.x += lg; -void -DrawTextPente ( - CPixmap * pPixmap, Point pos, const char * pText, Sint32 pente, Sint32 font) -{ - Sint32 rank, lg, rel, start; - - start = pos.y; - rel = 0; - while (*pText != 0) - { - rank = GetOffset (pText); - rank += (128 + 16) * font; - pPixmap->DrawIcon (-1, CHTEXT, rank, pos); + if (!numberSize && skip > 0) + { + pText += skip; + skip = 0; + } - lg = GetCharWidth (pText, font); + if (inc) + pText++; pText++; - rel += lg; - pos.x += lg; - pos.y = start + rel / pente; } } @@ -227,10 +308,7 @@ DrawTextRect ( continue; } - if (pente == 0) - DrawText (pPixmap, pos, pDest, font); - else - DrawTextPente (pPixmap, pos, pDest, pente, font); + DrawText (pPixmap, pos, pDest, font, pente); if (pDest[0] == 0) // ligne vide ? { @@ -253,6 +331,7 @@ DrawTextCenter (CPixmap * pPixmap, Point pos, const char * pText, Sint32 font) char * pDest; Sint32 itl; Point start; + auto isRightReading = IsRightReading (); if (font == FONTLITTLE) itl = DIMLITTLEY; @@ -270,8 +349,10 @@ DrawTextCenter (CPixmap * pPixmap, Point pos, const char * pText, Sint32 font) if (*pText == '\n') pText++; // saute '\n' - pDest = text; - start.x = pos.x - GetTextWidth (pDest) / 2; + pDest = text; + start.x = + pos.x + + (isRightReading ? GetTextWidth (pDest) : -GetTextWidth (pDest)) / 2; start.y = pos.y; DrawText (pPixmap, start, pDest, font); @@ -347,7 +428,13 @@ GetTextWidth (const char * pText, Sint32 font) while (*pText != 0) { + auto rank = GetOffset (pText); + auto inc = rank > 127; + width += GetCharWidth (pText, font); + + if (inc) + pText++; pText++; } |