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

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

Powered by Google App Engine
This is Rietveld 408576698