Files
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

983 lines
24 KiB
C++

/*
* (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 <boost/algorithm/string.hpp>
#include "oox_drawing.h"
#include <xml/simple_xml_writer.h>
#include "../../DataTypes/custom_shape_types_convert.h"
#include "../Format/style_graphic_properties.h"
using namespace cpdoccore;
namespace svg_path
{
void oox_serialize(std::wostream& strm, std::vector<std::pair<std::wstring, std::wstring>>& equations)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"a:gdLst")
{
for (auto equation : equations)
{
CP_XML_NODE(L"a:gd")
{
CP_XML_ATTR(L"name", equation.first);
CP_XML_ATTR(L"fmla", equation.second);
}
}
}
}
}
void oox_serialize(std::wostream& strm, std::vector<_polylineS>& path)
{
CP_XML_WRITER(strm)
{
for (size_t i = 0; i < path.size(); i++)
{
oox_serialize(strm, path[i]);
}
}
}
void oox_serialize(std::wostream& strm, _polylineS& val)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(val.command)
{
if (val.command == L"a:arcTo")
{
if (val.points.size() > 0)
{
CP_XML_ATTR(L"wR", val.points[0].x.get());
CP_XML_ATTR(L"hR", val.points[0].y.get());
}
if (val.points.size() > 1)
{
CP_XML_ATTR(L"stAng", val.points[1].x.get());
CP_XML_ATTR(L"swAng", val.points[1].y.get());
}
}
else
{
for (size_t i = 0; i < val.points.size(); i++)
{
oox_serialize(CP_XML_STREAM(), val.points[i]);
}
}
}
}
}
void oox_serialize(std::wostream& strm, _pointS& val)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"a:pt")
{
if (val.x) CP_XML_ATTR(L"x", val.x.get());
if (val.y) CP_XML_ATTR(L"y", val.y.get());
}
}
}
void oox_serialize(std::wostream& strm, std::vector<_polyline>& path)
{
CP_XML_WRITER(strm)
{
for (size_t i = 0; i < path.size(); i++)
{
oox_serialize(strm, path[i]);
}
}
}
void oox_serialize(std::wostream & strm, _polyline & val)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(val.command)
{
if (val.command == L"a:ArcTo")
{
if (val.points.size() > 0)
{
CP_XML_ATTR(L"wR", (int)(val.points[0].x.get()));
CP_XML_ATTR(L"hR", (int)(val.points[0].y.get()));
}
if (val.points.size() > 1)
{
CP_XML_ATTR(L"stAng", (int)(val.points[1].x.get() * 60000));
CP_XML_ATTR(L"swAng", (int)(val.points[1].y.get() * 60000));
}
}
else
{
for (size_t i = 0; i < val.points.size(); i++)
{
oox_serialize(CP_XML_STREAM(), val.points[i]);
}
}
}
}
}
void oox_serialize(std::wostream & strm, _point & val)
{
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"a:pt")
{
if (val.x)CP_XML_ATTR(L"x", (int)(val.x.get()));
if (val.y)CP_XML_ATTR(L"y", (int)(val.y.get()));
}
}
}
}
namespace cpdoccore {
static const std::wstring _ooxShapeType[]=
{
L"rect", //frame
L"rect", //text box
L"rect", //shape
L"ellipse",
L"ellipse",
L"line",
L"path",
L"custGeom",//uses sub-sub type,
L"polygon",
L"roundRect",
L"bentConnector3",
L"curvedConnector3",
L"",//3-D shape
L"",
L"polyline",
L"cube",
L"ellipse", //sphere
L""
};
namespace oox {
static const std::wstring _ooxDashStyle[]=
{
L"none",
L"solid",
L"dot",
L"dash",
L"dash",
L"dashDot",
L"sysDashDotDot"
L"solid",
L"solid",
L"solid",
L"solid",
L"solid",
L"none",
L"dash",
L"solid"
};
static const std::wstring _vmlDashStyle[]=
{
L"none",
L"solid",
L"dot",
L"dash",
L"dash",
L"dashdot",
L"shortdashdotdot",
L"solid",
L"solid",
L"solid",
L"solid",
L"solid",
L"none",
L"dash",
L"solid"
};
void oox_serialize_effects(std::wostream & strm, const std::vector<odf_reader::_property> & prop)
{
_CP_OPT(bool) bShadow;
_CP_OPT(std::wstring) strShadowColor;
_CP_OPT(double) dShadowOpacity;
_CP_OPT(double) dShadowOffsetX;
_CP_OPT(double) dShadowOffsetY;
odf_reader::GetProperty(prop, L"shadow", bShadow);
odf_reader::GetProperty(prop, L"shadow-color", strShadowColor);
odf_reader::GetProperty(prop, L"shadow-opacity", dShadowOpacity);
odf_reader::GetProperty(prop, L"shadow-offset-x", dShadowOffsetX);
odf_reader::GetProperty(prop, L"shadow-offset-y", dShadowOffsetY);
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"a:effectLst")
{
if ((bShadow) && (*bShadow))
{
CP_XML_NODE(L"a:outerShdw")
{
//CP_XML_ATTR(L"blurRad", 0);
double offsetX = dShadowOffsetX.get_value_or(0);
double offsetY = dShadowOffsetY.get_value_or(0);
double dist = sqrt(offsetX * offsetX + offsetY * offsetY);
double dir = (offsetX != 0) ? atan(offsetY / offsetX) * 180. / 3.1415926 : 0;
if (offsetX < 0) dir += 180;
if (dir < 0) dir += 360;
CP_XML_ATTR(L"dist", (int)(dist));
CP_XML_ATTR(L"dir", (int)(dir * 60000));
CP_XML_ATTR(L"algn", L"tl");
CP_XML_NODE(L"a:srgbClr")
{
if (strShadowColor)
{
CP_XML_ATTR(L"val", *strShadowColor);
}
else
{
CP_XML_ATTR(L"val", L"000000");
}
if (dShadowOpacity)
{
CP_XML_NODE(L"a:alpha")
{
CP_XML_ATTR(L"val", (int)(*dShadowOpacity * 1000));
}
}
}
}
}
}
}
}
void oox_serialize_ln(std::wostream & strm, const odf_reader::graphic_format_properties_ptr & val, bool always_draw, const std::wstring &ns)
{
std::vector<odf_reader::_property> prop;
if (val)
val->apply_to(prop);
oox_serialize_ln(strm, prop, always_draw, ns);
}
void vml_serialize_ln(std::wostream & strm, const odf_reader::graphic_format_properties_ptr & val)
{
std::vector<odf_reader::_property> prop;
if (val)
val->apply_to(prop);
vml_serialize_ln(strm, prop);
}
void oox_serialize_ln(std::wostream & strm, const std::vector<odf_reader::_property> & prop, bool always_draw, const std::wstring &ns)
{
std::wstring ns_att = (ns == L"a" ? L"" : ns + L":");
std::wstring ns_node = L"a:ln";
if (ns == L"w14")
ns_node = L"w14:textOutline";
_CP_OPT(std::wstring) sStrokeGradient;
_CP_OPT(std::wstring) strStrokeColor;
_CP_OPT(int) iStroke;
_CP_OPT(double) dStrokeWidth;
_CP_OPT(double) dStrokeOpacity;
_CP_OPT(bool) bWordArt;
odf_reader::GetProperty(prop, L"wordArt", bWordArt);
odf_reader::GetProperty(prop, L"stroke-color" , strStrokeColor);
odf_reader::GetProperty(prop, L"stroke" , iStroke);
odf_reader::GetProperty(prop, L"stroke-width" , dStrokeWidth);
odf_reader::GetProperty(prop, L"stroke-opacity" , dStrokeOpacity);
odf_reader::GetProperty(prop, L"stroke-gradient-name", sStrokeGradient);
if ((!strStrokeColor && !iStroke && !dStrokeWidth) && !always_draw) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(ns_node)
{
std::wstring color, dash_style, fill = ns + L":solidFill" ;
if (strStrokeColor) color = *strStrokeColor;
if (iStroke)
{
int Val = iStroke.get();
if (Val == 0 || bWordArt) fill = ns + L":noFill";
else if (Val < sizeof(_ooxDashStyle))
{
dash_style = _ooxDashStyle[Val];
}
}
if ((dStrokeWidth) && (*dStrokeWidth >= 0) && fill != ns + L":noFill")
{
int val = dStrokeWidth.get() * 12700; //in emu (1 pt = 12700)
if (val < 10) val = 0;
CP_XML_ATTR2(ns_att + L"w", val);
if (color.length()<1)color = L"729FCF";
}
CP_XML_NODE(fill)
{
if (fill != ns + L":noFill")
{
if ( color.empty() )
{
if (always_draw) color = L"000000";
else color = L"FFFFFF";
}
CP_XML_NODE(ns + L":srgbClr")
{
CP_XML_ATTR2(ns_att + L"val", color);
if (dStrokeOpacity)
{
CP_XML_NODE(ns + L":alpha")
{
CP_XML_ATTR2(ns_att + L"val", (int)(*dStrokeOpacity * 1000));
}
}
}
}
}
if (fill != ns + L":noFill")
{
_CP_OPT(std::wstring) strVal;
if (dash_style.length() > 0 && dash_style != L"solid")
{
CP_XML_NODE(ns + L":prstDash")
{
CP_XML_ATTR2(ns_att + L"val", dash_style);
}
}
odf_reader::GetProperty(prop,L"marker-start", strVal);
if (strVal)
{
CP_XML_NODE(ns + L":headEnd")
{
CP_XML_ATTR2(ns_att + L"type", strVal.get());
_CP_OPT(double) dWidth;
odf_reader::GetProperty(prop, L"marker-start-width", dWidth);
if (dWidth && dStrokeWidth)
{
double kf = *dWidth / *dStrokeWidth;
if (kf > 3.5) CP_XML_ATTR2(ns_att + L"w", L"lg");
else if (kf < 2.6) CP_XML_ATTR2(ns_att + L"w", L"sm");
else CP_XML_ATTR2(ns_att + L"w", L"med");
}
}
}
odf_reader::GetProperty(prop,L"marker-end", strVal);
if (strVal)
{
CP_XML_NODE(ns + L":tailEnd")
{
CP_XML_ATTR2(ns_att + L"type", strVal.get());
_CP_OPT(double) dWidth;
odf_reader::GetProperty(prop, L"marker-start-width", dWidth);
if (dWidth && dStrokeWidth)
{
double kf = *dWidth / *dStrokeWidth;
if (kf > 3.5) CP_XML_ATTR2(ns_att + L"w", L"lg");
else if (kf < 2.6) CP_XML_ATTR2(ns_att + L"w", L"sm");
else CP_XML_ATTR2(ns_att + L"w", L"med");
}
}
}
}
}
}
}
void vml_serialize_text(std::wostream & strm, const std::vector<odf_reader::_property> & prop)
{
_CP_OPT(std::wstring) strTextContent;
odf_reader::GetProperty(prop, L"text-content", strTextContent);
CP_XML_WRITER(strm)
{
if (strTextContent)
{
CP_XML_NODE(L"v:textbox")
{
CP_XML_ATTR(L"style", L"mso-direction-alt:auto");
CP_XML_ATTR(L"o:singleclick", L"f");
CP_XML_NODE(L"div")
{
CP_XML_ATTR(L"style", L"text-align:left");
CP_XML_NODE(L"font")
{
CP_XML_ATTR(L"face", L"Segoe UI");
CP_XML_ATTR(L"size", L"160");
CP_XML_ATTR(L"color", L"#000000");
const std::wstring & test_string = strTextContent.get();
CP_XML_STREAM() << test_string;
}
}
}
}
}
}
void vml_serialize_ln(std::wostream & strm, const std::vector<odf_reader::_property> & prop)
{
_CP_OPT(std::wstring) strStrokeColor;
_CP_OPT(int) iStroke;
_CP_OPT(double) dStrokeWidth;
_CP_OPT(double) dStrokeOpacity;
_CP_OPT(bool) bWordArt;
odf_reader::GetProperty(prop, L"wordArt", bWordArt);
odf_reader::GetProperty(prop, L"stroke-color" , strStrokeColor);
odf_reader::GetProperty(prop, L"stroke" , iStroke);
odf_reader::GetProperty(prop, L"stroke-width" , dStrokeWidth);
odf_reader::GetProperty(prop, L"stroke-opacity" , dStrokeOpacity);
if (!strStrokeColor && !iStroke && !dStrokeWidth) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"v:stroke")
{
std::wstring color, dash_style ;
if (strStrokeColor) color = *strStrokeColor;
if (iStroke)
{
if (iStroke.get() != 0 ) dash_style = _vmlDashStyle[iStroke.get()];
}
if ((dStrokeWidth) && (*dStrokeWidth >= 0))
{
int val = dStrokeWidth.get() * 12700; //in emu (1 pt = 12700)
if (val < 10) val = 12700;
CP_XML_ATTR(L"weight", val);
}
if (false == color.empty())
{
CP_XML_ATTR(L"color", L"#" + color);
}
if (!dash_style.empty() && dash_style != L"solid")
{
CP_XML_ATTR(L"dashstyle", dash_style);
}
//odf_reader::GetProperty(prop,L"marker-start", strVal);
//if (strVal)
//{
//}
//odf_reader::GetProperty(prop,L"marker-end",strVal);
//if (strVal)
//{
//}
CP_XML_ATTR(L"startarrow", L"block");
CP_XML_ATTR(L"startarrowwidth", L"medium");
CP_XML_ATTR(L"startarrowlength", L"medium");
CP_XML_ATTR(L"joinstyle", L"round");
CP_XML_ATTR(L"endcap", L"flat");
}
}
}
void oox_serialize_aLst(std::wostream & strm, const std::vector<odf_reader::_property> & prop, const std::wstring & shapeGeomPreset, int max_count_values, const std::wstring &ns)
{
std::wstring ns_att = (ns == L"a" ? L"" : ns + L":");
CP_XML_WRITER(strm)
{
CP_XML_NODE(ns + L":avLst")
{
_CP_OPT(std::wstring) strModifiers;
odf_reader::GetProperty(prop, L"oox-draw-modifiers", strModifiers);
if (strModifiers)
{
std::vector< std::wstring > values;
boost::algorithm::split(values, strModifiers.get(), boost::algorithm::is_any_of(L" "), boost::algorithm::token_compress_on);
if (!values.empty() && values.back().empty()) values.pop_back();
std::vector<std::wstring> names;
if (std::wstring::npos != shapeGeomPreset.find(L"math") ||
std::wstring::npos != shapeGeomPreset.find(L"bentConnector") ||
std::wstring::npos != shapeGeomPreset.find(L"curvedConnector")||
std::wstring::npos != shapeGeomPreset.find(L"frame"))
{
names.push_back(L"adj1");
}
//else if (std::wstring::npos != shapeGeomPreset.find(L"heptagon") ||
// std::wstring::npos != shapeGeomPreset.find(L"decagon") ||
// std::wstring::npos != shapeGeomPreset.find(L"bevel"))
//{
// values.clear();
//}
else if (std::wstring::npos != shapeGeomPreset.find(L"decagon"))
{
names.push_back(L"vf");
}
else if (std::wstring::npos != shapeGeomPreset.find(L"pentagon"))
{
names.push_back(L"hf");
names.push_back(L"vf");
}
else if (std::wstring::npos != shapeGeomPreset.find(L"hexagon"))
{
names.push_back(L"adj");
names.push_back(L"vf");
}
else if (std::wstring::npos != shapeGeomPreset.find(L"star5")||
std::wstring::npos != shapeGeomPreset.find(L"star7"))
{
names.push_back(L"adj");
names.push_back(L"hf");
names.push_back(L"vf");
}
else if (std::wstring::npos != shapeGeomPreset.find(L"star6") ||
std::wstring::npos != shapeGeomPreset.find(L"star10"))
{
names.push_back(L"adj");
names.push_back(L"hf");
}
if (max_count_values >= 0 && values.size() > max_count_values)
{
values.resize(max_count_values);
}
for (size_t i = 0; i < values.size(); i++)
{
if (values[i].empty()) continue;
CP_XML_NODE(ns + L":gd")
{
if (names.size() > i)
{
CP_XML_ATTR2(ns_att + L"name", names[i]);
}
else
{
CP_XML_ATTR2(ns_att + L"name", L"adj" + std::to_wstring(i + 1));
}
CP_XML_ATTR2(ns_att + L"fmla", L"val " + values[i]);
}
}
}
}
}
}
void _oox_drawing::serialize_bodyPr(std::wostream & strm, const std::wstring & namespace_)
{
const std::vector<odf_reader::_property> & prop = additional;
_CP_OPT(bool) bWordArt;
odf_reader::GetProperty(prop,L"wordArt", bWordArt);
CP_XML_WRITER(strm)
{
CP_XML_NODE(namespace_ + L":bodyPr")
{
_CP_OPT(double)dPaddingLeft, dPaddingRight, dPaddingTop, dPaddingBottom;
_CP_OPT(int) numCol, spcCol;
_CP_OPT(bool) is_math_formula;
odf_reader::GetProperty(prop,L"text-padding-left" , dPaddingLeft);
odf_reader::GetProperty(prop,L"text-padding-right" , dPaddingRight);
odf_reader::GetProperty(prop,L"text-padding-top" , dPaddingTop);
odf_reader::GetProperty(prop,L"text-padding-bottom" , dPaddingBottom);
odf_reader::GetProperty(prop, L"style_columns_count", numCol);
odf_reader::GetProperty(prop, L"style_columns_gap" , spcCol);
odf_reader::GetProperty(prop, L"is-math-formula", is_math_formula);
if (is_math_formula && *is_math_formula)
{
CP_XML_ATTR(L"lIns", 0);
CP_XML_ATTR(L"tIns", 0);
CP_XML_ATTR(L"rIns", 0);
CP_XML_ATTR(L"bIns", 0);
}
else
{
if (dPaddingLeft) CP_XML_ATTR(L"lIns", (int)(*dPaddingLeft));
if (dPaddingTop) CP_XML_ATTR(L"tIns", (int)(*dPaddingTop));
if (dPaddingRight) CP_XML_ATTR(L"rIns", (int)(*dPaddingRight));
if (dPaddingBottom) CP_XML_ATTR(L"bIns", (int)(*dPaddingBottom));
}
CP_XML_ATTR_OPT(L"numCol" , numCol);
CP_XML_ATTR_OPT(L"spcCol" , spcCol);
if (inGroup == false)
{
_CP_OPT(bool) bAutoGrowWidth;
odf_reader::GetProperty(prop, L"auto-grow-width", bAutoGrowWidth);
if (bAutoGrowWidth)
{
if (*bAutoGrowWidth == true)
CP_XML_ATTR(L"wrap", L"none");
}
else
{
_CP_OPT(int) iWrap;
odf_reader::GetProperty(prop, L"text-wrap", iWrap);
if (((iWrap) && (*iWrap == 0)) || ((is_math_formula) && (*is_math_formula)))
CP_XML_ATTR(L"wrap", L"none");
}
}
_CP_OPT(int) iAlign, iVert;
odf_reader::GetProperty(prop, L"textarea-vertical_align", iAlign);
if (iAlign)
{
switch (iAlign.get())
{
case 0://Baseline,
CP_XML_ATTR(L"anchor", L"dist");break;
case 1://Top,
case 4://Auto,
CP_XML_ATTR(L"anchor", L"t");break;
case 2://Middle,
CP_XML_ATTR(L"anchor", L"ctr");break;
case 3://Bottom,
CP_XML_ATTR(L"anchor", L"b");break;
case 5://Justify
CP_XML_ATTR(L"anchor", L"just");break;
}
}
odf_reader::GetProperty(prop, L"text_vert", iVert);
if (iVert)
{
switch (iVert.get())
{
case 1: CP_XML_ATTR(L"vert", L"vert"); break;
case 2: CP_XML_ATTR(L"vert", L"vert270"); break;
}
}
_CP_OPT(bool) bAutoGrowHeight;
_CP_OPT(bool) bFitToSize;
odf_reader::GetProperty(prop,L"fit-to-size", bFitToSize);
odf_reader::GetProperty(prop,L"auto-grow-height", bAutoGrowHeight);
if ((bAutoGrowHeight) && (*bAutoGrowHeight))
{
CP_XML_NODE(L"a:spAutoFit");
}
else if ((bFitToSize) && (*bFitToSize))
{
CP_XML_NODE(L"a:normAutofit");
//{
// CP_XML_ATTR(L"lnSpcReduction", 10000);
//}
}
//else CP_XML_ATTR(L"anchor", L"dist");break;
if (bWordArt)
{
_CP_OPT(int) iVal;
odf_reader::GetProperty(prop, L"oox-geom-index", iVal);
if (iVal)
{
std::wstring shapeType = _OO_OOX_wordart[*iVal].oox;
CP_XML_NODE(L"a:prstTxWarp")
{
CP_XML_ATTR(L"prst", shapeType);
oox_serialize_aLst(CP_XML_STREAM(), prop, shapeType, _OO_OOX_wordart[*iVal].count_values);
}
}
}
}
}
}
void _oox_drawing::serialize_shape(std::wostream & strm)
{
_CP_OPT(int) iOoxShapeIndex;
_CP_OPT(bool) bWordArt, bOoxShape;
_CP_OPT(std::wstring) sCustomPath, sCustomEquations;
odf_reader::GetProperty(additional, L"wordArt", bWordArt);
odf_reader::GetProperty(additional, L"oox-geom-index", iOoxShapeIndex);
odf_reader::GetProperty(additional, L"oox-geom", bOoxShape);
odf_reader::GetProperty(additional, L"custom_path", sCustomPath);
odf_reader::GetProperty(additional, L"custom_equations", sCustomEquations);
std::wstring shapeGeomPreset;
int max_count_values = -1;
if (sub_type == 7)//custom
{
if (iOoxShapeIndex)
{
shapeGeomPreset = _OO_OOX_custom_shapes[*iOoxShapeIndex].oox;
max_count_values = _OO_OOX_custom_shapes[*iOoxShapeIndex].count_values;
}
else if (sCustomPath)
sub_type = 6; //path
if (shapeGeomPreset == L"textBox")
{
sub_type = 1;
shapeGeomPreset = L"rect";
}
}
else if (sub_type <= 16 && sub_type >= 0)
{
shapeGeomPreset = _ooxShapeType[sub_type]; //odf -> oox
}
if (bWordArt) sub_type = 1;
CP_XML_WRITER(strm)
{
if (connector_prst.empty())
connector = false;
if ((sub_type == 6 || sub_type == 8 || sub_type == 14) && !connector)
{
CP_XML_NODE(L"a:custGeom")
{
std::vector<std::wstring> names;
oox_serialize_aLst(CP_XML_STREAM(), additional, L"");
if (sCustomEquations)
{
CP_XML_STREAM() << L"<a:gdLst>" << *sCustomEquations << L"</a:gdLst>";
}
CP_XML_NODE(L"a:rect")
{
CP_XML_ATTR(L"b", L"b");
CP_XML_ATTR(L"l", 0);
CP_XML_ATTR(L"r", L"r");
CP_XML_ATTR(L"t", 0);
}
//<a:rect b="b" l="0" r="r" t="0"/>
_CP_OPT(int) w, h;
_CP_OPT(bool) stroke;
odf_reader::GetProperty(additional, L"custom_path_w", w);
odf_reader::GetProperty(additional, L"custom_path_h", h);
odf_reader::GetProperty(additional, L"custom_path_s", stroke);
CP_XML_NODE(L"a:pathLst")
{
CP_XML_NODE(L"a:path")
{
int path_w = w ? *w : cx;
int path_h = h ? *h : cy;
if (path_w < 1) path_w = 1024;
if (path_h < 1) path_h = 1024;
CP_XML_ATTR(L"w", path_w);
CP_XML_ATTR(L"h", path_h);
if (stroke)
{
CP_XML_ATTR(L"stroke", *stroke ? 1 : 0);
}
if (sCustomPath)
{
CP_XML_STREAM() << *sCustomPath;
}
}
}
}
}
else
{
if (shapeGeomPreset.empty())
{
shapeGeomPreset = L"rect";
sub_type = 2;
}
if (connector)
{
shapeGeomPreset = connector_prst;
}
CP_XML_NODE(L"a:prstGeom")//автофигура
{
CP_XML_ATTR(L"prst", shapeGeomPreset);
if (!bWordArt)
{
oox_serialize_aLst(CP_XML_STREAM(), additional, shapeGeomPreset, max_count_values);
}
}
}
if (bWordArt || lined)
{
_oox_fill no_fill;
oox_serialize_fill(strm, no_fill);
}
else
oox_serialize_fill(strm, fill);
}
}
void _oox_drawing::serialize_xfrm(std::wostream & strm, const std::wstring & name_space, bool always_position)
{
CP_XML_WRITER(strm)
{
std::wstring xfrm = name_space + L":xfrm";
_CP_OPT(double) dRotate;
odf_reader::GetProperty(additional, L"svg:rotate", dRotate);
_CP_OPT(double) dSkewX;
odf_reader::GetProperty(additional, L"svg:skewX", dSkewX);
_CP_OPT(double) dSkewY;
odf_reader::GetProperty(additional, L"svg:skewY", dSkewY);
CP_XML_NODE(xfrm)
{
if (dRotate)
{
double d = 360 - dRotate.get() * 180. / 3.14159265358979323846;
CP_XML_ATTR(L"rot", (int)( d * 60000) ); //60 000 per 1 gr - 19.5.5 oox
}
_CP_OPT(bool)bVal;
if (odf_reader::GetProperty(additional, L"flipH", bVal))
CP_XML_ATTR(L"flipH", bVal.get());
if (odf_reader::GetProperty(additional,L"flipV", bVal))
CP_XML_ATTR(L"flipV", bVal.get());
CP_XML_NODE(L"a:off")
{
if (inGroup || always_position)
{
CP_XML_ATTR(L"x", x);
CP_XML_ATTR(L"y", y);
}
else
{
CP_XML_ATTR(L"x", 0);
CP_XML_ATTR(L"y", 0);
}
}
if (cx > 0 || cy > 0)
{
CP_XML_NODE(L"a:ext")
{
CP_XML_ATTR(L"cx", cx);
CP_XML_ATTR(L"cy", cy);
}
}else
{
_CP_LOG << L"[error!!!] not set size object\n";
}
if (type == typeGroupShape)
{
CP_XML_NODE(L"a:chOff")
{
CP_XML_ATTR(L"x", 0);
CP_XML_ATTR(L"y", 0);
}
if (cx > 0 || cy > 0)
{
CP_XML_NODE(L"a:chExt")
{
CP_XML_ATTR(L"cx", cx);
CP_XML_ATTR(L"cy", cy);
}
}
}
}
}
}
void oox_serialize_action(std::wostream & strm, _action_desc const & val)
{
if (val.enabled == false) return;
CP_XML_WRITER(strm)
{
CP_XML_NODE(L"a:hlinkClick")
{
if (!val.action.empty())
CP_XML_ATTR(L"action", val.action);
if (val.highlightClick)
CP_XML_ATTR(L"highlightClick", val.highlightClick);
CP_XML_ATTR(L"r:id", val.hId);
if (!val.hSoundId.empty())
{
CP_XML_NODE(L"a:snd")
{
CP_XML_ATTR(L"r:embed", val.hSoundId);
CP_XML_ATTR(L"name", L"sound");
}
}
//CP_XML_ATTR(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships");
//CP_XML_ATTR(L"xmlns:a", L"http://schemas.openxmlformats.org/drawingml/2006/main");
}
}
}
}
}