def setup_images(self): for key, name in self.icons.items(): try: path = os.path.join(self.theme_path, name) img = cairocffi.ImageSurface.create_from_png(path) except (cairocffi.Error, FileNotFoundError): self.theme_path = None logger.warning('VolumeIcons wrong icons path') return input_width = img.get_width() input_height = img.get_height() size = self.fontsize sp = input_height / size width = input_width / sp if width > self.length: # cast to `int` only after handling all potentially-float values self.length = int(width + self.actual_padding * 2) imgpat = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() scaler.scale(sp, sp) translate_y = (self.bar.height - size) // 2 scaler.translate(self.actual_padding * -1, -translate_y) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) self.surfaces[key] = imgpat
def setup_images(self): for key, name in self.icons.items(): try: path = os.path.join(self.theme_path, name) img = cairocffi.ImageSurface.create_from_png(path) except cairocffi.Error: self.theme_path = None self.qtile.log.warning('Battery Icon switching to text mode') return input_width = img.get_width() input_height = img.get_height() sp = input_height / float(self.bar.height - 1) width = input_width / sp if width > self.width: self.width = int(width) + self.actual_padding * 2 imgpat = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() scaler.scale(sp, sp) scaler.translate(self.actual_padding * -1, 0) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) self.surfaces[key] = imgpat
def get_cairo_pattern(surface, width=None, height=None, theta=0.0): """Return a SurfacePattern from an ImageSurface. if width and height are not None scale the pattern to be size width and height. theta is in degrees ccw """ pattern = cairocffi.SurfacePattern(surface) pattern.set_filter(cairocffi.FILTER_BEST) matrix = cairocffi.Matrix() tr_width, tr_height = 1.0, 1.0 surf_width, surf_height = surface.get_width(), surface.get_height() if (width is not None) and (width != surf_width): tr_width = surf_width / width if (height is not None) and (height != surf_height): tr_height = surf_height / height matrix.scale(tr_width, tr_height) epsilon = 1.0e-6 pi = 3.141592653589793 if abs(theta) > epsilon: theta_rad = pi / 180.0 * theta mat_rot = cairocffi.Matrix() # https://cairographics.org/cookbook/transform_about_point/ xt = surf_width * tr_width * 0.5 yt = surf_height * tr_height * 0.5 mat_rot.translate(xt, yt) mat_rot.rotate(theta_rad) mat_rot.translate(-xt, -yt) matrix = mat_rot.multiply(matrix) pattern.set_matrix(matrix) return pattern
def setup_images(self): """ Create image structures for each icon files. """ for img_name, iconfile in self.icons_files.items(): try: img = cairocffi.ImageSurface.create_from_png(iconfile) except cairocffi.Error: self.qtile.log.exception('No icon found for application ' + img_name + '(' + iconfile + ')') return input_width = img.get_width() input_height = img.get_height() sp = input_height / float(self.bar.height - 4) width = input_width / sp if width > self.width: self.width = int(width) + self.padding * 2 imgpat = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() scaler.scale(sp, sp) scaler.translate(self.padding * -1, -2) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) self.surfaces[img_name] = imgpat self.icons_widths[img_name] = width
def _configure(self, qtile, bar): base._Widget._configure(self, qtile, bar) if not self.filename: raise ValueError("Filename not set!") self.filename = os.path.expanduser(self.filename) try: self.image = cairocffi.ImageSurface.create_from_png(self.filename) except MemoryError: raise ValueError("The image '%s' doesn't seem to be a valid PNG" % (self.filename)) self.pattern = cairocffi.SurfacePattern(self.image) self.image_width = self.image.get_width() self.image_height = self.image.get_height() if self.scale: new_height = self.bar.height - (self.margin_y * 2) if new_height and self.image_height != new_height: scaler = cairocffi.Matrix() sp = self.image_height / float(new_height) self.image_height = new_height self.image_width = int(self.image_width / sp) scaler.scale(sp, sp) self.pattern.set_matrix(scaler)
def get_window_icon(self, window): if not window.icons: return None wid = window.window.wid state = WindowState.from_window( window, current_window=self.bar.screen.group.current_window, ) cache = self._icons_cache if wid in cache: if state in cache[wid]: return cache[wid][state] else: cache[wid] = {} surface = self._icon_render(window, self.icon_size, state=state) width, height = util.cairo.get_surface_size(surface) pattern = cairocffi.SurfacePattern(surface) size = max(width, height) if size != self.icon_size: pattern.set_matrix(self._icon_scale_matrix( self.icon_size, size, )) cache[wid][state] = pattern return pattern
def silt_pattern(): p_surface = \ cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 32, 8)) ctx = cairo.Context(p_surface) ctx.set_line_width(.5) ctx.set_line_cap(cairo.LINE_CAP_ROUND) r = 0.5 sc = 2 yoffs = 1 ctx.set_source_rgb(0, 0, 0) def dot(x, y): ctx.arc(x * sc, y * sc + yoffs, r, 0, 2 * pi) ctx.fill() def hz_line(x0, x1, y): ctx.move_to(x0 * sc, y * sc + yoffs) ctx.line_to(x1 * sc, y * sc + yoffs) ctx.stroke() hz_line(0.2, 7.8, 1) hz_line(8.2, 15.8, 3) for x in 10, 12, 14: dot(x, 1) for x in 2, 4, 6: dot(x, 3) pattern = cairo.SurfacePattern(p_surface) pattern.set_extend(cairo.EXTEND_REPEAT) return pattern
def get_window_icon(self, window): if not window.icons: return None cache = self._icons_cache.get(window.wid) if cache: return cache icons = sorted( iter(window.icons.items()), key=lambda x: abs(self.icon_size - int(x[0].split("x")[0])) ) icon = icons[0] width, height = map(int, icon[0].split("x")) img = cairocffi.ImageSurface.create_for_data( icon[1], cairocffi.FORMAT_ARGB32, width, height ) surface = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() if height != self.icon_size: sp = height / self.icon_size height = self.icon_size width /= sp scaler.scale(sp, sp) surface.set_matrix(scaler) self._icons_cache[window.wid] = surface return surface
def setup_images(self): for img_name in ('audio-volume-high', 'audio-volume-low', 'audio-volume-medium', 'audio-volume-muted'): try: img = cairocffi.ImageSurface.create_from_png( os.path.join(self.theme_path, '%s.png' % img_name)) except cairocffi.Error: self.theme_path = None self.length_type = bar.CALCULATED logger.exception('Volume switching to text mode') return input_width = img.get_width() input_height = img.get_height() sp = input_height / float(self.bar.height - 1) width = input_width / sp if width > self.length: self.length = int(width) + self.actual_padding * 2 imgpat = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() scaler.scale(sp, sp) scaler.translate(self.actual_padding * -1, 0) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) self.surfaces[img_name] = imgpat
def draw_background_image(context, layer, image_rendering): # Background image if layer.image is None: return painting_x, painting_y, painting_width, painting_height = ( layer.painting_area) positioning_x, positioning_y, positioning_width, positioning_height = ( layer.positioning_area) position_x, position_y = layer.position repeat_x, repeat_y = layer.repeat image_width, image_height = layer.size if repeat_x == 'no-repeat': repeat_width = painting_width * 2 elif repeat_x in ('repeat', 'round'): repeat_width = image_width else: assert repeat_x == 'space' n_repeats = math.floor(positioning_width / image_width) if n_repeats >= 2: repeat_width = (positioning_width - image_width) / (n_repeats - 1) position_x = 0 # Ignore background-position for this dimension else: repeat_width = image_width if repeat_y == 'no-repeat': repeat_height = painting_height * 2 elif repeat_y in ('repeat', 'round'): repeat_height = image_height else: assert repeat_y == 'space' n_repeats = math.floor(positioning_height / image_height) if n_repeats >= 2: repeat_height = ( positioning_height - image_height) / (n_repeats - 1) position_y = 0 # Ignore background-position for this dimension else: repeat_height = image_height sub_surface = cairo.PDFSurface(None, repeat_width, repeat_height) sub_context = cairo.Context(sub_surface) sub_context.rectangle(0, 0, image_width, image_height) sub_context.clip() layer.image.draw(sub_context, image_width, image_height, image_rendering) pattern = cairo.SurfacePattern(sub_surface) pattern.set_extend(cairo.EXTEND_REPEAT) with stacked(context): if not layer.unbounded: context.rectangle(painting_x, painting_y, painting_width, painting_height) context.clip() # else: unrestricted, whole page box context.translate(positioning_x + position_x, positioning_y + position_y) context.set_source(pattern) context.paint()
def grayscale(surface): width, height = get_surface_size(surface) pattern = cairocffi.SurfacePattern(surface) ctx = cairocffi.Context(surface) ctx.rectangle(0, 0, width, height) ctx.set_source_rgb(0, 0, 0) ctx.set_operator(cairocffi.OPERATOR_HSL_SATURATION) ctx.mask(pattern)
def _paint(self, color=None, alpha=None): color = color if color is not None else self.color alpha = alpha if alpha is not None else self.alpha ptn = cairo.SurfacePattern(self.active_layer) ptn.set_matrix(self.active_matrix) self.output_ctx.set_source_rgba(*color, alpha=alpha) self.output_ctx.mask(ptn) self.ctx = None self.active_layer = None self.active_matrix = None
def burrow_pattern(): p_surface = \ cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 36, 36)) ctx = cairo.Context(p_surface) random.seed(17) ctx.set_source_rgb(0, 0, 0) for x in range(0, 4): for y in range(0, 2): burrow(ctx, 4.5 + x * 24 + random.random() * 8, 9 + y * 36 + random.random() * 8 + x * 8, 2) pattern = cairo.SurfacePattern(p_surface) pattern.set_extend(cairo.EXTEND_REPEAT) return pattern
def setup_images(self): """Create image structures for each icon files.""" for img_name, iconfile in self.icons_files.items(): if iconfile is None: logger.warning( 'No icon found for application "%s" (%s) switch to text mode', img_name, iconfile, ) # if no icon is found and no default icon was set, we just # print the name, based on a textbox. textbox = base._TextBox() textbox._configure(self.qtile, self.bar) textbox.layout = self.drawer.textlayout( textbox.text, self.foreground, self.font, self.fontsize, self.fontshadow, markup=textbox.markup, ) # the name will be displayed textbox.text = img_name textbox.calculate_length() self.icons_widths[img_name] = textbox.width self.surfaces[img_name] = textbox continue else: try: img = cairocffi.ImageSurface.create_from_png(iconfile) except cairocffi.Error: logger.exception( 'Error loading icon for application "%s" (%s)', img_name, iconfile) return input_width = img.get_width() input_height = img.get_height() sp = input_height / (self.bar.height - 4) width = int(input_width / sp) imgpat = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() scaler.scale(sp, sp) scaler.translate(self.padding * -1, -2) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) self.surfaces[img_name] = imgpat self.icons_widths[img_name] = width
def _setup_images(self): """ Loads layout icons. """ for layout_name in self._get_layout_names(): icon_file_path = self.find_icon_file_path(layout_name) if icon_file_path is None: logger.warning('No icon found for layout "{}"'.format(layout_name)) icon_file_path = self.find_icon_file_path("unknown") try: img = cairocffi.ImageSurface.create_from_png(icon_file_path) except (cairocffi.Error, IOError) as e: # Icon file is guaranteed to exist at this point. # If this exception happens, it means the icon file contains # an invalid image or is not readable. self.icons_loaded = False logger.exception( 'Failed to load icon from file "{}", ' "error was: {}".format(icon_file_path, e.message) ) return input_width = img.get_width() input_height = img.get_height() sp = input_height / (self.bar.height - 1) width = input_width / sp if width > self.length: self.length = int(width) + self.actual_padding * 2 imgpat = cairocffi.SurfacePattern(img) scaler = cairocffi.Matrix() scaler.scale(sp, sp) scaler.scale(self.scale, self.scale) factor = (1 - 1 / self.scale) / 2 scaler.translate(-width * factor, -width * factor) scaler.translate(self.actual_padding * -1, 0) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) self.surfaces[layout_name] = imgpat self.icons_loaded = True
def make_cairo_pattern(self): pat = cairo.SurfacePattern(self._cairo_surface) pat.set_filter({"best": cairo.FILTER_BEST, "nearest": cairo.FILTER_NEAREST, "gaussian": cairo.FILTER_GAUSSIAN, "good": cairo.FILTER_GOOD, "bilinear": cairo.FILTER_BILINEAR, "fast": cairo.FILTER_FAST}[self.filter]) pat.set_extend({"none": cairo.EXTEND_NONE, "repeat": cairo.EXTEND_REPEAT, "reflect": cairo.EXTEND_REFLECT, "pad": cairo.EXTEND_PAD}[self.extend]) pat.set_matrix(self._cairo_matrix()) return pat
def test_low_level_api(): """Test the low-level Python API with various parameters.""" expected_content = svg2png(SVG_SAMPLE) # Same as above, longer version tree = parser.Tree(bytestring=SVG_SAMPLE) file_like = io.BytesIO() png_surface = surface.PNGSurface(tree, file_like, 96) png_surface.finish() assert file_like.getvalue() == expected_content png_result = cairo.ImageSurface.create_from_png( io.BytesIO(expected_content)) expected_width = png_result.get_width() expected_height = png_result.get_height() # Abstract surface png_surface = surface.PNGSurface(tree, None, 96) assert png_surface.width == expected_width assert png_surface.height == expected_height assert cairo.SurfacePattern(png_surface.cairo)
def sand_pattern(): p_surface = \ cairo.RecordingSurface(cairo.CONTENT_COLOR_ALPHA, (0, 0, 36, 36)) p_ctx = cairo.Context(p_surface) r = 0.5 wiggle = 3 sc = 3.6 offs = 1.8 random.seed(11) p_ctx.set_source_rgb(0, 0, 0) for x in range(0, 10): for y in range(0, 10): p_ctx.arc(offs + x * sc + random.random() * wiggle - wiggle / 2, offs + y * sc + random.random() * wiggle - wiggle / 2, r, 0, 2 * pi) p_ctx.fill() # for x in range(0,2): # for y in range(0,2): # burrow(p_ctx, 4.5+x*18+random.random()*8.-8./2., # 9+y*18+random.random()*8.-8./2., 2) pattern = cairo.SurfacePattern(p_surface) pattern.set_extend(cairo.EXTEND_REPEAT) return pattern
def update_icons(self): w, h = self.icon_size sp = h / float(self.bar.height - 1) icons = [] widths = [] for gen in self.icon_gen: img = cairocffi.ImageSurface(cairocffi.FORMAT_ARGB32, w, h) ctx = cairocffi.Context(img) self.gen_icon(gen, ctx) scaler = cairocffi.Matrix() scaler.scale(sp, sp) imgpat = cairocffi.SurfacePattern(img) imgpat.set_matrix(scaler) imgpat.set_filter(cairocffi.FILTER_BEST) icons.append(imgpat) widths.append(w / sp) self.icon_current = icons self.icon_widths = widths
def draw_background_image(context, layer, image_rendering): if layer.image is None: return painting_x, painting_y, painting_width, painting_height = ( layer.painting_area) positioning_x, positioning_y, positioning_width, positioning_height = ( layer.positioning_area) position_x, position_y = layer.position repeat_x, repeat_y = layer.repeat image_width, image_height = layer.size if repeat_x == 'no-repeat': # We want at least the whole image_width drawn on sub_surface, but we # want to be sure it will not be repeated on the painting_width. repeat_width = max(image_width, painting_width) elif repeat_x in ('repeat', 'round'): # We repeat the image each image_width. repeat_width = image_width else: assert repeat_x == 'space' n_repeats = floor(positioning_width / image_width) if n_repeats >= 2: # The repeat width is the whole positioning width with one image # removed, divided by (the number of repeated images - 1). This # way, we get the width of one image + one space. We ignore # background-position for this dimension. repeat_width = (positioning_width - image_width) / (n_repeats - 1) position_x = 0 else: # We don't repeat the image. repeat_width = image_width # Comments above apply here too. if repeat_y == 'no-repeat': repeat_height = max(image_height, painting_height) elif repeat_y in ('repeat', 'round'): repeat_height = image_height else: assert repeat_y == 'space' n_repeats = floor(positioning_height / image_height) if n_repeats >= 2: repeat_height = (positioning_height - image_height) / (n_repeats - 1) position_y = 0 else: repeat_height = image_height sub_surface = cairo.PDFSurface(None, repeat_width, repeat_height) sub_context = cairo.Context(sub_surface) sub_context.rectangle(0, 0, image_width, image_height) sub_context.clip() layer.image.draw(sub_context, image_width, image_height, image_rendering) pattern = cairo.SurfacePattern(sub_surface) if repeat_x == repeat_y == 'no-repeat': pattern.set_extend(cairo.EXTEND_NONE) else: pattern.set_extend(cairo.EXTEND_REPEAT) with stacked(context): if not layer.unbounded: context.rectangle(painting_x, painting_y, painting_width, painting_height) context.clip() # else: unrestricted, whole page box context.translate(positioning_x + position_x, positioning_y + position_y) context.set_source(pattern) context.paint()
def _render_mask(self): self.ctx.set_operator(cairo.OPERATOR_OVER) ptn = cairo.SurfacePattern(self.mask) ptn.set_matrix(cairo.Matrix(xx=1.0, yy=-1.0, x0=-self.origin_in_pixels[0], y0=self.size_in_pixels[1] + self.origin_in_pixels[1])) self.ctx.set_source(ptn) self.ctx.paint()
def convert_page(path, note_name, notebook_path, directory, pdf_file, page_number): page = papyrus_pb2.Page() # Open and parse papyrus page using protobuf page.ParseFromString(open(path, 'rb').read()) # Create a new pdf surface for drawing if page.background.width == 0 and page.background.height == 0: print("\tInfinite page!") max_x = 0 max_y = 0 for item in page.layer.item: bounds = None if item.type == papyrus_pb2.Item.Type.Value('Stroke'): bounds = item.stroke.bounds elif item.type == papyrus_pb2.Item.Type.Value('Shape'): if item.shape.type == 'Ellipse': bounds = item.shape.ellipse.bounds elif item.type == papyrus_pb2.Item.Type.Value('Text'): bounds = item.text.bounds else: print(item) if bounds is not None: if bounds.right > max_x: max_x = bounds.right if bounds.bottom > max_y: max_y = bounds.bottom page.background.width = max_x + 1 page.background.height = max_y + 1 note_name = titlesafe(note_name) print("\t%s" % note_name) note_path = directory + '/' + notebook_path + '/' + dirsafe(note_name) new_note_path = note_path num = 1 #while os.path.exists(new_note_path): # new_note_path = note_path + '(' + str(num) + ')' # num += 1 makedir(note_path) note_path = new_note_path pdfpath = note_path + '/pdf' makedir(pdfpath) pdffile = pdfpath + '/page' + str(page_number) + '.pdf' print("\tSource: %s\n\tOutput: %s" % (path, pdffile)) pdf_out = open(pdffile, 'w') surface = cairocffi.PDFSurface(pdf_out, cm_to_point(page.background.width), cm_to_point(page.background.height)) context = cairocffi.Context(surface) # Paint the page white context.set_source_rgba(0, 0, 0, 0) context.paint() for item in page.layer.item: if item.type == papyrus_pb2.Item.Type.Value('Stroke'): context.save() # Translate to reference_point (stroke origin) context.translate(cm_to_point(item.stroke.reference_point.x), cm_to_point(item.stroke.reference_point.y)) # Set source color argb = u32_to_4f(item.stroke.color) context.set_source_rgba(argb[1], argb[2], argb[3], argb[0]) # Set line width width = cm_to_point(item.stroke.weight) # Other parameter context.set_line_join(cairocffi.LINE_JOIN_ROUND) context.set_line_cap(cairocffi.LINE_CAP_ROUND) context.move_to(0, 0) if item.stroke.stroke_type == papyrus_pb2.Stroke.Highlight: context.push_group() context.set_source_rgba(argb[1], argb[2], argb[3], 1) context.fill_preserve() context.set_line_cap(cairocffi.LINE_CAP_SQUARE) for point in item.stroke.point: context.line_to(cm_to_point(point.x), cm_to_point(point.y)) if item.stroke.stroke_type == papyrus_pb2.Stroke.Highlight: context.set_line_width(width) #context. elif point.HasField('pressure'): context.set_line_width(width * point.pressure) else: context.set_line_width(width) context.stroke() context.move_to(cm_to_point(point.x), cm_to_point(point.y)) if item.stroke.stroke_type == papyrus_pb2.Stroke.Highlight: context.pop_group_to_source() context.paint_with_alpha(argb[0]) context.restore() elif item.type == papyrus_pb2.Item.Type.Value( 'Shape') and item.shape.ellipse is not None: width = item.shape.ellipse.weight * 0.3 context.save() context.new_sub_path() context.translate(cm_to_point(item.shape.ellipse.center_x), cm_to_point(item.shape.ellipse.center_y)) context.set_line_width(item.shape.ellipse.weight) argb = u32_to_4f(item.shape.ellipse.color) context.set_line_width(width) context.set_source_rgba(argb[1], argb[2], argb[3], argb[0]) context.scale(cm_to_point(item.shape.ellipse.radius_x), cm_to_point(item.shape.ellipse.radius_y)) context.arc(0, 0, 1, (item.shape.ellipse.start_angle / 360) * 2 * math.pi, (item.shape.ellipse.sweep_angle / 360) * 2 * math.pi) context.close_path() context.stroke() context.restore() elif item.type == papyrus_pb2.Item.Type.Value('Text'): context.save() context.set_font_size(item.text.weight) # Color argb = u32_to_4f(item.text.color) context.set_source_rgba(argb[1], argb[2], argb[3], argb[0]) context.move_to(cm_to_point(item.text.bounds.left), cm_to_point(item.text.bounds.top)) tw = int(item.text.weight) size_m = cairocffi.Matrix(tw, 0, 0, tw, 0, 0) scaledFont = cairocffi.ScaledFont( cairocffi.ToyFontFace("sans-serif"), size_m) glyphs = scaledFont.text_to_glyphs( cm_to_point(item.text.bounds.left), cm_to_point(item.text.bounds.bottom), item.text.text, False) context.show_glyphs(glyphs) context.restore() elif item.type == papyrus_pb2.Item.Type.Value('Image'): if (DEBUG): print("Got an image!") print(item.image.image_hash) # Convert JPEG image to PNG im = Image.open(base_directory + "data/imgs/" + item.image.image_hash) im = im.crop( (item.image.crop_bounds.left, item.image.crop_bounds.top, item.image.crop_bounds.right, item.image.crop_bounds.bottom)) im.save( base_directory + "data/imgs/" + item.image.image_hash + ".png", "PNG") im.close() matrix = cairocffi.Matrix() scale_x = cm_to_point(item.image.bounds.right - item.image.bounds.left) / ( item.image.crop_bounds.right - item.image.crop_bounds.left) scale_y = cm_to_point(item.image.bounds.bottom - item.image.bounds.top) / ( item.image.crop_bounds.bottom - item.image.crop_bounds.top) if (DEBUG): print("Scale X: %d" % (1 / scale_x)) print("Scale Y: %d" % (1 / scale_y)) print("Translate: %d" % cm_to_point(item.image.bounds.left)) matrix.scale(1 / scale_x, 1 / scale_y) matrix.translate(-cm_to_point(item.image.bounds.left), -cm_to_point(item.image.bounds.top)) im_surface = cairocffi.ImageSurface.create_from_png( base_directory + "./data/imgs/" + item.image.image_hash + ".png") im_surface_pattern = cairocffi.SurfacePattern(im_surface) im_surface_pattern.set_filter(cairocffi.FILTER_GOOD) im_surface_pattern.set_matrix(matrix) context.save() context.set_source(im_surface_pattern) context.rectangle( cm_to_point(item.image.bounds.left), cm_to_point(item.image.bounds.top), cm_to_point(item.image.bounds.right - item.image.bounds.left), cm_to_point(item.image.bounds.bottom - item.image.bounds.top)) context.fill() context.restore() else: print(item) print("Item of type {} not supported".format( papyrus_pb2.Item.Type.Name(item.type))) surface.flush() surface.finish() pdf_out.close() if page.background.HasField("pdf_background"): try: output_file = PdfFileWriter() input_file = PdfFileReader(file(pdffile, "rb")) pdf_file = PdfFileReader( file(base_directory + "data/docs/" + pdf_file, "rb")) pdf_page = pdf_file.getPage( page.background.pdf_background.page_number) input_page = input_file.getPage(0) pdf_page.mergePage(input_page) output_file.addPage(pdf_page) with open(pdffile + ".tmp", "wb") as outputStream: output_file.write(outputStream) os.rename(pdffile + ".tmp", pdffile) except: print( "\t%sUnable to merge PDFs - maybe the PDF was malformed? Result was %s%s" % (color.RED, sys.exc_info()[0], color.END)) print("") return pdffile