Fix up renderer to protect it from Gushie

This commit is contained in:
Tim Bentley 2009-11-21 14:32:19 +00:00
parent b401179613
commit 56c69bd8e8
3 changed files with 85 additions and 68 deletions

View File

@ -168,35 +168,45 @@ class Renderer(object):
line_width = self._rect.width() - self._right_margin line_width = self._rect.width() - self._right_margin
#number of lines on a page - adjust for rounding up. #number of lines on a page - adjust for rounding up.
page_length = int(self._rect.height() / metrics.height() - 2 ) - 1 page_length = int(self._rect.height() / metrics.height() - 2 ) - 1
#Average number of characters in line
ave_line_width = line_width / metrics.averageCharWidth() ave_line_width = line_width / metrics.averageCharWidth()
ave_line_width = int(ave_line_width + (ave_line_width * 1)) #Maximum size of a character
max_char_width = metrics.maxWidth()
#Min size of a character
min_char_width = metrics.width(u'i')
char_per_line = line_width / min_char_width
log.debug(u'Page Length area height %s , metrics %s , lines %s' % log.debug(u'Page Length area height %s , metrics %s , lines %s' %
(int(self._rect.height()), metrics.height(), page_length )) (int(self._rect.height()), metrics.height(), page_length ))
split_pages = [] split_pages = []
page = [] page = []
split_lines = [] split_lines = []
count = 0
for line in text: for line in text:
#Must be a blank line so keep it. #Must be a blank line so keep it.
if len(line) == 0: if len(line) == 0:
line = u' ' line = u' '
while len(line) > 0: while len(line) > 0:
if len(line) > ave_line_width: pos = char_per_line
pos = line.find(u' ', ave_line_width) split_text = line[:pos]
split_text = line[:pos] #line needs splitting
else: if metrics.width(split_text, -1) > line_width:
pos = len(line) #We have no spaces
split_text = line if split_text.find(u' ') == -1:
while metrics.width(split_text, -1) > line_width: #Move back 1 char at a time till it fits
#Find the next space to the left
pos = line[:pos].rfind(u' ')
#no more spaces found
if pos == 0:
split_text = line
while metrics.width(split_text, -1) > line_width: while metrics.width(split_text, -1) > line_width:
split_text = split_text[:-1] split_text = split_text[:-1]
pos = len(split_text) pos = len(split_text)
else: else:
split_text = line[:pos] #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) split_lines.append(split_text)
line = line[pos:].lstrip() line = line[pos:].lstrip()
#if we have more text add up to 10 spaces on the front. #if we have more text add up to 10 spaces on the front.
@ -450,32 +460,32 @@ class Renderer(object):
draw=True, color = self._theme.display_shadow_color) draw=True, color = self._theme.display_shadow_color)
if self._theme.display_outline: if self._theme.display_outline:
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x+self._outline_offset, y), draw=True, (x + self._outline_offset, y), draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x, y+self._outline_offset), draw=True, (x, y + self._outline_offset), draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x, y-self._outline_offset), draw=True, (x, y - self._outline_offset), draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x-self._outline_offset, y), draw=True, (x - self._outline_offset, y), draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
if self._outline_offset > 1: if self._outline_offset > 1:
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x+self._outline_offset, y+self._outline_offset), (x + self._outline_offset, y + self._outline_offset),
draw=True, draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x-self._outline_offset, y+self._outline_offset), (x - self._outline_offset, y + self._outline_offset),
draw=True, draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x+self._outline_offset, y-self._outline_offset), (x + self._outline_offset, y - self._outline_offset),
draw=True, draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer, self._get_extent_and_render(line, footer,
(x-self._outline_offset, y-self._outline_offset), (x - self._outline_offset, y - self._outline_offset),
draw=True, draw=True,
color = self._theme.display_outline_color) color = self._theme.display_outline_color)
self._get_extent_and_render(line, footer,tlcorner=(x, y), self._get_extent_and_render(line, footer,tlcorner=(x, y),

View File

@ -189,21 +189,21 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.allowPreview = False self.allowPreview = False
self.paintUi(self.theme) self.paintUi(self.theme)
self.allowPreview = True self.allowPreview = True
self.previewTheme(self.theme) self.previewTheme()
def onImageToolButtonClicked(self): def onImageToolButtonClicked(self):
filename = QtGui.QFileDialog.getOpenFileName( filename = QtGui.QFileDialog.getOpenFileName(
self, self.trUtf8(u'Open file')) self, self.trUtf8('Open file'))
if filename: if filename:
self.ImageLineEdit.setText(filename) self.ImageLineEdit.setText(filename)
self.theme.background_filename = filename self.theme.background_filename = filename
self.previewTheme(self.theme) self.previewTheme()
# #
#Main Font Tab #Main Font Tab
# #
def onFontMainComboBoxSelected(self): def onFontMainComboBoxSelected(self):
self.theme.font_main_name = self.FontMainComboBox.currentFont().family() self.theme.font_main_name = self.FontMainComboBox.currentFont().family()
self.previewTheme(self.theme) self.previewTheme()
def onFontMainWeightComboBoxSelected(self, value): def onFontMainWeightComboBoxSelected(self, value):
if value == 0: if value == 0:
@ -218,7 +218,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.theme.font_main_weight = u'Bold' self.theme.font_main_weight = u'Bold'
self.theme.font_main_italics = True self.theme.font_main_italics = True
self.previewTheme(self.theme) self.previewTheme()
def onFontMainColorPushButtonClicked(self): def onFontMainColorPushButtonClicked(self):
self.theme.font_main_color = QtGui.QColorDialog.getColor( self.theme.font_main_color = QtGui.QColorDialog.getColor(
@ -226,12 +226,12 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontMainColorPushButton.setStyleSheet( self.FontMainColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.font_main_color)) u'background-color: %s' % unicode(self.theme.font_main_color))
self.previewTheme(self.theme) self.previewTheme()
def onFontMainSizeSpinBoxChanged(self): def onFontMainSizeSpinBoxChanged(self):
if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value(): if self.theme.font_main_proportion != self.FontMainSizeSpinBox.value():
self.theme.font_main_proportion = self.FontMainSizeSpinBox.value() self.theme.font_main_proportion = self.FontMainSizeSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontMainDefaultCheckBoxChanged(self, value): def onFontMainDefaultCheckBoxChanged(self, value):
if value == 2: # checked if value == 2: # checked
@ -252,41 +252,41 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontMainLineSpacingSpinBox.setValue( self.FontMainLineSpacingSpinBox.setValue(
self.theme.font_main_indentation) self.theme.font_main_indentation)
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onFontMainXSpinBoxChanged(self): def onFontMainXSpinBoxChanged(self):
if self.theme.font_main_x != self.FontMainXSpinBox.value(): if self.theme.font_main_x != self.FontMainXSpinBox.value():
self.theme.font_main_x = self.FontMainXSpinBox.value() self.theme.font_main_x = self.FontMainXSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontMainYSpinBoxChanged(self): def onFontMainYSpinBoxChanged(self):
if self.theme.font_main_y != self.FontMainYSpinBox.value(): if self.theme.font_main_y != self.FontMainYSpinBox.value():
self.theme.font_main_y = self.FontMainYSpinBox.value() self.theme.font_main_y = self.FontMainYSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontMainWidthSpinBoxChanged(self): def onFontMainWidthSpinBoxChanged(self):
if self.theme.font_main_width != self.FontMainWidthSpinBox.value(): if self.theme.font_main_width != self.FontMainWidthSpinBox.value():
self.theme.font_main_width = self.FontMainWidthSpinBox.value() self.theme.font_main_width = self.FontMainWidthSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontMainLineSpacingSpinBoxChanged(self): def onFontMainLineSpacingSpinBoxChanged(self):
if self.theme.font_main_indentation != \ if self.theme.font_main_indentation != \
self.FontMainLineSpacingSpinBox.value(): self.FontMainLineSpacingSpinBox.value():
self.theme.font_main_indentation = \ self.theme.font_main_indentation = \
self.FontMainLineSpacingSpinBox.value() self.FontMainLineSpacingSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontMainHeightSpinBoxChanged(self): def onFontMainHeightSpinBoxChanged(self):
if self.theme.font_main_height != self.FontMainHeightSpinBox.value(): if self.theme.font_main_height != self.FontMainHeightSpinBox.value():
self.theme.font_main_height = self.FontMainHeightSpinBox.value() self.theme.font_main_height = self.FontMainHeightSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
# #
#Footer Font Tab #Footer Font Tab
# #
def onFontFooterComboBoxSelected(self): def onFontFooterComboBoxSelected(self):
self.theme.font_footer_name = \ self.theme.font_footer_name = \
self.FontFooterComboBox.currentFont().family() self.FontFooterComboBox.currentFont().family()
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterWeightComboBoxSelected(self, value): def onFontFooterWeightComboBoxSelected(self, value):
if value == 0: if value == 0:
@ -301,22 +301,21 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.theme.font_footer_weight = u'Bold' self.theme.font_footer_weight = u'Bold'
self.theme.font_footer_italics = True self.theme.font_footer_italics = True
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterColorPushButtonClicked(self): def onFontFooterColorPushButtonClicked(self):
self.theme.font_footer_color = QtGui.QColorDialog.getColor( self.theme.font_footer_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.font_footer_color), self).name() QtGui.QColor(self.theme.font_footer_color), self).name()
self.FontFooterColorPushButton.setStyleSheet( self.FontFooterColorPushButton.setStyleSheet(
'background-color: %s' % unicode(self.theme.font_footer_color)) 'background-color: %s' % unicode(self.theme.font_footer_color))
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterSizeSpinBoxChanged(self): def onFontFooterSizeSpinBoxChanged(self):
if self.theme.font_footer_proportion != \ if self.theme.font_footer_proportion != \
self.FontFooterSizeSpinBox.value(): self.FontFooterSizeSpinBox.value():
self.theme.font_footer_proportion = \ self.theme.font_footer_proportion = \
self.FontFooterSizeSpinBox.value() self.FontFooterSizeSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterDefaultCheckBoxChanged(self, value): def onFontFooterDefaultCheckBoxChanged(self, value):
if value == 2: # checked if value == 2: # checked
@ -336,29 +335,29 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
self.FontFooterHeightSpinBox.setValue( self.FontFooterHeightSpinBox.setValue(
self.theme.font_footer_height) self.theme.font_footer_height)
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterXSpinBoxChanged(self): def onFontFooterXSpinBoxChanged(self):
if self.theme.font_footer_x != self.FontFooterXSpinBox.value(): if self.theme.font_footer_x != self.FontFooterXSpinBox.value():
self.theme.font_footer_x = self.FontFooterXSpinBox.value() self.theme.font_footer_x = self.FontFooterXSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterYSpinBoxChanged(self): def onFontFooterYSpinBoxChanged(self):
if self.theme.font_footer_y != self.FontFooterYSpinBox.value(): if self.theme.font_footer_y != self.FontFooterYSpinBox.value():
self.theme.font_footer_y = self.FontFooterYSpinBox.value() self.theme.font_footer_y = self.FontFooterYSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterWidthSpinBoxChanged(self): def onFontFooterWidthSpinBoxChanged(self):
if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value(): if self.theme.font_footer_width != self.FontFooterWidthSpinBox.value():
self.theme.font_footer_width = self.FontFooterWidthSpinBox.value() self.theme.font_footer_width = self.FontFooterWidthSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
def onFontFooterHeightSpinBoxChanged(self): def onFontFooterHeightSpinBoxChanged(self):
if self.theme.font_footer_height != \ if self.theme.font_footer_height != \
self.FontFooterHeightSpinBox.value(): self.FontFooterHeightSpinBox.value():
self.theme.font_footer_height = \ self.theme.font_footer_height = \
self.FontFooterHeightSpinBox.value() self.FontFooterHeightSpinBox.value()
self.previewTheme(self.theme) self.previewTheme()
# #
#Background Tab #Background Tab
# #
@ -372,7 +371,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.theme.background_mode = u'transparent' self.theme.background_mode = u'transparent'
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onBackgroundTypeComboBoxSelected(self, currentIndex): def onBackgroundTypeComboBoxSelected(self, currentIndex):
self.setBackground(currentIndex, self.GradientComboBox.currentIndex()) self.setBackground(currentIndex, self.GradientComboBox.currentIndex())
@ -397,7 +396,7 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.theme.background_type = u'image' self.theme.background_type = u'image'
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onColor1PushButtonClicked(self): def onColor1PushButtonClicked(self):
if self.theme.background_type == u'solid': if self.theme.background_type == u'solid':
@ -412,14 +411,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
u'background-color: %s' % \ u'background-color: %s' % \
unicode(self.theme.background_startColor)) unicode(self.theme.background_startColor))
self.previewTheme(self.theme) self.previewTheme()
def onColor2PushButtonClicked(self): def onColor2PushButtonClicked(self):
self.theme.background_endColor = QtGui.QColorDialog.getColor( self.theme.background_endColor = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.background_endColor), self).name() QtGui.QColor(self.theme.background_endColor), self).name()
self.Color2PushButton.setStyleSheet( self.Color2PushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.background_endColor)) u'background-color: %s' % unicode(self.theme.background_endColor))
self.previewTheme(self.theme) self.previewTheme()
# #
#Other Tab #Other Tab
# #
@ -429,14 +428,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.theme.display_outline = False self.theme.display_outline = False
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onOutlineColorPushButtonClicked(self): def onOutlineColorPushButtonClicked(self):
self.theme.display_outline_color = QtGui.QColorDialog.getColor( self.theme.display_outline_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.display_outline_color), self).name() QtGui.QColor(self.theme.display_outline_color), self).name()
self.OutlineColorPushButton.setStyleSheet( self.OutlineColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.display_outline_color)) u'background-color: %s' % unicode(self.theme.display_outline_color))
self.previewTheme(self.theme) self.previewTheme()
def onShadowCheckBoxChanged(self, value): def onShadowCheckBoxChanged(self, value):
if value == 2: # checked if value == 2: # checked
@ -444,24 +443,24 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.theme.display_shadow = False self.theme.display_shadow = False
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onShadowColorPushButtonClicked(self): def onShadowColorPushButtonClicked(self):
self.theme.display_shadow_color = QtGui.QColorDialog.getColor( self.theme.display_shadow_color = QtGui.QColorDialog.getColor(
QtGui.QColor(self.theme.display_shadow_color), self).name() QtGui.QColor(self.theme.display_shadow_color), self).name()
self.ShadowColorPushButton.setStyleSheet( self.ShadowColorPushButton.setStyleSheet(
u'background-color: %s' % unicode(self.theme.display_shadow_color)) u'background-color: %s' % unicode(self.theme.display_shadow_color))
self.previewTheme(self.theme) self.previewTheme()
def onHorizontalComboBoxSelected(self, currentIndex): def onHorizontalComboBoxSelected(self, currentIndex):
self.theme.display_horizontalAlign = currentIndex self.theme.display_horizontalAlign = currentIndex
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
def onVerticalComboBoxSelected(self, currentIndex): def onVerticalComboBoxSelected(self, currentIndex):
self.theme.display_verticalAlign = currentIndex self.theme.display_verticalAlign = currentIndex
self.stateChanging(self.theme) self.stateChanging(self.theme)
self.previewTheme(self.theme) self.previewTheme()
# #
#Local Methods #Local Methods
# #
@ -654,18 +653,10 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
else: else:
self.ShadowColorPushButton.setEnabled(False) self.ShadowColorPushButton.setEnabled(False)
def previewTheme(self, theme): def previewTheme(self):
if self.allowPreview: if self.allowPreview:
#calculate main number of rows #calculate main number of rows
main_weight = 50 metrics = self._getThemeMetrics()
if self.theme.font_main_weight == u'Bold':
main_weight = 75
mainFont = QtGui.QFont(self.theme.font_main_name,
self.theme.font_main_proportion, # size
main_weight, # weight
self.theme.font_main_italics)# italic
mainFont.setPixelSize(self.theme.font_main_proportion)
metrics = QtGui.QFontMetrics(mainFont)
page_length = \ page_length = \
(self.FontMainHeightSpinBox.value() / metrics.height() - 2) - 1 (self.FontMainHeightSpinBox.value() / metrics.height() - 2) - 1
log.debug(u'Page Length area height %s, metrics %s, lines %s' % log.debug(u'Page Length area height %s, metrics %s, lines %s' %
@ -673,6 +664,22 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog):
page_length)) page_length))
page_length_text = unicode(self.trUtf8(u'Slide Height is %s rows')) page_length_text = unicode(self.trUtf8(u'Slide Height is %s rows'))
self.FontMainLinesPageLabel.setText(page_length_text % page_length) self.FontMainLinesPageLabel.setText(page_length_text % page_length)
frame = self.thememanager.generateImage(theme) #a=c
frame = self.thememanager.generateImage(self.theme)
self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame)) self.ThemePreview.setPixmap(QtGui.QPixmap.fromImage(frame))
def _getThemeMetrics(self):
main_weight = 50
if self.theme.font_main_weight == u'Bold':
main_weight = 75
mainFont = QtGui.QFont(self.theme.font_main_name,
self.theme.font_main_proportion, # size
main_weight, # weight
self.theme.font_main_italics)# italic
mainFont.setPixelSize(self.theme.font_main_proportion)
metrics = QtGui.QFontMetrics(mainFont)
#Validate that the screen width is big enough to display the text
if self.theme.font_main_width < metrics.maxWidth() * 2 + 64:
self.theme.font_main_width = metrics.maxWidth() * 2 + 64
self.FontMainWidthSpinBox.setValue(self.theme.font_main_width)
return metrics

View File

@ -584,7 +584,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.trUtf8(u'The Main Display has been blanked out'), self.trUtf8(u'The Main Display has been blanked out'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
self.LiveController.blackPushButton.setChecked(True) #self.LiveController.blackPushButton.setChecked(True)
def onHelpAboutItemClicked(self): def onHelpAboutItemClicked(self):
""" """