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

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: 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 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
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
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