1 /* 2 * This file is part of darktable, 3 * Copyright (C) 2015-2020 darktable developers. 4 * 5 * darktable 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 3 of the License, or 8 * (at your option) any later version. 9 * 10 * darktable 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 darktable. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /* 20 * this is a simple PDF writer, capable of creating multi page PDFs with embedded images. 21 * it is NOT meant to be a full fledged PDF library, and shall never turn into something like that! 22 * see the main() function in pdf.c to see an example how to use this. 23 */ 24 25 #pragma once 26 27 #include <glib.h> 28 #include <glib/gi18n.h> 29 #include <inttypes.h> 30 #include <stdio.h> 31 32 // clang-format off 33 34 #define dt_pdf_inch_to_point(inch) ((inch) * 72.0) 35 #define dt_pdf_point_to_inch(pt) ((pt) / 72.0) 36 #define dt_pdf_mm_to_point(mm) dt_pdf_inch_to_point((mm) / 25.4) 37 #define dt_pdf_point_to_mm(pt) dt_pdf_point_to_inch((pt) * 25.4) 38 #define dt_pdf_point_to_pixel(pt, dpi) (dt_pdf_point_to_inch(pt) * (dpi)) 39 #define dt_pdf_pixel_to_point(px, dpi) (dt_pdf_inch_to_point((px) / (dpi))) 40 41 typedef enum dt_pdf_stream_encoder_t 42 { 43 DT_PDF_STREAM_ENCODER_ASCII_HEX = 0, // inflate size by 2 -- big & fast 44 DT_PDF_STREAM_ENCODER_FLATE = 1 // use zlib to compress -- small & slow 45 } dt_pdf_stream_encoder_t; 46 47 typedef struct dt_pdf_t 48 { 49 FILE *fd; 50 int next_id; 51 int next_image; 52 size_t bytes_written; 53 float page_width, page_height, dpi; 54 dt_pdf_stream_encoder_t default_encoder; 55 56 char *title; 57 58 size_t *offsets; 59 int n_offsets; 60 } dt_pdf_t; 61 62 typedef struct dt_pdf_image_t 63 { 64 int object_id; 65 int name_id; 66 size_t size; 67 size_t width, height; 68 float bb_x, bb_y, bb_width, bb_height; 69 70 gboolean rotate_to_fit; 71 72 gboolean outline_mode; // set to 1 to only draw a box instead of the image 73 gboolean show_bb; // set to 1 to draw the bounding box. useful for debugging 74 } dt_pdf_image_t; 75 76 typedef struct dt_pdf_page_t 77 { 78 int object_id; 79 size_t size; 80 } dt_pdf_page_t; 81 82 static const struct 83 { 84 char *name; 85 float factor; 86 } dt_pdf_units[] = 87 { 88 {N_("mm"), dt_pdf_mm_to_point(1.0)}, 89 {N_("cm"), dt_pdf_mm_to_point(10.0)}, 90 {N_("inch"), dt_pdf_inch_to_point(1.0)}, 91 {N_("\""), dt_pdf_inch_to_point(1.0)}, 92 {NULL, 0.0} 93 }; 94 95 static const int dt_pdf_units_n = sizeof(dt_pdf_units) / sizeof(dt_pdf_units[0]); 96 97 static const struct 98 { 99 char *name; 100 float width; 101 float height; 102 } dt_pdf_paper_sizes[] = 103 { 104 {N_("a4"), dt_pdf_mm_to_point(210), dt_pdf_mm_to_point(297)}, 105 {N_("a3"), dt_pdf_mm_to_point(297), dt_pdf_mm_to_point(420)}, 106 {N_("letter"), dt_pdf_inch_to_point(8.5), dt_pdf_inch_to_point(11.0)}, 107 {N_("legal"), dt_pdf_inch_to_point(8.5), dt_pdf_inch_to_point(14.0)}, 108 {NULL, 0.0, 0.0} 109 }; 110 111 // clang-format on 112 113 static const int dt_pdf_paper_sizes_n = sizeof(dt_pdf_paper_sizes) / sizeof(dt_pdf_paper_sizes[0]) - 1; 114 115 // construction of the pdf 116 dt_pdf_t *dt_pdf_start(const char *filename, float width, float height, float dpi, dt_pdf_stream_encoder_t default_encoder); 117 int dt_pdf_add_icc(dt_pdf_t *pdf, const char *filename); 118 int dt_pdf_add_icc_from_data(dt_pdf_t *pdf, const unsigned char *data, size_t size); 119 dt_pdf_image_t *dt_pdf_add_image(dt_pdf_t *pdf, const unsigned char *image, int width, int height, int bpp, int icc_id, float border); 120 dt_pdf_page_t *dt_pdf_add_page(dt_pdf_t *pdf, dt_pdf_image_t **images, int n_images); 121 void dt_pdf_finish(dt_pdf_t *pdf, dt_pdf_page_t **pages, int n_pages); 122 123 // general helpers 124 int dt_pdf_parse_length(const char *str, float *length); 125 int dt_pdf_parse_paper_size(const char *str, float *width, float *height); 126 127 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh 128 // vim: shiftwidth=2 expandtab tabstop=2 cindent 129 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified; 130