浏览代码

update canvas

/main
kg 6 年前
当前提交
4b9239b0
共有 81 个文件被更改,包括 5524 次插入1802 次删除
  1. 380
      Assets/UIWidgets/Tests/CanvasAndLayers.cs
  2. 16
      Assets/UIWidgets/Tests/EditableTextWiget.cs
  3. 166
      Assets/UIWidgets/Tests/Paragraph.cs
  4. 19
      Assets/UIWidgets/Tests/RenderBoxes.cs
  5. 16
      Assets/UIWidgets/Tests/RenderEditable.cs
  6. 12
      Assets/UIWidgets/Tests/Widgets.cs
  7. 32
      Assets/UIWidgets/async/timer.cs
  8. 231
      Assets/UIWidgets/editor/editor_window.cs
  9. 9
      Assets/UIWidgets/flow/clip_rect_layer.cs
  10. 6
      Assets/UIWidgets/flow/clip_rrect_layer.cs
  11. 4
      Assets/UIWidgets/flow/container_layer.cs
  12. 6
      Assets/UIWidgets/flow/layer.cs
  13. 23
      Assets/UIWidgets/flow/picture_layer.cs
  14. 134
      Assets/UIWidgets/flow/raster_cache.cs
  15. 14
      Assets/UIWidgets/flow/transform_layer.cs
  16. 2
      Assets/UIWidgets/foundation/debug.cs
  17. 5
      Assets/UIWidgets/lib/cache_manager/cache_manager.cs
  18. 11
      Assets/UIWidgets/painting/border_radius.cs
  19. 148
      Assets/UIWidgets/painting/box_border.cs
  20. 11
      Assets/UIWidgets/painting/box_decoration.cs
  21. 2
      Assets/UIWidgets/painting/box_shadow.cs
  22. 4
      Assets/UIWidgets/painting/clip.cs
  23. 2
      Assets/UIWidgets/painting/decoration_image.cs
  24. 9
      Assets/UIWidgets/promise/Promise.cs
  25. 9
      Assets/UIWidgets/promise/Promise_NonGeneric.cs
  26. 6
      Assets/UIWidgets/rendering/box.cs
  27. 4
      Assets/UIWidgets/rendering/editable.cs
  28. 6
      Assets/UIWidgets/rendering/layer.cs
  29. 2
      Assets/UIWidgets/rendering/object.cs
  30. 2
      Assets/UIWidgets/rendering/proxy_box.cs
  31. 6
      Assets/UIWidgets/rendering/view.cs
  32. 4
      Assets/UIWidgets/rendering/viewport.cs
  33. 2
      Assets/UIWidgets/scheduler/binding.cs
  34. 80
      Assets/UIWidgets/ui/compositing.cs
  35. 190
      Assets/UIWidgets/ui/geometry.cs
  36. 305
      Assets/UIWidgets/ui/painting/canvas.cs
  37. 978
      Assets/UIWidgets/ui/painting/canvas_impl.cs
  38. 95
      Assets/UIWidgets/ui/painting/draw_cmd.cs
  39. 202
      Assets/UIWidgets/ui/painting/painting.cs
  40. 315
      Assets/UIWidgets/ui/painting/picture.cs
  41. 120
      Assets/UIWidgets/ui/painting/txt/mesh_generator.cs
  42. 5
      Assets/UIWidgets/ui/painting/txt/text_blob.cs
  43. 6
      Assets/UIWidgets/ui/text.cs
  44. 21
      Assets/UIWidgets/ui/txt/paragraph.cs
  45. 2
      Assets/UIWidgets/ui/txt/styled_runs.cs
  46. 6
      Assets/UIWidgets/ui/window.cs
  47. 14
      Assets/UIWidgets/widgets/basic.cs
  48. 3
      Assets/UIWidgets/widgets/binding.cs
  49. 4
      Assets/UIWidgets/widgets/image.cs
  50. 80
      Assets/UIWidgets/Resources/UIWidgets_GUITexture.shader
  51. 3
      Assets/UIWidgets/Resources/UIWidgets_GUITexture.shader.meta
  52. 225
      Assets/UIWidgets/Resources/UIWidgets_canvas.shader
  53. 3
      Assets/UIWidgets/Resources/UIWidgets_canvas.shader.meta
  54. 92
      Assets/UIWidgets/editor/rasterizer.cs
  55. 3
      Assets/UIWidgets/editor/rasterizer.cs.meta
  56. 174
      Assets/UIWidgets/editor/surface.cs
  57. 3
      Assets/UIWidgets/editor/surface.cs.meta
  58. 66
      Assets/UIWidgets/flow/compositor_context.cs
  59. 3
      Assets/UIWidgets/flow/compositor_context.cs.meta
  60. 46
      Assets/UIWidgets/flow/layer_tree.cs
  61. 3
      Assets/UIWidgets/flow/layer_tree.cs.meta
  62. 1001
      Assets/UIWidgets/ui/matrix.cs
  63. 3
      Assets/UIWidgets/ui/matrix.cs.meta
  64. 275
      Assets/UIWidgets/ui/painting/canvas_clip.cs
  65. 3
      Assets/UIWidgets/ui/painting/canvas_clip.cs.meta
  66. 1001
      Assets/UIWidgets/ui/painting/path.cs
  67. 3
      Assets/UIWidgets/ui/painting/path.cs.meta
  68. 50
      Assets/UIWidgets/Resources/UIWidgets_CG.cginc
  69. 3
      Assets/UIWidgets/Resources/UIWidgets_CG.cginc.meta
  70. 162
      Assets/UIWidgets/Resources/UIWidgets_GUIRoundedRect.shader
  71. 3
      Assets/UIWidgets/Resources/UIWidgets_GUIRoundedRect.shader.meta
  72. 92
      Assets/UIWidgets/Resources/UIWidgets_GUITextureClip.shader
  73. 3
      Assets/UIWidgets/Resources/UIWidgets_GUITextureClip.shader.meta
  74. 119
      Assets/UIWidgets/Resources/UIWidgets_ShadowRect.shader
  75. 63
      Assets/UIWidgets/Resources/UIWidgets_2DHandlesLines.shader
  76. 3
      Assets/UIWidgets/Resources/UIWidgets_2DHandlesLines.shader.meta
  77. 9
      Assets/UIWidgets/Resources/UIWidgets_ShadowRect.shader.meta
  78. 70
      Assets/UIWidgets/Resources/UIWidgets_Text.shader
  79. 3
      Assets/UIWidgets/Resources/UIWidgets_Text.shader.meta
  80. 3
      Assets/UIWidgets/flow/layer_builder.cs.meta
  81. 107
      Assets/UIWidgets/flow/layer_builder.cs

380
Assets/UIWidgets/Tests/CanvasAndLayers.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.editor;
using UnityEditor.Experimental.UIElements;
using UnityEngine.Rendering;
using BlendMode = UIWidgets.ui.BlendMode;
using Gradient = UIWidgets.ui.Gradient;
using Random = System.Random;
static Material _guiTextureMat;
internal static Material _getGUITextureMat() {
if (_guiTextureMat) {
return _guiTextureMat;
}
var guiTextureShader = Shader.Find("UIWidgets/GUITexture");
if (guiTextureShader == null) {
throw new Exception("UIWidgets/GUITexture not found");
}
_guiTextureMat = new Material(guiTextureShader);
return _guiTextureMat;
}
private readonly Action[] _options;
private readonly string[] _optionStrings;

private PaintingBinding paintingBinding;
private PaintingBinding _paintingBinding;
private RenderTexture _renderTexture;
private WindowAdapter _windowAdapter;
CanvasAndLayers() {
this._options = new Action[] {
this.drawPloygon4,

this._selected = 0;
this.titleContent = new GUIContent("CanvasAndLayers");
this.SetAntiAliasing(4);
}
void OnGUI() {

}
}
this._windowAdapter.OnGUI();
this.createRenderTexture();
Window.instance = this._windowAdapter;
Window.instance = null;
Graphics.DrawTexture(new UnityEngine.Rect(0, 0, this.position.width, this.position.height),
this._renderTexture, _getGUITextureMat());
void Update() {
this._windowAdapter.Update();
}
this.paintingBinding = new PaintingBinding(null);
paintingBinding.initInstances();
this._windowAdapter = new WindowAdapter(this);
this._windowAdapter.OnEnable();
this._paintingBinding = new PaintingBinding(this._windowAdapter);
this._paintingBinding.initInstances();
}
void createRenderTexture() {
var width = (int) (this.position.width * EditorGUIUtility.pixelsPerPoint);
var height = (int) (this.position.height * EditorGUIUtility.pixelsPerPoint);
if (this._renderTexture == null ||
this._renderTexture.width != width ||
this._renderTexture.height != height) {
var desc = new RenderTextureDescriptor(
width,
height,
RenderTextureFormat.Default, 24) {
msaaSamples = QualitySettings.antiAliasing,
useMipMap = false,
autoGenerateMips = false,
};
this._renderTexture = RenderTexture.GetTemporary(desc);
}
}
private void LoadImage(string url) {

}
void drawPloygon4() {
var canvas = new CanvasImpl();
var canvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
canvas.drawPloygon4(
new[] {new Offset(10, 10), new Offset(10, 110), new Offset(110, 110), new Offset(110, 10)},
canvas.drawRect(
Rect.fromLTRB(10, 10, 110, 110),
canvas.drawPloygon4(
new[] {new Offset(10, 150), new Offset(10, 160), new Offset(140, 120), new Offset(110, 180)},
paint);
var path = new Path();
path.moveTo(10, 150);
path.lineTo(10, 160);
path.lineTo(140, 120);
path.lineTo(110, 180);
path.close();
canvas.drawPath(path, paint);
canvas.flush();
var canvas = new CanvasImpl();
var canvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
style = PaintingStyle.stroke,
strokeWidth = 10,
};
canvas.drawLine(

canvas.drawLine(
new Offset(10, 10),
new Offset(10, 50),

new Offset(40, 10),
new Offset(90, 10),
paint);
canvas.flush();
var canvas = new CanvasImpl();
var canvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
canvas.drawRect(
Rect.fromLTWH(10, 10, 100, 100),
BorderWidth.only(2, 4, 6, 8),
BorderRadius.only(0, 4, 8, 16),
paint);
canvas.rotate(15 * Mathf.PI / 180);
var rect = Rect.fromLTWH(10, 10, 100, 100);
var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
canvas.drawRRect(rrect, paint);
canvas.drawRect(
Rect.fromLTWH(10, 150, 100, 100),
BorderWidth.only(),
BorderRadius.only(0, 4, 8, 16),
paint);
rect = Rect.fromLTWH(10, 150, 100, 100);
rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
canvas.drawRRect(rrect, paint);
canvas.drawRect(
Rect.fromLTWH(150, 150, 100, 100),
BorderWidth.only(10, 12, 14, 16),
BorderRadius.only(),
paint);
rect = Rect.fromLTWH(150, 150, 100, 100);
rrect = RRect.fromRectAndCorners(rect, 10, 12, 14, 16);
var rect1 = Rect.fromLTWH(160, 160, 80, 80);
var rrect1 = RRect.fromRectAndCorners(rect1, 5, 6, 7, 8);
canvas.drawDRRect(rrect, rrect1, paint);
canvas.flush();
var canvas = new CanvasImpl();
var paint = new Paint {
color = new Color(0xFF00FF00),
blurSigma = 3.0,
};
canvas.drawRectShadow(
Rect.fromLTWH(10, 10, 100, 100),
paint);
paint = new Paint {
color = new Color(0xFFFFFF00),
blurSigma = 2.0,
};
canvas.drawRectShadow(
Rect.fromLTWH(10, 150, 100, 100),
paint);
// var canvas = new CanvasImpl();
//
// var paint = new Paint {
// color = new Color(0xFF00FF00),
// blurSigma = 3.0,
// };
//
// canvas.drawRectShadow(
// Rect.fromLTWH(10, 10, 100, 100),
// paint);
//
// paint = new Paint {
// color = new Color(0xFFFFFF00),
// blurSigma = 2.0,
// };
//
// canvas.drawRectShadow(
// Rect.fromLTWH(10, 150, 100, 100),
// paint);
}
void drawPicture() {

color = new Color(0xFFFF0000),
};
canvas.drawPloygon4(
new[] {new Offset(10, 10), new Offset(10, 110), new Offset(90, 110), new Offset(110, 10)},
paint);
var path = new Path();
path.moveTo(10, 10);
path.lineTo(10, 110);
path.lineTo(90, 110);
path.lineTo(100, 10);
path.close();
canvas.drawPath(path, paint);
canvas.drawRect(
Rect.fromLTWH(10, 150, 100, 100),
BorderWidth.only(2, 4, 6, 8),
BorderRadius.only(0, 4, 8, 16),
paint);
var rect = Rect.fromLTWH(10, 150, 100, 100);
var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
var rect1 = Rect.fromLTWH(18, 152, 88, 92);
var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16);
canvas.concat(Matrix4x4.Translate(new Vector2(-150, -150)));
canvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -45)));
canvas.concat(Matrix4x4.Translate(new Vector2(150, 150)));
canvas.drawDRRect(rrect, rrect1, paint);
canvas.rotate(-45 * Mathf.PI / 180, new Offset(150, 150));
canvas.drawRectShadow(
canvas.drawRect(
Rect.fromLTWH(150, 150, 110, 120),
paint);

var editorCanvas = new CanvasImpl();
var editorCanvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -15)));
editorCanvas.concat(Matrix4x4.Translate(new Vector2(100, 100)));
editorCanvas.rotate(-15 * Mathf.PI / 180);
editorCanvas.translate(100, 100);
editorCanvas.flush();
}
void drawImageRect() {

var canvas = new CanvasImpl();
var canvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
color = new Color(0xFFFF0000),
color = new Color(0x7FFF0000),
_stream.completer._currentImgae.image,
Rect.fromLTWH(150, 50, 250, 250),
Rect.fromLTWH(150, 50, 250, 250),
_stream.completer._currentImgae.image.texture,
Rect.fromLTWH(100, 50, 250, 250),
canvas.flush();
}
void clipRect() {

color = new Color(0xFFFF0000),
};
canvas.drawPloygon4(
new[] {new Offset(10, 10), new Offset(10, 110), new Offset(90, 110), new Offset(110, 10)},
paint);
var path = new Path();
path.moveTo(10, 10);
path.lineTo(10, 110);
path.lineTo(90, 110);
path.lineTo(110, 10);
path.close();
canvas.drawPath(path, paint);
canvas.drawRect(
Rect.fromLTWH(10, 150, 100, 100),
BorderWidth.only(2, 4, 6, 8),
BorderRadius.only(0, 4, 8, 16),
paint);
var rect = Rect.fromLTWH(10, 150, 100, 100);
var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
var rect1 = Rect.fromLTWH(18, 152, 88, 92);
var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16);
canvas.drawDRRect(rrect, rrect1, paint);
canvas.concat(Matrix4x4.Translate(new Vector2(-150, -150)));
canvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -45)));
canvas.concat(Matrix4x4.Translate(new Vector2(150, 150)));
canvas.rotate(-45 * Mathf.PI / 180.0, new Offset(150, 150));
paint = new Paint {
color = new Color(0xFF00FFFF),
blurSigma = 3,
};
canvas.drawRectShadow(
Rect.fromLTWH(150, 150, 110, 120),
paint);
// paint = new Paint {
// color = new Color(0xFF00FFFF),
// blurSigma = 3,
// };
// canvas.drawRectShadow(
// Rect.fromLTWH(150, 150, 110, 120),
// paint);
var editorCanvas = new CanvasImpl();
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -5)));
var editorCanvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
editorCanvas.rotate(-5 * Mathf.PI / 180);
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, 5)));
editorCanvas.rotate(5 * Mathf.PI / 180);
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -15)));
editorCanvas.concat(Matrix4x4.Translate(new Vector2(100, 100)));
editorCanvas.rotate(-15 * Mathf.PI / 180);
editorCanvas.translate(100, 100);
editorCanvas.flush();
}
void clipRRect() {

color = new Color(0xFFFF0000),
};
canvas.drawPloygon4(
new[] {new Offset(10, 10), new Offset(10, 110), new Offset(90, 110), new Offset(110, 10)},
paint);
var path = new Path();
path.moveTo(10, 10);
path.lineTo(10, 110);
path.lineTo(90, 110);
path.lineTo(110, 10);
path.close();
canvas.drawPath(path, paint);
canvas.drawRect(
Rect.fromLTWH(10, 150, 100, 100),
BorderWidth.only(2, 4, 6, 8),
BorderRadius.only(0, 4, 8, 16),
paint);
var rect = Rect.fromLTWH(10, 150, 100, 100);
var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
var rect1 = Rect.fromLTWH(18, 152, 88, 92);
var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16);
canvas.drawDRRect(rrect, rrect1, paint);
canvas.concat(Matrix4x4.Translate(new Vector2(-150, -150)));
canvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -45)));
canvas.concat(Matrix4x4.Translate(new Vector2(150, 150)));
canvas.rotate(-45 * Mathf.PI / 180.0, new Offset(150, 150));
paint = new Paint {
color = new Color(0xFF00FFFF),
blurSigma = 3,
};
canvas.drawRectShadow(
Rect.fromLTWH(150, 150, 110, 120),
paint);
// paint = new Paint {
// color = new Color(0xFF00FFFF),
// blurSigma = 3,
// };
// canvas.drawRectShadow(
// Rect.fromLTWH(150, 150, 110, 120),
// paint);
var editorCanvas = new CanvasImpl();
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -5)));
var editorCanvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
editorCanvas.rotate(-5 * Mathf.PI / 180);
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, 5)));
editorCanvas.rotate(5 * Mathf.PI / 180);
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -15)));
editorCanvas.concat(Matrix4x4.Translate(new Vector2(100, 100)));
editorCanvas.rotate(-15 * Mathf.PI / 180);
editorCanvas.translate(100, 100);
editorCanvas.flush();
}
void saveLayer() {

color = new Color(0xFFFF0000),
};
canvas.drawPloygon4(
new[] {new Offset(10, 10), new Offset(10, 110), new Offset(90, 110), new Offset(110, 10)},
paint);
var path = new Path();
path.moveTo(10, 10);
path.lineTo(10, 110);
path.lineTo(90, 110);
path.lineTo(110, 10);
path.close();
canvas.drawPath(path, paint);
canvas.drawRect(
Rect.fromLTWH(10, 150, 100, 100),
BorderWidth.only(2, 4, 6, 8),
BorderRadius.only(0, 4, 8, 16),
paint);
var rect = Rect.fromLTWH(10, 150, 100, 100);
var rrect = RRect.fromRectAndCorners(rect, 0, 4, 8, 16);
var rect1 = Rect.fromLTWH(18, 152, 88, 92);
var rrect1 = RRect.fromRectAndCorners(rect1, 0, 4, 8, 16);
canvas.drawDRRect(rrect, rrect1, paint);
canvas.concat(Matrix4x4.Translate(new Vector2(-150, -150)));
canvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -45)));
canvas.concat(Matrix4x4.Translate(new Vector2(150, 150)));
canvas.rotate(-45 * Mathf.PI / 180.0, new Offset(150, 150));
canvas.clipRRect(RRect.fromRectAndRadius(Rect.fromLTWH(180, 150, 60, 120), 40));
paint = new Paint {
color = new Color(0xFF00FFFF),
blurSigma = 3,
};
canvas.drawRectShadow(
Rect.fromLTWH(150, 150, 110, 120),
paint);
// paint = new Paint {
// color = new Color(0xFF00FFFF),
// blurSigma = 3,
// };
// canvas.drawRectShadow(
// Rect.fromLTWH(150, 150, 110, 120),
// paint);
Debug.Log("picture.paintBounds: " + picture.paintBounds);
var editorCanvas = new CanvasImpl();
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -5)));
editorCanvas.clipRRect(RRect.fromRectAndRadius(Rect.fromLTWH(25, 15, 250, 250), 50));
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, 5)));
var editorCanvas = new CommandBufferCanvas(this._renderTexture, (float) Window.instance.devicePixelRatio);
editorCanvas.restore();
editorCanvas.translate(150, 0);
editorCanvas.saveLayer(picture.paintBounds, new Paint {color = new Color(0xFFFFFFFF)});
editorCanvas.drawPicture(picture);
editorCanvas.restore();
editorCanvas.concat(Matrix4x4.Rotate(Quaternion.Euler(0, 0, -15)));
editorCanvas.concat(Matrix4x4.Translate(new Vector2(100, 100)));
editorCanvas.drawPicture(picture);
editorCanvas.restore();
editorCanvas.flush();
}
}
}

