Python interface for cairo graphics library providing 2D vector graphics, drawing operations, and rendering to multiple output formats
—
Pattern classes define the paint sources used in Cairo drawing operations. Patterns determine how areas are colored when filling shapes or stroking paths. Cairo supports solid colors, gradients, surface-based patterns, and advanced patterns like mesh gradients. All patterns can be transformed and have different extend modes for tiling behavior.
class Pattern:
def get_extend(self) -> Extend:
"""Get extend mode for pattern."""
def set_extend(self, extend: Extend) -> None:
"""Set extend mode (NONE, REPEAT, REFLECT, PAD)."""
def get_filter(self) -> Filter:
"""Get filter mode for pattern scaling."""
def set_filter(self, filter: Filter) -> None:
"""Set filter mode (FAST, GOOD, BEST, NEAREST, BILINEAR, GAUSSIAN)."""
def get_matrix(self) -> Matrix:
"""Get transformation matrix for pattern."""
def set_matrix(self, matrix: Matrix) -> None:
"""Set transformation matrix for pattern."""
def get_color_stop_count(self) -> int:
"""Get number of color stops in gradient pattern."""
def get_color_stop_rgba(self, index: int) -> tuple[float, float, float, float, float]:
"""Get color stop at index (offset, red, green, blue, alpha)."""
def get_rgba(self) -> tuple[float, float, float, float]:
"""Get RGBA values for solid pattern."""
def get_surface(self) -> Surface:
"""Get surface for surface pattern."""class SolidPattern(Pattern):
def __init__(self, red: float, green: float, blue: float, alpha: float = 1.0) -> None:
"""Create solid color pattern.
Args:
red: Red component (0.0 to 1.0)
green: Green component (0.0 to 1.0)
blue: Blue component (0.0 to 1.0)
alpha: Alpha component (0.0 to 1.0)
"""class SurfacePattern(Pattern):
def __init__(self, surface: Surface) -> None:
"""Create pattern from surface.
Args:
surface: Source surface for pattern
"""class Gradient(Pattern):
def add_color_stop_rgb(self, offset: float, red: float, green: float, blue: float) -> None:
"""Add RGB color stop to gradient.
Args:
offset: Position along gradient (0.0 to 1.0)
red: Red component (0.0 to 1.0)
green: Green component (0.0 to 1.0)
blue: Blue component (0.0 to 1.0)
"""
def add_color_stop_rgba(self, offset: float, red: float, green: float, blue: float, alpha: float) -> None:
"""Add RGBA color stop to gradient.
Args:
offset: Position along gradient (0.0 to 1.0)
red: Red component (0.0 to 1.0)
green: Green component (0.0 to 1.0)
blue: Blue component (0.0 to 1.0)
alpha: Alpha component (0.0 to 1.0)
"""
class LinearGradient(Gradient):
def __init__(self, x0: float, y0: float, x1: float, y1: float) -> None:
"""Create linear gradient between two points.
Args:
x0: X coordinate of start point
y0: Y coordinate of start point
x1: X coordinate of end point
y1: Y coordinate of end point
"""
def get_linear_points(self) -> tuple[float, float, float, float]:
"""Get linear gradient endpoints (x0, y0, x1, y1)."""
class RadialGradient(Gradient):
def __init__(self, cx0: float, cy0: float, radius0: float, cx1: float, cy1: float, radius1: float) -> None:
"""Create radial gradient between two circles.
Args:
cx0: X coordinate of first circle center
cy0: Y coordinate of first circle center
radius0: Radius of first circle
cx1: X coordinate of second circle center
cy1: Y coordinate of second circle center
radius1: Radius of second circle
"""
def get_radial_circles(self) -> tuple[float, float, float, float, float, float]:
"""Get radial gradient circles (cx0, cy0, radius0, cx1, cy1, radius1)."""class MeshPattern(Pattern):
def __init__(self) -> None:
"""Create empty mesh pattern."""
def begin_patch(self) -> None:
"""Begin new patch in mesh pattern."""
def end_patch(self) -> None:
"""End current patch."""
def move_to(self, x: float, y: float) -> None:
"""Move to point in current patch."""
def line_to(self, x: float, y: float) -> None:
"""Add line to current patch."""
def curve_to(self, x1: float, y1: float, x2: float, y2: float, x3: float, y3: float) -> None:
"""Add curve to current patch."""
def set_control_point(self, point_num: int, x: float, y: float) -> None:
"""Set control point in current patch."""
def set_corner_color_rgb(self, corner_num: int, red: float, green: float, blue: float) -> None:
"""Set RGB color for patch corner."""
def set_corner_color_rgba(self, corner_num: int, red: float, green: float, blue: float, alpha: float) -> None:
"""Set RGBA color for patch corner."""
def get_patch_count(self) -> int:
"""Get number of patches in mesh."""
def get_path(self, patch_num: int) -> Path:
"""Get path for specified patch."""
def get_control_point(self, patch_num: int, point_num: int) -> tuple[float, float]:
"""Get control point for specified patch."""
def get_corner_color_rgba(self, patch_num: int, corner_num: int) -> tuple[float, float, float, float]:
"""Get corner color for specified patch."""class RasterSourcePattern(Pattern):
def __init__(self, user_data: Any, content: Content, width: int, height: int) -> None:
"""Create raster source pattern with callback functions.
Args:
user_data: User data passed to callback functions
content: Content type (COLOR, ALPHA, COLOR_ALPHA)
width: Pattern width
height: Pattern height
"""
def set_callback_data(self, user_data: Any) -> None:
"""Set user data for callback functions."""
def get_callback_data(self) -> Any:
"""Get user data for callback functions."""
def set_acquire(self, acquire_func: Callable, release_func: Callable) -> None:
"""Set acquire and release callback functions."""
def set_snapshot(self, snapshot_func: Callable) -> None:
"""Set snapshot callback function."""
def set_copy(self, copy_func: Callable) -> None:
"""Set copy callback function."""
def set_finish(self, finish_func: Callable) -> None:
"""Set finish callback function."""import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(surface)
# Using set_source_rgb/rgba (creates SolidPattern internally)
ctx.set_source_rgb(0.8, 0.2, 0.2)
ctx.rectangle(50, 50, 100, 80)
ctx.fill()
# Creating SolidPattern explicitly
pattern = cairo.SolidPattern(0.2, 0.2, 0.8, 0.7) # Semi-transparent blue
ctx.set_source(pattern)
ctx.rectangle(200, 50, 100, 80)
ctx.fill()
surface.write_to_png("solid_patterns.png")import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(surface)
# Create linear gradient from left to right
gradient = cairo.LinearGradient(0, 0, 400, 0)
gradient.add_color_stop_rgb(0, 1, 0, 0) # Red at start
gradient.add_color_stop_rgb(0.5, 1, 1, 0) # Yellow at middle
gradient.add_color_stop_rgb(1, 0, 0, 1) # Blue at end
ctx.set_source(gradient)
ctx.rectangle(0, 0, 400, 300)
ctx.fill()
surface.write_to_png("linear_gradient.png")import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(surface)
# Create radial gradient from center outward
gradient = cairo.RadialGradient(200, 150, 20, 200, 150, 100)
gradient.add_color_stop_rgba(0, 1, 1, 1, 1) # White center
gradient.add_color_stop_rgba(0.7, 0.8, 0.4, 0.2, 0.8) # Orange
gradient.add_color_stop_rgba(1, 0.2, 0.2, 0.2, 0.5) # Dark transparent edge
ctx.set_source(gradient)
ctx.arc(200, 150, 120, 0, 2 * 3.14159)
ctx.fill()
surface.write_to_png("radial_gradient.png")import cairo
# Create source surface with pattern
pattern_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 50, 50)
pattern_ctx = cairo.Context(pattern_surface)
# Draw a simple pattern
pattern_ctx.set_source_rgb(0.8, 0.8, 0.9)
pattern_ctx.paint()
pattern_ctx.set_source_rgb(0.2, 0.4, 0.8)
pattern_ctx.rectangle(10, 10, 30, 30)
pattern_ctx.fill()
# Use as pattern with different extend modes
main_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(main_surface)
pattern = cairo.SurfacePattern(pattern_surface)
# Repeat pattern
pattern.set_extend(cairo.EXTEND_REPEAT)
ctx.set_source(pattern)
ctx.rectangle(0, 0, 200, 150)
ctx.fill()
# Reflect pattern
pattern.set_extend(cairo.EXTEND_REFLECT)
ctx.set_source(pattern)
ctx.rectangle(200, 0, 200, 150)
ctx.fill()
# Pad pattern
pattern.set_extend(cairo.EXTEND_PAD)
ctx.set_source(pattern)
ctx.rectangle(0, 150, 200, 150)
ctx.fill()
main_surface.write_to_png("surface_patterns.png")import cairo
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(surface)
# Create mesh pattern
mesh = cairo.MeshPattern()
# First patch - a quadrilateral with different colors at corners
mesh.begin_patch()
mesh.move_to(100, 100)
mesh.line_to(300, 100)
mesh.line_to(300, 200)
mesh.line_to(100, 200)
# Set corner colors
mesh.set_corner_color_rgb(0, 1, 0, 0) # Red
mesh.set_corner_color_rgb(1, 0, 1, 0) # Green
mesh.set_corner_color_rgb(2, 0, 0, 1) # Blue
mesh.set_corner_color_rgb(3, 1, 1, 0) # Yellow
mesh.end_patch()
# Second patch with curves
mesh.begin_patch()
mesh.move_to(100, 200)
mesh.curve_to(100, 250, 150, 250, 200, 200)
mesh.curve_to(250, 250, 300, 250, 300, 200)
mesh.line_to(300, 200)
mesh.line_to(100, 200)
mesh.set_corner_color_rgb(0, 1, 1, 0) # Yellow
mesh.set_corner_color_rgb(1, 1, 0, 1) # Magenta
mesh.set_corner_color_rgb(2, 0, 1, 1) # Cyan
mesh.set_corner_color_rgb(3, 1, 0.5, 0) # Orange
mesh.end_patch()
ctx.set_source(mesh)
ctx.paint()
surface.write_to_png("mesh_gradient.png")import cairo
import math
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(surface)
# Create a linear gradient
gradient = cairo.LinearGradient(0, 0, 100, 0)
gradient.add_color_stop_rgb(0, 1, 0, 0)
gradient.add_color_stop_rgb(1, 0, 0, 1)
# Apply transformation to pattern
matrix = cairo.Matrix()
matrix.rotate(math.pi / 4) # 45 degree rotation
matrix.scale(2, 1) # Scale horizontally
gradient.set_matrix(matrix)
ctx.set_source(gradient)
ctx.rectangle(50, 50, 300, 200)
ctx.fill()
surface.write_to_png("transformed_pattern.png")import cairo
# Create small pattern surface
pattern_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 20, 20)
pattern_ctx = cairo.Context(pattern_surface)
pattern_ctx.set_source_rgb(0.8, 0.2, 0.2)
pattern_ctx.arc(10, 10, 8, 0, 2 * 3.14159)
pattern_ctx.fill()
# Main surface
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 400, 300)
ctx = cairo.Context(surface)
pattern = cairo.SurfacePattern(pattern_surface)
# Test different filter modes
ctx.save()
pattern.set_filter(cairo.FILTER_NEAREST)
pattern.set_extend(cairo.EXTEND_REPEAT)
ctx.set_source(pattern)
ctx.rectangle(0, 0, 200, 150)
ctx.fill()
ctx.restore()
ctx.save()
pattern.set_filter(cairo.FILTER_BILINEAR)
ctx.set_source(pattern)
ctx.rectangle(200, 0, 200, 150)
ctx.fill()
ctx.restore()
# Scale pattern up to see filtering effects
matrix = cairo.Matrix()
matrix.scale(0.5, 0.5) # Make pattern twice as large
pattern.set_matrix(matrix)
ctx.save()
pattern.set_filter(cairo.FILTER_NEAREST)
ctx.set_source(pattern)
ctx.rectangle(0, 150, 200, 150)
ctx.fill()
ctx.restore()
ctx.save()
pattern.set_filter(cairo.FILTER_BILINEAR)
ctx.set_source(pattern)
ctx.rectangle(200, 150, 200, 150)
ctx.fill()
ctx.restore()
surface.write_to_png("pattern_filtering.png")Install with Tessl CLI
npx tessl i tessl/pypi-pycairo