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

Side by Side Diff: ui/gfx/render_text_harfbuzz.cc

Issue 943093002: Make bigger string size in RenderTextHarfBuzz. Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments addressed Created 5 years, 10 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 | ui/gfx/render_text_unittest.cc » ('j') | ui/gfx/render_text_unittest.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/render_text_harfbuzz.h" 5 #include "ui/gfx/render_text_harfbuzz.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/i18n/bidi_line_iterator.h" 9 #include "base/i18n/bidi_line_iterator.h"
10 #include "base/i18n/break_iterator.h" 10 #include "base/i18n/break_iterator.h"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 const internal::TextRunList& run_list) 226 const internal::TextRunList& run_list)
227 : max_width_((max_width == 0) ? SK_ScalarMax : SkIntToScalar(max_width)), 227 : max_width_((max_width == 0) ? SK_ScalarMax : SkIntToScalar(max_width)),
228 min_baseline_(min_baseline), 228 min_baseline_(min_baseline),
229 min_height_(min_height), 229 min_height_(min_height),
230 multiline_(multiline), 230 multiline_(multiline),
231 text_(text), 231 text_(text),
232 words_(words), 232 words_(words),
233 run_list_(run_list), 233 run_list_(run_list),
234 text_x_(0), 234 text_x_(0),
235 line_x_(0), 235 line_x_(0),
236 max_top_(0),
237 max_bottom_(0),
236 max_descent_(0), 238 max_descent_(0),
237 max_ascent_(0) { 239 max_ascent_(0) {
238 DCHECK_EQ(multiline_, (words_ != nullptr)); 240 DCHECK_EQ(multiline_, (words_ != nullptr));
239 AdvanceLine(); 241 AdvanceLine();
240 } 242 }
241 243
242 // Breaks the run at given |run_index| into Line structs. 244 // Breaks the run at given |run_index| into Line structs.
243 void AddRun(int run_index) { 245 void AddRun(int run_index) {
244 const internal::TextRunHarfBuzz* run = run_list_.runs()[run_index]; 246 const internal::TextRunHarfBuzz* run = run_list_.runs()[run_index];
245 base::char16 first_char = text_[run->range.start()]; 247 base::char16 first_char = text_[run->range.start()];
246 if (multiline_ && first_char == '\n') { 248 if (multiline_ && first_char == '\n') {
247 AdvanceLine(); 249 AdvanceLine();
248 } else if (multiline_ && (line_x_ + SkFloatToScalar(run->width)) > 250 } else if (multiline_ && (line_x_ + SkFloatToScalar(run->width)) >
249 max_width_) { 251 max_width_) {
250 BreakRun(run_index); 252 BreakRun(run_index);
251 } else { 253 } else {
252 AddSegment(run_index, run->range, run->width); 254 AddSegment(run_index, run->range, run->width);
253 } 255 }
254 } 256 }
255 257
256 // Finishes line breaking and outputs the results. Can be called at most once. 258 // Finishes line breaking and outputs the results. Can be called at most once.
257 void Finalize(std::vector<internal::Line>* lines, SizeF* size) { 259 void Finalize(std::vector<internal::Line>* lines, SizeF* size) {
258 DCHECK(!lines_.empty()); 260 DCHECK(!lines_.empty());
261 float trailing_height = std::max(0.f, max_bottom_ - max_descent_);
259 // Add an empty line to finish the line size calculation and remove it. 262 // Add an empty line to finish the line size calculation and remove it.
260 AdvanceLine(); 263 AdvanceLine();
261 lines_.pop_back(); 264 lines_.pop_back();
262 *size = total_size_; 265 *size = total_size_;
266 // Add extra space below the last line, because some characters (eg.
267 // underscore) may be drawn under the descent. See http://crbug.com/459812
268 // and the comments in AdvanceLine() below.
msw 2015/02/26 00:47:21 nit: you can remove this line "// and the comments
269 size->Enlarge(0, trailing_height);
263 lines->swap(lines_); 270 lines->swap(lines_);
264 } 271 }
265 272
266 private: 273 private:
267 // A (line index, segment index) pair that specifies a segment in |lines_|. 274 // A (line index, segment index) pair that specifies a segment in |lines_|.
268 typedef std::pair<size_t, size_t> SegmentHandle; 275 typedef std::pair<size_t, size_t> SegmentHandle;
269 276
270 internal::LineSegment* SegmentFromHandle(const SegmentHandle& handle) { 277 internal::LineSegment* SegmentFromHandle(const SegmentHandle& handle) {
271 return &lines_[handle.first].segments[handle.second]; 278 return &lines_[handle.first].segments[handle.second];
272 } 279 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 internal::Line* line = &lines_.back(); 384 internal::Line* line = &lines_.back();
378 std::sort(line->segments.begin(), line->segments.end(), 385 std::sort(line->segments.begin(), line->segments.end(),
379 [this](const internal::LineSegment& s1, 386 [this](const internal::LineSegment& s1,
380 const internal::LineSegment& s2) -> bool { 387 const internal::LineSegment& s2) -> bool {
381 return run_list_.logical_to_visual(s1.run) < 388 return run_list_.logical_to_visual(s1.run) <
382 run_list_.logical_to_visual(s2.run); 389 run_list_.logical_to_visual(s2.run);
383 }); 390 });
384 line->size.set_height(std::max(min_height_, max_descent_ + max_ascent_)); 391 line->size.set_height(std::max(min_height_, max_descent_ + max_ascent_));
385 line->baseline = 392 line->baseline =
386 std::max(min_baseline_, SkScalarRoundToInt(max_ascent_)); 393 std::max(min_baseline_, SkScalarRoundToInt(max_ascent_));
387 line->preceding_heights = std::ceil(total_size_.height()); 394 // Line height is assumed to be the height between the ascent and the
msw 2015/02/26 00:47:21 nit: consider just using a comment like that above
388 total_size_.set_height(total_size_.height() + line->size.height()); 395 // descent, however some diacritic marks may appear above the ascent.
396 // Therefore prepare enough space above the first line. Note that the
397 // line height wouldn't be the height between top and bottom to avoid
398 // making extra space between lines. See http://crbug.com/459812
399 if (line == &lines_.front()) {
400 line->preceding_heights =
401 std::ceil(std::max(0.f, max_top_ - max_ascent_));
402 total_size_.set_height(line->preceding_heights + line->size.height());
403 } else {
404 line->preceding_heights = std::ceil(total_size_.height());
405 total_size_.set_height(total_size_.height() + line->size.height());
406 }
389 total_size_.set_width(std::max(total_size_.width(), line->size.width())); 407 total_size_.set_width(std::max(total_size_.width(), line->size.width()));
390 } 408 }
409 max_top_ = 0;
410 max_bottom_ = 0;
391 max_descent_ = 0; 411 max_descent_ = 0;
392 max_ascent_ = 0; 412 max_ascent_ = 0;
393 line_x_ = 0; 413 line_x_ = 0;
394 lines_.push_back(internal::Line()); 414 lines_.push_back(internal::Line());
395 } 415 }
396 416
397 // Adds a new segment with the given properties to |lines_.back()|. 417 // Adds a new segment with the given properties to |lines_.back()|.
398 void AddSegment(int run_index, Range char_range, float width) { 418 void AddSegment(int run_index, Range char_range, float width) {
399 if (char_range.is_empty()) { 419 if (char_range.is_empty()) {
400 DCHECK_EQ(0, width); 420 DCHECK_EQ(0, width);
(...skipping 14 matching lines...) Expand all
415 435
416 SkPaint paint; 436 SkPaint paint;
417 paint.setTypeface(run.skia_face.get()); 437 paint.setTypeface(run.skia_face.get());
418 paint.setTextSize(SkIntToScalar(run.font_size)); 438 paint.setTextSize(SkIntToScalar(run.font_size));
419 paint.setAntiAlias(run.render_params.antialiasing); 439 paint.setAntiAlias(run.render_params.antialiasing);
420 SkPaint::FontMetrics metrics; 440 SkPaint::FontMetrics metrics;
421 paint.getFontMetrics(&metrics); 441 paint.getFontMetrics(&metrics);
422 442
423 line->size.set_width(line->size.width() + width); 443 line->size.set_width(line->size.width() + width);
424 max_descent_ = std::max(max_descent_, metrics.fDescent); 444 max_descent_ = std::max(max_descent_, metrics.fDescent);
425 // fAscent is always negative. 445 max_bottom_ = std::max(max_bottom_, metrics.fBottom);
446 // fAscent and fTop are always negative.
426 max_ascent_ = std::max(max_ascent_, -metrics.fAscent); 447 max_ascent_ = std::max(max_ascent_, -metrics.fAscent);
448 max_top_ = std::max(max_top_, -metrics.fTop);
427 449
428 if (run.is_rtl) { 450 if (run.is_rtl) {
429 rtl_segments_.push_back( 451 rtl_segments_.push_back(
430 SegmentHandle(lines_.size() - 1, line->segments.size() - 1)); 452 SegmentHandle(lines_.size() - 1, line->segments.size() - 1));
431 // If this is the last segment of an RTL run, reprocess the text-space x 453 // If this is the last segment of an RTL run, reprocess the text-space x
432 // ranges of all segments from the run. 454 // ranges of all segments from the run.
433 if (char_range.end() == run.range.end()) 455 if (char_range.end() == run.range.end())
434 UpdateRTLSegmentRanges(); 456 UpdateRTLSegmentRanges();
435 } 457 }
436 text_x_ += SkFloatToScalar(width); 458 text_x_ += SkFloatToScalar(width);
437 line_x_ += SkFloatToScalar(width); 459 line_x_ += SkFloatToScalar(width);
438 } 460 }
439 461
440 const SkScalar max_width_; 462 const SkScalar max_width_;
441 const int min_baseline_; 463 const int min_baseline_;
442 const float min_height_; 464 const float min_height_;
443 const bool multiline_; 465 const bool multiline_;
444 const base::string16& text_; 466 const base::string16& text_;
445 const BreakList<size_t>* const words_; 467 const BreakList<size_t>* const words_;
446 const internal::TextRunList& run_list_; 468 const internal::TextRunList& run_list_;
447 469
448 // Stores the resulting lines. 470 // Stores the resulting lines.
449 std::vector<internal::Line> lines_; 471 std::vector<internal::Line> lines_;
450 472
451 // Text space and line space x coordinates of the next segment to be added. 473 // Text space and line space x coordinates of the next segment to be added.
452 SkScalar text_x_; 474 SkScalar text_x_;
453 SkScalar line_x_; 475 SkScalar line_x_;
454 476
477 float max_top_;
478 float max_bottom_;
455 float max_descent_; 479 float max_descent_;
456 float max_ascent_; 480 float max_ascent_;
457 481
458 // Size of the multiline text, not including the currently processed line. 482 // Size of the multiline text, not including the currently processed line.
459 SizeF total_size_; 483 SizeF total_size_;
460 484
461 // The current RTL run segments, to be applied by |UpdateRTLSegmentRanges()|. 485 // The current RTL run segments, to be applied by |UpdateRTLSegmentRanges()|.
462 std::vector<SegmentHandle> rtl_segments_; 486 std::vector<SegmentHandle> rtl_segments_;
463 487
464 DISALLOW_COPY_AND_ASSIGN(HarfBuzzLineBreaker); 488 DISALLOW_COPY_AND_ASSIGN(HarfBuzzLineBreaker);
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 DCHECK(!update_layout_run_list_); 1492 DCHECK(!update_layout_run_list_);
1469 DCHECK(!update_display_run_list_); 1493 DCHECK(!update_display_run_list_);
1470 return text_elided() ? display_run_list_.get() : &layout_run_list_; 1494 return text_elided() ? display_run_list_.get() : &layout_run_list_;
1471 } 1495 }
1472 1496
1473 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const { 1497 const internal::TextRunList* RenderTextHarfBuzz::GetRunList() const {
1474 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList(); 1498 return const_cast<RenderTextHarfBuzz*>(this)->GetRunList();
1475 } 1499 }
1476 1500
1477 } // namespace gfx 1501 } // namespace gfx
OLDNEW
« no previous file with comments | « no previous file | ui/gfx/render_text_unittest.cc » ('j') | ui/gfx/render_text_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698