Graphics, Patterns & Shadings
PDF Oxide provides low-level graphics primitives through ContentStreamBuilder for drawing paths and shapes, TilingPatternBuilder for repeating patterns, gradient builders for linear and radial gradients, and ExtGStateBuilder for transparency and blend modes.
Binding coverage. The
FluentPageBuilderprimitivesrect(x, y, w, h),filled_rect(x, y, w, h, color), andline(x1, y1, x2, y2)ship in Rust, Python, Node, C#, Go, and WASM as of v0.3.38 — see DocumentBuilder → Graphics Primitives. The fullContentStreamBuildersurface on this page (arbitrary paths, bezier curves, colour spaces,TilingPatternBuilder,LinearGradientBuilder/RadialGradientBuilder,ExtGStateBuilder) remains Rust-only. Other bindings should chain the simple primitives throughDocumentBuilder, generate PDFs throughPdf::from_html_css/Pdf::from_markdown/Pdf::from_images, or call the Rust CLI for custom drawing.
Quick Example
Rust
use pdf_oxide::writer::{ContentStreamBuilder, LineCap, LineJoin};
let mut builder = ContentStreamBuilder::new();
builder
.save_state()
.set_stroke_color(0.0, 0.0, 1.0) // Blue stroke
.set_fill_color(0.8, 0.8, 1.0) // Light blue fill
.set_line_width(2.0)
.rect(72.0, 600.0, 200.0, 100.0)
.fill_and_stroke()
.restore_state();
ContentStreamBuilder – Drawing Primitives
ContentStreamBuilder generates PDF content stream operators for rendering graphics on a page.
Path Operations
use pdf_oxide::writer::ContentStreamBuilder;
let mut cs = ContentStreamBuilder::new();
// Move/Line/Curve
cs.move_to(72.0, 700.0)
.line_to(200.0, 700.0)
.line_to(200.0, 600.0)
.close_path()
.stroke();
// Rectangle
cs.rect(72.0, 500.0, 150.0, 80.0)
.fill();
// Bezier curve
cs.move_to(72.0, 400.0)
.curve_to(100.0, 450.0, 200.0, 350.0, 250.0, 400.0)
.stroke();
Color Operations
// RGB colors (0.0 to 1.0)
cs.set_fill_color(1.0, 0.0, 0.0); // Red fill
cs.set_stroke_color(0.0, 0.5, 0.0); // Green stroke
// Grayscale
cs.set_fill_color_gray(0.5); // 50% gray fill
cs.set_stroke_color_gray(0.0); // Black stroke
// CMYK
cs.set_fill_color_cmyk(0.0, 1.0, 1.0, 0.0); // Red in CMYK
cs.set_stroke_color_cmyk(1.0, 0.0, 0.0, 0.0); // Cyan stroke
Line Style
use pdf_oxide::writer::{ContentStreamBuilder, LineCap, LineJoin};
let mut cs = ContentStreamBuilder::new();
cs.set_line_width(2.0)
.set_line_cap(LineCap::Round)
.set_line_join(LineJoin::Round)
.set_miter_limit(10.0)
.set_dash_pattern(vec![5.0, 3.0], 0.0); // 5pt dash, 3pt gap
LineCap variants: Butt (default), Round, Square
LineJoin variants: Miter (default), Round, Bevel
Graphics State
// Save/restore state for isolated operations
cs.save_state()
.set_fill_color(1.0, 0.0, 0.0)
.rect(100.0, 100.0, 50.0, 50.0)
.fill()
.restore_state();
// State is restored to what it was before save_state()
Path Filling and Stroking
| Method | Description |
|---|---|
.stroke() |
Stroke the path outline |
.fill() |
Fill the path interior (non-zero winding) |
.fill_even_odd() |
Fill using even-odd rule |
.fill_and_stroke() |
Fill and stroke |
.fill_and_stroke_even_odd() |
Fill (even-odd) and stroke |
.close_and_stroke() |
Close path then stroke |
.close_fill_and_stroke() |
Close, fill, and stroke |
.end_path() |
End path without painting |
Clipping
// Clip to rectangle, then draw inside
cs.save_state()
.rect(100.0, 100.0, 200.0, 200.0)
.clip()
.end_path()
// Everything drawn here is clipped to the rectangle
.set_fill_color(1.0, 0.0, 0.0)
.rect(50.0, 50.0, 300.0, 300.0) // Only visible within clip
.fill()
.restore_state();
Transformations
// Apply transformation matrix [a b c d e f]
cs.save_state()
.transform(1.0, 0.0, 0.0, 1.0, 100.0, 200.0) // Translate
.rect(0.0, 0.0, 50.0, 50.0)
.fill()
.restore_state();
ContentStreamOp Enum
For maximum control, build operations directly:
use pdf_oxide::writer::ContentStreamOp;
let ops = vec![
ContentStreamOp::SaveState,
ContentStreamOp::SetLineWidth(2.0),
ContentStreamOp::SetStrokeColorRGB(0.0, 0.0, 1.0),
ContentStreamOp::MoveTo(72.0, 500.0),
ContentStreamOp::LineTo(300.0, 500.0),
ContentStreamOp::Stroke,
ContentStreamOp::RestoreState,
];
TilingPatternBuilder – Repeating Patterns
Tiling patterns repeat a small cell across an area.
use pdf_oxide::writer::{TilingPatternBuilder, PatternPaintType, PatternTilingType};
// Striped pattern
let (pattern_dict, content_bytes) = TilingPatternBuilder::new()
.bbox(0.0, 0.0, 10.0, 10.0)
.x_step(10.0)
.y_step(10.0)
.colored()
.tiling_type(PatternTilingType::ConstantSpacing)
.content_bytes(b"0.8 0 0 rg 0 0 5 10 re f".to_vec())
.build();
Configuration Methods
| Method | Description |
|---|---|
.bbox(x, y, w, h) |
Set bounding box of pattern cell |
.x_step(step) |
Horizontal spacing between cells |
.y_step(step) |
Vertical spacing between cells |
.step(x, y) |
Set both steps at once |
.colored() |
Colors defined in pattern content |
.uncolored() |
Color specified when pattern is used |
.tiling_type(type) |
Set tiling algorithm |
.matrix(a, b, c, d, e, f) |
Apply transformation to pattern |
.content_bytes(bytes) |
Set raw content stream bytes |
.build() |
Returns (Object, Vec<u8>) |
PatternPresets
PDF Oxide includes preset patterns for common use cases:
use pdf_oxide::writer::PatternPresets;
// Access presets for common patterns like hatching, dots, etc.
LinearGradientBuilder – Linear Gradients
Create axial (linear) gradient shadings.
use pdf_oxide::writer::{LinearGradientBuilder, GradientStop};
use pdf_oxide::layout::Color;
let (shading_dict, function_dict) = LinearGradientBuilder::new()
.from(0.0, 0.0)
.to(468.0, 0.0)
.add_stop(0.0, Color { r: 1.0, g: 0.0, b: 0.0 }) // Red
.add_stop(0.5, Color { r: 1.0, g: 1.0, b: 0.0 }) // Yellow
.add_stop(1.0, Color { r: 0.0, g: 0.0, b: 1.0 }) // Blue
.extend(true)
.build();
Two-Color Shortcut
use pdf_oxide::writer::LinearGradientBuilder;
use pdf_oxide::layout::Color;
let gradient = LinearGradientBuilder::two_color(
Color { r: 0.0, g: 0.0, b: 0.5 }, // Dark blue
Color { r: 0.5, g: 0.8, b: 1.0 }, // Light blue
);
Configuration Methods
| Method | Description |
|---|---|
.from(x, y) |
Start point of gradient |
.to(x, y) |
End point of gradient |
.add_stop(pos, color) |
Add color stop (position 0.0-1.0) |
.extend_start(bool) |
Extend gradient before start point |
.extend_end(bool) |
Extend gradient after end point |
.extend(bool) |
Set both extend flags |
RadialGradientBuilder – Radial Gradients
Create circular gradient shadings.
use pdf_oxide::writer::RadialGradientBuilder;
use pdf_oxide::layout::Color;
let (shading_dict, function_dict) = RadialGradientBuilder::new()
.center(200.0, 400.0)
.radius(0.0, 150.0) // Inner radius 0, outer radius 150
.add_stop(0.0, Color { r: 1.0, g: 1.0, b: 1.0 }) // White center
.add_stop(1.0, Color { r: 0.0, g: 0.0, b: 0.5 }) // Dark blue edge
.build();
ExtGStateBuilder – Transparency & Blend Modes
Control transparency, blend modes, and other graphics state parameters.
use pdf_oxide::writer::{ExtGStateBuilder, BlendMode};
let gs_dict = ExtGStateBuilder::new()
.fill_alpha(0.5) // 50% transparent fill
.stroke_alpha(0.8) // 80% opaque stroke
.blend_mode(BlendMode::Multiply)
.build();
Configuration Methods
| Method | Description |
|---|---|
.fill_alpha(a) |
Fill opacity (0.0 transparent, 1.0 opaque) |
.stroke_alpha(a) |
Stroke opacity |
.blend_mode(mode) |
Set blend mode |
.line_width(w) |
Override line width |
.line_cap(cap) |
Override line cap style |
.line_join(join) |
Override line join style |
.miter_limit(limit) |
Override miter limit |
.flatness(f) |
Flatness tolerance |
.overprint_stroke(b) |
Overprint mode for stroke |
.overprint_fill(b) |
Overprint mode for fill |
BlendMode Variants
Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn, HardLight, SoftLight
GradientPresets
Convenience methods for common gradient patterns:
use pdf_oxide::writer::GradientPresets;
// Access preset gradient configurations
Advanced Example
Drawing a Chart Background with Gradient
use pdf_oxide::writer::{
ContentStreamBuilder, LinearGradientBuilder, ExtGStateBuilder, BlendMode,
};
use pdf_oxide::layout::Color;
let mut cs = ContentStreamBuilder::new();
// Draw chart area with rounded-corner appearance
cs.save_state()
.set_fill_color(0.95, 0.95, 0.97)
.rect(72.0, 200.0, 468.0, 400.0)
.fill()
.restore_state();
// Draw grid lines
cs.save_state()
.set_stroke_color(0.85, 0.85, 0.85)
.set_line_width(0.5);
for i in 0..5 {
let y = 200.0 + (i as f32 * 100.0);
cs.move_to(72.0, y).line_to(540.0, y).stroke();
}
cs.restore_state();
// Draw data bars
let values = [280.0, 350.0, 180.0, 420.0, 310.0];
let colors = [
(0.2, 0.5, 0.8),
(0.3, 0.7, 0.4),
(0.8, 0.3, 0.3),
(0.6, 0.4, 0.8),
(0.9, 0.6, 0.2),
];
for (i, (&val, &(r, g, b))) in values.iter().zip(colors.iter()).enumerate() {
let x = 100.0 + (i as f32 * 85.0);
cs.save_state()
.set_fill_color(r, g, b)
.rect(x, 200.0, 50.0, val)
.fill()
.restore_state();
}
Related Pages
- DocumentBuilder Low-Level API – High-level page construction
- Table Rendering – Table creation API
- Annotation Creation – Adding annotations to pages