62 return mm * 72.0f / 25.4f;
72inline constexpr std::uint32_t
PDF_RGB(
unsigned int r,
unsigned int g,
unsigned int b) {
73 return (((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu));
76inline constexpr std::uint32_t
PDF_ARGB(
unsigned int a,
unsigned int r,
unsigned int g,
unsigned int b) {
77 return (((a & 0xffu) << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu));
87inline constexpr float PDF_RGB_R(std::uint32_t colour) {
88 return static_cast<float>((colour >> 16) & 0xffu) / 255.0f;
91inline constexpr float PDF_RGB_G(std::uint32_t colour) {
92 return static_cast<float>((colour >> 8) & 0xffu) / 255.0f;
95inline constexpr float PDF_RGB_B(std::uint32_t colour) {
96 return static_cast<float>(colour & 0xffu) / 255.0f;
100 return (colour >> 24) == 0xffu;
125 "Helvetica-BoldOblique",
129 "Courier-BoldOblique",
142 std::vector<pdf_object*> children;
143 std::vector<pdf_object*> ext_gstates;
152struct ext_gstate_data {
153 float fill_alpha = 1.0f;
154 float stroke_alpha = 1.0f;
158 const std::size_t size = std::min(left.size(), right.size());
159 for (std::size_t i = 0; i < size; ++i) {
160 const unsigned char a =
static_cast<unsigned char>(left[i]);
161 const unsigned char b =
static_cast<unsigned char>(right[i]);
162 const int lower_a = (a >=
'A' && a <=
'Z') ? (a -
'A' +
'a') : a;
163 const int lower_b = (b >=
'A' && b <=
'Z') ? (b -
'A' +
'a') : b;
164 if (lower_a != lower_b) {
165 return lower_a - lower_b;
168 if (left.size() == right.size()) {
171 return left.size() < right.size() ? -1 : 1;
176 va_start(args, format);
179 const int required = std::vsnprintf(
nullptr, 0, format, copy);
185 const std::size_t old_size = out.size();
186 out.resize(old_size +
static_cast<std::size_t
>(required) + 1);
187 std::vsnprintf(out.data() + old_size,
static_cast<std::size_t
>(required) + 1, format, args);
188 out.resize(old_size +
static_cast<std::size_t
>(required));
194 for (
const char character : value) {
195 if (character ==
'(' || character ==
')' || character ==
'\\') {
198 out.push_back(character);
204 std::time_t now = std::time(
nullptr);
207 const std::tm* tmp = std::localtime(&now);
208 if (tmp !=
nullptr) {
212 localtime_r(&now, &tm);
215 std::strftime(buffer,
sizeof(buffer),
"%Y%m%d%H%M%SZ", &tm);
237 std::vector<std::unique_ptr<pdf_object>>
objects;
246 if (doc ==
nullptr) {
250 va_start(args, buffer);
251 const int len = std::vsnprintf(doc->
errstr,
sizeof(doc->
errstr), buffer, args);
263 if (pdf ==
nullptr || pdf->
errstr[0] ==
'\0') {
266 if (errval !=
nullptr) {
273 if (pdf ==
nullptr) {
281 if (pdf ==
nullptr || index < 0 ||
static_cast<std::size_t
>(index) >= pdf->
objects.size()) {
284 return pdf->
objects[
static_cast<std::size_t
>(index)].get();
288 return pdf ==
nullptr ? nullptr : pdf->
first_objects[
static_cast<std::size_t
>(type)];
292 return pdf ==
nullptr ? nullptr : pdf->
last_objects[
static_cast<std::size_t
>(type)];
296 if (pdf ==
nullptr ||
object ==
nullptr) {
299 object->index =
static_cast<int>(pdf->
objects.size());
301 object->prev = pdf->
last_objects[
static_cast<std::size_t
>(
object->type)];
302 object->prev->next = object;
304 pdf->
last_objects[
static_cast<std::size_t
>(
object->type)] =
object;
306 pdf->
first_objects[
static_cast<std::size_t
>(
object->type)] =
object;
312 if (pdf ==
nullptr) {
315 std::unique_ptr<pdf_object>
object = std::make_unique<pdf_object>();
321 pdf->
objects.push_back(std::move(
object));
326 return pdf ==
nullptr ? 0.0f : pdf->
width;
330 return pdf ==
nullptr ? 0.0f : pdf->
height;
334 return page ==
nullptr ? 0.0f : page->
page.width;
338 return page ==
nullptr ? 0.0f : page->
page.height;
342 if (pdf ==
nullptr || font ==
nullptr) {
346 const char* canonical =
nullptr;
349 canonical = candidate;
353 if (canonical ==
nullptr) {
354 return pdf_set_err(pdf, -EINVAL,
"Invalid font name '%s'", font);
359 last_index = std::max(last_index, object->font.index);
360 if (std::strcmp(object->font.name, canonical) == 0) {
367 if (
object ==
nullptr) {
368 return pdf_set_err(pdf, -ENOMEM,
"Unable to allocate PDF font");
371 std::snprintf(object->
font.name,
sizeof(object->
font.name),
"%s", canonical);
372 object->font.name[
sizeof(
object->font.name) - 1] =
'\0';
373 object->font.index = last_index + 1;
379 std::unique_ptr<pdf_doc> pdf = std::make_unique<pdf_doc>();
381 pdf->height = height;
386 if (info_object ==
nullptr) {
389 if (info !=
nullptr) {
390 info_object->
info = *info;
398 if (info_object->
info.
date[0] ==
'\0') {
400 std::snprintf(info_object->
info.
date,
sizeof(info_object->
info.
date),
"%s", date.c_str());
413 return pdf.release();
422 if (page ==
nullptr) {
431 if (page_number <= 0) {
432 pdf_set_err(pdf, -EINVAL,
"page number must be >= 1");
436 if (page_number == 1) {
445 if (page ==
nullptr) {
449 return pdf_set_err(pdf, -EINVAL,
"Invalid PDF page");
451 page->
page.width = width;
452 page->
page.height = height;
457 if (page ==
nullptr) {
461 return pdf_set_err(pdf, -EINVAL,
"Invalid pdf page");
464 std::string trimmed = buffer;
465 while (!trimmed.empty() && (trimmed.back() ==
'\r' || trimmed.back() ==
'\n')) {
470 if (
object ==
nullptr) {
471 return pdf_set_err(pdf, -ENOMEM,
"Unable to allocate PDF stream");
473 object->stream.page = page;
474 object->
stream.stream = std::move(trimmed);
475 page->
page.children.push_back(
object);
481 escaped.reserve(value.size() + 4);
482 for (
const char character : value) {
483 if (character ==
'(' || character ==
')' || character ==
'\\') {
484 escaped.push_back(
'\\');
486 if (character ==
'\n' || character ==
'\r' || character ==
'\t' || character ==
'\b' || character ==
'\f') {
489 escaped.push_back(character);
495 if (text ==
nullptr || *text ==
'\0') {
499 return pdf_set_err(pdf, -EINVAL,
"No active font");
515 if (!std::isfinite(alpha)) {
518 return std::clamp(alpha, 0.0f, 1.0f);
522 return std::fabs(left - right) <= 0.000001f;
526 if (page ==
nullptr) {
530 return pdf_set_err(pdf, -EINVAL,
"Invalid pdf page");
535 for (std::size_t index = 0; index < page->
page.ext_gstates.size(); ++index) {
537 if (ext_gstate !=
nullptr &&
541 return static_cast<int>(index);
546 if (ext_gstate ==
nullptr) {
547 return pdf_set_err(pdf, -ENOMEM,
"Unable to allocate PDF ExtGState");
549 ext_gstate->
ext_gstate.fill_alpha = clamped_fill_alpha;
550 ext_gstate->
ext_gstate.stroke_alpha = clamped_stroke_alpha;
551 page->
page.ext_gstates.push_back(ext_gstate);
552 return static_cast<int>(page->
page.ext_gstates.size() - 1);
556 std::uint32_t colour,
const float pattern[],
int pattern_len,
float phase,
float stroke_alpha = 1.0f) {
557 if (pattern_len < 0 || (pattern_len > 0 && pattern ==
nullptr)) {
558 return pdf_set_err(pdf, -EINVAL,
"Invalid line pattern");
564 int ext_gstate_index = -1;
566 if (effective_stroke_alpha < 1.0f) {
568 if (ext_gstate_index < 0) {
569 return ext_gstate_index;
574 if (ext_gstate_index >= 0) {
577 if (pattern_len > 0) {
578 stream.push_back(
'[');
579 for (
int i = 0; i < pattern_len; ++i) {
588 if (ext_gstate_index >= 0) {
592 if (pattern_len > 0) {
593 stream +=
"[] 0 d\r\n";
595 if (ext_gstate_index >= 0) {
602 float stroke_alpha = 1.0f) {
603 return pdf_add_line_pattern(pdf, page, x1, y1, x2, y2, width, colour,
nullptr, 0, 0.0f, stroke_alpha);
607 float yq1,
float xq2,
float yq2,
float width, std::uint32_t colour,
float stroke_alpha = 1.0f) {
612 int ext_gstate_index = -1;
614 if (effective_stroke_alpha < 1.0f) {
616 if (ext_gstate_index < 0) {
617 return ext_gstate_index;
622 if (ext_gstate_index >= 0) {
629 if (ext_gstate_index >= 0) {
633 if (ext_gstate_index >= 0) {
640 float xq1,
float yq1,
float width, std::uint32_t colour,
float stroke_alpha = 1.0f) {
641 const float xc1 = x1 + (xq1 - x1) * (2.0f / 3.0f);
642 const float yc1 = y1 + (yq1 - y1) * (2.0f / 3.0f);
643 const float xc2 = x2 + (xq1 - x2) * (2.0f / 3.0f);
644 const float yc2 = y2 + (yq1 - y2) * (2.0f / 3.0f);
645 return pdf_add_cubic_bezier(pdf, page, x1, y1, x2, y2, xc1, yc1, xc2, yc2, width, colour, stroke_alpha);
649 int operation_count,
float stroke_width, std::uint32_t stroke_colour, std::uint32_t fill_colour,
650 float fill_alpha = 1.0f,
float stroke_alpha = 1.0f) {
651 if (operation_count < 0 || (operation_count > 0 && operations ==
nullptr)) {
652 return pdf_set_err(pdf, -EINVAL,
"Invalid path operations");
657 if (!has_fill && !has_stroke) {
661 int ext_gstate_index = -1;
662 const float effective_fill_alpha = has_fill ?
pdf_clamp_alpha(fill_alpha) : 1.0f;
663 const float effective_stroke_alpha = has_stroke ?
pdf_clamp_alpha(stroke_alpha) : 1.0f;
664 if (effective_fill_alpha < 1.0f || effective_stroke_alpha < 1.0f) {
666 if (ext_gstate_index < 0) {
667 return ext_gstate_index;
672 if (ext_gstate_index >= 0) {
682 for (
int i = 0; i < operation_count; ++i) {
684 switch (operation.
op) {
704 return pdf_set_err(pdf, -EINVAL,
"Invalid operation");
708 if (ext_gstate_index >= 0) {
711 if (has_fill && has_stroke) {
713 }
else if (has_fill) {
718 if (ext_gstate_index >= 0) {
726 std::uint32_t colour, std::uint32_t fill_colour,
float fill_alpha = 1.0f,
float stroke_alpha = 1.0f) {
727 const float lx = (4.0f / 3.0f) *
static_cast<float>(std::sqrt(2.0) - 1.0) * xradius;
728 const float ly = (4.0f / 3.0f) *
static_cast<float>(std::sqrt(2.0) - 1.0) * yradius;
730 std::array<pdf_path_operation, 5> operations{{
731 {
'm',
x + xradius,
y, 0.0f, 0.0f, 0.0f, 0.0f},
732 {
'c',
x + xradius,
y - ly,
x + lx,
y - yradius,
x,
y - yradius},
733 {
'c',
x - lx,
y - yradius,
x - xradius,
y - ly,
x - xradius,
y},
734 {
'c',
x - xradius,
y + ly,
x - lx,
y + yradius,
x,
y + yradius},
735 {
'c',
x + lx,
y + yradius,
x + xradius,
y + ly,
x + xradius,
y},
741 static_cast<int>(operations.size()),
751 std::uint32_t colour, std::uint32_t fill_colour,
float fill_alpha = 1.0f,
float stroke_alpha = 1.0f) {
752 return pdf_add_ellipse(pdf, page,
x,
y, radius, radius, width, colour, fill_colour, fill_alpha, stroke_alpha);
756 float border_width, std::uint32_t colour,
float stroke_alpha = 1.0f) {
761 int ext_gstate_index = -1;
763 if (effective_stroke_alpha < 1.0f) {
765 if (ext_gstate_index < 0) {
766 return ext_gstate_index;
771 if (ext_gstate_index >= 0) {
776 if (ext_gstate_index >= 0) {
780 if (ext_gstate_index >= 0) {
787 float border_width, std::uint32_t colour_fill, std::uint32_t colour_border,
float fill_alpha = 1.0f,
float stroke_alpha = 1.0f) {
790 if (!has_fill && !has_stroke) {
794 int ext_gstate_index = -1;
795 const float effective_fill_alpha = has_fill ?
pdf_clamp_alpha(fill_alpha) : 1.0f;
796 const float effective_stroke_alpha = has_stroke ?
pdf_clamp_alpha(stroke_alpha) : 1.0f;
797 if (effective_fill_alpha < 1.0f || effective_stroke_alpha < 1.0f) {
799 if (ext_gstate_index < 0) {
800 return ext_gstate_index;
805 if (ext_gstate_index >= 0) {
815 if (ext_gstate_index >= 0) {
818 stream += has_fill && has_stroke ?
"B\r\n" : (has_fill ?
"f\r\n" :
"S\r\n");
819 if (ext_gstate_index >= 0) {
826 float border_width, std::uint32_t colour,
float stroke_alpha = 1.0f) {
830 std::vector<pdf_path_operation> operations;
831 operations.reserve(
static_cast<std::size_t
>(count) + 1);
832 operations.push_back({
'm',
x[0],
y[0], 0.0f, 0.0f, 0.0f, 0.0f});
833 for (
int i = 1; i < count; ++i) {
834 operations.push_back({
'l',
x[i],
y[i], 0.0f, 0.0f, 0.0f, 0.0f});
836 operations.push_back({
'h', 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
841 static_cast<int>(operations.size()),
851 float border_width, std::uint32_t colour,
float fill_alpha = 1.0f,
float stroke_alpha = 1.0f) {
855 std::vector<pdf_path_operation> operations;
856 operations.reserve(
static_cast<std::size_t
>(count) + 1);
857 operations.push_back({
'm',
x[0],
y[0], 0.0f, 0.0f, 0.0f, 0.0f});
858 for (
int i = 1; i < count; ++i) {
859 operations.push_back({
'l',
x[i],
y[i], 0.0f, 0.0f, 0.0f, 0.0f});
861 operations.push_back({
'h', 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
866 static_cast<int>(operations.size()),
876 if (pdf ==
nullptr) {
882 const auto save_object = [&](
pdf_object& object) {
883 object.offset = out.size();
885 switch (
object.type) {
888 out +=
object.stream.stream;
889 out +=
"\r\nendstream\r\n";
893 if (
object.info.creator[0] !=
'\0') {
898 if (
object.info.producer[0] !=
'\0') {
899 out +=
" /Producer ";
903 if (
object.info.title[0] !=
'\0') {
908 if (
object.info.author[0] !=
'\0') {
913 if (
object.info.subject[0] !=
'\0') {
918 if (
object.info.date[0] !=
'\0') {
919 out +=
" /CreationDate (D:";
920 out +=
object.info.date;
927 out +=
"<<\r\n /Type /Page\r\n";
930 out +=
" /Resources <<\r\n /Font <<\r\n";
935 if (!
object.page.ext_gstates.empty()) {
936 out +=
" /ExtGState <<\r\n";
937 for (std::size_t index = 0; index <
object.page.ext_gstates.size(); ++index) {
943 out +=
" >>\r\n /Contents [\r\n";
944 for (
const pdf_object* child :
object.page.children) {
947 out +=
"]\r\n>>\r\n";
952 "<<\r\n /Type /ExtGState\r\n /ca %f\r\n /CA %f\r\n>>\r\n",
953 object.ext_gstate.fill_alpha,
954 object.ext_gstate.stroke_alpha);
958 "<<\r\n /Type /Font\r\n /Subtype /Type1\r\n /BaseFont /%s\r\n /Encoding /WinAnsiEncoding\r\n>>\r\n",
962 out +=
"<<\r\n /Type /Pages\r\n /Kids [ ";
974 out +=
"<<\r\n /Type /Catalog\r\n";
987 for (std::size_t index = 1; index < pdf->
objects.size(); ++index) {
989 if (
object !=
nullptr) {
990 save_object(*
object);
994 const std::size_t xref_offset = out.size();
996 out +=
"0000000000 65535 f\r\n";
997 for (std::size_t index = 1; index < pdf->
objects.size(); ++index) {
1004 out +=
"trailer\r\n<<\r\n";
1006 if (catalog !=
nullptr) {
1009 if (info !=
nullptr) {
1012 out +=
">>\r\nstartxref\r\n";
1018 if (fp ==
nullptr) {
1019 return pdf_set_err(pdf, -EINVAL,
"Invalid FILE pointer");
1026 if (!buffer.empty()) {
1027 const std::size_t written = std::fwrite(buffer.data(), 1, buffer.size(), fp);
1028 if (written != buffer.size()) {
1029 return pdf_set_err(pdf, -errno,
"Unable to write PDF bytes");
1036 if (filename ==
nullptr) {
1037 return pdf_set_err(pdf, -EINVAL,
"Invalid filename");
1039 std::ofstream output(filename, std::ios::binary);
1041 return pdf_set_err(pdf, -errno,
"Unable to open '%s'", filename);
1048 output.write(buffer.data(),
static_cast<std::streamsize
>(buffer.size()));
1050 return pdf_set_err(pdf, -errno,
"Unable to write '%s'", filename);
Definition pdfgen.hpp:103
std::string now_as_pdf_date()
Definition pdfgen.hpp:203
int ascii_casecmp(std::string_view left, std::string_view right)
Definition pdfgen.hpp:157
void append_escaped_string(std::string &out, std::string_view value)
Definition pdfgen.hpp:192
@ OBJ_pages
Definition pdfgen.hpp:113
@ OBJ_stream
Definition pdfgen.hpp:108
@ OBJ_none
Definition pdfgen.hpp:106
@ OBJ_ext_gstate
Definition pdfgen.hpp:111
@ OBJ_count
Definition pdfgen.hpp:114
@ OBJ_page
Definition pdfgen.hpp:110
@ OBJ_font
Definition pdfgen.hpp:109
@ OBJ_catalog
Definition pdfgen.hpp:112
@ OBJ_info
Definition pdfgen.hpp:107
constexpr std::array valid_fonts
Definition pdfgen.hpp:117
void append_format(std::string &out, const char *format,...)
Definition pdfgen.hpp:174
int pdf_add_rectangle(pdf_doc *pdf, pdf_object *page, float x, float y, float width, float height, float border_width, std::uint32_t colour, float stroke_alpha=1.0f)
Definition pdfgen.hpp:755
constexpr float PDF_A3_HEIGHT
Definition pdfgen.hpp:70
constexpr std::uint32_t PDF_TRANSPARENT
Definition pdfgen.hpp:85
constexpr std::uint32_t PDF_WHITE
Definition pdfgen.hpp:84
int pdf_save_buffer(pdf_doc *pdf, std::string &out)
Definition pdfgen.hpp:875
std::string pdf_escape_content_string(std::string_view value)
Definition pdfgen.hpp:479
constexpr std::uint32_t PDF_ARGB(unsigned int a, unsigned int r, unsigned int g, unsigned int b)
Definition pdfgen.hpp:76
int pdf_find_or_create_ext_gstate(pdf_doc *pdf, pdf_object *page, float fill_alpha, float stroke_alpha)
Definition pdfgen.hpp:525
int pdf_save(pdf_doc *pdf, const char *filename)
Definition pdfgen.hpp:1035
constexpr float PDF_MM_TO_POINT(float mm)
Definition pdfgen.hpp:61
pdf_doc * pdf_create(float width, float height, const pdf_info *info)
Definition pdfgen.hpp:378
constexpr float PDF_INCH_TO_POINT(float inch)
Definition pdfgen.hpp:57
int pdf_set_font(pdf_doc *pdf, const char *font)
Definition pdfgen.hpp:341
int pdf_add_text(pdf_doc *pdf, pdf_object *page, const char *text, float size, float xoff, float yoff, std::uint32_t colour)
Definition pdfgen.hpp:494
int pdf_page_set_size(pdf_doc *pdf, pdf_object *page, float width, float height)
Definition pdfgen.hpp:444
constexpr std::uint32_t PDF_RED
Definition pdfgen.hpp:80
constexpr std::uint32_t PDF_GREEN
Definition pdfgen.hpp:81
int pdf_append_object(pdf_doc *pdf, pdf_object *object)
Definition pdfgen.hpp:295
pdf_object * pdf_add_object(pdf_doc *pdf, int type)
Definition pdfgen.hpp:311
constexpr float PDF_RGB_R(std::uint32_t colour)
Definition pdfgen.hpp:87
float pdf_height(const pdf_doc *pdf)
Definition pdfgen.hpp:329
int pdf_add_ellipse(pdf_doc *pdf, pdf_object *page, float x, float y, float xradius, float yradius, float width, std::uint32_t colour, std::uint32_t fill_colour, float fill_alpha=1.0f, float stroke_alpha=1.0f)
Definition pdfgen.hpp:725
bool pdf_alpha_equal(float left, float right)
Definition pdfgen.hpp:521
constexpr std::uint32_t PDF_BLUE
Definition pdfgen.hpp:82
int pdf_add_filled_polygon(pdf_doc *pdf, pdf_object *page, const float x[], const float y[], int count, float border_width, std::uint32_t colour, float fill_alpha=1.0f, float stroke_alpha=1.0f)
Definition pdfgen.hpp:850
constexpr std::uint32_t PDF_BLACK
Definition pdfgen.hpp:83
int pdf_add_quadratic_bezier(pdf_doc *pdf, pdf_object *page, float x1, float y1, float x2, float y2, float xq1, float yq1, float width, std::uint32_t colour, float stroke_alpha=1.0f)
Definition pdfgen.hpp:639
pdf_object * pdf_get_page(pdf_doc *pdf, int page_number)
Definition pdfgen.hpp:430
pdf_object * pdf_get_object(const pdf_doc *pdf, int index)
Definition pdfgen.hpp:280
float pdf_width(const pdf_doc *pdf)
Definition pdfgen.hpp:325
constexpr std::uint32_t PDF_RGB(unsigned int r, unsigned int g, unsigned int b)
Definition pdfgen.hpp:72
std::string pdf_to_string(pdf_doc *pdf)
Definition pdfgen.hpp:1055
int pdf_add_polygon(pdf_doc *pdf, pdf_object *page, const float x[], const float y[], int count, float border_width, std::uint32_t colour, float stroke_alpha=1.0f)
Definition pdfgen.hpp:825
void pdf_clear_err(pdf_doc *pdf)
Definition pdfgen.hpp:272
constexpr float PDF_LETTER_WIDTH
Definition pdfgen.hpp:65
void pdf_destroy(pdf_doc *pdf)
Definition pdfgen.hpp:416
int pdf_add_circle(pdf_doc *pdf, pdf_object *page, float x, float y, float radius, float width, std::uint32_t colour, std::uint32_t fill_colour, float fill_alpha=1.0f, float stroke_alpha=1.0f)
Definition pdfgen.hpp:750
int pdf_add_cubic_bezier(pdf_doc *pdf, pdf_object *page, float x1, float y1, float x2, float y2, float xq1, float yq1, float xq2, float yq2, float width, std::uint32_t colour, float stroke_alpha=1.0f)
Definition pdfgen.hpp:606
int pdf_set_err(pdf_doc *doc, int errval, const char *buffer,...)
Definition pdfgen.hpp:245
pdf_object * pdf_find_first_object(const pdf_doc *pdf, int type)
Definition pdfgen.hpp:287
pdf_object * pdf_find_last_object(const pdf_doc *pdf, int type)
Definition pdfgen.hpp:291
int pdf_add_stream(pdf_doc *pdf, pdf_object *page, const std::string &buffer)
Definition pdfgen.hpp:456
const char * pdf_get_err(const pdf_doc *pdf, int *errval)
Definition pdfgen.hpp:262
float pdf_clamp_alpha(float alpha)
Definition pdfgen.hpp:514
float pdf_page_height(const pdf_object *page)
Definition pdfgen.hpp:337
constexpr bool PDF_IS_TRANSPARENT(std::uint32_t colour)
Definition pdfgen.hpp:99
int pdf_add_custom_path(pdf_doc *pdf, pdf_object *page, const pdf_path_operation *operations, int operation_count, float stroke_width, std::uint32_t stroke_colour, std::uint32_t fill_colour, float fill_alpha=1.0f, float stroke_alpha=1.0f)
Definition pdfgen.hpp:648
int pdf_add_filled_rectangle(pdf_doc *pdf, pdf_object *page, float x, float y, float width, float height, float border_width, std::uint32_t colour_fill, std::uint32_t colour_border, float fill_alpha=1.0f, float stroke_alpha=1.0f)
Definition pdfgen.hpp:786
pdf_object * pdf_append_page(pdf_doc *pdf)
Definition pdfgen.hpp:420
int pdf_add_line(pdf_doc *pdf, pdf_object *page, float x1, float y1, float x2, float y2, float width, std::uint32_t colour, float stroke_alpha=1.0f)
Definition pdfgen.hpp:601
constexpr float PDF_RGB_G(std::uint32_t colour)
Definition pdfgen.hpp:91
float pdf_page_width(const pdf_object *page)
Definition pdfgen.hpp:333
constexpr float PDF_A4_HEIGHT
Definition pdfgen.hpp:68
constexpr float PDF_A4_WIDTH
Definition pdfgen.hpp:67
int pdf_add_line_pattern(pdf_doc *pdf, pdf_object *page, float x1, float y1, float x2, float y2, float width, std::uint32_t colour, const float pattern[], int pattern_len, float phase, float stroke_alpha=1.0f)
Definition pdfgen.hpp:555
constexpr float PDF_A3_WIDTH
Definition pdfgen.hpp:69
int pdf_save_file(pdf_doc *pdf, FILE *fp)
Definition pdfgen.hpp:1017
constexpr float PDF_RGB_B(std::uint32_t colour)
Definition pdfgen.hpp:95
constexpr float PDF_LETTER_HEIGHT
Definition pdfgen.hpp:66
@ y
Definition intervaltree.hpp:24
@ x
Definition intervaltree.hpp:24
Definition pdfgen.hpp:234
std::array< pdf_object *, detail::OBJ_count > first_objects
Definition pdfgen.hpp:242
std::vector< std::unique_ptr< pdf_object > > objects
Definition pdfgen.hpp:237
char errstr[128]
Definition pdfgen.hpp:235
float height
Definition pdfgen.hpp:239
std::array< pdf_object *, detail::OBJ_count > last_objects
Definition pdfgen.hpp:241
int errval
Definition pdfgen.hpp:236
pdf_object * current_font
Definition pdfgen.hpp:240
float width
Definition pdfgen.hpp:238
char author[64]
Definition pdfgen.hpp:42
char subject[64]
Definition pdfgen.hpp:43
char creator[64]
Definition pdfgen.hpp:39
char title[64]
Definition pdfgen.hpp:41
char producer[64]
Definition pdfgen.hpp:40
char date[64]
Definition pdfgen.hpp:44
Definition pdfgen.hpp:221
detail::ext_gstate_data ext_gstate
Definition pdfgen.hpp:231
pdf_object * next
Definition pdfgen.hpp:226
std::size_t offset
Definition pdfgen.hpp:224
detail::page_data page
Definition pdfgen.hpp:229
pdf_object * prev
Definition pdfgen.hpp:225
pdf_info info
Definition pdfgen.hpp:227
detail::stream_data stream
Definition pdfgen.hpp:228
int index
Definition pdfgen.hpp:223
int type
Definition pdfgen.hpp:222
detail::font_data font
Definition pdfgen.hpp:230
float x2
Definition pdfgen.hpp:51
float y1
Definition pdfgen.hpp:50
char op
Definition pdfgen.hpp:48
float y3
Definition pdfgen.hpp:54
float x3
Definition pdfgen.hpp:53
float y2
Definition pdfgen.hpp:52
float x1
Definition pdfgen.hpp:49