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

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

Issue 440213004: Support float widths in RenderTextHarfBuzz. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update RenderTextWin minimally. Created 6 years, 4 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 | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_win.cc » ('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 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 <map> 7 #include <map>
8 8
9 #include "base/debug/leak_annotations.h" 9 #include "base/debug/leak_annotations.h"
10 #include "base/i18n/bidi_line_iterator.h" 10 #include "base/i18n/bidi_line_iterator.h"
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 DCHECK(!chars->is_empty()); 426 DCHECK(!chars->is_empty());
427 DCHECK(!glyphs->is_reversed()); 427 DCHECK(!glyphs->is_reversed());
428 DCHECK(!glyphs->is_empty()); 428 DCHECK(!glyphs->is_empty());
429 } 429 }
430 430
431 } // namespace 431 } // namespace
432 432
433 namespace internal { 433 namespace internal {
434 434
435 TextRunHarfBuzz::TextRunHarfBuzz() 435 TextRunHarfBuzz::TextRunHarfBuzz()
436 : width(0), 436 : width(0.0f),
437 preceding_run_widths(0), 437 preceding_run_widths(0.0f),
438 is_rtl(false), 438 is_rtl(false),
439 level(0), 439 level(0),
440 script(USCRIPT_INVALID_CODE), 440 script(USCRIPT_INVALID_CODE),
441 glyph_count(static_cast<size_t>(-1)), 441 glyph_count(static_cast<size_t>(-1)),
442 font_size(0), 442 font_size(0),
443 font_style(0), 443 font_style(0),
444 strike(false), 444 strike(false),
445 diagonal_strike(false), 445 diagonal_strike(false),
446 underline(false) {} 446 underline(false) {}
447 447
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 size_t missing = 0; 490 size_t missing = 0;
491 for (size_t i = 0; i < glyph_count; ++i) 491 for (size_t i = 0; i < glyph_count; ++i)
492 missing += (glyphs[i] == kMissingGlyphId) ? 1 : 0; 492 missing += (glyphs[i] == kMissingGlyphId) ? 1 : 0;
493 return missing; 493 return missing;
494 } 494 }
495 495
496 Range TextRunHarfBuzz::GetGraphemeBounds( 496 Range TextRunHarfBuzz::GetGraphemeBounds(
497 base::i18n::BreakIterator* grapheme_iterator, 497 base::i18n::BreakIterator* grapheme_iterator,
498 size_t text_index) { 498 size_t text_index) {
499 DCHECK_LT(text_index, range.end()); 499 DCHECK_LT(text_index, range.end());
500 // TODO(msw): Support floating point grapheme bounds.
501 const int preceding_run_widths_int = SkScalarRoundToInt(preceding_run_widths);
500 if (glyph_count == 0) 502 if (glyph_count == 0)
501 return Range(preceding_run_widths, preceding_run_widths + width); 503 return Range(preceding_run_widths_int, preceding_run_widths_int + width);
502 504
503 Range chars; 505 Range chars;
504 Range glyphs; 506 Range glyphs;
505 GetClusterAt(text_index, &chars, &glyphs); 507 GetClusterAt(text_index, &chars, &glyphs);
506 const int cluster_begin_x = SkScalarRoundToInt(positions[glyphs.start()].x()); 508 const int cluster_begin_x = SkScalarRoundToInt(positions[glyphs.start()].x());
507 const int cluster_end_x = glyphs.end() < glyph_count ? 509 const int cluster_end_x = glyphs.end() < glyph_count ?
508 SkScalarRoundToInt(positions[glyphs.end()].x()) : width; 510 SkScalarRoundToInt(positions[glyphs.end()].x()) : width;
509 511
510 // A cluster consists of a number of code points and corresponds to a number 512 // A cluster consists of a number of code points and corresponds to a number
511 // of glyphs that should be drawn together. A cluster can contain multiple 513 // of glyphs that should be drawn together. A cluster can contain multiple
(...skipping 13 matching lines...) Expand all
525 if (total > 1) { 527 if (total > 1) {
526 if (is_rtl) 528 if (is_rtl)
527 before = total - before - 1; 529 before = total - before - 1;
528 DCHECK_GE(before, 0); 530 DCHECK_GE(before, 0);
529 DCHECK_LT(before, total); 531 DCHECK_LT(before, total);
530 const int cluster_width = cluster_end_x - cluster_begin_x; 532 const int cluster_width = cluster_end_x - cluster_begin_x;
531 const int grapheme_begin_x = cluster_begin_x + static_cast<int>(0.5f + 533 const int grapheme_begin_x = cluster_begin_x + static_cast<int>(0.5f +
532 cluster_width * before / static_cast<float>(total)); 534 cluster_width * before / static_cast<float>(total));
533 const int grapheme_end_x = cluster_begin_x + static_cast<int>(0.5f + 535 const int grapheme_end_x = cluster_begin_x + static_cast<int>(0.5f +
534 cluster_width * (before + 1) / static_cast<float>(total)); 536 cluster_width * (before + 1) / static_cast<float>(total));
535 return Range(preceding_run_widths + grapheme_begin_x, 537 return Range(preceding_run_widths_int + grapheme_begin_x,
536 preceding_run_widths + grapheme_end_x); 538 preceding_run_widths_int + grapheme_end_x);
537 } 539 }
538 } 540 }
539 541
540 return Range(preceding_run_widths + cluster_begin_x, 542 return Range(preceding_run_widths_int + cluster_begin_x,
541 preceding_run_widths + cluster_end_x); 543 preceding_run_widths_int + cluster_end_x);
542 } 544 }
543 545
544 } // namespace internal 546 } // namespace internal
545 547
546 RenderTextHarfBuzz::RenderTextHarfBuzz() 548 RenderTextHarfBuzz::RenderTextHarfBuzz()
547 : RenderText(), 549 : RenderText(),
548 needs_layout_(false) {} 550 needs_layout_(false) {}
549 551
550 RenderTextHarfBuzz::~RenderTextHarfBuzz() {} 552 RenderTextHarfBuzz::~RenderTextHarfBuzz() {}
551 553
552 Size RenderTextHarfBuzz::GetStringSize() { 554 Size RenderTextHarfBuzz::GetStringSize() {
555 const SizeF size_f = GetStringSizeF();
556 return Size(std::ceil(size_f.width()), size_f.height());
557 }
558
559 SizeF RenderTextHarfBuzz::GetStringSizeF() {
553 EnsureLayout(); 560 EnsureLayout();
554 return lines()[0].size; 561 return lines()[0].size;
555 } 562 }
556 563
557 SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) { 564 SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) {
558 EnsureLayout(); 565 EnsureLayout();
559 566
560 int x = ToTextPoint(point).x(); 567 int x = ToTextPoint(point).x();
561 int offset = 0; 568 int offset = 0;
562 size_t run_index = GetRunContainingXCoord(x, &offset); 569 size_t run_index = GetRunContainingXCoord(x, &offset);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 base::i18n::BreakIterator::BREAK_CHARACTER)); 789 base::i18n::BreakIterator::BREAK_CHARACTER));
783 if (!grapheme_iterator_->Init()) 790 if (!grapheme_iterator_->Init())
784 grapheme_iterator_.reset(); 791 grapheme_iterator_.reset();
785 792
786 ItemizeText(); 793 ItemizeText();
787 794
788 for (size_t i = 0; i < runs_.size(); ++i) 795 for (size_t i = 0; i < runs_.size(); ++i)
789 ShapeRun(runs_[i]); 796 ShapeRun(runs_[i]);
790 797
791 // Precalculate run width information. 798 // Precalculate run width information.
792 size_t preceding_run_widths = 0; 799 float preceding_run_widths = 0.0f;
793 for (size_t i = 0; i < runs_.size(); ++i) { 800 for (size_t i = 0; i < runs_.size(); ++i) {
794 internal::TextRunHarfBuzz* run = runs_[visual_to_logical_[i]]; 801 internal::TextRunHarfBuzz* run = runs_[visual_to_logical_[i]];
795 run->preceding_run_widths = preceding_run_widths; 802 run->preceding_run_widths = preceding_run_widths;
796 preceding_run_widths += run->width; 803 preceding_run_widths += run->width;
797 } 804 }
798 } 805 }
799 806
800 needs_layout_ = false; 807 needs_layout_ = false;
801 std::vector<internal::Line> empty_lines; 808 std::vector<internal::Line> empty_lines;
802 set_lines(&empty_lines); 809 set_lines(&empty_lines);
(...skipping 16 matching lines...) Expand all
819 segment.run = i; 826 segment.run = i;
820 lines[0].segments.push_back(segment); 827 lines[0].segments.push_back(segment);
821 828
822 paint.setTypeface(run.skia_face.get()); 829 paint.setTypeface(run.skia_face.get());
823 paint.setTextSize(run.font_size); 830 paint.setTextSize(run.font_size);
824 SkPaint::FontMetrics metrics; 831 SkPaint::FontMetrics metrics;
825 paint.getFontMetrics(&metrics); 832 paint.getFontMetrics(&metrics);
826 833
827 lines[0].size.set_width(lines[0].size.width() + run.width); 834 lines[0].size.set_width(lines[0].size.width() + run.width);
828 lines[0].size.set_height(std::max(lines[0].size.height(), 835 lines[0].size.set_height(std::max(lines[0].size.height(),
829 SkScalarRoundToInt(metrics.fDescent - metrics.fAscent))); 836 metrics.fDescent - metrics.fAscent));
830 lines[0].baseline = std::max(lines[0].baseline, 837 lines[0].baseline = std::max(lines[0].baseline,
831 SkScalarRoundToInt(-metrics.fAscent)); 838 SkScalarRoundToInt(-metrics.fAscent));
832 } 839 }
833 840
834 set_lines(&lines); 841 set_lines(&lines);
835 } 842 }
836 } 843 }
837 844
838 void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) { 845 void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) {
839 DCHECK(!needs_layout_); 846 DCHECK(!needs_layout_);
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 best_font = current_font; 1071 best_font = current_font;
1065 } 1072 }
1066 } 1073 }
1067 1074
1068 if (!best_font.empty() && 1075 if (!best_font.empty() &&
1069 (best_font == current_font || ShapeRunWithFont(run, best_font))) { 1076 (best_font == current_font || ShapeRunWithFont(run, best_font))) {
1070 return; 1077 return;
1071 } 1078 }
1072 1079
1073 run->glyph_count = 0; 1080 run->glyph_count = 0;
1074 run->width = 0; 1081 run->width = 0.0f;
1075 } 1082 }
1076 1083
1077 bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run, 1084 bool RenderTextHarfBuzz::ShapeRunWithFont(internal::TextRunHarfBuzz* run,
1078 const std::string& font_family) { 1085 const std::string& font_family) {
1079 const base::string16& text = GetLayoutText(); 1086 const base::string16& text = GetLayoutText();
1080 skia::RefPtr<SkTypeface> skia_face = 1087 skia::RefPtr<SkTypeface> skia_face =
1081 internal::CreateSkiaTypeface(font_family, run->font_style); 1088 internal::CreateSkiaTypeface(font_family, run->font_style);
1082 if (skia_face == NULL) 1089 if (skia_face == NULL)
1083 return false; 1090 return false;
1084 run->skia_face = skia_face; 1091 run->skia_face = skia_face;
(...skipping 17 matching lines...) Expand all
1102 1109
1103 // Populate the run fields with the resulting glyph data in the buffer. 1110 // Populate the run fields with the resulting glyph data in the buffer.
1104 unsigned int glyph_count = 0; 1111 unsigned int glyph_count = 0;
1105 hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(buffer, &glyph_count); 1112 hb_glyph_info_t* infos = hb_buffer_get_glyph_infos(buffer, &glyph_count);
1106 run->glyph_count = glyph_count; 1113 run->glyph_count = glyph_count;
1107 hb_glyph_position_t* hb_positions = 1114 hb_glyph_position_t* hb_positions =
1108 hb_buffer_get_glyph_positions(buffer, NULL); 1115 hb_buffer_get_glyph_positions(buffer, NULL);
1109 run->glyphs.reset(new uint16[run->glyph_count]); 1116 run->glyphs.reset(new uint16[run->glyph_count]);
1110 run->glyph_to_char.resize(run->glyph_count); 1117 run->glyph_to_char.resize(run->glyph_count);
1111 run->positions.reset(new SkPoint[run->glyph_count]); 1118 run->positions.reset(new SkPoint[run->glyph_count]);
1112 run->width = 0; 1119 run->width = 0.0f;
1113 for (size_t i = 0; i < run->glyph_count; ++i) { 1120 for (size_t i = 0; i < run->glyph_count; ++i) {
1114 run->glyphs[i] = infos[i].codepoint; 1121 run->glyphs[i] = infos[i].codepoint;
1115 run->glyph_to_char[i] = infos[i].cluster; 1122 run->glyph_to_char[i] = infos[i].cluster;
1116 const int x_offset = 1123 const int x_offset = SkFixedToScalar(hb_positions[i].x_offset);
1117 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_offset)); 1124 const int y_offset = SkFixedToScalar(hb_positions[i].y_offset);
1118 const int y_offset =
1119 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].y_offset));
1120 run->positions[i].set(run->width + x_offset, -y_offset); 1125 run->positions[i].set(run->width + x_offset, -y_offset);
1121 run->width += 1126 run->width += SkFixedToScalar(hb_positions[i].x_advance);
1122 SkScalarRoundToInt(SkFixedToScalar(hb_positions[i].x_advance));
1123 } 1127 }
1124 1128
1125 hb_buffer_destroy(buffer); 1129 hb_buffer_destroy(buffer);
1126 hb_font_destroy(harfbuzz_font); 1130 hb_font_destroy(harfbuzz_font);
1127 return true; 1131 return true;
1128 } 1132 }
1129 1133
1130 } // namespace gfx 1134 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698