Commit 4604021d authored by Collin Jackson's avatar Collin Jackson

Support for non-alphabetic baselines

parent e1aa0431
...@@ -20,7 +20,7 @@ void main() { ...@@ -20,7 +20,7 @@ void main() {
TextStyle style = const TextStyle(color: const Color(0xFF000000)); TextStyle style = const TextStyle(color: const Color(0xFF000000));
RenderParagraph paragraph = new RenderParagraph(new InlineStyle(style, [new InlineText("${alignItems}")])); RenderParagraph paragraph = new RenderParagraph(new InlineStyle(style, [new InlineText("${alignItems}")]));
table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0))); table.add(new RenderPadding(child: paragraph, padding: new EdgeDims.only(top: 20.0)));
var row = new RenderFlex(alignItems: alignItems); var row = new RenderFlex(alignItems: alignItems, baseline: TextBaseline.alphabetic);
style = new TextStyle(fontSize: 15.0, color: const Color(0xFF000000)); style = new TextStyle(fontSize: 15.0, color: const Color(0xFF000000));
row.add(new RenderDecoratedBox( row.add(new RenderDecoratedBox(
...@@ -32,7 +32,7 @@ void main() { ...@@ -32,7 +32,7 @@ void main() {
decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCFFCC)), decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCFFCC)),
child: new RenderParagraph(new InlineStyle(style, [new InlineText('foo foo foo')])) child: new RenderParagraph(new InlineStyle(style, [new InlineText('foo foo foo')]))
)); ));
var subrow = new RenderFlex(alignItems: alignItems); var subrow = new RenderFlex(alignItems: alignItems, baseline: TextBaseline.alphabetic);
style = new TextStyle(fontSize: 25.0, color: const Color(0xFF000000)); style = new TextStyle(fontSize: 25.0, color: const Color(0xFF000000));
subrow.add(new RenderDecoratedBox( subrow.add(new RenderDecoratedBox(
decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCCCFF)), decoration: new BoxDecoration(backgroundColor: const Color(0x7FCCCCFF)),
......
...@@ -6,6 +6,7 @@ import 'package:sky/painting/text_style.dart'; ...@@ -6,6 +6,7 @@ import 'package:sky/painting/text_style.dart';
import 'package:sky/rendering/box.dart'; import 'package:sky/rendering/box.dart';
import 'package:sky/widgets/ink_well.dart'; import 'package:sky/widgets/ink_well.dart';
import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/default_text_style.dart';
import 'package:sky/widgets/theme.dart'; import 'package:sky/widgets/theme.dart';
import 'stock_arrow.dart'; import 'stock_arrow.dart';
...@@ -60,7 +61,11 @@ class StockRow extends Component { ...@@ -60,7 +61,11 @@ class StockRow extends Component {
margin: const EdgeDims.only(right: 5.0) margin: const EdgeDims.only(right: 5.0)
), ),
new Flexible( new Flexible(
child: new Flex(children, alignItems: FlexAlignItems.baseline) child: new Flex(
children,
alignItems: FlexAlignItems.baseline,
textBaseline: DefaultTextStyle.of(this).textBaseline
)
) )
]) ])
) )
......
...@@ -10,6 +10,8 @@ const bold = FontWeight.w700; ...@@ -10,6 +10,8 @@ const bold = FontWeight.w700;
enum TextAlign { left, right, center } enum TextAlign { left, right, center }
enum TextBaseline { alphabetic, ideographic }
enum TextDecoration { none, underline, overline, lineThrough } enum TextDecoration { none, underline, overline, lineThrough }
const underline = const <TextDecoration>[TextDecoration.underline]; const underline = const <TextDecoration>[TextDecoration.underline];
const overline = const <TextDecoration>[TextDecoration.overline]; const overline = const <TextDecoration>[TextDecoration.overline];
...@@ -24,6 +26,7 @@ class TextStyle { ...@@ -24,6 +26,7 @@ class TextStyle {
this.fontSize, this.fontSize,
this.fontWeight, this.fontWeight,
this.textAlign, this.textAlign,
this.textBaseline,
this.height, this.height,
this.decoration, this.decoration,
this.decorationColor, this.decorationColor,
...@@ -35,6 +38,7 @@ class TextStyle { ...@@ -35,6 +38,7 @@ class TextStyle {
final double fontSize; // in pixels final double fontSize; // in pixels
final FontWeight fontWeight; final FontWeight fontWeight;
final TextAlign textAlign; final TextAlign textAlign;
final TextBaseline textBaseline;
final double height; // multiple of fontSize final double height; // multiple of fontSize
final List<TextDecoration> decoration; // TODO(ianh): Switch this to a Set<> once Dart supports constant Sets final List<TextDecoration> decoration; // TODO(ianh): Switch this to a Set<> once Dart supports constant Sets
final Color decorationColor; final Color decorationColor;
...@@ -46,6 +50,7 @@ class TextStyle { ...@@ -46,6 +50,7 @@ class TextStyle {
double fontSize, double fontSize,
FontWeight fontWeight, FontWeight fontWeight,
TextAlign textAlign, TextAlign textAlign,
TextBaseline textBaseline,
double height, double height,
List<TextDecoration> decoration, List<TextDecoration> decoration,
Color decorationColor, Color decorationColor,
...@@ -57,6 +62,7 @@ class TextStyle { ...@@ -57,6 +62,7 @@ class TextStyle {
fontSize: fontSize != null ? fontSize : this.fontSize, fontSize: fontSize != null ? fontSize : this.fontSize,
fontWeight: fontWeight != null ? fontWeight : this.fontWeight, fontWeight: fontWeight != null ? fontWeight : this.fontWeight,
textAlign: textAlign != null ? textAlign : this.textAlign, textAlign: textAlign != null ? textAlign : this.textAlign,
textBaseline: textBaseline != null ? textBaseline : this.textBaseline,
height: height != null ? height : this.height, height: height != null ? height : this.height,
decoration: decoration != null ? decoration : this.decoration, decoration: decoration != null ? decoration : this.decoration,
decorationColor: decorationColor != null ? decorationColor : this.decorationColor, decorationColor: decorationColor != null ? decorationColor : this.decorationColor,
...@@ -71,6 +77,7 @@ class TextStyle { ...@@ -71,6 +77,7 @@ class TextStyle {
fontSize: other.fontSize, fontSize: other.fontSize,
fontWeight: other.fontWeight, fontWeight: other.fontWeight,
textAlign: other.textAlign, textAlign: other.textAlign,
textBaseline: other.textBaseline,
height: other.height, height: other.height,
decoration: other.decoration, decoration: other.decoration,
decorationColor: other.decorationColor, decorationColor: other.decorationColor,
...@@ -161,6 +168,7 @@ class TextStyle { ...@@ -161,6 +168,7 @@ class TextStyle {
fontSize == other.fontSize && fontSize == other.fontSize &&
fontWeight == other.fontWeight && fontWeight == other.fontWeight &&
textAlign == other.textAlign && textAlign == other.textAlign &&
textBaseline == other.textBaseline &&
decoration == other.decoration && decoration == other.decoration &&
decorationColor == other.decorationColor && decorationColor == other.decorationColor &&
decorationStyle == other.decorationStyle; decorationStyle == other.decorationStyle;
...@@ -174,6 +182,7 @@ class TextStyle { ...@@ -174,6 +182,7 @@ class TextStyle {
value = 37 * value + fontSize.hashCode; value = 37 * value + fontSize.hashCode;
value = 37 * value + fontWeight.hashCode; value = 37 * value + fontWeight.hashCode;
value = 37 * value + textAlign.hashCode; value = 37 * value + textAlign.hashCode;
value = 37 * value + textBaseline.hashCode;
value = 37 * value + decoration.hashCode; value = 37 * value + decoration.hashCode;
value = 37 * value + decorationColor.hashCode; value = 37 * value + decorationColor.hashCode;
value = 37 * value + decorationStyle.hashCode; value = 37 * value + decorationStyle.hashCode;
...@@ -193,6 +202,8 @@ class TextStyle { ...@@ -193,6 +202,8 @@ class TextStyle {
result.add('${prefix}fontWeight: $fontWeight'); result.add('${prefix}fontWeight: $fontWeight');
if (textAlign != null) if (textAlign != null)
result.add('${prefix}textAlign: $textAlign'); result.add('${prefix}textAlign: $textAlign');
if (textBaseline != null)
result.add('${prefix}textBaseline: $textBaseline');
if (decoration != null) if (decoration != null)
result.add('${prefix}decoration: $decoration'); result.add('${prefix}decoration: $decoration');
if (decorationColor != null) if (decorationColor != null)
......
...@@ -7,10 +7,12 @@ import 'dart:sky' as sky; ...@@ -7,10 +7,12 @@ import 'dart:sky' as sky;
import 'package:sky/base/debug.dart'; import 'package:sky/base/debug.dart';
import 'package:sky/painting/box_painter.dart'; import 'package:sky/painting/box_painter.dart';
import 'package:sky/painting/text_style.dart';
import 'package:sky/rendering/object.dart'; import 'package:sky/rendering/object.dart';
import 'package:vector_math/vector_math.dart'; import 'package:vector_math/vector_math.dart';
export 'package:sky/painting/box_painter.dart'; export 'package:sky/painting/box_painter.dart';
export 'package:sky/painting/text_style.dart' show TextBaseline;
// GENERIC BOX RENDERING // GENERIC BOX RENDERING
// Anything that has a concept of x, y, width, height is going to derive from this // Anything that has a concept of x, y, width, height is going to derive from this
...@@ -253,8 +255,6 @@ class BoxParentData extends ParentData { ...@@ -253,8 +255,6 @@ class BoxParentData extends ParentData {
String toString() => 'position=$position'; String toString() => 'position=$position';
} }
enum TextBaseline { alphabetic, ideographic }
abstract class RenderBox extends RenderObject { abstract class RenderBox extends RenderObject {
void setupParentData(RenderObject child) { void setupParentData(RenderObject child) {
......
...@@ -47,10 +47,12 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -47,10 +47,12 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
List<RenderBox> children, List<RenderBox> children,
FlexDirection direction: FlexDirection.horizontal, FlexDirection direction: FlexDirection.horizontal,
FlexJustifyContent justifyContent: FlexJustifyContent.start, FlexJustifyContent justifyContent: FlexJustifyContent.start,
FlexAlignItems alignItems: FlexAlignItems.center FlexAlignItems alignItems: FlexAlignItems.center,
TextBaseline textBaseline
}) : _direction = direction, }) : _direction = direction,
_justifyContent = justifyContent, _justifyContent = justifyContent,
_alignItems = alignItems { _alignItems = alignItems,
_textBaseline = textBaseline {
addAll(children); addAll(children);
} }
...@@ -81,6 +83,15 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -81,6 +83,15 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
} }
} }
TextBaseline _textBaseline;
TextBaseline get textBaseline => _textBaseline;
void set textBaseline (TextBaseline value) {
if (_textBaseline != value) {
_textBaseline = value;
markNeedsLayout();
}
}
bool _overflowOccurredDuringLayout = false; bool _overflowOccurredDuringLayout = false;
void setupParentData(RenderBox child) { void setupParentData(RenderBox child) {
...@@ -342,8 +353,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -342,8 +353,8 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
crossSize = math.max(crossSize, _getCrossSize(child)); crossSize = math.max(crossSize, _getCrossSize(child));
} }
if (alignItems == FlexAlignItems.baseline) { if (alignItems == FlexAlignItems.baseline) {
// TODO(jackson): Support for non-alphabetic baselines assert(textBaseline != null);
double distance = child.getDistanceToBaseline(TextBaseline.alphabetic, onlyReal: true); double distance = child.getDistanceToBaseline(textBaseline, onlyReal: true);
if (distance != null) if (distance != null)
maxBaselineDistance = math.max(maxBaselineDistance, distance); maxBaselineDistance = math.max(maxBaselineDistance, distance);
} }
...@@ -412,10 +423,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -412,10 +423,9 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
break; break;
case FlexAlignItems.baseline: case FlexAlignItems.baseline:
childCrossPosition = 0.0; childCrossPosition = 0.0;
// TODO(jackson): Support for vertical baselines
if (_direction == FlexDirection.horizontal) { if (_direction == FlexDirection.horizontal) {
// TODO(jackson): Support for non-alphabetic baselines assert(textBaseline != null);
double distance = child.getDistanceToBaseline(TextBaseline.alphabetic, onlyReal: true); double distance = child.getDistanceToBaseline(textBaseline, onlyReal: true);
if (distance != null) if (distance != null)
childCrossPosition = maxBaselineDistance - distance; childCrossPosition = maxBaselineDistance - distance;
} }
......
...@@ -9,20 +9,21 @@ import 'dart:sky'; ...@@ -9,20 +9,21 @@ import 'dart:sky';
import 'package:sky/painting/text_style.dart'; import 'package:sky/painting/text_style.dart';
// TODO(eseidel): Font weights are supposed to be language relative! // TODO(eseidel): Font weights are supposed to be language relative!
// TODO(jackson): Baseline should be language relative!
// These values are for English-like text. // These values are for English-like text.
class TextTheme { class TextTheme {
TextTheme._(Color color54, Color color87) TextTheme._(Color color54, Color color87)
: display4 = new TextStyle(fontSize: 112.0, fontWeight: FontWeight.w100, color: color54), : display4 = new TextStyle(fontSize: 112.0, fontWeight: FontWeight.w100, color: color54, textBaseline: TextBaseline.alphabetic),
display3 = new TextStyle(fontSize: 56.0, fontWeight: FontWeight.w400, color: color54), display3 = new TextStyle(fontSize: 56.0, fontWeight: FontWeight.w400, color: color54, textBaseline: TextBaseline.alphabetic),
display2 = new TextStyle(fontSize: 45.0, fontWeight: FontWeight.w400, color: color54, height: 48.0 / 45.0), display2 = new TextStyle(fontSize: 45.0, fontWeight: FontWeight.w400, color: color54, height: 48.0 / 45.0, textBaseline: TextBaseline.alphabetic),
display1 = new TextStyle(fontSize: 34.0, fontWeight: FontWeight.w400, color: color54, height: 40.0 / 34.0), display1 = new TextStyle(fontSize: 34.0, fontWeight: FontWeight.w400, color: color54, height: 40.0 / 34.0, textBaseline: TextBaseline.alphabetic),
headline = new TextStyle(fontSize: 24.0, fontWeight: FontWeight.w400, color: color87, height: 32.0 / 24.0), headline = new TextStyle(fontSize: 24.0, fontWeight: FontWeight.w400, color: color87, height: 32.0 / 24.0, textBaseline: TextBaseline.alphabetic),
title = new TextStyle(fontSize: 20.0, fontWeight: FontWeight.w500, color: color87, height: 28.0 / 20.0), title = new TextStyle(fontSize: 20.0, fontWeight: FontWeight.w500, color: color87, height: 28.0 / 20.0, textBaseline: TextBaseline.alphabetic),
subhead = new TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400, color: color87, height: 24.0 / 16.0), subhead = new TextStyle(fontSize: 16.0, fontWeight: FontWeight.w400, color: color87, height: 24.0 / 16.0, textBaseline: TextBaseline.alphabetic),
body2 = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: color87, height: 24.0 / 14.0), body2 = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: color87, height: 24.0 / 14.0, textBaseline: TextBaseline.alphabetic),
body1 = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400, color: color87, height: 20.0 / 14.0), body1 = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w400, color: color87, height: 20.0 / 14.0, textBaseline: TextBaseline.alphabetic),
caption = new TextStyle(fontSize: 12.0, fontWeight: FontWeight.w400, color: color54), caption = new TextStyle(fontSize: 12.0, fontWeight: FontWeight.w400, color: color54, textBaseline: TextBaseline.alphabetic),
button = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: color87); button = new TextStyle(fontSize: 14.0, fontWeight: FontWeight.w500, color: color87, textBaseline: TextBaseline.alphabetic);
final TextStyle display4; final TextStyle display4;
final TextStyle display3; final TextStyle display3;
......
...@@ -401,12 +401,14 @@ class Flex extends MultiChildRenderObjectWrapper { ...@@ -401,12 +401,14 @@ class Flex extends MultiChildRenderObjectWrapper {
String key, String key,
this.direction: FlexDirection.horizontal, this.direction: FlexDirection.horizontal,
this.justifyContent: FlexJustifyContent.start, this.justifyContent: FlexJustifyContent.start,
this.alignItems: FlexAlignItems.center this.alignItems: FlexAlignItems.center,
this.textBaseline
}) : super(key: key, children: children); }) : super(key: key, children: children);
final FlexDirection direction; final FlexDirection direction;
final FlexJustifyContent justifyContent; final FlexJustifyContent justifyContent;
final FlexAlignItems alignItems; final FlexAlignItems alignItems;
final TextBaseline textBaseline;
RenderFlex createNode() => new RenderFlex(direction: this.direction); RenderFlex createNode() => new RenderFlex(direction: this.direction);
RenderFlex get root => super.root; RenderFlex get root => super.root;
...@@ -416,6 +418,7 @@ class Flex extends MultiChildRenderObjectWrapper { ...@@ -416,6 +418,7 @@ class Flex extends MultiChildRenderObjectWrapper {
root.direction = direction; root.direction = direction;
root.justifyContent = justifyContent; root.justifyContent = justifyContent;
root.alignItems = alignItems; root.alignItems = alignItems;
root.textBaseline = textBaseline;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment