forked from dawbarton/pdf2svg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pdf2svg.c
185 lines (154 loc) · 4.99 KB
/
pdf2svg.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Copyright (C) 2007-2013 David Barton ([email protected])
// <http://www.cityinthesky.co.uk/>
// Copyright (C) 2007 Matthew Flaschen ([email protected])
// Updated to allow conversion of all pages at once.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Definitely works with Cairo v1.2.6 and Poppler 0.5.4
#include <assert.h>
#include <stdlib.h>
#include <glib.h>
#include <poppler.h>
#include <poppler-document.h>
#include <poppler-page.h>
#include <cairo.h>
#include <cairo-svg.h>
#include <stdio.h>
#include <string.h>
// Begin theft from ePDFview (Copyright (C) 2006 Emma's Software) under the GPL
gchar *getAbsoluteFileName(const gchar *fileName)
{
gchar *absoluteFileName = NULL;
if (g_path_is_absolute(fileName)) {
absoluteFileName = g_strdup(fileName);
}
else {
gchar *currentDir = g_get_current_dir();
absoluteFileName = g_build_filename(currentDir, fileName, NULL);
g_free(currentDir);
}
return absoluteFileName;
}
// End theft from ePDFview
int convertPage(PopplerPage *page, const char* svgFilename)
{
// Poppler stuff
double width, height;
// Cairo stuff
cairo_surface_t *surface;
cairo_t *drawcontext;
if (page == NULL) {
fprintf(stderr, "Page does not exist\n");
return -1;
}
poppler_page_get_size (page, &width, &height);
// 2018/06/01 Adjust to 150 DPI
double dpi_ratio = 150.0 / 96;
// Open the SVG file
// 2018/06/01 Adjust to 150 DPI
surface = cairo_svg_surface_create(svgFilename, width * dpi_ratio, height * dpi_ratio);
drawcontext = cairo_create(surface);
// 2018/06/01 Adjust to 150 DPI
cairo_scale(drawcontext, dpi_ratio, dpi_ratio);
// Render the PDF file into the SVG file
poppler_page_render_for_printing(page, drawcontext);
cairo_show_page(drawcontext);
// Close the SVG file
cairo_destroy(drawcontext);
cairo_surface_destroy(surface);
// Close the PDF file
g_object_unref(page);
return 0;
}
int main(int argn, char *args[])
{
// Poppler stuff
PopplerDocument *pdffile;
PopplerPage *page;
// Initialise the GType library
// 2018/05/24 pdf2svg.c:90:2: warning: 'g_type_init' is deprecated [-Wdeprecated-declarations]
// g_type_init ();
// Get command line arguments
if ((argn < 3)||(argn > 4)) {
printf("Usage: pdf2svg <in file.pdf> <out file.svg> [<page no>]\n");
return -2;
}
gchar *absoluteFileName = getAbsoluteFileName(args[1]);
gchar *filename_uri = g_filename_to_uri(absoluteFileName, NULL, NULL);
gchar *pageLabel = NULL;
char* svgFilename = args[2];
g_free(absoluteFileName);
if (argn == 4) {
// Get page number
pageLabel = g_strdup(args[3]);
}
// Open the PDF file
pdffile = poppler_document_new_from_file(filename_uri, NULL, NULL);
g_free(filename_uri);
if (pdffile == NULL) {
fprintf(stderr, "Unable to open file\n");
return -3;
}
int conversionErrors = 0;
// Get the page
if(pageLabel == NULL) {
page = poppler_document_get_page(pdffile, 0);
conversionErrors = convertPage(page, svgFilename);
}
else {
if(strcmp(pageLabel, "all") == 0) {
int curError;
int pageCount = poppler_document_get_n_pages(pdffile);
if(pageCount > 9999999) {
fprintf(stderr, "Too many pages (>9,999,999)\n");
return -5;
}
// 2018/05/24 Simplify buffer allocation to extend 10 bytes
size_t svgFilenameBufLen = strlen(svgFilename) + 10;
char *svgFilenameBuffer = (char*)malloc(svgFilenameBufLen);
assert(svgFilenameBuffer != NULL);
int pageInd;
for(pageInd = 0; pageInd < pageCount; pageInd++) {
// 2018/05/24 Generate formatted filename and comment realloc function
sprintf(svgFilenameBuffer, "%s_%d.svg", svgFilename, pageInd + 1);
// while (1) {
// size_t _wr_len = snprintf(svgFilenameBuffer, svgFilenameBufLen, svgFilename, pageInd + 1);
// if (_wr_len >= svgFilenameBufLen) {
// svgFilenameBufLen = _wr_len + 1;
// svgFilenameBuffer = (char*)realloc(svgFilenameBuffer, svgFilenameBufLen);
// assert(svgFilenameBuffer != NULL);
// continue;
// }
// break;
// }
page = poppler_document_get_page(pdffile, pageInd);
curError = convertPage(page, svgFilenameBuffer);
if(curError != 0)
conversionErrors = -1;
}
free(svgFilenameBuffer);
}
else {
page = poppler_document_get_page_by_label(pdffile, pageLabel);
conversionErrors = convertPage(page, svgFilename);
g_free(pageLabel);
}
}
g_object_unref(pdffile);
if(conversionErrors != 0) {
return -4;
}
else {
return 0;
}
}