This repository has been archived on 2020-08-22. You can view files and clone it, but cannot push or open issues or pull requests.
pyaudviz/src/components/text.py

204 lines
7.3 KiB
Python
Raw Normal View History

2017-08-07 21:03:01 -04:00
from PIL import ImageEnhance, ImageFilter, ImageChops
from PyQt5.QtGui import QColor, QFont
2017-06-24 23:12:41 -04:00
from PyQt5 import QtGui, QtCore, QtWidgets
import os
import logging
2017-07-02 20:46:48 -04:00
from component import Component
from toolkit.frame import FramePainter, PaintColor
log = logging.getLogger('AVP.Components.Text')
2017-07-02 20:46:48 -04:00
class Component(Component):
name = 'Title Text'
version = '1.0.1'
def widget(self, *args):
super().widget(*args)
self.title = 'Text'
self.alignment = 1
self.titleFont = QFont()
self.fontSize = self.height / 13.5
self.page.comboBox_textAlign.addItem("Left")
self.page.comboBox_textAlign.addItem("Middle")
self.page.comboBox_textAlign.addItem("Right")
self.page.comboBox_textAlign.setCurrentIndex(int(self.alignment))
self.page.spinBox_fontSize.setValue(int(self.fontSize))
self.page.lineEdit_title.setText(self.title)
self.page.pushButton_center.clicked.connect(self.centerXY)
self.page.fontComboBox_titleFont.currentFontChanged.connect(
self.update
)
self.trackWidgets({
'textColor': self.page.lineEdit_textColor,
'title': self.page.lineEdit_title,
'alignment': self.page.comboBox_textAlign,
'fontSize': self.page.spinBox_fontSize,
'xPosition': self.page.spinBox_xTextAlign,
'yPosition': self.page.spinBox_yTextAlign,
'fontStyle': self.page.comboBox_fontStyle,
'stroke': self.page.spinBox_stroke,
'strokeColor': self.page.lineEdit_strokeColor,
'shadow': self.page.checkBox_shadow,
'shadX': self.page.spinBox_shadX,
'shadY': self.page.spinBox_shadY,
'shadBlur': self.page.spinBox_shadBlur,
}, colorWidgets={
'textColor': self.page.pushButton_textColor,
'strokeColor': self.page.pushButton_strokeColor,
}, relativeWidgets=[
2017-08-08 06:03:14 -04:00
'xPosition', 'yPosition', 'fontSize',
'stroke', 'shadX', 'shadY', 'shadBlur'
])
self.centerXY()
def update(self):
self.titleFont = self.page.fontComboBox_titleFont.currentFont()
if self.page.checkBox_shadow.isChecked():
self.page.label_shadX.setHidden(False)
self.page.spinBox_shadX.setHidden(False)
self.page.spinBox_shadY.setHidden(False)
self.page.label_shadBlur.setHidden(False)
self.page.spinBox_shadBlur.setHidden(False)
else:
self.page.label_shadX.setHidden(True)
self.page.spinBox_shadX.setHidden(True)
self.page.spinBox_shadY.setHidden(True)
self.page.label_shadBlur.setHidden(True)
self.page.spinBox_shadBlur.setHidden(True)
def centerXY(self):
self.setRelativeWidget('xPosition', 0.5)
self.setRelativeWidget('yPosition', 0.521)
def getXY(self):
'''Returns true x, y after considering alignment settings'''
2017-05-28 14:49:35 -04:00
fm = QtGui.QFontMetrics(self.titleFont)
x = self.pixelValForAttr('xPosition')
if self.alignment == 1: # Middle
2017-07-13 00:05:11 -04:00
offset = int(fm.width(self.title)/2)
x -= offset
if self.alignment == 2: # Right
offset = fm.width(self.title)
x -= offset
return x, self.yPosition
def loadPreset(self, pr, *args):
super().loadPreset(pr, *args)
font = QFont()
font.fromString(pr['titleFont'])
self.page.fontComboBox_titleFont.setCurrentFont(font)
2017-05-28 21:24:51 -04:00
def savePreset(self):
saveValueStore = super().savePreset()
saveValueStore['titleFont'] = self.titleFont.toString()
return saveValueStore
2017-05-28 21:24:51 -04:00
def previewRender(self):
return self.addText(self.width, self.height)
def properties(self):
props = ['static']
if not self.title:
props.append('error')
return props
def error(self):
return "No text provided."
def frameRender(self, frameNo):
return self.addText(self.width, self.height)
def addText(self, width, height):
font = self.titleFont
font.setPixelSize(self.fontSize)
font.setStyle(QFont.StyleNormal)
font.setWeight(QFont.Normal)
font.setCapitalization(QFont.MixedCase)
if self.fontStyle == 1:
font.setWeight(QFont.DemiBold)
if self.fontStyle == 2:
font.setWeight(QFont.Bold)
elif self.fontStyle == 3:
font.setStyle(QFont.StyleItalic)
elif self.fontStyle == 4:
font.setWeight(QFont.Bold)
font.setStyle(QFont.StyleItalic)
elif self.fontStyle == 5:
font.setStyle(QFont.StyleOblique)
elif self.fontStyle == 6:
font.setCapitalization(QFont.SmallCaps)
2017-07-11 06:06:22 -04:00
image = FramePainter(width, height)
x, y = self.getXY()
log.debug('Text position translates to %s, %s', x, y)
if self.stroke > 0:
outliner = QtGui.QPainterPathStroker()
outliner.setWidth(self.stroke)
path = QtGui.QPainterPath()
2017-08-08 20:53:51 -04:00
if self.fontStyle == 6:
# PathStroker ignores smallcaps so we need this weird hack
path.addText(x, y, font, self.title[0])
fm = QtGui.QFontMetrics(font)
newX = x + fm.width(self.title[0])
strokeFont = self.page.fontComboBox_titleFont.currentFont()
strokeFont.setCapitalization(QFont.SmallCaps)
strokeFont.setPixelSize(int((self.fontSize / 7) * 5))
strokeFont.setLetterSpacing(QFont.PercentageSpacing, 139)
path.addText(newX, y, strokeFont, self.title[1:])
else:
path.addText(x, y, font, self.title)
path = outliner.createStroke(path)
image.setPen(QtCore.Qt.NoPen)
image.setBrush(PaintColor(*self.strokeColor))
image.drawPath(path)
image.setFont(font)
image.setPen(self.textColor)
image.drawText(x, y, self.title)
2017-08-07 21:03:01 -04:00
# turn QImage into Pillow frame
frame = image.finalize()
if self.shadow:
shadImg = ImageEnhance.Contrast(frame).enhance(0.0)
shadImg = shadImg.filter(ImageFilter.GaussianBlur(self.shadBlur))
shadImg = ImageChops.offset(shadImg, self.shadX, self.shadY)
shadImg.paste(frame, box=(0, 0), mask=frame)
frame = shadImg
return frame
def commandHelp(self):
print('Enter a string to use as centred white text:')
print(' "title=User Error"')
print('Specify a text color:\n color=255,255,255')
print('Set custom x, y position:\n x=500 y=500')
def command(self, arg):
if '=' in arg:
key, arg = arg.split('=', 1)
if key == 'color':
self.page.lineEdit_textColor.setText(arg)
return
elif key == 'size':
self.page.spinBox_fontSize.setValue(int(arg))
return
elif key == 'x':
self.page.spinBox_xTextAlign.setValue(int(arg))
return
elif key == 'y':
self.page.spinBox_yTextAlign.setValue(int(arg))
return
elif key == 'title':
self.page.lineEdit_title.setText(arg)
return
super().command(arg)