summaryrefslogtreecommitdiff
path: root/src/text_asset.cc
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2026-03-07 23:48:43 +0100
committerCarl Hetherington <cth@carlh.net>2026-03-07 23:48:43 +0100
commitdaceaad12cc73404f93d5aae0dd896fcb7b9d3b9 (patch)
tree7dc80711804d23bdcc0987d1372f326f03124c2a /src/text_asset.cc
parentf0cada65396759b4be19601d8537119a1bb4fbfa (diff)
wip: ruby2652-ruby
Diffstat (limited to 'src/text_asset.cc')
-rw-r--r--src/text_asset.cc148
1 files changed, 70 insertions, 78 deletions
diff --git a/src/text_asset.cc b/src/text_asset.cc
index 41690d93..05969d82 100644
--- a/src/text_asset.cc
+++ b/src/text_asset.cc
@@ -307,7 +307,6 @@ TextAsset::parse_texts(xmlpp::Element const * node, vector<ParseState>& state, o
float space_before = 0;
- /* Collect <Ruby>s first */
auto get_text_content = [](xmlpp::Element const* element) {
string all_content;
for (auto child: element->get_children()) {
@@ -319,73 +318,14 @@ TextAsset::parse_texts(xmlpp::Element const * node, vector<ParseState>& state, o
return all_content;
};
- vector<Ruby> rubies;
- for (auto child: node->get_children()) {
- auto element = dynamic_cast<xmlpp::Element const*>(child);
- if (element && element->get_name() == "Ruby") {
- optional<string> base;
- optional<string> annotation;
- optional<float> size;
- optional<RubyPosition> position;
- optional<float> offset;
- optional<float> spacing;
- optional<float> aspect_adjust;
- for (auto ruby_child: element->get_children()) {
- if (auto ruby_element = dynamic_cast<xmlpp::Element const*>(ruby_child)) {
- if (ruby_element->get_name() == "Rb") {
- base = get_text_content(ruby_element);
- } else if (ruby_element->get_name() == "Rt") {
- annotation = get_text_content(ruby_element);
- size = optional_number_attribute<float>(ruby_element, "Size");
- if (auto position_string = optional_string_attribute(ruby_element, "Position")) {
- if (*position_string == "before") {
- position = RubyPosition::BEFORE;
- } else if (*position_string == "after") {
- position = RubyPosition::AFTER;
- } else {
- DCP_ASSERT(false);
- }
- }
- offset = optional_number_attribute<float>(ruby_element, "Offset");
- spacing = optional_number_attribute<float>(ruby_element, "Spacing");
- aspect_adjust = optional_number_attribute<float>(ruby_element, "AspectAdjust");
- }
- }
- }
- DCP_ASSERT(base);
- DCP_ASSERT(annotation);
- auto ruby = Ruby{*base, *annotation};
- if (size) {
- ruby.size = *size;
- }
- if (position) {
- ruby.position = *position;
- }
- if (offset) {
- ruby.offset = *offset;
- }
- if (spacing) {
- ruby.spacing = *spacing;
- }
- if (aspect_adjust) {
- ruby.aspect_adjust = *aspect_adjust;
- }
- rubies.push_back(ruby);
- }
- }
-
for (auto i: node->get_children()) {
- /* Handle actual content e.g. text */
- auto const v = dynamic_cast<xmlpp::ContentNode const *>(i);
- if (v) {
- maybe_add_text(v->get_content(), state, space_before, standard, rubies);
+ if (auto const v = dynamic_cast<xmlpp::ContentNode const *>(i)) {
+ maybe_add_text(string{v->get_content()}, state, space_before, standard);
space_before = 0;
}
- /* Handle other nodes */
- auto const e = dynamic_cast<xmlpp::Element const *>(i);
- if (e) {
+ if (auto const e = dynamic_cast<xmlpp::Element const *>(i)) {
if (e->get_name() == "Space") {
if (node->get_name() != "Text") {
throw XMLError ("Space node found outside Text");
@@ -395,8 +335,57 @@ TextAsset::parse_texts(xmlpp::Element const * node, vector<ParseState>& state, o
boost::replace_all(size, "em", "");
}
space_before += raw_convert<float>(size);
- } else if (e->get_name() != "Ruby") {
- parse_texts (e, state, tcr, standard);
+ } else if (e->get_name() == "Ruby") {
+ optional<string> base;
+ optional<string> annotation;
+ optional<float> size;
+ optional<RubyPosition> position;
+ optional<float> offset;
+ optional<float> spacing;
+ optional<float> aspect_adjust;
+ for (auto ruby_child: e->get_children()) {
+ if (auto ruby_element = dynamic_cast<xmlpp::Element const*>(ruby_child)) {
+ if (ruby_element->get_name() == "Rb") {
+ base = get_text_content(ruby_element);
+ } else if (ruby_element->get_name() == "Rt") {
+ annotation = get_text_content(ruby_element);
+ size = optional_number_attribute<float>(ruby_element, "Size");
+ if (auto position_string = optional_string_attribute(ruby_element, "Position")) {
+ if (*position_string == "before") {
+ position = RubyPosition::BEFORE;
+ } else if (*position_string == "after") {
+ position = RubyPosition::AFTER;
+ } else {
+ DCP_ASSERT(false);
+ }
+ }
+ offset = optional_number_attribute<float>(ruby_element, "Offset");
+ spacing = optional_number_attribute<float>(ruby_element, "Spacing");
+ aspect_adjust = optional_number_attribute<float>(ruby_element, "AspectAdjust");
+ }
+ }
+ }
+ DCP_ASSERT(base);
+ DCP_ASSERT(annotation);
+ auto ruby = Ruby{*base, *annotation};
+ if (size) {
+ ruby.size = *size;
+ }
+ if (position) {
+ ruby.position = *position;
+ }
+ if (offset) {
+ ruby.offset = *offset;
+ }
+ if (spacing) {
+ ruby.spacing = *spacing;
+ }
+ if (aspect_adjust) {
+ ruby.aspect_adjust = *aspect_adjust;
+ }
+ maybe_add_text(ruby, state, space_before, standard);
+ } else {
+ parse_texts(e, state, tcr, standard);
}
}
}
@@ -408,11 +397,10 @@ TextAsset::parse_texts(xmlpp::Element const * node, vector<ParseState>& state, o
void
TextAsset::maybe_add_text(
- string text,
+ boost::variant<string, Ruby> text,
vector<ParseState> const & parse_state,
float space_before,
- Standard standard,
- vector<Ruby> const& rubies
+ Standard standard
)
{
auto wanted = [](ParseState const& ps) {
@@ -535,19 +523,20 @@ TextAsset::maybe_add_text(
ps.effect_colour.get_value_or (dcp::Colour (0, 0, 0)),
ps.fade_up_time.get_value_or(Time()),
ps.fade_down_time.get_value_or(Time()),
- space_before,
- rubies
+ space_before
)
);
break;
}
case ParseState::Type::IMAGE:
{
+ DCP_ASSERT(text.which() == 0);
+ auto text_string = boost::get<string>(text);
switch (standard) {
case Standard::INTEROP:
- if (text.size() >= 4) {
+ if (text_string.size() >= 4) {
/* Remove file extension */
- text = text.substr(0, text.size() - 4);
+ text_string = text_string.substr(0, text_string.size() - 4);
}
break;
case Standard::SMPTE:
@@ -556,8 +545,8 @@ TextAsset::maybe_add_text(
* a) it is not (always) used in the field, or
* b) nobody noticed / complained.
*/
- if (text.substr(0, 9) == "urn:uuid:") {
- text = text.substr(9);
+ if (text_string.substr(0, 9) == "urn:uuid:") {
+ text_string = text_string.substr(9);
}
break;
}
@@ -572,7 +561,7 @@ TextAsset::maybe_add_text(
_texts.push_back(
make_shared<TextImage>(
ArrayData(),
- text,
+ text_string,
ps.in.get(),
ps.out.get(),
ps.h_position.get_value_or(0),
@@ -824,8 +813,7 @@ TextAsset::texts_as_xml(xmlpp::Element* xml_root, int time_code_rate, Standard s
is->v_position(),
is->z_position(),
subtitle->find_or_add_variable_z_positions(is->variable_z_positions(), load_variable_z_index),
- is->direction(),
- is->rubies()
+ is->direction()
);
subtitle->children.push_back (text);
@@ -837,7 +825,11 @@ TextAsset::texts_as_xml(xmlpp::Element* xml_root, int time_code_rate, Standard s
last_direction = is->direction ();
}
- text->children.push_back (make_shared<order::String>(text, order::Font (is, standard), is->text(), is->space_before()));
+ if (is->string_text()) {
+ text->children.push_back(make_shared<order::String>(text, order::Font (is, standard), *is->string_text(), is->space_before()));
+ } else if (is->ruby_text()) {
+ text->children.push_back(make_shared<order::Ruby>(text, order::Font(is, standard), *is->ruby_text()));
+ }
}
if (auto ii = dynamic_pointer_cast<TextImage>(i)) {