Skip to content

Commit 1b733ee

Browse files
Merge pull request #846 from cgudrian/tables
Changelog: New Features/Editor: Add support for simple tables in schematics and boards
2 parents ff58bae + 074d9af commit 1b733ee

47 files changed

Lines changed: 1185 additions & 23 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ src_common = files(
197197
'src/common/polygon.cpp',
198198
'src/common/shape.cpp',
199199
'src/common/text.cpp',
200+
'src/common/table.cpp',
200201
'src/frame/frame.cpp',
201202
'src/logger/logger.cpp',
202203
'src/package/package_rules.cpp',
@@ -512,6 +513,7 @@ src_imp = files(
512513
'src/dialogs/edit_plane_window.cpp',
513514
'src/dialogs/edit_shape.cpp',
514515
'src/dialogs/edit_stackup.cpp',
516+
'src/dialogs/edit_table_window.cpp',
515517
'src/dialogs/edit_text_window.cpp',
516518
'src/dialogs/edit_via.cpp',
517519
'src/dialogs/enter_datum_angle_window.cpp',

scripts/app_versions.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ versions:
2222
20: add via definitions
2323
21: add user layers
2424
22: add height restrictions
25+
23: add tables
2526
schematic:
2627
1: add custom values on symbols
2728
2: add hierarchy
@@ -32,6 +33,7 @@ versions:
3233
7: keep nets on unconnected labels
3334
8: add BOM export customisation
3435
9: add bus ripper label position
36+
10: add tables
3537
package:
3638
1: package-defined solder mask & paste parameters override board parameters
3739
2: add heights

src/board/board.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const LutEnumStr<Board::OutputFormat> Board::output_format_lut = {
4343
{"odb", Board::OutputFormat::ODB},
4444
};
4545

46-
static const unsigned int app_version = 22;
46+
static const unsigned int app_version = 23;
4747

4848
unsigned int Board::get_app_version()
4949
{
@@ -157,6 +157,13 @@ Board::Board(const UUID &uu, const json &j, Block &iblock, IPool &pool, const st
157157
load_and_log(texts, ObjectType::TEXT, std::forward_as_tuple(u, it.value()), Logger::Domain::BOARD);
158158
}
159159
}
160+
if (j.count("tables")) {
161+
const json &o = j["tables"];
162+
for (auto it = o.cbegin(); it != o.cend(); ++it) {
163+
auto u = UUID(it.key());
164+
load_and_log(tables, ObjectType::TABLE, std::forward_as_tuple(u, it.value()), Logger::Domain::BOARD);
165+
}
166+
}
160167
if (j.count("lines")) {
161168
const json &o = j["lines"];
162169
for (auto it = o.cbegin(); it != o.cend(); ++it) {
@@ -377,16 +384,16 @@ const std::map<int, Layer> &Board::get_layers() const
377384

378385
Board::Board(const Board &brd, CopyMode copy_mode)
379386
: layers(brd.layers), uuid(brd.uuid), block(brd.block), name(brd.name), polygons(brd.polygons), holes(brd.holes),
380-
junctions(brd.junctions), tracks(brd.tracks), texts(brd.texts), lines(brd.lines), arcs(brd.arcs),
381-
planes(brd.planes), keepouts(brd.keepouts), dimensions(brd.dimensions), connection_lines(brd.connection_lines),
382-
included_boards(brd.included_boards), board_panels(brd.board_panels), pictures(brd.pictures), decals(brd.decals),
383-
net_ties(brd.net_ties), height_restrictions(brd.height_restrictions), warnings(brd.warnings),
384-
output_format(brd.output_format), rules(brd.rules), gerber_output_settings(brd.gerber_output_settings),
385-
odb_output_settings(brd.odb_output_settings), grid_settings(brd.grid_settings), airwires(brd.airwires),
386-
stackup(brd.stackup), colors(brd.colors), pdf_export_settings(brd.pdf_export_settings),
387-
step_export_settings(brd.step_export_settings), pnp_export_settings(brd.pnp_export_settings),
388-
version(brd.version), board_directory(brd.board_directory), n_inner_layers(brd.n_inner_layers),
389-
user_layers(brd.user_layers)
387+
junctions(brd.junctions), tracks(brd.tracks), texts(brd.texts), tables(brd.tables), lines(brd.lines),
388+
arcs(brd.arcs), planes(brd.planes), keepouts(brd.keepouts), dimensions(brd.dimensions),
389+
connection_lines(brd.connection_lines), included_boards(brd.included_boards), board_panels(brd.board_panels),
390+
pictures(brd.pictures), decals(brd.decals), net_ties(brd.net_ties), height_restrictions(brd.height_restrictions),
391+
warnings(brd.warnings), output_format(brd.output_format), rules(brd.rules),
392+
gerber_output_settings(brd.gerber_output_settings), odb_output_settings(brd.odb_output_settings),
393+
grid_settings(brd.grid_settings), airwires(brd.airwires), stackup(brd.stackup), colors(brd.colors),
394+
pdf_export_settings(brd.pdf_export_settings), step_export_settings(brd.step_export_settings),
395+
pnp_export_settings(brd.pnp_export_settings), version(brd.version), board_directory(brd.board_directory),
396+
n_inner_layers(brd.n_inner_layers), user_layers(brd.user_layers)
390397
{
391398
if (copy_mode == CopyMode::DEEP) {
392399
packages = brd.packages;
@@ -1310,6 +1317,10 @@ json Board::serialize() const
13101317
for (const auto &it : texts) {
13111318
j["texts"][(std::string)it.first] = it.second.serialize();
13121319
}
1320+
j["tables"] = json::object();
1321+
for (const auto &it : tables) {
1322+
j["tables"][(std::string)it.first] = it.second.serialize();
1323+
}
13131324
j["lines"] = json::object();
13141325
for (const auto &it : lines) {
13151326
j["lines"][(std::string)it.first] = it.second.serialize();

src/board/board.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "common/grid_settings.hpp"
3232
#include "board_net_tie.hpp"
3333
#include "height_restriction.hpp"
34+
#include "common/table.hpp"
3435

3536
namespace horizon {
3637
using json = nlohmann::json;
@@ -104,6 +105,7 @@ class Board : public ObjectProvider, public LayerProvider {
104105
std::map<UUID, Track> tracks;
105106
std::map<UUID, Via> vias;
106107
std::map<UUID, Text> texts;
108+
std::map<UUID, Table> tables;
107109
std::map<UUID, Line> lines;
108110
std::map<UUID, Arc> arcs;
109111
std::map<UUID, Plane> planes;

src/canvas/canvas.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class Canvas {
128128
void render(const class PowerSymbol &sym);
129129
void render(const class BusRipper &ripper);
130130
void render(const class Text &text, bool interactive = true, ColorP co = ColorP::FROM_LAYER);
131+
void render(const class Table &table, bool interactive = true, ColorP co = ColorP::FROM_LAYER);
131132
void render(const class Padstack &padstack, bool interactive = true);
132133
void render(const class Polygon &polygon, bool interactive = true, ColorP co = ColorP::FROM_LAYER);
133134
void render(const class Shape &shape, bool interactive = true);

src/canvas/grid.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ void Grid::render()
7070

7171
Coordf sp = spacing;
7272
Coordf sp_px = sp * ca.scale;
73-
unsigned int newmul = 1;
73+
uint64_t newmul = 1;
7474
while (sp_px.x < 20 || sp_px.y < 20) {
7575
newmul *= 2;
7676
sp = spacing * newmul;

src/canvas/render.cpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "common/hole.hpp"
66
#include "common/polygon.hpp"
77
#include "common/text.hpp"
8+
#include "common/table.hpp"
89
#include "layer_display.hpp"
910
#include "package/pad.hpp"
1011
#include "poly2tri/poly2tri.h"
@@ -800,6 +801,84 @@ void Canvas::render(const Text &text, bool interactive, ColorP co)
800801
}
801802
}
802803

804+
void Canvas::render(const Table &table, bool interactive, ColorP co)
805+
{
806+
const bool rev = layer_provider.get_layers().at(table.layer).reverse;
807+
808+
transform_save();
809+
transform.accumulate(table.placement);
810+
811+
object_ref_push(ObjectType::TABLE, table.uuid);
812+
813+
auto &layout = table.get_layout();
814+
815+
img_auto_line = img_mode;
816+
817+
uint64_t line_width = table.get_line_width();
818+
float total_width = rev ? -layout.total_width : layout.total_width;
819+
float total_height = -layout.total_height;
820+
821+
// draw outer border
822+
{
823+
draw_line({0, 0}, {total_width, 0}, co, table.layer, true, line_width);
824+
draw_line({total_width, 0}, {total_width, total_height}, co, table.layer, true, line_width);
825+
draw_line({total_width, total_height}, {0, total_height}, co, table.layer, true, line_width);
826+
draw_line({0, total_height}, {0, 0}, co, table.layer, true, line_width);
827+
}
828+
829+
// draw horizontal grid lines
830+
{
831+
float y = -layout.row_heights[0];
832+
for (size_t r = 1; r < table.get_n_rows(); r++) {
833+
draw_line({0, y}, {total_width, y}, co, table.layer, true, line_width);
834+
y -= layout.row_heights[r];
835+
}
836+
}
837+
838+
// draw vertical grid lines
839+
{
840+
float x = rev ? -layout.col_widths[0] : layout.col_widths[0];
841+
for (size_t c = 1; c < table.get_n_columns(); c++) {
842+
draw_line({x, 0}, {x, total_height}, co, table.layer, true, line_width);
843+
if (rev)
844+
x -= layout.col_widths[c];
845+
else
846+
x += layout.col_widths[c];
847+
}
848+
}
849+
850+
img_auto_line = false;
851+
852+
// draw cell contents
853+
{
854+
TextRenderer::Options opts;
855+
opts.width = line_width;
856+
opts.font = table.get_font();
857+
opts.allow_upside_down = true;
858+
opts.flip = rev;
859+
860+
auto &cells = table.get_cells();
861+
for (size_t idx = 0; idx < cells.size(); idx++) {
862+
auto textpos = layout.text_positions[idx];
863+
if (rev)
864+
textpos.x *= -1;
865+
auto pos = transform.transform(textpos);
866+
auto size = static_cast<float>(table.get_text_size());
867+
int angle = rev ? -transform.get_angle() : transform.get_angle();
868+
draw_text(pos, size, cells[idx], angle, TextOrigin::BASELINE, co, table.layer, opts);
869+
}
870+
}
871+
872+
object_ref_pop();
873+
874+
if (interactive) {
875+
selectables.append(table.uuid, ObjectType::TABLE, {0, 0}, {0, 0}, {total_width, total_height}, 0, table.layer);
876+
targets.emplace_back(table.uuid, ObjectType::TABLE, transform.transform(Coordi(0, 0)), 0, table.layer);
877+
}
878+
879+
transform_restore();
880+
}
881+
803882
template <typename T> static std::string join(const T &v, const std::string &delim)
804883
{
805884
std::ostringstream s;
@@ -1214,6 +1293,9 @@ void Canvas::render(const Sheet &sheet)
12141293
if (!it.second.from_smash)
12151294
render(it.second);
12161295
}
1296+
for (const auto &it : sheet.tables) {
1297+
render(it.second);
1298+
}
12171299
for (const auto &it : sheet.net_labels) {
12181300
render(it.second);
12191301
}
@@ -1684,6 +1766,9 @@ void Canvas::render(const Board &brd, bool interactive, PanelMode mode, OutlineM
16841766
for (const auto &it : brd.texts) {
16851767
render(it.second, interactive);
16861768
}
1769+
for (const auto &it : brd.tables) {
1770+
render(it.second, interactive);
1771+
}
16871772
for (const auto &it : brd.tracks) {
16881773
render(it.second, interactive);
16891774
}

src/common/common.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ enum class ObjectType {
7171
SCHEMATIC_NET_TIE,
7272
BOARD_NET_TIE,
7373
HEIGHT_RESTRICTION,
74+
TABLE,
7475
};
7576
enum class PatchType { OTHER, TRACK, PAD, PAD_TH, VIA, PLANE, HOLE_PTH, HOLE_NPTH, BOARD_EDGE, TEXT, NET_TIE, N_TYPES };
7677

src/common/object_descr.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,5 +406,31 @@ const std::map<ObjectType, ObjectDescription> object_descriptions = {
406406
{ObjectProperty::ID::HEIGHT, {ObjectProperty::Type::LENGTH, "Height", 0}},
407407

408408
}}},
409+
{ObjectType::TABLE,
410+
{"Table",
411+
"Tables",
412+
{
413+
{ObjectProperty::ID::LAYER, {ObjectProperty::Type::LAYER, "Layer", 0}},
414+
{ObjectProperty::ID::POSITION_X, {ObjectProperty::Type::DIM, "Position X", 1}},
415+
{ObjectProperty::ID::POSITION_Y, {ObjectProperty::Type::DIM, "Position Y", 2}},
416+
{ObjectProperty::ID::ANGLE, {ObjectProperty::Type::ANGLE, "Angle", 3}},
417+
{ObjectProperty::ID::FONT,
418+
{ObjectProperty::Type::ENUM,
419+
"Font",
420+
9,
421+
{
422+
{static_cast<int>(TextData::Font::SIMPLEX), "Simplex"},
423+
{static_cast<int>(TextData::Font::DUPLEX), "Duplex"},
424+
{static_cast<int>(TextData::Font::TRIPLEX), "Triplex"},
425+
{static_cast<int>(TextData::Font::TRIPLEX_ITALIC), "Triplex Italic"},
426+
{static_cast<int>(TextData::Font::COMPLEX), "Complex"},
427+
{static_cast<int>(TextData::Font::COMPLEX_ITALIC), "Complex Italic"},
428+
{static_cast<int>(TextData::Font::SCRIPT_SIMPLEX), "Script Simplex"},
429+
{static_cast<int>(TextData::Font::SCRIPT_COMPLEX), "Script Complex"},
430+
}}},
431+
{ObjectProperty::ID::SIZE, {ObjectProperty::Type::LENGTH, "Text Size", 5}},
432+
{ObjectProperty::ID::WIDTH, {ObjectProperty::Type::LENGTH, "Line Width", 6}},
433+
{ObjectProperty::ID::PADDING, {ObjectProperty::Type::LENGTH, "Cell Padding", 7}},
434+
}}},
409435
};
410436
} // namespace horizon

src/common/object_descr.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class ObjectProperty {
8989
SPAN,
9090
VIA_DEFINITION,
9191
TEXT_POSITION,
92+
PADDING,
9293
};
9394
ObjectProperty(Type t, const std::string &l, int o = 0, const std::vector<std::pair<int, std::string>> &its = {})
9495
: type(t), label(l), enum_items(its), order(o)

0 commit comments

Comments
 (0)