/** * @file XTPMarkupImage.cpp * * @copyright * (c) 1998-2025 Codejock Software, All Rights Reserved. * * This source file is the property of Codejock Software and must not be * redistributed by any means without the explicit written permission of * Codejock Software. * * The use of this source code is governed by the terms and conditions specified * in the Toolkit Pro license agreement. Codejock Software grants you, as a * single software developer, the limited right to use this software on one * computer only. * * Contact Information: * support@codejock.com * http://www.codejock.com * */ #include "stdafx.h" #include "GraphicLibrary/GdiPlus/XTPGdiPlus.h" #include "Common/XTPTypeId.h" #include "Common/XTPFramework.h" #include "Common/XTPSystemHelpers.h" #include "Common/XTPSynchro.h" #include "Common/XTPApplication.h" #include "Common/XTPSingleton.h" #include "Common/XTPGdiObjects.h" #include "Common/XTPResourceManager.h" #include "Common/Base/Types/XTPSize.h" #include #include "Markup/XTPMarkupContext.h" #include "Markup/XTPMarkupObject.h" #include "Markup/XTPMarkupString.h" #include "Markup/XTPMarkupInputElement.h" #include "Markup/XTPMarkupUIElement.h" #include "Markup/XTPMarkupFrameworkElement.h" #include "Markup/Shapes/XTPMarkupShape.h" #include "Markup/XTPMarkupDrawingContext.h" #include "Markup/DeviceContext/XTPMarkupDeviceContext.h" #include "Markup/DeviceContext/XTPMarkupDeviceDependentImage.h" #include "Markup/XTPMarkupBuilder.h" #include "Markup/Controls/XTPMarkupImage.h" #include "Markup/XTPMarkupIIDs.h" #include "Common/Base/Diagnostic/XTPDisableNoisyWarnings.h" #ifdef _DEBUG # undef THIS_FILE static char THIS_FILE[] = __FILE__; # define new DEBUG_NEW #endif CXTPMarkupDependencyProperty* CXTPMarkupImage::m_pSourceProperty = NULL; CXTPMarkupDependencyProperty* CXTPMarkupImage::m_pStretchProperty = NULL; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_MARKUPCLASS(L"Image", CXTPMarkupImage, CXTPMarkupFrameworkElement) void CXTPMarkupImage::RegisterMarkupClass() { m_pSourceProperty = CXTPMarkupDependencyProperty::Register( L"Source", MARKUP_TYPE(CXTPMarkupString), MARKUP_TYPE(CXTPMarkupImage), new CXTPMarkupPropertyMetadata(NULL, CXTPMarkupPropertyMetadata::flagAffectsMeasure | CXTPMarkupPropertyMetadata::flagAffectsArrange | CXTPMarkupPropertyMetadata::flagAffectsParentMeasure | CXTPMarkupPropertyMetadata::flagAffectsParentArrange | CXTPMarkupPropertyMetadata::flagAffectsRender)); m_pStretchProperty = CXTPMarkupDependencyProperty::Register( L"Stretch", MARKUP_TYPE(CXTPMarkupEnum), MARKUP_TYPE(CXTPMarkupImage), new CXTPMarkupPropertyMetadata(CXTPMarkupEnum::CreateValue(xtpMarkupStretchUniform), &CXTPMarkupBuilder::ConvertStretch, CXTPMarkupPropertyMetadata::flagAffectsMeasure)); } CXTPMarkupImage::CXTPMarkupImage() : m_pDeviceImage(NULL) { } CXTPMarkupImage::~CXTPMarkupImage() { if (NULL != m_pMarkupContext) m_pMarkupContext->FreeCachedImages(); SAFE_RELEASE(m_pDeviceImage); } void CXTPMarkupImage::SetStretch(XTPMarkupStretch stretch) { SetValue(m_pStretchProperty, CXTPMarkupEnum::CreateValue(stretch)); } CString CXTPMarkupImage::GetSource() { CXTPMarkupString* pSource = MARKUP_DYNAMICCAST(CXTPMarkupString, GetValue(m_pSourceProperty)); return CString(NULL != pSource ? XTP_CW2CT((LPCWSTR)*pSource) : _T("")); } void CXTPMarkupImage::SetSource(LPCTSTR lpszSource) { SetValue(m_pSourceProperty, new CXTPMarkupString(lpszSource)); } AFX_INLINE BOOL IsPositiveInfinity(int size) { return size > 32000; } CSize CXTPMarkupImage::GetOriginalSize() const { CSize szRet(0, 0); if (NULL != m_pDeviceImage) { szRet = m_pDeviceImage->GetSize(); if (NULL != m_pMarkupContext) { szRet = m_pMarkupContext->Scale(szRet); } } return szRet; } void CXTPMarkupImage::CreateImageInstance(CXTPMarkupDrawingContext* pDC) { _ASSERTE(NULL != pDC); SAFE_RELEASE(m_pDeviceImage); const CString& strSource = GetSource(); if (!strSource.IsEmpty()) { _ASSERTE(NULL != m_pMarkupContext); m_pDeviceImage = m_pMarkupContext->LoadImage(strSource, m_ConstraintSize, pDC->GetDeviceContext(), this); } } CSize CXTPMarkupImage::MeasureArrangeHelper(CSize availableSize) { CSize size(0, 0); if (NULL == m_pDeviceImage) return size; size = m_pDeviceImage->GetSize(); if (NULL != m_pMarkupContext) size = m_pMarkupContext->Scale(size); if (!(size.cx == 0 || size.cy == 0)) { XTPMarkupStretch stretch = GetStretch(); BOOL bWidth = !IsPositiveInfinity(availableSize.cx); BOOL bHeight = !IsPositiveInfinity(availableSize.cy); if (!((stretch == xtpMarkupStretchNone) || (!bWidth && !bHeight))) { double cx = (double)availableSize.cx / size.cx; double cy = (double)availableSize.cy / size.cy; if (!bWidth) { cx = cy; } else if (!bHeight) { cy = cx; } else { switch (stretch) { case xtpMarkupStretchUniform: cx = cy = min(cx, cy); break; case xtpMarkupStretchUniformToFill: cx = cy = max(cx, cy); break; } } size.cx = int(size.cx * cx); size.cy = int(size.cy * cy); } } return size; } CSize CXTPMarkupImage::MeasureOverride(CXTPMarkupDrawingContext* pDC, CSize constraint) { if (m_ConstraintSize != constraint || NULL == m_pDeviceImage) { m_ConstraintSize = constraint; CreateImageInstance(pDC); } return MeasureArrangeHelper(constraint); } CSize CXTPMarkupImage::ArrangeOverride(CSize arrangeSize) { return MeasureArrangeHelper(arrangeSize); } void CXTPMarkupImage::OnPropertyChanged(CXTPMarkupDependencyProperty* pProperty, CXTPMarkupObject* pOldValue, CXTPMarkupObject* pNewValue) { if (pProperty == m_pSourceProperty) SAFE_RELEASE(m_pDeviceImage); CXTPMarkupFrameworkElement::OnPropertyChanged(pProperty, pOldValue, pNewValue); } void CXTPMarkupImage::OnRender(CXTPMarkupDrawingContext* pDC) { if (NULL == m_pDeviceImage) CreateImageInstance(pDC); if (NULL != m_pDeviceImage) { CSize szRender = GetRenderSize(); pDC->DrawImage(m_pDeviceImage, CRect(0, 0, szRender.cx, szRender.cy)); } } // IXTPMarkupDeviceDependentImageSite overrides CXTPMarkupContext* CXTPMarkupImage::GetMarkupContext() { return m_pMarkupContext; } void CXTPMarkupImage::OnImageUpdateRequired() { InvalidateVisual(); } XTPMarkupStretch CXTPMarkupImage::GetStretch() const { CXTPMarkupEnum* pValue = MARKUP_DYNAMICCAST(CXTPMarkupEnum, GetValue(m_pStretchProperty)); return (pValue != NULL ? (XTPMarkupStretch)(int)*pValue : xtpMarkupStretchNone); } #include "Common/Base/Diagnostic/XTPBeginAfxMap.h" BEGIN_DISPATCH_MAP(CXTPMarkupImage, CXTPMarkupFrameworkElement) DISP_PROPERTY_EX_ID(CXTPMarkupImage, "Source", 500, OleGetSource, OleSetSource, VT_BSTR) DISP_PROPERTY_EX_ID(CXTPMarkupImage, "Stretch", 501, OleGetStretch, OleSetStretch, VT_I4) END_DISPATCH_MAP() #include "Common/Base/Diagnostic/XTPEndAfxMap.h" #ifdef _XTP_ACTIVEX BEGIN_INTERFACE_MAP(CXTPMarkupImage, CXTPMarkupFrameworkElement) INTERFACE_PART(CXTPMarkupImage, XTPDIID_MarkupImage, Dispatch) END_INTERFACE_MAP() IMPLEMENT_OLETYPELIB_EX(CXTPMarkupImage, XTPDIID_MarkupImage) #endif void CXTPMarkupImage::OleSetSource(LPCTSTR lpszSource) { SetSource(lpszSource); } BSTR CXTPMarkupImage::OleGetSource() { return GetSource().AllocSysString(); } long CXTPMarkupImage::OleGetStretch() { return GetStretch(); } void CXTPMarkupImage::OleSetStretch(long stretch) { SetStretch((XTPMarkupStretch)stretch); }