From ced4247e557bdd843e2701f4fd478ecbb34dc7e8 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Sun, 29 Sep 2024 23:05:28 -0600 Subject: [PATCH] font/sprite: refactor lines and fractional blocks, add ground truth for regression test Use a single unified function for intersection-style line drawing chars, and one for fractional block characters. Add a ground truth image based on this commit for the regression test (differences from before changes validated visually, 1 incorrect rendering actually fixed) --- src/font/sprite/Box.zig | 1871 ++++++++++-------------------- src/font/sprite/testdata/Box.ppm | Bin 0 -> 1048593 bytes 2 files changed, 619 insertions(+), 1252 deletions(-) create mode 100644 src/font/sprite/testdata/Box.ppm diff --git a/src/font/sprite/Box.zig b/src/font/sprite/Box.zig index 7feceeb6e..4478a38f7 100644 --- a/src/font/sprite/Box.zig +++ b/src/font/sprite/Box.zig @@ -3,12 +3,17 @@ //! characters that are provided by the terminal. //! //! The box drawing logic is based off similar logic in Kitty and Foot. -//! The primary drawing code was ported directly and slightly modified from Foot -//! (https://codeberg.org/dnkl/foot/). Foot is licensed under the MIT -//! license and is copyright 2019 Daniel Eklöf. +//! The primary drawing code was originally ported directly and slightly +//! modified from Foot (https://codeberg.org/dnkl/foot/). Foot is licensed +//! under the MIT license and is copyright 2019 Daniel Eklöf. //! -//! The modifications made are primarily around spacing, DPI calculations, -//! and adapting the code to our atlas model. +//! The modifications made were primarily around spacing, DPI calculations, +//! and adapting the code to our atlas model. Further, more extensive changes +//! were made, refactoring the line characters to all share a single unified +//! function (draw_lines), as well as many of the fractional block characters +//! which now use draw_block instead of dedicated separate functions. +//! +//! Additional characters from Unicode 16.0 and beyond are original work. const Box = @This(); const std = @import("std"); @@ -47,6 +52,59 @@ const Thickness = enum { } }; +/// Specification of a traditional intersection-style line/box-drawing char, +/// which can have a different style of line from each edge to the center. +const Lines = struct { + up: Style = .none, + right: Style = .none, + down: Style = .none, + left: Style = .none, + + const Style = enum { + none, + light, + heavy, + double, + }; +}; + +/// Alignment of a figure within a cell +const Alignment = struct { + horizontal: enum { + left, + right, + center, + } = .center, + + vertical: enum { + top, + bottom, + middle, + } = .middle, + + const upper: Alignment = .{ .vertical = .top }; + const lower: Alignment = .{ .vertical = .bottom }; + const left: Alignment = .{ .horizontal = .left }; + const right: Alignment = .{ .horizontal = .right }; + + const upper_left: Alignment = .{ .vertical = .top, .horizontal = .left }; + const upper_right: Alignment = .{ .vertical = .top, .horizontal = .right }; + const lower_left: Alignment = .{ .vertical = .bottom, .horizontal = .left }; + const lower_right: Alignment = .{ .vertical = .bottom, .horizontal = .right }; + + const top = upper; + const bottom = lower; +}; + +// Utility names for common fractions +const one_eighth: f64 = 0.125; +const one_quarter: f64 = 0.25; +const three_eighths: f64 = 0.375; +const half: f64 = 0.5; +const five_eighths: f64 = 0.625; +const three_quarters: f64 = 0.75; +const seven_eighths: f64 = 0.875; + pub fn renderGlyph( self: Box, alloc: Allocator, @@ -94,230 +152,427 @@ pub fn unadjustedCodepoint(cp: u32) bool { fn draw(self: Box, alloc: Allocator, canvas: *font.sprite.Canvas, cp: u32) !void { switch (cp) { - 0x2500 => self.draw_light_horizontal(canvas), - 0x2501 => self.draw_heavy_horizontal(canvas), - 0x2502 => self.draw_light_vertical(canvas), - 0x2503 => self.draw_heavy_vertical(canvas), + // '─' + 0x2500 => self.draw_lines(canvas, .{ .left = .light, .right = .light }), + // '━' + 0x2501 => self.draw_lines(canvas, .{ .left = .heavy, .right = .heavy }), + // '│' + 0x2502 => self.draw_lines(canvas, .{ .up = .light, .down = .light }), + // '┃' + 0x2503 => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy }), + // '┄' 0x2504 => self.draw_light_triple_dash_horizontal(canvas), + // '┅' 0x2505 => self.draw_heavy_triple_dash_horizontal(canvas), + // '┆' 0x2506 => self.draw_light_triple_dash_vertical(canvas), + // '┇' 0x2507 => self.draw_heavy_triple_dash_vertical(canvas), + // '┈' 0x2508 => self.draw_light_quadruple_dash_horizontal(canvas), + // '┉' 0x2509 => self.draw_heavy_quadruple_dash_horizontal(canvas), + // '┊' 0x250a => self.draw_light_quadruple_dash_vertical(canvas), + // '┋' 0x250b => self.draw_heavy_quadruple_dash_vertical(canvas), - 0x250c => self.draw_light_down_and_right(canvas), - 0x250d => self.draw_down_light_and_right_heavy(canvas), - 0x250e => self.draw_down_heavy_and_right_light(canvas), - 0x250f => self.draw_heavy_down_and_right(canvas), + // '┌' + 0x250c => self.draw_lines(canvas, .{ .down = .light, .right = .light }), + // '┍' + 0x250d => self.draw_lines(canvas, .{ .down = .light, .right = .heavy }), + // '┎' + 0x250e => self.draw_lines(canvas, .{ .down = .heavy, .right = .light }), + // '┏' + 0x250f => self.draw_lines(canvas, .{ .down = .heavy, .right = .heavy }), - 0x2510 => self.draw_light_down_and_left(canvas), - 0x2511 => self.draw_down_light_and_left_heavy(canvas), - 0x2512 => self.draw_down_heavy_and_left_light(canvas), - 0x2513 => self.draw_heavy_down_and_left(canvas), - 0x2514 => self.draw_light_up_and_right(canvas), - 0x2515 => self.draw_up_light_and_right_heavy(canvas), - 0x2516 => self.draw_up_heavy_and_right_light(canvas), - 0x2517 => self.draw_heavy_up_and_right(canvas), - 0x2518 => self.draw_light_up_and_left(canvas), - 0x2519 => self.draw_up_light_and_left_heavy(canvas), - 0x251a => self.draw_up_heavy_and_left_light(canvas), - 0x251b => self.draw_heavy_up_and_left(canvas), - 0x251c => self.draw_light_vertical_and_right(canvas), - 0x251d => self.draw_vertical_light_and_right_heavy(canvas), - 0x251e => self.draw_up_heavy_and_right_down_light(canvas), - 0x251f => self.draw_down_heavy_and_right_up_light(canvas), + // '┐' + 0x2510 => self.draw_lines(canvas, .{ .down = .light, .left = .light }), + // '┑' + 0x2511 => self.draw_lines(canvas, .{ .down = .light, .left = .heavy }), + // '┒' + 0x2512 => self.draw_lines(canvas, .{ .down = .heavy, .left = .light }), + // '┓' + 0x2513 => self.draw_lines(canvas, .{ .down = .heavy, .left = .heavy }), + // '└' + 0x2514 => self.draw_lines(canvas, .{ .up = .light, .right = .light }), + // '┕' + 0x2515 => self.draw_lines(canvas, .{ .up = .light, .right = .heavy }), + // '┖' + 0x2516 => self.draw_lines(canvas, .{ .up = .heavy, .right = .light }), + // '┗' + 0x2517 => self.draw_lines(canvas, .{ .up = .heavy, .right = .heavy }), + // '┘' + 0x2518 => self.draw_lines(canvas, .{ .up = .light, .left = .light }), + // '┙' + 0x2519 => self.draw_lines(canvas, .{ .up = .light, .left = .heavy }), + // '┚' + 0x251a => self.draw_lines(canvas, .{ .up = .heavy, .left = .light }), + // '┛' + 0x251b => self.draw_lines(canvas, .{ .up = .heavy, .left = .heavy }), + // '├' + 0x251c => self.draw_lines(canvas, .{ .up = .light, .down = .light, .right = .light }), + // '┝' + 0x251d => self.draw_lines(canvas, .{ .up = .light, .down = .light, .right = .heavy }), + // '┞' + 0x251e => self.draw_lines(canvas, .{ .up = .heavy, .right = .light, .down = .light }), + // '┟' + 0x251f => self.draw_lines(canvas, .{ .down = .heavy, .right = .light, .up = .light }), - 0x2520 => self.draw_vertical_heavy_and_right_light(canvas), - 0x2521 => self.draw_down_light_and_right_up_heavy(canvas), - 0x2522 => self.draw_up_light_and_right_down_heavy(canvas), - 0x2523 => self.draw_heavy_vertical_and_right(canvas), - 0x2524 => self.draw_light_vertical_and_left(canvas), - 0x2525 => self.draw_vertical_light_and_left_heavy(canvas), - 0x2526 => self.draw_up_heavy_and_left_down_light(canvas), - 0x2527 => self.draw_down_heavy_and_left_up_light(canvas), - 0x2528 => self.draw_vertical_heavy_and_left_light(canvas), - 0x2529 => self.draw_down_light_and_left_up_heavy(canvas), - 0x252a => self.draw_up_light_and_left_down_heavy(canvas), - 0x252b => self.draw_heavy_vertical_and_left(canvas), - 0x252c => self.draw_light_down_and_horizontal(canvas), - 0x252d => self.draw_left_heavy_and_right_down_light(canvas), - 0x252e => self.draw_right_heavy_and_left_down_light(canvas), - 0x252f => self.draw_down_light_and_horizontal_heavy(canvas), + // '┠' + 0x2520 => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy, .right = .light }), + // '┡' + 0x2521 => self.draw_lines(canvas, .{ .down = .light, .right = .heavy, .up = .heavy }), + // '┢' + 0x2522 => self.draw_lines(canvas, .{ .up = .light, .right = .heavy, .down = .heavy }), + // '┣' + 0x2523 => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy, .right = .heavy }), + // '┤' + 0x2524 => self.draw_lines(canvas, .{ .up = .light, .down = .light, .left = .light }), + // '┥' + 0x2525 => self.draw_lines(canvas, .{ .up = .light, .down = .light, .left = .heavy }), + // '┦' + 0x2526 => self.draw_lines(canvas, .{ .up = .heavy, .left = .light, .down = .light }), + // '┧' + 0x2527 => self.draw_lines(canvas, .{ .down = .heavy, .left = .light, .up = .light }), + // '┨' + 0x2528 => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy, .left = .light }), + // '┩' + 0x2529 => self.draw_lines(canvas, .{ .down = .light, .left = .heavy, .up = .heavy }), + // '┪' + 0x252a => self.draw_lines(canvas, .{ .up = .light, .left = .heavy, .down = .heavy }), + // '┫' + 0x252b => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy, .left = .heavy }), + // '┬' + 0x252c => self.draw_lines(canvas, .{ .down = .light, .left = .light, .right = .light }), + // '┭' + 0x252d => self.draw_lines(canvas, .{ .left = .heavy, .right = .light, .down = .light }), + // '┮' + 0x252e => self.draw_lines(canvas, .{ .right = .heavy, .left = .light, .down = .light }), + // '┯' + 0x252f => self.draw_lines(canvas, .{ .down = .light, .left = .heavy, .right = .heavy }), - 0x2530 => self.draw_down_heavy_and_horizontal_light(canvas), - 0x2531 => self.draw_right_light_and_left_down_heavy(canvas), - 0x2532 => self.draw_left_light_and_right_down_heavy(canvas), - 0x2533 => self.draw_heavy_down_and_horizontal(canvas), - 0x2534 => self.draw_light_up_and_horizontal(canvas), - 0x2535 => self.draw_left_heavy_and_right_up_light(canvas), - 0x2536 => self.draw_right_heavy_and_left_up_light(canvas), - 0x2537 => self.draw_up_light_and_horizontal_heavy(canvas), - 0x2538 => self.draw_up_heavy_and_horizontal_light(canvas), - 0x2539 => self.draw_right_light_and_left_up_heavy(canvas), - 0x253a => self.draw_left_light_and_right_up_heavy(canvas), - 0x253b => self.draw_heavy_up_and_horizontal(canvas), - 0x253c => self.draw_light_vertical_and_horizontal(canvas), - 0x253d => self.draw_left_heavy_and_right_vertical_light(canvas), - 0x253e => self.draw_right_heavy_and_left_vertical_light(canvas), - 0x253f => self.draw_vertical_light_and_horizontal_heavy(canvas), + // '┰' + 0x2530 => self.draw_lines(canvas, .{ .down = .heavy, .left = .light, .right = .light }), + // '┱' + 0x2531 => self.draw_lines(canvas, .{ .right = .light, .left = .heavy, .down = .heavy }), + // '┲' + 0x2532 => self.draw_lines(canvas, .{ .left = .light, .right = .heavy, .down = .heavy }), + // '┳' + 0x2533 => self.draw_lines(canvas, .{ .down = .heavy, .left = .heavy, .right = .heavy }), + // '┴' + 0x2534 => self.draw_lines(canvas, .{ .up = .light, .left = .light, .right = .light }), + // '┵' + 0x2535 => self.draw_lines(canvas, .{ .left = .heavy, .right = .light, .up = .light }), + // '┶' + 0x2536 => self.draw_lines(canvas, .{ .right = .heavy, .left = .light, .up = .light }), + // '┷' + 0x2537 => self.draw_lines(canvas, .{ .up = .light, .left = .heavy, .right = .heavy }), + // '┸' + 0x2538 => self.draw_lines(canvas, .{ .up = .heavy, .left = .light, .right = .light }), + // '┹' + 0x2539 => self.draw_lines(canvas, .{ .right = .light, .left = .heavy, .up = .heavy }), + // '┺' + 0x253a => self.draw_lines(canvas, .{ .left = .light, .right = .heavy, .up = .heavy }), + // '┻' + 0x253b => self.draw_lines(canvas, .{ .up = .heavy, .left = .heavy, .right = .heavy }), + // '┼' + 0x253c => self.draw_lines(canvas, .{ .up = .light, .down = .light, .left = .light, .right = .light }), + // '┽' + 0x253d => self.draw_lines(canvas, .{ .left = .heavy, .right = .light, .up = .light, .down = .light }), + // '┾' + 0x253e => self.draw_lines(canvas, .{ .right = .heavy, .left = .light, .up = .light, .down = .light }), + // '┿' + 0x253f => self.draw_lines(canvas, .{ .up = .light, .down = .light, .left = .heavy, .right = .heavy }), - 0x2540 => self.draw_up_heavy_and_down_horizontal_light(canvas), - 0x2541 => self.draw_down_heavy_and_up_horizontal_light(canvas), - 0x2542 => self.draw_vertical_heavy_and_horizontal_light(canvas), - 0x2543 => self.draw_left_up_heavy_and_right_down_light(canvas), - 0x2544 => self.draw_right_up_heavy_and_left_down_light(canvas), - 0x2545 => self.draw_left_down_heavy_and_right_up_light(canvas), - 0x2546 => self.draw_right_down_heavy_and_left_up_light(canvas), - 0x2547 => self.draw_down_light_and_up_horizontal_heavy(canvas), - 0x2548 => self.draw_up_light_and_down_horizontal_heavy(canvas), - 0x2549 => self.draw_right_light_and_left_vertical_heavy(canvas), - 0x254a => self.draw_left_light_and_right_vertical_heavy(canvas), - 0x254b => self.draw_heavy_vertical_and_horizontal(canvas), + // '╀' + 0x2540 => self.draw_lines(canvas, .{ .up = .heavy, .down = .light, .left = .light, .right = .light }), + // '╁' + 0x2541 => self.draw_lines(canvas, .{ .down = .heavy, .up = .light, .left = .light, .right = .light }), + // '╂' + 0x2542 => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy, .left = .light, .right = .light }), + // '╃' + 0x2543 => self.draw_lines(canvas, .{ .left = .heavy, .up = .heavy, .right = .light, .down = .light }), + // '╄' + 0x2544 => self.draw_lines(canvas, .{ .right = .heavy, .up = .heavy, .left = .light, .down = .light }), + // '╅' + 0x2545 => self.draw_lines(canvas, .{ .left = .heavy, .down = .heavy, .right = .light, .up = .light }), + // '╆' + 0x2546 => self.draw_lines(canvas, .{ .right = .heavy, .down = .heavy, .left = .light, .up = .light }), + // '╇' + 0x2547 => self.draw_lines(canvas, .{ .down = .light, .up = .heavy, .left = .heavy, .right = .heavy }), + // '╈' + 0x2548 => self.draw_lines(canvas, .{ .up = .light, .down = .heavy, .left = .heavy, .right = .heavy }), + // '╉' + 0x2549 => self.draw_lines(canvas, .{ .right = .light, .left = .heavy, .up = .heavy, .down = .heavy }), + // '╊' + 0x254a => self.draw_lines(canvas, .{ .left = .light, .right = .heavy, .up = .heavy, .down = .heavy }), + // '╋' + 0x254b => self.draw_lines(canvas, .{ .up = .heavy, .down = .heavy, .left = .heavy, .right = .heavy }), + // '╌' 0x254c => self.draw_light_double_dash_horizontal(canvas), + // '╍' 0x254d => self.draw_heavy_double_dash_horizontal(canvas), + // '╎' 0x254e => self.draw_light_double_dash_vertical(canvas), + // '╏' 0x254f => self.draw_heavy_double_dash_vertical(canvas), - 0x2550 => self.draw_double_horizontal(canvas), - 0x2551 => self.draw_double_vertical(canvas), - 0x2552 => self.draw_down_single_and_right_double(canvas), - 0x2553 => self.draw_down_double_and_right_single(canvas), - 0x2554 => self.draw_double_down_and_right(canvas), - 0x2555 => self.draw_down_single_and_left_double(canvas), - 0x2556 => self.draw_down_double_and_left_single(canvas), - 0x2557 => self.draw_double_down_and_left(canvas), - 0x2558 => self.draw_up_single_and_right_double(canvas), - 0x2559 => self.draw_up_double_and_right_single(canvas), - 0x255a => self.draw_double_up_and_right(canvas), - 0x255b => self.draw_up_single_and_left_double(canvas), - 0x255c => self.draw_up_double_and_left_single(canvas), - 0x255d => self.draw_double_up_and_left(canvas), - 0x255e => self.draw_vertical_single_and_right_double(canvas), - 0x255f => self.draw_vertical_double_and_right_single(canvas), + // '═' + 0x2550 => self.draw_lines(canvas, .{ .left = .double, .right = .double }), + // '║' + 0x2551 => self.draw_lines(canvas, .{ .up = .double, .down = .double }), + // '╒' + 0x2552 => self.draw_lines(canvas, .{ .down = .light, .right = .double }), + // '╓' + 0x2553 => self.draw_lines(canvas, .{ .down = .double, .right = .light }), + // '╔' + 0x2554 => self.draw_lines(canvas, .{ .down = .double, .right = .double }), + // '╕' + 0x2555 => self.draw_lines(canvas, .{ .down = .light, .left = .double }), + // '╖' + 0x2556 => self.draw_lines(canvas, .{ .down = .double, .left = .light }), + // '╗' + 0x2557 => self.draw_lines(canvas, .{ .down = .double, .left = .double }), + // '╘' + 0x2558 => self.draw_lines(canvas, .{ .up = .light, .right = .double }), + // '╙' + 0x2559 => self.draw_lines(canvas, .{ .up = .double, .right = .light }), + // '╚' + 0x255a => self.draw_lines(canvas, .{ .up = .double, .right = .double }), + // '╛' + 0x255b => self.draw_lines(canvas, .{ .up = .light, .left = .double }), + // '╜' + 0x255c => self.draw_lines(canvas, .{ .up = .double, .left = .light }), + // '╝' + 0x255d => self.draw_lines(canvas, .{ .up = .double, .left = .double }), + // '╞' + 0x255e => self.draw_lines(canvas, .{ .up = .light, .down = .light, .right = .double }), + // '╟' + 0x255f => self.draw_lines(canvas, .{ .up = .double, .down = .double, .right = .light }), - 0x2560 => self.draw_double_vertical_and_right(canvas), - 0x2561 => self.draw_vertical_single_and_left_double(canvas), - 0x2562 => self.draw_vertical_double_and_left_single(canvas), - 0x2563 => self.draw_double_vertical_and_left(canvas), - 0x2564 => self.draw_down_single_and_horizontal_double(canvas), - 0x2565 => self.draw_down_double_and_horizontal_single(canvas), - 0x2566 => self.draw_double_down_and_horizontal(canvas), - 0x2567 => self.draw_up_single_and_horizontal_double(canvas), - 0x2568 => self.draw_up_double_and_horizontal_single(canvas), - 0x2569 => self.draw_double_up_and_horizontal(canvas), - 0x256a => self.draw_vertical_single_and_horizontal_double(canvas), - 0x256b => self.draw_vertical_double_and_horizontal_single(canvas), - 0x256c => self.draw_double_vertical_and_horizontal(canvas), + // '╠' + 0x2560 => self.draw_lines(canvas, .{ .up = .double, .down = .double, .right = .double }), + // '╡' + 0x2561 => self.draw_lines(canvas, .{ .up = .light, .down = .light, .left = .double }), + // '╢' + 0x2562 => self.draw_lines(canvas, .{ .up = .double, .down = .double, .left = .light }), + // '╣' + 0x2563 => self.draw_lines(canvas, .{ .up = .double, .down = .double, .left = .double }), + // '╤' + 0x2564 => self.draw_lines(canvas, .{ .down = .light, .left = .double, .right = .double }), + // '╥' + 0x2565 => self.draw_lines(canvas, .{ .down = .double, .left = .light, .right = .light }), + // '╦' + 0x2566 => self.draw_lines(canvas, .{ .down = .double, .left = .double, .right = .double }), + // '╧' + 0x2567 => self.draw_lines(canvas, .{ .up = .light, .left = .double, .right = .double }), + // '╨' + 0x2568 => self.draw_lines(canvas, .{ .up = .double, .left = .light, .right = .light }), + // '╩' + 0x2569 => self.draw_lines(canvas, .{ .up = .double, .left = .double, .right = .double }), + // '╪' + 0x256a => self.draw_lines(canvas, .{ .up = .light, .down = .light, .left = .double, .right = .double }), + // '╫' + 0x256b => self.draw_lines(canvas, .{ .up = .double, .down = .double, .left = .light, .right = .light }), + // '╬' + 0x256c => self.draw_lines(canvas, .{ .up = .double, .down = .double, .left = .double, .right = .double }), 0x256d...0x2570 => try self.draw_light_arc(alloc, canvas, cp), + // '╱' 0x2571 => self.draw_light_diagonal_upper_right_to_lower_left(canvas), + // '╲' 0x2572 => self.draw_light_diagonal_upper_left_to_lower_right(canvas), + // '╳' 0x2573 => self.draw_light_diagonal_cross(canvas), - 0x2574 => self.draw_light_left(canvas), - 0x2575 => self.draw_light_up(canvas), - 0x2576 => self.draw_light_right(canvas), - 0x2577 => self.draw_light_down(canvas), - 0x2578 => self.draw_heavy_left(canvas), - 0x2579 => self.draw_heavy_up(canvas), - 0x257a => self.draw_heavy_right(canvas), - 0x257b => self.draw_heavy_down(canvas), - 0x257c => self.draw_light_left_and_heavy_right(canvas), - 0x257d => self.draw_light_up_and_heavy_down(canvas), - 0x257e => self.draw_heavy_left_and_light_right(canvas), - 0x257f => self.draw_heavy_up_and_light_down(canvas), + // '╴' + 0x2574 => self.draw_lines(canvas, .{ .left = .light }), + // '╵' + 0x2575 => self.draw_lines(canvas, .{ .up = .light }), + // '╶' + 0x2576 => self.draw_lines(canvas, .{ .right = .light }), + // '╷' + 0x2577 => self.draw_lines(canvas, .{ .down = .light }), + // '╸' + 0x2578 => self.draw_lines(canvas, .{ .left = .heavy }), + // '╹' + 0x2579 => self.draw_lines(canvas, .{ .up = .heavy }), + // '╺' + 0x257a => self.draw_lines(canvas, .{ .right = .heavy }), + // '╻' + 0x257b => self.draw_lines(canvas, .{ .down = .heavy }), + // '╼' + 0x257c => self.draw_lines(canvas, .{ .left = .light, .right = .heavy }), + // '╽' + 0x257d => self.draw_lines(canvas, .{ .up = .light, .down = .heavy }), + // '╾' + 0x257e => self.draw_lines(canvas, .{ .left = .heavy, .right = .light }), + // '╿' + 0x257f => self.draw_lines(canvas, .{ .up = .heavy, .down = .light }), - 0x2580 => self.draw_upper_half_block(canvas), - 0x2581 => self.draw_lower_one_eighth_block(canvas), - 0x2582 => self.draw_lower_one_quarter_block(canvas), - 0x2583 => self.draw_lower_three_eighths_block(canvas), - 0x2584 => self.draw_lower_half_block(canvas), - 0x2585 => self.draw_lower_five_eighths_block(canvas), - 0x2586 => self.draw_lower_three_quarters_block(canvas), - 0x2587 => self.draw_lower_seven_eighths_block(canvas), + // '▀' UPPER HALF BLOCK + 0x2580 => self.draw_block(canvas, Alignment.upper, 1, half), + // '▁' LOWER ONE EIGHTH BLOCK + 0x2581 => self.draw_block(canvas, Alignment.lower, 1, one_eighth), + // '▂' LOWER ONE QUARTER BLOCK + 0x2582 => self.draw_block(canvas, Alignment.lower, 1, one_quarter), + // '▃' LOWER THREE EIGHTHS BLOCK + 0x2583 => self.draw_block(canvas, Alignment.lower, 1, three_eighths), + // '▄' LOWER HALF BLOCK + 0x2584 => self.draw_block(canvas, Alignment.lower, 1, half), + // '▅' LOWER FIVE EIGHTHS BLOCK + 0x2585 => self.draw_block(canvas, Alignment.lower, 1, five_eighths), + // '▆' LOWER THREE QUARTERS BLOCK + 0x2586 => self.draw_block(canvas, Alignment.lower, 1, three_quarters), + // '▇' LOWER SEVEN EIGHTHS BLOCK + 0x2587 => self.draw_block(canvas, Alignment.lower, 1, seven_eighths), + // '█' FULL BLOCK 0x2588 => self.draw_full_block(canvas), - 0x2589 => self.draw_left_seven_eighths_block(canvas), - 0x258a => self.draw_left_three_quarters_block(canvas), - 0x258b => self.draw_left_five_eighths_block(canvas), - 0x258c => self.draw_left_half_block(canvas), - 0x258d => self.draw_left_three_eighths_block(canvas), - 0x258e => self.draw_left_one_quarter_block(canvas), - 0x258f => self.draw_left_one_eighth_block(canvas), + // '▉' LEFT SEVEN EIGHTHS BLOCK + 0x2589 => self.draw_block(canvas, Alignment.left, seven_eighths, 1), + // '▊' LEFT THREE QUARTERS BLOCK + 0x258a => self.draw_block(canvas, Alignment.left, three_quarters, 1), + // '▋' LEFT FIVE EIGHTHS BLOCK + 0x258b => self.draw_block(canvas, Alignment.left, five_eighths, 1), + // '▌' LEFT HALF BLOCK + 0x258c => self.draw_block(canvas, Alignment.left, half, 1), + // '▍' LEFT THREE EIGHTHS BLOCK + 0x258d => self.draw_block(canvas, Alignment.left, three_eighths, 1), + // '▎' LEFT ONE QUARTER BLOCK + 0x258e => self.draw_block(canvas, Alignment.left, one_quarter, 1), + // '▏' LEFT ONE EIGHTH BLOCK + 0x258f => self.draw_block(canvas, Alignment.left, one_eighth, 1), - 0x2590 => self.draw_right_half_block(canvas), + // '▐' RIGHT HALF BLOCK + 0x2590 => self.draw_block(canvas, Alignment.right, half, 1), + // '░' 0x2591 => self.draw_light_shade(canvas), + // '▒' 0x2592 => self.draw_medium_shade(canvas), + // '▓' 0x2593 => self.draw_dark_shade(canvas), - 0x2594 => self.draw_upper_one_eighth_block(canvas), - 0x2595 => self.draw_right_one_eighth_block(canvas), + // '▔' UPPER ONE EIGHTH BLOCK + 0x2594 => self.draw_block(canvas, Alignment.upper, 1, one_eighth), + // '▕' RIGHT ONE EIGHTH BLOCK + 0x2595 => self.draw_block(canvas, Alignment.right, one_eighth, 1), + + // ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟ 0x2596...0x259f => self.draw_quadrant(canvas, cp), - 0x2800...0x28FF => self.draw_braille(canvas, cp), + 0x2800...0x28ff => self.draw_braille(canvas, cp), - 0x1FB00...0x1FB3B => self.draw_sextant(canvas, cp), + 0x1fb00...0x1fb3b => self.draw_sextant(canvas, cp), - 0x1FB3C...0x1FB40, - 0x1FB47...0x1FB4B, - 0x1FB57...0x1FB5B, - 0x1FB62...0x1FB66, - 0x1FB6C...0x1FB6F, + 0x1fb3c...0x1fb40, + 0x1fb47...0x1fb4b, + 0x1fb57...0x1fb5b, + 0x1fb62...0x1fb66, + 0x1fb6c...0x1fb6f, => try self.draw_wedge_triangle(canvas, cp), - 0x1FB41...0x1FB45, - 0x1FB4C...0x1FB50, - 0x1FB52...0x1FB56, - 0x1FB5D...0x1FB61, - 0x1FB68...0x1FB6B, + 0x1fb41...0x1fb45, + 0x1fb4c...0x1fb50, + 0x1fb52...0x1fb56, + 0x1fb5d...0x1fb61, + 0x1fb68...0x1fb6b, => try self.draw_wedge_triangle_inverted(alloc, canvas, cp), - 0x1FB46, - 0x1FB51, - 0x1FB5C, - 0x1FB67, + // '🭆' + 0x1fb46, + // '🭑' + 0x1fb51, + // '🭜' + 0x1fb5c, + // '🭧' + 0x1fb67, => try self.draw_wedge_triangle_and_box(canvas, cp), - 0x1FB9A => { + // '🮚' + 0x1fb9a => { try self.draw_wedge_triangle(canvas, 0x1fb6d); try self.draw_wedge_triangle(canvas, 0x1fb6f); }, - 0x1FB9B => { + // '🮛' + 0x1fb9b => { try self.draw_wedge_triangle(canvas, 0x1fb6c); try self.draw_wedge_triangle(canvas, 0x1fb6e); }, - 0x1FB70 => self.draw_vertical_one_eighth_block_n(canvas, 1), - 0x1FB71 => self.draw_vertical_one_eighth_block_n(canvas, 2), - 0x1FB72 => self.draw_vertical_one_eighth_block_n(canvas, 3), - 0x1FB73 => self.draw_vertical_one_eighth_block_n(canvas, 4), - 0x1FB74 => self.draw_vertical_one_eighth_block_n(canvas, 5), - 0x1FB75 => self.draw_vertical_one_eighth_block_n(canvas, 6), + // '🭰' + 0x1fb70 => self.draw_vertical_one_eighth_block_n(canvas, 1), + // '🭱' + 0x1fb71 => self.draw_vertical_one_eighth_block_n(canvas, 2), + // '🭲' + 0x1fb72 => self.draw_vertical_one_eighth_block_n(canvas, 3), + // '🭳' + 0x1fb73 => self.draw_vertical_one_eighth_block_n(canvas, 4), + // '🭴' + 0x1fb74 => self.draw_vertical_one_eighth_block_n(canvas, 5), + // '🭵' + 0x1fb75 => self.draw_vertical_one_eighth_block_n(canvas, 6), - 0x1FB76 => self.draw_horizontal_one_eighth_block_n(canvas, 1), - 0x1FB77 => self.draw_horizontal_one_eighth_block_n(canvas, 2), - 0x1FB78 => self.draw_horizontal_one_eighth_block_n(canvas, 3), - 0x1FB79 => self.draw_horizontal_one_eighth_block_n(canvas, 4), - 0x1FB7A => self.draw_horizontal_one_eighth_block_n(canvas, 5), - 0x1FB7B => self.draw_horizontal_one_eighth_block_n(canvas, 6), + // '🭶' + 0x1fb76 => self.draw_horizontal_one_eighth_block_n(canvas, 1), + // '🭷' + 0x1fb77 => self.draw_horizontal_one_eighth_block_n(canvas, 2), + // '🭸' + 0x1fb78 => self.draw_horizontal_one_eighth_block_n(canvas, 3), + // '🭹' + 0x1fb79 => self.draw_horizontal_one_eighth_block_n(canvas, 4), + // '🭺' + 0x1fb7a => self.draw_horizontal_one_eighth_block_n(canvas, 5), + // '🭻' + 0x1fb7b => self.draw_horizontal_one_eighth_block_n(canvas, 6), - 0x1fb82 => self.draw_upper_one_quarter_block(canvas), - 0x1fb83 => self.draw_upper_three_eighths_block(canvas), - 0x1fb84 => self.draw_upper_five_eighths_block(canvas), - 0x1fb85 => self.draw_upper_three_quarters_block(canvas), - 0x1fb86 => self.draw_upper_seven_eighths_block(canvas), + // '🮂' UPPER ONE QUARTER BLOCK + 0x1fb82 => self.draw_block(canvas, Alignment.upper, 1, one_quarter), + // '🮃' UPPER THREE EIGHTHS BLOCK + 0x1fb83 => self.draw_block(canvas, Alignment.upper, 1, three_eighths), + // '🮄' UPPER FIVE EIGHTHS BLOCK + 0x1fb84 => self.draw_block(canvas, Alignment.upper, 1, five_eighths), + // '🮅' UPPER THREE QUARTERS BLOCK + 0x1fb85 => self.draw_block(canvas, Alignment.upper, 1, three_quarters), + // '🮆' UPPER SEVEN EIGHTHS BLOCK + 0x1fb86 => self.draw_block(canvas, Alignment.upper, 1, seven_eighths), - 0x1fb7c => self.draw_left_and_lower_one_eighth_block(canvas), - 0x1fb7d => self.draw_left_and_upper_one_eighth_block(canvas), - 0x1fb7e => self.draw_right_and_upper_one_eighth_block(canvas), - 0x1fb7f => self.draw_right_and_lower_one_eighth_block(canvas), - 0x1fb80 => self.draw_upper_and_lower_one_eighth_block(canvas), + // '🭼' LEFT AND LOWER ONE EIGHTH BLOCK + 0x1fb7c => { + self.draw_block(canvas, Alignment.left, one_eighth, 1); + self.draw_block(canvas, Alignment.lower, 1, one_eighth); + }, + // '🭽' LEFT AND UPPER ONE EIGHTH BLOCK + 0x1fb7d => { + self.draw_block(canvas, Alignment.left, one_eighth, 1); + self.draw_block(canvas, Alignment.upper, 1, one_eighth); + }, + // '🭾' RIGHT AND UPPER ONE EIGHTH BLOCK + 0x1fb7e => { + self.draw_block(canvas, Alignment.right, one_eighth, 1); + self.draw_block(canvas, Alignment.upper, 1, one_eighth); + }, + // '🭿' RIGHT AND LOWER ONE EIGHTH BLOCK + 0x1fb7f => { + self.draw_block(canvas, Alignment.right, one_eighth, 1); + self.draw_block(canvas, Alignment.lower, 1, one_eighth); + }, + // '🮀' UPPER AND LOWER ONE EIGHTH BLOCK + 0x1fb80 => { + self.draw_block(canvas, Alignment.upper, 1, one_eighth); + self.draw_block(canvas, Alignment.lower, 1, one_eighth); + }, + // '🮁' 0x1fb81 => self.draw_horizontal_one_eighth_1358_block(canvas), - 0x1fb87 => self.draw_right_one_quarter_block(canvas), - 0x1fb88 => self.draw_right_three_eighths_block(canvas), - 0x1fb89 => self.draw_right_five_eighths_block(canvas), - 0x1fb8a => self.draw_right_three_quarters_block(canvas), - 0x1fb8b => self.draw_right_seven_eighths_block(canvas), + // '🮇' RIGHT ONE QUARTER BLOCK + 0x1fb87 => self.draw_block(canvas, Alignment.right, one_quarter, 1), + // '🮈' RIGHT THREE EIGHTHS BLOCK + 0x1fb88 => self.draw_block(canvas, Alignment.right, three_eighths, 1), + // '🮉' RIGHT FIVE EIGHTHS BLOCK + 0x1fb89 => self.draw_block(canvas, Alignment.right, five_eighths, 1), + // '🮊' RIGHT THREE QUARTERS BLOCK + 0x1fb8a => self.draw_block(canvas, Alignment.right, three_quarters, 1), + // '🮋' RIGHT SEVEN EIGHTHS BLOCK + 0x1fb8b => self.draw_block(canvas, Alignment.right, seven_eighths, 1), // Not official box characters but special characters we hide // in the high bits of a unicode codepoint. @@ -329,20 +584,143 @@ fn draw(self: Box, alloc: Allocator, canvas: *font.sprite.Canvas, cp: u32) !void } } -fn draw_light_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); -} +fn draw_lines(self: Box, canvas: *font.sprite.Canvas, comptime lines: Lines) void { + const light_px = Thickness.light.height(self.thickness); + const heavy_px = Thickness.heavy.height(self.thickness); -fn draw_heavy_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); -} + // Top of light horizontal strokes + const h_light_top = (self.height -| light_px) / 2; + // Bottom of light horizontal strokes + const h_light_bottom = h_light_top +| light_px; -fn draw_light_vertical(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle(canvas, .light); -} + // Top of heavy horizontal strokes + const h_heavy_top = (self.height -| heavy_px) / 2; + // Bottom of heavy horizontal strokes + const h_heavy_bottom = h_heavy_top +| heavy_px; -fn draw_heavy_vertical(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle(canvas, .heavy); + // Top of the top doubled horizontal stroke (bottom is `h_light_top`) + const h_double_top = h_light_top -| light_px; + // Bottom of the bottom doubled horizontal stroke (top is `h_light_bottom`) + const h_double_bottom = h_light_bottom +| light_px; + + // Left of light vertical strokes + const v_light_left = (self.width -| light_px) / 2; + // Right of light vertical strokes + const v_light_right = v_light_left +| light_px; + + // Left of heavy vertical strokes + const v_heavy_left = (self.width -| heavy_px) / 2; + // Right of heavy vertical strokes + const v_heavy_right = v_heavy_left +| heavy_px; + + // Left of the left doubled vertical stroke (right is `v_light_left`) + const v_double_left = v_light_left -| light_px; + // Right of the right doubled vertical stroke (left is `v_light_right`) + const v_double_right = v_light_right +| light_px; + + // The bottom of the up line + const up_bottom = if (lines.left == .heavy or lines.right == .heavy) + h_heavy_bottom + else if (lines.left != lines.right or lines.down == lines.up) + if (lines.left == .double or lines.right == .double) + h_double_bottom + else + h_light_bottom + else if (lines.left == .none and lines.right == .none) + h_light_bottom + else + h_light_top; + + // The top of the down line + const down_top = if (lines.left == .heavy or lines.right == .heavy) + h_heavy_top + else if (lines.left != lines.right or lines.up == lines.down) + if (lines.left == .double or lines.right == .double) + h_double_top + else + h_light_top + else if (lines.left == .none and lines.right == .none) + h_light_top + else + h_light_bottom; + + // The right of the left line + const left_right = if (lines.up == .heavy or lines.down == .heavy) + v_heavy_right + else if (lines.up != lines.down or lines.left == lines.right) + if (lines.up == .double or lines.down == .double) + v_double_right + else + v_light_right + else if (lines.up == .none and lines.down == .none) + v_light_right + else + v_light_left; + + // The left of the right line + const right_left = if (lines.up == .heavy or lines.down == .heavy) + v_heavy_left + else if (lines.up != lines.down or lines.right == lines.left) + if (lines.up == .double or lines.down == .double) + v_double_left + else + v_light_left + else if (lines.up == .none and lines.down == .none) + v_light_left + else + v_light_right; + + switch (lines.up) { + .none => {}, + .light => self.rect(canvas, v_light_left, 0, v_light_right, up_bottom), + .heavy => self.rect(canvas, v_heavy_left, 0, v_heavy_right, up_bottom), + .double => { + const left_bottom = if (lines.left == .double) h_light_top else up_bottom; + const right_bottom = if (lines.right == .double) h_light_top else up_bottom; + + self.rect(canvas, v_double_left, 0, v_light_left, left_bottom); + self.rect(canvas, v_light_right, 0, v_double_right, right_bottom); + }, + } + + switch (lines.right) { + .none => {}, + .light => self.rect(canvas, right_left, h_light_top, self.width, h_light_bottom), + .heavy => self.rect(canvas, right_left, h_heavy_top, self.width, h_heavy_bottom), + .double => { + const top_left = if (lines.up == .double) v_light_right else right_left; + const bottom_left = if (lines.down == .double) v_light_right else right_left; + + self.rect(canvas, top_left, h_double_top, self.width, h_light_top); + self.rect(canvas, bottom_left, h_light_bottom, self.width, h_double_bottom); + }, + } + + switch (lines.down) { + .none => {}, + .light => self.rect(canvas, v_light_left, down_top, v_light_right, self.height), + .heavy => self.rect(canvas, v_heavy_left, down_top, v_heavy_right, self.height), + .double => { + const left_top = if (lines.left == .double) h_light_bottom else down_top; + const right_top = if (lines.right == .double) h_light_bottom else down_top; + + self.rect(canvas, v_double_left, left_top, v_light_left, self.height); + self.rect(canvas, v_light_right, right_top, v_double_right, self.height); + }, + } + + switch (lines.left) { + .none => {}, + .light => self.rect(canvas, 0, h_light_top, left_right, h_light_bottom), + .heavy => self.rect(canvas, 0, h_heavy_top, left_right, h_heavy_bottom), + .double => { + const top_right = if (lines.up == .double) v_light_left else left_right; + const bottom_right = if (lines.down == .double) v_light_left else left_right; + + self.rect(canvas, 0, h_double_top, top_right, h_light_top); + self.rect(canvas, 0, h_light_bottom, bottom_right, h_double_bottom); + }, + } } fn draw_light_triple_dash_horizontal(self: Box, canvas: *font.sprite.Canvas) void { @@ -417,358 +795,6 @@ fn draw_heavy_quadruple_dash_vertical(self: Box, canvas: *font.sprite.Canvas) vo ); } -fn draw_light_down_and_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_light_and_right_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_heavy_and_right_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .light); -} - -fn draw_heavy_down_and_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_light_down_and_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_light_and_left_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_heavy_and_left_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .light); -} - -fn draw_heavy_down_and_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_light_up_and_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_up_light_and_right_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .heavy); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_up_heavy_and_right_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .heavy, .light); -} - -fn draw_heavy_up_and_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); -} - -fn draw_light_up_and_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_up_light_and_left_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .heavy); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_up_heavy_and_left_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle_up(canvas, .heavy, .light); -} - -fn draw_heavy_up_and_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); -} - -fn draw_light_vertical_and_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle(canvas, .light); -} - -fn draw_vertical_light_and_right_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .heavy); - self.vline_middle(canvas, .light); -} - -fn draw_up_heavy_and_right_down_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .heavy, .light); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_heavy_and_right_up_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .light); -} - -fn draw_vertical_heavy_and_right_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); - self.vline_middle(canvas, .heavy); -} - -fn draw_down_light_and_right_up_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_up_light_and_right_down_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_heavy_vertical_and_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle(canvas, .heavy); -} - -fn draw_light_vertical_and_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle(canvas, .light); -} - -fn draw_vertical_light_and_left_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .heavy); - self.vline_middle(canvas, .light); -} - -fn draw_up_heavy_and_left_down_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle_up(canvas, .heavy, .light); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_heavy_and_left_up_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .light); -} - -fn draw_vertical_heavy_and_left_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.vline_middle(canvas, .heavy); -} - -fn draw_down_light_and_left_up_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_up_light_and_left_down_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_heavy_vertical_and_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.vline_middle(canvas, .heavy); -} - -fn draw_light_down_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_left_heavy_and_right_down_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_right_heavy_and_left_down_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .light, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_light_and_horizontal_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_heavy_and_horizontal_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_down(canvas, .heavy, .light); -} - -fn draw_right_light_and_left_down_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_left_light_and_right_down_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_heavy_down_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_light_up_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_left_heavy_and_right_up_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_right_heavy_and_left_up_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .light, .heavy); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_up_light_and_horizontal_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_up(canvas, .light, .light); -} - -fn draw_up_heavy_and_horizontal_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_up(canvas, .heavy, .light); -} - -fn draw_right_light_and_left_up_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .heavy, .heavy); -} - -fn draw_left_light_and_right_up_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); -} - -fn draw_heavy_up_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); -} - -fn draw_light_vertical_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle(canvas, .light); -} - -fn draw_left_heavy_and_right_vertical_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle(canvas, .light); -} - -fn draw_right_heavy_and_left_vertical_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .light, .heavy); - self.vline_middle(canvas, .light); -} - -fn draw_vertical_light_and_horizontal_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle(canvas, .light); -} - -fn draw_up_heavy_and_down_horizontal_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_down_heavy_and_up_horizontal_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .light); -} - -fn draw_vertical_heavy_and_horizontal_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .light); - self.vline_middle(canvas, .heavy); -} - -fn draw_left_up_heavy_and_right_down_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_right_up_heavy_and_left_down_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_left_down_heavy_and_right_up_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_right_down_heavy_and_left_up_light(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_down_light_and_up_horizontal_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_up_light_and_down_horizontal_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_right_light_and_left_vertical_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.hline_middle_right(canvas, .light, .light); - self.vline_middle(canvas, .heavy); -} - -fn draw_left_light_and_right_vertical_heavy(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .heavy, .heavy); - self.vline_middle(canvas, .heavy); -} - -fn draw_heavy_vertical_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle(canvas, .heavy); - self.vline_middle(canvas, .heavy); -} - fn draw_light_double_dash_horizontal(self: Box, canvas: *font.sprite.Canvas) void { self.draw_dash_horizontal( canvas, @@ -805,275 +831,6 @@ fn draw_heavy_double_dash_vertical(self: Box, canvas: *font.sprite.Canvas) void ); } -fn draw_double_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const mid = (self.height -| thick_px * 3) / 2; - self.hline(canvas, 0, self.width, mid, thick_px); - self.hline(canvas, 0, self.width, mid + 2 * thick_px, thick_px); -} - -fn draw_double_vertical(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const mid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, 0, self.height, mid, thick_px); - self.vline(canvas, 0, self.height, mid + 2 * thick_px, thick_px); -} - -fn draw_down_single_and_right_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px) / 2; - self.vline_middle_down(canvas, .light, .light); - self.hline(canvas, vmid, self.width, hmid, thick_px); - self.hline(canvas, vmid, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_down_double_and_right_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle_right(canvas, .light, .light); - self.vline(canvas, hmid, self.height, vmid, thick_px); - self.vline(canvas, hmid, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_down_and_right(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, hmid, self.height, vmid, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid + 2 * thick_px, thick_px); - self.hline(canvas, vmid, self.width, hmid, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_down_single_and_left_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width + thick_px) / 2; - self.vline_middle_down(canvas, .light, .light); - self.hline(canvas, 0, vmid, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); -} - -fn draw_down_double_and_left_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle_left(canvas, .light, .light); - self.vline(canvas, hmid, self.height, vmid, thick_px); - self.vline(canvas, hmid, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_down_and_left(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid, thick_px); - self.vline(canvas, hmid, self.height, vmid + 2 * thick_px, thick_px); - self.hline(canvas, 0, vmid + 2 * thick_px, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); -} - -fn draw_up_single_and_right_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px) / 2; - self.vline_middle_up(canvas, .light, .light); - self.hline(canvas, vmid, self.width, hmid, thick_px); - self.hline(canvas, vmid, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_up_double_and_right_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height + thick_px) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle_right(canvas, .light, .light); - self.vline(canvas, 0, hmid, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_up_and_right(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, 0, hmid + 2 * thick_px, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid, thick_px); - self.hline(canvas, vmid, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_up_single_and_left_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width + thick_px) / 2; - self.vline_middle_up(canvas, .light, .light); - self.hline(canvas, 0, vmid, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); -} - -fn draw_up_double_and_left_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height + thick_px) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle_left(canvas, .light, .light); - self.vline(canvas, 0, hmid, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_up_and_left(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, 0, hmid + 0 * thick_px + thick_px, vmid, thick_px); - self.vline(canvas, 0, hmid + 2 * thick_px + thick_px, vmid + 2 * thick_px, thick_px); - self.hline(canvas, 0, vmid, hmid, thick_px); - self.hline(canvas, 0, vmid + 2 * thick_px, hmid + 2 * thick_px, thick_px); -} - -fn draw_vertical_single_and_right_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px) / 2; - self.vline_middle(canvas, .light); - self.hline(canvas, vmid, self.width, hmid, thick_px); - self.hline(canvas, vmid, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_vertical_double_and_right_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const vmid = (self.width -| thick_px * 3) / 2; - self.hline(canvas, vmid + 2 * thick_px, self.width, (self.height -| thick_px) / 2, thick_px); - self.vline(canvas, 0, self.height, vmid, thick_px); - self.vline(canvas, 0, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_vertical_and_right(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, 0, self.height, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid + 2 * thick_px, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_vertical_single_and_left_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width + thick_px) / 2; - self.vline_middle(canvas, .light); - self.hline(canvas, 0, vmid, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); -} - -fn draw_vertical_double_and_left_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const vmid = (self.width -| thick_px * 3) / 2; - self.hline(canvas, 0, vmid, (self.height -| thick_px) / 2, thick_px); - self.vline(canvas, 0, self.height, vmid, thick_px); - self.vline(canvas, 0, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_vertical_and_left(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, 0, self.height, vmid + 2 * thick_px, thick_px); - self.vline(canvas, 0, hmid, vmid, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid, thick_px); - self.hline(canvas, 0, vmid + thick_px, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); -} - -fn draw_down_single_and_horizontal_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - self.vline(canvas, hmid + 2 * thick_px, self.height, (self.width -| thick_px) / 2, thick_px); - self.hline(canvas, 0, self.width, hmid, thick_px); - self.hline(canvas, 0, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_down_double_and_horizontal_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle(canvas, .light); - self.vline(canvas, hmid, self.height, vmid, thick_px); - self.vline(canvas, hmid, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_down_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline(canvas, 0, self.width, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid + 2 * thick_px, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_up_single_and_horizontal_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px) / 2; - self.vline(canvas, 0, hmid, vmid, thick_px); - self.hline(canvas, 0, self.width, hmid, thick_px); - self.hline(canvas, 0, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_up_double_and_horizontal_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle(canvas, .light); - self.vline(canvas, 0, hmid, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_up_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.vline(canvas, 0, hmid, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); - self.hline(canvas, 0, vmid + thick_px, hmid, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid, thick_px); - self.hline(canvas, 0, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_vertical_single_and_horizontal_double(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - self.vline_middle(canvas, .light); - self.hline(canvas, 0, self.width, hmid, thick_px); - self.hline(canvas, 0, self.width, hmid + 2 * thick_px, thick_px); -} - -fn draw_vertical_double_and_horizontal_single(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const vmid = (self.width -| thick_px * 3) / 2; - self.hline_middle(canvas, .light); - self.vline(canvas, 0, self.height, vmid, thick_px); - self.vline(canvas, 0, self.height, vmid + 2 * thick_px, thick_px); -} - -fn draw_double_vertical_and_horizontal(self: Box, canvas: *font.sprite.Canvas) void { - const thick_px = Thickness.light.height(self.thickness); - const hmid = (self.height -| thick_px * 3) / 2; - const vmid = (self.width -| thick_px * 3) / 2; - self.hline(canvas, 0, vmid, hmid, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid, thick_px); - self.hline(canvas, 0, vmid, hmid + 2 * thick_px, thick_px); - self.hline(canvas, vmid + 2 * thick_px, self.width, hmid + 2 * thick_px, thick_px); - self.vline(canvas, 0, hmid + thick_px, vmid, thick_px); - self.vline(canvas, 0, hmid, vmid + 2 * thick_px, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid, thick_px); - self.vline(canvas, hmid + 2 * thick_px, self.height, vmid + 2 * thick_px, thick_px); -} - fn draw_light_diagonal_upper_right_to_lower_left(self: Box, canvas: *font.sprite.Canvas) void { const thick_px = Thickness.light.height(self.thickness); canvas.trapezoid(.{ @@ -1139,254 +896,48 @@ fn draw_light_diagonal_cross(self: Box, canvas: *font.sprite.Canvas) void { self.draw_light_diagonal_upper_left_to_lower_right(canvas); } -fn draw_light_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); -} +fn draw_block( + self: Box, + canvas: *font.sprite.Canvas, + alignment: Alignment, + width: f64, + height: f64, +) void { + const float_width: f64 = @floatFromInt(self.width); + const float_height: f64 = @floatFromInt(self.height); -fn draw_light_up(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle_up(canvas, .light, .light); -} + const w: u32 = @intFromFloat(@round(float_width * width)); + const h: u32 = @intFromFloat(@round(float_height * height)); -fn draw_light_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .light, .light); -} + const x = switch (alignment.horizontal) { + .left => 0, + .right => self.width - w, + .center => (self.width - w) / 2, + }; + const y = switch (alignment.vertical) { + .top => 0, + .bottom => self.height - h, + .middle => (self.height - h) / 2, + }; -fn draw_light_down(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_heavy_left(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); -} - -fn draw_heavy_up(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle_up(canvas, .heavy, .heavy); -} - -fn draw_heavy_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_right(canvas, .heavy, .heavy); -} - -fn draw_heavy_down(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_light_left_and_heavy_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .light, .light); - self.hline_middle_right(canvas, .heavy, .heavy); -} - -fn draw_light_up_and_heavy_down(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle_up(canvas, .light, .light); - self.vline_middle_down(canvas, .heavy, .heavy); -} - -fn draw_heavy_left_and_light_right(self: Box, canvas: *font.sprite.Canvas) void { - self.hline_middle_left(canvas, .heavy, .heavy); - self.hline_middle_right(canvas, .light, .light); -} - -fn draw_heavy_up_and_light_down(self: Box, canvas: *font.sprite.Canvas) void { - self.vline_middle_up(canvas, .heavy, .heavy); - self.vline_middle_down(canvas, .light, .light); -} - -fn draw_upper_half_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect(canvas, 0, 0, self.width, self.height / 2); -} - -fn draw_lower_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect(canvas, 0, self.height -| (self.height / 8), self.width, self.height); -} - -fn draw_lower_one_quarter_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect(canvas, 0, self.height -| (self.height / 4), self.width, self.height); -} - -fn draw_lower_three_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - self.height -| @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.height)) / 8))), - self.width, - self.height, - ); -} - -fn draw_lower_half_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - self.height -| @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.height)) / 2))), - self.width, - self.height, - ); -} - -fn draw_lower_five_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - self.height -| @as(u32, @intFromFloat(@round(5 * @as(f64, @floatFromInt(self.height)) / 8))), - self.width, - self.height, - ); -} - -fn draw_lower_three_quarters_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - self.height -| @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.height)) / 4))), - self.width, - self.height, - ); -} - -fn draw_lower_seven_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - self.height -| @as(u32, @intFromFloat(@round(7 * @as(f64, @floatFromInt(self.height)) / 8))), - self.width, - self.height, - ); -} - -fn draw_upper_one_quarter_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - self.width, - @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.height)) / 4))), - ); -} - -fn draw_upper_three_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - self.width, - @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.height)) / 8))), - ); -} - -fn draw_upper_five_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - self.width, - @as(u32, @intFromFloat(@round(5 * @as(f64, @floatFromInt(self.height)) / 8))), - ); -} - -fn draw_upper_three_quarters_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - self.width, - @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.height)) / 4))), - ); -} - -fn draw_upper_seven_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - self.width, - @as(u32, @intFromFloat(@round(7 * @as(f64, @floatFromInt(self.height)) / 8))), - ); + canvas.rect(.{ + .x = @intCast(x), + .y = @intCast(y), + .width = w, + .height = h, + }, .on); } fn draw_full_block(self: Box, canvas: *font.sprite.Canvas) void { self.rect(canvas, 0, 0, self.width, self.height); } -fn draw_left_seven_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@round(7 * @as(f64, @floatFromInt(self.width)) / 8))), - self.height, - ); -} - -fn draw_left_three_quarters_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.width)) / 4))), - self.height, - ); -} - -fn draw_left_five_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@round(5 * @as(f64, @floatFromInt(self.width)) / 8))), - self.height, - ); -} - -fn draw_left_half_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.width)) / 2))), - self.height, - ); -} - -fn draw_left_three_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.width)) / 8))), - self.height, - ); -} - -fn draw_left_one_quarter_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.width)) / 4))), - self.height, - ); -} - fn draw_vertical_one_eighth_block_n(self: Box, canvas: *font.sprite.Canvas, n: u32) void { const x = @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(n)) * @as(f64, @floatFromInt(self.width)) / 8))); const w = @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.width)) / 8))); self.rect(canvas, x, 0, x + w, self.height); } -fn draw_left_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_vertical_one_eighth_block_n(canvas, 0); -} - -fn draw_right_half_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.width)) / 2))), - 0, - self.width, - self.height, - ); -} - fn draw_pixman_shade(self: Box, canvas: *font.sprite.Canvas, v: u16) void { canvas.rect((font.sprite.Box{ .x1 = 0, @@ -1409,145 +960,19 @@ fn draw_dark_shade(self: Box, canvas: *font.sprite.Canvas) void { } fn draw_horizontal_one_eighth_block_n(self: Box, canvas: *font.sprite.Canvas, n: u32) void { - const y = @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(n)) * @as(f64, @floatFromInt(self.height)) / 8))); const h = @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.height)) / 8))); + const y = @min( + self.height -| h, + @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(n)) * @as(f64, @floatFromInt(self.height)) / 8))), + ); self.rect(canvas, 0, y, self.width, y + h); } -fn draw_upper_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_horizontal_one_eighth_block_n(canvas, 0); -} - -fn draw_right_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - self.width -| @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.width)) / 8))), - 0, - self.width, - self.height, - ); -} - -fn draw_left_and_lower_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_left_one_eighth_block(canvas); - self.draw_lower_one_eighth_block(canvas); -} - -fn draw_left_and_upper_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_left_one_eighth_block(canvas); - self.draw_upper_one_eighth_block(canvas); -} - -fn draw_right_and_upper_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_right_one_eighth_block(canvas); - self.draw_upper_one_eighth_block(canvas); -} - -fn draw_right_and_lower_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_right_one_eighth_block(canvas); - self.draw_lower_one_eighth_block(canvas); -} - -fn draw_upper_and_lower_one_eighth_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_upper_one_eighth_block(canvas); - self.draw_lower_one_eighth_block(canvas); -} - fn draw_horizontal_one_eighth_1358_block(self: Box, canvas: *font.sprite.Canvas) void { - self.draw_upper_one_eighth_block(canvas); + self.draw_horizontal_one_eighth_block_n(canvas, 0); self.draw_horizontal_one_eighth_block_n(canvas, 2); self.draw_horizontal_one_eighth_block_n(canvas, 4); - self.draw_lower_one_eighth_block(canvas); -} - -fn draw_right_one_quarter_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - self.width -| @as(u32, @intFromFloat(@round(@as(f64, @floatFromInt(self.width)) / 4))), - 0, - self.width, - self.height, - ); -} - -fn draw_right_three_quarters_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - self.width -| @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.width)) / 4))), - 0, - self.width, - self.height, - ); -} - -fn draw_right_three_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - self.width -| @as(u32, @intFromFloat(@round(3 * @as(f64, @floatFromInt(self.width)) / 8))), - 0, - self.width, - self.height, - ); -} - -fn draw_right_five_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - self.width -| @as(u32, @intFromFloat(@round(5 * @as(f64, @floatFromInt(self.width)) / 8))), - 0, - self.width, - self.height, - ); -} - -fn draw_right_seven_eighths_block(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - self.width -| @as(u32, @intFromFloat(@round(7 * @as(f64, @floatFromInt(self.width)) / 8))), - 0, - self.width, - self.height, - ); -} - -fn quad_upper_left(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - 0, - @as(u32, @intFromFloat(@ceil(@as(f64, @floatFromInt(self.width)) / 2))), - @as(u32, @intFromFloat(@ceil(@as(f64, @floatFromInt(self.height)) / 2))), - ); -} - -fn quad_upper_right(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - @as(u32, @intFromFloat(@floor(@as(f64, @floatFromInt(self.width)) / 2))), - 0, - self.width, - @as(u32, @intFromFloat(@ceil(@as(f64, @floatFromInt(self.height)) / 2))), - ); -} - -fn quad_lower_left(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - 0, - @as(u32, @intFromFloat(@floor(@as(f64, @floatFromInt(self.height)) / 2))), - @as(u32, @intFromFloat(@ceil(@as(f64, @floatFromInt(self.width)) / 2))), - self.height, - ); -} - -fn quad_lower_right(self: Box, canvas: *font.sprite.Canvas) void { - self.rect( - canvas, - @as(u32, @intFromFloat(@floor(@as(f64, @floatFromInt(self.width)) / 2))), - @as(u32, @intFromFloat(@floor(@as(f64, @floatFromInt(self.height)) / 2))), - self.width, - self.height, - ); + self.draw_horizontal_one_eighth_block_n(canvas, 7); } fn draw_quadrant(self: Box, canvas: *font.sprite.Canvas, cp: u32) void { @@ -1572,10 +997,10 @@ fn draw_quadrant(self: Box, canvas: *font.sprite.Canvas, cp: u32) void { const idx = cp - 0x2596; const encoded = matrix[idx]; - if (encoded & UPPER_LEFT == UPPER_LEFT) self.quad_upper_left(canvas); - if (encoded & UPPER_RIGHT == UPPER_RIGHT) self.quad_upper_right(canvas); - if (encoded & LOWER_LEFT == LOWER_LEFT) self.quad_lower_left(canvas); - if (encoded & LOWER_RIGHT == LOWER_RIGHT) self.quad_lower_right(canvas); + if (encoded & UPPER_LEFT == UPPER_LEFT) self.draw_block(canvas, .{ .horizontal = .left, .vertical = .top }, 0.5, 0.5); + if (encoded & UPPER_RIGHT == UPPER_RIGHT) self.draw_block(canvas, .{ .horizontal = .right, .vertical = .top }, 0.5, 0.5); + if (encoded & LOWER_LEFT == LOWER_LEFT) self.draw_block(canvas, .{ .horizontal = .left, .vertical = .bottom }, 0.5, 0.5); + if (encoded & LOWER_RIGHT == LOWER_RIGHT) self.draw_block(canvas, .{ .horizontal = .right, .vertical = .bottom }, 0.5, 0.5); } fn draw_braille(self: Box, canvas: *font.sprite.Canvas, cp: u32) void { @@ -2598,79 +2023,11 @@ fn vline_middle(self: Box, canvas: *font.sprite.Canvas, thickness: Thickness) vo self.vline(canvas, 0, self.height, (self.width -| thick_px) / 2, thick_px); } -fn vline_middle_up( - self: Box, - canvas: *font.sprite.Canvas, - vthickness: Thickness, - hthickness: Thickness, -) void { - const hthick_px = hthickness.height(self.thickness); - const vthick_px = vthickness.height(self.thickness); - self.vline( - canvas, - 0, - (self.height + hthick_px) / 2, - (self.width -| vthick_px) / 2, - vthick_px, - ); -} - -fn vline_middle_down( - self: Box, - canvas: *font.sprite.Canvas, - vthickness: Thickness, - hthickness: Thickness, -) void { - const hthick_px = hthickness.height(self.thickness); - const vthick_px = vthickness.height(self.thickness); - self.vline( - canvas, - (self.height -| hthick_px) / 2, - self.height, - (self.width -| vthick_px) / 2, - vthick_px, - ); -} - fn hline_middle(self: Box, canvas: *font.sprite.Canvas, thickness: Thickness) void { const thick_px = thickness.height(self.thickness); self.hline(canvas, 0, self.width, (self.height -| thick_px) / 2, thick_px); } -fn hline_middle_left( - self: Box, - canvas: *font.sprite.Canvas, - vthickness: Thickness, - hthickness: Thickness, -) void { - const hthick_px = hthickness.height(self.thickness); - const vthick_px = vthickness.height(self.thickness); - self.hline( - canvas, - 0, - (self.width + vthick_px) / 2, - (self.height -| hthick_px) / 2, - hthick_px, - ); -} - -fn hline_middle_right( - self: Box, - canvas: *font.sprite.Canvas, - vthickness: Thickness, - hthickness: Thickness, -) void { - const hthick_px = hthickness.height(self.thickness); - const vthick_px = vthickness.height(self.thickness); - self.hline( - canvas, - (self.width -| vthick_px) / 2, - self.width, - (self.height -| hthick_px) / 2, - hthick_px, - ); -} - fn vline( self: Box, canvas: *font.sprite.Canvas, @@ -2724,7 +2081,7 @@ test "all" { const alloc = testing.allocator; var cp: u32 = 0x2500; - const end = 0x2570; + const end = 0x259f; while (cp <= end) : (cp += 1) { var atlas_grayscale = try font.Atlas.init(alloc, 512, .grayscale); defer atlas_grayscale.deinit(alloc); @@ -2803,10 +2160,20 @@ test "render all sprites" { } } - // Dump to PPM file for visual examination - // Uncomment whenever a new ground truth needs to be created. - const ppm = try std.fs.cwd().createFile("Box.ppm", .{}); - defer ppm.close(); + const ground_truth = @embedFile("./testdata/Box.ppm"); - try atlas_grayscale.dump(ppm.writer()); + var stream = std.io.changeDetectionStream(ground_truth, std.io.null_writer); + try atlas_grayscale.dump(stream.writer()); + + if (stream.changeDetected()) { + log.err( + "Change detected from ground truth, dumping to ./Box_test.ppm for comparison.", + .{}, + ); + + const ppm = try std.fs.cwd().createFile("Box_test.ppm", .{}); + defer ppm.close(); + + try atlas_grayscale.dump(ppm.writer()); + } } diff --git a/src/font/sprite/testdata/Box.ppm b/src/font/sprite/testdata/Box.ppm new file mode 100644 index 0000000000000000000000000000000000000000..676b07ebea775e35eb23bf1d5095343bb53d5300 GIT binary patch literal 1048593 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 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c z4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C z(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S`WG8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF z0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71* zAut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@? z8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiQ~ zMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ON zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU z1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0q zLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$( zGz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ON zU^E0q!DtAKhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD zjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By z2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1J zhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kin zXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD zjE2By2#kinC>RZa(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C z(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c z4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C z(GVC7fzc2c4S~@R7zLvtFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@? z8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF z0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71* zAut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@? z8UmvsFd71*Aut*OqaiRF0;6Cw1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0q zLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$( zGz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ON zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU z1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0q zLtr!nMnhmU1V%$(Gz3ONU^E0qLtqq)hQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By z2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1J zhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kin zXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeD zjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By z2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mg(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c z4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C z(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R z7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!85Z5Eu=C(GVC7 zfzc2c4S~@R7!85Z5Eu=C(GVC7fzc2c4S~@R7!83@Fd71*Aut*OqaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF z0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71* zAut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@? z8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*O zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?3PwX