Commit f2d3390b authored by ElenaSubbotina's avatar ElenaSubbotina

RtfFormatWriter - fix custom shape path

parent fb5af12d
......@@ -67,7 +67,7 @@ namespace svg_path
return isOnNumberChar(rStr[nPos],bSignAllowed);
}
bool getDoubleChar(double& o_fRetval,int & io_rPos, const std::wstring& rStr)
bool getDoubleChar(double& o_fRetval,int & io_rPos, const std::wstring& rStr)
{
wchar_t aChar( rStr[io_rPos] );
std::wstring sNumberString;
......@@ -119,7 +119,7 @@ namespace svg_path
return false;
}
bool importDoubleAndSpaces( double& o_fRetval, int& io_rPos, const std::wstring& rStr, const int nLen )
bool importDoubleAndSpaces( double& o_fRetval, int& io_rPos, const std::wstring& rStr, const int nLen )
{
if( !getDoubleChar(o_fRetval, io_rPos, rStr) )
return false;
......@@ -129,7 +129,7 @@ namespace svg_path
return true;
}
bool importFlagAndSpaces(int& o_nRetval, int& io_rPos, const std::wstring& rStr, const int nLen)
bool importFlagAndSpaces(int& o_nRetval, int& io_rPos, const std::wstring& rStr, const int nLen)
{
wchar_t aChar( rStr[io_rPos] );
......@@ -179,7 +179,6 @@ namespace svg_path
return bUseRelativeCoordinates ? cLowerCaseCommand : cUpperCaseCommand;
}
bool parseSvgD(std::vector<_polyline> & Polyline, const std::wstring & rSvgDStatement, bool bWrongPositionAfterZ)
{
Polyline.clear();
......@@ -806,5 +805,153 @@ namespace svg_path
}
bool parseVml(std::vector<_polyline> & Polyline, const std::wstring & rSvgDStatement)
{
Polyline.clear();
const int nLen(rSvgDStatement.length());
int nPos(0);
bool bIsClosed(false);
double nLastX( 0.0 );
double nLastY( 0.0 );
double nLastControlX( 0.0 );
double nLastControlY( 0.0 );
_polyline aCurrPoly;
skipSpaces(nPos, rSvgDStatement, nLen);
while(nPos < nLen)
{
bool bRelative (false);
bool bMoveTo (false);
const wchar_t aCurrChar(rSvgDStatement[nPos]);
aCurrPoly.command.clear();
switch(aCurrChar)
{
case 'z' :
{
nPos++;
skipSpaces(nPos, rSvgDStatement, nLen);
bIsClosed = true;
if( aCurrPoly.points.size() > 0)
{
const _point aFirst( aCurrPoly.points[0]);
nLastX = aFirst.x.get();
nLastY = aFirst.y.get();
}
aCurrPoly.command=L"z";
Polyline.push_back(aCurrPoly);
} break;
case 'm' :
case 't' :
{
bMoveTo = true;
}
case 'l' :
case 'r' :
{
if('t' == aCurrChar || 'r' == aCurrChar)
{
bRelative = true;
}
if(aCurrPoly.points.size() > 0)
{
if(bIsClosed)
{
}
Polyline.push_back(aCurrPoly);
bIsClosed = false;
if(bMoveTo) aCurrPoly.command = L"m";
else aCurrPoly.command = L"l";
aCurrPoly.points.clear();
}
nPos++;
skipSpaces(nPos, rSvgDStatement, nLen);
aCurrPoly.command.clear();
while(nPos < nLen && isOnNumberChar(rSvgDStatement, nPos))
{
double nX, nY;
if(!importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
if(!importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
if(bRelative)
{
nX += nLastX;
nY += nLastY;
}
nLastX = nX;
nLastY = nY;
if(bMoveTo) aCurrPoly.command = L"m";
else aCurrPoly.command = L"l";
aCurrPoly.points.push_back(_point(nX, nY));
Polyline.push_back(aCurrPoly);
aCurrPoly.points.clear();
}
}break;
case 'c' :
{
nPos++;
skipSpaces(nPos, rSvgDStatement, nLen);
while(nPos < nLen && isOnNumberChar(rSvgDStatement, nPos))
{
double nX, nY;
double nX1, nY1;
double nX2, nY2;
if(!importDoubleAndSpaces(nX1, nPos, rSvgDStatement, nLen)) return false;
if(!importDoubleAndSpaces(nY1, nPos, rSvgDStatement, nLen)) return false;
if(!importDoubleAndSpaces(nX2, nPos, rSvgDStatement, nLen)) return false;
if(!importDoubleAndSpaces(nY2, nPos, rSvgDStatement, nLen)) return false;
if(!importDoubleAndSpaces(nX, nPos, rSvgDStatement, nLen)) return false;
if(!importDoubleAndSpaces(nY, nPos, rSvgDStatement, nLen)) return false;
aCurrPoly.command = L"c";
aCurrPoly.points.push_back(_point(nX1, nY1));
aCurrPoly.points.push_back(_point(nX2, nY2));
aCurrPoly.points.push_back(_point(nX, nY));
Polyline.push_back(aCurrPoly);
aCurrPoly.points.clear();
nLastX = nX;
nLastY = nY;
nLastControlX = nX2;
nLastControlY = nY2;
}
}break;
default:
{
++nPos;
break;
}
}
}
return true;
}
}
......@@ -57,19 +57,10 @@ namespace svg_path
std::vector<_point> points; //будем бить строку пути по количеству точек в буковках
};
//m - 1 point
//c - 3 point
//s - 2 point
//l - 1 point
//z - finish
//h - 0.5 point :)
//v - 0.5 point
//q - 2 point
//t - 1 point
//a - [[[[
bool parseSvgD(std::vector<_polyline> & Polyline, const std::wstring & rSvgDStatement, bool bWrongPositionAfterZ);
bool parsePolygon(std::vector<_polyline> & Polyline, const std::wstring & rPolygonStatement, bool bWrongPositionAfterZ, bool closed);
bool parseVml(std::vector<_polyline> & Polyline, const std::wstring & path);
bool parseSvgD(std::vector<_polyline> & Polyline, const std::wstring & path, bool bWrongPositionAfterZ);
bool parsePolygon(std::vector<_polyline> & Polyline, const std::wstring & path, bool bWrongPositionAfterZ, bool closed);
}
......@@ -1069,20 +1069,27 @@ bool OOXShapeReader::Parse( ReaderParameter oParam, RtfShapePtr& pOutput)
std::wstring strVmlPath, strVmlRect;
LONG lW = 43200, lH = 43200;
LONG lW = 0, lH = 0;
if ((m_ooxShape->m_oSpPr->m_oXfrm.IsInit()) && (m_ooxShape->m_oSpPr->m_oXfrm->m_oExt.IsInit()))
{
lW = m_ooxShape->m_oSpPr->m_oXfrm->m_oExt->m_oCx.GetValue();
lH = m_ooxShape->m_oSpPr->m_oXfrm->m_oExt->m_oCy.GetValue();
}
//if ((m_ooxShape->m_oSpPr->m_oXfrm.IsInit()) && (m_ooxShape->m_oSpPr->m_oXfrm->m_oExt.IsInit()))
//{
// lW = m_ooxShape->m_oSpPr->m_oXfrm->m_oExt->m_oCx.GetValue();
// lH = m_ooxShape->m_oSpPr->m_oXfrm->m_oExt->m_oCy.GetValue();
//}
COOXToVMLGeometry *renderer = new COOXToVMLGeometry();
geom.ConvertToCustomVML(renderer, strVmlPath, strVmlRect, lW, lH);
delete renderer;
if (!strVmlPath.empty())
ParseVmlPath(pOutput, strVmlPath, lW, lH);
ParseVmlPath(pOutput, strVmlPath);
pOutput->m_nShapePath = 4; //complex
pOutput->m_nGeoLeft = 0;
pOutput->m_nGeoTop = 0;
pOutput->m_nGeoRight = 100000;
pOutput->m_nGeoBottom = 100000;
}
if (m_ooxShape->m_oSpPr->m_oXfrm.IsInit())
{
......@@ -1303,12 +1310,18 @@ bool OOXShapeReader::ParseVml( ReaderParameter oParam , RtfShapePtr& pOutput)
else if (OOX::Vml::CPolyLine* polyline = dynamic_cast<OOX::Vml::CPolyLine*>(m_vmlElement))
{
pOutput->m_nShapeType = NSOfficeDrawing::sptNotPrimitive;
//polyline->m_oPoints
}
if (pOutput->m_nShapeType == NSOfficeDrawing::sptNotPrimitive && custom_path)
{
ParseVmlPath(pOutput, custom_path->GetValue(), Width, Height);
ParseVmlPath(pOutput, custom_path->GetValue());
pOutput->m_nShapePath = 4; //complex
pOutput->m_nGeoLeft = 0;
pOutput->m_nGeoTop = 0;
pOutput->m_nGeoRight = Width;
pOutput->m_nGeoBottom = Height;
}
//-------------------------------------------------------------------------------------------------------------
if (m_vmlElement->m_oFilled.IsInit())
......@@ -1592,20 +1605,27 @@ bool OOXShapeGroupReader::Parse( ReaderParameter oParam , RtfShapePtr& pOutput)
return true;
}
void OOXShapeReader::ParseVmlPath (RtfShapePtr& pOutput, const std::wstring &custom_path, int W, int H)
void OOXShapeReader::ParseVmlPath (RtfShapePtr& pOutput, const std::wstring &custom_path)
{
std::vector<svg_path::_polyline> o_Polyline;
bool res = svg_path::parseSvgD(o_Polyline, custom_path, false);
bool res = svg_path::parseVml(o_Polyline, custom_path);
int val = 0;
for (size_t i = 0; i < o_Polyline.size(); i++)
{
if (o_Polyline[i].command == L"a:moveTo") val = 0x4000;
else if (o_Polyline[i].command == L"a:lnTo") val = 0x0000;
else if (o_Polyline[i].command == L"a:cubicBezTo") val = 0x2000;
val = val | o_Polyline[i].points.size();
if (o_Polyline[i].command == L"m")
{
val = 0x4000;
}
else if (o_Polyline[i].command == L"l")
{
val = 0x0000 | 1;
}
else if (o_Polyline[i].command == L"c")
{
val = 0x2000 | 1;
}
pOutput->m_aPSegmentInfo.push_back(val);
......@@ -1615,8 +1635,7 @@ void OOXShapeReader::ParseVmlPath (RtfShapePtr& pOutput, const std::wstring &cus
(int)(o_Polyline[i].points[j].y.get_value_or(0)/* / 10000. * H*/)));
}
}
pOutput->m_aPSegmentInfo.push_back(val);
pOutput->m_aPVerticles.push_back(pOutput->m_aPVerticles[0]);
pOutput->m_aPSegmentInfo.push_back(0x6001);
pOutput->m_aPSegmentInfo.push_back(0x8000);
}
......
......@@ -88,7 +88,7 @@ private:
OOX::Logic::CShape *m_ooxShape;
void ParseVmlPath (RtfShapePtr& pShape, const std::wstring &custom_path, int W, int H);
void ParseVmlPath (RtfShapePtr& pShape, const std::wstring &custom_path);
bool ParseVmlStyles (RtfShapePtr& pShape, std::vector<SimpleTypes::Vml::CCssPropertyPtr> & props)
{
for (size_t i=0; i< props.size(); i++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment