summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2022-07-09 20:22:38 +0200
committerCarl Hetherington <cth@carlh.net>2022-07-11 12:22:11 +0200
commit8b9888ed8247109dc3c09492302e865fa4731460 (patch)
tree1ff1c09074decfc44a1bff77d050f908d6542dda /src
parent5a5f6d3ac42668017141469fd0e5cd14e3bebe88 (diff)
Fix font handling for DCP subtitles.
Diffstat (limited to 'src')
-rw-r--r--src/lib/check_content_job.cc17
-rw-r--r--src/lib/content.h1
-rw-r--r--src/lib/dcp_content.cc39
-rw-r--r--src/lib/dcp_content.h8
-rw-r--r--src/lib/dcp_decoder.cc4
-rw-r--r--src/lib/dcp_examiner.cc9
-rw-r--r--src/lib/dcp_examiner.h6
-rw-r--r--src/lib/dcp_subtitle_content.cc10
-rw-r--r--src/lib/font.h5
-rw-r--r--src/lib/string_text_file_content.cc5
10 files changed, 93 insertions, 11 deletions
diff --git a/src/lib/check_content_job.cc b/src/lib/check_content_job.cc
index 2b6e25da8..b74b71cc0 100644
--- a/src/lib/check_content_job.cc
+++ b/src/lib/check_content_job.cc
@@ -21,6 +21,7 @@
#include "check_content_job.h"
#include "content.h"
+#include "dcp_content.h"
#include "examine_content_job.h"
#include "film.h"
#include "job_manager.h"
@@ -69,21 +70,23 @@ CheckContentJob::run ()
std::vector<shared_ptr<Content>> changed;
std::copy_if (content.begin(), content.end(), std::back_inserter(changed), [](shared_ptr<Content> c) { return c->changed(); });
- if (!changed.empty()) {
- for (auto i: changed) {
- JobManager::instance()->add(make_shared<ExamineContentJob>(_film, i));
- }
- set_message (_("Some files have been changed since they were added to the project.\n\nThese files will now be re-examined, so you may need to check their settings."));
- }
-
if (_film->last_written_by_earlier_than(2, 16, 14)) {
for (auto c: content) {
if (auto stf = dynamic_pointer_cast<StringTextFileContent>(c)) {
stf->check_font_ids();
+ } else if (auto dcp = dynamic_pointer_cast<DCPContent>(c)) {
+ dcp->check_font_ids();
}
}
}
+ if (!changed.empty()) {
+ for (auto i: changed) {
+ JobManager::instance()->add(make_shared<ExamineContentJob>(_film, i));
+ }
+ set_message (_("Some files have been changed since they were added to the project.\n\nThese files will now be re-examined, so you may need to check their settings."));
+ }
+
set_progress (1);
set_state (FINISHED_OK);
}
diff --git a/src/lib/content.h b/src/lib/content.h
index 7c02ee0e3..d0faeb9d4 100644
--- a/src/lib/content.h
+++ b/src/lib/content.h
@@ -226,6 +226,7 @@ private:
friend struct best_dcp_frame_rate_test_single;
friend struct best_dcp_frame_rate_test_double;
friend struct audio_sampling_rate_test;
+ friend struct subtitle_font_id_change_test2;
template<class, class> friend class ChangeSignaller;
void signal_change (ChangeType, int);
diff --git a/src/lib/dcp_content.cc b/src/lib/dcp_content.cc
index f8639cef9..2e89adff0 100644
--- a/src/lib/dcp_content.cc
+++ b/src/lib/dcp_content.cc
@@ -268,6 +268,7 @@ DCPContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
for (int i = 0; i < examiner->text_count(TextType::OPEN_SUBTITLE); ++i) {
auto c = make_shared<TextContent>(this, TextType::OPEN_SUBTITLE, TextType::OPEN_SUBTITLE);
c->set_language (examiner->open_subtitle_language());
+ add_fonts_from_examiner(c, examiner->fonts());
new_text.push_back (c);
}
@@ -820,3 +821,41 @@ DCPContent::resolution () const
return Resolution::TWO_K;
}
+
+void
+add_fonts_from_examiner(shared_ptr<TextContent> text, vector<vector<shared_ptr<Font>>> const & all_fonts)
+{
+ int reel_number = 0;
+ for (auto reel_fonts: all_fonts) {
+ for (auto font: reel_fonts) {
+ /* Each reel could have its own font with the same ID, so we disambiguate them here
+ * by prepending the reel number. We do the same disambiguation when emitting the
+ * subtitles in the DCP decoder.
+ */
+ font->set_id(id_for_font_in_reel(font->id(), reel_number));
+ text->add_font(font);
+ }
+ ++reel_number;
+ }
+
+}
+
+
+string
+id_for_font_in_reel(string id, int reel)
+{
+ return String::compose("%1_%2", reel, id);
+}
+
+
+void
+DCPContent::check_font_ids()
+{
+ if (text.empty()) {
+ return;
+ }
+
+ DCPExaminer examiner(shared_from_this(), true);
+ add_fonts_from_examiner(text.front(), examiner.fonts());
+}
+
diff --git a/src/lib/dcp_content.h b/src/lib/dcp_content.h
index 55773b944..1b73e8fc7 100644
--- a/src/lib/dcp_content.h
+++ b/src/lib/dcp_content.h
@@ -29,6 +29,7 @@
#include "content.h"
+#include "font.h"
#include <libcxml/cxml.h>
#include <dcp/encrypted_kdm.h>
#include <dcp/rating.h>
@@ -170,6 +171,8 @@ public:
return _content_versions;
}
+ void check_font_ids();
+
private:
friend struct reels_test5;
@@ -222,4 +225,9 @@ private:
};
+extern std::string id_for_font_in_reel(std::string id, int reel);
+extern void add_fonts_from_examiner(std::shared_ptr<TextContent> text, std::vector<std::vector<std::shared_ptr<dcpomatic::Font>>> const& fonts);
+
+
+
#endif
diff --git a/src/lib/dcp_decoder.cc b/src/lib/dcp_decoder.cc
index ad7d3e112..7e2001e0e 100644
--- a/src/lib/dcp_decoder.cc
+++ b/src/lib/dcp_decoder.cc
@@ -308,7 +308,9 @@ DCPDecoder::pass_texts (
strings.clear ();
}
- strings.push_back (*is);
+ dcp::SubtitleString is_copy = *is;
+ is_copy.set_font(id_for_font_in_reel(is_copy.font().get_value_or(""), _reel - _reels.begin()));
+ strings.push_back(is_copy);
}
/* XXX: perhaps these image subs should also be collected together like the string ones are;
diff --git a/src/lib/dcp_examiner.cc b/src/lib/dcp_examiner.cc
index f2ec68bdd..8fa41a8a5 100644
--- a/src/lib/dcp_examiner.cc
+++ b/src/lib/dcp_examiner.cc
@@ -54,8 +54,10 @@
using std::cout;
using std::dynamic_pointer_cast;
+using std::make_shared;
using std::shared_ptr;
using std::string;
+using std::vector;
using boost::optional;
@@ -132,6 +134,7 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
for (auto i: cpl->reels()) {
LOG_GENERAL ("Reel %1", i->id());
+ vector<shared_ptr<dcpomatic::Font>> reel_fonts;
if (i->main_picture ()) {
if (!i->main_picture()->asset_ref().resolved()) {
@@ -203,6 +206,10 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
_text_count[static_cast<int>(TextType::OPEN_SUBTITLE)] = 1;
_open_subtitle_language = try_to_parse_language (i->main_subtitle()->language());
+
+ for (auto const& font: i->main_subtitle()->asset()->font_data()) {
+ reel_fonts.push_back(make_shared<dcpomatic::Font>(font.first, font.second));
+ }
}
for (auto j: i->closed_captions()) {
@@ -244,6 +251,8 @@ DCPExaminer::DCPExaminer (shared_ptr<const DCPContent> content, bool tolerant)
} else if (!i->atmos()) {
_reel_lengths.push_back (i->atmos()->actual_duration());
}
+
+ _fonts.push_back(reel_fonts);
}
_encrypted = cpl->any_encrypted ();
diff --git a/src/lib/dcp_examiner.h b/src/lib/dcp_examiner.h
index a5bf2434e..ac4380597 100644
--- a/src/lib/dcp_examiner.h
+++ b/src/lib/dcp_examiner.h
@@ -166,6 +166,11 @@ public:
return _atmos_edit_rate;
}
+ /** @return fonts in each reel */
+ std::vector<std::vector<std::shared_ptr<dcpomatic::Font>>> fonts() const {
+ return _fonts;
+ }
+
private:
boost::optional<double> _video_frame_rate;
boost::optional<dcp::Size> _video_size;
@@ -198,4 +203,5 @@ private:
bool _has_atmos = false;
Frame _atmos_length = 0;
dcp::Fraction _atmos_edit_rate;
+ std::vector<std::vector<std::shared_ptr<dcpomatic::Font>>> _fonts;
};
diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc
index 3bae6e88f..a6cfd8d93 100644
--- a/src/lib/dcp_subtitle_content.cc
+++ b/src/lib/dcp_subtitle_content.cc
@@ -74,8 +74,14 @@ DCPSubtitleContent::examine (shared_ptr<const Film> film, shared_ptr<Job> job)
sc->fix_empty_font_ids ();
- for (auto i: sc->load_font_nodes()) {
- only_text()->add_font(make_shared<Font>(i->id));
+ auto font_data = sc->font_data();
+ for (auto node: sc->load_font_nodes()) {
+ auto data = font_data.find(node->id);
+ if (data != font_data.end()) {
+ only_text()->add_font(make_shared<Font>(node->id, data->second));
+ } else {
+ only_text()->add_font(make_shared<Font>(node->id));
+ }
}
}
diff --git a/src/lib/font.h b/src/lib/font.h
index c1405d0f6..24d8ed2bb 100644
--- a/src/lib/font.h
+++ b/src/lib/font.h
@@ -47,6 +47,11 @@ public:
, _file (file)
{}
+ Font (std::string id, dcp::ArrayData data)
+ : _id (id)
+ , _data (data)
+ {}
+
void as_xml (xmlpp::Node* node);
std::string id () const {
diff --git a/src/lib/string_text_file_content.cc b/src/lib/string_text_file_content.cc
index dae6811b5..d8c195be7 100644
--- a/src/lib/string_text_file_content.cc
+++ b/src/lib/string_text_file_content.cc
@@ -189,7 +189,10 @@ StringTextFileContent::check_font_ids()
auto names = font_names(file);
auto content = only_text();
- auto legacy_font_file = content->get_font("font")->file();
+ optional<boost::filesystem::path> legacy_font_file;
+ if (auto legacy_font = content->get_font("font")) {
+ legacy_font_file = legacy_font->file();
+ }
for (auto name: names) {
if (!content->get_font(name)) {