← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~j-corwin/openlp/render into lp:openlp

 

Jonathan Corwin has proposed merging lp:~j-corwin/openlp/render into lp:openlp.

Requested reviews:
  Tim Bentley (trb143)


Replace QtTextDocument with QWebView in renderer to more accurately detect page breaks.
Prevent multiple spaces getting compressed
Other HTML/CSS tidies
-- 
https://code.launchpad.net/~j-corwin/openlp/render/+merge/34616
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/core/lib/__init__.py'
--- openlp/core/lib/__init__.py	2010-09-04 08:12:54 +0000
+++ openlp/core/lib/__init__.py	2010-09-04 14:28:42 +0000
@@ -325,7 +325,8 @@
 from serviceitem import ServiceItem
 from serviceitem import ServiceItemType
 from serviceitem import ItemCapabilities
-from htmlbuilder import build_html
+from htmlbuilder import build_html, build_lyrics_format_css, \
+    build_lyrics_outline_css
 from toolbar import OpenLPToolbar
 from dockwidget import OpenLPDockWidget
 from theme import ThemeLevel, ThemeXML

=== modified file 'openlp/core/lib/htmlbuilder.py'
--- openlp/core/lib/htmlbuilder.py	2010-09-04 07:48:58 +0000
+++ openlp/core/lib/htmlbuilder.py	2010-09-04 14:28:42 +0000
@@ -266,14 +266,10 @@
     `islive`
         Item is going live, rather than preview/theme building
     """
-    try:
-        webkitvers = float(QtWebKit.qWebKitVersion())
-        log.debug(u'Webkit version = %s' % webkitvers)
-    except AttributeError:
-        webkitvers = 0
     width = screen[u'size'].width()
     height = screen[u'size'].height()
     theme = item.themedata
+    webkitvers = webkit_version()
     if item.bg_frame:
         image = u'data:image/png;base64,%s' % image_to_byte(item.bg_frame)
     else:
@@ -289,6 +285,18 @@
         build_lyrics_html(item, webkitvers))
     return html
 
+def webkit_version():
+    """
+    Return the Webkit version in use.
+    Note method added relatively recently, so return 0 if prior to this
+    """
+    try:
+        webkitvers = float(QtWebKit.qWebKitVersion())
+        log.debug(u'Webkit version = %s' % webkitvers)
+    except AttributeError:
+        webkitvers = 0
+    return webkitvers
+
 def build_background_css(item, width, height):
     """
     Build the background css
@@ -306,24 +314,25 @@
         else:
             if theme.background_direction == u'horizontal':
                 background = \
-                    u'background: -webkit-gradient(linear, left top, left bottom, ' \
+                    u'background: ' \
+                    u'-webkit-gradient(linear, left top, left bottom, ' \
                     'from(%s), to(%s))' % (theme.background_startColor,
                     theme.background_endColor)
             elif theme.background_direction == u'vertical':
                 background = \
-                    u'background: -webkit-gradient(linear, left top, right top,' \
-                    'from(%s), to(%s))' % (theme.background_startColor,
-                    theme.background_endColor)
+                    u'background: -webkit-gradient(linear, left top, ' \
+                    u'right top, from(%s), to(%s))' % \
+                    (theme.background_startColor, theme.background_endColor)
             else:
                 background = \
