Added option for fonts to be loaded from Windows

This restores some compatibility with Config.dat's font settings.
This commit is contained in:
Clownacy 2019-01-29 10:18:34 +00:00
parent 004d5adf7b
commit 90ef30bece
6 changed files with 264 additions and 144 deletions

View file

@ -20,8 +20,12 @@ ifeq ($(FIX_BUGS), 1)
CXXFLAGS += -DFIX_BUGS
endif
ifeq ($(CONSOLE), 1)
CXXFLAGS += -mconsole
ifeq ($(WINDOWS), 1)
ifeq ($(CONSOLE), 1)
CXXFLAGS += -mconsole
endif
CXXFLAGS += -DWINDOWS
LIBS += -lkernel32
endif
CXXFLAGS += `sdl2-config --cflags` `pkg-config freetype2 --cflags`

View file

@ -4,6 +4,18 @@
#include <stdio.h>
#include <stdint.h>
#ifdef WINDOWS
#define RECT WINRECT
#define FindResource WinFindResource // All these damn name collisions...
#define DrawText WinDrawText
#define LoadFont WinLoadFont
#include <windows.h>
#undef LoadFont
#undef DrawText
#undef FindResource
#undef RECT
#endif
#include <SDL_render.h>
#include <SDL_rwops.h>
#include <SDL_timer.h>
@ -388,7 +400,54 @@ void CortBox2(RECT *rect, uint32_t col, int surf_no)
SDL_SetRenderTarget(gRenderer, NULL);
}
void InitTextObject()
#ifdef WINDOWS
static unsigned char* GetFontFromWindows(size_t *data_size, const char *font_name, unsigned int fontWidth, unsigned int fontHeight)
{
unsigned char* buffer = NULL;
#ifdef JAPANESE
const DWORD charset = SHIFTJIS_CHARSET;
#else
const DWORD charset = DEFAULT_CHARSET;
#endif
HFONT hfont = CreateFontA(fontHeight, fontWidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, charset, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE, font_name);
if (hfont == NULL)
hfont = CreateFontA(fontHeight, fontWidth, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, charset, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE, NULL);
if (hfont != NULL)
{
HDC hdc = CreateCompatibleDC(NULL);
if (hdc != NULL)
{
SelectObject(hdc, hfont);
const DWORD size = GetFontData(hdc, 0, 0, NULL, 0);
if (size != GDI_ERROR)
{
buffer = new unsigned char[size];
if (data_size != NULL)
*data_size = size;
if (GetFontData(hdc, 0, 0, buffer, size) != size)
{
delete[] buffer;
buffer = NULL;
}
}
DeleteDC(hdc);
}
}
return buffer;
}
#endif
void InitTextObject(const char *font_name)
{
//Get font size
unsigned int fontWidth, fontHeight;
@ -403,6 +462,24 @@ void InitTextObject()
fontHeight = 10 * gWindowScale;
}
#ifdef WINDOWS
// Actually use the font Config.dat specifies
size_t data_size;
unsigned char *data = GetFontFromWindows(&data_size, font_name, fontWidth, fontHeight);
if (data != NULL)
{
gFont = LoadFontFromData(data, data_size, fontWidth, fontHeight);
delete[] data;
if (gFont)
return;
}
#endif
// Fall back on the built-in fonts
(void)font_name;
//Open Font.ttf
char path[PATH_LENGTH];
#ifdef JAPANESE
@ -411,7 +488,7 @@ void InitTextObject()
sprintf(path, "%s/cour.ttf", gDataPath);
#endif
gFont = LoadFont(fontWidth, fontHeight, path);
gFont = LoadFont(path, fontWidth, fontHeight);
}
void PutText(int x, int y, const char *text, uint32_t color)

View file

@ -66,7 +66,7 @@ void PutBitmap4(RECT *rcView, int x, int y, RECT *rect, int surf_no);
void Surface2Surface(int x, int y, RECT *rect, int to, int from);
void CortBox(RECT *rect, uint32_t col);
void CortBox2(RECT *rect, uint32_t col, int surf_no);
void InitTextObject();
void InitTextObject(const char *font_name);
void PutText(int x, int y, const char *text, uint32_t color);
void PutText2(int x, int y, const char *text, uint32_t color, int surf_no);
void EndTextObject();

