diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py
index f9af00f6e..decf30435 100644
--- a/openlp/core/lib/renderer.py
+++ b/openlp/core/lib/renderer.py
@@ -324,34 +324,28 @@ class Renderer(object):
"""
log.debug(u'_paginate_slide - Start')
- line_end = u''
+ line_end = u' '
if line_break:
line_end = u'
'
formatted = []
+ raw_text = u''
html_text = u''
- styled_text = u''
- line_count = 0
- for line in lines:
- if line_count != -1:
- line_count += 1
- styled_line = expand_tags(line) + line_end
- styled_text += styled_line
- html = self.page_shell + styled_text + HTML_END
- self.web.setHtml(html)
- # Text too long so go to next page.
- if self.web_frame.contentsSize().height() > self.page_height:
- if force_page and line_count > 0:
- Receiver.send_message(u'theme_line_count', line_count - 1)
- line_count = -1
- while html_text.endswith(u'
'):
- html_text = html_text[:-4]
- formatted.append(html_text)
- html_text = u''
- styled_text = styled_line
- html_text += line + line_end
- while html_text.endswith(u'
'):
- html_text = html_text[:-4]
- formatted.append(html_text)
+ html_words = map(expand_tags, lines)
+ html = self.page_shell + u''.join(html_words) + HTML_END
+ self.web.setHtml(html)
+ # Text too long so go to next page.
+ if self.web_frame.contentsSize().height() > self.page_height:
+ lines = [u'%s
' % line for line in lines]
+ html_text, raw_text, index = self._binary_chop(
+ formatted, html_text, raw_text, lines, line_end)
+ if force_page:
+ Receiver.send_message(u'theme_line_count', index + 1)
+ else:
+ formatted.append(line_end.join(html_words))
+ while raw_text.endswith(u'
'):
+ raw_text = raw_text[:-4]
+ if raw_text:
+ formatted.append(raw_text)
log.debug(u'_paginate_slide - End')
return formatted
@@ -408,53 +402,8 @@ class Renderer(object):
# Figure out how many words of the line will fit on screen by
# using the algorithm known as "binary chop".
raw_words = self._words_split(line)
- html_words = [expand_tags(word) for word in raw_words]
- smallest_index = 0
- highest_index = len(html_words) - 1
- index = int(highest_index / 2)
- while True:
- html = self.page_shell + previous_html + \
- u''.join(html_words[:index + 1]).strip() + HTML_END
- self.web.setHtml(html)
- if self.web_frame.contentsSize().height() > \
- self.page_height:
- # We know that it does not fit, so change/calculate the
- # new index and highest_index accordingly.
- highest_index = index
- index = int(index - (index - smallest_index) / 2)
- else:
- smallest_index = index
- index = int(index + (highest_index - index) / 2)
- # We found the number of words which will fit.
- if smallest_index == index or highest_index == index:
- index = smallest_index
- formatted.append(previous_raw.rstrip(u'
') +
- u''.join(raw_words[:index + 1]))
- previous_html = u''
- previous_raw = u''
- else:
- continue
- # Check if the rest of the line fits on the slide. If it
- # does we do not have to do the much more intensive "word by
- # word" checking.
- html = self.page_shell + \
- u''.join(html_words[index + 1:]).strip() + HTML_END
- self.web.setHtml(html)
- if self.web_frame.contentsSize().height() <= \
- self.page_height:
- previous_html = \
- u''.join(html_words[index + 1:]).strip() + line_end
- previous_raw = \
- u''.join(raw_words[index + 1:]).strip() + line_end
- break
- else:
- # The other words do not fit, thus reset the indexes,
- # create a new list and continue with "word by word".
- raw_words = raw_words[index + 1:]
- html_words = html_words[index + 1:]
- smallest_index = 0
- highest_index = len(html_words) - 1
- index = int(highest_index / 2)
+ previous_html, previous_raw, index = self._binary_chop(
+ formatted, previous_html, previous_raw, raw_words, line_end, u'
')
else:
previous_html += styled_line + line_end
previous_raw += line + line_end
@@ -464,6 +413,77 @@ class Renderer(object):
log.debug(u'_paginate_slide_words - End')
return formatted
+ def _binary_chop(self, formatted, previous_html, previous_raw, raw_text,
+ line_end):
+ """
+ This implements the binary chop algorithm for faster rendering. However,
+ it is assumed that this method is **only** called, when the text to be
+ rendered does not fit as a whole.
+
+ ``formatted``
+ The list of slides.
+
+ ``previous_html``
+ The html text which is know to fit on a slide, but is not yet added
+ to the list of slides.
+
+ ``previous_raw``
+ The raw text (with display tags) which is know to fit on a slide,
+ but is not yet added to the list of slides.
+
+ ``raw_text``
+ The text which does not fit on a slide and needs to be processed
+ using the binary chop. The text can contain display tags.
+
+ ``line_end``
+ The
+ """
+ html_words = map(expand_tags, raw_text)
+ smallest_index = 0
+ highest_index = len(html_words) - 1
+ index = int(highest_index / 2)
+ while True:
+ html = self.page_shell + previous_html + \
+ separator.join(html_words[:index + 1]).strip() + HTML_END
+ self.web.setHtml(html)
+ if self.web_frame.contentsSize().height() > self.page_height:
+ # We know that it does not fit, so change/calculate the
+ # new index and highest_index accordingly.
+ highest_index = index
+ index = int(index - (index - smallest_index) / 2)
+ else:
+ smallest_index = index
+ index = int(index + (highest_index - index) / 2)
+ # We found the number of words which will fit.
+ if smallest_index == index or highest_index == index:
+ index = smallest_index
+ formatted.append(previous_raw.rstrip(u'
') +
+ u''.join(raw_text[:index + 1]))
+ previous_html = u''
+ previous_raw = u''
+ else:
+ continue
+ # Check if the rest of the line fits on the slide. If it
+ # does we do not have to do the much more intensive "word by
+ # word" checking.
+ html = self.page_shell + \
+ u''.join(html_words[index + 1:]).strip() + HTML_END
+ self.web.setHtml(html)
+ if self.web_frame.contentsSize().height() <= self.page_height:
+ previous_html = \
+ u''.join(html_words[index + 1:]).strip() + line_end
+ previous_raw = u''.join(raw_text[index + 1:]).strip() + line_end
+ break
+ else:
+ # The other words do not fit, thus reset the indexes,
+ # create a new list and continue with "word by word".
+ raw_text = raw_text[index + 1:]
+ html_words = html_words[index + 1:]
+ smallest_index = 0
+ highest_index = len(html_words) - 1
+ index = int(highest_index / 2)
+ return previous_html, previous_raw, index
+
def _words_split(self, line):
"""
Split the slide up by word so can wrap better
diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py
index cf682abc6..62d29d8be 100644
--- a/openlp/core/lib/serviceitem.py
+++ b/openlp/core/lib/serviceitem.py
@@ -172,6 +172,9 @@ class ServiceItem(object):
self.themedata = self.renderer.theme_data
if self.service_item_type == ServiceItemType.Text:
log.debug(u'Formatting slides')
+ import time
+ import datetime
+ start = time.time()
for slide in self._raw_frames:
formatted = self.renderer \
.format_slide(slide[u'raw_slide'], line_break, self)
@@ -184,6 +187,7 @@ class ServiceItem(object):
u'html': html.replace(u' ', u' '),
u'verseTag': slide[u'verseTag']
})
+ print unicode(datetime.timedelta(seconds=time.time() - start))
elif self.service_item_type == ServiceItemType.Image or \
self.service_item_type == ServiceItemType.Command:
pass