mirror of https://github.com/odrling/Aegisub
Add support for writing unformatted level 1 teletext to the EBU STL subtitle format
Originally committed to SVN as r6638.
This commit is contained in:
parent
7335c520c1
commit
2d9213cdfc
|
@ -124,7 +124,6 @@ EbuExportConfigurationDialog::EbuExportConfigurationDialog(wxWindow *owner, EbuE
|
|||
};
|
||||
wxRadioBox *tv_standard_box = new wxRadioBox(this, -1, _("TV standard"), wxDefaultPosition, wxDefaultSize, 6, tv_standards, 0, wxRA_SPECIFY_ROWS);
|
||||
|
||||
wxStaticBox *timecode_control_box = new wxStaticBox(this, -1, _("Time codes"));
|
||||
wxTextCtrl *timecode_offset_entry = new wxTextCtrl(this, -1, "00:00:00:00");
|
||||
wxCheckBox *inclusive_end_times_check = new wxCheckBox(this, -1, _("Out-times are inclusive"));
|
||||
|
||||
|
@ -145,13 +144,20 @@ EbuExportConfigurationDialog::EbuExportConfigurationDialog(wxWindow *owner, EbuE
|
|||
_("Skip lines that are too long")
|
||||
};
|
||||
|
||||
wxStaticBox *text_formatting_box = new wxStaticBox(this, -1, _("Text formatting"));
|
||||
wxSpinCtrl *max_line_length_ctrl = new wxSpinCtrl(this, -1, wxString(), wxDefaultPosition, wxSize(65, -1));
|
||||
wxComboBox *wrap_mode_ctrl = new wxComboBox(this, -1, wrap_modes[0], wxDefaultPosition, wxDefaultSize, 4, wrap_modes, wxCB_DROPDOWN | wxCB_READONLY);
|
||||
wxCheckBox *translate_alignments_check = new wxCheckBox(this, -1, _("Translate alignments"));
|
||||
|
||||
max_line_length_ctrl->SetRange(10, 99);
|
||||
|
||||
wxString display_standards[] = {
|
||||
_("Open subtitles"),
|
||||
_("Level-1 teletext"),
|
||||
_("Level-2 teletext")
|
||||
};
|
||||
|
||||
wxComboBox *display_standard_ctrl = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, 2, display_standards, wxCB_DROPDOWN | wxCB_READONLY);
|
||||
|
||||
wxSizer *max_line_length_labelled = new wxBoxSizer(wxHORIZONTAL);
|
||||
max_line_length_labelled->Add(new wxStaticText(this, -1, _("Max. line length:")), 1, wxALIGN_CENTRE|wxRIGHT, 12);
|
||||
max_line_length_labelled->Add(max_line_length_ctrl, 0, 0, 0);
|
||||
|
@ -160,18 +166,22 @@ EbuExportConfigurationDialog::EbuExportConfigurationDialog(wxWindow *owner, EbuE
|
|||
timecode_offset_labelled->Add(new wxStaticText(this, -1, _("Time code offset:")), 1, wxALIGN_CENTRE|wxRIGHT, 12);
|
||||
timecode_offset_labelled->Add(timecode_offset_entry, 0, 0, 0);
|
||||
|
||||
wxSizer *text_formatting_sizer = new wxStaticBoxSizer(text_formatting_box, wxVERTICAL);
|
||||
wxSizer *text_formatting_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Text formatting"));
|
||||
text_formatting_sizer->Add(max_line_length_labelled, 0, wxEXPAND | (wxALL & ~wxTOP), 6);
|
||||
text_formatting_sizer->Add(wrap_mode_ctrl, 0, wxEXPAND | (wxALL & ~wxTOP), 6);
|
||||
text_formatting_sizer->Add(translate_alignments_check, 0, wxEXPAND | (wxALL & ~wxTOP), 6);
|
||||
|
||||
wxSizer *timecode_control_sizer = new wxStaticBoxSizer(timecode_control_box, wxVERTICAL);
|
||||
wxSizer *timecode_control_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Time codes"));
|
||||
timecode_control_sizer->Add(timecode_offset_labelled, 0, wxEXPAND | (wxALL & ~wxTOP), 6);
|
||||
timecode_control_sizer->Add(inclusive_end_times_check, 0, wxEXPAND | (wxALL & ~wxTOP), 6);
|
||||
|
||||
wxSizer *display_standard_sizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Display standard"));
|
||||
display_standard_sizer->Add(display_standard_ctrl, 0, wxEXPAND | (wxALL & ~wxTOP), 6);
|
||||
|
||||
wxSizer *left_column = new wxBoxSizer(wxVERTICAL);
|
||||
left_column->Add(tv_standard_box, 0, wxEXPAND|wxBOTTOM, 6);
|
||||
left_column->Add(timecode_control_sizer, 0, wxEXPAND, 0);
|
||||
left_column->Add(tv_standard_box, 0, wxEXPAND | wxBOTTOM, 6);
|
||||
left_column->Add(timecode_control_sizer, 0, wxEXPAND | wxBOTTOM, 6);
|
||||
left_column->Add(display_standard_sizer, 0, wxEXPAND, 0);
|
||||
|
||||
wxSizer *right_column = new wxBoxSizer(wxVERTICAL);
|
||||
right_column->Add(text_encoding_box, 0, wxEXPAND|wxBOTTOM, 6);
|
||||
|
@ -203,6 +213,7 @@ EbuExportConfigurationDialog::EbuExportConfigurationDialog(wxWindow *owner, EbuE
|
|||
wrap_mode_ctrl->SetValidator(wxGenericValidator((int*)&s.line_wrapping_mode));
|
||||
inclusive_end_times_check->SetValidator(wxGenericValidator(&s.inclusive_end_times));
|
||||
timecode_offset_entry->SetValidator(TimecodeValidator(&s.timecode_offset));
|
||||
display_standard_ctrl->SetValidator(wxGenericValidator((int*)&s.display_standard));
|
||||
}
|
||||
|
||||
agi::vfr::Framerate EbuExportSettings::GetFramerate() const {
|
||||
|
@ -237,6 +248,7 @@ EbuExportSettings::EbuExportSettings(std::string const& prefix)
|
|||
, line_wrapping_mode((LineWrappingMode)OPT_GET(prefix + "/Line Wrapping Mode")->GetInt())
|
||||
, translate_alignments(OPT_GET(prefix + "/Translate Alignments")->GetBool())
|
||||
, inclusive_end_times(OPT_GET(prefix + "/Inclusive End Times")->GetBool())
|
||||
, display_standard((DisplayStandard)OPT_GET(prefix + "/Display Standard")->GetInt())
|
||||
{
|
||||
timecode_offset.h = OPT_GET(prefix + "/Timecode Offset/H")->GetInt();
|
||||
timecode_offset.m = OPT_GET(prefix + "/Timecode Offset/M")->GetInt();
|
||||
|
@ -251,6 +263,7 @@ void EbuExportSettings::Save() const {
|
|||
OPT_SET(prefix + "/Line Wrapping Mode")->SetInt(line_wrapping_mode);
|
||||
OPT_SET(prefix + "/Translate Alignments")->SetBool(translate_alignments);
|
||||
OPT_SET(prefix + "/Inclusive End Times")->SetBool(inclusive_end_times);
|
||||
OPT_SET(prefix + "/Display Standard")->SetInt(display_standard);
|
||||
OPT_SET(prefix + "/Timecode Offset/H")->SetInt(timecode_offset.h);
|
||||
OPT_SET(prefix + "/Timecode Offset/M")->SetInt(timecode_offset.m);
|
||||
OPT_SET(prefix + "/Timecode Offset/S")->SetInt(timecode_offset.s);
|
||||
|
|
|
@ -67,6 +67,13 @@ public:
|
|||
IgnoreOverLength = 3 ///< Skip overly-long lines
|
||||
};
|
||||
|
||||
/// Types of subtitles/captions that can be stored in STL files
|
||||
enum DisplayStandard {
|
||||
DSC_Open = 0, ///< Open subtitles
|
||||
DSC_Level1 = 1, ///< Level-1 teletext closed captions
|
||||
DSC_Level2 = 2 ///< Level-2 teletext closed captions
|
||||
};
|
||||
|
||||
/// Which TV standard (frame rate + timecode encoding) to use
|
||||
TvStandard tv_standard;
|
||||
|
||||
|
@ -88,6 +95,9 @@ public:
|
|||
/// Are end timecodes inclusive or exclusive?
|
||||
bool inclusive_end_times;
|
||||
|
||||
/// Save as subtitles, or as closed captions?
|
||||
DisplayStandard display_standard;
|
||||
|
||||
/// Get the frame rate for the current TV Standard
|
||||
agi::vfr::Framerate GetFramerate() const;
|
||||
|
||||
|
|
|
@ -387,6 +387,7 @@
|
|||
|
||||
"Subtitle Format" : {
|
||||
"EBU STL" : {
|
||||
"Display Standard" : 0,
|
||||
"Inclusive End Times" : true,
|
||||
"Line Wrapping Mode" : 1,
|
||||
"Max Line Length" : 42,
|
||||
|
|
|
@ -455,7 +455,7 @@ namespace
|
|||
return reinterpret_cast<const char *>(str.wx_str());
|
||||
}
|
||||
|
||||
std::string convert_subtitle_line(std::vector<EbuSubtitle>::const_iterator sub, agi::charset::IconvWrapper *encoder)
|
||||
std::string convert_subtitle_line(std::vector<EbuSubtitle>::const_iterator sub, agi::charset::IconvWrapper *encoder, bool enable_formatting)
|
||||
{
|
||||
std::string fullstring;
|
||||
for (std::vector<EbuTextRow>::const_iterator row = sub->text_rows.begin(); row != sub->text_rows.end(); ++row)
|
||||
|
@ -464,14 +464,17 @@ namespace
|
|||
bool underline = false, italic = false;
|
||||
for (std::vector<EbuFormattedText>::const_iterator block = row->begin(); block != row->end(); ++block)
|
||||
{
|
||||
// insert codes for changed formatting
|
||||
if (underline != block->underline)
|
||||
fullstring += EBU_FORMAT_UNDERLINE[block->underline];
|
||||
if (italic != block->italic)
|
||||
fullstring += EBU_FORMAT_ITALIC[block->italic];
|
||||
if (enable_formatting)
|
||||
{
|
||||
// insert codes for changed formatting
|
||||
if (underline != block->underline)
|
||||
fullstring += EBU_FORMAT_UNDERLINE[block->underline];
|
||||
if (italic != block->italic)
|
||||
fullstring += EBU_FORMAT_ITALIC[block->italic];
|
||||
|
||||
underline = block->underline;
|
||||
italic = block->italic;
|
||||
underline = block->underline;
|
||||
italic = block->italic;
|
||||
}
|
||||
|
||||
// convert text to specified encoding
|
||||
fullstring += encoder->Convert(std::string(wx_str(block->text), buffer_size(block->text)));
|
||||
|
@ -500,13 +503,22 @@ namespace
|
|||
agi::scoped_ptr<agi::charset::IconvWrapper> encoder(export_settings.GetTextEncoder());
|
||||
agi::vfr::Framerate fps = export_settings.GetFramerate();
|
||||
|
||||
// Teletext captions are 1-23; Open subtitles are 0-99
|
||||
uint8_t min_row = 0;
|
||||
uint8_t max_row = 100;
|
||||
if (export_settings.display_standard != EbuExportSettings::DSC_Open) {
|
||||
min_row = 1;
|
||||
max_row = 24;
|
||||
}
|
||||
|
||||
uint16_t subtitle_number = 0;
|
||||
|
||||
std::vector<BlockTTI> tti;
|
||||
tti.reserve(subs_list.size());
|
||||
for (std::vector<EbuSubtitle>::const_iterator sub = subs_list.begin(); sub != subs_list.end(); ++sub)
|
||||
{
|
||||
std::string fullstring = convert_subtitle_line(sub, encoder.get());
|
||||
std::string fullstring = convert_subtitle_line(sub, encoder.get(),
|
||||
export_settings.display_standard == EbuExportSettings::DSC_Open);
|
||||
|
||||
// construct a base block that can be copied and filled
|
||||
BlockTTI base;
|
||||
|
@ -523,17 +535,17 @@ namespace
|
|||
{
|
||||
// vertical position
|
||||
if (sub->vertical_position == EbuSubtitle::PositionTop)
|
||||
base.vp = 0;
|
||||
base.vp = min_row;
|
||||
else if (sub->vertical_position == EbuSubtitle::PositionMiddle)
|
||||
base.vp = std::min<size_t>(0, 50 - (10 * sub->text_rows.size()));
|
||||
base.vp = std::min<uint8_t>(min_row, max_row / 2 - (max_row / 5 * sub->text_rows.size()));
|
||||
else //if (sub->vertical_position == EbuSubtitle::PositionBottom)
|
||||
base.vp = 99;
|
||||
base.vp = max_row - 1;
|
||||
|
||||
base.jc = sub->justification_code;
|
||||
}
|
||||
else
|
||||
{
|
||||
base.vp = 99;
|
||||
base.vp = max_row - 1;
|
||||
base.jc = EbuSubtitle::JustifyCentre;
|
||||
}
|
||||
|
||||
|
@ -591,7 +603,7 @@ namespace
|
|||
memcpy(gsi.dfc, "STL25.01", 8);
|
||||
break;
|
||||
}
|
||||
gsi.dsc = '0'; // open subtitling
|
||||
gsi.dsc = '0' + (int)export_settings.display_standard;
|
||||
gsi.cct[0] = '0';
|
||||
gsi.cct[1] = '0' + (int)export_settings.text_encoding;
|
||||
if (export_settings.text_encoding == EbuExportSettings::utf8)
|
||||
|
|
Loading…
Reference in New Issue