diff --git a/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.cpp b/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.cpp index 3a89650009..c0a6b52513 100644 --- a/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.cpp @@ -39,20 +39,40 @@ namespace DocFileFormat AnnotationReferenceDescriptor *newObject = new AnnotationReferenceDescriptor(); //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( &(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( &(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 - reader->ReadBytes(4, false); + FormatUtils::GetSTLCollectionFromBytes( &(newObject->m_UserInitials), chars, ( cch * 2 ), ENCODING_UTF16); + + 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(newObject); } diff --git a/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.h b/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.h index 947c4f665e..d3e12d14fd 100644 --- a/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.h +++ b/ASCOfficeDocFile/DocDocxConverter/AnnotationReferenceDescriptor.h @@ -39,6 +39,12 @@ namespace DocFileFormat { public: 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 { diff --git a/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp index e3259c3756..d56f27bb0b 100755 --- a/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp @@ -61,6 +61,8 @@ namespace DocFileFormat m_context = context; m_bInternalXmlWriter = false; + _writeWebHidden = false; + _writeInstrText = false; _isSectionPageBreak = 0; } @@ -642,52 +644,67 @@ namespace DocFileFormat int fcPic = m_document->FindFileCharPos( cpPic ); std::list* chpxs = m_document->GetCharacterPropertyExceptions(fcPic, fcPic + 1); - CharacterPropertyExceptions* chpxPic = chpxs->front(); + CharacterPropertyExceptions* chpxObj = chpxs->front(); - PictureDescriptor pic(chpxPic, m_document->DataStream, 0x7fffffff, m_document->bOlderVersion); - - RevisionData oData = RevisionData(chpxPic); + RevisionData oData = RevisionData(chpxObj); CharacterPropertiesMapping* rPr = new CharacterPropertiesMapping(m_pXmlWriter, m_document, &oData, _lastValidPapx, false); if(rPr) { - chpxPic->Convert(rPr); + chpxObj->Convert(rPr); RELEASEOBJECT(rPr); - } - XmlUtils::CXmlWriter OleWriter; - OleWriter.WriteNodeBegin (_T( "w:object" ), TRUE); + } + XmlUtils::CXmlWriter OleWriter; + VMLPictureMapping oVmlMapper (m_context, &OleWriter, true, _caller); - //append the origin attributes - OleWriter.WriteAttribute( _T( "w:dxaOrig" ), FormatUtils::IntToWideString( ( pic.dxaGoal + pic.dxaOrigin ) ).c_str() ); - OleWriter.WriteAttribute( _T( "w:dyaOrig" ), FormatUtils::IntToWideString( ( pic.dyaGoal + pic.dyaOrigin ) ).c_str() ); - OleWriter.WriteNodeEnd( _T( "" ), TRUE, FALSE ); - - VMLPictureMapping oVmlMapper (m_context, &OleWriter, true, _caller); - pic.Convert(&oVmlMapper); - RELEASEOBJECT(chpxs); - - if ( cpFieldSep < cpFieldEnd ) + if (m_document->bOlderVersion) { - int fcFieldSep = m_document->m_PieceTable->FileCharacterPositions->operator []( cpFieldSep ); - int fcFieldSep1 = m_document->FindFileCharPos( cpFieldSep ); + OleObject ole ( chpxObj, m_document->GetStorage(), m_document->bOlderVersion); - std::list* chpxs = m_document->GetCharacterPropertyExceptions( fcFieldSep, ( fcFieldSep + 1 ) ); - CharacterPropertyExceptions* chpxSep = chpxs->front(); - - OleObject ole ( chpxSep, m_document->GetStorage() ); - OleObjectMapping oleObjectMapping( &OleWriter, m_context, &pic, _caller, oVmlMapper.GetShapeId() ); - - if (oVmlMapper.m_isEmbedded) - { - ole.isEquation = oVmlMapper.m_isEquation; - ole.isEmbedded = oVmlMapper.m_isEmbedded; - ole.emeddedData = oVmlMapper.m_embeddedData; - } - ole.Convert( &oleObjectMapping ); - - RELEASEOBJECT( chpxs ); - } + OleWriter.WriteNodeBegin (_T( "w:object" ), TRUE); + OleWriter.WriteAttribute( _T( "w:dxaOrig" ), FormatUtils::IntToWideString( ( ole.pictureDesciptor.dxaGoal + ole.pictureDesciptor.dxaOrigin ) ).c_str() ); + OleWriter.WriteAttribute( _T( "w:dyaOrig" ), FormatUtils::IntToWideString( ( ole.pictureDesciptor.dyaGoal + ole.pictureDesciptor.dyaOrigin ) ).c_str() ); + OleWriter.WriteNodeEnd( _T( "" ), TRUE, FALSE ); + ole.pictureDesciptor.Convert(&oVmlMapper); + OleObjectMapping oleObjectMapping( &OleWriter, m_context, &ole.pictureDesciptor, _caller, oVmlMapper.GetShapeId() ); + + ole.Convert( &oleObjectMapping ); + } + else + { + PictureDescriptor pic(chpxObj, m_document->DataStream, 0x7fffffff, m_document->bOlderVersion); + + OleWriter.WriteNodeBegin (_T( "w:object" ), TRUE); + OleWriter.WriteAttribute( _T( "w:dxaOrig" ), FormatUtils::IntToWideString( ( pic.dxaGoal + pic.dxaOrigin ) ).c_str() ); + OleWriter.WriteAttribute( _T( "w:dyaOrig" ), FormatUtils::IntToWideString( ( pic.dyaGoal + pic.dyaOrigin ) ).c_str() ); + OleWriter.WriteNodeEnd( _T( "" ), TRUE, FALSE ); + + pic.Convert(&oVmlMapper); + RELEASEOBJECT(chpxs); + + if ( cpFieldSep < cpFieldEnd && m_document->m_PieceTable) + { + int fcFieldSep = m_document->m_PieceTable->FileCharacterPositions->operator []( cpFieldSep ); + int fcFieldSep1 = m_document->FindFileCharPos( cpFieldSep ); + + std::list* chpxs = m_document->GetCharacterPropertyExceptions( fcFieldSep, ( fcFieldSep + 1 ) ); + CharacterPropertyExceptions* chpxSep = chpxs->front(); + + OleObject ole ( chpxSep, m_document->GetStorage(), m_document->bOlderVersion); + OleObjectMapping oleObjectMapping( &OleWriter, m_context, &pic, _caller, oVmlMapper.GetShapeId() ); + + if (oVmlMapper.m_isEmbedded) + { + ole.isEquation = oVmlMapper.m_isEquation; + ole.isEmbedded = oVmlMapper.m_isEmbedded; + ole.emeddedData = oVmlMapper.m_embeddedData; + } + ole.Convert( &oleObjectMapping ); + + RELEASEOBJECT( chpxs ); + } + } OleWriter.WriteNodeEnd( _T( "w:object" ) ); if (!oVmlMapper.m_isEmbedded && oVmlMapper.m_isEquation) @@ -699,7 +716,7 @@ namespace DocFileFormat else { m_pXmlWriter->WriteString(OleWriter.GetXmlString()); - } + } } if (bEMBED) _skipRuns = 3; @@ -758,15 +775,15 @@ namespace DocFileFormat } else if ((TextMark::DrawnObject == c) && fSpec) { - Spa* pSpa = NULL; + Spa* pSpa = NULL; if (typeid(*this) == typeid(MainDocumentMapping)) { - pSpa = static_cast(m_document->OfficeDrawingPlex->GetStruct(cp)); + pSpa = static_cast(m_document->OfficeDrawingPlex->GetStruct(cp)); } else if ((typeid(*this) == typeid(HeaderMapping) ) || ( typeid(*this) == typeid(FooterMapping))) { int headerCp = ( cp - m_document->FIB->m_RgLw97.ccpText - m_document->FIB->m_RgLw97.ccpFtn ); - pSpa = static_cast(m_document->OfficeDrawingPlexHeader->GetStruct(headerCp)); + pSpa = static_cast(m_document->OfficeDrawingPlexHeader->GetStruct(headerCp)); } if (pSpa) @@ -815,7 +832,7 @@ namespace DocFileFormat if (oVmlMapper.m_isEmbedded) { - OleObject ole ( chpx, m_document->GetStorage() ); + OleObject ole ( chpx, m_document->GetStorage(), m_document->bOlderVersion); OleObjectMapping oleObjectMapping( m_pXmlWriter, m_context, &oPicture, _caller, oVmlMapper.GetShapeId() ); ole.isEquation = oVmlMapper.m_isEquation; @@ -1555,8 +1572,8 @@ namespace DocFileFormat { if (DocFileFormat::sprmCSymbol == iter->OpCode) { - //special symbol short fontIndex = FormatUtils::BytesToInt16( iter->Arguments, 0, iter->argumentsSize ); + short code = FormatUtils::BytesToInt16( iter->Arguments, 2, iter->argumentsSize ); FontFamilyName* ffn = static_cast( m_document->FontTable->operator [] ( fontIndex ) ); @@ -1566,6 +1583,19 @@ namespace DocFileFormat break; } + else if (DocFileFormat::sprmOldCSymbol == iter->OpCode) + { + short fontIndex = FormatUtils::BytesToInt16( iter->Arguments, 0, iter->argumentsSize ) ; + + short code = FormatUtils::BytesToUChar( iter->Arguments, 2, iter->argumentsSize ); + + FontFamilyName* ffn = static_cast( m_document->FontTable->operator [] ( fontIndex ) ); + + ret.FontName = ffn->xszFtn; + ret.HexValue = L"f0" + FormatUtils::IntToFormattedWideString( code, _T( "%02x" ) ); + + break; + } } return ret; diff --git a/ASCOfficeDocFile/DocDocxConverter/FooterMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/FooterMapping.cpp index a8933716fe..96ccfedf2f 100644 --- a/ASCOfficeDocFile/DocDocxConverter/FooterMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/FooterMapping.cpp @@ -65,7 +65,7 @@ namespace DocFileFormat //this additional paragraph mark shall not be converted. cpMax--; - while ( cp < cpMax ) + while ( cp < cpMax && cp < (int)m_document->Text->size()) { int fc = m_document->FindFileCharPos(cp); if (fc < 0) break; diff --git a/ASCOfficeDocFile/DocDocxConverter/FormattedDiskPagePAPX.cpp b/ASCOfficeDocFile/DocDocxConverter/FormattedDiskPagePAPX.cpp index a86ce84dc6..4ee4540d7d 100644 --- a/ASCOfficeDocFile/DocDocxConverter/FormattedDiskPagePAPX.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/FormattedDiskPagePAPX.cpp @@ -179,7 +179,7 @@ namespace DocFileFormat //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; diff --git a/ASCOfficeDocFile/DocDocxConverter/HeaderAndFooterTable.cpp b/ASCOfficeDocFile/DocDocxConverter/HeaderAndFooterTable.cpp index e33324b05d..f57561a726 100644 --- a/ASCOfficeDocFile/DocDocxConverter/HeaderAndFooterTable.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/HeaderAndFooterTable.cpp @@ -42,7 +42,7 @@ namespace DocFileFormat 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 ) ) { @@ -53,14 +53,15 @@ namespace DocFileFormat table[i] = tableReader.ReadInt32(); } - int count = ( tableSize - 8 ) / 6; - int initialPos = fib->m_RgLw97.ccpText + fib->m_RgLw97.ccpFtn; + //the first 6 _entries are about footnote and endnote formatting //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) { //Even Header @@ -123,7 +124,7 @@ namespace DocFileFormat pos++; - if (pos > tableSize) + if (pos >= tableSize) break; //First Page Footers diff --git a/ASCOfficeDocFile/DocDocxConverter/HeaderMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/HeaderMapping.cpp index 1abbc36f65..8301ed5506 100644 --- a/ASCOfficeDocFile/DocDocxConverter/HeaderMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/HeaderMapping.cpp @@ -65,7 +65,7 @@ namespace DocFileFormat //this additional paragraph mark shall not be converted. cpMax--; - while ( cp < cpMax ) + while ( cp < cpMax && cp < (int)m_document->Text->size()) { int fc = m_document->FindFileCharPos(cp); if (fc < 0) break; diff --git a/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h b/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h index 710916dc59..bc16657599 100644 --- a/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h +++ b/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h @@ -300,11 +300,11 @@ typedef enum _BlipCompression 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) { - this->m_rgbUid = this->Reader->ReadBytes( 16, true ); + m_rgbUid = Reader->ReadBytes( 16, true ); 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; @@ -312,22 +312,22 @@ typedef enum _BlipCompression CMetaHeader oMetaHeader; - this->m_cb = this->Reader->ReadInt32(); + m_cb = Reader->ReadInt32(); - this->m_rcBounds.left = this->Reader->ReadInt32(); - this->m_rcBounds.top = this->Reader->ReadInt32(); - this->m_rcBounds.right = this->Reader->ReadInt32() + this->m_rcBounds.left; - this->m_rcBounds.bottom = this->Reader->ReadInt32() + this->m_rcBounds.top; + m_rcBounds.left = Reader->ReadInt32(); + m_rcBounds.top = Reader->ReadInt32(); + m_rcBounds.right = Reader->ReadInt32() + m_rcBounds.left; + m_rcBounds.bottom = Reader->ReadInt32() + m_rcBounds.top; - this->m_ptSize.x = this->Reader->ReadInt32(); - this->m_ptSize.y = this->Reader->ReadInt32(); + m_ptSize.x = Reader->ReadInt32(); + m_ptSize.y = Reader->ReadInt32(); - this->m_cbSave = this->Reader->ReadInt32(); - this->m_fCompression = (BlipCompression)this->Reader->ReadByte(); - this->m_fFilter = ( this->Reader->ReadByte() == 1 ) ? (true) : (false); + m_cbSave = Reader->ReadInt32(); + m_fCompression = (BlipCompression)Reader->ReadByte(); + m_fFilter = ( Reader->ReadByte() == 1 ) ? (true) : (false); 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.cbSize = m_cb; @@ -369,9 +369,9 @@ typedef enum _BlipCompression virtual ~MetafilePictBlip() { - RELEASEARRAYOBJECTS( this->m_rgbUid ); - RELEASEARRAYOBJECTS( this->m_rgbUidPrimary ); - RELEASEARRAYOBJECTS( this->m_pvBits ); + RELEASEARRAYOBJECTS( m_rgbUid ); + RELEASEARRAYOBJECTS( m_rgbUidPrimary ); + RELEASEARRAYOBJECTS( m_pvBits ); } virtual Record* NewObject( IBinaryReader* _reader, unsigned int bodySize, unsigned int typeCode, unsigned int version, unsigned int instance ) @@ -386,9 +386,9 @@ typedef enum _BlipCompression 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]; HRESULT res = S_OK; @@ -396,19 +396,19 @@ typedef enum _BlipCompression if (pOfficeUtils) { - pOfficeUtils->Uncompress( *buffer, &uncomprLen, this->m_pvBits, this->m_cbSave ); + pOfficeUtils->Uncompress( *buffer, &uncomprLen, m_pvBits, m_cbSave ); delete pOfficeUtils; 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]; - memcpy( *buffer, this->m_pvBits , this->m_cbSave ); + memcpy( *buffer, m_pvBits , m_cbSave ); } return uncomprLen; diff --git a/ASCOfficeDocFile/DocDocxConverter/OleObject.h b/ASCOfficeDocFile/DocDocxConverter/OleObject.h index 5d3f06c1fe..7148c1a49f 100644 --- a/ASCOfficeDocFile/DocDocxConverter/OleObject.h +++ b/ASCOfficeDocFile/DocDocxConverter/OleObject.h @@ -33,43 +33,43 @@ #include "IVisitable.h" #include "StructuredStorageReader.h" +#include "PictureDescriptor.h" namespace DocFileFormat { - class OleObject: public IVisitable - { - friend class OleObjectMapping; + class OleObject: public IVisitable + { + friend class OleObjectMapping; - private: - POLE::Storage *oleStorage; - - public: - enum LinkUpdateOption - { - NoLink = 0, - Always = 1, - OnCall = 3 - }; + public: + enum LinkUpdateOption + { + NoLink = 0, + Always = 1, + OnCall = 3 + }; + bool bOlderVersion; + bool bLinked; // The the value is true, the object is a linked object + + std::wstring ObjectId; + std::wstring ClassId; - std::wstring ObjectId; - std::wstring ClassId; - // CLSID ClassId; - /// The the value is true, the object is a linked object - bool fLinked; - /// Display name of the linked object or embedded object. - std::wstring UserType; - std::wstring ClipboardFormat; - std::wstring Link; - std::wstring Program; - LinkUpdateOption updateMode; - std::wstring UpdateMode; + std::wstring UserType; // Display name of the linked object or embedded object. + std::wstring ClipboardFormat; + std::wstring Link; + std::wstring Program; + LinkUpdateOption updateMode; + std::wstring UpdateMode; - bool isEquation; - bool isEmbedded; - std::string emeddedData; + bool isEquation; + bool isEmbedded; + + std::string emeddedData; + + PictureDescriptor pictureDesciptor; - OleObject( const CharacterPropertyExceptions* chpx, StructuredStorageReader* docStorage ) - : fLinked(false), updateMode(NoLink) + OleObject( const CharacterPropertyExceptions* chpx, StructuredStorageReader* docStorage, bool bOlderVersion_ ) + : bLinked(false), updateMode(NoLink), bOlderVersion(bOlderVersion_) { isEquation = isEmbedded = false; @@ -86,12 +86,11 @@ namespace DocFileFormat ObjectId = getOleEntryName( chpx ); std::string sObjectId( ObjectId.begin(), ObjectId.end() ); - //if (oleStorage->enterDirectory(sObjectId)) { std::string name = "ObjectPool/" + sObjectId + "/"; processOleStream( name + "Ole" ); - if ( this->fLinked ) + if ( bLinked ) { processLinkInfoStream( name + "LinkInfo" ); } @@ -99,213 +98,246 @@ namespace DocFileFormat { processCompObjStream( name + "CompObj" ); } + + processPICStream( name + "PIC" ); processEquationNativeStream( name + "Equation Native" ); } - //oleStorage->leaveDirectory(); delete ObjectPoolStorage; } - - //STATSTG stg; - //this->oleStorage->Stat( &stg, STATFLAG_NONAME ); - //this->ClassId = stg.clsid; - } - } - - virtual ~OleObject() - { - } - - private: - void processLinkInfoStream( const std::string& linkStream ) - { - try - { - POLE::Stream* pLinkStream = NULL; - HRESULT res = S_OK; - - pLinkStream = //oleStorage->stream(linkStream); - new POLE::Stream(oleStorage, linkStream); - - if ( pLinkStream ) - { - VirtualStreamReader reader( pLinkStream, 0, false); - - //there are two versions of the Link string, one contains ANSI characters, the other contains - //unicode characters. - //Both strings seem not to be standardized: - //The length prefix is a character count EXCLUDING the terminating zero - - //Read the ANSI version - short cch = reader.ReadInt16(); - unsigned char* str = reader.ReadBytes( cch, true ); - FormatUtils::GetSTLCollectionFromBytes( &this->Link, str, cch, ENCODING_WINDOWS_1250 ); - RELEASEARRAYOBJECTS( str ); - - //skip the terminating zero of the ANSI string - //even if the characters are ANSI chars, the terminating zero has 2 bytes - reader.ReadBytes( 2, false ); - - //skip the next 4 bytes (flags?) - reader.ReadBytes( 4, false ); - - //Read the Unicode version - this->Link.clear(); - - cch = reader.ReadInt16(); - str = reader.ReadBytes( ( cch * 2 ), true ); - FormatUtils::GetSTLCollectionFromBytes( &this->Link, str, ( cch * 2 ), ENCODING_UTF16 ); - RELEASEARRAYOBJECTS( str ); - - //skip the terminating zero of the Unicode string - reader.ReadBytes( 2, false ); - - delete pLinkStream; - } - } - catch (...) - { - } - } - - void processEquationNativeStream( const std::string& eqStream ) - { - try - { - POLE::Stream* pCompStream = NULL; - HRESULT res = S_OK; - - pCompStream = new POLE::Stream(oleStorage, eqStream); - - if ( pCompStream ) - { - VirtualStreamReader reader( pCompStream, 0, false); - - int sz = reader.GetSize(); - - unsigned char *Buffer = reader.ReadBytes( sz, true ); - - if (Buffer) - { - delete []Buffer; - } - - delete pCompStream; - } - } - catch (...) - { - } - } - - void processCompObjStream( const std::string& compStream ) - { - try - { - POLE::Stream* pCompStream = NULL; - HRESULT res = S_OK; - - pCompStream = new POLE::Stream(oleStorage, compStream); - - if ( pCompStream ) - { - VirtualStreamReader reader( pCompStream, 0, false); - - //skip the CompObjHeader - reader.ReadBytes( 28, false ); - - int sz_obj = reader.GetSize() - reader.GetPosition(); - - if (sz_obj > 4) - { - //todooo сделать по нормальному CompObjHeader - psc3a.doc - //UserType = reader.ReadLengthPrefixedAnsiString(); - - //sz_obj = reader.GetSize() - reader.GetPosition(); - //if (sz_obj > 4) - // ClipboardFormat = reader.ReadLengthPrefixedAnsiString(); - - //sz_obj = reader.GetSize() - reader.GetPosition(); - //if (sz_obj > 4) - // Program = reader.ReadLengthPrefixedAnsiString(); - } - delete pCompStream; - } - } - catch (...) - { } } - void processOleStream( const std::string& oleStreamName ) - { - try - { - POLE::Stream* pOleStream; - HRESULT res = S_OK; + virtual ~OleObject() + { + } - pOleStream = new POLE::Stream(oleStorage, oleStreamName); - - if ( pOleStream ) - { - VirtualStreamReader reader( pOleStream, 0, false ); - - //skip version - reader.ReadBytes( 4, false ); - - //read the embedded/linked flag - int flag = reader.ReadInt32(); - this->fLinked = FormatUtils::BitmaskToBool( flag, 0x1 ); - - //Link update option - this->updateMode = (LinkUpdateOption)reader.ReadInt32(); - - switch ( this->updateMode ) - { - case NoLink: - { - this->UpdateMode = _T( "NoLink" ); - } - break; - - case Always: - { - this->UpdateMode = _T( "Always" ); - } - break; - - case OnCall: - { - this->UpdateMode = _T( "OnCall" ); - } - break; - } - delete pOleStream; - } - } - catch (...) - { - } - } - - std::wstring getOleEntryName( const CharacterPropertyExceptions* chpx ) - { - std::wstring ret; - - if ( chpx != NULL ) + private: + POLE::Storage *oleStorage; + + void processLinkInfoStream( const std::string& linkStream ) { - for ( std::list::const_iterator iter = chpx->grpprl->begin(); iter != chpx->grpprl->end(); iter++ ) - { - if ( iter->OpCode == sprmCPicLocation ) - { - ret = ( _T( "_" ) + FormatUtils::IntToWideString( FormatUtils::BytesToUInt32( iter->Arguments, 0, iter->argumentsSize ) ) ); - - break; - } - } + try + { + POLE::Stream* pLinkStream = NULL; + HRESULT res = S_OK; + + pLinkStream = //oleStorage->stream(linkStream); + new POLE::Stream(oleStorage, linkStream); + + if ( pLinkStream ) + { + VirtualStreamReader reader( pLinkStream, 0, false); + + //there are two versions of the Link string, one contains ANSI characters, the other contains + //unicode characters. + //Both strings seem not to be standardized: + //The length prefix is a character count EXCLUDING the terminating zero + + //Read the ANSI version + short cch = reader.ReadInt16(); + unsigned char* str = reader.ReadBytes( cch, true ); + FormatUtils::GetSTLCollectionFromBytes( &this->Link, str, cch, ENCODING_WINDOWS_1250 ); + RELEASEARRAYOBJECTS( str ); + + //skip the terminating zero of the ANSI string + //even if the characters are ANSI chars, the terminating zero has 2 bytes + reader.ReadBytes( 2, false ); + + //skip the next 4 bytes (flags?) + reader.ReadBytes( 4, false ); + + //Read the Unicode version + this->Link.clear(); + + cch = reader.ReadInt16(); + str = reader.ReadBytes( ( cch * 2 ), true ); + FormatUtils::GetSTLCollectionFromBytes( &this->Link, str, ( cch * 2 ), ENCODING_UTF16 ); + RELEASEARRAYOBJECTS( str ); + + //skip the terminating zero of the Unicode string + reader.ReadBytes( 2, false ); + + delete pLinkStream; + } + } + catch (...) + { + } + } + + void processEquationNativeStream( const std::string& eqStream ) + { + try + { + POLE::Stream* pCompStream = NULL; + HRESULT res = S_OK; + + pCompStream = new POLE::Stream(oleStorage, eqStream); + + if ( pCompStream ) + { + VirtualStreamReader reader( pCompStream, 0, false); + + int sz = reader.GetSize(); + + unsigned char *Buffer = reader.ReadBytes( sz, true ); + + if (Buffer && sz > 0) + { + isEquation = true; + delete []Buffer; + } + + delete pCompStream; + } + } + catch (...) + { + } } - return ret; - } + void processPICStream( const std::string& picStream ) + { + try + { + HRESULT res = S_OK; + + POLE::Stream* pPICStream = new POLE::Stream(oleStorage, picStream); + + if ( pPICStream ) + { + VirtualStreamReader reader( pPICStream, 0, false); + + int sz = reader.GetSize(); + + int cbHeader = reader.ReadUInt32(); + + reader.ReadBytes(4, false); + + int x = reader.ReadUInt32(); + int y = reader.ReadUInt32(); + pictureDesciptor.dyaGoal = reader.ReadUInt32(); + pictureDesciptor.dxaGoal = reader.ReadUInt32(); + + reader.ReadBytes(20, false); + + pictureDesciptor.mx = reader.ReadUInt32(); + pictureDesciptor.my = reader.ReadUInt32(); + + } + } + catch (...) + { + } + } + + void processCompObjStream( const std::string& compStream ) + { + try + { + HRESULT res = S_OK; + + POLE::Stream* pCompStream = new POLE::Stream(oleStorage, compStream); + + if ( pCompStream ) + { + VirtualStreamReader reader( pCompStream, 0, false); + + //skip the CompObjHeader + reader.ReadBytes( 28, false ); + + int sz_obj = reader.GetSize() - reader.GetPosition(); + + if (sz_obj > 4) + { + UserType = reader.ReadLengthPrefixedAnsiString(sz_obj); + + sz_obj = reader.GetSize() - reader.GetPosition(); + if (sz_obj > 4) + ClipboardFormat = reader.ReadLengthPrefixedAnsiString(sz_obj); + + sz_obj = reader.GetSize() - reader.GetPosition(); + if (sz_obj > 4) + Program = reader.ReadLengthPrefixedAnsiString(sz_obj); + } + delete pCompStream; + } + } + catch (...) + { + } + } + + void processOleStream( const std::string& oleStreamName ) + { + try + { + POLE::Stream* pOleStream; + HRESULT res = S_OK; + + pOleStream = new POLE::Stream(oleStorage, oleStreamName); + + if ( pOleStream ) + { + VirtualStreamReader reader( pOleStream, 0, false ); + + //skip version + reader.ReadBytes( 4, false ); + + //read the embedded/linked flag + int flag = reader.ReadInt32(); + bLinked = FormatUtils::BitmaskToBool( flag, 0x1 ); + + //Link update option + this->updateMode = (LinkUpdateOption)reader.ReadInt32(); + + switch ( this->updateMode ) + { + case NoLink: + { + this->UpdateMode = _T( "NoLink" ); + } + break; + + case Always: + { + this->UpdateMode = _T( "Always" ); + } + break; + + case OnCall: + { + this->UpdateMode = _T( "OnCall" ); + } + break; + } + delete pOleStream; + } + } + catch (...) + { + } + } + + std::wstring getOleEntryName( const CharacterPropertyExceptions* chpx ) + { + std::wstring ret; + + if ( chpx != NULL ) + { + for ( std::list::const_iterator iter = chpx->grpprl->begin(); iter != chpx->grpprl->end(); iter++ ) + { + if ( iter->OpCode == sprmCPicLocation || iter->OpCode == sprmOldCPicLocation) + { + ret = ( _T( "_" ) + FormatUtils::IntToWideString( FormatUtils::BytesToUInt32( iter->Arguments, 0, iter->argumentsSize ) ) ); + + break; + } + } + } + + return ret; + } }; } diff --git a/ASCOfficeDocFile/DocDocxConverter/OleObjectMapping.h b/ASCOfficeDocFile/DocDocxConverter/OleObjectMapping.h index ea9579fa9c..29120ff537 100644 --- a/ASCOfficeDocFile/DocDocxConverter/OleObjectMapping.h +++ b/ASCOfficeDocFile/DocDocxConverter/OleObjectMapping.h @@ -68,7 +68,7 @@ namespace DocFileFormat m_pXmlWriter->WriteNodeBegin( _T( "o:OLEObject" ), TRUE ); //type - if ( ole->fLinked ) + if ( ole->bLinked ) { int relID = -1; diff --git a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp index d9949bfd4e..e8e04a3dce 100644 --- a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp @@ -31,6 +31,7 @@ */ #include "PictureDescriptor.h" +#include "OfficeDrawing/MetafilePictBlip.h" #ifndef MM_ISOTROPIC #define MM_ISOTROPIC 7 @@ -52,13 +53,18 @@ namespace DocFileFormat //Get start and length of the PICT int fc = GetFcPic( chpx ); - if ( fc >= 0 ) { 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) + { + } PictureDescriptor::~PictureDescriptor() { Clear(); @@ -88,7 +94,7 @@ namespace DocFileFormat if (lcb > 10000000) 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); if ( bytes ) @@ -115,8 +121,14 @@ namespace DocFileFormat dxaGoal = mfp.xExt; dyaGoal = mfp.yExt; - embeddedDataSize = reader.GetSize() - reader.GetPosition(); //lcb ? + embeddedDataSize = lcb - 20;//reader.GetSize() - reader.GetPosition(); //lcb ? embeddedData = reader.ReadBytes( embeddedDataSize, true ); + + WmfPlaceableFileHeader *header = (WmfPlaceableFileHeader *)embeddedData; + + if (header) + { + } } else if (mfp.mm >= 98) { @@ -199,7 +211,7 @@ namespace DocFileFormat /// Returns -1 if the CHPX has no fcPic. int PictureDescriptor::GetFcPic(const CharacterPropertyExceptions* chpx) { - int ret = -1; + int ret = -1, ret1 = -1; for ( std::list::const_iterator iter = chpx->grpprl->begin(); iter != chpx->grpprl->end(); iter++ ) { @@ -210,6 +222,11 @@ namespace DocFileFormat ret = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize ); break; + case sprmOldCHps: + case sprmCHps: + ret1 = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize ); + break; + case sprmCHsp: ret = FormatUtils::BytesToInt32( iter->Arguments, 0, iter->argumentsSize ); break; diff --git a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h index 2228f6d82b..26c243380f 100644 --- a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h +++ b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h @@ -78,14 +78,17 @@ namespace DocFileFormat friend class VMLPictureMapping; friend class VMLShapeMapping; friend class NumberingMapping; + friend class OleObject; public: // 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(); + + void parse( POLE::Stream* stream, int fc, int sz, bool oldVersion); private: - void parse( POLE::Stream* stream, int fc, int sz, bool oldVersion); // Returns the fcPic into the "data" stream, where the PIC begins. // Returns -1 if the CHPX has no fcPic. @@ -127,6 +130,6 @@ namespace DocFileFormat BlipStoreEntry * blipStoreEntry; unsigned char *embeddedData; - short embeddedDataSize; + int embeddedDataSize; }; } diff --git a/ASCOfficeDocFile/DocDocxConverter/Plex.h b/ASCOfficeDocFile/DocDocxConverter/Plex.h index 594165a91d..3a35df1d60 100644 --- a/ASCOfficeDocFile/DocDocxConverter/Plex.h +++ b/ASCOfficeDocFile/DocDocxConverter/Plex.h @@ -44,9 +44,9 @@ namespace DocFileFormat protected: static const int CP_LENGTH = 4; - std::vector CharacterPositions; + std::vector CharacterPositions; std::vector Elements; - bool m_bIsValid; + bool m_bIsValid; public: Plex(int structureLength, POLE::Stream* stream, unsigned int fc, unsigned int lcb, bool oldVersion) diff --git a/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp b/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp index e39e5912f7..c29490882f 100644 --- a/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp @@ -66,7 +66,6 @@ namespace DocFileFormat while ( goOn ) { - //enough bytes to read? if ( ( sprmStart + opCodeSize ) < size ) { OperationCode opCode = oldVersion ? (OperationCode)FormatUtils::BytesToUChar ( bytes, sprmStart, size ) : diff --git a/ASCOfficeDocFile/DocDocxConverter/SectionPropertiesMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/SectionPropertiesMapping.cpp index 570ea396fb..769f5e9e1e 100644 --- a/ASCOfficeDocFile/DocDocxConverter/SectionPropertiesMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/SectionPropertiesMapping.cpp @@ -105,17 +105,28 @@ namespace DocFileFormat if (pTable) { + unsigned char fHF = 255; //all headers & footers + for (std::list::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 - 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")); - WriteSectionStory (pTable->GetFirstHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"first")); + if (FormatUtils::GetBitFromInt(fHF, 0)) WriteSectionStory (pTable->GetEvenHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"even")); + if (FormatUtils::GetBitFromInt(fHF, 1)) WriteSectionStory (pTable->GetOddHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"default")); + if (FormatUtils::GetBitFromInt(fHF, 4)) WriteSectionStory (pTable->GetFirstHeaders (m_nSelectProperties), std::wstring(L"headerReference"), std::wstring(L"first")); // Footer - 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")); - WriteSectionStory (pTable->GetFirstFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"first")); + if (FormatUtils::GetBitFromInt(fHF, 2)) WriteSectionStory (pTable->GetEvenFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"even")); + if (FormatUtils::GetBitFromInt(fHF, 3)) WriteSectionStory (pTable->GetOddFooters (m_nSelectProperties), std::wstring(L"footerReference"), std::wstring(L"default")); + 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) diff --git a/ASCOfficeDocFile/DocDocxConverter/Spa.h b/ASCOfficeDocFile/DocDocxConverter/Spa.h index 95c0d63c50..b6123f67c9 100644 --- a/ASCOfficeDocFile/DocDocxConverter/Spa.h +++ b/ASCOfficeDocFile/DocDocxConverter/Spa.h @@ -47,7 +47,13 @@ namespace DocFileFormat { public: friend class VMLShapeMapping; - static const int STRUCTURE_SIZE = 26; + static const int STRUCTURE_SIZE = 26; + static const int STRUCTURE_SIZE_OLD = 6; + + static const int GetSize(bool bOldVersion) + { + return bOldVersion ? STRUCTURE_SIZE_OLD : STRUCTURE_SIZE; + } Spa() { diff --git a/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp index f1654358c2..7a49681687 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp @@ -31,6 +31,7 @@ */ #include "VMLPictureMapping.h" +#include "OleObject.h" #include "OfficeDrawing/GeometryBooleanProperties.h" #include "OfficeDrawing/GeometryTextBooleanProperties.h" @@ -39,6 +40,28 @@ #include "../../Common/DocxFormat/Source/DocxFormat/Document.h" #include "../../Common/DocxFormat/Source/DocxFormat/Document.h" +typedef struct +{ + DWORD iType; // Record type EMR_HEADER + DWORD nSize; // Record size in bytes. This may be greater + // than the sizeof(ENHMETAHEADER). + RECT rclBounds; // Inclusive-inclusive bounds in device units + RECT rclFrame; // Inclusive-inclusive Picture Frame .01mm unit + DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE. + DWORD nVersion; // Version number + DWORD nBytes; // Size of the metafile in bytes + DWORD nRecords; // Number of records in the metafile + WORD nHandles; // Number of handles in the handle table + // Handle index zero is reserved. + WORD sReserved; // Reserved. Must be zero. + DWORD nDescription; // Number of chars in the unicode desc string + // This is 0 if there is no description string + DWORD offDescription; // Offset to the metafile description record. + // This is 0 if there is no description string + DWORD nPalEntries; // Number of entries in the metafile palette. + SIZE szlDevice; // Size of the reference device in pels + SIZE szlMillimeters; // Size of the reference device in millimeters +} ENHMETAHEADER3; namespace DocFileFormat { @@ -131,7 +154,41 @@ namespace DocFileFormat void VMLPictureMapping::Apply( IVisitable* visited ) { - PictureDescriptor* pict = static_cast(visited); + PictureDescriptor* pict = dynamic_cast(visited); + if (pict) ApplyPict(pict); + + OleObject* obj = dynamic_cast(visited); + if (obj) ApplyObj(obj); + } + + void VMLPictureMapping::ApplyObj( OleObject* obj ) + { + if (!obj) return; + + std::wstring widthString = FormatUtils::DoubleToWideString( 100 ); + std::wstring heightString = FormatUtils::DoubleToWideString( 100 ); + + m_pXmlWriter->WriteNodeBegin( _T( "v:shape" ), true ); + + PictureFrameType type; + m_pXmlWriter->WriteAttribute( _T( "type" ), std::wstring( _T( "#" ) + VMLShapeTypeMapping::GenerateTypeId(&type)).c_str()); + + std::wstring style = std::wstring( _T( "width:" ) ) + widthString + std::wstring( _T( "pt;" ) ) + std::wstring( _T( "height:" ) ) + heightString + std::wstring( _T( "pt;" ) ); + + m_pXmlWriter->WriteAttribute( _T( "style" ), style.c_str() ); + + m_pXmlWriter->WriteAttribute( _T( "id" ), m_ShapeId.c_str() ); + + if (m_isOlePreview) + { + m_pXmlWriter->WriteAttribute( _T( "o:ole" ), _T( "" ) ); + } + m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); + m_pXmlWriter->WriteNodeEnd( _T( "v:shape" ) ); + } + + void VMLPictureMapping::ApplyPict( PictureDescriptor* pict ) + { if (!pict) return; double xScaling = pict->mx / 1000.0; @@ -277,7 +334,6 @@ namespace DocFileFormat writePictureBorder( _T( "borderbottom" ), pict->brcBottom ); writePictureBorder( _T( "borderright" ), pict->brcRight ); - //close v:shape m_pXmlWriter->WriteNodeEnd( _T( "v:shape" ) ); } @@ -308,6 +364,45 @@ namespace DocFileFormat if (pict->embeddedData && pict->embeddedDataSize > 0) { + ENHMETAHEADER3 oHeader; + + int w = 0, h = 0; + + oHeader.iType = 0x00000001; + oHeader.nSize = sizeof(oHeader); + + oHeader.rclBounds.left = 0; + oHeader.rclBounds.top = 0; + oHeader.rclBounds.right = w; + oHeader.rclBounds.bottom = h; + + oHeader.rclFrame.left = 0; + oHeader.rclFrame.top = 0; + oHeader.rclFrame.right = w; + oHeader.rclFrame.bottom = h; + + oHeader.dSignature = 0x464D4520; + oHeader.nVersion = 0x00010000; + oHeader.nBytes = pict->embeddedDataSize - 176; + + oHeader.nRecords = 1; + oHeader.nHandles = 0; + + oHeader.sReserved = 0; + + oHeader.nDescription = 0; + oHeader.offDescription = 0; + + oHeader.nPalEntries = 0; + + oHeader.szlDevice.cx = 200; + oHeader.szlDevice.cy = 200; + + oHeader.szlMillimeters.cx = 100; + oHeader.szlMillimeters.cy = 100; + + memcpy(pict->embeddedData, &oHeader, sizeof(oHeader)); + m_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(Global::msoblipWMF), std::vector(pict->embeddedData, pict->embeddedData + pict->embeddedDataSize))); m_nImageId = m_ctx->_docx->RegisterImage(m_caller, Global::msoblipWMF); result = true; diff --git a/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.h b/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.h index 84e81f85ff..6f116c9b43 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.h +++ b/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.h @@ -44,6 +44,8 @@ namespace DocFileFormat { + class OleObject; + bool ParseEmbeddedEquation( const std::string & xmlString, std::wstring & newXmlString ); class VMLPictureMapping: public PropertiesMapping, public IMapping @@ -58,6 +60,9 @@ namespace DocFileFormat /// Writes a border element void writePictureBorder (const std::wstring & name, const BorderCode* brc); void appendStyleProperty( std::wstring* b, const std::wstring& propName, const std::wstring& propValue ) const; + + void ApplyPict ( PictureDescriptor* p ); + void ApplyObj ( OleObject* o ); protected: /// Copies the picture from the binary stream to the zip archive diff --git a/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp index 9d075f5deb..49f8a65da2 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp @@ -288,7 +288,7 @@ namespace DocFileFormat stroked = false; } - if (!(booleans.fUsefFillOK && booleans.fFillOK)) + if (booleans.fUsefFillOK && !booleans.fFillOK) { filled = false; } diff --git a/ASCOfficeDocFile/DocDocxConverter/VirtualStreamReader.h b/ASCOfficeDocFile/DocDocxConverter/VirtualStreamReader.h index e0834805bc..9d75bd410e 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VirtualStreamReader.h +++ b/ASCOfficeDocFile/DocDocxConverter/VirtualStreamReader.h @@ -187,28 +187,35 @@ public: std::wstring ReadXst() { - std::wstring wstrResult( _T( "" ) ); - if (stream) + if (!stream) return L""; + std::wstring wstrResult; + + unsigned char* xstz = NULL; + unsigned char* cch = NULL; + if (olderVersion) + { + int cchSize = 1; + cch = ReadBytes( cchSize, true ); + + int xstzSize = FormatUtils::BytesToUChar( cch, 0, cchSize ) * 1; + xstz = ReadBytes(xstzSize, true); + + FormatUtils::GetSTLCollectionFromBytes( &wstrResult, xstz, xstzSize, ENCODING_WINDOWS_1250 ); + } + else { int cchSize = 2; - unsigned char* cch = this->ReadBytes( cchSize, true ); + cch = ReadBytes( cchSize, true ); int xstzSize = FormatUtils::BytesToInt16( cch, 0, cchSize ) * 2; - unsigned char* xstz = ReadBytes(xstzSize, true); + xstz = ReadBytes(xstzSize, true); - if (this->olderVersion) - { - FormatUtils::GetSTLCollectionFromBytes( &wstrResult, xstz, xstzSize, ENCODING_WINDOWS_1250 ); - } - else - { - FormatUtils::GetSTLCollectionFromBytes( &wstrResult, xstz, xstzSize, ENCODING_UTF16 ); - } - - RELEASEARRAYOBJECTS(xstz); - RELEASEARRAYOBJECTS(cch); + FormatUtils::GetSTLCollectionFromBytes( &wstrResult, xstz, xstzSize, ENCODING_UTF16 ); } + RELEASEARRAYOBJECTS(xstz); + RELEASEARRAYOBJECTS(cch); + return wstrResult; } @@ -239,21 +246,42 @@ public: /// The string must have the following structure: /// unsigned char 1-4: Character count (cch) /// unsigned char 5-cch+4: ANSI characters terminated by \0 - std::wstring ReadLengthPrefixedAnsiString() + std::wstring ReadLengthPrefixedAnsiString(int max_size) { std::wstring result; - int cch = this->ReadInt32(); + unsigned int cch = ReadUInt32(); - if ( cch > 0 ) + unsigned char* stringBytes = NULL; + + if (cch > max_size) { - //dont read the terminating zero - unsigned char* stringBytes = ReadBytes( cch, true ); + //error ... skip to 0 + int pos_orinal = GetPosition(); + int pos = 0; + + stringBytes = ReadBytes( max_size, true ); - FormatUtils::GetSTLCollectionFromBytes( &result, stringBytes, ( cch - 1 ), ENCODING_WINDOWS_1250); + if (stringBytes) + { + while(pos < max_size) + { + if (stringBytes[pos] == 0) + break; + pos++; + } + } + Seek(pos_orinal + pos - 1, 0); + }else + if ( cch > 0 ) + { + //dont read the terminating zero + stringBytes = ReadBytes( cch, true ); - RELEASEARRAYOBJECTS( stringBytes ); - } + FormatUtils::GetSTLCollectionFromBytes( &result, stringBytes, ( cch - 1 ), ENCODING_WINDOWS_1250); + + } + RELEASEARRAYOBJECTS( stringBytes ); return result; } diff --git a/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp b/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp index 116dd2be5e..b60763af30 100644 --- a/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp @@ -179,7 +179,7 @@ namespace DocFileFormat if (document_code_page2 > 0) document_code_page = document_code_page2; } - if (!FIB->m_bOlderVersion) + if (!bOlderVersion) document_code_page = ENCODING_UTF16; FIB->m_CodePage = document_code_page; @@ -193,16 +193,16 @@ namespace DocFileFormat DataStream = NULL; } - if (TableStream->size() < 1 && FIB->m_bOlderVersion) + if (TableStream->size() < 1 && bOlderVersion) { RELEASEOBJECT(TableStream); m_pStorage->GetStream ("WordDocument", &TableStream); } - RevisionAuthorTable = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfRMark, FIB->m_FibWord97.lcbSttbfRMark, FIB->m_bOlderVersion); - FontTable = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfFfn, FIB->m_FibWord97.lcbSttbfFfn, FIB->m_bOlderVersion); - BookmarkNames = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfBkmk, FIB->m_FibWord97.lcbSttbfBkmk, FIB->m_bOlderVersion); - AutoTextNames = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfGlsy, FIB->m_FibWord97.lcbSttbfGlsy, FIB->m_bOlderVersion); + RevisionAuthorTable = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfRMark, FIB->m_FibWord97.lcbSttbfRMark, bOlderVersion); + FontTable = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfFfn, FIB->m_FibWord97.lcbSttbfFfn, bOlderVersion); + BookmarkNames = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfBkmk, FIB->m_FibWord97.lcbSttbfBkmk, bOlderVersion); + AutoTextNames = new StringTable (TableStream, FIB->m_FibWord97.fcSttbfGlsy, FIB->m_FibWord97.lcbSttbfGlsy, bOlderVersion); if (m_pCallFunc) { @@ -221,34 +221,35 @@ namespace DocFileFormat // Read all needed PLCFs if (FIB->m_RgLw97.ccpFtn > 0) { - IndividualFootnotesPlex = new Plex(EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcffndTxt, FIB->m_FibWord97.lcbPlcffndTxt, FIB->m_bOlderVersion); - FootnoteReferenceCharactersPlex = new Plex(FootnoteDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcffndRef, FIB->m_FibWord97.lcbPlcffndRef, FIB->m_bOlderVersion); + IndividualFootnotesPlex = new Plex(EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcffndTxt, FIB->m_FibWord97.lcbPlcffndTxt, bOlderVersion); + FootnoteReferenceCharactersPlex = new Plex(FootnoteDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcffndRef, FIB->m_FibWord97.lcbPlcffndRef, bOlderVersion); } if (FIB->m_RgLw97.ccpEdn > 0) { - IndividualEndnotesPlex = new Plex(EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfendTxt, FIB->m_FibWord97.lcbPlcfendTxt, FIB->m_bOlderVersion); - EndnoteReferenceCharactersPlex = new Plex(EndnoteDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfendRef, FIB->m_FibWord97.lcbPlcfendRef, FIB->m_bOlderVersion); + IndividualEndnotesPlex = new Plex(EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfendTxt, FIB->m_FibWord97.lcbPlcfendTxt, bOlderVersion); + EndnoteReferenceCharactersPlex = new Plex(EndnoteDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfendRef, FIB->m_FibWord97.lcbPlcfendRef, bOlderVersion); } if (FIB->m_RgLw97.ccpHdr > 0) { - HeaderStoriesPlex = new Plex( EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfHdd, FIB->m_FibWord97.lcbPlcfHdd, FIB->m_bOlderVersion); + HeaderStoriesPlex = new Plex( EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfHdd, FIB->m_FibWord97.lcbPlcfHdd, bOlderVersion); } if (FIB->m_RgLw97.ccpAtn > 0) { - IndividualCommentsPlex = new Plex(EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfandTxt, FIB->m_FibWord97.lcbPlcfandTxt, FIB->m_bOlderVersion); - AnnotationsReferencePlex = new Plex(AnnotationReferenceDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfandRef, FIB->m_FibWord97.lcbPlcfandRef, FIB->m_bOlderVersion); + IndividualCommentsPlex = new Plex(EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfandTxt, FIB->m_FibWord97.lcbPlcfandTxt, bOlderVersion); + AnnotationsReferencePlex = new Plex(AnnotationReferenceDescriptor::GetSize(bOlderVersion), TableStream, FIB->m_FibWord97.fcPlcfandRef, FIB->m_FibWord97.lcbPlcfandRef, bOlderVersion); } - OfficeDrawingPlex = new Plex (Spa::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcSpaMom, FIB->m_FibWord97.lcbPlcSpaMom, FIB->m_bOlderVersion); - OfficeDrawingPlexHeader = new Plex (Spa::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcSpaHdr, FIB->m_FibWord97.lcbPlcSpaHdr, FIB->m_bOlderVersion); - SectionPlex = new Plex (SectionDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfSed, FIB->m_FibWord97.lcbPlcfSed, FIB->m_bOlderVersion); - BookmarkStartPlex = new Plex (BookmarkFirst::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfBkf, FIB->m_FibWord97.lcbPlcfBkf, FIB->m_bOlderVersion); - BookmarkEndPlex = new Plex (EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfBkl, FIB->m_FibWord97.lcbPlcfBkl, FIB->m_bOlderVersion); + OfficeDrawingPlex = new Plex (Spa::GetSize(bOlderVersion), TableStream, FIB->m_FibWord97.fcPlcSpaMom, FIB->m_FibWord97.lcbPlcSpaMom, bOlderVersion); + OfficeDrawingPlexHeader = new Plex (Spa::GetSize(bOlderVersion), TableStream, FIB->m_FibWord97.fcPlcSpaHdr, FIB->m_FibWord97.lcbPlcSpaHdr, bOlderVersion); + + SectionPlex = new Plex (SectionDescriptor::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfSed, FIB->m_FibWord97.lcbPlcfSed, bOlderVersion); + BookmarkStartPlex = new Plex (BookmarkFirst::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfBkf, FIB->m_FibWord97.lcbPlcfBkf, bOlderVersion); + BookmarkEndPlex = new Plex (EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfBkl, FIB->m_FibWord97.lcbPlcfBkl, bOlderVersion); - TextboxBreakPlex = new Plex (Tbkd::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfTxbxBkd, FIB->m_FibWord97.lcbPlcfTxbxBkd, FIB->m_bOlderVersion); - TextboxBreakPlexHeader = new Plex (Tbkd::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfTxbxHdrBkd, FIB->m_FibWord97.lcbPlcfTxbxHdrBkd, FIB->m_bOlderVersion); + TextboxBreakPlex = new Plex (Tbkd::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfTxbxBkd, FIB->m_FibWord97.lcbPlcfTxbxBkd, bOlderVersion); + TextboxBreakPlexHeader = new Plex (Tbkd::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfTxbxHdrBkd, FIB->m_FibWord97.lcbPlcfTxbxHdrBkd, bOlderVersion); for (size_t i = 0; i < BookmarkStartPlex->Elements.size(); ++i) { @@ -259,11 +260,11 @@ namespace DocFileFormat } } - AutoTextPlex = new Plex (EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfGlsy, FIB->m_FibWord97.lcbPlcfGlsy, FIB->m_bOlderVersion); - FieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldMom, FIB->m_FibWord97.lcbPlcfFldMom, FIB->m_bOlderVersion); - FootnoteDocumentFieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldFtn, FIB->m_FibWord97.lcbPlcfFldFtn, FIB->m_bOlderVersion); - EndnoteDocumentFieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldEdn, FIB->m_FibWord97.lcbPlcfFldEdn, FIB->m_bOlderVersion); - HeadersAndFootersDocumentFieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldHdr, FIB->m_FibWord97.lcbPlcfFldHdr, FIB->m_bOlderVersion); + AutoTextPlex = new Plex (EmptyStructure::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfGlsy, FIB->m_FibWord97.lcbPlcfGlsy, bOlderVersion); + FieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldMom, FIB->m_FibWord97.lcbPlcfFldMom, bOlderVersion); + FootnoteDocumentFieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldFtn, FIB->m_FibWord97.lcbPlcfFldFtn, bOlderVersion); + EndnoteDocumentFieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldEdn, FIB->m_FibWord97.lcbPlcfFldEdn, bOlderVersion); + HeadersAndFootersDocumentFieldsPlex = new Plex (FieldCharacter::STRUCTURE_SIZE, TableStream, FIB->m_FibWord97.fcPlcfFldHdr, FIB->m_FibWord97.lcbPlcfFldHdr, bOlderVersion); if (m_pCallFunc) { @@ -392,13 +393,13 @@ namespace DocFileFormat int cp = SectionPlex->CharacterPositions[i + 1]; //Get the SEPX - VirtualStreamReader wordReader( this->WordDocumentStream, sed->fcSepx, FIB->m_bOlderVersion); + VirtualStreamReader wordReader( this->WordDocumentStream, sed->fcSepx, bOlderVersion); //!!!TODO: cbSepx is the size in bytes of the rest properties part!!! short cbSepx = wordReader.ReadInt16(); unsigned char* bytes = wordReader.ReadBytes( ( cbSepx /*- 2*/ ), true ); - AllSepx->insert( std::pair( cp, new SectionPropertyExceptions( bytes, ( cbSepx /*- 2*/ ), FIB->m_bOlderVersion ) ) ); + AllSepx->insert( std::pair( cp, new SectionPropertyExceptions( bytes, ( cbSepx /*- 2*/ ), bOlderVersion ) ) ); RELEASEARRAYOBJECTS( bytes ); }