mirror of
https://github.com/quantum5/win2xcur.git
synced 2025-04-24 10:11:57 -04:00
Add .cur writer
This commit is contained in:
parent
e7ec91ee18
commit
fbe77f9422
|
@ -4,6 +4,9 @@ from wand.sequence import SingleImage
|
||||||
|
|
||||||
|
|
||||||
class CursorImage:
|
class CursorImage:
|
||||||
|
image: SingleImage
|
||||||
|
hotspot: Tuple[int, int]
|
||||||
|
|
||||||
def __init__(self, image: SingleImage, hotspot: Tuple[int, int]) -> None:
|
def __init__(self, image: SingleImage, hotspot: Tuple[int, int]) -> None:
|
||||||
self.image = image
|
self.image = image
|
||||||
self.hotspot = hotspot
|
self.hotspot = hotspot
|
||||||
|
@ -13,6 +16,9 @@ class CursorImage:
|
||||||
|
|
||||||
|
|
||||||
class CursorFrame:
|
class CursorFrame:
|
||||||
|
images: List[CursorImage]
|
||||||
|
delay: int
|
||||||
|
|
||||||
def __init__(self, images: List[CursorImage], delay: int = 0) -> None:
|
def __init__(self, images: List[CursorImage], delay: int = 0) -> None:
|
||||||
self.images = images
|
self.images = images
|
||||||
self.delay = delay
|
self.delay = delay
|
||||||
|
|
|
@ -9,6 +9,7 @@ from win2xcur.parser.base import BaseParser
|
||||||
|
|
||||||
class CURParser(BaseParser):
|
class CURParser(BaseParser):
|
||||||
MAGIC = b'\0\0\02\0'
|
MAGIC = b'\0\0\02\0'
|
||||||
|
ICO_TYPE_CUR = 2
|
||||||
ICON_DIR = struct.Struct('<HHH')
|
ICON_DIR = struct.Struct('<HHH')
|
||||||
ICON_DIR_ENTRY = struct.Struct('<BBBBHHII')
|
ICON_DIR_ENTRY = struct.Struct('<BBBBHHII')
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ class CURParser(BaseParser):
|
||||||
def _parse_header(self) -> List[Tuple[int, int]]:
|
def _parse_header(self) -> List[Tuple[int, int]]:
|
||||||
reserved, ico_type, image_count = self.ICON_DIR.unpack(self.blob[:self.ICON_DIR.size])
|
reserved, ico_type, image_count = self.ICON_DIR.unpack(self.blob[:self.ICON_DIR.size])
|
||||||
assert reserved == 0
|
assert reserved == 0
|
||||||
assert ico_type == 2
|
assert ico_type == self.ICO_TYPE_CUR
|
||||||
assert image_count == len(self._image.sequence)
|
assert image_count == len(self._image.sequence)
|
||||||
|
|
||||||
offset = self.ICON_DIR.size
|
offset = self.ICON_DIR.size
|
||||||
|
|
26
win2xcur/writer/windows.py
Normal file
26
win2xcur/writer/windows.py
Normal 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))
|
Loading…
Reference in a new issue