mirror of
https://github.com/tmux/tmux.git
synced 2026-10-15 15:55:50 +00:00
A couple of missed tests.
This commit is contained in:
@@ -31,6 +31,14 @@ with image_test(sys.argv[1]) as test:
|
|||||||
assert len(client.images()) == 1
|
assert len(client.images()) == 1
|
||||||
check_image(client.images()[0], 8, 16, [rgb] * (8 * 16))
|
check_image(client.images()[0], 8, 16, [rgb] * (8 * 16))
|
||||||
|
|
||||||
|
# Undefined registers are black in the shared image model.
|
||||||
|
test.emit(b'\033[2J\033[H\033P9;1q"1;1;8;16'
|
||||||
|
b'#5!8~-!8~-!8N\033\\')
|
||||||
|
assert len(client.images()) == 1
|
||||||
|
check_image(client.images()[0], 8, 16, [(0, 0, 0)] * (8 * 16))
|
||||||
|
test.redraw()
|
||||||
|
check_image(client.images()[0], 8, 16, [(0, 0, 0)] * (8 * 16))
|
||||||
|
|
||||||
# Deliver the terminator in two pieces. No image is placed before it.
|
# Deliver the terminator in two pieces. No image is placed before it.
|
||||||
test.emit(b'\033[2J\033[H')
|
test.emit(b'\033[2J\033[H')
|
||||||
for byte in valid[:-1]:
|
for byte in valid[:-1]:
|
||||||
|
|||||||
@@ -125,9 +125,11 @@ class Terminal:
|
|||||||
if match is None:
|
if match is None:
|
||||||
break
|
break
|
||||||
if match[1] == b'P':
|
if match[1] == b'P':
|
||||||
image = re.match(rb'[0-9;]*q(.*)', match[2], re.S)
|
image = re.match(rb'([0-9;]*)q(.*)', match[2], re.S)
|
||||||
if image is not None:
|
if image is not None:
|
||||||
w, h, pixels = decode_sixel(image[1])
|
params = image[1].split(b';')
|
||||||
|
p2 = int(params[1] or b'0') if len(params) > 1 else 0
|
||||||
|
w, h, pixels = decode_sixel(image[2], p2)
|
||||||
for i, colour in enumerate(pixels):
|
for i, colour in enumerate(pixels):
|
||||||
if colour is not None:
|
if colour is not None:
|
||||||
self.pixels[self.x * self.cw + i % w,
|
self.pixels[self.x * self.cw + i % w,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
"""Helpers for image tests using an attached client on a PTY."""
|
"""Helpers for image tests using an attached client on a PTY."""
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import colorsys
|
||||||
import errno
|
import errno
|
||||||
import fcntl
|
import fcntl
|
||||||
import itertools
|
import itertools
|
||||||
@@ -46,8 +47,13 @@ class Client:
|
|||||||
|
|
||||||
def images(self):
|
def images(self):
|
||||||
"""Decode complete SIXEL sequences from the terminal output."""
|
"""Decode complete SIXEL sequences from the terminal output."""
|
||||||
return [decode_sixel(body) for body in re.findall(
|
images = []
|
||||||
rb"\033P[0-9;]*q(.*?)\033\\", self.data, re.S)]
|
for params, body in re.findall(
|
||||||
|
rb"\033P([0-9;]*)q(.*?)\033\\", self.data, re.S):
|
||||||
|
params = params.split(b";")
|
||||||
|
p2 = int(params[1] or b"0") if len(params) > 1 else 0
|
||||||
|
images.append(decode_sixel(body, p2))
|
||||||
|
return images
|
||||||
|
|
||||||
|
|
||||||
class ImageTest:
|
class ImageTest:
|
||||||
@@ -234,12 +240,12 @@ def sixel(w, h, palette, pixels, p2=1):
|
|||||||
return "".join(out).encode()
|
return "".join(out).encode()
|
||||||
|
|
||||||
|
|
||||||
def decode_sixel(body):
|
def decode_sixel(body, p2=1):
|
||||||
"""Read RGB output pixels without using tmux's SIXEL decoder."""
|
"""Read RGB output pixels without using tmux's SIXEL decoder."""
|
||||||
attributes = re.match(rb'"1;1;(\d+);(\d+)', body)
|
attributes = re.match(rb'"1;1;(\d+);(\d+)', body)
|
||||||
assert attributes is not None, ("missing raster attributes", body[:80])
|
assert attributes is not None, ("missing raster attributes", body[:80])
|
||||||
w, h = map(int, attributes.groups())
|
w, h = map(int, attributes.groups())
|
||||||
pixels = [None] * (w * h)
|
pixels = [None if p2 == 1 else (0, 0, 0)] * (w * h)
|
||||||
palette = {}
|
palette = {}
|
||||||
c = x = y = 0
|
c = x = y = 0
|
||||||
pos = attributes.end()
|
pos = attributes.end()
|
||||||
@@ -247,13 +253,19 @@ def decode_sixel(body):
|
|||||||
ch = body[pos]
|
ch = body[pos]
|
||||||
pos += 1
|
pos += 1
|
||||||
if ch == ord("#"):
|
if ch == ord("#"):
|
||||||
match = re.match(rb"(\d+)(?:;2;(\d+);(\d+);(\d+))?", body[pos:])
|
match = re.match(rb"(\d+)(?:;([12]);(\d+);(\d+);(\d+))?", body[pos:])
|
||||||
assert match is not None, body[pos:pos + 80]
|
assert match is not None, body[pos:pos + 80]
|
||||||
c = int(match[1])
|
c = int(match[1])
|
||||||
if match[2] is not None:
|
if match[2] is not None:
|
||||||
rgb = tuple(int(match[i]) for i in range(2, 5))
|
values = tuple(int(match[i]) for i in range(3, 6))
|
||||||
assert all(v <= 100 for v in rgb), rgb
|
if match[2] == b"1":
|
||||||
palette[c] = tuple((v * 255 + 50) // 100 for v in rgb)
|
hue, lightness, saturation = values
|
||||||
|
rgb = colorsys.hls_to_rgb(((hue + 240) % 360) / 360,
|
||||||
|
lightness / 100, saturation / 100)
|
||||||
|
palette[c] = tuple(int(v * 255 + .5) for v in rgb)
|
||||||
|
else:
|
||||||
|
assert all(v <= 100 for v in values), values
|
||||||
|
palette[c] = tuple((v * 255 + 50) // 100 for v in values)
|
||||||
pos += match.end()
|
pos += match.end()
|
||||||
continue
|
continue
|
||||||
if ch == ord("$"):
|
if ch == ord("$"):
|
||||||
|
|||||||
Reference in New Issue
Block a user