mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #5702 from IntelOrca/refactor/nosdl/freetype2
Remove SDL2_ttf dependency, replace with some code form SDL2_ttf without SDL2 dependencies and instead only requiring freetype alone.
This commit is contained in:
commit
89d43c1120
|
@ -26,6 +26,8 @@
|
|||
4C8B42721EEB1AE400F015CA /* HardwareDisplayDrawingEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B42711EEB1AE400F015CA /* HardwareDisplayDrawingEngine.cpp */; };
|
||||
4C8B42741EEB1B6F00F015CA /* Screenshot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B42731EEB1B6F00F015CA /* Screenshot.cpp */; };
|
||||
4CB832A71EFBDCCE00B88761 /* land_tool.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB832A51EFBDCCE00B88761 /* land_tool.c */; };
|
||||
4CB832AB1EFFB8D100B88761 /* ttf_sdlport.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB832A81EFFB8D100B88761 /* ttf_sdlport.c */; };
|
||||
4CB832AC1EFFB8D100B88761 /* ttf.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB832A91EFFB8D100B88761 /* ttf.c */; };
|
||||
C606CCBE1DB4054000FE4015 /* compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C606CCAB1DB4054000FE4015 /* compat.c */; };
|
||||
C606CCBF1DB4054000FE4015 /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = C606CCAC1DB4054000FE4015 /* data.c */; };
|
||||
C606CCC01DB4054000FE4015 /* FunctionCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C606CCAE1DB4054000FE4015 /* FunctionCall.cpp */; };
|
||||
|
@ -56,6 +58,7 @@
|
|||
C64FDAA71D6D9A2100F259B9 /* boat_ride.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9031CDBC3B7009F9BFC /* boat_ride.c */; };
|
||||
C64FDAA81D6D9A2100F259B9 /* dingy_slide.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9041CDBC3B7009F9BFC /* dingy_slide.c */; };
|
||||
C64FDAA91D6D9A2100F259B9 /* log_flume.c in Sources */ = {isa = PBXBuildFile; fileRef = C686F9051CDBC3B7009F9BFC /* log_flume.c */; };
|
||||
C6CB94F21EFFBF860065888F /* libfreetype.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B41CF3006400659A24 /* libfreetype.dylib */; };
|
||||
C6E96E361E0408B40076A04F /* libzip.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; };
|
||||
C6E96E371E040E040076A04F /* libzip.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D41B73EF1C2101890080A7B9 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41B73EE1C2101890080A7B9 /* libcurl.tbd */; };
|
||||
|
@ -64,7 +67,6 @@
|
|||
D43407E21D0E14CE00C2B3D4 /* shaders in Resources */ = {isa = PBXBuildFile; fileRef = D43407E11D0E14CE00C2B3D4 /* shaders */; };
|
||||
D45A38BC1CF3006400659A24 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B31CF3006400659A24 /* libcrypto.dylib */; };
|
||||
D45A38BE1CF3006400659A24 /* libjansson.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B51CF3006400659A24 /* libjansson.dylib */; };
|
||||
D45A38C01CF3006400659A24 /* libSDL2_ttf.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B71CF3006400659A24 /* libSDL2_ttf.dylib */; };
|
||||
D45A38C11CF3006400659A24 /* libSDL2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B81CF3006400659A24 /* libSDL2.dylib */; };
|
||||
D45A38C21CF3006400659A24 /* libspeexdsp.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B91CF3006400659A24 /* libspeexdsp.dylib */; };
|
||||
D45A39591CF300AF00659A24 /* libcrypto.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B31CF3006400659A24 /* libcrypto.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
|
@ -464,8 +466,6 @@
|
|||
F7D7749B1EC6705F00BE6EBC /* libspeexdsp.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B91CF3006400659A24 /* libspeexdsp.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
F7D7749C1EC6705F00BE6EBC /* libzip.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6E96E351E0408B40076A04F /* libzip.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
F7D7749E1EC6713200BE6EBC /* Cli.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F76C857D1EC4E80E00FA49E2 /* Cli.cpp */; };
|
||||
F7D7749F1EC6714C00BE6EBC /* libSDL2_ttf.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B71CF3006400659A24 /* libSDL2_ttf.dylib */; };
|
||||
F7D774A01EC6714C00BE6EBC /* libSDL2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B81CF3006400659A24 /* libSDL2.dylib */; };
|
||||
F7D774A11EC6715C00BE6EBC /* libSDL2_ttf.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B71CF3006400659A24 /* libSDL2_ttf.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
F7D774A21EC6715C00BE6EBC /* libSDL2.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D45A38B81CF3006400659A24 /* libSDL2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
F7D774AC1EC6741D00BE6EBC /* language in CopyFiles */ = {isa = PBXBuildFile; fileRef = D4EC48E41C2637710024B507 /* language */; };
|
||||
|
@ -573,6 +573,9 @@
|
|||
4C8B42731EEB1B6F00F015CA /* Screenshot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Screenshot.cpp; sourceTree = "<group>"; };
|
||||
4CB832A51EFBDCCE00B88761 /* land_tool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = land_tool.c; sourceTree = "<group>"; };
|
||||
4CB832A61EFBDCCE00B88761 /* land_tool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = land_tool.h; sourceTree = "<group>"; };
|
||||
4CB832A81EFFB8D100B88761 /* ttf_sdlport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttf_sdlport.c; sourceTree = "<group>"; };
|
||||
4CB832A91EFFB8D100B88761 /* ttf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttf.c; sourceTree = "<group>"; };
|
||||
4CB832AA1EFFB8D100B88761 /* ttf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttf.h; sourceTree = "<group>"; };
|
||||
C606CCAB1DB4054000FE4015 /* compat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = compat.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
C606CCAC1DB4054000FE4015 /* data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = data.c; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.c; };
|
||||
C606CCAD1DB4054000FE4015 /* data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = data.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
|
@ -1373,7 +1376,7 @@
|
|||
D45A38BE1CF3006400659A24 /* libjansson.dylib in Frameworks */,
|
||||
D4A8B4B41DB41873007A2F29 /* libpng16.dylib in Frameworks */,
|
||||
D45A38C11CF3006400659A24 /* libSDL2.dylib in Frameworks */,
|
||||
D45A38C01CF3006400659A24 /* libSDL2_ttf.dylib in Frameworks */,
|
||||
C6CB94F21EFFBF860065888F /* libfreetype.dylib in Frameworks */,
|
||||
D45A38C21CF3006400659A24 /* libspeexdsp.dylib in Frameworks */,
|
||||
C6E96E361E0408B40076A04F /* libzip.dylib in Frameworks */,
|
||||
);
|
||||
|
@ -1391,8 +1394,6 @@
|
|||
F7D774921EC66FBA00BE6EBC /* libfreetype.dylib in Frameworks */,
|
||||
F7D774931EC66FBA00BE6EBC /* libjansson.dylib in Frameworks */,
|
||||
F7D774941EC66FBA00BE6EBC /* libpng16.dylib in Frameworks */,
|
||||
F7D774A01EC6714C00BE6EBC /* libSDL2.dylib in Frameworks */,
|
||||
F7D7749F1EC6714C00BE6EBC /* libSDL2_ttf.dylib in Frameworks */,
|
||||
F7D774951EC66FBA00BE6EBC /* libspeexdsp.dylib in Frameworks */,
|
||||
F7D774961EC66FBA00BE6EBC /* libzip.dylib in Frameworks */,
|
||||
);
|
||||
|
@ -1899,6 +1900,9 @@
|
|||
F76C83AE1EC4E7CC00FA49E2 /* scrolling_text.c */,
|
||||
F76C83AF1EC4E7CC00FA49E2 /* sprite.cpp */,
|
||||
F76C83B01EC4E7CC00FA49E2 /* string.c */,
|
||||
4CB832A91EFFB8D100B88761 /* ttf.c */,
|
||||
4CB832AA1EFFB8D100B88761 /* ttf.h */,
|
||||
4CB832A81EFFB8D100B88761 /* ttf_sdlport.c */,
|
||||
4C8B426E1EEB1ABD00F015CA /* X8DrawingEngine.cpp */,
|
||||
4C8B426F1EEB1ABD00F015CA /* X8DrawingEngine.h */,
|
||||
);
|
||||
|
@ -2815,7 +2819,7 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "version=\"11\"\nzipname=\"openrct2-libs-macos.zip\"\nliburl=\"https://github.com/OpenRCT2/Dependencies/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/libxc\" || ! -e \"${SRCROOT}/libversion\" || $(head -n 1 \"${SRCROOT}/libversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/libxc\" ]]; then rm -r \"${SRCROOT}/libxc\"; fi\nmkdir \"${SRCROOT}/libxc\"\n\ncurl -L -o \"${SRCROOT}/libxc/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/libxc\" \"${SRCROOT}/libxc/$zipname\"\nrm \"${SRCROOT}/libxc/$zipname\"\n\necho $version > \"${SRCROOT}/libversion\"\nfi";
|
||||
shellScript = "version=\"12\"\nzipname=\"openrct2-libs-macos.zip\"\nliburl=\"https://github.com/OpenRCT2/Dependencies/releases/download/v$version/$zipname\"\n\n[[ ! -d \"${SRCROOT}/libxc\" || ! -e \"${SRCROOT}/libversion\" || $(head -n 1 \"${SRCROOT}/libversion\") != $version ]]\noutdated=$?\n\nif [[ $outdated -eq 0 ]]; then\nif [[ -d \"${SRCROOT}/libxc\" ]]; then rm -r \"${SRCROOT}/libxc\"; fi\nmkdir \"${SRCROOT}/libxc\"\n\ncurl -L -o \"${SRCROOT}/libxc/$zipname\" \"$liburl\"\nunzip -uaq -d \"${SRCROOT}/libxc\" \"${SRCROOT}/libxc/$zipname\"\nrm \"${SRCROOT}/libxc/$zipname\"\n\necho $version > \"${SRCROOT}/libversion\"\nfi";
|
||||
};
|
||||
D42C09D21C254F4E00309751 /* Build g2.dat */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
|
@ -2974,11 +2978,13 @@
|
|||
4C8B42741EEB1B6F00F015CA /* Screenshot.cpp in Sources */,
|
||||
F76C88781EC5324E00FA49E2 /* AudioChannel.cpp in Sources */,
|
||||
F76C88791EC5324E00FA49E2 /* AudioContext.cpp in Sources */,
|
||||
4CB832AC1EFFB8D100B88761 /* ttf.c in Sources */,
|
||||
4C8B42721EEB1AE400F015CA /* HardwareDisplayDrawingEngine.cpp in Sources */,
|
||||
F76C887A1EC5324E00FA49E2 /* AudioMixer.cpp in Sources */,
|
||||
F76C887B1EC5324E00FA49E2 /* FileAudioSource.cpp in Sources */,
|
||||
F7CB864D1EEDA1A80030C877 /* DummyWindowManager.cpp in Sources */,
|
||||
F76C887C1EC5324E00FA49E2 /* MemoryAudioSource.cpp in Sources */,
|
||||
4CB832AB1EFFB8D100B88761 /* ttf_sdlport.c in Sources */,
|
||||
F76C887D1EC5324E00FA49E2 /* CursorData.cpp in Sources */,
|
||||
4CB832A71EFBDCCE00B88761 /* land_tool.c in Sources */,
|
||||
F7D7747F1EC61E5100BE6EBC /* UiContext.macOS.mm in Sources */,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<Version>0.0.8</Version>
|
||||
<VersionExtra Condition="'$(GIT_BRANCH)'!=''">-$(GIT_BRANCH)-$(GIT_COMMIT_SHA1_SHORT)</VersionExtra>
|
||||
<VersionExtra Condition="'$(GIT_TAG)'!=''"></VersionExtra>
|
||||
<TargetLibsVersion>11</TargetLibsVersion>
|
||||
<TargetLibsVersion>12</TargetLibsVersion>
|
||||
|
||||
<!-- Set dynamic OpenRCT2 #defines -->
|
||||
<OPENRCT2_CL_ADDITIONALOPTIONS Condition="'$(BUILD_SERVER)'!=''">/D "OPENRCT2_BUILD_SERVER=\"$(BUILD_SERVER)\"" $(OPENRCT2_CL_ADDITIONALOPTIONS)</OPENRCT2_CL_ADDITIONALOPTIONS>
|
||||
|
@ -64,7 +64,7 @@
|
|||
<PropertyGroup>
|
||||
<DependenciesCheckFile>$(RootDir).dependencies</DependenciesCheckFile>
|
||||
<LibsUrl>https://github.com/OpenRCT2/Dependencies/releases/download/v$(TargetLibsVersion)/openrct2-libs-vs2015.zip</LibsUrl>
|
||||
<LibsSha1>f088adcd12450c2672f78679ea5d1fbffc28fd22</LibsSha1>
|
||||
<LibsSha1>f845fe2fad0a1dece905c42ac4cfc1234ec447a7</LibsSha1>
|
||||
<GtestVersion>1.8.0</GtestVersion>
|
||||
<GtestUrl>https://github.com/google/googletest/archive/release-1.8.0.zip</GtestUrl>
|
||||
<GtestSha1>667f873ab7a4d246062565fad32fb6d8e203ee73</GtestSha1>
|
||||
|
|
|
@ -48,7 +48,6 @@ add_executable(${PROJECT} ${OPENRCT2_UI_SOURCES} ${OPENRCT2_UI_M_SOURCES} ${OPEN
|
|||
|
||||
target_link_libraries(${PROJECT} "libopenrct2"
|
||||
${SDL2_LIBRARIES}
|
||||
${SDL2_TTF_LIBRARIES}
|
||||
${SPEEX_LIBRARIES})
|
||||
|
||||
if (APPLE)
|
||||
|
|
|
@ -14,7 +14,7 @@ option(DISABLE_RCT2 "Build a standalone version, without using code and data seg
|
|||
|
||||
option(DISABLE_HTTP_TWITCH "Disable HTTP and Twitch support.")
|
||||
option(DISABLE_NETWORK "Disable multiplayer functionality. Mainly for testing.")
|
||||
option(DISABLE_TTF "Disable support for TTF provided by SDL2_ttf.")
|
||||
option(DISABLE_TTF "Disable support for TTF provided by freetype2.")
|
||||
option(ENABLE_LIGHTFX "Enable lighting effects." ON)
|
||||
|
||||
if (NOT DISABLE_RCT2)
|
||||
|
@ -59,14 +59,10 @@ endif ()
|
|||
PKG_CHECK_MODULES(SDL2 REQUIRED sdl2)
|
||||
PKG_CHECK_MODULES(SPEEX REQUIRED speexdsp)
|
||||
if (NOT DISABLE_TTF)
|
||||
if (STATIC)
|
||||
# FreeType is required by SDL2_ttf, but not wired up properly in package
|
||||
PKG_CHECK_MODULES(FREETYPE REQUIRED freetype2)
|
||||
endif ()
|
||||
if (UNIX AND NOT APPLE)
|
||||
PKG_CHECK_MODULES(FONTCONFIG REQUIRED fontconfig)
|
||||
endif ()
|
||||
PKG_CHECK_MODULES(SDL2_TTF REQUIRED SDL2_ttf)
|
||||
PKG_CHECK_MODULES(FREETYPE REQUIRED freetype2)
|
||||
endif ()
|
||||
|
||||
# Sources
|
||||
|
@ -189,13 +185,12 @@ endif ()
|
|||
|
||||
if (NOT DISABLE_TTF)
|
||||
if (STATIC)
|
||||
target_link_libraries(${PROJECT} ${FREETYPE_STATIC_LIBRARIES}
|
||||
${SDL2_TTF_STATIC_LIBRARIES})
|
||||
target_link_libraries(${PROJECT} ${FREETYPE_STATIC_LIBRARIES})
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(${PROJECT} ${FONTCONFIG_STATIC_LIBRARIES})
|
||||
endif ()
|
||||
else ()
|
||||
target_link_libraries(${PROJECT} ${SDL2_TTF_LIBRARIES})
|
||||
target_link_libraries(${PROJECT} ${FREETYPE_LIBRARIES})
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(${PROJECT} ${FONTCONFIG_LIBRARIES})
|
||||
endif ()
|
||||
|
@ -210,6 +205,7 @@ endif()
|
|||
# Includes
|
||||
target_include_directories(${PROJECT} SYSTEM PRIVATE ${LIBZIP_INCLUDE_DIRS})
|
||||
target_include_directories(${PROJECT} PRIVATE ${SDL2_INCLUDE_DIRS}
|
||||
${FREETYPE_INCLUDE_DIRS}
|
||||
${JANSSON_INCLUDE_DIRS}
|
||||
${SPEEX_INCLUDE_DIRS}
|
||||
${PNG_INCLUDE_DIRS}
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
#include "../interface/colour.h"
|
||||
#include "font.h"
|
||||
|
||||
typedef struct SDL_Surface SDL_Surface;
|
||||
|
||||
// For g1 only enable packing when still relying on vanilla
|
||||
#ifndef NO_RCT2
|
||||
#pragma pack(push, 1)
|
||||
|
@ -360,13 +358,6 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, sint32 x, s
|
|||
void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, sint32 colour, sint32 x, sint32 y, const sint8 *yOffsets, bool forceSpriteFont);
|
||||
sint32 gfx_clip_string(char* buffer, sint32 width);
|
||||
void shorten_path(utf8 *buffer, size_t bufferSize, const utf8 *path, sint32 availableWidth);
|
||||
#ifndef NO_TTF
|
||||
SDL_Surface *ttf_surface_cache_get_or_add(TTF_Font *font, const utf8 *text);
|
||||
TTFFontDescriptor *ttf_get_font_from_sprite_base(uint16 spriteBase);
|
||||
#endif // NO_TTF
|
||||
|
||||
bool ttf_initialise();
|
||||
void ttf_dispose();
|
||||
|
||||
// scrolling text
|
||||
void scrolling_text_initialise_bitmaps();
|
||||
|
|
|
@ -14,15 +14,12 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#ifndef NO_TTF
|
||||
#include "../common.h"
|
||||
#include <SDL_ttf.h>
|
||||
#endif
|
||||
#include "../rct2/addresses.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../sprites.h"
|
||||
#include "drawing.h"
|
||||
#include "font.h"
|
||||
#include "ttf.h"
|
||||
|
||||
static const sint32 SpriteFontLineHeight[] = { 6, 10, 10, 18 };
|
||||
|
||||
|
@ -209,7 +206,7 @@ bool font_supports_string_ttf(const utf8 *text, sint32 fontSize)
|
|||
|
||||
uint32 codepoint;
|
||||
while ((codepoint = utf8_get_next(src, &src)) != 0) {
|
||||
bool supported = TTF_GlyphIsProvided(font, (uint16)codepoint);
|
||||
bool supported = ttf_provides_glyph(font, codepoint);
|
||||
if (!supported) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
#ifndef _DRAWING_FONT_H_
|
||||
#define _DRAWING_FONT_H_
|
||||
|
||||
#ifndef NO_TTF
|
||||
typedef struct _TTF_Font TTF_Font;
|
||||
#endif // NO_TTF
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
enum {
|
||||
|
@ -43,6 +39,8 @@ enum {
|
|||
};
|
||||
|
||||
#ifndef NO_TTF
|
||||
|
||||
typedef struct _TTF_Font TTF_Font;
|
||||
typedef struct TTFFontDescriptor {
|
||||
const utf8 *filename;
|
||||
const utf8 *font_name;
|
||||
|
@ -50,7 +48,7 @@ typedef struct TTFFontDescriptor {
|
|||
sint32 offset_x;
|
||||
sint32 offset_y;
|
||||
sint32 line_height;
|
||||
TTF_Font *font;
|
||||
TTF_Font * font;
|
||||
} TTFFontDescriptor;
|
||||
|
||||
typedef struct TTFFontSetDescriptor {
|
||||
|
|
|
@ -14,16 +14,13 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#ifndef NO_TTF
|
||||
#include "../common.h"
|
||||
#include <SDL_ttf.h>
|
||||
#endif
|
||||
#include "../rct2/addresses.h"
|
||||
#include "../config/Config.h"
|
||||
#include "../interface/colour.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../sprites.h"
|
||||
#include "drawing.h"
|
||||
#include "ttf.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
/* size: 0xA12 */
|
||||
|
@ -1543,19 +1540,15 @@ void scrolling_text_set_bitmap_for_ttf(utf8 *text, sint32 scroll, uint8 *bitmap,
|
|||
colour = g1Elements[SPR_TEXT_PALETTE].offset[(colour - FORMAT_COLOUR_CODE_START) * 4];
|
||||
}
|
||||
|
||||
SDL_Surface *surface = ttf_surface_cache_get_or_add(fontDesc->font, text);
|
||||
TTFSurface * surface = ttf_surface_cache_get_or_add(fontDesc->font, text);
|
||||
if (surface == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface) && SDL_LockSurface(surface) == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
sint32 pitch = surface->pitch;
|
||||
sint32 width = surface->w;
|
||||
sint32 height = surface->h;
|
||||
uint8 *src = surface->pixels;
|
||||
const uint8 *src = surface->pixels;
|
||||
|
||||
// Offset
|
||||
height -= 3;
|
||||
|
@ -1586,7 +1579,5 @@ void scrolling_text_set_bitmap_for_ttf(utf8 *text, sint32 scroll, uint8 *bitmap,
|
|||
x++;
|
||||
if (x >= width) x = 0;
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
|
||||
#endif // NO_TTF
|
||||
}
|
||||
|
|
|
@ -14,16 +14,13 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#ifndef NO_TTF
|
||||
#include "../common.h"
|
||||
#include <SDL_ttf.h>
|
||||
#endif
|
||||
#include "../interface/colour.h"
|
||||
#include "../interface/viewport.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../sprites.h"
|
||||
#include "../util/util.h"
|
||||
#include "ttf.h"
|
||||
|
||||
enum {
|
||||
TEXT_DRAW_FLAG_INSET = 1 << 0,
|
||||
|
@ -31,46 +28,13 @@ enum {
|
|||
TEXT_DRAW_FLAG_DARK = 1 << 2,
|
||||
TEXT_DRAW_FLAG_EXTRA_DARK = 1 << 3,
|
||||
TEXT_DRAW_FLAG_Y_OFFSET_EFFECT = 1 << 29,
|
||||
#ifndef NO_TTF
|
||||
TEXT_DRAW_FLAG_TTF = 1 << 30,
|
||||
#endif // NO_TTF
|
||||
TEXT_DRAW_FLAG_NO_DRAW = 1u << 31
|
||||
};
|
||||
|
||||
static sint32 ttf_get_string_width(const utf8 *text);
|
||||
static void ttf_draw_string(rct_drawpixelinfo *dpi, char *buffer, sint32 colour, sint32 x, sint32 y);
|
||||
|
||||
#ifndef NO_TTF
|
||||
static bool _ttfInitialised = false;
|
||||
|
||||
#define TTF_SURFACE_CACHE_SIZE 256
|
||||
#define TTF_GETWIDTH_CACHE_SIZE 1024
|
||||
|
||||
typedef struct ttf_cache_entry {
|
||||
SDL_Surface *surface;
|
||||
TTF_Font *font;
|
||||
utf8 *text;
|
||||
uint32 lastUseTick;
|
||||
} ttf_cache_entry;
|
||||
|
||||
static ttf_cache_entry _ttfSurfaceCache[TTF_SURFACE_CACHE_SIZE] = { 0 };
|
||||
static sint32 _ttfSurfaceCacheCount = 0;
|
||||
static sint32 _ttfSurfaceCacheHitCount = 0;
|
||||
static sint32 _ttfSurfaceCacheMissCount = 0;
|
||||
|
||||
typedef struct ttf_getwidth_cache_entry {
|
||||
uint32 width;
|
||||
TTF_Font *font;
|
||||
utf8 *text;
|
||||
uint32 lastUseTick;
|
||||
} ttf_getwidth_cache_entry;
|
||||
|
||||
static ttf_getwidth_cache_entry _ttfGetWidthCache[TTF_GETWIDTH_CACHE_SIZE] = { 0 };
|
||||
static sint32 _ttfGetWidthCacheCount = 0;
|
||||
static sint32 _ttfGetWidthCacheHitCount = 0;
|
||||
static sint32 _ttfGetWidthCacheMissCount = 0;
|
||||
#endif // NO_TTF
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006C23B1
|
||||
|
@ -711,206 +675,6 @@ void gfx_draw_string_centred_wrapped_partial(rct_drawpixelinfo *dpi, sint32 x, s
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef NO_TTF
|
||||
static uint32 _ttf_surface_cache_hash(TTF_Font *font, const utf8 *text)
|
||||
{
|
||||
uint32 hash = (uint32)((((uintptr_t)font * 23) ^ 0xAAAAAAAA) & 0xFFFFFFFF);
|
||||
for (const utf8 *ch = text; *ch != 0; ch++) {
|
||||
hash = ror32(hash, 3) ^ (*ch * 13);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void _ttf_surface_cache_dispose(ttf_cache_entry *entry)
|
||||
{
|
||||
if (entry->surface != NULL) {
|
||||
SDL_FreeSurface(entry->surface);
|
||||
free(entry->text);
|
||||
|
||||
entry->surface = NULL;
|
||||
entry->font = NULL;
|
||||
entry->text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void _ttf_surface_cache_dispose_all()
|
||||
{
|
||||
for (sint32 i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) {
|
||||
_ttf_surface_cache_dispose(&_ttfSurfaceCache[i]);
|
||||
_ttfSurfaceCacheCount--;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface *ttf_surface_cache_get_or_add(TTF_Font *font, const utf8 *text)
|
||||
{
|
||||
ttf_cache_entry *entry;
|
||||
|
||||
uint32 hash = _ttf_surface_cache_hash(font, text);
|
||||
sint32 index = hash % TTF_SURFACE_CACHE_SIZE;
|
||||
for (sint32 i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) {
|
||||
entry = &_ttfSurfaceCache[index];
|
||||
|
||||
// Check if entry is a hit
|
||||
if (entry->surface == NULL) break;
|
||||
if (entry->font == font && strcmp(entry->text, text) == 0) {
|
||||
_ttfSurfaceCacheHitCount++;
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->surface;
|
||||
}
|
||||
|
||||
// If entry hasn't been used for a while, replace it
|
||||
if (entry->lastUseTick < gCurrentDrawCount - 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if next entry is a hit
|
||||
if (++index >= TTF_SURFACE_CACHE_SIZE) index = 0;
|
||||
}
|
||||
|
||||
// Cache miss, replace entry with new surface
|
||||
entry = &_ttfSurfaceCache[index];
|
||||
_ttf_surface_cache_dispose(entry);
|
||||
|
||||
SDL_Color c = { 0, 0, 0, 255 };
|
||||
SDL_Surface *surface = TTF_RenderUTF8_Solid(font, text, c);
|
||||
if (surface == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_ttfSurfaceCacheMissCount++;
|
||||
// printf("CACHE HITS: %d MISSES: %d)\n", _ttfSurfaceCacheHitCount, _ttfSurfaceCacheMissCount);
|
||||
|
||||
_ttfSurfaceCacheCount++;
|
||||
entry->surface = surface;
|
||||
entry->font = font;
|
||||
entry->text = _strdup(text);
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->surface;
|
||||
}
|
||||
|
||||
static void _ttf_getwidth_cache_dispose(ttf_getwidth_cache_entry *entry)
|
||||
{
|
||||
if (entry->text != NULL) {
|
||||
free(entry->text);
|
||||
|
||||
entry->width = 0;
|
||||
entry->font = NULL;
|
||||
entry->text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void _ttf_getwidth_cache_dispose_all()
|
||||
{
|
||||
for (sint32 i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) {
|
||||
_ttf_getwidth_cache_dispose(&_ttfGetWidthCache[i]);
|
||||
_ttfGetWidthCacheCount--;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 _ttf_getwidth_cache_get_or_add(TTF_Font *font, const utf8 *text)
|
||||
{
|
||||
ttf_getwidth_cache_entry *entry;
|
||||
|
||||
uint32 hash = _ttf_surface_cache_hash(font, text);
|
||||
sint32 index = hash % TTF_GETWIDTH_CACHE_SIZE;
|
||||
for (sint32 i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) {
|
||||
entry = &_ttfGetWidthCache[index];
|
||||
|
||||
// Check if entry is a hit
|
||||
if (entry->text == NULL) break;
|
||||
if (entry->font == font && strcmp(entry->text, text) == 0) {
|
||||
_ttfGetWidthCacheHitCount++;
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->width;
|
||||
}
|
||||
|
||||
// If entry hasn't been used for a while, replace it
|
||||
if (entry->lastUseTick < gCurrentDrawCount - 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if next entry is a hit
|
||||
if (++index >= TTF_GETWIDTH_CACHE_SIZE) index = 0;
|
||||
}
|
||||
|
||||
// Cache miss, replace entry with new width
|
||||
entry = &_ttfGetWidthCache[index];
|
||||
_ttf_getwidth_cache_dispose(entry);
|
||||
|
||||
sint32 width, height;
|
||||
TTF_SizeUTF8(font, text, &width, &height);
|
||||
|
||||
_ttfGetWidthCacheMissCount++;
|
||||
|
||||
_ttfGetWidthCacheCount++;
|
||||
entry->width = width;
|
||||
entry->font = font;
|
||||
entry->text = _strdup(text);
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->width;
|
||||
}
|
||||
|
||||
bool ttf_initialise()
|
||||
{
|
||||
if (!_ttfInitialised) {
|
||||
if (TTF_Init() != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (sint32 i = 0; i < 4; i++) {
|
||||
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
|
||||
utf8 fontPath[MAX_PATH];
|
||||
if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) {
|
||||
log_error("Unable to load font '%s'", fontDesc->font_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
fontDesc->font = TTF_OpenFont(fontPath, fontDesc->ptSize);
|
||||
if (fontDesc->font == NULL) {
|
||||
log_error("Unable to load '%s'", fontPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_ttfInitialised = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ttf_dispose()
|
||||
{
|
||||
if (!_ttfInitialised)
|
||||
return;
|
||||
|
||||
_ttf_surface_cache_dispose_all();
|
||||
_ttf_getwidth_cache_dispose_all();
|
||||
|
||||
for (sint32 i = 0; i < 4; i++) {
|
||||
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
if (fontDesc->font != NULL) {
|
||||
TTF_CloseFont(fontDesc->font);
|
||||
fontDesc->font = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TTF_Quit();
|
||||
_ttfInitialised = false;
|
||||
}
|
||||
|
||||
TTFFontDescriptor *ttf_get_font_from_sprite_base(uint16 spriteBase)
|
||||
{
|
||||
return &gCurrentTTFFontSet->size[font_get_size_from_sprite_base(spriteBase)];
|
||||
}
|
||||
#else
|
||||
bool ttf_initialise()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void ttf_dispose() {}
|
||||
#endif // NO_TTF
|
||||
|
||||
typedef struct text_draw_info {
|
||||
sint32 startX;
|
||||
sint32 startY;
|
||||
|
@ -954,9 +718,10 @@ static void ttf_draw_string_raw_sprite(rct_drawpixelinfo *dpi, const utf8 *text,
|
|||
}
|
||||
|
||||
#ifndef NO_TTF
|
||||
|
||||
static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info)
|
||||
{
|
||||
if (!_ttfInitialised && !ttf_initialise())
|
||||
if (!ttf_initialise())
|
||||
return;
|
||||
|
||||
TTFFontDescriptor *fontDesc = ttf_get_font_from_sprite_base(info->font_sprite_base);
|
||||
|
@ -966,20 +731,14 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
|
|||
}
|
||||
|
||||
if (info->flags & TEXT_DRAW_FLAG_NO_DRAW) {
|
||||
info->x += _ttf_getwidth_cache_get_or_add(fontDesc->font, text);
|
||||
info->x += ttf_getwidth_cache_get_or_add(fontDesc->font, text);
|
||||
return;
|
||||
} else {
|
||||
uint8 colour = info->palette[1];
|
||||
SDL_Surface *surface = ttf_surface_cache_get_or_add(fontDesc->font, text);
|
||||
TTFSurface * surface = ttf_surface_cache_get_or_add(fontDesc->font, text);
|
||||
if (surface == NULL)
|
||||
return;
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
if (SDL_LockSurface(surface) != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sint32 drawX = info->x + fontDesc->offset_x;
|
||||
sint32 drawY = info->y + fontDesc->offset_y;
|
||||
sint32 width = surface->w;
|
||||
|
@ -993,7 +752,7 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
|
|||
sint32 skipY = drawY - dpi->y;
|
||||
info->x += width;
|
||||
|
||||
uint8 *src = surface->pixels;
|
||||
const uint8 *src = surface->pixels;
|
||||
uint8 *dst = dpi->bits;
|
||||
|
||||
if (skipX < 0) {
|
||||
|
@ -1013,7 +772,7 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
|
|||
sint32 srcScanSkip = surface->pitch - width;
|
||||
sint32 dstScanSkip = dpi->width + dpi->pitch - width;
|
||||
uint8 *dst_orig = dst;
|
||||
uint8 *src_orig = src;
|
||||
const uint8 *src_orig = src;
|
||||
|
||||
// Draw shadow/outline
|
||||
if (info->flags & TEXT_DRAW_FLAG_OUTLINE) {
|
||||
|
@ -1051,12 +810,9 @@ static void ttf_draw_string_raw_ttf(rct_drawpixelinfo *dpi, const utf8 *text, te
|
|||
dst += dstScanSkip;
|
||||
}
|
||||
}
|
||||
|
||||
if (SDL_MUSTLOCK(surface)) {
|
||||
SDL_UnlockSurface(surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NO_TTF
|
||||
|
||||
static void ttf_draw_string_raw(rct_drawpixelinfo *dpi, const utf8 *text, text_draw_info *info)
|
||||
|
@ -1296,9 +1052,9 @@ static void ttf_draw_string(rct_drawpixelinfo *dpi, char *text, sint32 colour, s
|
|||
info.x = x;
|
||||
info.y = y;
|
||||
|
||||
#ifndef NO_TTF
|
||||
if (gUseTrueTypeFont) info.flags |= TEXT_DRAW_FLAG_TTF;
|
||||
#endif // NO_TTF
|
||||
if (gUseTrueTypeFont) {
|
||||
info.flags |= TEXT_DRAW_FLAG_TTF;
|
||||
}
|
||||
|
||||
memcpy(info.palette, text_palette, sizeof(info.palette));
|
||||
ttf_process_initial_colour(colour, &info);
|
||||
|
@ -1325,9 +1081,9 @@ static sint32 ttf_get_string_width(const utf8 *text)
|
|||
info.maxY = 0;
|
||||
|
||||
info.flags |= TEXT_DRAW_FLAG_NO_DRAW;
|
||||
#ifndef NO_TTF
|
||||
if (gUseTrueTypeFont) info.flags |= TEXT_DRAW_FLAG_TTF;
|
||||
#endif // NO_TTF
|
||||
if (gUseTrueTypeFont) {
|
||||
info.flags |= TEXT_DRAW_FLAG_TTF;
|
||||
}
|
||||
|
||||
ttf_process_string(NULL, text, &info);
|
||||
|
||||
|
@ -1351,11 +1107,9 @@ void gfx_draw_string_with_y_offsets(rct_drawpixelinfo *dpi, const utf8 *text, si
|
|||
|
||||
info.flags |= TEXT_DRAW_FLAG_Y_OFFSET_EFFECT;
|
||||
|
||||
#ifndef NO_TTF
|
||||
if (!forceSpriteFont && gUseTrueTypeFont) {
|
||||
info.flags |= TEXT_DRAW_FLAG_TTF;
|
||||
}
|
||||
#endif // NO_TTF
|
||||
|
||||
memcpy(info.palette, text_palette, sizeof(info.palette));
|
||||
ttf_process_initial_colour(colour, &info);
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#ifndef NO_TTF
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../rct2.h"
|
||||
#include "ttf.h"
|
||||
|
||||
static bool _ttfInitialised = false;
|
||||
|
||||
#define TTF_SURFACE_CACHE_SIZE 256
|
||||
#define TTF_GETWIDTH_CACHE_SIZE 1024
|
||||
|
||||
typedef struct ttf_cache_entry
|
||||
{
|
||||
TTFSurface * surface;
|
||||
TTF_Font * font;
|
||||
utf8 * text;
|
||||
uint32 lastUseTick;
|
||||
} ttf_cache_entry;
|
||||
|
||||
typedef struct ttf_getwidth_cache_entry
|
||||
{
|
||||
uint32 width;
|
||||
TTF_Font * font;
|
||||
utf8 * text;
|
||||
uint32 lastUseTick;
|
||||
} ttf_getwidth_cache_entry;
|
||||
|
||||
static ttf_cache_entry _ttfSurfaceCache[TTF_SURFACE_CACHE_SIZE] = { 0 };
|
||||
static sint32 _ttfSurfaceCacheCount = 0;
|
||||
static sint32 _ttfSurfaceCacheHitCount = 0;
|
||||
static sint32 _ttfSurfaceCacheMissCount = 0;
|
||||
|
||||
static ttf_getwidth_cache_entry _ttfGetWidthCache[TTF_GETWIDTH_CACHE_SIZE] = { 0 };
|
||||
static sint32 _ttfGetWidthCacheCount = 0;
|
||||
static sint32 _ttfGetWidthCacheHitCount = 0;
|
||||
static sint32 _ttfGetWidthCacheMissCount = 0;
|
||||
|
||||
static TTF_Font * ttf_open_font(const utf8 * fontPath, sint32 ptSize);
|
||||
static void ttf_close_font(TTF_Font * font);
|
||||
static uint32 ttf_surface_cache_hash(TTF_Font * font, const utf8 * text);
|
||||
static void ttf_surface_cache_dispose(ttf_cache_entry * entry);
|
||||
static void ttf_surface_cache_dispose_all();
|
||||
static void ttf_getwidth_cache_dispose_all();
|
||||
static bool ttf_get_size(TTF_Font * font, const utf8 * text, sint32 * width, sint32 * height);
|
||||
static TTFSurface * ttf_render(TTF_Font * font, const utf8 * text);
|
||||
|
||||
bool ttf_initialise()
|
||||
{
|
||||
if (!_ttfInitialised) {
|
||||
if (TTF_Init() != 0) {
|
||||
log_error("Couldn't initialise FreeType engine");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (sint32 i = 0; i < 4; i++) {
|
||||
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
|
||||
utf8 fontPath[MAX_PATH];
|
||||
if (!platform_get_font_path(fontDesc, fontPath, sizeof(fontPath))) {
|
||||
log_error("Unable to load font '%s'", fontDesc->font_name);
|
||||
return false;
|
||||
}
|
||||
|
||||
fontDesc->font = ttf_open_font(fontPath, fontDesc->ptSize);
|
||||
if (fontDesc->font == NULL) {
|
||||
log_error("Unable to load '%s'", fontPath);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ttfInitialised = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ttf_dispose()
|
||||
{
|
||||
if (_ttfInitialised)
|
||||
{
|
||||
ttf_surface_cache_dispose_all();
|
||||
ttf_getwidth_cache_dispose_all();
|
||||
|
||||
for (sint32 i = 0; i < 4; i++) {
|
||||
TTFFontDescriptor *fontDesc = &(gCurrentTTFFontSet->size[i]);
|
||||
if (fontDesc->font != NULL) {
|
||||
ttf_close_font(fontDesc->font);
|
||||
fontDesc->font = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TTF_Quit();
|
||||
_ttfInitialised = false;
|
||||
}
|
||||
}
|
||||
|
||||
static TTF_Font * ttf_open_font(const utf8 * fontPath, sint32 ptSize)
|
||||
{
|
||||
return TTF_OpenFont(fontPath, ptSize);
|
||||
}
|
||||
|
||||
static void ttf_close_font(TTF_Font * font)
|
||||
{
|
||||
TTF_CloseFont(font);
|
||||
}
|
||||
|
||||
static uint32 ttf_surface_cache_hash(TTF_Font *font, const utf8 *text)
|
||||
{
|
||||
uint32 hash = (uint32)((((uintptr_t)font * 23) ^ 0xAAAAAAAA) & 0xFFFFFFFF);
|
||||
for (const utf8 *ch = text; *ch != 0; ch++) {
|
||||
hash = ror32(hash, 3) ^ (*ch * 13);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void ttf_surface_cache_dispose(ttf_cache_entry *entry)
|
||||
{
|
||||
if (entry->surface != NULL) {
|
||||
ttf_free_surface(entry->surface);
|
||||
free(entry->text);
|
||||
|
||||
entry->surface = NULL;
|
||||
entry->font = NULL;
|
||||
entry->text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ttf_surface_cache_dispose_all()
|
||||
{
|
||||
for (sint32 i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) {
|
||||
ttf_surface_cache_dispose(&_ttfSurfaceCache[i]);
|
||||
_ttfSurfaceCacheCount--;
|
||||
}
|
||||
}
|
||||
|
||||
TTFSurface * ttf_surface_cache_get_or_add(TTF_Font * font, const utf8 * text)
|
||||
{
|
||||
ttf_cache_entry *entry;
|
||||
|
||||
uint32 hash = ttf_surface_cache_hash(font, text);
|
||||
sint32 index = hash % TTF_SURFACE_CACHE_SIZE;
|
||||
for (sint32 i = 0; i < TTF_SURFACE_CACHE_SIZE; i++) {
|
||||
entry = &_ttfSurfaceCache[index];
|
||||
|
||||
// Check if entry is a hit
|
||||
if (entry->surface == NULL) break;
|
||||
if (entry->font == font && strcmp(entry->text, text) == 0) {
|
||||
_ttfSurfaceCacheHitCount++;
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->surface;
|
||||
}
|
||||
|
||||
// If entry hasn't been used for a while, replace it
|
||||
if (entry->lastUseTick < gCurrentDrawCount - 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if next entry is a hit
|
||||
if (++index >= TTF_SURFACE_CACHE_SIZE) index = 0;
|
||||
}
|
||||
|
||||
// Cache miss, replace entry with new surface
|
||||
entry = &_ttfSurfaceCache[index];
|
||||
ttf_surface_cache_dispose(entry);
|
||||
|
||||
TTFSurface * surface = ttf_render(font, text);
|
||||
if (surface == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_ttfSurfaceCacheMissCount++;
|
||||
// printf("CACHE HITS: %d MISSES: %d)\n", _ttfSurfaceCacheHitCount, _ttfSurfaceCacheMissCount);
|
||||
|
||||
_ttfSurfaceCacheCount++;
|
||||
entry->surface = surface;
|
||||
entry->font = font;
|
||||
entry->text = _strdup(text);
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->surface;
|
||||
}
|
||||
|
||||
static void ttf_getwidth_cache_dispose(ttf_getwidth_cache_entry *entry)
|
||||
{
|
||||
if (entry->text != NULL) {
|
||||
free(entry->text);
|
||||
|
||||
entry->width = 0;
|
||||
entry->font = NULL;
|
||||
entry->text = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void ttf_getwidth_cache_dispose_all()
|
||||
{
|
||||
for (sint32 i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) {
|
||||
ttf_getwidth_cache_dispose(&_ttfGetWidthCache[i]);
|
||||
_ttfGetWidthCacheCount--;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ttf_getwidth_cache_get_or_add(TTF_Font * font, const utf8 * text)
|
||||
{
|
||||
ttf_getwidth_cache_entry *entry;
|
||||
|
||||
uint32 hash = ttf_surface_cache_hash(font, text);
|
||||
sint32 index = hash % TTF_GETWIDTH_CACHE_SIZE;
|
||||
for (sint32 i = 0; i < TTF_GETWIDTH_CACHE_SIZE; i++) {
|
||||
entry = &_ttfGetWidthCache[index];
|
||||
|
||||
// Check if entry is a hit
|
||||
if (entry->text == NULL) break;
|
||||
if (entry->font == font && strcmp(entry->text, text) == 0) {
|
||||
_ttfGetWidthCacheHitCount++;
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->width;
|
||||
}
|
||||
|
||||
// If entry hasn't been used for a while, replace it
|
||||
if (entry->lastUseTick < gCurrentDrawCount - 64) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if next entry is a hit
|
||||
if (++index >= TTF_GETWIDTH_CACHE_SIZE) index = 0;
|
||||
}
|
||||
|
||||
// Cache miss, replace entry with new width
|
||||
entry = &_ttfGetWidthCache[index];
|
||||
ttf_getwidth_cache_dispose(entry);
|
||||
|
||||
sint32 width, height;
|
||||
ttf_get_size(font, text, &width, &height);
|
||||
|
||||
_ttfGetWidthCacheMissCount++;
|
||||
|
||||
_ttfGetWidthCacheCount++;
|
||||
entry->width = width;
|
||||
entry->font = font;
|
||||
entry->text = _strdup(text);
|
||||
entry->lastUseTick = gCurrentDrawCount;
|
||||
return entry->width;
|
||||
}
|
||||
|
||||
TTFFontDescriptor * ttf_get_font_from_sprite_base(uint16 spriteBase)
|
||||
{
|
||||
return &gCurrentTTFFontSet->size[font_get_size_from_sprite_base(spriteBase)];
|
||||
}
|
||||
|
||||
bool ttf_provides_glyph(const TTF_Font * font, codepoint_t codepoint)
|
||||
{
|
||||
return TTF_GlyphIsProvided(font, codepoint);
|
||||
}
|
||||
|
||||
static bool ttf_get_size(TTF_Font * font, const utf8 * text, sint32 * outWidth, sint32 * outHeight)
|
||||
{
|
||||
return TTF_SizeUTF8(font, text, outWidth, outHeight);
|
||||
}
|
||||
|
||||
static TTFSurface * ttf_render(TTF_Font * font, const utf8 * text)
|
||||
{
|
||||
return TTF_RenderUTF8_Solid(font, text, 0x000000FF);
|
||||
}
|
||||
|
||||
void ttf_free_surface(TTFSurface * surface)
|
||||
{
|
||||
free((void *)surface->pixels);
|
||||
free(surface);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "ttf.h"
|
||||
|
||||
bool ttf_initialise()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void ttf_dispose()
|
||||
{
|
||||
}
|
||||
|
||||
#endif // NO_TTF
|
|
@ -0,0 +1,48 @@
|
|||
#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "font.h"
|
||||
|
||||
bool ttf_initialise();
|
||||
void ttf_dispose();
|
||||
|
||||
#ifndef NO_TTF
|
||||
|
||||
typedef struct TTFSurface {
|
||||
const void * pixels;
|
||||
sint32 w;
|
||||
sint32 h;
|
||||
sint32 pitch;
|
||||
} TTFSurface;
|
||||
|
||||
TTFFontDescriptor * ttf_get_font_from_sprite_base(uint16 spriteBase);
|
||||
TTFSurface * ttf_surface_cache_get_or_add(TTF_Font * font, const utf8 * text);
|
||||
uint32 ttf_getwidth_cache_get_or_add(TTF_Font * font, const utf8 * text);
|
||||
bool ttf_provides_glyph(const TTF_Font * font, codepoint_t codepoint);
|
||||
void ttf_free_surface(TTFSurface * surface);
|
||||
|
||||
// TTF_SDLPORT
|
||||
int TTF_Init(void);
|
||||
TTF_Font * TTF_OpenFont(const char *file, int ptsize);
|
||||
int TTF_GlyphIsProvided(const TTF_Font *font, codepoint_t ch);
|
||||
int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h);
|
||||
TTFSurface * TTF_RenderUTF8_Solid(TTF_Font *font, const char *text, uint32 colour);
|
||||
void TTF_CloseFont(TTF_Font *font);
|
||||
void TTF_Quit(void);
|
||||
|
||||
#endif // NO_TTF
|
File diff suppressed because it is too large
Load Diff
|
@ -14,16 +14,17 @@
|
|||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#include "../common.h"
|
||||
#include "../config/Config.h"
|
||||
#include "../core/Console.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "../localisation/LanguagePack.h"
|
||||
#include "Fonts.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../config/Config.h"
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../localisation/language.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../drawing/ttf.h"
|
||||
#include "../localisation/language.h"
|
||||
}
|
||||
|
||||
#ifndef NO_TTF
|
||||
|
|
Loading…
Reference in New Issue