summaryrefslogtreecommitdiff
path: root/chromium/ui/base/clipboard
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 15:05:36 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:33:47 +0000
commite684a3455bcc29a6e3e66a004e352dea4e1141e7 (patch)
treed55b4003bde34d7d05f558f02cfd82b2a66a7aac /chromium/ui/base/clipboard
parent2b94bfe47ccb6c08047959d1c26e392919550e86 (diff)
downloadqtwebengine-chromium-e684a3455bcc29a6e3e66a004e352dea4e1141e7.tar.gz
BASELINE: Update Chromium to 72.0.3626.110 and Ninja to 1.9.0
Change-Id: Ic57220b00ecc929a893c91f5cc552f5d3e99e922 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/ui/base/clipboard')
-rw-r--r--chromium/ui/base/clipboard/clipboard.cc18
-rw-r--r--chromium/ui/base/clipboard/clipboard.h4
-rw-r--r--chromium/ui/base/clipboard/clipboard_android.cc6
-rw-r--r--chromium/ui/base/clipboard/clipboard_aura.cc85
-rw-r--r--chromium/ui/base/clipboard/clipboard_aura.h5
-rw-r--r--chromium/ui/base/clipboard/clipboard_aurax11.cc33
-rw-r--r--chromium/ui/base/clipboard/clipboard_mac.mm41
-rw-r--r--chromium/ui/base/clipboard/clipboard_test_template.h155
-rw-r--r--chromium/ui/base/clipboard/clipboard_util_mac.h13
-rw-r--r--chromium/ui/base/clipboard/clipboard_util_mac.mm27
-rw-r--r--chromium/ui/base/clipboard/clipboard_util_mac_unittest.mm14
-rw-r--r--chromium/ui/base/clipboard/clipboard_win.cc12
12 files changed, 272 insertions, 141 deletions
diff --git a/chromium/ui/base/clipboard/clipboard.cc b/chromium/ui/base/clipboard/clipboard.cc
index 38665261399..a621d64fa9e 100644
--- a/chromium/ui/base/clipboard/clipboard.cc
+++ b/chromium/ui/base/clipboard/clipboard.cc
@@ -64,6 +64,24 @@ Clipboard* Clipboard::GetForCurrentThread() {
}
// static
+std::unique_ptr<Clipboard> Clipboard::TakeForCurrentThread() {
+ base::AutoLock lock(clipboard_map_lock_.Get());
+
+ ClipboardMap* clipboard_map = clipboard_map_.Pointer();
+ base::PlatformThreadId id = base::PlatformThread::CurrentId();
+
+ Clipboard* clipboard = nullptr;
+
+ auto it = clipboard_map->find(id);
+ if (it != clipboard_map->end()) {
+ clipboard = it->second.release();
+ clipboard_map->erase(it);
+ }
+
+ return base::WrapUnique(clipboard);
+}
+
+// static
void Clipboard::OnPreShutdownForCurrentThread() {
base::AutoLock lock(clipboard_map_lock_.Get());
base::PlatformThreadId id = GetAndValidateThreadID();
diff --git a/chromium/ui/base/clipboard/clipboard.h b/chromium/ui/base/clipboard/clipboard.h
index d76a66d657b..60410973f82 100644
--- a/chromium/ui/base/clipboard/clipboard.h
+++ b/chromium/ui/base/clipboard/clipboard.h
@@ -142,6 +142,10 @@ class UI_BASE_EXPORT Clipboard : public base::ThreadChecker {
// the IO thread.
static Clipboard* GetForCurrentThread();
+ // Removes and transfers ownership of the current thread's clipboard to the
+ // caller. If the clipboard was never initialized, returns nullptr.
+ static std::unique_ptr<Clipboard> TakeForCurrentThread();
+
// Does any work necessary prior to Chrome shutdown for the current thread.
// All platforms but Windows have a single clipboard shared accross all
// threads. This function is a no-op on Windows. On Desktop Linux, if Chrome
diff --git a/chromium/ui/base/clipboard/clipboard_android.cc b/chromium/ui/base/clipboard/clipboard_android.cc
index c1fada750f6..6fe4940555d 100644
--- a/chromium/ui/base/clipboard/clipboard_android.cc
+++ b/chromium/ui/base/clipboard/clipboard_android.cc
@@ -497,10 +497,8 @@ void ClipboardAndroid::WriteObjects(ClipboardType type,
DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
g_map.Get().Clear();
- for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end();
- ++iter) {
- DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
- }
+ for (const auto& object : objects)
+ DispatchObject(static_cast<ObjectType>(object.first), object.second);
g_map.Get().CommitToAndroidClipboard();
}
diff --git a/chromium/ui/base/clipboard/clipboard_aura.cc b/chromium/ui/base/clipboard/clipboard_aura.cc
index f185182cb36..202a1963b0d 100644
--- a/chromium/ui/base/clipboard/clipboard_aura.cc
+++ b/chromium/ui/base/clipboard/clipboard_aura.cc
@@ -17,6 +17,7 @@
#include "base/memory/ptr_util.h"
#include "base/no_destructor.h"
#include "base/strings/utf_string_conversions.h"
+#include "skia/ext/skia_utils_base.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_monitor.h"
#include "ui/base/clipboard/custom_data_helper.h"
@@ -92,9 +93,9 @@ class ClipboardData {
const SkBitmap& bitmap() const { return bitmap_; }
void SetBitmapData(const SkBitmap& bitmap) {
- if (bitmap_.tryAllocPixels(bitmap.info())) {
- bitmap.readPixels(bitmap_.info(), bitmap_.getPixels(), bitmap_.rowBytes(),
- 0, 0);
+ if (!skia::SkBitmapToN32OpaqueOrPremul(bitmap, &bitmap_)) {
+ NOTREACHED() << "Unable to convert bitmap for clipboard";
+ return;
}
format_ |= BITMAP;
}
@@ -152,6 +153,8 @@ class ClipboardData {
DISALLOW_COPY_AND_ASSIGN(ClipboardData);
};
+} // namespace
+
// Platform clipboard implementation for Aura. This handles things like format
// conversion, versioning of clipboard items etc. The goal is to roughly provide
// a substitute to platform clipboards on other platforms such as GtkClipboard
@@ -330,24 +333,11 @@ class AuraClipboard {
DISALLOW_COPY_AND_ASSIGN(AuraClipboard);
};
-AuraClipboard* g_aura_clipboard = NULL;
-
-AuraClipboard* GetClipboard() {
- if (!g_aura_clipboard)
- g_aura_clipboard = new AuraClipboard();
- return g_aura_clipboard;
-}
-
-void DeleteClipboard() {
- delete g_aura_clipboard;
- g_aura_clipboard = NULL;
-}
-
// Helper class to build a ClipboardData object and write it to clipboard.
class ClipboardDataBuilder {
public:
- static void CommitToClipboard() {
- GetClipboard()->WriteData(TakeCurrentData());
+ static void CommitToClipboard(AuraClipboard* clipboard) {
+ clipboard->WriteData(TakeCurrentData());
}
static void WriteText(const char* text_data, size_t text_len) {
@@ -414,8 +404,6 @@ class ClipboardDataBuilder {
ClipboardData* ClipboardDataBuilder::current_data_ = nullptr;
-} // namespace
-
// Clipboard::FormatType implementation.
Clipboard::FormatType::FormatType() {
}
@@ -533,49 +521,45 @@ Clipboard* Clipboard::Create() {
}
// ClipboardAura implementation.
-ClipboardAura::ClipboardAura() {
+ClipboardAura::ClipboardAura()
+ : clipboard_internal_(std::make_unique<AuraClipboard>()) {
DCHECK(CalledOnValidThread());
- // Make sure clipboard is created.
- GetClipboard();
}
ClipboardAura::~ClipboardAura() {
DCHECK(CalledOnValidThread());
- DeleteClipboard();
}
void ClipboardAura::OnPreShutdown() {}
uint64_t ClipboardAura::GetSequenceNumber(ClipboardType type) const {
DCHECK(CalledOnValidThread());
- return GetClipboard()->sequence_number();
+ return clipboard_internal_->sequence_number();
}
bool ClipboardAura::IsFormatAvailable(const FormatType& format,
ClipboardType type) const {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
- AuraClipboard* clipboard = GetClipboard();
if (GetPlainTextFormatType().Equals(format) ||
GetUrlFormatType().Equals(format))
- return clipboard->IsFormatAvailable(TEXT);
+ return clipboard_internal_->IsFormatAvailable(TEXT);
if (GetHtmlFormatType().Equals(format))
- return clipboard->IsFormatAvailable(HTML);
+ return clipboard_internal_->IsFormatAvailable(HTML);
if (GetRtfFormatType().Equals(format))
- return clipboard->IsFormatAvailable(RTF);
+ return clipboard_internal_->IsFormatAvailable(RTF);
if (GetBitmapFormatType().Equals(format))
- return clipboard->IsFormatAvailable(BITMAP);
+ return clipboard_internal_->IsFormatAvailable(BITMAP);
if (GetWebKitSmartPasteFormatType().Equals(format))
- return clipboard->IsFormatAvailable(WEB);
- const ClipboardData* data = clipboard->GetData();
+ return clipboard_internal_->IsFormatAvailable(WEB);
+ const ClipboardData* data = clipboard_internal_->GetData();
return data && data->custom_data_format() == format.ToString();
}
void ClipboardAura::Clear(ClipboardType type) {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
- AuraClipboard* clipboard = GetClipboard();
- clipboard->Clear();
+ clipboard_internal_->Clear();
}
void ClipboardAura::ReadAvailableTypes(ClipboardType type,
@@ -598,22 +582,23 @@ void ClipboardAura::ReadAvailableTypes(ClipboardType type,
if (IsFormatAvailable(GetBitmapFormatType(), type))
types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
- AuraClipboard* clipboard = GetClipboard();
- if (clipboard->IsFormatAvailable(CUSTOM) && clipboard->GetData()) {
- ui::ReadCustomDataTypes(clipboard->GetData()->custom_data_data().c_str(),
- clipboard->GetData()->custom_data_data().size(), types);
+ if (clipboard_internal_->IsFormatAvailable(CUSTOM) &&
+ clipboard_internal_->GetData()) {
+ ui::ReadCustomDataTypes(
+ clipboard_internal_->GetData()->custom_data_data().c_str(),
+ clipboard_internal_->GetData()->custom_data_data().size(), types);
}
}
void ClipboardAura::ReadText(ClipboardType type, base::string16* result) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadText(result);
+ clipboard_internal_->ReadText(result);
}
void ClipboardAura::ReadAsciiText(ClipboardType type,
std::string* result) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadAsciiText(result);
+ clipboard_internal_->ReadAsciiText(result);
}
void ClipboardAura::ReadHTML(ClipboardType type,
@@ -622,46 +607,44 @@ void ClipboardAura::ReadHTML(ClipboardType type,
uint32_t* fragment_start,
uint32_t* fragment_end) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadHTML(markup, src_url, fragment_start, fragment_end);
+ clipboard_internal_->ReadHTML(markup, src_url, fragment_start, fragment_end);
}
void ClipboardAura::ReadRTF(ClipboardType type, std::string* result) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadRTF(result);
+ clipboard_internal_->ReadRTF(result);
}
SkBitmap ClipboardAura::ReadImage(ClipboardType type) const {
DCHECK(CalledOnValidThread());
- return GetClipboard()->ReadImage();
+ return clipboard_internal_->ReadImage();
}
void ClipboardAura::ReadCustomData(ClipboardType clipboard_type,
const base::string16& type,
base::string16* result) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadCustomData(type, result);
+ clipboard_internal_->ReadCustomData(type, result);
}
void ClipboardAura::ReadBookmark(base::string16* title,
std::string* url) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadBookmark(title, url);
+ clipboard_internal_->ReadBookmark(title, url);
}
void ClipboardAura::ReadData(const FormatType& format,
std::string* result) const {
DCHECK(CalledOnValidThread());
- GetClipboard()->ReadData(format.ToString(), result);
+ clipboard_internal_->ReadData(format.ToString(), result);
}
void ClipboardAura::WriteObjects(ClipboardType type, const ObjectMap& objects) {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
- for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end();
- ++iter) {
- DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
- }
- ClipboardDataBuilder::CommitToClipboard();
+ for (const auto& object : objects)
+ DispatchObject(static_cast<ObjectType>(object.first), object.second);
+ ClipboardDataBuilder::CommitToClipboard(clipboard_internal_.get());
}
void ClipboardAura::WriteText(const char* text_data, size_t text_len) {
diff --git a/chromium/ui/base/clipboard/clipboard_aura.h b/chromium/ui/base/clipboard/clipboard_aura.h
index dc65413435c..1d3b2083309 100644
--- a/chromium/ui/base/clipboard/clipboard_aura.h
+++ b/chromium/ui/base/clipboard/clipboard_aura.h
@@ -13,10 +13,11 @@
namespace ui {
+class AuraClipboard;
+
class ClipboardAura : public Clipboard {
private:
friend class Clipboard;
-
ClipboardAura();
~ClipboardAura() override;
@@ -60,6 +61,8 @@ class ClipboardAura : public Clipboard {
const char* data_data,
size_t data_len) override;
+ const std::unique_ptr<AuraClipboard> clipboard_internal_;
+
DISALLOW_COPY_AND_ASSIGN(ClipboardAura);
};
diff --git a/chromium/ui/base/clipboard/clipboard_aurax11.cc b/chromium/ui/base/clipboard/clipboard_aurax11.cc
index 4e767fcd9d9..447beb5bc09 100644
--- a/chromium/ui/base/clipboard/clipboard_aurax11.cc
+++ b/chromium/ui/base/clipboard/clipboard_aurax11.cc
@@ -147,9 +147,8 @@ TargetList::TargetList(const AtomVector& target_list)
bool TargetList::ContainsText() const {
std::vector<::Atom> atoms = GetTextAtomsFrom();
- for (std::vector< ::Atom>::const_iterator it = atoms.begin();
- it != atoms.end(); ++it) {
- if (ContainsAtom(*it))
+ for (const auto& atom : atoms) {
+ if (ContainsAtom(atom))
return true;
}
@@ -379,8 +378,8 @@ SelectionData ClipboardAuraX11::AuraX11Details::RequestAndWaitForTypes(
// with the X server.
const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
- for (auto it = types.begin(); it != types.end(); ++it) {
- auto format_map_it = format_map.find(*it);
+ for (const auto& type : types) {
+ auto format_map_it = format_map.find(type);
if (format_map_it != format_map.end())
return SelectionData(format_map_it->first, format_map_it->second);
}
@@ -405,9 +404,8 @@ TargetList ClipboardAuraX11::AuraX11Details::WaitAndGetTargetsList(
// We can local fastpath and return the list of local targets.
const SelectionFormatMap& format_map = LookupStorageForAtom(selection_name);
- for (auto it = format_map.begin(); it != format_map.end(); ++it) {
- out.push_back(it->first);
- }
+ for (const auto& format : format_map)
+ out.push_back(format.first);
} else {
scoped_refptr<base::RefCountedMemory> data;
size_t out_data_items = 0;
@@ -431,16 +429,12 @@ TargetList ClipboardAuraX11::AuraX11Details::WaitAndGetTargetsList(
// copy the data to see if it is available, but at least this path
// shouldn't be hit for conforming programs.
std::vector< ::Atom> types = GetTextAtoms();
- for (std::vector< ::Atom>::const_iterator it = types.begin();
- it != types.end(); ++it) {
+ for (const auto& text_atom : types) {
::Atom type = x11::None;
- if (selection_requestor_.PerformBlockingConvertSelection(selection_name,
- *it,
- NULL,
- NULL,
- &type) &&
- type == *it) {
- out.push_back(*it);
+ if (selection_requestor_.PerformBlockingConvertSelection(
+ selection_name, text_atom, NULL, NULL, &type) &&
+ type == text_atom) {
+ out.push_back(text_atom);
}
}
}
@@ -812,9 +806,8 @@ void ClipboardAuraX11::WriteObjects(ClipboardType type,
DCHECK(IsSupportedClipboardType(type));
aurax11_details_->CreateNewClipboardData();
- for (auto iter = objects.begin(); iter != objects.end(); ++iter) {
- DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
- }
+ for (const auto& object : objects)
+ DispatchObject(static_cast<ObjectType>(object.first), object.second);
aurax11_details_->TakeOwnershipOfSelection(type);
if (type == CLIPBOARD_TYPE_COPY_PASTE) {
diff --git a/chromium/ui/base/clipboard/clipboard_mac.mm b/chromium/ui/base/clipboard/clipboard_mac.mm
index e9abab846ec..267743860ce 100644
--- a/chromium/ui/base/clipboard/clipboard_mac.mm
+++ b/chromium/ui/base/clipboard/clipboard_mac.mm
@@ -18,6 +18,7 @@
#include "base/stl_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
+#include "skia/ext/skia_utils_base.h"
#include "skia/ext/skia_utils_mac.h"
#import "third_party/mozilla/NSPasteboard+Utils.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -214,7 +215,7 @@ void ClipboardMac::Clear(ClipboardType type) {
DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
NSPasteboard* pb = GetPasteboard();
- [pb declareTypes:[NSArray array] owner:nil];
+ [pb declareTypes:@[] owner:nil];
}
void ClipboardMac::ReadAvailableTypes(ClipboardType type,
@@ -277,15 +278,15 @@ void ClipboardMac::ReadHTML(ClipboardType type,
src_url->clear();
NSPasteboard* pb = GetPasteboard();
- NSArray* supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType,
- NSRTFPboardType,
- NSPasteboardTypeString,
- nil];
+ NSArray* supportedTypes =
+ @[ NSHTMLPboardType, NSRTFPboardType, NSPasteboardTypeString ];
NSString* bestType = [pb availableTypeFromArray:supportedTypes];
if (bestType) {
- NSString* contents = [pb stringForType:bestType];
+ NSString* contents;
if ([bestType isEqualToString:NSRTFPboardType])
- contents = [pb htmlFromRtf];
+ contents = ClipboardUtil::GetHTMLFromRTFOnPasteboard(pb);
+ else
+ contents = [pb stringForType:bestType];
*markup = base::SysNSStringToUTF16(contents);
}
@@ -337,7 +338,7 @@ SkBitmap ClipboardMac::ReadImage(ClipboardType type, NSPasteboard* pb) const {
// the way through to the web, but the clipboard API doesn't support the
// additional metainformation.
if ([[image representations] count] == 1u) {
- NSImageRep* rep = [[image representations] objectAtIndex:0];
+ NSImageRep* rep = [image representations][0];
NSInteger width = [rep pixelsWide];
NSInteger height = [rep pixelsHigh];
if (width != 0 && height != 0) {
@@ -400,7 +401,7 @@ void ClipboardMac::WriteObjects(ClipboardType type, const ObjectMap& objects) {
DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE);
NSPasteboard* pb = GetPasteboard();
- [pb declareTypes:[NSArray array] owner:nil];
+ [pb declareTypes:@[] owner:nil];
for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end();
++iter) {
@@ -412,7 +413,7 @@ void ClipboardMac::WriteText(const char* text_data, size_t text_len) {
std::string text_str(text_data, text_len);
NSString* text = base::SysUTF8ToNSString(text_str);
NSPasteboard* pb = GetPasteboard();
- [pb addTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
+ [pb addTypes:@[ NSPasteboardTypeString ] owner:nil];
[pb setString:text forType:NSPasteboardTypeString];
}
@@ -427,7 +428,7 @@ void ClipboardMac::WriteHTML(const char* markup_data,
// TODO(avi): url_data?
NSPasteboard* pb = GetPasteboard();
- [pb addTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil];
+ [pb addTypes:@[ NSHTMLPboardType ] owner:nil];
[pb setString:html_fragment forType:NSHTMLPboardType];
}
@@ -451,12 +452,22 @@ void ClipboardMac::WriteBookmark(const char* title_data,
}
void ClipboardMac::WriteBitmap(const SkBitmap& bitmap) {
+ SkBitmap out_bitmap;
+ if (!skia::SkBitmapToN32OpaqueOrPremul(bitmap, &out_bitmap)) {
+ NOTREACHED() << "Unable to convert bitmap for clipboard";
+ return;
+ }
+
NSImage* image = skia::SkBitmapToNSImageWithColorSpace(
- bitmap, base::mac::GetSystemColorSpace());
+ out_bitmap, base::mac::GetSystemColorSpace());
+ if (!image) {
+ NOTREACHED() << "SkBitmapToNSImageWithColorSpace failed";
+ return;
+ }
// An API to ask the NSImage to write itself to the clipboard comes in 10.6 :(
// For now, spit out the image as a TIFF.
NSPasteboard* pb = GetPasteboard();
- [pb addTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil];
+ [pb addTypes:@[ NSTIFFPboardType ] owner:nil];
NSData* tiff_data = [image TIFFRepresentation];
LOG_IF(ERROR, tiff_data == NULL) << "Failed to allocate image for clipboard";
if (tiff_data) {
@@ -468,7 +479,7 @@ void ClipboardMac::WriteData(const FormatType& format,
const char* data_data,
size_t data_len) {
NSPasteboard* pb = GetPasteboard();
- [pb addTypes:[NSArray arrayWithObject:format.ToNSString()] owner:nil];
+ [pb addTypes:@[ format.ToNSString() ] owner:nil];
[pb setData:[NSData dataWithBytes:data_data length:data_len]
forType:format.ToNSString()];
}
@@ -478,7 +489,7 @@ void ClipboardMac::WriteData(const FormatType& format,
void ClipboardMac::WriteWebSmartPaste() {
NSPasteboard* pb = GetPasteboard();
NSString* format = GetWebKitSmartPasteFormatType().ToNSString();
- [pb addTypes:[NSArray arrayWithObject:format] owner:nil];
+ [pb addTypes:@[ format ] owner:nil];
[pb setData:nil forType:format];
}
diff --git a/chromium/ui/base/clipboard/clipboard_test_template.h b/chromium/ui/base/clipboard/clipboard_test_template.h
index 65270477f08..fd0dcc60cf9 100644
--- a/chromium/ui/base/clipboard/clipboard_test_template.h
+++ b/chromium/ui/base/clipboard/clipboard_test_template.h
@@ -12,6 +12,9 @@
// TODO(dcheng): This is really horrible. In general, all tests should run on
// all platforms, to avoid this mess.
+#ifndef UI_BASE_CLIPBOARD_CLIPBOARD_TEST_TEMPLATE_H_
+#define UI_BASE_CLIPBOARD_CLIPBOARD_TEST_TEMPLATE_H_
+
#include <stdint.h>
#include <memory>
@@ -34,6 +37,7 @@
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/test/test_clipboard.h"
#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/half_float.h"
#if defined(OS_WIN)
#include "ui/base/clipboard/clipboard_util_win.h"
@@ -376,14 +380,20 @@ TYPED_TEST(ClipboardTest, URLTest) {
#endif
}
+namespace {
+
+using U8x4 = std::array<uint8_t, 4>;
+using F16x4 = std::array<gfx::HalfFloat, 4>;
+
+template <typename T>
static void TestBitmapWrite(Clipboard* clipboard,
- const gfx::Size& size,
- const uint32_t* bitmap_data) {
+ const SkImageInfo& info,
+ const T* bitmap_data,
+ const U8x4* expect_data) {
{
ScopedClipboardWriter scw(CLIPBOARD_TYPE_COPY_PASTE);
SkBitmap bitmap;
- ASSERT_TRUE(bitmap.setInfo(
- SkImageInfo::MakeN32Premul(size.width(), size.height())));
+ ASSERT_TRUE(bitmap.setInfo(info));
bitmap.setPixels(
const_cast<void*>(reinterpret_cast<const void*>(bitmap_data)));
scw.WriteImage(bitmap);
@@ -392,43 +402,120 @@ static void TestBitmapWrite(Clipboard* clipboard,
EXPECT_TRUE(clipboard->IsFormatAvailable(Clipboard::GetBitmapFormatType(),
CLIPBOARD_TYPE_COPY_PASTE));
const SkBitmap& image = clipboard->ReadImage(CLIPBOARD_TYPE_COPY_PASTE);
- EXPECT_EQ(size, gfx::Size(image.width(), image.height()));
- for (int j = 0; j < image.height(); ++j) {
- const uint32_t* row_address = image.getAddr32(0, j);
- for (int i = 0; i < image.width(); ++i) {
- int offset = i + j * image.width();
- EXPECT_EQ(bitmap_data[offset], row_address[i]) << "i = " << i
- << ", j = " << j;
+ ASSERT_EQ(image.info().colorType(), kN32_SkColorType);
+ ASSERT_NE(image.info().alphaType(), kUnpremul_SkAlphaType);
+ EXPECT_EQ(gfx::Size(info.width(), info.height()),
+ gfx::Size(image.width(), image.height()));
+ for (int y = 0; y < image.height(); ++y) {
+ const U8x4* actual_row =
+ reinterpret_cast<const U8x4*>(image.getAddr32(0, y));
+ const U8x4* expect_row = &expect_data[y * info.width()];
+ for (int x = 0; x < image.width(); ++x) {
+ EXPECT_EQ(expect_row[x], actual_row[x]) << "x = " << x << ", y = " << y;
}
}
}
-TYPED_TEST(ClipboardTest, SharedBitmapTest) {
- const uint32_t fake_bitmap_1[] = {
- 0x46061626, 0xf69f5988, 0x793f2937, 0xfa55b986,
- 0x78772152, 0x87692a30, 0x36322a25, 0x4320401b,
- 0x91848c21, 0xc3177b3c, 0x6946155c, 0x64171952,
- };
- {
- SCOPED_TRACE("first bitmap");
- TestBitmapWrite(&this->clipboard(), gfx::Size(4, 3), fake_bitmap_1);
- }
+constexpr U8x4 kRGBAUnpremul = {0x8a, 0x50, 0x15, 0x46};
+constexpr U8x4 kRGBAPremul = {0x26, 0x16, 0x06, 0x46};
+constexpr U8x4 kRGBAOpaque = {0x26, 0x16, 0x06, 0xff};
+constexpr U8x4 kBGRAUnpremul = {0x15, 0x50, 0x8a, 0x46};
+constexpr U8x4 kBGRAPremul = {0x06, 0x16, 0x26, 0x46};
+constexpr U8x4 kBGRAOpaque = {0x06, 0x16, 0x26, 0xff};
+constexpr F16x4 kRGBAF16Unpremul = {0x3854, 0x3505, 0x2d45, 0x3464};
+constexpr F16x4 kRGBAF16Premul = {0x30c5, 0x2d86, 0x2606, 0x3464};
+constexpr F16x4 kRGBAF16Opaque = {0x30c5, 0x2d86, 0x2606, 0x3c00};
+
+constexpr U8x4 kN32 =
+ (kN32_SkColorType == kRGBA_8888_SkColorType) ? kRGBAPremul : kBGRAPremul;
+constexpr U8x4 kN32Opaque =
+ (kN32_SkColorType == kRGBA_8888_SkColorType) ? kRGBAOpaque : kBGRAOpaque;
+
+// Either RGBA_8888 or BGRA_8888 will be equivalent to N32, but the other
+// won't be.
+TYPED_TEST(ClipboardTest, Bitmap_RGBA_Premul) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType),
+ &kRGBAPremul, &kN32);
+}
+TYPED_TEST(ClipboardTest, Bitmap_RGBA_Unpremul) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType),
+ &kRGBAUnpremul, &kN32);
+}
+TYPED_TEST(ClipboardTest, Bitmap_RGBA_Opaque) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType),
+ &kRGBAOpaque, &kN32Opaque);
+}
+TYPED_TEST(ClipboardTest, Bitmap_BGRA_Premul) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kPremul_SkAlphaType),
+ &kBGRAPremul, &kN32);
+}
+TYPED_TEST(ClipboardTest, Bitmap_BGRA_Unpremul) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kUnpremul_SkAlphaType),
+ &kBGRAUnpremul, &kN32);
+}
+TYPED_TEST(ClipboardTest, Bitmap_BGRA_Opaque) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kBGRA_8888_SkColorType, kOpaque_SkAlphaType),
+ &kBGRAOpaque, &kN32Opaque);
+}
+
+// Used by HTMLCanvasElement.
+TYPED_TEST(ClipboardTest, Bitmap_F16_Premul) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType),
+ &kRGBAF16Premul, &kN32);
+}
+TYPED_TEST(ClipboardTest, Bitmap_F16_Unpremul) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kRGBA_F16_SkColorType, kUnpremul_SkAlphaType),
+ &kRGBAF16Unpremul, &kN32);
+}
+TYPED_TEST(ClipboardTest, Bitmap_F16_Opaque) {
+ TestBitmapWrite(
+ &this->clipboard(),
+ SkImageInfo::Make(1, 1, kRGBA_F16_SkColorType, kOpaque_SkAlphaType),
+ &kRGBAF16Opaque, &kN32Opaque);
+}
- const uint32_t fake_bitmap_2[] = {
- 0x46061626, 0xf69f5988,
- 0x793f2937, 0xfa55b986,
- 0x78772152, 0x87692a30,
- 0x36322a25, 0x4320401b,
- 0x91848c21, 0xc3177b3c,
- 0x6946155c, 0x64171952,
- 0xa6910313, 0x8302323e,
+TYPED_TEST(ClipboardTest, Bitmap_N32_Premul) {
+ constexpr U8x4 b[4 * 3] = {
+ {0x26, 0x16, 0x06, 0x46}, {0x88, 0x59, 0x9f, 0xf6},
+ {0x37, 0x29, 0x3f, 0x79}, {0x86, 0xb9, 0x55, 0xfa},
+ {0x52, 0x21, 0x77, 0x78}, {0x30, 0x2a, 0x69, 0x87},
+ {0x25, 0x2a, 0x32, 0x36}, {0x1b, 0x40, 0x20, 0x43},
+ {0x21, 0x8c, 0x84, 0x91}, {0x3c, 0x7b, 0x17, 0xc3},
+ {0x5c, 0x15, 0x46, 0x69}, {0x52, 0x19, 0x17, 0x64},
};
- {
- SCOPED_TRACE("second bitmap");
- TestBitmapWrite(&this->clipboard(), gfx::Size(2, 7), fake_bitmap_2);
- }
+ TestBitmapWrite(&this->clipboard(), SkImageInfo::MakeN32Premul(4, 3), b, b);
+}
+TYPED_TEST(ClipboardTest, Bitmap_N32_Premul_2x7) {
+ constexpr U8x4 b[2 * 7] = {
+ {0x26, 0x16, 0x06, 0x46}, {0x88, 0x59, 0x9f, 0xf6},
+ {0x37, 0x29, 0x3f, 0x79}, {0x86, 0xb9, 0x55, 0xfa},
+ {0x52, 0x21, 0x77, 0x78}, {0x30, 0x2a, 0x69, 0x87},
+ {0x25, 0x2a, 0x32, 0x36}, {0x1b, 0x40, 0x20, 0x43},
+ {0x21, 0x8c, 0x84, 0x91}, {0x3c, 0x7b, 0x17, 0xc3},
+ {0x5c, 0x15, 0x46, 0x69}, {0x52, 0x19, 0x17, 0x64},
+ {0x13, 0x03, 0x91, 0xa6}, {0x3e, 0x32, 0x02, 0x83},
+ };
+ TestBitmapWrite(&this->clipboard(), SkImageInfo::MakeN32Premul(2, 7), b, b);
}
+} // namespace
+
TYPED_TEST(ClipboardTest, DataTest) {
const ui::Clipboard::FormatType kFormat =
ui::Clipboard::GetFormatType("chromium/x-test-format");
@@ -674,3 +761,5 @@ TYPED_TEST(ClipboardTest, WriteImageEmptyParams) {
}
} // namespace ui
+
+#endif // UI_BASE_CLIPBOARD_CLIPBOARD_TEST_TEMPLATE_H_ \ No newline at end of file
diff --git a/chromium/ui/base/clipboard/clipboard_util_mac.h b/chromium/ui/base/clipboard/clipboard_util_mac.h
index 31c459b1b08..29f927c3f31 100644
--- a/chromium/ui/base/clipboard/clipboard_util_mac.h
+++ b/chromium/ui/base/clipboard/clipboard_util_mac.h
@@ -63,16 +63,21 @@ class UI_BASE_EXPORT ClipboardUtil {
// and its associated data.
static void AddDataToPasteboard(NSPasteboard* pboard, NSPasteboardItem* item);
- // Returns whether the operation was succesful. On success, the two arrays are
- // guaranteed to be equal length, and are populated with strings of |urls| and
- // |titles|.
+ // Returns whether the operation was successful. On success, the two arrays
+ // are guaranteed to be equal length, and are populated with strings of |urls|
+ // and |titles|.
static bool URLsAndTitlesFromPasteboard(NSPasteboard* pboard,
NSArray** urls,
NSArray** titles);
// Gets the NSPasteboard specified from the clipboard type.
static NSPasteboard* PasteboardFromType(ui::ClipboardType type);
+
+ // If there is RTF data on the pasteboard, returns an HTML version of it.
+ // Otherwise returns nil.
+ static NSString* GetHTMLFromRTFOnPasteboard(NSPasteboard* pboard);
};
-}
+
+} // namespace ui
#endif // UI_BASE_CLIPBOARD_CLIPBOARD_UTIL_MAC_H_
diff --git a/chromium/ui/base/clipboard/clipboard_util_mac.mm b/chromium/ui/base/clipboard/clipboard_util_mac.mm
index b7bf6229dda..3611b997d66 100644
--- a/chromium/ui/base/clipboard/clipboard_util_mac.mm
+++ b/chromium/ui/base/clipboard/clipboard_util_mac.mm
@@ -150,10 +150,8 @@ bool ClipboardUtil::URLsAndTitlesFromPasteboard(NSPasteboard* pboard,
if ([bookmarkPairs count] != 2)
return false;
- NSArray* urlsArr =
- base::mac::ObjCCast<NSArray>([bookmarkPairs objectAtIndex:0]);
- NSArray* titlesArr =
- base::mac::ObjCCast<NSArray>([bookmarkPairs objectAtIndex:1]);
+ NSArray* urlsArr = base::mac::ObjCCast<NSArray>(bookmarkPairs[0]);
+ NSArray* titlesArr = base::mac::ObjCCast<NSArray>(bookmarkPairs[1]);
if (!urlsArr || !titlesArr)
return false;
@@ -195,4 +193,25 @@ NSPasteboard* ClipboardUtil::PasteboardFromType(ui::ClipboardType type) {
return [NSPasteboard pasteboardWithName:type_string];
}
+// static
+NSString* ClipboardUtil::GetHTMLFromRTFOnPasteboard(NSPasteboard* pboard) {
+ NSData* rtfData = [pboard dataForType:NSRTFPboardType];
+ if (!rtfData)
+ return nil;
+
+ NSAttributedString* attributed =
+ [[[NSAttributedString alloc] initWithRTF:rtfData
+ documentAttributes:nil] autorelease];
+ NSData* htmlData =
+ [attributed dataFromRange:NSMakeRange(0, [attributed length])
+ documentAttributes:@{
+ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType
+ }
+ error:nil];
+
+ // According to the docs, NSHTMLTextDocumentType is UTF8.
+ return [[[NSString alloc] initWithData:htmlData
+ encoding:NSUTF8StringEncoding] autorelease];
+}
+
} // namespace ui
diff --git a/chromium/ui/base/clipboard/clipboard_util_mac_unittest.mm b/chromium/ui/base/clipboard/clipboard_util_mac_unittest.mm
index 9981d3c0e2f..a03f88e1eb7 100644
--- a/chromium/ui/base/clipboard/clipboard_util_mac_unittest.mm
+++ b/chromium/ui/base/clipboard/clipboard_util_mac_unittest.mm
@@ -21,7 +21,7 @@ class ClipboardUtilMacTest : public PlatformTest {
NSArray* types = [pboard types];
NSMutableDictionary* data = [NSMutableDictionary dictionary];
for (NSString* type in types) {
- [data setObject:[pboard dataForType:type] forKey:type];
+ data[type] = [pboard dataForType:type];
}
return data;
}
@@ -46,9 +46,9 @@ TEST_F(ClipboardUtilMacTest, PasteboardItemFromUrl) {
convertingTextToURL:NO];
ASSERT_EQ(1u, [urls count]);
- EXPECT_NSEQ(urlString, [urls objectAtIndex:0]);
+ EXPECT_NSEQ(urlString, urls[0]);
ASSERT_EQ(1u, [titles count]);
- EXPECT_NSEQ(urlString, [titles objectAtIndex:0]);
+ EXPECT_NSEQ(urlString, titles[0]);
NSURL* url = [NSURL URLFromPasteboard:pasteboard->get()];
EXPECT_NSEQ([url absoluteString], urlString);
@@ -71,9 +71,9 @@ TEST_F(ClipboardUtilMacTest, PasteboardItemWithTitle) {
convertingTextToURL:NO];
ASSERT_EQ(1u, [urls count]);
- EXPECT_NSEQ(urlString, [urls objectAtIndex:0]);
+ EXPECT_NSEQ(urlString, urls[0]);
ASSERT_EQ(1u, [titles count]);
- EXPECT_NSEQ(title, [titles objectAtIndex:0]);
+ EXPECT_NSEQ(title, titles[0]);
NSURL* url = [NSURL URLFromPasteboard:pasteboard->get()];
EXPECT_NSEQ([url absoluteString], urlString);
@@ -97,9 +97,9 @@ TEST_F(ClipboardUtilMacTest, PasteboardItemWithFilePath) {
convertingTextToURL:NO];
ASSERT_EQ(1u, [urls count]);
- EXPECT_NSEQ(urlString, [urls objectAtIndex:0]);
+ EXPECT_NSEQ(urlString, urls[0]);
ASSERT_EQ(1u, [titles count]);
- EXPECT_NSEQ(urlString, [titles objectAtIndex:0]);
+ EXPECT_NSEQ(urlString, titles[0]);
NSURL* urlFromPasteboard = [NSURL URLFromPasteboard:pasteboard->get()];
EXPECT_NSEQ(urlFromPasteboard, url);
diff --git a/chromium/ui/base/clipboard/clipboard_win.cc b/chromium/ui/base/clipboard/clipboard_win.cc
index e49dd8c8127..1857bfa07ce 100644
--- a/chromium/ui/base/clipboard/clipboard_win.cc
+++ b/chromium/ui/base/clipboard/clipboard_win.cc
@@ -25,6 +25,7 @@
#include "base/win/message_window.h"
#include "base/win/scoped_gdi_object.h"
#include "base/win/scoped_hdc.h"
+#include "skia/ext/skia_utils_base.h"
#include "skia/ext/skia_utils_win.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/clipboard_util_win.h"
@@ -422,7 +423,7 @@ Clipboard* Clipboard::Create() {
// ClipboardWin implementation.
ClipboardWin::ClipboardWin() {
- if (base::MessageLoopForUI::IsCurrent())
+ if (base::MessageLoopCurrentForUI::IsSet())
clipboard_owner_.reset(new base::win::MessageWindow());
}
@@ -805,9 +806,16 @@ void ClipboardWin::WriteWebSmartPaste() {
NULL);
}
-void ClipboardWin::WriteBitmap(const SkBitmap& bitmap) {
+void ClipboardWin::WriteBitmap(const SkBitmap& in_bitmap) {
HDC dc = ::GetDC(NULL);
+ SkBitmap bitmap;
+ // Either points bitmap at in_bitmap, or allocates and converts pixels.
+ if (!skia::SkBitmapToN32OpaqueOrPremul(in_bitmap, &bitmap)) {
+ NOTREACHED() << "Unable to convert bitmap for clipboard";
+ return;
+ }
+
// This doesn't actually cost us a memcpy when the bitmap comes from the
// renderer as we load it into the bitmap using setPixels which just sets a
// pointer. Someone has to memcpy it into GDI, it might as well be us here.