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
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)
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
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
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
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>>"
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)
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
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()
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
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
def test_float_object_exception(): assert FloatObject("abc") == 0
def test_destination_exception(): with pytest.raises(PdfReadError): Destination(NameObject("title"), NullObject(), NameObject("foo"), FloatObject(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()
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)
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
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
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
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
def test_destination_fit_v(): Destination(NameObject("title"), NullObject(), NameObject(TF.FIT_V), FloatObject(0))