You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
510 lines
13 KiB
C++
510 lines
13 KiB
C++
// XTPFlowGraphDrawContextGdiPlus.cpp : implementation of the CXTPFlowGraphDrawContextGdiPlus class.
|
|
//
|
|
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include <math.h>
|
|
|
|
#include "Common/XTPDrawHelpers.h"
|
|
#include "Common/XTPResourceManager.h"
|
|
#include "Common/XTPVC80Helpers.h"
|
|
#include "GraphicLibrary/GdiPlus/GdiPlus.h"
|
|
|
|
#include "Markup/XTPMarkupObject.h"
|
|
#include "Markup/XTPMarkupInputElement.h"
|
|
#include "Markup/XTPMarkupUIElement.h"
|
|
#include "Markup/XTPMarkupContext.h"
|
|
#include "Markup/XTPMarkupDrawingContext.h"
|
|
|
|
#include "XTPFlowGraphTools.h"
|
|
#include "XTPFlowGraphDrawContext.h"
|
|
#include "XTPFlowGraphDrawContextGdiPlus.h"
|
|
#include "XTPFlowGraphControl.h"
|
|
#include "XTPFlowGraphImage.h"
|
|
|
|
#pragma comment(lib, "GdiPlus.lib")
|
|
|
|
using namespace Gdiplus;
|
|
using namespace Gdiplus::DllExports;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPFlowGraphDrawContextGdiPlus
|
|
|
|
class CXTPFlowGraphDrawContextGdiPlus::CGdiPlus
|
|
{
|
|
public:
|
|
CGdiPlus()
|
|
{
|
|
m_hModule = NULL;
|
|
m_nGdiplusToken = NULL;
|
|
m_nCount = 0;
|
|
}
|
|
|
|
public:
|
|
void Register(BOOL bInit);
|
|
|
|
public:
|
|
HMODULE m_hModule;
|
|
ULONG_PTR m_nGdiplusToken;
|
|
int m_nCount;
|
|
};
|
|
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::CGdiPlus::Register(BOOL bInit)
|
|
{
|
|
if (bInit)
|
|
{
|
|
m_nCount++;
|
|
|
|
if (m_nCount > 1)
|
|
return;
|
|
|
|
ASSERT(m_nGdiplusToken == 0 && m_hModule == 0);
|
|
|
|
|
|
m_hModule = LoadLibrary(_T("GdiPlus.dll"));
|
|
|
|
if (m_hModule)
|
|
{
|
|
GdiplusStartupInput gdiplusStartupInput;
|
|
GdiplusStartup(&m_nGdiplusToken, &gdiplusStartupInput, NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_nCount--;
|
|
|
|
if (m_nCount != 0)
|
|
return;
|
|
|
|
if (m_hModule)
|
|
{
|
|
GdiplusShutdown(m_nGdiplusToken);
|
|
FreeLibrary(m_hModule);
|
|
}
|
|
|
|
m_hModule = NULL;
|
|
m_nGdiplusToken = 0;
|
|
}
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::Register(BOOL bInit)
|
|
{
|
|
static CGdiPlus GdiPlus;
|
|
|
|
GdiPlus.Register(bInit);
|
|
}
|
|
|
|
CXTPFlowGraphDrawContextGdiPlus::CXTPFlowGraphDrawContextGdiPlus(HDC hDC, HDC hAttribDC, BOOL bPrinting)
|
|
: CXTPFlowGraphDrawContext(hDC, hAttribDC, bPrinting)
|
|
{
|
|
m_hDC = hDC;
|
|
m_bPrinting = FALSE;
|
|
|
|
if (hAttribDC && hAttribDC != hDC)
|
|
{
|
|
m_pGraphics = new Graphics(hDC, hAttribDC);
|
|
}
|
|
else
|
|
{
|
|
m_pGraphics = new Graphics(hDC);
|
|
}
|
|
m_bPrinting = bPrinting;
|
|
|
|
|
|
m_pGraphics->SetPageUnit(UnitPixel);
|
|
m_pGraphics->SetSmoothingMode(SmoothingModeHighQuality);
|
|
m_pGraphics->SetPixelOffsetMode(PixelOffsetModeHalf);
|
|
|
|
#if 0
|
|
SetSmoothingMode(0);
|
|
#endif
|
|
|
|
m_pActiveBrush = NULL;
|
|
m_pActivePen = NULL;
|
|
m_pActiveTextBrush = NULL;
|
|
m_pActiveFont = NULL;
|
|
|
|
Rect rcScreenBounds;
|
|
m_pGraphics->GetClipBounds(&rcScreenBounds);
|
|
m_rcClipRect = CRect(rcScreenBounds.GetLeft(), rcScreenBounds.GetTop(), rcScreenBounds.GetRight(), rcScreenBounds.GetBottom());
|
|
|
|
m_nBrushCount = 0;
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetSmoothingMode(int nMode)
|
|
{
|
|
if (nMode)
|
|
{
|
|
m_pGraphics->SetTextRenderingHint(TextRenderingHintSystemDefault);
|
|
m_pGraphics->SetSmoothingMode(SmoothingModeHighQuality);
|
|
m_pGraphics->SetPixelOffsetMode(PixelOffsetModeHalf);
|
|
}
|
|
else
|
|
{
|
|
m_pGraphics->SetTextRenderingHint(TextRenderingHintSingleBitPerPixelGridFit);
|
|
m_pGraphics->SetSmoothingMode(SmoothingModeHighSpeed);
|
|
m_pGraphics->SetPixelOffsetMode(PixelOffsetModeHighSpeed);
|
|
}
|
|
}
|
|
|
|
CXTPFlowGraphDrawContextGdiPlus::~CXTPFlowGraphDrawContextGdiPlus()
|
|
{
|
|
SAFE_DELETE(m_pActivePen);
|
|
SAFE_DELETE(m_pActiveFont);
|
|
|
|
for (int i = 0; i < m_nBrushCount; i++)
|
|
{
|
|
delete m_arrBrushes[i].pBrush;
|
|
}
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetWorldTransform(CPoint ptOffset, double dZoomLevel)
|
|
{
|
|
m_pGraphics->ResetTransform();
|
|
|
|
m_pGraphics->TranslateTransform((REAL)-ptOffset.x, (REAL)-ptOffset.y, MatrixOrderAppend);
|
|
m_pGraphics->ScaleTransform((REAL)dZoomLevel, (REAL)dZoomLevel, MatrixOrderAppend);
|
|
|
|
Rect rcScreenBounds;
|
|
m_pGraphics->GetClipBounds(&rcScreenBounds);
|
|
m_rcClipRect = CRect(rcScreenBounds.GetLeft(), rcScreenBounds.GetTop(), rcScreenBounds.GetRight(), rcScreenBounds.GetBottom());
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetClipRect(CRect rc)
|
|
{
|
|
Rect rcClip(rc.left, rc.top, rc.Width(), rc.Height());
|
|
m_pGraphics->SetClip(rcClip);
|
|
|
|
Rect rcScreenBounds;
|
|
m_pGraphics->GetClipBounds(&rcScreenBounds);
|
|
m_rcClipRect = CRect(rcScreenBounds.GetLeft(), rcScreenBounds.GetTop(), rcScreenBounds.GetRight(), rcScreenBounds.GetBottom());
|
|
}
|
|
|
|
CRect CXTPFlowGraphDrawContextGdiPlus::GetClipRect() const
|
|
{
|
|
return m_rcClipRect;
|
|
}
|
|
|
|
DWORD CXTPFlowGraphDrawContextGdiPlus::ColorRefToARGB(COLORREF clr)
|
|
{
|
|
DWORD dwArgb = RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr));
|
|
if (clr & 0xFF000000)
|
|
dwArgb |= (clr & 0xFF000000);
|
|
else
|
|
dwArgb |= 0xFF000000;
|
|
|
|
return dwArgb;
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::Clear(COLORREF clr)
|
|
{
|
|
m_pGraphics->Clear(ColorRefToARGB(clr));
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::FillSolidRect(LPCRECT lpRect, COLORREF clr)
|
|
{
|
|
FillSolidRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
|
|
lpRect->bottom - lpRect->top, clr);
|
|
|
|
}
|
|
|
|
Gdiplus::Brush* CXTPFlowGraphDrawContextGdiPlus::CreateBrush(COLORREF clr)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < m_nBrushCount; i++)
|
|
{
|
|
if (m_arrBrushes[i].clr == clr)
|
|
return m_arrBrushes[i].pBrush;
|
|
}
|
|
|
|
if (m_nBrushCount == MAX_BRUSH)
|
|
{
|
|
delete m_arrBrushes[m_nBrushCount - 1].pBrush;
|
|
}
|
|
else if (m_nBrushCount)
|
|
{
|
|
m_arrBrushes[m_nBrushCount] = m_arrBrushes[m_nBrushCount - 1];
|
|
}
|
|
|
|
for (i = m_nBrushCount - 1; i >= 1; i--)
|
|
{
|
|
m_arrBrushes[i] = m_arrBrushes[i - 1];
|
|
}
|
|
|
|
if (m_nBrushCount != MAX_BRUSH)
|
|
m_nBrushCount++;
|
|
|
|
m_arrBrushes[0].pBrush = new SolidBrush(ColorRefToARGB(clr));
|
|
m_arrBrushes[0].clr = clr;
|
|
|
|
return m_arrBrushes[0].pBrush;
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::FillSolidRect(int x, int y, int cx, int cy, COLORREF clr)
|
|
{
|
|
if (cx < 0)
|
|
{
|
|
x += cx;
|
|
cx = -cx;
|
|
}
|
|
|
|
if (cy < 0)
|
|
{
|
|
y += cy;
|
|
cy = -cy;
|
|
}
|
|
|
|
Brush* pBrush = CreateBrush(clr);
|
|
m_pGraphics->FillRectangle(pBrush, x, y, cx, cy);
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight)
|
|
{
|
|
Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
|
|
lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight);
|
|
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::Draw3dRect(int x, int y, int cx, int cy, COLORREF clrTopLeft, COLORREF clrBottomRight)
|
|
{
|
|
FillSolidRect(x, y, cx - 1, 1, clrTopLeft);
|
|
FillSolidRect(x, y, 1, cy - 1, clrTopLeft);
|
|
FillSolidRect(x + cx, y, -1, cy, clrBottomRight);
|
|
FillSolidRect(x, y + cy, cx, -1, clrBottomRight);
|
|
}
|
|
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawFrame(int x, int y, int cx, int cy, int sz, COLORREF clr)
|
|
{
|
|
FillSolidRect(x, y, cx - sz, sz, clr);
|
|
FillSolidRect(x, y, sz, cy - sz, clr);
|
|
FillSolidRect(x + cx, y, -sz, cy, clr);
|
|
FillSolidRect(x, y + cy, cx, -sz, clr);
|
|
}
|
|
|
|
CSize CXTPFlowGraphDrawContextGdiPlus::MeasureMarkupElement(CXTPMarkupUIElement* pMarkupUIElement)
|
|
{
|
|
pMarkupUIElement->GetMarkupContext()->SetDefaultFont(&m_lfActiveFont);
|
|
|
|
CXTPMarkupDrawingContext dc(pMarkupUIElement->GetMarkupContext(), m_pGraphics);
|
|
pMarkupUIElement->Measure(&dc, CSize(INT_MAX, INT_MAX));
|
|
|
|
CSize sz = pMarkupUIElement->GetDesiredSize();
|
|
|
|
return sz;
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawMarkupElement(CXTPMarkupUIElement* pMarkupUIElement, LPCRECT lpRect, UINT /*uFormat*/)
|
|
{
|
|
pMarkupUIElement->GetMarkupContext()->SetDefaultFont(&m_lfActiveFont);
|
|
pMarkupUIElement->GetMarkupContext()->SetDefaultTextColor(m_clrTextColor);
|
|
|
|
CXTPMarkupDrawingContext dc(pMarkupUIElement->GetMarkupContext(), m_pGraphics);
|
|
pMarkupUIElement->Arrange(lpRect);
|
|
pMarkupUIElement->Render(&dc);
|
|
}
|
|
|
|
|
|
CSize CXTPFlowGraphDrawContextGdiPlus::MeasureString(const CString& str)
|
|
{
|
|
|
|
if (!m_pActiveFont)
|
|
return CSize(0, 0);
|
|
|
|
|
|
RectF boundingBox;
|
|
RectF layoutRect(0, 0, 0.0f, 0.0f);
|
|
|
|
if (str.GetLength() != 0)
|
|
{
|
|
m_pGraphics->MeasureString(XTP_CT2CW(str), -1, m_pActiveFont, layoutRect, StringFormat::GenericTypographic(), &boundingBox);
|
|
}
|
|
else
|
|
{
|
|
m_pGraphics->MeasureString(L" ", 1, m_pActiveFont, layoutRect, StringFormat::GenericTypographic(), &boundingBox);
|
|
}
|
|
|
|
return CSize((int)ceil(boundingBox.Width), (int)(boundingBox.Height));
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawText(LPCTSTR lpszText, LPCRECT lpRect, UINT uFormat)
|
|
{
|
|
if (!m_pActiveFont)
|
|
return;
|
|
|
|
|
|
StringFormat stringFormat(StringFormat::GenericTypographic());
|
|
stringFormat.SetLineAlignment(uFormat & DT_VCENTER ? StringAlignmentCenter: StringAlignmentNear);
|
|
stringFormat.SetAlignment(uFormat & DT_CENTER ? StringAlignmentCenter : uFormat & DT_RIGHT ? StringAlignmentFar : StringAlignmentNear);
|
|
|
|
RectF rect((REAL)lpRect->left, (REAL)lpRect->top, (REAL)lpRect->right - lpRect->left, (REAL)lpRect->bottom - lpRect->top);
|
|
|
|
m_pGraphics->DrawString(XTP_CT2CW(lpszText), -1, m_pActiveFont, rect, &stringFormat, m_pActiveTextBrush);
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawCurve(Gdiplus::GraphicsPath* pPath)
|
|
{
|
|
if (m_pActivePen)
|
|
{
|
|
m_pGraphics->DrawPath(m_pActivePen, pPath);
|
|
}
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::Ellipse(LPCRECT lpRect)
|
|
{
|
|
if (m_pActiveBrush)
|
|
{
|
|
m_pGraphics->FillEllipse(m_pActiveBrush, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top);
|
|
}
|
|
|
|
if (m_pActivePen)
|
|
{
|
|
m_pGraphics->DrawEllipse(m_pActivePen, lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top);
|
|
}
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::Line(float x1, float y1, float x2, float y2)
|
|
{
|
|
if (m_pActivePen)
|
|
{
|
|
m_pGraphics->DrawLine(m_pActivePen, x1, y1, x2, y2);
|
|
}
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetBrush(COLORREF clr)
|
|
{
|
|
m_pActiveBrush = CreateBrush(clr);
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetPen(COLORREF clrPen, int nWidth)
|
|
{
|
|
SAFE_DELETE(m_pActivePen);
|
|
|
|
if (nWidth)
|
|
{
|
|
m_pActivePen = new Pen(ColorRefToARGB(clrPen), (REAL)nWidth);
|
|
}
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetTextColor(COLORREF clr)
|
|
{
|
|
m_pActiveTextBrush = CreateBrush(clr);
|
|
m_clrTextColor = clr;
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::SetFont(LOGFONT* lf)
|
|
{
|
|
SAFE_DELETE(m_pActiveFont);
|
|
if (!lf)
|
|
return;
|
|
|
|
m_pActiveFont = new Gdiplus::Font(m_hDC, lf);
|
|
m_lfActiveFont = *lf;
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawGrid(CRect rc, CPoint ptScrollOffset, double dZoomLevel, COLORREF clrGridColor)
|
|
{
|
|
double gap = 15.0 * dZoomLevel;
|
|
|
|
double x = -ptScrollOffset.x * dZoomLevel;
|
|
int cnt = int(x / gap);
|
|
x -= cnt * gap;
|
|
|
|
while (x < 0) x += gap;
|
|
while (x > gap) x -= gap;
|
|
|
|
|
|
SmoothingMode nSmoothingMode= m_pGraphics->GetSmoothingMode();
|
|
|
|
m_pGraphics->SetSmoothingMode(SmoothingModeHighSpeed);
|
|
|
|
|
|
Brush* pBrush = CreateBrush(clrGridColor);
|
|
|
|
for (x; x < rc.right; x += gap)
|
|
{
|
|
m_pGraphics->FillRectangle(pBrush, (int)x, rc.top, 1, rc.Width());
|
|
}
|
|
|
|
double y = -ptScrollOffset.y * dZoomLevel;
|
|
cnt = int(y / gap);
|
|
y -= cnt * gap;
|
|
|
|
while (y < 0) y += gap;
|
|
while (y > gap) y -= gap;
|
|
|
|
for (y; y < rc.bottom; y += gap)
|
|
{
|
|
m_pGraphics->FillRectangle(pBrush, rc.left, (int)y, rc.Width(), 1);
|
|
}
|
|
|
|
m_pGraphics->SetSmoothingMode(nSmoothingMode);
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::GradientFill(CRect rc, COLORREF clrFrom, COLORREF clrTo, BOOL bHoriz)
|
|
{
|
|
LinearGradientBrush brush(Rect(rc.left, rc.top, rc.Width(), rc.Height()),
|
|
ColorRefToARGB(clrFrom), ColorRefToARGB(clrTo), bHoriz ? LinearGradientModeHorizontal : LinearGradientModeVertical);
|
|
|
|
m_pGraphics->FillRectangle(&brush, rc.left, rc.top, rc.Width(), rc.Height());
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawImage(CXTPFlowGraphImage* pImage, CRect rc)
|
|
{
|
|
m_pGraphics->DrawImage(pImage->GetImage(), rc.left, rc.top, rc.Width(), rc.Height());
|
|
}
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::FillPolygon(const POINT* pts, int nCount)
|
|
{
|
|
m_pGraphics->FillPolygon(m_pActiveBrush, (Point*)pts, nCount);
|
|
|
|
}
|
|
|
|
|
|
#ifdef _XTP_DEMOMODE
|
|
|
|
void CXTPFlowGraphDrawContextGdiPlus::DrawWatermarkBackground(CRect rc)
|
|
{
|
|
m_pGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias);
|
|
|
|
SolidBrush brush(Color(100, 102, 102, 102));
|
|
|
|
|
|
LOGFONT lf = {0};
|
|
lf.lfHeight = LONG(rc.Width() * 80 / 1000);
|
|
|
|
lf.lfWeight = FW_BOLD;
|
|
STRCPY_S(lf.lfFaceName, LF_FACESIZE, _T("Myraid Pro"));
|
|
|
|
Font font(m_hDC, &lf);
|
|
|
|
|
|
StringFormat stringFormat;
|
|
|
|
stringFormat.SetLineAlignment(StringAlignmentCenter);
|
|
stringFormat.SetAlignment(StringAlignmentCenter);
|
|
|
|
RectF rcRect((float)rc.left, (float)rc.top, (float)rc.Width(), (float)rc.Height());
|
|
m_pGraphics->DrawString(L"Codejock Chart Pro Trial", -1, &font, rcRect, &stringFormat, &brush);
|
|
|
|
}
|
|
#endif
|