This repository was archived by the owner on Jul 19, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderer.h
More file actions
159 lines (129 loc) · 4.9 KB
/
Copy pathrenderer.h
File metadata and controls
159 lines (129 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
* Base class for file format renderers.
* Copyright (c) 2021-2026 Benjamin Johnson
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef RENDERER_H
#define RENDERER_H
#include <QObject> // inherited by basically everything else
#include <QSize>
#include <QString>
#include <QImage>
/*
* Base class for all Renderers.
*
* A Renderer processes files into a format the Viewer can display. It is
* intended to run in a separate QThread to prevent long render operations
* from locking up the user interface.
*
* This class defines the basic renderer API but does not itself implement
* any rendering logic. See render_*.h and render_*.cpp for that.
*
* Use Renderer::create() to create a renderer for a given file. This will
* automatically select the correct subclass to use based on the file type.
*
* Renderer implementations should inherit one of the specific subtypes
* TextContentRenderer or PagedContentRenderer, which provide additional
* common methods, signals, and slots specific to their rendering needs.
*/
class Renderer : public QObject
{
Q_OBJECT
public:
static Renderer *create(const QString &path,
QString *errorOut = nullptr);
static void init();
inline QString path() const { return m_path; }
enum Mode { TextContent, PagedContent };
virtual Renderer::Mode mode() const = 0;
protected:
Renderer();
inline void setPath(const QString &path) { m_path = path; }
// This runs in the constructor to load the file specified by path().
// Override this and return true if the file loaded, false otherwise.
virtual bool load() = 0;
// load() runs in the constructor so it can't use signals for this
static void storeLoadError(const QString &message);
private:
QString m_path;
signals:
void errorEncountered(const QString &details = QString());
};
/*
* Base class for text content renderers.
*
* render() is called once when the file is initially displayed.
* It passes back the entire file contents via the renderedText signal.
*/
class TextContentRenderer : public Renderer
{
Q_OBJECT
public:
inline Renderer::Mode mode() const { return TextContent; }
public slots:
virtual void render() = 0;
protected:
TextContentRenderer();
signals:
void renderedText(const QString &text);
};
/*
* Base class for paged content renderers.
*
* renderPage() is called through a signal from the viewer. It passes back
* a QImage of the requested page's contents via the renderedPage signal.
*
* Your subclass should also implement numPages(), which returns the total
* number of pages in the file, and pageSize(), which returns the dimensions
* in pixels of the specified page.
*/
class PagedContentRenderer : public Renderer
{
Q_OBJECT
public:
virtual int numPages() const = 0;
virtual QSize pageSize(int num) const = 0; // in pixels
inline Renderer::Mode mode() const { return PagedContent; }
// This hints to the viewer to determine how to handle high-DPI scaling.
// If this is true, 1 screen pixel == 1 image pixel regardless of DPI;
// otherwise, scaling is based on the image's inch, not pixel, dimensions.
// Note this is just a hint, and the renderer itself is DPI-agnostic.
virtual inline bool isPixelExact() const { return false; }
// If this is true, the viewer will paint placeholders for any pages
// that are still rendering.
virtual inline bool shouldPaintPlaceholders() const { return true; }
inline int dpiX() const { return m_dpiX; }
inline int dpiY() const { return m_dpiY; }
void setPixelDensity(int dpiX, int dpiY);
inline int zoomFactor() const { return m_zoomFactor; }
void setZoomFactor(int percent);
inline bool pageExists(int num) const
{ return (0 <= num && num < numPages()); }
public slots:
virtual void renderPage(int num) = 0;
protected:
PagedContentRenderer();
inline int zoomScaled(int value) const
{ return (m_zoomFactor == 100) ? value : value * m_zoomFactor / 100; }
inline QSize zoomScaled(const QSize &size) const
{ return (m_zoomFactor == 100) ? size : size * m_zoomFactor / 100; }
private:
int m_dpiX, m_dpiY;
int m_zoomFactor;
signals:
void renderedPage(int num, const QImage &image);
};
#endif /* RENDERER_H */