1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/cursor/cursor.h"
#include <algorithm>
#include <utility>
#include "base/check_op.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/skia_util.h"
namespace ui {
using mojom::CursorType;
CursorData::CursorData() : bitmaps({SkBitmap()}) {}
CursorData::CursorData(std::vector<SkBitmap> bitmaps,
gfx::Point hotspot,
float scale_factor)
: bitmaps(std::move(bitmaps)),
hotspot(std::move(hotspot)),
scale_factor(scale_factor) {
CHECK_GT(this->bitmaps.size(), 0u);
CHECK_GT(scale_factor, 0);
}
CursorData::CursorData(const CursorData& cursor_data) = default;
CursorData::~CursorData() = default;
// static
Cursor Cursor::NewCustom(SkBitmap bitmap,
gfx::Point hotspot,
float image_scale_factor) {
return Cursor(std::move(bitmap), std::move(hotspot), image_scale_factor);
}
Cursor::Cursor() = default;
Cursor::Cursor(CursorType type) : type_(type) {}
Cursor::Cursor(SkBitmap bitmap, gfx::Point hotspot, float image_scale_factor)
: type_(CursorType::kCustom),
custom_bitmap_(std::move(bitmap)),
image_scale_factor_(image_scale_factor) {
CHECK_GT(image_scale_factor_, 0);
// Clamp the hotspot to the custom image's dimensions.
if (!custom_bitmap_.empty()) {
custom_hotspot_ =
gfx::Point(std::clamp(hotspot.x(), 0, custom_bitmap_.width() - 1),
std::clamp(hotspot.y(), 0, custom_bitmap_.height() - 1));
}
}
Cursor::Cursor(const Cursor& cursor) = default;
Cursor::~Cursor() = default;
void Cursor::SetPlatformCursor(scoped_refptr<PlatformCursor> platform_cursor) {
platform_cursor_ = platform_cursor;
}
const SkBitmap& Cursor::custom_bitmap() const {
CHECK_EQ(type_, CursorType::kCustom);
return custom_bitmap_;
}
const gfx::Point& Cursor::custom_hotspot() const {
CHECK_EQ(type_, CursorType::kCustom);
return custom_hotspot_;
}
float Cursor::image_scale_factor() const {
CHECK_EQ(type_, CursorType::kCustom);
return image_scale_factor_;
}
bool Cursor::operator==(const Cursor& cursor) const {
return type_ == cursor.type_ && platform_cursor_ == cursor.platform_cursor_ &&
(type_ != CursorType::kCustom ||
(image_scale_factor_ == cursor.image_scale_factor_ &&
custom_hotspot_ == cursor.custom_hotspot_ &&
gfx::BitmapsAreEqual(custom_bitmap_, cursor.custom_bitmap_)));
}
// static
bool Cursor::AreDimensionsValidForWeb(const gfx::Size& size,
float scale_factor) {
if (scale_factor == 0) {
return false;
}
// https://developer.mozilla.org/en-US/docs/Web/CSS/cursor#icon_size_limits.
static constexpr int kMaximumCursorDIPSize = 128;
const gfx::Size size_in_dip = gfx::ScaleToCeiledSize(size, 1 / scale_factor);
if (size_in_dip.width() > kMaximumCursorDIPSize ||
size_in_dip.height() > kMaximumCursorDIPSize) {
return false;
}
return true;
}
} // namespace ui
|