Working on better support for Windows clipboard
This commit is contained in:
parent
340e694bdc
commit
afaf43823c
5 changed files with 90 additions and 4 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "deps/datachannel-wasm"]
|
||||
path = deps/datachannel-wasm
|
||||
url = https://github.com/paullouisageneau/datachannel-wasm.git
|
||||
[submodule "deps/clip"]
|
||||
path = deps/clip
|
||||
url = https://github.com/dacap/clip.git
|
||||
|
|
|
|||
|
|
@ -314,6 +314,12 @@ target_link_libraries(infinipaint zstd::libzstd_static)
|
|||
|
||||
if((NOT EMSCRIPTEN) AND WIN32)
|
||||
target_link_libraries(infinipaint dwrite)
|
||||
# Clip library for retrieving images from windows clipboard
|
||||
set(CLIP_EXAMPLES OFF CACHE BOOL "Compile clip examples")
|
||||
set(CLIP_TESTS OFF CACHE BOOL "Compile clip tests")
|
||||
set(CLIP_ENABLE_IMAGE ON CACHE BOOL "Compile with image clipboard support")
|
||||
add_subdirectory(deps/clip)
|
||||
target_link_libraries(infinipaint clip)
|
||||
endif()
|
||||
|
||||
if(EMSCRIPTEN)
|
||||
|
|
|
|||
20
data/third_party_licenses/clip
Normal file
20
data/third_party_licenses/clip
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
Copyright (c) 2015-2025 David Capello
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
1
deps/clip
vendored
Submodule
1
deps/clip
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 4e878e1392dc379a55e5b63de2c822e8f2b6aa98
|
||||
|
|
@ -5,6 +5,14 @@
|
|||
|
||||
#include <optional>
|
||||
|
||||
#include <Helpers/Logger.hpp>
|
||||
|
||||
#ifdef _WIN32_
|
||||
#include <include/core/SkStream.h>
|
||||
#include <include/encode/SkPngEncoder.h>
|
||||
#include "../deps/clip/clip.h"
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <EmscriptenHelpers/emscripten_browser_clipboard.h>
|
||||
|
||||
|
|
@ -148,17 +156,65 @@ void InputManager::get_clipboard_image_data_SDL(const std::function<void(std::st
|
|||
validMimetypes.emplace("image/jpeg");
|
||||
validMimetypes.emplace("image/svg+xml");
|
||||
validMimetypes.emplace("image/webp");
|
||||
#ifdef _WIN32
|
||||
validMimetypes.emplace("image/bmp");
|
||||
#endif
|
||||
}
|
||||
size_t mimeTypeSize;
|
||||
char** mimeTypes = SDL_GetClipboardMimeTypes(&mimeTypeSize);
|
||||
if(mimeTypes) {
|
||||
for(size_t i = 0; i < mimeTypeSize; i++) {
|
||||
if(validMimetypes.contains(mimeTypes[i])) {
|
||||
size_t clipboardDataSize;
|
||||
void* clipboardData = SDL_GetClipboardData(mimeTypes[i], &clipboardDataSize);
|
||||
callback(std::string_view(static_cast<char*>(clipboardData), clipboardDataSize));
|
||||
SDL_free(clipboardData);
|
||||
if(std::string(mimeTypes[i]) == "image/bmp") {
|
||||
#ifdef _WIN32_
|
||||
if(!clip::has(clip::image_format())) {
|
||||
Logger::get().log("INFO", "[InputManager::get_clipboard_image_data_SDL] Clipboard doesn't contain an image");
|
||||
return;
|
||||
}
|
||||
|
||||
clip::image img;
|
||||
if(!clip::get_image(img)) {
|
||||
Logger::get().log("INFO", "[InputManager::get_clipboard_image_data_SDL] Error getting image from clipboard");
|
||||
return;
|
||||
}
|
||||
|
||||
clip::image_spec spec = img.spec();
|
||||
|
||||
if(spec.bits_per_pixel != 8) {
|
||||
Logger::get().log("INFO", "[InputManager::get_clipboard_image_data_SDL] Clipboard doesn't use 8 bits per pixel");
|
||||
return;
|
||||
}
|
||||
|
||||
char* rawImageData = img.data();
|
||||
std::vector<uint8_t> rgbaImageData(spec.width * spec.height * 4);
|
||||
for(size_t y = 0; y < spec.height; y++) {
|
||||
for(size_t x = 0; x < spec.width; x++) {
|
||||
size_t rawDataIndex = x + y * spec.bytes_per_row;
|
||||
size_t rgbaDataIndex = x + y * spec.height;
|
||||
unsigned long rawDataAtIndex = *reinterpret_cast<unsigned long*>(rawImageData + rawDataIndex);
|
||||
rgbaImageData[rgbaDataIndex + 0] = (rawDataAtIndex & spec.red_mask) >> spec.red_shift;
|
||||
rgbaImageData[rgbaDataIndex + 1] = (rawDataAtIndex & spec.green_mask) >> spec.green_shift;
|
||||
rgbaImageData[rgbaDataIndex + 2] = (rawDataAtIndex & spec.blue_mask) >> spec.blue_mask;
|
||||
if(spec.alpha_mask == 0)
|
||||
rgbaImageData[rgbaDataIndex + 3] = 255;
|
||||
else
|
||||
rgbaImageData[rgbaDataIndex + 3] = (rawDataAtIndex & spec.alpha_mask) >> spec.alpha_mask;
|
||||
}
|
||||
}
|
||||
|
||||
SkDynamicMemoryWStream out;
|
||||
SkPngEncoder::Encode(&out, SkPixmap(SkImageInfo::Make(spec.width, spec.height, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType), rgbaImageData.data(), rgbaImageData.size()), {});
|
||||
out.flush();
|
||||
std::vector<uint8_t> result = out.detachAsVector();
|
||||
callback(std::string_view(reinterpret_cast<char*>(result.data()), result.size()));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
size_t clipboardDataSize;
|
||||
void* clipboardData = SDL_GetClipboardData(mimeTypes[i], &clipboardDataSize);
|
||||
callback(std::string_view(static_cast<char*>(clipboardData), clipboardDataSize));
|
||||
SDL_free(clipboardData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue