Skip to content
This repository was archived by the owner on Apr 29, 2021. It is now read-only.

Commit 9ec0292

Browse files
committed
add isRRect to path/uipath
1 parent e0994be commit 9ec0292

File tree

5 files changed

+183
-9
lines changed

5 files changed

+183
-9
lines changed

Runtime/ui/painting/painting.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ public enum BlurStyle {
200200
solid,
201201
outer,
202202
inner,
203+
shadow
203204
}
204205

205206
public class MaskFilter : IEquatable<MaskFilter> {
@@ -212,6 +213,10 @@ public static MaskFilter blur(BlurStyle style, float sigma) {
212213
return new MaskFilter(style, sigma);
213214
}
214215

216+
public static MaskFilter shadow(float sigma) {
217+
return new MaskFilter(BlurStyle.shadow, sigma);
218+
}
219+
215220
public readonly BlurStyle style;
216221
public readonly float sigma;
217222

Runtime/ui/painting/path.cs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class Path {
2222

2323
uint _pathKey = 0;
2424

25+
bool _isRRect = false;
26+
public bool isRRect => this._isRRect;
27+
2528
public uint pathKey {
2629
get {
2730
return this._pathKey;
@@ -35,6 +38,39 @@ public Path(int capacity = 128) {
3538

3639
public List<float> commands => this._commands;
3740

41+
void _updateRRectFlag(bool isRRect) {
42+
if (this._commands.Count > 0 && !this._isRRect) {
43+
return;
44+
}
45+
this._isRRect = isRRect && this._hasOnlyMoveTos();
46+
}
47+
48+
bool _hasOnlyMoveTos() {
49+
var i = 0;
50+
while (i < this._commands.Count) {
51+
var cmd = (PathCommand) this._commands[i];
52+
switch (cmd) {
53+
case PathCommand.moveTo:
54+
i += 3;
55+
break;
56+
case PathCommand.lineTo:
57+
return false;
58+
case PathCommand.bezierTo:
59+
return false;
60+
case PathCommand.close:
61+
i++;
62+
break;
63+
case PathCommand.winding:
64+
i += 2;
65+
break;
66+
default:
67+
return false;
68+
}
69+
}
70+
71+
return true;
72+
}
73+
3874
public override string ToString() {
3975
var sb = new StringBuilder("Path: count = " + this._commands.Count);
4076

@@ -88,6 +124,7 @@ void _reset() {
88124

89125
this._pathKey = pathGlobalKey++;
90126
this._cache = null;
127+
this._isRRect = false;
91128
}
92129

93130
internal PathCache flatten(float scale) {
@@ -238,22 +275,25 @@ public void moveTo(float x, float y) {
238275
public void relativeLineTo(float x, float y) {
239276
var x0 = this._commandx;
240277
var y0 = this._commandy;
241-
278+
279+
this._updateRRectFlag(false);
242280
this._appendLineTo(x + x0, y + y0);
243281
}
244282

245283
public void lineTo(float x, float y) {
284+
this._updateRRectFlag(false);
246285
this._appendLineTo(x, y);
247286
}
248287

249288
public void cubicTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
289+
this._updateRRectFlag(false);
250290
this._appendBezierTo(c1x, c1y, c2x, c2y, x, y);
251291
}
252292

253293
public void relativeCubicTo(float c1x, float c1y, float c2x, float c2y, float x, float y) {
254294
var x0 = this._commandx;
255295
var y0 = this._commandy;
256-
296+
this._updateRRectFlag(false);
257297
this.cubicTo(x0 + c1x, y0 + c1y, x0 + c2x, y0 + c2y, x0 + x, y0 + y);
258298
}
259299

@@ -262,6 +302,7 @@ public void quadraticBezierTo(float cx, float cy, float x, float y) {
262302
var y0 = this._commandy;
263303

264304
const float twoThird = 2.0f / 3.0f;
305+
this._updateRRectFlag(false);
265306
this._appendBezierTo(
266307
x0 + twoThird * (cx - x0), y0 + twoThird * (cy - y0),
267308
x + twoThird * (cx - x), y + twoThird * (cy - y),
@@ -272,10 +313,12 @@ public void relativeQuadraticBezierTo(float cx, float cy, float x, float y) {
272313
var x0 = this._commandx;
273314
var y0 = this._commandy;
274315

316+
this._updateRRectFlag(false);
275317
this.quadraticBezierTo(x0 + cx, y0 + cy, x0 + x, y0 + y);
276318
}
277319

278320
public void conicTo(float x1, float y1, float x2, float y2, float w) {
321+
this._updateRRectFlag(false);
279322
if (!(w > 0)) {
280323
this.lineTo(x2, y2);
281324
return;
@@ -313,7 +356,7 @@ public void conicTo(float x1, float y1, float x2, float y2, float w) {
313356
public void relativeConicTo(float x1, float y1, float x2, float y2, float w) {
314357
var x0 = this._commandx;
315358
var y0 = this._commandy;
316-
359+
this._updateRRectFlag(false);
317360
this.conicTo(x0 + x1, y0 + y1, x0 + x2, y0 + y2, w);
318361
}
319362

@@ -324,7 +367,7 @@ public void arcToPoint(Offset arcEnd,
324367
bool largeArc = false,
325368
bool clockwise = false) {
326369
radius = radius ?? Radius.zero;
327-
370+
this._updateRRectFlag(false);
328371
D.assert(PaintingUtils._offsetIsValid(arcEnd));
329372
D.assert(PaintingUtils._radiusIsValid(radius));
330373

@@ -458,6 +501,7 @@ public void winding(PathWinding dir) {
458501
}
459502

460503
public void addRect(Rect rect) {
504+
this._updateRRectFlag(true);
461505
this._appendMoveTo(rect.left, rect.top);
462506
this._appendLineTo(rect.left, rect.bottom);
463507
this._appendLineTo(rect.right, rect.bottom);
@@ -466,6 +510,7 @@ public void addRect(Rect rect) {
466510
}
467511

468512
public void addRRect(RRect rrect) {
513+
this._updateRRectFlag(true);
469514
float w = rrect.width;
470515
float h = rrect.height;
471516
float halfw = Mathf.Abs(w) * 0.5f;
@@ -501,6 +546,7 @@ public void addRRect(RRect rrect) {
501546
}
502547

503548
public void addEllipse(float cx, float cy, float rx, float ry) {
549+
this._updateRRectFlag(true);
504550
this._appendMoveTo(cx - rx, cy);
505551
this._appendBezierTo(cx - rx, cy + ry * _KAPPA90,
506552
cx - rx * _KAPPA90, cy + ry, cx, cy + ry);
@@ -514,16 +560,19 @@ public void addEllipse(float cx, float cy, float rx, float ry) {
514560
}
515561

516562
public void addCircle(float cx, float cy, float r) {
563+
this._updateRRectFlag(true);
517564
this.addEllipse(cx, cy, r, r);
518565
}
519566

520567
public void addOval(Rect oval) {
521568
D.assert(oval != null);
569+
this._updateRRectFlag(true);
522570
var center = oval.center;
523571
this.addEllipse(center.dx, center.dy, oval.width / 2, oval.height / 2);
524572
}
525573

526574
public void arcTo(float x1, float y1, float x2, float y2, float radius) {
575+
this._updateRRectFlag(false);
527576
var x0 = this._commandx;
528577
var y0 = this._commandy;
529578

@@ -563,6 +612,7 @@ public void arcTo(float x1, float y1, float x2, float y2, float radius) {
563612
}
564613

565614
public void arcTo(Rect rect, float startAngle, float sweepAngle, bool forceMoveTo = true) {
615+
this._updateRRectFlag(false);
566616
var mat = Matrix3.makeScale(rect.width / 2, rect.height / 2);
567617
var center = rect.center;
568618
mat.postTranslate(center.dx, center.dy);
@@ -572,6 +622,7 @@ public void arcTo(Rect rect, float startAngle, float sweepAngle, bool forceMoveT
572622
}
573623

574624
public void addArc(Rect rect, float startAngle, float sweepAngle) {
625+
this._updateRRectFlag(false);
575626
this.arcTo(rect, startAngle, sweepAngle, true);
576627
}
577628

@@ -659,10 +710,12 @@ void _addArcCommands(
659710
}
660711

661712
public void addArc(float cx, float cy, float r, float a0, float a1, PathWinding dir, bool forceMoveTo = true) {
713+
this._updateRRectFlag(false);
662714
this._addArcCommands(cx, cy, r, a0, a1, dir, forceMoveTo);
663715
}
664716

665717
public void addPolygon(IList<Offset> points, bool close) {
718+
this._updateRRectFlag(false);
666719
D.assert(points != null);
667720
if (points.Count == 0) {
668721
return;
@@ -705,7 +758,8 @@ public void addPath(Path path, Offset offset) {
705758

706759
public void addPath(Path path, Matrix3 transform = null) {
707760
D.assert(path != null);
708-
761+
762+
this._updateRRectFlag(path.isRRect);
709763
var i = 0;
710764
while (i < path._commands.Count) {
711765
var cmd = (PathCommand) path._commands[i];

Runtime/ui/painting/shadow_utils.cs

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
using Unity.UIWidgets.material;
12
using UnityEngine;
23

34
namespace Unity.UIWidgets.ui {
45
static class ShadowUtils {
5-
public const bool kUseFastShadow = false;
6+
public const bool kUseFastShadow = true;
67

78
const float kAmbientHeightFactor = 1.0f / 128.0f;
89
const float kAmbientGeomFactor = 64.0f;
@@ -11,6 +12,8 @@ static class ShadowUtils {
1112

1213
const float kMaxAmbientRadius = 300 * kAmbientHeightFactor * kAmbientGeomFactor;
1314

15+
const bool debugShadow = true;
16+
1417
static float divideAndPin(float numer, float denom, float min, float max) {
1518
return (numer / denom).clamp(min, max);
1619
}
@@ -140,7 +143,7 @@ float heightFunc(float x, float y) {
140143
public static void drawShadow(Canvas canvas, Path path, Vector3 zPlaneParams, Vector3 devLightPos,
141144
float lightRadius, uiColor ambientColor, uiColor spotColor, int flags) {
142145
if (kUseFastShadow) {
143-
drawShadowFast(canvas, path, zPlaneParams, devLightPos, lightRadius, ambientColor, spotColor, flags);
146+
drawShadowFull2(canvas, path, zPlaneParams, devLightPos, lightRadius, ambientColor, spotColor, flags);
144147
}
145148
else {
146149
drawShadowFull(canvas, path, zPlaneParams, devLightPos, lightRadius, ambientColor, spotColor, flags);
@@ -199,6 +202,67 @@ static void drawShadowFull(Canvas canvas, Path path, Vector3 zPlaneParams, Vecto
199202

200203
_shadowPaint.maskFilter = null;
201204
}
205+
206+
207+
static void drawShadowFull2(Canvas canvas, Path path, Vector3 zPlaneParams, Vector3 devLightPos,
208+
float lightRadius, uiColor ambientColor, uiColor spotColor, int flags) {
209+
Matrix3 viewMatrix = canvas.getTotalMatrix();
210+
211+
//debug shadow
212+
if (debugShadow) {
213+
var isRRect = path.isRRect;
214+
if (isRRect) {
215+
ambientColor = uiColor.fromColor(Colors.red);
216+
spotColor = uiColor.fromColor(Colors.red);
217+
}
218+
else {
219+
ambientColor = uiColor.fromColor(Colors.green);
220+
spotColor = uiColor.fromColor(Colors.green);
221+
}
222+
}
223+
224+
//ambient light
225+
_devSpacePath.resetAll();
226+
_devSpacePath.addPath(path, viewMatrix);
227+
float devSpaceOutset = ambientBlurRadius(zPlaneParams.z);
228+
float oneOverA = ambientRecipAlpha(zPlaneParams.z);
229+
float blurRadius = 0.5f * devSpaceOutset * oneOverA;
230+
float strokeWidth = 0.5f * (devSpaceOutset - blurRadius);
231+
232+
_shadowPaint.color = new Color(ambientColor.value);
233+
_shadowPaint.strokeWidth = strokeWidth;
234+
_shadowPaint.style = PaintingStyle.fill;
235+
236+
canvas.save();
237+
_shadowMatrix.reset();
238+
canvas.setMatrix(_shadowMatrix);
239+
float sigma = convertRadiusToSigma(blurRadius);
240+
_shadowPaint.maskFilter = MaskFilter.blur(BlurStyle.normal, sigma);
241+
canvas.drawPath(_devSpacePath, _shadowPaint);
242+
canvas.restore();
243+
244+
//spot light
245+
float radius = 0.0f;
246+
247+
if (!getSpotShadowTransform(devLightPos, lightRadius, viewMatrix, zPlaneParams, path.getBounds(),
248+
_shadowMatrix, ref radius)) {
249+
return;
250+
}
251+
252+
canvas.save();
253+
canvas.setMatrix(_shadowMatrix);
254+
255+
_shadowPaint.color = new Color(spotColor.value);
256+
_shadowPaint.strokeWidth = 0;
257+
_shadowPaint.style = PaintingStyle.fill;
258+
float sigma2 = convertRadiusToSigma(radius);
259+
_shadowPaint.maskFilter = MaskFilter.blur(BlurStyle.normal, sigma2);
260+
canvas.drawPath(path, _shadowPaint);
261+
262+
canvas.restore();
263+
264+
_shadowPaint.maskFilter = null;
265+
}
202266

203267
static void drawShadowFast(Canvas canvas, Path path, Vector3 zPlaneParams, Vector3 devLightPos,
204268
float lightRadius, uiColor ambientColor, uiColor spotColor, int flags) {

0 commit comments

Comments
 (0)