mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-22 18:55:23 +00:00
GUI2/Canvas: avoid saving config copy
- We now store the attribute list as a class member which is populated in the ctor. - parse_text_as_formula = false will use a custom formula to resolve the value as a string.
This commit is contained in:
parent
9ebb1406d9
commit
b10d6cdf49
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
#include "draw.hpp"
|
#include "draw.hpp"
|
||||||
#include "draw_manager.hpp"
|
#include "draw_manager.hpp"
|
||||||
#include "font/attributes.hpp"
|
|
||||||
#include "font/text.hpp"
|
#include "font/text.hpp"
|
||||||
#include "formatter.hpp"
|
#include "formatter.hpp"
|
||||||
#include "gettext.hpp"
|
#include "gettext.hpp"
|
||||||
@ -394,71 +393,31 @@ image_shape::resize_mode image_shape::get_resize_mode(const std::string& resize_
|
|||||||
|
|
||||||
/***** ***** ***** ***** ***** TEXT ***** ***** ***** ***** *****/
|
/***** ***** ***** ***** ***** TEXT ***** ***** ***** ***** *****/
|
||||||
|
|
||||||
text_shape::text_shape(const config& cfg, wfl::action_function_symbol_table& functions)
|
namespace
|
||||||
: rect_bounded_shape(cfg)
|
|
||||||
, cfg_(cfg)
|
|
||||||
, font_family_(font::str_to_family_class(cfg["font_family"]))
|
|
||||||
, font_size_(cfg["font_size"], font::SIZE_NORMAL)
|
|
||||||
, font_style_(decode_font_style(cfg["font_style"]))
|
|
||||||
, text_alignment_(cfg["text_alignment"])
|
|
||||||
, color_(cfg["color"])
|
|
||||||
, text_(cfg["text"])
|
|
||||||
, text_markup_(cfg["text_markup"], false)
|
|
||||||
, link_aware_(cfg["text_link_aware"], false)
|
|
||||||
, link_color_(cfg["text_link_color"], color_t::from_hex_string("ffff00"))
|
|
||||||
, maximum_width_(cfg["maximum_width"], -1)
|
|
||||||
, characters_per_line_(cfg["text_characters_per_line"].to_unsigned())
|
|
||||||
, maximum_height_(cfg["maximum_height"], -1)
|
|
||||||
, highlight_start_(cfg["highlight_start"])
|
|
||||||
, highlight_end_(cfg["highlight_end"])
|
|
||||||
, highlight_color_(cfg["highlight_color"], color_t::from_hex_string("215380"))
|
|
||||||
, outline_(cfg["outline"], false)
|
|
||||||
, actions_formula_(cfg["actions"], &functions)
|
|
||||||
{
|
{
|
||||||
const std::string& debug = (cfg["debug"]);
|
/** For cases where we want a string wrapped in formula parentheses. */
|
||||||
if(!debug.empty()) {
|
auto maybe_literal(const config::attribute_value& val, bool normal_formula)
|
||||||
DBG_GUI_P << "Text: found debug message '" << debug << "'.";
|
{
|
||||||
}
|
return typed_formula<t_string>{ normal_formula ? val : "('" + val + "')" };
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_shape::draw(wfl::map_formula_callable& variables)
|
/** Populates the attribute list from the given config child range. */
|
||||||
|
auto parse_attributes(const config::const_child_itors& range)
|
||||||
{
|
{
|
||||||
assert(variables.has_key("text"));
|
// TODO: most of the time this will be empty, unless you're using rich_label.
|
||||||
|
// It's a lot of memory allocations to always have a valid object here...
|
||||||
// We first need to determine the size of the text which need the rendered
|
// Do we need store it as an optional?
|
||||||
// text. So resolve and render the text first and then start to resolve
|
|
||||||
// the other formulas.
|
|
||||||
const t_string& text = cfg_["parse_text_as_formula"].to_bool(true) ? text_(variables) : cfg_["text"].t_str();
|
|
||||||
|
|
||||||
if(text.empty()) {
|
|
||||||
DBG_GUI_D << "Text: no text to render, leave.";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
font::attribute_list text_attributes;
|
font::attribute_list text_attributes;
|
||||||
|
|
||||||
//
|
for(const config& attr : range) {
|
||||||
// Highlight
|
const std::string name = attr["name"];
|
||||||
//
|
|
||||||
const int highlight_start = highlight_start_(variables);
|
|
||||||
const int highlight_end = highlight_end_(variables);
|
|
||||||
|
|
||||||
if(highlight_start != highlight_end) {
|
if(name.empty()) {
|
||||||
add_attribute_bg_color(text_attributes, highlight_start, highlight_end, highlight_color_(variables));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attribute subtags
|
|
||||||
//
|
|
||||||
for (const auto& attr : cfg_.child_range("attribute")) {
|
|
||||||
const std::string& name = attr["name"];
|
|
||||||
|
|
||||||
if (name.empty()) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned start = attr["start"].to_int(0);
|
const unsigned start = attr["start"].to_int(0);
|
||||||
const unsigned end = attr["end"].to_int(text.size());
|
const unsigned end = attr["end"].to_int(/* text.size() */); // TODO: do we need to restore this default?
|
||||||
|
|
||||||
if (name == "color" || name == "fgcolor" || name == "foreground") {
|
if (name == "color" || name == "fgcolor" || name == "foreground") {
|
||||||
add_attribute_fg_color(text_attributes, start, end, attr["value"].empty() ? font::NORMAL_COLOR : font::string_to_color(attr["value"]));
|
add_attribute_fg_color(text_attributes, start, end, attr["value"].empty() ? font::NORMAL_COLOR : font::string_to_color(attr["value"]));
|
||||||
@ -485,6 +444,62 @@ void text_shape::draw(wfl::map_formula_callable& variables)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return text_attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anon namespace
|
||||||
|
|
||||||
|
text_shape::text_shape(const config& cfg, wfl::action_function_symbol_table& functions)
|
||||||
|
: rect_bounded_shape(cfg)
|
||||||
|
, font_family_(font::str_to_family_class(cfg["font_family"]))
|
||||||
|
, font_size_(cfg["font_size"], font::SIZE_NORMAL)
|
||||||
|
, font_style_(decode_font_style(cfg["font_style"]))
|
||||||
|
, text_alignment_(cfg["text_alignment"])
|
||||||
|
, color_(cfg["color"])
|
||||||
|
, text_(maybe_literal(cfg["text"], cfg["parse_text_as_formula"].to_bool(true)))
|
||||||
|
, text_markup_(cfg["text_markup"], false)
|
||||||
|
, link_aware_(cfg["text_link_aware"], false)
|
||||||
|
, link_color_(cfg["text_link_color"], color_t::from_hex_string("ffff00"))
|
||||||
|
, maximum_width_(cfg["maximum_width"], -1)
|
||||||
|
, characters_per_line_(cfg["text_characters_per_line"].to_unsigned())
|
||||||
|
, maximum_height_(cfg["maximum_height"], -1)
|
||||||
|
, highlight_start_(cfg["highlight_start"])
|
||||||
|
, highlight_end_(cfg["highlight_end"])
|
||||||
|
, highlight_color_(cfg["highlight_color"], color_t::from_hex_string("215380"))
|
||||||
|
, outline_(cfg["outline"], false)
|
||||||
|
, actions_formula_(cfg["actions"], &functions)
|
||||||
|
, text_attributes_(parse_attributes(cfg.child_range("attribute")))
|
||||||
|
{
|
||||||
|
const std::string& debug = (cfg["debug"]);
|
||||||
|
if(!debug.empty()) {
|
||||||
|
DBG_GUI_P << "Text: found debug message '" << debug << "'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void text_shape::draw(wfl::map_formula_callable& variables)
|
||||||
|
{
|
||||||
|
assert(variables.has_key("text"));
|
||||||
|
|
||||||
|
// We first need to determine the size of the text which need the rendered
|
||||||
|
// text. So resolve and render the text first and then start to resolve
|
||||||
|
// the other formulas.
|
||||||
|
const t_string text = text_(variables);
|
||||||
|
|
||||||
|
if(text.empty()) {
|
||||||
|
DBG_GUI_D << "Text: no text to render, leave.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Highlight
|
||||||
|
//
|
||||||
|
const int highlight_start = highlight_start_(variables);
|
||||||
|
const int highlight_end = highlight_end_(variables);
|
||||||
|
|
||||||
|
if(highlight_start != highlight_end) {
|
||||||
|
add_attribute_bg_color(text_attributes_, highlight_start, highlight_end, highlight_color_(variables));
|
||||||
|
}
|
||||||
|
|
||||||
font::pango_text& text_renderer = font::get_text_renderer();
|
font::pango_text& text_renderer = font::get_text_renderer();
|
||||||
text_renderer.clear_attributes();
|
text_renderer.clear_attributes();
|
||||||
|
|
||||||
@ -507,7 +522,7 @@ void text_shape::draw(wfl::map_formula_callable& variables)
|
|||||||
.set_add_outline(outline_(variables));
|
.set_add_outline(outline_(variables));
|
||||||
|
|
||||||
// Do this last so it can merge with attributes from markup
|
// Do this last so it can merge with attributes from markup
|
||||||
text_renderer.apply_attributes(text_attributes);
|
text_renderer.apply_attributes(text_attributes_);
|
||||||
|
|
||||||
wfl::map_formula_callable local_variables(variables);
|
wfl::map_formula_callable local_variables(variables);
|
||||||
const auto [tw, th] = text_renderer.get_size();
|
const auto [tw, th] = text_renderer.get_size();
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#include "gui/core/canvas.hpp"
|
#include "gui/core/canvas.hpp"
|
||||||
#include "gui/auxiliary/typed_formula.hpp"
|
#include "gui/auxiliary/typed_formula.hpp"
|
||||||
|
|
||||||
|
#include "font/attributes.hpp"
|
||||||
|
|
||||||
namespace gui2
|
namespace gui2
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -246,9 +248,6 @@ public:
|
|||||||
void draw(wfl::map_formula_callable& variables) override;
|
void draw(wfl::map_formula_callable& variables) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** the source config */
|
|
||||||
config cfg_;
|
|
||||||
|
|
||||||
/** The text font family. */
|
/** The text font family. */
|
||||||
font::family_class font_family_;
|
font::family_class font_family_;
|
||||||
|
|
||||||
@ -299,6 +298,9 @@ private:
|
|||||||
|
|
||||||
/** Any extra WFL actions to execute. */
|
/** Any extra WFL actions to execute. */
|
||||||
wfl::formula actions_formula_;
|
wfl::formula actions_formula_;
|
||||||
|
|
||||||
|
/** Any custom Pango text attributes. */
|
||||||
|
font::attribute_list text_attributes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user