1
0
mirror of git://projects.qi-hardware.com/fped.git synced 2024-11-04 23:55:54 +02:00

- 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)



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5634 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-09-13 09:58:30 +00:00
parent c91156aac0
commit 8df866ab2f
11 changed files with 374 additions and 87 deletions

View File

@ -16,6 +16,7 @@ UPLOAD = werner@sita.openmoko.org:public_html/fped/
OBJS = fped.o expr.o coord.o obj.o delete.o inst.o util.o error.o \ 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 \ unparse.o file.o dump.o kicad.o postscript.o meas.o \
layer.o overlap.o \
cpp.o lex.yy.o y.tab.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.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 gui_tool.o gui_over.o gui_meas.o gui_frame.o

View File

@ -107,7 +107,7 @@ static void draw_arrow(GdkGC *gc, int fill,
} }
static enum mode get_mode(struct inst *self) static enum mode get_mode(const struct inst *self)
{ {
if (selected_inst == self) if (selected_inst == self)
return mode_selected; return mode_selected;
@ -257,23 +257,26 @@ static void gui_draw_pad_text(struct inst *self)
} }
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) void gui_draw_pad(struct inst *self)
{ {
struct coord min = translate(self->base); struct coord min = translate(self->base);
struct coord max = translate(self->u.pad.other); struct coord max = translate(self->u.pad.other);
GdkGC *gc; GdkGC *gc;
switch (self->obj->u.pad.type) { gc = pad_gc(self);
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;
}
sort_coord(&min, &max); sort_coord(&min, &max);
gdk_draw_rectangle(DA, gc, TRUE, gdk_draw_rectangle(DA, gc, TRUE,
min.x, min.y, max.x-min.x, max.y-min.y); min.x, min.y, max.x-min.x, max.y-min.y);
@ -289,17 +292,7 @@ void gui_draw_rpad(struct inst *self)
GdkGC *gc; GdkGC *gc;
unit_type h, w, r; unit_type h, w, r;
switch (self->obj->u.pad.type) { gc = pad_gc(self);
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;
}
sort_coord(&min, &max); sort_coord(&min, &max);
h = max.y-min.y; h = max.y-min.y;
w = max.x-min.x; w = max.x-min.x;

2
inst.c
View File

@ -18,6 +18,7 @@
#include "util.h" #include "util.h"
#include "coord.h" #include "coord.h"
#include "expr.h" #include "expr.h"
#include "layer.h"
#include "obj.h" #include "obj.h"
#include "delete.h" #include "delete.h"
#include "gui_util.h" #include "gui_util.h"
@ -802,6 +803,7 @@ int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord b)
inst->obj = obj; inst->obj = obj;
inst->u.pad.name = stralloc(name); inst->u.pad.name = stralloc(name);
inst->u.pad.other = b; inst->u.pad.other = b;
inst->u.pad.layers = pad_type_to_layers(obj->u.pad.type);
update_bbox(&inst->bbox, b); update_bbox(&inst->bbox, b);
propagate_bbox(inst); propagate_bbox(inst);
return 1; return 1;

2
inst.h
View File

@ -14,6 +14,7 @@
#ifndef INST_H #ifndef INST_H
#define INST_H #define INST_H
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include "coord.h" #include "coord.h"
@ -95,6 +96,7 @@ struct inst {
struct { struct {
char *name; char *name;
struct coord other; struct coord other;
layer_type layers; /* bit-set of layers */
} pad; } pad;
struct { struct {
unit_type r; unit_type r;

53
kicad.c
View File

@ -20,44 +20,10 @@
#include "kicad.h" #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) static void kicad_pad(FILE *file, const struct inst *inst)
{ {
struct coord min, max; struct coord min, max;
unit_type tmp; unit_type tmp;
int layers;
min.x = units_to_kicad(inst->base.x); min.x = units_to_kicad(inst->base.x);
min.y = units_to_kicad(inst->base.y); min.y = units_to_kicad(inst->base.y);
@ -87,24 +53,7 @@ static void kicad_pad(FILE *file, const struct inst *inst)
/* /*
* Attributes: pad type, N, layer mask * Attributes: pad type, N, layer mask
*/ */
layers = 0; fprintf(file, "At SMD N %8.8X\n", (unsigned) inst->u.pad.layers);
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);
/* /*
* Position: Xpos, Ypos * Position: Xpos, Ypos

56
layer.c Normal file
View File

@ -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();
}
}

85
layer.h Normal file
View File

@ -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 */

9
obj.h
View File

@ -20,6 +20,7 @@
#include "expr.h" #include "expr.h"
#include "coord.h" #include "coord.h"
#include "meas.h" #include "meas.h"
#include "layer.h"
struct var { struct var {
@ -139,14 +140,6 @@ enum obj_type {
ot_meas, 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 {
struct frame *ref; struct frame *ref;
int lineno; int lineno;

173
overlap.c Normal file
View File

@ -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);
}

32
overlap.h Normal file
View File

@ -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 */

View File

@ -16,6 +16,7 @@
#include "util.h" #include "util.h"
#include "coord.h" #include "coord.h"
#include "layer.h"
#include "obj.h" #include "obj.h"
#include "inst.h" #include "inst.h"
#include "unparse.h" #include "unparse.h"
@ -189,9 +190,9 @@ static void ps_pad_name(FILE *file, const struct inst *inst)
} }
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: case pt_normal:
return "crosspath"; return "crosspath";
case pt_bare: case pt_bare:
@ -217,7 +218,7 @@ static void ps_pad(FILE *file, const struct inst *inst, int show_name)
fprintf(file, " %d %d lineto\n", b.x, b.y); fprintf(file, " %d %d lineto\n", b.x, b.y);
fprintf(file, " %d %d lineto\n", a.x, b.y); fprintf(file, " %d %d lineto\n", a.x, b.y);
fprintf(file, " closepath gsave %s grestore stroke\n", fprintf(file, " closepath gsave %s grestore stroke\n",
hatch(inst->obj->u.pad.type)); hatch(inst->u.pad.layers));
if (show_name) if (show_name)
ps_pad_name(file, inst); ps_pad_name(file, inst);
@ -248,7 +249,7 @@ static void ps_rpad(FILE *file, const struct inst *inst, int show_name)
fprintf(file, " %d %d %d 90 270 arc\n", a.x+r, a.y+r, r); fprintf(file, " %d %d %d 90 270 arc\n", a.x+r, a.y+r, r);
} }
fprintf(file, " closepath gsave %s grestore stroke\n", fprintf(file, " closepath gsave %s grestore stroke\n",
hatch(inst->obj->u.pad.type)); hatch(inst->u.pad.layers));
if (show_name) if (show_name)
ps_pad_name(file, inst); ps_pad_name(file, inst);