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

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

Issue 8392011: GTK: Step 1 of tab strip refresh. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: More cleanup 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
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/canvas_skia.h" 5 #include "ui/gfx/canvas_skia.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include <cairo/cairo.h> 9 #include <cairo/cairo.h>
10 #include <pango/pango.h> 10 #include <pango/pango.h>
11 #include <pango/pangocairo.h> 11 #include <pango/pangocairo.h>
12 12
13 #include "base/i18n/rtl.h" 13 #include "base/i18n/rtl.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "ui/gfx/font.h" 15 #include "ui/gfx/font.h"
16 #include "ui/gfx/pango_util.h" 16 #include "ui/gfx/pango_util.h"
17 #include "ui/gfx/platform_font_pango.h" 17 #include "ui/gfx/platform_font_pango.h"
18 #include "ui/gfx/rect.h" 18 #include "ui/gfx/rect.h"
19 #include "ui/gfx/skia_util.h" 19 #include "ui/gfx/skia_util.h"
20 20
21 #if defined(TOOLKIT_USES_GTK) 21 #if defined(TOOLKIT_USES_GTK)
22 #include <gdk/gdk.h> 22 #include <gdk/gdk.h>
23 #endif 23 #endif
24 24
25 using std::max; 25 using std::max;
26 26
27 namespace { 27 namespace {
28 28
29 // Multiply by the text height to determine how much text should be faded
30 // when elliding.
31 const double kFadeWidthFactor = 1.5;
32
33 // End state of the elliding fade.
34 const double kFadeFinalAlpha = 0.15;
35
36 // Width of the border drawn around haloed text. 29 // Width of the border drawn around haloed text.
37 const double kTextHaloWidth = 1.0; 30 const double kTextHaloWidth = 1.0;
38 31
39 // A class to encapsulate string drawing params and operations. 32 // A class to encapsulate string drawing params and operations.
40 class DrawStringContext { 33 class DrawStringContext : public gfx::PangoDrawString {
41 public: 34 public:
42 DrawStringContext(gfx::CanvasSkia* canvas, 35 DrawStringContext(gfx::CanvasSkia* canvas,
43 const string16& text, 36 const string16& text,
44 const gfx::Font& font, 37 const gfx::Font& font,
45 const gfx::Rect& bounds, 38 const gfx::Rect& bounds,
46 const gfx::Rect& clip, 39 const gfx::Rect& clip,
47 int flags); 40 int flags);
48 ~DrawStringContext(); 41 ~DrawStringContext();
49 42
50 void Draw(const SkColor& text_color);
51 void DrawWithHalo(const SkColor& text_color, const SkColor& halo_color); 43 void DrawWithHalo(const SkColor& text_color, const SkColor& halo_color);
52 44
53 private: 45 private:
54 // Draw an underline under the text using |cr|, which must already be
55 // initialized with the correct source. |extra_edge_width| is added to the
56 // outer edge of the line. Helper method for Draw() and DrawWithHalo().
57 void DrawUnderline(cairo_t* cr, double extra_edge_width);
58
59 const gfx::Rect& bounds_;
60 int flags_;
61 const gfx::Font& font_;
62
63 gfx::CanvasSkia* canvas_; 46 gfx::CanvasSkia* canvas_;
64 cairo_t* cr_;
65 PangoLayout* layout_;
66
67 int text_x_;
68 int text_y_;
69 int text_width_;
70 int text_height_;
71
72 base::i18n::TextDirection text_direction_;
73 47
74 DISALLOW_COPY_AND_ASSIGN(DrawStringContext); 48 DISALLOW_COPY_AND_ASSIGN(DrawStringContext);
75 }; 49 };
76 50
77 DrawStringContext::DrawStringContext(gfx::CanvasSkia* canvas, 51 DrawStringContext::DrawStringContext(gfx::CanvasSkia* canvas,
78 const string16& text, 52 const string16& text,
79 const gfx::Font& font, 53 const gfx::Font& font,
80 const gfx::Rect& bounds, 54 const gfx::Rect& bounds,
81 const gfx::Rect& clip, 55 const gfx::Rect& clip,
82 int flags) 56 int flags)
83 : bounds_(bounds), 57 : PangoDrawString(skia::BeginPlatformPaint(canvas->sk_canvas()),
84 flags_(flags), 58 text,
85 font_(font), 59 font,
86 canvas_(canvas), 60 bounds,
87 cr_(NULL), 61 clip,
88 layout_(NULL), 62 flags),
89 text_x_(bounds.x()), 63 canvas_(canvas) {
90 text_y_(bounds.y()),
91 text_width_(0),
92 text_height_(0),
93 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) {
94 DCHECK(!bounds_.IsEmpty());
95
96 cr_ = skia::BeginPlatformPaint(canvas_->sk_canvas());
97 layout_ = pango_cairo_create_layout(cr_);
98
99 gfx::SetupPangoLayout(
100 layout_, text, font, bounds_.width(), text_direction_, flags_);
101
102 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE);
103
104 cairo_save(cr_);
105
106 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height());
107 cairo_clip(cr_);
108
109 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_);
110
111 if (flags_ & gfx::Canvas::TEXT_VALIGN_TOP) {
112 // Cairo should draw from the top left corner already.
113 } else if (flags_ & gfx::Canvas::TEXT_VALIGN_BOTTOM) {
114 text_y_ += (bounds.height() - text_height_);
115 } else {
116 // Vertically centered.
117 text_y_ += ((bounds.height() - text_height_) / 2);
118 }
119 } 64 }
120 65
121 DrawStringContext::~DrawStringContext() { 66 DrawStringContext::~DrawStringContext() {
122 cairo_restore(cr_);
123 skia::EndPlatformPaint(canvas_->sk_canvas()); 67 skia::EndPlatformPaint(canvas_->sk_canvas());
124 g_object_unref(layout_);
125 // NOTE: BeginPlatformPaint returned its surface, we shouldn't destroy it.
126 }
127
128 void DrawStringContext::Draw(const SkColor& text_color) {
129 double r = SkColorGetR(text_color) / 255.0,
130 g = SkColorGetG(text_color) / 255.0,
131 b = SkColorGetB(text_color) / 255.0,
132 a = SkColorGetA(text_color) / 255.0;
133
134 cairo_pattern_t* pattern = NULL;
135
136 cairo_save(cr_);
137
138 // If we're not eliding, use a fixed color.
139 // Otherwise, create a gradient pattern to use as the source.
140 if (text_direction_ == base::i18n::RIGHT_TO_LEFT ||
141 (flags_ & gfx::Canvas::NO_ELLIPSIS) ||
142 text_width_ <= bounds_.width()) {
143 cairo_set_source_rgba(cr_, r, g, b, a);
144 } else {
145 // Fade to semi-transparent to elide.
146 int fade_width = static_cast<double>(text_height_) * kFadeWidthFactor;
147 if (fade_width > (bounds_.width() / 2)) {
148 // Don't fade more than half the text.
149 fade_width = bounds_.width() / 2;
150 }
151 int fade_x = bounds_.x() + bounds_.width() - fade_width;
152
153 pattern = cairo_pattern_create_linear(
154 fade_x, bounds_.y(), bounds_.x() + bounds_.width(), bounds_.y());
155 cairo_pattern_add_color_stop_rgba(pattern, 0, r, g, b, a);
156 cairo_pattern_add_color_stop_rgba(pattern, 1, r, g, b, kFadeFinalAlpha);
157 cairo_set_source(cr_, pattern);
158 }
159
160 cairo_move_to(cr_, text_x_, text_y_);
161 pango_cairo_show_layout(cr_, layout_);
162
163 if (font_.GetStyle() & gfx::Font::UNDERLINED)
164 DrawUnderline(cr_, 0.0);
165
166 if (pattern)
167 cairo_pattern_destroy(pattern);
168
169 cairo_restore(cr_);
170 } 68 }
171 69
172 void DrawStringContext::DrawWithHalo(const SkColor& text_color, 70 void DrawStringContext::DrawWithHalo(const SkColor& text_color,
173 const SkColor& halo_color) { 71 const SkColor& halo_color) {
174 gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false); 72 gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false);
175 text_canvas.FillRectInt(static_cast<SkColor>(0), 73 text_canvas.FillRectInt(static_cast<SkColor>(0),
176 0, 0, bounds_.width() + 2, bounds_.height() + 2); 74 0, 0, bounds_.width() + 2, bounds_.height() + 2);
177 75
178 { 76 {
179 skia::ScopedPlatformPaint scoped_platform_paint(text_canvas.sk_canvas()); 77 skia::ScopedPlatformPaint scoped_platform_paint(text_canvas.sk_canvas());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 111
214 if (font_.GetStyle() & gfx::Font::UNDERLINED) 112 if (font_.GetStyle() & gfx::Font::UNDERLINED)
215 DrawUnderline(text_cr, 0.0); 113 DrawUnderline(text_cr, 0.0);
216 } 114 }
217 115
218 const SkBitmap& text_bitmap = const_cast<SkBitmap&>( 116 const SkBitmap& text_bitmap = const_cast<SkBitmap&>(
219 skia::GetTopDevice(*text_canvas.sk_canvas())->accessBitmap(false)); 117 skia::GetTopDevice(*text_canvas.sk_canvas())->accessBitmap(false));
220 canvas_->DrawBitmapInt(text_bitmap, text_x_ - 1, text_y_ - 1); 118 canvas_->DrawBitmapInt(text_bitmap, text_x_ - 1, text_y_ - 1);
221 } 119 }
222 120
223 void DrawStringContext::DrawUnderline(cairo_t* cr, double extra_edge_width) {
224 gfx::PlatformFontPango* platform_font =
225 static_cast<gfx::PlatformFontPango*>(font_.platform_font());
226 const double underline_y =
227 static_cast<double>(text_y_) + text_height_ +
228 platform_font->underline_position();
229 cairo_set_line_width(
230 cr, platform_font->underline_thickness() + 2 * extra_edge_width);
231 cairo_move_to(cr, text_x_ - extra_edge_width, underline_y);
232 cairo_line_to(cr, text_x_ + text_width_ + extra_edge_width, underline_y);
233 cairo_stroke(cr);
234 }
235
236 } // namespace 121 } // namespace
237 122
238 namespace gfx { 123 namespace gfx {
239 124
240 // static 125 // static
241 void CanvasSkia::SizeStringInt(const string16& text, 126 void CanvasSkia::SizeStringInt(const string16& text,
242 const gfx::Font& font, 127 const gfx::Font& font,
243 int* width, int* height, 128 int* width, int* height,
244 int flags) { 129 int flags) {
245 int org_width = *width; 130 int org_width = *width;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 cairo_paint(cr); 219 cairo_paint(cr);
335 } 220 }
336 #endif // defined(TOOLKIT_USES_GTK) 221 #endif // defined(TOOLKIT_USES_GTK)
337 222
338 ui::TextureID CanvasSkia::GetTextureID() { 223 ui::TextureID CanvasSkia::GetTextureID() {
339 // TODO(wjmaclean) 224 // TODO(wjmaclean)
340 return 0; 225 return 0;
341 } 226 }
342 227
343 } // namespace gfx 228 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698