diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e162bac..837232f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -66,11 +66,10 @@ IF(SDL2_FOUND) target_link_libraries(freerct ${SDL2_LIBRARY}) ENDIF() -find_package(SDL2_ttf REQUIRED) -# Legacy variable names -IF(SDL2_TTF_FOUND) - include_directories(${SDL2TTF_INCLUDE_DIR}) - target_link_libraries(freerct ${SDL2TTF_LIBRARY}) +find_package(Freetype REQUIRED) +IF(FREETYPE_FOUND) + include_directories(${FREETYPE_INCLUDE_DIRS}) + target_link_libraries(freerct ${FREETYPE_LIBRARIES}) ENDIF() # Translated messages are bad diff --git a/src/video.cpp b/src/video.cpp index 11141ad..c7f3f0f 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -185,29 +185,17 @@ std::string VideoSystem::Initialize(const char *font_name, int font_size) printf("Could not set window icon (%s)\n", SDL_GetError()); } - if (TTF_Init() != 0) { - SDL_Quit(); - delete[] this->mem; - std::string err = "TTF font initialization failed: "; - err += TTF_GetError(); - return err; + if (FT_Init_FreeType(&this->library) != 0) { } - this->font = TTF_OpenFont(font_name, font_size); - if (this->font == nullptr) { - std::string err = "TTF Opening font \""; - err += font_name; - err += "\" size "; - err += std::to_string(font_size); - err += " failed: "; - err += TTF_GetError(); - TTF_Quit(); - SDL_Quit(); - delete[] this->mem; - return err; + if (FT_New_Face(this->library, font_name, 0, &this->face) != 0) { + } + + /** @todo use actual screen dpi? */ + if (FT_Set_Char_Size(this->face, 0, font_size * 64, 0, 0) != 0) { } - this->font_height = TTF_FontLineSkip(this->font); + this->font_height = this->face->height / 64; this->initialized = true; this->dirty = true; // Ensure it gets painted. this->missing_sprites = false; @@ -454,8 +442,8 @@ void VideoSystem::MainLoop() void VideoSystem::Shutdown() { if (this->initialized) { - TTF_CloseFont(this->font); - TTF_Quit(); + FT_Done_Face(this->face); + FT_Done_FreeType(this->library); SDL_Quit(); delete[] this->mem; this->initialized = false; @@ -856,9 +844,29 @@ void VideoSystem::BlitImages(int32 x_base, int32 y_base, const ImageData *spr, u */ void VideoSystem::GetTextSize(const uint8 *text, int *width, int *height) { - if (TTF_SizeUTF8(this->font, (const char *)text, width, height) != 0) { - *width = 0; - *height = 0; + *width = 0; + *height = 0; + + bool use_kerning = FT_HAS_KERNING(this->face); + uint previous = 0; + FT_GlyphSlot slot = this->face->glyph; + + for (int n = 0; n < strlen((const char*)text); n++) { + uint glyph = FT_Get_Char_Index(this->face, text[n]); + + if (use_kerning && previous && glyph) { + FT_Vector delta; + FT_Get_Kerning(this->face, previous, glyph, FT_KERNING_DEFAULT, &delta); + + *width += delta.x / 64; + } + + if (FT_Load_Glyph(this->face, glyph, FT_LOAD_RENDER) != 0) { + } + *width += slot->advance.x / 64; + *height = std::max(*height, (int)slot->metrics.height / 64); + + previous = glyph; } } @@ -911,18 +919,37 @@ void VideoSystem::GetNumberRangeSize(int64 smallest, int64 biggest, int *width, */ void VideoSystem::BlitText(const uint8 *text, uint32 colour, int xpos, int ypos, int width, Alignment align) { - SDL_Color col = {0, 0, 0}; // Font colour does not matter as only the bitmap is used. - SDL_Surface *surf = TTF_RenderUTF8_Solid(this->font, (const char *)text, col); - if (surf == nullptr) { - fprintf(stderr, "Rendering text failed (%s)\n", TTF_GetError()); - return; - } + bool use_kerning = FT_HAS_KERNING(this->face); + uint previous = 0; + FT_GlyphSlot slot = this->face->glyph; - if (surf->format->BitsPerPixel != 8 || surf->format->BytesPerPixel != 1) { - fprintf(stderr, "Rendering text failed (Wrong surface format)\n"); - return; + for (int n = 0; n < strlen((const char*)tex); n++) { + uint glyph = FT_Get_Char_Index(this->face, tex[n]); + + if (use_kerning && previous && glyph) { + FT_Vector delta; + FT_Get_Kerning(this->face, previous, glyph, FT_KERNING_DEFAULT, &delta); + + } + + if (FT_Load_Glyph(this->face, glyph, FT_LOAD_RENDER) != 0) { + } + + for (int i = 0; i < slot->bitmap.rows; i++) { + for (int j = 0; j < slot->bitmap.pitch; j++) { + printf("%02x ", slot->bitmap.buffer[i * slot->bitmap.pitch + j]); + } + printf("\n"); + } + + printf("\n"); + + previous = glyph; } + SDL_Surface *surf = nullptr; + return; + int real_w = std::min(surf->w, width); switch (align) { case ALG_LEFT: diff --git a/src/video.h b/src/video.h index 6f435a9..f5bbb2b 100644 --- a/src/video.h +++ b/src/video.h @@ -13,8 +13,11 @@ #define VIDEO_H #include + #include -#include +#include +#include FT_FREETYPE_H + #include "geometry.h" #include "palette.h" @@ -160,7 +163,9 @@ private: bool initialized; ///< Video system is initialized. bool dirty; ///< Video display needs being repainted. - TTF_Font *font; ///< Opened text font. + FT_Library library; + FT_Face face; + SDL_Window *window; ///< %Window of the application. SDL_Renderer *renderer; ///< GPU renderer to the application window. SDL_Texture *texture; ///< GPU Texture storage of the application window.