diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_pmp/graphics.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_pmp/graphics.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_pmp/graphics.cpp | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_pmp/graphics.cpp b/Src/Plugins/Library/ml_pmp/graphics.cpp new file mode 100644 index 00000000..8fbfaecb --- /dev/null +++ b/Src/Plugins/Library/ml_pmp/graphics.cpp @@ -0,0 +1,316 @@ +#include "main.h" +#include "./graphics.h" + +BYTE +Graphics_GetSysFontQuality() +{ + BOOL smoothingEnabled; + if (FALSE == SystemParametersInfoW(SPI_GETFONTSMOOTHING, 0, &smoothingEnabled, 0) || + FALSE == smoothingEnabled) + { + return DEFAULT_QUALITY; + } + + OSVERSIONINFOW vi; + vi.dwOSVersionInfoSize = sizeof(vi); + if (FALSE == GetVersionExW(&vi)) + return DEFAULT_QUALITY; + + if (vi.dwMajorVersion > 5 || (vi.dwMajorVersion == 5 && vi.dwMinorVersion >= 1)) + { + UINT smootingType; + if (FALSE == SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &smootingType, 0)) + return DEFAULT_QUALITY; + + if (FE_FONTSMOOTHINGCLEARTYPE == smootingType) + return CLEARTYPE_NATURAL_QUALITY/*CLEARTYPE_QUALITY*/; + } + + return ANTIALIASED_QUALITY; +} + +HFONT +Graphics_CreateSysFont() +{ + LOGFONTW lf; + HFONT font; + + if (FALSE == SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0)) + return NULL; + + lf.lfQuality = Graphics_GetSysFontQuality(); + font = CreateFontIndirectW(&lf); + + return font; +} + +HFONT +Graphics_DuplicateFont(HFONT sourceFont, INT heightDeltaPt, BOOL forceBold, BOOL systemQuality) +{ + LOGFONTW lf; + + if (NULL == sourceFont) + return NULL; + + + if (sizeof(lf) != GetObjectW(sourceFont, sizeof(lf), &lf)) + return NULL; + + if (0 != heightDeltaPt) + { + HDC hdc, hdcTmp; + + hdc = GetDCEx(NULL, NULL, DCX_WINDOW | DCX_CACHE | DCX_NORESETATTRS); + hdcTmp = NULL; + + if (NULL != hdc) + { + hdcTmp = CreateCompatibleDC(hdc); + ReleaseDC(NULL, hdc); + } + + if (NULL == hdcTmp) + return NULL; + + LONG pixelsY = GetDeviceCaps(hdcTmp, LOGPIXELSY); + HFONT prevFont = SelectFont(hdcTmp, sourceFont); + + TEXTMETRICW tm; + if (FALSE != GetTextMetricsW(hdcTmp, &tm)) + { + INT basePt = MulDiv(tm.tmHeight - tm.tmInternalLeading, 72, pixelsY); + lf.lfHeight = -MulDiv((basePt + heightDeltaPt), pixelsY, 72); + + } + + SelectObject(hdcTmp, prevFont); + DeleteDC(hdcTmp); + } + + if (FALSE != systemQuality) + lf.lfQuality = Graphics_GetSysFontQuality(); + if (FALSE != forceBold && lf.lfWeight < FW_BOLD) + lf.lfWeight = FW_BOLD; + + return CreateFontIndirectW(&lf); +} + +long +Graphics_GetFontHeight(HDC hdc) +{ + TEXTMETRICW tm; + if (FALSE == GetTextMetricsW(hdc, &tm)) + return 0; + + return tm.tmHeight; +} + +long +Graphics_GetAveStrWidth(HDC hdc, UINT cchLen) +{ + const char szTest[] = + { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j','k','l', 'm','n','o','p','q','r','s','t','u','v','w','x','y','z' + }; + + SIZE textSize; + if (FALSE == GetTextExtentPointA(hdc, szTest, ARRAYSIZE(szTest) -1, &textSize)) + return 0; + + LONG result; + if (1 == cchLen) + { + result = (textSize.cx + ARRAYSIZE(szTest)/2)/ARRAYSIZE(szTest); + } + else + { + result = MulDiv(cchLen, textSize.cx + ARRAYSIZE(szTest)/2, ARRAYSIZE(szTest)); + if (0 != result) + { + TEXTMETRICW tm; + if (FALSE != GetTextMetricsW(hdc, &tm)) + result += tm.tmOverhang; + } + } + return result; +} + +BOOL +Graphics_GetWindowBaseUnits(HWND hwnd, LONG *baseUnitX, LONG *baseUnitY) +{ + BOOL result; + result = FALSE; + + if (NULL != hwnd) + { + HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS); + if (NULL != hdc) + { + TEXTMETRICW tm; + HFONT font, prevFont; + + font = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L); + prevFont = SelectFont(hdc, font); + + if (FALSE != GetTextMetricsW(hdc, &tm)) + { + if (NULL != baseUnitX) + *baseUnitX = Graphics_GetAveStrWidth(hdc, 1); + + if (NULL != baseUnitY) + *baseUnitY = tm.tmHeight; + + result = TRUE; + } + + SelectFont(hdc, prevFont); + ReleaseDC(hwnd, hdc); + } + } + return result; +} + + +typedef int (*SkinColorFunc)(int idx); + +COLORREF Graphics_GetSkinColor(unsigned int colorIndex) +{ + static SkinColorFunc GetSkinColor = NULL; + + if (NULL == GetSkinColor) + { + GetSkinColor = (SkinColorFunc)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SKIN_WADLG_GETFUNC, 1); + if (NULL == GetSkinColor) + return RGB(255, 0, 255); + } + + return GetSkinColor(colorIndex); +} + +COLORREF +Graphics_BlendColors(COLORREF rgbTop, COLORREF rgbBottom, INT alpha) +{ + if (alpha > 254) return rgbTop; + if (alpha < 0) return rgbBottom; + + WORD k = (WORD)(((255 - alpha)*255 + 127)/255); + + return RGB( (GetRValue(rgbTop)*alpha + k*GetRValue(rgbBottom) + 127)/255, + (GetGValue(rgbTop)*alpha + k*GetGValue(rgbBottom) + 127)/255, + (GetBValue(rgbTop)*alpha + k*GetBValue(rgbBottom) + 127)/255); +} + +INT +Graphics_GetColorDistance(COLORREF rgb1, COLORREF rgb2) +{ + return (1000 * ((GetRValue(rgb1) - GetRValue(rgb2)) + + (GetGValue(rgb1) - GetGValue(rgb2)) + + (GetBValue(rgb1) - GetBValue(rgb2))))/ (3 * 255); +} + +void +Graphics_ClampRect(RECT *rect, const RECT *boxRect) +{ + if (rect->left < boxRect->left) + rect->left = boxRect->left; + + if (rect->top < boxRect->top) + rect->top = boxRect->top; + + if (rect->right > boxRect->right) + rect->right = boxRect->right; + + if (rect->bottom > boxRect->bottom) + rect->bottom = boxRect->bottom; +} + +void +Graphics_NormalizeRect(RECT *rect) +{ + if (rect->top > rect->bottom) + rect->bottom = rect->top; + + if (rect->left > rect->right) + rect->right = rect->left; +} + +void +Graphics_GetRectSizeNormalized(const RECT *rect, SIZE *size) +{ + size->cx = rect->right - rect->left; + if (size->cx < 0) + size->cx = 0; + + size->cy = rect->bottom - rect->top; + if (size->cy < 0) + size->cy = 0; +} + +BOOL +Graphics_IsRectFit(const RECT *rect, const RECT *boxRect) +{ + if (rect->left < boxRect->left || + rect->top < boxRect->top || + rect->right > boxRect->right || + rect->bottom > boxRect->bottom) + { + return FALSE; + } + + return TRUE; +} + + +BOOL SetSizeEmpty(SIZE *size) +{ + if (NULL == size) + return FALSE; + + ZeroMemory(size, sizeof(SIZE)); + return TRUE; +} + +BOOL IsSizeEmpty(SIZE *size) +{ + return (NULL == size || 0 == size->cx || 0 == size->cy); +} + +BOOL SetSize(SIZE *size, long width, long height) +{ + if (NULL == size) + return FALSE; + + size->cx = width; + size->cy = height; + + return TRUE; +} + +BOOL SetPoint(POINT *pt, long x, long y) +{ + if (NULL == pt) + return FALSE; + + pt->x = x; + pt->y = y; + + return TRUE; +} + +BOOL MakeRectPolygon(POINT vertices[4], long left, long top, long right, long bottom) +{ + if (NULL == vertices) + return FALSE; + + vertices[0].x = left; + vertices[0].y = top; + vertices[1].x = right; + vertices[1].y = top; + vertices[2].x = right; + vertices[2].y = bottom; + vertices[3].x = left; + vertices[3].y = bottom; + + return TRUE; +} |