Files
DocumentServer-v-9.2.0/core/MsBinaryFile/PptFile/Reader/ReadStructures.cpp
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

963 lines
28 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#pragma once
#include "ReadStructures.h"
#include "../../DocFile/MemoryStream.h"
#include "../../../OfficeCryptReader/source/CryptTransform.h"
namespace PPT
{
static ODRAW::CColor GetStandartPaletteColor(int index)
{
ODRAW::CColor color;
static BYTE palette [56][3] =
{
{ 0 , 0 , 0 },
{ 255 , 255 , 255 },
{ 255 , 0 , 0 },
{ 0 , 255 , 0 },
{ 0 , 0 , 255 },
{ 255 , 255 , 0 },
{ 255 , 0 , 255 },
{ 0 , 255 , 255 },
{ 128 , 0 , 0 },
{ 0 , 128 , 0 },
{ 0 , 0 , 128 },
{ 128 , 128 , 0 },
{ 128 , 0 , 128 },
{ 0 , 128 , 128 },
{ 192 , 192 , 192 },
{ 128 , 128 , 128 },
{ 153 , 153 , 255 },
{ 153 , 51 , 102 },
{ 255 , 255 , 204 },
{ 204 , 255 , 255 },
{ 102 , 0 , 102 },
{ 255 , 128 , 128 },
{ 0 , 102 , 204 },
{ 204 , 204 , 255 },
{ 0 , 0 , 128 },
{ 255 , 0 , 255 },
{ 255 , 255 , 0 },
{ 0 , 255 , 255 },
{ 128 , 0 , 128 },
{ 128 , 0 , 0 },
{ 0 , 128 , 128 },
{ 0 , 0 , 255 },
{ 0 , 204 , 255 },
{ 204 , 255 , 255 },
{ 204 , 255 , 204 },
{ 255 , 255 , 153 },
{ 153 , 204 , 255 },
{ 255 , 153 , 204 },
{ 204 , 153 , 255 },
{ 255 , 204 , 153 },
{ 51 , 102 , 255 },
{ 51 , 204 , 204 },
{ 153 , 204 , 0 },
{ 255 , 204 , 0 },
{ 255 , 153 , 0 },
{ 255 , 102 , 0 },
{ 102 , 102 , 153 },
{ 150 , 150 , 150 },
{ 0 , 51 , 102 },
{ 51 , 153 , 102 },
{ 0 , 51 , 0 },
{ 51 , 51 , 0 },
{ 153 , 51 , 0 },
{ 153 , 51 , 102 },
{ 51 , 51 , 153 }
};
color.SetRGB(palette[index][0], palette[index][1], palette[index][2]);
return color;
}
namespace NSStreamReader
{
void Read(POLE::Stream* pStream, PPT::CTextRuler& oRun)
{
double dScaleX = 625 * 2.54;
//1/576 inch = 72/576 pt = 360000 *72 * 2.54 /(72*576) emu
_UINT32 dwFlags = StreamUtils::ReadDWORD(pStream);
BYTE flag1 = (BYTE)(dwFlags);
BYTE flag2 = (BYTE)(dwFlags >> 8);
BYTE flag3 = (BYTE)(dwFlags >> 16);
BYTE flag4 = (BYTE)(dwFlags >> 24);
bool bDefaultTabSize_ = (0x01 == (0x01 & flag1));
bool bCLevels_ = (0x02 == (0x02 & flag1));
bool bTabStops_ = (0x04 == (0x04 & flag1));
bool bLeftMargin1_ = (0x08 == (0x08 & flag1));
bool bLeftMargin2_ = (0x10 == (0x10 & flag1));
bool bLeftMargin3_ = (0x20 == (0x20 & flag1));
bool bLeftMargin4_ = (0x40 == (0x40 & flag1));
bool bLeftMargin5_ = (0x80 == (0x80 & flag1));
bool bIndent1_ = (0x01 == (0x01 & flag2));
bool bIndent2_ = (0x02 == (0x02 & flag2));
bool bIndent3_ = (0x04 == (0x04 & flag2));
bool bIndent4_ = (0x08 == (0x08 & flag2));
bool bIndent5_ = (0x10 == (0x10 & flag2));
if (bCLevels_)
oRun.CLevels = StreamUtils::ReadSHORT(pStream);
if (bDefaultTabSize_)
oRun.DefaultTabSize = (long)(StreamUtils::ReadSHORT(pStream) * dScaleX);
if (bTabStops_)
{
WORD tabStopsCount = StreamUtils::ReadWORD(pStream);
oRun.tabsStops.clear();
for (WORD i = 0; i < tabStopsCount; ++i)
{
WORD tabPos = StreamUtils::ReadWORD(pStream);
WORD tabType = StreamUtils::ReadWORD(pStream);
if ((tabPos & 0xff00) == 0xff00)
break;
tabType = 0x0000;
oRun.tabsStops.push_back(std::pair<int, int>(tabPos * dScaleX, tabType));
}
}
if (bLeftMargin1_) oRun.LeftMargin1 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bIndent1_) oRun.Indent1 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bLeftMargin2_) oRun.LeftMargin2 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bIndent2_) oRun.Indent2 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bLeftMargin3_) oRun.LeftMargin3 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bIndent3_) oRun.Indent3 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bLeftMargin4_) oRun.LeftMargin4 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bIndent4_) oRun.Indent4 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bLeftMargin5_) oRun.LeftMargin5 = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (bIndent5_) oRun.Indent5 = StreamUtils::ReadSHORT(pStream) * dScaleX;
}
void Read(POLE::Stream* pStream, PPT::CTextSIRun& oRun, bool bIsIndentation)
{
if (bIsIndentation)
{
oRun.lCount = StreamUtils::ReadDWORD(pStream);
}
_UINT32 dwFlags = StreamUtils::ReadDWORD(pStream);
BYTE flag1 = (BYTE)(dwFlags);
BYTE flag2 = (BYTE)(dwFlags >> 8);
oRun.bSpell = (0x01 == (0x01 & flag1));
oRun.bLang = (0x02 == (0x02 & flag1));
oRun.bAltLang = (0x04 == (0x04 & flag1));
// unused
// unused
oRun.bPp10ext = (0x20 == (0x20 & flag1));
oRun.bBidi = (0x40 == (0x40 & flag1));
// unused
// reserved
oRun.bSmartTag = (0x02 == (0x02 & flag2));
if (oRun.bSpell)
{
oRun.Spell = StreamUtils::ReadWORD(pStream);
}
if (oRun.bLang)
{
oRun.Lang = StreamUtils::ReadWORD(pStream);
}
if (oRun.bAltLang)
{
oRun.AltLang = StreamUtils::ReadWORD(pStream);
}
if (oRun.bBidi)
{
oRun.Bidi = StreamUtils::ReadWORD(pStream);
}
if (oRun.bPp10ext)
{
_UINT32 dwFlags = StreamUtils::ReadDWORD(pStream);
BYTE flag1 = (BYTE)(dwFlags);
BYTE flag2 = (BYTE)(dwFlags >> 8);
BYTE flag3 = (BYTE)(dwFlags >> 16);
BYTE flag4 = (BYTE)(dwFlags >> 24);
oRun.pp10runid = (0x0F & flag1);
oRun.bGramma = (0x80 == (0x80 & flag4));
}
/*if (bSmartTag)
{
_UINT32 tabStopsCount = StreamUtils::ReadDWORD(pStream);
arSmartTags.clear();
for (int i = 0; i < (int)tabStopsCount; ++i)
{
arSmartTags.Add(StreamUtils::ReadDWORD(pStream));
}
}*/
}
void Read(POLE::Stream *pStream, ODRAW::SPointAtom &oAtom)
{
oAtom.X = StreamUtils::ReadLONG(pStream);
oAtom.Y = StreamUtils::ReadLONG(pStream);
}
void Read(POLE::Stream *pStream, ODRAW::SColorAtom &oAtom)
{
oAtom.R = StreamUtils::ReadBYTE(pStream);
oAtom.G = StreamUtils::ReadBYTE(pStream);
oAtom.B = StreamUtils::ReadBYTE(pStream);
oAtom.Index = StreamUtils::ReadBYTE(pStream);
oAtom.bPaletteIndex = oAtom.bPaletteRGB = oAtom.bSystemRGB = oAtom.bSysIndex = oAtom.bSchemeIndex = false;
if (oAtom.Index != 0xFF)
{
oAtom.bPaletteRGB = (oAtom.Index == 0xFE);
oAtom.bSchemeIndex = (oAtom.Index != 0xFE);
}
}
}
CTextPFRunRecord::CTextPFRunRecord() : m_oRun()
{
m_lLevel = -1;
m_lCount = 0;
}
CTextPFRunRecord::CTextPFRunRecord(const CTextPFRunRecord &oSrc)
{
*this = oSrc;
}
CTextPFRunRecord &CTextPFRunRecord::operator=(const CTextPFRunRecord &oSrc)
{
m_oRun = oSrc.m_oRun;
m_lLevel = oSrc.m_lLevel;
m_lCount = oSrc.m_lCount;
return *this;
}
void CTextPFRunRecord::LoadFromStream(POLE::Stream* pStream, bool bIsIndentation)
{
double dScaleX = 625 * 2.54;
//1/576 inch = 72/576 pt = 360000 *72 * 2.54 /(72*576) emu
if (bIsIndentation)
{
m_lCount = StreamUtils::ReadLONG(pStream);
m_lLevel = (LONG)StreamUtils::ReadWORD(pStream);
if (m_lLevel > 0x0004)
m_lLevel = 0x0004;
}
_UINT32 dwFlags = StreamUtils::ReadDWORD(pStream);
BYTE flag1 = (BYTE)(dwFlags);
BYTE flag2 = (BYTE)(dwFlags >> 8);
BYTE flag3 = (BYTE)(dwFlags >> 16);
BYTE flag4 = (BYTE)(dwFlags >> 24);
//флаги чтения
bool hasBullet_ = (0x01 == (0x01 & flag1));
bool bulletHasFont_ = (0x02 == (0x02 & flag1));
bool bulletHasColor_ = (0x04 == (0x04 & flag1));
bool bulletHasSize_ = (0x08 == (0x08 & flag1));
bool bulletFontRef_ = (0x10 == (0x10 & flag1));
bool bulletColor_ = (0x20 == (0x20 & flag1));
bool bulletSize_ = (0x40 == (0x40 & flag1));
bool bulletChar_ = (0x80 == (0x80 & flag1));
bool leftMargin_ = (0x01 == (0x01 & flag2));
// reserved
bool indent_ = (0x04 == (0x04 & flag2));
bool textAlignment_ = (0x08 == (0x08 & flag2));
bool lineSpacing_ = (0x10 == (0x10 & flag2));
bool spaceBefore_ = (0x20 == (0x20 & flag2));
bool spaceAfter_ = (0x40 == (0x40 & flag2));
bool defaultTabSize_ = (0x80 == (0x80 & flag2));
bool fontAlign_ = (0x01 == (0x01 & flag3));
bool charWrap_ = (0x02 == (0x02 & flag3));
bool wordWrap_ = (0x04 == (0x04 & flag3));
bool overflow_ = (0x08 == (0x08 & flag3));
bool tabStops_ = (0x10 == (0x10 & flag3));
bool textDirection_ = (0x20 == (0x20 & flag3));
//reserved
bool bulletBlip_ = (0x80 == (0x80 & flag3));
bool bulletScheme_ = (0x01 == (0x01 & flag4));
bool bulletHasScheme_ = (0x02 == (0x02 & flag4));
WORD bulletFlag = 0;
if (hasBullet_ || bulletHasFont_ || bulletHasColor_ || bulletHasSize_)
{
bulletFlag = StreamUtils::ReadWORD(pStream);
if (bulletFlag & 0x0F)
{
m_oRun.hasBullet = (bool)(0x01 == (bulletFlag & 0x01));
}
else
m_oRun.hasBullet = false;
}
if (bulletChar_)
{
unsigned short utf16 = (unsigned short)StreamUtils::ReadWORD(pStream);
if (utf16 > 0x0013)
{
if (sizeof(wchar_t) == 2)
{
m_oRun.bulletChar = utf16;
}
else
{
std::wstring utf32 = NSFile::CUtf8Converter::GetWStringFromUTF16(&utf16, 1);
if (!utf32.empty())
m_oRun.bulletChar = utf32.c_str()[0];
}
}
}
if (bulletFontRef_)
{
m_oRun.bulletFontRef = StreamUtils::ReadWORD(pStream);
if (bulletFlag & 0x0F)
{
if (!(0x02 == (bulletFlag & 0x02)))
m_oRun.bulletFontRef.reset();
}
}
if (bulletSize_)
{
m_oRun.bulletSize = StreamUtils::ReadWORD(pStream);
if (bulletFlag & 0x0F)
{
if (!(0x08 == (bulletFlag & 0x08)))
m_oRun.bulletSize.reset();
}
}
if (bulletColor_)
{
ODRAW::SColorAtom oColorAtom;
NSStreamReader::Read(pStream, oColorAtom);
ODRAW::CColor oColor;
oColor.R = oColorAtom.R;
oColor.G = oColorAtom.G;
oColor.B = oColorAtom.B;
oColor.A = 255;
oColor.m_lSchemeIndex = -1;
if (oColorAtom.bSchemeIndex)
{
oColor.m_lSchemeIndex = oColorAtom.Index;
ODRAW::CorrectColorPPT(oColor.m_lSchemeIndex);
}
if (oColorAtom.bSchemeIndex || oColorAtom.bPaletteRGB)
{
m_oRun.bulletColor = oColor;
if (bulletFlag & 0x0F)
{
if (!(0x04 == (bulletFlag & 0x04)))
m_oRun.bulletColor.reset();
}
}
}
if (textAlignment_) m_oRun.textAlignment = StreamUtils::ReadWORD(pStream);
if (lineSpacing_) m_oRun.lineSpacing = -StreamUtils::ReadSHORT(pStream);
if (spaceBefore_) m_oRun.spaceBefore = -StreamUtils::ReadSHORT(pStream);
if (spaceAfter_) m_oRun.spaceAfter = -StreamUtils::ReadSHORT(pStream);
if (leftMargin_) m_oRun.leftMargin = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (indent_) m_oRun.indent = StreamUtils::ReadSHORT(pStream) * dScaleX;
if (defaultTabSize_) m_oRun.defaultTabSize = (_INT32)StreamUtils::ReadWORD(pStream) * dScaleX;
if (tabStops_)
{
WORD tabStopsCount = StreamUtils::ReadWORD(pStream);
m_oRun.tabStops.clear();
tabStopsCount = tabStopsCount & 0x000f;
for (int i = 0; i < (int)tabStopsCount; ++i)
{
WORD tabPos = StreamUtils::ReadWORD(pStream);
WORD tabType = StreamUtils::ReadWORD(pStream);
if ((tabPos & 0xff00) == 0xff00)
break;
m_oRun.tabStops.push_back(std::pair<int, int>(tabPos * dScaleX, tabType));
}
//if (0 < m_oRun.tabStops.size())
// m_oRun.defaultTabSize = m_oRun.tabStops[0];
}
if (fontAlign_)
m_oRun.fontAlign = StreamUtils::ReadWORD(pStream);
if (charWrap_ || wordWrap_ || overflow_)
{
m_oRun.wrapFlags = StreamUtils::ReadWORD(pStream);
}
if (textDirection_)
m_oRun.textDirection = StreamUtils::ReadWORD(pStream);
}
CTextCFRunRecord::CTextCFRunRecord() : m_oRun()
{
m_lCount = 0;
}
CTextCFRunRecord::CTextCFRunRecord(const CTextCFRunRecord &oSrc)
{
*this = oSrc;
}
CTextCFRunRecord &CTextCFRunRecord::operator=(const CTextCFRunRecord &oSrc)
{
m_oRun = oSrc.m_oRun;
m_lCount = oSrc.m_lCount;
return *this;
}
void CTextCFRunRecord::LoadFromStream(POLE::Stream* pStream, bool bIsIndentation)
{
if (bIsIndentation)
{
m_lCount = StreamUtils::ReadLONG(pStream);
}
_UINT32 dwFlags = StreamUtils::ReadDWORD(pStream);
BYTE flag1 = (BYTE)(dwFlags);
BYTE flag2 = (BYTE)(dwFlags >> 8);
BYTE flag3 = (BYTE)(dwFlags >> 16);
BYTE flag4 = (BYTE)(dwFlags >> 24);
bool hasBold = (0x01 == (0x01 & flag1));
bool hasItalic = (0x02 == (0x02 & flag1));
bool hasUnderline = (0x04 == (0x04 & flag1));
// unused
bool hasShadow = (0x10 == (0x10 & flag1));
bool hasFehint = (0x20 == (0x20 & flag1));
// unused
bool hasKimi = (0x80 == (0x80 & flag1));
// unused
bool hasEmboss = (0x02 == (0x02 & flag2));
// unused
BYTE hasStyle = ((0x3C & flag2) >> 2);
// unused
bool typeface_ = (0x01 == (0x01 & flag3));
bool size_ = (0x02 == (0x02 & flag3));
bool color_ = (0x04 == (0x04 & flag3));
bool BaseLineOffset_ = (0x08 == (0x08 & flag3));
bool EAFontRef_ = (0x20 == (0x20 & flag3));
bool AnsiFontRef_ = (0x40 == (0x40 & flag3));
bool SymbolFontRef_ = (0x80 == (0x80 & flag3));
bool hasNewEATypeface = (0x01 == (0x01 & flag4));
bool hasCsTypeface = (0x02 == (0x02 & flag4));
bool hasPp11ext = (0x04 == (0x04 & flag4));
bool bIsFontStylePresent = (hasBold || hasItalic || hasUnderline || hasShadow ||
hasFehint || hasKimi || hasEmboss || hasStyle != 0);
if (bIsFontStylePresent)
{
WORD fontStyle = StreamUtils::ReadWORD(pStream);
m_oRun.FontBold = 0x01 == (0x01 & fontStyle);
m_oRun.FontItalic = 0x02 == (0x02 & fontStyle);
m_oRun.FontUnderline = 0x04 == (0x04 & fontStyle);
m_oRun.FontShadow = 0x10 == (0x10 & fontStyle);
m_oRun.pp9rt = (0x3c00 & fontStyle) >> 10;
}
if (typeface_)
m_oRun.fontRef = StreamUtils::ReadWORD(pStream);
if (EAFontRef_)
m_oRun.eaFontRef = StreamUtils::ReadWORD(pStream);
if (AnsiFontRef_)
m_oRun.ansiFontRef = StreamUtils::ReadWORD(pStream);
if (SymbolFontRef_)
m_oRun.symbolFontRef = StreamUtils::ReadWORD(pStream);
if (size_)
m_oRun.Size = StreamUtils::ReadWORD(pStream);
if (color_)
{
ODRAW::SColorAtom oColorAtom;
NSStreamReader::Read(pStream, oColorAtom);
ODRAW::CColor oColor;
oColor.R = oColorAtom.R;
oColor.G = oColorAtom.G;
oColor.B = oColorAtom.B;
oColor.A = 255;
oColor.m_lSchemeIndex = -1;
if (oColorAtom.Index < 8 && oColorAtom.bSchemeIndex)
{
oColor.m_lSchemeIndex = oColorAtom.Index;
ODRAW::CorrectColorPPT(oColor.m_lSchemeIndex);
}
if (oColorAtom.bSchemeIndex || oColorAtom.bPaletteRGB)
{
m_oRun.Color = oColor;
}
}
if (BaseLineOffset_)
m_oRun.BaseLineOffset = (double)StreamUtils::ReadSHORT(pStream);
// или два последних наоборот????
}
void ConvertPPTTextToEditorStructure(std::vector<CTextPFRunRecord>& oArrayPF, std::vector<CTextCFRunRecord>& oArrayCF,
std::wstring& strText, PPT::CTextAttributesEx& oAttributes)
{
int nCountPFs = (int)oArrayPF.size();
int nCountCFs = (int)oArrayCF.size();
oAttributes.m_arParagraphs.clear();
oAttributes.m_originalText = strText;
int nCurrentPF = 0;
int nCurrentCF = 0;
int nOffsetCF = 0;
int nIndexLast = strText.length();
int nIndexText = 0;
for (int nIndexPF = 0; nIndexPF < nCountPFs; ++nIndexPF)
{
CParagraph elm;
oAttributes.m_arParagraphs.push_back(elm);
PPT::CParagraph* pPar = &oAttributes.m_arParagraphs[nIndexPF];
pPar->m_lTextLevel = oArrayPF[nIndexPF].m_lLevel;
pPar->m_oPFRun = oArrayPF[nIndexPF].m_oRun;
pPar->m_lTextType = oAttributes.m_lTextType;
pPar->m_lStyleThemeIndex = oAttributes.m_lStyleThemeIndex;
int nCountInPF = oArrayPF[nIndexPF].m_lCount;
while (true)
{
if (nCurrentCF >= nCountCFs)
break;
int nCountAdd = oArrayCF[nCurrentCF].m_lCount - nOffsetCF;
int nCountAddTrue = nCountAdd;
if (nIndexText + nCountAdd > nIndexLast)
{
nCountAddTrue = nIndexLast - nIndexText;
if (nCountAddTrue < 0) nCountAddTrue = 0;
}
if (nCountAdd > nCountInPF)
{
nOffsetCF += nCountInPF;
PPT::CSpan oSpan;
oSpan.m_oRun = oArrayCF[nCurrentCF].m_oRun;
nCountAddTrue = nCountInPF;
if (nIndexText + nCountInPF > nIndexLast)
{
nCountAddTrue = nIndexLast - nIndexText;
if (nCountAddTrue < 0) nCountAddTrue = 0;
}
if (nCountAddTrue > 0)
{
oSpan.m_strText = strText.substr(nIndexText, nCountAddTrue);
pPar->m_arSpans.push_back(oSpan);
}
nIndexText += nCountInPF;
break;
}
else if (nCountAdd == nCountInPF)
{
nOffsetCF = 0;
PPT::CSpan oSpan;
oSpan.m_oRun = oArrayCF[nCurrentCF].m_oRun;
if (nCountAddTrue > 0)
{
oSpan.m_strText = strText.substr(nIndexText, nCountAddTrue);
pPar->m_arSpans.push_back(oSpan);
}
nIndexText += nCountAdd;
++nCurrentCF;
break;
}
else
{
nOffsetCF = 0;
PPT::CSpan oSpan;
oSpan.m_oRun = oArrayCF[nCurrentCF].m_oRun;
if (nCountAddTrue > 0)
{
oSpan.m_strText = strText.substr(nIndexText, nCountAddTrue);
pPar->m_arSpans.push_back(oSpan);
}
nIndexText += nCountAdd;
nCountInPF -= nCountAdd;
++nCurrentCF;
}
}
}
}
//------------------------------------------------------------------------------------
CMetaHeader::CMetaHeader()
{
}
void CMetaHeader::FromStream(POLE::Stream* pStream, CRYPT::ECMADecryptor *pDecryptor)
{
BYTE pData[34];
pStream->read(pData, 34);
if (pDecryptor)
{
pDecryptor->Decrypt((char*)pData, 34, 0);
}
MemoryStream memStream(pData, 34, false);
cbSize = memStream.ReadUInt32();
rcBounds.left = memStream.ReadInt32();
rcBounds.top = memStream.ReadInt32();
rcBounds.right = memStream.ReadInt32();
rcBounds.bottom = memStream.ReadInt32();
ptSize.x = memStream.ReadInt32();
ptSize.y = memStream.ReadInt32();
cbSave = memStream.ReadUInt32();
compression = memStream.ReadByte();
filter = memStream.ReadByte();
}
void CMetaHeader::ToEMFHeader(Gdiplus::ENHMETAHEADER3* pHeader)
{
if (NULL == pHeader)
return;
pHeader->iType = 0x00000001;
pHeader->nSize = 88;
pHeader->rclBounds.left = rcBounds.left;
pHeader->rclBounds.top = rcBounds.top;
pHeader->rclBounds.right = rcBounds.right;
pHeader->rclBounds.bottom = rcBounds.bottom;
// нужно перевести в мм
pHeader->rclFrame.left = rcBounds.left;
pHeader->rclFrame.top = rcBounds.top;
pHeader->rclFrame.right = rcBounds.right;
pHeader->rclFrame.bottom = rcBounds.bottom;
pHeader->dSignature = 0x464D4520;
pHeader->nVersion = 0x00010000;
pHeader->nBytes = cbSize;
pHeader->nRecords = 1;
pHeader->nHandles = 0;
pHeader->sReserved = 0;
pHeader->nDescription = 0;
pHeader->offDescription = 0;
pHeader->nPalEntries = 0;
pHeader->szlDevice.cx = 200;
pHeader->szlDevice.cy = 200;
// нужно перевести в мм
pHeader->szlMillimeters.cx = 100;
pHeader->szlMillimeters.cy = 100;
}
void CMetaHeader::ToWMFHeader(Gdiplus::WmfPlaceableFileHeader* pHeader)
{
if (NULL == pHeader)
return;
pHeader->Key = 0x9AC6CDD7;
pHeader->Hmf = 0;
pHeader->BoundingBox.Left = (short)rcBounds.left;
pHeader->BoundingBox.Top = (short)rcBounds.top;
pHeader->BoundingBox.Right = (short)rcBounds.right;
pHeader->BoundingBox.Bottom = (short)rcBounds.bottom;
pHeader->Inch = 1440; // 1:1
pHeader->Reserved = 0;
pHeader->Checksum = 0;
pHeader->Checksum ^= (pHeader->Key & 0x0000FFFFL);
pHeader->Checksum ^= ((pHeader->Key & 0xFFFF0000L) >> 16);
pHeader->Checksum ^= pHeader->Hmf;
pHeader->Checksum ^= pHeader->BoundingBox.Left;
pHeader->Checksum ^= pHeader->BoundingBox.Top;
pHeader->Checksum ^= pHeader->BoundingBox.Right;
pHeader->Checksum ^= pHeader->BoundingBox.Bottom;
pHeader->Checksum ^= pHeader->Inch;
pHeader->Checksum ^= (pHeader->Reserved & 0x0000FFFFL);
pHeader->Checksum ^= ((pHeader->Reserved & 0xFFFF0000L) >> 16);
}
#define CLIPSIZE 12
#define PIXMAPRECSIZE 50
#define HEADERSIZE 40
#define MAXCOLORTABLESIZE 256*8+8
#define OPCODEMISCSIZE 2+8+8+2 /* opcode+srcRect+dstRect+mode */
#define ENDOFPICTSIZE 2
#define PICSIZE PIXMAPRECSIZE + HEADERSIZE + MAXCOLORTABLESIZE + ENDOFPICTSIZE + OPCODEMISCSIZE + CLIPSIZE
void CMetaHeader::ToPICTHeader(BYTE *& pHeader, int & size)
{
short myRowBytes;
short *picPtr;
// short iii;
// long handleSize;
myRowBytes = cbSize & 0x3fff;
//Skip picSize and put out picFrame (10 bytes).
picPtr = (short *)pHeader;
*picPtr++ = (short)myRowBytes;
*picPtr++ = (short)rcBounds.top;
*picPtr++ = (short)rcBounds.left;
*picPtr++ = (short)rcBounds.bottom;
*picPtr++ = (short)rcBounds.right;
// Put out header (30 bytes). This could be done from a resource or taken from an existing picture.
*picPtr++ = 0x11; /* Version opcode. */
*picPtr++ = 0x2ff; /* Version number. */
*picPtr++ = 0xC00; /* Header opcode. */
*picPtr++ = 0xFFFF; /* Put out PICT header version. */
*picPtr++ = 0xFFFF;
//The rest of the header is ignored--0 it out.
for (int iii = 10; iii > 0; iii--)
*picPtr++ = 0; /* Write out 24 bytes of 0. */
/* Put out current port's clip region. */
*picPtr++ = 0x01;
*picPtr++ = 0x0A; /* Clip region only has bounds rectangle. */
*picPtr++ = (short)rcBounds.top;
*picPtr++ = (short)rcBounds.left;
*picPtr++ = (short)rcBounds.bottom;
*picPtr++ = (short)rcBounds.right;
//filter ???
//if(srcBits->pixelType == RGBDirect)
//{ /* Must be 32-bits/pixel */
///* Put out opCode $9A, DirectBitsRect. */
*picPtr++ = 0x9A;
// *picPtr++ = 0; /* BaseAddr for direct pixMaps is 0x000000FF. */
// *picPtr++ = 0xFF;
// PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect,
// dstRect, mode);
// if(PutOutPackedDirectPixData(srcBits, &picPtr)) /* Nonzero
// indicates an error. */
// goto errorExit;
//}
//else
//{
/* Put out opCode $98, PackBitsRect. */
//*picPtr++ = 0x98;
//PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect, dstRect, mode);
//if(PutOutPackedIndexedPixData(srcBits, &picPtr))
//{
// /* Nonzero indicates an error. */
//}
//}
int sz = ((BYTE*)picPtr - pHeader);
size = sz;
}
CMetaFileBuffer::CMetaFileBuffer()
{
m_bIsCompressed = false;
m_bIsValid = false;
m_pMetaHeader = NULL;
m_pMetaFile = NULL;
m_lMetaHeaderSize = 0;
m_lMetaFileSize = 0;
}
CMetaFileBuffer::~CMetaFileBuffer()
{
RELEASEARRAYOBJECTS(m_pMetaHeader);
RELEASEARRAYOBJECTS(m_pMetaFile);
if (m_bIsCompressed)
RELEASEARRAYOBJECTS(m_pMetaFile);
m_bIsCompressed = false;
}
void CMetaFileBuffer::SetHeader(BYTE *pHeader, LONG lSize)
{
m_pMetaHeader = pHeader;
m_lMetaHeaderSize = lSize;
}
void CMetaFileBuffer::SetData(BYTE *pCompress, LONG lCompressSize, LONG lUncompressSize, bool bIsCompressed)
{
m_bIsCompressed = bIsCompressed;
if (!m_bIsCompressed)
{
m_pMetaFile = pCompress;
m_lMetaFileSize = lUncompressSize;
}
else
{
ULONG lSize = lUncompressSize;
m_pMetaFile = new BYTE[lUncompressSize];
bool bRes = NSZip::Decompress(pCompress, (ULONG)lCompressSize, m_pMetaFile, lSize);
if (bRes)
{
m_lMetaFileSize = (LONG)lSize;
m_bIsCompressed = true;
}
else
{
RELEASEARRAYOBJECTS(m_pMetaFile);
m_pMetaFile = pCompress;
m_lMetaFileSize = lUncompressSize;
m_bIsCompressed = false;
}
}
}
int CMetaFileBuffer::ToBuffer(BYTE*& Data)
{
int sz = 0;
if (NULL != m_pMetaHeader) sz += m_lMetaHeaderSize;
if (NULL != m_pMetaFile) sz += m_lMetaFileSize;
Data = new BYTE[sz];
int pos = 0;
if (NULL != m_pMetaHeader)
{
memcpy(Data, (BYTE*)m_pMetaHeader, m_lMetaHeaderSize);
pos += m_lMetaHeaderSize;
}
if (NULL != m_pMetaFile)
{
memcpy(Data + pos, (BYTE*)m_pMetaFile, m_lMetaFileSize);
}
return sz;
}
void CMetaFileBuffer::ToFile(NSFile::CFileBinary *pFile)
{
if (NULL != m_pMetaHeader)
{
pFile->WriteFile(m_pMetaHeader, m_lMetaHeaderSize);
}
if (NULL != m_pMetaFile)
{
pFile->WriteFile(m_pMetaFile, m_lMetaFileSize);
}
}
void SScalingAtom::FromStream(POLE::Stream *pStream)
{
X.FromStream(pStream);
Y.FromStream(pStream);
}
void SRatioAtom::FromStream(POLE::Stream *pStream)
{
Number = StreamUtils::ReadLONG(pStream);
Denom = StreamUtils::ReadLONG(pStream);
}
void SFileIdCluster::ReadFromStream(POLE::Stream *pStream)
{
DrawingGroupID = (UINT)StreamUtils::ReadDWORD(pStream);
CurrentShapeID = (UINT)StreamUtils::ReadDWORD(pStream);
}
}