mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-12-22 22:52:25 +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:
parent
c91156aac0
commit
8df866ab2f
1
Makefile
1
Makefile
@ -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 \
|
||||
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
|
||||
|
39
gui_inst.c
39
gui_inst.c
@ -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)
|
||||
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)
|
||||
{
|
||||
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 @@ void gui_draw_rpad(struct inst *self)
|
||||
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;
|
||||
|
2
inst.c
2
inst.c
@ -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 @@ int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord b)
|
||||
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;
|
||||
|
2
inst.h
2
inst.h
@ -14,6 +14,7 @@
|
||||
#ifndef INST_H
|
||||
#define INST_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "coord.h"
|
||||
@ -95,6 +96,7 @@ struct inst {
|
||||
struct {
|
||||
char *name;
|
||||
struct coord other;
|
||||
layer_type layers; /* bit-set of layers */
|
||||
} pad;
|
||||
struct {
|
||||
unit_type r;
|
||||
|
53
kicad.c
53
kicad.c
@ -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 @@ static void kicad_pad(FILE *file, const struct inst *inst)
|
||||
/*
|
||||
* 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
|
||||
|
56
layer.c
Normal file
56
layer.c
Normal 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
85
layer.h
Normal 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
9
obj.h
@ -20,6 +20,7 @@
|
||||
#include "expr.h"
|
||||
#include "coord.h"
|
||||
#include "meas.h"
|
||||
#include "layer.h"
|
||||
|
||||
|
||||
struct var {
|
||||
@ -139,14 +140,6 @@ enum obj_type {
|
||||
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;
|
||||
|
173
overlap.c
Normal file
173
overlap.c
Normal 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
32
overlap.h
Normal 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 */
|
@ -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 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:
|
||||
return "crosspath";
|
||||
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", 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 @@ 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, " 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);
|
||||
|
Loading…
Reference in New Issue
Block a user