| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'node.dart'; | 5 import 'node.dart'; |
| 6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
| 7 | 7 |
| 8 // ABSTRACT LAYOUT | 8 // ABSTRACT LAYOUT |
| 9 | 9 |
| 10 class ParentData { | 10 class ParentData { |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 | 233 |
| 234 void handlePointer(sky.PointerEvent event) { | 234 void handlePointer(sky.PointerEvent event) { |
| 235 // override this if you have a client, to hand it to the client | 235 // override this if you have a client, to hand it to the client |
| 236 // override this if you want to do anything with the pointer event | 236 // override this if you want to do anything with the pointer event |
| 237 } | 237 } |
| 238 | 238 |
| 239 // RenderNode subclasses are expected to have a method like the | 239 // RenderNode subclasses are expected to have a method like the |
| 240 // following (with the signature being whatever passes for coordinates | 240 // following (with the signature being whatever passes for coordinates |
| 241 // for this particular class): | 241 // for this particular class): |
| 242 // bool hitTest(HitTestResult result, { double x, double y }) { | 242 // bool hitTest(HitTestResult result, { double x, double y }) { |
| 243 // // If (x,y) is not inside this node, then return false. | 243 // // If (x,y) is not inside this node, then return false. (You |
| 244 // // can assume that the given coordinate is inside your |
| 245 // // dimensions. You only need to check this if you're an |
| 246 // // irregular shape, e.g. if you have a hole.) |
| 244 // // Otherwise: | 247 // // Otherwise: |
| 245 // // For each child that intersects x,y, in z-order starting from the top, | 248 // // For each child that intersects x,y, in z-order starting from the top, |
| 246 // // call hitTest() for that child, passing it /result/, and the coordinate
s | 249 // // call hitTest() for that child, passing it /result/, and the coordinate
s |
| 247 // // converted to the child's coordinate origin, and stop at the first chil
d | 250 // // converted to the child's coordinate origin, and stop at the first chil
d |
| 248 // // that returns true. | 251 // // that returns true. |
| 249 // // Then, add yourself to /result/, and return true. | 252 // // Then, add yourself to /result/, and return true. |
| 250 // } | 253 // } |
| 251 // You must not add yourself to /result/ if you return false. | 254 // You must not add yourself to /result/ if you return false. |
| 252 | 255 |
| 253 } | 256 } |
| 254 | 257 |
| 255 class HitTestResult { | 258 class HitTestResult { |
| 256 final List<RenderNode> path = new List<RenderNode>(); | 259 final List<RenderNode> path = new List<RenderNode>(); |
| 257 | 260 |
| 258 RenderNode get result => path.first; | 261 RenderNode get result => path.first; |
| 259 | 262 |
| 260 void add(RenderNode node) { | 263 void add(RenderNode node) { |
| 261 path.add(node); | 264 path.add(node); |
| 262 } | 265 } |
| 263 } | 266 } |
| 264 | 267 |
| 268 |
| 269 // GENERIC MIXIN FOR RENDER NODES WITH ONE CHILD |
| 270 |
| 265 abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> { | 271 abstract class RenderNodeWithChildMixin<ChildType extends RenderNode> { |
| 266 ChildType _child; | 272 ChildType _child; |
| 267 ChildType get child => _child; | 273 ChildType get child => _child; |
| 268 void set child (ChildType value) { | 274 void set child (ChildType value) { |
| 269 if (_child != null) | 275 if (_child != null) |
| 270 dropChild(_child); | 276 dropChild(_child); |
| 271 _child = value; | 277 _child = value; |
| 272 if (_child != null) | 278 if (_child != null) |
| 273 adoptChild(_child); | 279 adoptChild(_child); |
| 274 markNeedsLayout(); | 280 markNeedsLayout(); |
| 275 } | 281 } |
| 276 } | 282 } |
| 277 | 283 |
| 278 // GENERIC MIXIN FOR RENDER NODES THAT TAKE A LIST OF CHILDREN | 284 |
| 285 // GENERIC MIXIN FOR RENDER NODES WITH A LIST OF CHILDREN |
| 279 | 286 |
| 280 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { | 287 abstract class ContainerParentDataMixin<ChildType extends RenderNode> { |
| 281 ChildType previousSibling; | 288 ChildType previousSibling; |
| 282 ChildType nextSibling; | 289 ChildType nextSibling; |
| 283 void detachSiblings() { | 290 void detachSiblings() { |
| 284 if (previousSibling != null) { | 291 if (previousSibling != null) { |
| 285 assert(previousSibling.parentData is ContainerParentDataMixin<ChildType>); | 292 assert(previousSibling.parentData is ContainerParentDataMixin<ChildType>); |
| 286 assert(previousSibling != this); | 293 assert(previousSibling != this); |
| 287 assert(previousSibling.parentData.nextSibling == this); | 294 assert(previousSibling.parentData.nextSibling == this); |
| 288 previousSibling.parentData.nextSibling = nextSibling; | 295 previousSibling.parentData.nextSibling = nextSibling; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 assert(child.parentData is ParentDataType); | 430 assert(child.parentData is ParentDataType); |
| 424 return child.parentData.nextSibling; | 431 return child.parentData.nextSibling; |
| 425 } | 432 } |
| 426 | 433 |
| 427 } | 434 } |
| 428 | 435 |
| 429 | 436 |
| 430 // GENERIC BOX RENDERING | 437 // GENERIC BOX RENDERING |
| 431 // Anything that has a concept of x, y, width, height is going to derive from th
is | 438 // Anything that has a concept of x, y, width, height is going to derive from th
is |
| 432 | 439 |
| 440 class EdgeDims { |
| 441 // used for e.g. padding |
| 442 const EdgeDims(this.top, this.right, this.bottom, this.left); |
| 443 final double top; |
| 444 final double right; |
| 445 final double bottom; |
| 446 final double left; |
| 447 operator ==(EdgeDims other) => (top == other.top) || |
| 448 (right == other.right) || |
| 449 (bottom == other.bottom) || |
| 450 (left == other.left); |
| 451 } |
| 452 |
| 433 class BoxConstraints { | 453 class BoxConstraints { |
| 434 const BoxConstraints({ | 454 const BoxConstraints({ |
| 435 this.minWidth: 0.0, | 455 this.minWidth: 0.0, |
| 436 this.maxWidth: double.INFINITY, | 456 this.maxWidth: double.INFINITY, |
| 437 this.minHeight: 0.0, | 457 this.minHeight: 0.0, |
| 438 this.maxHeight: double.INFINITY}); | 458 this.maxHeight: double.INFINITY}); |
| 439 | 459 |
| 440 const BoxConstraints.tight({ double width: 0.0, double height: 0.0 }) | 460 const BoxConstraints.tight({ double width: 0.0, double height: 0.0 }) |
| 441 : minWidth = width, | 461 : minWidth = width, |
| 442 maxWidth = width, | 462 maxWidth = width, |
| 443 minHeight = height, | 463 minHeight = height, |
| 444 maxHeight = height; | 464 maxHeight = height; |
| 445 | 465 |
| 466 BoxConstraints deflate(EdgeDims edges) { |
| 467 assert(edges != null); |
| 468 return new BoxConstraints( |
| 469 minWidth: minWidth, |
| 470 maxWidth: maxWidth - (edges.left + edges.right), |
| 471 minHeight: minHeight, |
| 472 maxHeight: maxHeight - (edges.top + edges.bottom) |
| 473 ); |
| 474 } |
| 475 |
| 446 final double minWidth; | 476 final double minWidth; |
| 447 final double maxWidth; | 477 final double maxWidth; |
| 448 final double minHeight; | 478 final double minHeight; |
| 449 final double maxHeight; | 479 final double maxHeight; |
| 450 | 480 |
| 451 double constrainWidth(double width) { | 481 double constrainWidth(double width) { |
| 452 return clamp(min: minWidth, max: maxWidth, value: width); | 482 return clamp(min: minWidth, max: maxWidth, value: width); |
| 453 } | 483 } |
| 454 | 484 |
| 455 double constrainHeight(double height) { | 485 double constrainHeight(double height) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 return new BoxDimensions.withConstraints(constraints); | 523 return new BoxDimensions.withConstraints(constraints); |
| 494 } | 524 } |
| 495 | 525 |
| 496 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { | 526 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
| 497 width = constraints.constrainWidth(0.0); | 527 width = constraints.constrainWidth(0.0); |
| 498 height = constraints.constrainHeight(0.0); | 528 height = constraints.constrainHeight(0.0); |
| 499 layoutDone(); | 529 layoutDone(); |
| 500 } | 530 } |
| 501 | 531 |
| 502 bool hitTest(HitTestResult result, { double x, double y }) { | 532 bool hitTest(HitTestResult result, { double x, double y }) { |
| 503 if (x < 0.0 || x >= width || y < 0.0 || y >= height) | |
| 504 return false; | |
| 505 hitTestChildren(result, x: x, y: y); | 533 hitTestChildren(result, x: x, y: y); |
| 506 result.add(this); | 534 result.add(this); |
| 507 return true; | 535 return true; |
| 508 } | 536 } |
| 509 void hitTestChildren(HitTestResult result, { double x, double y }) { } | 537 void hitTestChildren(HitTestResult result, { double x, double y }) { } |
| 510 | 538 |
| 511 double width; | 539 double width; |
| 512 double height; | 540 double height; |
| 513 } | 541 } |
| 514 | 542 |
| 543 class RenderPadding extends RenderBox with RenderNodeWithChildMixin<RenderBox> { |
| 544 |
| 545 RenderPadding(EdgeDims padding, RenderBox child) { |
| 546 assert(padding != null); |
| 547 this.padding = padding; |
| 548 this.child = child; |
| 549 } |
| 550 |
| 551 EdgeDims _padding; |
| 552 EdgeDims get padding => _padding; |
| 553 void set padding (EdgeDims value) { |
| 554 assert(value != null); |
| 555 if (_padding != value) { |
| 556 _padding = value; |
| 557 markNeedsLayout(); |
| 558 } |
| 559 } |
| 560 |
| 561 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { |
| 562 assert(padding != null); |
| 563 constraints = constraints.deflate(padding); |
| 564 if (child == null) |
| 565 return super.getIntrinsicDimensions(constraints); |
| 566 return child.getIntrinsicDimensions(constraints); |
| 567 } |
| 568 |
| 569 void layout(BoxConstraints constraints, { RenderNode relayoutSubtreeRoot }) { |
| 570 assert(padding != null); |
| 571 constraints = constraints.deflate(padding); |
| 572 if (child == null) { |
| 573 width = constraints.constrainWidth(padding.left + padding.right); |
| 574 height = constraints.constrainHeight(padding.top + padding.bottom); |
| 575 return; |
| 576 } |
| 577 if (relayoutSubtreeRoot != null) |
| 578 saveRelayoutSubtreeRoot(relayoutSubtreeRoot); |
| 579 else |
| 580 relayoutSubtreeRoot = this; |
| 581 child.layout(constraints, relayoutSubtreeRoot: relayoutSubtreeRoot); |
| 582 assert(child.parentData is BoxParentData); |
| 583 child.parentData.x = padding.left; |
| 584 child.parentData.y = padding.top; |
| 585 width = constraints.constrainWidth(padding.left + child.width + padding.righ
t); |
| 586 height = constraints.constrainHeight(padding.top + child.height + padding.bo
ttom); |
| 587 } |
| 588 |
| 589 void paint(RenderNodeDisplayList canvas) { |
| 590 if (child != null) |
| 591 canvas.paintChild(child, child.parentData.x, child.parentData.y); |
| 592 } |
| 593 |
| 594 void hitTestChildren(HitTestResult result, { double x, double y }) { |
| 595 if (child != null) { |
| 596 assert(child.parentData is BoxParentData); |
| 597 if ((x >= child.parentData.x) && (x < child.parentData.x + child.width) && |
| 598 (y >= child.parentData.y) && (y < child.parentData.y + child.height)) |
| 599 child.hitTest(result, x: x+child.parentData.x, y: y+child.parentData.y); |
| 600 } |
| 601 } |
| 602 |
| 603 } |
| 604 |
| 515 // This must be immutable, because we won't notice when it changes | 605 // This must be immutable, because we won't notice when it changes |
| 516 class BoxDecoration { | 606 class BoxDecoration { |
| 517 const BoxDecoration({ | 607 const BoxDecoration({ |
| 518 this.backgroundColor | 608 this.backgroundColor |
| 519 }); | 609 }); |
| 520 | 610 |
| 521 final int backgroundColor; | 611 final int backgroundColor; |
| 522 } | 612 } |
| 523 | 613 |
| 524 class RenderDecoratedBox extends RenderBox { | 614 class RenderDecoratedBox extends RenderBox { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 _width = newWidth; | 696 _width = newWidth; |
| 607 _height = newHeight; | 697 _height = newHeight; |
| 608 relayout(); | 698 relayout(); |
| 609 } else { | 699 } else { |
| 610 layoutDone(); | 700 layoutDone(); |
| 611 } | 701 } |
| 612 } | 702 } |
| 613 | 703 |
| 614 void relayout() { | 704 void relayout() { |
| 615 if (child != null) { | 705 if (child != null) { |
| 616 child.layout(new BoxConstraints( | 706 child.layout(new BoxConstraints.tight(width: width, height: height)); |
| 617 minWidth: width, | |
| 618 maxWidth: width, | |
| 619 minHeight: height, | |
| 620 maxHeight: height | |
| 621 )); | |
| 622 assert(child.width == width); | 707 assert(child.width == width); |
| 623 assert(child.height == height); | 708 assert(child.height == height); |
| 624 } | 709 } |
| 625 layoutDone(); | 710 layoutDone(); |
| 626 } | 711 } |
| 627 | 712 |
| 628 void rotate({ int oldAngle, int newAngle, Duration time }) { | 713 void rotate({ int oldAngle, int newAngle, Duration time }) { |
| 629 assert(false); // nobody tells the screen to rotate, the whole rotate() danc
e is started from our layout() | 714 assert(false); // nobody tells the screen to rotate, the whole rotate() danc
e is started from our layout() |
| 630 } | 715 } |
| 631 | 716 |
| 632 bool hitTest(HitTestResult result, { double x, double y }) { | 717 bool hitTest(HitTestResult result, { double x, double y }) { |
| 633 if (x < 0.0 || x >= width || y < 0.0 || y >= height) | 718 if (child != null && x >= 0.0 && x < child.width && y >= 0.0 && y < child.he
ight) |
| 634 return false; | 719 child.hitTest(result, x: x, y: y); |
| 635 if (child != null) { | |
| 636 if (x >= 0.0 && x < child.width && y >= 0.0 && y < child.height) | |
| 637 child.hitTest(result, x: x, y: y); | |
| 638 } | |
| 639 result.add(this); | 720 result.add(this); |
| 640 return true; | 721 return true; |
| 641 } | 722 } |
| 642 | 723 |
| 643 void paint(RenderNodeDisplayList canvas) { | 724 void paint(RenderNodeDisplayList canvas) { |
| 644 if (child != null) | 725 if (child != null) |
| 645 canvas.paintChild(child, 0.0, 0.0); | 726 canvas.paintChild(child, 0.0, 0.0); |
| 646 } | 727 } |
| 647 | 728 |
| 648 void paintFrame() { | 729 void paintFrame() { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 677 while (child != null) { | 758 while (child != null) { |
| 678 assert(child.parentData is BoxParentData); | 759 assert(child.parentData is BoxParentData); |
| 679 canvas.paintChild(child, child.parentData.x, child.parentData.y); | 760 canvas.paintChild(child, child.parentData.x, child.parentData.y); |
| 680 child = child.parentData.nextSibling; | 761 child = child.parentData.nextSibling; |
| 681 } | 762 } |
| 682 } | 763 } |
| 683 } | 764 } |
| 684 | 765 |
| 685 // BLOCK LAYOUT MANAGER | 766 // BLOCK LAYOUT MANAGER |
| 686 | 767 |
| 687 class EdgeDims { | |
| 688 // used for e.g. padding | |
| 689 const EdgeDims(this.top, this.right, this.bottom, this.left); | |
| 690 final double top; | |
| 691 final double right; | |
| 692 final double bottom; | |
| 693 final double left; | |
| 694 operator ==(EdgeDims other) => (top == other.top) || | |
| 695 (right == other.right) || | |
| 696 (bottom == other.bottom) || | |
| 697 (left == other.left); | |
| 698 } | |
| 699 | |
| 700 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render
Box> { } | 768 class BlockParentData extends BoxParentData with ContainerParentDataMixin<Render
Box> { } |
| 701 | 769 |
| 702 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende
rBox, BlockParentData>, | 770 class RenderBlock extends RenderDecoratedBox with ContainerRenderNodeMixin<Rende
rBox, BlockParentData>, |
| 703 RenderBoxContainerDefaultsMixi
n<RenderBox, BlockParentData> { | 771 RenderBoxContainerDefaultsMixi
n<RenderBox, BlockParentData> { |
| 704 // lays out RenderBox children in a vertical stack | 772 // lays out RenderBox children in a vertical stack |
| 705 // uses the maximum width provided by the parent | 773 // uses the maximum width provided by the parent |
| 706 // sizes itself to the height of its child stack | 774 // sizes itself to the height of its child stack |
| 707 | 775 |
| 708 RenderBlock({ | 776 RenderBlock({ |
| 709 BoxDecoration decoration, | 777 BoxDecoration decoration |
| 710 EdgeDims padding: const EdgeDims(0.0, 0.0, 0.0, 0.0) | 778 }) : super(decoration); |
| 711 }) : super(decoration), _padding = padding; | |
| 712 | |
| 713 EdgeDims _padding; | |
| 714 EdgeDims get padding => _padding; | |
| 715 void set padding (EdgeDims value) { | |
| 716 assert(value != null); | |
| 717 if (_padding != value) { | |
| 718 _padding = value; | |
| 719 markNeedsLayout(); | |
| 720 } | |
| 721 } | |
| 722 | 779 |
| 723 void setParentData(RenderBox child) { | 780 void setParentData(RenderBox child) { |
| 724 if (child.parentData is! BlockParentData) | 781 if (child.parentData is! BlockParentData) |
| 725 child.parentData = new BlockParentData(); | 782 child.parentData = new BlockParentData(); |
| 726 } | 783 } |
| 727 | 784 |
| 728 // override this to report what dimensions you would have if you | 785 // override this to report what dimensions you would have if you |
| 729 // were laid out with the given constraints this can walk the tree | 786 // were laid out with the given constraints this can walk the tree |
| 730 // if it must, but it should be as cheap as possible; just get the | 787 // if it must, but it should be as cheap as possible; just get the |
| 731 // dimensions and nothing else (e.g. don't calculate hypothetical | 788 // dimensions and nothing else (e.g. don't calculate hypothetical |
| 732 // child positions if they're not needed to determine dimensions) | 789 // child positions if they're not needed to determine dimensions) |
| 733 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { | 790 BoxDimensions getIntrinsicDimensions(BoxConstraints constraints) { |
| 734 double outerHeight = _padding.top + _padding.bottom; | 791 double outerHeight = 0.0; |
| 735 double outerWidth = constraints.constrainWidth(constraints.maxWidth); | 792 double outerWidth = constraints.constrainWidth(constraints.maxWidth); |
| 736 assert(outerWidth < double.INFINITY); | 793 assert(outerWidth < double.INFINITY); |
| 737 double innerWidth = outerWidth - (_padding.left + _padding.right); | 794 double innerWidth = outerWidth; |
| 738 RenderBox child = firstChild; | 795 RenderBox child = firstChild; |
| 739 BoxConstraints innerConstraints = new BoxConstraints(minWidth: innerWidth, | 796 BoxConstraints innerConstraints = new BoxConstraints(minWidth: innerWidth, |
| 740 maxWidth: innerWidth); | 797 maxWidth: innerWidth); |
| 741 while (child != null) { | 798 while (child != null) { |
| 742 outerHeight += child.getIntrinsicDimensions(innerConstraints).height; | 799 outerHeight += child.getIntrinsicDimensions(innerConstraints).height; |
| 743 assert(child.parentData is BlockParentData); | 800 assert(child.parentData is BlockParentData); |
| 744 child = child.parentData.nextSibling; | 801 child = child.parentData.nextSibling; |
| 745 } | 802 } |
| 746 | 803 |
| 747 return new BoxDimensions(width: outerWidth, | 804 return new BoxDimensions(width: outerWidth, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 759 _constraints = constraints; | 816 _constraints = constraints; |
| 760 internalLayout(relayoutSubtreeRoot); | 817 internalLayout(relayoutSubtreeRoot); |
| 761 } | 818 } |
| 762 | 819 |
| 763 void relayout() { | 820 void relayout() { |
| 764 internalLayout(this); | 821 internalLayout(this); |
| 765 } | 822 } |
| 766 | 823 |
| 767 void internalLayout(RenderNode relayoutSubtreeRoot) { | 824 void internalLayout(RenderNode relayoutSubtreeRoot) { |
| 768 assert(_constraints != null); | 825 assert(_constraints != null); |
| 769 double y = _padding.top; | 826 double y = 0.0; |
| 770 double innerWidth = width - (_padding.left + _padding.right); | 827 double innerWidth = width; |
| 771 RenderBox child = firstChild; | 828 RenderBox child = firstChild; |
| 772 while (child != null) { | 829 while (child != null) { |
| 773 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth
), | 830 child.layout(new BoxConstraints(minWidth: innerWidth, maxWidth: innerWidth
), |
| 774 relayoutSubtreeRoot: relayoutSubtreeRoot); | 831 relayoutSubtreeRoot: relayoutSubtreeRoot); |
| 775 assert(child.parentData is BlockParentData); | 832 assert(child.parentData is BlockParentData); |
| 776 child.parentData.x = _padding.left; | 833 child.parentData.x = 0.0; |
| 777 child.parentData.y = y; | 834 child.parentData.y = y; |
| 778 y += child.height; | 835 y += child.height; |
| 779 child = child.parentData.nextSibling; | 836 child = child.parentData.nextSibling; |
| 780 } | 837 } |
| 781 height = _constraints.constrainHeight(y + _padding.bottom); | 838 height = _constraints.constrainHeight(y); |
| 782 layoutDone(); | 839 layoutDone(); |
| 783 } | 840 } |
| 784 | 841 |
| 785 void hitTestChildren(HitTestResult result, { double x, double y }) { | 842 void hitTestChildren(HitTestResult result, { double x, double y }) { |
| 786 defaultHitTestChildren(result, x: x, y: y); | 843 defaultHitTestChildren(result, x: x, y: y); |
| 787 } | 844 } |
| 788 | 845 |
| 789 void paint(RenderNodeDisplayList canvas) { | 846 void paint(RenderNodeDisplayList canvas) { |
| 790 super.paint(canvas); | 847 super.paint(canvas); |
| 791 defaultPaint(canvas); | 848 defaultPaint(canvas); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 | 974 |
| 918 void hitTestChildren(HitTestResult result, { double x, double y }) { | 975 void hitTestChildren(HitTestResult result, { double x, double y }) { |
| 919 defaultHitTestChildren(result, x: x, y: y); | 976 defaultHitTestChildren(result, x: x, y: y); |
| 920 } | 977 } |
| 921 | 978 |
| 922 void paint(RenderNodeDisplayList canvas) { | 979 void paint(RenderNodeDisplayList canvas) { |
| 923 super.paint(canvas); | 980 super.paint(canvas); |
| 924 defaultPaint(canvas); | 981 defaultPaint(canvas); |
| 925 } | 982 } |
| 926 } | 983 } |
| OLD | NEW |