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