| 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/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> |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 canvas_(canvas), | 86 canvas_(canvas), |
| 87 cr_(NULL), | 87 cr_(NULL), |
| 88 layout_(NULL), | 88 layout_(NULL), |
| 89 text_x_(bounds.x()), | 89 text_x_(bounds.x()), |
| 90 text_y_(bounds.y()), | 90 text_y_(bounds.y()), |
| 91 text_width_(0), | 91 text_width_(0), |
| 92 text_height_(0), | 92 text_height_(0), |
| 93 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) { | 93 text_direction_(base::i18n::GetFirstStrongCharacterDirection(text)) { |
| 94 DCHECK(!bounds_.IsEmpty()); | 94 DCHECK(!bounds_.IsEmpty()); |
| 95 | 95 |
| 96 cr_ = skia::BeginPlatformPaint(canvas_); | 96 cr_ = skia::BeginPlatformPaint(canvas_->sk_canvas()); |
| 97 layout_ = pango_cairo_create_layout(cr_); | 97 layout_ = pango_cairo_create_layout(cr_); |
| 98 | 98 |
| 99 gfx::SetupPangoLayout( | 99 gfx::SetupPangoLayout( |
| 100 layout_, text, font, bounds_.width(), text_direction_, flags_); | 100 layout_, text, font, bounds_.width(), text_direction_, flags_); |
| 101 | 101 |
| 102 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE); | 102 pango_layout_set_height(layout_, bounds_.height() * PANGO_SCALE); |
| 103 | 103 |
| 104 cairo_save(cr_); | 104 cairo_save(cr_); |
| 105 | 105 |
| 106 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height()); | 106 cairo_rectangle(cr_, clip.x(), clip.y(), clip.width(), clip.height()); |
| 107 cairo_clip(cr_); | 107 cairo_clip(cr_); |
| 108 | 108 |
| 109 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_); | 109 pango_layout_get_pixel_size(layout_, &text_width_, &text_height_); |
| 110 | 110 |
| 111 if (flags_ & gfx::Canvas::TEXT_VALIGN_TOP) { | 111 if (flags_ & gfx::Canvas::TEXT_VALIGN_TOP) { |
| 112 // Cairo should draw from the top left corner already. | 112 // Cairo should draw from the top left corner already. |
| 113 } else if (flags_ & gfx::Canvas::TEXT_VALIGN_BOTTOM) { | 113 } else if (flags_ & gfx::Canvas::TEXT_VALIGN_BOTTOM) { |
| 114 text_y_ += (bounds.height() - text_height_); | 114 text_y_ += (bounds.height() - text_height_); |
| 115 } else { | 115 } else { |
| 116 // Vertically centered. | 116 // Vertically centered. |
| 117 text_y_ += ((bounds.height() - text_height_) / 2); | 117 text_y_ += ((bounds.height() - text_height_) / 2); |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 DrawStringContext::~DrawStringContext() { | 121 DrawStringContext::~DrawStringContext() { |
| 122 cairo_restore(cr_); | 122 cairo_restore(cr_); |
| 123 skia::EndPlatformPaint(canvas_); | 123 skia::EndPlatformPaint(canvas_->sk_canvas()); |
| 124 g_object_unref(layout_); | 124 g_object_unref(layout_); |
| 125 // NOTE: BeginPlatformPaint returned its surface, we shouldn't destroy it. | 125 // NOTE: BeginPlatformPaint returned its surface, we shouldn't destroy it. |
| 126 } | 126 } |
| 127 | 127 |
| 128 void DrawStringContext::Draw(const SkColor& text_color) { | 128 void DrawStringContext::Draw(const SkColor& text_color) { |
| 129 double r = SkColorGetR(text_color) / 255.0, | 129 double r = SkColorGetR(text_color) / 255.0, |
| 130 g = SkColorGetG(text_color) / 255.0, | 130 g = SkColorGetG(text_color) / 255.0, |
| 131 b = SkColorGetB(text_color) / 255.0, | 131 b = SkColorGetB(text_color) / 255.0, |
| 132 a = SkColorGetA(text_color) / 255.0; | 132 a = SkColorGetA(text_color) / 255.0; |
| 133 | 133 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 cairo_restore(cr_); | 169 cairo_restore(cr_); |
| 170 } | 170 } |
| 171 | 171 |
| 172 void DrawStringContext::DrawWithHalo(const SkColor& text_color, | 172 void DrawStringContext::DrawWithHalo(const SkColor& text_color, |
| 173 const SkColor& halo_color) { | 173 const SkColor& halo_color) { |
| 174 gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false); | 174 gfx::CanvasSkia text_canvas(bounds_.width() + 2, bounds_.height() + 2, false); |
| 175 text_canvas.FillRectInt(static_cast<SkColor>(0), | 175 text_canvas.FillRectInt(static_cast<SkColor>(0), |
| 176 0, 0, bounds_.width() + 2, bounds_.height() + 2); | 176 0, 0, bounds_.width() + 2, bounds_.height() + 2); |
| 177 | 177 |
| 178 { | 178 { |
| 179 skia::ScopedPlatformPaint scoped_platform_paint(&text_canvas); | 179 skia::ScopedPlatformPaint scoped_platform_paint(text_canvas.sk_canvas()); |
| 180 cairo_t* text_cr = scoped_platform_paint.GetPlatformSurface(); | 180 cairo_t* text_cr = scoped_platform_paint.GetPlatformSurface(); |
| 181 | 181 |
| 182 // TODO: The current approach (stroking the text path to generate the halo | 182 // TODO: The current approach (stroking the text path to generate the halo |
| 183 // and then filling it for the main text) won't work if |text_color| is | 183 // and then filling it for the main text) won't work if |text_color| is |
| 184 // non-opaque. If we need to do this at some later point, | 184 // non-opaque. If we need to do this at some later point, |
| 185 // http://lists.freedesktop.org/archives/cairo/2004-September/001829.html | 185 // http://lists.freedesktop.org/archives/cairo/2004-September/001829.html |
| 186 // suggests "do[ing] the stroke and fill with opaque paint onto an | 186 // suggests "do[ing] the stroke and fill with opaque paint onto an |
| 187 // intermediate surface, and then us[ing] cairo_show_surface to composite | 187 // intermediate surface, and then us[ing] cairo_show_surface to composite |
| 188 // that intermediate result with the desired compositing operator." | 188 // that intermediate result with the desired compositing operator." |
| 189 cairo_set_source_rgba(text_cr, | 189 cairo_set_source_rgba(text_cr, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 209 SkColorGetG(text_color) / 255.0, | 209 SkColorGetG(text_color) / 255.0, |
| 210 SkColorGetB(text_color) / 255.0, | 210 SkColorGetB(text_color) / 255.0, |
| 211 SkColorGetA(text_color) / 255.0); | 211 SkColorGetA(text_color) / 255.0); |
| 212 cairo_fill(text_cr); | 212 cairo_fill(text_cr); |
| 213 | 213 |
| 214 if (font_.GetStyle() & gfx::Font::UNDERLINED) | 214 if (font_.GetStyle() & gfx::Font::UNDERLINED) |
| 215 DrawUnderline(text_cr, 0.0); | 215 DrawUnderline(text_cr, 0.0); |
| 216 } | 216 } |
| 217 | 217 |
| 218 const SkBitmap& text_bitmap = const_cast<SkBitmap&>( | 218 const SkBitmap& text_bitmap = const_cast<SkBitmap&>( |
| 219 skia::GetTopDevice(text_canvas)->accessBitmap(false)); | 219 skia::GetTopDevice(*text_canvas.sk_canvas())->accessBitmap(false)); |
| 220 canvas_->DrawBitmapInt(text_bitmap, text_x_ - 1, text_y_ - 1); | 220 canvas_->DrawBitmapInt(text_bitmap, text_x_ - 1, text_y_ - 1); |
| 221 } | 221 } |
| 222 | 222 |
| 223 void DrawStringContext::DrawUnderline(cairo_t* cr, double extra_edge_width) { | 223 void DrawStringContext::DrawUnderline(cairo_t* cr, double extra_edge_width) { |
| 224 gfx::PlatformFontPango* platform_font = | 224 gfx::PlatformFontPango* platform_font = |
| 225 static_cast<gfx::PlatformFontPango*>(font_.platform_font()); | 225 static_cast<gfx::PlatformFontPango*>(font_.platform_font()); |
| 226 const double underline_y = | 226 const double underline_y = |
| 227 static_cast<double>(text_y_) + text_height_ + | 227 static_cast<double>(text_y_) + text_height_ + |
| 228 platform_font->underline_position(); | 228 platform_font->underline_position(); |
| 229 cairo_set_line_width( | 229 cairo_set_line_width( |
| 230 cr, platform_font->underline_thickness() + 2 * extra_edge_width); | 230 cr, platform_font->underline_thickness() + 2 * extra_edge_width); |
| 231 cairo_move_to(cr, text_x_ - extra_edge_width, underline_y); | 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); | 232 cairo_line_to(cr, text_x_ + text_width_ + extra_edge_width, underline_y); |
| 233 cairo_stroke(cr); | 233 cairo_stroke(cr); |
| 234 } | 234 } |
| 235 | 235 |
| 236 } // namespace | 236 } // namespace |
| 237 | 237 |
| 238 namespace gfx { | 238 namespace gfx { |
| 239 | 239 |
| 240 CanvasSkia::CanvasSkia(int width, int height, bool is_opaque) | |
| 241 : skia::PlatformCanvas(width, height, is_opaque) { | |
| 242 } | |
| 243 | |
| 244 CanvasSkia::CanvasSkia() : skia::PlatformCanvas() { | |
| 245 } | |
| 246 | |
| 247 CanvasSkia::~CanvasSkia() { | |
| 248 } | |
| 249 | |
| 250 // static | 240 // static |
| 251 void CanvasSkia::SizeStringInt(const string16& text, | 241 void CanvasSkia::SizeStringInt(const string16& text, |
| 252 const gfx::Font& font, | 242 const gfx::Font& font, |
| 253 int* width, int* height, | 243 int* width, int* height, |
| 254 int flags) { | 244 int flags) { |
| 255 int org_width = *width; | 245 int org_width = *width; |
| 256 cairo_surface_t* surface = | 246 cairo_surface_t* surface = |
| 257 cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); | 247 cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0); |
| 258 cairo_t* cr = cairo_create(surface); | 248 cairo_t* cr = cairo_create(surface); |
| 259 PangoLayout* layout = pango_cairo_create_layout(cr); | 249 PangoLayout* layout = pango_cairo_create_layout(cr); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 context.Draw(color); | 321 context.Draw(color); |
| 332 } | 322 } |
| 333 | 323 |
| 334 #if defined(TOOLKIT_USES_GTK) | 324 #if defined(TOOLKIT_USES_GTK) |
| 335 void CanvasSkia::DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y) { | 325 void CanvasSkia::DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y) { |
| 336 if (!pixbuf) { | 326 if (!pixbuf) { |
| 337 NOTREACHED(); | 327 NOTREACHED(); |
| 338 return; | 328 return; |
| 339 } | 329 } |
| 340 | 330 |
| 341 skia::ScopedPlatformPaint scoped_platform_paint(this); | 331 skia::ScopedPlatformPaint scoped_platform_paint(canvas_); |
| 342 cairo_t* cr = scoped_platform_paint.GetPlatformSurface(); | 332 cairo_t* cr = scoped_platform_paint.GetPlatformSurface(); |
| 343 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); | 333 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); |
| 344 cairo_paint(cr); | 334 cairo_paint(cr); |
| 345 } | 335 } |
| 346 #endif // defined(TOOLKIT_USES_GTK) | 336 #endif // defined(TOOLKIT_USES_GTK) |
| 347 | 337 |
| 348 ui::TextureID CanvasSkia::GetTextureID() { | 338 ui::TextureID CanvasSkia::GetTextureID() { |
| 349 // TODO(wjmaclean) | 339 // TODO(wjmaclean) |
| 350 return 0; | 340 return 0; |
| 351 } | 341 } |
| 352 | 342 |
| 353 } // namespace gfx | 343 } // namespace gfx |
| OLD | NEW |