16
Assets/UIWidgets/Tests/EditableTextWiget.cs


private Widget image;
[MenuItem("UIWidgetsTests/EditableTextWiget")]
[MenuItem("UIWidgetsTests/EditableTextWidget")]
public static void renderWidgets() {
EditorWindow.GetWindow(typeof(EditableTextWiget));
}

}
void OnGUI() {
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
}
this.windowAdapter.OnGUI();
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
this.windowAdapter.Update();
}
private void OnEnable() {

this.windowAdapter.OnEnable();
this.root = new widgets.Container(
width: 200,
height: 200,

)
);
this.windowAdapter.attachRootWidget(root);
this.titleContent = new GUIContent("EditableTextWiget");
this.titleContent = new GUIContent("EditableTextWidget");
void OnDestroy() {
void OnDisable() {
this.windowAdapter.OnDisable();
this.windowAdapter = null;
}
}

166
Assets/UIWidgets/Tests/Paragraph.cs


using Color = UIWidgets.ui.Color;
using FontStyle = UIWidgets.ui.FontStyle;
namespace UIWidgets.Tests
{
public class Paragraph : EditorWindow
{
namespace UIWidgets.Tests {
public class Paragraph : EditorWindow {
private readonly Func<RenderBox>[] _options;
private readonly string[] _optionStrings;

this.hasInvoked = true;
var renderBox = this._options[this._selected]();
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
this.windowAdapter.attachRootRenderBox(renderBox);
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
}
this.windowAdapter.OnGUI();
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
this.windowAdapter.Update();
this.windowAdapter.OnEnable();
void OnDestroy() {
void OnDisable() {
this.windowAdapter.OnDisable();
this.windowAdapter = null;
}

private RenderBox box(RenderParagraph p, int width = 200, int height = 200)
{
private RenderBox box(RenderParagraph p, int width = 200, int height = 200) {
minWidth: width,
maxWidth: width,
minHeight: height,
maxHeight: height,
alignment: Alignment.center,
child: p
minWidth: width,
maxWidth: width,
minHeight: height,
maxHeight: height,
alignment: Alignment.center,
child: p
private RenderBox flexItemBox(RenderParagraph p, int width = 200, int height = 150)
{
private RenderBox flexItemBox(RenderParagraph p, int width = 200, int height = 150) {
return new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: width, maxWidth: width, minHeight: height,
maxHeight: height),

)
));
}
RenderBox text()
{
RenderBox text() {
new List<TextSpan>()
{
new List<TextSpan>() {
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0)),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0)),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(125, 255, 0, 0)),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(125, 255, 0, 0)),
new TextSpan(style: new painting.TextStyle(fontWeight: FontWeight.w700),
new TextSpan(style: new painting.TextStyle(fontWeight: FontWeight.w700),
new TextSpan(style: new painting.TextStyle(fontStyle: FontStyle.italic),
new TextSpan(style: new painting.TextStyle(fontStyle: FontStyle.italic),
new TextSpan(style: new painting.TextStyle(fontStyle: FontStyle.italic, fontWeight: FontWeight.w700),
text: "This is FontStyle.italic And 发撒放豆腐sad 发生的 Bold Text This is FontStyle.italic And Bold Text\n\n"),
new TextSpan(style: new painting.TextStyle(fontSize: 18),
new TextSpan(
style: new painting.TextStyle(fontStyle: FontStyle.italic, fontWeight: FontWeight.w700),
text:
"This is FontStyle.italic And 发撒放豆腐sad 发生的 Bold Text This is FontStyle.italic And Bold Text\n\n"),
new TextSpan(style: new painting.TextStyle(fontSize: 18),
new TextSpan(style: new painting.TextStyle(fontSize: 14),
new TextSpan(style: new painting.TextStyle(fontSize: 14),
RenderBox textDecoration()
{
RenderBox textDecoration() {
new RenderParagraph(new TextSpan(style: new painting.TextStyle(height:1.2), text: "", children:
new List<TextSpan>()
{
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.underline),
new RenderParagraph(new TextSpan(style: new painting.TextStyle(height: 1.2), text: "", children:
new List<TextSpan>() {
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.underline),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.underline, decorationStyle: TextDecorationStyle.doubleLine),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.underline, decorationStyle: TextDecorationStyle.doubleLine),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.underline, fontSize: 24),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.underline, fontSize: 24),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.overline),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.overline),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.overline, decorationStyle: TextDecorationStyle.doubleLine),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.overline, decorationStyle: TextDecorationStyle.doubleLine),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.lineThrough),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.lineThrough),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.lineThrough, decorationColor:Color.fromARGB(255, 0, 255, 0)),
new TextSpan(style: new painting.TextStyle(color: Color.fromARGB(255, 255, 0, 0),
decoration: TextDecoration.lineThrough,
decorationColor: Color.fromARGB(255, 0, 255, 0)),
RenderBox textAlign()
{
RenderBox textAlign() {
var flexbox = new RenderFlex(
direction: Axis.vertical,
mainAxisAlignment: MainAxisAlignment.spaceAround,

flexbox.add(flexItemBox(
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + "Align To Left\nMaterials define how light reacts with the " +
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() +
"Align To Left\nMaterials define how light reacts with the " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.left),
"believable visuals. When you’ve created a "),
textAlign: TextAlign.left),
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + "Align To Rgit\nMaterials define how light reacts with the " +
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() +
"Align To Rgit\nMaterials define how light reacts with the " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.right),
"believable visuals. When you’ve created a "),
textAlign: TextAlign.right),
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() + "Align To Center\nMaterials define how light reacts with the " +
new RenderParagraph(new TextSpan(EditorGUIUtility.pixelsPerPoint.ToString() +
"Align To Center\nMaterials define how light reacts with the " +
"believable visuals. When you’ve created a "), textAlign: TextAlign.center),
"believable visuals. When you’ve created a "),
textAlign: TextAlign.center),
"believable visuals. When you’ve created a "), textAlign: TextAlign.justify),
height: height
"believable visuals. When you’ve created a "),
textAlign: TextAlign.justify),
height: height
return flexbox;
return flexbox;
RenderBox textOverflow()
{
RenderBox textOverflow() {
new List<TextSpan>()
{
new TextSpan("Real-time 3D revolutionizes:\n the animation pipeline.\n\n\nrevolutionizesn\n\nReal-time 3D revolutionizes the animation pipeline ", null),
new List<TextSpan>() {
new TextSpan(
"Real-time 3D revolutionizes:\n the animation pipeline.\n\n\nrevolutionizesn\n\nReal-time 3D revolutionizes the animation pipeline ",
null),
RenderBox textHeight()
{
RenderBox textHeight() {
new List<TextSpan>()
{
new TextSpan(style: new painting.TextStyle(height: 1),
new List<TextSpan>() {
new TextSpan(style: new painting.TextStyle(height: 1),
new TextSpan(style: new painting.TextStyle(height: 1.2),
new TextSpan(style: new painting.TextStyle(height: 1.2),
new TextSpan(style: new painting.TextStyle(height: 1.5),
text: "Height 1.5 Text:" + text),
new TextSpan(style: new painting.TextStyle(height: 1.5),
text: "Height 1.5 Text:" + text),
}
}

19
Assets/UIWidgets/Tests/RenderBoxes.cs


this.hasInvoked = true;
var renderBox = this._options[this._selected]();
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
}
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
this.windowAdapter.attachRootRenderBox(renderBox);
this.windowAdapter.OnGUI();
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
this.windowAdapter.Update();
this.windowAdapter.OnEnable();
void OnDestroy() {
void OnDisable() {
this.windowAdapter.OnDisable();
this.windowAdapter = null;
}

maxHeight: 100,
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFFFFFFFF),
color: new Color(0xFFFF00FF),
borderRadius: BorderRadius.all(3),
boxShadow: new List<BoxShadow> {
new BoxShadow(

16
Assets/UIWidgets/Tests/RenderEditable.cs


this.hasInvoked = true;
var renderBox = this._options[this._selected]();
if (this.windowAdapter != null) {
this.windowAdapter.attachRootRenderBox(renderBox);
}
this.windowAdapter.attachRootRenderBox(renderBox);
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
}
this.windowAdapter.OnGUI();
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
this.windowAdapter.Update();
this.windowAdapter.OnEnable();
void OnDestroy() {
void OnDisable() {
this.windowAdapter.OnDisable();
this.windowAdapter = null;
}

12
Assets/UIWidgets/Tests/Widgets.cs


this.windowAdapter.attachRootWidget(rootWidget);
}
if (this.windowAdapter != null) {
this.windowAdapter.OnGUI();
}
this.windowAdapter.OnGUI();
if (this.windowAdapter != null) {
this.windowAdapter.Update();
}
this.windowAdapter.Update();
}
private void OnEnable() {

this.windowAdapter.OnEnable();
void OnDestroy() {
void OnDisable() {
this.windowAdapter.OnDisable();
this.windowAdapter = null;
}

32
Assets/UIWidgets/async/timer.cs


using System;
using System.Collections.Generic;
static readonly TimerProvider _globalTimerProvider = new TimerProvider();
public static Timer run(TimeSpan duration, Action callback) {
return _globalTimerProvider.run(duration, callback);
}
public static Timer run(Action callback) {
return run(TimeSpan.Zero, callback);
}
internal static void update() {
_globalTimerProvider.update();
}
}
public class TimerProvider {

public Timer run(TimeSpan duration, Action callback) {
var timer = new TimerImpl(DateTime.Now + duration, callback);
this._queue.enqueue(timer);
lock (this._queue) {
this._queue.enqueue(timer);
}
return timer;
}

while (this._queue.count > 0 && this._queue.peek().deadline <= now) {
var timer = this._queue.dequeue();
var timers = new List<TimerImpl>();
lock (this._queue) {
while (this._queue.count > 0 && this._queue.peek().deadline <= now) {
var timer = this._queue.dequeue();
timers.Add(timer);
}
}
foreach (var timer in timers) {
timer.invoke();
}
}

231
Assets/UIWidgets/editor/editor_window.cs


using System.Collections.Generic;
using System.Diagnostics;
using UIWidgets.async;
using UIWidgets.flow;
using UIWidgets.foundation;
using UIWidgets.service;
using UIWidgets.rendering;
using UIWidgets.ui;

using Rect = UnityEngine.Rect;
public abstract class UIWidgetsEditorWindow : EditorWindow {
WindowAdapter _windowAdapter;
void OnEnable() {
if (this._windowAdapter == null) {
this._windowAdapter = new WindowAdapter(this);
}
this._windowAdapter.OnEnable();
var rootRenderBox = this.rootRenderBox();
if (rootRenderBox != null) {
this._windowAdapter.attachRootRenderBox(rootRenderBox);
return;
}
this._windowAdapter.attachRootWidget(this.rootWidget());
}
void OnDisable() {
this._windowAdapter.OnDisable();
}
void OnGUI() {
this._windowAdapter.OnGUI();
}
void Update() {
this._windowAdapter.Update();
}
protected virtual RenderBox rootRenderBox() {
return null;
}
protected abstract Widget rootWidget();
}
}
public readonly EditorWindow editorWindow;
this._devicePixelRatio = EditorGUIUtility.pixelsPerPoint;
WidgetsBinding _binding;
float _lastWindowWidth;
float _lastWindowHeight;
this._lastPosition = editorWindow.position;
readonly DateTime _epoch = new DateTime(Stopwatch.GetTimestamp());
readonly MicrotaskQueue _microtaskQueue = new MicrotaskQueue();
readonly TimerProvider _timerProvider = new TimerProvider();
readonly TextInput _textInput = new TextInput();
readonly Rasterizer _rasterizer = new Rasterizer();
bool _regenerateLayerTree;
Surface _surface;
public void OnEnable() {
this._devicePixelRatio = EditorGUIUtility.pixelsPerPoint;
this._lastWindowWidth = this.editorWindow.position.width;
this._lastWindowHeight = this.editorWindow.position.height;
this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
this._lastPosition.height * EditorGUIUtility.pixelsPerPoint);
this._lastWindowWidth * this._devicePixelRatio,
this._lastWindowHeight * this._devicePixelRatio);
D.assert(this._surface == null);
this._surface = new EditorWindowSurface();
this._rasterizer.setup(this._surface);
}
public void OnDisable() {
this._rasterizer.teardown();
D.assert(this._surface != null);
this._surface.Dispose();
this._surface = null;
}
public override IDisposable getScope() {
try {
if (this._binding == null) {
finally {
WidgetsBinding.instance = this._binding;
return new WindowDisposable();
}
class WindowDisposable : IDisposable {
public void Dispose() {
WidgetsBinding.instance = null;
this._rasterCache = new RasterCache();
public readonly EditorWindow editorWindow;
public void OnGUI() {
using (this.getScope()) {
bool dirty = false;
readonly WidgetsBinding _binding;
if (this._devicePixelRatio != EditorGUIUtility.pixelsPerPoint) {
dirty = true;
}
readonly RasterCache _rasterCache;
if (this._lastWindowWidth != this.editorWindow.position.width
|| this._lastWindowHeight != this.editorWindow.position.height) {
dirty = true;
}
Rect _lastPosition;
readonly DateTime _epoch = new DateTime(Stopwatch.GetTimestamp());
readonly MicrotaskQueue _microtaskQueue = new MicrotaskQueue();
readonly TimerProvider _timerProvider = new TimerProvider();
readonly TextInput _textInput = new TextInput();
if (dirty) {
this._devicePixelRatio = EditorGUIUtility.pixelsPerPoint;
this._lastWindowWidth = this.editorWindow.position.width;
this._lastWindowHeight = this.editorWindow.position.height;
this._physicalSize = new Size(
this._lastWindowWidth * this._devicePixelRatio,
this._lastWindowHeight * this._devicePixelRatio);
public void OnGUI() {
instance = this;
WidgetsBinding.instance = this._binding;
if (this.onMetricsChanged != null) {
this.onMetricsChanged();
}
}
try {
finally {
instance = null;
WidgetsBinding.instance = null;
}
void _beginFrame() {
if (this.onBeginFrame != null) {
this.onBeginFrame(new DateTime(Stopwatch.GetTimestamp()) - this._epoch);
}
this.flushMicrotasks();
if (this.onDrawFrame != null) {
this.onDrawFrame();
}
}

if (evt.type == EventType.Repaint) {
if (this.onBeginFrame != null) {
this.onBeginFrame(new DateTime(Stopwatch.GetTimestamp()) - this._epoch);
}
this.flushMicrotasks();
if (this.onDrawFrame != null) {
this.onDrawFrame();
if (this._regenerateLayerTree) {
this._regenerateLayerTree = false;
this._beginFrame();
} else {
this._rasterizer.drawLastLayerTree();
}
return;

}
public void Update() {
Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
Timer.update();
using (this.getScope()) {
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
}
bool dirty = false;
if (this._devicePixelRatio != EditorGUIUtility.pixelsPerPoint) {
dirty = true;
public override void scheduleFrame(bool regenerateLayerTree = true) {
if (regenerateLayerTree) {
this._regenerateLayerTree = true;
if (this._lastPosition != this.editorWindow.position) {
dirty = true;
}
if (dirty) {
this._devicePixelRatio = EditorGUIUtility.pixelsPerPoint;
this._lastPosition = this.editorWindow.position;
this._physicalSize = new Size(
this._lastPosition.width * EditorGUIUtility.pixelsPerPoint,
this._lastPosition.height * EditorGUIUtility.pixelsPerPoint);
if (this.onMetricsChanged != null) {
this.onMetricsChanged();
}
}
}
public override void scheduleFrame() {
if (this.editorWindow != null) {
this.editorWindow.Repaint();
}

var layer = scene.takeLayer();
var layerTree = scene.takeLayerTree();
if (layerTree == null) {
return;
}
var prerollContext = new PrerollContext {
rasterCache = this._rasterCache
};
layer.preroll(prerollContext, Matrix4x4.identity);
if (this._physicalSize.isEmpty) {
return;
}
var paintContext = new PaintContext {
canvas = new CanvasImpl()
};
layer.paint(paintContext);
this._rasterCache.sweepAfterFrame();
layerTree.frameSize = this._physicalSize;
layerTree.devicePixelRatio = this._devicePixelRatio;
this._rasterizer.draw(layerTree);
}
public override void scheduleMicrotask(Action callback) {

}
public void attachRootRenderBox(RenderBox root) {
Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
using (this.getScope()) {
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
Window.instance = this;
WidgetsBinding.instance = this._binding;
try {
using (this.getScope()) {
}
finally {
Window.instance = null;
WidgetsBinding.instance = null;
}
}

9
Assets/UIWidgets/flow/clip_rect_layer.cs


using UIWidgets.ui;
using UnityEngine;
using Color = UIWidgets.ui.Color;
namespace UIWidgets.flow {
public class ClipRectLayer : ContainerLayer {

set { this._clipRect = value; }
}
public override void preroll(PrerollContext context, Matrix4x4 matrix) {
public override void preroll(PrerollContext context, Matrix3 matrix) {
var childPaintBounds = Rect.zero;
this.prerollChildren(context, matrix, ref childPaintBounds);
childPaintBounds = childPaintBounds.intersect(this._clipRect);

public override void paint(PaintContext context) {
var canvas = context.canvas;
var paint = new Paint {color = new Color(0xFFFFFFFF)};
canvas.saveLayer(this.paintBounds, paint);
canvas.save();
canvas.clipRect(this.paintBounds);
try {
this.paintChildren(context);
}

6
Assets/UIWidgets/flow/clip_rrect_layer.cs


set { this._clipRRect = value; }
}
public override void preroll(PrerollContext context, Matrix4x4 matrix) {
public override void preroll(PrerollContext context, Matrix3 matrix) {
var childPaintBounds = Rect.zero;
this.prerollChildren(context, matrix, ref childPaintBounds);
childPaintBounds = childPaintBounds.intersect(this._clipRRect.outerRect);

canvas.save();
canvas.clipRRect(this._clipRRect);
var paint = new Paint {color = new Color(0xFFFFFFFF)};
canvas.saveLayer(this.paintBounds, paint);
canvas.restore();
canvas.restore();
}
}

4
Assets/UIWidgets/flow/container_layer.cs


this._layers.Add(layer);
}
public override void preroll(PrerollContext context, Matrix4x4 matrix) {
public override void preroll(PrerollContext context, Matrix3 matrix) {
protected void prerollChildren(PrerollContext context, Matrix4x4 childMatrix, ref Rect childPaintBounds) {
protected void prerollChildren(PrerollContext context, Matrix3 childMatrix, ref Rect childPaintBounds) {
foreach (var layer in this._layers) {
layer.preroll(context, childMatrix);
childPaintBounds = childPaintBounds.expandToInclude(layer.paintBounds);

6
Assets/UIWidgets/flow/layer.cs


using UnityEngine;
using UIWidgets.ui;
using UnityEngine;
using Rect = UIWidgets.ui.Rect;
using Canvas = UIWidgets.ui.Canvas;

public float devicePixelRatio;
}
public class PaintContext {

get { return !this._paintBounds.isEmpty; }
}
public virtual void preroll(PrerollContext context, Matrix4x4 matrix) {
public virtual void preroll(PrerollContext context, Matrix3 matrix) {
}
public abstract void paint(PaintContext context);

23
Assets/UIWidgets/flow/picture_layer.cs


private RasterCacheResult _rasterCacheResult;
public override void preroll(PrerollContext context, Matrix4x4 matrix) {
public override void preroll(PrerollContext context, Matrix3 matrix) {
Matrix4x4 ctm = matrix;
ctm = Matrix4x4.Translate(this._offset.toVector()) * ctm;
ctm.m03 = Mathf.Round(ctm.m03);
ctm.m13 = Mathf.Round(ctm.m13);
Matrix3 ctm = Matrix3.makeTrans((float) this._offset.dx, (float) this._offset.dy);
ctm.preConcat(matrix);
ctm[6] = ctm[6].alignToPixel(context.devicePixelRatio);
ctm[7] = ctm[7].alignToPixel(context.devicePixelRatio);
this._picture, ref ctm, this._isComplex, this._willChange);
this._picture, ctm, context.devicePixelRatio, this._isComplex, this._willChange);
} else {
this._rasterCacheResult = null;
}

var canvas = context.canvas;
canvas.save();
canvas.concat(Matrix4x4.Translate(this._offset.toVector()));
var matrix = canvas.getMatrix();
matrix.m03 = Mathf.Round(matrix.m03);
matrix.m13 = Mathf.Round(matrix.m13);
canvas.translate(this._offset.dx, this._offset.dy);
// align to pixel
var matrix = canvas.getTotalMatrix();
var devicePixelRatio = context.canvas.getDevicePixelRatio();
matrix[6] = matrix[6].alignToPixel(devicePixelRatio);
matrix[7] = matrix[7].alignToPixel(devicePixelRatio);
canvas.setMatrix(matrix);
try {

134
Assets/UIWidgets/flow/raster_cache.cs


using System;
using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.painting;
using UnityEditor;
using Object = UnityEngine.Object;
public RasterCacheResult(Image image, Rect bounds) {
D.assert(image != null);
D.assert(bounds != null);
public RasterCacheResult(Texture texture, Rect logicalRect, float devicePixelRatio) {
D.assert(texture != null);
D.assert(logicalRect != null);
this.image = image;
this.bounds = bounds;
this.texture = texture;
this.logicalRect = logicalRect;
this.devicePixelRatio = devicePixelRatio;
public readonly Image image;
public readonly Texture texture;
public readonly Rect bounds;
public readonly Rect logicalRect;
public readonly float devicePixelRatio;
var bounds = canvas.getMatrix().transformRect(this.bounds).roundOut();
var bounds = canvas.getTotalMatrix().mapRect(this.logicalRect);
var textureWidth = (int) Math.Ceiling(
bounds.width * EditorGUIUtility.pixelsPerPoint); // todo: use window.pixelsPerPoint;
var textureHeight = (int) Math.Ceiling(
bounds.height * EditorGUIUtility.pixelsPerPoint);
var textureWidth = Mathf.CeilToInt((float) bounds.width * this.devicePixelRatio);
var textureHeight = Mathf.CeilToInt((float) bounds.height * this.devicePixelRatio);
D.assert(this.image.width == textureWidth);
D.assert(this.image.height == textureHeight);
D.assert(this.texture.width == textureWidth);
D.assert(this.texture.height == textureHeight);
canvas.setMatrix(Matrix4x4.identity);
canvas.drawImageRect(this.image, bounds);
canvas.resetMatrix();
canvas.drawImage(this.texture, bounds.topLeft, new Paint());
}
finally {
canvas.restore();

class _RasterCacheKey : IEquatable<_RasterCacheKey> {
internal _RasterCacheKey(Picture picture, ref Matrix4x4 matrix) {
internal _RasterCacheKey(Picture picture, Matrix3 matrix, float devicePixelRatio) {
D.assert(matrix != null);
this.matrix = matrix;
this.matrix.m03 = this.matrix.m03 - (int) this.matrix.m03; // x
this.matrix.m13 = this.matrix.m13 - (int) this.matrix.m13; // y
D.assert(this.matrix.m03 == 0);
D.assert(this.matrix.m13 == 0);
this.matrix = new Matrix3(matrix);
var x = this.matrix[6] * devicePixelRatio;
var y = this.matrix[7] * devicePixelRatio;
this.matrix[6] = (x - (int) x) / devicePixelRatio; // x
this.matrix[7] = (y - (int) y) / devicePixelRatio; // y
D.assert(this.matrix[6] == 0);
D.assert(this.matrix[7] == 0);
this.devicePixelRatio = devicePixelRatio;
public readonly Matrix4x4 matrix;
public readonly Matrix3 matrix;
public readonly float devicePixelRatio;
return this.picture.Equals(other.picture) && this.matrix.Equals(other.matrix);
return Equals(this.picture, other.picture) &&
Equals(this.matrix, other.matrix) &&
this.devicePixelRatio.Equals(other.devicePixelRatio);
}
public override bool Equals(object obj) {

public override int GetHashCode() {
unchecked {
return (this.picture.GetHashCode() * 397) ^ this.matrix.GetHashCode();
var hashCode = (this.picture != null ? this.picture.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.matrix != null ? this.matrix.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.devicePixelRatio.GetHashCode();
return hashCode;
}
}

readonly Dictionary<_RasterCacheKey, _RasterCacheEntry> _cache;
public RasterCacheResult getPrerolledImage(
Picture picture, ref Matrix4x4 transform, bool isComplex, bool willChange) {
Picture picture, Matrix3 transform, float devicePixelRatio, bool isComplex, bool willChange) {
if (this.threshold == 0) {
return null;
}

}
if (transform.m33 == 0 || transform.determinant == 0) {
if (!transform.invert(null)) {
_RasterCacheKey cacheKey = new _RasterCacheKey(picture, ref transform);
_RasterCacheKey cacheKey = new _RasterCacheKey(picture, transform, devicePixelRatio);
var entry = this._cache.putIfAbsent(cacheKey, () => new _RasterCacheEntry());

}
if (entry.image == null) {
entry.image = this._rasterizePicture(picture, ref transform);
entry.image = this._rasterizePicture(picture, transform, devicePixelRatio);
}
return entry.image;

return true;
}
RasterCacheResult _rasterizePicture(Picture picture, ref Matrix4x4 transform) {
var bounds = transform.transformRect(picture.paintBounds).roundOut();
RasterCacheResult _rasterizePicture(Picture picture, Matrix3 transform, float devicePixelRatio) {
var bounds = transform.mapRect(picture.paintBounds);
var textureWidth = (int) Math.Ceiling(
bounds.width * EditorGUIUtility.pixelsPerPoint); // todo: use window.pixelsPerPoint;
var textureHeight = (int) Math.Ceiling(
bounds.height * EditorGUIUtility.pixelsPerPoint);
var desc = new RenderTextureDescriptor(
Mathf.CeilToInt((float) (bounds.width * devicePixelRatio)),
Mathf.CeilToInt((float) (bounds.height * devicePixelRatio)),
RenderTextureFormat.Default, 24) {
msaaSamples = QualitySettings.antiAliasing,
useMipMap = false,
autoGenerateMips = false,
};
var texture = RenderTexture.GetTemporary(
textureWidth, textureHeight, 32,
RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);
var renderTexture = new RenderTexture(desc);
var canvas = new CommandBufferCanvas(renderTexture, devicePixelRatio);
canvas.translate((float) -bounds.left, (float) -bounds.top);
canvas.concat(transform);
canvas.drawPicture(picture);
canvas.flush();
var oldTexture = RenderTexture.active;
RenderTexture.active = texture;
GL.PushMatrix();
GL.LoadPixelMatrix((float) bounds.left, (float) bounds.right, (float) bounds.bottom, (float) bounds.top);
GL.Clear(true, true, new UnityEngine.Color(0, 0, 0, 0));
try {
var canvas = new CanvasImpl();
canvas.concat(transform);
canvas.drawPicture(picture);
Texture2D tex = new Texture2D(textureWidth, textureHeight, TextureFormat.ARGB32, false);
tex.ReadPixels(new UnityEngine.Rect(0, 0, textureWidth, textureHeight), 0, 0, false);
tex.Apply();
return new RasterCacheResult(new Image(texture: tex), picture.paintBounds);
}
finally {
GL.PopMatrix();
RenderTexture.active = oldTexture;
RenderTexture.ReleaseTemporary(texture);
}
return new RasterCacheResult(renderTexture, bounds, devicePixelRatio);
}
public void sweepAfterFrame() {

foreach (var entry in dead) {
this._cache.Remove(entry.Key);
if (entry.Value.image != null) {
Object.DestroyImmediate(entry.Value.image.texture);
}
foreach (var entry in this._cache) {
if (entry.Value.image != null) {
Object.DestroyImmediate(entry.Value.image.texture);
}
}
this._cache.Clear();
}
}

14
Assets/UIWidgets/flow/transform_layer.cs


using UIWidgets.painting;
using UIWidgets.ui;
using Matrix4x4 = UnityEngine.Matrix4x4;
using UIWidgets.ui;
private Matrix4x4 _tranform;
private Matrix3 _tranform;
public Matrix4x4 transform {
public Matrix3 transform {
public override void preroll(PrerollContext context, Matrix4x4 matrix) {
var childMatrix = this._tranform * matrix;
public override void preroll(PrerollContext context, Matrix3 matrix) {
var childMatrix = Matrix3.concat(this._tranform, matrix);
childPaintBounds = this._tranform.transformRect(childPaintBounds);
childPaintBounds = this._tranform.mapRect(childPaintBounds);
this.paintBounds = childPaintBounds;
}

2
Assets/UIWidgets/foundation/debug.cs


new Color(0xFF0090FF));
Paint paint = new Paint();
paint.color = new Color(0x90909090);
canvas.drawRect(outerRect, BorderWidth.zero, BorderRadius.zero, paint);
// canvas.drawRect(outerRect, BorderWidth.zero, BorderRadius.zero, paint);
}
return true;

5
Assets/UIWidgets/lib/cache_manager/cache_manager.cs


using UnityEngine;
using System.Net;
using Mono.Data.Sqlite;
using UIWidgets.async;
using UIWidgets.painting;
namespace UIWidgets.lib.cache_manager {

stream.Close();
localStream.Close();
promise.Resolve(meta);
Timer.run(() => { promise.Resolve(meta); });
promise.Resolve(meta);
Timer.run(() => { promise.Resolve(meta); });
}
}, null);
}

11
Assets/UIWidgets/painting/border_radius.cs


using System;
using UIWidgets.ui;
namespace UIWidgets.painting {
public class BorderRadius : IEquatable<BorderRadius> {

public readonly double bottomRight;
public readonly double bottomLeft;
public RRect toRRect(Rect rect) {
return RRect.fromRectAndCorners(
rect,
topLeft: this.topLeft,
topRight: this.topRight,
bottomLeft: this.bottomLeft,
bottomRight: this.bottomRight
);
}
public bool Equals(BorderRadius other) {
if (object.ReferenceEquals(null, other)) return false;
if (object.ReferenceEquals(this, other)) return true;

148
Assets/UIWidgets/painting/box_border.cs


}
}
public bool isSameWidth {
get {
var topWidth = this.top.width;
return this.right.width == topWidth
&& this.bottom.width == topWidth
&& this.left.width == topWidth;
}
}
public Border add(Border other) {
if (BorderSide.canMerge(this.top, other.top) &&
BorderSide.canMerge(this.right, other.right) &&

}
public void paint(Canvas canvas, Rect rect, BorderRadius borderRadius = null) {
var paint = new Paint();
if (this.isSameColor && this.isSameWidth) {
if (borderRadius == null) {
var width = this.top.width;
var paint = new Paint {
color = this.top.color,
strokeWidth = width,
style = PaintingStyle.stroke
};
canvas.drawRect(rect.deflate(width / 2), paint);
return;
}
if (this.isSameColor) {
paint.color = this.top.color;
var outer = borderRadius.toRRect(rect);
if (this.top.width == 0) {
var paint = new Paint {
color = this.top.color,
style = PaintingStyle.stroke
};
canvas.drawRect(rect,
BorderWidth.only(this.top.width, this.right.width, this.bottom.width, this.left.width),
borderRadius, paint);
canvas.drawRRect(outer, paint);
return;
}
{
var inner = outer.deflate(this.top.width);
var paint = new Paint {
color = this.top.color,
};
canvas.drawDRRect(outer, inner, paint);
}
if (borderRadius != null) {
canvas.save();
canvas.clipRRect(RRect.fromRectAndCorners(rect,
borderRadius.topLeft, borderRadius.topRight,
borderRadius.bottomRight, borderRadius.bottomLeft));
}
D.assert(borderRadius == null, "A borderRadius can only be given for uniform borders.");
if (this.top.width > 0) {
paint.color = this.top.color;
var points = new Offset[] {
new Offset(rect.left, rect.top),
new Offset(rect.right, rect.top),
new Offset(rect.right - this.right.width, rect.top + this.top.width),
new Offset(rect.left + this.right.width, rect.top + this.top.width),
};
canvas.drawPloygon4(points, paint);
}
if (this.right.width > 0) {
paint.color = this.right.color;
var points = new Offset[] {
new Offset(rect.right, rect.top),
new Offset(rect.right, rect.bottom),
new Offset(rect.right - this.right.width, rect.bottom - this.bottom.width),
new Offset(rect.right - this.right.width, rect.top + this.top.width),
{
var paint = new Paint {
color = this.top.color,
canvas.drawPloygon4(points, paint);
var path = new Path();
path.moveTo(rect.left, rect.top);
path.lineTo(rect.right, rect.top);
if (this.top.width == 0) {
paint.style = PaintingStyle.stroke;
} else {
path.lineTo(rect.right - this.right.width, rect.top + this.top.width);
path.lineTo(rect.left + this.right.width, rect.top + this.top.width);
}
canvas.drawPath(path, paint);
if (this.bottom.width > 0) {
paint.color = this.bottom.color;
var points = new Offset[] {
new Offset(rect.right, rect.bottom),
new Offset(rect.left, rect.bottom),
new Offset(rect.left + this.left.width, rect.bottom - this.bottom.width),
new Offset(rect.right - this.right.width, rect.bottom - this.bottom.width),
{
var paint = new Paint {
color = this.right.color,
canvas.drawPloygon4(points, paint);
var path = new Path();
path.moveTo(rect.right, rect.top);
path.lineTo(rect.right, rect.bottom);
if (this.right.width == 0) {
paint.style = PaintingStyle.stroke;
} else {
path.lineTo(rect.right - this.right.width, rect.bottom - this.bottom.width);
path.lineTo(rect.right - this.right.width, rect.top + this.top.width);
}
canvas.drawPath(path, paint);
if (this.left.width > 0) {
paint.color = this.left.color;
var points = new Offset[] {
new Offset(rect.left, rect.bottom),
new Offset(rect.left, rect.top),
new Offset(rect.left + this.left.width, rect.top + this.top.width),
new Offset(rect.left + this.left.width, rect.bottom - this.bottom.width),
{
var paint = new Paint {
color = this.bottom.color,
canvas.drawPloygon4(points, paint);
var path = new Path();
path.moveTo(rect.right, rect.bottom);
path.lineTo(rect.left, rect.bottom);
if (this.bottom.width == 0) {
paint.style = PaintingStyle.stroke;
} else {
path.lineTo(rect.left + this.left.width, rect.bottom - this.bottom.width);
path.lineTo(rect.right - this.right.width, rect.bottom - this.bottom.width);
}
canvas.drawPath(path, paint);
if (borderRadius != null) {
canvas.restore();
{
var paint = new Paint {
color = this.left.color,
};
var path = new Path();
path.moveTo(rect.left, rect.bottom);
path.lineTo(rect.left, rect.top);
if (this.left.width == 0) {
paint.style = PaintingStyle.stroke;
} else {
path.lineTo(rect.left + this.left.width, rect.top + this.top.width);
path.lineTo(rect.left + this.left.width, rect.bottom - this.bottom.width);
}
canvas.drawPath(path, paint);
}
}

11
Assets/UIWidgets/painting/box_decoration.cs


public Paint _getBackgroundPaint(Rect rect) {
if (this._cachedBackgroundPaint == null) {
var paint = new Paint();
if (this._decoration.color != null) {
paint.color = this._decoration.color;
}

}
public void _paintBox(Canvas canvas, Rect rect, Paint paint) {
canvas.drawRect(rect, null, this._decoration.borderRadius, paint);
if (this._decoration.borderRadius == null) {
canvas.drawRect(rect, paint);
} else {
canvas.drawRRect(this._decoration.borderRadius.toRRect(rect), paint);
}
}
public void _paintShadows(Canvas canvas, Rect rect) {

foreach (BoxShadow boxShadow in this._decoration.boxShadow) {
Paint paint = boxShadow.toPaint();
Rect bounds = rect.shift(boxShadow.offset).inflate(boxShadow.spreadRadius);
canvas.drawRectShadow(bounds, paint);
// canvas.drawRectShadow(bounds, paint);
}
}

canvas.drawRect(rect, null, this._decoration.borderRadius, paint);
this._paintBox(canvas, rect, paint);
}
}

2
Assets/UIWidgets/painting/box_shadow.cs


public Paint toPaint() {
return new Paint {
color = this.color,
blurSigma = this.blurSigma
//blurSigma = this.blurSigma
};
}

4
Assets/UIWidgets/painting/clip.cs


}
public void clipRRectAndPaint(RRect rrect, Clip clipBehavior, Rect bounds, Action painter) {
this._clipAndPaint(doAntiAias => this.canvas.clipRRect(rrect, doAntiAlias: doAntiAias),
this._clipAndPaint(doAntiAias => this.canvas.clipRRect(rrect),
this._clipAndPaint(doAntiAias => this.canvas.clipRect(rect, doAntiAlias: doAntiAias),
this._clipAndPaint(doAntiAias => this.canvas.clipRect(rect),
clipBehavior, bounds, painter);
}
}

2
Assets/UIWidgets/painting/decoration_image.cs


fittedSizes.source, Offset.zero & inputSize
);
foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) {
canvas.drawImageRect(image, tileRect, sourceRect, paint);
//canvas.drawImageRect(image, tileRect, sourceRect, paint);
}
}
else {

9
Assets/UIWidgets/promise/Promise.cs


using System.Collections.Generic;
using System.Linq;
using RSG.Exceptions;
using UIWidgets.ui;
namespace RSG
{

{
if (CurState == PromiseState.Resolved)
{
Window.instance.scheduleMicrotask(() => {
InvokeHandler(resolveHandler, resultPromise, resolveValue);
});
InvokeHandler(resolveHandler, resultPromise, resolveValue);
Window.instance.scheduleMicrotask(() => {
InvokeHandler(rejectHandler, resultPromise, rejectionException);
});
InvokeHandler(rejectHandler, resultPromise, rejectionException);
}
else
{

9
Assets/UIWidgets/promise/Promise_NonGeneric.cs


using System.Collections.Generic;
using System.Linq;
using RSG.Exceptions;
using UIWidgets.ui;
namespace RSG
{

PendingPromises.Remove(this);
}
Window.instance.scheduleMicrotask(() => {
InvokeRejectHandlers(ex);
});
InvokeRejectHandlers(ex);
}

PendingPromises.Remove(this);
}
Window.instance.scheduleMicrotask(() => {
InvokeResolveHandlers();
});
InvokeResolveHandlers();
}

6
Assets/UIWidgets/rendering/box.cs


color = new Color(0xFF00FFFF),
};
context.canvas.drawRect((offset & this.size).deflate(0.5),
BorderWidth.all(1), BorderRadius.zero, paint);
// context.canvas.drawRect((offset & this.size).deflate(0.5),
// BorderWidth.all(1), BorderRadius.zero, paint);
return true;
});
}

var paint = new Paint {
color = new Color(0x00BBBB | ((0x04000000 * this.depth) & 0xFF000000)),
};
context.canvas.drawRect(offset & this.size, BorderWidth.zero, BorderRadius.zero, paint);
// context.canvas.drawRect(offset & this.size, BorderWidth.zero, BorderRadius.zero, paint);
}
return true;

4
Assets/UIWidgets/rendering/editable.cs


var caretOffset = _textPainter.getOffsetForCaret(_selection.extendPos, _caretPrototype);
var paint = new Paint() {color = _cursorColor};
var caretRec = _caretPrototype.shift(caretOffset + effectiveOffset);
canvas.drawRect(caretRec, BorderWidth.zero, BorderRadius.zero, paint);
canvas.drawRect(caretRec, paint);
if (!caretRec.Equals(_lastCaretRect))
{
_lastCaretRect = caretRec;

foreach (var box in _selectionRects)
{
canvas.drawRect(box.toRect().shift(effectiveOffset), BorderWidth.zero, BorderRadius.zero, paint);
canvas.drawRect(box.toRect().shift(effectiveOffset), paint);
}
}

6
Assets/UIWidgets/rendering/layer.cs


public override void addToScene(SceneBuilder builder, Offset layerOffset) {
builder.addPicture(layerOffset, this.picture,
isComplexHint: this.isComplexHint, willChangeHint: this.willChangeHint);
isComplex: this.isComplexHint, willChange: this.willChangeHint);
}
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) {

});
if (enabled) {
builder.pushClipRect(this.clipRect.shift(layerOffset), clipBehavior: this.clipBehavior);
builder.pushClipRect(this.clipRect.shift(layerOffset));
}
this.addChildrenToScene(builder, layerOffset);

});
if (enabled) {
builder.pushClipRRect(this.clipRRect.shift(layerOffset), clipBehavior: this.clipBehavior);
builder.pushClipRRect(this.clipRRect.shift(layerOffset));
}
this.addChildrenToScene(builder, layerOffset);

2
Assets/UIWidgets/rendering/object.cs


);
} else {
this.canvas.save();
this.canvas.concat(effectiveTransform);
this.canvas.concat(effectiveTransform.toMatrix3());
painter(this, offset);
this.canvas.restore();
}

2
Assets/UIWidgets/rendering/proxy_box.cs


var paint = new Paint {
color = new Color(0x90909090)
};
context.canvas.drawRect(offset & this.size, BorderWidth.zero, BorderRadius.zero, paint);
// context.canvas.drawRect(offset & this.size, BorderWidth.zero, BorderRadius.zero, paint);
}
return true;

6
Assets/UIWidgets/rendering/view.cs


public void compositeFrame() {
var builder = new SceneBuilder();
this.layer.addToScene(builder, Offset.zero);
var scene = builder.build();
Window.instance.render(scene);
scene.dispose();
using (var scene = builder.build()) {
Window.instance.render(scene);
}
D.assert(() => {
// if (D.debugRepaintRainbowEnabled || D.debugRepaintTextRainbowEnabled) {

4
Assets/UIWidgets/rendering/viewport.cs


}
D.assert(size != null);
canvas.drawRect(((offset + this.paintOffsetOf(child)) & size).deflate(0.5),
BorderWidth.all(1), BorderRadius.zero, paint);
// canvas.drawRect(((offset + this.paintOffsetOf(child)) & size).deflate(0.5),
// BorderWidth.all(1), BorderRadius.zero, paint);
child = this.childAfter(child);
}

2
Assets/UIWidgets/scheduler/binding.cs


}
static SchedulerBinding _instance;
public SchedulerBinding() {
Window.instance.onBeginFrame += this._handleBeginFrame;
Window.instance.onDrawFrame += this._handleDrawFrame;

80
Assets/UIWidgets/ui/compositing.cs


namespace UIWidgets.ui {
public class SceneBuilder {
private readonly LayerBuilder _layerBuilder = new LayerBuilder();
private ContainerLayer _rootLayer;
private ContainerLayer _currentLayer;
public SceneBuilder() {
}
public Scene build() {
return new Scene(this._rootLayer);
}
private void _pushLayer(ContainerLayer layer) {
if (this._rootLayer == null) {
this._rootLayer = layer;
this._currentLayer = layer;
return;
}
if (this._currentLayer == null) {
return;
}
this._currentLayer.add(layer);
this._currentLayer = layer;
}
this._layerBuilder.pushTransform(matrix);
var layer = new TransformLayer();
layer.transform = matrix.toMatrix3();
this._pushLayer(layer);
public void pushClipRect(Rect rect, Clip clipBehavior = Clip.hardEdge) {
this._layerBuilder.pushClipRect(rect);
public void pushClipRect(Rect clipRect) {
var layer = new ClipRectLayer();
layer.clipRect = clipRect;
this._pushLayer(layer);
public void pushClipRRect(RRect rrect, Clip clipBehavior = Clip.antiAlias) {
this._layerBuilder.pushClipRRect(rrect);
public void pushClipRRect(RRect clipRRect) {
var layer = new ClipRRectLayer();
layer.clipRRect = clipRRect;
this._pushLayer(layer);
this._layerBuilder.pushOpacity(alpha);
var layer = new OpacityLayer();
layer.alpha = alpha;
this._pushLayer(layer);
this._layerBuilder.pop();
if (this._currentLayer == null) {
return;
}
this._currentLayer = this._currentLayer.parent;
bool isComplexHint = false, bool willChangeHint = false) {
this._layerBuilder.addPicture(offset, picture, isComplexHint, willChangeHint);
}
bool isComplex = false, bool willChange = false) {
if (this._currentLayer == null) {
return;
}
public Scene build() {
return new Scene(this._layerBuilder.takeLayer());
var layer = new PictureLayer();
layer.offset = offset;
layer.picture = picture;
layer.isComplex = isComplex;
layer.willChange = willChange;
this._currentLayer.add(layer);
public class Scene {
public class Scene : IDisposable {
this._layerTree = new LayerTree();
this._layerTree.rootLayer = rootLayer;
private readonly Layer _rootLayer;
readonly Layer _rootLayer;
public Layer takeLayer() {
return this._rootLayer;
readonly LayerTree _layerTree;
public LayerTree takeLayerTree() {
return this._layerTree;
public void dispose() {
public void Dispose() {
}
}
}

190
Assets/UIWidgets/ui/geometry.cs


return value;
}
public static float clamp(this float value, float min, float max) {
if (value < min) {
value = min;
} else if (value > max) {
value = max;
}
return value;
}
public static int clamp(this int value, int min, int max) {
if (value < min) {
value = min;

public static bool isNaN(this double it) {
return double.IsNaN(it);
}
public static double lerpDouble(double a, double b, double t) {
return a + (b - a) * t;
}

this.bottom + translateY);
}
public Rect scale(double scaleX, double? scaleY = null) {
scaleY = scaleY ?? scaleX;
return Rect.fromLTRB(
this.left * scaleX, this.top * scaleY.Value,
this.right * scaleX, this.bottom * scaleY.Value);
}
public Rect inflate(double delta) {
return Rect.fromLTRB(this.left - delta, this.top - delta, this.right + delta, this.bottom + delta);
}

return this.contains(rect.topLeft) && this.contains(rect.bottomRight);
}
public Rect round() {
return Rect.fromLTRB(
Math.Round(this.left), Math.Round(this.top),
Math.Round(this.right), Math.Round(this.bottom));
}
Math.Ceiling(this.right), Math.Ceiling(this.bottom));
Math.Ceiling(this.right), Math.Ceiling(this.bottom));
}
public static Rect lerp(Rect a, Rect b, double t) {

return "Rect.fromLTRB(" + this.left.ToString("0.0") + ", " + this.top.ToString("0.0") + ", " +
this.right.ToString("0.0") + ", " + this.bottom.ToString("0.0") + ")";
}
public static bool operator ==(Rect left, Rect right) {
return object.Equals(left, right);
}
public static bool operator !=(Rect left, Rect right) {
return !object.Equals(left, right);
}
public class Radius : IEquatable<Radius> {
private Radius(double x, double y) {
this.x = x;
this.y = y;
}
public static Radius circular(double radius) {
return elliptical(radius, radius);
}
public static Radius elliptical(double x, double y) {
return new Radius(x, y);
}
public readonly double x;
public readonly double y;
public static readonly Radius zero = Radius.circular(0.0);
public static Radius operator -(Radius a) {
return elliptical(-a.x, -a.y);
}
public static Radius operator -(Radius a, Radius b) {
return elliptical(a.x - b.x, a.y - b.y);
}
public static Radius operator +(Radius a, Radius b) {
return elliptical(a.x + b.x, a.y + b.y);
}
public static Radius operator *(Radius a, Radius b) {
return elliptical(a.x * b.x, a.y * b.y);
}
public static Radius operator /(Radius a, Radius b) {
return elliptical(a.x / b.x, a.y / b.y);
}
public static Radius operator %(Radius a, Radius b) {
return elliptical(a.x % b.x, a.y % b.y);
}
public static Radius lerp(Radius a, Radius b, double t) {
if (a == null && b == null) {
return null;
}
if (a == null) {
return elliptical(b.x * t, b.y * t);
}
if (b == null) {
double k = 1.0 - t;
return elliptical(a.x * k, a.y * k);
}
return elliptical(
MathUtils.lerpDouble(a.x, b.x, t),
MathUtils.lerpDouble(a.y, b.y, t)
);
}
public bool Equals(Radius other) {
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return this.x.Equals(other.x) && this.y.Equals(other.y);
}
public override bool Equals(object obj) {
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return this.Equals((Radius) obj);
}
public override int GetHashCode() {
unchecked {
return (this.x.GetHashCode() * 397) ^ this.y.GetHashCode();
}
}
public static bool operator ==(Radius left, Radius right) {
return Equals(left, right);
}
public static bool operator !=(Radius left, Radius right) {
return !Equals(left, right);
}
public override string ToString() {
return this.x == this.y
? string.Format("Radius.circular({0:F1})", this.x)
: string.Format("Radius.elliptical({0:F1}, ${1:F1})", this.x, this.y);
}
}
public class RRect : IEquatable<RRect> {
private RRect(double left, double top, double right, double bottom,

public static RRect fromLTRBAndRadius(
double left, double top, double right, double bottom,
double radius) {
double radius = 0) {
}
public static RRect fromRect(Rect rect) {
return new RRect(rect.left, rect.top, rect.right, rect.bottom,
0, 0, 0, 0);
}
public static RRect fromRectAndRadius(Rect rect, double radius) {

public Offset center {
get { return new Offset(this.left + this.width / 2.0, this.top + this.height / 2.0); }
}
public bool contains(Rect rect) {
if (!this.outerRect.contains(rect)) {
return false;
}
if (this.isRect) {
return true;
}
return this.checkCornerContainment(rect.left, rect.top) &&
this.checkCornerContainment(rect.right, rect.top) &&
this.checkCornerContainment(rect.right, rect.bottom) &&
this.checkCornerContainment(rect.left, rect.bottom);
}
bool checkCornerContainment(double x, double y) {
double radius;
if (x < this.left + this.tlRadius &&
y < this.top + this.tlRadius) {
x -= this.left + this.tlRadius;
y -= this.top + this.tlRadius;
radius = this.tlRadius;
} else if (x < this.left + this.blRadius &&
y > this.bottom - this.blRadius) {
x -= this.left + this.blRadius;
y -= this.bottom - this.blRadius;
radius = this.blRadius;
} else if (x > this.right - this.trRadius &&
y < this.top + this.trRadius) {
x -= this.right - this.trRadius;
y -= this.bottom - this.blRadius;
radius = this.trRadius;
} else if (x > this.right - this.brRadius &&
y > this.bottom - this.brRadius) {
x -= this.right - this.brRadius;
y -= this.bottom - this.brRadius;
radius = this.brRadius;
} else {
return true;
}
// A point is in an ellipse (in standard position) if:
// x^2 y^2
// ----- + ----- <= 1
// a^2 b^2
// or :
// b^2*x^2 + a^2*y^2 <= (ab)^2
return x * x + y * y <= radius * radius;
}
public bool Equals(RRect other) {

305
Assets/UIWidgets/ui/painting/canvas.cs


using System;
using UIWidgets.foundation;
using UIWidgets.painting;
void drawPloygon4(Offset[] points, Paint paint = null);
void save();
void saveLayer(Rect bounds, Paint paint = null);
void restore();
int getSaveCount();
void translate(double dx, double dy);
void scale(double sx, double? sy = null);
void rotate(double radians, Offset offset = null);
void skew(double sx, double sy);
void concat(Matrix3 matrix);
Matrix3 getTotalMatrix();
void resetMatrix();
void setMatrix(Matrix3 matrix);
float getDevicePixelRatio();
void clipRect(Rect rect);
void clipRRect(RRect rrect);
void clipPath(Path path);
void drawLine(Offset from, Offset to, Paint paint);
void drawRect(Rect rect, BorderWidth borderWidth = null, BorderRadius borderRadius = null, Paint paint = null);
void drawRect(Rect rect, Paint paint);
void drawRRect(RRect rect, Paint paint);
void drawRectShadow(Rect rect, Paint paint = null);
void drawDRRect(RRect outer, RRect inner, Paint paint);
void drawPicture(Picture picture);
void drawOval(Rect rect, Paint paint);
void drawImageRect(Image image, Rect dest, Rect src = null, Paint paint = null);
void drawCircle(Offset c, double radius, Paint paint);
void drawLine(Offset from, Offset to, Paint paint = null);
void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint);
void concat(Matrix4x4 transform);
void drawPath(Path path, Paint paint);
void setMatrix(Matrix4x4 matrix);
void drawImage(Texture image, Offset offset, Paint paint);
Matrix4x4 getMatrix();
void drawImageRect(Texture image, Rect dst, Paint paint);
void save();
void drawImageRect(Texture image, Rect src, Rect dst, Paint paint);
void saveLayer(Rect rect, Paint paint = null);
void drawImageNine(Texture image, Rect center, Rect dst, Paint paint);
void restore();
void drawImageNine(Texture image, Rect src, Rect center, Rect dst, Paint paint);
int getSaveCount();
void drawPicture(Picture picture);
void clipRect(Rect rect, bool doAntiAlias = true);
void drawTextBlob(TextBlob textBlob, Offset offset, Paint paint);
void clipRRect(RRect rrect, bool doAntiAlias = true);
void flush();
void drawTextBlob(TextBlob textBlob, Offset offset);
void reset();
}
public class RecorderCanvas : Canvas {

int _saveCount = 1;
public void drawPloygon4(Offset[] points, Paint paint) {
this._recorder.addDrawCmd(new DrawPloygon4 {
points = points,
public void save() {
this._saveCount++;
this._recorder.addDrawCmd(new DrawSave {
});
}
public void saveLayer(Rect rect, Paint paint) {
this._saveCount++;
this._recorder.addDrawCmd(new DrawSaveLayer {
rect = rect,
public void drawRect(Rect rect, BorderWidth borderWidth, BorderRadius borderRadius, Paint paint) {
this._recorder.addDrawCmd(new DrawRect {
public void restore() {
this._saveCount--;
this._recorder.addDrawCmd(new DrawRestore {
});
}
public int getSaveCount() {
return this._saveCount;
}
public void translate(double dx, double dy) {
this._recorder.addDrawCmd(new DrawTranslate {
dx = dx,
dy = dy,
});
}
public void scale(double sx, double? sy = null) {
this._recorder.addDrawCmd(new DrawScale {
sx = sx,
sy = sy,
});
}
public void rotate(double radians, Offset offset = null) {
this._recorder.addDrawCmd(new DrawRotate {
radians = radians,
offset = offset,
});
}
public void skew(double sx, double sy) {
this._recorder.addDrawCmd(new DrawSkew {
sx = sx,
sy = sy,
});
}
public void concat(Matrix3 matrix) {
this._recorder.addDrawCmd(new DrawConcat {
matrix = matrix,
});
}
public Matrix3 getTotalMatrix() {
throw new Exception("not available in recorder");
}
public void resetMatrix() {
this._recorder.addDrawCmd(new DrawResetMatrix {
});
}
public void setMatrix(Matrix3 matrix) {
this._recorder.addDrawCmd(new DrawSetMatrix {
matrix = matrix,
});
}
public float getDevicePixelRatio() {
throw new Exception("not available in recorder");
}
public void clipRect(Rect rect) {
this._recorder.addDrawCmd(new DrawClipRect {
borderWidth = borderWidth,
borderRadius = borderRadius,
});
}
public void clipRRect(RRect rrect) {
this._recorder.addDrawCmd(new DrawClipRRect {
rrect = rrect,
});
}
public void clipPath(Path path) {
this._recorder.addDrawCmd(new DrawClipPath {
path = path,
});
}
public void drawLine(Offset from, Offset to, Paint paint) {
var path = new Path();
path.moveTo(from.dx, from.dy);
path.lineTo(to.dx, to.dy);
this._recorder.addDrawCmd(new DrawPath {
path = path,
public void drawRectShadow(Rect rect, Paint paint) {
this._recorder.addDrawCmd(new DrawRectShadow {
rect = rect,
public void drawRect(Rect rect, Paint paint) {
var path = new Path();
path.addRect(rect);
this._recorder.addDrawCmd(new DrawPath {
path = path,
public void drawPicture(Picture picture) {
this._recorder.addDrawCmd(new DrawPicture {
picture = picture,
public void drawRRect(RRect rrect, Paint paint) {
var path = new Path();
path.addRRect(rrect);
this._recorder.addDrawCmd(new DrawPath {
path = path,
paint = paint,
public void drawImageRect(Image image, Rect dest, Rect src, Paint paint) {
this._recorder.addDrawCmd(new DrawImageRect {
image = image,
dest = dest,
src = src,
public void drawDRRect(RRect outer, RRect inner, Paint paint) {
var path = new Path();
path.addRRect(outer);
path.addRRect(inner);
path.winding(PathWinding.clockwise);
this._recorder.addDrawCmd(new DrawPath {
path = path,
public void drawLine(Offset from, Offset to, Paint paint) {
this._recorder.addDrawCmd(new DrawLine {
from = from,
to = to,
public void drawOval(Rect rect, Paint paint) {
var w = rect.width / 2;
var h = rect.height / 2;
var path = new Path();
path.addEllipse(rect.left + w, rect.top + h, w, h);
this._recorder.addDrawCmd(new DrawPath {
path = path,
public void concat(Matrix4x4 transform) {
this._recorder.addDrawCmd(new DrawConcat {
transform = transform,
public void drawCircle(Offset c, double radius, Paint paint) {
var path = new Path();
path.addCircle(c.dx, c.dy, radius);
this._recorder.addDrawCmd(new DrawPath {
path = path,
paint = paint,
public void setMatrix(Matrix4x4 matrix) {
this._recorder.addDrawCmd(new DrawSetMatrix {
matrix = matrix,
public void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint) {
var path = new Path();
//path.(c.dx, c.dy, radius);
this._recorder.addDrawCmd(new DrawPath {
path = path,
paint = paint,
public Matrix4x4 getMatrix() {
throw new Exception("not available in recorder");
public void drawPath(Path path, Paint paint) {
this._recorder.addDrawCmd(new DrawPath {
path = path,
paint = paint,
});
public void save() {
this._saveCount++;
this._recorder.addDrawCmd(new DrawSave {
public void drawImage(Texture image, Offset offset, Paint paint) {
this._recorder.addDrawCmd(new DrawImage {
image = image,
offset = offset,
paint = paint,
public void saveLayer(Rect rect, Paint paint) {
this._saveCount++;
this._recorder.addDrawCmd(new DrawSaveLayer {
rect = rect,
public void drawImageRect(Texture image, Rect dst, Paint paint) {
this._recorder.addDrawCmd(new DrawImageRect {
image = image,
dst = dst,
public void restore() {
this._saveCount--;
this._recorder.addDrawCmd(new DrawRestore {
public void drawImageRect(Texture image, Rect src, Rect dst, Paint paint) {
this._recorder.addDrawCmd(new DrawImageRect {
image = image,
src = src,
dst = dst,
paint = paint,
public int getSaveCount() {
return this._saveCount;
public void drawImageNine(Texture image, Rect center, Rect dst, Paint paint) {
this._recorder.addDrawCmd(new DrawImageNine {
image = image,
center = center,
dst = dst,
paint = paint,
});
public void clipRect(Rect rect, bool doAntiAlias = true) {
this._recorder.addDrawCmd(new DrawClipRect {
rect = rect,
public void drawImageNine(Texture image, Rect src, Rect center, Rect dst, Paint paint) {
this._recorder.addDrawCmd(new DrawImageNine {
image = image,
src = src,
center = center,
dst = dst,
paint = paint,
public void clipRRect(RRect rrect, bool doAntiAlias = true) {
this._recorder.addDrawCmd(new DrawClipRRect {
rrect = rrect,
public void drawPicture(Picture picture) {
this._recorder.addDrawCmd(new DrawPicture {
picture = picture,
public void drawTextBlob(TextBlob textBlob, Offset offset) {
public void drawTextBlob(TextBlob textBlob, Offset offset, Paint paint) {
offset = offset
offset = offset,
paint = paint,
}
public void flush() {
throw new Exception("not available in recorder");
}
public void reset() {
throw new Exception("not available in recorder");
}
}
}

978
Assets/UIWidgets/ui/painting/canvas_impl.cs
文件差异内容过多而无法显示
查看文件

95
Assets/UIWidgets/ui/painting/draw_cmd.cs


using UIWidgets.painting;
using UIWidgets.ui.txt;
using UIWidgets.ui.txt;
public interface DrawCmd {
public abstract class DrawCmd {
public class DrawPloygon4 : DrawCmd {
public Offset[] points;
public Paint paint;
public class DrawSave : DrawCmd {
public class DrawRect : DrawCmd {
public class DrawSaveLayer : DrawCmd {
public BorderWidth borderWidth;
public BorderRadius borderRadius;
public class DrawRectShadow : DrawCmd {
public Rect rect;
public Paint paint;
public class DrawRestore : DrawCmd {
public class DrawPicture : DrawCmd {
public Picture picture;
public class DrawTranslate : DrawCmd {
public double dx;
public double dy;
public class DrawImageRect : DrawCmd {
public Paint paint;
public Image image;
public Rect src;
public Rect dest;
public class DrawScale : DrawCmd {
public double sx;
public double? sy;
public class DrawConcat : DrawCmd {
public Matrix4x4 transform;
public class DrawRotate : DrawCmd {
public double radians;
public Offset offset;
public class DrawSetMatrix : DrawCmd {
public Matrix4x4 matrix;
public class DrawSkew : DrawCmd {
public double sx;
public double sy;
public class DrawSave : DrawCmd {
public class DrawConcat : DrawCmd {
public Matrix3 matrix;
public class DrawSaveLayer : DrawCmd {
public Rect rect;
public Paint paint;
public class DrawResetMatrix : DrawCmd {
public class DrawRestore : DrawCmd {
public class DrawSetMatrix : DrawCmd {
public Matrix3 matrix;
}
public class DrawClipRect : DrawCmd {

public class DrawClipRRect : DrawCmd {
public RRect rrect;
}
public class DrawTextBlob : DrawCmd
{
public TextBlob textBlob;
public class DrawClipPath : DrawCmd {
public Path path;
}
public class DrawPath : DrawCmd {
public Path path;
public Paint paint;
}
public class DrawImage : DrawCmd {
public Texture image;
public Paint paint;
public class DrawLine : DrawCmd
{
public Offset from;
public Offset to;
public class DrawImageRect : DrawCmd {
public Texture image;
public Rect src;
public Rect dst;
public Paint paint;
}
public class DrawImageNine : DrawCmd {
public Texture image;
public Rect src;
public Rect center;
public Rect dst;
}
public class DrawPicture : DrawCmd {
public Picture picture;
}
public class DrawTextBlob : DrawCmd {
public TextBlob textBlob;
public Offset offset;
public Paint paint;
}
}

202
Assets/UIWidgets/ui/painting/painting.cs


using UnityEngine;
namespace UIWidgets.ui {
public static class PaintingUtils {
internal static Color _scaleAlpha(this Color a, double factor) {
return a.withAlpha((a.alpha * factor).round().clamp(0, 255));
}
}
public class Color : IEquatable<Color> {
public Color(long value) {
this.value = value & 0xFFFFFFFF;

return !(a == b);
}
public override string ToString()
{
return string.Format("Color(0x{0:X8})", value);
public override string ToString() {
return string.Format("Color(0x{0:X8})", this.value);
}
}

antiAliasWithSaveLayer,
}
public class Paint {
public enum PaintingStyle {
fill,
stroke,
}
public enum StrokeCap {
butt,
round,
square,
}
public enum StrokeJoin {
miter,
round,
bevel,
}
public class ColorFilter {
public BlendMode blendMode;
}
public enum TileMode {
// todo: implement repeated, mirror.
clamp,
repeated,
mirror
}
public abstract class PaintShader {
}
public class Gradient : PaintShader {
internal float[] invXform;
internal float[] extent;
internal float radius;
internal float feather;
internal Color innerColor;
internal Color outerColor;
public static Gradient linear(
Offset from, Offset to,
Color color0, Color color1, TileMode tileMode = TileMode.clamp) {
const float large = 1e5f;
var dir = to - from;
var dx = (float) dir.dx;
var dy = (float) dir.dy;
var d = (float) dir.distance;
if (d > 0.0001f) {
dx /= d;
dy /= d;
} else {
dx = 0;
dy = 1;
}
var xform = new[] {dy, -dx, dx, dy, (float) from.dx - dx * large, (float) from.dy - dy * large};
var invXform = new float[6];
XformUtils.transformInverse(invXform, xform);
return new Gradient {
invXform = invXform,
extent = new[] {large, large + d * 0.5f},
radius = 0.0f,
feather = Mathf.Max(1.0f, d),
innerColor = color0,
outerColor = color1
};
}
public static Gradient radial(
Offset center, double radius0, double radius1,
Color color0, Color color1, TileMode tileMode = TileMode.clamp) {
float r = (float) (radius0 + radius1) * 0.5f;
float f = (float) (radius1 - radius0);
var xform = new[] {1, 0, 0, 1, (float) center.dx, (float) center.dy};
var invXform = new float[6];
XformUtils.transformInverse(invXform, xform);
return new Gradient {
invXform = invXform,
extent = new[] {r, r},
radius = r,
feather = Mathf.Max(1.0f, f),
innerColor = color0,
outerColor = color1
};
}
public static Gradient box(
Rect rect, double radius, double feather,
Color color0, Color color1, TileMode tileMode = TileMode.clamp) {
var ext0 = (float) rect.width * 0.5f;
var ext1 = (float) rect.height * 0.5f;
var xform = new[] {1, 0, 0, 1, (float) rect.left + ext0, (float) rect.top + ext1};
var invXform = new float[6];
XformUtils.transformInverse(invXform, xform);
return new Gradient {
invXform = invXform,
extent = new[] {ext0, ext1},
radius = (float) radius,
feather = Mathf.Max(1.0f, (float) feather),
innerColor = color0,
outerColor = color1
};
}
}
public class Paint {
static readonly Color _kColorDefault = new Color(0xFFFFFFFF);
public Color color = _kColorDefault;
public BlendMode blendMode = BlendMode.srcOver;
public PaintingStyle style = PaintingStyle.fill;
public double strokeWidth = 0;
public StrokeCap strokeCap = StrokeCap.butt;
public StrokeJoin strokeJoin = StrokeJoin.miter;
public double strokeMiterLimit = 4.0;
public FilterMode filterMode = FilterMode.Point;
public ColorFilter colorFilter = null;
public PaintShader shader = null;
public double strokeWidth = 1;
}
public static class Conversions {

}
public static Color32 toColor32(this Color color) {
return new Color32(
(byte) color.red, (byte) color.green, (byte) color.blue, (byte) color.alpha);
}
public static Vector2 toVector(this Offset offset) {

(float) borderRadius.bottomRight, (float) borderRadius.bottomLeft
};
}
}
// public class ColorFilter {
// public ColorFilter(Color color, BlendMode blendMode) {
// _color = color;
// _blendMode = blendMode;
// }
//
// Color _color;
// BlendMode _blendMode;
// }
public static Matrix3 toMatrix3(this Matrix4x4 matrix4x4) {
return Matrix3.makeAll(
matrix4x4[0], matrix4x4[4], matrix4x4[12],
matrix4x4[1], matrix4x4[5], matrix4x4[13],
matrix4x4[3], matrix4x4[7], matrix4x4[15]
);
}
public static Matrix4x4 toMatrix4x4(this Matrix3 matrix3) {
var result = Matrix4x4.identity;
result[0] = matrix3[0];
result[1] = matrix3[1];
result[3] = matrix3[2];
result[4] = matrix3[3];
result[5] = matrix3[4];
result[7] = matrix3[5];
result[12] = matrix3[6];
result[13] = matrix3[7];
result[14] = matrix3[8];
return result;
}
public static float alignToPixel(this float v, float devicePixelRatio) {
return Mathf.Round(v * devicePixelRatio) / devicePixelRatio;
}
internal static Color _scaleAlpha(this Color a, double factor) {
return a.withAlpha((a.alpha * factor).round().clamp(0, 255));
}
}
None = 0, // explicitly assign zero to make it more clear
srcOver,
dstOver,
srcIn,
dstIn,

dstATop,
xor,
plus,
// REF: https://www.w3.org/TR/compositing-1/#blendingseparable
screen, // The last coeff mode.
screen,
overlay,
darken,
lighten,

softLight,
difference,
exclusion,
multiply, // The last separable mode.
multiply,
// REF: https://www.w3.org/TR/compositing-1/#blendingnonseparable
hue,
saturation,
color,

315
Assets/UIWidgets/ui/painting/picture.cs


using System;
using System.Collections.Generic;
using UIWidgets.painting;
using System.Linq;
using UIWidgets.foundation;
using UnityEngine;
namespace UIWidgets.ui {

}
public class PictureRecorder {
private readonly List<DrawCmd> _drawCmds = new List<DrawCmd>();
private Matrix4x4 _transform;
private Rect _clipRect;
private bool _isInLayer;
private Rect _paintBounds;
readonly List<DrawCmd> _drawCmds = new List<DrawCmd>();
private Stack<CanvasRec> _stack;
readonly List<CanvasState> _states = new List<CanvasState>();
this._transform = Matrix4x4.identity;
this._clipRect = null;
this._isInLayer = false;
this._paintBounds = null;
this._states.Add(new CanvasState {
xform = Matrix3.I(),
scissor = null,
saveLayer = false,
layerOffset = null,
paintBounds = Rect.zero,
});
private Stack<CanvasRec> stack {
get { return this._stack ?? (this._stack = new Stack<CanvasRec>()); }
CanvasState _getState() {
D.assert(this._states.Count > 0);
return this._states.Last();
if (this._stack != null && this._stack.Count > 0) {
if (this._states.Count > 1) {
return new Picture(this._drawCmds, this._paintBounds);
var state = this._getState();
return new Picture(this._drawCmds, state.paintBounds);
if (drawCmd is DrawPloygon4) {
var drawPloygon4 = (DrawPloygon4) drawCmd;
if (drawPloygon4.paint.color.alpha > 0) {
this.addPaintBounds(drawPloygon4.points);
if (drawCmd is DrawSave) {
this._states.Add(this._getState().copy());
} else if (drawCmd is DrawSaveLayer) {
var drawSaveLayer = (DrawSaveLayer) drawCmd;
this._states.Add(new CanvasState {
xform = Matrix3.I(),
scissor = drawSaveLayer.rect.shift(-drawSaveLayer.rect.topLeft),
saveLayer = true,
layerOffset = drawSaveLayer.rect.topLeft,
paintBounds = Rect.zero,
});
} else if (drawCmd is DrawRestore) {
var stateToRestore = this._getState();
this._states.RemoveAt(this._states.Count - 1);
var state = this._getState();
if (!stateToRestore.saveLayer) {
state.paintBounds = stateToRestore.paintBounds;
} else {
var paintBounds = stateToRestore.paintBounds.shift(stateToRestore.layerOffset);
paintBounds = state.xform.mapRect(paintBounds);
this._addPaintBounds(paintBounds);
} else if (drawCmd is DrawRect) {
var drawRect = (DrawRect) drawCmd;
if (drawRect.paint.color.alpha > 0) {
this.addPaintBounds(drawRect.rect);
}
} else if (drawCmd is DrawRectShadow) {
var drawRectShadow = (DrawRectShadow) drawCmd;
if (drawRectShadow.paint.color.alpha > 0) {
this.addPaintBounds(drawRectShadow.rect);
} else if (drawCmd is DrawTranslate) {
var drawTranslate = (DrawTranslate) drawCmd;
var state = this._getState();
state.xform.preTranslate((float) drawTranslate.dx, (float) drawTranslate.dy);
} else if (drawCmd is DrawScale) {
var drawScale = (DrawScale) drawCmd;
var state = this._getState();
state.xform.preScale((float) drawScale.sx, (float) (drawScale.sy ?? drawScale.sx));
} else if (drawCmd is DrawRotate) {
var drawRotate = (DrawRotate) drawCmd;
var state = this._getState();
if (drawRotate.offset == null) {
state.xform.preRotate((float) drawRotate.radians * Mathf.PI);
} else {
state.xform.preRotate((float) drawRotate.radians * Mathf.PI,
(float) drawRotate.offset.dx,
(float) drawRotate.offset.dy);
} else if (drawCmd is DrawPicture) {
var drawPicture = (DrawPicture) drawCmd;
this.addPaintBounds(drawPicture.picture.paintBounds);
} else if (drawCmd is DrawSkew) {
var drawSkew = (DrawSkew) drawCmd;
var state = this._getState();
state.xform.preSkew((float) drawSkew.sx, (float) drawSkew.sy);
this._transform = ((DrawConcat) drawCmd).transform * this._transform;
} else if (drawCmd is DrawSave) {
this.stack.Push(new CanvasRec(
this._transform,
this._clipRect,
this._isInLayer,
null
));
} else if (drawCmd is DrawLine)
{
var drawLine = (DrawLine) drawCmd;
Offset vect = drawLine.to - drawLine.from;
var distance = vect.distance;
if (distance > 0)
{
var halfWidth = drawLine.paint.strokeWidth * 0.5;
var diff = vect / distance * halfWidth;
diff = new Offset(diff.dy, -diff.dx);
var offsets = new Offset[]
{
drawLine.from + diff,
drawLine.from - diff,
drawLine.to + diff,
drawLine.to - diff,
};
var drawConcat = (DrawConcat) drawCmd;
var state = this._getState();
state.xform.preConcat(drawConcat.matrix);
} else if (drawCmd is DrawResetMatrix) {
var state = this._getState();
state.xform.reset();
} else if (drawCmd is DrawSetMatrix) {
var drawSetMatrix = (DrawSetMatrix) drawCmd;
var state = this._getState();
state.xform = new Matrix3(drawSetMatrix.matrix);
} else if (drawCmd is DrawClipRect) {
var drawClipRect = (DrawClipRect) drawCmd;
var state = this._getState();
var rect = state.xform.mapRect(drawClipRect.rect);
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
} else if (drawCmd is DrawClipRRect) {
var drawClipRRect = (DrawClipRRect) drawCmd;
var state = this._getState();
var rect = state.xform.mapRect(drawClipRRect.rrect.outerRect);
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
} else if (drawCmd is DrawClipPath) {
var drawClipPath = (DrawClipPath) drawCmd;
var state = this._getState();
bool convex;
var rect = drawClipPath.path.flatten(
XformUtils.fromMatrix3(state.xform), (float) Window.instance.devicePixelRatio
).getFillMesh(out convex).getBounds();
state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
} else if (drawCmd is DrawPath) {
var drawPath = (DrawPath) drawCmd;
var state = this._getState();
var xform = XformUtils.fromMatrix3(state.xform);
var path = drawPath.path;
var paint = drawPath.paint;
var devicePixelRatio = (float) Window.instance.devicePixelRatio;
var minX = offsets[0].dx;
var maxX = offsets[0].dx;
var minY = offsets[0].dy;
var maxY = offsets[0].dy;
for (int i = 1; i < offsets.Length; i++)
{
minX = Math.Min(minX, offsets[i].dx);
maxX = Math.Max(maxX, offsets[i].dx);
minY = Math.Min(minY, offsets[i].dy);
maxY = Math.Min(maxY, offsets[i].dy);
}
this.addPaintBounds(Rect.fromLTRB(minX, minY, maxX, maxY));
}
}
else if (drawCmd is DrawSaveLayer) {
this.stack.Push(new CanvasRec(
this._transform,
this._clipRect,
this._isInLayer,
this._paintBounds
));
Mesh mesh;
if (paint.style == PaintingStyle.fill) {
var cache = path.flatten(xform, devicePixelRatio);
var drawSaveLayer = (DrawSaveLayer) drawCmd;
this._transform = Matrix4x4.identity;
this._clipRect = drawSaveLayer.rect;
this._isInLayer = true;
this._paintBounds = null;
} else if (drawCmd is DrawRestore) {
var isLayer = this._isInLayer;
bool convex;
mesh = cache.getFillMesh(out convex);
} else {
float scale = XformUtils.getAverageScale(xform);
float strokeWidth = ((float) paint.strokeWidth * scale).clamp(0, 200.0f);
float fringeWidth = 1 / devicePixelRatio;
var state = this._stack.Pop();
this._transform = state.transform;
this._clipRect = state.clipRect;
this._isInLayer = state.isInLayer;
if (strokeWidth < fringeWidth) {
strokeWidth = fringeWidth;
}
if (isLayer) {
var paintBounds = this._paintBounds;
this._paintBounds = state.paintBounds;
this.addPaintBounds(paintBounds);
var cache = path.flatten(xform, devicePixelRatio);
mesh = cache.getStrokeMesh(
strokeWidth * 0.5f,
paint.strokeCap,
paint.strokeJoin,
(float) paint.strokeMiterLimit);
} else if (drawCmd is DrawClipRect) {
var drawClipRect = (DrawClipRect) drawCmd;
this.addClipRect(drawClipRect.rect);
} else if (drawCmd is DrawClipRRect) {
var drawClipRRect = (DrawClipRRect) drawCmd;
this.addClipRect(drawClipRRect.rrect.outerRect);
} else if (drawCmd is DrawTextBlob)
{
var drawTextBlob = (DrawTextBlob) drawCmd;
var bounds = drawTextBlob.textBlob.boundsInText.shift(drawTextBlob.offset);
this.addPaintBounds(bounds);
this._addPaintBounds(mesh.getBounds());
} else if (drawCmd is DrawImage) {
var drawImage = (DrawImage) drawCmd;
var state = this._getState();
var rect = Rect.fromLTWH(drawImage.offset.dx, drawImage.offset.dy,
drawImage.image.width, drawImage.image.height);
rect = state.xform.mapRect(rect);
this._addPaintBounds(rect);
this.addPaintBounds(drawImageRect.dest);
var state = this._getState();
var rect = state.xform.mapRect(drawImageRect.dst);
this._addPaintBounds(rect);
} else if (drawCmd is DrawImageNine) {
var drawImageNine = (DrawImageNine) drawCmd;
var state = this._getState();
var rect = state.xform.mapRect(drawImageNine.dst);
this._addPaintBounds(rect);
} else if (drawCmd is DrawPicture) {
var drawPicture = (DrawPicture) drawCmd;
var state = this._getState();
var rect = state.xform.mapRect(drawPicture.picture.paintBounds);
this._addPaintBounds(rect);
} else if (drawCmd is DrawTextBlob) {
var drawTextBlob = (DrawTextBlob) drawCmd;
var state = this._getState();
var rect = drawTextBlob.textBlob.boundsInText.shift(drawTextBlob.offset);
rect = state.xform.mapRect(rect);
this._addPaintBounds(rect);
private void addClipRect(Rect rect) {
if (rect.isInfinite) {
return;
void _addPaintBounds(Rect paintBounds) {
var state = this._getState();
if (state.scissor != null) {
paintBounds = paintBounds.intersect(state.scissor);
if (this._clipRect != null) {
throw new Exception("already a clipRec, considering using saveLayer.");
if (state.paintBounds.isEmpty) {
state.paintBounds = paintBounds;
} else {
state.paintBounds = state.paintBounds.expandToInclude(paintBounds);
this._clipRect = this._transform.transformRect(rect);
private void addPaintBounds(Rect paintBounds) {
if (paintBounds == null) {
return;
}
paintBounds = this._transform.transformRect(paintBounds);
if (this._clipRect != null) {
paintBounds = paintBounds.intersect(this._clipRect);
}
this._paintBounds = this._paintBounds == null
? paintBounds
: this._paintBounds.expandToInclude(paintBounds);
}
class CanvasState {
public Matrix3 xform;
public Rect scissor;
public bool saveLayer;
public Offset layerOffset;
public Rect paintBounds;
private void addPaintBounds(Offset[] points) {
var paintBounds = this._transform.transformRect(points);
if (this._clipRect != null) {
paintBounds = paintBounds.intersect(this._clipRect);
public CanvasState copy() {
return new CanvasState {
xform = this.xform,
scissor = this.scissor,
saveLayer = false,
layerOffset = null,
paintBounds = this.paintBounds,
};
this._paintBounds = this._paintBounds == null
? paintBounds
: this._paintBounds.expandToInclude(paintBounds);
}
private class CanvasRec {
public CanvasRec(Matrix4x4 transform, Rect clipRect, bool isInLayer, Rect paintBounds) {
this.transform = transform;
this.clipRect = clipRect;
this.isInLayer = isInLayer;
this.paintBounds = paintBounds;
}
public readonly Matrix4x4 transform;
public readonly Rect clipRect;
public readonly bool isInLayer;
public readonly Rect paintBounds;
}
}
}

120
Assets/UIWidgets/ui/painting/txt/mesh_generator.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgets.ui.txt;
using UnityEditor;
// TODO: probably we don't need this cache.
public class MeshKey : IEquatable<MeshKey>
{
public readonly string text;

get { return _frameCount; }
}
public static long MeshCount
public static int meshCount
{
get { return _meshes.Count; }
}

}
}
public static Mesh generateMesh(TextBlob textBlob)
public static Mesh generateMesh(TextBlob textBlob, float[] xform, float devicePixelRatio)
{
var style = textBlob.style;
var fontInfo = FontManager.instance.getOrCreate(style.fontFamily);

var text = textBlob.text;
var scale = EditorGUIUtility.pixelsPerPoint;
var fontSizeToLoad = (int) scale * style.UnityFontSize;
var scale = XformUtils.getAverageScale(xform) * devicePixelRatio;
var fontSizeToLoad = Mathf.CeilToInt( style.UnityFontSize * scale);
font.RequestCharactersInTexture(subText,
fontSizeToLoad, style.UnityFontStyle);
font.RequestCharactersInTexture(subText, fontSizeToLoad, style.UnityFontStyle);
MeshInfo meshInfo;
var key = new MeshKey(subText, font.GetInstanceID(),
fontInfo.textureVersion,
style.UnityFontSize, style.UnityFontStyle, scale, style.UnityColor);
Mesh mesh = null;
_meshes.TryGetValue(key, out meshInfo);
if (meshInfo != null)
{
mesh = meshInfo.mesh;
meshInfo.touch();
}
if (mesh != null)
{
return mesh;
}
var vertices = new List<Vector3>(length * 4);
var triangles = new List<int>(length * 6);
var uv = new List<Vector2>(length * 4);
Mesh mesh = new Mesh();
var vertices = new Vector3[length * 4];
var triangles = new int[length * 6];
var uv = new Vector2[length * 4];
mesh = new Mesh();
_meshes[key] = new MeshInfo(key, mesh);
for (int charIndex = 0; charIndex < length; ++charIndex)
{
for (int charIndex = 0; charIndex < length; ++charIndex) {
var position = textBlob.positions[charIndex + textBlob.start] - textBlob.positions[textBlob.start];
if (Paragraph.isWordSpace(ch) || Paragraph.isLineEndSpace(ch) || ch == '\t')
{
vertices[4 * charIndex + 0] = vertices[4 * charIndex + 1] =
vertices[4 * charIndex + 2] = vertices[4 * charIndex + 3] = Vector3.zero;
uv[4 * charIndex + 0] = Vector2.zero;
uv[4 * charIndex + 1] = Vector2.zero;
uv[4 * charIndex + 2] = Vector2.zero;
uv[4 * charIndex + 3] = Vector2.zero;
var position = textBlob.positions[charIndex + textBlob.start];
if (Paragraph.isWordSpace(ch) || Paragraph.isLineEndSpace(ch) || ch == '\t') {
continue;
else
{
CharacterInfo charInfo;
font.GetCharacterInfo(ch, out charInfo, fontSizeToLoad, style.UnityFontStyle);
var minX = charInfo.minX / scale;
var maxX = charInfo.maxX / scale;
var minY = charInfo.minY / scale;
var maxY = charInfo.maxY / scale;
vertices[4 * charIndex + 0] = new Vector3((float) (position.x + minX),
(float) (position.y - maxY), 0);
vertices[4 * charIndex + 1] = new Vector3((float) (position.x + maxX),
(float) (position.y - maxY), 0);
vertices[4 * charIndex + 2] = new Vector3(
(float) (position.x + maxX), (float) (position.y - minY), 0);
vertices[4 * charIndex + 3] = new Vector3(
(float) (position.x + minX), (float) (position.y - minY), 0);
uv[4 * charIndex + 0] = charInfo.uvTopLeft;
uv[4 * charIndex + 1] = charInfo.uvTopRight;
uv[4 * charIndex + 2] = charInfo.uvBottomRight;
uv[4 * charIndex + 3] = charInfo.uvBottomLeft;
}
CharacterInfo charInfo;
font.GetCharacterInfo(ch, out charInfo, fontSizeToLoad, style.UnityFontStyle);
var minX = charInfo.minX / scale;
var maxX = charInfo.maxX / scale;
var minY = charInfo.minY / scale;
var maxY = charInfo.maxY / scale;
triangles[6 * charIndex + 0] = 4 * charIndex + 0;
triangles[6 * charIndex + 1] = 4 * charIndex + 1;
triangles[6 * charIndex + 2] = 4 * charIndex + 2;
var baseIndex = vertices.Count;
triangles[6 * charIndex + 3] = 4 * charIndex + 0;
triangles[6 * charIndex + 4] = 4 * charIndex + 2;
triangles[6 * charIndex + 5] = 4 * charIndex + 3;
}
float x, y;
PathUtils.transformPoint(out x, out y, xform, (float) (position.x + minX), (float) (position.y - maxY));
vertices.Add(new Vector3(x, y, 0));
PathUtils.transformPoint(out x, out y, xform, (float) (position.x + maxX), (float) (position.y - maxY));
vertices.Add(new Vector3(x, y, 0));
PathUtils.transformPoint(out x, out y, xform, (float) (position.x + maxX), (float) (position.y - minY));
vertices.Add(new Vector3(x, y, 0));
PathUtils.transformPoint(out x, out y, xform, (float) (position.x + minX), (float) (position.y - minY));
vertices.Add(new Vector3(x, y, 0));
var colors = new UnityEngine.Color[vertices.Length];
for (var i = 0; i < colors.Length; i++)
{
colors[i] = style.UnityColor;
triangles.Add(baseIndex);
triangles.Add(baseIndex + 1);
triangles.Add(baseIndex + 2);
triangles.Add(baseIndex);
triangles.Add(baseIndex + 2);
triangles.Add(baseIndex + 3);
uv.Add(charInfo.uvTopLeft);
uv.Add(charInfo.uvTopRight);
uv.Add(charInfo.uvBottomRight);
uv.Add(charInfo.uvBottomLeft);
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.colors = colors;
mesh.uv = uv;
mesh.SetVertices(vertices);
mesh.SetIndices(triangles.ToArray(), MeshTopology.Triangles, 0);
mesh.SetUVs(0, uv);
return mesh;
}
}

5
Assets/UIWidgets/ui/painting/txt/text_blob.cs


using System;
using UnityEngine;
using UIWidgets.foundation;
namespace UIWidgets.ui.txt
{

{
Debug.Assert(start < end);
D.assert(start < end);
this.text = text;
this.start = start;
this.end = end;

6
Assets/UIWidgets/ui/text.cs


public readonly string fontFamily = "Helvetica";
public readonly Paint background;
public UnityEngine.Color UnityColor
internal UnityEngine.Color UnityColor
public UnityEngine.FontStyle UnityFontStyle
internal UnityEngine.FontStyle UnityFontStyle
{
get
{

}
}
public int UnityFontSize
internal int UnityFontSize
{
get { return (int) fontSize; }
}

21
Assets/UIWidgets/ui/txt/paragraph.cs


public readonly int endIncludingNewLine;
public readonly bool hardBreak;
}
private static readonly Shader textShader;
static Paragraph() {
textShader = Shader.Find("UIWidgets/Text Shader");
if (textShader == null) {
throw new Exception("UIWidgets/Text Shader Lines not found");
}
}
private bool _needsLayout = true;

public void paint(Canvas canvas, Offset offset)
{
foreach (var paintRecord in _paintRecords)
{
canvas.drawTextBlob(paintRecord.text, offset);
foreach (var paintRecord in _paintRecords) {
var paint = new Paint {
color = paintRecord.style.color,
};
canvas.drawTextBlob(paintRecord.text, offset, paint);
paintDecorations(canvas, paintRecord, offset);
}
}

var bounds = Rect.fromLTWH(0, -metrics.ascent,
_characterPositions[end - 1].x + _characterWidths[end - 1] -
_characterPositions[start].x,
metrics.descent);
metrics.ascent + metrics.descent);
linePaintRecords.Add(new PaintRecord(run.style, new Offset(_characterPositions[start].x, yOffset)
, new TextBlob(

var width = record.runWidth;
var metrics = record.metrics;
double underLineThickness = metrics.underlineThickness ?? (record.style.fontSize / 14.0);
paint.style = PaintingStyle.stroke;
paint.strokeWidth = underLineThickness;
var recordOffset = baseOffset + record.offset;
var x = recordOffset.dx;

2
Assets/UIWidgets/ui/txt/styled_runs.cs


public int addStyle(TextStyle style)
{
var styleIndex = styles.Count;
styles.Add( style);
styles.Add(style);
return styleIndex;
}

6
Assets/UIWidgets/ui/window.cs


}
static Window _instance;
public double devicePixelRatio {
get { return this._devicePixelRatio; }
}

PointerDataPacketCallback _onPointerEvent;
public abstract void scheduleFrame();
public abstract void scheduleFrame(bool regenerateLayerTree = true);
public abstract void render(Scene scene);

}
public abstract TextInput textInput { get; }
public abstract IDisposable getScope();
}
}

14
Assets/UIWidgets/widgets/basic.cs


this.textBaseline = textBaseline;
}
public Axis direction;
public MainAxisAlignment mainAxisAlignment;
public MainAxisSize mainAxisSize;
public CrossAxisAlignment crossAxisAlignment;
public TextDirection? textDirection;
public VerticalDirection verticalDirection;
public TextBaseline? textBaseline;
public readonly Axis direction;
public readonly MainAxisAlignment mainAxisAlignment;
public readonly MainAxisSize mainAxisSize;
public readonly CrossAxisAlignment crossAxisAlignment;
public readonly TextDirection? textDirection;
public readonly VerticalDirection verticalDirection;
public readonly TextBaseline? textBaseline;
private bool _needTextDirection {
get {

3
Assets/UIWidgets/widgets/binding.cs


public WidgetsBinding() {
this.buildOwner.onBuildScheduled = this._handleBuildScheduled;
Window.instance.onLocaleChanged += this.handleLocaleChanged;
this.addPersistentFrameCallback((duration) =>
{
this.addPersistentFrameCallback((duration) => {
MeshGenrator.tickNextFrame();
});
}

4
Assets/UIWidgets/widgets/image.cs


double? width = null,
double? height = null,
Color color = null,
BlendMode colorBlendMode = BlendMode.None,
BlendMode colorBlendMode = BlendMode.srcOver,
BoxFit fit = BoxFit.none,
Alignment alignment = null,
ui.Rect centerSlice = null,

double? width = null,
double? height = null,
Color color = null,
BlendMode colorBlendMode = BlendMode.None,
BlendMode colorBlendMode = BlendMode.srcOver,
BoxFit fit = BoxFit.none,
Alignment alignment = null,
ui.Rect centerSlice = null,

80
Assets/UIWidgets/Resources/UIWidgets_GUITexture.shader


Shader "UIWidgets/GUITexture"
{
Properties { _MainTex ("Texture", any) = "" {} }
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return 2.0f * tex2D(_MainTex, i.texcoord) * i.color;
}
ENDCG
SubShader {
Tags { "RenderType"="Overlay" }
Lighting Off
Blend One OneMinusSrcAlpha, One OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
SubShader {
Tags { "RenderType"="Overlay" }
Lighting Off
Blend One OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
Fallback off
}

3
Assets/UIWidgets/Resources/UIWidgets_GUITexture.shader.meta


fileFormatVersion: 2
guid: ea02b3553b38477c85b9ca45949cc85c
timeCreated: 1544158153

225
Assets/UIWidgets/Resources/UIWidgets_canvas.shader


Shader "UIWidgets/canvas"
{
Properties {
_SrcBlend("_SrcBlend", Int) = 1 // One
_DstBlend("_DstBlend", Int) = 10 // OneMinusSrcAlpha
}
CGINCLUDE
float2 _viewSize;
float4x4 _paintMat;
float4 _innerCol;
float4 _outerCol;
float2 _extent;
float _radius;
float _feather;
sampler2D _tex;
struct appdata_t {
float4 vertex : POSITION;
float2 tcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
float2 ftcoord : TEXCOORD0;
float2 fpos : TEXCOORD1;
};
float sdroundrect (float2 pt, float2 ext, float rad) {
float2 ext2 = ext - float2(rad, rad);
float2 d = abs(pt) - ext2;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - rad;
}
#pragma vertex vert
v2f vert (appdata_t v) {
v2f o;
o.ftcoord = v.tcoord;
o.fpos = v.vertex;
o.vertex = float4(2.0 * v.vertex.x / _viewSize.x - 1.0, 2.0 * v.vertex.y / _viewSize.y - 1.0, 0, 1);
return o;
}
fixed4 frag (v2f i) : SV_Target {
float2 pt = (mul(_paintMat, float3(i.fpos, 1.0))).xy;
float d = clamp((sdroundrect(pt, _extent, _radius) + _feather * 0.5) / _feather, 0.0, 1.0);
float4 color = lerp(_innerCol, _outerCol, d);
return color;
}
fixed4 frag_stencil (v2f i) : SV_Target {
return float4(0, 0, 0, 0);
}
fixed4 frag_tex (v2f i) : SV_Target {
float4 color = tex2D(_tex, i.ftcoord);
color = color * _innerCol; // tint color
color = float4(color.xyz * color.w, color.w);
return color;
}
fixed4 frag_texrt (v2f i) : SV_Target {
float4 color = tex2D(_tex, i.ftcoord);
color = color * _innerCol; // tint color
color = float4(color.xyz * _innerCol.w, color.w);
return color;
}
fixed4 frag_texfont (v2f i) : SV_Target {
float4 color = tex2D(_tex, i.ftcoord);
color = float4(1, 1, 1, color.w) * _innerCol; // tint color
color = float4(color.xyz * color.w, color.w);
return color;
}
ENDCG
SubShader {
ZTest Always
ZWrite Off
Blend [_SrcBlend] [_DstBlend]
Pass { // 0, fill pass 0
Cull Off
ColorMask 0
Stencil {
Ref 128
CompFront Equal
CompBack Equal
ReadMask 128
WriteMask 127
PassFront IncrWrap
PassBack DecrWrap
}
CGPROGRAM
#pragma fragment frag_stencil
ENDCG
}
Pass { // 1, fill pass 1
Stencil {
Ref 0
Comp NotEqual
ReadMask 127
WriteMask 127
Pass Zero
}
CGPROGRAM
#pragma fragment frag
ENDCG
}
Pass { // 2, convex fill
Stencil {
Ref 128
Comp Equal
}
CGPROGRAM
#pragma fragment frag
ENDCG
}
Pass { // 3, stroke pass 0
Stencil {
Ref 128
Comp Equal
Pass IncrSat
}
CGPROGRAM
#pragma fragment frag
ENDCG
}
Pass { // 4, stroke pass 1
ColorMask 0
Stencil {
Ref 0
Comp NotEqual
ReadMask 127
WriteMask 127
Pass Zero
}
CGPROGRAM
#pragma fragment frag_stencil
ENDCG
}
Pass { // 5, texture pass 0
Stencil {
Ref 128
Comp Equal
}
CGPROGRAM
#pragma fragment frag_tex
ENDCG
}
Pass { // 6, render texture pass 0
Stencil {
Ref 128
Comp Equal
}
CGPROGRAM
#pragma fragment frag_texrt
ENDCG
}
Pass { // 7, stencil clear
ColorMask 0
Stencil {
Ref 128
Pass Replace
}
CGPROGRAM
#pragma fragment frag_stencil
ENDCG
}
Pass { // 8, stencil intersect 0
Cull Off
ColorMask 0
Stencil {
WriteMask 127
PassFront IncrWrap
PassBack DecrWrap
}
CGPROGRAM
#pragma fragment frag_stencil
ENDCG
}
Pass { // 9, stencil intersect 1
ColorMask 0
Stencil {
Ref 128
Comp Less
Pass Replace
Fail Zero
}
CGPROGRAM
#pragma fragment frag_stencil
ENDCG
}
Pass { // 10, font texture pass 0
Stencil {
Ref 128
Comp Equal
}
CGPROGRAM
#pragma fragment frag_texfont
ENDCG
}
}
}

3
Assets/UIWidgets/Resources/UIWidgets_canvas.shader.meta


fileFormatVersion: 2
guid: baf507ab371c4f4c9eb9ce70a004ba0d
timeCreated: 1543832597

92
Assets/UIWidgets/editor/rasterizer.cs


using System;
using UIWidgets.flow;
using UIWidgets.foundation;
namespace UIWidgets.editor {
public class Rasterizer {
Surface _surface;
CompositorContext _compositorContext;
LayerTree _lastLayerTree;
Action _nextFrameCallback;
public Rasterizer() {
this._compositorContext = new CompositorContext();
}
public void setup(Surface surface) {
this._surface = surface;
this._compositorContext.onGrContextCreated();
}
public void teardown() {
this._compositorContext.onGrContextDestroyed();
this._surface = null;
this._lastLayerTree = null;
}
public LayerTree getLastLayerTree() {
return this._lastLayerTree;
}
public void drawLastLayerTree() {
if (this._lastLayerTree == null || this._surface == null) {
return;
}
this._drawToSurface(this._lastLayerTree);
}
public void draw(LayerTree layerTree) {
this._doDraw(layerTree);
}
public void setNextFrameCallback(Action callback) {
this._nextFrameCallback = callback;
}
public CompositorContext getCompositorContext() {
return this._compositorContext;
}
void _doDraw(LayerTree layerTree) {
if (layerTree == null || this._surface == null) {
return;
}
if (this._drawToSurface(layerTree)) {
this._lastLayerTree = layerTree;
}
}
bool _drawToSurface(LayerTree layerTree) {
D.assert(this._surface != null);
var frame = this._surface.acquireFrame(layerTree.frameSize, layerTree.devicePixelRatio);
if (frame == null) {
return false;
}
var canvas = frame.getCanvas();
using (var compositorFrame = this._compositorContext.acquireFrame(canvas)) {
if (compositorFrame != null && compositorFrame.raster(layerTree, false)) {
frame.submit();
this._fireNextFrameCallbackIfPresent();
return true;
}
return false;
}
}
void _fireNextFrameCallbackIfPresent() {
if (this._nextFrameCallback == null) {
return;
}
var callback = this._nextFrameCallback;
this._nextFrameCallback = null;
callback();
}
}
}

3
Assets/UIWidgets/editor/rasterizer.cs.meta


fileFormatVersion: 2
guid: 21e090dc4e194f588fac14d963f8e2ff
timeCreated: 1543285616

174
Assets/UIWidgets/editor/surface.cs


using System;
using UIWidgets.foundation;
using UIWidgets.ui;
using UnityEngine;
using Canvas = UIWidgets.ui.Canvas;
using Object = UnityEngine.Object;
using Rect = UnityEngine.Rect;
namespace UIWidgets.editor {
public delegate bool SubmitCallback(SurfaceFrame surfaceFrame, Canvas canvas);
public class SurfaceFrame : IDisposable {
bool _submitted;
readonly GrSurface _surface;
readonly SubmitCallback _submitCallback;
public SurfaceFrame(GrSurface surface, SubmitCallback submitCallback) {
this._surface = surface;
this._submitCallback = submitCallback;
}
public void Dispose() {
if (this._submitCallback != null && !this._submitted) {
this._submitCallback(this, null);
}
}
public Canvas getCanvas() {
return this._surface != null ? this._surface.getCanvas() : null;
}
public bool submit() {
if (this._submitted) {
return false;
}
this._submitted = this._performSubmit();
return this._submitted;
}
bool _performSubmit() {
if (this._submitCallback == null) {
return false;
}
if (this._submitCallback(this, this.getCanvas())) {
return true;
}
return false;
}
}
public interface Surface : IDisposable {
SurfaceFrame acquireFrame(Size size, double devicePixelRatio);
}
public class EditorWindowSurface : Surface {
static Material _guiTextureMat;
internal static Material _getGUITextureMat() {
if (_guiTextureMat) {
return _guiTextureMat;
}
var guiTextureShader = Shader.Find("UIWidgets/GUITexture");
if (guiTextureShader == null) {
throw new Exception("UIWidgets/GUITexture not found");
}
_guiTextureMat = new Material(guiTextureShader);
return _guiTextureMat;
}
GrSurface _surface;
public EditorWindowSurface() {
}
public SurfaceFrame acquireFrame(Size size, double devicePixelRatio) {
this._createOrUpdateRenderTexture(size, devicePixelRatio);
return new SurfaceFrame(this._surface,
(frame, canvas) => this._presentSurface(canvas));
}
public void Dispose() {
if (this._surface != null) {
this._surface.Dispose();
this._surface = null;
}
}
bool _presentSurface(Canvas canvas) {
if (canvas == null) {
return false;
}
this._surface.getCanvas().flush();
this._surface.getCanvas().reset();
var screenRect = new Rect(0, 0,
(float) (this._surface.size.width / this._surface.devicePixelRatio),
(float) (this._surface.size.height / this._surface.devicePixelRatio));
Graphics.DrawTexture(screenRect, this._surface.getRenderTexture(), _getGUITextureMat());
return true;
}
void _createOrUpdateRenderTexture(Size size, double devicePixelRatio) {
if (this._surface != null
&& this._surface.size == size
&& this._surface.devicePixelRatio == devicePixelRatio) {
return;
}
if (this._surface != null) {
this._surface.Dispose();
this._surface = null;
}
this._surface = new GrSurface(size, devicePixelRatio);
}
}
public class GrSurface : IDisposable {
public readonly Size size;
public readonly double devicePixelRatio;
RenderTexture _renderTexture;
Canvas _canvas;
public RenderTexture getRenderTexture() {
return this._renderTexture;
}
public Canvas getCanvas() {
if (this._canvas == null) {
this._canvas = new CommandBufferCanvas(this._renderTexture, (float) this.devicePixelRatio);
}
return this._canvas;
}
public GrSurface(Size size, double devicePixelRatio) {
this.size = size;
this.devicePixelRatio = devicePixelRatio;
var desc = new RenderTextureDescriptor(
(int) this.size.width, (int) this.size.height,
RenderTextureFormat.Default, 24) {
msaaSamples = QualitySettings.antiAliasing,
useMipMap = false,
autoGenerateMips = false,
};
this._renderTexture = new RenderTexture(desc);
}
public void Dispose() {
D.assert(this._renderTexture);
Object.DestroyImmediate(this._renderTexture);
this._renderTexture = null;
D.assert(this._canvas != null);
this._canvas = null;
}
}
}

3
Assets/UIWidgets/editor/surface.cs.meta


fileFormatVersion: 2
guid: a51bc6189001451e94e00094c384ff33
timeCreated: 1543283841

66
Assets/UIWidgets/flow/compositor_context.cs


using System;
using UIWidgets.editor;
using UIWidgets.ui;
namespace UIWidgets.flow {
public class CompositorContext {
public class ScopedFrame : IDisposable {
readonly CompositorContext _context;
readonly Canvas _canvas;
public ScopedFrame(CompositorContext context, Canvas canvas) {
this._context = context;
this._canvas = canvas;
this._context._beginFrame(this);
}
public CompositorContext context() {
return this._context;
}
public Canvas canvas() {
return this._canvas;
}
public bool raster(LayerTree layerTree, bool ignoreRasterCache) {
layerTree.preroll(this, ignoreRasterCache);
layerTree.paint(this);
return true;
}
public void Dispose() {
this._context._endFrame(this);
}
}
readonly RasterCache _rasterCache;
public CompositorContext() {
this._rasterCache = new RasterCache();
}
public ScopedFrame acquireFrame(Canvas canvas) {
return new ScopedFrame(this, canvas);
}
public void onGrContextCreated() {
this._rasterCache.clear();
}
public void onGrContextDestroyed() {
this._rasterCache.clear();
}
public RasterCache rasterCache() {
return this._rasterCache;
}
void _beginFrame(ScopedFrame frame) {
}
void _endFrame(ScopedFrame frame) {
this._rasterCache.sweepAfterFrame();
}
}
}

3
Assets/UIWidgets/flow/compositor_context.cs.meta


fileFormatVersion: 2
guid: a0850468c2b64e86800b95b9bb3fb75c
timeCreated: 1543221797

46
Assets/UIWidgets/flow/layer_tree.cs


using UIWidgets.ui;
using UnityEngine;
namespace UIWidgets.flow {
public class LayerTree {
Layer _rootLayer;
public Layer rootLayer {
get { return this._rootLayer; }
set { this._rootLayer = value; }
}
Size _frameSize;
public Size frameSize {
get { return this._frameSize; }
set { this._frameSize = value; }
}
double _devicePixelRatio;
public double devicePixelRatio {
get { return this._devicePixelRatio; }
set { this._devicePixelRatio = value; }
}
public void preroll(CompositorContext.ScopedFrame frame, bool ignoreRasterCache = false) {
var prerollContext = new PrerollContext {
rasterCache = ignoreRasterCache ? null : frame.context().rasterCache(),
devicePixelRatio = frame.canvas().getDevicePixelRatio()
};
this._rootLayer.preroll(prerollContext, Matrix3.I());
}
public void paint(CompositorContext.ScopedFrame frame) {
var paintContext = new PaintContext {
canvas = frame.canvas(),
};
if (this._rootLayer.needsPainting) {
this._rootLayer.paint(paintContext);
}
}
}
}

3
Assets/UIWidgets/flow/layer_tree.cs.meta


fileFormatVersion: 2
guid: bdfca7356538435ca9ff0344640fc5c0
timeCreated: 1543215909

1001
Assets/UIWidgets/ui/matrix.cs
文件差异内容过多而无法显示
查看文件

3
Assets/UIWidgets/ui/matrix.cs.meta


fileFormatVersion: 2
guid: a19f4ef042264cc0a0f98d27ed41d3f2
timeCreated: 1541066625

275
Assets/UIWidgets/ui/painting/canvas_clip.cs


using System.Collections.Generic;
using System.Linq;
using UIWidgets.foundation;
using UnityEngine;
namespace UIWidgets.ui {
internal class ClipElement {
public readonly int saveCount;
public readonly Mesh mesh;
public readonly bool convex;
public readonly bool isRect;
public Rect rect { get; private set; }
uint _genId;
bool _isIntersectionOfRects;
Rect _bound;
public ClipElement(int saveCount, Path path, float[] xform, float devicePixelRatio) {
this.saveCount = saveCount;
var pathCache = path.flatten(xform, devicePixelRatio);
this.mesh = pathCache.getFillMesh(out this.convex);
var vertices = this.mesh.vertices;
if (this.convex && vertices.Length == 4 &&
(Mathf.Abs(vertices[0].x - vertices[1].x) < 1e-6 && Mathf.Abs(vertices[1].y - vertices[2].y) < 1e-6 &&
Mathf.Abs(vertices[2].x - vertices[3].x) < 1e-6 && Mathf.Abs(vertices[3].y - vertices[0].y) < 1e-6 ||
Mathf.Abs(vertices[0].y - vertices[1].y) < 1e-6 && Mathf.Abs(vertices[1].x - vertices[2].x) < 1e-6 &&
Mathf.Abs(vertices[2].y - vertices[3].y) < 1e-6 && Mathf.Abs(vertices[3].x - vertices[0].x) < 1e-6)) {
var minx = Mathf.Min(vertices[0].x, vertices[1].x, vertices[2].x, vertices[3].x);
var miny = Mathf.Min(vertices[0].y, vertices[1].y, vertices[2].y, vertices[3].y);
var maxx = Mathf.Max(vertices[0].x, vertices[1].x, vertices[2].x, vertices[3].x);
var maxy = Mathf.Max(vertices[0].y, vertices[1].y, vertices[2].y, vertices[3].y);
this.isRect = true;
this.rect = Rect.fromLTRB(minx, miny, maxx, maxy);
} else {
this.isRect = false;
this.rect = null;
}
}
public void setRect(Rect rect) {
D.assert(ClipStack.invalidGenID != this._genId);
D.assert(this.isRect && this.rect.contains(rect));
this.rect = rect;
}
public void setEmpty() {
this._genId = ClipStack.emptyGenID;
this._isIntersectionOfRects = false;
this._bound = Rect.zero;
}
public void updateBoundAndGenID(ClipElement prior) {
this._genId = ClipStack.getNextGenID();
this._isIntersectionOfRects = false;
if (this.isRect) {
this._bound = this.rect;
if (prior == null || prior.isIntersectionOfRects()) {
this._isIntersectionOfRects = true;
}
} else {
this._bound = this.mesh.getBounds();
}
if (prior != null) {
this._bound = this._bound.intersect(prior.getBound());
}
if (this._bound.isEmpty) {
this.setEmpty();
}
}
public bool isEmpty() {
D.assert(ClipStack.invalidGenID != this._genId);
return this.getGenID() == ClipStack.emptyGenID;
}
public Rect getBound() {
D.assert(ClipStack.invalidGenID != this._genId);
return this._bound;
}
public bool isIntersectionOfRects() {
D.assert(ClipStack.invalidGenID != this._genId);
return this._isIntersectionOfRects;
}
public uint getGenID() {
D.assert(ClipStack.invalidGenID != this._genId);
return this._genId;
}
bool _convexContains(float x, float y) {
if (this.mesh.vertexCount <= 2) {
return false;
}
for (var i = 0; i < this.mesh.vertexCount; i++) {
var p0 = this.mesh.vertices[i];
var p1 = this.mesh.vertices[i == this.mesh.vertexCount - 1 ? 0 : i + 1];
if (PathUtils.triarea2(p0.x, p0.y, p1.x, p1.y, x, y) < 0.0f) {
return false;
}
}
return true;
}
public bool contains(Rect rect) {
if (this.isRect) {
return this.rect.contains(rect);
}
if (this.convex) {
return this._convexContains((float) rect.left, (float) rect.top) &&
this._convexContains((float) rect.left, (float) rect.bottom) &&
this._convexContains((float) rect.right, (float) rect.top) &&
this._convexContains((float) rect.right, (float) rect.bottom);
}
return false;
}
}
internal class ClipStack {
static uint _genId = wideOpenGenID;
public static uint getNextGenID() {
return ++_genId;
}
public const uint invalidGenID = 0;
public const uint emptyGenID = 1;
public const uint wideOpenGenID = 2;
public readonly List<ClipElement> stack = new List<ClipElement>();
Rect _bound;
int _saveCount;
public void save() {
this._saveCount++;
}
public void restore() {
this._saveCount--;
this._restoreTo(this._saveCount);
}
void _restoreTo(int saveCount) {
while (this.stack.Count > 0) {
var element = this.stack[this.stack.Count - 1];
if (element.saveCount <= saveCount) {
break;
}
this.stack.RemoveAt(this.stack.Count - 1);
}
}
public void clipPath(Path path, float[] xform, float devicePixelRatio) {
var element = new ClipElement(this._saveCount, path, xform, devicePixelRatio);
this._pushElement(element);
}
void _pushElement(ClipElement element) {
ClipElement prior = this.stack.LastOrDefault();
if (prior != null) {
if (prior.isEmpty()) {
return;
}
if (prior.saveCount == this._saveCount) {
// can not update prior if it's cross save count.
if (prior.isRect && element.isRect) {
var isectRect = prior.rect.intersect(element.rect);
if (isectRect.isEmpty) {
prior.setEmpty();
return;
}
prior.setRect(isectRect);
var priorprior = this.stack.Count > 1 ? this.stack[this.stack.Count - 2] : null;
prior.updateBoundAndGenID(priorprior);
return;
}
if (!prior.getBound().overlaps(element.getBound())) {
prior.setEmpty();
return;
}
}
}
this.stack.Add(element);
element.updateBoundAndGenID(prior);
}
public void getBounds(out Rect bound, out bool isIntersectionOfRects) {
if (this.stack.Count == 0) {
bound = null;
isIntersectionOfRects = false;
return;
}
var element = this.stack.Last();
bound = element.getBound();
isIntersectionOfRects = element.isIntersectionOfRects();
}
}
internal class ReducedClip {
public readonly Rect scissor;
public readonly List<ClipElement> maskElements = new List<ClipElement>();
public bool isEmpty() {
return this.scissor != null && this.scissor.isEmpty;
}
public uint maskGenID() {
var element = this.maskElements.LastOrDefault();
if (element == null) {
return ClipStack.wideOpenGenID;
}
return element.getGenID();
}
public ReducedClip(ClipStack stack, Rect layerBounds, Rect queryBounds) {
Rect stackBounds;
bool iior;
stack.getBounds(out stackBounds, out iior);
if (stackBounds == null) {
this.scissor = layerBounds;
return;
}
stackBounds = layerBounds.intersect(stackBounds);
if (iior) {
this.scissor = stackBounds;
return;
}
queryBounds = stackBounds.intersect(queryBounds);
if (queryBounds.isEmpty) {
this.scissor = Rect.zero;
return;
}
this.scissor = queryBounds;
this._walkStack(stack, this.scissor);
}
void _walkStack(ClipStack stack, Rect queryBounds) {
foreach (var element in stack.stack) {
if (element.isRect) {
continue;
}
if (element.contains(queryBounds)) {
continue;
}
this.maskElements.Add(element);
}
}
}
}

3
Assets/UIWidgets/ui/painting/canvas_clip.cs.meta


fileFormatVersion: 2
guid: b1a2d4d35a8f41fbb664c641ded2c5d0
timeCreated: 1545176084

1001
Assets/UIWidgets/ui/painting/path.cs
文件差异内容过多而无法显示
查看文件

3
Assets/UIWidgets/ui/painting/path.cs.meta


fileFormatVersion: 2
guid: ee8aadd0031b4e7cb981f68d2ee9dd60
timeCreated: 1545295393

50
Assets/UIWidgets/Resources/UIWidgets_CG.cginc


uniform float4x4 UIWidgets_GUIClipMatrix;
uniform float4 UIWidgets_GUIClipRect;
uniform float4 UIWidgets_GUIClipRectRadius;
half __getCornerAlpha (float2 p, float2 center, float radius, float pixelScale) {
float2 v = p - center;
float pixelCenterDist = length(v);
float outerDist = (pixelCenterDist - radius) * pixelScale;
half outerDistAlpha = saturate(0.5f - outerDist);
return outerDistAlpha;
}
float getClipAlpha (float2 p, float pixelScale) {
bool xIsLeft = (p.x - UIWidgets_GUIClipRect[0] - UIWidgets_GUIClipRect[2] / 2.0f) <= 0.0f;
bool yIsTop = (p.y - UIWidgets_GUIClipRect[1] - UIWidgets_GUIClipRect[3] / 2.0f) <= 0.0f;
int radiusIndex = 0;
if (xIsLeft) {
radiusIndex = yIsTop ? 0 : 3;
} else {
radiusIndex = yIsTop ? 1 : 2;
}
float activeRadius = UIWidgets_GUIClipRectRadius[radiusIndex];
float2 center = float2(UIWidgets_GUIClipRect[0] + activeRadius, UIWidgets_GUIClipRect[1] + activeRadius);
if (!xIsLeft) {
center.x = (UIWidgets_GUIClipRect[0] + UIWidgets_GUIClipRect[2] - activeRadius);
}
if (!yIsTop) {
center.y = (UIWidgets_GUIClipRect[1] + UIWidgets_GUIClipRect[3] - activeRadius);
}
float clipAlpha = 1.0f;
bool isInCorner = (xIsLeft ? p.x <= center.x : p.x >= center.x) && (yIsTop ? p.y <= center.y : p.y >= center.y);
float cornerAlpha = isInCorner ? __getCornerAlpha(p, center, activeRadius, pixelScale) : 1.0f;
clipAlpha *= cornerAlpha;
bool isInRect =
p.x >= UIWidgets_GUIClipRect[0]
&& p.x <= UIWidgets_GUIClipRect[0] + UIWidgets_GUIClipRect[2]
&& p.y >= UIWidgets_GUIClipRect[1]
&& p.y <= UIWidgets_GUIClipRect[1] + UIWidgets_GUIClipRect[3];
float rectAlpha = isInRect ? 1.0f : 0.0f;
clipAlpha *= rectAlpha;
return clipAlpha;
}

3
Assets/UIWidgets/Resources/UIWidgets_CG.cginc.meta


fileFormatVersion: 2
guid: 511bc0855fde4327992a4074f1d1ac42
timeCreated: 1534670219

162
Assets/UIWidgets/Resources/UIWidgets_GUIRoundedRect.shader


Shader "UIWidgets/GUIRoundedRect"
{
Properties {
_MainTex("Texture", any) = "white" {}
_SrcBlend("SrcBlend", Int) = 5 // SrcAlpha
_DstBlend("DstBlend", Int) = 10 // OneMinusSrcAlpha
}
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#pragma target 2.5
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 clipUV : TEXCOORD1;
float4 pos : TEXCOORD2;
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform bool _ManualTex2SRGB;
uniform int _SrcBlend;
uniform float _Rect[4];
uniform float UIWidgets_BorderWidth[4];
uniform float UIWidgets_CornerRadius[4];
#include "UIWidgets_CG.cginc"
half getCornerAlpha (float2 p, float2 center, float borderWidth1, float borderWidth2, float radius, float pixelScale) {
float2 v = p - center;
float outerDist = (length(v) - radius) * pixelScale;
half outerDistAlpha = saturate(0.5f - outerDist);
bool hasBorder = borderWidth1 > 0.0f || borderWidth2 > 0.0f;
float a = radius - borderWidth1;
float b = radius - borderWidth2;
v.y *= a / b;
half rawDist = (length(v) - a) * pixelScale;
half alpha = saturate(0.5f + rawDist);
half innerDistAlpha = (hasBorder && a > 0 && b > 0) ? alpha : 1.0f;
return (outerDistAlpha == 1.0f) ? innerDistAlpha : outerDistAlpha;
}
bool isPointInside (float2 p, float4 rect) {
return p.x >= rect.x && p.x <= (rect.x+rect.z) && p.y >= rect.y && p.y <= (rect.y+rect.w);
}
v2f vert (appdata_t v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
float3 eyePos = UnityObjectToViewPos(v.vertex);
o.clipUV = mul(UIWidgets_GUIClipMatrix, float4(eyePos.xy, 0, 1.0));
o.pos = v.vertex;
return o;
}
fixed4 frag (v2f i) : SV_Target {
half4 col = tex2D(_MainTex, i.texcoord);
if (_ManualTex2SRGB) {
col.rgb = LinearToGammaSpace(col.rgb);
}
col *= i.color;
float2 p = i.pos.xy;
bool xIsLeft = (p.x - _Rect[0] - _Rect[2] / 2.0f) <= 0.0f;
bool yIsTop = (p.y - _Rect[1] - _Rect[3] / 2.0f) <= 0.0f;
float bw1 = UIWidgets_BorderWidth[0];
float bw2 = UIWidgets_BorderWidth[1];
int radiusIndex = 0;
if (xIsLeft) {
radiusIndex = yIsTop ? 0 : 3;
} else {
radiusIndex = yIsTop ? 1 : 2;
}
float activeRadius = UIWidgets_CornerRadius[radiusIndex];
float2 center = float2(_Rect[0] + activeRadius, _Rect[1] + activeRadius);
if (!xIsLeft) {
center.x = (_Rect[0] + _Rect[2] - activeRadius);
bw1 = UIWidgets_BorderWidth[2];
}
if (!yIsTop) {
center.y = (_Rect[1] + _Rect[3] - activeRadius);
bw2 = UIWidgets_BorderWidth[3];
}
bool isInCorner = (xIsLeft ? p.x <= center.x : p.x >= center.x) && (yIsTop ? p.y <= center.y : p.y >= center.y);
float pixelScale = 1.0f / abs(ddx(i.pos.x));
float cornerAlpha = isInCorner ? getCornerAlpha(p, center, bw1, bw2, activeRadius, pixelScale) : 1.0f;
col.a *= cornerAlpha;
float4 centerRect = float4(
_Rect[0] + UIWidgets_BorderWidth[0],
_Rect[1] + UIWidgets_BorderWidth[1],
_Rect[2] - (UIWidgets_BorderWidth[0] + UIWidgets_BorderWidth[2]),
_Rect[3] - (UIWidgets_BorderWidth[1] + UIWidgets_BorderWidth[3]));
bool isPointInCenter = isPointInside(p, centerRect);
half middleMask = isPointInCenter ? 0.0f : 1.0f;
bool hasBorder = UIWidgets_BorderWidth[0] > 0 || UIWidgets_BorderWidth[1] > 0 || UIWidgets_BorderWidth[2] > 0 || UIWidgets_BorderWidth[3] > 0;
float borderAlpha = hasBorder ? (isInCorner ? 1.0f : middleMask) : 1.0f;
col.a *= borderAlpha;
pixelScale = 1.0f / abs(ddx(i.clipUV.x));
float clipAlpha = getClipAlpha(i.clipUV, pixelScale);
col.a *= clipAlpha;
// If the source blend is not SrcAlpha (default) we need to multiply the color by the rounded corner
// alpha factors for clipping, since it will not be done at the blending stage.
if (_SrcBlend != 5) { // 5 SrcAlpha
col.rgb *= cornerAlpha * borderAlpha * clipAlpha;
}
return col;
}
ENDCG
SubShader {
Blend [_SrcBlend] [_DstBlend], One OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
SubShader {
Blend [_SrcBlend] [_DstBlend]
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
FallBack "UIWidgets/GUITextureClip"
}

3
Assets/UIWidgets/Resources/UIWidgets_GUIRoundedRect.shader.meta


fileFormatVersion: 2
guid: 84dfa8cbdc4a4a85a2d4eb117458c52e
timeCreated: 1534572810

92
Assets/UIWidgets/Resources/UIWidgets_GUITextureClip.shader


Shader "UIWidgets/GUITextureClip"
{
Properties {
_MainTex ("Texture", Any) = "white" {}
}
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 clipUV : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform bool _ManualTex2SRGB;
#include "UIWidgets_CG.cginc"
v2f vert (appdata_t v) {
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
float3 eyePos = UnityObjectToViewPos(v.vertex);
o.clipUV = mul(UIWidgets_GUIClipMatrix, float4(eyePos.xy, 0, 1.0));
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target {
fixed4 colTex = tex2D(_MainTex, i.texcoord);
if (_ManualTex2SRGB) {
colTex.rgb = LinearToGammaSpace(colTex.rgb);
}
fixed4 col = colTex * i.color;
float pixelScale = 1.0f / abs(ddx(i.clipUV.x));
col.a *= getClipAlpha(i.clipUV, pixelScale);
return col;
}
ENDCG
SubShader {
Tags { "ForceSupported" = "True" }
Lighting Off
Blend SrcAlpha OneMinusSrcAlpha, One One
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
SubShader {
Tags { "ForceSupported" = "True" }
Lighting Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
}

3
Assets/UIWidgets/Resources/UIWidgets_GUITextureClip.shader.meta


fileFormatVersion: 2
guid: e811bda0727841a097b27e41a45067eb
timeCreated: 1534572896

119
Assets/UIWidgets/Resources/UIWidgets_ShadowRect.shader


Shader "UIWidgets/ShadowRect"
{
Properties {
_MainTex("Texture", any) = "white" {}
_SrcBlend("SrcBlend", Int) = 5 // SrcAlpha
_DstBlend("DstBlend", Int) = 10 // OneMinusSrcAlpha
}
CGINCLUDE
#pragma vertex vert
#pragma fragment frag
#pragma target 2.5
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 clipUV : TEXCOORD1;
float4 pos : TEXCOORD2;
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform bool _ManualTex2SRGB;
uniform int _SrcBlend;
uniform float _Rect[4];
uniform float UIWidgets_sigma;
#include "UIWidgets_CG.cginc"
// http://madebyevan.com/shaders/fast-rounded-rectangle-shadows/
float4 erf (float4 x) {
float4 s = sign(x);
float4 a = abs(x);
x = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
x *= x;
return s - s / (x * x);
}
float UIWidgets_boxShadow (float2 lower, float2 upper, float2 pos, float sigma) {
float4 query = float4((lower - pos).xy, (upper - pos).xy);
float4 integral = erf(query * (sqrt(0.5) / sigma)) * 0.5 + 0.5;
return (integral.z - integral.x) * (integral.w - integral.y);
}
v2f vert (appdata_t v) {
float3 eyePos = UnityObjectToViewPos(v.vertex);
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
o.clipUV = mul(UIWidgets_GUIClipMatrix, float4(eyePos.xy, 0, 1.0));
o.pos = v.vertex;
return o;
}
fixed4 frag (v2f i) : SV_Target {
half4 col = tex2D(_MainTex, i.texcoord);
if (_ManualTex2SRGB) {
col.rgb = LinearToGammaSpace(col.rgb);
}
col *= i.color;
float2 p = i.pos.xy;
float shadowAlpha = UIWidgets_boxShadow(
float2(_Rect[0] + 3 * UIWidgets_sigma, _Rect[1] + 3 * UIWidgets_sigma),
float2(_Rect[0] + _Rect[2] - 3 * UIWidgets_sigma, _Rect[1] + _Rect[3] - 3 * UIWidgets_sigma),
p, UIWidgets_sigma);
col.a *= shadowAlpha;
float pixelScale = 1.0f / abs(ddx(i.clipUV.x));
float clipAlpha = getClipAlpha(i.clipUV, pixelScale);
col.a *= clipAlpha;
// If the source blend is not SrcAlpha (default) we need to multiply the color by the rounded corner
// alpha factors for clipping, since it will not be done at the blending stage.
if (_SrcBlend != 5) { // 5 SrcAlpha
col.rgb *= shadowAlpha * clipAlpha;
}
return col;
}
ENDCG
SubShader {
Blend [_SrcBlend] [_DstBlend], One OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
SubShader {
Blend [_SrcBlend] [_DstBlend]
Cull Off
ZWrite Off
ZTest Always
Pass {
CGPROGRAM
ENDCG
}
}
FallBack "UIWidgets/GUITextureClip"
}

63
Assets/UIWidgets/Resources/UIWidgets_2DHandlesLines.shader


Shader "UIWidgets/2D Handles Lines" {
Properties
{
_MainTex ("Texture", Any) = "white" {}
_HandleZTest ("_HandleZTest", Int) = 8 // Always
}
SubShader {
Tags { "ForceSupported" = "True" }
Lighting Off
Blend SrcAlpha OneMinusSrcAlpha
Cull Off
ZWrite Off
ZTest [_HandleZTest]
BindChannels {
Bind "vertex", vertex
Bind "color", color
Bind "TexCoord", texcoord
}
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#include "UnityCG.cginc"
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 uv : TEXCOORD0;
float4 clipUV : TEXCOORD1;
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
#include "UIWidgets_CG.cginc"
v2f vert (float4 vertex : POSITION, float2 uv : TEXCOORD0, float4 color : COLOR0)
{
v2f o;
o.vertex = UnityObjectToClipPos(vertex);
float3 screenUV = UnityObjectToViewPos(vertex);
o.clipUV = mul(UIWidgets_GUIClipMatrix, float4(screenUV.xy, 0, 1.0));
o.color = color;
o.uv = TRANSFORM_TEX(uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv) * i.color;
float pixelScale = 1.0f / abs(ddx(i.clipUV.x));
col.a *= getClipAlpha(i.clipUV, pixelScale);
return col;
}
ENDCG
}
}
}

3
Assets/UIWidgets/Resources/UIWidgets_2DHandlesLines.shader.meta


fileFormatVersion: 2
guid: 81e78a346e6a4cad9c4fcc54da649074
timeCreated: 1534472967

9
Assets/UIWidgets/Resources/UIWidgets_ShadowRect.shader.meta


fileFormatVersion: 2
guid: 1f7a328e0f36042d89a5781d0a2b9cdf
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

70
Assets/UIWidgets/Resources/UIWidgets_Text.shader


Shader "UIWidgets/Text Shader" {
Properties {
_MainTex ("Font Texture", 2D) = "white" {}
_Color ("Text Color", Color) = (1,1,1,1)
}
SubShader {
Tags {
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
}
Lighting Off Cull Off ZTest Always ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 clipUV : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform fixed4 _Color;
#include "UIWidgets_CG.cginc"
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
float3 eyePos = UnityObjectToViewPos(v.vertex);
o.color = v.color * _Color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
o.clipUV = mul(UIWidgets_GUIClipMatrix, float4(eyePos.xy, 0, 1.0));
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = i.color;
col.a *= tex2D(_MainTex, i.texcoord).a;
float pixelScale = 1.0f / abs(ddx(i.clipUV.x));
col.a *= getClipAlpha(i.clipUV, pixelScale);
return col;
}
ENDCG
}
}
}

3
Assets/UIWidgets/Resources/UIWidgets_Text.shader.meta


fileFormatVersion: 2
guid: 3d9aebae673b434491eb311fc9d0df0f
timeCreated: 1536033642

3
Assets/UIWidgets/flow/layer_builder.cs.meta


fileFormatVersion: 2
guid: f7ca7d815141405a85b3a2de247eb1dc
timeCreated: 1534391496

107
Assets/UIWidgets/flow/layer_builder.cs


using System.Collections.Generic;
using UIWidgets.foundation;
using UIWidgets.painting;
using UIWidgets.ui;
using Matrix4x4 = UnityEngine.Matrix4x4;
namespace UIWidgets.flow {
public class LayerBuilder {
private ContainerLayer _rootLayer;
private ContainerLayer _currentLayer;
private readonly Stack<Rect> _cullRects = new Stack<Rect>();
public LayerBuilder() {
this._cullRects.Push(Rect.largest);
}
private void pushLayer(ContainerLayer layer, Rect cullRect) {
this._cullRects.Push(cullRect);
if (this._rootLayer == null) {
this._rootLayer = layer;
this._currentLayer = layer;
return;
}
if (this._currentLayer == null) {
return;
}
this._currentLayer.add(layer);
this._currentLayer = layer;
}
public Layer takeLayer() {
return this._rootLayer;
}
public void pop() {
if (this._currentLayer == null) {
return;
}
this._cullRects.Pop();
this._currentLayer = this._currentLayer.parent;
}
public void pushTransform(Matrix4x4 matrix) {
D.assert(matrix.determinant != 0.0);
Rect cullRect = Rect.largest;
if (!matrix.isPerspective()) {
cullRect = matrix.inverse.transformRect(this._cullRects.Peek());
}
var layer = new TransformLayer();
layer.transform = matrix;
this.pushLayer(layer, cullRect);
}
public void pushClipRect(Rect clipRect) {
Rect cullRect = clipRect.intersect(this._cullRects.Peek());
var layer = new ClipRectLayer();
layer.clipRect = clipRect;
this.pushLayer(layer, cullRect);
}
public void pushClipRRect(RRect clipRRect) {
Rect cullRect = clipRRect.outerRect.intersect(this._cullRects.Peek());
var layer = new ClipRRectLayer();
layer.clipRRect = clipRRect;
this.pushLayer(layer, cullRect);
}
public void pushOpacity(int alpha) {
var layer = new OpacityLayer();
layer.alpha = alpha;
this.pushLayer(layer, this._cullRects.Peek());
}
public void addPicture(Offset offset, Picture picture, bool isComplex, bool willChange) {
if (this._currentLayer == null) {
return;
}
Rect pictureRect = picture.paintBounds;
pictureRect = pictureRect.shift(offset);
if (!pictureRect.overlaps(this._cullRects.Peek())) {
return;
}
var layer = new PictureLayer();
layer.offset = offset;
layer.picture = picture;
layer.isComplex = isComplex;
layer.willChange = willChange;
this._currentLayer.add(layer);
}
}
}
正在加载...
取消
保存