summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2018-11-25 02:00:42 +0100
committerOwen Rudge <owen@owenrudge.net>2019-05-14 11:21:36 +0100
commit2675762ae9c58c47dc442b422927206c7bee13a8 (patch)
treecb1272f39546c66c03441887b3541fb48e6f96f3
parenta8b6e9f23cc7f8c0835743d462fd27a20af6518e (diff)
downloadopenttd-2675762ae9c58c47dc442b422927206c7bee13a8.tar.xz
Add: [Win32] GDI engine for font glyph rendering as a replacement for including FreeType.
Building with FreeType is still possible and will take precedence over the GDI renderer, but the project files don't include FreeType anymore by default. Combining GDI rendering with ICU text layout is untested.
-rw-r--r--config.lib6
-rw-r--r--docs/Readme_Windows_MSVC.md5
-rw-r--r--projects/openttd_vs140.vcxproj8
-rw-r--r--projects/openttd_vs140.vcxproj.in8
-rw-r--r--projects/openttd_vs141.vcxproj8
-rw-r--r--projects/openttd_vs141.vcxproj.in8
-rw-r--r--projects/openttd_vs142.vcxproj8
-rw-r--r--projects/openttd_vs142.vcxproj.in8
-rw-r--r--src/fontcache.cpp275
-rw-r--r--src/fontcache.h4
-rw-r--r--src/fontdetection.cpp10
-rw-r--r--src/fontdetection.h5
-rw-r--r--src/settings.cpp4
-rw-r--r--src/strings.cpp4
-rw-r--r--src/textfile_gui.cpp2
15 files changed, 325 insertions, 38 deletions
diff --git a/config.lib b/config.lib
index f65aaa535..e8f77adc7 100644
--- a/config.lib
+++ b/config.lib
@@ -2786,6 +2786,12 @@ detect_png() {
}
detect_freetype() {
+ if [ "$with_freetype" = "1" ] && ([ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]); then
+ log 1 "checking freetype2... WIN32, skipping"
+ freetype_config=""
+ return 0
+ fi
+
detect_pkg_config "$with_freetype" "freetype2" "freetype_config" "2.2" "1"
}
diff --git a/docs/Readme_Windows_MSVC.md b/docs/Readme_Windows_MSVC.md
index 90ab2af65..247ad74e7 100644
--- a/docs/Readme_Windows_MSVC.md
+++ b/docs/Readme_Windows_MSVC.md
@@ -32,7 +32,6 @@ by following the `Quick Start` intructions of their
After this, you can install the dependencies OpenTTD needs. We advise to use
the `static` versions, and OpenTTD currently needs the following dependencies:
-- freetype
- liblzma
- libpng
- lzo
@@ -41,8 +40,8 @@ the `static` versions, and OpenTTD currently needs the following dependencies:
To install both the x64 (64bit) and x86 (32bit) variants, you can use:
```ps
-.\vcpkg install freetype:x64-windows-static liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static
-.\vcpkg install freetype:x86-windows-static liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static
+.\vcpkg install liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static
+.\vcpkg install liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static
```
## TTD Graphics files
diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj
index 53c0fb623..070a3a144 100644
--- a/projects/openttd_vs140.vcxproj
+++ b/projects/openttd_vs140.vcxproj
@@ -107,7 +107,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -172,7 +172,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
@@ -230,7 +230,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -293,7 +293,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
diff --git a/projects/openttd_vs140.vcxproj.in b/projects/openttd_vs140.vcxproj.in
index 17b4356cc..b5628a23d 100644
--- a/projects/openttd_vs140.vcxproj.in
+++ b/projects/openttd_vs140.vcxproj.in
@@ -107,7 +107,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -172,7 +172,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
@@ -230,7 +230,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -293,7 +293,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj
index fb671ef1b..6fd1388c9 100644
--- a/projects/openttd_vs141.vcxproj
+++ b/projects/openttd_vs141.vcxproj
@@ -107,7 +107,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -172,7 +172,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
@@ -230,7 +230,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -293,7 +293,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
diff --git a/projects/openttd_vs141.vcxproj.in b/projects/openttd_vs141.vcxproj.in
index 0b04ebacc..015c23d3c 100644
--- a/projects/openttd_vs141.vcxproj.in
+++ b/projects/openttd_vs141.vcxproj.in
@@ -107,7 +107,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -172,7 +172,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
@@ -230,7 +230,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -293,7 +293,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj
index 16a7bf7aa..ee2886e71 100644
--- a/projects/openttd_vs142.vcxproj
+++ b/projects/openttd_vs142.vcxproj
@@ -107,7 +107,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -172,7 +172,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
@@ -230,7 +230,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -293,7 +293,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
diff --git a/projects/openttd_vs142.vcxproj.in b/projects/openttd_vs142.vcxproj.in
index 37f0d6cf9..6b5c18d25 100644
--- a/projects/openttd_vs142.vcxproj.in
+++ b/projects/openttd_vs142.vcxproj.in
@@ -107,7 +107,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -172,7 +172,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
@@ -230,7 +230,7 @@
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
@@ -293,7 +293,7 @@
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<AdditionalIncludeDirectories>..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
diff --git a/src/fontcache.cpp b/src/fontcache.cpp
index 50600de40..778af3440 100644
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -199,7 +199,7 @@ bool SpriteFontCache::GetDrawGlyphShadow()
/* static */ FontCache *FontCache::caches[FS_END] = { new SpriteFontCache(FS_NORMAL), new SpriteFontCache(FS_SMALL), new SpriteFontCache(FS_LARGE), new SpriteFontCache(FS_MONO) };
-#if defined(WITH_FREETYPE)
+#if defined(WITH_FREETYPE) || defined(_WIN32)
FreeTypeSettings _freetype;
@@ -710,9 +710,278 @@ const void *FreeTypeFontCache::InternalGetFontTable(uint32 tag, size_t &length)
return result;
}
+#elif defined(_WIN32)
+
+#include "os/windows/win32.h"
+#ifndef ANTIALIASED_QUALITY
+#define ANTIALIASED_QUALITY 4
+#endif
+
+/** Font cache for fonts that are based on a Win32 font. */
+class Win32FontCache : public TrueTypeFontCache {
+private:
+ LOGFONT logfont; ///< Logical font information for selecting the font face.
+ HFONT font = nullptr; ///< The font face associated with this font.
+ HDC dc = nullptr; ///< Cached GDI device context.
+ HGDIOBJ old_font; ///< Old font selected into the GDI context.
+ SIZE glyph_size; ///< Maximum size of regular glyphs.
+
+ void SetFontSize(FontSize fs, int pixels);
+ virtual const void *InternalGetFontTable(uint32 tag, size_t &length);
+ virtual const Sprite *InternalGetGlyph(GlyphID key, bool aa);
+
+public:
+ Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels);
+ ~Win32FontCache();
+ virtual void ClearFontCache();
+ virtual GlyphID MapCharToGlyph(WChar key);
+ virtual const char *GetFontName() { return WIDE_TO_MB(this->logfont.lfFaceName); }
+ virtual bool IsBuiltInFont() { return false; }
+};
+
+
+/**
+ * Create a new Win32FontCache.
+ * @param fs The font size that is going to be cached.
+ * @param logfont The font that has to be loaded.
+ * @param pixels The number of pixels this font should be high.
+ */
+Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels) : TrueTypeFontCache(fs, pixels), logfont(logfont)
+{
+ this->dc = CreateCompatibleDC(nullptr);
+ this->SetFontSize(fs, pixels);
+}
+
+Win32FontCache::~Win32FontCache()
+{
+ this->ClearFontCache();
+ DeleteDC(this->dc);
+ DeleteObject(this->font);
+}
+
+void Win32FontCache::SetFontSize(FontSize fs, int pixels)
+{
+ if (pixels == 0) {
+ /* Try to determine a good height based on the minimal height recommended by the font. */
+ int scaled_height = ScaleFontTrad(_default_font_height[this->fs]);
+ pixels = scaled_height;
+
+ HFONT temp = CreateFontIndirect(&this->logfont);
+ if (temp != nullptr) {
+ HGDIOBJ old = SelectObject(this->dc, temp);
+
+ UINT size = GetOutlineTextMetrics(this->dc, 0, nullptr);
+ LPOUTLINETEXTMETRIC otm = (LPOUTLINETEXTMETRIC)AllocaM(BYTE, size);
+ GetOutlineTextMetrics(this->dc, size, otm);
+
+ /* Font height is minimum height plus the difference between the default
+ * height for this font size and the small size. */
+ int diff = scaled_height - ScaleFontTrad(_default_font_height[FS_SMALL]);
+ pixels = Clamp(min(otm->otmusMinimumPPEM, 20) + diff, scaled_height, MAX_FONT_SIZE);
+
+ SelectObject(dc, old);
+ DeleteObject(temp);
+ }
+ } else {
+ pixels = ScaleFontTrad(pixels);
+ }
+ this->used_size = pixels;
+
+ /* Create GDI font handle. */
+ this->logfont.lfHeight = -pixels;
+ this->logfont.lfWidth = 0;
+ this->logfont.lfOutPrecision = ANTIALIASED_QUALITY;
+
+ if (this->font != nullptr) {
+ SelectObject(dc, this->old_font);
+ DeleteObject(this->font);
+ }
+ this->font = CreateFontIndirect(&this->logfont);
+ this->old_font = SelectObject(this->dc, this->font);
+
+ /* Query the font metrics we needed. */
+ UINT otmSize = GetOutlineTextMetrics(this->dc, 0, nullptr);
+ POUTLINETEXTMETRIC otm = (POUTLINETEXTMETRIC)AllocaM(BYTE, otmSize);
+ GetOutlineTextMetrics(this->dc, otmSize, otm);
+
+ this->units_per_em = otm->otmEMSquare;
+ this->ascender = otm->otmTextMetrics.tmAscent;
+ this->descender = otm->otmTextMetrics.tmDescent;
+ this->height = this->ascender + this->descender;
+ this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth;
+ this->glyph_size.cy = otm->otmTextMetrics.tmHeight;
+
+ DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels);
+}
+
+/**
+ * Reset cached glyphs.
+ */
+void Win32FontCache::ClearFontCache()
+{
+ /* GUI scaling might have changed, determine font size anew if it was automatically selected. */
+ if (this->font != nullptr) this->SetFontSize(this->fs, this->req_size);
+
+ this->TrueTypeFontCache::ClearFontCache();
+}
+
+/* virtual */ const Sprite *Win32FontCache::InternalGetGlyph(GlyphID key, bool aa)
+{
+ GLYPHMETRICS gm;
+ MAT2 mat = { {0, 1}, {0, 0}, {0, 0}, {0, 1} };
+
+ /* Make a guess for the needed memory size. */
+ DWORD size = this->glyph_size.cy * Align(aa ? this->glyph_size.cx : max(this->glyph_size.cx / 8l, 1l), 4); // Bitmap data is DWORD-aligned rows.
+ byte *bmp = AllocaM(byte, size);
+ size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat);
+
+ if (size == GDI_ERROR) {
+ /* No dice with the guess. First query size of needed glyph memory, then allocate the
+ * memory and query again. This dance is necessary as some glyphs will only render with
+ * the exact matching size; e.g. the space glyph has no pixels and must be requested
+ * with size == 0, anything else fails. Unfortunately, a failed call doesn't return any
+ * info about the size and thus the triple GetGlyphOutline()-call. */
+ size = GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, 0, nullptr, &mat);
+ if (size == GDI_ERROR) usererror("Unable to render font glyph");
+ bmp = AllocaM(byte, size);
+ GetGlyphOutline(this->dc, key, GGO_GLYPH_INDEX | (aa ? GGO_GRAY8_BITMAP : GGO_BITMAP), &gm, size, bmp, &mat);
+ }
+
+ /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */
+ uint width = max(1U, (uint)gm.gmBlackBoxX + (this->fs == FS_NORMAL));
+ uint height = max(1U, (uint)gm.gmBlackBoxY + (this->fs == FS_NORMAL));
+
+ /* Limit glyph size to prevent overflows later on. */
+ if (width > 256 || height > 256) usererror("Font glyph is too large");
+
+ /* GDI has rendered the glyph, now we allocate a sprite and copy the image into it. */
+ SpriteLoader::Sprite sprite;
+ sprite.AllocateData(ZOOM_LVL_NORMAL, width * height);
+ sprite.type = ST_FONT;
+ sprite.width = width;
+ sprite.height = height;
+ sprite.x_offs = gm.gmptGlyphOrigin.x;
+ sprite.y_offs = this->ascender - gm.gmptGlyphOrigin.y;
+
+ if (size > 0) {
+ /* All pixel data returned by GDI is in the form of DWORD-aligned rows.
+ * For a non anti-aliased glyph, the returned bitmap has one bit per pixel.
+ * For anti-aliased rendering, GDI uses the strange value range of 0 to 64,
+ * inclusively. To map this to 0 to 255, we shift left by two and then
+ * subtract one. */
+ uint pitch = Align(aa ? gm.gmBlackBoxX : max(gm.gmBlackBoxX / 8u, 1u), 4);
+
+ /* Draw shadow for medium size. */
+ if (this->fs == FS_NORMAL && !aa) {
+ for (uint y = 0; y < gm.gmBlackBoxY; y++) {
+ for (uint x = 0; x < gm.gmBlackBoxX; x++) {
+ if (aa ? (bmp[x + y * pitch] > 0) : HasBit(bmp[(x / 8) + y * pitch], 7 - (x % 8))) {
+ sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR;
+ sprite.data[1 + x + (1 + y) * sprite.width].a = aa ? (bmp[x + y * pitch] << 2) - 1 : 0xFF;
+ }
+ }
+ }
+ }
+
+ for (uint y = 0; y < gm.gmBlackBoxY; y++) {
+ for (uint x = 0; x < gm.gmBlackBoxX; x++) {
+ if (aa ? (bmp[x + y * pitch] > 0) : HasBit(bmp[(x / 8) + y * pitch], 7 - (x % 8))) {
+ sprite.data[x + y * sprite.width].m = FACE_COLOUR;
+ sprite.data[x + y * sprite.width].a = aa ? (bmp[x + y * pitch] << 2) - 1 : 0xFF;
+ }
+ }
+ }
+ }
+
+ GlyphEntry new_glyph;
+ new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(&sprite, AllocateFont);
+ new_glyph.width = gm.gmCellIncX;
+
+ this->SetGlyphPtr(key, &new_glyph);
+
+ return new_glyph.sprite;
+}
+
+/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(WChar key)
+{
+ assert(IsPrintable(key));
+
+ if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
+ return this->parent->MapCharToGlyph(key);
+ }
+
+ /* Convert characters outside of the BMP into surrogate pairs. */
+ WCHAR chars[2];
+ if (key >= 0x010000U) {
+ chars[0] = (WCHAR)(((key - 0x010000U) >> 10) + 0xD800);
+ chars[1] = (WCHAR)(((key - 0x010000U) & 0x3FF) + 0xDC00);
+ } else {
+ chars[0] = (WCHAR)(key & 0xFFFF);
+ }
+
+ WORD glyphs[2] = {0, 0};
+ GetGlyphIndicesW(this->dc, chars, key >= 0x010000U ? 2 : 1, glyphs, GGI_MARK_NONEXISTING_GLYPHS);
+
+ return glyphs[0] != 0xFFFF ? glyphs[0] : 0;
+}
+
+/* virtual */ const void *Win32FontCache::InternalGetFontTable(uint32 tag, size_t &length)
+{
+ DWORD len = GetFontData(this->dc, tag, 0, nullptr, 0);
+
+ void *result = nullptr;
+ if (len != GDI_ERROR && len > 0) {
+ result = MallocT<BYTE>(len);
+ GetFontData(this->dc, tag, 0, result, len);
+ }
+
+ length = len;
+ return result;
+}
+
+/**
+ * Loads the GDI font.
+ * If a GDI font description is present, e.g. from the automatic font
+ * fallback search, use it. Otherwise, try to resolve it by font name.
+ * @param fs The font size to load.
+ */
+static void LoadWin32Font(FontSize fs)
+{
+ FreeTypeSubSetting *settings = nullptr;
+ switch (fs) {
+ default: NOT_REACHED();
+ case FS_SMALL: settings = &_freetype.small; break;
+ case FS_NORMAL: settings = &_freetype.medium; break;
+ case FS_LARGE: settings = &_freetype.large; break;
+ case FS_MONO: settings = &_freetype.mono; break;
+ }
+
+ if (StrEmpty(settings->font)) return;
+
+ LOGFONT logfont;
+ MemSetT(&logfont, 0);
+
+ logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
+ logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
+ logfont.lfCharSet = DEFAULT_CHARSET;
+ logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
+ logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
+ convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false);
+
+ HFONT font = CreateFontIndirect(&logfont);
+ if (font == nullptr) {
+ static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
+ ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", settings->font, SIZE_TO_NAME[fs], GetLastError());
+ return;
+ }
+ DeleteObject(font);
+
+ new Win32FontCache(fs, logfont, settings->size);
+}
+
#endif /* WITH_FREETYPE */
-#endif /* defined(WITH_FREETYPE) */
+#endif /* defined(WITH_FREETYPE) || defined(_WIN32) */
/**
* (Re)initialize the freetype related things, i.e. load the non-sprite fonts.
@@ -728,6 +997,8 @@ void InitFreeType(bool monospace)
#ifdef WITH_FREETYPE
LoadFreeTypeFont(fs);
+#elif defined(_WIN32)
+ LoadWin32Font(fs);
#endif
}
}
diff --git a/src/fontcache.h b/src/fontcache.h
index 9a08ba09f..62ce596f3 100644
--- a/src/fontcache.h
+++ b/src/fontcache.h
@@ -202,7 +202,7 @@ static inline bool GetDrawGlyphShadow(FontSize size)
return FontCache::Get(size)->GetDrawGlyphShadow();
}
-#ifdef WITH_FREETYPE
+#if defined(WITH_FREETYPE) || defined(_WIN32)
/** Settings for a single freetype font. */
struct FreeTypeSubSetting {
@@ -221,7 +221,7 @@ struct FreeTypeSettings {
extern FreeTypeSettings _freetype;
-#endif /* WITH_FREETYPE */
+#endif /* defined(WITH_FREETYPE) || defined(_WIN32) */
void InitFreeType(bool monospace);
void UninitFreeType();
diff --git a/src/fontdetection.cpp b/src/fontdetection.cpp
index 3a5893e11..f7465a268 100644
--- a/src/fontdetection.cpp
+++ b/src/fontdetection.cpp
@@ -9,7 +9,7 @@
/** @file fontdetection.cpp Detection of the right font. */
-#ifdef WITH_FREETYPE
+#if defined(WITH_FREETYPE) || defined(_WIN32)
#include "stdafx.h"
#include "debug.h"
@@ -17,7 +17,9 @@
#include "string_func.h"
#include "strings_func.h"
+#ifdef WITH_FREETYPE
extern FT_Library _library;
+#endif /* WITH_FREETYPE */
/**
* Get the font loaded into a Freetype face by using a font-name.
@@ -37,6 +39,7 @@ extern FT_Library _library;
#include "safeguards.h"
+#ifdef WITH_FREETYPE
/**
* Get the short DOS 8.3 format for paths.
* FreeType doesn't support Unicode filenames and Windows' fopen (as used
@@ -241,6 +244,7 @@ err2:
err1:
return ret_font_name == nullptr ? WIDE_TO_MB((const TCHAR*)logfont->elfFullName) : ret_font_name;
}
+#endif /* WITH_FREETYPE */
class FontList {
protected:
@@ -317,6 +321,7 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
char font_name[MAX_PATH];
convert_from_fs((const TCHAR *)logfont->elfFullName, font_name, lengthof(font_name));
+#ifdef WITH_FREETYPE
/* Add english name after font name */
const char *english_name = GetEnglishFontName(logfont);
strecpy(font_name + strlen(font_name) + 1, english_name, lastof(font_name));
@@ -337,6 +342,9 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
}
if (!found) return 1;
+#else
+ const char *english_name = font_name;
+#endif /* WITH_FREETYPE */
info->callback->SetFontNames(info->settings, font_name);
if (info->callback->FindMissingGlyphs(nullptr)) return 1;
diff --git a/src/fontdetection.h b/src/fontdetection.h
index edb961e6d..01e0223cd 100644
--- a/src/fontdetection.h
+++ b/src/fontdetection.h
@@ -27,6 +27,9 @@
*/
FT_Error GetFontByFaceName(const char *font_name, FT_Face *face);
+#endif /* WITH_FREETYPE */
+
+#if defined(WITH_FREETYPE) || defined(_WIN32)
/**
* We would like to have a fallback font as the current one
* doesn't contain all characters we need.
@@ -39,6 +42,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face);
*/
bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, class MissingGlyphSearcher *callback);
-#endif /* WITH_FREETYPE */
+#endif /* defined(WITH_FREETYPE) || defined(WIN32)*/
#endif
diff --git a/src/settings.cpp b/src/settings.cpp
index 74a8bd8d8..88cd95b71 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -39,7 +39,7 @@
#include "sound_func.h"
#include "company_func.h"
#include "rev.h"
-#ifdef WITH_FREETYPE
+#if defined(WITH_FREETYPE) || defined(_WIN32)
#include "fontcache.h"
#endif
#include "textbuf_gui.h"
@@ -68,7 +68,7 @@
#include "void_map.h"
#include "station_base.h"
-#if defined(WITH_FREETYPE)
+#if defined(WITH_FREETYPE) || defined(_WIN32)
#define HAS_TRUETYPE_FONT
#endif
diff --git a/src/strings.cpp b/src/strings.cpp
index 1ed679e27..fda92d8a7 100644
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -2070,7 +2070,7 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher {
void SetFontNames(FreeTypeSettings *settings, const char *font_name) override
{
-#ifdef WITH_FREETYPE
+#if defined(WITH_FREETYPE) || defined(_WIN32)
strecpy(settings->small.font, font_name, lastof(settings->small.font));
strecpy(settings->medium.font, font_name, lastof(settings->medium.font));
strecpy(settings->large.font, font_name, lastof(settings->large.font));
@@ -2096,7 +2096,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher)
static LanguagePackGlyphSearcher pack_searcher;
if (searcher == nullptr) searcher = &pack_searcher;
bool bad_font = !base_font || searcher->FindMissingGlyphs(nullptr);
-#ifdef WITH_FREETYPE
+#if defined(WITH_FREETYPE) || defined(_WIN32)
if (bad_font) {
/* We found an unprintable character... lets try whether we can find
* a fallback font that can print the characters in the current language. */
diff --git a/src/textfile_gui.cpp b/src/textfile_gui.cpp
index 7a2eb44ca..07851e12f 100644
--- a/src/textfile_gui.cpp
+++ b/src/textfile_gui.cpp
@@ -196,7 +196,7 @@ void TextfileWindow::SetupScrollbars()
/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name)
{
-#ifdef WITH_FREETYPE
+#if defined(WITH_FREETYPE) || defined(_WIN32)
strecpy(settings->mono.font, font_name, lastof(settings->mono.font));
#endif /* WITH_FREETYPE */
}