Add a new image tiling mode: "tile_highres" for high-DPI tiled images.
The other options "tile" and "tile_center" work in draw space, which is consistent with past behaviour, but doesn't look as nice.
This commit is contained in:
parent
352236a094
commit
ebcae03e48
7 changed files with 56 additions and 5 deletions
|
@ -23,7 +23,7 @@
|
|||
w = "(width)"
|
||||
h = "(height)"
|
||||
name = "dialogs/opaque-background.png"
|
||||
resize_mode = "tile"
|
||||
resize_mode = "tile_highres"
|
||||
[/image]
|
||||
|
||||
{_BACKGROUND_DRAW}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
w = "(width - 4)"
|
||||
h = "(height - 4)"
|
||||
name = "dialogs/{BASE_NAME}-background.png"
|
||||
resize_mode = "tile"
|
||||
resize_mode = "tile_highres"
|
||||
[/image]
|
||||
|
||||
[/draw]
|
||||
|
@ -152,7 +152,7 @@
|
|||
w = "(width)"
|
||||
h = "(height)"
|
||||
name = "dialogs/menu-background.png"
|
||||
resize_mode = "tile"
|
||||
resize_mode = "tile_highres"
|
||||
[/image]
|
||||
|
||||
[rectangle]
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
[/type]
|
||||
[type]
|
||||
name=resize_mode
|
||||
value="scale|scale_sharp|stretch|tile|tile_center"
|
||||
value="scale|scale_sharp|stretch|tile|tile_center|tile_highres"
|
||||
[/type]
|
||||
[type]
|
||||
name=scrollbar_mode
|
||||
|
|
34
src/draw.cpp
34
src/draw.cpp
|
@ -270,11 +270,11 @@ void draw::flipped(const texture& tex, bool flip_h, bool flip_v)
|
|||
}
|
||||
|
||||
|
||||
// TODO: highdpi - maybe expose this mirrored mode to WML somehow
|
||||
void draw::tiled(const texture& tex, const SDL_Rect& dst, bool centered,
|
||||
bool mirrored)
|
||||
{
|
||||
if (!tex) { return; }
|
||||
// TODO: highdpi - should this draw at full res? Or game res? For now it's using game res. To draw in higher res, width and height would have to be specified.
|
||||
|
||||
// Reduce clip to dst.
|
||||
auto clipper = draw::reduce_clip(dst);
|
||||
|
@ -297,6 +297,38 @@ void draw::tiled(const texture& tex, const SDL_Rect& dst, bool centered,
|
|||
}
|
||||
}
|
||||
|
||||
void draw::tiled_highres(const texture& tex, const SDL_Rect& dst,
|
||||
bool centered, bool mirrored)
|
||||
{
|
||||
if (!tex) { return; }
|
||||
|
||||
const int pixel_scale = CVideo::get_singleton().get_pixel_scale();
|
||||
|
||||
// Reduce clip to dst.
|
||||
auto clipper = draw::reduce_clip(dst);
|
||||
|
||||
const auto info = tex.get_info();
|
||||
const float w = float(info.w) / float(pixel_scale);
|
||||
const float h = float(info.h) / float(pixel_scale);
|
||||
const float xoff = centered ? (dst.w - w) / 2 : 0.0f;
|
||||
const float yoff = centered ? (dst.h - h) / 2 : 0.0f;
|
||||
|
||||
// Just blit the image however many times is necessary.
|
||||
bool vf = false;
|
||||
SDL_FRect t{dst.x - xoff, dst.y - yoff, w, h};
|
||||
for (; t.y < dst.y + dst.h; t.y += t.h, vf = !vf) {
|
||||
bool hf = false;
|
||||
for (t.x = dst.x - xoff; t.x < dst.x + dst.w; t.x += t.w, hf = !hf) {
|
||||
if (mirrored) {
|
||||
SDL_RendererFlip flip = get_flip(hf, vf);
|
||||
SDL_RenderCopyExF(renderer(), tex, nullptr, &t, 0.0, nullptr, flip);
|
||||
} else {
|
||||
SDL_RenderCopyF(renderer(), tex, nullptr, &t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***************************/
|
||||
/* RAII state manipulation */
|
||||
|
|
13
src/draw.hpp
13
src/draw.hpp
|
@ -238,6 +238,8 @@ void flipped(const texture& tex, bool flip_h = true, bool flip_v = false);
|
|||
/**
|
||||
* Tile a texture to fill a region.
|
||||
*
|
||||
* This function tiles the texture in draw-space.
|
||||
*
|
||||
* The texture may be aligned either with its center at the center
|
||||
* of the region, or with its top-left corner at the top-left corner
|
||||
* of the region.
|
||||
|
@ -256,6 +258,17 @@ void tiled(const texture& tex,
|
|||
bool mirrored = false
|
||||
);
|
||||
|
||||
/** Tile a texture to fill a region.
|
||||
*
|
||||
* This function tiles the texture in output space. It is otherwise
|
||||
* identical to draw::tiled().
|
||||
*/
|
||||
void tiled_highres(const texture& tex,
|
||||
const SDL_Rect& dst,
|
||||
bool centered = false,
|
||||
bool mirrored = false
|
||||
);
|
||||
|
||||
|
||||
/***************************/
|
||||
/* RAII state manipulation */
|
||||
|
|
|
@ -431,6 +431,9 @@ void image_shape::draw(
|
|||
case (resize_mode::tile_center):
|
||||
draw::tiled(tex, adjusted_draw_loc, true, mirror_(variables));
|
||||
break;
|
||||
case resize_mode::tile_highres:
|
||||
draw::tiled_highres(tex, adjusted_draw_loc, false, mirror_(variables));
|
||||
break;
|
||||
case resize_mode::stretch:
|
||||
// Stretching is identical to scaling in terms of handling.
|
||||
// Is this intended? That's what previous code was doing.
|
||||
|
@ -456,6 +459,8 @@ image_shape::resize_mode image_shape::get_resize_mode(const std::string& resize_
|
|||
return resize_mode::tile;
|
||||
} else if(resize_mode == "tile_center") {
|
||||
return resize_mode::tile_center;
|
||||
} else if(resize_mode == "tile_highres") {
|
||||
return resize_mode::tile_highres;
|
||||
} else if(resize_mode == "stretch") {
|
||||
return resize_mode::stretch;
|
||||
} else if(resize_mode == "scale_sharp") {
|
||||
|
|
|
@ -386,6 +386,7 @@ private:
|
|||
stretch,
|
||||
tile,
|
||||
tile_center,
|
||||
tile_highres,
|
||||
};
|
||||
|
||||
/** Converts a string to a resize mode. */
|
||||
|
|
Loading…
Add table
Reference in a new issue