Skip to content

API V1 Reference (legacy)

Deprecation warning

This is a legacy Gerber API, it will be removed in PyGerber 3.0.

api

pygerber.gerberx3.api module provides simple, high-level API for rendering Gerber X3/X2 files.

ColorScheme

Bases: FrozenGeneralModel

Set of colors which should be used for rendering.

ColorScheme class contains set of colors which should be used for different parts of rendered image. At the same time it also works as a container for predefined color schemes commonly used for parts of PCB.

Predefined colors

All predefined colors have two variants - normal one and one with "*_ALPHA" suffix. Those without suffix have solid background and are not intended for constructing multi-layer images out of them ie. they are not suitable for rendering a project consisting of separate copper, silk, pase mask and composing them into single image. For cases when rendered images are intended for stacking "*_ALPHA" schemes should be used, as background and transparent parts of image will be truly transparent.

Source code in src\pygerber\backend\rasterized_2d\color_scheme.py
class ColorScheme(FrozenGeneralModel):
    r"""Set of colors which should be used for rendering.

    ColorScheme class contains set of colors which should be used for different parts
    of rendered image. At the same time it also works as a container for predefined
    color schemes commonly used for parts of PCB.

    !!! info "Predefined colors"

        All predefined colors have two variants - normal one and one with "\*_ALPHA"
        suffix. Those without suffix have solid background and are not intended for
        constructing multi-layer images out of them ie. they are not suitable for
        rendering a project consisting of separate copper, silk, pase mask and composing
        them into single image. For cases when rendered images are intended for stacking
        "\*_ALPHA" schemes should be used, as background and transparent parts of image
        will be truly transparent.

    """

    SILK: ClassVar[ColorScheme]
    """Default color of silk layer.

    This schema provided non-transparent background, which results in images which
    can not be used for stacking on top of other layers, as they would completely
    obscure them."""

    SILK_ALPHA: ClassVar[ColorScheme]
    """Default color of silk layer with alpha channel.

    This schema provides transparent background. Images using this schema can be
    stacked on top of each other without obscuring layers below."""

    COPPER: ClassVar[ColorScheme]
    """Default color of copper layer.

    This schema provided non-transparent background, which results in images which
    can not be used for stacking on top of other layers, as they would completely
    obscure them."""

    COPPER_ALPHA: ClassVar[ColorScheme]
    """Default color of copper layer with alpha channel.

    This schema provides transparent background. Images using this schema can be
    stacked on top of each other without obscuring layers below."""

    PASTE_MASK: ClassVar[ColorScheme]
    """Default color of paste mask layer.

    This schema provided non-transparent background, which results in images which
    can not be used for stacking on top of other layers, as they would completely
    obscure them."""

    PASTE_MASK_ALPHA: ClassVar[ColorScheme]
    """Default color of paste mask layer with alpha channel.

    This schema provides transparent background. Images using this schema can be
    stacked on top of each other without obscuring layers below."""

    SOLDER_MASK: ClassVar[ColorScheme]
    """Default color of solder mask layer.

    This schema provided non-transparent background, which results in images which
    can not be used for stacking on top of other layers, as they would completely
    obscure them."""

    SOLDER_MASK_ALPHA: ClassVar[ColorScheme]
    """Default color of solder mask layer with alpha channel.

    This schema provides transparent background. Images using this schema can be
    stacked on top of each other without obscuring layers below."""

    DEFAULT_GRAYSCALE: ClassVar[ColorScheme]
    """Default color scheme for files which were not assigned other color scheme."""

    DEBUG_1: ClassVar[ColorScheme]
    """Debug color scheme."""

    DEBUG_1_ALPHA: ClassVar[ColorScheme]
    """Debug color scheme with alpha channel."""

    background_color: RGBA
    """Color used as empty image background."""

    clear_color: RGBA
    """Color used for clear draws."""

    solid_color: RGBA
    """Color used for solid draws."""

    clear_region_color: RGBA
    """Color used for clear region draws."""

    solid_region_color: RGBA
    """Color used for solid region draws."""

    debug_1_color: RGBA = RGBA.from_hex("#ababab")
    """Color used for debug elements."""

    debug_2_color: RGBA = RGBA.from_hex("#7d7d7d")
    """Color used for debug elements."""

    def get_grayscale_to_rgba_color_map(self) -> dict[int, tuple[int, int, int, int]]:
        """Return grayscale to RGBA color map."""
        return {
            Polarity.Dark.get_2d_rasterized_color(): self.solid_color.as_rgba_int(),
            Polarity.Clear.get_2d_rasterized_color(): self.clear_color.as_rgba_int(),
            Polarity.DarkRegion.get_2d_rasterized_color(): self.solid_region_color.as_rgba_int(),  # noqa: E501
            Polarity.ClearRegion.get_2d_rasterized_color(): self.clear_region_color.as_rgba_int(),  # noqa: E501
            Polarity.Background.get_2d_rasterized_color(): self.background_color.as_rgba_int(),  # noqa: E501
            Polarity.DEBUG.get_2d_rasterized_color(): self.debug_1_color.as_rgba_int(),
            Polarity.DEBUG2.get_2d_rasterized_color(): self.debug_2_color.as_rgba_int(),
        }

SILK class-attribute

SILK: ColorScheme

Default color of silk layer.

This schema provided non-transparent background, which results in images which can not be used for stacking on top of other layers, as they would completely obscure them.

SILK_ALPHA class-attribute

SILK_ALPHA: ColorScheme

Default color of silk layer with alpha channel.

This schema provides transparent background. Images using this schema can be stacked on top of each other without obscuring layers below.

COPPER class-attribute

COPPER: ColorScheme

Default color of copper layer.

This schema provided non-transparent background, which results in images which can not be used for stacking on top of other layers, as they would completely obscure them.

COPPER_ALPHA class-attribute

COPPER_ALPHA: ColorScheme