-                    u'background: -webkit-gradient(radial, %s 50%%, 100, %s 50%%, %s,' \
-                    'from(%s), to(%s))' % (width, width, width, theme.background_startColor,
-                    theme.background_endColor)
+                    u'background: -webkit-gradient(radial, %s 50%%, 100, %s ' \
+                    u'50%%, %s, from(%s), to(%s))' % (width, width, width, 
+                    theme.background_startColor, theme.background_endColor)
     return background
 
 def build_lyrics_css(item, webkitvers):
     """
-    Build the video display css
+    Build the lyrics display css
 
     `item`
         Service Item containing theme and location information
@@ -363,24 +372,8 @@
     if theme:
         lyricstable = u'left: %spx; top: %spx;' % \
             (item.main.x(), item.main.y())
-        if theme.display_horizontalAlign == 2:
-            align = u'center'
-        elif theme.display_horizontalAlign == 1:
-            align = u'right'
-        else:
-            align = u'left'
-        if theme.display_verticalAlign == 2:
-            valign = u'bottom'
-        elif theme.display_verticalAlign == 1:
-            valign = u'middle'
-        else:
-            valign = u'top'
-        lyrics = u'width: %spx; height: %spx; text-align: %s; ' \
-            'vertical-align: %s; font-family: %s; font-size: %spt; ' \
-            'color: %s; line-height: %d%%;' % \
-            (item.main.width(), item.main.height(), align, valign,
-            theme.font_main_name, theme.font_main_proportion,
-            theme.font_main_color, 100 + int(theme.font_main_line_adjustment))
+        lyrics = build_lyrics_format_css(theme, item.main.width(), 
+            item.main.height())
         # For performance reasons we want to show as few DIV's as possible,
         # especially when animating/transitions.
         # However some bugs in older versions of qtwebkit mean we need to
@@ -396,30 +389,89 @@
         # Before 534.4 the text-shadow didn't get displayed when
         # webkit-text-stroke was used. So use an offset text layer underneath.
         # https://bugs.webkit.org/show_bug.cgi?id=19728
-        if theme.display_outline:
-            if webkitvers < 534.3:
-                lyrics += u' letter-spacing: 1px;'
-            outline = u' -webkit-text-stroke: %sem %s; ' \
-                '-webkit-text-fill-color: %s; ' % \
-                (float(theme.display_outline_size) / 16,
-                theme.display_outline_color, theme.font_main_color)
-            if webkitvers >= 533.3:
-                lyricsmain += outline
-            if theme.display_shadow and webkitvers < 534.3:
-                shadow = u'-webkit-text-stroke: %sem %s; ' \
-                    u'-webkit-text-fill-color: %s; ' \
-                    u' padding-left: %spx; padding-top: %spx' % \
-                    (float(theme.display_outline_size) / 16,
-                    theme.display_shadow_color, theme.display_shadow_color,
-                    theme.display_shadow_size, theme.display_shadow_size)
-        if theme.display_shadow and \
-            (not theme.display_outline or webkitvers >= 534.3):
-            lyricsmain += u' text-shadow: %s %spx %spx;' % \
-                (theme.display_shadow_color, theme.display_shadow_size,
-                theme.display_shadow_size)
+        if webkitvers >= 533.3:
+            lyricsmain += build_lyrics_outline_css(theme)
+        else:
+            outline = build_lyrics_outline_css(theme) 
+        if theme.display_shadow:
+            if theme.display_outline and webkitvers < 534.3:
+                shadow = u'padding-left: %spx; padding-top: %spx ' % \
+                    (theme.display_shadow_size, theme.display_shadow_size)
+                shadow += build_lyrics_outline_css(theme, True)
+            else:
+                lyricsmain += u' text-shadow: %s %spx %spx;' % \
+                    (theme.display_shadow_color, theme.display_shadow_size,
+                    theme.display_shadow_size)
     lyrics_css = style % (lyricstable, lyrics, lyricsmain, outline, shadow)
     return lyrics_css
-
+    
+def build_lyrics_outline_css(theme, is_shadow=False):
+    """
+    Build the css which controls the theme outline
+    Also used by renderer for splitting verses
+
+    `theme`
+        Object containing theme information
+    
+    `is_shadow`
+        If true, use the shadow colors instead
+    """
+    if theme.display_outline:
+        size = float(theme.display_outline_size) / 16
+        if is_shadow:
+            fill_color = theme.display_shadow_color
+            outline_color = theme.display_shadow_color
+        else:
+            fill_color = theme.font_main_color
+            outline_color = theme.display_outline_color
+        return u' -webkit-text-stroke: %sem %s; ' \
+            u'-webkit-text-fill-color: %s; ' % (size, outline_color, fill_color)
+    else:
+        return u''
+
+def build_lyrics_format_css(theme, width, height):
+    """
+    Build the css which controls the theme format
+    Also used by renderer for splitting verses
+
+    `theme`
+        Object containing theme information
+    
+    `width`
+        Width of the lyrics block
+
+    `height`
+        Height of the lyrics block
+
+    """
+    if theme.display_horizontalAlign == 2:
+        align = u'center'
+    elif theme.display_horizontalAlign == 1:
+        align = u'right'
+    else:
+        align = u'left'
+    if theme.display_verticalAlign == 2:
+        valign = u'bottom'
+    elif theme.display_verticalAlign == 1:
+        valign = u'middle'
+    else:
+        valign = u'top'
+    lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \
+        'text-align: %s; vertical-align: %s; font-family: %s; ' \
+        'font-size: %spt; color: %s; line-height: %d%%; ' \
+        'margin:0; padding:0; width: %spx; height: %spx; ' % \
+        (align, valign, theme.font_main_name, theme.font_main_proportion, 
+        theme.font_main_color, 100 + int(theme.font_main_line_adjustment), 
+        width, height)
+    if theme.display_outline:
+        if webkit_version() < 534.3:
+            lyrics += u' letter-spacing: 1px;'
+    if theme.font_main_italics:
+        lyrics += u' font-style:italic; '
+    if theme.font_main_weight == u'Bold':
+        lyrics += u' font-weight:bold; '
+    return lyrics
+    
 def build_lyrics_html(item, webkitvers):
     """
     Build the HTML required to show the lyrics

