Graphical interface

The reasitic.gui package re-exports a few names at the top level (run, Viewport, the colour helpers); see the submodule pages below for the full surface.

Pan / zoom viewport math for the layout view.

Mirrors the world↔screen transformation used by the original ASITIC X11 front-end (see decomp/output/asitic_repl.c lines ~6920 / 21800):

/* world coords (μm) → screen coords (px) */
sx =  (wx + g_pan_x) * g_zoom_scale + g_x11_canvas_width  / 2
sy = -(wy + g_pan_y) * g_zoom_scale + g_x11_canvas_height / 2

The screen Y axis points down, the world Y axis points up, hence the sign flip on the Y term. The transformation is implemented here with no Tkinter dependency so that it can be unit-tested headlessly.

class reasitic.gui.viewport.Viewport[source]

Bases: object

A 2-D pan/zoom transform from layout (μm) to canvas (px) coordinates.

Mirrors the binary’s view-state globals: zoom is g_zoom_scale and pan_x / pan_y are g_pan_x / g_pan_y. canvas_width / canvas_height track the live canvas widget size in pixels (the binary uses g_x11_canvas_width / g_x11_canvas_height).

canvas_width: int = 800
canvas_height: int = 600
zoom: float = 1.0
pan_x: float = 0.0
pan_y: float = 0.0
world_to_screen(wx, wy)[source]

Map a world-space (μm) point to canvas pixel coordinates.

Parameters:
Return type:

tuple[float, float]

screen_to_world(sx, sy)[source]

Inverse of world_to_screen().

Parameters:
Return type:

tuple[float, float]

pan_by_pixels(dx_px, dy_px)[source]

Shift the view by (dx, dy) pixels (pixel-space).

Parameters:
Return type:

None

zoom_at_screen(sx, sy, factor)[source]

Multiply zoom by factor, keeping the world point under (sx, sy) fixed on the canvas (matches the binary’s cmd_scale_clamp_view zoom behaviour).

Parameters:
Return type:

None

fit_bbox(x_min, y_min, x_max, y_max, *, margin=0.05)[source]

Set zoom and pan so the bbox fits the canvas with margin.

Parameters:
Return type:

None

reset()[source]

Reset to identity (zoom=1, pan=0).

Return type:

None

world_bbox()[source]

Return the current world-space (x_min, y_min, x_max, y_max).

Return type:

tuple[float, float, float, float]

__init__(canvas_width=800, canvas_height=600, zoom=1.0, pan_x=0.0, pan_y=0.0)
Parameters:
Return type:

None

Per-metal-layer color palette for the layout view.

The original ASITIC binary indexes metals by g_metal_layer_color_index (see decomp/output/asitic_repl.c line ~3427) and resolves each entry through XParseColor against the X11 rgb.txt color database. Tech files name each colour with an X11 colour string (red, blue, greenish, …); we re-use that mapping but normalise unusual names (greenish, yellowish…) to standard CSS hex codes that Tk understands.

reasitic.gui.colors.normalize(name)[source]

Return a Tk-acceptable colour string for an X11 colour name.

Parameters:

name (str)

Return type:

str

reasitic.gui.colors.metal_color(tech, metal_name)[source]

Return the canvas colour for metal_name in tech.

Falls back to a deterministic palette entry keyed by index if the metal has no colour assigned.

Parameters:
Return type:

str

reasitic.gui.colors.via_color(tech, via_name)[source]

Return the canvas colour for via_name in tech.

Parameters:
Return type:

str

Tk Canvas renderer for layout shapes.

Mirrors the pipeline in xui_render_layout_view / xui_redraw_substrate_polygons (see decomp/output/asitic_repl.c ~22217 / 22825):

  1. Clear the canvas (X11 XClearWindow).

  2. Draw the chip outline (xui_draw_chip_outline).

  3. Draw the snap/view grid (xui_draw_grid_or_ruler).

  4. For every shape, fill each polygon stroke with the metal colour and stamp the shape name at its centroid (xui_draw_string_at_world).

  5. Highlight the currently-selected shape with a thick border (xui_draw_zoom_box_around_current_shape).

Tkinter takes the role of the X11 GC + pixmap pair; the Viewport handles world↔screen.

reasitic.gui.renderer.draw_chip_outline(canvas, tech, vp)[source]

Draw the rectangular chip boundary on the canvas.

Parameters:
Return type:

None

reasitic.gui.renderer.draw_grid(canvas, vp, *, step_um, color='#2c2c2c')[source]

Stamp a regular grid of points over the visible world bbox.

Mirrors xui_draw_grid_or_ruler minus the ruler labels (those show up in the dedicated dimension-overlay path on selection).

Parameters:
Return type:

None

reasitic.gui.renderer.draw_polygon(canvas, poly, vp, color, *, tags=())[source]

Render a single polygon onto the canvas as a filled stroke band.

Parameters:
Return type:

None

reasitic.gui.renderer.shape_centroid(shape)[source]

Return the centroid of shape’s vertices (μm).

Parameters:

shape (Shape)

Return type:

Point

reasitic.gui.renderer.draw_shape(canvas, shape, tech, vp, *, label=True, extra_tags=())[source]

Render every polygon of shape plus a name label.

Parameters:
Return type:

None

reasitic.gui.renderer.draw_selection(canvas, shape, vp)[source]

Highlight shape with a thick yellow bbox.

Parameters:
Return type:

None

reasitic.gui.renderer.render_all(canvas, tech, shapes, vp, *, grid_step_um=0.0, selected=None)[source]

Top-level redraw — wipe existing layout, draw chip + grid + shapes.

Parameters:
Return type:

None

reASITIC interactive GUI — a single-window layout viewer + console.

Mirrors the original ASITIC X11 front-end (decomp/output/asitic_repl.c):

  • A 2-D top-down layout view (xui_render_layout_view) with pan/zoom, chip outline (xui_draw_chip_outline) and a substrate grid (xui_draw_grid_or_ruler).

  • A status bar showing current zoom and world cursor coordinates.

  • An embedded REPL pane that drives reasitic.cli.Repl exactly the way the original binary’s terminal-side readline did, so every one of the 117 binary commands works in the GUI.

  • Mouse interactions: drag to pan, scroll wheel to zoom around the cursor, click on a shape to select it (highlights its bounding box, matching xui_draw_zoom_box_around_current_shape).

class reasitic.gui.app.GuiApp[source]

Bases: object

The reASITIC graphical workspace.

The GUI is a thin presentation layer over an embedded Repl. Each command typed into the console pane is forwarded verbatim to repl.execute (with stdout / stderr captured into the console widget) and then the layout view is redrawn from repl.shapes. This means every command that works in the headless CLI also works in the GUI, with identical output.

__init__(*, repl=None, width=1100, height=720, title='reASITIC')[source]

Build the Tk window. Tk imports are deferred so the rest of reasitic.gui stays importable on headless boxes.

Parameters:
Return type:

None

action_fit()[source]

Frame all shapes — or the chip outline if there are none.

Return type:

None

action_reset_view()[source]

Restore identity zoom (1 px/μm) and zero pan.

Return type:

None

action_toggle_grid()[source]

Switch the substrate grid overlay on/off.

Return type:

None

refresh_view()[source]

Wipe the canvas and re-render chip / grid / shapes / selection.

Return type:

None

mainloop()[source]

Run the Tk event loop; returns when the window is closed.

Return type:

None

reasitic.gui.app.run(*, tech_path=None, session_path=None)[source]

Spawn the GUI. Optionally load a tech file and/or session on startup.

Parameters:
  • tech_path (str | None)

  • session_path (str | None)

Return type:

None