Files
core/OdfFile/Reader/Format/anim_elements.cpp
Kamil Kerimov fd90fbae21 Fix bug #70318
2024-09-19 13:01:07 +05:00

1887 lines
65 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "anim_elements.h"
#include "serialize_elements.h"
#include "odfcontext.h"
#include "odf_document.h"
#include "draw_common.h"
#include "../Converter/pptx_animation_context.h"
#include "svg_parser.h"
#include "../Converter/oox_drawing.h"
#include "../../../Common/Network/FileTransporter/include/manager.h"
#include <xml/xmlchar.h>
#include <xml/simple_xml_writer.h>
#include <boost/algorithm/string.hpp>
//#include <boost/filesystem.hpp>
#include <unordered_map>
#include <vector>
namespace cpdoccore {
using namespace odf_types;
namespace odf_reader {
struct preset_id_maping
{
odf_types::preset_id::type ODF_PresetID;
int OOX_PresetID;
};
struct preset_subtype_maping
{
int OOX_PresetID;
std::wstring ODF_PresetID;
};
static const preset_id_maping s_preset_id_map[] = {
{ preset_id::type::ooo_entrance_appear , 1 },
{ preset_id::type::ooo_entrance_fly_in , 2 },
{ preset_id::type::ooo_entrance_venetian_blinds , 3 },
{ preset_id::type::ooo_entrance_box , 4 },
{ preset_id::type::ooo_entrance_checkerboard , 5 },
{ preset_id::type::ooo_entrance_circle , 6 },
{ preset_id::type::ooo_entrance_fly_in_slow , 7 },
{ preset_id::type::ooo_entrance_diamond , 8 },
{ preset_id::type::ooo_entrance_dissolve_in , 9 },
{ preset_id::type::ooo_entrance_fade_in , 10 },
{ preset_id::type::ooo_entrance_flash_once , 11 },
{ preset_id::type::ooo_entrance_peek_in , 12 },
{ preset_id::type::ooo_entrance_plus , 13 },
{ preset_id::type::ooo_entrance_random_bars , 14 },
{ preset_id::type::ooo_entrance_spiral_in , 15 },
{ preset_id::type::ooo_entrance_split , 16 },
{ preset_id::type::ooo_entrance_stretchy , 17 },
{ preset_id::type::ooo_entrance_diagonal_squares , 18 },
{ preset_id::type::ooo_entrance_swivel , 19 },
{ preset_id::type::ooo_entrance_wedge , 20 },
{ preset_id::type::ooo_entrance_wheel , 21 },
{ preset_id::type::ooo_entrance_wipe , 22 },
{ preset_id::type::ooo_entrance_zoom , 23 },
{ preset_id::type::ooo_entrance_random , 24 },
{ preset_id::type::ooo_entrance_boomerang , 25 },
{ preset_id::type::ooo_entrance_bounce , 26 },
{ preset_id::type::ooo_entrance_colored_lettering , 27 },
{ preset_id::type::ooo_entrance_movie_credits , 28 },
{ preset_id::type::ooo_entrance_ease_in , 29 },
{ preset_id::type::ooo_entrance_float , 30 },
{ preset_id::type::ooo_entrance_turn_and_grow , 31 },
{ preset_id::type::ooo_entrance_breaks , 34 },
{ preset_id::type::ooo_entrance_pinwheel , 35 },
{ preset_id::type::ooo_entrance_rise_up , 37 },
{ preset_id::type::ooo_entrance_falling_in , 38 },
{ preset_id::type::ooo_entrance_thread , 39 },
{ preset_id::type::ooo_entrance_unfold , 40 },
{ preset_id::type::ooo_entrance_whip , 41 },
{ preset_id::type::ooo_entrance_ascend , 42 },
{ preset_id::type::ooo_entrance_center_revolve , 43 },
{ preset_id::type::ooo_entrance_fade_in_and_swivel , 45 },
{ preset_id::type::ooo_entrance_descend , 47 },
{ preset_id::type::ooo_entrance_sling , 48 },
{ preset_id::type::ooo_entrance_spin_in , 49 },
{ preset_id::type::ooo_entrance_compress , 50 },
{ preset_id::type::ooo_entrance_magnify , 51 },
{ preset_id::type::ooo_entrance_curve_up , 52 },
{ preset_id::type::ooo_entrance_fade_in_and_zoom , 53 },
{ preset_id::type::ooo_entrance_glide , 54 },
{ preset_id::type::ooo_entrance_expand , 55 },
{ preset_id::type::ooo_entrance_flip , 56 },
{ preset_id::type::ooo_entrance_fold , 58 },
{ preset_id::type::ooo_emphasis_fill_color , 1 },
{ preset_id::type::ooo_emphasis_font , 2 },
{ preset_id::type::ooo_emphasis_font_color , 3 },
{ preset_id::type::ooo_emphasis_font_size , 4 },
{ preset_id::type::ooo_emphasis_font_style , 5 },
{ preset_id::type::ooo_emphasis_grow_and_shrink , 6 },
{ preset_id::type::ooo_emphasis_line_color , 7 },
{ preset_id::type::ooo_emphasis_spin , 8 },
{ preset_id::type::ooo_emphasis_transparency , 9 },
{ preset_id::type::ooo_emphasis_bold_flash , 10 },
{ preset_id::type::ooo_emphasis_blast , 14 },
{ preset_id::type::ooo_emphasis_bold_reveal , 15 },
{ preset_id::type::ooo_emphasis_color_over_by_word , 16 },
{ preset_id::type::ooo_emphasis_reveal_underline , 18 },
{ preset_id::type::ooo_emphasis_color_blend , 19 },
{ preset_id::type::ooo_emphasis_color_over_by_letter, 20 },
{ preset_id::type::ooo_emphasis_complementary_color , 21 },
{ preset_id::type::ooo_emphasis_complementary_color_2, 22 },
{ preset_id::type::ooo_emphasis_contrasting_color , 23 },
{ preset_id::type::ooo_emphasis_darken , 24 },
{ preset_id::type::ooo_emphasis_desaturate , 25 },
{ preset_id::type::ooo_emphasis_flash_bulb , 26 },
{ preset_id::type::ooo_emphasis_flicker , 27 },
{ preset_id::type::ooo_emphasis_grow_with_color , 28 },
{ preset_id::type::ooo_emphasis_lighten , 30 },
{ preset_id::type::ooo_emphasis_style_emphasis , 31 },
{ preset_id::type::ooo_emphasis_teeter , 32 },
{ preset_id::type::ooo_emphasis_vertical_highlight , 33 },
{ preset_id::type::ooo_emphasis_wave , 34 },
{ preset_id::type::ooo_emphasis_blink , 35 },
{ preset_id::type::ooo_emphasis_shimmer , 36 },
{ preset_id::type::ooo_exit_disappear , 1 },
{ preset_id::type::ooo_exit_fly_out , 2 },
{ preset_id::type::ooo_exit_venetian_blinds , 3 },
{ preset_id::type::ooo_exit_box , 4 },
{ preset_id::type::ooo_exit_checkerboard , 5 },
{ preset_id::type::ooo_exit_circle , 6 },
{ preset_id::type::ooo_exit_crawl_out , 7 },
{ preset_id::type::ooo_exit_diamond , 8 },
{ preset_id::type::ooo_exit_dissolve , 9 },
{ preset_id::type::ooo_exit_fade_out , 10 },
{ preset_id::type::ooo_exit_flash_once , 11 },
{ preset_id::type::ooo_exit_peek_out , 12 },
{ preset_id::type::ooo_exit_plus , 13 },
{ preset_id::type::ooo_exit_random_bars , 14 },
{ preset_id::type::ooo_exit_spiral_out , 15 },
{ preset_id::type::ooo_exit_split , 16 },
{ preset_id::type::ooo_exit_collapse , 17 },
{ preset_id::type::ooo_exit_diagonal_squares , 18 },
{ preset_id::type::ooo_exit_swivel , 19 },
{ preset_id::type::ooo_exit_wedge , 20 },
{ preset_id::type::ooo_exit_wheel , 21 },
{ preset_id::type::ooo_exit_wipe , 22 },
{ preset_id::type::ooo_exit_zoom , 23 },
{ preset_id::type::ooo_exit_random , 24 },
{ preset_id::type::ooo_exit_boomerang , 25 },
{ preset_id::type::ooo_exit_bounce , 26 },
{ preset_id::type::ooo_exit_colored_lettering , 27 },
{ preset_id::type::ooo_exit_movie_credits , 28 },
{ preset_id::type::ooo_exit_ease_out , 29 },
{ preset_id::type::ooo_exit_float , 30 },
{ preset_id::type::ooo_exit_turn_and_grow , 31 },
{ preset_id::type::ooo_exit_breaks , 34 },
{ preset_id::type::ooo_exit_pinwheel , 35 },
{ preset_id::type::ooo_exit_sink_down , 37 },
{ preset_id::type::ooo_exit_swish , 38 },
{ preset_id::type::ooo_exit_thread , 39 },
{ preset_id::type::ooo_exit_unfold , 40 },
{ preset_id::type::ooo_exit_whip , 41 },
{ preset_id::type::ooo_exit_descend , 42 },
{ preset_id::type::ooo_exit_center_revolve , 43 },
{ preset_id::type::ooo_exit_fade_out_and_swivel , 45 },
{ preset_id::type::ooo_exit_ascend , 47 },
{ preset_id::type::ooo_exit_sling , 48 },
{ preset_id::type::ooo_exit_fade_out_and_zoom , 53 },
{ preset_id::type::ooo_exit_contract , 55 },
{ preset_id::type::ooo_exit_spin_out , 49 },
{ preset_id::type::ooo_exit_stretchy , 50 },
{ preset_id::type::ooo_exit_magnify , 51 },
{ preset_id::type::ooo_exit_curve_down , 52 },
{ preset_id::type::ooo_exit_glide , 54 },
{ preset_id::type::ooo_exit_flip , 56 },
{ preset_id::type::ooo_exit_fold , 58 },
{ preset_id::type::ooo_motionpath_4_point_star , 16 },
{ preset_id::type::ooo_motionpath_5_point_star , 5 },
{ preset_id::type::ooo_motionpath_6_point_star , 11 },
{ preset_id::type::ooo_motionpath_8_point_star , 17 },
{ preset_id::type::ooo_motionpath_circle , 1 },
{ preset_id::type::ooo_motionpath_crescent_moon , 6 },
{ preset_id::type::ooo_motionpath_diamond , 3 },
{ preset_id::type::ooo_motionpath_equal_triangle , 13 },
{ preset_id::type::ooo_motionpath_oval , 12 },
{ preset_id::type::ooo_motionpath_heart , 9 },
{ preset_id::type::ooo_motionpath_hexagon , 4 },
{ preset_id::type::ooo_motionpath_octagon , 10 },
{ preset_id::type::ooo_motionpath_parallelogram , 14 },
{ preset_id::type::ooo_motionpath_pentagon , 15 },
{ preset_id::type::ooo_motionpath_right_triangle , 2 },
{ preset_id::type::ooo_motionpath_square , 7 },
{ preset_id::type::ooo_motionpath_teardrop , 18 },
{ preset_id::type::ooo_motionpath_trapezoid , 8 },
{ preset_id::type::ooo_motionpath_arc_down , 37 },
{ preset_id::type::ooo_motionpath_arc_left , 51 },
{ preset_id::type::ooo_motionpath_arc_right , 58 },
{ preset_id::type::ooo_motionpath_arc_up , 44 },
{ preset_id::type::ooo_motionpath_bounce_left , 41 },
{ preset_id::type::ooo_motionpath_bounce_right , 54 },
{ preset_id::type::ooo_motionpath_curvy_left , 48 },
{ preset_id::type::ooo_motionpath_curvy_right , 61 },
{ preset_id::type::ooo_motionpath_decaying_wave , 60 },
{ preset_id::type::ooo_motionpath_diagonal_down_right, 49 },
{ preset_id::type::ooo_motionpath_diagonal_up_right , 56 },
{ preset_id::type::ooo_motionpath_down , 42 },
{ preset_id::type::ooo_motionpath_funnel , 52 },
{ preset_id::type::ooo_motionpath_spring , 53 },
{ preset_id::type::ooo_motionpath_stairs_down , 62 },
{ preset_id::type::ooo_motionpath_turn_down , 50 },
{ preset_id::type::ooo_motionpath_turn_down_right , 36 },
{ preset_id::type::ooo_motionpath_turn_up , 43 },
{ preset_id::type::ooo_motionpath_turn_up_right , 57 },
{ preset_id::type::ooo_motionpath_up , 64 },
{ preset_id::type::ooo_motionpath_wave , 47 },
{ preset_id::type::ooo_motionpath_zigzag , 38 },
{ preset_id::type::ooo_motionpath_bean , 31 },
{ preset_id::type::ooo_motionpath_buzz_saw , 25 },
{ preset_id::type::ooo_motionpath_curved_square , 20 },
{ preset_id::type::ooo_motionpath_curved_x , 21 },
{ preset_id::type::ooo_motionpath_curvy_star , 23 },
{ preset_id::type::ooo_motionpath_figure_8_four , 28 },
{ preset_id::type::ooo_motionpath_horizontal_figure_8, 26 },
{ preset_id::type::ooo_motionpath_inverted_square , 34 },
{ preset_id::type::ooo_motionpath_inverted_triangle , 33 },
{ preset_id::type::ooo_motionpath_loop_de_loop , 24 },
{ preset_id::type::ooo_motionpath_neutron , 29 },
{ preset_id::type::ooo_motionpath_peanut , 27 },
{ preset_id::type::ooo_motionpath_clover , 32 },
{ preset_id::type::ooo_motionpath_pointy_star , 19 },
{ preset_id::type::ooo_motionpath_swoosh , 30 },
{ preset_id::type::ooo_motionpath_vertical_figure_8 , 22 },
{ preset_id::type::ooo_motionpath_left , 35 },
{ preset_id::type::ooo_motionpath_right , 63 },
{ preset_id::type::ooo_motionpath_spiral_left , 55 },
{ preset_id::type::ooo_motionpath_spiral_right , 46 },
{ preset_id::type::ooo_motionpath_sine_wave , 40 },
{ preset_id::type::ooo_motionpath_s_curve_1 , 59 },
{ preset_id::type::ooo_motionpath_s_curve_2 , 39 },
{ preset_id::type::ooo_motionpath_heartbeat , 45 },
{ preset_id::type::none , 0 },
};
static const preset_subtype_maping s_preset_subtype_maping[] =
{
{ 1, L"from-top" },
{ 2, L"from-right" },
{ 3, L"from-top-right" },
{ 4, L"from-bottom" },
{ 5, L"horizontal" },
{ 6, L"from-bottom-right" },
{ 8, L"from-left" },
{ 9, L"from-top-left" },
{ 10, L"vertical" },
{ 12, L"from-bottom-left" },
{ 16, L"in" },
{ 21, L"vertical-in" },
{ 26, L"horizontal-in" },
{ 32, L"out" },
{ 36, L"out-from-screen-center" },
{ 37, L"vertical-out" },
{ 42, L"horizontal-out" },
{ 272, L"in-slightly" },
{ 288, L"out-slightly" },
{ 528, L"in-from-screen-center" },
{ 0, L""}
};
static _CP_OPT(std::wstring) pptx_convert_smil_attribute_name(const odf_types::smil_attribute_name& smil_attribute_name_)
{
using namespace odf_types;
_CP_OPT(std::wstring) result;
switch (smil_attribute_name_.get_type())
{
case smil_attribute_name::charColor: result = boost::none; break;
case smil_attribute_name::charFontName: result = boost::none; break;
case smil_attribute_name::charHeight: result = boost::none; break;
case smil_attribute_name::charPosture: result = boost::none; break;
case smil_attribute_name::charUnderline: result = boost::none; break;
case smil_attribute_name::charWeight: result = boost::none; break;
case smil_attribute_name::color: result = L"style.color"; break;
case smil_attribute_name::fill: result = L"fill.type"; break;
case smil_attribute_name::fillColor: result = L"fillcolor"; break;
case smil_attribute_name::fillStyle: result = boost::none; break;
case smil_attribute_name::fillOn: result = L"fill.on"; break;
case smil_attribute_name::height: result = L"ppt_h"; break;
case smil_attribute_name::lineColor: result = boost::none; break;
case smil_attribute_name::lineStyle: result = boost::none; break;
case smil_attribute_name::opacity: result = L"style.opacity"; break;
case smil_attribute_name::rotate: result = L"style.rotation"; break;
case smil_attribute_name::stroke: result = L"stroke.on"; break;
case smil_attribute_name::strokeColor: result = L"stroke.color"; break;
case smil_attribute_name::skewX: result = L"xshear"; break;
case smil_attribute_name::skewY: result = boost::none; break;
case smil_attribute_name::visibility: result = L"style.visibility"; break;
case smil_attribute_name::width: result = L"ppt_w"; break;
case smil_attribute_name::x: result = L"ppt_x"; break;
case smil_attribute_name::y: result = L"ppt_y"; break;
case smil_attribute_name::dim: result = L"ppt_c"; break;
}
return result;
}
static std::wstring pptx_convert_presentation_node_type(const odf_types::presentation_node_type& presentation_node_type_)
{
using namespace odf_types;
switch (presentation_node_type_.get_type())
{
case presentation_node_type::default_ : return L"clickEffect";
case presentation_node_type::after_previous : return L"afterEffect";
case presentation_node_type::interactive_sequence : return L"interactiveSeq";
case presentation_node_type::main_sequence : return L"mainSeq";
case presentation_node_type::on_click : return L"clickEffect";
case presentation_node_type::timing_root : return L"tmRoot";
case presentation_node_type::with_previous : return L"withEffect";
}
return L"clickEffect";
}
static std::wstring pptx_convert_animation_function(std::wstring animation_function)
{
boost::replace_all(animation_function, L"x", L"#ppt_x");
boost::replace_all(animation_function, L"y", L"#ppt_y");
boost::replace_all(animation_function, L"width", L"#ppt_w");
boost::replace_all(animation_function, L"height", L"#ppt_h");
return animation_function;
}
static std::wstring pptx_convert_smil_begin(const std::wstring& smil_begin)
{
if (smil_begin == L"next")
return L"indefinite";
else if (smil_begin == L"indefinite")
return L"indefinite";
if (boost::ends_with(smil_begin, L"click"))
return smil_begin;
std::wstring delay;
clockvalue delayClockvalue = clockvalue::parse(smil_begin);
if (delayClockvalue.get_value() != -1)
delay = boost::lexical_cast<std::wstring>(delayClockvalue.get_value());
return delay;
}
static std::wstring pptx_convert_svg_path(const std::vector<::svg_path::_polyline>& polylines)
{
using namespace ::svg_path;
std::wstringstream result;
for (size_t i = 0; i < polylines.size(); i++)
{
const _polyline& polyline = polylines[i];
if (polyline.command == L"a:close")
result << L"Z ";
else if (polyline.command == L"a:moveTo")
result << L"M ";
else if (polyline.command == L"a:lnTo")
result << L"L ";
else if (polyline.command == L"a:cubicBezTo")
result << L"C ";
else if (polyline.command == L"a:ArcTo")
result << L"G ";
for (size_t pointIndex = 0; pointIndex < polyline.points.size(); pointIndex++)
{
if (polyline.points[pointIndex].x)
result << polyline.points[pointIndex].x << L" ";
if (polyline.points[pointIndex].y)
result << polyline.points[pointIndex].y << L" ";
}
}
result << L"E"; // end of svg path
return result.str();
}
static std::vector<int> pptx_convert_smil_key_times(const odf_types::smil_key_times& key_times)
{
std::vector<int> result;
const int pptx_key_time_multiplier = 100000;
const std::vector<float> values = key_times.get_values();
for (size_t i = 0; i < values.size(); i++)
{
result.push_back(values[i] * pptx_key_time_multiplier);
}
return result;
}
static std::vector<std::wstring> pptx_convert_smil_values(const odf_types::smil_values& smil_values_)
{
std::vector<std::wstring> result;
const std::vector<std::wstring>& values = smil_values_.get_values();
for (size_t i = 0; i < values.size(); i++)
{
std::wstring value = values[i];
boost::replace_all(value, L"x", L"ppt_x");
boost::replace_all(value, L"y", L"ppt_y");
boost::replace_all(value, L"width", L"ppt_w");
boost::replace_all(value, L"height", L"ppt_h");
result.push_back(value);
}
return result;
}
static std::wstring pptx_convert_smil_fill(const odf_types::smil_fill& smil_fill_, bool durationSpecified)
{
switch (smil_fill_.get_type())
{
case smil_fill::type::_remove: return L"remove";
case smil_fill::type::_freeze: return L"freeze";
case smil_fill::type::_hold: return L"hold";
case smil_fill::type::_transition: return L"transition";
case smil_fill::type::_auto:
default:
return durationSpecified ? L"remove" : L"freeze";
}
}
static int pptx_convert_acceleration(double acceleration)
{
const int pptx_multiplier = 100000;
return static_cast<int>(acceleration * pptx_multiplier);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
const wchar_t* anim_par::ns = L"anim";
const wchar_t* anim_par::name = L"par";
void anim_par::add_attributes( const xml::attributes_wc_ptr & Attributes )
{
common_attlist_.add_attributes(Attributes);
par_attlist_.add_attributes(Attributes);
}
static _CP_OPT(int) pptx_convert_preset_subtype(const std::wstring& preset_class_, const int preset_id_, const std::wstring& preset_subtype_)
{
_CP_OPT(int) pptx_preset_subtype;
if ((preset_class_ == L"entr") || (preset_class_ == L"exit"))
{
// skip "wheel" preset id
if (preset_id_ != 21)
{
switch (preset_id_)
{
case 5:
{
if (preset_subtype_ == L"downward")
pptx_preset_subtype = 5;
else if (preset_subtype_ == L"across")
pptx_preset_subtype = 10;
}
break;
case 6:
{
if (preset_subtype_ == L"out")
pptx_preset_subtype = 16;
else if (preset_subtype_ == L"in")
pptx_preset_subtype = 32;
}
break;
case 17:
{
if (preset_subtype_ == L"across")
pptx_preset_subtype = 10;
}
break;
case 18:
{
if (preset_subtype_ == L"right-to-top")
pptx_preset_subtype = 3;
else if (preset_subtype_ == L"right-to-bottom")
pptx_preset_subtype = 6;
else if (preset_subtype_ == L"left-to-top")
pptx_preset_subtype = 9;
else if (preset_subtype_ == L"left-to-bottom")
pptx_preset_subtype = 12;
}
break;
}
}
if (!pptx_preset_subtype)
{
const preset_subtype_maping* p = s_preset_subtype_maping;
while (p->OOX_PresetID != 0)
{
if (preset_subtype_ == p->ODF_PresetID)
{
pptx_preset_subtype = p->OOX_PresetID;
break;
}
p++;
}
}
}
if (!pptx_preset_subtype)
{
try
{
pptx_preset_subtype = boost::lexical_cast<int>(preset_subtype_);
}
catch (const boost::bad_lexical_cast& e)
{
pptx_preset_subtype = 0;
}
}
return pptx_preset_subtype;
}
void anim_par::pptx_convert(oox::pptx_conversion_context & Context)
{
oox::pptx_animation_context & animationContext = Context.get_slide_context().get_animation_context();
_CP_OPT(std::wstring) presentationNodeType;
_CP_OPT(std::wstring) direction;
_CP_OPT(std::wstring) restart;
_CP_OPT(int) duration;
_CP_OPT(std::wstring) delay; // NOTE: Comes from smil:begin
_CP_OPT(std::wstring) end;
_CP_OPT(std::wstring) fill;
_CP_OPT(std::wstring) presentationPresetClass;
_CP_OPT(int) presentationPresetId;
_CP_OPT(int) presentationPresetPresetSubType;
bool isSlideAnimation = false; // NOTE: Анимация применяется к самому слайду, а не элементу на слайде
_CP_OPT(int) accelerate;
_CP_OPT(int) decelerate;
if (common_attlist_.presentation_node_type_)
presentationNodeType = pptx_convert_presentation_node_type(common_attlist_.presentation_node_type_.value());
if (common_attlist_.smil_direction_)
{
if (common_attlist_.smil_direction_.value() == L"reverse")
direction = L"reverse";
}
if (common_attlist_.smil_restart_)
{
// smil:restart = "never", "always", "whenNotActive" or "default".
// NOTE: Hardcode for now
// TODO: Figure out correct value
restart = boost::none;
}
if (common_attlist_.smil_dur_)
{
duration = common_attlist_.smil_dur_->get_value();
}
if (common_attlist_.smil_begin_)
{
const std::wstring& smil_begin = common_attlist_.smil_begin_.value();
isSlideAnimation = boost::algorithm::ends_with(smil_begin, L".begin");
if (boost::algorithm::contains(smil_begin, L"click"))
{
std::wstring id = smil_begin.substr(0, smil_begin.find(L".click"));
std::wstring del = L"";
if(boost::algorithm::contains(smil_begin, L"+"))
del = smil_begin.substr(smil_begin.find(L"+"));
animationContext.set_seq_animation_delay(del);
animationContext.set_seq_animation_restart(L"whenNotActive");
animationContext.set_seq_animation_target_element(std::to_wstring(Context.get_slide_context().get_id(id)));
}
else if(!isSlideAnimation)
delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value());
}
// TODO: Figure out correct value
end = boost::none;
if (par_attlist_.presentation_preset_class_)
{
switch (par_attlist_.presentation_preset_class_.value().get_type())
{
case preset_class::entrance:
presentationPresetClass = L"entr";
presentationPresetId = pptx_convert_preset_id();
break;
case preset_class::exit:
presentationPresetClass = L"exit";
presentationPresetId = pptx_convert_preset_id();
break;
case preset_class::emphasis:
presentationPresetClass = L"emph";
presentationPresetId = pptx_convert_preset_id();
break;
case preset_class::motion_path:
presentationPresetClass = L"path";
presentationPresetId = pptx_convert_preset_id();
break;
case preset_class::ole_action:
presentationPresetClass = L"verb";
break;
case preset_class::media_call:
presentationPresetClass = L"mediacall";
break;
default:
presentationPresetClass = L"custom";
}
if (par_attlist_.presentation_preset_sub_type_ && presentationPresetId)
presentationPresetPresetSubType = pptx_convert_preset_subtype(
*presentationPresetClass,
*presentationPresetId,
*par_attlist_.presentation_preset_sub_type_);
else
presentationPresetPresetSubType = 0;
}
if (common_attlist_.smil_fill_)
{
bool durationSpecified = common_attlist_.smil_dur_.has_value() || common_attlist_.smil_end_.has_value();
fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), durationSpecified);
}
else
fill = L"hold";
if (par_attlist_.smil_accelerate_)
{
const int pptx_multiplyer = 100000;
accelerate = par_attlist_.smil_accelerate_.value() * pptx_multiplyer;
}
if (par_attlist_.smil_decelerate_)
{
const int pptx_multiplyer = 100000;
decelerate = par_attlist_.smil_decelerate_.value() * pptx_multiplyer;
}
if (!isSlideAnimation)
{
animationContext.start_par_animation();
if (presentationNodeType) animationContext.set_par_animation_presentation_node_type(presentationNodeType.value());
if (direction) animationContext.set_par_animation_direction(direction.value());
if (restart) animationContext.set_par_animation_restart(restart.value());
if (duration) animationContext.set_par_animation_duration(duration.value());
if (delay) animationContext.set_par_animation_delay(delay.value());
if (end) animationContext.set_par_animation_end(end.value());
if (presentationPresetClass) animationContext.set_par_animation_preset_class(presentationPresetClass.value());
if (presentationPresetId) animationContext.set_par_animation_preset_id(presentationPresetId.value());
if (presentationPresetPresetSubType) animationContext.set_par_animation_preset_subtype(presentationPresetPresetSubType.value());
if (fill) animationContext.set_par_animation_fill(fill.value());
if (accelerate) animationContext.set_par_animation_accelerate(accelerate.value());
if (decelerate) animationContext.set_par_animation_decelerate(decelerate.value());
}
animationContext.set_is_slide_animation(isSlideAnimation);
if (anim_par_array_.size())
{
for(size_t i = 0; i < anim_par_array_.size(); i++)
anim_par_array_[i]->pptx_convert(Context); // это для самого слайда (то что и нужно)
}
for (size_t i = 0; i < anim_seq_array_.size(); i++)
{
anim_seq_array_[i]->pptx_convert(Context);
}
/////////////////////////////////////////////////////////////////
//внутренние эффекты - те что внутри одной последовательности
for (size_t i = 0; i < content_.size(); i++)
{
content_[i]->pptx_convert(Context);
}
if(!isSlideAnimation)
animationContext.end_par_animation();
}
void anim_par::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name)
{
if CP_CHECK_NAME(L"anim", L"par")
CP_CREATE_ELEMENT(anim_par_array_);
else if CP_CHECK_NAME(L"anim", L"seq")
CP_CREATE_ELEMENT(anim_seq_array_);//более 1 элемента- взаимосвязанная анимация (между фигурами)
else
CP_CREATE_ELEMENT(content_);
}
boost::optional<int> anim_par::pptx_convert_preset_id()
{
if (par_attlist_.presentation_preset_id_)
{
preset_id::type presetID = par_attlist_.presentation_preset_id_.value().get_type();
for (size_t i = 0; s_preset_id_map[i].ODF_PresetID != preset_id::type::none; i++)
{
if (s_preset_id_map[i].ODF_PresetID == presetID)
return s_preset_id_map[i].OOX_PresetID;
}
return 0;
}
return boost::none;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
const wchar_t * anim_seq::ns = L"anim";
const wchar_t * anim_seq::name = L"seq";
void anim_seq::add_attributes( const xml::attributes_wc_ptr & Attributes )
{
attlist_.add_attributes(Attributes);
}
void anim_seq::pptx_convert(oox::pptx_conversion_context & Context)
{
_CP_OPT(std::wstring) presentationNodeType;
_CP_OPT(int) duration;
if (attlist_.presentation_node_type_)
presentationNodeType = pptx_convert_presentation_node_type(attlist_.presentation_node_type_.value());
if (attlist_.smil_dur_)
duration = attlist_.smil_dur_->get_value();
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
animationContext.start_seq_animation();
if (presentationNodeType) animationContext.set_seq_animation_presentation_node_type(presentationNodeType.value());
if (attlist_.smil_direction_) animationContext.set_seq_animation_direction(attlist_.smil_direction_.value());
if (attlist_.smil_restart_) animationContext.set_seq_animation_restart(attlist_.smil_restart_.value());
if (duration) animationContext.set_seq_animation_dur(duration.value());
if (attlist_.smil_begin_) animationContext.set_seq_animation_delay(attlist_.smil_begin_.value());
if (attlist_.smil_end_) animationContext.set_seq_animation_end(attlist_.smil_end_.value());
for (size_t i = 0; i < anim_par_array_.size(); i++)
{
anim_par_array_[i]->pptx_convert(Context);
}
animationContext.end_seq_animation();
}
void anim_seq::add_child_element( xml::sax * Reader, const std::wstring & Ns, const std::wstring & Name)
{
if CP_CHECK_NAME(L"anim", L"par")
CP_CREATE_ELEMENT(anim_par_array_);
}
////////////////////////////////////////////////////////////////
const wchar_t * anim_transitionFilter::ns = L"anim";
const wchar_t * anim_transitionFilter::name = L"transitionFilter";
void anim_transitionFilter::add_attributes( const xml::attributes_wc_ptr & Attributes )
{
common_attlist_.add_attributes(Attributes);
filter_attlist_.add_attributes(Attributes);
}
std::wstring anim_transitionFilter::convert_filter()
{
std::wstring filter;
const _CP_OPT(std::wstring)& subtype = filter_attlist_.smil_subtype_;
_CP_OPT(std::wstring) pptx_subtype;
if (filter_attlist_.smil_type_)
{
switch (filter_attlist_.smil_type_.value().get_type())
{
case smil_transition_type::barWipe:
filter = L"wipe";
if (subtype)
{
if (subtype.value() == L"topToBottom") pptx_subtype = L"down";
else pptx_subtype = L"up";
}
else
pptx_subtype = L"up";
break;
case smil_transition_type::boxWipe:
filter = L"slide";
if (subtype)
{
if (subtype.value() == L"topRight") pptx_subtype = L"fromTop";
else if (subtype.value() == L"bottomRight") pptx_subtype = L"fromBottom";
else if (subtype.value() == L"bottomLeft") pptx_subtype = L"fromBottom";
else if (subtype.value() == L"topCenter") pptx_subtype = L"fromTop";
else if (subtype.value() == L"rightCenter") pptx_subtype = L"fromRight";
else if (subtype.value() == L"bottomCenter") pptx_subtype = L"fromBottom";
else if (subtype.value() == L"leftCenter") pptx_subtype = L"fromLeft";
else pptx_subtype = L"fromTop";
}
else
pptx_subtype = L"fromTop";
break;
case smil_transition_type::fourBoxWipe:
filter = L"plus";
if (subtype)
{
if (subtype.value() == L"cornersOut") pptx_subtype = L"out";
else pptx_subtype = L"in";
}
else
pptx_subtype = L"in";
break;
case smil_transition_type::barnDoorWipe:
filter = L"barn";
if (subtype)
{
if (subtype.value() == L"horizontal") pptx_subtype = L"inHorizontal";
else pptx_subtype = L"inVertical";
}
else
pptx_subtype = L"inHorizontal";
break;
case smil_transition_type::irisWipe:
if (subtype)
{
if (subtype.value() == L"rectangle")
{
filter = L"box";
pptx_subtype = L"out";
}
else if (subtype.value() == L"diamond")
{
filter = L"diamond";
pptx_subtype = L"out";
}
else
{
filter = L"box";
pptx_subtype = L"out";
}
}
else
{
filter = L"box";
pptx_subtype = L"out";
}
break;
case smil_transition_type::ellipseWipe:
filter = L"circle";
pptx_subtype = L"out";
break;
case smil_transition_type::pinWheelWipe:
filter = L"wheel";
if (subtype)
{
if (subtype.value() == L"oneBlade") pptx_subtype = L"1";
else if (subtype.value() == L"twoBladeVertical") pptx_subtype = L"2";
else if (subtype.value() == L"fourBlade") pptx_subtype = L"4";
else pptx_subtype = L"2";
}
else
pptx_subtype = L"2";
break;
case smil_transition_type::fanWipe:
filter = L"wedge";
break;
case smil_transition_type::waterfallWipe:
filter = L"strips";
if (subtype)
{
if (subtype.value() == L"horizontalLeft") pptx_subtype = L"downRight";
else if (subtype.value() == L"horizontalRight") pptx_subtype = L"downLeft";
else if (subtype.value() == L"verticalLeft") pptx_subtype = L"upRight";
else if (subtype.value() == L"verticalRight") pptx_subtype = L"upLeft";
else pptx_subtype = L"upRight";
}
else
pptx_subtype = L"upRight";
break;
case smil_transition_type::slideWipe:
filter = L"wipe";
if (subtype)
{
if (subtype.value() == L"fromLeft") pptx_subtype = L"left";
else if (subtype.value() == L"fromTop") pptx_subtype = L"up";
else if (subtype.value() == L"fromRight") pptx_subtype = L"right";
else if (subtype.value() == L"fromBottom") pptx_subtype = L"down";
}
break;
case smil_transition_type::fade:
filter = L"fade";
break;
case smil_transition_type::checkerBoardWipe:
filter = L"checkerboard";
if (subtype)
{
if (subtype.value() == L"across") pptx_subtype = L"across";
else pptx_subtype = L"across";
}
else
pptx_subtype = L"across";
break;
case smil_transition_type::blindsWipe:
filter = L"blinds";
if (subtype)
{
if (subtype.value() == L"horizontal") pptx_subtype = L"horizontal";
else pptx_subtype = L"vertical";
}
else
pptx_subtype = L"vertical";
break;
case smil_transition_type::dissolve:
filter = L"dissolve";
break;
case smil_transition_type::randomBarWipe:
filter = L"randombar";
if (subtype)
{
if (subtype.value() == L"horizontal") pptx_subtype = L"horizontal";
else pptx_subtype = L"vertical";
}
break;
case smil_transition_type::pushWipe:
filter = L"slide";
if (subtype)
pptx_subtype = subtype.value(); // fromLeft, fromTop, fromRight, fromBottom
break;
case smil_transition_type::doubleSweepWipe:
case smil_transition_type::doubleFanWipe:
filter = L"wheel";
pptx_subtype = L"2";
break;
case smil_transition_type::saloonDoorWipe:
case smil_transition_type::windshieldWipe:
filter = L"slide";
pptx_subtype = L"fromLeft";
break;
case smil_transition_type::snakeWipe:
if (subtype)
{
if (subtype.value() == L"topLeftHorizontal") { filter = L"slide" ; pptx_subtype = L"fromLeft"; }
else if (subtype.value() == L"topLeftVertical") { filter = L"slide" ; pptx_subtype = L"fromTop"; }
else if (subtype.value() == L"topLeftDiagonal") { filter = L"strips"; pptx_subtype = L"downRight"; }
else if (subtype.value() == L"topRightDiagonal") { filter = L"strips"; pptx_subtype = L"downLeft"; }
else if (subtype.value() == L"bottomRightDiagonal") { filter = L"strips"; pptx_subtype = L"upLeft"; }
else if (subtype.value() == L"bottomLeftDiagonal") { filter = L"strips"; pptx_subtype = L"upRight"; }
else
filter = L"fade";
}
break;
case smil_transition_type::spiralWipe:
filter = L"circle";
break;
case smil_transition_type::parallelSnakesWipe:
if (subtype)
{
if (boost::starts_with(subtype.value(), L"vertical"))
{
filter = L"barn";
pptx_subtype = L"inVertical";
}
else if (boost::starts_with(subtype.value(), L"horizontal"))
{
filter = L"barn";
pptx_subtype = L"inHorizontal";
}
else
filter = L"fade"; // NOTE: This is no corresponding transition to "diagonalBottomLeftOpposite" and "diagonalTopLeftOpposite"
}
break;
case smil_transition_type::boxSnakesWipe:
if (subtype)
{
filter = L"barn";
if (subtype.value() == L"twoBoxTop") pptx_subtype = L"inVertical";
else if (subtype.value() == L"twoBoxBottom") pptx_subtype = L"inVertical";
else if (subtype.value() == L"twoBoxLeft") pptx_subtype = L"inHorizontal";
else if (subtype.value() == L"twoBoxRight") pptx_subtype = L"inHorizontal";
else if (subtype.value() == L"fourBoxVertical") pptx_subtype = L"inVertical";
else if (subtype.value() == L"fourBoxHorizontal") pptx_subtype = L"inVertical";
else
pptx_subtype = L"inVertical";
}
break;
// NOTE: Not implemented. There is no corresponding conversion. Set "fade" as default animation
case smil_transition_type::singleSweepWipe:
case smil_transition_type::eyeWipe:
case smil_transition_type::roundRectWipe:
case smil_transition_type::starWipe:
case smil_transition_type::miscShapeWipe:
case smil_transition_type::clockWipe:
case smil_transition_type::triangleWipe:
case smil_transition_type::arrowHeadWipe:
case smil_transition_type::pentagonWipe:
case smil_transition_type::hexagonWipe:
case smil_transition_type::diagonalWipe:
case smil_transition_type::bowTieWipe:
case smil_transition_type::miscDiagonalWipe:
case smil_transition_type::veeWipe:
case smil_transition_type::barnVeeWipe:
case smil_transition_type::zigZagWipe:
case smil_transition_type::barnZigZagWipe:
default:
filter = L"fade";
break;
}
}
if (pptx_subtype)
{
if (filter_attlist_.smil_direction_
&& filter_attlist_.smil_direction_.value() == L"reverse")
{
if (pptx_subtype.value() == L"in")
pptx_subtype = L"out";
else if (pptx_subtype.value() == L"out")
pptx_subtype = L"in";
else if(pptx_subtype.value() == L"inHorizontal")
pptx_subtype = L"outHorizontal";
else if (pptx_subtype.value() == L"outHorizontal")
pptx_subtype = L"inHorizontal";
}
filter += L"(" + pptx_subtype.value() + L")";
}
return filter;
}
void anim_transitionFilter::convert_slide_transition_filter(oox::pptx_conversion_context& Context)
{
_CP_OPT(std::wstring) color;
_CP_OPT(std::wstring) dir;
_CP_OPT(int) time;
std::wstring type;
_CP_OPT(std::wstring) param;
if (common_attlist_.smil_dur_)
{
time = common_attlist_.smil_dur_->get_value();
}
if (filter_attlist_.smil_fadeColor_)
{
color = filter_attlist_.smil_fadeColor_->get_hex_value();
}
smil_transition_type::type transition_type;
if (filter_attlist_.smil_type_)
{
transition_type = filter_attlist_.smil_type_->get_type();
}
switch (transition_type)
{
case smil_transition_type::barnVeeWipe:
type = L"split";
break;
case smil_transition_type::irisWipe:
if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"diamond"))
type = L"diamond";
else
type = L"zoom";
break;
case smil_transition_type::miscDiagonalWipe:
if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"doubleDiamond"))
type = L"diamond";
else
type = L"zoom";
break;
case smil_transition_type::ellipseWipe:
case smil_transition_type::eyeWipe:
type = L"circle";
break;
case smil_transition_type::roundRectWipe:
type = L"zoom";
break;
case smil_transition_type::fourBoxWipe:
case smil_transition_type::triangleWipe:
case smil_transition_type::arrowHeadWipe:
case smil_transition_type::pentagonWipe:
case smil_transition_type::hexagonWipe:
case smil_transition_type::starWipe:
case smil_transition_type::miscShapeWipe:
type = L"plus";
break;
case smil_transition_type::pinWheelWipe:
param = L"2";
case smil_transition_type::clockWipe:
case smil_transition_type::singleSweepWipe: //
case smil_transition_type::doubleFanWipe: //
type = L"wheel";
if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"oneBlade")) param = L"1";
else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"threeBlade")) param = L"3";
else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"fourBlade")) param = L"4";
else if ((filter_attlist_.smil_subtype_) && (filter_attlist_.smil_subtype_.get() == L"eightBlade")) param = L"8";
break;
case smil_transition_type::fanWipe:
type = L"wedge";
break;
case smil_transition_type::fade:
type = L"fade";
param = L"1";
break;
case smil_transition_type::checkerBoardWipe:
type = L"checker";
if (filter_attlist_.smil_subtype_.get() == L"across") dir = L"horz";
if (filter_attlist_.smil_subtype_.get() == L"down") dir = L"vert";
break;
case smil_transition_type::blindsWipe:
type = L"blinds";
if (filter_attlist_.smil_subtype_.get() == L"vertical") dir = L"vert";
else if (filter_attlist_.smil_subtype_.get() == L"horizontal") dir = L"horz";
break;
case smil_transition_type::diagonalWipe:
case smil_transition_type::waterfallWipe:
type = L"strips";
if (filter_attlist_.smil_subtype_)
{
if (filter_attlist_.smil_subtype_.get() == L"horizontalLeft") dir = L"rd";
else if (filter_attlist_.smil_subtype_.get() == L"horizontalRight") dir = L"lu";
else if (filter_attlist_.smil_subtype_.get() == L"verticalRight") dir = L"ld";
else dir = L"ru";
}
break;
case smil_transition_type::dissolve:
type = L"dissolve";
break;
case smil_transition_type::randomBarWipe:
type = L"randomBar";
if (filter_attlist_.smil_subtype_)
{
if (filter_attlist_.smil_subtype_.get() == L"vertical") dir = L"vert";
else if (filter_attlist_.smil_subtype_.get() == L"horizontal") dir = L"horz";
}
break;
case smil_transition_type::pushWipe:
type = L"push";
if (filter_attlist_.smil_subtype_.get() == L"combVertical") { type = L"comb"; dir = L"vert"; }
else if (filter_attlist_.smil_subtype_.get() == L"combHorizontal") { type = L"comb"; dir = L"horz"; }
break;
case smil_transition_type::slideWipe:
case smil_transition_type::boxWipe:
type = L"cover";
break;
case smil_transition_type::barnDoorWipe:
type = L"split";
if (filter_attlist_.smil_subtype_.get() == L"vertical") param = L"vert";
if (filter_attlist_.smil_subtype_.get() == L"horizontal") param = L"horz";
break;
case smil_transition_type::barWipe:
type = L"wipe";
if (filter_attlist_.smil_subtype_)
{
if (filter_attlist_.smil_subtype_.get() == L"fromTopLeft") { type = L"strips"; dir = L"rd"; }
else if (filter_attlist_.smil_subtype_.get() == L"fromBottomLeft") { type = L"strips"; dir = L"ru"; }
else if (filter_attlist_.smil_subtype_.get() == L"fromTopRight") { type = L"strips"; dir = L"ld"; }
else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight") { type = L"strips"; dir = L"lu"; }
else if (filter_attlist_.smil_subtype_.get() == L"fadeOverColor") { type = L"fade"; param = L"0"; }
}
break;
///////////////////////////////////////////////////////
case smil_transition_type::bowTieWipe:
case smil_transition_type::veeWipe:
case smil_transition_type::zigZagWipe:
case smil_transition_type::barnZigZagWipe:
case smil_transition_type::doubleSweepWipe:
case smil_transition_type::saloonDoorWipe:
case smil_transition_type::windshieldWipe:
case smil_transition_type::snakeWipe:
case smil_transition_type::spiralWipe:
case smil_transition_type::parallelSnakesWipe:
case smil_transition_type::boxSnakesWipe:
break;
//////////////////////////////////////////////////////
}
if (filter_attlist_.smil_subtype_)
{
if (!dir)
{
if (filter_attlist_.smil_subtype_.get() == L"leftToRight")
{
if ((common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get() == L"reverse"))dir = L"l";
else dir = L"r";
}
if (filter_attlist_.smil_subtype_.get() == L"topToBottom")
{
if ((common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get() == L"reverse"))dir = L"u";
else dir = L"d";
}
if (filter_attlist_.smil_subtype_.get() == L"fromTop") dir = L"d";
else if (filter_attlist_.smil_subtype_.get() == L"fromLeft") dir = L"r";
else if (filter_attlist_.smil_subtype_.get() == L"fromRight") dir = L"l";
else if (filter_attlist_.smil_subtype_.get() == L"fromBottom") dir = L"u";
else if (filter_attlist_.smil_subtype_.get() == L"topRight") dir = L"ld";
else if (filter_attlist_.smil_subtype_.get() == L"bottomLeft") dir = L"lu";
else if (filter_attlist_.smil_subtype_.get() == L"bottomRight") dir = L"ru";
else if (filter_attlist_.smil_subtype_.get() == L"topLeft") dir = L"rd";
else if (filter_attlist_.smil_subtype_.get() == L"fromTopLeft") dir = L"rd";
else if (filter_attlist_.smil_subtype_.get() == L"fromBottomLeft") dir = L"ru";
else if (filter_attlist_.smil_subtype_.get() == L"fromTopRight") dir = L"ld";
else if (filter_attlist_.smil_subtype_.get() == L"fromBottomRight") dir = L"lu";
}
if (!dir && (common_attlist_.smil_direction_) && (common_attlist_.smil_direction_.get() == L"reverse"))
dir = L"in";
}
Context.get_slide_context().start_slide_animation();
Context.get_slide_context().set_transitionFilter(type, dir, param, time);
Context.get_slide_context().end_slide_animation();
}
void anim_transitionFilter::pptx_convert(oox::pptx_conversion_context & Context)
{
if (Context.get_slide_context().get_animation_context().get_is_slide_animation())
{
convert_slide_transition_filter(Context);
return;
}
std::wstring filter = convert_filter();
_CP_OPT(std::wstring) transition;
_CP_OPT(int) time;
_CP_OPT(std::wstring) delay;
_CP_OPT(int) acceleration;
_CP_OPT(int) deceleration;
size_t shapeId = 0;
if (common_attlist_.smil_dur_)
time = common_attlist_.smil_dur_->get_value();
if (filter_attlist_.smil_mode_)
transition = filter_attlist_.smil_mode_.value();
if (common_attlist_.smil_target_element_)
shapeId = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value());
if (common_attlist_.smil_begin_)
delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value());
if (common_attlist_.smil_accelerate_)
acceleration = pptx_convert_acceleration(common_attlist_.smil_accelerate_.value());
if (common_attlist_.smil_decelerate_)
deceleration = pptx_convert_acceleration(common_attlist_.smil_decelerate_.value());
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
animationContext.start_anim_effect();
animationContext.set_anim_effect_filter(filter);
if(transition) animationContext.set_anim_effect_transition(transition.value());
if (time) animationContext.set_anim_effect_duration(time.value());
if (delay) animationContext.set_anim_effect_delay(delay.value());
if (acceleration)animationContext.set_anim_effect_accel(acceleration.value());
if (deceleration)animationContext.set_anim_effect_decel(deceleration.value());
animationContext.set_anim_effect_shape_id(shapeId);
animationContext.end_anim_effect();
}
const wchar_t * anim_audio::ns = L"anim";
const wchar_t * anim_audio::name = L"audio";
void anim_audio::add_attributes( const xml::attributes_wc_ptr & Attributes )
{
common_attlist_.add_attributes(Attributes);
audio_attlist_.add_attributes(Attributes);
}
//static bool is_absolute_path(const std::wstring& path) {
// boost::filesystem::path p(path);
// return p.is_absolute();
//}
void anim_audio::pptx_convert(oox::pptx_conversion_context & Context)
{
oox::pptx_slide_context& slideContext = Context.get_slide_context();
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
if (audio_attlist_.xlink_href_)
{
std::wstring href = audio_attlist_.xlink_href_.value();
if (boost::algorithm::starts_with(href, L"file:///"))
href = href.substr(std::wstring(L"file:///").size());
//else if (boost::algorithm::starts_with(href, L"http"))
//{
// const std::wstring mediaFolder = Context.root()->get_folder() + FILE_SEPARATOR_STR + L"Media";
// if (!NSDirectory::Exists(mediaFolder))
// NSDirectory::CreateDirectory(mediaFolder);
// const std::wstring audioPath = mediaFolder + FILE_SEPARATOR_STR + NSFile::GetFileName(href);
// ASC::CDownloadManager::DownloadExternal(href, audioPath);
// href = audioPath;
//}
std::wstring relative_href = href;
if (slideContext.get_mediaitems()->is_internal_path(href, Context.root()->get_folder()))
{
relative_href = Context.root()->get_folder() + FILE_SEPARATOR_STR + href;
}
if (NSFile::CFileBinary::Exists(relative_href))
{
const std::wstring name = NSFile::GetFileName(href);
std::wstring ref;
bool isInternal;
const std::wstring& rId = slideContext.get_mediaitems()->add_or_find_anim_audio(href, isInternal, ref);
slideContext.add_rels(true, rId, ref, oox::_rels_type::typeAudio);
animationContext.start_anim_audio();
animationContext.add_anim_audio(rId, name);
animationContext.end_anim_audio();
}
}
}
////////////////////////////////////////////////////////////////
const wchar_t* anim_set::ns = L"anim";
const wchar_t* anim_set::name = L"set";
void anim_set::pptx_convert(oox::pptx_conversion_context& Context)
{
_CP_OPT(std::wstring) direction;
_CP_OPT(std::wstring) restart;
_CP_OPT(int) duration;
_CP_OPT(std::wstring) delay;
_CP_OPT(std::wstring) end;
_CP_OPT(std::wstring) fill;
_CP_OPT(std::wstring) autoRev;
_CP_OPT(std::wstring) attribute_name;
_CP_OPT(std::wstring) to_value;
size_t shapeID = 0;
if (common_attlist_.smil_direction_)
{
}
if (common_attlist_.smil_auto_reverse_)
autoRev = common_attlist_.smil_auto_reverse_->get() == true ? L"1" : L"0";
if (common_attlist_.smil_restart_)
{
}
if (common_attlist_.smil_dur_)
{
duration = common_attlist_.smil_dur_->get_value();
}
if (common_attlist_.smil_begin_)
{
delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value());
}
if (common_attlist_.smil_end_)
{
}
if (common_attlist_.smil_fill_)
{
fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), false);
}
if (common_attlist_.smil_target_element_)
{
shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value());
}
if (common_attlist_.smil_attribute_name_)
{
attribute_name = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value());
}
if (set_attlist_.smil_to_)
{
if (set_attlist_.smil_to_.value() == L"visible")
to_value = L"visible";
else if (set_attlist_.smil_to_.value() == L"hidden")
to_value = L"hidden";
else if (set_attlist_.smil_to_.value() == L"solid")
to_value = L"solid";
else if (set_attlist_.smil_to_.value() == L"false")
to_value = L"false";
else if (set_attlist_.smil_to_.value() == L"true")
to_value = L"true";
else
{
try
{
to_value = std::to_wstring(boost::lexical_cast<double>(set_attlist_.smil_to_.value()));
}
catch (const boost::bad_lexical_cast& e)
{
// Ignore
}
}
}
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
animationContext.start_set();
if (direction) animationContext.set_set_direction(direction.value());
if (restart) animationContext.set_set_restart(restart.value());
if (duration) animationContext.set_set_duration(duration.value());
if (delay) animationContext.set_set_delay(delay.value());
if (end) animationContext.set_set_end(end.value());
if (autoRev) animationContext.set_set_auto_rev(autoRev.value());
if (fill) animationContext.set_set_fill(fill.value());
if (attribute_name) animationContext.set_set_attribute_name(attribute_name.value());
if (to_value) animationContext.set_set_to_value(to_value.value());
animationContext.set_set_shape_id(shapeID);
animationContext.end_set();
}
void anim_set::add_attributes(const xml::attributes_wc_ptr& Attributes)
{
common_attlist_.add_attributes(Attributes);
set_attlist_.add_attributes(Attributes);
}
////////////////////////////////////////////////////////////////
const wchar_t* anim_animate_motion::ns = L"anim";
const wchar_t* anim_animate_motion::name = L"animateMotion";
void anim_animate_motion::pptx_convert(oox::pptx_conversion_context& Context)
{
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
size_t shapeID = 0;
_CP_OPT(std::wstring) path;
_CP_OPT(std::wstring) fill;
if (common_attlist_.smil_target_element_)
shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value());
if (animate_motion_attlist_.svg_path_)
{
std::vector<::svg_path::_polyline> polylines;
bool closed, stroked;
::svg_path::parseSvgD(polylines, animate_motion_attlist_.svg_path_.value(), false, closed, stroked);
path = pptx_convert_svg_path(polylines);
}
if (common_attlist_.smil_fill_)
{
fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), false);
}
animationContext.start_animate_motion();
// if (common_attlist_.presentation_node_type_) animationContext.set_animate_motion_presentation_node_type(common_attlist_.presentation_node_type_.value());
// if (common_attlist_.smil_direction_) animationContext.set_animate_motion_direction(common_attlist_.smil_direction_.value());
// if (common_attlist_.smil_restart_) animationContext.set_animate_motion_restart(common_attlist_.smil_restart_.value());
if (common_attlist_.smil_dur_) animationContext.set_animate_motion_dur(common_attlist_.smil_dur_.value().get_value());
// if (common_attlist_.smil_begin_) animationContext.set_animate_motion_delay(common_attlist_.smil_begin_.value());
// if (common_attlist_.smil_end_) animationContext.set_animate_motion_end(common_attlist_.smil_end_.value());
if (fill) animationContext.set_animate_motion_fill(fill.value());
if (path) animationContext.set_animate_motion_svg_path(path.value());
animationContext.set_animate_motion_shape_id(shapeID);
animationContext.end_animate_motion();
}
void anim_animate_motion::add_attributes(const xml::attributes_wc_ptr& Attributes)
{
common_attlist_.add_attributes(Attributes);
animate_motion_attlist_.add_attributes(Attributes);
}
////////////////////////////////////////////////////////////////
const wchar_t* anim_animate_color::ns = L"anim";
const wchar_t* anim_animate_color::name = L"animateColor";
void anim_animate_color::pptx_convert(oox::pptx_conversion_context& Context)
{
_CP_OPT(std::wstring) colorSpace = std::wstring(L"rgb");
_CP_OPT(int) duration;
_CP_OPT(std::wstring) delay;
_CP_OPT(std::wstring) attributeName;
_CP_OPT(std::wstring) toValue;
_CP_OPT(std::wstring) byValue;
_CP_OPT(std::wstring) fill = std::wstring(L"hold");
_CP_OPT(bool) autoRev = false;
_CP_OPT(std::wstring) dir = std::wstring(L"cw"); // clockwise (cw)
size_t shapeID = 0;
if (animate_color_attlist_.anim_color_interpolation_)
{
colorSpace = animate_color_attlist_.anim_color_interpolation_.value();
}
if (animate_color_attlist_.anim_color_interpolation_direction)
{
if (animate_color_attlist_.anim_color_interpolation_direction.value() == L"clockwise")
dir = L"cw";
else if (animate_color_attlist_.anim_color_interpolation_direction.value() == L"counter-clockwise")
dir = L"ccw";
}
if (common_attlist_.smil_dur_)
duration = common_attlist_.smil_dur_->get_value();
else
duration = 1;
if (common_attlist_.smil_fill_)
{
bool durationSpecified = common_attlist_.smil_dur_.has_value() || common_attlist_.smil_end_.has_value();
fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), durationSpecified);
}
if (common_attlist_.smil_begin_)
delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value());
if (common_attlist_.smil_attribute_name_)
attributeName = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value());
if (animate_color_attlist_.smil_to_)
{
toValue = animate_color_attlist_.smil_to_.value();
boost::erase_all(toValue.value(), L"#");
}
if (common_attlist_.smil_auto_reverse_)
autoRev = common_attlist_.smil_auto_reverse_->get();
if (animate_color_attlist_.smil_by_)
byValue = animate_color_attlist_.smil_by_.value();
if (common_attlist_.smil_target_element_)
shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value());
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
animationContext.start_animate_color();
if (colorSpace) animationContext.set_animate_color_color_space(colorSpace.value());
if (duration) animationContext.set_animate_color_duration(duration.value());
if (delay) animationContext.set_animate_color_delay(delay.value());
if (attributeName) animationContext.set_animate_color_attribute_name(attributeName.value());
if (toValue) animationContext.set_animate_color_to_value(toValue.value());
if (byValue) animationContext.set_animate_color_by_value(byValue.value());
if (autoRev) animationContext.set_animate_color_auto_rev(autoRev.value());
if (dir) animationContext.set_animate_color_dir(dir.value());
if (fill) animationContext.set_animate_color_fill(fill.value());
animationContext.set_animate_color_shape_id(shapeID);
animationContext.end_animate_color();
}
void anim_animate_color::add_attributes(const xml::attributes_wc_ptr& Attributes)
{
common_attlist_.add_attributes(Attributes);
animate_color_attlist_.add_attributes(Attributes);
}
//////////////////////////////////////////////////////////////////////////
// anim:animate
const wchar_t* anim_animate::ns = L"anim";
const wchar_t* anim_animate::name = L"animate";
void anim_animate::pptx_convert(oox::pptx_conversion_context& Context)
{
_CP_OPT(std::wstring) calcmode;
_CP_OPT(std::wstring) valueType;
_CP_OPT(int) duration;
_CP_OPT(std::wstring) attributeName;
size_t shapeID = 0;
_CP_OPT(std::wstring) from;
_CP_OPT(std::wstring) to;
_CP_OPT(std::wstring) by;
_CP_OPT(std::wstring) additive;
_CP_OPT(bool) autoRev;
_CP_OPT(std::wstring) delay;
_CP_OPT(std::wstring) formula;
std::vector<std::wstring> values;
std::vector<int> keyTimes;
if (animate_attlist_.smil_calc_mode_)
{
if (animate_attlist_.smil_calc_mode_.value() == L"discrete") calcmode = L"discrete";
else calcmode = L"lin";
}
else
calcmode = L"lin";
valueType = L"num";
duration = common_attlist_.smil_dur_ ? common_attlist_.smil_dur_->get_value() : 1;
if (common_attlist_.smil_attribute_name_)
{
attributeName = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value());
}
if (common_attlist_.smil_target_element_)
shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value());
if (animate_attlist_.smil_values_)
values = pptx_convert_smil_values(animate_attlist_.smil_values_.value());
if (animate_attlist_.smil_key_times_)
keyTimes = pptx_convert_smil_key_times(animate_attlist_.smil_key_times_.value());
if (animate_attlist_.anim_formula_)
formula = pptx_convert_animation_function(animate_attlist_.anim_formula_.value());
if (animate_attlist_.smil_from_)
from = pptx_convert_animation_function(animate_attlist_.smil_from_.value());
if (animate_attlist_.smil_to_)
to = pptx_convert_animation_function(animate_attlist_.smil_to_.value());
if (animate_attlist_.smil_by_)
by = pptx_convert_animation_function(animate_attlist_.smil_by_.value());
if (animate_attlist_.smil_additive_)
{
switch (animate_attlist_.smil_additive_.value().get_type())
{
case odf_types::smil_additive::replace: additive = L"repl";
case odf_types::smil_additive::sum: additive = L"sum";
default: additive = L"repl";
}
}
else
additive = L"repl";
if (animate_attlist_.smil_auto_reverse_)
{
autoRev = animate_attlist_.smil_auto_reverse_.value().get();
}
if (common_attlist_.smil_begin_)
{
delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value());
}
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
animationContext.start_animate();
if (calcmode) animationContext.set_animate_calc_mode(calcmode.value());
if (valueType) animationContext.set_animate_value_type(valueType.value());
if (duration) animationContext.set_animate_duration(duration.value());
if (attributeName) animationContext.set_animate_attribute_name(attributeName.value());
if (from) animationContext.set_animate_from(from.value());
if (to) animationContext.set_animate_to(to.value());
if (by) animationContext.set_animate_by(by.value());
if (additive) animationContext.set_animate_additive(additive.value());
if (autoRev) animationContext.set_animate_auto_reverse(autoRev.value());
if (delay) animationContext.set_animate_delay(delay.value());
animationContext.set_animate_shape_id(shapeID);
if (keyTimes.size() == values.size())
{
size_t size = keyTimes.size();
for (size_t i = 0; i < size; i++)
{
animationContext.add_animate_keypoint(keyTimes[i], values[i], formula);
}
}
animationContext.end_animate();
}
void anim_animate::add_attributes(const xml::attributes_wc_ptr& Attributes)
{
common_attlist_.add_attributes(Attributes);
animate_attlist_.add_attributes(Attributes);
}
//////////////////////////////////////////////////////////////////////////
// anim:animateTransform
const wchar_t* anim_animate_transform::ns = L"anim";
const wchar_t* anim_animate_transform::name = L"animateTransform";
static std::vector<int> smil_list_to_oox_vector(const std::wstring& list, int pptx_mulipier)
{
std::vector<int> oox_list;
std::vector<std::wstring> list_str;
boost::split(list_str, list, boost::is_any_of(","));
for (const auto& el : list_str)
{
try
{
int num = boost::lexical_cast<double>(el) * pptx_mulipier;
oox_list.push_back(num);
}
catch (boost::bad_lexical_cast e)
{
continue;
}
}
return oox_list;
}
void anim_animate_transform::pptx_convert(oox::pptx_conversion_context& Context)
{
size_t shapeID = 0;
_CP_OPT(int) duration;
_CP_OPT(std::wstring) fill;
_CP_OPT(std::wstring) delay;
_CP_OPT(bool) autoRev;
_CP_OPT(int) by;
_CP_OPT(std::wstring) attributeName;
if(common_attlist_.smil_target_element_)
shapeID = Context.get_slide_context().get_id(common_attlist_.smil_target_element_.value());
if (common_attlist_.smil_dur_)
duration = common_attlist_.smil_dur_.value().get_value();
if (common_attlist_.smil_fill_)
{
bool durationSpecified = common_attlist_.smil_dur_.has_value() || common_attlist_.smil_end_.has_value();
fill = pptx_convert_smil_fill(common_attlist_.smil_fill_.value(), durationSpecified);
}
if (common_attlist_.smil_attribute_name_)
attributeName = pptx_convert_smil_attribute_name(common_attlist_.smil_attribute_name_.value());
if (common_attlist_.smil_begin_)
delay = pptx_convert_smil_begin(common_attlist_.smil_begin_.value());
if (animate_transform_attlist_.smil_auto_reverse_)
autoRev = animate_transform_attlist_.smil_auto_reverse_.value().get();
if (animate_transform_attlist_.svg_type_)
{
oox::pptx_animation_context& animationContext = Context.get_slide_context().get_animation_context();
switch (animate_transform_attlist_.svg_type_->get_type())
{
case odf_types::svg_type::scale:
{
animationContext.start_animate_scale();
animationContext.set_animate_scale_shape_id(shapeID);
if (duration) animationContext.set_animate_scale_duration(duration.value());
if (fill) animationContext.set_animate_scale_fill(fill.value());
if (delay) animationContext.set_animate_scale_delay(delay.value());
if (attributeName) animationContext.set_animate_scale_attribute_name(attributeName.value());
if (autoRev) animationContext.set_animate_scale_auto_reverse(autoRev.value());
if (animate_transform_attlist_.smil_from_)
{
const int pptx_mulipier = 100000;
const std::vector<int> oox_from = smil_list_to_oox_vector(animate_transform_attlist_.smil_from_.value(), pptx_mulipier);
if (oox_from.size() >= 2)
animationContext.set_animate_scale_from(oox_from[0], oox_from[1]);
else
_CP_LOG << "[ warning ] cannot convert scale smil:from";
}
if (animate_transform_attlist_.smil_to_)
{
const int pptx_mulipier = 100000;
const std::vector<int> oox_to = smil_list_to_oox_vector(animate_transform_attlist_.smil_to_.value(), pptx_mulipier);
if (oox_to.size() >= 2)
animationContext.set_animate_scale_to(oox_to[0], oox_to[1]);
else
_CP_LOG << "[ warning ] cannot convert scale smil:to";
}
if (animate_transform_attlist_.smil_by_)
{
const int pptx_mulipier = 100000;
const std::vector<int> oox_by = smil_list_to_oox_vector(animate_transform_attlist_.smil_by_.value(), pptx_mulipier);
if (oox_by.size() >= 2)
animationContext.set_animate_scale_by(oox_by[0] + pptx_mulipier, oox_by[1] + pptx_mulipier);
else
_CP_LOG << "[ warning ] cannot convert scale smil:by";
}
animationContext.end_animate_scale();
break;
}
case odf_types::svg_type::rotate:
{
if (animate_transform_attlist_.smil_by_)
{
try
{
const int pptx_muliplier = 60000;
by = boost::lexical_cast<double>(animate_transform_attlist_.smil_by_.value()) * pptx_muliplier;
}
catch (...)
{
by = 0;
}
}
animationContext.start_animate_rotate();
animationContext.set_animate_rotate_shape_id(shapeID);
if (duration) animationContext.set_animate_rotate_duration(duration.value());
if (fill) animationContext.set_animate_rotate_fill(fill.value());
if (delay) animationContext.set_animate_rotate_delay(delay.value());
if (autoRev) animationContext.set_animate_rotate_auto_reverse(autoRev.value());
if (by) animationContext.set_animate_rotate_by(by.value());
if (attributeName) animationContext.set_animate_rotate_attribute_name(attributeName.value());
animationContext.end_animate_rotate();
break;
}
}
}
}
void anim_animate_transform::add_attributes(const xml::attributes_wc_ptr& Attributes)
{
common_attlist_.add_attributes(Attributes);
animate_transform_attlist_.add_attributes(Attributes);
}
}
}