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