Example #1
0
def create_annot_box(x1, y1, x2, y2, meta, color=[1, 0, 0]):
    new_annot = DictionaryObject()

    new_annot.update({
        # NameObject("/P"): parent,
        NameObject("/F"):
        NumberObject(4),
        NameObject("/Type"):
        NameObject("/Annot"),
        NameObject("/Subtype"):
        NameObject("/Square"),
        NameObject("/T"):
        TextStringObject(meta["author"]),
        NameObject("/Contents"):
        TextStringObject(meta["contents"]),
        NameObject("/C"):
        ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"):
        ArrayObject([
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x2),
            FloatObject(y2)
        ]),
    })
    return new_annot
Example #2
0
def crop(pdf_file, top, right, bottom, left):
    # POINT_MM = 25.4 / 72.0

    input_pdf = PdfFileReader(open(pdf_file, 'rb'), strict=False)
    output_pdf = PdfFileWriter()
    top, right, bottom, left = int(top), int(right), int(bottom), int(left)

    new_name = rename_file(pdf_file, '_croped')
    new_file = open(new_name, 'wb')

    num_pages = input_pdf.getNumPages()

    for i in range(num_pages):
        page = input_pdf.getPage(i)

        page.mediaBox.upperRight = (page.mediaBox.getUpperRight_x() -
                                    FloatObject(right),
                                    page.mediaBox.getUpperRight_y() -
                                    FloatObject(top))
        page.mediaBox.lowerLeft = (page.mediaBox.getLowerLeft_x() +
                                   FloatObject(left),
                                   page.mediaBox.getLowerLeft_y() +
                                   FloatObject(bottom))
        output_pdf.addPage(page)
        output_pdf.write(new_file)

    new_file.close()

    settings.setsave('last_file', new_name)
Example #3
0
def createAnnotPdf(geom_type, myShapePdf):
    # input variables
    # part 1: read geometry pdf to get the vertices and rectangle to use
    source = PdfFileReader(open(myShapePdf, 'rb'))
    geomPage = source.getPage(0)
    mystr = geomPage.getObject()['/Contents'].getData()
    # to pinpoint the string part: 1.19997 791.75999 m 1.19997 0.19466 l 611.98627 0.19466 l 611.98627 791.75999 l 1.19997 791.75999 l
    # the format seems to follow x1 y1 m x2 y2 l x3 y3 l x4 y4 l x5 y5 l
    geomString = mystr.split('S\r\n')[0].split('M\r\n')[1]
    coordsString = [
        value for value in geomString.split(' ')
        if value not in ['m', 'l', '']
    ]

    # part 2: update geometry in the map
    if geom_type.upper() == 'POLYGON':
        pdf_geom = PdfFileReader(open(annot_poly, 'rb'))
    elif geom_type.upper() == 'POLYLINE':
        pdf_geom = PdfFileReader(open(annot_line, 'rb'))
    page_geom = pdf_geom.getPage(0)

    annot = page_geom['/Annots'][0]
    updateVertices = "annot.getObject().update({NameObject('/Vertices'):ArrayObject([FloatObject(" + coordsString[
        0] + ")"
    for item in coordsString[1:]:
        updateVertices = updateVertices + ',FloatObject(' + item + ')'
    updateVertices = updateVertices + "])})"
    exec(updateVertices)

    xcoords = []
    ycoords = []
    for i in range(0, len(coordsString) - 1):
        if i % 2 == 0:
            xcoords.append(float(coordsString[i]))
        else:
            ycoords.append(float(coordsString[i]))

    # below rect seems to be geom bounding box coordinates: xmin, ymin, xmax,ymax
    annot.getObject().update({
        NameObject('/Rect'):
        ArrayObject([
            FloatObject(min(xcoords)),
            FloatObject(min(ycoords)),
            FloatObject(max(xcoords)),
            FloatObject(max(ycoords))
        ])
    })
    annot.getObject().pop('/AP')  # this is to get rid of the ghost shape

    annot.getObject().update({NameObject('/T'): createStringObject(u'ERIS')})

    output = PdfFileWriter()
    output.addPage(page_geom)
    annotPdf = os.path.join(scratch, "annot.pdf")
    outputStream = open(annotPdf, "wb")
    #output.setPageMode('/UseOutlines')
    output.write(outputStream)
    outputStream.close()
    output = None
    return annotPdf
