nim_duilib/duilib/Render/Render.cpp
jiajia_deng 4933d1f2bc Remove dependency on shared
Signed-off-by: jiajia_deng <2894220@gmail.com>
2019-09-20 16:27:58 +08:00

627 lines
22 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "StdAfx.h"
namespace ui {
static inline void DrawFunction(HDC hDC, bool bTransparent, UiRect rcDest, HDC hdcSrc, UiRect rcSrc, bool bAlphaChannel, int uFade)
{
if (bTransparent || bAlphaChannel || uFade < 255
|| (rcSrc.GetWidth() == rcDest.GetWidth() && rcSrc.GetHeight() == rcDest.GetHeight())) {
BLENDFUNCTION ftn = { AC_SRC_OVER, 0, uFade, AC_SRC_ALPHA };
::AlphaBlend(hDC, rcDest.left, rcDest.top, rcDest.GetWidth(), rcDest.GetHeight(),
hdcSrc, rcSrc.left, rcSrc.top, rcSrc.GetWidth(), rcSrc.GetHeight(), ftn);
}
else {
::StretchBlt(hDC, rcDest.left, rcDest.top, rcDest.GetWidth(), rcDest.GetHeight(),
hdcSrc, rcSrc.left, rcSrc.top, rcSrc.GetWidth(), rcSrc.GetHeight(), SRCCOPY);
}
}
RenderContext_GdiPlus::RenderContext_GdiPlus()
: m_hDC(NULL)
, m_hOldBitmap(NULL)
, m_bTransparent(false)
{
HDC hDC = ::GetDC(NULL);
m_hDC = ::CreateCompatibleDC(hDC);
::ReleaseDC(NULL, hDC);
ASSERT(m_hDC);
}
RenderContext_GdiPlus::~RenderContext_GdiPlus()
{
if (m_hOldBitmap != NULL)
{
::SelectObject(m_hDC, m_hOldBitmap);
m_hOldBitmap = NULL;
}
if (m_hDC != NULL)
{
::DeleteDC(m_hDC);
m_hDC = NULL;
}
}
HDC RenderContext_GdiPlus::GetDC()
{
return m_hDC;
}
bool RenderContext_GdiPlus::Resize(int width, int height, bool flipBItmap)
{
ASSERT(m_hDC);
if (m_bitmap.GetWidth() == width && m_bitmap.GetHeight() == height)
return false;
if (m_hOldBitmap != NULL)
{
::SelectObject(m_hDC, m_hOldBitmap);
}
bool ret = m_bitmap.Init(m_hDC, width, height, flipBItmap);
m_hOldBitmap = (HBITMAP)::SelectObject(m_hDC, m_bitmap.GetBitmap());
return ret;
}
void RenderContext_GdiPlus::Clear()
{
ASSERT(m_hDC);
m_bitmap.Clear();
}
std::unique_ptr<ui::IRenderContext> RenderContext_GdiPlus::Clone()
{
std::unique_ptr<ui::IRenderContext> pClone = std::make_unique<ui::RenderContext_GdiPlus>();
pClone->Resize(GetWidth(), GetHeight());
pClone->BitBlt(0, 0, GetWidth(), GetHeight(), m_hDC);
return pClone;
}
HBITMAP RenderContext_GdiPlus::DetachBitmap()
{
ASSERT(m_hDC && m_hOldBitmap);
ASSERT(m_bitmap.GetHeight() != 0 && m_bitmap.GetWidth() != 0);
if (m_hOldBitmap == NULL)
return NULL;
::SelectObject(m_hDC, m_hOldBitmap);
return m_bitmap.DetachBitmap();
}
BYTE* RenderContext_GdiPlus::GetBits()
{
return m_bitmap.GetBits();
}
int RenderContext_GdiPlus::GetWidth()
{
return m_bitmap.GetWidth();
}
int RenderContext_GdiPlus::GetHeight()
{
return m_bitmap.GetHeight();
}
void RenderContext_GdiPlus::ClearAlpha(const UiRect& rcDirty, int alpha)
{
m_bitmap.ClearAlpha(rcDirty, alpha);
}
void RenderContext_GdiPlus::RestoreAlpha(const UiRect& rcDirty, const UiRect& rcShadowPadding, int alpha)
{
m_bitmap.RestoreAlpha(rcDirty, rcShadowPadding, alpha);
}
bool RenderContext_GdiPlus::IsRenderTransparent() const
{
return m_bTransparent;
}
bool RenderContext_GdiPlus::SetRenderTransparent(bool bTransparent)
{
bool oldValue = m_bTransparent;
m_bTransparent = bTransparent;
return oldValue;
}
void RenderContext_GdiPlus::Save()
{
m_saveDC = SaveDC(m_hDC);
}
void RenderContext_GdiPlus::Restore()
{
RestoreDC(m_hDC, m_saveDC);
}
CPoint RenderContext_GdiPlus::OffsetWindowOrg(CPoint ptOffset)
{
CPoint ptOldWindowOrg;
GetWindowOrgEx(m_hDC, &ptOldWindowOrg);
ptOffset.Offset(ptOldWindowOrg.x, ptOldWindowOrg.y);
::SetWindowOrgEx(m_hDC, ptOffset.x, ptOffset.y, NULL);
return ptOldWindowOrg;
}
CPoint RenderContext_GdiPlus::SetWindowOrg(CPoint ptOffset)
{
CPoint ptOldWindowOrg;
GetWindowOrgEx(m_hDC, &ptOldWindowOrg);
::SetWindowOrgEx(m_hDC, ptOffset.x, ptOffset.y, NULL);
return ptOldWindowOrg;
}
CPoint RenderContext_GdiPlus::GetWindowOrg() const
{
CPoint ptWindowOrg;
GetWindowOrgEx(m_hDC, &ptWindowOrg);
return ptWindowOrg;
}
void RenderContext_GdiPlus::SetClip(const UiRect& rc)
{
m_clip.CreateClip(m_hDC, rc);
}
void RenderContext_GdiPlus::SetRoundClip(const UiRect& rc, int width, int height)
{
m_clip.CreateRoundClip(m_hDC, rc, width, height);
}
void RenderContext_GdiPlus::ClearClip()
{
m_clip.ClearClip(m_hDC);
}
HRESULT RenderContext_GdiPlus::BitBlt(int x, int y, int cx, int cy, HDC hdcSrc, int xSrc /*= 0*/, int yScr /*= 0*/, DWORD rop /*= SRCCOPY*/)
{
return ::BitBlt(m_hDC, x, y, cx, cy, hdcSrc, xSrc, yScr, rop);
}
bool RenderContext_GdiPlus::AlphaBlend(int xDest, int yDest, int widthDest, int heightDest, HDC hdcSrc, int xSrc, int yScr, int widthSrc, int heightSrc, BYTE uFade /*= 255*/)
{
BLENDFUNCTION bf = { AC_SRC_OVER, 0, uFade, AC_SRC_ALPHA };
return (TRUE == ::AlphaBlend(m_hDC, xDest, yDest, widthDest, heightDest, hdcSrc, xSrc, yScr, widthSrc, heightSrc, bf));
}
void RenderContext_GdiPlus::DrawImage(const UiRect& rcPaint, HBITMAP hBitmap, bool bAlphaChannel,
const UiRect& rcImageDest, const UiRect& rcImageSource, const UiRect& rcCorners, BYTE uFade /*= 255*/, bool xtiled /*= false*/, bool ytiled /*= false*/)
{
UiRect rcTestTemp;
if (!::IntersectRect(&rcTestTemp, &rcImageDest, &rcPaint)) return;
ASSERT(::GetObjectType(m_hDC) == OBJ_DC || ::GetObjectType(m_hDC) == OBJ_MEMDC);
if (hBitmap == NULL) return;
HDC hCloneDC = ::CreateCompatibleDC(m_hDC);
HBITMAP hOldBitmap = (HBITMAP) ::SelectObject(hCloneDC, hBitmap);
int stretchBltMode = ::SetStretchBltMode(m_hDC, HALFTONE);
UiRect rcTemp;
UiRect rcSource;
UiRect rcDest;
UiRect rcDpiCorner = rcCorners;
DpiManager::GetInstance()->ScaleRect(rcDpiCorner);
// middle
rcDest.left = rcImageDest.left + rcDpiCorner.left;
rcDest.top = rcImageDest.top + rcDpiCorner.top;
rcDest.right = rcImageDest.right - rcDpiCorner.right;
rcDest.bottom = rcImageDest.bottom - rcDpiCorner.bottom;
rcSource.left = rcImageSource.left + rcCorners.left;
rcSource.top = rcImageSource.top + rcCorners.top;
rcSource.right = rcImageSource.right - rcCorners.right;
rcSource.bottom = rcImageSource.bottom - rcCorners.bottom;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
if (!xtiled && !ytiled) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
else if (xtiled && ytiled) {
LONG lWidth = rcImageSource.right - rcImageSource.left - rcCorners.left - rcCorners.right;
LONG lHeight = rcImageSource.bottom - rcImageSource.top - rcCorners.top - rcCorners.bottom;
int iTimesX = (rcDest.right - rcDest.left + lWidth - 1) / lWidth;
int iTimesY = (rcDest.bottom - rcDest.top + lHeight - 1) / lHeight;
for (int j = 0; j < iTimesY; ++j) {
LONG lDestTop = rcDest.top + lHeight * j;
LONG lDestBottom = rcDest.top + lHeight * (j + 1);
LONG lDrawHeight = lHeight;
if (lDestBottom > rcDest.bottom) {
lDrawHeight -= lDestBottom - rcDest.bottom;
lDestBottom = rcDest.bottom;
}
for (int i = 0; i < iTimesX; ++i) {
LONG lDestLeft = rcDest.left + lWidth * i;
LONG lDestRight = rcDest.left + lWidth * (i + 1);
LONG lDrawWidth = lWidth;
if (lDestRight > rcDest.right) {
lDrawWidth -= lDestRight - rcDest.right;
lDestRight = rcDest.right;
}
rcDest.left = rcDest.left + lWidth * i;
rcDest.top = rcDest.top + lHeight * j;
rcDest.right = rcDest.left + lDestRight - lDestLeft;
rcDest.bottom = rcDest.top + lDestBottom - lDestTop;
rcSource.left = rcImageSource.left + rcCorners.left;
rcSource.top = rcImageSource.top + rcCorners.top;
rcSource.right = rcSource.left + lDrawWidth;
rcSource.bottom = rcSource.top + lDrawHeight;
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
}
else if (xtiled) {
LONG lWidth = rcImageSource.right - rcImageSource.left - rcCorners.left - rcCorners.right;
int iTimes = (rcDest.right - rcDest.left + lWidth - 1) / lWidth;
for (int i = 0; i < iTimes; ++i) {
LONG lDestLeft = rcDest.left + lWidth * i;
LONG lDestRight = rcDest.left + lWidth * (i + 1);
LONG lDrawWidth = lWidth;
if (lDestRight > rcDest.right) {
lDrawWidth -= lDestRight - rcDest.right;
lDestRight = rcDest.right;
}
rcDest.left = lDestLeft;
rcDest.top = rcDest.top;
rcDest.right = lDestRight;
rcDest.bottom = rcDest.top + rcDest.bottom;
rcSource.left = rcImageSource.left + rcCorners.left;
rcSource.top = rcImageSource.top + rcCorners.top;
rcSource.right = rcSource.left + lDrawWidth;
rcSource.bottom = rcImageSource.bottom - rcCorners.bottom;
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
else { // ytiled
LONG lHeight = rcImageSource.bottom - rcImageSource.top - rcCorners.top - rcCorners.bottom;
int iTimes = (rcDest.bottom - rcDest.top + lHeight - 1) / lHeight;
for (int i = 0; i < iTimes; ++i) {
LONG lDestTop = rcDest.top + lHeight * i;
LONG lDestBottom = rcDest.top + lHeight * (i + 1);
LONG lDrawHeight = lHeight;
if (lDestBottom > rcDest.bottom) {
lDrawHeight -= lDestBottom - rcDest.bottom;
lDestBottom = rcDest.bottom;
}
rcDest.left = rcDest.left;
rcDest.top = rcDest.top + lHeight * i;
rcDest.right = rcDest.left + rcDest.right;
rcDest.bottom = rcDest.top + lDestBottom - lDestTop;
rcSource.left = rcImageSource.left + rcCorners.left;
rcSource.top = rcImageSource.top + rcCorners.top;
rcSource.right = rcImageSource.right - rcCorners.right;
rcSource.bottom = rcSource.top + lDrawHeight;
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
}
// left-top
if (rcCorners.left > 0 && rcCorners.top > 0) {
rcDest.left = rcImageDest.left;
rcDest.top = rcImageDest.top;
rcDest.right = rcImageDest.left + rcDpiCorner.left;
rcDest.bottom = rcImageDest.top + rcDpiCorner.top;
rcSource.left = rcImageSource.left;
rcSource.top = rcImageSource.top;
rcSource.right = rcImageSource.left + rcCorners.left;
rcSource.bottom = rcImageSource.top + rcCorners.top;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// top
if (rcCorners.top > 0) {
rcDest.left = rcImageDest.left + rcDpiCorner.left;
rcDest.top = rcImageDest.top;
rcDest.right = rcImageDest.right - rcDpiCorner.right;
rcDest.bottom = rcImageDest.top + rcDpiCorner.top;
rcSource.left = rcImageSource.left + rcCorners.left;
rcSource.top = rcImageSource.top;
rcSource.right = rcImageSource.right - rcCorners.right;
rcSource.bottom = rcImageSource.top + rcCorners.top;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// right-top
if (rcCorners.right > 0 && rcCorners.top > 0) {
rcDest.left = rcImageDest.right - rcDpiCorner.right;
rcDest.top = rcImageDest.top;
rcDest.right = rcImageDest.right;
rcDest.bottom = rcImageDest.top + rcDpiCorner.top;
rcSource.left = rcImageSource.right - rcCorners.right;
rcSource.top = rcImageSource.top;
rcSource.right = rcImageSource.right;
rcSource.bottom = rcImageSource.top + rcCorners.top;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// left
if (rcCorners.left > 0) {
rcDest.left = rcImageDest.left;
rcDest.top = rcImageDest.top + rcDpiCorner.top;
rcDest.right = rcImageDest.left + rcDpiCorner.left;
rcDest.bottom = rcImageDest.bottom - rcDpiCorner.bottom;
rcSource.left = rcImageSource.left;
rcSource.top = rcImageSource.top + rcCorners.top;
rcSource.right = rcImageSource.left + rcCorners.left;
rcSource.bottom = rcImageSource.bottom - rcCorners.bottom;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// right
if (rcCorners.right > 0) {
rcDest.left = rcImageDest.right - rcDpiCorner.right;
rcDest.top = rcImageDest.top + rcDpiCorner.top;
rcDest.right = rcImageDest.right;
rcDest.bottom = rcImageDest.bottom - rcDpiCorner.bottom;
rcSource.left = rcImageSource.right - rcCorners.right;
rcSource.top = rcImageSource.top + rcCorners.top;
rcSource.right = rcImageSource.right;
rcSource.bottom = rcImageSource.bottom - rcCorners.bottom;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// left-bottom
if (rcCorners.left > 0 && rcCorners.bottom > 0) {
rcDest.left = rcImageDest.left;
rcDest.top = rcImageDest.bottom - rcDpiCorner.bottom;
rcDest.right = rcImageDest.left + rcDpiCorner.left;
rcDest.bottom = rcImageDest.bottom;
rcSource.left = rcImageSource.left;
rcSource.top = rcImageSource.bottom - rcCorners.bottom;
rcSource.right = rcImageSource.left + rcCorners.left;
rcSource.bottom = rcImageSource.bottom;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// bottom
if (rcCorners.bottom > 0) {
rcDest.left = rcImageDest.left + rcDpiCorner.left;
rcDest.top = rcImageDest.bottom - rcDpiCorner.bottom;
rcDest.right = rcImageDest.right - rcDpiCorner.right;
rcDest.bottom = rcImageDest.bottom;
rcSource.left = rcImageSource.left + rcCorners.left;
rcSource.top = rcImageSource.bottom - rcCorners.bottom;
rcSource.right = rcImageSource.right - rcCorners.right;
rcSource.bottom = rcImageSource.bottom;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
// right-bottom
if (rcCorners.right > 0 && rcCorners.bottom > 0) {
rcDest.left = rcImageDest.right - rcDpiCorner.right;
rcDest.top = rcImageDest.bottom - rcDpiCorner.bottom;
rcDest.right = rcImageDest.right;
rcDest.bottom = rcImageDest.bottom;
rcSource.left = rcImageSource.right - rcCorners.right;
rcSource.top = rcImageSource.bottom - rcCorners.bottom;
rcSource.right = rcImageSource.right;
rcSource.bottom = rcImageSource.bottom;
if (::IntersectRect(&rcTemp, &rcPaint, &rcDest)) {
DrawFunction(m_hDC, m_bTransparent, rcDest, hCloneDC, rcSource, bAlphaChannel, uFade);
}
}
::SetStretchBltMode(m_hDC, stretchBltMode);
::SelectObject(hCloneDC, hOldBitmap);
::DeleteDC(hCloneDC);
}
void RenderContext_GdiPlus::DrawColor(const UiRect& rc, DWORD dwColor, BYTE uFade)
{
DWORD dwNewColor = dwColor;
if (uFade < 255) {
int alpha = dwColor >> 24;
dwNewColor = dwColor % 0xffffff;
alpha *= double(uFade) / 255;
dwNewColor += alpha << 24;
}
Gdiplus::Graphics graphics(m_hDC);
Gdiplus::Color color(dwNewColor);
Gdiplus::SolidBrush brush(color);
Gdiplus::RectF rcFill(rc.left, rc.top, rc.GetWidth(), rc.GetHeight());
graphics.FillRectangle(&brush, rcFill);
}
void RenderContext_GdiPlus::DrawColor(const UiRect& rc, const std::wstring& colorStr, BYTE uFade)
{
if (colorStr.empty()) {
return;
}
DWORD dwColor = GlobalManager::GetTextColor(colorStr);
DrawColor(rc, dwColor, uFade);
}
void RenderContext_GdiPlus::DrawLine(const UiRect& rc, int nSize, DWORD dwPenColor)
{
Gdiplus::Graphics graphics(m_hDC);
Gdiplus::Pen pen(Gdiplus::Color(dwPenColor), (Gdiplus::REAL)nSize);
graphics.DrawLine(&pen, Gdiplus::Point(rc.left, rc.top), Gdiplus::Point(rc.right, rc.bottom));
}
void RenderContext_GdiPlus::DrawLine(const IPen* pen, int x1, int y1, int x2, int y2)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
graphics.DrawLine(((Pen_GdiPlus*)pen)->GetPen(), x1, y1, x2, y2);
}
void RenderContext_GdiPlus::DrawBezier(const IPen* pen, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
graphics.DrawBezier(((Pen_GdiPlus*)pen)->GetPen(), x1, y1, x2, y2, x3, y3, x4, y4);
}
void RenderContext_GdiPlus::DrawRect(const UiRect& rc, int nSize, DWORD dwPenColor)
{
Gdiplus::Graphics graphics(m_hDC);
Gdiplus::Pen pen(Gdiplus::Color(dwPenColor), (Gdiplus::REAL)nSize);
graphics.DrawRectangle(&pen, rc.left, rc.top, rc.GetWidth(), rc.GetHeight());
}
void RenderContext_GdiPlus::DrawRoundRect(const UiRect& rc, const CSize& roundSize, int nSize, DWORD dwPenColor)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
Gdiplus::Pen pen(Gdiplus::Color(dwPenColor), (Gdiplus::REAL)nSize);
// <20>ü<EFBFBD><C3BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>±߿<C2B1><DFBF><EFBFBD>ʱ<EFBFBD><CAB1>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// UiRect rcInflate = rc;
// rcInflate.Inflate({ -1, -1, -1, -1 });
Gdiplus::GraphicsPath pPath;
pPath.AddArc(rc.left, rc.top, roundSize.cx, roundSize.cy, 180, 90);
pPath.AddLine(rc.left + roundSize.cx, rc.top, rc.right - roundSize.cx, rc.top);
pPath.AddArc(rc.right - roundSize.cx, rc.top, roundSize.cx, roundSize.cy, 270, 90);
pPath.AddLine(rc.right, rc.top + roundSize.cy, rc.right, rc.bottom - roundSize.cy);
pPath.AddArc(rc.right - roundSize.cx, rc.bottom - roundSize.cy, roundSize.cx, roundSize.cy, 0, 90);
pPath.AddLine(rc.right - roundSize.cx, rc.bottom, rc.left + roundSize.cx, rc.bottom);
pPath.AddArc(rc.left, rc.bottom - roundSize.cy, roundSize.cx, roundSize.cy, 90, 90);
pPath.AddLine(rc.left, rc.bottom - roundSize.cy, rc.left, rc.top + roundSize.cy);
pPath.CloseFigure();
graphics.DrawPath(&pen, &pPath);
}
void RenderContext_GdiPlus::DrawText(const UiRect& rc, const std::wstring& strText, DWORD dwTextColor, const std::wstring& strFontId, UINT uStyle, BYTE uFade /*= 255*/, bool bLineLimit /*= false*/)
{
ASSERT(::GetObjectType(m_hDC) == OBJ_DC || ::GetObjectType(m_hDC) == OBJ_MEMDC);
if (strText.empty()) return;
Gdiplus::Graphics graphics(m_hDC);
Gdiplus::Font font(m_hDC, GlobalManager::GetFont(strFontId));
Gdiplus::RectF rcPaint((Gdiplus::REAL)rc.left, (Gdiplus::REAL)rc.top, (Gdiplus::REAL)(rc.right - rc.left), (Gdiplus::REAL)(rc.bottom - rc.top));
int alpha = dwTextColor >> 24;
uFade *= double(alpha) / 255;
if (uFade == 255) {
uFade = 254;
}
Gdiplus::SolidBrush tBrush(Gdiplus::Color(uFade, GetBValue(dwTextColor), GetGValue(dwTextColor), GetRValue(dwTextColor)));
Gdiplus::StringFormat stringFormat = Gdiplus::StringFormat::GenericTypographic();
if ((uStyle & DT_END_ELLIPSIS) != 0) {
stringFormat.SetTrimming(Gdiplus::StringTrimmingEllipsisCharacter);
}
int formatFlags = 0;
if ((uStyle & DT_NOCLIP) != 0) {
formatFlags |= Gdiplus::StringFormatFlagsNoClip;
}
if ((uStyle & DT_SINGLELINE) != 0) {
formatFlags |= Gdiplus::StringFormatFlagsNoWrap;
}
if (bLineLimit) {
formatFlags |= Gdiplus::StringFormatFlagsLineLimit;
}
stringFormat.SetFormatFlags(formatFlags);
if ((uStyle & DT_LEFT) != 0) {
stringFormat.SetAlignment(Gdiplus::StringAlignmentNear);
}
else if ((uStyle & DT_CENTER) != 0) {
stringFormat.SetAlignment(Gdiplus::StringAlignmentCenter);
}
else if ((uStyle & DT_RIGHT) != 0) {
stringFormat.SetAlignment(Gdiplus::StringAlignmentFar);
}
else {
stringFormat.SetAlignment(Gdiplus::StringAlignmentNear);
}
if ((uStyle & DT_TOP) != 0) {
stringFormat.SetLineAlignment(Gdiplus::StringAlignmentNear);
}
else if ((uStyle & DT_VCENTER) != 0) {
TFontInfo* fontInfo = GlobalManager::GetTFontInfo(strFontId);
if (fontInfo->sFontName == L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>") {
if (rcPaint.Height >= fontInfo->iSize + 2) {
rcPaint.Offset(0, 1);
}
}
stringFormat.SetLineAlignment(Gdiplus::StringAlignmentCenter);
}
else if ((uStyle & DT_BOTTOM) != 0) {
stringFormat.SetLineAlignment(Gdiplus::StringAlignmentFar);
}
else {
stringFormat.SetLineAlignment(Gdiplus::StringAlignmentNear);
}
graphics.DrawString(strText.c_str(), (int)strText.length(), &font, rcPaint, &stringFormat, &tBrush);
}
void RenderContext_GdiPlus::DrawEllipse(const UiRect& rc, int nSize, DWORD dwColor)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
Gdiplus::Pen pen(dwColor, nSize);
graphics.DrawEllipse(&pen, rc.left, rc.top, rc.GetWidth(), rc.GetHeight());
}
void RenderContext_GdiPlus::FillEllipse(const UiRect& rc, DWORD dwColor)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
Gdiplus::SolidBrush brush(dwColor);
graphics.FillEllipse(&brush, rc.left, rc.top, rc.GetWidth(), rc.GetHeight());
}
void RenderContext_GdiPlus::DrawPath(const IPath* path, const IPen* pen)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
graphics.DrawPath(((Pen_GdiPlus*)pen)->GetPen(), ((Path_Gdiplus*)path)->GetPath());
}
void RenderContext_GdiPlus::FillPath(const IPath* path, const IBrush* brush)
{
Gdiplus::Graphics graphics(m_hDC);
graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
graphics.FillPath(((Brush_Gdiplus*)brush)->GetBrush(), ((Path_Gdiplus*)path)->GetPath());
}
ui::UiRect RenderContext_GdiPlus::MeasureText(const std::wstring& strText, const std::wstring& strFontId, UINT uStyle, int width /*= DUI_NOSET_VALUE*/)
{
Gdiplus::Graphics graphics(m_hDC);
Gdiplus::Font font(m_hDC, GlobalManager::GetFont(strFontId));
Gdiplus::RectF bounds;
Gdiplus::StringFormat stringFormat = Gdiplus::StringFormat::GenericTypographic();
int formatFlags = 0;
if ((uStyle & DT_SINGLELINE) != 0) {
formatFlags |= Gdiplus::StringFormatFlagsNoWrap;
}
stringFormat.SetFormatFlags(formatFlags);
if (width == DUI_NOSET_VALUE) {
graphics.MeasureString(strText.c_str(), (int)strText.length(), &font, Gdiplus::PointF(), &stringFormat, &bounds);
}
else {
Gdiplus::REAL height = 0;
if ((uStyle & DT_SINGLELINE) != 0) {
Gdiplus::RectF rcEmpty((Gdiplus::REAL)0, (Gdiplus::REAL)0, (Gdiplus::REAL)0, (Gdiplus::REAL)0);
graphics.MeasureString(L"<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 2, &font, rcEmpty, &stringFormat, &bounds);
height = bounds.Height;
}
Gdiplus::RectF rcText((Gdiplus::REAL)0, (Gdiplus::REAL)0, (Gdiplus::REAL)width, height);
graphics.MeasureString(strText.c_str(), (int)strText.length(), &font, rcText, &stringFormat, &bounds);
}
UiRect rc(int(bounds.GetLeft()), int(bounds.GetTop()), int(bounds.GetRight() + 1), int(bounds.GetBottom() + 1));
return rc;
}
} // namespace ui