1 #pragma once
2 #include "common/common.hpp"
3 #include <iostream>
4 #include <fstream>
5 #include <map>
6 #include <deque>
7 #include "pool/padstack.hpp"
8 #include "util/placement.hpp"
9 #include "clipper/clipper.hpp"
10 
11 namespace horizon {
12 
13 class GerberWriter {
14 public:
15     GerberWriter(const std::string &filename);
16     void write_line(const std::string &s);
17     void close();
18     void comment(const std::string &s);
19     void write_format();
20     void write_apertures();
21     void write_lines();
22     void write_arcs();
23     void write_pads();
24     void write_regions();
25     unsigned int get_or_create_aperture_circle(uint64_t diameter);
26     // unsigned int get_or_create_aperture_padstack(const class Padstack *ps,
27     // int layer, )
28     void draw_line(const Coordi &from, const Coordi &to, uint64_t width);
29     void draw_arc(const Coordi &from, const Coordi &to, const Coordi &center, bool flip, uint64_t width);
30     void draw_padstack(const Padstack &ps, int layer, const Placement &transform);
31     void draw_region(const ClipperLib::Path &path, bool dark = true, int prio = 0);
32     const std::string &get_filename();
33 
34 private:
35     class Line {
36     public:
Line(const Coordi & f,const Coordi & t,unsigned int ap)37         Line(const Coordi &f, const Coordi &t, unsigned int ap) : from(f), to(t), aperture(ap)
38         {
39         }
40         Coordi from;
41         Coordi to;
42         unsigned int aperture;
43     };
44     class Arc {
45     public:
Arc(const Coordi & f,const Coordi & t,const Coordi & c,bool fl,unsigned int ap)46         Arc(const Coordi &f, const Coordi &t, const Coordi &c, bool fl, unsigned int ap)
47             : from(f), to(t), center(c), flip(fl), aperture(ap)
48         {
49         }
50         Coordi from;
51         Coordi to;
52         Coordi center;
53         bool flip = false;
54         unsigned int aperture;
55     };
56 
57     class Region {
58     public:
Region(const ClipperLib::Path & p,bool d=true,int prio=0)59         Region(const ClipperLib::Path &p, bool d = true, int prio = 0) : path(p), dark(d), priority(prio){};
60         ClipperLib::Path path;
61         bool dark;
62         int priority;
63     };
64 
65     class ApertureMacro {
66     public:
67         class Primitive {
68         public:
69             enum class Code { CIRCLE = 1, CENTER_LINE = 21, OUTLINE = 4 };
70             const Code code;
71             std::vector<int64_t> modifiers;
Primitive(Code c)72             Primitive(Code c) : code(c)
73             {
74             }
~Primitive()75             virtual ~Primitive()
76             {
77             }
78         };
79 
80         class PrimitiveCircle : public Primitive {
81         public:
PrimitiveCircle()82             PrimitiveCircle() : Primitive(Code::CIRCLE){};
83             int64_t diameter = 0;
84             Coordi center;
85         };
86 
87         class PrimitiveCenterLine : public Primitive {
88         public:
PrimitiveCenterLine()89             PrimitiveCenterLine() : Primitive(Code::CENTER_LINE){};
90             int64_t width = 0;
91             int64_t height = 0;
92             int angle = 0;
93             Coordi center;
94         };
95         class PrimitiveOutline : public Primitive {
96         public:
PrimitiveOutline()97             PrimitiveOutline() : Primitive(Code::OUTLINE){};
98             std::vector<Coordi> vertices;
99         };
100 
ApertureMacro(unsigned int n)101         ApertureMacro(unsigned int n) : name(n)
102         {
103         }
104 
105         unsigned int name;
106         std::vector<std::unique_ptr<Primitive>> primitives;
107     };
108 
109     std::ofstream ofs;
110     std::string out_filename;
111     void check_open();
112     std::map<uint64_t, unsigned int> apertures_circle;
113     std::map<std::tuple<UUID, std::string, int, bool>, ApertureMacro> apertures_macro;
114 
115     unsigned int aperture_n = 10;
116 
117     std::deque<Line> lines;
118     std::deque<Arc> arcs;
119     std::deque<Region> regions;
120     std::deque<std::pair<unsigned int, Coordi>> pads;
121     void write_decimal(int64_t x, bool comma = true);
122     void write_prim(const ApertureMacro::PrimitiveOutline *prim);
123     void write_prim(const ApertureMacro::PrimitiveCenterLine *prim);
124 };
125 } // namespace horizon
126