Example #4
0
 def _swapColorCmd(self, content, index, toColor):
     redObj = FloatObject((toColor.red / 255.0))
     greenObj = FloatObject((toColor.green / 255.0))
     blueObj = FloatObject((toColor.blue / 255.0))
     operator = b_("rg")
     obj = ([redObj, greenObj, blueObj], operator)
     content.operations.pop(index)
     content.operations.insert(index, obj)
     return
Example #5
0
def createHighlight(bbox=(0, 0, 1, 1),
                    contents="",
                    color=[1, 1, 0],
                    author="iwasakishuto(@cabernet_rock)"):
    """Create a Highlight

    Args:
        bbox (tuple)   : a bounding box showing the location of highlight.
        contents (str) : Text comments for a highlight label.
        color (list)   : Highlight color. Defaults to ``[1,1,0]``. (yellow)
        author (str)   : Who wrote the annotation (comment). Defaults to ``"iwasakishuto(@cabernet_rock)"`` .

    Returns:
        DictionaryObject: Highlight information.

    Examples:
        >>> from gummy.utils import createHighlight, addHighlightToPage
        >>> from PyPDF2 import PdfFileWriter, PdfFileReader
        >>> page_no = 0
        >>> pdfOutput = PdfFileWriter()
        >>> with open("input.pdf", mode="rb") as inPdf:
        ...     pdfInput = PdfFileReader(inPdf)
        ...     page = pdfInput.getPage(page_no)
        ...     highlight = createHighlight(bbox=(10,10,90,90), contents="COMMENT", color=(1,1,0))
        ...     addHighlightToPage(highlight, page, pdfOutput)
        ...     pdfOutput.addPage(page)
        ...     with open("output.pdf", mode="wb") as outPdf:
        ...         pdfOutput.write(outPdf)
    """
    from PyPDF2.generic import (DictionaryObject, NumberObject, FloatObject,
                                NameObject, TextStringObject, ArrayObject)
    x1, y1, x2, y2 = bbox
    newHighlight = DictionaryObject()
    newHighlight.update({
        NameObject("/F"):
        NumberObject(4),
        NameObject("/Type"):
        NameObject("/Annot"),
        NameObject("/Subtype"):
        NameObject("/Highlight"),
        NameObject("/T"):
        TextStringObject(author),
        NameObject("/Contents"):
        TextStringObject(contents),
        NameObject("/C"):
        ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"):
        ArrayObject([FloatObject(e) for e in bbox]),
        NameObject("/QuadPoints"):
        ArrayObject([FloatObject(e)
                     for e in [x1, y2, x2, y2, x1, y1, x2, y1]]),
    })
    return newHighlight
def _create_annotation(x1, y1, x2, y2, color, subtype):
    annotation = DictionaryObject()

    annotation.update({
        NameObject('/Subtype'): NameObject(subtype),
        NameObject('/C'): ArrayObject([FloatObject(c) for c in color]),
        NameObject('/Rect'): ArrayObject([
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x2),
            FloatObject(y2)]),
    })

    return annotation
Example #7
0
def test_bookmark_write_to_stream():
    stream = BytesIO()
    bm = Bookmark(NameObject("title"), NullObject(), NameObject(TF.FIT_V),
                  FloatObject(0))
    bm.write_to_stream(stream, None)
    stream.seek(0, 0)
    assert stream.read() == b"<<\n/Title title\n/Dest [ null /FitV 0 ]\n>>"
Example #8
0
def add_comment(output, page, text, rectangle):
    obj = output._addObject(
        DictionaryObject({
            NameObject('/DA'):
            TextStringObject(' /Helv 10 Tf'),
            NameObject('/Subtype'):
            NameObject('/FreeText'),
            NameObject('/Rect'):
            RectangleObject(rectangle),
            NameObject('/Type'):
            NameObject('/Annot'),
            NameObject('/Contents'):
            TextStringObject(text),
            NameObject('/C'):
            ArrayObject([FloatObject(1),
                         FloatObject(1),
                         FloatObject(1)]),
        }))
    page['/Annots'].append(obj)
