1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Crow
{
public static class CairoHelpers
{
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
if (val.CompareTo(min) < 0) return min;
else if(val.CompareTo(max) > 0) return max;
else return val;
}
/// <summary>
/// Convert string to utf8 (extension method)
/// </summary>
/// <returns>byte array with utf8 encoding</returns>
public static byte[] ToUtf8(this String str)
{
return System.Text.UTF8Encoding.UTF8.GetBytes (str);
}
public static double min(params double[] arr)
{
int minp = 0;
for (int i = 1; i < arr.Length; i++)
if (arr[i] < arr[minp])
minp = i;
return arr[minp];
}
public static void CairoRectangle(Cairo.Context gr, Rectangle r, double radius, double stroke = 0.0)
{
if (radius > 0)
CairoHelpers.DrawRoundedRectangle (gr, r, radius, stroke);
else
gr.Rectangle (r, stroke);
}
public static void CairoCircle(Cairo.Context gr, Rectangle r)
{
gr.Arc(r.X + r.Width/2, r.Y + r.Height/2, Math.Min(r.Width,r.Height)/2, 0, 2*Math.PI);
}
public static void DrawRoundedRectangle(Cairo.Context gr, Rectangle r, double radius, double stroke = 0.0)
{
if (stroke>0.0) {
gr.LineWidth = stroke;
double hsw = stroke / 2.0;
DrawRoundedRectangle (gr, r.X + hsw, r.Y + hsw, r.Width - stroke, r.Height - stroke, radius);
gr.Stroke ();
}else
DrawRoundedRectangle(gr, r.X, r.Y, r.Width, r.Height, radius);
}
public static void DrawRoundedRectangle(Cairo.Context gr, double x, double y, double width, double height, double radius)
{
gr.Save();
if ((radius > height / 2) || (radius > width / 2))
radius = min(height / 2, width / 2);
gr.MoveTo(x, y + radius);
gr.Arc(x + radius, y + radius, radius, Math.PI, -Math.PI / 2);
gr.LineTo(x + width - radius, y);
gr.Arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0);
gr.LineTo(x + width, y + height - radius);
gr.Arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2);
gr.LineTo(x + radius, y + height);
gr.Arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
gr.ClosePath();
gr.Restore();
}
public static void StrokeRaisedRectangle(Cairo.Context gr, Rectangle r, double width = 1)
{
gr.Save();
r.Inflate((int)-width / 2, (int)-width / 2);
gr.LineWidth = width;
gr.SetSourceColor(Color.White);
gr.MoveTo(r.BottomLeft);
gr.LineTo(r.TopLeft);
gr.LineTo(r.TopRight);
gr.Stroke();
gr.SetSourceColor(Color.DarkGray);
gr.MoveTo(r.TopRight);
gr.LineTo(r.BottomRight);
gr.LineTo(r.BottomLeft);
gr.Stroke();
gr.Restore();
}
public static void StrokeLoweredRectangle(Cairo.Context gr, Rectangle r, double width = 1)
{
gr.Save();
r.Inflate((int)-width / 2, (int)-width / 2);
gr.LineWidth = width;
gr.SetSourceColor(Color.DarkGray);
gr.MoveTo(r.BottomLeft);
gr.LineTo(r.TopLeft);
gr.LineTo(r.TopRight);
gr.Stroke();
gr.SetSourceColor(Color.White);
gr.MoveTo(r.TopRight);
gr.LineTo(r.BottomRight);
gr.LineTo(r.BottomLeft);
gr.Stroke();
gr.Restore();
}
}
}
|