Created
April 12, 2020 03:11
-
-
Save iamtekeste/847f91ee46317ab8fb7ca523f8fdf049 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "config.h" | |
#include <poppler-config.h> | |
#include <cstdint> | |
#include <cstdio> | |
#include <cmath> | |
#include <cstring> | |
#include "goo/gmem.h" | |
#include "goo/GooString.h" | |
#include "GlobalParams.h" | |
#include "Object.h" | |
#include "PDFDoc.h" | |
#include "PDFDocFactory.h" | |
#include "CairoOutputDev.h" | |
#include "numberofcharacters.h" | |
#include <cairo.h> | |
#include <cairo-svg.h> | |
static bool useMediaBox = true; | |
static bool printing = true; | |
static double resolution = 0.0; | |
static double x_resolution = 150.0; | |
static double y_resolution = 150.0; | |
static int scaleTo = 0; | |
static int x_scaleTo = 0; | |
static int y_scaleTo = 0; | |
static int crop_x = 0; | |
static int crop_y = 0; | |
static int crop_w = 0; | |
static int crop_h = 0; | |
static int sz = 0; | |
static cairo_surface_t *surface; | |
static FILE *output_file; | |
static void getCropSize(double page_w, double page_h, double *width, double *height) | |
{ | |
int w = crop_w; | |
int h = crop_h; | |
if (w == 0) | |
w = (int)ceil(page_w); | |
if (h == 0) | |
h = (int)ceil(page_h); | |
*width = (crop_x + w > page_w ? (int)ceil(page_w - crop_x) : w); | |
*height = (crop_y + h > page_h ? (int)ceil(page_h - crop_y) : h); | |
} | |
static void getOutputSize(double page_w, double page_h, double *width, double *height) | |
{ | |
*width = page_w; | |
*height = page_h; | |
} | |
static void getFitToPageTransform(double page_w, double page_h, | |
double paper_w, double paper_h, | |
cairo_matrix_t *m) | |
{ | |
double x_scale, y_scale, scale; | |
x_scale = paper_w / page_w; | |
y_scale = paper_h / page_h; | |
if (x_scale < y_scale) | |
scale = x_scale; | |
else | |
scale = y_scale; | |
if (scale > 1.0 && !expand) | |
scale = 1.0; | |
if (scale < 1.0 && noShrink) | |
scale = 1.0; | |
cairo_matrix_init_identity (m); | |
if (!noCenter) { | |
// centre page | |
cairo_matrix_translate (m, (paper_w - page_w*scale)/2, (paper_h - page_h*scale)/2); | |
} else if (!svg) { | |
// move to PostScript origin | |
cairo_matrix_translate (m, 0, (paper_h - page_h*scale)); | |
} | |
cairo_matrix_scale (m, scale, scale); | |
} | |
static cairo_status_t writeStream(void *closure, const unsigned char *data, unsigned int length) | |
{ | |
FILE *file = (FILE *)closure; | |
if (fwrite(data, length, 1, file) == 1) | |
return CAIRO_STATUS_SUCCESS; | |
else | |
return CAIRO_STATUS_WRITE_ERROR; | |
} | |
static void beginDocument(GooString *outputFileName, double w, double h) | |
{ | |
output_file = fopen(outputFileName->c_str(), "wb"); | |
if (!output_file) { | |
fprintf(stderr, "Error opening output file %s\n", outputFileName->c_str()); | |
exit(2); | |
} | |
surface = cairo_svg_surface_create_for_stream(writeStream, output_file, w, h); | |
cairo_svg_surface_restrict_to_version (surface, CAIRO_SVG_VERSION_1_2); | |
} | |
static void beginPage(double *w, double *h) | |
{ | |
cairo_surface_set_fallback_resolution (surface, x_resolution, y_resolution); | |
} | |
static void renderPage(PDFDoc *doc, CairoOutputDev *cairoOut, int pg, | |
double page_w, double page_h, | |
double output_w, double output_h) | |
{ | |
cairo_t *cr; | |
cairo_status_t status; | |
cairo_matrix_t m; | |
cr = cairo_create(surface); | |
cairoOut->setCairo(cr); | |
cairoOut->setPrinting(printing); | |
cairo_save(cr); | |
cairo_translate (cr, -crop_x, -crop_y); | |
double cropped_w, cropped_h; | |
getCropSize(page_w, page_h, &cropped_w, &cropped_h); | |
getFitToPageTransform(cropped_w, cropped_h, output_w, output_h, &m); | |
cairo_transform (cr, &m); | |
cairo_rectangle(cr, crop_x, crop_y, cropped_w, cropped_h); | |
cairo_clip(cr); | |
doc->displayPageSlice(cairoOut, | |
pg, | |
72.0, 72.0, | |
0, /* rotate */ | |
useMediaBox, /* useMediaBox */ | |
false, /* Crop */ | |
printing, | |
-1, -1, -1, -1); | |
cairo_restore(cr); | |
cairoOut->setCairo(nullptr); | |
status = cairo_status(cr); | |
if (status) | |
fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status)); | |
cairo_destroy (cr); | |
} | |
static void endPage() | |
{ | |
cairo_surface_show_page(surface); | |
} | |
static void endDocument() | |
{ | |
cairo_status_t status; | |
if (printing) { | |
cairo_surface_finish(surface); | |
status = cairo_surface_status(surface); | |
if (status) | |
fprintf(stderr, "cairo error: %s\n", cairo_status_to_string(status)); | |
cairo_surface_destroy(surface); | |
if (output_file) | |
fclose(output_file); | |
} | |
} | |
int getNumberOfPages (char *inputFileName) { | |
PDFDoc *doc; | |
GooString *fileName = new GooString(inputFileName); | |
doc = PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr); | |
if (!doc->isOk()) { | |
fprintf(stderr, "Error opening PDF file.\n"); | |
exit(1); | |
} | |
return doc->getNumPages(); | |
} | |
int myConverter(int pageNumber, char *inputFileName, char *outputFileName) { | |
PDFDoc *doc; | |
GooString *fileName = new GooString(inputFileName); | |
GooString *outputName = new GooString(outputFileName);; | |
CairoOutputDev *cairoOut; | |
int pg, pg_num_len; | |
double pg_w, pg_h, tmp, output_w, output_h; | |
doc = PDFDocFactory().createPDFDoc(*fileName, nullptr, nullptr); | |
if (!doc->isOk()) { | |
fprintf(stderr, "Error opening PDF file.\n"); | |
exit(1); | |
} | |
cairoOut = new CairoOutputDev(); | |
cairoOut->startDoc(doc); | |
pg_w = doc->getPageMediaWidth(pageNumber); | |
pg_h = doc->getPageMediaHeight(pageNumber); | |
if ((doc->getPageRotate(pageNumber) == 90) || (doc->getPageRotate(pageNumber) == 270)) { | |
tmp = pg_w; | |
pg_w = pg_h; | |
pg_h = tmp; | |
} | |
getOutputSize(pg_w, pg_h, &output_w, &output_h); | |
beginDocument(outputName, output_w, output_h); | |
beginPage(&output_w, &output_h); | |
renderPage(doc, cairoOut, pg, pg_w, pg_h, output_w, output_h); | |
endPage(); | |
endDocument(); | |
// clean up | |
delete cairoOut; | |
delete doc; | |
if (fileName) | |
delete fileName; | |
if (outputName) | |
delete outputName; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment