diff --git a/src/effects/Caption.cpp b/src/effects/Caption.cpp index 2d38b0e8..c82790c0 100644 --- a/src/effects/Caption.cpp +++ b/src/effects/Caption.cpp @@ -27,9 +27,9 @@ using namespace openshot; /// Blank constructor, useful when using Json to load the effect properties -Caption::Caption() : color("#ffffff"), stroke("#a9a9a9"), background("#ff000000"), background_alpha(0.0), left(0.1), top(0.75), right(0.1), +Caption::Caption() : color("#ffffff"), stroke("#a9a9a9"), background("#ff000000"), background_alpha(0.0), left(0.1), top(0.75), right(0.1), bottom(0.0), stroke_width(0.5), font_size(30.0), font_alpha(1.0), is_dirty(true), font_name("sans"), font(NULL), metrics(NULL), - fade_in(0.35), fade_out(0.35), background_corner(10.0), background_padding(20.0), line_spacing(1.0) + fade_in(0.0), fade_out(0.0), background_corner(10.0), background_padding(20.0), line_spacing(1.0) { // Init effect properties init_effect_details(); @@ -37,9 +37,9 @@ Caption::Caption() : color("#ffffff"), stroke("#a9a9a9"), background("#ff000000" // Default constructor Caption::Caption(std::string captions) : - color("#ffffff"), stroke("#a9a9a9"), background("#ff000000"), background_alpha(0.0), left(0.1), top(0.75), right(0.1), + color("#ffffff"), stroke("#a9a9a9"), background("#ff000000"), background_alpha(0.0), left(0.1), top(0.75), right(0.1), bottom(0.0), stroke_width(0.5), font_size(30.0), font_alpha(1.0), is_dirty(true), font_name("sans"), font(NULL), metrics(NULL), - fade_in(0.35), fade_out(0.35), background_corner(10.0), background_padding(20.0), line_spacing(1.0), + fade_in(0.0), fade_out(0.0), background_corner(10.0), background_padding(20.0), line_spacing(1.0), caption_text(captions) { // Init effect properties @@ -162,22 +162,28 @@ std::shared_ptr Caption::GetFrame(std::shared_ptrwidth() * left_value; - double starting_y = (frame_image->height() * top_value) + metrics_line_spacing; + double top_margin_y = frame_image->height() * top_value; + double starting_y = top_margin_y + metrics_line_spacing; double current_y = starting_y; double bottom_y = starting_y; double top_y = starting_y; double max_text_width = 0.0; double right_margin_x = frame_image->width() - (frame_image->width() * right_value); double caption_area_width = right_margin_x - left_margin_x; - QRectF caption_area = QRectF(left_margin_x, starting_y, caption_area_width, frame_image->height()); + double bottom_margin_y = frame_image->height() - (frame_image->height() * bottom_value); + double caption_area_height = std::max(bottom_margin_y - starting_y, 0.0); + QRectF caption_area = QRectF(left_margin_x, starting_y, caption_area_width, caption_area_height); + QRectF caption_clip_area = QRectF(left_margin_x, top_margin_y, caption_area_width, + std::max(bottom_margin_y - top_margin_y, 0.0)); // Keep track of all required text paths std::vector text_paths; @@ -220,8 +226,12 @@ std::shared_ptr Caption::GetFrame(std::shared_ptr= start_frame && frame_number <= end_frame && line.length() > 1) { // Calculate fade in/out ranges - fade_in_percentage = ((float) frame_number - (float) start_frame) / fade_in_value; - fade_out_percentage = 1.0 - (((float) frame_number - ((float) end_frame - fade_out_value)) / fade_out_value); + fade_in_percentage = fade_in_value > 0.0 + ? ((float) frame_number - (float) start_frame) / fade_in_value + : 1.0; + fade_out_percentage = fade_out_value > 0.0 + ? 1.0 - (((float) frame_number - ((float) end_frame - fade_out_value)) / fade_out_value) + : -1.0; // Loop through words, and find word-wrap boundaries QStringList words = line.split(" "); @@ -317,6 +327,8 @@ std::shared_ptr Caption::GetFrame(std::shared_ptr Caption::GetFrame(std::shared_ptr 00:10:00:000\nEdit this caption with our caption editor"); + Json::Value caption_json = c1.JsonValue(); + REQUIRE(caption_json["bottom"].isObject()); + caption_json["bottom"] = openshot::Keyframe(0.25).JsonValue(); + openshot::Caption c2; + c2.SetJsonValue(caption_json); + CHECK(c2.bottom.GetValue(1) == Approx(0.25).margin(0.00001)); + + Json::Value properties = openshot::stringToJson(c1.PropertiesJSON(1)); + CHECK(properties["top"]["name"].asString() == "Margin: Top"); + CHECK(properties["left"]["name"].asString() == "Margin: Left"); + CHECK(properties["bottom"]["name"].asString() == "Margin: Bottom"); + CHECK(properties["right"]["name"].asString() == "Margin: Right"); + // Load clip with video std::stringstream path; path << TEST_MEDIA_PATH << "sintel_trailer-720p.mp4";