93 lines
3.3 KiB
C#
93 lines
3.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace EasyChart.Layers
|
|
{
|
|
public static class RoundedRectUtils
|
|
{
|
|
private static readonly List<Vector2> s_tempRoundedPoints = new List<Vector2>(64);
|
|
|
|
public static void BuildRoundedRectPoints(List<Vector2> points, Rect rect, float radius, int segments, bool roundTL, bool roundTR, bool roundBR, bool roundBL)
|
|
{
|
|
if (points == null) return;
|
|
points.Clear();
|
|
|
|
float x = rect.xMin;
|
|
float y = rect.yMin;
|
|
float w = rect.width;
|
|
float h = rect.height;
|
|
|
|
if (w <= 0f || h <= 0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float r = Mathf.Max(0f, radius);
|
|
r = Mathf.Min(r, Mathf.Min(w, h) * 0.5f);
|
|
int seg = Mathf.Clamp(segments, 1, 16);
|
|
|
|
void AddPoint(Vector2 p)
|
|
{
|
|
if (points.Count > 0)
|
|
{
|
|
var last = points[points.Count - 1];
|
|
if (Mathf.Approximately(last.x, p.x) && Mathf.Approximately(last.y, p.y)) return;
|
|
}
|
|
points.Add(p);
|
|
}
|
|
|
|
void AddArc(Vector2 center, float startDeg, float endDeg)
|
|
{
|
|
for (int i = 1; i <= seg; i++)
|
|
{
|
|
float t = (float)i / seg;
|
|
float a = Mathf.Deg2Rad * Mathf.Lerp(startDeg, endDeg, t);
|
|
float px = center.x + Mathf.Cos(a) * r;
|
|
float py = center.y + Mathf.Sin(a) * r;
|
|
AddPoint(new Vector2(px, py));
|
|
}
|
|
}
|
|
|
|
bool useTL = roundTL && r > 0f;
|
|
bool useTR = roundTR && r > 0f;
|
|
bool useBR = roundBR && r > 0f;
|
|
bool useBL = roundBL && r > 0f;
|
|
|
|
AddPoint(new Vector2(x + (useTL ? r : 0f), y));
|
|
AddPoint(new Vector2(x + w - (useTR ? r : 0f), y));
|
|
if (useTR) AddArc(new Vector2(x + w - r, y + r), 270f, 360f);
|
|
else AddPoint(new Vector2(x + w, y));
|
|
|
|
AddPoint(new Vector2(x + w, y + h - (useBR ? r : 0f)));
|
|
if (useBR) AddArc(new Vector2(x + w - r, y + h - r), 0f, 90f);
|
|
else AddPoint(new Vector2(x + w, y + h));
|
|
|
|
AddPoint(new Vector2(x + (useBL ? r : 0f), y + h));
|
|
if (useBL) AddArc(new Vector2(x + r, y + h - r), 90f, 180f);
|
|
else AddPoint(new Vector2(x, y + h));
|
|
|
|
AddPoint(new Vector2(x, y + (useTL ? r : 0f)));
|
|
if (useTL) AddArc(new Vector2(x + r, y + r), 180f, 270f);
|
|
else AddPoint(new Vector2(x, y));
|
|
}
|
|
|
|
public static void BeginRoundedRectPath(Painter2D painter, Rect rect, float radius, int segments, bool roundTL, bool roundTR, bool roundBR, bool roundBL)
|
|
{
|
|
if (painter == null) return;
|
|
|
|
s_tempRoundedPoints.Clear();
|
|
BuildRoundedRectPoints(s_tempRoundedPoints, rect, radius, segments, roundTL, roundTR, roundBR, roundBL);
|
|
if (s_tempRoundedPoints.Count == 0) return;
|
|
|
|
painter.BeginPath();
|
|
painter.MoveTo(s_tempRoundedPoints[0]);
|
|
for (int i = 1; i < s_tempRoundedPoints.Count; i++)
|
|
{
|
|
painter.LineTo(s_tempRoundedPoints[i]);
|
|
}
|
|
painter.ClosePath();
|
|
}
|
|
}
|
|
}
|