Merge pull request #7797 from Gymnasiast/extra-letters

Add sprite font glyphs for Æ and Ø
This commit is contained in:
Michael Steenbeek 2018-07-20 18:39:58 +02:00 committed by GitHub
commit 8cb7cc424c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 183 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

View File

@ -439,5 +439,80 @@
"path": "icons/eyedropper.png",
"x_offset": 5,
"y_offset": 5
},
{
"path": "font/ae-uc-small.png",
"y_offset": 0,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/ae-small.png",
"y_offset": 2,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/o-stroke-uc-small.png",
"x_offset": -1,
"y_offset": 0,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/o-stroke-small.png",
"y_offset": 2,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/ae-uc-bold.png",
"y_offset": 0,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/ae-bold.png",
"y_offset": 2,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/o-stroke-uc-bold.png",
"x_offset": -1,
"y_offset": -1,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/o-stroke-bold.png",
"x_offset": 0,
"y_offset": 2,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/ae-uc-tiny.png",
"y_offset": 0,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/ae-tiny.png",
"y_offset": 1,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/o-stroke-uc-tiny.png",
"y_offset": 0,
"palette": "keep",
"forceBmp": true
},
{
"path": "font/o-stroke-tiny.png",
"y_offset": 1,
"palette": "keep",
"forceBmp": true
}
]

View File

