Files
OmaPhoto/tests/ProjectFixtures.h
雷电芽衣andClaude c864304695
Release / deb (push) Canceled after 0s
Release / rpm (push) Canceled after 0s
Release / arch (push) Canceled after 0s
Release / publish (push) Canceled after 0s
OmaPhoto 1.0.0: the Linux port of Compositor
A layered image editor for Linux and Omarchy, ported from Compositor
(github.com/robbietilton/Compositor), whose Swift source is its
specification. It reads and writes Compositor's .comp projects.

Packages for Ubuntu, Fedora and Arch come from the release workflow;
scripts/install/ holds one install script per distribution family,
and flake.nix serves NixOS.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-09-26 00:44:52 -04:00

64 lines
2.3 KiB
C++

#pragma once
#include "IO/ProjectStore.h"
#include "RenderFixtures.h"
#include <QDir>
#include <QFile>
// A 64x32 image: red on the left, clear right.
inline QImage halfRed()
{
QImage image = BrushRaster::context(64, 32, false);
for (int y = 0; y < 32; ++y) {
for (int x = 0; x < 32; ++x)
image.setPixel(x, y, qRgba(255, 0, 0, 255));
}
return image;
}
inline ImportedImage asset(const QImage &image, const QString &name)
{
return ImportedImage(image, image, name);
}
// A hidden, turned, flipped image layer under a blank one.
inline ProjectSnapshot twoLayers()
{
const QUuid imageID = QUuid::createUuid(), blankID = QUuid::createUuid();
const LayerTransform turned{.origin = {-27.5, 88.25}, .size = {123, 47}, .rotation = 38, .flipX = true, .flipY = true,
.sampling = LayerSampling::nearest};
const ProjectLayerRecord image{.id = imageID, .name = QStringLiteral("Paint & sky \U0001F324"), .isVisible = false, .transform = turned,
.imageFile = uuidString(imageID) + ".png"};
const ProjectLayerRecord blank{.id = blankID, .name = "Layer 2", .isVisible = true,
.transform = {.origin = {0, 0}, .size = {100, 80}}, .imageFile = std::nullopt};
return {.manifest = {.resolution = 300, .documentID = QUuid::createUuid(), .width = 100, .height = 80, .activeLayerID = blankID,
.layers = {image, blank}},
.images = {{imageID, asset(halfRed(), "source")}}};
}
inline QByteArray contents(const QString &path)
{
QFile file(path);
if (!file.open(QIODevice::ReadOnly))
throw std::runtime_error("cannot read " + path.toStdString());
return file.readAll();
}
inline void overwrite(const QString &path, const QByteArray &data)
{
QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate) || file.write(data) != data.size())
throw std::runtime_error("cannot write " + path.toStdString());
}
// The kind of ProjectError `body` throws, if it throws one.
template <typename Body>
std::optional<ProjectError::Kind> projectError(Body body)
{
try {
body();
} catch (const ProjectError &error) {
return error.kind;
}
return std::nullopt;
}