Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

407 lines
12 KiB

  1. //-------------------------------------------------------------------------
  2. // NtlEng.cpp - support for Native Theme Language runtime graphics engine
  3. //-------------------------------------------------------------------------
  4. #include "stdafx.h"
  5. #include "ntleng.h"
  6. //---------------------------------------------------------------------------
  7. #define COLORNULL 0xff000000
  8. //---------------------------------------------------------------------------
  9. POINT TranslateLogPoint(POINT &pt, RECT &rcLogRect, RECT &rcCaller)
  10. {
  11. POINT ptNew;
  12. ptNew.x = rcCaller.left + (WIDTH(rcCaller) * (pt.x - rcLogRect.left))/WIDTH(rcLogRect);
  13. ptNew.y = rcCaller.top + (HEIGHT(rcCaller) * (pt.y - rcLogRect.top))/HEIGHT(rcLogRect);
  14. return ptNew;
  15. }
  16. //---------------------------------------------------------------------------
  17. int TranslateLogSize(int iSize, RECT &rcLogRect, RECT &rcCaller)
  18. {
  19. //---- "iSize" is somewhere between width & height ----
  20. int iWidthSize = (WIDTH(rcCaller) * iSize)/WIDTH(rcLogRect);
  21. int iHeightSize = (HEIGHT(rcCaller) * iSize)/HEIGHT(rcLogRect);
  22. return min(iWidthSize, iHeightSize);
  23. }
  24. //---------------------------------------------------------------------------
  25. COLORREF GetParamColor(MIXEDPTRS &u)
  26. {
  27. COLORREF crVal = 0;
  28. if (*u.pb == PT_COLORREF)
  29. crVal = *u.pi++;
  30. else if (*u.pb == PT_SYSCOLORINDEX)
  31. crVal = GetSysColor(*u.ps++);
  32. else if (*u.pb == PT_COLORNULL)
  33. crVal = COLORNULL;
  34. else
  35. {
  36. Log(LOG_ERROR, L"Bad color param value in NTL stream: 0x%0x", *u.pb);
  37. }
  38. return crVal;
  39. }
  40. //---------------------------------------------------------------------------
  41. int GetParamInt(MIXEDPTRS &u)
  42. {
  43. int iVal;
  44. if (*u.pb == PT_INT)
  45. iVal = *u.pi++;
  46. else
  47. iVal = ClassicGetSystemMetrics(*u.ps++);
  48. return iVal;
  49. }
  50. //---------------------------------------------------------------------------
  51. POINT GetParamPoint(MIXEDPTRS &u, RECT &rcCaller, RECT &rcLogRect)
  52. {
  53. POINT pt = *u.ppt++;
  54. pt = TranslateLogPoint(pt, rcCaller, rcLogRect);
  55. return pt;
  56. }
  57. //---------------------------------------------------------------------------
  58. void SetPen(HDC hdc, HPEN &hPen, COLORREF crLine, int iLineWidth)
  59. {
  60. DeleteObject(hPen);
  61. if (crLine == COLORNULL)
  62. hPen = (HPEN)GetStockObject(NULL_PEN);
  63. else
  64. hPen = CreatePen(PS_SOLID, iLineWidth, crLine);
  65. SelectObject(hdc, hPen);
  66. }
  67. //---------------------------------------------------------------------------
  68. HRESULT GetImageBrush(HDC hdc, int iPartId, int iStateId, int iIndex,
  69. INtlEngCallBack *pCallBack, HBRUSH *phbr)
  70. {
  71. HRESULT hr;
  72. if (! pCallBack)
  73. {
  74. Log(LOG_ERROR, L"No callback for NtlRun specified");
  75. hr = MakeError32(ERROR_INTERNAL_ERROR);
  76. }
  77. else
  78. hr = pCallBack->CreateImageBrush(hdc, iPartId, iStateId, iIndex, phbr);
  79. return hr;
  80. }
  81. //---------------------------------------------------------------------------
  82. HRESULT GetFillBrush(HDC hdc, MIXEDPTRS &u, int iPartId, int iStateId,
  83. INtlEngCallBack *pCallBack, HBRUSH *phbr)
  84. {
  85. HBRUSH hbr = NULL;
  86. BYTE bIndex;
  87. HRESULT hr = S_OK;
  88. switch (*u.pb)
  89. {
  90. case PT_IMAGEFILE:
  91. bIndex = *u.pb++;
  92. hr = GetImageBrush(hdc, iPartId, iStateId, bIndex, pCallBack, &hbr);
  93. break;
  94. default:
  95. COLORREF crVal = GetParamColor(u);
  96. if (crVal == COLORNULL)
  97. hbr = (HBRUSH)GetStockObject(NULL_BRUSH);
  98. else
  99. hbr = CreateSolidBrush(crVal);
  100. break;
  101. }
  102. if (SUCCEEDED(hr))
  103. *phbr = hbr;
  104. return hr;
  105. }
  106. //---------------------------------------------------------------------------
  107. void DrawRect(HDC hdc, MIXEDPTRS &u, RECT &rcCaller)
  108. {
  109. int iVals[4];
  110. COLORREF crVals[4];
  111. //---- get int params ----
  112. for (int i=0; i < 4; i++)
  113. {
  114. if ((*u.pb != PT_INT) && (*u.pb != PT_SYSMETRICINDEX))
  115. break;
  116. iVals[i] = GetParamInt(u);
  117. }
  118. int cInts = i;
  119. //---- get color param s----
  120. for (i=0; i < 4; i++)
  121. {
  122. if ((*u.pb != PT_COLORREF) && (*u.pb != PT_COLORNULL)
  123. && (*u.pb != PT_SYSCOLORINDEX))
  124. break;
  125. crVals[i] = GetParamColor(u);
  126. }
  127. int cColors = i;
  128. if ((cInts == 1) && (cColors == 1)) // single size/color for all 4 sides
  129. {
  130. if (crVals[0] != COLORNULL)
  131. {
  132. HPEN hpen = CreatePen(PS_SOLID | PS_INSIDEFRAME, iVals[0], crVals[0]);
  133. HPEN hpenOld = (HPEN)SelectObject(hdc, hpen);
  134. HBRUSH hbrOld = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
  135. Rectangle(hdc, rcCaller.left, rcCaller.top, rcCaller.right, rcCaller.bottom);
  136. SelectObject(hdc, hpenOld);
  137. SelectObject(hdc, hbrOld);
  138. DeleteObject(hpen);
  139. }
  140. InflateRect(&rcCaller, -iVals[0], -iVals[0]);
  141. }
  142. else // need to draw each side one at a time
  143. {
  144. //---- expand int's into 4 values ----
  145. if (cInts == 1)
  146. {
  147. iVals[1] = iVals[2] = iVals[3] = iVals[0];
  148. }
  149. else if (cInts == 2)
  150. {
  151. iVals[2] = iVals[0];
  152. iVals[3] = iVals[1];
  153. }
  154. //---- expand colors's into 4 values ----
  155. if (cColors == 1)
  156. {
  157. crVals[1] = crVals[2] = crVals[3] = crVals[0];
  158. }
  159. else if (cColors == 2)
  160. {
  161. crVals[2] = crVals[0];
  162. crVals[3] = crVals[1];
  163. }
  164. HBRUSH hbrOld = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
  165. HBRUSH hbr = NULL;
  166. //---- left ----
  167. if ((crVals[0] != COLORNULL) && (iVals[0]))
  168. {
  169. hbr = CreateSolidBrush(crVals[0]);
  170. SelectObject(hdc, hbr);
  171. PatBlt(hdc, rcCaller.left, rcCaller.top, iVals[0], HEIGHT(rcCaller), PATCOPY);
  172. }
  173. rcCaller.left += iVals[0];
  174. //---- top ----
  175. if ((crVals[1] != COLORNULL) && (iVals[1]))
  176. {
  177. if (crVals[1] != crVals[0]) // need new brush
  178. {
  179. hbr = CreateSolidBrush(crVals[1]);
  180. SelectObject(hdc, hbr);
  181. }
  182. PatBlt(hdc, rcCaller.left, rcCaller.top, WIDTH(rcCaller), iVals[0], PATCOPY);
  183. }
  184. rcCaller.top += iVals[1];
  185. //---- right ----
  186. if ((crVals[2] != COLORNULL) && (iVals[2]))
  187. {
  188. if (crVals[2] != crVals[1]) // need new brush
  189. {
  190. hbr = CreateSolidBrush(crVals[2]);
  191. SelectObject(hdc, hbr);
  192. }
  193. PatBlt(hdc, rcCaller.right - iVals[0], rcCaller.top, iVals[0], HEIGHT(rcCaller), PATCOPY);
  194. }
  195. rcCaller.right -= iVals[2];
  196. //---- bottom ----
  197. if ((crVals[3] != COLORNULL) && (iVals[3]))
  198. {
  199. if (crVals[3] != crVals[2]) // need new brush
  200. {
  201. hbr = CreateSolidBrush(crVals[3]);
  202. SelectObject(hdc, hbr);
  203. }
  204. PatBlt(hdc, rcCaller.left, rcCaller.bottom - iVals[0], WIDTH(rcCaller), iVals[0], PATCOPY);
  205. }
  206. rcCaller.bottom -= iVals[3];
  207. SelectObject(hdc, hbrOld);
  208. DeleteObject(hbr);
  209. }
  210. }
  211. //---------------------------------------------------------------------------
  212. HRESULT RunNtl(HDC hdc, RECT &rcCaller, HBRUSH hbrBkDefault, DWORD dwOptions,
  213. int iPartId, int iStateId, BYTE *pbCode, int iCodeLen, INtlEngCallBack *pCallBack)
  214. {
  215. HRESULT hr = S_OK;
  216. MIXEDPTRS u;
  217. u.pb = pbCode;
  218. RECT rcLogRect = {0, 0, 1000, 1000};
  219. RESOURCE HPEN hPen = (HPEN)GetStockObject(BLACK_PEN);
  220. RESOURCE HBRUSH hBrush = (HBRUSH)GetStockObject(GRAY_BRUSH);
  221. BOOL fDeleteBrush = FALSE;
  222. if (hbrBkDefault)
  223. hBrush = hbrBkDefault;
  224. RESOURCE HBRUSH hbrOld = (HBRUSH)SelectObject(hdc, hBrush);
  225. RESOURCE HPEN hpenOld = (HPEN)SelectObject(hdc, hPen);
  226. while (*u.pb != NTL_RETURN)
  227. {
  228. switch (*u.pb)
  229. {
  230. case NTL_STATEJUMPTABLE:
  231. {
  232. BYTE bStateCount = *u.pb++;
  233. if ((iStateId < 1) || (iStateId > bStateCount))
  234. iStateId = 1;
  235. u.pb = pbCode + u.pi[iStateId-1];
  236. }
  237. break;
  238. case NTL_JMPON:
  239. {
  240. BYTE bBitNum = *u.pb++;
  241. int iOffset = *u.pi++;
  242. if (dwOptions & (1 << bBitNum))
  243. u.pb = pbCode + iOffset;
  244. }
  245. break;
  246. case NTL_JMPOFF:
  247. {
  248. BYTE bBitNum = *u.pb++;
  249. int iOffset = *u.pi++;
  250. if (! (dwOptions & (1 << bBitNum)))
  251. u.pb = pbCode + iOffset;
  252. }
  253. break;
  254. case NTL_JMP:
  255. {
  256. int iOffset = *u.pi++;
  257. u.pb = pbCode + iOffset;
  258. }
  259. break;
  260. case NTL_LOGRECT:
  261. rcLogRect = *u.prc++;
  262. break;
  263. case NTL_LINEBRUSH:
  264. {
  265. COLORREF crLine = GetParamColor(u);
  266. int iLineWidth = GetParamInt(u);
  267. BOOL fLogWidth = *u.pb++;
  268. if (fLogWidth)
  269. iLineWidth = TranslateLogSize(iLineWidth, rcCaller, rcLogRect);
  270. SetPen(hdc, hPen, crLine, iLineWidth);
  271. }
  272. break;
  273. case NTL_FILLBRUSH:
  274. {
  275. HBRUSH hbr;
  276. hr = GetFillBrush(hdc, u, iPartId, iStateId, pCallBack, &hbr);
  277. if (FAILED(hr))
  278. goto exit;
  279. SelectObject(hdc, hbr);
  280. if (fDeleteBrush)
  281. DeleteObject(hBrush);
  282. hBrush = hbr;
  283. fDeleteBrush = TRUE;
  284. }
  285. break;
  286. case NTL_MOVETO:
  287. {
  288. POINT pt = GetParamPoint(u, rcCaller, rcLogRect);
  289. MoveToEx(hdc, pt.x, pt.y, NULL);
  290. }
  291. break;
  292. case NTL_LINETO:
  293. {
  294. POINT pt = GetParamPoint(u, rcCaller, rcLogRect);
  295. LineTo(hdc, pt.x, pt.y);
  296. }
  297. break;
  298. case NTL_CURVETO:
  299. {
  300. POINT pts[3];
  301. pts[0] = GetParamPoint(u, rcCaller, rcLogRect);
  302. pts[1] = GetParamPoint(u, rcCaller, rcLogRect);
  303. pts[2] = GetParamPoint(u, rcCaller, rcLogRect);
  304. PolyBezierTo(hdc, pts, 3);
  305. }
  306. break;
  307. case NTL_SHAPE:
  308. {
  309. POINT pt = GetParamPoint(u, rcCaller, rcLogRect);
  310. BeginPath(hdc);
  311. MoveToEx(hdc, pt.x, pt.y, NULL);
  312. }
  313. break;
  314. case NTL_ENDSHAPE:
  315. {
  316. EndPath(hdc);
  317. StrokeAndFillPath(hdc);
  318. }
  319. break;
  320. case NTL_DRAWRECT:
  321. {
  322. DrawRect(hdc, u, rcCaller);
  323. }
  324. break;
  325. case NTL_FILLRECT:
  326. {
  327. HBRUSH hbr;
  328. hr = GetFillBrush(hdc, u, iPartId, iStateId, pCallBack, &hbr);
  329. if (FAILED(hr))
  330. goto exit;
  331. FillRect(hdc, &rcCaller, hbr);
  332. DeleteObject(hbr);
  333. }
  334. break;
  335. }
  336. }
  337. exit:
  338. SelectObject(hdc, hbrOld);
  339. SelectObject(hdc, hpenOld);
  340. DeleteObject(hPen);
  341. if (fDeleteBrush)
  342. DeleteObject(hBrush);
  343. return S_OK;
  344. }
  345. //---------------------------------------------------------------------------