Notcurses-Native.git | xt/ | 03-cell-channel.rakutest edit


use Test;
use lib 'lib';
use lib 't/lib';
use TestHelper;
use NativeCall;
use Notcurses::Native;
use Notcurses::Native::Types;
use Notcurses::Native::Plane;
use Notcurses::Native::Cell;
use Notcurses::Native::Channel;

plan 10;


my $opts = NotcursesOptions.new(
	:loglevel(NCLOGLEVEL_SILENT),
	:flags(NCOPTION_SUPPRESS_BANNERS +| NCOPTION_NO_ALTERNATE_SCREEN +| NCOPTION_INHIBIT_SETLOCALE),
);
my ($nc, $) = test-init-nc($opts);
unless $nc.defined {
	skip 'No terminal available', 10;
	exit 0;
}
LEAVE { notcurses_stop($nc) if $nc.defined }
my $std = notcurses_stdplane($nc);

# === Channel math (pure computation) ===

subtest 'Dual channel set/get RGB' => {
	plan 4;
	my uint64 $channels = 0;
	ncchannels_set_fg_rgb($channels, 0xFF0000);
	ncchannels_set_bg_rgb($channels, 0x00FF00);
	is ncchannels_fg_rgb($channels), 0xFF0000, 'FG red';
	is ncchannels_bg_rgb($channels), 0x00FF00, 'BG green';
	ncchannels_set_fg_rgb8($channels, 0, 0, 255);
	is ncchannels_fg_rgb($channels), 0x0000FF, 'FG blue via rgb8';
	ncchannels_set_bg_rgb8($channels, 128, 128, 128);
	is ncchannels_bg_rgb($channels), 0x808080, 'BG grey via rgb8';
};

subtest 'Dual channel alpha' => {
	plan 2;
	my uint64 $channels = 0;
	my $BLEND = 0x10000000;
	my $TRANSPARENT = 0x20000000;
	ncchannels_set_fg_alpha($channels, $BLEND);
	is ncchannels_fg_alpha($channels), $BLEND, 'FG alpha BLEND';
	ncchannels_set_bg_alpha($channels, $TRANSPARENT);
	is ncchannels_bg_alpha($channels), $TRANSPARENT, 'BG alpha TRANSPARENT';
};

subtest 'Single channel operations' => {
	plan 4;
	my uint32 $ch = 0;
	ncchannel_set($ch, 0xABCDEF);
	is ncchannel_rgb($ch), 0xABCDEF, 'Channel RGB set/get';
	is ncchannel_r($ch), 0xAB, 'Red component';
	is ncchannel_g($ch), 0xCD, 'Green component';
	is ncchannel_b($ch), 0xEF, 'Blue component';
};

subtest 'Channel combine/reverse' => {
	plan 2;
	my $combined = ncchannels_combine(0xFF0000, 0x00FF00);
	is ncchannels_fg_rgb($combined), 0xFF0000, 'Combined FG';
	my $reversed = ncchannels_reverse($combined);
	is ncchannels_fg_rgb($reversed), 0x00FF00, 'Reversed FG = old BG';
};

subtest 'Channel defaults' => {
	plan 2;
	my uint64 $channels = 0;
	ncchannels_set_fg_rgb($channels, 0xFF0000);
	ncchannels_set_fg_default($channels);
	ok ncchannels_fg_default_p($channels), 'FG default set';
	ncchannels_set_bg_default($channels);
	ok ncchannels_bg_default_p($channels), 'BG default set';
};

subtest 'Pixel operations' => {
	plan 4;
	my uint32 $px = ncpixel(255, 128, 64);
	is ncpixel_r($px), 255, 'Pixel R';
	is ncpixel_g($px), 128, 'Pixel G';
	is ncpixel_b($px), 64, 'Pixel B';
	ncpixel_set_r($px, 100);
	is ncpixel_r($px), 100, 'Pixel R after set';
};

# === Cell operations ===

subtest 'Cell load and read' => {
	plan 3;
	my $child = ncplane_create($std, NcplaneOptions.new(:rows(5), :cols(20)));
	my $c = Nccell.new;
	my $loaded = nccell_load($child, $c, 'A');
	ok $loaded > 0, "Cell loaded ($loaded bytes)";
	is $c.gcluster +& 0xFF, 'A'.ord, 'Cell gcluster is A';
	my $s = nccell_strdup($child, $c);
	is $s, 'A', 'Cell strdup returns A';
	nccell_release($child, $c);
	ncplane_destroy($child);
};

subtest 'Cell colors' => {
	plan 4;
	my $c = Nccell.new;
	nccell_set_fg_rgb($c, 0xFF0000);
	nccell_set_bg_rgb($c, 0x00FF00);
	is nccell_fg_rgb($c), 0xFF0000, 'Cell FG red';
	is nccell_bg_rgb($c), 0x00FF00, 'Cell BG green';
	nccell_set_fg_rgb8($c, 0, 0, 255);
	is nccell_fg_rgb($c), 0x0000FF, 'Cell FG blue via rgb8';
	ok !nccell_fg_default_p($c), 'Cell FG not default after set';
};

subtest 'Cell styles' => {
	plan 3;
	my $c = Nccell.new;
	nccell_set_styles($c, NCSTYLE_BOLD +| NCSTYLE_ITALIC);
	is nccell_styles($c), NCSTYLE_BOLD +| NCSTYLE_ITALIC, 'Both styles set';
	nccell_off_styles($c, NCSTYLE_BOLD);
	is nccell_styles($c), NCSTYLE_ITALIC, 'Bold removed, italic remains';
	nccell_on_styles($c, NCSTYLE_UNDERLINE);
	is nccell_styles($c), NCSTYLE_ITALIC +| NCSTYLE_UNDERLINE, 'Underline added';
};

subtest 'Cell duplicate' => {
	plan 2;
	my $child = ncplane_create($std, NcplaneOptions.new(:rows(5), :cols(20)));
	my $c = Nccell.new;
	nccell_load($child, $c, 'X');
	nccell_set_fg_rgb($c, 0xABCDEF);
	my $dup = Nccell.new;
	my $rc = nccell_duplicate($child, $dup, $c);
	is $rc, 0, 'Duplicate succeeded';
	is nccell_fg_rgb($dup), 0xABCDEF, 'Duplicate has same FG color';
	nccell_release($child, $c);
	nccell_release($child, $dup);
	ncplane_destroy($child);
};

done-testing;