1 /*
2 * Copyright (C) 2019, Masamichi Hosoda <trueroad@trueroad.jp>
3 * Copyright (C) 2019 Albert Astals Cid <aacid@kde.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 /**
21 \file poppler-destination.h
22 */
23 #include "poppler-destination.h"
24
25 #include "poppler-destination-private.h"
26
27 #include "PDFDoc.h"
28 #include "Link.h"
29
30 #include <utility>
31
32 using namespace poppler;
33
destination_private(const LinkDest * ld,PDFDoc * doc)34 destination_private::destination_private(const LinkDest *ld, PDFDoc *doc) : pdf_doc(doc)
35 {
36 if (!ld) {
37 type = destination::unknown;
38 return;
39 }
40
41 switch (ld->getKind()) {
42 case ::destXYZ:
43 type = destination::xyz;
44 break;
45 case ::destFit:
46 type = destination::fit;
47 break;
48 case ::destFitH:
49 type = destination::fit_h;
50 break;
51 case ::destFitV:
52 type = destination::fit_v;
53 break;
54 case ::destFitR:
55 type = destination::fit_r;
56 break;
57 case ::destFitB:
58 type = destination::fit_b;
59 break;
60 case ::destFitBH:
61 type = destination::fit_b_h;
62 break;
63 case ::destFitBV:
64 type = destination::fit_b_v;
65 break;
66 default:
67 type = destination::unknown;
68 break;
69 }
70
71 if (!ld->isPageRef()) {
72 // The page number has been resolved.
73 page_number_unresolved = false;
74 page_number = ld->getPageNum();
75 } else if (doc) {
76 // It is necessary to resolve the page number by its accessor.
77 page_number_unresolved = true;
78 page_ref = ld->getPageRef();
79 } else {
80 // The page number cannot be resolved because there is no PDFDoc.
81 page_number_unresolved = false;
82 page_number = 0;
83 }
84
85 left = ld->getLeft();
86 bottom = ld->getBottom();
87 right = ld->getRight();
88 top = ld->getTop();
89 zoom = ld->getZoom();
90 change_left = ld->getChangeLeft();
91 change_top = ld->getChangeTop();
92 change_zoom = ld->getChangeZoom();
93 }
94
95 /**
96 \class poppler::destination poppler-destination.h "poppler/cpp/poppler-destination.h"
97
98 The information about a destination used in a PDF %document.
99 */
100
101 /**
102 \enum poppler::destination::type_enum
103
104 The various types of destinations available in a PDF %document.
105 */
106 /**
107 \var poppler::destination::type_enum poppler::destination::unknown
108
109 unknown destination
110 */
111 /**
112 \var poppler::destination::type_enum poppler::destination::xyz
113
114 go to page with coordinates (left, top) positioned at the upper-left
115 corner of the window and the contents of the page magnified
116 by the factor zoom
117 */
118 /**
119 \var poppler::destination::type_enum poppler::destination::fit
120
121 go to page with its contents magnified just enough to fit the entire page
122 within the window both horizontally and vertically
123 */
124 /**
125 \var poppler::destination::type_enum poppler::destination::fit_h
126
127 go to page with the vertical coordinate top positioned at the top edge
128 of the window and the contents of the page magnified just enough to fit
129 the entire width of the page within the window
130 */
131 /**
132 \var poppler::destination::type_enum poppler::destination::fit_v
133
134 go to page with the horizontal coordinate left positioned at the left edge
135 of the window and the contents of the page magnified just enough to fit
136 the entire height of the page within the window
137 */
138 /**
139 \var poppler::destination::type_enum poppler::destination::fit_r
140
141 go to page with its contents magnified just enough to fit the rectangle
142 specified by the coordinates left, bottom, right, and top entirely
143 within the window both horizontally and vertically
144 */
145 /**
146 \var poppler::destination::type_enum poppler::destination::fit_b
147
148 go to page with its contents magnified just enough to fit its bounding box
149 entirely within the window both horizontally and vertically
150 */
151 /**
152 \var poppler::destination::type_enum poppler::destination::fit_b_h
153
154 go to page with the vertical coordinate top positioned at the top edge
155 of the window and the contents of the page magnified just enough to fit
156 the entire width of its bounding box within the window
157 */
158 /**
159 \var poppler::destination::type_enum poppler::destination::fit_b_v
160
161 go to page with the horizontal coordinate left positioned at the left edge
162 of the window and the contents of the page magnified just enough to fit
163 the entire height of its bounding box within the window
164 */
165
destination(destination_private * dd)166 destination::destination(destination_private *dd) : d(dd) { }
167
168 /**
169 Move constructor.
170 */
destination(destination && other)171 destination::destination(destination &&other) noexcept
172 {
173 *this = std::move(other);
174 }
175
176 /**
177 \returns the type of the destination
178 */
type() const179 destination::type_enum destination::type() const
180 {
181 return d->type;
182 }
183
184 /**
185 \note It is necessary not to destruct parent poppler::document
186 before calling this function for the first time.
187
188 \returns the page number of the destination
189 */
page_number() const190 int destination::page_number() const
191 {
192 if (d->page_number_unresolved) {
193 d->page_number_unresolved = false;
194 d->page_number = d->pdf_doc->findPage(d->page_ref);
195 }
196
197 return d->page_number;
198 }
199
200 /**
201 \returns the left coordinate of the destination
202 */
left() const203 double destination::left() const
204 {
205 return d->left;
206 }
207
208 /**
209 \returns the bottom coordinate of the destination
210 */
bottom() const211 double destination::bottom() const
212 {
213 return d->bottom;
214 }
215
216 /**
217 \returns the right coordinate of the destination
218 */
right() const219 double destination::right() const
220 {
221 return d->right;
222 }
223
224 /**
225 \returns the top coordinate of the destination
226 */
top() const227 double destination::top() const
228 {
229 return d->top;
230 }
231
232 /**
233 \returns the scale factor of the destination
234 */
zoom() const235 double destination::zoom() const
236 {
237 return d->zoom;
238 }
239
240 /**
241 \returns whether left coordinate should be changed
242 */
is_change_left() const243 bool destination::is_change_left() const
244 {
245 return d->change_left;
246 }
247
248 /**
249 \returns whether top coordinate should be changed
250 */
is_change_top() const251 bool destination::is_change_top() const
252 {
253 return d->change_top;
254 }
255
256 /**
257 \returns whether scale factor should be changed
258 */
is_change_zoom() const259 bool destination::is_change_zoom() const
260 {
261 return d->change_zoom;
262 }
263
264 /**
265 Move assignment operator.
266 */
operator =(destination && other)267 destination &destination::operator=(destination &&other) noexcept
268 {
269 if (this != &other) {
270 d = other.d;
271 other.d = nullptr;
272 }
273
274 return *this;
275 }
276
277 /**
278 Destructor.
279 */
~destination()280 destination::~destination()
281 {
282 delete d;
283 }
284