The Battle for Wesnoth  1.19.11+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/cairo.hpp"
17 #include "font/font_config.hpp"
18 
19 #include "color.hpp"
20 #include "gui/core/log.hpp"
21 #include "picture.hpp"
23 #include "sdl/surface.hpp"
24 #include "tstring.hpp"
25 #include "video.hpp"
26 
27 #include <memory>
28 
29 namespace font
30 {
31 namespace
32 {
33 /**
34  * Private helper class to manage a single PangoAttribute.
35  *
36  * This object owns its attribute until relinquished to an attribute_list
37  * by calling @ref add_to or @ref modify_in.
38  */
39 class attribute
40 {
41 public:
42  attribute(PangoAttribute* attr, unsigned offset_start, unsigned offset_end)
43  : value_(attr, &pango_attribute_destroy)
44  {
45  attr->start_index = offset_start;
46  attr->end_index = offset_end;
47  }
48 
49  void add_to(font::attribute_list& list)
50  {
51  list.insert(value_.release());
52  }
53 
54  void modify_in(font::attribute_list& list)
55  {
56  list.modify(value_.release());
57  }
58 
59 private:
60  std::unique_ptr<PangoAttribute, void(*)(PangoAttribute*)> value_;
61 };
62 } // anon namespace
63 
64 void add_attribute_size(attribute_list& list, unsigned offset_start, unsigned offset_end, int size)
65 {
66  // TODO: we shouldn't be doing scaling stuff here...
68 
69  attribute attr {
70  pango_attr_size_new_absolute(PANGO_SCALE * size),
71  offset_start, offset_end
72  };
73 
74  DBG_GUI_D << "attribute: size";
75  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
76 
77  attr.add_to(list);
78 }
79 
80 void add_attribute_weight(attribute_list& list, unsigned offset_start, unsigned offset_end, PangoWeight weight)
81 {
82  attribute attr {
83  pango_attr_weight_new(weight),
84  offset_start, offset_end
85  };
86 
87  DBG_GUI_D << "attribute: weight";
88  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
89 
90  attr.add_to(list);
91 }
92 
93 void add_attribute_style(attribute_list& list, unsigned offset_start, unsigned offset_end, PangoStyle style)
94 {
95  attribute attr {
96  pango_attr_style_new(style),
97  offset_start, offset_end
98  };
99 
100  DBG_GUI_D << "attribute: style";
101  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
102 
103  attr.add_to(list);
104 }
105 
106 void add_attribute_underline(attribute_list& list, unsigned offset_start, unsigned offset_end, PangoUnderline underline)
107 {
108  attribute attr {
109  pango_attr_underline_new(underline),
110  offset_start, offset_end
111  };
112 
113  DBG_GUI_D << "attribute: underline";
114  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
115 
116  attr.add_to(list);
117 }
118 
119 void add_attribute_fg_color(attribute_list& list, unsigned offset_start, unsigned offset_end, const color_t& color)
120 {
121  auto [col_r, col_g, col_b] = color.to_pango_format();
122 
123  attribute attr {
124  pango_attr_foreground_new(col_r, col_g, col_b),
125  offset_start, offset_end
126  };
127 
128  DBG_GUI_D << "attribute: fg color";
129  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
130  DBG_GUI_D << "color: " << col_r << "," << col_g << "," << col_b;
131 
132  attr.add_to(list);
133 }
134 
135 void add_attribute_bg_color(attribute_list& list, unsigned offset_start, unsigned offset_end, const color_t& color)
136 {
137  auto [col_r, col_g, col_b] = color.to_pango_format();
138 
139  attribute attr {
140  pango_attr_background_new(col_r, col_g, col_b),
141  offset_start, offset_end
142  };
143 
144  DBG_GUI_D << "highlight start: " << offset_start << "end : " << offset_end;
145  DBG_GUI_D << "highlight color: " << col_r << "," << col_g << "," << col_b;
146 
147  attr.modify_in(list);
148 }
149 
150 void add_attribute_font_family(attribute_list& list, unsigned offset_start, unsigned offset_end, font::family_class family)
151 {
152  const t_string& family_name = get_font_families(family);
153 
154  attribute attr {
155  pango_attr_family_new(family_name.c_str()),
156  offset_start, offset_end
157  };
158 
159  DBG_GUI_D << "attribute: font family";
160  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
161  DBG_GUI_D << "font family: " << family_name;
162 
163  attr.add_to(list);
164 }
165 
166 void add_attribute_line_height(attribute_list& list, unsigned offset_start, unsigned offset_end, const double factor)
167 {
168  attribute attr {
169  pango_attr_line_height_new(factor),
170  offset_start, offset_end
171  };
172 
173  DBG_GUI_D << "attribute: line height (relative)";
174  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
175  DBG_GUI_D << "factor: " << factor;
176 
177  attr.add_to(list);
178 }
179 
180 void add_attribute_image_shape(attribute_list& list, unsigned offset_start, unsigned offset_end, const std::string& image_path)
181 {
182  surface surf = ::image::get_surface(image_path);
184  auto cairo_surface = cairo::create_surface(
185  reinterpret_cast<uint8_t*>(surf->pixels), point(surf->w, surf->h));
186  PangoRectangle bounds {
187  0,
188  -PANGO_SCALE * surf->h * scale,
189  PANGO_SCALE * surf->w * scale,
190  PANGO_SCALE * surf->h * scale
191  };
192 
193  attribute attr {
194  pango_attr_shape_new_with_data(&bounds, &bounds, cairo_surface.release(), nullptr, nullptr),
195  offset_start, offset_end
196  };
197 
198  DBG_GUI_D << "attribute: shape";
199  DBG_GUI_D << "attribute start: " << offset_start << " end : " << offset_end;
200  DBG_GUI_D << "image path: " << image_path;
201 
202  attr.add_to(list);
203 }
204 
205 } // namespace font
std::unique_ptr< PangoAttribute, void(*)(PangoAttribute *)> value_
Definition: attributes.cpp:60
Helper class to encapsulate the management of a PangoAttrList.
Definition: attributes.hpp:28
void modify(PangoAttribute *attr)
Definition: attributes.hpp:61
void insert(PangoAttribute *attr)
Definition: attributes.hpp:56
static prefs & get()
int font_scaled(int size)
const char * c_str() const
Definition: tstring.hpp:203
Define the common log macros for the gui toolkit.
#define DBG_GUI_D
Definition: log.hpp:29
surface_ptr create_surface(uint8_t *buffer, const point &size)
Definition: cairo.hpp:30
Graphical text output.
void add_attribute_image_shape(attribute_list &list, unsigned offset_start, unsigned offset_end, const std::string &image_path)
Add Pango shape attribute to a specific portion of text.
Definition: attributes.cpp:180
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:64
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:135
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:80
const t_string & get_font_families(family_class fclass)
Returns the currently defined fonts.
Definition: font_config.cpp:93
void add_attribute_line_height(attribute_list &list, unsigned offset_start, unsigned offset_end, const double factor)
Add Pango line height attribute to a specific portion of text.
Definition: attributes.cpp:166
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:106
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:150
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:93
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:119
surface get_surface(const image::locator &i_locator, TYPE type, bool skip_cache)
Returns an image surface suitable for software manipulation.
Definition: picture.cpp:665
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:481
void scale(size_t factor, const uint32_t *src, uint32_t *trg, int srcWidth, int srcHeight, ColorFormat colFmt, const ScalerCfg &cfg=ScalerCfg(), int yFirst=0, int yLast=std::numeric_limits< int >::max())
Definition: xbrz.cpp:1170
surface surf
Image.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:61
constexpr std::tuple< uint16_t, uint16_t, uint16_t > to_pango_format() const
Returns the color as a triplet of 16 bit integers, a format used by Pango.
Definition: color.hpp:211
Holds a 2D point.
Definition: point.hpp:25