From 0333e2cda73616dbf30e6c4092c275046a9043af Mon Sep 17 00:00:00 2001 From: ALRBP <26524976+ALRBP@users.noreply.github.com> Date: Mon, 29 Sep 2025 01:52:31 +0200 Subject: [PATCH 1/3] Fix .ass non-integer margin values --- src/ass_dialogue.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/ass_dialogue.cpp b/src/ass_dialogue.cpp index 093be7b7b0..556dd42f59 100644 --- a/src/ass_dialogue.cpp +++ b/src/ass_dialogue.cpp @@ -109,8 +109,23 @@ void AssDialogue::Parse(std::string const& raw) { End = agi::Trim(tkn.next_tok()); Style = tkn.next_str_trim(); Actor = tkn.next_str_trim(); - for (int& margin : Margin) - margin = mid(-9999, boost::lexical_cast(tkn.next_tok()), 99999); + for (int& margin : Margin) { + int parsed_margin = 0; + auto tok = tkn.next_tok(); + try { + parsed_margin = boost::lexical_cast(tok); + } + catch (boost::bad_lexical_cast const&) { + try { + // Try parsing and rounding a floating point number if integer failed + parsed_margin = (int)(boost::lexical_cast(tok)+0.5); + } + catch (...) { + // Just keep 0 if can not parse a number, eg. if field is empty + } + } + margin = mid(-9999, parsed_margin, 99999); + } Effect = tkn.next_str_trim(); std::string text{tkn.next_tok().begin(), str.end()}; From 37f13ef77b170fbd20f73a7abd489380e4df4df2 Mon Sep 17 00:00:00 2001 From: ALRBP <26524976+ALRBP@users.noreply.github.com> Date: Mon, 29 Sep 2025 03:21:30 +0200 Subject: [PATCH 2/3] Match libass behavior --- src/ass_dialogue.cpp | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/ass_dialogue.cpp b/src/ass_dialogue.cpp index 556dd42f59..f2a5368e8e 100644 --- a/src/ass_dialogue.cpp +++ b/src/ass_dialogue.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include #include @@ -111,20 +112,38 @@ void AssDialogue::Parse(std::string const& raw) { Actor = tkn.next_str_trim(); for (int& margin : Margin) { int parsed_margin = 0; - auto tok = tkn.next_tok(); - try { - parsed_margin = boost::lexical_cast(tok); + int sign = 1; + std::string tok{tkn.next_tok()}; + boost::trim(tok); + if (tok.starts_with("-")) {// Handling sign + sign = -1; + tok.erase(0,1); } - catch (boost::bad_lexical_cast const&) { + else if (tok.starts_with("+")) { + tok.erase(0,1); + } + if (tok.starts_with("0x")) {// Hexadecimal value try { - // Try parsing and rounding a floating point number if integer failed - parsed_margin = (int)(boost::lexical_cast(tok)+0.5); + std::size_t pos = 2; + parsed_margin = std::stoi(tok,&pos,16); } - catch (...) { - // Just keep 0 if can not parse a number, eg. if field is empty + catch (boost::bad_lexical_cast const&) {} + } + else { + try { + parsed_margin = boost::lexical_cast(tok); + } + catch (boost::bad_lexical_cast const&) { + try { + // Try parsing and rounding a floating point number if integer failed + parsed_margin = (int)(boost::lexical_cast(tok)+0.5); + } + catch (boost::bad_lexical_cast const&) { + // Just keep 0 if can not parse a number, eg. if field is empty + } } } - margin = mid(-9999, parsed_margin, 99999); + margin = mid(-9999, parsed_margin*sign, 99999); } Effect = tkn.next_str_trim(); From 0960471f9e7d46e0a094b392ef38f3f99e6d610c Mon Sep 17 00:00:00 2001 From: ALRBP <26524976+ALRBP@users.noreply.github.com> Date: Mon, 29 Sep 2025 03:27:48 +0200 Subject: [PATCH 3/3] Also recognize uppercase 0X hexa prefix --- src/ass_dialogue.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ass_dialogue.cpp b/src/ass_dialogue.cpp index f2a5368e8e..1047012750 100644 --- a/src/ass_dialogue.cpp +++ b/src/ass_dialogue.cpp @@ -122,7 +122,7 @@ void AssDialogue::Parse(std::string const& raw) { else if (tok.starts_with("+")) { tok.erase(0,1); } - if (tok.starts_with("0x")) {// Hexadecimal value + if (tok.starts_with("0x") || tok.starts_with("0X")) {// Hexadecimal value try { std::size_t pos = 2; parsed_margin = std::stoi(tok,&pos,16);