1 module skia.SKRoundRect; 2 3 import skia.Definitions; 4 import skia.MathTypes; 5 import skia.SKObject; 6 import skia.SkiaApi; 7 import skia.SKMatrix; 8 import skia.Exceptions; 9 import skia.Util; 10 11 class SKRoundRect : SKObject, ISKSkipObjectRegistration { 12 this(void* handle, bool owns) { 13 super(handle, owns); 14 } 15 16 this() { 17 this(SkiaApi.sk_rrect_new(), true); 18 if (Handle is null) { 19 throw new InvalidOperationException("Unable to create a new SKRoundRect instance."); 20 } 21 SetEmpty(); 22 } 23 24 this(SKRect rect) { 25 this(SkiaApi.sk_rrect_new(), true); 26 if (Handle is null) { 27 throw new InvalidOperationException("Unable to create a new SKRoundRect instance."); 28 } 29 SetRect(rect); 30 } 31 32 this(SKRect rect, float radius) { 33 this(rect, radius, radius); 34 } 35 36 this(SKRect rect, float xRadius, float yRadius) { 37 this(SkiaApi.sk_rrect_new(), true); 38 if (Handle is null) { 39 throw new InvalidOperationException("Unable to create a new SKRoundRect instance."); 40 } 41 SetRect(rect, xRadius, yRadius); 42 } 43 44 this(SKRoundRect rrect) { 45 this(SkiaApi.sk_rrect_new_copy(cast(sk_rrect_t*) rrect.Handle), true); 46 } 47 48 // protected override void Dispose (bool disposing) 49 // { 50 // return super.Dispose (disposing); 51 // } 52 53 protected override void DisposeNative() { 54 return SkiaApi.sk_rrect_delete(cast(sk_rrect_t*) Handle); 55 } 56 57 SKRect Rect() { 58 59 SKRect rect; 60 SkiaApi.sk_rrect_get_rect(cast(sk_rrect_t*) Handle, &rect); 61 return rect; 62 } 63 64 // SKPoint[] Radii() 65 // { 66 // return new[] { 67 // GetRadii(SKRoundRectCorner.UpperLeft), 68 // GetRadii(SKRoundRectCorner.UpperRight), 69 // GetRadii(SKRoundRectCorner.LowerRight), 70 // GetRadii(SKRoundRectCorner.LowerLeft), 71 // }; 72 // } 73 74 SKRoundRectType Type() { 75 return SkiaApi.sk_rrect_get_type(cast(sk_rrect_t*) Handle); 76 } 77 78 float Width() { 79 return SkiaApi.sk_rrect_get_width(cast(sk_rrect_t*) Handle); 80 } 81 82 float Height() { 83 return SkiaApi.sk_rrect_get_height(cast(sk_rrect_t*) Handle); 84 } 85 86 bool IsValid() { 87 return SkiaApi.sk_rrect_is_valid(cast(sk_rrect_t*) Handle); 88 } 89 90 bool AllCornersCircular() { 91 return CheckAllCornersCircular(Utils.NearlyZero); 92 } 93 94 bool CheckAllCornersCircular(float tolerance) { 95 auto ul = GetRadii(SKRoundRectCorner.UpperLeft); 96 auto ur = GetRadii(SKRoundRectCorner.UpperRight); 97 auto lr = GetRadii(SKRoundRectCorner.LowerRight); 98 auto ll = GetRadii(SKRoundRectCorner.LowerLeft); 99 100 return Utils.NearlyEqual(ul.X, ul.Y, tolerance) 101 && Utils.NearlyEqual(ur.X, ur.Y, tolerance) 102 && Utils.NearlyEqual(lr.X, lr.Y, tolerance) && Utils.NearlyEqual(ll.X, ll.Y, tolerance); 103 } 104 105 void SetEmpty() { 106 SkiaApi.sk_rrect_set_empty(cast(sk_rrect_t*) Handle); 107 } 108 109 void SetRect(SKRect rect) { 110 SkiaApi.sk_rrect_set_rect(cast(sk_rrect_t*) Handle, &rect); 111 } 112 113 void SetRect(SKRect rect, float xRadius, float yRadius) { 114 SkiaApi.sk_rrect_set_rect_xy(cast(sk_rrect_t*) Handle, &rect, xRadius, yRadius); 115 } 116 117 void SetOval(SKRect rect) { 118 SkiaApi.sk_rrect_set_oval(cast(sk_rrect_t*) Handle, &rect); 119 } 120 121 void SetNinePatch(SKRect rect, float leftRadius, float topRadius, 122 float rightRadius, float bottomRadius) { 123 SkiaApi.sk_rrect_set_nine_patch(cast(sk_rrect_t*) Handle, &rect, 124 leftRadius, topRadius, rightRadius, bottomRadius); 125 } 126 127 void SetRectRadii(SKRect rect, SKPoint[] radii) { 128 if (radii is null) 129 throw new ArgumentNullException(radii.stringof); 130 if (radii.length != 4) 131 throw new ArgumentException("Radii must have a length of 4.", radii.stringof); 132 133 SKPoint* r = radii.ptr; 134 SkiaApi.sk_rrect_set_rect_radii(cast(sk_rrect_t*) Handle, &rect, r); 135 } 136 137 bool Contains(SKRect rect) { 138 return SkiaApi.sk_rrect_contains(cast(sk_rrect_t*) Handle, &rect); 139 } 140 141 SKPoint GetRadii(SKRoundRectCorner corner) { 142 SKPoint radii; 143 SkiaApi.sk_rrect_get_radii(cast(sk_rrect_t*) Handle, corner, &radii); 144 return radii; 145 } 146 147 void Deflate(SKSize size) { 148 Deflate(size.Width, size.Height); 149 } 150 151 void Deflate(float dx, float dy) { 152 SkiaApi.sk_rrect_inset(cast(sk_rrect_t*) Handle, dx, dy); 153 } 154 155 void Inflate(SKSize size) { 156 Inflate(size.Width, size.Height); 157 } 158 159 void Inflate(float dx, float dy) { 160 SkiaApi.sk_rrect_outset(cast(sk_rrect_t*) Handle, dx, dy); 161 } 162 163 void Offset(SKPoint pos) { 164 Offset(pos.X, pos.Y); 165 } 166 167 void Offset(float dx, float dy) { 168 SkiaApi.sk_rrect_offset(cast(sk_rrect_t*) Handle, dx, dy); 169 } 170 171 bool TryTransform(SKMatrix matrix, out SKRoundRect transformed) { 172 auto destHandle = SkiaApi.sk_rrect_new(); 173 if (SkiaApi.sk_rrect_transform(cast(sk_rrect_t*) Handle, &matrix, destHandle)) { 174 transformed = new SKRoundRect(destHandle, true); 175 return true; 176 } 177 SkiaApi.sk_rrect_delete(destHandle); 178 transformed = null; 179 return false; 180 } 181 182 SKRoundRect Transform(SKMatrix matrix) { 183 SKRoundRect transformed; 184 if (TryTransform(matrix, transformed)) { 185 return transformed; 186 } 187 return null; 188 } 189 }