15 #define GETTEXT_DOMAIN "wesnoth-lib"
35 # pragma GCC diagnostic ignored "-Wold-style-cast"
48 :
private boost::noncopyable
52 explicit titor(PangoLayout* layout_) :
53 itor_(pango_layout_get_iter(layout_))
57 ~titor() { pango_layout_iter_free(itor_); }
59 operator PangoLayoutIter*() {
return itor_; }
63 PangoLayoutIter* itor_;
78 for(
const char c : text) {
80 case '&': result +=
"&";
break;
81 case '<': result +=
"<";
break;
82 case '>': result +=
">";
break;
83 case '\'': result +=
"'";
break;
84 case '"': result +=
""";
break;
92 #
if PANGO_VERSION_CHECK(1,22,0)
93 context_(pango_font_map_create_context(pango_cairo_font_map_get_default())),
95 context_(pango_cairo_font_map_create_context((
96 reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))),
98 layout_(pango_layout_new(context_)),
105 markedup_text_(false),
111 foreground_color_(0xFFFFFFFF),
115 ellipse_mode_(PANGO_ELLIPSIZE_END),
116 alignment_(PANGO_ALIGN_LEFT),
118 calculation_dirty_(true),
120 surface_dirty_(true),
121 surface_buffer_(nullptr)
124 pango_cairo_context_set_resolution(
context_, 72.0);
128 pango_layout_set_wrap(
layout_, PANGO_WRAP_WORD_CHAR);
134 pango_layout_set_spacing(
layout_, 2 * PANGO_SCALE);
136 cairo_font_options_t *fo = cairo_font_options_create();
137 cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
138 cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON);
146 cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
148 pango_cairo_context_set_font_options(
context_, fo);
149 cairo_font_options_destroy(fo);
173 sdl::timage ttext::render_as_texture()
const
201 return (pango_layout_is_ellipsized(
layout_) != 0);
236 const unsigned column,
const unsigned line)
const
246 if(pango_layout_get_line_count(
layout_) >= static_cast<int>(line)) {
250 for(
size_t i = 0;
i < line; ++
i) {
251 pango_layout_iter_next_line(itor);
257 if(!pango_layout_iter_next_char(itor)) {
261 if(
i + 1 == column) {
270 const int offset = pango_layout_iter_get_index(itor);
274 pango_layout_get_cursor_pos(
layout_, offset, &rect,
nullptr);
276 return gui2::tpoint(PANGO_PIXELS(rect.x), PANGO_PIXELS(rect.y));
285 if (!pango_layout_xy_to_index(
layout_, position.
x * PANGO_SCALE,
286 position.
y * PANGO_SCALE, &index, &trailing)) {
294 if (index < 0 || (static_cast<size_t>(index) >= txt.size()) || d.find(txt.at(index)) != std::string::npos) {
299 while (l > 0 && (d.find(txt.at(l-1)) == std::string::npos)) {
303 size_t r = index + 1;
304 while (r < txt.size() && (d.find(txt.at(r)) == std::string::npos)) {
308 return txt.substr(l,r-l);
332 pango_layout_xy_to_index(
layout_, position.
x * PANGO_SCALE,
333 position.
y * PANGO_SCALE, &index, &trailing);
337 pango_layout_index_to_line_x(
layout_, index, trailing, &line, &offset);
338 offset = PANGO_PIXELS(offset);
351 for(
size_t i = 0; ; ++
i) {
370 <<
"' contains invalid utf-8, trimmed the invalid parts.\n";
382 pango_layout_set_attributes(
layout_,
nullptr);
383 pango_layout_set_text(
layout_, narrow.c_str(), narrow.size());
467 pango_layout_set_width(
layout_, width == -1
469 : (width + 4) * PANGO_SCALE);
501 pango_layout_set_height(
layout_, !multiline ? -1 : height * PANGO_SCALE);
515 pango_layout_set_ellipsize(
layout_, ellipse_mode);
527 pango_layout_set_alignment(
layout_, alignment);
571 :
private boost::noncopyable
575 font_(pango_font_description_new())
577 pango_font_description_set_family(font_, name.c_str());
578 pango_font_description_set_size(font_, size * PANGO_SCALE);
580 if(style != ttext::STYLE_NORMAL) {
581 if(style & ttext::STYLE_ITALIC) {
582 pango_font_description_set_style(font_, PANGO_STYLE_ITALIC);
584 if(style & ttext::STYLE_BOLD) {
585 pango_font_description_set_weight(font_, PANGO_WEIGHT_BOLD);
587 if(style & ttext::STYLE_UNDERLINE) {
593 ~tfont() { pango_font_description_free(font_); }
595 PangoFontDescription*
get() {
return font_; }
598 PangoFontDescription *font_;
601 std::ostream&
operator<<(std::ostream&
s,
const PangoRectangle &rect)
603 s << rect.x <<
',' << rect.y <<
" x " << rect.width <<
',' << rect.height;
618 pango_layout_set_font_description(
layout_, font.get());
621 PangoAttrList *attribute_list = pango_attr_list_new();
622 pango_attr_list_insert(attribute_list
623 , pango_attr_underline_new(PANGO_UNDERLINE_SINGLE));
625 pango_layout_set_attributes (
layout_, attribute_list);
626 pango_attr_list_unref(attribute_list);
629 int maximum_width = 0;
631 PangoFont*
f = pango_font_map_load_font(
632 pango_cairo_font_map_get_default()
636 PangoFontMetrics*
m = pango_font_get_metrics(f,
nullptr);
638 int w = pango_font_metrics_get_approximate_char_width(m);
641 maximum_width = ceil(pango_units_to_double(w));
660 pango_layout_set_width(
layout_, maximum_width == -1
662 : (maximum_width + hack) * PANGO_SCALE);
663 pango_layout_get_pixel_extents(
layout_,
nullptr, &
rect_);
667 <<
"' maximum_width " << maximum_width
673 }
while(maximum_width != -1
674 && hack >= 0 &&
rect_.x +
rect_.width > maximum_width);
680 <<
" font_style " << std::hex <<
font_style_ << std::dec
681 <<
" maximum_width " << maximum_width
683 <<
" result " <<
rect_
685 if(maximum_width != -1 && rect_.x + rect_.width > maximum_width) {
688 <<
" ' width " << rect_.x + rect_.width
689 <<
" greater as the wanted maximum of " << maximum_width
702 for (
int i = 1;
i < 256; ++
i) values[
i - 1] = (255 * 256) /
i;
717 #if defined(__GNUC__) && defined(__BIG_ENDIAN__)
722 if (alpha == 0)
return;
728 unsigned color = p[i]; \
729 color = color * div / 256; \
730 if (color > 255) color = 255; \
734 #if defined(__GNUC__) && defined(__BIG_ENDIAN__)
757 const unsigned stride = width * 4;
760 cairo_surface_t *cairo_surface =
762 CAIRO_FORMAT_ARGB32, width, height, stride);
763 cairo_t *cr = cairo_create(cairo_surface);
766 cairo_set_source_rgba(cr,
772 pango_cairo_show_layout(cr,
layout_);
789 pango_cairo_show_layout(cr,
layout_);
790 pango_cairo_show_layout(cr,
layout_);
791 pango_cairo_show_layout(cr,
layout_);
795 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000));
800 cairo_surface_destroy(cairo_surface);
824 std::stringstream ss;
828 if (delim.find(text.at(
index)) != std::string::npos) {
830 ss << text.at(
index);
834 if (last_delim < static_cast<int>(text.size()) - 1) {
835 ss <<
handle_token(text.substr(last_delim + 1, text.size() - last_delim - 1));
844 return (str.size() >= 8) && ((str.substr(0,7) ==
"http://") || (str.substr(0,8) ==
"https://"));
850 return "<span underline=\'single\' color=\'" +
link_color_ +
"\'>" + token +
"</span>";
858 if(pango_parse_markup(text.c_str(), text.size()
859 , 0,
nullptr,
nullptr,
nullptr,
nullptr)) {
862 pango_layout_set_markup(
layout_, text.c_str(), text.size());
875 for(
const char c : text) {
877 semi_escaped +=
"&";
888 if(text.size() == semi_escaped.size()
889 || !pango_parse_markup(semi_escaped.c_str(), semi_escaped.size()
890 , 0,
nullptr,
nullptr,
nullptr,
nullptr)) {
895 <<
"' has broken markup, set to normal text.\n";
897 set_text(
_(
"The text contains invalid markup: ") + text,
false);
904 <<
"' has unescaped ampersands '&', escaped them.\n";
906 pango_layout_set_markup(
layout_, semi_escaped.c_str(), semi_escaped.size());
Define the common log macros for the gui toolkit.
Uint32 foreground_color_
The foreground color.
void create_surface_buffer(const size_t size) const
Creates a new buffer.
static bool looks_like_url(const std::string &token)
std::vector< char_t > string
size_t index(const utf8::string &str, const size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
ttext & set_alignment(const PangoAlignment alignment)
tformula< int > maximum_height_
The maximum height for the text.
family_class
Font classes for get_font_families().
ttext & set_link_aware(bool b)
void recalculate(const bool force=false) const
Recalculates the text.
const std::string & text() const
ttext & set_font_style(const unsigned font_style)
ttext & set_maximum_length(const size_t maximum_length)
bool calculation_dirty_
The text has two dirty states:
unsigned insert_text(const unsigned offset, const std::string &text)
Inserts UTF-8 text.
ucs4_convert_impl::enableif< TD, typename TS::value_type >::type unicode_cast(const TS &source)
bool is_truncated() const
Has the text been truncated?
ttext & set_font_size(const unsigned font_size)
gui2::tpoint get_column_line(const gui2::tpoint &position) const
Gets the column of line of the character at the position.
GLint GLint GLint GLint GLint GLint y
bool markedup_text_
Is the text markedup if so the markedup render routines need to be used.
ttext & set_maximum_width(int width)
ttext & set_link_color(const std::string &color)
bool surface_dirty_
The dirty state of the surface.
tformula< t_string > text_
The text to draw.
PangoAlignment alignment_
The alignment of the text.
GLboolean GLenum GLenum GLvoid * values
GLdouble GLdouble GLdouble b
std::string link_color_
The color to render links in.
unsigned characters_per_line_
The number of characters per line.
int get_height() const
Returns the height needed for the text.
const t_string & get_font_families(family_class fclass)
Returns the currently defined fonts.
bool set_markup(const std::string &text)
Sets the markup'ed text.
static UNUSEDNOWARN std::string _(const char *str)
std::ostream & operator<<(std::ostream &s, ai::attack_result const &r)
std::string get_link(const gui2::tpoint &position) const
Checks if position points to a character in a link in the text, returns it if so, empty string otherw...
unsigned font_style_
The style of the text.
ttext & set_maximum_height(int height, bool multiline)
GLubyte GLubyte GLubyte GLubyte w
gui2::tpoint get_size() const
Returns the size needed for the text.
int font_scaled(int size)
font::family_class font_class_
The font family class used.
static const unsigned STYLE_BOLD
Bold text.
gui2::tpoint get_cursor_position(const unsigned column, const unsigned line=0) const
Gets the location for the cursor.
GLclampf GLclampf GLclampf alpha
int maximum_height_
The maximum height of the text.
ttext & set_characters_per_line(const unsigned characters_per_line)
void rerender(const bool force=false) const
Renders the text.
bool link_aware_
Are hyperlinks in the text marked-up, and will get_link return them.
static const unsigned STYLE_ITALIC
Italicized text.
unsigned font_style_
The style of the font, this is an orred mask of the font flags.
utf8::string & truncate(utf8::string &str, const size_t size)
Truncates a UTF-8 string to the specified number of characters.
static const unsigned STYLE_NORMAL
The flags have the same values as the ones in SDL_TTF so it's easy to mix them for now...
GLenum GLenum GLvoid GLvoid * column
size_t size(const utf8::string &str)
Length in characters of a UTF-8 string.
std::string escape_text(const std::string &text)
Escapes the markup characters in a text.
std::string get_token(const gui2::tpoint &position, const char *delimiters=" \n\r\t") const
Gets the largest collection of characters, including the token at position, and not including any cha...
std::map< std::string, tfilter >::iterator itor
static void decode_pixel(unsigned char *p)
Converts from premultiplied alpha to plain alpha.
surface render() const
Returns the rendered text.
std::string handle_token(const std::string &token) const
surface surface_
The surface to render upon used as a cache.
std::string debug_truncate(const std::string &text)
Returns a truncated version of the text.
tformula< bool > link_aware_
The link aware switch of the text.
bool insert_unicode(const unsigned offset, ucs4::char_t unicode)
Inserts a unicode char.
GLint GLint GLint GLint GLint x
GLdouble GLdouble GLdouble r
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
GLuint const GLchar * name
unsigned characters_per_line_
The number of characters per line.
tformula< int > maximum_width_
The maximum width for the text.
unsigned char * surface_buffer_
Buffer to store the image on.
tformula< std::string > link_color_
The link color of the text.
unsigned font_size_
The font size to draw.
ttext & set_family_class(font::family_class fclass)
int get_width() const
Returns the width needed for the text.
int maximum_width_
The maximum width of the text.
void assign(const surface &o)
bool set_text(const std::string &text, const bool markedup)
Sets the text to render.
GLint GLint GLint GLint GLint GLint GLsizei width
utf8::string & insert(utf8::string &str, const size_t pos, const utf8::string &insert)
Insert a UTF-8 string at the specified position.
PangoEllipsizeMode ellipse_mode_
The way too long text is shown depends on this mode.
std::string text_
The text to draw (stored as UTF-8).
bool set_markup_helper(const std::string &text)
size_t maximum_length_
The maximum length of the text.
static const unsigned STYLE_UNDERLINE
Underlined text.
GLsizei const GLcharARB ** string
size_t length_
Length of the text.
ttext & set_ellipse_mode(const PangoEllipsizeMode ellipse_mode)
ttext & set_foreground_color(const Uint32 color)