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

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

Issue 10245003: Makes ImageSkia more like SkBitmap (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated comment Created 8 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.h ('k') | ui/gfx/image/image.h » ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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.h" 5 #include "ui/gfx/canvas.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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 } 247 }
248 248
249 void Canvas::DrawPath(const SkPath& path, const SkPaint& paint) { 249 void Canvas::DrawPath(const SkPath& path, const SkPaint& paint) {
250 canvas_->drawPath(path, paint); 250 canvas_->drawPath(path, paint);
251 } 251 }
252 252
253 void Canvas::DrawFocusRect(const gfx::Rect& rect) { 253 void Canvas::DrawFocusRect(const gfx::Rect& rect) {
254 DrawDashedRect(rect, SK_ColorGRAY); 254 DrawDashedRect(rect, SK_ColorGRAY);
255 } 255 }
256 256
257 void Canvas::DrawBitmapInt(const SkBitmap& bitmap, int x, int y) { 257 void Canvas::DrawBitmapInt(const gfx::ImageSkia& image, int x, int y) {
258 canvas_->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y)); 258 SkPaint paint;
259 DrawBitmapInt(image, x, y, paint);
259 } 260 }
260 261
261 void Canvas::DrawBitmapInt(const SkBitmap& bitmap, 262 void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
262 int x, int y, 263 int x, int y,
263 const SkPaint& paint) { 264 const SkPaint& paint) {
264 canvas_->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y), &paint); 265 float bitmap_scale;
266 const SkBitmap& bitmap = GetBitmapToPaint(image, &bitmap_scale);
267 if (bitmap.isNull())
268 return;
269
270 canvas_->save();
271 canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale),
272 SkFloatToScalar(1.0f / bitmap_scale));
273 canvas_->drawBitmap(bitmap,
274 SkFloatToScalar(x * bitmap_scale),
275 SkFloatToScalar(y * bitmap_scale));
276 canvas_->restore();
265 } 277 }
266 278
267 void Canvas::DrawBitmapInt(const SkBitmap& bitmap, 279 void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
268 int src_x, int src_y, int src_w, int src_h, 280 int src_x, int src_y, int src_w, int src_h,
269 int dest_x, int dest_y, int dest_w, int dest_h, 281 int dest_x, int dest_y, int dest_w, int dest_h,
270 bool filter) { 282 bool filter) {
271 SkPaint p; 283 SkPaint p;
272 DrawBitmapInt(bitmap, src_x, src_y, src_w, src_h, dest_x, dest_y, 284 DrawBitmapInt(image, src_x, src_y, src_w, src_h, dest_x, dest_y,
273 dest_w, dest_h, filter, p); 285 dest_w, dest_h, filter, p);
274 } 286 }
275 287
276 void Canvas::DrawBitmapInt(const SkBitmap& bitmap, 288 void Canvas::DrawBitmapInt(const gfx::ImageSkia& image,
277 int src_x, int src_y, int src_w, int src_h, 289 int src_x, int src_y, int src_w, int src_h,
278 int dest_x, int dest_y, int dest_w, int dest_h, 290 int dest_x, int dest_y, int dest_w, int dest_h,
279 bool filter, 291 bool filter,
280 const SkPaint& paint) { 292 const SkPaint& paint) {
281 DrawBitmapFloat(bitmap, static_cast<float>(src_x), static_cast<float>(src_y),
282 static_cast<float>(src_w), static_cast<float>(src_h),
283 static_cast<float>(dest_x), static_cast<float>(dest_y),
284 static_cast<float>(dest_w), static_cast<float>(dest_h),
285 filter, paint);
286 }
287
288 void Canvas::DrawBitmapFloat(const SkBitmap& bitmap,
289 float src_x, float src_y, float src_w, float src_h,
290 float dest_x, float dest_y, float dest_w, float dest_h,
291 bool filter,
292 const SkPaint& paint) {
293 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() && 293 DLOG_ASSERT(src_x + src_w < std::numeric_limits<int16_t>::max() &&
294 src_y + src_h < std::numeric_limits<int16_t>::max()); 294 src_y + src_h < std::numeric_limits<int16_t>::max());
295 if (src_w <= 0 || src_h <= 0) { 295 if (src_w <= 0 || src_h <= 0) {
296 NOTREACHED() << "Attempting to draw bitmap from an empty rect!"; 296 NOTREACHED() << "Attempting to draw bitmap from an empty rect!";
297 return; 297 return;
298 } 298 }
299 299
300 if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h)) 300 if (!IntersectsClipRectInt(dest_x, dest_y, dest_w, dest_h))
301 return; 301 return;
302 302
303 SkRect dest_rect = { SkFloatToScalar(dest_x), 303 float user_scale_x = static_cast<float>(dest_w) / src_w;
304 SkFloatToScalar(dest_y), 304 float user_scale_y = static_cast<float>(dest_h) / src_h;
305 SkFloatToScalar(dest_x + dest_w),
306 SkFloatToScalar(dest_y + dest_h) };
307 305
308 if (src_w == dest_w && src_h == dest_h) { 306 float bitmap_scale;
307 const SkBitmap& bitmap = GetBitmapToPaint(image, user_scale_x, user_scale_y,
308 &bitmap_scale);
309 if (bitmap.isNull())
310 return;
311
312 SkRect dest_rect = { SkIntToScalar(dest_x),
313 SkIntToScalar(dest_y),
314 SkIntToScalar(dest_x + dest_w),
315 SkIntToScalar(dest_y + dest_h) };
316
317 if (src_w == dest_w && src_h == dest_h &&
318 bitmap_scale == 1.0f && bitmap_scale == 1.0f) {
309 // Workaround for apparent bug in Skia that causes image to occasionally 319 // Workaround for apparent bug in Skia that causes image to occasionally
310 // shift. 320 // shift.
311 SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h }; 321 SkIRect src_rect = { src_x, src_y, src_x + src_w, src_y + src_h };
312 canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint); 322 canvas_->drawBitmapRect(bitmap, &src_rect, dest_rect, &paint);
313 return; 323 return;
314 } 324 }
315 325
316 // Make a bitmap shader that contains the bitmap we want to draw. This is 326 // Make a bitmap shader that contains the bitmap we want to draw. This is
317 // basically what SkCanvas.drawBitmap does internally, but it gives us 327 // basically what SkCanvas.drawBitmap does internally, but it gives us
318 // more control over quality and will use the mipmap in the source image if 328 // more control over quality and will use the mipmap in the source image if
319 // it has one, whereas drawBitmap won't. 329 // it has one, whereas drawBitmap won't.
320 SkShader* shader = SkShader::CreateBitmapShader(bitmap, 330 SkShader* shader = SkShader::CreateBitmapShader(bitmap,
321 SkShader::kRepeat_TileMode, 331 SkShader::kRepeat_TileMode,
322 SkShader::kRepeat_TileMode); 332 SkShader::kRepeat_TileMode);
323 SkMatrix shader_scale; 333 SkMatrix shader_scale;
324 shader_scale.setScale(SkFloatToScalar(dest_w / src_w), 334 shader_scale.setScale(SkFloatToScalar(user_scale_x),
325 SkFloatToScalar(dest_h / src_h)); 335 SkFloatToScalar(user_scale_y));
326 shader_scale.preTranslate(SkFloatToScalar(-src_x), SkFloatToScalar(-src_y)); 336 shader_scale.preTranslate(SkFloatToScalar(-src_x * bitmap_scale),
327 shader_scale.postTranslate(SkFloatToScalar(dest_x), SkFloatToScalar(dest_y)); 337 SkFloatToScalar(-src_y * bitmap_scale));
338 shader_scale.postTranslate(SkFloatToScalar(dest_x * bitmap_scale),
339 SkFloatToScalar(dest_y * bitmap_scale));
340 shader_scale.postScale(1.0f / bitmap_scale, 1.0f / bitmap_scale);
328 shader->setLocalMatrix(shader_scale); 341 shader->setLocalMatrix(shader_scale);
329 342
330 // Set up our paint to use the shader & release our reference (now just owned 343 // Set up our paint to use the shader & release our reference (now just owned
331 // by the paint). 344 // by the paint).
332 SkPaint p(paint); 345 SkPaint p(paint);
333 p.setFilterBitmap(filter); 346 p.setFilterBitmap(filter);
334 p.setShader(shader); 347 p.setShader(shader);
335 shader->unref(); 348 shader->unref();
336 349
337 // The rect will be filled by the bitmap. 350 // The rect will be filled by the bitmap.
(...skipping 21 matching lines...) Expand all
359 int x, int y, int w, int h, 372 int x, int y, int w, int h,
360 int flags) { 373 int flags) {
361 DrawStringWithShadows(text, 374 DrawStringWithShadows(text,
362 font, 375 font,
363 color, 376 color,
364 gfx::Rect(x, y, w, h), 377 gfx::Rect(x, y, w, h),
365 flags, 378 flags,
366 std::vector<ShadowValue>()); 379 std::vector<ShadowValue>());
367 } 380 }
368 381
369 void Canvas::TileImageInt(const SkBitmap& bitmap, 382 void Canvas::TileImageInt(const gfx::ImageSkia& image,
370 int x, int y, int w, int h) { 383 int x, int y, int w, int h) {
371 TileImageInt(bitmap, 0, 0, x, y, w, h); 384 TileImageInt(image, 0, 0, x, y, w, h);
372 } 385 }
373 386
374 void Canvas::TileImageInt(const SkBitmap& bitmap, 387 void Canvas::TileImageInt(const gfx::ImageSkia& image,
375 int src_x, int src_y, 388 int src_x, int src_y,
376 int dest_x, int dest_y, int w, int h) { 389 int dest_x, int dest_y, int w, int h) {
377 if (!IntersectsClipRectInt(dest_x, dest_y, w, h)) 390 if (!IntersectsClipRectInt(dest_x, dest_y, w, h))
378 return; 391 return;
379 392
393 float bitmap_scale;
394 const SkBitmap& bitmap = GetBitmapToPaint(image, &bitmap_scale);
395 if (bitmap.isNull())
396 return;
397
380 SkPaint paint; 398 SkPaint paint;
381 399
382 SkShader* shader = SkShader::CreateBitmapShader(bitmap, 400 SkShader* shader = SkShader::CreateBitmapShader(bitmap,
383 SkShader::kRepeat_TileMode, 401 SkShader::kRepeat_TileMode,
384 SkShader::kRepeat_TileMode); 402 SkShader::kRepeat_TileMode);
385 paint.setShader(shader); 403 paint.setShader(shader);
386 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); 404 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
387 405
388 // CreateBitmapShader returns a Shader with a reference count of one, we 406 // CreateBitmapShader returns a Shader with a reference count of one, we
389 // need to unref after paint takes ownership of the shader. 407 // need to unref after paint takes ownership of the shader.
390 shader->unref(); 408 shader->unref();
391 canvas_->save(); 409 canvas_->save();
392 canvas_->translate(SkIntToScalar(dest_x - src_x), 410 canvas_->translate(SkIntToScalar(dest_x - src_x),
393 SkIntToScalar(dest_y - src_y)); 411 SkIntToScalar(dest_y - src_y));
394 ClipRect(gfx::Rect(src_x, src_y, w, h)); 412 ClipRect(gfx::Rect(src_x, src_y, w, h));
413 canvas_->scale(SkFloatToScalar(1.0f / bitmap_scale),
414 SkFloatToScalar(1.0f / bitmap_scale));
395 canvas_->drawPaint(paint); 415 canvas_->drawPaint(paint);
396 canvas_->restore(); 416 canvas_->restore();
397 } 417 }
398 418
399 gfx::NativeDrawingContext Canvas::BeginPlatformPaint() { 419 gfx::NativeDrawingContext Canvas::BeginPlatformPaint() {
400 return skia::BeginPlatformPaint(canvas_); 420 return skia::BeginPlatformPaint(canvas_);
401 } 421 }
402 422
403 void Canvas::EndPlatformPaint() { 423 void Canvas::EndPlatformPaint() {
404 skia::EndPlatformPaint(canvas_); 424 skia::EndPlatformPaint(canvas_);
405 } 425 }
406 426
407 void Canvas::Transform(const ui::Transform& transform) { 427 void Canvas::Transform(const ui::Transform& transform) {
408 canvas_->concat(transform.matrix()); 428 canvas_->concat(transform.matrix());
409 } 429 }
410 430
411 bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) { 431 bool Canvas::IntersectsClipRectInt(int x, int y, int w, int h) {
412 SkRect clip; 432 SkRect clip;
413 return canvas_->getClipBounds(&clip) && 433 return canvas_->getClipBounds(&clip) &&
414 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), 434 clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
415 SkIntToScalar(y + h)); 435 SkIntToScalar(y + h));
416 } 436 }
417 437
418 bool Canvas::IntersectsClipRect(const gfx::Rect& rect) { 438 bool Canvas::IntersectsClipRect(const gfx::Rect& rect) {
419 return IntersectsClipRectInt(rect.x(), rect.y(), 439 return IntersectsClipRectInt(rect.x(), rect.y(),
420 rect.width(), rect.height()); 440 rect.width(), rect.height());
421 } 441 }
422 442
443
444 const SkBitmap& Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
445 float* bitmap_scale_factor) const {
446 return GetBitmapToPaint(image, 1.0f, 1.0f, bitmap_scale_factor);
447 }
448
449 const SkBitmap& Canvas::GetBitmapToPaint(const gfx::ImageSkia& image,
450 float user_additional_scale_x,
451 float user_additional_scale_y,
452 float* bitmap_scale_factor) const {
453 SkMatrix m = canvas_->getTotalMatrix();
454 float scale_x = SkScalarToFloat(SkScalarAbs(m.getScaleX())) *
455 user_additional_scale_x;
456 float scale_y = SkScalarToFloat(SkScalarAbs(m.getScaleY())) *
457 user_additional_scale_y;
458
459 const SkBitmap& bitmap = image.GetBitmapForScale(scale_x, scale_y,
460 bitmap_scale_factor);
461 if (!bitmap.isNull() &&
462 (scale_x < *bitmap_scale_factor || scale_y < *bitmap_scale_factor))
463 const_cast<SkBitmap&>(bitmap).buildMipMap();
464
465 return bitmap;
466 }
467
423 } // namespace gfx 468 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gfx/canvas.h ('k') | ui/gfx/image/image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698