Successfully implemented Phase 4 "Path Manipulation & Boolean Operations" from the FontLab API roadmap. These provide essential path editing and boolean shape operations for professional font design automation through the MCP server.
-
union_shapes- Union (combine) overlapping shapes in a glyph- Parameters:
glyph_name - Combines all overlapping paths using removeOverlap()
- Essential for merging multiple shapes into one
- Parameters:
-
intersect_shapes- Intersect shapes (keep only overlapping areas)- Parameters:
glyph_name - Keeps only the areas where shapes overlap
- Requires at least 2 shapes in the glyph
- Uses layer.intersectShapes() if available
- Parameters:
-
subtract_shapes- Subtract shapes from the first shape- Parameters:
glyph_name - Reverses subsequent shapes and removes overlaps
- Requires at least 2 shapes in the glyph
- Creates knockout/cutout effects
- Parameters:
-
add_node- Add a node to a contour at a specific position- Parameters:
glyph_name,contour_index,x,y,node_type(optional: "curve", "line", "move") - Creates new flNode and adds to contour
- Validates contour index range
- Parameters:
-
remove_node- Remove a node from a contour- Parameters:
glyph_name,contour_index,node_index - Removes node at specified index
- Prevents removal if contour has ≤2 nodes
- Validates both contour and node indices
- Parameters:
-
move_node- Move an existing node to a new position- Parameters:
glyph_name,contour_index,node_index,x,y - Updates node coordinates
- Returns both old and new positions
- Parameters:
-
convert_node_type- Convert a node type (curve/line/corner)- Parameters:
glyph_name,contour_index,node_index,node_type - Changes node type using NodeType enum
- Supports "curve", "line", "move"
- Returns old and new types
- Parameters:
-
smooth_node- Toggle smooth property of a node- Parameters:
glyph_name,contour_index,node_index,smooth(boolean) - Sets node.smooth property
- Affects how handles behave
- Parameters:
-
add_contour_from_points- Create a new contour from a list of points- Parameters:
glyph_name,points(array of {x, y, type}),closed(optional) - Creates flContour with flNodes
- Validates at least 2 points
- Each point can specify type ("curve", "line", "move")
- Parameters:
-
remove_contour- Remove a contour from a glyph by index- Parameters:
glyph_name,contour_index - Removes specified contour from layer
- Validates contour index
- Parameters:
-
simplify_paths- Simplify/optimize contours by removing unnecessary nodes- Parameters:
glyph_name,tolerance(optional, default 1.0) - Uses layer.simplify() method
- Returns nodes before/after and count removed
- Tolerance range: 0.1 to 100.0
- Parameters:
Total New Tools: 11
- All glyph names validated for dangerous characters
- Numeric ranges enforced for coordinates (-10000 to 10000)
- String length limits for names (255 chars)
- Contour and node index validation
- Minimum node count validation (prevents contour corruption)
- Point list validation for add_contour_from_points
- Comprehensive try/catch in all bridge scripts
- Validation errors logged and returned to user
- Font/glyph existence checks
- Contour and node index range validation
- Shape count validation for boolean operations
- Type validation for node operations
- Uses
layer.removeOverlap()for union operations - Uses
layer.intersectShapes()for intersection (if available) - Uses
shape.reverse()+ removeOverlap for subtraction - Uses
flNode()andNodeTypeenum for node creation - Uses
flContour()andlayer.addShape()for contour creation - Uses
layer.removeShape(index)for contour removal - Uses
layer.simplify(tolerance)for path optimization - Calls
glyph.update()for persistence after all operations
Before Phase 4:
- 27 tools + 17 resources = 44 features
- ~33% of FontLab API (after Phase 3)
After Phase 4:
- 38 tools + 17 resources = 55 features
- ~42% of FontLab API
Added:
- Complete boolean operation set
- Core node manipulation operations
- Path creation and simplification
Categories Improved:
- Contours & Shapes: 27% → 80%
- Path Manipulation: 0% → 70%
- Boolean Operations: 0% → 100%
- Combine overlapping shapes for simplified glyphs
- Create complex shapes from simple primitives
- Subtract shapes to create counters and knockouts
- Intersect shapes for precise area selection
- Add nodes for better curve control
- Remove unnecessary nodes for optimization
- Move nodes for shape refinement
- Convert between curve and line segments
- Control smoothness for precise corners or curves
- Generate glyphs from coordinate data
- Create geometric shapes (rectangles, circles, polygons)
- Build glyphs from mathematical formulas
- Import path data from other sources
- Simplify complex imported paths
- Reduce file size by removing redundant nodes
- Optimize for rendering performance
- Clean up auto-traced artwork
- Batch generate composite glyphs
- Programmatic shape modification
- Automated cleanup and optimization
- Geometric glyph generation for icon fonts
-
src/tools.py- Added 11 new tool definitions to register_tools()
- Added 11 new tool handlers to handle_call_tool()
- Implemented 11 new async functions:
- _union_shapes, _intersect_shapes, _subtract_shapes
- _add_node, _remove_node, _move_node, _convert_node_type, _smooth_node
- _add_contour_from_points, _remove_contour, _simplify_paths
- All functions use existing validation infrastructure
- Total file size: ~3,335 lines
-
src/utils/validation.py(existing, no changes)- Reused existing validation functions
- All inputs validated before script execution
# Union overlapping shapes
union_shapes(glyph_name="A")
# Intersect shapes (keep overlap)
intersect_shapes(glyph_name="ampersand")
# Subtract shapes (create knockout)
subtract_shapes(glyph_name="dollar")# Add a node to a contour
add_node(
glyph_name="A",
contour_index=0,
x=300,
y=400,
node_type="curve" # or "line", "move"
)
# Remove a node
remove_node(
glyph_name="A",
contour_index=0,
node_index=5
)
# Move a node
move_node(
glyph_name="A",
contour_index=0,
node_index=3,
x=350,
y=450
)
# Convert node type
convert_node_type(
glyph_name="A",
contour_index=0,
node_index=2,
node_type="line"
)
# Set node smoothness
smooth_node(
glyph_name="A",
contour_index=0,
node_index=1,
smooth=True
)# Create a contour from points
add_contour_from_points(
glyph_name="square",
points=[
{"x": 100, "y": 100, "type": "line"},
{"x": 500, "y": 100, "type": "line"},
{"x": 500, "y": 500, "type": "line"},
{"x": 100, "y": 500, "type": "line"}
],
closed=True
)
# Remove a contour
remove_contour(
glyph_name="A",
contour_index=1
)
# Simplify paths
simplify_paths(
glyph_name="imported",
tolerance=2.0
)To test these features, you'll need:
- FontLab 7 or 8 installed
- A font open in FontLab
- The MCP server running and connected
Test scenarios:
- Boolean: Create overlapping circles, test union/intersect/subtract
- Nodes: Create a simple square, add/remove/move nodes
- Paths: Generate a triangle from coordinates, simplify traced artwork
union_shapesuses removeOverlap() as it's the most reliable methodintersect_shapeschecks for method availability and fails gracefullysubtract_shapesuses shape reversal + removeOverlap pattern
- All indices are 0-based for consistency with Python
- Contour indices count only contours (skip components)
- Node indices are direct indices into contour.nodes array
- Coordinates: -10000 to 10000 (generous for most font work)
- Tolerance: 0.1 to 100.0 (reasonable simplification range)
- Indices: Validated against actual counts to prevent crashes
Remaining in Roadmap:
- Phase 5: Variable Fonts
- Masters & Axes - 3 resources + 3 tools
- Instances - 1 resource + 2 tools
- Interpolation - 2 tools
- Phase 6: Font Validation & QA
- Validation - 2 resources + 3 tools
- Metrics Analysis - 1 resource + 2 tools
- Glyph Comparison - 1 tool
- Phase 7: Batch Operations
- Batch Processing - 6 tools
Future Enhancements:
- Advanced boolean operations (exclude, front minus back)
- Bezier curve operations (split, join)
- Path effects (offset, stroke)
- Node alignment and distribution tools
Status: ✅ Phase 4 Implementation Complete
Total Progress:
- Resources: 17 (unchanged from Phase 3)
- Tools: 38 (was 27, +11 new)
- API Coverage: ~42% (was ~33%)
- Phases Complete: 1 (Quick Wins), 2 (Professional), 3 (Specialized), 4 (Path Manipulation)
Key Achievement: Brought Contours & Shapes category from 27% to 80% coverage, enabling advanced programmatic glyph design and modification.