| 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/render_text_win.h" | 5 #include "ui/gfx/render_text_win.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 c == base::i18n::kLeftToRightEmbeddingMark || | 125 c == base::i18n::kLeftToRightEmbeddingMark || |
| 126 c == base::i18n::kRightToLeftEmbeddingMark || | 126 c == base::i18n::kRightToLeftEmbeddingMark || |
| 127 c == base::i18n::kPopDirectionalFormatting || | 127 c == base::i18n::kPopDirectionalFormatting || |
| 128 c == base::i18n::kLeftToRightOverride || | 128 c == base::i18n::kLeftToRightOverride || |
| 129 c == base::i18n::kRightToLeftOverride; | 129 c == base::i18n::kRightToLeftOverride; |
| 130 } | 130 } |
| 131 | 131 |
| 132 // Returns the corresponding glyph range of the given character range. | 132 // Returns the corresponding glyph range of the given character range. |
| 133 // |range| is in text-space (0 corresponds to |GetLayoutText()[0]|). | 133 // |range| is in text-space (0 corresponds to |GetLayoutText()[0]|). |
| 134 // Returned value is in run-space (0 corresponds to the first glyph in the run). | 134 // Returned value is in run-space (0 corresponds to the first glyph in the run). |
| 135 ui::Range CharRangeToGlyphRange(const internal::TextRun& run, | 135 gfx::Range CharRangeToGlyphRange(const internal::TextRun& run, |
| 136 const ui::Range& range) { | 136 const gfx::Range& range) { |
| 137 DCHECK(run.range.Contains(range)); | 137 DCHECK(run.range.Contains(range)); |
| 138 DCHECK(!range.is_reversed()); | 138 DCHECK(!range.is_reversed()); |
| 139 DCHECK(!range.is_empty()); | 139 DCHECK(!range.is_empty()); |
| 140 const ui::Range run_range = ui::Range(range.start() - run.range.start(), | 140 const gfx::Range run_range = gfx::Range(range.start() - run.range.start(), |
| 141 range.end() - run.range.start()); | 141 range.end() - run.range.start()); |
| 142 ui::Range result; | 142 gfx::Range result; |
| 143 if (run.script_analysis.fRTL) { | 143 if (run.script_analysis.fRTL) { |
| 144 result = ui::Range(run.logical_clusters[run_range.end() - 1], | 144 result = gfx::Range(run.logical_clusters[run_range.end() - 1], |
| 145 run_range.start() > 0 ? run.logical_clusters[run_range.start() - 1] | 145 run_range.start() > 0 ? run.logical_clusters[run_range.start() - 1] |
| 146 : run.glyph_count); | 146 : run.glyph_count); |
| 147 } else { | 147 } else { |
| 148 result = ui::Range(run.logical_clusters[run_range.start()], | 148 result = gfx::Range(run.logical_clusters[run_range.start()], |
| 149 run_range.end() < run.range.length() ? | 149 run_range.end() < run.range.length() ? |
| 150 run.logical_clusters[run_range.end()] : run.glyph_count); | 150 run.logical_clusters[run_range.end()] : run.glyph_count); |
| 151 } | 151 } |
| 152 DCHECK(!result.is_reversed()); | 152 DCHECK(!result.is_reversed()); |
| 153 DCHECK(ui::Range(0, run.glyph_count).Contains(result)); | 153 DCHECK(gfx::Range(0, run.glyph_count).Contains(result)); |
| 154 return result; | 154 return result; |
| 155 } | 155 } |
| 156 | 156 |
| 157 } // namespace | 157 } // namespace |
| 158 | 158 |
| 159 namespace internal { | 159 namespace internal { |
| 160 | 160 |
| 161 TextRun::TextRun() | 161 TextRun::TextRun() |
| 162 : font_style(0), | 162 : font_style(0), |
| 163 strike(false), | 163 strike(false), |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 DCHECK_LE(cursor, text().length()); | 259 DCHECK_LE(cursor, text().length()); |
| 260 return SelectionModel(cursor, trailing ? CURSOR_BACKWARD : CURSOR_FORWARD); | 260 return SelectionModel(cursor, trailing ? CURSOR_BACKWARD : CURSOR_FORWARD); |
| 261 } | 261 } |
| 262 | 262 |
| 263 std::vector<RenderText::FontSpan> RenderTextWin::GetFontSpansForTesting() { | 263 std::vector<RenderText::FontSpan> RenderTextWin::GetFontSpansForTesting() { |
| 264 EnsureLayout(); | 264 EnsureLayout(); |
| 265 | 265 |
| 266 std::vector<RenderText::FontSpan> spans; | 266 std::vector<RenderText::FontSpan> spans; |
| 267 for (size_t i = 0; i < runs_.size(); ++i) { | 267 for (size_t i = 0; i < runs_.size(); ++i) { |
| 268 spans.push_back(RenderText::FontSpan(runs_[i]->font, | 268 spans.push_back(RenderText::FontSpan(runs_[i]->font, |
| 269 ui::Range(LayoutIndexToTextIndex(runs_[i]->range.start()), | 269 gfx::Range(LayoutIndexToTextIndex(runs_[i]->range.start()), |
| 270 LayoutIndexToTextIndex(runs_[i]->range.end())))); | 270 LayoutIndexToTextIndex(runs_[i]->range.end())))); |
| 271 } | 271 } |
| 272 | 272 |
| 273 return spans; | 273 return spans; |
| 274 } | 274 } |
| 275 | 275 |
| 276 SelectionModel RenderTextWin::AdjacentCharSelectionModel( | 276 SelectionModel RenderTextWin::AdjacentCharSelectionModel( |
| 277 const SelectionModel& selection, | 277 const SelectionModel& selection, |
| 278 VisualCursorDirection direction) { | 278 VisualCursorDirection direction) { |
| 279 DCHECK(!needs_layout_); | 279 DCHECK(!needs_layout_); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 break; | 357 break; |
| 358 } else { | 358 } else { |
| 359 pos = iter.pos() - iter.GetString().length(); | 359 pos = iter.pos() - iter.GetString().length(); |
| 360 } | 360 } |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 return SelectionModel(pos, CURSOR_FORWARD); | 364 return SelectionModel(pos, CURSOR_FORWARD); |
| 365 } | 365 } |
| 366 | 366 |
| 367 ui::Range RenderTextWin::GetGlyphBounds(size_t index) { | 367 gfx::Range RenderTextWin::GetGlyphBounds(size_t index) { |
| 368 const size_t run_index = | 368 const size_t run_index = |
| 369 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD)); | 369 GetRunContainingCaret(SelectionModel(index, CURSOR_FORWARD)); |
| 370 // Return edge bounds if the index is invalid or beyond the layout text size. | 370 // Return edge bounds if the index is invalid or beyond the layout text size. |
| 371 if (run_index >= runs_.size()) | 371 if (run_index >= runs_.size()) |
| 372 return ui::Range(string_size_.width()); | 372 return gfx::Range(string_size_.width()); |
| 373 internal::TextRun* run = runs_[run_index]; | 373 internal::TextRun* run = runs_[run_index]; |
| 374 const size_t layout_index = TextIndexToLayoutIndex(index); | 374 const size_t layout_index = TextIndexToLayoutIndex(index); |
| 375 return ui::Range(GetGlyphXBoundary(run, layout_index, false), | 375 return gfx::Range(GetGlyphXBoundary(run, layout_index, false), |
| 376 GetGlyphXBoundary(run, layout_index, true)); | 376 GetGlyphXBoundary(run, layout_index, true)); |
| 377 } | 377 } |
| 378 | 378 |
| 379 std::vector<Rect> RenderTextWin::GetSubstringBounds(const ui::Range& range) { | 379 std::vector<Rect> RenderTextWin::GetSubstringBounds(const gfx::Range& range) { |
| 380 DCHECK(!needs_layout_); | 380 DCHECK(!needs_layout_); |
| 381 DCHECK(ui::Range(0, text().length()).Contains(range)); | 381 DCHECK(gfx::Range(0, text().length()).Contains(range)); |
| 382 ui::Range layout_range(TextIndexToLayoutIndex(range.start()), | 382 gfx::Range layout_range(TextIndexToLayoutIndex(range.start()), |
| 383 TextIndexToLayoutIndex(range.end())); | 383 TextIndexToLayoutIndex(range.end())); |
| 384 DCHECK(ui::Range(0, GetLayoutText().length()).Contains(layout_range)); | 384 DCHECK(gfx::Range(0, GetLayoutText().length()).Contains(layout_range)); |
| 385 | 385 |
| 386 std::vector<Rect> bounds; | 386 std::vector<Rect> bounds; |
| 387 if (layout_range.is_empty()) | 387 if (layout_range.is_empty()) |
| 388 return bounds; | 388 return bounds; |
| 389 | 389 |
| 390 // Add a Rect for each run/selection intersection. | 390 // Add a Rect for each run/selection intersection. |
| 391 // TODO(msw): The bounds should probably not always be leading the range ends. | 391 // TODO(msw): The bounds should probably not always be leading the range ends. |
| 392 for (size_t i = 0; i < runs_.size(); ++i) { | 392 for (size_t i = 0; i < runs_.size(); ++i) { |
| 393 const internal::TextRun* run = runs_[visual_to_logical_[i]]; | 393 const internal::TextRun* run = runs_[visual_to_logical_[i]]; |
| 394 ui::Range intersection = run->range.Intersect(layout_range); | 394 gfx::Range intersection = run->range.Intersect(layout_range); |
| 395 if (intersection.IsValid()) { | 395 if (intersection.IsValid()) { |
| 396 DCHECK(!intersection.is_reversed()); | 396 DCHECK(!intersection.is_reversed()); |
| 397 ui::Range range_x(GetGlyphXBoundary(run, intersection.start(), false), | 397 gfx::Range range_x(GetGlyphXBoundary(run, intersection.start(), false), |
| 398 GetGlyphXBoundary(run, intersection.end(), false)); | 398 GetGlyphXBoundary(run, intersection.end(), false)); |
| 399 Rect rect(range_x.GetMin(), 0, range_x.length(), run->font.GetHeight()); | 399 Rect rect(range_x.GetMin(), 0, range_x.length(), run->font.GetHeight()); |
| 400 rect.set_origin(ToViewPoint(rect.origin())); | 400 rect.set_origin(ToViewPoint(rect.origin())); |
| 401 // Union this with the last rect if they're adjacent. | 401 // Union this with the last rect if they're adjacent. |
| 402 if (!bounds.empty() && rect.SharesEdgeWith(bounds.back())) { | 402 if (!bounds.empty() && rect.SharesEdgeWith(bounds.back())) { |
| 403 rect.Union(bounds.back()); | 403 rect.Union(bounds.back()); |
| 404 bounds.pop_back(); | 404 bounds.pop_back(); |
| 405 } | 405 } |
| 406 bounds.push_back(rect); | 406 bounds.push_back(rect); |
| 407 } | 407 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 } | 503 } |
| 504 pos.back().set(glyph_x, y); | 504 pos.back().set(glyph_x, y); |
| 505 | 505 |
| 506 renderer.SetTextSize(run->font.GetFontSize()); | 506 renderer.SetTextSize(run->font.GetFontSize()); |
| 507 renderer.SetFontFamilyWithStyle(run->font.GetFontName(), run->font_style); | 507 renderer.SetFontFamilyWithStyle(run->font.GetFontName(), run->font_style); |
| 508 | 508 |
| 509 for (BreakList<SkColor>::const_iterator it = | 509 for (BreakList<SkColor>::const_iterator it = |
| 510 colors().GetBreak(run->range.start()); | 510 colors().GetBreak(run->range.start()); |
| 511 it != colors().breaks().end() && it->first < run->range.end(); | 511 it != colors().breaks().end() && it->first < run->range.end(); |
| 512 ++it) { | 512 ++it) { |
| 513 const ui::Range glyph_range = CharRangeToGlyphRange(*run, | 513 const gfx::Range glyph_range = CharRangeToGlyphRange(*run, |
| 514 colors().GetRange(it).Intersect(run->range)); | 514 colors().GetRange(it).Intersect(run->range)); |
| 515 if (glyph_range.is_empty()) | 515 if (glyph_range.is_empty()) |
| 516 continue; | 516 continue; |
| 517 renderer.SetForegroundColor(it->second); | 517 renderer.SetForegroundColor(it->second); |
| 518 renderer.DrawPosText(&pos[glyph_range.start()], | 518 renderer.DrawPosText(&pos[glyph_range.start()], |
| 519 &run->glyphs[glyph_range.start()], | 519 &run->glyphs[glyph_range.start()], |
| 520 glyph_range.length()); | 520 glyph_range.length()); |
| 521 const SkScalar width = pos[glyph_range.end()].x() - | 521 const SkScalar width = pos[glyph_range.end()].x() - |
| 522 pos[glyph_range.start()].x(); | 522 pos[glyph_range.start()].x(); |
| 523 renderer.DrawDecorations(pos[glyph_range.start()].x(), y, | 523 renderer.DrawDecorations(pos[glyph_range.start()].x(), y, |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 896 size_t position = LayoutIndexToTextIndex(run->range.end()); | 896 size_t position = LayoutIndexToTextIndex(run->range.end()); |
| 897 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); | 897 position = IndexOfAdjacentGrapheme(position, CURSOR_BACKWARD); |
| 898 return SelectionModel(position, CURSOR_FORWARD); | 898 return SelectionModel(position, CURSOR_FORWARD); |
| 899 } | 899 } |
| 900 | 900 |
| 901 RenderText* RenderText::CreateInstance() { | 901 RenderText* RenderText::CreateInstance() { |
| 902 return new RenderTextWin; | 902 return new RenderTextWin; |
| 903 } | 903 } |
| 904 | 904 |
| 905 } // namespace gfx | 905 } // namespace gfx |
| OLD | NEW |