Index: trunk/src/obj_arc.c =================================================================== --- trunk/src/obj_arc.c (revision 14720) +++ trunk/src/obj_arc.c (revision 14721) @@ -282,11 +282,11 @@ return 1; } -unsigned int pcb_subc_arc_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_arc_t *a) +unsigned int pcb_arc_hash(const pcb_host_trans_t *tr, const pcb_arc_t *a) { unsigned int crd = 0; if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, a)) - crd = pcb_hash_coord(a->X-ox) ^ pcb_hash_coord(a->Y-oy); + crd = pcb_hash_cx(tr, a->X) ^ pcb_hash_cy(tr, a->Y); return pcb_hash_coord(a->Thickness) ^ pcb_hash_coord(a->Clearance) ^ Index: trunk/src/obj_arc.h =================================================================== --- trunk/src/obj_arc.h (revision 14720) +++ trunk/src/obj_arc.h (revision 14721) @@ -67,7 +67,7 @@ /*** hash ***/ int pcb_arc_eq(const pcb_element_t *e1, const pcb_arc_t *a1, const pcb_element_t *e2, const pcb_arc_t *a2); -unsigned int pcb_subc_arc_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_arc_t *a); +unsigned int pcb_arc_hash(const pcb_host_trans_t *tr, const pcb_arc_t *a); /* Return the x;y coordinate of the endpoint of an arc; if which is 0, return Index: trunk/src/obj_common.h =================================================================== --- trunk/src/obj_common.h (revision 14720) +++ trunk/src/obj_common.h (revision 14721) @@ -93,6 +93,15 @@ int pcb_obj_get_bbox(int Type, void *Ptr1, void *Ptr2, void *Ptr3, pcb_box_t *res); +/* Host transformations: typically the transformations an object of a subc + inherits from the subc */ +typedef struct pcb_host_trans_s { + pcb_coord_t ox, oy; + int on_bottom; + double rot; + double cosa, sina; /* rot angle cache */ +} pcb_host_trans_t; + /* memset object to 0, but keep the link field */ #define reset_obj_mem(type, obj) \ do { \ @@ -169,6 +178,18 @@ return murmurhash(&(c), sizeof(pcb_coord_t)); } +PCB_INLINE unsigned pcb_hash_cx(const pcb_host_trans_t *tr, pcb_coord_t c) +{ + c -= tr->ox; + return murmurhash(&(c), sizeof(pcb_coord_t)); +} + +PCB_INLINE unsigned pcb_hash_cy(const pcb_host_trans_t *tr, pcb_coord_t c) +{ + c -= tr->oy; + return murmurhash(&(c), sizeof(pcb_coord_t)); +} + /* Return the geometric center of an object, as shown (center of bbox usually, but not for an arc) */ void pcb_obj_center(const pcb_any_obj_t *obj, pcb_coord_t *x, pcb_coord_t *y); Index: trunk/src/obj_line.c =================================================================== --- trunk/src/obj_line.c (revision 14720) +++ trunk/src/obj_line.c (revision 14721) @@ -281,12 +281,12 @@ } -unsigned int pcb_subc_line_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_line_t *l) +unsigned int pcb_line_hash(const pcb_host_trans_t *tr, const pcb_line_t *l) { unsigned int crd = 0; if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, l)) - crd = pcb_hash_coord(l->Point1.X-ox) ^ pcb_hash_coord(l->Point1.Y-oy) ^ - pcb_hash_coord(l->Point2.X-ox) ^ pcb_hash_coord(l->Point2.Y-oy); + crd = pcb_hash_cx(tr, l->Point1.X) ^ pcb_hash_cy(tr, l->Point1.Y) ^ + pcb_hash_cx(tr, l->Point2.X) ^ pcb_hash_cy(tr, l->Point2.Y); return pcb_hash_coord(l->Thickness) ^ pcb_hash_coord(l->Clearance) ^ pcb_hash_str(l->term) ^ crd; Index: trunk/src/obj_line.h =================================================================== --- trunk/src/obj_line.h (revision 14720) +++ trunk/src/obj_line.h (revision 14721) @@ -75,7 +75,7 @@ /* hash */ int pcb_line_eq(const pcb_element_t *e1, const pcb_line_t *l1, const pcb_element_t *e2, const pcb_line_t *l2); -unsigned int pcb_subc_line_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_line_t *l); +unsigned int pcb_line_hash(const pcb_host_trans_t *tr, const pcb_line_t *l); /*** DRC enforcement (obj_line_drcenf.c) ***/ Index: trunk/src/obj_poly.c =================================================================== --- trunk/src/obj_poly.c (revision 14720) +++ trunk/src/obj_poly.c (revision 14721) @@ -209,7 +209,7 @@ } #endif -unsigned int pcb_subc_poly_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_poly_t *p) +unsigned int pcb_subc_poly_hash(const pcb_host_trans_t *tr, const pcb_poly_t *p) { unsigned int crd = 0; pcb_cardinal_t n; @@ -216,7 +216,7 @@ if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, p)) for(n = 0; n < p->PointN; n++) - crd ^= pcb_hash_coord(p->Points[n].X-ox) ^ pcb_hash_coord(p->Points[n].Y-oy); + crd ^= pcb_hash_cx(tr, p->Points[n].X) ^ pcb_hash_cy(tr, p->Points[n].Y); return pcb_hash_coord(p->Clearance) ^ pcb_hash_str(p->term) ^ crd; } Index: trunk/src/obj_poly.h =================================================================== --- trunk/src/obj_poly.h (revision 14720) +++ trunk/src/obj_poly.h (revision 14721) @@ -77,7 +77,7 @@ pcb_poly_t *pcb_poly_copy(pcb_poly_t *Dest, pcb_poly_t *Src, pcb_coord_t dx, pcb_coord_t dy); /* hash */ -unsigned int pcb_subc_poly_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_poly_t *p); +unsigned int pcb_poly_hash(const pcb_host_trans_t *tr, const pcb_poly_t *p); /* Add objects without creating them or making any "sanity modifications" to them */ void pcb_add_poly_on_layer(pcb_layer_t *Layer, pcb_poly_t *polygon); Index: trunk/src/obj_text.c =================================================================== --- trunk/src/obj_text.c (revision 14720) +++ trunk/src/obj_text.c (revision 14721) @@ -343,11 +343,11 @@ } #endif -unsigned int pcb_subc_text_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_text_t *t) +unsigned int pcb_text_hash(const pcb_host_trans_t *tr, const pcb_text_t *t) { unsigned int crd = 0; if (!PCB_FLAG_TEST(PCB_FLAG_FLOATER, t)) - crd = pcb_hash_coord(t->X-ox) ^ pcb_hash_coord(t->Y-oy) ^ pcb_hash_coord(t->Scale); + crd = pcb_hash_cx(tr, t->X) ^ pcb_hash_cy(tr, t->Y) ^ pcb_hash_coord(t->Scale); return pcb_hash_str(t->TextString) ^ pcb_hash_str(t->term) ^ crd; } Index: trunk/src/obj_text.h =================================================================== --- trunk/src/obj_text.h (revision 14720) +++ trunk/src/obj_text.h (revision 14721) @@ -73,7 +73,7 @@ void pcb_text_dyn_bbox_update(pcb_data_t *data); /* hash */ -unsigned int pcb_subc_text_hash(pcb_coord_t ox, pcb_coord_t oy, const pcb_text_t *t); +unsigned int pcb_text_hash(const pcb_host_trans_t *tr, const pcb_text_t *t); /* Append dyntext fmt rendered from the perspective of obj */ int pcb_append_dyntext(gds_t *dst, pcb_any_obj_t *obj, const char *fmt);