1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/base/cursor/cursor_util.h" 6 7#include "base/logging.h" 8#include "skia/ext/image_operations.h" 9#include "ui/base/resource/resource_bundle.h" 10#include "ui/gfx/image/image_skia.h" 11#include "ui/gfx/point_conversions.h" 12#include "ui/gfx/size_conversions.h" 13#include "ui/gfx/skbitmap_operations.h" 14#include "ui/gfx/skia_util.h" 15 16namespace ui { 17 18void ScaleAndRotateCursorBitmapAndHotpoint(float scale, 19 gfx::Display::Rotation rotation, 20 SkBitmap* bitmap, 21 gfx::Point* hotpoint) { 22 switch (rotation) { 23 case gfx::Display::ROTATE_0: 24 break; 25 case gfx::Display::ROTATE_90: 26 hotpoint->SetPoint(bitmap->height() - hotpoint->y(), hotpoint->x()); 27 *bitmap = SkBitmapOperations::Rotate( 28 *bitmap, SkBitmapOperations::ROTATION_90_CW); 29 break; 30 case gfx::Display::ROTATE_180: 31 hotpoint->SetPoint( 32 bitmap->width() - hotpoint->x(), bitmap->height() - hotpoint->y()); 33 *bitmap = SkBitmapOperations::Rotate( 34 *bitmap, SkBitmapOperations::ROTATION_180_CW); 35 break; 36 case gfx::Display::ROTATE_270: 37 hotpoint->SetPoint(hotpoint->y(), bitmap->width() - hotpoint->x()); 38 *bitmap = SkBitmapOperations::Rotate( 39 *bitmap, SkBitmapOperations::ROTATION_270_CW); 40 break; 41 } 42 43 if (scale < FLT_EPSILON) { 44 NOTREACHED() << "Scale must be larger than 0."; 45 scale = 1.0f; 46 } 47 48 if (scale == 1.0f) 49 return; 50 51 gfx::Size scaled_size = gfx::ToFlooredSize( 52 gfx::ScaleSize(gfx::Size(bitmap->width(), bitmap->height()), scale)); 53 54 *bitmap = skia::ImageOperations::Resize( 55 *bitmap, 56 skia::ImageOperations::RESIZE_BETTER, 57 scaled_size.width(), 58 scaled_size.height()); 59 *hotpoint = gfx::ToFlooredPoint(gfx::ScalePoint(*hotpoint, scale)); 60} 61 62void GetImageCursorBitmap(int resource_id, 63 float scale, 64 gfx::Display::Rotation rotation, 65 gfx::Point* hotspot, 66 SkBitmap* bitmap) { 67 const gfx::ImageSkia* image = 68 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); 69 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale); 70 // TODO(oshima): The cursor should use resource scale factor when 71 // fractional scale factor is enabled. crbug.com/372212 72 (*bitmap) = image_rep.sk_bitmap(); 73 ScaleAndRotateCursorBitmapAndHotpoint( 74 scale / image_rep.scale(), rotation, bitmap, hotspot); 75 // |image_rep| is owned by the resource bundle. So we do not need to free it. 76} 77 78void GetAnimatedCursorBitmaps(int resource_id, 79 float scale, 80 gfx::Display::Rotation rotation, 81 gfx::Point* hotspot, 82 std::vector<SkBitmap>* bitmaps) { 83 // TODO(oshima|tdanderson): Support rotation and fractional scale factor. 84 const gfx::ImageSkia* image = 85 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); 86 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale); 87 SkBitmap bitmap = image_rep.sk_bitmap(); 88 int frame_width = bitmap.height(); 89 int frame_height = frame_width; 90 int total_width = bitmap.width(); 91 DCHECK_EQ(total_width % frame_width, 0); 92 int frame_count = total_width / frame_width; 93 DCHECK_GT(frame_count, 0); 94 95 bitmaps->resize(frame_count); 96 97 for (int frame = 0; frame < frame_count; ++frame) { 98 int x_offset = frame_width * frame; 99 DCHECK_LE(x_offset + frame_width, total_width); 100 101 SkBitmap cropped = SkBitmapOperations::CreateTiledBitmap( 102 bitmap, x_offset, 0, frame_width, frame_height); 103 DCHECK_EQ(frame_width, cropped.width()); 104 DCHECK_EQ(frame_height, cropped.height()); 105 106 (*bitmaps)[frame] = cropped; 107 } 108} 109 110} // namespace ui 111