mirror of
https://github.com/wesnoth/wesnoth
synced 2025-04-15 17:54:57 +00:00
Floating Labels: refactored draw impl
No longer relies on surface manipulation.
This commit is contained in:
parent
672ee6feec
commit
a5b154088c
|
@ -60,8 +60,7 @@ floating_label::floating_label(const std::string& text, const surface& surf)
|
|||
, text_(text)
|
||||
, font_size_(SIZE_SMALL)
|
||||
, color_(NORMAL_COLOR)
|
||||
, bgcolor_()
|
||||
, bgalpha_(0)
|
||||
, bgcolor_(0, 0, 0, SDL_ALPHA_TRANSPARENT)
|
||||
, xpos_(0)
|
||||
, ypos_(0)
|
||||
, xmove_(0)
|
||||
|
@ -99,6 +98,17 @@ int floating_label::xpos(std::size_t width) const
|
|||
return xpos;
|
||||
}
|
||||
|
||||
rect floating_label::get_bg_rect(const rect& text_rect) const
|
||||
{
|
||||
const int zf = display::get_singleton()->get_zoom_factor();
|
||||
return {
|
||||
text_rect.x - (border_ * zf),
|
||||
text_rect.y - (border_ * zf),
|
||||
text_rect.w + (border_ * zf * 2),
|
||||
text_rect.h + (border_ * zf * 2)
|
||||
};
|
||||
}
|
||||
|
||||
bool floating_label::create_texture()
|
||||
{
|
||||
if(video::headless()) {
|
||||
|
@ -127,7 +137,8 @@ bool floating_label::create_texture()
|
|||
.set_maximum_width(width_ < 0 ? clip_rect_.w : width_)
|
||||
.set_maximum_height(height_ < 0 ? clip_rect_.h : height_, true)
|
||||
.set_ellipse_mode(PANGO_ELLIPSIZE_END)
|
||||
.set_characters_per_line(0);
|
||||
.set_characters_per_line(0)
|
||||
.set_add_outline(bgcolor_.a == 0);
|
||||
|
||||
// ignore last '\n'
|
||||
if(!text_.empty() && *(text_.rbegin()) == '\n') {
|
||||
|
@ -136,65 +147,19 @@ bool floating_label::create_texture()
|
|||
text.set_text(text_, use_markup_);
|
||||
}
|
||||
|
||||
surface foreground = text.render_surface();
|
||||
|
||||
// Pixel scaling is necessary as we are manipulating the raw surface
|
||||
const int ps = video::get_pixel_scale();
|
||||
// For consistent results we must also enlarge according to zoom
|
||||
const int sf = ps * display::get_singleton()->get_zoom_factor();
|
||||
|
||||
if(foreground == nullptr) {
|
||||
tex_ = text.render_and_get_texture();
|
||||
if(!tex_) {
|
||||
ERR_FT << "could not create floating label's text";
|
||||
return false;
|
||||
}
|
||||
|
||||
// combine foreground text with its background
|
||||
if(bgalpha_ != 0) {
|
||||
// background is a dark tooltip box
|
||||
surface background(foreground->w + border_ * 2 * sf, foreground->h + border_ * 2 * sf);
|
||||
|
||||
if(background == nullptr) {
|
||||
ERR_FT << "could not create tooltip box";
|
||||
tex_ = texture(foreground);
|
||||
return tex_ != nullptr;
|
||||
}
|
||||
|
||||
uint32_t color = SDL_MapRGBA(foreground->format, bgcolor_.r, bgcolor_.g, bgcolor_.b, bgalpha_);
|
||||
sdl::fill_surface_rect(background, nullptr, color);
|
||||
|
||||
SDL_Rect r{border_ * sf, border_ * sf, 0, 0};
|
||||
adjust_surface_alpha(foreground, SDL_ALPHA_OPAQUE);
|
||||
sdl_blit(foreground, nullptr, background, &r);
|
||||
|
||||
tex_ = texture(background);
|
||||
} else {
|
||||
// background is blurred shadow of the text
|
||||
surface background(foreground->w + 4*sf, foreground->h + 4*sf);
|
||||
sdl::fill_surface_rect(background, nullptr, 0);
|
||||
SDL_Rect r{2*sf, 2*sf, 0, 0};
|
||||
sdl_blit(foreground, nullptr, background, &r);
|
||||
background = shadow_image(background, sf);
|
||||
|
||||
if(background == nullptr) {
|
||||
ERR_FT << "could not create floating label's shadow";
|
||||
tex_ = texture(foreground);
|
||||
return tex_ != nullptr;
|
||||
}
|
||||
sdl_blit(foreground, nullptr, background, &r);
|
||||
tex_ = texture(background);
|
||||
}
|
||||
|
||||
// adjust high-dpi text display scale
|
||||
tex_.set_draw_width(tex_.w() / ps);
|
||||
tex_.set_draw_height(tex_.h() / ps);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void floating_label::undraw()
|
||||
{
|
||||
DBG_FT << "undrawing floating label from " << screen_loc_;
|
||||
draw_manager::invalidate_region(screen_loc_);
|
||||
draw_manager::invalidate_region(get_bg_rect(screen_loc_));
|
||||
screen_loc_ = {};
|
||||
}
|
||||
|
||||
|
@ -210,7 +175,7 @@ void floating_label::update(int time)
|
|||
}
|
||||
|
||||
point new_pos = get_pos(time);
|
||||
rect draw_loc = {new_pos.x, new_pos.y, tex_.w(), tex_.h()};
|
||||
rect draw_loc {new_pos.x, new_pos.y, tex_.w(), tex_.h()};
|
||||
|
||||
uint8_t new_alpha = get_alpha(time);
|
||||
|
||||
|
@ -219,11 +184,13 @@ void floating_label::update(int time)
|
|||
return;
|
||||
}
|
||||
|
||||
// Invalidate former draw loc
|
||||
draw_manager::invalidate_region(screen_loc_);
|
||||
draw_manager::invalidate_region(draw_loc);
|
||||
|
||||
DBG_FT << "updating floating label from " << screen_loc_
|
||||
<< " to " << draw_loc;
|
||||
// Invalidate new draw loc in preparation
|
||||
draw_manager::invalidate_region(get_bg_rect(draw_loc));
|
||||
|
||||
DBG_FT << "updating floating label from " << screen_loc_ << " to " << draw_loc;
|
||||
|
||||
screen_loc_ = draw_loc;
|
||||
alpha_ = new_alpha;
|
||||
|
@ -254,6 +221,11 @@ void floating_label::draw()
|
|||
// Clip if appropriate.
|
||||
auto clipper = draw::reduce_clip(clip_rect_);
|
||||
|
||||
// Draw background, if appropriate
|
||||
if(bgcolor_.a != 0) {
|
||||
draw::fill(get_bg_rect(screen_loc_), bgcolor_);
|
||||
}
|
||||
|
||||
// Apply the label texture to the screen.
|
||||
tex_.set_alpha_mod(alpha_);
|
||||
draw::blit(tex_, screen_loc_);
|
||||
|
|
|
@ -60,7 +60,6 @@ public:
|
|||
void set_color(const color_t& color) {color_ = color;}
|
||||
void set_bg_color(const color_t& bg_color) {
|
||||
bgcolor_ = bg_color;
|
||||
bgalpha_ = bg_color.a;
|
||||
}
|
||||
void set_border_size(int border) {border_ = border;}
|
||||
// set width for word wrapping (use -1 to disable it)
|
||||
|
@ -105,6 +104,7 @@ private:
|
|||
int xpos(std::size_t width) const;
|
||||
point get_pos(int time);
|
||||
uint8_t get_alpha(int time);
|
||||
rect get_bg_rect(const rect& text_rect) const;
|
||||
texture tex_;
|
||||
rect screen_loc_;
|
||||
uint8_t alpha_;
|
||||
|
@ -113,7 +113,6 @@ private:
|
|||
std::string text_;
|
||||
int font_size_;
|
||||
color_t color_, bgcolor_;
|
||||
int bgalpha_;
|
||||
double xpos_, ypos_, xmove_, ymove_;
|
||||
int lifetime_;
|
||||
int width_, height_;
|
||||
|
|
Loading…
Reference in New Issue
Block a user