mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
13 Commits
71aaed860b
...
53fa54f8e9
Author | SHA1 | Date |
---|---|---|
|
53fa54f8e9 | |
|
32fc740582 | |
|
302ba93471 | |
|
994bdff81e | |
|
e1f5be6244 | |
|
20f1a0dc57 | |
|
36cf6b1d13 | |
|
6e766a2e81 | |
|
37610af0e4 | |
|
564441e822 | |
|
a6873ef7dd | |
|
e8d6b496c2 | |
|
f219557cf2 |
|
@ -56,6 +56,7 @@
|
|||
- George - Canal/Lock graphics
|
||||
- Andrew Parkhouse (andythenorth) - River graphics
|
||||
- David Dallaston (Pikka) - Tram tracks
|
||||
- Richard Wheeler (zephyris) - OpenTTD TrueType font
|
||||
- All Translators - For their support to make OpenTTD a truly international game
|
||||
- Bug Reporters - Thanks for all bug reports
|
||||
- Chris Sawyer - For an amazing game!
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
.Op Fl g Op Ar savegame
|
||||
.Op Fl G Ar seed
|
||||
.Op Fl I Ar graphicsset
|
||||
.Op Fl l Ar host Ns Op : Ns Ar port
|
||||
.Op Fl m Ar driver
|
||||
.Op Fl M Ar musicset
|
||||
.Op Fl n Ar host Ns Oo : Ns Ar port Oc Ns Op # Ns Ar company
|
||||
|
@ -82,9 +81,6 @@ Select the graphics set
|
|||
see
|
||||
.Fl h
|
||||
for a full list.
|
||||
.It Fl l Ar host Ns Op : Ns Ar port
|
||||
Redirect debug output; see
|
||||
.Fl d .
|
||||
.It Fl m Ar driver
|
||||
Select the music driver
|
||||
.Ar driver ;
|
||||
|
|
|
@ -18,6 +18,10 @@ set(BASESET_OTHER_SOURCE_FILES
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/opntitle.dat
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/orig_extra.grf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../openttd.32.bmp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Sans.ttf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Serif.ttf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Small.ttf
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/OpenTTD-Mono.ttf
|
||||
)
|
||||
|
||||
# Done by the subdirectories, if nforenum / grfcodec is installed
|
||||
|
@ -63,7 +67,7 @@ foreach(BASESET_OTHER_SOURCE_FILE IN LISTS BASESET_OTHER_SOURCE_FILES)
|
|||
get_filename_component(BASESET_OTHER_SOURCE_FILE_NAME "${BASESET_OTHER_SOURCE_FILE}" NAME)
|
||||
set(BASESET_OTHER_BINARY_FILE "${CMAKE_BINARY_DIR}/baseset/${BASESET_OTHER_SOURCE_FILE_NAME}")
|
||||
|
||||
add_custom_command(OUTPUT ${BASESET_OTHER_BINARY_FILE}
|
||||
add_custom_command_timestamp(OUTPUT ${BASESET_OTHER_BINARY_FILE}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${BASESET_OTHER_SOURCE_FILE}
|
||||
${BASESET_OTHER_BINARY_FILE}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
# OpenTTD TrueType font
|
||||
|
||||
The OpenTTD TrueType font was created by Zephyris and is maintained on [Github](https://github.com/zephyris/openttd-ttf).
|
||||
It is licensed under GPL-2.0.
|
||||
|
||||
The currently included files correspond to release v0.3.
|
|
@ -106,7 +106,7 @@ void IConsolePrint(TextColour colour_code, const std::string &string)
|
|||
|
||||
/* Create a copy of the string, strip it of colours and invalid
|
||||
* characters and (when applicable) assign it to the console buffer */
|
||||
std::string str = StrMakeValid(string);
|
||||
std::string str = StrMakeValid(string, SVS_NONE);
|
||||
|
||||
if (_network_dedicated) {
|
||||
NetworkAdminConsole("console", str);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "3rdparty/fmt/chrono.h"
|
||||
|
||||
#include "network/network_admin.h"
|
||||
SOCKET _debug_socket = INVALID_SOCKET;
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
|
@ -111,18 +110,6 @@ void DumpDebugFacilityNames(std::back_insert_iterator<std::string> &output_itera
|
|||
*/
|
||||
void DebugPrint(const char *level, const std::string &message)
|
||||
{
|
||||
if (_debug_socket != INVALID_SOCKET) {
|
||||
std::string msg = fmt::format("{}dbg: [{}] {}\n", GetLogPrefix(), level, message);
|
||||
|
||||
/* Prevent sending a message concurrently, as that might cause interleaved messages. */
|
||||
static std::mutex _debug_socket_mutex;
|
||||
std::lock_guard<std::mutex> lock(_debug_socket_mutex);
|
||||
|
||||
/* Sending out an error when this fails would be nice, however... the error
|
||||
* would have to be send over this failing socket which won't work. */
|
||||
send(_debug_socket, msg.c_str(), (int)msg.size(), 0);
|
||||
return;
|
||||
}
|
||||
if (strcmp(level, "desync") == 0) {
|
||||
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
|
||||
if (f == nullptr) return;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "strings_func.h"
|
||||
#include "viewport_func.h"
|
||||
#include "window_func.h"
|
||||
#include "fileio_func.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
|
@ -95,7 +96,7 @@ bool GetFontAAState(FontSize size, bool check_blitter)
|
|||
/* AA is only supported for 32 bpp */
|
||||
if (check_blitter && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false;
|
||||
|
||||
return GetFontCacheSubSetting(size)->aa;
|
||||
return _fcsettings.global_aa || GetFontCacheSubSetting(size)->aa;
|
||||
}
|
||||
|
||||
void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa)
|
||||
|
@ -143,13 +144,52 @@ void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa)
|
|||
|
||||
#ifdef WITH_FREETYPE
|
||||
extern void LoadFreeTypeFont(FontSize fs);
|
||||
extern void LoadFreeTypeFont(FontSize fs, const std::string &file_name, uint size);
|
||||
extern void UninitFreeType();
|
||||
#elif defined(_WIN32)
|
||||
extern void LoadWin32Font(FontSize fs);
|
||||
extern void LoadWin32Font(FontSize fs, const std::string &file_name, uint size);
|
||||
#elif defined(WITH_COCOA)
|
||||
extern void LoadCoreTextFont(FontSize fs);
|
||||
extern void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size);
|
||||
#endif
|
||||
|
||||
static void TryLoadDefaultTrueTypeFont([[maybe_unused]] FontSize fs)
|
||||
{
|
||||
#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
|
||||
std::string font_name{};
|
||||
switch (fs) {
|
||||
case FS_NORMAL:
|
||||
font_name = "OpenTTD-Sans.ttf";
|
||||
break;
|
||||
case FS_SMALL:
|
||||
font_name = "OpenTTD-Small.ttf";
|
||||
break;
|
||||
case FS_LARGE:
|
||||
font_name = "OpenTTD-Serif.ttf";
|
||||
break;
|
||||
case FS_MONO:
|
||||
font_name = "OpenTTD-Mono.ttf";
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
/* Find font file. */
|
||||
std::string full_font = FioFindFullPath(BASESET_DIR, font_name);
|
||||
if (!full_font.empty()) {
|
||||
int size = FontCache::GetDefaultFontHeight(fs);
|
||||
#ifdef WITH_FREETYPE
|
||||
LoadFreeTypeFont(fs, full_font, size);
|
||||
#elif defined(_WIN32)
|
||||
LoadWin32Font(fs, full_font, size);
|
||||
#elif defined(WITH_COCOA)
|
||||
LoadCoreTextFont(fs, full_font, size);
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA) */
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re)initialize the font cache related things, i.e. load the non-sprite fonts.
|
||||
* @param monospace Whether to initialise the monospace or regular fonts.
|
||||
|
@ -164,13 +204,17 @@ void InitFontCache(bool monospace)
|
|||
FontCache *fc = FontCache::Get(fs);
|
||||
if (fc->HasParent()) delete fc;
|
||||
|
||||
if (!_fcsettings.prefer_sprite && GetFontCacheSubSetting(fs)->font.empty()) {
|
||||
TryLoadDefaultTrueTypeFont(fs);
|
||||
} else {
|
||||
#ifdef WITH_FREETYPE
|
||||
LoadFreeTypeFont(fs);
|
||||
LoadFreeTypeFont(fs);
|
||||
#elif defined(_WIN32)
|
||||
LoadWin32Font(fs);
|
||||
LoadWin32Font(fs);
|
||||
#elif defined(WITH_COCOA)
|
||||
LoadCoreTextFont(fs);
|
||||
LoadCoreTextFont(fs);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -108,9 +108,10 @@ public:
|
|||
/**
|
||||
* Map a character into a glyph.
|
||||
* @param key The character.
|
||||
* @param fallback Allow fallback to the parent font.
|
||||
* @return The glyph ID used to draw the character.
|
||||
*/
|
||||
virtual GlyphID MapCharToGlyph(char32_t key) = 0;
|
||||
virtual GlyphID MapCharToGlyph(char32_t key, bool fallback = true) = 0;
|
||||
|
||||
/**
|
||||
* Read a font table from the font.
|
||||
|
@ -217,6 +218,8 @@ struct FontCacheSettings {
|
|||
FontCacheSubSetting medium; ///< The normal font size.
|
||||
FontCacheSubSetting large; ///< The largest font; mostly used for newspapers.
|
||||
FontCacheSubSetting mono; ///< The mono space font used for license/readme viewers.
|
||||
bool prefer_sprite; ///< Whether to prefer the built-in sprite font over resizable fonts.
|
||||
bool global_aa; ///< Whether to anti alias all font sizes.
|
||||
};
|
||||
|
||||
extern FontCacheSettings _fcsettings;
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
FreeTypeFontCache(FontSize fs, FT_Face face, int pixels);
|
||||
~FreeTypeFontCache();
|
||||
void ClearFontCache() override;
|
||||
GlyphID MapCharToGlyph(char32_t key) override;
|
||||
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
|
||||
std::string GetFontName() override { return fmt::format("{}, {}", face->family_name, face->style_name); }
|
||||
bool IsBuiltInFont() override { return false; }
|
||||
const void *GetOSHandle() override { return &face; }
|
||||
|
@ -115,6 +115,42 @@ void FreeTypeFontCache::SetFontSize(FontSize, FT_Face, int pixels)
|
|||
}
|
||||
}
|
||||
|
||||
static FT_Error LoadFont(FontSize fs, FT_Face face, const char *font_name, uint size)
|
||||
{
|
||||
Debug(fontcache, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
|
||||
|
||||
/* Attempt to select the unicode character map */
|
||||
FT_Error error = FT_Select_Charmap(face, ft_encoding_unicode);
|
||||
if (error == FT_Err_Ok) goto found_face; // Success
|
||||
|
||||
if (error == FT_Err_Invalid_CharMap_Handle) {
|
||||
/* Try to pick a different character map instead. We default to
|
||||
* the first map, but platform_id 0 encoding_id 0 should also
|
||||
* be unicode (strange system...) */
|
||||
FT_CharMap found = face->charmaps[0];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < face->num_charmaps; i++) {
|
||||
FT_CharMap charmap = face->charmaps[i];
|
||||
if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
|
||||
found = charmap;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != nullptr) {
|
||||
error = FT_Set_Charmap(face, found);
|
||||
if (error == FT_Err_Ok) goto found_face;
|
||||
}
|
||||
}
|
||||
|
||||
FT_Done_Face(face);
|
||||
return error;
|
||||
|
||||
found_face:
|
||||
new FreeTypeFontCache(fs, face, size);
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the freetype font.
|
||||
* First type to load the fontname as if it were a path. If that fails,
|
||||
|
@ -157,40 +193,40 @@ void LoadFreeTypeFont(FontSize fs)
|
|||
if (error != FT_Err_Ok) error = GetFontByFaceName(font_name, &face);
|
||||
|
||||
if (error == FT_Err_Ok) {
|
||||
Debug(fontcache, 2, "Requested '{}', using '{} {}'", font_name, face->family_name, face->style_name);
|
||||
|
||||
/* Attempt to select the unicode character map */
|
||||
error = FT_Select_Charmap(face, ft_encoding_unicode);
|
||||
if (error == FT_Err_Ok) goto found_face; // Success
|
||||
|
||||
if (error == FT_Err_Invalid_CharMap_Handle) {
|
||||
/* Try to pick a different character map instead. We default to
|
||||
* the first map, but platform_id 0 encoding_id 0 should also
|
||||
* be unicode (strange system...) */
|
||||
FT_CharMap found = face->charmaps[0];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < face->num_charmaps; i++) {
|
||||
FT_CharMap charmap = face->charmaps[i];
|
||||
if (charmap->platform_id == 0 && charmap->encoding_id == 0) {
|
||||
found = charmap;
|
||||
}
|
||||
}
|
||||
|
||||
if (found != nullptr) {
|
||||
error = FT_Set_Charmap(face, found);
|
||||
if (error == FT_Err_Ok) goto found_face;
|
||||
}
|
||||
error = LoadFont(fs, face, font_name, settings->size);
|
||||
if (error != FT_Err_Ok) {
|
||||
ShowInfo("Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
|
||||
}
|
||||
} else {
|
||||
FT_Done_Face(face);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a TrueType font from a file.
|
||||
* @param fs The font size to load.
|
||||
* @param file_name Path to the font file.
|
||||
* @param size Requested font size.
|
||||
*/
|
||||
void LoadFreeTypeFont(FontSize fs, const std::string &file_name, uint size)
|
||||
{
|
||||
if (_library == nullptr) {
|
||||
if (FT_Init_FreeType(&_library) != FT_Err_Ok) {
|
||||
ShowInfo("Unable to initialize FreeType, using sprite fonts instead");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug(fontcache, 2, "Initialized");
|
||||
}
|
||||
|
||||
FT_Done_Face(face);
|
||||
|
||||
ShowInfo("Unable to use '{}' for {} font, FreeType reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), error);
|
||||
return;
|
||||
|
||||
found_face:
|
||||
new FreeTypeFontCache(fs, face, settings->size);
|
||||
FT_Face face = nullptr;
|
||||
int32_t index = 0;
|
||||
FT_Error error = FT_New_Face(_library, file_name.c_str(), index, &face);
|
||||
if (error == FT_Err_Ok) {
|
||||
LoadFont(fs, face, file_name.c_str(), size);
|
||||
} else {
|
||||
FT_Done_Face(face);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -276,15 +312,17 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
|
|||
}
|
||||
|
||||
|
||||
GlyphID FreeTypeFontCache::MapCharToGlyph(char32_t key)
|
||||
GlyphID FreeTypeFontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
|
||||
{
|
||||
assert(IsPrintable(key));
|
||||
|
||||
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
|
||||
FT_UInt glyph = FT_Get_Char_Index(this->face, key);
|
||||
|
||||
if (glyph == 0 && allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
|
||||
return this->parent->MapCharToGlyph(key);
|
||||
}
|
||||
|
||||
return FT_Get_Char_Index(this->face, key);
|
||||
return glyph;
|
||||
}
|
||||
|
||||
const void *FreeTypeFontCache::InternalGetFontTable(uint32_t tag, size_t &length)
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
const Sprite *GetGlyph(GlyphID key) override;
|
||||
uint GetGlyphWidth(GlyphID key) override;
|
||||
bool GetDrawGlyphShadow() override;
|
||||
GlyphID MapCharToGlyph(char32_t key) override { assert(IsPrintable(key)); return SPRITE_GLYPH | key; }
|
||||
GlyphID MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback = true) override { assert(IsPrintable(key)); return SPRITE_GLYPH | key; }
|
||||
const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
|
||||
std::string GetFontName() override { return "sprite"; }
|
||||
bool IsBuiltInFont() override { return true; }
|
||||
|
|
14
src/gfx.cpp
14
src/gfx.cpp
|
@ -579,6 +579,8 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
|||
bool draw_shadow = false;
|
||||
for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
|
||||
const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index);
|
||||
const auto &glyphs = run.GetGlyphs();
|
||||
const auto &positions = run.GetPositions();
|
||||
const Font *f = run.GetFont();
|
||||
|
||||
FontCache *fc = f->fc;
|
||||
|
@ -592,14 +594,14 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
|
|||
draw_shadow = fc->GetDrawGlyphShadow() && (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK;
|
||||
|
||||
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
||||
GlyphID glyph = run.GetGlyphs()[i];
|
||||
GlyphID glyph = glyphs[i];
|
||||
|
||||
/* Not a valid glyph (empty) */
|
||||
if (glyph == 0xFFFF) continue;
|
||||
|
||||
int begin_x = (int)run.GetPositions()[i * 2] + left - offset_x;
|
||||
int end_x = (int)run.GetPositions()[i * 2 + 2] + left - offset_x - 1;
|
||||
int top = (int)run.GetPositions()[i * 2 + 1] + y;
|
||||
int begin_x = (int)positions[i * 2] + left - offset_x;
|
||||
int end_x = (int)positions[i * 2 + 2] + left - offset_x - 1;
|
||||
int top = (int)positions[i * 2 + 1] + y;
|
||||
|
||||
/* Truncated away. */
|
||||
if (truncation && (begin_x < min_x || end_x > max_x)) continue;
|
||||
|
@ -1777,6 +1779,10 @@ bool ToggleFullScreen(bool fs)
|
|||
void SortResolutions()
|
||||
{
|
||||
std::sort(_resolutions.begin(), _resolutions.end());
|
||||
|
||||
/* Remove any duplicates from the list. */
|
||||
auto last = std::unique(_resolutions.begin(), _resolutions.end());
|
||||
_resolutions.erase(last, _resolutions.end());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -254,11 +254,13 @@ Point Layouter::GetCharPosition(std::string_view::const_iterator ch) const
|
|||
/* Scan all runs until we've found our code point index. */
|
||||
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
|
||||
const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
|
||||
const auto &positions = run.GetPositions();
|
||||
const auto &charmap = run.GetGlyphToCharMap();
|
||||
|
||||
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
||||
/* Matching glyph? Return position. */
|
||||
if ((size_t)run.GetGlyphToCharMap()[i] == index) {
|
||||
Point p = { (int)run.GetPositions()[i * 2], (int)run.GetPositions()[i * 2 + 1] };
|
||||
if ((size_t)charmap[i] == index) {
|
||||
Point p = { (int)positions[i * 2], (int)positions[i * 2 + 1] };
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
@ -281,17 +283,20 @@ ptrdiff_t Layouter::GetCharAtPosition(int x, size_t line_index) const
|
|||
|
||||
for (int run_index = 0; run_index < line->CountRuns(); run_index++) {
|
||||
const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index);
|
||||
const auto &glyphs = run.GetGlyphs();
|
||||
const auto &positions = run.GetPositions();
|
||||
const auto &charmap = run.GetGlyphToCharMap();
|
||||
|
||||
for (int i = 0; i < run.GetGlyphCount(); i++) {
|
||||
/* Not a valid glyph (empty). */
|
||||
if (run.GetGlyphs()[i] == 0xFFFF) continue;
|
||||
if (glyphs[i] == 0xFFFF) continue;
|
||||
|
||||
int begin_x = (int)run.GetPositions()[i * 2];
|
||||
int end_x = (int)run.GetPositions()[i * 2 + 2];
|
||||
int begin_x = (int)positions[i * 2];
|
||||
int end_x = (int)positions[i * 2 + 2];
|
||||
|
||||
if (IsInsideMM(x, begin_x, end_x)) {
|
||||
/* Found our glyph, now convert to UTF-8 string index. */
|
||||
size_t index = run.GetGlyphToCharMap()[i];
|
||||
size_t index = charmap[i];
|
||||
|
||||
size_t cur_idx = 0;
|
||||
for (auto str = this->string.begin(); str != this->string.end();) {
|
||||
|
|
|
@ -193,7 +193,7 @@ void ICURun::Shape(UChar *buff, size_t buff_length)
|
|||
for (unsigned int i = 0; i < glyph_count; i++) {
|
||||
int x_advance;
|
||||
|
||||
if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END) {
|
||||
if (buff[glyph_info[i].cluster] >= SCC_SPRITE_START && buff[glyph_info[i].cluster] <= SCC_SPRITE_END && glyph_info[i].codepoint == 0) {
|
||||
auto glyph = this->font->fc->MapCharToGlyph(buff[glyph_info[i].cluster]);
|
||||
|
||||
this->glyphs.push_back(glyph);
|
||||
|
|
35
src/gui.h
35
src/gui.h
|
@ -43,25 +43,38 @@ void ShowHeightmapLoad();
|
|||
/* misc_gui.cpp */
|
||||
void ShowLandInfo(TileIndex tile);
|
||||
void ShowAboutWindow();
|
||||
void ShowBuildTreesToolbar();
|
||||
void ShowTownDirectory();
|
||||
void ShowIndustryDirectory();
|
||||
void ShowIndustryCargoesWindow();
|
||||
void ShowSubsidiesList();
|
||||
void ShowGoalsList(CompanyID company);
|
||||
void ShowGoalQuestion(uint16_t id, byte type, uint32_t button_mask, const std::string &question);
|
||||
void ShowStoryBook(CompanyID company, uint16_t page_id = INVALID_STORY_PAGE);
|
||||
|
||||
void ShowEstimatedCostOrIncome(Money cost, int x, int y);
|
||||
|
||||
/* tree_gui.cpp */
|
||||
void ShowBuildTreesToolbar();
|
||||
|
||||
/* town_gui.cpp */
|
||||
void ShowTownDirectory();
|
||||
void ShowFoundTownWindow();
|
||||
|
||||
/* industry_gui.cpp */
|
||||
void ShowIndustryDirectory();
|
||||
void ShowIndustryCargoesWindow();
|
||||
void ShowBuildIndustryWindow();
|
||||
|
||||
/* subsidy_gui.cpp */
|
||||
void ShowSubsidiesList();
|
||||
|
||||
/* goal_gui.cpp */
|
||||
void ShowGoalsList(CompanyID company);
|
||||
void ShowGoalQuestion(uint16_t id, byte type, uint32_t button_mask, const std::string &question);
|
||||
|
||||
/* story_gui.cpp */
|
||||
void ShowStoryBook(CompanyID company, uint16_t page_id = INVALID_STORY_PAGE);
|
||||
|
||||
/* viewport_gui.cpp */
|
||||
void ShowExtraViewportWindow(TileIndex tile = INVALID_TILE);
|
||||
void ShowExtraViewportWindowForTileUnderCursor();
|
||||
|
||||
/* bridge_gui.cpp */
|
||||
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type);
|
||||
|
||||
void ShowBuildIndustryWindow();
|
||||
void ShowFoundTownWindow();
|
||||
/* music_gui.cpp */
|
||||
void ShowMusicWindow();
|
||||
|
||||
#endif /* GUI_H */
|
||||
|
|
|
@ -1002,6 +1002,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dolla
|
|||
STR_GAME_OPTIONS_CURRENCY_INR :Indisk rupi
|
||||
STR_GAME_OPTIONS_CURRENCY_IDR :Indonesisk Rupiah
|
||||
STR_GAME_OPTIONS_CURRENCY_MYR :Malaysisk Ringgit
|
||||
STR_GAME_OPTIONS_CURRENCY_LVL :lettiske lats
|
||||
|
||||
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Automatisk gemning
|
||||
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Vælg interval imellem automatisk gemning
|
||||
|
@ -3016,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Ejer af
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokal myndighed: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ingen
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinater: {LTBLUE}{NUM}x{NUM}x{NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Produceret: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Bygget/renoveret: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Stationsklasse: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Stationstype: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Lufthavnsklasse: {LTBLUE}{STRING}
|
||||
|
|
|
@ -1044,6 +1044,11 @@ STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Check th
|
|||
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Scale bevels
|
||||
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Check this box to scale bevels by interface size
|
||||
|
||||
STR_GAME_OPTIONS_GUI_FONT_SPRITE :{BLACK}Use traditional sprite font
|
||||
STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP :{BLACK}Check this box if you prefer to use the tradition fixed-size sprite font.
|
||||
STR_GAME_OPTIONS_GUI_FONT_AA :{BLACK}Anti-alias fonts
|
||||
STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP :{BLACK}Check this box to anti-alias resizable fonts.
|
||||
|
||||
STR_GAME_OPTIONS_GUI_SCALE_1X :1x
|
||||
STR_GAME_OPTIONS_GUI_SCALE_2X :2x
|
||||
STR_GAME_OPTIONS_GUI_SCALE_3X :3x
|
||||
|
|
|
@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railway
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built/renovated: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Airport class: {LTBLUE}{STRING}
|
||||
|
|
|
@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Railroad
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Local authority: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :None
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Co-ordinates: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Built/renovated: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Station class: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Station type: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Airport class: {LTBLUE}{STRING}
|
||||
|
|
|
@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Rautatie
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Kunta: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Ei mitään
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Koordinaatit: {LTBLUE}{NUM}×{NUM}×{NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Rakennettu: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Rakennettu/peruskorjattu: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Aseman luokka: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Aseman tyyppi: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Lentokentän luokka: {LTBLUE}{STRING}
|
||||
|
|
|
@ -1003,7 +1003,7 @@ STR_GAME_OPTIONS_CURRENCY_HKD :Dollar de Hong
|
|||
STR_GAME_OPTIONS_CURRENCY_INR :Roupie indienne
|
||||
STR_GAME_OPTIONS_CURRENCY_IDR :Roupie indonésienne
|
||||
STR_GAME_OPTIONS_CURRENCY_MYR :Malaysian Ringgit
|
||||
STR_GAME_OPTIONS_CURRENCY_LVL :Lats
|
||||
STR_GAME_OPTIONS_CURRENCY_LVL :Lats letton
|
||||
|
||||
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Sauvegarde automatique
|
||||
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Sélectionner l'intervalle de temps entre les sauvegardes automatiques
|
||||
|
@ -3018,7 +3018,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Proprié
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Municipalité{NBSP}: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Aucune
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordonnées{NBSP}: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construit le{NBSP}: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construit/rénové le{NBSP}: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Type de station{NBSP}: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Type de station{NBSP}: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Type d'aéroport{NBSP}: {LTBLUE}{STRING}
|
||||
|
|
|
@ -2727,7 +2727,7 @@ STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}자동
|
|||
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}차량기지를 건설합니다. 차량을 구입하거나 점검을 할 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}선로에 경유지를 설치합니다. CTRL 키를 사용하면 같은 이름의 경유지를 서로 떨어진 곳에 지을 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}철도역을 짓습니다. CTRL 키를 사용하면 같은 이름의 역을 서로 떨어진 곳에 지을 수 있습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}신호기를 설치합니다. CTRL 키를 누르면 구식/전자식으로 전환합니다.{}선로를 따라 드래그해서 설치할 수 있습니다. CTRL 키를 누른 채로 드래그하면 다음 분기점이나 다음 신호기까지 신호기를 설치합니다.{}CTRL 키를 누른 채 클릭하면 신호기 선택 창을 전환합니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}선로에 신호기를 설치합니다. CTRL 키를 누르면 구식/전자식으로 전환합니다.{}선로를 따라 드래그해서 설치할 수 있습니다. CTRL 키를 누른 채로 드래그하면 다음 분기점이나 다음 신호기까지 신호기를 설치합니다.{}CTRL 키를 누른 채 클릭하면 신호기 선택 창을 전환합니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}철교를 짓습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}터널을 짓습니다. SHIFT 키를 누른 채로 사용하면 예상 비용을 볼 수 있습니다
|
||||
STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}선로, 신호기, 경유지, 역 등의 철도 시설 건설/철거 모드를 켜거나 끌 수 있습니다. CTRL 키를 누르고 있어도 선로에서 경유지와 역을 제거할 수 있습니다
|
||||
|
|
|
@ -3018,7 +3018,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Dono da
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autoridade local: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhum
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído/renovado: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tipo de estação: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estação: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Tipo de aeroporto: {LTBLUE}{STRING}
|
||||
|
|
|
@ -3192,7 +3192,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Влад
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Администрация: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Нет
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Координаты: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Построено: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Построено/обновлено: {LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Класс станции: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Тип станции: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Класс аэропорта: {LTBLUE}{STRING.nom}
|
||||
|
|
|
@ -350,7 +350,7 @@ STR_SORT_BY_CARGO_CAPACITY :运载能力
|
|||
STR_SORT_BY_RANGE :航行距离
|
||||
STR_SORT_BY_POPULATION :人口
|
||||
STR_SORT_BY_RATING :评价
|
||||
STR_SORT_BY_NUM_VEHICLES :交通工具数量
|
||||
STR_SORT_BY_NUM_VEHICLES :载具数量
|
||||
STR_SORT_BY_TOTAL_PROFIT_LAST_YEAR :去年总利润
|
||||
STR_SORT_BY_TOTAL_PROFIT_THIS_YEAR :今年总利润
|
||||
STR_SORT_BY_AVERAGE_PROFIT_LAST_YEAR :去年平均利润
|
||||
|
@ -1325,7 +1325,7 @@ STR_CONFIG_SETTING_PERCENTAGE :{COMMA}%
|
|||
STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :汽车斜坡坡度: {STRING}
|
||||
STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :设置对汽车而言,一格斜坡的坡度大小。数值越高,坡度越大,汽车越难爬上斜坡。
|
||||
|
||||
STR_CONFIG_SETTING_FORBID_90_DEG :禁止列车 90 度转弯:{STRING}
|
||||
STR_CONFIG_SETTING_FORBID_90_DEG :禁止列车直角转向:{STRING}
|
||||
STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :当水平方向轨道与垂直方向轨道交叉时,没有采用45度的轨道组合连接,而是采用轨道90度直接连接时,列车通过时需要90度转弯,当本设置”打开“时,将禁止火车90度转弯。
|
||||
|
||||
STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :允许非毗邻站台合并:{STRING}
|
||||
|
@ -1344,7 +1344,7 @@ STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH :隧道最大长
|
|||
STR_CONFIG_SETTING_MAX_TUNNEL_LENGTH_HELPTEXT :建设隧道时允许的最大长度
|
||||
|
||||
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD :原料工业建设方式: {STRING}
|
||||
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :建立重工业企业的的设定. '禁止'表示不能建立; '勘探'表示可以建立但是只能在地图上一随机处, 并可能会失败; '像别的工业一样'表示采矿业也能像其它加工业那样可以随意在任何地方建立.
|
||||
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_HELPTEXT :设定原料工业的建造方式。“禁止”表示不能建造;“勘探”表示可以建立但是只能在地图上一随机处,并可能会失败;“同其他工业”表示可以和随意建造。
|
||||
###length 3
|
||||
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NONE :不允许
|
||||
STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD_NORMAL :同其他工业
|
||||
|
@ -1911,7 +1911,7 @@ STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :四倍(原版
|
|||
STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :线性
|
||||
|
||||
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :树木自动生长: {STRING}
|
||||
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制游戏中数目的随机生长,这将影响依赖树木的工业,比如木材厂
|
||||
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制游戏内树木的生长。此选项可能会影响一些依赖树木的工业,例如伐木场。
|
||||
###length 4
|
||||
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NO_SPREAD :生长但不扩散 {RED}(损坏伐木场)
|
||||
STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_SPREAD_RAINFOREST :仅在雨林扩散
|
||||
|
@ -2826,7 +2826,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}建设/
|
|||
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}转换/升级 公路类型。按住 Shift 键显示预计费用。
|
||||
STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :转换/升级 电车道类型。按住 Shift 键显示预计费用。
|
||||
|
||||
STR_ROAD_NAME_ROAD :路
|
||||
STR_ROAD_NAME_ROAD :公路
|
||||
STR_ROAD_NAME_TRAM :电车轨道
|
||||
|
||||
# Road depot construction window
|
||||
|
@ -3017,7 +3017,7 @@ STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}铁路
|
|||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}地方政府:{LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :没有
|
||||
STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}坐标: {LTBLUE}{NUM} × {NUM} × {NUM} ({STRING})
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}建造时间:{LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}建造/翻新于:{LTBLUE}{DATE_LONG}
|
||||
STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}车站分类: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}车站类型: {LTBLUE}{STRING}
|
||||
STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}飞机场分类: {LTBLUE}{STRING}
|
||||
|
@ -3246,7 +3246,7 @@ STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
|
|||
STR_MAPGEN_TERRAIN_TYPE :{BLACK}地形特点:
|
||||
STR_MAPGEN_SEA_LEVEL :{BLACK}海洋面积:
|
||||
STR_MAPGEN_SEA_LEVEL_TOOLTIP :{BLACK}选择海洋覆盖率
|
||||
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河流数量:
|
||||
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}河流数量:
|
||||
STR_MAPGEN_SMOOTHNESS :{BLACK}平滑程度:
|
||||
STR_MAPGEN_VARIETY :{BLACK}多样地形:
|
||||
STR_MAPGEN_GENERATE :{WHITE}生成
|
||||
|
@ -3854,7 +3854,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}运河
|
|||
STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}站台:
|
||||
STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS :{WHITE}车站
|
||||
STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS :{WHITE}机场
|
||||
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}每年{CURRENCY_LONG}
|
||||
STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENCY_LONG}/年
|
||||
|
||||
# Industry directory
|
||||
STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}工业设施
|
||||
|
@ -5625,7 +5625,7 @@ STR_VEHICLE_NAME_AIRCRAFT_POWERNAUT_HELICOPTER :Powernaut 直
|
|||
# Formatting of some strings
|
||||
STR_FORMAT_DATE_TINY :{ZEROFILL_NUM}-{ZEROFILL_NUM}-{NUM}
|
||||
STR_FORMAT_DATE_SHORT :{STRING} {NUM}
|
||||
STR_FORMAT_DATE_LONG :{2:NUM}年 {1:STRING}月 {0:STRING}日
|
||||
STR_FORMAT_DATE_LONG :{2:NUM} 年 {1:STRING} 月 {0:STRING} 日
|
||||
STR_FORMAT_DATE_ISO :{2:NUM}-{1:ZEROFILL_NUM}-{0:ZEROFILL_NUM}
|
||||
|
||||
STR_FORMAT_COMPANY_NUM :(公司 {COMMA})
|
||||
|
|
|
@ -24,7 +24,6 @@ static const uint16_t NETWORK_TURN_SERVER_PORT = 3974; ///< The
|
|||
static const uint16_t NETWORK_CONTENT_SERVER_PORT = 3978; ///< The default port of the content server (TCP)
|
||||
static const uint16_t NETWORK_DEFAULT_PORT = 3979; ///< The default port of the game server (TCP & UDP)
|
||||
static const uint16_t NETWORK_ADMIN_PORT = 3977; ///< The default port for admin network
|
||||
static const uint16_t NETWORK_DEFAULT_DEBUGLOG_PORT = 3982; ///< The default port debug-log is sent to (TCP)
|
||||
|
||||
static const uint16_t UDP_MTU = 1460; ///< Number of bytes we can pack in a single UDP packet
|
||||
|
||||
|
|
|
@ -1218,32 +1218,6 @@ static void NetworkGenerateServerId()
|
|||
_settings_client.network.network_id = GenerateUid("OpenTTD Server ID");
|
||||
}
|
||||
|
||||
class TCPNetworkDebugConnecter : TCPConnecter {
|
||||
private:
|
||||
std::string connection_string;
|
||||
|
||||
public:
|
||||
TCPNetworkDebugConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_DEBUGLOG_PORT), connection_string(connection_string) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
Debug(net, 0, "Failed to open connection to {} for redirecting Debug()", this->connection_string);
|
||||
}
|
||||
|
||||
void OnConnect(SOCKET s) override
|
||||
{
|
||||
Debug(net, 3, "Redirecting Debug() to {}", this->connection_string);
|
||||
|
||||
extern SOCKET _debug_socket;
|
||||
_debug_socket = s;
|
||||
}
|
||||
};
|
||||
|
||||
void NetworkStartDebugLog(const std::string &connection_string)
|
||||
{
|
||||
new TCPNetworkDebugConnecter(connection_string);
|
||||
}
|
||||
|
||||
/** This tries to launch the network for a given OS */
|
||||
void NetworkStartUp()
|
||||
{
|
||||
|
|
|
@ -47,7 +47,6 @@ void NetworkDisconnect(bool close_admins = true);
|
|||
void NetworkGameLoop();
|
||||
void NetworkBackgroundLoop();
|
||||
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16_t &port, CompanyID *company_id = nullptr);
|
||||
void NetworkStartDebugLog(const std::string &connection_string);
|
||||
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
|
||||
|
||||
void NetworkUpdateClientInfo(ClientID client_id);
|
||||
|
|
|
@ -169,7 +169,6 @@ static void ShowHelp()
|
|||
" -p password = Password to join server\n"
|
||||
" -P password = Password to join company\n"
|
||||
" -D [host][:port] = Start dedicated server\n"
|
||||
" -l host[:port] = Redirect Debug()\n"
|
||||
#if !defined(_WIN32)
|
||||
" -f = Fork into the background (dedicated only)\n"
|
||||
#endif
|
||||
|
@ -489,7 +488,6 @@ static const OptionData _options[] = {
|
|||
GETOPT_SHORT_VALUE('b'),
|
||||
GETOPT_SHORT_OPTVAL('D'),
|
||||
GETOPT_SHORT_VALUE('n'),
|
||||
GETOPT_SHORT_VALUE('l'),
|
||||
GETOPT_SHORT_VALUE('p'),
|
||||
GETOPT_SHORT_VALUE('P'),
|
||||
#if !defined(_WIN32)
|
||||
|
@ -528,7 +526,6 @@ int openttd_main(int argc, char *argv[])
|
|||
Dimension resolution = {0, 0};
|
||||
std::unique_ptr<AfterNewGRFScan> scanner(new AfterNewGRFScan());
|
||||
bool dedicated = false;
|
||||
char *debuglog_conn = nullptr;
|
||||
bool only_local_path = false;
|
||||
|
||||
extern bool _dedicated_forks;
|
||||
|
@ -565,9 +562,6 @@ int openttd_main(int argc, char *argv[])
|
|||
case 'n':
|
||||
scanner->connection_string = mgo.opt; // host:port#company parameter
|
||||
break;
|
||||
case 'l':
|
||||
debuglog_conn = mgo.opt;
|
||||
break;
|
||||
case 'p':
|
||||
scanner->join_server_password = mgo.opt;
|
||||
break;
|
||||
|
@ -762,10 +756,6 @@ int openttd_main(int argc, char *argv[])
|
|||
|
||||
NetworkStartUp(); // initialize network-core
|
||||
|
||||
if (debuglog_conn != nullptr && _network_available) {
|
||||
NetworkStartDebugLog(debuglog_conn);
|
||||
}
|
||||
|
||||
if (!HandleBootstrap()) {
|
||||
ShutdownGame();
|
||||
return ret;
|
||||
|
|
|
@ -180,14 +180,10 @@ void CoreTextFontCache::SetFontSize(int pixels)
|
|||
Debug(fontcache, 2, "Loaded font '{}' with size {}", this->font_name, pixels);
|
||||
}
|
||||
|
||||
GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key)
|
||||
GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
|
||||
{
|
||||
assert(IsPrintable(key));
|
||||
|
||||
if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
|
||||
return this->parent->MapCharToGlyph(key);
|
||||
}
|
||||
|
||||
/* Convert characters outside of the Basic Multilingual Plane into surrogate pairs. */
|
||||
UniChar chars[2];
|
||||
if (key >= 0x010000U) {
|
||||
|
@ -202,6 +198,10 @@ GlyphID CoreTextFontCache::MapCharToGlyph(char32_t key)
|
|||
return glyph[0];
|
||||
}
|
||||
|
||||
if (allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) {
|
||||
return this->parent->MapCharToGlyph(key);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -298,6 +298,40 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa)
|
|||
return new_glyph.sprite;
|
||||
}
|
||||
|
||||
static CTFontDescriptorRef LoadFontFromFile(const std::string &font_name)
|
||||
{
|
||||
if (!MacOSVersionIsAtLeast(10, 6, 0)) return nullptr;
|
||||
|
||||
/* Might be a font file name, try load it. Direct font loading is
|
||||
* only supported starting on OSX 10.6. */
|
||||
CFAutoRelease<CFStringRef> path;
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(font_name)) {
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, font_name.c_str(), kCFStringEncodingUTF8));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
|
||||
if (!full_font.empty()) {
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8));
|
||||
}
|
||||
}
|
||||
|
||||
if (path) {
|
||||
/* Try getting a font descriptor to see if the system can use it. */
|
||||
CFAutoRelease<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false));
|
||||
CFAutoRelease<CFArrayRef> descs(CTFontManagerCreateFontDescriptorsFromURL(url.get()));
|
||||
|
||||
if (descs && CFArrayGetCount(descs.get()) > 0) {
|
||||
CTFontDescriptorRef font_ref = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0);
|
||||
CFRetain(font_ref);
|
||||
return font_ref;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the TrueType font.
|
||||
* If a CoreText font description is present, e.g. from the automatic font
|
||||
|
@ -318,33 +352,9 @@ void LoadCoreTextFont(FontSize fs)
|
|||
}
|
||||
|
||||
if (!font_ref && MacOSVersionIsAtLeast(10, 6, 0)) {
|
||||
/* Might be a font file name, try load it. Direct font loading is
|
||||
* only supported starting on OSX 10.6. */
|
||||
CFAutoRelease<CFStringRef> path;
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(settings->font)) {
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, settings->font.c_str(), kCFStringEncodingUTF8));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, settings->font);
|
||||
if (!full_font.empty()) {
|
||||
path.reset(CFStringCreateWithCString(kCFAllocatorDefault, full_font.c_str(), kCFStringEncodingUTF8));
|
||||
}
|
||||
}
|
||||
|
||||
if (path) {
|
||||
/* Try getting a font descriptor to see if the system can use it. */
|
||||
CFAutoRelease<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false));
|
||||
CFAutoRelease<CFArrayRef> descs(CTFontManagerCreateFontDescriptorsFromURL(url.get()));
|
||||
|
||||
if (descs && CFArrayGetCount(descs.get()) > 0) {
|
||||
font_ref.reset((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0));
|
||||
CFRetain(font_ref.get());
|
||||
} else {
|
||||
ShowInfo("Unable to load file '{}' for {} font, using default OS font selection instead", settings->font, FontSizeToName(fs));
|
||||
}
|
||||
}
|
||||
/* Might be a font file name, try load it. */
|
||||
font_ref.reset(LoadFontFromFile(settings->font));
|
||||
if (!font_ref) ShowInfo("Unable to load file '{}' for {} font, using default OS font selection instead", settings->font, FontSizeToName(fs));
|
||||
}
|
||||
|
||||
if (!font_ref) {
|
||||
|
@ -372,3 +382,17 @@ void LoadCoreTextFont(FontSize fs)
|
|||
|
||||
new CoreTextFontCache(fs, std::move(font_ref), settings->size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a TrueType font from a file.
|
||||
* @param fs The font size to load.
|
||||
* @param file_name Path to the font file.
|
||||
* @param size Requested font size.
|
||||
*/
|
||||
void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size)
|
||||
{
|
||||
CFAutoRelease<CTFontDescriptorRef> font_ref{LoadFontFromFile(file_name)};
|
||||
if (font_ref) {
|
||||
new CoreTextFontCache(fs, std::move(font_ref), size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,13 @@ public:
|
|||
~CoreTextFontCache() {}
|
||||
|
||||
void ClearFontCache() override;
|
||||
GlyphID MapCharToGlyph(char32_t key) override;
|
||||
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
|
||||
std::string GetFontName() override { return font_name; }
|
||||
bool IsBuiltInFont() override { return false; }
|
||||
const void *GetOSHandle() override { return font.get(); }
|
||||
};
|
||||
|
||||
void LoadCoreTextFont(FontSize fs);
|
||||
void LoadCoreTextFont(FontSize fs, const std::string &file_name, uint size);
|
||||
|
||||
#endif /* FONT_OSX_H */
|
||||
|
|
|
@ -168,6 +168,9 @@ static CTRunDelegateCallbacks _sprite_font_callback = {
|
|||
CFAutoRelease<CFStringRef> base(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buff, length, kCFAllocatorNull));
|
||||
CFAttributedStringReplaceString(str.get(), CFRangeMake(0, 0), base.get());
|
||||
|
||||
const UniChar replacment_char = 0xFFFC;
|
||||
CFAutoRelease<CFStringRef> replacment_str(CFStringCreateWithCharacters(kCFAllocatorDefault, &replacment_char, 1));
|
||||
|
||||
/* Apply font and colour ranges to our string. This is important to make sure
|
||||
* that we get proper glyph boundaries on style changes. */
|
||||
int last = 0;
|
||||
|
@ -189,10 +192,12 @@ static CTRunDelegateCallbacks _sprite_font_callback = {
|
|||
CFAttributedStringSetAttribute(str.get(), CFRangeMake(last, i.first - last), kCTForegroundColorAttributeName, color);
|
||||
CGColorRelease(color);
|
||||
|
||||
/* Install a size callback for our special sprite glyphs. */
|
||||
/* Install a size callback for our special private-use sprite glyphs in case the font does not provide them. */
|
||||
for (ssize_t c = last; c < i.first; c++) {
|
||||
if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END) {
|
||||
if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END && i.second->fc->MapCharToGlyph(buff[c], false) == 0) {
|
||||
CFAutoRelease<CTRunDelegateRef> del(CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i.second->fc->GetSize() << 24))));
|
||||
/* According to the offical documentation, if a run delegate is used, the char should always be 0xFFFC. */
|
||||
CFAttributedStringReplaceString(str.get(), CFRangeMake(c, 1), replacment_str.get());
|
||||
CFAttributedStringSetAttribute(str.get(), CFRangeMake(c, 1), kCTRunDelegateAttributeName, del.get());
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +247,8 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font
|
|||
CGGlyph gl[this->glyphs.size()];
|
||||
CTRunGetGlyphs(run, CFRangeMake(0, 0), gl);
|
||||
for (size_t i = 0; i < this->glyphs.size(); i++) {
|
||||
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END) {
|
||||
if (buff[this->glyph_to_char[i]] >= SCC_SPRITE_START && buff[this->glyph_to_char[i]] <= SCC_SPRITE_END && (gl[i] == 0 || gl[i] == 3)) {
|
||||
/* A glyph of 0 indidicates not found, while apparently 3 is what char 0xFFFC maps to. */
|
||||
this->glyphs[i] = font->fc->MapCharToGlyph(buff[this->glyph_to_char[i]]);
|
||||
this->positions[i * 2 + 0] = pts[i].x;
|
||||
this->positions[i * 2 + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre
|
||||
|
|
|
@ -282,14 +282,10 @@ void Win32FontCache::ClearFontCache()
|
|||
return new_glyph.sprite;
|
||||
}
|
||||
|
||||
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key)
|
||||
/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(char32_t key, bool allow_fallback)
|
||||
{
|
||||
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) {
|
||||
|
@ -302,7 +298,8 @@ void Win32FontCache::ClearFontCache()
|
|||
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;
|
||||
if (glyphs[0] != 0xFFFF) return glyphs[0];
|
||||
return allow_fallback && key >= SCC_SPRITE_START && key <= SCC_SPRITE_END ? this->parent->MapCharToGlyph(key) : 0;
|
||||
}
|
||||
|
||||
/* virtual */ const void *Win32FontCache::InternalGetFontTable(uint32_t tag, size_t &length)
|
||||
|
@ -320,6 +317,66 @@ void Win32FontCache::ClearFontCache()
|
|||
}
|
||||
|
||||
|
||||
static bool TryLoadFontFromFile(const std::string &font_name, LOGFONT &logfont)
|
||||
{
|
||||
wchar_t fontPath[MAX_PATH] = {};
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(font_name)) {
|
||||
convert_to_fs(font_name, fontPath, lengthof(fontPath));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
|
||||
if (!full_font.empty()) {
|
||||
convert_to_fs(font_name, fontPath, lengthof(fontPath));
|
||||
}
|
||||
}
|
||||
|
||||
if (fontPath[0] != 0) {
|
||||
if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
|
||||
/* Try a nice little undocumented function first for getting the internal font name.
|
||||
* Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */
|
||||
static LibraryLoader _gdi32("gdi32.dll");
|
||||
typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
|
||||
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetFunction("GetFontResourceInfoW");
|
||||
|
||||
if (GetFontResourceInfo != nullptr) {
|
||||
/* Try to query an array of LOGFONTs that describe the file. */
|
||||
DWORD len = 0;
|
||||
if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) {
|
||||
LOGFONT *buf = (LOGFONT *)new byte[len];
|
||||
if (GetFontResourceInfo(fontPath, &len, buf, 2)) {
|
||||
logfont = *buf; // Just use first entry.
|
||||
}
|
||||
delete[](byte *)buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* No dice yet. Use the file name as the font face name, hoping it matches. */
|
||||
if (logfont.lfFaceName[0] == 0) {
|
||||
wchar_t fname[_MAX_FNAME];
|
||||
_wsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
|
||||
|
||||
wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE);
|
||||
logfont.lfWeight = strcasestr(font_name.c_str(), " bold") != nullptr || strcasestr(font_name.c_str(), "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return logfont.lfFaceName[0] != 0;
|
||||
}
|
||||
|
||||
static void LoadWin32Font(FontSize fs, const LOGFONT &logfont, uint size, const char *font_name)
|
||||
{
|
||||
HFONT font = CreateFontIndirect(&logfont);
|
||||
if (font == nullptr) {
|
||||
ShowInfo("Unable to use '{}' for {} font, Win32 reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), GetLastError());
|
||||
return;
|
||||
}
|
||||
DeleteObject(font);
|
||||
|
||||
new Win32FontCache(fs, logfont, size);
|
||||
}
|
||||
/**
|
||||
* Loads the GDI font.
|
||||
* If a GDI font description is present, e.g. from the automatic font
|
||||
|
@ -344,51 +401,8 @@ void LoadWin32Font(FontSize fs)
|
|||
logfont = *(const LOGFONT *)settings->os_handle;
|
||||
} else if (strchr(font_name, '.') != nullptr) {
|
||||
/* Might be a font file name, try load it. */
|
||||
|
||||
wchar_t fontPath[MAX_PATH] = {};
|
||||
|
||||
/* See if this is an absolute path. */
|
||||
if (FileExists(settings->font)) {
|
||||
convert_to_fs(font_name, fontPath, lengthof(fontPath));
|
||||
} else {
|
||||
/* Scan the search-paths to see if it can be found. */
|
||||
std::string full_font = FioFindFullPath(BASE_DIR, font_name);
|
||||
if (!full_font.empty()) {
|
||||
convert_to_fs(font_name, fontPath, lengthof(fontPath));
|
||||
}
|
||||
}
|
||||
|
||||
if (fontPath[0] != 0) {
|
||||
if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) {
|
||||
/* Try a nice little undocumented function first for getting the internal font name.
|
||||
* Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */
|
||||
static LibraryLoader _gdi32("gdi32.dll");
|
||||
typedef BOOL(WINAPI *PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD);
|
||||
static PFNGETFONTRESOURCEINFO GetFontResourceInfo = _gdi32.GetFunction("GetFontResourceInfoW");
|
||||
|
||||
if (GetFontResourceInfo != nullptr) {
|
||||
/* Try to query an array of LOGFONTs that describe the file. */
|
||||
DWORD len = 0;
|
||||
if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) {
|
||||
LOGFONT *buf = (LOGFONT *)new byte[len];
|
||||
if (GetFontResourceInfo(fontPath, &len, buf, 2)) {
|
||||
logfont = *buf; // Just use first entry.
|
||||
}
|
||||
delete[] (byte *)buf;
|
||||
}
|
||||
}
|
||||
|
||||
/* No dice yet. Use the file name as the font face name, hoping it matches. */
|
||||
if (logfont.lfFaceName[0] == 0) {
|
||||
wchar_t fname[_MAX_FNAME];
|
||||
_wsplitpath(fontPath, nullptr, nullptr, fname, nullptr);
|
||||
|
||||
wcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE);
|
||||
logfont.lfWeight = strcasestr(font_name, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts.
|
||||
}
|
||||
} else {
|
||||
ShowInfo("Unable to load file '{}' for {} font, using default windows font selection instead", font_name, FontSizeToName(fs));
|
||||
}
|
||||
if (!TryLoadFontFromFile(settings->font, logfont)) {
|
||||
ShowInfo("Unable to load file '{}' for {} font, using default windows font selection instead", font_name, FontSizeToName(fs));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,12 +411,25 @@ void LoadWin32Font(FontSize fs)
|
|||
convert_to_fs(font_name, logfont.lfFaceName, lengthof(logfont.lfFaceName));
|
||||
}
|
||||
|
||||
HFONT font = CreateFontIndirect(&logfont);
|
||||
if (font == nullptr) {
|
||||
ShowInfo("Unable to use '{}' for {} font, Win32 reported error 0x{:X}, using sprite font instead", font_name, FontSizeToName(fs), GetLastError());
|
||||
return;
|
||||
}
|
||||
DeleteObject(font);
|
||||
|
||||
new Win32FontCache(fs, logfont, settings->size);
|
||||
LoadWin32Font(fs, logfont, settings->size, font_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a TrueType font from a file.
|
||||
* @param fs The font size to load.
|
||||
* @param file_name Path to the font file.
|
||||
* @param size Requested font size.
|
||||
*/
|
||||
void LoadWin32Font(FontSize fs, const std::string &file_name, uint size)
|
||||
{
|
||||
LOGFONT logfont;
|
||||
MemSetT(&logfont, 0);
|
||||
logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH;
|
||||
logfont.lfCharSet = DEFAULT_CHARSET;
|
||||
logfont.lfOutPrecision = OUT_OUTLINE_PRECIS;
|
||||
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
|
||||
|
||||
if (TryLoadFontFromFile(file_name, logfont)) {
|
||||
LoadWin32Font(fs, logfont, size, file_name.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,11 +35,12 @@ public:
|
|||
Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels);
|
||||
~Win32FontCache();
|
||||
void ClearFontCache() override;
|
||||
GlyphID MapCharToGlyph(char32_t key) override;
|
||||
GlyphID MapCharToGlyph(char32_t key, bool allow_fallback = true) override;
|
||||
std::string GetFontName() override { return this->fontname; }
|
||||
const void *GetOSHandle() override { return &this->logfont; }
|
||||
};
|
||||
|
||||
void LoadWin32Font(FontSize fs);
|
||||
void LoadWin32Font(FontSize fs, const std::string &file_name, uint size);
|
||||
|
||||
#endif /* FONT_WIN32_H */
|
||||
|
|
|
@ -194,9 +194,11 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b
|
|||
for (int i = 0; i < range.len; i++) {
|
||||
if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) {
|
||||
auto pos = range.char_to_glyph[i];
|
||||
range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
|
||||
range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre
|
||||
range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]);
|
||||
if (range.ft_glyphs[pos] == 0) { // Font doesn't have our special glyph, so remap.
|
||||
range.ft_glyphs[pos] = range.font->fc->MapCharToGlyph(buff[range.pos + i]);
|
||||
range.offsets[pos].dv = (range.font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(range.font->fc->GetSize()))) / 2; // Align sprite font to centre
|
||||
range.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,10 @@
|
|||
#include "safeguards.h"
|
||||
|
||||
|
||||
#if defined(WITH_FREETYPE) || defined(_WIN32) || defined(WITH_COCOA)
|
||||
# define HAS_TRUETYPE_FONT
|
||||
#endif
|
||||
|
||||
static const StringID _autosave_dropdown[] = {
|
||||
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF,
|
||||
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_10_MINUTES,
|
||||
|
@ -559,6 +563,31 @@ struct GameOptionsWindow : Window {
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef HAS_TRUETYPE_FONT
|
||||
case WID_GO_GUI_FONT_SPRITE:
|
||||
_fcsettings.prefer_sprite = !_fcsettings.prefer_sprite;
|
||||
|
||||
this->SetWidgetLoweredState(WID_GO_GUI_FONT_SPRITE, _fcsettings.prefer_sprite);
|
||||
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
|
||||
this->SetDirty();
|
||||
|
||||
InitFontCache(false);
|
||||
InitFontCache(true);
|
||||
ClearFontCache();
|
||||
SetupWidgetDimensions();
|
||||
ReInitAllWindows(true);
|
||||
break;
|
||||
|
||||
case WID_GO_GUI_FONT_AA:
|
||||
_fcsettings.global_aa = !_fcsettings.global_aa;
|
||||
|
||||
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
|
||||
this->SetDirty();
|
||||
|
||||
ClearFontCache();
|
||||
break;
|
||||
#endif /* HAS_TRUETYPE_FONT */
|
||||
|
||||
case WID_GO_GUI_SCALE:
|
||||
if (ClickSliderWidget(this->GetWidget<NWidgetBase>(widget)->GetCurrentRect(), pt, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE, this->gui_scale)) {
|
||||
if (!_ctrl_pressed) this->gui_scale = ((this->gui_scale + 12) / 25) * 25;
|
||||
|
@ -750,6 +779,11 @@ struct GameOptionsWindow : Window {
|
|||
|
||||
this->SetWidgetLoweredState(WID_GO_GUI_SCALE_AUTO, _gui_scale_cfg == -1);
|
||||
this->SetWidgetLoweredState(WID_GO_GUI_SCALE_BEVEL_BUTTON, _settings_client.gui.scale_bevels);
|
||||
#ifdef HAS_TRUETYPE_FONT
|
||||
this->SetWidgetLoweredState(WID_GO_GUI_FONT_SPRITE, _fcsettings.prefer_sprite);
|
||||
this->SetWidgetLoweredState(WID_GO_GUI_FONT_AA, _fcsettings.global_aa);
|
||||
this->SetWidgetDisabledState(WID_GO_GUI_FONT_AA, _fcsettings.prefer_sprite);
|
||||
#endif /* HAS_TRUETYPE_FONT */
|
||||
|
||||
this->SetWidgetDisabledState(WID_GO_BASE_GRF_DROPDOWN, _game_mode != GM_MENU);
|
||||
this->SetWidgetDisabledState(WID_GO_BASE_SFX_DROPDOWN, _game_mode != GM_MENU);
|
||||
|
@ -823,6 +857,16 @@ static const NWidgetPart _nested_game_options_widgets[] = {
|
|||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_SCALE_BEVELS, STR_NULL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_SCALE_BEVEL_BUTTON), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP),
|
||||
EndContainer(),
|
||||
#ifdef HAS_TRUETYPE_FONT
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_SPRITE, STR_NULL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_SPRITE), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_SPRITE_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_normal, 0),
|
||||
NWidget(WWT_TEXT, COLOUR_GREY), SetMinimalSize(0, 12), SetFill(1, 0), SetDataTip(STR_GAME_OPTIONS_GUI_FONT_AA, STR_NULL),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GO_GUI_FONT_AA), SetMinimalSize(21, 9), SetDataTip(STR_EMPTY, STR_GAME_OPTIONS_GUI_FONT_AA_TOOLTIP),
|
||||
EndContainer(),
|
||||
#endif /* HAS_TRUETYPE_FONT */
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
|
|
|
@ -258,6 +258,18 @@ name = ""mono_aa""
|
|||
var = _fcsettings.mono.aa
|
||||
def = false
|
||||
|
||||
[SDTG_BOOL]
|
||||
ifdef = HAS_TRUETYPE_FONT
|
||||
name = ""global_aa""
|
||||
var = _fcsettings.global_aa
|
||||
def = true
|
||||
|
||||
[SDTG_BOOL]
|
||||
ifdef = HAS_TRUETYPE_FONT
|
||||
name = ""prefer_sprite_font""
|
||||
var = _fcsettings.prefer_sprite
|
||||
def = false
|
||||
|
||||
[SDTG_VAR]
|
||||
name = ""sprite_cache_size_px""
|
||||
type = SLE_UINT
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
const Sprite *GetGlyph(GlyphID) override { return nullptr; }
|
||||
uint GetGlyphWidth(GlyphID) override { return this->height / 2; }
|
||||
bool GetDrawGlyphShadow() override { return false; }
|
||||
GlyphID MapCharToGlyph(char32_t key) override { return key; }
|
||||
GlyphID MapCharToGlyph(char32_t key, [[maybe_unused]] bool allow_fallback = true) override { return key; }
|
||||
const void *GetFontTable(uint32_t, size_t &length) override { length = 0; return nullptr; }
|
||||
std::string GetFontName() override { return "mock"; }
|
||||
bool IsBuiltInFont() override { return true; }
|
||||
|
|
|
@ -59,13 +59,15 @@ static void FindResolutions()
|
|||
{
|
||||
_resolutions.clear();
|
||||
|
||||
for (int i = 0; i < SDL_GetNumDisplayModes(0); i++) {
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetDisplayMode(0, i, &mode);
|
||||
for (int display = 0; display < SDL_GetNumVideoDisplays(); display++) {
|
||||
for (int i = 0; i < SDL_GetNumDisplayModes(display); i++) {
|
||||
SDL_DisplayMode mode;
|
||||
SDL_GetDisplayMode(display, i, &mode);
|
||||
|
||||
if (mode.w < 640 || mode.h < 480) continue;
|
||||
if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(mode.w, mode.h)) != _resolutions.end()) continue;
|
||||
_resolutions.emplace_back(mode.w, mode.h);
|
||||
if (mode.w < 640 || mode.h < 480) continue;
|
||||
if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(mode.w, mode.h)) != _resolutions.end()) continue;
|
||||
_resolutions.emplace_back(mode.w, mode.h);
|
||||
}
|
||||
}
|
||||
|
||||
/* We have found no resolutions, show the default list */
|
||||
|
@ -663,7 +665,7 @@ bool VideoDriver_SDL_Base::ToggleFullscreen(bool fullscreen)
|
|||
if (fullscreen) {
|
||||
/* Find fullscreen window size */
|
||||
SDL_DisplayMode dm;
|
||||
if (SDL_GetCurrentDisplayMode(0, &dm) < 0) {
|
||||
if (SDL_GetCurrentDisplayMode(SDL_GetWindowDisplayIndex(this->sdl_window), &dm) < 0) {
|
||||
Debug(driver, 0, "SDL_GetCurrentDisplayMode() failed: {}", SDL_GetError());
|
||||
} else {
|
||||
SDL_SetWindowSize(this->sdl_window, dm.w, dm.h);
|
||||
|
|
|
@ -25,6 +25,8 @@ enum GameOptionsWidgets : WidgetID {
|
|||
WID_GO_GUI_SCALE, ///< GUI Scale slider.
|
||||
WID_GO_GUI_SCALE_AUTO, ///< Autodetect GUI scale button.
|
||||
WID_GO_GUI_SCALE_BEVEL_BUTTON, ///< Toggle for chunky bevels.
|
||||
WID_GO_GUI_FONT_SPRITE, ///< Toggle whether to prefer the sprite font over TTF fonts.
|
||||
WID_GO_GUI_FONT_AA, ///< Toggle whether to anti-alias fonts.
|
||||
WID_GO_BASE_GRF_DROPDOWN, ///< Use to select a base GRF.
|
||||
WID_GO_BASE_GRF_PARAMETERS, ///< Base GRF parameters.
|
||||
WID_GO_BASE_GRF_OPEN_URL, ///< Open base GRF URL.
|
||||
|
|
Loading…
Reference in New Issue