OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "ui/gfx/canvas.h" | 5 #include "ui/gfx/canvas.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "ui/base/range/range.h" | 10 #include "ui/base/range/range.h" |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 | 162 |
163 return flags; | 163 return flags; |
164 } | 164 } |
165 | 165 |
166 } // namespace | 166 } // namespace |
167 | 167 |
168 // static | 168 // static |
169 void Canvas::SizeStringInt(const string16& text, | 169 void Canvas::SizeStringInt(const string16& text, |
170 const Font& font, | 170 const Font& font, |
171 int* width, int* height, | 171 int* width, int* height, |
| 172 int line_height, |
172 int flags) { | 173 int flags) { |
173 DCHECK_GE(*width, 0); | 174 DCHECK_GE(*width, 0); |
174 DCHECK_GE(*height, 0); | 175 DCHECK_GE(*height, 0); |
175 | 176 |
176 flags = AdjustPlatformSpecificFlags(text, flags); | 177 flags = AdjustPlatformSpecificFlags(text, flags); |
177 | 178 |
178 string16 adjusted_text = text; | 179 string16 adjusted_text = text; |
179 #if defined(OS_WIN) | 180 #if defined(OS_WIN) |
180 AdjustStringDirection(flags, &adjusted_text); | 181 AdjustStringDirection(flags, &adjusted_text); |
181 #endif | 182 #endif |
(...skipping 12 matching lines...) Expand all Loading... |
194 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 195 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
195 UpdateRenderText(rect, string16(), font, flags, 0, render_text.get()); | 196 UpdateRenderText(rect, string16(), font, flags, 0, render_text.get()); |
196 | 197 |
197 int h = 0; | 198 int h = 0; |
198 int w = 0; | 199 int w = 0; |
199 for (size_t i = 0; i < strings.size(); ++i) { | 200 for (size_t i = 0; i < strings.size(); ++i) { |
200 StripAcceleratorChars(flags, &strings[i]); | 201 StripAcceleratorChars(flags, &strings[i]); |
201 render_text->SetText(strings[i]); | 202 render_text->SetText(strings[i]); |
202 const Size string_size = render_text->GetStringSize(); | 203 const Size string_size = render_text->GetStringSize(); |
203 w = std::max(w, string_size.width()); | 204 w = std::max(w, string_size.width()); |
204 h += string_size.height(); | 205 h += (i > 0 && line_height > 0) ? line_height : string_size.height(); |
205 } | 206 } |
206 *width = w; | 207 *width = w; |
207 *height = h; | 208 *height = h; |
208 } else { | 209 } else { |
209 // If the string is too long, the call by |RenderTextWin| to |ScriptShape()| | 210 // If the string is too long, the call by |RenderTextWin| to |ScriptShape()| |
210 // will inexplicably fail with result E_INVALIDARG. Guard against this. | 211 // will inexplicably fail with result E_INVALIDARG. Guard against this. |
211 const size_t kMaxRenderTextLength = 5000; | 212 const size_t kMaxRenderTextLength = 5000; |
212 if (adjusted_text.length() >= kMaxRenderTextLength) { | 213 if (adjusted_text.length() >= kMaxRenderTextLength) { |
213 *width = adjusted_text.length() * font.GetAverageCharacterWidth(); | 214 *width = adjusted_text.length() * font.GetAverageCharacterWidth(); |
214 *height = font.GetHeight(); | 215 *height = font.GetHeight(); |
215 } else { | 216 } else { |
216 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); | 217 scoped_ptr<RenderText> render_text(RenderText::CreateInstance()); |
217 Rect rect(*width, *height); | 218 Rect rect(*width, *height); |
218 StripAcceleratorChars(flags, &adjusted_text); | 219 StripAcceleratorChars(flags, &adjusted_text); |
219 UpdateRenderText(rect, adjusted_text, font, flags, 0, render_text.get()); | 220 UpdateRenderText(rect, adjusted_text, font, flags, 0, render_text.get()); |
220 const Size string_size = render_text->GetStringSize(); | 221 const Size string_size = render_text->GetStringSize(); |
221 *width = string_size.width(); | 222 *width = string_size.width(); |
222 *height = string_size.height(); | 223 *height = string_size.height(); |
223 } | 224 } |
224 } | 225 } |
225 } | 226 } |
226 | 227 |
227 void Canvas::DrawStringWithShadows(const string16& text, | 228 void Canvas::DrawStringWithShadows(const string16& text, |
228 const Font& font, | 229 const Font& font, |
229 SkColor color, | 230 SkColor color, |
230 const Rect& text_bounds, | 231 const Rect& text_bounds, |
| 232 int line_height, |
231 int flags, | 233 int flags, |
232 const ShadowValues& shadows) { | 234 const ShadowValues& shadows) { |
233 if (!IntersectsClipRect(text_bounds)) | 235 if (!IntersectsClipRect(text_bounds)) |
234 return; | 236 return; |
235 | 237 |
236 flags = AdjustPlatformSpecificFlags(text, flags); | 238 flags = AdjustPlatformSpecificFlags(text, flags); |
237 | 239 |
238 Rect clip_rect(text_bounds); | 240 Rect clip_rect(text_bounds); |
239 clip_rect.Inset(ShadowValue::GetMargin(shadows)); | 241 clip_rect.Inset(ShadowValue::GetMargin(shadows)); |
240 | 242 |
(...skipping 20 matching lines...) Expand all Loading... |
261 std::vector<string16> strings; | 263 std::vector<string16> strings; |
262 ui::ElideRectangleText(adjusted_text, | 264 ui::ElideRectangleText(adjusted_text, |
263 font, | 265 font, |
264 text_bounds.width(), text_bounds.height(), | 266 text_bounds.width(), text_bounds.height(), |
265 wrap_behavior, | 267 wrap_behavior, |
266 &strings); | 268 &strings); |
267 | 269 |
268 for (size_t i = 0; i < strings.size(); i++) { | 270 for (size_t i = 0; i < strings.size(); i++) { |
269 ui::Range range = StripAcceleratorChars(flags, &strings[i]); | 271 ui::Range range = StripAcceleratorChars(flags, &strings[i]); |
270 UpdateRenderText(rect, strings[i], font, flags, color, render_text.get()); | 272 UpdateRenderText(rect, strings[i], font, flags, color, render_text.get()); |
271 const int line_height = render_text->GetStringSize().height(); | 273 int line_padding = 0; |
| 274 if (line_height > 0) |
| 275 line_padding = line_height - render_text->GetStringSize().height(); |
| 276 else |
| 277 line_height = render_text->GetStringSize().height(); |
272 | 278 |
273 // TODO(msw|asvitkine): Center Windows multi-line text: crbug.com/107357 | 279 // TODO(msw|asvitkine): Center Windows multi-line text: crbug.com/107357 |
274 #if !defined(OS_WIN) | 280 #if !defined(OS_WIN) |
275 if (i == 0) { | 281 if (i == 0) { |
276 // TODO(msw|asvitkine): Support multi-line text with varied heights. | 282 // TODO(msw|asvitkine): Support multi-line text with varied heights. |
277 const int aggregate_height = strings.size() * line_height; | 283 const int text_height = strings.size() * line_height - line_padding; |
278 rect += Vector2d(0, (text_bounds.height() - aggregate_height) / 2); | 284 rect += Vector2d(0, (text_bounds.height() - text_height) / 2); |
279 } | 285 } |
280 #endif | 286 #endif |
281 | 287 |
282 rect.set_height(line_height); | 288 rect.set_height(line_height - line_padding); |
283 | 289 |
284 if (range.IsValid()) | 290 if (range.IsValid()) |
285 render_text->ApplyStyle(UNDERLINE, true, range); | 291 render_text->ApplyStyle(UNDERLINE, true, range); |
286 render_text->SetDisplayRect(rect); | 292 render_text->SetDisplayRect(rect); |
287 render_text->Draw(this); | 293 render_text->Draw(this); |
288 rect += Vector2d(0, line_height); | 294 rect += Vector2d(0, line_height); |
289 } | 295 } |
290 } else { | 296 } else { |
291 ui::Range range = StripAcceleratorChars(flags, &adjusted_text); | 297 ui::Range range = StripAcceleratorChars(flags, &adjusted_text); |
292 bool elide_text = ((flags & NO_ELLIPSIS) == 0); | 298 bool elide_text = ((flags & NO_ELLIPSIS) == 0); |
(...skipping 13 matching lines...) Expand all Loading... |
306 if (elide_text) { | 312 if (elide_text) { |
307 ElideTextAndAdjustRange(font, | 313 ElideTextAndAdjustRange(font, |
308 text_bounds.width(), | 314 text_bounds.width(), |
309 &adjusted_text, | 315 &adjusted_text, |
310 &range); | 316 &range); |
311 } | 317 } |
312 | 318 |
313 UpdateRenderText(rect, adjusted_text, font, flags, color, | 319 UpdateRenderText(rect, adjusted_text, font, flags, color, |
314 render_text.get()); | 320 render_text.get()); |
315 | 321 |
316 const int line_height = render_text->GetStringSize().height(); | 322 const int text_height = render_text->GetStringSize().height(); |
317 // Center the text vertically. | 323 // Center the text vertically. |
318 rect += Vector2d(0, (text_bounds.height() - line_height) / 2); | 324 rect += Vector2d(0, (text_bounds.height() - text_height) / 2); |
319 rect.set_height(line_height); | 325 rect.set_height(text_height); |
320 render_text->SetDisplayRect(rect); | 326 render_text->SetDisplayRect(rect); |
321 if (range.IsValid()) | 327 if (range.IsValid()) |
322 render_text->ApplyStyle(UNDERLINE, true, range); | 328 render_text->ApplyStyle(UNDERLINE, true, range); |
323 render_text->Draw(this); | 329 render_text->Draw(this); |
324 } | 330 } |
325 | 331 |
326 canvas_->restore(); | 332 canvas_->restore(); |
327 } | 333 } |
328 | 334 |
329 void Canvas::DrawStringWithHalo(const string16& text, | 335 void Canvas::DrawStringWithHalo(const string16& text, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 rect.set_height(line_height); | 444 rect.set_height(line_height); |
439 render_text->SetDisplayRect(rect); | 445 render_text->SetDisplayRect(rect); |
440 | 446 |
441 canvas_->save(SkCanvas::kClip_SaveFlag); | 447 canvas_->save(SkCanvas::kClip_SaveFlag); |
442 ClipRect(display_rect); | 448 ClipRect(display_rect); |
443 render_text->Draw(this); | 449 render_text->Draw(this); |
444 canvas_->restore(); | 450 canvas_->restore(); |
445 } | 451 } |
446 | 452 |
447 } // namespace gfx | 453 } // namespace gfx |
OLD | NEW |