diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-02-13 15:05:36 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-02-14 10:33:47 +0000 |
commit | e684a3455bcc29a6e3e66a004e352dea4e1141e7 (patch) | |
tree | d55b4003bde34d7d05f558f02cfd82b2a66a7aac /chromium/ui/base/clipboard | |
parent | 2b94bfe47ccb6c08047959d1c26e392919550e86 (diff) | |
download | qtwebengine-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.cc | 18 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard.h | 4 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_android.cc | 6 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_aura.cc | 85 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_aura.h | 5 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_aurax11.cc | 33 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_mac.mm | 41 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_test_template.h | 155 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_util_mac.h | 13 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_util_mac.mm | 27 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_util_mac_unittest.mm | 14 | ||||
-rw-r--r-- | chromium/ui/base/clipboard/clipboard_win.cc | 12 |
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. |