r5634 - trunk/eda/fped
werner at docs.openmoko.org
werner at docs.openmoko.org
Sun Sep 13 11:58:31 CEST 2009
Author: werner
Date: 2009-09-13 11:58:30 +0200 (Sun, 13 Sep 2009)
New Revision: 5634
Added:
trunk/eda/fped/layer.c
trunk/eda/fped/layer.h
trunk/eda/fped/overlap.c
trunk/eda/fped/overlap.h
Modified:
trunk/eda/fped/Makefile
trunk/eda/fped/gui_inst.c
trunk/eda/fped/inst.c
trunk/eda/fped/inst.h
trunk/eda/fped/kicad.c
trunk/eda/fped/obj.h
trunk/eda/fped/postscript.c
Log:
- the set of layers of a pad is now maintained in the instance, so that we can
make adjustments when removing layers provided by specialized pads
- gui_inst.c: moved gc construction from gui_draw_pad and gui_draw_rpad to
shared pad_gc
- layer.h: new home of all definitions related to pads and layers
- layer.c:
- overlap.c: functions to test for overlaps of pad shapes (in progress)
Modified: trunk/eda/fped/Makefile
===================================================================
--- trunk/eda/fped/Makefile 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/Makefile 2009-09-13 09:58:30 UTC (rev 5634)
@@ -16,6 +16,7 @@
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \
unparse.o file.o dump.o kicad.o postscript.o meas.o \
+ layer.o overlap.o \
cpp.o lex.yy.o y.tab.o \
gui.o gui_util.o gui_style.o gui_inst.o gui_status.o gui_canvas.o \
gui_tool.o gui_over.o gui_meas.o gui_frame.o
Modified: trunk/eda/fped/gui_inst.c
===================================================================
--- trunk/eda/fped/gui_inst.c 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/gui_inst.c 2009-09-13 09:58:30 UTC (rev 5634)
@@ -107,7 +107,7 @@
}
-static enum mode get_mode(struct inst *self)
+static enum mode get_mode(const struct inst *self)
{
if (selected_inst == self)
return mode_selected;
@@ -257,23 +257,26 @@
}
+static GdkGC *pad_gc(const struct inst *inst)
+{
+ switch (layers_to_pad_type(inst->u.pad.layers)) {
+ case pt_bare:
+ return gc_pad_bare[get_mode(inst)];
+ case pt_mask:
+ return gc_pad_mask[get_mode(inst)];
+ default:
+ return gc_pad[get_mode(inst)];
+ }
+}
+
+
void gui_draw_pad(struct inst *self)
{
struct coord min = translate(self->base);
struct coord max = translate(self->u.pad.other);
GdkGC *gc;
- switch (self->obj->u.pad.type) {
- case pt_bare:
- gc = gc_pad_bare[get_mode(self)];
- break;
- case pt_mask:
- gc = gc_pad_mask[get_mode(self)];
- break;
- default:
- gc = gc_pad[get_mode(self)];
- break;
- }
+ gc = pad_gc(self);
sort_coord(&min, &max);
gdk_draw_rectangle(DA, gc, TRUE,
min.x, min.y, max.x-min.x, max.y-min.y);
@@ -289,17 +292,7 @@
GdkGC *gc;
unit_type h, w, r;
- switch (self->obj->u.pad.type) {
- case pt_bare:
- gc = gc_pad_bare[get_mode(self)];
- break;
- case pt_mask:
- gc = gc_pad_mask[get_mode(self)];
- break;
- default:
- gc = gc_pad[get_mode(self)];
- break;
- }
+ gc = pad_gc(self);
sort_coord(&min, &max);
h = max.y-min.y;
w = max.x-min.x;
Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/inst.c 2009-09-13 09:58:30 UTC (rev 5634)
@@ -18,6 +18,7 @@
#include "util.h"
#include "coord.h"
#include "expr.h"
+#include "layer.h"
#include "obj.h"
#include "delete.h"
#include "gui_util.h"
@@ -802,6 +803,7 @@
inst->obj = obj;
inst->u.pad.name = stralloc(name);
inst->u.pad.other = b;
+ inst->u.pad.layers = pad_type_to_layers(obj->u.pad.type);
update_bbox(&inst->bbox, b);
propagate_bbox(inst);
return 1;
Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/inst.h 2009-09-13 09:58:30 UTC (rev 5634)
@@ -14,6 +14,7 @@
#ifndef INST_H
#define INST_H
+#include <stdint.h>
#include <stdio.h>
#include "coord.h"
@@ -95,6 +96,7 @@
struct {
char *name;
struct coord other;
+ layer_type layers; /* bit-set of layers */
} pad;
struct {
unit_type r;
Modified: trunk/eda/fped/kicad.c
===================================================================
--- trunk/eda/fped/kicad.c 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/kicad.c 2009-09-13 09:58:30 UTC (rev 5634)
@@ -20,44 +20,10 @@
#include "kicad.h"
-enum kicad_layer {
- layer_bottom, /* "copper" */
- layer_l15,
- layer_l14,
- layer_l13,
- layer_l12,
- layer_l11,
- layer_l10,
- layer_l9,
- layer_l8,
- layer_l7,
- layer_l6,
- layer_l5,
- layer_l4,
- layer_l3,
- layer_l2,
- layer_top, /* "component" */
- layer_glue_bottom, /* adhesive, copper side */
- layer_glue_top, /* adhesive, component side */
- layer_paste_bottom, /* solder paste */
- layer_paste_top,
- layer_silk_bottom, /* silk screen */
- layer_silk_top,
- layer_mask_bottom, /* solder mask */
- layer_mask_top,
- layer_draw, /* general drawing */
- layer_comment,
- layer_eco1,
- layer_eco2,
- layer_edge, /* edge */
-};
-
-
static void kicad_pad(FILE *file, const struct inst *inst)
{
struct coord min, max;
unit_type tmp;
- int layers;
min.x = units_to_kicad(inst->base.x);
min.y = units_to_kicad(inst->base.y);
@@ -87,24 +53,7 @@
/*
* Attributes: pad type, N, layer mask
*/
- layers = 0;
- switch (inst->obj->u.pad.type) {
- case pt_normal:
- layers = 1 << layer_paste_top;
- /* fall through */
- case pt_bare:
- layers |= (1 << layer_top) | (1 << layer_mask_top);
- break;
- case pt_paste:
- layers = 1 << layer_paste_top;
- break;
- case pt_mask:
- layers = 1 << layer_mask_top;
- break;
- default:
- abort();
- }
- fprintf(file, "At SMD N %8.8X\n", layers);
+ fprintf(file, "At SMD N %8.8X\n", (unsigned) inst->u.pad.layers);
/*
* Position: Xpos, Ypos
Added: trunk/eda/fped/layer.c
===================================================================
--- trunk/eda/fped/layer.c (rev 0)
+++ trunk/eda/fped/layer.c 2009-09-13 09:58:30 UTC (rev 5634)
@@ -0,0 +1,56 @@
+/*
+ * layer.c - PCB layers on a pad
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <stdlib.h>
+
+#include "layer.h"
+
+
+layer_type pad_type_to_layers(enum pad_type type)
+{
+ layer_type layers = 0;
+
+ switch (type) {
+ case pt_normal:
+ layers = LAYER_PASTE;
+ /* fall through */
+ case pt_bare:
+ layers |= LAYER_COPPER | LAYER_MASK;
+ break;
+ case pt_paste:
+ layers = LAYER_PASTE;
+ break;
+ case pt_mask:
+ layers = LAYER_MASK;
+ break;
+ default:
+ abort();
+ }
+ return layers;
+}
+
+
+enum pad_type layers_to_pad_type(layer_type layers)
+{
+ if (layers & LAYER_COPPER) {
+ if (layers & LAYER_PASTE)
+ return pt_normal;
+ return pt_bare;
+ } else {
+ if (layers & LAYER_PASTE)
+ return pt_paste;
+ if (layers & LAYER_MASK)
+ return pt_mask;
+ abort();
+ }
+}
Added: trunk/eda/fped/layer.h
===================================================================
--- trunk/eda/fped/layer.h (rev 0)
+++ trunk/eda/fped/layer.h 2009-09-13 09:58:30 UTC (rev 5634)
@@ -0,0 +1,85 @@
+/*
+ * layer.h - PCB layers on a pad
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef LAYER_H
+#define LAYER_H
+
+#include <stdint.h>
+
+
+typedef uint32_t layer_type;
+
+
+enum kicad_layer {
+ layer_bottom, /* "copper" */
+ layer_l15,
+ layer_l14,
+ layer_l13,
+ layer_l12,
+ layer_l11,
+ layer_l10,
+ layer_l9,
+ layer_l8,
+ layer_l7,
+ layer_l6,
+ layer_l5,
+ layer_l4,
+ layer_l3,
+ layer_l2,
+ layer_top, /* "component" */
+ layer_glue_bottom, /* adhesive, copper side */
+ layer_glue_top, /* adhesive, component side */
+ layer_paste_bottom, /* solder paste */
+ layer_paste_top,
+ layer_silk_bottom, /* silk screen */
+ layer_silk_top,
+ layer_mask_bottom, /* solder mask */
+ layer_mask_top,
+ layer_draw, /* general drawing */
+ layer_comment,
+ layer_eco1,
+ layer_eco2,
+ layer_edge, /* edge */
+};
+
+
+enum pad_type {
+ pt_normal, /* copper and solder mask */
+ pt_bare, /* only copper (and finish) */
+ pt_paste, /* only solder paste */
+ pt_mask, /* only solder mask */
+ pt_n
+};
+
+
+/*
+ * Shorthands for the layers we use in a general sense.
+ */
+
+#define LAYER_COPPER (1 << layer_top)
+#define LAYER_PASTE (1 << layer_paste_top)
+#define LAYER_MASK (1 << layer_mask_top)
+
+
+/*
+ * pad_type_to_layers returns the initial set of layers. This set can then be
+ * modified by overlaying other pads. For display purposes, we translate back
+ * to the effective pad type with layers_to_pad_type.
+ *
+ * What this basically means is that pt_normal becomes pt_bare if its solder
+ * paste mask has been removed.
+ */
+
+layer_type pad_type_to_layers(enum pad_type type);
+enum pad_type layers_to_pad_type(layer_type layers);
+
+#endif /* !LAYER_H */
Modified: trunk/eda/fped/obj.h
===================================================================
--- trunk/eda/fped/obj.h 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/obj.h 2009-09-13 09:58:30 UTC (rev 5634)
@@ -20,6 +20,7 @@
#include "expr.h"
#include "coord.h"
#include "meas.h"
+#include "layer.h"
struct var {
@@ -139,14 +140,6 @@
ot_meas,
};
-enum pad_type {
- pt_normal, /* copper and solder mask */
- pt_bare, /* only copper (and finish) */
- pt_paste, /* only solder paste */
- pt_mask, /* only solder mask */
- pt_n
-};
-
struct frame_ref {
struct frame *ref;
int lineno;
Added: trunk/eda/fped/overlap.c
===================================================================
--- trunk/eda/fped/overlap.c (rev 0)
+++ trunk/eda/fped/overlap.c 2009-09-13 09:58:30 UTC (rev 5634)
@@ -0,0 +1,173 @@
+/*
+ * overlap.c - Test for overlaps
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include "coord.h"
+#include "obj.h"
+#include "inst.h"
+#include "overlap.h"
+
+
+/*
+ * @@@ result may be too optimistic if "b" is arounded pad.
+ */
+
+int inside(const struct inst *a, const struct inst *b)
+{
+ struct coord min_a, max_a;
+ struct coord min_b, max_b;
+
+ min_a = a->base;
+ max_a = a->u.pad.other;
+ sort_coord(&min_a, &max_a);
+
+ min_b = b->base;
+ max_b = b->u.pad.other;
+ sort_coord(&min_b, &max_b);
+
+ return min_a.x >= min_b.x && max_a.x <= max_b.x &&
+ min_a.y >= min_b.y && max_a.y <= max_b.y;
+}
+
+
+/* ----- Overlap test for primitives --------------------------------------- */
+
+
+struct shape {
+ int circle;
+ struct coord center;
+ unit_type r;
+ struct coord min, max;
+};
+
+
+static int circle_circle_overlap(struct coord c1, unit_type r1,
+ struct coord c2, unit_type r2)
+{
+ return dist_point(c1, c2) <= r1+r2;
+}
+
+
+static int circle_rect_overlap(struct coord c, unit_type r,
+ struct coord min, struct coord max)
+{
+ if (c.x < min.x-r || c.x > max.x+r)
+ return 0;
+ if (c.y < min.y-r || c.y > max.y+r)
+ return 0;
+ return 1;
+}
+
+
+static int rect_rect_overlap(struct coord min1, struct coord max1,
+ struct coord min2, struct coord max2)
+{
+ if (max1.x < min2.x || max2.x < min1.x)
+ return 0;
+ if (max1.y < min2.y || max2.y < min1.y)
+ return 0;
+ return 1;
+}
+
+
+static int shapes_overlap(const struct shape *a, const struct shape *b)
+{
+ if (a->circle && !b->circle)
+ return shapes_overlap(b, a);
+ if (a->circle) /* b must be circle, too */
+ return circle_circle_overlap(a->center, a->r, b->center, b->r);
+ if (b->circle) /* a must be rect */
+ return circle_rect_overlap(b->center, b->r, a->min, a->max);
+ return rect_rect_overlap(a->min, a->max, b->min, b->max);
+}
+
+
+/* ----- Recursive overlap tester ------------------------------------------ */
+
+
+static int test_overlap(const struct inst *a, const struct inst *b,
+ const struct shape *other);
+
+
+static int do_circle(const struct inst *next, const struct shape *other,
+ unit_type x, unit_type y, unit_type r)
+{
+ struct shape shape = {
+ .circle = 1,
+ .center = {
+ .x = x,
+ .y = y,
+ },
+ .r = r,
+ };
+
+ if (next)
+ return test_overlap(next, NULL, &shape);
+ return shapes_overlap(other, &shape);
+}
+
+
+static int do_rect(const struct inst *next, const struct shape *other,
+ unit_type x, unit_type y, unit_type w, unit_type h)
+{
+ struct shape shape = {
+ .circle = 0,
+ .min = {
+ .x = x,
+ .y = y,
+ },
+ .max = {
+ .x = x+w,
+ .y = y+w,
+ },
+ };
+
+ if (next)
+ return test_overlap(next, NULL, &shape);
+ return shapes_overlap(other, &shape);
+}
+
+
+static int test_overlap(const struct inst *a, const struct inst *b,
+ const struct shape *other)
+{
+ struct coord min, max;
+ unit_type h, w, r;
+
+ min = a->base;
+ max = a->u.pad.other;
+ sort_coord(&min, &max);
+
+ h = max.y-min.y;
+ w = max.x-min.x;
+
+ if (!a->obj->u.pad.rounded)
+ return do_rect(b, other, min.x, min.y, w, h);
+
+ if (h > w) {
+ r = w/2;
+ return do_circle(b, other, min.x+r, max.y-r, r) ||
+ do_rect(b, other, min.x, min.y+r, w, h-2*r) ||
+ do_circle(b, other, min.x+r, min.y+r, r);
+ } else {
+ r = h/2;
+ return do_circle(b, other, min.x+r, max.y+r, r) ||
+ do_rect(b, other, min.x+r, min.y, w-2*r, h) ||
+ do_circle(b, other, min.x-r, min.y+r, r);
+ }
+}
+
+
+int overlap(const struct inst *a, const struct inst *b)
+{
+ return test_overlap(a, b, NULL);
+}
Added: trunk/eda/fped/overlap.h
===================================================================
--- trunk/eda/fped/overlap.h (rev 0)
+++ trunk/eda/fped/overlap.h 2009-09-13 09:58:30 UTC (rev 5634)
@@ -0,0 +1,32 @@
+/*
+ * overlap.h - Test for overlaps
+ *
+ * Written 2009 by Werner Almesberger
+ * Copyright 2009 by Werner Almesberger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef OVERLAP_H
+#define OVERLAP_H
+
+#include "inst.h"
+
+
+/*
+ * "inside" returns 1 if "a" is completely enclosed by "b". If "a" == "b",
+ * that also counts as "a" being inside "b".
+ */
+
+int inside(const struct inst *a, const struct inst *b);
+
+/*
+ * "overlap" returns 1 if "a" and "b" have at least one point in common.
+ */
+
+int overlap(const struct inst *a, const struct inst *b);
+
+#endif /* !OVERLAP_H */
Modified: trunk/eda/fped/postscript.c
===================================================================
--- trunk/eda/fped/postscript.c 2009-09-12 23:15:15 UTC (rev 5633)
+++ trunk/eda/fped/postscript.c 2009-09-13 09:58:30 UTC (rev 5634)
@@ -16,6 +16,7 @@
#include "util.h"
#include "coord.h"
+#include "layer.h"
#include "obj.h"
#include "inst.h"
#include "unparse.h"
@@ -189,9 +190,9 @@
}
-static const char *hatch(enum pad_type type)
+static const char *hatch(layer_type layers)
{
- switch (type) {
+ switch (layers_to_pad_type(layers)) {
case pt_normal:
return "crosspath";
case pt_bare:
@@ -217,7 +218,7 @@
fprintf(file, " %d %d lineto\n", b.x, b.y);
fprintf(file, " %d %d lineto\n", a.x, b.y);
fprintf(file, " closepath gsave %s grestore stroke\n",
- hatch(inst->obj->u.pad.type));
+ hatch(inst->u.pad.layers));
if (show_name)
ps_pad_name(file, inst);
@@ -248,7 +249,7 @@
fprintf(file, " %d %d %d 90 270 arc\n", a.x+r, a.y+r, r);
}
fprintf(file, " closepath gsave %s grestore stroke\n",
- hatch(inst->obj->u.pad.type));
+ hatch(inst->u.pad.layers));
if (show_name)
ps_pad_name(file, inst);
More information about the commitlog
mailing list