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

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: Addressing comments. 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
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_b, text_color_g)); 217 SkColorSetARGB(alpha, text_color_r, text_color_b, text_color_g));
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 = skia::BeginPlatformPaint(this);
351 SetBkMode(dc, TRANSPARENT); 351 SetBkMode(dc, TRANSPARENT);
352 HFONT old_font = (HFONT)SelectObject(dc, font); 352 HFONT old_font = (HFONT)SelectObject(dc, font);
353 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color), 353 COLORREF brush_color = RGB(SkColorGetR(color), SkColorGetG(color),
354 SkColorGetB(color)); 354 SkColorGetB(color));
355 SetTextColor(dc, brush_color); 355 SetTextColor(dc, brush_color);
356 356
357 int f = ComputeFormatFlags(flags, clamped_string); 357 int f = ComputeFormatFlags(flags, clamped_string);
358 DoDrawText(dc, clamped_string, &text_bounds, f); 358 DoDrawText(dc, clamped_string, &text_bounds, f);
359 endPlatformPaint(); 359 skia::EndPlatformPaint(this);
360 360
361 // Restore the old font. This way we don't have to worry if the caller 361 // Restore the old font. This way we don't have to worry if the caller
362 // deletes the font and the DC lives longer. 362 // deletes the font and the DC lives longer.
363 SelectObject(dc, old_font); 363 SelectObject(dc, old_font);
364 364
365 // Windows will have cleared the alpha channel of the text we drew. Assume 365 // 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 366 // we're drawing to an opaque surface, or at least the text rect area is
367 // opaque. 367 // opaque.
368 getTopPlatformDevice().makeOpaque(clip.fLeft, clip.fTop, 368 skia::MakeOpaque(&getTopDevice(), clip.fLeft, clip.fTop, clip.width(),
369 clip.width(), clip.height()); 369 clip.height());
370 } 370 }
371 371
372 void CanvasSkia::DrawStringInt(const string16& text, 372 void CanvasSkia::DrawStringInt(const string16& text,
373 const gfx::Font& font, 373 const gfx::Font& font,
374 const SkColor& color, 374 const SkColor& color,
375 int x, int y, int w, int h, 375 int x, int y, int w, int h,
376 int flags) { 376 int flags) {
377 DrawStringInt(text, font.GetNativeFont(), color, x, y, w, h, flags); 377 DrawStringInt(text, font.GetNativeFont(), color, x, y, w, h, flags);
378 } 378 }
379 379
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 text_canvas.DrawRectInt(0, 0, w + 2, h + 2, bkgnd_paint); 423 text_canvas.DrawRectInt(0, 0, w + 2, h + 2, bkgnd_paint);
424 424
425 // Draw the text into the temporary buffer. This will have correct 425 // Draw the text into the temporary buffer. This will have correct
426 // ClearType since the background color is the same as the halo color. 426 // 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); 427 text_canvas.DrawStringInt(text, font, text_color, 1, 1, w, h, flags);
428 428
429 // Windows will have cleared the alpha channel for the pixels it drew. Make it 429 // 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 430 // 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 431 // 0 to see if a pixel has been modified to transparent, and black text that
432 // Windows draw will look transparent to it! 432 // Windows draw will look transparent to it!
433 text_canvas.getTopPlatformDevice().makeOpaque(0, 0, w + 2, h + 2); 433 skia::MakeOpaque(&text_canvas.getTopDevice(), 0, 0, w + 2, h + 2);
434 434
435 uint32_t halo_premul = SkPreMultiplyColor(halo_color); 435 uint32_t halo_premul = SkPreMultiplyColor(halo_color);
436 SkBitmap& text_bitmap = const_cast<SkBitmap&>( 436 SkBitmap& text_bitmap = const_cast<SkBitmap&>(
437 text_canvas.getTopPlatformDevice().accessBitmap(true)); 437 text_canvas.getTopDevice().accessBitmap(true));
438 for (int cur_y = 0; cur_y < h + 2; cur_y++) { 438 for (int cur_y = 0; cur_y < h + 2; cur_y++) {
439 uint32_t* text_row = text_bitmap.getAddr32(0, cur_y); 439 uint32_t* text_row = text_bitmap.getAddr32(0, cur_y);
440 for (int cur_x = 0; cur_x < w + 2; cur_x++) { 440 for (int cur_x = 0; cur_x < w + 2; cur_x++) {
441 if (text_row[cur_x] == halo_premul) { 441 if (text_row[cur_x] == halo_premul) {
442 // This pixel was not touched by the text routines. See if it borders 442 // 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). 443 // a touched pixel in any of the 4 directions (not diagonally).
444 if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul)) 444 if (!pixelShouldGetHalo(text_bitmap, cur_x, cur_y, halo_premul))
445 text_row[cur_x] = 0; // Make transparent. 445 text_row[cur_x] = 0; // Make transparent.
446 } else { 446 } else {
447 text_row[cur_x] |= 0xff << SK_A32_SHIFT; // Make opaque. 447 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, 546 DivideRect(solid_part, is_rtl ? PrimaryOnLeft : PrimaryOnRight,
547 gradient_width, &tail_part, &solid_part); 547 gradient_width, &tail_part, &solid_part);
548 548
549 // Grow |display_rect| by |offset_x|. 549 // Grow |display_rect| by |offset_x|.
550 gfx::Rect text_rect(gfx::Point(), display_rect.size()); 550 gfx::Rect text_rect(gfx::Point(), display_rect.size());
551 if (!is_rtl) 551 if (!is_rtl)
552 text_rect.set_x(text_rect.x() - offset_x); 552 text_rect.set_x(text_rect.x() - offset_x);
553 text_rect.set_width(text_rect.width() + offset_x); 553 text_rect.set_width(text_rect.width() + offset_x);
554 554
555 // Create a temporary bitmap to draw the gradient to. 555 // Create a temporary bitmap to draw the gradient to.
556 scoped_ptr<skia::BitmapPlatformDevice> gradient_bitmap( 556 scoped_ptr<SkDevice> gradient_bitmap(
557 skia::BitmapPlatformDevice::create( 557 skia::BitmapPlatformDevice::create(
558 display_rect.width(), display_rect.height(), false, NULL)); 558 display_rect.width(), display_rect.height(), false, NULL));
559 DCHECK(gradient_bitmap.get()); 559 DCHECK(gradient_bitmap.get());
560 560
561 HDC hdc = beginPlatformPaint(); 561 HDC hdc = skia::BeginPlatformPaint(this);
562 if (is_truncating_head) 562 if (is_truncating_head)
563 DrawTextGradientPart(hdc, *gradient_bitmap, text, color, 563 DrawTextGradientPart(hdc, *gradient_bitmap, text, color,
564 font.GetNativeFont(), text_rect, head_part, is_rtl, 564 font.GetNativeFont(), text_rect, head_part, is_rtl,
565 flags); 565 flags);
566 if (is_truncating_tail) 566 if (is_truncating_tail)
567 DrawTextGradientPart(hdc, *gradient_bitmap, text, color, 567 DrawTextGradientPart(hdc, *gradient_bitmap, text, color,
568 font.GetNativeFont(), text_rect, tail_part, !is_rtl, 568 font.GetNativeFont(), text_rect, tail_part, !is_rtl,
569 flags); 569 flags);
570 endPlatformPaint(); 570 skia::EndPlatformPaint(this);
571 571
572 // Draw the solid part. 572 // Draw the solid part.
573 save(kClip_SaveFlag); 573 save(kClip_SaveFlag);
574 ClipRectInt(solid_part.x(), solid_part.y(), 574 ClipRectInt(solid_part.x(), solid_part.y(),
575 solid_part.width(), solid_part.height()); 575 solid_part.width(), solid_part.height());
576 DrawStringInt(text, font, color, 576 DrawStringInt(text, font, color,
577 text_rect.x(), text_rect.y(), 577 text_rect.x(), text_rect.y(),
578 text_rect.width(), text_rect.height(), 578 text_rect.width(), text_rect.height(),
579 flags); 579 flags);
580 restore(); 580 restore();
581 restore(); 581 restore();
582 } 582 }
583 583
584 } // namespace gfx 584 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698