• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 namespace ui {
17 
ScaleAndRotateCursorBitmapAndHotpoint(float scale,gfx::Display::Rotation rotation,SkBitmap * bitmap,gfx::Point * hotpoint)18 void 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 
GetImageCursorBitmap(int resource_id,float scale,gfx::Display::Rotation rotation,gfx::Point * hotspot,SkBitmap * bitmap)62 void 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 
GetAnimatedCursorBitmaps(int resource_id,float scale,gfx::Display::Rotation rotation,gfx::Point * hotspot,std::vector<SkBitmap> * bitmaps)78 void 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