mirror of
https://github.com/flutter/flutter.git
synced 2026-02-13 14:21:39 +08:00
Similar to widgets.dart, rendering.dart exports the entire rendering layer. Also, update the examples to use rendering.dart and widgets.dart. Also clean up some exports so that the examples have more sensible imports.
113 lines
4.0 KiB
Dart
113 lines
4.0 KiB
Dart
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:sky/painting/paragraph_painter.dart';
|
|
import 'package:sky/rendering/box.dart';
|
|
import 'package:sky/rendering/object.dart';
|
|
|
|
export 'package:sky/painting/paragraph_painter.dart';
|
|
|
|
// Unfortunately, using full precision floating point here causes bad layouts
|
|
// because floating point math isn't associative. If we add and subtract
|
|
// padding, for example, we'll get different values when we estimate sizes and
|
|
// when we actually compute layout because the operations will end up associated
|
|
// differently. To work around this problem for now, we round fractional pixel
|
|
// values up to the nearest whole pixel value. The right long-term fix is to do
|
|
// layout using fixed precision arithmetic.
|
|
double _applyFloatingPointHack(double layoutValue) {
|
|
return layoutValue.ceilToDouble();
|
|
}
|
|
|
|
class RenderParagraph extends RenderBox {
|
|
|
|
RenderParagraph(TextSpan text)
|
|
: _paragraphPainter = new ParagraphPainter(text) {
|
|
assert(text != null);
|
|
}
|
|
|
|
ParagraphPainter _paragraphPainter;
|
|
|
|
BoxConstraints _constraintsForCurrentLayout; // when null, we don't have a current layout
|
|
|
|
TextSpan get text => _paragraphPainter.text;
|
|
void set text(TextSpan value) {
|
|
if (_paragraphPainter.text == value)
|
|
return;
|
|
_paragraphPainter.text = value;
|
|
_constraintsForCurrentLayout = null;
|
|
markNeedsLayout();
|
|
}
|
|
|
|
void _layout(BoxConstraints constraints) {
|
|
assert(constraints != null);
|
|
if (_constraintsForCurrentLayout == constraints)
|
|
return; // already cached this layout
|
|
_paragraphPainter.maxWidth = constraints.maxWidth;
|
|
_paragraphPainter.minWidth = constraints.minWidth;
|
|
_paragraphPainter.minHeight = constraints.minHeight;
|
|
_paragraphPainter.maxHeight = constraints.maxHeight;
|
|
_paragraphPainter.layout();
|
|
_constraintsForCurrentLayout = constraints;
|
|
}
|
|
|
|
double getMinIntrinsicWidth(BoxConstraints constraints) {
|
|
_layout(constraints);
|
|
return constraints.constrainWidth(
|
|
_applyFloatingPointHack(_paragraphPainter.minContentWidth));
|
|
}
|
|
|
|
double getMaxIntrinsicWidth(BoxConstraints constraints) {
|
|
_layout(constraints);
|
|
return constraints.constrainWidth(
|
|
_applyFloatingPointHack(_paragraphPainter.maxContentWidth));
|
|
}
|
|
|
|
double _getIntrinsicHeight(BoxConstraints constraints) {
|
|
_layout(constraints);
|
|
return constraints.constrainHeight(
|
|
_applyFloatingPointHack(_paragraphPainter.height));
|
|
}
|
|
|
|
double getMinIntrinsicHeight(BoxConstraints constraints) {
|
|
return _getIntrinsicHeight(constraints);
|
|
}
|
|
|
|
double getMaxIntrinsicHeight(BoxConstraints constraints) {
|
|
return _getIntrinsicHeight(constraints);
|
|
}
|
|
|
|
double computeDistanceToActualBaseline(TextBaseline baseline) {
|
|
assert(!needsLayout);
|
|
_layout(constraints);
|
|
return _paragraphPainter.computeDistanceToActualBaseline(baseline);
|
|
}
|
|
|
|
void performLayout() {
|
|
_layout(constraints);
|
|
// _paragraphPainter.width always expands to fill, use maxContentWidth instead.
|
|
size = constraints.constrain(new Size(_applyFloatingPointHack(_paragraphPainter.maxContentWidth),
|
|
_applyFloatingPointHack(_paragraphPainter.height)));
|
|
}
|
|
|
|
void paint(PaintingContext context, Offset offset) {
|
|
// Ideally we could compute the min/max intrinsic width/height with a
|
|
// non-destructive operation. However, currently, computing these values
|
|
// will destroy state inside the painter. If that happens, we need to
|
|
// get back the correct state by calling _layout again.
|
|
//
|
|
// TODO(abarth): Make computing the min/max intrinsic width/height
|
|
// a non-destructive operation.
|
|
_layout(constraints);
|
|
_paragraphPainter.paint(context.canvas, offset);
|
|
}
|
|
|
|
// we should probably expose a way to do precise (inter-glpyh) hit testing
|
|
|
|
String debugDescribeSettings(String prefix) {
|
|
String result = '${super.debugDescribeSettings(prefix)}';
|
|
result += '${prefix}text:\n${text.toString("$prefix ")}\n';
|
|
return result;
|
|
}
|
|
}
|