split gui1 font interface into a font_config and sdl_ttf interface
move all of these into font folder
This commit is contained in:
parent
df8f42c26d
commit
e3417bd954
45 changed files with 1515 additions and 1210 deletions
|
@ -150,7 +150,8 @@ if(ENABLE_FRIBIDI AND FRIBIDI_FOUND)
|
|||
include_directories(SYSTEM ${FRIBIDI_INCLUDE_DIRS} )
|
||||
# latest FriBiDi deprecated some functions we rely on...
|
||||
set_source_files_properties(
|
||||
font.cpp
|
||||
font/sdl_ttf.cpp
|
||||
font/text_surface.cpp
|
||||
PROPERTIES COMPILE_FLAGS
|
||||
"-Wno-deprecated-declarations -Wno-unused-result"
|
||||
)
|
||||
|
@ -984,7 +985,10 @@ set(libwesnoth-game_STAT_SRC
|
|||
display_context.cpp
|
||||
events.cpp
|
||||
floating_label.cpp
|
||||
font.cpp
|
||||
font/font_config.cpp
|
||||
font/sdl_ttf.cpp
|
||||
font/text_cache.cpp
|
||||
font/text_surface.cpp
|
||||
format_time_summary.cpp
|
||||
generators/cave_map_generator.cpp
|
||||
generators/map_create.cpp
|
||||
|
|
|
@ -90,7 +90,10 @@ libwesnoth_sources = Split("""
|
|||
display.cpp
|
||||
events.cpp
|
||||
floating_label.cpp
|
||||
font.cpp
|
||||
font/font_config.cpp
|
||||
font/sdl_ttf.cpp
|
||||
font/text_cache.cpp
|
||||
font/text_surface.cpp
|
||||
format_time_summary.cpp
|
||||
game_end_exceptions.cpp
|
||||
generators/cave_map_generator.cpp
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "config.hpp"
|
||||
|
||||
#include "addon/manager.hpp"
|
||||
#include "font.hpp"
|
||||
#include "log.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace wb {
|
|||
#include "animated.hpp"
|
||||
#include "display_context.hpp"
|
||||
#include "filter_context.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "image.hpp" //only needed for enums (!)
|
||||
#include "key.hpp"
|
||||
#include "team.hpp"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "tristate_button.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "image.hpp"
|
||||
#include "log.hpp"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "floating_label.hpp"
|
||||
|
||||
#include "display.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "log.hpp"
|
||||
#include "text.hpp"
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "font.hpp"
|
||||
|
||||
#include "sdl/utils.hpp"
|
||||
#include <string>
|
||||
|
||||
|
|
1128
src/font.cpp
1128
src/font.cpp
File diff suppressed because it is too large
Load diff
259
src/font/font_config.cpp
Normal file
259
src/font/font_config.cpp
Normal file
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "font_config.hpp"
|
||||
#include "font_description.hpp"
|
||||
#include "sdl_ttf.hpp"
|
||||
|
||||
#include "config.hpp"
|
||||
#include "log.hpp"
|
||||
#include "tstring.hpp"
|
||||
|
||||
#include "filesystem.hpp"
|
||||
#include "game_config.hpp"
|
||||
|
||||
#include "serialization/parser.hpp"
|
||||
#include "serialization/preprocessor.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
#include "serialization/unicode.hpp"
|
||||
#include "preferences.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <stack>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#include <cairo-features.h>
|
||||
|
||||
#ifdef CAIRO_HAS_WIN32_FONT
|
||||
#include <windows.h>
|
||||
#undef CAIRO_HAS_FT_FONT
|
||||
#endif
|
||||
|
||||
#ifdef CAIRO_HAS_FT_FONT
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#endif
|
||||
|
||||
#if !defined(CAIRO_HAS_FT_FONT) && !defined(CAIRO_HAS_WIN32_FONT)
|
||||
#error unable to find font loading tools.
|
||||
#endif
|
||||
|
||||
static lg::log_domain log_font("font");
|
||||
#define DBG_FT LOG_STREAM(debug, log_font)
|
||||
#define LOG_FT LOG_STREAM(info, log_font)
|
||||
#define WRN_FT LOG_STREAM(warn, log_font)
|
||||
#define ERR_FT LOG_STREAM(err, log_font)
|
||||
|
||||
namespace font {
|
||||
|
||||
|
||||
bool check_font_file(std::string name) {
|
||||
if(game_config::path.empty() == false) {
|
||||
if(!filesystem::file_exists(game_config::path + "/fonts/" + name)) {
|
||||
if(!filesystem::file_exists("fonts/" + name)) {
|
||||
if(!filesystem::file_exists(name)) {
|
||||
WRN_FT << "Failed opening font file '" << name << "': No such file or directory" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(!filesystem::file_exists("fonts/" + name)) {
|
||||
if(!filesystem::file_exists(name)) {
|
||||
WRN_FT << "Failed opening font file '" << name << "': No such file or directory" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool add_font_to_fontlist(const config &fonts_config,
|
||||
std::vector<font::subset_descriptor>& fontlist, const std::string& name)
|
||||
{
|
||||
const config &font = fonts_config.find_child("font", "name", name);
|
||||
if (!font) {
|
||||
return false;
|
||||
}
|
||||
//DBG_FT << "Adding a font record: " << font.debug() << std::endl;
|
||||
|
||||
fontlist.push_back(font::subset_descriptor(font));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Current font family for sanserif and monospace fonts in the game
|
||||
|
||||
t_string family_order_sans;
|
||||
t_string family_order_mono;
|
||||
|
||||
/***
|
||||
* Public interface
|
||||
*/
|
||||
|
||||
bool load_font_config()
|
||||
{
|
||||
//read font config separately, so we do not have to re-read the whole
|
||||
//config when changing languages
|
||||
config cfg;
|
||||
try {
|
||||
const std::string& cfg_path = filesystem::get_wml_location("hardwired/fonts.cfg");
|
||||
if(cfg_path.empty()) {
|
||||
ERR_FT << "could not resolve path to fonts.cfg, file not found\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
filesystem::scoped_istream stream = preprocess_file(cfg_path);
|
||||
read(cfg, *stream);
|
||||
} catch(config::error &e) {
|
||||
ERR_FT << "could not read fonts.cfg:\n"
|
||||
<< e.message << '\n';
|
||||
return false;
|
||||
}
|
||||
|
||||
const config &fonts_config = cfg.child("fonts");
|
||||
if (!fonts_config)
|
||||
return false;
|
||||
|
||||
std::set<std::string> known_fonts;
|
||||
for (const config &font : fonts_config.child_range("font")) {
|
||||
known_fonts.insert(font["name"]);
|
||||
if (font.has_attribute("bold_name")) {
|
||||
known_fonts.insert(font["bold_name"]);
|
||||
}
|
||||
if (font.has_attribute("italic_name")) {
|
||||
known_fonts.insert(font["italic_name"]);
|
||||
}
|
||||
}
|
||||
|
||||
family_order_sans = fonts_config["family_order"];
|
||||
family_order_mono = fonts_config["family_order_monospace"];
|
||||
|
||||
if(family_order_mono.empty()) {
|
||||
ERR_FT << "No monospace font family order defined, falling back to sans serif order\n";
|
||||
family_order_mono = family_order_sans;
|
||||
}
|
||||
|
||||
std::vector<font::subset_descriptor> fontlist;
|
||||
|
||||
for(auto font : utils::split(fonts_config["order"])) {
|
||||
add_font_to_fontlist(fonts_config, fontlist, font);
|
||||
known_fonts.erase(font);
|
||||
}
|
||||
|
||||
for(auto kfont : known_fonts) {
|
||||
add_font_to_fontlist(fonts_config, fontlist, kfont);
|
||||
}
|
||||
|
||||
if(fontlist.empty())
|
||||
return false;
|
||||
|
||||
sdl_ttf::set_font_list(fontlist);
|
||||
return true;
|
||||
}
|
||||
|
||||
const t_string& get_font_families(family_class fclass)
|
||||
{
|
||||
switch(fclass) {
|
||||
case FONT_MONOSPACE:
|
||||
return family_order_mono;
|
||||
default:
|
||||
return family_order_sans;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Manager methods
|
||||
*/
|
||||
|
||||
manager::manager() {
|
||||
this->init();
|
||||
}
|
||||
|
||||
manager::~manager() {
|
||||
this->deinit();
|
||||
}
|
||||
|
||||
void manager::update_font_path() const
|
||||
{
|
||||
this->deinit();
|
||||
this->init();
|
||||
}
|
||||
|
||||
void manager::init() const
|
||||
{
|
||||
#ifdef CAIRO_HAS_FT_FONT
|
||||
if (!FcConfigAppFontAddDir(FcConfigGetCurrent(),
|
||||
reinterpret_cast<const FcChar8 *>((game_config::path + "/fonts").c_str())))
|
||||
{
|
||||
ERR_FT << "Could not load the true type fonts" << std::endl;
|
||||
throw error();
|
||||
}
|
||||
|
||||
if(!FcConfigParseAndLoad(FcConfigGetCurrent(),
|
||||
reinterpret_cast<const FcChar8*>((game_config::path + "/fonts/fonts.conf").c_str()),
|
||||
FcFalse))
|
||||
{
|
||||
ERR_FT << "Could not load local font configuration\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_FT << "Local font configuration loaded\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CAIRO_HAS_WIN32_FONT
|
||||
for(const std::string& path : filesystem::get_binary_paths("fonts")) {
|
||||
std::vector<std::string> files;
|
||||
if(filesystem::is_directory(path)) {
|
||||
filesystem::get_files_in_dir(path, &files, nullptr, filesystem::ENTIRE_FILE_PATH);
|
||||
}
|
||||
for(const std::string& file : files) {
|
||||
if(file.substr(file.length() - 4) == ".ttf" || file.substr(file.length() - 4) == ".ttc")
|
||||
{
|
||||
const std::wstring wfile = unicode_cast<std::wstring>(file);
|
||||
AddFontResourceExW(wfile.c_str(), FR_PRIVATE, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void manager::deinit() const
|
||||
{
|
||||
#ifdef CAIRO_HAS_FT_FONT
|
||||
FcConfigAppFontClear(FcConfigGetCurrent());
|
||||
#endif
|
||||
|
||||
#if CAIRO_HAS_WIN32_FONT
|
||||
for(const std::string& path : filesystem::get_binary_paths("fonts")) {
|
||||
std::vector<std::string> files;
|
||||
if(filesystem::is_directory(path))
|
||||
filesystem::get_files_in_dir(path, &files, nullptr, filesystem::ENTIRE_FILE_PATH);
|
||||
for(const std::string& file : files) {
|
||||
if(file.substr(file.length() - 4) == ".ttf" || file.substr(file.length() - 4) == ".ttc")
|
||||
{
|
||||
const std::wstring wfile = unicode_cast<std::wstring>(file);
|
||||
RemoveFontResourceExW(wfile.c_str(), FR_PRIVATE, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // end namespace font
|
72
src/font/font_config.hpp
Normal file
72
src/font/font_config.hpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
#ifndef FONT_FONT_CONFIG_HPP_INCLUDED
|
||||
#define FONT_FONT_CONFIG_HPP_INCLUDED
|
||||
|
||||
/***
|
||||
* The font::manager initializes cairo and font_config in order to figure out
|
||||
* what local fonts to use. It also asks SDL_TTF to initialize itself, via the
|
||||
* sdl_ttf raii object.
|
||||
*/
|
||||
|
||||
#include "exceptions.hpp"
|
||||
#include "font_options.hpp"
|
||||
#include "sdl_ttf.hpp"
|
||||
|
||||
class t_string;
|
||||
|
||||
namespace font {
|
||||
|
||||
//object which initializes and destroys structures needed for fonts
|
||||
//
|
||||
struct manager {
|
||||
manager();
|
||||
~manager();
|
||||
|
||||
/**
|
||||
* Updates the font path, when initialized it sets the fontpath to
|
||||
* game_config::path. When this path is updated, this function should be
|
||||
* called.
|
||||
*/
|
||||
void update_font_path() const;
|
||||
|
||||
struct error : public game::error {
|
||||
error() : game::error("Font initialization failed") {}
|
||||
};
|
||||
private:
|
||||
/** Initializes the font path. */
|
||||
void init() const;
|
||||
|
||||
/** Deinitializes the font path. */
|
||||
void deinit() const;
|
||||
|
||||
/** Initialize sdl_ttf concurrent with font::manager lifetime */
|
||||
sdl_ttf sdl_ttf_initializer_;
|
||||
};
|
||||
|
||||
/***
|
||||
* load_font_config actually searches the game font path for fonts, and refreshes
|
||||
* the set of loaded fonts
|
||||
*/
|
||||
bool load_font_config();
|
||||
|
||||
/** Returns the currently defined fonts. */
|
||||
const t_string& get_font_families(family_class fclass = FONT_SANS_SERIF);
|
||||
|
||||
/** Test if a font file exists */
|
||||
bool check_font_file(std::string name);
|
||||
|
||||
} // end namespace font
|
||||
|
||||
#endif
|
82
src/font/font_description.hpp
Normal file
82
src/font/font_description.hpp
Normal file
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifndef FONT_FONT_DESCRIPTION_HPP
|
||||
#define FONT_FONT_DESCRIPTION_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
#include "util.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace font {
|
||||
|
||||
// structure used to describe a font, and the subset of the Unicode character
|
||||
// set it covers.
|
||||
//
|
||||
// used by font_config interface (not specific to sdl_ttf or pango)
|
||||
struct subset_descriptor
|
||||
{
|
||||
subset_descriptor()
|
||||
: name()
|
||||
, bold_name()
|
||||
, italic_name()
|
||||
, present_codepoints()
|
||||
{
|
||||
}
|
||||
|
||||
explicit subset_descriptor(const config & font)
|
||||
: name(font["name"].str())
|
||||
, bold_name()
|
||||
, italic_name()
|
||||
, present_codepoints()
|
||||
{
|
||||
if (font.has_attribute("bold_name")) {
|
||||
bold_name = font["bold_name"].str();
|
||||
}
|
||||
|
||||
if (font.has_attribute("italic_name")) {
|
||||
italic_name = font["italic_name"].str();
|
||||
}
|
||||
|
||||
std::vector<std::string> ranges = utils::split(font["codepoints"]);
|
||||
|
||||
for (const std::string & i : ranges) {
|
||||
std::vector<std::string> r = utils::split(i, '-');
|
||||
if(r.size() == 1) {
|
||||
size_t r1 = lexical_cast_default<size_t>(r[0], 0);
|
||||
present_codepoints.push_back(std::pair<size_t, size_t>(r1, r1));
|
||||
} else if(r.size() == 2) {
|
||||
size_t r1 = lexical_cast_default<size_t>(r[0], 0);
|
||||
size_t r2 = lexical_cast_default<size_t>(r[1], 0);
|
||||
|
||||
present_codepoints.push_back(std::pair<size_t, size_t>(r1, r2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string name;
|
||||
boost::optional<std::string> bold_name; //If we are using another font for styled characters in this font, rather than SDL TTF method
|
||||
boost::optional<std::string> italic_name;
|
||||
|
||||
typedef std::pair<int, int> range;
|
||||
std::vector<range> present_codepoints;
|
||||
};
|
||||
|
||||
} // end namespace font
|
||||
#endif
|
74
src/font/font_id.hpp
Normal file
74
src/font/font_id.hpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/***
|
||||
* Note: Specific to SDL_TTF code path
|
||||
*/
|
||||
|
||||
#ifndef FONT_FONT_ID_HPP
|
||||
#define FONT_FONT_ID_HPP
|
||||
|
||||
#include <string>
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
/***
|
||||
* Note: This is specific to SDL_TTF code path
|
||||
*/
|
||||
|
||||
namespace font {
|
||||
|
||||
// Signed int. Negative values mean "no subset".
|
||||
typedef int subset_id;
|
||||
|
||||
// Used as a key in the font table, which caches the get_font results.
|
||||
struct font_id
|
||||
{
|
||||
explicit font_id(subset_id subset, int size) : subset(subset), size(size), style(TTF_STYLE_NORMAL) {}
|
||||
explicit font_id(subset_id subset, int size, int style) : subset(subset), size(size), style(style) {}
|
||||
|
||||
bool operator==(const font_id& o) const
|
||||
{
|
||||
return subset == o.subset && size == o.size && style == o.style;
|
||||
}
|
||||
bool operator<(const font_id& o) const
|
||||
{
|
||||
return subset < o.subset || (subset == o.subset && size < o.size) || (subset == o.subset && size == o.size && style < o.style);
|
||||
}
|
||||
|
||||
subset_id subset;
|
||||
int size;
|
||||
int style;
|
||||
};
|
||||
|
||||
/***
|
||||
* Text chunk is used by text_surfaces and these are cached sometimes.
|
||||
*/
|
||||
struct text_chunk
|
||||
{
|
||||
text_chunk(subset_id subset) :
|
||||
subset(subset),
|
||||
text()
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(text_chunk const & t) const { return subset == t.subset && text == t.text; }
|
||||
bool operator!=(text_chunk const & t) const { return !operator==(t); }
|
||||
|
||||
subset_id subset;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
} // end namespace font
|
||||
|
||||
#endif
|
592
src/font/sdl_ttf.cpp
Normal file
592
src/font/sdl_ttf.cpp
Normal file
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "sdl_ttf.hpp"
|
||||
|
||||
#include "font_config.hpp"
|
||||
#include "font_id.hpp"
|
||||
#include "text_cache.hpp"
|
||||
#include "text_surface.hpp"
|
||||
|
||||
#include "filesystem.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "log.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "preferences.hpp"
|
||||
#include "tooltips.hpp"
|
||||
|
||||
#include "sdl/image.hpp"
|
||||
#include "sdl/rect.hpp"
|
||||
#include "sdl/utils.hpp"
|
||||
#include "serialization/unicode.hpp"
|
||||
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
static lg::log_domain log_font("font");
|
||||
#define DBG_FT LOG_STREAM(debug, log_font)
|
||||
#define LOG_FT LOG_STREAM(info, log_font)
|
||||
#define WRN_FT LOG_STREAM(warn, log_font)
|
||||
#define ERR_FT LOG_STREAM(err, log_font)
|
||||
|
||||
namespace font {
|
||||
|
||||
/***
|
||||
* Caches used to speed up font rendering
|
||||
*/
|
||||
|
||||
// Record stored in the font table.
|
||||
// If the record for font_id (FOO, Bold + Underline) is a record (BAR, Bold),
|
||||
// it means that BAR is a Bold-styled version of FOO which we shipped with the
|
||||
// game, and now SDL_TTF should be used to style BAR as underline for the final results.
|
||||
struct ttf_record
|
||||
{
|
||||
TTF_Font* font;
|
||||
int style;
|
||||
};
|
||||
|
||||
typedef std::map<font_id, ttf_record> tfont_table;
|
||||
|
||||
static tfont_table font_table;
|
||||
static std::vector<std::string> font_names;
|
||||
static std::vector<std::string> bold_names;
|
||||
static std::vector<std::string> italic_names;
|
||||
|
||||
struct char_block_map
|
||||
{
|
||||
char_block_map()
|
||||
: cbmap()
|
||||
{
|
||||
}
|
||||
|
||||
typedef std::pair<int, subset_id> block_t;
|
||||
typedef std::map<int, block_t> cbmap_t;
|
||||
cbmap_t cbmap;
|
||||
/** Associates not-associated parts of a range with a new font. */
|
||||
void insert(int first, int last, subset_id id)
|
||||
{
|
||||
if (first > last) return;
|
||||
cbmap_t::iterator i = cbmap.lower_bound(first);
|
||||
// At this point, either first <= i->first or i is past the end.
|
||||
if (i != cbmap.begin()) {
|
||||
cbmap_t::iterator j = i;
|
||||
--j;
|
||||
if (first <= j->second.first /* prev.last */) {
|
||||
insert(j->second.first + 1, last, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i != cbmap.end()) {
|
||||
if (/* next.first */ i->first <= last) {
|
||||
insert(first, i->first - 1, id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cbmap.insert(std::make_pair(first, block_t(last, id)));
|
||||
}
|
||||
/**
|
||||
* Compresses map by merging consecutive ranges with the same font, even
|
||||
* if there is some unassociated ranges in-between.
|
||||
*/
|
||||
void compress()
|
||||
{
|
||||
LOG_FT << "Font map size before compression: " << cbmap.size() << " ranges\n";
|
||||
cbmap_t::iterator i = cbmap.begin(), e = cbmap.end();
|
||||
while (i != e) {
|
||||
cbmap_t::iterator j = i;
|
||||
++j;
|
||||
if (j == e || i->second.second != j->second.second) {
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
i->second.first = j->second.first;
|
||||
cbmap.erase(j);
|
||||
}
|
||||
LOG_FT << "Font map size after compression: " << cbmap.size() << " ranges\n";
|
||||
}
|
||||
subset_id get_id(int ch)
|
||||
{
|
||||
cbmap_t::iterator i = cbmap.upper_bound(ch);
|
||||
// At this point, either ch < i->first or i is past the end.
|
||||
if (i != cbmap.begin()) {
|
||||
--i;
|
||||
if (ch <= i->second.first /* prev.last */)
|
||||
return i->second.second;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
static char_block_map char_blocks;
|
||||
|
||||
//cache sizes of small text
|
||||
typedef std::map<std::string,SDL_Rect> line_size_cache_map;
|
||||
|
||||
//map of styles -> sizes -> cache
|
||||
static std::map<int,std::map<int,line_size_cache_map> > line_size_cache;
|
||||
|
||||
typedef std::map<std::pair<std::string, int>, TTF_Font*> topen_font_cache;
|
||||
topen_font_cache open_fonts;
|
||||
|
||||
static TTF_Font* open_font_impl(const std::string & , int);
|
||||
|
||||
// A wrapper which caches the results of open_font_impl.
|
||||
// Note that clear_fonts() is responsible to clean up all of these font pointers,
|
||||
// so to avoid memory leaks fonts should only be opened from this function.
|
||||
static TTF_Font* open_font(const std::string& fname, int size)
|
||||
{
|
||||
const std::pair<std::string, int> key = std::make_pair(fname, size);
|
||||
const topen_font_cache::iterator it = open_fonts.find(key);
|
||||
if (it != open_fonts.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
TTF_Font* result = open_font_impl(fname, size);
|
||||
open_fonts.insert(std::make_pair(key, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static TTF_Font* open_font_impl(const std::string & fname, int size) {
|
||||
std::string name;
|
||||
if(!game_config::path.empty()) {
|
||||
name = game_config::path + "/fonts/" + fname;
|
||||
if(!filesystem::file_exists(name)) {
|
||||
name = "fonts/" + fname;
|
||||
if(!filesystem::file_exists(name)) {
|
||||
name = fname;
|
||||
if(!filesystem::file_exists(name)) {
|
||||
ERR_FT << "Failed opening font: '" << name << "': No such file or directory" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
name = "fonts/" + fname;
|
||||
if(!filesystem::file_exists(name)) {
|
||||
if(!filesystem::file_exists(fname)) {
|
||||
ERR_FT << "Failed opening font: '" << name << "': No such file or directory" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
name = fname;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RWops *rwops = filesystem::load_RWops(name);
|
||||
TTF_Font* font = TTF_OpenFontRW(rwops, true, size); // SDL takes ownership of rwops
|
||||
if(font == nullptr) {
|
||||
ERR_FT << "Failed opening font: '" << fname << "'\n";
|
||||
ERR_FT << "TTF_OpenFont: " << TTF_GetError() << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DBG_FT << "Opened a font: " << fname << std::endl;
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
// Gets an appropriately configured TTF Font, for this font size and style.
|
||||
// Loads fonts if necessary. For styled fonts, we search for a ``shipped''
|
||||
// version of the font which is prestyled. If this fails we find the closest
|
||||
// thing which we did ship, and store a record of this, which allows to
|
||||
// rapidly correct the remaining styling using SDL_TTF.
|
||||
//
|
||||
// Uses the font table for caching.
|
||||
TTF_Font* sdl_ttf::get_font(font_id id)
|
||||
{
|
||||
const auto it = font_table.find(id);
|
||||
if(it != font_table.end()) {
|
||||
if (it->second.font != nullptr) {
|
||||
// If we found a valid record, use SDL_TTF to add in the difference
|
||||
// between its intrinsic style and the desired style.
|
||||
TTF_SetFontStyle(it->second.font, it->second.style ^ id.style);
|
||||
}
|
||||
return it->second.font;
|
||||
}
|
||||
|
||||
// There's no record, so we need to try to find a solution for this font
|
||||
// and make a record of it. If the indices are out of bounds don't bother though.
|
||||
if(id.subset < 0 || size_t(id.subset) >= font_names.size()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Favor to use the shipped Italic font over bold if both are present and are needed.
|
||||
if ((id.style & TTF_STYLE_ITALIC) && italic_names[id.subset].size()) {
|
||||
if (TTF_Font* font = open_font(italic_names[id.subset], id.size)) {
|
||||
ttf_record rec = {font, TTF_STYLE_ITALIC};
|
||||
font_table.insert(std::make_pair(id, rec));
|
||||
return sdl_ttf::get_font(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Now see if the shipped Bold font is useful and available.
|
||||
if ((id.style & TTF_STYLE_BOLD) && bold_names[id.subset].size()) {
|
||||
if (TTF_Font* font = open_font(bold_names[id.subset], id.size)) {
|
||||
ttf_record rec = {font, TTF_STYLE_BOLD};
|
||||
font_table.insert(std::make_pair(id, rec));
|
||||
return sdl_ttf::get_font(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Try just to use the basic version of the font then.
|
||||
if (font_names[id.subset].size()) {
|
||||
if(TTF_Font* font = open_font(font_names[id.subset], id.size)) {
|
||||
ttf_record rec = {font, TTF_STYLE_NORMAL};
|
||||
font_table.insert(std::make_pair(id, rec));
|
||||
return sdl_ttf::get_font(id);
|
||||
}
|
||||
}
|
||||
|
||||
// Failed to find a font.
|
||||
ttf_record rec = {nullptr, TTF_STYLE_NORMAL};
|
||||
font_table.insert(std::make_pair(id, rec));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* Interface to SDL_TTF
|
||||
*/
|
||||
|
||||
static surface render_text(const std::string& text, int fontsize, const SDL_Color& color, int style, bool use_markup)
|
||||
{
|
||||
// we keep blank lines and spaces (may be wanted for indentation)
|
||||
const std::vector<std::string> lines = utils::split(text, '\n', 0);
|
||||
std::vector<std::vector<surface> > surfaces;
|
||||
surfaces.reserve(lines.size());
|
||||
size_t width = 0, height = 0;
|
||||
|
||||
for(std::vector< std::string >::const_iterator ln = lines.begin(), ln_end = lines.end(); ln != ln_end; ++ln) {
|
||||
|
||||
int sz = fontsize;
|
||||
int text_style = style;
|
||||
|
||||
std::string::const_iterator after_markup = use_markup ?
|
||||
parse_markup(ln->begin(), ln->end(), &sz, nullptr, &text_style) : ln->begin();
|
||||
text_surface txt_surf(sz, color, text_style);
|
||||
|
||||
if (after_markup == ln->end() && (ln+1 != ln_end || lines.begin()+1 == ln_end)) {
|
||||
// we replace empty line by a space (to have a line height)
|
||||
// except for the last line if we have several
|
||||
txt_surf.set_text(" ");
|
||||
} else if (after_markup == ln->begin()) {
|
||||
// simple case, no markup to skip
|
||||
txt_surf.set_text(*ln);
|
||||
} else {
|
||||
const std::string line(after_markup,ln->end());
|
||||
txt_surf.set_text(line);
|
||||
}
|
||||
|
||||
const text_surface& cached_surf = text_cache::find(txt_surf);
|
||||
const std::vector<surface>&res = cached_surf.get_surfaces();
|
||||
|
||||
if (!res.empty()) {
|
||||
surfaces.push_back(res);
|
||||
width = std::max<size_t>(cached_surf.width(), width);
|
||||
height += cached_surf.height();
|
||||
}
|
||||
}
|
||||
|
||||
if (surfaces.empty()) {
|
||||
return surface();
|
||||
} else if (surfaces.size() == 1 && surfaces.front().size() == 1) {
|
||||
surface surf = surfaces.front().front();
|
||||
adjust_surface_alpha(surf, SDL_ALPHA_OPAQUE);
|
||||
return surf;
|
||||
} else {
|
||||
|
||||
surface res(create_compatible_surface(surfaces.front().front(),width,height));
|
||||
if (res.null())
|
||||
return res;
|
||||
|
||||
size_t ypos = 0;
|
||||
for(std::vector< std::vector<surface> >::iterator i = surfaces.begin(),
|
||||
i_end = surfaces.end(); i != i_end; ++i) {
|
||||
size_t xpos = 0;
|
||||
height = 0;
|
||||
|
||||
for(std::vector<surface>::iterator j = i->begin(),
|
||||
j_end = i->end(); j != j_end; ++j) {
|
||||
adjust_surface_alpha(*j, SDL_ALPHA_TRANSPARENT); // direct blit without alpha blending
|
||||
SDL_Rect dstrect = sdl::create_rect(xpos, ypos, 0, 0);
|
||||
sdl_blit(*j, nullptr, res, &dstrect);
|
||||
xpos += (*j)->w;
|
||||
height = std::max<size_t>((*j)->h, height);
|
||||
}
|
||||
ypos += height;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
surface get_rendered_text(const std::string& str, int size, const SDL_Color& color, int style)
|
||||
{
|
||||
// TODO maybe later also to parse markup here, but a lot to check
|
||||
return render_text(str, size, color, style, false);
|
||||
}
|
||||
|
||||
SDL_Rect draw_text_line(surface& gui_surface, const SDL_Rect& area, int size,
|
||||
const SDL_Color& color, const std::string& text,
|
||||
int x, int y, bool use_tooltips, int style)
|
||||
{
|
||||
size = preferences::font_scaled(size);
|
||||
if (gui_surface.null()) {
|
||||
text_surface const &u = text_cache::find(text_surface(text, size, color, style));
|
||||
return sdl::create_rect(0, 0, u.width(), u.height());
|
||||
}
|
||||
|
||||
if(area.w == 0) { // no place to draw
|
||||
return sdl::create_rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
const std::string etext = make_text_ellipsis(text, size, area.w);
|
||||
|
||||
// for the main current use, we already parsed markup
|
||||
surface surface(render_text(etext,size,color,style,false));
|
||||
if(surface == nullptr) {
|
||||
return sdl::create_rect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
SDL_Rect dest;
|
||||
if(x!=-1) {
|
||||
dest.x = x;
|
||||
#ifdef HAVE_FRIBIDI
|
||||
// Oron -- Conditional, until all draw_text_line calls have fixed area parameter
|
||||
if(getenv("NO_RTL") == nullptr) {
|
||||
bool is_rtl = text_cache::find(text_surface(text, size, color, style)).is_rtl();
|
||||
if(is_rtl)
|
||||
dest.x = area.x + area.w - surface->w - (x - area.x);
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
dest.x = (area.w/2)-(surface->w/2);
|
||||
if(y!=-1)
|
||||
dest.y = y;
|
||||
else
|
||||
dest.y = (area.h/2)-(surface->h/2);
|
||||
dest.w = surface->w;
|
||||
dest.h = surface->h;
|
||||
|
||||
if(line_width(text, size) > area.w) {
|
||||
tooltips::add_tooltip(dest,text);
|
||||
}
|
||||
|
||||
if(dest.x + dest.w > area.x + area.w) {
|
||||
dest.w = area.x + area.w - dest.x;
|
||||
}
|
||||
|
||||
if(dest.y + dest.h > area.y + area.h) {
|
||||
dest.h = area.y + area.h - dest.y;
|
||||
}
|
||||
|
||||
if(gui_surface != nullptr) {
|
||||
SDL_Rect src = dest;
|
||||
src.x = 0;
|
||||
src.y = 0;
|
||||
sdl_blit(surface,&src,gui_surface,&dest);
|
||||
}
|
||||
|
||||
if(use_tooltips) {
|
||||
tooltips::add_tooltip(dest,text);
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int get_max_height(int size)
|
||||
{
|
||||
// Only returns the maximal size of the first font
|
||||
TTF_Font* const font = sdl_ttf::get_font(font_id(0, size));
|
||||
if(font == nullptr)
|
||||
return 0;
|
||||
return TTF_FontHeight(font);
|
||||
}
|
||||
|
||||
int line_width(const std::string& line, int font_size, int style)
|
||||
{
|
||||
return line_size(line,font_size,style).w;
|
||||
}
|
||||
|
||||
SDL_Rect line_size(const std::string& line, int font_size, int style)
|
||||
{
|
||||
line_size_cache_map& cache = line_size_cache[style][font_size];
|
||||
|
||||
const line_size_cache_map::const_iterator i = cache.find(line);
|
||||
if(i != cache.end()) {
|
||||
return i->second;
|
||||
}
|
||||
|
||||
SDL_Rect res;
|
||||
|
||||
const SDL_Color col = { 0, 0, 0, 0 };
|
||||
text_surface s(line, font_size, col, style);
|
||||
|
||||
res.w = s.width();
|
||||
res.h = s.height();
|
||||
res.x = res.y = 0;
|
||||
|
||||
cache.insert(std::pair<std::string,SDL_Rect>(line,res));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string make_text_ellipsis(const std::string &text, int font_size,
|
||||
int max_width, int style)
|
||||
{
|
||||
static const std::string ellipsis = "...";
|
||||
|
||||
if (line_width(text, font_size, style) <= max_width)
|
||||
return text;
|
||||
if(line_width(ellipsis, font_size, style) > max_width)
|
||||
return "";
|
||||
|
||||
std::string current_substring;
|
||||
|
||||
utf8::iterator itor(text);
|
||||
|
||||
for(; itor != utf8::iterator::end(text); ++itor) {
|
||||
std::string tmp = current_substring;
|
||||
tmp.append(itor.substr().first, itor.substr().second);
|
||||
|
||||
if (line_width(tmp + ellipsis, font_size, style) > max_width) {
|
||||
return current_substring + ellipsis;
|
||||
}
|
||||
|
||||
current_substring.append(itor.substr().first, itor.substr().second);
|
||||
}
|
||||
|
||||
return text; // Should not happen
|
||||
}
|
||||
|
||||
void cache_mode(CACHE mode)
|
||||
{
|
||||
if(mode == CACHE_LOBBY) {
|
||||
text_cache::resize(1000);
|
||||
} else {
|
||||
text_cache::resize(50);
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* Initialize and destruction
|
||||
*/
|
||||
|
||||
sdl_ttf::sdl_ttf() {
|
||||
const int res = TTF_Init();
|
||||
if(res == -1) {
|
||||
ERR_FT << "Could not initialize SDL_TTF" << std::endl;
|
||||
throw manager::error();
|
||||
} else {
|
||||
LOG_FT << "Initialized true type fonts\n";
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_fonts() {
|
||||
for(const auto & i : open_fonts) {
|
||||
TTF_CloseFont(i.second);
|
||||
}
|
||||
|
||||
open_fonts.clear();
|
||||
|
||||
font_table.clear();
|
||||
|
||||
font_names.clear();
|
||||
bold_names.clear();
|
||||
italic_names.clear();
|
||||
|
||||
char_blocks.cbmap.clear();
|
||||
line_size_cache.clear();
|
||||
}
|
||||
|
||||
sdl_ttf::~sdl_ttf() {
|
||||
clear_fonts();
|
||||
TTF_Quit();
|
||||
}
|
||||
|
||||
//sets the font list to be used.
|
||||
void sdl_ttf::set_font_list(const std::vector<subset_descriptor>& fontlist)
|
||||
{
|
||||
clear_fonts();
|
||||
|
||||
for(const auto & f : fontlist) {
|
||||
if (!check_font_file(f.name)) continue;
|
||||
// Insert fonts only if the font file exists
|
||||
const subset_id subset = font_names.size();
|
||||
font_names.push_back(f.name);
|
||||
|
||||
if (f.bold_name && check_font_file(*f.bold_name)) {
|
||||
bold_names.push_back(*f.bold_name);
|
||||
} else {
|
||||
bold_names.push_back("");
|
||||
}
|
||||
|
||||
if (f.italic_name && check_font_file(*f.italic_name)) {
|
||||
italic_names.push_back(*f.italic_name);
|
||||
} else {
|
||||
italic_names.push_back("");
|
||||
}
|
||||
|
||||
for (const subset_descriptor::range &cp_range : f.present_codepoints) {
|
||||
char_blocks.insert(cp_range.first, cp_range.second, subset);
|
||||
}
|
||||
}
|
||||
char_blocks.compress();
|
||||
|
||||
assert(font_names.size() == bold_names.size());
|
||||
assert(font_names.size() == italic_names.size());
|
||||
|
||||
DBG_FT << "Set the font list. The styled font families are:\n";
|
||||
|
||||
for (size_t i = 0; i < font_names.size(); ++i) {
|
||||
DBG_FT << "[" << i << "]:\t\tbase:\t'" << font_names[i] << "'\tbold:\t'" << bold_names[i] << "'\titalic:\t'" << italic_names[i] << "'\n";
|
||||
}
|
||||
}
|
||||
|
||||
//Splits the UTF-8 text into text_chunks using the same font.
|
||||
std::vector<text_chunk> sdl_ttf::split_text(std::string const & utf8_text) {
|
||||
text_chunk current_chunk(0);
|
||||
std::vector<text_chunk> chunks;
|
||||
|
||||
if (utf8_text.empty())
|
||||
return chunks;
|
||||
|
||||
try {
|
||||
utf8::iterator ch(utf8_text);
|
||||
int sub = char_blocks.get_id(*ch);
|
||||
if (sub >= 0) current_chunk.subset = sub;
|
||||
for(utf8::iterator end = utf8::iterator::end(utf8_text); ch != end; ++ch)
|
||||
{
|
||||
sub = char_blocks.get_id(*ch);
|
||||
if (sub >= 0 && sub != current_chunk.subset) {
|
||||
chunks.push_back(current_chunk);
|
||||
current_chunk.text.clear();
|
||||
current_chunk.subset = sub;
|
||||
}
|
||||
current_chunk.text.append(ch.substr().first, ch.substr().second);
|
||||
}
|
||||
if (!current_chunk.text.empty()) {
|
||||
chunks.push_back(current_chunk);
|
||||
}
|
||||
}
|
||||
catch(utf8::invalid_utf8_exception&) {
|
||||
WRN_FT << "Invalid UTF-8 string: \"" << utf8_text << "\"" << std::endl;
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
|
||||
} // end namespace font
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2003 - 2016 by David White <dave@whitevine.net>
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -11,57 +11,30 @@
|
|||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
#ifndef FONT_HPP_INCLUDED
|
||||
#define FONT_HPP_INCLUDED
|
||||
|
||||
#include "exceptions.hpp"
|
||||
#include "font_options.hpp"
|
||||
#ifndef FONT_SDL_TTF_HPP
|
||||
#define FONT_SDL_TTF_HPP
|
||||
|
||||
#include "sdl/utils.hpp"
|
||||
#include "sdl/image.hpp"
|
||||
#include "font_id.hpp"
|
||||
#include "font_description.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
class t_string;
|
||||
|
||||
/***
|
||||
* Note: This is the SDL_TTF code path. For pango cairo code path, see class ttext.
|
||||
*/
|
||||
class surface;
|
||||
|
||||
namespace font {
|
||||
|
||||
//object which initializes and destroys structures needed for fonts
|
||||
struct manager {
|
||||
manager();
|
||||
~manager();
|
||||
|
||||
/**
|
||||
* Updates the font path, when initialized it sets the fontpath to
|
||||
* game_config::path. When this path is updated, this function should be
|
||||
* called.
|
||||
*/
|
||||
void update_font_path() const;
|
||||
|
||||
struct error : public game::error {
|
||||
error() : game::error("Font initialization failed") {}
|
||||
};
|
||||
private:
|
||||
/** Initializes the font path. */
|
||||
void init() const;
|
||||
|
||||
/** Deinitializes the font path. */
|
||||
void deinit() const;
|
||||
};
|
||||
|
||||
//various standard colors
|
||||
extern const SDL_Color NORMAL_COLOR, GRAY_COLOR, LOBBY_COLOR, GOOD_COLOR, BAD_COLOR,
|
||||
BLACK_COLOR, YELLOW_COLOR, BUTTON_COLOR, BIGMAP_COLOR,
|
||||
PETRIFIED_COLOR, TITLE_COLOR, DISABLED_COLOR, LABEL_COLOR;
|
||||
|
||||
// font sizes, to be made theme parameters
|
||||
const int SIZE_NORMAL = 14;
|
||||
constexpr int SIZE_NORMAL = 14;
|
||||
// automatic computation of other font sizes, to be made a default for theme-provided values
|
||||
const int
|
||||
constexpr int
|
||||
SIZE_TINY = 10 * SIZE_NORMAL / 14,
|
||||
SIZE_SMALL = 12 * SIZE_NORMAL / 14,
|
||||
|
||||
|
@ -107,14 +80,33 @@ std::string make_text_ellipsis(const std::string& text, int font_size, int max_w
|
|||
int style = TTF_STYLE_NORMAL);
|
||||
|
||||
|
||||
bool load_font_config();
|
||||
|
||||
/** Returns the currently defined fonts. */
|
||||
const t_string& get_font_families(family_class fclass = FONT_SANS_SERIF);
|
||||
|
||||
enum CACHE { CACHE_LOBBY, CACHE_GAME };
|
||||
void cache_mode(CACHE mode);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***
|
||||
* RAII object which initializes and destroys SDL_TTF, and manages caches of open fonts
|
||||
*/
|
||||
struct sdl_ttf {
|
||||
sdl_ttf();
|
||||
~sdl_ttf();
|
||||
|
||||
sdl_ttf(const sdl_ttf &) = delete;
|
||||
|
||||
// Load a font
|
||||
static TTF_Font * get_font(font_id);
|
||||
|
||||
// Set the list of fonts
|
||||
static void set_font_list(const std::vector<subset_descriptor>& fontlist);
|
||||
|
||||
// Split a utf8 string into text_chunks
|
||||
static std::vector<text_chunk> split_text(const std::string & utf8_text);
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // end namespace font
|
||||
|
||||
#endif
|
41
src/font/text_cache.cpp
Normal file
41
src/font/text_cache.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
#include "text_cache.hpp"
|
||||
|
||||
namespace font {
|
||||
|
||||
text_cache::text_list text_cache::cache_;
|
||||
|
||||
unsigned int text_cache::max_size_ = 50;
|
||||
|
||||
void text_cache::resize(unsigned int size)
|
||||
{
|
||||
// DBG_FT << "Text cache: resize from: " << max_size_ << " to: "
|
||||
// << size << " items in cache: " << cache_.size() << '\n';
|
||||
|
||||
while(size < cache_.size()) {
|
||||
cache_.pop_back();
|
||||
}
|
||||
max_size_ = size;
|
||||
}
|
||||
|
||||
text_surface &text_cache::find(text_surface const &t)
|
||||
{
|
||||
static size_t lookup_ = 0, hit_ = 0;
|
||||
text_list::iterator it_bgn = cache_.begin(), it_end = cache_.end();
|
||||
text_list::iterator it = std::find(it_bgn, it_end, t);
|
||||
if (it != it_end) {
|
||||
cache_.splice(it_bgn, cache_, it);
|
||||
++hit_;
|
||||
} else {
|
||||
if (cache_.size() >= max_size_)
|
||||
cache_.pop_back();
|
||||
cache_.push_front(t);
|
||||
}
|
||||
if (++lookup_ % 1000 == 0) {
|
||||
// DBG_FT << "Text cache: " << lookup_ << " lookups, " << (hit_ / 10) << "% hits\n";
|
||||
hit_ = 0;
|
||||
}
|
||||
return cache_.front();
|
||||
}
|
||||
|
||||
} // end namespace font
|
41
src/font/text_cache.hpp
Normal file
41
src/font/text_cache.hpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Note: Specific to sdl_ttf
|
||||
*/
|
||||
|
||||
#ifndef FONT_TEXT_CACHE_HPP
|
||||
#define FONT_TEXT_CACHE_HPP
|
||||
|
||||
#include "text_surface.hpp"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace font {
|
||||
|
||||
class text_cache
|
||||
{
|
||||
public:
|
||||
static text_surface &find(text_surface const &t);
|
||||
static void resize(unsigned int size);
|
||||
private:
|
||||
typedef std::list< text_surface > text_list;
|
||||
static text_list cache_;
|
||||
static unsigned int max_size_;
|
||||
};
|
||||
|
||||
} // end namespace font
|
||||
|
||||
#endif
|
188
src/font/text_surface.cpp
Normal file
188
src/font/text_surface.cpp
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include "text_surface.hpp"
|
||||
|
||||
#include "sdl_ttf.hpp"
|
||||
|
||||
#include "sdl/utils.hpp"
|
||||
#include "sdl/image.hpp"
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_FRIBIDI
|
||||
#include <fribidi.h>
|
||||
#endif
|
||||
|
||||
static lg::log_domain log_font("font");
|
||||
#define DBG_FT LOG_STREAM(debug, log_font)
|
||||
#define LOG_FT LOG_STREAM(info, log_font)
|
||||
#define WRN_FT LOG_STREAM(warn, log_font)
|
||||
#define ERR_FT LOG_STREAM(err, log_font)
|
||||
|
||||
namespace font {
|
||||
|
||||
#ifdef HAVE_FRIBIDI
|
||||
void text_surface::bidi_cvt()
|
||||
{
|
||||
char *c_str = const_cast<char *>(str_.c_str()); // fribidi forgot const...
|
||||
FriBidiStrIndex len = str_.length();
|
||||
FriBidiChar *bidi_logical = new FriBidiChar[len + 2];
|
||||
FriBidiChar *bidi_visual = new FriBidiChar[len + 2];
|
||||
char *utf8str = new char[4*len + 1]; //assume worst case here (all 4 Byte characters)
|
||||
FriBidiCharType base_dir = FRIBIDI_TYPE_ON;
|
||||
FriBidiStrIndex n;
|
||||
|
||||
|
||||
n = fribidi_charset_to_unicode(FRIBIDI_CHAR_SET_UTF8, c_str, len, bidi_logical);
|
||||
fribidi_log2vis(bidi_logical, n, &base_dir, bidi_visual, nullptr, nullptr, nullptr);
|
||||
|
||||
fribidi_unicode_to_charset(FRIBIDI_CHAR_SET_UTF8, bidi_visual, n, utf8str);
|
||||
is_rtl_ = base_dir == FRIBIDI_TYPE_RTL;
|
||||
str_ = std::string(utf8str);
|
||||
delete[] bidi_logical;
|
||||
delete[] bidi_visual;
|
||||
delete[] utf8str;
|
||||
}
|
||||
#endif
|
||||
|
||||
text_surface::text_surface(std::string const &str, int size,
|
||||
SDL_Color color, int style) :
|
||||
hash_(0),
|
||||
font_size_(size),
|
||||
color_(color),
|
||||
style_(style),
|
||||
w_(-1),
|
||||
h_(-1),
|
||||
str_(str),
|
||||
initialized_(false),
|
||||
chunks_(),
|
||||
surfs_()
|
||||
#ifdef HAVE_FRIBIDI
|
||||
,is_rtl_(false)
|
||||
#endif
|
||||
{
|
||||
#ifdef HAVE_FRIBIDI
|
||||
bidi_cvt();
|
||||
#endif
|
||||
hash();
|
||||
}
|
||||
|
||||
text_surface::text_surface(int size, SDL_Color color, int style) :
|
||||
hash_(0),
|
||||
font_size_(size),
|
||||
color_(color),
|
||||
style_(style),
|
||||
w_(-1),
|
||||
h_(-1),
|
||||
str_(),
|
||||
initialized_(false),
|
||||
chunks_(),
|
||||
surfs_()
|
||||
#ifdef HAVE_FRIBIDI
|
||||
,is_rtl_(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
void text_surface::set_text(std::string const &str)
|
||||
{
|
||||
initialized_ = false;
|
||||
w_ = -1;
|
||||
h_ = -1;
|
||||
str_ = str;
|
||||
#ifdef HAVE_FRIBIDI
|
||||
bidi_cvt();
|
||||
#endif
|
||||
hash();
|
||||
}
|
||||
|
||||
void text_surface::hash()
|
||||
{
|
||||
int h = 0;
|
||||
for(const char c : str_) {
|
||||
h = ((h << 9) | (h >> (sizeof(int) * 8 - 9))) ^ (c);
|
||||
}
|
||||
hash_ = h;
|
||||
}
|
||||
|
||||
void text_surface::measure() const
|
||||
{
|
||||
w_ = 0;
|
||||
h_ = 0;
|
||||
|
||||
for(text_chunk const &chunk : chunks_)
|
||||
{
|
||||
TTF_Font* ttfont = sdl_ttf::get_font(font_id(chunk.subset, font_size_, style_));
|
||||
if(ttfont == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int w, h;
|
||||
TTF_SizeUTF8(ttfont, chunk.text.c_str(), &w, &h);
|
||||
w_ += w;
|
||||
h_ = std::max<int>(h_, h);
|
||||
}
|
||||
}
|
||||
|
||||
size_t text_surface::width() const
|
||||
{
|
||||
if (w_ == -1) {
|
||||
if(chunks_.empty())
|
||||
chunks_ = sdl_ttf::split_text(str_);
|
||||
measure();
|
||||
}
|
||||
return w_;
|
||||
}
|
||||
|
||||
size_t text_surface::height() const
|
||||
{
|
||||
if (h_ == -1) {
|
||||
if(chunks_.empty())
|
||||
chunks_ = sdl_ttf::split_text(str_);
|
||||
measure();
|
||||
}
|
||||
return h_;
|
||||
}
|
||||
|
||||
std::vector<surface> const &text_surface::get_surfaces() const
|
||||
{
|
||||
if(initialized_)
|
||||
return surfs_;
|
||||
|
||||
initialized_ = true;
|
||||
|
||||
// Impose a maximal number of characters for a text line. Do now draw
|
||||
// any text longer that that, to prevent a SDL buffer overflow
|
||||
if(width() > max_text_line_width)
|
||||
return surfs_;
|
||||
|
||||
for(text_chunk const &chunk : chunks_)
|
||||
{
|
||||
TTF_Font* ttfont = sdl_ttf::get_font(font_id(chunk.subset, font_size_, style_));
|
||||
|
||||
surface s = surface(TTF_RenderUTF8_Blended(ttfont, chunk.text.c_str(), color_));
|
||||
if(!s.null())
|
||||
surfs_.push_back(s);
|
||||
}
|
||||
|
||||
return surfs_;
|
||||
}
|
||||
|
||||
} // end namespace font
|
88
src/font/text_surface.hpp
Normal file
88
src/font/text_surface.hpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright (C) 2016 by Chris Beck<render787@gmail.com>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifndef FONT_TEXT_SURFACE_HPP
|
||||
#define FONT_TEXT_SURFACE_HPP
|
||||
|
||||
#include "font_id.hpp" // for text_chunk
|
||||
#include "sdl/utils.hpp"
|
||||
#include "sdl/image.hpp"
|
||||
|
||||
#include <SDL_ttf.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/***
|
||||
* Note: This is specific to the SDL_TTF codepath.
|
||||
*/
|
||||
|
||||
namespace font {
|
||||
|
||||
const SDL_Color NORMAL_COLOR = {0xDD,0xDD,0xDD,0},
|
||||
GRAY_COLOR = {0x77,0x77,0x77,0},
|
||||
LOBBY_COLOR = {0xBB,0xBB,0xBB,0},
|
||||
GOOD_COLOR = {0x00,0xFF,0x00,0},
|
||||
BAD_COLOR = {0xFF,0x00,0x00,0},
|
||||
BLACK_COLOR = {0x00,0x00,0x00,0},
|
||||
YELLOW_COLOR = {0xFF,0xFF,0x00,0},
|
||||
BUTTON_COLOR = {0xBC,0xB0,0x88,0},
|
||||
PETRIFIED_COLOR = {0xA0,0xA0,0xA0,0},
|
||||
TITLE_COLOR = {0xBC,0xB0,0x88,0},
|
||||
LABEL_COLOR = {0x6B,0x8C,0xFF,0},
|
||||
BIGMAP_COLOR = {0xFF,0xFF,0xFF,0};
|
||||
const SDL_Color DISABLED_COLOR = inverse(PETRIFIED_COLOR);
|
||||
|
||||
static const size_t max_text_line_width = 4096;
|
||||
|
||||
class text_surface
|
||||
{
|
||||
public:
|
||||
text_surface(std::string const &str, int size, SDL_Color color, int style);
|
||||
text_surface(int size, SDL_Color color, int style);
|
||||
void set_text(std::string const &str);
|
||||
|
||||
void measure() const;
|
||||
size_t width() const;
|
||||
size_t height() const;
|
||||
#ifdef HAVE_FRIBIDI
|
||||
bool is_rtl() const { return is_rtl_; } // Right-To-Left alignment
|
||||
#endif
|
||||
std::vector<surface> const & get_surfaces() const;
|
||||
|
||||
bool operator==(text_surface const &t) const {
|
||||
return hash_ == t.hash_ && font_size_ == t.font_size_
|
||||
&& color_ == t.color_ && style_ == t.style_ && str_ == t.str_;
|
||||
}
|
||||
bool operator!=(text_surface const &t) const { return !operator==(t); }
|
||||
private:
|
||||
int hash_;
|
||||
int font_size_;
|
||||
SDL_Color color_;
|
||||
int style_;
|
||||
mutable int w_, h_;
|
||||
std::string str_;
|
||||
mutable bool initialized_;
|
||||
mutable std::vector<text_chunk> chunks_;
|
||||
mutable std::vector<surface> surfs_;
|
||||
#ifdef HAVE_FRIBIDI
|
||||
bool is_rtl_;
|
||||
void bidi_cvt();
|
||||
#endif
|
||||
void hash();
|
||||
};
|
||||
|
||||
} // end namespace font
|
||||
|
||||
#endif
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "editor/editor_main.hpp" // for EXIT_STATUS
|
||||
#include "events.hpp" // for event_context
|
||||
#include "font.hpp" // for manager
|
||||
#include "font/font_config.hpp" // for manager
|
||||
#include "game_preferences.hpp" // for manager
|
||||
#include "hotkey/hotkey_manager.hpp" // for manager
|
||||
#include "image.hpp" // for manager
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
#include "serialization/string_utils.hpp"
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "font.hpp"
|
||||
// #include "font.hpp"
|
||||
#include "preferences.hpp"
|
||||
#include "strftime.hpp"
|
||||
#include "video.hpp"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "control.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
// #include "font.hpp"
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "gui/auxiliary/iterator/walker_widget.hpp"
|
||||
#include "gui/core/log.hpp"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "gui/widgets/text_box.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "gui/core/log.hpp"
|
||||
#include "gui/core/register_widget.hpp"
|
||||
#include "gui/widgets/settings.hpp"
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "events.hpp"
|
||||
#include "floating_label.hpp"
|
||||
#include "formula/callable.hpp"
|
||||
#include "font.hpp"
|
||||
//#include "font.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "log.hpp"
|
||||
#include "gui/auxiliary/formula.hpp"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include "config.hpp" // for config, etc
|
||||
#include "events.hpp" // for raise_draw_event, pump, etc
|
||||
#include "font.hpp" // for relative_size
|
||||
#include "font/sdl_ttf.hpp" // for relative_size
|
||||
#include "game_preferences.hpp"
|
||||
#include "gettext.hpp" // for _
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include <iostream> // for operator<<, basic_ostream, etc
|
||||
#include <SDL_mouse.h> // for SDL_GetMouseState, etc
|
||||
#include "cursor.hpp" // for set, CURSOR_TYPE::HYPERLINK, etc
|
||||
#include "font.hpp" // for relative_size
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "gettext.hpp" // for _
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
#include "help/help_text_area.hpp" // for help_text_area
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#define HELP_IMPL_INCLUDED
|
||||
|
||||
#include "exceptions.hpp" // for error
|
||||
#include "font.hpp" // for line_width, relative_size
|
||||
#include "font/sdl_ttf.hpp" // for line_width, relative_size
|
||||
#include "gettext.hpp"
|
||||
#include <cstring>
|
||||
#include <list> // for list
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <string> // for string
|
||||
#include <utility> // for pair
|
||||
#include <SDL_video.h> // for SDL_Color (ptr only), etc
|
||||
#include "font.hpp" // for NORMAL_COLOR
|
||||
#include "font/sdl_ttf.hpp" // for NORMAL_COLOR
|
||||
#include "sdl/utils.hpp" // for surface
|
||||
#include "widgets/scrollarea.hpp" // for scrollarea
|
||||
class CVideo;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef HELP_TOPIC_GENERATORS_HPP
|
||||
#define HELP_TOPIC_GENERATORS_HPP
|
||||
|
||||
#include "font.hpp" // for line_width
|
||||
#include "font/sdl_ttf.hpp" // for line_width
|
||||
#include "help_impl.hpp"
|
||||
|
||||
#include <string> // for string
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "gettext.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "sdl/rect.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
|
||||
void the_end(CVideo &video, std::string text, unsigned int duration)
|
||||
{
|
||||
|
|
|
@ -15,10 +15,13 @@
|
|||
#ifndef MAP_LABEL_HPP_INCLUDED
|
||||
#define MAP_LABEL_HPP_INCLUDED
|
||||
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "map/location.hpp"
|
||||
#include "font.hpp"
|
||||
#include "tstring.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class config;
|
||||
class display;
|
||||
class display_context;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "global.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "attack_prediction.hpp"
|
||||
//#include "editor/editor_controller.hpp"
|
||||
//#include "editor/palette/terrain_palettes.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "game_preferences.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "language.hpp"
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
class config;
|
||||
class display;
|
||||
class surface;
|
||||
|
||||
#include "cursor.hpp"
|
||||
#include "floating_label.hpp"
|
||||
#include "font.hpp"
|
||||
#include "tooltips.hpp"
|
||||
#include "video.hpp"
|
||||
#include "widgets/menu.hpp"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "config.hpp"
|
||||
#include "config_cache.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/font_config.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "hotkey/hotkey_manager.hpp"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "gui/widgets/helper.hpp"
|
||||
#include "gui/core/log.hpp"
|
||||
#include "gui/core/point.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/font_config.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
#include "serialization/unicode.hpp"
|
||||
#include "preferences.hpp"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "global.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "hotkey/hotkey_command.hpp"
|
||||
#include "hotkey/hotkey_item.hpp"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "tooltips.hpp"
|
||||
|
||||
#include "floating_label.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "game_display.hpp"
|
||||
#include "help/help.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "global.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "floating_label.hpp"
|
||||
#include "image.hpp"
|
||||
#include "log.hpp"
|
||||
|
@ -42,9 +42,6 @@ static lg::log_domain log_display("display");
|
|||
|
||||
CVideo* CVideo::singleton_ = nullptr;
|
||||
|
||||
namespace {
|
||||
}
|
||||
|
||||
static unsigned int get_flags(unsigned int flags)
|
||||
{
|
||||
/* The wanted flags for the render need to be evaluated for SDL2. */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "editor/editor_main.hpp"
|
||||
#include "filesystem.hpp" // for filesystem::file_exists, filesystem::io_exception, etc
|
||||
#include "floating_label.hpp"
|
||||
#include "font.hpp" // for load_font_config, etc
|
||||
#include "font/font_config.hpp" // for load_font_config, etc
|
||||
#include "formula/formula.hpp" // for formula_error
|
||||
#include "game_config.hpp" // for path, debug, debug_lua, etc
|
||||
#include "game_config_manager.hpp" // for game_config_manager, etc
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "global.hpp"
|
||||
|
||||
#include "filesystem.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "game_errors.hpp"
|
||||
#include "image.hpp"
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef LABEL_HPP_INCLUDED
|
||||
#define LABEL_HPP_INCLUDED
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "widget.hpp"
|
||||
#include <string>
|
||||
#include "sdl/image.hpp"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "widgets/menu.hpp"
|
||||
|
||||
#include "game_config.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "language.hpp"
|
||||
#include "image.hpp"
|
||||
#include "marked-up_text.hpp"
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "widgets/menu.hpp"
|
||||
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "image.hpp"
|
||||
#include "video.hpp"
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#include "widgets/slider.hpp"
|
||||
#include "game_config.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
#include "image.hpp"
|
||||
#include "sdl/rect.hpp"
|
||||
#include "sound.hpp"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define TEXTBOX_HPP_INCLUDED
|
||||
|
||||
#include "serialization/unicode.hpp"
|
||||
#include "font.hpp"
|
||||
#include "font/sdl_ttf.hpp"
|
||||
|
||||
#include "scrollarea.hpp"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue