Shape Renderers
This section documents all available shape renderers and the factory system.
Shape Factory
Shape renderer factory for managing and creating shape renderers.
This module provides a centralized factory for creating shape renderers and managing the registry of available shapes.
The factory pattern allows:
Dynamic registration of new shape renderers
Centralized management of shape types
Easy extension with custom shapes
Consistent renderer instantiation
Example
Using the factory to create renderers:
factory = get_shape_factory()
renderer = factory.create_renderer('star', {})
element = renderer.render(0, 0, 10)
Registering a custom renderer:
register_custom_renderer('my-shape', MyShapeRenderer)
- class segnomms.shapes.factory.ShapeRendererFactory[source]
Bases:
RendererFactoryFactory for creating and managing shape renderers.
This factory maintains a registry of available shape renderers and provides methods to create appropriate renderers based on shape type names.
- _renderers
Internal registry mapping shape names to renderer classes
- register_renderer(shape_type, renderer_class)[source]
Register a custom shape renderer.
- Parameters:
shape_type (
str) – Name of the shape typerenderer_class (
Type[ShapeRenderer]) – Renderer class to register
- Return type:
Example
>>> factory.register_renderer('my-shape', MyShapeRenderer)
- create_renderer(shape_type, config)[source]
Create a renderer for the specified shape type.
- Parameters:
- Returns:
Instance of appropriate renderer
- Return type:
Note
Falls back to ‘square’ renderer if shape type is not found, but logs a warning with available options.
- list_supported_types()[source]
List all shape types supported by this factory.
- Returns:
List of all registered shape type names
- Return type:
List[str]
- segnomms.shapes.factory.get_shape_factory()[source]
Get the global shape factory instance.
- Returns:
Singleton factory instance
- Return type:
Note
This function ensures only one factory instance exists globally.
- segnomms.shapes.factory.register_custom_renderer(shape_type, renderer_class)[source]
Register a custom shape renderer with the global factory.
- Parameters:
shape_type (
str) – Name of the shape typerenderer_class (
Type[ShapeRenderer]) – Renderer class to register
- Return type:
Example
>>> from segnomms import register_custom_renderer >>> register_custom_renderer('my-shape', MyShapeRenderer)
- segnomms.shapes.factory.create_shape_renderer(shape_type, config=None)[source]
Create a shape renderer using the global factory.
- Parameters:
- Returns:
Instance of appropriate renderer
- Return type:
Example
>>> renderer = create_shape_renderer('star') >>> element = renderer.render(0, 0, 10)
Basic Shapes
Basic shape renderers for QR code modules.
This module provides simple geometric shape renderers that don’t depend on neighboring modules. Each renderer creates a single SVG element for each QR code module.
- Available shapes:
SquareRenderer: Traditional square modules
CircleRenderer: Circular modules
DotRenderer: Small circular dots
DiamondRenderer: Diamond/rhombus shapes
StarRenderer: Configurable star shapes
TriangleRenderer: Directional triangles
HexagonRenderer: Six-sided polygons
CrossRenderer: Plus/cross shapes
- class segnomms.shapes.basic.BaseShapeRenderer[source]
Bases:
ShapeRendererAbstract base class for basic shape renderers with common functionality.
Provides standardized implementations of common methods like supports_type() and shared constants. Subclasses should define shape_names to specify which shape types they support.
- segnomms.shapes.basic.apply_element_attributes(element, kwargs)[source]
Apply common attributes to an SVG element.
This helper function applies standard attributes like id, data-* attributes, and other interactive properties to SVG elements.
- Parameters:
- Return type:
- segnomms.shapes.basic.create_svg_element(tag, attributes, kwargs)[source]
Create an SVG element with common attributes applied.
This helper function combines element creation with common attribute application, reducing boilerplate code across all renderers.
- Parameters:
- Returns:
SVG element with all attributes applied
- Return type:
ET.Element
- segnomms.shapes.basic.get_module_center(x, y, size)[source]
Calculate the center point of a module.
- segnomms.shapes.basic.apply_size_ratio(size, kwargs, default=1.0)[source]
Apply size ratio from kwargs to a base size.
- segnomms.shapes.basic.get_corner_radius(size, kwargs, param_name='roundness', default=0.3)[source]
Calculate corner radius from size and roundness parameter.
- segnomms.shapes.basic.generate_regular_polygon(center_x, center_y, radius, sides, start_angle=0.0)[source]
Generate points for a regular polygon.
- Parameters:
- Returns:
List of point strings in “x,y” format for SVG polygon
- Return type:
- Raises:
ValueError – If sides < 3
- segnomms.shapes.basic.generate_star_polygon(center_x, center_y, outer_radius, inner_radius, points, start_angle=-1.5707963267948966)[source]
Generate points for a star polygon.
- Parameters:
center_x (
float) – X coordinate of star centercenter_y (
float) – Y coordinate of star centerouter_radius (
float) – Distance from center to outer pointsinner_radius (
float) – Distance from center to inner pointspoints (
int) – Number of star points (must be >= 3)start_angle (
float) – Starting angle in radians (default: -π/2 for upward point)
- Returns:
List of point strings in “x,y” format for SVG polygon
- Return type:
- Raises:
ValueError – If points < 3
- segnomms.shapes.basic.generate_diamond_points(x, y, size)[source]
Generate points for a diamond (rotated square) shape.
- segnomms.shapes.basic.generate_triangle_points(x, y, size, direction='up')[source]
Generate points for a triangle in the specified direction.
- Parameters:
- Returns:
List of point strings for triangle polygon
- Return type:
- Raises:
ValueError – If direction is not valid
- class segnomms.shapes.basic.SquareRenderer[source]
Bases:
BaseShapeRendererRenders traditional square QR code modules.
The most basic shape renderer, creating perfect squares for each module. This is the default shape for QR codes and provides maximum reliability for scanning while maintaining the classic QR code appearance.
Example
>>> renderer = SquareRenderer() >>> square = renderer.render(0, 0, 10) >>> # Creates a 10x10 square at position (0,0)
- class segnomms.shapes.basic.CircleRenderer[source]
Bases:
BaseShapeRendererRenders circular QR code modules.
Creates perfect circles that fit within the module grid. This shape provides a softer, more organic appearance while maintaining good scannability due to the consistent module centers.
Example
>>> renderer = CircleRenderer() >>> circle = renderer.render(5, 5, 10) >>> # Creates a circle with radius 5 centered at (10,10)
- class segnomms.shapes.basic.RoundedRenderer[source]
Bases:
BaseShapeRendererRenders square modules with rounded corners.
Creates modules with softly rounded corners for a more friendly, modern appearance. The corner radius can be controlled via the roundness parameter.
Example
>>> renderer = RoundedRenderer() >>> rounded_rect = renderer.render(0, 0, 10, roundness=0.3) >>> # Creates a square with 30% corner radius
- render(x, y, size, **kwargs)[source]
Render a rounded square module.
- Parameters:
x (
float) – X coordinate of the module’s top-left cornery (
float) – Y coordinate of the module’s top-left cornersize (
float) – Module size**kwargs (
Any) – Additional parameters including: roundness: Corner radius as fraction of size (default: 0.3) css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID
- Returns:
SVG rect element with rounded corners
- Return type:
ET.Element
- class segnomms.shapes.basic.DotRenderer[source]
Bases:
BaseShapeRendererRenders small dot modules for a minimalist QR code style.
Creates smaller circles that leave more whitespace between modules, resulting in a lighter, more delicate appearance. The dot size can be controlled via the size_ratio parameter.
Example
>>> renderer = DotRenderer() >>> dot = renderer.render(0, 0, 10, size_ratio=0.5) >>> # Creates a 5-pixel diameter dot in a 10x10 module
- render(x, y, size, **kwargs)[source]
Render a small dot module.
- Parameters:
x (
float) – X coordinate of the module’s top-left cornery (
float) – Y coordinate of the module’s top-left cornersize (
float) – Module size**kwargs (
Any) – Additional parameters including: size_ratio: Dot size relative to module (default: 0.6) css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID
- Returns:
SVG circle element smaller than the module size
- Return type:
ET.Element
- class segnomms.shapes.basic.DiamondRenderer[source]
Bases:
BaseShapeRendererRenders diamond (rhombus) shaped modules.
Creates 45-degree rotated squares that form diamond patterns. This shape adds a geometric, crystalline quality to QR codes while maintaining good contrast for scanning.
Example
>>> renderer = DiamondRenderer() >>> diamond = renderer.render(0, 0, 10) >>> # Creates a diamond touching all edges of the 10x10 module
- class segnomms.shapes.basic.StarRenderer[source]
Bases:
BaseShapeRendererRenders star-shaped modules with configurable points.
Creates multi-pointed star shapes that add a decorative flair to QR codes. The number of points and the inner/outer radius ratio can be customized to create different star styles from sharp to more rounded.
Example
>>> renderer = StarRenderer() >>> star = renderer.render(0, 0, 10, star_points=6, inner_ratio=0.4) >>> # Creates a 6-pointed star with sharp points
- render(x, y, size, **kwargs)[source]
Render a star shape module.
- Parameters:
x (
float) – X coordinate of the module’s top-left cornery (
float) – Y coordinate of the module’s top-left cornersize (
float) – Module size**kwargs (
Any) – Additional parameters including: star_points: Number of star points (default: 5) inner_ratio: Inner radius ratio 0-1 (default: 0.5) css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID
- Returns:
SVG polygon element forming a star
- Return type:
ET.Element
- class segnomms.shapes.basic.TriangleRenderer[source]
Bases:
BaseShapeRendererRenders triangular modules with directional orientation.
Creates equilateral triangles that can point in different directions. This shape adds a dynamic, directional quality to QR codes and can create interesting patterns when modules align.
Example
>>> renderer = TriangleRenderer() >>> triangle = renderer.render(0, 0, 10, direction='up') >>> # Creates an upward-pointing triangle
- render(x, y, size, **kwargs)[source]
Render a triangle shape module.
- Parameters:
x (
float) – X coordinate of the module’s top-left cornery (
float) – Y coordinate of the module’s top-left cornersize (
float) – Module size**kwargs (
Any) – Additional parameters including: direction: Triangle direction (‘up’, ‘down’, ‘left’, ‘right’) css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID
- Returns:
SVG polygon element forming a triangle
- Return type:
ET.Element
- class segnomms.shapes.basic.HexagonRenderer[source]
Bases:
BaseShapeRendererRenders hexagonal modules for a honeycomb-like appearance.
Creates regular hexagons that can tessellate beautifully when adjacent modules are also hexagons. This shape provides an organic, nature-inspired look to QR codes.
Example
>>> renderer = HexagonRenderer() >>> hexagon = renderer.render(0, 0, 10, size_ratio=0.95) >>> # Creates a hexagon slightly smaller than the module
- render(x, y, size, **kwargs)[source]
Render a hexagon shape module.
- Parameters:
x (
float) – X coordinate of the module’s top-left cornery (
float) – Y coordinate of the module’s top-left cornersize (
float) – Module size**kwargs (
Any) – Additional parameters including: size_ratio: Hexagon size relative to module (default: 0.9) css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID
- Returns:
SVG polygon element forming a regular hexagon
- Return type:
ET.Element
- class segnomms.shapes.basic.CrossRenderer[source]
Bases:
BaseShapeRendererRenders cross (plus sign) shaped modules.
Creates cross or plus sign shapes that can vary in thickness and style. Supports both uniform width crosses and tapered crosses for a sharper appearance. This shape adds a technical, precise feel to QR codes.
Example
>>> renderer = CrossRenderer() >>> cross = renderer.render(0, 0, 10, thickness=0.25, sharp=True) >>> # Creates a sharp cross with tapered arms
- render(x, y, size, **kwargs)[source]
Render a cross shape module.
- Parameters:
x (
float) – X coordinate of the module’s top-left cornery (
float) – Y coordinate of the module’s top-left cornersize (
float) – Module size**kwargs (
Any) – Additional parameters including: thickness: Cross arm thickness ratio (default: 0.2) sharp: Use tapered arms for sharper look (default: False) css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID
- Returns:
SVG path element forming a cross
- Return type:
ET.Element
- class segnomms.shapes.basic.SquircleRenderer[source]
Bases:
BaseShapeRendererRenders superellipse (squircle) shaped QR code modules.
A squircle is a mathematical shape that’s between a square and a circle, providing a modern, smooth appearance while maintaining good scannability. The shape is defined by the superellipse equation with n=4.
Example
>>> renderer = SquircleRenderer() >>> squircle = renderer.render(0, 0, 10) >>> # Creates a 10x10 squircle at position (0,0)
- render(x, y, size, **kwargs)[source]
Render a squircle module.
- Parameters:
x (
float) – X coordinate of the top-left cornery (
float) – Y coordinate of the top-left cornersize (
float) – Width and height of the module**kwargs (
Any) – Additional parameters including: css_class: CSS class for styling (default: ‘qr-module’) id: Optional element ID corner_radius: Override corner radius (0.0-1.0)
- Returns:
SVG path element forming a squircle
- Return type:
ET.Element
Connected Shapes
Connected shape renderers that create fluid, context-aware QR code modules.
These renderers analyze neighboring modules to create shapes that connect smoothly, inspired by qr-code-styling’s advanced rendering techniques.
The connected renderers use neighbor analysis to determine the appropriate shape for each module, creating smooth transitions and organic patterns.
Available connected renderers:
ConnectedRoundedRenderer: Basic connected style with rounded corners
ConnectedExtraRoundedRenderer: Extra smooth curves using quadratic beziers
AdvancedClassyRenderer: Boundary-focused styling with strategic rounding
AdvancedClassyRoundedRenderer: Classy style with extra-rounded corners
- class segnomms.shapes.connected.Corner(*values)[source]
Bases:
EnumEnumeration for corner positions.
Used to specify which corner of a module should be rounded.
- TOP_LEFT = 1
- TOP_RIGHT = 2
- BOTTOM_LEFT = 3
- BOTTOM_RIGHT = 4
- class segnomms.shapes.connected.Side(*values)[source]
Bases:
EnumEnumeration for side positions.
Used to specify which side of a module should be rounded.
- TOP = 1
- BOTTOM = 2
- LEFT = 3
- RIGHT = 4
- class segnomms.shapes.connected.ConnectedRoundedRenderer[source]
Bases:
ShapeRendererRenders modules that connect to their neighbors with rounded corners.
Creates fluid, organic-looking QR codes by analyzing module context. The renderer determines the appropriate shape based on the number and position of neighboring dark modules.
Shape selection logic:
0 neighbors: Isolated dot
1 neighbor: Rounded end cap
2 neighbors (line): Straight module
2 neighbors (corner): Rounded corner
3+ neighbors: Straight module
- class segnomms.shapes.connected.ConnectedExtraRoundedRenderer[source]
Bases:
ConnectedRoundedRendererRenders modules with extra rounded corners for a softer appearance.
Similar to ConnectedRoundedRenderer but with more pronounced curves using quadratic Bezier curves instead of circular arcs.
Key differences from ConnectedRoundedRenderer:
Smaller isolated dots (0.375 vs 0.5 radius)
Quadratic Bezier curves for ultra-smooth corners
Full-size radius for side rounding
More organic, flowing appearance
Example
>>> renderer = ConnectedExtraRoundedRenderer() >>> # Requires get_neighbor function >>> element = renderer.render(0, 0, 10, get_neighbor=neighbor_func)
- class segnomms.shapes.connected.AdvancedClassyRenderer[source]
Bases:
ConnectedRoundedRendererRenders modules with advanced classy style focusing on shape boundaries.
This renderer implements a sophisticated boundary detection algorithm that only rounds specific corners of QR code shapes, creating a distinctive “classy” appearance.
The renderer follows these rules:
Isolated modules: Get jewel-like appearance with opposite corners rounded
Top-left outer corners: Modules with no neighbors above or left
Bottom-right outer corners: Modules with no neighbors below or right
All other modules: Rendered as solid squares
This creates an elegant look where only the outer boundaries of shapes have rounded corners, while internal modules remain square for stability.
Example
>>> renderer = AdvancedClassyRenderer() >>> # Requires get_neighbor function >>> element = renderer.render(0, 0, 10, get_neighbor=neighbor_func)
Note
Based on the TypeScript QRDot.ts _drawClassy logic from qr-code-styling.
- render(x, y, size, **kwargs)[source]
Render a module using classy boundary rounding rules.
Applies rounded corners only on outer boundaries based on neighbor states to achieve a refined “classy” look.
- Parameters:
x (
float) – X coordinate in pixels.y (
float) – Y coordinate in pixels.size (
float) – Module size in pixels.**kwargs (
Any) –Additional rendering parameters. Recognized keys: - get_neighbor: Callable(dx, dy) -> bool indicating whether a
neighbor exists at the given offset relative to the current module.
- Return type:
- Returns:
ET.Element representing the rendered module.
- class segnomms.shapes.connected.AdvancedClassyRoundedRenderer[source]
Bases:
ConnectedExtraRoundedRendererRenders modules with classy rounded style using ultra-smooth curves.
Combines the boundary detection logic of AdvancedClassyRenderer with the extra-rounded drawing methods of ConnectedExtraRoundedRenderer.
Key features:
Same boundary detection rules as AdvancedClassyRenderer
Uses quadratic Bezier curves instead of circular arcs
Creates softer, more organic appearance
Isolated modules get jewel-like shapes with Bezier curves
The result is a highly polished look with smooth boundaries and flowing curves that enhance the QR code’s visual appeal.
Example
>>> renderer = AdvancedClassyRoundedRenderer() >>> # Creates ultra-smooth classy style >>> element = renderer.render(0, 0, 10, get_neighbor=neighbor_func)
- render(x, y, size, **kwargs)[source]
Render a module using ultra-smooth classy rounding (Bezier curves).
Uses the same boundary detection rules as
AdvancedClassyRendererbut renders with quadratic Bezier curves for softer transitions.- Parameters:
x (
float) – X coordinate in pixels.y (
float) – Y coordinate in pixels.size (
float) – Module size in pixels.**kwargs (
Any) –Additional rendering parameters. Recognized keys: - get_neighbor: Callable(dx, dy) -> bool indicating whether a
neighbor exists at the given offset relative to the current module.
- Return type:
- Returns:
ET.Element representing the rendered module.
Shape Interface
All shape renderers implement the following interface:
- class segnomms.core.interfaces.ShapeRenderer[source]
Bases:
ABCInterface for shape rendering implementations.
All shape renderers must implement this interface to ensure compatibility with the rendering pipeline.
Implementations should:
Create SVG elements for individual modules
Support configuration through kwargs
Declare which shape types they handle
Creating Custom Shapes
To create a custom shape, inherit from ShapeRenderer:
from segnomms.core.interfaces import ShapeRenderer
import xml.etree.ElementTree as ET
class MyCustomShape(ShapeRenderer):
def render(self, x, y, size, **kwargs):
# Create and return an SVG element
return ET.Element('rect', {
'x': str(x),
'y': str(y),
'width': str(size),
'height': str(size),
'rx': str(size * 0.3)
})
def supports_type(self, shape_type):
return shape_type == 'my-custom'
# Register the shape
from segnomms import register_custom_renderer
register_custom_renderer('my-custom', MyCustomShape)