Files
core/ASCImageStudio3/ASCGraphics/Interfaces/GdiplusRenderer.h
Oleg.Korshul 48302b8d9e font_selection.bin в папке с процессом
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@61041 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-20 23:40:24 +03:00

1068 lines
26 KiB
C++

#pragma once
#include "StructuresGDI.h"
#include "GdiplusEx.h"
#include "..\..\..\..\Common\MediaFormatDefine.h"
class CGdiplusRenderer
{
public:
// îòðèñîâùèê
Gdiplus::Graphics* m_pRenderer;
// êîíòåéíåð ïðèìèòèâîâ
Gdiplus::GraphicsPath* m_pPath;
// ñîñòîÿíèå
NSStructuresGDI::CPen m_oPen;
NSStructuresGDI::CBrush m_oBrush;
NSStructuresGDI::CFont m_oFont;
NSStructuresGDI::CShadow m_oShadow;
NSStructuresGDI::CEdgeText m_oEdge;
// ôîðìàò äëÿ ðèñîâàíèÿ
Gdiplus::StringFormat m_oFormat;
double m_dWidth;
double m_dHeight;
double m_dPixelsWidth;
double m_dPixelsHeight;
// êàðòèíêà - íà êîòîðîé âñå ðèñóåòñÿ...
// íóæíà òîëüêî äëÿ Addref - Release ( à òî âäðóã êòî óäàëèò êàðòèíî÷êó, ïîêà ìû òóò ðèñóåì )
MediaCore::IAVSUncompressedVideoFrame* m_pImage;
Gdiplus::Bitmap* m_pBitmap;
DWORD m_lCurrentCommandType;
LONG m_lCurrentClipMode;
Gdiplus::Matrix m_oBaseMatrix;
BOOL m_bBaseMatrixUse;
CGdiPlusInit m_oInit;
BOOL m_bIsSetupClip;
public:
CGdiplusRenderer() : m_oFormat(StringFormat::GenericTypographic()), m_oBaseMatrix(1, 0, 0, 1, 0, 0)
{
m_pRenderer = NULL;
m_pPath = NULL;
m_oInit.Init();
m_oFormat.SetFormatFlags(StringFormatFlagsNoClip | StringFormatFlagsMeasureTrailingSpaces | StringFormatFlagsNoFitBlackBox);
m_oFormat.SetAlignment(StringAlignmentNear);
m_oFormat.SetLineAlignment(StringAlignmentNear);
m_pImage = NULL;
m_pBitmap = NULL;
m_dWidth = 210;
m_dHeight = 190;
m_dPixelsWidth = 720;
m_dPixelsHeight = 576;
m_lCurrentCommandType = 0;
m_lCurrentClipMode = 0;
m_bBaseMatrixUse = FALSE;
m_bIsSetupClip = FALSE;
}
~CGdiplusRenderer()
{
Clear();
}
public:
inline BOOL CheckValidate(BOOL bOnlyGraphics = FALSE)
{
if (NULL == m_pRenderer)
return FALSE;
if (!bOnlyGraphics)
{
return (NULL != m_pPath);
}
return TRUE;
}
inline void Clear()
{
RELEASEOBJECT(m_pPath);
RELEASEOBJECT(m_pRenderer);
RELEASEINTERFACE(m_pImage);
RELEASEOBJECT(m_pBitmap);
}
inline BOOL COM_GetBGRAImageFromInterface(IUnknown* pSource, BYTE*& pBGRA, int& nWidth, int& nHeight, int* pStride = NULL, long* pAspectX = NULL, long* pAspectY = NULL)
{
/* @desc:
int COM_GetBGRAImageFromInterface(IUnknown* pSource, BYTE*& pBGRA, int& nWidth, int& nHeight)
{
èç óêàçàííîãî èíòåðôåéñà (pSource) âûòàñêèâàåòñÿ êàðòèíêà (pBGRA, nWidth, nHeight)
â ôîðìàòå BGRA; åñëè ôîðìàò èíòåðôåéñà íå CSP_BGRA - êîíâåðòàöèÿ ôîðìàòà íå ïðîèçâîäèòñÿ
}
*/
if (NULL == pSource)
return FALSE;
// âûòàñêèâàåì èç èíòåðôåéñà uncompressed frame
MediaCore::IAVSUncompressedVideoFrame* pUncompressedFrame = NULL;
pSource->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)(&pUncompressedFrame));
if (NULL == pUncompressedFrame)
return FALSE;
// çàïðàøèâàåì íàñòðîéêè êàðòèíêè
long lWidth = 0; pUncompressedFrame->get_Width(&lWidth);
long lHeight = 0; pUncompressedFrame->get_Height(&lHeight);
long lColorSpace = 0; pUncompressedFrame->get_ColorSpace(&lColorSpace);
long lStride = 0; pUncompressedFrame->get_Stride(0, &lStride);
long lBufferSize = 0; pUncompressedFrame->get_BufferSize(&lBufferSize);
BYTE* pSourceBuffer = NULL; pUncompressedFrame->get_Buffer(&pSourceBuffer);
// ïðîâåðÿåì ñîâìåñòèìîñòü êàäðà è ôîðìàòà
if (CSP_BGRA != (CSP_COLOR_MASK & lColorSpace) || 4*lWidth != lStride || lWidth < 1 || lHeight < 1 || lBufferSize != 4*lWidth*lHeight || !pSourceBuffer)
{
pUncompressedFrame->Release();
return FALSE;
}
if( pStride )
*pStride = (lColorSpace & CSP_VFLIP) ? -lStride : lStride;
if( pAspectX ) pUncompressedFrame->get_AspectRatioX( pAspectX );
if( pAspectY ) pUncompressedFrame->get_AspectRatioY( pAspectY );
// âñå õîðîøî, îçâðàùàåì íàâåðõ íóæíûå ïàðàìåòðû
pBGRA = pSourceBuffer;
nWidth = lWidth;
nHeight = lHeight;
pUncompressedFrame->Release();
return TRUE;
}
inline void UpdateSize()
{
if (NULL == m_pBitmap)
return;
RELEASEOBJECT(m_pRenderer);
double MMToInch = 25.4;
float fDpiX = (float)(m_dPixelsWidth / (m_dWidth / MMToInch));
float fDpiY = (float)(m_dPixelsHeight / (m_dHeight / MMToInch));
m_pBitmap->SetResolution(fDpiX, fDpiY);
if( Gdiplus::Ok != m_pBitmap->GetLastStatus() )
{
RELEASEINTERFACE(m_pImage);
RELEASEOBJECT(m_pBitmap);
return;
}
m_pRenderer = new Gdiplus::Graphics(m_pBitmap);
m_pRenderer->SetSmoothingMode(SmoothingModeAntiAlias);
m_pRenderer->SetTextRenderingHint(TextRenderingHintAntiAlias);
m_pRenderer->SetPageUnit(UnitMillimeter);
}
public:
// ñîçäàíèå ðåíäåðåðà èç êàðòèíêè
STDMETHOD(CreateFromMediaData)(IUnknown* punkMediaData)
{
Clear();
if (NULL == punkMediaData)
return S_FALSE;
punkMediaData->QueryInterface(MediaCore::IID_IAVSUncompressedVideoFrame, (void**)&m_pImage);
if (NULL == m_pImage)
return S_FALSE;
BYTE* pBGRA = NULL;
int nWidth = 0;
int nHeight = 0;
int nStride = 0;
// âûòàñêèâàåì èç èíòåðôåéñà óêàçàòåëü íà ïàìÿòü â ôîðìàòå BGRA
BOOL bRes = COM_GetBGRAImageFromInterface(punkMediaData, pBGRA, nWidth, nHeight, &nStride);
if (!bRes)
{
RELEASEINTERFACE(m_pImage);
return S_FALSE;
}
m_dPixelsWidth = max(1.0, (double)nWidth);
m_dPixelsHeight = max(1.0, (double)nHeight);
if (nStride < 0)
{
// ïåðåâîðà÷èâàåì èçîáðàæåíèå äëÿ GDI+
pBGRA += 4 * nWidth * (nHeight - 1);
}
m_pBitmap = new Gdiplus::Bitmap( nWidth, nHeight, /*-4*nWidth*/nStride, PixelFormat32bppARGB, pBGRA );
double MMToInch = 25.4;
float fDpiX = (float)(nWidth / (m_dWidth / MMToInch));
float fDpiY = (float)(nHeight / (m_dHeight / MMToInch));
m_pBitmap->SetResolution(fDpiX, fDpiY);
if( Gdiplus::Ok != m_pBitmap->GetLastStatus() )
{
RELEASEINTERFACE(m_pImage);
RELEASEOBJECT(m_pBitmap);
return S_FALSE;
}
m_pRenderer = new Gdiplus::Graphics(m_pBitmap);
m_pRenderer->SetSmoothingMode(SmoothingModeAntiAlias);
m_pRenderer->SetTextRenderingHint(TextRenderingHintAntiAlias);
m_pRenderer->SetPageUnit(UnitMillimeter);
m_pPath = new Gdiplus::GraphicsPath(FillModeWinding);
return S_OK;
}
STDMETHOD(CreateFromHDC)(HDC* phDC)
{
Clear();
m_pRenderer = new Gdiplus::Graphics(*phDC);
m_pRenderer->SetSmoothingMode(SmoothingModeAntiAlias);
m_pRenderer->SetTextRenderingHint(TextRenderingHintAntiAlias);
m_pRenderer->SetPageUnit(UnitMillimeter);
m_pPath = new Gdiplus::GraphicsPath(FillModeWinding);
return S_OK;
}
// ---------------------------------------------
// ôóíêöèè äëÿ ðàáîòû ñî ñòðàíèöåé (çäåñü - òîëüêî ëèøü äëÿ âû÷èñëåíèÿ dpi)
inline STDMETHOD(NewPage)()
{
// íó íå âëåçëî òàê íå âëåçëî
return S_OK;
}
inline STDMETHOD(put_Height)(double fHeight)
{
double dOldH = m_dHeight;
m_dHeight = max(10.0, fHeight);
if (dOldH != m_dHeight)
{
UpdateSize();
}
return S_OK;
}
inline STDMETHOD(get_Height)(double* fHeight)
{
*fHeight = m_dHeight;
return S_OK;
}
inline STDMETHOD(put_Width)(double fWidth)
{
double dOldW = m_dWidth;
m_dWidth = max(10.0, fWidth);
if (dOldW != m_dWidth)
{
UpdateSize();
}
return S_OK;
}
inline STDMETHOD(get_Width)(double* fWidth)
{
*fWidth = m_dWidth;
return S_OK;
}
inline STDMETHOD(get_DpiX)(double* dDpiX)
{
if (NULL == dDpiX)
return S_FALSE;
*dDpiX = 25.4 * m_dPixelsWidth / m_dWidth;
return S_OK;
}
inline STDMETHOD(get_DpiY)(double* dDpiY)
{
if (NULL == dDpiY)
return S_FALSE;
*dDpiY = 25.4 * m_dPixelsHeight / m_dHeight;
return S_OK;
}
// ---------------------------------------------
// ôóíêöèè ñîñòîÿíèÿ îòêèñîâùèêà ---------------
inline STDMETHOD(SetPen)(BSTR bsXML)
{
m_oPen.FromXmlString((CString)bsXML);
return S_OK;
}
PROPERTY_RENDERER(Pen, Color, LONG)
PROPERTY_RENDERER(Pen, Alpha, LONG)
PROPERTY_RENDERER(Pen, Size, double)
PROPERTY_RENDERER(Pen, DashStyle, BYTE)
PROPERTY_RENDERER(Pen, LineStartCap, BYTE)
PROPERTY_RENDERER(Pen, LineEndCap, BYTE)
PROPERTY_RENDERER(Pen, LineJoin, BYTE)
PROPERTY_RENDERER(Pen, DashOffset, double)
PROPERTY_RENDERER(Pen, Align, LONG)
PROPERTY_RENDERER(Pen, MiterLimit, double)
STDMETHOD(PenDashPattern)(SAFEARRAY* pPattern)
{
if (NULL == pPattern)
return NULL;
m_oPen.SetDashPattern((double*)pPattern->pvData, pPattern->rgsabound[0].cElements);
return S_OK;
}
inline STDMETHOD(SetBrush)(BSTR bsXML)
{
m_oBrush.FromXmlString(CString(bsXML));
return S_OK;
}
PROPERTY_RENDERER(Brush, Type, LONG)
PROPERTY_RENDERER(Brush, Color1, LONG)
PROPERTY_RENDERER(Brush, Color2, LONG)
PROPERTY_RENDERER(Brush, Alpha1, LONG)
PROPERTY_RENDERER(Brush, Alpha2, LONG)
PROPERTY_RENDERER(Brush, TextureMode, LONG)
PROPERTY_RENDERER(Brush, TextureAlpha, LONG)
PROPERTY_RENDERER(Brush, LinearAngle, double)
STDMETHOD(get_BrushTexturePath)(BSTR* bsPath)
{
*bsPath = m_oBrush.TexturePath.AllocSysString();
return S_OK;
}
STDMETHOD(put_BrushTexturePath)(BSTR bsPath)
{
m_oBrush.TexturePath = (CString)bsPath;
return S_OK;
}
STDMETHOD(BrushRect)(BOOL val, double left, double top, double width, double height)
{
m_oBrush.Rectable = val;
m_oBrush.Rect.X = (float)left;
m_oBrush.Rect.Y = (float)top;
m_oBrush.Rect.Width = (float)width;
m_oBrush.Rect.Height = (float)height;
return S_OK;
}
inline STDMETHOD(SetFont)(BSTR bsXML)
{
m_oFont.FromXmlString(CString(bsXML));
return S_OK;
}
STDMETHOD(get_FontName)(BSTR* bsName)
{
*bsName = m_oFont.Name.AllocSysString();
return S_OK;
}
STDMETHOD(put_FontName)(BSTR bsName)
{
m_oFont.Name = (CString)bsName;
return S_OK;
}
STDMETHOD(get_FontPath)(BSTR* bsPath)
{
*bsPath = m_oFont.Name.AllocSysString();
return S_OK;
}
STDMETHOD(put_FontPath)(BSTR bsPath)
{
m_oFont.Path = (CString)bsPath;
return S_OK;
}
PROPERTY_RENDERER(Font, Size, double)
STDMETHOD(get_FontStyle)(LONG* val)
{
*val = m_oFont.GetStyle();
return S_OK;
}
STDMETHOD(put_FontStyle)(LONG val)
{
m_oFont.SetStyle(val);
return S_OK;
}
PROPERTY_RENDERER(Font, StringGID, BOOL)
PROPERTY_RENDERER(Font, CharSpace, double)
inline STDMETHOD(SetShadow)(BSTR bsXML)
{
m_oShadow.FromXmlString(CString(bsXML));
return S_OK;
}
PROPERTY_RENDERER(Shadow, DistanceX, double)
PROPERTY_RENDERER(Shadow, DistanceY, double)
PROPERTY_RENDERER(Shadow, BlurSize, double)
PROPERTY_RENDERER(Shadow, Color, LONG)
PROPERTY_RENDERER(Shadow, Alpha, LONG)
PROPERTY_RENDERER(Shadow, Visible, BOOL)
inline STDMETHOD(SetEdgeText)(BSTR bsXML)
{
m_oEdge.FromXmlString(CString(bsXML));
return S_OK;
}
PROPERTY_RENDERER(Edge, Visible, LONG)
PROPERTY_RENDERER(Edge, Color, LONG)
PROPERTY_RENDERER(Edge, Alpha, LONG)
PROPERTY_RENDERER(Edge, Dist, double)
// ---------------------------------------------
// îòðèñîâêà òåêñòà
inline STDMETHOD(CommandDrawText)(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
if (!CheckValidate(TRUE))
return S_FALSE;
if (c_nHyperlinkType == m_lCurrentCommandType)
return S_OK;
CString strText = (CString)(bsText);
int nLength = strText.GetLength();
Gdiplus::Font* pFont = m_oFont.GetFont(UnitPoint);
RectF oRect((float)fX, (float)fY, (float)fWidth, (float)fHeight);
if (m_oShadow.Visible)
{
m_oShadow.Draw(m_pRenderer, pFont, &m_oFormat, bsText, nLength, oRect);
}
m_oBrush.Rect = oRect;
Gdiplus::Brush* pBrush = m_oBrush.GetBrush();
m_pRenderer->DrawString(bsText, nLength, pFont, oRect, &m_oFormat, pBrush);
if (m_oEdge.Visible)
{
m_oEdge.Draw(m_pRenderer, pFont, &m_oFormat, bsText, nLength, oRect);
}
RELEASEOBJECT(pBrush);
RELEASEOBJECT(pFont);
return S_OK;
}
// ---------------------------------------------
// GraphicPath Methods
inline STDMETHOD(PathCommandMoveTo)(double fX, double fY)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->StartFigure();
m_pPath->AddLine((float)fX, (float)fY, (float)fX, (float)fY);
return S_OK;
}
inline STDMETHOD(PathCommandLineTo)(double fX, double fY)
{
if (!CheckValidate())
return S_FALSE;
PointF pointCur(0, 0);
CheckLastPoint(pointCur);
m_pPath->AddLine(pointCur.X, pointCur.Y, (float)fX, (float)fY);
return S_OK;
}
inline STDMETHOD(PathCommandLinesTo)(SAFEARRAY* pPoints)
{
if (!CheckValidate() || (NULL == pPoints))
return S_FALSE;
LONG lCount = pPoints->rgsabound[0].cElements;
lCount /= 2;
double* points = (double*)pPoints->pvData;
CSimpleArray<Gdiplus::PointF> arPoints;
for (int nIndex = 0; nIndex < lCount; ++nIndex)
{
Gdiplus::PointF oPoint((float)points[0], (float)points[1]);
points += 2;
arPoints.Add(oPoint);
}
if (1 < lCount)
{
m_pPath->AddLines(arPoints.m_aT, lCount);
}
return S_OK;
}
inline STDMETHOD(PathCommandCurveTo)(double fX1, double fY1, double fX2, double fY2, double fX3, double fY3)
{
if (!CheckValidate())
return S_FALSE;
PointF pointCur(0, 0);
CheckLastPoint(pointCur);
CSimpleArray<PointF> arPoints;
arPoints.Add(pointCur);
pointCur.X = (float)fX1; pointCur.Y = (float)fY1;
arPoints.Add(pointCur);
pointCur.X = (float)fX2; pointCur.Y = (float)fY2;
arPoints.Add(pointCur);
pointCur.X = (float)fX3; pointCur.Y = (float)fY3;
arPoints.Add(pointCur);
//m_pPath->AddCurve(arPoints.m_aT, 4);
m_pPath->AddBeziers(arPoints.m_aT, 4);
return S_OK;
}
inline STDMETHOD(PathCommandCurvesTo)(SAFEARRAY* pPoints)
{
if (!CheckValidate())
return S_FALSE;
LONG lCount = pPoints->rgsabound[0].cElements;
lCount /= 2;
double* points = (double*)pPoints->pvData;
CSimpleArray<Gdiplus::PointF> arPoints;
for (int nIndex = 0; nIndex < lCount; ++nIndex)
{
Gdiplus::PointF oPoint((float)points[0], (float)points[1]);
points += 2;
arPoints.Add(oPoint);
}
int nSize = arPoints.GetSize();
if (1 < nSize)
{
//m_pPath->AddCurve(arPoints.m_aT, nSize);
m_pPath->AddBeziers(arPoints.m_aT, nSize);
}
return S_OK;
}
inline STDMETHOD(PathCommandArcTo)(double fX, double fY, double fWidth, double fHeight, double fStartAngle, double fSweepAngle)
{
if (!CheckValidate())
return S_FALSE;
m_pPath->AddArc((float)fX, (float)fY, (float)fWidth, (float)fHeight, (float)fStartAngle, (float)fSweepAngle);
return S_OK;
}
inline STDMETHOD(PathCommandClose)()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->CloseFigure();
return S_OK;
}
inline STDMETHOD(PathCommandEnd)()
{
//RELEASEOBJECT(m_pPath);
//m_pPath = new Gdiplus::GraphicsPath(FillModeWinding);
m_pPath->Reset();
return S_OK;
}
inline STDMETHOD(PathCommandStart)()
{
if (!CheckValidate())
return S_FALSE;
m_pPath->StartFigure();
return S_OK;
}
inline STDMETHOD(PathCommandGetCurrentPoint)(double* fX, double* fY)
{
if (!CheckValidate())
return S_FALSE;
if ((NULL == fX) || (NULL == fY))
return S_FALSE;
PointF oPoint(0, 0);
CheckLastPoint(oPoint);
*fX = (double)oPoint.X;
*fY = (double)oPoint.Y;
return S_OK;
}
inline STDMETHOD(DrawPath)(long nType)
{
if (!CheckValidate(TRUE))
return S_FALSE;
LONG lFillType = (nType & 0xFF00);
BOOL bIsStroke = (0x01 == (nType & 0x01));
float fLeft = 0;
float fTop = 0;
float fRight = 0;
float fBottom = 0;
/*Painter::CTextureManager oManager;
if (0 < lFillType)
{
int nCount = m_pPath->GetPointCount();
if (0 < nCount)
{
PointF* pPoints = new PointF[nCount];
m_pPath->GetPathPoints(pPoints, nCount);
fLeft = pPoints[0].X;
fTop = pPoints[0].Y;
fRight = pPoints[0].X;
fBottom = pPoints[0].Y;
for (int nIndex = 1; nIndex < nCount; ++nIndex)
{
fLeft = min(fLeft, pPoints[nIndex].X);
fTop = min(fTop, pPoints[nIndex].Y);
fRight = max(fRight, pPoints[nIndex].X);
fBottom = max(fBottom, pPoints[nIndex].Y);
}
delete []pPoints;
}
if (Painter::c_BrushTypeTexture == m_oBrush.Type)
{
oManager.Add(m_oBrush.TexturePath);
}
}*/
RectF oRect(0, 0, 1, 1);
switch (lFillType)
{
case c_nWindingFillMode:
{
/*m_pPath->SetFillMode(FillModeWinding);
RectF oRect(fLeft, fTop, fRight - fLeft, fBottom - fTop);
SmoothingMode oOldMode = m_pRenderer->GetSmoothingMode();
m_pRenderer->SetSmoothingMode(SmoothingModeNone);
m_pRenderer->FillPath(m_oBrush.GetBrush(&oManager, &oRect), m_pPath);
m_pRenderer->SetSmoothingMode(oOldMode);*/
m_pPath->SetFillMode(Gdiplus::FillModeWinding);
m_pPath->GetBounds(&oRect);
Gdiplus::Brush* pBrush = m_oBrush.GetBrush();
m_pRenderer->FillPath(pBrush, m_pPath);
RELEASEOBJECT(pBrush);
break;
}
case c_nEvenOddFillMode:
{
/*m_pPath->SetFillMode(FillModeAlternate);
RectF oRect(fLeft, fTop, fRight - fLeft, fBottom - fTop);
SmoothingMode oOldMode = m_pRenderer->GetSmoothingMode();
m_pRenderer->SetSmoothingMode(SmoothingModeNone);
m_pRenderer->FillPath(m_oBrush.GetBrush(&oManager, &oRect), m_pPath);
m_pRenderer->SetSmoothingMode(oOldMode);*/
m_pPath->SetFillMode(Gdiplus::FillModeAlternate);
m_pPath->GetBounds(&oRect);
Gdiplus::Brush* pBrush = m_oBrush.GetBrush();
m_pRenderer->FillPath(pBrush, m_pPath);
RELEASEOBJECT(pBrush);
break;
}
default:
break;
};
if (bIsStroke)
{
//m_pRenderer->DrawPath(m_oPen.GetPen(), m_pPath);
Gdiplus::Pen* pPen = m_oPen.GetPen();
m_pRenderer->DrawPath(pPen, m_pPath);
RELEASEOBJECT(pPen);
}
return S_OK;
}
// ---------------------------------------------
inline STDMETHOD(DrawImage)(IUnknown* pInterface, double fX, double fY, double fWidth, double fHeight)
{
if (!CheckValidate(TRUE) || NULL == pInterface)
return S_FALSE;
BYTE* pBGRA = NULL;
int nWidth = 0;
int nHeight = 0;
int lStride = 0;
BOOL bRes = COM_GetBGRAImageFromInterface(pInterface, pBGRA, nWidth, nHeight, &lStride);
if (!bRes)
return S_FALSE;
if (0 > lStride)
{
// ïåðåâîðà÷èâàåì èçîáðàæåíèå äëÿ GDI+
pBGRA += 4 * nWidth * (nHeight - 1);
}
Bitmap oImage( nWidth, nHeight, lStride, PixelFormat32bppARGB, pBGRA );
m_pRenderer->DrawImage(&oImage, (float)fX, (float)fY, (float)fWidth, (float)fHeight);
return S_OK;
}
//----------------------------------------------
inline STDMETHOD(SetAdditionalParam)(BSTR ParamName, VARIANT ParamValue)
{
return S_OK;
}
inline STDMETHOD(GetAdditionalParam)(BSTR ParamName, VARIANT* ParamValue)
{
return S_OK;
}
// new
inline STDMETHOD(BeginCommand)(DWORD lType)
{
m_lCurrentCommandType = lType;
switch (lType)
{
case c_nPageType:
{
return NewPage();
}
default:
break;
};
return S_OK;
}
inline STDMETHOD(EndCommand)(DWORD lType)
{
switch (lType)
{
case c_nClipType:
{
Gdiplus::Region oCurrentRegion;
m_pRenderer->GetClip(&oCurrentRegion);
BOOL bIsIn = (c_nClipRegionTypeWinding == (0x0001 & m_lCurrentClipMode));
m_pPath->SetFillMode(bIsIn ? Gdiplus::FillModeWinding : Gdiplus::FillModeAlternate);
Region oNewRegion(m_pPath);
if (!m_bIsSetupClip)
{
m_pRenderer->SetClip(&oNewRegion);
m_bIsSetupClip = TRUE;
}
else
{
BOOL bIsIntersect = (c_nClipRegionIntersect == (0x0100 & m_lCurrentClipMode));
if (bIsIntersect)
{
oCurrentRegion.Intersect(&oNewRegion);
}
else
{
oCurrentRegion.Union(&oNewRegion);
}
m_pRenderer->SetClip(&oCurrentRegion);
}
RELEASEOBJECT(m_pPath);
m_pPath = new Gdiplus::GraphicsPath(FillModeWinding);
break;
}
case c_nResetClipType:
{
m_pRenderer->ResetClip();
m_bIsSetupClip = FALSE;
break;
}
default:
break;
};
m_lCurrentCommandType = 0;
return S_OK;
}
inline STDMETHOD(CommandDrawTextEx)(BSTR bsText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (NULL != bsGidText)
{
m_oFont.StringGID = TRUE;
return CommandDrawText(bsGidText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
m_oFont.StringGID = FALSE;
return CommandDrawText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
inline STDMETHOD(DrawImageFromFile)(BSTR bstrVal, double fX, double fY, double fWidth, double fHeight)
{
return S_OK;
}
inline STDMETHOD(GetCommandParams)(double* dAngle, double* dLeft, double* dTop, double* dWidth, double* dHeight, DWORD* lFlags)
{
return S_OK;
}
inline STDMETHOD(SetCommandParams)(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
ApplyTransform2(dAngle, dLeft, dTop, dWidth, dHeight, lFlags);
return S_OK;
}
inline STDMETHOD(SetTransform)(double dA, double dB, double dC, double dD, double dE, double dF)
{
if (!CheckValidate())
return S_FALSE;
ApplyTransform(dA, dB, dC, dD, dE, dF);
return S_OK;
}
inline STDMETHOD(GetTransform)(double *pdA, double *pdB, double *pdC, double *pdD, double *pdE, double *pdF)
{
if (!CheckValidate())
return S_FALSE;
Gdiplus::Matrix oMatrix;
m_pRenderer->GetTransform(&oMatrix);
float buffer[10];
oMatrix.GetElements(buffer);
*pdA = (double)buffer[0];
*pdB = (double)buffer[1];
*pdC = (double)buffer[2];
*pdD = (double)buffer[3];
*pdE = (double)buffer[4];
*pdF = (double)buffer[5];
return S_OK;
}
inline STDMETHOD(ResetTransform)(void)
{
_ResetTransform();
return S_OK;
}
inline STDMETHOD(get_ClipMode)(LONG* plMode)
{
if ((!CheckValidate()) || (NULL == plMode))
return S_FALSE;
*plMode = m_lCurrentClipMode;
return S_OK;
}
inline STDMETHOD(put_ClipMode)(LONG lMode)
{
if (!CheckValidate())
return S_FALSE;
m_lCurrentClipMode = lMode;
return S_OK;
}
inline STDMETHOD(PathCommandText)(BSTR bsText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset)
{
if (!CheckValidate())
return S_FALSE;
CString strText = (CString)(bsText);
int nLength = strText.GetLength();
Gdiplus::Font* pFont = m_oFont.GetFont(UnitPoint);
PointF pointOrigin((float)fX, (float)fY);
Gdiplus::FontFamily oFamily;
pFont->GetFamily(&oFamily);
// òàê êàê ïàò ðèñóåòñÿ â ìèëëèìåòðàõ - íàäî ïåðåâåñòè ïóíêòû â ìèëëèìåòðû
float fSize = (float)(0.3528 * pFont->GetSize());
m_pPath->AddString(bsText, nLength, &oFamily, pFont->GetStyle(), fSize, pointOrigin, &m_oFormat);
RELEASEOBJECT(pFont);
return S_OK;
}
inline STDMETHOD(PathCommandTextEx)(BSTR bsText, BSTR bsGidText, BSTR bsSourceCodeText, double fX, double fY, double fWidth, double fHeight, double fBaseLineOffset, DWORD lFlags)
{
if (NULL != bsGidText)
{
m_oFont.StringGID = TRUE;
return PathCommandText(bsGidText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
m_oFont.StringGID = FALSE;
return PathCommandText(bsText, fX, fY, fWidth, fHeight, fBaseLineOffset);
}
protected:
void ApplyTransform(double d1, double d2, double d3, double d4, double d5, double d6)
{
Gdiplus::Matrix oMatrix((float)d1, (float)d2, (float)d3, (float)d4, (float)d5, (float)d6);
ApplyTransform(&oMatrix);
}
void ApplyTransform2(double dAngle, double dLeft, double dTop, double dWidth, double dHeight, DWORD lFlags)
{
if ((dWidth <= 1) || (dHeight <= 1))
lFlags = 0;
BOOL bFlipX = (0 != (c_nParamFlipX & lFlags));
BOOL bFlipY = (0 != (c_nParamFlipY & lFlags));
float m11 = bFlipX ? -1.0f : 1.0f;
float m22 = bFlipY ? -1.0f : 1.0f;
Gdiplus::Matrix oMatrix(1, 0, 0, 1, 0, 0);
if ((0 != dAngle) || (0 != lFlags))
{
float dCentreX = (float)(dLeft + dWidth / 2.0);
float dCentreY = (float)(dTop + dHeight / 2.0);
oMatrix.Translate(-dCentreX, -dCentreY , MatrixOrderAppend);
oMatrix.Rotate((float)dAngle , MatrixOrderAppend);
oMatrix.Scale(m11, m22 , MatrixOrderAppend);
oMatrix.Translate(dCentreX, dCentreY , MatrixOrderAppend);
}
ApplyTransform(&oMatrix);
}
inline void ApplyTransform(Gdiplus::Matrix* pMatrix)
{
if (!CheckValidate())
return;
if (m_bBaseMatrixUse)
{
pMatrix->Multiply(&m_oBaseMatrix, MatrixOrderPrepend);
}
m_pRenderer->SetTransform(pMatrix);
}
inline void _ResetTransform()
{
if (!CheckValidate())
return;
ApplyTransform(1, 0, 0, 1, 0, 0);
}
void CheckLastPoint(PointF& pointCur)
{
if (!CheckValidate())
return;
int nCount = m_pPath->GetPointCount();
if (0 < nCount)
{
PointF* pPoints = new PointF[nCount];
m_pPath->GetPathPoints(pPoints, nCount);
pointCur.X = pPoints[nCount - 1].X;
pointCur.Y = pPoints[nCount - 1].Y;
delete []pPoints;
}
}
public:
inline void CalculatePoint(PointF& oPoint)
{
CalculatePoint(oPoint.X, oPoint.Y);
}
inline void CalculatePoints(CSimpleArray<Gdiplus::PointF>& arPoints)
{
for (int nIndex = 0; nIndex < arPoints.GetSize(); ++nIndex)
{
CalculatePoint(arPoints[nIndex]);
}
}
inline void CalculatePoint(float& fX, float& fY)
{
fX = (float)(fX * m_dPixelsWidth / m_dWidth);
fY = (float)(fY * m_dPixelsHeight / m_dHeight);
}
public:
void SetBaseMatrix(const Gdiplus::Matrix& oMatrix)
{
float elements[6];
oMatrix.GetElements(elements);
m_oBaseMatrix.SetElements(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
m_bBaseMatrixUse = TRUE;
}
void ResetBaseMatrix()
{
m_oBaseMatrix.SetElements(1, 0, 0, 1, 0, 0);
m_bBaseMatrixUse = FALSE;
}
void ApplyBaseMatrix()
{
if (!CheckValidate())
return;
m_pRenderer->SetTransform(&m_oBaseMatrix);
}
};