Leaked source code of windows server 2003
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.

130 lines
3.5 KiB

  1. #include "stdafx.h"
  2. #include "RenderUtil.h"
  3. namespace DUser
  4. {
  5. namespace RenderUtil
  6. {
  7. //------------------------------------------------------------------------------
  8. void
  9. ComputeBorder(
  10. IN Gdiplus::Pen * pgppen,
  11. IN const Gdiplus::RectF * prcGadgetPxl,
  12. IN EBorderAlignment ba,
  13. OUT Gdiplus::RectF * prcBorderPxl)
  14. {
  15. float flPenThickness = pgppen->GetWidth();
  16. BOOL fEven = fabs(fmod(flPenThickness, 2.0f)) < 0.0001f;
  17. float flOffset, flSize;
  18. switch (ba) {
  19. case baOutside:
  20. flOffset = (flPenThickness + (fEven ? 0.0f : 1.0f)) / 2.0f + (fEven ? 0.5f : 0.0f);
  21. flSize = flPenThickness;
  22. break;
  23. case baCenter:
  24. flOffset = (fEven ? 0.5f : 0.0f);
  25. flSize = (fEven ? 1.0f : 0.0f);
  26. break;
  27. case baInside:
  28. // Inside is opposite of outside
  29. flOffset = -((flPenThickness + (fEven ? 0.0f : 1.0f)) / 2.0f + (fEven ? 0.5f : 0.0f));
  30. flSize = -flPenThickness;
  31. break;
  32. default:
  33. AssertMsg(0, "Unknown alignment");
  34. return;
  35. }
  36. prcBorderPxl->X = prcGadgetPxl->X - flOffset;
  37. prcBorderPxl->Y = prcGadgetPxl->Y - flOffset;
  38. prcBorderPxl->Width = prcGadgetPxl->Width + flSize;
  39. prcBorderPxl->Height = prcGadgetPxl->Height + flSize;
  40. }
  41. //------------------------------------------------------------------------------
  42. void
  43. ComputeRoundRect(
  44. IN const Gdiplus::RectF * prc,
  45. IN const Gdiplus::SizeF sizeCorner,
  46. IN OUT Gdiplus::GraphicsPath * pgppath)
  47. {
  48. float W = (prc->Width > (sizeCorner.Width * 2)) ? sizeCorner.Width : prc->Width / 2.0f;
  49. float H = (prc->Height > (sizeCorner.Height * 2)) ? sizeCorner.Width : prc->Height / 2.0f;
  50. float W2 = W * 2.0f;
  51. float H2 = H * 2.0f;
  52. float LX1 = prc->X;
  53. float LY1 = prc->Y;
  54. float LX2 = prc->X + prc->Width;
  55. float LY2 = prc->Y + prc->Height;
  56. float RX1 = prc->X + W;
  57. float RY1 = prc->Y + H;
  58. float RX2 = prc->X + prc->Width - W;
  59. float RY2 = prc->Y + prc->Height - H;
  60. pgppath->AddLine(RX1, LY1, RX2, LY1);
  61. pgppath->AddArc(RX2-W, RY1-H, W2, H2, 270.0f, 90.0f);
  62. pgppath->AddLine(LX2, RY1, LX2, RY2);
  63. pgppath->AddArc(RX2-W, RY2-H, W2, H2, 0.0f, 90.0f);
  64. pgppath->AddLine(RX2, LY2, RX1, LY2);
  65. pgppath->AddArc(RX1-W, RY2-H, W2, H2, 90.0f, 90.0f);
  66. pgppath->AddLine(LX1, RY2, LX1, RY1);
  67. pgppath->AddArc(RX1-W, RY1-H, W2, H2, 180.0f, 90.0f);
  68. pgppath->CloseFigure();
  69. }
  70. //------------------------------------------------------------------------------
  71. void
  72. DrawRoundRect(
  73. IN Gdiplus::Graphics * pgpgr,
  74. IN Gdiplus::Pen * pgppenBorder,
  75. IN const Gdiplus::RectF & rc,
  76. IN const Gdiplus::SizeF sizeCorner,
  77. IN EBorderAlignment ba)
  78. {
  79. Assert(pgppenBorder != NULL);
  80. Gdiplus::RectF rcUse;
  81. ComputeBorder(pgppenBorder, &rc, ba, &rcUse);
  82. Gdiplus::GraphicsPath gppath;
  83. ComputeRoundRect(&rcUse, sizeCorner, &gppath);
  84. pgpgr->DrawPath(pgppenBorder, &gppath);
  85. }
  86. //------------------------------------------------------------------------------
  87. void
  88. FillRoundRect(
  89. IN Gdiplus::Graphics * pgpgr,
  90. IN Gdiplus::Brush * pgpbrFill,
  91. IN const Gdiplus::RectF & rc,
  92. IN const Gdiplus::SizeF sizeCorner)
  93. {
  94. Assert(pgpbrFill != NULL);
  95. Gdiplus::GraphicsPath gppath;
  96. ComputeRoundRect(&rc, sizeCorner, &gppath);
  97. pgpgr->FillPath(pgpbrFill, &gppath);
  98. }
  99. } // namespace DUser
  100. } // namespace RenderUtil