From 96737c0bc0f936daa2183c40db9dbba1d93d8ad1 Mon Sep 17 00:00:00 2001 From: Jonathan Corwin Date: Thu, 2 Sep 2010 21:41:24 +0100 Subject: [PATCH] Use QtGraphicsWebview. Reduce div count where possible --- openlp/core/lib/htmlbuilder.py | 223 +++++++++++++++++++++------------ openlp/core/ui/maindisplay.py | 7 +- 2 files changed, 150 insertions(+), 80 deletions(-) diff --git a/openlp/core/lib/htmlbuilder.py b/openlp/core/lib/htmlbuilder.py index c5b5088c4..7d283ae8c 100644 --- a/openlp/core/lib/htmlbuilder.py +++ b/openlp/core/lib/htmlbuilder.py @@ -24,6 +24,8 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### +from PyQt4 import QtWebKit + from openlp.core.lib import image_to_byte HTMLSRC = u""" @@ -39,7 +41,7 @@ HTMLSRC = u""" body { background-color: black; } -.dim { +.size { position: absolute; left: 0px; top: 0px; @@ -51,6 +53,9 @@ body { background-color: black; display: none; } +#image { + z-index:1; +} #video { z-index:2; } @@ -136,8 +141,12 @@ body { } document.getElementById('black').style.display = black; document.getElementById('lyricsmain').style.visibility = lyrics; - document.getElementById('lyricsoutline').style.visibility = lyrics; - document.getElementById('lyricsshadow').style.visibility = lyrics; + outline = document.getElementById('lyricsoutline') + if(outline) + outline.style.visibility = lyrics; + shadow = document.getElementById('lyricsshadow') + if(shadow) + shadow.style.visibility = lyrics; document.getElementById('footer').style.visibility = lyrics; var vid = document.getElementById('video'); if(vid.src != ''){ @@ -193,7 +202,17 @@ body { } function text_fade(id, newtext){ + /* + Using -webkit-transition: opacity 1s linear; would have been preferred + but it isn't currently quick enough when animating multiple layers of + large areas of large text. Therefore do it manually as best we can. + Hopefully in the future we can revisit and do more interesting + transitions using -webkit-transition and -webkit-transform. + However we need to ensure interrupted transitions (quickly change 2 + slides) still looks pretty and is zippy. + */ var text = document.getElementById(id); + if(text==null) return; if(!transition){ text.innerHTML = newtext; return; @@ -213,37 +232,19 @@ body { var text = document.getElementById('lyricsmain'); return getComputedStyle(text, '').opacity; } + function show_text_complete(){ return (text_opacity()==1); } - -
-
-
-
-
-
-
-
-
- + + +%s - -
- +
+ """ @@ -258,7 +259,13 @@ def build_html(item, screen, alert, islive): Current display information `alert` Alert display display information + `islive` + Item is going live, rather than preview/theme building """ + try: + webkitvers = float(QtWebKit.qWebKitVersion()) + except AttributeError: + webkitvers = 0 width = screen[u'size'].width() height = screen[u'size'].height() theme = item.themedata @@ -267,83 +274,143 @@ def build_html(item, screen, alert, islive): else: image = u'' html = HTMLSRC % (width, height, - build_alert(alert, width), - build_footer(item), - build_lyrics(item), + build_alert_css(alert, width), + build_footer_css(item), + build_lyrics_css(item, webkitvers), u'true' if theme and theme.display_slideTransition and islive \ else u'false', - image) + image, + build_lyrics_html(item, webkitvers)) return html -def build_lyrics(item): +def build_lyrics_css(item, webkitvers): """ - Build the video display div + Build the video display css `item` Service Item containing theme and location information + + `webkitvers` + The version of qtwebkit we're using + """ style = """ - .lyricscommon { position: absolute; %s } - .lyricstable { z-index:4; %s } - .lyricsoutlinetable { z-index:3; %s } - .lyricsshadowtable { z-index:2; %s } - .lyrics { %s } - .lyricsoutline { %s } - .lyricsshadow { %s } +.lyricstable { + z-index:4; + position: absolute; + display: table; + %s +} +.lyricscell { + display:table-cell; + word-wrap: break-word; + %s +} +.lyricsmain { +%s +} +.lyricsoutline { +%s +} +.lyricsshadow { +%s +} """ theme = item.themedata - lyricscommon = u'' lyricstable = u'' - outlinetable = u'' - shadowtable = u'' lyrics = u'' - outline = u'display: none;' - shadow = u'display: none;' + lyricsmain = u'' + outline = u'' + shadow = u'' if theme: - lyricscommon = u'display: table; width: %spx; height: %spx; word-wrap: break-word; ' \ - u'font-family: %s; font-size: %spt; color: %s; line-height: %d%%;' \ - % (item.main.width(), item.main.height(), theme.font_main_name, - theme.font_main_proportion, theme.font_main_color, - 100 + int(theme.font_main_line_adjustment)) lyricstable = u'left: %spx; top: %spx;' % \ (item.main.x(), item.main.y()) - outlinetable = u'left: %spx; top: %spx;' % \ - (item.main.x(), item.main.y()) - shadowtable = u'left: %spx; top: %spx;' % \ - (item.main.x() + float(theme.display_shadow_size), - item.main.y() + float(theme.display_shadow_size)) - align = u'' if theme.display_horizontalAlign == 2: - align = u'text-align:center;' + align = u'center' elif theme.display_horizontalAlign == 1: - align = u'text-align:right;' + align = u'right' else: - align = u'text-align:left;' + align = u'left' if theme.display_verticalAlign == 2: - valign = u'vertical-align:bottom;' + valign = u'bottom' elif theme.display_verticalAlign == 1: - valign = u'vertical-align:middle;' + valign = u'middle' else: - valign = u'vertical-align:top;' - lyrics = u'display:table-cell; %s %s' % (align, valign) + 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)) + # 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 + # perform workarounds and add extra divs. Only do these when needed. + # + # Before 533.3 the webkit-text-fill colour wasn't displayed, only the + # stroke (outline) color. So put stroke layer underneath the main text. + # + # Before 534.4 the webkit-text-stroke was sometimes out of alignment + # with the fill, or normal text. letter-spacing=1 is workaround + # https://bugs.webkit.org/show_bug.cgi?id=44403 + # + # 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: - lyricscommon += u' letter-spacing: 1px;' - outline = u'-webkit-text-stroke: %sem %s; ' % \ + 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) - if theme.display_shadow: + 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'-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) - else: - if theme.display_shadow: - shadow = u'color: %s;' % (theme.display_shadow_color) - lyrics_html = style % (lyricscommon, lyricstable, outlinetable, - shadowtable, lyrics, outline, shadow) - return lyrics_html + 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) + lyrics_css = style % (lyricstable, lyrics, lyricsmain, outline, shadow) + return lyrics_css + +def build_lyrics_html(item, webkitvers): + """ + Build the HTML required to show the lyrics -def build_footer(item): + `item` + Service Item containing theme and location information + + `webkitvers` + The version of qtwebkit we're using + """ + # Bugs in some versions of QtWebKit mean we sometimes need additional + # divs for outline and shadow, since the CSS doesn't work. + # To support vertical alignment middle and bottom, nested div's using + # display:table/display:table-cell are required for each lyric block. + lyrics = u'' + theme = item.themedata + if webkitvers < 534.4 and theme and theme.display_outline: + lyrics += u'
' \ + u'
' \ + u'
' + if webkitvers < 533.3: + lyrics += u'
' \ + u'
' \ + u'
' + lyrics += u'
' \ + u'
' + return lyrics + +def build_footer_css(item): """ Build the display of the item footer @@ -374,7 +441,7 @@ def build_footer(item): theme.font_footer_proportion, theme.font_footer_color, align) return lyrics_html -def build_alert(alertTab, width): +def build_alert_css(alertTab, width): """ Build the display of the footer @@ -382,7 +449,7 @@ def build_alert(alertTab, width): Details from the Alert tab for fonts etc """ style = """ - width: %s; + width: %spx; vertical-align: %s; font-family: %s; font-size: %spt; diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index c985434c1..4f2ea6df6 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -115,8 +115,11 @@ class MainDisplay(DisplayWidget): self.screen = self.screens.current self.setVisible(False) self.setGeometry(self.screen[u'size']) - self.webView = QtWebKit.QWebView(self) - self.webView.setGeometry(0, 0, self.screen[u'size'].width(), \ + self.scene = QtGui.QGraphicsScene() + self.setScene(self.scene) + self.webView = QtWebKit.QGraphicsWebView() + self.scene.addItem(self.webView) + self.webView.resize(self.screen[u'size'].width(), \ self.screen[u'size'].height()) self.page = self.webView.page() self.frame = self.page.mainFrame()