Commit 5d7db3dd authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Wmf перенесен из ImageStudio. Исходники wmf сделаны кроссплатформенными (убран...

Wmf перенесен из ImageStudio. Исходники wmf сделаны кроссплатформенными (убран CString и заменены функции винды). Исправлены некоторые баги в wmf. Написан внешний класс CMetaFile для работы и с Emf и с Wmf. Написаны заготовочные классы для чтениния Emf, чтение уже происходит нормально, но почти все пока не поддерживается. В Emf реализована поддержка картинок.

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62020 954022d7-b5bf-4e40-9824-e11837661b57
parent b93aede1
...@@ -2959,6 +2959,9 @@ DesktopEditor/mac_build/raster/raster.xcodeproj/project.xcworkspace/xcuserdata/a ...@@ -2959,6 +2959,9 @@ DesktopEditor/mac_build/raster/raster.xcodeproj/project.xcworkspace/xcuserdata/a
DesktopEditor/mac_build/raster/raster.xcodeproj/xcuserdata svnc_tsvn_003alogminsize=5 DesktopEditor/mac_build/raster/raster.xcodeproj/xcuserdata svnc_tsvn_003alogminsize=5
DesktopEditor/mac_build/raster/raster.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad svnc_tsvn_003alogminsize=5 DesktopEditor/mac_build/raster/raster.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad svnc_tsvn_003alogminsize=5
DesktopEditor/mac_build/raster/raster.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes svnc_tsvn_003alogminsize=5 DesktopEditor/mac_build/raster/raster.xcodeproj/xcuserdata/alexey.musinov.xcuserdatad/xcschemes svnc_tsvn_003alogminsize=5
DesktopEditor/raster/Metafile svnc_tsvn_003alogminsize=5
DesktopEditor/raster/Metafile/Emf svnc_tsvn_003alogminsize=5
DesktopEditor/raster/Metafile/Wmf svnc_tsvn_003alogminsize=5
DoctRenderer/COMMON/Dlls/AVSGraphics.dll svn_mime_002dtype=application%2Foctet-stream DoctRenderer/COMMON/Dlls/AVSGraphics.dll svn_mime_002dtype=application%2Foctet-stream
DoctRenderer/COMMON/Dlls/AVSOfficeFOFile.dll svn_mime_002dtype=application%2Foctet-stream DoctRenderer/COMMON/Dlls/AVSOfficeFOFile.dll svn_mime_002dtype=application%2Foctet-stream
DoctRenderer/COMMON/Joiner/bin/Debug/Joiner.exe svn_mime_002dtype=application%2Foctet-stream DoctRenderer/COMMON/Joiner/bin/Debug/Joiner.exe svn_mime_002dtype=application%2Foctet-stream
......
#include "Common.h"
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../raster/BgraFrame.h"
namespace Metafile
{
bool ReadImageCoreHeader(BYTE* pHeaderBuffer, unsigned long ulHeaderBufferLen, BYTE* pImageBuffer, unsigned long ulImageBufferLen, BYTE** ppDstBuffer, unsigned long* pulWidth, unsigned long* pulHeight)
{
CDataStream oHeaderStream;
oHeaderStream.SetStream(pHeaderBuffer, ulHeaderBufferLen);
unsigned short ushWidth;
unsigned short ushHeight;
unsigned short ushPlanes;
unsigned short ushBitCount;
oHeaderStream >> ushWidth;
oHeaderStream >> ushHeight;
oHeaderStream >> ushPlanes;
oHeaderStream >> ushBitCount;
if (0x0001 != ushPlanes)
return false;
return false;
}
bool ReadImageInfoHeader(BYTE* pHeaderBuffer, unsigned long ulHeaderBufferLen, BYTE* pImageBuffer, unsigned long ulImageBufferLen, BYTE** ppDstBuffer, unsigned long* pulWidth, unsigned long* pulHeight)
{
CDataStream oHeaderStream;
oHeaderStream.SetStream(pHeaderBuffer, ulHeaderBufferLen);
int nWidth;
int nHeight;
unsigned short ushPlanes;
unsigned short ushBitCount;
unsigned int unCompression;
unsigned int unImageSize;
unsigned int unXPelsPerMeter;
unsigned int unYPelsPerMeter;
unsigned int unColorUsed;
unsigned int unColorImportant;
oHeaderStream >> nWidth;
oHeaderStream >> nHeight;
oHeaderStream >> ushPlanes;
oHeaderStream >> ushBitCount;
oHeaderStream >> unCompression;
oHeaderStream >> unImageSize;
oHeaderStream >> unXPelsPerMeter;
oHeaderStream >> unYPelsPerMeter;
oHeaderStream >> unColorUsed;
oHeaderStream >> unColorImportant;
if (0x0001 != ushPlanes)
return false;
if (nHeight < 0x00000000 && (BI_RGB != unCompression))
return false;
if (nWidth < 0)
return false;
BYTE* pBgraBuffer = NULL;
unsigned long ulWidth = 0;
unsigned long ulHeight = 0;
BYTE* pBuffer = pImageBuffer;
long lBufLen = ulImageBufferLen;
*ppDstBuffer = NULL;
*pulWidth = 0;
*pulHeight = 0;
if (BI_BITCOUNT_0 == ushBitCount) // PNG, JPEG
{
if (BI_JPEG != unCompression || BI_PNG != unCompression)
return false;
std::wstring wsTempFileName;
FILE* pTempFile = NULL;
if (!WmfOpenTempFile(&wsTempFileName, &pTempFile, L"wb", L".wmf0", NULL))
return false;
::fwrite(pBuffer, 1, unImageSize, pTempFile);
::fclose(pTempFile);
CBgraFrame oFrame;
oFrame.OpenFile(wsTempFileName);
// TODO: .
::_wunlink(wsTempFileName.c_str());
return false;
}
else if (BI_BITCOUNT_1 == ushBitCount)
{
// , 2-
TWmfRGB oColor1, oColor2;
oColor1.r = *pBuffer; pBuffer++; lBufLen--;
oColor1.g = *pBuffer; pBuffer++; lBufLen--;
oColor1.b = *pBuffer; pBuffer++; lBufLen--;
pBuffer++; lBufLen--;
oColor2.r = *pBuffer; pBuffer++; lBufLen--;
oColor2.g = *pBuffer; pBuffer++; lBufLen--;
oColor2.b = *pBuffer; pBuffer++; lBufLen--;
pBuffer++; lBufLen--;
//
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
ulHeight = (unsigned short)abs(nHeight);
ulWidth = (unsigned short)nWidth;
int nWidthBytes = (nWidth + 7) / 8;
int nAdditBytes = 4 - div_t(div(((nWidth + 7) / 8), 4)).rem;
if (4 == nAdditBytes)
nAdditBytes = 0;
int nLastBitCount = div_t(div(nWidth, 8)).rem - 1;
if (-1 == nLastBitCount)
nLastBitCount = 7;
nLastBitCount = (int)pow((double)2, (double)nLastBitCount);
for (int nY = 0, nIndex = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidthBytes; nX++)
{
int nByte = *pBuffer; pBuffer++; lBufLen--;
int nBitCount = 128;
if (nX == nWidthBytes - 1)
nBitCount = nLastBitCount;
for (int nBitIndex = nBitCount; nBitIndex > 0; nBitIndex /= 2)
{
int nBit = (nByte & nBitIndex);
TWmfRGB oColor = (nBit ? oColor2 : oColor1);
pBgraBuffer[nIndex * 4 + 0] = oColor.b;
pBgraBuffer[nIndex * 4 + 1] = oColor.g;
pBgraBuffer[nIndex * 4 + 2] = oColor.r;
pBgraBuffer[nIndex * 4 + 3] = 255;
nIndex++;
}
}
for (int nAddIndex = 0; nAddIndex < nAdditBytes; nAddIndex++)
{
int nByte = *pBuffer; pBuffer++; lBufLen--;
}
}
*ppDstBuffer = pBgraBuffer;
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return true;
}
else if (BI_BITCOUNT_2 == ushBitCount)
{
// TODO: ,
return false;
}
else if (BI_BITCOUNT_3 == ushBitCount)
{
unsigned short ushColorTableLen = 256;
if (0 != unColorUsed)
ushColorTableLen = (std::min)((unsigned short)256, (unsigned short)unColorUsed);
TWmfRGB oColorTable[256];
if (lBufLen < ushColorTableLen * 4)
return false;
//
for (unsigned short ushIndex = 0; ushIndex < ushColorTableLen; ushIndex++)
{
oColorTable[ushIndex].r = *pBuffer; pBuffer++; lBufLen--;
oColorTable[ushIndex].g = *pBuffer; pBuffer++; lBufLen--;
oColorTable[ushIndex].b = *pBuffer; pBuffer++; lBufLen--;
pBuffer++; lBufLen--;
}
// 1 - 1
// 4.
int nAdd = 0;
while (0 != div_t(div(nWidth + nAdd, 4)).rem)
{
nAdd++;
}
if (lBufLen < nWidth * nHeight)
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
ulHeight = (unsigned short)abs(nHeight);
ulWidth = (unsigned short)nWidth;
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
BYTE nByte = *pBuffer; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 0] = oColorTable[nByte].b;
pBgraBuffer[nIndex + 1] = oColorTable[nByte].g;
pBgraBuffer[nIndex + 2] = oColorTable[nByte].r;
pBgraBuffer[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
BYTE nByte = *pBuffer; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 0] = oColorTable[nByte].b;
pBgraBuffer[nIndex + 1] = oColorTable[nByte].g;
pBgraBuffer[nIndex + 2] = oColorTable[nByte].r;
pBgraBuffer[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
*ppDstBuffer = pBgraBuffer;
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return true;
}
else if (BI_BITCOUNT_4 == ushBitCount)
{
// ( )
pBuffer += unColorUsed * 4; lBufLen -= unColorUsed * 4;
if (BI_RGB != unCompression)
return false; // TODO: ,
//
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
ulHeight = (unsigned short)abs(nHeight);
ulWidth = (unsigned short)nWidth;
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
unsigned short ushValue = ((pBuffer[1] << 8) | pBuffer[0]) & 32767; pBuffer += 2; lBufLen -= 2;
unsigned char unR = ushValue & 31; // 000000000011111
unsigned char unG = (ushValue & 992) >> 5; // 000001111100000
unsigned char unB = (ushValue & 31744) >> 10; // 111110000000000
pBgraBuffer[nIndex + 0] = (unsigned char)(unR / 31.0 * 255);
pBgraBuffer[nIndex + 1] = (unsigned char)(unG / 31.0 * 255);
pBgraBuffer[nIndex + 2] = (unsigned char)(unB / 31.0 * 255);
pBgraBuffer[nIndex + 3] = 255;
}
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
unsigned short ushValue = ((pBuffer[1] << 8) | pBuffer[0]) & 32767; pBuffer += 2; lBufLen -= 2;
unsigned char unR = ushValue & 31; // 000000000011111
unsigned char unG = (ushValue & 992) >> 5; // 000001111100000
unsigned char unB = (ushValue & 31744) >> 10; // 111110000000000
pBgraBuffer[nIndex + 0] = (unsigned char)(unR / 31.0 * 255);
pBgraBuffer[nIndex + 1] = (unsigned char)(unG / 31.0 * 255);
pBgraBuffer[nIndex + 2] = (unsigned char)(unB / 31.0 * 255);
pBgraBuffer[nIndex + 3] = 255;
}
}
}
*ppDstBuffer = pBgraBuffer;
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return false;
}
else if (BI_BITCOUNT_5 == ushBitCount)
{
// ( )
pBuffer += unColorUsed * 4; lBufLen -= unColorUsed * 4;
if (BI_RGB != unCompression)
return false; // TODO: ,
//
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
// 1
// ( * 3) 4.
int nAdd = 0;
while (0 != div_t(div(3 * nWidth + nAdd, 4)).rem)
{
nAdd++;
}
int nSize = nWidth * nHeight * 4;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
ulHeight = (unsigned short)abs(nHeight);
ulWidth = (unsigned short)nWidth;
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
pBgraBuffer[nIndex + 0] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 1] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 2] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
pBgraBuffer[nIndex + 0] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 1] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 2] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
*ppDstBuffer = pBgraBuffer;
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return true;
}
else if (BI_BITCOUNT_6 == ushBitCount)
{
// ( )
pBuffer += unColorUsed * 4; lBufLen -= unColorUsed * 4;
if (BI_RGB != unCompression)
return false; // TO DO: ,
//
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
// 1
// 4.
int nAdd = 0;
while (0 != div_t(div(nWidth + nAdd, 4)).rem)
{
nAdd++;
}
int nSize = nWidth * nHeight * 4;
pBgraBuffer = new BYTE[(nWidth + nAdd) * nHeight * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
ulHeight = (unsigned short)abs(nHeight);
ulWidth = (unsigned short)(nWidth + nAdd);
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * ((nWidth + nAdd) * nY + nX);
pBgraBuffer[nIndex + 0] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 1] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 2] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 3] = 255; pBuffer++; lBufLen--; // ,
}
for (int nX = nWidth; nX < nWidth + nAdd; nX++)
{
int nIndex = 4 * ((nWidth + nAdd) * nY + nX);
pBgraBuffer[nIndex + 0] = 255;
pBgraBuffer[nIndex + 1] = 255;
pBgraBuffer[nIndex + 2] = 255;
pBgraBuffer[nIndex + 3] = 0;
}
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * ((nWidth + nAdd) * nY + nX);
pBgraBuffer[nIndex + 0] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 1] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 2] = pBuffer[0]; pBuffer++; lBufLen--;
pBgraBuffer[nIndex + 3] = 255; pBuffer++; lBufLen--; // ,
}
for (int nX = nWidth; nX < nWidth + nAdd; nX++)
{
int nIndex = 4 * ((nWidth + nAdd) * nY + nX);
pBgraBuffer[nIndex + 0] = 255;
pBgraBuffer[nIndex + 1] = 255;
pBgraBuffer[nIndex + 2] = 255;
pBgraBuffer[nIndex + 3] = 0;
}
}
}
*ppDstBuffer = pBgraBuffer;
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return true;
}
return false;
}
void ReadImage(BYTE* pHeaderBuffer, unsigned long ulHeaderBufferLen, BYTE* pImageBuffer, unsigned long ulImageBufferLen, BYTE** ppDstBuffer, unsigned long* pulWidth, unsigned long* pulHeight)
{
if (ulHeaderBufferLen <= 0 || NULL == pHeaderBuffer || NULL == pImageBuffer || ulImageBufferLen < 0)
return;
CDataStream oHeaderStream;
oHeaderStream.SetStream(pHeaderBuffer, ulHeaderBufferLen);
//
unsigned long ulHeaderSize;
oHeaderStream >> ulHeaderSize;
if (ulHeaderSize < 0x0000000C)
return;
else if (0x0000000C == ulHeaderSize) // BitmapCoreHeader
ReadImageCoreHeader(pHeaderBuffer + 4, ulHeaderBufferLen - 4, pImageBuffer, ulImageBufferLen, ppDstBuffer, pulWidth, pulHeight);
else // BitmapInfoHeader
ReadImageInfoHeader(pHeaderBuffer + 4, ulHeaderBufferLen - 4, pImageBuffer, ulImageBufferLen, ppDstBuffer, pulWidth, pulHeight);
}
}
\ No newline at end of file
#ifndef _METAFILE_WMF_EMF_COMMON_H
#define _METAFILE_WMF_EMF_COMMON_H
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef NULL
#define NULL 0
#endif
#include <algorithm>
#include "Emf/EmfTypes.h"
#include "Wmf/WmfTypes.h"
#include "Wmf/WmfUtils.h"
#include "Emf/EmfObjects.h"
namespace Metafile
{
class CDataStream
{
public:
CDataStream() : pBuffer(NULL)
{
}
~CDataStream()
{
}
void SetStream(BYTE* pBuf, unsigned long unSize)
{
pBuffer = pBuf;
pCur = pBuf;
pEnd = pBuf + unSize + 1;
};
unsigned char ReadUChar()
{
if (pCur + 1 >= pEnd)
return 0;
unsigned char unResult = pCur[0];
pCur++;
return unResult;
};
unsigned short ReadUShort()
{
if (pCur + 2 >= pEnd)
return 0;
unsigned short ushResult = (pCur[0]) | ((pCur[1]) << 8);
pCur += 2;
return ushResult;
};
unsigned long ReadULong()
{
if (pCur + 4 >= pEnd)
return 0;
unsigned long unResult = (unsigned long)((pCur[0] << 0) | ((pCur[1]) << 8) | ((pCur[2]) << 16) | ((pCur[3]) << 24));
pCur += 4;
return unResult;
};
double ReadDouble()
{
if (pCur + 4 >= pEnd)
return 0;
long lIntValue = (long)((pCur[0] << 16) | ((pCur[1]) << 8) | ((pCur[2]) << 0));
long lFracValue = (long)(pCur[3]);
pCur += 4;
return (double)(lIntValue + (lFracValue / 16.0));
};
char ReadChar()
{
return (char)ReadUChar();
};
short ReadShort()
{
return (short)ReadUShort();
};
long ReadLong()
{
return (long)ReadULong();
};
void ReadBytes(BYTE* pBuffer, unsigned long ulSize)
{
size_t ulRemainSize = (pEnd - pCur);
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
for (size_t ulIndex = 0; ulIndex < ulFinalSize; ulIndex++)
{
pBuffer[ulIndex] = ReadChar();
}
};
CDataStream& operator>>(unsigned char& nValue)
{
nValue = ReadUChar();
return *this;
}
CDataStream& operator>>(unsigned short& nValue)
{
nValue = ReadUShort();
return *this;
}
CDataStream& operator>>(unsigned long& nValue)
{
nValue = ReadULong();
return *this;
}
CDataStream& operator>>(unsigned int& nValue)
{
nValue = ReadULong();
return *this;
}
CDataStream& operator>>(double& dValue)
{
dValue = ReadDouble();
return *this;
}
CDataStream& operator>>(char& nValue)
{
nValue = ReadChar();
return *this;
}
CDataStream& operator>>(short& nValue)
{
nValue = ReadShort();
return *this;
}
CDataStream& operator>>(long& nValue)
{
nValue = ReadLong();
return *this;
}
CDataStream& operator>>(int& nValue)
{
nValue = ReadLong();
return *this;
}
CDataStream& operator>>(TEmfRect& oRect)
{
*this >> oRect.shLeft;
*this >> oRect.shTop;
*this >> oRect.shRight;
*this >> oRect.shBottom;
return *this;
}
CDataStream& operator>>(TEmfRectL& oRect)
{
*this >> oRect.lLeft;
*this >> oRect.lTop;
*this >> oRect.lRight;
*this >> oRect.lBottom;
return *this;
}
CDataStream& operator>>(TEmfSizeL& oSize)
{
*this >> oSize.ulX;
*this >> oSize.ulY;
return *this;
}
CDataStream& operator>>(TEmfColor& oColor)
{
*this >> oColor.r;
*this >> oColor.g;
*this >> oColor.b;
*this >> oColor.a;
return *this;
}
CDataStream& operator>>(CEmfLogBrushEx& oBrush)
{
*this >> oBrush.BrushStyle;
*this >> oBrush.Color;
*this >> oBrush.BrushHatch;
return *this;
}
bool IsValid() const
{
if (NULL == pBuffer)
return false;
return true;
}
bool IsEof() const
{
if (pCur >= pEnd)
return true;
return false;
}
unsigned long Tell()
{
return (unsigned long)(pCur - pBuffer);
}
void Skip(unsigned long ulSkip)
{
pCur += ulSkip;
}
void SeekBack(unsigned long ulSkipBack)
{
pCur -= ulSkipBack;
}
private:
BYTE *pBuffer;
BYTE *pCur;
BYTE *pEnd;
};
void ReadImage(BYTE* pHeaderBuffer, unsigned long ulHeaderBufferLen, BYTE* pImageBuffer, unsigned long ulImageBufferLen, BYTE** ppDstBuffer, unsigned long* pulWidth, unsigned long* pulHeight);
};
#endif //_METAFILE_WMF_EMF_COMMON_H
\ No newline at end of file
#ifndef _EMF_FILE_H
#define _EMF_FILE_H
#include "../Wmf/WmfUtils.h"
#include "../Wmf/WmfTypes.h"
#include "../Common.h"
#include "EmfTypes.h"
#include "EmfOutputDevice.h"
#include "EmfPlayer.h"
#include "../../../fontengine/FontManager.h"
namespace Metafile
{
class CEmfFile
{
public:
CEmfFile() : m_oPlayer(this)
{
m_pBufferData = NULL;
m_bError = false;
m_pOutput = NULL;
m_oStream.SetStream(NULL, 0);
m_pDC = m_oPlayer.GetDC();
};
~CEmfFile()
{
};
bool OpenFromFile(const wchar_t* wsFilePath)
{
if (m_pBufferData)
delete m_pBufferData;
NSFile::CFileBinary oFile;
oFile.OpenFile(wsFilePath);
long lFileSize = oFile.GetFileSize();
m_pBufferData = new BYTE[lFileSize];
if (!m_pBufferData)
return false;
DWORD lReadedSize;
oFile.ReadFile(m_pBufferData, lFileSize, lReadedSize);
m_oStream.SetStream(m_pBufferData, lFileSize);
return true;
}
void Close()
{
if (m_pBufferData)
delete m_pBufferData;
m_pOutput = NULL;
m_oStream.SetStream(NULL, 0);
m_bError = false;
m_oPlayer.Clear();
m_pDC = m_oPlayer.GetDC();
}
TEmfRectL GetBounds()
{
return m_oHeader.oFrame;
}
void SetOutputDevice(CEmfOutputDevice* pOutput)
{
m_pOutput = pOutput;
}
void Scan()
{
Read_EMR_HEADER();
}
bool CheckError()
{
return m_bError;
}
void SetFontManager(CFontManager* pManager)
{
m_pFontManager = pManager;
}
void PlayMetaFile()
{
unsigned long ulSize, ulType;
unsigned long ulNumber = 0;
bool bEof = false;
do
{
m_oStream >> ulType;
m_oStream >> ulSize;
m_ulRecordSize = ulSize - 8;
switch (ulType)
{
case EMR_STRETCHDIBITS:
{
Read_EMR_STRETCHDIBITS();
break;
}
//-----------------------------------------------------------
// 2.3.5 Drawing
//-----------------------------------------------------------
case EMR_EXTTEXTOUTW:
{
Read_EMR_EXTTEXTOUTW();
break;
}
//-----------------------------------------------------------
// 2.3.7 Object Creation
//-----------------------------------------------------------
case EMR_CREATEBRUSHINDIRECT:
{
Read_EMR_CREATEBRUSHINDIRECT();
break;
}
//-----------------------------------------------------------
// 2.3.11 State
//-----------------------------------------------------------
case EMR_SAVEDC:
{
Read_EMR_SAVEDC();
break;
}
case EMR_RESTOREDC:
{
Read_EMR_RESTOREDC();
break;
}
case EMR_SETTEXTCOLOR:
{
Read_EMR_SETTEXTCOLOR();
break;
}
//-----------------------------------------------------------
// 2.3.12 Transform
//-----------------------------------------------------------
case EMR_SETWORLDTRANSFORM:
{
Read_EMR_SETWORLDTRANSFORM();
break;
}
case EMR_MODIFYWORLDTRANSFORM:
{
Read_EMR_MODIFYWORLDTRANSFORM();
break;
}
case EMR_EOF:
{
Read_EMR_EOF();
bEof = true;
break;
}
case EMR_SETICMMODE:
default:
{
Read_EMR_UNKNOWN();
break;
}
}
if (bEof)
break;
if (!m_oStream.IsValid())
SetError();
} while (!CheckError());
}
private:
void SetError()
{
m_bError = true;
}
void Read_EMR_HEADER()
{
unsigned long ulType, ulSize;
m_oStream >> ulType;
m_oStream >> ulSize;
if (EMR_HEADER != ulType)
return SetError();
m_oStream >> m_oHeader.oBounds;
m_oStream >> m_oHeader.oFrame;
m_oStream >> m_oHeader.ulSignature;
m_oStream >> m_oHeader.ulVersion;
m_oStream >> m_oHeader.ulSize;
m_oStream >> m_oHeader.ulRecords;
m_oStream >> m_oHeader.ushObjects;
m_oStream >> m_oHeader.ushReserved;
m_oStream >> m_oHeader.ulSizeDescription;
m_oStream >> m_oHeader.ulOffsetDescription;
m_oStream >> m_oHeader.ulPalEntries;
m_oStream >> m_oHeader.oDevice;
m_oStream >> m_oHeader.oMillimeters;
if (ENHMETA_SIGNATURE != m_oHeader.ulSignature || 0x00010000 != m_oHeader.ulVersion)
return SetError();
// , ..
unsigned long ulRemaining = ulSize - 88; // 8 + sizeof(TEmfHeader)
m_oStream.Skip(ulRemaining);
}
void Read_EMR_STRETCHDIBITS()
{
TEmfStretchDIBITS oBitmap;
m_oStream >> oBitmap.Bounds;
m_oStream >> oBitmap.xDest;
m_oStream >> oBitmap.yDest;
m_oStream >> oBitmap.xSrc;
m_oStream >> oBitmap.ySrc;
m_oStream >> oBitmap.cxSrc;
m_oStream >> oBitmap.cySrc;
m_oStream >> oBitmap.offBmiSrc;
m_oStream >> oBitmap.cbBmiSrc;
m_oStream >> oBitmap.offBitsSrc;
m_oStream >> oBitmap.cbBitsSrc;
m_oStream >> oBitmap.UsageSrc;
m_oStream >> oBitmap.BitBltRasterOperation;
m_oStream >> oBitmap.cxDest;
m_oStream >> oBitmap.cyDest;
unsigned long ulHeaderOffset = oBitmap.offBmiSrc - sizeof(TEmfStretchDIBITS) - 8;
unsigned long ulHeaderSize = oBitmap.cbBmiSrc;
m_oStream.Skip(ulHeaderOffset);
BYTE* pHeaderBuffer = new BYTE[ulHeaderSize];
if (!pHeaderBuffer)
return SetError();
m_oStream.ReadBytes(pHeaderBuffer, ulHeaderSize);
unsigned long ulBitsOffset = oBitmap.offBitsSrc - oBitmap.offBmiSrc - oBitmap.cbBmiSrc;
unsigned long ulBitsSize = oBitmap.cbBitsSrc;
m_oStream.Skip(ulBitsOffset);
BYTE* pBitsBuffer = new BYTE[ulBitsSize];
if (!pBitsBuffer)
{
delete[] pHeaderBuffer;
return SetError();
}
m_oStream.ReadBytes(pBitsBuffer, ulBitsSize);
BYTE* pBgraBuffer;
unsigned long ulWidth, ulHeight;
ReadImage(pHeaderBuffer, ulHeaderSize, pBitsBuffer, ulBitsSize, &pBgraBuffer, &ulWidth, &ulHeight);
if (m_pOutput)
m_pOutput->Draw_Bitmap(oBitmap.xDest, oBitmap.yDest, oBitmap.cxDest, oBitmap.cyDest, pBgraBuffer, ulWidth, ulHeight);
if (pBgraBuffer)
delete[] pBgraBuffer;
delete[] pBitsBuffer;
delete[] pHeaderBuffer;
}
void Read_EMR_EOF()
{
unsigned long ulCount, ulOffset, ulSizeLast;
m_oStream >> ulCount;
m_oStream >> ulOffset;
m_oStream.Skip(m_ulRecordSize - 8 - 4);
m_oStream >> ulSizeLast;
}
void Read_EMR_UNKNOWN()
{
//
m_oStream.Skip(m_ulRecordSize);
}
void Read_EMR_SAVEDC()
{
m_pDC = m_oPlayer.SaveDC();
}
void Read_EMR_RESTOREDC()
{
long lSavedDC;
m_oStream >> lSavedDC;
if (lSavedDC >= 0)
{
SetError();
return;
}
long lCount = -lSavedDC;
for (long lIndex = 0; lIndex < lCount; lIndex++)
m_oPlayer.RestoreDC();
m_pDC = m_oPlayer.GetDC();
}
void Read_EMR_MODIFYWORLDTRANSFORM()
{
TEmfXForm oXForm;
m_oStream >> oXForm.M11;
m_oStream >> oXForm.M12;
m_oStream >> oXForm.M21;
m_oStream >> oXForm.M22;
m_oStream >> oXForm.Dx;
m_oStream >> oXForm.Dy;
unsigned long ulMode;
m_oStream >> ulMode;
TEmfXForm* pCurTransform = m_pDC->GetTransform();
pCurTransform->Multiply(oXForm, ulMode);
}
void Read_EMR_SETWORLDTRANSFORM()
{
TEmfXForm oXForm;
m_oStream >> oXForm.M11;
m_oStream >> oXForm.M12;
m_oStream >> oXForm.M21;
m_oStream >> oXForm.M22;
m_oStream >> oXForm.Dx;
m_oStream >> oXForm.Dy;
TEmfXForm* pCurTransform = m_pDC->GetTransform();
pCurTransform->Multiply(oXForm, MWT_SET);
}
void Read_EMR_CREATEBRUSHINDIRECT()
{
unsigned long ulBrushIndex;
CEmfLogBrushEx* pBrush = new CEmfLogBrushEx();
m_oStream >> ulBrushIndex;
m_oStream >> *pBrush;
m_oPlayer.RegisterObject(ulBrushIndex, (CEmfObjectBase*)pBrush);
}
void Read_EMR_SETTEXTCOLOR()
{
TEmfColor oColor;
m_oStream >> oColor;
m_pDC->SetTextColor(oColor);
}
void Read_EMR_EXTTEXTOUTW()
{
TEmfRectL oBounds;
m_oStream >> oBounds;
unsigned long ulGrMode;
double dExScale, dEyScale;
m_oStream >> ulGrMode;
m_oStream >> dExScale;
m_oStream >> dEyScale;
// EmrText
}
private:
CDataStream m_oStream;
BYTE* m_pBufferData;
bool m_bError;
CFontManager* m_pFontManager;
TEmfHeader m_oHeader;
unsigned long m_ulRecordSize;
CEmfOutputDevice* m_pOutput;
CEmfDC* m_pDC;
CEmfPlayer m_oPlayer;
friend class CEmfRendererOutput;
friend class CEmfPlayer;
};
}
#endif // _EMF_FILE_H
\ No newline at end of file
#ifndef _EMF_OBJECTS_H
#define _EMF_OBJECTS_H
#include "EmfTypes.h"
#include "../Wmf/WmfTypes.h"
namespace Metafile
{
class CEmfObjectBase
{
public:
CEmfObjectBase(){}
virtual ~CEmfObjectBase(){}
};
class CEmfLogBrushEx : public CEmfObjectBase
{
public:
CEmfLogBrushEx()
{
BrushStyle = BS_SOLID;
BrushHatch = HS_HORIZONTAL;
}
virtual ~CEmfLogBrushEx()
{
}
public:
unsigned long BrushStyle;
TEmfColor Color;
unsigned long BrushHatch;
};
}
#endif // _EMF_OBJECTS_H
\ No newline at end of file
#ifndef _EMF_OUTPUT_DEVICE_H
#define _EMF_OUTPUT_DEVICE_H
#include "../Wmf/WmfTypes.h"
namespace Metafile
{
class CEmfOutputDevice
{
public:
CEmfOutputDevice() {}
virtual ~CEmfOutputDevice() {}
//
virtual void Begin() = 0;
virtual void End() = 0;
// pBuffer - BGRA ulWidth, ulHeight,
virtual void Draw_Bitmap(long lX, long lY, long lW, long lH, BYTE* pBuffer, unsigned long ulWidth, unsigned long ulHeight) = 0;
};
}
#endif //_EMF_OUTPUT_DEVICE_H
\ No newline at end of file
#include "EmfPlayer.h"
#include "EmfFile.h"
namespace Metafile
{
CEmfPlayer::CEmfPlayer(CEmfFile* pFile)
{
CEmfDC* pDC = new CEmfDC();
if (!pDC)
{
pFile->SetError();
return;
}
m_pDC = pDC;
m_vDCStack.push_back(pDC);
};
CEmfPlayer::~CEmfPlayer()
{
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
{
CEmfDC* pDC = m_vDCStack.at(nIndex);
delete pDC;
}
for (CEmfObjectMap::iterator oIterator = m_mObjects.begin(); oIterator != m_mObjects.end(); oIterator++)
{
CEmfObjectBase* pOldObject = oIterator->second;
delete pOldObject;
}
m_mObjects.clear();
}
void CEmfPlayer::Clear()
{
for (int nIndex = 0; nIndex < m_vDCStack.size(); nIndex++)
{
CEmfDC* pDC = m_vDCStack.at(nIndex);
delete pDC;
}
for (CEmfObjectMap::iterator oIterator = m_mObjects.begin(); oIterator != m_mObjects.end(); oIterator++)
{
CEmfObjectBase* pOldObject = oIterator->second;
delete pOldObject;
}
m_mObjects.clear();
CEmfDC* pDC = new CEmfDC();
if (!pDC)
{
m_pEmfFile->SetError();
return;
}
m_pDC = pDC;
m_vDCStack.push_back(pDC);
}
CEmfDC* CEmfPlayer::SaveDC()
{
if (!m_pDC)
{
m_pEmfFile->SetError();
return NULL;
}
CEmfDC* pNewDC = m_pDC->Copy();
if (!pNewDC)
{
m_pEmfFile->SetError();
return NULL;
}
m_vDCStack.push_back(pNewDC);
m_pDC = pNewDC;
return pNewDC;
}
CEmfDC* CEmfPlayer::RestoreDC()
{
if (m_vDCStack.size() <= 1)
{
m_pEmfFile->SetError();
return m_pDC;
}
CEmfDC* pDC = m_vDCStack.at(m_vDCStack.size() - 1);
m_vDCStack.pop_back();
delete pDC;
pDC = m_vDCStack.at(m_vDCStack.size() - 1);
m_pDC = pDC;
return m_pDC;
}
CEmfDC* CEmfPlayer::GetDC()
{
return m_pDC;
}
void CEmfPlayer::RegisterObject(unsigned long ulIndex, CEmfObjectBase* pObject)
{
CEmfObjectMap::const_iterator oPos = m_mObjects.find(ulIndex);
if (m_mObjects.end() != oPos)
{
CEmfObjectBase* pOldObject = oPos->second;
delete pOldObject;
}
m_mObjects.insert(std::pair<unsigned long, CEmfObjectBase*>(ulIndex, pObject));
}
CEmfDC::CEmfDC()
{
m_oTransform.Init();
m_oTextColor.Init();
}
CEmfDC::~CEmfDC()
{
}
CEmfDC* CEmfDC::Copy()
{
CEmfDC* pNewDC = new CEmfDC();
if (!pNewDC)
return NULL;
pNewDC->m_oTransform.Copy(&m_oTransform);
pNewDC->m_oTextColor.Copy(&m_oTextColor);
return pNewDC;
}
TEmfXForm* CEmfDC::GetTransform()
{
return &m_oTransform;
}
void CEmfDC::SetTextColor(TEmfColor& oColor)
{
m_oTextColor.Copy(&oColor);
}
}
\ No newline at end of file
#ifndef _EMF_PLAYER_H
#define _EMF_PLAYER_H
#include <vector>
#include <map>
#include "EmfTypes.h"
#include "EmfObjects.h"
namespace Metafile
{
class CEmfFile;
class CEmfDC;
class CEmfPlayer
{
public:
CEmfPlayer(CEmfFile* pFile);
~CEmfPlayer();
void Clear();
CEmfDC* SaveDC();
CEmfDC* RestoreDC();
CEmfDC* GetDC();
void RegisterObject(unsigned long ulIndex, CEmfObjectBase* pObject);
private:
typedef std::map < unsigned long, CEmfObjectBase* > CEmfObjectMap;
CEmfDC* m_pDC;
std::vector<CEmfDC*> m_vDCStack;
CEmfFile* m_pEmfFile;
CEmfObjectMap m_mObjects;
};
class CEmfDC
{
public:
CEmfDC();
~CEmfDC();
CEmfDC* Copy();
TEmfXForm* GetTransform();
void SetTextColor(TEmfColor& oColor);
private:
TEmfXForm m_oTransform;
TEmfColor m_oTextColor;
};
}
#endif //_EMF_PLAYER_H
\ No newline at end of file
#ifndef _EMF_TYPES_H
#define _EMF_TYPES_H
namespace Metafile
{
struct TEmfColor
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a; //Reserved Must be 0x00
void Init()
{
r = 0;
g = 0;
b = 0;
a = 0;
}
void Copy(TEmfColor* pOther)
{
r = pOther->r;
g = pOther->g;
b = pOther->b;
a = pOther->a;
}
};
struct TEmfRect
{
short shLeft;
short shTop;
short shRight;
short shBottom;
};
struct TEmfRectL
{
long lLeft;
long lTop;
long lRight;
long lBottom;
};
struct TEmfSizeL
{
unsigned long ulX;
unsigned long ulY;
};
struct TEmfPointL
{
long x;
long y;
};
struct TEmfHeader
{
TEmfRectL oBounds;
TEmfRectL oFrame;
unsigned long ulSignature;
unsigned long ulVersion;
unsigned long ulSize;
unsigned long ulRecords;
unsigned short ushObjects;
unsigned short ushReserved;
unsigned long ulSizeDescription;
unsigned long ulOffsetDescription;
unsigned long ulPalEntries;
TEmfSizeL oDevice;
TEmfSizeL oMillimeters;
};
struct TEmfStretchDIBITS
{
TEmfRectL Bounds;
long xDest;
long yDest;
long xSrc;
long ySrc;
long cxSrc;
long cySrc;
unsigned long offBmiSrc;
unsigned long cbBmiSrc;
unsigned long offBitsSrc;
unsigned long cbBitsSrc;
unsigned long UsageSrc;
unsigned long BitBltRasterOperation;
long cxDest;
long cyDest;
};
#define MWT_IDENTITY 0x01
#define MWT_LEFTMULTIPLY 0x02
#define MWT_RIGHTMULTIPLY 0x03
#define MWT_SET 0x04
struct TEmfXForm
{
double M11;
double M12;
double M21;
double M22;
double Dx;
double Dy;
void Init()
{
M11 = 1;
M12 = 0;
M21 = 0;
M22 = 1;
Dx = 0;
Dy = 0;
}
void Copy(TEmfXForm* pOther)
{
M11 = pOther->M11;
M12 = pOther->M12;
M21 = pOther->M21;
M22 = pOther->M22;
Dx = pOther->Dx;
Dy = pOther->Dy;
}
void Multiply(TEmfXForm &oOther, unsigned long ulMode)
{
if (MWT_IDENTITY == ulMode)
Init();
else if (MWT_LEFTMULTIPLY == ulMode)
{
// oOther ,
double dM11 = oOther.M11 * M11 + oOther.M12 * M21;
double dM12 = oOther.M11 * M21 + oOther.M12 * M22;
double dM21 = oOther.M21 * M11 + oOther.M22 * M21;
double dM22 = oOther.M21 * M21 + oOther.M22 * M22;
double dDx = oOther.Dx * M11 + oOther.Dy * M21 + Dx;
double dDy = oOther.Dx * M21 + oOther.Dy * M22 + Dy;
M11 = dM11;
M12 = dM12;
M21 = dM21;
M22 = dM22;
Dx = dDx;
Dy = dDy;
}
else if (MWT_RIGHTMULTIPLY == ulMode)
{
// oOther ,
double dM11 = M11 * oOther.M11 + M12 * oOther.M21;
double dM12 = M11 * oOther.M21 + M12 * oOther.M22;
double dM21 = M21 * oOther.M11 + M22 * oOther.M21;
double dM22 = M21 * oOther.M21 + M22 * oOther.M22;
double dDx = Dx * oOther.M11 + Dy * oOther.M21 + oOther.Dx;
double dDy = Dx * oOther.M21 + Dy * oOther.M22 + oOther.Dy;
M11 = dM11;
M12 = dM12;
M21 = dM21;
M22 = dM22;
Dx = dDx;
Dy = dDy;
}
else //if (MWT_SET == ulMode)
{
Copy(&oOther);
}
}
};
};
#endif //_EMF_TYPES_H
\ No newline at end of file
#ifndef _RENDERER_OUPUT_EMF_H
#define _RENDERER_OUPUT_EMF_H
#include "../../../graphics/IRenderer.h"
#include "../../../graphics/structures.h"
#include "../../../graphics/Image.h"
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../raster/BgraFrame.h"
#include "EmfOutputDevice.h"
#include "EmfFile.h"
namespace Metafile
{
class CEmfRendererOutput : public CEmfOutputDevice
{
public:
CEmfRendererOutput(CEmfFile *pFile, IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
{
m_pEmfFile = pFile;
m_dX = dX;
m_dY = dY;
m_dW = dWidth;
m_dH = dHeight;
m_pRenderer = NULL;
if (!pRenderer)
return;
m_pRenderer = pRenderer;
}
~CEmfRendererOutput()
{
}
void Begin()
{
}
void End()
{
}
void Draw_Bitmap(long lX, long lY, long lW, long lH, BYTE* pBuffer, unsigned long ulWidth, unsigned long ulHeight)
{
Aggplus::CImage oImage;
BYTE* pBufferPtr = new BYTE[4 * ulWidth * ulHeight];
oImage.Create(pBufferPtr, ulWidth, ulHeight, 4 * ulWidth);
for (int nIndex = 0, nSize = 4 * ulWidth * ulHeight; nIndex < nSize; nIndex += 4)
{
pBufferPtr[0] = (unsigned char)pBuffer[nIndex + 0];
pBufferPtr[1] = (unsigned char)pBuffer[nIndex + 1];
pBufferPtr[2] = (unsigned char)pBuffer[nIndex + 2];
pBufferPtr[3] = (unsigned char)pBuffer[nIndex + 3];
pBufferPtr += 4;
}
double dX = TransX(lX);
double dY = TransX(lY);
double dX1 = TransX(lX + lW);
double dY1 = TransY(lY + lH);
m_pRenderer->DrawImage(&oImage, dX, dY, dX1 - dX, dY1 - dY);
}
private:
double TransX(long lX)
{
long lL = m_pEmfFile->m_oHeader.oBounds.lLeft;
long lR = m_pEmfFile->m_oHeader.oBounds.lRight;
if (lR - lL <= 0)
return 0;
return m_dW * (double)(lX - lL) / (double)(lR - lL);
}
double TransY(long lY)
{
long lT = m_pEmfFile->m_oHeader.oBounds.lTop;
long lB = m_pEmfFile->m_oHeader.oBounds.lBottom;
if (lB - lT <= 0)
return 0;
return m_dH * (double)(lY - lT) / (double)(lB - lT);
}
private:
IRenderer* m_pRenderer;
NSStructures::CPen m_oPen;
NSStructures::CBrush m_oBrush;
NSStructures::CFont m_oFont;
double m_dDpiX;
double m_dDpiY;
double m_dX; //
double m_dY; //
double m_dW; // /,
double m_dH; // .
CEmfFile* m_pEmfFile;
};
}
#endif // _RENDERER_OUPUT_EMF_H
\ No newline at end of file
#include "MetaFile.h"
#include "../../graphics/GraphicsRenderer.h"
#include "../../raster/BgraFrame.h"
#include "Emf/RendererOutput.h"
namespace Metafile
{
CMetaFile::CMetaFile(CApplicationFonts *pAppFonts)
{
m_pAppFonts = pAppFonts;
//
m_pFontManager = pAppFonts->GenerateFontManager();
CFontsCache* pMeasurerCache = new CFontsCache();
pMeasurerCache->SetStreams(pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
m_oWmfFile.SetFontManager(m_pFontManager);
m_oEmfFile.SetFontManager(m_pFontManager);
}
CMetaFile::~CMetaFile()
{
Close();
RELEASEINTERFACE(m_pFontManager);
}
bool CMetaFile::LoadFromFile(const wchar_t *wsFilePath)
{
// Wmf
m_oWmfFile.OpenFromFile(wsFilePath);
m_oWmfFile.Scan(&m_oWmfRect);
if (!m_oWmfFile.CheckError())
{
m_lType = c_lMetaWmf;
return true;
}
// Wmf, Emf
m_oWmfFile.Close();
m_oEmfFile.OpenFromFile(wsFilePath);
m_oEmfFile.Scan();
if (!m_oEmfFile.CheckError())
{
m_lType = c_lMetaEmf;
return true;
}
// Emf
m_oEmfFile.Close();
return false;
};
bool CMetaFile::DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer)
return false;
pRenderer->BeginCommand(c_nImageType);
if (c_lMetaWmf == m_lType)
{
double dRendererDpix, dRendererDpiY;
pRenderer->get_DpiX(&dRendererDpix);
pRenderer->get_DpiY(&dRendererDpiY);
CRendererOutput oWmfOut(&m_oWmfFile, pRenderer, dX, dY, dWidth, dHeight);
double fSrcWidth, fSrcHeight;
float fW, fH;
m_oWmfFile.GetSize(&fW, &fH);
m_oWmfFile.GetDisplaySize(&fSrcWidth, &fSrcHeight, dRendererDpix, dRendererDpiY);
//m_oWmfFile.GetDisplaySize( &fSrcWidth, &fSrcHeight, 25.4, 25.4 );
TWmfRectF oRectB = m_oWmfFile.GetBounds();
//double dW = m_oRect.oBR.fX - m_oRect.oTL.fX;
//double dH = m_oRect.oBR.fY - m_oRect.oTL.fY;
double dW = oRectB.oBR.fX - oRectB.oTL.fX;
double dH = oRectB.oBR.fY - oRectB.oTL.fY;
double dScaleX = dWidth / dW;//fSrcWidth;
double dScaleY = dHeight / dH;//fSrcHeight;
//double dScaleX = dWidth / fSrcWidth;
//double dScaleY = dHeight / fSrcHeight;
double dSrcDpiX, dSrcDpiY;
m_oWmfFile.GetDpi(&dSrcDpiX, &dSrcDpiY);
double dDpiKoefX = dRendererDpix / dSrcDpiX;
double dDpiKoefY = dRendererDpiY / dSrcDpiY;
double dDpi = dSrcDpiY * fSrcHeight / fH;
oWmfOut.SetDpi(dRendererDpix, dDpi);
oWmfOut.SetWmfRect(oRectB);
oWmfOut.SetScales(dScaleX, dScaleY);
m_oWmfFile.SetOutputDevice(&oWmfOut);
TWmfRectF oRect;
m_oWmfFile.Play(&oRect);
}
else if (c_lMetaEmf == m_lType)
{
CEmfRendererOutput oEmfOut(&m_oEmfFile, pRenderer, dX, dY, dWidth, dHeight);
m_oEmfFile.SetOutputDevice(&oEmfOut);
m_oEmfFile.PlayMetaFile();
}
pRenderer->EndCommand(c_nImageType);
return true;
};
void CMetaFile::Close()
{
m_oWmfFile.Close();
};
void CMetaFile::GetBounds(double* pdX, double* pdY, double* pdW, double* pdH)
{
if (c_lMetaWmf == m_lType)
{
*pdX = m_oWmfRect.oTL.fX;
*pdY = m_oWmfRect.oTL.fY;
*pdW = m_oWmfRect.oBR.fX - m_oWmfRect.oTL.fX;
*pdH = m_oWmfRect.oBR.fY - m_oWmfRect.oTL.fY;
}
else if (c_lMetaEmf == m_lType)
{
TEmfRectL oRect = m_oEmfFile.GetBounds();
*pdX = oRect.lLeft;
*pdY = oRect.lTop;
*pdW = oRect.lRight - oRect.lLeft;
*pdH = oRect.lBottom - oRect.lTop;
}
else
{
*pdX = 0;
*pdY = 0;
*pdW = 0;
*pdH = 0;
}
};
void CMetaFile::ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight)
{
CFontManager *pFontManager = m_pAppFonts->GenerateFontManager();
CImageFilesCache oCache;
CGraphicsRenderer oRenderer;
oRenderer.SetFontManager(pFontManager);
oRenderer.SetImageCache(&oCache);
if (-1 == nHeight)
{
double dX, dY, dW, dH;
GetBounds(&dX, &dY, &dW, &dH);
nHeight = (int)((double)nWidth * dH / dW);
}
double dDpiX, dDpiY;
oRenderer.get_DpiX(&dDpiX);
oRenderer.get_DpiX(&dDpiY);
double dWidth = nWidth * 72 / 25.4 / dDpiX;
double dHeight = nHeight * 72 / 25.4 / dDpiY;
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
CBgraFrame oFrame;
oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth);
oFrame.put_Height(nHeight);
oFrame.put_Stride(-4 * nWidth);
oRenderer.CreateFromBgraFrame(&oFrame);
oRenderer.put_Width(dWidth);
oRenderer.put_Height(dHeight);
DrawOnRenderer(&oRenderer, 0, 0, dWidth, dHeight);
oFrame.SaveFile(wsOutFilePath, unFileType);
RELEASEINTERFACE(pFontManager);
}
}
#ifndef _METAFILE_H
#define _METAFILE_H
#include "../../fontengine/ApplicationFonts.h"
#include "Wmf/WmfFile.h"
#include "Wmf/RendererOutput.h"
#include "Emf/EmfFile.h"
namespace Metafile
{
const long c_lMetaWmf = 0x01;
const long c_lMetaEmf = 0x02;
const long c_lMetaSvg = 0x04;
class CMetaFile
{
public:
CMetaFile(CApplicationFonts *pAppFonts);
~CMetaFile();
bool LoadFromFile(const wchar_t* wsFilePath);
bool DrawOnRenderer(IRenderer* pRenderer, double dX, double dY, double dWidth, double dHeight);
void Close();
void GetBounds(double* pdX, double* pdY, double* pdW, double* pdH);
void ConvertToRaster(const wchar_t* wsOutFilePath, unsigned int unFileType, int nWidth, int nHeight = -1);
private:
CApplicationFonts* m_pAppFonts;
CFontManager* m_pFontManager;
CWmfFile m_oWmfFile;
TWmfRectF m_oWmfRect;
CEmfFile m_oEmfFile;
long m_lType;
};
}
#endif //_METAFILE_H
\ No newline at end of file
#ifndef _RENDERER_OUTPUT_H
#define _RENDERER_OUTPUT_H
#include "../../../graphics/IRenderer.h"
#include "../../../graphics/structures.h"
#include "../../../graphics/Image.h"
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../raster/BgraFrame.h"
#include "WmfUtils.h"
#include "WmfCharsets.h"
// TODO: Эти два файла не нужны
#include "WmfOutputDevice.h"
#include "WmfFile.h"
//------ Для дебага ----------------------------------------------------
#define NO_PIE // отключаем команду Draw_Pie
//#define NO_ARC // отключаем команду Draw_Arc
#define NO_ELLIPSE // отключаем команду Draw_Ellipse
#define NO_LINE // отключаем команду Draw_Line
#define NO_POLYGON // отключаем команду Draw_Polygon
#define NO_POLYGONS // отключаем команду Draw_Polypolygon
#define NO_POLYLINE // отключаем команду Draw_Polyline
#define NO_CLIP // отключаем комануд Region_Clip
#define NO_RECT // отключаем команду Draw_Rectangle
#define NO_TEXT // отключаем комунду Draw_Text
//#define DRAW_BOUNDS // рисуем границы
//----------------------------------------------------------------------
#define WMF_RGBA(r, g, b) ((DWORD)( ( (BYTE)(r) )| ( ( (BYTE)(g) ) << 8 ) | ( ( (BYTE)(b) ) << 16 ) | ( (BYTE)(0) << 24 ) ) )
class CRendererOutput : public CWmfOutputDevice
{
public:
CRendererOutput(CWmfFile *pFile, IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
{
m_pWmfFile = pFile;
//m_oPen.SetSize( 0.1 );
m_oPen.Size = 0.1;
m_dX = 0;
m_dY = 0;
m_dX1 = dX;
m_dY1 = dY;
m_pRenderer = NULL;
if ( !pRenderer )
return;
m_pRenderer = pRenderer;
//m_oShadow.Visible = FALSE;
//m_pRenderer->put_ShadowVisible(m_oShadow.Visible);
}
~CRendererOutput()
{
}
virtual bool IsSupportPolypolygon() { return true; }
void SetDpi(double dDpiX, double dDpiY)
{
m_dDpiX = dDpiX;
m_dDpiY = dDpiY;
}
void SetWmfRect(TWmfRectF oRect)
{
m_oWmfRect = oRect;
}
void SetScales(double dScaleX, double dScaleY)
{
m_dScaleX = dScaleX;
m_dScaleY = dScaleY;
}
//----------------------------------------------------------------------------------
void Begin()
{
}
void End()
{
DrawBounds( m_pWmfFile->m_pPlayerData->pDC );
}
void Flood_Interior(TWmfFlood *pFlood)
{
// TO DO: Сделать, как будут тестовые файлы
int k = 10;
}
void Flood_Exterior(TWmfFlood *pFlood)
{
// TO DO: Сделать, как будут тестовые файлы
int k = 10;
}
void Draw_Pixel (TWmfDrawPixel *pDrawPixel)
{
// TO DO: Сделать, как будут тестовые файлы
int k =10;
}
void Draw_Pie (TWmfDrawArc *pArc)
{
#ifdef NO_PIE
return;
#endif
long lDrawPathType = -1;
if ( SetBrush( pArc->pDC ) )
lDrawPathType = c_nWindingFillMode;
if ( SetPen( pArc->pDC ) )
{
if ( -1 == lDrawPathType )
lDrawPathType = c_nStroke;
else
lDrawPathType |= c_nStroke;
}
if ( -1 == lDrawPathType )
return;
double dX = pArc->oTL.fX;
double dY = pArc->oTL.fY;
double dW = pArc->oBR.fX - pArc->oTL.fX;
double dH = pArc->oBR.fY - pArc->oTL.fY;
double dStartAngle;
if ( 0 == pArc->oStart.fX )
{
if ( pArc->oStart.fY >= 0 )
dStartAngle = 90;
else
dStartAngle = -90;
}
else
{
dStartAngle = tan( pArc->oStart.fY / pArc->oStart.fX ) * 180 / M_PI;
}
double dEndAngle;
if ( 0 == pArc->oEnd.fX )
{
if ( pArc->oEnd.fY >= 0 )
dEndAngle = 90;
else
dEndAngle = -90;
}
else
{
dEndAngle = tan( pArc->oEnd.fY / pArc->oEnd.fX ) * 180 / M_PI;
}
Trans( pArc->pDC, &dX, &dY );
double dX1 = pArc->oBR.fX;
double dY1 = pArc->oBR.fY;
Trans( pArc->pDC, &dX1, &dY1 );
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
double dXX = pArc->oStart.fX + ( pArc->oTL.fX + pArc->oBR.fX ) / 2;
double dYY = pArc->oStart.fY + ( pArc->oTL.fY + pArc->oBR.fY ) / 2;
Trans( pArc->pDC, &dXX, &dYY );
m_pRenderer->PathCommandMoveTo( (float)dXX, (float)dYY );
m_pRenderer->PathCommandArcTo( (float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), (float)dStartAngle, (float)(dEndAngle - dStartAngle) );
dX = ( pArc->oTL.fX + pArc->oBR.fX ) / 2;
dY = ( pArc->oTL.fY + pArc->oBR.fY ) / 2;
Trans( pArc->pDC, &dX, &dY );
m_pRenderer->PathCommandLineTo( (float)dX, (float)dY );
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath( lDrawPathType );
m_pRenderer->EndCommand( c_nPathType );
}
void Draw_Chord (TWmfDrawArc *pArc)
{
// TO DO: Сделать, как будут тестовые файлы
int k =10;
}
void Draw_Arc (TWmfDrawArc *pArc)
{
#ifdef NO_ARC
return;
#endif
if ( !SetPen( pArc->pDC ) )
return;
double dX = pArc->oTL.fX;
double dY = pArc->oTL.fY;
double dW = pArc->oBR.fX - pArc->oTL.fX;
double dH = pArc->oBR.fY - pArc->oTL.fY;
double dStartAngle;
if ( 0 == pArc->oStart.fX )
{
if ( pArc->oStart.fY >= 0 )
dStartAngle = 90;
else
dStartAngle = -90;
}
else
{
dStartAngle = tan( pArc->oStart.fY / pArc->oStart.fX ) * 180 / M_PI;
}
double dEndAngle;
if ( 0 == pArc->oEnd.fX )
{
if ( pArc->oEnd.fY >= 0 )
dEndAngle = 90;
else
dEndAngle = -90;
}
else
{
dEndAngle = tan( pArc->oEnd.fY / pArc->oEnd.fX ) * 180 / M_PI;
}
Trans( pArc->pDC, &dX, &dY );
double dX1 = pArc->oBR.fX;
double dY1 = pArc->oBR.fY;
Trans( pArc->pDC, &dX1, &dY1 );
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandStart();
double dXX = pArc->oStart.fX + ( pArc->oTL.fX + pArc->oBR.fX ) / 2;
double dYY = pArc->oStart.fY + ( pArc->oTL.fY + pArc->oBR.fY ) / 2;
Trans( pArc->pDC, &dXX, &dYY );
m_pRenderer->PathCommandMoveTo( (float)dXX, (float)dYY );
m_pRenderer->PathCommandArcTo( (float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), (float)dStartAngle, (float)(dEndAngle - dStartAngle) );
m_pRenderer->DrawPath( c_nStroke );
m_pRenderer->EndCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
}
void Draw_Ellipse (TWmfDrawArc *pArc)
{
#ifdef NO_ELLIPSE
return;
#endif
long lDrawPathType = -1;
if ( SetBrush( pArc->pDC ) )
lDrawPathType = c_nWindingFillMode;
if ( SetPen( pArc->pDC ) )
{
if ( -1 == lDrawPathType )
lDrawPathType = c_nStroke;
else
lDrawPathType |= c_nStroke;
}
if ( -1 == lDrawPathType )
return;
double dX = pArc->oTL.fX;
double dY = pArc->oTL.fY;
double dX1 = pArc->oBR.fX;
double dY1 = pArc->oBR.fY;
Trans( pArc->pDC, &dX, &dY );
Trans( pArc->pDC, &dX1, &dY1 );
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
m_pRenderer->PathCommandArcTo( (float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), 0.f, 360.f );
m_pRenderer->DrawPath( lDrawPathType );
m_pRenderer->EndCommand( c_nPathType );
}
void Draw_Line (TWmfDrawLine *pLine)
{
#ifdef NO_LINE
return;
#endif
if ( !SetPen( pLine->pDC ) )
return;
double dX, dY;
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
dX = pLine->oFrom.fX;
dY = pLine->oFrom.fY;
Trans( pLine->pDC, &dX, &dY );
m_pRenderer->PathCommandMoveTo( (float)dX, (float)dY );
dX = pLine->oTo.fX;
dY = pLine->oTo.fY;
Trans( pLine->pDC, &dX, &dY );
m_pRenderer->PathCommandLineTo( (float)dX, (float)dY );
m_pRenderer->DrawPath( c_nStroke );
m_pRenderer->EndCommand( c_nPathType );
}
void Poly_Line (TWmfPolyLine *pPolyLine)
{
#ifdef NO_POLYLINE
return;
#endif
TWmfDC *pDC = pPolyLine->pDC;
if ( !SetPen( pDC ) )
return;
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
for ( unsigned short ushIndex = 0; ushIndex < pPolyLine->ushCount; ushIndex++ )
{
double dX = (double)pPolyLine->pPoints[ushIndex].fX;
double dY = (double)pPolyLine->pPoints[ushIndex].fY;
Trans( pDC, &dX, &dY );
if ( 0 == ushIndex )
m_pRenderer->PathCommandMoveTo( (float)dX, (float)dY );
else
m_pRenderer->PathCommandLineTo( (float)dX, (float)dY );
}
m_pRenderer->DrawPath( c_nStroke );
m_pRenderer->EndCommand( c_nPathType );
}
void Draw_Polypolygon(TWmfPolyPoly *pPolyPoly)
{
#ifdef NO_POLYGONS
return;
#endif
TWmfDC *pDC = pPolyPoly->pDC;
long lDrawPathType = -1;
if ( SetBrush( pDC ) )
{
if ( WINDING == pDC->ushPolyFillMode )
lDrawPathType = c_nWindingFillMode;
else if ( ALTERNATE == pDC->ushPolyFillMode )
lDrawPathType = c_nEvenOddFillMode;
}
if ( SetPen( pDC ) )
{
if ( -1 == lDrawPathType )
lDrawPathType = c_nStroke;
else
lDrawPathType |= c_nStroke;
}
if ( -1 == lDrawPathType )
return;
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
for ( unsigned short ushPolyIndex = 0; ushPolyIndex < pPolyPoly->ushPolyCount; ushPolyIndex++ )
{
unsigned short ushCount = pPolyPoly->pCount[ushPolyIndex];
TWmfCoordF *pPoints = pPolyPoly->ppPoints[ushPolyIndex];
for ( unsigned short ushIndex = 0; ushIndex < ushCount; ushIndex++ )
{
double fX = pPoints[ushIndex].fX;
double fY = pPoints[ushIndex].fY;
Trans( pDC, (double *)&fX, (double *)&fY );
if ( 0 == ushIndex )
{
m_pRenderer->PathCommandMoveTo( (float)fX, (float)fY );
}
else
{
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
}
}
m_pRenderer->PathCommandClose();
}
m_pRenderer->DrawPath( lDrawPathType );
m_pRenderer->EndCommand( c_nPathType );
}
void Draw_Polygon (TWmfPolyLine *pPolyLine)
{
#ifdef NO_POLYGON
return;
#endif
TWmfDC *pDC = pPolyLine->pDC;
long lDrawPathType = -1;
if (SetBrush(pDC))
{
if (WINDING == pDC->ushPolyFillMode)
lDrawPathType = c_nWindingFillMode;
else if (ALTERNATE == pDC->ushPolyFillMode)
lDrawPathType = c_nEvenOddFillMode;
}
if (SetPen(pDC))
{
if (-1 == lDrawPathType)
lDrawPathType = c_nStroke;
else
lDrawPathType |= c_nStroke;
}
if (-1 == lDrawPathType)
return;
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
for (unsigned short ushIndex = 0; ushIndex < pPolyLine->ushCount; ushIndex++)
{
double fX = pPolyLine->pPoints[ushIndex].fX;
double fY = pPolyLine->pPoints[ushIndex].fY;
Trans(pDC, (double *)&fX, (double *)&fY);
if (0 == ushIndex)
{
m_pRenderer->PathCommandMoveTo((float)fX, (float)fY);
}
else
{
m_pRenderer->PathCommandLineTo((float)fX, (float)fY);
}
}
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath(lDrawPathType);
m_pRenderer->EndCommand(c_nPathType);
}
void Draw_Rectangle (TWmfDrawRectangle *pRect)
{
#ifdef NO_RECT
return;
#endif
long lDrawPathType = -1;
if (SetBrush(pRect->pDC))
lDrawPathType = c_nWindingFillMode;
if (SetPen(pRect->pDC))
{
if (-1 == lDrawPathType)
lDrawPathType = c_nStroke;
else
lDrawPathType |= c_nStroke;
}
if (-1 == lDrawPathType)
return;
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
if (0 == pRect->fWidth && 0 == pRect->fHeight) // Простой прямоугольник
{
double dX = pRect->oTL.fX;
double dY = pRect->oTL.fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandMoveTo((float)dX, (float)dY);
dX = pRect->oTL.fX;
dY = pRect->oBR.fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo((float)dX, (float)dY);
dX = pRect->oBR.fX;
dY = pRect->oBR.fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo((float)dX, (float)dY);
dX = pRect->oBR.fX;
dY = pRect->oTL.fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo((float)dX, (float)dY);
m_pRenderer->PathCommandClose();
}
else // прямоугольник с закругленными углами
{
double dA = pRect->fWidth / 2;
double dB = pRect->fHeight / 2;
double dX = pRect->oTL.fX;
double dY = pRect->oTL.fY + dB;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandMoveTo((float)dX, (float)dY);
dX = pRect->oTL.fX;
dY = pRect->oTL.fY;
double dX1 = dX + pRect->fWidth;
double dY1 = dY + pRect->fHeight;
Trans(pRect->pDC, &dX, &dY);
Trans(pRect->pDC, &dX1, &dY1);
m_pRenderer->PathCommandArcTo((float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), 180.f, 90.f);
dX = pRect->oBR.fX - dA;
dY = pRect->oTL.fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo((float)dX, (float)dY);
dX = pRect->oBR.fX - pRect->fWidth;
dY = pRect->oTL.fY;
dX1 = dX + pRect->fWidth;
dY1 = dY + pRect->fHeight;
Trans(pRect->pDC, &dX, &dY);
Trans(pRect->pDC, &dX1, &dY1);
m_pRenderer->PathCommandArcTo((float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), 270.f, 90.f);
dX = pRect->oBR.fX;
dY = pRect->oBR.fY - dB;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo((float)dX, (float)dY);
dX = pRect->oBR.fX - pRect->fWidth;
dY = pRect->oBR.fY - pRect->fHeight;
dX1 = pRect->oBR.fX;
dY1 = pRect->oBR.fY;
Trans(pRect->pDC, &dX, &dY);
Trans(pRect->pDC, &dX1, &dY1);
m_pRenderer->PathCommandArcTo((float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), 0.f, 90.f);
dX = pRect->oTL.fX + dA;
dY = pRect->oBR.fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo((float)dX, (float)dY);
dX = pRect->oTL.fX;
dY = pRect->oBR.fY - pRect->fHeight;
dX1 = dX + pRect->fWidth;
dY1 = dY + pRect->fHeight;
Trans(pRect->pDC, &dX, &dY);
Trans(pRect->pDC, &dX1, &dY1);
m_pRenderer->PathCommandArcTo((float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY), 90.f, 90.f);
m_pRenderer->PathCommandClose();
}
m_pRenderer->DrawPath(lDrawPathType);
m_pRenderer->EndCommand(c_nPathType);
}
void Rop_Draw(TWmfROPDraw *pROP)
{
// TO DO: Сделать, как будут тестовые файлы
int k =10;
}
void Bmp_Draw(TWmfBMPDraw *pDrawBitmap)
{
TWmfDC *pDC = pDrawBitmap->pDC;
USHORT nWidth = pDrawBitmap->oBitmap.ushWidth;
USHORT nHeight = pDrawBitmap->oBitmap.ushHeight;
int nBufferSize = 4 * nWidth * nHeight;
if ( nBufferSize < 1 )
return;
Aggplus::CImage oImage;
BYTE* pBufferPtr = new BYTE[4 * nWidth * nHeight];
oImage.Create(pBufferPtr, nWidth, nHeight, 4 * nWidth);
// Пишем данные в pBufferPtr
for ( int nIndex = 0; nIndex < 4 * nWidth * nHeight; nIndex += 4 )
{
pBufferPtr[0] = (unsigned char)pDrawBitmap->oBitmap.pData[nIndex + 0];
pBufferPtr[1] = (unsigned char)pDrawBitmap->oBitmap.pData[nIndex + 1];
pBufferPtr[2] = (unsigned char)pDrawBitmap->oBitmap.pData[nIndex + 2];
pBufferPtr[3] = (unsigned char)pDrawBitmap->oBitmap.pData[nIndex + 3];
pBufferPtr += 4;
}
double dX = pDrawBitmap->oPoint.fX;
double dY = pDrawBitmap->oPoint.fY;
double dX1 = dX + pDrawBitmap->oBitmap.ushWidth * pDrawBitmap->dPixelWidth;
double dY1 = dY + pDrawBitmap->oBitmap.ushHeight * pDrawBitmap->dPixelHeight;
Trans( pDC, &dX, &dY );
Trans( pDC, &dX1, &dY1 );
m_pRenderer->DrawImage( &oImage, (float)dX, (float)dY, (float)(dX1 - dX), (float)(dY1 - dY));
}
void Bmp_Read(TWmfBMPRead *pReadBitmap)
{
if ( pReadBitmap->lLength <= 0 || NULL == pReadBitmap->pBuffer )
return;
BYTE *pBuffer = pReadBitmap->pBuffer;
long lBufLen = pReadBitmap->lLength;
// Считываем заголовок
unsigned int unHeaderSize = ReadUInt ( pBuffer ); pBuffer += 4; lBufLen -=4;
if ( unHeaderSize < 0x0000000C )
return;
else if ( 0x0000000C == unHeaderSize ) // BitmapCoreHeader
ReadImage_CoreHeader( pReadBitmap, pBuffer, lBufLen );
else // BitmapInfoHeader
ReadImage_InfoHeader( pReadBitmap, pBuffer, lBufLen );
}
void Bmp_Free(TWmfBMP *pBitmap)
{
if ( pBitmap->pData )
free( pBitmap->pData );
}
void Draw_Text(TWmfDrawText *pText)
{
#ifdef NO_TEXT
return;
#endif
double dSize = pText->dFontHeight * m_dScaleY * 72 / 25.4;
SetFont(pText->pDC, dSize);
double dTheta = -((((double)pText->pDC->pFont->shEscapement) / 10) * M_PI / 180);
float fCosTheta = (float)cos(dTheta);
float fSinTheta = (float)sin(dTheta);
double dX = 0, dY = 0;
float fL = 0, fT = 0, fW = 0, fH = 0;
float fUndX1 = 0, fUndY1 = 0, fUndX2 = 0, fUndY2 = 0, fUndSize = 1;
if (m_pWmfFile->m_pFontManager)
{
TWmfFont *pFont = pText->pDC->pFont;
long lStyle = (pFont->ushWeight > 550 ? 1 : 0) + (pFont->unItalic ? 2 : 0);
m_pWmfFile->m_pFontManager->LoadFontByName(ascii_to_unicode(pText->pDC->pFont->sFaceName), dSize, lStyle, 72, 72);
m_pWmfFile->m_pFontManager->LoadString1(ascii_to_unicode(pText->sText), 0, 0);
TBBox oBox = m_pWmfFile->m_pFontManager->MeasureString2();
fL = oBox.fMinX;
fT = oBox.fMinY;
fW = oBox.fMaxX - oBox.fMinX;
fH = oBox.fMaxY - oBox.fMinY;
m_pWmfFile->m_pFontManager->GetUnderline(&fUndX1, &fUndY1, &fUndX2, &fUndY2, &fUndSize);
double fKoef = 25.4 / 72;
fL *= (float)fKoef;
fT *= (float)fKoef;
fW *= (float)fKoef;
fH *= (float)fKoef;
fUndX1 *= (float)fKoef; fUndY1 *= (float)fKoef;
fUndX2 *= (float)fKoef; fUndY2 *= (float)fKoef;
fUndSize *= (float)fKoef / 2;
}
if (!pText->bUseDx)
{
dX = pText->oOrigin.fX;
dY = pText->oOrigin.fY;
Trans(pText->pDC, &dX, &dY);
// Найдем начальную точку текста
if (pText->pDC->ushTextAlign & TA_BASELINE)
{
// Ничего не делаем
}
else if (pText->pDC->ushTextAlign & TA_BOTTOM)
{
float fTemp = -(-fT + fH);
dX += -fTemp * fSinTheta;
dY += fTemp * fCosTheta;
}
else // if ( pPlayer->pDC->ushTextAlign & TA_TOP )
{
float fTemp = -fT;
dX += -fTemp * fSinTheta;
dY += fTemp * fCosTheta;
}
if (pText->pDC->ushTextAlign & TA_CENTER)
{
dX += -fW / 2 * fCosTheta;
dY += -fW / 2 * fSinTheta;
}
else if (pText->pDC->ushTextAlign & TA_RIGHT)
{
dX += -fW * fCosTheta;
dY += -fW * fSinTheta;
}
else //if ( pText->pDC->ushTextAlign & TA_LEFT )
{
// Ничего не делаем
}
}
else
{
dX = pText->oPoint.fX;
dY = pText->oPoint.fY;
Trans(pText->pDC, &dX, &dY);
}
if (pText->pDC->pFont->unUnderline)
{
fUndX1 += (float)dX;
fUndX2 += (float)dX;
fUndY1 += (float)dY;
fUndY2 += (float)dY;
}
std::wstring wsText = TextToUnicode(pText->pDC, pText->sText);
bool bChangeCTM = false;
if (0 != pText->pDC->pFont->shEscapement)
{
// TO DO: тут реализован только параметр shEscapement, еще нужно реализовать параметр shOrientation
m_pRenderer->SetTransform(fCosTheta, fSinTheta, -fSinTheta, fCosTheta, dX - dX * fCosTheta + dY * fSinTheta, dY - dX * fSinTheta - dY * fCosTheta);
bChangeCTM = true;
}
// Для начала нарисуем фон текста
if (OPAQUE == pText->pDC->ushBGMode)
{
long lOldColor = m_oBrush.Color1;
long lOldAlpha = m_oBrush.Alpha1;
long lOldType = m_oBrush.Type;
m_oBrush.Color1 = (RGB(pText->pDC->oBGColor.r, pText->pDC->oBGColor.g, pText->pDC->oBGColor.b));
m_oBrush.Alpha1 = 255;
m_oBrush.Type = c_BrushTypeSolid; // Solid
m_pRenderer->put_BrushType(m_oBrush.Type);
m_pRenderer->put_BrushColor1(m_oBrush.Color1);
m_pRenderer->put_BrushAlpha1(m_oBrush.Alpha1);
float fX = (float)dX;
float fY = (float)dY;
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
m_pRenderer->PathCommandMoveTo(fX + fL, fY + fT);
m_pRenderer->PathCommandLineTo(fX + fL + fW, fY + fT);
m_pRenderer->PathCommandLineTo(fX + fL + fW, fY + fT + fH);
m_pRenderer->PathCommandLineTo(fX + fL, fY + fT + fH);
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath(c_nWindingFillMode);
m_pRenderer->EndCommand(c_nPathType);
m_oBrush.Color1 = lOldColor;
m_oBrush.Alpha1 = lOldAlpha;
m_oBrush.Type = lOldType;
m_pRenderer->put_BrushType(m_oBrush.Type);
m_pRenderer->put_BrushColor1(m_oBrush.Color1);
m_pRenderer->put_BrushAlpha1(m_oBrush.Alpha1);
}
// Нарисуем подчеркивание
if (pText->pDC->pFont->unUnderline)
{
double dOldSize = m_oPen.Size;
unsigned char unOldEndCap = m_oPen.LineEndCap;
unsigned char unOldStartCap = m_oPen.LineStartCap;
m_pRenderer->put_PenSize((double)fUndSize);
m_pRenderer->put_PenLineEndCap(0);
m_pRenderer->put_PenLineStartCap(0);
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
m_pRenderer->PathCommandMoveTo(fUndX1, fUndY1);
m_pRenderer->PathCommandLineTo(fUndX2, fUndY2);
m_pRenderer->DrawPath(c_nStroke);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->put_PenSize(dOldSize);
m_pRenderer->put_PenLineEndCap(unOldEndCap);
m_pRenderer->put_PenLineStartCap(unOldStartCap);
}
// Рисуем сам текст
m_pRenderer->CommandDrawText(wsText, dX, dY, 0, 0, 0);
if (bChangeCTM)
m_pRenderer->ResetTransform();
}
void Region_Frame(TWmfPolyRectangle *pRect)
{
// TO DO: Сделать, как будут тестовые файлы
int k =10;
}
void Region_Paint(TWmfPolyRectangle *pRect)
{
// TO DO: Сделать, как будут тестовые файлы
int k =10;
}
void Region_Clip(TWmfPolyRectangle *pRect)
{
#ifdef NO_CLIP
return;
#endif
m_pRenderer->BeginCommand(c_nResetClipType);
m_pRenderer->EndCommand(c_nResetClipType);
if (pRect->unCount <= 0)
return;
m_pRenderer->BeginCommand(c_nClipType);
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandStart();
for (unsigned int unIndex = 0; unIndex < pRect->unCount; unIndex++)
{
double dX = pRect->pTL[unIndex].fX;
double dY = pRect->pTL[unIndex].fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandMoveTo(dX, dY);
dX = pRect->pTL[unIndex].fX;
dY = pRect->pBR[unIndex].fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo(dX, dY);
dX = pRect->pBR[unIndex].fX;
dY = pRect->pBR[unIndex].fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo(dX, dY);
dX = pRect->pBR[unIndex].fX;
dY = pRect->pTL[unIndex].fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo(dX, dY);
dX = pRect->pTL[unIndex].fX;
dY = pRect->pTL[unIndex].fY;
Trans(pRect->pDC, &dX, &dY);
m_pRenderer->PathCommandLineTo(dX, dY);
}
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->EndCommand(c_nClipType);
m_pRenderer->PathCommandEnd();
}
private:
void DrawBounds(TWmfDC *pDC)
{
#ifdef DRAW_BOUNDS
m_pRenderer->put_PenAlpha( 255 );
m_pRenderer->put_PenColor( 0 );
m_pRenderer->put_PenSize( 1 );
m_pRenderer->put_PenDashStyle( 0 );
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
double dW_4 = (m_oWmfRect.oBR.fX - m_oWmfRect.oTL.fX) / 4;
double dH_4 = (m_oWmfRect.oBR.fY - m_oWmfRect.oTL.fY) / 4;
double fX = m_oWmfRect.oTL.fX;
double fY = m_oWmfRect.oTL.fY;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandMoveTo( (float)fX, (float)fY );
fX = m_oWmfRect.oBR.fX;
fY = m_oWmfRect.oTL.fY;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
fX = m_oWmfRect.oBR.fX;
fY = m_oWmfRect.oBR.fY;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
fX = m_oWmfRect.oTL.fX;
fY = m_oWmfRect.oBR.fY;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath( c_nStroke );
m_pRenderer->EndCommand( c_nPathType );
m_pRenderer->BeginCommand( c_nPathType );
m_pRenderer->PathCommandEnd();
fX = m_oWmfRect.oTL.fX + dW_4;
fY = m_oWmfRect.oTL.fY + dH_4;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandMoveTo( (float)fX, (float)fY );
fX = m_oWmfRect.oBR.fX - dW_4;
fY = m_oWmfRect.oTL.fY + dH_4;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
fX = m_oWmfRect.oBR.fX - dW_4;
fY = m_oWmfRect.oBR.fY - dH_4;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
fX = m_oWmfRect.oTL.fX + dW_4;
fY = m_oWmfRect.oBR.fY - dH_4;
Trans( pDC, (double *)&fX, (double *)&fY );
m_pRenderer->PathCommandLineTo( (float)fX, (float)fY );
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath( c_nStroke );
m_pRenderer->EndCommand( c_nPathType );
#endif
}
void Trans(TWmfDC *pDC, double *pdX, double *pdY)
{
double dX = *pdX;
double dY = *pdY;
if ( pDC->oWindow.nHeight < 0 )
{
*pdY = m_dScaleY * ( (m_oWmfRect.oBR.fY - m_oWmfRect.oTL.fY) - (dY - m_oWmfRect.oTL.fY) ) + m_dY1;
}
else
*pdY = m_dScaleY * ( dY - m_oWmfRect.oTL.fY ) + m_dY1;
if ( pDC->oWindow.nWidth < 0 )
{
*pdX = m_dScaleX * ( (m_oWmfRect.oBR.fX - m_oWmfRect.oTL.fX) - (dX - m_oWmfRect.oTL.fX) ) + m_dX1;
}
else
*pdX = m_dScaleX * (dX - m_oWmfRect.oTL.fX) + m_dX1;
}
std::wstring TextToUnicode(TWmfDC *pDC, char *sText)
{
// Соответствие Charset -> Codepage: http://support.microsoft.com/kb/165478
// http://msdn.microsoft.com/en-us/library/cc194829.aspx
// Charset Name Charset Value(hex) Codepage number
// ------------------------------------------------------
//
// DEFAULT_CHARSET 1 (x01)
// SYMBOL_CHARSET 2 (x02)
// OEM_CHARSET 255 (xFF)
// ANSI_CHARSET 0 (x00) 1252
// RUSSIAN_CHARSET 204 (xCC) 1251
// EASTEUROPE_CHARSET 238 (xEE) 1250
// GREEK_CHARSET 161 (xA1) 1253
// TURKISH_CHARSET 162 (xA2) 1254
// BALTIC_CHARSET 186 (xBA) 1257
// HEBREW_CHARSET 177 (xB1) 1255
// ARABIC _CHARSET 178 (xB2) 1256
// SHIFTJIS_CHARSET 128 (x80) 932
// HANGEUL_CHARSET 129 (x81) 949
// GB2313_CHARSET 134 (x86) 936
// CHINESEBIG5_CHARSET 136 (x88) 950
// THAI_CHARSET 222 (xDE) 874
// JOHAB_CHARSET 130 (x82) 1361
// VIETNAMESE_CHARSET 163 (xA3) 1258
if ( ANSI_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1252[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( DEFAULT_CHARSET == pDC->pFont->unCharSet || UNKNOWN_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
wsText[nIndex] = (unsigned char)(sText[nIndex]);
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( SYMBOL_CHARSET == pDC->pFont->unCharSet )
{
// Ко всем символам, кроме пробела добавляем 0xF000 (Вот и вся кодировка :))
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
wsText[nIndex] = (unsigned char)(sText[nIndex]);
//if ( wsText[nIndex] != 0x0020 )
wsText[nIndex] += 0xF000;
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( MAC_CHARSET == pDC->pFont->unCharSet )
{
// Не используется
return L"";
}
else if ( SHIFTJIS_CHARSET == pDC->pFont->unCharSet )
{
return CP932_CharToUnicode( sText );
}
else if ( HANGUL_CHARSET == pDC->pFont->unCharSet )
{
return CP949_CharToUnicode( sText );
}
else if ( JOHAB_CHARSET == pDC->pFont->unCharSet )
{
return CP1361_CharToUnicode( sText );
}
else if ( GB2312_CHARSET == pDC->pFont->unCharSet )
{
return CP936_CharToUnicode( sText );
}
else if ( CHINESEBIG5_CHARSET == pDC->pFont->unCharSet )
{
return CP950_CharToUnicode( sText );
}
else if ( GREEK_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1253[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( TURKISH_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1254[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( VIETNAMESE_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1258[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( HEBREW_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1255[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( ARABIC_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1256[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( BALTIC_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1257[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( RUSSIAN_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1251[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( THAI_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP874[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( EASTEUROPE_CHARSET == pDC->pFont->unCharSet )
{
wchar_t *wsText = new wchar_t[strlen(sText) + 1];
if ( NULL == wsText )
return L"";
wsText[strlen(sText)] = '\0';
int nLen = (int)strlen(sText);
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP1250[unChar - MSCP_FIRST_CHAR] );
}
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else if ( OEM_CHARSET == pDC->pFont->unCharSet )
{
int nLen = (int)strlen(sText);
wchar_t *wsText = new wchar_t[nLen + 1];
if ( NULL == wsText )
return L"";
wsText[nLen] = '\0';
#ifdef _WIN32
// Пытаемся воспользоваться системной функцией
if ( !OemToCharBuffW( sText, wsText, nLen ) )
{
// Системная функция почему-то не сработала. Конвертируем самостоятельно.
// Запрашиваем кодировку
UINT unCP = GetOEMCP();
// Предполагаем, что кодировка CP866 (на самом деле, надо исходить из unCP)
for ( int nIndex = 0; nIndex < nLen; nIndex++ )
{
unsigned char unChar = (unsigned char)(sText[nIndex]);
if ( unChar < MSCP_FIRST_CHAR || unChar > MSCP_LAST_CHAR )
wsText[nIndex] = (unsigned char)(sText[nIndex]);
else
wsText[nIndex] = (wchar_t)( c_anUnicodeMapCP866[unChar - MSCP_FIRST_CHAR] );
}
}
#endif
std::wstring wsResult(wsText);
delete []wsText;
return wsResult;
}
else
{
//
}
return L"";
}
bool SetPen (TWmfDC *pDC)
{
TWmfPen *pPen = pDC->pPen;
long lColor = WMF_RGBA(pPen->oColor.r, pPen->oColor.g, pPen->oColor.b);
double dWidth = pPen->dWidth * m_dScaleX ;
if ( dWidth <= 0.01 )
dWidth = 0;
m_oPen.Size = dWidth;
m_oPen.Color = lColor;
unsigned short ushPenType = pPen->ushStyle & PS_TYPE_MASK;
unsigned short ushPenEndCap = pPen->ushStyle & PS_ENDCAP_MASK;
unsigned short ushPenJoin = pPen->ushStyle & PS_JOIN_MASK;
unsigned short ushPenStyle = pPen->ushStyle & PS_STYLE_MASK;
BYTE nCapStyle = 0;
if ( 0 == ushPenEndCap )
nCapStyle = 2;
else if ( 1 == ushPenEndCap )
nCapStyle = 1;
else if ( 2 == ushPenEndCap )
nCapStyle = 0;
m_oPen.LineStartCap = nCapStyle;
m_oPen.LineEndCap = nCapStyle;
BYTE nJoinStyle = 0;
if ( 0 == ushPenJoin )
nJoinStyle = 2;
else if ( 1 == ushPenJoin )
nJoinStyle = 1;
else if ( 2 == ushPenJoin )
nJoinStyle = 2;
m_oPen.LineJoin = nJoinStyle;
// TODO: Некоторые типы пена невозможно реализовать с текущим интерфейсом рендерера, поэтому мы делаем его пока PS_SOLID.
if (PS_ALTERNATE == ushPenStyle || PS_USERSTYLE == ushPenStyle || PS_INSIDEFRAME == ushPenStyle)
m_oPen.DashStyle = (BYTE)PS_SOLID;
else if (PS_NULL != ushPenStyle)
m_oPen.DashStyle = (BYTE)ushPenStyle;
m_pRenderer->put_PenDashStyle( m_oPen.DashStyle );
m_pRenderer->put_PenLineJoin( m_oPen.LineJoin );
m_pRenderer->put_PenLineStartCap( m_oPen.LineStartCap );
m_pRenderer->put_PenLineEndCap( m_oPen.LineEndCap );
m_pRenderer->put_PenColor( m_oPen.Color );
m_pRenderer->put_PenSize( m_oPen.Size );
m_pRenderer->put_PenAlpha( 255 );
// TO DO: С текущим интерфейсом AVSRenderer, остальные случаи ushROPMode
// реализовать невозможно. Потому что данный параметр нужно протаскивать
// как параметр Pen'a, и тот кто рисует сам должен разруливать все случаи.
switch (pDC->ushROPMode)
{
case R2_BLACK: m_pRenderer->put_PenColor( 0 ); break;
case R2_NOP: m_pRenderer->put_PenAlpha( 0 ); break;
case R2_COPYPEN: break;
case R2_WHITE: m_pRenderer->put_PenColor(WMF_RGBA(255, 255, 255)); break;
}
if ( PS_NULL == ushPenStyle )
return false;
return true;
}
bool SetBrush(TWmfDC *pDC)
{
TWmfBrush *pBrush = pDC->pBrush;
long lColor = WMF_RGBA(pBrush->oColor.r, pBrush->oColor.g, pBrush->oColor.b);
if ( BS_NULL == pBrush->ushStyle )
return false;
else if ( BS_SOLID == pBrush->ushStyle )
{
m_oBrush.Color1 = lColor;
m_oBrush.Alpha1 = 255;
m_oBrush.Type = c_BrushTypeSolid;
m_pRenderer->put_BrushColor1( m_oBrush.Color1 );
m_pRenderer->put_BrushAlpha1( m_oBrush.Alpha1 );
m_pRenderer->put_BrushType( m_oBrush.Type );
}
else if ( BS_PATTERN == pBrush->ushStyle )
{
// TO DO: сделать этот вариант
}
else if (BS_DIBPATTERN == pBrush->ushStyle)
{
if (NULL == pBrush->oBitmap.pData || 0 == pBrush->oBitmap.ushHeight || 0 == pBrush->oBitmap.ushWidth)
return false;
USHORT nWidth = pBrush->oBitmap.ushWidth;
USHORT nHeight = pBrush->oBitmap.ushHeight;
int nBufferSize = 4 * nWidth * nHeight;
if (nBufferSize < 1)
return false;
Aggplus::CImage oImage;
BYTE* pBufferPtr = new BYTE[4 * nWidth * nHeight];
oImage.Create(pBufferPtr, nWidth, nHeight, 4 * nWidth);
// Пишем данные в pBufferPtr
for (int nIndex = 0; nIndex < 4 * nWidth * nHeight; nIndex += 4)
{
pBufferPtr[0] = (unsigned char)pBrush->oBitmap.pData[nIndex + 0];
pBufferPtr[1] = (unsigned char)pBrush->oBitmap.pData[nIndex + 1];
pBufferPtr[2] = (unsigned char)pBrush->oBitmap.pData[nIndex + 2];
pBufferPtr[3] = (unsigned char)pBrush->oBitmap.pData[nIndex + 3];
pBufferPtr += 4;
}
FILE *pTempFile = NULL;
std::wstring wsTempFileName;
if (!WmfOpenTempFile(&wsTempFileName, &pTempFile, L"wb", L".wmf0", NULL))
{
return false;
}
::fclose(pTempFile);
oImage.SaveFile(wsTempFileName, _CXIMAGE_FORMAT_PNG);
m_oBrush.TexturePath = wsTempFileName;
m_oBrush.TextureMode = c_BrushTextureModeTile;
m_oBrush.Type = c_BrushTypeTexture;
m_pRenderer->put_BrushTextureMode(m_oBrush.Type);
m_pRenderer->put_BrushType(m_oBrush.Type);
m_pRenderer->put_BrushTexturePath(m_oBrush.TexturePath);
//m_oBrush.SetTexturePath( wsTempFileName );
//m_oBrush.SetTextureMode( 1 );
//m_oBrush.SetType( 8 ); // Текстурный
//BSTR bsBrush = m_oBrush.ToXmlString().AllocSysString();
//m_pRenderer->SetBrush( bsBrush );
//::SysFreeString( bsBrush );
// TODO: Либо переделать этот вариант, либо разобраться что делать с темповым файлом в конце
return true;
}
else if ( BS_HATCHED == pBrush->ushStyle )
{
/*m_oBrush.SetType( 9 + pBrush->ushHatch );
m_oBrush.SetColor1( RGB( pBrush->oColor.r, pBrush->oColor.g, pBrush->oColor.b ) );
m_oBrush.SetColor2( RGB( pDC->oBGColor.r, pDC->oBGColor.g, pDC->oBGColor.b ) );
m_oBrush.SetAlpha1( 255 );
m_oBrush.SetAlpha2( 255 );
if ( TRANSPARENT == pDC->ushBGMode )
m_oBrush.SetAlpha2( 0 );
else // OPAQUE
m_oBrush.SetAlpha2( 255 );*/
m_oBrush.Type = ( 9 + pBrush->ushHatch );
m_oBrush.Color1 = ( RGB( pBrush->oColor.r, pBrush->oColor.g, pBrush->oColor.b ) );
m_oBrush.Color2 = ( RGB( pDC->oBGColor.r, pDC->oBGColor.g, pDC->oBGColor.b ) );
m_oBrush.Alpha1 = ( 255 );
m_oBrush.Alpha2 = ( 255 );
if ( TRANSPARENT == pDC->ushBGMode )
m_oBrush.Alpha2 = ( 0 );
else // OPAQUE
m_oBrush.Alpha2 = ( 255 );
m_pRenderer->put_BrushColor1( m_oBrush.Color1 );
m_pRenderer->put_BrushAlpha1( m_oBrush.Alpha1 );
m_pRenderer->put_BrushColor2( m_oBrush.Color2 );
m_pRenderer->put_BrushAlpha2( m_oBrush.Alpha2 );
m_pRenderer->put_BrushType( m_oBrush.Type );
}
return true;
}
bool SetFont (TWmfDC *pDC, double dFontHeight)
{
TWmfFont *pFont = pDC->pFont;
m_pRenderer->put_FontName(ascii_to_unicode(pFont->sFaceName));
m_pRenderer->put_FontSize(dFontHeight);
LONG lStyle = 0;
if (pFont->ushWeight > 550)
lStyle |= 0x01;
if (pFont->unItalic)
lStyle |= 0x02;
if (pFont->unUnderline)
lStyle |= (1 << 2);
if (pFont->unStrikeOut)
lStyle |= (1 << 7);
m_pRenderer->put_FontStyle(lStyle);
// Установим цвет текста и фона
m_oBrush.Color1 = ( RGB( pDC->oTextColor.r, pDC->oTextColor.g, pDC->oTextColor.b ) );
m_oBrush.Alpha1 = ( 255 );
m_oBrush.Color2 = ( RGB( pDC->oBGColor.r, pDC->oBGColor.g, pDC->oBGColor.b ) );
m_oBrush.Alpha2 = ( 255 );
m_oBrush.Type = ( c_BrushTypeSolid );
m_pRenderer->put_BrushType(m_oBrush.Type);
m_pRenderer->put_BrushColor1(m_oBrush.Color1);
m_pRenderer->put_BrushAlpha1(m_oBrush.Alpha1);
return true;
}
unsigned int ReadUInt (BYTE *pBuffer)
{
return (unsigned int)( (pBuffer[3] << 24) | (pBuffer[2] << 16) | (pBuffer[1] << 8) | pBuffer[0] );
}
unsigned short ReadUShort(BYTE *pBuffer)
{
return (unsigned short)( (pBuffer[1] << 8) | pBuffer[0] );
}
int ReadInt (BYTE *pBuffer)
{
return (int)( (pBuffer[3] << 24) | (pBuffer[2] << 16) | (pBuffer[1] << 8) | pBuffer[0] );
}
BYTE ReadByte (BYTE *pBuffer)
{
return (BYTE)(pBuffer[0]);
}
bool ReadImage_CoreHeader(TWmfBMPRead *pReadBitmap, BYTE *pBuffer, long lBufLen)
{
unsigned short ushWidth = ReadUShort( pBuffer ); pBuffer += 2; lBufLen -= 2;
unsigned short ushHeight = ReadUShort( pBuffer ); pBuffer += 2; lBufLen -= 2;
unsigned short ushPlanes = ReadUShort( pBuffer ); pBuffer += 2; lBufLen -= 2;
unsigned short ushBitCount = ReadUShort( pBuffer ); pBuffer += 2; lBufLen -= 2;
if ( 0x0001 != ushPlanes )
return false;
return false;
}
bool ReadImage_InfoHeader(TWmfBMPRead *pReadBitmap, BYTE *pBuffer, long lBufLen)
{
int nWidth = ReadInt(pBuffer); pBuffer += 4; lBufLen -= 4;
int nHeight = ReadInt(pBuffer); pBuffer += 4; lBufLen -= 4;
unsigned short ushPlanes = ReadUShort(pBuffer); pBuffer += 2; lBufLen -= 2;
unsigned short ushBitCount = ReadUShort(pBuffer); pBuffer += 2; lBufLen -= 2;
unsigned int unCompression = ReadUInt(pBuffer); pBuffer += 4; lBufLen -= 4;
unsigned int unImageSize = ReadUInt(pBuffer); pBuffer += 4; lBufLen -= 4;
unsigned int unXPelsPerMeter = ReadUInt(pBuffer); pBuffer += 4; lBufLen -= 4;
unsigned int unYPelsPerMeter = ReadUInt(pBuffer); pBuffer += 4; lBufLen -= 4;
unsigned int unColorUsed = ReadUInt(pBuffer); pBuffer += 4; lBufLen -= 4;
unsigned int unColorImportant = ReadUInt(pBuffer); pBuffer += 4; lBufLen -= 4;
if (0x0001 != ushPlanes)
return false;
if (nHeight < 0x00000000 && (BI_RGB != unCompression))
return false;
if (nWidth < 0)
return false;
if (BI_BITCOUNT_0 == ushBitCount) // Значит компрессия либо PNG, либо JPEG
{
if (BI_JPEG != unCompression || BI_PNG != unCompression)
return false;
std::wstring wsTempFileName;
FILE* pTempFile = NULL;
if (!WmfOpenTempFile(&wsTempFileName, &pTempFile, L"wb", L".wmf0", NULL))
return false;
::fwrite(pBuffer, 1, unImageSize, pTempFile);
::fclose(pTempFile);
CBgraFrame oFrame;
oFrame.OpenFile(wsTempFileName);
// TODO: Как будут файлы сделать чтение.
::_wunlink(wsTempFileName.c_str());
return false;
}
else if (BI_BITCOUNT_1 == ushBitCount)
{
// Двуцветная картинка, значит палитра состоит из 2-х цветов
TWmfRGB oColor1, oColor2;
oColor1.r = ReadByte(pBuffer); pBuffer++; lBufLen--;
oColor1.g = ReadByte(pBuffer); pBuffer++; lBufLen--;
oColor1.b = ReadByte(pBuffer); pBuffer++; lBufLen--;
pBuffer++; lBufLen--;
oColor2.r = ReadByte(pBuffer); pBuffer++; lBufLen--;
oColor2.g = ReadByte(pBuffer); pBuffer++; lBufLen--;
oColor2.b = ReadByte(pBuffer); pBuffer++; lBufLen--;
pBuffer++; lBufLen--;
// Считываем саму картинку
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
pReadBitmap->oBitmap.pData = (BYTE *)malloc(nWidth * nHeight * 4 * sizeof(BYTE));
if (NULL == pReadBitmap->oBitmap.pData)
return false;
pReadBitmap->oBitmap.ushHeight = (unsigned short)abs(nHeight);
pReadBitmap->oBitmap.ushWidth = (unsigned short)nWidth;
int nWidthBytes = (nWidth + 7) / 8;
int nAdditBytes = 4 - div_t(div(((nWidth + 7) / 8), 4)).rem;
if (4 == nAdditBytes)
nAdditBytes = 0;
int nLastBitCount = div_t(div(nWidth, 8)).rem - 1;
if (-1 == nLastBitCount)
nLastBitCount = 7;
nLastBitCount = (int)pow((double)2, (double)nLastBitCount);
for (int nY = 0, nIndex = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidthBytes; nX++)
{
int nByte = ReadByte(pBuffer); pBuffer++; lBufLen--;
int nBitCount = 128;
if (nX == nWidthBytes - 1)
nBitCount = nLastBitCount;
for (int nBitIndex = nBitCount; nBitIndex > 0; nBitIndex /= 2)
{
int nBit = (nByte & nBitIndex);
TWmfRGB oColor = (nBit ? oColor2 : oColor1);
pReadBitmap->oBitmap.pData[nIndex * 4 + 0] = oColor.b;
pReadBitmap->oBitmap.pData[nIndex * 4 + 1] = oColor.g;
pReadBitmap->oBitmap.pData[nIndex * 4 + 2] = oColor.r;
pReadBitmap->oBitmap.pData[nIndex * 4 + 3] = 255;
nIndex++;
}
}
for (int nAddIndex = 0; nAddIndex < nAdditBytes; nAddIndex++)
{
int nByte = ReadByte(pBuffer); pBuffer++; lBufLen--;
}
}
return true;
}
else if (BI_BITCOUNT_2 == ushBitCount)
{
// TO DO: Сделать данный вариант, как только будет файлы с данным типом
int nTODO = 100;
return false;
}
else if (BI_BITCOUNT_3 == ushBitCount)
{
unsigned short ushColorTableLen = 256;
if (0 != unColorUsed)
ushColorTableLen = (std::min)((unsigned short)256, (unsigned short)unColorUsed);
TWmfRGB oColorTable[256];
if (lBufLen < ushColorTableLen * 4)
return false;
// Считываем палитру
for (unsigned short ushIndex = 0; ushIndex < ushColorTableLen; ushIndex++)
{
oColorTable[ushIndex].r = ReadByte(pBuffer); pBuffer++; lBufLen--;
oColorTable[ushIndex].g = ReadByte(pBuffer); pBuffer++; lBufLen--;
oColorTable[ushIndex].b = ReadByte(pBuffer); pBuffer++; lBufLen--;
pBuffer++; lBufLen--;
}
// 1 байт - 1 пиксел
// Ширина должна быть кратна 4.
int nAdd = 0;
while (0 != div_t(div(nWidth + nAdd, 4)).rem)
{
nAdd++;
}
if (lBufLen < nWidth * nHeight)
return false;
pReadBitmap->oBitmap.pData = (BYTE *)malloc(nWidth * nHeight * 4 * sizeof(BYTE));
if (NULL == pReadBitmap->oBitmap.pData)
return false;
pReadBitmap->oBitmap.ushHeight = (unsigned short)abs(nHeight);
pReadBitmap->oBitmap.ushWidth = (unsigned short)nWidth;
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
BYTE nByte = ReadByte(pBuffer); pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 0] = oColorTable[nByte].b;
pReadBitmap->oBitmap.pData[nIndex + 1] = oColorTable[nByte].g;
pReadBitmap->oBitmap.pData[nIndex + 2] = oColorTable[nByte].r;
pReadBitmap->oBitmap.pData[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
BYTE nByte = ReadByte(pBuffer); pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 0] = oColorTable[nByte].b;
pReadBitmap->oBitmap.pData[nIndex + 1] = oColorTable[nByte].g;
pReadBitmap->oBitmap.pData[nIndex + 2] = oColorTable[nByte].r;
pReadBitmap->oBitmap.pData[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
return true;
}
else if (BI_BITCOUNT_4 == ushBitCount)
{
// TO DO: Сделать данный вариант, как только будет файлы с данным типом
int nTODO = 100;
return false;
}
else if (BI_BITCOUNT_5 == ushBitCount)
{
// Пропускаем таблицу цветов (она не нужна)
pBuffer += unColorUsed * 4; lBufLen -= unColorUsed * 4;
if (BI_RGB != unCompression)
return false; // TO DO: Сделать данный вариант, как только будет файлы с данным типом
// Считываем саму картинку
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
// 1 байт на каждый канал
// (Ширина * 3) должна быть кратна 4.
int nAdd = 0;
while (0 != div_t(div(3 * nWidth + nAdd, 4)).rem)
{
nAdd++;
}
int nSize = nWidth * nHeight * 4;
pReadBitmap->oBitmap.pData = (BYTE *)malloc(nWidth * nHeight * 4 * sizeof(BYTE));
if (NULL == pReadBitmap->oBitmap.pData)
return false;
pReadBitmap->oBitmap.ushHeight = (unsigned short)abs(nHeight);
pReadBitmap->oBitmap.ushWidth = (unsigned short)nWidth;
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
pReadBitmap->oBitmap.pData[nIndex + 0] = pBuffer[0]; pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 1] = pBuffer[0]; pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 2] = pBuffer[0]; pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nX = 0; nX < nWidth; nX++)
{
int nIndex = 4 * (nWidth * nY + nX);
pReadBitmap->oBitmap.pData[nIndex + 0] = pBuffer[0]; pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 1] = pBuffer[0]; pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 2] = pBuffer[0]; pBuffer++; lBufLen--;
pReadBitmap->oBitmap.pData[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
}
}
return true;
}
else if (BI_BITCOUNT_6 == ushBitCount)
{
// TO DO: Сделать данный вариант, как только будет файлы с данным типом
int nTODO = 100;
return false;
}
return false;
}
private:
IRenderer* m_pRenderer;
NSStructures::CPen m_oPen;
NSStructures::CBrush m_oBrush;
NSStructures::CFont m_oFont;
double m_dDpiX;
double m_dDpiY;
TWmfRectF m_oWmfRect; // Общий рект, в котором рисуется вся картинка
double m_dX; // Координаты левого верхнего угла
double m_dY; //
double m_dScaleX; // Коэффициенты сжатия/растяжения, чтобы
double m_dScaleY; // результирующая картинка была нужных размеров.
double m_dX1;
double m_dY1;
CWmfFile* m_pWmfFile;
};
#endif /* _RENDERER_OUTPUT_H */
#ifndef _WMF_CHARSETS_H
#define _WMF_CHARSETS_H
#include "WmfCodePage932.h"
#include "WmfCodePage936.h"
#include "WmfCodePage949.h"
#include "WmfCodePage950.h"
#include "WmfCodePage1361.h"
#define MSCP_FIRST_CHAR 32
#define MSCP_LAST_CHAR 255
//-- CP866 Encoding - (OEM_CHARSET) --------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP866[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040e, 0x045e,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x2116, 0x00a4, 0x25a0, 0x00a0
};
//-- CP874 Encoding ------------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP874[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x2026, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F,
0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0x0000, 0x0000, 0x0000, 0x0000
};
//-- CP1250 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1250[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
};
//-- CP1251 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1251[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F
};
//-- CP1252 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1252[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017D, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x017E, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
};
//-- CP1253 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1253[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x0000, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x0000
};
//-- CP1254 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1254[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF
};
//-- CP1255 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1255[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0000, 0x0000, 0x0000, 0x0000,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
0x05B8, 0x05B9, 0x0000, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
0x05F4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, 0x0000
};
//-- CP1256 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1256[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2
};
//-- CP1257 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1257[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0000, 0x201E, 0x2026, 0x2020, 0x2021,
0x0000, 0x2030, 0x0000, 0x2039, 0x0000, 0x00A8, 0x02C7, 0x00B8,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x0000, 0x2122, 0x0000, 0x203A, 0x0000, 0x00AF, 0x02DB, 0x0000,
0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x0000, 0x00A6, 0x00A7,
0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9
};
//-- CP1258 Encoding -----------------------------------------------------------------------------
static const unsigned short c_anUnicodeMapCP1258[] =
{
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
0x20AC, 0x0000, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
0x02C6, 0x2030, 0x0000, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000,
0x0000, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
0x02DC, 0x2122, 0x0000, 0x203A, 0x0153, 0x0000, 0x0000, 0x0178,
0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF
};
#endif /* _WMF_CHARSETS_H */
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef _WMF_COLOR_H
#define _WMF_COLOR_H
#include "WmfTypes.h"
#include <stdio.h>
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
const TWmfRGB c_oColorAliceblue = { 240, 248, 255 };
const TWmfRGB c_oColorAntiquewhite = { 250, 235, 215 };
const TWmfRGB c_oColorAqua = { 0, 255, 255 };
const TWmfRGB c_oColorAquamarine = { 127, 255, 212 };
const TWmfRGB c_oColorAzure = { 240, 255, 255 };
const TWmfRGB c_oColorBeige = { 245, 245, 220 };
const TWmfRGB c_oColorBisque = { 255, 228, 196 };
const TWmfRGB c_oColorBlack = { 0, 0, 0 };
const TWmfRGB c_oColorBlanchedalmond = { 255, 235, 205 };
const TWmfRGB c_oColorBlue = { 0, 0, 255 };
const TWmfRGB c_oColorBlueviolet = { 138, 43, 226 };
const TWmfRGB c_oColorBrown = { 165, 42, 42 };
const TWmfRGB c_oColorBurlywood = { 222, 184, 135 };
const TWmfRGB c_oColorCadetblue = { 95, 158, 160 };
const TWmfRGB c_oColorChartreuse = { 127, 255, 0 };
const TWmfRGB c_oColorChocolate = { 210, 105, 30 };
const TWmfRGB c_oColorCoral = { 255, 127, 80 };
const TWmfRGB c_oColorCornflowerblue = { 100, 149, 237 };
const TWmfRGB c_oColorCornsilk = { 255, 248, 220 };
const TWmfRGB c_oColorCrimson = { 220, 20, 60 };
const TWmfRGB c_oColorCyan = { 0, 255, 255 };
const TWmfRGB c_oColorDarkblue = { 0, 0, 139 };
const TWmfRGB c_oColorDarkcyan = { 0, 139, 139 };
const TWmfRGB c_oColorDarkgoldenrod = { 184, 134, 11 };
const TWmfRGB c_oColorDarkgray = { 169, 169, 169 };
const TWmfRGB c_oColorDarkgreen = { 0, 100, 0 };
const TWmfRGB c_oColorDarkgrey = { 169, 169, 169 };
const TWmfRGB c_oColorDarkkhaki = { 189, 183, 107 };
const TWmfRGB c_oColorDarkmagenta = { 139, 0, 139 };
const TWmfRGB c_oColorDarkolivegreen = { 85, 107, 47 };
const TWmfRGB c_oColorDarkorange = { 255, 140, 0 };
const TWmfRGB c_oColorDarkorchid = { 153, 50, 204 };
const TWmfRGB c_oColorDarkred = { 139, 0, 0 };
const TWmfRGB c_oColorDarksalmon = { 233, 150, 122 };
const TWmfRGB c_oColorDarkseagreen = { 143, 188, 143 };
const TWmfRGB c_oColorDarkslateblue = { 72, 61, 139 };
const TWmfRGB c_oColorDarkslategray = { 47, 79, 79 };
const TWmfRGB c_oColorDarkslategrey = { 47, 79, 79 };
const TWmfRGB c_oColorDarkturquoise = { 0, 206, 209 };
const TWmfRGB c_oColorDarkviolet = { 148, 0, 211 };
const TWmfRGB c_oColorDeeppink = { 255, 20, 147 };
const TWmfRGB c_oColorDeepskyblue = { 0, 191, 255 };
const TWmfRGB c_oColorDimgray = { 105, 105, 105 };
const TWmfRGB c_oColorDimgrey = { 105, 105, 105 };
const TWmfRGB c_oColorDodgerblue = { 30, 144, 255 };
const TWmfRGB c_oColorFirebrick = { 178, 34, 34 };
const TWmfRGB c_oColorFloralwhite = { 255, 250, 240 };
const TWmfRGB c_oColorForestgreen = { 34, 139, 34 };
const TWmfRGB c_oColorFuchsia = { 255, 0, 255 };
const TWmfRGB c_oColorGainsboro = { 220, 220, 220 };
const TWmfRGB c_oColorGhostwhite = { 248, 248, 255 };
const TWmfRGB c_oColorGold = { 255, 215, 0 };
const TWmfRGB c_oColorGoldenrod = { 218, 165, 32 };
const TWmfRGB c_oColorGray = { 128, 128, 128 };
const TWmfRGB c_oColorGrey = { 128, 128, 128 };
const TWmfRGB c_oColorGreen = { 0, 128, 0 };
const TWmfRGB c_oColorGreenyellow = { 173, 255, 47 };
const TWmfRGB c_oColorHoneydew = { 240, 255, 240 };
const TWmfRGB c_oColorHotpink = { 255, 105, 180 };
const TWmfRGB c_oColorIndianred = { 205, 92, 92 };
const TWmfRGB c_oColorIndigo = { 75, 0, 130 };
const TWmfRGB c_oColorIvory = { 255, 255, 240 };
const TWmfRGB c_oColorKhaki = { 240, 230, 140 };
const TWmfRGB c_oColorLavender = { 230, 230, 250 };
const TWmfRGB c_oColorLavenderblush = { 255, 240, 245 };
const TWmfRGB c_oColorLawngreen = { 124, 252, 0 };
const TWmfRGB c_oColorLemonchiffon = { 255, 250, 205 };
const TWmfRGB c_oColorLightblue = { 173, 216, 230 };
const TWmfRGB c_oColorLightcoral = { 240, 128, 128 };
const TWmfRGB c_oColorLightcyan = { 224, 255, 255 };
const TWmfRGB c_oColorLightgoldenrodyellow = { 250, 250, 210 };
const TWmfRGB c_oColorLightgray = { 211, 211, 211 };
const TWmfRGB c_oColorLightgreen = { 144, 238, 144 };
const TWmfRGB c_oColorLightgrey = { 211, 211, 211 };
const TWmfRGB c_oColorLightpink = { 255, 182, 193 };
const TWmfRGB c_oColorLightsalmon = { 255, 160, 122 };
const TWmfRGB c_oColorLightseagreen = { 32, 178, 170 };
const TWmfRGB c_oColorLightskyblue = { 135, 206, 250 };
const TWmfRGB c_oColorLightslategray = { 119, 136, 153 };
const TWmfRGB c_oColorLightslategrey = { 119, 136, 153 };
const TWmfRGB c_oColorLightsteelblue = { 176, 196, 222 };
const TWmfRGB c_oColorLightyellow = { 255, 255, 224 };
const TWmfRGB c_oColorLime = { 0, 255, 0 };
const TWmfRGB c_oColorLimegreen = { 50, 205, 50 };
const TWmfRGB c_oColorLinen = { 250, 240, 230 };
const TWmfRGB c_oColorMagenta = { 255, 0, 255 };
const TWmfRGB c_oColorMaroon = { 128, 0, 0 };
const TWmfRGB c_oColorMediumaquamarine = { 102, 205, 170 };
const TWmfRGB c_oColorMediumblue = { 0, 0, 205 };
const TWmfRGB c_oColorMediumorchid = { 186, 85, 211 };
const TWmfRGB c_oColorMediumpurple = { 147, 112, 219 };
const TWmfRGB c_oColorMediumseagreen = { 60, 179, 113 };
const TWmfRGB c_oColorMediumslateblue = { 123, 104, 238 };
const TWmfRGB c_oColorMediumspringgreen = { 0, 250, 154 };
const TWmfRGB c_oColorMediumturquoise = { 72, 209, 204 };
const TWmfRGB c_oColorMediumvioletred = { 199, 21, 133 };
const TWmfRGB c_oColorMidnightblue = { 25, 25, 112 };
const TWmfRGB c_oColorMintcream = { 245, 255, 250 };
const TWmfRGB c_oColorMistyrose = { 255, 228, 225 };
const TWmfRGB c_oColorMoccasin = { 255, 228, 181 };
const TWmfRGB c_oColorNavajowhite = { 255, 222, 173 };
const TWmfRGB c_oColorNavy = { 0, 0, 128 };
const TWmfRGB c_oColorOldlace = { 253, 245, 230 };
const TWmfRGB c_oColorOlive = { 128, 128, 0 };
const TWmfRGB c_oColorOlivedrab = { 107, 142, 35 };
const TWmfRGB c_oColorOrange = { 255, 165, 0 };
const TWmfRGB c_oColorOrangered = { 255, 69, 0 };
const TWmfRGB c_oColorOrchid = { 218, 112, 214 };
const TWmfRGB c_oColorPalegoldenrod = { 238, 232, 170 };
const TWmfRGB c_oColorPalegreen = { 152, 251, 152 };
const TWmfRGB c_oColorPaleturquoise = { 175, 238, 238 };
const TWmfRGB c_oColorPalevioletred = { 219, 112, 147 };
const TWmfRGB c_oColorPapayawhip = { 255, 239, 213 };
const TWmfRGB c_oColorPeachpuff = { 255, 218, 185 };
const TWmfRGB c_oColorPeru = { 205, 133, 63 };
const TWmfRGB c_oColorPink = { 255, 192, 203 };
const TWmfRGB c_oColorPlum = { 221, 160, 221 };
const TWmfRGB c_oColorPowderblue = { 176, 224, 230 };
const TWmfRGB c_oColorPurple = { 128, 0, 128 };
const TWmfRGB c_oColorRed = { 255, 0, 0 };
const TWmfRGB c_oColorRosybrown = { 188, 143, 143 };
const TWmfRGB c_oColorRoyalblue = { 65, 105, 225 };
const TWmfRGB c_oColorSaddlebrown = { 139, 69, 19 };
const TWmfRGB c_oColorSalmon = { 250, 128, 114 };
const TWmfRGB c_oColorSandybrown = { 244, 164, 96 };
const TWmfRGB c_oColorSeagreen = { 46, 139, 87 };
const TWmfRGB c_oColorSeashell = { 255, 245, 238 };
const TWmfRGB c_oColorSienna = { 160, 82, 45 };
const TWmfRGB c_oColorSilver = { 192, 192, 192 };
const TWmfRGB c_oColorSkyblue = { 135, 206, 235 };
const TWmfRGB c_oColorSlateblue = { 106, 90, 205 };
const TWmfRGB c_oColorSlategray = { 112, 128, 144 };
const TWmfRGB c_oColorSlategrey = { 112, 128, 144 };
const TWmfRGB c_oColorSnow = { 255, 250, 250 };
const TWmfRGB c_oColorSpringgreen = { 0, 255, 127 };
const TWmfRGB c_oColorSteelblue = { 70, 130, 180 };
const TWmfRGB c_oColorTan = { 210, 180, 140 };
const TWmfRGB c_oColorTeal = { 0, 128, 128 };
const TWmfRGB c_oColorThistle = { 216, 191, 216 };
const TWmfRGB c_oColorTomato = { 255, 99, 71 };
const TWmfRGB c_oColorTurquoise = { 64, 224, 208 };
const TWmfRGB c_oColorViolet = { 238, 130, 238 };
const TWmfRGB c_oColorWheat = { 245, 222, 179 };
const TWmfRGB c_oColorWhite = { 255, 255, 255 };
const TWmfRGB c_oColorWhitesmoke = { 245, 245, 245 };
const TWmfRGB c_oColorYellow = { 255, 255, 0 };
const TWmfRGB c_oColorYellowgreen = { 154, 205, 50 };
//---------------------------------------------------------------------------------------------------
// CWmfColor
//---------------------------------------------------------------------------------------------------
class CWmfColor
{
public:
CWmfColor()
{
m_pError = NULL;
m_ulmax = 32;
m_ulCount = 0;
m_pRGB = (TWmfRGB *)malloc(m_ulmax * sizeof(TWmfRGB));
m_pRGB[0] = c_oColorRed;
}
~CWmfColor()
{
if ( NULL != m_pRGB )
free( m_pRGB );
}
void SetErrorHandler(EWmfError *pError)
{
m_pError = pError;
}
void Add(TWmfRGB *pRGB)
{
if ( CheckError() )
return;
bool bNewColor = true;
for (unsigned long ulIndex = 0; ulIndex < m_ulCount; ulIndex++)
{
if ( ( pRGB->r == m_pRGB[ulIndex].r ) && ( pRGB->g == m_pRGB[ulIndex].g ) && ( pRGB->b == m_pRGB[ulIndex].b ) )
{
bNewColor = false;
break;
}
}
if ( !bNewColor )
return;
if ( m_ulCount == m_ulmax )
{
TWmfRGB *pData = (TWmfRGB *)realloc( m_pRGB, (m_ulmax + 32) * sizeof(TWmfRGB) );
if ( NULL == pData )
{
SetError( wmf_error_NotEnoughMemory );
return;
}
m_pRGB = pData;
m_ulmax += 32;
}
m_pRGB[m_ulCount] = (*pRGB);
m_ulCount++;
}
unsigned long GetColorIndex(TWmfRGB *pRGB)
{
unsigned long ulBest = 0;
unsigned int unDistBest = 766;
if ( CheckError() || 0 == m_ulCount )
{
return ulBest;
}
//
for (unsigned long ulIndex = 0; ulIndex < m_ulCount; ulIndex++)
{
if ( ( pRGB->r == m_pRGB[ulIndex].r ) && ( pRGB->g == m_pRGB[ulIndex].g ) && ( pRGB->b == m_pRGB[ulIndex].b ) )
{
ulBest = ulIndex;
unDistBest = 0;
break;
}
}
if ( 0 == unDistBest )
return ulBest;
//
for (unsigned long ulIndex = 0; ulIndex < m_ulCount; ulIndex++)
{
unsigned int unDistR = (unsigned int) abs(((int) (pRGB->r)) - ((int) (m_pRGB[ulIndex].r)));
unsigned int unDistG = (unsigned int) abs(((int) (pRGB->g)) - ((int) (m_pRGB[ulIndex].g)));
unsigned int unDistB = (unsigned int) abs(((int) (pRGB->b)) - ((int) (m_pRGB[ulIndex].b)));
unsigned int unDist = (std::max)( (std::max)( unDistR, unDistG ),unDistB );
if ( unDist < unDistBest )
{
ulBest = ulIndex;
unDistBest = unDist;
}
}
return ulBest;
}
unsigned long GetCount()
{
return m_ulCount;
}
TWmfRGB* GetColor(unsigned long ulIndex)
{
if ( CheckError() || ulIndex >= m_ulCount )
return ((TWmfRGB *)&c_oColorRed);
return (m_pRGB + ulIndex);
}
public:
static TWmfRGB LongToRGB(unsigned short ushFirstByte, unsigned short ushSecondByte)
{
TWmfRGB oColor;
oColor.r = (unsigned char) (ushFirstByte & 0x00FF);
oColor.g = (unsigned char)((ushFirstByte & 0xFF00) >> 8);
oColor.b = (unsigned char) (ushSecondByte & 0x00FF);
return oColor;
}
static TWmfRGB WhiteColor()
{
return c_oColorWhite;
}
static TWmfRGB BlackColor()
{
return c_oColorWhite;
}
static TWmfRGB RGBColor(float fRed, float fGreen, float fBlue)
{
TWmfRGB oColor;
fRed = (std::max)( 0.0f, (std::min)( 1.0f, fRed ) );
fGreen = (std::max)( 0.0f, (std::min)( 1.0f, fGreen ) );
fBlue = (std::max)( 0.0f, (std::min)( 1.0f, fBlue ) );
int nRed = (int) (fRed * (float) 256);
int nGreen = (int) (fGreen * (float) 256);
int nBlue = (int) (fBlue * (float) 256);
nRed = (std::max)( 0, (std::min)( 255, nRed ) );
nGreen = (std::max)( 0, (std::min)( 255, nGreen ) );
nBlue = (std::max)( 0, (std::min)( 255, nBlue ) );
oColor.r = (unsigned char) nRed;
oColor.g = (unsigned char) nGreen;
oColor.b = (unsigned char) nBlue;
return oColor;
}
private:
bool CheckError()
{
if ( NULL == m_pError || wmf_error_None == *m_pError )
return false;
return true;
}
void SetError(EWmfError eError)
{
if ( NULL != m_pError )
{
*m_pError = eError;
}
}
private:
unsigned long m_ulmax;
unsigned long m_ulCount;
TWmfRGB *m_pRGB;
EWmfError *m_pError;
};
#endif /* _WMF_COLOR_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
#ifndef _WMF_MEMORY_H
#define _WMF_MEMORY_H
#include <stdio.h>
#ifdef _DEBUG
//#define DebugCheckMemory
//#include <vector>
//#include <iterator>
#endif
class CWmfMemoryManager
{
public:
CWmfMemoryManager()
{
#ifdef DebugCheckMemory
m_arrDescription.clear();
m_arrMemoryList.clear();
#endif
}
~CWmfMemoryManager()
{
#ifdef DebugCheckMemory
m_arrDescription.clear();
m_arrMemoryList.clear();
#endif
}
void *Malloc(size_t unSize, std::wstring sDescription)
{
void *pAddress = malloc(unSize);
if (NULL == pAddress)
return NULL;
#ifdef DebugCheckMemory
Add(pAddress, sDescription);
#endif
return pAddress;
}
void *Realloc(void *pMemory, size_t unSize)
{
#ifdef DebugCheckMemory
std::wstring sDescription = Remove(pMemory);
#endif
void *pAddress = realloc(pMemory, unSize);
if (NULL == pAddress)
return NULL;
#ifdef DebugCheckMemory
Add(pAddress, sDescription);
#endif
return pAddress;
}
void Free(void *pMemory)
{
if (pMemory)
{
free(pMemory);
}
#ifdef DebugCheckMemory
Remove(pMemory);
#endif
}
private:
#ifdef DebugCheckMemory
void Add(void *pAddress, std::wstring sDescription)
{
m_arrDescription.push_back(sDescription);
m_arrMemoryList.push_back(pAddress);
}
std::wstring Remove(void *pAddress)
{
int nIndex = 0;
for (nIndex = 0; nIndex < m_arrMemoryList.size(); nIndex++)
{
if (pAddress == m_arrMemoryList.at(nIndex))
break;
}
if (nIndex >= m_arrMemoryList.size())
return L"";
m_arrMemoryList.erase(m_arrMemoryList.begin() + nIndex);
std::wstring sResult = m_arrDescription.at(nIndex);
m_arrDescription.erase(m_arrDescription.begin() + nIndex);
return sResult;
}
#endif
private:
#ifdef DebugCheckMemory
std::vector<void *> m_arrMemoryList;
std::vector<std::wstring> m_arrDescription;
#endif
};
#endif /* _WMF_MEMORY_H */
\ No newline at end of file
#ifndef _WMF_OUTPUT_DEVICE_H
#define _WMF_OUTPUT_DEVICE_H
#include "WmfTypes.h"
class CWmfOutputDevice
{
public:
CWmfOutputDevice() {}
virtual ~CWmfOutputDevice() {}
virtual bool IsSupportPolypolygon() { return false; }
//
virtual void Begin() = 0;
virtual void End () = 0;
virtual void Flood_Interior(TWmfFlood*) = 0;
virtual void Flood_Exterior(TWmfFlood*) = 0;
virtual void Draw_Pixel (TWmfDrawPixel*) = 0;
virtual void Draw_Pie (TWmfDrawArc*) = 0;
virtual void Draw_Chord (TWmfDrawArc*) = 0;
virtual void Draw_Arc (TWmfDrawArc*) = 0;
virtual void Draw_Ellipse (TWmfDrawArc*) = 0;
virtual void Draw_Line (TWmfDrawLine*) = 0;
virtual void Poly_Line (TWmfPolyLine*) = 0;
virtual void Draw_Polygon (TWmfPolyLine*) = 0;
virtual void Draw_Polypolygon(TWmfPolyPoly*) = 0;
virtual void Draw_Rectangle (TWmfDrawRectangle*) = 0;
virtual void Rop_Draw(TWmfROPDraw*) = 0;
virtual void Bmp_Draw(TWmfBMPDraw*) = 0;
virtual void Bmp_Read(TWmfBMPRead*) = 0;
virtual void Bmp_Free(TWmfBMP*) = 0;
virtual void Draw_Text(TWmfDrawText*) = 0;
virtual void Region_Frame(TWmfPolyRectangle*) = 0;
virtual void Region_Paint(TWmfPolyRectangle*) = 0;
virtual void Region_Clip (TWmfPolyRectangle*) = 0;
private:
};
#endif /* _WMF_OUTPUT_DEVICE_H */
\ No newline at end of file
#ifndef _WMF_REGION_H
#define _WMF_REGION_H
#include "WmfTypes.h"
typedef bool (*pProcO) (TWmfRegion*, TWmfRectF*, TWmfRectF*, TWmfRectF*, TWmfRectF*, float, float);
typedef bool (*pProcNonO) (TWmfRegion*, TWmfRectF*, TWmfRectF*, float, float);
static bool REGION_CopyRegion (TWmfRegion *pDst, TWmfRegion *pSrc);
static bool REGION_UnionRegion (TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB);
static void REGION_IntersectRegion (TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB);
static void REGION_SubtractRegion (TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB);
static bool REGION_UnionO (TWmfRegion *pRegion, TWmfRectF *pRect1, TWmfRectF *pRect1End, TWmfRectF *pRect2, TWmfRectF *pRect2End, float fTop, float fBottom);
static bool REGION_UnionNonO (TWmfRegion *pRegion, TWmfRectF *pRect, TWmfRectF *pRectEnd, float fTop, float fBottom);
static bool REGION_SubtractO (TWmfRegion *pRegion, TWmfRectF *pRect1, TWmfRectF *pRect1End, TWmfRectF *pRect2, TWmfRectF *pRect2End, float fTop, float fBottom);
static bool REGION_IntersectO(TWmfRegion *pRegion, TWmfRectF *pRect1, TWmfRectF *pRect1End, TWmfRectF *pRect2, TWmfRectF *pRect2End, float fTop, float fBottom);
static void REGION_RegionOp (TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB, pProcO pOverlapFunc, pProcNonO pNonOverlap1Func, pProcNonO pNonOverlap2Func);
static unsigned int REGION_Coalesce (TWmfRegion *pRegion, unsigned int unPrevStart, unsigned int unCurStart);
static void REGION_SetExtents (TWmfRegion *pRegion);
static TWmfRectF *RegionMemChk(TWmfRegion *pRegion)
{
if ( pRegion->unNumRects < ( pRegion->unSize - 1 ) )
return pRegion->pRects + pRegion->unNumRects;
TWmfRectF *pMore = (TWmfRectF *)realloc( pRegion->pRects, (pRegion->unSize + 8) * sizeof (TWmfRectF));
if ( NULL == pMore )
return NULL;
pRegion->pRects = pMore;
pRegion->unSize += 8;
return pRegion->pRects + pRegion->unNumRects;
}
static bool RectMerge (TWmfRegion *pRegion, TWmfRectF *pRect, float fTop, float fBottom)
{
TWmfRectF *pNextRect = 0;
TWmfRectF *pPrior = 0;
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
if ( pRegion->unNumRects == 0 )
{
pRegion->unNumRects++;
pNextRect->oTL.fX = pRect->oTL.fX;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect->oBR.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
}
else
{
pPrior = pNextRect - 1;
if ( ( pPrior->oTL.fY == fTop ) && ( pPrior->oBR.fY == fBottom ) && ( pPrior->oBR.fX >= pRect->oTL.fX ) )
{
if ( pPrior->oBR.fX < pRect->oBR.fX )
pPrior->oBR.fX = pRect->oBR.fX;
}
else
{
pRegion->unNumRects++;
pNextRect->oTL.fX = pRect->oTL.fX;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect->oBR.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
}
}
return true;
}
// 1
// 0
#define EXTENTCHECK(pRegion1,pRegion2) \
( ((pRegion1)->oBR.fX > (pRegion2)->oTL.fX) \
&& ((pRegion1)->oTL.fX < (pRegion2)->oBR.fX) \
&& ((pRegion1)->oBR.fY > (pRegion2)->oTL.fY) \
&& ((pRegion1)->oTL.fY < (pRegion2)->oBR.fY) )
static void WmfSetRectRegion(TWmfRegion *pRegion, TWmfRectF *pRect)
{
if ( ( NULL == pRect ) || ( pRect->oTL.fX == pRect->oBR.fX ) || ( pRect->oTL.fY == pRect->oBR.fY ) )
{
pRegion->oExtents.oTL.fX = 0;
pRegion->oExtents.oTL.fY = 0;
pRegion->oExtents.oBR.fX = 0;
pRegion->oExtents.oBR.fY = 0;
pRegion->unNumRects = 0;
pRegion->ushType = NULLREGION;
}
else
{
pRegion->oExtents = (*pRect);
(*(pRegion->pRects)) = (*pRect);
pRegion->unNumRects = 1;
pRegion->ushType = SIMPLEREGION;
}
}
static void WmfCombineRegion(TWmfRegion *pDestObj, TWmfRegion *pSrcObjA, TWmfRegion *pSrcObjB, unsigned short ushMode)
{
if ( ( NULL == pDestObj ) || ( NULL == pSrcObjA ) )
return;
if ( RGN_COPY == ushMode )
{
REGION_CopyRegion( pDestObj, pSrcObjA );
return;
}
if ( pSrcObjB )
{
switch ( ushMode )
{
case RGN_OR:
REGION_UnionRegion( pDestObj, pSrcObjA, pSrcObjB );
break;
case RGN_AND:
REGION_IntersectRegion( pDestObj, pSrcObjA, pSrcObjB );
break;
#if 0
case RGN_XOR:
REGION_XorRegion (API,destObj,src1Obj,src2Obj);
break;
#endif
case RGN_DIFF:
REGION_SubtractRegion( pDestObj, pSrcObjA, pSrcObjB );
break;
}
}
}
static bool REGION_UnionRegion(TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB)
{
//
// ,
if ( ( pRegionA == pRegionB ) || ( !( pRegionA->unNumRects ) ) )
{
if ( pNewRegion != pRegionB )
return REGION_CopyRegion( pNewRegion, pRegionB );
return true;
}
//
if ( 0 == pRegionB->unNumRects )
{
if ( pNewRegion != pRegionA )
return REGION_CopyRegion( pNewRegion, pRegionA );
return true;
}
// B A
if ( ( pRegionA->unNumRects == 1 ) && ( pRegionA->oExtents.oTL.fX <= pRegionB->oExtents.oTL.fX ) && ( pRegionA->oExtents.oTL.fY <= pRegionB->oExtents.oTL.fY ) && ( pRegionA->oExtents.oBR.fX >= pRegionB->oExtents.oBR.fX ) && ( pRegionA->oExtents.oBR.fY >= pRegionB->oExtents.oBR.fY ) )
{
if ( pNewRegion != pRegionA )
return REGION_CopyRegion( pNewRegion, pRegionA );
return true;
}
// A B
if ( ( pRegionB->unNumRects == 1 ) && ( pRegionB->oExtents.oTL.fX <= pRegionA->oExtents.oTL.fX ) && ( pRegionB->oExtents.oTL.fY <= pRegionA->oExtents.oTL.fY ) && ( pRegionB->oExtents.oBR.fX >= pRegionA->oExtents.oBR.fX ) && ( pRegionB->oExtents.oBR.fY >= pRegionA->oExtents.oBR.fY ) )
{
if ( pNewRegion != pRegionB )
return REGION_CopyRegion( pNewRegion, pRegionB );
return true;
}
REGION_RegionOp( pNewRegion, pRegionA, pRegionB, REGION_UnionO, REGION_UnionNonO, REGION_UnionNonO);
pNewRegion->oExtents.oTL.fX = (std::min)( pRegionA->oExtents.oTL.fX, pRegionB->oExtents.oTL.fX );
pNewRegion->oExtents.oTL.fY = (std::min)( pRegionA->oExtents.oTL.fY, pRegionB->oExtents.oTL.fY );
pNewRegion->oExtents.oBR.fX = (std::max)( pRegionA->oExtents.oBR.fX, pRegionB->oExtents.oBR.fX );
pNewRegion->oExtents.oBR.fY = (std::max)( pRegionA->oExtents.oBR.fY, pRegionB->oExtents.oBR.fY );
pNewRegion->ushType = ( pNewRegion->unNumRects ? COMPLEXREGION : NULLREGION );
return true;
}
static bool REGION_CopyRegion (TWmfRegion *pDst, TWmfRegion *pSrc)
{
if ( pDst != pSrc )
{
if ( pDst->unSize < pSrc->unNumRects )
{
pDst->pRects = (TWmfRectF *)realloc( pDst->pRects, pSrc->unNumRects * sizeof (TWmfRectF) );
if ( NULL == pDst->pRects )
return false;
pDst->unSize = pSrc->unNumRects;
}
pDst->unNumRects = pSrc->unNumRects;
pDst->oExtents.oTL.fX = pSrc->oExtents.oTL.fX;
pDst->oExtents.oTL.fY = pSrc->oExtents.oTL.fY;
pDst->oExtents.oBR.fX = pSrc->oExtents.oBR.fX;
pDst->oExtents.oBR.fY = pSrc->oExtents.oBR.fY;
pDst->ushType = pSrc->ushType;
memcpy ( (char*)pDst->pRects, (char*)pSrc->pRects, (int)(pSrc->unNumRects * sizeof(TWmfRectF)));
}
return true;
}
static void REGION_RegionOp (TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB, pProcO pOverlapFunc, pProcNonO pNonOverlap1Func, pProcNonO pNonOverlap2Func)
{
TWmfRectF* r1; /* Pointer into first region */
TWmfRectF* r2; /* Pointer into 2d region */
TWmfRectF* r1End; /* End of 1st region */
TWmfRectF* r2End; /* End of 2d region */
TWmfRectF* oldRects; /* Old rects for newReg */
TWmfRectF* r1BandEnd; /* End of current band in r1 */
TWmfRectF* r2BandEnd; /* End of current band in r2 */
TWmfRectF* prev_rects;
float ytop; /* Top of intersection */
float ybot; /* Bottom of intersection */
float top; /* Top of non-overlapping band */
float bot; /* Bottom of non-overlapping band */
unsigned int prevBand; /* Index of start of previous band in newReg */
unsigned int curBand; /* Index of start of current band in newReg */
/*Initialization:
*
* set r1, r2, r1End and r2End appropriately, preserve the important
* parts of the destination region until the end in case it's one of
* the two source regions, then mark the "new" region empty, allocating
* another array of rectangles for it to use.
*/
r1 = pRegionA->pRects;
r2 = pRegionB->pRects;
r1End = r1 + pRegionA->unNumRects;
r2End = r2 + pRegionB->unNumRects;
/* newReg may be one of the src regions so we can't empty it. We keep a
* note of its rects pointer (so that we can free them later), preserve its
* extents and simply set numRects to zero.
*/
oldRects = pNewRegion->pRects;
pNewRegion->unNumRects = 0;
/* Allocate a reasonable number of rectangles for the new region. The idea
* is to allocate enough so the individual functions don't need to
* reallocate and copy the array, which is time consuming, yet we don't
* have to worry about using too much memory. I hope to be able to
* nuke the Xrealloc() at the end of this function eventually.
*/
pNewRegion->unSize = (std::max)( pRegionA->unNumRects, pRegionB->unNumRects ) * 2;
if ( NULL == ( pNewRegion->pRects = (TWmfRectF *)malloc( sizeof(TWmfRectF) * pNewRegion->unSize ) ) )
{
pNewRegion->unSize = 0;
return;
}
/* Initialize ybot and ytop.
*
* In the upcoming loop, ybot and ytop serve different functions depending
* on whether the band being handled is an overlapping or non-overlapping
* band.
*
* In the case of a non-overlapping band (only one of the regions
* has points in the band), ybot is the bottom of the most recent
* intersection and thus clips the top of the rectangles in that band.
* ytop is the top of the next intersection between the two regions and
* serves to clip the bottom of the rectangles in the current band.
*
* For an overlapping band (where the two regions intersect), ytop clips
* the top of the rectangles of both regions and ybot clips the bottoms.
*/
if ( pRegionA->oExtents.oTL.fY < pRegionB->oExtents.oTL.fY )
{
ybot = pRegionA->oExtents.oTL.fY;
}
else
{
ybot = pRegionB->oExtents.oTL.fY;
}
/* prevBand serves to mark the start of the previous band so rectangles
* can be coalesced into larger rectangles. qv. miCoalesce, above.
* In the beginning, there is no previous band, so prevBand == curBand
* (curBand is set later on, of course, but the first band will always
* start at index 0). prevBand and curBand must be indices because of
* the possible expansion, and resultant moving, of the new region's
* array of rectangles.
*/
prevBand = 0;
do
{
curBand = pNewRegion->unNumRects;
/* This algorithm proceeds one source-band (as opposed to a
* destination band, which is determined by where the two regions
* intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
* rectangle after the last one in the current band for their
* respective regions.
*/
r1BandEnd = r1;
while ( ( r1BandEnd != r1End ) && ( r1BandEnd->oTL.fY == r1->oTL.fY ) )
r1BandEnd++;
r2BandEnd = r2;
while ( ( r2BandEnd != r2End ) && ( r2BandEnd->oTL.fY == r2->oTL.fY ) )
r2BandEnd++;
/* First handle the band that doesn't intersect, if any.
*
* Note that attention is restricted to one band in the
* non-intersecting region at once, so if a region has n
* bands between the current position and the next place it overlaps
* the other, this entire loop will be passed through n times.
*/
if ( r1->oTL.fY < r2->oTL.fY )
{
top = (std::max)( r1->oTL.fY, ybot );
bot = (std::min)( r1->oBR.fY, r2->oTL.fY );
if ( ( top != bot ) && ( pNonOverlap1Func ) )
{
(*pNonOverlap1Func)( pNewRegion, r1, r1BandEnd, top, bot);
}
ytop = r2->oTL.fY;
}
else if ( r2->oTL.fY < r1->oTL.fY )
{
top = (std::max)( r2->oTL.fY, ybot );
bot = (std::min)( r2->oBR.fY, r1->oTL.fY );
if ( ( top != bot ) && ( pNonOverlap2Func ) )
{
(*pNonOverlap2Func)( pNewRegion, r2, r2BandEnd, top, bot);
}
ytop = r1->oTL.fY;
}
else
{
ytop = r1->oTL.fY;
}
/* If any rectangles got added to the region, try and coalesce them
* with rectangles from the previous band. Note we could just do
* this test in miCoalesce, but some machines incur a not
* inconsiderable cost for function calls, so...
*/
if ( pNewRegion->unNumRects != curBand )
{
prevBand = REGION_Coalesce( pNewRegion, prevBand, curBand );
}
/* Now see if we've hit an intersecting band. The two bands only
* intersect if ybot > ytop
*/
ybot = (std::min)( r1->oBR.fY, r2->oBR.fY );
curBand = pNewRegion->unNumRects;
if ( ( ybot > ytop ) && ( pOverlapFunc ) )
{
(*pOverlapFunc)( pNewRegion, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot );
}
if ( pNewRegion->unNumRects != curBand )
{
prevBand = REGION_Coalesce( pNewRegion, prevBand, curBand );
}
/* If we've finished with a band (bottom == ybot) we skip forward
* in the region to the next band.
*/
if ( r1->oBR.fY == ybot )
r1 = r1BandEnd;
if ( r2->oBR.fY == ybot )
r2 = r2BandEnd;
} while ((r1 != r1End) && (r2 != r2End));
/* Deal with whichever region still has rectangles left.
*/
curBand = pNewRegion->unNumRects;
if ( r1 != r1End )
{
if ( pNonOverlap1Func )
{
do
{
r1BandEnd = r1;
while ( ( r1BandEnd < r1End ) && ( r1BandEnd->oTL.fY == r1->oTL.fY ) )
r1BandEnd++;
(*pNonOverlap1Func)( pNewRegion, r1, r1BandEnd, (std::max)( r1->oTL.fY, ybot ), r1->oBR.fY );
r1 = r1BandEnd;
} while ( r1 != r1End );
}
}
else if ( ( r2 != r2End ) && ( pNonOverlap2Func ) )
{
do
{
r2BandEnd = r2;
while ( ( r2BandEnd < r2End ) && ( r2BandEnd->oTL.fY == r2->oTL.fY ) )
r2BandEnd++;
(*pNonOverlap2Func)( pNewRegion, r2, r2BandEnd, (std::max)( r2->oTL.fY, ybot ), r2->oBR.fY );
r2 = r2BandEnd;
} while ( r2 != r2End );
}
if ( pNewRegion->unNumRects != curBand )
{
REGION_Coalesce( pNewRegion, prevBand, curBand );
}
/* A bit of cleanup. To keep regions from growing without bound,
* we shrink the array of rectangles to match the new number of
* rectangles in the region. This never goes to 0, however...
*
* Only do this stuff if the number of rectangles allocated is more than
* twice the number of rectangles in the region (a simple optimization...).
*/
if ( pNewRegion->unNumRects < ( pNewRegion->unSize >> 1 ) )
{
if ( pNewRegion->unNumRects ) /* REGION_NOT_EMPTY */
{
prev_rects = pNewRegion->pRects;
pNewRegion->unSize = pNewRegion->unNumRects;
pNewRegion->pRects = (TWmfRectF *)realloc( pNewRegion->pRects, sizeof(TWmfRectF) * pNewRegion->unSize );
if ( NULL == pNewRegion->pRects )
pNewRegion->pRects = prev_rects;
}
else
{ /* No point in doing the extra work involved in an Xrealloc if
* the region is empty
*/
pNewRegion->unSize = 1;
free( pNewRegion->pRects );
pNewRegion->pRects = (TWmfRectF *)malloc( sizeof(TWmfRectF) );
}
}
free( oldRects );
}
static unsigned int REGION_Coalesce (TWmfRegion *pRegion, unsigned int unPrevStart, unsigned int unCurStart)
{
TWmfRectF *pPrevRect; /* Current rect in previous band */
TWmfRectF *pCurRect; /* Current rect in current band */
TWmfRectF *pRegEnd; /* End of region */
unsigned int curNumRects; /* Number of rectangles in current band */
unsigned int prevNumRects; /* Number of rectangles in previous band */
float bandtop; /* top coordinate for current band */
pRegEnd = pRegion->pRects + pRegion->unNumRects;
pPrevRect = pRegion->pRects + unPrevStart;
prevNumRects = unCurStart - unPrevStart;
/* Figure out how many rectangles are in the current band. Have to do
* this because multiple bands could have been added in REGION_RegionOp
* at the end when one region has been exhausted.
*/
pCurRect = pRegion->pRects + unCurStart;
bandtop = pCurRect->oTL.fY;
for (curNumRects = 0; (pCurRect != pRegEnd) && (pCurRect->oTL.fY == bandtop); curNumRects++)
{
pCurRect++;
}
if (pCurRect != pRegEnd)
{ /* If more than one band was added, we have to find the start
* of the last band added so the next coalescing job can start
* at the right place... (given when multiple bands are added,
* this may be pointless -- see above).
*/
pRegEnd--;
while ( pRegEnd[-1].oTL.fY == pRegEnd->oTL.fY )
pRegEnd--;
unCurStart = (unsigned int) ( pRegEnd - pRegion->pRects );
pRegEnd = pRegion->pRects + pRegion->unNumRects;
}
if ((curNumRects == prevNumRects) && (curNumRects != 0))
{ pCurRect -= curNumRects;
/* The bands may only be coalesced if the bottom of the previous
* matches the top scanline of the current.
*/
if ( pPrevRect->oBR.fY == pCurRect->oTL.fY )
{ /* Make sure the bands have rects in the same places. This
* assumes that rects have been added in such a way that they
* cover the most area possible. I.e. two rects in a band must
* have some horizontal space between them.
*/
do
{ if ( (pPrevRect->oTL.fX != pCurRect->oTL.fX )
|| (pPrevRect->oBR.fX != pCurRect->oBR.fX))
{ /* The bands don't line up so they can't be coalesced.
*/
return (unCurStart);
}
pPrevRect++;
pCurRect++;
prevNumRects -= 1;
} while (prevNumRects != 0);
pRegion->unNumRects -= curNumRects;
pCurRect -= curNumRects;
pPrevRect -= curNumRects;
/* The bands may be merged, so set the bottom of each rect
* in the previous band to that of the corresponding rect in
* the current band.
*/
do
{ pPrevRect->oBR.fY = pCurRect->oBR.fY;
pPrevRect++;
pCurRect++;
curNumRects -= 1;
} while (curNumRects != 0);
/* If only one band was added to the region, we have to backup
* curStart to the start of the previous band.
*
* If more than one band was added to the region, copy the
* other bands down. The assumption here is that the other bands
* came from the same region as the current one and no further
* coalescing can be done on them since it's all been done
* already... curStart is already in the right place.
*/
if (pCurRect == pRegEnd)
{ unCurStart = unPrevStart;
}
else
{ do
{ *pPrevRect++ = *pCurRect++;
} while (pCurRect != pRegEnd);
}
}
}
return (unCurStart);
}
static bool REGION_UnionO (TWmfRegion *pRegion, TWmfRectF *pRect1, TWmfRectF *pRect1End, TWmfRectF *pRect2, TWmfRectF *pRect2End, float fTop, float fBottom)
{
while ( ( pRect1 != pRect1End ) && ( pRect2 != pRect2End ) )
{
if ( pRect1->oTL.fX < pRect2->oTL.fX )
{
if ( !RectMerge( pRegion, pRect1, fTop, fBottom ) )
return false;
pRect1++;
}
else
{
if ( !RectMerge( pRegion, pRect2, fTop, fBottom ) )
return false;
pRect2++;
}
}
if ( pRect1 != pRect1End )
{
do
{
if ( !RectMerge( pRegion, pRect1, fTop, fBottom ) )
return false;
pRect1++;
} while ( pRect1 != pRect1End );
}
else
{
while ( pRect2 != pRect2End )
{
if ( !RectMerge( pRegion, pRect2, fTop, fBottom ) )
return false;
pRect2++;
}
}
return true;
}
static bool REGION_UnionNonO(TWmfRegion *pRegion, TWmfRectF *pRect, TWmfRectF *pRectEnd, float fTop, float fBottom)
{
TWmfRectF* pNextRect = 0;
while ( pRect != pRectEnd )
{
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
pRegion->unNumRects++;
pNextRect->oTL.fX = pRect->oTL.fX;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect->oBR.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
pRect++;
}
return true;
}
static bool REGION_SubtractNonO1 (TWmfRegion *pRegion, TWmfRectF *pRect, TWmfRectF *pRectEnd, float fTop, float fBottom)
{
TWmfRectF *pNextRect = 0;
while ( pRect != pRectEnd )
{
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
pRegion->unNumRects++;
pNextRect->oTL.fX = pRect->oTL.fX;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect->oBR.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
pRect++;
}
return true;
}
static void REGION_SubtractRegion(TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB)
{
if ( ( pRegionA->unNumRects == 0 ) || ( pRegionB->unNumRects == 0 ) || ( !EXTENTCHECK ( &pRegionA->oExtents, &pRegionB->oExtents ) ) )
{
REGION_CopyRegion ( pNewRegion, pRegionA );
return;
}
REGION_RegionOp( pNewRegion, pRegionA, pRegionB, REGION_SubtractO, REGION_SubtractNonO1, NULL );
/* Can't alter newReg's extents before we call miRegionOp because
* it might be one of the source regions and miRegionOp depends
* on the extents of those regions being the unaltered. Besides, this
* way there's no checking against rectangles that will be nuked
* due to coalescing, so we have to examine fewer rectangles.
*/
REGION_SetExtents( pNewRegion );
pNewRegion->ushType = ( pNewRegion->unNumRects ? COMPLEXREGION : NULLREGION );
}
static bool REGION_SubtractO (TWmfRegion *pRegion, TWmfRectF *pRect1, TWmfRectF *pRect1End, TWmfRectF *pRect2, TWmfRectF *pRect2End, float fTop, float fBottom)
{
TWmfRectF* pNextRect = 0;
float fLeft = pRect1->oTL.fX;
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
while ( ( pRect1 != pRect1End ) && ( pRect2 != pRect2End ) )
{
if ( pRect2->oBR.fX <= fLeft )
{
pRect2++;
}
else if ( pRect2->oTL.fX <= fLeft )
{
fLeft = pRect2->oBR.fX;
if ( fLeft >= pRect1->oBR.fX )
{
pRect1++;
if ( pRect1 != pRect1End )
fLeft = pRect1->oTL.fX;
}
else
{
pRect2++;
}
}
else if ( pRect2->oTL.fX < pRect1->oBR.fX )
{
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
pRegion->unNumRects++;
pNextRect->oTL.fX = fLeft;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect2->oTL.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
fLeft = pRect2->oBR.fX;
if ( fLeft >= pRect1->oBR.fX )
{
pRect1++;
if ( pRect1 != pRect1End )
fLeft = pRect1->oTL.fX;
}
else
{
pRect2++;
}
}
else
{
if ( pRect1->oBR.fX > fLeft )
{
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
pRegion->unNumRects++;
pNextRect->oTL.fX = fLeft;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect1->oBR.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
}
pRect1++;
fLeft = pRect1->oTL.fX;
}
}
while ( pRect1 != pRect1End )
{
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
pRegion->unNumRects++;
pNextRect->oTL.fX = fLeft;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = pRect1->oBR.fX;
pNextRect->oBR.fY = fBottom;
pNextRect++;
pRect1++;
if ( pRect1 != pRect1End )
fLeft = pRect1->oTL.fX;
}
return true;
}
static void REGION_SetExtents (TWmfRegion *pRegion)
{
if ( 0 == pRegion->unNumRects )
{
pRegion->oExtents.oTL.fX = 0;
pRegion->oExtents.oTL.fY = 0;
pRegion->oExtents.oBR.fX = 0;
pRegion->oExtents.oBR.fY = 0;
return;
}
TWmfRectF *pExtents = &pRegion->oExtents;
TWmfRectF *pRect = pRegion->pRects;
TWmfRectF *pRectEnd = pRect + pRegion->unNumRects - 1;
// pRect - pRegion,
// , , pRectEnd
// .
pExtents->oTL.fX = pRect->oTL.fX;
pExtents->oTL.fY = pRect->oTL.fY;
pExtents->oBR.fX = pRectEnd->oBR.fX;
pExtents->oBR.fY = pRectEnd->oBR.fY;
while ( pRect <= pRectEnd )
{
if ( pRect->oTL.fX < pExtents->oTL.fX )
pExtents->oTL.fX = pRect->oTL.fX;
if ( pRect->oBR.fX > pExtents->oBR.fX )
pExtents->oBR.fX = pRect->oBR.fX;
pRect++;
}
}
static void REGION_IntersectRegion (TWmfRegion *pNewRegion, TWmfRegion *pRegionA, TWmfRegion *pRegionB)
{
if ( ( !( pRegionA->unNumRects ) ) || ( !( pRegionB->unNumRects ) ) || ( !EXTENTCHECK( &pRegionA->oExtents, &pRegionB->oExtents ) ) )
{
pNewRegion->unNumRects = 0;
}
else
{
REGION_RegionOp( pNewRegion, pRegionA, pRegionB, REGION_IntersectO, 0, 0 );
}
/* Can't alter newReg's extents before we call miRegionOp because
* it might be one of the source regions and miRegionOp depends
* on the extents of those regions being the same. Besides, this
* way there's no checking against rectangles that will be nuked
* due to coalescing, so we have to examine fewer rectangles.
*/
REGION_SetExtents( pNewRegion );
pNewRegion->ushType = ( pNewRegion->unNumRects ? COMPLEXREGION : NULLREGION );
}
static bool REGION_IntersectO (TWmfRegion *pRegion, TWmfRectF *pRect1, TWmfRectF *pRect1End, TWmfRectF *pRect2, TWmfRectF *pRect2End, float fTop, float fBottom)
{
TWmfRectF *pNextRect;
while ( ( pRect1 != pRect1End ) && ( pRect2 != pRect2End ) )
{
float fLeft = (std::max)( pRect1->oTL.fX, pRect2->oTL.fX );
float fRight = (std::min)( pRect1->oBR.fX, pRect2->oBR.fX );
/* If there's any overlap between the two rectangles, add that
* overlap to the new region.
* There's no need to check for subsumption because the only way
* such a need could arise is if some region has two rectangles
* right next to each other. Since that should never happen...
*/
if ( fLeft < fRight )
{
if ( NULL == ( pNextRect = RegionMemChk( pRegion ) ) )
return false;
pRegion->unNumRects++;
pNextRect->oTL.fX = fLeft;
pNextRect->oTL.fY = fTop;
pNextRect->oBR.fX = fRight;
pNextRect->oBR.fY = fBottom;
pNextRect++;
}
/* Need to advance the pointers. Shift the one that extends
* to the right the least, since the other still has a chance to
* overlap with that region's next rectangle, if you see what I mean.
*/
if ( pRect1->oBR.fX < pRect2->oBR.fX )
{
pRect1++;
}
else if ( pRect2->oBR.fX < pRect1->oBR.fX )
{
pRect2++;
}
else
{
pRect1++;
pRect2++;
}
}
return true;
}
static bool Clipping (TWmfRegion *pClip, TWmfRegion *pVis, TWmfRectF *pRect, unsigned short ushFlags)
{
TWmfRegion oRegion;
oRegion.pRects = 0;
if ( pClip->unNumRects == 0 )
{
if ( pClip->pRects )
{
oRegion.pRects = pClip->pRects;
oRegion.unSize = pClip->unSize;
pClip->pRects = 0;
pClip->unSize = 0;
}
}
if ( oRegion.pRects == 0 )
{
oRegion.pRects = (TWmfRectF*)malloc( 8 * sizeof (TWmfRectF) );
oRegion.unSize = 8;
if ( !oRegion.pRects )
return false;
}
WmfSetRectRegion( &oRegion, pRect );
if ( ( pClip->unNumRects == 0 ) && ( ushFlags & CLIP_INTERSECT ) )
{
(*pClip) = oRegion;
return true;
}
/* else if ( ushFlags & CLIP_EXCLUDE) ...
*/
if ( pClip->unNumRects == 0 )
{
if ( pClip->pRects == 0 )
{
pClip->pRects = (TWmfRectF*)malloc( 8 * sizeof (TWmfRectF) );
pClip->unSize = 8;
if ( !pClip->pRects )
return false;
}
WmfSetRectRegion( pClip, NULL );
WmfCombineRegion( pClip, pVis, 0, RGN_COPY );
}
WmfCombineRegion( &oRegion, pClip, &oRegion, (unsigned short)( ( ushFlags & CLIP_EXCLUDE ) ? RGN_DIFF : RGN_AND ) );
(*pClip) = oRegion; /* What about what *was* in clip ?? Check WmfCombineRgn */
return true;
}
#endif /* _WMF_REGION_H */
#ifndef _WMF_TYPES_H_
#define _WMF_TYPES_H_
// freetype
#include <ft2build.h>
#include FT_OUTLINE_H
//#include FT_SIZES_H
//#include FT_GLYPH_H
//#include FT_TRUETYPE_IDS_H
//#include FT_TRUETYPE_TABLES_H
//#include FT_XFREE86_H
//#include FT_ADVANCES_H
#ifndef BYTE
typedef unsigned char BYTE;
#endif
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
#ifdef UShort_2_Short
#undef UShort_2_Short
#endif /* UShort_2_Short */
#define UShort_2_Short(X) (((X) & 0x8000) ? ((short) ((int) (X) - (int) 0x10000)) : ((short) (X)))
#ifdef UShort_2_Long
#undef UShort_2_Long
#endif /* UShort_2_Long */
#define UShort_2_Long(X) (((X) & 0x8000) ? ((int) (X) - (int) 0x10000) : ((int) (X)))
#define POINT_TO_INCH(X) ((double) (X) / (double) 72 )
#define INCH_TO_POINT(X) ((double) (X) * (double) 72 )
#define MM_TO_INCH(X) ((double) (X) / (double) 25.4)
//---------------------------------------------------------------------------------------------------
// Modes for CWmfFile.SetMapMode
//---------------------------------------------------------------------------------------------------
#define MM_TEXT 1
#define MM_LOMETRIC 2
#define MM_HIMETRIC 3
#define MM_LOENGLISH 4
#define MM_HIENGLISH 5
#define MM_TWIPS 6
#define MM_ISOTROPIC 7
#define MM_ANISOTROPIC 8
#define MM_DPI 9
//---------------------------------------------------------------------------------------------------
// Regions
//---------------------------------------------------------------------------------------------------
#define ERROR 0
#define NULLREGION 1
#define SIMPLEREGION 2
#define COMPLEXREGION 3
#define RGN_AND 1
#define RGN_OR 2
#define RGN_XOR 3
#define RGN_DIFF 4
#define RGN_COPY 5
#define CLIP_INTERSECT 0x0001
#define CLIP_EXCLUDE 0x0002
#define CLIP_KEEPRGN 0x0004
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
struct TMemoryInfo
{
unsigned char *pMemory; //
unsigned char *pPointer; //
long lPos; //
long lLength; //
bool bNeedDelete; //
};
#define WMF_NOT_OPEN -1
#define WMF_OPEN_FROM_FILE 0
#define WMF_OPEN_FROM_MEMORY 1
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
enum EWmfWrite
{
wmf_write_WMF = 0,
wmf_write_XML = 1
};
struct TWmfWriteFileInfo
{
FILE *pFile;
EWmfWrite eType;
};
//---------------------------------------------------------------------------------------------------
// Wmf-
//---------------------------------------------------------------------------------------------------
struct TWmfPlaceableMetaHeader
{
unsigned int unKey; // Magic number ( 9AC6CDD7h)
unsigned short ushHandle; // Metafile HANDLE number ( 0)
short shLeft; //
short shTop; //
short shRight; //
short shBottom; //
unsigned short ushInch; // (dpi)
unsigned int unReserved; // Reserved ( 0)
unsigned short ushChecksum; // 20
};
struct TWmfHead
{
unsigned short ushFileType; // (0 = memory, 1 = disk)
unsigned short ushHeaderSize; // ( 9)
unsigned short ushVersion; // Version of Microsoft Windows
unsigned int unFileSize; // Unsigned Short
unsigned short ushNumberOfObjects; //
unsigned int unMaxRecordSize; // (Record)
unsigned short ushNumberOfMembers; // Not Used ( 0)
};
typedef struct _TWmfMetaHeader
{
TWmfPlaceableMetaHeader *pPlaceableMetaHeader;
TWmfHead *pHeader;
FILE *pFileIn;
long lPos;
int nPlaceable;
} TWmfMetaHeader, *TWmfFile;
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
enum EWmfError
{
wmf_error_None = 0, //
wmf_error_NotEnoughMemory = 1, //
wmf_error_BadFile = 2, //
wmf_error_BadFormat = 3, //
wmf_error_EOF = 4, //
wmf_error_DeviceError = 5, //
wmf_error_Internal = 6, //
wmf_error_Assert = 7, //
wmf_error_UserExit = 8, //
wmf_error_UnSupported = 9 //
};
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
//
struct TWmfCoordF
{
float fX;
float fY;
};
//
struct TWmfRectF
{
TWmfCoordF oTL; //
TWmfCoordF oBR; //
};
struct TWmfMapping
{
char *sName;
char *sMapping;
/* I had been hoping to keep FT out of this file, but
* it seems easier just to use the FT encoding defs
* rather than create some kind of wrapper...
*/
FT_Encoding eEncoding;
};
struct TWmfFontMap
{
char *sName; // Wmf font name
char *sNamePS; // Postscript font names
char *sItalic;
char *sBold;
char *sBoldItalic;
};
struct TWmfRGB
{
unsigned char r;
unsigned char g;
unsigned char b;
};
struct TWmfBMP
{
unsigned short ushWidth;
unsigned short ushHeight;
BYTE *pData;
};
struct TWmfPen
{
unsigned short ushStyle;
double dWidth;
double dHeight; // ignored
TWmfRGB oColor;
};
struct TWmfBrush
{
unsigned short ushStyle;
unsigned short ushHatch;
TWmfRGB oColor;
TWmfBMP oBitmap;
};
struct TWmfFont
{
unsigned short ushHeight;
unsigned short ushWidth;
short shEscapement;
short shOrientation;
unsigned short ushWeight;
unsigned char unItalic;
unsigned char unUnderline;
unsigned char unStrikeOut;
unsigned char unCharSet;
unsigned char unOutPrecision;
unsigned char unClipPrecision;
unsigned char unQuality;
unsigned char unPitchAndFamily;
char *sFaceName;
void *pUserData;
};
// Structure containing list of XML attributes
struct TWmfAttributes
{
char *sName;
char **psAttrs;
unsigned long ulCount;
unsigned long ulMax;
unsigned char *sBuffer;
unsigned long ulLength;
unsigned long ulOffset;
};
// Structure containing list of lists of XML attributes
struct TWmfAttributeStore
{
TWmfAttributes *pAttrlist;
unsigned long ulCount;
unsigned long ulMax;
};
struct TWmfRegion;
struct TWmfDC
{
TWmfBrush *pBrush;
TWmfPen *pPen;
TWmfFont *pFont;
TWmfRGB oTextColor;
TWmfRGB oBGColor;
unsigned short ushTextAlign;
unsigned short ushBGMode;
unsigned short ushPolyFillMode;
unsigned short ushCharExtra;
unsigned short ushBreakExtra;
unsigned short ushROPMode;
struct
{
int nX;
int nY;
int nWidth;
int nHeight;
} oWindow;
double dPixelWidth; // dpi
double dPixelHeight;
unsigned short ushMapMode;
TWmfRegion *pClip;
};
//---------------------------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------------------------
struct TWmfFlood
{
TWmfDC *pDC;
TWmfCoordF oPoint;
TWmfRGB oColor;
unsigned short ushType;
double dPixelWidth;
double dPixelHeight;
};
struct TWmfDrawPixel
{
TWmfDC *pDC;
TWmfCoordF oPoint;
TWmfRGB oColor;
double dPixelWidth;
double dPixelHeight;
};
struct TWmfDrawArc
{
TWmfDC *pDC;
TWmfCoordF oTL; // ,
TWmfCoordF oBR; //
TWmfCoordF oStart; // ( )
TWmfCoordF oEnd; // ( )
};
struct TWmfDrawLine
{
TWmfDC *pDC;
TWmfCoordF oFrom;
TWmfCoordF oTo;
};
struct TWmfPolyLine
{
TWmfDC *pDC;
TWmfCoordF *pPoints;
unsigned short ushCount;
};
struct TWmfPolyPoly
{
TWmfDC *pDC;
TWmfCoordF **ppPoints; // ppPoints[i][*] - i-
unsigned short *pCount; // i-
unsigned short ushPolyCount; //
};
struct TWmfDrawRectangle
{
TWmfDC *pDC;
TWmfCoordF oTL;
TWmfCoordF oBR;
float fWidth; // (0, )
float fHeight; //
};
struct TWmfPolyRectangle
{
TWmfDC *pDC;
TWmfCoordF *pTL;
TWmfCoordF *pBR;
unsigned int unCount;
float fWidth;
float fHeight;
};
struct TWmfBMPRead
{
long lOffset;
long lLength;
unsigned char *pBuffer;
unsigned short ushWidth;
unsigned short ushHeight;
TWmfBMP oBitmap;
};
struct TWmfBMPDraw
{
TWmfDC *pDC;
TWmfCoordF oPoint;
TWmfBMP oBitmap;
unsigned int unType;
struct
{
unsigned short ushX;
unsigned short ushY;
unsigned short ushW;
unsigned short ushH;
} oCrop;
double dPixelWidth;
double dPixelHeight;
};
struct TWmfROPDraw
{
TWmfDC *pDC;
TWmfCoordF oTL;
TWmfCoordF oBR;
unsigned int unROP;
double dPixelWidth;
double dPixelHeight;
};
struct TWmfDrawText
{
TWmfDC *pDC;
TWmfCoordF oPoint; // ( TextAlign)
TWmfCoordF oOrigin; //
bool bUseDx;
TWmfCoordF oTL; // Clip
TWmfCoordF oBR; //
struct
{
TWmfCoordF oTL;
TWmfCoordF oTR;
TWmfCoordF oBL;
TWmfCoordF oBR;
} oBBox;
char *sText;
unsigned short ushFlags;
double dFontHeight;
double dFontRatio; //
};
struct TWmfUserData
{
TWmfDC *pDC;
void *pData;
};
struct TWmfFunctionReference
{
void (*Device_Open )();
void (*Device_Close)();
void (*Device_Begin)();
void (*Device_End )();
void (*Flood_Interior) (TWmfFlood*);
void (*Flood_Exterior) (TWmfFlood*);
void (*Draw_Pixel ) (TWmfDrawPixel*);
void (*Draw_Pie ) (TWmfDrawArc*);
void (*Draw_Chord ) (TWmfDrawArc*);
void (*Draw_Arc ) (TWmfDrawArc*);
void (*Draw_Ellipse ) (TWmfDrawArc*);
void (*Draw_Line ) (TWmfDrawLine*);
void (*Poly_Line ) (TWmfPolyLine*);
void (*Draw_Polygon ) (TWmfPolyLine*);
void (*Draw_Polypolygon) (TWmfPolyPoly*);
void (*Draw_Rectangle ) (TWmfDrawRectangle*);
void (*Rop_Draw) (TWmfROPDraw*);
void (*Bmp_Draw) (TWmfBMPDraw*);
void (*Bmp_Read) (TWmfBMPRead*);
void (*Bmp_Free) (TWmfBMP*);
void (*Draw_Text) (TWmfDrawText*);
void (*UserData_Init) (TWmfUserData*);
void (*UserData_Copy) (TWmfUserData*);
void (*UserData_Set ) (TWmfUserData*);
void (*UserData_Free) (TWmfUserData*);
void (*Region_Frame) (TWmfPolyRectangle*);
void (*Region_Paint) (TWmfPolyRectangle*);
void (*Region_Clip ) (TWmfPolyRectangle*);
};
//---------------------------------------------------------------------------------------------------
// Player
//---------------------------------------------------------------------------------------------------
#define PLAYER_SCANNED (1 << 0)
#define PLAYER_PLAY (1 << 1)
#define PLAYER_TLBR_D_SET (1 << 2)
struct TWmfCoord
{
unsigned int unX;
unsigned int unY;
};
struct TWmfRegion
{
unsigned int unSize;
unsigned int unNumRects;
unsigned short ushType; // NULL, SIMPLE, COMPLEX
TWmfRectF *pRects;
TWmfRectF oExtents;
};
struct TWmfObject
{
int nType;
union
{
TWmfBrush oBrush;
TWmfPen oPen;
TWmfFont oFont;
int nPalette;
TWmfRegion oRegion;
} uObject;
};
struct TWmfPlayer
{
TWmfPen oDefaultPen;
TWmfBrush oDefaultBrush;
TWmfFont oDefaultFont;
TWmfDC *pDC; // DC
int nDCStackMaxLen;
int nDCStackLength;
TWmfDC **ppDCStack;
TWmfObject *pObjects;
TWmfRegion oVisible; /* I don't understand this... what is the purpose of `visible'? */
TWmfCoord oCurrent; /* Current position */
TWmfCoordF oDisplayTL; /* Bounding box from Display perspective */
TWmfCoordF oDisplayBR;
TWmfCoordF oBoundTL;
TWmfCoordF oBoundBR;
TWmfCoordF oViewportOrigin; /* Origin of Viewport */
unsigned int unViewportWidth; /* Display extents */
unsigned int unViewportHeight;
unsigned char *pParameters; /* meta file parameter values */
unsigned long ulFlags;
struct
{
int nX;
int nY;
int nWidth;
int nHeight;
} oWindow;
};
struct TWmfRecord
{
unsigned long ulSize;
unsigned int unFunction;
unsigned char *sParameter;
long lPosition;
};
//---------------------------------------------------------------------------------------------------
// Device Indepent Bitmap
//---------------------------------------------------------------------------------------------------
enum EWmfBitCount
{
BI_BITCOUNT_0 = 0x0000,
BI_BITCOUNT_1 = 0x0001,
BI_BITCOUNT_2 = 0x0004,
BI_BITCOUNT_3 = 0x0008,
BI_BITCOUNT_4 = 0x0010,
BI_BITCOUNT_5 = 0x0018,
BI_BITCOUNT_6 = 0x0020
};
//--------------------------------------------------------------------------------------------------
// From wingdi.h
//--------------------------------------------------------------------------------------------------
/* PolyFill() Modes */
#define ALTERNATE 1
#define WINDING 2
#define POLYFILL_LAST 2
/* Background Modes */
#define TRANSPARENT 1
#define OPAQUE 2
#define BKMODE_LAST 2
/* Brush Styles */
#define BS_SOLID 0
#define BS_NULL 1
#define BS_HOLLOW BS_NULL
#define BS_HATCHED 2
#define BS_PATTERN 3
#define BS_INDEXED 4
#define BS_DIBPATTERN 5
#define BS_DIBPATTERNPT 6
#define BS_PATTERN8X8 7
#define BS_DIBPATTERN8X8 8
#define BS_MONOPATTERN 9
/* Hatch Styles */
#define HS_HORIZONTAL 0 /* ----- */
#define HS_VERTICAL 1 /* ||||| */
#define HS_FDIAGONAL 2 /* \\\\\ */
#define HS_BDIAGONAL 3 /* ///// */
#define HS_CROSS 4 /* +++++ */
#define HS_DIAGCROSS 5 /* xxxxx */
/* Pen Styles */
#define PS_SOLID 0
#define PS_DASH 1 /* ------- */
#define PS_DOT 2 /* ....... */
#define PS_DASHDOT 3 /* _._._._ */
#define PS_DASHDOTDOT 4 /* _.._.._ */
#define PS_NULL 5
#define PS_INSIDEFRAME 6
#define PS_USERSTYLE 7
#define PS_ALTERNATE 8
#define PS_STYLE_MASK 0x0000000F
#define PS_ENDCAP_ROUND 0x00000000
#define PS_ENDCAP_SQUARE 0x00000100
#define PS_ENDCAP_FLAT 0x00000200
#define PS_ENDCAP_MASK 0x00000F00
#define PS_JOIN_ROUND 0x00000000
#define PS_JOIN_BEVEL 0x00001000
#define PS_JOIN_MITER 0x00002000
#define PS_JOIN_MASK 0x0000F000
#define PS_COSMETIC 0x00000000
#define PS_GEOMETRIC 0x00010000
#define PS_TYPE_MASK 0x000F0000
/* Text Alignment Options */
#define TA_NOUPDATECP 0
#define TA_UPDATECP 1
#define TA_LEFT 0
#define TA_RIGHT 2
#define TA_CENTER 6
#define TA_TOP 0
#define TA_BOTTOM 8
#define TA_BASELINE 24
/* Binary raster ops */
#define R2_BLACK 1 /* 0 */
#define R2_NOTMERGEPEN 2 /* DPon */
#define R2_MASKNOTPEN 3 /* DPna */
#define R2_NOTCOPYPEN 4 /* PN */
#define R2_MASKPENNOT 5 /* PDna */
#define R2_NOT 6 /* Dn */
#define R2_XORPEN 7 /* DPx */
#define R2_NOTMASKPEN 8 /* DPan */
#define R2_MASKPEN 9 /* DPa */
#define R2_NOTXORPEN 10 /* DPxn */
#define R2_NOP 11 /* D */
#define R2_MERGENOTPEN 12 /* DPno */
#define R2_COPYPEN 13 /* P */
#define R2_MERGEPENNOT 14 /* PDno */
#define R2_MERGEPEN 15 /* DPo */
#define R2_WHITE 16 /* 1 */
#define R2_LAST 16
/* Ternary raster operations */
#define SRCCOPY (DWORD)0x00CC0020 /* dest = source */
#define SRCPAINT (DWORD)0x00EE0086 /* dest = source OR dest */
#define SRCAND (DWORD)0x008800C6 /* dest = source AND dest */
#define SRCINVERT (DWORD)0x00660046 /* dest = source XOR dest */
#define SRCERASE (DWORD)0x00440328 /* dest = source AND (NOT dest ) */
#define NOTSRCCOPY (DWORD)0x00330008 /* dest = (NOT source) */
#define NOTSRCERASE (DWORD)0x001100A6 /* dest = (NOT src) AND (NOT dest) */
#define MERGECOPY (DWORD)0x00C000CA /* dest = (source AND pattern) */
#define MERGEPAINT (DWORD)0x00BB0226 /* dest = (NOT source) OR dest */
#define PATCOPY (DWORD)0x00F00021 /* dest = pattern */
#define PATPAINT (DWORD)0x00FB0A09 /* dest = DPSnoo */
#define PATINVERT (DWORD)0x005A0049 /* dest = pattern XOR dest */
#define DSTINVERT (DWORD)0x00550009 /* dest = (NOT dest) */
#define BLACKNESS (DWORD)0x00000042 /* dest = BLACK */
#define WHITENESS (DWORD)0x00FF0062 /* dest = WHITE */
/* Object Definitions for EnumObjects() */
#define OBJ_PEN 1
#define OBJ_BRUSH 2
#define OBJ_DC 3
#define OBJ_METADC 4
#define OBJ_PAL 5
#define OBJ_FONT 6
#define OBJ_BITMAP 7
#define OBJ_REGION 8
#define OBJ_METAFILE 9
#define OBJ_MEMDC 10
#define OBJ_EXTPEN 11
#define OBJ_ENHMETADC 12
#define OBJ_ENHMETAFILE 13
#define OBJ_COLORSPACE 14
#define ANSI_CHARSET 0
#define DEFAULT_CHARSET 1
#define SYMBOL_CHARSET 2
#define SHIFTJIS_CHARSET 128
#define HANGEUL_CHARSET 129
#define HANGUL_CHARSET 129
#define GB2312_CHARSET 134
#define CHINESEBIG5_CHARSET 136
#define OEM_CHARSET 255
#define JOHAB_CHARSET 130
#define HEBREW_CHARSET 177
#define ARABIC_CHARSET 178
#define GREEK_CHARSET 161
#define TURKISH_CHARSET 162
#define VIETNAMESE_CHARSET 163
#define THAI_CHARSET 222
#define EASTEUROPE_CHARSET 238
#define RUSSIAN_CHARSET 204
#define MAC_CHARSET 77
#define BALTIC_CHARSET 186
/* constants for the biCompression field */
#define BI_RGB 0L
#define BI_RLE8 1L
#define BI_RLE4 2L
#define BI_BITFIELDS 3L
#define BI_JPEG 4L
#define BI_PNG 5L
/* Metafile Functions */
#define META_SETBKCOLOR 0x0201
#define META_SETBKMODE 0x0102
#define META_SETMAPMODE 0x0103
#define META_SETROP2 0x0104
#define META_SETRELABS 0x0105
#define META_SETPOLYFILLMODE 0x0106
#define META_SETSTRETCHBLTMODE 0x0107
#define META_SETTEXTCHAREXTRA 0x0108
#define META_SETTEXTCOLOR 0x0209
#define META_SETTEXTJUSTIFICATION 0x020A
#define META_SETWINDOWORG 0x020B
#define META_SETWINDOWEXT 0x020C
#define META_SETVIEWPORTORG 0x020D
#define META_SETVIEWPORTEXT 0x020E
#define META_OFFSETWINDOWORG 0x020F
#define META_SCALEWINDOWEXT 0x0410
#define META_OFFSETVIEWPORTORG 0x0211
#define META_SCALEVIEWPORTEXT 0x0412
#define META_LINETO 0x0213
#define META_MOVETO 0x0214
#define META_EXCLUDECLIPRECT 0x0415
#define META_INTERSECTCLIPRECT 0x0416
#define META_ARC 0x0817
#define META_ELLIPSE 0x0418
#define META_FLOODFILL 0x0419
#define META_PIE 0x081A
#define META_RECTANGLE 0x041B
#define META_ROUNDRECT 0x061C
#define META_PATBLT 0x061D
#define META_SAVEDC 0x001E
#define META_SETPIXEL 0x041F
#define META_OFFSETCLIPRGN 0x0220
#define META_TEXTOUT 0x0521
#define META_BITBLT 0x0922
#define META_STRETCHBLT 0x0B23
#define META_POLYGON 0x0324
#define META_POLYLINE 0x0325
#define META_ESCAPE 0x0626
#define META_RESTOREDC 0x0127
#define META_FILLREGION 0x0228
#define META_FRAMEREGION 0x0429
#define META_INVERTREGION 0x012A
#define META_PAINTREGION 0x012B
#define META_SELECTCLIPREGION 0x012C
#define META_SELECTOBJECT 0x012D
#define META_SETTEXTALIGN 0x012E
#define META_CHORD 0x0830
#define META_SETMAPPERFLAGS 0x0231
#define META_EXTTEXTOUT 0x0a32
#define META_SETDIBTODEV 0x0d33
#define META_SELECTPALETTE 0x0234
#define META_REALIZEPALETTE 0x0035
#define META_ANIMATEPALETTE 0x0436
#define META_SETPALENTRIES 0x0037
#define META_POLYPOLYGON 0x0538
#define META_RESIZEPALETTE 0x0139
#define META_DIBBITBLT 0x0940
#define META_DIBSTRETCHBLT 0x0b41
#define META_DIBCREATEPATTERNBRUSH 0x0142
#define META_STRETCHDIB 0x0f43
#define META_EXTFLOODFILL 0x0548
#define META_SETLAYOUT 0x0149
#define META_DELETEOBJECT 0x01f0
#define META_CREATEPALETTE 0x00f7
#define META_CREATEPATTERNBRUSH 0x01F9
#define META_CREATEPENINDIRECT 0x02FA
#define META_CREATEFONTINDIRECT 0x02FB
#define META_CREATEBRUSHINDIRECT 0x02FC
#define META_CREATEREGION 0x06FF
#endif /* _WMF_TYPES_H_ */
\ No newline at end of file
#ifndef _WMF_UTILS_H
#define _WMF_UTILS_H
#include "WmfTypes.h"
#include <stdio.h>
#include <time.h>
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <math.h>
#include "../../../common/File.h"
#define UTF8_TO_U(val) NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)val, strlen(val))
#define U_TO_UTF8(val) NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(val, wcslen(val))
static std::wstring ascii_to_unicode(const char *src)
{
size_t nSize = mbstowcs(0, src, 0);
wchar_t* pBuffer = new wchar_t[nSize];
nSize = mbstowcs(pBuffer, src, nSize);
std::wstring sRes;
if (nSize != (size_t)-1)
sRes = std::wstring(pBuffer, nSize);
delete[] pBuffer;
return sRes;
}
static std::string unicode_to_ascii(const wchar_t *src)
{
size_t nSize = wcstombs(0, src, 0);
char* pBuffer = new char[nSize];
nSize = wcstombs(pBuffer, src, nSize);
std::string sRes;
if (nSize != (size_t)-1)
sRes = std::string(pBuffer, nSize);
delete[] pBuffer;
return sRes;
}
static char *WmfStrDup(const char *sString)
{
if ( NULL == sString )
return NULL;
char *sCopy = (char*)malloc( strlen(sString) + 1 );
if ( NULL == sCopy )
return NULL;
strcpy( sCopy, sString );
return sCopy;
}
static TWmfCoord WmfCoord(unsigned short ushX, unsigned short ushY)
{
TWmfCoord oPoint;
oPoint.unX = UShort_2_Long( ushX );
oPoint.unY = UShort_2_Long( ushY );
return oPoint;
}
static void PolyPoly_To_PolyLine(TWmfPolyPoly *pPolyPoly, TWmfPolyLine *pPolyLine, unsigned short ushPolyIndex)
{
unsigned short ushCount = pPolyPoly->pCount[ushPolyIndex];
if ( NULL == pPolyPoly->ppPoints )
return;
if ( ( NULL == pPolyPoly->ppPoints[ushPolyIndex] ) || ( pPolyPoly->pCount[ushPolyIndex] < 3 ) )
return;
// Избавляемся от лишних точек
while ( ( pPolyPoly->ppPoints[ushPolyIndex][0].fX == pPolyPoly->ppPoints[ushPolyIndex][ushCount - 1].fX ) && ( pPolyPoly->ppPoints[ushPolyIndex][0].fY == pPolyPoly->ppPoints[ushPolyIndex][ushCount - 1].fY ) )
{
ushCount--;
if ( ushCount < 3 )
break;
}
if ( ushCount < 3 )
return;
// Определяем последний ли полигон
bool bLast = false;
if ( ushPolyIndex < ( pPolyPoly->ushPolyCount - 1 ) )
{
if ( ( NULL == pPolyPoly->ppPoints[ushPolyIndex + 1] == 0 ) || ( pPolyPoly->pCount[ushPolyIndex + 1] < 3 ) )
{
bLast = 1;
}
}
else
{
bLast = 1;
}
if ( bLast )
{
for ( unsigned short ushPointIndex = 0; ushPointIndex < ushCount; ushPointIndex++ )
{
pPolyLine->pPoints[pPolyLine->ushCount].fX = pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fX;
pPolyLine->pPoints[pPolyLine->ushCount].fY = pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fY;
pPolyLine->ushCount++;
}
pPolyLine->pPoints[pPolyLine->ushCount].fX = pPolyPoly->ppPoints[ushPolyIndex][0].fX;
pPolyLine->pPoints[pPolyLine->ushCount].fY = pPolyPoly->ppPoints[ushPolyIndex][0].fY;
pPolyLine->ushCount++;
return;
}
// Ищем в данном полигоне точку ближающую к нулевой точке следующего полигона (т.к. этот полигон не последний, то все впорядке)
unsigned short ushMinIndex = 0;
double dMinR2;
for ( unsigned short ushPointIndex = 0; ushPointIndex < ushCount; ushPointIndex++ )
{
double dX2 = (double) pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fX - (double) pPolyPoly->ppPoints[ushPolyIndex+1][0].fX;
dX2 *= dX2;
double dY2 = (double) pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fY - (double) pPolyPoly->ppPoints[ushPolyIndex+1][0].fY;
dY2 *= dY2;
double dR2 = dX2 + dY2;
if ( 0 == ushPointIndex )
{
dMinR2 = dR2;
}
else if ( dR2 < dMinR2 )
{
dMinR2 = dR2;
ushMinIndex = ushPointIndex;
}
}
for ( unsigned short ushPointIndex = 0; ushPointIndex <= ushMinIndex; ushPointIndex++ )
{
pPolyLine->pPoints[pPolyLine->ushCount].fX = pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fX;
pPolyLine->pPoints[pPolyLine->ushCount].fY = pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fY;
pPolyLine->ushCount++;
}
PolyPoly_To_PolyLine( pPolyPoly, pPolyLine, (unsigned short)(ushPolyIndex + 1) );
for ( unsigned short ushPointIndex = ushMinIndex; ushPointIndex < ushCount; ushPointIndex++ )
{
pPolyLine->pPoints[pPolyLine->ushCount].fX = pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fX;
pPolyLine->pPoints[pPolyLine->ushCount].fY = pPolyPoly->ppPoints[ushPolyIndex][ushPointIndex].fY;
pPolyLine->ushCount++;
}
pPolyLine->pPoints[pPolyLine->ushCount].fX = pPolyPoly->ppPoints[ushPolyIndex][0].fX;
pPolyLine->pPoints[pPolyLine->ushCount].fY = pPolyPoly->ppPoints[ushPolyIndex][0].fY;
pPolyLine->ushCount++;
}
static BOOL WmfOpenTempFile(std::wstring *pwsName, FILE **ppFile, wchar_t *wsMode, wchar_t *wsExt, wchar_t *wsFolder)
{
std::wstring wsTemp, wsFileName;
FILE *pTempFile;
#ifdef _WIN32
wchar_t *wsTempDir;
if ((wsTempDir = _wgetenv(L"TEMP")) && (wsFolder == NULL))
{
wsTemp = std::wstring(wsTempDir);
#else
char *wsTempDirA;
if ( ( wsTempDirA = getenv( "TEMP" ) ) && ( wsFolder == NULL ) )
{
std::wstring wsTempDir = UTF8_TO_U( wsTempDirA );
wsTemp = wsTempDir.c_str();
#endif
wsTemp.append(L"/");
}
else if (wsFolder != NULL)
{
wsTemp = std::wstring(wsFolder);
wsTemp.append(L"/");
}
else
{
wsTemp = L"";
}
wsTemp.append(L"x");
int nTime = (int)time(NULL);
for (int nIndex = 0; nIndex < 1000; ++nIndex)
{
wsFileName = wsTemp;
wsFileName.append(std::to_wstring(nTime + nIndex));
if (wsExt)
{
wsFileName.append(wsExt);
}
#ifdef _WIN32
if (!(pTempFile = _wfopen(wsFileName.c_str(), L"r")))
{
if (!(pTempFile = _wfopen(wsFileName.c_str(), wsMode)))
#else
std::string sFileName = U_TO_UTF8(wsFileName);
if ( !( pTempFile = fopen( sFileName.c_str(), "r" ) ) )
{
std::string sMode = U_TO_UTF8(wsMode);
if ( !( pTempFile = fopen( sFileName.c_str(), sMode.c_str() ) ) )
#endif
{
return FALSE;
}
*pwsName = wsFileName;
*ppFile = pTempFile;
return TRUE;
}
fclose(pTempFile);
}
return FALSE;
}
#endif /* _WMF_UTILS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment