mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 01:52:24 +08:00
2941 lines
102 KiB
C++
2941 lines
102 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
|
|
*
|
|
*/
|
|
|
|
#include "ShapeContainer.h"
|
|
|
|
#include "../../Drawing/Document.h"
|
|
#include "../../../Common/Vml/PPTShape/ElementSettings.h"
|
|
|
|
#include "../../../../DesktopEditor/raster/BgraFrame.h"
|
|
#include "../../../../DesktopEditor/common/Directory.h"
|
|
#include "../../../../OOXML/Base/Base.h"
|
|
|
|
#include "../../../../OfficeUtils/src/OfficeUtils.h"
|
|
#include "../../Enums/_includer.h"
|
|
#include "../RecordsIncluder.h"
|
|
|
|
#define FIXED_POINT_unsigned(val) (double)((WORD)(val >> 16) + ((WORD)(val) / 65536.0))
|
|
|
|
ULONG xmlName = 1;
|
|
|
|
using namespace ODRAW;
|
|
using namespace PPT;
|
|
|
|
CPPTElement::CPPTElement(const std::wstring& tempPath) : m_tempPath(tempPath)
|
|
{
|
|
}
|
|
bool CPPTElement::ChangeBlack2ColorImage(std::wstring image_path, int rgbColor1, int rgbColor2)
|
|
{
|
|
CBgraFrame bgraFrame;
|
|
|
|
if (bgraFrame.OpenFile(image_path))
|
|
{
|
|
int smpl = abs(bgraFrame.get_Stride() / bgraFrame.get_Width());
|
|
|
|
BYTE * rgb = bgraFrame.get_Data();
|
|
|
|
BYTE R1 = (BYTE)(rgbColor1);
|
|
BYTE G1 = (BYTE)(rgbColor1 >> 8);
|
|
BYTE B1 = (BYTE)(rgbColor1 >> 16);
|
|
|
|
BYTE R2 = (BYTE)(rgbColor2);
|
|
BYTE G2 = (BYTE)(rgbColor2 >> 8);
|
|
BYTE B2 = (BYTE)(rgbColor2 >> 16);
|
|
|
|
for (int i = 0 ; i < bgraFrame.get_Width() * bgraFrame.get_Height(); i++)
|
|
{
|
|
if (rgb[i * smpl + 0 ] == 0x00 && rgb[i * smpl + 1 ] == 0x00 && rgb[i * smpl + 2 ] == 0x00)
|
|
{
|
|
rgb[i * smpl + 0 ] = R1;
|
|
rgb[i * smpl + 1 ] = G1;
|
|
rgb[i * smpl + 2 ] = B1;
|
|
}
|
|
else
|
|
{
|
|
rgb[i * smpl + 0 ] = R2;
|
|
rgb[i * smpl + 1 ] = G2;
|
|
rgb[i * smpl + 2 ] = B2;
|
|
}
|
|
}
|
|
bgraFrame.SaveFile(image_path, 1);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
CColor CPPTElement::CorrectSysColor(int nColorCode, CElementPtr pElement, CTheme* pTheme)
|
|
{
|
|
if (!pElement) return CColor();
|
|
|
|
CColor color;
|
|
|
|
unsigned short nParameter = (unsigned short)(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o
|
|
unsigned short nFunctionBits = (unsigned short)(( nColorCode & 0x00000f00 ) >> 8 );
|
|
unsigned short nAdditionalFlags = (unsigned short)(( nColorCode & 0x0000f000) >> 8 );
|
|
unsigned short nColorIndex = (unsigned short) ( nColorCode & 0x00ff);
|
|
unsigned short nPropColor = 0;
|
|
|
|
switch (nColorIndex)
|
|
{
|
|
case 0xF0: color = pElement->m_oBrush.Color1; break;
|
|
case 0xF1:
|
|
{
|
|
if (pElement->m_bLine) color = pElement->m_oPen.Color;
|
|
else color = pElement->m_oBrush.Color1;
|
|
}break;
|
|
case 0xF2: color = pElement->m_oPen.Color; break;
|
|
case 0xF3: color = pElement->m_oShadow.Color; break;
|
|
case 0xF4: break; ///this
|
|
case 0xF5: color = pElement->m_oBrush.Color2; break;
|
|
case 0xF6: break; //lineBackColor
|
|
case 0xF7: //FillThenLine
|
|
case 0xF8: //colorIndexMask
|
|
color = pElement->m_oBrush.Color1; break;
|
|
default:
|
|
//from table
|
|
break;
|
|
}
|
|
|
|
if (color.m_lSchemeIndex != -1 &&
|
|
(int)pTheme->m_arColorScheme.size() > color.m_lSchemeIndex)
|
|
{
|
|
//extract color (
|
|
|
|
color = pTheme->m_arColorScheme[color.m_lSchemeIndex];
|
|
}
|
|
|
|
//if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive
|
|
// color = CorrectSysColor( nPropColor, pElement);
|
|
|
|
if( nAdditionalFlags & 0x80 ) // make color gray
|
|
{
|
|
BYTE nZwi = 0x7f;//= aColor.GetLuminance();
|
|
color.SetRGB(nZwi, nZwi, nZwi);
|
|
}
|
|
switch( nFunctionBits )
|
|
{
|
|
case 0x01 : // darken color by parameter
|
|
{
|
|
color.SetR ( static_cast<BYTE> ( ( nParameter * color.GetR() ) >> 8 ) );
|
|
color.SetG ( static_cast<BYTE> ( ( nParameter * color.GetG() ) >> 8 ) );
|
|
color.SetB ( static_cast<BYTE> ( ( nParameter * color.GetB() ) >> 8 ) );
|
|
}
|
|
break;
|
|
case 0x02 : // lighten color by parameter
|
|
{
|
|
unsigned short nInvParameter = ( 0x00ff - nParameter ) * 0xff;
|
|
color.SetR( static_cast<BYTE>( ( nInvParameter + ( nParameter * color.GetR() ) ) >> 8 ) );
|
|
color.SetG( static_cast<BYTE>( ( nInvParameter + ( nParameter * color.GetG() ) ) >> 8 ) );
|
|
color.SetB( static_cast<BYTE>( ( nInvParameter + ( nParameter * color.GetB() ) ) >> 8 ) );
|
|
}
|
|
break;
|
|
case 0x03 : // add grey level RGB(p,p,p)
|
|
{
|
|
short nR = (short)color.GetR() + (short)nParameter;
|
|
short nG = (short)color.GetG() + (short)nParameter;
|
|
short nB = (short)color.GetB() + (short)nParameter;
|
|
|
|
if ( nR > 0x00ff ) nR = 0x00ff;
|
|
if ( nG > 0x00ff ) nG = 0x00ff;
|
|
if ( nB > 0x00ff ) nB = 0x00ff;
|
|
|
|
color.SetRGB( (BYTE)nR, (BYTE)nG, (BYTE)nB );
|
|
}
|
|
break;
|
|
case 0x04 : // substract grey level RGB(p,p,p)
|
|
{
|
|
short nR = (short)color.GetR() - (short)nParameter;
|
|
short nG = (short)color.GetG() - (short)nParameter;
|
|
short nB = (short)color.GetB() - (short)nParameter;
|
|
if ( nR < 0 ) nR = 0;
|
|
if ( nG < 0 ) nG = 0;
|
|
if ( nB < 0 ) nB = 0;
|
|
color.SetRGB( (BYTE)nR, (BYTE)nG, (BYTE)nB );
|
|
}
|
|
break;
|
|
case 0x05 : // substract from gray level RGB(p,p,p)
|
|
{
|
|
short nR = (short)nParameter - (short)color.GetR();
|
|
short nG = (short)nParameter - (short)color.GetG();
|
|
short nB = (short)nParameter - (short)color.GetB();
|
|
if ( nR < 0 ) nR = 0;
|
|
if ( nG < 0 ) nG = 0;
|
|
if ( nB < 0 ) nB = 0;
|
|
color.SetRGB( (BYTE)nR, (BYTE)nG, (BYTE)nB );
|
|
}
|
|
break;
|
|
case 0x06 : // per component: black if < p, white if >= p
|
|
{
|
|
color.SetR( color.GetR() < nParameter ? 0x00 : 0xff );
|
|
color.SetG( color.GetG() < nParameter ? 0x00 : 0xff );
|
|
color.SetB( color.GetB() < nParameter ? 0x00 : 0xff );
|
|
}
|
|
break;
|
|
}
|
|
if ( nAdditionalFlags & 0x40 ) // top-bit invert
|
|
color.SetRGB( color.GetR() ^ 0x80, color.GetG() ^ 0x80, color.GetB() ^ 0x80 );
|
|
|
|
if ( nAdditionalFlags & 0x20 ) // invert color
|
|
color.SetRGB(0xff - color.GetR(), 0xff - color.GetG(), 0xff - color.GetB());
|
|
|
|
return color;
|
|
}
|
|
void CPPTElement::SetUpProperties(CElementPtr pElement, CTheme* pTheme, CSlideInfo* pWrapper, CSlide* pSlide, CProperties* pProperties, bool reset_default)
|
|
{
|
|
size_t lCount = pProperties->m_lCount;
|
|
switch (pElement->m_etType)
|
|
{
|
|
case PPT::etVideo:
|
|
{
|
|
if (reset_default)
|
|
{
|
|
pElement->m_bLine = false;
|
|
}
|
|
for (size_t i = 0; i < lCount; ++i)
|
|
{
|
|
SetUpPropertyVideo(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]);
|
|
}
|
|
}break;
|
|
case PPT::etPicture:
|
|
case PPT::etOleObject:
|
|
{
|
|
if (reset_default)
|
|
{
|
|
pElement->m_bIsFilled = false;
|
|
pElement->m_bLine = false;
|
|
pElement->m_oBrush.Type = c_BrushTypeTexture; // or 3000 set ???
|
|
}
|
|
for (size_t i = 0; i < lCount; ++i)
|
|
{
|
|
SetUpPropertyImage(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]);
|
|
}
|
|
if (false == pElement->m_bIsFilled)
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeNoFill;
|
|
}
|
|
else if (pElement->m_oBrush.Type == c_BrushTypeTexture)
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeSolid;
|
|
}
|
|
}break;
|
|
case PPT::etAudio:
|
|
{
|
|
if (reset_default)
|
|
{
|
|
pElement->m_bIsFilled = false;
|
|
pElement->m_bLine = false;
|
|
}
|
|
for (size_t i = 0; i < lCount; ++i)
|
|
{
|
|
SetUpPropertyAudio(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]);
|
|
}
|
|
}break;
|
|
case PPT::etGroup:
|
|
{
|
|
if (reset_default)
|
|
{
|
|
pElement->m_bLine = false;
|
|
pElement->m_bIsFilled = false;
|
|
}
|
|
for (size_t i = 0; i < lCount; ++i)
|
|
{
|
|
SetUpProperty(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]);
|
|
}
|
|
}break;
|
|
case PPT::etShape:
|
|
{
|
|
CShapeElement* pShapeElem = dynamic_cast<CShapeElement*>(pElement.get());
|
|
CPPTShape* pPPTShape = dynamic_cast<CPPTShape*>(pShapeElem->m_pShape->getBaseShape().get());
|
|
|
|
if (NULL != pPPTShape)
|
|
{
|
|
pPPTShape->m_oCustomVML.SetAdjusts(&pPPTShape->m_arAdjustments);
|
|
}
|
|
|
|
for (size_t i = 0; i < lCount; ++i)
|
|
{
|
|
SetUpPropertyShape(pElement, pTheme, pWrapper, pSlide, &pProperties->m_arProperties[i]);
|
|
}
|
|
|
|
if (false == pElement->m_bIsFilled)
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeNoFill;
|
|
}
|
|
else if (pElement->m_oBrush.Type == c_BrushTypeNotSet &&
|
|
(pElement->m_lPlaceholderType == 0 && pElement->m_lPlaceholderID < 0))
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeSolid;
|
|
}
|
|
|
|
if (NULL != pPPTShape)
|
|
{
|
|
pPPTShape->m_oCustomVML.ToCustomShape(pPPTShape, pPPTShape->m_oManager);
|
|
pPPTShape->ReCalculate();
|
|
}
|
|
}break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CPPTElement::SetUpProperty(CElementPtr pElement, CTheme* pTheme, CSlideInfo* pInfo, CSlide* pSlide, CProperty* pProperty)
|
|
{
|
|
switch (pProperty->m_ePID)
|
|
{
|
|
case wzName:
|
|
{
|
|
pElement->m_sName = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)pProperty->m_pOptions, pProperty->m_lValue /2 - 1);
|
|
}break;
|
|
case wzDescription:
|
|
{
|
|
pElement->m_sDescription = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)pProperty->m_pOptions, pProperty->m_lValue /2 - 1);
|
|
}break;
|
|
case hspMaster:
|
|
{
|
|
pElement->m_lLayoutID = (LONG)pProperty->m_lValue;
|
|
}break;
|
|
case ePropertyId_rotation:
|
|
{
|
|
pElement->m_dRotate = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ePropertyId_fFlipH:
|
|
{
|
|
BYTE flag1 = (BYTE)pProperty->m_lValue;
|
|
BYTE flag3 = (BYTE)(pProperty->m_lValue >> 16);
|
|
|
|
bool bFlipH = (0x01 == (0x01 & flag1));
|
|
bool bFlipV = (0x02 == (0x02 & flag1));
|
|
|
|
bool bUseFlipH = (0x01 == (0x01 & flag3));
|
|
bool bUseFlipV = (0x02 == (0x02 & flag3));
|
|
|
|
if (bUseFlipH)
|
|
pElement->m_bFlipH = bFlipH;
|
|
|
|
if (bUseFlipV)
|
|
pElement->m_bFlipV = bFlipV;
|
|
}break;
|
|
case fillType:
|
|
{
|
|
_UINT32 dwType = pProperty->m_lValue;
|
|
switch(dwType)
|
|
{
|
|
case ODRAW::fillPattern:
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypePattern;
|
|
//texture + change black to color2, white to color1
|
|
}break;
|
|
case ODRAW::fillTexture :
|
|
case ODRAW::fillPicture :
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeTexture;
|
|
pElement->m_oBrush.TextureMode = (ODRAW::fillPicture == dwType) ? c_BrushTextureModeStretch : c_BrushTextureModeTile;
|
|
}break;
|
|
case ODRAW::fillShadeCenter://1 color
|
|
case ODRAW::fillShadeShape:
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeCenter;
|
|
}break;//
|
|
case ODRAW::fillShadeTitle://2 colors and more
|
|
case ODRAW::fillShade :
|
|
case ODRAW::fillShadeScale:
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypePathGradient1;
|
|
}break;
|
|
case ODRAW::fillBackground:
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeNoFill;
|
|
}break;
|
|
}
|
|
}break;
|
|
case fillBlip:
|
|
{
|
|
int dwOffset = 0 ;
|
|
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
//inline
|
|
dwOffset = -1;
|
|
}
|
|
else
|
|
{
|
|
dwOffset = pInfo->GetIndexPicture(pProperty->m_lValue);
|
|
}
|
|
int nLen = pElement->m_oBrush.TexturePath.length() - 1;
|
|
int nIndex = pElement->m_oBrush.TexturePath.rfind(FILE_SEPARATOR_CHAR);
|
|
if (nLen != nIndex)
|
|
{
|
|
pElement->m_oBrush.TexturePath.erase(nIndex + 1, nLen - nIndex);
|
|
}
|
|
|
|
pElement->m_oBrush.TexturePath = pElement->m_oBrush.TexturePath + pInfo->GetFileNamePicture(dwOffset);
|
|
if (pElement->m_oBrush.Type == c_BrushTypePattern)
|
|
{
|
|
int rgbColor1 = 0xFFFFFF;
|
|
int rgbColor2 = 0;
|
|
|
|
if (pElement->m_oBrush.Color1.m_lSchemeIndex == -1)
|
|
{
|
|
rgbColor1 = pElement->m_oBrush.Color1.GetLONG_RGB();
|
|
}
|
|
else
|
|
{
|
|
if ((pSlide) && (pSlide->m_arColorScheme.size() > 0))
|
|
{
|
|
rgbColor1 = pSlide->m_arColorScheme[pElement->m_oBrush.Color1.m_lSchemeIndex].GetLONG_RGB();
|
|
}
|
|
else if ((pTheme) && (pTheme->m_arColorScheme.size() > 0))
|
|
{
|
|
rgbColor1 = pTheme->m_arColorScheme[pElement->m_oBrush.Color1.m_lSchemeIndex].GetLONG_RGB();
|
|
}
|
|
}
|
|
if (pElement->m_oBrush.Color2.m_lSchemeIndex == -1)
|
|
{
|
|
rgbColor2 = pElement->m_oBrush.Color2.GetLONG_RGB();
|
|
}
|
|
else
|
|
{
|
|
if ((pSlide) && (pSlide->m_arColorScheme.size() > 0))
|
|
{
|
|
rgbColor2 = pSlide->m_arColorScheme[pElement->m_oBrush.Color2.m_lSchemeIndex].GetLONG_RGB();
|
|
}
|
|
else if ((pTheme) && (pTheme->m_arColorScheme.size() > 0))
|
|
{
|
|
rgbColor2 = pTheme->m_arColorScheme[pElement->m_oBrush.Color2.m_lSchemeIndex].GetLONG_RGB();
|
|
}
|
|
}
|
|
ChangeBlack2ColorImage(pElement->m_oBrush.TexturePath, rgbColor2, rgbColor1);
|
|
|
|
pElement->m_oBrush.Type = c_BrushTypeTexture;
|
|
pElement->m_oBrush.TextureMode = c_BrushTextureModeTile;
|
|
}
|
|
}break;
|
|
case fillColor:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
if(oAtom.bSysIndex)
|
|
pElement->m_oBrush.Color1 = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else
|
|
oAtom.ToColor(&pElement->m_oBrush.Color1);
|
|
|
|
if (pElement->m_oBrush.Type == c_BrushTypeNotSet )
|
|
pElement->m_oBrush.Type = c_BrushTypeSolid;
|
|
|
|
}break;
|
|
case fillBackColor:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
if(oAtom.bSysIndex)
|
|
pElement->m_oBrush.Color2 = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else
|
|
oAtom.ToColor(&pElement->m_oBrush.Color2);
|
|
|
|
if (pElement->m_bIsBackground && pElement->m_oBrush.Type == c_BrushTypeNotSet )
|
|
{
|
|
pElement->m_oBrush.Type = c_BrushTypeSolid;
|
|
}
|
|
}break;
|
|
case fillOpacity:
|
|
{
|
|
pElement->m_oBrush.Alpha1 = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
|
}break;
|
|
case fillBackOpacity:
|
|
{
|
|
pElement->m_oBrush.Alpha2 = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
|
}break;
|
|
case fillAngle:
|
|
{
|
|
pElement->m_oBrush.LinearAngle = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case fillRectLeft:
|
|
{
|
|
pElement->m_oBrush.Rect.X = pProperty->m_lValue;
|
|
pElement->m_oBrush.Rectable = true;
|
|
}break;
|
|
case fillRectRight:
|
|
{
|
|
pElement->m_oBrush.Rect.Width = pProperty->m_lValue - pElement->m_oBrush.Rect.X;
|
|
pElement->m_oBrush.Rectable = true;
|
|
}break;
|
|
case fillRectTop:
|
|
{
|
|
pElement->m_oBrush.Rect.Y = pProperty->m_lValue;
|
|
pElement->m_oBrush.Rectable = true;
|
|
}break;
|
|
case fillRectBottom:
|
|
{
|
|
pElement->m_oBrush.Rect.Height = pProperty->m_lValue - pElement->m_oBrush.Rect.Y;
|
|
pElement->m_oBrush.Rectable = true;
|
|
}break;
|
|
case fillBackground:
|
|
{
|
|
}break;
|
|
case fillShadeType:
|
|
{
|
|
bool bShadeNone = GETBIT(pProperty->m_lValue, 31);
|
|
bool bShadeGamma = GETBIT(pProperty->m_lValue, 30);
|
|
bool bShadeSigma = GETBIT(pProperty->m_lValue, 29);
|
|
bool bShadeBand = GETBIT(pProperty->m_lValue, 28);
|
|
bool bShadeOneColor = GETBIT(pProperty->m_lValue, 27);
|
|
|
|
}break;
|
|
case fillFocus://relative position of the last color in the shaded fill
|
|
{
|
|
pElement->m_oBrush.Focus = pProperty->m_lValue;
|
|
}break;
|
|
case fillShadePreset:
|
|
{//value (int) from 0x00000088 through 0x0000009F or complex
|
|
}break;
|
|
case fillShadeColors:
|
|
{
|
|
unsigned short nElems = pProperty->m_lValue/8;
|
|
_INT32* pCompl = (_INT32*)pProperty->m_pOptions;
|
|
|
|
while(nElems--)
|
|
{
|
|
CColor color;
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(*pCompl); pCompl++;
|
|
oAtom.ToColor(&color);
|
|
|
|
_UINT32 dwPosition = *pCompl; pCompl++;
|
|
pElement->m_oBrush.ColorsPosition.push_back(std::pair<CColor, double>(color, 100. * FIXED_POINT_unsigned(dwPosition)));
|
|
}
|
|
}break;
|
|
case fillStyleBooleanProperties:
|
|
{
|
|
BYTE flag1 = (BYTE)(pProperty->m_lValue);
|
|
BYTE flag2 = (BYTE)(pProperty->m_lValue >> 16);
|
|
|
|
bool bNoFillHitTest = (0x01 == (0x01 & flag1));
|
|
bool bFillUseRect = (0x02 == (0x02 & flag1));
|
|
bool bFillShape = (0x04 == (0x04 & flag1));
|
|
bool bHitTestFill = (0x08 == (0x08 & flag1));
|
|
bool bFilled = (0x10 == (0x10 & flag1));
|
|
bool bUseShapeAnchor = (0x20 == (0x20 & flag1));
|
|
bool bRecolorFillAsPictures = (0x40 == (0x40 & flag1));
|
|
|
|
bool bUsebNoFillHitTest = (0x01 == (0x01 & flag2));
|
|
bool bUsebFillUseRect = (0x02 == (0x02 & flag2));
|
|
bool bUsebFillShape = (0x04 == (0x04 & flag2));
|
|
bool bUsebHitTestFill = (0x08 == (0x08 & flag2));
|
|
bool bUsebFilled = (0x10 == (0x10 & flag2));
|
|
bool bUsebUseShapeAnchor = (0x20 == (0x20 & flag2));
|
|
bool bUsebRecolorFillAsPictures = (0x40 == (0x40 & flag2));
|
|
|
|
if (bUsebFilled)
|
|
{
|
|
pElement->m_bIsFilled = bFilled;
|
|
if (pElement->m_oBrush.Type == c_BrushTypeNotSet)
|
|
pElement->m_oBrush.Type = c_BrushTypeSolid;
|
|
}
|
|
|
|
|
|
break;
|
|
}
|
|
case ODRAW::geometryBooleanProperties:
|
|
{
|
|
BYTE flag1 = (BYTE)(pProperty->m_lValue);
|
|
BYTE flag2 = (BYTE)(pProperty->m_lValue >> 8);
|
|
BYTE flag3 = (BYTE)(pProperty->m_lValue >> 16);
|
|
BYTE flag4 = (BYTE)(pProperty->m_lValue >> 24);
|
|
|
|
bool bFillOk = (0x01 == (0x01 & flag1));
|
|
bool bFillShadeShapeOk = (0x02 == (0x02 & flag1));
|
|
bool bGTextOk = (0x04 == (0x04 & flag1));
|
|
bool bLineOk = (0x08 == (0x08 & flag1));
|
|
bool b3DOk = (0x10 == (0x10 & flag1));
|
|
bool bShadowOk = (0x20 == (0x20 & flag1));
|
|
|
|
bool bUseFillOk = (0x01 == (0x01 & flag3));
|
|
bool bUseFillShadeShapeOk = (0x02 == (0x02 & flag3));
|
|
bool bUseGTextOk = (0x04 == (0x04 & flag3));
|
|
bool bUseLineOk = (0x08 == (0x08 & flag3));
|
|
bool bUse3DOk = (0x10 == (0x10 & flag3));
|
|
bool bUseShadowOk = (0x20 == (0x20 & flag3));
|
|
|
|
//if (bUseLineOk)
|
|
// pElement->m_bLine = bLineOk;//?? todooo check - doesn't work ! 1 (82).ppt
|
|
|
|
if (bUseFillOk)
|
|
pElement->m_bIsFilled = bFillOk;
|
|
|
|
break;
|
|
}
|
|
// line --------------------------------------------------------
|
|
case lineStyleBooleanProperties: //Line Style Boolean Properties
|
|
{
|
|
bool bUsefLineOpaqueBackColor = GETBIT(pProperty->m_lValue, 25);
|
|
bool bUsefInsetPen = GETBIT(pProperty->m_lValue, 22);
|
|
bool bUsefInsetPenOK = GETBIT(pProperty->m_lValue, 21);
|
|
bool bUsefArrowheadsOK = GETBIT(pProperty->m_lValue, 20);
|
|
bool bUsefLine = GETBIT(pProperty->m_lValue, 19);
|
|
bool bUsefHitTestLine = GETBIT(pProperty->m_lValue, 18);
|
|
bool bUsefLineFillShape = GETBIT(pProperty->m_lValue, 17);
|
|
bool bUsefNoLineDrawDash = GETBIT(pProperty->m_lValue, 16);
|
|
|
|
bool bLineOpaqueBackColor = GETBIT(pProperty->m_lValue, 9);
|
|
bool bInsetPen = GETBIT(pProperty->m_lValue, 6);
|
|
bool bInsetPenOK = GETBIT(pProperty->m_lValue, 5);
|
|
bool bArrowheadsOK = GETBIT(pProperty->m_lValue, 4);
|
|
bool bLine = GETBIT(pProperty->m_lValue, 3);
|
|
bool bHitTestLine = GETBIT(pProperty->m_lValue, 2);
|
|
bool bLineFillShape = GETBIT(pProperty->m_lValue, 1);
|
|
bool bNoLineDrawDash = GETBIT(pProperty->m_lValue, 0);
|
|
|
|
if (bUsefLine)
|
|
pElement->m_bLine = bLine;
|
|
}break;
|
|
case lineDashStyle://from Complex
|
|
{
|
|
pElement->m_bLine = true;
|
|
}break;
|
|
case lineColor:
|
|
{
|
|
pElement->m_bLine = true;
|
|
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
if (oAtom.bSysIndex)
|
|
pElement->m_oPen.Color = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else
|
|
oAtom.ToColor(&pElement->m_oPen.Color);
|
|
}break;
|
|
case lineOpacity:
|
|
{
|
|
pElement->m_oPen.Alpha = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
|
}break;
|
|
case lineBackColor:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
if (oAtom.bSysIndex)
|
|
pElement->m_oPen.Color2 = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else
|
|
oAtom.ToColor(&pElement->m_oPen.Color2);
|
|
|
|
}break;
|
|
case lineWidth:
|
|
{
|
|
pElement->m_oPen.Size = pProperty->m_lValue;
|
|
pElement->m_bLine = true;
|
|
}break;
|
|
case lineStyle:
|
|
{
|
|
pElement->m_bLine = true;
|
|
pElement->m_oPen.LineStyle = pProperty->m_lValue;
|
|
}break;
|
|
case lineDashing:
|
|
{
|
|
pElement->m_bLine = true;
|
|
pElement->m_oPen.DashStyle = pProperty->m_lValue;
|
|
}break;
|
|
case lineJoinStyle:
|
|
{
|
|
pElement->m_oPen.LineJoin = pProperty->m_lValue;
|
|
}break;
|
|
case lineStartArrowLength:
|
|
{
|
|
pElement->m_oPen.LineStartLength = pProperty->m_lValue;
|
|
}break;
|
|
case lineEndArrowLength:
|
|
{
|
|
pElement->m_oPen.LineEndLength = pProperty->m_lValue;
|
|
}break;
|
|
case lineStartArrowWidth:
|
|
{
|
|
pElement->m_oPen.LineStartWidth = pProperty->m_lValue;
|
|
}break;
|
|
case lineEndArrowWidth:
|
|
{
|
|
pElement->m_oPen.LineEndWidth = pProperty->m_lValue;
|
|
}break;
|
|
case lineStartArrowhead:
|
|
{
|
|
pElement->m_oPen.LineStartCap = pProperty->m_lValue;
|
|
}break;
|
|
case lineEndArrowhead:
|
|
{
|
|
pElement->m_oPen.LineEndCap = pProperty->m_lValue;
|
|
}break;
|
|
case shadowType:
|
|
{
|
|
pElement->m_oShadow.Type = pProperty->m_lValue;
|
|
}break;
|
|
case shadowOriginX://in emu, relative from center shape
|
|
{
|
|
pElement->m_oShadow.OriginX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case shadowOriginY:
|
|
{
|
|
pElement->m_oShadow.OriginY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case shadowColor:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
if (oAtom.bSysIndex)
|
|
pElement->m_oShadow.Color = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else
|
|
oAtom.ToColor(&pElement->m_oShadow.Color);
|
|
|
|
}break;
|
|
case shadowWeight:
|
|
{
|
|
}break;
|
|
case shadowOpacity:
|
|
{
|
|
pElement->m_oShadow.Alpha = (BYTE)(std::min)(255, (int)CDirectory::NormFixedPoint(pProperty->m_lValue, 255));
|
|
}break;
|
|
case shadowHighlight:
|
|
{
|
|
//double shadow tint
|
|
}break;
|
|
case shadowOffsetX:
|
|
{//signed
|
|
pElement->m_oShadow.DistanceX = (_INT32)pProperty->m_lValue;
|
|
}break;
|
|
case shadowOffsetY:
|
|
{//signed
|
|
pElement->m_oShadow.DistanceY = (_INT32)pProperty->m_lValue;
|
|
}break;
|
|
case shadowScaleXToX:
|
|
{
|
|
pElement->m_oShadow.ScaleXToX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case shadowScaleYToX:
|
|
{
|
|
pElement->m_oShadow.ScaleYToX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case shadowScaleXToY:
|
|
{
|
|
pElement->m_oShadow.ScaleXToY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case shadowScaleYToY:
|
|
{
|
|
pElement->m_oShadow.ScaleYToY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case shadowPerspectiveX:
|
|
{
|
|
pElement->m_oShadow.PerspectiveX = pProperty->m_lValue;
|
|
}break;
|
|
case shadowPerspectiveY:
|
|
{
|
|
pElement->m_oShadow.PerspectiveY = pProperty->m_lValue;
|
|
}break;
|
|
case shadowStyleBooleanProperties:
|
|
{
|
|
bool fshadowObscured = GETBIT(pProperty->m_lValue, 0);
|
|
bool fShadow = GETBIT(pProperty->m_lValue, 1);
|
|
bool fUsefshadowObscured = GETBIT(pProperty->m_lValue, 16);
|
|
bool fUsefShadow = GETBIT(pProperty->m_lValue, 17);
|
|
|
|
if (fUsefShadow)
|
|
pElement->m_oShadow.Visible = fShadow;
|
|
|
|
if (!fUsefShadow && fUsefshadowObscured)
|
|
{
|
|
//outline
|
|
pElement->m_oShadow.Visible = fshadowObscured;
|
|
}
|
|
}break;
|
|
case shapeBoolean:
|
|
{
|
|
bool fUsefPolicyLabel = GETBIT(pProperty->m_lValue, 25);
|
|
bool fUsefPolicyBarcode = GETBIT(pProperty->m_lValue, 24);
|
|
bool fUsefFlipHOverride = GETBIT(pProperty->m_lValue, 23);
|
|
bool fUsefFlipVOverride = GETBIT(pProperty->m_lValue, 22);
|
|
bool fUsefOleIcon = GETBIT(pProperty->m_lValue, 21);
|
|
bool fUsefPreferRelativeResize = GETBIT(pProperty->m_lValue, 20);
|
|
bool fUsefLockShapeType = GETBIT(pProperty->m_lValue, 19);
|
|
bool fUsefInitiator = GETBIT(pProperty->m_lValue, 18);
|
|
bool fUsefBackground = GETBIT(pProperty->m_lValue, 16);
|
|
|
|
bool fPolicyLabel = fUsefPolicyLabel ? GETBIT(pProperty->m_lValue, 9) : false;
|
|
bool fPolicyBarcode = fUsefPolicyBarcode ? GETBIT(pProperty->m_lValue, 8) : false;
|
|
bool fFlipHOverride = fUsefFlipHOverride ? GETBIT(pProperty->m_lValue, 7) : false;
|
|
bool fFlipVOverride = fUsefFlipVOverride ? GETBIT(pProperty->m_lValue, 6) : false;
|
|
bool fOleIcon = fUsefOleIcon ? GETBIT(pProperty->m_lValue, 5) : false;
|
|
bool fPreferRelativeResize = fUsefPreferRelativeResize ? GETBIT(pProperty->m_lValue, 4) : false;
|
|
bool fLockShapeType = fUsefLockShapeType ? GETBIT(pProperty->m_lValue, 3) : false;
|
|
bool fInitiator = fUsefInitiator ? GETBIT(pProperty->m_lValue, 2) : false;
|
|
bool fBackground = fUsefBackground ? GETBIT(pProperty->m_lValue, 0) : false;
|
|
}break;
|
|
case groupShapeBooleanProperties:
|
|
{
|
|
bool fUsefLayoutInCell = GETBIT(pProperty->m_lValue, 31);
|
|
bool fUsefIsBullet = GETBIT(pProperty->m_lValue, 30);
|
|
bool fUsefStandardHR = GETBIT(pProperty->m_lValue, 29);
|
|
bool fUsefNoshadeHR = GETBIT(pProperty->m_lValue, 28);
|
|
bool fUsefHorizRule = GETBIT(pProperty->m_lValue, 27);
|
|
bool fUsefUserDrawn = GETBIT(pProperty->m_lValue, 26);
|
|
bool fUsefAllowOverlap = GETBIT(pProperty->m_lValue, 25);
|
|
bool fUsefReallyHidden = GETBIT(pProperty->m_lValue, 24);
|
|
bool fUsefScriptAnchor = GETBIT(pProperty->m_lValue, 23);
|
|
bool fUsefEditedWrap = GETBIT(pProperty->m_lValue, 22);
|
|
bool fUsefBehindDocument = GETBIT(pProperty->m_lValue, 21);
|
|
bool fUsefOnDblClickNotify = GETBIT(pProperty->m_lValue, 20);
|
|
bool fUsefIsButton = GETBIT(pProperty->m_lValue, 19);
|
|
bool fUsefOneD = GETBIT(pProperty->m_lValue, 18);
|
|
bool fUsefHidden = GETBIT(pProperty->m_lValue, 17);
|
|
bool fUsefPrint = GETBIT(pProperty->m_lValue, 16);
|
|
|
|
bool fLayoutInCell = fUsefLayoutInCell ? GETBIT(pProperty->m_lValue, 15) : true;
|
|
bool fIsBullet = fUsefIsBullet ? GETBIT(pProperty->m_lValue, 14) : false;
|
|
bool fStandardHR = fUsefStandardHR ? GETBIT(pProperty->m_lValue, 13) : false;
|
|
bool fNoshadeHR = fUsefNoshadeHR ? GETBIT(pProperty->m_lValue, 12) : false;
|
|
bool fHorizRule = fUsefHorizRule ? GETBIT(pProperty->m_lValue, 11) : false;
|
|
bool fUserDrawn = fUsefUserDrawn ? GETBIT(pProperty->m_lValue, 10) : false;
|
|
bool fAllowOverlap = fUsefAllowOverlap ? GETBIT(pProperty->m_lValue, 9) : true;
|
|
bool fReallyHidden = fUsefReallyHidden ? GETBIT(pProperty->m_lValue, 8) : false;
|
|
bool fScriptAnchor = fUsefScriptAnchor ? GETBIT(pProperty->m_lValue, 7) : false;
|
|
bool fEditedWrap = fUsefEditedWrap ? GETBIT(pProperty->m_lValue, 6) : false;
|
|
bool fBehindDocument = fUsefBehindDocument ? GETBIT(pProperty->m_lValue, 5) : false;
|
|
bool fOnDblClickNotify = fUsefOnDblClickNotify ? GETBIT(pProperty->m_lValue, 4) : false;
|
|
bool fIsButton = fUsefIsButton ? GETBIT(pProperty->m_lValue, 3) : false;
|
|
bool fOneD = fUsefOneD ? GETBIT(pProperty->m_lValue, 2) : false;
|
|
bool fHidden = fUsefHidden ? GETBIT(pProperty->m_lValue, 1) : false;
|
|
bool fPrint = fUsefPrint ? GETBIT(pProperty->m_lValue, 0) : true;
|
|
|
|
pElement->m_bHidden = fHidden || fIsBullet;
|
|
//presentation_ticio_20100610.ppt
|
|
}break;
|
|
case tableProperties:
|
|
case tableRowProperties:
|
|
{
|
|
pElement->m_etType = etTable;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CPPTElement::SetUpPropertyVideo(CElementPtr pElement, CTheme* pTheme, CSlideInfo* pInfo, CSlide* pSlide, CProperty* pProperty)
|
|
{
|
|
SetUpPropertyImage(pElement, pTheme, pInfo, pSlide, pProperty);
|
|
}
|
|
void CPPTElement::SetUpPropertyAudio(CElementPtr pElement, CTheme* pTheme, CSlideInfo* pInfo, CSlide* pSlide, CProperty* pProperty)
|
|
{
|
|
SetUpPropertyImage(pElement, pTheme, pInfo, pSlide, pProperty);
|
|
}
|
|
void CPPTElement::SetUpPropertyImage(CElementPtr pElement, CTheme* pTheme, CSlideInfo* pInfo, CSlide* pSlide, CProperty* pProperty)
|
|
{
|
|
SetUpProperty(pElement, pTheme, pInfo, pSlide, pProperty);
|
|
|
|
CImageElement* image_element = dynamic_cast<CImageElement*>(pElement.get());
|
|
|
|
switch(pProperty->m_ePID)
|
|
{
|
|
case pib:
|
|
{
|
|
int dwOffset = pInfo->GetIndexPicture(pProperty->m_lValue);
|
|
if (dwOffset >=0)
|
|
{
|
|
image_element->m_strImageFileName += pInfo->GetFileNamePicture(dwOffset);
|
|
image_element->m_bImagePresent = true;
|
|
}
|
|
}break;
|
|
case pictureId://OLE identifier of the picture.
|
|
{
|
|
image_element->m_bOLE = true;
|
|
}break;
|
|
case pibName:
|
|
{
|
|
image_element->m_sImageName = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)pProperty->m_pOptions, pProperty->m_lValue /2-1);
|
|
// TextMining05.ppt, slide 20 - incorrect name ( - todooo clean it up later
|
|
}break;
|
|
case cropFromTop:
|
|
{
|
|
image_element->m_lcropFromTop = (_INT32)pProperty->m_lValue;
|
|
image_element->m_bCropEnabled = true;
|
|
}break;
|
|
case cropFromBottom:
|
|
{
|
|
image_element->m_lcropFromBottom = (_INT32)pProperty->m_lValue;
|
|
image_element->m_bCropEnabled = true;
|
|
}break;
|
|
case cropFromLeft:
|
|
{
|
|
image_element->m_lcropFromLeft = (_INT32)pProperty->m_lValue;
|
|
image_element->m_bCropEnabled = true;
|
|
}break;
|
|
case cropFromRight:
|
|
{
|
|
image_element->m_lcropFromRight = (_INT32)pProperty->m_lValue;
|
|
image_element->m_bCropEnabled = true;
|
|
}break;
|
|
case pibFlags:
|
|
{
|
|
}break;
|
|
case pictureContrast:
|
|
image_element->m_lpictureContrast = (_INT32)pProperty->m_lValue;
|
|
break;
|
|
case pictureBrightness:
|
|
image_element->m_lpictureBrightness = (_INT32)pProperty->m_lValue;
|
|
break;
|
|
case fillBackColor:
|
|
// TODO to fix 53541
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
void CPPTElement::SetUpPropertyShape(CElementPtr pElement, CTheme* pTheme, CSlideInfo* pInfo, CSlide* pSlide, CProperty* pProperty)
|
|
{
|
|
SetUpProperty(pElement, pTheme, pInfo, pSlide, pProperty);
|
|
|
|
CShapeElement* shape_element = dynamic_cast<CShapeElement*>(pElement.get());
|
|
|
|
CShapePtr pParentShape = shape_element->m_pShape;
|
|
if (NULL == pParentShape)
|
|
return;
|
|
|
|
CPPTShape* pShape = dynamic_cast<CPPTShape*>(pParentShape->getBaseShape().get());
|
|
|
|
if (NULL == pShape)
|
|
return;
|
|
|
|
switch (pProperty->m_ePID)
|
|
{
|
|
case ODRAW::metroBlob:
|
|
{
|
|
NSFile::CFileBinary file;
|
|
std::wstring tempFileName = NSFile::CFileBinary::CreateTempFileWithUniqueName(m_tempPath, L"Blob") + L".zip";
|
|
|
|
if (file.CreateFileW(tempFileName))
|
|
{
|
|
file.WriteFile(pProperty->m_pOptions, pProperty->m_lValue);
|
|
file.CloseFile();
|
|
}
|
|
COfficeUtils officeUtils(NULL);
|
|
|
|
BYTE *utf8Data = NULL;
|
|
ULONG utf8DataSize = 0;
|
|
if (S_OK != officeUtils.LoadFileFromArchive(tempFileName, L"drs/shapexml.xml", &utf8Data, utf8DataSize))
|
|
{
|
|
officeUtils.LoadFileFromArchive(tempFileName, L"drs/diagrams/drawing1.xml", &utf8Data, utf8DataSize);
|
|
}
|
|
|
|
if (utf8Data && utf8DataSize > 0)
|
|
{
|
|
pParentShape->m_strXmlString = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(utf8Data, utf8DataSize);
|
|
// std::string filename = std::to_string(nRTCounter++) + "_shape.xml";
|
|
// std::ofstream file("data/" + filename, std::ios::out);
|
|
// file.write((char*)utf8Data, utf8DataSize);
|
|
// file.close();
|
|
|
|
delete []utf8Data;
|
|
}
|
|
NSFile::CFileBinary::Remove(tempFileName);
|
|
}break;
|
|
case ODRAW::geoRight:
|
|
{
|
|
if (0 < pProperty->m_lValue)
|
|
pParentShape->m_dWidthLogic = (double)(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::geoBottom:
|
|
{
|
|
if (0 < pProperty->m_lValue)
|
|
pParentShape->m_dHeightLogic = (double)(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::shapePath:
|
|
{
|
|
pShape->m_oCustomVML.SetPath((RulesType)pProperty->m_lValue);
|
|
pShape->m_bCustomShape = true;
|
|
}break;
|
|
case ODRAW::pSegmentInfo:
|
|
{
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
pShape->m_oCustomVML.LoadSegments(pProperty);
|
|
pShape->m_bCustomShape = true;
|
|
}
|
|
}break;
|
|
case ODRAW::pVertices:
|
|
{
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
pShape->m_oCustomVML.LoadVertices(pProperty);
|
|
pShape->m_bCustomShape = true;
|
|
}
|
|
}break;
|
|
case ODRAW::pConnectionSites:
|
|
{
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
pShape->m_oCustomVML.LoadConnectionSites(pProperty);
|
|
}
|
|
}break;
|
|
case ODRAW::pConnectionSitesDir:
|
|
{
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
pShape->m_oCustomVML.LoadConnectionSitesDir(pProperty);
|
|
}
|
|
}break;
|
|
case ODRAW::pGuides:
|
|
{
|
|
if (pProperty->m_bComplex/* && pShape->m_eType != sptNotchedCircularArrow*/)
|
|
{//Тікбұрышты үшбұрыштарды.ppt - slide 25
|
|
pShape->m_oCustomVML.LoadGuides(pProperty);
|
|
}
|
|
}break;
|
|
case ODRAW::pInscribe:
|
|
{
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
pShape->m_oCustomVML.LoadInscribe(pProperty);
|
|
}
|
|
}break;
|
|
case ODRAW::pAdjustHandles:
|
|
{
|
|
if (pProperty->m_bComplex)
|
|
{
|
|
pShape->m_oCustomVML.LoadAHs(pProperty);
|
|
}
|
|
}break;
|
|
case ODRAW::adjustValue:
|
|
case ODRAW::adjust2Value:
|
|
case ODRAW::adjust3Value:
|
|
case ODRAW::adjust4Value:
|
|
case ODRAW::adjust5Value:
|
|
case ODRAW::adjust6Value:
|
|
case ODRAW::adjust7Value:
|
|
case ODRAW::adjust8Value:
|
|
case ODRAW::adjust9Value:
|
|
case ODRAW::adjust10Value:
|
|
{
|
|
LONG lIndexAdj = pProperty->m_ePID - ODRAW::adjustValue;
|
|
if (lIndexAdj >= 0 && lIndexAdj < (LONG)pShape->m_arAdjustments.size())
|
|
{
|
|
pShape->m_oCustomVML.LoadAdjusts(lIndexAdj, (LONG)pProperty->m_lValue);
|
|
}
|
|
else
|
|
{
|
|
pShape->m_oCustomVML.LoadAdjusts(lIndexAdj, (LONG)pProperty->m_lValue);
|
|
}
|
|
}break;
|
|
//--------------------------------------------------------------------------------------------------------------------
|
|
case lTxid:
|
|
{
|
|
}break;
|
|
case ODRAW::dxTextLeft:
|
|
{
|
|
pParentShape->m_dTextMarginX = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::dxTextRight:
|
|
{
|
|
pParentShape->m_dTextMarginRight = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::dyTextTop:
|
|
{
|
|
pParentShape->m_dTextMarginY = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::dyTextBottom:
|
|
{
|
|
pParentShape->m_dTextMarginBottom = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::WrapText:
|
|
{
|
|
pParentShape->m_oText.m_lWrapMode = (LONG)pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::gtextUNICODE://word art text
|
|
{
|
|
if (pProperty->m_bComplex && 0 < pProperty->m_lValue)
|
|
{
|
|
std::wstring str = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)pProperty->m_pOptions, pProperty->m_lValue/2-1);
|
|
|
|
if (!str.empty() && pParentShape->m_oText.m_arParagraphs.empty())
|
|
{
|
|
int length = str.length();
|
|
|
|
for (int i = length-1; i>=0; i--)
|
|
{
|
|
if (str.at(i) > 13 ) break;
|
|
length--;
|
|
}
|
|
PPT::CParagraph p;
|
|
PPT::CSpan s;
|
|
s.m_strText = str.substr(0,length);
|
|
p.m_arSpans.push_back(s);
|
|
pParentShape->m_oText.m_arParagraphs.push_back(p);
|
|
}
|
|
}
|
|
}break;
|
|
case ODRAW::gtextFont:
|
|
{
|
|
if (pProperty->m_bComplex && 0 < pProperty->m_lValue)
|
|
{
|
|
std::wstring str = NSFile::CUtf8Converter::GetWStringFromUTF16((unsigned short*)pProperty->m_pOptions, pProperty->m_lValue/2-1);
|
|
pParentShape->m_oText.m_oAttributes.m_oFont.Name = str;
|
|
}
|
|
}break;
|
|
case ODRAW::gtextSize:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_oFont.Size = (INT)((pProperty->m_lValue >> 16) & 0x0000FFFF);
|
|
break;
|
|
}
|
|
case ODRAW::anchorText:
|
|
{
|
|
switch (pProperty->m_lValue)
|
|
{
|
|
case ODRAW::anchorTop:
|
|
case ODRAW::anchorTopBaseline:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = 0;
|
|
break;
|
|
}
|
|
case ODRAW::anchorMiddle:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = 1;
|
|
break;
|
|
}
|
|
case ODRAW::anchorBottom:
|
|
case ODRAW::anchorBottomBaseline:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 0;
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = 2;
|
|
break;
|
|
}
|
|
case ODRAW::anchorTopCentered:
|
|
case ODRAW::anchorTopCenteredBaseline:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = 0;
|
|
break;
|
|
}
|
|
case ODRAW::anchorMiddleCentered:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = 1;
|
|
break;
|
|
}
|
|
case ODRAW::anchorBottomCentered:
|
|
case ODRAW::anchorBottomCenteredBaseline:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = 2;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignVertical = -1; // not set
|
|
break;
|
|
}
|
|
};
|
|
break;
|
|
}
|
|
case ODRAW::gtextAlign:
|
|
{
|
|
switch (pProperty->m_lValue)
|
|
{
|
|
case ODRAW::alignTextLeft:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 0;
|
|
}break;
|
|
case ODRAW::alignTextCenter:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
}break;
|
|
case ODRAW::alignTextRight:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 2;
|
|
}break;
|
|
default:
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
}break;
|
|
};
|
|
break;
|
|
}
|
|
case ODRAW::geometryTextBooleanProperties:
|
|
{
|
|
// here - need to convert units to pixels
|
|
BYTE flag1 = (BYTE)(pProperty->m_lValue);
|
|
BYTE flag2 = (BYTE)(pProperty->m_lValue >> 8);
|
|
BYTE flag3 = (BYTE)(pProperty->m_lValue >> 16);
|
|
BYTE flag4 = (BYTE)(pProperty->m_lValue >> 24);
|
|
|
|
bool bStrikethrought = (0x01 == (0x01 & flag1));
|
|
bool bSmallCaps = (0x02 == (0x02 & flag1));
|
|
bool bShadow = (0x04 == (0x04 & flag1));
|
|
bool bUnderline = (0x08 == (0x08 & flag1));
|
|
bool bItalic = (0x10 == (0x10 & flag1));
|
|
bool bBold = (0x20 == (0x20 & flag1));
|
|
|
|
bool bUseStrikethrought = (0x01 == (0x01 & flag3));
|
|
bool bUseSmallCaps = (0x02 == (0x02 & flag3));
|
|
bool bUseShadow = (0x04 == (0x04 & flag3));
|
|
bool bUseUnderline = (0x08 == (0x08 & flag3));
|
|
bool bUseItalic = (0x10 == (0x10 & flag3));
|
|
bool bUseBold = (0x20 == (0x20 & flag3));
|
|
|
|
bool bVertical = (0x20 == (0x20 & flag2));
|
|
bool bUseVertical = (0x20 == (0x20 & flag4));
|
|
|
|
if (bUseStrikethrought)
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_oFont.Strikeout = (BYTE)bStrikethrought;
|
|
}
|
|
if (bUseShadow)
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_oTextShadow.Visible = true;
|
|
}
|
|
if (bUseUnderline)
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_oFont.Underline = (BYTE)bUnderline;
|
|
}
|
|
if (bUseItalic)
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_oFont.Italic = bItalic;
|
|
}
|
|
if (bUseBold)
|
|
{
|
|
pParentShape->m_oText.m_oAttributes.m_oFont.Bold = bBold;
|
|
}
|
|
if (bUseVertical)
|
|
{
|
|
pParentShape->m_oText.m_bVertical = (true == bVertical) ? true : false;
|
|
}
|
|
}break;
|
|
case ODRAW::cdirFont:
|
|
{
|
|
switch (pProperty->m_lValue)
|
|
{
|
|
case 1:
|
|
pParentShape->m_oText.m_bVertical = true;
|
|
break;
|
|
case 2:
|
|
pParentShape->m_oText.m_oAttributes.m_dTextRotate = 180;
|
|
break;
|
|
case 3:
|
|
pParentShape->m_oText.m_bVertical = true;
|
|
pParentShape->m_oText.m_oAttributes.m_dTextRotate = 180;
|
|
break;
|
|
}
|
|
}break;
|
|
case ODRAW::txflTextFlow:
|
|
{
|
|
pParentShape->m_oText.m_nTextFlow = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::textBooleanProperties:
|
|
{
|
|
BYTE flag1 = (BYTE)(pProperty->m_lValue);
|
|
BYTE flag2 = (BYTE)(pProperty->m_lValue >> 8);
|
|
BYTE flag3 = (BYTE)(pProperty->m_lValue >> 16);
|
|
BYTE flag4 = (BYTE)(pProperty->m_lValue >> 24);
|
|
|
|
bool bFitShapeToText = (0x02 == (0x02 & flag1));
|
|
bool bAutoTextMargin = (0x08 == (0x08 & flag1));
|
|
bool bSelectText = (0x10 == (0x10 & flag1));
|
|
|
|
bool bUseFitShapeToText = (0x02 == (0x02 & flag3));
|
|
bool bUseAutoTextMargin = (0x08 == (0x08 & flag3));
|
|
bool bUseSelectText = (0x10 == (0x10 & flag3));
|
|
|
|
if (bUseAutoTextMargin)
|
|
{
|
|
if (bAutoTextMargin)
|
|
{
|
|
pParentShape->m_dTextMarginX = 2.54;
|
|
pParentShape->m_dTextMarginRight = 1.27;
|
|
pParentShape->m_dTextMarginY = 2.54;
|
|
pParentShape->m_dTextMarginBottom = 1.27;
|
|
}
|
|
}
|
|
if (bUseFitShapeToText)
|
|
pParentShape->m_oText.m_bAutoFit = bFitShapeToText;
|
|
|
|
}break;
|
|
case ODRAW::c3DSpecularAmt:
|
|
{
|
|
pShape->m_3dOptions.dSpecularAmt = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DDiffuseAmt:
|
|
{
|
|
pShape->m_3dOptions.dDiffuseAmt = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DShininess:
|
|
{
|
|
pShape->m_3dOptions.dShininess = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DEdgeThickness:
|
|
{
|
|
pShape->m_3dOptions.nEdgeThickness = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::C3DExtrudeForward:
|
|
{
|
|
pShape->m_3dOptions.nExtrudeForward = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::c3DExtrudeBackward:
|
|
{
|
|
pShape->m_3dOptions.nExtrudeBackward = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::c3DExtrudePlane:
|
|
{
|
|
//ExtrudePlane = 0;
|
|
}break;
|
|
case ODRAW::c3DExtrusionColor:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
CColor tmp;
|
|
if(oAtom.bSysIndex) tmp = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else oAtom.ToColor(&tmp);
|
|
|
|
pShape->m_3dOptions.oExtrusionColor = tmp;
|
|
}break;
|
|
case ODRAW::c3DCrMod:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
CColor tmp;
|
|
if(oAtom.bSysIndex) tmp = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else oAtom.ToColor(&tmp);
|
|
|
|
pShape->m_3dOptions.oCrMod = tmp;
|
|
}break;
|
|
case ODRAW::c3DExtrusionColorExt:
|
|
{
|
|
SColorAtom oAtom;
|
|
oAtom.FromValue(pProperty->m_lValue);
|
|
|
|
CColor tmp;
|
|
if(oAtom.bSysIndex) tmp = CorrectSysColor(pProperty->m_lValue, pElement, pTheme);
|
|
else oAtom.ToColor(&tmp);
|
|
pShape->m_3dOptions.oExtrusionColorExt = tmp;
|
|
}break;
|
|
case ODRAW::c3DExtrusionColorExtMod:
|
|
{
|
|
pShape->m_3dOptions.nTypeExtrusionColorExt = (pProperty->m_lValue & 0x00000300) >> 8;
|
|
}break;
|
|
case ODRAW::c3DBottomBevelWidth:
|
|
{
|
|
pShape->m_3dOptions.dBottomBevelWidth = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DBottomBevelHeight:
|
|
{
|
|
pShape->m_3dOptions.dBottomBevelHeight = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DBottomBevelType:
|
|
{
|
|
pShape->m_3dOptions.nBottomBevelType = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::c3DTopBevelWidth:
|
|
{
|
|
pShape->m_3dOptions.dTopBevelWidth = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DTopBevelHeight:
|
|
{
|
|
pShape->m_3dOptions.dTopBevelHeight = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DTopBevelType:
|
|
{
|
|
pShape->m_3dOptions.nTopBevelType = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::threeDObjectBooleanProperties:
|
|
{
|
|
bool fUsef3D = GETBIT(pProperty->m_lValue, 19);
|
|
bool fUsefc3DMetallic = GETBIT(pProperty->m_lValue, 18);
|
|
bool fUsefc3DUseExtrusionColor = GETBIT(pProperty->m_lValue, 17);
|
|
bool fUsefc3DLightFace = GETBIT(pProperty->m_lValue, 16);
|
|
|
|
pShape->m_3dOptions.bEnabled = fUsef3D ? GETBIT(pProperty->m_lValue, 3) : false;
|
|
pShape->m_3dOptions.bMetallic = fUsefc3DMetallic ? GETBIT(pProperty->m_lValue, 2) : false;
|
|
pShape->m_3dOptions.bExtrusionColor= fUsefc3DUseExtrusionColor ? GETBIT(pProperty->m_lValue, 1) : false;
|
|
pShape->m_3dOptions.bLightFace = fUsefc3DLightFace ? GETBIT(pProperty->m_lValue, 0) : true;
|
|
|
|
}break;
|
|
case ODRAW::c3DYRotationAngle:
|
|
{
|
|
double val = FixedPointToDouble(pProperty->m_lValue);
|
|
if (val < 0) val += 360;
|
|
pShape->m_3dOptions.dYRotationAngle = val;
|
|
}break;
|
|
case ODRAW::c3DXRotationAngle:
|
|
{
|
|
double val = FixedPointToDouble(pProperty->m_lValue);
|
|
if (val < 0) val += 360;
|
|
pShape->m_3dOptions.dXRotationAngle = val;
|
|
}break;
|
|
case ODRAW::c3DRotationAxisX:
|
|
{
|
|
pShape->m_3dOptions.dRotationAxisX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRotationAxisY:
|
|
{
|
|
pShape->m_3dOptions.dRotationAxisY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRotationAxisZ:
|
|
{
|
|
pShape->m_3dOptions.dRotationAxisZ = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRotationAngle:
|
|
{
|
|
pShape->m_3dOptions.dRotationAngle = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRotationCenterX:
|
|
{
|
|
pShape->m_3dOptions.dRotationCenterX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRotationCenterY:
|
|
{
|
|
pShape->m_3dOptions.dRotationCenterY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRotationCenterZ:
|
|
{
|
|
pShape->m_3dOptions.dRotationCenterZ = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DRenderMode:
|
|
{
|
|
pShape->m_3dOptions.nRenderMode = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::c3DTolerance:
|
|
{
|
|
pShape->m_3dOptions.dTolerance = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DXViewpoint:
|
|
{
|
|
pShape->m_3dOptions.dXViewpoint = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DYViewpoint:
|
|
{
|
|
pShape->m_3dOptions.dYViewpoint = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DZViewpoint:
|
|
{
|
|
pShape->m_3dOptions.dZViewpoint = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DOriginX:
|
|
{
|
|
pShape->m_3dOptions.dOriginX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DOriginY:
|
|
{
|
|
pShape->m_3dOptions.dOriginY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DSkewAngle:
|
|
{
|
|
double val = FixedPointToDouble(pProperty->m_lValue);
|
|
if (val <= 0) val += 360;
|
|
pShape->m_3dOptions.dSkewAngle = val;
|
|
}break;
|
|
case ODRAW::c3DSkewAmount:
|
|
{
|
|
pShape->m_3dOptions.nSkewAmount = pProperty->m_lValue;
|
|
}break;
|
|
case ODRAW::c3DAmbientIntensity:
|
|
{
|
|
pShape->m_3dOptions.dAmbientIntensity = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DKeyX:
|
|
{
|
|
pShape->m_3dOptions.dKeyX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DKeyY:
|
|
{
|
|
pShape->m_3dOptions.dKeyY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DKeyZ:
|
|
{
|
|
pShape->m_3dOptions.dKeyZ = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DKeyIntensity:
|
|
{
|
|
pShape->m_3dOptions.dKeyIntensity = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DFillX:
|
|
{
|
|
pShape->m_3dOptions.dFillX = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DFillY:
|
|
{
|
|
pShape->m_3dOptions.dFillY = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DFillZ:
|
|
{
|
|
pShape->m_3dOptions.dFillZ = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::c3DFillIntensity:
|
|
{
|
|
pShape->m_3dOptions.dFillIntensity = FixedPointToDouble(pProperty->m_lValue);
|
|
}break;
|
|
case ODRAW::threeDStyleBooleanProperties:
|
|
{
|
|
bool fUsefc3DConstrainRotation = GETBIT(pProperty->m_lValue, 20);
|
|
bool fUsefc3DRotationCenterAuto = GETBIT(pProperty->m_lValue, 19);
|
|
bool fUsefc3DParallel = GETBIT(pProperty->m_lValue, 18);
|
|
bool fUsefc3DKeyHarsh = GETBIT(pProperty->m_lValue, 17);
|
|
bool fUsefc3DFillHarsh = GETBIT(pProperty->m_lValue, 16);
|
|
|
|
pShape->m_3dOptions.bConstrainRotation = fUsefc3DConstrainRotation ? GETBIT(pProperty->m_lValue, 4) : true;
|
|
pShape->m_3dOptions.bRotationCenterAuto= fUsefc3DRotationCenterAuto? GETBIT(pProperty->m_lValue, 3) : false;
|
|
pShape->m_3dOptions.bParallel = fUsefc3DParallel ? GETBIT(pProperty->m_lValue, 2) : true;
|
|
pShape->m_3dOptions.bKeyHarsh = fUsefc3DKeyHarsh ? GETBIT(pProperty->m_lValue, 1) : true;
|
|
pShape->m_3dOptions.bFillHarsh = fUsefc3DFillHarsh ? GETBIT(pProperty->m_lValue, 0) : true;
|
|
}break;
|
|
default:
|
|
{
|
|
int unknown_value = pProperty->m_lValue;
|
|
unknown_value = unknown_value;
|
|
}break;
|
|
}
|
|
}
|
|
|
|
|
|
CRecordShapeContainer::CRecordShapeContainer()
|
|
{
|
|
bGroupShape = false;
|
|
m_pStream = NULL;
|
|
|
|
}
|
|
|
|
CRecordShapeContainer::~CRecordShapeContainer()
|
|
{
|
|
m_pStream = NULL;
|
|
}
|
|
|
|
void CRecordShapeContainer::ReadFromStream(SRecordHeader &oHeader, POLE::Stream *pStream)
|
|
{
|
|
m_pStream = pStream;
|
|
CRecordsContainer::ReadFromStream(oHeader, pStream);
|
|
}
|
|
|
|
CElementPtr CRecordShapeContainer::GetElement (bool inGroup, CExMedia* pMapIDs,
|
|
CTheme* pTheme, CLayout* pLayout,
|
|
CSlideInfo* pThemeWrapper, CSlideInfo* pSlideWrapper, CSlide* pSlide)
|
|
{
|
|
CElementPtr pElement;
|
|
|
|
std::vector<CRecordShape*> oArrayShape;
|
|
GetRecordsByType(&oArrayShape, true, true);
|
|
|
|
if (0 == oArrayShape.size())
|
|
return pElement;
|
|
|
|
// PlaceHolder
|
|
std::vector<CRecordPlaceHolderAtom*> oArrayPlaceHolder;
|
|
GetRecordsByType(&oArrayPlaceHolder, true, true);
|
|
|
|
std::vector<CRecordShapeProperties*> oArrayOptions;
|
|
GetRecordsByType(&oArrayOptions, true, /*true*/false/*secondary & tetriary*/);
|
|
|
|
PPTShapes::ShapeType eType = (PPTShapes::ShapeType)oArrayShape[0]->m_oHeader.RecInstance;
|
|
PPT::ElementType elType = GetTypeElem((ODRAW::eSPT)oArrayShape[0]->m_oHeader.RecInstance);
|
|
|
|
int lMasterID = -1;
|
|
|
|
CElementPtr pElementLayout;
|
|
|
|
if (NULL != pSlide)
|
|
{
|
|
bool bIsMaster = oArrayShape[0]->m_bHaveMaster;
|
|
if (bIsMaster && elType !=etPicture)
|
|
{
|
|
for (size_t i = 0; i < oArrayOptions[0]->m_oProperties.m_lCount; ++i)
|
|
{
|
|
if (hspMaster == oArrayOptions[0]->m_oProperties.m_arProperties[i].m_ePID)
|
|
{
|
|
lMasterID = oArrayOptions[0]->m_oProperties.m_arProperties[i].m_lValue;
|
|
|
|
if (pLayout && !oArrayPlaceHolder.empty())
|
|
{
|
|
int placeholder_type = oArrayPlaceHolder[0]->m_nPlacementID;
|
|
int placeholder_id = oArrayPlaceHolder[0]->m_nPosition;
|
|
|
|
size_t nIndexMem = pLayout->m_arElements.size();
|
|
|
|
for (size_t nIndex = 0; nIndex < nIndexMem; ++nIndex)
|
|
{
|
|
if ((placeholder_type == pLayout->m_arElements[nIndex]->m_lPlaceholderType ) &&
|
|
( placeholder_id < 0 || pLayout->m_arElements[nIndex]->m_lPlaceholderID < 0 ||
|
|
placeholder_id == pLayout->m_arElements[nIndex]->m_lPlaceholderID))
|
|
{
|
|
if (pLayout->m_arElements[nIndex]->m_bPlaceholderSet == false)
|
|
{
|
|
pElementLayout = pLayout->m_arElements[nIndex]; //for transferring settings
|
|
pElementLayout->m_lID = lMasterID;
|
|
|
|
if (placeholder_id >= 0 && pLayout->m_arElements[nIndex]->m_lPlaceholderID < 0 )
|
|
pLayout->m_arElements[nIndex]->m_lPlaceholderID = placeholder_id;
|
|
}
|
|
|
|
pElement = pLayout->m_arElements[nIndex]->CreateDublicate();
|
|
|
|
if (elType == etShape)
|
|
{
|
|
CShapeElement* pShape = dynamic_cast<CShapeElement*>(pElement.get());
|
|
if (NULL != pShape)
|
|
pShape->m_pShape->m_oText.m_arParagraphs.clear();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!pElement)
|
|
{
|
|
switch (eType)
|
|
{
|
|
case sptMax:
|
|
case sptNil:
|
|
break;
|
|
case sptPictureFrame:
|
|
{
|
|
std::vector<CRecordExObjRefAtom*> oArrayEx;
|
|
GetRecordsByType(&oArrayEx, true, true);
|
|
|
|
CExFilesInfo oInfo;
|
|
CExFilesInfo oInfoDefault;
|
|
// by default image (or ole object)
|
|
CExFilesInfo::ExFilesType exType = CExFilesInfo::eftNone;
|
|
CExFilesInfo* pInfo = pMapIDs->Lock(0xFFFFFFFF, exType);
|
|
if (NULL != pInfo)
|
|
{
|
|
oInfo = *pInfo;
|
|
oInfoDefault = oInfo;
|
|
}
|
|
|
|
if (0 != oArrayEx.size())
|
|
{
|
|
pInfo = pMapIDs->Lock(oArrayEx[0]->m_nExObjID, exType);
|
|
if (NULL != pInfo)
|
|
{
|
|
oInfo = *pInfo;
|
|
}
|
|
}
|
|
|
|
if (CExFilesInfo::eftVideo == exType)
|
|
{
|
|
CVideoElement* pVideoElem = new CVideoElement();
|
|
|
|
pVideoElem->m_strVideoFileName = oInfo.m_strFilePath ;
|
|
pVideoElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR;
|
|
|
|
pElement = CElementPtr(pVideoElem);
|
|
}
|
|
else if (CExFilesInfo::eftAudio == exType)
|
|
{
|
|
CAudioElement* pAudioElem = new CAudioElement();
|
|
pElement = CElementPtr(pAudioElem);
|
|
|
|
pAudioElem->m_strAudioFileName = oInfo.m_strFilePath;
|
|
pAudioElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR;
|
|
|
|
pAudioElem->m_dClipStartTime = oInfo.m_dStartTime;
|
|
pAudioElem->m_dClipEndTime = oInfo.m_dEndTime;
|
|
|
|
pAudioElem->m_bLoop = oInfo.m_bLoop;
|
|
|
|
if (NULL != pSlide)
|
|
{
|
|
pAudioElem->m_dStartTime = pSlide->m_dStartTime;
|
|
pAudioElem->m_dEndTime = pSlide->m_dEndTime;
|
|
|
|
}
|
|
else
|
|
{
|
|
if (pLayout)
|
|
pLayout->m_arElements.push_back(pElement);
|
|
}
|
|
|
|
}
|
|
else if (CExFilesInfo::eftOleObject == exType)
|
|
{
|
|
COleObjectElement* pOleObjectElem = new COleObjectElement();
|
|
pOleObjectElem->m_strBinFileName = oInfo.m_strFilePath;
|
|
pOleObjectElem->m_strImageFileName = oInfoDefault.m_strFilePath + FILE_SEPARATOR_STR;
|
|
|
|
pOleObjectElem->m_strProgId = oInfo.m_progName;
|
|
pOleObjectElem->m_strOleName = oInfo.m_name;
|
|
|
|
pElement = CElementPtr(pOleObjectElem);
|
|
}
|
|
else
|
|
{
|
|
CImageElement* pImageElem = new CImageElement();
|
|
pImageElem->m_strImageFileName = oInfo.m_strFilePath + FILE_SEPARATOR_STR;
|
|
|
|
pElement = CElementPtr(pImageElem);
|
|
}
|
|
}break;
|
|
default:
|
|
{
|
|
if (isTable())
|
|
{
|
|
CTableElement* pTableElem = new CTableElement();
|
|
pTableElem->m_xmlRawData = getTableXmlStr();
|
|
pTableElem->m_etType = etGroup;
|
|
pElement = CElementPtr(pTableElem);
|
|
}
|
|
else if (bGroupShape)
|
|
{
|
|
CGroupElement* pGroupElem = new CGroupElement();
|
|
pElement = CElementPtr(pGroupElem);
|
|
}
|
|
else
|
|
{
|
|
// shape
|
|
CShapeElement* pShape = new CShapeElement(NSBaseShape::ppt, eType);
|
|
CPPTShape *ppt_shape = dynamic_cast<CPPTShape *>(pShape->m_pShape->getBaseShape().get());
|
|
|
|
if ( (ppt_shape) && (OOXMLShapes::sptCustom == ppt_shape->m_eType))
|
|
{
|
|
pShape->m_bShapePreset = true;
|
|
}
|
|
pElement = CElementPtr(pShape);
|
|
}
|
|
}break;
|
|
}
|
|
}
|
|
|
|
if (!pElement)
|
|
return pElement;
|
|
|
|
pElement->m_lID = oArrayShape[0]->m_nID;
|
|
pElement->m_lLayoutID = lMasterID;
|
|
|
|
//---------external links
|
|
{
|
|
CExFilesInfo::ExFilesType exType = CExFilesInfo::eftNone;
|
|
CExFilesInfo * pTextureInfo = pMapIDs->Lock(0xFFFFFFFF, exType);
|
|
|
|
if (NULL != pTextureInfo)
|
|
{
|
|
pElement->m_oBrush.TexturePath = pTextureInfo->m_strFilePath + FILE_SEPARATOR_STR;
|
|
}
|
|
|
|
std::vector<CRecordExObjRefAtom*> oArrayEx;
|
|
GetRecordsByType(&oArrayEx, true, true);
|
|
if (0 != oArrayEx.size())
|
|
{
|
|
CExFilesInfo* pInfo = pMapIDs->Lock(oArrayEx[0]->m_nExObjID, exType);
|
|
|
|
if (CExFilesInfo::eftHyperlink == exType && pInfo)
|
|
{
|
|
pElement->m_sHyperlink = pInfo->m_strFilePath;
|
|
}
|
|
}
|
|
}
|
|
std::wstring strShapeText;
|
|
//------------------------------------------------------------------------------------------------
|
|
// placeholders
|
|
if (0 < oArrayPlaceHolder.size())
|
|
{
|
|
pElement->m_bLine = false; //by default they have no lines
|
|
pElement->m_lPlaceholderID = oArrayPlaceHolder[0]->m_nPosition;
|
|
pElement->m_lPlaceholderType = oArrayPlaceHolder[0]->m_nPlacementID;
|
|
pElement->m_lPlaceholderSizePreset = oArrayPlaceHolder[0]->m_nSize;
|
|
|
|
if (pElementLayout)
|
|
pElementLayout->m_lPlaceholderSizePreset = oArrayPlaceHolder[0]->m_nSize;
|
|
|
|
CorrectPlaceholderType(pElement->m_lPlaceholderType);
|
|
}
|
|
|
|
std::vector<RoundTripHFPlaceholder12Atom*> oArrayHFPlaceholder;
|
|
GetRecordsByType(&oArrayHFPlaceholder, true, true);
|
|
if (0 < oArrayHFPlaceholder.size())
|
|
{
|
|
pElement->m_lPlaceholderType = oArrayHFPlaceholder[0]->m_nPlacementID;//PT_MasterDate, PT_MasterSlideNumber, PT_MasterFooter, or PT_MasterHeader
|
|
CorrectPlaceholderType(pElement->m_lPlaceholderType);
|
|
|
|
if (pLayout)
|
|
{
|
|
std::multimap<int, CElementPtr>::iterator it = pLayout->m_mapPlaceholders.find(pElement->m_lPlaceholderType);
|
|
if (it != pLayout->m_mapPlaceholders.end())
|
|
{
|
|
pElement->m_lPlaceholderID = (it->second)->m_lPlaceholderID;
|
|
}
|
|
}
|
|
}
|
|
//meta placeholders
|
|
std::vector<CRecordFooterMetaAtom*> oArrayFooterMeta;
|
|
|
|
GetRecordsByType(&oArrayFooterMeta, true, true);
|
|
if (0 < oArrayFooterMeta.size())
|
|
{
|
|
pElement->m_lPlaceholderType = PT_MasterFooter;
|
|
pElement->m_lPlaceholderUserStr = oArrayFooterMeta[0]->m_nPosition;
|
|
}
|
|
std::vector<CRecordSlideNumberMetaAtom*> oArraySlideNumberMeta;
|
|
GetRecordsByType(&oArraySlideNumberMeta, true, true);
|
|
if (0 < oArraySlideNumberMeta.size())
|
|
{
|
|
pElement->m_lPlaceholderType = PT_MasterSlideNumber;
|
|
}
|
|
std::vector<CRecordGenericDateMetaAtom*> oArrayDateMeta;
|
|
GetRecordsByType(&oArrayDateMeta, true, true);
|
|
if (0 < oArrayDateMeta.size())
|
|
{
|
|
pElement->m_lPlaceholderType = PT_MasterDate;
|
|
|
|
CRecordDateTimeMetaAtom* format_data = dynamic_cast<CRecordDateTimeMetaAtom*>(oArrayDateMeta[0]);
|
|
if (format_data)
|
|
{
|
|
pElement->m_nFormatDate = 1;
|
|
//todooo make formatted output
|
|
}
|
|
else
|
|
{
|
|
pElement->m_lPlaceholderUserStr = oArrayDateMeta[0]->m_nPosition;
|
|
pElement->m_nFormatDate = 2;
|
|
}
|
|
}
|
|
//------------- bindings ---------------------------------------------------------------------------------
|
|
std::vector<CRecordGroupShape*> oArrayGroupShape;
|
|
this->GetRecordsByType(&oArrayGroupShape, true, true);
|
|
|
|
if (0 != oArrayGroupShape.size())
|
|
{
|
|
pElement->m_rcGroupAnchor.left = (LONG)oArrayGroupShape[0]->m_oBounds.left;
|
|
pElement->m_rcGroupAnchor.top = (LONG)oArrayGroupShape[0]->m_oBounds.top;
|
|
pElement->m_rcGroupAnchor.right = (LONG)oArrayGroupShape[0]->m_oBounds.right;
|
|
pElement->m_rcGroupAnchor.bottom = (LONG)oArrayGroupShape[0]->m_oBounds.bottom;
|
|
|
|
pElement->m_bGroupAnchorEnabled = true;
|
|
}
|
|
std::vector<CRecordClientAnchor*> oArrayAnchor;
|
|
this->GetRecordsByType(&oArrayAnchor, true, true);
|
|
|
|
if (0 != oArrayAnchor.size())
|
|
{
|
|
pElement->m_rcAnchor.left = (LONG)oArrayAnchor[0]->m_oBounds.Left;
|
|
pElement->m_rcAnchor.top = (LONG)oArrayAnchor[0]->m_oBounds.Top;
|
|
pElement->m_rcAnchor.right = (LONG)oArrayAnchor[0]->m_oBounds.Right;
|
|
pElement->m_rcAnchor.bottom = (LONG)oArrayAnchor[0]->m_oBounds.Bottom;
|
|
|
|
pElement->m_bAnchorEnabled = true;
|
|
}
|
|
|
|
std::vector<CRecordChildAnchor*> oArrayChildAnchor;
|
|
this->GetRecordsByType(&oArrayChildAnchor, true, true);
|
|
|
|
if (0 != oArrayChildAnchor.size())
|
|
{
|
|
pElement->m_rcChildAnchor.left = oArrayChildAnchor[0]->m_oBounds.left;
|
|
pElement->m_rcChildAnchor.top = oArrayChildAnchor[0]->m_oBounds.top;
|
|
pElement->m_rcChildAnchor.right = oArrayChildAnchor[0]->m_oBounds.right;
|
|
pElement->m_rcChildAnchor.bottom = oArrayChildAnchor[0]->m_oBounds.bottom;
|
|
|
|
pElement->m_bChildAnchorEnabled = true;
|
|
}
|
|
|
|
pElement->m_bFlipH = oArrayShape[0]->m_bFlipH;
|
|
pElement->m_bFlipV = oArrayShape[0]->m_bFlipV;
|
|
|
|
pElement->m_bIsBackground = (true == oArrayShape[0]->m_bBackground);
|
|
pElement->m_bHaveAnchor = (true == oArrayShape[0]->m_bHaveAnchor);
|
|
|
|
if (pElementLayout && (pElement->m_bAnchorEnabled || pElement->m_bChildAnchorEnabled))
|
|
{
|
|
pElementLayout->m_rcAnchor = pElement->m_rcAnchor;
|
|
pElementLayout->m_rcChildAnchor = pElement->m_rcChildAnchor;
|
|
|
|
pElementLayout->m_bPlaceholderSet = true;
|
|
pElementLayout->m_bAnchorEnabled = pElement->m_bAnchorEnabled;
|
|
pElementLayout->m_bChildAnchorEnabled = pElement->m_bChildAnchorEnabled;
|
|
}
|
|
|
|
std::vector<CRecordOfficeArtClientData*> oArrayArtClient;
|
|
GetRecordsByType(&oArrayArtClient, false, true);
|
|
std::vector<CRecordMouseInteractiveInfoContainer*> oArrayInteractive;
|
|
|
|
if (oArrayArtClient.size())
|
|
oArrayArtClient[0]->GetRecordsByType(&oArrayInteractive, true, false);
|
|
|
|
for (auto const* interactiveCont : oArrayInteractive)
|
|
{
|
|
CInteractiveInfo interactiveInfo;
|
|
ConvertInteractiveInfo(interactiveInfo, interactiveCont, pMapIDs);
|
|
|
|
pElement->m_arrActions.push_back(interactiveInfo);
|
|
}
|
|
|
|
|
|
//--------- text presence --------------------------------------------------------------------------
|
|
CShapeElement* pShapeElem = dynamic_cast<CShapeElement*>(pElement.get());
|
|
|
|
if (NULL != pShapeElem)
|
|
{
|
|
CElementInfo oElementInfo;
|
|
|
|
oElementInfo.m_lMasterPlaceholderType = pElement->m_lPlaceholderType;
|
|
|
|
pShapeElem->m_pShape->m_dWidthLogic = ShapeSizeVML;
|
|
pShapeElem->m_pShape->m_dHeightLogic = ShapeSizeVML;
|
|
|
|
// check for textheader present
|
|
std::vector<CRecordTextHeaderAtom*> oArrayTextHeader;
|
|
GetRecordsByType(&oArrayTextHeader, true, true);
|
|
|
|
if (0 < oArrayTextHeader.size())
|
|
{
|
|
pShapeElem->m_pShape->m_oText.m_lTextType = oArrayTextHeader[0]->m_nTextType;
|
|
pShapeElem->m_pShape->m_oText.m_lTextMasterType = oArrayTextHeader[0]->m_nTextType;
|
|
oElementInfo.m_lMasterTextType = oArrayTextHeader[0]->m_nTextType;
|
|
}
|
|
else
|
|
{
|
|
pShapeElem->m_pShape->m_oText.m_lTextType = NoPresent;
|
|
pShapeElem->m_pShape->m_oText.m_lTextMasterType = NoPresent;
|
|
oElementInfo.m_lMasterTextType = NoPresent;
|
|
}
|
|
|
|
// check for persist reference
|
|
std::vector<CRecordOutlineTextRefAtom*> oArrayTextRefs;
|
|
GetRecordsByType(&oArrayTextRefs, true, true);
|
|
|
|
if (0 < oArrayTextRefs.size())
|
|
{
|
|
oElementInfo.m_lPersistIndex = oArrayTextRefs[0]->m_nIndex;
|
|
}
|
|
|
|
// the text itself...
|
|
std::vector<CRecordTextBytesAtom*> oArrayTextBytes;
|
|
GetRecordsByType(&oArrayTextBytes, true, true);
|
|
if (0 < oArrayTextBytes.size() && strShapeText.empty())
|
|
{
|
|
strShapeText = oArrayTextBytes[0]->m_strText;
|
|
}
|
|
|
|
std::vector<CRecordTextCharsAtom*> oArrayTextChars;
|
|
GetRecordsByType(&oArrayTextChars, true, true);
|
|
|
|
if (0 < oArrayTextChars.size() && strShapeText.empty())
|
|
{
|
|
strShapeText = oArrayTextChars[0]->m_strText;
|
|
}
|
|
|
|
if (pElement->m_lPlaceholderType == PT_MasterSlideNumber && strShapeText.length() > 5)
|
|
{
|
|
int pos = strShapeText.find(L"*");
|
|
if (pos < 0) pElement->m_lPlaceholderType = PT_MasterFooter; ///???? 1-(33).ppt
|
|
}
|
|
|
|
//------ shape properties ----------------------------------------------------------------------------------------
|
|
CPPTElement oElement(m_pCommonInfo->tempPath);
|
|
|
|
for (size_t nIndexProp = 0; nIndexProp < oArrayOptions.size(); ++nIndexProp)
|
|
{
|
|
oElement.SetUpProperties(pElement, pTheme, pSlideWrapper, pSlide, &oArrayOptions[nIndexProp]->m_oProperties, (nIndexProp == 0));
|
|
}
|
|
|
|
std::vector<CRecordStyleTextPropAtom*> oArrayTextStyle;
|
|
this->GetRecordsByType(&oArrayTextStyle, true, true);
|
|
if (0 != oArrayTextStyle.size())
|
|
{
|
|
oElementInfo.m_pStream = m_pStream;
|
|
oElementInfo.m_lOffsetTextStyle = oArrayTextStyle[0]->m_lOffsetInStream;
|
|
}
|
|
|
|
std::vector<CRecordTextSpecInfoAtom*> oArrayTextProp;
|
|
this->GetRecordsByType(&oArrayTextProp, true, true);
|
|
if (0 != oArrayTextProp.size())
|
|
{
|
|
oElementInfo.m_pStream = m_pStream;
|
|
oElementInfo.m_lOffsetTextProp = oArrayTextProp[0]->m_lOffsetInStream;
|
|
}
|
|
|
|
std::vector<CRecordTextRulerAtom*> oArrayTextRuler;
|
|
this->GetRecordsByType(&oArrayTextRuler, true, true);
|
|
if (0 != oArrayTextRuler.size())
|
|
{
|
|
pShapeElem->m_pShape->m_oText.m_oRuler = oArrayTextRuler[0]->m_oTextRuler;
|
|
}
|
|
|
|
|
|
std::vector<CRecordOfficeArtClientTextbox*> oArrayTextBox;
|
|
std::vector<CRecordMouseInteractiveInfoContainer*> oArrayInteractiveCont;
|
|
std::vector<CRecordTextInteractiveInfoAtom*> oArrayTextInteractive;
|
|
this->GetRecordsByType(&oArrayTextBox, false);
|
|
|
|
if (oArrayTextBox.size())
|
|
{
|
|
// It's differance records
|
|
oArrayTextBox[0]->GetRecordsByType(&oArrayTextInteractive, false);
|
|
oArrayTextBox[0]->GetRecordsByType(&oArrayInteractiveCont, false);
|
|
}
|
|
|
|
for (const auto* pInerAtom : oArrayInteractiveCont)
|
|
{
|
|
CInteractiveInfo interactive;
|
|
ConvertInteractiveInfo(interactive, pInerAtom, pMapIDs);
|
|
pShapeElem->m_textHyperlinks.push_back(interactive);
|
|
}
|
|
|
|
if (!oArrayTextInteractive.empty())
|
|
{
|
|
pShapeElem->m_oTextActions.m_bPresent = true;
|
|
|
|
int nSize = oArrayTextInteractive.size();
|
|
for (int i = 0; i < nSize; ++i)
|
|
{
|
|
CTextRange oRange;
|
|
|
|
oRange.m_lStart = oArrayTextInteractive[i]->m_lStart;
|
|
oRange.m_lEnd = oArrayTextInteractive[i]->m_lEnd;
|
|
|
|
pShapeElem->m_oTextActions.m_arRanges.push_back(oRange);
|
|
}
|
|
}
|
|
|
|
double dAngle = pShapeElem->m_dRotate;
|
|
if (0 <= dAngle)
|
|
{
|
|
int lCount = (int)dAngle / 360;
|
|
dAngle -= (lCount * 360.0);
|
|
}
|
|
else
|
|
{
|
|
int lCount = (int)dAngle / 360;
|
|
dAngle += ((-lCount + 1) * 360.0);
|
|
}
|
|
if (((dAngle > 45) && (dAngle < 135)) || ((dAngle > 225) && (dAngle < 315)))
|
|
{
|
|
if (pShapeElem->m_bAnchorEnabled)
|
|
{
|
|
double dW = pShapeElem->m_rcAnchor.GetWidth();
|
|
double dH = pShapeElem->m_rcAnchor.GetHeight();
|
|
|
|
double dCx = (pShapeElem->m_rcAnchor.left + pShapeElem->m_rcAnchor.right) / 2.0;
|
|
double dCy = (pShapeElem->m_rcAnchor.top + pShapeElem->m_rcAnchor.bottom) / 2.0;
|
|
|
|
pShapeElem->m_rcAnchor.left = dCx - dH / 2.0;
|
|
pShapeElem->m_rcAnchor.right = dCx + dH / 2.0;
|
|
|
|
pShapeElem->m_rcAnchor.top = dCy - dW / 2.0;
|
|
pShapeElem->m_rcAnchor.bottom = dCy + dW / 2.0;
|
|
}
|
|
if (pShapeElem->m_bChildAnchorEnabled)
|
|
{
|
|
double dW = pShapeElem->m_rcChildAnchor.GetWidth();
|
|
double dH = pShapeElem->m_rcChildAnchor.GetHeight();
|
|
|
|
double dCx = (pShapeElem->m_rcChildAnchor.left + pShapeElem->m_rcChildAnchor.right) / 2.0;
|
|
double dCy = (pShapeElem->m_rcChildAnchor.top + pShapeElem->m_rcChildAnchor.bottom) / 2.0;
|
|
|
|
pShapeElem->m_rcChildAnchor.left = dCx - dH / 2.0;
|
|
pShapeElem->m_rcChildAnchor.right = dCx + dH / 2.0;
|
|
|
|
pShapeElem->m_rcChildAnchor.top = dCy - dW / 2.0;
|
|
pShapeElem->m_rcChildAnchor.bottom = dCy + dW / 2.0;
|
|
}
|
|
}
|
|
|
|
std::vector<CRecordMasterTextPropAtom*> oArrayMasterTextProp;
|
|
GetRecordsByType(&oArrayMasterTextProp, true);
|
|
|
|
CRecordMasterTextPropAtom* master_level = NULL;
|
|
if (!oArrayMasterTextProp.empty())
|
|
master_level = oArrayMasterTextProp[0];
|
|
|
|
pSlideWrapper->m_mapElements.insert(std::pair<LONG, CElementInfo>(pShapeElem->m_lID, oElementInfo));
|
|
|
|
SetUpTextStyle(strShapeText, pTheme, pLayout, pElement, pThemeWrapper, pSlideWrapper, pSlide, master_level);
|
|
}
|
|
else
|
|
{//image, audio, video ....
|
|
CPPTElement oElement(m_pCommonInfo->tempPath);
|
|
for (size_t nIndexProp = 0; nIndexProp < oArrayOptions.size(); ++nIndexProp)
|
|
{
|
|
oElement.SetUpProperties(pElement, pTheme, pSlideWrapper, pSlide, &oArrayOptions[nIndexProp]->m_oProperties, (nIndexProp == 0));
|
|
}
|
|
|
|
pElement->m_lLayoutID = lMasterID;
|
|
}
|
|
//----------------------------------------------------------------------------------------------------
|
|
if (NULL != pSlide)
|
|
{
|
|
pElement->m_dStartTime = pSlide->m_dStartTime;
|
|
pElement->m_dEndTime = pSlide->m_dEndTime;
|
|
}
|
|
else
|
|
{
|
|
pElement->m_dStartTime = 0;
|
|
pElement->m_dEndTime = 0;
|
|
}
|
|
|
|
return pElement;
|
|
}
|
|
|
|
PPT::ElementType CRecordShapeContainer::GetTypeElem(eSPT eType)
|
|
{
|
|
switch (eType)
|
|
{
|
|
//case sptMin:
|
|
case sptMax:
|
|
case sptNil:
|
|
{
|
|
return etShape;
|
|
}
|
|
case sptPictureFrame:
|
|
{
|
|
return etPicture;
|
|
}
|
|
default:
|
|
{
|
|
return etShape;
|
|
}
|
|
};
|
|
return etShape;
|
|
}
|
|
|
|
std::wstring CRecordShapeContainer::GetFileName(std::wstring strFilePath)
|
|
{
|
|
int nIndex = strFilePath.rfind(wchar_t('\\'));
|
|
if (-1 != nIndex)
|
|
return strFilePath.substr(nIndex + 1);
|
|
else
|
|
return strFilePath;
|
|
}
|
|
bool CRecordShapeContainer::isTable() const
|
|
{
|
|
std::vector<CRecordShapeProperties*> oArrayOptions;
|
|
GetRecordsByType(&oArrayOptions, true, false);
|
|
|
|
for (const auto* option : oArrayOptions)
|
|
{
|
|
for (const auto& prop : option->m_oProperties.m_arProperties)
|
|
{
|
|
if ((prop.m_ePID == tableProperties ||
|
|
prop.m_ePID == tableRowProperties) &&
|
|
bGroupShape)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
std::wstring CRecordShapeContainer::getTableXmlStr() const
|
|
{
|
|
std::vector<CRecordShapeProperties*> oArrayOptions;
|
|
GetRecordsByType(&oArrayOptions, true, false);
|
|
std::wstring xmlStr;
|
|
|
|
if (oArrayOptions.size() > 1 &&
|
|
oArrayOptions[1]->m_oProperties.m_arProperties.size() > 2)
|
|
{
|
|
COfficeUtils officeUtils(NULL);
|
|
BYTE *utf8Data = NULL;
|
|
ULONG utf8DataSize = 0;
|
|
auto& xmlProp = oArrayOptions[1]->m_oProperties.m_arProperties[2]; //id == 0x2065 ?
|
|
|
|
if (xmlProp.m_pOptions && xmlProp.m_lValue > 0) // file513.ppt
|
|
{
|
|
std::wstring tempPath = NSDirectory::CreateDirectoryWithUniqueName(m_pCommonInfo->tempPath);
|
|
std::wstring tempFileName = tempPath + FILE_SEPARATOR_STR + L"tempMetroBlob.zip";
|
|
|
|
NSFile::CFileBinary file;
|
|
if (file.CreateFileW(tempFileName))
|
|
{
|
|
file.WriteFile(xmlProp.m_pOptions, xmlProp.m_lValue);
|
|
file.CloseFile();
|
|
}
|
|
|
|
if (S_OK == officeUtils.LoadFileFromArchive(tempFileName, L"drs/e2oDoc.xml", &utf8Data, utf8DataSize))
|
|
{
|
|
xmlStr = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(utf8Data, utf8DataSize);
|
|
}
|
|
|
|
delete[] utf8Data;
|
|
NSFile::CFileBinary::Remove(tempFileName);
|
|
NSDirectory::DeleteDirectory(tempPath);
|
|
}
|
|
}
|
|
|
|
return xmlStr;
|
|
}
|
|
|
|
void CRecordShapeContainer::ApplyThemeStyle(CElementPtr pElem, CTheme* pTheme, CRecordMasterTextPropAtom* master_levels)
|
|
{
|
|
CShapeElement* pShape = dynamic_cast<CShapeElement*>(pElem.get());
|
|
if (NULL == pShape)
|
|
return;
|
|
|
|
CTextAttributesEx* pText = &(pShape->m_pShape->m_oText);
|
|
|
|
|
|
if (master_levels)
|
|
{
|
|
for (size_t i = 0; i < pText->m_arParagraphs.size(); i++)
|
|
{
|
|
if (i >= master_levels->m_arrProps.size()) break;
|
|
|
|
pText->m_arParagraphs[i].m_lTextLevel = master_levels->m_arrProps[i].lIndentLevel;
|
|
pText->m_arParagraphs[i].m_oPFRun.leftMargin.reset();
|
|
pText->m_arParagraphs[i].m_oPFRun.indent.reset();
|
|
}
|
|
}
|
|
|
|
pText->ApplyThemeStyle(pTheme);
|
|
// AutoNumbering and BulletBlip
|
|
ConvertStyleTextProp9(pText);
|
|
}
|
|
void CRecordShapeContainer::SetUpTextStyle(std::wstring& strText, CTheme* pTheme, CLayout* pLayout, CElementPtr pElem, CSlideInfo* pThemeWrapper, CSlideInfo* pSlideWrapper, CSlide* pSlide, CRecordMasterTextPropAtom* master_levels)
|
|
{
|
|
// first check for shape
|
|
// then apply all settings in order
|
|
// 1) master + TextMasterStyles
|
|
// 2) persist + TextMasterStyles
|
|
// 3) own settings + TextMasterStyles
|
|
// where "own settings" are purely "advanced settings"
|
|
// because all common ones (via properties) - are already set
|
|
|
|
if (NULL == pElem)
|
|
return;
|
|
|
|
if (etShape != pElem->m_etType)
|
|
return;
|
|
|
|
CShapeElement* pShape = dynamic_cast<CShapeElement*>(pElem.get());
|
|
if (NULL == pShape)
|
|
return;
|
|
|
|
CTextAttributesEx* pTextSettings = &(pShape->m_pShape->m_oText);
|
|
|
|
// first apply links to masterstyle (for template element)
|
|
// how to know - just check if arrays exist (since they could only appear from there)
|
|
// - now this is not needed - since this function is also called in master -
|
|
// and everything should already be applied there
|
|
bool bIsPersistPresentSettings = false;
|
|
bool bIsOwnPresentSettings = false;
|
|
|
|
TextTypeEnum eTypeMaster = NoPresent;
|
|
TextTypeEnum eTypePersist = NoPresent;
|
|
TextTypeEnum eTypeOwn = (TextTypeEnum)pTextSettings->m_lTextType;
|
|
|
|
CShapeElement* pElementLayoutPH = NULL;
|
|
|
|
// set the master type
|
|
if (NULL != pSlide)
|
|
{
|
|
int ph_type = pShape->m_lPlaceholderType;
|
|
int ph_pos = pShape->m_lPlaceholderID;
|
|
|
|
pTextSettings->m_lPlaceholderType = pShape->m_lPlaceholderType;
|
|
|
|
size_t lElemsCount = 0;
|
|
|
|
if (pLayout)
|
|
{
|
|
for (size_t i = 0; i < pLayout->m_arElements.size(); ++i)
|
|
{
|
|
CElementPtr & pPh = pLayout->m_arElements[i];
|
|
if ((etShape == pPh->m_etType) && (ph_type == pPh->m_lPlaceholderType) && (/*ph_pos == pPh->m_lPlaceholderID*/true))
|
|
{
|
|
pElementLayoutPH = dynamic_cast<CShapeElement*>(pPh.get());
|
|
eTypeMaster = (TextTypeEnum)pElementLayoutPH->m_pShape->m_oText.m_lTextMasterType;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
eTypeMaster = (TextTypeEnum)pTextSettings->m_lTextMasterType;
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------
|
|
CElementInfo oElemInfo;
|
|
std::map<LONG, CElementInfo>::iterator pPair = pSlideWrapper->m_mapElements.find(pShape->m_lID);
|
|
if (pSlideWrapper->m_mapElements.end() != pPair)
|
|
oElemInfo = pPair->second;
|
|
|
|
// persist ----------------------------------------------------------------------
|
|
std::vector<CTextFullSettings>* pArrayPlaceHolders = &pSlideWrapper->m_arTextPlaceHolders;
|
|
int lCountPersistObjects = pArrayPlaceHolders->size();
|
|
int lPersistIndex = oElemInfo.m_lPersistIndex;
|
|
|
|
if ((lPersistIndex >= 0) && (lPersistIndex < lCountPersistObjects))
|
|
{
|
|
CTextFullSettings* pSettings = &pArrayPlaceHolders->at(lPersistIndex);
|
|
|
|
eTypePersist = (TextTypeEnum)pSettings->m_nTextType;
|
|
strText = pSettings->ApplyProperties(pTextSettings);
|
|
|
|
if ((0 != pSettings->m_arRanges.size()) && (0 == pShape->m_oTextActions.m_arRanges.size()))
|
|
{
|
|
pShape->m_oTextActions.m_bPresent = true;
|
|
pShape->m_oTextActions.m_arRanges = pSettings->m_arRanges;
|
|
}
|
|
|
|
bIsPersistPresentSettings = ((NULL != pSettings->m_pTextStyleProp) && (0 < pSettings->m_pTextStyleProp->m_lCount));
|
|
}
|
|
// ------------------------------------------------------------------------------
|
|
|
|
if (NULL != oElemInfo.m_pStream && -1 != oElemInfo.m_lOffsetTextStyle)
|
|
{
|
|
// now we need to load text styles from the stream.
|
|
LONG lPosition = 0; StreamUtils::StreamPosition(lPosition, oElemInfo.m_pStream);
|
|
|
|
StreamUtils::StreamSeek(oElemInfo.m_lOffsetTextStyle - 8, oElemInfo.m_pStream);
|
|
|
|
SRecordHeader oHeader;
|
|
oHeader.ReadFromStream(oElemInfo.m_pStream) ;
|
|
|
|
if (RT_StyleTextPropAtom == oHeader.RecType)
|
|
{
|
|
CRecordStyleTextPropAtom* pStyle = new CRecordStyleTextPropAtom();
|
|
pStyle->m_lCount = strText.length();
|
|
|
|
pStyle->ReadFromStream(oHeader, oElemInfo.m_pStream);
|
|
|
|
PPT::ConvertPPTTextToEditorStructure(pStyle->m_arrPFs, pStyle->m_arrCFs, strText, pShape->m_pShape->m_oText);
|
|
|
|
bIsOwnPresentSettings = (0 < pStyle->m_lCount);
|
|
|
|
RELEASEOBJECT(pStyle);
|
|
}
|
|
StreamUtils::StreamSeek(lPosition, oElemInfo.m_pStream);
|
|
}
|
|
|
|
// ------------------------------------------------------------------------------
|
|
|
|
// now set all text settings (styles)
|
|
if (NULL == pSlide)
|
|
{
|
|
int nTextMasterType = (int)eTypeMaster;
|
|
if (-1 != pShape->m_lPlaceholderType)
|
|
{
|
|
switch (oElemInfo.m_lMasterPlaceholderType)
|
|
{
|
|
case PT_Title:
|
|
case PT_MasterTitle:
|
|
case PT_VerticalTitle:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 1;
|
|
|
|
if (Tx_TYPE_TITLE != eTypeMaster)
|
|
{
|
|
if (0 <= nTextMasterType && nTextMasterType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nTextMasterType].is_init())
|
|
pTextSettings->m_oStyles = pThemeWrapper->m_pStyles[nTextMasterType].get();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PT_CenterTitle:
|
|
case PT_MasterCenterTitle:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 1;
|
|
|
|
if (Tx_TYPE_TITLE != eTypeMaster)
|
|
{
|
|
if (0 <= nTextMasterType && nTextMasterType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nTextMasterType].is_init())
|
|
pTextSettings->m_oStyles = pThemeWrapper->m_pStyles[nTextMasterType].get();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case PT_Body:
|
|
case PT_MasterBody:
|
|
case PT_NotesBody:
|
|
case PT_MasterNotesBody:
|
|
case PT_VerticalBody:
|
|
case PT_MasterSubTitle:
|
|
case PT_SubTitle:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 2;
|
|
|
|
if ((Tx_TYPE_BODY != eTypeMaster) || !pLayout)
|
|
{
|
|
if (0 <= nTextMasterType && nTextMasterType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nTextMasterType].is_init())
|
|
pTextSettings->m_oStyles = pThemeWrapper->m_pStyles[nTextMasterType].get();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 3;
|
|
|
|
if ((Tx_TYPE_OTHER != eTypeMaster) || !pLayout)
|
|
{
|
|
if (0 <= nTextMasterType && nTextMasterType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nTextMasterType].is_init())
|
|
{
|
|
pTextSettings->m_oStyles = pThemeWrapper->m_pStyles[nTextMasterType].get();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//pTextSettings->m_lTextType = 0;
|
|
|
|
//if (Other != eTypeMaster)
|
|
//{
|
|
// if (0 <= nTextMasterType && nTextMasterType < 9)
|
|
// {
|
|
// if (pThemeWrapper->m_pStyles[nTextMasterType].is_init())
|
|
// pTextSettings->m_oStyles = pThemeWrapper->m_pStyles[nTextMasterType].get();
|
|
// }
|
|
//}
|
|
}
|
|
|
|
// now look at all other styles (persist and own) - just apply them to m_oStyles
|
|
if (eTypePersist != NoPresent && eTypePersist != eTypeMaster)
|
|
{
|
|
int nIndexType = (int)eTypePersist;
|
|
if (0 <= nIndexType && nIndexType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nIndexType].is_init())
|
|
pTextSettings->m_oStyles.ApplyAfter(pThemeWrapper->m_pStyles[nIndexType].get());
|
|
}
|
|
}
|
|
if (eTypeOwn != NoPresent && eTypeOwn != eTypePersist && eTypeOwn != eTypeMaster)
|
|
{
|
|
int nIndexType = (int)eTypeOwn;
|
|
if (0 <= nIndexType && nIndexType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nIndexType].is_init())
|
|
pTextSettings->m_oStyles.ApplyAfter(pThemeWrapper->m_pStyles[nIndexType].get());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (-1 != pShape->m_lPlaceholderType)
|
|
{
|
|
if (NULL != pElementLayoutPH)
|
|
{
|
|
pTextSettings->m_oLayoutStyles = pElementLayoutPH->m_pShape->m_oText.m_oStyles;
|
|
pTextSettings->m_lTextType = pElementLayoutPH->m_pShape->m_oText.m_lTextType;
|
|
pTextSettings->m_lStyleThemeIndex = pElementLayoutPH->m_pShape->m_oText.m_lStyleThemeIndex;
|
|
}
|
|
else
|
|
{
|
|
switch (oElemInfo.m_lMasterPlaceholderType)
|
|
{
|
|
case PT_Title:
|
|
case PT_MasterTitle:
|
|
case PT_VerticalTitle:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 1;
|
|
break;
|
|
}
|
|
case PT_CenterTitle:
|
|
case PT_MasterCenterTitle:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 1;
|
|
break;
|
|
}
|
|
case PT_Body:
|
|
case PT_MasterBody:
|
|
case PT_NotesBody:
|
|
case PT_MasterNotesBody:
|
|
case PT_VerticalBody:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 2;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = 3;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pTextSettings->m_lStyleThemeIndex = -1;
|
|
}
|
|
|
|
// now look at all other styles (persist and own) - just apply them to m_oStyles
|
|
if (eTypePersist != NoPresent && eTypePersist != eTypeMaster)
|
|
{
|
|
int nIndexType = (int)eTypePersist;
|
|
if (0 <= nIndexType && nIndexType < 9)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[nIndexType].is_init())
|
|
pTextSettings->m_oStyles.ApplyAfter(pThemeWrapper->m_pStyles[nIndexType].get());
|
|
}
|
|
}
|
|
if (eTypeOwn != NoPresent && eTypeOwn != Tx_TYPE_OTHER && eTypeOwn != eTypePersist && eTypeOwn != eTypeMaster)
|
|
{//齐孟尧-2015年度职工考核报告.ppt
|
|
int nIndexType = (int)eTypeOwn;
|
|
|
|
if (0 <= nIndexType && nIndexType < 9 && pLayout)
|
|
{
|
|
if (eTypeOwn == Tx_TYPE_HALFBODY || eTypeOwn == Tx_TYPE_QUARTERBODY)
|
|
{
|
|
if (pThemeWrapper->m_pStyles[1].IsInit())//body -> (560).ppt
|
|
{
|
|
pTextSettings->m_oStyles.ApplyAfter(pThemeWrapper->m_pStyles[1].get());
|
|
}
|
|
}
|
|
if (pThemeWrapper->m_pStyles[nIndexType].IsInit())
|
|
{
|
|
pTextSettings->m_oStyles.ApplyAfter(pThemeWrapper->m_pStyles[nIndexType].get());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((L"" != strText) && 0 == pTextSettings->m_arParagraphs.size())
|
|
{
|
|
// means no own settings. So just empty own settings
|
|
std::vector<CTextPFRunRecord> oArrayPF;
|
|
|
|
CTextPFRunRecord elm;
|
|
|
|
elm.m_lCount = strText.length();
|
|
elm.m_lLevel = 0;
|
|
|
|
oArrayPF.push_back(elm);
|
|
|
|
std::vector<CTextCFRunRecord> oArrayCF;
|
|
|
|
CTextCFRunRecord elm1;
|
|
elm1.m_lCount = elm.m_lCount;
|
|
|
|
oArrayCF.push_back(elm1);
|
|
|
|
PPT::ConvertPPTTextToEditorStructure(oArrayPF, oArrayCF, strText, *pTextSettings);
|
|
}
|
|
|
|
if (NULL != oElemInfo.m_pStream && -1 != oElemInfo.m_lOffsetTextProp)
|
|
{
|
|
//text language settings
|
|
LONG lPosition = 0; StreamUtils::StreamPosition(lPosition, oElemInfo.m_pStream);
|
|
|
|
StreamUtils::StreamSeek(oElemInfo.m_lOffsetTextProp - 8, oElemInfo.m_pStream);
|
|
|
|
SRecordHeader oHeader;
|
|
oHeader.ReadFromStream(oElemInfo.m_pStream) ;
|
|
|
|
if (RT_TextSpecialInfoAtom == oHeader.RecType)
|
|
{
|
|
CRecordTextSpecInfoAtom* pSpecInfo = new CRecordTextSpecInfoAtom();
|
|
pSpecInfo->m_lCount = -1;
|
|
|
|
pSpecInfo->ReadFromStream(oHeader, oElemInfo.m_pStream);
|
|
pSpecInfo->ApplyProperties(&(pShape->m_pShape->m_oText));
|
|
|
|
RELEASEOBJECT(pSpecInfo);
|
|
}
|
|
StreamUtils::StreamSeek(lPosition, oElemInfo.m_pStream);
|
|
}
|
|
pShape->m_pShape->m_oText.RecalcParagraphsPPT();
|
|
|
|
ApplyThemeStyle(pElem, pTheme, master_levels);
|
|
|
|
if (pShape->m_oTextActions.m_bPresent)
|
|
{
|
|
//todooo figure out if we need to change color for hyperlink - 1-(34).ppt
|
|
ODRAW::CColor oColor;
|
|
if ((NULL != pSlide) && !pSlide->m_bUseLayoutColorScheme) oColor = pSlide->GetColor(11);
|
|
else if ((NULL != pLayout) && (!pLayout->m_bUseThemeColorScheme)) oColor = pLayout->GetColor(11);
|
|
else if (NULL != pTheme) oColor = pTheme->GetColor(11);
|
|
oColor.m_lSchemeIndex = 11;
|
|
|
|
ApplyHyperlink(pShape, oColor);
|
|
}
|
|
|
|
CPPTShape* pPPTShape = dynamic_cast<CPPTShape*>(pShape->m_pShape->getBaseShape().get());
|
|
|
|
if (NULL != pPPTShape) // check for wordart
|
|
{
|
|
switch (pPPTShape->m_eType)
|
|
{
|
|
case sptTextPlainText:
|
|
case sptTextStop:
|
|
case sptTextTriangle:
|
|
case sptTextTriangleInverted:
|
|
case sptTextChevron:
|
|
case sptTextChevronInverted:
|
|
case sptTextRingInside:
|
|
case sptTextRingOutside:
|
|
case sptTextArchUpCurve:
|
|
case sptTextArchDownCurve:
|
|
case sptTextCircleCurve:
|
|
case sptTextButtonCurve:
|
|
case sptTextArchUpPour:
|
|
case sptTextArchDownPour:
|
|
case sptTextCirclePour:
|
|
case sptTextButtonPour:
|
|
case sptTextCurveUp:
|
|
case sptTextCurveDown:
|
|
case sptTextCascadeUp:
|
|
case sptTextCascadeDown:
|
|
case sptTextWave1:
|
|
case sptTextWave2:
|
|
case sptTextWave3:
|
|
case sptTextWave4:
|
|
case sptTextInflate:
|
|
case sptTextDeflate:
|
|
case sptTextInflateBottom:
|
|
case sptTextDeflateBottom:
|
|
case sptTextInflateTop:
|
|
case sptTextDeflateTop:
|
|
case sptTextDeflateInflate:
|
|
case sptTextDeflateInflateDeflate:
|
|
case sptTextFadeRight:
|
|
case sptTextFadeLeft:
|
|
case sptTextFadeUp:
|
|
case sptTextFadeDown:
|
|
case sptTextSlantUp:
|
|
case sptTextSlantDown:
|
|
case sptTextCanUp:
|
|
case sptTextCanDown:
|
|
{
|
|
pShape->m_pShape->m_oText.m_oAttributes.m_oTextBrush = pShape->m_oBrush;
|
|
|
|
pShape->m_pShape->m_oText.m_oAttributes.m_nTextAlignHorizontal = 1;
|
|
pShape->m_pShape->m_oText.m_oAttributes.m_nTextAlignVertical = 1;
|
|
|
|
pShape->m_pShape->m_lDrawType = c_ShapeDrawType_Text;
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
};
|
|
}
|
|
}
|
|
|
|
void CRecordShapeContainer::ApplyHyperlink(CShapeElement* pShape, CColor& oColor)
|
|
{
|
|
auto& oTextAttributes = pShape->m_pShape->m_oText;
|
|
const auto& originalText = oTextAttributes.m_originalText;
|
|
|
|
|
|
// lenght these ones shoud be equal
|
|
const auto& arrRanges = pShape->m_oTextActions.m_arRanges;
|
|
const auto arrSplitedInteractive = splitInteractive(pShape->m_textHyperlinks);
|
|
|
|
// It cannot be changed
|
|
if (arrRanges.empty() || arrSplitedInteractive.empty() || originalText.empty())
|
|
return;
|
|
|
|
size_t posOrigText(0);
|
|
auto iterRange = arrRanges.begin();
|
|
auto iterInteractive = arrSplitedInteractive.begin();
|
|
for (auto& paragraph : oTextAttributes.m_arParagraphs)
|
|
{
|
|
auto& arrSpans = paragraph.m_arSpans;
|
|
for (auto iterSpan = arrSpans.begin(); iterSpan != arrSpans.end(); iterSpan++)
|
|
{
|
|
// if there isn't needed changes in next spans & paragraps
|
|
if (iterRange == arrRanges.end())
|
|
{
|
|
return;
|
|
}
|
|
|
|
const bool isHyperlink = iterRange->inRange(posOrigText);
|
|
|
|
const int posBlockStart = posOrigText;
|
|
const int posOrigSpanEnd = posBlockStart + iterSpan->m_strText.length();
|
|
const int posBlockEnd = isHyperlink ?
|
|
(std::min)(posOrigSpanEnd, iterRange->m_lEnd) :
|
|
(std::min)(posOrigSpanEnd, iterRange->m_lStart);
|
|
const size_t blockLen = posBlockEnd - posBlockStart;
|
|
|
|
const bool isNeedToSplit = posBlockEnd < posOrigSpanEnd && isHyperlink;
|
|
|
|
// Skiping span with '\r'
|
|
if (iterSpan->m_strText.size() && (int)iterSpan->m_strText.find(L"\r") != -1)
|
|
continue;
|
|
|
|
posOrigText += blockLen;
|
|
// Skipping span
|
|
if (iterRange->m_lStart > posBlockEnd)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// HYPERLINK
|
|
if (isHyperlink)
|
|
{
|
|
// case: HYPERLINK & text(or next HYPERLINK inside original span)
|
|
if (isNeedToSplit)
|
|
{
|
|
// HYPERLINK
|
|
iterSpan->m_strText = originalText.substr(posBlockStart, blockLen);
|
|
|
|
const size_t nextBlockLen = posOrigSpanEnd - posBlockEnd;
|
|
iterSpan = arrSpans.insert(iterSpan, *iterSpan);
|
|
// Go to next new span and correct text
|
|
iterSpan++;
|
|
iterSpan->m_strText = originalText.substr(posBlockEnd, nextBlockLen);
|
|
iterSpan->m_arrInteractive.clear();
|
|
// Return to current span
|
|
iterSpan--;
|
|
}
|
|
|
|
if (iterSpan != arrSpans.end() && iterInteractive != arrSplitedInteractive.end())
|
|
addHyperlinkToSpan(*iterSpan, *iterInteractive, oColor);
|
|
else
|
|
break; //GZoabli_PhD.ppt
|
|
|
|
if (posBlockEnd == iterRange->m_lEnd)
|
|
{
|
|
iterRange++;
|
|
iterInteractive++;
|
|
}
|
|
}
|
|
// Hyperlink will be written in the next iteration
|
|
// case: text & HYPERLINK
|
|
else
|
|
{
|
|
iterSpan = arrSpans.insert(iterSpan, *iterSpan);
|
|
iterSpan->m_strText = originalText.substr(posBlockStart, blockLen);
|
|
iterSpan->m_arrInteractive.clear();
|
|
|
|
// Go to next new span and correct text
|
|
iterSpan++;
|
|
const size_t nextBlockLen = posOrigSpanEnd - posBlockEnd;
|
|
iterSpan->m_strText = originalText.substr(posBlockEnd, nextBlockLen);
|
|
iterSpan->m_arrInteractive.clear();
|
|
// Return to current span
|
|
iterSpan--;
|
|
}
|
|
}
|
|
// skipping '\r'
|
|
posOrigText++;
|
|
}
|
|
}
|
|
|
|
void CRecordShapeContainer::addHyperlinkToSpan(CSpan &oSpan, const std::vector<CInteractiveInfo> &arrInteractive, const CColor &oColor)
|
|
{
|
|
if (isRealHyperlink(arrInteractive))
|
|
{
|
|
oSpan.m_oRun.Color = oColor;
|
|
oSpan.m_oRun.FontUnderline = (bool)true;
|
|
oSpan.m_arrInteractive = arrInteractive;
|
|
}
|
|
}
|
|
|
|
bool CRecordShapeContainer::isRealHyperlink(const std::vector<CInteractiveInfo> &arrInteractive)
|
|
{
|
|
bool isReal = false;
|
|
for (const auto& interInfo : arrInteractive)
|
|
{
|
|
switch (interInfo.m_lHyperlinkType)
|
|
{
|
|
case LT_Url:
|
|
if (interInfo.m_strHyperlink.size())
|
|
isReal = true;
|
|
break;
|
|
default:
|
|
isReal = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return isReal;
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::vector<CInteractiveInfo> > CRecordShapeContainer::splitInteractive(const std::vector<CInteractiveInfo> &arrInteractive)
|
|
{
|
|
std::vector<std::vector<CInteractiveInfo> > splited;
|
|
std::vector<CInteractiveInfo> inserting;
|
|
for (const auto& interactive : arrInteractive)
|
|
{
|
|
if (interactive.m_eActivation == interactive.click && !inserting.empty())
|
|
splited.push_back(std::move(inserting));
|
|
inserting.push_back(interactive);
|
|
}
|
|
if (!inserting.empty())
|
|
splited.push_back(std::move(inserting));
|
|
|
|
return splited;
|
|
}
|
|
|
|
void CRecordShapeContainer::ConvertInteractiveInfo(CInteractiveInfo &interactiveInfo, const CRecordMouseInteractiveInfoContainer *interactiveCont, CExMedia *pMapIDs)
|
|
{
|
|
|
|
auto& interactiveAtom = interactiveCont->interactiveInfoAtom;
|
|
interactiveInfo.m_bPresent = true;
|
|
interactiveInfo.m_eActivation = interactiveCont->isOver;
|
|
|
|
if (pMapIDs)
|
|
{
|
|
CExFilesInfo* pInfo1 = pMapIDs->LockAudioFromCollection(interactiveAtom.m_nSoundIdRef);
|
|
if (NULL != pInfo1)
|
|
{
|
|
interactiveInfo.m_strAudioFileName = pInfo1->m_strFilePath;
|
|
interactiveInfo.m_strAudioName = pInfo1->m_name;
|
|
}
|
|
CExFilesInfo* pInfo2 = pMapIDs->LockSlide(interactiveAtom.m_nExHyperlinkIdRef);
|
|
if (NULL != pInfo2)
|
|
{
|
|
interactiveInfo.m_strHyperlink = pInfo2->m_strFilePath;
|
|
} else {
|
|
pInfo2 = pMapIDs->LockHyperlink(interactiveAtom.m_nExHyperlinkIdRef);
|
|
if (NULL != pInfo2)
|
|
{
|
|
interactiveInfo.m_strHyperlink = pInfo2->m_strFilePath;
|
|
}
|
|
}
|
|
}
|
|
if (interactiveCont->macroNameAtom.is_init())
|
|
interactiveInfo.m_macro = interactiveCont->macroNameAtom->m_strText;
|
|
|
|
interactiveInfo.m_lType = interactiveAtom.m_nAction;
|
|
interactiveInfo.m_lOleVerb = interactiveAtom.m_nOleVerb;
|
|
interactiveInfo.m_lJump = interactiveAtom.m_nJump;
|
|
interactiveInfo.m_lHyperlinkType = interactiveAtom.m_nHyperlinkType;
|
|
|
|
interactiveInfo.m_bAnimated = interactiveAtom.m_bAnimated;
|
|
interactiveInfo.m_bStopSound = interactiveAtom.m_bStopSound;
|
|
interactiveInfo.m_bCustomShowReturn = interactiveAtom.m_bCustomShowReturn;
|
|
interactiveInfo.m_bVisited = interactiveAtom.m_bVisited;
|
|
|
|
}
|
|
|
|
void CRecordShapeContainer::ConvertStyleTextProp9(CTextAttributesEx *pText)
|
|
{
|
|
|
|
std::vector<CRecordOfficeArtClientData*> arrOfficeData;
|
|
GetRecordsByType(&arrOfficeData, false, true);
|
|
|
|
if (arrOfficeData.empty())
|
|
return;
|
|
|
|
auto pUnknownBinaryTag =arrOfficeData[0]->getProgTag(___PPT9);
|
|
if (pUnknownBinaryTag == nullptr)
|
|
return;
|
|
auto progTag9 = dynamic_cast<CRecordPP9ShapeBinaryTagExtension*>(pUnknownBinaryTag->m_pTagContainer);
|
|
if (progTag9 == nullptr)
|
|
return;
|
|
|
|
const auto& arrStyleTextProp9 = progTag9->m_styleTextPropAtom.m_rgStyleTextProp9;
|
|
if (arrStyleTextProp9.empty())
|
|
return;
|
|
|
|
WORD pp9rt = 0;
|
|
auto& arrPars = pText->m_arParagraphs;
|
|
for (auto& par : arrPars)
|
|
{
|
|
if (par.m_arSpans.empty())
|
|
continue;
|
|
|
|
if (par.m_arSpans[0].m_oRun.pp9rt.is_init())
|
|
pp9rt = par.m_arSpans[0].m_oRun.pp9rt.get();
|
|
|
|
if (pp9rt >= arrStyleTextProp9.size())
|
|
continue;
|
|
|
|
auto& prop9 = arrStyleTextProp9[pp9rt];
|
|
|
|
if (prop9.m_pf9.m_optBulletAutoNumberScheme.is_init() &&
|
|
prop9.m_pf9.m_optfBulletHasAutoNumber.get_value_or(false))
|
|
{
|
|
auto* pBuAutoNum = new CBulletAutoNum;
|
|
pBuAutoNum->type = prop9.m_pf9.m_optBulletAutoNumberScheme->SchemeToStr();
|
|
pBuAutoNum->startAt = prop9.m_pf9.m_optBulletAutoNumberScheme->m_nStartNum;
|
|
|
|
par.m_oPFRun.bulletAutoNum.reset(pBuAutoNum);
|
|
}
|
|
if (prop9.m_pf9.m_optBulletBlipRef.is_init())
|
|
{
|
|
auto* pBuBlip = new CBulletBlip;
|
|
if (prop9.m_pf9.m_optBulletBlipRef.IsInit())
|
|
pBuBlip->bulletBlipRef = prop9.m_pf9.m_optBulletBlipRef.get();
|
|
else
|
|
pBuBlip->bulletBlipRef = -1;
|
|
|
|
par.m_oPFRun.bulletBlip.reset(pBuBlip);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//void CRecordShapeContainer::ConvertExtention9(CElement* pElement)
|
|
//{
|
|
// if (pElement == nullptr)
|
|
// return;
|
|
|
|
// std::vector<CRecordOfficeArtClientData*> arrOfficeData;
|
|
// GetRecordsByType(&arrOfficeData, false, true);
|
|
|
|
// if (arrOfficeData.empty())
|
|
// return;
|
|
|
|
// auto pUnknownBinaryTag =arrOfficeData[0]->getProgTag(___PPT9);
|
|
// if (pUnknownBinaryTag == nullptr)
|
|
// return;
|
|
// auto progTag9 = dynamic_cast<CRecordPP9ShapeBinaryTagExtension*>(pUnknownBinaryTag->m_pTagContainer);
|
|
// if (progTag9 == nullptr)
|
|
// return;
|
|
|
|
// const auto& arrStyleTextProp9 = progTag9->m_styleTextPropAtom.m_rgStyleTextProp9;
|
|
|
|
// for (const auto& textProp9 : arrStyleTextProp9)
|
|
// {
|
|
// CBulletBlip buBlip;
|
|
// if (textProp9.m_pf9.m_optBulletBlipRef.IsInit())
|
|
// buBlip.bulletBlipRef = textProp9.m_pf9.m_optBulletBlipRef.get();
|
|
// else
|
|
// buBlip.bulletBlipRef = -1;
|
|
|
|
// pElement->m_arrBlip.push_back(buBlip);
|
|
// }
|
|
|
|
//}
|
|
|
|
//void CRecordGroupShapeContainer::ReadFromStream(SRecordHeader & oHeader, POLE::Stream* pStream)
|
|
//{
|
|
// CRecordsContainer::ReadFromStream(oHeader, pStream);
|
|
|
|
//}
|