summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2022-10-20 23:17:40 +0200
committerCarl Hetherington <cth@carlh.net>2022-11-03 09:31:53 +0100
commit5048e3e1d91858c2a4132e616438e1943f820124 (patch)
tree5ef98efb29690e8320d4e9e36266f41e1214e174 /src
parent80fc63959caa039401a4d7e33bc72cd3c6ec2fe3 (diff)
Add Z position to subtitles; existing tests pass.
Diffstat (limited to 'src')
-rw-r--r--src/subtitle.cc7
-rw-r--r--src/subtitle.h10
-rw-r--r--src/subtitle_asset.cc16
-rw-r--r--src/subtitle_asset.h1
-rw-r--r--src/subtitle_asset_internal.cc10
-rw-r--r--src/subtitle_asset_internal.h8
-rw-r--r--src/subtitle_image.cc12
-rw-r--r--src/subtitle_image.h2
-rw-r--r--src/subtitle_string.cc5
-rw-r--r--src/subtitle_string.h3
10 files changed, 62 insertions, 12 deletions
diff --git a/src/subtitle.cc b/src/subtitle.cc
index 15481528..522b0e5f 100644
--- a/src/subtitle.cc
+++ b/src/subtitle.cc
@@ -53,6 +53,7 @@ Subtitle::Subtitle (
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Time fade_up_time,
Time fade_down_time
)
@@ -62,6 +63,7 @@ Subtitle::Subtitle (
, _h_align (h_align)
, _v_position (v_position)
, _v_align (v_align)
+ , _z_position(z_position)
, _fade_up_time (fade_up_time)
, _fade_down_time (fade_down_time)
{
@@ -104,6 +106,11 @@ Subtitle::equals(shared_ptr<const Subtitle> other, EqualityOptions, NoteHandler
same = false;
}
+ if (z_position() != other->z_position()) {
+ note(NoteType::ERROR, "subtitle Z positions differ");
+ same = false;
+ }
+
if (fade_up_time() != other->fade_up_time()) {
note(NoteType::ERROR, "subtitle fade-up times differ");
same = false;
diff --git a/src/subtitle.h b/src/subtitle.h
index 2a8e0322..d42a54b7 100644
--- a/src/subtitle.h
+++ b/src/subtitle.h
@@ -82,6 +82,10 @@ public:
return _v_align;
}
+ float z_position() const {
+ return _z_position;
+ }
+
Time fade_up_time () const {
return _fade_up_time;
}
@@ -109,6 +113,10 @@ public:
_v_position = p;
}
+ void set_z_position(float z) {
+ _z_position = z;
+ }
+
void set_fade_up_time (Time t) {
_fade_up_time = t;
}
@@ -128,6 +136,7 @@ protected:
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Time fade_up_time,
Time fade_down_time
);
@@ -144,6 +153,7 @@ protected:
*/
float _v_position = 0;
VAlign _v_align = VAlign::CENTER;
+ float _z_position = 0;
Time _fade_up_time;
Time _fade_down_time;
};
diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc
index 271199ef..f707c665 100644
--- a/src/subtitle_asset.cc
+++ b/src/subtitle_asset.cc
@@ -203,6 +203,10 @@ SubtitleAsset::position_align (SubtitleAsset::ParseState& ps, xmlpp::Element con
ps.v_align = string_to_valign (va.get ());
}
+ auto zp = optional_number_attribute<float>(node, "Zposition");
+ if (zp) {
+ ps.z_position = zp.get() / 100;
+ }
}
@@ -365,6 +369,9 @@ SubtitleAsset::maybe_add_subtitle (string text, vector<ParseState> const & parse
if (i.v_align) {
ps.v_align = i.v_align.get();
}
+ if (i.z_position) {
+ ps.z_position = i.z_position.get();
+ }
if (i.direction) {
ps.direction = i.direction.get();
}
@@ -409,6 +416,7 @@ SubtitleAsset::maybe_add_subtitle (string text, vector<ParseState> const & parse
ps.h_align.get_value_or(HAlign::CENTER),
ps.v_position.get_value_or(0),
ps.v_align.get_value_or(VAlign::CENTER),
+ ps.z_position.get_value_or(0),
ps.direction.get_value_or (Direction::LTR),
text,
ps.effect.get_value_or (Effect::NONE),
@@ -451,6 +459,7 @@ SubtitleAsset::maybe_add_subtitle (string text, vector<ParseState> const & parse
ps.h_align.get_value_or(HAlign::CENTER),
ps.v_position.get_value_or(0),
ps.v_align.get_value_or(VAlign::CENTER),
+ ps.z_position.get_value_or(0),
ps.fade_up_time.get_value_or(Time()),
ps.fade_down_time.get_value_or(Time())
)
@@ -674,6 +683,7 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* xml_root, int time_code_rate, S
float last_h_position;
VAlign last_v_align;
float last_v_position;
+ float last_z_position;
Direction last_direction;
for (auto i: sorted) {
@@ -701,15 +711,17 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* xml_root, int time_code_rate, S
fabs(last_h_position - is->h_position()) > ALIGN_EPSILON ||
last_v_align != is->v_align() ||
fabs(last_v_position - is->v_position()) > ALIGN_EPSILON ||
+ fabs(last_z_position - is->z_position()) > ALIGN_EPSILON ||
last_direction != is->direction()
) {
- text = make_shared<order::Text>(subtitle, is->h_align(), is->h_position(), is->v_align(), is->v_position(), is->direction());
+ text = make_shared<order::Text>(subtitle, is->h_align(), is->h_position(), is->v_align(), is->v_position(), is->z_position(), is->direction());
subtitle->children.push_back (text);
last_h_align = is->h_align ();
last_h_position = is->h_position ();
last_v_align = is->v_align ();
last_v_position = is->v_position ();
+ last_z_position = is->z_position();
last_direction = is->direction ();
}
@@ -720,7 +732,7 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* xml_root, int time_code_rate, S
if (ii) {
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())
+ 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())
);
}
}
diff --git a/src/subtitle_asset.h b/src/subtitle_asset.h
index 88b5378c..7448ac9a 100644
--- a/src/subtitle_asset.h
+++ b/src/subtitle_asset.h
@@ -152,6 +152,7 @@ protected:
boost::optional<HAlign> h_align;
boost::optional<float> v_position;
boost::optional<VAlign> v_align;
+ boost::optional<float> z_position;
boost::optional<Direction> direction;
boost::optional<Time> in;
boost::optional<Time> out;
diff --git a/src/subtitle_asset_internal.cc b/src/subtitle_asset_internal.cc
index 7a10f472..bb67b45a 100644
--- a/src/subtitle_asset_internal.cc
+++ b/src/subtitle_asset_internal.cc
@@ -165,7 +165,7 @@ 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)
+position_align (xmlpp::Element* e, order::Context& context, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position)
{
if (h_align != HAlign::CENTER) {
if (context.standard == Standard::SMPTE) {
@@ -202,6 +202,10 @@ position_align (xmlpp::Element* e, order::Context& context, HAlign h_align, floa
e->set_attribute ("VPosition", "0");
}
}
+
+ if (fabs(z_position) > ALIGN_EPSILON && context.standard == Standard::SMPTE) {
+ e->set_attribute("Zposition", raw_convert<string>(z_position * 100, 6));
+ }
}
@@ -210,7 +214,7 @@ order::Text::as_xml (xmlpp::Element* parent, Context& context) const
{
auto e = parent->add_child ("Text");
- position_align (e, context, _h_align, _h_position, _v_align, _v_position);
+ position_align(e, context, _h_align, _h_position, _v_align, _v_position, _z_position);
/* Interop only supports "horizontal" or "vertical" for direction, so only write this
for SMPTE.
@@ -260,7 +264,7 @@ order::Image::as_xml (xmlpp::Element* parent, Context& context) const
{
auto e = parent->add_child ("Image");
- position_align (e, context, _h_align, _h_position, _v_align, _v_position);
+ position_align(e, context, _h_align, _h_position, _v_align, _v_position, _z_position);
if (context.standard == Standard::SMPTE) {
e->add_child_text ("urn:uuid:" + _id);
} else {
diff --git a/src/subtitle_asset_internal.h b/src/subtitle_asset_internal.h
index 55880797..7fe142fc 100644
--- a/src/subtitle_asset_internal.h
+++ b/src/subtitle_asset_internal.h
@@ -144,12 +144,13 @@ private:
class Text : public Part
{
public:
- Text (std::shared_ptr<Part> parent, HAlign h_align, float h_position, VAlign v_align, float v_position, Direction direction)
+ Text (std::shared_ptr<Part> parent, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position, Direction direction)
: Part (parent)
, _h_align (h_align)
, _h_position (h_position)
, _v_align (v_align)
, _v_position (v_position)
+ , _z_position(z_position)
, _direction (direction)
{}
@@ -160,6 +161,7 @@ private:
float _h_position;
VAlign _v_align;
float _v_position;
+ float _z_position;
Direction _direction;
};
@@ -188,7 +190,7 @@ private:
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)
+ 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)
: Part (parent)
, _png_data (png_data)
, _id (id)
@@ -196,6 +198,7 @@ public:
, _h_position (h_position)
, _v_align (v_align)
, _v_position (v_position)
+ , _z_position(z_position)
{}
xmlpp::Element* as_xml (xmlpp::Element* parent, Context& context) const override;
@@ -207,6 +210,7 @@ private:
float _h_position;
VAlign _v_align;
float _v_position;
+ float _z_position;
};
diff --git a/src/subtitle_image.cc b/src/subtitle_image.cc
index 5f51f05e..19d7f4eb 100644
--- a/src/subtitle_image.cc
+++ b/src/subtitle_image.cc
@@ -43,8 +43,8 @@
using std::dynamic_pointer_cast;
using std::ostream;
-using std::string;
using std::shared_ptr;
+using std::string;
using namespace dcp;
@@ -56,10 +56,11 @@ SubtitleImage::SubtitleImage (
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Time fade_up_time,
Time fade_down_time
)
- : Subtitle (in, out, h_position, h_align, v_position, v_align, fade_up_time, fade_down_time)
+ : Subtitle(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
, _png_image (png_image)
, _id (make_uuid ())
{
@@ -76,10 +77,11 @@ SubtitleImage::SubtitleImage (
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Time fade_up_time,
Time fade_down_time
)
- : Subtitle (in, out, h_position, h_align, v_position, v_align, fade_up_time, fade_down_time)
+ : Subtitle(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
, _png_image (png_image)
, _id (id)
{
@@ -115,6 +117,7 @@ dcp::operator== (SubtitleImage const & a, SubtitleImage const & b)
a.h_align() == b.h_align() &&
a.v_position() == b.v_position() &&
a.v_align() == b.v_align() &&
+ a.z_position() == b.z_position() &&
a.fade_up_time() == b.fade_up_time() &&
a.fade_down_time() == b.fade_down_time()
);
@@ -170,7 +173,8 @@ dcp::operator<< (ostream& s, SubtitleImage const & sub)
s << "\n[IMAGE] from " << sub.in() << " to " << sub.out() << ";\n"
<< "fade up " << sub.fade_up_time() << ", fade down " << sub.fade_down_time() << ";\n"
<< "v pos " << sub.v_position() << ", valign " << ((int) sub.v_align())
- << ", hpos " << sub.h_position() << ", halign " << ((int) sub.h_align()) << "\n";
+ << ", hpos " << sub.h_position() << ", halign " << ((int) sub.h_align())
+ << ", zpos " << sub.z_position() << "\n";
return s;
}
diff --git a/src/subtitle_image.h b/src/subtitle_image.h
index 9d74d18c..8b1c3521 100644
--- a/src/subtitle_image.h
+++ b/src/subtitle_image.h
@@ -66,6 +66,7 @@ public:
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Time fade_up_time,
Time fade_down_time
);
@@ -79,6 +80,7 @@ public:
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Time fade_up_time,
Time fade_down_time
);
diff --git a/src/subtitle_string.cc b/src/subtitle_string.cc
index 7f7c74a5..91a129da 100644
--- a/src/subtitle_string.cc
+++ b/src/subtitle_string.cc
@@ -67,6 +67,7 @@ SubtitleString::SubtitleString (
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Direction direction,
string text,
Effect effect,
@@ -75,7 +76,7 @@ SubtitleString::SubtitleString (
Time fade_down_time,
float space_before
)
- : Subtitle (in, out, h_position, h_align, v_position, v_align, fade_up_time, fade_down_time)
+ : Subtitle(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
, _font (font)
, _italic (italic)
, _bold (bold)
@@ -122,6 +123,7 @@ dcp::operator== (SubtitleString const & a, SubtitleString const & b)
a.h_align() == b.h_align() &&
a.v_position() == b.v_position() &&
a.v_align() == b.v_align() &&
+ a.z_position() == b.z_position() &&
a.direction() == b.direction() &&
a.text() == b.text() &&
a.effect() == b.effect() &&
@@ -167,6 +169,7 @@ dcp::operator<< (ostream& s, SubtitleString 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())
<< ", effect " << ((int) sub.effect())
<< ", effect colour (" << sub.effect_colour().r << ", " << sub.effect_colour().g << ", " << sub.effect_colour().b << ")"
diff --git a/src/subtitle_string.h b/src/subtitle_string.h
index 0ffa6ec5..98ff960b 100644
--- a/src/subtitle_string.h
+++ b/src/subtitle_string.h
@@ -70,6 +70,8 @@ public:
* @param h_align Horizontal alignment point
* @param v_position Vertical position as a fraction of the screen height (between 0 and 1) from v_align
* @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 direction Direction of text
* @param text The text to display
* @param effect Effect to use
@@ -92,6 +94,7 @@ public:
HAlign h_align,
float v_position,
VAlign v_align,
+ float z_position,
Direction direction,
std::string text,
Effect effect,