| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/win/scoped_hdc.h" |
| 13 #include "third_party/skia/include/core/SkTypeface.h" | 14 #include "third_party/skia/include/core/SkTypeface.h" |
| 14 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
| 15 #include "ui/gfx/canvas_skia.h" | 16 #include "ui/gfx/canvas_skia.h" |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 | 19 |
| 19 // The maximum supported number of Uniscribe runs; a SCRIPT_ITEM is 8 bytes. | 20 // The maximum supported number of Uniscribe runs; a SCRIPT_ITEM is 8 bytes. |
| 20 // TODO(msw): Review memory use/failure? Max string length? Alternate approach? | 21 // TODO(msw): Review memory use/failure? Max string length? Alternate approach? |
| 21 const int kGuessItems = 100; | 22 const int kGuessItems = 100; |
| 22 const int kMaxItems = 10000; | 23 const int kMaxItems = 10000; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 size_t start = run->range.start(); | 310 size_t start = run->range.start(); |
| 310 if (position == start) | 311 if (position == start) |
| 311 return true; | 312 return true; |
| 312 return run->logical_clusters[position - start] != | 313 return run->logical_clusters[position - start] != |
| 313 run->logical_clusters[position - start - 1]; | 314 run->logical_clusters[position - start - 1]; |
| 314 } | 315 } |
| 315 | 316 |
| 316 void RenderTextWin::UpdateLayout() { | 317 void RenderTextWin::UpdateLayout() { |
| 317 // TODO(msw): Skip complex processing if ScriptIsComplex returns false. | 318 // TODO(msw): Skip complex processing if ScriptIsComplex returns false. |
| 318 ItemizeLogicalText(); | 319 ItemizeLogicalText(); |
| 319 HDC hdc = CreateCompatibleDC(NULL); | 320 if (!runs_.empty()) |
| 320 LayoutVisualText(hdc); | 321 LayoutVisualText(); |
| 321 DeleteDC(hdc); | |
| 322 } | 322 } |
| 323 | 323 |
| 324 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) { | 324 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) { |
| 325 size_t run_index = GetRunContainingPosition(index); | 325 size_t run_index = GetRunContainingPosition(index); |
| 326 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL; | 326 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL; |
| 327 int start = run ? run->range.start() : 0; | 327 int start = run ? run->range.start() : 0; |
| 328 int length = run ? run->range.length() : text().length(); | 328 int length = run ? run->range.length() : text().length(); |
| 329 int ch = index - start; | 329 int ch = index - start; |
| 330 WORD cluster = run ? run->logical_clusters[ch] : 0; | 330 WORD cluster = run ? run->logical_clusters[ch] : 0; |
| 331 | 331 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 run_break = std::min(script_item_end, style_range_end); | 391 run_break = std::min(script_item_end, style_range_end); |
| 392 if (script_item_end <= style_range_end) | 392 if (script_item_end <= style_range_end) |
| 393 script_item++; | 393 script_item++; |
| 394 if (script_item_end >= style_range_end) | 394 if (script_item_end >= style_range_end) |
| 395 style++; | 395 style++; |
| 396 run->range.set_end(run_break); | 396 run->range.set_end(run_break); |
| 397 runs_.push_back(run); | 397 runs_.push_back(run); |
| 398 } | 398 } |
| 399 } | 399 } |
| 400 | 400 |
| 401 void RenderTextWin::LayoutVisualText(HDC hdc) { | 401 void RenderTextWin::LayoutVisualText() { |
| 402 HRESULT hr = E_FAIL; | 402 HRESULT hr = E_FAIL; |
| 403 base::win::ScopedCreateDC hdc(CreateCompatibleDC(NULL)); |
| 403 std::vector<internal::TextRun*>::const_iterator run_iter; | 404 std::vector<internal::TextRun*>::const_iterator run_iter; |
| 404 for (run_iter = runs_.begin(); run_iter < runs_.end(); ++run_iter) { | 405 for (run_iter = runs_.begin(); run_iter < runs_.end(); ++run_iter) { |
| 405 internal::TextRun* run = *run_iter; | 406 internal::TextRun* run = *run_iter; |
| 406 size_t run_length = run->range.length(); | 407 size_t run_length = run->range.length(); |
| 407 const wchar_t* run_text = &(text()[run->range.start()]); | 408 const wchar_t* run_text = &(text()[run->range.start()]); |
| 408 | 409 |
| 409 // Select the font desired for glyph generation. | 410 // Select the font desired for glyph generation. |
| 410 SelectObject(hdc, run->font.GetNativeFont()); | 411 SelectObject(hdc, run->font.GetNativeFont()); |
| 411 | 412 |
| 412 run->logical_clusters.reset(new WORD[run_length]); | 413 run->logical_clusters.reset(new WORD[run_length]); |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 Rect r(GetUpdatedCursorBounds()); | 667 Rect r(GetUpdatedCursorBounds()); |
| 667 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); | 668 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height()); |
| 668 } | 669 } |
| 669 } | 670 } |
| 670 | 671 |
| 671 RenderText* RenderText::CreateRenderText() { | 672 RenderText* RenderText::CreateRenderText() { |
| 672 return new RenderTextWin; | 673 return new RenderTextWin; |
| 673 } | 674 } |
| 674 | 675 |
| 675 } // namespace gfx | 676 } // namespace gfx |
| OLD | NEW |