static void fill_clipped_contour (hidGC gc, PLINE *pl, const BoxType *clip_box) { PLINE *pl_copy; POLYAREA *clip_poly; POLYAREA *piece_poly; POLYAREA *clipped_pieces; POLYAREA *draw_piece; int x; clip_poly = RectPoly (clip_box->X1, clip_box->X2, clip_box->Y1, clip_box->Y2); poly_CopyContour (&pl_copy, pl); piece_poly = poly_Create (); poly_InclContour (piece_poly, pl_copy); x = poly_Boolean_free (piece_poly, clip_poly, &clipped_pieces, PBO_ISECT); if (x != err_ok || clipped_pieces == NULL) return; draw_piece = clipped_pieces; do { /* NB: The polygon won't have any holes in it */ fill_contour (gc, draw_piece->contours); } while ((draw_piece = draw_piece->f) != clipped_pieces); poly_Free (&clipped_pieces); }
static POLYAREA * oct_therm (PinTypePtr pin, Cardinal style) { POLYAREA *p, *p2, *m; Coord t = 0.5 * pcb->ThermScale * pin->Clearance; Coord w = pin->Thickness + pin->Clearance; p = OctagonPoly (pin->X, pin->Y, w); p2 = OctagonPoly (pin->X, pin->Y, pin->Thickness); /* make full clearance ring */ poly_Boolean_free (p, p2, &m, PBO_SUB); switch (style) { default: case 1: p = diag_line (pin->X, pin->Y, w, t, true); poly_Boolean_free (m, p, &p2, PBO_SUB); p = diag_line (pin->X, pin->Y, w, t, false); poly_Boolean_free (p2, p, &m, PBO_SUB); return m; case 2: p = RectPoly (pin->X - t, pin->X + t, pin->Y - w, pin->Y + w); poly_Boolean_free (m, p, &p2, PBO_SUB); p = RectPoly (pin->X - w, pin->X + w, pin->Y - t, pin->Y + t); poly_Boolean_free (p2, p, &m, PBO_SUB); return m; /* fix me add thermal style 4 */ case 5: { Coord t = pin->Thickness / 2; POLYAREA *q; /* cheat by using the square therm's rounded parts */ p = square_therm (pin, style); q = RectPoly (pin->X - t, pin->X + t, pin->Y - t, pin->Y + t); poly_Boolean_free (p, q, &p2, PBO_UNITE); poly_Boolean_free (m, p2, &p, PBO_ISECT); return p; } } }
/* ThermPoly returns a POLYAREA having all of the clearance that when * subtracted from the plane create the desired thermal fingers. * Usually this is 4 disjoint regions. * */ POLYAREA * ThermPoly (PCBTypePtr p, PinTypePtr pin, Cardinal laynum) { ArcType a; POLYAREA *pa, *arc; Cardinal style = GET_THERM (laynum, pin); if (style == 3) return NULL; /* solid connection no clearance */ pcb = p; if (TEST_FLAG (SQUAREFLAG, pin)) return square_therm (pin, style); if (TEST_FLAG (OCTAGONFLAG, pin)) return oct_therm (pin, style); /* must be circular */ switch (style) { case 1: case 2: { POLYAREA *m; Coord t = (pin->Thickness + pin->Clearance) / 2; Coord w = 0.5 * pcb->ThermScale * pin->Clearance; pa = CirclePoly (pin->X, pin->Y, t); arc = CirclePoly (pin->X, pin->Y, pin->Thickness / 2); /* create a thin ring */ poly_Boolean_free (pa, arc, &m, PBO_SUB); /* fix me needs error checking */ if (style == 2) { /* t is the theoretically required length, but we use twice that * to avoid descritisation errors in our circle approximation. */ pa = RectPoly (pin->X - t * 2, pin->X + t * 2, pin->Y - w, pin->Y + w); poly_Boolean_free (m, pa, &arc, PBO_SUB); pa = RectPoly (pin->X - w, pin->X + w, pin->Y - t * 2, pin->Y + t * 2); } else { /* t is the theoretically required length, but we use twice that * to avoid descritisation errors in our circle approximation. */ pa = diag_line (pin->X, pin->Y, t * 2, w, true); poly_Boolean_free (m, pa, &arc, PBO_SUB); pa = diag_line (pin->X, pin->Y, t * 2, w, false); } poly_Boolean_free (arc, pa, &m, PBO_SUB); return m; } default: a.X = pin->X; a.Y = pin->Y; a.Height = a.Width = pin->Thickness / 2 + pin->Clearance / 4; a.Thickness = 1; a.Clearance = pin->Clearance / 2; a.Flags = NoFlags (); a.Delta = 90 - (a.Clearance * (1. + 2. * pcb->ThermScale) * 180) / (M_PI * a.Width); a.StartAngle = 90 - a.Delta / 2 + (style == 4 ? 0 : 45); pa = ArcPoly (&a, a.Clearance); if (!pa) return NULL; a.StartAngle += 90; arc = ArcPoly (&a, a.Clearance); if (!arc) return NULL; pa->f = arc; arc->b = pa; a.StartAngle += 90; arc = ArcPoly (&a, a.Clearance); if (!arc) return NULL; pa->f->f = arc; arc->b = pa->f; a.StartAngle += 90; arc = ArcPoly (&a, a.Clearance); if (!arc) return NULL; pa->b = arc; pa->f->f->f = arc; arc->b = pa->f->f; arc->f = pa; pa->b = arc; return pa; } }