=== modified file 'openlp/core/lib/renderer.py'
--- openlp/core/lib/renderer.py	2010-09-04 07:48:58 +0000
+++ openlp/core/lib/renderer.py	2010-09-04 14:28:42 +0000
@@ -29,9 +29,10 @@
 """
 import logging
 
-from PyQt4 import QtGui, QtCore
+from PyQt4 import QtGui, QtCore, QtWebKit
 
-from openlp.core.lib import resize_image, expand_tags
+from openlp.core.lib import resize_image, expand_tags, \
+    build_lyrics_format_css, build_lyrics_outline_css
 
 log = logging.getLogger(__name__)
 
@@ -142,42 +143,35 @@
         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.setPointSize(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()
+                text.append(line)               
+        web = QtWebKit.QWebView()
+        web.resize(self._rect.width(), self._rect.height())
+        web.setVisible(False)
+        frame = web.page().mainFrame()
+        # Adjust width and height to account for shadow. outline done in css
+        width = self._rect.width() - int(self._theme.display_shadow_size) 
+        height = self._rect.height() - int(self._theme.display_shadow_size) 
+        shell = u'<html><head><style>#main {%s %s}</style><body>' \
+            u'<div id="main">' % \
+            (build_lyrics_format_css(self._theme, width, height),
+            build_lyrics_outline_css(self._theme))
         formatted = []
-        if self._theme.font_main_weight == u'Bold' and \
-            self._theme.font_main_italics:
-            shell = u'{p}{st}{it}%s{/it}{/st}{/p}'
-        elif self._theme.font_main_weight == u'Bold' and \
-            not self._theme.font_main_italics:
-            shell = u'{p}{st}%s{/st}{/p}'
-        elif self._theme.font_main_italics:
-            shell = u'{p}{it}%s{/it}{/p}'
-        else:
-            shell = u'{p}%s{/p}'
-        temp_text = u''
-        old_html_text = u''
+        html_text = u''
+        styled_text = u''
+        js_height = 'document.getElementById("main").scrollHeight'
         for line in text:
-            # mark line ends
-            temp_text = temp_text + line + line_end
-            html_text = shell % expand_tags(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 + line_end
-            old_html_text = temp_text
-        formatted.append(shell % old_html_text)
+            styled_line = expand_tags(line) + line_end
+            styled_text += styled_line
+            html = shell + styled_text + u'</div></body></html>'
+            web.setHtml(html)
+            # Text too long so go to next page
+            text_height = int(frame.evaluateJavaScript(js_height).toString())
+            if text_height > height:
+                formatted.append(html_text)
+                html_text = u''
+                styled_text = styled_line
+            html_text += line + line_end
+        formatted.append(html_text)
         log.debug(u'format_slide - End')
         return formatted
 

=== modified file 'openlp/core/lib/serviceitem.py'
--- openlp/core/lib/serviceitem.py	2010-08-24 17:12:47 +0000
+++ openlp/core/lib/serviceitem.py	2010-09-04 14:28:42 +0000
@@ -160,9 +160,9 @@
             self.themedata = self.render_manager.renderer._theme
             for slide in self._raw_frames:
                 before = time.time()
-                formated = self.render_manager \
+                formatted = self.render_manager \
                     .format_slide(slide[u'raw_slide'], line_break)
-                for page in formated:
+                for page in formatted:
                     self._display_frames.append(
                         {u'title': clean_tags(page),
                         u'text': clean_tags(page.rstrip()),


Follow ups