Example #9
0
def get_pdf_gpts(m, poly):
    """
    Returns the GPTS array object containing the four corners of the
    map rect in map projection.
    The GPTS entry is an array of numbers, taken pairwise, defining
    points as latitude and longitude.
    m = mapnik map object
    poly = tuple of (x,y) tuples describing rect polygon - allows geocoding of rotated maps.
    """
    gpts = ArrayObject()

    proj = mapnik.Projection(m.srs)
    for x, y in poly:
        latlon_corner = proj.inverse(mapnik.Coord(x, y))
        # these are in lat,lon order according to the specification
        gpts.append(FloatObject(str(latlon_corner.y)))
        gpts.append(FloatObject(str(latlon_corner.x)))

    return gpts
Example #10
0
def test_destination_fit_r():
    d = Destination(
        NameObject("title"),
        NullObject(),
        NameObject(TF.FIT_R),
        FloatObject(0),
        FloatObject(0),
        FloatObject(0),
        FloatObject(0),
    )
    assert d.title == NameObject("title")
    assert d.typ == "/FitR"
    assert d.zoom is None
    assert d.left == FloatObject(0)
    assert d.right == FloatObject(0)
    assert d.top == FloatObject(0)
    assert d.bottom == FloatObject(0)
    assert list(d) == []
    d.empty_tree()
Example #11
0
def get_pdf_measure(m, gcs, poly, bounds_default):
    """
    Returns the PDF Measure dictionary.
    The Measure dictionary is used in the viewport array
    and specifies the scale and units that apply to the output map.
    """
    measure = DictionaryObject()
    measure[NameObject('/Type')] = NameObject('/Measure')
    measure[NameObject('/Subtype')] = NameObject('/GEO')
    bounds = ArrayObject()
    """
    Returns the PDF BOUNDS array.
    The PDF's bounds array is equivalent to the map's neatline, i.e.,
    the border delineating the extent of geographic data on the output map.
    """
    for x in [0, 1, 0, 0, 1, 0, 1, 1]:
        bounds.append(FloatObject(str(x)))

    measure[NameObject('/Bounds')] = bounds
    measure[NameObject('/GPTS')] = get_pdf_gpts(m, poly)
    measure[NameObject('/LPTS')] = bounds
    measure[NameObject('/GCS')] = gcs
    return measure
def createHighlight(x0, y0, x1, y1, color=[0, 0, 0]):
    newHighlight = DictionaryObject()

    newHighlight.update({
        NameObject("/F"):
        NumberObject(4),
        NameObject("/Type"):
        NameObject("/Annot"),
        NameObject("/Subtype"):
        NameObject("/Highlight"),
        NameObject("/C"):
        ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"):
        ArrayObject([
            FloatObject(x0),
            FloatObject(y0),
            FloatObject(x1),
            FloatObject(y1)
        ]),
        NameObject("/QuadPoints"):
        ArrayObject([
            FloatObject(x0),
            FloatObject(y1),
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x0),
            FloatObject(y0),
            FloatObject(x1),
            FloatObject(y0)
        ]),
    })

    return newHighlight
Example #13
0
    def _create_highlight(self,
                          x0,
                          y0,
                          width,
                          height,
                          comment,
                          author='',
                          color=[0, 0, 0, 0]):
        self.add_rect(x0, y0, width, height)
        highlight = DictionaryObject()

        highlight.update({
            NameObject("/F"):
            NumberObject(4),
            NameObject("/Type"):
            NameObject("/Annot"),
            NameObject("/Subtype"):
            NameObject("/Highlight"),
            NameObject("/T"):
            TextStringObject(author),
            NameObject("/Contents"):
            TextStringObject(comment),
            NameObject("/C"):
            ArrayObject([FloatObject(c) for c in color]),
            NameObject("/Rect"):
            ArrayObject([
                FloatObject(x0),
                FloatObject(y0),
                FloatObject(x0 + width),
                FloatObject(y0 + width)
            ]),
            NameObject("/QuadPoints"):
            ArrayObject([
                FloatObject(x0),
                FloatObject(y0 + width),
                FloatObject(x0 + width),
                FloatObject(y0 + width),
                FloatObject(x0),
                FloatObject(y0),
                FloatObject(x0 + width),
                FloatObject(y0)
            ]),
        })

        return highlight
Example #14
0
def test_float_object_exception():
    assert FloatObject("abc") == 0