Default color of copper layer with alpha channel.

This schema provides transparent background. Images using this schema can be stacked on top of each other without obscuring layers below.

PASTE_MASK class-attribute

PASTE_MASK: ColorScheme

Default color of paste mask layer.

This schema provided non-transparent background, which results in images which can not be used for stacking on top of other layers, as they would completely obscure them.

PASTE_MASK_ALPHA class-attribute

PASTE_MASK_ALPHA: ColorScheme

Default color of paste mask layer with alpha channel.

This schema provides transparent background. Images using this schema can be stacked on top of each other without obscuring layers below.

SOLDER_MASK class-attribute

SOLDER_MASK: ColorScheme

Default color of solder mask layer.

This schema provided non-transparent background, which results in images which can not be used for stacking on top of other layers, as they would completely obscure them.

SOLDER_MASK_ALPHA class-attribute

SOLDER_MASK_ALPHA: ColorScheme

Default color of solder mask layer with alpha channel.

This schema provides transparent background. Images using this schema can be stacked on top of each other without obscuring layers below.

DEFAULT_GRAYSCALE class-attribute

DEFAULT_GRAYSCALE: ColorScheme

Default color scheme for files which were not assigned other color scheme.

DEBUG_1 class-attribute

DEBUG_1: ColorScheme

Debug color scheme.

DEBUG_1_ALPHA class-attribute

DEBUG_1_ALPHA: ColorScheme

Debug color scheme with alpha channel.

background_color instance-attribute

background_color: RGBA

Color used as empty image background.

clear_color instance-attribute

clear_color: RGBA

Color used for clear draws.

solid_color instance-attribute

solid_color: RGBA

Color used for solid draws.

clear_region_color instance-attribute

clear_region_color: RGBA

Color used for clear region draws.

solid_region_color instance-attribute

solid_region_color: RGBA

Color used for solid region draws.

debug_1_color class-attribute instance-attribute

debug_1_color: RGBA = from_hex('#ababab')

Color used for debug elements.

debug_2_color class-attribute instance-attribute

debug_2_color: RGBA = from_hex('#7d7d7d')

Color used for debug elements.

get_grayscale_to_rgba_color_map

get_grayscale_to_rgba_color_map() -> (
    dict[int, tuple[int, int, int, int]]
)

Return grayscale to RGBA color map.

Source code in src\pygerber\backend\rasterized_2d\color_scheme.py
def get_grayscale_to_rgba_color_map(self) -> dict[int, tuple[int, int, int, int]]:
    """Return grayscale to RGBA color map."""
    return {
        Polarity.Dark.get_2d_rasterized_color(): self.solid_color.as_rgba_int(),
        Polarity.Clear.get_2d_rasterized_color(): self.clear_color.as_rgba_int(),
        Polarity.DarkRegion.get_2d_rasterized_color(): self.solid_region_color.as_rgba_int(),  # noqa: E501
        Polarity.ClearRegion.get_2d_rasterized_color(): self.clear_region_color.as_rgba_int(),  # noqa: E501
        Polarity.Background.get_2d_rasterized_color(): self.background_color.as_rgba_int(),  # noqa: E501
        Polarity.DEBUG.get_2d_rasterized_color(): self.debug_1_color.as_rgba_int(),
        Polarity.DEBUG2.get_2d_rasterized_color(): self.debug_2_color.as_rgba_int(),
    }

RGBA

Bases: FrozenGeneralModel

Representation of RGBA color.

