From 52d67accb47bef8022f60da5efe2c673ee55cbb5 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 30 Jul 2013 20:31:10 -0700 Subject: [PATCH] Fix some issues with resampling drawings The X scale/offset was being used for both X and Y coordinates. Only non-negative integers were supported. xy-VSFilter and libass both now support non-integer coordinates, and negative coordinates have of course always been valid. Resampled coordinates are now rounded to eighth-pixels rather than whole pixels. --- aegisub/src/resolution_resampler.cpp | 14 +++++++++----- aegisub/src/utils.cpp | 8 ++++++++ aegisub/src/utils.h | 2 ++ aegisub/src/vector2d.cpp | 9 ++------- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/aegisub/src/resolution_resampler.cpp b/aegisub/src/resolution_resampler.cpp index a3509dee4..d63956ade 100644 --- a/aegisub/src/resolution_resampler.cpp +++ b/aegisub/src/resolution_resampler.cpp @@ -21,9 +21,11 @@ #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" +#include "utils.h" #include #include +#include #include #include @@ -44,14 +46,16 @@ namespace { final.reserve(drawing.size()); for (auto const& cur : agi::Split(drawing, ' ')) { - if (std::all_of(begin(cur), end(cur), isdigit)) { - int val = boost::lexical_cast(agi::str(cur)); + double val; + if (agi::util::try_parse(agi::str(cur), &val)) { if (is_x) - val = (int)((val + shift_x) * scale_x + .5); + val = (val + shift_x) * scale_x; else - val = (int)((val + shift_y) * scale_y + .5); - final += std::to_string(val); + val = (val + shift_y) * scale_y; + val = int(val * 8 + .5) / 8.0; // round to eighth-pixels + final += float_to_string(val); final += ' '; + is_x = !is_x; } else if (cur.size() == 1) { char c = tolower(cur[0]); diff --git a/aegisub/src/utils.cpp b/aegisub/src/utils.cpp index 482e00e96..70c9ea19f 100644 --- a/aegisub/src/utils.cpp +++ b/aegisub/src/utils.cpp @@ -86,6 +86,14 @@ wxString PrettySize(int bytes) { return wxString::Format(fmt, size) + " " + suffix[i]; } +std::string float_to_string(double val) { + std::string s = str(boost::format("%.3f") % val); + size_t pos = s.find_last_not_of("0"); + if (pos != s.find(".")) ++pos; + s.erase(begin(s) + pos, end(s)); + return s; +} + void StatusTimeout(wxString const& msg, int ms) { wxGetApp().frame->StatusTimeout(msg, ms); } diff --git a/aegisub/src/utils.h b/aegisub/src/utils.h index 5586ef41c..404949e03 100644 --- a/aegisub/src/utils.h +++ b/aegisub/src/utils.h @@ -52,6 +52,8 @@ class wxWindow; wxString PrettySize(int bytes); +std::string float_to_string(double val); + void StatusTimeout(wxString const& msg, int ms = 10000); /// @brief Get the smallest power of two that is greater or equal to x diff --git a/aegisub/src/vector2d.cpp b/aegisub/src/vector2d.cpp index ab6d492a9..842087e62 100644 --- a/aegisub/src/vector2d.cpp +++ b/aegisub/src/vector2d.cpp @@ -23,6 +23,8 @@ #include "vector2d.h" +#include "utils.h" + #include #include @@ -86,13 +88,6 @@ std::string Vector2D::DStr(char sep) const { return str(boost::format("%d%c%d") % (int)x % sep % (int)y); } -static std::string float_to_string(float val) { - std::string s = str(boost::format("%.3f") % val); - size_t pos = s.find_last_not_of("0"); - if (pos != s.find(".")) ++pos; - return s.substr(0, pos); -} - std::string Vector2D::Str(char sep) const { return float_to_string(x) + sep + float_to_string(y); }