Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions src/modules/qt/kdenlivetitle_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,6 @@ void loadFromXml(producer_ktitle self,
qWarning() << "Ignoring invalid title rich-text gradient metadata";
}
txt->document()->setDocumentMargin(0);
TitlerGradientV1::applyBrushes(txt->document(), int(boxWidth), int(boxHeight));

QTextOption option = txt->document()->defaultTextOption();
if (tabWidth > 0) {
Expand Down Expand Up @@ -592,16 +591,35 @@ void loadFromXml(producer_ktitle self,
txt->setTextWidth(boxWidth);
}

// Selective brushes use the final laid-out glyph positions. A
// legacy object gradient retains precedence over run metadata.
if (txtProperties.namedItem("gradient").isNull()) {
TitlerGradientV1::applyBrushes(txt->document(),
int(boxWidth),
int(boxHeight));
}

if (!TitlerShadowV1::restore(contentElement, txt->document())) {
qWarning() << "Ignoring invalid title rich-text shadow metadata";
}
if (!txtProperties.namedItem("shadow").isNull()) {
const QStringList values
= txtProperties.namedItem("shadow").nodeValue().split(";");

if (values.count() >= 5 && values.at(0).toInt() != 0) {
auto *shadow = new QGraphicsDropShadowEffect();
shadow->setColor(QColor(values.at(1)));
shadow->setBlurRadius(values.at(2).toDouble());
shadow->setOffset(values.at(3).toDouble(), values.at(4).toDouble());
txt->setGraphicsEffect(shadow);
if (values.count() >= 5) {
txt->setShadowFallback({values.at(0).toInt() != 0,
QColor(values.at(1)),
values.at(2).toInt(),
values.at(3).toInt(),
values.at(4).toInt()});
if (values.at(0).toInt() != 0
&& !TitlerShadowV1::hasOverrides(txt->document())) {
auto *shadow = new QGraphicsDropShadowEffect();
shadow->setColor(QColor(values.at(1)));
shadow->setBlurRadius(values.at(2).toDouble());
shadow->setOffset(values.at(3).toDouble(), values.at(4).toDouble());
txt->setGraphicsEffect(shadow);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/qt/producer_kdenlivetitle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ schema_version: 7.2
type: producer
identifier: kdenlivetitle
title: Kdenlive Titler
version: 8
version: 9
copyright: Marco Gittler, Jean-Baptiste Mardelle
creator: Marco Gittler, Jean-Baptiste Mardelle
license: LGPLv2.1
Expand Down
56 changes: 50 additions & 6 deletions src/modules/qt/richtextanimation.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#pragma once

#include "richtextoutline.h"
#include "richtextshadow.h"

#include <algorithm>
#include <cmath>
Expand Down Expand Up @@ -103,6 +104,7 @@ class Schedule
class Item : public QGraphicsTextItem
{
public:
void setShadowFallback(const TitlerShadowV1::Style &style) { m_shadowStyle = style; }
void setOutline(qreal width, const QColor &color)
{
width = std::isfinite(width) ? std::max(qreal(0), width) : qreal(0);
Expand All @@ -123,6 +125,7 @@ class Item : public QGraphicsTextItem
{
const qreal margin = m_outlineMargin;
return QGraphicsTextItem::boundingRect()
.united(m_shadowBounds)
.united(m_inkBounds)
.adjusted(-margin, -margin, margin, margin);
}
Expand All @@ -131,6 +134,11 @@ class Item : public QGraphicsTextItem
prepareGeometryChange();
m_inkBounds = TitlerOutline::inkBounds(document());
m_outlineMargin = TitlerOutline::margin(document(), m_outlinePen);
m_shadowOverrides = TitlerShadowV1::hasOverrides(document());
m_shadowBounds = m_shadowOverrides
? TitlerShadowV1::bounds(document(), m_shadowStyle, m_outlinePen)
: QRectF();
m_shadowVisible = -1;
m_total = document()->characterCount() - 1;
m_text = document()->toPlainText();
m_visible = m_total;
Expand Down Expand Up @@ -175,6 +183,7 @@ class Item : public QGraphicsTextItem
int lineId;
QTextCharFormat format;
QRawFont physicalFont;
QRectF lineBounds;
};

QVector<VisualCell> visibleCells() const
Expand Down Expand Up @@ -228,16 +237,22 @@ class Item : public QGraphicsTextItem
const qreal a = line.cursorToX(start);
const qreal z = line.cursorToX(end);
const QPointF origin = layout->position();
const QRectF rect(origin.x() + std::min(a, z),
origin.y() + line.y(),
std::abs(z - a),
line.height());
// Preserve the legacy title path; selective shadows and their
// visible text share the same shaped decoration intervals.
const QRectF rect
= m_shadowOverrides
? TitlerShadowV1::decorationRect(line, start, end - start, runs, origin)
: QRectF(origin.x() + std::min(a, z),
origin.y() + line.y(),
std::abs(z - a),
line.height());
cells.append({rect,
block.position() + end <= m_visible ? rect : QRectF(),
origin.y() + line.y() + line.ascent(),
block.position() + line.textStart(),
format,
physicalFont});
physicalFont,
line.naturalTextRect().translated(origin)});
}
}
std::sort(cells.begin(), cells.end(), [](const VisualCell &a, const VisualCell &b) {
Expand Down Expand Up @@ -395,6 +410,17 @@ class Item : public QGraphicsTextItem
return;
}
painter->save();
if (m_shadowOverrides) {
if (m_shadowVisible != m_visible) {
m_shadowLayers = TitlerShadowV1::render(document(),
m_shadowStyle,
m_outlinePen,
m_visible,
defaultTextColor());
m_shadowVisible = m_visible;
}
TitlerShadowV1::paint(painter, m_shadowLayers);
}
TitlerOutline::paint(painter, document(), m_outlinePen, m_visible);
{
// The final reveal uses the same cells, glyphs and decorations as earlier frames.
Expand Down Expand Up @@ -438,12 +464,30 @@ class Item : public QGraphicsTextItem
}
}
}
paintDecorations(painter, cells);
if (m_shadowOverrides) {
// New selective-shadow titles use Qt's decoration placement for
// both the visible text and its alpha mask. Keep legacy frames.
painter->save();
painter->setClipRect(TitlerShadowV1::decorationBounds(document(), m_outlinePen),
Qt::IntersectClip);
TitlerShadowV1::paintShadowDecorations(painter,
cells,
document()->defaultFont(),
defaultTextColor());
painter->restore();
} else {
paintDecorations(painter, cells);
}
}
painter->restore();
}

private:
TitlerShadowV1::Style m_shadowStyle;
TitlerShadowV1::Layers m_shadowLayers;
QRectF m_shadowBounds;
int m_shadowVisible{-1};
bool m_shadowOverrides{false};
QPen m_outlinePen{Qt::NoPen};
qreal m_outlineMargin{0};
QRectF m_inkBounds;
Expand Down
Loading
Loading