Skip to documentation
SLOP

tiny.gui.paint.gradient

Reference tiny.gui paint gradient

Defined in paint.

API (10)

Actions

Public operations.

Types and contracts

Public types and contracts.

No direct callersNo direct callspaintgradient
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsNo direct callerspaint.gradient.SamplercolorAtRowpaint.gradient.SamplerrowProjectionpaint.gradient.SamplercolorAt
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.gui.src.paint.cpu.spangradientRowspaint.gradient.SamplercolorAtpaint.gradient.SamplerparameterAtRowprivate sourcelib.gui.src.paint.gradientinterpolateValueprivate sourcelib.gui.src.paint.gradientroundedChannelprivate sourcelib.gui.src.paint.gradientunpremultipliedValuepaint.gradient.SamplercolorAtRow
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.gui.src.paint.cpu.spangradientRowspaint.gradientcolorAtpaint.gradientparameterprivate sourcelib.gui.src.paint.gradient.PremultipliedColorinitpaint.gradient.Samplerinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspaint.gradient.SamplerparameterAtRowpaint.gradient.SamplerrowProjectionpaint.gradient.SamplerparameterAt
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspaint.gradient.SamplercolorAtRowpaint.gradient.SamplerparameterAtpaint.gradient.SamplerparameterAtRow
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callsprivate sourcelib.gui.src.paint.cpu.spangradientRowspaint.gradient.SamplercolorAtpaint.gradient.SamplerparameterAtpaint.gradient.SamplerrowProjection
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsprivate sourcelib.gui.src.paint.cpu.coveragecommandColorAttest sourcelib.gui.src.paint.gradienttest: linear gradient clamps and reve...test sourcelib.gui.src.paint.gradienttest: linear gradient degenerate vect...paint.gradient.Samplerinitpaint.gradientcolorAt
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallstest sourcelib.gui.src.paint.gradienttest: linear gradient premultiplies t...private sourcelib.gui.src.paint.gradientinterpolateprivate sourcelib.gui.src.paint.gradientroundedChannelprivate sourcelib.gui.src.paint.gradientunpremultipliedpaint.gradientcolorAtParameter
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspaint.gradient.Samplerinitpaint.gradientparameter
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/gui/src/paint/gradient.zig

