// XTPFlowGraphDrawContext.cpp : implementation of the CXTPFlowGraphDrawContext 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 #include "Common/XTPDrawHelpers.h" #include "Common/XTPResourceManager.h" #include "Common/XTPImageManager.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 "XTPFlowGraphControl.h" #include "XTPFlowGraphImage.h" using namespace Gdiplus; using namespace Gdiplus::DllExports; ////////////////////////////////////////////////////////////////////////// // CXTPFlowGraphDrawContext CXTPFlowGraphDrawContext::CXTPFlowGraphDrawContext(HDC hDC, HDC /*hAttribDC*/, BOOL bPrinting) { m_hDC = hDC; m_bPrinting = bPrinting; #if 0 SetSmoothingMode(0); #endif m_hActiveBrush = NULL; m_hActivePen = NULL; m_hActiveFont = NULL; ::GetClipBox(m_hDC, m_rcClipRect); } void CXTPFlowGraphDrawContext::SetSmoothingMode(int /*nMode*/) { } CXTPFlowGraphDrawContext::~CXTPFlowGraphDrawContext() { if (m_hActivePen) DeleteObject(m_hActivePen); } void CXTPFlowGraphDrawContext::SetWorldTransform(CPoint ptOffset, double dZoomLevel) { ::SetMapMode(m_hDC, MM_ANISOTROPIC); ::SetViewportExtEx(m_hDC, int(dZoomLevel * 96), int(dZoomLevel * 96), 0); ::SetWindowExtEx(m_hDC, int(96), int(96 ), 0); CSize m_sizeWinExt, m_sizeVpExt; ::GetWindowExtEx(m_hDC, &m_sizeWinExt); ::GetViewportExtEx(m_hDC, &m_sizeVpExt); SetViewportOrgEx(m_hDC, -ptOffset.x * m_sizeVpExt.cx / m_sizeWinExt.cx, -ptOffset.y * m_sizeVpExt.cy / m_sizeWinExt.cy, NULL); ::GetClipBox(m_hDC, m_rcClipRect); } void CXTPFlowGraphDrawContext::SetClipRect(CRect /*rc*/) { } CRect CXTPFlowGraphDrawContext::GetClipRect() const { return m_rcClipRect; } void CXTPFlowGraphDrawContext::Clear(COLORREF clr) { FillSolidRect(m_rcClipRect, clr); } void CXTPFlowGraphDrawContext::FillSolidRect(LPCRECT lpRect, COLORREF clr) { if ((clr & 0xFF000000) == 0) { ::SetBkColor(m_hDC, clr); ::ExtTextOut(m_hDC, 0, 0, ETO_OPAQUE, lpRect, NULL, 0, NULL); } else { LPDWORD lpBits; HBITMAP hBitmap = CXTPImageManager::Create32BPPDIBSection(m_hDC, 1, 1, (LPBYTE*)&lpBits); if (hBitmap) { lpBits[0] = RGB(GetBValue(clr), GetGValue(clr), GetRValue(clr)); HDC hDC = CreateCompatibleDC(m_hDC); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hDC, hBitmap); XTPImageManager()->AlphaBlend2(m_hDC, lpRect, hDC, CRect(0, 0, 1, 1), 100); SelectObject(hDC, hOldBitmap); DeleteObject(hBitmap); DeleteDC(hDC); } } } void CXTPFlowGraphDrawContext::FillSolidRect(int x, int y, int cx, int cy, COLORREF clr) { CRect rect(x, y, x + cx, y + cy); FillSolidRect(rect, clr); } void CXTPFlowGraphDrawContext::Draw3dRect(LPCRECT lpRect, COLORREF clrTopLeft, COLORREF clrBottomRight) { Draw3dRect(lpRect->left, lpRect->top, lpRect->right - lpRect->left, lpRect->bottom - lpRect->top, clrTopLeft, clrBottomRight); } void CXTPFlowGraphDrawContext::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 CXTPFlowGraphDrawContext::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 CXTPFlowGraphDrawContext::MeasureMarkupElement(CXTPMarkupUIElement* pMarkupUIElement) { pMarkupUIElement->GetMarkupContext()->SetDefaultFont(m_hActiveFont); CXTPMarkupDrawingContext dc(pMarkupUIElement->GetMarkupContext(), m_hDC); pMarkupUIElement->Measure(&dc, CSize(INT_MAX, INT_MAX)); CSize sz = pMarkupUIElement->GetDesiredSize(); return sz; } void CXTPFlowGraphDrawContext::DrawMarkupElement(CXTPMarkupUIElement* pMarkupUIElement, LPCRECT lpRect, UINT /*uFormat*/) { pMarkupUIElement->GetMarkupContext()->SetDefaultFont(m_hActiveFont); pMarkupUIElement->GetMarkupContext()->SetDefaultTextColor(::GetTextColor(m_hDC)); CXTPMarkupDrawingContext dc(pMarkupUIElement->GetMarkupContext(), m_hDC); pMarkupUIElement->Arrange(lpRect); pMarkupUIElement->Render(&dc); } CSize CXTPFlowGraphDrawContext::MeasureString(const CString& str) { if (!m_hActiveFont) return CSize(0, 0); HFONT hOldFont = (HFONT)SelectObject(m_hDC, m_hActiveFont); CSize sz; if (str.GetLength() != 0) { ::GetTextExtentPoint(m_hDC, str, str.GetLength(), &sz); } else { ::GetTextExtentPoint(m_hDC, _T(" "), 1, &sz); } ::SelectObject(m_hDC, hOldFont); return sz; } void CXTPFlowGraphDrawContext::DrawText(LPCTSTR lpszText, LPCRECT lpRect, UINT uFormat) { if (!m_hActiveFont) return; HFONT hOldFont = (HFONT)SelectObject(m_hDC, m_hActiveFont); ::SetBkMode(m_hDC, TRANSPARENT); ::DrawText(m_hDC, lpszText, (int)_tcslen(lpszText), (LPRECT)lpRect, uFormat | DT_SINGLELINE); ::SelectObject(m_hDC, hOldFont); } void CXTPFlowGraphDrawContext::DrawCurve(Gdiplus::GraphicsPath* pPath) { int nCount = pPath->GetPointCount(); Point* lppt = new Point[nCount]; pPath->GetPathPoints(lppt, nCount); BYTE* pTypes = new BYTE[nCount]; pPath->GetPathTypes(pTypes, nCount); CDC* pDC = CDC::FromHandle(m_hDC); int nIndex; Point* pptLastMoveTo = NULL; HPEN hOldPen = (HPEN)SelectObject(m_hDC, m_hActivePen); // for each of the points we have... for (nIndex = 0; nIndex 0) pDC->LineTo(pptLastMoveTo->X, pptLastMoveTo->Y); pDC->MoveTo(lppt[nIndex].X, lppt[nIndex].Y); pptLastMoveTo = &lppt[nIndex]; break; case PathPointTypeLine | PathPointTypeCloseSubpath: pDC->LineTo(lppt[nIndex].X, lppt[nIndex].Y); if (pptLastMoveTo != NULL) pDC->LineTo(pptLastMoveTo->X, pptLastMoveTo->Y); pptLastMoveTo = NULL; break; case PathPointTypeLine: pDC->LineTo(lppt[nIndex].X, lppt[nIndex].Y); break; case PathPointTypeBezier | PathPointTypeCloseSubpath: ASSERT(nIndex + 2 <= nCount); pDC->PolyBezierTo((POINT*)&lppt[nIndex], 3); nIndex += 2; if (pptLastMoveTo != NULL) pDC->LineTo(pptLastMoveTo->X, pptLastMoveTo->Y); pptLastMoveTo = NULL; break; case PathPointTypeBezier: ASSERT(nIndex + 2 <= nCount); pDC->PolyBezierTo((POINT*)&lppt[nIndex], 3); nIndex += 2; break; } } delete[] lppt; delete[] pTypes; SelectObject(m_hDC, hOldPen); } void CXTPFlowGraphDrawContext::Ellipse(LPCRECT lpRect) { HBRUSH hOldBrush = 0; HPEN hOldPen = 0; if (m_hActiveBrush) { hOldBrush = (HBRUSH)SelectObject(m_hDC, m_hActiveBrush); } if (m_hActivePen) { hOldPen = (HPEN)SelectObject(m_hDC, m_hActivePen); } else { hOldPen = (HPEN)SelectObject(m_hDC, GetStockObject(NULL_PEN)); } ::Ellipse(m_hDC, lpRect->left, lpRect->top, lpRect->right, lpRect->bottom); if (hOldBrush) { SelectObject(m_hDC, hOldBrush); } if (hOldPen) { SelectObject(m_hDC, hOldPen); } } void CXTPFlowGraphDrawContext::Line(float x1, float y1, float x2, float y2) { if (!m_hActivePen) return; HPEN hOldPen = 0; if (m_hActivePen) { hOldPen = (HPEN)SelectObject(m_hDC, m_hActivePen); } MoveToEx(m_hDC, (int)x1, (int)y1, 0); LineTo(m_hDC, (int)x2, (int)y2); if (hOldPen) { SelectObject(m_hDC, hOldPen); } } void CXTPFlowGraphDrawContext::SetBrush(COLORREF clr) { if (clr == (COLORREF)-1) m_hActiveBrush = 0; else m_hActiveBrush = m_arrBrushes.GetHandle(clr); } void CXTPFlowGraphDrawContext::SetPen(COLORREF clrPen, int nWidth) { if (m_hActivePen) { DeleteObject(m_hActivePen); m_hActivePen = 0; } if (nWidth) { m_hActivePen = ::CreatePen(PS_SOLID, nWidth, clrPen); } } void CXTPFlowGraphDrawContext::SetTextColor(COLORREF clr) { ::SetTextColor(m_hDC, clr); } void CXTPFlowGraphDrawContext::SetFont(LOGFONT* lf) { if (!lf) { m_hActiveFont = 0; } else { m_hActiveFont = m_arrFonts.GetHandle(*lf); } } void CXTPFlowGraphDrawContext::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; for (x; x < rc.right; x += gap) { FillSolidRect((int)x, rc.top, 1, rc.Width(), clrGridColor); } 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) { FillSolidRect(rc.left, (int)y, rc.Width(), 1,clrGridColor); } } void CXTPFlowGraphDrawContext::GradientFill(CRect rc, COLORREF clrFrom, COLORREF clrTo, BOOL bHoriz) { XTPDrawHelpers()->GradientFill(CDC::FromHandle(m_hDC), rc, clrFrom, clrTo, bHoriz); } void CXTPFlowGraphDrawContext::DrawImage(CXTPFlowGraphImage* pImage, CRect rc) { CXTPImageManagerIcon* pIcon = pImage->GetIcon(); if (pIcon) { pIcon->Draw(CDC::FromHandle(m_hDC), rc.TopLeft(), rc.Size()); } } void CXTPFlowGraphDrawContext::DrawSelectionRect(CRect rcSelectedArea) { COLORREF clrSelectionFrame = GetSysColor(COLOR_HIGHLIGHT); COLORREF clrSelection = clrSelectionFrame | 0x88000000; FillSolidRect(rcSelectedArea, clrSelection); Draw3dRect(rcSelectedArea, clrSelectionFrame, clrSelectionFrame); } void CXTPFlowGraphDrawContext::FillPolygon(const POINT* pts, int nCount) { HBRUSH hOldBrush = 0; HPEN hOldPen = 0; if (m_hActiveBrush) { hOldBrush = (HBRUSH)SelectObject(m_hDC, m_hActiveBrush); } if (m_hActivePen) { hOldPen = (HPEN)SelectObject(m_hDC, m_hActivePen); } else { hOldPen = (HPEN)SelectObject(m_hDC, GetStockObject(NULL_PEN)); } ::Polygon(m_hDC, pts, nCount); if (hOldBrush) { SelectObject(m_hDC, hOldBrush); } if (hOldPen) { SelectObject(m_hDC, hOldPen); } } #ifdef _XTP_DEMOMODE void CXTPFlowGraphDrawContext::DrawWatermarkBackground(CRect rc) { LOGFONT lf = {0}; lf.lfHeight = LONG(rc.Width() * 80 / 1000); lf.lfWeight = FW_BOLD; STRCPY_S(lf.lfFaceName, LF_FACESIZE, _T("Myraid Pro")); CFont font; font.CreateFontIndirect(&lf); HFONT hOldFont = (HFONT)SelectObject(m_hDC, font.GetSafeHandle()); SetTextColor(RGB(102, 102, 102)); ::SetBkMode(m_hDC, TRANSPARENT); ::DrawText(m_hDC, _T("Codejock Chart Pro Trial"), -1, rc, DT_VCENTER | DT_CENTER | DT_SINGLELINE); SelectObject(m_hDC, hOldFont); } #endif