Skip to content

図形・パターン・シェーディング

PDF Oxide は、パスや図形を描画する ContentStreamBuilder、繰り返しパターンを生成する TilingPatternBuilder、線形・放射状グラデーション用のグラデーションビルダー、そして透明度とブレンドモードを扱う ExtGStateBuilder を通じて、低レベルのグラフィックスプリミティブを提供します。

バインディング対応状況。 FluentPageBuilder のプリミティブ rect(x, y, w, h)filled_rect(x, y, w, h, color)line(x1, y1, x2, y2) は、v0.3.38 時点で Rust、Python、Node、C#、Go、WASM に搭載されています — DocumentBuilder → グラフィックスプリミティブ を参照してください。このページで扱う ContentStreamBuilder の全機能(任意のパス、ベジェ曲線、カラースペース、TilingPatternBuilderLinearGradientBuilder / RadialGradientBuilderExtGStateBuilder)は引き続き Rust 専用です。その他のバインディングでは、DocumentBuilder を介してシンプルなプリミティブを連結するか、Pdf::from_html_css / Pdf::from_markdown / Pdf::from_images で PDF を生成するか、カスタム描画には Rust CLI を呼び出してください。

クイック例

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 – 描画プリミティブ

ContentStreamBuilder は、ページ上に図形を描画するための PDF コンテンツストリーム演算子を生成します。

パス操作

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();

色の操作

// 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

線のスタイル

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 のバリアント: Butt(デフォルト)、RoundSquare

LineJoin のバリアント: Miter(デフォルト)、RoundBevel

グラフィックスステート

// 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()

パスの塗りつぶしとストローク

メソッド 説明
.stroke() パスの輪郭をストロークする
.fill() パス内部を塗りつぶす(非ゼロワインディング)
.fill_even_odd() 偶奇規則で塗りつぶす
.fill_and_stroke() 塗りつぶしとストローク
.fill_and_stroke_even_odd() 塗りつぶし(偶奇)とストローク
.close_and_stroke() パスを閉じてからストローク
.close_fill_and_stroke() 閉じて、塗りつぶし、ストローク
.end_path() 描画せずにパスを終了する

クリッピング

// 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();

変換

// 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 列挙型

最大限の制御が必要な場合は、操作を直接組み立てます:

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 – 繰り返しパターン

タイリングパターンは、小さなセルを領域全体に繰り返します。

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();

設定メソッド

メソッド 説明
.bbox(x, y, w, h) パターンセルのバウンディングボックスを設定
.x_step(step) セル間の水平方向の間隔
.y_step(step) セル間の垂直方向の間隔
.step(x, y) 両方の間隔を一度に設定
.colored() パターンコンテンツ内で色を定義
.uncolored() パターン使用時に色を指定
.tiling_type(type) タイリングアルゴリズムを設定
.matrix(a, b, c, d, e, f) パターンに変換を適用
.content_bytes(bytes) 生のコンテンツストリームバイトを設定
.build() (Object, Vec<u8>) を返す

PatternPresets

PDF Oxide には、一般的なユースケース向けのプリセットパターンが含まれています:

use pdf_oxide::writer::PatternPresets;

// Access presets for common patterns like hatching, dots, etc.

LinearGradientBuilder – 線形グラデーション

軸方向(線形)のグラデーションシェーディングを作成します。

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();

2色ショートカット

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
);

設定メソッド

メソッド 説明
.from(x, y) グラデーションの開始点
.to(x, y) グラデーションの終了点
.add_stop(pos, color) カラーストップを追加(位置 0.0〜1.0)
.extend_start(bool) 開始点より前にグラデーションを延長
.extend_end(bool) 終了点より後にグラデーションを延長
.extend(bool) 両方の延長フラグを設定

RadialGradientBuilder – 放射状グラデーション

円形のグラデーションシェーディングを作成します。

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 – 透明度とブレンドモード

透明度、ブレンドモード、その他のグラフィックスステートパラメータを制御します。

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();

設定メソッド

メソッド 説明
.fill_alpha(a) 塗りつぶしの不透明度(0.0 透明、1.0 不透明)
.stroke_alpha(a) ストロークの不透明度
.blend_mode(mode) ブレンドモードを設定
.line_width(w) 線幅を上書き
.line_cap(cap) 線端のスタイルを上書き
.line_join(join) 線の結合スタイルを上書き
.miter_limit(limit) マイター制限を上書き
.flatness(f) 平坦化の許容値
.overprint_stroke(b) ストロークのオーバープリントモード
.overprint_fill(b) 塗りつぶしのオーバープリントモード

BlendMode のバリアント

NormalMultiplyScreenOverlayDarkenLightenColorDodgeColorBurnHardLightSoftLight

GradientPresets

一般的なグラデーションパターン向けの便利なメソッド:

use pdf_oxide::writer::GradientPresets;

// Access preset gradient configurations

応用例

グラデーションでチャートの背景を描画する

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();
}

関連ページ