Add .cur writer

This commit is contained in:
Quantum 2020-10-03 00:35:41 -04:00
parent e7ec91ee18
commit fbe77f9422
3 changed files with 34 additions and 1 deletions

View file

@ -4,6 +4,9 @@ from wand.sequence import SingleImage
class CursorImage:
image: SingleImage
hotspot: Tuple[int, int]
def __init__(self, image: SingleImage, hotspot: Tuple[int, int]) -> None:
self.image = image
self.hotspot = hotspot
@ -13,6 +16,9 @@ class CursorImage:
class CursorFrame:
images: List[CursorImage]
delay: int
def __init__(self, images: List[CursorImage], delay: int = 0) -> None:
self.images = images
self.delay = delay

View file

@ -9,6 +9,7 @@ from win2xcur.parser.base import BaseParser
class CURParser(BaseParser):
MAGIC = b'\0\0\02\0'
ICO_TYPE_CUR = 2
ICON_DIR = struct.Struct('<HHH')
ICON_DIR_ENTRY = struct.Struct('<BBBBHHII')
@ -27,7 +28,7 @@ class CURParser(BaseParser):
def _parse_header(self) -> List[Tuple[int, int]]:
reserved, ico_type, image_count = self.ICON_DIR.unpack(self.blob[:self.ICON_DIR.size])
assert reserved == 0
assert ico_type == 2
assert ico_type == self.ICO_TYPE_CUR
assert image_count == len(self._image.sequence)
offset = self.ICON_DIR.size

View file

@ -0,0 +1,26 @@
from itertools import chain
from typing import List
from win2xcur.cursor import CursorFrame
from win2xcur.parser import CURParser
def to_cur(frame: CursorFrame) -> bytes:
header = CURParser.ICON_DIR.pack(0, CURParser.ICO_TYPE_CUR, len(frame))
directory: List[bytes] = []
image_data: List[bytes] = []
offset = CURParser.ICON_DIR.size + len(frame) * CURParser.ICON_DIR_ENTRY.size
for image in frame:
clone = image.image.clone()
if clone.width > 256 or clone.height > 256:
raise ValueError(f'Image too big for CUR format: {clone.width}x{clone.height}')
blob = clone.make_blob('png')
image_data.append(blob)
x_offset, y_offset = image.hotspot
directory.append(CURParser.ICON_DIR_ENTRY.pack(
clone.height & 0xFF, clone.height & 0xFF, 0, 0, x_offset, y_offset, len(blob), offset
))
offset += len(blob)
return b''.join(chain([header], directory, image_data))