graphics.cpp 6.2 KB

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