Example #15
0
def test_destination_exception():
    with pytest.raises(PdfReadError):
        Destination(NameObject("title"), NullObject(), NameObject("foo"),
                    FloatObject(0))
Example #16
0
def annotate(fp_in, annotations):
    reader = PdfFileReader(fp_in)
    pdf = PdfFileWriter()
    for page in reader.pages:
        pdf.addPage(page)

    for annotation in annotations:
        page = annotation.get('page', 0)
        try:
            pdfpage = pdf.getPage(page)
        except IndexError:
            print >> sys.stderr, 'Page %d not found in pdf, not adding annotations %r' % (
                page, annotation)
            continue

        size = pdfpage.mediaBox
        angle = int(pdfpage.get('/Rotate', 0))
        x = annotation['x']
        y = annotation['y']
        if angle == 0:
            x = float(x)
            y = size[3] - float(y) - 20
        elif angle == 90:
            x, y = float(y) - 2, float(x) - 15
        else:
            x = float(x)
            y = float(y)
            print >> sys.stderr, 'Page rotated by %d degrees not implemented yet' % (
                angle)

        color = annotation.get('color', None)
        if isinstance(color, basestring):
            if color[:1] != '#':
                print >> sys.stderr, 'Unsupported color format: %s' % (color)
                color = None
            else:
                # Assume HTML color with format "#RRGGBB".
                try:
                    color = int(color[1:], 16)
                except ValueError as e:
                    print >> sys.stderr, 'Unsupported color format: %s (%s)' % (
                        color, e)
                    color = None

        if color is not None:
            r, g, b = color >> 16, (color >> 8) & 0xff, color & 0xff
            color = (r * BYTE_TO_COLOR, g * BYTE_TO_COLOR, b * BYTE_TO_COLOR)
        else:
            color = None

        pages = pdf.getObject(pdf._pages)
        pageref = pages["/Kids"][page]

        anno = DictionaryObject()
        anno.update({
            NameObject('/Type'):
            NameObject('/Annot'),
            NameObject('/Subtype'):
            NameObject('/Text'),
            NameObject('/P'):
            pageref,
            NameObject('/Rect'):
            RectangleObject([x, y, x + 18, y + 20]),
            NameObject('/Contents'):
            TextStringObject(annotation['text']),
            NameObject('/C'):
            ArrayObject([FloatObject(x) for x in color]),
            NameObject('/Open'):
            BooleanObject(True),
        })
        author = annotation.get('author', None)
        if author:
            anno[NameObject('/T')] = TextStringObject(author)
        modified = annotation.get('modified', None)
        if modified:
            modified = time.strftime('%Y%m%d%H%M%SZ', time.gmtime(modified))
            anno[NameObject('/M')] = TextStringObject(modified)

        annoRef = pdf._addObject(anno)
        annots = pdfpage.get('/Annots', None)
        if annots is None:
            annots = pdfpage[NameObject('/Annots')] = ArrayObject([annoRef])
        else:
            annots.append(annoRef)

    fp_out = StringIO()
    pdf.write(fp_out)
    return fp_out.getvalue()