zig
const std = @import("std");const gui = @import("../root.zig");const Color = gui.model.UiColor;const Command = gui.paint.command.Command;const Point = gui.model.UiPoint;pub fn colorAt(paint: Command, x: f32, y: f32) Color {    return Sampler.init(paint).colorAt(x, y);}pub fn parameter(paint: Command, x: f32, y: f32) f32 {    return Sampler.init(paint).parameterAt(x, y);}pub const Sampler = struct {    start: Point,    start_color: PremultipliedColor,    end_color: PremultipliedColor,    dx: f32,    dy: f32,    length_squared: f32,    degenerate: bool,    pub fn init(paint: Command) Sampler {        const dx = paint.gradient_end.x - paint.gradient_start.x;        const dy = paint.gradient_end.y - paint.gradient_start.y;        const length_squared = dx * dx + dy * dy;        return .{            .start = paint.gradient_start,            .start_color = PremultipliedColor.init(paint.color),            .end_color = PremultipliedColor.init(paint.color_end),            .dx = dx,            .dy = dy,            .length_squared = length_squared,            .degenerate = !std.math.isFinite(length_squared) or                length_squared <= std.math.floatEps(f32),        };    }    pub fn colorAt(self: Sampler, x: f32, y: f32) Color {        return self.colorAtRow(x, self.rowProjection(y));    }    pub fn parameterAt(self: Sampler, x: f32, y: f32) f32 {        return self.parameterAtRow(x, self.rowProjection(y));    }    pub fn rowProjection(self: Sampler, y: f32) f32 {        return (y - self.start.y) * self.dy;    }    pub fn colorAtRow(self: Sampler, x: f32, row_projection: f32) Color {        const t = self.parameterAtRow(x, row_projection);        const alpha_value = interpolateValue(self.start_color.a, self.end_color.a, t);        if (alpha_value <= 0) return .{ .a = 0 };        return .{            .r = unpremultipliedValue(self.start_color.r, self.end_color.r, t, alpha_value),            .g = unpremultipliedValue(self.start_color.g, self.end_color.g, t, alpha_value),            .b = unpremultipliedValue(self.start_color.b, self.end_color.b, t, alpha_value),            .a = roundedChannel(alpha_value),        };    }    pub fn parameterAtRow(self: Sampler, x: f32, row_projection: f32) f32 {        if (self.degenerate) return 1;        const projected = ((x - self.start.x) * self.dx + row_projection) /            self.length_squared;        if (!std.math.isFinite(projected)) return 1;        return std.math.clamp(projected, @as(f32, 0), @as(f32, 1));    }};const PremultipliedColor = struct {    r: f32,    g: f32,    b: f32,    a: f32,    fn init(color: Color) PremultipliedColor {        const alpha: f32 = @floatFromInt(color.a);        return .{            .r = @as(f32, @floatFromInt(color.r)) * alpha,            .g = @as(f32, @floatFromInt(color.g)) * alpha,            .b = @as(f32, @floatFromInt(color.b)) * alpha,            .a = alpha,        };    }};pub fn colorAtParameter(start: Color, end: Color, parameter_value: f32) Color {    const t = std.math.clamp(parameter_value, @as(f32, 0), @as(f32, 1));    const alpha_value = interpolate(start.a, end.a, t);    if (alpha_value <= 0) return .{ .a = 0 };    return .{        .r = unpremultiplied(start.r, start.a, end.r, end.a, t, alpha_value),        .g = unpremultiplied(start.g, start.a, end.g, end.a, t, alpha_value),        .b = unpremultiplied(start.b, start.a, end.b, end.a, t, alpha_value),        .a = roundedChannel(alpha_value),    };}fn unpremultiplied(start: u8, start_alpha: u8, end: u8, end_alpha: u8, t: f32, alpha_value: f32) u8 {    const start_value = @as(f32, @floatFromInt(start)) * @as(f32, @floatFromInt(start_alpha));    const end_value = @as(f32, @floatFromInt(end)) * @as(f32, @floatFromInt(end_alpha));    return unpremultipliedValue(start_value, end_value, t, alpha_value);}fn unpremultipliedValue(start: f32, end: f32, t: f32, alpha_value: f32) u8 {    return roundedChannel(interpolateValue(start, end, t) / alpha_value);}fn interpolate(start: u8, end: u8, t: f32) f32 {    return interpolateValue(@floatFromInt(start), @floatFromInt(end), t);}fn interpolateValue(start: f32, end: f32, t: f32) f32 {    return start + (end - start) * t;}fn roundedChannel(value: f32) u8 {    return @intFromFloat(std.math.clamp(@round(value), @as(f32, 0), @as(f32, 255)));}test "linear gradient clamps and reverses direction" {    const paint = Command{        .kind = .linear_gradient,        .rect = .{ .width = 12, .height = 4 },        .clip = .{ .width = 12, .height = 4 },        .color = .{ .r = 10, .g = 20, .b = 30, .a = 255 },        .color_end = .{ .r = 210, .g = 120, .b = 80, .a = 255 },        .gradient_start = .{ .x = 10 },        .gradient_end = .{ .x = 2 },    };    try std.testing.expectEqual(paint.color, colorAt(paint, 12, 2));    try std.testing.expectEqual(paint.color_end, colorAt(paint, 0, 2));    try std.testing.expectEqual(@as(u8, 110), colorAt(paint, 6, 2).r);}test "linear gradient degenerate vector resolves to end color" {    const paint = Command{        .kind = .linear_gradient,        .rect = .{ .width = 4, .height = 4 },        .clip = .{ .width = 4, .height = 4 },        .color = .{ .r = 255, .a = 255 },        .color_end = .{ .b = 255, .a = 120 },        .gradient_start = .{ .x = 2, .y = 2 },        .gradient_end = .{ .x = 2, .y = 2 },    };    try std.testing.expectEqual(paint.color_end, colorAt(paint, 1, 3));}test "linear gradient premultiplies translucent interpolation" {    const color = colorAtParameter(        .{ .r = 255, .g = 40, .b = 20, .a = 255 },        .{ .r = 0, .g = 0, .b = 0, .a = 0 },        0.5,    );    try std.testing.expectEqual(@as(u8, 255), color.r);    try std.testing.expectEqual(@as(u8, 40), color.g);    try std.testing.expectEqual(@as(u8, 20), color.b);    try std.testing.expectEqual(@as(u8, 128), color.a);}

Source: lib/gui/src/paint/root.zig:7

zig
pub const gradient = @import("gradient.zig");

Audit

Definitions11
Public names11
Members7
Version26.7.0
Revisiondaab053ee433