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

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

Issue 7019013: Removal of dependencies on PlatformDevice classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Syncing merge conflicts. Created 9 years, 7 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
« no previous file with comments | « ui/gfx/canvas_skia_mac.mm ('k') | ui/gfx/native_theme_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 (f & DT_RIGHT) && base::i18n::StringContainsStrongRTLChars(text))) { 131 (f & DT_RIGHT) && base::i18n::StringContainsStrongRTLChars(text))) {
132 f |= DT_RTLREADING; 132 f |= DT_RTLREADING;
133 } 133 }
134 134
135 return f; 135 return f;
136 } 136 }
137 137
138 // Changes the alpha of the given bitmap. 138 // Changes the alpha of the given bitmap.
139 // If |fade_to_right| is true then the rect fades from opaque to clear, 139 // If |fade_to_right| is true then the rect fades from opaque to clear,
140 // otherwise the rect fades from clear to opaque. 140 // otherwise the rect fades from clear to opaque.
141 void FadeBitmapRect(skia::BitmapPlatformDevice& bmp_device, 141 void FadeBitmapRect(SkDevice& bmp_device,
142 const gfx::Rect& rect, 142 const gfx::Rect& rect,
143 bool fade_to_right) { 143 bool fade_to_right) {
144 SkBitmap bmp = bmp_device.accessBitmap(true); 144 SkBitmap bmp = bmp_device.accessBitmap(true);
145 DCHECK_EQ(SkBitmap::kARGB_8888_Config, bmp.config()); 145 DCHECK_EQ(SkBitmap::kARGB_8888_Config, bmp.config());
146 SkAutoLockPixels lock(bmp); 146 SkAutoLockPixels lock(bmp);
147 float total_width = static_cast<float>(rect.width()); 147 float total_width = static_cast<float>(rect.width());
148 148
149 for (int x = rect.x(); x < rect.right(); x++) { 149 for (int x = rect.x(); x < rect.right(); x++) {
150 float cur_width = static_cast<float>(fade_to_right ? 150 float cur_width = static_cast<float>(fade_to_right ?
151 rect.right() - x : x - rect.x()); 151 rect.right() - x : x - rect.x());
152 // We want the fade effect to go from 0.2 to 1.0. 152 // We want the fade effect to go from 0.2 to 1.0.
153 float alpha_percent = ((cur_width / total_width) * 0.8f) + 0.2f; 153 float alpha_percent = ((cur_width / total_width) * 0.8f) + 0.2f;
154 154
155 for (int y = rect.y(); y < rect.bottom(); y++) { 155 for (int y = rect.y(); y < rect.bottom(); y++) {
156 SkColor color = bmp.getColor(x, y); 156 SkColor color = bmp.getColor(x, y);
157 SkAlpha alpha = static_cast<SkAlpha>(SkColorGetA(color) * alpha_percent); 157 SkAlpha alpha = static_cast<SkAlpha>(SkColorGetA(color) * alpha_percent);
158 *bmp.getAddr32(x, y) = SkPreMultiplyColor(SkColorSetA(color, alpha)); 158 *bmp.getAddr32(x, y) = SkPreMultiplyColor(SkColorSetA(color, alpha));
159 } 159 }
160 } 160 }
161 } 161 }
162 162
163 // DrawText() doesn't support alpha channels. To create a transparent background 163 // DrawText() doesn't support alpha channels. To create a transparent background
164 // this function draws black on white. It then uses the intensity of black 164 // this function draws black on white. It then uses the intensity of black
165 // to determine how much alpha to use. The text is drawn in |gfx_text_rect| and 165 // to determine how much alpha to use. The text is drawn in |gfx_text_rect| and
166 // clipped to |gfx_draw_rect|. 166 // clipped to |gfx_draw_rect|.
167 void DrawTextAndClearBackground(skia::BitmapPlatformDevice& bmp_device, 167 void DrawTextAndClearBackground(SkDevice& bmp_device,
168 HFONT font, 168 HFONT font,
169 COLORREF text_color, 169 COLORREF text_color,
170 const string16& text, 170 const string16& text,
171 int flags, 171 int flags,
172 const gfx::Rect& gfx_text_rect, 172 const gfx::Rect& gfx_text_rect,
173 const gfx::Rect& gfx_draw_rect) { 173 const gfx::Rect& gfx_draw_rect) {
174 HDC hdc = bmp_device.BeginPlatformPaint(); 174 HDC hdc = skia::BeginPlatformPaint(&bmp_device);
175 175
176 // Clear the background by filling with white. 176 // Clear the background by filling with white.
177 HBRUSH fill_brush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH)); 177 HBRUSH fill_brush = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
178 HANDLE old_brush = SelectObject(hdc, fill_brush); 178 HANDLE old_brush = SelectObject(hdc, fill_brush);
179 RECT draw_rect = gfx_draw_rect.ToRECT(); 179 RECT draw_rect = gfx_draw_rect.ToRECT();
180 FillRect(hdc, &draw_rect, fill_brush); 180 FillRect(hdc, &draw_rect, fill_brush);
181 SelectObject(hdc, old_brush); 181 SelectObject(hdc, old_brush);
182 182
183 // Set black text with trasparent background. 183 // Set black text with trasparent background.
184 SetBkMode(hdc, TRANSPARENT); 184 SetBkMode(hdc, TRANSPARENT);
(...skipping 26 matching lines...) Expand all
211 // using SkBitmap::getColor() won't work here. 211 // using SkBitmap::getColor() won't work here.
212 SkColor color = *bmp.getAddr32(x, y); 212 SkColor color = *bmp.getAddr32(x, y);
213 // Calculate the alpha using the luminance. Since this is black text 213 // Calculate the alpha using the luminance. Since this is black text
214 // on a white background the luminosity must be inverted. 214 // on a white background the luminosity must be inverted.
215 BYTE alpha = 0xFF - color_utils::GetLuminanceForColor(color); 215 BYTE alpha = 0xFF - color_utils::GetLuminanceForColor(color);
216 *bmp.getAddr32(x, y) = SkPreMultiplyColor( 216 *bmp.getAddr32(x, y) = SkPreMultiplyColor(
217 SkColorSetARGB(alpha, text_color_r, text_color_g, text_color_b)); 217 SkColorSetARGB(alpha, text_color_r, text_color_g, text_color_b));
218 } 218 }
219 } 219 }
220 220
221 bmp_device.EndPlatformPaint(); 221 skia::EndPlatformPaint(&bmp_device);
222 } 222 }
223 223
224 // Draws the given text with a fade out gradient. |bmp_device| is a bitmap 224 // Draws the given text with a fade out gradient. |bmp_device| is a bitmap
225 // that is used to temporary drawing. The text is drawn in |text_rect| and 225 // that is used to temporary drawing. The text is drawn in |text_rect| and
226 // clipped to |draw_rect|. 226 // clipped to |draw_rect|.
227 void DrawTextGradientPart(HDC hdc, 227 void DrawTextGradientPart(HDC hdc,
228 skia::BitmapPlatformDevice& bmp_device, 228 SkDevice& bmp_device,
229 const string16& text, 229 const string16& text,
230 const SkColor& color, 230 const SkColor& color,
231 HFONT font, 231 HFONT font,
232 const gfx::Rect& text_rect, 232 const gfx::Rect& text_rect,
233 const gfx::Rect& draw_rect, 233 const gfx::Rect& draw_rect,
234 bool fade_to_right, 234 bool fade_to_right,
235 int flags) { 235 int flags) {
236 DrawTextAndClearBackground(bmp_device, font, skia::SkColorToCOLORREF(color), 236 DrawTextAndClearBackground(bmp_device, font, skia::SkColorToCOLORREF(color),
237 text, flags, text_rect, draw_rect); 237 text, flags, text_rect, draw_rect);
238 FadeBitmapRect(bmp_device, draw_rect, fade_to_right); 238 FadeBitmapRect(bmp_device, draw_rect, fade_to_right);
239 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA}; 239 BLENDFUNCTION blend = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
240 240
241 HDC bmp_hdc = bmp_device.BeginPlatformPaint(); 241 HDC bmp_hdc = skia::BeginPlatformPaint(&bmp_device);
242 AlphaBlend(hdc, draw_rect.x(), draw_rect.y(), draw_rect.width(), 242 AlphaBlend(hdc, draw_rect.x(), draw_rect.y(), draw_rect.width(),
243 draw_rect.height(), bmp_hdc, draw_rect.x(), draw_rect.y(), 243 draw_rect.height(), bmp_hdc, draw_rect.x(), draw_rect.y(),
244 draw_rect.width(), draw_rect.height(), blend); 244 draw_rect.width(), draw_rect.height(), blend);
245 bmp_device.EndPlatformPaint(); 245 skia::EndPlatformPaint(&bmp_device);
246 } 246 }
247 247
248 enum PrimarySide { 248 enum PrimarySide {
249 PrimaryOnLeft, 249 PrimaryOnLeft,
250 PrimaryOnRight, 250 PrimaryOnRight,
251 }; 251 };
252 252
253 // Divides |rect| horizontally into a |primary| of width |primary_width| and a 253 // Divides |rect| horizontally into a |primary| of width |primary_width| and a
254 // |secondary| taking up the remainder. 254 // |secondary| taking up the remainder.
255 void DivideRect(const gfx::Rect& rect, 255 void DivideRect(const gfx::Rect& rect,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 if (!clip.intersect(skia::RECTToSkIRect(text_bounds))) 340 if (!clip.intersect(skia::RECTToSkIRect(text_bounds)))
341 return; 341 return;
342 342
343 // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in 343 // Clamp the max amount of text we'll draw to 32K. There seem to be bugs in
344 // DrawText() if you e.g. ask it to character-break a no-whitespace string of 344 // DrawText() if you e.g. ask it to character-break a no-whitespace string of
345 // length > 43680 (for which it draws nothing), and since we clamped to 2K in 345 // length > 43680 (for which it draws nothing), and since we clamped to 2K in
346 // SizeStringInt() we're unlikely to be able to display this much anyway. 346 // SizeStringInt() we're unlikely to be able to display this much anyway.
347 const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K. 347 const int kMaxStringLength = 32768 - 1; // So the trailing \0 fits in 32K.
348 string16 clamped_string(text.substr(0, kMaxStringLength)); 348 string16 clamped_string(text.substr(0, kMaxStringLength));
349 349
350 HDC dc = beginPlatformPaint(); 350 HDC dc;
351 SetBkMode(dc, TRANSPARENT); 351 HFONT old_font;
352 HFONT old_font = (HFONT)SelectObject(dc, font); 352 {
353 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color), 353 skia::ScopedPlatformPaint scoped_platform_paint(this);
354 SkColorGetB(color)); 354 dc = scoped_platform_paint.GetPlatformSurface();
355 SetTextColor(dc, brush_color); 355 SetBkMode(dc, TRANSPARENT);
356 old_font = (HFONT)SelectObject(dc, font);
357 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color),
358 SkColorGetB(color));
359 SetTextColor(dc, brush_color);
356 360
357 int f = ComputeFormatFlags(flags, clamped_string); 361 int f = ComputeFormatFlags(flags, clamped_string);
358 DoDrawText(dc, clamped_string, &text_bounds, f); 362 DoDrawText(dc, clamped_string, &text_bounds, f);
359 endPlatformPaint(); 363 }
360 364
361 // Restore the old font. This way we don't have to worry if the caller 365 // Restore the old font. This way we don't have to worry if the caller
362 // deletes the font and the DC lives longer. 366 // deletes the font and the DC lives longer.
363 SelectObject(dc, old_font); 367 SelectObject(dc, old_font);
364 368
365 // Windows will have cleared the alpha channel of the text we drew. Assume 369 // Windows will have cleared the alpha channel of the text we drew. Assume
366 // we're drawing to an opaque surface, or at least the text rect area is 370 // we're drawing to an opaque surface, or at least the text rect area is
367 // opaque. 371 // opaque.
368 getTopPlatformDevice().makeOpaque(clip.fLeft, clip.fTop, 372 skia::MakeOpaque(this, clip.fLeft, clip.fTop, clip.width(),
369 clip.width(), clip.height()); 373 clip.height());
370 } 374 }
371 375
372 void CanvasSkia::DrawStringInt(const string16& text, 376 void CanvasSkia::DrawStringInt(const string16& text,
373 const gfx::Font& font, 377 const gfx::Font& font,
374 const SkColor& color, 378 const SkColor& color,
375 int x, int y, int w, int h, 379 int x, int y, int w, int h,
376 int flags) { 380 int flags) {
377 DrawStringInt(text, font.GetNativeFont(), color, x, y, w, h, flags); 381 DrawStringInt(text, font.GetNativeFont(), color, x, y, w, h, flags);
378 } 382 }
379 383
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 text_canvas.DrawRectInt(0, 0, w + 2, h + 2, bkgnd_paint); 427 text_canvas.DrawRectInt(0, 0, w + 2, h + 2, bkgnd_paint);
424 428
425 // Draw the text into the temporary buffer. This will have correct 429 // Draw the text into the temporary buffer. This will have correct
426 // ClearType since the background color is the same as the halo color. 430 // ClearType since the background color is the same as the halo color.
427 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags); 431 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags);
428 432
429 // Windows will have cleared the alpha channel for the pixels it drew. Make it 433 // Windows will have cleared the alpha channel for the pixels it drew. Make it
430 // opaque. We have to do this first since pixelShouldGetHalo will check for 434 // opaque. We have to do this first since pixelShouldGetHalo will check for
431 // 0 to see if a pixel has been modified to transparent, and black text that 435 // 0 to see if a pixel has been modified to transparent, and black text that
432 // Windows draw will look transparent to it! 436 // Windows draw will look transparent to it!
433 text_canvas.getTopPlatformDevice().makeOpaque(0, 0, w + 2, h + 2); 437 skia::MakeOpaque(&text_canvas, 0, 0, w + 2, h + 2);
434 438
435 uint32_t halo_premul = SkPreMultiplyColor(halo_color); 439 uint32_t halo_premul = SkPreMultiplyColor(halo_color);
436 SkBitmap& text_bitmap = const_cast<SkBitmap&>( 440 SkBitmap& text_bitmap = const_cast<SkBitmap&>(
437 text_canvas.getTopPlatformDevice().accessBitmap(true)); 441 skia::GetTopDevice(text_canvas)->accessBitmap(true));
438 for (int cur_y = 0; cur_y < h + 2; cur_y++) { 442 for (int cur_y = 0; cur_y < h + 2; cur_y++) {
439 uint32_t* text_row = text_bitmap.getAddr32(0, cur_y); 443 uint32_t* text_row = text_bitmap.getAddr32(0, cur_y);
440 for (int cur_x = 0; cur_x < w + 2; cur_x++) { 444 for (int cur_x = 0; cur_x < w + 2; cur_x++) {
441 if (text_row[cur_x] == halo_premul) { 445 if (text_row[cur_x] == halo_premul) {
442 // This pixel was not touched by the text routines. See if it borders 446 // This pixel was not touched by the text routines. See if it borders
443 // a touched pixel in any of the 4 directions (not diagonally). 447 // a touched pixel in any of the 4 directions (not diagonally).
444 if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul)) 448 if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul))
445 text_row[cur_x] = 0; // Make transparent. 449 text_row[cur_x] = 0; // Make transparent.
446 } else { 450 } else {
447 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque. 451 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 DivideRect(solid_part, is_rtl ? PrimaryOnLeft : PrimaryOnRight, 550 DivideRect(solid_part, is_rtl ? PrimaryOnLeft : PrimaryOnRight,
547 gradient_width, &tail_part, &solid_part); 551 gradient_width, &tail_part, &solid_part);
548 552
549 // Grow |display_rect| by |offset_x|. 553 // Grow |display_rect| by |offset_x|.
550 gfx::Rect text_rect(gfx::Point(), display_rect.size()); 554 gfx::Rect text_rect(gfx::Point(), display_rect.size());
551 if (!is_rtl) 555 if (!is_rtl)
552 text_rect.set_x(text_rect.x() - offset_x); 556 text_rect.set_x(text_rect.x() - offset_x);
553 text_rect.set_width(text_rect.width() + offset_x); 557 text_rect.set_width(text_rect.width() + offset_x);
554 558
555 // Create a temporary bitmap to draw the gradient to. 559 // Create a temporary bitmap to draw the gradient to.
556 scoped_ptr<skia::BitmapPlatformDevice> gradient_bitmap( 560 scoped_ptr<SkDevice> gradient_bitmap(
557 skia::BitmapPlatformDevice::create( 561 skia::BitmapPlatformDevice::create(
558 display_rect.width(), display_rect.height(), false, NULL)); 562 display_rect.width(), display_rect.height(), false, NULL));
559 DCHECK(gradient_bitmap.get()); 563 DCHECK(gradient_bitmap.get());
560 564
561 HDC hdc = beginPlatformPaint(); 565 {
562 if (is_truncating_head) 566 skia::ScopedPlatformPaint scoped_platform_paint(this);
563 DrawTextGradientPart(hdc, *gradient_bitmap, text, color, 567 HDC hdc = scoped_platform_paint.GetPlatformSurface();
564 font.GetNativeFont(), text_rect, head_part, is_rtl, 568 if (is_truncating_head)
565 flags); 569 DrawTextGradientPart(hdc, *gradient_bitmap, text, color,
566 if (is_truncating_tail) 570 font.GetNativeFont(), text_rect, head_part, is_rtl,
567 DrawTextGradientPart(hdc, *gradient_bitmap, text, color, 571 flags);
568 font.GetNativeFont(), text_rect, tail_part, !is_rtl, 572 if (is_truncating_tail)
569 flags); 573 DrawTextGradientPart(hdc, *gradient_bitmap, text, color,
570 endPlatformPaint(); 574 font.GetNativeFont(), text_rect, tail_part, !is_rtl,
575 flags);
576 }
571 577
572 // Draw the solid part. 578 // Draw the solid part.
573 save(kClip_SaveFlag); 579 save(kClip_SaveFlag);
574 ClipRectInt(solid_part.x(), solid_part.y(), 580 ClipRectInt(solid_part.x(), solid_part.y(),
575 solid_part.width(), solid_part.height()); 581 solid_part.width(), solid_part.height());
576 DrawStringInt(text, font, color, 582 DrawStringInt(text, font, color,
577 text_rect.x(), text_rect.y(), 583 text_rect.x(), text_rect.y(),
578 text_rect.width(), text_rect.height(), 584 text_rect.width(), text_rect.height(),
579 flags); 585 flags);
580 restore(); 586 restore();
581 restore(); 587 restore();
582 } 588 }
583 589
584 } // namespace gfx 590 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/canvas_skia_mac.mm ('k') | ui/gfx/native_theme_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698