Skip to content

Commit 843c984

Browse files
committed
Cache HTML doc rendering
1 parent 49498c3 commit 843c984

File tree

2 files changed

+60
-27
lines changed

2 files changed

+60
-27
lines changed

src/subtitlestyle.cpp

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <QtGui/QTextDocument>
2020
#include <QtGui/QTextFrame>
2121
#include <QRegularExpression>
22+
#include <QHash>
2223

2324
#include "script.h"
2425
#include "subtitlestyle.h"
@@ -46,11 +47,13 @@ SubtitleStyle::SubtitleStyle(const SubtitleStyle &p_oth, const QFont &f,
4647

4748
void SubtitleStyle::setAlignment(Qt::Alignment p_alignment) {
4849
m_alignment = p_alignment;
50+
invalidateCache();
4951
}
5052

5153
void SubtitleStyle::setOffsets(double p_h, double p_v) {
5254
m_offsetH = p_h;
5355
m_offsetV = p_v;
56+
invalidateCache();
5457
}
5558

5659
int SubtitleStyle::marginL() const { return m_marginL; }
@@ -65,6 +68,7 @@ void SubtitleStyle::setMargins(int p_marginL, int p_marginR, int p_marginV) {
6568
m_marginL = p_marginL;
6669
m_marginR = p_marginR;
6770
m_marginV = p_marginV;
71+
invalidateCache();
6872
}
6973

7074
const QString &SubtitleStyle::name() const { return m_name; }
@@ -91,16 +95,21 @@ const QFont &SubtitleStyle::font() const { return m_font; }
9195
void SubtitleStyle::setFont(const QFont &f) {
9296
m_font = f;
9397
m_font.setStyleStrategy(QFont::PreferAntialias);
98+
invalidateCache();
9499
}
95100

96101
const QColor &SubtitleStyle::primaryColour() const { return m_primaryColour; }
97102

98-
void SubtitleStyle::setPrimaryColour(const QColor &c) { m_primaryColour = c; }
103+
void SubtitleStyle::setPrimaryColour(const QColor &c) {
104+
m_primaryColour = c;
105+
invalidateCache();
106+
}
99107

100108
qreal SubtitleStyle::lineSpacing() const { return m_lineSpacing; }
101109

102110
void SubtitleStyle::setLineSpacing(qreal p_lineSpacing) {
103111
m_lineSpacing = p_lineSpacing;
112+
invalidateCache();
104113
}
105114

106115
int SubtitleStyle::subtitleHeight(const Subtitle &subtitle,
@@ -135,6 +144,11 @@ const QPoint SubtitleStyle::textAnchor(const QPoint &p_point,
135144
return p_point + offset;
136145
}
137146

147+
void SubtitleStyle::invalidateCache() const {
148+
qDeleteAll(m_docCache);
149+
m_docCache.clear();
150+
}
151+
138152
void SubtitleStyle::drawSubtitle(QPainter *painter, const Subtitle &subtitle,
139153
const QRect &bounds, const QPen &outline,
140154
const qreal p_scale, const qreal p_dpi) const {
@@ -152,12 +166,12 @@ void SubtitleStyle::drawSubtitle(QPainter *painter, const Subtitle &subtitle,
152166

153167
int stack = 0;
154168

155-
foreach (SubtitleLine line, subtitle.lines()) {
169+
for (const SubtitleLine &line : subtitle.lines()) {
156170
QRect final(bounds);
157171

158172
QPoint position = line.position();
159173

160-
QString horizontalAlign = "";
174+
QString horizontalAlign = "center";
161175
if (position.x() >= 0 && position.y() >= 0) {
162176
// absolute positioning : (x, y)
163177
position.setX(bounds.x() + qRound(position.x() * scale.x()));
@@ -210,28 +224,44 @@ void SubtitleStyle::drawSubtitle(QPainter *painter, const Subtitle &subtitle,
210224
stack += qRound(fontMetrics.height() * (1.0 + m_lineSpacing));
211225
}
212226

213-
// Replace text and create document with the scaled font
214-
QString html =
215-
QString("<style>p { font-size: 100%%; }</style><p align=\"%1\">%2</p>")
216-
.arg(horizontalAlign)
217-
.arg(line.text());
218-
QTextDocument doc;
219-
// Ensure page size is at least 1x1
220-
QSize pageSize(qMax(1, final.width()), qMax(1, final.height()));
221-
doc.setPageSize(pageSize);
222-
doc.setDefaultFont(scaledFont);
223-
doc.setHtml(html);
224-
225-
// Reduce document margins to 0 (all sides)
226-
QTextFrame *tf = doc.rootFrame();
227-
QTextFrameFormat tff = tf->frameFormat();
228-
tff.setTopMargin(0);
229-
tff.setBottomMargin(0);
230-
tff.setLeftMargin(0);
231-
tff.setRightMargin(0);
232-
tf->setFrameFormat(tff);
233-
234-
QAbstractTextDocumentLayout *layout = doc.documentLayout();
227+
// Prepare cache key (text + font family + font point size + scale +
228+
// alignment)
229+
QString cacheKey = QString("%1|%2|%3|%4|%5")
230+
.arg(line.text())
231+
.arg(scaledFont.family())
232+
.arg(scaledFont.pointSizeF())
233+
.arg(uniformScale)
234+
.arg(horizontalAlign);
235+
236+
QTextDocument *doc = nullptr;
237+
238+
if (m_docCache.contains(cacheKey)) {
239+
doc = m_docCache.value(cacheKey);
240+
} else {
241+
doc = new QTextDocument();
242+
m_docCache.insert(cacheKey, doc);
243+
244+
// Set font and HTML once
245+
doc->setDefaultFont(scaledFont);
246+
QString html = QString("<style>p { font-size: 100%%; margin:0; "
247+
"padding:0; }</style><p align=\"%1\">%2</p>")
248+
.arg(horizontalAlign)
249+
.arg(line.text());
250+
doc->setHtml(html);
251+
252+
QTextFrame *tf = doc->rootFrame();
253+
QTextFrameFormat tff = tf->frameFormat();
254+
tff.setTopMargin(0);
255+
tff.setBottomMargin(0);
256+
tff.setLeftMargin(0);
257+
tff.setRightMargin(0);
258+
tf->setFrameFormat(tff);
259+
}
260+
261+
// Set page size to fit final rect
262+
doc->setPageSize(QSize(qMax(1, final.width()), qMax(1, final.height())));
263+
264+
QAbstractTextDocumentLayout *layout = doc->documentLayout();
235265
painter->setFont(scaledFont);
236266
painter->setPen(m_primaryColour);
237267
QAbstractTextDocumentLayout::PaintContext context;
@@ -241,8 +271,7 @@ void SubtitleStyle::drawSubtitle(QPainter *painter, const Subtitle &subtitle,
241271
painter->translate(final.x(), final.y());
242272

243273
if (outline.width() > 0) {
244-
// Paint outline by applying a text outline format to the whole document
245-
QTextCursor cursor(&doc);
274+
QTextCursor cursor(doc);
246275
cursor.select(QTextCursor::Document);
247276
QTextCharFormat format;
248277
format.setTextOutline(outline);

src/subtitlestyle.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class SubtitleStyle : public QObject {
6666
const QPoint textAnchor(const QPoint &p_point, const QString &p_text,
6767
const QFontMetrics &metrics) const;
6868
const QFont scaledFont(const qreal, const qreal) const;
69+
void invalidateCache() const;
70+
6971
QString m_name;
7072
QFont m_font;
7173
QColor m_primaryColour;
@@ -89,6 +91,8 @@ class SubtitleStyle : public QObject {
8991
*/
9092
double m_offsetH;
9193
double m_offsetV;
94+
95+
mutable QHash<QString, QTextDocument *> m_docCache;
9296
};
9397

9498
#endif // SUBTITLESTYLE_H

0 commit comments

Comments
 (0)