@ -246,12 +246,18 @@ static bool sprite_file_export(int32_t spriteIndex, const char *outPath)
}
}
static bool sprite_file_import(const char *path, int16_t x_offset, int16_t y_offset, bool keep_palette, rct_g1_element *outElement, uint8_t **outBuffer, int *outBufferLength, int32_t mode)
static bool sprite_file_import(const char *path, int16_t x_offset, int16_t y_offset, bool keep_palette, bool forceBmp, rct_g1_element *outElement, uint8_t **outBuffer, int *outBufferLength, int32_t mode)
{
try
{
auto format = IMAGE_FORMAT::PNG_32;
auto flags = ImageImporter::IMPORT_FLAGS::RLE;
auto flags = ImageImporter::IMPORT_FLAGS::NONE;
if (!forceBmp)
{
flags = (ImageImporter::IMPORT_FLAGS)ImageImporter::IMPORT_FLAGS::RLE;
}
if (keep_palette)
{
format = IMAGE_FORMAT::PNG;
@ -464,7 +470,7 @@ int32_t cmdline_for_sprite(const char **argv, int32_t argc)
uint8_t *buffer;
int32_t bufferLength;
if (!sprite_file_import(imagePath, x_offset, y_offset, false, &spriteElement, &buffer, &bufferLength, gSpriteMode))
if (!sprite_file_import(imagePath, x_offset, y_offset, false, false, &spriteElement, &buffer, &bufferLength, gSpriteMode))
return -1;
if (!sprite_file_open(spriteFilePath)) {
@ -558,6 +564,14 @@ int32_t cmdline_for_sprite(const char **argv, int32_t argc)
}
}
// Get forcebmp option, if present
bool forceBmp = false;
json_t* forceBmpObject = json_object_get(sprite_description, "forceBmp");
if (palette && json_is_boolean(forceBmpObject))
{
forceBmp = json_boolean_value(forceBmpObject);
}
// Resolve absolute sprite path
char *imagePath = platform_get_absolute_path(json_string_value(path), directoryPath);
@ -568,7 +582,7 @@ int32_t cmdline_for_sprite(const char **argv, int32_t argc)
if (!sprite_file_import(imagePath,
x_offset == nullptr ? 0 : json_integer_value(x_offset),
y_offset == nullptr ? 0 : json_integer_value(y_offset),
keep_palette, &spriteElement, &buffer, &bufferLength, gSpriteMode))
keep_palette, forceBmp, &spriteElement, &buffer, &bufferLength, gSpriteMode))
{
fprintf(stderr, "Could not import image file: %s\nCanceling\n", imagePath);
json_decref(sprite_list);

View File

@ -19,6 +19,7 @@
static constexpr const int32_t SpriteFontLineHeight[FONT_SIZE_COUNT] = { 6, 10, 10 };
static uint8_t _spriteFontCharacterWidths[FONT_SIZE_COUNT][FONT_SPRITE_GLYPH_COUNT];
static uint8_t _additionalSpriteFontCharacterWidth[FONT_SIZE_COUNT][SPR_G2_GLYPH_COUNT] = {};
#ifndef NO_TTF
TTFFontSetDescriptor *gCurrentTTFFontSet;
@ -46,6 +47,22 @@ void font_sprite_initialise_characters()
}
}
for (uint8_t fontSize : { FONT_SIZE_SMALL, FONT_SIZE_MEDIUM, FONT_SIZE_TINY })
{
int32_t glyphOffset = fontSize * SPR_G2_GLYPH_COUNT;
for (int32_t glyphIndex = 0; glyphIndex < SPR_G2_GLYPH_COUNT; glyphIndex++)
{
const rct_g1_element * g1 = gfx_get_g1_element(glyphIndex + SPR_G2_CHAR_BEGIN + glyphOffset);
int32_t width = 0;
if (g1 != nullptr)
{
width = g1->width + (2 * g1->x_offset) - 1;
}
_additionalSpriteFontCharacterWidth[fontSize][glyphIndex] = (uint8_t)width;
}
}
scrolling_text_initialise_bitmaps();
}
@ -107,6 +124,15 @@ int32_t font_sprite_get_codepoint_offset(int32_t codepoint)
// Render capital sharp-S (ẞ) with lowercase sprite (ß)
case UNICODE_CAPITAL_SHARP_S: return 223 - 32;
case UNICODE_AE_UC:
return SPR_G2_AE_UPPER - SPR_CHAR_START;
case UNICODE_O_STROKE_UC:
return SPR_G2_O_STROKE_UPPER - SPR_CHAR_START;
case UNICODE_AE:
return SPR_G2_AE_LOWER - SPR_CHAR_START;
case UNICODE_O_STROKE:
return SPR_G2_O_STROKE_LOWER - SPR_CHAR_START;
case UNICODE_DINGBATS_PLUS: return 11;
case UNICODE_DINGBATS_MINUS: return 13;
@ -126,7 +152,18 @@ int32_t font_sprite_get_codepoint_width(uint16_t fontSpriteBase, int32_t codepoi
int32_t glyphIndex = font_sprite_get_codepoint_offset(codepoint);
int32_t baseFontIndex = font_get_font_index_from_sprite_base(fontSpriteBase);
if (glyphIndex < 0 || glyphIndex >= (int32_t)FONT_SPRITE_GLYPH_COUNT)
if (glyphIndex >= FONT_SPRITE_GLYPH_COUNT)
{
glyphIndex = (SPR_CHAR_START + glyphIndex) - SPR_G2_CHAR_BEGIN;
if (glyphIndex >= (int32_t)Util::CountOf(_additionalSpriteFontCharacterWidth[baseFontIndex]))
{
log_warning("Invalid glyph index %u", glyphIndex);
glyphIndex = 0;
}
return _additionalSpriteFontCharacterWidth[baseFontIndex][glyphIndex];
}
else if (glyphIndex < 0 || glyphIndex >= (int32_t)FONT_SPRITE_GLYPH_COUNT)
{
log_warning("Invalid glyph index %u", glyphIndex);
glyphIndex = 0;
@ -136,7 +173,13 @@ int32_t font_sprite_get_codepoint_width(uint16_t fontSpriteBase, int32_t codepoi
int32_t font_sprite_get_codepoint_sprite(int32_t fontSpriteBase, int32_t codepoint)
{
return SPR_CHAR_START + (IMAGE_TYPE_REMAP | (fontSpriteBase + font_sprite_get_codepoint_offset(codepoint)));
auto codePointOffset = font_sprite_get_codepoint_offset(codepoint);
if (codePointOffset > FONT_SPRITE_GLYPH_COUNT)
{
fontSpriteBase = font_get_font_index_from_sprite_base(fontSpriteBase) * SPR_G2_GLYPH_COUNT;
}
return SPR_CHAR_START + (IMAGE_TYPE_REMAP | (fontSpriteBase + codePointOffset));
}
int32_t font_get_font_index_from_sprite_base(uint16_t spriteBase)

View File

@ -34,7 +34,7 @@ assert_struct_size(rct_draw_scroll_text, 0xA12);
#define MAX_SCROLLING_TEXT_ENTRIES 32
static rct_draw_scroll_text _drawScrollTextList[MAX_SCROLLING_TEXT_ENTRIES];
static uint8_t _characterBitmaps[FONT_SPRITE_GLYPH_COUNT][8];
static uint8_t _characterBitmaps[FONT_SPRITE_GLYPH_COUNT + SPR_G2_GLYPH_COUNT][8];
static uint32_t _drawSCrollNextIndex = 0;
static void scrolling_text_set_bitmap_for_sprite(utf8 *text, int32_t scroll, uint8_t *bitmap, const int16_t *scrollPositionOffsets);
@ -71,6 +71,23 @@ void scrolling_text_initialise_bitmaps()
}
}
for (int32_t i = 0; i < SPR_G2_GLYPH_COUNT; i++) {
memset(drawingSurface, 0, sizeof(drawingSurface));
gfx_draw_sprite_software(&dpi, SPR_G2_CHAR_BEGIN + (FONT_SIZE_TINY * SPR_G2_GLYPH_COUNT) + i, -1, 0, 0);
for (int32_t x = 0; x < 8; x++) {
uint8_t val = 0;
for (int32_t y = 0; y < 8; y++) {
val >>= 1;
uint8_t pixel = dpi.bits[x + y * 8];
if (pixel == 1 || (gTinyFontAntiAliased && pixel == 2)) {
val |= 0x80;
}
}
_characterBitmaps[FONT_SPRITE_GLYPH_COUNT + i][x] = val;
}
}
for (int32_t i = 0; i < MAX_SCROLLING_TEXT_ENTRIES; i++)
{
int32_t imageId = SPR_SCROLLING_TEXT_START + i;
@ -94,7 +111,15 @@ void scrolling_text_initialise_bitmaps()
static uint8_t *font_sprite_get_codepoint_bitmap(int32_t codepoint)
{
return _characterBitmaps[font_sprite_get_codepoint_offset(codepoint)];
auto offset = font_sprite_get_codepoint_offset(codepoint);
if (offset >= FONT_SPRITE_GLYPH_COUNT)
{
return _characterBitmaps[offset - (SPR_G2_CHAR_BEGIN - SPR_CHAR_START) + FONT_SPRITE_GLYPH_COUNT];
}
else
{
return _characterBitmaps[offset];
}
}

View File

@ -179,6 +179,14 @@ enum UnicodeGerman
UNICODE_CAPITAL_SHARP_S = 0x1E9E,
};
enum UnicodeNorwegianDanish
{
UNICODE_AE_UC = 198,
UNICODE_O_STROKE_UC = 216,
UNICODE_AE = 230,
UNICODE_O_STROKE = 248,
};
enum UnicodeDingbats
{
UNICODE_DINGBATS_PLUS = 0x2795,

View File

@ -840,6 +840,16 @@ enum {
SPR_G2_EYEDROPPER = SPR_G2_BEGIN + 123,
SPR_G2_CHAR_BEGIN = SPR_G2_BEGIN + 124,
SPR_G2_AE_UPPER = SPR_G2_CHAR_BEGIN,
SPR_G2_AE_LOWER = SPR_G2_CHAR_BEGIN + 1,
SPR_G2_O_STROKE_UPPER = SPR_G2_CHAR_BEGIN + 2,
SPR_G2_O_STROKE_LOWER = SPR_G2_CHAR_BEGIN + 3,
SPR_G2_CHAR_END = SPR_G2_O_STROKE_LOWER,
SPR_G2_GLYPH_COUNT = (SPR_G2_CHAR_END - SPR_G2_CHAR_BEGIN) + 1,
// 0x60000, chosen because it's a round hex number
// of the last possible range of image ID values that is large enough to fit all csg1 sprites.
SPR_CSG_BEGIN = 393216,