Clipboard: Store PNGs and bitmaps using same format on ChromeOS
Currently, bitmaps are stored as SkBitmaps on the clipboard. This is limiting, since it requires the bitmap to be re-encoded when later used, and does not allow for us to retain metadata. The ReadPng path fixes both of these issues, but it doesn't make sense to have separate backing stores for PNGs and bitmaps. This CL changes the ClipboardInternalFormat to store each as raw PNG bytes on ChromeOS. Bitmaps are encoded when placed on the clipboard and decoded on read. This CL also consistently adds usage of GetPngType(). Bug: 1201018 Change-Id: I49e425b69437f17c6b93e7fa155150667ca80618 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2859391 Commit-Queue: Austin Sullivan <asully@chromium.org> Reviewed-by: Alex Newcomer <newcomer@chromium.org> Reviewed-by: Darwin Huang <huangdarwin@chromium.org> Cr-Commit-Position: refs/heads/master@{#884536}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
603e236fe8
commit
23dba352a4
ash/clipboard
clipboard_history_resource_manager.ccclipboard_history_resource_manager_unittest.ccclipboard_history_util.ccclipboard_history_util_unittest.cc
test_support
views
content/browser/renderer_host
ui
base
clipboard
strings
@ -159,7 +159,7 @@ std::u16string ClipboardHistoryResourceManager::GetLabel(
|
||||
const ClipboardHistoryItem& item) const {
|
||||
const ui::ClipboardData& data = item.data();
|
||||
switch (ClipboardHistoryUtil::CalculateMainFormat(data).value()) {
|
||||
case ui::ClipboardInternalFormat::kBitmap:
|
||||
case ui::ClipboardInternalFormat::kPng:
|
||||
RecordPlaceholderString(ClipboardHistoryPlaceholderStringType::kBitmap);
|
||||
return GetLocalizedString(IDS_CLIPBOARD_MENU_IMAGE);
|
||||
case ui::ClipboardInternalFormat::kText:
|
||||
|
@ -131,16 +131,16 @@ TEST_F(ClipboardHistoryResourceManagerTest, GetLabel) {
|
||||
.SetFilenames({ui::FileInfo(base::FilePath("/dir/filename"),
|
||||
base::FilePath("filename"))})
|
||||
.SetBookmarkTitle("Bookmark Title")
|
||||
.SetBitmap(gfx::test::CreateBitmap(10, 10))
|
||||
.SetPng(gfx::test::CreatePNGBytes(10))
|
||||
.SetFileSystemData({u"/path/to/File.txt", u"/path/to/Other%20File.txt"})
|
||||
.SetWebSmartPaste(true);
|
||||
|
||||
// Bitmap data always take precedence.
|
||||
// PNG data always take precedence.
|
||||
EXPECT_EQ(resource_manager()->GetLabel(builder.Build()), u"Image");
|
||||
|
||||
builder.ClearBitmap();
|
||||
builder.ClearPng();
|
||||
|
||||
// In the absence of bitmap data, HTML data takes precedence, but we use
|
||||
// In the absence of PNG data, HTML data takes precedence, but we use
|
||||
// plain-text format for the label.
|
||||
EXPECT_EQ(resource_manager()->GetLabel(builder.Build()), u"Text");
|
||||
|
||||
|
@ -29,7 +29,7 @@ constexpr char16_t kFileSystemSourcesType[] = u"fs/sources";
|
||||
|
||||
// The array of formats in order of decreasing priority.
|
||||
constexpr ui::ClipboardInternalFormat kPrioritizedFormats[] = {
|
||||
ui::ClipboardInternalFormat::kBitmap,
|
||||
ui::ClipboardInternalFormat::kPng,
|
||||
ui::ClipboardInternalFormat::kHtml,
|
||||
ui::ClipboardInternalFormat::kText,
|
||||
ui::ClipboardInternalFormat::kRtf,
|
||||
@ -53,7 +53,8 @@ absl::optional<ui::ClipboardInternalFormat> CalculateMainFormat(
|
||||
ClipboardHistoryDisplayFormat CalculateDisplayFormat(
|
||||
const ui::ClipboardData& data) {
|
||||
switch (CalculateMainFormat(data).value()) {
|
||||
case ui::ClipboardInternalFormat::kBitmap:
|
||||
case ui::ClipboardInternalFormat::kPng:
|
||||
// TODO(crbug.com/1207638): Rename this to kImage or kPng.
|
||||
return ClipboardHistoryDisplayFormat::kBitmap;
|
||||
case ui::ClipboardInternalFormat::kHtml:
|
||||
if ((data.markup_data().find("<img") == std::string::npos) &&
|
||||
|
@ -19,7 +19,7 @@ namespace ClipboardHistoryUtil {
|
||||
namespace {
|
||||
|
||||
constexpr std::array<ui::ClipboardInternalFormat, 7> kAllFormats = {
|
||||
ui::ClipboardInternalFormat::kBitmap,
|
||||
ui::ClipboardInternalFormat::kPng,
|
||||
ui::ClipboardInternalFormat::kHtml,
|
||||
ui::ClipboardInternalFormat::kText,
|
||||
ui::ClipboardInternalFormat::kRtf,
|
||||
@ -47,7 +47,7 @@ TEST_F(ClipboardHistoryUtilTest, CalculateMainFormat) {
|
||||
|
||||
// We will cycle through all formats in prioritized order.
|
||||
std::deque<ui::ClipboardInternalFormat> prioritized_formats = {
|
||||
ui::ClipboardInternalFormat::kBitmap,
|
||||
ui::ClipboardInternalFormat::kPng,
|
||||
ui::ClipboardInternalFormat::kHtml,
|
||||
ui::ClipboardInternalFormat::kText,
|
||||
ui::ClipboardInternalFormat::kRtf,
|
||||
|
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/clipboard/test_support/clipboard_history_item_builder.h"
|
||||
#include <vector>
|
||||
|
||||
#include "ash/clipboard/clipboard_history_item.h"
|
||||
#include "base/notreached.h"
|
||||
@ -12,6 +13,7 @@
|
||||
#include "ui/base/clipboard/clipboard_data.h"
|
||||
#include "ui/base/clipboard/clipboard_format_type.h"
|
||||
#include "ui/base/clipboard/custom_data_helper.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/image/image_unittest_util.h"
|
||||
|
||||
namespace ash {
|
||||
@ -32,8 +34,8 @@ ClipboardHistoryItem ClipboardHistoryItemBuilder::Build() const {
|
||||
data.set_filenames(filenames_);
|
||||
if (bookmark_title_.has_value())
|
||||
data.set_bookmark_title(bookmark_title_.value());
|
||||
if (bitmap_.has_value())
|
||||
data.SetBitmapData(bitmap_.value());
|
||||
if (png_.has_value())
|
||||
data.SetPngData(png_.value());
|
||||
if (custom_format_.has_value() && custom_data_.has_value())
|
||||
data.SetCustomData(custom_format_.value(), custom_data_.value());
|
||||
if (web_smart_paste_.has_value())
|
||||
@ -46,7 +48,7 @@ ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::Clear() {
|
||||
markup_ = absl::nullopt;
|
||||
rtf_ = absl::nullopt;
|
||||
bookmark_title_ = absl::nullopt;
|
||||
bitmap_ = absl::nullopt;
|
||||
png_ = absl::nullopt;
|
||||
custom_format_ = absl::nullopt;
|
||||
custom_data_ = absl::nullopt;
|
||||
web_smart_paste_ = absl::nullopt;
|
||||
@ -69,8 +71,8 @@ ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::SetFormat(
|
||||
base::FilePath("filename"))});
|
||||
case ui::ClipboardInternalFormat::kBookmark:
|
||||
return SetBookmarkTitle("Bookmark Title");
|
||||
case ui::ClipboardInternalFormat::kBitmap:
|
||||
return SetBitmap(gfx::test::CreateBitmap(10, 10));
|
||||
case ui::ClipboardInternalFormat::kPng:
|
||||
return SetPng(gfx::test::CreatePNGBytes(10));
|
||||
case ui::ClipboardInternalFormat::kCustom:
|
||||
return SetCustomData("Custom Format", "Custom Data");
|
||||
case ui::ClipboardInternalFormat::kWeb:
|
||||
@ -94,8 +96,8 @@ ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::ClearFormat(
|
||||
return ClearFilenames();
|
||||
case ui::ClipboardInternalFormat::kBookmark:
|
||||
return ClearBookmarkTitle();
|
||||
case ui::ClipboardInternalFormat::kBitmap:
|
||||
return ClearBitmap();
|
||||
case ui::ClipboardInternalFormat::kPng:
|
||||
return ClearPng();
|
||||
case ui::ClipboardInternalFormat::kCustom:
|
||||
return ClearCustomData();
|
||||
case ui::ClipboardInternalFormat::kWeb:
|
||||
@ -171,14 +173,20 @@ ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::ClearBookmarkTitle() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::SetBitmap(
|
||||
const SkBitmap& bitmap) {
|
||||
bitmap_ = bitmap;
|
||||
ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::SetPng(
|
||||
const scoped_refptr<base::RefCountedMemory>& png) {
|
||||
std::vector<uint8_t> data(png->data(), png->data() + png->size());
|
||||
return SetPng(std::move(data));
|
||||
}
|
||||
|
||||
ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::SetPng(
|
||||
std::vector<uint8_t> png) {
|
||||
png_ = std::move(png);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::ClearBitmap() {
|
||||
bitmap_ = absl::nullopt;
|
||||
ClipboardHistoryItemBuilder& ClipboardHistoryItemBuilder::ClearPng() {
|
||||
png_ = absl::nullopt;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
#include <string>
|
||||
|
||||
#include "ash/ash_export.h"
|
||||
#include "base/memory/ref_counted_memory.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/clipboard/file_info.h"
|
||||
|
||||
namespace ui {
|
||||
@ -67,9 +67,11 @@ class ASH_EXPORT ClipboardHistoryItemBuilder {
|
||||
const std::string& bookmark_title);
|
||||
ClipboardHistoryItemBuilder& ClearBookmarkTitle();
|
||||
|
||||
// Sets/clears `bitmap_` data.
|
||||
ClipboardHistoryItemBuilder& SetBitmap(const SkBitmap& bitmap);
|
||||
ClipboardHistoryItemBuilder& ClearBitmap();
|
||||
// Sets/clears `png_` data.
|
||||
ClipboardHistoryItemBuilder& SetPng(std::vector<uint8_t> png);
|
||||
ClipboardHistoryItemBuilder& SetPng(
|
||||
const scoped_refptr<base::RefCountedMemory>& png);
|
||||
ClipboardHistoryItemBuilder& ClearPng();
|
||||
|
||||
// Sets/clears `custom_format_` and `custom_data_` data.
|
||||
ClipboardHistoryItemBuilder& SetCustomData(const std::string& custom_format,
|
||||
@ -93,7 +95,7 @@ class ASH_EXPORT ClipboardHistoryItemBuilder {
|
||||
absl::optional<std::string> rtf_;
|
||||
std::vector<ui::FileInfo> filenames_;
|
||||
absl::optional<std::string> bookmark_title_;
|
||||
absl::optional<SkBitmap> bitmap_;
|
||||
absl::optional<std::vector<uint8_t>> png_;
|
||||
absl::optional<std::string> custom_format_;
|
||||
absl::optional<std::string> custom_data_;
|
||||
absl::optional<bool> web_smart_paste_;
|
||||
|
@ -15,9 +15,11 @@
|
||||
#include "base/time/time.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/base/models/image_model.h"
|
||||
#include "ui/compositor/layer.h"
|
||||
#include "ui/compositor/layer_animation_observer.h"
|
||||
#include "ui/compositor/scoped_layer_animation_settings.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/strings/grit/ui_strings.h"
|
||||
#include "ui/views/controls/image_view.h"
|
||||
@ -235,11 +237,13 @@ class ClipboardHistoryBitmapItemView::BitmapContentsView
|
||||
clipboard_history_item, container_->resource_manager_,
|
||||
base::BindRepeating(&BitmapContentsView::UpdateImageViewSize,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
case ui::ClipboardInternalFormat::kBitmap: {
|
||||
case ui::ClipboardInternalFormat::kPng: {
|
||||
auto image_view = std::make_unique<views::ImageView>();
|
||||
gfx::ImageSkia bitmap_image = gfx::ImageSkia::CreateFrom1xBitmap(
|
||||
clipboard_history_item->data().bitmap());
|
||||
image_view->SetImage(bitmap_image);
|
||||
gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
|
||||
clipboard_history_item->data().png().data(),
|
||||
clipboard_history_item->data().png().size());
|
||||
ui::ImageModel image_model = ui::ImageModel::FromImage(image);
|
||||
image_view->SetImage(image_model);
|
||||
return image_view;
|
||||
}
|
||||
default:
|
||||
@ -262,7 +266,7 @@ class ClipboardHistoryBitmapItemView::BitmapContentsView
|
||||
// should meet at least one edge of the contents bounds.
|
||||
float scaling_up_ratio = 0.f;
|
||||
switch (container_->data_format_) {
|
||||
case ui::ClipboardInternalFormat::kBitmap: {
|
||||
case ui::ClipboardInternalFormat::kPng: {
|
||||
scaling_up_ratio = std::fmin(width_ratio, height_ratio);
|
||||
break;
|
||||
}
|
||||
@ -318,8 +322,8 @@ std::u16string ClipboardHistoryBitmapItemView::GetAccessibleName() const {
|
||||
switch (data_format_) {
|
||||
case ui::ClipboardInternalFormat::kHtml:
|
||||
return l10n_util::GetStringUTF16(IDS_CLIPBOARD_HISTORY_MENU_HTML_IMAGE);
|
||||
case ui::ClipboardInternalFormat::kBitmap:
|
||||
return l10n_util::GetStringUTF16(IDS_CLIPBOARD_HISTORY_MENU_BITMAP_IMAGE);
|
||||
case ui::ClipboardInternalFormat::kPng:
|
||||
return l10n_util::GetStringUTF16(IDS_CLIPBOARD_HISTORY_MENU_PNG_IMAGE);
|
||||
default:
|
||||
NOTREACHED();
|
||||
return std::u16string();
|
||||
|
@ -335,9 +335,8 @@ void ClipboardHostImpl::OnReadPng(ui::ClipboardBuffer clipboard_buffer,
|
||||
const std::vector<uint8_t>& data) {
|
||||
std::string string_data(
|
||||
reinterpret_cast<const char*>(data.data(), data.data() + data.size()));
|
||||
// TODO(crbug.com/1201018): Create GetPngType() and use it here.
|
||||
PasteIfPolicyAllowed(
|
||||
clipboard_buffer, ui::ClipboardFormatType::GetBitmapType(),
|
||||
clipboard_buffer, ui::ClipboardFormatType::GetPngType(),
|
||||
std::move(string_data),
|
||||
base::BindOnce(
|
||||
[](std::vector<uint8_t> data, ReadPngCallback callback,
|
||||
|
@ -211,6 +211,7 @@ source_set("clipboard_test_support") {
|
||||
"//build:chromecast_buildflags",
|
||||
"//build:chromeos_buildflags",
|
||||
"//ui/base:features",
|
||||
"//ui/gfx",
|
||||
]
|
||||
|
||||
if (is_android) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "base/notreached.h"
|
||||
#include "skia/ext/skia_utils_base.h"
|
||||
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
|
||||
#include "ui/gfx/codec/png_codec.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
|
||||
namespace ui {
|
||||
@ -22,7 +23,7 @@ ClipboardData::ClipboardData(const ClipboardData& other) {
|
||||
markup_data_ = other.markup_data_;
|
||||
url_ = other.url_;
|
||||
rtf_data_ = other.rtf_data_;
|
||||
bitmap_ = other.bitmap();
|
||||
png_ = other.png_;
|
||||
bookmark_title_ = other.bookmark_title_;
|
||||
bookmark_url_ = other.bookmark_url_;
|
||||
custom_data_format_ = other.custom_data_format_;
|
||||
@ -48,7 +49,7 @@ bool ClipboardData::operator==(const ClipboardData& that) const {
|
||||
custom_data_data_ == that.custom_data_data() &&
|
||||
web_smart_paste_ == that.web_smart_paste() &&
|
||||
svg_data_ == that.svg_data() && filenames_ == that.filenames() &&
|
||||
gfx::BitmapsAreEqual(bitmap_, that.bitmap()) &&
|
||||
png_ == that.png() &&
|
||||
(src_.get() ? (that.source() && *src_.get() == *that.source())
|
||||
: !that.source());
|
||||
}
|
||||
@ -57,10 +58,22 @@ bool ClipboardData::operator!=(const ClipboardData& that) const {
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
void ClipboardData::SetPngData(std::vector<uint8_t> png) {
|
||||
png_ = std::move(png);
|
||||
format_ |= static_cast<int>(ClipboardInternalFormat::kPng);
|
||||
}
|
||||
|
||||
SkBitmap ClipboardData::bitmap() const {
|
||||
SkBitmap bitmap;
|
||||
gfx::PNGCodec::Decode(png_.data(), png_.size(), &bitmap);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
void ClipboardData::SetBitmapData(const SkBitmap& bitmap) {
|
||||
DCHECK_EQ(bitmap.colorType(), kN32_SkColorType);
|
||||
bitmap_ = bitmap;
|
||||
format_ |= static_cast<int>(ClipboardInternalFormat::kBitmap);
|
||||
gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, /*discard_transparency=*/false,
|
||||
&png_);
|
||||
format_ |= static_cast<int>(ClipboardInternalFormat::kPng);
|
||||
}
|
||||
|
||||
void ClipboardData::SetCustomData(const std::string& data_format,
|
||||
|
@ -24,7 +24,7 @@ enum class ClipboardInternalFormat {
|
||||
kSvg = 1 << 2,
|
||||
kRtf = 1 << 3,
|
||||
kBookmark = 1 << 4,
|
||||
kBitmap = 1 << 5,
|
||||
kPng = 1 << 5,
|
||||
kCustom = 1 << 6,
|
||||
kWeb = 1 << 7,
|
||||
kFilenames = 1 << 8,
|
||||
@ -88,7 +88,12 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardData {
|
||||
format_ |= static_cast<int>(ClipboardInternalFormat::kBookmark);
|
||||
}
|
||||
|
||||
const SkBitmap& bitmap() const { return bitmap_; }
|
||||
const std::vector<uint8_t>& png() const { return png_; }
|
||||
void SetPngData(std::vector<uint8_t> png);
|
||||
|
||||
// Bitmaps are stored as encoded bytes in the `png_` member. This means we
|
||||
// cannot return a const reference, since the bitmap is created on request.
|
||||
SkBitmap bitmap() const;
|
||||
void SetBitmapData(const SkBitmap& bitmap);
|
||||
|
||||
const std::string& custom_data_format() const { return custom_data_format_; }
|
||||
@ -130,8 +135,8 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD) ClipboardData {
|
||||
std::string bookmark_title_;
|
||||
std::string bookmark_url_;
|
||||
|
||||
// Bitmap images.
|
||||
SkBitmap bitmap_;
|
||||
// PNG image data. Bitmaps are encoded into and decoded from this member.
|
||||
std::vector<uint8_t> png_;
|
||||
|
||||
// Data with custom format.
|
||||
std::string custom_data_format_;
|
||||
|
@ -9,13 +9,14 @@
|
||||
#include "base/strings/string_piece_forward.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
|
||||
#include "ui/gfx/skia_util.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Tests that two ClipboardData objects won't be equal if they don't have the
|
||||
// same bitmap.
|
||||
TEST(ClipboardDataTest, BitMapTest) {
|
||||
TEST(ClipboardDataTest, BitmapTest) {
|
||||
ClipboardData data1;
|
||||
SkBitmap test_bitmap;
|
||||
test_bitmap.allocN32Pixels(3, 2);
|
||||
@ -43,4 +44,15 @@ TEST(ClipboardDataTest, DataSrcTest) {
|
||||
EXPECT_EQ(data1, data2);
|
||||
}
|
||||
|
||||
// Tests that encoding/decoding bitmaps as PNG bytes works as intended.
|
||||
TEST(ClipboardDataTest, BitmapAsBytesTest) {
|
||||
ClipboardData data1;
|
||||
SkBitmap test_bitmap;
|
||||
test_bitmap.allocN32Pixels(3, 2);
|
||||
test_bitmap.eraseARGB(255, 0, 255, 0);
|
||||
EXPECT_FALSE(gfx::BitmapsAreEqual(data1.bitmap(), test_bitmap));
|
||||
data1.SetBitmapData(test_bitmap);
|
||||
EXPECT_TRUE(gfx::BitmapsAreEqual(data1.bitmap(), test_bitmap));
|
||||
}
|
||||
|
||||
} // namespace ui
|
@ -62,6 +62,8 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) ClipboardFormatType {
|
||||
static const ClipboardFormatType& GetHtmlType();
|
||||
static const ClipboardFormatType& GetSvgType();
|
||||
static const ClipboardFormatType& GetRtfType();
|
||||
static const ClipboardFormatType& GetPngType();
|
||||
// TODO(crbug.com/1201018): Remove this type.
|
||||
static const ClipboardFormatType& GetBitmapType();
|
||||
static const ClipboardFormatType& GetWebCustomDataType();
|
||||
|
||||
@ -83,9 +85,6 @@ class COMPONENT_EXPORT(UI_BASE_CLIPBOARD_TYPES) ClipboardFormatType {
|
||||
static const ClipboardFormatType& GetFilenameType();
|
||||
static const ClipboardFormatType& GetIDListType();
|
||||
static const ClipboardFormatType& GetMozUrlType();
|
||||
|
||||
// Specific image types that handle transparency on Windows.
|
||||
static const ClipboardFormatType& GetPNGType();
|
||||
#endif
|
||||
|
||||
// ClipboardFormatType can be used in a set on some platforms.
|
||||
|
@ -90,11 +90,16 @@ const ClipboardFormatType& ClipboardFormatType::GetRtfType() {
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetBitmapType() {
|
||||
const ClipboardFormatType& ClipboardFormatType::GetPngType() {
|
||||
static base::NoDestructor<ClipboardFormatType> type(kMimeTypePNG);
|
||||
return *type;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetBitmapType() {
|
||||
return ClipboardFormatType::GetPngType();
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetWebCustomDataType() {
|
||||
static base::NoDestructor<ClipboardFormatType> type(kMimeTypeWebCustomData);
|
||||
|
@ -86,11 +86,16 @@ const ClipboardFormatType& ClipboardFormatType::GetRtfType() {
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetBitmapType() {
|
||||
const ClipboardFormatType& ClipboardFormatType::GetPngType() {
|
||||
static base::NoDestructor<ClipboardFormatType> type(kMimeTypePNG);
|
||||
return *type;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetBitmapType() {
|
||||
return ClipboardFormatType::GetPngType();
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetWebKitSmartPasteType() {
|
||||
static base::NoDestructor<ClipboardFormatType> type(
|
||||
|
@ -98,6 +98,12 @@ const ClipboardFormatType& ClipboardFormatType::GetRtfType() {
|
||||
return *type;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetPngType() {
|
||||
static base::NoDestructor<ClipboardFormatType> type(NSPasteboardTypePNG);
|
||||
return *type;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetBitmapType() {
|
||||
static base::NoDestructor<ClipboardFormatType> type(NSTIFFPboardType);
|
||||
|
@ -211,6 +211,13 @@ const ClipboardFormatType& ClipboardFormatType::GetRtfType() {
|
||||
return *format;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetPngType() {
|
||||
static base::NoDestructor<ClipboardFormatType> format(
|
||||
::RegisterClipboardFormat(L"PNG"));
|
||||
return *format;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetBitmapType() {
|
||||
static base::NoDestructor<ClipboardFormatType> format(CF_DIBV5);
|
||||
@ -340,11 +347,4 @@ const ClipboardFormatType& ClipboardFormatType::GetWebCustomDataType() {
|
||||
return *format;
|
||||
}
|
||||
|
||||
// static
|
||||
const ClipboardFormatType& ClipboardFormatType::GetPNGType() {
|
||||
static base::NoDestructor<ClipboardFormatType> format(
|
||||
::RegisterClipboardFormat(L"PNG"));
|
||||
return *format;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -183,7 +183,7 @@ class ClipboardInternal {
|
||||
// Reads image from the ClipboardData.
|
||||
SkBitmap ReadImage() const {
|
||||
SkBitmap img;
|
||||
if (!HasFormat(ClipboardInternalFormat::kBitmap))
|
||||
if (!HasFormat(ClipboardInternalFormat::kPng))
|
||||
return img;
|
||||
|
||||
// A shallow copy should be fine here, but just to be safe...
|
||||
@ -435,9 +435,10 @@ bool ClipboardNonBacked::IsFormatAvailable(
|
||||
if (format == ClipboardFormatType::GetRtfType())
|
||||
return clipboard_internal_->IsFormatAvailable(
|
||||
ClipboardInternalFormat::kRtf);
|
||||
if (format == ClipboardFormatType::GetBitmapType())
|
||||
if (format == ClipboardFormatType::GetPngType() ||
|
||||
format == ClipboardFormatType::GetBitmapType())
|
||||
return clipboard_internal_->IsFormatAvailable(
|
||||
ClipboardInternalFormat::kBitmap);
|
||||
ClipboardInternalFormat::kPng);
|
||||
if (format == ClipboardFormatType::GetWebKitSmartPasteType())
|
||||
return clipboard_internal_->IsFormatAvailable(
|
||||
ClipboardInternalFormat::kWeb);
|
||||
|
@ -779,7 +779,7 @@ void ClipboardWin::WriteBitmap(const SkBitmap& bitmap) {
|
||||
&png_encoded_bitmap)) {
|
||||
HGLOBAL png_hglobal = skia::CreateHGlobalForByteArray(png_encoded_bitmap);
|
||||
if (png_hglobal)
|
||||
WriteToClipboard(ClipboardFormatType::GetPNGType(), png_hglobal);
|
||||
WriteToClipboard(ClipboardFormatType::GetPngType(), png_hglobal);
|
||||
}
|
||||
HGLOBAL dibv5_hglobal = skia::CreateDIBV5ImageDataFromN32SkBitmap(bitmap);
|
||||
if (dibv5_hglobal)
|
||||
|
@ -1074,7 +1074,7 @@ need to be translated for each locale.-->
|
||||
</message>
|
||||
|
||||
<!-- Clipboard history menu -->
|
||||
<message name="IDS_CLIPBOARD_HISTORY_MENU_BITMAP_IMAGE" desc="Accessibility text for the bitmap image shown on the clipboard history menu">
|
||||
<message name="IDS_CLIPBOARD_HISTORY_MENU_PNG_IMAGE" desc="Accessibility text for the PNG image shown on the clipboard history menu">
|
||||
Image.
|
||||
</message>
|
||||
<message name="IDS_CLIPBOARD_HISTORY_MENU_HTML_IMAGE" desc="Accessibility text for the HTML-rendered image shown on the clipboard history menu">
|
||||
|
Reference in New Issue
Block a user