123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719 |
- using System;
- using UnityEngine;
- using UnityEngine.Profiling;
- // TODO: Find a way to break this the hell up.
- // TODO: Normalize conventions away from Java-style SetX to properties.
- public class SVGGraphicsStroke : ISVGPathDraw {
- private SVGGraphics _graphics;
- private SVGBasicDraw _basicDraw;
- private float _width;
- private bool isUseWidth = false;
- public SVGGraphicsStroke(SVGGraphics graphics) {
- _graphics = graphics;
- _basicDraw = new SVGBasicDraw();
- _basicDraw.SetPixelMethod = new SetPixelDelegate(SetPixel);
- }
- private void SetPixel(int x, int y) {
- _graphics.SetPixel(x, y);
- }
- //Ve Line Cap, dau cuoi Left
- private static Vector2[] rect_points = new Vector2[4];
- private void StrokeLineCapLeft(Vector2 p1, Vector2 p2, float width) {
- if((int)width == 1)
- return;
- if((_graphics.StrokeLineCap == SVGStrokeLineCapMethod.Unknown) ||
- (_graphics.StrokeLineCap == SVGStrokeLineCapMethod.Butt))
- return;
- if(((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)) <= 4f)
- return;
- if(_graphics.StrokeLineCap == SVGStrokeLineCapMethod.Round) {
- _graphics.FillCircle(p1, width / 2f);
- return;
- }
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 t_p1 = Vector2.zero;
- Vector2 t_p2 = Vector2.zero;
- Vector2 t_p3 = Vector2.zero;
- Vector2 t_p4 = Vector2.zero;
- _graphics.GetThickLine(_p2, _p1, width, ref t_p1, ref t_p2, ref t_p3, ref t_p4);
- rect_points[0] = t_p1;
- rect_points[1] = _p2;
- rect_points[2] = _p1;
- rect_points[3] = t_p3;
- _graphics.FillPolygon(rect_points);
- }
- //Ve Line Cap, dau cuoi Right
- private void StrokeLineCapRight(Vector2 p1, Vector2 p2, float width) {
- if((int)width == 1)
- return;
- if((_graphics.StrokeLineCap == SVGStrokeLineCapMethod.Unknown) ||
- (_graphics.StrokeLineCap == SVGStrokeLineCapMethod.Butt))
- return;
- if(((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)) <= 4f)
- return;
- if(_graphics.StrokeLineCap == SVGStrokeLineCapMethod.Round) {
- _graphics.FillCircle(p2, width / 2f);
- return;
- }
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 t_p1 = Vector2.zero;
- Vector2 t_p2 = Vector2.zero;
- Vector2 t_p3 = Vector2.zero;
- Vector2 t_p4 = Vector2.zero;
- _graphics.GetThickLine(_p4, _p3, width, ref t_p1, ref t_p2, ref t_p3, ref t_p4);
- rect_points[0] = _p4;
- rect_points[1] = t_p2;
- rect_points[2] = t_p4;
- rect_points[3] = _p3;
- _graphics.FillPolygon(rect_points);
- }
- private static Vector2[] joint_points = new Vector2[8],
- joint_points_small = new Vector2[6];
- private void StrokeLineJoin(Vector2 p1, Vector2 p2, Vector2 p3, float width) {
- if((int)width == 1)
- return;
- if(((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)) <= 4f)
- return;
- if(_graphics.StrokeLineJoin == SVGStrokeLineJoinMethod.Round) {
- _graphics.FillCircle(p2, width / 2f);
- return;
- }
- if((_graphics.StrokeLineJoin == SVGStrokeLineJoinMethod.Miter) ||
- (_graphics.StrokeLineJoin == SVGStrokeLineJoinMethod.Unknown)) {
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 _p5 = Vector2.zero;
- Vector2 _p6 = Vector2.zero;
- Vector2 _p7 = Vector2.zero;
- Vector2 _p8 = Vector2.zero;
- _graphics.GetThickLine(p2, p3, width, ref _p5, ref _p6, ref _p7, ref _p8);
- Vector2 _cp1, _cp2;
- _cp1 = _graphics.GetCrossPoint(_p1, _p3, _p5, _p7);
- _cp2 = _graphics.GetCrossPoint(_p2, _p4, _p6, _p8);
- //Vector2[] points = new Vector2[8];
- joint_points[0] = p2;
- joint_points[1] = _p3;
- joint_points[2] = _cp1;
- joint_points[3] = _p5;
- joint_points[4] = p2;
- joint_points[5] = _p6;
- joint_points[6] = _cp2;
- joint_points[7] = _p4;
- _graphics.FillPolygon(joint_points);
- return;
- }
- if(_graphics.StrokeLineJoin == SVGStrokeLineJoinMethod.Bevel) {
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 _p5 = Vector2.zero;
- Vector2 _p6 = Vector2.zero;
- Vector2 _p7 = Vector2.zero;
- Vector2 _p8 = Vector2.zero;
- _graphics.GetThickLine(p2, p3, width, ref _p5, ref _p6, ref _p7, ref _p8);
- joint_points_small[0] = p2;
- joint_points_small[1] = _p3;
- joint_points_small[2] = _p5;
- joint_points_small[3] = p2;
- joint_points_small[4] = _p6;
- joint_points_small[5] = _p4;
- _graphics.FillPolygon(joint_points_small);
- return;
- }
- }
- public void MoveTo(Vector2 p) {
- _basicDraw.MoveTo(p);
- }
- public void CircleTo(Vector2 p, float r) {
- if((isUseWidth) && ((int)_width > 1)) {
- CircleTo(p, r, _width);
- return;
- }
- Circle(p, r);
- }
- // TODO: Kill this method.
- public void CircleTo(Vector2 p, float r, float width) {
- Circle(p, r, width);
- }
- public void EllipseTo(Vector2 p, float r1, float r2, float angle) {
- if((isUseWidth) && ((int)_width > 1)) {
- EllipseTo(p, r1, r2, angle, _width);
- return;
- }
- Ellipse(p, r1, r2, angle);
- }
- public void EllipseTo(Vector2 p, float r1, float r2, float angle, float width) {
- Ellipse(p, r1, r2, angle, width);
- }
- public void ArcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, Vector2 p) {
- if((isUseWidth) && ((int)_width > 1))
- ArcTo(r1, r2, angle, largeArcFlag, sweepFlag, p, _width);
- else
- _basicDraw.ArcTo(r1, r2, angle, largeArcFlag, sweepFlag, p);
- }
- public void ArcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, Vector2 p, float width) {
- Profiler.BeginSample("SVGGraphicsStroke.ArcTo");
- float rx = r1, ry = r2;
- Vector2 p1 = _basicDraw.currentPoint, p2 = p;
- float _radian = (angle * Mathf.PI / 180.0f);
- // TODO: Do we have single-precision methods we can use here? How's the performance?
- float _CosRadian = (float)Math.Cos(_radian);
- float _SinRadian = (float)Math.Sin(_radian);
- float temp1 = (p1.x - p2.x) / 2.0f;
- float temp2 = (p1.y - p2.y) / 2.0f;
- float tx = (_CosRadian * temp1) + (_SinRadian * temp2);
- float ty = (-_SinRadian * temp1) + (_CosRadian * temp2);
- double trx2 = rx * rx;
- double try2 = ry * ry;
- double tx2 = tx * tx;
- double ty2 = ty * ty;
- double radiiCheck = tx2 / trx2 + ty2 / try2;
- if(radiiCheck > 1) {
- rx = (float)Math.Sqrt((float)radiiCheck) * rx;
- ry = (float)Math.Sqrt((float)radiiCheck) * ry;
- trx2 = rx * rx;
- try2 = ry * ry;
- }
- double tm1 = (trx2 * try2 - trx2 * ty2 - try2 * tx2) / (trx2 * ty2 + try2 * tx2);
- tm1 = (tm1 < 0) ? 0 : tm1;
- float tm2 = (largeArcFlag == sweepFlag) ? -(float)Math.Sqrt((float)tm1) : (float)Math.Sqrt((float)tm1);
- float tcx = tm2 * ((rx * ty) / ry);
- float tcy = tm2 * (-(ry * tx) / rx);
- float cx = _CosRadian * tcx - _SinRadian * tcy + ((p1.x + p2.x) / 2.0f);
- float cy = _SinRadian * tcx + _CosRadian * tcy + ((p1.y + p2.y) / 2.0f);
- float ux = (tx - tcx) / rx;
- float uy = (ty - tcy) / ry;
- float vx = (-tx - tcx) / rx;
- float vy = (-ty - tcy) / ry;
- float tp, n;
- n = (float)Math.Sqrt((ux * ux) + (uy * uy));
- tp = ux;
- float _angle = (uy < 0) ? -(float)Math.Acos(tp / n) : (float)Math.Acos(tp / n);
- _angle = _angle * 180.0f / Mathf.PI;
- _angle %= 360f;
- n = (float)Math.Sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
- tp = ux * vx + uy * vy;
- float _delta = (ux * vy - uy * vx < 0) ? -(float)Math.Acos(tp / n) : (float)Math.Acos(tp / n);
- _delta = _delta * 180.0f / Mathf.PI;
- if(!sweepFlag && _delta > 0)
- _delta -= 360f;
- else if(sweepFlag && _delta < 0)
- _delta += 360f;
- _delta %= 360f;
- int number = 50;
- float deltaT = _delta / number;
- //---Get Control Point
- Vector2 _controlPoint1 = Vector2.zero;
- Vector2 _controlPoint2 = Vector2.zero;
- for(int i = 0; i <= number; i++) {
- float t_angle = (deltaT * i + _angle) * Mathf.PI / 180.0f;
- _controlPoint1.x = _CosRadian * rx * (float)Math.Cos(t_angle) - _SinRadian * ry * (float)Math.Sin(t_angle) + cx;
- _controlPoint1.y = _SinRadian * rx * (float)Math.Cos(t_angle) + _CosRadian * ry * (float)Math.Sin(t_angle) + cy;
- if((_controlPoint1.x != p1.x) && (_controlPoint1.y != p1.y))
- i = number + 1;
- }
- for(int i = number; i >= 0; i--) {
- float t_angle = (deltaT * i + _angle) * Mathf.PI / 180.0f;
- _controlPoint2.x = _CosRadian * rx * (float)Math.Cos(t_angle) - _SinRadian * ry * (float)Math.Sin(t_angle) + cx;
- _controlPoint2.y = _SinRadian * rx * (float)Math.Cos(t_angle) + _CosRadian * ry * (float)Math.Sin(t_angle) + cy;
- if((_controlPoint2.x != p2.x) && (_controlPoint2.y != p2.y))
- i = -1;
- }
- //-----
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, _controlPoint1, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 _p5 = Vector2.zero;
- Vector2 _p6 = Vector2.zero;
- Vector2 _p7 = Vector2.zero;
- Vector2 _p8 = Vector2.zero;
- _graphics.GetThickLine(_controlPoint2, p2, width, ref _p5, ref _p6, ref _p7, ref _p8);
- float _half = width / 2f;
- float _ihalf1 = _half;
- float _ihalf2 = width - _ihalf1 + 0.5f;
- //-----
- float t_len1 = (_p1.x - cx) * (_p1.x - cx) + (_p1.y - cy) * (_p1.y - cy);
- float t_len2 = (_p2.x - cx) * (_p2.x - cx) + (_p2.y - cy) * (_p2.y - cy);
- Vector2 tempPoint;
- if(t_len1 > t_len2) {
- tempPoint = _p1;
- _p1 = _p2;
- _p2 = tempPoint;
- }
- t_len1 = (_p7.x - cx) * (_p7.x - cx) + (_p7.y - cy) * (_p7.y - cy);
- t_len2 = (_p8.x - cx) * (_p8.x - cx) + (_p8.y - cy) * (_p8.y - cy);
- if(t_len1 > t_len2) {
- tempPoint = _p7;
- _p7 = _p8;
- _p8 = tempPoint;
- }
- Profiler.BeginSample("SVGGraphicsStroke.ArcTo[CreateGraphicsPath]");
- SVGGraphicsPath _graphicsPath = new SVGGraphicsPath();
- _graphicsPath.AddMoveTo(_p2);
- _graphicsPath.AddArcTo(r1 + _ihalf1, r2 + _ihalf1, angle, largeArcFlag, sweepFlag, _p8);
- _graphicsPath.AddLineTo(_p7);
- _graphicsPath.AddArcTo(r1 - _ihalf2, r2 - _ihalf2, angle, largeArcFlag, !sweepFlag, _p1);
- _graphicsPath.AddLineTo(_p2);
- Profiler.EndSample();
- Profiler.BeginSample("SVGGraphicsStroke.ArcTo[FillPath]");
- _graphics.FillPath(_graphicsPath);
- Profiler.EndSample();
- MoveTo(p);
- Profiler.EndSample();
- }
- public void CubicCurveTo(Vector2 p1, Vector2 p2, Vector2 p) {
- if((isUseWidth) && ((int)_width > 1)) {
- CubicCurveTo(p1, p2, p, _width);
- return;
- }
- _basicDraw.CubicCurveTo(p1, p2, p);
- }
- public void CubicCurveTo(Vector2 p1, Vector2 p2, Vector2 p, float width) {
- Vector2 _point = Vector2.zero;
- _point = _basicDraw.currentPoint;
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- bool temp;
- temp = _graphics.GetThickLine(_point, p1, width, ref _p1, ref _p2, ref _p3, ref _p4);
- if(temp == false) {
- QuadraticCurveTo(p2, p, width);
- return;
- }
- Vector2 _p5 = Vector2.zero;
- Vector2 _p6 = Vector2.zero;
- Vector2 _p7 = Vector2.zero;
- Vector2 _p8 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p5, ref _p6, ref _p7, ref _p8);
- Vector2 _p9 = Vector2.zero;
- Vector2 _p10 = Vector2.zero;
- Vector2 _p11 = Vector2.zero;
- Vector2 _p12 = Vector2.zero;
- _graphics.GetThickLine(p2, p, width, ref _p9, ref _p10, ref _p11, ref _p12);
- Vector2 _cp1, _cp2, _cp3, _cp4;
- _cp1 = _graphics.GetCrossPoint(_p1, _p3, _p5, _p7);
- _cp2 = _graphics.GetCrossPoint(_p2, _p4, _p6, _p8);
- _cp3 = _graphics.GetCrossPoint(_p5, _p7, _p9, _p11);
- _cp4 = _graphics.GetCrossPoint(_p6, _p8, _p10, _p12);
- _basicDraw.MoveTo(_point);
- _basicDraw.CubicCurveTo(p1, p2, p);
- SVGGraphicsPath _graphicsPath = new SVGGraphicsPath();
- _graphicsPath.AddMoveTo(_p2);
- _graphicsPath.AddCubicCurveTo(_cp2, _cp4, _p12);
- _graphicsPath.AddLineTo(_p11);
- _graphicsPath.AddCubicCurveTo(_cp3, _cp1, _p1);
- _graphicsPath.AddLineTo(_p2);
- _graphics.FillPath(_graphicsPath);
- MoveTo(p);
- }
- public void QuadraticCurveTo(Vector2 p1, Vector2 p) {
- if((isUseWidth) && ((int)_width > 1)) {
- QuadraticCurveTo(p1, p, _width);
- return;
- }
- _basicDraw.QuadraticCurveTo(p1, p);
- }
- public void QuadraticCurveTo(Vector2 p1, Vector2 p, float width) {
- Vector2 _point = Vector2.zero;
- _point = _basicDraw.currentPoint;
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(_point, p1, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 _p5 = Vector2.zero;
- Vector2 _p6 = Vector2.zero;
- Vector2 _p7 = Vector2.zero;
- Vector2 _p8 = Vector2.zero;
- _graphics.GetThickLine(p1, p, width, ref _p5, ref _p6, ref _p7, ref _p8);
- Vector2 _cp1, _cp2;
- _cp1 = _graphics.GetCrossPoint(_p1, _p3, _p5, _p7);
- _cp2 = _graphics.GetCrossPoint(_p2, _p4, _p6, _p8);
- SVGGraphicsPath _graphicsPath = new SVGGraphicsPath();
- _graphicsPath.AddMoveTo(_p2);
- _graphicsPath.AddQuadraticCurveTo(_cp2, _p8);
- _graphicsPath.AddLineTo(_p7);
- _graphicsPath.AddQuadraticCurveTo(_cp1, _p1);
- _graphicsPath.AddLineTo(_p2);
- _graphics.FillPath(_graphicsPath);
- MoveTo(p);
- }
- public void LineTo(Vector2 p) {
- if((isUseWidth) && ((int)_width > 1)) {
- LineTo(p, _width);
- return;
- }
- _basicDraw.LineTo(p);
- }
- public void LineTo(Vector2 p, float width) {
- Vector2 _point = Vector2.zero;
- _point = _basicDraw.currentPoint;
- Line(_point, p, width);
- MoveTo(p);
- }
- public void Line(Vector2 p1, Vector2 p2) {
- if((isUseWidth) && ((int)_width > 1)) {
- Line(p1, p2, _width);
- return;
- }
- _basicDraw.Line(p1, p2);
- }
- public void Line(Vector2 p1, Vector2 p2, float width) {
- if((int)width == 1)
- Line(p1, p2);
- else {
- if(((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)) <= 4f)
- return;
- StrokeLineCapLeft(p1, p2, width);
- StrokeLineCapRight(p1, p2, width);
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2[] points = new Vector2[4];
- points[0] = _p1;
- points[1] = _p3;
- points[2] = _p4;
- points[3] = _p2;
- _graphics.FillPolygon(points);
- }
- }
- public void Rect(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4) {
- if((isUseWidth) && ((int)_width > 1)) {
- Rect(p1, p2, p3, p4, _width);
- return;
- }
- _basicDraw.Rect(p1, p2, p3, p4);
- }
- public void Rect(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float width) {
- if((int)width == 1)
- Rect(p1, p2, p3, p4);
- //Vector2[] points = new Vector2[4];
- rect_points[0] = p1;
- rect_points[1] = p2;
- rect_points[2] = p3;
- rect_points[3] = p4;
- Polygon(rect_points, width);
- }
- public void RoundedRect(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 p5, Vector2 p6, Vector2 p7, Vector2 p8,
- float r1, float r2,
- float angle) {
- if((isUseWidth) && ((int)_width > 1)) {
- RoundedRect(p1, p2, p3, p4, p5, p6, p7, p8, r1, r2,
- angle, _width);
- return;
- }
- _basicDraw.MoveTo(p1);
- _basicDraw.LineTo(p2);
- _basicDraw.ArcTo(r1, r2, angle, false, true, p3);
- _basicDraw.MoveTo(p3);
- _basicDraw.LineTo(p4);
- _basicDraw.ArcTo(r1, r2, angle, false, true, p5);
- _basicDraw.MoveTo(p5);
- _basicDraw.LineTo(p6);
- _basicDraw.ArcTo(r1, r2, angle, false, true, p7);
- _basicDraw.MoveTo(p7);
- _basicDraw.LineTo(p8);
- _basicDraw.ArcTo(r1, r2, angle, false, true, p1);
- }
- public void RoundedRect(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 p5, Vector2 p6, Vector2 p7, Vector2 p8,
- float r1, float r2,
- float angle, float width) {
- if((int)width == 1) {
- RoundedRect(p1, p2, p3, p4, p5, p6, p7, p8, r1, r2,
- angle);
- return;
- }
- Line(p1, p2, width);
- Line(p3, p4, width);
- Line(p5, p6, width);
- Line(p7, p8, width);
- // TODO: IIRC, `Vector2.zero` is a p/invoke. Would it be safe to chain assignments here? Would it be more
- // TODO: performant? What about just calling `new Vector2(0f, 0f)`?
- Vector2 _p1 = Vector2.zero;
- Vector2 _p2 = Vector2.zero;
- Vector2 _p3 = Vector2.zero;
- Vector2 _p4 = Vector2.zero;
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- Vector2 _p5 = Vector2.zero;
- Vector2 _p6 = Vector2.zero;
- Vector2 _p7 = Vector2.zero;
- Vector2 _p8 = Vector2.zero;
- //-------
- _graphics.GetThickLine(p3, p4, width, ref _p5, ref _p6, ref _p7, ref _p8);
- SVGGraphicsPath _graphicsPath = new SVGGraphicsPath();
- _graphicsPath.AddMoveTo(_p4);
- _graphicsPath.AddArcTo(r1 + (width / 2f), r2 + (width / 2f), angle, false, true, _p6);
- _graphicsPath.AddLineTo(_p5);
- _graphicsPath.AddArcTo(r1 - (width / 2f), r2 - (width / 2f), angle, false, false, _p3);
- _graphicsPath.AddLineTo(_p4);
- _graphics.FillPath(_graphicsPath);
- //-------
- _graphics.GetThickLine(p5, p6, width, ref _p1, ref _p2, ref _p3, ref _p4);
- _graphicsPath.Reset();
- _graphicsPath.AddMoveTo(_p8);
- _graphicsPath.AddArcTo(r1 + (width / 2f), r2 + (width / 2f), angle, false, true, _p2);
- _graphicsPath.AddLineTo(_p1);
- _graphicsPath.AddArcTo(r1 - (width / 2f), r2 - (width / 2f), angle, false, false, _p7);
- _graphicsPath.AddLineTo(_p8);
- _graphics.FillPath(_graphicsPath);
- //----------
- _graphics.GetThickLine(p7, p8, width, ref _p5, ref _p6, ref _p7, ref _p8);
- _graphicsPath.Reset();
- _graphicsPath.AddMoveTo(_p4);
- _graphicsPath.AddArcTo(r1 + (width / 2f), r2 + (width / 2f), angle, false, true, _p6);
- _graphicsPath.AddLineTo(_p5);
- _graphicsPath.AddArcTo(r1 - (width / 2f), r2 - (width / 2f), angle, false, false, _p3);
- _graphicsPath.AddLineTo(_p4);
- _graphics.FillPath(_graphicsPath);
- //-------
- _graphics.GetThickLine(p1, p2, width, ref _p1, ref _p2, ref _p3, ref _p4);
- _graphicsPath.Reset();
- _graphicsPath.AddMoveTo(_p8);
- _graphicsPath.AddArcTo(r1 + (width / 2f), r2 + (width / 2f), angle, false, true, _p2);
- _graphicsPath.AddLineTo(_p1);
- _graphicsPath.AddArcTo(r1 - (width / 2f), r2 - (width / 2f), angle, false, false, _p7);
- _graphicsPath.AddLineTo(_p8);
- _graphics.FillPath(_graphicsPath);
- }
- public void Circle(Vector2 p, float r) {
- if((isUseWidth) && ((int)_width > 1)) {
- Circle(p, r, _width);
- return;
- }
- _basicDraw.Circle(p, r);
- }
- public void Circle(Vector2 p, float r, float width) {
- if((int)width == 1)
- Circle(p, r);
- else {
- int r1 = (int)(width / 2f);
- int r2 = (int)width - r1;
- //Vector2[] _points = new Vector2[1];
- //_points[0] = new Vector2(p.x, p.y);
- SVGGraphicsPath _graphicsPath = new SVGGraphicsPath();
- _graphicsPath.AddCircleTo(p, r + r1);
- _graphicsPath.AddCircleTo(p, r - r2);
- _graphics.FillPath(_graphicsPath, p);
- }
- }
- public void Ellipse(Vector2 p, float rx, float ry, float angle) {
- if((isUseWidth) && ((int)_width > 1)) {
- Ellipse(p, rx, ry, angle, _width);
- return;
- }
- _basicDraw.Ellipse(p, rx, ry, angle);
- }
- public void Ellipse(Vector2 p, float rx, float ry, float angle, float width) {
- if((int)width == 1)
- Ellipse(p, rx, ry, angle);
- else {
- int r1 = (int)(width / 2f);
- int r2 = (int)width - r1;
- //Vector2[] _points = new Vector2[1] { p };
- SVGGraphicsPath _graphicsPath = new SVGGraphicsPath();
- _graphicsPath.AddEllipseTo(p, rx + r1, ry + r1, angle);
- _graphicsPath.AddEllipseTo(p, rx - r2, ry - r2, angle);
- _graphics.FillPath(_graphicsPath, p);
- }
- }
- public void Polygon(Vector2[] points) {
- if((isUseWidth) && ((int)_width > 1)) {
- Polygon(points, _width);
- return;
- }
- int _length = points.GetLength(0);
- if(_length > 1) {
- _basicDraw.MoveTo(points[0]);
- for(int i = 1; i < _length; i++)
- _basicDraw.LineTo(points[i]);
- _basicDraw.LineTo(points[0]);
- }
- }
- public void Polygon(Vector2[] points, float width) {
- if((int)width == 1) {
- Polygon(points);
- return;
- }
- int _length = points.GetLength(0);
- if(_length > 1) {
- if(_length == 2) {
- Line(points[0], points[1], width);
- StrokeLineCapLeft(points[0], points[1], width);
- StrokeLineCapRight(points[0], points[1], width);
- } else if(_length > 2) {
- StrokeLineJoin(points[_length - 1], points[0], points[1], width);
- Line(points[0], points[1], width);
- StrokeLineJoin(points[_length - 2], points[_length - 1], points[0], width);
- Line(points[_length - 1], points[0], width);
- for(int i = 1; i < _length - 1; i++) {
- StrokeLineJoin(points[i - 1], points[i], points[i + 1], width);
- Line(points[i], points[i + 1], width);
- }
- }
- }
- }
- public void DrawPath(SVGGraphicsPath graphicsPath) {
- graphicsPath.RenderPath(this, false);
- }
- //Fill co Stroke trong do luon
- public void DrawPath(SVGGraphicsPath graphicsPath, float width) {
- _width = width;
- isUseWidth = true;
- graphicsPath.RenderPath(this, false);
- isUseWidth = false;
- }
- }
|