Skip to content

Commit

Permalink
rendering: add bounded size hint
Browse files Browse the repository at this point in the history
Provides a new size-hint mechanism for rendering, `bounded`.  A bounded
size hint specifies a limit for both width and height and then renders the
maximum size that fits within these limits while also maintaining the
aspect ratio.

This option is exposed in `tvg-render` via the:

    --bounded <width>x<height>

command line option.
  • Loading branch information
marler8997 authored and ikskuh committed Jul 30, 2024
1 parent d103ec3 commit d771f6d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/sdk-readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Tools:
-g, --geometry Specifies the output geometry of the image. Has the format <width>x<height>.
--width <width> Specifies the output width to be <width>. Height will be derived via aspect ratio.
--height <height> Specifies the output height to be <height>. Width will be derived via aspect ratio.
--bounded <geom> Output's maximum size within the given <width>x<height> that maintains the aspect ratio.
-s, --super-sampling Sets the super-sampling size for the image. Use 1 for no super sampling and 16 for very high quality.
-a, --anti-alias Sets the super-sampling size to 4. This is usually decent enough for most images.

Expand Down
20 changes: 20 additions & 0 deletions src/lib/rendering.zig
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub fn renderStream(
.width = (height * parser.header.width) / parser.header.height,
.height = height,
},
.bounded => |bounds| calcBoundedSize(
bounds, parser.header.width, parser.header.height
),
};

const super_scale: u32 = if (anti_alias) |factor|
Expand Down Expand Up @@ -226,8 +229,25 @@ pub const SizeHint = union(enum) {
width: u32,
height: u32,
size: Size,
/// The maximum size that maintains the aspect ratio and fits within the given bounds
bounded: Size,
};

fn calcBoundedSize(bounds: Size, width: u32, height: u32) Size {
const width_f32: f32 = @floatFromInt(width);
const height_f32: f32 = @floatFromInt(height);
const width_mult = @as(f32, @floatFromInt(bounds.width)) / width_f32;
const height_mult = @as(f32, @floatFromInt(bounds.height)) / height_f32;
if (width_mult >= height_mult) return .{
.width = @intFromFloat(@trunc(width_f32 * height_mult)),
.height = bounds.height,
};
return .{
.width = bounds.width,
.height = @intFromFloat(@trunc(height_f32 * width_mult)),
};
}

pub const Size = struct {
width: u32,
height: u32,
Expand Down
10 changes: 9 additions & 1 deletion src/tools/render.zig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ fn printUsage(stream: anytype) !void {
\\ -g, --geometry <geom> Specifies the output geometry of the image. Has the format <width>x<height>.
\\ --width <width> Specifies the output width to be <width>. Height will be derived via aspect ratio.
\\ --height <height> Specifies the output height to be <height>. Width will be derived via aspect ratio.
\\ --bounded <geom> Output's maximum size within the given <width>x<height> that maintains the aspect ratio.
\\ -s, --super-sampling Sets the super-sampling size for the image. Use 1 for no super sampling and 16 for very high quality.
\\ -a, --anti-alias Sets the super-sampling size to 4. This is usually decent enough for most images.
\\
Expand All @@ -28,6 +29,10 @@ const CliOptions = struct {
geometry: ?Geometry = null,
width: ?u32 = null,
height: ?u32 = null,
bounded: ?Geometry = null,

max_width: ?u32 = null,
max_height: ?u32 = null,

@"anti-alias": bool = false,
@"super-sampling": ?u32 = null,
Expand Down Expand Up @@ -69,8 +74,9 @@ pub fn main() !u8 {
if (cli.options.width != null) cnt += 1;
if (cli.options.height != null) cnt += 1;
if (cli.options.geometry != null) cnt += 1;
if (cli.options.bounded != null) cnt += 1;
if (cnt > 1) {
try stderr.writeAll("--width, --height and --geometry are mutual exclusive!\n");
try stderr.writeAll("--width, --height, --geometry and --bounded are mutually exclusive!\n");
try printUsage(stderr);
return 1;
}
Expand Down Expand Up @@ -118,6 +124,8 @@ pub fn main() !u8 {
tvg.rendering.SizeHint{ .height = height }
else if (cli.options.geometry) |geom|
tvg.rendering.SizeHint{ .size = tvg.rendering.Size{ .width = geom.width, .height = geom.height } }
else if (cli.options.bounded) |b|
tvg.rendering.SizeHint{ .bounded = .{ .width = b.width, .height = b.height } }
else
.inherit,
@enumFromInt(super_scale),
Expand Down

0 comments on commit d771f6d

Please sign in to comment.