mirror of
https://github.com/hyprwm/hyprlock.git
synced 2024-11-16 23:05:58 +01:00
asyncResourceGatherer: deduplicate image rendering code (#433)
* asyncResourceGatherer: deduplicate image rendering code Also happens to add support for JPEG and WEBP for image widgets * asyncResourceGatherer: use a reference for path in getFileType
This commit is contained in:
parent
20c01d91d4
commit
3d3b52e42c
1 changed files with 59 additions and 61 deletions
|
@ -91,6 +91,51 @@ enum class FileType {
|
|||
UNKNOWN,
|
||||
};
|
||||
|
||||
FileType getFileType(const std::filesystem::path& path) {
|
||||
std::string ext = path.extension().string();
|
||||
// convert the extension to lower case
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), [](char c) { return c <= 'Z' && c >= 'A' ? c - ('Z' - 'z') : c; });
|
||||
|
||||
FileType ft = FileType::UNKNOWN;
|
||||
Debug::log(TRACE, "Extension: {}", ext);
|
||||
if (ext == ".png")
|
||||
ft = FileType::PNG;
|
||||
else if (ext == ".jpg" || ext == ".jpeg")
|
||||
ft = FileType::JPEG;
|
||||
else if (ext == ".webp")
|
||||
ft = FileType::WEBP;
|
||||
else {
|
||||
// magic is slow, so only use it when no recognized extension is found
|
||||
auto handle = magic_open(MAGIC_NONE | MAGIC_COMPRESS);
|
||||
magic_load(handle, nullptr);
|
||||
|
||||
const auto type_str = std::string(magic_file(handle, path.c_str()));
|
||||
const auto first_word = type_str.substr(0, type_str.find(" "));
|
||||
magic_close(handle);
|
||||
|
||||
if (first_word == "PNG")
|
||||
ft = FileType::PNG;
|
||||
else if (first_word == "JPEG")
|
||||
ft = FileType::JPEG;
|
||||
else if (first_word == "RIFF" && type_str.find("Web/P image") != std::string::npos)
|
||||
ft = FileType::WEBP;
|
||||
}
|
||||
|
||||
return ft;
|
||||
}
|
||||
|
||||
cairo_surface_t* getCairoSurfaceFromImageFile(const std::filesystem::path& path) {
|
||||
cairo_surface_t* cairoSurface = nullptr;
|
||||
switch (getFileType(path)) {
|
||||
case FileType::PNG: cairoSurface = cairo_image_surface_create_from_png(path.c_str()); break;
|
||||
case FileType::JPEG: cairoSurface = JPEG::createSurfaceFromJPEG(path); break;
|
||||
case FileType::WEBP: cairoSurface = WEBP::createSurfaceFromWEBP(path); break;
|
||||
default: Debug::log(ERR, "unrecognized image format of {}", path.c_str());
|
||||
}
|
||||
|
||||
return cairoSurface;
|
||||
}
|
||||
|
||||
void CAsyncResourceGatherer::gather() {
|
||||
const auto CWIDGETS = g_pConfigManager->getWidgetConfigs();
|
||||
|
||||
|
@ -117,67 +162,15 @@ void CAsyncResourceGatherer::gather() {
|
|||
if (path.empty() || path == "screenshot")
|
||||
continue;
|
||||
|
||||
std::string id = (c.type == "background" ? std::string{"background:"} : std::string{"image:"}) + path;
|
||||
std::filesystem::path ABSOLUTEPATH(absolutePath(path, ""));
|
||||
std::string id = (c.type == "background" ? std::string{"background:"} : std::string{"image:"}) + path;
|
||||
|
||||
// determine the file type
|
||||
std::string ext = ABSOLUTEPATH.extension().string();
|
||||
// convert the extension to lower case
|
||||
std::transform(ext.begin(), ext.end(), ext.begin(), [](char c) { return c <= 'Z' && c >= 'A' ? c - ('Z' - 'z') : c; });
|
||||
// render the image directly, since we are in a seperate thread
|
||||
CAsyncResourceGatherer::SPreloadRequest rq;
|
||||
rq.type = CAsyncResourceGatherer::TARGET_IMAGE;
|
||||
rq.asset = path;
|
||||
rq.id = id;
|
||||
|
||||
FileType ft = FileType::UNKNOWN;
|
||||
Debug::log(WARN, "Extension: {}", ext);
|
||||
if (ext == ".png")
|
||||
ft = FileType::PNG;
|
||||
else if (ext == ".jpg" || ext == ".jpeg")
|
||||
ft = FileType::JPEG;
|
||||
else if (ext == ".webp")
|
||||
ft = FileType::WEBP;
|
||||
else {
|
||||
// magic is slow, so only use it when no recognized extension is found
|
||||
auto handle = magic_open(MAGIC_NONE | MAGIC_COMPRESS);
|
||||
magic_load(handle, nullptr);
|
||||
|
||||
const auto type_str = std::string(magic_file(handle, ABSOLUTEPATH.c_str()));
|
||||
const auto first_word = type_str.substr(0, type_str.find(" "));
|
||||
magic_close(handle);
|
||||
|
||||
if (first_word == "PNG")
|
||||
ft = FileType::PNG;
|
||||
else if (first_word == "JPEG")
|
||||
ft = FileType::JPEG;
|
||||
else if (first_word == "RIFF" && type_str.find("Web/P image") != std::string::npos)
|
||||
ft = FileType::WEBP;
|
||||
}
|
||||
|
||||
// preload bg img
|
||||
cairo_surface_t* CAIROISURFACE = nullptr;
|
||||
switch (ft) {
|
||||
case FileType::PNG: CAIROISURFACE = cairo_image_surface_create_from_png(ABSOLUTEPATH.c_str()); break;
|
||||
case FileType::JPEG: CAIROISURFACE = JPEG::createSurfaceFromJPEG(ABSOLUTEPATH); break;
|
||||
case FileType::WEBP: CAIROISURFACE = WEBP::createSurfaceFromWEBP(ABSOLUTEPATH); break;
|
||||
default: Debug::log(ERR, "unrecognized image format of {}", path.c_str()); continue;
|
||||
}
|
||||
|
||||
if (CAIROISURFACE == nullptr)
|
||||
continue;
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROISURFACE);
|
||||
cairo_scale(CAIRO, 1, 1);
|
||||
|
||||
{
|
||||
std::lock_guard lg{preloadTargetsMutex};
|
||||
const auto TARGET = &preloadTargets.emplace_back(CAsyncResourceGatherer::SPreloadTarget{});
|
||||
|
||||
TARGET->size = {cairo_image_surface_get_width(CAIROISURFACE), cairo_image_surface_get_height(CAIROISURFACE)};
|
||||
TARGET->type = TARGET_IMAGE;
|
||||
TARGET->id = id;
|
||||
|
||||
const auto DATA = cairo_image_surface_get_data(CAIROISURFACE);
|
||||
TARGET->cairo = CAIRO;
|
||||
TARGET->cairosurface = CAIROISURFACE;
|
||||
TARGET->data = DATA;
|
||||
}
|
||||
renderImage(rq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,8 +236,13 @@ void CAsyncResourceGatherer::renderImage(const SPreloadRequest& rq) {
|
|||
target.type = TARGET_IMAGE;
|
||||
target.id = rq.id;
|
||||
|
||||
const auto ABSOLUTEPATH = absolutePath(rq.asset, "");
|
||||
const auto CAIROISURFACE = cairo_image_surface_create_from_png(ABSOLUTEPATH.c_str());
|
||||
std::filesystem::path ABSOLUTEPATH(absolutePath(rq.asset, ""));
|
||||
const auto CAIROISURFACE = getCairoSurfaceFromImageFile(ABSOLUTEPATH);
|
||||
|
||||
if (!CAIROISURFACE) {
|
||||
Debug::log(ERR, "No cairo surface!");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto CAIRO = cairo_create(CAIROISURFACE);
|
||||
cairo_scale(CAIRO, 1, 1);
|
||||
|
|
Loading…
Reference in a new issue