From d81e2f45ac65cdeae8c67f258b878f603c10ce2f Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 20 Sep 2013 07:43:33 -0700 Subject: [PATCH] Add an option to ignore whitespace for the character counter --- aegisub/src/libresrc/default_config.json | 3 ++ aegisub/src/libresrc/osx/default_config.json | 3 ++ aegisub/src/preferences.cpp | 40 ++++++++++---------- aegisub/src/subs_edit_box.cpp | 3 +- aegisub/src/utils.cpp | 23 +++++++++-- aegisub/src/utils.h | 2 +- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/aegisub/src/libresrc/default_config.json b/aegisub/src/libresrc/default_config.json index 0058a4d9f..2fbd8df57 100644 --- a/aegisub/src/libresrc/default_config.json +++ b/aegisub/src/libresrc/default_config.json @@ -350,6 +350,9 @@ }, "Subtitle" : { + "Character Counter" : { + "Ignore Whitespace" : false + }, "Character Limit" : 40, "Default Resolution" : { "Auto" : true, diff --git a/aegisub/src/libresrc/osx/default_config.json b/aegisub/src/libresrc/osx/default_config.json index 11097fc18..ad2dc1032 100644 --- a/aegisub/src/libresrc/osx/default_config.json +++ b/aegisub/src/libresrc/osx/default_config.json @@ -350,6 +350,9 @@ }, "Subtitle" : { + "Character Counter" : { + "Ignore Whitespace" : false + }, "Character Limit" : 40, "Default Resolution" : { "Auto" : true, diff --git a/aegisub/src/preferences.cpp b/aegisub/src/preferences.cpp index d20a76c79..bd8368bbd 100644 --- a/aegisub/src/preferences.cpp +++ b/aegisub/src/preferences.cpp @@ -18,24 +18,6 @@ #include "config.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - #include "preferences.h" #include "audio_renderer_waveform.h" @@ -61,6 +43,23 @@ #include #endif +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #define CLASS_PAGE(name) \ class name: public OptionPage { \ public: \ @@ -192,7 +191,10 @@ Interface::Interface(wxTreebook *book, Preferences *parent): OptionPage(book, pa OptionAdd(edit_box, _("Enable syntax highlighting"), "Subtitle/Highlight/Syntax"); OptionBrowse(edit_box, _("Dictionaries path"), "Path/Dictionary"); OptionFont(edit_box, "Subtitle/Edit Box/"); - OptionAdd(edit_box, _("Maximum characters per line"), "Subtitle/Character Limit", 0, 1000); + + wxFlexGridSizer *character_count = PageSizer(_("Character Counter")); + OptionAdd(character_count, _("Maximum characters per line"), "Subtitle/Character Limit", 0, 1000); + OptionAdd(character_count, _("Ignore whitespace"), "Subtitle/Character Counter/Ignore Whitespace"); wxFlexGridSizer *grid = PageSizer(_("Grid")); OptionAdd(grid, _("Focus grid on click"), "Subtitle/Grid/Focus Allow"); diff --git a/aegisub/src/subs_edit_box.cpp b/aegisub/src/subs_edit_box.cpp index c38b6519a..bc13dd2f2 100644 --- a/aegisub/src/subs_edit_box.cpp +++ b/aegisub/src/subs_edit_box.cpp @@ -577,8 +577,9 @@ void SubsEditBox::CallCommand(const char *cmd_name) { } void SubsEditBox::UpdateCharacterCount(std::string const& text) { + auto ignore_whitespace = OPT_GET("Subtitle/Character Counter/Ignore Whitespace")->GetBool(); agi::dispatch::Background().Async([=]{ - size_t length = MaxLineLength(text); + size_t length = MaxLineLength(text, ignore_whitespace); agi::dispatch::Main().Async([=]{ char_count->SetValue(wxString::Format("%lu", (unsigned long)length)); size_t limit = (size_t)OPT_GET("Subtitle/Character Limit")->GetInt(); diff --git a/aegisub/src/utils.cpp b/aegisub/src/utils.cpp index 90e4a312d..228345927 100644 --- a/aegisub/src/utils.cpp +++ b/aegisub/src/utils.cpp @@ -54,6 +54,8 @@ #include #include #include +#include +#include #include #include @@ -222,7 +224,7 @@ void CleanCache(agi::fs::path const& directory, std::string const& file_type, ui }); } -size_t MaxLineLength(std::string const& text) { +size_t MaxLineLength(std::string const& text, bool ignore_whitespace) { auto tokens = agi::ass::TokenizeDialogueBody(text); agi::ass::MarkDrawings(text, tokens); @@ -231,8 +233,10 @@ size_t MaxLineLength(std::string const& text) { size_t current_line_length = 0; for (auto token : tokens) { if (token.type == agi::ass::DialogueTokenType::LINE_BREAK) { - if (text[pos + 1] == 'h') - current_line_length += 1; + if (text[pos + 1] == 'h') { + if (!ignore_whitespace) + current_line_length += 1; + } else { // N or n max_line_length = std::max(max_line_length, current_line_length); current_line_length = 0; @@ -241,7 +245,18 @@ size_t MaxLineLength(std::string const& text) { else if (token.type == agi::ass::DialogueTokenType::TEXT) { using namespace boost::locale::boundary; const ssegment_index characters(character, begin(text) + pos, begin(text) + pos + token.length); - current_line_length += boost::distance(characters); + if (!ignore_whitespace) + current_line_length += boost::distance(characters); + else { + // characters.rule(word_any) doesn't seem to work for character indexes (everything is word_none) + for (auto const& chr : characters) { + UChar32 c; + int i = 0; + U8_NEXT_UNSAFE(chr.begin(), i, c); + if (!u_isUWhiteSpace(c)) + ++current_line_length; + } + } } pos += token.length; diff --git a/aegisub/src/utils.h b/aegisub/src/utils.h index 4bdc943d0..0f19889d9 100644 --- a/aegisub/src/utils.h +++ b/aegisub/src/utils.h @@ -62,7 +62,7 @@ void StatusTimeout(wxString const& msg, int ms = 10000); int SmallestPowerOf2(int x); /// Get the length in characters of the longest line in the given text -size_t MaxLineLength(std::string const& text); +size_t MaxLineLength(std::string const& text, bool ignore_whitespace); /// @brief Launch a new copy of Aegisub. ///