forked from openlp/openlp
620 lines
24 KiB
Python
620 lines
24 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
|
|
|
###############################################################################
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
# --------------------------------------------------------------------------- #
|
|
# Copyright (c) 2008-2010 Raoul Snyman #
|
|
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
|
|
# Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian #
|
|
# Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
|
# Carsten Tinggaard, Frode Woldsund #
|
|
# --------------------------------------------------------------------------- #
|
|
# This program is free software; you can redistribute it and/or modify it #
|
|
# under the terms of the GNU General Public License as published by the Free #
|
|
# Software Foundation; version 2 of the License. #
|
|
# #
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
|
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
|
# more details. #
|
|
# #
|
|
# You should have received a copy of the GNU General Public License along #
|
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
|
###############################################################################
|
|
"""
|
|
The :mod:`renderer` module enables OpenLP to take the input from plugins and
|
|
format it for the output display.
|
|
"""
|
|
import logging
|
|
|
|
from PyQt4 import QtGui, QtCore
|
|
|
|
from openlp.core.lib import resize_image
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
class Renderer(object):
|
|
"""
|
|
Genarates a pixmap image of a array of text. The Text is formatted to
|
|
make sure it fits on the screen and if not extra frames are generated.
|
|
"""
|
|
log.info(u'Renderer Loaded')
|
|
|
|
def __init__(self):
|
|
"""
|
|
Initialise the renderer.
|
|
"""
|
|
self._rect = None
|
|
self._debug = False
|
|
self._display_shadow_size_footer = 0
|
|
self._display_outline_size_footer = 0
|
|
self.theme_name = None
|
|
self._theme = None
|
|
self._bg_image_filename = None
|
|
self.frame = None
|
|
self.frame_opaque = None
|
|
self.bg_frame = None
|
|
self.bg_image = None
|
|
|
|
def set_debug(self, debug):
|
|
"""
|
|
Set the debug mode of the renderer.
|
|
|
|
``debug``
|
|
The debug mode.
|
|
"""
|
|
self._debug = debug
|
|
|
|
def set_theme(self, theme):
|
|
"""
|
|
Set the theme to be used.
|
|
|
|
``theme``
|
|
The theme to be used.
|
|
"""
|
|
log.debug(u'set theme')
|
|
self._theme = theme
|
|
self.bg_frame = None
|
|
self.bg_image = None
|
|
self._bg_image_filename = None
|
|
self.theme_name = theme.theme_name
|
|
#self._set_theme_font()
|
|
if theme.background_type == u'image':
|
|
if theme.background_filename:
|
|
self.set_bg_image(theme.background_filename)
|
|
|
|
def set_bg_image(self, filename):
|
|
"""
|
|
Set a background image.
|
|
|
|
``filename``
|
|
The name of the image file.
|
|
"""
|
|
log.debug(u'set bg image %s', filename)
|
|
self._bg_image_filename = unicode(filename)
|
|
if self.frame:
|
|
self.bg_image = resize_image(self._bg_image_filename,
|
|
self.frame.width(),
|
|
self.frame.height())
|
|
|
|
def set_text_rectangle(self, rect_main, rect_footer):
|
|
"""
|
|
Sets the rectangle within which text should be rendered.
|
|
|
|
``rect_main``
|
|
The main text block.
|
|
|
|
``rect_footer``
|
|
The footer text block.
|
|
"""
|
|
log.debug(u'set_text_rectangle %s , %s' % (rect_main, rect_footer))
|
|
self._rect = rect_main
|
|
self._rect_footer = rect_footer
|
|
|
|
def set_frame_dest(self, frame_width, frame_height, preview=False):
|
|
"""
|
|
Set the size of the slide.
|
|
|
|
``frame_width``
|
|
The width of the slide.
|
|
|
|
``frame_height``
|
|
The height of the slide.
|
|
|
|
``preview``
|
|
Defaults to *False*. Whether or not to generate a preview.
|
|
"""
|
|
if preview:
|
|
self.bg_frame = None
|
|
log.debug(u'set frame dest (frame) w %d h %d', frame_width,
|
|
frame_height)
|
|
self.frame = QtGui.QImage(frame_width, frame_height,
|
|
QtGui.QImage.Format_ARGB32_Premultiplied)
|
|
if self._bg_image_filename and not self.bg_image:
|
|
self.bg_image = resize_image(self._bg_image_filename,
|
|
self.frame.width(), self.frame.height())
|
|
if self.bg_frame is None:
|
|
self._generate_background_frame()
|
|
|
|
def format_slide(self, words, line_break):
|
|
"""
|
|
Figure out how much text can appear on a slide, using the current
|
|
theme settings.
|
|
|
|
``words``
|
|
The words to be fitted on the slide.
|
|
"""
|
|
log.debug(u'format_slide - Start')
|
|
line_end = u''
|
|
if line_break:
|
|
line_end = u'<br>'
|
|
words = words.replace(u'\r\n', u'\n')
|
|
verses_text = words.split(u'\n')
|
|
text = []
|
|
for verse in verses_text:
|
|
lines = verse.split(u'\n')
|
|
for line in lines:
|
|
text.append(line)
|
|
doc = QtGui.QTextDocument()
|
|
doc.setPageSize(QtCore.QSizeF(self._rect.width(), self._rect.height()))
|
|
df = doc.defaultFont()
|
|
df.setPixelSize(self._theme.font_main_proportion)
|
|
df.setFamily(self._theme.font_main_name)
|
|
main_weight = 50
|
|
if self._theme.font_main_weight == u'Bold':
|
|
main_weight = 75
|
|
df.setWeight(main_weight)
|
|
doc.setDefaultFont(df)
|
|
layout = doc.documentLayout()
|
|
formatted = []
|
|
shell = u'<p>%s</p>'
|
|
temp_text = u''
|
|
old_html_text = u''
|
|
for line in text:
|
|
# mark line ends
|
|
temp_text = temp_text + line + line_end
|
|
html_text = shell % temp_text
|
|
doc.setHtml(html_text)
|
|
#Text too long so gone to next mage
|
|
if layout.pageCount() != 1:
|
|
formatted.append(shell % old_html_text)
|
|
temp_text = line
|
|
old_html_text = temp_text
|
|
formatted.append(shell % old_html_text)
|
|
log.debug(u'format_slide - End')
|
|
return formatted
|
|
|
|
# def pre_render_text(self, text):
|
|
# metrics = QtGui.QFontMetrics(self.main_font)
|
|
# #work out line width
|
|
# line_width = self._rect.width()
|
|
# #number of lines on a page - adjust for rounding up.
|
|
# line_height = metrics.height()
|
|
# if self._theme.display_shadow:
|
|
# line_height += int(self._theme.display_shadow_size)
|
|
# if self._theme.display_outline:
|
|
# # pixels top/bottom
|
|
# line_height += 2 * int(self._theme.display_outline_size)
|
|
# page_length = int(self._rect.height() / line_height )
|
|
# #Average number of characters in line
|
|
# ave_line_width = line_width / metrics.averageCharWidth()
|
|
# #Maximum size of a character
|
|
# max_char_width = metrics.maxWidth()
|
|
# #Max characters pre line based on min size of a character
|
|
# char_per_line = line_width / metrics.width(u'i')
|
|
# log.debug(u'Page Length area height %s , metrics %s , lines %s' %
|
|
# (int(self._rect.height()), metrics.height(), page_length ))
|
|
# split_pages = []
|
|
# page = []
|
|
# split_lines = []
|
|
# count = 0
|
|
# for line in text:
|
|
# #Must be a blank line so keep it.
|
|
# if len(line) == 0:
|
|
# line = u' '
|
|
# while line:
|
|
# pos = char_per_line
|
|
# split_text = line[:pos]
|
|
# #line needs splitting
|
|
# if metrics.width(split_text, -1) > line_width:
|
|
# #We have no spaces
|
|
# if split_text.find(u' ') == -1:
|
|
# #Move back 1 char at a time till it fits
|
|
# while metrics.width(split_text, -1) > line_width:
|
|
# split_text = split_text[:-1]
|
|
# pos = len(split_text)
|
|
# else:
|
|
# #We have spaces so split at previous one
|
|
# while metrics.width(split_text, -1) > line_width:
|
|
# pos = split_text.rfind(u' ')
|
|
# #no more spaces and we are still too long
|
|
# if pos == -1:
|
|
# while \
|
|
# metrics.width(split_text, -1) > line_width:
|
|
# split_text = split_text[:-1]
|
|
# pos = len(split_text)
|
|
# else:
|
|
# split_text = line[:pos]
|
|
# split_lines.append(split_text)
|
|
# line = line[pos:].lstrip()
|
|
# #if we have more text add up to 10 spaces on the front.
|
|
# if line and self._theme.font_main_indentation > 0:
|
|
# line = u'%s%s' % \
|
|
# (u' '[:int(self._theme.font_main_indentation)],
|
|
# line)
|
|
# #Text fits in a line now
|
|
# for count, line in enumerate(split_lines):
|
|
# page.append(line)
|
|
# #last but one line and only 2 lines to go or end of page
|
|
# if (len(page) == page_length - 1 and
|
|
# len(split_lines) - 3 == count) or \
|
|
# len(page) == page_length:
|
|
# split_pages.append(page)
|
|
# page = []
|
|
# if page and page != u' ':
|
|
# split_pages.append(page)
|
|
# return split_pages
|
|
#
|
|
# def generate_frame_from_lines(self, lines, footer_lines=None):
|
|
# """
|
|
# Render a set of lines according to the theme, and return the block
|
|
# dimensions.
|
|
#
|
|
# ``lines``
|
|
# The lines to be rendered.
|
|
#
|
|
# ``footer_lines``
|
|
# Defaults to *None*. The footer to render.
|
|
# """
|
|
# log.debug(u'generate_frame_from_lines - Start')
|
|
# bbox = self._render_lines_unaligned(lines, False)
|
|
# if footer_lines:
|
|
# bbox1 = self._render_lines_unaligned(footer_lines, True)
|
|
# # reset the frame. first time do not worry about what you paint on.
|
|
# self.frame = QtGui.QImage(self.bg_frame)
|
|
# if self._theme.display_slideTransition:
|
|
# self.frame_opaque = QtGui.QImage(self.bg_frame)
|
|
# x, y = self._correct_alignment(self._rect, bbox)
|
|
# bbox = self._render_lines_unaligned(lines, False, (x, y), True)
|
|
# if footer_lines:
|
|
# bbox = self._render_lines_unaligned(footer_lines, True,
|
|
# (self._rect_footer.left(), self._rect_footer.top()), True)
|
|
# log.debug(u'generate_frame_from_lines - Finish')
|
|
# if self._theme.display_slideTransition:
|
|
# return {u'main':self.frame, u'trans':self.frame_opaque}
|
|
# else:
|
|
# return {u'main':self.frame, u'trans':None}
|
|
|
|
def _generate_background_frame(self):
|
|
"""
|
|
Generate a background frame to the same size as the frame to be used.
|
|
Results are cached for performance reasons.
|
|
"""
|
|
assert(self._theme)
|
|
# if self._theme.background_mode == u'transparent':
|
|
# self.bg_frame = \
|
|
# QtGui.QPixmap(self.frame.width(), self.frame.height())
|
|
# self.bg_frame.fill(QtCore.Qt.transparent)
|
|
# else:
|
|
self.bg_frame = QtGui.QImage(self.frame.width(),
|
|
self.frame.height(), QtGui.QImage.Format_ARGB32_Premultiplied)
|
|
log.debug(u'render background %s start', self._theme.background_type)
|
|
painter = QtGui.QPainter()
|
|
painter.begin(self.bg_frame)
|
|
# if self._theme.background_mode == u'transparent':
|
|
# painter.fillRect(self.frame.rect(), QtCore.Qt.transparent)
|
|
# else:
|
|
if self._theme.background_type == u'solid':
|
|
painter.fillRect(self.frame.rect(),
|
|
QtGui.QColor(self._theme.background_color))
|
|
elif self._theme.background_type == u'gradient':
|
|
# gradient
|
|
gradient = None
|
|
if self._theme.background_direction == u'horizontal':
|
|
w = int(self.frame.width()) / 2
|
|
# vertical
|
|
gradient = QtGui.QLinearGradient(w, 0, w,
|
|
self.frame.height())
|
|
elif self._theme.background_direction == u'vertical':
|
|
h = int(self.frame.height()) / 2
|
|
# Horizontal
|
|
gradient = QtGui.QLinearGradient(0, h, self.frame.width(),
|
|
h)
|
|
else:
|
|
w = int(self.frame.width()) / 2
|
|
h = int(self.frame.height()) / 2
|
|
# Circular
|
|
gradient = QtGui.QRadialGradient(w, h, w)
|
|
gradient.setColorAt(0,
|
|
QtGui.QColor(self._theme.background_startColor))
|
|
gradient.setColorAt(1,
|
|
QtGui.QColor(self._theme.background_endColor))
|
|
painter.setBrush(QtGui.QBrush(gradient))
|
|
rect_path = QtGui.QPainterPath()
|
|
max_x = self.frame.width()
|
|
max_y = self.frame.height()
|
|
rect_path.moveTo(0, 0)
|
|
rect_path.lineTo(0, max_y)
|
|
rect_path.lineTo(max_x, max_y)
|
|
rect_path.lineTo(max_x, 0)
|
|
rect_path.closeSubpath()
|
|
painter.drawPath(rect_path)
|
|
elif self._theme.background_type == u'image':
|
|
# image
|
|
painter.fillRect(self.frame.rect(), QtCore.Qt.black)
|
|
if self.bg_image:
|
|
painter.drawImage(0, 0, self.bg_image)
|
|
painter.end()
|
|
log.debug(u'render background End')
|
|
|
|
# def _correct_alignment(self, rect, bbox):
|
|
# """
|
|
# Corrects the vertical alignment of text.
|
|
#
|
|
# ``rect``
|
|
# The block dimentions.
|
|
#
|
|
# ``bbox``
|
|
# Footer dimensions?
|
|
# """
|
|
# x = rect.left()
|
|
# if self._theme.display_verticalAlign == 0:
|
|
# # top align
|
|
# y = rect.top()
|
|
# elif self._theme.display_verticalAlign == 2:
|
|
# # bottom align
|
|
# y = rect.bottom() - bbox.height()
|
|
# elif self._theme.display_verticalAlign == 1:
|
|
# # centre align
|
|
# y = rect.top() + (rect.height() - bbox.height()) / 2
|
|
# else:
|
|
# log.error(u'Invalid value for theme.VerticalAlign:%s',
|
|
# self._theme.display_verticalAlign)
|
|
# return x, y
|
|
#
|
|
# def _render_lines_unaligned(self, lines, footer, tlcorner=(0, 0),
|
|
# live=False):
|
|
# """
|
|
# Given a list of lines to render, render each one in turn (using the
|
|
# ``_render_single_line`` fn - which may result in going off the bottom).
|
|
# They are expected to be pre-arranged to less than a screenful (eg. by
|
|
# using split_set_of_lines).
|
|
#
|
|
# Returns the bounding box of the text as QRect.
|
|
#
|
|
# ``lines``
|
|
# The lines of text to render.
|
|
#
|
|
# ``footer``
|
|
# The slide footer.
|
|
#
|
|
# ``tlcorner``
|
|
# Defaults to *``(0, 0)``*. Co-ordinates of the top left corner.
|
|
#
|
|
# ``live``
|
|
# Defaults to *False*. Whether or not this is a live screen.
|
|
# """
|
|
# x, y = tlcorner
|
|
# brx = x
|
|
# bry = y
|
|
# for line in lines:
|
|
# # render after current bottom, but at original left edge
|
|
# # keep track of right edge to see which is biggest
|
|
# (thisx, bry) = self._render_and_wrap_single_line(line, footer,
|
|
# (x, bry), live)
|
|
# if (thisx > brx):
|
|
# brx = thisx
|
|
# retval = QtCore.QRect(x, y, brx - x, bry - y)
|
|
# if self._debug:
|
|
# painter = QtGui.QPainter()
|
|
# painter.begin(self.frame)
|
|
# painter.setPen(QtGui.QPen(QtGui.QColor(0, 0, 255)))
|
|
# painter.drawRect(retval)
|
|
# painter.end()
|
|
# return retval
|
|
#
|
|
# def _render_and_wrap_single_line(self, line, footer, tlcorner=(0, 0),
|
|
# live=False):
|
|
# """
|
|
# Render a single line of words onto the DC, top left corner specified.
|
|
# If the line is too wide for the context, it wraps, but right-aligns
|
|
# the surplus words in the manner of song lyrics.
|
|
#
|
|
# Returns the bottom-right corner (of what was rendered) as a tuple(x, y).
|
|
#
|
|
# ``line``
|
|
# Line of text to be rendered.
|
|
#
|
|
# ``footer``
|
|
# The footer of the slide.
|
|
#
|
|
# ``tlcorner``
|
|
# Defaults to *``(0, 0)``*. The top left corner.
|
|
#
|
|
# ``live``
|
|
# Defaults to *False*. Whether or not this is a live screen.
|
|
# """
|
|
# x, y = tlcorner
|
|
# maxx = self._rect.width()
|
|
# maxy = self._rect.height()
|
|
# lines = []
|
|
# lines.append(line)
|
|
# startx = x
|
|
# starty = y
|
|
# rightextent = None
|
|
# self.painter = QtGui.QPainter()
|
|
# self.painter.begin(self.frame)
|
|
# self.painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
|
# if self._theme.display_slideTransition:
|
|
# self.painter2 = QtGui.QPainter()
|
|
# self.painter2.begin(self.frame_opaque)
|
|
# self.painter2.setRenderHint(QtGui.QPainter.Antialiasing)
|
|
# self.painter2.setOpacity(0.7)
|
|
# # dont allow alignment messing with footers
|
|
# if footer:
|
|
# align = 0
|
|
# display_shadow_size = self._display_shadow_size_footer
|
|
# display_outline_size = self._display_outline_size_footer
|
|
# else:
|
|
# align = self._theme.display_horizontalAlign
|
|
# display_shadow_size = int(self._theme.display_shadow_size)
|
|
# display_outline_size = int(self._theme.display_outline_size)
|
|
# for linenum in range(len(lines)):
|
|
# line = lines[linenum]
|
|
# #find out how wide line is
|
|
# w, h = self._get_extent_and_render(line, footer, tlcorner=(x, y),
|
|
# draw=False)
|
|
# if self._theme.display_shadow:
|
|
# w += display_shadow_size
|
|
# h += display_shadow_size
|
|
# if self._theme.display_outline:
|
|
# # pixels either side
|
|
# w += 2 * display_outline_size
|
|
# # pixels top/bottom
|
|
# h += 2 * display_outline_size
|
|
# if align == 0: # left align
|
|
# rightextent = x + w
|
|
# # shift right from last line's rh edge
|
|
# if self._theme.display_wrapStyle == 1 and linenum != 0:
|
|
# rightextent = self._first_line_right_extent
|
|
# if rightextent > maxx:
|
|
# rightextent = maxx
|
|
# x = rightextent - w
|
|
# # right align
|
|
# elif align == 1:
|
|
# rightextent = maxx
|
|
# x = maxx - w
|
|
# # centre
|
|
# elif align == 2:
|
|
# x = (maxx - w) / 2
|
|
# rightextent = x + w
|
|
# if live:
|
|
# # now draw the text, and any outlines/shadows
|
|
# if self._theme.display_shadow:
|
|
# self._get_extent_and_render(line, footer,
|
|
# tlcorner=(x + display_shadow_size,
|
|
# y + display_shadow_size),
|
|
# draw=True, color=self._theme.display_shadow_color)
|
|
# self._get_extent_and_render(line, footer, tlcorner=(x, y),
|
|
# draw=True, outline_size=display_outline_size)
|
|
# y += h
|
|
# if linenum == 0:
|
|
# self._first_line_right_extent = rightextent
|
|
# # draw a box around the text - debug only
|
|
#
|
|
# if self._debug:
|
|
# self.painter.setPen(QtGui.QPen(QtGui.QColor(0, 255, 0)))
|
|
# self.painter.drawRect(startx, starty, rightextent-startx, y-starty)
|
|
# brcorner = (rightextent, y)
|
|
# self.painter.end()
|
|
# if self._theme.display_slideTransition:
|
|
# self.painter2.end()
|
|
# return brcorner
|
|
#
|
|
# def _set_theme_font(self):
|
|
# """
|
|
# Set the fonts from the current theme settings.
|
|
# """
|
|
# footer_weight = 50
|
|
# if self._theme.font_footer_weight == u'Bold':
|
|
# footer_weight = 75
|
|
# #TODO Add myfont.setPixelSize((screen_height / 100) * font_size)
|
|
# self.footer_font = QtGui.QFont(self._theme.font_footer_name,
|
|
# self._theme.font_footer_proportion, # size
|
|
# footer_weight, # weight
|
|
# self._theme.font_footer_italics) # italic
|
|
# self.footer_font.setPixelSize(self._theme.font_footer_proportion)
|
|
# main_weight = 50
|
|
# if self._theme.font_main_weight == u'Bold':
|
|
# main_weight = 75
|
|
# self.main_font = QtGui.QFont(self._theme.font_main_name,
|
|
# self._theme.font_main_proportion, # size
|
|
# main_weight, # weight
|
|
# self._theme.font_main_italics)# italic
|
|
# self.main_font.setPixelSize(self._theme.font_main_proportion)
|
|
#
|
|
# def _get_extent_and_render(self, line, footer, tlcorner=(0, 0), draw=False,
|
|
# color=None, outline_size=0):
|
|
# """
|
|
# Find bounding box of text - as render_single_line. If draw is set,
|
|
# actually draw the text to the current DC as well return width and
|
|
# height of text as a tuple (w, h).
|
|
#
|
|
# ``line``
|
|
# The line of text to render.
|
|
#
|
|
# ``footer``
|
|
# The footer text.
|
|
#
|
|
# ``tlcorner``
|
|
# Defaults to *``(0, 0)``*. The top left corner co-ordinates.
|
|
#
|
|
# ``draw``
|
|
# Defaults to *False*. Draw the text to the current surface.
|
|
#
|
|
# ``color``
|
|
# Defaults to *None*. The colour to draw with.
|
|
# """
|
|
# # setup defaults
|
|
# if footer:
|
|
# font = self.footer_font
|
|
# else:
|
|
# font = self.main_font
|
|
# metrics = QtGui.QFontMetrics(font)
|
|
# w = metrics.width(line)
|
|
# if footer:
|
|
# h = metrics.height()
|
|
# else:
|
|
# h = metrics.height() + int(self._theme.font_main_line_adjustment)
|
|
# if draw:
|
|
# self.painter.setFont(font)
|
|
# if color is None:
|
|
# if footer:
|
|
# pen = QtGui.QColor(self._theme.font_footer_color)
|
|
# else:
|
|
# pen = QtGui.QColor(self._theme.font_main_color)
|
|
# else:
|
|
# pen = QtGui.QColor(color)
|
|
# x, y = tlcorner
|
|
# rowpos = y + metrics.ascent()
|
|
# if self._theme.display_outline and outline_size != 0 and not footer:
|
|
# path = QtGui.QPainterPath()
|
|
# path.addText(QtCore.QPointF(x, rowpos), font, line)
|
|
# self.painter.setBrush(self.painter.pen().brush())
|
|
# self.painter.setPen(QtGui.QPen(QtGui.QColor(
|
|
# self._theme.display_outline_color), outline_size))
|
|
# self.painter.drawPath(path)
|
|
# self.painter.setPen(pen)
|
|
# self.painter.drawText(x, rowpos, line)
|
|
# if self._theme.display_slideTransition:
|
|
# # Print 2nd image with 70% weight
|
|
# if self._theme.display_outline and outline_size != 0 and \
|
|
# not footer:
|
|
# path = QtGui.QPainterPath()
|
|
# path.addText(QtCore.QPointF(x, rowpos), font, line)
|
|
# self.painter2.setBrush(self.painter2.pen().brush())
|
|
# self.painter2.setPen(QtGui.QPen(
|
|
# QtGui.QColor(self._theme.display_outline_color),
|
|
# outline_size))
|
|
# self.painter2.drawPath(path)
|
|
# self.painter2.setFont(font)
|
|
# self.painter2.setPen(pen)
|
|
# self.painter2.drawText(x, rowpos, line)
|
|
# return (w, h)
|
|
#
|
|
# def snoop_image(self, image, image2=None):
|
|
# """
|
|
# Debugging method to allow images to be viewed.
|
|
#
|
|
# ``image``
|
|
# An image to save to disk.
|
|
#
|
|
# ``image2``
|
|
# Defaults to *None*. Another image to save to disk.
|
|
# """
|
|
# image.save(u'renderer.png', u'png')
|
|
# if image2:
|
|
# image2.save(u'renderer2.png', u'png')
|