Show page number 'pno' of PDF 'src' in rectangle 'rect'.

    Args:
        rect: (rect-like) where to place the source image
        src: (document) source PDF
        pno: (int) source page number
        overlay: (bool) put in foreground
        keep_proportion: (bool) do not change width-height-ratio
        rotate: (int) degrees (multiple of 90)
        clip: (rect-like) part of source page rectangle
    Returns:
        xref of inserted object (for reuse)

def showPDFpage(
        page,
        rect,
        src,
        pno=0,
        overlay=True,
        keep_proportion=True,
        rotate=0,
        reuse_xref=0,
        clip = None,
    ):
    """Show page number 'pno' of PDF 'src' in rectangle 'rect'.

    Args:
        rect: (rect-like) where to place the source image
        src: (document) source PDF
        pno: (int) source page number
        overlay: (bool) put in foreground
        keep_proportion: (bool) do not change width-height-ratio
        rotate: (int) degrees (multiple of 90)
        clip: (rect-like) part of source page rectangle
    Returns:
        xref of inserted object (for reuse)
    """

    def calc_matrix(sr, tr, keep=True, rotate=0):
        """ Calculate transformation matrix from source to target rect.

        Notes:
            The product of four matrices in this sequence: (1) translate correct
            source corner to origin, (2) rotate, (3) scale, (4) translate to
            target's top-left corner.
        Args:
            sr: source rect in PDF (!) coordinate system
            tr: target rect in PDF coordinate system
            keep: whether to keep source ratio of width to height
            rotate: rotation angle in degrees
        Returns:
            Transformation matrix.
        """
        # calc center point of source rect
        smp = Point((sr.x1 + sr.x0) / 2., (sr.y1 + sr.y0) / 2.)
        # calc center point of target rect
        tmp = Point((tr.x1 + tr.x0) / 2., (tr.y1 + tr.y0) / 2.)

        rot = Matrix(rotate)  # rotation matrix

        # m moves to (0, 0), then rotates
        m = Matrix(1, 0, 0, 1, -smp.x, -smp.y) * rot

        sr1 = sr * m  # resulting source rect to calculate scale factors

        fw = tr.width / sr1.width  # scale the width
        fh = tr.height / sr1.height  # scale the height
        if keep:
            fw = fh = min(fw, fh)  # take min if keeping aspect ratio

        m *= Matrix(fw, fh)  # concat scale matrix
        m *= Matrix(1, 0, 0, 1, tmp.x, tmp.y)  # concat move to target center
        return m

    CheckParent(page)
    doc = page.parent

    if not doc.isPDF or not src.isPDF:
        raise ValueError("not a PDF")

    rect = page.rect & rect  # intersect with page rectangle
    if rect.isEmpty or rect.isInfinite:
        raise ValueError("rect must be finite and not empty")

    if reuse_xref > 0:
        warnings.warn("ignoring 'reuse_xref'", DeprecationWarning)

    while pno < 0:  # support negative page numbers
        pno += len(src)
    src_page = src[pno]  # load ource page
    if len(src_page._getContents()) == 0:
        raise ValueError("nothing to show - source page empty")

    tar_rect = rect * ~page._getTransformation()  # target rect in PDF coordinates

    src_rect = src_page.rect if not clip else src_page.rect & clip  # source rect
    if src_rect.isEmpty or src_rect.isInfinite:
        raise ValueError("clip must be finite and not empty")
    src_rect = src_rect * ~src_page._getTransformation()  # ... in PDF coord

    matrix = calc_matrix(src_rect, tar_rect, keep=keep_proportion, rotate=rotate)

    # list of existing /Form /XObjects
    ilst = [i[1] for i in doc._getPageInfo(page.number, 3)]

    # create a name that is not in that list
    n = "fzFrm"
    i = 0
    _imgname = n + "0"
    while _imgname in ilst:
        i += 1
        _imgname = n + str(i)

    isrc = src._graft_id          # used as key for graftmaps
    if doc._graft_id == isrc:
        raise ValueError("source document must not equal target")

    # check if we have already copied objects from this source doc
    if isrc in doc.Graftmaps:     # yes: use the old graftmap
        gmap = doc.Graftmaps[isrc]
    else:                         # no: make a new graftmap
        gmap = Graftmap(doc)
        doc.Graftmaps[isrc] = gmap

    # take note of generated xref for automatic reuse
    pno_id = (isrc, pno)          # id of src[pno]
    xref = doc.ShownPages.get(pno_id, 0)

    xref = page._showPDFpage(
                src_page,
                overlay=overlay,
                matrix=matrix,
                xref=xref,
                clip=src_rect,
                graftmap=gmap,
                _imgname=_imgname,
            )
    doc.ShownPages[pno_id] = xref

    return xref