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

Side by Side Diff: ui/gfx/render_text_win.cc

Issue 8536047: Separate selection highlight from pango layout (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: fix an lint error Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« ui/gfx/render_text_linux.cc ('K') | « ui/gfx/render_text_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 102
103 RenderTextWin::~RenderTextWin() { 103 RenderTextWin::~RenderTextWin() {
104 ScriptFreeCache(&script_cache_); 104 ScriptFreeCache(&script_cache_);
105 STLDeleteContainerPointers(runs_.begin(), runs_.end()); 105 STLDeleteContainerPointers(runs_.begin(), runs_.end());
106 } 106 }
107 107
108 int RenderTextWin::GetStringWidth() { 108 int RenderTextWin::GetStringWidth() {
109 return string_width_; 109 return string_width_;
110 } 110 }
111 111
112 void RenderTextWin::Draw(Canvas* canvas) {
113 DrawSelection(canvas);
114 DrawVisualText(canvas);
115 DrawCursor(canvas);
116 }
117
118 SelectionModel RenderTextWin::FindCursorPosition(const Point& point) { 112 SelectionModel RenderTextWin::FindCursorPosition(const Point& point) {
119 if (text().empty()) 113 if (text().empty())
120 return SelectionModel(); 114 return SelectionModel();
121 115
122 // Find the run that contains the point and adjust the argument location. 116 // Find the run that contains the point and adjust the argument location.
123 Point p(ToTextPoint(point)); 117 Point p(ToTextPoint(point));
124 size_t run_index = GetRunContainingPoint(p); 118 size_t run_index = GetRunContainingPoint(p);
125 if (run_index == runs_.size()) 119 if (run_index == runs_.size())
126 return (p.x() < 0) ? LeftEndSelectionModel() : RightEndSelectionModel(); 120 return (p.x() < 0) ? LeftEndSelectionModel() : RightEndSelectionModel();
127 internal::TextRun* run = runs_[run_index]; 121 internal::TextRun* run = runs_[run_index];
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 } 308 }
315 309
316 void RenderTextWin::UpdateLayout() { 310 void RenderTextWin::UpdateLayout() {
317 // TODO(msw): Skip complex processing if ScriptIsComplex returns false. 311 // TODO(msw): Skip complex processing if ScriptIsComplex returns false.
318 ItemizeLogicalText(); 312 ItemizeLogicalText();
319 HDC hdc = CreateCompatibleDC(NULL); 313 HDC hdc = CreateCompatibleDC(NULL);
320 LayoutVisualText(hdc); 314 LayoutVisualText(hdc);
321 DeleteDC(hdc); 315 DeleteDC(hdc);
322 } 316 }
323 317
318 void RenderTextWin::DrawVisualText(Canvas* canvas) {
319 if (text().empty())
320 return;
321
322 SkCanvas* canvas_skia = canvas->GetSkCanvas();
323
324 Point offset(ToViewPoint(Point()));
325 // TODO(msw): Establish a vertical baseline for strings of mixed font heights.
326 size_t height = default_style().font.GetHeight();
327
328 SkScalar x = SkIntToScalar(offset.x());
329 SkScalar y = SkIntToScalar(offset.y());
330 // Center the text vertically in the display area.
331 y += (display_rect().height() - height) / 2;
332 // Offset by the font size to account for Skia expecting y to be the bottom.
333 y += default_style().font.GetFontSize();
334
335 SkPaint paint;
336 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
337 paint.setStyle(SkPaint::kFill_Style);
338 paint.setAntiAlias(true);
339 paint.setSubpixelText(true);
340 paint.setLCDRenderText(true);
341
342 std::vector<SkPoint> pos;
343 for (size_t i = 0; i < runs_.size(); ++i) {
344 // Get the run specified by the visual-to-logical map.
345 internal::TextRun* run = runs_[visual_to_logical_[i]];
346
347 // TODO(msw): Font default/fallback and style integration.
348 SkTypeface::Style style = SkTypeface::kNormal;
349 SkTypeface* typeface =
350 SkTypeface::CreateFromName(run->font.GetFontName().c_str(), style);
351 if (typeface) {
352 paint.setTypeface(typeface);
353 // |paint| adds its own ref. Release the ref from CreateFromName.
354 typeface->unref();
355 }
356 paint.setTextSize(run->font.GetFontSize());
357 paint.setColor(run->foreground);
358
359 SkScalar run_x = x;
360
361 // Based on WebCore::skiaDrawText.
362 pos.resize(run->glyph_count);
363 for (int glyph = 0; glyph < run->glyph_count; glyph++) {
364 pos[glyph].set(x + run->offsets[glyph].du,
365 y + run->offsets[glyph].dv);
366 x += SkIntToScalar(run->advance_widths[glyph]);
367 }
368
369 size_t byte_length = run->glyph_count * sizeof(WORD);
370 canvas_skia->drawPosText(run->glyphs.get(), byte_length, &pos[0], paint);
371
372 if (run->strike || run->underline)
373 DrawTextRunDecorations(canvas_skia, paint, *run, run_x, y);
374 }
375 }
376
324 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) { 377 size_t RenderTextWin::IndexOfAdjacentGrapheme(size_t index, bool next) {
325 size_t run_index = GetRunContainingPosition(index); 378 size_t run_index = GetRunContainingPosition(index);
326 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL; 379 internal::TextRun* run = run_index < runs_.size() ? runs_[run_index] : NULL;
327 int start = run ? run->range.start() : 0; 380 int start = run ? run->range.start() : 0;
328 int length = run ? run->range.length() : text().length(); 381 int length = run ? run->range.length() : text().length();
329 int ch = index - start; 382 int ch = index - start;
330 WORD cluster = run ? run->logical_clusters[ch] : 0; 383 WORD cluster = run ? run->logical_clusters[ch] : 0;
331 384
332 if (!next) { 385 if (!next) {
333 do { 386 do {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 638
586 // The character is at the end of its run; go to the next visual run. 639 // The character is at the end of its run; go to the next visual run.
587 size_t visual_index = logical_to_visual_[run_index]; 640 size_t visual_index = logical_to_visual_[run_index];
588 if (visual_index == runs_.size() - 1) 641 if (visual_index == runs_.size() - 1)
589 return RightEndSelectionModel(); 642 return RightEndSelectionModel();
590 internal::TextRun* next = runs_[visual_to_logical_[visual_index + 1]]; 643 internal::TextRun* next = runs_[visual_to_logical_[visual_index + 1]];
591 return next->script_analysis.fRTL ? LastSelectionModelInsideRun(next) : 644 return next->script_analysis.fRTL ? LastSelectionModelInsideRun(next) :
592 FirstSelectionModelInsideRun(next); 645 FirstSelectionModelInsideRun(next);
593 } 646 }
594 647
595 void RenderTextWin::DrawSelection(Canvas* canvas) {
596 std::vector<Rect> sel(
597 GetSubstringBounds(GetSelectionStart(), GetCursorPosition()));
598 SkColor color = focused() ? kFocusedSelectionColor : kUnfocusedSelectionColor;
599 for (std::vector<Rect>::const_iterator i = sel.begin(); i < sel.end(); ++i)
600 canvas->FillRect(color, *i);
601 }
602
603 void RenderTextWin::DrawVisualText(Canvas* canvas) {
604 if (text().empty())
605 return;
606
607 SkCanvas* canvas_skia = canvas->GetSkCanvas();
608
609 Point offset(ToViewPoint(Point()));
610 // TODO(msw): Establish a vertical baseline for strings of mixed font heights.
611 size_t height = default_style().font.GetHeight();
612
613 SkScalar x = SkIntToScalar(offset.x());
614 SkScalar y = SkIntToScalar(offset.y());
615 // Center the text vertically in the display area.
616 y += (display_rect().height() - height) / 2;
617 // Offset by the font size to account for Skia expecting y to be the bottom.
618 y += default_style().font.GetFontSize();
619
620 SkPaint paint;
621 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
622 paint.setStyle(SkPaint::kFill_Style);
623 paint.setAntiAlias(true);
624 paint.setSubpixelText(true);
625 paint.setLCDRenderText(true);
626
627 std::vector<SkPoint> pos;
628 for (size_t i = 0; i < runs_.size(); ++i) {
629 // Get the run specified by the visual-to-logical map.
630 internal::TextRun* run = runs_[visual_to_logical_[i]];
631
632 // TODO(msw): Font default/fallback and style integration.
633 SkTypeface::Style style = SkTypeface::kNormal;
634 SkTypeface* typeface =
635 SkTypeface::CreateFromName(run->font.GetFontName().c_str(), style);
636 if (typeface) {
637 paint.setTypeface(typeface);
638 // |paint| adds its own ref. Release the ref from CreateFromName.
639 typeface->unref();
640 }
641 paint.setTextSize(run->font.GetFontSize());
642 paint.setColor(run->foreground);
643
644 SkScalar run_x = x;
645
646 // Based on WebCore::skiaDrawText.
647 pos.resize(run->glyph_count);
648 for (int glyph = 0; glyph < run->glyph_count; glyph++) {
649 pos[glyph].set(x + run->offsets[glyph].du,
650 y + run->offsets[glyph].dv);
651 x += SkIntToScalar(run->advance_widths[glyph]);
652 }
653
654 size_t byte_length = run->glyph_count * sizeof(WORD);
655 canvas_skia->drawPosText(run->glyphs.get(), byte_length, &pos[0], paint);
656
657 if (run->strike || run->underline)
658 DrawTextRunDecorations(canvas_skia, paint, *run, run_x, y);
659 }
660 }
661
662 void RenderTextWin::DrawCursor(Canvas* canvas) {
663 // Paint cursor. Replace cursor is drawn as rectangle for now.
664 // TODO(msw): Draw a better cursor with a better indication of association.
665 if (cursor_visible() && focused()) {
666 Rect r(GetUpdatedCursorBounds());
667 canvas->DrawRectInt(kCursorColor, r.x(), r.y(), r.width(), r.height());
668 }
669 }
670
671 RenderText* RenderText::CreateRenderText() { 648 RenderText* RenderText::CreateRenderText() {
672 return new RenderTextWin; 649 return new RenderTextWin;
673 } 650 }
674 651
675 } // namespace gfx 652 } // namespace gfx
OLDNEW
« ui/gfx/render_text_linux.cc ('K') | « ui/gfx/render_text_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698