Source code in src\pygerber\common\rgba.py
class RGBA(FrozenGeneralModel):
    """Representation of RGBA color."""

    r: Color = ColorField
    g: Color = ColorField
    b: Color = ColorField
    a: Color = ColorField

    @classmethod
    def from_hex(cls, string: str) -> Self:
        """Build RGBA color object from hexadecimal string.

        Parameters
        ----------
        string : str
            String containing color value. Accepted formats are `RRGGBBAA` and `RRGGBB`.
            For latter, alpha value is assumed to be 0xFF. Formats are case insensitive.
            `#` symbol prefix for hex string is accepted.

        Returns
        -------
        RGBA
            Color built from hexadecimal values.

        """
        if string[0] == "#":
            string = string[1:]

        r, g, b, a = string[:2], string[2:4], string[4:6], string[6:]
        if len(a) == 0:
            a = "FF"

        return cls(
            r=int(r, base=16),
            g=int(g, base=16),
            b=int(b, base=16),
            a=int(a, base=16),
        )

    @classmethod
    def from_rgba(cls, r: int, g: int, b: int, a: int = 0xFF) -> Self:
        """Build RGBA color object from reg, green, blue and alpha integer values.

        Parameters
        ----------
        r : int
            Red chanel value as integer from 0 to 255, inclusive.
        g : int
            Green chanel value as integer from 0 to 255, inclusive.
        b : int
            Blue chanel value as integer from 0 to 255, inclusive.
        a : int, optional
            Alpha chanel value as integer from 0 to 255, inclusive., by default 0xFF

        Returns
        -------
        Self
            Color built from r, g, b, a values.

        """
        return cls(r=r, g=g, b=b, a=a)

    @classmethod
    def from_hsv(
        cls,
        h: int,
        s: float,
        v: float,
        a: int = 255,
    ) -> Self:
        """Build RGBA color object from hue, saturation, value and alpha.

        For extended information refer to Wikipedia: https://en.wikipedia.org/wiki/HSL_and_HSV

        Parameters
        ----------
        h : int
            Hue of color, integer in range 0 to 360 inclusive.
        s : float
            Saturation of color, float in range 0.0 to 100.0 inclusive.
        v : float
            Value of color, float in range 0.0 to 100.0 inclusive.
        a : int
            Alpha of color, int in range 0 to 255 inclusive.

        Returns
        -------
        Self
            Color built from h, s, v, a values.

        """
        h %= 360
        s /= 100
        v /= 100

        c = v * s
        x = c * (1 - abs(((h / 60) % 2) - 1))
        m = v - c

        if 0 <= h < HSV_Q0_MAX_ANGLE_DEGREES:
            r_, g_, b_ = c, x, 0.0
        elif HSV_Q0_MAX_ANGLE_DEGREES <= h < HSV_Q1_MAX_ANGLE_DEGREES:
            r_, g_, b_ = x, c, 0.0
        elif HSV_Q1_MAX_ANGLE_DEGREES <= h < HSV_Q2_MAX_ANGLE_DEGREES:
            r_, g_, b_ = 0.0, c, x
        elif HSV_Q2_MAX_ANGLE_DEGREES <= h < HSV_Q3_MAX_ANGLE_DEGREES:
            r_, g_, b_ = 0.0, x, c
        elif HSV_Q3_MAX_ANGLE_DEGREES <= h < HSV_Q4_MAX_ANGLE_DEGREES:
            r_, g_, b_ = x, 0.0, c
        elif HSV_Q4_MAX_ANGLE_DEGREES <= h <= HSV_Q5_MAX_ANGLE_DEGREES:
            r_, g_, b_ = c, 0.0, x
        else:
            raise ValueError(h)

        return cls(
            r=round((r_ + m) * 255),
            g=round((g_ + m) * 255),
            b=round((b_ + m) * 255),
            a=a,
        )

    def as_rgba_int(self) -> tuple[int, int, int, int]:
        """Return RGBA color as tuple of integers in range 0 to 255 inclusive."""
        return self.r, self.g, self.b, self.a

    def as_rgb_int(self) -> tuple[int, int, int]:
        """Return RGB color as tuple of integers in range 0 to 255 inclusive."""
        return self.r, self.g, self.b

    def as_rgba_float(self) -> tuple[float, float, float, float]:
        """Return RGBA color as tuple of floats in range 0.0 to 1.0 inclusive."""
        return (
            float(Decimal(self.r) / Decimal(255)),
            float(Decimal(self.g) / Decimal(255)),
            float(Decimal(self.b) / Decimal(255)),
            float(Decimal(self.a) / Decimal(255)),
        )

    def to_hex(self) -> str:
        """Return color as hexadecimal string.

        Eg. `#FF0000FF` for red color.
        """
        r = f"{self.r:0{2}x}"
        g = f"{self.g:0{2}x}"
        b = f"{self.b:0{2}x}"
        a = f"{self.a:0{2}x}"
        return f"#{r}{g}{b}{a}"

from_hex classmethod

from_hex(string: str) -> Self

Build RGBA color object from hexadecimal string.

Parameters:

Name Type Description Default
string str

String containing color value. Accepted formats are RRGGBBAA and RRGGBB. For latter, alpha value is assumed to be 0xFF. Formats are case insensitive. # symbol prefix for hex string is accepted.

required

Returns:

Type Description
RGBA

Color built from hexadecimal values.

Source code in src\pygerber\common\rgba.py
@classmethod
def from_hex(cls, string: str) -> Self:
    """Build RGBA color object from hexadecimal string.

    Parameters
    ----------
    string : str
        String containing color value. Accepted formats are `RRGGBBAA` and `RRGGBB`.
        For latter, alpha value is assumed to be 0xFF. Formats are case insensitive.
        `#` symbol prefix for hex string is accepted.

    Returns
    -------
    RGBA
        Color built from hexadecimal values.

    """
    if string[0] == "#":
        string = string[1:]

    r, g, b, a = string[:2], string[2:4], string[4:6], string[6:]
    if len(a) == 0:
        a = "FF"

    return cls(
        r=int(r, base=16),
        g=int(g, base=16),
        b=int(b, base=16),
        a=int(a, base=16),
    )

from_rgba classmethod

from_rgba(r: int, g: int, b: int, a: int = 255) -> Self

Build RGBA color object from reg, green, blue and alpha integer values.

Parameters:

Name Type Description Default
r int

Red chanel value as integer from 0 to 255, inclusive.

required
g int

Green chanel value as integer from 0 to 255, inclusive.

required
b int

Blue chanel value as integer from 0 to 255, inclusive.

required
a int

Alpha chanel value as integer from 0 to 255, inclusive., by default 0xFF

255

Returns:

Type Description
Self

Color built from r, g, b, a values.

Source code in src\pygerber\common\rgba.py
@classmethod
def from_rgba(cls, r: int, g: int, b: int, a: int = 0xFF) -> Self:
    """Build RGBA color object from reg, green, blue and alpha integer values.

    Parameters
    ----------
    r : int
        Red chanel value as integer from 0 to 255, inclusive.
    g : int
        Green chanel value as integer from 0 to 255, inclusive.
    b : int
        Blue chanel value as integer from 0 to 255, inclusive.
    a : int, optional
        Alpha chanel value as integer from 0 to 255, inclusive., by default 0xFF

    Returns
    -------
    Self
        Color built from r, g, b, a values.

    """
    return cls(r=r, g=g, b=b, a=a)

from_hsv classmethod

from_hsv(h: int, s: float, v: float, a: int = 255) -> Self

Build RGBA color object from hue, saturation, value and alpha.

For extended information refer to Wikipedia: https://en.wikipedia.org/wiki/HSL_and_HSV

Parameters:

Name Type Description Default
h int

Hue of color, integer in range 0 to 360 inclusive.

required
s float

Saturation of color, float in range 0.0 to 100.0 inclusive.

required
v float

Value of color, float in range 0.0 to 100.0 inclusive.

required
a int

Alpha of color, int in range 0 to 255 inclusive.

255

Returns:

Type Description
Self

Color built from h, s, v, a values.