Example #17
0
def add_geospatial_pdf_header(m, f, f2, map_bounds, poly, epsg=None, wkt=None):
    """
        Adds geospatial PDF information to the PDF file as per:
            AdobeĀ® Supplement to the ISO 32000 PDF specification
            BaseVersion: 1.7
            ExtensionLevel: 3
            (June 2008)
        Notes:
            The epsg code or the wkt text of the projection must be provided.
            Must be called *after* the page has had .finish() called.
        """
    if not HAS_PYPDF2:
        raise RuntimeError(
            "PyPDF2 not available; PyPDF2 required to add geospatial header to PDF"
        )

    if not any((epsg, wkt)):
        raise RuntimeError(
            "EPSG or WKT required to add geospatial header to PDF")

    file_reader = PdfFileReader(f)
    file_writer = PdfFileWriter()

    # preserve OCProperties at document root if we have one
    if NameObject('/OCProperties'
                  ) in file_reader.trailer['/Root']:  #Python3-friendly
        file_writer._root_object[NameObject(
            '/OCProperties')] = file_reader.trailer['/Root'].getObject()[
                NameObject('/OCProperties')]

    for page in file_reader.pages:
        gcs = DictionaryObject()
        gcs[NameObject('/Type')] = NameObject('/PROJCS')

        if epsg:
            gcs[NameObject('/EPSG')] = NumberObject(int(epsg))
        if wkt:
            gcs[NameObject('/WKT')] = TextStringObject(wkt)

        measure = get_pdf_measure(m, gcs, poly, map_bounds)
        """
            Returns the PDF's VP array.
            The VP entry is an array of viewport dictionaries. A viewport is basiscally
            a rectangular region on the PDF page. The only required entry is the BBox which
            specifies the location of the viewport on the page.
            """
        viewport = DictionaryObject()
        viewport[NameObject('/Type')] = NameObject('/Viewport')

        bbox = ArrayObject()
        for x in (0, int(page.mediaBox[3]), int(page.mediaBox[2]), 0):  #in pts
            bbox.append(FloatObject(str(x)))  #Fixed

        viewport[NameObject('/BBox')] = bbox
        #viewport[NameObject('/Name')] = TextStringObject('OOMAP')
        viewport[NameObject('/Measure')] = measure

        vp_array = ArrayObject()
        vp_array.append(viewport)
        page[NameObject('/VP')] = vp_array
        file_writer.addPage(page)

    file_writer.write(f2)
    return (f2)
Example #18
0
def create_annotation(x, y, meta):
    color = [255.0 / 255.0, 209 / 255.0, 0]
    # link
    linkAnnotation = DictionaryObject()
    # https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf
    linkAnnotation.update({
        # Table 165 NoZoom
        NameObject("/F"):
        NumberObject(4),
        NameObject("/Type"):
        NameObject("/Annot"),
        NameObject("/Subtype"):
        NameObject("/Link"),

        # Table 164 color, annotation rectangle
        NameObject("/C"):
        ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"):
        ArrayObject([
            FloatObject(x),
            FloatObject(y),
            FloatObject(x + 20),
            FloatObject(y + 20)
        ]),

        # Table 173 link annotation
        NameObject('/A'):
        DictionaryObject({
            # Table 206 uri
            NameObject('/S'): NameObject('/URI'),
            NameObject('/URI'): TextStringObject(meta["contents"])
        }),
        # Table 173 invert rect when mouse
        NameObject('/H'):
        NameObject('/I'),
        # table 164 hor corner radius, vert corner radius, border width
        # dash array table 56
        NameObject('/Border'):
        ArrayObject([
            NameObject(0),
            NameObject(0),
            NameObject(5),
        ]),
    })

    commentAnnotation = DictionaryObject()
    # https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf
    commentAnnotation.update({
        # Table 165 NoZoom
        NameObject("/F"):
        NumberObject(4),
        NameObject("/Type"):
        NameObject("/Annot"),
        NameObject("/Subtype"):
        NameObject("/Text"),

        # Table 170 titlebar
        NameObject("/T"):
        TextStringObject(meta["author"]),
        NameObject("/Contents"):
        TextStringObject(meta["contents"]),

        # Table 164 color, annotation rectangle
        NameObject("/C"):
        ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"):
        ArrayObject([
            FloatObject(x),
            FloatObject(y),
            FloatObject(x + 5),
            FloatObject(y + 5)
        ]),

        # 12.5.6.4 text annotation
        NameObject('/Open'):
        BooleanObject(False),
        NameObject('/Name'):
        NameObject('/Comment'),
    })

    return linkAnnotation, commentAnnotation
    def create_highlight(self, x1, y1, x2, y2, meta, color=[0, 1, 0]):
        """
        Create a highlight for a PDF.

        Parameters
        ----------
        x1, y1 : float
            bottom left corner
        x2, y2 : float
            top right corner
        meta : dict
            keys are "author" and "contents"
        color : iterable
            Three elements, (r,g,b)
        """
        new_highlight = DictionaryObject()

        new_highlight.update({
            NameObject("/F"):
            NumberObject(4),
            NameObject("/Type"):
            NameObject("/Annot"),
            NameObject("/Subtype"):
            NameObject("/Highlight"),
            NameObject("/T"):
            TextStringObject(meta["author"]),
            NameObject("/Contents"):
            TextStringObject(meta["contents"]),
            NameObject("/C"):
            ArrayObject([FloatObject(c) for c in color]),
            NameObject("/Rect"):
            ArrayObject([
                FloatObject(x1),
                FloatObject(y1),
                FloatObject(x2),
                FloatObject(y2)
            ]),
            NameObject("/QuadPoints"):
            ArrayObject([
                FloatObject(x1),
                FloatObject(y2),
                FloatObject(x2),
                FloatObject(y2),
                FloatObject(x1),
                FloatObject(y1),
                FloatObject(x2),
                FloatObject(y1)
            ]),
        })

        return new_highlight
