summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/text.cc17
-rw-r--r--src/text.h13
-rw-r--r--src/text_asset.cc52
-rw-r--r--src/text_asset.h5
-rw-r--r--src/text_asset_internal.cc46
-rw-r--r--src/text_asset_internal.h36
-rw-r--r--src/text_image.cc8
-rw-r--r--src/text_image.h2
-rw-r--r--src/text_string.cc8
-rw-r--r--src/text_string.h2
10 files changed, 178 insertions, 11 deletions
diff --git a/src/text.cc b/src/text.cc
index 158af38c..8f72b953 100644
--- a/src/text.cc
+++ b/src/text.cc
@@ -44,6 +44,9 @@
using std::shared_ptr;
+using std::string;
+using std::vector;
+using boost::optional;
using namespace dcp;
@@ -56,6 +59,7 @@ Text::Text(
float v_position,
VAlign v_align,
float z_position,
+ vector<VariableZPosition> variable_z_positions,
Time fade_up_time,
Time fade_down_time
)
@@ -66,6 +70,7 @@ Text::Text(
, _v_position (v_position)
, _v_align (v_align)
, _z_position(z_position)
+ , _variable_z_positions(variable_z_positions)
, _fade_up_time (fade_up_time)
, _fade_down_time (fade_down_time)
{
@@ -117,6 +122,11 @@ Text::equals(shared_ptr<const Text> other, EqualityOptions const& options, NoteH
same = false;
}
+ if (variable_z_positions() != other->variable_z_positions()) {
+ note(NoteType::ERROR, "text variable Z positions differ");
+ same = false;
+ }
+
if (fade_up_time() != other->fade_up_time()) {
note(NoteType::ERROR, "text fade-up times differ");
same = false;
@@ -129,3 +139,10 @@ Text::equals(shared_ptr<const Text> other, EqualityOptions const& options, NoteH
return same;
}
+
+
+bool dcp::operator==(Text::VariableZPosition a, Text::VariableZPosition b)
+{
+ return a.position == b.position && a.duration == b.duration;
+}
+
diff --git a/src/text.h b/src/text.h
index 70dfa3a6..f3b6ecea 100644
--- a/src/text.h
+++ b/src/text.h
@@ -97,6 +97,10 @@ public:
int64_t duration;
};
+ std::vector<VariableZPosition> variable_z_positions() const {
+ return _variable_z_positions;
+ }
+
Time fade_up_time () const {
return _fade_up_time;
}
@@ -128,6 +132,10 @@ public:
_z_position = z;
}
+ void set_variable_z_positions(std::vector<VariableZPosition> z) {
+ _variable_z_positions = std::move(z);
+ }
+
void set_fade_up_time (Time t) {
_fade_up_time = t;
}
@@ -148,6 +156,7 @@ protected:
float v_position,
VAlign v_align,
float z_position,
+ std::vector<VariableZPosition> variable_z,
Time fade_up_time,
Time fade_down_time
);
@@ -165,11 +174,15 @@ protected:
float _v_position = 0;
VAlign _v_align = VAlign::CENTER;
float _z_position = 0;
+ std::vector<VariableZPosition> _variable_z_positions;
Time _fade_up_time;
Time _fade_down_time;
};
+bool operator==(Text::VariableZPosition a, Text::VariableZPosition b);
+
+
}
diff --git a/src/text_asset.cc b/src/text_asset.cc
index c3341452..41690d93 100644
--- a/src/text_asset.cc
+++ b/src/text_asset.cc
@@ -206,6 +206,10 @@ TextAsset::position_align(TextAsset::ParseState& ps, xmlpp::Element const * node
if (auto zp = optional_number_attribute<float>(node, "Zposition")) {
ps.z_position = zp.get() / 100;
}
+
+ if (auto variable_z = optional_string_attribute(node, "VariableZ")) {
+ ps.variable_z = *variable_z;
+ }
}
@@ -248,6 +252,14 @@ TextAsset::subtitle_node_state(xmlpp::Element const * node, optional<int> tcr) c
ps.out = Time (string_attribute(node, "TimeOut"), tcr);
ps.fade_up_time = fade_time (node, "FadeUpTime", tcr);
ps.fade_down_time = fade_time (node, "FadeDownTime", tcr);
+
+ for (auto child: node->get_children()) {
+ auto element = dynamic_cast<xmlpp::Element const*>(child);
+ if (element && element->get_name() == "LoadVariableZ") {
+ ps.load_variable_z.push_back(LoadVariableZ(element));
+ }
+ }
+
return ps;
}
@@ -287,6 +299,8 @@ TextAsset::parse_texts(xmlpp::Element const * node, vector<ParseState>& state, o
state.push_back (ParseState ());
} else if (node->get_name() == "Image") {
state.push_back (image_node_state (node));
+ } else if (node->get_name() == "LoadVariableZ") {
+ return;
} else {
throw XMLError ("unexpected node " + node->get_name());
}
@@ -453,6 +467,9 @@ TextAsset::maybe_add_text(
if (i.z_position) {
ps.z_position = i.z_position.get();
}
+ if (i.variable_z) {
+ ps.variable_z = i.variable_z.get();
+ }
if (i.direction) {
ps.direction = i.direction.get();
}
@@ -471,6 +488,13 @@ TextAsset::maybe_add_text(
if (i.type) {
ps.type = i.type.get();
}
+ for (auto j: i.load_variable_z) {
+ /* j is a LoadVariableZ from this "sub" ParseState. See if we should add it to the end result */
+ auto const k = std::find_if(ps.load_variable_z.begin(), ps.load_variable_z.end(), [j](LoadVariableZ const& z) { return j.id() == z.id(); });
+ if (k == ps.load_variable_z.end()) {
+ ps.load_variable_z.push_back(j);
+ }
+ }
}
if (!ps.in || !ps.out) {
@@ -482,6 +506,12 @@ TextAsset::maybe_add_text(
switch (ps.type.get()) {
case ParseState::Type::TEXT:
+ {
+ vector<Text::VariableZPosition> variable_z;
+ auto iter = std::find_if(ps.load_variable_z.begin(), ps.load_variable_z.end(), [&ps](LoadVariableZ const& z) { return z.id() == ps.variable_z; });
+ if (iter != ps.load_variable_z.end()) {
+ variable_z = iter->positions();
+ }
_texts.push_back (
make_shared<TextString>(
ps.font_id,
@@ -498,6 +528,7 @@ TextAsset::maybe_add_text(
ps.v_position.get_value_or(0),
ps.v_align.get_value_or(VAlign::CENTER),
ps.z_position.get_value_or(0),
+ variable_z,
ps.direction.get_value_or (Direction::LTR),
text,
ps.effect.get_value_or (Effect::NONE),
@@ -509,6 +540,7 @@ TextAsset::maybe_add_text(
)
);
break;
+ }
case ParseState::Type::IMAGE:
{
switch (standard) {
@@ -530,6 +562,12 @@ TextAsset::maybe_add_text(
break;
}
+ vector<Text::VariableZPosition> variable_z;
+ auto iter = std::find_if(ps.load_variable_z.begin(), ps.load_variable_z.end(), [&ps](LoadVariableZ const& z) { return ps.variable_z && z.id() == *ps.variable_z; });
+ if (iter != ps.load_variable_z.end()) {
+ variable_z = iter->positions();
+ }
+
/* Add a text with no image data and we'll fill that in later */
_texts.push_back(
make_shared<TextImage>(
@@ -542,6 +580,7 @@ TextAsset::maybe_add_text(
ps.v_position.get_value_or(0),
ps.v_align.get_value_or(VAlign::CENTER),
ps.z_position.get_value_or(0),
+ variable_z,
ps.fade_up_time.get_value_or(Time()),
ps.fade_down_time.get_value_or(Time())
)
@@ -747,6 +786,7 @@ TextAsset::texts_as_xml(xmlpp::Element* xml_root, int time_code_rate, Standard s
float last_v_position;
float last_z_position;
Direction last_direction;
+ int load_variable_z_index = 1;
for (auto i: sorted) {
if (!subtitle ||
@@ -783,6 +823,7 @@ TextAsset::texts_as_xml(xmlpp::Element* xml_root, int time_code_rate, Standard s
is->v_align(),
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()
);
@@ -802,7 +843,16 @@ TextAsset::texts_as_xml(xmlpp::Element* xml_root, int time_code_rate, Standard s
if (auto ii = dynamic_pointer_cast<TextImage>(i)) {
text.reset ();
subtitle->children.push_back (
- make_shared<order::Image>(subtitle, ii->id(), ii->png_image(), ii->h_align(), ii->h_position(), ii->v_align(), ii->v_position(), ii->z_position())
+ make_shared<order::Image>(
+ subtitle, ii->id(),
+ ii->png_image(),
+ ii->h_align(),
+ ii->h_position(),
+ ii->v_align(),
+ ii->v_position(),
+ ii->z_position(),
+ subtitle->find_or_add_variable_z_positions(ii->variable_z_positions(), load_variable_z_index)
+ )
);
}
}
diff --git a/src/text_asset.h b/src/text_asset.h
index 4d739027..113896f8 100644
--- a/src/text_asset.h
+++ b/src/text_asset.h
@@ -44,6 +44,7 @@
#include "array_data.h"
#include "asset.h"
#include "dcp_time.h"
+#include "load_variable_z.h"
#include "subtitle_standard.h"
#include "text_string.h"
#include <libcxml/cxml.h>
@@ -156,6 +157,7 @@ protected:
boost::optional<float> v_position;
boost::optional<VAlign> v_align;
boost::optional<float> z_position;
+ boost::optional<std::string> variable_z;
boost::optional<Direction> direction;
boost::optional<Time> in;
boost::optional<Time> out;
@@ -167,6 +169,8 @@ protected:
};
boost::optional<Type> type;
float space_before = 0;
+
+ std::vector<LoadVariableZ> load_variable_z;
};
void parse_texts(xmlpp::Element const * node, std::vector<ParseState>& state, boost::optional<int> tcr, Standard standard);
@@ -181,6 +185,7 @@ protected:
/** All our texts, in no particular order */
std::vector<std::shared_ptr<Text>> _texts;
+ std::vector<LoadVariableZ> _load_variable_z;
class Font
{
diff --git a/src/text_asset_internal.cc b/src/text_asset_internal.cc
index 549bbec9..4ae5dbfe 100644
--- a/src/text_asset_internal.cc
+++ b/src/text_asset_internal.cc
@@ -44,9 +44,12 @@
#include <cmath>
+using std::dynamic_pointer_cast;
using std::string;
using std::map;
using std::shared_ptr;
+using std::vector;
+using boost::optional;
using namespace dcp;
@@ -166,7 +169,16 @@ order::Part::write_xml (xmlpp::Element* parent, order::Context& context) const
static void
-position_align (xmlpp::Element* e, order::Context& context, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position)
+position_align(
+ xmlpp::Element* e,
+ order::Context& context,
+ HAlign h_align,
+ float h_position,
+ VAlign v_align,
+ float v_position,
+ float z_position,
+ optional<string> variable_z
+ )
{
if (h_align != HAlign::CENTER) {
if (context.standard == Standard::SMPTE) {
@@ -207,6 +219,10 @@ position_align (xmlpp::Element* e, order::Context& context, HAlign h_align, floa
if (fabs(z_position) > ALIGN_EPSILON && context.standard == Standard::SMPTE) {
e->set_attribute("Zposition", fmt::format("{:.6}", z_position * 100));
}
+
+ if (variable_z) {
+ e->set_attribute("VariableZ", *variable_z);
+ }
}
@@ -215,7 +231,7 @@ order::Text::as_xml (xmlpp::Element* parent, Context& context) const
{
auto e = cxml::add_child(parent, "Text");
- position_align(e, context, _h_align, _h_position, _v_align, _v_position, _z_position);
+ position_align(e, context, _h_align, _h_position, _v_align, _v_position, _z_position, _variable_z);
/* Interop only supports "horizontal" or "vertical" for direction, so only write this
for SMPTE.
@@ -240,6 +256,24 @@ order::Text::as_xml (xmlpp::Element* parent, Context& context) const
}
+optional<string>
+order::Subtitle::find_or_add_variable_z_positions(vector<dcp::Text::VariableZPosition> const& positions, int& load_variable_z_index)
+{
+ if (positions.empty()) {
+ return {};
+ }
+
+ auto iter = std::find_if(_load_variable_z.begin(), _load_variable_z.end(), [positions](LoadVariableZ const& load) { return positions == load.positions(); });
+ if (iter == _load_variable_z.end()) {
+ auto const id = fmt::format("Zvector{}", load_variable_z_index++);
+ _load_variable_z.push_back(LoadVariableZ(id, positions));
+ return id;
+ }
+
+ return iter->id();
+}
+
+
xmlpp::Element*
order::Subtitle::as_xml (xmlpp::Element* parent, Context& context) const
{
@@ -254,6 +288,11 @@ order::Subtitle::as_xml (xmlpp::Element* parent, Context& context) const
e->set_attribute("FadeUpTime", fmt::to_string(_fade_up.as_editable_units_ceil(context.time_code_rate)));
e->set_attribute("FadeDownTime", fmt::to_string(_fade_down.as_editable_units_ceil(context.time_code_rate)));
}
+
+ for (auto const& vz: _load_variable_z) {
+ vz.as_xml(cxml::add_child(e, "LoadVariableZ"));
+ }
+
return e;
}
@@ -277,7 +316,7 @@ order::Image::as_xml (xmlpp::Element* parent, Context& context) const
{
auto e = cxml::add_child(parent, "Image");
- position_align(e, context, _h_align, _h_position, _v_align, _v_position, _z_position);
+ position_align(e, context, _h_align, _h_position, _v_align, _v_position, _z_position, _variable_z);
if (context.standard == Standard::SMPTE) {
e->add_child_text ("urn:uuid:" + _id);
} else {
@@ -286,3 +325,4 @@ order::Image::as_xml (xmlpp::Element* parent, Context& context) const
return e;
}
+
diff --git a/src/text_asset_internal.h b/src/text_asset_internal.h
index ddbc8833..2dfccce9 100644
--- a/src/text_asset_internal.h
+++ b/src/text_asset_internal.h
@@ -44,6 +44,7 @@
#include "array_data.h"
#include "dcp_time.h"
#include "h_align.h"
+#include "load_variable_z.h"
#include "raw_convert.h"
#include "v_align.h"
#include "warnings.h"
@@ -146,25 +147,41 @@ private:
class Text : public Part
{
public:
- Text(std::shared_ptr<Part> parent, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position, Direction direction, std::vector<Ruby> rubies)
+ Text(
+ std::shared_ptr<Part> parent,
+ HAlign h_align,
+ float h_position,
+ VAlign v_align,
+ float v_position,
+ float z_position,
+ boost::optional<std::string> variable_z,
+ Direction direction,
+ std::vector<Ruby> rubies
+ )
: Part (parent)
, _h_align (h_align)
, _h_position (h_position)
, _v_align (v_align)
, _v_position (v_position)
, _z_position(z_position)
+ , _variable_z(variable_z)
, _direction (direction)
, _rubies(rubies)
{}
xmlpp::Element* as_xml (xmlpp::Element* parent, Context& context) const override;
+ boost::optional<std::string> variable_z() {
+ return _variable_z;
+ }
+
private:
HAlign _h_align;
float _h_position;
VAlign _v_align;
float _v_position;
float _z_position;
+ boost::optional<std::string> _variable_z;
Direction _direction;
std::vector<Ruby> _rubies;
};
@@ -181,6 +198,8 @@ public:
, _fade_down (fade_down)
{}
+ boost::optional<std::string> find_or_add_variable_z_positions(std::vector<dcp::Text::VariableZPosition> const& positions, int& load_variable_z_index);
+
xmlpp::Element* as_xml (xmlpp::Element* parent, Context& context) const override;
private:
@@ -188,13 +207,24 @@ private:
Time _out;
Time _fade_up;
Time _fade_down;
+ std::vector<LoadVariableZ> _load_variable_z;
};
class Image : public Part
{
public:
- Image (std::shared_ptr<Part> parent, std::string id, ArrayData png_data, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position)
+ Image(
+ std::shared_ptr<Part> parent,
+ std::string id,
+ ArrayData png_data,
+ HAlign h_align,
+ float h_position,
+ VAlign v_align,
+ float v_position,
+ float z_position,
+ boost::optional<std::string> variable_z
+ )
: Part (parent)
, _png_data (png_data)
, _id (id)
@@ -203,6 +233,7 @@ public:
, _v_align (v_align)
, _v_position (v_position)
, _z_position(z_position)
+ , _variable_z(variable_z)
{}
xmlpp::Element* as_xml (xmlpp::Element* parent, Context& context) const override;
@@ -215,6 +246,7 @@ private:
VAlign _v_align;
float _v_position;
float _z_position;
+ boost::optional<std::string> _variable_z;
};
diff --git a/src/text_image.cc b/src/text_image.cc
index 7a6c4222..119a6301 100644
--- a/src/text_image.cc
+++ b/src/text_image.cc
@@ -47,6 +47,8 @@ using std::dynamic_pointer_cast;
using std::ostream;
using std::shared_ptr;
using std::string;
+using std::vector;
+using boost::optional;
using namespace dcp;
@@ -59,10 +61,11 @@ TextImage::TextImage(
float v_position,
VAlign v_align,
float z_position,
+ vector<VariableZPosition> variable_z_positions,
Time fade_up_time,
Time fade_down_time
)
- : Text(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
+ : Text(in, out, h_position, h_align, v_position, v_align, z_position, variable_z_positions, fade_up_time, fade_down_time)
, _png_image (png_image)
, _id (make_uuid ())
{
@@ -80,10 +83,11 @@ TextImage::TextImage(
float v_position,
VAlign v_align,
float z_position,
+ vector<VariableZPosition> variable_z_positions,
Time fade_up_time,
Time fade_down_time
)
- : Text(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
+ : Text(in, out, h_position, h_align, v_position, v_align, z_position, variable_z_positions, fade_up_time, fade_down_time)
, _png_image (png_image)
, _id (id)
{
diff --git a/src/text_image.h b/src/text_image.h
index 1f1e464e..5b78f380 100644
--- a/src/text_image.h
+++ b/src/text_image.h
@@ -66,6 +66,7 @@ public:
float v_position,
VAlign v_align,
float z_position,
+ std::vector<VariableZPosition> variable_z_positions,
Time fade_up_time,
Time fade_down_time
);
@@ -80,6 +81,7 @@ public:
float v_position,
VAlign v_align,
float z_position,
+ std::vector<VariableZPosition> variable_z_positions,
Time fade_up_time,
Time fade_down_time
);
diff --git a/src/text_string.cc b/src/text_string.cc
index 32f9e4ed..12e86fce 100644
--- a/src/text_string.cc
+++ b/src/text_string.cc
@@ -69,6 +69,7 @@ TextString::TextString(
float v_position,
VAlign v_align,
float z_position,
+ vector<VariableZPosition> variable_z_positions,
Direction direction,
string text,
Effect effect,
@@ -78,7 +79,7 @@ TextString::TextString(
float space_before,
vector<Ruby> rubies
)
- : Text(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
+ : Text(in, out, h_position, h_align, v_position, v_align, z_position, variable_z_positions, fade_up_time, fade_down_time)
, _font (font)
, _italic (italic)
, _bold (bold)
@@ -127,6 +128,7 @@ dcp::operator==(TextString const & a, TextString const & b)
a.v_position() == b.v_position() &&
a.v_align() == b.v_align() &&
a.z_position() == b.z_position() &&
+ a.variable_z_positions() == b.variable_z_positions() &&
a.direction() == b.direction() &&
a.text() == b.text() &&
a.effect() == b.effect() &&
@@ -173,8 +175,8 @@ dcp::operator<<(ostream& s, TextString const & sub)
<< ", colour (" << sub.colour().r << ", " << sub.colour().g << ", " << sub.colour().b << ")"
<< ", vpos " << sub.v_position() << ", valign " << ((int) sub.v_align())
<< ", hpos " << sub.h_position() << ", halign " << ((int) sub.h_align())
- << ", zpos " << sub.z_position()
- << ", direction " << ((int) sub.direction())
+ << ", zpos " << sub.z_position();
+ s << ", direction " << ((int) sub.direction())
<< ", effect " << ((int) sub.effect())
<< ", effect colour (" << sub.effect_colour().r << ", " << sub.effect_colour().g << ", " << sub.effect_colour().b << ")"
<< ", space before " << sub.space_before();
diff --git a/src/text_string.h b/src/text_string.h
index f532bafe..78788786 100644
--- a/src/text_string.h
+++ b/src/text_string.h
@@ -72,6 +72,7 @@ public:
* @param v_align Vertical alignment point
* @param z_position Z position as a proportion of the primary picture width between -1 and +1;
* +ve moves the image away from the viewer, -ve moves it toward the viewer, 0 is in the plane of the screen.
+ * @param variable_z_positions List of variable Z positions for this text (or empty).
* @param direction Direction of text
* @param text The text to display
* @param effect Effect to use
@@ -95,6 +96,7 @@ public:
float v_position,
VAlign v_align,
float z_position,
+ std::vector<VariableZPosition> variable_z_positions,
Direction direction,
std::string text,
Effect effect,