Fix #884, annoying wxString::Trim is destructive and there's no non-destructive variant. Adding a new function to utils.cpp to test whether a string is "blank", ie. empty or whitespace-only, as well as a function to check if a wchar_t is a whitspace character.
Trimming was used to test whether a string was blank or not, and this caused the source syllable texts to be altered when the kanji interpolation algorithm was run. Originally committed to SVN as r3085.
This commit is contained in:
parent
a7760db77b
commit
beedca2fba
5 changed files with 47 additions and 13 deletions
|
@ -42,6 +42,7 @@
|
|||
#include "ass_style.h"
|
||||
#include "ass_file.h"
|
||||
#include "ass_override.h"
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include "../../contrib/lua51/src/lualib.h"
|
||||
|
@ -78,7 +79,7 @@ namespace Automation4 {
|
|||
lua_pushstring(L, raw.mb_str(wxConvUTF8));
|
||||
lua_setfield(L, -2, "raw");
|
||||
|
||||
if (raw.Trim().IsEmpty()) {
|
||||
if (StringEmptyOrWhitespace(raw)) {
|
||||
lua_pushstring(L, "clear");
|
||||
|
||||
} else if (raw[0] == _T(';')) {
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "ass_style.h"
|
||||
#include "ass_file.h"
|
||||
#include "ass_override.h"
|
||||
#include "utils.h"
|
||||
#include <assert.h>
|
||||
#include <algorithm>
|
||||
#include <ruby.h>
|
||||
|
@ -67,7 +68,7 @@ namespace Automation4 {
|
|||
rb_hash_aset(ass_entry, STR2SYM("raw"), rb_str_new2(e->GetEntryData().mb_str(wxConvUTF8)));
|
||||
VALUE entry_class;
|
||||
|
||||
if (raw.Trim().IsEmpty()) {
|
||||
if (StringEmptyOrWhitespace(raw)) {
|
||||
entry_class = STR2SYM("clear");
|
||||
|
||||
} else if (raw[0] == _T(';')) {
|
||||
|
|
|
@ -64,11 +64,11 @@ class KaraokeLineMatchDisplay : public wxControl {
|
|||
struct MatchSyllable {
|
||||
int dur;
|
||||
wxString text;
|
||||
MatchSyllable() : dur(0) { }
|
||||
MatchSyllable(int _dur, const wxString &_text) : dur(_dur), text(_text) { }
|
||||
};
|
||||
struct MatchGroup {
|
||||
std::vector<MatchSyllable> src;
|
||||
typedef std::vector<MatchSyllable>::iterator SrcIterator;
|
||||
std::vector<const MatchSyllable> src;
|
||||
typedef std::vector<const MatchSyllable>::iterator SrcIterator;
|
||||
wxString dst;
|
||||
int duration;
|
||||
int last_render_width;
|
||||
|
@ -79,8 +79,8 @@ class KaraokeLineMatchDisplay : public wxControl {
|
|||
std::vector<MatchGroup> matched_groups;
|
||||
typedef std::vector<MatchGroup>::iterator MatchedGroupIterator;
|
||||
// Unmatched source syllables
|
||||
std::deque<MatchSyllable> unmatched_source;
|
||||
typedef std::deque<MatchSyllable>::iterator UnmatchedSourceIterator;
|
||||
std::deque<const MatchSyllable> unmatched_source;
|
||||
typedef std::deque<const MatchSyllable>::iterator UnmatchedSourceIterator;
|
||||
// Unmatched destination text
|
||||
wxString unmatched_destination;
|
||||
|
||||
|
@ -374,10 +374,7 @@ void KaraokeLineMatchDisplay::SetInputData(const AssDialogue *src, const AssDial
|
|||
// Start from 1 instead of 0: The first syllable is actually everything before the first
|
||||
for (size_t i = 1; i < kara.size(); ++i)
|
||||
{
|
||||
MatchSyllable syl;
|
||||
syl.text = kara[i].text;
|
||||
syl.dur = kara[i].duration;
|
||||
unmatched_source.push_back(syl);
|
||||
unmatched_source.push_back(MatchSyllable(kara[i].duration, kara[i].text));
|
||||
}
|
||||
delete varsrc;
|
||||
}
|
||||
|
@ -521,7 +518,7 @@ void KaraokeLineMatchDisplay::AutoMatchJapanese()
|
|||
|
||||
// Now the source syllable might consist of just whitespace.
|
||||
// Eat all whitespace at the start of the destination.
|
||||
if (src.Trim().size() == 0)
|
||||
if (StringEmptyOrWhitespace(src))
|
||||
{
|
||||
trycatchingmorespaces:
|
||||
// ASCII space
|
||||
|
@ -594,7 +591,7 @@ trycatchingmorespaces:
|
|||
// Yay! Time to interpolate.
|
||||
// Special case: If the last source syllable before the matching one is
|
||||
// empty or contains just whitespace, don't include that one.
|
||||
if (src_lookahead_pos > 1 && unmatched_source[src_lookahead_pos-2].text.Trim().size() == 0)
|
||||
if (src_lookahead_pos > 1 && StringEmptyOrWhitespace(unmatched_source[src_lookahead_pos-2].text))
|
||||
src_lookahead_pos -= 1;
|
||||
// Special case: Just one source syllable matching, pick all destination found
|
||||
if (src_lookahead_pos == 2)
|
||||
|
|
|
@ -303,6 +303,39 @@ void GetWordBoundaries(const wxString text,IntPairVector &results,int start,int
|
|||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// Determine whether wchar 'c' is a whitespace character
|
||||
bool IsWhitespace(wchar_t c)
|
||||
{
|
||||
const wchar_t whitespaces[] = {
|
||||
// http://en.wikipedia.org/wiki/Space_(punctuation)#Table_of_spaces
|
||||
0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x0020, 0x0085, 0x00A0,
|
||||
0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
|
||||
0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x2028, 0x2029, 0x202F,
|
||||
0x025F, 0x3000, 0xFEFF
|
||||
};
|
||||
const size_t num_chars = sizeof(whitespaces) / sizeof(whitespaces[0]);
|
||||
|
||||
for (size_t i = 0; i < num_chars; ++i)
|
||||
if (whitespaces[i] == c)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Returns true if str is empty of consists of only whitespace
|
||||
bool StringEmptyOrWhitespace(const wxString &str)
|
||||
{
|
||||
for (size_t i = 0; i < str.size(); ++i)
|
||||
if (!IsWhitespace(str[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// String to integer
|
||||
// wxString::ToLong() is slow and not as flexible
|
||||
|
|
|
@ -68,6 +68,8 @@ wxString PrettySize(int bytes);
|
|||
wxMenuItem *AppendBitmapMenuItem (wxMenu* parentMenu,int id,wxString text,wxString help,wxBitmap bmp,int pos=-1);
|
||||
int SmallestPowerOf2(int x);
|
||||
void GetWordBoundaries(const wxString text,IntPairVector &results,int start=0,int end=-1);
|
||||
bool IsWhitespace(wchar_t c);
|
||||
bool StringEmptyOrWhitespace(const wxString &str);
|
||||
int AegiStringToInt(const wxString &str,int start=0,int end=-1);
|
||||
int AegiStringToFix(const wxString &str,size_t decimalPlaces,int start=0,int end=-1);
|
||||
wxIcon BitmapToIcon(wxBitmap bmp);
|
||||
|
|
Loading…
Reference in a new issue