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

Unified Diff: ui/gfx/render_text_harfbuzz.cc

Issue 738363002: Enable subpixel positioning for UI (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: std::round to std::floor(+0.5) Created 6 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/render_text_harfbuzz.cc
diff --git a/ui/gfx/render_text_harfbuzz.cc b/ui/gfx/render_text_harfbuzz.cc
index 5628b9b5c8d0dbd4dc239ec6cca623299c3622eb..508655b61bf2c04b773b3ab34014bac55d5511b8 100644
--- a/ui/gfx/render_text_harfbuzz.cc
+++ b/ui/gfx/render_text_harfbuzz.cc
@@ -25,6 +25,9 @@
#include "ui/gfx/font_fallback_win.h"
#endif
+using gfx::internal::RangeF;
+using gfx::internal::RoundRangeF;
+
namespace gfx {
namespace {
@@ -461,6 +464,11 @@ void GetClusterAtImpl(size_t pos,
namespace internal {
+Range RoundRangeF(const RangeF& range_f) {
+ return Range(std::floor(range_f.first + 0.5f),
+ std::floor(range_f.second + 0.5f));
+}
+
TextRunHarfBuzz::TextRunHarfBuzz()
: width(0.0f),
preceding_run_widths(0.0f),
@@ -522,21 +530,19 @@ size_t TextRunHarfBuzz::CountMissingGlyphs() const {
return missing;
}
-Range TextRunHarfBuzz::GetGraphemeBounds(
+RangeF TextRunHarfBuzz::GetGraphemeBounds(
base::i18n::BreakIterator* grapheme_iterator,
size_t text_index) {
DCHECK_LT(text_index, range.end());
- // TODO(msw): Support floating point grapheme bounds.
- const int preceding_run_widths_int = SkScalarRoundToInt(preceding_run_widths);
if (glyph_count == 0)
- return Range(preceding_run_widths_int, preceding_run_widths_int + width);
+ return RangeF(preceding_run_widths, preceding_run_widths + width);
Range chars;
Range glyphs;
GetClusterAt(text_index, &chars, &glyphs);
- const int cluster_begin_x = SkScalarRoundToInt(positions[glyphs.start()].x());
- const int cluster_end_x = glyphs.end() < glyph_count ?
- SkScalarRoundToInt(positions[glyphs.end()].x()) : width;
+ const float cluster_begin_x = positions[glyphs.start()].x();
+ const float cluster_end_x = glyphs.end() < glyph_count ?
+ positions[glyphs.end()].x() : SkFloatToScalar(width);
// A cluster consists of a number of code points and corresponds to a number
// of glyphs that should be drawn together. A cluster can contain multiple
@@ -563,13 +569,13 @@ Range TextRunHarfBuzz::GetGraphemeBounds(
cluster_width * before / static_cast<float>(total));
const int grapheme_end_x = cluster_begin_x + static_cast<int>(0.5f +
cluster_width * (before + 1) / static_cast<float>(total));
- return Range(preceding_run_widths_int + grapheme_begin_x,
- preceding_run_widths_int + grapheme_end_x);
+ return RangeF(preceding_run_widths + grapheme_begin_x,
+ preceding_run_widths + grapheme_end_x);
}
}
- return Range(preceding_run_widths_int + cluster_begin_x,
- preceding_run_widths_int + cluster_end_x);
+ return RangeF(preceding_run_widths + cluster_begin_x,
+ preceding_run_widths + cluster_end_x);
}
} // namespace internal
@@ -596,7 +602,7 @@ SelectionModel RenderTextHarfBuzz::FindCursorPosition(const Point& point) {
EnsureLayout();
int x = ToTextPoint(point).x();
- int offset = 0;
+ float offset = 0;
size_t run_index = GetRunContainingXCoord(x, &offset);
if (run_index >= runs_.size())
return EdgeSelectionModel((x < 0) ? CURSOR_LEFT : CURSOR_RIGHT);
@@ -646,8 +652,15 @@ Range RenderTextHarfBuzz::GetGlyphBounds(size_t index) {
return Range(GetStringSize().width());
const size_t layout_index = TextIndexToLayoutIndex(index);
internal::TextRunHarfBuzz* run = runs_[run_index];
- Range bounds = run->GetGraphemeBounds(grapheme_iterator_.get(), layout_index);
- return run->is_rtl ? Range(bounds.end(), bounds.start()) : bounds;
+ RangeF bounds =
+ run->GetGraphemeBounds(grapheme_iterator_.get(), layout_index);
+ // If cursor is enabled, extend the last glyph up to the rightmost cursor
+ // position since clients expect them to be contiguous.
+ if (cursor_enabled() && run_index == runs_.size() - 1 &&
+ index == (run->is_rtl ? run->range.start() : run->range.end() - 1))
+ bounds.second = std::ceil(bounds.second);
+ return RoundRangeF(run->is_rtl ?
+ RangeF(bounds.second, bounds.first) : bounds);
}
int RenderTextHarfBuzz::GetLayoutTextBaseline() {
@@ -778,12 +791,12 @@ std::vector<Rect> RenderTextHarfBuzz::GetSubstringBounds(const Range& range) {
if (!intersection.IsValid())
continue;
DCHECK(!intersection.is_reversed());
- const Range leftmost_character_x = run->GetGraphemeBounds(
+ const Range leftmost_character_x = RoundRangeF(run->GetGraphemeBounds(
grapheme_iterator_.get(),
- run->is_rtl ? intersection.end() - 1 : intersection.start());
- const Range rightmost_character_x = run->GetGraphemeBounds(
+ run->is_rtl ? intersection.end() - 1 : intersection.start()));
+ const Range rightmost_character_x = RoundRangeF(run->GetGraphemeBounds(
grapheme_iterator_.get(),
- run->is_rtl ? intersection.start() : intersection.end() - 1);
+ run->is_rtl ? intersection.start() : intersection.end() - 1));
Range range_x(leftmost_character_x.start(), rightmost_character_x.end());
DCHECK(!range_x.is_reversed());
if (range_x.is_empty())
@@ -911,7 +924,6 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) {
ApplyTextShadows(&renderer);
ApplyCompositionAndSelectionStyles();
- int current_x = 0;
const Vector2d line_offset = GetLineOffset(0);
for (size_t i = 0; i < runs_.size(); ++i) {
const internal::TextRunHarfBuzz& run = *runs_[visual_to_logical_[i]];
@@ -920,11 +932,12 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) {
renderer.SetFontRenderParams(run.render_params,
background_is_transparent());
- Vector2d origin = line_offset + Vector2d(current_x, lines()[0].baseline);
+ Vector2d origin = line_offset + Vector2d(0, lines()[0].baseline);
scoped_ptr<SkPoint[]> positions(new SkPoint[run.glyph_count]);
for (size_t j = 0; j < run.glyph_count; ++j) {
positions[j] = run.positions[j];
- positions[j].offset(SkIntToScalar(origin.x()), SkIntToScalar(origin.y()));
+ positions[j].offset(SkIntToScalar(origin.x()) + run.preceding_run_widths,
+ SkIntToScalar(origin.y()));
}
for (BreakList<SkColor>::const_iterator it =
@@ -946,13 +959,11 @@ void RenderTextHarfBuzz::DrawVisualText(Canvas* canvas) {
colored_glyphs.length());
int start_x = SkScalarRoundToInt(positions[colored_glyphs.start()].x());
int end_x = SkScalarRoundToInt((colored_glyphs.end() == run.glyph_count) ?
- (run.width + SkIntToScalar(origin.x())) :
+ (run.width + run.preceding_run_widths + SkIntToScalar(origin.x())) :
positions[colored_glyphs.end()].x());
renderer.DrawDecorations(start_x, origin.y(), end_x - start_x,
run.underline, run.strike, run.diagonal_strike);
}
-
- current_x += run.width;
}
renderer.EndDiagonalStrike();
@@ -972,12 +983,13 @@ size_t RenderTextHarfBuzz::GetRunContainingCaret(
return runs_.size();
}
-size_t RenderTextHarfBuzz::GetRunContainingXCoord(int x, int* offset) const {
+size_t RenderTextHarfBuzz::GetRunContainingXCoord(float x,
+ float* offset) const {
DCHECK(!needs_layout_);
if (x < 0)
return runs_.size();
// Find the text run containing the argument point (assumed already offset).
- int current_x = 0;
+ float current_x = 0;
for (size_t i = 0; i < runs_.size(); ++i) {
size_t run = visual_to_logical_[i];
current_x += runs_[run]->width;
« no previous file with comments | « ui/gfx/render_text_harfbuzz.h ('k') | ui/gfx/render_text_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698