Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "gfx/canvas_skia.h" | 5 #include "gfx/canvas_skia.h" |
| 6 | 6 |
| 7 #include <cairo/cairo.h> | 7 #include <cairo/cairo.h> |
| 8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 9 #include <pango/pango.h> | 9 #include <pango/pango.h> |
| 10 #include <pango/pangocairo.h> | 10 #include <pango/pangocairo.h> |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 // asked for. See the loop in pango-layout.c process_item that determines | 201 // asked for. See the loop in pango-layout.c process_item that determines |
| 202 // where to wrap. | 202 // where to wrap. |
| 203 *width = org_width; | 203 *width = org_width; |
| 204 } | 204 } |
| 205 | 205 |
| 206 g_object_unref(layout); | 206 g_object_unref(layout); |
| 207 cairo_destroy(cr); | 207 cairo_destroy(cr); |
| 208 cairo_surface_destroy(surface); | 208 cairo_surface_destroy(surface); |
| 209 } | 209 } |
| 210 | 210 |
| 211 void CanvasSkia::DrawStringInt(const std::wstring& text, | 211 void CanvasSkia::DrawStringWithHalo(const std::wstring& text, |
|
DaveMoore
2010/11/17 01:07:43
I don't think this method should be called "DrawSt
xiyuan
2010/11/17 17:59:22
One possible way to share is wrapping the common c
| |
| 212 const gfx::Font& font, | 212 const gfx::Font& font, |
| 213 const SkColor& color, | 213 const SkColor& text_color, |
| 214 int x, int y, int w, int h, | 214 const SkColor& halo_color, |
| 215 int flags) { | 215 int x, int y, int w, int h, |
| 216 int flags) { | |
| 216 if (w <= 0 || h <= 0) | 217 if (w <= 0 || h <= 0) |
| 217 return; | 218 return; |
| 218 | 219 |
| 220 bool has_halo = text_color != halo_color; | |
| 221 | |
| 219 cairo_t* cr = beginPlatformPaint(); | 222 cairo_t* cr = beginPlatformPaint(); |
| 220 PangoLayout* layout = pango_cairo_create_layout(cr); | 223 PangoLayout* layout = pango_cairo_create_layout(cr); |
| 221 | 224 |
| 222 SetupPangoLayout(layout, text, font, w, flags); | 225 SetupPangoLayout(layout, text, font, w, flags); |
| 223 | 226 |
| 224 pango_layout_set_height(layout, h * PANGO_SCALE); | 227 pango_layout_set_height(layout, h * PANGO_SCALE); |
| 225 | 228 |
| 226 cairo_save(cr); | 229 cairo_save(cr); |
| 227 cairo_set_source_rgba(cr, | |
| 228 SkColorGetR(color) / 255.0, | |
| 229 SkColorGetG(color) / 255.0, | |
| 230 SkColorGetB(color) / 255.0, | |
| 231 SkColorGetA(color) / 255.0); | |
| 232 | 230 |
| 233 int width, height; | 231 int width, height; |
| 234 pango_layout_get_pixel_size(layout, &width, &height); | 232 pango_layout_get_pixel_size(layout, &width, &height); |
| 235 | 233 |
| 236 cairo_rectangle(cr, x, y, w, h); | 234 // Use a bigger clip rect for text with halo. |
| 235 if (has_halo) | |
| 236 cairo_rectangle(cr, x - 1, y - 1, w + 2, h + 2); | |
| 237 else | |
| 238 cairo_rectangle(cr, x, y, w, h); | |
| 237 cairo_clip(cr); | 239 cairo_clip(cr); |
| 238 | 240 |
| 239 if (flags & Canvas::TEXT_VALIGN_TOP) { | 241 if (flags & Canvas::TEXT_VALIGN_TOP) { |
| 240 // Cairo should draw from the top left corner already. | 242 // Cairo should draw from the top left corner already. |
| 241 } else if (flags & Canvas::TEXT_VALIGN_BOTTOM) { | 243 } else if (flags & Canvas::TEXT_VALIGN_BOTTOM) { |
| 242 y += (h - height); | 244 y += (h - height); |
| 243 } else { | 245 } else { |
| 244 // Vertically centered. | 246 // Vertically centered. |
| 245 y += ((h - height) / 2); | 247 y += ((h - height) / 2); |
| 246 } | 248 } |
| 247 | 249 |
| 248 cairo_move_to(cr, x, y); | 250 if (has_halo) { |
| 249 pango_cairo_show_layout(cr, layout); | 251 CanvasSkia text_canvas(w + 2, h + 2, false); |
| 252 text_canvas.FillRectInt(static_cast<SkColor>(0), 0, 0, w + 2, h + 2); | |
| 253 | |
| 254 cairo_t* text_cr = text_canvas.beginPlatformPaint(); | |
| 255 | |
| 256 cairo_move_to(text_cr, 1, 1); | |
| 257 pango_cairo_layout_path(text_cr, layout); | |
| 258 | |
| 259 cairo_set_source_rgba(text_cr, | |
| 260 SkColorGetR(halo_color) / 255.0, | |
| 261 SkColorGetG(halo_color) / 255.0, | |
| 262 SkColorGetB(halo_color) / 255.0, | |
| 263 SkColorGetA(halo_color) / 255.0); | |
| 264 cairo_set_line_width(text_cr, 2.0); | |
| 265 cairo_stroke_preserve(text_cr); | |
| 266 | |
| 267 cairo_set_operator(text_cr, CAIRO_OPERATOR_SOURCE); | |
| 268 cairo_set_source_rgba(text_cr, | |
| 269 SkColorGetR(text_color) / 255.0, | |
| 270 SkColorGetG(text_color) / 255.0, | |
| 271 SkColorGetB(text_color) / 255.0, | |
| 272 SkColorGetA(text_color) / 255.0); | |
| 273 cairo_fill(text_cr); | |
| 274 | |
| 275 text_canvas.endPlatformPaint(); | |
| 276 | |
| 277 const SkBitmap& text_bitmap = const_cast<SkBitmap&>( | |
| 278 text_canvas.getTopPlatformDevice().accessBitmap(false)); | |
| 279 DrawBitmapInt(text_bitmap, x - 1, y - 1); | |
| 280 } else { | |
| 281 cairo_move_to(cr, x, y); | |
| 282 cairo_set_source_rgba(cr, | |
| 283 SkColorGetR(text_color) / 255.0, | |
| 284 SkColorGetG(text_color) / 255.0, | |
| 285 SkColorGetB(text_color) / 255.0, | |
| 286 SkColorGetA(text_color) / 255.0); | |
| 287 pango_cairo_show_layout(cr, layout); | |
| 288 } | |
| 289 | |
| 250 if (font.GetStyle() & gfx::Font::UNDERLINED) { | 290 if (font.GetStyle() & gfx::Font::UNDERLINED) { |
| 251 gfx::PlatformFontGtk* platform_font = | 291 gfx::PlatformFontGtk* platform_font = |
| 252 static_cast<gfx::PlatformFontGtk*>(font.platform_font()); | 292 static_cast<gfx::PlatformFontGtk*>(font.platform_font()); |
| 253 double underline_y = | 293 double underline_y = |
| 254 static_cast<double>(y) + height + platform_font->underline_position(); | 294 static_cast<double>(y) + height + platform_font->underline_position(); |
| 255 cairo_set_line_width(cr, platform_font->underline_thickness()); | 295 cairo_set_line_width(cr, platform_font->underline_thickness()); |
| 256 cairo_move_to(cr, x, underline_y); | 296 cairo_move_to(cr, x, underline_y); |
| 257 cairo_line_to(cr, x + width, underline_y); | 297 cairo_line_to(cr, x + width, underline_y); |
| 258 cairo_stroke(cr); | 298 cairo_stroke(cr); |
| 259 } | 299 } |
| 260 cairo_restore(cr); | 300 cairo_restore(cr); |
| 261 | 301 |
| 262 g_object_unref(layout); | 302 g_object_unref(layout); |
| 263 // NOTE: beginPlatformPaint returned its surface, we shouldn't destroy it. | 303 // NOTE: beginPlatformPaint returned its surface, we shouldn't destroy it. |
| 264 } | 304 } |
| 265 | 305 |
| 306 void CanvasSkia::DrawStringInt(const std::wstring& text, | |
| 307 const gfx::Font& font, | |
| 308 const SkColor& color, | |
| 309 int x, int y, int w, int h, | |
| 310 int flags) { | |
| 311 DrawStringWithHalo(text, font, color, color, x, y, w, h, flags); | |
| 312 } | |
| 313 | |
| 266 void CanvasSkia::DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y) { | 314 void CanvasSkia::DrawGdkPixbuf(GdkPixbuf* pixbuf, int x, int y) { |
| 267 if (!pixbuf) { | 315 if (!pixbuf) { |
| 268 NOTREACHED(); | 316 NOTREACHED(); |
| 269 return; | 317 return; |
| 270 } | 318 } |
| 271 | 319 |
| 272 cairo_t* cr = beginPlatformPaint(); | 320 cairo_t* cr = beginPlatformPaint(); |
| 273 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); | 321 gdk_cairo_set_source_pixbuf(cr, pixbuf, x, y); |
| 274 cairo_paint(cr); | 322 cairo_paint(cr); |
| 275 } | 323 } |
| 276 | 324 |
| 277 } // namespace gfx | 325 } // namespace gfx |
| OLD | NEW |