diff --git a/changelog b/changelog index e19c50783501..1d620709572e 100644 --- a/changelog +++ b/changelog @@ -9,6 +9,7 @@ Version 1.13.4+dev: * Add highlight=yes|no to [scroll_to], [scroll_to_unit], [message] Defaults to no in the first two cases, yes in the third If yes, the target hex is outlined. + * New ~SCALE_INTO(w,h) IPF which preserves aspect ratio, using NN. * Lua API: * wesnoth.match_unit can now take a location (rather than a unit) as the optional third parameter. This will cause the filter to consider diff --git a/src/image_modifications.cpp b/src/image_modifications.cpp index dcee46edd877..e480f6adcf2a 100644 --- a/src/image_modifications.cpp +++ b/src/image_modifications.cpp @@ -426,6 +426,41 @@ int scale_sharp_modification::get_h() const return h_; } +surface scale_into_modification::operator()(const surface& src) const +{ + const int old_w = src->w; + const int old_h = src->h; + long double w = w_; + long double h = h_; + + if(w <= 0) { + if(w < 0) { + ERR_DP << "width of SCALE_INTO is negative - resetting to original width" << std::endl; + } + w = old_w; + } + if(h <= 0) { + if(h < 0) { + ERR_DP << "height of SCALE_INTO is negative - resetting to original height" << std::endl; + } + h = old_h; + } + + long double ratio = std::min(w / old_w, h / old_h); + + return scale_surface_sharp(src, old_w * ratio, old_h * ratio); +} + +int scale_into_modification::get_w() const +{ + return w_; +} + +int scale_into_modification::get_h() const +{ + return h_; +} + surface xbrz_modification::operator()(const surface& src) const { if (z_ == 1) { @@ -1080,6 +1115,27 @@ REGISTER_MOD_PARSER(SCALE_SHARP, args) return new scale_sharp_modification(w, h); } +REGISTER_MOD_PARSER(SCALE_INTO, args) +{ + std::vector const& scale_params = utils::split(args, ',', utils::STRIP_SPACES); + const size_t s = scale_params.size(); + + if(s == 0 || (s == 1 && scale_params[0].empty())) { + ERR_DP << "no arguments passed to the ~SCALE_INTO() function" << std::endl; + return NULL; + } + + int w = 0, h = 0; + + w = lexical_cast_default(scale_params[0]); + + if(s > 1) { + h = lexical_cast_default(scale_params[1]); + } + + return new scale_into_modification(w, h); +} + // xBRZ REGISTER_MOD_PARSER(XBRZ, args) diff --git a/src/image_modifications.hpp b/src/image_modifications.hpp index 45aa184525e8..713825723967 100644 --- a/src/image_modifications.hpp +++ b/src/image_modifications.hpp @@ -401,6 +401,24 @@ class scale_sharp_modification : public modification int w_, h_; }; +/** + * Scale into (SCALE_INTO) modification. (Uses nearest neighbor.) + * Preserves aspect ratio. + */ +class scale_into_modification : public modification +{ +public: + scale_into_modification(int width, int height) + : w_(width), h_(height) + {} + virtual surface operator()(const surface& src) const; + int get_w() const; + int get_h() const; + +private: + int w_, h_; +}; + /** * xBRZ scale (xBRZ) modification