Skip to content

Commit

Permalink
vaev-paint: Initial implementation for printing.
Browse files Browse the repository at this point in the history
  • Loading branch information
sleepy-monax committed Aug 1, 2024
1 parent 649712e commit 5a71566
Show file tree
Hide file tree
Showing 53 changed files with 622 additions and 467 deletions.
49 changes: 31 additions & 18 deletions src/clis/html2pdf/main.cpp
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
#include <karm-print/pdf.h>
#include <karm-sys/entry.h>
#include <karm-sys/file.h>
#include <karm-sys/time.h>
#include <vaev-driver/fetcher.h>
#include <vaev-driver/render.h>

namespace Vaev {

Style::Media constructMedia(Vec2Px pageSize) {
Style::Media constructMedia(Print::PaperStock paper) {
return {
.type = MediaType::SCREEN,
.width = Px{pageSize.width},
.height = Px{pageSize.height},
.aspectRatio = pageSize.width.toFloat<Number>() / pageSize.height.toFloat<Number>(),
.width = Px{paper.width},
.height = Px{paper.height},
.aspectRatio = paper.width / paper.height,
.orientation = Orientation::LANDSCAPE,

.resolution = Resolution::fromDpi(96),
.scan = Scan::PROGRESSIVE,
.grid = false,
.update = Update::FAST,
.update = Update::NONE,

.overflowBlock = OverflowBlock::SCROLL,
.overflowInline = OverflowInline::SCROLL,
.overflowBlock = OverflowBlock::PAGED,
.overflowInline = OverflowInline::NONE,

.color = 8,
.colorIndex = 0,
.monochrome = 0,
.colorGamut = ColorGamut::SRGB,
.pointer = Pointer::FINE,
.hover = Hover::HOVER,
.anyPointer = Pointer::FINE,
.anyHover = Hover::HOVER,
.pointer = Pointer::NONE,
.hover = Hover::NONE,
.anyPointer = Pointer::NONE,
.anyHover = Hover::NONE,

.prefersReducedMotion = ReducedMotion::REDUCE,
.prefersReducedTransparency = ReducedTransparency::NO_PREFERENCE,
.prefersContrast = Contrast::NO_PREFERENCE,
.prefersReducedTransparency = ReducedTransparency::REDUCE,
.prefersContrast = Contrast::MORE,
.forcedColors = Colors::NONE,
.prefersColorScheme = ColorScheme::LIGHT,
.prefersReducedData = ReducedData::NO_PREFERENCE,
Expand All @@ -49,18 +51,29 @@ Async::Task<> entryPointAsync(Sys::Context &ctx) {
}

auto input = co_try$(Mime::parseUrlOrPath(args[0]));
auto output = co_try$(Mime::parseUrlOrPath(args[1]));

auto dom = co_try$(Vaev::Driver::fetchDocument(input));

Vaev::Vec2Px viewport{Vaev::Px{800}, Vaev::Px{600}};
auto media = Vaev::constructMedia(viewport);
auto paper = Print::A4;
auto media = Vaev::constructMedia(paper);

auto start = Sys::now();
auto result = Vaev::Driver::render(*dom, media, viewport);
auto [layout, paint] = Vaev::Driver::render(*dom, media, paper);
auto elapsed = Sys::now() - start;
logDebug("render time: {}", elapsed);

logDebug("layout tree: {}", result.layout);
logDebug("paint tree: {}", result.paint);
logDebug("layout tree: {}", layout);
logDebug("paint tree: {}", paint);

Print::PdfPrinter printer;
paint->print(printer);

auto file = co_try$(Sys::File::create(output));
Io::TextEncoder<> encoder{file};
Io::Emit e{encoder};
printer.write(e);
co_try$(e.flush());

co_return Ok();
}
2 changes: 1 addition & 1 deletion src/impls/impl-efi/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"requires": [
"efi",
"abi",
"karm-net.json"
"karm-json"
],
"provides": [
"karm-logger-impl",
Expand Down
6 changes: 3 additions & 3 deletions src/impls/impl-efi/sys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <karm-base/align.h>
#include <karm-io/funcs.h>
#include <karm-io/impls.h>
#include <karm-json>
#include <karm-logger/logger.h>
#include <karm-net/json/json.h>
#include <karm-sys/file.h>

#include <karm-sys/_embed.h>
Expand Down Expand Up @@ -237,7 +237,7 @@ Res<Strong<Fd>> listenIpc(Mime::Url) {

// MARK: Files -----------------------------------------------------------------

static Opt<Net::Json::Value> _index = NONE;
static Opt<Json::Value> _index = NONE;

static Res<Mime::Path> resolve(Mime::Url url) {
if (url.scheme == "file") {
Expand All @@ -251,7 +251,7 @@ static Res<Mime::Path> resolve(Mime::Url url) {

auto indexFile = try$(File::open("file:/bundles/_index.json"_url));
auto indexStr = try$(Io::readAllUtf8(indexFile));
auto indexJson = try$(Net::Json::parse(indexStr));
auto indexJson = try$(Json::parse(indexStr));

_index = indexJson.get("objects");

Expand Down
2 changes: 1 addition & 1 deletion src/kernel/opstart/entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Async::Task<> entryPointAsync(Sys::Context &ctx) {

logInfo("parsing configs...");
auto fileStr = co_try$(Io::readAllUtf8(file));
auto json = co_try$(Net::Json::parse(fileStr));
auto json = co_try$(Json::parse(fileStr));

logInfo("validating configs...");
logInfo("configs: {}", json);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/opstart/loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Res<> loadEntry(Entry const &entry) {
auto blobFile = try$(Sys::File::open(blob.url));
auto blobMem = try$(Sys::mmap().map(blobFile));
auto blobRange = blobMem.prange();
auto propStr = try$(Net::Json::stringify(blob.props));
auto propStr = try$(Json::stringify(blob.props));

payload.add({
.tag = Handover::FILE,
Expand Down
14 changes: 7 additions & 7 deletions src/kernel/opstart/loader.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once

#include <karm-image/loader.h>
#include <karm-json>
#include <karm-logger/logger.h>
#include <karm-media/icon.h>
#include <karm-net/json/json.h>
#include <karm-sys/context.h>
#include <karm-sys/file.h>

Expand All @@ -13,9 +13,9 @@ Res<Sys::File> openUrl(Mime::Url const &url);

struct Blob {
Mime::Url url;
Net::Json::Value props;
Json::Value props;

static Res<Blob> fromJson(Net::Json::Value const &json) {
static Res<Blob> fromJson(Json::Value const &json) {
if (json.isStr())
return Ok(Blob{
.url = Mime::Url::parse(json.asStr()),
Expand All @@ -38,7 +38,7 @@ struct Entry {
Blob kernel;
Vec<Blob> blobs;

static Res<Entry> fromJson(Net::Json::Value const &json) {
static Res<Entry> fromJson(Json::Value const &json) {
if (not json.isObject())
return Error::invalidInput("expected object");

Expand All @@ -58,7 +58,7 @@ struct Entry {
auto kernelJson = json.get("kernel");
entry.kernel = try$(Blob::fromJson(kernelJson));

auto blobsJson = try$(json.get("blobs").take<Net::Json::Array>());
auto blobsJson = try$(json.get("blobs").take<Json::Array>());
for (auto const &blobJson : blobsJson) {
auto blob = try$(Blob::fromJson(blobJson));
entry.blobs.pushBack(blob);
Expand All @@ -73,7 +73,7 @@ struct Configs {
Opt<String> subtitle;
Vec<Entry> entries;

static Res<Configs> fromJson(Net::Json::Value const &json) {
static Res<Configs> fromJson(Json::Value const &json) {
if (not json.isObject()) {
return Error::invalidInput("expected array");
}
Expand All @@ -83,7 +83,7 @@ struct Configs {
configs.title = json.get("title").take<String>();
configs.subtitle = json.get("subtitle").take<String>();

auto entriesJson = try$(json.get("entries").take<Net::Json::Array>());
auto entriesJson = try$(json.get("entries").take<Json::Array>());
for (auto const &entryJson : entriesJson) {
auto entry = try$(Entry::fromJson(entryJson));
configs.entries.pushBack(entry);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/opstart/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
"hideo-base",
"karm-sys",
"opstart-impl",
"karm-net.json"
"karm-json"
]
}
6 changes: 6 additions & 0 deletions src/libs/karm-base/buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ struct Buf {
ensure(cap);
}

Buf(Move, T *buf, usize len)
: _buf(buf),
_cap(len),
_len(len) {
}

Buf(std::initializer_list<T> other) {
ensure(other.size());

Expand Down
2 changes: 1 addition & 1 deletion src/libs/karm-base/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ struct _StringBuilder {
return _buf;
}

Bytes bytes() {
Bytes bytes() const {
return ::bytes(_buf);
}

Expand Down
68 changes: 68 additions & 0 deletions src/libs/karm-gfx/canvas.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

#include <karm-meta/nocopy.h>

#include "paint.h"
#include "path.h"
#include "stroke.h"
#include "types.h"

namespace Karm::Gfx {

struct Canvas : public Meta::NoCopy {
// NOTE: Canvas is marked as NoCopy because it doesn't make sense to copy
// a context. And it's also a good way to prevent accidental copies.

Canvas() = default;
Canvas(Canvas &&) = default;
Canvas &operator=(Canvas &&) = default;

virtual ~Canvas() = default;

// Begin a new path.
virtual void begin() = 0;

// Close the current path. This will connect the last point to the first
virtual void close() = 0;

// Begin a new subpath at the given point.
virtual void moveTo(Math::Vec2f p, Path::Flags flags = Path::DEFAULT) = 0;

// Add a line segment to the current path.
virtual void lineTo(Math::Vec2f p, Path::Flags flags = Path::DEFAULT) = 0;

// Add a horizontal line segment to the current path.
virtual void hlineTo(f64 x, Path::Flags flags = Path::DEFAULT) = 0;

// Add a vertical line segment to the current path.
virtual void vlineTo(f64 y, Path::Flags flags = Path::DEFAULT) = 0;

// Add a cubic Bezier curve to the current path.
virtual void cubicTo(Math::Vec2f cp1, Math::Vec2f cp2, Math::Vec2f p, Path::Flags flags = Path::DEFAULT) = 0;

// Add a quadratic Bezier curve to the current path.
virtual void quadTo(Math::Vec2f cp, Math::Vec2f p, Path::Flags flags = Path::DEFAULT) = 0;

// Add an elliptical arc to the current path.
virtual void arcTo(Math::Vec2f radius, f64 angle, Math::Vec2f p, Path::Flags flags = Path::DEFAULT) = 0;

// Add a line segment to the current path.
virtual void line(Math::Edgef line) = 0;

// Add a curve to the current path.
virtual void curve(Math::Curvef curve) = 0;

// Add a rectangle to the current path.
virtual void rect(Math::Rectf rect, Math::Radiusf radius = 0) = 0;

// Add an ellipse to the current path.
virtual void ellipse(Math::Ellipsef ellipse) = 0;

// Fill the current path with the given paint.
virtual void fill(Paint paint, FillRule rule = FillRule::NONZERO) = 0;

// Stroke the current path with the given style.
virtual void stroke(Stroke style) = 0;
};

} // namespace Karm::Gfx
36 changes: 17 additions & 19 deletions src/libs/karm-gfx/context.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "buffer.h"
#include "canvas.h"
#include "filters.h"
#include "paint.h"
#include "path.h"
Expand All @@ -19,10 +20,7 @@ static LcdLayout RGB = {{+0.33, 0.0}, {0.0, 0.0}, {-0.33, 0.0}};
static LcdLayout BGR = {{-0.33, 0.0}, {0.0, 0.0}, {+0.33, 0.0}};
static LcdLayout VRGB = {{0.0, +0.33}, {0.0, 0.0}, {0.0, -0.33}};

struct Context : public Meta::NoCopy {
// NOTE: Context is marked as NoCopy because it doesn't make sense to copy
// a context. And it's also a good way to prevent accidental copies.

struct Context : public Canvas {
struct Scope {
Paint paint = Gfx::WHITE;
Stroke stroke{};
Expand Down Expand Up @@ -217,58 +215,58 @@ struct Context : public Meta::NoCopy {
void _fill(Paint paint, FillRule rule = FillRule::NONZERO);

// Begin a new path.
void begin();
void begin() override;

// Close the current path. This will connect the last point to the first
void close();
void close() override;

// Begin a new subpath at the given point.
void moveTo(Math::Vec2f p, Path::Flags flags = Path::DEFAULT);
void moveTo(Math::Vec2f p, Path::Flags flags = Path::DEFAULT) override;

// Add a line segment to the current path.
void lineTo(Math::Vec2f p, Path::Flags flags = Path::DEFAULT);
void lineTo(Math::Vec2f p, Path::Flags flags = Path::DEFAULT) override;

// Add a horizontal line segment to the current path.
void hlineTo(f64 x, Path::Flags flags = Path::DEFAULT);
void hlineTo(f64 x, Path::Flags flags = Path::DEFAULT) override;

// Add a vertical line segment to the current path.
void vlineTo(f64 y, Path::Flags flags = Path::DEFAULT);
void vlineTo(f64 y, Path::Flags flags = Path::DEFAULT) override;

// Add a cubic Bezier curve to the current path.
void cubicTo(Math::Vec2f cp1, Math::Vec2f cp2, Math::Vec2f p, Path::Flags flags = Path::DEFAULT);
void cubicTo(Math::Vec2f cp1, Math::Vec2f cp2, Math::Vec2f p, Path::Flags flags = Path::DEFAULT) override;

// Add a quadratic Bezier curve to the current path.
void quadTo(Math::Vec2f cp, Math::Vec2f p, Path::Flags flags = Path::DEFAULT);
void quadTo(Math::Vec2f cp, Math::Vec2f p, Path::Flags flags = Path::DEFAULT) override;

// Add an elliptical arc to the current path.
void arcTo(Math::Vec2f radius, f64 angle, Math::Vec2f p, Path::Flags flags = Path::DEFAULT);
void arcTo(Math::Vec2f radius, f64 angle, Math::Vec2f p, Path::Flags flags = Path::DEFAULT) override;

// Evaluate the given SVG path and add it to the current path.
bool evalSvg(Str path);

// Add a line segment to the current path.
void line(Math::Edgef line);
void line(Math::Edgef line) override;

// Add a curve to the current path.
void curve(Math::Curvef curve);
void curve(Math::Curvef curve) override;

// Add a rectangle to the current path.
void rect(Math::Rectf rect, Math::Radiusf radius = 0);
void rect(Math::Rectf rect, Math::Radiusf radius = 0) override;

// Add an ellipse to the current path.
void ellipse(Math::Ellipsef ellipse);
void ellipse(Math::Ellipsef ellipse) override;

// Fill the current path.
void fill(FillRule rule = FillRule::NONZERO);

// Fill the current path with the given paint.
void fill(Paint paint, FillRule rule = FillRule::NONZERO);
void fill(Paint paint, FillRule rule = FillRule::NONZERO) override;

// Stroke the current path.
void stroke();

// Stroke the current path with the given style.
void stroke(Stroke style);
void stroke(Stroke style) override;

// MARK: Filters -----------------------------------------------------------

Expand Down
Loading

0 comments on commit 5a71566

Please sign in to comment.