Merge pull request 'fix/CustomShapePath' (#433) from fix/CustomShapePath into release/v9.1.0

Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/433
This commit is contained in:
Elena Subbotina
2025-09-06 11:54:07 +00:00
8 changed files with 243 additions and 94 deletions

View File

@ -1,12 +1,17 @@
#include "gtest/gtest.h"
#include "../smcustomshapepars.h"
#define LEFT L"0"
#define TOP L"0"
#define RIGHT L"21600"
#define BOTTOM L"21600"
TEST(SMCustomShapeTest,Number)
{
std::wstring wsString =L"45";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"val 45 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -16,9 +21,9 @@ TEST(SMCustomShapeTest,Plus)
std::wstring wsString =L"left+?f2";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"+/ 0 gd2 1 \" />";
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"+/ " + std::wstring(LEFT) + L" gd2 1 \" />" ;
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
}
TEST(SMCustomShapeTest,Minus)
@ -26,9 +31,9 @@ TEST(SMCustomShapeTest,Minus)
std::wstring wsString =L"bottom-?f2 ";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"+- 0 h gd2 \" />";
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"+- 0 " + std::wstring(RIGHT) + L" gd2 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
}
TEST(SMCustomShapeTest,Multi)
@ -36,7 +41,7 @@ TEST(SMCustomShapeTest,Multi)
std::wstring wsString =L"?f1 *3163/7636";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"*/ gd1 3163 7636 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -46,7 +51,7 @@ TEST(SMCustomShapeTest,Divide)
std::wstring wsString =L"10800/cos(pi/8)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1.1.1\" fmla=\"+/ 0 314 100\" /><a:gd name=\"gd35.1.1\" fmla=\"+/ 0 gd35.1.1.1 8 \" /><a:gd name=\"gd35.1\" fmla=\"cos 1 gd35.1.1 \" /><a:gd name=\"gd35\" fmla=\"+/ 0 10800 gd35.1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -56,7 +61,7 @@ TEST(SMCustomShapeTest,Sqrt)
std::wstring wsString =L"*sqrt(2)/2";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"sqrt 2 \" /><a:gd name=\"gd35\" fmla=\"*/ 0 gd35.1 2 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -66,7 +71,7 @@ TEST(SMCustomShapeTest,DoubleBracket)
std::wstring wsString =L"$0 *sin(?f0 *(pi/180))";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1.1.1.1\" fmla=\"+/ 0 314 100\" /><a:gd name=\"gd35.1.1.1\" fmla=\"+/ 0 gd35.1.1.1.1 180 \" /><a:gd name=\"gd35.1.1\" fmla=\"*/ gd0 gd35.1.1.1 1 \" /><a:gd name=\"gd35.1\" fmla=\"sin 1 gd35.1.1 \" /><a:gd name=\"gd35\" fmla=\"*/ $0 gd35.1 1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -76,7 +81,7 @@ TEST(SMCustomShapeTest,Min)
std::wstring wsString =L"min(?f36+25,?f37/2)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"+/ gd36 25 1 \" /><a:gd name=\"gd35.2\" fmla=\"+/ 0 gd37 2 \" /><a:gd name=\"gd35\" fmla=\"min gd35.1 gd35.2 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -86,7 +91,7 @@ TEST(SMCustomShapeTest,Max)
std::wstring wsString =L"max(?f36,2)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"max gd36 2 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -96,7 +101,7 @@ TEST(SMCustomShapeTest,Abs)
std::wstring wsString =L"abs(?f2+?f3)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"+/ gd2 gd3 1 \" /><a:gd name=\"gd35\" fmla=\"abs gd35.1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -106,7 +111,7 @@ TEST(SMCustomShapeTest,Sin)
std::wstring wsString =L"sin(26500)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"sin 1 26500 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -116,7 +121,7 @@ TEST(SMCustomShapeTest,Cos)
std::wstring wsString =L"cos(45/?f40)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"+/ 0 45 gd40 \" /><a:gd name=\"gd35\" fmla=\"cos 1 gd35.1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -126,7 +131,7 @@ TEST(SMCustomShapeTest,IF)
std::wstring wsString =L"if(2+?f1,26500/sqrt(2),min(?f35,?f37))";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"+/ 2 gd1 1 \" /><a:gd name=\"gd35.2.1\" fmla=\"sqrt 2 \" /><a:gd name=\"gd35.2\" fmla=\"+/ 0 26500 gd35.2.1 \" /><a:gd name=\"gd35.3\" fmla=\"min gd35 gd37 \" /><a:gd name=\"gd35\" fmla=\"?: gd35.1 gd35.2 gd35.3 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -136,7 +141,7 @@ TEST(SMCustomShapeTest,Tan)
std::wstring wsString =L"tan(?f40*?f41)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"*/ gd40 gd41 1 \" /><a:gd name=\"gd35\" fmla=\"tan 1 gd35.1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -146,7 +151,7 @@ TEST(SMCustomShapeTest,ComplexEquation)
std::wstring wsString =L"sqrt(?f36 * ?f36 + ?f39 * ?f39 + 0 * 0)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1.1.1\" fmla=\"*/ gd36 gd36 1 \" /><a:gd name=\"gd35.1.1.2\" fmla=\"*/ gd39 gd39 1 \" /><a:gd name=\"gd35.1.1\" fmla=\"+/ gd35.1.1.1 gd35.1.1.2 1 \" /><a:gd name=\"gd35.1.2\" fmla=\"*/ 0 0 1 \" /><a:gd name=\"gd35.1\" fmla=\"+/ gd35.1.1 gd35.1.2 1 \" /><a:gd name=\"gd35\" fmla=\"sqrt gd35.1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -156,7 +161,7 @@ TEST(SMCustomShapeTest,Atan)
std::wstring wsString =L"atan(25/5)";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35.1\" fmla=\"+/ 0 25 5 \" /><a:gd name=\"gd35\" fmla=\"at2 1 gd35.1 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -166,7 +171,7 @@ TEST(SMCustomShapeTest,PlusSecondMinusEmpty)
std::wstring wsString =L"+1-";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"+- 0 1 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -176,7 +181,7 @@ TEST(SMCustomShapeTest,SinWithoutBracket)
std::wstring wsString =L"sin";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"sqrt 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -186,7 +191,7 @@ TEST(SMCustomShapeTest,SinEmpty)
std::wstring wsString =L"sin()";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"sin 1 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -196,7 +201,7 @@ TEST(SMCustomShapeTest,MaxEmpty)
std::wstring wsString =L"max()";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"max 0 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -206,7 +211,7 @@ TEST(SMCustomShapeTest,IfEmpty)
std::wstring wsString =L"if()";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"?: 0 0 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -216,7 +221,7 @@ TEST(SMCustomShapeTest,AbsEmpty)
std::wstring wsString =L"abs()";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"abs 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);
@ -226,7 +231,7 @@ TEST(SMCustomShapeTest,PlusFirstMinusEmpty)
std::wstring wsString =L"1+-";
OdfCustomShape::SMCustomShapePars oPars;
OdfCustomShape::SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(wsString);
oPars.StartParsSMCustomShape(wsString,LEFT,TOP,RIGHT,BOTTOM);
oConvers.StartConversion(oPars.GetVector(),L"gd35");
std::wstring wsXmlString = L"<a:gd name=\"gd35\" fmla=\"+- 1 0 0 \" />";
EXPECT_EQ(oConvers.GetStringXml(),wsXmlString);

