Skip to content

Missing IC property positioning rules causes incorrect text placement #176

@shanemmattner

Description

@shanemmattner

Problem Statement

kicad-sch-api is missing property positioning rules for IC components, causing Reference/Value/Footprint text to be placed incorrectly when generating KiCad schematics. The library falls back to the resistor pattern which is completely inappropriate for large ICs.

Visual Impact

When circuit-synth (or any tool using kicad-sch-api) generates a schematic with ICs, the component property text is placed way too close to the component body, making schematics look unprofessional and difficult to read. For a large IC like ESP32-WROOM-32 (40mm × 86mm), using the resistor offset (+2.54mm, -1.27mm) places text practically ON TOP of the component instead of properly spaced above it.

Root Cause

kicad_sch_api/core/property_positioning.py contains a POSITIONING_RULES dictionary that defines property offsets for different component types. Currently it only has rules for:

  • Device:R (Resistor)
  • Device:C (Capacitor)
  • Device:LED

When a component type is not found in POSITIONING_RULES, the code falls back to the resistor pattern:

rule = POSITIONING_RULES.get(lib_id)
if not rule:
    logger.warning(f"No positioning rule for {lib_id}, using default resistor pattern")
    rule = POSITIONING_RULES["Device:R"]  # Default fallback

Evidence

When generating schematics with ICs, we see warnings like:

2025-11-17 21:47:42,652 - WARNING - kicad_sch_api.core.property_positioning - No positioning rule for RF_Module:ESP32-WROOM-32, using default resistor pattern
2025-11-17 21:47:42,652 - WARNING - kicad_sch_api.core.property_positioning - No positioning rule for 74xx:74LS245, using default resistor pattern  
2025-11-17 21:47:42,652 - WARNING - kicad_sch_api.core.property_positioning - No positioning rule for Interface_UART:MAX3485, using default resistor pattern

The resistor pattern uses offsets like:

"Device:R": ComponentPositioningRule(
    reference_offset=PropertyOffset(x=2.54, y=-1.2701, rotation=0),
    value_offset=PropertyOffset(x=2.54, y=1.2699, rotation=0),
    footprint_offset=PropertyOffset(x=-1.778, y=0, rotation=90),
)

These tiny offsets (2.54mm) are appropriate for a small resistor but completely wrong for a 40mm × 86mm IC.

Source of Truth: KiCad Symbol Library Files

The correct property positions are defined in KiCad's .kicad_sym library files. These contain the default property positions that KiCad uses when auto-placing fields.

Example: ESP32-WROOM-32 (from RF_Module.kicad_sym):

(symbol "ESP32-WROOM-32"
    (property "Reference" "U"
        (at -12.7 34.29 0)    # 34.29mm above component center!
        ...
    )
    (property "Value" "ESP32-WROOM-32"
        (at 1.27 34.29 0)
        ...
    )
    (property "Footprint" "RF_Module:ESP32-WROOM-32"
        (at 0 -38.1 0)        # 38.1mm below component center
        ...
    )
)

Example: 74LS245 (from 74xx.kicad_sym):

(symbol "74LS245"
    (property "Reference" "U"
        (at -7.62 16.51 0)
        ...
    )
    (property "Value" "74LS245"
        (at -7.62 -16.51 0)
        ...
    )
    (property "Footprint" ""
        (at 0 0 0)
        ...
    )
)

Components Affected (Tested)

The following components have been tested and confirmed to have missing positioning rules:

ICs (SOIC Packages)

  • RF_Module:ESP32-WROOM-32 (38-pin RF module, ~40×86mm)

    • Should be: Reference (-12.7, 34.29), Value (1.27, 34.29)
    • Currently using: Resistor pattern (+2.54, -1.27)
  • 74xx:74LS245 (SOIC-20W level shifter)

    • Should be: Reference (-7.62, 16.51), Value (-7.62, -16.51)
    • Currently using: Resistor pattern
  • Interface_UART:MAX3485 (SOIC-8 transceiver)

    • Manual analysis shows: Reference (+2.1433, -17.78)
    • Currently using: Resistor pattern

Voltage Regulators

  • Regulator_Linear:AMS1117-3.3 (SOT-223 LDO)

    • Should use centered text above component
    • Currently using: Resistor pattern (incorrect for regulators)
  • Regulator_Switching:TPS54202DDC (SOT-23-6 buck converter)

    • Should use centered text above component
    • Currently using: Resistor pattern

Transistors

  • Transistor_FET:AO3401A (SOT-23 P-FET)
    • Should use larger horizontal offset than resistor
    • Currently using: Resistor pattern

Solution

Step 1: Extract Property Positions from KiCad Libraries

Parse the .kicad_sym files to extract the (at x y rotation) parameters from each symbol's Reference, Value, and Footprint properties.

KiCad symbol library locations:

  • macOS: /Applications/KiCad/KiCad.app/Contents/SharedSupport/symbols/
  • Linux: /usr/share/kicad/symbols/
  • Windows: C:\Program Files\KiCad\share\kicad\symbols\

Step 2: Add Rules to property_positioning.py

Add entries to the POSITIONING_RULES dictionary:

POSITIONING_RULES = {
    # Existing rules
    "Device:R": ComponentPositioningRule(...),
    "Device:C": ComponentPositioningRule(...),
    "Device:LED": ComponentPositioningRule(...),
    
    # NEW: IC rules
    "RF_Module:ESP32-WROOM-32": ComponentPositioningRule(
        reference_offset=PropertyOffset(x=-12.7, y=34.29, rotation=0),
        value_offset=PropertyOffset(x=1.27, y=34.29, rotation=0),
        footprint_offset=PropertyOffset(x=0, y=-38.1, rotation=0),
    ),
    "74xx:74LS245": ComponentPositioningRule(
        reference_offset=PropertyOffset(x=-7.62, y=16.51, rotation=0),
        value_offset=PropertyOffset(x=-7.62, y=-16.51, rotation=0),
        footprint_offset=PropertyOffset(x=0, y=0, rotation=0),
    ),
    # ... more IC rules
}

Step 3: Consider Auto-Loading from Symbol Libraries

For a more maintainable long-term solution, consider:

  1. Parsing .kicad_sym files at runtime to extract positioning
  2. Caching parsed rules
  3. Falling back to parsed rules when POSITIONING_RULES doesn't have an entry

This would automatically support all KiCad components without manual rule entry.

Test Data

Reference schematics with manual KiCad placements are in:
tests/reference_tests/ic_property_positioning/

These schematics were generated with circuit-synth, then manually opened in KiCad with the "fields autoplaced" feature. They show the CORRECT positioning that KiCad uses natively and can be used to verify our rules are correct.

Each component directory contains:

  • generate_*.py - Script to regenerate the schematic
  • circuit_synth_generated/*.kicad_sch - Circuit-synth generated version
  • analysis.md - Manual analysis of property positions

Acceptance Criteria

  1. ✅ No warnings about missing positioning rules when generating schematics with tested ICs
  2. ✅ Property text positioned at correct offsets matching KiCad's native auto-placement
  3. ✅ Reference schematics in tests/reference_tests/ic_property_positioning/ validate correctly
  4. ✅ Documentation updated explaining how positioning rules work
  5. ✅ Consider automated extraction from .kicad_sym files for future maintainability

Related Issues

This issue was discovered during investigation of component property positioning in circuit-synth. The root cause is in kicad-sch-api, not circuit-synth.

Branch

Work is being done in branch: fix/ic-property-positioning

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions