mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-21 01:10:35 +08:00
825 lines
22 KiB
C++
825 lines
22 KiB
C++
#ifndef _METAFILE_EMF_EMFPLUSOBJECTS_H
|
|
#define _METAFILE_EMF_EMFPLUSOBJECTS_H
|
|
|
|
#include "EmfPath.h"
|
|
#include "EmfObjects.h"
|
|
#include "EmfPlusTypes.h"
|
|
#include "../../../common/File.h"
|
|
#include "../Common/MetaFileObjects.h"
|
|
|
|
namespace MetaFile
|
|
{
|
|
typedef enum
|
|
{
|
|
ObjectTypeInvalid = 0x00,
|
|
ObjectTypeBrush = 0x01,
|
|
ObjectTypePen = 0x02,
|
|
ObjectTypePath = 0x03,
|
|
ObjectTypeRegion = 0x04,
|
|
ObjectTypeImage = 0x05,
|
|
ObjectTypeFont = 0x06,
|
|
ObjectTypeStringFormat = 0x07,
|
|
ObjectTypeImageAttributes = 0x08,
|
|
ObjectTypeCustomLineCap = 0x09
|
|
} EEmfPlusObjectType;
|
|
|
|
#define CEmfPlusObjectBase CEmfObjectBase
|
|
#define CEmfPlusDC CEmfDC
|
|
|
|
typedef enum
|
|
{
|
|
BrushTypeSolidColor = 0x00,
|
|
BrushTypeHatchFill = 0x01,
|
|
BrushTypeTextureFill = 0x02,
|
|
BrushTypePathGradient = 0x03,
|
|
BrushTypeLinearGradient = 0x04
|
|
} EEmfPlusBrushType;
|
|
|
|
#define PEN_DATA_TRANSFORM 0x00000001
|
|
#define PEN_DATA_STARTCAP 0x00000002
|
|
#define PEN_DATA_ENDCAP 0x00000004
|
|
#define PEN_DATA_JOIN 0x00000008
|
|
#define PEN_DATA_MITERLIMIT 0x00000010
|
|
#define PEN_DATA_LINESTYLE 0x00000020
|
|
#define PEN_DATA_DASHEDLINECAP 0x00000040
|
|
#define PEN_DATA_DASHEDLINEOFFSET 0x00000080
|
|
#define PEN_DATA_DASHEDLINE 0x00000100
|
|
#define PEN_DATA_NONCENTER 0x00000200
|
|
#define PEN_DATA_COMPOUNDLINE 0x00000400
|
|
#define PEN_DATA_CUSTOMSTARTCAP 0x00000800
|
|
#define PEN_DATA_CUSTOMENDCAP 0x00001000
|
|
|
|
#define PS_STARTCAP_ROUND 0x00000040
|
|
#define PS_STARTCAP_SQUARE 0x00000050
|
|
#define PS_STARTCAP_FLAT 0x00000060
|
|
#define PS_STARTCAP_MASK 0x000000F0
|
|
|
|
typedef enum
|
|
{
|
|
ImageDataTypeUnknown = 0x00,
|
|
ImageDataTypeBitmap = 0x01,
|
|
ImageDataTypeMetafile = 0x02
|
|
} EEmfPlusImageDataType;
|
|
|
|
typedef enum
|
|
{
|
|
BitmapDataTypePixel = 0x00,
|
|
BitmapDataTypeCompressed = 0x01,
|
|
BitmapDataTypeUnknow = 0x02
|
|
} EEmfPlusBitmapDataType;
|
|
|
|
typedef enum
|
|
{
|
|
MetafileDataTypeUnknown = 0x00,
|
|
MetafileDataTypeWmf = 0x01,
|
|
MetafileDataTypeWmfPlaceable = 0x02,
|
|
MetafileDataTypeEmf = 0x03,
|
|
MetafileDataTypeEmfPlusOnly = 0x04,
|
|
MetafileDataTypeEmfPlusDual = 0x05
|
|
} EEmfPlusMetafileDataType;
|
|
|
|
class CEmfPlusObject : public CEmfPlusObjectBase
|
|
{
|
|
public:
|
|
CEmfPlusObject(){};
|
|
virtual ~CEmfPlusObject(){};
|
|
|
|
virtual EEmfPlusObjectType GetObjectType()
|
|
{
|
|
return ObjectTypeInvalid;
|
|
}
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
HatchStyleHorizontal = 0x00000000,
|
|
HatchStyleVertical = 0x00000001,
|
|
HatchStyleForwardDiagonal = 0x00000002,
|
|
HatchStyleBackwardDiagonal = 0x00000003,
|
|
HatchStyleLargeGrid = 0x00000004,
|
|
HatchStyleDiagonalCross = 0x00000005,
|
|
HatchStyle05Percent = 0x00000006,
|
|
HatchStyle10Percent = 0x00000007,
|
|
HatchStyle20Percent = 0x00000008,
|
|
HatchStyle25Percent = 0x00000009,
|
|
HatchStyle30Percent = 0x0000000A,
|
|
HatchStyle40Percent = 0x0000000B,
|
|
HatchStyle50Percent = 0x0000000C,
|
|
HatchStyle60Percent = 0x0000000D,
|
|
HatchStyle70Percent = 0x0000000E,
|
|
HatchStyle75Percent = 0x0000000F,
|
|
HatchStyle80Percent = 0x00000010,
|
|
HatchStyle90Percent = 0x00000011,
|
|
HatchStyleLightDownwardDiagonal = 0x00000012,
|
|
HatchStyleLightUpwardDiagonal = 0x00000013,
|
|
HatchStyleDarkDownwardDiagonal = 0x00000014,
|
|
HatchStyleDarkUpwardDiagonal = 0x00000015,
|
|
HatchStyleWideDownwardDiagonal = 0x00000016,
|
|
HatchStyleWideUpwardDiagonal = 0x00000017,
|
|
HatchStyleLightVertical = 0x00000018,
|
|
HatchStyleLightHorizontal = 0x00000019,
|
|
HatchStyleNarrowVertical = 0x0000001A,
|
|
HatchStyleNarrowHorizontal = 0x0000001B,
|
|
HatchStyleDarkVertical = 0x0000001C,
|
|
HatchStyleDarkHorizontal = 0x0000001D,
|
|
HatchStyleDashedDownwardDiagonal = 0x0000001E,
|
|
HatchStyleDashedUpwardDiagonal = 0x0000001F,
|
|
HatchStyleDashedHorizontal = 0x00000020,
|
|
HatchStyleDashedVertical = 0x00000021,
|
|
HatchStyleSmallConfetti = 0x00000022,
|
|
HatchStyleLargeConfetti = 0x00000023,
|
|
HatchStyleZigZag = 0x00000024,
|
|
HatchStyleWave = 0x00000025,
|
|
HatchStyleDiagonalBrick = 0x00000026,
|
|
HatchStyleHorizontalBrick = 0x00000027,
|
|
HatchStyleWeave = 0x00000028,
|
|
HatchStylePlaid = 0x00000029,
|
|
HatchStyleDivot = 0x0000002A,
|
|
HatchStyleDottedGrid = 0x0000002B,
|
|
HatchStyleDottedDiamond = 0x0000002C,
|
|
HatchStyleShingle = 0x0000002D,
|
|
HatchStyleTrellis = 0x0000002E,
|
|
HatchStyleSphere = 0x0000002F,
|
|
HatchStyleSmallGrid = 0x00000030,
|
|
HatchStyleSmallCheckerBoard = 0x00000031,
|
|
HatchStyleLargeCheckerBoard = 0x00000032,
|
|
HatchStyleOutlinedDiamond = 0x00000033,
|
|
HatchStyleSolidDiamond = 0x00000034
|
|
} EEmfPlusHatchStyle;
|
|
|
|
typedef enum
|
|
{
|
|
BrushDataPath = 0x00000001,
|
|
BrushDataTransform = 0x00000002,
|
|
BrushDataPresetColors = 0x00000004,
|
|
BrushDataBlendFactorsH = 0x00000008,
|
|
BrushDataBlendFactorsV = 0x00000010,
|
|
BrushDataFocusScales = 0x00000040,
|
|
BrushDataIsGammaCorrected = 0x00000080,
|
|
BrushDataDoNotTransform = 0x00000100
|
|
} EEmfPlusBrushDataFlags;
|
|
|
|
class CEmfPlusBrush : public CEmfPlusObject, public IBrush
|
|
{
|
|
public:
|
|
CEmfPlusBrush() : CEmfPlusObject(), Style(BS_SOLID), Hatch(0), Angle(0) {};
|
|
virtual ~CEmfPlusBrush()
|
|
{
|
|
if (!DibPatterPath.empty() && NSFile::CFileBinary::Exists(DibPatterPath))
|
|
NSFile::CFileBinary::Remove(DibPatterPath);
|
|
|
|
};
|
|
virtual EEmfObjectType GetType() override
|
|
{
|
|
return EMF_OBJECT_BRUSH;
|
|
}
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypeBrush;
|
|
}
|
|
|
|
int GetColor()
|
|
{
|
|
return METAFILE_RGBA(Color.chRed, Color.chGreen, Color.chBlue);
|
|
}
|
|
|
|
int GetColor2()
|
|
{
|
|
return METAFILE_RGBA(ColorBack.chRed, ColorBack.chGreen, ColorBack.chBlue);
|
|
}
|
|
|
|
unsigned int GetStyle()
|
|
{
|
|
return Style;
|
|
}
|
|
|
|
unsigned int GetStyleEx()
|
|
{
|
|
return Angle;
|
|
}
|
|
|
|
unsigned int GetHatch()
|
|
{
|
|
return Hatch;
|
|
}
|
|
|
|
unsigned int GetAlpha()
|
|
{
|
|
return Color.chAlpha;
|
|
}
|
|
|
|
unsigned int GetAlpha2()
|
|
{
|
|
return ColorBack.chAlpha;
|
|
}
|
|
|
|
std::wstring GetDibPatterPath()
|
|
{
|
|
return DibPatterPath;
|
|
}
|
|
|
|
void GetBounds(double& left, double& top, double& width, double& height)
|
|
{
|
|
left = RectF.dX;
|
|
top = RectF.dY;
|
|
width = RectF.dWidth;
|
|
height = RectF.dHeight;
|
|
};
|
|
|
|
TEmfPlusARGB Color;
|
|
TEmfPlusARGB ColorBack;
|
|
unsigned int Style;
|
|
unsigned int Hatch;
|
|
TEmfPlusRectF RectF;
|
|
unsigned int Angle;
|
|
std::wstring DibPatterPath;
|
|
};
|
|
|
|
class CEmfPlusPen: public CEmfPlusObject, public IPen
|
|
{
|
|
public:
|
|
CEmfPlusPen() : Style(PS_SOLID), Width(1), Color(0, 0, 0),
|
|
Brush(NULL), MiterLimit(0), DashOffset(0),
|
|
DataDash(NULL), SizeDash(0), LineStartCapData(NULL), LineEndCapData(NULL) {}
|
|
virtual ~CEmfPlusPen() { RELEASEOBJECT(Brush)
|
|
RELEASEARRAYOBJECTS(DataDash)
|
|
RELEASEOBJECT(LineStartCapData)
|
|
RELEASEOBJECT(LineEndCapData)}
|
|
virtual EEmfObjectType GetType()
|
|
{
|
|
return EMF_OBJECT_PEN;
|
|
}
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypePen;
|
|
}
|
|
|
|
int GetColor()
|
|
{
|
|
if (NULL != Brush)
|
|
return Brush->GetColor();
|
|
|
|
return METAFILE_RGBA(Color.chRed, Color.chGreen, Color.chBlue);
|
|
};
|
|
|
|
unsigned int GetStyle()
|
|
{
|
|
return Style;
|
|
}
|
|
|
|
double GetWidth()
|
|
{
|
|
if (Width < 0)
|
|
return 1;
|
|
|
|
return Width;
|
|
}
|
|
|
|
unsigned int GetAlpha()
|
|
{
|
|
if (NULL != Brush)
|
|
return Brush->Color.chAlpha;
|
|
|
|
return 255;
|
|
// return (unsigned int)Color.chAlpha;
|
|
}
|
|
|
|
double GetMiterLimit()
|
|
{
|
|
return MiterLimit;
|
|
}
|
|
|
|
double GetDashOffset()
|
|
{
|
|
return DashOffset;
|
|
}
|
|
|
|
void GetDashData(double*& arDatas, unsigned int& unSize)
|
|
{
|
|
arDatas = DataDash;
|
|
unSize = SizeDash;
|
|
}
|
|
|
|
unsigned int Style;
|
|
double Width;
|
|
TEmfPlusARGB Color;
|
|
CEmfPlusBrush *Brush;
|
|
double MiterLimit;
|
|
double DashOffset;
|
|
double* DataDash;
|
|
unsigned int SizeDash;
|
|
|
|
CLineCapData *LineStartCapData;
|
|
CLineCapData *LineEndCapData;
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
FontStyleBold = 0x00000001,
|
|
FontStyleItalic = 0x00000002,
|
|
FontStyleUnderline = 0x00000004,
|
|
FontStyleStrikeout = 0x00000008
|
|
} EEmfPlusFontStyle;
|
|
|
|
class CEmfPlusFont : public CEmfPlusObject, public IFont
|
|
{
|
|
public:
|
|
CEmfPlusFont() : m_dEmSize(18), m_unSizeUnit(0), m_bBold(false),
|
|
m_bItalic(false), m_bUnderline(false), m_bStrikeout(false),
|
|
m_wsFamilyName(L""){}
|
|
virtual ~CEmfPlusFont() {}
|
|
|
|
virtual EEmfObjectType GetType() override
|
|
{
|
|
return EMF_OBJECT_FONT;
|
|
}
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypeFont;
|
|
}
|
|
|
|
double GetHeight()
|
|
{
|
|
return m_dEmSize;
|
|
}
|
|
|
|
std::wstring GetFaceName()
|
|
{
|
|
return m_wsFamilyName;
|
|
}
|
|
|
|
int GetWeight()
|
|
{
|
|
return (m_bBold) ? 700 : 400;
|
|
}
|
|
|
|
bool IsItalic()
|
|
{
|
|
return m_bItalic;
|
|
}
|
|
|
|
bool IsStrikeOut()
|
|
{
|
|
return m_bStrikeout;
|
|
}
|
|
bool IsUnderline()
|
|
{
|
|
return m_bUnderline;
|
|
}
|
|
int GetEscapement()
|
|
{
|
|
return 0;
|
|
}
|
|
int GetCharSet()
|
|
{
|
|
return 0;
|
|
}
|
|
int GetOrientation()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
double m_dEmSize;
|
|
unsigned int m_unSizeUnit;
|
|
bool m_bBold;
|
|
bool m_bItalic;
|
|
bool m_bUnderline;
|
|
bool m_bStrikeout;
|
|
std::wstring m_wsFamilyName;
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
PathPointTypeStart = 0x00,
|
|
PathPointTypeLine = 0x01,
|
|
PathPointTypeBezier = 0x03
|
|
} EEmfPlusPathPointType;
|
|
|
|
class CEmfPlusPath : public CEmfPlusObject, public CEmfPath
|
|
{
|
|
public:
|
|
CEmfPlusPath() : CEmfPlusObject(), CEmfPath() {};
|
|
CEmfPlusPath(CEmfPlusPath* pPath) : CEmfPlusObject(), CEmfPath(pPath) {};
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypePath;
|
|
}
|
|
|
|
void Clear()
|
|
{
|
|
CEmfPath::Clear();
|
|
}
|
|
|
|
TRectD ConvertToRect() const
|
|
{
|
|
TRectD oRect;
|
|
|
|
oRect.dRight = oRect.dBottom = 0;
|
|
|
|
for (unsigned int ulIndex = 0; ulIndex < m_pCommands.size(); ulIndex++)
|
|
{
|
|
CEmfPathCommandBase* pCommand = m_pCommands.at(ulIndex);
|
|
switch (pCommand->GetType())
|
|
{
|
|
case EMF_PATHCOMMAND_MOVETO:
|
|
{
|
|
CEmfPathMoveTo* pMoveTo = (CEmfPathMoveTo*)pCommand;
|
|
|
|
oRect.dLeft = std::min(oRect.dLeft, pMoveTo->x);
|
|
oRect.dTop = std::min(oRect.dTop, pMoveTo->y);
|
|
oRect.dRight = std::max(oRect.dRight, pMoveTo->x);
|
|
oRect.dBottom = std::max(oRect.dBottom, pMoveTo->y);
|
|
|
|
break;
|
|
}
|
|
case EMF_PATHCOMMAND_LINETO:
|
|
{
|
|
CEmfPathLineTo* pLineTo = (CEmfPathLineTo*)pCommand;
|
|
|
|
oRect.dLeft = std::min(oRect.dLeft, pLineTo->x);
|
|
oRect.dTop = std::min(oRect.dTop, pLineTo->y);
|
|
oRect.dRight = std::max(oRect.dRight, pLineTo->x);
|
|
oRect.dBottom = std::max(oRect.dBottom, pLineTo->y);
|
|
|
|
break;
|
|
}
|
|
case EMF_PATHCOMMAND_CLOSE: return oRect;
|
|
}
|
|
}
|
|
|
|
return oRect;
|
|
}
|
|
};
|
|
|
|
|
|
typedef enum
|
|
{
|
|
WrapModeTile = 0x00,
|
|
WrapModeTileFlipX = 0x01,
|
|
WrapModeTileFlipY = 0x02,
|
|
WrapModeTileFlipXY = 0x03,
|
|
WrapModeClamp = 0x04
|
|
} EEmfPlusWrapMode;
|
|
|
|
class CEmfPlusImageAttributes : public CEmfPlusObject
|
|
{
|
|
public:
|
|
CEmfPlusImageAttributes() : CEmfPlusObject() {};
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypeImageAttributes;
|
|
}
|
|
|
|
EEmfPlusWrapMode eWrapMode;
|
|
TEmfPlusARGB oClampColor;
|
|
int nObjectClamp;
|
|
};
|
|
|
|
class CEmfPlusImage : public CEmfPlusObject
|
|
{
|
|
public:
|
|
CEmfPlusImage() : CEmfPlusObject(), m_pImageBuffer(NULL), m_ulPosition(0),
|
|
m_ulFullSize(0), m_eImageDataType(ImageDataTypeUnknown),
|
|
m_eMetafileDataType(MetafileDataTypeUnknown){};
|
|
virtual ~CEmfPlusImage()
|
|
{
|
|
if (NULL != m_pImageBuffer)
|
|
delete [] m_pImageBuffer;
|
|
};
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypeImage;
|
|
}
|
|
|
|
void SetImageDataType(unsigned int unImageDataType)
|
|
{
|
|
if (ImageDataTypeBitmap == unImageDataType)
|
|
m_eImageDataType = ImageDataTypeBitmap;
|
|
else if (ImageDataTypeMetafile == unImageDataType)
|
|
m_eImageDataType = ImageDataTypeMetafile;
|
|
}
|
|
|
|
EEmfPlusImageDataType GetImageDataType() const
|
|
{
|
|
return m_eImageDataType;
|
|
}
|
|
|
|
bool SetMetafileType(unsigned int unType)
|
|
{
|
|
switch (unType)
|
|
{
|
|
case 1: m_eMetafileDataType = MetafileDataTypeWmf; return true;
|
|
case 2: m_eMetafileDataType = MetafileDataTypeWmfPlaceable; return true;
|
|
case 3: m_eMetafileDataType = MetafileDataTypeEmf; return true;
|
|
case 4: m_eMetafileDataType = MetafileDataTypeEmfPlusOnly; return true;
|
|
case 5: m_eMetafileDataType = MetafileDataTypeEmfPlusDual; return true;
|
|
default:m_eMetafileDataType = MetafileDataTypeUnknown; return false;
|
|
}
|
|
|
|
}
|
|
|
|
EEmfPlusMetafileDataType GetMetafileType() const
|
|
{
|
|
return m_eMetafileDataType;
|
|
}
|
|
|
|
void SetSizeData(unsigned int unSize)
|
|
{
|
|
if (NULL != m_pImageBuffer)
|
|
delete [] m_pImageBuffer;
|
|
|
|
m_pImageBuffer = new BYTE[unSize];
|
|
m_ulFullSize = unSize;
|
|
}
|
|
|
|
unsigned int GetUnreadSize() const
|
|
{
|
|
return (m_ulFullSize - m_ulPosition);
|
|
}
|
|
|
|
void AddData(BYTE *pData, unsigned int unSize)
|
|
{
|
|
if (NULL == m_pImageBuffer && 0 == m_ulFullSize && 0 < unSize)
|
|
{
|
|
SetSizeData(unSize);
|
|
}
|
|
else if (0 == m_ulFullSize)
|
|
return;
|
|
|
|
if (unSize + m_ulPosition > m_ulFullSize)
|
|
unSize = m_ulFullSize - m_ulPosition;
|
|
|
|
memcpy(m_pImageBuffer + m_ulPosition * sizeof (BYTE), pData, unSize);
|
|
|
|
m_ulPosition += unSize;
|
|
}
|
|
|
|
void GetData(BYTE*& pBuffer, unsigned int& unSize) const
|
|
{
|
|
pBuffer = m_pImageBuffer;
|
|
unSize = m_ulPosition;
|
|
}
|
|
|
|
private:
|
|
BYTE* m_pImageBuffer;
|
|
ULONG m_ulPosition;
|
|
ULONG m_ulFullSize;
|
|
|
|
EEmfPlusImageDataType m_eImageDataType;
|
|
EEmfPlusMetafileDataType m_eMetafileDataType;
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
RegionNodeDataTypeAnd = 0x00000001,
|
|
RegionNodeDataTypeOr = 0x00000002,
|
|
RegionNodeDataTypeXor = 0x00000003,
|
|
RegionNodeDataTypeExclude = 0x00000004,
|
|
RegionNodeDataTypeComplement = 0x00000005,
|
|
RegionNodeDataTypeRect = 0x10000000,
|
|
RegionNodeDataTypePath = 0x10000001,
|
|
RegionNodeDataTypeEmpty = 0x10000002,
|
|
RegionNodeDataTypeInfinite = 0x10000003
|
|
} EEmfPlusRegionNodeDataType;
|
|
|
|
typedef enum
|
|
{
|
|
EmfPLusRegionNodeTypeEmpty = 0,
|
|
EmfPLusRegionNodeTypePath = 1,
|
|
EmfPLusRegionNodeTypeRectF = 2,
|
|
EmfPLusRegionNodeTypeChild = 3
|
|
} EEmfPLusRegionNodeType;
|
|
|
|
class CEmfPlusRegionNode
|
|
{
|
|
public:
|
|
CEmfPlusRegionNode() {};
|
|
virtual ~CEmfPlusRegionNode() {};
|
|
|
|
EEmfPlusRegionNodeDataType GetType() const
|
|
{
|
|
return eType;
|
|
}
|
|
|
|
EEmfPLusRegionNodeType GetNodeType() const
|
|
{
|
|
return EmfPLusRegionNodeTypeEmpty;
|
|
}
|
|
|
|
EEmfPlusRegionNodeDataType eType;
|
|
};
|
|
|
|
class CEmfPlusRegionNodePath : public CEmfPlusRegionNode
|
|
{
|
|
public:
|
|
CEmfPlusRegionNodePath() : pPath(NULL) {};
|
|
virtual ~CEmfPlusRegionNodePath()
|
|
{
|
|
RELEASEOBJECT(pPath);
|
|
}
|
|
|
|
EEmfPLusRegionNodeType GetNodeType()
|
|
{
|
|
return EmfPLusRegionNodeTypePath;
|
|
}
|
|
|
|
bool Empty() const
|
|
{
|
|
return (NULL == pPath);
|
|
}
|
|
|
|
CEmfPlusPath* GetPath() const
|
|
{
|
|
return pPath;
|
|
}
|
|
|
|
CEmfPlusPath *pPath;
|
|
};
|
|
|
|
class CEmfPlusRegionNodeRectF : public CEmfPlusRegionNode
|
|
{
|
|
public:
|
|
CEmfPlusRegionNodeRectF() : pRect(NULL) {}
|
|
virtual ~CEmfPlusRegionNodeRectF()
|
|
{
|
|
RELEASEOBJECT(pRect);
|
|
}
|
|
|
|
EEmfPLusRegionNodeType GetNodeType()
|
|
{
|
|
return EmfPLusRegionNodeTypeRectF;
|
|
}
|
|
|
|
bool Empty() const
|
|
{
|
|
return NULL == pRect;
|
|
}
|
|
|
|
TEmfPlusRectF* GetRect() const
|
|
{
|
|
return pRect;
|
|
}
|
|
|
|
TEmfPlusRectF* pRect;
|
|
};
|
|
|
|
class CEmfPlusRegionNodeChild : public CEmfPlusRegionNode
|
|
{
|
|
public:
|
|
CEmfPlusRegionNodeChild() : pLeft(NULL), pRigth(NULL) {};
|
|
virtual ~CEmfPlusRegionNodeChild()
|
|
{
|
|
RELEASEOBJECT(pLeft);
|
|
RELEASEOBJECT(pRigth);
|
|
}
|
|
|
|
EEmfPLusRegionNodeType GetNodeType()
|
|
{
|
|
return EmfPLusRegionNodeTypeChild;
|
|
}
|
|
|
|
void ClipRegionOnRenderer(IOutputDevice* pOutput, TRect* pOutRect = NULL)
|
|
{
|
|
if (NULL == pOutput)
|
|
return;
|
|
|
|
unsigned int unType;
|
|
|
|
switch (eType)
|
|
{
|
|
case RegionNodeDataTypeAnd:
|
|
case RegionNodeDataTypeExclude:
|
|
case RegionNodeDataTypeComplement:
|
|
{
|
|
unType = RGN_AND;
|
|
break;
|
|
}
|
|
case RegionNodeDataTypeOr:
|
|
{
|
|
unType = RGN_OR;
|
|
break;
|
|
}
|
|
case RegionNodeDataTypeXor:
|
|
{
|
|
unType = RGN_XOR;
|
|
break;
|
|
}
|
|
default: return;
|
|
}
|
|
|
|
pOutput->StartClipPath(unType, ALTERNATE);
|
|
|
|
for (CEmfPlusRegionNode *pNode : std::vector<CEmfPlusRegionNode*>{pLeft, pRigth})
|
|
{
|
|
switch (pNode->GetNodeType())
|
|
{
|
|
case EmfPLusRegionNodeTypeEmpty:
|
|
{
|
|
if (NULL != pOutRect)
|
|
{
|
|
pOutput->MoveTo(pOutRect->nLeft, pOutRect->nTop);
|
|
pOutput->LineTo(pOutRect->nRight, pOutRect->nTop);
|
|
pOutput->LineTo(pOutRect->nRight, pOutRect->nBottom);
|
|
pOutput->LineTo(pOutRect->nLeft, pOutRect->nBottom);
|
|
pOutput->ClosePath();
|
|
}
|
|
break;
|
|
}
|
|
case EmfPLusRegionNodeTypePath:
|
|
{
|
|
CEmfPlusRegionNodePath *pRegionNodePath = (CEmfPlusRegionNodePath*)pNode;
|
|
|
|
if (!pRegionNodePath->Empty())
|
|
{
|
|
for (unsigned int ulIndex = 0; ulIndex < pRegionNodePath->GetPath()->m_pCommands.size(); ulIndex++)
|
|
{
|
|
CEmfPathCommandBase* pCommand = pRegionNodePath->GetPath()->m_pCommands.at(ulIndex);
|
|
switch (pCommand->GetType())
|
|
{
|
|
case EMF_PATHCOMMAND_MOVETO:
|
|
{
|
|
CEmfPathMoveTo* pMoveTo = (CEmfPathMoveTo*)pCommand;
|
|
pOutput->MoveTo(pMoveTo->x, pMoveTo->y);
|
|
break;
|
|
}
|
|
case EMF_PATHCOMMAND_LINETO:
|
|
{
|
|
CEmfPathLineTo* pLineTo = (CEmfPathLineTo*)pCommand;
|
|
pOutput->LineTo(pLineTo->x, pLineTo->y);
|
|
break;
|
|
}
|
|
case EMF_PATHCOMMAND_CURVETO:
|
|
{
|
|
CEmfPathCurveTo* pCurveTo = (CEmfPathCurveTo*)pCommand;
|
|
pOutput->CurveTo(pCurveTo->x1, pCurveTo->y1, pCurveTo->x2, pCurveTo->y2, pCurveTo->xE, pCurveTo->yE);
|
|
break;
|
|
}
|
|
case EMF_PATHCOMMAND_ARCTO:
|
|
{
|
|
CEmfPathArcTo* pArcTo = (CEmfPathArcTo*)pCommand;
|
|
pOutput->ArcTo(pArcTo->left, pArcTo->top, pArcTo->right, pArcTo->bottom, pArcTo->start, pArcTo->sweep);
|
|
break;
|
|
}
|
|
case EMF_PATHCOMMAND_CLOSE:
|
|
{
|
|
pOutput->ClosePath();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
case EmfPLusRegionNodeTypeRectF:
|
|
{
|
|
CEmfPlusRegionNodeRectF *pRegionNodeRectF = (CEmfPlusRegionNodeRectF*)pNode;
|
|
|
|
if (!pRegionNodeRectF->Empty())
|
|
{
|
|
TRectD oRect = pRegionNodeRectF->GetRect()->GetRectD();
|
|
|
|
pOutput->MoveTo(oRect.dLeft, oRect.dTop);
|
|
pOutput->LineTo(oRect.dRight, oRect.dTop);
|
|
pOutput->LineTo(oRect.dRight, oRect.dBottom);
|
|
pOutput->LineTo(oRect.dLeft, oRect.dBottom);
|
|
pOutput->ClosePath();
|
|
}
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
pOutput->EndClipPath(unType);
|
|
}
|
|
|
|
CEmfPlusRegionNode *pLeft, *pRigth;
|
|
};
|
|
|
|
class CEmfPlusRegion : public CEmfPlusObject
|
|
{
|
|
public:
|
|
CEmfPlusRegion() : CEmfPlusObject() {};
|
|
virtual ~CEmfPlusRegion()
|
|
{
|
|
for (CEmfPlusRegionNode* pNode : arNodes)
|
|
delete pNode;
|
|
|
|
arNodes.clear();
|
|
};
|
|
|
|
virtual EEmfPlusObjectType GetObjectType() override
|
|
{
|
|
return ObjectTypeRegion;
|
|
}
|
|
|
|
std::vector<CEmfPlusRegionNode*> arNodes;
|
|
};
|
|
}
|
|
|
|
#endif // _METAFILE_EMF_EMFPLUSOBJECTS_H
|