The Battle for Wesnoth  1.19.9+dev
attributes.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2025 - 2025
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "font/attributes.hpp"
16 #include "font/font_config.hpp"
17 
18 #include "color.hpp"
19 #include "gui/core/log.hpp"
21 #include "tstring.hpp"
22 #include "video.hpp"
23 
24 #include <memory>
25 
26 namespace font
27 {
28 namespace
29 {
30 /**
31  * Private helper class to manage a single PangoAttribute.
32  *
33  * This object owns its attribute until relinquished to an attribute_list
34  * by calling @ref add_to or @ref modify_in.
35  */
36 class attribute
37 {
38 public:
39  attribute(PangoAttribute* attr, unsigned offset_start, unsigned offset_end)
40  : value_(attr, &pango_attribute_destroy)
41  {
42  attr->start_index = offset_start;
43  attr->end_index = offset_end;
44  }
45 
46  void add_to(font::attribute_list& list)
47  {
48  list.insert(value_.release());
49  }
50 
51  void modify_in(font::attribute_list& list)
52  {
53  list.modify(value_.release());
54  }
55 
56 private:
57  std::unique_ptr<PangoAttribute, void(*)(PangoAttribute*)> value_;
58 };
59 
60 /** Pango sometimes handles colors as 16 bit integers. */
61 constexpr std::tuple<uint16_t, uint16_t, uint16_t> color_to_uint16(const color_t& color)
62 {
63  return {
64  color.r / 255.0 * std::numeric_limits<uint16_t>::max(),
65  color.g / 255.0 * std::numeric_limits<uint16_t>::max(),
66  color.b / 255.0 * std::numeric_limits<uint16_t>::max()
67  };
68 }
69 
70 } // anon namespace
71 
72 void add_attribute_size(attribute_list& list, unsigned offset_start, unsigned offset_end, int size)
73 {
74  // TODO: we shouldn't be doing scaling stuff here...
76 
77  attribute attr {
78  pango_attr_size_new_absolute(PANGO_SCALE * size),
79  offset_start, offset_end
80  };
81 
82  DBG_GUI_D << "attribute: size";
83  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
84 
85  attr.add_to(list);
86 }
87 
88 void add_attribute_weight(attribute_list& list, unsigned offset_start, unsigned offset_end, PangoWeight weight)
89 {
90  attribute attr {
91  pango_attr_weight_new(weight),
92  offset_start, offset_end
93  };
94 
95  DBG_GUI_D << "attribute: weight";
96  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
97 
98  attr.add_to(list);
99 }
100 
101 void add_attribute_style(attribute_list& list, unsigned offset_start, unsigned offset_end, PangoStyle style)
102 {
103  attribute attr {
104  pango_attr_style_new(style),
105  offset_start, offset_end
106  };
107 
108  DBG_GUI_D << "attribute: style";
109  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
110 
111  attr.add_to(list);
112 }
113 
114 void add_attribute_underline(attribute_list& list, unsigned offset_start, unsigned offset_end, PangoUnderline underline)
115 {
116  attribute attr {
117  pango_attr_underline_new(underline),
118  offset_start, offset_end
119  };
120 
121  DBG_GUI_D << "attribute: underline";
122  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
123 
124  attr.add_to(list);
125 }
126 
127 void add_attribute_fg_color(attribute_list& list, unsigned offset_start, unsigned offset_end, const color_t& color)
128 {
129  auto [col_r, col_g, col_b] = color_to_uint16(color);
130 
131  attribute attr {
132  pango_attr_foreground_new(col_r, col_g, col_b),
133  offset_start, offset_end
134  };
135 
136  DBG_GUI_D << "attribute: fg color";
137  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
138  DBG_GUI_D << "color: " << col_r << "," << col_g << "," << col_b;
139 
140  attr.add_to(list);
141 }
142 
143 void add_attribute_bg_color(attribute_list& list, unsigned offset_start, unsigned offset_end, const color_t& color)
144 {
145  auto [col_r, col_g, col_b] = color_to_uint16(color);
146 
147  attribute attr {
148  pango_attr_background_new(col_r, col_g, col_b),
149  offset_start, offset_end
150  };
151 
152  DBG_GUI_D << "highlight start: " << offset_start << "end : " << offset_end;
153  DBG_GUI_D << "highlight color: " << col_r << "," << col_g << "," << col_b;
154 
155  attr.modify_in(list);
156 }
157 
158 void add_attribute_font_family(attribute_list& list, unsigned offset_start, unsigned offset_end, font::family_class family)
159 {
160  const t_string& family_name = get_font_families(family);
161 
162  attribute attr {
163  pango_attr_family_new(family_name.c_str()),
164  offset_start, offset_end
165  };
166 
167  DBG_GUI_D << "attribute: font family";
168  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
169  DBG_GUI_D << "font family: " << family;
170 
171  attr.add_to(list);
172 }
173 
174 } // namespace font
std::unique_ptr< PangoAttribute, void(*)(PangoAttribute *)> value_
Definition: attributes.cpp:57
Helper class to encapsulate the management of a PangoAttrList.
Definition: attributes.hpp:27
void modify(PangoAttribute *attr)
Definition: attributes.hpp:47
void insert(PangoAttribute *attr)
Definition: attributes.hpp:42
static prefs & get()
int font_scaled(int size)
const char * c_str() const
Definition: tstring.hpp:201
Define the common log macros for the gui toolkit.
#define DBG_GUI_D
Definition: log.hpp:29
Graphical text output.
family_class
Font classes for get_font_families().
void add_attribute_size(attribute_list &list, unsigned offset_start, unsigned offset_end, int size)
Add Pango font size attribute to a specific portion of text.
Definition: attributes.cpp:72
void add_attribute_bg_color(attribute_list &list, unsigned offset_start, unsigned offset_end, const color_t &color)
Mark a specific portion of text for highlighting.
Definition: attributes.cpp:143
void add_attribute_weight(attribute_list &list, unsigned offset_start, unsigned offset_end, PangoWeight weight)
Add Pango font weight attribute to a specific portion of text.
Definition: attributes.cpp:88
const t_string & get_font_families(family_class fclass)
Returns the currently defined fonts.
void add_attribute_underline(attribute_list &list, unsigned offset_start, unsigned offset_end, PangoUnderline underline)
Add Pango underline attribute to a specific portion of text.
Definition: attributes.cpp:114
void add_attribute_font_family(attribute_list &list, unsigned offset_start, unsigned offset_end, font::family_class family)
Add Pango font family attribute to a specific portion of text.
Definition: attributes.cpp:158
void add_attribute_style(attribute_list &list, unsigned offset_start, unsigned offset_end, PangoStyle style)
Add Pango font style attribute to a specific portion of text, used to set italic/oblique text.
Definition: attributes.cpp:101
void add_attribute_fg_color(attribute_list &list, unsigned offset_start, unsigned offset_end, const color_t &color)
Add Pango fg color attribute to a specific portion of text.
Definition: attributes.cpp:127
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
int get_pixel_scale()
Get the current active pixel scale multiplier.
Definition: video.cpp:480
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59