Source code in src\pygerber\common\rgba.py
@classmethod
def from_hsv(
    cls,
    h: int,
    s: float,
    v: float,
    a: int = 255,
) -> Self:
    """Build RGBA color object from hue, saturation, value and alpha.

    For extended information refer to Wikipedia: https://en.wikipedia.org/wiki/HSL_and_HSV

    Parameters
    ----------
    h : int
        Hue of color, integer in range 0 to 360 inclusive.
    s : float
        Saturation of color, float in range 0.0 to 100.0 inclusive.
    v : float
        Value of color, float in range 0.0 to 100.0 inclusive.
    a : int
        Alpha of color, int in range 0 to 255 inclusive.

    Returns
    -------
    Self
        Color built from h, s, v, a values.

    """
    h %= 360
    s /= 100
    v /= 100

    c = v * s
    x = c * (1 - abs(((h / 60) % 2) - 1))
    m = v - c

    if 0 <= h < HSV_Q0_MAX_ANGLE_DEGREES:
        r_, g_, b_ = c, x, 0.0
    elif HSV_Q0_MAX_ANGLE_DEGREES <= h < HSV_Q1_MAX_ANGLE_DEGREES:
        r_, g_, b_ = x, c, 0.0
    elif HSV_Q1_MAX_ANGLE_DEGREES <= h < HSV_Q2_MAX_ANGLE_DEGREES:
        r_, g_, b_ = 0.0, c, x
    elif HSV_Q2_MAX_ANGLE_DEGREES <= h < HSV_Q3_MAX_ANGLE_DEGREES:
        r_, g_, b_ = 0.0, x, c
    elif HSV_Q3_MAX_ANGLE_DEGREES <= h < HSV_Q4_MAX_ANGLE_DEGREES:
        r_, g_, b_ = x, 0.0, c
    elif HSV_Q4_MAX_ANGLE_DEGREES <= h <= HSV_Q5_MAX_ANGLE_DEGREES:
        r_, g_, b_ = c, 0.0, x
    else:
        raise ValueError(h)

    return cls(
        r=round((r_ + m) * 255),
        g=round((g_ + m) * 255),
        b=round((b_ + m) * 255),
        a=a,
    )

as_rgba_int

as_rgba_int() -> tuple[int, int, int, int]

Return RGBA color as tuple of integers in range 0 to 255 inclusive.

Source code in src\pygerber\common\rgba.py
def as_rgba_int(self) -> tuple[int, int, int, int]:
    """Return RGBA color as tuple of integers in range 0 to 255 inclusive."""
    return self.r, self.g, self.b, self.a

as_rgb_int

as_rgb_int() -> tuple[int, int, int]

Return RGB color as tuple of integers in range 0 to 255 inclusive.

Source code in src\pygerber\common\rgba.py
def as_rgb_int(self) -> tuple[int, int, int]:
    """Return RGB color as tuple of integers in range 0 to 255 inclusive."""
    return self.r, self.g, self.b

as_rgba_float

as_rgba_float() -> tuple[float, float, float, float]

Return RGBA color as tuple of floats in range 0.0 to 1.0 inclusive.

Source code in src\pygerber\common\rgba.py
def as_rgba_float(self) -> tuple[float, float, float, float]:
    """Return RGBA color as tuple of floats in range 0.0 to 1.0 inclusive."""
    return (
        float(Decimal(self.r) / Decimal(255)),
        float(Decimal(self.g) / Decimal(255)),
        float(Decimal(self.b) / Decimal(255)),
        float(Decimal(self.a) / Decimal(255)),
    )

to_hex

to_hex() -> str

Return color as hexadecimal string.

Eg. #FF0000FF for red color.

Source code in src\pygerber\common\rgba.py
def to_hex(self) -> str:
    """Return color as hexadecimal string.

    Eg. `#FF0000FF` for red color.
    """
    r = f"{self.r:0{2}x}"
    g = f"{self.g:0{2}x}"
    b = f"{self.b:0{2}x}"
    a = f"{self.a:0{2}x}"
    return f"#{r}{g}{b}{a}"

GerberX3APIError

Bases: Exception

Base class for API errors.

Exceptions derived from this exception are exclusively raised in PyGerber's Gerber X3 high level API. This exception can be used in try: ... except GerberX3APIError: ... block to catch all exceptions raised by this API while allowing other exceptions to interrupt execution.

Source code in src\pygerber\gerberx3\api\_errors.py
class GerberX3APIError(Exception):
    """Base class for API errors.

    Exceptions derived from this exception are exclusively raised in PyGerber's Gerber
    X3 high level API. This exception can be used in
    `#!python try: ... except GerberX3APIError: ...` block to catch all exceptions
    raised by this API while allowing other exceptions to interrupt execution.
    """

MutuallyExclusiveViolationError

Bases: GerberX3APIError

Raised when two or more of mutually exclusive parameters are provided.

LayerParams class accepts three mutually exclusive fields, source_path, source_code and source_buffer for providing source code to Layer. When more than one of those options is set, this exception will be raised.

Source code in src\pygerber\gerberx3\api\_errors.py
class MutuallyExclusiveViolationError(GerberX3APIError):
    """Raised when two or more of mutually exclusive parameters are provided.

    `LayerParams` class accepts three mutually exclusive fields, `source_path`,
    `source_code` and `source_buffer` for providing source code to `Layer`.
    When more than one of those options is set, this exception will be raised.
    """

RenderingResultNotReadyError

Bases: GerberX3APIError

Raised when RenderingResult is requested before it was rendered.

Layer.get_rendering_result() method can only be called after Layer.render(). Breaking this rule will cause this exception to be raised.

Source code in src\pygerber\gerberx3\api\_errors.py
class RenderingResultNotReadyError(GerberX3APIError):
    """Raised when RenderingResult is requested before it was rendered.

    `Layer.get_rendering_result()` method can only be called after `Layer.render()`.
    Breaking this rule will cause this exception to be raised.
    """

Layer

Representation of Gerber X3 image layer.

This is only abstract base class, please use one of its subclasses with rendering system guarantees.

Source code in src\pygerber\gerberx3\api\_layers.py
class Layer:
    """Representation of Gerber X3 image layer.

    This is only abstract base class, please use one of its subclasses with rendering
    system guarantees.
    """

    def __init__(self, options: LayerParams) -> None:
        """Create PCB layer.

        Parameters
        ----------
        options: LayerOptions
            Configuration of layer.

        """
        self.options = options

        self.tokenizer = self._create_tokenizer()
        self.backend = self._create_backend()
        self.parser = self._create_parser()

        self._rendering_result: Optional[RenderingResult] = None

    def _create_tokenizer(self) -> Tokenizer:
        return Tokenizer()

    @abstractmethod
    def _create_backend(self) -> Backend:
        pass

    def _create_parser(self) -> Parser:
        return Parser(
            ParserOptions(
                backend=self.backend,
                on_update_drawing_state_error=self.options.parser_error,
            ),
        )

    def render(self) -> RenderingResult:
        """Render layer image."""
        stack = self.tokenizer.tokenize(self.options.get_source_code())
        draw_commands = self.parser.parse(stack)

        result_handle = draw_commands.draw()
        properties = LayerProperties(
            target_bounding_box=self.backend.drawing_target.bounding_box,
            target_coordinate_origin=self.backend.drawing_target.coordinate_origin,
            gerber_bounding_box=self.backend.bounding_box,
            gerber_coordinate_origin=self.backend.coordinate_origin,
        )

        self._rendering_result = self._get_rendering_result_cls()(
            result_handle=result_handle,
            properties=properties,
        )
        return self._rendering_result

    def _get_rendering_result_cls(self) -> type[RenderingResult]:
        return RenderingResult

    def get_rendering_result(self) -> RenderingResult:
        """Return result of rendering Gerber file."""
        if self._rendering_result is None:
            msg = "Use `render()` method to create result first."
            raise RenderingResultNotReadyError(msg)

        return self._rendering_result

__init__

__init__(options: LayerParams) -> None

Create PCB layer.

Parameters:

Name Type Description Default
options LayerParams

Configuration of layer.

required
Source code in src\pygerber\gerberx3\api\_layers.py
def __init__(self, options: LayerParams) -> None:
    """Create PCB layer.

    Parameters
    ----------
    options: LayerOptions
        Configuration of layer.

    """
    self.options = options

    self.tokenizer = self._create_tokenizer()
    self.backend = self._create_backend()
    self.parser = self._create_parser()

    self._rendering_result: Optional[RenderingResult] = None

render

render() -> RenderingResult

Render layer image.

Source code in src\pygerber\gerberx3\api\_layers.py
def render(self) -> RenderingResult:
    """Render layer image."""
    stack = self.tokenizer.tokenize(self.options.get_source_code())
    draw_commands = self.parser.parse(stack)

    result_handle = draw_commands.draw()
    properties = LayerProperties(
        target_bounding_box=self.backend.drawing_target.bounding_box,
        target_coordinate_origin=self.backend.drawing_target.coordinate_origin,
        gerber_bounding_box=self.backend.bounding_box,
        gerber_coordinate_origin=self.backend.coordinate_origin,
    )

    self._rendering_result = self._get_rendering_result_cls()(
        result_handle=result_handle,
        properties=properties,
    )
    return self._rendering_result

get_rendering_result

get_rendering_result() -> RenderingResult

Return result of rendering Gerber file.

Source code in src\pygerber\gerberx3\api\_layers.py
def get_rendering_result(self) -> RenderingResult:
    """Return result of rendering Gerber file."""
    if self._rendering_result is None:
        msg = "Use `render()` method to create result first."
        raise RenderingResultNotReadyError(msg)

    return self._rendering_result

LayerParams

Bases: BaseModel

Parameters for Layer object.

source_path, source_code and source_buffer are mutually exclusive. When more than one of them is provided to constructor, MutuallyExclusiveViolationError will be raised.

Source code in src\pygerber\gerberx3\api\_layers.py
class LayerParams(BaseModel):
    """Parameters for Layer object.

    `source_path`, `source_code` and `source_buffer` are mutually exclusive.
    When more than one of them is provided to constructor,
    MutuallyExclusiveViolationError will be raised.
    """

    model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid")

    source_path: Optional[Union[Path, str]] = None
    """Path to source file containing Gerber code. It will be automatically loaded
    from local storage, when provided. Mutually exclusive with `source_code` and
    `source_buffer`.
    """

    source_code: Optional[Union[str, bytes]] = None
    """Gerber source code. Mutually exclusive with `source_path` and `source_buffer`."""

    source_buffer: Optional[Union[StringIO, BytesIO]] = None
    """Buffer containing Gerber source code. Buffer pointer should be at the
    beginning of the buffer. Mutually exclusive with `source_path` and
    `source_code`."""

    parser_error: Union[
        Callable[[Exception, Parser, Token], None],
        ParserOnErrorAction,
    ] = ParserOnErrorAction.Raise
    """Callback function or rule describing how to treat errors during parsing."""

    encoding: str = "utf-8"
    """Encoding of code, used when loading from file, decoding `source_code`
    provided as bytes and reading `source_buffer` provided as BytesIO."""

    draw_region_outlines: bool = False
    """When drawing regions, after filling region, draw also outline of region with
    apertures used for region outlines. This behavior is not expected by KiCAD by
    default but may be useful in some scenarios."""

    @model_validator(mode="after")
    def _load_source_code(self) -> Self:
        """Load source code.

        Raises
        ------
        MutuallyExclusiveViolationError
            When more than one of mutually exclusive `source_path`, `source_code` and
            `source_buffer` is provided to constructor.

        """
        if self.source_path:
            if self.source_code or self.source_buffer:
                msg = "'source_code' and 'source_buffer' provided at once."
                raise MutuallyExclusiveViolationError(msg)

            self.source_code = (
                Path(self.source_path or "source.grb")
                .expanduser()
                .resolve()
                .read_text(encoding=self.encoding)
            )
            return self

        if self.source_code:
            if self.source_path or self.source_buffer:
                msg = "'source_path' and 'source_buffer' provided at once."
                raise MutuallyExclusiveViolationError(msg)

            self.source_code = (
                self.source_code
                if isinstance(self.source_code, str)
                else self.source_code.decode(self.encoding)
            )
            return self

        if self.source_buffer:
            if self.source_path or self.source_code:
                msg = "'source_path' and 'source_buffer' provided at once."
                raise MutuallyExclusiveViolationError(msg)

            source_code = self.source_buffer.read()
            if isinstance(source_code, bytes):
                self.source_code = source_code.decode(encoding="utf-8")
            else:
                self.source_code = source_code

        return self

    def get_source_code(self) -> str:
        """Return source code of layer."""
        if not isinstance(self.source_code, str):
            msg = f"Expected {str} got {type(self.source_code)}."
            raise TypeError(msg)

        return self.source_code

