//-----------------------------------------------------------------------------------------------------
//  Adjusts a 2D Bounding area to scale with screen and safe areas based on the current 
//  layout state.
//
//  in/out :
//  			fX,fY - in:  the position, in screen space of the asset's pivot i.e. the (center,left), (top,left) 
//  			             or (bottom,right) point of the asset (for example) (in Virtual Space)
//  			       out:  the top left corner of the BB after aligning and scaling with delta screen 
//  			             resolution and safe areas (out Virtual Space).
//  
//  			fSizeX,fSizeY - in:  the size of the BB before any alignment or adjustments are done (in Virtual Space)
//  			              - out: the size of the BB after all appropriate alignments and adjustments are done (out Virtual Space)
//
//  As we want to preserve proportional distance of elements from the screen 
//  edge then the p(x,y) needs to be adjusted based on some proportional
//  relationship to the delta-screen resolution :
//                     p (is-proportional-to) k*(delta)Screen
//  
//  The size of element s(w,h), when not preserving aspect or keeping square
//  should follow the same rule.
//                     s (is-propotional-to) k*(delta)Screen
//  
//  When scaling elements with (delta)ScreenY only, then p is the same as above
//  (to preserve proportional distance from the screen edge), but s(w.h) varies
//  as follows :
//                     s.w (is-propotional-to) k*(delta)ScreenY
//                     s.h (is-propotional-to) k*(delta)ScreenY
//
void ScreenLayoutManager::AdjustToSafeArea( float *fX, float* fY, float* fSizeX /* = NULL*/, float* fSizeY /* = NULL*/,
                                            const EUIDRAWHORIZONTAL eUIDrawHorizontal,        
                                            const EUIDRAWVERTICAL   eUIDrawVertical,
                                            const EUIDRAWHORIZONTAL eUIDrawHorizontalDocking, 
                                            const EUIDRAWVERTICAL   eUIDrawVerticalDocking  ) const
{
	//-----------------------------------------------
	// Get intermediate p(x,y) in proportional space
	// at this point the p is at still the (center,left),
	// (top,left) or (bottom,right) of the asset.
	Vec2 p( *fX/GetVirtualWidth(), *fY/GetVirtualHeight() );
	Vec2 s( 0.0f, 0.0f );
	float assetAspect = 1.0f;

	CRY_ASSERT_MESSAGE( fSizeX && fSizeY || (fSizeX == NULL && fSizeY == NULL), "HUD: Invalid combination of size pointers, probably a mistake in calling code!" );
	const bool bHaveSize = fSizeX && fSizeY && (*fSizeY)!=0.0f;
	if( bHaveSize)
	{
		s = Vec2( (*fSizeX)/GetVirtualWidth(), (*fSizeY)/GetVirtualHeight() );
		assetAspect = (*fSizeX)/(*fSizeY);
	}

	// Do the work and get every thing in proportional space.
	AdjustToSafeAreaProportional( p,s,assetAspect, eUIDrawHorizontal,eUIDrawVertical,eUIDrawHorizontalDocking,eUIDrawVerticalDocking );

	// offset p by the safe-area borders if we are adjusting by safe-areas.
	if( !(m_flags & eSLO_DoNotAdaptToSafeArea) )
	{
		const Vec2 safeAreaBorderP = GetSafeAreaBorderScreenProportion(m_curSafeAreaID);
		p.x += safeAreaBorderP.x; // x border width
		p.y += safeAreaBorderP.y; // y border height
	}

	// Publish the results :
	*fX = p.x * GetVirtualWidth();
	*fY = p.y * GetVirtualHeight();

	if(bHaveSize)
	{
		*fSizeX = s.x * GetVirtualWidth();
		*fSizeY = s.y * GetVirtualHeight();








	}
}
Exemplo n.º 2
0
void CDuiText::DrawControl(CDC &dc, CRect rcUpdate)
{
	int nWidth = m_rc.Width();
	int nHeight = m_rc.Height();
	
	// 计算显示位置
	CDuiScrollVertical* pScrollV = (CDuiScrollVertical*)m_pControScrollV;
	int nCurPos = pScrollV->GetScrollCurrentPos();	// 当前top位置
	int nMaxRange = pScrollV->GetScrollMaxRange();
	int nVirtualTop = 0;	// 当前显示的是虚拟图片中什么位置开始的图片
	m_nVirtualHeight = GetVirtualHeight();
	if(m_nVirtualHeight > m_rc.Height())
	{
		nVirtualTop = (nMaxRange > 0) ? nCurPos*(m_nVirtualHeight-m_rc.Height())/nMaxRange : 0;
	}else
	{
		nVirtualTop = 0;
	}

	if(!m_bUpdate)
	{
		UpdateMemDC(dc, nWidth, m_nVirtualHeight);

		Graphics graphics(m_memDC);
		
		if(m_bBack)
		{
			SolidBrush brush(m_clrBack);
			graphics.FillRectangle(&brush, 0, 0, nWidth, nHeight);
		}
		else
		{
			//m_memDC.BitBlt(0, 0, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, SRCCOPY);
			m_memDC.BitBlt(0, 0, nWidth, nHeight, &dc, m_rc.left ,m_rc.top, WHITENESS);	// 画白色背景
			DrawVerticalTransition(m_memDC, dc, CRect(0, 0+nVirtualTop, nWidth, nHeight+nVirtualTop),	// 背景透明度
					m_rc, m_nBkTransparent, m_nBkTransparent);
		}
		
		BSTR bsFont = m_strFont.AllocSysString();
		FontFamily fontFamily(bsFont);
		Font font(&fontFamily, (REAL)m_nFontWidth, m_fontStyle, UnitPixel);
		::SysFreeString(bsFont);

		SolidBrush solidBrush(m_clrText);
		
		graphics.SetTextRenderingHint( TextRenderingHintClearTypeGridFit );

		// 设置水平和垂直对齐方式
		DUI_STRING_ALIGN_DEFINE();

		//strFormat.SetFormatFlags( StringFormatFlagsNoWrap | StringFormatFlagsMeasureTrailingSpaces);
		strFormat.SetFormatFlags( StringFormatFlagsNoClip | StringFormatFlagsMeasureTrailingSpaces);
		//strFormat.SetTrimming(StringTrimmingEllipsisWord);	// 以单词为单位去尾,略去部分使用省略号

		int nXPos = 0;
		if(m_pImage != NULL)
		{
			graphics.DrawImage(m_pImage, Rect(0, (nHeight - m_sizeImage.cy) / 2, m_sizeImage.cx, m_sizeImage.cy),
				0, 0, m_sizeImage.cx, m_sizeImage.cy, UnitPixel);
			nXPos += m_sizeImage.cx + 5;
		}
		
		Size size = GetTextBounds(font, strFormat, nWidth, m_strTitle);
		
		int nStart = m_strTitle.Find(m_strMark, m_nStart);
		if(m_strMark.IsEmpty() || (nStart == -1))
		{
			int nTextWidth = nWidth - nXPos;
			if(m_bScrollV)
			{
				nTextWidth -= m_nScrollWidth;
			}

			// 先画阴影
			if(m_bEnableShadow)
			{
				RectF rectShadow((Gdiplus::REAL)(nXPos  + 1), (Gdiplus::REAL)1, (Gdiplus::REAL)nTextWidth, (Gdiplus::REAL)max(size.Height, nHeight));
				SolidBrush solidBrushS(m_clrTextShadow);
				BSTR bsTitle = m_strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rectShadow, &strFormat, &solidBrushS);
				::SysFreeString(bsTitle);
			}

			// 再画正常的文字
			RectF rect((Gdiplus::REAL)(nXPos), (Gdiplus::REAL)0, (Gdiplus::REAL)nTextWidth, (Gdiplus::REAL)(max(size.Height, nHeight)));
			if((m_enButtonState == enBSHover) && m_bEnableHover)
			{
				SolidBrush solidBrushH(m_clrTextHover);
				BSTR bsTitle = m_strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormat, &solidBrushH);
				::SysFreeString(bsTitle);
			}else
			{
				BSTR bsTitle = m_strTitle.AllocSysString();
				graphics.DrawString(bsTitle, (INT)wcslen(bsTitle), &font, rect, &strFormat, &solidBrush);
				::SysFreeString(bsTitle);
			}
		}
		else
		{
			SolidBrush solidBrushM(m_clrMark);
			SolidBrush solidBrushS(m_clrTextShadow);

			CString srtL = m_strTitle.Left(nStart);
			CString srtR  = m_strTitle.Right(m_strTitle.GetLength() - m_strMark.GetLength() - nStart);
			Size sizeL = GetTextBounds(font, strFormat, srtL);
			Size sizeM = GetTextBounds(font, strFormat, m_strMark);
			Size sizeR = GetTextBounds(font, strFormat, srtR);

			if(m_bEnableShadow)
			{
				BSTR bsL = srtL.AllocSysString();
				graphics.DrawString(bsL, (INT)wcslen(bsL), &font, 
					PointF((Gdiplus::REAL)(nXPos + 1), (Gdiplus::REAL)1), &strFormat, &solidBrushS);
				::SysFreeString(bsL);
				BSTR bsMark = m_strMark.AllocSysString();
				graphics.DrawString(bsMark, (INT)wcslen(bsMark), &font, 
					PointF((Gdiplus::REAL)(nXPos + sizeL.Width + 2 + 1), (Gdiplus::REAL)1), &strFormat, &solidBrushS);
				::SysFreeString(bsMark);
			}
			BSTR bsL = srtL.AllocSysString();
			graphics.DrawString(bsL, (INT)wcslen(bsL), &font, 
				PointF((Gdiplus::REAL)(nXPos), (Gdiplus::REAL)0), &strFormat, &solidBrush);
			::SysFreeString(bsL);
			BSTR bsMark = m_strMark.AllocSysString();
			graphics.DrawString(bsMark, (INT)wcslen(bsMark), &font, 
				PointF((Gdiplus::REAL)(nXPos + sizeL.Width + 2), (Gdiplus::REAL)0), &strFormat, &solidBrushM);
			::SysFreeString(bsMark);

			if(m_bEnableShadow)
			{
				RectF rect((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4 + 1), (Gdiplus::REAL)(1), (Gdiplus::REAL)(nWidth - (nXPos + sizeL.Width + sizeM.Width + 4)), (Gdiplus::REAL)nHeight);
				BSTR bsR = srtR.AllocSysString();
				graphics.DrawString(bsR, (INT)wcslen(bsR), &font, 
					PointF((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4), (Gdiplus::REAL)0), &strFormat, &solidBrushS);
				::SysFreeString(bsR);
			}
			//RectF rect(nXPos + point.x + sizeL.Width + sizeM.Width + 4, point.y, nWidth - (nXPos + sizeL.Width + sizeM.Width + 4 + point.x), size.Height);
			RectF rect((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4), (Gdiplus::REAL)0, (Gdiplus::REAL)(nWidth - (nXPos + sizeL.Width + sizeM.Width + 4)), (Gdiplus::REAL)nHeight);
			BSTR bsR = srtR.AllocSysString();
			graphics.DrawString(bsR, (INT)wcslen(bsR), &font, 
				PointF((Gdiplus::REAL)(nXPos + sizeL.Width + sizeM.Width + 4), (Gdiplus::REAL)0), &strFormat, &solidBrush);
			::SysFreeString(bsR);
		}
	}

	dc.BitBlt(m_rc.left,m_rc.top, m_rc.Width(), m_rc.Height(), &m_memDC, 0, nVirtualTop, SRCCOPY);
}