Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Side by Side Diff: sky/sdk/lib/framework/rendering/paragraph.dart

Issue 1179663005: WIP make it possible to do TextFragment Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 'dart:sky' as sky; 5 import 'dart:sky' as sky;
6 import 'box.dart'; 6 import 'box.dart';
7 import 'object.dart'; 7 import 'object.dart';
8 8
9 class RenderInline extends RenderObject { 9 class RenderInline extends RenderObject {
10 RenderInline(this.data); 10 RenderInline(this.data);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 int get hashCode { 61 int get hashCode {
62 // Use Quiver: https://github.com/domokit/mojo/issues/236 62 // Use Quiver: https://github.com/domokit/mojo/issues/236
63 int value = 373; 63 int value = 373;
64 value = 37 * value + color.hashCode; 64 value = 37 * value + color.hashCode;
65 value = 37 * value + fontSize.hashCode; 65 value = 37 * value + fontSize.hashCode;
66 value = 37 * value + fontWeight.hashCode; 66 value = 37 * value + fontWeight.hashCode;
67 value = 37 * value + textAlign.hashCode; 67 value = 37 * value + textAlign.hashCode;
68 return value; 68 return value;
69 } 69 }
70 70
71 void _applyToCSSStyle(CSSStyleDeclaration cssStyle) {
72 if (color != null) {
73 cssStyle['color'] = 'rgba(${color.red}, ${color.green}, ${color.blue}, ${c olor.alpha / 255.0})';
74 }
75 if (fontSize != null) {
76 cssStyle['font-size'] = "${fontSize}px";
77 }
78 if (fontWeight != null) {
79 cssStyle['font-weight'] = const {
80 FontWeight.light: '300',
81 FontWeight.regular: '400',
82 FontWeight.medium: '500',
83 }[fontWeight];
84 }
85 if (textAlign != null) {
86 cssStyle['text-align'] = const {
87 TextAlign.left: 'left',
88 TextAlign.right: 'right',
89 TextAlign.center: 'center',
90 }[textAlign];
91 }
92 }
93
71 String toString([String prefix = '']) { 94 String toString([String prefix = '']) {
72 List<String> result = []; 95 List<String> result = [];
73 if (color != null) 96 if (color != null)
74 result.add('${prefix}color: $color'); 97 result.add('${prefix}color: $color');
75 if (fontSize != null) 98 if (fontSize != null)
76 result.add('${prefix}fontSize: $fontSize'); 99 result.add('${prefix}fontSize: $fontSize');
77 if (fontWeight != null) 100 if (fontWeight != null)
78 result.add('${prefix}fontWeight: fontWeight'); 101 result.add('${prefix}fontWeight: $fontWeight');
79 if (textAlign != null) 102 if (textAlign != null)
80 result.add('${prefix}textAlign: textAlign'); 103 result.add('${prefix}textAlign: $textAlign');
81 if (result.isEmpty) 104 if (result.isEmpty)
82 return '${prefix}<no style specified>'; 105 return '${prefix}<no style specified>';
83 return result.join('\n'); 106 return result.join('\n');
84 } 107 }
85 } 108 }
86 109
110 class TextNode {
111 const TextStyle(this.style);
112
113 final TextStyle style;
114
115 Node _toDOM();
116 }
117
118 class StyledText extends TextNode {
119 const StyledText(this.text, { TextStyle style }) : super(style);
120
121 final String text;
122
123 Node _toDOM(Document owner) {
124 Node node = owner.createText(text);
125 if (style != null) {
126 Element wrapper = owner.createElement('t');
127 style._applyToCSSStyle(wrapper.style);
128 wrapper.appendChild(node);
129 node = wrapper;
130 }
131 return node;
132 }
133 }
134
135 class TextFragment extends TextNode {
136 const StyledText(this.text, { TextStyle style }) : super(style);
137
138 final List<TextNode> _children;
139
140 List<TextNode> get children => new UnmodifiableListView<TextNode>(_children);
141
142 Node _toDOM() {
143 Element wrapper = owner.createElement('f');
144 if (style)
145 style._applyToCSSStyle(wrapper.style);
146 for (TextNode child in children)
147 wrapper.appendChild(child._toDOM());
148 return wrapper;
149 }
150 }
151
87 // Unfortunately, using full precision floating point here causes bad layouts 152 // Unfortunately, using full precision floating point here causes bad layouts
88 // because floating point math isn't associative. If we add and subtract 153 // because floating point math isn't associative. If we add and subtract
89 // padding, for example, we'll get different values when we estimate sizes and 154 // padding, for example, we'll get different values when we estimate sizes and
90 // when we actually compute layout because the operations will end up associated 155 // when we actually compute layout because the operations will end up associated
91 // differently. To work around this problem for now, we round fractional pixel 156 // differently. To work around this problem for now, we round fractional pixel
92 // values up to the nearest whole pixel value. The right long-term fix is to do 157 // values up to the nearest whole pixel value. The right long-term fix is to do
93 // layout using fixed precision arithmetic. 158 // layout using fixed precision arithmetic.
94 double _applyFloatingPointHack(double layoutValue) { 159 double _applyFloatingPointHack(double layoutValue) {
95 return layoutValue.ceilToDouble(); 160 return layoutValue.ceilToDouble();
96 } 161 }
97 162
98 class RenderParagraph extends RenderBox { 163 class RenderParagraph extends RenderBox {
99 164
100 RenderParagraph({ 165 RenderParagraph({
101 String text, 166 TextNode node;
102 Color color,
103 TextStyle style
104 }) : _style = style { 167 }) : _style = style {
105 _layoutRoot.rootElement = _document.createElement('p'); 168 _layoutRoot.rootElement = _document.createElement('p');
106 this.text = text; 169 this.text = text;
107 } 170 }
108 171
109 final sky.Document _document = new sky.Document(); 172 final sky.Document _document = new sky.Document();
110 final sky.LayoutRoot _layoutRoot = new sky.LayoutRoot(); 173 final sky.LayoutRoot _layoutRoot = new sky.LayoutRoot();
111 174
112 String get text => (_layoutRoot.rootElement.firstChild as sky.Text).data; 175 String get text => (_layoutRoot.rootElement.firstChild as sky.Text).data;
113 void set text (String value) { 176 void set text (String value) {
114 _layoutRoot.rootElement.setChild(_document.createText(value)); 177 _layoutRoot.rootElement.setChild(_document.createText(value));
115 markNeedsLayout(); 178 markNeedsLayout();
116 } 179 }
117 180
118 TextStyle _style; 181 TextNode _style;
119 TextStyle get style => _style; 182 TextNode get style => _style;
120 void set style (TextStyle value) { 183 void set style (TextStyle value) {
121 if (_style != value) { 184 if (_style != value) {
122 // TODO(hansmuller): decide if a new layout or paint is needed 185 // TODO(hansmuller): decide if a new layout or paint is needed
123 markNeedsLayout(); 186 markNeedsLayout();
124 _style = value; 187 _style = value;
125 } 188 }
126 } 189 }
127 190
128 BoxConstraints _constraintsForCurrentLayout; 191 BoxConstraints _constraintsForCurrentLayout;
129 192
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 // will destroy state inside the layout root. If that happens, we need to 239 // will destroy state inside the layout root. If that happens, we need to
177 // get back the correct state by calling _layout again. 240 // get back the correct state by calling _layout again.
178 // 241 //
179 // TODO(abarth): Make computing the min/max intrinsic width/height a 242 // TODO(abarth): Make computing the min/max intrinsic width/height a
180 // non-destructive operation. 243 // non-destructive operation.
181 if (_constraintsForCurrentLayout != constraints && constraints != null) 244 if (_constraintsForCurrentLayout != constraints && constraints != null)
182 _layout(constraints); 245 _layout(constraints);
183 246
184 if (style != null) { 247 if (style != null) {
185 var cssStyle = _layoutRoot.rootElement.style; 248 var cssStyle = _layoutRoot.rootElement.style;
186 if (style.color != null) {
187 Color c = style.color;
188 cssStyle['color'] =
189 'rgba(${c.red}, ${c.green}, ${c.blue}, ${c.alpha / 255.0})';
190 }
191 if (style.fontSize != null) {
192 cssStyle['font-size'] = "${style.fontSize}px";
193 }
194 if (style.fontWeight != null) {
195 cssStyle['font-weight'] = const {
196 FontWeight.light: '300',
197 FontWeight.regular: '400',
198 FontWeight.medium: '500',
199 }[style.fontWeight];
200 }
201 if (style.textAlign != null) {
202 cssStyle['text-align'] = const {
203 TextAlign.left: 'left',
204 TextAlign.right: 'right',
205 TextAlign.center: 'center',
206 }[style.textAlign];
207 }
208 } 249 }
209 _layoutRoot.paint(canvas); 250 _layoutRoot.paint(canvas);
210 } 251 }
211 252
212 // we should probably expose a way to do precise (inter-glpyh) hit testing 253 // we should probably expose a way to do precise (inter-glpyh) hit testing
213 254
214 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}style:\n${style.toString("$prefix ")}\n${prefix}text: ${text}\ n'; 255 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings( prefix)}${prefix}style:\n${style.toString("$prefix ")}\n${prefix}text: ${text}\ n';
215 } 256 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698