Commit 320dce8d authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Исправлены баги при отрисовке текста. Исправлены баги с обновлением...

Исправлены баги при отрисовке текста. Исправлены баги с обновлением DeviceContext в WMF. Добавлена обработка CharSet в wmf.

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62364 954022d7-b5bf-4e40-9824-e11837661b57
parent eb320f77
......@@ -110,7 +110,6 @@ namespace MetaFile
oFrame.OpenFile(wsTempFileName);
// TODO: .
//::_wunlink(wsTempFileName.c_str());
NSFile::CFileBinary::Remove(wsTempFileName);
return false;
}
......@@ -122,10 +121,10 @@ namespace MetaFile
//
int lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
if (lCalcLen > lBufLen)
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
......@@ -239,10 +238,10 @@ namespace MetaFile
}
int nScanLineBytes = (nWidth + nAdd) / 2;
if (lBufLen < (nScanLineBytes * nHeight))
if (lBufLen < (nScanLineBytes * abs(nHeight)))
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
......@@ -349,10 +348,10 @@ namespace MetaFile
nAdd++;
}
if (lBufLen < (nWidth + nAdd) * nHeight)
if (lBufLen < (nWidth + nAdd) * abs(nHeight))
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
......@@ -445,7 +444,7 @@ namespace MetaFile
nAdd++;
}
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
......@@ -522,7 +521,7 @@ namespace MetaFile
int nSize = nWidth * nHeight * 4;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
pBgraBuffer = new BYTE[nWidth * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
......@@ -615,7 +614,7 @@ namespace MetaFile
int nSize = nWidth * nHeight * 4;
pBgraBuffer = new BYTE[(nWidth + nAdd) * nHeight * 4 * sizeof(BYTE)];
pBgraBuffer = new BYTE[(nWidth + nAdd) * abs(nHeight) * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
......@@ -732,6 +731,49 @@ namespace MetaFile
else // BitmapInfoHeader
ReadImageInfoHeader(pHeaderBuffer + 4, ulHeaderBufferLen - 4, pImageBuffer, ulImageBufferLen, ppDstBuffer, pulWidth, pulHeight);
}
void ReadImage(BYTE* pImageBuffer, unsigned int unBufferLen, unsigned int unColorUsage, BYTE** ppDstBuffer, unsigned int* punWidth, unsigned int* punHeight)
{
if (unBufferLen <= 0 || NULL == pImageBuffer)
return;
CDataStream oHeaderStream;
oHeaderStream.SetStream(pImageBuffer, unBufferLen);
//
unsigned int unHeaderSize;
oHeaderStream >> unHeaderSize;
if (unHeaderSize > unBufferLen)
return;
else if (unHeaderSize < 0x0000000C)
return;
else if (0x0000000C == unHeaderSize) // BitmapCoreHeader
ReadImageCoreHeader(pImageBuffer + 4, unHeaderSize - 4, pImageBuffer + unHeaderSize, unBufferLen - unHeaderSize, ppDstBuffer, punWidth, punHeight);
else // BitmapInfoHeader
{
unsigned short ushBitCount;
unsigned int unColorUsed;
oHeaderStream.Skip(10);
oHeaderStream >> ushBitCount;
oHeaderStream.Skip(16);
oHeaderStream >> unColorUsed;
if (DIB_RGB_COLORS == unColorUsage)
{
if (0 == unColorUsed && BI_BITCOUNT_1 == ushBitCount)
unColorUsed = 2;
else if (0 == unColorUsed && BI_BITCOUNT_3 == ushBitCount)
unColorUsed = 256;
unHeaderSize += 4 * unColorUsed; // RGBQuad
ReadImageInfoHeader(pImageBuffer + 4, unHeaderSize - 4, pImageBuffer + unHeaderSize, unBufferLen - unHeaderSize, ppDstBuffer, punWidth, punHeight);
}
else
{
// TODO:
}
}
}
double GetEllipseAngle(int nL, int nT, int nR, int nB, int nX, int nY)
{
double dX0 = (nL + nR) / 2.0;
......@@ -742,16 +784,16 @@ namespace MetaFile
if (nX >= dX0)
{
if (nY <= dY0)
nQuarter = 0;
else
nQuarter = 3;
else
nQuarter = 0;
}
else
{
if (nY <= dY0)
nQuarter = 1;
else
nQuarter = 2;
else
nQuarter = 1;
}
double dDist = sqrt((double)(nX - dX0) * (nX - dX0) + (nY - dY0) * (nY - dY0));
......@@ -767,4 +809,37 @@ namespace MetaFile
return dAngle;
}
void ProcessRasterOperation(unsigned int unRasterOperation, BYTE** ppBgra, unsigned int unWidth, unsigned int unHeight)
{
BYTE* pBgra = *ppBgra;
// SRCPAINT SRCAND , .
if (0x008800C6 == unRasterOperation) // SRCPAINT
{
BYTE* pCur = pBgra;
for (unsigned int unY = 0; unY < unHeight; unY++)
{
for (unsigned int unX = 0; unX < unWidth; unX++)
{
unsigned int unIndex = (unY * unWidth + unX) * 4;
if (0xff == pCur[unIndex + 0] && 0xff == pCur[unIndex + 1] && 0xff == pCur[unIndex + 2])
pCur[unIndex + 3] = 0;
}
}
}
else if (0x00EE0086 == unRasterOperation) // SRCAND
{
BYTE* pCur = pBgra;
for (unsigned int unY = 0; unY < unHeight; unY++)
{
for (unsigned int unX = 0; unX < unWidth; unX++)
{
unsigned int unIndex = (unY * unWidth + unX) * 4;
if (0 == pCur[unIndex + 0] && 0 == pCur[unIndex + 1] && 0 == pCur[unIndex + 2])
pCur[unIndex + 3] = 0;
}
}
}
}
}
......@@ -47,6 +47,10 @@ namespace MetaFile
pCur = pBuf;
pEnd = pBuf + unSize + 1;
};
BYTE* GetCurPtr()
{
return pCur;
}
unsigned char ReadUChar()
{
......@@ -770,6 +774,81 @@ namespace MetaFile
return *this;
}
CDataStream& operator>>(TWmfStretchBlt& oBitmap)
{
*this >> oBitmap.RasterOperation;
*this >> oBitmap.SrcHeight;
*this >> oBitmap.SrcWidth;
*this >> oBitmap.YSrc;
*this >> oBitmap.XSrc;
*this >> oBitmap.DestHeight;
*this >> oBitmap.DestWidth;
*this >> oBitmap.YDest;
*this >> oBitmap.XDest;
return *this;
}
CDataStream& operator>>(TWmfBitmap16& oBitmap)
{
*this >> oBitmap.Type;
*this >> oBitmap.Width;
*this >> oBitmap.Height;
*this >> oBitmap.WidthBytes;
*this >> oBitmap.Planes;
*this >> oBitmap.BitsPixel;
unsigned int unBitsCount = (((oBitmap.Width * oBitmap.BitsPixel + 15) >> 4) << 1) * oBitmap.Height;
if (CanRead() >= unBitsCount)
{
//oBitmap.Bits = new unsigned char[unBitsCount];
}
else
{
oBitmap.Bits = NULL;
oBitmap.Width = 0;
oBitmap.Height = 0;
}
return *this;
}
CDataStream& operator>>(TWmfBitBlt& oBitmap)
{
*this >> oBitmap.RasterOperation;
*this >> oBitmap.YSrc;
*this >> oBitmap.XSrc;
*this >> oBitmap.Height;
*this >> oBitmap.Width;
*this >> oBitmap.YDest;
*this >> oBitmap.XDest;
return *this;
}
CDataStream& operator>>(TWmfSetDibToDev& oBitmap)
{
*this >> oBitmap.ColorUsage;
*this >> oBitmap.ScanCount;
*this >> oBitmap.StartScan;
*this >> oBitmap.yDib;
*this >> oBitmap.xDib;
*this >> oBitmap.Height;
*this >> oBitmap.Width;
*this >> oBitmap.yDest;
*this >> oBitmap.xDest;
return *this;
}
CDataStream& operator>>(TWmfStretchDib& oBitmap)
{
*this >> oBitmap.RasterOperation;
*this >> oBitmap.ColorUsage;
*this >> oBitmap.SrcHeight;
*this >> oBitmap.SrcWidth;
*this >> oBitmap.YSrc;
*this >> oBitmap.XSrc;
*this >> oBitmap.DestHeight;
*this >> oBitmap.DestWidth;
*this >> oBitmap.yDst;
*this >> oBitmap.xDst;
return *this;
}
bool IsValid() const
{
......@@ -859,7 +938,9 @@ namespace MetaFile
};
void ReadImage(BYTE* pHeaderBuffer, unsigned int ulHeaderBufferLen, BYTE* pImageBuffer, unsigned int ulImageBufferLen, BYTE** ppDstBuffer, unsigned int* pulWidth, unsigned int* pulHeight);
void ReadImage(BYTE* pImageBuffer, unsigned int unBufferLen, unsigned int unColorUsage, BYTE** ppDstBuffer, unsigned int* punWidth, unsigned int* punHeight);
double GetEllipseAngle(int nL, int nT, int nR, int nB, int nX, int nY);
void ProcessRasterOperation(unsigned int unRasterOperation, BYTE** ppBgra, unsigned int unWidth, unsigned int unHeight);
};
#endif //_METAFILE_WMF_EMF_COMMON_H
......@@ -61,6 +61,7 @@ namespace MetaFile
oFile.ReadFile(m_pBufferData, lFileSize, lReadedSize);
m_oStream.SetStream(m_pBufferData, lFileSize);
oFile.CloseFile();
return true;
}
......@@ -80,7 +81,7 @@ namespace MetaFile
PlayMetaFile();
m_pOutput = pOutput;
ClearFile();
this->ClearFile();
}
CFontManager* GetFontManager()
{
......
......@@ -16,6 +16,7 @@ namespace MetaFile
virtual bool IsStrikeOut() = 0;
virtual bool IsUnderline() = 0;
virtual int GetEscapement() = 0;
virtual int GetCharSet() = 0;
};
class IBrush
......
......@@ -119,11 +119,6 @@ namespace MetaFile
m_pRenderer->put_FontStyle(lStyle);
//
m_pRenderer->put_BrushType(c_BrushTypeSolid);
m_pRenderer->put_BrushColor1(m_pFile->GetTextColor());
m_pRenderer->put_BrushAlpha1(255);
double dTheta = -((((double)pFont->GetEscapement()) / 10) * M_PI / 180);
double dCosTheta = (float)cos(dTheta);
......@@ -154,19 +149,6 @@ namespace MetaFile
if (bWithOutLast)
wsTempText.erase(ulCharsCount - 1);
//wchar_t* wsTempText = new wchar_t[ulCharsCount + 1];
//if (!wsTempText)
// return;
//wsTempText[ulCharsCount] = 0x0000;
//for (unsigned int unIndex = 0; unIndex < ulCharsCount; unIndex++)
//{
// wsTempText[unIndex] = wsText[unIndex];
//}
//if (bWithOutLast)
// wsTempText[ulCharsCount - 1] = 0x0000;
pFontManager->LoadString1(wsTempText, 0, 0);
TBBox oBox = pFontManager->MeasureString2();
......@@ -186,8 +168,6 @@ namespace MetaFile
m_pRenderer->put_FontCharSpace(dCharSpace * 25.4 / 72);
}
/*delete[] wsTempText;*/
pFontManager->LoadString1(wsText, 0, 0);
oBox = pFontManager->MeasureString2();
fL = (float)dMmToPt * (oBox.fMinX);
......@@ -278,8 +258,8 @@ namespace MetaFile
if (OPAQUE == m_pFile->GetTextBgMode())
{
m_pRenderer->put_BrushType(c_BrushTypeSolid);
m_pRenderer->put_BrushColor1(255);
m_pRenderer->put_BrushAlpha1(m_pFile->GetTextBgColor());
m_pRenderer->put_BrushAlpha1(255);
m_pRenderer->put_BrushColor1(m_pFile->GetTextBgColor());
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandStart();
......@@ -290,7 +270,7 @@ namespace MetaFile
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath(c_nWindingFillMode);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->PathCommandStart();
m_pRenderer->PathCommandEnd();
}
//
......@@ -309,6 +289,11 @@ namespace MetaFile
m_pRenderer->PathCommandEnd();
}
//
m_pRenderer->put_BrushType(c_BrushTypeSolid);
m_pRenderer->put_BrushColor1(m_pFile->GetTextColor());
m_pRenderer->put_BrushAlpha1(255);
//
m_pRenderer->CommandDrawText(wsText, dX, dY, 0, 0, 0);
......
......@@ -656,39 +656,12 @@ namespace MetaFile
if (ReadImage(oBitmap.offBmiSrc, oBitmap.cbBmiSrc, oBitmap.offBitsSrc, oBitmap.cbBitsSrc, sizeof(TEmfStretchDIBITS) + 8, &pBgraBuffer, &ulWidth, &ulHeight))
{
// SRCPAINT SRCAND , .
if (0x008800C6 == oBitmap.BitBltRasterOperation) // SRCPAINT
{
BYTE* pCur = pBgraBuffer;
for (unsigned int unY = 0; unY < ulHeight; unY++)
{
for (unsigned int unX = 0; unX < ulWidth; unX++)
{
unsigned int unIndex = (unY * ulWidth + unX) * 4;
if (0xff == pCur[unIndex + 0] && 0xff == pCur[unIndex + 1] && 0xff == pCur[unIndex + 2])
pCur[unIndex + 3] = 0;
}
}
}
else if (0x00EE0086 == oBitmap.BitBltRasterOperation) // SRCAND
{
BYTE* pCur = pBgraBuffer;
for (unsigned int unY = 0; unY < ulHeight; unY++)
{
for (unsigned int unX = 0; unX < ulWidth; unX++)
{
unsigned int unIndex = (unY * ulWidth + unX) * 4;
if (0 == pCur[unIndex + 0] && 0 == pCur[unIndex + 1] && 0 == pCur[unIndex + 2])
pCur[unIndex + 3] = 0;
}
}
}
if (m_pOutput)
{
ProcessRasterOperation(oBitmap.BitBltRasterOperation, &pBgraBuffer, ulWidth, ulHeight);
m_pOutput->DrawBitmap(oBitmap.xDest, oBitmap.yDest, oBitmap.cxDest, oBitmap.cyDest, pBgraBuffer, ulWidth, ulHeight);
}
}
if (pBgraBuffer)
delete[] pBgraBuffer;
......
......@@ -118,6 +118,10 @@ namespace MetaFile
{
return LogFontEx.LogFont.Escapement;
}
int GetCharSet()
{
return LogFontEx.LogFont.CharSet;
}
public:
......
......@@ -35,6 +35,19 @@ namespace MetaFile
}
bool CMetaFile::LoadFromFile(const wchar_t *wsFilePath)
{
// TODO:
// FontManager, .
//------------------------------------------------------
RELEASEINTERFACE(m_pFontManager);
m_pFontManager = m_pAppFonts->GenerateFontManager();
CFontsCache* pMeasurerCache = new CFontsCache();
pMeasurerCache->SetStreams(m_pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
m_oWmfFile.SetFontManager(m_pFontManager);
m_oEmfFile.SetFontManager(m_pFontManager);
//------------------------------------------------------
// Wmf
m_oWmfFile.OpenFromFile(wsFilePath);
......@@ -184,11 +197,9 @@ namespace MetaFile
CFontsCache* pFontCache = new CFontsCache();
pFontCache->SetStreams(m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache);
CImageFilesCache oCache;
CGraphicsRenderer oRenderer;
oRenderer.SetFontManager(pFontManager);
oRenderer.SetImageCache(&oCache);
if (-1 == nHeight)
{
......
......@@ -158,11 +158,9 @@
<ClInclude Include="Emf\EmfClip.h" />
<ClInclude Include="Emf\EmfFile.h" />
<ClInclude Include="Emf\EmfObjects.h" />
<ClInclude Include="Emf\EmfOutputDevice.h" />
<ClInclude Include="Emf\EmfPath.h" />
<ClInclude Include="Emf\EmfPlayer.h" />
<ClInclude Include="Emf\EmfTypes.h" />
<ClInclude Include="Emf\RendererOutput.h" />
<ClInclude Include="MetaFile.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="Wmf\RendererOutput.h" />
......
......@@ -75,15 +75,9 @@
<ClInclude Include="Emf\EmfTypes.h">
<Filter>Emf</Filter>
</ClInclude>
<ClInclude Include="Emf\EmfOutputDevice.h">
<Filter>Emf</Filter>
</ClInclude>
<ClInclude Include="Common.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Emf\RendererOutput.h">
<Filter>Emf</Filter>
</ClInclude>
<ClInclude Include="Emf\EmfPlayer.h">
<Filter>Emf</Filter>
</ClInclude>
......
......@@ -14,6 +14,7 @@
#include "../Common/IOutputDevice.h"
#include <iostream>
#include "../Common/MetaFile.h"
#include "../../../common/String.h"
namespace MetaFile
{
......@@ -85,7 +86,12 @@ namespace MetaFile
//-----------------------------------------------------------
// 2.3.1 Bitmap records
//-----------------------------------------------------------
case META_BITBLT: Read_META_BITBLT(); break;
case META_DIBBITBLT: Read_META_DIBBITBLT(); break;
case META_DIBSTRETCHBLT: Read_META_DIBSTRETCHBLT(); break;
case META_SETDIBTODEV: Read_META_SETDIBTODEV(); break;
case META_STRETCHBLT: Read_META_STRETCHBLT(); break;
case META_STRETCHDIB: Read_META_STRETCHDIB(); break;
//-----------------------------------------------------------
// 2.3.2 Control records
//-----------------------------------------------------------
......@@ -170,7 +176,7 @@ namespace MetaFile
//-----------------------------------------------------------
default:
{
std::cout << ushType << " ";
//std::cout << ushType << " ";
Read_META_UNKNOWN();
break;
}
......@@ -403,8 +409,58 @@ namespace MetaFile
if (m_pOutput)
{
// TODO: В зависимости от CharSet нужно переводить строку в юникод. Пока переводим как Ascii -> Unicode
std::wstring wsText = NSFile::CUtf8Converter::GetUnicodeFromCharPtr((const char*)pString, unCharsCount, 0);
IFont* pFont = GetFont();
NSString::CConverter::ESingleByteEncoding eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT;;
if (pFont)
{
// Соответствие 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
switch (pFont->GetCharSet())
{
default:
case DEFAULT_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break;
case SYMBOL_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_DEFAULT; break;
case ANSI_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1252; break;
case RUSSIAN_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1251; break;
case EASTEUROPE_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1250; break;
case GREEK_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1253; break;
case TURKISH_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1254; break;
case BALTIC_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1257; break;
case HEBREW_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1255; break;
case ARABIC_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1256; break;
case SHIFTJIS_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP932; break;
case HANGEUL_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP949; break;
case 134/*GB2313_CHARSET*/: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP936; break;
case CHINESEBIG5_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP950; break;
case THAI_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP874; break;
case JOHAB_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1361; break;
case VIETNAMESE_CHARSET: eCharSet = NSString::CConverter::ESingleByteEncoding::SINGLE_BYTE_ENCODING_CP1258; break;
}
}
std::wstring wsText = NSString::CConverter::GetUnicodeFromSingleByteString((const unsigned char*)pString, (long)unCharsCount, eCharSet);
m_pOutput->DrawText(wsText, unCharsCount, nX, nY, nTextW, bWithOutLast);
}
else
......@@ -436,6 +492,21 @@ namespace MetaFile
m_oBoundingBox.nBottom = shY;
}
}
bool ReadImage(unsigned short ushColorUsage, BYTE** ppBgraBuffer, unsigned int* pulWidth, unsigned int* pulHeight)
{
unsigned int unRemainBytes = GetRecordRemainingBytesCount();
if (unRemainBytes <= 0)
return false;
BYTE* pBuffer = m_oStream.GetCurPtr();
MetaFile::ReadImage(pBuffer, unRemainBytes, ushColorUsage, ppBgraBuffer, pulWidth, pulHeight);
return true;
}
void UpdateOutputDC()
{
if (m_pOutput)
m_pOutput->UpdateDC();
}
void Read_META_UNKNOWN()
{
......@@ -501,18 +572,220 @@ namespace MetaFile
m_oRect = m_oPlaceable.BoundingBox;
else
m_oRect = m_oBoundingBox;
m_pDC->SetWindowOff(m_oRect.nLeft, m_oRect.nTop);
m_pDC->SetWindowExt(m_oRect.nRight - m_oRect.nLeft, m_oRect.nBottom - m_oRect.nTop);
}
else
{
m_bFirstPoint = true;
}
}
void Read_META_BITBLT()
{
TWmfBitBlt oBitmap;
m_oStream >> oBitmap;
unsigned int unRecordSizeDword = m_unRecordSize >> 1;
unsigned int unValue = (META_BITBLT >> 8) + 3;
if (unRecordSizeDword == unValue)
{
m_oStream.Skip(2); // Reserved
}
else
{
if (m_pOutput)
{
TWmfBitmap16 oBitmap16;
m_oStream >> oBitmap16;
// TODO: Сделать чтение Bitmap16
}
else
{
RegisterPoint(oBitmap.XDest, oBitmap.YDest);
RegisterPoint(oBitmap.XDest + oBitmap.Width, oBitmap.YDest + oBitmap.Height);
}
int nRemainingBytes = GetRecordRemainingBytesCount();
if (nRemainingBytes < 0)
return SetError();
}
}
void Read_META_DIBBITBLT()
{
TWmfBitBlt oBitmap;
m_oStream >> oBitmap;
unsigned int unRecordSizeDword = m_unRecordSize >> 1;
unsigned int unValue = (META_DIBBITBLT >> 8) + 3;
if (unRecordSizeDword == unValue)
{
m_oStream.Skip(2); // Reserved
}
else
{
if (m_pOutput)
{
BYTE* pBgra;
unsigned int unWidth, unHeight;
if (ReadImage(0, &pBgra, &unWidth, &unHeight))
{
m_pOutput->DrawBitmap(oBitmap.XDest, oBitmap.YDest, oBitmap.Width, oBitmap.Height, pBgra, unWidth, unHeight);
}
if (pBgra)
delete[] pBgra;
}
else
{
RegisterPoint(oBitmap.XDest, oBitmap.YDest);
RegisterPoint(oBitmap.XDest + oBitmap.Width, oBitmap.YDest + oBitmap.Height);
}
int nRemainingBytes = GetRecordRemainingBytesCount();
if (nRemainingBytes < 0)
return SetError();
}
}
void Read_META_DIBSTRETCHBLT()
{
TWmfStretchBlt oBitmap;
m_oStream >> oBitmap;
unsigned int unRecordSizeDWORD = m_unRecordSize >> 1;
unsigned int unValue = (META_DIBSTRETCHBLT >> 8) + 3;
if (unRecordSizeDWORD == unValue)
{
m_oStream.Skip(2); // Reserved
}
else
{
if (m_pOutput)
{
BYTE* pBgra;
unsigned int unWidth, unHeight;
if (ReadImage(0, &pBgra, &unWidth, &unHeight))
{
ProcessRasterOperation(oBitmap.RasterOperation, &pBgra, unWidth, unHeight);
m_pOutput->DrawBitmap(oBitmap.XDest, oBitmap.YDest, oBitmap.DestWidth, oBitmap.DestHeight, pBgra, unWidth, unHeight);
}
if (pBgra)
delete[] pBgra;
}
else
{
RegisterPoint(oBitmap.XDest, oBitmap.YDest);
RegisterPoint(oBitmap.XDest + oBitmap.DestWidth, oBitmap.YDest + oBitmap.DestHeight);
}
int nRemainingBytes = GetRecordRemainingBytesCount();
if (nRemainingBytes < 0)
return SetError();
}
}
void Read_META_SETDIBTODEV()
{
TWmfSetDibToDev oBitmap;
m_oStream >> oBitmap;
if (m_pOutput)
{
// TODO: Тут надо делать обрезку в зависимости от ScanCount и StartScan. Как встретится файл сделать.
BYTE* pBgra;
unsigned int unWidth, unHeight;
if (ReadImage(oBitmap.ColorUsage, &pBgra, &unWidth, &unHeight))
{
m_pOutput->DrawBitmap(oBitmap.xDest, oBitmap.yDest, oBitmap.Width, oBitmap.Height, pBgra, unWidth, unHeight);
}
if (pBgra)
delete[] pBgra;
}
else
{
RegisterPoint(oBitmap.xDest, oBitmap.yDest);
RegisterPoint(oBitmap.xDest + oBitmap.Width, oBitmap.yDest + oBitmap.Height);
}
int nRemainingBytes = GetRecordRemainingBytesCount();
if (nRemainingBytes < 0)
return SetError();
}
void Read_META_STRETCHBLT()
{
TWmfStretchBlt oBitmap;
m_oStream >> oBitmap;
unsigned int unRecordSizeDWORD = m_unRecordSize >> 1;
unsigned int unValue = (META_STRETCHBLT >> 8) + 3;
if (unRecordSizeDWORD == ((META_STRETCHBLT >> 8) + 3))
{
m_oStream.Skip(2); // Reserved
}
else
{
if (m_pOutput)
{
TWmfBitmap16 oBitmap16;
m_oStream >> oBitmap16;
// TODO: Сделать чтение Bitmap16
}
else
{
RegisterPoint(oBitmap.XDest, oBitmap.YDest);
RegisterPoint(oBitmap.XDest + oBitmap.DestWidth, oBitmap.YDest + oBitmap.DestHeight);
}
int nRemainingBytes = GetRecordRemainingBytesCount();
if (nRemainingBytes < 0)
return SetError();
}
}
void Read_META_STRETCHDIB()
{
TWmfStretchDib oBitmap;
m_oStream >> oBitmap;
if (m_pOutput)
{
BYTE* pBgra;
unsigned int unWidth, unHeight;
if (ReadImage(oBitmap.ColorUsage, &pBgra, &unWidth, &unHeight))
{
m_pOutput->DrawBitmap(oBitmap.xDst, oBitmap.yDst, oBitmap.DestWidth, oBitmap.DestHeight, pBgra, unWidth, unHeight);
}
if (pBgra)
delete[] pBgra;
}
else
{
RegisterPoint(oBitmap.xDst, oBitmap.yDst);
RegisterPoint(oBitmap.xDst + oBitmap.DestWidth, oBitmap.yDst + oBitmap.DestHeight);
}
int nRemainingBytes = GetRecordRemainingBytesCount();
if (nRemainingBytes < 0)
return SetError();
}
void Read_META_ARC()
{
short shYEndArc, shXEndArc, shYStartArc, shXStartArc, shBottom, shRight, shTop, shLeft;
m_oStream >> shYEndArc >> shXEndArc >> shYStartArc >> shXStartArc >> shBottom >> shRight >> shTop >> shLeft;
double dStartAngle = GetEllipseAngle((int)shLeft, (int)shTop, (int)shRight, (int)shBottom, (int)shXStartArc, (int)shYStartArc);
double dSweepAngle = GetEllipseAngle((int)shLeft, (int)shTop, (int)shRight, (int)shBottom, (int)shXEndArc, (int)shYEndArc) - dStartAngle;
if (dSweepAngle <= 0)
dSweepAngle += 360;
m_pDC->SetCurPos(shXStartArc, shYStartArc);
ArcTo(shLeft, shTop, shRight, shBottom, dStartAngle, dSweepAngle);
DrawPath(true, false);
m_pDC->SetCurPos(shXEndArc, shYEndArc);
......@@ -523,6 +796,10 @@ namespace MetaFile
m_oStream >> shYEndArc >> shXEndArc >> shYStartArc >> shXStartArc >> shBottom >> shRight >> shTop >> shLeft;
double dStartAngle = GetEllipseAngle((int)shLeft, (int)shTop, (int)shRight, (int)shBottom, (int)shXStartArc, (int)shYStartArc);
double dSweepAngle = GetEllipseAngle((int)shLeft, (int)shTop, (int)shRight, (int)shBottom, (int)shXEndArc, (int)shYEndArc) - dStartAngle;
if (dSweepAngle <= 0)
dSweepAngle += 360;
MoveTo(shXStartArc, shYStartArc);
ArcTo(shLeft, shTop, shRight, shBottom, dStartAngle, dSweepAngle);
LineTo(shXStartArc, shYStartArc);
......@@ -535,6 +812,7 @@ namespace MetaFile
m_oStream >> shBottom >> shRight >> shTop >> shLeft;
ArcTo(shLeft, shTop, shRight, shBottom, 0, 360);
DrawPath(true, true);
m_pDC->SetCurPos((shLeft + shRight) / 2, (shTop + shBottom) / 2);
}
void Read_META_EXTTEXTOUT()
{
......@@ -730,6 +1008,8 @@ namespace MetaFile
LineTo(shL, shB);
ClosePath();
DrawPath(true, true);
m_pDC->SetCurPos((shL + shR) / 2, (shT + shB) / 2);
}
void Read_META_ROUNDRECT()
{
......@@ -775,7 +1055,7 @@ namespace MetaFile
if (!pString)
return SetError();
pString[shStringLength + 1] = 0x00;
pString[shStringLength] = 0x00;
m_oStream.ReadBytes(pString, shStringLength);
if (shStringLength & 1)
......@@ -816,12 +1096,19 @@ namespace MetaFile
}
void Read_META_CREATEPATTERNBRUSH()
{
// TODO: Реализовать чтение Bitmap16
CWmfBrush* pBrush = new CWmfBrush();
if (!pBrush)
return SetError();
m_oPlayer.RegisterObject((CWmfObjectBase*)pBrush);
if (m_pOutput)
{
TWmfBitmap16 oBitmap16;
m_oStream >> oBitmap16;
// TODO: Сделать чтение Bitmap16
}
}
void Read_META_CREATEPENINDIRECT()
{
......@@ -845,17 +1132,28 @@ namespace MetaFile
unsigned short ushIndex;
m_oStream >> ushIndex;
m_oPlayer.DeleteObject(ushIndex);
UpdateOutputDC();
}
void Read_META_DIBCREATEPATTERNBRUSH()
{
unsigned short ushStyle, ushColorUsage;
m_oStream >> ushStyle >> ushColorUsage;
//TODO: Организовать чтение картинки
CWmfBrush* pBrush = new CWmfBrush();
if (!pBrush)
return SetError();
if (m_pOutput)
{
BYTE* pBgra = NULL;
unsigned int unWidth, unHeight;
if (ReadImage(ushColorUsage, &pBgra, &unWidth, &unHeight))
{
pBrush->SetDibPattern(pBgra, unWidth, unHeight);
}
}
m_oPlayer.RegisterObject((CWmfObjectBase*)pBrush);
}
void Read_META_SELECTCLIPREGION()
......@@ -864,30 +1162,36 @@ namespace MetaFile
m_oStream >> ushIndex;
// TODO: Реализовать
UpdateOutputDC();
}
void Read_META_SELECTOBJECT()
{
unsigned short ushIndex;
m_oStream >> ushIndex;
m_oPlayer.SelectObject(ushIndex);
UpdateOutputDC();
}
void Read_META_SELECTPALETTE()
{
unsigned short ushIndex;
m_oStream >> ushIndex;
m_oPlayer.SelectPalette(ushIndex);
UpdateOutputDC();
}
void Read_META_EXCLUDECLIPRECT()
{
short shLeft, shTop, shRight, shBottom;
m_oStream >> shBottom >> shRight >> shTop >> shLeft;
// TODO: Реализовать клип
UpdateOutputDC();
}
void Read_META_INTERSECTCLIPRECT()
{
short shLeft, shTop, shRight, shBottom;
m_oStream >> shBottom >> shRight >> shTop >> shLeft;
// TODO: Реализовать клип
UpdateOutputDC();
}
void Read_META_MOVETO()
{
......@@ -900,128 +1204,150 @@ namespace MetaFile
short shOffsetX, shOffsetY;
m_oStream >> shOffsetY >> shOffsetX;
// TODO: Реализовать
UpdateOutputDC();
}
void Read_META_OFFSETVIEWPORTORG()
{
short shXOffset, shYOffset;
m_oStream >> shYOffset >> shXOffset;
m_pDC->SetViewportOff(shXOffset, shYOffset);
UpdateOutputDC();
}
void Read_META_OFFSETWINDOWORG()
{
short shXOffset, shYOffset;
m_oStream >> shYOffset >> shXOffset;
m_pDC->SetWindowOff(shXOffset, shYOffset);
UpdateOutputDC();
}
void Read_META_RESTOREDC()
{
m_pDC = m_oPlayer.RestoreDC();
UpdateOutputDC();
}
void Read_META_SAVEDC()
{
m_pDC = m_oPlayer.SaveDC();
UpdateOutputDC();
}
void Read_META_SCALEVIEWPORTEXT()
{
short yDenom, yNum, xDenom, xNum;
m_oStream >> yDenom >> yNum >> xDenom >> xNum;
m_pDC->SetViewportScale((double)xNum / (double)xDenom, (double)yNum / (double)xDenom);
UpdateOutputDC();
}
void Read_META_SCALEWINDOWEXT()
{
short yDenom, yNum, xDenom, xNum;
m_oStream >> yDenom >> yNum >> xDenom >> xNum;
m_pDC->SetWindowScale((double)xNum / (double)xDenom, (double)yNum / (double)xDenom);
UpdateOutputDC();
}
void Read_META_SETBKCOLOR()
{
TWmfColor oColor;
m_oStream >> oColor;
m_pDC->SetTextBgColor(oColor);
UpdateOutputDC();
}
void Read_META_SETBKMODE()
{
unsigned short ushMode;
m_oStream >> ushMode;
m_pDC->SetTextBgMode(ushMode);
UpdateOutputDC();
}
void Read_META_SETLAYOUT()
{
unsigned short ushLayout, ushReserved;
m_oStream >> ushLayout >> ushReserved;
m_pDC->SetLayout(ushLayout);
UpdateOutputDC();
}
void Read_META_SETMAPMODE()
{
unsigned short ushMapMode;
m_oStream >> ushMapMode;
m_pDC->SetMapMode(ushMapMode);
UpdateOutputDC();
}
void Read_META_SETPOLYFILLMODE()
{
unsigned short ushMode;
m_oStream >> ushMode;
m_pDC->SetPolyFillMode(ushMode);
UpdateOutputDC();
}
void Read_META_SETROP2()
{
unsigned short ushMode;
m_oStream >> ushMode;
m_pDC->SetRop2Mode(ushMode);
UpdateOutputDC();
}
void Read_META_SETSTRETCHBLTMODE()
{
unsigned short ushMode;
m_oStream >> ushMode;
m_pDC->SetStretchBltMode(ushMode);
UpdateOutputDC();
}
void Read_META_SETTEXTALIGN()
{
unsigned short ushTextAlign;
m_oStream >> ushTextAlign;
m_pDC->SetTextAlign(ushTextAlign);
UpdateOutputDC();
}
void Read_META_SETTEXTCHAREXTRA()
{
unsigned short ushCharSpacing;
m_oStream >> ushCharSpacing;
m_pDC->SetCharSpacing(ushCharSpacing);
UpdateOutputDC();
}
void Read_META_SETTEXTCOLOR()
{
TWmfColor oColor;
m_oStream >> oColor;
m_pDC->SetTextColor(oColor);
UpdateOutputDC();
}
void Read_META_SETTEXTJUSTIFICATION()
{
unsigned short ushBreakCount, ushBreakExtra;
m_oStream >> ushBreakCount >> ushBreakExtra;
// TODO: Реализовать
UpdateOutputDC();
}
void Read_META_SETVIEWPORTEXT()
{
short shX, shY;
m_oStream >> shY >> shX;
m_pDC->SetViewportExt(shX, shY);
UpdateOutputDC();
}
void Read_META_SETVIEWPORTORG()
{
short shX, shY;
m_oStream >> shY >> shX;
m_pDC->SetViewportOrg(shX, shY);
UpdateOutputDC();
}
void Read_META_SETWINDOWEXT()
{
short shX, shY;
m_oStream >> shY >> shX;
m_pDC->SetWindowExt(shX, shY);
UpdateOutputDC();
}
void Read_META_SETWINDOWORG()
{
short shX, shY;
m_oStream >> shY >> shX;
m_pDC->SetWindowOrg(shX, shY);
UpdateOutputDC();
}
void Read_META_ESCAPE()
{
......
......@@ -102,6 +102,10 @@ namespace MetaFile
{
return (int)Escapement;
}
int GetCharSet()
{
return (int)CharSet;
}
public:
......
......@@ -149,6 +149,7 @@ namespace MetaFile
{
CWmfObjectBase* pObject = oPos->second;
switch (pObject->GetType())
{
case WMF_OBJECT_BRUSH: m_pDC->SetBrush((CWmfBrush*)pObject); break;
......
......@@ -997,6 +997,63 @@ namespace MetaFile
TWmfColor Color;
unsigned short BurshHatch;
};
struct TWmfBitmap16
{
short Type;
short Width;
short Height;
short WidthBytes;
unsigned char Planes;
unsigned char BitsPixel;
unsigned char* Bits;
};
struct TWmfBitBlt
{
unsigned int RasterOperation;
short YSrc;
short XSrc;
short Height;
short Width;
short YDest;
short XDest;
};
struct TWmfSetDibToDev
{
unsigned short ColorUsage;
unsigned short ScanCount;
unsigned short StartScan;
unsigned short yDib;
unsigned short xDib;
unsigned short Height;
unsigned short Width;
unsigned short yDest;
unsigned short xDest;
};
struct TWmfStretchBlt
{
unsigned int RasterOperation;
short SrcHeight;
short SrcWidth;
short YSrc;
short XSrc;
short DestHeight;
short DestWidth;
short YDest;
short XDest;
};
struct TWmfStretchDib
{
unsigned int RasterOperation;
unsigned short ColorUsage;
short SrcHeight;
short SrcWidth;
short YSrc;
short XSrc;
short DestHeight;
short DestWidth;
short yDst;
short xDst;
};
}
#endif /* _WMF_TYPES_H_ */
\ No newline at end of file
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