| 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/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/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "base/win/scoped_hdc.h" | 14 #include "ui/gfx/screen_compatible_dc_win.h" |
| 15 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
| 16 #include "ui/gfx/canvas_skia.h" | 16 #include "ui/gfx/canvas_skia.h" |
| 17 #include "ui/gfx/platform_font.h" | 17 #include "ui/gfx/platform_font.h" |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // The maximum supported number of Uniscribe runs; a SCRIPT_ITEM is 8 bytes. | 21 // The maximum supported number of Uniscribe runs; a SCRIPT_ITEM is 8 bytes. |
| 22 // TODO(msw): Review memory use/failure? Max string length? Alternate approach? | 22 // TODO(msw): Review memory use/failure? Max string length? Alternate approach? |
| 23 const int kGuessItems = 100; | 23 const int kGuessItems = 100; |
| 24 const int kMaxItems = 10000; | 24 const int kMaxItems = 10000; |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 script_item++; | 588 script_item++; |
| 589 if (script_item_end >= style_range_end) | 589 if (script_item_end >= style_range_end) |
| 590 style++; | 590 style++; |
| 591 run->range.set_end(run_break); | 591 run->range.set_end(run_break); |
| 592 runs_.push_back(run); | 592 runs_.push_back(run); |
| 593 } | 593 } |
| 594 } | 594 } |
| 595 | 595 |
| 596 void RenderTextWin::LayoutVisualText() { | 596 void RenderTextWin::LayoutVisualText() { |
| 597 HRESULT hr = E_FAIL; | 597 HRESULT hr = E_FAIL; |
| 598 base::win::ScopedCreateDC hdc(CreateCompatibleDC(NULL)); | 598 ScopedTemporaryScreenCompatibleDC hdc; |
| 599 std::vector<internal::TextRun*>::const_iterator run_iter; | 599 std::vector<internal::TextRun*>::const_iterator run_iter; |
| 600 for (run_iter = runs_.begin(); run_iter < runs_.end(); ++run_iter) { | 600 for (run_iter = runs_.begin(); run_iter < runs_.end(); ++run_iter) { |
| 601 internal::TextRun* run = *run_iter; | 601 internal::TextRun* run = *run_iter; |
| 602 size_t run_length = run->range.length(); | 602 size_t run_length = run->range.length(); |
| 603 const wchar_t* run_text = &(text()[run->range.start()]); | 603 const wchar_t* run_text = &(text()[run->range.start()]); |
| 604 bool tried_fallback = false; | 604 bool tried_fallback = false; |
| 605 | 605 |
| 606 // Select the font desired for glyph generation. | 606 // Select the font desired for glyph generation. |
| 607 SelectObject(hdc, run->font.GetNativeFont()); | 607 SelectObject(hdc.get(), run->font.GetNativeFont()); |
| 608 | 608 |
| 609 run->logical_clusters.reset(new WORD[run_length]); | 609 run->logical_clusters.reset(new WORD[run_length]); |
| 610 run->glyph_count = 0; | 610 run->glyph_count = 0; |
| 611 // Max glyph guess: http://msdn.microsoft.com/en-us/library/dd368564.aspx | 611 // Max glyph guess: http://msdn.microsoft.com/en-us/library/dd368564.aspx |
| 612 size_t max_glyphs = static_cast<size_t>(1.5 * run_length + 16); | 612 size_t max_glyphs = static_cast<size_t>(1.5 * run_length + 16); |
| 613 while (max_glyphs < kMaxGlyphs) { | 613 while (max_glyphs < kMaxGlyphs) { |
| 614 run->glyphs.reset(new WORD[max_glyphs]); | 614 run->glyphs.reset(new WORD[max_glyphs]); |
| 615 run->visible_attributes.reset(new SCRIPT_VISATTR[max_glyphs]); | 615 run->visible_attributes.reset(new SCRIPT_VISATTR[max_glyphs]); |
| 616 hr = ScriptShape(hdc, | 616 hr = ScriptShape(hdc.get(), |
| 617 &run->script_cache, | 617 &run->script_cache, |
| 618 run_text, | 618 run_text, |
| 619 run_length, | 619 run_length, |
| 620 max_glyphs, | 620 max_glyphs, |
| 621 &(run->script_analysis), | 621 &(run->script_analysis), |
| 622 run->glyphs.get(), | 622 run->glyphs.get(), |
| 623 run->logical_clusters.get(), | 623 run->logical_clusters.get(), |
| 624 run->visible_attributes.get(), | 624 run->visible_attributes.get(), |
| 625 &(run->glyph_count)); | 625 &(run->glyph_count)); |
| 626 if (hr == E_OUTOFMEMORY) { | 626 if (hr == E_OUTOFMEMORY) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 637 // not found that can display the text. This is expected behavior | 637 // not found that can display the text. This is expected behavior |
| 638 // under Windows XP without additional language packs installed and | 638 // under Windows XP without additional language packs installed and |
| 639 // may also happen on newer versions when trying to display text in | 639 // may also happen on newer versions when trying to display text in |
| 640 // an obscure script that the system doesn't have the right font for. | 640 // an obscure script that the system doesn't have the right font for. |
| 641 hr = 0; | 641 hr = 0; |
| 642 break; | 642 break; |
| 643 } | 643 } |
| 644 | 644 |
| 645 // The run's font doesn't contain the required glyphs, use an alternate. | 645 // The run's font doesn't contain the required glyphs, use an alternate. |
| 646 // TODO(msw): support RenderText's font_list(). | 646 // TODO(msw): support RenderText's font_list(). |
| 647 if (ChooseFallbackFont(hdc, run->font, run_text, run_length, | 647 if (ChooseFallbackFont(hdc.get(), run->font, run_text, run_length, |
| 648 &run->font)) { | 648 &run->font)) { |
| 649 ScriptFreeCache(&run->script_cache); | 649 ScriptFreeCache(&run->script_cache); |
| 650 SelectObject(hdc, run->font.GetNativeFont()); | 650 SelectObject(hdc.get(), run->font.GetNativeFont()); |
| 651 } | 651 } |
| 652 | 652 |
| 653 tried_fallback = true; | 653 tried_fallback = true; |
| 654 } else { | 654 } else { |
| 655 break; | 655 break; |
| 656 } | 656 } |
| 657 } | 657 } |
| 658 DCHECK(SUCCEEDED(hr)); | 658 DCHECK(SUCCEEDED(hr)); |
| 659 | 659 |
| 660 if (run->glyph_count > 0) { | 660 if (run->glyph_count > 0) { |
| 661 run->advance_widths.reset(new int[run->glyph_count]); | 661 run->advance_widths.reset(new int[run->glyph_count]); |
| 662 run->offsets.reset(new GOFFSET[run->glyph_count]); | 662 run->offsets.reset(new GOFFSET[run->glyph_count]); |
| 663 hr = ScriptPlace(hdc, | 663 hr = ScriptPlace(hdc.get(), |
| 664 &run->script_cache, | 664 &run->script_cache, |
| 665 run->glyphs.get(), | 665 run->glyphs.get(), |
| 666 run->glyph_count, | 666 run->glyph_count, |
| 667 run->visible_attributes.get(), | 667 run->visible_attributes.get(), |
| 668 &(run->script_analysis), | 668 &(run->script_analysis), |
| 669 run->advance_widths.get(), | 669 run->advance_widths.get(), |
| 670 run->offsets.get(), | 670 run->offsets.get(), |
| 671 &(run->abc_widths)); | 671 &(run->abc_widths)); |
| 672 DCHECK(SUCCEEDED(hr)); | 672 DCHECK(SUCCEEDED(hr)); |
| 673 } | 673 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 internal::TextRun* run) { | 734 internal::TextRun* run) { |
| 735 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); | 735 size_t caret = IndexOfAdjacentGrapheme(run->range.end(), CURSOR_BACKWARD); |
| 736 return SelectionModel(caret, caret, SelectionModel::LEADING); | 736 return SelectionModel(caret, caret, SelectionModel::LEADING); |
| 737 } | 737 } |
| 738 | 738 |
| 739 RenderText* RenderText::CreateRenderText() { | 739 RenderText* RenderText::CreateRenderText() { |
| 740 return new RenderTextWin; | 740 return new RenderTextWin; |
| 741 } | 741 } |
| 742 | 742 |
| 743 } // namespace gfx | 743 } // namespace gfx |
| OLD | NEW |