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 |