GraphicsPath.jvm.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. using System;
  2. using System.Drawing;
  3. using System.Collections;
  4. using java.awt.geom;
  5. using java.awt;
  6. namespace System.Drawing.Drawing2D
  7. {
  8. public sealed class GraphicsPath : BasicShape, ICloneable
  9. {
  10. internal enum JPI {
  11. SEG_MOVETO = ExtendedGeneralPath.SEG_MOVETO,
  12. SEG_LINETO = ExtendedGeneralPath.SEG_LINETO,
  13. SEG_QUADTO = ExtendedGeneralPath.SEG_QUADTO,
  14. SEG_CUBICTO = ExtendedGeneralPath.SEG_CUBICTO,
  15. SEG_CLOSE = ExtendedGeneralPath.SEG_CLOSE
  16. }
  17. #region Internal
  18. internal ExtendedGeneralPath NativeObject
  19. {
  20. get
  21. {
  22. return (ExtendedGeneralPath)Shape;
  23. }
  24. }
  25. GraphicsPath (ExtendedGeneralPath ptr) : base(ptr)
  26. {
  27. }
  28. #endregion
  29. #region C-tors.
  30. public GraphicsPath ():
  31. this(FillMode.Alternate)
  32. {
  33. }
  34. public GraphicsPath (FillMode fillMode) : this(new ExtendedGeneralPath ())
  35. {
  36. FillMode = fillMode;
  37. }
  38. public GraphicsPath (Point[] pts, byte[] types) : this(pts, types, FillMode.Alternate)
  39. {
  40. }
  41. public GraphicsPath (PointF [] pts, byte [] types) : this(pts, types, FillMode.Alternate)
  42. {
  43. }
  44. public GraphicsPath (Point [] pts, byte [] types, FillMode fillMode) : this(new ExtendedGeneralPath ())
  45. {
  46. FillMode = fillMode;
  47. for (int i=0; i < pts.Length; i++) {
  48. switch ((PathPointType)types [i]) {
  49. case PathPointType.Start :
  50. NativeObject.moveTo (pts [i].X, pts [i].Y);
  51. break;
  52. case PathPointType.Bezier3 :
  53. float x1 = pts [i].X;
  54. float y1 = pts [i].Y;
  55. i++;
  56. float x2 = pts [i].X;
  57. float y2 = pts [i].Y;
  58. i++;
  59. float x3 = pts [i].X;
  60. float y3 = pts [i].Y;
  61. NativeObject.curveTo (x1,y1, x2, y2, x3, y3);
  62. break;
  63. }
  64. if (((PathPointType)types [i] & PathPointType.CloseSubpath) != 0)
  65. NativeObject.closePath();
  66. }
  67. }
  68. public GraphicsPath (PointF [] pts, byte [] types, FillMode fillMode) : this(new ExtendedGeneralPath ())
  69. {
  70. FillMode = fillMode;
  71. for (int i=0; i < pts.Length; i++) {
  72. switch ((PathPointType)types [i]) {
  73. case PathPointType.Start :
  74. NativeObject.moveTo (pts [i].X, pts [i].Y);
  75. break;
  76. case PathPointType.Bezier3 :
  77. float x1 = pts [i].X;
  78. float y1 = pts [i].Y;
  79. i++;
  80. float x2 = pts [i].X;
  81. float y2 = pts [i].Y;
  82. i++;
  83. float x3 = pts [i].X;
  84. float y3 = pts [i].Y;
  85. NativeObject.curveTo (x1,y1, x2, y2, x3, y3);
  86. break;
  87. }
  88. if (((PathPointType)types [i] & PathPointType.CloseSubpath) != 0)
  89. NativeObject.closePath();
  90. }
  91. }
  92. #endregion
  93. #region Clone
  94. public object Clone ()
  95. {
  96. return new GraphicsPath ((ExtendedGeneralPath) NativeObject.Clone ());
  97. }
  98. #endregion
  99. #region Properties
  100. public FillMode FillMode
  101. {
  102. get
  103. { if(NativeObject.getWindingRule() == GeneralPath.WIND_NON_ZERO)
  104. return FillMode.Alternate;
  105. else
  106. return FillMode.Winding;
  107. }
  108. set
  109. {
  110. if (value == FillMode.Alternate)
  111. NativeObject.setWindingRule (GeneralPath.WIND_NON_ZERO);
  112. else
  113. NativeObject.setWindingRule (GeneralPath.WIND_EVEN_ODD);
  114. }
  115. }
  116. public PathData PathData
  117. {
  118. get
  119. {
  120. PathIterator iter = NativeObject.getPathIterator(null);
  121. PathData pathData = new PathData();
  122. pathData.Types = new byte [PointCount];
  123. pathData.Points = new PointF [PointCount];
  124. int tpos = 0;
  125. int ppos = 0;
  126. float [] jpoints = new float [6];
  127. while (!iter.isDone ()) {
  128. //if (tpos == 0)
  129. // pathData.Types [tpos++] = PathPointType.Start;
  130. JPI segmentType = (JPI)iter.currentSegment (jpoints);
  131. switch (segmentType) {
  132. case JPI.SEG_CLOSE:
  133. pathData.Types [tpos - 1] = (byte) (pathData.Types [tpos - 1] | (byte) PathPointType.CloseSubpath);
  134. break;
  135. case JPI.SEG_MOVETO:
  136. pathData.Types [tpos++] = (byte) PathPointType.Start;
  137. pathData.Points [ppos++] = new PointF (jpoints [0], jpoints [1]);
  138. break;
  139. case JPI.SEG_LINETO:
  140. pathData.Types [tpos++] = (byte) PathPointType.Line;
  141. pathData.Points [ppos++] = new PointF (jpoints [0], jpoints [1]);
  142. break;
  143. case JPI.SEG_QUADTO:
  144. pathData.Types [tpos++] = (byte) PathPointType.Bezier;
  145. pathData.Points [ppos++] = new PointF (jpoints [0], jpoints [1]);
  146. pathData.Types [tpos++] = (byte) PathPointType.Bezier;
  147. pathData.Points [ppos++] = new PointF (jpoints [2], jpoints [3]);
  148. break;
  149. case JPI.SEG_CUBICTO:
  150. pathData.Types [tpos++] = (byte) PathPointType.Bezier3;
  151. pathData.Points [ppos++] = new PointF (jpoints [0], jpoints [1]);
  152. pathData.Types [tpos++] = (byte) PathPointType.Bezier3;
  153. pathData.Points [ppos++] = new PointF (jpoints [2], jpoints [3]);
  154. pathData.Types [tpos++] = (byte) PathPointType.Bezier3;
  155. pathData.Points [ppos++] = new PointF (jpoints [4], jpoints [5]);
  156. break;
  157. }
  158. iter.next ();
  159. }
  160. return pathData;
  161. }
  162. }
  163. public PointF [] PathPoints
  164. {
  165. get
  166. {
  167. return PathData.Points;
  168. }
  169. }
  170. public byte [] PathTypes
  171. {
  172. get
  173. {
  174. return PathData.Types;
  175. }
  176. }
  177. #endregion
  178. #region PointCount [TODO]
  179. public int PointCount
  180. {
  181. get
  182. {
  183. return NativeObject.CoordsCount / 2;
  184. }
  185. }
  186. #endregion
  187. #region AddArc
  188. public void AddArc (Rectangle rect, float startAngle, float sweepAngle)
  189. {
  190. AddArc(rect.X,rect.Y,rect.Width,rect.Height,startAngle,sweepAngle);
  191. }
  192. public void AddArc (RectangleF rect, float startAngle, float sweepAngle)
  193. {
  194. AddArc(rect.X,rect.Y,rect.Width,rect.Height,startAngle,sweepAngle);
  195. }
  196. public void AddArc (int x, int y, int width, int height, float startAngle, float sweepAngle)
  197. {
  198. AddArc((float)x,(float)y,(float)width,(float)height,startAngle,sweepAngle);
  199. }
  200. public void AddArc (float x, float y, float width, float height, float startAngle, float sweepAngle)
  201. {
  202. Shape shape = null;
  203. if (sweepAngle >= 360)
  204. shape = new Ellipse2D.Float(x, y, width, height);
  205. else {
  206. double d1Tod2 = width/height;
  207. double sqrd1Tod2 = d1Tod2*d1Tod2;
  208. double start = ConvertArcAngle(sqrd1Tod2, startAngle);
  209. double extent = ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
  210. shape = new Arc2D.Double(x,y,width,height,-start,-extent,Arc2D.OPEN);
  211. }
  212. NativeObject.append(shape);
  213. }
  214. /// <summary>
  215. /// .Net computes an angle by intersection of ellipse with a ray
  216. /// java does the following: x1 = d1*cos(a), y1 = d2*sin(a)
  217. /// where: d1 = width/2, d2 = height/2
  218. /// we need to find angle x, which satisfies:
  219. /// x1 = m*cos(a) = d1*cos(x)
  220. /// y1 = m*sin(a) = d2*sin(x)
  221. /// (x1*x1)/(d1*d1) + (x2*x2)/(d2*d2) = 1
  222. /// </summary>
  223. /// <param name="sqrd1Tod2">(d1/d2)*(d1/d2)</param>
  224. /// <param name="angle">angle in degrees</param>
  225. /// <returns>converted angle in degrees</returns>
  226. static double ConvertArcAngle(double sqrd1Tod2, double angle) {
  227. double angleRad = java.lang.Math.toRadians(angle);
  228. double tan = Math.Tan(angleRad);
  229. double cosx = 1/Math.Sqrt( sqrd1Tod2 * (tan*tan) + 1);
  230. double xRad = Math.Acos(cosx);
  231. double x = java.lang.Math.toDegrees(xRad);
  232. int q = ((int)angle)/90;
  233. switch (q&3) {
  234. default:
  235. return x;
  236. case 1:
  237. return 180-x;
  238. case 2:
  239. return 180+x;
  240. case 3:
  241. return 360-x;
  242. }
  243. }
  244. #endregion
  245. #region AddBezier(s)
  246. public void AddBezier (Point pt1, Point pt2, Point pt3, Point pt4)
  247. {
  248. AddBezier(pt1.X,pt1.Y,pt2.X,pt2.Y,pt3.X,pt3.Y,pt4.X,pt4.Y);
  249. }
  250. public void AddBezier (PointF pt1, PointF pt2, PointF pt3, PointF pt4)
  251. {
  252. AddBezier(pt1.X,pt1.Y,pt2.X,pt2.Y,pt3.X,pt3.Y,pt4.X,pt4.Y);
  253. }
  254. public void AddBezier (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4)
  255. {
  256. AddBezier((float)x1,(float)y1,(float)x2,(float)y2,(float)x3,(float)y3,(float)x4,(float)y4);
  257. }
  258. public void AddBezier (float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
  259. {
  260. CubicCurve2D cc = new CubicCurve2D.Float(x1,y1,x2,y2,x3,y3,x4,y4);
  261. NativeObject.append(cc);
  262. }
  263. public void AddBeziers (Point [] pts)
  264. {
  265. if (pts == null)
  266. throw new ArgumentNullException("points");
  267. AddBezier(pts [0].X,pts [0].Y,
  268. pts [1].X,pts [1].Y,
  269. pts [2].X,pts [2].Y,
  270. pts [3].X,pts [3].Y);
  271. for (int i = 4; i < pts.Length; i += 3) {
  272. NativeObject.curveTo(
  273. pts [i].X,pts [i].Y,
  274. pts [i+1].X,pts [i+1].Y,
  275. pts [i+2].X,pts [i+2].Y);
  276. }
  277. }
  278. public void AddBeziers (PointF [] pts)
  279. {
  280. if (pts == null)
  281. throw new ArgumentNullException("points");
  282. AddBezier(pts [0].X,pts [0].Y,
  283. pts [1].X,pts [1].Y,
  284. pts [2].X,pts [2].Y,
  285. pts [3].X,pts [3].Y);
  286. for (int i = 4; i < pts.Length; i += 3) {
  287. NativeObject.curveTo(
  288. pts [i].X,pts [i].Y,
  289. pts [i+1].X,pts [i+1].Y,
  290. pts [i+2].X,pts [i+2].Y);
  291. }
  292. }
  293. #endregion
  294. #region AdEllipse
  295. public void AddEllipse (float x, float y, float width, float height)
  296. {
  297. Ellipse2D e = new Ellipse2D.Float(x,y,width,height);
  298. NativeObject.append(e,false);
  299. }
  300. public void AddEllipse (RectangleF r)
  301. {
  302. AddEllipse(r.X,r.Y,r.Width,r.Height);
  303. }
  304. public void AddEllipse (Rectangle r)
  305. {
  306. AddEllipse(r.X,r.Y,r.Width,r.Height);
  307. }
  308. public void AddEllipse (int x, int y, int width, int height)
  309. {
  310. AddEllipse((float)x, (float)y, (float)width, (float)height);
  311. }
  312. #endregion
  313. #region AddLine
  314. public void AddLine (float x1, float y1, float x2, float y2)
  315. {
  316. Line2D l = new Line2D.Float(x1,y1,x2,y2);
  317. NativeObject.append(l);
  318. }
  319. public void AddLine (Point a, Point b)
  320. {
  321. AddLine(a.X,a.Y,b.X,b.Y);
  322. }
  323. public void AddLine (PointF a, PointF b)
  324. {
  325. AddLine(a.X,a.Y,b.X,b.Y);
  326. }
  327. public void AddLine (int x1, int y1, int x2, int y2)
  328. {
  329. AddLine((float)x1,(float)y1,(float)x2,(float)y2);
  330. }
  331. public void AddLines (Point [] points)
  332. {
  333. if (points == null)
  334. throw new ArgumentNullException("points");
  335. if (points.Length == 0)
  336. return;
  337. if (NativeObject.LastFigureClosed)
  338. NativeObject.moveTo(points[0].X, points[0].Y);
  339. else
  340. NativeObject.lineTo(points[0].X, points[0].Y);
  341. for (int i = 1; i < points.Length; i ++)
  342. NativeObject.lineTo(points[i].X, points[i].Y);
  343. }
  344. public void AddLines (PointF [] points)
  345. {
  346. if (points == null)
  347. throw new ArgumentNullException("points");
  348. if (points.Length == 0)
  349. return;
  350. if (NativeObject.LastFigureClosed)
  351. NativeObject.moveTo(points[0].X, points[0].Y);
  352. else
  353. NativeObject.lineTo(points[0].X, points[0].Y);
  354. for (int i = 1; i < points.Length; i ++)
  355. NativeObject.lineTo(points[i].X, points[i].Y);
  356. }
  357. #endregion
  358. #region AddPie
  359. public void AddPie (float x, float y, float width, float height, float startAngle, float sweepAngle)
  360. {
  361. Shape shape = null;
  362. if (sweepAngle >= 360)
  363. shape = new Ellipse2D.Float(x, y, width, height);
  364. else {
  365. double d1Tod2 = width/height;
  366. double sqrd1Tod2 = d1Tod2*d1Tod2;
  367. double start = ConvertArcAngle(sqrd1Tod2, startAngle);
  368. double extent = ConvertArcAngle(sqrd1Tod2, startAngle+sweepAngle) - start;
  369. shape = new Arc2D.Double(x,y,width,height,-start,-extent,Arc2D.PIE);
  370. }
  371. NativeObject.append(shape,false);
  372. }
  373. public void AddPie (Rectangle rect, float startAngle, float sweepAngle)
  374. {
  375. AddPie((float)rect.X, (float)rect.Y,(float)rect.Width,(float)rect.Height,startAngle,sweepAngle);
  376. }
  377. public void AddPie (int x, int y, int width, int height, float startAngle, float sweepAngle)
  378. {
  379. AddPie((float)x,(float)y,(float)width,(float)height,startAngle,sweepAngle);
  380. }
  381. #endregion
  382. #region AddPolygon
  383. public void AddPolygon (Point [] points)
  384. {
  385. if (points == null)
  386. throw new ArgumentNullException("points");
  387. if (points.Length < 3)
  388. throw new ArgumentException("Invalid parameter used.");
  389. NativeObject.moveTo((float)points[0].X,(float)points[0].Y);
  390. for (int i = 1; i< points.Length; i++)
  391. {
  392. NativeObject.lineTo((float)points[i].X,(float)points[i].Y);
  393. }
  394. NativeObject.closePath();
  395. }
  396. public void AddPolygon (PointF [] points)
  397. {
  398. if (points == null)
  399. throw new ArgumentNullException("points");
  400. if (points.Length < 3)
  401. throw new ArgumentException("Invalid parameter used.");
  402. NativeObject.moveTo(points[0].X,points[0].Y);
  403. for (int i = 1; i < points.Length; i++)
  404. {
  405. NativeObject.lineTo(points[i].X,points[i].Y);
  406. }
  407. NativeObject.closePath();
  408. }
  409. #endregion
  410. #region AddRectangle(s)
  411. internal void AddRectangle(float x,float y, float w, float h)
  412. {
  413. if (NativeObject.LastFigureClosed)
  414. NativeObject.moveTo(x, y);
  415. NativeObject.lineTo (x + w, y);
  416. NativeObject.lineTo (x + w, y + h);
  417. NativeObject.lineTo (x, y + h);
  418. NativeObject.closePath ();
  419. }
  420. public void AddRectangle (RectangleF rect)
  421. {
  422. AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
  423. }
  424. public void AddRectangle (Rectangle rect)
  425. {
  426. AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
  427. }
  428. public void AddRectangles (Rectangle [] rects)
  429. {
  430. foreach(Rectangle rect in rects)
  431. AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
  432. }
  433. public void AddRectangles (RectangleF [] rects)
  434. {
  435. foreach(RectangleF rect in rects)
  436. AddRectangle(rect.X,rect.Y,rect.Width,rect.Height);
  437. }
  438. #endregion
  439. #region AddPath
  440. public void AddPath (GraphicsPath addingPath, bool connect)
  441. {
  442. NativeObject.append(addingPath.NativeObject,connect);
  443. }
  444. #endregion
  445. #region GetLastPoint
  446. public PointF GetLastPoint ()
  447. {
  448. int length = NativeObject.CoordsCount;
  449. if (length == 0)
  450. throw new System.ArgumentException ("Invalid parameter used.");
  451. return new PointF (NativeObject.Coords [length - 2], NativeObject.Coords [length - 1]);
  452. }
  453. #endregion
  454. #region Reset
  455. public void Reset ()
  456. {
  457. NativeObject.reset();
  458. }
  459. #endregion
  460. #region GetBounds
  461. public RectangleF GetBounds ()
  462. {
  463. Rectangle2D rect = NativeObject.getBounds2D();
  464. return new RectangleF((float)rect.getX(),(float)rect.getY(),(float)rect.getWidth(),(float)rect.getHeight());
  465. }
  466. public RectangleF GetBounds (Matrix matrix)
  467. {
  468. Shape shape = matrix != null ?
  469. NativeObject.createTransformedShape(matrix.NativeObject) : NativeObject;
  470. Rectangle2D rect = shape.getBounds2D();
  471. return new RectangleF((float)rect.getX(),(float)rect.getY(),(float)rect.getWidth(),(float)rect.getHeight());
  472. }
  473. public RectangleF GetBounds (Matrix matrix, Pen pen)
  474. {
  475. throw new NotImplementedException();
  476. }
  477. #endregion
  478. #region Transform
  479. public void Transform (Matrix matrix)
  480. {
  481. if(matrix == null)
  482. return;
  483. NativeObject.transform(matrix.NativeObject);
  484. }
  485. #endregion
  486. #region IsVisible
  487. public bool IsVisible (Point point)
  488. {
  489. return IsVisible (point.X, point.Y, null);
  490. }
  491. public bool IsVisible (PointF point)
  492. {
  493. return IsVisible (point.X, point.Y, null);
  494. }
  495. public bool IsVisible (int x, int y)
  496. {
  497. return IsVisible (x, y, null);
  498. }
  499. public bool IsVisible (float x, float y)
  500. {
  501. return IsVisible (x, y, null);
  502. }
  503. public bool IsVisible (Point pt, Graphics graphics)
  504. {
  505. return IsVisible (pt.X, pt.Y, graphics);
  506. }
  507. public bool IsVisible (PointF pt, Graphics graphics)
  508. {
  509. return IsVisible (pt.X, pt.Y, graphics);
  510. }
  511. public bool IsVisible (int x, int y, Graphics graphics)
  512. {
  513. return IsVisible((float)x,(float)y,null);
  514. }
  515. public bool IsVisible (float x, float y, Graphics graphics)
  516. {
  517. if (graphics != null && !graphics.IsVisible(x,y))
  518. return false;
  519. return NativeObject.contains(x,y);
  520. }
  521. #endregion
  522. #region Reverse [TODO]
  523. public void Reverse ()
  524. {
  525. throw new NotImplementedException();
  526. }
  527. #endregion
  528. #region AddClosedCurve
  529. public void AddClosedCurve (Point [] points)
  530. {
  531. AddClosedCurve(points, 0.5f);
  532. }
  533. public void AddClosedCurve (PointF [] points)
  534. {
  535. AddClosedCurve(points, 0.5f);
  536. }
  537. public void AddClosedCurve (Point [] points, float tension)
  538. {
  539. if (points == null)
  540. throw new ArgumentNullException("points");
  541. if (points.Length < 3)
  542. throw new ArgumentException("Invalid parameter used.");
  543. int length = (points.Length + 3)*2;
  544. float[] pts = new float[length];
  545. pts[--length] = points[1].Y;
  546. pts[--length] = points[1].X;
  547. pts[--length] = points[0].Y;
  548. pts[--length] = points[0].X;
  549. for (int i = points.Length-1; i >= 0; i--) {
  550. pts[--length] = points[i].Y;
  551. pts[--length] = points[i].X;
  552. }
  553. pts[--length] = points[points.Length-1].Y;
  554. pts[--length] = points[points.Length-1].X;
  555. AddCurve(pts, !NativeObject.LastFigureClosed, tension);
  556. }
  557. public void AddClosedCurve (PointF [] points, float tension)
  558. {
  559. if (points == null)
  560. throw new ArgumentNullException("points");
  561. if (points.Length < 3)
  562. throw new ArgumentException("Invalid parameter used.");
  563. int length = (points.Length + 3)*2;
  564. float[] pts = new float[length];
  565. pts[--length] = points[1].Y;
  566. pts[--length] = points[1].X;
  567. pts[--length] = points[0].Y;
  568. pts[--length] = points[0].X;
  569. for (int i = points.Length-1; i >= 0; i--) {
  570. pts[--length] = points[i].Y;
  571. pts[--length] = points[i].X;
  572. }
  573. pts[--length] = points[points.Length-1].Y;
  574. pts[--length] = points[points.Length-1].X;
  575. AddCurve(pts, !NativeObject.LastFigureClosed, tension);
  576. }
  577. #endregion
  578. #region AddCurve
  579. //we have now two approaches for drawing cardinal curves
  580. //the first one is to convert cardinals into approximate beziers
  581. //the second one - to draw curve ourself with all interpolation staff
  582. //here. I preffer the first one because we could utilize java antialiasing and
  583. //flattening features, otherwise curves will be more strict but less cool
  584. public void AddCurve (Point [] points)
  585. {
  586. AddCurve(points,0.5F);
  587. }
  588. public void AddCurve (PointF [] points)
  589. {
  590. AddCurve(points,0.5f);
  591. }
  592. public void AddCurve (Point [] points, float tension)
  593. {
  594. AddCurve(points, 0, points.Length-1, tension);
  595. }
  596. public void AddCurve (PointF [] points, float tension)
  597. {
  598. AddCurve(points, 0, points.Length-1, tension);
  599. }
  600. public void AddCurve (Point [] points, int offset, int numberOfSegments, float tension)
  601. {
  602. int nPoints = numberOfSegments + 1;
  603. int length = nPoints*2 + 4;
  604. float[] pts = new float[length];
  605. int lastP = offset + nPoints;
  606. if (lastP == points.Length) {
  607. lastP--;
  608. pts[--length] = points[lastP].Y;
  609. pts[--length] = points[lastP].X;
  610. }
  611. for (; length > 0 && lastP >= 0; lastP--) {
  612. pts[--length] = points[lastP].Y;
  613. pts[--length] = points[lastP].X;
  614. }
  615. if (length > 0) {
  616. pts[1] = points[0].Y;
  617. pts[0] = points[0].X;
  618. }
  619. AddCurve(pts, !NativeObject.LastFigureClosed, tension);
  620. }
  621. public void AddCurve (PointF [] points, int offset, int numberOfSegments, float tension)
  622. {
  623. int nPoints = numberOfSegments + 1;
  624. int length = nPoints*2 + 4;
  625. float[] pts = new float[length];
  626. int lastP = offset + nPoints;
  627. if (lastP == points.Length) {
  628. lastP--;
  629. pts[--length] = points[lastP].Y;
  630. pts[--length] = points[lastP].X;
  631. }
  632. for (; length > 0 && lastP >= 0; lastP--) {
  633. pts[--length] = points[lastP].Y;
  634. pts[--length] = points[lastP].X;
  635. }
  636. if (length > 0) {
  637. pts[1] = points[0].Y;
  638. pts[0] = points[0].X;
  639. }
  640. AddCurve(pts, !NativeObject.LastFigureClosed, tension);
  641. }
  642. /// <summary>
  643. /// Based on http://pubpages.unh.edu/~cs770/a5/cardinal.html
  644. /// </summary>
  645. /// <param name="pts">point array (x1,y1,x2,y2 ...).
  646. /// The first and last points considered only for calculations, but are not added.</param>
  647. void AddCurve(float[] pts, bool connect, float tension) {
  648. tension /= 3f; //looks like a good pick
  649. if (connect)
  650. NativeObject.lineTo(pts[2],pts[3]);
  651. else
  652. NativeObject.moveTo(pts[2],pts[3]);
  653. float dx = pts[4] - pts[0];
  654. float dy = pts[5] - pts[1];
  655. float sx = pts[2] + tension*dx;
  656. float sy = pts[3] + tension*dy;
  657. for (int offset = 2, total = pts.Length-4; offset < total; offset += 2) {
  658. int cur_offset = offset;
  659. int pX = cur_offset++;
  660. int pY = cur_offset++;
  661. int X = cur_offset++;
  662. int Y = cur_offset++;
  663. int nX = cur_offset++;
  664. int nY = cur_offset++;
  665. dx = pts[nX] - pts[pX];
  666. dy = pts[nY] - pts[pY];
  667. float rx = pts[X] - tension*dx;
  668. float ry = pts[Y] - tension*dy;
  669. NativeObject.curveTo(sx, sy, rx, ry, pts[X], pts[Y]);
  670. sx = pts[X] + tension*dx;
  671. sy = pts[Y] + tension*dy;
  672. }
  673. }
  674. #endregion
  675. #region AddString [TODO]
  676. public void AddString (string s, FontFamily family, int style, float emSize, Point origin, StringFormat format)
  677. {
  678. throw new NotImplementedException ();
  679. }
  680. public void AddString (string s, FontFamily family, int style, float emSize, PointF origin, StringFormat format)
  681. {
  682. throw new NotImplementedException ();
  683. }
  684. public void AddString (string s, FontFamily family, int style, float emSize, Rectangle layoutRect, StringFormat format)
  685. {
  686. throw new NotImplementedException ();
  687. }
  688. public void AddString (string s, FontFamily family, int style, float emSize, RectangleF layoutRect, StringFormat format)
  689. {
  690. throw new NotImplementedException ();
  691. }
  692. #endregion
  693. #region ClearMarkers [TODO]
  694. public void ClearMarkers()
  695. {
  696. throw new NotImplementedException ();
  697. }
  698. #endregion
  699. #region Close(All) [REVIEW-EXTEND]
  700. public void CloseAllFigures()
  701. {
  702. ExtendedGeneralPath p = new ExtendedGeneralPath();
  703. PathIterator pi = NativeObject.getPathIterator(null);
  704. JPI lastSeg = JPI.SEG_CLOSE;
  705. float [] points = new float[6];
  706. p.setWindingRule(pi.getWindingRule());
  707. while(!pi.isDone())
  708. {
  709. JPI curSeg = (JPI)pi.currentSegment(points);
  710. switch(curSeg)
  711. {
  712. case JPI.SEG_CLOSE:
  713. p.closePath();
  714. break;
  715. case JPI.SEG_MOVETO:
  716. if(lastSeg != JPI.SEG_CLOSE)
  717. p.closePath();
  718. p.moveTo(points[0],points[1]);
  719. break;
  720. case JPI.SEG_LINETO:
  721. p.lineTo(points[0],points[1]);
  722. break;
  723. case JPI.SEG_QUADTO:
  724. p.quadTo(points[0],points[1],points[2],points[3]);
  725. break;
  726. case JPI.SEG_CUBICTO:
  727. p.curveTo(points[0],points[1],points[2],points[3],points[4],points[5]);
  728. break;
  729. default:
  730. break;
  731. }
  732. lastSeg = curSeg;
  733. pi.next();
  734. }
  735. p.closePath();
  736. Shape = p;
  737. //_isNewFigure = (lastSeg == PathIterator.SEG_CLOSE);
  738. }
  739. public void CloseFigure()
  740. {
  741. NativeObject.closePath();
  742. }
  743. #endregion
  744. #region Flatten [REVIEW]
  745. public void Flatten ()
  746. {
  747. // 1/4 is the FlatnessDefault as defined in GdiPlusEnums.h
  748. Flatten (null, 1.0f / 4.0f);
  749. }
  750. public void Flatten (Matrix matrix)
  751. {
  752. Flatten (matrix, 1.0f / 4.0f);
  753. }
  754. public void Flatten (Matrix matrix, float flatness)
  755. {
  756. AffineTransform tr = null;
  757. if(matrix != null)
  758. tr = matrix.NativeObject;
  759. //REVIEW. Perfomance reasons.
  760. PathIterator pi = NativeObject.getPathIterator(tr,flatness);
  761. ExtendedGeneralPath newPath = new ExtendedGeneralPath();
  762. newPath.append(pi,false);
  763. Shape = newPath;
  764. }
  765. #endregion
  766. #region GetOutlineVisible [TODO]
  767. public bool IsOutlineVisible (Point point, Pen pen)
  768. {
  769. throw new NotImplementedException();
  770. }
  771. public bool IsOutlineVisible (PointF point, Pen pen)
  772. {
  773. throw new NotImplementedException();
  774. }
  775. public bool IsOutlineVisible (int x, int y, Pen pen)
  776. {
  777. throw new NotImplementedException();
  778. }
  779. public bool IsOutlineVisible (float x, float y, Pen pen)
  780. {
  781. throw new NotImplementedException();
  782. }
  783. public bool IsOutlineVisible (Point pt, Pen pen, Graphics graphics)
  784. {
  785. throw new NotImplementedException();
  786. }
  787. public bool IsOutlineVisible (PointF pt, Pen pen, Graphics graphics)
  788. {
  789. throw new NotImplementedException();
  790. }
  791. public bool IsOutlineVisible (int x, int y, Pen pen, Graphics graphics)
  792. {
  793. throw new NotImplementedException();
  794. }
  795. public bool IsOutlineVisible (float x, float y, Pen pen, Graphics graphics)
  796. {
  797. throw new NotImplementedException();
  798. }
  799. #endregion
  800. #region SetMarkers [TODO]
  801. public void SetMarkers ()
  802. {
  803. throw new NotImplementedException();
  804. }
  805. #endregion
  806. #region StartFigure
  807. public void StartFigure()
  808. {
  809. NativeObject.Types [NativeObject.TypesCount - 1] |= ExtendedGeneralPath.SEG_START;
  810. }
  811. #endregion
  812. #region Warp [TODO]
  813. public void Warp (PointF[] destPoints, RectangleF srcRect)
  814. {
  815. Warp (destPoints, srcRect, null, WarpMode.Perspective, 1.0f / 4.0f);
  816. }
  817. public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix)
  818. {
  819. Warp (destPoints, srcRect, matrix, WarpMode.Perspective, 1.0f / 4.0f);
  820. }
  821. public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode)
  822. {
  823. Warp (destPoints, srcRect, matrix, warpMode, 1.0f / 4.0f);
  824. }
  825. public void Warp (PointF[] destPoints, RectangleF srcRect, Matrix matrix, WarpMode warpMode, float flatness)
  826. {
  827. throw new NotImplementedException();
  828. }
  829. #endregion
  830. #region Widen
  831. public void Widen (Pen pen)
  832. {
  833. Widen (pen, null);
  834. }
  835. public void Widen (Pen pen, Matrix matrix)
  836. {
  837. Widen (pen, matrix, 2f/3f);
  838. }
  839. public void Widen (Pen pen, Matrix matrix, float flatness)
  840. {
  841. if (pen == null)
  842. throw new ArgumentNullException("pen");
  843. Shape = new ExtendedGeneralPath(((Stroke)pen).createStrokedShape(this));
  844. Flatten(matrix, flatness);
  845. }
  846. #endregion
  847. }
  848. }