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

Side by Side Diff: samples/swarm/swarm_ui_lib/view/MeasureText.dart

Issue 11361190: a === b -> identical(a, b) (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 // TODO(jacobr): handle splitting lines on symbols such as '-' that aren't 5 // TODO(jacobr): handle splitting lines on symbols such as '-' that aren't
6 // whitespace but are valid word breaking points. 6 // whitespace but are valid word breaking points.
7 /** 7 /**
8 * Utility class to efficiently word break and measure text without requiring 8 * Utility class to efficiently word break and measure text without requiring
9 * access to the DOM. 9 * access to the DOM.
10 */ 10 */
11 class MeasureText { 11 class MeasureText {
12 static CanvasRenderingContext2D _context; 12 static CanvasRenderingContext2D _context;
13 13
14 final String font; 14 final String font;
15 num _spaceLength; 15 num _spaceLength;
16 num _typicalCharLength; 16 num _typicalCharLength;
17 17
18 static const String ELLIPSIS = '...'; 18 static const String ELLIPSIS = '...';
19 19
20 MeasureText(this.font) { 20 MeasureText(this.font) {
21 if (_context === null) { 21 if (_context == null) {
22 CanvasElement canvas = new Element.tag('canvas'); 22 CanvasElement canvas = new Element.tag('canvas');
23 _context = canvas.getContext('2d'); 23 _context = canvas.getContext('2d');
24 } 24 }
25 if (_spaceLength === null) { 25 if (_spaceLength == null) {
26 _context.font = font; 26 _context.font = font;
27 _spaceLength = _context.measureText(' ').width; 27 _spaceLength = _context.measureText(' ').width;
28 _typicalCharLength = _context.measureText('k').width; 28 _typicalCharLength = _context.measureText('k').width;
29 } 29 }
30 } 30 }
31 31
32 // TODO(jacobr): we are DOA for i18N... 32 // TODO(jacobr): we are DOA for i18N...
33 // the right solution is for the server to send us text perparsed into words 33 // the right solution is for the server to send us text perparsed into words
34 // perhaps even with hints on the guess for the correct breaks so on the 34 // perhaps even with hints on the guess for the correct breaks so on the
35 // client all we have to do is verify and fix errors rather than perform the 35 // client all we have to do is verify and fix errors rather than perform the
(...skipping 16 matching lines...) Expand all
52 if (targetLength < text.length) { 52 if (targetLength < text.length) {
53 return '${text.substring(0, targetLength)}$ELLIPSIS'; 53 return '${text.substring(0, targetLength)}$ELLIPSIS';
54 } else { 54 } else {
55 return text; 55 return text;
56 } 56 }
57 } 57 }
58 58
59 /** 59 /**
60 * Add line broken text as html separated by <br> elements. 60 * Add line broken text as html separated by <br> elements.
61 * Returns the number of lines in the output. 61 * Returns the number of lines in the output.
62 * This function is safe to call with [:sb === null:] in which case just the 62 * This function is safe to call with [:sb == null:] in which case just the
63 * line count is returned. 63 * line count is returned.
64 */ 64 */
65 int addLineBrokenText(StringBuffer sb, String text, num lineWidth, 65 int addLineBrokenText(StringBuffer sb, String text, num lineWidth,
66 int maxLines) { 66 int maxLines) {
67 // Strip surrounding whitespace. This ensures we create zero lines if there 67 // Strip surrounding whitespace. This ensures we create zero lines if there
68 // is no visible text. 68 // is no visible text.
69 text = text.trim(); 69 text = text.trim();
70 70
71 // We can often avoid performing a full line break calculation when only 71 // We can often avoid performing a full line break calculation when only
72 // the number of lines and not the actual linebreaks is required. 72 // the number of lines and not the actual linebreaks is required.
73 if (sb === null) { 73 if (sb == null) {
74 _context.font = font; 74 _context.font = font;
75 int textWidth = _context.measureText(text).width.toInt(); 75 int textWidth = _context.measureText(text).width.toInt();
76 // By the pigeon hole principle, the resulting text will require at least 76 // By the pigeon hole principle, the resulting text will require at least
77 // maxLines if the raw text is longer than the amount of text that will 77 // maxLines if the raw text is longer than the amount of text that will
78 // fit on maxLines - 1. We add the length of a whitespace 78 // fit on maxLines - 1. We add the length of a whitespace
79 // character to the lineWidth as each line is separated by a whitespace 79 // character to the lineWidth as each line is separated by a whitespace
80 // character. We assume all whitespace characters have the same length. 80 // character. We assume all whitespace characters have the same length.
81 if (textWidth >= (lineWidth + _spaceLength) * (maxLines - 1)) { 81 if (textWidth >= (lineWidth + _spaceLength) * (maxLines - 1)) {
82 return maxLines; 82 return maxLines;
83 } else if (textWidth == 0) { 83 } else if (textWidth == 0) {
84 return 0; 84 return 0;
85 } else if (textWidth < lineWidth) { 85 } else if (textWidth < lineWidth) {
86 return 1; 86 return 1;
87 } 87 }
88 // Fall through to the regular line breaking calculation as the number 88 // Fall through to the regular line breaking calculation as the number
89 // of lines required is unclear. 89 // of lines required is unclear.
90 } 90 }
91 int lines = 0; 91 int lines = 0;
92 lineBreak(text, lineWidth, maxLines, (int start, int end, num width) { 92 lineBreak(text, lineWidth, maxLines, (int start, int end, num width) {
93 lines++; 93 lines++;
94 if (lines == maxLines) { 94 if (lines == maxLines) {
95 // Overflow case... there may be more lines of text than we can handle. 95 // Overflow case... there may be more lines of text than we can handle.
96 // Add a few characters to the last line so that the browser will 96 // Add a few characters to the last line so that the browser will
97 // render ellipses correctly. 97 // render ellipses correctly.
98 // TODO(jacobr): make this optional and only add characters until 98 // TODO(jacobr): make this optional and only add characters until
99 // the first whitespace character encountered. 99 // the first whitespace character encountered.
100 end = Math.min(end + 50, text.length); 100 end = Math.min(end + 50, text.length);
101 } 101 }
102 if (sb !== null) { 102 if (sb != null) {
103 if (lines > 1) { 103 if (lines > 1) {
104 sb.add('<br>'); 104 sb.add('<br>');
105 } 105 }
106 // TODO(jacobr): HTML escape this text. 106 // TODO(jacobr): HTML escape this text.
107 sb.add(text.substring(start, end)); 107 sb.add(text.substring(start, end));
108 } 108 }
109 }); 109 });
110 return lines; 110 return lines;
111 } 111 }
112 112
(...skipping 16 matching lines...) Expand all
129 num wordLength = _context.measureText(text.substring( 129 num wordLength = _context.measureText(text.substring(
130 wordStartIndex, i)).width; 130 wordStartIndex, i)).width;
131 // TODO(jimhug): Replace the line above with this one to workaround 131 // TODO(jimhug): Replace the line above with this one to workaround
132 // dartium bug - error: unimplemented code 132 // dartium bug - error: unimplemented code
133 // num wordLength = (i - wordStartIndex) * 17; 133 // num wordLength = (i - wordStartIndex) * 17;
134 currentLength += wordLength; 134 currentLength += wordLength;
135 if (currentLength > lineWidth) { 135 if (currentLength > lineWidth) {
136 // Edge case: 136 // Edge case:
137 // It could be the very first word we ran into was too long for a 137 // It could be the very first word we ran into was too long for a
138 // line in which case we let it have its own line. 138 // line in which case we let it have its own line.
139 if (lastWordEndIndex !== null) { 139 if (lastWordEndIndex != null) {
140 lines++; 140 lines++;
141 callback(startIndex, lastWordEndIndex, currentLength - wordLength); 141 callback(startIndex, lastWordEndIndex, currentLength - wordLength);
142 } 142 }
143 if (lines == maxLines) { 143 if (lines == maxLines) {
144 return; 144 return;
145 } 145 }
146 startIndex = wordStartIndex; 146 startIndex = wordStartIndex;
147 currentLength = wordLength; 147 currentLength = wordLength;
148 } 148 }
149 lastWordEndIndex = i; 149 lastWordEndIndex = i;
150 currentLength += _spaceLength; 150 currentLength += _spaceLength;
151 wordStartIndex = null; 151 wordStartIndex = null;
152 } else if (wordStartIndex === null && !whitespace) { 152 } else if (wordStartIndex == null && !whitespace) {
153 wordStartIndex = i; 153 wordStartIndex = i;
154 } 154 }
155 lastWhitespace = whitespace; 155 lastWhitespace = whitespace;
156 } 156 }
157 if (currentLength > 0) { 157 if (currentLength > 0) {
158 callback(startIndex, text.length, currentLength); 158 callback(startIndex, text.length, currentLength);
159 } 159 }
160 } 160 }
161 } 161 }
OLDNEW
« no previous file with comments | « samples/swarm/swarm_ui_lib/view/CompositeView.dart ('k') | samples/swarm/swarm_ui_lib/view/view.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698