{
SubtitleTransform tx;
+ /* The area of the original subtitle, in the coordinate space of the source video frame */
Rectangle sub_area (sub_pos.x, sub_pos.y + fs->subtitle_offset, sub_width, sub_height);
-
+
+ /* The cropped area of the source video frame, in the same coordinate space */
Rectangle cropped_target_area (
fs->crop.left,
fs->crop.top,
target_base_width - (fs->crop.left + fs->crop.right),
target_base_height - (fs->crop.top + fs->crop.bottom)
);
-
+
+ /* Hence the area of the cropped subtitle, in the same coordinate space */
Rectangle cropped_sub_area = sub_area.intersection (cropped_target_area);
-
+
+ /* The crop that should be applied to the subtitle, in its coordinate space */
tx.crop.x = cropped_sub_area.x - sub_area.x;
tx.crop.y = cropped_sub_area.y - sub_area.y;
tx.crop.w = cropped_sub_area.w;
tx.crop.h = cropped_sub_area.h;
+ /* We will scale the subtitle by the same amount as the video frame, and also by the additional
+ subtitle_scale
+ */
tx.transformed.w = cropped_sub_area.w * target_x_scale * fs->subtitle_scale;
tx.transformed.h = cropped_sub_area.h * target_y_scale * fs->subtitle_scale;
+ /* Then we need a corrective translation, consisting of two parts:
+ *
+ * 1. that which is the result of the scaling of the subtitle by target_x_scale and target_y_scale; this will be
+ * (sub_area.x - fs->crop_left) * target_x_scale and (sub_area.y - fs->crop_top) * target_y_scale.
+ *
+ * 2. that to shift the origin of the scale by fs->subtitle_scale to the centre of the subtitle; this will be
+ * (width_before_subtitle_scale * (1 - fs->subtitle_scale) / 2) and
+ * (height_before_subtitle_scale * (1 - fs->subtitle_scale) / 2).
+ *
+ * Combining these two translations gives these expressions.
+ */
+
tx.transformed.x = target_x_scale * ((sub_area.x - fs->crop.left) + (cropped_sub_area.w * (1 - fs->subtitle_scale) / 2));
tx.transformed.y = target_y_scale * ((sub_area.y - fs->crop.top) + (cropped_sub_area.h * (1 - fs->subtitle_scale) / 2));
_subtitle_offset = new wxSpinCtrl (this);
_sizer->Add (video_control (_subtitle_offset), 1);
- video_control (add_label_to_sizer (_sizer, this, "Subtitle Scale"));
- _subtitle_scale = new wxSpinCtrl (this);
- _sizer->Add (video_control (_subtitle_scale), 1);
+ {
+ video_control (add_label_to_sizer (_sizer, this, "Subtitle Scale"));
+ wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+ _subtitle_scale = new wxSpinCtrl (this);
+ s->Add (video_control (_subtitle_scale));
+ video_control (add_label_to_sizer (s, this, "%"));
+ _sizer->Add (s);
+ }
video_control (add_label_to_sizer (_sizer, this, "Frames Per Second"));
_frames_per_second = new wxStaticText (this, wxID_ANY, wxT (""));
_audio_delay->SetRange (-1000, 1000);
_still_duration->SetRange (0, 60 * 60);
_subtitle_offset->SetRange (-1024, 1024);
+ _subtitle_scale->SetRange (1, 1000);
vector<DCPContentType const *> const ct = DCPContentType::all ();
for (vector<DCPContentType const *>::const_iterator i = ct.begin(); i != ct.end(); ++i) {
}
_ignore_changes = Film::SUBTITLE_OFFSET;
- _film->set_subtitle_scale (_subtitle_scale->GetValue ());
+ _film->set_subtitle_scale (_subtitle_scale->GetValue() / 100.0);
_ignore_changes = Film::NONE;
}
_subtitle_offset->SetValue (_film->subtitle_offset ());
break;
case Film::SUBTITLE_SCALE:
- _subtitle_scale->SetValue (_film->subtitle_scale ());
+ _subtitle_scale->SetValue (_film->subtitle_scale() * 100);
break;
}
}