View file

@ -2,7 +2,9 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef JAPANESE
#include <iconv.h>
@ -27,6 +29,7 @@ typedef struct FontObject
{
FT_Library library;
FT_Face face;
unsigned char *data;
#ifndef DISABLE_FONT_ANTIALIASING
bool lcd_mode;
#endif
@ -89,7 +92,7 @@ static unsigned long UTF8ToCode(const unsigned char *string, unsigned int *bytes
return charcode;
}
FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *font_filename)
FontObject* LoadFontFromData(const unsigned char *data, size_t data_size, unsigned int cell_width, unsigned int cell_height)
{
FontObject *font_object = (FontObject*)malloc(sizeof(FontObject));
@ -99,10 +102,19 @@ FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *fo
font_object->lcd_mode = FT_Library_SetLcdFilter(font_object->library, FT_LCD_FILTER_DEFAULT) != FT_Err_Unimplemented_Feature;
#endif
FT_New_Face(font_object->library, font_filename, 0, &font_object->face);
font_object->data = (unsigned char*)malloc(data_size);
memcpy(font_object->data, data, data_size);
FT_Error error = FT_New_Memory_Face(font_object->library, font_object->data, data_size, 0, &font_object->face);
if (error)
{
free(font_object->data);
FT_Done_FreeType(font_object->library);
free(font_object);
return NULL;
}
unsigned int best_cell_width = 0;
unsigned int best_cell_height = 0;
unsigned int best_pixel_width = 0;
unsigned int best_pixel_height = 0;
@ -120,15 +132,10 @@ FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *fo
else
{
if (current_cell_width <= cell_width)
{
best_pixel_width = i;
best_cell_width = current_cell_width;
}
if (current_cell_height <= cell_height)
{
best_pixel_height = i;
best_cell_height = current_cell_height;
}
}
}
@ -145,8 +152,33 @@ FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *fo
return font_object;
}
FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigned int cell_height)
{
FontObject *font_object = NULL;
FILE *file = fopen(font_filename, "rb");
if (file != NULL)
{
fseek(file, 0, SEEK_END);
const size_t file_size = ftell(file);
rewind(file);
unsigned char *file_buffer = (unsigned char*)malloc(file_size);
fread(file_buffer, 1, file_size, file);
fclose(file);
font_object = LoadFontFromData(file_buffer, file_size, cell_width, cell_height);
free(file_buffer);
}
return font_object;
}
void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *texture, int x, int y, unsigned long colour, const char *string, size_t string_length)
{
if (font_object != NULL)
{
const unsigned char colours[3] = {(unsigned char)(colour >> 16), (unsigned char)(colour >> 8), (unsigned char)colour};
SDL_Texture *old_render_target = SDL_GetRenderTarget(renderer);
@ -277,13 +309,19 @@ void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *text
SDL_RenderCopy(renderer, screen_texture, NULL, NULL);
SDL_DestroyTexture(screen_texture);
SDL_SetRenderTarget(renderer, old_render_target);
}
}
void UnloadFont(FontObject *font_object)
{
if (font_object != NULL)
{
#ifdef JAPANESE
iconv_close(font_object->conv);
#endif
FT_Done_Face(font_object->face);
free(font_object->data);
FT_Done_FreeType(font_object->library);
free(font_object);
}
}

View file

@ -6,6 +6,7 @@
typedef struct FontObject FontObject;
FontObject* LoadFont(unsigned int cell_width, unsigned int cell_height, char *font_filename);
FontObject* LoadFontFromData(const unsigned char *data, size_t data_size, unsigned int cell_width, unsigned int cell_height);
FontObject* LoadFont(const char *font_filename, unsigned int cell_width, unsigned int cell_height);
void DrawText(FontObject *font_object, SDL_Renderer *renderer, SDL_Texture *texture, int x, int y, unsigned long colour, const char *string, size_t string_length);
void UnloadFont(FontObject *font_object);

View file

@ -284,7 +284,7 @@ int main(int argc, char *argv[])
}
//Initialize stuff
InitTextObject();
InitTextObject(config.font_name);
InitTriangleTable();
//Run game code