static void ghid_draw_grid (void) { static GdkPoint *points = 0; static int npoints = 0; int x1, y1, x2, y2, n, i; double x, y; if (!Settings.DrawGrid) return; if (Vz (PCB->Grid) < MIN_GRID_DISTANCE) return; if (!gport->grid_gc) { if (gdk_color_parse (Settings.GridColor, &gport->grid_color)) { gport->grid_color.red ^= gport->bg_color.red; gport->grid_color.green ^= gport->bg_color.green; gport->grid_color.blue ^= gport->bg_color.blue; gdk_color_alloc (gport->colormap, &gport->grid_color); } gport->grid_gc = gdk_gc_new (gport->drawable); gdk_gc_set_function (gport->grid_gc, GDK_XOR); gdk_gc_set_foreground (gport->grid_gc, &gport->grid_color); } x1 = GRIDFIT_X (SIDE_X (gport->view_x0), PCB->Grid); y1 = GRIDFIT_Y (SIDE_Y (gport->view_y0), PCB->Grid); x2 = GRIDFIT_X (SIDE_X (gport->view_x0 + gport->view_width - 1), PCB->Grid); y2 = GRIDFIT_Y (SIDE_Y (gport->view_y0 + gport->view_height - 1), PCB->Grid); if (x1 > x2) { int tmp = x1; x1 = x2; x2 = tmp; } if (y1 > y2) { int tmp = y1; y1 = y2; y2 = tmp; } if (Vx (x1) < 0) x1 += PCB->Grid; if (Vy (y1) < 0) y1 += PCB->Grid; if (Vx (x2) >= gport->width) x2 -= PCB->Grid; if (Vy (y2) >= gport->height) y2 -= PCB->Grid; n = (int) ((x2 - x1) / PCB->Grid + 0.5) + 1; if (n > npoints) { npoints = n + 10; points = (GdkPoint *)realloc (points, npoints * sizeof (GdkPoint)); } n = 0; for (x = x1; x <= x2; x += PCB->Grid) { points[n].x = Vx (x); n++; } if (n == 0) return; for (y = y1; y <= y2; y += PCB->Grid) { int vy = Vy (y); for (i = 0; i < n; i++) points[i].y = vy; gdk_draw_points (gport->drawable, gport->grid_gc, points, n); } }
/* --------------------------------------------------------------------------- * recalculates the passed coordinates to fit the current grid setting */ void FitCrosshairIntoGrid (LocationType X, LocationType Y) { LocationType x2, y2, x0, y0; void *ptr1, *ptr2, *ptr3; float nearest, sq_dist; int ans; x0 = 0; y0 = 0; x2 = PCB->MaxWidth; y2 = PCB->MaxHeight; Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X)); Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y)); if (PCB->RatDraw) { x0 = -600; y0 = -600; } else { /* check if new position is inside the output window * This might not be true after the window has been resized. * In this case we just set it to the center of the window or * with respect to the grid (if possible) */ if (Crosshair.X < x0 || Crosshair.X > x2) { if (x2 + 1 >= PCB->Grid) /* there must be a point that matches the grid * so we just have to look for it with some integer * calculations */ x0 = GRIDFIT_X (PCB->Grid, PCB->Grid); else x0 = (x2) / 2; } else /* check if the new position matches the grid */ x0 = GRIDFIT_X (Crosshair.X, PCB->Grid); /* do the same for the second coordinate */ if (Crosshair.Y < y0 || Crosshair.Y > y2) { if (y2 + 1 >= PCB->Grid) y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid); else y0 = (y2) / 2; } else y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid); if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB)) { int dx = Crosshair.X - Marked.X; int dy = Crosshair.Y - Marked.Y; if (ABS (dx) > ABS (dy)) y0 = Marked.Y; else x0 = Marked.X; } } nearest = -1; if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, PAD_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; /* Avoid self-snapping when moving */ if (ans && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans && (Settings.Mode == LINE_MODE || (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE))) { PadTypePtr pad = (PadTypePtr) ptr2; LayerType *desired_layer; Cardinal desired_group; Cardinal SLayer, CLayer; int found_our_layer = false; desired_layer = CURRENT; if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == LINEPOINT_TYPE) { desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1; } /* find layer groups of the component side and solder side */ SLayer = GetLayerGroupNumberByNumber (solder_silk_layer); CLayer = GetLayerGroupNumberByNumber (component_silk_layer); desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? SLayer : CLayer; GROUP_LOOP (PCB->Data, desired_group); { if (layer == desired_layer) { found_our_layer = true; break; } } END_LOOP; if (found_our_layer == false) ans = NO_TYPE; } if (ans) { PadTypePtr pad = (PadTypePtr) ptr2; LocationType px, py; px = (pad->Point1.X + pad->Point2.X) / 2; py = (pad->Point1.Y + pad->Point2.Y) / 2; sq_dist = SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y); if (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist) { x0 = px; y0 = py; nearest = sq_dist; } } if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, PIN_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; /* Avoid self-snapping when moving */ if (ans && Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == ELEMENT_TYPE && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; if (ans) { PinTypePtr pin = (PinTypePtr) ptr2; sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pin->X; y0 = pin->Y; nearest = sq_dist; } } if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, VIA_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; /* Avoid snapping vias to any other vias */ if (Settings.Mode == MOVE_MODE && Crosshair.AttachedObject.Type == VIA_TYPE) { if (ans & PIN_TYPES) ans = NO_TYPE; } if (ans) { PinTypePtr pin = (PinTypePtr) ptr2; sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pin->X; y0 = pin->Y; nearest = sq_dist; } } if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; if (ans) { PointTypePtr pnt = (PointTypePtr) ptr3; sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pnt->X; y0 = pnt->Y; nearest = sq_dist; } } if (TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; if (ans) { PointTypePtr pnt = (PointTypePtr) ptr3; sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && (!gui->shift_is_pressed() || SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)) { x0 = pnt->X; y0 = pnt->Y; nearest = sq_dist; } } if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); else ans = NO_TYPE; if (ans & ELEMENT_TYPE) { ElementTypePtr el = (ElementTypePtr) ptr1; sq_dist = SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y); if ((nearest == -1 || sq_dist < nearest) && SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist) { x0 = el->MarkX; y0 = el->MarkY; nearest = sq_dist; } } if (x0 >= 0 && y0 >= 0) { Crosshair.X = x0; Crosshair.Y = y0; } if (Settings.Mode == ARROW_MODE) { ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE) hid_action("PointCursor"); else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2)) hid_actionl("PointCursor","True", NULL); } if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST && TEST_FLAG (AUTODRCFLAG, PCB)) EnforceLineDRC (); gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING); }
/* --------------------------------------------------------------------------- * recalculates the passed coordinates to fit the current grid setting */ void FitCrosshairIntoGrid (LocationType X, LocationType Y) { LocationType x2, y2, x0, y0; void *ptr1, *ptr2, *ptr3; int ans; x0 = 0; y0 = 0; x2 = PCB->MaxWidth; y2 = PCB->MaxHeight; Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X)); Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y)); if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB)) { ans = SearchScreen (Crosshair.X, Crosshair.Y, PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE && !PCB->RatDraw) ans = SearchScreen (Crosshair.X, Crosshair.Y, VIA_TYPE | LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE && !PCB->RatDraw) ans = SearchScreen (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2, &ptr3); } else ans = NO_TYPE; /* avoid self-snapping */ if (Settings.Mode == MOVE_MODE) { switch (Crosshair.AttachedObject.Type) { case ELEMENT_TYPE: if ((ans & (PAD_TYPE | PIN_TYPE)) && ptr1 == Crosshair.AttachedObject.Ptr1) ans = NO_TYPE; break; case VIA_TYPE: /* just avoid snapping to any other vias */ if (ans & PIN_TYPES) ans = NO_TYPE; break; } } if (PCB->RatDraw) { x0 = -600; y0 = -600; } else { /* check if new position is inside the output window * This might not be true after the window has been resized. * In this case we just set it to the center of the window or * with respect to the grid (if possible) */ if (Crosshair.X < x0 || Crosshair.X > x2) { if (x2 + 1 >= PCB->Grid) /* there must be a point that matches the grid * so we just have to look for it with some integer * calculations */ x0 = GRIDFIT_X (PCB->Grid, PCB->Grid); else x0 = (x2) / 2; } else /* check if the new position matches the grid */ x0 = GRIDFIT_X (Crosshair.X, PCB->Grid); /* do the same for the second coordinate */ if (Crosshair.Y < y0 || Crosshair.Y > y2) { if (y2 + 1 >= PCB->Grid) y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid); else y0 = (y2) / 2; } else y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid); if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB)) { int dx = Crosshair.X - Marked.X; int dy = Crosshair.Y - Marked.Y; if (ABS (dx) > ABS (dy)) y0 = Marked.Y; else x0 = Marked.X; } } if (ans & PAD_TYPE) { PadTypePtr pad = (PadTypePtr) ptr2; LocationType px, py; px = (pad->Point1.X + pad->Point2.X) / 2; py = (pad->Point1.Y + pad->Point2.Y) / 2; if (!gui->shift_is_pressed() || (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y))) { x0 = px; y0 = py; } } else if (ans & (PIN_TYPE | VIA_TYPE)) { PinTypePtr pin = (PinTypePtr) ptr2; if (!gui->shift_is_pressed() || (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y))) { x0 = pin->X; y0 = pin->Y; } } else if (ans & LINEPOINT_TYPE) { PointTypePtr pnt = (PointTypePtr) ptr3; if (((x0 - Crosshair.X) * (x0 - Crosshair.X) + (y0 - Crosshair.Y) * (y0 - Crosshair.Y)) > ((pnt->X - Crosshair.X) * (pnt->X - Crosshair.X) + (pnt->Y - Crosshair.Y) * (pnt->Y - Crosshair.Y))) { x0 = pnt->X; y0 = pnt->Y; } } else if (ans & ELEMENT_TYPE) { ElementTypePtr el = (ElementTypePtr) ptr1; if (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y)) { x0 = el->MarkX; y0 = el->MarkY; } } if (x0 >= 0 && y0 >= 0) { Crosshair.X = x0; Crosshair.Y = y0; } if (Settings.Mode == ARROW_MODE) { ans = SearchScreen (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3); if (ans == NO_TYPE) hid_action("PointCursor"); else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2)) hid_actionl("PointCursor","True", NULL); } if (Settings.Mode == LINE_MODE && Crosshair.AttachedLine.State != STATE_FIRST && TEST_FLAG (AUTODRCFLAG, PCB)) EnforceLineDRC (); gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING); }