Beat some semblance of sanity into ass_override and related files. Fixes a pile of crashes when tags are missing expected parameters.
Originally committed to SVN as r4581.
This commit is contained in:
parent
c64e764648
commit
e2f8e69612
10 changed files with 413 additions and 872 deletions
|
@ -47,7 +47,6 @@
|
|||
#include "utils.h"
|
||||
#include "vfr.h"
|
||||
|
||||
/// @brief Constructs AssDialogue
|
||||
AssDialogue::AssDialogue()
|
||||
: Comment(false)
|
||||
, Layer(0)
|
||||
|
@ -109,29 +108,21 @@ AssDialogue::AssDialogue(wxString _data,int version)
|
|||
}
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssDialogue::~AssDialogue () {
|
||||
Clear();
|
||||
}
|
||||
|
||||
/// @brief Clear
|
||||
void AssDialogue::Clear () {
|
||||
ClearBlocks();
|
||||
}
|
||||
|
||||
/// @brief Clear blocks
|
||||
void AssDialogue::ClearBlocks() {
|
||||
using std::vector;
|
||||
for (vector<AssDialogueBlock*>::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) {
|
||||
for (std::vector<AssDialogueBlock*>::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) {
|
||||
delete *cur;
|
||||
}
|
||||
Blocks.clear();
|
||||
}
|
||||
|
||||
/// @brief Parse ASS Data
|
||||
/// @param rawData
|
||||
/// @param version
|
||||
/// @return
|
||||
bool AssDialogue::Parse(wxString rawData, int version) {
|
||||
size_t pos = 0;
|
||||
wxString temp;
|
||||
|
@ -224,92 +215,51 @@ bool AssDialogue::Parse(wxString rawData, int version) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// @brief Make data
|
||||
/// @return
|
||||
wxString AssDialogue::MakeData() {
|
||||
// Prepare
|
||||
static wxString final = _T("");
|
||||
wxString AssDialogue::GetData(bool ssa) {
|
||||
wxString final;
|
||||
|
||||
// Write all final
|
||||
if (Comment) final = _T("Comment: ");
|
||||
else final = _T("Dialogue: ");
|
||||
if (Comment) final = L"Comment: ";
|
||||
else final = L"Dialogue: ";
|
||||
|
||||
final += wxString::Format(_T("%01i"),Layer);
|
||||
final += _T(",");
|
||||
if (ssa) final += L"Marked=0,";
|
||||
|
||||
final += Start.GetASSFormated() + _T(",");
|
||||
final += End.GetASSFormated() + _T(",");
|
||||
final += wxString::Format(L"%01i",Layer);
|
||||
final += L",";
|
||||
|
||||
Style.Replace(_T(","),_T(";"));
|
||||
Actor.Replace(_T(","),_T(";"));
|
||||
final += Style + _T(",");
|
||||
final += Actor + _T(",");
|
||||
final += Start.GetASSFormated() + L",";
|
||||
final += End.GetASSFormated() + L",";
|
||||
|
||||
Style.Replace(L",",L";");
|
||||
Actor.Replace(L",",L";");
|
||||
final += Style + L",";
|
||||
final += Actor + L",";
|
||||
|
||||
final += GetMarginString(0);
|
||||
final += _T(",");
|
||||
final += L",";
|
||||
final += GetMarginString(1);
|
||||
final += _T(",");
|
||||
final += L",";
|
||||
final += GetMarginString(2);
|
||||
final += _T(",");
|
||||
final += L",";
|
||||
|
||||
Effect.Replace(_T(","),_T(";"));
|
||||
final += Effect + _T(",");
|
||||
Effect.Replace(L",",L";");
|
||||
final += Effect + L",";
|
||||
final += Text;
|
||||
|
||||
// Make sure that final has no line breaks
|
||||
final.Replace(_T("\n"),_T(""));
|
||||
final.Replace(_T("\r"),_T(""));
|
||||
final.Replace(L"\n","");
|
||||
final.Replace(L"\r","");
|
||||
|
||||
// Return final
|
||||
return final;
|
||||
}
|
||||
|
||||
/// @brief Get entry data
|
||||
/// @return
|
||||
const wxString AssDialogue::GetEntryData() {
|
||||
return MakeData();
|
||||
return GetData(false);
|
||||
}
|
||||
|
||||
/// @brief Set entry data
|
||||
/// @param newData
|
||||
void AssDialogue::SetEntryData(wxString newData) {
|
||||
}
|
||||
|
||||
/// @brief Get SSA version of Dialogue
|
||||
/// @return
|
||||
wxString AssDialogue::GetSSAText () {
|
||||
// Prepare
|
||||
wxString work = _T("");
|
||||
|
||||
// Write all work
|
||||
if (Comment) work += _T("Comment: ");
|
||||
else work += _T("Dialogue: ");
|
||||
|
||||
work += _T("Marked=0,");
|
||||
|
||||
work += Start.GetASSFormated() + _T(",");
|
||||
work += End.GetASSFormated() + _T(",");
|
||||
|
||||
Style.Replace(_T(","),_T(";"));
|
||||
Actor.Replace(_T(","),_T(";"));
|
||||
work += Style + _T(",");
|
||||
work += Actor + _T(",");
|
||||
|
||||
work += GetMarginString(0);
|
||||
work += _T(",");
|
||||
work += GetMarginString(1);
|
||||
work += _T(",");
|
||||
work += GetMarginString(2);
|
||||
work += _T(",");
|
||||
|
||||
Effect.Replace(_T(","),_T(";"));
|
||||
work += Effect + _T(",");
|
||||
work += Text;
|
||||
|
||||
return work;
|
||||
return GetData(true);
|
||||
}
|
||||
|
||||
/// @brief Yea, I convert to ASS tags, then parse that. So sue me. -------------- Parse SRT tags
|
||||
void AssDialogue::ParseSRTTags () {
|
||||
// Search and replace
|
||||
size_t total = 0;
|
||||
|
@ -350,7 +300,7 @@ void AssDialogue::ParseSRTTags () {
|
|||
|
||||
// Open tag
|
||||
if (isOpen) {
|
||||
wxString replaced = _T("");
|
||||
wxString replaced;
|
||||
|
||||
// Color tag
|
||||
if ((pos = work.find(_T("COLOR=\""),start)) != wxString::npos) {
|
||||
|
@ -441,15 +391,11 @@ void AssDialogue::ParseSRTTags () {
|
|||
Text.Replace(_T("}{"),_T(""));
|
||||
}
|
||||
|
||||
/// @brief Parse ASS tags
|
||||
void AssDialogue::ParseASSTags () {
|
||||
// Clear blocks
|
||||
ClearBlocks();
|
||||
|
||||
// Is drawing?
|
||||
int drawingLevel = 0;
|
||||
|
||||
// Loop through
|
||||
const size_t len = Text.size();
|
||||
size_t cur = 0;
|
||||
size_t end = 0;
|
||||
|
@ -472,7 +418,6 @@ void AssDialogue::ParseASSTags () {
|
|||
AssDialogueBlockPlain *block = new AssDialogueBlockPlain;
|
||||
block->text = work;
|
||||
Blocks.push_back(block);
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
|
@ -487,9 +432,8 @@ void AssDialogue::ParseASSTags () {
|
|||
// Look for \p in block
|
||||
std::vector<AssOverrideTag*>::iterator curTag;
|
||||
for (curTag = block->Tags.begin();curTag != block->Tags.end();curTag++) {
|
||||
AssOverrideTag *tag = *curTag;
|
||||
if (tag->Name == _T("\\p")) {
|
||||
drawingLevel = tag->Params.at(0)->Get<int>();
|
||||
if ((*curTag)->Name == L"\\p") {
|
||||
drawingLevel = (*curTag)->Params[0]->Get<int>(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,16 +479,11 @@ void AssDialogue::ParseASSTags () {
|
|||
}
|
||||
}
|
||||
|
||||
/// @brief Strip tags
|
||||
void AssDialogue::StripTags () {
|
||||
static wxRegEx reg(_T("\\{[^\\{]*\\}"),wxRE_ADVANCED);
|
||||
reg.Replace(&Text,_T(""));
|
||||
Text = GetStrippedText();
|
||||
}
|
||||
|
||||
/// @brief Strip a specific tag
|
||||
/// @param tagName
|
||||
void AssDialogue::StripTag (wxString tagName) {
|
||||
// Parse
|
||||
using std::list;
|
||||
using std::vector;
|
||||
ParseASSTags();
|
||||
|
@ -556,7 +495,7 @@ void AssDialogue::StripTag (wxString tagName) {
|
|||
AssDialogueBlockOverride *over = dynamic_cast<AssDialogueBlockOverride*>(*cur);
|
||||
wxString temp;
|
||||
for (size_t i=0;i<over->Tags.size();i++) {
|
||||
if (over->Tags[i]->Name != tagName) temp += over->Tags[i]->ToString();
|
||||
if (over->Tags[i]->Name != tagName) temp += *over->Tags[i];
|
||||
}
|
||||
|
||||
// Insert
|
||||
|
@ -565,14 +504,11 @@ void AssDialogue::StripTag (wxString tagName) {
|
|||
else final += (*cur)->GetText();
|
||||
}
|
||||
|
||||
// Update
|
||||
ClearBlocks();
|
||||
Text = final;
|
||||
}
|
||||
|
||||
/// @brief TODO: Improve this code ------------------- Convert tags to SRT
|
||||
void AssDialogue::ConvertTagsToSRT () {
|
||||
// Setup
|
||||
using std::list;
|
||||
using std::vector;
|
||||
AssDialogueBlockOverride* curBlock;
|
||||
|
@ -669,11 +605,10 @@ void AssDialogue::ConvertTagsToSRT () {
|
|||
ClearBlocks();
|
||||
}
|
||||
|
||||
/// @brief Updates text from tags
|
||||
void AssDialogue::UpdateText () {
|
||||
using std::vector;
|
||||
Text = _T("");
|
||||
for (vector<AssDialogueBlock*>::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) {
|
||||
if (Blocks.empty()) return;
|
||||
Text.clear();
|
||||
for (std::vector<AssDialogueBlock*>::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) {
|
||||
if ((*cur)->GetType() == BLOCK_OVERRIDE) {
|
||||
Text += _T("{");
|
||||
Text += (*cur)->GetText();
|
||||
|
@ -683,10 +618,9 @@ void AssDialogue::UpdateText () {
|
|||
}
|
||||
}
|
||||
|
||||
/// @brief Sets margin from a string
|
||||
/// @param origvalue
|
||||
/// @param which
|
||||
void AssDialogue::SetMarginString(const wxString origvalue,int which) {
|
||||
if (which < 0 || which >= 4) throw Aegisub::InvalidMarginIdError();
|
||||
|
||||
// Make it numeric
|
||||
wxString strvalue = origvalue;
|
||||
if (!strvalue.IsNumber()) {
|
||||
|
@ -707,14 +641,9 @@ void AssDialogue::SetMarginString(const wxString origvalue,int which) {
|
|||
if (value > 9999) value = 9999;
|
||||
|
||||
// Assign
|
||||
if (which < 0 || which >= 4) throw Aegisub::InvalidMarginIdError();
|
||||
Margin[which] = value;
|
||||
}
|
||||
|
||||
/// @brief Gets string for margin
|
||||
/// @param which
|
||||
/// @param pad
|
||||
/// @return
|
||||
wxString AssDialogue::GetMarginString(int which,bool pad) {
|
||||
if (which < 0 || which >= 4) throw Aegisub::InvalidMarginIdError();
|
||||
int value = Margin[which];
|
||||
|
@ -735,9 +664,6 @@ void AssDialogue::ProcessParameters(AssDialogueBlockOverride::ProcessParametersC
|
|||
//ClearBlocks();
|
||||
}
|
||||
|
||||
/// @brief Checks if two lines collide
|
||||
/// @param target
|
||||
/// @return
|
||||
bool AssDialogue::CollidesWith(AssDialogue *target) {
|
||||
if (!target) return false;
|
||||
int a = Start.GetMS();
|
||||
|
@ -747,49 +673,20 @@ bool AssDialogue::CollidesWith(AssDialogue *target) {
|
|||
return ((a < c) ? (c < b) : (a < d));
|
||||
}
|
||||
|
||||
/// @brief Return just the text without any overrides
|
||||
/// @return
|
||||
wxString AssDialogue::GetStrippedText() const {
|
||||
wxString justtext = wxString(_T(""));
|
||||
bool inCode = false;
|
||||
|
||||
for (size_t charindex = 0; charindex != Text.Len(); charindex++) {
|
||||
if (Text[charindex] == '{') inCode = true;
|
||||
else if (Text[charindex] == '}') inCode = false;
|
||||
else if (!inCode) justtext = justtext + Text[charindex];
|
||||
}
|
||||
return justtext;
|
||||
static wxRegEx reg(_T("\\{[^\\{]*\\}"),wxRE_ADVANCED);
|
||||
wxString txt(Text);
|
||||
reg.Replace(&txt,_T(""));
|
||||
return txt;
|
||||
}
|
||||
|
||||
/// @brief Clone
|
||||
/// @return
|
||||
AssEntry *AssDialogue::Clone() const {
|
||||
return new AssDialogue(*this);
|
||||
}
|
||||
|
||||
/// @brief Constructor AssDialogueBlock
|
||||
AssDialogueBlock::AssDialogueBlock () {
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssDialogueBlock::~AssDialogueBlock () {
|
||||
}
|
||||
|
||||
/// @brief Constructor AssDialogueBlockPlain
|
||||
AssDialogueBlockPlain::AssDialogueBlockPlain () {
|
||||
}
|
||||
|
||||
/// @brief Constructor AssDialogueBlockDrawing
|
||||
AssDialogueBlockDrawing::AssDialogueBlockDrawing () {
|
||||
}
|
||||
|
||||
/// @brief Multiply coordinates
|
||||
/// @param mx
|
||||
/// @param my
|
||||
/// @param x
|
||||
/// @param y
|
||||
void AssDialogueBlockDrawing::TransformCoords(int mx,int my,double x,double y) {
|
||||
// HACK: Implement a proper parser ffs!!
|
||||
// Could use Spline but it'd be slower and this seems to work fine
|
||||
wxStringTokenizer tkn(GetText(),_T(" "),wxTOKEN_DEFAULT);
|
||||
wxString cur;
|
||||
wxString final;
|
||||
|
@ -825,4 +722,3 @@ void AssDialogueBlockDrawing::TransformCoords(int mx,int my,double x,double y) {
|
|||
final = final.Left(final.Length()-1);
|
||||
text = final;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,6 @@
|
|||
/// @ingroup subs_storage
|
||||
///
|
||||
|
||||
|
||||
////////////
|
||||
// Includes
|
||||
|
||||
#ifndef AGI_PRE
|
||||
#include <vector>
|
||||
#endif
|
||||
|
@ -45,33 +41,15 @@
|
|||
#include "ass_entry.h"
|
||||
#include "ass_time.h"
|
||||
|
||||
|
||||
//////////////
|
||||
// Prototypes
|
||||
class AssOverrideParameter;
|
||||
class AssOverrideTag;
|
||||
class AssDialogueBlockPlain;
|
||||
class AssDialogueBlockOverride;
|
||||
class AssDialogueBlockDrawing;
|
||||
|
||||
|
||||
|
||||
/// DOCME
|
||||
enum ASS_BlockType {
|
||||
|
||||
/// DOCME
|
||||
BLOCK_BASE,
|
||||
|
||||
/// DOCME
|
||||
BLOCK_PLAIN,
|
||||
|
||||
/// DOCME
|
||||
BLOCK_OVERRIDE,
|
||||
|
||||
/// DOCME
|
||||
BLOCK_DRAWING
|
||||
};
|
||||
|
||||
class AssOverrideParameter;
|
||||
class AssOverrideTag;
|
||||
|
||||
/// DOCME
|
||||
/// @class AssDialogueBlock
|
||||
|
@ -97,15 +75,14 @@ enum ASS_BlockType {
|
|||
/// @endverbatim
|
||||
class AssDialogueBlock {
|
||||
public:
|
||||
|
||||
/// DOCME
|
||||
wxString text;
|
||||
|
||||
/// DOCME
|
||||
AssDialogue *parent;
|
||||
|
||||
AssDialogueBlock();
|
||||
virtual ~AssDialogueBlock();
|
||||
AssDialogueBlock() { }
|
||||
virtual ~AssDialogueBlock() { }
|
||||
|
||||
virtual ASS_BlockType GetType() = 0;
|
||||
|
||||
|
@ -125,12 +102,8 @@ public:
|
|||
/// DOCME
|
||||
class AssDialogueBlockPlain : public AssDialogueBlock {
|
||||
public:
|
||||
|
||||
/// @brief DOCME
|
||||
/// @return
|
||||
///
|
||||
ASS_BlockType GetType() { return BLOCK_PLAIN; }
|
||||
AssDialogueBlockPlain();
|
||||
AssDialogueBlockPlain() { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -142,16 +115,11 @@ public:
|
|||
/// DOCME
|
||||
class AssDialogueBlockDrawing : public AssDialogueBlock {
|
||||
public:
|
||||
|
||||
/// DOCME
|
||||
int Scale;
|
||||
|
||||
|
||||
/// @brief DOCME
|
||||
/// @return
|
||||
///
|
||||
ASS_BlockType GetType() { return BLOCK_DRAWING; }
|
||||
AssDialogueBlockDrawing();
|
||||
AssDialogueBlockDrawing() { }
|
||||
void TransformCoords(int trans_x,int trans_y,double mult_x,double mult_y);
|
||||
};
|
||||
|
||||
|
@ -164,7 +132,7 @@ public:
|
|||
/// DOCME
|
||||
class AssDialogueBlockOverride : public AssDialogueBlock {
|
||||
public:
|
||||
AssDialogueBlockOverride();
|
||||
AssDialogueBlockOverride() { }
|
||||
~AssDialogueBlockOverride();
|
||||
|
||||
/// DOCME
|
||||
|
@ -195,15 +163,12 @@ public:
|
|||
///
|
||||
/// DOCME
|
||||
class AssDialogue : public AssEntry {
|
||||
private:
|
||||
wxString MakeData();
|
||||
|
||||
wxString GetData(bool ssa);
|
||||
public:
|
||||
|
||||
/// Contains information about each block of text
|
||||
std::vector<AssDialogueBlock*> Blocks;
|
||||
|
||||
|
||||
/// Is this a comment line?
|
||||
bool Comment;
|
||||
/// Layer number
|
||||
|
@ -223,36 +188,54 @@ public:
|
|||
/// Raw text data
|
||||
wxString Text;
|
||||
|
||||
|
||||
/// @brief DOCME
|
||||
/// @return
|
||||
///
|
||||
ASS_EntryType GetType() { return ENTRY_DIALOGUE; }
|
||||
|
||||
bool Parse(wxString data,int version=1); // Parses raw ASS data into everything else
|
||||
void ParseASSTags(); // Parses text to generate block information (doesn't update data)
|
||||
void ParseSRTTags(); // Converts tags to ass format and calls ParseASSTags+UpdateData
|
||||
void ClearBlocks(); // Clear all blocks, ALWAYS call this after you're done processing tags
|
||||
/// @brief Parse raw ASS data into everything else
|
||||
/// @param data ASS line
|
||||
/// @param version ASS version to try first (4, 4+, ASS2)
|
||||
/// @return Did it successfully parse?
|
||||
bool Parse(wxString data,int version=1);
|
||||
/// Parse text as ASS to generate block information
|
||||
void ParseASSTags();
|
||||
/// Parse text as SRT to generate block information
|
||||
void ParseSRTTags();
|
||||
/// Clear all blocks, ALWAYS call this after you're done processing tags
|
||||
void ClearBlocks();
|
||||
|
||||
/// @brief Process parameters via callback
|
||||
/// @param callback The callback function to call per tag paramer
|
||||
/// @param callback The callback function to call per tag parameter
|
||||
/// @param userData User data to pass to callback function
|
||||
void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL); // Callback to process parameters
|
||||
void ConvertTagsToSRT(); // Converts tags to SRT format
|
||||
void StripTags(); // Strips all tags from the text
|
||||
void StripTag(wxString tagName);// Strips a specific tag from the text
|
||||
wxString GetStrippedText() const; // Gets text without tags
|
||||
void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL);
|
||||
/// Convert ASS tags to SRT tags
|
||||
void ConvertTagsToSRT();
|
||||
/// Strip all ASS tags from the text
|
||||
void StripTags();
|
||||
/// Strip a specific ASS tag from the text
|
||||
void StripTag(wxString tagName);
|
||||
/// Get text without tags
|
||||
wxString GetStrippedText() const;
|
||||
|
||||
void UpdateText(); // Generates text from the override tags
|
||||
/// If blocks have been parsed, update the text from their current value
|
||||
void UpdateText();
|
||||
const wxString GetEntryData();
|
||||
void SetEntryData(wxString newData);
|
||||
void Clear(); // Wipes all data
|
||||
/// Do nothing
|
||||
void SetEntryData(wxString) { }
|
||||
/// Synonym for ClearBlocks
|
||||
void Clear();
|
||||
|
||||
|
||||
void SetMarginString(const wxString value,int which); // Set string to a margin value (0 = left, 1 = right, 2 = vertical/top, 3 = bottom)
|
||||
wxString GetMarginString(int which,bool pad=true); // Returns the string of a margin value (0 = left, 1 = right, 2 = vertical/top, 3 = bottom)
|
||||
/// @brief Set a margin
|
||||
/// @param value New value of the margin
|
||||
/// @param which 0 = left, 1 = right, 2 = vertical/top, 3 = bottom
|
||||
void SetMarginString(const wxString value,int which);
|
||||
/// @brief Get a margin
|
||||
/// @param which 0 = left, 1 = right, 2 = vertical/top, 3 = bottom
|
||||
/// @param pad Pad the number to four digits
|
||||
wxString GetMarginString(int which,bool pad=true);
|
||||
/// Get the line as SSA rather than ASS
|
||||
wxString GetSSAText();
|
||||
bool CollidesWith(AssDialogue *target); // Checks if two lines collide
|
||||
/// Does this line collide with the passed line?
|
||||
bool CollidesWith(AssDialogue *target);
|
||||
|
||||
AssEntry *Clone() const;
|
||||
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
|
||||
/// @brief AssFile constructor
|
||||
AssFile::AssFile () {
|
||||
AssOverrideTagProto::LoadProtos();
|
||||
Clear();
|
||||
loaded = false;
|
||||
Modified = false;
|
||||
}
|
||||
|
||||
/// @brief AssFile destructor
|
||||
|
|
|
@ -110,7 +110,7 @@ void ParseAssKaraokeTags(const AssDialogue *line, AssKaraokeVector &syls)
|
|||
syl.unstripped_text += _T("{");
|
||||
brackets_open = true;
|
||||
}
|
||||
syl.unstripped_text += tag->ToString();
|
||||
syl.unstripped_text += *tag;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Copyright (c) 2005, Rodrigo Braz Monteiro
|
||||
// Copyright (c) 2010, Thomas Goyne <plorkyeran@aegisub.org>
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,114 +46,72 @@
|
|||
|
||||
#include "ass_dialogue.h"
|
||||
#include "ass_override.h"
|
||||
#include "utils.h"
|
||||
|
||||
/// @brief Constructor
|
||||
AssOverrideParameter::AssOverrideParameter () {
|
||||
classification = PARCLASS_NORMAL;
|
||||
ommited = false;
|
||||
AssOverrideParameter::AssOverrideParameter()
|
||||
: classification(PARCLASS_NORMAL)
|
||||
, omitted(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssOverrideParameter::~AssOverrideParameter () {
|
||||
AssOverrideParameter::AssOverrideParameter(const AssOverrideParameter ¶m)
|
||||
: VariableData(param)
|
||||
, classification(param.classification)
|
||||
, omitted(param.omitted)
|
||||
{
|
||||
}
|
||||
|
||||
void AssOverrideParameter::operator=(const AssOverrideParameter ¶m) {
|
||||
DeleteValue();
|
||||
new(this) AssOverrideParameter(param);
|
||||
}
|
||||
|
||||
/// @brief Copy
|
||||
/// @param param
|
||||
///
|
||||
void AssOverrideParameter::CopyFrom (const AssOverrideParameter ¶m) {
|
||||
*static_cast<VariableData*>(this) = static_cast<const VariableData&>(param);
|
||||
classification = param.classification;
|
||||
ommited = param.ommited;
|
||||
// From ass_dialogue.h
|
||||
AssDialogueBlockOverride::~AssDialogueBlockOverride() {
|
||||
delete_clear(Tags);
|
||||
}
|
||||
|
||||
/// @brief DOCME
|
||||
/// @param param
|
||||
///
|
||||
void AssOverrideParameter::operator= (const AssOverrideParameter ¶m) {
|
||||
CopyFrom(param);
|
||||
}
|
||||
void AssDialogueBlockOverride::ParseTags() {
|
||||
delete_clear(Tags);
|
||||
|
||||
/// @brief Constructor
|
||||
AssDialogueBlockOverride::AssDialogueBlockOverride () {
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssDialogueBlockOverride::~AssDialogueBlockOverride () {
|
||||
for (size_t i=0;i<Tags.size();i++) {
|
||||
delete Tags[i];
|
||||
}
|
||||
Tags.clear();
|
||||
}
|
||||
|
||||
/// @brief Read tags
|
||||
///
|
||||
void AssDialogueBlockOverride::ParseTags () {
|
||||
// Clear current vector
|
||||
for (size_t i=0;i<Tags.size();i++) {
|
||||
delete Tags[i];
|
||||
}
|
||||
Tags.clear();
|
||||
|
||||
// Fix parenthesis matching
|
||||
while (text.Freq(_T('(')) > text.Freq(_T(')'))) {
|
||||
text += _T(")");
|
||||
}
|
||||
|
||||
// Initialize tokenizer
|
||||
wxStringTokenizer tkn(text,_T("\\"),wxTOKEN_RET_EMPTY_ALL);
|
||||
wxStringTokenizer tkn(text, L"\\", wxTOKEN_STRTOK);
|
||||
wxString curTag;
|
||||
if (text.StartsWith(_T("\\"))) curTag = _T("\\");
|
||||
if (text.StartsWith(L"\\")) curTag = L"\\";
|
||||
|
||||
while (tkn.HasMoreTokens()) {
|
||||
//curTag will always start with a backslash after first loop - see end of loop
|
||||
curTag += tkn.GetNextToken();
|
||||
if (curTag == _T("\\")) continue;
|
||||
|
||||
// Check for parenthesis matching
|
||||
while (curTag.Freq(_T('(')) > curTag.Freq(_T(')'))) {
|
||||
if (!tkn.HasMoreTokens()) {
|
||||
wxLogWarning(_T("Unmatched parenthesis! Line contents: ") + parent->Text);
|
||||
break;
|
||||
}
|
||||
curTag << _T("\\") << tkn.GetNextToken();
|
||||
// Check for parenthesis matching for \t
|
||||
while (curTag.Freq(L'(') > curTag.Freq(L')') && tkn.HasMoreTokens()) {
|
||||
curTag << L"\\" << tkn.GetNextToken();
|
||||
}
|
||||
|
||||
AssOverrideTag *newTag = new AssOverrideTag;
|
||||
newTag->SetText(curTag);
|
||||
Tags.push_back(newTag);
|
||||
Tags.push_back(new AssOverrideTag(curTag));
|
||||
|
||||
curTag = _T("\\");
|
||||
curTag = L"\\";
|
||||
}
|
||||
}
|
||||
void AssDialogueBlockOverride::AddTag(wxString const& tag) {
|
||||
AssOverrideTag *newTag = new AssOverrideTag;
|
||||
newTag->SetText(tag);
|
||||
Tags.push_back(newTag);
|
||||
Tags.push_back(new AssOverrideTag(tag));
|
||||
}
|
||||
|
||||
/// @brief Get Text representation
|
||||
/// @return
|
||||
///
|
||||
wxString AssDialogueBlockOverride::GetText () {
|
||||
text = _T("");
|
||||
wxString AssDialogueBlockOverride::GetText() {
|
||||
text.clear();
|
||||
for (std::vector<AssOverrideTag*>::iterator cur=Tags.begin();cur!=Tags.end();cur++) {
|
||||
text += (*cur)->ToString();
|
||||
text += **cur;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
void AssDialogueBlockOverride::ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData) {
|
||||
for (std::vector<AssOverrideTag*>::iterator cur=Tags.begin();cur!=Tags.end();cur++) {
|
||||
int n = 0;
|
||||
AssOverrideTag *curTag = *cur;
|
||||
|
||||
// Find parameters
|
||||
for (std::vector<AssOverrideParameter*>::iterator curParam=curTag->Params.begin();curParam!=curTag->Params.end();curParam++) {
|
||||
AssOverrideParameter *curPar = *curParam;
|
||||
for (unsigned n = 0; n < curTag->Params.size(); n++) {
|
||||
AssOverrideParameter *curPar = curTag->Params[n];
|
||||
|
||||
if (curPar->GetType() != VARDATA_NONE && curPar->ommited == false) {
|
||||
// Do callback
|
||||
if (curPar->GetType() != VARDATA_NONE && !curPar->omitted) {
|
||||
(*callback)(curTag->Name,n,curPar,userData);
|
||||
|
||||
// Go recursive if it's a block parameter
|
||||
|
@ -160,45 +119,28 @@ void AssDialogueBlockOverride::ProcessParameters(AssDialogueBlockOverride::Proce
|
|||
curPar->Get<AssDialogueBlockOverride*>()->ProcessParameters(callback,userData);
|
||||
}
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Constructor
|
||||
/// @param _type
|
||||
/// @param opt
|
||||
/// @param classi
|
||||
///
|
||||
AssOverrideParamProto::AssOverrideParamProto (VariableDataType _type,int opt,ASS_ParameterClass classi) {
|
||||
type = _type;
|
||||
optional = opt;
|
||||
classification = classi;
|
||||
AssOverrideParamProto::AssOverrideParamProto(VariableDataType type,int opt,ASS_ParameterClass classi)
|
||||
: type(type)
|
||||
, optional(opt)
|
||||
, classification(classi)
|
||||
{
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssOverrideParamProto::~AssOverrideParamProto() {
|
||||
void AssOverrideTagProto::AddParam(VariableDataType type, ASS_ParameterClass classi, int opt) {
|
||||
params.push_back(AssOverrideParamProto(type, opt, classi));
|
||||
}
|
||||
void AssOverrideTagProto::Set(wxString newName, VariableDataType type, ASS_ParameterClass classi, int opt) {
|
||||
name = newName;
|
||||
params.push_back(AssOverrideParamProto(type, opt, classi));
|
||||
}
|
||||
|
||||
/// DOCME
|
||||
std::vector<AssOverrideTagProto> AssOverrideTagProto::proto;
|
||||
|
||||
/// DOCME
|
||||
bool AssOverrideTagProto::loaded = false;
|
||||
|
||||
/// @brief Constructor
|
||||
AssOverrideTagProto::AssOverrideTagProto() {
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssOverrideTagProto::~AssOverrideTagProto() {
|
||||
}
|
||||
|
||||
/// @brief Load prototypes
|
||||
/// @return
|
||||
///
|
||||
void AssOverrideTagProto::LoadProtos () {
|
||||
static std::vector<AssOverrideTagProto> proto;
|
||||
static void load_protos() {
|
||||
static bool loaded = false;
|
||||
if (loaded) return;
|
||||
loaded = true;
|
||||
|
||||
|
@ -207,341 +149,149 @@ void AssOverrideTagProto::LoadProtos () {
|
|||
|
||||
// Longer tag names must appear before shorter tag names
|
||||
|
||||
// \alpha
|
||||
proto[i].name = _T("\\alpha");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT));
|
||||
|
||||
// \bord<depth>
|
||||
i++;
|
||||
proto[i].name = _T("\\bord");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \xbord<depth>
|
||||
i++;
|
||||
proto[i].name = _T("\\xbord");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \ybord<depth>
|
||||
i++;
|
||||
proto[i].name = _T("\\ybord");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \shad<depth>
|
||||
i++;
|
||||
proto[i].name = _T("\\shad");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \xshad<depth>
|
||||
i++;
|
||||
proto[i].name = _T("\\xshad");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \yshad<depth>
|
||||
i++;
|
||||
proto[i].name = _T("\\yshad");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
proto[0].Set(L"\\alpha", VARDATA_TEXT); // \alpha
|
||||
proto[++i].Set(L"\\bord", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \bord<depth>
|
||||
proto[++i].Set(L"\\xbord", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \xbord<depth>
|
||||
proto[++i].Set(L"\\ybord", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \ybord<depth>
|
||||
proto[++i].Set(L"\\shad", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \shad<depth>
|
||||
proto[++i].Set(L"\\xshad", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \xshad<depth>
|
||||
proto[++i].Set(L"\\yshad", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \yshad<depth>
|
||||
|
||||
// \fade(<a1>,<a2>,<a3>,<t1>,<t2>,<t3>,<t4>)
|
||||
i++;
|
||||
proto[i].name = _T("\\fade");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].name = L"\\fade";
|
||||
proto[i].AddParam(VARDATA_INT);
|
||||
proto[i].AddParam(VARDATA_INT);
|
||||
proto[i].AddParam(VARDATA_INT);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
|
||||
// \move(<x1>,<y1>,<x2>,<y2>[,<t1>,<t2>])
|
||||
i++;
|
||||
proto[i].name = _T("\\move");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_6,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_6,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].name = L"\\move";
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
|
||||
// If these are rearranged, keep rect clip and vector clip adjacent in this order
|
||||
// \clip(<x1>,<y1>,<x2>,<y2>)
|
||||
i++;
|
||||
proto[i].name = _T("\\clip");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].name = L"\\clip";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
|
||||
// \clip([<scale>,]<some drawings>)
|
||||
i++;
|
||||
proto[i].name = _T("\\clip");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_2,PARCLASS_NORMAL));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_DRAWING));
|
||||
proto[i].name = L"\\clip";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_NORMAL,OPTIONAL_2);
|
||||
proto[i].AddParam(VARDATA_TEXT,PARCLASS_DRAWING);
|
||||
|
||||
// \iclip(<x1>,<y1>,<x2>,<y2>)
|
||||
i++;
|
||||
proto[i].name = _T("\\iclip");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].name = L"\\iclip";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
|
||||
// \iclip([<scale>,]<some drawings>)
|
||||
i++;
|
||||
proto[i].name = _T("\\iclip");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_2,PARCLASS_NORMAL));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_DRAWING));
|
||||
|
||||
// \fscx<percent>
|
||||
i++;
|
||||
proto[i].name = _T("\\fscx");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_RELATIVE_SIZE_X));
|
||||
|
||||
// \fscy<percent>
|
||||
i++;
|
||||
proto[i].name = _T("\\fscy");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_RELATIVE_SIZE_Y));
|
||||
proto[i].name = L"\\iclip";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_NORMAL,OPTIONAL_2);
|
||||
proto[i].AddParam(VARDATA_TEXT,PARCLASS_DRAWING);
|
||||
|
||||
proto[++i].Set(L"\\fscx", VARDATA_FLOAT,PARCLASS_RELATIVE_SIZE_X); // \fscx<percent>
|
||||
proto[++i].Set(L"\\fscy", VARDATA_FLOAT,PARCLASS_RELATIVE_SIZE_Y); // \fscy<percent>
|
||||
// \pos(<x>,<y>)
|
||||
i++;
|
||||
proto[i].name = _T("\\pos");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].name = L"\\pos";
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
|
||||
// \org(<x>,<y>)
|
||||
i++;
|
||||
proto[i].name = _T("\\org");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
|
||||
// \pbo<y>
|
||||
i++;
|
||||
proto[i].name = _T("\\pbo");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y));
|
||||
proto[i].name = L"\\org";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y);
|
||||
|
||||
proto[++i].Set(L"\\pbo", VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); // \pbo<y>
|
||||
// \fad(<t1>,<t2>)
|
||||
i++;
|
||||
proto[i].name = _T("\\fad");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_END));
|
||||
proto[i].name = L"\\fad";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_END);
|
||||
|
||||
// \fsp<pixels>
|
||||
i++;
|
||||
proto[i].name = _T("\\fsp");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \frx<degrees>
|
||||
i++;
|
||||
proto[i].name = _T("\\frx");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fry<degrees>
|
||||
i++;
|
||||
proto[i].name = _T("\\fry");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \frz<degrees>
|
||||
i++;
|
||||
proto[i].name = _T("\\frz");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fr<degrees>
|
||||
i++;
|
||||
proto[i].name = _T("\\fr");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fax<factor>
|
||||
i++;
|
||||
proto[i].name = _T("\\fax");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fay<factor>
|
||||
i++;
|
||||
proto[i].name = _T("\\fay");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \1c&H<bbggrr>&
|
||||
i++;
|
||||
proto[i].name = _T("\\1c");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \2c&H<bbggrr>&
|
||||
i++;
|
||||
proto[i].name = _T("\\2c");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \3c&H<bbggrr>&
|
||||
i++;
|
||||
proto[i].name = _T("\\3c");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \4c&H<bbggrr>&
|
||||
i++;
|
||||
proto[i].name = _T("\\4c");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \1a&H<aa>&
|
||||
i++;
|
||||
proto[i].name = _T("\\1a");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \2a&H<aa>&
|
||||
i++;
|
||||
proto[i].name = _T("\\2a");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \3a&H<aa>&
|
||||
i++;
|
||||
proto[i].name = _T("\\3a");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \4a&H<aa>&
|
||||
i++;
|
||||
proto[i].name = _T("\\4a");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fe<charset>
|
||||
i++;
|
||||
proto[i].name = _T("\\fe");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \ko<duration>
|
||||
i++;
|
||||
proto[i].name = _T("\\ko");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE));
|
||||
|
||||
// \kf<duration>
|
||||
i++;
|
||||
proto[i].name = _T("\\kf");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE));
|
||||
|
||||
// \be<strength>
|
||||
i++;
|
||||
proto[i].name = _T("\\be");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \blur<strength>
|
||||
i++;
|
||||
proto[i].name = _T("\\blur");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fn<name>
|
||||
i++;
|
||||
proto[i].name = _T("\\fn");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fs+<size>
|
||||
i++;
|
||||
proto[i].name = _T("\\fs+");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fs-<size>
|
||||
i++;
|
||||
proto[i].name = _T("\\fs-");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \fs<size>
|
||||
i++;
|
||||
proto[i].name = _T("\\fs");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE));
|
||||
|
||||
// \an<alignment>
|
||||
i++;
|
||||
proto[i].name = _T("\\an");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \c&H<bbggrr>&
|
||||
i++;
|
||||
proto[i].name = _T("\\c");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \b<0/1/weight>
|
||||
i++;
|
||||
proto[i].name = _T("\\b");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_1,PARCLASS_NORMAL));
|
||||
proto[i].params.back().defaultValue.Set<bool>(false);
|
||||
|
||||
// \i<0/1>
|
||||
i++;
|
||||
proto[i].name = _T("\\i");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_BOOL,OPTIONAL_1,PARCLASS_NORMAL));
|
||||
proto[i].params.back().defaultValue.Set<bool>(false);
|
||||
|
||||
// \u<0/1>
|
||||
i++;
|
||||
proto[i].name = _T("\\u");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_BOOL,OPTIONAL_1,PARCLASS_NORMAL));
|
||||
proto[i].params.back().defaultValue.Set<bool>(false);
|
||||
|
||||
// \s<0/1>
|
||||
i++;
|
||||
proto[i].name = _T("\\s");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_BOOL,OPTIONAL_1,PARCLASS_NORMAL));
|
||||
proto[i].params.back().defaultValue.Set<bool>(false);
|
||||
|
||||
// \a<alignment>
|
||||
i++;
|
||||
proto[i].name = _T("\\a");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \k<duration>
|
||||
i++;
|
||||
proto[i].name = _T("\\k");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE));
|
||||
|
||||
// \K<duration>
|
||||
i++;
|
||||
proto[i].name = _T("\\K");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE));
|
||||
|
||||
// \q<0-3>
|
||||
i++;
|
||||
proto[i].name = _T("\\q");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \p<n>
|
||||
i++;
|
||||
proto[i].name = _T("\\p");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
|
||||
// \r[<name>]
|
||||
i++;
|
||||
proto[i].name = _T("\\r");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,OPTIONAL_1,PARCLASS_NORMAL));
|
||||
proto[++i].Set(L"\\fsp", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \fsp<pixels>
|
||||
proto[++i].Set(L"\\frx", VARDATA_FLOAT); // \frx<degrees>
|
||||
proto[++i].Set(L"\\fry", VARDATA_FLOAT); // \fry<degrees>
|
||||
proto[++i].Set(L"\\frz", VARDATA_FLOAT); // \frz<degrees>
|
||||
proto[++i].Set(L"\\fr", VARDATA_FLOAT); // \fr<degrees>
|
||||
proto[++i].Set(L"\\fax", VARDATA_FLOAT); // \fax<factor>
|
||||
proto[++i].Set(L"\\fay", VARDATA_FLOAT); // \fay<factor>
|
||||
proto[++i].Set(L"\\1c", VARDATA_TEXT); // \1c&H<bbggrr>&
|
||||
proto[++i].Set(L"\\2c", VARDATA_TEXT); // \2c&H<bbggrr>&
|
||||
proto[++i].Set(L"\\3c", VARDATA_TEXT); // \3c&H<bbggrr>&
|
||||
proto[++i].Set(L"\\4c", VARDATA_TEXT); // \4c&H<bbggrr>&
|
||||
proto[++i].Set(L"\\1a", VARDATA_TEXT); // \1a&H<aa>&
|
||||
proto[++i].Set(L"\\2a", VARDATA_TEXT); // \2a&H<aa>&
|
||||
proto[++i].Set(L"\\3a", VARDATA_TEXT); // \3a&H<aa>&
|
||||
proto[++i].Set(L"\\4a", VARDATA_TEXT); // \4a&H<aa>&
|
||||
proto[++i].Set(L"\\fe", VARDATA_TEXT); // \fe<charset>
|
||||
proto[++i].Set(L"\\ko", VARDATA_INT,PARCLASS_KARAOKE); // \ko<duration>
|
||||
proto[++i].Set(L"\\kf", VARDATA_INT,PARCLASS_KARAOKE); // \kf<duration>
|
||||
proto[++i].Set(L"\\be", VARDATA_INT); // \be<strength>
|
||||
proto[++i].Set(L"\\blur", VARDATA_FLOAT); // \blur<strength>
|
||||
proto[++i].Set(L"\\fn", VARDATA_TEXT); // \fn<name>
|
||||
proto[++i].Set(L"\\fs+", VARDATA_FLOAT); // \fs+<size>
|
||||
proto[++i].Set(L"\\fs-", VARDATA_FLOAT); // \fs-<size>
|
||||
proto[++i].Set(L"\\fs", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \fs<size>
|
||||
proto[++i].Set(L"\\an", VARDATA_INT); // \an<alignment>
|
||||
proto[++i].Set(L"\\c", VARDATA_TEXT); // \c&H<bbggrr>&
|
||||
proto[++i].Set(L"\\b", VARDATA_INT); // \b<0/1/weight>
|
||||
proto[++i].Set(L"\\i", VARDATA_BOOL); // \i<0/1>
|
||||
proto[++i].Set(L"\\u", VARDATA_BOOL); // \u<0/1>
|
||||
proto[++i].Set(L"\\s", VARDATA_BOOL); // \s<0/1>
|
||||
proto[++i].Set(L"\\a", VARDATA_INT); // \a<alignment>
|
||||
proto[++i].Set(L"\\k", VARDATA_INT,PARCLASS_KARAOKE); // \k<duration>
|
||||
proto[++i].Set(L"\\K", VARDATA_INT,PARCLASS_KARAOKE); // \K<duration>
|
||||
proto[++i].Set(L"\\q", VARDATA_INT); // \q<0-3>
|
||||
proto[++i].Set(L"\\p", VARDATA_INT); // \p<n>
|
||||
proto[++i].Set(L"\\r", VARDATA_TEXT); // \r[<name>]
|
||||
|
||||
// \t([<t1>,<t2>,][<accel>,]<style modifiers>)
|
||||
i++;
|
||||
proto[i].name = _T("\\t");
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_3 | OPTIONAL_4,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_3 | OPTIONAL_4,PARCLASS_RELATIVE_TIME_START));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,OPTIONAL_2 | OPTIONAL_4,PARCLASS_NORMAL));
|
||||
proto[i].params.push_back(AssOverrideParamProto(VARDATA_BLOCK,NOT_OPTIONAL,PARCLASS_NORMAL));
|
||||
proto[i].name = L"\\t";
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START,OPTIONAL_3 | OPTIONAL_4);
|
||||
proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START,OPTIONAL_3 | OPTIONAL_4);
|
||||
proto[i].AddParam(VARDATA_FLOAT,PARCLASS_NORMAL,OPTIONAL_2 | OPTIONAL_4);
|
||||
proto[i].AddParam(VARDATA_BLOCK);
|
||||
}
|
||||
|
||||
/// @brief Constructor
|
||||
AssOverrideTag::AssOverrideTag () {
|
||||
valid = false;
|
||||
AssOverrideTag::AssOverrideTag() : valid(false) { }
|
||||
AssOverrideTag::AssOverrideTag(wxString text) {
|
||||
SetText(text);
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
AssOverrideTag::~AssOverrideTag () {
|
||||
Clear();
|
||||
delete_clear(Params);
|
||||
}
|
||||
|
||||
/// @brief Clear
|
||||
void AssOverrideTag::Clear() {
|
||||
for (std::vector<AssOverrideParameter*>::iterator cur=Params.begin();cur!=Params.end();cur++) {
|
||||
delete *cur;
|
||||
}
|
||||
Params.clear();
|
||||
delete_clear(Params);
|
||||
Params.reserve(6);
|
||||
valid = false;
|
||||
}
|
||||
|
||||
/// @brief Parses text and sets tag
|
||||
/// @param text
|
||||
void AssOverrideTag::SetText (const wxString &text) {
|
||||
// Determine name
|
||||
for (AssOverrideTagProto::iterator cur=AssOverrideTagProto::proto.begin();cur!=AssOverrideTagProto::proto.end();cur++) {
|
||||
void AssOverrideTag::SetText(const wxString &text) {
|
||||
load_protos();
|
||||
for (AssOverrideTagProto::iterator cur=proto.begin();cur!=proto.end();cur++) {
|
||||
if (text.StartsWith(cur->name)) {
|
||||
Name = cur->name;
|
||||
ParseParameters(text.Mid(Name.length()), cur);
|
||||
|
@ -554,213 +304,168 @@ void AssOverrideTag::SetText (const wxString &text) {
|
|||
valid = false;
|
||||
}
|
||||
|
||||
/// @brief Checks if it is valid
|
||||
/// @return
|
||||
///
|
||||
bool AssOverrideTag::IsValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
/// @brief Parses the parameters for the ass override tag
|
||||
/// @param text All text between the name and the next \ or the end of the override block
|
||||
///
|
||||
std::vector<wxString> tokenize(const wxString &text) {
|
||||
std::vector<wxString> paramList;
|
||||
paramList.reserve(6);
|
||||
|
||||
if (text.empty()) {
|
||||
return paramList;
|
||||
}
|
||||
if (text[0] != L'(') {
|
||||
// There's just one parameter (because there's no parentheses)
|
||||
// This means text is all our parameters
|
||||
wxString param(text);
|
||||
paramList.push_back(param.Trim(true).Trim(false));
|
||||
return paramList;
|
||||
}
|
||||
|
||||
// Ok, so there are parentheses used here, so there may be more than one parameter
|
||||
// Enter fullscale parsing!
|
||||
size_t i = 0, textlen = text.size();
|
||||
size_t start = 0;
|
||||
int parDepth = 1;
|
||||
while (i < textlen && parDepth > 0) {
|
||||
// Just skip until next ',' or ')', whichever comes first
|
||||
// (Next ')' is achieved when parDepth == 0)
|
||||
start = ++i;
|
||||
while (i < textlen && parDepth > 0) {
|
||||
wxChar c = text[i];
|
||||
// parDepth 1 is where we start, and the tag-level we're interested in parsing on
|
||||
if (c == L',' && parDepth == 1) break;
|
||||
if (c == _T('(')) parDepth++;
|
||||
else if (c == _T(')')) {
|
||||
parDepth--;
|
||||
if (parDepth < 0) {
|
||||
wxLogWarning(L"Unmatched parenthesis near '%s'!\nTag-parsing incomplete.", text.SubString(i, 10).c_str());
|
||||
return paramList;
|
||||
}
|
||||
else if (parDepth == 0) {
|
||||
// We just ate the parenthesis ending this parameter block
|
||||
// Make sure it doesn't get included in the parameter text
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// i now points to the first character not member of this parameter
|
||||
paramList.push_back(text.SubString(start, i-1).Trim(true).Trim(false));
|
||||
}
|
||||
|
||||
if (i+1 < textlen) {
|
||||
// There's some additional garbage after the parentheses
|
||||
// Just add it in for completeness
|
||||
paramList.push_back(text.Mid(i+1));
|
||||
}
|
||||
return paramList;
|
||||
}
|
||||
|
||||
void AssOverrideTag::ParseParameters(const wxString &text, AssOverrideTagProto::iterator proto) {
|
||||
Clear();
|
||||
|
||||
// Tokenize text, attempting to find all parameters
|
||||
wxArrayString paramList;
|
||||
paramList.reserve(6);
|
||||
wxString work;
|
||||
|
||||
{
|
||||
if (text.IsEmpty() || text[0] != _T('(')) {
|
||||
// There's just one (or none at all) parameter (because there's no parantheses)
|
||||
// This means text is all our parameters
|
||||
wxString param(text);
|
||||
paramList.Add(param.Trim(true).Trim(false));
|
||||
// Only using goto here to avoid yet another nested block (keeps the code cleaner!)
|
||||
goto end_tokenizing;
|
||||
}
|
||||
|
||||
// Ok, so there are parantheses used here, so there may be more than one parameter
|
||||
// Enter fullscale parsing!
|
||||
size_t i = 0, textlen = text.Length();
|
||||
size_t start = 0;
|
||||
int parDepth = 1;
|
||||
while (i < textlen && parDepth > 0) {
|
||||
// Just skip until next ',' or ')', whichever comes first
|
||||
// (Next ')' is achieved when parDepth == 0)
|
||||
start = ++i;
|
||||
while (i < textlen && parDepth > 0) {
|
||||
wxChar c = text[i];
|
||||
// parDepth 1 is where we start, and the tag-level we're interested in parsing on
|
||||
if (c == L',' && parDepth == 1) break;
|
||||
if (c == _T('(')) parDepth++;
|
||||
else if (c == _T(')')) {
|
||||
parDepth--;
|
||||
if (parDepth < 0) {
|
||||
wxLogWarning(_T("Unmatched parenthesis near '%s'!\nTag-parsing incomplete."), text.SubString(i, 10).c_str());
|
||||
goto end_tokenizing;
|
||||
}
|
||||
else if (parDepth == 0) {
|
||||
// We just ate the paranthesis ending this parameter block
|
||||
// Make sure it doesn't get included in the parameter text
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// i now points to the first character not member of this parameter
|
||||
work = text.SubString(start, i-1);
|
||||
work.Trim(true).Trim(false);
|
||||
paramList.Add(work);
|
||||
//LOG_D("subtitle/ass/override" << "Got parameter: << work.c_str();
|
||||
}
|
||||
|
||||
if (i+1 < textlen) {
|
||||
// There's some additional garbage after the parantheses
|
||||
// Just add it in for completeness
|
||||
paramList.Add(text.Mid(i+1));
|
||||
}
|
||||
}
|
||||
// This label is only gone to from inside the previous block, if the tokenizing needs to end early
|
||||
end_tokenizing:
|
||||
|
||||
int curPar = 0;
|
||||
size_t totalPars = paramList.GetCount();
|
||||
|
||||
// Get optional parameters flag
|
||||
ASS_ParameterOptional parsFlag = OPTIONAL_0;
|
||||
switch (totalPars) {
|
||||
case 1: parsFlag = OPTIONAL_1; break;
|
||||
case 2: parsFlag = OPTIONAL_2; break;
|
||||
case 3: parsFlag = OPTIONAL_3; break;
|
||||
case 4: parsFlag = OPTIONAL_4; break;
|
||||
case 5: parsFlag = OPTIONAL_5; break;
|
||||
case 6: parsFlag = OPTIONAL_6; break;
|
||||
case 7: parsFlag = OPTIONAL_7; break;
|
||||
}
|
||||
std::vector<wxString> paramList = tokenize(text);
|
||||
size_t totalPars = paramList.size();
|
||||
|
||||
int parsFlag = 1 << (totalPars - 1); // Get optional parameters flag
|
||||
// vector (i)clip is the second clip prototype in the list
|
||||
if ((Name == _T("\\clip") || Name == _T("\\iclip")) && totalPars != 4) {
|
||||
if ((Name == L"\\clip" || Name == L"\\iclip") && totalPars != 4) {
|
||||
++proto;
|
||||
}
|
||||
|
||||
// Get parameters
|
||||
size_t n=0;
|
||||
wxString curtok = _T("");
|
||||
if (curPar < (signed)totalPars) {
|
||||
curtok = paramList[curPar];
|
||||
curPar++;
|
||||
}
|
||||
|
||||
// For each parameter
|
||||
while (n < proto->params.size()) {
|
||||
unsigned curPar = 0;
|
||||
for (size_t n = 0; n < proto->params.size(); n++) {
|
||||
AssOverrideParamProto *curproto = &proto->params[n];
|
||||
bool isDefault = false;
|
||||
n++;
|
||||
|
||||
// Create parameter
|
||||
AssOverrideParameter *newparam = new AssOverrideParameter;
|
||||
newparam->classification = curproto->classification;
|
||||
Params.push_back(newparam);
|
||||
|
||||
// Check if it's optional and not set (set to default)
|
||||
if (!(curproto->optional & parsFlag)) {
|
||||
if (curproto->defaultValue.GetType() != VARDATA_NONE) {
|
||||
isDefault = true;
|
||||
newparam->CopyFrom(curproto->defaultValue);
|
||||
}
|
||||
newparam->ommited = true;
|
||||
// This parameter doesn't really count against the number of parsed parameters,
|
||||
// since it's left out. Don't count it.
|
||||
curPar--;
|
||||
// Check if it's optional and not present
|
||||
if (!(curproto->optional & parsFlag) || curPar >= totalPars) {
|
||||
newparam->omitted = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isDefault == false && curtok.length() > 0) {
|
||||
wxChar firstChar = curtok[0];
|
||||
bool auto4 = (firstChar == _T('!') || firstChar == _T('$') || firstChar == _T('%')) && curproto->type != VARDATA_BLOCK;
|
||||
if (auto4) {
|
||||
newparam->Set(curtok);
|
||||
}
|
||||
else {
|
||||
// Determine parameter type and set value
|
||||
switch (curproto->type) {
|
||||
case VARDATA_INT: {
|
||||
long temp = 0;
|
||||
curtok.ToLong(&temp);
|
||||
newparam->Set<int>(temp);
|
||||
break;
|
||||
}
|
||||
case VARDATA_FLOAT: {
|
||||
double temp = 0.0;
|
||||
curtok.ToDouble(&temp);
|
||||
newparam->Set<double>(temp);
|
||||
break;
|
||||
}
|
||||
case VARDATA_TEXT:
|
||||
newparam->Set(curtok);
|
||||
break;
|
||||
case VARDATA_BOOL: {
|
||||
long temp = false;
|
||||
curtok.ToLong(&temp);
|
||||
newparam->Set<bool>(temp != 0);
|
||||
break;
|
||||
}
|
||||
case VARDATA_BLOCK: {
|
||||
AssDialogueBlockOverride *temp = new AssDialogueBlockOverride;
|
||||
temp->text = curtok;
|
||||
temp->ParseTags();
|
||||
newparam->Set(temp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
wxString curtok = paramList[curPar++];
|
||||
|
||||
// Get next actual parameter
|
||||
if (curPar < (signed)totalPars) {
|
||||
// Unless this parameter was omitted (in which case the token shouldn't be eaten)
|
||||
if (!newparam->ommited) {
|
||||
curtok = paramList[curPar];
|
||||
if (curtok.empty()) {
|
||||
curPar++;
|
||||
continue;
|
||||
}
|
||||
|
||||
wxChar firstChar = curtok[0];
|
||||
bool auto4 = (firstChar == _T('!') || firstChar == _T('$') || firstChar == _T('%')) && curproto->type != VARDATA_BLOCK;
|
||||
if (auto4) {
|
||||
newparam->Set(curtok);
|
||||
}
|
||||
else {
|
||||
switch (curproto->type) {
|
||||
case VARDATA_INT: {
|
||||
long temp;
|
||||
curtok.ToLong(&temp);
|
||||
newparam->Set<int>(temp);
|
||||
break;
|
||||
}
|
||||
curPar++;
|
||||
case VARDATA_FLOAT: {
|
||||
double temp;
|
||||
curtok.ToDouble(&temp);
|
||||
newparam->Set(temp);
|
||||
break;
|
||||
}
|
||||
case VARDATA_TEXT:
|
||||
newparam->Set(curtok);
|
||||
break;
|
||||
case VARDATA_BOOL: {
|
||||
long temp;
|
||||
curtok.ToLong(&temp);
|
||||
newparam->Set<bool>(temp != 0);
|
||||
break;
|
||||
}
|
||||
case VARDATA_BLOCK: {
|
||||
AssDialogueBlockOverride *temp = new AssDialogueBlockOverride;
|
||||
temp->text = curtok;
|
||||
temp->ParseTags();
|
||||
newparam->Set(temp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else curtok = _T("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Get string
|
||||
wxString AssOverrideTag::ToString() {
|
||||
// Start with name
|
||||
AssOverrideTag::operator wxString() {
|
||||
wxString result = Name;
|
||||
|
||||
// Determine if it needs parentheses
|
||||
bool parenthesis = false;
|
||||
if (Name == _T("\\t") ||
|
||||
Name == _T("\\pos") ||
|
||||
Name == _T("\\fad") ||
|
||||
Name == _T("\\org") ||
|
||||
Name == _T("\\clip") ||
|
||||
Name == _T("\\iclip") ||
|
||||
Name == _T("\\move") ||
|
||||
Name == _T("\\fade")) parenthesis = true;
|
||||
if (parenthesis) result += _T("(");
|
||||
bool parentheses =
|
||||
Name == L"\\t" ||
|
||||
Name == L"\\pos" ||
|
||||
Name == L"\\fad" ||
|
||||
Name == L"\\org" ||
|
||||
Name == L"\\clip" ||
|
||||
Name == L"\\iclip" ||
|
||||
Name == L"\\move" ||
|
||||
Name == L"\\fade";
|
||||
if (parentheses) result += L"(";
|
||||
|
||||
// Add parameters
|
||||
int n = 0;
|
||||
bool any = false;
|
||||
for (std::vector<AssOverrideParameter*>::iterator cur=Params.begin();cur!=Params.end();cur++) {
|
||||
if ((*cur)->GetType() != VARDATA_NONE && (*cur)->ommited == false) {
|
||||
if ((*cur)->GetType() != VARDATA_NONE && !(*cur)->omitted) {
|
||||
result += (*cur)->Get<wxString>();
|
||||
result += _T(",");
|
||||
n++;
|
||||
result += L",";
|
||||
any = true;
|
||||
}
|
||||
}
|
||||
if (n > 0) result = result.Left(result.Length()-1);
|
||||
if (any) result = result.Left(result.Length()-1);
|
||||
|
||||
// Finish
|
||||
if (parenthesis) result += _T(")");
|
||||
if (parentheses) result += L")";
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -40,142 +40,88 @@
|
|||
|
||||
#include "variable_data.h"
|
||||
|
||||
class AssDialogueBlockOverride;
|
||||
|
||||
/// DOCME
|
||||
/// Type of parameter; probably only used by the resample tool
|
||||
enum ASS_ParameterClass {
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_NORMAL,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_ABSOLUTE_SIZE,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_ABSOLUTE_POS_X,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_ABSOLUTE_POS_Y,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_RELATIVE_SIZE_X,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_RELATIVE_SIZE_Y,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_RELATIVE_TIME_START,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_RELATIVE_TIME_END,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_KARAOKE,
|
||||
|
||||
/// DOCME
|
||||
PARCLASS_DRAWING
|
||||
};
|
||||
|
||||
/// DOCME
|
||||
/// The parameter is absent unless the total number of parameters is the
|
||||
/// indicated number. Note that only arguments not at the end need to be marked
|
||||
/// as optional; this is just to know which parameters to skip when there are
|
||||
/// earlier optional arguments
|
||||
enum ASS_ParameterOptional {
|
||||
|
||||
/// DOCME
|
||||
NOT_OPTIONAL = 0xFF,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_0 = 0x00,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_1 = 0x01,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_2 = 0x02,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_3 = 0x04,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_4 = 0x08,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_5 = 0x10,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_6 = 0x20,
|
||||
|
||||
/// DOCME
|
||||
OPTIONAL_7 = 0x40
|
||||
};
|
||||
|
||||
/// DOCME
|
||||
/// @class AssOverrideParameter
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// DOCME
|
||||
/// @brief A single parameter to an override tag
|
||||
class AssOverrideParameter : public VariableData {
|
||||
public:
|
||||
|
||||
/// DOCME
|
||||
/// Type of parameter
|
||||
ASS_ParameterClass classification;
|
||||
|
||||
/// DOCME
|
||||
bool ommited;
|
||||
/// Is the parameter's value actually given?
|
||||
bool omitted;
|
||||
|
||||
AssOverrideParameter();
|
||||
~AssOverrideParameter();
|
||||
|
||||
void operator= (const AssOverrideParameter ¶m);
|
||||
void CopyFrom (const AssOverrideParameter ¶m);
|
||||
AssOverrideParameter(const AssOverrideParameter&);
|
||||
void operator=(const AssOverrideParameter ¶m);
|
||||
};
|
||||
|
||||
/// DOCME
|
||||
/// @class AssOverrideParamProto
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// DOCME
|
||||
class AssOverrideParamProto {
|
||||
public:
|
||||
|
||||
/// DOCME
|
||||
/// @brief Prototype of a single override parameter
|
||||
struct AssOverrideParamProto {
|
||||
/// ASS_ParameterOptional
|
||||
int optional;
|
||||
|
||||
/// DOCME
|
||||
/// Type of this parameter
|
||||
VariableDataType type;
|
||||
|
||||
/// DOCME
|
||||
AssOverrideParameter defaultValue;
|
||||
|
||||
/// DOCME
|
||||
/// Semantic type of this parameter
|
||||
ASS_ParameterClass classification;
|
||||
|
||||
AssOverrideParamProto (VariableDataType _type,int opt=NOT_OPTIONAL,ASS_ParameterClass classi=PARCLASS_NORMAL);
|
||||
~AssOverrideParamProto();
|
||||
AssOverrideParamProto (VariableDataType type, int opt=NOT_OPTIONAL, ASS_ParameterClass classi=PARCLASS_NORMAL);
|
||||
};
|
||||
|
||||
/// DOCME
|
||||
/// @class AssOverrideTagProto
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// DOCME
|
||||
class AssOverrideTagProto {
|
||||
public:
|
||||
/// DOCME
|
||||
struct AssOverrideTagProto {
|
||||
/// Name of the tag, with slash
|
||||
wxString name;
|
||||
|
||||
/// DOCME
|
||||
/// Parameters to this tag
|
||||
std::vector<AssOverrideParamProto> params;
|
||||
|
||||
/// DOCME
|
||||
static std::vector<AssOverrideTagProto> proto;
|
||||
|
||||
/// DOCME
|
||||
static bool loaded;
|
||||
static void LoadProtos();
|
||||
|
||||
typedef std::vector<AssOverrideTagProto>::iterator iterator;
|
||||
|
||||
AssOverrideTagProto();
|
||||
~AssOverrideTagProto();
|
||||
/// @brief Add a parameter to this tag prototype
|
||||
/// @param type Data type of the parameter
|
||||
/// @param classi Semantic type of the parameter
|
||||
/// @param opt Situations in which this parameter is present
|
||||
void AddParam(VariableDataType type, ASS_ParameterClass classi = PARCLASS_NORMAL, int opt = NOT_OPTIONAL);
|
||||
/// @brief Convenience function for single-argument tags
|
||||
/// @param name Name of the tag, with slash
|
||||
/// @param type Data type of the parameter
|
||||
/// @param classi Semantic type of the parameter
|
||||
/// @param opt Situations in which this parameter is present
|
||||
void Set(wxString name, VariableDataType type, ASS_ParameterClass classi = PARCLASS_NORMAL, int opt = NOT_OPTIONAL);
|
||||
};
|
||||
|
||||
/// DOCME
|
||||
|
@ -184,25 +130,21 @@ public:
|
|||
///
|
||||
/// DOCME
|
||||
class AssOverrideTag {
|
||||
private:
|
||||
|
||||
/// DOCME
|
||||
bool valid;
|
||||
|
||||
public:
|
||||
|
||||
/// DOCME
|
||||
wxString Name;
|
||||
|
||||
/// DOCME
|
||||
std::vector <AssOverrideParameter*> Params;
|
||||
|
||||
AssOverrideTag();
|
||||
AssOverrideTag(wxString text);
|
||||
~AssOverrideTag();
|
||||
|
||||
bool IsValid();
|
||||
/// @brief Parses the parameters for the ass override tag
|
||||
/// @param text All text between the name and the next \ or the end of the override block
|
||||
void ParseParameters(const wxString &text, AssOverrideTagProto::iterator proto);
|
||||
void Clear();
|
||||
void SetText(const wxString &text);
|
||||
wxString ToString();
|
||||
operator wxString();
|
||||
};
|
||||
|
|
|
@ -946,7 +946,7 @@ namespace Automation4 {
|
|||
ktext += _T("{");
|
||||
brackets_open = true;
|
||||
}
|
||||
ktext += tag->ToString();
|
||||
ktext += *tag;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1290,7 +1290,7 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b
|
|||
//if (insert.Contains(override->Tags.at(i)->Name)) {
|
||||
wxString name = override->Tags.at(i)->Name;
|
||||
if (insertTags.Index(name) != wxNOT_FOUND || removeTag == name) {
|
||||
shift -= override->Tags.at(i)->ToString().Length();
|
||||
shift -= ((wxString)*override->Tags.at(i)).Length();
|
||||
delete override->Tags.at(i);
|
||||
override->Tags.erase(override->Tags.begin() + i);
|
||||
i--;
|
||||
|
@ -1329,7 +1329,7 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b
|
|||
for (size_t i=0;i<override->Tags.size()-nInserted;i++) {
|
||||
wxString name = override->Tags.at(i)->Name;
|
||||
if (insert.Contains(name) || removeTag == name) {
|
||||
shift -= override->Tags.at(i)->ToString().Length();
|
||||
shift -= ((wxString)*override->Tags.at(i)).Length();
|
||||
override->Tags.erase(override->Tags.begin() + i);
|
||||
i--;
|
||||
}
|
||||
|
|
|
@ -108,3 +108,15 @@ static FORCEINLINE int ClampSignedInteger32(int x,int min,int max) {
|
|||
x += max;
|
||||
return x;
|
||||
}
|
||||
|
||||
struct delete_ptr {
|
||||
template<class T>
|
||||
void operator()(T* ptr) const {
|
||||
delete ptr;
|
||||
}
|
||||
};
|
||||
template<class T>
|
||||
void delete_clear(T& container) {
|
||||
std::for_each(container.begin(), container.end(), delete_ptr());
|
||||
container.clear();
|
||||
}
|
||||
|
|
|
@ -117,6 +117,9 @@ public:
|
|||
template<class T> void Set(T param);
|
||||
void ResetWith(wxString value);
|
||||
template<class T> T Get() const;
|
||||
template<class T> T Get(T def) const {
|
||||
return value ? Get<T>() : def;
|
||||
}
|
||||
|
||||
void operator= (const VariableData ¶m);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue