display_list.dart 4.8 KB
Newer Older
1

2
import 'dart:async';
3
import 'dart:sky' as sky;
4
import 'dart:typed_data';
5

6
import 'package:sky/widgets/basic.dart';
A
Adam Barth 已提交
7 8
import 'package:sky/rendering/box.dart';
import 'package:sky/rendering/object.dart';
9

10 11
import 'harness.dart';

12 13
typedef void Logger (String s);

14 15
class TestPaintingCanvas extends PaintingCanvas {
  TestPaintingCanvas(sky.PictureRecorder recorder, Size size, this.logger, { this.indent: '' })
H
Hixie 已提交
16
    : size = size,
17
      super(recorder, Point.origin & size) {
18
    log("TestPaintingCanvas() constructor: ${size.width} x ${size.height}");
19 20 21
  }

  final String indent;
H
Hixie 已提交
22
  final Size size;
23 24 25 26 27 28 29 30 31 32

  Logger logger;
  void log(String s) {
    logger("${indent} ${s}");
  }

  void save() {
    log("save");
  }

33
  void saveLayer(Rect bounds, Paint paint) {
34
    log("saveLayer($bounds, $paint)");
35 36 37 38 39 40 41 42 43 44 45 46 47 48
  }

  void restore() {
    log("restore");
  }

  void translate(double dx, double dy) {
    log("translate($dx, $dy)");
  }

  void scale(double sx, double sy) {
    log("scale($sx, $sy)");
  }

49 50
  void rotate(double radians) {
    log("rotate($radians)");
51 52 53 54 55 56
  }

  void skew(double sx, double sy) {
    log("skew($sx, $sy)");
  }

57 58
  void concat(Float32List matrix4) {
    log("concat($matrix4)");
59 60
  }

61 62 63 64 65 66 67 68 69 70 71 72
  void clipRect(Rect rect) {
    log("clipRect($rect)");
  }

  void clipRRect(sky.RRect rrect) {
    log("clipRRect()");
  }

  void clipPath(Path path) {
    log("clipPath($path)");
  }

H
Hixie 已提交
73 74
  void drawLine(Point p1, Point p2, Paint paint) {
    log("drawLine($p1, $p2, $paint)");
75 76 77
  }

  void drawPicture(sky.Picture picture) {
78
    log("drawPicture($picture)");
79 80
  }

81
  void drawPaint(Paint paint) {
82
    log("drawPaint($paint)");
83 84
  }

85
  void drawRect(Rect rect, Paint paint) {
86
    log("drawRect($rect, $paint)");
87 88
  }

89
  void drawRRect(sky.RRect rrect, Paint paint) {
90
    log("drawRRect($rrect, $paint)");
91 92
  }

A
Adam Barth 已提交
93 94 95 96
  void drawDRRect(sky.RRect outer, sky.RRect inner, Paint paint) {
    log("drawDRRect($outer, $inner, $paint)");
  }

97
  void drawOval(Rect rect, Paint paint) {
98
    log("drawOval($rect, $paint)");
99 100
  }

H
Hixie 已提交
101 102
  void drawCircle(Point c, double radius, Paint paint) {
    log("drawCircle($c, $radius, $paint)");
103 104
  }

105
  void drawPath(Path path, Paint paint) {
106
    log("drawPath($path, $paint)");
107 108
  }

H
Hixie 已提交
109 110
  void drawImage(sky.Image image, Point p, Paint paint) {
    log("drawImage($image, $p, $paint)");
111 112
  }

113 114 115
  void drawImageRect(sky.Image image, sky.Rect src, sky.Rect dst, Paint paint) {
    log("drawImageRect($image, $src, $dst, paint)");
  }
116 117 118
}

class TestPaintingContext extends PaintingContext {
119 120 121
  TestPaintingContext(TestPaintingCanvas canvas) : super.forTesting(canvas);

  TestPaintingCanvas get canvas => super.canvas;
122

123
  void paintChild(RenderObject child, Point position) {
124 125 126
    canvas.log("paintChild ${child.runtimeType} at $position");
    TestPaintingCanvas childCanvas = new TestPaintingCanvas(new sky.PictureRecorder(), canvas.size, canvas.logger, indent: "${canvas.indent}  |");
    child.paint(new TestPaintingContext(childCanvas), position.toOffset());
127 128 129
  }
}

130
class TestRenderView extends RenderView {
131

132 133 134
  TestRenderView([ RenderBox child = null ]) : super(child: child) {
    print("TestRenderView enabled");
    attach();
H
Hixie 已提交
135
    rootConstraints = new ViewConstraints(size: new Size(800.0, 600.0)); // arbitrary figures
136
    scheduleInitialLayout();
137
    syncCheckFrame();
138 139 140 141 142 143 144 145 146 147
  }

  int frame = 0;

  String lastPaint = '';
  void log(String s) {
    lastPaint += "\n$s";
  }

  void paintFrame() {
H
Hixie 已提交
148
    RenderObject.debugDoingPaint = true;
149
    frame += 1;
150
    lastPaint = '';
151
    log("PAINT FOR FRAME #${frame} ----------------------------------------------");
152 153 154 155 156
    sky.PictureRecorder recorder = new sky.PictureRecorder();
    TestPaintingCanvas canvas = new TestPaintingCanvas(recorder, rootConstraints.size, log, indent: "${frame} |");
    TestPaintingContext context = new TestPaintingContext(canvas);

    paint(context, Offset.zero);
157
    recorder.endRecording();
158
    log("------------------------------------------------------------------------");
H
Hixie 已提交
159
    RenderObject.debugDoingPaint = false;
160 161
  }

162 163
  // TEST API:

164
  void syncCheckFrame() {
A
Adam Barth 已提交
165
    Component.flushBuild();
H
Hixie 已提交
166
    RenderObject.flushLayout();
167 168
    paintFrame();
    print(lastPaint); // TODO(ianh): figure out how to make this fit the unit testing framework better
169 170
  }

171 172 173 174
  Future checkFrame() {
    return new Future.microtask(syncCheckFrame);
  }

175
  void endTest() {
176
    notifyTestComplete("PAINTED $frame FRAMES");
177 178
  }

179
}
180 181

class TestApp extends App {
182
  TestApp({ this.builder });
183 184 185 186 187 188 189 190 191 192 193

  Function builder;

  Widget build() {
    return builder();
  }
}

class WidgetTester {
  TestRenderView renderView = new TestRenderView();

194
  Future test(Function builder, { int frameCount: 1 }) async {
195
    runApp(new TestApp(builder: builder), renderViewOverride: renderView);
196 197 198
    while (--frameCount != 0)
      await renderView.checkFrame();
    return await renderView.checkFrame();
199 200
  }

201 202
  void endTest() {
    renderView.endTest();
203 204
  }
}