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.

1504 lines
38 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: test.c
  3. *
  4. * Created: 09-Dec-1992 10:51:46
  5. * Author: Kirk Olynyk [kirko]
  6. *
  7. * Copyright (c) 1991 Microsoft Corporation
  8. *
  9. * Contains the test
  10. *
  11. \**************************************************************************/
  12. #include <windows.h>
  13. #include <objbase.h>
  14. #include <math.h> // sin & cos
  15. #include "debug.h"
  16. #define USE_NEW_APIS 1
  17. #define USE_NEW_APIS2 1
  18. //
  19. // Where is IStream included from?
  20. //
  21. #define IStream int
  22. #include <gdiplus.h>
  23. using namespace Gdiplus;
  24. /******************************Public*Routine******************************\
  25. * vTest
  26. *
  27. * This is the workhorse routine that does the test. The test is
  28. * started by chosing it from the window menu.
  29. *
  30. * History:
  31. * Tue 08-Dec-1992 17:31:22 by Kirk Olynyk [kirko]
  32. * Wrote it.
  33. \**************************************************************************/
  34. class RectI
  35. {
  36. public:
  37. INT X;
  38. INT Y;
  39. INT Width;
  40. INT Height;
  41. };
  42. VOID TestContainerClip(Graphics *g);
  43. VOID TestContainer(Graphics *g);
  44. VOID TestPolygons(Graphics *g);
  45. VOID TestPaths(Graphics *g);
  46. VOID TestDashes(Graphics *g);
  47. VOID TestRegions(Graphics *g);
  48. VOID TestGradients(Graphics* g);
  49. VOID TestHatches(Graphics* g);
  50. VOID TestBitmaps(Graphics* g);
  51. VOID TestPrimitives(Graphics *g);
  52. VOID TestMixedObjects(Graphics *g);
  53. VOID TestTexts(Graphics* g);
  54. VOID TestTextAlongPath(Graphics *g);
  55. VOID TestDerive(HWND hwnd);
  56. VOID TestImaging(Graphics* g);
  57. VOID TestBitmapGraphics(Graphics* g);
  58. VOID TestCompoundLines(Graphics *g);
  59. VOID
  60. Test(
  61. HWND hwnd
  62. )
  63. {
  64. Graphics *g = Graphics::FromHWND(hwnd);
  65. g->SetSmoothingMode(SmoothingModeAntiAlias);
  66. // Scale everything up by scale
  67. REAL scale = (REAL) 1.2;
  68. g->SetPageUnit(UnitDisplay);
  69. g->SetPageScale(scale);
  70. g->RotateTransform(10);
  71. {
  72. HDC hdc = GetDC(hwnd);
  73. {
  74. Metafile recording(L"TestEmfP.Emf", hdc);
  75. Graphics gMeta(&recording);
  76. gMeta.SetSmoothingMode(SmoothingModeAntiAlias);
  77. TestContainer(&gMeta);
  78. }
  79. GpRectF playbackRect;
  80. g->GetVisibleClipBounds(&playbackRect);
  81. {
  82. Metafile playback(L"TestEmfP.Emf");
  83. g->DrawImage(&playback, playbackRect);
  84. }
  85. ReleaseDC(hwnd, hdc);
  86. }
  87. TestContainerClip(g);
  88. TestPolygons(g);
  89. TestPaths(g);
  90. TestRegions(g);
  91. TestBitmaps(g);
  92. TestPrimitives(g);
  93. TestMixedObjects(g);
  94. TestGradients(g);
  95. TestHatches(g);
  96. TestTexts(g);
  97. TestDerive(hwnd);
  98. TestImaging(g);
  99. TestDashes(g);
  100. TestBitmapGraphics(g);
  101. TestCompoundLines(g);
  102. delete g;
  103. }
  104. VOID DrawContainer(Graphics * g, ARGB * argb, INT count)
  105. {
  106. Matrix mymatrix;
  107. g->SetPageUnit(UnitInch);
  108. Rect clipRect(0,0,5,5);
  109. g->SetClip(clipRect);
  110. mymatrix.Translate(2.5, 2.5);
  111. mymatrix.Rotate(15);
  112. mymatrix.Translate(-2.5, -2.5);
  113. g->SetTransform(&mymatrix);
  114. Color color(*argb++);
  115. SolidBrush contBrush(color);
  116. g->FillRectangle(&contBrush, 0, 0, 5, 5);
  117. if (--count == 0)
  118. {
  119. return;
  120. }
  121. RectF destRect(.5, .5, 4, 4);
  122. RectF srcRect(0, 0, 5, 5);
  123. INT id = g->BeginContainer(destRect, srcRect, UnitInch);
  124. g->ResetClip();
  125. DrawContainer (g, argb, count);
  126. g->EndContainer(id);
  127. }
  128. VOID TestContainerClip(Graphics *g)
  129. {
  130. ARGB colors[5];
  131. colors[0] = Color::MakeARGB(255, 255, 0, 0);
  132. colors[1] = Color::MakeARGB(255, 0, 255, 0);
  133. colors[2] = Color::MakeARGB(255, 0, 0, 255);
  134. colors[3] = Color::MakeARGB(255, 255, 255, 0);
  135. colors[4] = Color::MakeARGB(255, 0, 255, 255);
  136. GraphicsState s = g->Save();
  137. DrawContainer(g, colors, 5);
  138. g->Restore(s);
  139. }
  140. GraphicsPath circlePath;
  141. RectF circleRect(0,0,4,4);
  142. #define ROOT 0
  143. #define LEFT 1
  144. #define RIGHT 2
  145. #define TOP 3
  146. #define BOTTOM 4
  147. VOID DrawFractal(Graphics * g, BYTE gray, INT side, INT count)
  148. {
  149. ARGB argb;
  150. switch (count % 3)
  151. {
  152. case 0:
  153. argb = Color::MakeARGB(255, 0, 0, gray);
  154. break;
  155. case 1:
  156. argb = Color::MakeARGB(255, 0, gray, 0);
  157. break;
  158. case 2:
  159. argb = Color::MakeARGB(255, gray, 0, 0);
  160. gray -= 60;
  161. break;
  162. }
  163. Color color(argb);
  164. SolidBrush contBrush(color);
  165. g->SetPageUnit(UnitInch);
  166. g->FillPath(&contBrush, &circlePath);
  167. if (--count == 0)
  168. {
  169. return;
  170. }
  171. RectF destRect;
  172. GraphicsContainer cstate;
  173. if (side != LEFT)
  174. {
  175. destRect = RectF(4, 1, 2, 2);
  176. cstate = g->BeginContainer(destRect, circleRect, UnitInch);
  177. g->SetSmoothingMode(SmoothingModeAntiAlias);
  178. DrawFractal(g, gray, RIGHT, count);
  179. g->EndContainer(cstate);
  180. }
  181. if (side != TOP)
  182. {
  183. destRect = RectF(1, 4, 2, 2);
  184. cstate = g->BeginContainer(destRect, circleRect, UnitInch);
  185. g->SetSmoothingMode(SmoothingModeAntiAlias);
  186. DrawFractal(g, gray, BOTTOM, count);
  187. g->EndContainer(cstate);
  188. }
  189. if (side != RIGHT)
  190. {
  191. destRect = RectF(-2, 1, 2, 2);
  192. cstate = g->BeginContainer(destRect, circleRect, UnitInch);
  193. g->SetSmoothingMode(SmoothingModeAntiAlias);
  194. DrawFractal(g, gray, LEFT, count);
  195. g->EndContainer(cstate);
  196. }
  197. if (side != BOTTOM)
  198. {
  199. destRect = RectF(1, -2, 2, 2);
  200. cstate = g->BeginContainer(destRect, circleRect, UnitInch);
  201. g->SetSmoothingMode(SmoothingModeAntiAlias);
  202. DrawFractal(g, gray, TOP, count);
  203. g->EndContainer(cstate);
  204. }
  205. }
  206. VOID TestContainer(Graphics * g)
  207. {
  208. circlePath.AddEllipse(circleRect);
  209. INT id = g->Save();
  210. g->TranslateTransform(5, 4);
  211. DrawFractal(g, 245, ROOT, 8);
  212. g->Restore(id);
  213. }
  214. /**************************************************************************\
  215. * TestPolygons
  216. *
  217. * A test for drawing and filling of rectangles and polygons.
  218. *
  219. \**************************************************************************/
  220. VOID TestPolygons(Graphics *g)
  221. {
  222. REAL width = 4; // Pen width
  223. Color redColor(255, 0, 0);
  224. SolidBrush redBrush(redColor);
  225. g->FillRectangle(&redBrush, 20, 20, 50, 50);
  226. Color alphaColor(128, 0, 255, 0);
  227. SolidBrush alphaBrush(alphaColor);
  228. g->FillRectangle(&alphaBrush, 10, 10, 40, 40);
  229. Point points[4];
  230. points[0].X = 50;
  231. points[0].Y = 50;
  232. points[1].X = 100;
  233. points[1].Y = 50;
  234. points[2].X = 120;
  235. points[2].Y = 120;
  236. points[3].X = 50;
  237. points[3].Y = 100;
  238. Color blueColor(128, 0, 0, 255);
  239. SolidBrush blueBrush(blueColor);
  240. g->FillPolygon(&blueBrush, points, 4);
  241. // Currently only Geometric pen works for lines. - ikkof 1/6/99.
  242. Color blackColor(0, 0, 0);
  243. SolidBrush blackBrush(blackColor);
  244. Pen blackPen(&blackBrush, width);
  245. blackPen.SetLineJoin(LineJoinRound);
  246. g->DrawPolygon(&blackPen, points, 4);
  247. // g->DrawLines(&blackPen, points, 4, FALSE);
  248. }
  249. /**************************************************************************\
  250. * TestPaths
  251. *
  252. * A test for general paths.
  253. *
  254. \**************************************************************************/
  255. VOID TestPaths(Graphics *g)
  256. {
  257. REAL width = 4; // Pen width
  258. Point points[4];
  259. points[0].X = 100;
  260. points[0].Y = 10;
  261. points[1].X = -50;
  262. points[1].Y = 50;
  263. points[2].X = 150;
  264. points[2].Y = 200;
  265. points[3].X = 200;
  266. points[3].Y = 70;
  267. Color yellowColor(128, 255, 255, 0);
  268. SolidBrush yellowBrush(yellowColor);
  269. GraphicsPath* path = new GraphicsPath(FillModeAlternate);
  270. path->AddBeziers(points, 4);
  271. Matrix matrix;
  272. matrix.Scale(1.5, 1.5);
  273. path->Transform(&matrix);
  274. Color blackColor(0, 0, 0);
  275. SolidBrush blackBrush(blackColor);
  276. // Set the pen width in inch.
  277. width = (REAL) 0.2;
  278. Pen blackPen(&blackBrush, width);
  279. blackPen.SetStartCap(LineCapRound);
  280. // blackPen.SetEndCap(LineCapSquare);
  281. blackPen.SetEndCap(LineCapArrowAnchor);
  282. Region * region = new Region(path);
  283. g->FillPath(&yellowBrush, path);
  284. g->DrawPath(&blackPen, path);
  285. delete path;
  286. delete region;
  287. }
  288. /**************************************************************************\
  289. * TestDashes
  290. *
  291. * A test for drawing dashed lines.
  292. *
  293. \**************************************************************************/
  294. VOID TestDashes(Graphics *g)
  295. {
  296. REAL width = 4; // Pen width
  297. PointF points[4];
  298. points[0].X = 100;
  299. points[0].Y = 10;
  300. points[1].X = -50;
  301. points[1].Y = 50;
  302. points[2].X = 150;
  303. points[2].Y = 200;
  304. points[3].X = 200;
  305. points[3].Y = 70;
  306. Color yellowColor(128, 255, 255, 0);
  307. SolidBrush yellowBrush(yellowColor);
  308. GraphicsPath* path = new GraphicsPath(FillModeAlternate);
  309. path->AddBeziers(points, 4);
  310. Matrix matrix;
  311. matrix.Scale(1.5, 1.5);
  312. path->Transform(&matrix);
  313. Color blackColor(0, 0, 0);
  314. SolidBrush blackBrush(blackColor);
  315. // Set the pen width in inch.
  316. width = (REAL) 0.2;
  317. Pen pen1(&blackBrush, width);
  318. pen1.SetDashStyle(DashStyleDashDotDot);
  319. pen1.SetDashCap(DashCapRound);
  320. g->DrawPath(&pen1, path);
  321. // Create a multiple segment with a closed segment.
  322. points[0].X = 50;
  323. points[0].Y = 50;
  324. points[1].X = 100;
  325. points[1].Y = 50;
  326. points[2].X = 120;
  327. points[2].Y = 120;
  328. points[3].X = 50;
  329. points[3].Y = 100;
  330. path->Reset();
  331. path->AddLines(points, 4);
  332. path->CloseFigure();
  333. points[0].X = 150;
  334. points[0].Y = 60;
  335. points[1].X = 200;
  336. points[1].Y = 150;
  337. path->AddLines(points, 2);
  338. path->Transform(&matrix);
  339. Color blueColor(128, 0, 0, 255);
  340. SolidBrush blueBrush(blueColor);
  341. width = 5;
  342. Pen pen2(&blueBrush, width);
  343. pen2.SetDashStyle(DashStyleDashDotDot);
  344. g->DrawPath(&pen2, path);
  345. delete path;
  346. }
  347. /**************************************************************************\
  348. * TestRegions
  349. *
  350. * A test for region fill.
  351. *
  352. \**************************************************************************/
  353. VOID TestRegions(Graphics *g)
  354. {
  355. REAL width = 2; // Pen width
  356. PointF points[5];
  357. REAL s, c, theta;
  358. REAL pi = 3.1415926535897932f;
  359. REAL scale = 30;
  360. PointF orig(200, 140);
  361. theta = -pi/2;
  362. // Create a star shape.
  363. for(INT i = 0; i < 5; i++)
  364. {
  365. s = sinf(theta);
  366. c = cosf(theta);
  367. points[i].X = scale*c + orig.X;
  368. points[i].Y = scale*s + orig.Y;
  369. theta += 0.8f*pi;
  370. }
  371. Color orangeColor(128, 255, 180, 0);
  372. SolidBrush orangeBrush(orangeColor);
  373. GraphicsPath* path = new GraphicsPath(FillModeAlternate);
  374. // Path* path = new GraphicsPath(Winding);
  375. path->AddPolygon(points, 5);
  376. Color blackColor(0, 0, 0);
  377. SolidBrush blackBrush(blackColor);
  378. Pen blackPen(&blackBrush, width);
  379. Region * region = new Region(path);
  380. g->FillRegion(&orangeBrush, region); // There is a BUG!
  381. // g->FillGraphicsPath(&orangeBrush, path); // Fill path works fine.
  382. blackPen.SetLineJoin(LineJoinMiter);
  383. g->DrawPath(&blackPen, path);
  384. delete path;
  385. delete region;
  386. }
  387. GraphicsPath* CreateHeartPath(const RectF& rect)
  388. {
  389. GpPointF points[7];
  390. points[0].X = 0;
  391. points[0].Y = 0;
  392. points[1].X = 1.00;
  393. points[1].Y = -1.00;
  394. points[2].X = 2.00;
  395. points[2].Y = 1.00;
  396. points[3].X = 0;
  397. points[3].Y = 2.00;
  398. points[4].X = -2.00;
  399. points[4].Y = 1.00;
  400. points[5].X = -1.00;
  401. points[5].Y = -1.00;
  402. points[6].X = 0;
  403. points[6].Y = 0;
  404. Matrix matrix;
  405. matrix.Scale(rect.Width/2, rect.Height/3, MatrixOrderAppend);
  406. matrix.Translate(3*rect.Width/2, 4*rect.Height/3, MatrixOrderAppend);
  407. matrix.TransformPoints(&points[0], 7);
  408. GraphicsPath* path = new GraphicsPath();
  409. if(path)
  410. {
  411. path->AddBeziers(&points[0], 7);
  412. path->CloseFigure();
  413. }
  414. return path;
  415. }
  416. /**************************************************************************\
  417. * TestGradients
  418. *
  419. * A test for rectangle and radial gradients.
  420. *
  421. \**************************************************************************/
  422. VOID TestGradients(Graphics* g)
  423. {
  424. REAL width = 4; // Pen width
  425. // Create a rectangular gradient brush.
  426. RectF brushRect(0, 0, 32, 32);
  427. Color colors[5] = {
  428. Color(255, 255, 255, 255),
  429. Color(255, 255, 0, 0),
  430. Color(255, 0, 255, 0),
  431. Color(255, 0, 0, 255),
  432. Color(255, 0, 0, 0)
  433. };
  434. // RectangleGradientBrush rectGrad(brushRect, (Color*) &colors, WrapModeTile);
  435. // Rotate a brush.
  436. GpMatrix xForm;
  437. xForm.Rotate(30);
  438. // rectGrad.SetTransform(&xForm);
  439. // Change the wrapping mode and fill.
  440. // !! No longer supported
  441. // rectGrad.SetWrapMode(WrapModeTileFlipXY);
  442. // g->FillRectangle(&rectGrad, 350, 20, 100, 80);
  443. Color blackColor(0, 0, 0);
  444. SolidBrush blackBrush(blackColor);
  445. Pen blackPen(&blackBrush, width);
  446. g->DrawRectangle(&blackPen, brushRect);
  447. // Create a radial gradient brush.
  448. Color centerColor(255, 255, 255, 255);
  449. Color boundaryColor(255, 0, 0, 0);
  450. brushRect.X = 380;
  451. brushRect.Y = 130;
  452. brushRect.Width = 60;
  453. brushRect.Height = 32;
  454. PointF center;
  455. center.X = brushRect.X + brushRect.Width/2;
  456. center.Y = brushRect.Y + brushRect.Height/2;
  457. xForm.Reset();
  458. xForm.RotateAt(-30, center, MatrixOrderAppend);
  459. // !! No longer supported
  460. // RadialGradientBrush radGrad(brushRect, centerColor,
  461. // boundaryColor, WrapModeClamp);
  462. // radGrad.SetTransform(&xForm);
  463. // g->FillRectangle(&radGrad, 320, 120, 120, 100);
  464. // Pen gradPen(&rectGrad, width);
  465. // g->DrawRectangle(&gradPen, 320, 120, 120, 100);
  466. // Triangle gradient.
  467. PointF points[7];
  468. points[0].X = 50;
  469. points[0].Y = 10;
  470. points[1].X = 200;
  471. points[1].Y = 20;
  472. points[2].X = 100;
  473. points[2].Y = 100;
  474. points[3].X = 30;
  475. points[3].Y = 120;
  476. Color colors1[5] = {
  477. Color(255, 255, 255, 0),
  478. Color(255, 255, 0, 0),
  479. Color(255, 0, 255, 0),
  480. Color(255, 0, 0, 255),
  481. Color(255, 0, 0, 0)
  482. };
  483. // !! No longer supported
  484. // TriangleGradientBrush triGrad(points, (Color*) &colors);
  485. // g->FillPolygon(&triGrad, points, 3);
  486. RectF triRect;
  487. // triGrad.GetRectangle(triRect);
  488. // g->FillRectangle(&triGrad, triRect);
  489. points[0].X = 200;
  490. points[0].Y = 300;
  491. points[1].X = 280;
  492. points[1].Y = 350;
  493. points[2].X = 220;
  494. points[2].Y = 420;
  495. points[3].X = 160;
  496. points[3].Y = 440;
  497. points[4].X = 120;
  498. points[4].Y = 370;
  499. PathGradientBrush polyGrad(points, 5);
  500. REAL blend[10];
  501. Color presetColors[10];
  502. REAL positions[10];
  503. INT count;
  504. INT i;
  505. count = 3;
  506. blend[0] = (REAL) 0;
  507. blend[1] = (REAL) 0;
  508. blend[2] = (REAL) 1;
  509. positions[0] = (REAL) 0;
  510. positions[1] = (REAL) 0.4;
  511. positions[2] = (REAL) 1;
  512. // Test for blending factors.
  513. polyGrad.SetBlend(&blend[0], &positions[0], count);
  514. polyGrad.SetCenterColor(centerColor);
  515. i = 5;
  516. polyGrad.SetSurroundColors(colors1, &i);
  517. // g->FillPolygon(&polyGrad, points, 5);
  518. RectF polyRect;
  519. polyGrad.GetRectangle(&polyRect);
  520. g->FillRectangle(&polyGrad, polyRect);
  521. // Create a heart shaped path.
  522. RectF rect;
  523. rect.X = 300;
  524. rect.Y = 300;
  525. rect.Width = 150;
  526. rect.Height = 150;
  527. GraphicsPath *path = CreateHeartPath(rect);
  528. // Create a gradient from a path.
  529. PathGradientBrush pathGrad(path);
  530. delete path;
  531. pathGrad.SetCenterColor(centerColor);
  532. i = 1;
  533. pathGrad.SetSurroundColors(&Color(255, 255, 0, 0), &i);
  534. pathGrad.GetRectangle(&polyRect);
  535. // Set the rect focus.
  536. PointF centerPt;
  537. pathGrad.GetCenterPoint(&centerPt);
  538. centerPt.X -= 15;
  539. centerPt.Y += 30;
  540. pathGrad.SetCenterPoint(centerPt);
  541. REAL xScale, yScale;
  542. pathGrad.GetFocusScales(&xScale, &yScale);
  543. xScale = 0.4f;
  544. yScale = 0.3f;
  545. pathGrad.SetFocusScales(xScale, yScale);
  546. g->FillRectangle(&pathGrad, polyRect);
  547. // Test for LineGradientBrush.
  548. RectF lineRect(120, -20, 200, 60);
  549. Color color1(200, 255, 255, 0);
  550. Color color2(200, 0, 0, 255);
  551. LinearGradientBrush lineGrad(lineRect, color1, color1,
  552. LinearGradientModeForwardDiagonal);
  553. // Test for preset colors
  554. presetColors[0] = Color(200, 0, 255, 255);
  555. presetColors[1] = Color(200, 255, 255, 0);
  556. presetColors[2] = Color(200, 0, 255, 0);
  557. lineGrad.SetInterpolationColors(&presetColors[0], &positions[0], count);
  558. g->FillRectangle(&lineGrad, lineRect);
  559. }
  560. /**************************************************************************\
  561. * TestHatches
  562. *
  563. * A test for hatch brushes
  564. *
  565. \**************************************************************************/
  566. VOID TestHatches(Graphics* g)
  567. {
  568. Color foreColor(0, 0, 0);
  569. Color backColor(128, 255, 255, 255);
  570. HatchStyle style[6];
  571. style[0] = HatchStyleForwardDiagonal;
  572. style[1] = HatchStyleBackwardDiagonal;
  573. style[2] = HatchStyleCross;
  574. style[3] = HatchStyleDiagonalCross;
  575. style[4] = HatchStyleHorizontal;
  576. style[5] = HatchStyleVertical;
  577. // Pick one of the above hatch styles.
  578. HatchBrush hatch(style[3], foreColor, backColor);
  579. g->FillRectangle(&hatch, 200, 20, 100, 80);
  580. }
  581. /**************************************************************************\
  582. * TestBitmaps
  583. *
  584. * A test for texture filling and DrawImage.
  585. *
  586. \**************************************************************************/
  587. VOID TestBitmaps(Graphics* g)
  588. {
  589. Point points[4];
  590. REAL width = 4; // Pen width
  591. WCHAR filename[256];
  592. wcscpy(filename, L"../data/brick.jpg");
  593. Bitmap *bitmap = new Bitmap(filename);
  594. // Create a texture brush.
  595. RectI copyRect;
  596. copyRect.X = 0;
  597. copyRect.Y = 0;
  598. copyRect.Width = 40;
  599. copyRect.Height = 30;
  600. Bitmap *copiedBitmap = bitmap->Clone(copyRect.X, copyRect.Y,
  601. copyRect.Width, copyRect.Height,
  602. PixelFormat32bppARGB);
  603. if(copiedBitmap)
  604. {
  605. // Create a texture brush.
  606. TextureBrush textureBrush(copiedBitmap, WrapModeTile);
  607. //copiedBitmap->Dispose();
  608. // Create a radial gradient pen.
  609. Color redColor(255, 0, 0);
  610. SolidBrush redBrush(redColor);
  611. Pen redPen(&redBrush, width);
  612. GraphicsPath *path;
  613. points[0].X = 100;
  614. points[0].Y = 60;
  615. points[1].X = -50;
  616. points[1].Y = 60;
  617. points[2].X = 150;
  618. points[2].Y = 250;
  619. points[3].X = 200;
  620. points[3].Y = 120;
  621. path = new GraphicsPath(FillModeAlternate);
  622. path->AddBeziers(points, 4);
  623. g->FillPath(&textureBrush, path);
  624. g->DrawPath(&redPen, path);
  625. delete path;
  626. delete copiedBitmap;
  627. }
  628. delete bitmap;
  629. PointF destPoints[3];
  630. destPoints[0].X = 300;
  631. destPoints[0].Y = 50;
  632. destPoints[1].X = 450;
  633. destPoints[1].Y = 50;
  634. destPoints[2].X = 240;
  635. destPoints[2].Y = 200;
  636. Matrix mat;
  637. mat.Translate(0, 100);
  638. mat.TransformPoints(&destPoints[0], 3);
  639. wcscpy(filename, L"../data/apple1.png");
  640. bitmap = new Bitmap(filename);
  641. g->DrawImage(bitmap, &destPoints[0], 3);
  642. delete bitmap;
  643. destPoints[0].X = 30;
  644. destPoints[0].Y = 200;
  645. destPoints[1].X = 200;
  646. destPoints[1].Y = 200;
  647. destPoints[2].X = 200;
  648. destPoints[2].Y = 420;
  649. wcscpy(filename, L"../data/dog2.png");
  650. bitmap = new Bitmap(filename);
  651. g->DrawImage(bitmap, &destPoints[0], 3);
  652. delete bitmap;
  653. Color color(100, 128, 255, 0);
  654. SolidBrush brush(color);
  655. Point pts[10];
  656. INT count = 4;
  657. pts[0].X = 150;
  658. pts[0].Y = 60;
  659. pts[1].X = 100;
  660. pts[1].Y = 230;
  661. pts[2].X = 250;
  662. pts[2].Y = 260;
  663. pts[3].X = 350;
  664. pts[3].Y = 100;
  665. g->FillClosedCurve(&brush, pts, count);
  666. wcscpy(filename, L"../data/ballmer.jpg");
  667. bitmap = new Bitmap(filename);
  668. RectF destRect(220, 50, 180, 120);
  669. RectF srcRect;
  670. srcRect.X = 100;
  671. srcRect.Y = 40;
  672. srcRect.Width = 200;
  673. srcRect.Height = 200;
  674. g->DrawImage(bitmap, destRect, srcRect.X, srcRect.Y,
  675. srcRect.Width, srcRect.Height, UnitPixel);
  676. delete bitmap;
  677. }
  678. /**************************************************************************\
  679. * TestPrimitives
  680. *
  681. * A test for ellipse, arc, pie, curve, and closed curve.
  682. *
  683. \**************************************************************************/
  684. VOID
  685. TestPrimitives(
  686. Graphics* g
  687. )
  688. {
  689. RectF rect;
  690. rect.X = 250;
  691. rect.Y = 230;
  692. rect.Width = 150;
  693. rect.Height = 100;
  694. Color color(128, 128, 255, 0);
  695. SolidBrush brush(color);
  696. REAL width = 1;
  697. Color blackColor(0, 0, 0);
  698. SolidBrush blackBrush(blackColor);
  699. Pen pen(&blackBrush, width);
  700. // g->FillEllipse(&brush, rect);
  701. // g->DrawEllipse(&pen, rect);
  702. REAL startAngle = 0;
  703. REAL sweepAngle = 240;
  704. g->FillPie(&brush, rect, startAngle, sweepAngle);
  705. g->DrawPie(&pen, rect, startAngle, sweepAngle);
  706. PointF pts[10];
  707. INT count = 4;
  708. pts[0].X = 200;
  709. pts[0].Y = 160;
  710. pts[1].X = 150;
  711. pts[1].Y = 230;
  712. pts[2].X = 200;
  713. pts[2].Y = 260;
  714. pts[3].X = 300;
  715. pts[3].Y = 200;
  716. g->FillClosedCurve(&brush, pts, count);
  717. g->DrawClosedCurve(&pen, pts, count);
  718. }
  719. /**************************************************************************\
  720. * TestMixedObjects
  721. *
  722. * A test for different brushes and pens.
  723. *
  724. \**************************************************************************/
  725. VOID TestMixedObjects(Graphics* g)
  726. {
  727. Point points[10];
  728. REAL width = 4; // Pen width
  729. // Load bmp files.
  730. WCHAR *filename = L"winnt256.bmp";
  731. Bitmap *bitmap = new Bitmap(filename);
  732. // Create a texture brush.
  733. RectI copyRect;
  734. copyRect.X = 60;
  735. copyRect.Y = 60;
  736. copyRect.Width = 80;
  737. copyRect.Height = 60;
  738. Bitmap *copiedBitmap = bitmap->Clone(copyRect.X, copyRect.Y,
  739. copyRect.Width, copyRect.Height,
  740. PixelFormat32bppPARGB);
  741. // Create a rectangular gradient brush.
  742. RectF brushRect(0, 0, 32, 32);
  743. Color colors[4] = {
  744. Color(255, 255, 255, 255),
  745. Color(255, 255, 0, 0),
  746. Color(255, 0, 255, 0),
  747. Color(255, 0, 0, 255)
  748. };
  749. // !! No longer supported
  750. // RectangleGradientBrush rectGrad(brushRect, (Color*)&colors, WrapModeTile);
  751. width = 8;
  752. // Pen gradPen(&rectGrad, width);
  753. if(copiedBitmap)
  754. {
  755. // Create a texture brush.
  756. TextureBrush textureBrush(copiedBitmap, WrapModeTile);
  757. //copiedBitmap->Dispose();
  758. // Create a radial gradient pen.
  759. points[3].X = 50;
  760. points[3].Y = 300;
  761. points[2].X = 100;
  762. points[2].Y = 300;
  763. points[1].X = 120;
  764. points[1].Y = 370;
  765. points[0].X = 50;
  766. points[0].Y = 350;
  767. // gradPen.SetLineJoin(LineJoinMiter);
  768. g->FillPolygon(&textureBrush, points, 4);
  769. // g->DrawPolygon(&gradPen, points, 4);
  770. }
  771. delete copiedBitmap;
  772. delete bitmap;
  773. }
  774. /**************************************************************************\
  775. * TestTexts
  776. *
  777. * A test for drawing texts.
  778. *
  779. \**************************************************************************/
  780. VOID TestTexts(Graphics *g)
  781. {
  782. //Font font(L"Arial", 60);
  783. FontFamily ff(L"Arial");
  784. RectF rectf(20, 0, 300, 200);
  785. GraphicsPath path;
  786. // Solid color text.
  787. Color color(128, 100, 0, 200);
  788. SolidBrush brush(color);
  789. path.AddString(L"Color", 5, &ff, 0, 60, rectf, NULL);
  790. g->FillPath(&brush, &path);
  791. // Texture text.
  792. WCHAR filename[256];
  793. wcscpy(filename, L"../data/marble1.jpg");
  794. Bitmap *bitmap = new Bitmap(filename);
  795. TextureBrush textureBrush(bitmap, WrapModeTile);
  796. path.Reset();
  797. rectf.X = 200;
  798. rectf.Y = 20;
  799. path.AddString(L"Texture", 7, &ff, 0, 60, rectf, NULL);
  800. g->FillPath(&textureBrush, &path);
  801. delete bitmap;
  802. // Gradient text.
  803. rectf.X = 40;
  804. rectf.Y = 80;
  805. path.Reset();
  806. path.AddString(L"Gradient", 8, &ff, 0, 60, rectf, NULL);
  807. Color color1(255, 255, 0, 0);
  808. Color color2(255, 0, 255, 0);
  809. LinearGradientBrush lineGrad(rectf, color1, color2, 0.0f);
  810. g->FillPath(&lineGrad, &path);
  811. // Shadow test
  812. REAL charHeight = 60;
  813. REAL topMargin = - 5;
  814. rectf.X = 0;
  815. rectf.Y = - charHeight - topMargin; // Make y-coord of the base line
  816. // of the characters to be 0.
  817. path.Reset();
  818. path.AddString(L"Shadow", 6, &ff, 0, charHeight, rectf, NULL);
  819. GraphicsPath* clonePath = path.Clone();
  820. Color redColor(255, 0, 0);
  821. Color grayColor(128, 0, 0, 0);
  822. SolidBrush redBrush(redColor);
  823. SolidBrush grayBrush(grayColor);
  824. // Shadow part.
  825. REAL tx = 180, ty = 200;
  826. Matrix skew;
  827. skew.Scale(1.0, 0.5);
  828. skew.Shear(-2.0, 0, MatrixOrderAppend);
  829. skew.Translate(tx, ty, MatrixOrderAppend);
  830. clonePath->Transform(&skew);
  831. g->FillPath(&grayBrush, clonePath);
  832. delete clonePath;
  833. // Front part.
  834. Matrix trans1;
  835. trans1.Translate(tx, ty);
  836. path.Transform(&trans1);
  837. g->FillPath(&redBrush, &path);
  838. return;
  839. /*
  840. REAL x = 200, y = 150;
  841. RectF brushRect(x, y, 150, 32);
  842. Color colors[4] = {
  843. Color(180, 255, 0, 0),
  844. Color(180, 0, 255, 0),
  845. Color(180, 255, 0, 0),
  846. Color(180, 0, 255, 0)
  847. };
  848. RectangleGradientBrush rectGrad(brushRect, (Color*)&colors, WrapModeTile);
  849. g->DrawString(L"GDI+", &font, &rectGrad, x, y);
  850. // And now with DrawText
  851. RectF rect(400, 200, 400, 400);
  852. g->DrawText(
  853. DrawTextDisplay,
  854. L"A few words powered by GDI+: \
  855. \x3c3\x3bb\x3b1\x3b4 \
  856. \x627\x644\x633\x644\x627\x645 \
  857. \x5e9\x5dc\x5d5\x5dd \
  858. \xe2d\xe4d\xe01\xe29\xe23\xe44\xe17\xe22 \
  859. \x110\x068\x0ea\x300\x103",
  860. &font, // Initial font
  861. &rectGrad, // Initial brush (ignored for the time being)
  862. LANG_NEUTRAL, // Initial language
  863. &rect // Formatting rectangle
  864. );
  865. */
  866. }
  867. VOID TestTextAlongPath(Graphics *g)
  868. {
  869. Point points[4];
  870. points[3].X = 100;
  871. points[3].Y = 10;
  872. points[2].X = -50;
  873. points[2].Y = 50;
  874. points[1].X = 150;
  875. points[1].Y = 200;
  876. points[0].X = 200;
  877. points[0].Y = 70;
  878. GraphicsPath* path = new GraphicsPath(FillModeAlternate);
  879. path->AddBeziers(points, 4);
  880. Matrix matrix;
  881. matrix.Scale(1.5, 1.5);
  882. path->Transform(&matrix);
  883. Color textColor(180, 200, 0, 200);
  884. SolidBrush textBrush(textColor);
  885. WCHAR text[] = L"Windows 2000";
  886. REAL offset = 60;
  887. // g->DrawString(text, 12, NULL, path, NULL, &textBrush, offset);
  888. delete path;
  889. }
  890. /**************************************************************************\
  891. * TestDerive
  892. *
  893. * Test
  894. * A test for derivation support.
  895. *
  896. \**************************************************************************/
  897. VOID
  898. TestDerive(
  899. HWND hwnd
  900. )
  901. {
  902. HDC hdcScreen = GetDC(hwnd);
  903. HRGN hrgn = CreateEllipticRgn(10, 10, 300, 300);
  904. SetMapMode(hdcScreen, MM_TWIPS);
  905. SelectClipRgn(hdcScreen, hrgn);
  906. HBRUSH hbrushRed = CreateSolidBrush(RGB(255, 0, 0));
  907. SelectObject(hdcScreen, hbrushRed);
  908. Rectangle(hdcScreen, 0, 0, 3000, -3000);
  909. {
  910. Graphics g(hdcScreen);
  911. SolidBrush solidBrush(Color(0, 255, 0));
  912. g.FillRectangle(&solidBrush, 0, -3000, 3000, 3000);
  913. }
  914. HBITMAP hbmBitmap = CreateCompatibleBitmap(hdcScreen, 50, 50);
  915. HDC hdcBitmap = CreateCompatibleDC(hdcScreen);
  916. SelectObject(hdcBitmap, hbmBitmap);
  917. SetWindowOrgEx(hdcBitmap, 40, 80, NULL);
  918. SelectObject(hdcBitmap, hbrushRed);
  919. Rectangle(hdcBitmap, 40, 80, 50, 50);
  920. {
  921. Graphics g(hdcBitmap);
  922. SolidBrush solidBrush(Color(0, 0, 255));
  923. g.FillRectangle(&solidBrush, 40, 80, 90, 130);
  924. #if 0
  925. // The DC that we get back should have the same transform set
  926. // as that which we originally passed in:
  927. HDC hdcGet = g.GetHdc();
  928. point.x = 0;
  929. point.y = 0;
  930. DPtoLP(hdcGet, &point, 1);
  931. // !!! BAD on Alpha box
  932. // if ((hdcGet == NULL) || (point.x != 40) || (point.y != 80)) _asm int 3;
  933. g.ReleaseHdc(hdcGet);
  934. #endif
  935. }
  936. // The DC should have beeen returned to the top save level:
  937. INT saveLevel = SaveDC(hdcBitmap);
  938. // !!! BAD on Alpha box
  939. // if (saveLevel != 1) _asm int 3;
  940. // The DC should have had its transform restored:
  941. POINT oldPoint;
  942. SetWindowOrgEx(hdcBitmap, 0, 0, &oldPoint);
  943. // !!! BAD on Alpha box
  944. // if ((oldPoint.x != 40) || (oldPoint.y != 80)) _asm int 3;
  945. // Blt the (hopefully) blue square to the screen. But first,
  946. // reset our transform on 'hdcScreen' the lazy way:
  947. ReleaseDC(hwnd, hdcScreen);
  948. hdcScreen = GetDC(hwnd);
  949. BitBlt(hdcScreen, 0, 0, 50, 50, hdcBitmap, 0, 0, SRCCOPY);
  950. ReleaseDC(hwnd, hdcScreen);
  951. }
  952. /**************************************************************************\
  953. * TestImaging
  954. *
  955. * A test for imaging and DrawImage.
  956. *
  957. \**************************************************************************/
  958. BOOL CALLBACK MyDrawImageAbort(VOID* data)
  959. {
  960. UINT *count = (UINT*) data;
  961. *count += 1;
  962. //LBprintf("MyDrawImageAbort: %ld", *count);
  963. return FALSE;
  964. }
  965. VOID TestImaging(Graphics* g)
  966. {
  967. // Load bmp files.
  968. WCHAR *filename = L"winnt256.bmp";
  969. Image *image = new Image(filename);
  970. // Get information on the image.
  971. Image *imageThumb = image->GetThumbnailImage(32, 32);
  972. // Try to save thumbnail
  973. WCHAR *thumbfile = L"thumb256.bmp";
  974. CLSID _BmpCodecClsID_ =
  975. {
  976. 0x557cf400,
  977. 0x1a04,
  978. 0x11d3,
  979. {0x9a, 0x73, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e}
  980. };
  981. if (imageThumb->Save(thumbfile, &_BmpCodecClsID_, NULL) == Ok)
  982. LBprintf("thumbnail save OK");
  983. else
  984. LBprintf("thumbnail save failed");
  985. RectF srcRect;
  986. srcRect.X = 20;
  987. srcRect.Y = 20;
  988. srcRect.Width = 180;
  989. srcRect.Height = 180;
  990. PointF points[4];
  991. PointF destPoints[3];
  992. destPoints[0].X = 300;
  993. destPoints[0].Y = 50;
  994. destPoints[1].X = 450;
  995. destPoints[1].Y = 50;
  996. destPoints[2].X = 240;
  997. destPoints[2].Y = 200;
  998. //g->DrawImage(image, &destPoints[0], 3);
  999. RectF thumbRect(220, 50, (REAL) imageThumb->GetWidth(), (REAL) imageThumb->GetHeight());
  1000. //g->DrawImage(imageThumb, thumbRect);
  1001. UINT abortCount = 0;
  1002. ImageAttributes imgAttrib;
  1003. Rect destRect(50, 10, 100, 100);
  1004. // Make near-white to white transparent
  1005. Color c1(200, 200, 200);
  1006. Color c2(255, 255, 255);
  1007. imgAttrib.SetColorKey(c1, c2);
  1008. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1009. MyDrawImageAbort, (VOID*)&abortCount);
  1010. ColorMatrix darkMatrix = {.75, 0, 0, 0, 0,
  1011. 0, .75, 0, 0, 0,
  1012. 0, 0, .75, 0, 0,
  1013. 0, 0, 0, 1, 0,
  1014. 0, 0, 0, 0, 1};
  1015. ColorMatrix greyMatrix = {.25, .25, .25, 0, 0,
  1016. .25, .25, .25, 0, 0,
  1017. .25, .25, .25, 0, 0,
  1018. 0, 0, 0, 1, 0,
  1019. (REAL).1, (REAL).1, (REAL).1, 0, 1};
  1020. ColorMatrix pinkMatrix = {(REAL).33, .25, .25, 0, 0,
  1021. (REAL).33, .25, .25, 0, 0,
  1022. (REAL).33, .25, .25, 0, 0,
  1023. 0, 0, 0, 1, 0,
  1024. 0, 0, 0, 0, 1};
  1025. // red->blue, green->red, blue->green, alpha = 0.75
  1026. ColorMatrix swapMatrix = {0, 0, 1, 0, 0,
  1027. 1, 0, 0, 0, 0,
  1028. 0, 1, 0, 0, 0,
  1029. 0, 0, 0, .75, 0,
  1030. 0, 0, 0, 0, 1};
  1031. // red->blue, green->red, blue->green, alpha = 0.9
  1032. ColorMatrix swapMatrix2 = {0, 0, 1, 0, 0,
  1033. 1, 0, 0, 0, 0,
  1034. 0, 1, 0, 0, 0,
  1035. 0, 0, 0, 0, 0,
  1036. 0, 0, 0, (REAL).9, 1};
  1037. imgAttrib.ClearColorKey();
  1038. imgAttrib.SetColorMatrix(&greyMatrix);
  1039. destRect.Y += destRect.Height;
  1040. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1041. MyDrawImageAbort, (VOID*)&abortCount);
  1042. imgAttrib.SetColorMatrix(&pinkMatrix, ColorMatrixFlagsSkipGrays);
  1043. destRect.Y += destRect.Height;
  1044. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1045. MyDrawImageAbort, (VOID*)&abortCount);
  1046. imgAttrib.SetColorMatrix(&darkMatrix);
  1047. destRect.X += destRect.Width;
  1048. destRect.Y = 10;
  1049. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1050. MyDrawImageAbort, (VOID*)&abortCount);
  1051. destRect.Y += destRect.Height;
  1052. imgAttrib.ClearColorMatrix();
  1053. imgAttrib.SetGamma(3.0);
  1054. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1055. MyDrawImageAbort, (VOID*)&abortCount);
  1056. destRect.Y += destRect.Height;
  1057. imgAttrib.SetThreshold(0.5);
  1058. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1059. MyDrawImageAbort, (VOID*)&abortCount);
  1060. imgAttrib.SetColorMatrix(&swapMatrix);
  1061. imgAttrib.ClearGamma();
  1062. imgAttrib.ClearThreshold();
  1063. destRect.X += destRect.Width;
  1064. destRect.Y = 10;
  1065. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1066. MyDrawImageAbort, (VOID*)&abortCount);
  1067. destRect.Y += destRect.Height;
  1068. imgAttrib.SetNoOp();
  1069. imgAttrib.SetColorMatrix(&swapMatrix2);
  1070. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1071. MyDrawImageAbort, (VOID*)&abortCount);
  1072. destRect.Y += destRect.Height;
  1073. imgAttrib.ClearNoOp();
  1074. g->DrawImage(image, destRect, 0, 0, 180, 180, UnitPixel, &imgAttrib,
  1075. MyDrawImageAbort, (VOID*)&abortCount);
  1076. delete image;
  1077. delete imageThumb;
  1078. }
  1079. VOID TestBitmapGraphics(Graphics* g)
  1080. {
  1081. INT bitmapSize = 500;
  1082. Bitmap* bitmap = new Bitmap(bitmapSize, bitmapSize, g);
  1083. if (!bitmap)
  1084. LBprintf("Bitmap creation failed");
  1085. else
  1086. {
  1087. LBprintf("ImageInfo: %ld x %ld", bitmap->GetWidth(), bitmap->GetHeight());
  1088. }
  1089. Graphics *bitmapGraphics = Graphics::FromImage(bitmap);
  1090. if (!bitmapGraphics)
  1091. LBprintf("Bitmap.GetGraphics() failed");
  1092. TestContainerClip(bitmapGraphics);
  1093. TestContainer(bitmapGraphics);
  1094. TestPolygons(bitmapGraphics);
  1095. TestPaths(bitmapGraphics);
  1096. TestRegions(bitmapGraphics);
  1097. TestGradients(bitmapGraphics);
  1098. TestHatches(bitmapGraphics);
  1099. TestBitmaps(bitmapGraphics);
  1100. TestPrimitives(bitmapGraphics);
  1101. TestMixedObjects(bitmapGraphics);
  1102. TestTexts(bitmapGraphics);
  1103. TestImaging(bitmapGraphics);
  1104. delete bitmapGraphics;
  1105. Rect destRect(100, 100, bitmapSize, bitmapSize);
  1106. g->DrawImage(bitmap, destRect, 0, 0, bitmapSize, bitmapSize, UnitPixel);
  1107. delete bitmap;
  1108. }
  1109. /**************************************************************************\
  1110. * TestCompoundLines
  1111. *
  1112. * A test for compound lines.
  1113. *
  1114. \**************************************************************************/
  1115. VOID TestCompoundLines(Graphics *g)
  1116. {
  1117. REAL width = 4; // Pen width
  1118. PointF points[4];
  1119. points[0].X = 100;
  1120. points[0].Y = 10;
  1121. points[1].X = -50;
  1122. points[1].Y = 50;
  1123. points[2].X = 150;
  1124. points[2].Y = 200;
  1125. points[3].X = 200;
  1126. points[3].Y = 70;
  1127. Color yellowColor(128, 255, 255, 0);
  1128. SolidBrush yellowBrush(yellowColor);
  1129. GraphicsPath* path = new GraphicsPath(FillModeAlternate);
  1130. path->AddBeziers(points, 4);
  1131. points[0].X = 260;
  1132. points[0].Y = 20;
  1133. path->AddLines(points, 1);
  1134. Matrix matrix;
  1135. matrix.Scale(1.5, 1.5);
  1136. matrix.Translate(0, 30);
  1137. // If you wanto to flatten the path before rendering,
  1138. // Flatten() can be called.
  1139. BOOL flattenFirst = FALSE;
  1140. if(!flattenFirst)
  1141. {
  1142. // Don't flatten and keep the original path.
  1143. // FillPath or DrawPath will flatten the path automatically
  1144. // without modifying the original path.
  1145. path->Transform(&matrix);
  1146. }
  1147. else
  1148. {
  1149. // Flatten this path. The resultant path is made of line
  1150. // segments. The original path information is lost.
  1151. path->Flatten(&matrix);
  1152. }
  1153. Color blackColor(0, 0, 0);
  1154. SolidBrush blackBrush(blackColor);
  1155. // Set the pen width in inch.
  1156. width = (REAL) 0.2;
  1157. Pen blackPen(&blackBrush, width);
  1158. REAL* compoundArray = new REAL[6];
  1159. compoundArray[0] = 0.0f;
  1160. compoundArray[1] = 0.2f;
  1161. compoundArray[2] = 0.4f;
  1162. compoundArray[3] = 0.6f;
  1163. compoundArray[4] = 0.8f;
  1164. compoundArray[5] = 1.0f;
  1165. blackPen.SetCompoundArray(&compoundArray[0], 6);
  1166. blackPen.SetDashStyle(DashStyleDash);
  1167. blackPen.SetStartCap(LineCapDiamondAnchor);
  1168. blackPen.SetEndCap(LineCapArrowAnchor);
  1169. g->FillPath(&yellowBrush, path);
  1170. g->DrawPath(&blackPen, path);
  1171. delete [] compoundArray;
  1172. delete path;
  1173. }