graphics.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. #include "main.h"
  2. #include "./graphics.h"
  3. BYTE
  4. Graphics_GetSysFontQuality()
  5. {
  6. BOOL smoothingEnabled;
  7. if (FALSE == SystemParametersInfoW(SPI_GETFONTSMOOTHING, 0, &smoothingEnabled, 0) ||
  8. FALSE == smoothingEnabled)
  9. {
  10. return DEFAULT_QUALITY;
  11. }
  12. OSVERSIONINFOW vi;
  13. vi.dwOSVersionInfoSize = sizeof(vi);
  14. if (FALSE == GetVersionExW(&vi))
  15. return DEFAULT_QUALITY;
  16. if (vi.dwMajorVersion > 5 || (vi.dwMajorVersion == 5 && vi.dwMinorVersion >= 1))
  17. {
  18. UINT smootingType;
  19. if (FALSE == SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &smootingType, 0))
  20. return DEFAULT_QUALITY;
  21. if (FE_FONTSMOOTHINGCLEARTYPE == smootingType)
  22. return CLEARTYPE_NATURAL_QUALITY/*CLEARTYPE_QUALITY*/;
  23. }
  24. return ANTIALIASED_QUALITY;
  25. }
  26. HFONT
  27. Graphics_CreateSysFont()
  28. {
  29. LOGFONTW lf = {0};
  30. HFONT font = NULL;
  31. if (FALSE == SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
  32. return NULL;
  33. lf.lfQuality = Graphics_GetSysFontQuality();
  34. font = CreateFontIndirectW(&lf);
  35. return font;
  36. }
  37. HFONT
  38. Graphics_DuplicateFont(HFONT sourceFont, INT heightDeltaPt, BOOL forceBold, BOOL systemQuality)
  39. {
  40. LOGFONTW lf = {0};
  41. if (NULL == sourceFont)
  42. return NULL;
  43. if (sizeof(lf) != GetObjectW(sourceFont, sizeof(lf), &lf))
  44. return NULL;
  45. if (0 != heightDeltaPt)
  46. {
  47. HDC hdcTmp = NULL, hdc = GetDCEx(NULL, NULL, DCX_WINDOW | DCX_CACHE | DCX_NORESETATTRS);
  48. if (NULL != hdc)
  49. {
  50. hdcTmp = CreateCompatibleDC(hdc);
  51. ReleaseDC(NULL, hdc);
  52. }
  53. if (NULL == hdcTmp)
  54. return NULL;
  55. LONG pixelsY = GetDeviceCaps(hdcTmp, LOGPIXELSY);
  56. HFONT prevFont = SelectFont(hdcTmp, sourceFont);
  57. TEXTMETRICW tm = {0};
  58. if (FALSE != GetTextMetricsW(hdcTmp, &tm))
  59. {
  60. INT basePt = MulDiv(tm.tmHeight - tm.tmInternalLeading, 96, pixelsY);
  61. lf.lfHeight = -MulDiv((basePt + heightDeltaPt), pixelsY, 96);
  62. }
  63. SelectObject(hdcTmp, prevFont);
  64. DeleteDC(hdcTmp);
  65. }
  66. if (FALSE != systemQuality)
  67. lf.lfQuality = Graphics_GetSysFontQuality();
  68. if (FALSE != forceBold && lf.lfWeight < FW_BOLD)
  69. lf.lfWeight = FW_BOLD;
  70. return CreateFontIndirectW(&lf);
  71. }
  72. long
  73. Graphics_GetFontHeight(HDC hdc)
  74. {
  75. TEXTMETRICW tm;
  76. if (FALSE == GetTextMetricsW(hdc, &tm))
  77. return 0;
  78. return tm.tmHeight;
  79. }
  80. long
  81. Graphics_GetAveStrWidth(HDC hdc, UINT cchLen)
  82. {
  83. const char szTest[] =
  84. {
  85. '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',
  86. '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'
  87. };
  88. SIZE textSize;
  89. if (FALSE == GetTextExtentPointA(hdc, szTest, ARRAYSIZE(szTest) -1, &textSize))
  90. return 0;
  91. LONG result;
  92. if (1 == cchLen)
  93. {
  94. result = (textSize.cx + ARRAYSIZE(szTest)/2)/ARRAYSIZE(szTest);
  95. }
  96. else
  97. {
  98. result = MulDiv(cchLen, textSize.cx + ARRAYSIZE(szTest)/2, ARRAYSIZE(szTest));
  99. if (0 != result)
  100. {
  101. TEXTMETRICW tm;
  102. if (FALSE != GetTextMetricsW(hdc, &tm))
  103. result += tm.tmOverhang;
  104. }
  105. }
  106. return result;
  107. }
  108. BOOL
  109. Graphics_GetWindowBaseUnits(HWND hwnd, LONG *baseUnitX, LONG *baseUnitY)
  110. {
  111. BOOL result;
  112. result = FALSE;
  113. if (NULL != hwnd)
  114. {
  115. HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
  116. if (NULL != hdc)
  117. {
  118. TEXTMETRICW tm;
  119. HFONT font, prevFont;
  120. font = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L);
  121. prevFont = SelectFont(hdc, font);
  122. if (FALSE != GetTextMetricsW(hdc, &tm))
  123. {
  124. if (NULL != baseUnitX)
  125. *baseUnitX = Graphics_GetAveStrWidth(hdc, 1);
  126. if (NULL != baseUnitY)
  127. *baseUnitY = tm.tmHeight;
  128. result = TRUE;
  129. }
  130. SelectFont(hdc, prevFont);
  131. ReleaseDC(hwnd, hdc);
  132. }
  133. }
  134. return result;
  135. }
  136. typedef int (*SkinColorFunc)(int idx);
  137. COLORREF Graphics_GetSkinColor(unsigned int colorIndex)
  138. {
  139. static SkinColorFunc GetSkinColor = NULL;
  140. if (NULL == GetSkinColor)
  141. {
  142. GetSkinColor = (SkinColorFunc)SENDMLIPC(Plugin_GetLibraryWindow(), ML_IPC_SKIN_WADLG_GETFUNC, 1);
  143. if (NULL == GetSkinColor)
  144. return RGB(255, 0, 255);
  145. }
  146. return GetSkinColor(colorIndex);
  147. }
  148. COLORREF
  149. Graphics_BlendColors(COLORREF rgbTop, COLORREF rgbBottom, INT alpha)
  150. {
  151. if (alpha > 254) return rgbTop;
  152. if (alpha < 0) return rgbBottom;
  153. WORD k = (WORD)(((255 - alpha)*255 + 127)/255);
  154. return RGB( (GetRValue(rgbTop)*alpha + k*GetRValue(rgbBottom) + 127)/255,
  155. (GetGValue(rgbTop)*alpha + k*GetGValue(rgbBottom) + 127)/255,
  156. (GetBValue(rgbTop)*alpha + k*GetBValue(rgbBottom) + 127)/255);
  157. }
  158. INT
  159. Graphics_GetColorDistance(COLORREF rgb1, COLORREF rgb2)
  160. {
  161. return (1000 * ((GetRValue(rgb1) - GetRValue(rgb2)) +
  162. (GetGValue(rgb1) - GetGValue(rgb2)) +
  163. (GetBValue(rgb1) - GetBValue(rgb2))))/ (3 * 255);
  164. }
  165. void
  166. Graphics_ClampRect(RECT *rect, const RECT *boxRect)
  167. {
  168. if (rect->left < boxRect->left)
  169. rect->left = boxRect->left;
  170. if (rect->top < boxRect->top)
  171. rect->top = boxRect->top;
  172. if (rect->right > boxRect->right)
  173. rect->right = boxRect->right;
  174. if (rect->bottom > boxRect->bottom)
  175. rect->bottom = boxRect->bottom;
  176. }
  177. void
  178. Graphics_NormalizeRect(RECT *rect)
  179. {
  180. if (rect->top > rect->bottom)
  181. rect->bottom = rect->top;
  182. if (rect->left > rect->right)
  183. rect->right = rect->left;
  184. }
  185. void
  186. Graphics_GetRectSizeNormalized(const RECT *rect, SIZE *size)
  187. {
  188. size->cx = rect->right - rect->left;
  189. if (size->cx < 0)
  190. size->cx = 0;
  191. size->cy = rect->bottom - rect->top;
  192. if (size->cy < 0)
  193. size->cy = 0;
  194. }
  195. BOOL
  196. Graphics_IsRectFit(const RECT *rect, const RECT *boxRect)
  197. {
  198. if (rect->left < boxRect->left ||
  199. rect->top < boxRect->top ||
  200. rect->right > boxRect->right ||
  201. rect->bottom > boxRect->bottom)
  202. {
  203. return FALSE;
  204. }
  205. return TRUE;
  206. }
  207. BOOL SetSizeEmpty(SIZE *size)
  208. {
  209. if (NULL == size)
  210. return FALSE;
  211. ZeroMemory(size, sizeof(SIZE));
  212. return TRUE;
  213. }
  214. BOOL IsSizeEmpty(SIZE *size)
  215. {
  216. return (NULL == size || 0 == size->cx || 0 == size->cy);
  217. }
  218. BOOL SetSize(SIZE *size, long width, long height)
  219. {
  220. if (NULL == size)
  221. return FALSE;
  222. size->cx = width;
  223. size->cy = height;
  224. return TRUE;
  225. }
  226. BOOL SetPoint(POINT *pt, long x, long y)
  227. {
  228. if (NULL == pt)
  229. return FALSE;
  230. pt->x = x;
  231. pt->y = y;
  232. return TRUE;
  233. }
  234. BOOL MakeRectPolygon(POINT vertices[4], long left, long top, long right, long bottom)
  235. {
  236. if (NULL == vertices)
  237. return FALSE;
  238. vertices[0].x = left;
  239. vertices[0].y = top;
  240. vertices[1].x = right;
  241. vertices[1].y = top;
  242. vertices[2].x = right;
  243. vertices[2].y = bottom;
  244. vertices[3].x = left;
  245. vertices[3].y = bottom;
  246. return TRUE;
  247. }