libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNPDF.cpp
Go to the documentation of this file.
1 /* Copyright 2011 CoReNum
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn 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 Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNPDF.cpp
19  * \author Yann LEYDIER
20  */
21 
22 #include <CRN.h>
23 #ifdef CRN_USING_HARU
24 
25 #include <CRNException.h>
26 #include <CRNUtils/CRNPDF.h>
27 #include <CRNIO/CRNPath.h>
28 #include <CRNGeometry/CRNRect.h>
29 #include <hpdf_error.h>
30 #include <hpdf.h>
31 
32 using namespace crn;
33 
34 static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *user_data)
35 {
36  switch (error_no)
37  {
38  case HPDF_ARRAY_COUNT_ERR :
39  throw ExceptionRuntime("Internal error. Data consistency was lost.");
40  case HPDF_ARRAY_ITEM_NOT_FOUND :
41  throw ExceptionRuntime("Internal error. Data consistency was lost.");
42  case HPDF_ARRAY_ITEM_UNEXPECTED_TYPE :
43  throw ExceptionRuntime("Internal error. Data consistency was lost.");
44  case HPDF_BINARY_LENGTH_ERR :
45  throw ExceptionRuntime("Data length > HPDF_LIMIT_MAX_STRING_LEN.");
46  case HPDF_CANNOT_GET_PALLET :
47  throw ExceptionRuntime("Cannot get pallet data from PNG image.");
48  case HPDF_DICT_COUNT_ERR :
49  throw ExceptionRuntime("Dictionary elements > HPDF_LIMIT_MAX_DICT_ELEMENT");
50  case HPDF_DICT_ITEM_NOT_FOUND :
51  throw ExceptionRuntime("Internal error. Data consistency was lost.");
52  case HPDF_DICT_ITEM_UNEXPECTED_TYPE :
53  throw ExceptionRuntime("Internal error. Data consistency was lost.");
54  case HPDF_DICT_STREAM_LENGTH_NOT_FOUND :
55  throw ExceptionRuntime("Internal error. Data consistency was lost.");
56  case HPDF_DOC_ENCRYPTDICT_NOT_FOUND :
57  throw ExceptionRuntime("HPDF_SetEncryptMode() or HPDF_SetPermission() called before password set.");
58  case HPDF_DOC_INVALID_OBJECT :
59  throw ExceptionRuntime("Internal error. Data consistency was lost.");
60  case HPDF_DUPLICATE_REGISTRATION :
61  throw ExceptionRuntime("Tried to re-register a registered font.");
62  case HPDF_EXCEED_JWW_CODE_NUM_LIMIT :
63  throw ExceptionRuntime("Cannot register a character to the Japanese word wrap characters list.");
64  case HPDF_ENCRYPT_INVALID_PASSWORD :
65  throw ExceptionRuntime("1. Tried to set the owner password to NULL. 2. Owner and user password are the same.");
66  case HPDF_ERR_UNKNOWN_CLASS :
67  throw ExceptionRuntime("Internal error. Data consistency was lost.");
68  case HPDF_EXCEED_GSTATE_LIMIT :
69  throw ExceptionRuntime("Stack depth > HPDF_LIMIT_MAX_GSTATE.");
70  case HPDF_FAILD_TO_ALLOC_MEM :
71  throw ExceptionRuntime("Memory allocation failed.");
72  case HPDF_FILE_IO_ERROR :
73  throw ExceptionRuntime("File processing failed. (Detailed code is set.)");
74  case HPDF_FILE_OPEN_ERROR :
75  throw ExceptionRuntime("Cannot open a file. (Detailed code is set.)");
76  case HPDF_FONT_EXISTS :
77  throw ExceptionRuntime("Tried to load a font that has been registered.");
78  case HPDF_FONT_INVALID_WIDTHS_TABLE :
79  throw ExceptionRuntime("1. Font-file format is invalid. 2. Internal error. Data consistency was lost.");
80  case HPDF_INVALID_AFM_HEADER :
81  throw ExceptionRuntime("Cannot recognize header of afm file.");
82  case HPDF_INVALID_ANNOTATION :
83  throw ExceptionRuntime("Specified annotation handle is invalid.");
84  case HPDF_INVALID_BIT_PER_COMPONENT :
85  throw ExceptionRuntime("Bit-per-component of a image which was set as mask-image is invalid.");
86  case HPDF_INVALID_CHAR_MATRICS_DATA :
87  throw ExceptionRuntime("Cannot recognize char-matrics-data of afm file.");
88  case HPDF_INVALID_COLOR_SPACE :
89  throw ExceptionRuntime("1. Invalid color_space parameter of HPDF_LoadRawImage. 2. Color-space of a image which was set as mask-image is invalid. 3. Invoked function invalid in present color-space.");
90  case HPDF_INVALID_COMPRESSION_MODE :
91  throw ExceptionRuntime("Invalid value set when invoking HPDF_SetCommpressionMode().");
92  case HPDF_INVALID_DATE_TIME :
93  throw ExceptionRuntime("An invalid date-time value was set.");
94  case HPDF_INVALID_DESTINATION :
95  throw ExceptionRuntime("An invalid destination handle was set.");
96  case HPDF_INVALID_DOCUMENT :
97  throw ExceptionRuntime("An invalid document handle was set.");
98  case HPDF_INVALID_DOCUMENT_STATE :
99  throw ExceptionRuntime("Function invalid in the present state was invoked.");
100  case HPDF_INVALID_ENCODER :
101  throw ExceptionRuntime("An invalid encoder handle was set.");
102  case HPDF_INVALID_ENCODER_TYPE :
103  throw ExceptionRuntime("Combination between font and encoder is wrong.");
104  case HPDF_INVALID_ENCODING_NAME :
105  throw ExceptionRuntime("An Invalid encoding name is specified.");
106  case HPDF_INVALID_ENCRYPT_KEY_LEN :
107  throw ExceptionRuntime("Encryption key length is invalid.");
108  case HPDF_INVALID_FONTDEF_DATA :
109  throw ExceptionRuntime("1. An invalid font handle was set. 2. Unsupported font format.");
110  case HPDF_INVALID_FONTDEF_TYPE :
111  throw ExceptionRuntime("Internal error. Data consistency was lost.");
112  case HPDF_INVALID_FONT_NAME :
113  throw ExceptionRuntime("Font with the specified name is not found.");
114  case HPDF_INVALID_IMAGE :
115  throw ExceptionRuntime("Unsupported image format.");
116  case HPDF_INVALID_JPEG_DATA :
117  throw ExceptionRuntime("Unsupported image format.");
118  case HPDF_INVALID_N_DATA :
119  throw ExceptionRuntime("Cannot read a postscript-name from an afm file.");
120  case HPDF_INVALID_OBJECT :
121  throw ExceptionRuntime("1. An invalid object is set. 2. Internal error. Data consistency was lost.");
122  case HPDF_INVALID_OBJ_ID :
123  throw ExceptionRuntime("Internal error. Data consistency was lost.");
124  case HPDF_INVALID_OPERATION :
125  throw ExceptionRuntime("Invoked HPDF_Image_SetColorMask() against the image-object which was set a mask-image.");
126  case HPDF_INVALID_OUTLINE :
127  throw ExceptionRuntime("An invalid outline-handle was specified.");
128  case HPDF_INVALID_PAGE :
129  throw ExceptionRuntime("An invalid page-handle was specified.");
130  case HPDF_INVALID_PAGES :
131  throw ExceptionRuntime("An invalid pages-handle was specified. (internal error)");
132  case HPDF_INVALID_PARAMETER :
133  throw ExceptionRuntime("An invalid value is set.");
134  case HPDF_INVALID_PNG_IMAGE :
135  throw ExceptionRuntime("Invalid PNG image format.");
136  case HPDF_INVALID_STREAM :
137  throw ExceptionRuntime("Internal error. Data consistency was lost.");
138  case HPDF_MISSING_FILE_NAME_ENTRY :
139  throw ExceptionRuntime("Internal error. _FILE_NAME entry for delayed loading is missing.");
140  case HPDF_INVALID_TTC_FILE :
141  throw ExceptionRuntime("Invalid .TTC file format.");
142  case HPDF_INVALID_TTC_INDEX :
143  throw ExceptionRuntime("Index parameter > number of included fonts.");
144  case HPDF_INVALID_WX_DATA :
145  throw ExceptionRuntime("Cannot read a width-data from an afm file.");
146  case HPDF_ITEM_NOT_FOUND :
147  throw ExceptionRuntime("Internal error. Data consistency was lost.");
148  case HPDF_LIBPNG_ERROR :
149  throw ExceptionRuntime("Error returned from PNGLIB while loading image.");
150  case HPDF_NAME_INVALID_VALUE :
151  throw ExceptionRuntime("Internal error. Data consistency was lost.");
152  case HPDF_NAME_OUT_OF_RANGE :
153  throw ExceptionRuntime("Internal error. Data consistency was lost.");
154  case HPDF_PAGES_MISSING_KIDS_ENTRY :
155  throw ExceptionRuntime("Internal error. Data consistency was lost.");
156  case HPDF_PAGE_CANNOT_FIND_OBJECT :
157  throw ExceptionRuntime("Internal error. Data consistency was lost.");
158  case HPDF_PAGE_CANNOT_GET_ROOT_PAGES :
159  throw ExceptionRuntime("Internal error. Data consistency was lost.");
160  case HPDF_PAGE_CANNOT_RESTORE_GSTATE :
161  throw ExceptionRuntime("There are no graphics-states to be restored.");
162  case HPDF_PAGE_CANNOT_SET_PARENT :
163  throw ExceptionRuntime("Internal error. Data consistency was lost.");
164  case HPDF_PAGE_FONT_NOT_FOUND :
165  throw ExceptionRuntime("The current font is not set.");
166  case HPDF_PAGE_INVALID_FONT :
167  throw ExceptionRuntime("An invalid font-handle was specified.");
168  case HPDF_PAGE_INVALID_FONT_SIZE :
169  throw ExceptionRuntime("An invalid font-size was set.");
170  case HPDF_PAGE_INVALID_GMODE :
171  throw ExceptionRuntime("See Graphics mode.");
172  case HPDF_PAGE_INVALID_INDEX :
173  throw ExceptionRuntime("Internal error. Data consistency was lost.");
174  case HPDF_PAGE_INVALID_ROTATE_VALUE :
175  throw ExceptionRuntime("Specified value is not multiple of 90.");
176  case HPDF_PAGE_INVALID_SIZE :
177  throw ExceptionRuntime("An invalid page-size was set.");
178  case HPDF_PAGE_INVALID_XOBJECT :
179  throw ExceptionRuntime("An invalid image-handle was set.");
180  case HPDF_PAGE_OUT_OF_RANGE :
181  throw ExceptionRuntime("The specified value is out of range.");
182  case HPDF_REAL_OUT_OF_RANGE :
183  throw ExceptionRuntime("The specified value is out of range.");
184  case HPDF_STREAM_EOF :
185  throw ExceptionRuntime("Unexpected EOF marker was detected.");
186  case HPDF_STREAM_READLN_CONTINUE :
187  throw ExceptionRuntime("Internal error. Data consistency was lost.");
188  case HPDF_STRING_OUT_OF_RANGE :
189  throw ExceptionRuntime("The length of the text is too long.");
190  case HPDF_THIS_FUNC_WAS_SKIPPED :
191  throw ExceptionRuntime("Function not executed because of other errors.");
192  case HPDF_TTF_CANNOT_EMBEDDING_FONT :
193  throw ExceptionRuntime("Font cannot be embedded. (license restriction)");
194  case HPDF_TTF_INVALID_CMAP :
195  throw ExceptionRuntime("Unsupported ttf format. (cannot find unicode cmap)");
196  case HPDF_TTF_INVALID_FOMAT :
197  throw ExceptionRuntime("Unsupported ttf format.");
198  case HPDF_TTF_MISSING_TABLE :
199  throw ExceptionRuntime("Unsupported ttf format. (cannot find a necessary table)");
200  case HPDF_UNSUPPORTED_FONT_TYPE :
201  throw ExceptionRuntime("Internal error. Data consistency was lost.");
202  case HPDF_UNSUPPORTED_FUNC :
203  throw ExceptionRuntime("1. Library not configured to use PNGLIB. 2. Internal error. Data consistency was lost.");
204  case HPDF_UNSUPPORTED_JPEG_FORMAT :
205  throw ExceptionRuntime("Unsupported JPEG format.");
206  case HPDF_UNSUPPORTED_TYPE1_FONT :
207  throw ExceptionRuntime("Failed to parse .PFB file.");
208  case HPDF_XREF_COUNT_ERR :
209  throw ExceptionRuntime("Internal error. Data consistency was lost.");
210  case HPDF_ZLIB_ERROR :
211  throw ExceptionRuntime("Error while executing ZLIB function.");
212  case HPDF_INVALID_PAGE_INDEX :
213  throw ExceptionRuntime("An invalid page index was passed.");
214  case HPDF_INVALID_URI :
215  throw ExceptionRuntime("An invalid URI was set.");
216  /*
217  case HPDF_PAGELAYOUT_OUT_OF_RANGE :
218  throw ExceptionRuntime("An invalid page-layout was set.");
219  case HPDF_PAGEMODE_OUT_OF_RANGE :
220  throw ExceptionRuntime("An invalid page-mode was set.");
221  case HPDF_PAGENUM_STYLE_OUT_OF_RANGE :
222  throw ExceptionRuntime("An invalid page-num-style was set.");
223  */
224  case HPDF_ANNOT_INVALID_ICON :
225  throw ExceptionRuntime("An invalid icon was set.");
226  case HPDF_ANNOT_INVALID_BORDER_STYLE :
227  throw ExceptionRuntime("An invalid border-style was set.");
228  case HPDF_PAGE_INVALID_DIRECTION :
229  throw ExceptionRuntime("An invalid page-direction was set.");
230  case HPDF_INVALID_FONT :
231  throw ExceptionRuntime("An invalid font-handle was specified.");
232  }
233 }
234 
235 using namespace crn::PDF;
236 
240 Doc::Doc():
241  doc(HPDF_New(error_handler, NULL)),
242  has_pass(false)
243 {
244  HPDF_SetCompressionMode(HPDF_Doc(doc), HPDF_COMP_ALL);
245  SetCreator("libcrn");
246 }
247 
252 Doc::Doc(const Attributes &attr):
253  doc(HPDF_New(error_handler, NULL)),
254  has_pass(false)
255 {
256  HPDF_SetCompressionMode(HPDF_Doc(doc), HPDF_COMP_ALL);
257  SetAttributes(attr);
258 }
259 
261 Doc::~Doc()
262 {
263  HPDF_Free(HPDF_Doc(doc));
264  doc = nullptr;
265 }
266 
271 void Doc::Save(const Path &file_name)
272 {
273  HPDF_SaveToFile(HPDF_Doc(doc), file_name.CStr());
274 }
275 
280 void Doc::SetPageLayout(Attributes::Layout layout)
281 {
282  switch (layout)
283  {
284  case Attributes::Layout::ONE_PAGE:
285  HPDF_SetPageLayout(HPDF_Doc(doc), HPDF_PAGE_LAYOUT_SINGLE);
286  break;
287  case Attributes::Layout::CONTINUOUS:
288  HPDF_SetPageLayout(HPDF_Doc(doc), HPDF_PAGE_LAYOUT_ONE_COLUMN);
289  break;
290  case Attributes::Layout::OPEN_LEFT:
291  HPDF_SetPageLayout(HPDF_Doc(doc), HPDF_PAGE_LAYOUT_TWO_COLUMN_LEFT);
292  break;
293  case Attributes::Layout::OPEN_RIGHT:
294  HPDF_SetPageLayout(HPDF_Doc(doc), HPDF_PAGE_LAYOUT_TWO_COLUMN_RIGHT);
295  break;
296  }
297 }
298 
302 Attributes::Layout Doc::GetPageLayout() const
303 {
304  HPDF_PageLayout l = HPDF_GetPageLayout(HPDF_Doc(doc));
305  switch (l)
306  {
307  case HPDF_PAGE_LAYOUT_SINGLE:
308  return Attributes::Layout::ONE_PAGE;
309  case HPDF_PAGE_LAYOUT_ONE_COLUMN:
310  return Attributes::Layout::CONTINUOUS;
311  case HPDF_PAGE_LAYOUT_TWO_COLUMN_LEFT:
312  return Attributes::Layout::OPEN_LEFT;
313  default:
314  return Attributes::Layout::OPEN_RIGHT;
315  }
316 }
317 
322 Page Doc::GetCurrentPage()
323 {
324  return Page(HPDF_GetCurrentPage(HPDF_Doc(doc)));
325 }
326 
331 Page Doc::AddPage()
332 {
333  return Page(HPDF_AddPage(HPDF_Doc(doc)));
334 }
335 
341 Page Doc::InsertPage(const Page& target)
342 {
343  return Page(HPDF_InsertPage(HPDF_Doc(doc), HPDF_Page(target.page)));
344 }
345 
351 Image Doc::AddJPEG(const Path &fname)
352 {
353  return Image(HPDF_LoadJpegImageFromFile(HPDF_Doc(doc), fname.CStr()));
354 }
355 
362 Image Doc::AddPNG(const Path &fname, bool delay)
363 {
364  if (delay)
365  {
366  return Image(HPDF_LoadPngImageFromFile2(HPDF_Doc(doc), fname.CStr()));
367  }
368  else
369  {
370  return Image(HPDF_LoadPngImageFromFile(HPDF_Doc(doc), fname.CStr()));
371  }
372 }
373 
378 void Doc::SetAuthor(const StringUTF8 &s)
379 {
380  HPDF_SetInfoAttr(HPDF_Doc(doc), HPDF_INFO_AUTHOR, s.CStr());
381 }
382 
387 void Doc::SetCreator(const StringUTF8 &s)
388 {
389  HPDF_SetInfoAttr(HPDF_Doc(doc), HPDF_INFO_CREATOR, s.CStr());
390 }
391 
396 void Doc::SetTitle(const StringUTF8 &s)
397 {
398  HPDF_SetInfoAttr(HPDF_Doc(doc), HPDF_INFO_TITLE, s.CStr());
399 }
400 
405 void Doc::SetSubject(const StringUTF8 &s)
406 {
407  HPDF_SetInfoAttr(HPDF_Doc(doc), HPDF_INFO_SUBJECT, s.CStr());
408 }
409 
414 void Doc::SetKeywords(const StringUTF8 &s)
415 {
416  HPDF_SetInfoAttr(HPDF_Doc(doc), HPDF_INFO_KEYWORDS, s.CStr());
417 }
418 
425 void Doc::SetPasswords(const StringUTF8 &admin, const StringUTF8 &user)
426 {
427  if (admin.IsEmpty())
428  throw ExceptionUninitialized("PDF admin password must not be empty.");
429  HPDF_SetPassword(HPDF_Doc(doc), admin.CStr(), user.CStr());
430  HPDF_SetEncryptionMode(HPDF_Doc(doc), HPDF_ENCRYPT_R3, 16);
431  has_pass = true;
432 }
433 
439 void Doc::SetPermissions(bool can_copy, bool can_print)
440 {
441  if (!has_pass)
442  throw ExceptionLogic("Cannot set permissions of a document that has no admin password.");
443  HPDF_UINT perm = HPDF_ENABLE_READ|HPDF_ENABLE_EDIT_ALL|HPDF_ENABLE_EDIT;
444  if (can_copy)
445  perm |= HPDF_ENABLE_COPY;
446  if (can_print)
447  perm |= HPDF_ENABLE_PRINT;
448  HPDF_SetPermission(HPDF_Doc(doc), perm);
449 }
450 
455 void Doc::SetAttributes(const Attributes &attr)
456 {
457  SetPageLayout(attr.layout);
458  SetAuthor(attr.author);
459  SetCreator(attr.creator);
460  SetTitle(attr.title);
461  SetSubject(attr.subject);
462  SetKeywords(attr.keywords);
463  if (attr.owner_password.IsNotEmpty())
464  {
465  SetPasswords(attr.owner_password, attr.user_password);
466  SetPermissions(attr.copyable, attr.printable);
467  }
468 }
469 
473 PDF::Image::Image(void *obj):
474  img(obj)
475 {
476 }
477 
482 size_t PDF::Image::GetWidth() const
483 {
484  return HPDF_Image_GetWidth(HPDF_Image(img));
485 }
486 
491 size_t PDF::Image::GetHeight() const
492 {
493  return HPDF_Image_GetHeight(HPDF_Image(img));
494 }
495 
499 Page::Page(void *obj):
500  page(obj)
501 {
502 }
503 
505 double Page::GetWidth()
506 {
507  return HPDF_Page_GetWidth(HPDF_Page(page));
508 }
509 
511 double Page::GetHeight()
512 {
513  return HPDF_Page_GetHeight(HPDF_Page(page));
514 }
515 
520 void Page::SetWidth(double w)
521 {
522  HPDF_Page_SetWidth(HPDF_Page(page), HPDF_REAL(w));
523 }
524 
529 void Page::SetHeight(double h)
530 {
531  HPDF_Page_SetHeight(HPDF_Page(page), HPDF_REAL(h));
532 }
533 
538 void Page::SetPenColor(const crn::pixel::RGB8 &color)
539 {
540  HPDF_Page_SetRGBStroke(HPDF_Page(page), HPDF_REAL(color.r / 255.0), HPDF_REAL(color.g / 255.0), HPDF_REAL(color.b / 255.0));
541 }
542 
547 void Page::SetFillColor(const crn::pixel::RGB8 &color)
548 {
549  HPDF_Page_SetRGBFill(HPDF_Page(page), HPDF_REAL(color.r / 255.0), HPDF_REAL(color.g / 255.0), HPDF_REAL(color.b / 255.0));
550 }
551 
558 void Page::DrawImage(Image &img, const Rect &bbox)
559 {
560  HPDF_Page_DrawImage(HPDF_Page(page), HPDF_Image(img.img), HPDF_REAL(bbox.GetLeft()), HPDF_REAL(GetHeight()) - HPDF_REAL(bbox.GetBottom()), HPDF_REAL(bbox.GetWidth()), HPDF_REAL(bbox.GetHeight()));
561 }
562 
565 void Page::DrawLine(double x1, double y1, double x2, double y2)
566 {
567  HPDF_Page_MoveTo(HPDF_Page(page), HPDF_REAL(x1), HPDF_REAL(GetHeight() - y1));
568  HPDF_Page_LineTo(HPDF_Page(page), HPDF_REAL(x2), HPDF_REAL(GetHeight() - y2));
569  HPDF_Page_Stroke(HPDF_Page(page));
570 }
571 
577 void Page::DrawRect(const Rect &rect, bool fill)
578 {
579  HPDF_Page_Rectangle(HPDF_Page(page), HPDF_REAL(rect.GetLeft()), HPDF_REAL(GetHeight() - rect.GetBottom()), HPDF_REAL(rect.GetWidth()), HPDF_REAL(rect.GetHeight()));
580  if (fill)
581  HPDF_Page_FillStroke(HPDF_Page(page));
582  else
583  HPDF_Page_Stroke(HPDF_Page(page));
584 }
585 
586 #endif // CRN_USING_HARU
Abstract class for images.
Definition: CRNImage.h:141
A generic runtime error.
Definition: CRNException.h:131
int GetBottom() const
Returns the bottommost coordinate.
Definition: CRNRect.h:111
Unintialized object error.
Definition: CRNException.h:155
bool IsNotEmpty() const noexcept
Checks if the string is not empty.
int GetLeft() const
Returns the leftmost coordinate.
Definition: CRNRect.h:99
A generic logic error.
Definition: CRNException.h:71
#define false
Definition: ConvertUTF.cpp:56
const char * CStr() const noexcept
Conversion to UTF8 cstring.
bool IsEmpty() const noexcept
Checks if the string is empty.
A convenience class for file paths.
Definition: CRNPath.h:39
int GetHeight() const
Returns the height of the rectangle.
Definition: CRNRect.h:119
int GetWidth() const
Returns the width of the rectangle.
Definition: CRNRect.h:115
Attributes to create a PDF export of a document.
A character string class.
Definition: CRNStringUTF8.h:49
A rectangle class.
Definition: CRNRect.h:46