from __future__ import annotations
import pathlib
from typing import Optional
from neoscore.core.layout_controllers import NewLine
from neoscore.core.point import ORIGIN, Point, PointDef
from neoscore.core.positioned_object import PositionedObject
from neoscore.core.units import ZERO, Unit
from neoscore.interface.image_interface import ImageInterface
[docs]class Image(PositionedObject):
"""An image which can be placed in the document.
Supported image extensions/formats include: BMP, GIF, JPG, JPEG,
PNG, PBM, PGM, PPM, XBM, XPM, and SVG.
"""
[docs] def __init__(
self,
pos: PointDef,
parent: Optional[PositionedObject],
file_path: str | pathlib.Path,
scale: float = 1,
rotation: float = 0,
transform_origin: PointDef = ORIGIN,
opacity: float = 1,
):
"""
Args:
pos: Position relative to the parent
parent: The parent object or None
file_path: Path to an image file to be used
scale: A scaling factor applied to the image.
rotation: Rotation angle in degrees.
transform_origin: The origin point for rotation and scaling transforms
opacity: The image's opacity, where 1 is fully opaque and 0 is invisible.
"""
super().__init__(pos, parent)
self._scale = scale
self._rotation = rotation
self.transform_origin = transform_origin
self._opacity = opacity
self.file_path = file_path
@property
def file_path(self) -> pathlib.Path:
"""Path to an image file to be used"""
return self._file_path
@file_path.setter
def file_path(self, value: str | pathlib.Path):
if isinstance(value, str):
value = pathlib.Path(value)
self._file_path = value
@property
def opacity(self) -> float:
"""The image's opacity, where 1 is fully opaque and 0 is invisible."""
return self._opacity
@opacity.setter
def opacity(self, value: float):
self._opacity = value
@property
def breakable_length(self) -> Unit:
"""The breakable length of the object.
This is always ``ZERO``, meaning images cannot be broken across :obj:`.Flowable`
lines.
"""
return ZERO
# Since Image isn't breakable (for now?), we only need to
# implement complete rendering
[docs] def render_complete(
self,
pos: Point,
flowable_line: Optional[NewLine] = None,
flowable_x: Optional[Unit] = None,
):
interface = ImageInterface(
pos,
None if flowable_line else self.parent.interface_for_children,
self.scale,
self.rotation,
self.transform_origin,
self.file_path,
self.opacity,
)
interface.render()
self.interfaces.append(interface)