Commit 504284e6 authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Реализованы настройки текста, настройки шрифта, полигон, кисть, и один из...

Реализованы настройки текста, настройки шрифта, полигон, кисть, и один из вариантов рисования картинок.

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62023 954022d7-b5bf-4e40-9824-e11837661b57
parent 5d7db3dd
......@@ -18,6 +18,9 @@ typedef unsigned char BYTE;
namespace Metafile
{
#define METAFILE_RGBA(r, g, b) ((DWORD)( ( (BYTE)(r) )| ( ( (BYTE)(g) ) << 8 ) | ( ( (BYTE)(b) ) << 16 ) | ( (BYTE)(0) << 24 ) ) )
class CDataStream
{
public:
......@@ -86,7 +89,7 @@ namespace Metafile
{
return (long)ReadULong();
};
void ReadBytes(BYTE* pBuffer, unsigned long ulSize)
void ReadBytes(unsigned char* pBuffer, unsigned long ulSize)
{
size_t ulRemainSize = (pEnd - pCur);
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
......@@ -96,7 +99,26 @@ namespace Metafile
pBuffer[ulIndex] = ReadChar();
}
};
void ReadBytes(unsigned short* pBuffer, unsigned long ulSize)
{
size_t ulRemainSize = (pEnd - pCur) / 2;
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
for (size_t ulIndex = 0; ulIndex < ulFinalSize; ulIndex++)
{
pBuffer[ulIndex] = ReadUShort();
}
}
void ReadBytes(unsigned long* pBuffer, unsigned long ulSize)
{
size_t ulRemainSize = (pEnd - pCur) / 4;
size_t ulFinalSize = (ulRemainSize > ulSize ? ulSize : ulRemainSize);
for (size_t ulIndex = 0; ulIndex < ulFinalSize; ulIndex++)
{
pBuffer[ulIndex] = ReadULong();
}
}
CDataStream& operator>>(unsigned char& nValue)
{
nValue = ReadUChar();
......@@ -184,6 +206,147 @@ namespace Metafile
return *this;
}
CDataStream& operator>>(TEmfPointL& oPoint)
{
*this >> oPoint.x;
*this >> oPoint.y;
return *this;
}
CDataStream& operator>>(TEmfPointS& oPoint)
{
*this >> oPoint.x;
*this >> oPoint.y;
return *this;
}
CDataStream& operator>>(TEmfEmrText& oText)
{
*this >> oText.Reference;
*this >> oText.Chars;
*this >> oText.offString;
*this >> oText.Options;
*this >> oText.Rectangle;
*this >> oText.offDx;
oText.OutputString = NULL;
oText.OutputDx = NULL;
return *this;
}
CDataStream& operator>>(TEmfExtTextoutW& oText)
{
*this >> oText.Bounds;
*this >> oText.iGraphicsMode;
*this >> oText.exScale;
*this >> oText.eyScale;
*this >> oText.wEmrText;
return *this;
}
CDataStream& operator>>(TEmfLogFont& oFont)
{
*this >> oFont.Height;
*this >> oFont.Width;
*this >> oFont.Escapement;
*this >> oFont.Orientation;
*this >> oFont.Weight;
*this >> oFont.Italic;
*this >> oFont.Underline;
*this >> oFont.StrikOut;
*this >> oFont.CharSet;
*this >> oFont.OutPrecision;
*this >> oFont.ClipPrecision;
*this >> oFont.Quality;
*this >> oFont.PitchAndFamily;
ReadBytes(oFont.FaceName, 32);
return *this;
}
CDataStream& operator>>(TEmfLogFontEx& oFont)
{
*this >> oFont.LogFont;
ReadBytes(oFont.FullName, 64);
ReadBytes(oFont.Style, 32);
ReadBytes(oFont.Script, 32);
return *this;
}
CDataStream& operator>>(TEmfDesignVector& oVector)
{
*this >> oVector.Signature;
*this >> oVector.NumAxes;
oVector.Values = NULL;
if (oVector.NumAxes <= 0)
return *this;
oVector.Values = new long[oVector.NumAxes];
if (!oVector.Values)
return *this;
for (unsigned long ulIndex = 0; ulIndex < oVector.NumAxes; ulIndex++)
*this >> oVector.Values[ulIndex];
return *this;
}
CDataStream& operator>>(CEmfLogFont& oFont)
{
*this >> oFont.LogFontEx;
*this >> oFont.DesignVector;
return *this;
}
CDataStream& operator>>(TEmfBitBlt& oBitBtl)
{
*this >> oBitBtl.Bounds;
*this >> oBitBtl.xDest;
*this >> oBitBtl.yDest;
*this >> oBitBtl.cxDest;
*this >> oBitBtl.cyDest;
*this >> oBitBtl.BitBltRasterOperation;
*this >> oBitBtl.xSrc;
*this >> oBitBtl.ySrc;
*this >> oBitBtl.XfromSrc;
*this >> oBitBtl.BkColorSrc;
*this >> oBitBtl.UsageSrc;
*this >> oBitBtl.offBmiSrc;
*this >> oBitBtl.cbBmiSrc;
*this >> oBitBtl.offBitsSrc;
*this >> oBitBtl.cbBitsSrc;
return *this;
}
CDataStream& operator>>(TEmfXForm& oXForm)
{
*this >> oXForm.M11;
*this >> oXForm.M12;
*this >> oXForm.M21;
*this >> oXForm.M22;
*this >> oXForm.Dx;
*this >> oXForm.Dy;
return *this;
}
CDataStream& operator>>(TEmfStretchDIBITS& oBitmap)
{
*this >> oBitmap.Bounds;
*this >> oBitmap.xDest;
*this >> oBitmap.yDest;
*this >> oBitmap.xSrc;
*this >> oBitmap.ySrc;
*this >> oBitmap.cxSrc;
*this >> oBitmap.cySrc;
*this >> oBitmap.offBmiSrc;
*this >> oBitmap.cbBmiSrc;
*this >> oBitmap.offBitsSrc;
*this >> oBitmap.cbBitsSrc;
*this >> oBitmap.UsageSrc;
*this >> oBitmap.BitBltRasterOperation;
*this >> oBitmap.cxDest;
*this >> oBitmap.cyDest;
return *this;
}
bool IsValid() const
{
......
......@@ -11,6 +11,7 @@
#include "EmfPlayer.h"
#include "../../../fontengine/FontManager.h"
#include <iostream>
namespace Metafile
{
......@@ -105,12 +106,29 @@ namespace Metafile
switch (ulType)
{
//-----------------------------------------------------------
// 2.3.1 Bitmap
//-----------------------------------------------------------
case EMR_BITBLT:
{
Read_EMR_BITBLT();
break;
}
case EMR_STRETCHDIBITS:
{
Read_EMR_STRETCHDIBITS();
break;
}
//-----------------------------------------------------------
// 2.3.4 Control
//-----------------------------------------------------------
case EMR_EOF:
{
Read_EMR_EOF();
bEof = true;
break;
}
//-----------------------------------------------------------
// 2.3.5 Drawing
//-----------------------------------------------------------
case EMR_EXTTEXTOUTW:
......@@ -118,6 +136,11 @@ namespace Metafile
Read_EMR_EXTTEXTOUTW();
break;
}
case EMR_POLYGON16:
{
Read_EMR_POLYGON16();
break;
}
//-----------------------------------------------------------
// 2.3.7 Object Creation
//-----------------------------------------------------------
......@@ -126,6 +149,24 @@ namespace Metafile
Read_EMR_CREATEBRUSHINDIRECT();
break;
}
case EMR_EXTCREATEFONTINDIRECTW:
{
Read_EMR_EXTCREATEFONTINDIRECTW();
break;
}
//-----------------------------------------------------------
// 2.3.8 Object Manipulation
//-----------------------------------------------------------
case EMR_SELECTOBJECT:
{
Read_EMR_SELECTOBJECT();
break;
}
case EMR_DELETEOBJECT:
{
Read_EMR_DELETEOBJECT();
break;
}
//-----------------------------------------------------------
// 2.3.11 State
//-----------------------------------------------------------
......@@ -144,6 +185,16 @@ namespace Metafile
Read_EMR_SETTEXTCOLOR();
break;
}
case EMR_SETTEXTALIGN:
{
Read_EMR_SETTEXTALIGN();
break;
}
case EMR_SETBKMODE:
{
Read_EMR_SETBKMODE();
break;
}
//-----------------------------------------------------------
// 2.3.12 Transform
//-----------------------------------------------------------
......@@ -157,17 +208,21 @@ namespace Metafile
Read_EMR_MODIFYWORLDTRANSFORM();
break;
}
case EMR_EOF:
//-----------------------------------------------------------
//
//-----------------------------------------------------------
case EMR_GDICOMMENT:
case EMR_SETICMMODE:
{
Read_EMR_EOF();
bEof = true;
Read_EMR_UNKNOWN();
break;
}
case EMR_SETICMMODE:
//-----------------------------------------------------------
//
//-----------------------------------------------------------
default:
{
{
std::cout << ulType << " ";
Read_EMR_UNKNOWN();
break;
}
......@@ -179,16 +234,21 @@ namespace Metafile
if (!m_oStream.IsValid())
SetError();
} while (!CheckError());
} while (!CheckError());
}
private:
void SetError()
{
m_bError = true;
}
CEmfDC* GetDC()
{
return m_pDC;
}
void Read_EMR_HEADER()
{
......@@ -224,26 +284,30 @@ namespace Metafile
void Read_EMR_STRETCHDIBITS()
{
TEmfStretchDIBITS oBitmap;
m_oStream >> oBitmap;
long lHeaderOffset = oBitmap.offBmiSrc - sizeof(TEmfBitBlt) - 8;
unsigned long ulHeaderSize = oBitmap.cbBmiSrc;
long lBitsOffset = oBitmap.offBitsSrc - oBitmap.offBmiSrc - oBitmap.cbBmiSrc;
unsigned long ulBitsSize = oBitmap.cbBitsSrc;
if (ulHeaderSize <= 0 || ulBitsSize <= 0 || lHeaderOffset < 0 || lBitsOffset < 0)
{
// TODO: , oBitmap.BitBltRasterOperation
if (lHeaderOffset > 0)
m_oStream.Skip(lHeaderOffset);
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);
m_oStream.Skip(ulHeaderSize);
if (lBitsOffset > 0)
m_oStream.Skip(lBitsOffset);
m_oStream.Skip(ulBitsSize);
return;
}
m_oStream.Skip(lHeaderOffset);
BYTE* pHeaderBuffer = new BYTE[ulHeaderSize];
if (!pHeaderBuffer)
......@@ -251,9 +315,7 @@ namespace Metafile
m_oStream.ReadBytes(pHeaderBuffer, ulHeaderSize);
unsigned long ulBitsOffset = oBitmap.offBitsSrc - oBitmap.offBmiSrc - oBitmap.cbBmiSrc;
unsigned long ulBitsSize = oBitmap.cbBitsSrc;
m_oStream.Skip(ulBitsOffset);
m_oStream.Skip(lBitsOffset);
BYTE* pBitsBuffer = new BYTE[ulBitsSize];
if (!pBitsBuffer)
{
......@@ -267,7 +329,7 @@ namespace Metafile
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);
m_pOutput->DrawBitmap(oBitmap.xDest, oBitmap.yDest, oBitmap.cxDest, oBitmap.cyDest, pBgraBuffer, ulWidth, ulHeight);
if (pBgraBuffer)
delete[] pBgraBuffer;
......@@ -315,15 +377,9 @@ namespace Metafile
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 >> oXForm;
m_oStream >> ulMode;
TEmfXForm* pCurTransform = m_pDC->GetTransform();
......@@ -333,12 +389,7 @@ namespace Metafile
{
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;
m_oStream >> oXForm;
TEmfXForm* pCurTransform = m_pDC->GetTransform();
pCurTransform->Multiply(oXForm, MWT_SET);
......@@ -361,19 +412,166 @@ namespace Metafile
m_pDC->SetTextColor(oColor);
}
void Read_EMR_EXTTEXTOUTW()
{
TEmfExtTextoutW oText;
m_oStream >> oText;
// OutputString
const unsigned long ulCharsCount = oText.wEmrText.Chars;
long lSkip = oText.wEmrText.offString - 76; // 8 + 28 + 40
m_oStream.Skip(lSkip);
unsigned short* pUnicode = new unsigned short[ulCharsCount + 1];
pUnicode[ulCharsCount] = 0x0000;
m_oStream.ReadBytes(pUnicode, ulCharsCount);
oText.wEmrText.OutputString = (void*)pUnicode;
// OutputDx
lSkip = oText.wEmrText.offDx - oText.wEmrText.offString - 2 * ulCharsCount;
m_oStream.Skip(lSkip);
const unsigned long ulDxCount = oText.wEmrText.Options & ETO_PDY ? 2 * ulCharsCount : ulCharsCount;
unsigned long* pDx = new unsigned long[ulDxCount];
m_oStream.ReadBytes(pDx, ulDxCount);
std::wstring wsText((wchar_t*)pUnicode);
if (m_pOutput)
m_pOutput->DrawText(wsText.c_str(), ulCharsCount, oText.wEmrText.Reference.x, oText.wEmrText.Reference.x);
delete[] pUnicode;
delete[] pDx;
}
void Read_EMR_SELECTOBJECT()
{
unsigned long ulObjectIndex;
m_oStream >> ulObjectIndex;
m_oPlayer.SelectObject(ulObjectIndex);
}
void Read_EMR_POLYGON16()
{
TEmfRectL oBounds;
m_oStream >> oBounds;
unsigned long ulCount;
m_oStream >> ulCount;
if (ulCount <= 0)
return;
TEmfPointS* pPoints = new TEmfPointS[ulCount];
if (!pPoints)
return SetError();
unsigned long ulGrMode;
double dExScale, dEyScale;
for (unsigned long ulIndex = 0; ulIndex < ulCount; ulIndex++)
{
m_oStream >> pPoints[ulIndex];
}
CEmfOutputDevice* pOut = m_pOutput;
if (pOut)
{
pOut->StartPath();
pOut->MoveTo(pPoints[0].x, pPoints[0].y);
m_oStream >> ulGrMode;
m_oStream >> dExScale;
m_oStream >> dEyScale;
for (unsigned long ulIndex = 1; ulIndex < ulCount; ulIndex++)
{
pOut->LineTo(pPoints[ulIndex].x, pPoints[ulIndex].y);
}
pOut->ClosePath();
pOut->DrawPath();
pOut->EndPath();
}
// EmrText
delete[] pPoints;
}
void Read_EMR_EXTCREATEFONTINDIRECTW()
{
unsigned long ulIndex;
CEmfLogFont* pFont = new CEmfLogFont();
if (!pFont)
return SetError();
m_oStream >> ulIndex;
m_oStream >> *pFont;
m_oPlayer.RegisterObject(ulIndex, (CEmfObjectBase*)pFont);
}
void Read_EMR_SETTEXTALIGN()
{
unsigned long ulAlign;
m_oStream >> ulAlign;
m_pDC->SetTextAlign(ulAlign);
}
void Read_EMR_SETBKMODE()
{
unsigned long ulBgMode;
m_oStream >> ulBgMode;
m_pDC->SetBgMode(ulBgMode);
}
void Read_EMR_DELETEOBJECT()
{
unsigned long ulIndex;
m_oStream >> ulIndex;
// . , ,
// , .
}
void Read_EMR_BITBLT()
{
TEmfBitBlt oBitmap;
m_oStream >> oBitmap;
long lHeaderOffset = oBitmap.offBmiSrc - sizeof(TEmfBitBlt) - 8;
unsigned long ulHeaderSize = oBitmap.cbBmiSrc;
long lBitsOffset = oBitmap.offBitsSrc - oBitmap.offBmiSrc - oBitmap.cbBmiSrc;
unsigned long ulBitsSize = oBitmap.cbBitsSrc;
if (ulHeaderSize <= 0 || ulBitsSize <= 0 || lHeaderOffset < 0 || lBitsOffset < 0)
{
// TODO: , oBitmap.BitBltRasterOperation
if (lHeaderOffset > 0)
m_oStream.Skip(lHeaderOffset);
m_oStream.Skip(ulHeaderSize);
if (lBitsOffset > 0)
m_oStream.Skip(lBitsOffset);
m_oStream.Skip(ulBitsSize);
return;
}
m_oStream.Skip(lHeaderOffset);
BYTE* pHeaderBuffer = new BYTE[ulHeaderSize];
if (!pHeaderBuffer)
return SetError();
m_oStream.ReadBytes(pHeaderBuffer, ulHeaderSize);
m_oStream.Skip(lBitsOffset);
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->DrawBitmap(oBitmap.xDest, oBitmap.yDest, oBitmap.cxDest, oBitmap.cyDest, pBgraBuffer, ulWidth, ulHeight);
if (pBgraBuffer)
delete[] pBgraBuffer;
delete[] pBitsBuffer;
delete[] pHeaderBuffer;
}
private:
......
......@@ -6,11 +6,22 @@
namespace Metafile
{
typedef enum
{
EMF_OBJECT_UNKNOWN = 0x00,
EMF_OBJECT_BRUSH = 0x01,
EMF_OBJECT_FONT = 0x02
} EEmfObjectType;
class CEmfObjectBase
{
public:
CEmfObjectBase(){}
virtual ~CEmfObjectBase(){}
virtual EEmfObjectType GetType()
{
return EMF_OBJECT_UNKNOWN;
}
};
class CEmfLogBrushEx : public CEmfObjectBase
......@@ -25,12 +36,39 @@ namespace Metafile
virtual ~CEmfLogBrushEx()
{
}
virtual EEmfObjectType GetType()
{
return EMF_OBJECT_BRUSH;
}
public:
unsigned long BrushStyle;
TEmfColor Color;
unsigned long BrushHatch;
};
class CEmfLogFont : public CEmfObjectBase
{
public:
CEmfLogFont()
{
DesignVector.Values = NULL;
}
virtual ~CEmfLogFont()
{
if (DesignVector.Values)
delete[] DesignVector.Values;
}
virtual EEmfObjectType GetType()
{
return EMF_OBJECT_FONT;
}
public:
TEmfLogFontEx LogFontEx;
TEmfDesignVector DesignVector;
};
}
#endif // _EMF_OBJECTS_H
\ No newline at end of file
......@@ -18,7 +18,16 @@ namespace Metafile
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;
virtual void DrawBitmap(long lX, long lY, long lW, long lH, BYTE* pBuffer, unsigned long ulWidth, unsigned long ulHeight) = 0;
virtual void DrawText(const wchar_t* wsText, unsigned long ulCharsCount, long lX, long lY) = 0;
virtual void StartPath() = 0;
virtual void MoveTo(long lX, long lY) = 0;
virtual void LineTo(long lX, long lY) = 0;
virtual void ClosePath() = 0;
virtual void DrawPath() = 0;
virtual void EndPath() = 0;
};
}
......
......@@ -101,15 +101,31 @@ namespace Metafile
{
CEmfObjectBase* pOldObject = oPos->second;
delete pOldObject;
m_mObjects.erase(ulIndex);
}
m_mObjects.insert(std::pair<unsigned long, CEmfObjectBase*>(ulIndex, pObject));
}
void CEmfPlayer::SelectObject(unsigned long ulIndex)
{
CEmfObjectMap::const_iterator oPos = m_mObjects.find(ulIndex);
if (m_mObjects.end() != oPos)
{
CEmfObjectBase* pObject = oPos->second;
switch (pObject->GetType())
{
case EMF_OBJECT_BRUSH: m_pDC->SetBrush((CEmfLogBrushEx*)pObject); break;
case EMF_OBJECT_FONT: m_pDC->SetFont((CEmfLogFont*)pObject); break;
}
}
}
CEmfDC::CEmfDC()
{
m_oTransform.Init();
m_oTextColor.Init();
m_pBrush = NULL;
}
CEmfDC::~CEmfDC()
{
......@@ -122,6 +138,7 @@ namespace Metafile
pNewDC->m_oTransform.Copy(&m_oTransform);
pNewDC->m_oTextColor.Copy(&m_oTextColor);
pNewDC->m_pBrush = m_pBrush;
return pNewDC;
}
......@@ -133,4 +150,48 @@ namespace Metafile
{
m_oTextColor.Copy(&oColor);
}
TEmfColor& CEmfDC::GetTextColor()
{
return m_oTextColor;
}
void CEmfDC::SetBrush(CEmfLogBrushEx* pBrush)
{
m_pBrush = pBrush;
}
CEmfLogBrushEx* CEmfDC::GetBrush()
{
return m_pBrush;
}
void CEmfDC::SetFont(CEmfLogFont* pFont)
{
m_pFont = pFont;
}
CEmfLogFont* CEmfDC::GetFont()
{
return m_pFont;
}
void CEmfDC::SetTextAlign(unsigned long ulAlign)
{
m_ulTextAlign = ulAlign;
}
unsigned long CEmfDC::GetTextAlign()
{
return m_ulTextAlign;
}
void CEmfDC::SetBgMode(unsigned long ulBgMode)
{
m_ulBgMode = ulBgMode;
}
unsigned long CEmfDC::GetBgMode()
{
return m_ulBgMode;
}
void CEmfDC::SetBgColor(TEmfColor& oColor)
{
m_oBgColor.Copy(&oColor);
}
TEmfColor& CEmfDC::GetBgColor()
{
return m_oBgColor;
}
}
\ No newline at end of file
......@@ -22,6 +22,7 @@ namespace Metafile
CEmfDC* RestoreDC();
CEmfDC* GetDC();
void RegisterObject(unsigned long ulIndex, CEmfObjectBase* pObject);
void SelectObject(unsigned long ulIndex);
private:
......@@ -40,13 +41,29 @@ namespace Metafile
CEmfDC();
~CEmfDC();
CEmfDC* Copy();
TEmfXForm* GetTransform();
void SetTextColor(TEmfColor& oColor);
TEmfXForm* GetTransform();
void SetTextColor(TEmfColor& oColor);
TEmfColor& GetTextColor();
void SetBrush(CEmfLogBrushEx* pBrush);
CEmfLogBrushEx* GetBrush();
void SetFont(CEmfLogFont* pFont);
CEmfLogFont* GetFont();
void SetTextAlign(unsigned long ulAlign);
unsigned long GetTextAlign();
void SetBgMode(unsigned long ulBgMode);
unsigned long GetBgMode();
void SetBgColor(TEmfColor& oColor);
TEmfColor& GetBgColor();
private:
TEmfXForm m_oTransform;
TEmfColor m_oTextColor;
CEmfLogBrushEx* m_pBrush;
CEmfLogFont* m_pFont;
TEmfXForm m_oTransform;
TEmfColor m_oTextColor;
TEmfColor m_oBgColor;
unsigned long m_ulTextAlign;
unsigned long m_ulBgMode;
};
}
......
......@@ -55,6 +55,12 @@ namespace Metafile
long y;
};
struct TEmfPointS
{
short x;
short y;
};
struct TEmfHeader
{
TEmfRectL oBounds;
......@@ -171,5 +177,78 @@ namespace Metafile
}
}
};
struct TEmfEmrText
{
TEmfPointL Reference;
unsigned long Chars;
unsigned long offString;
unsigned long Options;
TEmfRectL Rectangle;
unsigned long offDx;
void* OutputString; // unsinged short* unsigned char*
unsigned long* OutputDx;
};
struct TEmfExtTextoutW
{
TEmfRectL Bounds;
unsigned long iGraphicsMode;
double exScale;
double eyScale;
TEmfEmrText wEmrText;
};
struct TEmfLogFont
{
long Height;
long Width;
long Escapement;
long Orientation;
long Weight;
unsigned char Italic;
unsigned char Underline;
unsigned char StrikOut;
unsigned char CharSet;
unsigned char OutPrecision;
unsigned char ClipPrecision;
unsigned char Quality;
unsigned char PitchAndFamily;
unsigned short FaceName[32];
};
struct TEmfLogFontEx
{
TEmfLogFont LogFont;
unsigned short FullName[64];
unsigned short Style[32];
unsigned short Script[32];
};
struct TEmfDesignVector
{
unsigned long Signature;
unsigned long NumAxes;
long* Values;
};
struct TEmfBitBlt
{
TEmfRectL Bounds;
long xDest;
long yDest;
long cxDest;
long cyDest;
unsigned long BitBltRasterOperation;
long xSrc;
long ySrc;
TEmfXForm XfromSrc;
TEmfColor BkColorSrc;
unsigned long UsageSrc;
unsigned long offBmiSrc;
unsigned long cbBmiSrc;
unsigned long offBitsSrc;
unsigned long cbBitsSrc;
};
};
#endif //_EMF_TYPES_H
\ No newline at end of file
......@@ -44,8 +44,10 @@ namespace Metafile
{
}
void Draw_Bitmap(long lX, long lY, long lW, long lH, BYTE* pBuffer, unsigned long ulWidth, unsigned long ulHeight)
void DrawBitmap(long lX, long lY, long lW, long lH, BYTE* pBuffer, unsigned long ulWidth, unsigned long ulHeight)
{
UpdateTransform();
Aggplus::CImage oImage;
BYTE* pBufferPtr = new BYTE[4 * ulWidth * ulHeight];
oImage.Create(pBufferPtr, ulWidth, ulHeight, 4 * ulWidth);
......@@ -67,6 +69,209 @@ namespace Metafile
m_pRenderer->DrawImage(&oImage, dX, dY, dX1 - dX, dY1 - dY);
}
void DrawText(const wchar_t* wsText, unsigned long ulCharsCount, long lX, long lY)
{
UpdateTransform();
CEmfDC* pDC = m_pEmfFile->GetDC();
if (!pDC)
return;
CEmfLogFont* pFont = pDC->GetFont();
if (!pFont)
return;
TEmfLogFont* pLogFont = &pFont->LogFontEx.LogFont;
TEmfRectL* pBounds = &m_pEmfFile->m_oHeader.oBounds;
TEmfRectL* pFrame = &m_pEmfFile->m_oHeader.oFrame;
double dFontHeight = TransY(std::abs(pLogFont->Height)) / 25.4 * 72;
std::wstring wsFaceName((const wchar_t*)pLogFont->FaceName);
m_pRenderer->put_FontName(wsFaceName);
m_pRenderer->put_FontSize(dFontHeight);
long lStyle = 0;
if (pLogFont->Weight > 550)
lStyle |= 0x01;
if (pLogFont->Italic)
lStyle |= 0x02;
if (pLogFont->Underline)
lStyle |= (1 << 2);
if (pLogFont->StrikOut)
lStyle |= (1 << 7);
m_pRenderer->put_FontStyle(lStyle);
TEmfColor oTextColor = pDC->GetTextColor();
//
m_pRenderer->put_BrushType(c_BrushTypeSolid);
m_pRenderer->put_BrushColor1(METAFILE_RGBA(oTextColor.r, oTextColor.g, oTextColor.b));
m_pRenderer->put_BrushAlpha1(255);
double dTheta = -((((double)pLogFont->Escapement) / 10) * M_PI / 180);
double dCosTheta = (float)cos(dTheta);
double dSinTheta = (float)sin(dTheta);
float fL = 0, fT = 0, fW = 0, fH = 0;
float fUndX1 = 0, fUndY1 = 0, fUndX2 = 0, fUndY2 = 0, fUndSize = 1;
CFontManager* pFontManager = m_pEmfFile->m_pFontManager;
if (pFontManager)
{
pFontManager->LoadFontByName(wsFaceName, dFontHeight, lStyle, 72, 72);
pFontManager->LoadString1(wsText, 0, 0);
TBBox oBox = pFontManager->MeasureString2();
fL = oBox.fMinX;
fT = oBox.fMinY;
fW = oBox.fMaxX - oBox.fMinX;
fH = oBox.fMaxY - oBox.fMinY;
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;
}
double dX = TransX(lX);
double dY = TransX(lY);
//
unsigned long ulTextAlign = pDC->GetTextAlign();
if (ulTextAlign & TA_BASELINE)
{
//
}
else if (ulTextAlign & TA_BOTTOM)
{
float fTemp = -(-fT + fH);
dX += -fTemp * dSinTheta;
dY += fTemp * dCosTheta;
}
else // if (ulTextAlign & TA_TOP)
{
float fTemp = -fT;
dX += -fTemp * dSinTheta;
dY += fTemp * dCosTheta;
}
if (ulTextAlign & TA_CENTER)
{
dX += -fW / 2 * dCosTheta;
dY += -fW / 2 * dSinTheta;
}
else if (ulTextAlign & TA_RIGHT)
{
dX += -fW * dCosTheta;
dY += -fW * dSinTheta;
}
else //if (ulTextAlign & TA_LEFT)
{
//
}
if (pLogFont->Underline)
{
fUndX1 += (float)dX;
fUndX2 += (float)dX;
fUndY1 += (float)dY;
fUndY2 += (float)dY;
}
bool bChangeCTM = false;
if (0 != pLogFont->Escapement)
{
// TODO: shEscapement, Orientation
m_pRenderer->SetTransform(dCosTheta, dSinTheta, -dSinTheta, dCosTheta, dX - dX * dCosTheta + dY * dSinTheta, dY - dX * dSinTheta - dY * dCosTheta);
bChangeCTM = true;
}
//
if (OPAQUE == pDC->GetBgMode())
{
TEmfColor oBgColor = pDC->GetBgColor();
m_pRenderer->put_BrushType(c_BrushTypeSolid);
m_pRenderer->put_BrushColor1(255);
m_pRenderer->put_BrushAlpha1(METAFILE_RGBA(oBgColor.r, oBgColor.g, oBgColor.b));
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandStart();
m_pRenderer->PathCommandMoveTo(dX + fL, dY + fT);
m_pRenderer->PathCommandLineTo(dX + fL + fW, dY + fT);
m_pRenderer->PathCommandLineTo(dX + fL + fW, dY + fT + fH);
m_pRenderer->PathCommandLineTo(dX + fL, dY + fT + fH);
m_pRenderer->PathCommandClose();
m_pRenderer->DrawPath(c_nWindingFillMode);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->PathCommandStart();
}
//
if (pLogFont->Underline)
{
m_pRenderer->put_PenSize((double)fUndSize);
m_pRenderer->put_PenLineEndCap(0);
m_pRenderer->put_PenLineStartCap(0);
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandStart();
m_pRenderer->PathCommandMoveTo(fUndX1, fUndY1);
m_pRenderer->PathCommandLineTo(fUndX2, fUndY2);
m_pRenderer->DrawPath(c_nStroke);
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
}
//
m_pRenderer->CommandDrawText(wsText, dX, dY, 0, 0, 0);
if (bChangeCTM)
m_pRenderer->ResetTransform();
}
void StartPath()
{
UpdateTransform();
UpdateBrush();
m_pRenderer->BeginCommand(c_nPathType);
m_pRenderer->PathCommandStart();
}
void MoveTo(long lX, long lY)
{
double dX = TransX(lX);
double dY = TransY(lY);
m_pRenderer->PathCommandMoveTo(dX, dY);
}
void LineTo(long lX, long lY)
{
double dX = TransX(lX);
double dY = TransY(lY);
m_pRenderer->PathCommandLineTo(dX, dY);
}
void ClosePath()
{
m_pRenderer->PathCommandClose();
}
void DrawPath()
{
m_pRenderer->DrawPath(c_nWindingFillMode);
}
void EndPath()
{
m_pRenderer->EndCommand(c_nPathType);
m_pRenderer->PathCommandEnd();
}
private:
......@@ -80,7 +285,6 @@ namespace Metafile
return m_dW * (double)(lX - lL) / (double)(lR - lL);
}
double TransY(long lY)
{
long lT = m_pEmfFile->m_oHeader.oBounds.lTop;
......@@ -92,16 +296,61 @@ namespace Metafile
return m_dH * (double)(lY - lT) / (double)(lB - lT);
}
bool UpdateBrush()
{
CEmfDC* pDC = m_pEmfFile->GetDC();
if (!pDC)
return false;
CEmfLogBrushEx* pBrush = pDC->GetBrush();
if (!pBrush)
return false;
long lColor = METAFILE_RGBA(pBrush->Color.r, pBrush->Color.g, pBrush->Color.b);
if (BS_NULL == pBrush->BrushStyle)
return false;
else //if (BS_SOLID == pBrush->BrushStyle)
{
m_pRenderer->put_BrushColor1(lColor);
m_pRenderer->put_BrushAlpha1(255);
m_pRenderer->put_BrushType(c_BrushTypeSolid);
}
return true;
}
void UpdateTransform()
{
CEmfDC* pDC = m_pEmfFile->GetDC();
if (!pDC)
return;
long lL = m_pEmfFile->m_oHeader.oBounds.lLeft;
long lR = m_pEmfFile->m_oHeader.oBounds.lRight;
long lT = m_pEmfFile->m_oHeader.oBounds.lTop;
long lB = m_pEmfFile->m_oHeader.oBounds.lBottom;
if (lB - lT <= 0 || lR - lL <= 0)
return;
double dKoefX = m_dW / (double)(lR - lL);
double dKoefY = m_dW / (double)(lR - lL);
TEmfXForm* pMatrix = pDC->GetTransform();
m_pRenderer->ResetTransform();
m_pRenderer->SetTransform(pMatrix->M11, pMatrix->M12 * dKoefY / dKoefX, pMatrix->M21 * dKoefX / dKoefY, pMatrix->M22, pMatrix->Dx * dKoefX, pMatrix->Dy * dKoefY);
}
private:
IRenderer* m_pRenderer;
NSStructures::CPen m_oPen;
NSStructures::CBrush m_oBrush;
NSStructures::CFont m_oFont;
double m_dDpiX;
double m_dDpiY;
long m_lDrawPathType;
double m_dX; //
double m_dY; //
double m_dW; // /,
......
......@@ -14,22 +14,22 @@
#include "WmfOutputDevice.h"
#include "WmfFile.h"
#include "../Common.h"
//------ Для дебага ----------------------------------------------------
#define NO_PIE // отключаем команду Draw_Pie
//#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 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
{
......@@ -1328,7 +1328,7 @@ private:
{
TWmfPen *pPen = pDC->pPen;
long lColor = WMF_RGBA(pPen->oColor.r, pPen->oColor.g, pPen->oColor.b);
long lColor = METAFILE_RGBA(pPen->oColor.r, pPen->oColor.g, pPen->oColor.b);
double dWidth = pPen->dWidth * m_dScaleX ;
if ( dWidth <= 0.01 )
......@@ -1386,7 +1386,7 @@ private:
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;
case R2_WHITE: m_pRenderer->put_PenColor(METAFILE_RGBA(255, 255, 255)); break;
}
if ( PS_NULL == ushPenStyle )
......@@ -1398,7 +1398,7 @@ private:
bool SetBrush(TWmfDC *pDC)
{
TWmfBrush *pBrush = pDC->pBrush;
long lColor = WMF_RGBA(pBrush->oColor.r, pBrush->oColor.g, pBrush->oColor.b);
long lColor = METAFILE_RGBA(pBrush->oColor.r, pBrush->oColor.g, pBrush->oColor.b);
if ( BS_NULL == pBrush->ushStyle )
return false;
......
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