Commit 32922220 authored by Alexey Golubev's avatar Alexey Golubev

Merge branch 'release/v4.1.0'

parents 06a7ed6d 21fb5c56
...@@ -2,6 +2,20 @@ build/ ...@@ -2,6 +2,20 @@ build/
dictionaries/ dictionaries/
LicenceManager/ LicenceManager/
Common/boost_1_58_0 Common/boost_1_58_0
Common/3dParty/boost/boost_1_58_0
Common/3dParty/icu/win_64
Common/3dParty/icu/win_32
Common/3dParty/icu/linux_64
Common/3dParty/icu/linux_32
Common/3dParty/icu/mac_64
Common/3dParty/v8/v8
Common/3dParty/v8/depot_tools
Common/3dParty/v8/win_64
Common/3dParty/v8/win_32
Common/3dParty/v8/linux_64
Common/3dParty/v8/linux_32
Common/3dParty/v8/mac_64
**/core_build
**/Release **/Release
**/Debug **/Debug
*.user *.user
...@@ -20,3 +34,7 @@ ASCOfficeXlsFile2/win32/_ASCOfficeXlsFile2_i.c ...@@ -20,3 +34,7 @@ ASCOfficeXlsFile2/win32/_ASCOfficeXlsFile2_i.c
ASCOfficeXlsFile2/win32/_ASCOfficeXlsFile2_p.c ASCOfficeXlsFile2/win32/_ASCOfficeXlsFile2_p.c
ASCOfficeXlsFile2/win32/dlldata.c ASCOfficeXlsFile2/win32/dlldata.c
OfficeUtils/win32/OfficeUtilsLib/OfficeUtilsLib/ReadMe.txt OfficeUtils/win32/OfficeUtilsLib/OfficeUtilsLib/ReadMe.txt
*.obj
*.pdb
*.tlb
*.idb
...@@ -38,7 +38,7 @@ namespace DocFileFormat ...@@ -38,7 +38,7 @@ namespace DocFileFormat
//verison 1995 and earler //verison 1995 and earler
sprmOldPIstd = 2, sprmOldPIstd = 2,
sprmOldPIstdPermute = 3, sprmOldPIstdPermute = 3,
sprmOldPIncLv1 = 4, sprmOldPIncLvl = 4,
sprmOldPJc = 5, sprmOldPJc = 5,
sprmOldPFSideBySide = 6, sprmOldPFSideBySide = 6,
sprmOldPFKeep = 7, sprmOldPFKeep = 7,
...@@ -98,6 +98,7 @@ namespace DocFileFormat ...@@ -98,6 +98,7 @@ namespace DocFileFormat
sprmOldCChse = 73, sprmOldCChse = 73,
sprmOldCSymbol = 74, sprmOldCSymbol = 74,
sprmOldCFOle2 = 75, sprmOldCFOle2 = 75,
sprmCOldHighlight = 77,
sprmOldCIstd = 80, sprmOldCIstd = 80,
sprmOldCIstdPermute = 81, sprmOldCIstdPermute = 81,
sprmOldCDefault = 82, sprmOldCDefault = 82,
......
...@@ -39,20 +39,40 @@ namespace DocFileFormat ...@@ -39,20 +39,40 @@ namespace DocFileFormat
AnnotationReferenceDescriptor *newObject = new AnnotationReferenceDescriptor(); AnnotationReferenceDescriptor *newObject = new AnnotationReferenceDescriptor();
//read the user initials (LPXCharBuffer9) //read the user initials (LPXCharBuffer9)
short cch = reader->ReadInt16();
unsigned char *chars = reader->ReadBytes(18, true); if (reader->olderVersion)
{
short cch = reader->ReadByte();
unsigned char *chars = reader->ReadBytes(cch, true);
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(newObject->m_UserInitials), chars, cch , ENCODING_WINDOWS_1250);
newObject->m_AuthorIndex = reader->ReadUInt16();
newObject->m_BookmarkId = reader->ReadInt16();
RELEASEARRAYOBJECTS(chars);
chars = reader->ReadBytes(length - cch - 1 - 4, true);
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(newObject->m_UserInitials), chars, ( cch * 2 ), ENCODING_UTF16); RELEASEARRAYOBJECTS(chars);
}
else
{
short cch = reader->ReadInt16();
newObject->m_AuthorIndex = reader->ReadUInt16(); unsigned char *chars = reader->ReadBytes(18, true);
//skip 4 bytes FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(newObject->m_UserInitials), chars, ( cch * 2 ), ENCODING_UTF16);
reader->ReadBytes(4, false);
newObject->m_AuthorIndex = reader->ReadUInt16();
newObject->m_BookmarkId = reader->ReadInt32(); //skip 4 bytes
reader->ReadBytes(4, false);
newObject->m_BookmarkId = reader->ReadInt32();
RELEASEARRAYOBJECTS(chars);
}
RELEASEARRAYOBJECTS(chars);
return static_cast<ByteStructure*>(newObject); return static_cast<ByteStructure*>(newObject);
} }
......
...@@ -39,6 +39,12 @@ namespace DocFileFormat ...@@ -39,6 +39,12 @@ namespace DocFileFormat
{ {
public: public:
static const int STRUCTURE_SIZE = 30; static const int STRUCTURE_SIZE = 30;
static const int STRUCTURE_SIZE_OLD = 20;
static const int GetSize(bool bOldVersion)
{
return bOldVersion ? STRUCTURE_SIZE_OLD : STRUCTURE_SIZE;
}
inline std::wstring GetUserInitials() const inline std::wstring GetUserInitials() const
{ {
......
...@@ -301,6 +301,10 @@ namespace DocFileFormat ...@@ -301,6 +301,10 @@ namespace DocFileFormat
colorVal->SetValue( rgbColor.GetString() ); colorVal->SetValue( rgbColor.GetString() );
}break; }break;
case sprmCOldHighlight:
{
appendValueElement( parent, _T( "highlight" ), FormatUtils::MapValueToWideString( iter->Arguments[1], &Global::ColorIdentifier[0][0], 17, 12 ).c_str(), true );
}break;
case sprmCHighlight: case sprmCHighlight:
{ {
appendValueElement( parent, _T( "highlight" ), FormatUtils::MapValueToWideString( iter->Arguments[0], &Global::ColorIdentifier[0][0], 17, 12 ).c_str(), true ); appendValueElement( parent, _T( "highlight" ), FormatUtils::MapValueToWideString( iter->Arguments[0], &Global::ColorIdentifier[0][0], 17, 12 ).c_str(), true );
......
...@@ -70,6 +70,7 @@ namespace OpenXmlContentTypes ...@@ -70,6 +70,7 @@ namespace OpenXmlContentTypes
static const TCHAR* Png = _T("image/png"); static const TCHAR* Png = _T("image/png");
static const TCHAR* Tiff = _T("image/tiff"); static const TCHAR* Tiff = _T("image/tiff");
static const TCHAR* Wmf = _T("image/x-wmf"); static const TCHAR* Wmf = _T("image/x-wmf");
static const TCHAR* Bmp = _T("image/bmp");
} }
namespace WordprocessingMLContentTypes namespace WordprocessingMLContentTypes
......
...@@ -65,24 +65,11 @@ namespace DocFileFormat ...@@ -65,24 +65,11 @@ namespace DocFileFormat
{ {
ConversionContext context( doc, docx ); ConversionContext context( doc, docx );
//Write numbering.xml //Write styles.xml
if (doc->listTable) if (doc->Styles)
{
NumberingMapping numberingMapping( &context );
doc->listTable->Convert( &numberingMapping );
}
if ( progress != NULL )
{ {
progress->OnProgress( progress->caller, DOC_ONPROGRESSEVENT_ID, 810000 ); StyleSheetMapping styleSheetMapping( &context );
doc->Styles->Convert( &styleSheetMapping );
short cancel = 0;
progress->OnProgressEx( progress->caller, DOC_ONPROGRESSEVENT_ID, 810000, &cancel );
if ( cancel != 0 )
{
return S_FALSE;
}
} }
//write document.xml and the header and footers //write document.xml and the header and footers
...@@ -91,10 +78,10 @@ namespace DocFileFormat ...@@ -91,10 +78,10 @@ namespace DocFileFormat
if ( progress != NULL ) if ( progress != NULL )
{ {
progress->OnProgress( progress->caller, DOC_ONPROGRESSEVENT_ID, 825000 ); progress->OnProgress( progress->caller, DOC_ONPROGRESSEVENT_ID, 810000 );
short cancel = 0; short cancel = 0;
progress->OnProgressEx( progress->caller, DOC_ONPROGRESSEVENT_ID, 825000, &cancel ); progress->OnProgressEx( progress->caller, DOC_ONPROGRESSEVENT_ID, 810000, &cancel );
if ( cancel != 0 ) if ( cancel != 0 )
{ {
...@@ -102,11 +89,12 @@ namespace DocFileFormat ...@@ -102,11 +89,12 @@ namespace DocFileFormat
} }
} }
//Write styles.xml
if (doc->Styles) //Write numbering.xml
if (doc->listTable)
{ {
StyleSheetMapping styleSheetMapping( &context ); NumberingMapping numberingMapping( &context );
doc->Styles->Convert( &styleSheetMapping ); doc->listTable->Convert( &numberingMapping );
} }
if ( progress != NULL ) if ( progress != NULL )
......
...@@ -142,6 +142,7 @@ namespace DocFileFormat ...@@ -142,6 +142,7 @@ namespace DocFileFormat
int _footnoteNr; int _footnoteNr;
int _endnoteNr; int _endnoteNr;
int _commentNr; int _commentNr;
bool _isTextBoxContent;
int _isSectionPageBreak; //0 - not set, 1 -page break, 2 - continues int _isSectionPageBreak; //0 - not set, 1 -page break, 2 - continues
bool _writeInstrText; bool _writeInstrText;
bool _writeWebHidden; bool _writeWebHidden;
......
/*
* (c) Copyright Ascensio System SIA 2010-2016
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "DrawingPrimitives.h"
#include "VirtualStreamReader.h"
namespace DocFileFormat
{
DrawingPrimitive * DrawingPrimitive::Create(VirtualStreamReader* reader, int length, short dpk)
{
DrawingPrimitive * dp = NULL;
int pos1 = reader->GetPosition();
switch(dpk)
{
case 0x0000:
dp = new DrawingPrimitiveGroup(reader, length, true);
break;
case 0x0001:
dp = new DrawingPrimitiveLine(reader, length);
break;
case 0x0002: //textbox
dp = new DrawingPrimitiveTextBox(reader, length);
break;
case 0x0003: //rectangle
dp = new DrawingPrimitiveRect(reader, length);
break;
case 0x0004: //elipse
dp = new DrawingPrimitiveElipse(reader, length);
break;
case 0x0005: //arc
dp = new DrawingPrimitiveArc(reader, length);
break;
case 0x0006: //polyline
dp = new DrawingPrimitivePolyline(reader, length);
break;
case 0x0007: //callout textbox
dp = new DrawingPrimitiveCTextBox(reader, length);
break;
case 0x0008: //callout textbox
dp = new DrawingPrimitiveGroup(reader, length, false);
break;
case 0x0009: //sample primitive holding default values
default:
dp = new DrawingPrimitive(reader, length);
break;
}
if (dp)
{
dp->type = dpk;
}
int pos2 = reader->GetPosition();
if (pos2 - pos1 < length && dpk != 0 && dpk != 8)
{
int sz = length - (pos2 - pos1);
unsigned char * data = reader->ReadBytes(sz, true);
if (data)
delete []data;
}
return dp;
}
DrawingPrimitive::DrawingPrimitive(VirtualStreamReader *reader, int length) :
lineWeight(0), lineStyle(0), lineColor(0), fillBack(0), fillFore(0), fillPattern(0), shadowX(0), shadowY(0)
{
xa = reader->ReadInt16();
ya = reader->ReadInt16();
dxa = reader->ReadInt16();
dya = reader->ReadInt16();
}
void DrawingPrimitive::read_fill(VirtualStreamReader* reader)
{
fillBack = read_color(reader);
fillFore = read_color(reader);
fillPattern = reader->ReadInt16();
}
void DrawingPrimitive::read_shadow(VirtualStreamReader* reader)
{
shadowInt = reader->ReadInt16();
shadowX = reader->ReadInt16();
shadowY = reader->ReadInt16();
}
void DrawingPrimitive::read_line(VirtualStreamReader* reader)
{
lineColor = read_color(reader);
lineWeight = reader->ReadInt16();
lineStyle = reader->ReadInt16();
}
long DrawingPrimitive::read_color(VirtualStreamReader* reader)
{
//int ind = reader->ReadUInt32();
//return shemeDefaultColor[ind];
unsigned r = reader->ReadByte();
unsigned g = reader->ReadByte();
unsigned b = reader->ReadByte();
unsigned a = reader->ReadByte();
return ( (r<<16) | (g<<8) | (b) );
}
DrawingPrimitiveGroup::DrawingPrimitiveGroup(VirtualStreamReader *reader, int length, bool start) : DrawingPrimitive(reader, length)
{
strVmlType = L"v:group";
bStart = start;
val = reader->ReadInt16();
}
DrawingPrimitiveLine::DrawingPrimitiveLine(VirtualStreamReader *reader, int length, bool read_as_line) : DrawingPrimitive(reader, length)
{
strVmlType = L"v:line";
if (!read_as_line) return;
read_start_end (reader);
read_line(reader);
read_epp(reader);
read_shadow(reader);
}
void DrawingPrimitiveLine::read_epp(VirtualStreamReader* reader)
{
unsigned short f = reader->ReadUInt16();
eppsStart = FormatUtils::BitmaskToInt (f, 0x0003);
eppwStart = FormatUtils::BitmaskToInt (f, 0x000c);
epplStart = FormatUtils::BitmaskToInt (f, 0x0030);
f = reader->ReadUInt16();
eppsEnd = FormatUtils::BitmaskToInt (f, 0x0003);
eppwEnd = FormatUtils::BitmaskToInt (f, 0x000c);
epplEnd = FormatUtils::BitmaskToInt (f, 0x0030);
}
void DrawingPrimitiveLine::read_start_end(VirtualStreamReader* reader)
{
xaStart = reader->ReadInt16();
yaStart = reader->ReadInt16();
xaEnd = reader->ReadInt16();
yaEnd = reader->ReadInt16();
}
DrawingPrimitiveRect::DrawingPrimitiveRect(VirtualStreamReader *reader, int length) : DrawingPrimitive(reader, length)
{
strVmlType = L"v:rect";
read_line(reader);
read_fill(reader);
read_shadow(reader);
unsigned short f = reader->ReadUInt16();
fRoundCorners = FormatUtils::BitmaskToInt (f, 0x0001);
zaShape = FormatUtils::BitmaskToInt (f, 0x000e);
}
DrawingPrimitiveArc::DrawingPrimitiveArc(VirtualStreamReader *reader, int length) : DrawingPrimitive(reader, length)
{
strVmlType = L"v:oval";//L"v:shape";
read_line (reader);
read_fill (reader);
read_shadow (reader);
unsigned short f = reader->ReadUInt16();
fLeft = FormatUtils::BitmaskToInt (f, 0x00ff);
fUp = FormatUtils::BitmaskToInt (f, 0xff00);
}
DrawingPrimitiveElipse::DrawingPrimitiveElipse(VirtualStreamReader *reader, int length) : DrawingPrimitive(reader, length)
{
strVmlType = L"v:oval";
read_line (reader);
read_fill (reader);
read_shadow (reader);
}
DrawingPrimitiveTextBox::DrawingPrimitiveTextBox(VirtualStreamReader *reader, int length) : DrawingPrimitiveRect(reader, length)
{
}
DrawingPrimitiveCTextBox::DrawingPrimitiveCTextBox(VirtualStreamReader *reader, int length) : DrawingPrimitive(reader, length)
{
strVmlType = L"v:rect";
txbx = NULL;
polyline = NULL;
unsigned short f = reader->ReadUInt16();
dzaOffset = reader->ReadUInt16();
dzaDescent = reader->ReadUInt16();
dzaLength = reader->ReadUInt16();
unsigned short dpk_txbx = reader->ReadUInt16();
unsigned short cb_txbx = reader->ReadUInt16();
txbx = new DrawingPrimitiveTextBox(reader, cb_txbx);
unsigned short dpk_polyline = reader->ReadUInt16();
unsigned short cb_polyline = reader->ReadUInt16();
polyline = new DrawingPrimitivePolyline(reader, cb_polyline);
}
DrawingPrimitiveCTextBox::~DrawingPrimitiveCTextBox()
{
if (polyline) delete polyline;
if (txbx) delete txbx;
}
DrawingPrimitivePolyline::DrawingPrimitivePolyline(VirtualStreamReader *reader, int length) : DrawingPrimitiveLine(reader, length, false)
{
strVmlType = L"v:shape";
read_line(reader);
read_fill(reader);
read_epp(reader);
read_shadow(reader);
unsigned short f = reader->ReadUInt16();
fPolygon = FormatUtils::BitmaskToInt (f, 0x0001);
count = FormatUtils::BitmaskToInt (f, 0x00fe);
read_start_end(reader);
for (int i = 0; i < count; i++)
{
std::pair<short, short> point;
point.first = reader->ReadInt16();
point.second = reader->ReadInt16();
arPoints.push_back(point);
}
}
}
/*
* (c) Copyright Ascensio System SIA 2010-2016
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include <string>
#include <vector>
#include "IVisitable.h"
class VirtualStreamReader;
namespace DocFileFormat
{
class DrawingPrimitive
{
public:
DrawingPrimitive(VirtualStreamReader* reader, int length) ;
virtual ~DrawingPrimitive() {}
short type;
short xa;
short ya;
short dxa;
short dya;
short lineWeight;
short lineStyle;
long lineColor;
long fillBack;
long fillFore;
short fillPattern;
short shadowInt;
short shadowX;
short shadowY;
std::wstring strVmlType;
void read_fill (VirtualStreamReader* reader);
void read_line (VirtualStreamReader* reader);
void read_shadow(VirtualStreamReader* reader);
long read_color (VirtualStreamReader* reader);
static DrawingPrimitive * Create(VirtualStreamReader* reader, int length, short dpk);
};
class DrawingPrimitiveGroup : public DrawingPrimitive
{
public:
DrawingPrimitiveGroup(VirtualStreamReader* reader, int length, bool start);
bool bStart;
short val;
};
class DrawingPrimitiveLine : public DrawingPrimitive
{
public:
DrawingPrimitiveLine(VirtualStreamReader* reader, int length, bool read_as_line = true) ;
void read_epp ( VirtualStreamReader* reader);
void read_start_end (VirtualStreamReader* reader);
short xaStart;
short yaStart;
short xaEnd;
short yaEnd;
short eppsStart; //Start EndPoint Property Style
short eppwStart; //Start EndPoint Property Weight
short epplStart; //Start EndPoint Property length
short eppsEnd; //End EndPoint Property Style
short eppwEnd; //End EndPoint Property Weight
short epplEnd; //End EndPoint Property length
};
class DrawingPrimitiveRect: public DrawingPrimitive
{
public:
DrawingPrimitiveRect(VirtualStreamReader* reader, int length);
bool fRoundCorners;
unsigned short zaShape;
};
class DrawingPrimitiveTextBox: public DrawingPrimitiveRect
{
public:
DrawingPrimitiveTextBox(VirtualStreamReader* reader, int length);
};
class DrawingPrimitiveElipse: public DrawingPrimitive
{
public:
DrawingPrimitiveElipse(VirtualStreamReader* reader, int length);
};
class DrawingPrimitivePolyline: public DrawingPrimitiveLine
{
public:
DrawingPrimitivePolyline(VirtualStreamReader* reader, int length);
bool fPolygon;
short count;
std::vector<std::pair<short, short>> arPoints;
};
class DrawingPrimitiveCTextBox: public DrawingPrimitive
{
public:
DrawingPrimitiveCTextBox(VirtualStreamReader* reader, int length);
virtual ~DrawingPrimitiveCTextBox();
unsigned short dzaOffset;
unsigned short dzaDescent;
unsigned short dzaLength;
DrawingPrimitiveTextBox *txbx;
DrawingPrimitivePolyline *polyline;
};
class DrawingPrimitiveArc: public DrawingPrimitive
{
public:
DrawingPrimitiveArc(VirtualStreamReader* reader, int length);
bool fLeft;
bool fUp;
};
//-------------------------------------------------------------------------------------
class DrawingPrimitives : public IVisitable, public std::vector<DrawingPrimitive*>
{
public:
DrawingPrimitives () {}
};
}
\ No newline at end of file
...@@ -49,46 +49,120 @@ namespace DocFileFormat ...@@ -49,46 +49,120 @@ namespace DocFileFormat
if(0x0001 == vMajor) // RC4 encryption header structure if(0x0001 == vMajor) // RC4 encryption header structure
{// fib->m_FibBase.lKey == 52 {// fib->m_FibBase.lKey == 52
crypt_data.Salt.b1 = tStream.ReadUInt32(); bStandard = true;
crypt_data.Salt.b2 = tStream.ReadUInt32();
crypt_data.Salt.b3 = tStream.ReadUInt32(); crypt_data_rc4.Salt.b1 = tStream.ReadUInt32();
crypt_data.Salt.b4 = tStream.ReadUInt32(); crypt_data_rc4.Salt.b2 = tStream.ReadUInt32();
crypt_data_rc4.Salt.b3 = tStream.ReadUInt32();
crypt_data_rc4.Salt.b4 = tStream.ReadUInt32();
crypt_data.EncryptedVerifier.b1 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifier.b1 = tStream.ReadUInt32();
crypt_data.EncryptedVerifier.b2 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifier.b2 = tStream.ReadUInt32();
crypt_data.EncryptedVerifier.b3 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifier.b3 = tStream.ReadUInt32();
crypt_data.EncryptedVerifier.b4 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifier.b4 = tStream.ReadUInt32();
crypt_data.EncryptedVerifierHash.b1 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifierHash.b1 = tStream.ReadUInt32();
crypt_data.EncryptedVerifierHash.b2 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifierHash.b2 = tStream.ReadUInt32();
crypt_data.EncryptedVerifierHash.b3 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifierHash.b3 = tStream.ReadUInt32();
crypt_data.EncryptedVerifierHash.b4 = tStream.ReadUInt32(); crypt_data_rc4.EncryptedVerifierHash.b4 = tStream.ReadUInt32();
} }
else else
{ {
// unsigned short flags = tStream.ReadUInt16(); bStandard = false;
crypt_data_aes.bAgile = false;
// bool fCryptoAPI = GETBIT(flags, 2);
// bool fDocProps = GETBIT(flags, 3); unsigned short flags = tStream.ReadUInt32();
// bool fExternal = GETBIT(flags, 4); unsigned char *pDataRead = NULL;
// bool fAES = GETBIT(flags, 5);
bool fCryptoAPI = GETBIT(flags, 1);
// _UINT32 EncryptionHeaderSize = tStream.ReadUInt32(); bool fDocProps = GETBIT(flags, 2);
////header bool fExternal = GETBIT(flags, 3);
// bool fAES = GETBIT(flags, 4);
// tStream.ReadUInt32(); // reserved (SizeExtra)
// _INT32 AlgID = tStream.ReadInt32(); //EncryptionHeader
// _INT32 AlgIDHash = tStream.ReadInt32(); int HeaderSize = tStream.ReadUInt32();
// _UINT32 KeySize = tStream.ReadUInt32(); int Flags = tStream.ReadUInt32();
// _UINT32 ProviderType = tStream.ReadUInt32(); int SizeExtra = tStream.ReadUInt32();
int AlgID = tStream.ReadUInt32();
// tStream.ReadUInt32(); int AlgIDHash = tStream.ReadUInt32();
// tStream.ReadUInt32(); // reserved int KeySize = tStream.ReadUInt32();
// int ProviderType= tStream.ReadUInt32();
// //std::wstring CSPName; int Reserved1 = tStream.ReadUInt32();
// //record >> CSPName; int Reserved2 = tStream.ReadUInt32();
//// + crypt_data int pos = tStream.GetPosition();
int size = tStream.GetSize();
std::vector<char> dataCSPName;
while(pos < size - 1)
{
dataCSPName.push_back(tStream.ReadByte());
dataCSPName.push_back(tStream.ReadByte());
if (dataCSPName[dataCSPName.size() - 1] == 0 && dataCSPName[dataCSPName.size() - 2] == 0)
{
break;
}
pos+=2;//unicode null-terminate string
}
//EncryptionVerifier
crypt_data_aes.saltSize = tStream.ReadUInt32();
pDataRead = tStream.ReadBytes(crypt_data_aes.saltSize, true);
if (pDataRead)
{
crypt_data_aes.saltValue = std::string((char*)pDataRead, crypt_data_aes.saltSize);
delete pDataRead;
}
pDataRead = tStream.ReadBytes(0x10, true);
if (pDataRead)
{
crypt_data_aes.encryptedVerifierInput = std::string((char*)pDataRead, 0x10);
delete pDataRead;
}
crypt_data_aes.hashSize = tStream.ReadUInt32();
int szEncryptedVerifierHash = (ProviderType == 0x0001) ? 0x14 : 0x20;
pDataRead = tStream.ReadBytes(szEncryptedVerifierHash, true);
if (pDataRead)
{
crypt_data_aes.encryptedVerifierValue = std::string((char*)pDataRead, szEncryptedVerifierHash);
delete pDataRead;
}
pos = tStream.GetPosition();
//------------------------------------------------------------------------------------------
crypt_data_aes.hashAlgorithm = CRYPT_METHOD::SHA1; //by AlgIDHash -> 0x0000 || 0x8004
crypt_data_aes.spinCount = 50000;
switch(AlgID)
{
case 0x6801:
crypt_data_aes.cipherAlgorithm = CRYPT_METHOD::RC4;
crypt_data_aes.keySize = KeySize / 8;
break;
case 0x660E:
crypt_data_aes.cipherAlgorithm = CRYPT_METHOD::AES_ECB;
crypt_data_aes.keySize = 128 /8;
break;
case 0x660F:
crypt_data_aes.cipherAlgorithm = CRYPT_METHOD::AES_ECB;
crypt_data_aes.keySize = 192 /8;
break;
case 0x6610:
crypt_data_aes.cipherAlgorithm = CRYPT_METHOD::AES_ECB;
crypt_data_aes.keySize = 256 /8;
break;
}
switch(ProviderType)
{
case 0x0001: crypt_data_aes.cipherAlgorithm = CRYPT_METHOD::RC4; break;
case 0x0018: crypt_data_aes.cipherAlgorithm = CRYPT_METHOD::AES_ECB; break;
}
} }
//RELEASEARRAYOBJECTS( bytes ); //RELEASEARRAYOBJECTS( bytes );
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#pragma once #pragma once
#include "FileInformationBlock.h" #include "FileInformationBlock.h"
#include "../../OfficeCryptReader/source/CryptTransform.h"
#include "IVisitable.h" #include "IVisitable.h"
...@@ -49,6 +50,8 @@ namespace DocFileFormat ...@@ -49,6 +50,8 @@ namespace DocFileFormat
EncryptionHeader( FileInformationBlock* fib, POLE::Stream* tableStream ); EncryptionHeader( FileInformationBlock* fib, POLE::Stream* tableStream );
private: private:
CRYPT::CryptRC4Data crypt_data; CRYPT::CryptRC4Data crypt_data_rc4;
CRYPT::ECMADecryptor::_cryptData crypt_data_aes;
bool bStandard;
}; };
} }
...@@ -509,7 +509,6 @@ namespace DocFileFormat ...@@ -509,7 +509,6 @@ namespace DocFileFormat
public: public:
bool m_bOlderVersion; bool m_bOlderVersion;
int m_CodePage; int m_CodePage;
CRYPT::DecryptorPtr m_Decryptor;
FibBase m_FibBase; FibBase m_FibBase;
RgW97 m_RgW97; RgW97 m_RgW97;
......
...@@ -52,6 +52,7 @@ namespace DocFileFormat ...@@ -52,6 +52,7 @@ namespace DocFileFormat
friend class DocumentMapping; friend class DocumentMapping;
friend class FontTableMapping; friend class FontTableMapping;
friend class StyleSheetMapping; friend class StyleSheetMapping;
friend class NumberingMapping;
private: private:
/// When true, font is a TrueType font /// When true, font is a TrueType font
......
...@@ -65,7 +65,7 @@ namespace DocFileFormat ...@@ -65,7 +65,7 @@ namespace DocFileFormat
//this additional paragraph mark shall not be converted. //this additional paragraph mark shall not be converted.
cpMax--; cpMax--;
while ( cp < cpMax ) while ( cp < cpMax && cp < (int)m_document->Text->size())
{ {
int fc = m_document->FindFileCharPos(cp); int fc = m_document->FindFileCharPos(cp);
if (fc < 0) break; if (fc < 0) break;
......
...@@ -179,7 +179,7 @@ namespace DocFileFormat ...@@ -179,7 +179,7 @@ namespace DocFileFormat
//there are n offsets and n-1 fkp's in the bin table //there are n offsets and n-1 fkp's in the bin table
if (fib->m_FibBase.fComplex == false) if (fib->m_bOlderVersion && fib->m_FibBase.fComplex == false)
{ {
int n = ( ( (int)fib->m_FibWord97.lcbPlcfBtePapx - 8 ) / 6 ) + 1; int n = ( ( (int)fib->m_FibWord97.lcbPlcfBtePapx - 8 ) / 6 ) + 1;
......
...@@ -42,7 +42,7 @@ namespace DocFileFormat ...@@ -42,7 +42,7 @@ namespace DocFileFormat
if (fib->m_FibWord97.fcPlcfHdd > tableReader.GetSize()) return; if (fib->m_FibWord97.fcPlcfHdd > tableReader.GetSize()) return;
unsigned int tableSize = fib->m_FibWord97.lcbPlcfHdd / (fib->m_bOlderVersion ? 1: 4); unsigned int tableSize = fib->m_FibWord97.lcbPlcfHdd / 4;//in bytes
if ( ( tableSize > 0 ) && ( fib->m_RgLw97.ccpHdr > 0 ) ) if ( ( tableSize > 0 ) && ( fib->m_RgLw97.ccpHdr > 0 ) )
{ {
...@@ -53,14 +53,15 @@ namespace DocFileFormat ...@@ -53,14 +53,15 @@ namespace DocFileFormat
table[i] = tableReader.ReadInt32(); table[i] = tableReader.ReadInt32();
} }
int count = ( tableSize - 8 ) / 6;
int initialPos = fib->m_RgLw97.ccpText + fib->m_RgLw97.ccpFtn; int initialPos = fib->m_RgLw97.ccpText + fib->m_RgLw97.ccpFtn;
//the first 6 _entries are about footnote and endnote formatting //the first 6 _entries are about footnote and endnote formatting
//so skip these _entries //so skip these _entries
int pos = 6; int pos = (fib->m_FibBase.fComplex || !fib->m_bOlderVersion) ? 6 : 0;
int count = ( tableSize - pos - 2) / 6;
for (int i = 0; i < count; ++i) for (int i = 0; i < count; ++i)
{ {
//Even Header //Even Header
...@@ -123,7 +124,7 @@ namespace DocFileFormat ...@@ -123,7 +124,7 @@ namespace DocFileFormat
pos++; pos++;
if (pos > tableSize) if (pos >= tableSize)
break; break;
//First Page Footers //First Page Footers
......
...@@ -65,7 +65,7 @@ namespace DocFileFormat ...@@ -65,7 +65,7 @@ namespace DocFileFormat
//this additional paragraph mark shall not be converted. //this additional paragraph mark shall not be converted.
cpMax--; cpMax--;
while ( cp < cpMax ) while ( cp < cpMax && cp < (int)m_document->Text->size())
{ {
int fc = m_document->FindFileCharPos(cp); int fc = m_document->FindFileCharPos(cp);
if (fc < 0) break; if (fc < 0) break;
......
...@@ -37,11 +37,11 @@ namespace DocFileFormat ...@@ -37,11 +37,11 @@ namespace DocFileFormat
{ {
friend class ParagraphPropertiesMapping; friend class ParagraphPropertiesMapping;
private: private:
short dyaLine; short dyaLine;
bool fMultLinespace; bool fMultLinespace;
public: public:
/// Creates a new LineSpacingDescriptor with empty values /// Creates a new LineSpacingDescriptor with empty values
LineSpacingDescriptor(): dyaLine(0), fMultLinespace(false) LineSpacingDescriptor(): dyaLine(0), fMultLinespace(false)
{ {
...@@ -50,18 +50,17 @@ namespace DocFileFormat ...@@ -50,18 +50,17 @@ namespace DocFileFormat
/// Parses the bytes to retrieve a LineSpacingDescriptor /// Parses the bytes to retrieve a LineSpacingDescriptor
LineSpacingDescriptor( unsigned char* bytes, int size ) : dyaLine(0), fMultLinespace(false) LineSpacingDescriptor( unsigned char* bytes, int size ) : dyaLine(0), fMultLinespace(false)
{ {
if ( size == 4 ) dyaLine = FormatUtils::BytesToInt16( bytes, 0, size );
{
dyaLine = FormatUtils::BytesToInt16( bytes, 0, size );
if ( FormatUtils::BytesToInt16( bytes, 2, size ) == 1 ) if ( FormatUtils::BytesToInt16( bytes, 2, size ) == 1 )
{ {
fMultLinespace = true; fMultLinespace = true;
}
} }
else
if ( size > 4 )
{ {
} }
} }
}; };
} }
\ No newline at end of file
...@@ -32,7 +32,10 @@ ...@@ -32,7 +32,10 @@
#include "ListData.h" #include "ListData.h"
#include <algorithm> #include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
namespace DocFileFormat namespace DocFileFormat
{ {
...@@ -41,44 +44,152 @@ namespace DocFileFormat ...@@ -41,44 +44,152 @@ namespace DocFileFormat
for_each(rglvl->begin(), rglvl->end(), DeleteDynamicObject()); for_each(rglvl->begin(), rglvl->end(), DeleteDynamicObject());
RELEASEOBJECT(rglvl); RELEASEOBJECT(rglvl);
RELEASEARRAYOBJECTS(_rawBytes);
} }
// Parses the StreamReader to retrieve a ListData // Parses the StreamReader to retrieve a ListData
ListData::ListData(VirtualStreamReader* reader, int length) : rglvl(NULL), _rawBytes(NULL) ListData::ListData(VirtualStreamReader* reader, int length) : rglvl(NULL)
{ {
long startPos = reader->GetPosition(); long startPos = reader->GetPosition();
this->lsid = reader->ReadInt32(); lsid = reader->ReadInt32();
this->tplc = reader->ReadInt32(); tplc = reader->ReadInt32();
for ( int i = 0; i < 9; i++ ) for ( int i = 0; i < 9; i++ )
{ {
this->rgistd.push_back( reader->ReadInt16() ); rgistd.push_back( reader->ReadInt16() );
} }
//parse flagbyte //parse flagbyte
int flag = (int)reader->ReadByte(); int flag = (int)reader->ReadByte();
this->fSimpleList = FormatUtils::BitmaskToBool( flag, 0x01 ); fSimpleList = FormatUtils::BitmaskToBool( flag, 0x01 );
if ( this->fSimpleList ) if ( fSimpleList )
{ {
this->rglvl = new std::vector<ListLevel*>( 1 ); rglvl = new std::vector<ListLevel*>( 1 );
} }
else else
{ {
this->rglvl = new std::vector<ListLevel*>( 9 ); rglvl = new std::vector<ListLevel*>( 9 );
} }
this->fRestartHdn = FormatUtils::BitmaskToBool( flag, 0x02 ); fRestartHdn = FormatUtils::BitmaskToBool( flag, 0x02 );
this->fAutoNum = FormatUtils::BitmaskToBool( flag, 0x04 ); fAutoNum = FormatUtils::BitmaskToBool( flag, 0x04 );
this->fPreRTF = FormatUtils::BitmaskToBool( flag, 0x08 ); fPreRTF = FormatUtils::BitmaskToBool( flag, 0x08 );
this->fHybrid = FormatUtils::BitmaskToBool( flag, 0x10 ); fHybrid = FormatUtils::BitmaskToBool( flag, 0x10 );
this->grfhic = reader->ReadByte(); grfhic = reader->ReadByte();
}
NumberingDescriptor::NumberingDescriptor( unsigned char * data, int length )
{
nfc = FormatUtils::BytesToUChar(data, 0, length);
cbTextBefore = FormatUtils::BytesToUChar(data, 1, length);
cbTextAfter = FormatUtils::BytesToUChar(data, 2, length);
int flag = FormatUtils::BytesToUChar(data, 3, length);
jc = (unsigned char)( flag & 0x03 );
fPrev = FormatUtils::BitmaskToBool( flag, 0x04 );
fHang = FormatUtils::BitmaskToBool( flag, 0x08 );
fSetBold = FormatUtils::BitmaskToBool( flag, 0x10 );
fSetItalic = FormatUtils::BitmaskToBool( flag, 0x20 );
fSetSmallCaps = FormatUtils::BitmaskToBool( flag, 0x40 );
fSetCaps = FormatUtils::BitmaskToBool( flag, 0x80 );
flag = FormatUtils::BytesToUChar(data, 4, length);;
fSetStrike = FormatUtils::BitmaskToBool( flag, 0x01 );
fSetKul = FormatUtils::BitmaskToBool( flag, 0x02 );
fPrevSpace = FormatUtils::BitmaskToBool( flag, 0x04 );
fBold = FormatUtils::BitmaskToBool( flag, 0x08 );
fItalic = FormatUtils::BitmaskToBool( flag, 0x10 );
fSmallCaps = FormatUtils::BitmaskToBool( flag, 0x20 );
fCaps = FormatUtils::BitmaskToBool( flag, 0x40 );
fStrike = FormatUtils::BitmaskToBool( flag, 0x80 );
flag = FormatUtils::BytesToUChar(data, 5, length);
kul = FormatUtils::BitmaskToBool( flag, 0x07 );//3 bit
ico = FormatUtils::BitmaskToBool( flag, 0xf1 );//5 bit
ftc = FormatUtils::BytesToInt16 (data, 6, length);
ftc = ftc & 0x0fff; // 0x8001 ???? file(31).doc
hps = FormatUtils::BytesToUInt16(data, 8, length);
iStartAt = FormatUtils::BytesToUInt16(data, 10, length);
dxaIndent = FormatUtils::BytesToUInt16(data, 12, length);
dxaSpace = FormatUtils::BytesToUInt16(data, 14, length);
fNumber1 = FormatUtils::BytesToUChar(data, 16, length);
fNumberAcross = FormatUtils::BytesToUChar(data, 17, length);
fRestartHdn = FormatUtils::BytesToUChar(data, 18, length);
fSpareX = FormatUtils::BytesToUChar(data, 19, length);
// fixed size = 20
//read the number text
short strLen = length - 20;
while (strLen > 0)
{
if (data[strLen + 20 - 1] != 0)
break;
strLen--;
}
if (strLen > 0)
{
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(xst), data + 20, ( strLen ), ENCODING_WINDOWS_1250);
}
}
OutlineListDescriptor::~OutlineListDescriptor()
{
for (int i = 0 ; i < 9; i++)
{
if (lvl[i]) delete lvl[i];
lvl[i] = NULL;
}
}
OutlineListDescriptor::OutlineListDescriptor( unsigned char * data, int length )
{
int pos = 0;
for (int i = 0 ; i < 9; i++)
{
lvl[i] = new NumberingLevelDescriptor(data + pos, length - pos);
pos += 16;
}
fRestartHdr = FormatUtils::BytesToUChar(data, pos, length); pos += 2;
fSpareOlst2 = FormatUtils::BytesToUChar(data, pos, length); pos += 2;
fSpareOlst3 = FormatUtils::BytesToUChar(data, pos, length); pos += 2;
fSpareOlst4 = FormatUtils::BytesToUChar(data, pos, length); pos += 2;
short strLen = length - pos;
while (strLen > 0)
{
if (data[strLen + 20 - 1] != 0)
break;
strLen--;
}
if (strLen > 0)
{
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(xst), data + 20, ( strLen ), ENCODING_WINDOWS_1250);
}
}
reader->Seek( startPos, 0/*STREAM_SEEK_SET */); ByteStructure* OutlineListDescriptor::ConstructObject(VirtualStreamReader* reader, int length)
_rawBytes = reader->ReadBytes( LSTF_LENGTH, true ); {
unsigned char *data = reader->ReadBytes(212, true);
OutlineListDescriptor *newObject = new OutlineListDescriptor(data, 212);
delete []data;
return static_cast<ByteStructure*>(newObject);
} }
} }
...@@ -32,48 +32,124 @@ ...@@ -32,48 +32,124 @@
#pragma once #pragma once
#include "ListLevel.h" #include "ListLevel.h"
#include "ByteStructure.h"
namespace DocFileFormat namespace DocFileFormat
{ {
class ListData class ListData
{ {
friend class ListTable; friend class ListTable;
friend class NumberingMapping; friend class NumberingMapping;
private: private:
/// Unique List ID /// Unique List ID
int lsid; int lsid;
/// Unique template code /// Unique template code
int tplc; int tplc;
/// Array of shorts containing the istd‘s linked to each level of the list, /// Array of shorts containing the istd‘s linked to each level of the list,
/// or ISTD_NIL (4095) if no style is linked. /// or ISTD_NIL (4095) if no style is linked.
std::vector<short> rgistd; std::vector<short> rgistd;
/// True if this is a simple (one-level) list. /// True if this is a simple (one-level) list.
/// False if this is a multilevel (nine-level) list. /// False if this is a multilevel (nine-level) list.
bool fSimpleList; bool fSimpleList;
/// Word 6.0 compatibility option: /// Word 6.0 compatibility option:
/// True if the list should start numbering over at the beginning of each section. /// True if the list should start numbering over at the beginning of each section.
bool fRestartHdn; bool fRestartHdn;
/// To emulate Word 6.0 numbering: /// To emulate Word 6.0 numbering:
/// True if Auto numbering /// True if Auto numbering
bool fAutoNum; bool fAutoNum;
/// When true, this list was there before we started reading RTF. /// When true, this list was there before we started reading RTF.
bool fPreRTF; bool fPreRTF;
/// When true, list is a hybrid multilevel/simple (UI=simple, internal=multilevel) /// When true, list is a hybrid multilevel/simple (UI=simple, internal=multilevel)
bool fHybrid; bool fHybrid;
/// Array of ListLevel describing the several levels of the list. /// Array of ListLevel describing the several levels of the list.
std::vector<ListLevel*>* rglvl; std::vector<ListLevel*>* rglvl;
/// A grfhic that specifies HTML incompatibilities of the list. /// A grfhic that specifies HTML incompatibilities of the list.
unsigned char grfhic; unsigned char grfhic;
unsigned char* _rawBytes;
public:
public: static const int LSTF_LENGTH = 28;
static const int LSTF_LENGTH = 28; static const short ISTD_NIL = 4095;
static const short ISTD_NIL = 4095; static const int VARIABLE_LENGTH = INT_MAX;
static const int VARIABLE_LENGTH = INT_MAX;
virtual ~ListData();
virtual ~ListData(); ListData( VirtualStreamReader* reader, int length );
/// Parses the StreamReader to retrieve a ListData };
ListData( VirtualStreamReader* reader, int length );
}; class NumberingDescriptor : public IVisitable
{
friend class ListTable;
friend class NumberingMapping;
private:
unsigned char nfc;
unsigned char cbTextBefore;
unsigned char cbTextAfter;
unsigned char jc;
bool fPrev;
bool fHang;
bool fSetBold;
bool fSetItalic;
bool fSetSmallCaps;
bool fSetCaps;
bool fSetStrike;
bool fSetKul;
bool fPrevSpace;
bool fBold;
bool fItalic;
bool fSmallCaps;
bool fCaps;
bool fStrike;
unsigned char kul;
unsigned char ico;
short ftc;
unsigned short hps;
unsigned short iStartAt;
unsigned short dxaIndent;
unsigned short dxaSpace;
unsigned char fNumber1;
unsigned char fNumberAcross;
unsigned char fRestartHdn;
unsigned char fSpareX;
std::wstring xst; //32 chars ansi
public:
virtual ~NumberingDescriptor(){}
// Parses the given StreamReader to retrieve a ANLD struct
NumberingDescriptor( unsigned char * data, int length ); //cbANLD (count of bytes of ANLD) is 52
};
class OutlineListDescriptor : public IVisitable, public ByteStructure
{
friend class ListTable;
friend class NumberingMapping;
private:
NumberingLevelDescriptor *lvl[9];
unsigned char fRestartHdr;
unsigned char fSpareOlst2;
unsigned char fSpareOlst3;
unsigned char fSpareOlst4;
std::wstring xst; //64 chars ansi
public:
static const int STRUCTURE_SIZE = 212;
virtual ByteStructure* ConstructObject( VirtualStreamReader* reader, int length );
virtual ~OutlineListDescriptor();
// Parses the given StreamReader to retrieve a OLST struct
OutlineListDescriptor( unsigned char * data, int length ); //cbOLST(count of bytes of OLST) is 212
OutlineListDescriptor() {}
};
} }
\ No newline at end of file
...@@ -34,77 +34,115 @@ ...@@ -34,77 +34,115 @@
namespace DocFileFormat namespace DocFileFormat
{ {
ListLevel::~ListLevel() ListLevel::~ListLevel()
{ {
RELEASEOBJECT( this->grpprlPapx ); RELEASEOBJECT( grpprlPapx );
RELEASEOBJECT( this->grpprlChpx ); RELEASEOBJECT( grpprlChpx );
}
RELEASEARRAYOBJECTS( this->_rawBytes );
} ListLevel::ListLevel( VirtualStreamReader* reader, int length ):
grpprlPapx(NULL), grpprlChpx(NULL)
/*========================================================================================================*/ {
//parse the fix part
/// Parses the given StreamReader to retrieve a LVL struct iStartAt = reader->ReadInt32();
ListLevel::ListLevel( VirtualStreamReader* reader, int length ): nfc = reader->ReadByte();
grpprlPapx(NULL), grpprlChpx(NULL), _rawBytes(NULL) int flag = reader->ReadByte();
{ jc = (unsigned char)( flag & 0x03 );
long startPos = reader->GetPosition();
fLegal = FormatUtils::BitmaskToBool( flag, 0x04 );
//parse the fix part fNoRestart = FormatUtils::BitmaskToBool( flag, 0x08 );
this->iStartAt = reader->ReadInt32(); fPrev = FormatUtils::BitmaskToBool( flag, 0x10 );
this->nfc = reader->ReadByte(); fPrevSpace = FormatUtils::BitmaskToBool( flag, 0x20 );
int flag = reader->ReadByte(); fWord6 = FormatUtils::BitmaskToBool( flag, 0x40 );
this->jc = (unsigned char)( flag & 0x03 );
this->fLegal = FormatUtils::BitmaskToBool( flag, 0x04 );
this->fNoRestart = FormatUtils::BitmaskToBool( flag, 0x08 );
this->fPrev = FormatUtils::BitmaskToBool( flag, 0x10 );
this->fPrevSpace = FormatUtils::BitmaskToBool( flag, 0x20 );
this->fWord6 = FormatUtils::BitmaskToBool( flag, 0x40 );
for ( int i = 0; i < 9; i++ ) for ( int i = 0; i < 9; i++ )
{ {
rgbxchNums.push_back( reader->ReadByte() ); rgbxchNums.push_back( reader->ReadByte() );
} }
this->ixchFollow = (FollowingChar)reader->ReadByte(); ixchFollow = (FollowingChar)reader->ReadByte();
this->dxaSpace = reader->ReadInt32(); dxaSpace = reader->ReadInt32();
this->dxaIndent = reader->ReadInt32(); dxaIndent = reader->ReadInt32();
this->cbGrpprlChpx = reader->ReadByte(); cbGrpprlChpx = reader->ReadByte();
this->cbGrpprlPapx = reader->ReadByte(); cbGrpprlPapx = reader->ReadByte();
ilvlRestartLim = reader->ReadByte();
grfhic = reader->ReadByte();
//parse the variable part
//read the group of papx sprms
//this papx has no istd, so use PX to parse it
unsigned char *bytes = reader->ReadBytes( cbGrpprlPapx, true );
PropertyExceptions* px = new PropertyExceptions( bytes, cbGrpprlPapx, reader->olderVersion);
grpprlPapx = new ParagraphPropertyExceptions( *(px->grpprl) );
this->ilvlRestartLim = reader->ReadByte();
this->grfhic = reader->ReadByte();
//parse the variable part
//read the group of papx sprms
//this papx has no istd, so use PX to parse it
unsigned char *bytes = reader->ReadBytes( this->cbGrpprlPapx, true );
PropertyExceptions* px = new PropertyExceptions( bytes, this->cbGrpprlPapx, reader->olderVersion);
this->grpprlPapx = new ParagraphPropertyExceptions( *(px->grpprl) );
RELEASEOBJECT( px ); RELEASEOBJECT( px );
RELEASEARRAYOBJECTS( bytes ); RELEASEARRAYOBJECTS( bytes );
//read the group of chpx sprms //read the group of chpx sprms
bytes = reader->ReadBytes( this->cbGrpprlChpx, true ); bytes = reader->ReadBytes( cbGrpprlChpx, true );
this->grpprlChpx = new CharacterPropertyExceptions( bytes, this->cbGrpprlChpx, reader->olderVersion ); grpprlChpx = new CharacterPropertyExceptions( bytes, cbGrpprlChpx, reader->olderVersion );
RELEASEARRAYOBJECTS( bytes ); RELEASEARRAYOBJECTS( bytes );
//read the number text //read the number text
short strLen = reader->ReadInt16(); short strLen = reader->ReadInt16();
if (strLen > 0)//file(14).doc if (strLen > 0)//file(14).doc
{ {
bytes = reader->ReadBytes( ( strLen * 2 ), true ); bytes = reader->ReadBytes( ( strLen * 2 ), true );
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(this->xst), bytes, ( strLen * 2 ), ENCODING_UTF16 ); FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &(xst), bytes, ( strLen * 2 ), ENCODING_UTF16 );
RELEASEARRAYOBJECTS( bytes ); RELEASEARRAYOBJECTS( bytes );
} }
}
NumberingLevelDescriptor::~NumberingLevelDescriptor()
{
}
NumberingLevelDescriptor::NumberingLevelDescriptor( unsigned char * data, int length )
{
nfc = FormatUtils::BytesToUChar(data, 0, length);
cbTextBefore = FormatUtils::BytesToUChar(data, 1, length);
cbTextAfter = FormatUtils::BytesToUChar(data, 2, length);
long endPos = reader->GetPosition(); int flag = FormatUtils::BytesToUChar(data, 3, length);
reader->Seek( startPos, 0/*STREAM_SEEK_SET*/ );
_rawBytes = reader->ReadBytes( (int)( endPos - startPos ), true ); jc = (unsigned char)( flag & 0x03 );
}
fPrev = FormatUtils::BitmaskToBool( flag, 0x04 );
fHang = FormatUtils::BitmaskToBool( flag, 0x08 );
fSetBold = FormatUtils::BitmaskToBool( flag, 0x10 );
fSetItalic = FormatUtils::BitmaskToBool( flag, 0x20 );
fSetSmallCaps = FormatUtils::BitmaskToBool( flag, 0x40 );
fSetCaps = FormatUtils::BitmaskToBool( flag, 0x80 );
flag = FormatUtils::BytesToUChar(data, 4, length);;
fSetStrike = FormatUtils::BitmaskToBool( flag, 0x01 );
fSetKul = FormatUtils::BitmaskToBool( flag, 0x02 );
fPrevSpace = FormatUtils::BitmaskToBool( flag, 0x04 );
fBold = FormatUtils::BitmaskToBool( flag, 0x08 );
fItalic = FormatUtils::BitmaskToBool( flag, 0x10 );
fSmallCaps = FormatUtils::BitmaskToBool( flag, 0x20 );
fCaps = FormatUtils::BitmaskToBool( flag, 0x40 );
fStrike = FormatUtils::BitmaskToBool( flag, 0x80 );
flag = FormatUtils::BytesToUChar(data, 5, length);
kul = FormatUtils::BitmaskToBool( flag, 0x07 );//3 bit
ico = FormatUtils::BitmaskToBool( flag, 0xf1 );//5 bit
ftc = FormatUtils::BytesToInt16 (data, 6, length);
hps = FormatUtils::BytesToUInt16(data, 8, length);
iStartAt = FormatUtils::BytesToUInt16(data, 10, length);
dxaIndent = FormatUtils::BytesToUInt16(data, 12, length);
dxaSpace = FormatUtils::BytesToUInt16(data, 14, length);
}
} }
...@@ -37,75 +37,112 @@ ...@@ -37,75 +37,112 @@
namespace DocFileFormat namespace DocFileFormat
{ {
typedef enum _FollowingChar typedef enum _FollowingChar
{ {
tab = 0, tab = 0,
space, space,
nothing nothing
} FollowingChar; } FollowingChar;
static const wchar_t FollowingCharMap[3][8] = static const wchar_t FollowingCharMap[3][8] =
{ {
_T( "tab" ), _T( "tab" ),
_T( "space" ), _T( "space" ),
_T( "nothing" ) _T( "nothing" )
}; };
class ListLevel class ListLevel
{ {
friend class NumberingMapping; friend class NumberingMapping;
private: private:
/// Start at value for this list level /// Start at value for this list level
int iStartAt; int iStartAt;
/// Number format code (see anld.nfc for a list of options) /// Number format code (see anld.nfc for a list of options)
unsigned char nfc; unsigned char nfc;
/// Alignment (left, right, or centered) of the paragraph number. /// Alignment (left, right, or centered) of the paragraph number.
unsigned char jc; unsigned char jc;
/// True if the level turns all inherited numbers to arabic, /// True if the level turns all inherited numbers to arabic,
/// false if it preserves their number format code (nfc) /// false if it preserves their number format code (nfc)
bool fLegal; bool fLegal;
/// True if the level‘s number sequence is not restarted by /// True if the level‘s number sequence is not restarted by
/// higher (more significant) levels in the list /// higher (more significant) levels in the list
bool fNoRestart; bool fNoRestart;
/// Word 6.0 compatibility option: equivalent to anld.fPrev (see ANLD) /// Word 6.0 compatibility option: equivalent to anld.fPrev (see ANLD)
bool fPrev; bool fPrev;
/// Word 6.0 compatibility option: equivalent to anld.fPrevSpace (see ANLD) /// Word 6.0 compatibility option: equivalent to anld.fPrevSpace (see ANLD)
bool fPrevSpace; bool fPrevSpace;
/// True if this level was from a converted Word 6.0 document. /// True if this level was from a converted Word 6.0 document.
/// If it is true, all of the Word 6.0 compatibility options become /// If it is true, all of the Word 6.0 compatibility options become
/// valid otherwise they are ignored. /// valid otherwise they are ignored.
bool fWord6; bool fWord6;
/// Contains the character offsets into the LVL’s XST of the inherited numbers of previous levels. /// Contains the character offsets into the LVL’s XST of the inherited numbers of previous levels.
/// The XST contains place holders for any paragraph numbers contained in the text of the number, /// The XST contains place holders for any paragraph numbers contained in the text of the number,
/// and the place holder contains the ilvl of the inherited number, /// and the place holder contains the ilvl of the inherited number,
/// so lvl.xst[lvl.rgbxchNums[0]] == the level of the first inherited number in this level. /// so lvl.xst[lvl.rgbxchNums[0]] == the level of the first inherited number in this level.
std::vector<unsigned char> rgbxchNums; std::vector<unsigned char> rgbxchNums;
/// The type of character following the number text for the paragraph. /// The type of character following the number text for the paragraph.
FollowingChar ixchFollow; FollowingChar ixchFollow;
/// Word 6.0 compatibility option: equivalent to anld.dxaSpace (see ANLD). /// Word 6.0 compatibility option: equivalent to anld.dxaSpace (see ANLD).
/// For newer versions indent to remove if we remove this numbering. /// For newer versions indent to remove if we remove this numbering.
int dxaSpace; int dxaSpace;
/// Word 6.0 compatibility option: equivalent to anld.dxaIndent (see ANLD). /// Word 6.0 compatibility option: equivalent to anld.dxaIndent (see ANLD).
/// Unused in newer versions. /// Unused in newer versions.
int dxaIndent; int dxaIndent;
/// Length, in bytes, of the LVL‘s grpprlChpx. /// Length, in bytes, of the LVL‘s grpprlChpx.
unsigned char cbGrpprlChpx; unsigned char cbGrpprlChpx;
/// Length, in bytes, of the LVL‘s grpprlPapx. /// Length, in bytes, of the LVL‘s grpprlPapx.
unsigned char cbGrpprlPapx; unsigned char cbGrpprlPapx;
/// Limit of levels that we restart after. /// Limit of levels that we restart after.
unsigned char ilvlRestartLim; unsigned char ilvlRestartLim;
/// A grfhic that specifies HTML incompatibilities of the level. /// A grfhic that specifies HTML incompatibilities of the level.
unsigned char grfhic; unsigned char grfhic;
ParagraphPropertyExceptions* grpprlPapx; ParagraphPropertyExceptions* grpprlPapx;
CharacterPropertyExceptions* grpprlChpx; CharacterPropertyExceptions* grpprlChpx;
std::wstring xst; std::wstring xst;
unsigned char* _rawBytes; public:
virtual ~ListLevel();
// Parses the given StreamReader to retrieve a LVL struct
ListLevel( VirtualStreamReader* reader, int length );
};
public: class NumberingLevelDescriptor
virtual ~ListLevel(); {
/// Parses the given StreamReader to retrieve a LVL struct friend class NumberingMapping;
ListLevel( VirtualStreamReader* reader, int length ); private:
}; unsigned char nfc;
unsigned char cbTextBefore;
unsigned char cbTextAfter;
unsigned char jc;
bool fPrev;
bool fHang;
bool fSetBold;
bool fSetItalic;
bool fSetSmallCaps;
bool fSetCaps;
bool fSetStrike;
bool fSetKul;
bool fPrevSpace;
bool fBold;
bool fItalic;
bool fSmallCaps;
bool fCaps;
bool fStrike;
unsigned char kul;
unsigned char ico;
short ftc;
unsigned short hps;
unsigned short iStartAt;
unsigned short dxaIndent;
unsigned short dxaSpace;
public:
virtual ~NumberingLevelDescriptor();
// Parses the given StreamReader to retrieve a ANLV struct
NumberingLevelDescriptor( unsigned char * data, int length ); //cbANLV is 16 bytes
};
} }
\ No newline at end of file
...@@ -72,4 +72,10 @@ namespace DocFileFormat ...@@ -72,4 +72,10 @@ namespace DocFileFormat
} }
} }
} }
void ListTable::appendNumbering( const NumberingDescriptor & desc )
{
listNumbering.push_back(desc);
}
} }
\ No newline at end of file
...@@ -41,9 +41,12 @@ namespace DocFileFormat ...@@ -41,9 +41,12 @@ namespace DocFileFormat
class ListTable: public IVisitable class ListTable: public IVisitable
{ {
public: public:
std::list<ListData*> listData; std::list<ListData*> listData;
std::list<NumberingDescriptor> listNumbering;
virtual ~ListTable(); virtual ~ListTable();
ListTable( FileInformationBlock* fib, POLE::Stream* tableStream ); ListTable( FileInformationBlock* fib, POLE::Stream* tableStream );
void appendNumbering( const NumberingDescriptor & desc );
}; };
} }
\ No newline at end of file
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#pragma once #pragma once
#include "IBinaryReader.h" #include "IBinaryReader.h"
#include "../Common/FormatUtils.h"
class MemoryStream: public IBinaryReader class MemoryStream: public IBinaryReader
{ {
......
...@@ -62,17 +62,24 @@ namespace DocFileFormat ...@@ -62,17 +62,24 @@ namespace DocFileFormat
public: public:
NumberingMapping(ConversionContext* ctx); NumberingMapping(ConversionContext* ctx);
void Apply(IVisitable* visited); void Apply(IVisitable* visited);
static int FindIndexbyId(const std::list<ListData*>& listData, int id); static int FindIndexbyId(const std::list<ListData*>& listData, int id);
/// Converts the number format code of the binary format. /// Converts the number format code of the binary format.
static std::wstring GetNumberFormatWideString(int nfc); static std::wstring GetNumberFormatWideString(int nfc, bool bOlderVersion = false);
virtual ~NumberingMapping(); virtual ~NumberingMapping();
private: private:
// Converts the number text of the binary format to the number text of OOXML. // Converts the number text of the binary format to the number text of OOXML.
// OOXML uses different placeholders for the numbers. // OOXML uses different placeholders for the numbers.
std::wstring GetLvlText(const ListLevel* lvl, bool bIsSymbol) const; std::wstring GetLvlText(const ListLevel* lvl, bool bIsSymbol) const;
std::wstring GetLvlText(const NumberingDescriptor& lvl, bool bIsSymbol, int Before, int After) const;
static bool IsPlaceholder(wchar_t symbol); static bool IsPlaceholder(wchar_t symbol);
void LevelMapping(const ListLevel* lvl, unsigned int level, short styleIndex); void LevelMapping(const ListLevel* lvl, unsigned int level, short styleIndex);
void LevelMapping(const NumberingDescriptor& lvl, unsigned int level);
void PictureBulletsMapping(); void PictureBulletsMapping();
void WriteLevelPictureBullet(const CharacterPropertyExceptions* grpprlChpx); void WriteLevelPictureBullet(const CharacterPropertyExceptions* grpprlChpx);
bool IsPictureBullet(const CharacterPropertyExceptions* grpprlChpx); bool IsPictureBullet(const CharacterPropertyExceptions* grpprlChpx);
......
...@@ -70,6 +70,12 @@ public: ...@@ -70,6 +70,12 @@ public:
public: public:
CMetaHeader() CMetaHeader()
{ {
cbSize = cbSave = 0;
filter = compression = 0;
ptSize.x = ptSize.y = 0;
rcBounds.bottom = rcBounds.left = rcBounds.right = rcBounds.top = 0;
} }
...@@ -300,11 +306,11 @@ typedef enum _BlipCompression ...@@ -300,11 +306,11 @@ typedef enum _BlipCompression
Record( _reader, size, typeCode, version, instance ), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_cb(0), m_cbSave(0), Record( _reader, size, typeCode, version, instance ), m_rgbUid(NULL), m_rgbUidPrimary(NULL), m_cb(0), m_cbSave(0),
m_fCompression(BlipCompressionNone), m_fFilter(false), m_pvBits(NULL) m_fCompression(BlipCompressionNone), m_fFilter(false), m_pvBits(NULL)
{ {
this->m_rgbUid = this->Reader->ReadBytes( 16, true ); m_rgbUid = Reader->ReadBytes( 16, true );
if ( ( instance == 0x3D5 ) || ( instance == 0x217 ) || ( instance == 0x543 ) ) if ( ( instance == 0x3D5 ) || ( instance == 0x217 ) || ( instance == 0x543 ) )
{ {
this->m_rgbUidPrimary = this->Reader->ReadBytes( 16, true ); m_rgbUidPrimary = Reader->ReadBytes( 16, true );
} }
oMetaFile.m_bIsValid = TRUE; oMetaFile.m_bIsValid = TRUE;
...@@ -312,22 +318,22 @@ typedef enum _BlipCompression ...@@ -312,22 +318,22 @@ typedef enum _BlipCompression
CMetaHeader oMetaHeader; CMetaHeader oMetaHeader;
this->m_cb = this->Reader->ReadInt32(); m_cb = Reader->ReadInt32();
this->m_rcBounds.left = this->Reader->ReadInt32(); m_rcBounds.left = Reader->ReadInt32();
this->m_rcBounds.top = this->Reader->ReadInt32(); m_rcBounds.top = Reader->ReadInt32();
this->m_rcBounds.right = this->Reader->ReadInt32() + this->m_rcBounds.left; m_rcBounds.right = Reader->ReadInt32() + m_rcBounds.left;
this->m_rcBounds.bottom = this->Reader->ReadInt32() + this->m_rcBounds.top; m_rcBounds.bottom = Reader->ReadInt32() + m_rcBounds.top;
this->m_ptSize.x = this->Reader->ReadInt32(); m_ptSize.x = Reader->ReadInt32();
this->m_ptSize.y = this->Reader->ReadInt32(); m_ptSize.y = Reader->ReadInt32();
this->m_cbSave = this->Reader->ReadInt32(); m_cbSave = Reader->ReadInt32();
this->m_fCompression = (BlipCompression)this->Reader->ReadByte(); m_fCompression = (BlipCompression)Reader->ReadByte();
this->m_fFilter = ( this->Reader->ReadByte() == 1 ) ? (true) : (false); m_fFilter = ( Reader->ReadByte() == 1 ) ? (true) : (false);
int sz = Reader->GetSize() - Reader->GetPosition(); int sz = Reader->GetSize() - Reader->GetPosition();
this->m_pvBits = this->Reader->ReadBytes( sz/*this->m_cbSave*/, true ); m_pvBits = Reader->ReadBytes( sz/*m_cbSave*/, true );
oMetaHeader.rcBounds = m_rcBounds; oMetaHeader.rcBounds = m_rcBounds;
oMetaHeader.cbSize = m_cb; oMetaHeader.cbSize = m_cb;
...@@ -369,9 +375,9 @@ typedef enum _BlipCompression ...@@ -369,9 +375,9 @@ typedef enum _BlipCompression
virtual ~MetafilePictBlip() virtual ~MetafilePictBlip()
{ {
RELEASEARRAYOBJECTS( this->m_rgbUid ); RELEASEARRAYOBJECTS( m_rgbUid );
RELEASEARRAYOBJECTS( this->m_rgbUidPrimary ); RELEASEARRAYOBJECTS( m_rgbUidPrimary );
RELEASEARRAYOBJECTS( this->m_pvBits ); RELEASEARRAYOBJECTS( m_pvBits );
} }
virtual Record* NewObject( IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance ) virtual Record* NewObject( IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance )
...@@ -386,9 +392,9 @@ typedef enum _BlipCompression ...@@ -386,9 +392,9 @@ typedef enum _BlipCompression
unsigned long uncomprLen = 0; unsigned long uncomprLen = 0;
if ( this->m_fCompression == BlipCompressionDeflate ) if ( m_fCompression == BlipCompressionDeflate )
{ {
uncomprLen = this->m_cb; uncomprLen = m_cb;
*buffer = new unsigned char[uncomprLen]; *buffer = new unsigned char[uncomprLen];
HRESULT res = S_OK; HRESULT res = S_OK;
...@@ -396,19 +402,19 @@ typedef enum _BlipCompression ...@@ -396,19 +402,19 @@ typedef enum _BlipCompression
if (pOfficeUtils) if (pOfficeUtils)
{ {
pOfficeUtils->Uncompress( *buffer, &uncomprLen, this->m_pvBits, this->m_cbSave ); pOfficeUtils->Uncompress( *buffer, &uncomprLen, m_pvBits, m_cbSave );
delete pOfficeUtils; delete pOfficeUtils;
pOfficeUtils = NULL; pOfficeUtils = NULL;
} }
} }
else if ( this->m_fCompression == BlipCompressionNone ) else if ( m_fCompression == BlipCompressionNone )
{ {
uncomprLen = this->m_cbSave; uncomprLen = m_cbSave;
*buffer = new unsigned char[uncomprLen]; *buffer = new unsigned char[uncomprLen];
memcpy( *buffer, this->m_pvBits , this->m_cbSave ); memcpy( *buffer, m_pvBits , m_cbSave );
} }
return uncomprLen; return uncomprLen;
......
...@@ -35,8 +35,8 @@ namespace DocFileFormat ...@@ -35,8 +35,8 @@ namespace DocFileFormat
{ {
Record::~Record() Record::~Record()
{ {
RELEASEARRAYOBJECTS( this->RawData ); RELEASEARRAYOBJECTS( RawData );
RELEASEOBJECT( this->Reader ); RELEASEOBJECT( Reader );
} }
/*========================================================================================================*/ /*========================================================================================================*/
...@@ -53,20 +53,27 @@ namespace DocFileFormat ...@@ -53,20 +53,27 @@ namespace DocFileFormat
HeaderSize(0), BodySize(0), RawData(NULL), SiblingIdx(0), TypeCode(0), Version(0), Instance(0), Reader(NULL), HeaderSize(0), BodySize(0), RawData(NULL), SiblingIdx(0), TypeCode(0), Version(0), Instance(0), Reader(NULL),
_ParentRecord(NULL) _ParentRecord(NULL)
{ {
this->BodySize = bodySize; BodySize = bodySize;
this->TypeCode = typeCode; TypeCode = typeCode;
this->Version = version; Version = version;
this->Instance = instance; Instance = instance;
this->HeaderSize = Record::HEADER_SIZE_IN_BYTES; HeaderSize = Record::HEADER_SIZE_IN_BYTES;
this->RawData = _reader->ReadBytes( (int)this->BodySize, true ); int real_size = _reader->GetSize() - _reader->GetPosition();
this->Reader = new MemoryStream( this->RawData, this->BodySize, false );
if (real_size < BodySize)
{
BodySize = real_size;
}
RawData = _reader->ReadBytes( BodySize, true );
Reader = new MemoryStream( RawData, BodySize, false );
} }
/*========================================================================================================*/ /*========================================================================================================*/
unsigned int Record::GetTotalSize() const unsigned int Record::GetTotalSize() const
{ {
return ( this->HeaderSize + this->BodySize ); return ( HeaderSize + BodySize );
} }
} }
...@@ -74,7 +74,8 @@ namespace DocFileFormat ...@@ -74,7 +74,8 @@ namespace DocFileFormat
if (pRecord) if (pRecord)
{ {
result = pRecord->NewObject (reader, size, typeCode, version, instance); result = pRecord->NewObject (reader, size, typeCode, version, instance);
result->SiblingIdx = siblingIdx; if (result)
result->SiblingIdx = siblingIdx;
RELEASEOBJECT(pRecord); RELEASEOBJECT(pRecord);
} }
} }
......
...@@ -217,9 +217,18 @@ namespace DocFileFormat ...@@ -217,9 +217,18 @@ namespace DocFileFormat
case msosptTextStop : { pShape = new WordArtTextStop(); } break; case msosptTextStop : { pShape = new WordArtTextStop(); } break;
case msosptTextArchUpCurve : { pShape = new WordArtTextArchUpCurve(); } break; case msosptTextArchUpCurve : { pShape = new WordArtTextArchUpCurve(); } break;
case msosptTextPlainText : case msosptTextSlantUp : { pShape = new WordArtTextSlantUp(); } break;
//без детализаций - todooo прописать формулы case msosptTextDeflate : { pShape = new WordArtTextDeflate(); } break;
case msosptTextTriangle : case msosptTextCanDown : { pShape = new WordArtTextCanDown(); } break;
case msosptTextWave1 : { pShape = new WordArtTextWave1(); } break;
case msosptTextWave3 : { pShape = new WordArtTextWave3(); } break;
case msosptTextWave4 : { pShape = new WordArtTextWave4(); } break;
case msosptTextCurveUp : { pShape = new WordArtTextCurveUp(); } break;
case msosptTextFadeUp : { pShape = new WordArtTextFadeUp(); } break;
case msosptTextTriangle : { pShape = new WordArtTextTriangle(); } break;
case msosptTextCascadeUp : { pShape = new WordArtTextCascadeUp(); } break;
case msosptTextDeflateBottom : { pShape = new WordArtTextDeflateBottom(); } break;
case msosptTextTriangleInverted : case msosptTextTriangleInverted :
case msosptTextChevron : case msosptTextChevron :
case msosptTextChevronInverted : case msosptTextChevronInverted :
...@@ -232,30 +241,21 @@ namespace DocFileFormat ...@@ -232,30 +241,21 @@ namespace DocFileFormat
case msosptTextArchDownPour : case msosptTextArchDownPour :
case msosptTextCirclePour : case msosptTextCirclePour :
case msosptTextButtonPour : case msosptTextButtonPour :
case msosptTextCurveUp :
case msosptTextCurveDown : case msosptTextCurveDown :
case msosptTextCascadeUp :
case msosptTextCascadeDown : case msosptTextCascadeDown :
case msosptTextWave1 :
case msosptTextWave2 : case msosptTextWave2 :
case msosptTextWave3 :
case msosptTextWave4 :
case msosptTextInflate : case msosptTextInflate :
case msosptTextDeflate :
case msosptTextInflateBottom : case msosptTextInflateBottom :
case msosptTextDeflateBottom :
case msosptTextInflateTop : case msosptTextInflateTop :
case msosptTextDeflateTop : case msosptTextDeflateTop :
case msosptTextDeflateInflate : case msosptTextDeflateInflate :
case msosptTextDeflateInflateDeflate : case msosptTextDeflateInflateDeflate :
case msosptTextFadeRight : case msosptTextFadeRight :
case msosptTextFadeLeft : case msosptTextFadeLeft :
case msosptTextFadeUp :
case msosptTextFadeDown : case msosptTextFadeDown :
case msosptTextSlantUp :
case msosptTextSlantDown : case msosptTextSlantDown :
case msosptTextCanUp : case msosptTextCanUp :
case msosptTextCanDown : case msosptTextPlainText :
{ pShape = new WordArtTextType(TypeCode); } break; { pShape = new WordArtTextType(TypeCode); } break;
default : { pShape = NULL; } break; default : { pShape = NULL; } break;
......
...@@ -66,7 +66,7 @@ namespace DocFileFormat ...@@ -66,7 +66,7 @@ namespace DocFileFormat
virtual Record* NewObject( IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance ) virtual Record* NewObject( IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance )
{ {
return new UnknownRecord( _reader, bodySize, typeCode, version, instance ); return NULL;//new UnknownRecord( _reader, bodySize, typeCode, version, instance );
} }
}; };
} }
\ No newline at end of file
...@@ -68,7 +68,7 @@ namespace DocFileFormat ...@@ -68,7 +68,7 @@ namespace DocFileFormat
m_pXmlWriter->WriteNodeBegin( _T( "o:OLEObject" ), TRUE ); m_pXmlWriter->WriteNodeBegin( _T( "o:OLEObject" ), TRUE );
//type //type
if ( ole->fLinked ) if ( ole->bLinked )
{ {
int relID = -1; int relID = -1;
......
...@@ -31,26 +31,40 @@ ...@@ -31,26 +31,40 @@
*/ */
#include "PictureDescriptor.h" #include "PictureDescriptor.h"
#include "OfficeDrawing/MetafilePictBlip.h"
#ifndef MM_ISOTROPIC
#define MM_ISOTROPIC 7
#endif
#ifndef MM_ANISOTROPIC
#define MM_ANISOTROPIC 8
#endif
namespace DocFileFormat namespace DocFileFormat
{ {
/// Parses the CHPX for a fcPic an loads the PictureDescriptor at this offset /// Parses the CHPX for a fcPic an loads the PictureDescriptor at this offset
PictureDescriptor::PictureDescriptor(CharacterPropertyExceptions* chpx, POLE::Stream* stream, int size, bool oldVersion) PictureDescriptor::PictureDescriptor(CharacterPropertyExceptions* chpx, POLE::Stream* stream, int size, bool oldVersion)
: :
dxaGoal(0), dyaGoal(0), mx(0), my(0), Type(jpg), Name( _T( "" ) ), mfp(), dxaCropLeft(0), dyaCropTop(0), dxaGoal(0), dyaGoal(0), mx(0), my(0), Type(jpg), mfp(), dxaCropLeft(0), dyaCropTop(0),
dxaCropRight(0), dyaCropBottom(0), brcTop(NULL), brcLeft(NULL), brcBottom(NULL), brcRight(NULL), dxaOrigin(0), dyaOrigin(0), dxaCropRight(0), dyaCropBottom(0), brcTop(NULL), brcLeft(NULL), brcBottom(NULL), brcRight(NULL), dxaOrigin(0), dyaOrigin(0),
cProps(0), shapeContainer(NULL), blipStoreEntry(NULL) cProps(0), shapeContainer(NULL), blipStoreEntry(NULL), embeddedData(NULL), embeddedDataSize(0), embeddedDataHeader(NULL)
{ {
//Get start and length of the PICT //Get start and length of the PICT
int fc = GetFcPic( chpx ); int fc = GetFcPic( chpx );
if ( fc >= 0 ) if ( fc >= 0 )
{ {
parse( stream, fc, size, oldVersion); parse( stream, fc, size, oldVersion);
} }
} }
PictureDescriptor::PictureDescriptor()
:
dxaGoal(0), dyaGoal(0), mx(0), my(0), Type(jpg), mfp(), dxaCropLeft(0), dyaCropTop(0),
dxaCropRight(0), dyaCropBottom(0), brcTop(NULL), brcLeft(NULL), brcBottom(NULL), brcRight(NULL), dxaOrigin(0), dyaOrigin(0),
cProps(0), shapeContainer(NULL), blipStoreEntry(NULL), embeddedData(NULL), embeddedDataSize(0), embeddedDataHeader(NULL)
{
}
PictureDescriptor::~PictureDescriptor() PictureDescriptor::~PictureDescriptor()
{ {
Clear(); Clear();
...@@ -64,6 +78,9 @@ namespace DocFileFormat ...@@ -64,6 +78,9 @@ namespace DocFileFormat
RELEASEOBJECT(shapeContainer); RELEASEOBJECT(shapeContainer);
RELEASEOBJECT(blipStoreEntry); RELEASEOBJECT(blipStoreEntry);
RELEASEARRAYOBJECTS(embeddedData);
RELEASEARRAYOBJECTS(embeddedDataHeader);
} }
void PictureDescriptor::parse(POLE::Stream* stream, int fc, int sz, bool oldVersion) void PictureDescriptor::parse(POLE::Stream* stream, int fc, int sz, bool oldVersion)
{ {
...@@ -75,10 +92,12 @@ namespace DocFileFormat ...@@ -75,10 +92,12 @@ namespace DocFileFormat
int lcb = reader.ReadInt32(); int lcb = reader.ReadInt32();
int pos_start = reader.GetPosition();
if (lcb > 10000000) if (lcb > 10000000)
return; return;
if (lcb > sz && sz != 2) //bullet picture с неверным размером if (lcb > sz && sz != 1 && sz != 2) //bullet picture с неверным размером
{ {
unsigned char* bytes = reader.ReadBytes(sz - fc - 4, false); unsigned char* bytes = reader.ReadBytes(sz - fc - 4, false);
if ( bytes ) if ( bytes )
...@@ -88,114 +107,111 @@ namespace DocFileFormat ...@@ -88,114 +107,111 @@ namespace DocFileFormat
return; return;
} }
if (lcb >= 10) if (lcb < 10)
{ return;
int cbHeader = reader.ReadUInt16();
int cbHeader = reader.ReadUInt16();
mfp.mm = reader.ReadInt16(); mfp.mm = reader.ReadInt16();
mfp.xExt = reader.ReadInt16(); mfp.xExt = reader.ReadInt16();
mfp.yExt = reader.ReadInt16(); mfp.yExt = reader.ReadInt16();
mfp.hMf = reader.ReadInt16(); mfp.hMf = reader.ReadInt16();
if (mfp.mm >= 98 || oldVersion) unsigned char* bytes = reader.ReadBytes(14, true);
{ rcWinMf = std::vector<unsigned char>(bytes, (bytes + 14));
unsigned char* bytes = reader.ReadBytes(14, true); RELEASEARRAYOBJECTS(bytes);
rcWinMf = std::vector<unsigned char>(bytes, (bytes + 14));
RELEASEARRAYOBJECTS(bytes);
//dimensions
dxaGoal = reader.ReadInt16();
dyaGoal = reader.ReadInt16();
mx = reader.ReadUInt16();
my = reader.ReadUInt16();
//cropping
dxaCropLeft = reader.ReadInt16();
dyaCropTop = reader.ReadInt16();
dxaCropRight = reader.ReadInt16();
dyaCropBottom = reader.ReadInt16();
short brcl = reader.ReadInt16();
// borders
int bytesCount = 4;
bytes = reader.ReadBytes( bytesCount, true );
brcTop = new BorderCode( bytes, bytesCount );
RELEASEARRAYOBJECTS( bytes );
bytes = reader.ReadBytes( bytesCount, true ); //dimensions
brcLeft = new BorderCode( bytes, 4 ); dxaGoal = reader.ReadInt16();
RELEASEARRAYOBJECTS( bytes ); dyaGoal = reader.ReadInt16();
mx = reader.ReadUInt16();
my = reader.ReadUInt16();
bytes = reader.ReadBytes( bytesCount, true ); //cropping
brcBottom = new BorderCode( bytes, 4 ); dxaCropLeft = reader.ReadInt16();
RELEASEARRAYOBJECTS( bytes ); dyaCropTop = reader.ReadInt16();
dxaCropRight = reader.ReadInt16();
dyaCropBottom = reader.ReadInt16();
bytes = reader.ReadBytes( bytesCount, true ); int brcl = reader.ReadInt16();
brcRight = new BorderCode( bytes, 4 );
RELEASEARRAYOBJECTS( bytes ); // borders
int bytesCount = oldVersion ? 2 : 4;
bytes = reader.ReadBytes( bytesCount, true );
brcTop = new BorderCode( bytes, bytesCount );
RELEASEARRAYOBJECTS( bytes );
dxaOrigin = reader.ReadInt16(); bytes = reader.ReadBytes( bytesCount, true );
dyaOrigin = reader.ReadInt16(); brcLeft = new BorderCode( bytes, bytesCount );
cProps = reader.ReadInt16(); RELEASEARRAYOBJECTS( bytes );
if (mfp.mm == MM_SHAPEFILE) bytes = reader.ReadBytes( bytesCount, true );
{ brcBottom = new BorderCode( bytes, bytesCount );
unsigned char cchPicName = reader.ReadByte(); RELEASEARRAYOBJECTS( bytes );
unsigned char* stPicName = reader.ReadBytes(cchPicName, true);
if ( stPicName != NULL )
{
std::wstring picName;
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &picName, stPicName, cchPicName, ENCODING_WINDOWS_1250 );
RELEASEARRAYOBJECTS(stPicName);
}
}
if (oldVersion) bytes = reader.ReadBytes( bytesCount, true );
{ brcRight = new BorderCode( bytes, bytesCount );
////blipStoreEntry = new BlipStoreEntry(); RELEASEARRAYOBJECTS( bytes );
dxaOrigin = reader.ReadInt16();
dyaOrigin = reader.ReadInt16();
//blipStoreEntry = new BlipStoreEntry(&reader,lcb, Global::msoblipDIB,0,0); int pos_end = reader.GetPosition();
//long pos = reader.GetPosition(); if (oldVersion)
{
int flag = brcl;
//unsigned char* pPicData = reader.ReadBytes(lcb - pos, true); brcl = FormatUtils::BitmaskToBool(flag, 0x000F);
//( 0 single 1 thick 2 double 3 shadow )
//int pos1 = 0; bool fFrameEmpty = FormatUtils::BitmaskToBool(flag, 0x0010);// picture consists of a single frame
bool fBitmap = FormatUtils::BitmaskToBool(flag, 0x0020);// ==1, when picture is just a bitmap
bool fDrawHatch = FormatUtils::BitmaskToBool(flag, 0x0040);// ==1, when picture is an active OLE object
bool fError = FormatUtils::BitmaskToBool(flag, 0x0080);// ==1, when picture is just an error message
short bpp = FormatUtils::BitmaskToBool(flag, 0x8000);// bits per pixel
//(0 unknown 1 monochrome 4 VGA)
//BITMAPINFOHEADER *bm = (BITMAPINFOHEADER *)(pPicData + pos1); int sz_hdr = pos_end - pos_start;
//NSFile::CFileBinary f; int header_size = 114;
//
//f.CreateFile(L"d:\\test.jpg");
//f.WriteFile(pPicData + pos1, lcb - pos - pos1);
//f.CloseFile();
//RELEASEARRAYOBJECTS(pPicData); embeddedDataSize = lcb - sz_hdr - header_size;
embeddedDataHeader = reader.ReadBytes( header_size, true);
embeddedData = reader.ReadBytes( embeddedDataSize, true );
}
else
{
cProps = reader.ReadInt16();
if (mfp.mm == MM_SHAPEFILE)
{
unsigned char cchPicName = reader.ReadByte();
unsigned char* stPicName = reader.ReadBytes(cchPicName, true);
if ( stPicName != NULL )
{
std::wstring picName;
FormatUtils::GetSTLCollectionFromBytes<std::wstring>( &picName, stPicName, cchPicName, ENCODING_WINDOWS_1250 );
RELEASEARRAYOBJECTS(stPicName);
}
}
shapeContainer = dynamic_cast<ShapeContainer*>(RecordFactory::ReadRecord(&reader, 0));
long pos = reader.GetPosition();
if( pos < ( fc + lcb ))
{
Record* rec = RecordFactory::ReadRecord( &reader, 0 );
if ((rec) && ( typeid(*rec) == typeid(BlipStoreEntry) ))
{
blipStoreEntry = dynamic_cast<BlipStoreEntry*>( rec );
} }
else else
{ {
//Parse the OfficeDrawing Stuff RELEASEOBJECT(rec);
shapeContainer = dynamic_cast<ShapeContainer*>(RecordFactory::ReadRecord(&reader, 0));
long pos = reader.GetPosition();
if( pos < ( fc + lcb ))
{
Record* rec = RecordFactory::ReadRecord( &reader, 0 );
if ((rec) && ( typeid(*rec) == typeid(BlipStoreEntry) ))
{
blipStoreEntry = dynamic_cast<BlipStoreEntry*>( rec );
}
else
{
RELEASEOBJECT(rec);
}
}
} }
} }
} }
...@@ -205,7 +221,7 @@ namespace DocFileFormat ...@@ -205,7 +221,7 @@ namespace DocFileFormat
/// Returns -1 if the CHPX has no fcPic. /// Returns -1 if the CHPX has no fcPic.
int PictureDescriptor::GetFcPic(const CharacterPropertyExceptions* chpx) int PictureDescriptor::GetFcPic(const CharacterPropertyExceptions* chpx)
{ {
int ret = -1; int ret = -1, ret1 = -1;
for ( std::list<SinglePropertyModifier>::const_iterator iter = chpx->grpprl->begin(); iter != chpx->grpprl->end(); iter++ ) for ( std::list<SinglePropertyModifier>::const_iterator iter = chpx->grpprl->begin(); iter != chpx->grpprl->end(); iter++ )
{ {
...@@ -216,6 +232,11 @@ namespace DocFileFormat ...@@ -216,6 +232,11 @@ namespace DocFileFormat
ret = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize ); ret = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize );
break; break;
case sprmOldCHps:
case sprmCHps:
ret1 = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize );
break;
case sprmCHsp: case sprmCHsp:
ret = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize ); ret = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize );
break; break;
......
...@@ -49,26 +49,26 @@ namespace DocFileFormat ...@@ -49,26 +49,26 @@ namespace DocFileFormat
struct MetafilePicture struct MetafilePicture
{ {
/// Specifies the mapping mode in which the picture is drawn. // Specifies the mapping mode in which the picture is drawn.
short mm; short mm;
/// Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes. // Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes.
/// (For more information about these modes, see the yExt member.) // (For more information about these modes, see the yExt member.)
/// The x-extent specifies the width of the rectangle within which the picture is drawn. // The x-extent specifies the width of the rectangle within which the picture is drawn.
/// The coordinates are in units that correspond to the mapping mode. // The coordinates are in units that correspond to the mapping mode.
short xExt; short xExt;
/// Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes. // Specifies the size of the metafile picture for all modes except the MM_ISOTROPIC and MM_ANISOTROPIC modes.
/// The y-extent specifies the height of the rectangle within which the picture is drawn. // The y-extent specifies the height of the rectangle within which the picture is drawn.
/// The coordinates are in units that correspond to the mapping mode. // The coordinates are in units that correspond to the mapping mode.
/// For MM_ISOTROPIC and MM_ANISOTROPIC modes, which can be scaled, the xExt and yExt members // For MM_ISOTROPIC and MM_ANISOTROPIC modes, which can be scaled, the xExt and yExt members
/// contain an optional suggested size in MM_HIMETRIC units. // contain an optional suggested size in MM_HIMETRIC units.
/// For MM_ANISOTROPIC pictures, xExt and yExt can be zero when no suggested size is supplied. // For MM_ANISOTROPIC pictures, xExt and yExt can be zero when no suggested size is supplied.
/// For MM_ISOTROPIC pictures, an aspect ratio must be supplied even when no suggested size is given. // For MM_ISOTROPIC pictures, an aspect ratio must be supplied even when no suggested size is given.
/// (If a suggested size is given, the aspect ratio is implied by the size.) // (If a suggested size is given, the aspect ratio is implied by the size.)
/// To give an aspect ratio without implying a suggested size, set xExt and yExt to negative values // To give an aspect ratio without implying a suggested size, set xExt and yExt to negative values
/// whose ratio is the appropriate aspect ratio. // whose ratio is the appropriate aspect ratio.
/// The magnitude of the negative xExt and yExt values is ignored; only the ratio is used. // The magnitude of the negative xExt and yExt values is ignored; only the ratio is used.
short yExt; short yExt;
/// Handle to a memory metafile. // Handle to a memory metafile.
short hMf; short hMf;
}; };
...@@ -78,16 +78,20 @@ namespace DocFileFormat ...@@ -78,16 +78,20 @@ namespace DocFileFormat
friend class VMLPictureMapping; friend class VMLPictureMapping;
friend class VMLShapeMapping; friend class VMLShapeMapping;
friend class NumberingMapping; friend class NumberingMapping;
friend class OleObject;
public: public:
/// Parses the CHPX for a fcPic an loads the PictureDescriptor at this offset // Parses the CHPX for a fcPic an loads the PictureDescriptor at this offset
PictureDescriptor( CharacterPropertyExceptions* chpx, POLE::Stream* stream, int size, bool oldVersion); PictureDescriptor ( );
PictureDescriptor ( CharacterPropertyExceptions* chpx, POLE::Stream* stream, int size, bool oldVersion);
virtual ~PictureDescriptor(); virtual ~PictureDescriptor();
void parse( POLE::Stream* stream, int fc, int sz, bool oldVersion);
private: private:
void parse( POLE::Stream* stream, int fc, int sz, bool oldVersion);
/// Returns the fcPic into the "data" stream, where the PIC begins. // Returns the fcPic into the "data" stream, where the PIC begins.
/// Returns -1 if the CHPX has no fcPic. // Returns -1 if the CHPX has no fcPic.
static int GetFcPic( const CharacterPropertyExceptions* chpx ); static int GetFcPic( const CharacterPropertyExceptions* chpx );
void Clear(); void Clear();
...@@ -95,45 +99,38 @@ namespace DocFileFormat ...@@ -95,45 +99,38 @@ namespace DocFileFormat
static const short MM_SHAPE = 0x0064; // Shape object static const short MM_SHAPE = 0x0064; // Shape object
static const short MM_SHAPEFILE = 0x0066; // Shape file static const short MM_SHAPEFILE = 0x0066; // Shape file
/// Rectangle for window origin and extents when metafile is stored (ignored if 0). std::vector<unsigned char> rcWinMf; // Rectangle for window origin and extents when metafile is stored (ignored if 0).
std::vector<unsigned char> rcWinMf;
/// Horizontal measurement in twips of the rectangle the picture should be imaged within. short dxaGoal; // Horizontal measurement in twips of the rectangle the picture should be imaged within.
short dxaGoal; short dyaGoal; // Vertical measurement in twips of the rectangle the picture should be imaged within.
/// Vertical measurement in twips of the rectangle the picture should be imaged within.
short dyaGoal; unsigned short mx; // Horizontal scaling factor supplied by user expressed in .001% units
/// Horizontal scaling factor supplied by user expressed in .001% units unsigned short my; // Vertical scaling factor supplied by user expressed in .001% units
unsigned short mx;
/// Vertical scaling factor supplied by user expressed in .001% units PictureType Type; // The type of the picture
unsigned short my;
/// The type of the picture MetafilePicture mfp;
PictureType Type;
/// The name of the picture short dxaCropLeft; // The amount the picture has been cropped on the left in twips
std::wstring Name; short dyaCropTop; // The amount the picture has been cropped on the top in twips
/// The data of the windows metafile picture (WMF) short dxaCropRight; // The amount the picture has been cropped on the right in twips
MetafilePicture mfp; short dyaCropBottom; // The amount the picture has been cropped on the bottom in twips
/// The amount the picture has been cropped on the left in twips
short dxaCropLeft; BorderCode *brcTop; // Border above picture
/// The amount the picture has been cropped on the top in twips BorderCode *brcLeft; // Border to the left of the picture
short dyaCropTop; BorderCode *brcBottom; // Border below picture
/// The amount the picture has been cropped on the right in twips BorderCode *brcRight; // Border to the right of the picture
short dxaCropRight;
/// The amount the picture has been cropped on the bottom in twips short dxaOrigin; // horizontal offset of hand annotation origin
short dyaCropBottom; short dyaOrigin; // vertical offset of hand annotation origin
/// Border above picture
BorderCode *brcTop;
/// Border to the left of the picture
BorderCode *brcLeft;
/// Border below picture
BorderCode *brcBottom;
/// Border to the right of the picture
BorderCode *brcRight;
/// Horizontal offset of hand annotation origin
short dxaOrigin;
/// vertical offset of hand annotation origin
short dyaOrigin;
/// unused
short cProps; short cProps;
ShapeContainer* shapeContainer; //------------------
BlipStoreEntry* blipStoreEntry; ShapeContainer * shapeContainer;
BlipStoreEntry * blipStoreEntry;
unsigned char *embeddedDataHeader;
unsigned char *embeddedData;
int embeddedDataSize;
}; };
} }
...@@ -62,7 +62,7 @@ namespace DocFileFormat ...@@ -62,7 +62,7 @@ namespace DocFileFormat
} }
else else
{ {
code_page = ENCODING_UTF16; code_page = (code_page == ENCODING_WINDOWS_1250 ? ENCODING_UTF16 : code_page_);
this->fc = fcValue; this->fc = fcValue;
} }
} }
......
...@@ -44,9 +44,9 @@ namespace DocFileFormat ...@@ -44,9 +44,9 @@ namespace DocFileFormat
protected: protected:
static const int CP_LENGTH = 4; static const int CP_LENGTH = 4;
std::vector<int> CharacterPositions; std::vector<int> CharacterPositions;
std::vector<ByteStructure*> Elements; std::vector<ByteStructure*> Elements;
bool m_bIsValid; bool m_bIsValid;
public: public:
Plex(int structureLength, POLE::Stream* stream, unsigned int fc, unsigned int lcb, bool oldVersion) Plex(int structureLength, POLE::Stream* stream, unsigned int fc, unsigned int lcb, bool oldVersion)
......
...@@ -66,12 +66,17 @@ namespace DocFileFormat ...@@ -66,12 +66,17 @@ namespace DocFileFormat
while ( goOn ) while ( goOn )
{ {
//enough bytes to read?
if ( ( sprmStart + opCodeSize ) < size ) if ( ( sprmStart + opCodeSize ) < size )
{ {
OperationCode opCode = oldVersion ? (OperationCode)FormatUtils::BytesToUChar ( bytes, sprmStart, size ) : unsigned short code = oldVersion ? FormatUtils::BytesToUChar ( bytes, sprmStart, size ) :
(OperationCode)FormatUtils::BytesToUInt16 ( bytes, sprmStart, size ) ; FormatUtils::BytesToUInt16 ( bytes, sprmStart, size ) ;
if (oldVersion && code == 0)
{
sprmStart++;
continue;
}
OperationCode opCode = (OperationCode)code;
short opSize = -1; short opSize = -1;
if (oldVersion) if (oldVersion)
...@@ -91,28 +96,32 @@ namespace DocFileFormat ...@@ -91,28 +96,32 @@ namespace DocFileFormat
//some opCode need special treatment //some opCode need special treatment
switch ( opCode ) switch ( opCode )
{ {
case sprmOldTDefTable:
case sprmOldTDefTable10:
case sprmTDefTable: case sprmTDefTable:
case sprmTDefTable10: case sprmTDefTable10:
{ {
//The opSize of the table definition is stored in 2 bytes instead of 1 //The opSize of the table definition is stored in 2 bytes instead of 1
lenByte = 2; lenByte = 2;
opSize = FormatUtils::BytesToInt16( bytes, ( sprmStart + 2 ), size ); opSize = FormatUtils::BytesToInt16( bytes, ( sprmStart + opCodeSize ), size );
//Word adds an additional unsigned char to the opSize to compensate the additional //Word adds an additional unsigned char to the opSize to compensate the additional
//unsigned char needed for the length //unsigned char needed for the length
opSize--; opSize--;
}break; }break;
case sprmOldPChgTabs:
case sprmPChgTabs: case sprmPChgTabs:
{ {
//The tab operand can be bigger than 255 bytes (length unsigned char is set to 255). //The tab operand can be bigger than 255 bytes (length unsigned char is set to 255).
//In this case a special calculation of the opSize is needed //In this case a special calculation of the opSize is needed
lenByte = 1; lenByte = 1;
opSize = bytes[sprmStart + 2]; opSize = bytes[sprmStart + opCodeSize];
if ( opSize == 255 ) if ( opSize == 255 )
{ {
unsigned char itbdDelMax = bytes[sprmStart + 3]; unsigned char itbdDelMax = bytes[sprmStart + opCodeSize + 1];
unsigned char itbdAddMax = bytes[sprmStart + 3 + 2 * itbdDelMax]; unsigned char itbdAddMax = bytes[sprmStart + opCodeSize + 1 + 2 * itbdDelMax];
opSize = (short)( ( itbdDelMax * 4 + itbdAddMax * 3 ) - 1 ); opSize = (short)( ( itbdDelMax * 4 + itbdAddMax * 3 ) - 1 );
} }
}break; }break;
...@@ -133,7 +142,6 @@ namespace DocFileFormat ...@@ -133,7 +142,6 @@ namespace DocFileFormat
} }
} }
//copy sprm to array
//length is 2byte for the opCode, lenByte for the length, opSize for the length of the operand //length is 2byte for the opCode, lenByte for the length, opSize for the length of the operand
int sprmBytesSize = opCodeSize + lenByte + opSize; int sprmBytesSize = opCodeSize + lenByte + opSize;
unsigned char* sprmBytes = NULL; unsigned char* sprmBytes = NULL;
...@@ -144,7 +152,6 @@ namespace DocFileFormat ...@@ -144,7 +152,6 @@ namespace DocFileFormat
{ {
memcpy( sprmBytes, ( bytes + sprmStart ), sprmBytesSize ); memcpy( sprmBytes, ( bytes + sprmStart ), sprmBytesSize );
//parse
SinglePropertyModifier sprm( sprmBytes, sprmBytesSize, oldVersion ); SinglePropertyModifier sprm( sprmBytes, sprmBytesSize, oldVersion );
grpprl->push_back( sprm ); grpprl->push_back( sprm );
......
...@@ -105,17 +105,28 @@ namespace DocFileFormat ...@@ -105,17 +105,28 @@ namespace DocFileFormat
if (pTable) if (pTable)
{ {
unsigned char fHF = 255; //all headers & footers
for (std::list<SinglePropertyModifier>::iterator iter = sepx->grpprl->begin(); iter != sepx->grpprl->end(); ++iter)
{
switch (iter->OpCode)
{
case sprmOldSGprfIhdt:
case sprmSGprfIhdt:
fHF = FormatUtils::BytesToUChar( iter->Arguments, 0, iter->argumentsSize );
break;
}
}
// Header // Header
WriteSectionStory (pTable->GetEvenHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"even")); if (FormatUtils::GetBitFromInt(fHF, 0)) WriteSectionStory (pTable->GetEvenHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"even"));
WriteSectionStory (pTable->GetOddHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"default")); if (FormatUtils::GetBitFromInt(fHF, 1)) WriteSectionStory (pTable->GetOddHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"default"));
WriteSectionStory (pTable->GetFirstHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"first")); if (FormatUtils::GetBitFromInt(fHF, 4)) WriteSectionStory (pTable->GetFirstHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"first"));
// Footer // Footer
WriteSectionStory (pTable->GetEvenFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"even")); if (FormatUtils::GetBitFromInt(fHF, 2)) WriteSectionStory (pTable->GetEvenFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"even"));
WriteSectionStory (pTable->GetOddFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"default")); if (FormatUtils::GetBitFromInt(fHF, 3)) WriteSectionStory (pTable->GetOddFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"default"));
WriteSectionStory (pTable->GetFirstFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"first")); if (FormatUtils::GetBitFromInt(fHF, 5)) WriteSectionStory (pTable->GetFirstFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"first"));
} }
//MUST be ignored if the section does not have page number restart enabled.([MS-DOC] — v20101113. стр 152) //MUST be ignored if the section does not have page number restart enabled.([MS-DOC] — v20101113. стр 152)
......
...@@ -51,7 +51,14 @@ namespace DocFileFormat ...@@ -51,7 +51,14 @@ namespace DocFileFormat
opCodeSize = 1; opCodeSize = 1;
//first 1 byte are the operation code ... //first 1 byte are the operation code ...
OpCode = (OperationCode)FormatUtils::BytesToUChar( bytes, 0, size ); OpCode = (OperationCode)FormatUtils::BytesToUChar( bytes, 0, size );
opSize = GetOldOperandSize( (unsigned char)OpCode ); if (OpCode == 0 && size == 4)
{
//так записывается rgb цвет (
OpCode = sprmCCv;
opSize = 3;
}
else
opSize = GetOldOperandSize( (unsigned char)OpCode );
} }
else else
{ {
...@@ -86,6 +93,8 @@ namespace DocFileFormat ...@@ -86,6 +93,8 @@ namespace DocFileFormat
{ {
switch ( OpCode ) switch ( OpCode )
{ {
case sprmOldTDefTable:
case sprmOldTDefTable10:
case sprmTDefTable: case sprmTDefTable:
case sprmTDefTable10: case sprmTDefTable10:
{ {
...@@ -99,6 +108,7 @@ namespace DocFileFormat ...@@ -99,6 +108,7 @@ namespace DocFileFormat
} }
break; break;
case sprmOldPChgTabs:
case sprmPChgTabs: case sprmPChgTabs:
{ {
argumentsSize = bytes[2]; argumentsSize = bytes[2];
...@@ -205,7 +215,9 @@ namespace DocFileFormat ...@@ -205,7 +215,9 @@ namespace DocFileFormat
} }
static const unsigned char OldOperandSizeTable[] = static const unsigned char OldOperandSizeTable[] =
{ {
0, 0, 2, 255, 1, 1, 1, 1, 1, 1, 1, 1, 255, 1, 1, 255, 2, 2, 2, 2, 4, 2, 2, 255, 1, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 255, 2, 4, 1, 2, 3, 255, 1, 0, 0, 0, 0, 2, 255, 255, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 3, 2, 2, 1, 1, 1, 1, 1, 255, 1, 255, 255, 2, 255, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1, 1, 255, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1, 255, 0, 0, 3, 3, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 2, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 1, 1, 12, 255, 2, 0, 0, 4, 5, 4, 2, 4, 2, 2, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0 // 0,0,2,255,1,1,1,1,1,1,1,1,255,1,1,255,2,2,2,2,4,2,2,255,1,1,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,1,2,2,2,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,255,2,4,1,2,3,255,1,0,0,0,0,2,255,255,0,0,1,1,1,1,1,1,1,1,2,1,3,2,2,1,1,1,1,1,255,1,255,255,2,255,2,2,0,0,0,0,0,0,1,1,1,255,2,2,2,2,0,0,0,0,0,0,1,1,255,0,0,3,3,1,1,2,2,1,1,2,2,1,1,2,2,1,1,1,1,2,2,2,2,1,1,2,2,1,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,2,1,1,12,255,2,255,255,4,5,4,2,4,2,2,5,4,0,0,0,0,0,0,0,0
0,0,2,255,1,1,1,1,1,1,1,1,255,1,1,255,2,2,2,2,4,2,2,255,1,1,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,1,2,2,2,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,255,2,4,1,2,3,255,1,0,2,0,0,2,255,255,0,0,1,1,1,1,1,1,1,1,2,1,3,2,2,1,1,1,1,1,255,1,255,255,2,255,2,2,0,0,0,0,0,0,1,1,1,255,2,2,2,2,0,0,0,0,0,0,1,1,255,0,0,3,3,1,1,2,2,1,1,2,2,1,1,2,2,1,1,1,1,2,2,2,2,1,1,2,2,1,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,2,2,2,1,1,12,255,2,255,255,4,5,4,2,4,2,2,5,4,0,0,0,0,0,0,0,0
}; };
unsigned char SinglePropertyModifier::GetOldOperandSize(unsigned char code) unsigned char SinglePropertyModifier::GetOldOperandSize(unsigned char code)
......
/*
* (c) Copyright Ascensio System SIA 2010-2016
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia,
* EU, LV-1021.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "Spa.h"
#include "VirtualStreamReader.h"
namespace DocFileFormat
{
Spa::Spa() : spid(0), fHdr(0), bx(MARGIN), by(MARGIN), wr(0), wrk(0),
xaLeft(0), yaTop(0), xaRight(0), yaBottom(0),
fRcaSimple(0), fBelowText(0), fAnchorLock(0), cTxbx(0)
{
}
Spa::~Spa()
{
for (int i = 0 ; i < primitives.size(); i++)
{
if (primitives[i]) delete primitives[i];
primitives[i] = NULL;
}
}
void Spa::read_primitives(Spa* pSpa, VirtualStreamReader* reader, int length)
{
if (!pSpa) return;
if (!reader || length < 1) return;
int stream_pos = reader->GetPosition();
int pos = 0;
while (pos < length)
{
reader->Seek(stream_pos + pos, 0);
unsigned short dpk = reader->ReadUInt16();
int shape_type = FormatUtils::BitmaskToInt (dpk, 0x00ff);
short cb_primitive = reader->ReadInt16();
if (pos + cb_primitive > length)
{
reader->Seek(reader->GetPosition() - 4, 0);
break;
}
DrawingPrimitive *dp = DrawingPrimitive::Create(reader, cb_primitive - 4, shape_type);
if (dp)
pSpa->primitives.push_back(dp);
if (shape_type == 0x00)
{
//start group
read_primitives(pSpa, reader, cb_primitive - 4);
}
else if (shape_type == 0x08)
{
//end group
break;
}
pos += cb_primitive;
}
}
ByteStructure* Spa::ConstructObject(VirtualStreamReader* reader, int length)
{
Spa* pSpa = new Spa();
if (!pSpa) return NULL;
if (reader->olderVersion)
{
int fc = reader->ReadInt32();
pSpa->cTxbx = reader->ReadUInt16();
int pos_keep = reader->GetPosition();
reader->Seek(fc, 0);
unsigned short dok = reader->ReadUInt16();
short cb = reader->ReadInt16();
pSpa->bx = (AnchorType)reader->ReadByte();
pSpa->by = (AnchorType)reader->ReadByte();
short height = reader->ReadInt16();
pSpa->fAnchorLock = reader->ReadUInt16();
int pos = 10; //fixed size
read_primitives(pSpa, reader, cb - 10/*_primitive*/);
reader->Seek(pos_keep, 0);
}
else
{
pSpa->spid = reader->ReadInt32();
pSpa->xaLeft = reader->ReadInt32();
pSpa->yaTop = reader->ReadInt32();
pSpa->xaRight = reader->ReadInt32();
pSpa->yaBottom = reader->ReadInt32();
unsigned short flag = reader->ReadUInt16();
pSpa->fHdr = FormatUtils::BitmaskToBool(flag, 0x0001);
pSpa->bx = (AnchorType)FormatUtils::BitmaskToInt(flag, 0x0006);
pSpa->by = (AnchorType)FormatUtils::BitmaskToInt(flag, 0x0018);
pSpa->wr = (unsigned short)FormatUtils::BitmaskToInt(flag, 0x01E0);
pSpa->wrk = (unsigned short)FormatUtils::BitmaskToInt(flag, 0x1E00);
pSpa->fRcaSimple = FormatUtils::BitmaskToBool(flag, 0x2000);
pSpa->fBelowText = FormatUtils::BitmaskToBool(flag, 0x4000);
pSpa->fAnchorLock = FormatUtils::BitmaskToBool(flag, 0x8000);
pSpa->cTxbx = reader->ReadInt32();
}
return static_cast<ByteStructure*>(pSpa);
}
}
...@@ -31,8 +31,10 @@ ...@@ -31,8 +31,10 @@
*/ */
#pragma once #pragma once
#include "VirtualStreamReader.h"
#include "ByteStructure.h" #include "ByteStructure.h"
#include "DrawingPrimitives.h"
class VirtualStreamReader;
namespace DocFileFormat namespace DocFileFormat
{ {
...@@ -47,48 +49,21 @@ namespace DocFileFormat ...@@ -47,48 +49,21 @@ namespace DocFileFormat
{ {
public: public:
friend class VMLShapeMapping; friend class VMLShapeMapping;
static const int STRUCTURE_SIZE = 26; friend class DocumentMapping;
static const int STRUCTURE_SIZE = 26;
static const int STRUCTURE_SIZE_OLD = 6;
Spa() static const int GetSize(bool bOldVersion)
{ {
return bOldVersion ? STRUCTURE_SIZE_OLD : STRUCTURE_SIZE;
} }
virtual ~Spa() Spa();
{
}
virtual ByteStructure* ConstructObject(VirtualStreamReader* reader, int length)
{
Spa* pSpa = new Spa();
if (pSpa)
{
pSpa->spid = reader->ReadInt32();
pSpa->xaLeft = reader->ReadInt32();
pSpa->yaTop = reader->ReadInt32();
pSpa->xaRight = reader->ReadInt32();
pSpa->yaBottom = reader->ReadInt32();
unsigned short flag = reader->ReadUInt16();
pSpa->fHdr = FormatUtils::BitmaskToBool(flag, 0x0001);
pSpa->bx = (AnchorType)FormatUtils::BitmaskToInt(flag, 0x0006);
pSpa->by = (AnchorType)FormatUtils::BitmaskToInt(flag, 0x0018);
pSpa->wr = (unsigned short)FormatUtils::BitmaskToInt(flag, 0x01E0);
pSpa->wrk = (unsigned short)FormatUtils::BitmaskToInt(flag, 0x1E00);
pSpa->fRcaSimple = FormatUtils::BitmaskToBool(flag, 0x2000);
pSpa->fBelowText = FormatUtils::BitmaskToBool(flag, 0x4000);
pSpa->fAnchorLock = FormatUtils::BitmaskToBool(flag, 0x8000);
pSpa->cTxbx = reader->ReadInt32(); virtual ~Spa();
return static_cast<ByteStructure*>(pSpa);
}
return NULL;
}
virtual ByteStructure* ConstructObject(VirtualStreamReader* reader, int length);
inline int GetShapeID() const inline int GetShapeID() const
{ {
return spid; return spid;
...@@ -141,13 +116,12 @@ namespace DocFileFormat ...@@ -141,13 +116,12 @@ namespace DocFileFormat
/// forcing the xaLeft, xaRight, yaTop, and yaBottom fields /// forcing the xaLeft, xaRight, yaTop, and yaBottom fields
/// to all be page relative. /// to all be page relative.
bool fRcaSimple; bool fRcaSimple;
/// true: shape is below text bool fBelowText; // true: shape is below text
/// false: shape is above text bool fAnchorLock; // true: anchor is locked
bool fBelowText; int cTxbx; // Count of textboxes in shape (undo doc only)
/// true: anchor is locked
/// fasle: anchor is not locked DrawingPrimitives primitives;
bool fAnchorLock;
/// Count of textboxes in shape (undo doc only) void read_primitives(Spa* pSpa, VirtualStreamReader* reader, int length);
int cTxbx;
}; };
} }
...@@ -45,7 +45,8 @@ namespace DocFileFormat ...@@ -45,7 +45,8 @@ namespace DocFileFormat
friend class FontTableMapping; friend class FontTableMapping;
friend class StyleSheetMapping; friend class StyleSheetMapping;
friend class DocumentMapping; friend class DocumentMapping;
friend class NumberingMapping;
private: private:
bool fExtend; bool fExtend;
int cbData; int cbData;
......
...@@ -353,7 +353,7 @@ namespace DocFileFormat ...@@ -353,7 +353,7 @@ namespace DocFileFormat
} }
Table::Table( DocumentMapping* _documentMapping, int _cp, unsigned int _depth ): Table::Table( DocumentMapping* _documentMapping, int _cp, unsigned int _depth ):
cpStart(_cp), cpEnd(_cp), depth(_depth), documentMapping(_documentMapping) cpStart(_cp), cpEnd(_cp), depth(_depth), documentMapping(_documentMapping)
{ {
if ( documentMapping != NULL ) if ( documentMapping != NULL )
{ {
...@@ -371,8 +371,8 @@ namespace DocFileFormat ...@@ -371,8 +371,8 @@ namespace DocFileFormat
TableInfo tai( papx ); TableInfo tai( papx );
TableRow tableRow( documentMapping, _cp ); TableRow tableRow ( documentMapping, _cp );
TableCell tableCell( documentMapping, _cp ); TableCell tableCell ( documentMapping, _cp );
do do
{ {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment