Skip to content

Commit

Permalink
Merge pull request #755 from fk0815/master
Browse files Browse the repository at this point in the history
Add support for libpodofo version >= 0.10.0
  • Loading branch information
carrotIndustries authored Feb 11, 2024
2 parents b78d806 + 8520345 commit 8274cb8
Show file tree
Hide file tree
Showing 17 changed files with 926 additions and 163 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/all.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ jobs:
- name: Install updates
run: pacman -Syu --noconfirm
- name: Install dependencies
run: pacman -Sy --needed --noconfirm zeromq cppzmq gtkmm3 cairomm librsvg sqlite3 libgit2 curl opencascade glm podofo-0.9 libarchive python libspnav cmake meson
run: pacman -Sy --needed --noconfirm zeromq cppzmq gtkmm3 cairomm librsvg sqlite3 libgit2 curl opencascade glm podofo libarchive python libspnav cmake meson
- name: Install python dependencies
if: ${{ matrix.target == 'horizon.so' }}
run: pacman -S --needed --noconfirm mesa python-cairo python-yaml
Expand All @@ -145,7 +145,6 @@ jobs:
runs-on: ubuntu-latest
container: opensuse/tumbleweed
needs: stylecheck
continue-on-error: true
steps:
- uses: actions/checkout@v3
- name: Install dependencies
Expand Down
Binary file added 3rd_party/DejaVuSans.ttf
Binary file not shown.
2 changes: 2 additions & 0 deletions imp.gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,7 @@
<file>canvas3d/shaders/background-fragment.glsl</file>

<file>color_presets.json</file>

<file>DejaVuSans.ttf</file>
</gresource>
</gresources>
36 changes: 27 additions & 9 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,32 @@ if get_option('debug')
cpp_args += '-DCONNECTION_CHECK'
endif

# pkg-config is useless for podofo :(
# pkg-config is useless for old podofo :(
podofo_legacy = true
podofo_lib =cxx.find_library('podofo', dirs: '/usr/lib/podofo-0.9/', required: false, has_headers:['/usr/include/podofo-0.9/podofo/podofo.h'] )
if podofo_lib.found()
podofo = declare_dependency (
podofo = declare_dependency (
dependencies: podofo_lib,
include_directories: include_directories('/usr/include/podofo-0.9')
)
include_directories: include_directories('/usr/include/podofo-0.9')
)
else
podofo = dependency('libpodofo09', required:false)
if podofo.found()
cpp_args += '-DINC_PODOFO_WITHOUT_DIRECTORY'
else
podofo = dependency('libpodofo')
if podofo.version() == 'unknown' or podofo.version() < '0.10.0'
podofo_legacy = true
else
podofo_legacy = false
endif
endif
endif

if podofo_legacy
message('using legacy podofo')
endif

stdlibs = []
is_libstdcpp = cxx.get_define('__GLIBCXX__', prefix: '#include <vector>') != ''
if is_libstdcpp
Expand Down Expand Up @@ -666,10 +676,6 @@ src_export = files(
'src/export_util/tree_writer.cpp',
'src/export_util/tree_writer_fs.cpp',
'src/export_util/tree_writer_archive.cpp',
'src/export_pdf/canvas_pdf.cpp',
'src/export_pdf/export_pdf.cpp',
'src/export_pdf/export_pdf_board.cpp',
'src/export_pdf/export_pdf_util.cpp',
'src/export_pnp/export_pnp.cpp',
'src/export_bom/export_bom.cpp',
'src/export_odb/odb_export.cpp',
Expand All @@ -686,6 +692,18 @@ src_export = files(
'src/export_odb/structured_text_writer.cpp'
)

if podofo_legacy
src_export += 'src/export_pdf/legacy/canvas_pdf.cpp'
src_export += 'src/export_pdf/legacy/export_pdf.cpp'
src_export += 'src/export_pdf/legacy/export_pdf_board.cpp'
src_export += 'src/export_pdf/legacy/export_pdf_util.cpp'
else
src_export += 'src/export_pdf/canvas_pdf.cpp'
src_export += 'src/export_pdf/export_pdf.cpp'
src_export += 'src/export_pdf/export_pdf_board.cpp'
src_export += 'src/export_pdf/export_pdf_util.cpp'
endif

src_board_rules_check = files(
'src/rules/cache.cpp',
'src/board/board_rules_check.cpp',
Expand Down Expand Up @@ -918,7 +936,7 @@ resources = gnome.compile_resources(
'imp.gresource.xml',
dependencies: color_presets_json,
c_name: 'horizon_resources',
source_dir: 'src'
source_dir: ['src', '3rd_party']
)

libhorizon = static_library('libhorizon',
Expand Down
84 changes: 43 additions & 41 deletions src/export_pdf/canvas_pdf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "common/hole.hpp"
#include "canvas/appearance.hpp"
#include "board/plane.hpp"
#include <sstream>

namespace horizon {

Expand All @@ -15,11 +16,12 @@ double to_pt(double x_nm)
}

CanvasPDF::CanvasPDF(PoDoFo::PdfPainter &p, PoDoFo::PdfFont &f, const PDFExportSettings &s)
: Canvas::Canvas(), painter(p), font(f), settings(s), metrics(font.GetFontMetrics())
: Canvas::Canvas(), painter(p), font(f), settings(s), metrics(font.GetMetrics())
{
img_mode = true;
Appearance apperarance;
layer_colors = apperarance.layer_colors;
path.Reset();
}

bool CanvasPDF::pdf_layer_visible(int l) const
Expand All @@ -42,19 +44,18 @@ void CanvasPDF::img_line(const Coordi &p0, const Coordi &p1, const uint64_t widt
{
if (!pdf_layer_visible(layer))
return;
painter.Save();
auto w = std::max(width, settings.min_line_width);
painter.SetStrokeWidth(to_pt(w));

auto w = std::max(width, std::max(settings.min_line_width, (uint64_t).001_mm));
painter.GraphicsState.SetLineWidth(to_pt(w));
Coordi rp0 = p0;
Coordi rp1 = p1;
if (tr) {
rp0 = transform.transform(p0);
rp1 = transform.transform(p1);
}
auto color = get_pdf_layer_color(layer);
painter.SetStrokingColor(color.r, color.g, color.b);
painter.GraphicsState.SetStrokeColor(PoDoFo::PdfColor(color.r, color.g, color.b));
painter.DrawLine(to_pt(rp0.x), to_pt(rp0.y), to_pt(rp1.x), to_pt(rp1.y));
painter.Restore();
}

void CanvasPDF::img_draw_text(const Coordf &p, float size, const std::string &rtext, int angle, bool flip,
Expand Down Expand Up @@ -87,10 +88,11 @@ void CanvasPDF::img_draw_text(const Coordf &p, float size, const std::string &rt
if (mirror) {
lineskip *= -1;
}
font.SetFontSize(to_pt(size) * 1.6);

painter.TextState.SetFont(font, to_pt(size) * 1.6);
while (std::getline(ss, line, '\n')) {
line = TextData::trim(line);
int64_t line_width = metrics->StringWidthMM(line.c_str()) * 1000;
int64_t line_width = font.GetStringLength(line.c_str(), painter.TextState);

Placement tf;
tf.shift.x = p.x;
Expand Down Expand Up @@ -128,9 +130,9 @@ void CanvasPDF::img_draw_text(const Coordf &p, float size, const std::string &rt
Coordi p0(xshift, yshift);
Coordi pt = tf.transform(p0);

painter.SetTransformationMatrix(cos(fangle), sin(fangle), -sin(fangle), cos(fangle), to_pt(pt.x), to_pt(pt.y));
PoDoFo::PdfString pstr(reinterpret_cast<const PoDoFo::pdf_utf8 *>(line.c_str()));
painter.DrawText(0, to_pt(size) / -2, pstr);
painter.GraphicsState.SetCurrentMatrix(PoDoFo::Matrix::FromCoefficients(cos(fangle), sin(fangle), -sin(fangle),
cos(fangle), to_pt(pt.x), to_pt(pt.y)));
painter.DrawText(line.c_str(), 0, to_pt(size) / -2);
painter.Restore();

i_line++;
Expand All @@ -139,74 +141,74 @@ void CanvasPDF::img_draw_text(const Coordf &p, float size, const std::string &rt

void CanvasPDF::img_polygon(const Polygon &ipoly, bool tr)
{

if (!pdf_layer_visible(ipoly.layer))
return;
painter.Save();

auto color = get_pdf_layer_color(ipoly.layer);
painter.SetColor(color.r, color.g, color.b);
painter.SetStrokingColor(color.r, color.g, color.b);
painter.SetStrokeWidth(to_pt(settings.min_line_width));
painter.GraphicsState.SetFillColor(PoDoFo::PdfColor(color.r, color.g, color.b));
painter.GraphicsState.SetStrokeColor(PoDoFo::PdfColor(color.r, color.g, color.b));
painter.GraphicsState.SetLineWidth(to_pt(settings.min_line_width));
if (ipoly.usage == nullptr) { // regular patch
draw_polygon(ipoly, tr);
if (fill)
painter.Fill();
painter.DrawPath(path, PoDoFo::PdfPathDrawMode::Fill);
else
painter.Stroke();
painter.DrawPath(path, PoDoFo::PdfPathDrawMode::Stroke);
}
else if (auto plane = dynamic_cast<const Plane *>(ipoly.usage.ptr)) {
for (const auto &frag : plane->fragments) {
for (const auto &path : frag.paths) {
for (const auto &dpath : frag.paths) {
bool first = true;
for (const auto &it : path) {
for (const auto &it : dpath) {
Coordi p(it.X, it.Y);
if (tr)
p = transform.transform(p);
if (first)
painter.MoveTo(to_pt(p.x), to_pt(p.y));
path.MoveTo(to_pt(p.x), to_pt(p.y));
else
painter.LineTo(to_pt(p.x), to_pt(p.y));
path.AddLineTo(to_pt(p.x), to_pt(p.y));
first = false;
}
painter.ClosePath();
path.Close();
}
}
if (fill)
painter.Fill(true);
painter.DrawPath(path, PoDoFo::PdfPathDrawMode::Fill);
else
painter.Stroke();
painter.DrawPath(path, PoDoFo::PdfPathDrawMode::Stroke);
}
painter.Restore();
path.Reset();
}

void CanvasPDF::img_hole(const Hole &hole)
{
if (!pdf_layer_visible(PDFExportSettings::HOLES_LAYER))
return;
painter.Save();

auto color = get_pdf_layer_color(PDFExportSettings::HOLES_LAYER);
painter.SetColor(color.r, color.g, color.b);
painter.SetStrokingColor(color.r, color.g, color.b);
painter.SetStrokeWidth(to_pt(settings.min_line_width));
painter.GraphicsState.SetFillColor(PoDoFo::PdfColor(color.r, color.g, color.b));
painter.GraphicsState.SetStrokeColor(PoDoFo::PdfColor(color.r, color.g, color.b));
painter.GraphicsState.SetLineWidth(to_pt(settings.min_line_width));

auto hole2 = hole;
if (settings.set_holes_size) {
hole2.diameter = settings.holes_diameter;
}
draw_polygon(hole2.to_polygon(), true);
if (fill)
painter.Fill(true);
painter.DrawPath(path, PoDoFo::PdfPathDrawMode::Fill);
else
painter.Stroke();
painter.Restore();
painter.DrawPath(path, PoDoFo::PdfPathDrawMode::Stroke);
path.Reset();
}

// c is the arc center.
// angles must be in radians, c and r must be in mm.
// See "How to determine the control points of a Bézier curve that approximates a
// small circular arc" by Richard ADeVeneza, Nov 2004
// https://www.tinaja.com/glib/bezcirc2.pdf
static Coordd pdf_arc_segment(PoDoFo::PdfPainter &painter, const Coordd c, const double r, double a0, double a1)
static Coordd pdf_arc_segment(PoDoFo::PdfPainterPath &path, const Coordd c, const double r, double a0, double a1)
{
const auto da = a0 - a1;
assert(da != 0);
Expand All @@ -227,11 +229,11 @@ static Coordd pdf_arc_segment(PoDoFo::PdfPainter &painter, const Coordd c, const
const auto c2 = p2.rotate(theta) * r + c;
const auto c3 = p3.rotate(theta) * r + c;

painter.CubicBezierTo(to_pt(c1.x), to_pt(c1.y), to_pt(c2.x), to_pt(c2.y), to_pt(c3.x), to_pt(c3.y));
path.AddCubicBezierTo(to_pt(c1.x), to_pt(c1.y), to_pt(c2.x), to_pt(c2.y), to_pt(c3.x), to_pt(c3.y));
return c3; // end point
}

static void pdf_arc(PoDoFo::PdfPainter &painter, const Coordd start, const Coordd c, const Coordd end, bool cw)
static void pdf_arc(PoDoFo::PdfPainterPath &path, const Coordd start, const Coordd c, const Coordd end, bool cw)
{
const auto r = (start - c).mag();

Expand All @@ -258,7 +260,7 @@ static void pdf_arc(PoDoFo::PdfPainter &painter, const Coordd start, const Coord
while (std::abs(e) > 1e-6) {
const auto d = (cw) ? std::max(e, da) : std::min(e, da);
const auto a = a0 + d;
pdf_arc_segment(painter, c, r, a0, a);
pdf_arc_segment(path, c, r, a0, a);
a0 = a;
e = a1 - a0;
}
Expand All @@ -278,29 +280,29 @@ void CanvasPDF::draw_polygon(const Polygon &ipoly, bool tr)
it_next = ipoly.vertices.cbegin();
}
if (first) {
painter.MoveTo(to_pt(p.x), to_pt(p.y));
path.MoveTo(to_pt(p.x), to_pt(p.y));
}
if (it->type == Polygon::Vertex::Type::LINE) {
if (!first) {
painter.LineTo(to_pt(p.x), to_pt(p.y));
path.AddLineTo(to_pt(p.x), to_pt(p.y));
}
}
else if (it->type == Polygon::Vertex::Type::ARC) {
Coordd end = it_next->position;
Coordd c = project_onto_perp_bisector(end, it->position, it->arc_center);
if (!first)
painter.LineTo(to_pt(p.x), to_pt(p.y));
path.AddLineTo(to_pt(p.x), to_pt(p.y));

if (tr) {
c = transform.transform(c);
end = transform.transform(end);
}
pdf_arc(painter, p, c, end, it->arc_reverse);
pdf_arc(path, p, c, end, it->arc_reverse);
}
first = false;
}

painter.ClosePath();
path.Close();
}

void CanvasPDF::request_push()
Expand Down
3 changes: 2 additions & 1 deletion src/export_pdf/canvas_pdf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class CanvasPDF : public Canvas {
PoDoFo::PdfPainter &painter;
PoDoFo::PdfFont &font;
const PDFExportSettings &settings;
const PoDoFo::PdfFontMetrics *metrics;
const PoDoFo::PdfFontMetrics &metrics;
void img_line(const Coordi &p0, const Coordi &p1, const uint64_t width, int layer, bool tr) override;
void img_polygon(const class Polygon &poly, bool tr) override;
void img_draw_text(const Coordf &p, float size, const std::string &rtext, int angle, bool flip, TextOrigin origin,
Expand All @@ -37,5 +37,6 @@ class CanvasPDF : public Canvas {
bool pdf_layer_visible(int l) const;
void draw_polygon(const Polygon &ipoly, bool tr);
Color get_pdf_layer_color(int layer) const;
PoDoFo::PdfPainterPath path;
};
} // namespace horizon
Loading

0 comments on commit 8274cb8

Please sign in to comment.