View File

@ -33,14 +33,14 @@
namespace OdfCustomShape
{
std::wstring convert_formula(const std::wstring& odf_formula, const std::wstring& name)
std::wstring convert_formula(const std::wstring& odf_formula, const std::wstring& name,const std::wstring& wsLeft,const std::wstring& wsTop,const std::wstring& wsRight,const std::wstring& wsBottom)
{
SMCustomShapePars oPars;
SMCustomShapeConversion oConvers;
oPars.StartParsSMCustomShape(odf_formula);
oPars.StartParsSMCustomShape(odf_formula,wsLeft,wsTop,wsRight,wsBottom);
oConvers.StartConversion(oPars.GetVector(), name);
return oConvers.GetStringXml();
}
}
}

View File

@ -32,5 +32,5 @@
#pragma once
namespace OdfCustomShape
{
std::wstring convert_formula(const std::wstring& odf_formula, const std::wstring& name);
}
std::wstring convert_formula(const std::wstring& odf_formula, const std::wstring& name, const std::wstring& wsLeft,const std::wstring& wsTop,const std::wstring& wsRight,const std::wstring& wsBottom);
}

View File

@ -40,9 +40,9 @@ namespace OdfCustomShape
for(CElement* pElement:m_arVecElements)
delete pElement;
}
void SMCustomShapePars::StartParsSMCustomShape(const std::wstring & wsFormula)
void SMCustomShapePars::StartParsSMCustomShape(const std::wstring & wsFormula, const std::wstring& wsLeft,const std::wstring& wsTop,const std::wstring& wsRight,const std::wstring& wsBottom)
{
CSMReader* pReader = new CSMReader(wsFormula);
CSMReader* pReader = new CSMReader(wsFormula,wsLeft,wsTop,wsRight,wsBottom);
SMCustomShapePars::ParsString(pReader, m_arVecElements);
return;
}
@ -143,12 +143,19 @@ namespace OdfCustomShape
{
if(!pReader->GetElement().empty())
pReader->ClearElement();
if(m_wsNumber == L"width" || m_wsNumber == L"top")
m_wsNumber = L"w";
else if(m_wsNumber == L"height" || m_wsNumber == L"bottom")
if(m_wsNumber == L"left")
m_wsNumber = pReader->GetLeft() != L"" ? pReader->GetLeft():L"l";
else if(m_wsNumber == L"top")
m_wsNumber = pReader->GetTop() != L"" ? pReader->GetTop():L"t";
else if(m_wsNumber == L"right")
m_wsNumber = pReader->GetRight() != L"" ? pReader->GetRight():L"r";
else if(m_wsNumber == L"bottom")
m_wsNumber = pReader->GetBottom() != L"" ? pReader->GetBottom():L"b";
/*The height and width may be different*/
else if(m_wsNumber == L"height")
m_wsNumber = L"h";
else if(m_wsNumber == L"right" || m_wsNumber == L"left")
m_wsNumber = L"0";
else if(m_wsNumber == L"width")
m_wsNumber = L"w";
}
bool CElementNumber::CheckNumber(const std::wstring& wsNumber)
{
@ -454,7 +461,7 @@ namespace OdfCustomShape
pXmlWriter->WriteString(L"1 ");
}
//CSMReader
CSMReader::CSMReader(const std::wstring& wsFormula) : m_Formula (wsFormula), m_pElement(nullptr), m_bDoubleSign(false)
CSMReader::CSMReader(const std::wstring& wsFormula, const std::wstring &wsLeft, const std::wstring &wsTop, const std::wstring &wsRight, const std::wstring &wsBottom) : m_Formula (wsFormula), m_pElement(nullptr), m_bDoubleSign(false),m_wsLeft(wsLeft),m_wsTop(wsTop),m_wsRight(wsRight),m_wsBottom(wsBottom)
{
m_itStart = m_Formula.begin();
m_itEnd = m_Formula.end();
@ -573,6 +580,22 @@ namespace OdfCustomShape
{
return m_bDoubleSign;
}
std::wstring CSMReader::GetLeft()
{
return m_wsLeft;
}
std::wstring CSMReader::GetTop()
{
return m_wsTop;
}
std::wstring CSMReader::GetRight()
{
return m_wsRight;
}
std::wstring CSMReader::GetBottom()
{
return m_wsBottom;
}
//CElementBracket
CElementBracket::CElementBracket()
{

View File

@ -73,7 +73,7 @@ namespace OdfCustomShape
class CSMReader
{
public:
CSMReader(const std::wstring& wsStarMath);
CSMReader(const std::wstring& wsStarMath, const std::wstring& wsLeft,const std::wstring& wsTop,const std::wstring& wsRight,const std::wstring& wsBottom);
~CSMReader();
std::wstring GetElement(std::wstring::iterator& itStart, std::wstring::iterator& itEnd);
CElement* ReadingElement();
@ -85,21 +85,25 @@ namespace OdfCustomShape
void RemovingTheParenthesisIterator();
void SetDoubleSign(const bool& bDoubleSign);
bool GetDoubleSign();
std::wstring GetLeft();
std::wstring GetTop();
std::wstring GetRight();
std::wstring GetBottom();
private:
std::wstring m_Formula;
std::wstring::iterator m_itStart;
std::wstring::iterator m_itEnd,m_itEndForBrecket;
std::stack<std::wstring::iterator> m_stEndBrecket;
std::wstring m_wsElement;
CElement* m_pElement;
bool m_bDoubleSign;
std::wstring m_wsElement,m_wsLeft,m_wsTop,m_wsRight,m_wsBottom;
};
class SMCustomShapePars
{
public:
SMCustomShapePars();
~SMCustomShapePars();
void StartParsSMCustomShape(const std::wstring& wsFormula);
void StartParsSMCustomShape(const std::wstring& wsFormula, const std::wstring &wsLeft, const std::wstring &wsTop, const std::wstring &wsRight, const std::wstring &wsBottom);
static CElement* ParseElement(CSMReader* pReader);
static void ParsString(CSMReader* pReader, std::vector<CElement*>& arVec);
std::vector<CElement*>& GetVector();

View File

@ -869,6 +869,8 @@ bool draw_enhanced_geometry::oox_convert(std::vector<odf_reader::_property>& pro
bool set_shape = false;
std::wstring wsH(L""),wsW(L""),wsLeft(L""),wsTop(L"");
if (attlist_.draw_mirror_horizontal_)
{
props.push_back(_property(L"flipH", *attlist_.draw_mirror_horizontal_));
@ -893,6 +895,60 @@ bool draw_enhanced_geometry::oox_convert(std::vector<odf_reader::_property>& pro
owner_shape->sub_type_ = sub_type_.get();
set_shape = true;
}
if (attlist_.drawooo_sub_view_size_)
{
std::vector< std::wstring > splitted;
boost::algorithm::split(splitted, *attlist_.drawooo_sub_view_size_, boost::algorithm::is_any_of(L" "), boost::algorithm::token_compress_on);
if (splitted.size() == 2)
{
int w = boost::lexical_cast<int>(splitted[0]);
int h = boost::lexical_cast<int>(splitted[1]);
props.push_back(odf_reader::_property(L"custom_path_w", w));
props.push_back(odf_reader::_property(L"custom_path_h", h));
}
else if (splitted.size() == 4)
{///???? rect ???
int l = boost::lexical_cast<int>(splitted[0]);
int t = boost::lexical_cast<int>(splitted[1]);
int r = boost::lexical_cast<int>(splitted[2]);
int b = boost::lexical_cast<int>(splitted[3]);
}
//if (shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_)
//{
// int w_shape = shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_->get_value();
// if (w_shape < 1) shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_ = length(1, length::pt);
//}
//if (shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_)
//{
// int h_shape = shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_->get_value();
// if (h_shape < 1) shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_ = length(1, length::pt);
//}
}
else if (svg_viewbox_)
{
std::vector< std::wstring > splitted;
boost::algorithm::split(splitted, *svg_viewbox_, boost::algorithm::is_any_of(L" "), boost::algorithm::token_compress_on);
if (splitted.size() == 4)
{
int w = boost::lexical_cast<int>(splitted[2]);
int h = boost::lexical_cast<int>(splitted[3]);
wsLeft = std::to_wstring(boost::lexical_cast<int>(splitted[0]));
wsTop = std::to_wstring(boost::lexical_cast<int>(splitted[1]));
wsH = std::to_wstring(h);
wsW = std::to_wstring(w);
props.push_back(odf_reader::_property(L"custom_path_w", w));
props.push_back(odf_reader::_property(L"custom_path_h", h));
}
}
std::vector<std::wstring> equation_names;
if (false == draw_equations_.empty() && !draw_type_oox_index_)
{
@ -908,7 +964,7 @@ bool draw_enhanced_geometry::oox_convert(std::vector<odf_reader::_property>& pro
XmlUtils::replace_all(name, L"f", L"gd");
oox_formulas += OdfCustomShape::convert_formula(value, name);
oox_formulas += OdfCustomShape::convert_formula(value, name,wsLeft,wsTop,wsW,wsH);
equation_names.push_back(name);
}
}
@ -922,6 +978,7 @@ bool draw_enhanced_geometry::oox_convert(std::vector<odf_reader::_property>& pro
if (!odf_path_.empty())
{
bool bCPathWithArgs = (std::wstring::npos != odf_path_.find(L"?"));
std::wstring wsNewFormula;
if (bOoxType_ || (bCPathWithArgs && false == equation_names.empty()))
{
std::vector<::svg_path::_polylineS> o_Polyline;
@ -931,13 +988,21 @@ bool draw_enhanced_geometry::oox_convert(std::vector<odf_reader::_property>& pro
try
{
res = ::svg_path::parseSvgS(o_Polyline, odf_path_, true, bClosed, bStroked);
res = ::svg_path::parseSvgS(o_Polyline, odf_path_, true, bClosed, bStroked,wsNewFormula,wsH,wsW);
}
catch (...)
{
res = false;
}
if(!props.empty() && !wsNewFormula.empty())
for(odf_reader::_property& stTempProps:props)
if(stTempProps.name_ == L"custom_equations")
{
boost::get<std::wstring>(stTempProps.val_) += wsNewFormula;
wsNewFormula.clear();
}
if (!o_Polyline.empty() && res)
{
set_shape = true;
@ -989,53 +1054,6 @@ bool draw_enhanced_geometry::oox_convert(std::vector<odf_reader::_property>& pro
}
}
if (attlist_.drawooo_sub_view_size_)
{
std::vector< std::wstring > splitted;
boost::algorithm::split(splitted, *attlist_.drawooo_sub_view_size_, boost::algorithm::is_any_of(L" "), boost::algorithm::token_compress_on);
if (splitted.size() == 2)
{
int w = boost::lexical_cast<int>(splitted[0]);
int h = boost::lexical_cast<int>(splitted[1]);
props.push_back(odf_reader::_property(L"custom_path_w", w));
props.push_back(odf_reader::_property(L"custom_path_h", h));
}
else if (splitted.size() == 4)
{///???? rect ???
int l = boost::lexical_cast<int>(splitted[0]);
int t = boost::lexical_cast<int>(splitted[1]);
int r = boost::lexical_cast<int>(splitted[2]);
int b = boost::lexical_cast<int>(splitted[3]);
}
//if (shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_)
//{
// int w_shape = shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_->get_value();
// if (w_shape < 1) shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_width_ = length(1, length::pt);
//}
//if (shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_)
//{
// int h_shape = shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_->get_value();
// if (h_shape < 1) shape->common_draw_attlists_.rel_size_.common_draw_size_attlist_.svg_height_ = length(1, length::pt);
//}
}
else if (svg_viewbox_)
{
std::vector< std::wstring > splitted;
boost::algorithm::split(splitted, *svg_viewbox_, boost::algorithm::is_any_of(L" "), boost::algorithm::token_compress_on);
if (splitted.size() == 4)
{
int w = boost::lexical_cast<int>(splitted[2]);
int h = boost::lexical_cast<int>(splitted[3]);
props.push_back(odf_reader::_property(L"custom_path_w", w));
props.push_back(odf_reader::_property(L"custom_path_h", h));
}
}
if (attlist_.draw_modifiers_ && ((set_shape && bOoxType_ && !draw_type_oox_index_) || (false == equation_names.empty())))
{
props.push_back(_property(L"oox-draw-modifiers", attlist_.draw_modifiers_.get()));

View File

@ -861,7 +861,7 @@ namespace svg_path
return true;
}
bool parseSvgS(std::vector<_polylineS>& Polyline, const std::wstring& rSvgDStatement, bool bWrongPositionAfterZ, bool& bIsClosed, bool& bStroked)
bool parseSvgS(std::vector<_polylineS>& Polyline, const std::wstring& rSvgDStatement, bool bWrongPositionAfterZ, bool& bIsClosed, bool& bStroked, std::wstring &wsNewFormula, std::wstring &wsH, std::wstring &wsW)
{
Polyline.clear();
const int nLen(rSvgDStatement.length());
@ -873,6 +873,8 @@ namespace svg_path
std::wstring nLastControlX;
std::wstring nLastControlY;
unsigned int iCountFormul(1);
_polylineS aCurrPoly;
bIsClosed = false;
@ -1162,10 +1164,107 @@ namespace svg_path
bRelative = true;
}
case 'A':
case 'W':
{
nPos++;
skipSpaces(nPos, rSvgDStatement, nLen);
while(nPos < nLen && isOnNumberChar(rSvgDStatement,nPos))
{
std::wstring wsX1,wsY1,wsX2,wsY2;
std::wstring wsAngleStartX,wsAngleStartY,wsAngleEndX,wsAngleEndY;
return false;
if(!importStringAndSpaces(wsX1,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsY1,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsX2,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsY2,nPos,rSvgDStatement,nLen)) return false;
if(aCurrChar == L'A')
{
if(!importStringAndSpaces(wsAngleEndX,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsAngleEndY,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsAngleStartX,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsAngleStartY,nPos,rSvgDStatement,nLen)) return false;
}
else
{
if(!importStringAndSpaces(wsAngleStartX,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsAngleStartY,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsAngleEndX,nPos,rSvgDStatement,nLen)) return false;
if(!importStringAndSpaces(wsAngleEndY,nPos,rSvgDStatement,nLen)) return false;
}
std::wstring wsKoefHeight{L"af" + std::to_wstring(iCountFormul++)},
wsKoefWidth{L"af" + std::to_wstring(iCountFormul++)},
wsHeight{L"af" + std::to_wstring(iCountFormul++)},
wsWidth{L"af" + std::to_wstring(iCountFormul++)},
wsNewFirstAngleX{L"af" + std::to_wstring(iCountFormul++)},
wsNewFirstAngleY{L"af" + std::to_wstring(iCountFormul++)},
wsDifferenceX_FirstAngle{L"af" + std::to_wstring(iCountFormul++)},
wsDifferenceY_FirsAngle{L"af" + std::to_wstring(iCountFormul++)},
wsNewSecondAngleX{L"af" + std::to_wstring(iCountFormul++)},
wsNewSecondAngleY{L"af" + std::to_wstring(iCountFormul++)},
wsDifferenceX_SecondAngle{L"af" + std::to_wstring(iCountFormul++)},
wsDifferenceY_SecondAngle{L"af" + std::to_wstring(iCountFormul++)},
wsArcTangensFirst{L"af" + std::to_wstring(iCountFormul++)},
wsArcTangensSecond{L"af" + std::to_wstring(iCountFormul++)},
wsConversionToDegreesStAngle{L"af" + std::to_wstring(iCountFormul++)},
wsConversionToDegreesSecondAngle{L"af" + std::to_wstring(iCountFormul++)},
wsDifferenceBetweenAngles{L"af" + std::to_wstring(iCountFormul++)},
wsStAngle{L"af" + std::to_wstring(iCountFormul++)},
wsSwAngleNegative{L"af" + std::to_wstring(iCountFormul++)},
wsSwAngle{L"af" + std::to_wstring(iCountFormul++)};
{/*...*/}
/* implemented without taking into account the left offset*/
if(wsH.empty())
wsH = L"h";
if(wsW.empty())
wsW = L"w";
wsNewFormula += L"<a:gd name=\""+ wsKoefHeight + L"\" fmla=\"*/ h 1 " + wsH + L"\"/>";
wsNewFormula += L"<a:gd name=\""+ wsKoefWidth + L"\" fmla=\"*/ w 1 " + wsW + L"\"/>";
// }
wsNewFormula += L"<a:gd name=\""+ wsHeight + L"\" fmla=\"*/ vc " + wsH + L" h\"/>";
wsNewFormula += L"<a:gd name=\""+ wsWidth + L"\" fmla=\"*/ wd2 " + wsW + L" w\"/>";
wsNewFormula += L"<a:gd name=\""+ wsNewFirstAngleX + L"\" fmla=\"*/ "+ wsAngleStartX +L" " + wsKoefWidth + L" 1\"/>";
wsNewFormula += L"<a:gd name=\""+ wsNewFirstAngleY + L"\" fmla=\"*/ "+ wsAngleStartY +L" " + wsKoefHeight + L" 1\"/>";
wsNewFormula += L"<a:gd name=\""+ wsDifferenceX_FirstAngle + L"\" fmla=\"+- 0 " + wsNewFirstAngleX + L" wd2\"/>";
wsNewFormula += L"<a:gd name=\""+ wsDifferenceY_FirsAngle + L"\" fmla=\"+- 0 " + wsNewFirstAngleY + L" vc\"/>";
wsNewFormula += L"<a:gd name=\""+ wsNewSecondAngleX + L"\" fmla=\"*/ "+ wsAngleEndX +L" " + wsKoefWidth + L" 1\"/>";
wsNewFormula += L"<a:gd name=\""+ wsNewSecondAngleY + L"\" fmla=\"*/ "+ wsAngleEndY +L" " + wsKoefHeight + L" 1\"/>";
wsNewFormula += L"<a:gd name=\""+ wsDifferenceX_SecondAngle + L"\" fmla=\"+- 0 " + wsNewSecondAngleX + L" wd2\"/>";
wsNewFormula += L"<a:gd name=\""+ wsDifferenceY_SecondAngle + L"\" fmla=\"+- 0 " + wsNewSecondAngleY + L" vc\"/>";
wsNewFormula += L"<a:gd name=\""+ wsArcTangensFirst + L"\" fmla=\"at2 " + wsDifferenceX_FirstAngle + L" " + wsDifferenceY_FirsAngle + L"\"/>";
wsNewFormula += L"<a:gd name=\""+ wsArcTangensSecond + L"\" fmla=\"at2 " + wsDifferenceX_SecondAngle + L" " + wsDifferenceY_SecondAngle + L"\"/>";
wsNewFormula += L"<a:gd name=\""+ wsDifferenceBetweenAngles + L"\" fmla=\"+- 0 " + wsArcTangensSecond + L" " + wsArcTangensFirst + L"\"/>";
wsNewFormula += L"<a:gd name=\""+ wsStAngle + L"\" fmla=\"val " + wsArcTangensFirst + L"\"/>";
wsNewFormula += L"<a:gd name=\""+ wsSwAngleNegative + L"\" fmla=\"+- 21600000 " + wsDifferenceBetweenAngles + L" 0 \"/>";
wsNewFormula += L"<a:gd name=\""+ wsSwAngle +L"\" fmla=\"?: " + wsDifferenceBetweenAngles + L" " + wsDifferenceBetweenAngles + L" " + wsSwAngleNegative +L"\"/>";
aCurrPoly.command = L"a:moveTo";
aCurrPoly.points.push_back(_pointS(wsAngleStartX,wsAngleStartY));
Polyline.push_back(aCurrPoly);
aCurrPoly.points.clear();
aCurrPoly.command = L"a:arcTo";
aCurrPoly.points.push_back(_pointS(wsWidth,wsHeight));
aCurrPoly.points.push_back(_pointS(wsStAngle,wsSwAngle));
Polyline.push_back(aCurrPoly);
aCurrPoly.points.clear();
nLastX = wsAngleEndX;
nLastY = wsAngleEndY;
nLastControlX = wsAngleEndX;
nLastControlY = wsAngleEndY;
}
}break;
default:
{

View File

@ -70,5 +70,5 @@ namespace svg_path
bool parseSvgD(std::vector<_polyline>& Polyline, const std::wstring& path, bool bWrongPositionAfterZ, bool& bIsClosed, bool& bIsStroked);
bool parsePolygon(std::vector<_polyline>& Polyline, const std::wstring& path, bool bWrongPositionAfterZ, bool closed);
bool parseSvgS(std::vector<_polylineS>& Polyline, const std::wstring& path, bool bWrongPositionAfterZ, bool& bIsClosed, bool& bIsStroked);
}
bool parseSvgS(std::vector<_polylineS>& Polyline, const std::wstring& path, bool bWrongPositionAfterZ, bool& bIsClosed, bool& bIsStroked, std::wstring& wsNewFormula, std::wstring &wsH, std::wstring &wsW);
}