source_path class-attribute instance-attribute

source_path: Optional[Union[Path, str]] = None

Path to source file containing Gerber code. It will be automatically loaded from local storage, when provided. Mutually exclusive with source_code and source_buffer.

source_code class-attribute instance-attribute

source_code: Optional[Union[str, bytes]] = None

Gerber source code. Mutually exclusive with source_path and source_buffer.

source_buffer class-attribute instance-attribute

source_buffer: Optional[Union[StringIO, BytesIO]] = None

Buffer containing Gerber source code. Buffer pointer should be at the beginning of the buffer. Mutually exclusive with source_path and source_code.

parser_error class-attribute instance-attribute

parser_error: Union[
    Callable[[Exception, Parser, Token], None],
    ParserOnErrorAction,
] = Raise

Callback function or rule describing how to treat errors during parsing.

encoding class-attribute instance-attribute

encoding: str = 'utf-8'

Encoding of code, used when loading from file, decoding source_code provided as bytes and reading source_buffer provided as BytesIO.

draw_region_outlines class-attribute instance-attribute

draw_region_outlines: bool = False

When drawing regions, after filling region, draw also outline of region with apertures used for region outlines. This behavior is not expected by KiCAD by default but may be useful in some scenarios.

get_source_code

get_source_code() -> str

Return source code of layer.

Source code in src\pygerber\gerberx3\api\_layers.py
def get_source_code(self) -> str:
    """Return source code of layer."""
    if not isinstance(self.source_code, str):
        msg = f"Expected {str} got {type(self.source_code)}."
        raise TypeError(msg)

    return self.source_code

LayerProperties

Properties of layer retrieved from Gerber source code.

Source code in src\pygerber\gerberx3\api\_layers.py
class LayerProperties:
    """Properties of layer retrieved from Gerber source code."""

    target_bounding_box: BoundingBox
    """Bounding box of rendering target. May differ from coordinates used in Gerber
    file as it uses rendering target coordinate space."""

    target_coordinate_origin: Vector2D
    """Offset of origin of coordinate system used by rendering target. Bottom left
    corner of coordinate space of rendering target."""

    gerber_bounding_box: BoundingBox
    """Bounding box of drawing area in Gerber file coordinate space."""

    gerber_coordinate_origin: Vector2D
    """Origin of coordinate space of Gerber file. Equivalent to bottom left corner of
    `gerber_bounding_box`.

    Can be useful to determine how to align multiple Gerber files by calculating
    how their coordinate origins are positioned in relation to each other."""

    def __init__(
        self,
        target_bounding_box: BoundingBox,
        target_coordinate_origin: Vector2D,
        gerber_bounding_box: BoundingBox,
        gerber_coordinate_origin: Vector2D,
    ) -> None:
        """Initialize layer properties."""
        self.target_bounding_box = target_bounding_box
        self.target_coordinate_origin = target_coordinate_origin

        self.gerber_bounding_box = gerber_bounding_box
        self.gerber_coordinate_origin = gerber_coordinate_origin

target_bounding_box instance-attribute

target_bounding_box: BoundingBox = target_bounding_box

Bounding box of rendering target. May differ from coordinates used in Gerber file as it uses rendering target coordinate space.

target_coordinate_origin instance-attribute

target_coordinate_origin: Vector2D = (
    target_coordinate_origin
)

Offset of origin of coordinate system used by rendering target. Bottom left corner of coordinate space of rendering target.

gerber_bounding_box instance-attribute

gerber_bounding_box: BoundingBox = gerber_bounding_box

Bounding box of drawing area in Gerber file coordinate space.

gerber_coordinate_origin instance-attribute

gerber_coordinate_origin: Vector2D = (
    gerber_coordinate_origin
)

Origin of coordinate space of Gerber file. Equivalent to bottom left corner of gerber_bounding_box.

Can be useful to determine how to align multiple Gerber files by calculating how their coordinate origins are positioned in relation to each other.

__init__

__init__(
    target_bounding_box: BoundingBox,
    target_coordinate_origin: Vector2D,
    gerber_bounding_box: BoundingBox,
    gerber_coordinate_origin: Vector2D,
) -> None

Initialize layer properties.

Source code in src\pygerber\gerberx3\api\_layers.py
def __init__(
    self,
    target_bounding_box: BoundingBox,
    target_coordinate_origin: Vector2D,
    gerber_bounding_box: BoundingBox,
    gerber_coordinate_origin: Vector2D,
) -> None:
    """Initialize layer properties."""
    self.target_bounding_box = target_bounding_box
    self.target_coordinate_origin = target_coordinate_origin

    self.gerber_bounding_box = gerber_bounding_box
    self.gerber_coordinate_origin = gerber_coordinate_origin

Rasterized2DLayer

Bases: Layer

Representation of Gerber X3 rasterized 2D image layer.

