mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-12 19:06:03 +08:00
Compare commits
13 Commits
core/devel
...
core/devel
| Author | SHA1 | Date | |
|---|---|---|---|
| 5b4c6363bb | |||
| 2026d064ef | |||
| 42257ca447 | |||
| 6f2fdcd971 | |||
| 9b4b7a26fd | |||
| 4d688b3922 | |||
| be8d427e26 | |||
| 7e0749ddda | |||
| 9f2324d208 | |||
| 6e258b85d7 | |||
| 24e55018a0 | |||
| 2352ae5d88 | |||
| 2cba43e6f3 |
@ -35,11 +35,23 @@
|
||||
|
||||
namespace DocFileFormat
|
||||
{
|
||||
struct _guides
|
||||
{
|
||||
unsigned char type;
|
||||
|
||||
unsigned char param_type1;
|
||||
unsigned char param_type2;
|
||||
unsigned char param_type3;
|
||||
|
||||
WORD param1;
|
||||
WORD param2;
|
||||
WORD param3;
|
||||
};
|
||||
class PathParser
|
||||
{
|
||||
public:
|
||||
|
||||
PathParser (const unsigned char* pSegmentInfo, unsigned int pSegmentInfoSize, const unsigned char* pVertices, unsigned int pVerticesSize)
|
||||
PathParser (const unsigned char* pSegmentInfo, unsigned int pSegmentInfoSize, const unsigned char* pVertices, unsigned int pVerticesSize, std::vector<_guides> & guides)
|
||||
{
|
||||
if ((pSegmentInfo != NULL) && (pSegmentInfoSize > 0))
|
||||
{
|
||||
@ -105,31 +117,40 @@ namespace DocFileFormat
|
||||
unsigned short nElemsAlloc = FormatUtils::BytesToUInt16(pVertices, 2, pVerticesSize);
|
||||
unsigned short cb = FormatUtils::BytesToUInt16(pVertices, 4, pVerticesSize);
|
||||
|
||||
if (0xfff0 == cb)
|
||||
{
|
||||
cb = 4;
|
||||
|
||||
for (unsigned short i = 0; i < nElems; ++i)
|
||||
for (unsigned short i = 0; i < nElems; ++i)
|
||||
{
|
||||
POINT point;
|
||||
if (0xfff0 == cb)
|
||||
{
|
||||
POINT point;
|
||||
|
||||
cb = 4;
|
||||
point.x = FormatUtils::BytesToInt16(pVertices + 6, (i * cb), pVerticesSize);
|
||||
point.y = FormatUtils::BytesToInt16(pVertices + 6, (i * cb) + (cb / 2), pVerticesSize);
|
||||
|
||||
m_arPoints.push_back(point);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned short i = 0; i < nElems; ++i)
|
||||
else
|
||||
{
|
||||
POINT point;
|
||||
|
||||
point.x = FormatUtils::BytesToInt32(pVertices + 6, (i * cb), pVerticesSize);
|
||||
point.y = FormatUtils::BytesToInt32(pVertices + 6, (i * cb) + (cb / 2), pVerticesSize);
|
||||
|
||||
m_arPoints.push_back(point);
|
||||
}
|
||||
|
||||
LONG lMinF = (LONG)0x80000000;
|
||||
if (lMinF <= point.x)
|
||||
{
|
||||
int index = (DWORD)point.x - 0x80000000;
|
||||
if (index >= 0 && index < guides.size())
|
||||
{
|
||||
point.x = guides[index].param3;
|
||||
}
|
||||
}
|
||||
if (lMinF <= point.y)
|
||||
{
|
||||
int index = (DWORD)point.y - 0x80000000;
|
||||
if (index >= 0 && index < guides.size())
|
||||
{
|
||||
point.y = guides[index].param3;
|
||||
}
|
||||
}
|
||||
|
||||
m_arPoints.push_back(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,21 +106,20 @@ namespace DocFileFormat
|
||||
return new ShapeContainer( _reader, bodySize, typeCode, version, instance );
|
||||
}
|
||||
|
||||
std::list<OptionEntry> ExtractOptions() const
|
||||
std::vector<OptionEntryPtr> ExtractOptions() const
|
||||
{
|
||||
std::list<OptionEntry> ret;
|
||||
std::vector<OptionEntryPtr> ret;
|
||||
|
||||
//build the list of all option entries of this shape
|
||||
for ( std::vector<Record*>::const_iterator iter = this->Children.begin(); iter != this->Children.end(); iter++ )
|
||||
{
|
||||
ShapeOptions* opt = dynamic_cast<ShapeOptions*>( *iter );
|
||||
|
||||
if ( opt != NULL )
|
||||
if ( opt == NULL ) continue;
|
||||
|
||||
for ( size_t i = 0; i < opt->Options.size(); i++)
|
||||
{
|
||||
for ( std::vector<OptionEntry>::iterator oeIter = opt->Options.begin(); oeIter != opt->Options.end(); oeIter++ )
|
||||
{
|
||||
ret.push_back( *oeIter );
|
||||
}
|
||||
ret.push_back( opt->Options[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -568,18 +568,19 @@ namespace DocFileFormat
|
||||
|
||||
struct OptionEntry
|
||||
{
|
||||
OptionEntry() : pid(PropertyId_left), fBid(false), fComplex(false), op(0), opComplex(NULL)
|
||||
OptionEntry() : pid(PropertyId_left), fBid(false), fComplex(false), op(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PropertyId pid;
|
||||
bool fBid;
|
||||
bool fComplex;
|
||||
unsigned int op;
|
||||
unsigned char* opComplex;
|
||||
std::shared_ptr<unsigned char> opComplex;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<OptionEntry> OptionEntryPtr;
|
||||
|
||||
class ShapeOptions: public Record
|
||||
{
|
||||
public:
|
||||
@ -587,8 +588,8 @@ namespace DocFileFormat
|
||||
static const unsigned short TYPE_CODE_0xF121 = 0xF121;
|
||||
static const unsigned short TYPE_CODE_0xF122 = 0xF122;
|
||||
|
||||
std::vector<OptionEntry> Options;
|
||||
std::map<PropertyId, OptionEntry> OptionsByID;
|
||||
std::vector<OptionEntryPtr> Options;
|
||||
std::map<PropertyId, OptionEntryPtr> OptionsByID;
|
||||
|
||||
ShapeOptions() : Record()
|
||||
{
|
||||
@ -596,8 +597,8 @@ namespace DocFileFormat
|
||||
|
||||
virtual ~ShapeOptions()
|
||||
{
|
||||
for (std::vector<OptionEntry>::iterator iter = Options.begin(); iter != Options.end(); ++iter)
|
||||
RELEASEARRAYOBJECTS( iter->opComplex );
|
||||
//for (std::vector<OptionEntry>::iterator iter = Options.begin(); iter != Options.end(); ++iter)
|
||||
// RELEASEARRAYOBJECTS( iter->opComplex );
|
||||
}
|
||||
|
||||
ShapeOptions (IBinaryReader* _reader, unsigned int size, unsigned int typeCode, unsigned int version, unsigned int instance) : Record (_reader, size, typeCode, version, instance)
|
||||
@ -606,16 +607,16 @@ namespace DocFileFormat
|
||||
|
||||
//instance is the count of properties stored in this record
|
||||
|
||||
OptionEntry entry;
|
||||
//parse the flags and the simple values
|
||||
for (unsigned int i = 0; i < instance; ++i)
|
||||
{
|
||||
OptionEntryPtr entry = std::shared_ptr<OptionEntry>(new OptionEntry());
|
||||
unsigned short flag = Reader->ReadUInt16();
|
||||
|
||||
entry.pid = (PropertyId)FormatUtils::BitmaskToInt (flag, 0x3FFF);
|
||||
entry.fBid = FormatUtils::BitmaskToBool (flag, 0x4000);
|
||||
entry.fComplex = FormatUtils::BitmaskToBool (flag, 0x8000);
|
||||
entry.op = Reader->ReadUInt32();
|
||||
entry->pid = (PropertyId)FormatUtils::BitmaskToInt (flag, 0x3FFF);
|
||||
entry->fBid = FormatUtils::BitmaskToBool (flag, 0x4000);
|
||||
entry->fComplex = FormatUtils::BitmaskToBool (flag, 0x8000);
|
||||
entry->op = Reader->ReadUInt32();
|
||||
|
||||
Options.push_back( entry );
|
||||
}
|
||||
@ -625,21 +626,12 @@ namespace DocFileFormat
|
||||
//of the OptionEntry arry, sorted by pid
|
||||
for (unsigned int i = 0; i < instance; ++i)
|
||||
{
|
||||
if (Options[i].fComplex)
|
||||
{
|
||||
int read_size = (int)Options[i].op + 6 ; //????
|
||||
//todooo !!!! проверить все остальные !! тут размер в зависимости от типа Complex!!!
|
||||
switch(Options[i].pid)
|
||||
{
|
||||
case PropertyId::gtextUNICODE:
|
||||
case PropertyId::gtextFont:
|
||||
read_size = (int)Options[i].op;
|
||||
break;
|
||||
}
|
||||
Options[i].opComplex = Reader->ReadBytes( read_size, true );
|
||||
if (Options[i]->fComplex && Options[i]->op > 0)
|
||||
{
|
||||
Options[i]->opComplex = std::shared_ptr<unsigned char>(Reader->ReadBytes( Options[i]->op, true ));
|
||||
}
|
||||
|
||||
OptionsByID.insert(std::pair<PropertyId, OptionEntry>(Options[i].pid, Options[i]));
|
||||
OptionsByID.insert(std::make_pair(Options[i]->pid, Options[i]));
|
||||
}
|
||||
|
||||
Reader->Seek(( pos + size ), 0/*STREAM_SEEK_SET*/);
|
||||
|
||||
@ -241,7 +241,7 @@ namespace DocFileFormat
|
||||
std::wstring strHeight = FormatUtils::DoubleToWideString( height.ToPoints() );
|
||||
std::wstring strStyle;
|
||||
|
||||
std::list<OptionEntry> options;
|
||||
std::vector<OptionEntryPtr> options;
|
||||
|
||||
PictureFrameType type;
|
||||
if ((pict->shapeContainer || pict->blipStoreEntry) && pict->shapeContainer->Children.size() > 0)
|
||||
@ -282,9 +282,9 @@ namespace DocFileFormat
|
||||
}
|
||||
//todooo oбъединить с shape_mapping
|
||||
|
||||
std::list<OptionEntry>::iterator end = options.end();
|
||||
for (std::list<OptionEntry>::iterator iter = options.begin(); iter != end; ++iter)
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
OptionEntryPtr & iter = options[i];
|
||||
switch ( iter->pid )
|
||||
{
|
||||
case wzEquationXML:
|
||||
@ -292,7 +292,7 @@ namespace DocFileFormat
|
||||
m_isEquation = true;
|
||||
m_isEmbedded = true;
|
||||
|
||||
m_embeddedData = std::string((char*)iter->opComplex, iter->op);
|
||||
m_embeddedData = std::string((char*)iter->opComplex.get(), iter->op);
|
||||
|
||||
if (ParseEmbeddedEquation( m_embeddedData, m_equationXml))
|
||||
{
|
||||
@ -303,7 +303,7 @@ namespace DocFileFormat
|
||||
{
|
||||
//встроенная неведомая хуйня
|
||||
m_isEmbedded = true;
|
||||
m_embeddedData = std::string((char*)iter->opComplex, iter->op);
|
||||
m_embeddedData = std::string((char*)iter->opComplex.get(), iter->op);
|
||||
|
||||
//if (ParseEmbeddedBlob( m_embeddedData, m_blobXml)) // todoooo
|
||||
//{
|
||||
|
||||
@ -143,8 +143,9 @@ namespace DocFileFormat
|
||||
ShapeContainer* groupShape = static_cast<ShapeContainer*>(container->Children[0]);
|
||||
GroupShapeRecord* gsr = static_cast<GroupShapeRecord*>(groupShape->Children[0]);
|
||||
Shape* shape = static_cast<Shape*>(groupShape->Children[1]);
|
||||
std::list<OptionEntry> options = groupShape->ExtractOptions();
|
||||
ChildAnchor* anchor = groupShape->FirstChildWithType<ChildAnchor>();
|
||||
|
||||
ChildAnchor* anchor = groupShape->FirstChildWithType<ChildAnchor>();
|
||||
std::vector<OptionEntryPtr> options = groupShape->ExtractOptions();
|
||||
|
||||
m_shapeId = GetShapeID(shape);
|
||||
|
||||
@ -155,14 +156,13 @@ namespace DocFileFormat
|
||||
m_pXmlWriter->WriteAttribute( L"coordsize", ( FormatUtils::IntToWideString(gsr->rcgBounds.size.cx) + L"," + FormatUtils::IntToWideString(gsr->rcgBounds.size.cy)));
|
||||
|
||||
// Write wrap coords
|
||||
std::list<OptionEntry>::const_iterator end = options.end();
|
||||
for (std::list<OptionEntry>::const_iterator iter = options.begin(); iter != end; ++iter)
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
switch (iter->pid)
|
||||
switch (options[i]->pid)
|
||||
{
|
||||
case pWrapPolygonVertices:
|
||||
case pWrapPolygonVertices:
|
||||
{
|
||||
std::wstring wrapCoords = getWrapCoords(*iter);
|
||||
std::wstring wrapCoords = GetWrapCoords(options[i]);
|
||||
if (wrapCoords.length())
|
||||
m_pXmlWriter->WriteAttribute(L"wrapcoords", wrapCoords);
|
||||
}
|
||||
@ -226,9 +226,9 @@ namespace DocFileFormat
|
||||
bool freeform = true;
|
||||
std::wstring sShapeId;
|
||||
|
||||
std::list<OptionEntry> options = pContainer->ExtractOptions();
|
||||
ChildAnchor* pAnchor = pContainer->FirstChildWithType<ChildAnchor>();
|
||||
ClientAnchor* clientAnchor = pContainer->FirstChildWithType<ClientAnchor>();
|
||||
std::vector<OptionEntryPtr> options = pContainer->ExtractOptions();
|
||||
ChildAnchor* pAnchor = pContainer->FirstChildWithType<ChildAnchor>();
|
||||
ClientAnchor* clientAnchor = pContainer->FirstChildWithType<ClientAnchor>();
|
||||
|
||||
WriteBeginShapeNode (pShape);
|
||||
|
||||
@ -294,13 +294,17 @@ namespace DocFileFormat
|
||||
|
||||
std::wstring sTextboxStyle;
|
||||
|
||||
std::wstring adjValues[8];
|
||||
ShadowStyleBooleanProperties shadowBoolean(0);
|
||||
std::vector<std::wstring> arrInscribe;
|
||||
|
||||
OptionEntryPtr opSegmentInfo;
|
||||
OptionEntryPtr opVerticles;
|
||||
OptionEntryPtr opInscribe;
|
||||
OptionEntryPtr opConnectAngles;
|
||||
OptionEntryPtr opConnectLocs;
|
||||
|
||||
std::list<OptionEntry>::const_iterator end = options.end();
|
||||
for (std::list<OptionEntry>::const_iterator iter = options.begin(); iter != end; ++iter)
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
OptionEntryPtr & iter = options[i];
|
||||
switch (iter->pid)
|
||||
{
|
||||
//BOOLEANS
|
||||
@ -335,19 +339,16 @@ namespace DocFileFormat
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case protectionBooleans:
|
||||
{
|
||||
ProtectionBooleanProperties booleans(iter->op);
|
||||
}
|
||||
break;
|
||||
|
||||
case diagramBooleans:
|
||||
{
|
||||
DiagramBooleanProperties booleans(iter->op);
|
||||
}
|
||||
break;
|
||||
|
||||
case groupShapeBooleans:
|
||||
{
|
||||
GroupShapeBooleanProperties booleans(iter->op);
|
||||
@ -357,56 +358,80 @@ namespace DocFileFormat
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// GEOMETRY
|
||||
|
||||
// GEOMETRY
|
||||
case shapePath :
|
||||
{
|
||||
bHavePath = true;
|
||||
}break;
|
||||
case pVertices:
|
||||
{
|
||||
opVerticles = iter;
|
||||
}break;
|
||||
case pSegmentInfo:
|
||||
{
|
||||
opSegmentInfo = iter;
|
||||
}break;
|
||||
case pGuides:
|
||||
{
|
||||
GetGuides(iter);
|
||||
}break;
|
||||
case pConnectionSites:
|
||||
{
|
||||
opConnectLocs = iter;
|
||||
}break;
|
||||
case pConnectionSitesDir:
|
||||
{
|
||||
opConnectAngles = iter;
|
||||
}break;
|
||||
case pInscribe:
|
||||
{
|
||||
opInscribe = iter;
|
||||
}break;
|
||||
case adjustValue:
|
||||
{
|
||||
adjValues[0] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,1);
|
||||
m_nAdjValues[0] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues,1);
|
||||
}
|
||||
break;
|
||||
|
||||
case adjust2Value:
|
||||
{
|
||||
adjValues[1] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,2);
|
||||
m_nAdjValues[1] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case adjust3Value:
|
||||
{
|
||||
adjValues[2] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,3);
|
||||
m_nAdjValues[2] = (int)iter->op;
|
||||
nAdjValues =(std::max)(nAdjValues, 3);
|
||||
}break;
|
||||
case adjust4Value:
|
||||
{
|
||||
adjValues[3] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,4);
|
||||
m_nAdjValues[3] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues, 4);
|
||||
}break;
|
||||
case adjust5Value:
|
||||
{
|
||||
adjValues[4] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,5);
|
||||
m_nAdjValues[4] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues, 5);
|
||||
}break;
|
||||
case adjust6Value:
|
||||
{
|
||||
adjValues[5] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,6);
|
||||
m_nAdjValues[5] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues, 6);
|
||||
}break;
|
||||
case adjust7Value:
|
||||
{
|
||||
adjValues[6] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,7);
|
||||
m_nAdjValues[6] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues, 7);
|
||||
}break;
|
||||
case adjust8Value:
|
||||
{
|
||||
adjValues[7] = FormatUtils::IntToWideString( (int)iter->op );
|
||||
nAdjValues = (std::max)(nAdjValues,8);
|
||||
m_nAdjValues[7] = (int)iter->op;
|
||||
nAdjValues = (std::max)(nAdjValues, 8);
|
||||
}break;
|
||||
case pWrapPolygonVertices:
|
||||
{
|
||||
std::wstring wrapCoords = getWrapCoords(*iter);
|
||||
std::wstring wrapCoords = GetWrapCoords(iter);
|
||||
|
||||
if (!wrapCoords.empty())
|
||||
{
|
||||
@ -421,13 +446,6 @@ namespace DocFileFormat
|
||||
{
|
||||
yCoord = iter->op;
|
||||
}break;
|
||||
case pGuides:
|
||||
{
|
||||
}break;
|
||||
case pInscribe:
|
||||
{
|
||||
arrInscribe = GetTextRectangles(*iter);
|
||||
}break;
|
||||
// OUTLINE
|
||||
case lineColor:
|
||||
{
|
||||
@ -497,7 +515,7 @@ namespace DocFileFormat
|
||||
}break;
|
||||
case fillShadeColors:
|
||||
{
|
||||
appendValueAttribute(&m_fill, L"colors", getFillColorString( iter->opComplex, iter->op ));
|
||||
appendValueAttribute(&m_fill, L"colors", getFillColorString( iter->opComplex.get(), iter->op ));
|
||||
}break;
|
||||
case fillFocus:
|
||||
{
|
||||
@ -602,7 +620,7 @@ namespace DocFileFormat
|
||||
case pibName:
|
||||
{
|
||||
std::wstring name;
|
||||
FormatUtils::GetSTLCollectionFromBytes<std::wstring>(&name, iter->opComplex, iter->op, ENCODING_UTF16);
|
||||
FormatUtils::GetSTLCollectionFromBytes<std::wstring>(&name, iter->opComplex.get(), iter->op, ENCODING_UTF16);
|
||||
if (!name.empty())
|
||||
appendValueAttribute(&m_imagedata, L"o:title", FormatUtils::XmlEncode(name));
|
||||
}break;
|
||||
@ -676,10 +694,10 @@ namespace DocFileFormat
|
||||
hasTextbox = true;
|
||||
nLTxID = (((iter->op) >> 16) & 0xFFFF);
|
||||
}break;
|
||||
case dxTextLeft: {ndxTextLeft = (int)iter->op;break;}
|
||||
case dyTextTop: {ndyTextTop = (int)iter->op;break;}
|
||||
case dxTextRight: {ndxTextRight = (int)iter->op;break;}
|
||||
case dyTextBottom: {ndyTextBottom = (int)iter->op;break;}
|
||||
case dxTextLeft: {ndxTextLeft = (int)iter->op; break;}
|
||||
case dyTextTop: {ndyTextTop = (int)iter->op; break;}
|
||||
case dxTextRight: {ndxTextRight = (int)iter->op; break;}
|
||||
case dyTextBottom: {ndyTextBottom = (int)iter->op; break;}
|
||||
case txflTextFlow:
|
||||
{
|
||||
switch(iter->op)
|
||||
@ -700,7 +718,7 @@ namespace DocFileFormat
|
||||
// Word Art
|
||||
case gtextUNICODE:
|
||||
{
|
||||
std::wstring text = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)iter->opComplex, (iter->op)/2);
|
||||
std::wstring text = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)iter->opComplex.get(), (iter->op)/2);
|
||||
|
||||
text = FormatUtils::XmlEncode(text);
|
||||
|
||||
@ -713,7 +731,7 @@ namespace DocFileFormat
|
||||
}break;
|
||||
case gtextFont:
|
||||
{
|
||||
std::wstring font = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)iter->opComplex, (iter->op)/2);
|
||||
std::wstring font = NSStringExt::CConverter::GetUnicodeFromUTF16((unsigned short*)iter->opComplex.get(), (iter->op)/2);
|
||||
int i = font.size();
|
||||
while (i > 0)
|
||||
{
|
||||
@ -764,31 +782,31 @@ namespace DocFileFormat
|
||||
appendStyleProperty(&m_textPathStyle, L"font-weight", L"bold");
|
||||
}
|
||||
}break;
|
||||
// PATH
|
||||
case shapePath :
|
||||
{
|
||||
bHavePath = true;
|
||||
|
||||
std::wstring path = ParsePath(options);
|
||||
|
||||
if (false == path.empty())
|
||||
m_pXmlWriter->WriteAttribute (L"path", path);
|
||||
}break;
|
||||
default:
|
||||
default:
|
||||
{
|
||||
int val = iter->op;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
if (false == bHavePath) // фигура может быть задана только наборами вершин и индексов
|
||||
if (opVerticles && opSegmentInfo)
|
||||
{
|
||||
std::wstring path = ParsePath(options);
|
||||
const unsigned char* pVP = opVerticles->opComplex.get();
|
||||
unsigned int nVP = opVerticles->op;
|
||||
const unsigned char* pSI = opSegmentInfo->opComplex.get();
|
||||
unsigned int nSI = opSegmentInfo->op;
|
||||
|
||||
PathParser oParser (pSI, nSI, pVP, nVP, m_arrGuides);
|
||||
std::wstring path = oParser.GetVmlPath();
|
||||
|
||||
if (false == path.empty())
|
||||
m_pXmlWriter->WriteAttribute (L"path", path);
|
||||
}
|
||||
|
||||
if (freeform && (xCoord == 0 || yCoord == 0 ))
|
||||
{
|
||||
xCoord = 21600;
|
||||
yCoord = 21600;
|
||||
}
|
||||
if ( !filled )
|
||||
{
|
||||
m_pXmlWriter->WriteAttribute( L"filled", L"f" );
|
||||
@ -804,10 +822,10 @@ namespace DocFileFormat
|
||||
m_pXmlWriter->WriteAttribute(L"o:allowincell", L"f");
|
||||
}
|
||||
|
||||
if ( ( xCoord > 0 ) && ( yCoord > 0 ) )
|
||||
if ( xCoord > 0 && yCoord > 0 )
|
||||
{
|
||||
m_pXmlWriter->WriteAttribute( L"coordsize", ( FormatUtils::IntToWideString( xCoord ) + L"," + FormatUtils::IntToWideString( yCoord ) ));
|
||||
}
|
||||
}
|
||||
|
||||
int nCode = 0;
|
||||
if (pShape->GetShapeType())
|
||||
@ -819,17 +837,17 @@ namespace DocFileFormat
|
||||
{
|
||||
if (nAdjValues)
|
||||
{
|
||||
m_pXmlWriter->WriteAttribute(L"arcsize", adjValues[0]);
|
||||
m_pXmlWriter->WriteAttribute(L"arcsize", m_nAdjValues[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nAdjValues)
|
||||
if (nAdjValues > 0)
|
||||
{
|
||||
std::wstring adjTag = adjValues[0];
|
||||
std::wstring adjTag = std::to_wstring(m_nAdjValues[0]);
|
||||
|
||||
for (int i = 1; i < nAdjValues; ++i)
|
||||
adjTag += std::wstring(L",") + adjValues[i];
|
||||
adjTag += L"," + std::to_wstring(m_nAdjValues[i]);
|
||||
|
||||
m_pXmlWriter->WriteAttribute(L"adj", adjTag);
|
||||
}
|
||||
@ -982,10 +1000,24 @@ namespace DocFileFormat
|
||||
}
|
||||
if (freeform)
|
||||
{
|
||||
if (arrInscribe.size())
|
||||
if (opInscribe || opConnectAngles || opConnectLocs)
|
||||
{
|
||||
std::vector<std::wstring> arrInscribe = GetTextRectangles(opInscribe);
|
||||
std::wstring strConnectAngles = GetConnectAngles(opConnectAngles);
|
||||
std::wstring strConnectLocs = GetConnectLocs(opConnectLocs);
|
||||
|
||||
m_pXmlWriter->WriteNodeBegin(L"v:path", true);
|
||||
m_pXmlWriter->WriteAttribute(L"textboxrect", arrInscribe[0]);
|
||||
if (!arrInscribe.empty())
|
||||
m_pXmlWriter->WriteAttribute(L"textboxrect", arrInscribe[0]);
|
||||
if (!strConnectAngles.empty() || !strConnectLocs.empty())
|
||||
{
|
||||
m_pXmlWriter->WriteAttribute(L"o:connecttype", L"custom");
|
||||
if (!strConnectLocs.empty())
|
||||
m_pXmlWriter->WriteAttribute(L"o:connectlocs", strConnectLocs);
|
||||
if (!strConnectAngles.empty())
|
||||
m_pXmlWriter->WriteAttribute(L"o:connectangles", strConnectAngles);
|
||||
}
|
||||
|
||||
m_pXmlWriter->WriteNodeEnd(L"", true);
|
||||
}
|
||||
}
|
||||
@ -1182,11 +1214,13 @@ namespace DocFileFormat
|
||||
}
|
||||
|
||||
/// Build the VML wrapcoords string for a given pWrapPolygonVertices
|
||||
std::wstring VMLShapeMapping::getWrapCoords(const OptionEntry& pWrapPolygonVertices) const
|
||||
std::wstring VMLShapeMapping::GetWrapCoords(const OptionEntryPtr& pWrapPolygonVertices) const
|
||||
{
|
||||
if (!pWrapPolygonVertices) return L"";
|
||||
|
||||
std::wstring coords;
|
||||
|
||||
MemoryStream oStream(pWrapPolygonVertices.opComplex, pWrapPolygonVertices.op);
|
||||
MemoryStream oStream(pWrapPolygonVertices->opComplex.get(), pWrapPolygonVertices->op);
|
||||
std::list<int> arrVertices;
|
||||
|
||||
unsigned short nElems = oStream.ReadUInt16();
|
||||
@ -1498,7 +1532,7 @@ namespace DocFileFormat
|
||||
}
|
||||
}
|
||||
|
||||
void VMLShapeMapping::AppendOptionsToStyle (std::wstring* oStyle, const std::list<OptionEntry>& options, int zIndex) const
|
||||
void VMLShapeMapping::AppendOptionsToStyle (std::wstring* oStyle, const std::vector<OptionEntryPtr>& options, int zIndex) const
|
||||
{
|
||||
bool bRelH = false;
|
||||
bool bRelV = false;
|
||||
@ -1508,9 +1542,9 @@ namespace DocFileFormat
|
||||
|
||||
bool bZIndex = false;
|
||||
|
||||
std::list<OptionEntry>::const_iterator end = options.end();
|
||||
for (std::list<OptionEntry>::const_iterator iter = options.begin(); iter != end; ++iter)
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
const OptionEntryPtr & iter = options[i];
|
||||
switch (iter->pid)
|
||||
{
|
||||
// POSITIONING
|
||||
@ -1616,15 +1650,16 @@ namespace DocFileFormat
|
||||
}
|
||||
|
||||
//
|
||||
std::wstring VMLShapeMapping::buildStyle (const Shape* shape, const ChildAnchor* anchor, const std::list<OptionEntry>& options, int zIndex) const
|
||||
std::wstring VMLShapeMapping::buildStyle (const Shape* shape, const ChildAnchor* anchor, const std::vector<OptionEntryPtr>& options, int zIndex) const
|
||||
{
|
||||
std::wstring style;
|
||||
|
||||
// Check if some properties are set that cause the dimensions to be twisted
|
||||
bool twistDimensions = false;
|
||||
std::list<OptionEntry>::const_iterator end = options.end();
|
||||
for (std::list<OptionEntry>::const_iterator iter = options.begin(); iter != end; ++iter)
|
||||
|
||||
for (size_t i = 0; i < options.size(); i++)
|
||||
{
|
||||
const OptionEntryPtr & iter = options[i];
|
||||
|
||||
if (geometryTextBooleanProperties == iter->pid)
|
||||
{
|
||||
GeometryTextBooleanProperties props(iter->op);
|
||||
@ -1860,61 +1895,210 @@ namespace DocFileFormat
|
||||
|
||||
return wrapType;
|
||||
}
|
||||
|
||||
std::wstring VMLShapeMapping::ParsePath (const std::list<OptionEntry>& options) const
|
||||
std::wstring VMLShapeMapping::GetConnectAngles(const OptionEntryPtr& opAngles) const
|
||||
{
|
||||
const unsigned char* pVP = NULL;
|
||||
unsigned int nVP = 0;
|
||||
const unsigned char* pSI = NULL;
|
||||
unsigned int nSI = 0;
|
||||
if (!opAngles) return L"";
|
||||
if (!opAngles->opComplex) return L"";
|
||||
|
||||
std::list<OptionEntry>::const_iterator end = options.end();
|
||||
for (std::list<OptionEntry>::const_iterator iter = options.begin(); iter != end; ++iter)
|
||||
MemoryStream reader(opAngles->opComplex.get(), opAngles->op);
|
||||
|
||||
unsigned short nElems = reader.ReadUInt16();
|
||||
unsigned short nElemsAlloc = reader.ReadUInt16();
|
||||
unsigned short nElemSize = reader.ReadUInt16();
|
||||
|
||||
bool bTruncated = false;
|
||||
|
||||
if (0xFFF0 == nElemSize)
|
||||
{
|
||||
nElemSize = 4;
|
||||
bTruncated = true;
|
||||
}
|
||||
|
||||
long dwSize = nElems * nElemSize;
|
||||
|
||||
if (opAngles->op - 6 != (dwSize))
|
||||
{
|
||||
bool b = false;
|
||||
}
|
||||
if (nElemSize < 1) return L"";
|
||||
|
||||
int count = dwSize / nElemSize;
|
||||
|
||||
std::wstring angles;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (iter->pid == pVertices)
|
||||
{
|
||||
pVP = iter->opComplex;
|
||||
nVP = iter->op;
|
||||
}
|
||||
|
||||
if (iter->pid == pSegmentInfo)
|
||||
{
|
||||
pSI = iter->opComplex;
|
||||
nSI = iter->op;
|
||||
}
|
||||
DWORD v = reader.ReadUInt32();
|
||||
double val = (double)((WORD)(v >> 16) + ((WORD)(v) / 65536.0));
|
||||
angles += std::to_wstring((int)val) + (i < (count - 1) ? L"," : L"");
|
||||
}
|
||||
return angles;
|
||||
}
|
||||
int VMLShapeMapping::UpdateFromGuides(const int val) const
|
||||
{
|
||||
int new_val = val;
|
||||
LONG lMinF = (LONG)0x80000000;
|
||||
if (lMinF <= val)
|
||||
{
|
||||
int index = (DWORD)val - 0x80000000;
|
||||
|
||||
if (index >= 0 && index < m_arrGuides.size())
|
||||
{
|
||||
new_val = m_arrGuides[index].param3;
|
||||
}
|
||||
|
||||
PathParser oParser (pSI, nSI, pVP, nVP);
|
||||
return oParser.GetVmlPath();
|
||||
}
|
||||
return new_val;
|
||||
}
|
||||
void VMLShapeMapping::GetGuides( const OptionEntryPtr& opGuides )
|
||||
{
|
||||
if (!opGuides) return;
|
||||
if (!opGuides->opComplex) return;
|
||||
|
||||
MemoryStream reader(opGuides->opComplex.get(), opGuides->op);
|
||||
|
||||
unsigned short nElems = reader.ReadUInt16();
|
||||
unsigned short nElemsAlloc = reader.ReadUInt16();
|
||||
unsigned short nElemSize = reader.ReadUInt16();
|
||||
|
||||
bool bTruncated = false;
|
||||
|
||||
if (0xFFF0 == nElemSize)
|
||||
{
|
||||
nElemSize = 4;
|
||||
bTruncated = true;
|
||||
}
|
||||
long dwSize = nElems * nElemSize;
|
||||
|
||||
if (opGuides->op - 6 != (dwSize))
|
||||
{
|
||||
bool b = false;
|
||||
}
|
||||
int count = dwSize / nElemSize; //1x (int or short)
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
_guides g;
|
||||
WORD flags = reader.ReadUInt16();
|
||||
|
||||
g.type = flags & 0x1FFF;
|
||||
|
||||
g.param_type1 = (unsigned char)(flags & 0x04);
|
||||
g.param_type2 = (unsigned char)(flags & 0x02);
|
||||
g.param_type3 = (unsigned char)(flags & 0x01);
|
||||
|
||||
g.param1 = reader.ReadUInt16();
|
||||
g.param2 = reader.ReadUInt16();
|
||||
g.param3 = reader.ReadUInt16();
|
||||
|
||||
m_arrGuides.push_back(g);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
std::vector<std::wstring> VMLShapeMapping::GetTextRectangles(const OptionEntry& inscribe) const
|
||||
std::wstring VMLShapeMapping::GetConnectLocs( const OptionEntryPtr& opLocs ) const
|
||||
{
|
||||
MemoryStream reader(inscribe.opComplex, inscribe.op + 6);
|
||||
if (!opLocs) return L"";
|
||||
if (!opLocs->opComplex) return L"";
|
||||
|
||||
unsigned short elems = reader.ReadUInt16();
|
||||
unsigned short allocElems = reader.ReadUInt16();
|
||||
unsigned short cb = reader.ReadUInt16();
|
||||
|
||||
MemoryStream reader(opLocs->opComplex.get(), opLocs->op);
|
||||
|
||||
unsigned short nElems = reader.ReadUInt16();
|
||||
unsigned short nElemsAlloc = reader.ReadUInt16();
|
||||
unsigned short nElemSize = reader.ReadUInt16();
|
||||
|
||||
bool bTruncated = false;
|
||||
|
||||
if (0xFFF0 == nElemSize)
|
||||
{
|
||||
nElemSize = 4;
|
||||
bTruncated = true;
|
||||
}
|
||||
|
||||
long dwSize = nElems * nElemSize;
|
||||
|
||||
if (opLocs->op - 6 != (dwSize))
|
||||
{
|
||||
bool b = false;
|
||||
}
|
||||
int count = dwSize / nElemSize; //2x (int or short)
|
||||
|
||||
std::wstring locs;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
POINT pt;
|
||||
|
||||
if (bTruncated)
|
||||
{
|
||||
pt.x = reader.ReadInt16();
|
||||
pt.y = reader.ReadInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
pt.x = reader.ReadInt32();
|
||||
pt.y = reader.ReadInt32();
|
||||
}
|
||||
|
||||
pt.x = UpdateFromGuides(pt.x);
|
||||
pt.y = UpdateFromGuides(pt.y);
|
||||
|
||||
locs += std::to_wstring(pt.x) + L"," + std::to_wstring(pt.y) + (i < (count - 1) ? L";" : L"");
|
||||
}
|
||||
|
||||
return locs;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> VMLShapeMapping::GetTextRectangles( const OptionEntryPtr& opInscribe ) const
|
||||
{
|
||||
std::vector<std::wstring> rectangles;
|
||||
|
||||
if (!opInscribe) return rectangles;
|
||||
if (!opInscribe->opComplex) return rectangles;
|
||||
|
||||
if (16 != cb) return rectangles; // TODO: доделать
|
||||
MemoryStream reader(opInscribe->opComplex.get(), opInscribe->op);
|
||||
|
||||
int count = (inscribe.op) / 16;
|
||||
unsigned short nElems = reader.ReadUInt16();
|
||||
unsigned short nElemsAlloc = reader.ReadUInt16();
|
||||
unsigned short nElemSize = reader.ReadUInt16();
|
||||
|
||||
bool bTruncated = false;
|
||||
|
||||
if (0xFFF0 == nElemSize)
|
||||
{
|
||||
nElemSize = 4;
|
||||
bTruncated = true;
|
||||
}
|
||||
|
||||
long dwSize = nElems * nElemSize;
|
||||
|
||||
if (opInscribe->op - 6 != (dwSize))
|
||||
{
|
||||
bool b = false;
|
||||
}
|
||||
int count = dwSize / nElemSize; //4x (int or short)
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
RECT rc;
|
||||
|
||||
rc.top = reader.ReadInt32();
|
||||
rc.left = reader.ReadInt32();
|
||||
rc.right = reader.ReadInt32();
|
||||
rc.bottom = reader.ReadInt32();
|
||||
if (bTruncated)
|
||||
{
|
||||
rc.top = reader.ReadInt16();
|
||||
rc.left = reader.ReadInt16();
|
||||
rc.right = reader.ReadInt16();
|
||||
rc.bottom = reader.ReadInt16();
|
||||
}
|
||||
else
|
||||
{
|
||||
rc.top = reader.ReadInt32();
|
||||
rc.left = reader.ReadInt32();
|
||||
rc.right = reader.ReadInt32();
|
||||
rc.bottom = reader.ReadInt32();
|
||||
}
|
||||
rc.top = UpdateFromGuides(rc.top);
|
||||
rc.left = UpdateFromGuides(rc.left);
|
||||
rc.right = UpdateFromGuides(rc.right);
|
||||
rc.bottom = UpdateFromGuides(rc.bottom);
|
||||
|
||||
std::wstringstream sstream;
|
||||
sstream << boost::wformat(L"%d,%d,%d,%d") % rc.top % rc.left % rc.right % rc.bottom;
|
||||
rectangles.push_back(sstream.str());
|
||||
rectangles.push_back( std::to_wstring(rc.top) + L"," + std::to_wstring(rc.left) + L"," +
|
||||
std::to_wstring(rc.right) + L"," + std::to_wstring(rc.bottom));
|
||||
}
|
||||
|
||||
return rectangles;
|
||||
|
||||
@ -77,17 +77,10 @@ namespace DocFileFormat
|
||||
|
||||
void WritePrimitiveProps(DrawingPrimitive * primitive, bool root);
|
||||
|
||||
// Converts a group of shapes
|
||||
void WriteGroup(const GroupContainer* pContainer);
|
||||
// Converts a single shape
|
||||
void WriteShape (const ShapeContainer* pContainer);
|
||||
|
||||
/// Generates a string id for the given shape
|
||||
std::wstring GenShapeId(const Shape* pShape) const;
|
||||
/// Build the VML wrapcoords string for a given pWrapPolygonVertices
|
||||
std::wstring getWrapCoords( const OptionEntry& pWrapPolygonVertices ) const;
|
||||
/// Copies the picture from the binary stream to the zip archive
|
||||
/// and creates the relationships for the image.
|
||||
bool copyPicture( const BlipStoreEntry* bse );
|
||||
std::wstring GetTargetExt( Global::BlipType _type ) const;
|
||||
|
||||
@ -98,21 +91,22 @@ namespace DocFileFormat
|
||||
|
||||
std::wstring getTextboxAnchor( unsigned int anchor ) const;
|
||||
|
||||
void AppendOptionsToStyle( std::wstring* style, const std::list<OptionEntry>& options, int zIndex ) const;
|
||||
std::wstring buildStyle ( const Shape* shape, const ChildAnchor* anchor, const std::vector<OptionEntryPtr>& options, int zIndex ) const;
|
||||
void AppendOptionsToStyle ( std::wstring* style, const std::vector<OptionEntryPtr>& options, int zIndex ) const;
|
||||
|
||||
std::wstring buildStyle ( const Shape* shape, const ChildAnchor* anchor, const std::list<OptionEntry>& options, int zIndex ) const;
|
||||
int UpdateFromGuides(const int val) const;
|
||||
|
||||
std::wstring getLineStyle ( unsigned int p ) const;
|
||||
std::wstring getArrowStyle ( unsigned int op ) const;
|
||||
std::wstring getArrowLength ( unsigned int op ) const;
|
||||
std::wstring getArrowWidth ( unsigned int op ) const;
|
||||
std::wstring getFillMethod ( unsigned int p ) const;
|
||||
std::wstring getFillColorString( const unsigned char* p, unsigned int size ) const;
|
||||
/// Returns the OpenXML fill type of a fill effect
|
||||
|
||||
std::wstring getFillType ( unsigned int p ) const;
|
||||
std::wstring getShadowType ( unsigned int p ) const;
|
||||
/// Returns the OpenXML wrap type of the shape
|
||||
|
||||
std::wstring getWrapType (const Spa* pSpa) const;
|
||||
std::wstring ParsePath (const std::list<OptionEntry>& options) const;
|
||||
|
||||
void WriteBeginShapeNode (const Shape* pShape);
|
||||
void WriteEndShapeNode (const Shape* pShape);
|
||||
@ -121,9 +115,15 @@ namespace DocFileFormat
|
||||
std::wstring GetLineFrom (const ChildAnchor* pAnchor) const;
|
||||
std::wstring GetLineTo (const ChildAnchor* pAnchor) const;
|
||||
|
||||
std::vector<std::wstring> GetTextRectangles(const OptionEntry& inscribe) const;
|
||||
std::wstring GetWrapCoords ( const OptionEntryPtr& pOpt ) const;
|
||||
std::vector<std::wstring> GetTextRectangles ( const OptionEntryPtr& pOpt ) const;
|
||||
std::wstring GetConnectAngles ( const OptionEntryPtr& pOpt ) const;
|
||||
std::wstring GetConnectLocs ( const OptionEntryPtr& pOpt ) const;
|
||||
void GetGuides ( const OptionEntryPtr& pOpt );
|
||||
|
||||
private:
|
||||
int m_nAdjValues[8];
|
||||
std::vector<_guides> m_arrGuides;
|
||||
|
||||
bool m_isInlineShape;
|
||||
Spa* m_pSpa;
|
||||
IMapping* m_pCaller;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Version="8,00"
|
||||
Name="OdfFileReaderTest"
|
||||
ProjectGUID="{C2882DDD-07E6-4314-AD4B-48F43F38D722}"
|
||||
RootNamespace="ASCOfficeOdfFileTest"
|
||||
|
||||
@ -155,8 +155,11 @@ void pptx_serialize_shape(std::wostream & strm, _pptx_drawing & val)
|
||||
odf_reader::GetProperty(val.additional,L"no_rect",bNoRect);
|
||||
|
||||
if (!bNoRect)
|
||||
{
|
||||
val.serialize_xfrm(CP_XML_STREAM(), L"a", true);
|
||||
{
|
||||
if (val.cx != 0 || val.cy != 0) //layout
|
||||
{
|
||||
val.serialize_xfrm(CP_XML_STREAM(), L"a", true);
|
||||
}
|
||||
val.serialize_shape(CP_XML_STREAM());
|
||||
|
||||
oox_serialize_ln(CP_XML_STREAM(), val.additional);
|
||||
|
||||
@ -352,7 +352,7 @@ void PptxConverter::convert_slides()
|
||||
current_slide = slide->Master.operator->();
|
||||
|
||||
if (bShowLayoutMasterSp && bShowMasterSp)
|
||||
convert_slide(&slide->Master->cSld, current_txStyles, false, true);
|
||||
convert_slide(&slide->Master->cSld, current_txStyles, false, true, 2);
|
||||
else
|
||||
convert(slide->Master->cSld.bg.GetPointer());
|
||||
|
||||
@ -360,7 +360,7 @@ void PptxConverter::convert_slides()
|
||||
current_clrMap = slide->Layout->clrMapOvr->overrideClrMapping.GetPointer();
|
||||
current_slide = slide->Layout.operator->();
|
||||
|
||||
convert_slide(&slide->Layout->cSld, current_txStyles, true, bShowLayoutMasterSp);
|
||||
convert_slide(&slide->Layout->cSld, current_txStyles, true, bShowLayoutMasterSp, 3);
|
||||
|
||||
if (!presentation->notesMasterIdLst.empty())
|
||||
{
|
||||
@ -407,7 +407,7 @@ void PptxConverter::convert_slides()
|
||||
odp_context->current_slide().set_master_page (master_style_name);
|
||||
odp_context->current_slide().set_layout_page (layout_style_name);
|
||||
|
||||
convert_slide (slide->cSld.GetPointer(), current_txStyles, true, bShowMasterSp);
|
||||
convert_slide (slide->cSld.GetPointer(), current_txStyles, true, bShowMasterSp, 1);
|
||||
convert (slide->comments.operator->());
|
||||
convert (slide->Note.operator->());
|
||||
|
||||
@ -439,7 +439,7 @@ void PptxConverter::convert(PPTX::NotesMaster *oox_notes)
|
||||
|
||||
odf_context()->page_layout_context()->set_page_size(width, height);
|
||||
}
|
||||
convert_slide(&oox_notes->cSld, NULL, true, true);
|
||||
convert_slide(&oox_notes->cSld, NULL, true, true, 2);
|
||||
|
||||
odp_context->end_note();
|
||||
|
||||
@ -472,7 +472,7 @@ void PptxConverter::convert(PPTX::NotesSlide *oox_notes)
|
||||
if (oox_notes->clrMapOvr.IsInit() && oox_notes->clrMapOvr->overrideClrMapping.IsInit())
|
||||
current_clrMap = oox_notes->clrMapOvr->overrideClrMapping.GetPointer();
|
||||
|
||||
convert_slide(&oox_notes->cSld, NULL, true, true);
|
||||
convert_slide(&oox_notes->cSld, NULL, true, true, 1);
|
||||
|
||||
odp_context->end_note();
|
||||
|
||||
@ -1021,7 +1021,7 @@ void PptxConverter::convert(PPTX::Logic::Bg *oox_background)
|
||||
odp_context->end_drawings();
|
||||
}
|
||||
|
||||
void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp)
|
||||
void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp, int type)
|
||||
{
|
||||
if (oox_slide == NULL) return;
|
||||
|
||||
@ -1051,6 +1051,9 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
|
||||
{
|
||||
int ph_type = pShape->nvSpPr.nvPr.ph->type->GetBYTECode();
|
||||
|
||||
if (type == 3 && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12))
|
||||
continue;
|
||||
|
||||
odf_context()->drawing_context()->set_placeholder_type(ph_type);
|
||||
}
|
||||
else
|
||||
|
||||
@ -108,7 +108,7 @@ namespace Oox2Odf
|
||||
|
||||
void convert(OOX::WritingElement *oox_unknown);
|
||||
|
||||
void convert_slide (PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp);
|
||||
void convert_slide (PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp, int type);
|
||||
void convert_layout (PPTX::Logic::CSld *oox_slide);
|
||||
void convert (PPTX::Comments *oox_comments);
|
||||
void convert (PPTX::NotesSlide *oox_notes);
|
||||
|
||||
@ -293,21 +293,79 @@ NSPresentationEditor::CShapeWriter::CShapeWriter()
|
||||
m_pImageElement = NULL;
|
||||
m_pShapeElement = NULL;
|
||||
}
|
||||
std::wstring NSPresentationEditor::CShapeWriter::ConvertLine(CPen & pen)
|
||||
std::wstring NSPresentationEditor::CShapeWriter::ConvertLine(CPen & pen)
|
||||
{
|
||||
NSPresentationEditor::CStringWriter line_writer;
|
||||
|
||||
std::wstring str = std::to_wstring( (int)(pen.Size * 36000));
|
||||
line_writer.WriteString(L"<a:ln w=\"" + str + L"\">");
|
||||
std::wstring strL;
|
||||
switch(pen.LineStyle)
|
||||
{
|
||||
case 1: strL = L" cmpd=\"dbl\""; break;
|
||||
case 2: strL = L" cmpd=\"thickThin\""; break;
|
||||
case 3: strL = L" cmpd=\"thinThick\""; break;
|
||||
case 4: strL = L" cmpd=\"tri\""; break;
|
||||
}
|
||||
line_writer.WriteString(L"<a:ln w=\"" + std::to_wstring((int)(pen.Size * 36000)) + L"\"" + strL + L">");
|
||||
|
||||
line_writer.WriteString(L"<a:solidFill>");
|
||||
line_writer.WriteString(ConvertColor(pen.Color, pen.Alpha));
|
||||
line_writer.WriteString(L"</a:solidFill>");
|
||||
|
||||
line_writer.WriteString(L"<a:round/><a:headEnd/><a:tailEnd/></a:ln>");
|
||||
switch(pen.DashStyle)
|
||||
{
|
||||
case 1: line_writer.WriteString(L"<a:prstDash val=\"sysDash\"/>"); break;
|
||||
case 2: line_writer.WriteString(L"<a:prstDash val=\"sysDot\"/>"); break;
|
||||
case 3: line_writer.WriteString(L"<a:prstDash val=\"sysDashDot\"/>"); break;
|
||||
case 4: line_writer.WriteString(L"<a:prstDash val=\"sysDashDotDot\"/>"); break;
|
||||
case 5: line_writer.WriteString(L"<a:prstDash val=\"dot\"/>"); break;
|
||||
case 6: line_writer.WriteString(L"<a:prstDash val=\"dash\"/>"); break;
|
||||
case 7: line_writer.WriteString(L"<a:prstDash val=\"lgDash\"/>"); break;
|
||||
case 8: line_writer.WriteString(L"<a:prstDash val=\"dashDot\"/>"); break;
|
||||
case 9: line_writer.WriteString(L"<a:prstDash val=\"lgDashDot\"/>"); break;
|
||||
case 10:line_writer.WriteString(L"<a:prstDash val=\"lgDashDotDot\"/>"); break;
|
||||
}
|
||||
switch(pen.LineJoin)
|
||||
{
|
||||
case 0: line_writer.WriteString(L"<a:bevel/>"); break;
|
||||
case 1: line_writer.WriteString(L"<a:miter/>"); break;
|
||||
case 2: line_writer.WriteString(L"<a:round/>"); break;
|
||||
}
|
||||
|
||||
line_writer.WriteString(L"<a:headEnd" + ConvertLineEnd(pen.LineStartCap, pen.LineStartLength, pen.LineStartWidth) + L"/>");
|
||||
line_writer.WriteString(L"<a:tailEnd" + ConvertLineEnd(pen.LineEndCap, pen.LineEndLength, pen.LineEndWidth) + L"/>");
|
||||
|
||||
line_writer.WriteString(L"</a:ln>");
|
||||
|
||||
return line_writer.GetData();
|
||||
}
|
||||
std::wstring NSPresentationEditor::CShapeWriter::ConvertLineEnd(unsigned char cap, unsigned char length, unsigned char width)
|
||||
{
|
||||
if (cap < 1) return L"";
|
||||
|
||||
std::wstring sResult;
|
||||
|
||||
switch(cap)
|
||||
{
|
||||
case 1: sResult += L" type=\"triangle\""; break;
|
||||
case 2: sResult += L" type=\"stealth\""; break;
|
||||
case 3: sResult += L" type=\"diamond\""; break;
|
||||
case 4: sResult += L" type=\"oval\""; break;
|
||||
case 5: sResult += L" type=\"arrow\""; break;
|
||||
}
|
||||
switch(length)
|
||||
{
|
||||
case 0: sResult += L" len=\"sm\""; break;
|
||||
case 1: sResult += L" len=\"med\""; break;
|
||||
case 2: sResult += L" len=\"lg\""; break;
|
||||
}
|
||||
switch(width)
|
||||
{
|
||||
case 0: sResult += L" w=\"sm\""; break;
|
||||
case 1: sResult += L" w=\"med\""; break;
|
||||
case 2: sResult += L" w=\"lg\""; break;
|
||||
}
|
||||
return sResult;
|
||||
}
|
||||
std::wstring NSPresentationEditor::CShapeWriter::ConvertBrush(CBrush & brush)
|
||||
{
|
||||
NSPresentationEditor::CStringWriter brush_writer;
|
||||
@ -1168,7 +1226,8 @@ std::wstring NSPresentationEditor::CShapeWriter::ConvertShape()
|
||||
}
|
||||
m_oWriter.WriteString(std::wstring(L">"));
|
||||
|
||||
m_oWriter.WriteString(L"<a:off x=\"" + std::to_wstring((int)m_pShapeElement->m_rcBoundsOriginal.left) + L"\" y=\"" + std::to_wstring((int)m_pShapeElement->m_rcBoundsOriginal.top) + L"\"/>");
|
||||
m_oWriter.WriteString(L"<a:off x=\"" + std::to_wstring((int)m_pShapeElement->m_rcBoundsOriginal.left) +
|
||||
L"\" y=\"" + std::to_wstring((int)m_pShapeElement->m_rcBoundsOriginal.top) + L"\"/>");
|
||||
|
||||
int width = m_pShapeElement->m_rcBoundsOriginal.right - m_pShapeElement->m_rcBoundsOriginal.left;
|
||||
int height = m_pShapeElement->m_rcBoundsOriginal.bottom - m_pShapeElement->m_rcBoundsOriginal.top;
|
||||
|
||||
@ -213,6 +213,7 @@ namespace NSPresentationEditor
|
||||
std::wstring ConvertShadow (CShadow & shadow);
|
||||
std::wstring ConvertBrush (CBrush & brush);
|
||||
static std::wstring ConvertColor (CColor & color, long alpha);
|
||||
std::wstring ConvertLineEnd(unsigned char cap, unsigned char length, unsigned char width);
|
||||
// тип рендерера-----------------------------------------------------------------------------
|
||||
virtual HRESULT get_Type(LONG* lType) ;
|
||||
//-------- Функции для работы со страницей --------------------------------------------------
|
||||
|
||||
@ -401,48 +401,47 @@ static std::string GetRecordName(DWORD dwType)
|
||||
case RECORD_TYPE_ROUNDTRIPNOTESMASTERTEXTSTYLES12 : { strName = ("RoundTripNotesMasterTextStyles12"); break; }
|
||||
case RECORD_TYPE_ROUNDTRIPCUSTOMTABLESTYLES12 : { strName = ("RoundTripCustomTableStyles12"); break; }
|
||||
|
||||
//records greater then 0xF000 belong to with Microsoft Office Drawing format also known as Escher
|
||||
case RECORD_TYPE_ESCHER_DGG_CONTAINER : { strName = ("Escher_DrawingGroupContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_DGG : { strName = ("Escher_DrawingGroupRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLSID : { strName = ("Escher_CLSID_Record"); break; }
|
||||
case RECORD_TYPE_ESCHER_OPT : { strName = ("Escher_OPT"); break; }
|
||||
case RECORD_TYPE_ESCHER_BSTORE_CONTAINER : { strName = ("Escher_BlipStoreContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_BSE : { strName = ("Escher_BlipStoreEntry"); break; }
|
||||
case RECORD_TYPE_ESCHER_BLIP_START : { strName = ("Escher_BlipStart"); break; }
|
||||
case RECORD_TYPE_ESCHER_BLIP_END : { strName = ("Escher_BlipEnd"); break; }
|
||||
case RECORD_TYPE_ESCHER_DG_CONTAINER : { strName = ("Escher_DrawingContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_DG : { strName = ("Escher_DrawingRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_REGROUPITEMS : { strName = ("Escher_RegGroupItems"); break; }
|
||||
case RECORD_TYPE_ESCHER_COLORSCHEME : { strName = ("Escher_ColorSheme"); break; }
|
||||
case RECORD_TYPE_ESCHER_SPGR_CONTAINER : { strName = ("Escher_GroupShapeContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_SP_CONTAINER : { strName = ("Escher_ShapeContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_SPGR : { strName = ("Escher_GroupShapeRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_SP : { strName = ("Escher_ShapeRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_TEXTBOX : { strName = ("Escher_TextBox"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTTEXTBOX : { strName = ("Escher_ClientTextBox"); break; }
|
||||
case RECORD_TYPE_ESCHER_ANCHOR : { strName = ("Escher_Anchor"); break; }
|
||||
case RECORD_TYPE_ESCHER_CHILDANCHOR : { strName = ("Escher_ChildAnchor"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTANCHOR : { strName = ("Escher_ClientAnchor"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTDATA : { strName = ("Escher_ClientData"); break; }
|
||||
case RECORD_TYPE_ESCHER_SOLVERCONTAINER : { strName = ("Escher_SolverContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_CONNECTORRULE : { strName = ("Escher_ConnectorRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_ALIGNRULE : { strName = ("Escher_AlignRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_ARCRULE : { strName = ("Escher_ArcRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTRULE : { strName = ("Escher_ClientRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_CALLOUTRULE : { strName = ("Escher_CallOutRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_SELECTION : { strName = ("Escher_Selection"); break; }
|
||||
case RECORD_TYPE_ESCHER_COLORMRU : { strName = ("Escher_ColorMRU"); break; }
|
||||
case RECORD_TYPE_ESCHER_DELETEDPSPL : { strName = ("Escher_DeletedPSPL"); break; }
|
||||
case RECORD_TYPE_ESCHER_SPLITMENUCOLORS : { strName = ("Escher_SplitMenuColors"); break; }
|
||||
case RECORD_TYPE_ESCHER_OLEOBJECT : { strName = ("Escher_OleObject"); break; }
|
||||
case RECORD_TYPE_ESCHER_SECONDARY_OPT : { strName = ("Escher_SecondaryOPT"); break; }
|
||||
case RECORD_TYPE_ESCHER_TETRIARY_OPT : { strName = ("Escher_TetriaryOPT"); break; }
|
||||
case RECORD_TYPE_ESCHER_DGG_CONTAINER : { strName = ("DrawingGroupContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_DGG : { strName = ("DrawingGroupRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLSID : { strName = ("CLSID_Record"); break; }
|
||||
case RECORD_TYPE_ESCHER_OPT : { strName = ("OPT"); break; }
|
||||
case RECORD_TYPE_ESCHER_BSTORE_CONTAINER : { strName = ("BlipStoreContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_BSE : { strName = ("BlipStoreEntry"); break; }
|
||||
case RECORD_TYPE_ESCHER_BLIP_START : { strName = ("BlipStart"); break; }
|
||||
case RECORD_TYPE_ESCHER_BLIP_END : { strName = ("BlipEnd"); break; }
|
||||
case RECORD_TYPE_ESCHER_DG_CONTAINER : { strName = ("DrawingContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_DG : { strName = ("DrawingRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_REGROUPITEMS : { strName = ("RegGroupItems"); break; }
|
||||
case RECORD_TYPE_ESCHER_COLORSCHEME : { strName = ("ColorSheme"); break; }
|
||||
case RECORD_TYPE_ESCHER_SPGR_CONTAINER : { strName = ("GroupShapeContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_SP_CONTAINER : { strName = ("ShapeContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_SPGR : { strName = ("GroupShapeRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_SP : { strName = ("ShapeRecord"); break; }
|
||||
case RECORD_TYPE_ESCHER_TEXTBOX : { strName = ("TextBox"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTTEXTBOX : { strName = ("ClientTextBox"); break; }
|
||||
case RECORD_TYPE_ESCHER_ANCHOR : { strName = ("Anchor"); break; }
|
||||
case RECORD_TYPE_ESCHER_CHILDANCHOR : { strName = ("ChildAnchor"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTANCHOR : { strName = ("ClientAnchor"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTDATA : { strName = ("ClientData"); break; }
|
||||
case RECORD_TYPE_ESCHER_SOLVERCONTAINER : { strName = ("SolverContainer"); break; }
|
||||
case RECORD_TYPE_ESCHER_CONNECTORRULE : { strName = ("ConnectorRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_ALIGNRULE : { strName = ("AlignRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_ARCRULE : { strName = ("ArcRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_CLIENTRULE : { strName = ("ClientRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_CALLOUTRULE : { strName = ("CallOutRule"); break; }
|
||||
case RECORD_TYPE_ESCHER_SELECTION : { strName = ("Selection"); break; }
|
||||
case RECORD_TYPE_ESCHER_COLORMRU : { strName = ("ColorMRU"); break; }
|
||||
case RECORD_TYPE_ESCHER_DELETEDPSPL : { strName = ("DeletedPSPL"); break; }
|
||||
case RECORD_TYPE_ESCHER_SPLITMENUCOLORS : { strName = ("SplitMenuColors"); break; }
|
||||
case RECORD_TYPE_ESCHER_OLEOBJECT : { strName = ("OleObject"); break; }
|
||||
case RECORD_TYPE_ESCHER_SECONDARY_OPT : { strName = ("SecondaryOPT"); break; }
|
||||
case RECORD_TYPE_ESCHER_TETRIARY_OPT : { strName = ("TetriaryOPT"); break; }
|
||||
default: break;
|
||||
};
|
||||
|
||||
if ((dwType > RECORD_TYPE_ESCHER_BLIP_START) && (dwType < RECORD_TYPE_ESCHER_BLIP_END))
|
||||
{
|
||||
strName = ("Escher_Blip");
|
||||
strName = ("Blip");
|
||||
}
|
||||
|
||||
return strName;
|
||||
|
||||
@ -575,212 +575,134 @@ public:
|
||||
}
|
||||
// line --------------------------------------------------------
|
||||
case lineBoolean: //Line Style Boolean Properties
|
||||
{
|
||||
bool bNoLineDrawDash = GETBIT(pProperty->m_lValue, 0);
|
||||
bool bLineFillShape = GETBIT(pProperty->m_lValue, 1);
|
||||
bool bHitTestLine = GETBIT(pProperty->m_lValue, 2);
|
||||
bool bLine = GETBIT(pProperty->m_lValue, 3);
|
||||
bool bArrowheadsOK = GETBIT(pProperty->m_lValue, 4);
|
||||
bool bInsetPenOK = GETBIT(pProperty->m_lValue, 5);
|
||||
bool bInsetPen = GETBIT(pProperty->m_lValue, 6);
|
||||
bool bLineOpaqueBackColor = GETBIT(pProperty->m_lValue, 9);
|
||||
{
|
||||
bool bNoLineDrawDash = GETBIT(pProperty->m_lValue, 0);
|
||||
bool bLineFillShape = GETBIT(pProperty->m_lValue, 1);
|
||||
bool bHitTestLine = GETBIT(pProperty->m_lValue, 2);
|
||||
bool bLine = GETBIT(pProperty->m_lValue, 3);
|
||||
bool bArrowheadsOK = GETBIT(pProperty->m_lValue, 4);
|
||||
bool bInsetPenOK = GETBIT(pProperty->m_lValue, 5);
|
||||
bool bInsetPen = GETBIT(pProperty->m_lValue, 6);
|
||||
bool bLineOpaqueBackColor = GETBIT(pProperty->m_lValue, 9);
|
||||
|
||||
bool bUsefNoLineDrawDash = GETBIT(pProperty->m_lValue, 16);
|
||||
bool bUsefLineFillShape = GETBIT(pProperty->m_lValue, 17);
|
||||
bool bUsefHitTestLine = GETBIT(pProperty->m_lValue, 18);
|
||||
bool bUsefLine = GETBIT(pProperty->m_lValue, 19);
|
||||
bool bUsefArrowheadsOK = GETBIT(pProperty->m_lValue, 20);
|
||||
bool bUsefInsetPenOK = GETBIT(pProperty->m_lValue, 21);
|
||||
bool bUsefInsetPen = GETBIT(pProperty->m_lValue, 22);
|
||||
bool bUsefLineOpaqueBackColor = GETBIT(pProperty->m_lValue, 25);
|
||||
bool bUsefNoLineDrawDash = GETBIT(pProperty->m_lValue, 16);
|
||||
bool bUsefLineFillShape = GETBIT(pProperty->m_lValue, 17);
|
||||
bool bUsefHitTestLine = GETBIT(pProperty->m_lValue, 18);
|
||||
bool bUsefLine = GETBIT(pProperty->m_lValue, 19);
|
||||
bool bUsefArrowheadsOK = GETBIT(pProperty->m_lValue, 20);
|
||||
bool bUsefInsetPenOK = GETBIT(pProperty->m_lValue, 21);
|
||||
bool bUsefInsetPen = GETBIT(pProperty->m_lValue, 22);
|
||||
bool bUsefLineOpaqueBackColor = GETBIT(pProperty->m_lValue, 25);
|
||||
|
||||
if (bUsefLine)
|
||||
pElement->m_bLine = bLine;
|
||||
}break;
|
||||
case lineStyle:
|
||||
if (bUsefLine)
|
||||
pElement->m_bLine = bLine;
|
||||
}break;
|
||||
case lineDashStyle://from Complex
|
||||
{
|
||||
pElement->m_bLine = true;
|
||||
}break;
|
||||
{
|
||||
pElement->m_bLine = true;
|
||||
}break;
|
||||
case lineColor:
|
||||
{
|
||||
SColorAtom oAtom;
|
||||
oAtom.FromValue(pProperty->m_lValue);
|
||||
|
||||
if (oAtom.bSysIndex)
|
||||
pElement->m_oPen.Color = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
||||
else
|
||||
oAtom.ToColor(&pElement->m_oPen.Color);
|
||||
break;
|
||||
}
|
||||
{
|
||||
SColorAtom oAtom;
|
||||
oAtom.FromValue(pProperty->m_lValue);
|
||||
|
||||
if (oAtom.bSysIndex)
|
||||
pElement->m_oPen.Color = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
||||
else
|
||||
oAtom.ToColor(&pElement->m_oPen.Color);
|
||||
}break;
|
||||
case lineOpacity:
|
||||
{
|
||||
pElement->m_oPen.Alpha = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
||||
break;
|
||||
}
|
||||
{
|
||||
pElement->m_oPen.Alpha = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
||||
}break;
|
||||
case lineBackColor:
|
||||
{
|
||||
SColorAtom oAtom;
|
||||
oAtom.FromValue(pProperty->m_lValue);
|
||||
|
||||
if (oAtom.bSysIndex)
|
||||
pElement->m_oPen.Color2 = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
||||
else
|
||||
oAtom.ToColor(&pElement->m_oPen.Color2);
|
||||
{
|
||||
SColorAtom oAtom;
|
||||
oAtom.FromValue(pProperty->m_lValue);
|
||||
|
||||
if (oAtom.bSysIndex)
|
||||
pElement->m_oPen.Color2 = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
||||
else
|
||||
oAtom.ToColor(&pElement->m_oPen.Color2);
|
||||
|
||||
}break;
|
||||
}break;
|
||||
case lineWidth:
|
||||
{
|
||||
pElement->m_oPen.Size = (double)pProperty->m_lValue / EMU_MM;
|
||||
pElement->m_bLine = true;
|
||||
break;
|
||||
}
|
||||
{
|
||||
pElement->m_oPen.Size = (double)pProperty->m_lValue / EMU_MM;
|
||||
pElement->m_bLine = true;
|
||||
}break;
|
||||
case lineStyle:
|
||||
{
|
||||
pElement->m_bLine = true;
|
||||
pElement->m_oPen.LineStyle = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineDashing:
|
||||
{
|
||||
BYTE nDashStyle = 0;
|
||||
switch (pProperty->m_lValue)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
nDashStyle = 0; // solid
|
||||
}break;
|
||||
case 1:
|
||||
case 6:
|
||||
case 7:
|
||||
{
|
||||
nDashStyle = 1; // dash
|
||||
}break;
|
||||
case 2:
|
||||
case 5:
|
||||
{
|
||||
nDashStyle = 2; // dot
|
||||
}break;
|
||||
case 3:
|
||||
case 8:
|
||||
case 9:
|
||||
{
|
||||
nDashStyle = 3; // dashdot
|
||||
}break;
|
||||
case 4:
|
||||
case 10:
|
||||
{
|
||||
nDashStyle = 4;// dashdotdot
|
||||
}break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
pElement->m_bLine = true;
|
||||
pElement->m_oPen.DashStyle = nDashStyle;
|
||||
break;
|
||||
}
|
||||
{
|
||||
pElement->m_bLine = true;
|
||||
pElement->m_oPen.DashStyle = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineJoinStyle:
|
||||
{
|
||||
BYTE nLineJoin = 2;
|
||||
switch (pProperty->m_lValue)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
nLineJoin = 1; // bevel
|
||||
}break;
|
||||
case 1:
|
||||
{
|
||||
nLineJoin = 1; // Miter
|
||||
}break;
|
||||
case 2:
|
||||
{
|
||||
nLineJoin = 2; // round
|
||||
}break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
pElement->m_oPen.LineJoin = nLineJoin;
|
||||
break;
|
||||
}
|
||||
{
|
||||
pElement->m_oPen.LineJoin = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineStartArrowLength:
|
||||
{
|
||||
pElement->m_oPen.LineStartLength = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineEndArrowLength:
|
||||
{
|
||||
pElement->m_oPen.LineEndLength = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineStartArrowWidth:
|
||||
{
|
||||
pElement->m_oPen.LineStartWidth = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineEndArrowWidth:
|
||||
{
|
||||
pElement->m_oPen.LineEndWidth = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineStartArrowhead:
|
||||
{
|
||||
BYTE nStartCap = 0;
|
||||
switch (pProperty->m_lValue)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
{
|
||||
nStartCap = 0x14;
|
||||
}break;
|
||||
case 3:
|
||||
case 4:
|
||||
|
||||
{
|
||||
nStartCap = 2;
|
||||
}break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
pElement->m_oPen.LineStartCap = nStartCap;
|
||||
|
||||
break;
|
||||
}
|
||||
{
|
||||
pElement->m_oPen.LineStartCap = pProperty->m_lValue;
|
||||
}break;
|
||||
case lineEndArrowhead:
|
||||
{
|
||||
BYTE nEndCap = 0;
|
||||
switch (pProperty->m_lValue)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 5:
|
||||
{
|
||||
nEndCap = 0x14;
|
||||
}break;
|
||||
case 3:
|
||||
case 4:
|
||||
|
||||
{
|
||||
nEndCap = 2;
|
||||
}break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
pElement->m_oPen.LineEndCap = nEndCap;
|
||||
break;
|
||||
}
|
||||
{
|
||||
pElement->m_oPen.LineEndCap = pProperty->m_lValue;
|
||||
}break;
|
||||
case shadowType:
|
||||
{
|
||||
pElement->m_oShadow.Type = pProperty->m_lValue;
|
||||
|
||||
}break;
|
||||
{
|
||||
pElement->m_oShadow.Type = pProperty->m_lValue;
|
||||
}break;
|
||||
case shadowOriginX://in emu, relative from center shape
|
||||
{
|
||||
pElement->m_oShadow.OriginX = FixedPointToDouble(pProperty->m_lValue);
|
||||
}break;
|
||||
{
|
||||
pElement->m_oShadow.OriginX = FixedPointToDouble(pProperty->m_lValue);
|
||||
}break;
|
||||
case shadowOriginY:
|
||||
{
|
||||
pElement->m_oShadow.OriginY = FixedPointToDouble(pProperty->m_lValue);
|
||||
}break;
|
||||
{
|
||||
pElement->m_oShadow.OriginY = FixedPointToDouble(pProperty->m_lValue);
|
||||
}break;
|
||||
case shadowColor:
|
||||
{
|
||||
SColorAtom oAtom;
|
||||
oAtom.FromValue(pProperty->m_lValue);
|
||||
{
|
||||
SColorAtom oAtom;
|
||||
oAtom.FromValue(pProperty->m_lValue);
|
||||
|
||||
if (oAtom.bSysIndex)
|
||||
pElement->m_oShadow.Color = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
||||
else
|
||||
oAtom.ToColor(&pElement->m_oShadow.Color);
|
||||
if (oAtom.bSysIndex)
|
||||
pElement->m_oShadow.Color = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
||||
else
|
||||
oAtom.ToColor(&pElement->m_oShadow.Color);
|
||||
|
||||
}break;
|
||||
}break;
|
||||
case shadowWeight:
|
||||
{
|
||||
}break;
|
||||
case shadowOpacity:
|
||||
{
|
||||
pElement->m_oShadow.Alpha = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
||||
}break;
|
||||
{
|
||||
pElement->m_oShadow.Alpha = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
||||
}break;
|
||||
case shadowHighlight:
|
||||
{
|
||||
//оттенок двойной тени
|
||||
}break;
|
||||
{
|
||||
//оттенок двойной тени
|
||||
}break;
|
||||
case shadowOffsetX:
|
||||
{
|
||||
pElement->m_oShadow.DistanceX = ((int)pProperty->m_lValue) / EMU_MM;
|
||||
@ -949,65 +871,80 @@ public:
|
||||
|
||||
switch (pProperty->m_ePID)
|
||||
{
|
||||
// здесь просто применяем проперти...
|
||||
// geometry ----------------------------------------------------
|
||||
// top, left, right, bottom logic
|
||||
case NSOfficeDrawing::metroBlob:
|
||||
{
|
||||
//альтернатива в формате oox
|
||||
//NSFile::CFileBinary f;
|
||||
//f.CreateFileW(L"d:\\test.zip");
|
||||
//f.WriteFile(pProperty->m_pOptions, pProperty->m_lValue);
|
||||
//f.CloseFile();
|
||||
}break;
|
||||
{
|
||||
//альтернатива в формате oox
|
||||
//NSFile::CFileBinary f;
|
||||
//f.CreateFileW(L"d:\\test.zip");
|
||||
//f.WriteFile(pProperty->m_pOptions, pProperty->m_lValue);
|
||||
//f.CloseFile();
|
||||
}break;
|
||||
case NSOfficeDrawing::geoRight:
|
||||
{
|
||||
if (0 < pProperty->m_lValue)
|
||||
pParentShape->m_dWidthLogic = (double)(pProperty->m_lValue);
|
||||
}break;
|
||||
{
|
||||
if (0 < pProperty->m_lValue)
|
||||
pParentShape->m_dWidthLogic = (double)(pProperty->m_lValue);
|
||||
}break;
|
||||
case NSOfficeDrawing::geoBottom:
|
||||
{
|
||||
if (0 < pProperty->m_lValue)
|
||||
pParentShape->m_dHeightLogic = (double)(pProperty->m_lValue);
|
||||
}break;
|
||||
// shapePath
|
||||
{
|
||||
if (0 < pProperty->m_lValue)
|
||||
pParentShape->m_dHeightLogic = (double)(pProperty->m_lValue);
|
||||
}break;
|
||||
case NSOfficeDrawing::shapePath:
|
||||
{
|
||||
pShape->m_oCustomVML.SetPath((RulesType)pProperty->m_lValue);
|
||||
pShape->m_bCustomShape = true;
|
||||
}break;
|
||||
// segmentsInfo
|
||||
{
|
||||
pShape->m_oCustomVML.SetPath((RulesType)pProperty->m_lValue);
|
||||
pShape->m_bCustomShape = true;
|
||||
}break;
|
||||
case NSOfficeDrawing::pSegmentInfo:
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
pShape->m_oCustomVML.LoadSegments(pProperty);
|
||||
pShape->m_bCustomShape = true;
|
||||
}
|
||||
}break;
|
||||
// verticesInfo
|
||||
pShape->m_oCustomVML.LoadSegments(pProperty);
|
||||
pShape->m_bCustomShape = true;
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::pVertices:
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
pShape->m_oCustomVML.LoadVertices(pProperty);
|
||||
pShape->m_bCustomShape = true;
|
||||
}
|
||||
}break;
|
||||
pShape->m_oCustomVML.LoadVertices(pProperty);
|
||||
pShape->m_bCustomShape = true;
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::pConnectionSites:
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
pShape->m_oCustomVML.LoadConnectionSites(pProperty);
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::pConnectionSitesDir:
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
pShape->m_oCustomVML.LoadConnectionSitesDir(pProperty);
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::pGuides:
|
||||
{
|
||||
if (pProperty->m_bComplex/* && pShape->m_eType != sptNotchedCircularArrow*/)
|
||||
{//Тікбұрышты үшбұрыштарды.ppt - slide 25
|
||||
pShape->m_oCustomVML.LoadGuides(pProperty);
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::pInscribe:
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
if (pProperty->m_bComplex && pShape->m_eType != sptNotchedCircularArrow)
|
||||
{//Тікбұрышты үшбұрыштарды.ppt - slide 25
|
||||
pShape->m_oCustomVML.LoadGuides(pProperty);
|
||||
}
|
||||
}break;
|
||||
pShape->m_oCustomVML.LoadInscribe(pProperty);
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::pAdjustHandles:
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
if (pProperty->m_bComplex)
|
||||
{
|
||||
pShape->m_oCustomVML.LoadAHs(pProperty);
|
||||
}
|
||||
}break;
|
||||
pShape->m_oCustomVML.LoadAHs(pProperty);
|
||||
}
|
||||
}break;
|
||||
case NSOfficeDrawing::adjustValue:
|
||||
case NSOfficeDrawing::adjust2Value:
|
||||
case NSOfficeDrawing::adjust3Value:
|
||||
|
||||
@ -1026,6 +1026,26 @@
|
||||
RelativePath="..\..\..\ASCOfficePPTXFile\Editor\Drawing\XmlWriter.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="ppt shapes"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\..\ASCOfficePPTXFile\Editor\Drawing\Shapes\BaseShape\PPTShape\customgeomshape.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\ASCOfficePPTXFile\Editor\Drawing\Shapes\BaseShape\PPTShape\elementsettings.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\ASCOfficePPTXFile\Editor\Drawing\Shapes\BaseShape\PPTShape\formula.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\ASCOfficePPTXFile\Editor\Drawing\Shapes\BaseShape\PPTShape\PPTShape.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="OOXWriter"
|
||||
|
||||
@ -478,10 +478,17 @@ namespace NSPresentationEditor
|
||||
long Alpha;
|
||||
double Size;
|
||||
|
||||
BYTE DashStyle;
|
||||
BYTE LineStartCap;
|
||||
BYTE LineEndCap;
|
||||
BYTE LineJoin;
|
||||
unsigned char DashStyle;
|
||||
unsigned char LineStyle;
|
||||
unsigned char LineJoin;
|
||||
|
||||
unsigned char LineEndCap;
|
||||
unsigned char LineEndLength;
|
||||
unsigned char LineEndWidth;
|
||||
|
||||
unsigned char LineStartCap;
|
||||
unsigned char LineStartLength;
|
||||
unsigned char LineStartWidth;
|
||||
|
||||
double* DashPattern;
|
||||
long Count;
|
||||
@ -492,9 +499,8 @@ namespace NSPresentationEditor
|
||||
double MiterLimit;
|
||||
|
||||
CColor Color2; //backLine
|
||||
public:
|
||||
|
||||
void GetDashPattern(double* arrDashPattern, long& nCount) const
|
||||
void GetDashPattern(double* arrDashPattern, long& nCount) const
|
||||
{
|
||||
if (nCount == Count)
|
||||
{
|
||||
@ -579,10 +585,16 @@ namespace NSPresentationEditor
|
||||
Alpha = 255;
|
||||
Size = 0.26458;
|
||||
|
||||
DashStyle = 0;
|
||||
LineStartCap = 0;
|
||||
LineEndCap = 0;
|
||||
LineJoin = 0;
|
||||
LineStyle = 0; //single(Simple)
|
||||
DashStyle = 0; //Solid
|
||||
LineJoin = 2; //round
|
||||
|
||||
LineStartCap = 0;
|
||||
LineEndCap = 0;
|
||||
LineEndLength = 1; //med
|
||||
LineStartLength = 1;
|
||||
LineEndWidth = 1;
|
||||
LineStartWidth = 1;
|
||||
|
||||
DashPattern = NULL;
|
||||
Count = 0;
|
||||
|
||||
@ -488,6 +488,9 @@ namespace NSCustomVML
|
||||
std::vector<CSegment> m_arSegments;
|
||||
std::vector<CGuide> m_arGuides;
|
||||
std::vector<LONG>* m_pAdjustValues;
|
||||
std::vector<Aggplus::POINT> m_arConnectionSites;
|
||||
std::vector<Aggplus::RECT> m_arInscribe;
|
||||
std::vector<double> m_arConnectionSitesDir;
|
||||
|
||||
bool m_bIsVerticesPresent;
|
||||
bool m_bIsPathPresent;
|
||||
@ -496,7 +499,7 @@ namespace NSCustomVML
|
||||
CPen m_oPen;
|
||||
|
||||
public:
|
||||
CCustomVML() : m_arVertices(), m_arSegments(), m_arGuides(), m_pAdjustValues(NULL)
|
||||
CCustomVML() : m_pAdjustValues(NULL)
|
||||
{
|
||||
m_ePath = rtCurveTo/*rtLineTo*/;
|
||||
|
||||
@ -579,6 +582,63 @@ namespace NSCustomVML
|
||||
m_arVertices.push_back(oPoint);
|
||||
}
|
||||
}
|
||||
void LoadConnectionSitesDir(CProperty* pProperty)
|
||||
{
|
||||
NSOfficeDrawing::CBinaryReader oReader(pProperty->m_pOptions, pProperty->m_lValue);
|
||||
m_arConnectionSitesDir.clear();
|
||||
|
||||
WORD lCount = (WORD)(pProperty->m_lValue / 4);
|
||||
|
||||
for (WORD lIndex = 0; lIndex < lCount; ++lIndex)
|
||||
{
|
||||
DWORD v = oReader.ReadLONG();
|
||||
double val = (double)((WORD)(v >> 16) + ((WORD)(v) / 65536.0));
|
||||
m_arConnectionSitesDir.push_back(val);
|
||||
}
|
||||
}
|
||||
void LoadConnectionSites(CProperty* pProperty)
|
||||
{
|
||||
NSOfficeDrawing::CBinaryReader oReader(pProperty->m_pOptions, pProperty->m_lValue);
|
||||
m_arConnectionSites.clear();
|
||||
|
||||
WORD lCount = (WORD)(pProperty->m_lValue / 8);
|
||||
if (pProperty->m_bIsTruncated)
|
||||
{
|
||||
lCount = (WORD)(pProperty->m_lValue / 4);
|
||||
}
|
||||
|
||||
for (WORD lIndex = 0; lIndex < lCount; ++lIndex)
|
||||
{
|
||||
Aggplus::POINT oPoint;
|
||||
if (pProperty->m_bIsTruncated)
|
||||
{
|
||||
oPoint.x = (short)oReader.ReadWORD();
|
||||
oPoint.y = (short)oReader.ReadWORD();
|
||||
}
|
||||
else
|
||||
{
|
||||
oPoint.x = oReader.ReadLONG();
|
||||
oPoint.y = oReader.ReadLONG();
|
||||
}
|
||||
|
||||
LONG lMinF = (LONG)0x80000000;
|
||||
LONG lMaxF = (LONG)0x8000007F;
|
||||
if (lMinF <= oPoint.x)
|
||||
{
|
||||
int nGuideIndex = (DWORD)oPoint.x - 0x80000000;
|
||||
|
||||
bool b = false;
|
||||
}
|
||||
if (lMinF <= oPoint.y)
|
||||
{
|
||||
int nGuideIndex = (DWORD)oPoint.y - 0x80000000;
|
||||
|
||||
bool b = false;
|
||||
}
|
||||
|
||||
m_arConnectionSites.push_back(oPoint);
|
||||
}
|
||||
}
|
||||
void LoadVertices(CProperty* pProperty)
|
||||
{
|
||||
NSOfficeDrawing::CBinaryReader oReader(pProperty->m_pOptions, pProperty->m_lValue);
|
||||
@ -704,8 +764,38 @@ namespace NSCustomVML
|
||||
oInfo.Read(oReader);
|
||||
m_arGuides.push_back(oInfo);
|
||||
}
|
||||
|
||||
}
|
||||
void LoadInscribe(CProperty* pProperty)
|
||||
{
|
||||
NSOfficeDrawing::CBinaryReader oReader(pProperty->m_pOptions, pProperty->m_lValue);
|
||||
m_arInscribe.clear();
|
||||
|
||||
WORD lCount = (WORD)(pProperty->m_lValue / 16);
|
||||
if (pProperty->m_bIsTruncated)
|
||||
{
|
||||
lCount = (WORD)(pProperty->m_lValue / 8);
|
||||
}
|
||||
|
||||
for (WORD lIndex = 0; lIndex < lCount; ++lIndex)
|
||||
{
|
||||
Aggplus::RECT oRect;
|
||||
if (pProperty->m_bIsTruncated)
|
||||
{
|
||||
oRect.left = (short)oReader.ReadWORD();
|
||||
oRect.right = (short)oReader.ReadWORD();
|
||||
oRect.top = (short)oReader.ReadWORD();
|
||||
oRect.bottom = (short)oReader.ReadWORD();
|
||||
}
|
||||
else
|
||||
{
|
||||
oRect.left = (short)oReader.ReadLONG();
|
||||
oRect.right = (short)oReader.ReadLONG();
|
||||
oRect.top = (short)oReader.ReadLONG();
|
||||
oRect.bottom = (short)oReader.ReadLONG();
|
||||
}
|
||||
m_arInscribe.push_back(oRect);
|
||||
}
|
||||
}
|
||||
void LoadAdjusts(LONG lIndex, LONG lValue)
|
||||
{
|
||||
if (NULL == m_pAdjustValues)
|
||||
|
||||
@ -47,10 +47,10 @@ CPPTShape* CPPTShape::CreateByType(PPTShapes::ShapeType type)
|
||||
CPPTShape* pShape = NULL;
|
||||
switch (type)
|
||||
{
|
||||
// msosptNotchedCircularArrow 0x00000064 A value that SHOULD NOT be used.
|
||||
// msosptNotchedCircularArrow 0x00000064 A value that SHOULD NOT be used.
|
||||
// msosptHostControl 0x000000C9 A value that SHOULD NOT be used.
|
||||
|
||||
case sptNotchedCircularArrow:
|
||||
//case sptNotchedCircularArrow:
|
||||
case sptHostControl:
|
||||
{ pShape = new CPPTShape(); pShape->m_eType = type; break; }
|
||||
case 0: { pShape = new CRectangleType(); break; }
|
||||
|
||||
@ -45,6 +45,12 @@
|
||||
#pragma comment(lib,"Shell32.lib")
|
||||
#pragma comment(lib,"Advapi32.lib")
|
||||
|
||||
#if defined(_WIN64)
|
||||
#pragma comment(lib, "../../build/bin/icu/win_64/icuuc.lib")
|
||||
#elif defined (_WIN32)
|
||||
#pragma comment(lib, "../../build/bin/icu/win_32/icuuc.lib")
|
||||
#endif
|
||||
|
||||
int _tmain(int argc, _TCHAR* argv[])
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="windows-1251"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Version="8,00"
|
||||
Name="XlsFormatTest"
|
||||
ProjectGUID="{C2882DDD-07E6-4314-AD4B-48F43F38D722}"
|
||||
RootNamespace="ASCOfficeOdfFileTest"
|
||||
@ -367,14 +367,6 @@
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\..\build\bin\icu\win_32\icudt.lib"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\build\bin\icu\win_32\icuuc.lib"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
|
||||
@ -312,7 +312,7 @@ namespace NSCustomShapesConvert
|
||||
if (lMaxF > m_arVertices[nIndex].x ) nGuideIndex_x = (DWORD)m_arVertices[nIndex].x - (DWORD)lMinF;
|
||||
if (lMaxF > m_arVertices[nIndex].y ) nGuideIndex_y = (DWORD)m_arVertices[nIndex].y - (DWORD)lMinF;
|
||||
|
||||
if (nGuideIndex_x >= 0 )
|
||||
if (nGuideIndex_x >= 0 && nGuideIndex_x < m_arGuides.size())
|
||||
{
|
||||
strPath += std::to_wstring(m_arGuides[nGuideIndex_x].m_param_value1) + L",";
|
||||
}
|
||||
@ -320,7 +320,7 @@ namespace NSCustomShapesConvert
|
||||
{
|
||||
strPath += std::to_wstring(m_arVertices[nIndex].x) + L",";
|
||||
}
|
||||
if (nGuideIndex_y >= 0)
|
||||
if (nGuideIndex_y >= 0 && nGuideIndex_y < m_arGuides.size())
|
||||
{
|
||||
strPath += std::to_wstring(m_arGuides[nGuideIndex_y].m_param_value1) + L",";
|
||||
}
|
||||
@ -388,7 +388,7 @@ namespace NSCustomShapesConvert
|
||||
if (lMaxF > m_arVertices[nV].x ) nGuideIndex_x = (DWORD)m_arVertices[nV].x - (DWORD)lMinF;
|
||||
if (lMaxF > m_arVertices[nV].y ) nGuideIndex_y = (DWORD)m_arVertices[nV].y - (DWORD)lMinF;
|
||||
|
||||
if (nGuideIndex_x >= 0 )
|
||||
if (nGuideIndex_x >= 0 && nGuideIndex_x < m_arGuides.size() )
|
||||
{
|
||||
strPath += std::to_wstring(m_arGuides[nGuideIndex_x].m_param_value1) + L",";
|
||||
}
|
||||
@ -396,7 +396,7 @@ namespace NSCustomShapesConvert
|
||||
{
|
||||
strPath += std::to_wstring(m_arVertices[nV].x) + L",";
|
||||
}
|
||||
if (nGuideIndex_y >= 0)
|
||||
if (nGuideIndex_y >= 0 && nGuideIndex_y < m_arGuides.size())
|
||||
{
|
||||
strPath += std::to_wstring(m_arGuides[nGuideIndex_y].m_param_value1) + L",";
|
||||
}
|
||||
|
||||
@ -251,6 +251,19 @@ namespace oox
|
||||
case msosptRectangle : return L"rect";
|
||||
case msosptEllipse : return L"ellipse";
|
||||
case msosptLine : return L"line";
|
||||
case msosptActionButtonBlank : return L"actionButtonBlank";
|
||||
case msosptActionButtonHome : return L"actionButtonHome";
|
||||
case msosptActionButtonHelp : return L"actionButtonHelp";
|
||||
case msosptActionButtonInformation : return L"actionButtonInformation";
|
||||
case msosptActionButtonForwardNext : return L"actionButtonForwardNext";
|
||||
case msosptActionButtonBackPrevious : return L"actionButtonBackPrevious";
|
||||
case msosptActionButtonEnd : return L"actionButtonEnd";
|
||||
case msosptActionButtonBeginning : return L"actionButtonBeginning";
|
||||
case msosptActionButtonReturn : return L"actionButtonReturn";
|
||||
case msosptActionButtonDocument : return L"actionButtonDocument";
|
||||
case msosptActionButtonSound : return L"actionButtonSound";
|
||||
case msosptActionButtonMovie : return L"actionButtonMovie";
|
||||
case msosptLeftArrow : return L"leftArrow";
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@ private:
|
||||
if (differenceInLength < 0)
|
||||
differenceInLength = -differenceInLength;
|
||||
|
||||
for (int i = number1.size() - 1; i >= 0; --i)
|
||||
for (int i = (int)(number1.size()) - 1; i >= 0; --i)
|
||||
{
|
||||
add[i] = ((carry-'0')+(number1[i]-'0')+(number2[i]-'0')) + '0';
|
||||
|
||||
@ -364,7 +364,7 @@ private:
|
||||
if (differenceInLength < 0)
|
||||
differenceInLength = -differenceInLength;
|
||||
|
||||
for (int i = number1.length() - 1; i >= 0; --i)
|
||||
for (int i = (int)(number1.length()) - 1; i >= 0; --i)
|
||||
{
|
||||
if (number1[i] < number2[i])
|
||||
{
|
||||
@ -386,13 +386,13 @@ private:
|
||||
n1.swap(n2);
|
||||
|
||||
std::string res = "0";
|
||||
for (int i = n1.length() - 1; i >= 0; --i)
|
||||
for (int i = (int)(n1.length()) - 1; i >= 0; --i)
|
||||
{
|
||||
std::string temp = n2;
|
||||
int currentDigit = n1[i] - '0';
|
||||
int carry = 0;
|
||||
|
||||
for (int j = temp.length() - 1; j >= 0; --j)
|
||||
for (int j = (int)(temp.length()) - 1; j >= 0; --j)
|
||||
{
|
||||
temp[j] = ((temp[j]-'0') * currentDigit) + carry;
|
||||
|
||||
|
||||
@ -11,6 +11,19 @@ TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
QMAKE_CXXFLAGS += -Wall -g
|
||||
|
||||
DEFINES += \
|
||||
LIBXML_READER_ENABLED \
|
||||
LIBXML_PUSH_ENABLED \
|
||||
LIBXML_HTML_ENABLED \
|
||||
LIBXML_XPATH_ENABLED \
|
||||
LIBXML_OUTPUT_ENABLED \
|
||||
LIBXML_C14N_ENABLED \
|
||||
LIBXML_SAX1_ENABLED \
|
||||
LIBXML_TREE_ENABLED \
|
||||
LIBXML_XPTR_ENABLED \
|
||||
IN_LIBXML \
|
||||
LIBXML_STATIC
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/../../../..
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
include(../../../../Common/base.pri)
|
||||
|
||||
@ -305,6 +305,19 @@ namespace XmlUtils
|
||||
strValues.push_back (NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)p->second.c_str(), (long)p->second.length()));
|
||||
}
|
||||
}
|
||||
template<typename T>
|
||||
void ReadAllAttributesA(T& strNames, T& strValues)
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
std::map<std::string, std::string>::iterator p;
|
||||
for (p = m_pBase->m_attributes.begin(); p != m_pBase->m_attributes.end(); ++p)
|
||||
{
|
||||
strNames.push_back(p->first);
|
||||
strValues.push_back(p->second);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void ReadNodeValueBase(const wchar_t* bsName, T& value)
|
||||
{
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include "./XmlCanonicalizator.h"
|
||||
#include "./XmlSignerBase.h"
|
||||
#include "./XmlTransform.h"
|
||||
|
||||
class COOXMLSigner
|
||||
{
|
||||
@ -23,167 +24,6 @@ public:
|
||||
|
||||
std::wstring m_guid;
|
||||
|
||||
public:
|
||||
class COOXMLRelationship
|
||||
{
|
||||
public:
|
||||
std::wstring rid;
|
||||
std::wstring type;
|
||||
std::wstring target;
|
||||
std::wstring target_mode;
|
||||
|
||||
public:
|
||||
|
||||
COOXMLRelationship()
|
||||
{
|
||||
}
|
||||
|
||||
COOXMLRelationship(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
rid = node.GetAttribute("Id");
|
||||
type = node.GetAttribute("Type");
|
||||
target = node.GetAttribute("Target");
|
||||
|
||||
CheckTargetMode();
|
||||
}
|
||||
|
||||
std::wstring GetXml()
|
||||
{
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
builder.WriteString(L"<Relationship Id=\"");
|
||||
builder.WriteEncodeXmlString(rid);
|
||||
builder.WriteString(L"\" Type=\"");
|
||||
builder.WriteEncodeXmlString(type);
|
||||
builder.WriteString(L"\" Target=\"");
|
||||
builder.WriteEncodeXmlString(target);
|
||||
builder.WriteString(L"\" TargetMode=\"");
|
||||
builder.WriteEncodeXmlString(target_mode);
|
||||
builder.WriteString(L"\" />");
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j)
|
||||
{
|
||||
return i.rid < j.rid;
|
||||
}
|
||||
|
||||
protected:
|
||||
void CheckTargetMode()
|
||||
{
|
||||
if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp"))
|
||||
target_mode = L"External";
|
||||
else
|
||||
target_mode = L"Internal";
|
||||
}
|
||||
};
|
||||
|
||||
class COOXMLRelationships
|
||||
{
|
||||
public:
|
||||
std::vector<COOXMLRelationship> rels;
|
||||
|
||||
public:
|
||||
|
||||
COOXMLRelationships()
|
||||
{
|
||||
}
|
||||
|
||||
COOXMLRelationships(std::wstring& file)
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
if (!oNode.FromXmlFile(file))
|
||||
return;
|
||||
|
||||
XmlUtils::CXmlNodes oNodes;
|
||||
if (!oNode.GetNodes(L"Relationship", oNodes))
|
||||
return;
|
||||
|
||||
int nCount = oNodes.GetCount();
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode oRel;
|
||||
oNodes.GetAt(i, oRel);
|
||||
rels.push_back(COOXMLRelationship(oRel));
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring GetXml()
|
||||
{
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
|
||||
builder.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
|
||||
|
||||
// sort by rId
|
||||
std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare);
|
||||
|
||||
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
|
||||
builder.WriteString(i->GetXml());
|
||||
|
||||
builder.WriteString(L"</Relationships>");
|
||||
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
std::wstring GetTransforms()
|
||||
{
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
|
||||
builder.WriteString(L"<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">");
|
||||
|
||||
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
|
||||
{
|
||||
builder.WriteString(L"<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"");
|
||||
builder.WriteEncodeXmlString(i->rid);
|
||||
builder.WriteString(L"\" />");
|
||||
}
|
||||
|
||||
builder.WriteString(L"</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
|
||||
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
void CheckOriginSigs(std::wstring& file)
|
||||
{
|
||||
int rId = 0;
|
||||
std::vector<COOXMLRelationship>::iterator i = rels.begin();
|
||||
while (i != rels.end())
|
||||
{
|
||||
if (0 == i->target.find(L"_xmlsignatures/"))
|
||||
return;
|
||||
|
||||
std::wstring rid = i->rid;
|
||||
rid = rid.substr(3);
|
||||
|
||||
int nTemp = std::stoi(rid);
|
||||
|
||||
if (nTemp > rId)
|
||||
rId = nTemp;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
std::string sXmlA;
|
||||
NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA);
|
||||
|
||||
std::string::size_type pos = sXmlA.rfind("</Relationships>");
|
||||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
rId++;
|
||||
std::string sRet = sXmlA.substr(0, pos);
|
||||
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
|
||||
Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin\" Target=\"_xmlsignatures/origin.sigs\"/>\
|
||||
</Relationships>");
|
||||
|
||||
NSFile::CFileBinary::Remove(file);
|
||||
|
||||
NSFile::CFileBinary oFile;
|
||||
oFile.CreateFileW(file);
|
||||
oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length());
|
||||
oFile.CloseFile();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
COOXMLSigner(const std::wstring& sFolder, ICertificate* pContext)
|
||||
{
|
||||
@ -204,7 +44,7 @@ public:
|
||||
std::wstring sXml = L"<Reference URI=\"" + file + L"?ContentType=" + content_type + L"\">";
|
||||
sXml += L"<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>";
|
||||
sXml += L"<DigestValue>";
|
||||
sXml += UTF8_TO_U(m_certificate->GetHash(m_sFolder + file));
|
||||
sXml += UTF8_TO_U(m_certificate->GetHash(m_sFolder + file, OOXML_HASH_ALG_SHA1));
|
||||
sXml += L"</DigestValue>";
|
||||
sXml += L"</Reference>";
|
||||
return sXml;
|
||||
@ -214,7 +54,7 @@ public:
|
||||
{
|
||||
std::string sXmlSigned = U_TO_UTF8(xml);
|
||||
sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0);
|
||||
return m_certificate->GetHash(sXmlSigned);
|
||||
return m_certificate->GetHash(sXmlSigned, OOXML_HASH_ALG_SHA1);
|
||||
}
|
||||
|
||||
std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true)
|
||||
@ -259,7 +99,7 @@ public:
|
||||
|
||||
std::wstring GetRelsReference(const std::wstring& file)
|
||||
{
|
||||
COOXMLRelationships oRels(m_sFolder + file);
|
||||
COOXMLRelationships oRels(m_sFolder + file, true);
|
||||
|
||||
if (L"/_rels/.rels" == file)
|
||||
{
|
||||
@ -651,7 +491,7 @@ Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-sign
|
||||
m_signed_info.WriteString("<Reference Type=\"http://uri.etsi.org/01903#SignedProperties\" URI=\"#idSignedProperties\">");
|
||||
m_signed_info.WriteString("<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
|
||||
m_signed_info.WriteString("<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>");
|
||||
m_signed_info.WriteString(m_certificate->GetHash(sXmlTmp));
|
||||
m_signed_info.WriteString(m_certificate->GetHash(sXmlTmp, OOXML_HASH_ALG_SHA1));
|
||||
m_signed_info.WriteString("</DigestValue></Reference>");
|
||||
|
||||
return (L"<Object><xd:QualifyingProperties xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Target=\"#idPackageSignature\">\
|
||||
|
||||
248
DesktopEditor/xmlsec/src/OOXMLVerifier.h
Normal file
248
DesktopEditor/xmlsec/src/OOXMLVerifier.h
Normal file
@ -0,0 +1,248 @@
|
||||
#ifndef _XML_OOXMLVERIFIER_H_
|
||||
#define _XML_OOXMLVERIFIER_H_
|
||||
|
||||
#include "./XmlCanonicalizator.h"
|
||||
#include "./XmlTransform.h"
|
||||
#include "./XmlCertificate.h"
|
||||
|
||||
#define OOXML_SIGNATURE_VALID 0
|
||||
#define OOXML_SIGNATURE_INVALID 1
|
||||
#define OOXML_SIGNATURE_NOTSUPPORTED 2
|
||||
#define OOXML_SIGNATURE_BAD 3
|
||||
|
||||
class COOXMLSignature
|
||||
{
|
||||
private:
|
||||
int m_valid;
|
||||
std::string m_guid;
|
||||
ICertificate* m_cert;
|
||||
|
||||
std::string m_sImageValidBase64;
|
||||
std::string m_sImageInvalidBase64;
|
||||
|
||||
private:
|
||||
XmlUtils::CXmlNode m_node; // signature file
|
||||
|
||||
class CXmlStackNamespaces
|
||||
{
|
||||
public:
|
||||
std::wstring m_namespaces;
|
||||
XmlUtils::CXmlNode m_node;
|
||||
|
||||
public:
|
||||
CXmlStackNamespaces(const CXmlStackNamespaces& src)
|
||||
{
|
||||
m_namespaces = src.m_namespaces;
|
||||
m_node = src.m_node;
|
||||
}
|
||||
CXmlStackNamespaces()
|
||||
{
|
||||
}
|
||||
CXmlStackNamespaces(const XmlUtils::CXmlNode& node)
|
||||
{
|
||||
m_node = node;
|
||||
}
|
||||
|
||||
CXmlStackNamespaces& operator=(const CXmlStackNamespaces& src)
|
||||
{
|
||||
m_namespaces = src.m_namespaces;
|
||||
m_node = src.m_node;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CXmlStackNamespaces GetById(const std::string& id)
|
||||
{
|
||||
return GetByIdRec(*this, id);
|
||||
}
|
||||
|
||||
CXmlStackNamespaces GetByIdRec(CXmlStackNamespaces& stack, const std::string& id)
|
||||
{
|
||||
if (stack.m_node.GetAttributeA("Id") == id)
|
||||
return stack;
|
||||
|
||||
CXmlStackNamespaces ret = stack;
|
||||
|
||||
std::vector<std::wstring> _names;
|
||||
std::vector<std::wstring> _values;
|
||||
ret.m_node.ReadAllAttributes(_names, _values);
|
||||
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
oBuilder.WriteString(L" ");
|
||||
for (std::vector<std::wstring>::iterator i = _names.begin(), j = _values.begin(); i != _names.end(); i++, j++)
|
||||
{
|
||||
if (i->find(L"xmlns") == 0)
|
||||
{
|
||||
oBuilder.WriteString(*i);
|
||||
oBuilder.WriteString(L"=\"");
|
||||
oBuilder.WriteEncodeXmlString(*j);
|
||||
oBuilder.WriteString(L"\"");
|
||||
}
|
||||
}
|
||||
|
||||
if (oBuilder.GetCurSize() != 1)
|
||||
ret.m_namespaces += oBuilder.GetData();
|
||||
|
||||
XmlUtils::CXmlNodes oNodes;
|
||||
if (stack.m_node.GetChilds(oNodes))
|
||||
{
|
||||
int nCount = oNodes.GetCount();
|
||||
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
oNodes.GetAt(i, ret.m_node);
|
||||
CXmlStackNamespaces _retRecursion = ret.GetByIdRec(ret, id);
|
||||
if (_retRecursion.m_node.IsValid())
|
||||
return _retRecursion;
|
||||
}
|
||||
}
|
||||
|
||||
return CXmlStackNamespaces();
|
||||
}
|
||||
|
||||
std::string GetXml()
|
||||
{
|
||||
std::wstring sXml = m_node.GetXml();
|
||||
if (!m_namespaces.empty())
|
||||
{
|
||||
std::wstring sName = m_node.GetName();
|
||||
|
||||
std::wstring sXmlFind = L"<" + sName + L" ";
|
||||
if (0 == sXml.find(sXmlFind))
|
||||
sXml.replace(0, sXmlFind.length(), L"<" + sName + L" " + m_namespaces + L" ");
|
||||
}
|
||||
|
||||
return U_TO_UTF8(sXml);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
COOXMLSignature()
|
||||
{
|
||||
m_valid = OOXML_SIGNATURE_INVALID;
|
||||
m_guid = "";
|
||||
m_cert = NULL;
|
||||
}
|
||||
~COOXMLSignature()
|
||||
{
|
||||
RELEASEOBJECT(m_cert);
|
||||
}
|
||||
|
||||
public:
|
||||
int GetValid()
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
std::string GetGuid()
|
||||
{
|
||||
return m_guid;
|
||||
}
|
||||
ICertificate* GetCertificate()
|
||||
{
|
||||
return m_cert;
|
||||
}
|
||||
std::string GetImageValidBase64()
|
||||
{
|
||||
return m_sImageValidBase64;
|
||||
}
|
||||
std::string GetImageInvalidBase64()
|
||||
{
|
||||
return m_sImageInvalidBase64;
|
||||
}
|
||||
|
||||
public:
|
||||
void Check()
|
||||
{
|
||||
// 1) get cert
|
||||
XmlUtils::CXmlNode oNodeCert = m_node.ReadNode(L"KeyInfo").ReadNode(L"X509Data").ReadNode(L"X509Certificate");
|
||||
if (!oNodeCert.IsValid())
|
||||
{
|
||||
m_valid = OOXML_SIGNATURE_NOTSUPPORTED;
|
||||
return;
|
||||
}
|
||||
m_cert = new CCertificate();
|
||||
if (!m_cert->LoadFromBase64Data(U_TO_UTF8(oNodeCert.GetText())))
|
||||
{
|
||||
m_valid = OOXML_SIGNATURE_NOTSUPPORTED;
|
||||
return;
|
||||
}
|
||||
|
||||
// 2) Objects
|
||||
XmlUtils::CXmlNodes nodesReferences;
|
||||
m_node.ReadNode(L"SignedInfo").GetNodes(L"Reference", nodesReferences);
|
||||
|
||||
CXmlStackNamespaces stack(m_node);
|
||||
int nCount = nodesReferences.GetCount();
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
XmlUtils::CXmlNode nodeRef;
|
||||
nodesReferences.GetAt(i, nodeRef);
|
||||
|
||||
std::string sId = nodeRef.GetAttributeA("URI");
|
||||
if (0 == sId.find("#"))
|
||||
sId = sId.substr(1);
|
||||
|
||||
CXmlStackNamespaces _stack = stack.GetById(sId);
|
||||
std::string sTmp = _stack.GetXml();
|
||||
XML_UNUSED(sTmp);
|
||||
}
|
||||
}
|
||||
|
||||
friend class COOXMLVerifier;
|
||||
};
|
||||
|
||||
class COOXMLVerifier
|
||||
{
|
||||
public:
|
||||
std::wstring m_sFolder;
|
||||
std::vector<COOXMLSignature*> m_arSignatures;
|
||||
|
||||
public:
|
||||
COOXMLVerifier(const std::wstring& sFolder)
|
||||
{
|
||||
m_sFolder = sFolder;
|
||||
|
||||
if (!NSFile::CFileBinary::Exists(m_sFolder + L"/_xmlsignatures/origin.sigs"))
|
||||
return;
|
||||
|
||||
XmlUtils::CXmlNode oContentTypes;
|
||||
if (!oContentTypes.FromXmlFile(m_sFolder + L"/[Content_Types].xml"))
|
||||
return;
|
||||
|
||||
XmlUtils::CXmlNodes oOverrides = oContentTypes.GetNodes(L"Override");
|
||||
int nCount = oOverrides.GetCount();
|
||||
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
XmlUtils::CXmlNode node;
|
||||
oOverrides.GetAt(i, node);
|
||||
|
||||
if (node.GetAttributeA("ContentType") != "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")
|
||||
continue;
|
||||
|
||||
std::wstring sFile = m_sFolder + node.GetAttribute("PartName");
|
||||
XmlUtils::CXmlNode nodeSig;
|
||||
if (!nodeSig.FromXmlFile(sFile))
|
||||
continue;
|
||||
|
||||
if (nodeSig.GetName() != L"Signature")
|
||||
continue;
|
||||
|
||||
COOXMLSignature* pSignature = new COOXMLSignature();
|
||||
pSignature->m_node = nodeSig;
|
||||
pSignature->Check();
|
||||
|
||||
m_arSignatures.push_back(pSignature);
|
||||
}
|
||||
}
|
||||
~COOXMLVerifier()
|
||||
{
|
||||
for (std::vector<COOXMLSignature*>::iterator i = m_arSignatures.begin(); i != m_arSignatures.end(); i++)
|
||||
{
|
||||
COOXMLSignature* v = *i;
|
||||
RELEASEOBJECT(v);
|
||||
}
|
||||
m_arSignatures.clear();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_XML_OOXMLVERIFIER_H_
|
||||
@ -8,6 +8,10 @@
|
||||
#include "../../xml/include/xmlutils.h"
|
||||
#include "../../xml/libxml2/include/libxml/c14n.h"
|
||||
|
||||
#ifndef XML_UNUSED
|
||||
#define XML_UNUSED( arg ) ( (arg) = (arg) )
|
||||
#endif
|
||||
|
||||
class CXmlCanonicalizator
|
||||
{
|
||||
private:
|
||||
@ -33,11 +37,14 @@ private:
|
||||
|
||||
static int buffer_xmlBufferIOClose(CXmlBuffer* buf)
|
||||
{
|
||||
XML_UNUSED(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int buffer_xmlC14NIsVisibleCallback(void * user_data, xmlNodePtr node, xmlNodePtr parent)
|
||||
{
|
||||
XML_UNUSED(user_data);
|
||||
XML_UNUSED(parent);
|
||||
if (node->type == XML_TEXT_NODE)
|
||||
{
|
||||
const char* cur = (char*)node->content;
|
||||
@ -53,7 +60,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
static std::string Execute(const std::string& sXml, int mode)
|
||||
static std::string Execute(const std::string& sXml, int mode = XML_C14N_1_0, bool withComments = false)
|
||||
{
|
||||
xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length());
|
||||
|
||||
@ -63,21 +70,18 @@ public:
|
||||
&bufferC14N,
|
||||
NULL);
|
||||
|
||||
xmlC14NExecute(xmlDoc, buffer_xmlC14NIsVisibleCallback, NULL, mode, NULL, 0, _buffer);
|
||||
xmlC14NExecute(xmlDoc, buffer_xmlC14NIsVisibleCallback, NULL, mode, NULL, withComments ? 1 : 0, _buffer);
|
||||
|
||||
xmlOutputBufferClose(_buffer);
|
||||
|
||||
return bufferC14N.builder.GetData();
|
||||
}
|
||||
|
||||
static std::string Execute(const std::wstring& sXmlFile, int mode)
|
||||
static std::string Execute(const std::wstring& sXmlFile, int mode = XML_C14N_1_0, bool withComments = false)
|
||||
{
|
||||
std::string sXml;
|
||||
NSFile::CFileBinary::ReadAllTextUtf8A(sXmlFile, sXml);
|
||||
|
||||
xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length());
|
||||
|
||||
return Execute(sXml, mode);
|
||||
return Execute(sXml, mode, withComments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
17
DesktopEditor/xmlsec/src/XmlCertificate.h
Normal file
17
DesktopEditor/xmlsec/src/XmlCertificate.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _XMLSIGNER_CERTIFICATE_H_
|
||||
#define _XMLSIGNER_CERTIFICATE_H_
|
||||
|
||||
#ifdef WIN32
|
||||
#include "XmlSigner_mscrypto.h"
|
||||
#define CCertificate CCertificate_mscrypto
|
||||
#endif
|
||||
|
||||
#if defined(_LINUX) && !defined(_MAC)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MAC
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _XMLSIGNER_CERTIFICATE_H_
|
||||
199
DesktopEditor/xmlsec/src/XmlRels.h
Normal file
199
DesktopEditor/xmlsec/src/XmlRels.h
Normal file
@ -0,0 +1,199 @@
|
||||
#ifndef _XML_RELS_H_
|
||||
#define _XML_RELS_H_
|
||||
|
||||
#include "./XmlCanonicalizator.h"
|
||||
|
||||
class COOXMLRelationship
|
||||
{
|
||||
public:
|
||||
std::wstring rid;
|
||||
std::wstring type;
|
||||
std::wstring target;
|
||||
std::wstring target_mode;
|
||||
|
||||
public:
|
||||
|
||||
COOXMLRelationship()
|
||||
{
|
||||
}
|
||||
|
||||
COOXMLRelationship(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
rid = node.GetAttribute("Id");
|
||||
type = node.GetAttribute("Type");
|
||||
target = node.GetAttribute("Target");
|
||||
|
||||
CheckTargetMode();
|
||||
}
|
||||
|
||||
std::wstring GetXml()
|
||||
{
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
builder.WriteString(L"<Relationship Id=\"");
|
||||
builder.WriteEncodeXmlString(rid);
|
||||
builder.WriteString(L"\" Type=\"");
|
||||
builder.WriteEncodeXmlString(type);
|
||||
builder.WriteString(L"\" Target=\"");
|
||||
builder.WriteEncodeXmlString(target);
|
||||
builder.WriteString(L"\" TargetMode=\"");
|
||||
builder.WriteEncodeXmlString(target_mode);
|
||||
builder.WriteString(L"\" />");
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
static bool Compare(const COOXMLRelationship& i, const COOXMLRelationship& j)
|
||||
{
|
||||
return i.rid < j.rid;
|
||||
}
|
||||
|
||||
protected:
|
||||
void CheckTargetMode()
|
||||
{
|
||||
if (0 == target.find(L"http") || 0 == target.find(L"www") || 0 == target.find(L"ftp"))
|
||||
target_mode = L"External";
|
||||
else
|
||||
target_mode = L"Internal";
|
||||
}
|
||||
};
|
||||
|
||||
class COOXMLRelationships
|
||||
{
|
||||
public:
|
||||
std::vector<COOXMLRelationship> rels;
|
||||
|
||||
public:
|
||||
|
||||
COOXMLRelationships()
|
||||
{
|
||||
}
|
||||
|
||||
COOXMLRelationships(const std::string& xml, std::map<std::wstring, bool>* check_need = NULL)
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
if (!oNode.FromXmlStringA(xml))
|
||||
return;
|
||||
|
||||
FromXmlNode(oNode, check_need);
|
||||
}
|
||||
|
||||
COOXMLRelationships(const std::wstring& xml, const bool& is_file, std::map<std::wstring, bool>* check_need = NULL)
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
|
||||
if (!is_file)
|
||||
{
|
||||
if (!oNode.FromXmlString(xml))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!oNode.FromXmlFile(xml))
|
||||
return;
|
||||
}
|
||||
|
||||
FromXmlNode(oNode, check_need);
|
||||
}
|
||||
|
||||
void FromXmlNode(XmlUtils::CXmlNode& oNode, std::map<std::wstring, bool>* check_need = NULL)
|
||||
{
|
||||
XmlUtils::CXmlNodes oNodes;
|
||||
if (!oNode.GetNodes(L"Relationship", oNodes))
|
||||
return;
|
||||
|
||||
int nCount = oNodes.GetCount();
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode oRel;
|
||||
oNodes.GetAt(i, oRel);
|
||||
|
||||
if (NULL == check_need)
|
||||
{
|
||||
rels.push_back(COOXMLRelationship(oRel));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring sRid = oRel.GetAttribute("Id");
|
||||
if (check_need->find(sRid) != check_need->end())
|
||||
rels.push_back(COOXMLRelationship(oRel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring GetXml()
|
||||
{
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
|
||||
builder.WriteString(L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">");
|
||||
|
||||
// sort by rId
|
||||
std::sort(rels.begin(), rels.end(), COOXMLRelationship::Compare);
|
||||
|
||||
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
|
||||
builder.WriteString(i->GetXml());
|
||||
|
||||
builder.WriteString(L"</Relationships>");
|
||||
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
std::wstring GetTransforms()
|
||||
{
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
|
||||
builder.WriteString(L"<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">");
|
||||
|
||||
for (std::vector<COOXMLRelationship>::iterator i = rels.begin(); i != rels.end(); i++)
|
||||
{
|
||||
builder.WriteString(L"<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"");
|
||||
builder.WriteEncodeXmlString(i->rid);
|
||||
builder.WriteString(L"\" />");
|
||||
}
|
||||
|
||||
builder.WriteString(L"</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>");
|
||||
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
void CheckOriginSigs(std::wstring& file)
|
||||
{
|
||||
int rId = 0;
|
||||
std::vector<COOXMLRelationship>::iterator i = rels.begin();
|
||||
while (i != rels.end())
|
||||
{
|
||||
if (0 == i->target.find(L"_xmlsignatures/"))
|
||||
return;
|
||||
|
||||
std::wstring rid = i->rid;
|
||||
rid = rid.substr(3);
|
||||
|
||||
int nTemp = std::stoi(rid);
|
||||
|
||||
if (nTemp > rId)
|
||||
rId = nTemp;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
std::string sXmlA;
|
||||
NSFile::CFileBinary::ReadAllTextUtf8A(file, sXmlA);
|
||||
|
||||
std::string::size_type pos = sXmlA.rfind("</Relationships>");
|
||||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
rId++;
|
||||
std::string sRet = sXmlA.substr(0, pos);
|
||||
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
|
||||
Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin\" Target=\"_xmlsignatures/origin.sigs\"/>\
|
||||
</Relationships>");
|
||||
|
||||
NSFile::CFileBinary::Remove(file);
|
||||
|
||||
NSFile::CFileBinary oFile;
|
||||
oFile.CreateFileW(file);
|
||||
oFile.WriteFile((BYTE*)sRet.c_str(), (DWORD)sRet.length());
|
||||
oFile.CloseFile();
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_XML_RELS_H_
|
||||
@ -8,6 +8,9 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#define OOXML_HASH_ALG_SHA1 0
|
||||
#define OOXML_HASH_ALG_INVALID 1
|
||||
|
||||
class ICertificate
|
||||
{
|
||||
public:
|
||||
@ -27,14 +30,26 @@ public:
|
||||
virtual std::string GetCertificateHash() = 0;
|
||||
|
||||
public:
|
||||
virtual std::string Sign(std::string sXml) = 0;
|
||||
virtual std::string GetHash(unsigned char* pData, unsigned int nSize) = 0;
|
||||
virtual std::string GetHash(std::string& sXml) = 0;
|
||||
virtual std::string GetHash(std::wstring& sXmlFile) = 0;
|
||||
virtual bool Verify(std::string& sXml, std::string& sXmlSignature) = 0;
|
||||
virtual std::string Sign(std::string sXml) = 0;
|
||||
virtual std::string GetHash(unsigned char* pData, unsigned int nSize, int nAlg) = 0;
|
||||
virtual std::string GetHash(std::string& sXml, int nAlg) = 0;
|
||||
virtual std::string GetHash(std::wstring& sXmlFile, int nAlg) = 0;
|
||||
virtual bool Verify(std::string& sXml, std::string& sXmlSignature, int nAlg) = 0;
|
||||
|
||||
virtual bool LoadFromBase64Data(const std::string& data) = 0;
|
||||
virtual int ShowCertificate() = 0;
|
||||
|
||||
public:
|
||||
virtual bool ShowSelectDialog() = 0;
|
||||
|
||||
static int GetOOXMLHashAlg(const std::string& sAlg)
|
||||
{
|
||||
if ("http://www.w3.org/2000/09/xmldsig#rsa-sha1" == sAlg ||
|
||||
"http://www.w3.org/2000/09/xmldsig#sha1" == sAlg)
|
||||
return OOXML_HASH_ALG_SHA1;
|
||||
|
||||
return OOXML_HASH_ALG_INVALID;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _XMLSIGNER_BASE_H_
|
||||
|
||||
@ -14,27 +14,40 @@ public:
|
||||
HCERTSTORE m_store;
|
||||
PCCERT_CONTEXT m_context;
|
||||
|
||||
protected:
|
||||
BYTE* m_rawData;
|
||||
int m_rawDataLen;
|
||||
|
||||
public:
|
||||
CCertificate_mscrypto() : ICertificate()
|
||||
{
|
||||
m_store = NULL;
|
||||
m_context = NULL;
|
||||
|
||||
m_rawData = NULL;
|
||||
m_rawDataLen = 0;
|
||||
}
|
||||
CCertificate_mscrypto(PCCERT_CONTEXT ctx) : ICertificate()
|
||||
{
|
||||
m_store = NULL;
|
||||
m_context = ctx;
|
||||
|
||||
m_rawData = NULL;
|
||||
m_rawDataLen = 0;
|
||||
}
|
||||
|
||||
virtual ~CCertificate_mscrypto()
|
||||
{
|
||||
if (m_store != NULL)
|
||||
if (m_store != NULL || m_rawData != NULL)
|
||||
{
|
||||
if (NULL != m_context)
|
||||
CertFreeCertificateContext(m_context);
|
||||
|
||||
CertCloseStore(m_store, 0);
|
||||
RELEASEARRAYOBJECTS(m_rawData);
|
||||
}
|
||||
|
||||
if (m_store != NULL)
|
||||
CertCloseStore(m_store, 0);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -80,7 +93,7 @@ public:
|
||||
|
||||
virtual std::string GetCertificateHash()
|
||||
{
|
||||
return GetHash(m_context->pbCertEncoded, (unsigned int)m_context->cbCertEncoded);
|
||||
return GetHash(m_context->pbCertEncoded, (unsigned int)m_context->cbCertEncoded, OOXML_HASH_ALG_SHA1);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -153,8 +166,11 @@ public:
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
virtual std::string GetHash(unsigned char* pData, unsigned int nSize)
|
||||
virtual std::string GetHash(unsigned char* pData, unsigned int nSize, int nAlg)
|
||||
{
|
||||
if (nAlg == OOXML_HASH_ALG_INVALID)
|
||||
return "";
|
||||
|
||||
BOOL bResult = TRUE;
|
||||
DWORD dwKeySpec = 0;
|
||||
HCRYPTHASH hHash = NULL;
|
||||
@ -168,7 +184,7 @@ public:
|
||||
if (!bResult)
|
||||
return "";
|
||||
|
||||
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
|
||||
bResult = CryptCreateHash(hCryptProv, GetHashId(nAlg), 0, 0, &hHash);
|
||||
if (!bResult)
|
||||
{
|
||||
CryptReleaseContext(hCryptProv, 0);
|
||||
@ -218,12 +234,12 @@ public:
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
virtual std::string GetHash(std::string& sXml)
|
||||
virtual std::string GetHash(std::string& sXml, int nAlg)
|
||||
{
|
||||
return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length());
|
||||
return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length(), nAlg);
|
||||
}
|
||||
|
||||
virtual std::string GetHash(std::wstring& sXmlFile)
|
||||
virtual std::string GetHash(std::wstring& sXmlFile, int nAlg)
|
||||
{
|
||||
BYTE* pFileData = NULL;
|
||||
DWORD dwFileDataLen = 0;
|
||||
@ -232,13 +248,13 @@ public:
|
||||
if (0 == dwFileDataLen)
|
||||
return "";
|
||||
|
||||
std::string sReturn = GetHash(pFileData, dwFileDataLen);
|
||||
std::string sReturn = GetHash(pFileData, dwFileDataLen, nAlg);
|
||||
|
||||
RELEASEARRAYOBJECTS(pFileData);
|
||||
return sReturn;
|
||||
}
|
||||
|
||||
virtual bool Verify(std::string& sXml, std::string& sXmlSignature)
|
||||
virtual bool Verify(std::string& sXml, std::string& sXmlSignature, int nAlg)
|
||||
{
|
||||
DWORD dwKeySpec = 0;
|
||||
HCRYPTHASH hHash = NULL;
|
||||
@ -250,7 +266,7 @@ public:
|
||||
if (!bResult)
|
||||
return FALSE;
|
||||
|
||||
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
|
||||
bResult = CryptCreateHash(hCryptProv, GetHashId(nAlg), 0, 0, &hHash);
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
@ -286,6 +302,28 @@ public:
|
||||
return bResultRet && bResult;
|
||||
}
|
||||
|
||||
virtual bool LoadFromBase64Data(const std::string& data)
|
||||
{
|
||||
RELEASEARRAYOBJECTS(m_rawData);
|
||||
if (!NSFile::CBase64Converter::Decode(data.c_str(), (int)data.length(), m_rawData, m_rawDataLen))
|
||||
return false;
|
||||
|
||||
m_context = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, m_rawData, m_rawDataLen);
|
||||
if (!m_context)
|
||||
{
|
||||
RELEASEARRAYOBJECTS(m_rawData);
|
||||
m_rawDataLen = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual int ShowCertificate()
|
||||
{
|
||||
return (int)CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, m_context, NULL, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual bool ShowSelectDialog()
|
||||
{
|
||||
@ -309,6 +347,17 @@ private:
|
||||
for(BYTE* p = dst + size - 1; p >= dst; ++src, --p)
|
||||
(*p) = (*src);
|
||||
}
|
||||
|
||||
ALG_ID GetHashId(int nAlg)
|
||||
{
|
||||
switch (nAlg)
|
||||
{
|
||||
case OOXML_HASH_ALG_SHA1:
|
||||
return CALG_SHA1;
|
||||
default:
|
||||
return CALG_SHA1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _XMLSIGNER_MSCRYPTO_H_
|
||||
|
||||
186
DesktopEditor/xmlsec/src/XmlTransform.h
Normal file
186
DesktopEditor/xmlsec/src/XmlTransform.h
Normal file
@ -0,0 +1,186 @@
|
||||
#ifndef _XML_TRANSFORM_H_
|
||||
#define _XML_TRANSFORM_H_
|
||||
|
||||
#include "./XmlRels.h"
|
||||
|
||||
class IXmlTransform
|
||||
{
|
||||
protected:
|
||||
std::string m_algorithm;
|
||||
|
||||
public:
|
||||
IXmlTransform()
|
||||
{
|
||||
m_algorithm = "";
|
||||
}
|
||||
virtual ~IXmlTransform()
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
virtual std::string Transform(const std::string& sXml) = 0;
|
||||
virtual void LoadFromXml(XmlUtils::CXmlNode& node) = 0;
|
||||
|
||||
static IXmlTransform* GetFromType(const std::string& alg);
|
||||
};
|
||||
|
||||
class CXmlTransformRelationship : public IXmlTransform
|
||||
{
|
||||
protected:
|
||||
std::map<std::wstring, bool> m_arIds;
|
||||
|
||||
public:
|
||||
CXmlTransformRelationship() : IXmlTransform()
|
||||
{
|
||||
m_algorithm = "http://schemas.openxmlformats.org/package/2006/RelationshipTransform";
|
||||
}
|
||||
|
||||
virtual std::string Transform(const std::string& xml)
|
||||
{
|
||||
COOXMLRelationships _rels(xml, &m_arIds);
|
||||
return U_TO_UTF8(_rels.GetXml());
|
||||
}
|
||||
|
||||
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
XmlUtils::CXmlNodes oNodesIds;
|
||||
node.GetChilds(oNodesIds);
|
||||
|
||||
int nCount = oNodesIds.GetCount();
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode _node;
|
||||
oNodesIds.GetAt(i, _node);
|
||||
|
||||
std::wstring sType = _node.GetAttribute("SourceId");
|
||||
if (!sType.empty())
|
||||
m_arIds.insert(std::pair<std::wstring, bool>(sType, true));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CXmlTransformC14N : public IXmlTransform
|
||||
{
|
||||
protected:
|
||||
int m_mode;
|
||||
bool m_comments;
|
||||
|
||||
public:
|
||||
CXmlTransformC14N() : IXmlTransform()
|
||||
{
|
||||
m_mode = -1;
|
||||
m_comments = false;
|
||||
}
|
||||
|
||||
bool CheckC14NTransform(const std::string& alg)
|
||||
{
|
||||
m_mode = -1;
|
||||
if ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315" == alg)
|
||||
{
|
||||
m_mode = XML_C14N_1_0;
|
||||
m_comments = false;
|
||||
}
|
||||
else if ("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" == alg)
|
||||
{
|
||||
m_mode = XML_C14N_1_0;
|
||||
m_comments = true;
|
||||
}
|
||||
else if ("http://www.w3.org/2006/12/xml-c14n11" == alg)
|
||||
{
|
||||
m_mode = XML_C14N_1_1;
|
||||
m_comments = false;
|
||||
}
|
||||
else if ("http://www.w3.org/2006/12/xml-c14n11#WithComments" == alg)
|
||||
{
|
||||
m_mode = XML_C14N_1_1;
|
||||
m_comments = true;
|
||||
}
|
||||
else if ("http://www.w3.org/2001/10/xml-exc-c14n#" == alg)
|
||||
{
|
||||
m_mode = XML_C14N_EXCLUSIVE_1_0;
|
||||
m_comments = false;
|
||||
}
|
||||
else if ("http://www.w3.org/2001/10/xml-exc-c14n#WithComments" == alg)
|
||||
{
|
||||
m_mode = XML_C14N_EXCLUSIVE_1_0;
|
||||
m_comments = true;
|
||||
}
|
||||
return (-1 != m_mode) ? true : false;
|
||||
}
|
||||
|
||||
virtual std::string Transform(const std::string& xml)
|
||||
{
|
||||
// TODO
|
||||
return xml;
|
||||
}
|
||||
|
||||
virtual void LoadFromXml(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
// none
|
||||
XML_UNUSED(node);
|
||||
}
|
||||
};
|
||||
|
||||
IXmlTransform* IXmlTransform::GetFromType(const std::string& alg)
|
||||
{
|
||||
if (true)
|
||||
{
|
||||
CXmlTransformRelationship* transform = new CXmlTransformRelationship();
|
||||
if (transform->m_algorithm == alg)
|
||||
return transform;
|
||||
RELEASEOBJECT(transform);
|
||||
}
|
||||
if (true)
|
||||
{
|
||||
CXmlTransformC14N* transform = new CXmlTransformC14N();
|
||||
if (transform->CheckC14NTransform(alg))
|
||||
return transform;
|
||||
RELEASEOBJECT(transform);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class CXmlTransforms
|
||||
{
|
||||
protected:
|
||||
std::vector<IXmlTransform*> m_transforms;
|
||||
bool m_valid;
|
||||
|
||||
public:
|
||||
CXmlTransforms(XmlUtils::CXmlNode& node)
|
||||
{
|
||||
m_valid = true;
|
||||
|
||||
XmlUtils::CXmlNodes oNodes = node.GetNodes(L"Transform");
|
||||
int nCount = oNodes.GetCount();
|
||||
for (int i = 0; i < nCount; ++i)
|
||||
{
|
||||
XmlUtils::CXmlNode nodeTransform;
|
||||
oNodes.GetAt(i, nodeTransform);
|
||||
|
||||
IXmlTransform* pTransform = IXmlTransform::GetFromType(nodeTransform.GetAttributeA("Algorithm"));
|
||||
if (NULL == pTransform)
|
||||
{
|
||||
m_valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
pTransform->LoadFromXml(nodeTransform);
|
||||
m_transforms.push_back(pTransform);
|
||||
}
|
||||
}
|
||||
|
||||
~CXmlTransforms()
|
||||
{
|
||||
for (std::vector<IXmlTransform*>::iterator i = m_transforms.begin(); i != m_transforms.end(); i++)
|
||||
{
|
||||
IXmlTransform* t = *i;
|
||||
RELEASEOBJECT(t);
|
||||
}
|
||||
m_transforms.clear();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif //_XML_TRANSFORM_H_
|
||||
@ -6,7 +6,9 @@ TEMPLATE = app
|
||||
CONFIG += console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
DEFINES += UNICODE
|
||||
DEFINES -= \
|
||||
UNICODE \
|
||||
_UNICODE
|
||||
|
||||
CORE_ROOT_DIR = $$PWD/../../../..
|
||||
PWD_ROOT_DIR = $$PWD
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "../../src/XmlCanonicalizator.h"
|
||||
#include "../../src/XmlSigner_mscrypto.h"
|
||||
#include "../../src/XmlCertificate.h"
|
||||
#include "../../src/OOXMLSigner.h"
|
||||
#include "../../src/OOXMLVerifier.h"
|
||||
|
||||
#pragma comment (lib, "crypt32.lib")
|
||||
#pragma comment (lib, "cryptui.lib")
|
||||
@ -12,17 +12,34 @@ void main(void)
|
||||
//std::wstring sSignId = L"{39B6B9C7-60AD-45A2-9F61-40C74A24042E}";
|
||||
|
||||
std::wstring sFolderOOXML = L"D:\\555";
|
||||
std::wstring sSignId = L"{9792D33F-AB37-4E5B-A465-481B9465818B}";
|
||||
|
||||
CCertificate_mscrypto oCertificate;
|
||||
if (!oCertificate.ShowSelectDialog())
|
||||
return;
|
||||
if (false)
|
||||
{
|
||||
std::wstring sSignId = L"{9792D33F-AB37-4E5B-A465-481B9465818B}";
|
||||
|
||||
COOXMLSigner oOOXMLSigner(sFolderOOXML, &oCertificate);
|
||||
CCertificate oCertificate;
|
||||
if (!oCertificate.ShowSelectDialog())
|
||||
return;
|
||||
|
||||
oOOXMLSigner.SetGuid(sSignId);
|
||||
oOOXMLSigner.SetImageValid(NSFile::GetProcessDirectory() + L"/../../../resources/valid.png");
|
||||
oOOXMLSigner.SetImageInvalid(NSFile::GetProcessDirectory() + L"/../../../resources/invalid.png");
|
||||
COOXMLSigner oOOXMLSigner(sFolderOOXML, &oCertificate);
|
||||
|
||||
oOOXMLSigner.Sign();
|
||||
oOOXMLSigner.SetGuid(sSignId);
|
||||
oOOXMLSigner.SetImageValid(NSFile::GetProcessDirectory() + L"/../../../resources/valid.png");
|
||||
oOOXMLSigner.SetImageInvalid(NSFile::GetProcessDirectory() + L"/../../../resources/invalid.png");
|
||||
|
||||
oOOXMLSigner.Sign();
|
||||
}
|
||||
else
|
||||
{
|
||||
COOXMLVerifier oVerifier(sFolderOOXML);
|
||||
|
||||
size_t nCount = oVerifier.m_arSignatures.size();
|
||||
for (std::vector<COOXMLSignature*>::iterator i = oVerifier.m_arSignatures.begin(); i != oVerifier.m_arSignatures.end(); i++)
|
||||
{
|
||||
COOXMLSignature* pSign = *i;
|
||||
XML_UNUSED(pSign);
|
||||
}
|
||||
|
||||
XML_UNUSED(nCount);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user