Example #20
0
def generateNup(inPathOrFile, n, outPathPatternOrFile=None, dirs="RD",
                verbose=False):
    """Generate a N-up document version.

    If outPathPatternOrFile is None, the output will be written
    in a file named after the input file.
    """

    assert isSquare(n) or isHalfSquare(n)

    ipof = inPathOrFile
    oppof = outPathPatternOrFile

    if isFileLike(ipof):
        inFile = ipof
        if oppof is None:
            raise AssertionError("Must specify output for file input!")
        elif isFileLike(oppof):
            outFile = oppof
        elif type(oppof) in (str,):
            outPath = oppof
            outFile = open(outPath, "wb")
    elif type(ipof) in (str,):
        inFile = open(ipof, "rb")
        if isFileLike(oppof):
            outFile = oppof
        elif oppof is None or type(oppof) in (str,):
            if oppof is None:
                oppof = "%(dirname)s/%(base)s-%(n)dup%(ext)s"
            aDict = {
                "dirname": os.path.dirname(inPathOrFile) or ".",
                "basename": os.path.basename(inPathOrFile),
                "base": os.path.basename(os.path.splitext(inPathOrFile)[0]),
                "ext": os.path.splitext(inPathOrFile)[1],
                "n": n,
            }
            outPath = oppof % aDict
            outPath = os.path.normpath(outPath)
            outFile = open(outPath, "wb")

    # get info about source document
    docReader = PdfFileReader(inFile)
    numPages = docReader.getNumPages()
    oldPageSize = docReader.getPage(0).mediaBox.upperRight

    # create empty output document buffer
    if isSquare(n):
        newPageSize = oldPageSize
    elif isHalfSquare(n):
        newPageSize = oldPageSize[1], oldPageSize[0]
    np = numPages // n + numPages % n
    buf = exP1multiN(_mtA4Pdf, newPageSize, np)

    # calculate mini page areas
    rects = calcRects(newPageSize, n, dirs)

    # combine
    ops = []
    newPageNum = -1
    for i in range(numPages):
        if i % n == 0:
            newPageNum += 1
        op = (inPathOrFile, i, (0, 0, None, None), i // n, rects[i % n])
        ops.append(op)

    srcr = srcReader = PdfFileReader(inFile)
    srcPages = [srcr.getPage(i) for i in range(srcr.getNumPages())]

    if type(oppof) in (str,):
        outFile = open(outPath, "rb")
    outr = outReader = PdfFileReader(buf)
    outPages = [outr.getPage(i) for i in range(outr.getNumPages())]
    output = PdfFileWriter()

    mapping = {}
    for op in ops:
        dummy, dummy, dummy, destPageNum, dummy = op
        if destPageNum not in mapping:
            mapping[destPageNum] = []
        mapping[destPageNum].append(op)

    PO, AO, DO, NO = PageObject, ArrayObject, DictionaryObject, NameObject

    for destPageNum, ops in list(mapping.items()):
        for op in ops:
            inPathOrFile, srcPageNum, srcRect, destPageNum, destRect = op
            page2 = srcPages[srcPageNum]
            page1 = outPages[destPageNum]
            pageWidth, pageHeight = page2.mediaBox.upperRight
            destX, destY, destWidth, destHeight = destRect
            xScale, yScale = calcScalingFactors(
                destWidth, destHeight, pageWidth, pageHeight)

            newResources = DO()
            rename = {}
            orgResources = page1["/Resources"].getObject()
            page2Resources = page2["/Resources"].getObject()

            names = "ExtGState Font XObject ColorSpace Pattern Shading"
            for res in names.split():
                res = "/" + res
                new, newrename = PO._mergeResources(orgResources,
                                                    page2Resources, res)
                if new:
                    newResources[NO(res)] = new
                    rename.update(newrename)

            newResources[NO("/ProcSet")] = AO(
                frozenset(orgResources.get("/ProcSet", AO()).getObject()).union(
                    frozenset(page2Resources.get("/ProcSet", AO()).getObject())
                )
            )

            newContentArray = AO()
            orgContent = page1["/Contents"].getObject()
            newContentArray.append(PO._pushPopGS(orgContent, page1.pdf))
            page2Content = page2['/Contents'].getObject()
            page2Content = PO._contentStreamRename(page2Content, rename,
                                                   page1.pdf)
            page2Content = ContentStream(page2Content, page1.pdf)
            page2Content.operations.insert(0, [[], "q"])

            # handle rotation
            try:
                rotation = page2["/Rotate"].getObject()
            except KeyError:
                rotation = 0
            if rotation in (180, 270):
                dw, dh = destWidth, destHeight
                arr = [-xScale, 0, 0, -yScale, destX + dw, destY + dh]
            elif rotation in (0, 90):
                arr = [xScale, 0, 0, yScale, destX, destY]
            else:
                # treat any other (illegal) rotation as 0
                arr = [xScale, 0, 0, yScale, destX, destY]

            arr = [FloatObject(str(x)) for x in arr]
            page2Content.operations.insert(1, [arr, "cm"])
            page2Content.operations.append([[], "Q"])
            newContentArray.append(page2Content)
            page1[NO('/Contents')] = ContentStream(newContentArray, page1.pdf)
            page1[NO('/Resources')] = newResources

        output.addPage(page1)

    if type(oppof) in (str,):
        outFile = open(outPath, "wb")
    output.write(outFile)

    if verbose:
        if type(oppof) in (str,):
            print(("written: %s" % outPath))
        elif isFileLike:
            print("written to file-like input parameter")

    return outPath
Example #21
0
    def createHighlight(self,x1, y1, x2, y2, meta, color = [1, 0, 0]):
        newHighlight = DictionaryObject()

        newHighlight.update({
            NameObject("/F"): NumberObject(4),
            NameObject("/Type"): NameObject("/Annot"),
            NameObject("/Subtype"): NameObject("/Highlight"),

            NameObject("/T"): TextStringObject(meta["author"]),
            NameObject("/Contents"): TextStringObject(meta["contents"]),

            NameObject("/C"): ArrayObject([FloatObject(c) for c in color]),
            NameObject("/Rect"): ArrayObject([
                FloatObject(x1),
                FloatObject(y1),
                FloatObject(x2),
                FloatObject(y2)
            ]),
            NameObject("/QuadPoints"): ArrayObject([
                FloatObject(x1),
                FloatObject(y2),
                FloatObject(x2),
                FloatObject(y2),
                FloatObject(x1),
                FloatObject(y1),
                FloatObject(x2),
                FloatObject(y1)
            ]),
        })

        return newHighlight
Example #22
0
def createHighlight(x1, y1, x2, y2, meta, color=[1, 0, 0]):
    '''
	Create a highlight object which will be applied to a box in a PDF page (please,
	notice that coordinates start in the bottom left) with specific metadata and
	colors.
	'''
    newHighlight = DictionaryObject()

    newHighlight.update({
        NameObject("/F"):
        NumberObject(4),
        NameObject("/Type"):
        NameObject("/Annot"),
        NameObject("/Subtype"):
        NameObject("/Highlight"),
        NameObject("/T"):
        TextStringObject(meta["author"]),
        NameObject("/Contents"):
        TextStringObject(meta["contents"]),
        NameObject("/C"):
        ArrayObject([FloatObject(c) for c in color]),
        NameObject("/Rect"):
        ArrayObject([
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x2),
            FloatObject(y2)
        ]),
        NameObject("/QuadPoints"):
        ArrayObject([
            FloatObject(x1),
            FloatObject(y2),
            FloatObject(x2),
            FloatObject(y2),
            FloatObject(x1),
            FloatObject(y1),
            FloatObject(x2),
            FloatObject(y1)
        ]),
    })
    return newHighlight
Example #23
0
def test_destination_fit_v():
    Destination(NameObject("title"), NullObject(), NameObject(TF.FIT_V),
                FloatObject(0))