1//
2// Page.cpp
3//
4// Library: PDF
5// Package: PDFCore
6// Module: Page
7//
8// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/PDF/Page.h"
16#include "Poco/PDF/Document.h"
17#include "Poco/PDF/PDFException.h"
18#undef min
19#undef max
20#include <limits>
21
22
23namespace Poco {
24namespace PDF {
25
26
27Page::Page(Document* pDocument,
28 const HPDF_Page& page,
29 Size pageSize,
30 Orientation orientation):
31 _pDocument(pDocument),
32 _page(page),
33 _size(pageSize),
34 _orientation(orientation),
35 _pCurrentFont(0)
36{
37}
38
39
40Page::Page(const Page& other):
41 _pDocument(other._pDocument),
42 _page(other._page),
43 _size(other._size),
44 _orientation(other._orientation),
45 _pCurrentFont(other._pCurrentFont ? new Font(*other._pCurrentFont) : (Font*)0)
46{
47}
48
49
50Page::~Page()
51{
52}
53
54
55Page& Page::operator = (const Page& page)
56{
57 Page tmp(page);
58 swap(tmp);
59 return *this;
60}
61
62
63bool Page::operator == (const Page& other) const
64{
65 return &_pDocument->handle() == &other._pDocument->handle() && _page == other._page;
66}
67
68
69void Page::swap(Page& other)
70{
71 using std::swap;
72
73 swap(_pDocument, other._pDocument);
74 swap(_page, other._page);
75 swap(_size, other._size);
76 swap(_orientation, other._orientation);
77 swap(_pCurrentFont, other._pCurrentFont);
78}
79
80
81void Page::writeOnce(float xPos, float yPos, const std::string& text)
82{
83 beginText();
84 write(xPos, yPos, text);
85 endText();
86}
87
88
89int Page::writeOnceInRectangle(float left,
90 float top,
91 float right,
92 float bottom,
93 const std::string& text,
94 TextAlignment align)
95{
96 beginText();
97 int ret = writeInRectangle(left, top, right, bottom, text, align);
98 endText();
99 return ret;
100}
101
102
103float Page::textWidth(const std::string& text)
104{
105 return HPDF_Page_TextWidth(_page, text.c_str());
106}
107
108
109void Page::setFont(const std::string& name, float size, const std::string& encoding)
110{
111 setFont(_pDocument->font(name, encoding), size);
112}
113
114
115void Page::setTTFont(const std::string& name, float size, const std::string& encoding, bool embed)
116{
117 setFont(_pDocument->font(_pDocument->loadTTFont(name, embed), encoding), size);
118}
119
120
121const Font& Page::getFont() const
122{
123 delete _pCurrentFont;
124 return *(_pCurrentFont = new Font(&_pDocument->handle(), HPDF_Page_GetCurrentFont(_page)));
125}
126
127
128void Page::setRotation(int angle)
129{
130 if (0 != angle % 90 || angle > std::numeric_limits<HPDF_UINT16>::max())
131 throw InvalidArgumentException("Invalid angle value.");
132
133 HPDF_Page_SetRotate(_page, static_cast<HPDF_UINT16>(angle));
134}
135
136
137const Destination& Page::createDestination(const std::string& name)
138{
139 DestinationContainer::iterator it = _destinations.find(name);
140 if (_destinations.end() != it)
141 throw InvalidArgumentException("Destination already exists.");
142
143 Destination dest(&_pDocument->handle(), HPDF_Page_CreateDestination(_page), name);
144 std::pair<DestinationContainer::iterator, bool> ret =
145 _destinations.insert(DestinationContainer::value_type(name, dest));
146
147 if (ret.second) return ret.first->second;
148
149 throw IllegalStateException("Could not create destination.");
150}
151
152
153const TextAnnotation& Page::createTextAnnotation(const std::string& name,
154 const Rectangle& rect,
155 const std::string& text,
156 const Encoder& encoder)
157{
158 TextAnnotationContainer::iterator it = _textAnnotations.find(name);
159 if (_textAnnotations.end() != it)
160 throw InvalidArgumentException("Annotation already exists.");
161
162 TextAnnotation ann(&_pDocument->handle(),
163 HPDF_Page_CreateTextAnnot(_page, rect, text.c_str(), encoder),
164 name);
165
166 std::pair<TextAnnotationContainer::iterator, bool> ret =
167 _textAnnotations.insert(TextAnnotationContainer::value_type(name, ann));
168
169 if (ret.second) return ret.first->second;
170
171 throw IllegalStateException("Could not create annotation.");
172}
173
174
175const LinkAnnotation& Page::createLinkAnnotation(const std::string& name,
176 const Rectangle& rect,
177 const Destination& dest)
178{
179 LinkAnnotationContainer::iterator it = _linkAnnotations.find(name);
180 if (_linkAnnotations.end() != it)
181 throw InvalidArgumentException("Annotation already exists.");
182
183 LinkAnnotation ann(&_pDocument->handle(),
184 HPDF_Page_CreateLinkAnnot(_page, rect, dest),
185 name);
186 std::pair<LinkAnnotationContainer::iterator, bool> ret =
187 _linkAnnotations.insert(LinkAnnotationContainer::value_type(name, ann));
188
189 if (ret.second) return ret.first->second;
190
191 throw IllegalStateException("Could not create annotation.");
192}
193
194
195const LinkAnnotation& Page::createURILinkAnnotation(const std::string& name,
196 const Rectangle& rect,
197 const std::string& uri)
198{
199 LinkAnnotationContainer::iterator it = _linkAnnotations.find(name);
200 if (_linkAnnotations.end() != it)
201 throw InvalidArgumentException("Annotation already exists.");
202
203 LinkAnnotation ann(&_pDocument->handle(),
204 HPDF_Page_CreateURILinkAnnot(_page, rect, uri.c_str()),
205 name);
206 std::pair<LinkAnnotationContainer::iterator, bool> ret =
207 _linkAnnotations.insert(LinkAnnotationContainer::value_type(name, ann));
208
209 if (ret.second) return ret.first->second;
210
211 throw IllegalStateException("Could not create annotation.");
212}
213
214
215} } // namespace Poco::PDF
216