1 #include "export_pdf.hpp"
2 #include "canvas_pdf.hpp"
3 #include <podofo/podofo.h>
4 #include "util/util.hpp"
5 #include "board/board.hpp"
6 #include "export_pdf_util.hpp"
7
8 namespace horizon {
9
cb_nop(std::string,double)10 static void cb_nop(std::string, double)
11 {
12 }
13
export_pdf(const class Board & brd,const class PDFExportSettings & settings,std::function<void (std::string,double)> cb)14 void export_pdf(const class Board &brd, const class PDFExportSettings &settings,
15 std::function<void(std::string, double)> cb)
16 {
17 if (!cb)
18 cb = &cb_nop;
19 cb("Initializing", 0);
20
21 PoDoFo::PdfStreamedDocument document(settings.output_filename.c_str());
22 PoDoFo::PdfPainterMM painter;
23 auto info = document.GetInfo();
24 info->SetCreator("horizon EDA");
25 info->SetProducer("horizon EDA");
26
27
28 auto font = document.CreateFont("Helvetica");
29
30 PDFExportSettings my_settings(settings);
31 my_settings.include_text = false; // need to work out text placement
32 CanvasPDF ca(painter, *font, my_settings);
33
34 cb("Exporting Board", 0);
35 int64_t border_width = 1_mm;
36 auto bbox = brd.get_bbox();
37 auto width = bbox.second.x - bbox.first.x + border_width * 2;
38 auto height = bbox.second.y - bbox.first.y + border_width * 2;
39
40 auto page = document.CreatePage(PoDoFo::PdfRect(0, 0, to_pt(width), to_pt(height)));
41 painter.SetPage(page);
42 painter.SetLineCapStyle(PoDoFo::ePdfLineCapStyle_Round);
43 painter.SetFont(font);
44 painter.SetColor(0, 0, 0);
45 painter.SetTextRenderingMode(PoDoFo::ePdfTextRenderingMode_Invisible);
46 if (settings.mirror) {
47 painter.SetTransformationMatrix(-1, 0, 0, 1, to_pt(bbox.second.x + border_width),
48 to_pt(-bbox.first.y + border_width));
49 }
50 else {
51 painter.SetTransformationMatrix(1, 0, 0, 1, to_pt(-bbox.first.x + border_width),
52 to_pt(-bbox.first.y + border_width));
53 }
54 ca.layer_filter = true;
55 ca.use_layer_colors = true;
56
57 std::vector<int> layers_sorted;
58 for (const auto &it : settings.layers) {
59 if (it.second.enabled) {
60 layers_sorted.push_back(it.first);
61 ca.set_layer_color(it.first, it.second.color);
62 }
63 }
64 std::sort(layers_sorted.begin(), layers_sorted.end());
65 if (settings.reverse_layers)
66 std::reverse(layers_sorted.begin(), layers_sorted.end());
67
68 for (const auto &[uu, pic] : brd.pictures) {
69 if (!pic.on_top)
70 render_picture(document, painter, pic);
71 }
72
73 unsigned int i_layer = 0;
74 for (int layer : layers_sorted) {
75 ca.clear();
76 ca.current_layer = layer;
77 ca.fill = settings.layers.at(layer).mode == PDFExportSettings::Layer::Mode::FILL;
78 cb("Exporting layer " + format_m_of_n(i_layer, layers_sorted.size()), ((double)i_layer) / layers_sorted.size());
79 ca.update(brd);
80 i_layer++;
81 }
82
83 for (const auto &[uu, pic] : brd.pictures) {
84 if (pic.on_top)
85 render_picture(document, painter, pic);
86 }
87
88 painter.FinishPage();
89
90 document.Close();
91 }
92 } // namespace horizon
93