From 46130bcad501e88bae89a371f3cdf87cfe10f93a Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 12 Jul 2016 19:42:50 +0300 Subject: [PATCH] DocFormat(before 1997) - fix pictures --- ASCOfficeDocFile/Common/SPRMCodes.h | 1 + .../CharacterPropertiesMapping.cpp | 4 + .../DocDocxConverter/ContentTypes.h | 1 + .../DocDocxConverter/DocumentMapping.cpp | 2 +- .../DocDocxConverter/DrawingPrimitives.cpp | 29 +- .../DocDocxConverter/DrawingPrimitives.h | 39 ++- .../OfficeDrawing/MetafilePictBlip.h | 6 + .../DocDocxConverter/PictureDescriptor.cpp | 186 +++++----- .../DocDocxConverter/PictureDescriptor.h | 1 + .../DocDocxConverter/PropertyExceptions.cpp | 7 +- .../SinglePropertyModifier.cpp | 13 +- .../DocDocxConverter/TextboxMapping.cpp | 3 +- .../DocDocxConverter/VMLPictureMapping.cpp | 161 +++++---- .../DocDocxConverter/VMLShapeMapping.cpp | 330 +++++++++--------- .../DocDocxConverter/VMLShapeMapping.h | 13 +- .../DocDocxConverter/WordDocument.cpp | 1 + .../WordprocessingDocument.cpp | 135 +++++-- .../source/XlsXlsxConverter/XlsConverter.cpp | 2 +- 18 files changed, 545 insertions(+), 389 deletions(-) diff --git a/ASCOfficeDocFile/Common/SPRMCodes.h b/ASCOfficeDocFile/Common/SPRMCodes.h index 1965806e83..5af1a9bcb4 100644 --- a/ASCOfficeDocFile/Common/SPRMCodes.h +++ b/ASCOfficeDocFile/Common/SPRMCodes.h @@ -98,6 +98,7 @@ namespace DocFileFormat sprmOldCChse = 73, sprmOldCSymbol = 74, sprmOldCFOle2 = 75, + sprmCOldHighlight = 77, sprmOldCIstd = 80, sprmOldCIstdPermute = 81, sprmOldCDefault = 82, diff --git a/ASCOfficeDocFile/DocDocxConverter/CharacterPropertiesMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/CharacterPropertiesMapping.cpp index 85e802e88e..873df56dac 100644 --- a/ASCOfficeDocFile/DocDocxConverter/CharacterPropertiesMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/CharacterPropertiesMapping.cpp @@ -301,6 +301,10 @@ namespace DocFileFormat colorVal->SetValue( rgbColor.GetString() ); }break; + case sprmCOldHighlight: + { + appendValueElement( parent, _T( "highlight" ), FormatUtils::MapValueToWideString( iter->Arguments[1], &Global::ColorIdentifier[0][0], 17, 12 ).c_str(), true ); + }break; case sprmCHighlight: { appendValueElement( parent, _T( "highlight" ), FormatUtils::MapValueToWideString( iter->Arguments[0], &Global::ColorIdentifier[0][0], 17, 12 ).c_str(), true ); diff --git a/ASCOfficeDocFile/DocDocxConverter/ContentTypes.h b/ASCOfficeDocFile/DocDocxConverter/ContentTypes.h index 386a33b20f..4479b14d77 100644 --- a/ASCOfficeDocFile/DocDocxConverter/ContentTypes.h +++ b/ASCOfficeDocFile/DocDocxConverter/ContentTypes.h @@ -70,6 +70,7 @@ namespace OpenXmlContentTypes static const TCHAR* Png = _T("image/png"); static const TCHAR* Tiff = _T("image/tiff"); static const TCHAR* Wmf = _T("image/x-wmf"); + static const TCHAR* Bmp = _T("image/bmp"); } namespace WordprocessingMLContentTypes diff --git a/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp index b3505903a9..29bc96b835 100755 --- a/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp @@ -268,7 +268,7 @@ namespace DocFileFormat std::vector bookmarks = searchBookmarks(chpxChars, cp); //if there are bookmarks in this run, split the run into several runs - if (bookmarks.size()) + if (!bookmarks.empty()) { std::list>* runs = splitCharList(chpxChars, &bookmarks); if (runs) diff --git a/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.cpp b/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.cpp index 429637f974..d41095fed7 100644 --- a/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.cpp @@ -103,8 +103,8 @@ namespace DocFileFormat void DrawingPrimitive::read_fill(VirtualStreamReader* reader) { - fillFore = read_color(reader); fillBack = read_color(reader); + fillFore = read_color(reader); fillPattern = reader->ReadInt16(); } void DrawingPrimitive::read_shadow(VirtualStreamReader* reader) @@ -225,13 +225,34 @@ namespace DocFileFormat } DrawingPrimitiveTextBox::DrawingPrimitiveTextBox(VirtualStreamReader *reader, int length) : DrawingPrimitiveRect(reader, length) { - strVmlType = L"v:rect"; - //strVmlType = L"v:shape"; } DrawingPrimitiveCTextBox::DrawingPrimitiveCTextBox(VirtualStreamReader *reader, int length) : DrawingPrimitive(reader, length) { - strVmlType = L"v:shape"; + 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() + { } DrawingPrimitivePolyline::DrawingPrimitivePolyline(VirtualStreamReader *reader, int length) : DrawingPrimitiveLine(reader, length, false) diff --git a/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.h b/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.h index e180a039fb..a58a269c49 100644 --- a/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.h +++ b/ASCOfficeDocFile/DocDocxConverter/DrawingPrimitives.h @@ -121,21 +121,6 @@ namespace DocFileFormat }; - class DrawingPrimitiveCTextBox: public DrawingPrimitive - { - public: - DrawingPrimitiveCTextBox(VirtualStreamReader* reader, int length); - - }; - - class DrawingPrimitiveArc: public DrawingPrimitive - { - public: - DrawingPrimitiveArc(VirtualStreamReader* reader, int length); - - bool fLeft; - bool fUp; - }; class DrawingPrimitiveElipse: public DrawingPrimitive { public: @@ -153,6 +138,30 @@ namespace DocFileFormat std::vector> 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 { diff --git a/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h b/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h index bc16657599..f17e4d7943 100644 --- a/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h +++ b/ASCOfficeDocFile/DocDocxConverter/OfficeDrawing/MetafilePictBlip.h @@ -70,6 +70,12 @@ public: public: CMetaHeader() { + cbSize = cbSave = 0; + filter = compression = 0; + ptSize.x = ptSize.y = 0; + + rcBounds.bottom = rcBounds.left = rcBounds.right = rcBounds.top = 0; + } diff --git a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp index e8e04a3dce..c7ce0da4f9 100644 --- a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.cpp @@ -48,7 +48,7 @@ namespace DocFileFormat : 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) + cProps(0), shapeContainer(NULL), blipStoreEntry(NULL), embeddedData(NULL), embeddedDataSize(0), embeddedDataHeader(NULL) { //Get start and length of the PICT int fc = GetFcPic( chpx ); @@ -62,7 +62,7 @@ namespace DocFileFormat : 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) + cProps(0), shapeContainer(NULL), blipStoreEntry(NULL), embeddedData(NULL), embeddedDataSize(0), embeddedDataHeader(NULL) { } PictureDescriptor::~PictureDescriptor() @@ -80,6 +80,7 @@ namespace DocFileFormat RELEASEOBJECT(blipStoreEntry); RELEASEARRAYOBJECTS(embeddedData); + RELEASEARRAYOBJECTS(embeddedDataHeader); } void PictureDescriptor::parse(POLE::Stream* stream, int fc, int sz, bool oldVersion) { @@ -91,6 +92,8 @@ namespace DocFileFormat int lcb = reader.ReadInt32(); + int pos_start = reader.GetPosition(); + if (lcb > 10000000) return; @@ -104,104 +107,111 @@ namespace DocFileFormat return; } - if (lcb >= 10) + if (lcb < 10) + return; + + int cbHeader = reader.ReadUInt16(); + + mfp.mm = reader.ReadInt16(); + mfp.xExt = reader.ReadInt16(); + mfp.yExt = reader.ReadInt16(); + mfp.hMf = reader.ReadInt16(); + + unsigned char* bytes = reader.ReadBytes(14, true); + rcWinMf = std::vector(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(); + + int brcl = reader.ReadInt16(); + + // borders + int bytesCount = oldVersion ? 2 : 4; + + bytes = reader.ReadBytes( bytesCount, true ); + brcTop = new BorderCode( bytes, bytesCount ); + RELEASEARRAYOBJECTS( bytes ); + + bytes = reader.ReadBytes( bytesCount, true ); + brcLeft = new BorderCode( bytes, bytesCount ); + RELEASEARRAYOBJECTS( bytes ); + + bytes = reader.ReadBytes( bytesCount, true ); + brcBottom = new BorderCode( bytes, bytesCount ); + RELEASEARRAYOBJECTS( bytes ); + + bytes = reader.ReadBytes( bytesCount, true ); + brcRight = new BorderCode( bytes, bytesCount ); + RELEASEARRAYOBJECTS( bytes ); + + dxaOrigin = reader.ReadInt16(); + dyaOrigin = reader.ReadInt16(); + + int pos_end = reader.GetPosition(); + if (oldVersion) { - int cbHeader = reader.ReadUInt16(); + int flag = brcl; - mfp.mm = reader.ReadInt16(); - mfp.xExt = reader.ReadInt16(); - mfp.yExt = reader.ReadInt16(); - mfp.hMf = reader.ReadInt16(); + brcl = FormatUtils::BitmaskToBool(flag, 0x000F); + //( 0 single 1 thick 2 double 3 shadow ) - if (mfp.mm == MM_ISOTROPIC || mfp.mm == MM_ANISOTROPIC) + 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) + + int sz_hdr = pos_end - pos_start; + + int header_size = 114; + + 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) { - Type = wmf; + unsigned char cchPicName = reader.ReadByte(); + unsigned char* stPicName = reader.ReadBytes(cchPicName, true); - mx = my = 200; - dxaGoal = mfp.xExt; - dyaGoal = mfp.yExt; - - embeddedDataSize = lcb - 20;//reader.GetSize() - reader.GetPosition(); //lcb ? - embeddedData = reader.ReadBytes( embeddedDataSize, true ); - - WmfPlaceableFileHeader *header = (WmfPlaceableFileHeader *)embeddedData; - - if (header) + if ( stPicName != NULL ) { + std::wstring picName; + FormatUtils::GetSTLCollectionFromBytes( &picName, stPicName, cchPicName, ENCODING_WINDOWS_1250 ); + RELEASEARRAYOBJECTS(stPicName); } - } - else if (mfp.mm >= 98) + } + + shapeContainer = dynamic_cast(RecordFactory::ReadRecord(&reader, 0)); + + long pos = reader.GetPosition(); + + if( pos < ( fc + lcb )) { - unsigned char* bytes = reader.ReadBytes(14, true); - rcWinMf = std::vector(bytes, (bytes + 14)); - RELEASEARRAYOBJECTS(bytes); + Record* rec = RecordFactory::ReadRecord( &reader, 0 ); - //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 ); - brcLeft = new BorderCode( bytes, 4 ); - RELEASEARRAYOBJECTS( bytes ); - - bytes = reader.ReadBytes( bytesCount, true ); - brcBottom = new BorderCode( bytes, 4 ); - RELEASEARRAYOBJECTS( bytes ); - - bytes = reader.ReadBytes( bytesCount, true ); - brcRight = new BorderCode( bytes, 4 ); - RELEASEARRAYOBJECTS( bytes ); - - dxaOrigin = reader.ReadInt16(); - dyaOrigin = reader.ReadInt16(); - cProps = reader.ReadInt16(); - - if (mfp.mm == MM_SHAPEFILE) + if ((rec) && ( typeid(*rec) == typeid(BlipStoreEntry) )) { - unsigned char cchPicName = reader.ReadByte(); - unsigned char* stPicName = reader.ReadBytes(cchPicName, true); - - if ( stPicName != NULL ) - { - std::wstring picName; - FormatUtils::GetSTLCollectionFromBytes( &picName, stPicName, cchPicName, ENCODING_WINDOWS_1250 ); - RELEASEARRAYOBJECTS(stPicName); - } + blipStoreEntry = dynamic_cast( rec ); } - - shapeContainer = dynamic_cast(RecordFactory::ReadRecord(&reader, 0)); - - long pos = reader.GetPosition(); - - if( pos < ( fc + lcb )) + else { - Record* rec = RecordFactory::ReadRecord( &reader, 0 ); - - if ((rec) && ( typeid(*rec) == typeid(BlipStoreEntry) )) - { - blipStoreEntry = dynamic_cast( rec ); - } - else - { - RELEASEOBJECT(rec); - } + RELEASEOBJECT(rec); } } } diff --git a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h index 26c243380f..7ae7025ded 100644 --- a/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h +++ b/ASCOfficeDocFile/DocDocxConverter/PictureDescriptor.h @@ -129,6 +129,7 @@ namespace DocFileFormat ShapeContainer * shapeContainer; BlipStoreEntry * blipStoreEntry; + unsigned char *embeddedDataHeader; unsigned char *embeddedData; int embeddedDataSize; }; diff --git a/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp b/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp index 36b3244732..ff1d83ee2a 100644 --- a/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/PropertyExceptions.cpp @@ -71,6 +71,11 @@ namespace DocFileFormat unsigned short code = oldVersion ? FormatUtils::BytesToUChar ( bytes, sprmStart, size ) : FormatUtils::BytesToUInt16 ( bytes, sprmStart, size ) ; + if (oldVersion && code == 0) + { + sprmStart++; + continue; + } OperationCode opCode = (OperationCode)code; short opSize = -1; @@ -137,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 int sprmBytesSize = opCodeSize + lenByte + opSize; unsigned char* sprmBytes = NULL; @@ -148,7 +152,6 @@ namespace DocFileFormat { memcpy( sprmBytes, ( bytes + sprmStart ), sprmBytesSize ); - //parse SinglePropertyModifier sprm( sprmBytes, sprmBytesSize, oldVersion ); grpprl->push_back( sprm ); diff --git a/ASCOfficeDocFile/DocDocxConverter/SinglePropertyModifier.cpp b/ASCOfficeDocFile/DocDocxConverter/SinglePropertyModifier.cpp index 915b1b0bf9..8110b6127a 100644 --- a/ASCOfficeDocFile/DocDocxConverter/SinglePropertyModifier.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/SinglePropertyModifier.cpp @@ -51,7 +51,14 @@ namespace DocFileFormat opCodeSize = 1; //first 1 byte are the operation code ... 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 { @@ -208,7 +215,9 @@ namespace DocFileFormat } 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, 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,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) diff --git a/ASCOfficeDocFile/DocDocxConverter/TextboxMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/TextboxMapping.cpp index f8ecbe36d3..bf3082fb61 100644 --- a/ASCOfficeDocFile/DocDocxConverter/TextboxMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/TextboxMapping.cpp @@ -130,7 +130,8 @@ namespace DocFileFormat } else if (m_nTBIndex + 1 < m_document->TextboxIndividualPlex->CharacterPositions.size()) { - cp = m_document->TextboxIndividualPlex->CharacterPositions[m_nTBIndex]; + //todooo сделать чище + cp = m_document->TextboxIndividualPlex->CharacterPositions[m_nTBIndex] + 2; cpEnd = m_document->TextboxIndividualPlex->CharacterPositions[m_nTBIndex + 1]; } } diff --git a/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp index cfe76b8015..0b389e8e6c 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/VMLPictureMapping.cpp @@ -34,10 +34,13 @@ #include "OfficeDrawing/GeometryBooleanProperties.h" #include "OfficeDrawing/GeometryTextBooleanProperties.h" +#include "OfficeDrawing/MetafilePictBlip.h" #include "../../DesktopEditor/common/String.h" #include "../../Common/DocxFormat/Source/DocxFormat/Document.h" -#include "../../Common/DocxFormat/Source/DocxFormat/Document.h" + +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/raster/BgraFrame.h" typedef struct { @@ -64,6 +67,50 @@ typedef struct namespace DocFileFormat { + Global::BlipType GetFormatPict(unsigned char* data, int size) + { + Global::BlipType btWin32 = Global::msoblipDIB; + + int offset = 0, biSizeImage = 0; + + BITMAPINFOHEADER * header = (BITMAPINFOHEADER*)data; + if (!header) return btWin32; + + if (header->biWidth > 100000 || header->biHeight > 100000 || header->biSize != 40) + { + BITMAPCOREHEADER * header_core = (BITMAPCOREHEADER *)data; + + if (header_core->bcSize != 12) + { + btWin32 = Global::msoblipWMF; + } + else + { + offset = 12; //sizeof(BITMAPCOREHEADER) + int stride = (size - offset) / header_core->bcHeight; + + biSizeImage = size - offset; + + if (stride >= header_core->bcWidth && header_core->bcBitCount >=24 ) + { + btWin32 = Global::msoblipPNG; + } + } + } + else + { + offset = 40; //sizeof(BITMAPINFOHEADER) + int sz_bitmap = header->biHeight * header->biWidth * header->biBitCount/ 8; + + int stride = (size - offset) / header->biHeight; + + if (stride >= header->biWidth && header->biBitCount >= 24) + { + btWin32 = Global::msoblipPNG; + } + } + return btWin32; + } bool ParseEmbeddedEquation( const std::string & xmlString, std::wstring & newXmlString) { newXmlString.clear(); @@ -307,7 +354,6 @@ namespace DocFileFormat return m_ShapeId; } - /// Writes a border element void VMLPictureMapping::writePictureBorder( const std::wstring & name, const BorderCode* brc ) { if (!brc || name.empty()) return; @@ -318,8 +364,6 @@ namespace DocFileFormat m_pXmlWriter->WriteNodeEnd ( _T( "" ), true ); } - /// Copies the picture from the binary stream to the zip archive - /// and creates the relationships for the image. bool VMLPictureMapping::CopyPicture (PictureDescriptor* pict) { if (!pict) return false; @@ -329,57 +373,45 @@ namespace DocFileFormat if (pict->embeddedData && pict->embeddedDataSize > 0) { - ENHMETAHEADER3 oHeader; + Global::BlipType btWin32 = GetFormatPict(pict->embeddedData, pict->embeddedDataSize); - int w = 0, h = 0; + if (btWin32 == Global::msoblipWMF) + { + CMetaHeader oMetaHeader; + + oMetaHeader.rcBounds.right = pict->mfp.xExt ; + oMetaHeader.rcBounds.bottom = pict->mfp.yExt ; - oHeader.iType = 0x00000001; - oHeader.nSize = sizeof(oHeader); + WmfPlaceableFileHeader oWmfHeader = {}; + oMetaHeader.ToWMFHeader(&oWmfHeader); + + int lLenHeader = 114 + 22; - oHeader.rclBounds.left = 0; - oHeader.rclBounds.top = 0; - oHeader.rclBounds.right = w; - oHeader.rclBounds.bottom = h; + unsigned char *newData = new unsigned char[pict->embeddedDataSize + lLenHeader]; + + memcpy(newData, (unsigned char *)(&oWmfHeader), 22); + memcpy(newData + 22, pict->embeddedDataHeader, 114 ); + + memcpy(newData + lLenHeader, pict->embeddedData, pict->embeddedDataSize); - oHeader.rclFrame.left = 0; - oHeader.rclFrame.top = 0; - oHeader.rclFrame.right = w; - oHeader.rclFrame.bottom = h; + pict->embeddedDataSize += lLenHeader; + delete []pict->embeddedData; + pict->embeddedData = newData; - 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; + } + m_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(Global::msoblipDIB), + std::vector(pict->embeddedData, (pict->embeddedData + pict->embeddedDataSize)), Global::msoblipDIB)); - 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; + m_nImageId = m_ctx->_docx->RegisterImage(m_caller, btWin32); + result = true; } else if ((oBlipEntry != NULL) && (oBlipEntry->Blip != NULL)) { switch (oBlipEntry->btWin32) { - case Global::msoblipEMF: - case Global::msoblipWMF: + case Global::msoblipEMF: + case Global::msoblipWMF: { - //it's a meta image MetafilePictBlip* metaBlip = static_cast(oBlipEntry->Blip); if (metaBlip) {//decompress inside MetafilePictBlip @@ -393,11 +425,11 @@ namespace DocFileFormat } break; - case Global::msoblipJPEG: - case Global::msoblipCMYKJPEG: - case Global::msoblipPNG: - case Global::msoblipTIFF: - case Global::msoblipDIB: + case Global::msoblipJPEG: + case Global::msoblipCMYKJPEG: + case Global::msoblipPNG: + case Global::msoblipTIFF: + case Global::msoblipDIB: { BitmapBlip* bitBlip = static_cast(oBlipEntry->Blip); if (bitBlip) @@ -405,19 +437,16 @@ namespace DocFileFormat m_ctx->_docx->ImagesList.push_back(ImageFileStructure(GetTargetExt(oBlipEntry->btWin32), std::vector(bitBlip->m_pvBits, (bitBlip->m_pvBits + bitBlip->pvBitsSize)), oBlipEntry->btWin32)); } - } - break; + }break; - default: + default: { return false; - } - break; + }break; } m_nImageId = m_ctx->_docx->RegisterImage(m_caller, oBlipEntry->btWin32); - - result = true; + result = true; } return result; @@ -430,28 +459,16 @@ namespace DocFileFormat { switch (nType) { - //case Global::msoblipDIB: - // return std::wstring( _T( ".bmp" ) ); - - //case msoblipBMP: - // return wstring( _T( ".bmp" ) ); + case Global::msoblipDIB: + return std::wstring(_T(".bmp")); case Global::msoblipEMF: return std::wstring(_T(".emf")); - //case msoblipGIF: - // return wstring( _T( ".gif" ) ); - - //case msoblipICON: - // return wstring( _T( ".ico" ) ); - case Global::msoblipJPEG: case Global::msoblipCMYKJPEG: return std::wstring(_T(".jpg")); - //case msoblipPCX: - // return wstring( _T( ".pcx" ) ); - case Global::msoblipPNG: return std::wstring(_T(".png")); @@ -470,9 +487,6 @@ namespace DocFileFormat { switch (nType) { - //case msoblipBMP: - // return wstring( _T( "image/bmp" ) ); - case Global::msoblipEMF: return std::wstring(OpenXmlContentTypes::Emf); @@ -498,6 +512,9 @@ namespace DocFileFormat case Global::msoblipWMF: return std::wstring(OpenXmlContentTypes::Wmf); + case Global::msoblipDIB: + return std::wstring(OpenXmlContentTypes::Bmp); + default: return std::wstring(OpenXmlContentTypes::Png); } diff --git a/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp b/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp index 54f7d94d64..8970b855a9 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.cpp @@ -95,12 +95,6 @@ namespace DocFileFormat { m_pBlipStore = static_cast(recBs); } - m_offset_x.push_back(0); - m_offset_y.push_back(0); - - m_scale_x.push_back(1); - m_scale_y.push_back(1); - } VMLShapeMapping::~VMLShapeMapping() @@ -1333,36 +1327,36 @@ namespace DocFileFormat { switch ( _type ) { - //case msoblipBMP: - // return std::wstring( _T( ".bmp" ) ); + case Global::msoblipDIB: + return std::wstring( _T( ".bmp" ) ); - case Global::msoblipEMF: - return std::wstring( _T( ".emf" ) ); + case Global::msoblipEMF: + return std::wstring( _T( ".emf" ) ); - //case msoblipGIF: - // return std::wstring( _T( ".gif" ) ); + //case msoblipGIF: + // return std::wstring( _T( ".gif" ) ); - //case msoblipICON: - // return std::wstring( _T( ".ico" ) ); + //case msoblipICON: + // return std::wstring( _T( ".ico" ) ); - case Global::msoblipJPEG: - case Global::msoblipCMYKJPEG: - return std::wstring( _T( ".jpg" ) ); + case Global::msoblipJPEG: + case Global::msoblipCMYKJPEG: + return std::wstring( _T( ".jpg" ) ); - //case msoblipPCX: - // return std::wstring( _T( ".pcx" ) ); + //case msoblipPCX: + // return std::wstring( _T( ".pcx" ) ); - case Global::msoblipPNG: - return std::wstring( _T( ".png" ) ); + case Global::msoblipPNG: + return std::wstring( _T( ".png" ) ); - case Global::msoblipTIFF: - return std::wstring( _T( ".tif" ) ); + case Global::msoblipTIFF: + return std::wstring( _T( ".tif" ) ); - case Global::msoblipWMF: - return std::wstring( _T( ".wmf" ) ); + case Global::msoblipWMF: + return std::wstring( _T( ".wmf" ) ); - default: - return std::wstring( _T( ".png" ) ); + default: + return std::wstring( _T( ".png" ) ); } } @@ -2121,153 +2115,163 @@ namespace DocFileFormat if (index >= primitives->size()) return index++; DrawingPrimitive *primitive = dynamic_cast(primitives->at(index)); - + m_pXmlWriter->WriteNodeBegin(primitive->strVmlType.c_str(), TRUE ); + + if (primitive->type == 0x0007) + { + DrawingPrimitiveCTextBox * callout = dynamic_cast(primitive); + if ((callout) && (callout->txbx)) + { + //временно обычный текстбокс + callout->txbx->xa += callout->xa; + callout->txbx->ya += callout->ya; + + WritePrimitiveProps(dynamic_cast(callout->txbx), (index==0?true:false)); + } + //todooo нарисовать кастомный шейп + } + else + WritePrimitiveProps(primitive, (index==0?true:false)); + + + if (primitive->type == 0x0000) + { + index++; - TwipsValue x( primitive->xa ); - TwipsValue y( primitive->ya ); - TwipsValue w( primitive->dxa ); - TwipsValue h( primitive->dya ); - - std::wstring strId = std::wstring(L"_x0000_s") + FormatUtils::IntToWideString(1024 + (count_vml_objects++)); - //m_pXmlWriter->WriteAttribute ( _T( "id") , strId.c_str()); - m_pXmlWriter->WriteAttribute ( _T( "o:spid"), strId.c_str()); - - std::wstring strStyle = _T("position:absolute;visibility:visible;mso-wrap-style:square;"); - - DrawingPrimitiveLine * line = dynamic_cast(primitive); - if (line) + while(true) { - TwipsValue x1( line->xaStart ); - TwipsValue y1( line->yaStart ); - TwipsValue x2( line->xaEnd ); - TwipsValue y2( line->yaEnd ); - - std::wstring strStart = FormatUtils::IntToWideString(line->xaStart + primitive->xa) + _T(",") + FormatUtils::IntToWideString(line->yaStart + primitive->ya); - std::wstring strEnd = FormatUtils::IntToWideString(line->xaEnd + primitive->xa) + _T(",") + FormatUtils::IntToWideString(line->yaEnd + primitive->ya); - - m_pXmlWriter->WriteAttribute(_T("from"), strStart.c_str() ); - m_pXmlWriter->WriteAttribute(_T("to"), strEnd.c_str()); - } - else - { - if (index > 0) - { - strStyle += _T("left:") + FormatUtils::IntToWideString( primitive->xa) + _T(";"); - strStyle += _T("top:") + FormatUtils::IntToWideString( primitive->ya) + _T(";"); - strStyle += _T("width:") + FormatUtils::IntToWideString( primitive->dxa) + _T(";"); - strStyle += _T("height:") + FormatUtils::IntToWideString( primitive->dya) + _T(";"); - - - } - else - { - //strStyle += _T("left:") + FormatUtils::IntToWideString( x.ToPoints()) + _T("pt;"); - //strStyle += _T("top:") + FormatUtils::IntToWideString( y.ToPoints()) + _T("pt;"); - strStyle += _T("width:") + FormatUtils::IntToWideString( w.ToPoints()) + _T("pt;"); - strStyle += _T("height:") + FormatUtils::IntToWideString( h.ToPoints()) + _T("pt;"); - - strStyle += _T("margin-left:") + FormatUtils::IntToWideString( x.ToPoints()) + _T("pt;"); - strStyle += _T("margin-top:") + FormatUtils::IntToWideString( y.ToPoints()) + _T("pt;"); - - std::wstring xMargin; - std::wstring yMargin; - if (m_pSpa->bx == PAGE) xMargin = _T("page;"); - if (m_pSpa->by == PAGE) yMargin = _T("page;"); - - if (m_pSpa->bx == MARGIN) xMargin = _T("margin;"); - if (m_pSpa->by == MARGIN) yMargin = _T("margin;"); - - if (!xMargin.empty()) strStyle += _T("mso-position-horizontal-relative:") + xMargin; - if (!yMargin.empty()) strStyle += _T("mso-position-vertical-relative:") + yMargin; - - std::wstring strSize = FormatUtils::IntToWideString(primitive->dxa) + _T(",") + FormatUtils::IntToWideString(primitive->dya); - std::wstring strOrigin = FormatUtils::IntToWideString(primitive->xa) + _T(",") + FormatUtils::IntToWideString(primitive->ya); - - m_pXmlWriter->WriteAttribute( _T("coordsize"), strSize.c_str()); - //m_pXmlWriter->WriteAttribute( _T("coordorigin"), strOrigin.c_str()); - } - } - if (primitive->type > 1) - { - m_pXmlWriter->WriteAttribute( _T("fillColor"), FormatUtils::IntToFormattedWideString(primitive->fillFore, L"#%06x").c_str()); - } - m_pXmlWriter->WriteAttribute( _T("style"), strStyle.c_str()); - - std::wstring strStrokeWeight = FormatUtils::IntToWideString(primitive->lineWeight / 20) + _T("pt"); - if (primitive->lineWeight > 20) - m_pXmlWriter->WriteAttribute( _T("strokeweight"), strStrokeWeight.c_str()); - - if (primitive->type > 0) - m_pXmlWriter->WriteAttribute( _T("strokecolor"), FormatUtils::IntToFormattedWideString(primitive->lineColor, L"#%06x").c_str()); - - m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); - - if (primitive->type > 1) - { - m_pXmlWriter->WriteNodeBegin(_T("v:fill"), TRUE ); - m_pXmlWriter->WriteAttribute( _T("color2"), FormatUtils::IntToFormattedWideString(primitive->fillBack, L"#%06x").c_str()); - if (primitive->fillPattern > 0) - { - m_pXmlWriter->WriteAttribute( _T("type"), _T("pattern")); - } - m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); - m_pXmlWriter->WriteNodeEnd( _T("v:fill") ); - } - - if (primitive->lineStyle > 1) - { - m_pXmlWriter->WriteNodeBegin(_T("v:stroke"), TRUE ); - std::wstring strDashStyle = FormatUtils::IntToWideString(primitive->lineStyle) + _T(" 1"); - m_pXmlWriter->WriteAttribute( _T("dashstyle"), strDashStyle.c_str()); - m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); - m_pXmlWriter->WriteNodeEnd( _T("v:stroke") ); - } - if (primitive->type == 0x0000) - { - m_offset_x.push_back(20000. / primitive->xa); - m_offset_y.push_back(20000. / primitive->ya); - - m_scale_x.push_back(20000. / primitive->dxa); - m_scale_y.push_back(20000. / primitive->dya); - - index++; + if (index > primitives->size() - 1) + break; - while(true) + primitive = dynamic_cast(primitives->at(index)); + + if (primitive->type == 0x0008) { - if (index > primitives->size() - 1) - break; - - primitive = dynamic_cast(primitives->at(index)); - - if (primitive->type == 0x0008) - { - m_offset_x.pop_back(); - m_offset_y.pop_back(); - - m_scale_x.pop_back(); - m_scale_y.pop_back(); - break; - } - - index = ApplyPrimitive(primitives, index); + break; } - } - if (primitive->type == 0x0002 || primitive->type == 0x0007) - { - int nLTxID = currentTextBoxIndex++;; - - if (-1 != nLTxID) - { - TextboxMapping textboxMapping(m_ctx, nLTxID - 1, m_pXmlWriter, m_pCaller); - //textboxMapping.SetInset(ndxTextLeft, ndyTextTop, ndxTextRight, ndyTextBottom); - m_ctx->_doc->Convert(&textboxMapping); - } + index = ApplyPrimitive(primitives, index); } + } + + if (primitive->type == 0x0002 || primitive->type == 0x0007) + { + int nLTxID = currentTextBoxIndex++;; + + if (-1 != nLTxID) + { + TextboxMapping textboxMapping(m_ctx, nLTxID - 1, m_pXmlWriter, m_pCaller); + //textboxMapping.SetInset(ndxTextLeft, ndyTextTop, ndxTextRight, ndyTextBottom); + m_ctx->_doc->Convert(&textboxMapping); + } + } + m_pXmlWriter->WriteNodeEnd( primitive->strVmlType.c_str() ); index++; return index; } + + void VMLShapeMapping::WritePrimitiveProps (DrawingPrimitive * primitive, bool root) + { + TwipsValue x( primitive->xa ); + TwipsValue y( primitive->ya ); + TwipsValue w( primitive->dxa ); + TwipsValue h( primitive->dya ); + + std::wstring strId = std::wstring(L"_x0000_s") + FormatUtils::IntToWideString(1024 + (count_vml_objects++)); + //m_pXmlWriter->WriteAttribute ( _T( "id") , strId.c_str()); + m_pXmlWriter->WriteAttribute ( _T( "o:spid"), strId.c_str()); + + std::wstring strStyle = _T("position:absolute;visibility:visible;mso-wrap-style:square;"); + + DrawingPrimitiveLine * line = dynamic_cast(primitive); + if (line) + { + TwipsValue x1( line->xaStart ); + TwipsValue y1( line->yaStart ); + TwipsValue x2( line->xaEnd ); + TwipsValue y2( line->yaEnd ); + + std::wstring strStart = FormatUtils::IntToWideString(line->xaStart + primitive->xa) + _T(",") + FormatUtils::IntToWideString(line->yaStart + primitive->ya); + std::wstring strEnd = FormatUtils::IntToWideString(line->xaEnd + primitive->xa) + _T(",") + FormatUtils::IntToWideString(line->yaEnd + primitive->ya); + + m_pXmlWriter->WriteAttribute(_T("from"), strStart.c_str() ); + m_pXmlWriter->WriteAttribute(_T("to"), strEnd.c_str()); + } + else + { + if (root) + { + //strStyle += _T("left:") + FormatUtils::IntToWideString( x.ToPoints()) + _T("pt;"); + //strStyle += _T("top:") + FormatUtils::IntToWideString( y.ToPoints()) + _T("pt;"); + strStyle += _T("width:") + FormatUtils::IntToWideString( w.ToPoints()) + _T("pt;"); + strStyle += _T("height:") + FormatUtils::IntToWideString( h.ToPoints()) + _T("pt;"); + + strStyle += _T("margin-left:") + FormatUtils::IntToWideString( x.ToPoints()) + _T("pt;"); + strStyle += _T("margin-top:") + FormatUtils::IntToWideString( y.ToPoints()) + _T("pt;"); + + std::wstring xMargin; + std::wstring yMargin; + if (m_pSpa->bx == PAGE) xMargin = _T("page;"); + if (m_pSpa->by == PAGE) yMargin = _T("page;"); + + if (m_pSpa->bx == MARGIN) xMargin = _T("margin;"); + if (m_pSpa->by == MARGIN) yMargin = _T("margin;"); + + if (!xMargin.empty()) strStyle += _T("mso-position-horizontal-relative:") + xMargin; + if (!yMargin.empty()) strStyle += _T("mso-position-vertical-relative:") + yMargin; + + std::wstring strSize = FormatUtils::IntToWideString(primitive->dxa) + _T(",") + FormatUtils::IntToWideString(primitive->dya); + std::wstring strOrigin = FormatUtils::IntToWideString(primitive->xa) + _T(",") + FormatUtils::IntToWideString(primitive->ya); + + m_pXmlWriter->WriteAttribute( _T("coordsize"), strSize.c_str()); + //m_pXmlWriter->WriteAttribute( _T("coordorigin"), strOrigin.c_str()); + } + else + { + strStyle += _T("left:") + FormatUtils::IntToWideString( primitive->xa) + _T(";"); + strStyle += _T("top:") + FormatUtils::IntToWideString( primitive->ya) + _T(";"); + strStyle += _T("width:") + FormatUtils::IntToWideString( primitive->dxa) + _T(";"); + strStyle += _T("height:") + FormatUtils::IntToWideString( primitive->dya) + _T(";"); + } + } + if (primitive->fillPattern == 0) + m_pXmlWriter->WriteAttribute( _T("filled"), _T("f")); + + if (primitive->type > 1) + { + m_pXmlWriter->WriteAttribute( _T("fillColor"), FormatUtils::IntToFormattedWideString(primitive->fillFore, L"#%06x").c_str()); + } + m_pXmlWriter->WriteAttribute( _T("style"), strStyle.c_str()); + + std::wstring strStrokeWeight = FormatUtils::IntToWideString(primitive->lineWeight / 20) + _T("pt"); + if (primitive->lineWeight > 20) + m_pXmlWriter->WriteAttribute( _T("strokeweight"), strStrokeWeight.c_str()); + + if (primitive->type > 0) + m_pXmlWriter->WriteAttribute( _T("strokecolor"), FormatUtils::IntToFormattedWideString(primitive->lineColor, L"#%06x").c_str()); + + m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); + + if (primitive->type > 1 && primitive->fillPattern > 1) + { + m_pXmlWriter->WriteNodeBegin(_T("v:fill"), TRUE ); + m_pXmlWriter->WriteAttribute( _T("color2"), FormatUtils::IntToFormattedWideString(primitive->fillBack, L"#%06x").c_str()); + m_pXmlWriter->WriteAttribute( _T("type"), _T("pattern")); + m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); + m_pXmlWriter->WriteNodeEnd( _T("v:fill") ); + } + + if (primitive->lineStyle > 1) + { + m_pXmlWriter->WriteNodeBegin(_T("v:stroke"), TRUE ); + std::wstring strDashStyle = FormatUtils::IntToWideString(primitive->lineStyle) + _T(" 1"); + m_pXmlWriter->WriteAttribute( _T("dashstyle"), strDashStyle.c_str()); + m_pXmlWriter->WriteNodeEnd( _T( "" ), TRUE, FALSE ); + m_pXmlWriter->WriteNodeEnd( _T("v:stroke") ); + } + } + } diff --git a/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.h b/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.h index ba59ea0b9e..6cf3ffc516 100644 --- a/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.h +++ b/ASCOfficeDocFile/DocDocxConverter/VMLShapeMapping.h @@ -65,8 +65,10 @@ namespace DocFileFormat private: - void ApplyPrimitives(DrawingPrimitives * primitives ); - int ApplyPrimitive (DrawingPrimitives * primitives, int index); + void ApplyPrimitives (DrawingPrimitives * primitives ); + int ApplyPrimitive (DrawingPrimitives * primitives, int index); + + void WritePrimitiveProps(DrawingPrimitive * primitive, bool root); // Converts a group of shapes void WriteGroup(const GroupContainer* pContainer); @@ -135,12 +137,5 @@ namespace DocFileFormat XMLTools::XMLElement m_imagedata; XMLTools::XMLElement m_3dstyle; XMLTools::XMLElement m_textpath; - -//---------------------------------------------------------------- - std::vector m_offset_x; - std::vector m_offset_y; - - std::vector m_scale_x; - std::vector m_scale_y; }; } diff --git a/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp b/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp index 108a46c140..525c01d10d 100644 --- a/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/WordDocument.cpp @@ -49,6 +49,7 @@ namespace DocFileFormat EndnoteReferenceCharactersPlex(NULL), FieldsPlex(NULL), FootnoteDocumentFieldsPlex(NULL), EndnoteDocumentFieldsPlex(NULL), HeadersAndFootersDocumentFieldsPlex(NULL), HeaderStoriesPlex(NULL), AnnotationsReferencePlex(NULL), IndividualCommentsPlex(NULL), TextboxBreakPlex(NULL), TextboxBreakPlexHeader(NULL), + TextboxIndividualPlex(NULL), OfficeDrawingPlex(NULL), OfficeDrawingPlexHeader(NULL), SectionPlex(NULL), BookmarkStartPlex(NULL), BookmarkEndPlex(NULL), AutoTextPlex(NULL), AllPapxFkps(NULL), AllChpxFkps(NULL), AllPapx(NULL), AllPapxVector(NULL), AllSepx(NULL), Styles(NULL), listTable(NULL), AnnotationOwners(NULL), DocProperties(NULL), listFormatOverrideTable(NULL), headerAndFooterTable(NULL), encryptionHeader(NULL) diff --git a/ASCOfficeDocFile/DocDocxConverter/WordprocessingDocument.cpp b/ASCOfficeDocFile/DocDocxConverter/WordprocessingDocument.cpp index 13d678caf2..66ac56bd8a 100644 --- a/ASCOfficeDocFile/DocDocxConverter/WordprocessingDocument.cpp +++ b/ASCOfficeDocFile/DocDocxConverter/WordprocessingDocument.cpp @@ -39,7 +39,7 @@ namespace ImageHelper { - typedef struct ___tagBITMAPINFOHEADER + struct __BITMAPINFOHEADER { DWORD biSize; LONG biWidth; @@ -52,44 +52,117 @@ namespace ImageHelper LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; - } ___BITMAPINFOHEADER; + }; - inline static int CompareStrings (const wchar_t* str1, const wchar_t* str2) + struct __BITMAPCOREHEADER { - CString cstr1; cstr1 = str1; - CString cstr2; cstr2 = str2; + DWORD bcSize; /* used to get to color table */ + WORD bcWidth; + WORD bcHeight; + WORD bcPlanes; + WORD bcBitCount; + }; - if (cstr1 == cstr2) - return 0; - - return 1; - } - inline bool SaveImageToFileFromDIB(unsigned char* buffer, int size, const std::wstring& file) + inline Global::_BlipType SaveImageToFileFromDIB(unsigned char* data, int size, const std::wstring& file_name)//without ext { - bool result = false; - const ___BITMAPINFOHEADER* info = (___BITMAPINFOHEADER*)buffer; + Global::_BlipType result = Global::msoblipERROR; - if (NULL != info && info->biSize == 40) + CBgraFrame oFrame; + int offset = 0, biSizeImage = 0; + + __BITMAPINFOHEADER * header = (__BITMAPINFOHEADER*)data; + if (!header) return result; + + result == Global::msoblipDIB; + + if (header->biWidth > 100000 || header->biHeight > 100000 || header->biSize != 40) { - unsigned char* pBgraData = buffer + sizeof(___BITMAPINFOHEADER); + __BITMAPCOREHEADER * header_core = (__BITMAPCOREHEADER *)data; + if (header_core->bcSize != 12) + { + result = Global::msoblipWMF; + } + else + { + offset = 12; //sizeof(BITMAPCOREHEADER) - int nWidth = info->biWidth; - int nHeight = info->biHeight; + oFrame.put_Height (header_core->bcHeight ); + oFrame.put_Width (header_core->bcWidth ); + + int sz_bitmap = header_core->bcHeight * header_core->bcWidth * header_core->bcBitCount/ 8; + + //if (header_core->bcWidth % 2 != 0 && sz_bitmap < size - offset) + // header_core->bcWidth++; + ///???? todooo непонятно .. в biff5 нужно флипать картинку, в biff8 не ясно ( - + + int stride = -(size - offset) / header_core->bcHeight; + oFrame.put_Stride (stride/*header_core->bcBitCount * header_core->bcWidth /8 */); - CBgraFrame oFrame; - oFrame.put_Data (pBgraData); - oFrame.put_Width (nWidth); - oFrame.put_Height (nHeight); + biSizeImage = size - offset; + + if (-stride >= header_core->bcWidth && header_core->bcBitCount >=24 ) + { + result = Global::msoblipPNG; + } + } + } + else + { + offset = 40; //sizeof(BITMAPINFOHEADER) - int nStride = info->biSizeImage / nHeight; - oFrame.put_Stride( -nStride ); + oFrame.put_Height (header->biHeight ); + oFrame.put_Width (header->biWidth ); + + int sz_bitmap = header->biHeight * header->biWidth * header->biBitCount/ 8; + + //if (header->biWidth % 2 != 0 && sz_bitmap < size -offset) + // header->biWidth++; + + int stride = -(size - offset) / header->biHeight; - result = oFrame.SaveFile(file, 4); + if (-stride >= header->biWidth && header->biBitCount >= 24) + { + result = Global::msoblipPNG; + } + oFrame.put_Stride (stride/*header->biBitCount * header->biWidth /8*/); + + biSizeImage = header->biSizeImage > 0 ? header->biSizeImage : (size - offset); + } + +//------------------------------------------------------------------------------------------ + + if (result == Global::msoblipPNG) + { + oFrame.put_Data((unsigned char*)data + offset); + + if (!oFrame.SaveFile(file_name + _T(".png"), 4/*CXIMAGE_FORMAT_PNG*/)) + result = Global::msoblipERROR; oFrame.put_Data(NULL); - } - + else if (result == Global::msoblipWMF) + { + NSFile::CFileBinary file; + if (file.CreateFileW(file_name + _T(".wmf"))) + { + file.WriteFile((BYTE*)data, size); + file.CloseFile(); + } + } + else if (biSizeImage > 0) + { + NSFile::CFileBinary file; + if (file.CreateFileW(file_name + _T(".bmp"))) + { + WORD vtType = 0x4D42; file.WriteFile((BYTE*)&vtType, 2); + DWORD dwLen = biSizeImage; file.WriteFile((BYTE*)&dwLen, 4); + DWORD dwRes = 0; file.WriteFile((BYTE*)&dwRes, 4); + DWORD dwOffset = 2; file.WriteFile((BYTE*)&dwOffset, 4); + + file.WriteFile((BYTE*)data, size); + file.CloseFile(); + } + } return result; } } @@ -120,11 +193,11 @@ namespace DocFileFormat //Write main content. (word directory) SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T("document.xml" ) ), DocumentXML ); - SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "fontTable.xml" ) ), FontTableXML ); + SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "fontTable.xml" ) ), FontTableXML ); SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "styles.xml" ) ), StyleSheetXML ); - SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "footnotes.xml" ) ), FootnotesXML ); + SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "footnotes.xml" ) ), FootnotesXML ); SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "endnotes.xml" ) ), EndnotesXML ); - SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "numbering.xml" ) ), NumberingXML ); + SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "numbering.xml" ) ), NumberingXML ); SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "comments.xml" ) ), CommentsXML ); SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "settings.xml" ) ), SettingsXML ); SaveToFile(string2std_string(pathWord.GetPath()), std::wstring( _T( "customizations.xml" ) ),CommandTableXML ); @@ -147,8 +220,8 @@ namespace DocFileFormat if (Global::msoblipDIB == iter->blipType) {//user_manual_v52.doc - std::wstring file_name = string2std_string(pathMedia.GetPath()) + FILE_SEPARATOR_STR + _T("image") + FormatUtils::IntToWideString(i++) + iter->ext; - ImageHelper::SaveImageToFileFromDIB(bytes, iter->data.size(), file_name); + std::wstring file_name = string2std_string(pathMedia.GetPath()) + FILE_SEPARATOR_STR + _T("image") + FormatUtils::IntToWideString(i++); + iter->blipType = ImageHelper::SaveImageToFileFromDIB(bytes, iter->data.size(), file_name); } else { diff --git a/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp b/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp index 85cc0d5082..677a36fbcd 100644 --- a/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp +++ b/ASCOfficeXlsFile2/source/XlsXlsxConverter/XlsConverter.cpp @@ -657,7 +657,7 @@ std::wstring XlsConverter::WriteMediaFile(char *data, int size, std::wstring typ if (file.CreateFileW(xlsx_context->get_mediaitems().media_path() + file_name)) { WORD vtType = 0x4D42; file.WriteFile((BYTE*)&vtType, 2); - DWORD dwLen = biSizeImage; file.WriteFile((BYTE*)&dwLen, 4); + DWORD dwLen = biSizeImage; file.WriteFile((BYTE*)&dwLen, 4); DWORD dwRes = 0; file.WriteFile((BYTE*)&dwRes, 4); DWORD dwOffset = 2; file.WriteFile((BYTE*)&dwOffset, 4);