from _typeshed import Incomplete
from collections.abc import Callable
from typing import IO, Literal

from reportlab.lib.colors import Color, _ConvertibleToColor
from reportlab.pdfbase.acroform import AcroForm
from reportlab.pdfbase.pdfdoc import Destination
from reportlab.pdfgen.pathobject import PDFPathObject
from reportlab.pdfgen.textobject import PDFTextObject, _PDFColorSetter

class ShowBoundaryValue:
    color: _ConvertibleToColor | None
    width: float
    dashArray: Incomplete
    def __init__(
        self,
        color: _ConvertibleToColor | None = (0, 0, 0),
        width: float = 0.1,
        dashArray: list[float] | tuple[float, ...] | None = None,
    ) -> None: ...
    def __bool__(self) -> bool: ...

class Canvas(_PDFColorSetter):
    bottomup: bool | Literal[0, 1]
    imageCaching: Incomplete
    state_stack: list[Incomplete]
    def __init__(
        self,
        filename: str | IO[bytes],
        pagesize: tuple[float, float] | None = None,
        bottomup: bool | Literal[0, 1] = 1,
        pageCompression=None,
        invariant=None,
        verbosity: int = 0,
        encrypt=None,
        cropMarks=None,
        pdfVersion=None,
        enforceColorSpace=None,
        initialFontName: float | None = None,
        initialFontSize: float | None = None,
        initialLeading: float | None = None,
        cropBox=None,
        artBox=None,
        trimBox=None,
        bleedBox=None,
        lang=None,
    ) -> None: ...
    def setEncrypt(self, encrypt) -> None: ...
    def init_graphics_state(self) -> None: ...
    def push_state_stack(self) -> None: ...
    def pop_state_stack(self) -> None: ...
    STATE_ATTRIBUTES: list[str]
    STATE_RANGE: list[int]
    def setAuthor(self, author: str | None) -> None: ...
    def setDateFormatter(self, dateFormatter) -> None: ...
    def addOutlineEntry(self, title, key, level: int = 0, closed=None) -> None: ...
    def setOutlineNames0(self, *nametree) -> None: ...
    def setTitle(self, title: str | None) -> None: ...
    def setSubject(self, subject: str | None) -> None: ...
    def setCreator(self, creator: str | None) -> None: ...
    def setProducer(self, producer: str | None) -> None: ...
    def setKeywords(self, keywords: str | None) -> None: ...
    def pageHasData(self) -> bool: ...
    def showOutline(self) -> None: ...
    def showFullScreen0(self) -> None: ...
    def setBlendMode(self, v) -> None: ...
    def showPage(self) -> None: ...
    def setPageCallBack(self, func) -> None: ...
    def bookmarkPage(self, key, fit: str = "Fit", left=None, top=None, bottom=None, right=None, zoom=None) -> Destination: ...
    def bookmarkHorizontalAbsolute(self, key, top, left: int = 0, fit: str = "XYZ", **kw) -> Destination: ...
    def bookmarkHorizontal(self, key, relativeX, relativeY, **kw) -> None: ...
    def doForm(self, name) -> None: ...
    def hasForm(self, name: str) -> bool: ...
    def drawInlineImage(
        self,
        image,
        x: float,
        y: float,
        width: float | None = None,
        height: float | None = None,
        preserveAspectRatio: bool = False,
        anchor: str = "c",
        anchorAtXY: bool = False,
        showBoundary: bool = False,
        extraReturn=None,
    ) -> tuple[Incomplete, Incomplete]: ...
    def drawImage(
        self,
        image,
        x: float,
        y: float,
        width: float | None = None,
        height: float | None = None,
        mask=None,
        preserveAspectRatio: bool = False,
        anchor: str = "c",
        anchorAtXY: bool = False,
        showBoundary: bool = False,
        extraReturn=None,
    ) -> tuple[Incomplete, Incomplete]: ...
    def beginForm(self, name, lowerx: int = 0, lowery: int = 0, upperx=None, uppery=None) -> None: ...
    def endForm(self, **extra_attributes) -> None: ...
    def addPostScriptCommand(self, command, position: int = 1) -> None: ...
    def freeTextAnnotation(
        self, contents, DA, Rect=None, addtopage: bool | Literal[0, 1] = 1, name=None, relative: bool | Literal[0, 1] = 0, **kw
    ) -> None: ...
    def textAnnotation(
        self, contents, Rect=None, addtopage: bool | Literal[0, 1] = 1, name=None, relative: bool | Literal[0, 1] = 0, **kw
    ) -> None: ...
    textAnnotation0 = textAnnotation
    def highlightAnnotation(
        self,
        contents,
        Rect,
        QuadPoints=None,
        Color=[0.83, 0.89, 0.95],
        addtopage: bool | Literal[0, 1] = 1,
        name=None,
        relative: bool | Literal[0, 1] = 0,
        **kw,
    ) -> None: ...
    def inkAnnotation(
        self,
        contents,
        InkList=None,
        Rect=None,
        addtopage: bool | Literal[0, 1] = 1,
        name=None,
        relative: bool | Literal[0, 1] = 0,
        **kw,
    ) -> None: ...
    inkAnnotation0 = inkAnnotation
    def linkAbsolute(
        self,
        contents,
        destinationname,
        Rect=None,
        addtopage: bool | Literal[0, 1] = 1,
        name=None,
        thickness: int = 0,
        color: Color | None = None,
        dashArray=None,
        **kw,
    ) -> None: ...
    def linkRect(
        self,
        contents,
        destinationname,
        Rect=None,
        addtopage: bool | Literal[0, 1] = 1,
        name=None,
        relative: bool | Literal[0, 1] = 1,
        thickness: int = 0,
        color: Color | None = None,
        dashArray=None,
        **kw,
    ) -> None: ...
    def linkURL(
        self,
        url,
        rect,
        relative: bool | Literal[0, 1] = 0,
        thickness: int = 0,
        color: Color | None = None,
        dashArray=None,
        kind: str = "URI",
        **kw,
    ) -> None: ...
    def getPageNumber(self) -> int: ...
    def save(self) -> None: ...
    def getpdfdata(self): ...
    def setPageSize(self, size: tuple[float, float]) -> None: ...
    def setCropBox(self, size, name: str = "crop") -> None: ...
    def setTrimBox(self, size) -> None: ...
    def setArtBox(self, size) -> None: ...
    def setBleedBox(self, size) -> None: ...
    # NOTE: Only accepts right angles
    def setPageRotation(self, rot: float) -> None: ...
    def addLiteral(self, s: object, escaped: Literal[0, 1] = 1) -> None: ...
    def resetTransforms(self) -> None: ...
    def transform(self, a: float, b: float, c: float, d: float, e: float, f: float) -> None: ...
    def absolutePosition(self, x: float, y: float) -> tuple[float, float]: ...
    def translate(self, dx: float, dy: float) -> None: ...
    def scale(self, x: float, y: float) -> None: ...
    def rotate(self, theta: float) -> None: ...
    def skew(self, alpha: float, beta: float) -> None: ...
    def saveState(self) -> None: ...
    def restoreState(self) -> None: ...
    def line(self, x1: float, y1: float, x2: float, y2: float) -> None: ...
    def lines(self, linelist) -> None: ...
    def cross(
        self,
        x: float,
        y: float,
        size: float = 5,
        gap: float = 1,
        text=None,
        strokeColor=None,
        strokeWidth: float | None = None,
        fontSize: float = 3,
    ) -> None: ...
    def grid(self, xlist, ylist) -> None: ...
    def bezier(self, x1: float, y1: float, x2: float, y2: float, x3: float, y3: float, x4: float, y4: float) -> None: ...
    def arc(self, x1: float, y1: float, x2: float, y2: float, startAng: float = 0, extent: float = 90) -> None: ...
    def rect(self, x: float, y: float, width: float, height: float, stroke: float = 1, fill: float = 0) -> None: ...
    def ellipse(self, x1: float, y1: float, x2: float, y2: float, stroke: float = 1, fill: float = 0) -> None: ...
    def wedge(
        self, x1: float, y1: float, x2: float, y2: float, startAng: float, extent: float, stroke: float = 1, fill: float = 0
    ) -> None: ...
    def circle(self, x_cen: float, y_cen: float, r: float, stroke: float = 1, fill: float = 0) -> None: ...
    def roundRect(
        self, x: float, y: float, width: float, height: float, radius: float, stroke: float = 1, fill: float = 0
    ) -> None: ...
    def shade(self, shading) -> None: ...
    def linearGradient(self, x0: float, y0: float, x1: float, y1: float, colors, positions=None, extend: bool = True) -> None: ...
    def radialGradient(self, x: float, y: float, radius: float, colors, positions=None, extend: bool = True) -> None: ...
    def drawString(
        self,
        x: float,
        y: float,
        text: str,
        mode: Literal[0, 1, 2, 3, 4, 5, 6, 7] | None = None,
        charSpace: float = 0,
        direction: Literal["LTR", "RTL"] | None = None,
        wordSpace: float | None = None,
        shaping: bool = False,
    ) -> None: ...
    def drawRightString(
        self,
        x: float,
        y: float,
        text: str,
        mode: Literal[0, 1, 2, 3, 4, 5, 6, 7] | None = None,
        charSpace: float = 0,
        direction: Literal["LTR", "RTL"] | None = None,
        wordSpace: float | None = None,
        shaping: bool = False,
    ) -> None: ...
    def drawCentredString(
        self,
        x: float,
        y: float,
        text: str,
        mode: Literal[0, 1, 2, 3, 4, 5, 6, 7] | None = None,
        charSpace: float = 0,
        direction: Literal["LTR", "RTL"] | None = None,
        wordSpace: float | None = None,
        shaping: bool = False,
    ) -> None: ...
    def drawAlignedString(
        self,
        x: float,
        y: float,
        text: str,
        pivotChar: str = ".",
        mode: Literal[0, 1, 2, 3, 4, 5, 6, 7] | None = None,
        charSpace: float = 0,
        direction: Literal["LTR", "RTL"] | None = None,
        wordSpace: float | None = None,
        shaping: bool = False,
    ) -> None: ...
    def getAvailableFonts(self) -> list[Incomplete]: ...
    def listLoadedFonts0(self) -> list[Incomplete]: ...
    def setFont(self, psfontname: str, size: float, leading: float | None = None) -> None: ...
    def setFontSize(self, size: float | None = None, leading: float | None = None) -> None: ...
    def stringWidth(self, text: str, fontName: str | None = None, fontSize: float | None = None) -> float: ...
    def setLineWidth(self, width: float) -> None: ...
    def setLineCap(self, mode) -> None: ...
    def setLineJoin(self, mode) -> None: ...
    def setMiterLimit(self, limit) -> None: ...
    def setDash(self, array: list[float] | tuple[float, ...] | float = [], phase: float = 0) -> None: ...
    def beginPath(self) -> PDFPathObject: ...
    def drawPath(self, aPath, stroke: int = 1, fill: int = 0, fillMode=None) -> None: ...
    def clipPath(self, aPath, stroke: int = 1, fill: int = 0, fillMode=None) -> None: ...
    def beginText(self, x: float = 0, y: float = 0, direction: Literal["LTR", "RTL"] | None = None) -> PDFTextObject: ...
    def drawText(self, aTextObject: PDFTextObject) -> None: ...
    def setPageCompression(self, pageCompression: bool | Literal[0, 1] | None = 1) -> None: ...
    def setPageDuration(self, duration=None) -> None: ...
    def setPageTransition(
        self, effectname: str | None = None, duration: float = 1, direction: float = 0, dimension: str = "H", motion: str = "I"
    ) -> None: ...
    def getCurrentPageContent(self) -> str: ...
    def setViewerPreference(self, pref, value) -> None: ...
    def getViewerPreference(self, pref): ...
    def delViewerPreference(self, pref) -> None: ...
    def setCatalogEntry(self, key: str, value) -> None: ...
    def getCatalogEntry(self, key: str): ...
    def delCatalogEntry(self, key: str) -> None: ...
    def addPageLabel(self, pageNum, style=None, start=None, prefix=None) -> None: ...
    @property
    def acroForm(self) -> AcroForm: ...
    def drawBoundary(self, sb, x1: float, y1: float, width: float, height: float) -> None: ...
    # Following callbacks are accepted: canvas, kind and label
    def setNamedCB(self, name: str, cb: Callable[[Canvas, str | None, str], None]) -> None: ...
    def getNamedCB(self, name: str) -> Callable[[Canvas, str | None, str], None] | None: ...

__all__ = ["Canvas", "ShowBoundaryValue"]
