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 |