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

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

Issue 1177833012: Styling for text fragments (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Merge 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 | « sky/sdk/lib/editing2/editable_text.dart ('k') | sky/sdk/lib/widgets/basic.dart » ('j') | 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 6
7 import 'box.dart'; 7 import 'box.dart';
8 import 'object.dart'; 8 import 'object.dart';
9 9
10 class RenderInline extends RenderObject {
11 RenderInline(this.data);
12 String data;
13 }
14
15 enum FontWeight { 10 enum FontWeight {
16 light, // 300 11 light, // 300
17 regular, // 400 12 regular, // 400
18 medium, // 500 13 medium, // 500
19 } 14 }
20 15
21 enum TextAlign { 16 enum TextAlign {
22 left, 17 left,
23 right, 18 right,
24 center 19 center
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 int get hashCode { 57 int get hashCode {
63 // Use Quiver: https://github.com/domokit/mojo/issues/236 58 // Use Quiver: https://github.com/domokit/mojo/issues/236
64 int value = 373; 59 int value = 373;
65 value = 37 * value + color.hashCode; 60 value = 37 * value + color.hashCode;
66 value = 37 * value + fontSize.hashCode; 61 value = 37 * value + fontSize.hashCode;
67 value = 37 * value + fontWeight.hashCode; 62 value = 37 * value + fontWeight.hashCode;
68 value = 37 * value + textAlign.hashCode; 63 value = 37 * value + textAlign.hashCode;
69 return value; 64 return value;
70 } 65 }
71 66
67 void _applyToCSSStyle(sky.CSSStyleDeclaration cssStyle) {
68 if (color != null) {
69 cssStyle['color'] = 'rgba(${color.red}, ${color.green}, ${color.blue}, ${c olor.alpha / 255.0})';
70 }
71 if (fontSize != null) {
72 cssStyle['font-size'] = "${fontSize}px";
73 }
74 if (fontWeight != null) {
75 cssStyle['font-weight'] = const {
76 FontWeight.light: '300',
77 FontWeight.regular: '400',
78 FontWeight.medium: '500',
79 }[fontWeight];
80 }
81 if (textAlign != null) {
82 cssStyle['text-align'] = const {
83 TextAlign.left: 'left',
84 TextAlign.right: 'right',
85 TextAlign.center: 'center',
86 }[textAlign];
87 }
88 }
89
72 String toString([String prefix = '']) { 90 String toString([String prefix = '']) {
73 List<String> result = []; 91 List<String> result = [];
74 if (color != null) 92 if (color != null)
75 result.add('${prefix}color: $color'); 93 result.add('${prefix}color: $color');
76 if (fontSize != null) 94 if (fontSize != null)
77 result.add('${prefix}fontSize: $fontSize'); 95 result.add('${prefix}fontSize: $fontSize');
78 if (fontWeight != null) 96 if (fontWeight != null)
79 result.add('${prefix}fontWeight: fontWeight'); 97 result.add('${prefix}fontWeight: $fontWeight');
80 if (textAlign != null) 98 if (textAlign != null)
81 result.add('${prefix}textAlign: textAlign'); 99 result.add('${prefix}textAlign: $textAlign');
82 if (result.isEmpty) 100 if (result.isEmpty)
83 return '${prefix}<no style specified>'; 101 return '${prefix}<no style specified>';
84 return result.join('\n'); 102 return result.join('\n');
85 } 103 }
86 } 104 }
87 105
106 class InlineBase {
107 sky.Node _toDOM(sky.Document owner);
108 String toString([String prefix = '']);
109 }
110
111 class InlineText extends InlineBase {
112 InlineText(this.text) {
113 assert(text != null);
114 }
115
116 final String text;
117
118 sky.Node _toDOM(sky.Document owner) {
119 return owner.createText(text);
120 }
121
122 String toString([String prefix = '']) => '${prefix}InlineText: "${text}"';
123 }
124
125 class InlineStyle extends InlineBase {
126 InlineStyle(this.style, this.children) {
127 assert(style != null && children != null);
128 }
129
130 final TextStyle style;
131 final List<InlineBase> children;
132
133 sky.Node _toDOM(sky.Document owner) {
134 sky.Element parent = owner.createElement('t');
135 style._applyToCSSStyle(parent.style);
136 for (InlineBase child in children) {
137 parent.appendChild(child._toDOM(owner));
138 }
139 return parent;
140 }
141
142 String toString([String prefix = '']) {
143 List<String> result = [];
144 result.add('${prefix}InlineStyle:');
145 var indent = '${prefix} ';
146 result.add('${style.toString(indent)}');
147 for (InlineBase child in children) {
148 result.add(child.toString(indent));
149 }
150 return result.join('\n');
151 }
152 }
153
88 // Unfortunately, using full precision floating point here causes bad layouts 154 // Unfortunately, using full precision floating point here causes bad layouts
89 // because floating point math isn't associative. If we add and subtract 155 // because floating point math isn't associative. If we add and subtract
90 // padding, for example, we'll get different values when we estimate sizes and 156 // padding, for example, we'll get different values when we estimate sizes and
91 // when we actually compute layout because the operations will end up associated 157 // when we actually compute layout because the operations will end up associated
92 // differently. To work around this problem for now, we round fractional pixel 158 // differently. To work around this problem for now, we round fractional pixel
93 // values up to the nearest whole pixel value. The right long-term fix is to do 159 // values up to the nearest whole pixel value. The right long-term fix is to do
94 // layout using fixed precision arithmetic. 160 // layout using fixed precision arithmetic.
95 double _applyFloatingPointHack(double layoutValue) { 161 double _applyFloatingPointHack(double layoutValue) {
96 return layoutValue.ceilToDouble(); 162 return layoutValue.ceilToDouble();
97 } 163 }
98 164
99 class RenderParagraph extends RenderBox { 165 class RenderParagraph extends RenderBox {
100 166
101 RenderParagraph({ 167 RenderParagraph(InlineBase inlineValue) {
102 String text,
103 Color color,
104 TextStyle style
105 }) : _style = style {
106 _layoutRoot.rootElement = _document.createElement('p'); 168 _layoutRoot.rootElement = _document.createElement('p');
107 this.text = text; 169 inline = inlineValue;
108 } 170 }
109 171
110 final sky.Document _document = new sky.Document(); 172 final sky.Document _document = new sky.Document();
111 final sky.LayoutRoot _layoutRoot = new sky.LayoutRoot(); 173 final sky.LayoutRoot _layoutRoot = new sky.LayoutRoot();
112 174
113 String get text => (_layoutRoot.rootElement.firstChild as sky.Text).data; 175 InlineBase _inline;
114 void set text (String value) { 176 BoxConstraints _constraintsForCurrentLayout;
115 _layoutRoot.rootElement.setChild(_document.createText(value)); 177
178 String get inline => _inline;
179 void set inline (InlineBase value) {
180 _inline = value;
181 _layoutRoot.rootElement.setChild(_inline._toDOM(_document));
116 markNeedsLayout(); 182 markNeedsLayout();
117 } 183 }
118 184
119 TextStyle _style;
120 TextStyle get style => _style;
121 void set style (TextStyle value) {
122 if (_style != value) {
123 // TODO(hansmuller): decide if a new layout or paint is needed
124 markNeedsLayout();
125 _style = value;
126 }
127 }
128
129 BoxConstraints _constraintsForCurrentLayout;
130
131 sky.Element _layout(BoxConstraints constraints) { 185 sky.Element _layout(BoxConstraints constraints) {
132 _layoutRoot.maxWidth = constraints.maxWidth; 186 _layoutRoot.maxWidth = constraints.maxWidth;
133 _layoutRoot.minWidth = constraints.minWidth; 187 _layoutRoot.minWidth = constraints.minWidth;
134 _layoutRoot.minHeight = constraints.minHeight; 188 _layoutRoot.minHeight = constraints.minHeight;
135 _layoutRoot.maxHeight = constraints.maxHeight; 189 _layoutRoot.maxHeight = constraints.maxHeight;
136 _layoutRoot.layout(); 190 _layoutRoot.layout();
137 _constraintsForCurrentLayout = constraints; 191 _constraintsForCurrentLayout = constraints;
138 } 192 }
139 193
140 double getMinIntrinsicWidth(BoxConstraints constraints) { 194 double getMinIntrinsicWidth(BoxConstraints constraints) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 // Ideally we could compute the min/max intrinsic width/height with a 229 // Ideally we could compute the min/max intrinsic width/height with a
176 // non-destructive operation. However, currently, computing these values 230 // non-destructive operation. However, currently, computing these values
177 // will destroy state inside the layout root. If that happens, we need to 231 // will destroy state inside the layout root. If that happens, we need to
178 // get back the correct state by calling _layout again. 232 // get back the correct state by calling _layout again.
179 // 233 //
180 // TODO(abarth): Make computing the min/max intrinsic width/height a 234 // TODO(abarth): Make computing the min/max intrinsic width/height a
181 // non-destructive operation. 235 // non-destructive operation.
182 if (_constraintsForCurrentLayout != constraints && constraints != null) 236 if (_constraintsForCurrentLayout != constraints && constraints != null)
183 _layout(constraints); 237 _layout(constraints);
184 238
185 if (style != null) {
186 var cssStyle = _layoutRoot.rootElement.style;
187 if (style.color != null) {
188 Color c = style.color;
189 cssStyle['color'] =
190 'rgba(${c.red}, ${c.green}, ${c.blue}, ${c.alpha / 255.0})';
191 }
192 if (style.fontSize != null) {
193 cssStyle['font-size'] = "${style.fontSize}px";
194 }
195 if (style.fontWeight != null) {
196 cssStyle['font-weight'] = const {
197 FontWeight.light: '300',
198 FontWeight.regular: '400',
199 FontWeight.medium: '500',
200 }[style.fontWeight];
201 }
202 if (style.textAlign != null) {
203 cssStyle['text-align'] = const {
204 TextAlign.left: 'left',
205 TextAlign.right: 'right',
206 TextAlign.center: 'center',
207 }[style.textAlign];
208 }
209 }
210 _layoutRoot.paint(canvas); 239 _layoutRoot.paint(canvas);
211 } 240 }
212 241
213 // we should probably expose a way to do precise (inter-glpyh) hit testing 242 // we should probably expose a way to do precise (inter-glpyh) hit testing
214 243
215 String debugDescribeSettings(String prefix) { 244 String debugDescribeSettings(String prefix) {
216 String result = '${super.debugDescribeSettings(prefix)}'; 245 String result = '${super.debugDescribeSettings(prefix)}';
217 if (style != null) 246 result += '${prefix}inline: ${inline}\n';
218 result += '${prefix}style:\n' + style.toString('$prefix ') + '\n';
219 result += '${prefix}text: ${text}\n';
220 return result; 247 return result;
221 } 248 }
222 } 249 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/editing2/editable_text.dart ('k') | sky/sdk/lib/widgets/basic.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698