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.

472 lines
13 KiB

  1. #include <crtdbg.h>
  2. #include <stdio.h>
  3. #include <objbase.h>
  4. #include <windows.h>
  5. #include <winspool.h>
  6. #include <commdlg.h>
  7. #include <gdiplus.h>
  8. using namespace Gdiplus;
  9. #include "wndstuff.h"
  10. GraphicsPath gppath;
  11. GraphicsPath widepath;
  12. GraphicsPath clippath;
  13. TextureBrush *texturebrush = NULL;
  14. PointF lastpoint(-1,-1);
  15. Bitmap *offscreenbitmap = NULL;
  16. int subpathlength = 0;
  17. int ScaleColorMode = 0;
  18. WCHAR savedFilename[255];
  19. void
  20. RemakePath(GraphicsPath *linepath, GraphicsPath *bezpath, BOOL bezmode)
  21. {
  22. GraphicsPath *temppath = linepath->Clone();
  23. temppath->CloseFigure();
  24. bezpath->Reset();
  25. PointF *points = new PointF[temppath->GetPointCount()];
  26. BYTE *types = new BYTE[temppath->GetPointCount()];
  27. temppath->GetPathPoints(points, temppath->GetPointCount());
  28. temppath->GetPathTypes(types, temppath->GetPointCount());
  29. int last = 0;
  30. for (int i=0; i<temppath->GetPointCount(); i++)
  31. {
  32. if (types[i] & PathPointTypeCloseSubpath)
  33. {
  34. if (i-last+1 > 2)
  35. {
  36. if (!bezmode)
  37. {
  38. bezpath->AddPolygon(points+last, i-last+1);
  39. }
  40. else
  41. {
  42. bezpath->AddClosedCurve(points+last, i-last+1);
  43. }
  44. last = i+1;
  45. }
  46. }
  47. }
  48. delete points;
  49. delete types;
  50. delete temppath;
  51. }
  52. void
  53. SplitPath(BOOL bezmode, BOOL before, BOOL after, float flatness)
  54. {
  55. if (gppath.GetPointCount() < 3)
  56. return;
  57. RemakePath(&gppath, &widepath, bezmode);
  58. if (widepath.GetPointCount() > 2)
  59. {
  60. Pen pen(Color(0xff000000), 20);
  61. pen.SetLineJoin(LineJoinMiter);
  62. pen.SetMiterLimit(5);
  63. Matrix matrix;
  64. if (before)
  65. widepath.Outline(NULL, flatness);
  66. widepath.Widen(&pen, NULL, flatness);
  67. if (after)
  68. widepath.Outline(NULL, flatness);
  69. }
  70. }
  71. void
  72. ClosePath()
  73. {
  74. if (gppath.GetPointCount() < 1)
  75. return;
  76. gppath.CloseFigure();
  77. lastpoint = PointF(-1,-1);
  78. }
  79. void
  80. ClearPath()
  81. {
  82. lastpoint = PointF(-1,-1);
  83. gppath.Reset();
  84. widepath.Reset();
  85. }
  86. void
  87. ClipPath(BOOL bezmode)
  88. {
  89. clippath.Reset();
  90. GraphicsPath remadepath;
  91. RemakePath(&gppath, &remadepath, bezmode);
  92. clippath.AddPath(&remadepath, FALSE);
  93. ClearPath();
  94. }
  95. void
  96. ClearClipPath()
  97. {
  98. clippath.Reset();
  99. }
  100. void
  101. AddPoint(INT x, INT y)
  102. {
  103. if (!(lastpoint.X == -1 && lastpoint.Y == -1))
  104. {
  105. gppath.AddLine(lastpoint, PointF((float)x, (float)y));
  106. }
  107. lastpoint = PointF((float)x, (float)y);
  108. }
  109. void
  110. OpenPath(char *filename)
  111. {
  112. FILE *f = fopen(filename, "rt");
  113. INT count;
  114. fscanf(f, "%i", &count);
  115. for (INT i=0; i<count; i++)
  116. {
  117. INT type;
  118. REAL x, y;
  119. fscanf(f, "%i %f %f\n", &type, &x, &y);
  120. if (((type & 7) == 0) && i == 0)
  121. {
  122. gppath.Reset();
  123. PointF lastpoint; lastpoint.X = -1; lastpoint.Y = -1;
  124. }
  125. if ((type & 7) == 0)
  126. {
  127. lastpoint = PointF((float)x, (float)y);
  128. }
  129. else if ((type & 7) == 1)
  130. {
  131. gppath.AddLine(lastpoint, PointF((float)x, (float)y));
  132. lastpoint = PointF((float)x, (float)y);
  133. }
  134. if (type & 128)
  135. {
  136. //gppath.AddLine(firstpoint, lastpoint);
  137. ClosePath();
  138. }
  139. }
  140. fclose(f);
  141. }
  142. void
  143. SavePath(char *filename)
  144. {
  145. FILE *f = fopen(filename, "wt");
  146. int count = gppath.GetPointCount();
  147. Point *pathpoints = new Point[count];
  148. BYTE *pathtypes = new BYTE[count];
  149. gppath.GetPathPoints(pathpoints, count);
  150. gppath.GetPathTypes(pathtypes, count);
  151. fprintf(f, "%d\n", count);
  152. for (int i=0; i<count; i++)
  153. {
  154. fprintf(f, "%i %d %d\n", pathtypes[i], pathpoints[i].X, pathpoints[i].Y);
  155. }
  156. fclose(f);
  157. delete pathpoints;
  158. delete pathtypes;
  159. }
  160. void
  161. SetColorMode(INT colorMode)
  162. {
  163. ScaleColorMode = colorMode;
  164. ChangeTexture(savedFilename);
  165. }
  166. Color
  167. ScaleColor(Color color, INT x, INT width)
  168. {
  169. REAL alphaScale = 1, redScale = 1, greenScale = 1, blueScale = 1;
  170. switch (ScaleColorMode)
  171. {
  172. case 1:
  173. alphaScale = 0.5;
  174. break;
  175. case 2:
  176. alphaScale = (REAL)x / width;
  177. break;
  178. }
  179. REAL alpha = ((REAL)color.GetAlpha())*alphaScale;
  180. REAL red = ((REAL)color.GetRed())*redScale;
  181. REAL green = ((REAL)color.GetGreen())*greenScale;
  182. REAL blue = ((REAL)color.GetBlue())*blueScale;
  183. return Color((BYTE)alpha, (BYTE)red, (BYTE)green, (BYTE)blue);
  184. }
  185. void
  186. ScaleColors(Bitmap* destBitmap, Bitmap *bitmap)
  187. {
  188. BitmapData bmpData;
  189. Rect rect = Rect(0, 0, bitmap->GetWidth(), bitmap->GetHeight());
  190. if (bitmap->LockBits(&rect, ImageLockModeRead, PixelFormat32bppARGB, &bmpData) == Ok)
  191. {
  192. ARGB *data;
  193. for (UINT y=0; y<bitmap->GetHeight(); y++)
  194. {
  195. data = (ARGB*)((BYTE*)bmpData.Scan0+(y*bmpData.Stride));
  196. for (UINT x=0; x<bitmap->GetWidth(); x++)
  197. {
  198. *data = ScaleColor(Color(*data), x, bitmap->GetWidth()).GetValue();
  199. data++;
  200. }
  201. }
  202. BitmapData bmpDataDest;
  203. if (destBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat32bppARGB, &bmpDataDest) == Ok)
  204. {
  205. memcpy(bmpDataDest.Scan0, bmpData.Scan0, bitmap->GetWidth() * bitmap->GetHeight() * sizeof(ARGB));
  206. destBitmap->UnlockBits(&bmpDataDest);
  207. }
  208. bitmap->UnlockBits(&bmpData);
  209. }
  210. }
  211. void
  212. ChangeTexture(const WCHAR *filename)
  213. {
  214. wcsncpy(savedFilename, filename, 255);
  215. delete texturebrush;
  216. Bitmap image(filename);
  217. Bitmap image2(image.GetWidth(), image.GetHeight(), PixelFormat32bppARGB);
  218. ScaleColors(&image2, &image);
  219. texturebrush = new TextureBrush(&image2);
  220. }
  221. void
  222. Resize(INT x, INT y)
  223. {
  224. delete offscreenbitmap;
  225. offscreenbitmap = new Bitmap(x, y, PixelFormat32bppPARGB);
  226. }
  227. void
  228. CleanUp()
  229. {
  230. delete offscreenbitmap;
  231. delete texturebrush;
  232. }
  233. VOID
  234. Print(HWND hwnd, float flatness, PtFlag flags)
  235. {
  236. PRINTDLG printdlg;
  237. memset(&printdlg, 0, sizeof(PRINTDLG));
  238. printdlg.lStructSize = sizeof(PRINTDLG);
  239. printdlg.hwndOwner = hwnd;
  240. printdlg.hDevMode = NULL;
  241. printdlg.hDevNames = NULL;
  242. printdlg.hDC = NULL;
  243. printdlg.Flags = PD_RETURNDC;
  244. if (PrintDlg(&printdlg))
  245. {
  246. DOCINFO di;
  247. memset(&di, 0, sizeof(DOCINFO));
  248. di.cbSize = sizeof(DOCINFO);
  249. di.lpszDocName = "Path Printing Test";
  250. di.lpszOutput = (LPTSTR)NULL;
  251. di.lpszDatatype = (LPTSTR)NULL;
  252. di.fwType = 0;
  253. DEVMODE *devmode = (DEVMODE*)GlobalLock(printdlg.hDevMode);
  254. if (devmode == NULL)
  255. return;
  256. HANDLE hprinter;
  257. OpenPrinter((LPSTR)devmode->dmDeviceName, &hprinter, NULL);
  258. GlobalUnlock(printdlg.hDevMode);
  259. StartDoc(printdlg.hDC, &di);
  260. StartPage(printdlg.hDC);
  261. DrawPath(hwnd, &printdlg.hDC, &hprinter, flatness, flags);
  262. EndPage(printdlg.hDC);
  263. EndDoc(printdlg.hDC);
  264. }
  265. else
  266. {
  267. DWORD error = CommDlgExtendedError();
  268. if (error)
  269. {
  270. char errormessage[100];
  271. sprintf(errormessage, "PrintDlg error: %d", error);
  272. MessageBox(hwnd, errormessage, "PrintDlg error", MB_OK);
  273. }
  274. }
  275. }
  276. void
  277. DrawPath(HWND hwnd, HDC *phdc, HANDLE *hprinter, float flatness, PtFlag flags)
  278. {
  279. if (!offscreenbitmap)
  280. return;
  281. Graphics *renderinggraphics;
  282. if (phdc)
  283. {
  284. renderinggraphics = new Graphics(*phdc, *hprinter);
  285. }
  286. else
  287. {
  288. renderinggraphics = new Graphics(offscreenbitmap);
  289. }
  290. RECT rect;
  291. GetClientRect(hwnd, &rect);
  292. Brush *background;
  293. if (flags & PTBackgroundGradFillFlag)
  294. {
  295. background = new LinearGradientBrush(Point(0, 0), Point((rect.right-rect.left)/4, 0), Color(0xffffffff), Color(0xff0000ff));
  296. ((LinearGradientBrush*)background)->SetWrapMode(WrapModeTileFlipX);
  297. }
  298. else
  299. {
  300. background = new SolidBrush(Color(0xffffffff));
  301. }
  302. renderinggraphics->FillRectangle(background, Rect(rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top));
  303. delete background;
  304. renderinggraphics->SetSmoothingMode(SmoothingModeAntiAlias);
  305. if (gppath.GetPointCount() > 0)
  306. {
  307. SplitPath(flags & PtBezierFlag, flags & PtOutlineBeforeFlag, flags & PtOutlineAfterFlag, flatness);
  308. if (clippath.GetPointCount() > 2)
  309. {
  310. renderinggraphics->SetClip(&clippath);
  311. }
  312. if (flags & PtTextureFillFlag)
  313. {
  314. if (!texturebrush)
  315. ChangeTexture(L"mycomputer.jpg");
  316. GraphicsPath bezpath;
  317. RemakePath(&gppath, &bezpath, flags & PtBezierFlag);
  318. if (flags & PtOutlineBeforeFlag)
  319. bezpath.Outline();
  320. bezpath.SetFillMode(FillModeWinding);
  321. renderinggraphics->FillPath(texturebrush, &bezpath);
  322. }
  323. if (flags & PtTransSolidFillFlag)
  324. {
  325. SolidBrush transsolidbrush(Color(0x80ffff00));
  326. GraphicsPath bezpath;
  327. RemakePath(&gppath, &bezpath, flags & PtBezierFlag);
  328. if (flags & PtOutlineBeforeFlag)
  329. bezpath.Outline();
  330. bezpath.SetFillMode(FillModeAlternate);
  331. renderinggraphics->FillPath(&transsolidbrush, &bezpath);
  332. }
  333. if (flags & PtTransGradFillFlag)
  334. {
  335. GraphicsPath bezpath;
  336. RemakePath(&gppath, &bezpath, flags & PtBezierFlag);
  337. Matrix m;
  338. bezpath.Flatten(&m, flatness);
  339. INT count = bezpath.GetPointCount();
  340. if (flags & PtOutlineBeforeFlag)
  341. bezpath.Outline();
  342. bezpath.SetFillMode(FillModeAlternate);
  343. PathGradientBrush pathgradientbrush(&bezpath);
  344. Color *colors = new Color[count];
  345. for (int i=0; i<count; i++)
  346. colors[i] = (i/2 == (float)i/2) ? 0xffff0000 : 0x80000000;
  347. pathgradientbrush.SetCenterColor(0x00000000);
  348. pathgradientbrush.SetSurroundColors(colors, &count);
  349. renderinggraphics->FillPath(&pathgradientbrush, &bezpath);
  350. delete colors;
  351. }
  352. if (!(flags & PtHatchBrushFlag))
  353. {
  354. SolidBrush pathbrush(Color(0xffc0c0ff));
  355. renderinggraphics->FillPath(&pathbrush, &widepath);
  356. }
  357. else
  358. {
  359. HatchBrush pathbrush(HatchStyleDiagonalBrick, Color(0xff000000), Color(0xffc0c0ff));
  360. renderinggraphics->FillPath(&pathbrush, &widepath);
  361. }
  362. Pen blackpen(Color(0xff000000), 2);
  363. blackpen.SetLineJoin(LineJoinMiter);
  364. renderinggraphics->DrawPath(&blackpen, &widepath);
  365. renderinggraphics->ResetClip();
  366. SolidBrush solidbrush(0xff0000ff);
  367. Pen pathpen(&solidbrush);
  368. pathpen.SetLineJoin(LineJoinRound);
  369. if (!(flags & PtDashPatternFlag))
  370. {
  371. pathpen.SetWidth(6);
  372. }
  373. else
  374. {
  375. pathpen.SetWidth(8);
  376. pathpen.SetDashStyle(DashStyleDot);
  377. pathpen.SetDashCap(DashCapRound);
  378. REAL distances[6] = {1.0f, 1.0f, 3.0f, 3.5f, 7.0f, 9.0f};
  379. pathpen.SetDashPattern(distances,6);
  380. }
  381. renderinggraphics->DrawPath(&pathpen, &gppath);
  382. PointF *points = new PointF[gppath.GetPointCount()];
  383. gppath.GetPathPoints(points, gppath.GetPointCount());
  384. for (INT i=0; i<gppath.GetPointCount(); i++)
  385. {
  386. SolidBrush bluebrush(Color(0xff0000ff));
  387. RectF rect((float)points[i].X-4, (float)points[i].Y-4, 8, 8);
  388. renderinggraphics->FillEllipse(&bluebrush, rect);
  389. }
  390. delete points;
  391. }
  392. if (clippath.GetPointCount() > 2)
  393. {
  394. Pen clippen(Color(0xffff0000), 4);
  395. clippen.SetDashStyle(DashStyleDot);
  396. clippen.SetLineJoin(LineJoinRound);
  397. renderinggraphics->DrawPath(&clippen, &clippath);
  398. }
  399. SolidBrush darkbluebrush(Color(0xff0000c0));
  400. if (lastpoint.X != -1 && lastpoint.Y != -1)
  401. {
  402. RectF rect(lastpoint.X-6, lastpoint.Y-6, 12, 12);
  403. renderinggraphics->FillEllipse(&darkbluebrush, rect);
  404. }
  405. delete renderinggraphics;
  406. if (phdc == NULL)
  407. {
  408. HDC hdc = GetDC(hwnd);
  409. Graphics *g = new Graphics(hdc);
  410. PAINTSTRUCT paintstruct;
  411. BeginPaint(hwnd, &paintstruct);
  412. g->DrawImage(offscreenbitmap, 0, 0);
  413. EndPaint(hwnd, &paintstruct);
  414. ReleaseDC(hwnd, hdc);
  415. delete g;
  416. }
  417. }