Replace sdl::intersect_rects with new rect::intersect and rect::clip

rect::intersect returns the constructed intersection, whereas
rect::clip modifies the rectangle.
This commit is contained in:
Tommy 2022-06-29 17:11:14 +12:00
parent d4a152a307
commit 96703ca242
13 changed files with 59 additions and 54 deletions

View File

@ -1933,10 +1933,10 @@ bool display::scroll(int xmove, int ymove, bool force)
//
if(!screen_.update_locked()) {
SDL_Rect dstrect = map_area();
rect dstrect = map_area();
dstrect.x += diff_x;
dstrect.y += diff_y;
dstrect = sdl::intersect_rects(dstrect, map_area());
dstrect.clip(map_area());
SDL_Rect srcrect = dstrect;
srcrect.x -= diff_x;
@ -3000,7 +3000,7 @@ bool display::propagate_invalidation(const std::set<map_location>& locs)
bool display::invalidate_visible_locations_in_rect(const SDL_Rect& rect)
{
return invalidate_locations_in_rect(sdl::intersect_rects(map_area(), rect));
return invalidate_locations_in_rect(map_area().intersect(rect));
}
bool display::invalidate_locations_in_rect(const SDL_Rect& rect)

View File

@ -458,8 +458,7 @@ draw::clip_setter draw::reduce_clip(const SDL_Rect& clip)
if (!draw::clip_enabled()) {
return draw::clip_setter(clip);
}
SDL_Rect c = draw::get_clip();
return draw::clip_setter(sdl::intersect_rects(clip, c));
return draw::clip_setter(draw::get_clip().intersect(clip));
}
void draw::force_clip(const SDL_Rect& clip)
@ -474,7 +473,7 @@ void draw::force_clip(const SDL_Rect& clip)
SDL_RenderSetClipRect(renderer(), &clip);
}
SDL_Rect draw::get_clip()
rect draw::get_clip()
{
// TODO: highdpi - fix whatever reason there is for this guard (CI fail)
if (!renderer()) {
@ -487,7 +486,7 @@ SDL_Rect draw::get_clip()
return CVideo::get_singleton().draw_area();
}
SDL_Rect clip;
::rect clip;
SDL_RenderGetClipRect(renderer(), &clip);
return clip;
}

View File

@ -29,7 +29,8 @@
* resolution when possible, without any extra handling required.
*/
#include <SDL2/SDL_rect.h>
#include "sdl/rect.hpp"
#include <vector>
struct color_t;
@ -329,7 +330,7 @@ void force_clip(const SDL_Rect& clip);
*
* If clipping is disabled, this will return the full drawing area.
*/
SDL_Rect get_clip();
::rect get_clip();
/** Whether clipping is enabled. */
bool clip_enabled();

View File

@ -455,10 +455,10 @@ void text_shape::draw(wfl::map_formula_callable& variables)
const int y = y_(local_variables);
const int w = w_(local_variables);
const int h = h_(local_variables);
SDL_Rect dst_rect{x, y, w, h};
rect dst_rect{x, y, w, h};
// Get the visible portion of text.
SDL_Rect visible = sdl::intersect_rects(draw::get_clip(), dst_rect);
rect visible = dst_rect.intersect(draw::get_clip());
// Get the source region of text for clipping.
rect clip_in = visible;

View File

