Index: sky/sdk/lib/framework/rendering/paragraph.dart |
diff --git a/sky/sdk/lib/framework/rendering/paragraph.dart b/sky/sdk/lib/framework/rendering/paragraph.dart |
index 16caee3a9d99b5ef995d21a043bd51961bdbe8e1..09bcde52c52eca4f2ed1e3807c14583dea7565fd 100644 |
--- a/sky/sdk/lib/framework/rendering/paragraph.dart |
+++ b/sky/sdk/lib/framework/rendering/paragraph.dart |
@@ -68,6 +68,29 @@ class TextStyle { |
return value; |
} |
+ void _applyToCSSStyle(CSSStyleDeclaration cssStyle) { |
+ if (color != null) { |
+ cssStyle['color'] = 'rgba(${color.red}, ${color.green}, ${color.blue}, ${color.alpha / 255.0})'; |
+ } |
+ if (fontSize != null) { |
+ cssStyle['font-size'] = "${fontSize}px"; |
+ } |
+ if (fontWeight != null) { |
+ cssStyle['font-weight'] = const { |
+ FontWeight.light: '300', |
+ FontWeight.regular: '400', |
+ FontWeight.medium: '500', |
+ }[fontWeight]; |
+ } |
+ if (textAlign != null) { |
+ cssStyle['text-align'] = const { |
+ TextAlign.left: 'left', |
+ TextAlign.right: 'right', |
+ TextAlign.center: 'center', |
+ }[textAlign]; |
+ } |
+ } |
+ |
String toString([String prefix = '']) { |
List<String> result = []; |
if (color != null) |
@@ -75,15 +98,57 @@ class TextStyle { |
if (fontSize != null) |
result.add('${prefix}fontSize: $fontSize'); |
if (fontWeight != null) |
- result.add('${prefix}fontWeight: fontWeight'); |
+ result.add('${prefix}fontWeight: $fontWeight'); |
if (textAlign != null) |
- result.add('${prefix}textAlign: textAlign'); |
+ result.add('${prefix}textAlign: $textAlign'); |
if (result.isEmpty) |
return '${prefix}<no style specified>'; |
return result.join('\n'); |
} |
} |
+class TextNode { |
+ const TextStyle(this.style); |
+ |
+ final TextStyle style; |
+ |
+ Node _toDOM(); |
+} |
+ |
+class StyledText extends TextNode { |
+ const StyledText(this.text, { TextStyle style }) : super(style); |
+ |
+ final String text; |
+ |
+ Node _toDOM(Document owner) { |
+ Node node = owner.createText(text); |
+ if (style != null) { |
+ Element wrapper = owner.createElement('t'); |
+ style._applyToCSSStyle(wrapper.style); |
+ wrapper.appendChild(node); |
+ node = wrapper; |
+ } |
+ return node; |
+ } |
+} |
+ |
+class TextFragment extends TextNode { |
+ const StyledText(this.text, { TextStyle style }) : super(style); |
+ |
+ final List<TextNode> _children; |
+ |
+ List<TextNode> get children => new UnmodifiableListView<TextNode>(_children); |
+ |
+ Node _toDOM() { |
+ Element wrapper = owner.createElement('f'); |
+ if (style) |
+ style._applyToCSSStyle(wrapper.style); |
+ for (TextNode child in children) |
+ wrapper.appendChild(child._toDOM()); |
+ return wrapper; |
+ } |
+} |
+ |
// 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 |
@@ -98,9 +163,7 @@ double _applyFloatingPointHack(double layoutValue) { |
class RenderParagraph extends RenderBox { |
RenderParagraph({ |
- String text, |
- Color color, |
- TextStyle style |
+ TextNode node; |
}) : _style = style { |
_layoutRoot.rootElement = _document.createElement('p'); |
this.text = text; |
@@ -115,8 +178,8 @@ class RenderParagraph extends RenderBox { |
markNeedsLayout(); |
} |
- TextStyle _style; |
- TextStyle get style => _style; |
+ TextNode _style; |
+ TextNode get style => _style; |
void set style (TextStyle value) { |
if (_style != value) { |
// TODO(hansmuller): decide if a new layout or paint is needed |
@@ -183,28 +246,6 @@ class RenderParagraph extends RenderBox { |
if (style != null) { |
var cssStyle = _layoutRoot.rootElement.style; |
- if (style.color != null) { |
- Color c = style.color; |
- cssStyle['color'] = |
- 'rgba(${c.red}, ${c.green}, ${c.blue}, ${c.alpha / 255.0})'; |
- } |
- if (style.fontSize != null) { |
- cssStyle['font-size'] = "${style.fontSize}px"; |
- } |
- if (style.fontWeight != null) { |
- cssStyle['font-weight'] = const { |
- FontWeight.light: '300', |
- FontWeight.regular: '400', |
- FontWeight.medium: '500', |
- }[style.fontWeight]; |
- } |
- if (style.textAlign != null) { |
- cssStyle['text-align'] = const { |
- TextAlign.left: 'left', |
- TextAlign.right: 'right', |
- TextAlign.center: 'center', |
- }[style.textAlign]; |
- } |
} |
_layoutRoot.paint(canvas); |
} |