From 3835f9580bab320d4d575855e67a3d9f2542bec2 Mon Sep 17 00:00:00 2001 From: Tommy Date: Sat, 16 Jul 2022 22:05:58 +1200 Subject: [PATCH] Fix some poor indentation, and tidy some TODOs --- src/floating_label.cpp | 154 ++++++++++++++-------------- src/font/sdl_ttf_compat.cpp | 1 - src/gui/core/canvas.cpp | 4 +- src/halo.cpp | 197 ++++++++++++++++++------------------ 4 files changed, 177 insertions(+), 179 deletions(-) diff --git a/src/floating_label.cpp b/src/floating_label.cpp index 1df206b2ffa..07693349ae8 100644 --- a/src/floating_label.cpp +++ b/src/floating_label.cpp @@ -102,84 +102,86 @@ bool floating_label::create_texture() return false; } - // TODO: highdpi - this really does not need the extra indent - if(tex_ == nullptr) { - DBG_FT << "creating floating label texture"; - font::pango_text& text = font::get_text_renderer(); - - text.set_link_aware(false) - .set_family_class(font::FONT_SANS_SERIF) - .set_font_size(font_size_) - .set_font_style(font::pango_text::STYLE_NORMAL) - .set_alignment(PANGO_ALIGN_LEFT) - .set_foreground_color(color_) - .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); - - // ignore last '\n' - if(!text_.empty() && *(text_.rbegin()) == '\n') { - text.set_text(std::string(text_.begin(), text_.end() - 1), use_markup_); - } else { - 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 = CVideo::get_singleton().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) { - // TODO: draw_manager - find what triggers this and fix it - //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); + if(tex_ != nullptr) { + // Already have a texture + return true; } - return tex_ != nullptr; + DBG_FT << "creating floating label texture"; + font::pango_text& text = font::get_text_renderer(); + + text.set_link_aware(false) + .set_family_class(font::FONT_SANS_SERIF) + .set_font_size(font_size_) + .set_font_style(font::pango_text::STYLE_NORMAL) + .set_alignment(PANGO_ALIGN_LEFT) + .set_foreground_color(color_) + .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); + + // ignore last '\n' + if(!text_.empty() && *(text_.rbegin()) == '\n') { + text.set_text(std::string(text_.begin(), text_.end() - 1), use_markup_); + } else { + 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 = CVideo::get_singleton().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) { + // TODO: draw_manager - find what triggers this and fix it + //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() diff --git a/src/font/sdl_ttf_compat.cpp b/src/font/sdl_ttf_compat.cpp index 1cf2fcd521c..d2189ebb32c 100644 --- a/src/font/sdl_ttf_compat.cpp +++ b/src/font/sdl_ttf_compat.cpp @@ -139,7 +139,6 @@ std::string pango_word_wrap(const std::string& unwrapped_text, int font_size, in return res; } -// TODO: highdpi - cache results, especially size checks SDL_Rect pango_draw_text(CVideo* video, const SDL_Rect& area, int size, const color_t& color, const std::string& text, int x, int y, bool use_tooltips, pango_text::FONT_STYLE style) { auto& ptext = private_renderer(); diff --git a/src/gui/core/canvas.cpp b/src/gui/core/canvas.cpp index 94cb643e4d0..7310581c729 100644 --- a/src/gui/core/canvas.cpp +++ b/src/gui/core/canvas.cpp @@ -500,7 +500,7 @@ void canvas::draw() return; } - // TODO: highdpi - it is assumed this will never move after blit + // Note: this doesn't update if whatever is underneath changes. if(blur_depth_ && !blur_texture_) { // Cache a blurred image of whatever is underneath. SDL_Rect rect = draw::get_viewport(); @@ -510,7 +510,7 @@ void canvas::draw() } // Draw blurred background. - // TODO: highdpi - this should be able to be removed at some point with shaders + // TODO: hwaccel - this should be able to be removed at some point with shaders if(blur_depth_ && blur_texture_) { draw::blit(blur_texture_); } diff --git a/src/halo.cpp b/src/halo.cpp index 49d7b7a07d4..7b9a4d0a366 100644 --- a/src/halo.cpp +++ b/src/halo.cpp @@ -39,117 +39,114 @@ static lg::log_domain log_halo("halo"); namespace halo { -// TODO: draw_manager - GH#1350 - halo issues on edge of screen - maybe fixed // TODO: draw_manager - GH#1354 - halo_mod doesn't mod halos - maybe not hard // TODO: draw_manager - GH#1960 - halos inherit alpha from unit - maybe not hard -// TODO: draw_manager - GH#2458 - artifacts when zooming (probably fixed) // TODO: draw_manager - GH#6738 - (1) done already (2) halos off screen maybe done -// TODO: draw_manager - fucking indent, what the shit class halo_impl { -class effect -{ -public: - effect( - int xpos, int ypos, - const animated::anim_description& img, - const map_location& loc, ORIENTATION, bool infinite - ); + class effect + { + public: + effect( + int xpos, int ypos, + const animated::anim_description& img, + const map_location& loc, ORIENTATION, bool infinite + ); - void set_location(int x, int y); - rect get_draw_location(); + void set_location(int x, int y); + rect get_draw_location(); - /** Whether the halo is currently visible */ - bool visible(); + /** Whether the halo is currently visible */ + bool visible(); + + void queue_undraw(); + void queue_redraw(); + void update(); + bool render(); + + bool expired() const { return !images_.cycles() && images_.animation_finished(); } + bool need_update() const { return images_.need_update(); } + bool does_change() const { return !images_.does_not_change(); } + bool on_location(const std::set& locations) const; + bool location_not_known() const; + + private: + + const image::locator& current_image() const { return images_.get_current_frame(); } + + animated images_; + + ORIENTATION orientation_; + + // The mid-point of the halo in pixels relative to the absolute top-left of the map, in screen coordinates. + // Yes it's just as ridiculous as it sounds... + // TODO: make this something sane. Like a floating-point map location. + point abs_mid_ = {0, 0}; + + // The current halo image frame + texture tex_ = {}; + // The current location where the halo will be drawn on the screen + rect screen_loc_ = {}; + // The last drawn location + rect last_draw_loc_ = {}; + // The display zoom level, cached so we can compensate when it changes. + double cached_zoom_ = 1.0; + + // The map location the halo is attached to, if any + map_location map_loc_ = {-1, -1}; + + display* disp = nullptr; + }; + + std::map haloes; + int halo_id; + + /** + * Upon unrendering, an invalidation list is send. All haloes in that area and + * the other invalidated haloes are stored in this set. Then there'll be + * tested which haloes overlap and they're also stored in this set. + */ + std::set invalidated_haloes; + + /** + * Upon deleting, a halo isn't deleted but added to this set, upon unrendering + * the image is unrendered and deleted. + */ + std::set deleted_haloes; + + /** + * Haloes that have an animation or expiration time need to be checked every + * frame and are stored in this set. + */ + std::set changing_haloes; + + public: + /** + * impl's of exposed functions + */ + + explicit halo_impl() : + haloes(), + halo_id(1), + invalidated_haloes(), + deleted_haloes(), + changing_haloes() + {} + + + int add(int x, int y, const std::string& image, const map_location& loc, + ORIENTATION orientation=NORMAL, bool infinite=true); + + /** Set the position of an existing haloing effect, according to its handle. */ + void set_location(int handle, int x, int y); + + /** Remove the halo with the given handle. */ + void remove(int handle); - void queue_undraw(); - void queue_redraw(); void update(); - bool render(); - - bool expired() const { return !images_.cycles() && images_.animation_finished(); } - bool need_update() const { return images_.need_update(); } - bool does_change() const { return !images_.does_not_change(); } - bool on_location(const std::set& locations) const; - bool location_not_known() const; - -private: - - const image::locator& current_image() const { return images_.get_current_frame(); } - - animated images_; - - ORIENTATION orientation_; - - // The mid-point of the halo in pixels relative to the absolute top-left of the map, in screen coordinates. - // Yes it's just as ridiculous as it sounds... - // TODO: make this something sane. Like a floating-point map location. - point abs_mid_ = {0, 0}; - - // The current halo image frame - texture tex_ = {}; - // The current location where the halo will be drawn on the screen - rect screen_loc_ = {}; - // The last drawn location - rect last_draw_loc_ = {}; - // The display zoom level, cached so we can compensate when it changes. - double cached_zoom_ = 1.0; - - // The map location the halo is attached to, if any - map_location map_loc_ = {-1, -1}; - - display* disp = nullptr; -}; - -std::map haloes; -int halo_id; - -/** - * Upon unrendering, an invalidation list is send. All haloes in that area and - * the other invalidated haloes are stored in this set. Then there'll be - * tested which haloes overlap and they're also stored in this set. - */ -std::set invalidated_haloes; - -/** - * Upon deleting, a halo isn't deleted but added to this set, upon unrendering - * the image is unrendered and deleted. - */ -std::set deleted_haloes; - -/** - * Haloes that have an animation or expiration time need to be checked every - * frame and are stored in this set. - */ -std::set changing_haloes; - -public: -/** - * impl's of exposed functions - */ - -explicit halo_impl() : - haloes(), - halo_id(1), - invalidated_haloes(), - deleted_haloes(), - changing_haloes() -{} - - -int add(int x, int y, const std::string& image, const map_location& loc, - ORIENTATION orientation=NORMAL, bool infinite=true); - -/** Set the position of an existing haloing effect, according to its handle. */ -void set_location(int handle, int x, int y); - -/** Remove the halo with the given handle. */ -void remove(int handle); - -void update(); -void render(); + void render(); }; //end halo_impl