@ -107,8 +107,9 @@ void terrain_layers::pre_show(window& window)
// Cut and mask the image
// ~CROP and ~BLIT have limitations, we do some math to avoid them
// TODO: ^ eh? what limitations?
SDL_Rect r2 = sdl::intersect_rects(r, {0,0,img_size.x,img_size.y});
if(r2.w > 0 && r2.h > 0) {
rect r2{0, 0, img_size.x, img_size.y};
r2.clip(r);
if(!r2.empty()) {
image_steam
<< "~BLIT(" << name
<< "~CROP("

View File

@ -466,7 +466,7 @@ void scrollbar_container::set_visible_rectangle(const SDL_Rect& rectangle)
container_base::set_visible_rectangle(rectangle);
// Now get the visible part of the content.
content_visible_area_ = sdl::intersect_rects(rectangle, content_->get_rectangle());
content_visible_area_ = content_->get_rectangle().intersect(rectangle);
content_grid_->set_visible_rectangle(content_visible_area_);
}

View File

@ -459,7 +459,7 @@ SDL_Rect widget::get_dirty_rectangle() const
void widget::set_visible_rectangle(const SDL_Rect& rectangle)
{
clipping_rectangle_ = sdl::intersect_rects(rectangle, get_rectangle());
clipping_rectangle_ = get_rectangle().intersect(rectangle);
if(clipping_rectangle_ == get_rectangle()) {
redraw_action_ = redraw_action::full;

View File

@ -20,20 +20,6 @@
#include <iostream>
namespace sdl
{
SDL_Rect intersect_rects(const SDL_Rect& rect1, const SDL_Rect& rect2)
{
SDL_Rect res;
if(!SDL_IntersectRect(&rect1, &rect2, &res)) {
return empty_rect;
}
return res;
}
} // namespace sdl
bool operator==(const SDL_Rect& a, const SDL_Rect& b)
{
return SDL_RectEquals(&a, &b) != SDL_FALSE;
@ -89,6 +75,20 @@ rect rect::minimal_cover(const SDL_Rect& other) const
return result;
}
rect rect::intersect(const SDL_Rect& other) const
{
rect result;
if(!SDL_IntersectRect(this, &other, &result)) {
return rect();
}
return result;
}
void rect::clip(const SDL_Rect& other)
{
*this = this->intersect(other);
}
std::ostream& operator<<(std::ostream& s, const rect& r)
{
s << '[' << r.x << ',' << r.y << '|' << r.w << ',' << r.h << ']';

View File

@ -40,16 +40,6 @@ inline SDL_Rect create_rect(const int x, const int y, const int w, const int h)
return {x, y, w, h};
}
/**
* Calculates the intersection of two rectangles.
*
* @param rect1 One rectangle.
* @param rect2 Another rectangle
* @return The intersection of rect1 and rect2, or
* empty_rect if they don't overlap.
*/
SDL_Rect intersect_rects(const SDL_Rect& rect1, const SDL_Rect& rect2);
} // namespace sdl
bool operator==(const SDL_Rect& a, const SDL_Rect& b);
@ -106,6 +96,19 @@ public:
* this rectangle and the given rectangle.
*/
rect minimal_cover(const SDL_Rect& r) const;
/**
* Calculates the intersection of this rectangle and another;
* that is, the maximal rectangle that is contained by both.
*/
rect intersect(const SDL_Rect& r) const;
/**
* Clip this rectangle by the given rectangle.
*
* This rectangle will be reduced to the intersection of both rectangles.
*/
void clip(const SDL_Rect& r);
};
std::ostream& operator<<(std::ostream&, const rect&);

View File

@ -85,14 +85,14 @@ void surface::free_surface()
surface_restorer::surface_restorer()
: target_(nullptr)
, rect_(sdl::empty_rect)
, rect_()
, surface_()
{
}
surface_restorer::surface_restorer(CVideo* target, const SDL_Rect& rect)
surface_restorer::surface_restorer(CVideo* target, const rect& location)
: target_(target)
, rect_(rect)
, rect_(location)
, surface_()
{
update();
@ -103,18 +103,18 @@ surface_restorer::~surface_restorer()
restore();
}
void surface_restorer::restore(const SDL_Rect& dst) const
void surface_restorer::restore(const rect& dst) const
{
if(!surface_) {
return;
}
SDL_Rect dst2 = sdl::intersect_rects(dst, rect_);
rect dst2 = rect_.intersect(dst);
if(dst2.w == 0 || dst2.h == 0) {
return;
}
SDL_Rect src = dst2;
rect src = dst2;
src.x -= rect_.x;
src.y -= rect_.y;
draw::blit(surface_, dst2, src);

View File

@ -14,6 +14,7 @@
#pragma once
#include "sdl/rect.hpp"
#include "sdl/texture.hpp" // for surface_restorer. Remove that, then remove this
#include "utils/const_clone.hpp"
@ -118,19 +119,19 @@ std::ostream& operator<<(std::ostream& stream, const surface& surf);
struct surface_restorer
{
surface_restorer();
surface_restorer(class CVideo* target, const SDL_Rect& rect);
surface_restorer(class CVideo* target, const rect& location);
~surface_restorer();
void restore() const;
void restore(const SDL_Rect& dst) const;
void restore(const rect& dst) const;
void update();
void cancel();
const SDL_Rect& area() const { return rect_; }
const rect& area() const { return rect_; }
private:
class CVideo* target_;
SDL_Rect rect_;
rect rect_;
texture surface_;
};

View File

@ -472,7 +472,7 @@ SDL_Point CVideo::window_size() const
return window->get_size();
}
SDL_Rect CVideo::draw_area() const
rect CVideo::draw_area() const
{
return {0, 0, logical_size_.x, logical_size_.y};
}
@ -522,7 +522,7 @@ SDL_Texture* CVideo::get_render_target()
SDL_Rect CVideo::clip_to_draw_area(const SDL_Rect* r) const
{
if(r) {
return sdl::intersect_rects(*r, draw_area());
return draw_area().intersect(*r);
} else {
return draw_area();
}
@ -588,9 +588,9 @@ surface CVideo::read_pixels(SDL_Rect* r)
}
// Intersect with the given rect.
SDL_Rect r_clipped = d;
rect r_clipped = d;
if (r) {
r_clipped = sdl::intersect_rects(*r, d);
r_clipped.clip(*r);
if (r_clipped != *r) {
DBG_DP << "modifying pixel read area\n"
<< " from " << *r << "\n"

View File

@ -166,7 +166,7 @@ public:
* Returns the size and location of the current drawing area in pixels.
* This will usually be an SDL_Rect indicating the full drawing surface.
*/
SDL_Rect draw_area() const;
rect draw_area() const;
/**
* Returns the size and location of the window's input area in pixels.