ported ALL effects to opengl
This commit is contained in:
+186
-70
@@ -21,9 +21,9 @@
|
||||
#include "ui/fontcombobox.h"
|
||||
|
||||
TextEffect::TextEffect(Clip *c) :
|
||||
Effect(c, EFFECT_TYPE_VIDEO, VIDEO_TEXT_EFFECT)
|
||||
SuperimposeEffect(c, EFFECT_TYPE_VIDEO, VIDEO_TEXT_EFFECT)
|
||||
{
|
||||
enable_image = true;
|
||||
enable_superimpose = true;
|
||||
|
||||
text_val = add_row("Text:")->add_field(EFFECT_FIELD_STRING, 2);
|
||||
|
||||
@@ -98,6 +98,186 @@ TextEffect::TextEffect(Clip *c) :
|
||||
connect(outline_bool, SIGNAL(toggled(bool)), this, SLOT(outline_enable(bool)));
|
||||
}
|
||||
|
||||
void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = false) {
|
||||
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
|
||||
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
|
||||
|
||||
int r1 = rect.top();
|
||||
int r2 = rect.bottom();
|
||||
int c1 = rect.left();
|
||||
int c2 = rect.right();
|
||||
|
||||
int bpl = result.bytesPerLine();
|
||||
int rgba[4];
|
||||
unsigned char* p;
|
||||
|
||||
int i1 = 0;
|
||||
int i2 = 3;
|
||||
|
||||
if (alphaOnly)
|
||||
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
|
||||
|
||||
for (int col = c1; col <= c2; col++) {
|
||||
p = result.scanLine(r1) + col * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p += bpl;
|
||||
for (int j = r1; j < r2; j++, p += bpl)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int row = r1; row <= r2; row++) {
|
||||
p = result.scanLine(row) + c1 * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p += 4;
|
||||
for (int j = c1; j < c2; j++, p += 4)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int col = c1; col <= c2; col++) {
|
||||
p = result.scanLine(r2) + col * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p -= bpl;
|
||||
for (int j = r1; j < r2; j++, p -= bpl)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int row = r1; row <= r2; row++) {
|
||||
p = result.scanLine(row) + c2 * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p -= 4;
|
||||
for (int j = c1; j < c2; j++, p -= 4)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
void TextEffect::redraw(double timecode) {
|
||||
img.fill(Qt::transparent);
|
||||
|
||||
QPainter p(&img);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
int width = img.width();
|
||||
int height = img.height();
|
||||
|
||||
// set font
|
||||
font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias);
|
||||
font.setFamily(set_font_combobox->get_font_name(timecode));
|
||||
font.setPointSize(size_val->get_double_value(timecode));
|
||||
p.setFont(font);
|
||||
QFontMetrics fm(font);
|
||||
|
||||
QStringList lines = text_val->get_string_value(timecode).split('\n');
|
||||
|
||||
// word wrap function
|
||||
if (word_wrap_field->get_bool_value(timecode)) {
|
||||
for (int i=0;i<lines.size();i++) {
|
||||
QString s(lines.at(i));
|
||||
if (fm.width(s) > width) {
|
||||
int last_space_index = 0;
|
||||
for (int j=0;j<s.length();j++) {
|
||||
if (s.at(j) == ' ') {
|
||||
if (fm.width(s.left(j)) > width) {
|
||||
break;
|
||||
} else {
|
||||
last_space_index = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last_space_index > 0) {
|
||||
lines.insert(i+1, s.mid(last_space_index + 1));
|
||||
lines[i] = s.left(last_space_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPainterPath path;
|
||||
|
||||
int text_height = fm.height()*lines.size();
|
||||
|
||||
for (int i=0;i<lines.size();i++) {
|
||||
int text_x, text_y;
|
||||
|
||||
switch (halign_field->get_combo_data(timecode).toInt()) {
|
||||
case Qt::AlignLeft: text_x = 0; break;
|
||||
case Qt::AlignHCenter: text_x = (width/2) - (fm.width(lines.at(i))/2); break;
|
||||
case Qt::AlignRight: text_x = width - fm.width(lines.at(i)); break;
|
||||
case Qt::AlignJustify:
|
||||
// add spaces until the string is too big
|
||||
text_x = 0;
|
||||
while (fm.width(lines.at(i) < width)) {
|
||||
bool space = false;
|
||||
QString spaced(lines.at(i));
|
||||
for (int i=0;i<spaced.length();i++) {
|
||||
if (spaced.at(i) == ' ') {
|
||||
// insert a space
|
||||
spaced.insert(i, ' ');
|
||||
space = true;
|
||||
|
||||
// scan to next non-space
|
||||
while (i < spaced.length() && spaced.at(i) == ' ') i++;
|
||||
}
|
||||
}
|
||||
if (fm.width(spaced) > width || !space) {
|
||||
break;
|
||||
} else {
|
||||
lines[i] = spaced;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (valign_field->get_combo_data(timecode).toInt()) {
|
||||
case Qt::AlignTop: text_y = (fm.height()*i)+fm.ascent(); break;
|
||||
case Qt::AlignVCenter: text_y = ((height/2) - (text_height/2) - fm.descent()) + (fm.height()*(i+1)); break;
|
||||
case Qt::AlignBottom: text_y = (height - text_height - fm.descent()) + (fm.height()*(i+1)); break;
|
||||
}
|
||||
|
||||
path.addText(text_x, text_y, font, lines.at(i));
|
||||
}
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
// draw shadow
|
||||
if (shadow_bool->get_bool_value(timecode)) {
|
||||
int shadow_offset = shadow_distance->get_double_value(timecode);
|
||||
|
||||
QPainterPath shadow_path(path);
|
||||
shadow_path.translate(shadow_offset, shadow_offset);
|
||||
|
||||
QColor col = shadow_color->get_color_value(timecode);
|
||||
col.setAlphaF(shadow_opacity->get_double_value(timecode)*0.01);
|
||||
p.setBrush(col);
|
||||
p.drawPath(shadow_path);
|
||||
|
||||
int blurSoftness = shadow_softness->get_double_value(timecode);
|
||||
if (blurSoftness > 0) blurred2(img, img.rect(), blurSoftness, false);
|
||||
}
|
||||
|
||||
// draw outline
|
||||
int outline_width_val = outline_width->get_double_value(timecode);
|
||||
if (outline_bool->get_bool_value(timecode) && outline_width_val > 0) {
|
||||
QPen outline(outline_color->get_color_value(timecode));
|
||||
outline.setWidth(outline_width_val);
|
||||
p.setPen(outline);
|
||||
}
|
||||
|
||||
// draw "master" text
|
||||
p.setBrush(set_color_button->get_color_value(timecode));
|
||||
p.drawPath(path);
|
||||
}
|
||||
|
||||
void TextEffect::shadow_enable(bool e) {
|
||||
shadow_color->set_enabled(e);
|
||||
shadow_distance->set_enabled(e);
|
||||
@@ -110,7 +290,7 @@ void TextEffect::outline_enable(bool e) {
|
||||
outline_width->set_enabled(e);
|
||||
}
|
||||
|
||||
QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
|
||||
/*QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
|
||||
{
|
||||
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
|
||||
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
|
||||
@@ -176,73 +356,9 @@ QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnl
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}*/
|
||||
|
||||
void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = false) {
|
||||
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
|
||||
int alpha = (radius < 1) ? 16 : (radius > 17) ? 1 : tab[radius-1];
|
||||
|
||||
int r1 = rect.top();
|
||||
int r2 = rect.bottom();
|
||||
int c1 = rect.left();
|
||||
int c2 = rect.right();
|
||||
|
||||
int bpl = result.bytesPerLine();
|
||||
int rgba[4];
|
||||
unsigned char* p;
|
||||
|
||||
int i1 = 0;
|
||||
int i2 = 3;
|
||||
|
||||
if (alphaOnly)
|
||||
i1 = i2 = (QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3);
|
||||
|
||||
for (int col = c1; col <= c2; col++) {
|
||||
p = result.scanLine(r1) + col * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p += bpl;
|
||||
for (int j = r1; j < r2; j++, p += bpl)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int row = r1; row <= r2; row++) {
|
||||
p = result.scanLine(row) + c1 * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p += 4;
|
||||
for (int j = c1; j < c2; j++, p += 4)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int col = c1; col <= c2; col++) {
|
||||
p = result.scanLine(r2) + col * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p -= bpl;
|
||||
for (int j = r1; j < r2; j++, p -= bpl)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
|
||||
for (int row = r1; row <= r2; row++) {
|
||||
p = result.scanLine(row) + c2 * 4;
|
||||
for (int i = i1; i <= i2; i++)
|
||||
rgba[i] = p[i] << 4;
|
||||
|
||||
p -= 4;
|
||||
for (int j = c1; j < c2; j++, p -= 4)
|
||||
for (int i = i1; i <= i2; i++)
|
||||
p[i] = (rgba[i] += ((p[i] << 4) - rgba[i]) * alpha / 16) >> 4;
|
||||
}
|
||||
}
|
||||
|
||||
void TextEffect::process_image(double timecode, uint8_t* data, int w, int h) {
|
||||
/*void TextEffect::process_image(double timecode, uint8_t* data, int w, int h) {
|
||||
QImage img(data, w, h, QImage::Format_RGBA8888);
|
||||
QPainter p(&img);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
@@ -357,4 +473,4 @@ void TextEffect::process_image(double timecode, uint8_t* data, int w, int h) {
|
||||
// draw "master" text
|
||||
p.setBrush(set_color_button->get_color_value(timecode));
|
||||
p.drawPath(path);
|
||||
}
|
||||
}*/
|
||||
|
||||
Reference in New Issue
Block a user