Rasterized images can be saved in any image format supported by Pillow library. For full list of supported formats please refer to Pillow documentation.

Source code in src\pygerber\gerberx3\api\_layers.py
class Rasterized2DLayer(Layer):
    """Representation of Gerber X3 rasterized 2D image layer.

    Rasterized images can be saved in any image format supported by Pillow library.
    For full list of supported formats please refer to
    [Pillow documentation](https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html).
    """

    options: Rasterized2DLayerParams

    def __init__(self, options: Rasterized2DLayerParams) -> None:
        """Initialize Layer object."""
        if not isinstance(options, Rasterized2DLayerParams):
            msg = f"Expected {Rasterized2DLayerParams} got {type(options)}."  # type: ignore[unreachable]
            raise TypeError(msg)
        super().__init__(options)

    def _create_backend(self) -> Backend:
        return Rasterized2DBackend(
            Rasterized2DBackendOptions(
                dpi=self.options.dpi,
                color_scheme=self.options.colors,
                dump_apertures=self.options.debug_dump_apertures,
                include_debug_padding=self.options.debug_include_extra_padding,
                include_bounding_boxes=self.options.debug_include_bounding_boxes,
                draw_region_outlines=self.options.draw_region_outlines,
            ),
        )

    def _get_rendering_result_cls(self) -> type[RenderingResult]:
        return Rasterized2DRenderingResult

__init__

__init__(options: Rasterized2DLayerParams) -> None

Initialize Layer object.

Source code in src\pygerber\gerberx3\api\_layers.py
def __init__(self, options: Rasterized2DLayerParams) -> None:
    """Initialize Layer object."""
    if not isinstance(options, Rasterized2DLayerParams):
        msg = f"Expected {Rasterized2DLayerParams} got {type(options)}."  # type: ignore[unreachable]
        raise TypeError(msg)
    super().__init__(options)

Rasterized2DLayerParams

Bases: LayerParams

Parameters for Layer with 2D rendering.

source_path, source_code and source_buffer are mutually exclusive. When more than one of them is provided to constructor, MutuallyExclusiveViolationError will be raised.

Source code in src\pygerber\gerberx3\api\_layers.py
class Rasterized2DLayerParams(LayerParams):
    """Parameters for Layer with 2D rendering.

    `source_path`, `source_code` and `source_buffer` are mutually exclusive.
    When more than one of them is provided to constructor,
    MutuallyExclusiveViolationError will be raised.
    """

    colors: ColorScheme
    """Colors to use for rendering of image."""

    dpi: int = 1000
    """DPI of output image."""

    debug_dump_apertures: Optional[Path] = None
    """Debug option - dump aperture images to files in given directory."""

    debug_include_extra_padding: bool = False
    """Debug option - include large extra padding on all rendering targets to simplify
    tracking of mispositioned draw commands."""

    debug_include_bounding_boxes: bool = False
    """Debug option - include bounding boxes as square outlines on drawing targets
    to simplify tracking of miscalculated bounding boxes."""

colors instance-attribute

colors: ColorScheme

Colors to use for rendering of image.

dpi class-attribute instance-attribute

dpi: int = 1000

DPI of output image.

debug_dump_apertures class-attribute instance-attribute

debug_dump_apertures: Optional[Path] = None

Debug option - dump aperture images to files in given directory.

debug_include_extra_padding class-attribute instance-attribute

debug_include_extra_padding: bool = False

Debug option - include large extra padding on all rendering targets to simplify tracking of mispositioned draw commands.

debug_include_bounding_boxes class-attribute instance-attribute

debug_include_bounding_boxes: bool = False

Debug option - include bounding boxes as square outlines on drawing targets to simplify tracking of miscalculated bounding boxes.

RenderingResult

Result of rendering of layer.

Source code in src\pygerber\gerberx3\api\_layers.py
class RenderingResult:
    """Result of rendering of layer."""

    def __init__(
        self,
        properties: LayerProperties,
        result_handle: ResultHandle,
    ) -> None:
        """Initialize rendering result object."""
        self._properties = properties
        self._result_handle = result_handle

    def save(
        self,
        dest: Path | str | BytesIO,
        **options: Any,
    ) -> None:
        """Save result to specified file or buffer.

        Parameters
        ----------
        dest : Path | str | BytesIO
            Write target.
        **options: Any
            Extra parameters which will be passed to saving implementation.
            When dest is BytesIO or alike, `format` option must be specified.
            For Rasterized2D rendering options see [Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.save).

        """
        self._result_handle.save(dest, **options)

    def get_properties(self) -> LayerProperties:
        """Get properties of layer."""
        return self._properties

__init__

__init__(
    properties: LayerProperties, result_handle: ResultHandle
) -> None

Initialize rendering result object.

Source code in src\pygerber\gerberx3\api\_layers.py
def __init__(
    self,
    properties: LayerProperties,
    result_handle: ResultHandle,
) -> None:
    """Initialize rendering result object."""
    self._properties = properties
    self._result_handle = result_handle

save

save(dest: Path | str | BytesIO, **options: Any) -> None

Save result to specified file or buffer.

Parameters:

Name Type Description Default
dest Path | str | BytesIO

Write target.

required
**options Any

Extra parameters which will be passed to saving implementation. When dest is BytesIO or alike, format option must be specified. For Rasterized2D rendering options see Pillow documentation.

{}
Source code in src\pygerber\gerberx3\api\_layers.py
def save(
    self,
    dest: Path | str | BytesIO,
    **options: Any,
) -> None:
    """Save result to specified file or buffer.

    Parameters
    ----------
    dest : Path | str | BytesIO
        Write target.
    **options: Any
        Extra parameters which will be passed to saving implementation.
        When dest is BytesIO or alike, `format` option must be specified.
        For Rasterized2D rendering options see [Pillow documentation](https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.save).

    """
    self._result_handle.save(dest, **options)

get_properties

get_properties() -> LayerProperties

