From f4b08fb9511347c038a3a474ab7bdc073e75baff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?=
Date: Sun, 12 Jan 2025 10:00:32 +0100
Subject: [PATCH] lpg: improve Picture sizing, clean up
Restraining a Picture in one dimension with a Frame should make it
report the right overall dimensions (keeping its aspect ratio).
Also applying the F.9 C++ Core Guideline.
---
lpg/lpg.cpp | 68 +++++++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/lpg/lpg.cpp b/lpg/lpg.cpp
index 0301945..341a104 100644
--- a/lpg/lpg.cpp
+++ b/lpg/lpg.cpp
@@ -88,8 +88,8 @@ struct Widget {
}
/// Render to the context within the designated space, no clipping.
- virtual void render([[maybe_unused]] cairo_t *cr, [[maybe_unused]] double w,
- [[maybe_unused]] double h) {}
+ virtual void render([[maybe_unused]] cairo_t *cr,
+ [[maybe_unused]] double w, [[maybe_unused]] double h) {}
};
/// Special container that basically just fucks with the system right now.
@@ -111,6 +111,20 @@ DefWidget(Frame) {
return d;
}
+ virtual tuple prepare_for_size(
+ PangoContext *pc, double width, double height) override {
+ if (auto v = getattr("w_override"); v && get(*v) >= 0)
+ width = get(*v);
+ if (auto v = getattr("h_override"); v && get(*v) >= 0)
+ height = get(*v);
+ auto d = child->prepare_for_size(pc, width, height);
+ if (auto v = getattr("w_override"))
+ get<0>(d) = get(*v);
+ if (auto v = getattr("h_override"))
+ get<1>(d) = get(*v);
+ return d;
+ }
+
virtual void render(cairo_t *cr, double w, double h) override {
cairo_save(cr);
@@ -252,8 +266,7 @@ DefContainer(VBox) {
DefWidget(Filler) {
double w, h;
Filler(double w = -1, double h = -1) : w(w), h(h) {}
- virtual tuple prepare(
- [[maybe_unused]] PangoContext *pc) override {
+ virtual tuple prepare(PangoContext *) override {
return {w, h};
}
};
@@ -261,8 +274,7 @@ DefWidget(Filler) {
DefWidget(HLine) {
double thickness;
HLine(double thickness = 1) : thickness(thickness) {}
- virtual tuple prepare(
- [[maybe_unused]] PangoContext *pc) override {
+ virtual tuple prepare(PangoContext *) override {
return {-1, thickness};
}
virtual void render(cairo_t *cr, double w, double h) override {
@@ -276,8 +288,7 @@ DefWidget(HLine) {
DefWidget(VLine) {
double thickness;
VLine(double thickness = 1) : thickness(thickness) {}
- virtual tuple prepare(
- [[maybe_unused]] PangoContext *pc) override {
+ virtual tuple prepare(PangoContext *) override {
return {thickness, -1};
}
virtual void render(cairo_t *cr, double w, double h) override {
@@ -355,8 +366,8 @@ DefWidget(Text) {
double(w) / PANGO_SCALE, double(h) / PANGO_SCALE + 2 * y_offset};
}
- virtual tuple prepare_for_size(PangoContext *pc,
- double width, [[maybe_unused]] double height) override {
+ virtual tuple prepare_for_size(
+ PangoContext *pc, double width, double) override {
prepare_layout(pc);
// It's difficult to get vertical text, so wrap horizontally.
@@ -368,7 +379,7 @@ DefWidget(Text) {
double(w) / PANGO_SCALE, double(h) / PANGO_SCALE + 2 * y_offset};
}
- virtual void render(cairo_t *cr, double w, [[maybe_unused]] double h)
+ virtual void render(cairo_t *cr, double w, double)
override {
g_return_if_fail(layout);
// Assuming horizontal text, make it span the whole allocation.
@@ -424,20 +435,33 @@ DefWidget(Picture) {
double scale_x = 1., scale_y = 1.;
cairo_surface_t *surface = nullptr;
+ double postscale_for(double width, double height) {
+ double w = this->w * scale_x;
+ double h = this->h * scale_y;
+ if (w < 0 || h < 0)
+ return 1;
+
+ double postscale = width / w;
+ if (h * postscale > height)
+ postscale = height / h;
+ return postscale;
+ }
+
virtual tuple prepare(PangoContext *) override {
return {w * scale_x, h * scale_y};
}
+ virtual tuple prepare_for_size(
+ PangoContext *pc, double width, double height) override {
+ auto d = prepare(pc);
+ auto postscale = postscale_for(width, height);
+ return {get<0>(d) * postscale, get<1>(d) * postscale};
+ }
+
virtual void render(cairo_t *cr, double width, double height) override {
if (!surface || width <= 0 || height <= 0)
return;
- double ww = this->w * scale_x;
- double hh = this->h * scale_y;
- double postscale = width / ww;
- if (hh * postscale > height)
- postscale = height / hh;
-
// For PDF-A, ISO 19005-3:2012 6.2.8: interpolation is not allowed
// (Cairo sets it on by default).
bool interpolate = true;
@@ -447,6 +471,7 @@ DefWidget(Picture) {
pattern, interpolate ? CAIRO_FILTER_GOOD : CAIRO_FILTER_NEAREST);
// Maybe we should also center the picture or something...
+ auto postscale = postscale_for(width, height);
cairo_scale(cr, scale_x * postscale, scale_y * postscale);
cairo_set_source(cr, pattern);
cairo_paint(cr);
@@ -524,16 +549,14 @@ DefWidget(QR) {
QRcode_free(code);
}
- virtual tuple prepare([[maybe_unused]] PangoContext *pc)
- override {
+ virtual tuple prepare(PangoContext *) override {
if (!code)
return {0, 0};
return {T * code->width, T * code->width};
}
- virtual void render(cairo_t *cr,
- [[maybe_unused]] double w, [[maybe_unused]] double h) override {
+ virtual void render(cairo_t *cr, double, double) override {
if (!code)
return;
@@ -1062,8 +1085,7 @@ static int xlua_error_handler(lua_State *L) {
return 1;
}
-static void *xlua_alloc([[maybe_unused]] void *ud, void *ptr,
- [[maybe_unused]] size_t o_size, size_t n_size) {
+static void *xlua_alloc(void *, void *ptr, size_t, size_t n_size) {
if (n_size)
return realloc(ptr, n_size);