openlp/openlp/core/lib/htmlbuilder.py

757 lines
27 KiB
Python
Raw Normal View History

2010-07-11 10:58:36 +00:00
# -*- coding: utf-8 -*-
2012-12-28 22:06:43 +00:00
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
2010-07-11 10:58:36 +00:00
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2015-12-31 22:46:06 +00:00
# Copyright (c) 2008-2016 OpenLP Developers #
2010-07-11 10:58:36 +00:00
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
2013-09-11 13:00:34 +00:00
"""
This module is responsible for generating the HTML for :class:`~openlp.core.ui.maindisplay`. The ``build_html`` function
is the function which has to be called from outside. The generated and returned HTML will look similar to this::
<!DOCTYPE html>
<html>
<head>
<title>OpenLP Display</title>
<style>
*{
margin: 0;
padding: 0;
border: 0;
overflow: hidden;
-webkit-user-select: none;
}
body {
background-color: #000000;
}
.size {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
#black {
z-index: 8;
background-color: black;
display: none;
}
#bgimage {
z-index: 1;
}
#image {
z-index: 2;
}
#videobackboard {
z-index:3;
background-color: #000000;
}
#video {
background-color: #000000;
z-index:4;
}
#flash {
z-index:5;
}
#alert {
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
width: 100%;
vertical-align: bottom;
font-family: DejaVu Sans;
font-size: 40pt;
color: #ffffff;
background-color: #660000;
word-wrap: break-word;
}
#footer {
position: absolute;
z-index: 6;
left: 10px;
bottom: 0px;
width: 1580px;
font-family: Nimbus Sans L;
font-size: 12pt;
color: #FFFFFF;
text-align: left;
white-space: nowrap;
}
/* lyric css */
.lyricstable {
z-index: 5;
position: absolute;
display: table;
left: 10px; top: 0px;
}
.lyricscell {
display: table-cell;
word-wrap: break-word;
-webkit-transition: opacity 0.4s ease;
2014-03-20 19:10:31 +00:00
white-space:pre-wrap; word-wrap: break-word; text-align: left; vertical-align: top; font-family: Nimbus
Sans L; font-size: 40pt; color: #FFFFFF; line-height: 100%; margin: 0;padding: 0; padding-bottom: 0;
padding-left: 4px; width: 1580px; height: 810px;
2013-09-11 13:00:34 +00:00
}
.lyricsmain {
-webkit-text-stroke: 0.125em #000000; -webkit-text-fill-color: #FFFFFF; text-shadow: #000000 5px 5px;
}
sup {
font-size: 0.6em;
vertical-align: top;
position: relative;
top: -0.3em;
}
</style>
<script>
var timer = null;
var transition = false;
function show_video(state, path, volume, loop, variable_value){
// Sometimes video.currentTime stops slightly short of video.duration and video.ended is intermittent!
var video = document.getElementById('video');
if(volume != null){
video.volume = volume;
}
switch(state){
case 'load':
video.src = 'file:///' + path;
if(loop == true) {
video.loop = true;
}
video.load();
break;
case 'play':
video.play();
break;
case 'pause':
video.pause();
break;
case 'stop':
show_video('pause');
video.currentTime = 0;
break;
case 'close':
show_video('stop');
video.src = '';
break;
case 'length':
return video.duration;
case 'current_time':
return video.currentTime;
case 'seek':
video.currentTime = variable_value;
break;
case 'isEnded':
return video.ended;
case 'setVisible':
video.style.visibility = variable_value;
break;
case 'setBackBoard':
var back = document.getElementById('videobackboard');
back.style.visibility = variable_value;
break;
}
}
2013-08-31 18:17:38 +00:00
2013-09-11 13:00:34 +00:00
function getFlashMovieObject(movieName)
{
if (window.document[movieName]){
return window.document[movieName];
}
if (document.embeds && document.embeds[movieName]){
return document.embeds[movieName];
}
}
function show_flash(state, path, volume, variable_value){
var text = document.getElementById('flash');
var flashMovie = getFlashMovieObject("OpenLPFlashMovie");
var src = "src = 'file:///" + path + "'";
var view_parm = " wmode='opaque'" + " width='100%%'" + " height='100%%'";
var swf_parm = " name='OpenLPFlashMovie'" + " autostart='true' loop='false' play='true'" +
" hidden='false' swliveconnect='true' allowscriptaccess='always'" + " volume='" + volume + "'";
switch(state){
case 'load':
text.innerHTML = "<embed " + src + view_parm + swf_parm + "/>";
flashMovie = getFlashMovieObject("OpenLPFlashMovie");
flashMovie.Play();
break;
case 'play':
flashMovie.Play();
break;
case 'pause':
flashMovie.StopPlay();
break;
case 'stop':
flashMovie.StopPlay();
tempHtml = text.innerHTML;
text.innerHTML = '';
text.innerHTML = tempHtml;
break;
case 'close':
flashMovie.StopPlay();
text.innerHTML = '';
break;
case 'length':
return flashMovie.TotalFrames();
case 'current_time':
return flashMovie.CurrentFrame();
case 'seek':
// flashMovie.GotoFrame(variable_value);
break;
case 'isEnded':
//TODO check flash end
return false;
case 'setVisible':
text.style.visibility = variable_value;
break;
}
}
function show_alert(alerttext, position){
var text = document.getElementById('alert');
text.innerHTML = alerttext;
if(alerttext == '') {
text.style.visibility = 'hidden';
return 0;
}
if(position == ''){
position = getComputedStyle(text, '').verticalAlign;
}
switch(position)
{
case 'top':
text.style.top = '0px';
break;
case 'middle':
text.style.top = ((window.innerHeight - text.clientHeight) / 2)
+ 'px';
break;
case 'bottom':
text.style.top = (window.innerHeight - text.clientHeight)
+ 'px';
break;
}
text.style.visibility = 'visible';
return text.clientHeight;
}
function update_css(align, font, size, color, bgcolor){
var text = document.getElementById('alert');
text.style.fontSize = size + "pt";
text.style.fontFamily = font;
text.style.color = color;
text.style.backgroundColor = bgcolor;
switch(align)
{
case 'top':
text.style.top = '0px';
break;
case 'middle':
text.style.top = ((window.innerHeight - text.clientHeight) / 2)
+ 'px';
break;
case 'bottom':
text.style.top = (window.innerHeight - text.clientHeight)
+ 'px';
break;
}
}
function show_image(src){
var img = document.getElementById('image');
img.src = src;
if(src == '')
img.style.display = 'none';
else
img.style.display = 'block';
}
function show_blank(state){
var black = 'none';
var lyrics = '';
switch(state){
case 'theme':
lyrics = 'hidden';
break;
case 'black':
black = 'block';
break;
case 'desktop':
break;
}
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
document.getElementById('footer').style.visibility = lyrics;
}
function show_footer(footertext){
document.getElementById('footer').innerHTML = footertext;
}
function show_text(new_text){
var match = /-webkit-text-fill-color:[^;"]+/gi;
if(timer != null)
clearTimeout(timer);
/*
QtWebkit bug with outlines and justify causing outline alignment
problems. (Bug 859950) Surround each word with a <span> to workaround,
but only in this scenario.
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
function(match) {
return '</span>' + match + '<span>';
});
new_text = '<span>' + new_text + '</span>';
}
}
text_fade('lyricsmain', new_text);
}
function text_fade(id, new_text){
/*
Show the text.
*/
var text = document.getElementById(id);
if(text == null) return;
if(!transition){
text.innerHTML = new_text;
return;
}
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.1';
// Fade new text in after the old text has finished fading out.
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
function _show_text(text, new_text) {
/*
Helper function to show the new_text delayed.
*/
text.innerHTML = new_text;
text.style.opacity = '1';
// Wait until the text is completely visible. We want to save the timer id, to be able to call
// clearTimeout(timer) when the text has changed before finishing fading.
timer = window.setTimeout(function(){timer = null;}, 400);
}
function show_text_completed(){
return (timer == null);
}
</script>
</head>
<body>
<img id="bgimage" class="size" style="display:none;" />
<img id="image" class="size" style="display:none;" />
<div id="videobackboard" class="size" style="visibility:hidden"></div>
<video id="video" class="size" style="visibility:hidden" autobuffer preload></video>
<div id="flash" class="size" style="visibility:hidden"></div>
<div id="alert" style="visibility:hidden"></div>
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
<div id="footer" class="footer"></div>
<div id="black" class="size"></div>
</body>
</html>
"""
2010-09-04 07:48:58 +00:00
import logging
2010-10-16 13:54:57 +00:00
2015-11-07 00:49:40 +00:00
from PyQt5 import QtWebKit
2014-07-21 06:37:41 +00:00
from openlp.core.common import Settings
2012-12-28 22:06:43 +00:00
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, VerticalType, HorizontalType
2010-10-16 13:54:57 +00:00
2010-09-04 07:48:58 +00:00
log = logging.getLogger(__name__)
2013-08-31 18:17:38 +00:00
HTMLSRC = """
<!DOCTYPE html>
2010-07-11 10:58:36 +00:00
<html>
<head>
<title>OpenLP Display</title>
<style>
*{
margin: 0;
2010-08-09 21:21:04 +00:00
padding: 0;
border: 0;
2010-09-04 17:55:10 +00:00
overflow: hidden;
2012-04-04 07:26:51 +00:00
-webkit-user-select: none;
2010-07-11 10:58:36 +00:00
}
2010-08-07 06:18:05 +00:00
body {
2010-09-04 07:48:58 +00:00
%s;
2010-08-07 06:18:05 +00:00
}
.size {
position: absolute;
left: 0px;
2010-08-09 21:21:04 +00:00
top: 0px;
2011-08-30 16:54:45 +00:00
width: 100%%;
height: 100%%;
2010-08-09 21:21:04 +00:00
}
#black {
z-index: 8;
background-color: black;
2010-08-09 21:21:04 +00:00
display: none;
}
#bgimage {
z-index: 1;
}
#image {
z-index: 2;
}
2011-06-08 13:18:05 +00:00
%s
2010-08-09 21:21:04 +00:00
#footer {
position: absolute;
z-index: 6;
%s
2010-08-09 21:21:04 +00:00
}
/* lyric css */
2010-07-11 10:58:36 +00:00
%s
sup {
font-size: 0.6em;
vertical-align: top;
position: relative;
top: -0.3em;
}
2010-07-11 10:58:36 +00:00
</style>
<script>
2010-08-09 21:21:04 +00:00
var timer = null;
var transition = %s;
2011-06-08 13:18:05 +00:00
%s
2010-08-07 06:18:05 +00:00
2010-08-09 21:21:04 +00:00
function show_image(src){
2010-08-07 06:18:05 +00:00
var img = document.getElementById('image');
img.src = src;
2010-08-09 21:21:04 +00:00
if(src == '')
2010-08-07 06:18:05 +00:00
img.style.display = 'none';
else
img.style.display = 'block';
}
2010-08-09 21:21:04 +00:00
function show_blank(state){
2010-08-05 05:37:26 +00:00
var black = 'none';
var lyrics = '';
switch(state){
case 'theme':
2010-08-07 06:18:05 +00:00
lyrics = 'hidden';
2010-08-05 05:37:26 +00:00
break;
case 'black':
2010-08-07 06:18:05 +00:00
black = 'block';
break;
case 'desktop':
2010-08-05 19:01:24 +00:00
break;
2010-08-05 05:37:26 +00:00
}
document.getElementById('black').style.display = black;
document.getElementById('lyricsmain').style.visibility = lyrics;
document.getElementById('image').style.visibility = lyrics;
2010-08-07 06:18:05 +00:00
document.getElementById('footer').style.visibility = lyrics;
2010-08-05 05:37:26 +00:00
}
2010-08-21 10:07:59 +00:00
function show_footer(footertext){
2010-08-23 22:24:42 +00:00
document.getElementById('footer').innerHTML = footertext;
2010-08-09 21:21:04 +00:00
}
2013-03-04 11:04:15 +00:00
function show_text(new_text){
var match = /-webkit-text-fill-color:[^;\"]+/gi;
if(timer != null)
clearTimeout(timer);
2012-01-04 17:19:49 +00:00
/*
QtWebkit bug with outlines and justify causing outline alignment
problems. (Bug 859950) Surround each word with a <span> to workaround,
but only in this scenario.
2011-12-08 19:24:25 +00:00
*/
var txt = document.getElementById('lyricsmain');
if(window.getComputedStyle(txt).textAlign == 'justify'){
if(window.getComputedStyle(txt).webkitTextStrokeWidth != '0px'){
2013-03-04 11:04:15 +00:00
new_text = new_text.replace(/(\s|&nbsp;)+(?![^<]*>)/g,
2012-01-04 17:19:49 +00:00
function(match) {
return '</span>' + match + '<span>';
});
2013-03-04 11:04:15 +00:00
new_text = '<span>' + new_text + '</span>';
}
}
2013-03-04 11:04:15 +00:00
text_fade('lyricsmain', new_text);
2010-08-30 18:55:59 +00:00
}
2013-03-04 11:04:15 +00:00
function text_fade(id, new_text){
/*
2013-03-06 13:21:27 +00:00
Show the text.
*/
var text = document.getElementById(id);
2011-12-08 19:24:25 +00:00
if(text == null) return;
if(!transition){
2013-03-04 11:04:15 +00:00
text.innerHTML = new_text;
2010-09-01 21:36:02 +00:00
return;
}
2013-03-12 09:00:22 +00:00
// Fade text out. 0.1 to minimize the time "nothing" is shown on the screen.
text.style.opacity = '0.1';
// Fade new text in after the old text has finished fading out.
2013-03-04 19:14:36 +00:00
timer = window.setTimeout(function(){_show_text(text, new_text)}, 400);
}
2010-08-30 20:57:59 +00:00
2013-03-04 11:04:15 +00:00
function _show_text(text, new_text) {
/*
Helper function to show the new_text delayed.
*/
text.innerHTML = new_text;
2013-03-04 10:52:38 +00:00
text.style.opacity = '1';
2013-03-05 17:08:15 +00:00
// Wait until the text is completely visible. We want to save the timer id, to be able to call
// clearTimeout(timer) when the text has changed before finishing fading.
timer = window.setTimeout(function(){timer = null;}, 400);
}
2010-09-04 07:48:58 +00:00
2013-03-05 10:36:41 +00:00
function show_text_completed(){
2013-03-04 19:14:36 +00:00
return (timer == null);
2010-07-11 10:58:36 +00:00
}
</script>
</head>
<body>
<img id="bgimage" class="size" %s />
<img id="image" class="size" %s />
2011-06-08 13:18:05 +00:00
%s
2013-07-01 06:47:20 +00:00
<div class="lyricstable"><div id="lyricsmain" style="opacity:1" class="lyricscell lyricsmain"></div></div>
2010-07-19 18:03:00 +00:00
<div id="footer" class="footer"></div>
<div id="black" class="size"></div>
2010-07-11 10:58:36 +00:00
</body>
</html>
"""
2010-07-27 19:13:56 +00:00
2013-02-01 19:58:18 +00:00
def build_html(item, screen, is_live, background, image=None, plugins=None):
2010-07-25 08:58:08 +00:00
"""
Build the full web paged structure for display
2014-03-17 19:05:55 +00:00
:param item: Service Item to be displayed
:param screen: Current display information
:param is_live: Item is going live, rather than preview/theme building
:param background: Theme background image - bytes
:param image: Image media item - bytes
:param plugins: The List of available plugins
2010-07-25 08:58:08 +00:00
"""
2013-08-31 18:17:38 +00:00
width = screen['size'].width()
height = screen['size'].height()
2013-12-26 08:56:53 +00:00
theme_data = item.theme_data
2010-10-23 07:23:49 +00:00
# Image generated and poked in
if background:
2013-08-31 18:17:38 +00:00
bgimage_src = 'src="data:image/png;base64,%s"' % background
elif item.bg_image_bytes:
2013-08-31 18:17:38 +00:00
bgimage_src = 'src="data:image/png;base64,%s"' % item.bg_image_bytes
2010-08-07 06:18:05 +00:00
else:
2013-08-31 18:17:38 +00:00
bgimage_src = 'style="display:none;"'
if image:
2013-08-31 18:17:38 +00:00
image_src = 'src="data:image/png;base64,%s"' % image
else:
2013-08-31 18:17:38 +00:00
image_src = 'style="display:none;"'
css_additions = ''
js_additions = ''
html_additions = ''
2011-06-08 13:18:05 +00:00
if plugins:
for plugin in plugins:
2013-03-19 19:43:22 +00:00
css_additions += plugin.get_display_css()
js_additions += plugin.get_display_javascript()
html_additions += plugin.get_display_html()
html = HTMLSRC % (
2013-03-07 12:59:35 +00:00
build_background_css(item, width),
2011-08-29 19:55:58 +00:00
css_additions,
build_footer_css(item, height),
2013-07-01 06:57:13 +00:00
build_lyrics_css(item),
2013-09-05 22:41:24 +00:00
'true' if theme_data and theme_data.display_slide_transition and is_live else 'false',
2011-08-29 19:55:58 +00:00
js_additions,
2013-07-01 06:57:13 +00:00
bgimage_src,
image_src,
2013-07-01 06:47:20 +00:00
html_additions
)
2010-08-09 21:21:04 +00:00
return html
2010-07-11 10:58:36 +00:00
2013-02-01 19:58:18 +00:00
def webkit_version():
2010-09-04 14:23:20 +00:00
"""
2013-03-01 10:50:41 +00:00
Return the Webkit version in use. Note method added relatively recently, so return 0 if prior to this
2010-09-04 14:23:20 +00:00
"""
try:
webkit_ver = float(QtWebKit.qWebKitVersion())
2013-08-31 18:17:38 +00:00
log.debug('Webkit version = %s' % webkit_ver)
except AttributeError:
webkit_ver = 0
return webkit_ver
2013-02-01 19:58:18 +00:00
2013-03-07 12:59:35 +00:00
def build_background_css(item, width):
2010-09-04 07:48:58 +00:00
"""
Build the background css
2014-03-17 19:05:55 +00:00
:param item: Service Item containing theme and location information
:param width:
2010-09-04 07:48:58 +00:00
"""
2013-04-24 19:05:34 +00:00
width = int(width) // 2
2013-12-26 08:56:53 +00:00
theme = item.theme_data
2013-08-31 18:17:38 +00:00
background = 'background-color: black'
2010-09-04 07:48:58 +00:00
if theme:
2012-12-28 22:06:43 +00:00
if theme.background_type == BackgroundType.to_string(BackgroundType.Transparent):
2013-08-31 18:17:38 +00:00
background = ''
2012-12-28 22:06:43 +00:00
elif theme.background_type == BackgroundType.to_string(BackgroundType.Solid):
2013-08-31 18:17:38 +00:00
background = 'background-color: %s' % theme.background_color
2010-09-04 07:48:58 +00:00
else:
2012-12-28 22:06:43 +00:00
if theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Horizontal):
2013-08-31 18:17:38 +00:00
background = 'background: -webkit-gradient(linear, left top, left bottom, from(%s), to(%s)) fixed' \
2012-12-28 22:06:43 +00:00
% (theme.background_start_color, theme.background_end_color)
elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftTop):
2013-08-31 18:17:38 +00:00
background = 'background: -webkit-gradient(linear, left top, right bottom, from(%s), to(%s)) fixed' \
2012-12-28 22:06:43 +00:00
% (theme.background_start_color, theme.background_end_color)
elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.LeftBottom):
2013-08-31 18:17:38 +00:00
background = 'background: -webkit-gradient(linear, left bottom, right top, from(%s), to(%s)) fixed' \
2012-12-28 22:06:43 +00:00
% (theme.background_start_color, theme.background_end_color)
elif theme.background_direction == BackgroundGradientType.to_string(BackgroundGradientType.Vertical):
2013-08-31 18:17:38 +00:00
background = 'background: -webkit-gradient(linear, left top, right top, from(%s), to(%s)) fixed' % \
2010-09-11 06:59:36 +00:00
(theme.background_start_color, theme.background_end_color)
2010-09-04 07:48:58 +00:00
else:
2013-08-31 18:17:38 +00:00
background = 'background: -webkit-gradient(radial, %s 50%%, 100, %s 50%%, %s, from(%s), to(%s)) fixed'\
2012-12-28 22:06:43 +00:00
% (width, width, width, theme.background_start_color, theme.background_end_color)
2010-09-04 07:48:58 +00:00
return background
2013-02-01 19:58:18 +00:00
2013-07-01 06:57:13 +00:00
def build_lyrics_css(item):
2010-07-25 08:58:08 +00:00
"""
Build the lyrics display css
2010-07-25 08:58:08 +00:00
2014-03-17 19:05:55 +00:00
:param item: Service Item containing theme and location information
2010-07-25 08:58:08 +00:00
"""
2013-08-31 18:17:38 +00:00
style = """
2010-09-04 07:48:58 +00:00
.lyricstable {
z-index: 5;
2010-09-04 07:48:58 +00:00
position: absolute;
display: table;
%s
}
2010-09-04 07:48:58 +00:00
.lyricscell {
display: table-cell;
2010-09-04 07:48:58 +00:00
word-wrap: break-word;
2013-03-05 09:40:00 +00:00
-webkit-transition: opacity 0.4s ease;
%s
}
2010-09-04 07:48:58 +00:00
.lyricsmain {
2013-07-01 06:47:20 +00:00
%s
}
2013-09-11 13:51:49 +00:00
"""
2013-12-26 08:56:53 +00:00
theme_data = item.theme_data
2013-08-31 18:17:38 +00:00
lyricstable = ''
lyrics = ''
lyricsmain = ''
2013-07-01 06:57:13 +00:00
if theme_data and item.main:
2013-08-31 18:17:38 +00:00
lyricstable = 'left: %spx; top: %spx;' % (item.main.x(), item.main.y())
2013-07-01 06:57:13 +00:00
lyrics = build_lyrics_format_css(theme_data, item.main.width(), item.main.height())
lyricsmain += build_lyrics_outline_css(theme_data)
if theme_data.font_main_shadow:
2013-09-05 22:41:24 +00:00
lyricsmain += ' text-shadow: %s %spx %spx;' % \
2013-07-01 06:57:13 +00:00
(theme_data.font_main_shadow_color, theme_data.font_main_shadow_size, theme_data.font_main_shadow_size)
2013-07-01 06:47:20 +00:00
lyrics_css = style % (lyricstable, lyrics, lyricsmain)
return lyrics_css
2013-02-01 19:58:18 +00:00
2013-07-01 06:57:13 +00:00
def build_lyrics_outline_css(theme_data):
2010-09-04 14:23:20 +00:00
"""
2013-03-01 10:50:41 +00:00
Build the css which controls the theme outline. Also used by renderer for splitting verses
2010-09-04 14:23:20 +00:00
2014-03-17 19:05:55 +00:00
:param theme_data: Object containing theme information
2010-09-04 14:23:20 +00:00
"""
2013-07-01 06:57:13 +00:00
if theme_data.font_main_outline:
size = float(theme_data.font_main_outline_size) / 16
fill_color = theme_data.font_main_color
outline_color = theme_data.font_main_outline_color
2013-08-31 18:17:38 +00:00
return ' -webkit-text-stroke: %sem %s; -webkit-text-fill-color: %s; ' % (size, outline_color, fill_color)
2013-09-05 22:41:24 +00:00
return ''
2013-02-01 19:58:18 +00:00
2013-07-01 06:57:13 +00:00
def build_lyrics_format_css(theme_data, width, height):
"""
2013-03-01 10:50:41 +00:00
Build the css which controls the theme format. Also used by renderer for splitting verses
2014-03-17 19:05:55 +00:00
:param theme_data: Object containing theme information
:param width: Width of the lyrics block
:param height: Height of the lyrics block
"""
2013-07-01 06:57:13 +00:00
align = HorizontalType.Names[theme_data.display_horizontal_align]
valign = VerticalType.Names[theme_data.display_vertical_align]
if theme_data.font_main_outline:
left_margin = int(theme_data.font_main_outline_size) * 2
else:
left_margin = 0
2013-08-31 18:17:38 +00:00
justify = 'white-space:pre-wrap;'
# fix tag incompatibilities
2013-07-01 06:57:13 +00:00
if theme_data.display_horizontal_align == HorizontalType.Justify:
2013-08-31 18:17:38 +00:00
justify = ''
2013-07-01 06:57:13 +00:00
if theme_data.display_vertical_align == VerticalType.Bottom:
2013-08-31 18:17:38 +00:00
padding_bottom = '0.5em'
2012-03-21 22:27:04 +00:00
else:
2013-08-31 18:17:38 +00:00
padding_bottom = '0'
lyrics = '%s word-wrap: break-word; ' \
2014-03-20 19:10:31 +00:00
'text-align: %s; vertical-align: %s; font-family: %s; ' \
'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \
'padding: 0; padding-bottom: %s; padding-left: %spx; width: %spx; height: %spx; ' % \
2013-07-01 06:57:13 +00:00
(justify, align, valign, theme_data.font_main_name, theme_data.font_main_size,
2014-03-20 19:10:31 +00:00
theme_data.font_main_color, 100 + int(theme_data.font_main_line_adjustment), padding_bottom,
left_margin, width, height)
2013-07-01 06:57:13 +00:00
if theme_data.font_main_italics:
2013-09-11 14:22:28 +00:00
lyrics += 'font-style:italic; '
2013-07-01 06:57:13 +00:00
if theme_data.font_main_bold:
2013-09-11 14:22:28 +00:00
lyrics += 'font-weight:bold; '
return lyrics
2013-02-01 19:58:18 +00:00
def build_footer_css(item, height):
2010-08-03 04:56:21 +00:00
"""
Build the display of the item footer
2014-03-17 19:05:55 +00:00
:param item: Service Item to be processed.
:param height:
2010-08-03 04:56:21 +00:00
"""
2013-08-31 18:17:38 +00:00
style = """
2010-08-30 20:57:59 +00:00
left: %spx;
bottom: %spx;
2010-08-30 20:57:59 +00:00
width: %spx;
font-family: %s;
font-size: %spt;
color: %s;
text-align: left;
2014-07-21 06:37:41 +00:00
white-space: %s;
2010-07-19 18:03:00 +00:00
"""
2013-12-26 08:56:53 +00:00
theme = item.theme_data
if not theme or not item.footer:
2013-08-31 18:17:38 +00:00
return ''
bottom = height - int(item.footer.y()) - int(item.footer.height())
2014-07-21 06:37:41 +00:00
whitespace = 'normal' if Settings().value('themes/wrap footer') else 'nowrap'
2012-12-28 22:06:43 +00:00
lyrics_html = style % (item.footer.x(), bottom, item.footer.width(),
2014-07-21 06:37:41 +00:00
theme.font_footer_name, theme.font_footer_size, theme.font_footer_color, whitespace)
2010-07-12 16:49:38 +00:00
return lyrics_html