Get properties of layer.

Source code in src\pygerber\gerberx3\api\_layers.py
def get_properties(self) -> LayerProperties:
    """Get properties of layer."""
    return self._properties

ApertureNotDefinedError

Bases: ParserError

Raised when undefined aperture is selected.

Source code in src\pygerber\gerberx3\parser\errors.py
class ApertureNotDefinedError(ParserError):
    """Raised when undefined aperture is selected."""

ApertureNotSelectedError

Bases: ParserError

Raised when attempting to use aperture without selecting it first.

Source code in src\pygerber\gerberx3\parser\errors.py
class ApertureNotSelectedError(ParserError):
    """Raised when attempting to use aperture without selecting it first."""

CoordinateFormatNotSetError

Bases: ParserError

Raised when coordinate parser is requested before coordinate format was set.

Source code in src\pygerber\gerberx3\parser\errors.py
class CoordinateFormatNotSetError(ParserError):
    """Raised when coordinate parser is requested before coordinate format was set."""

ExitParsingProcessInterrupt

Bases: Exception

Raised to stop parsing.

Source code in src\pygerber\gerberx3\parser\errors.py
class ExitParsingProcessInterrupt(Exception):  # noqa: N818
    """Raised to stop parsing."""

IncrementalCoordinatesNotSupportedError

Bases: ParserError

Raised when incremental coordinates are selected. (Spec. 8.2.1.2).

Source code in src\pygerber\gerberx3\parser\errors.py
class IncrementalCoordinatesNotSupportedError(ParserError):
    """Raised when incremental coordinates are selected. (Spec. 8.2.1.2)."""

InvalidCoordinateLengthError

Bases: ParserError

Raised when coordinate string is too long.

Source code in src\pygerber\gerberx3\parser\errors.py
class InvalidCoordinateLengthError(ParserError):
    """Raised when coordinate string is too long."""

OnUpdateDrawingStateError

Bases: ParserError

Raised when parser encounters fatal failure from non-parser specific exception during call to .update_drawing_state() call.

Source code in src\pygerber\gerberx3\parser\errors.py
class OnUpdateDrawingStateError(ParserError):
    """Raised when parser encounters fatal failure from non-parser specific
    exception during call to .update_drawing_state() call.
    """

    def __init__(self, token: Token, *args: object) -> None:
        super().__init__(*args)
        self.token = token

    def __str__(self) -> str:
        return f"{self.token} {self.token.get_token_position()}"

ParserError

Bases: ValueError

Base class for parser errors.

Exceptions derived from this exception are exclusively raised in PyGerber's Gerber X3 Parser. This exception can be used in try: ... except ParserError: ... block to catch all exceptions raised by Parser while allowing other exceptions to interrupt execution.

Source code in src\pygerber\gerberx3\parser\errors.py
class ParserError(ValueError):
    """Base class for parser errors.

    Exceptions derived from this exception are exclusively raised in PyGerber's Gerber
    X3 Parser. This exception can be used in
    `#!python try: ... except ParserError: ...` block to catch all exceptions
    raised by Parser while allowing other exceptions to interrupt execution.
    """

    def get_message(self) -> str:
        """Get parser error help message."""
        return f"{self.__class__.__qualname__}: {self.__doc__}"

get_message

get_message() -> str

Get parser error help message.

Source code in src\pygerber\gerberx3\parser\errors.py
def get_message(self) -> str:
    """Get parser error help message."""
    return f"{self.__class__.__qualname__}: {self.__doc__}"

ParserFatalError

Bases: ParserError

Raised when parser encounters fatal failure from non-parser specific exception.

Source code in src\pygerber\gerberx3\parser\errors.py
class ParserFatalError(ParserError):
    """Raised when parser encounters fatal failure from non-parser specific
    exception.
    """

UnitNotSetError

Bases: ParserError

Raised when operation which requires units to be set is executed before units are set.

Source code in src\pygerber\gerberx3\parser\errors.py
class UnitNotSetError(ParserError):
    """Raised when operation which requires units to be set is executed before units
    are set.
    """

UnsupportedCoordinateTypeError

Bases: ParserError

Raised for unsupported coordinate types.

Source code in src\pygerber\gerberx3\parser\errors.py
class UnsupportedCoordinateTypeError(ParserError):
    """Raised for unsupported coordinate types."""

ZeroOmissionNotSupportedError

Bases: ParserError

Raised when incremental coordinates are selected. (Spec. 8.2.1.2).

Source code in src\pygerber\gerberx3\parser\errors.py
class ZeroOmissionNotSupportedError(ParserError):
    """Raised when incremental coordinates are selected. (Spec. 8.2.1.2)."""

ParserOnErrorAction

Bases: Enum

Possible error actions.

Source code in src\pygerber\gerberx3\parser\parser.py
class ParserOnErrorAction(Enum):
    """Possible error actions."""

    Ignore = "ignore"
    """Ignore parser errors. Errors which occurred will not be signaled. May yield
    unexpected results for broken files, with missing draw commands or even more
    significant errors."""

    Warn = "warn"
    """Warn on parser error. Parser will log warning message about what went wrong.
    Best for supporting wide range of files without silently ignoring errors in code."""

    Raise = "raise"
    """Raise exception whenever parser encounters error. Will completely break out of
    parsing process, making it impossible to render slightly malformed files."""

Ignore class-attribute instance-attribute

Ignore = 'ignore'

Ignore parser errors. Errors which occurred will not be signaled. May yield unexpected results for broken files, with missing draw commands or even more significant errors.

Warn class-attribute instance-attribute

Warn = 'warn'

Warn on parser error. Parser will log warning message about what went wrong. Best for supporting wide range of files without silently ignoring errors in code.

Raise class-attribute instance-attribute

Raise = 'raise'

Raise exception whenever parser encounters error. Will completely break out of parsing process, making it impossible to render slightly malformed files.