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

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

Issue 8122013: Allow CanvasSkia to bind to an existing SkCanvas. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: 1 more fix Created 9 years, 2 months 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
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 <limits> 7 #include <limits>
8 8
9 #include "base/i18n/rtl.h" 9 #include "base/i18n/rtl.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 primary->Inset(remainder, 0, 0, 0); 274 primary->Inset(remainder, 0, 0, 0);
275 secondary->Inset(0, 0, primary_width, 0); 275 secondary->Inset(0, 0, primary_width, 0);
276 break; 276 break;
277 } 277 }
278 } 278 }
279 279
280 } // anonymous namespace 280 } // anonymous namespace
281 281
282 namespace gfx { 282 namespace gfx {
283 283
284 CanvasSkia::CanvasSkia(int width, int height, bool is_opaque)
285 : skia::PlatformCanvas(width, height, is_opaque) {
286 }
287
288 CanvasSkia::CanvasSkia() : skia::PlatformCanvas() {
289 }
290
291 CanvasSkia::~CanvasSkia() {
292 }
293
294 // static 284 // static
295 void CanvasSkia::SizeStringInt(const string16& text, 285 void CanvasSkia::SizeStringInt(const string16& text,
296 const gfx::Font& font, 286 const gfx::Font& font,
297 int* width, int* height, 287 int* width, int* height,
298 int flags) { 288 int flags) {
299 // Clamp the max amount of text we'll measure to 2K. When the string is 289 // Clamp the max amount of text we'll measure to 2K. When the string is
300 // actually drawn, it will be clipped to whatever size box is provided, and 290 // actually drawn, it will be clipped to whatever size box is provided, and
301 // the time to do that doesn't depend on the length being clipped off. 291 // the time to do that doesn't depend on the length being clipped off.
302 const int kMaxStringLength = 2048 - 1; // So the trailing \0 fits in 2K. 292 const int kMaxStringLength = 2048 - 1; // So the trailing \0 fits in 2K.
303 string16 clamped_string(text.substr(0, kMaxStringLength)); 293 string16 clamped_string(text.substr(0, kMaxStringLength));
(...skipping 25 matching lines...) Expand all
329 *width = r.right; 319 *width = r.right;
330 *height = r.bottom; 320 *height = r.bottom;
331 } 321 }
332 322
333 void CanvasSkia::DrawStringInt(const string16& text, 323 void CanvasSkia::DrawStringInt(const string16& text,
334 HFONT font, 324 HFONT font,
335 const SkColor& color, 325 const SkColor& color,
336 int x, int y, int w, int h, 326 int x, int y, int w, int h,
337 int flags) { 327 int flags) {
338 SkRect fclip; 328 SkRect fclip;
339 if (!getClipBounds(&fclip)) 329 if (!canvas_->getClipBounds(&fclip))
340 return; 330 return;
341 RECT text_bounds = { x, y, x + w, y + h }; 331 RECT text_bounds = { x, y, x + w, y + h };
342 SkIRect clip; 332 SkIRect clip;
343 fclip.round(&clip); 333 fclip.round(&clip);
344 if (!clip.intersect(skia::RECTToSkIRect(text_bounds))) 334 if (!clip.intersect(skia::RECTToSkIRect(text_bounds)))
345 return; 335 return;
346 336
347 // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in 337 // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in
348 // DrawText() if you e.g. ask it to character-break a no-whitespace string of 338 // DrawText() if you e.g. ask it to character-break a no-whitespace string of
349 // length > 43680 (for which it draws nothing), and since we clamped to 2K in 339 // length > 43680 (for which it draws nothing), and since we clamped to 2K in
350 // SizeStringInt() we're unlikely to be able to display this much anyway. 340 // SizeStringInt() we're unlikely to be able to display this much anyway.
351 const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K. 341 const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K.
352 string16 clamped_string(text.substr(0, kMaxStringLength)); 342 string16 clamped_string(text.substr(0, kMaxStringLength));
353 343
354 HDC dc; 344 HDC dc;
355 HFONT old_font; 345 HFONT old_font;
356 { 346 {
357 skia::ScopedPlatformPaint scoped_platform_paint(this); 347 skia::ScopedPlatformPaint scoped_platform_paint(canvas_);
358 dc = scoped_platform_paint.GetPlatformSurface(); 348 dc = scoped_platform_paint.GetPlatformSurface();
359 SetBkMode(dc, TRANSPARENT); 349 SetBkMode(dc, TRANSPARENT);
360 old_font = (HFONT)SelectObject(dc, font); 350 old_font = (HFONT)SelectObject(dc, font);
361 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color), 351 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color),
362 SkColorGetB(color)); 352 SkColorGetB(color));
363 SetTextColor(dc, brush_color); 353 SetTextColor(dc, brush_color);
364 354
365 int f = ComputeFormatFlags(flags, clamped_string); 355 int f = ComputeFormatFlags(flags, clamped_string);
366 DoDrawText(dc, clamped_string, &text_bounds, f); 356 DoDrawText(dc, clamped_string, &text_bounds, f);
367 } 357 }
368 358
369 // Restore the old font. This way we don't have to worry if the caller 359 // Restore the old font. This way we don't have to worry if the caller
370 // deletes the font and the DC lives longer. 360 // deletes the font and the DC lives longer.
371 SelectObject(dc, old_font); 361 SelectObject(dc, old_font);
372 362
373 // Windows will have cleared the alpha channel of the text we drew. Assume 363 // Windows will have cleared the alpha channel of the text we drew. Assume
374 // we're drawing to an opaque surface, or at least the text rect area is 364 // we're drawing to an opaque surface, or at least the text rect area is
375 // opaque. 365 // opaque.
376 skia::MakeOpaque(this, clip.fLeft, clip.fTop, clip.width(), 366 skia::MakeOpaque(canvas_, clip.fLeft, clip.fTop, clip.width(),
377 clip.height()); 367 clip.height());
378 } 368 }
379 369
380 void CanvasSkia::DrawStringInt(const string16& text, 370 void CanvasSkia::DrawStringInt(const string16& text,
381 const gfx::Font& font, 371 const gfx::Font& font,
382 const SkColor& color, 372 const SkColor& color,
383 int x, int y, int w, int h, 373 int x, int y, int w, int h,
384 int flags) { 374 int flags) {
385 DrawStringInt(text, font.GetNativeFont(), color, x, y, w, h, flags); 375 DrawStringInt(text, font.GetNativeFont(), color, x, y, w, h, flags);
386 } 376 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 text_canvas.DrawRectInt(0, 0, w + 2, h + 2, bkgnd_paint); 421 text_canvas.DrawRectInt(0, 0, w + 2, h + 2, bkgnd_paint);
432 422
433 // Draw the text into the temporary buffer. This will have correct 423 // Draw the text into the temporary buffer. This will have correct
434 // ClearType since the background color is the same as the halo color. 424 // ClearType since the background color is the same as the halo color.
435 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags); 425 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags);
436 426
437 // Windows will have cleared the alpha channel for the pixels it drew. Make it 427 // Windows will have cleared the alpha channel for the pixels it drew. Make it
438 // opaque. We have to do this first since pixelShouldGetHalo will check for 428 // opaque. We have to do this first since pixelShouldGetHalo will check for
439 // 0 to see if a pixel has been modified to transparent, and black text that 429 // 0 to see if a pixel has been modified to transparent, and black text that
440 // Windows draw will look transparent to it! 430 // Windows draw will look transparent to it!
441 skia::MakeOpaque(&text_canvas, 0, 0, w + 2, h + 2); 431 skia::MakeOpaque(text_canvas.sk_canvas(), 0, 0, w + 2, h + 2);
442 432
443 uint32_t halo_premul = SkPreMultiplyColor(halo_color); 433 uint32_t halo_premul = SkPreMultiplyColor(halo_color);
444 SkBitmap& text_bitmap = const_cast<SkBitmap&>( 434 SkBitmap& text_bitmap = const_cast<SkBitmap&>(
445 skia::GetTopDevice(text_canvas)->accessBitmap(true)); 435 skia::GetTopDevice(*text_canvas.sk_canvas())->accessBitmap(true));
446 for (int cur_y = 0; cur_y < h + 2; cur_y++) { 436 for (int cur_y = 0; cur_y < h + 2; cur_y++) {
447 uint32_t* text_row = text_bitmap.getAddr32(0, cur_y); 437 uint32_t* text_row = text_bitmap.getAddr32(0, cur_y);
448 for (int cur_x = 0; cur_x < w + 2; cur_x++) { 438 for (int cur_x = 0; cur_x < w + 2; cur_x++) {
449 if (text_row[cur_x] == halo_premul) { 439 if (text_row[cur_x] == halo_premul) {
450 // This pixel was not touched by the text routines. See if it borders 440 // This pixel was not touched by the text routines. See if it borders
451 // a touched pixel in any of the 4 directions (not diagonally). 441 // a touched pixel in any of the 4 directions (not diagonally).
452 if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul)) 442 if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul))
453 text_row[cur_x] = 0; // Make transparent. 443 text_row[cur_x] = 0; // Make transparent.
454 } else { 444 } else {
455 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque. 445 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 flags |= TEXT_ALIGN_LEFT; 524 flags |= TEXT_ALIGN_LEFT;
535 525
536 // Fade in/out about 2.5 characters of the beginning/end of the string. 526 // Fade in/out about 2.5 characters of the beginning/end of the string.
537 // The .5 here is helpful if one of the characters is a space. 527 // The .5 here is helpful if one of the characters is a space.
538 // Use a quarter of the display width if the string is very short. 528 // Use a quarter of the display width if the string is very short.
539 int gradient_width = Round(std::min(average_character_width * 2.5, 529 int gradient_width = Round(std::min(average_character_width * 2.5,
540 display_rect.width() / 4.0)); 530 display_rect.width() / 4.0));
541 531
542 // Move the origin to |display_rect.origin()|. This simplifies all the 532 // Move the origin to |display_rect.origin()|. This simplifies all the
543 // drawing so that both the source and destination can be (0,0). 533 // drawing so that both the source and destination can be (0,0).
544 save(kMatrix_SaveFlag); 534 canvas_->save(SkCanvas::kMatrix_SaveFlag);
545 TranslateInt(display_rect.x(), display_rect.y()); 535 TranslateInt(display_rect.x(), display_rect.y());
546 536
547 gfx::Rect solid_part(gfx::Point(), display_rect.size()); 537 gfx::Rect solid_part(gfx::Point(), display_rect.size());
548 gfx::Rect head_part; 538 gfx::Rect head_part;
549 gfx::Rect tail_part; 539 gfx::Rect tail_part;
550 if (is_truncating_head) 540 if (is_truncating_head)
551 DivideRect(solid_part, is_rtl ? PrimaryOnRight : PrimaryOnLeft, 541 DivideRect(solid_part, is_rtl ? PrimaryOnRight : PrimaryOnLeft,
552 gradient_width, &head_part, &solid_part); 542 gradient_width, &head_part, &solid_part);
553 if (is_truncating_tail) 543 if (is_truncating_tail)
554 DivideRect(solid_part, is_rtl ? PrimaryOnLeft : PrimaryOnRight, 544 DivideRect(solid_part, is_rtl ? PrimaryOnLeft : PrimaryOnRight,
555 gradient_width, &tail_part, &solid_part); 545 gradient_width, &tail_part, &solid_part);
556 546
557 // Grow |display_rect| by |offset_x|. 547 // Grow |display_rect| by |offset_x|.
558 gfx::Rect text_rect(gfx::Point(), display_rect.size()); 548 gfx::Rect text_rect(gfx::Point(), display_rect.size());
559 if (!is_rtl) 549 if (!is_rtl)
560 text_rect.set_x(text_rect.x() - offset_x); 550 text_rect.set_x(text_rect.x() - offset_x);
561 text_rect.set_width(text_rect.width() + offset_x); 551 text_rect.set_width(text_rect.width() + offset_x);
562 552
563 // Create a temporary bitmap to draw the gradient to. 553 // Create a temporary bitmap to draw the gradient to.
564 scoped_ptr<SkCanvas> gradient_canvas(skia::CreateBitmapCanvas( 554 scoped_ptr<SkCanvas> gradient_canvas(skia::CreateBitmapCanvas(
565 display_rect.width(), display_rect.height(), false)); 555 display_rect.width(), display_rect.height(), false));
566 556
567 { 557 {
568 skia::ScopedPlatformPaint scoped_platform_paint(this); 558 skia::ScopedPlatformPaint scoped_platform_paint(canvas_);
569 HDC hdc = scoped_platform_paint.GetPlatformSurface(); 559 HDC hdc = scoped_platform_paint.GetPlatformSurface();
570 if (is_truncating_head) 560 if (is_truncating_head)
571 DrawTextGradientPart(hdc, gradient_canvas.get(), text, color, 561 DrawTextGradientPart(hdc, gradient_canvas.get(), text, color,
572 font.GetNativeFont(), text_rect, head_part, is_rtl, 562 font.GetNativeFont(), text_rect, head_part, is_rtl,
573 flags); 563 flags);
574 if (is_truncating_tail) 564 if (is_truncating_tail)
575 DrawTextGradientPart(hdc, gradient_canvas.get(), text, color, 565 DrawTextGradientPart(hdc, gradient_canvas.get(), text, color,
576 font.GetNativeFont(), text_rect, tail_part, !is_rtl, 566 font.GetNativeFont(), text_rect, tail_part, !is_rtl,
577 flags); 567 flags);
578 } 568 }
579 569
580 // Draw the solid part. 570 // Draw the solid part.
581 save(kClip_SaveFlag); 571 canvas_->save(SkCanvas::kClip_SaveFlag);
582 ClipRectInt(solid_part.x(), solid_part.y(), 572 ClipRectInt(solid_part.x(), solid_part.y(),
583 solid_part.width(), solid_part.height()); 573 solid_part.width(), solid_part.height());
584 DrawStringInt(text, font, color, 574 DrawStringInt(text, font, color,
585 text_rect.x(), text_rect.y(), 575 text_rect.x(), text_rect.y(),
586 text_rect.width(), text_rect.height(), 576 text_rect.width(), text_rect.height(),
587 flags); 577 flags);
588 restore(); 578 canvas_->restore();
589 restore(); 579 canvas_->restore();
590 } 580 }
591 581
592 } // namespace gfx 582 } // namespace gfx
OLDNEW
« ui/gfx/canvas.h ('K') | « ui/gfx/canvas_skia_paint.h ('k') | ui/gfx/compositor/layer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698