メタデータ & XMP
PDF Oxide は、複数のソースからドキュメントレベルのメタデータを読み取ります。PDF ヘッダー(バージョン)、トレーラーおよびカタログ辞書、XMP メタデータストリーム(ISO 16684)、そしてページラベル定義です。XmpExtractor は Dublin Core、XMP Core、PDF、XMP Rights の各名前空間とカスタムプロパティを解析します。
基本的なドキュメントプロパティには version() と catalog()、リッチメタデータには XmpExtractor::extract()、ページ番号スキームには PageLabelExtractor を使用してください。
クイック例
Python
from pdf_oxide import PdfDocument
doc = PdfDocument("report.pdf")
major, minor = doc.version()
print(f"PDF {major}.{minor}, {doc.page_count()} pages")
Node.js
const { PdfDocument } = require("pdf-oxide");
const doc = new PdfDocument("report.pdf");
const { major, minor } = doc.getVersion();
console.log(`PDF ${major}.${minor}, ${doc.pageCount()} pages`);
doc.close();
Go
import pdfoxide "github.com/yfedoseev/pdf_oxide/go"
doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
major, minor, _ := doc.Version()
pages, _ := doc.PageCount()
fmt.Printf("PDF %d.%d, %d pages\n", major, minor, pages)
C#
using PdfOxide.Core;
using var doc = PdfDocument.Open("report.pdf");
var (major, minor) = doc.Version;
Console.WriteLine($"PDF {major}.{minor}, {doc.PageCount} pages");
WASM
const doc = new WasmPdfDocument(bytes);
const version = doc.version();
console.log(`PDF ${version}, ${doc.pageCount()} pages`);
Rust
use pdf_oxide::PdfDocument;
let mut doc = PdfDocument::open("report.pdf")?;
let (major, minor) = doc.version();
println!("PDF {}.{}", major, minor);
println!("Pages: {}", doc.page_count()?);
PHP
use PdfOxide\PdfDocument;
$doc = PdfDocument::open("report.pdf");
$v = $doc->version(); // ['major' => int, 'minor' => int]
echo "PDF {$v['major']}.{$v['minor']}, {$doc->pageCount()} pages\n";
$doc->close();
Ruby
require "pdf_oxide"
PdfOxide::PdfDocument.open("report.pdf") do |doc|
puts "PDF #{doc.pdf_version}, #{doc.page_count} pages"
end
C++
#include <pdf_oxide/pdf_oxide.hpp>
auto doc = pdf_oxide::Document::open("report.pdf");
auto v = doc.version();
std::cout << "PDF " << static_cast<int>(v.major) << "."
<< static_cast<int>(v.minor) << ", " << doc.page_count() << " pages\n";
Swift
import PdfOxide
let doc = try Document.open("report.pdf")
let v = try doc.version()
print("PDF \(v.major).\(v.minor), \(try doc.pageCount()) pages")
Dart
import 'package:pdf_oxide/pdf_oxide.dart';
final doc = PdfDocument.open('report.pdf');
final v = doc.version;
print('PDF ${v.major}.${v.minor}, ${doc.pageCount} pages');
doc.close();
R
library(pdfoxide)
doc <- pdf_open("report.pdf")
v <- pdf_version(doc)
cat(sprintf("PDF %d.%d, %d pages\n", v$major, v$minor, pdf_page_count(doc)))
Julia
using PdfOxide
doc = open_document("report.pdf")
v = version(doc)
println("PDF $(v.major).$(v.minor), $(page_count(doc)) pages")
Zig
const pdf_oxide = @import("pdf_oxide");
var doc = try pdf_oxide.Document.open("report.pdf");
const v = doc.version();
std.debug.print("PDF {d}.{d}, {d} pages\n", .{ v.major, v.minor, try doc.pageCount() });
Objective-C
#import "POXPdfOxide.h"
NSError *err = nil;
POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
POXVersion v = [doc version];
printf("PDF %d.%d, %ld pages\n", v.major, v.minor, (long)[doc pageCountError:&err]);
Elixir
{:ok, doc} = PdfOxide.open("report.pdf")
%{major: maj, minor: min} = PdfOxide.version(doc)
{:ok, pages} = PdfOxide.page_count(doc)
IO.puts("PDF #{maj}.#{min}, #{pages} pages")
API リファレンス
version() -> (u8, u8)
ファイルヘッダーから PDF バージョンを取得します。
戻り値: (major, minor) のタプル。例: PDF 1.7 は (1, 7)、PDF 2.0 は (2, 0)。
catalog() -> Result<Object>
ドキュメントカタログ辞書を取得します。カタログは PDF オブジェクト階層のルートであり、ページツリー、アウトライン、名前、その他のドキュメントレベル構造への参照を含みます。
Rust
let mut doc = PdfDocument::open("report.pdf")?;
let catalog = doc.catalog()?;
if let Some(dict) = catalog.as_dict() {
for (key, _) in dict {
println!("Catalog key: {}", key);
}
}
trailer() -> &Object
ドキュメントトレーラー辞書を取得します。トレーラーには、相互参照テーブルの場所、ドキュメント ID、暗号化辞書の参照、および Info 辞書の参照が含まれます。
Rust
let doc = PdfDocument::open("report.pdf")?;
let trailer = doc.trailer();
println!("Trailer: {:?}", trailer);
XmpExtractor::extract(doc) -> Result<Option<XmpMetadata>>
ドキュメントのメタデータストリームから XMP(Extensible Metadata Platform)メタデータを抽出します。XMP は標準的な XML 名前空間を使用し、従来の Info 辞書よりも豊富なメタデータを提供します。
| パラメータ | 型 | 説明 |
|---|---|---|
doc |
&mut PdfDocument |
PDF ドキュメント |
戻り値: XMP データが存在する場合は Some(XmpMetadata)、それ以外は None。
XmpMetadata フィールド
Dublin Core 名前空間 (dc:)
| フィールド | 型 | 説明 |
|---|---|---|
dc_title |
Option<String> |
ドキュメントタイトル |
dc_creator |
Vec<String> |
著者・作成者リスト |
dc_description |
Option<String> |
ドキュメントの説明 |
dc_subject |
Vec<String> |
件名キーワード |
dc_language |
Option<String> |
ドキュメントの言語(例: "en-US") |
dc_rights |
Option<String> |
著作権表示 |
dc_format |
Option<String> |
MIME フォーマット(例: "application/pdf") |
XMP Core 名前空間 (xmp:)
| フィールド | 型 | 説明 |
|---|---|---|
xmp_creator_tool |
Option<String> |
ドキュメント作成に使用したツール |
xmp_create_date |
Option<String> |
作成日時(ISO 8601) |
xmp_modify_date |
Option<String> |
最終更新日時 |
xmp_metadata_date |
Option<String> |
メタデータの更新日時 |
PDF 名前空間 (pdf:)
| フィールド | 型 | 説明 |
|---|---|---|
pdf_producer |
Option<String> |
PDF 生成アプリケーション |
pdf_keywords |
Option<String> |
キーワード文字列 |
pdf_version |
Option<String> |
XMP の PDF バージョン(ヘッダーと異なる場合あり) |
pdf_trapped |
Option<String> |
トラッピング状態 |
XMP Rights 名前空間 (xmpRights:)
| フィールド | 型 | 説明 |
|---|---|---|
xmp_rights_usage_terms |
Option<String> |
利用規約 |
xmp_rights_marked |
Option<bool> |
権利マークの有無 |
xmp_rights_web_statement |
Option<String> |
Web 上の権利表示 URL |
その他
| フィールド | 型 | 説明 |
|---|---|---|
custom |
HashMap<String, String> |
カスタムプロパティ(名前空間:プロパティ → 値) |
raw_xml |
Option<String> |
元の XMP XML パケット |
Rust
use pdf_oxide::extractors::xmp::XmpExtractor;
let mut doc = PdfDocument::open("report.pdf")?;
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
if let Some(title) = &xmp.dc_title {
println!("Title: {}", title);
}
for creator in &xmp.dc_creator {
println!("Author: {}", creator);
}
if let Some(tool) = &xmp.xmp_creator_tool {
println!("Created with: {}", tool);
}
if let Some(date) = &xmp.xmp_create_date {
println!("Created: {}", date);
}
if let Some(producer) = &xmp.pdf_producer {
println!("Producer: {}", producer);
}
}
WASM
const doc = new WasmPdfDocument(bytes);
const xmp = doc.xmpMetadata();
if (xmp) {
console.log(`Title: ${xmp.dc_title}`);
console.log(`Authors: ${xmp.dc_creator}`);
console.log(`Created with: ${xmp.xmp_creator_tool}`);
console.log(`Created: ${xmp.xmp_create_date}`);
console.log(`Producer: ${xmp.pdf_producer}`);
}
doc.free();
Python
doc = PdfDocument("report.pdf")
xmp = doc.xmp_metadata()
if xmp:
print(f"Title: {xmp.get('dc_title')}")
print(f"Authors: {xmp.get('dc_creator')}")
print(f"Created with: {xmp.get('xmp_creator_tool')}")
print(f"Created: {xmp.get('xmp_create_date')}")
print(f"Producer: {xmp.get('pdf_producer')}")
<!-- Node.js: no equivalent on PdfDocumentImpl — xmp metadata not exposed in js/src/index.ts -->
Go
doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
xmp, _ := doc.XmpMetadata() // returns JSON string
fmt.Println(xmp)
C#
using var doc = PdfDocument.Open("report.pdf");
var xmp = doc.GetXmpMetadata(); // returns JSON string
Console.WriteLine(xmp);
C++
auto doc = pdf_oxide::Document::open("report.pdf");
std::string xmp = doc.get_xmp_metadata(); // raw XMP XML packet
std::cout << xmp << "\n";
Swift
let doc = try Document.open("report.pdf")
let xmp = try doc.xmpMetadata() // raw XMP XML packet
print(xmp)
Dart
final doc = PdfDocument.open('report.pdf');
final xmp = doc.getXmpMetadata(); // raw XMP XML packet
print(xmp);
doc.close();
R
doc <- pdf_open("report.pdf")
xmp <- pdf_get_xmp_metadata(doc) # XMP metadata as JSON
cat(xmp, "\n")
Julia
doc = open_document("report.pdf")
xmp = get_xmp_metadata(doc) # XMP metadata string
println(xmp)
Zig
var doc = try pdf_oxide.Document.open("report.pdf");
const xmp = try doc.xmpMetadata(a); // caller owns the slice
defer a.free(xmp);
std.debug.print("{s}\n", .{xmp});
Objective-C
POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
NSString *xmp = [doc xmpMetadataWithError:&err];
printf("%s\n", xmp.UTF8String);
Elixir
{:ok, doc} = PdfOxide.open("report.pdf")
xmp = PdfOxide.xmp_metadata(doc) # XMP metadata as an XML/JSON string
IO.puts(xmp)
Pdf 便利メソッド
高レベルの Pdf API は、よく使うメタデータクエリのショートカットメソッドを提供します。
xmp_metadata() -> Result<Option<XmpMetadata>>
XMP メタデータオブジェクト全体を取得します。
xmp_title() -> Result<Option<String>>
XMP からドキュメントタイトルのみを取得します。
xmp_creators() -> Result<Vec<String>>
XMP から作成者・著者のリストを取得します。
Rust
use pdf_oxide::api::Pdf;
let mut pdf = Pdf::open("report.pdf")?;
if let Some(title) = pdf.xmp_title()? {
println!("Title: {}", title);
}
let creators = pdf.xmp_creators()?;
for creator in &creators {
println!("Author: {}", creator);
}
PageLabelExtractor::extract(doc) -> Result<Vec<PageLabelRange>>
ドキュメントからページラベル定義を抽出します。ページラベルは、ページ番号の表示方法を定義します(例: 前付けにローマ数字、本文にアラビア数字)。
| パラメータ | 型 | 説明 |
|---|---|---|
doc |
&mut PdfDocument |
PDF ドキュメント |
戻り値: PageLabelRange 定義のベクター。
PageLabelRange フィールド
| フィールド | 型 | 説明 |
|---|---|---|
start_page |
usize |
この範囲が適用される最初のページインデックス |
style |
PageLabelStyle |
番号付けスタイル |
prefix |
Option<String> |
ラベルのプレフィックス文字列 |
start_number |
u32 |
この範囲の開始番号 |
PageLabelStyle バリアント
| バリアント | 説明 | 例 |
|---|---|---|
DecimalArabic |
アラビア数字 | 1, 2, 3 |
UppercaseRoman |
大文字ローマ数字 | I, II, III |
LowercaseRoman |
小文字ローマ数字 | i, ii, iii |
UppercaseLetters |
大文字アルファベット | A, B, C |
LowercaseLetters |
小文字アルファベット | a, b, c |
None |
番号なし(プレフィックスのみ) | – |
Pdf ページラベル便利メソッド
page_labels() -> Result<Vec<PageLabelRange>>
すべてのページラベル範囲定義を取得します。
page_label(page) -> Result<String>
特定のページインデックスの表示ラベルを取得します。
Rust
use pdf_oxide::api::Pdf;
let mut pdf = Pdf::open("book.pdf")?;
// Get all label ranges
let ranges = pdf.page_labels()?;
for range in &ranges {
println!(
"Pages from {}: {:?} style, prefix={:?}, start={}",
range.start_page, range.style, range.prefix, range.start_number
);
}
// Get label for a specific page
let label = pdf.page_label(0)?;
println!("Page 0 label: {}", label); // e.g., "i" or "Cover"
WASM
const doc = new WasmPdfDocument(bytes);
const labels = doc.pageLabels();
for (const range of labels) {
console.log(`Pages from ${range.start_page}: style=${range.style}, prefix=${range.prefix}`);
}
doc.free();
Python
doc = PdfDocument("book.pdf")
labels = doc.page_labels()
for range in labels:
print(f"Pages from {range['start_page']}: style={range['style']}, prefix={range['prefix']}")
<!-- Node.js: no equivalent on PdfDocumentImpl — pageLabels not exposed on class, only via properties mixin -->
Go
doc, _ := pdfoxide.Open("book.pdf")
defer doc.Close()
labels, _ := doc.PageLabels() // returns JSON string
fmt.Println(labels)
C#
using var doc = PdfDocument.Open("book.pdf");
var labels = doc.GetPageLabels(); // returns JSON string
Console.WriteLine(labels);
C++
auto doc = pdf_oxide::Document::open("book.pdf");
std::string labels = doc.get_page_labels(); // JSON string
std::cout << labels << "\n";
Swift
let doc = try Document.open("book.pdf")
let labels = try doc.pageLabels() // JSON string
print(labels)
Dart
final doc = PdfDocument.open('book.pdf');
final labels = doc.getPageLabels(); // JSON string
print(labels);
doc.close();
R
doc <- pdf_open("book.pdf")
labels <- pdf_get_page_labels(doc) # JSON string
cat(labels, "\n")
Julia
doc = open_document("book.pdf")
labels = get_page_labels(doc) # JSON string
println(labels)
Zig
var doc = try pdf_oxide.Document.open("book.pdf");
const labels = try doc.pageLabels(a); // JSON string; caller owns the slice
defer a.free(labels);
std.debug.print("{s}\n", .{labels});
Objective-C
POXDocument *doc = [POXDocument openPath:@"book.pdf" error:&err];
NSString *labels = [doc pageLabelsWithError:&err];
printf("%s\n", labels.UTF8String);
Elixir
{:ok, doc} = PdfOxide.open("book.pdf")
labels = PdfOxide.page_labels(doc) # JSON string
IO.puts(labels)
get_producer — ドキュメントのプロデューサー
プロデューサーは PDF を生成したツールです(/Info.Producer)。エディターサーフェスでは読み書き可能なアクセサーとして公開されています。get_producer / Producer で読み取り、対応するセッター(保存時に /Info.Producer に永続化)で書き込みます。XMP 上の同等フィールドは上記 XmpMetadata の pdf_producer です。
このアクセサーは C ABI 関数 document_editor_get_producer によって実装されています。
char *document_editor_get_producer(DocumentEditor *handle, int32_t *error_code);
呼び出し元が所有する C 文字列(free_string で解放)を返します。プロデューサーが設定されていない場合は null。
Rust
use pdf_oxide::editor::DocumentEditor;
let mut editor = DocumentEditor::open("report.pdf")?;
if let Some(producer) = editor.producer()? {
println!("Producer: {}", producer);
}
Go
import pdfoxide "github.com/yfedoseev/pdf_oxide/go"
editor, _ := pdfoxide.OpenEditor("report.pdf")
defer editor.Close()
producer, _ := editor.Producer()
fmt.Printf("Producer: %s\n", producer)
C#
using PdfOxide.Core;
using var editor = DocumentEditor.Open("report.pdf");
Console.WriteLine($"Producer: {editor.Producer}");
Swift
import PdfOxide
let editor = try DocumentEditor.open("report.pdf")
let producer = try editor.getProducer()
print("Producer: \(producer)")
PHP
use PdfOxide\DocumentEditor;
$editor = DocumentEditor::open("report.pdf");
echo "Producer: " . $editor->getProducer() . "\n";
C++
auto editor = pdf_oxide::DocumentEditor::open("report.pdf");
std::cout << "Producer: " << editor.get_producer() << "\n";
Dart
final editor = DocumentEditor.open('report.pdf');
print('Producer: ${editor.getProducer()}');
R
editor <- pdf_editor_open("report.pdf")
cat("Producer:", pdf_editor_get_producer(editor), "\n")
Julia
editor = open_editor("report.pdf")
println("Producer: ", get_producer(editor))
Zig
var editor = try pdf_oxide.Document.openEditor("report.pdf");
const producer = try editor.getProducer(a); // caller owns the slice
defer a.free(producer);
std.debug.print("Producer: {s}\n", .{producer});
Objective-C
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"report.pdf" error:&err];
NSString *producer = [editor producerError:&err];
printf("Producer: %s\n", producer.UTF8String);
Elixir
{:ok, editor} = PdfOxide.open_editor("report.pdf")
producer = PdfOxide.get_producer(editor)
IO.puts("Producer: #{producer}")
バインディングの対応状況。
get_producerはエディター(DocumentEditor)上に存在し、読み取り専用のPdfDocumentには属しません。Rust (editor.producer())、Go (editor.Producer())、C# (editor.Producerプロパティ)、Swift (editor.getProducer())、C ABI (document_editor_get_producer) で公開されています。セッター(set_producer/SetProducer/Producer = ...)は保存時に変更を永続化します。このアクセサーは WASM ターゲットではコンパイルされません。
embedded_fonts — ページで使用されているフォント
embedded_fonts は、ページのコンテンツストリームで参照されているフォントを列挙し、ページのテキストスパンからフォント名、埋め込みステータス、サブセットステータスを導出します。(サブセットフォントは標準の 6 文字プレフィックス++ の命名規則で検出されます。例: ABCDEF+Helvetica。)C ABI 関数 pdf_document_get_embedded_fonts と pdf_oxide_font_* アクセサーファミリーによって実装されています。
Go
import pdfoxide "github.com/yfedoseev/pdf_oxide/go"
doc, _ := pdfoxide.Open("report.pdf")
defer doc.Close()
fonts, _ := doc.Fonts(0) // []pdfoxide.Font
for _, f := range fonts {
fmt.Printf("%s (%s) embedded=%v subset=%v\n",
f.Name, f.Encoding, f.IsEmbedded, f.IsSubset)
}
Swift
import PdfOxide
let doc = try Document.open("report.pdf")
let fonts = try doc.embeddedFonts(0) // [Font]
for f in fonts {
print("\(f.name) (\(f.encoding)) embedded=\(f.embedded) subset=\(f.subset)")
}
C ABI
#include "pdf_oxide.h"
int32_t err = 0;
FfiFontList *fonts = pdf_document_get_embedded_fonts(doc, /*page=*/0, &err);
int32_t n = pdf_oxide_font_count(fonts);
for (int32_t i = 0; i < n; i++) {
char *name = pdf_oxide_font_get_name(fonts, i, &err);
int32_t embedded = pdf_oxide_font_is_embedded(fonts, i, &err);
int32_t subset = pdf_oxide_font_is_subset(fonts, i, &err);
printf("%s embedded=%d subset=%d\n", name, embedded, subset);
free_string(name);
}
pdf_oxide_font_list_free(fonts);
C++
auto doc = pdf_oxide::Document::open("report.pdf");
for (const auto& f : doc.embedded_fonts(0)) { // std::vector<Font>
std::cout << f.name << " (" << f.encoding << ") embedded="
<< f.embedded << " subset=" << f.subset << "\n";
}
Dart
final doc = PdfDocument.open('report.pdf');
for (final f in doc.embeddedFonts(0)) { // List<Font>
print('${f.name} (${f.encoding}) embedded=${f.embedded} subset=${f.subset}');
}
doc.close();
R
doc <- pdf_open("report.pdf")
for (f in pdf_embedded_fonts(doc, 0)) { # list of Font records
cat(sprintf("%s (%s) embedded=%s subset=%s\n",
f$name, f$encoding, f$embedded, f$subset))
}
Julia
doc = open_document("report.pdf")
for f in embedded_fonts(doc, 0) # Vector{Font}
println("$(f.name) ($(f.encoding)) embedded=$(f.embedded) subset=$(f.subset)")
end
Zig
var doc = try pdf_oxide.Document.open("report.pdf");
const fonts = try doc.embeddedFonts(a, 0); // []Font
defer pdf_oxide.Document.freeFonts(a, fonts);
for (fonts) |f| {
std.debug.print("{s} ({s}) embedded={} subset={}\n",
.{ f.name, f.encoding, f.embedded, f.subset });
}
Objective-C
POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
for (POXFont *f in [doc embeddedFonts:0 error:&err]) {
printf("%s (%s) embedded=%d subset=%d\n",
f.name.UTF8String, f.encoding.UTF8String, f.embedded, f.subset);
}
Elixir
{:ok, doc} = PdfOxide.open("report.pdf")
for f <- PdfOxide.embedded_fonts(doc, 0) do # list of %Font{}
IO.puts("#{f.name} (#{f.encoding}) embedded=#{f.embedded} subset=#{f.subset}")
end
フォントアクセサーフィールド
| フィールド (Go / Swift) | 型 | 説明 |
|---|---|---|
Name / name |
string |
フォントリソース名(例: "ABCDEF+Helvetica") |
Type / type |
string |
フォントサブタイプ |
Encoding / encoding |
string |
フォントエンコーディング |
IsEmbedded / embedded |
bool |
フォントプログラムが埋め込まれているか |
IsSubset / subset |
bool |
フォントがサブセット化されているか |
Size (Go) |
float32 |
フォントサイズ(取得可能な場合) |
バインディングの対応状況。
embedded_fontsは Go (doc.Fonts(page))、Swift (doc.embeddedFonts(page))、および C ABI (pdf_document_get_embedded_fonts) で公開されています。WASM ターゲットではコンパイルされません。
fonts_to_json — ページのフォントをシリアライズ
fonts_to_json は、embedded_fonts から取得したフォントリスト全体を、1 回の FFI 呼び出しで JSON 配列にシリアライズします。Go バインディングは内部的にこれを使用して []Font を生成し、Swift では fontsToJson として直接公開されています。C ABI シグネチャ:
char *pdf_oxide_fonts_to_json(const FfiFontList *fonts, int32_t *error_code);
返される UTF-8 文字列は呼び出し元が所有します(free_string で解放)。スキーマ:
[{"name": "...", "type": "...", "encoding": "...",
"isEmbedded": true, "isSubset": false, "size": 0}]
Swift
import PdfOxide
let doc = try Document.open("report.pdf")
let json = try doc.fontsToJson(0) // String of JSON
print(json)
C ABI
#include "pdf_oxide.h"
int32_t err = 0;
FfiFontList *fonts = pdf_document_get_embedded_fonts(doc, /*page=*/0, &err);
char *json = pdf_oxide_fonts_to_json(fonts, &err);
printf("%s\n", json);
free_string(json);
pdf_oxide_font_list_free(fonts);
C++
auto doc = pdf_oxide::Document::open("report.pdf");
std::string json = doc.fonts_to_json(0); // JSON array string
std::cout << json << "\n";
Dart
final doc = PdfDocument.open('report.pdf');
final json = doc.embeddedFontsJson(0); // JSON array string
print(json);
doc.close();
R
doc <- pdf_open("report.pdf")
json <- pdf_fonts_to_json(doc, 0) # JSON array string
cat(json, "\n")
Julia
doc = open_document("report.pdf")
json = fonts_to_json(doc, 0) # JSON array string
println(json)
Zig
var doc = try pdf_oxide.Document.open("report.pdf");
var fl = try doc.fontList(0); // owned FontList handle
defer fl.deinit();
const json = try fl.toJson(a); // JSON array string; caller owns the slice
defer a.free(json);
std.debug.print("{s}\n", .{json});
Objective-C
POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
NSString *json = [doc embeddedFontsJson:0 error:&err]; // JSON array string
printf("%s\n", json.UTF8String);
Elixir
{:ok, doc} = PdfOxide.open("report.pdf")
json = PdfOxide.fonts_to_json(doc, 0) # JSON array string
IO.puts(json)
バインディングの対応状況。
fonts_to_jsonは Swift (doc.fontsToJson(page)) と C ABI (pdf_oxide_fonts_to_json) で直接公開されています。Go バインディングは内部的にこれを呼び出してdoc.Fonts(page)を型付き構造体にデコードします。WASM ターゲットではコンパイルされません。
応用例
ドキュメントメタデータの完全表示
use pdf_oxide::PdfDocument;
use pdf_oxide::extractors::xmp::XmpExtractor;
let mut doc = PdfDocument::open("report.pdf")?;
// Basic info
let (major, minor) = doc.version();
println!("PDF Version: {}.{}", major, minor);
println!("Pages: {}", doc.page_count()?);
// XMP metadata
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
println!("\nXMP Metadata:");
println!(" Title: {:?}", xmp.dc_title);
println!(" Authors: {:?}", xmp.dc_creator);
println!(" Description: {:?}", xmp.dc_description);
println!(" Keywords: {:?}", xmp.pdf_keywords);
println!(" Creator: {:?}", xmp.xmp_creator_tool);
println!(" Producer: {:?}", xmp.pdf_producer);
println!(" Created: {:?}", xmp.xmp_create_date);
println!(" Modified: {:?}", xmp.xmp_modify_date);
println!(" Language: {:?}", xmp.dc_language);
println!(" Rights: {:?}", xmp.dc_rights);
if !xmp.custom.is_empty() {
println!("\n Custom properties:");
for (key, value) in &xmp.custom {
println!(" {}: {}", key, value);
}
}
}
生の XMP XML へのアクセス
use pdf_oxide::extractors::xmp::XmpExtractor;
let mut doc = PdfDocument::open("report.pdf")?;
if let Some(xmp) = XmpExtractor::extract(&mut doc)? {
if let Some(xml) = &xmp.raw_xml {
std::fs::write("metadata.xml", xml)?;
println!("Raw XMP saved ({} bytes)", xml.len());
}
}
ページ番号の表示文字列を生成する
use pdf_oxide::api::Pdf;
let mut pdf = Pdf::open("thesis.pdf")?;
let page_count = pdf.page_count()?;
for i in 0..page_count {
let label = pdf.page_label(i)?;
println!("Physical page {} -> display label '{}'", i + 1, label);
}
// Example output:
// Physical page 1 -> display label 'i'
// Physical page 2 -> display label 'ii'
// Physical page 3 -> display label 'iii'
// Physical page 4 -> display label '1'
// Physical page 5 -> display label '2'
よくある質問
get_producer はどこから読み取りますか?
ドキュメント Info 辞書の /Info.Producer エントリから読み取ります。DocumentEditor(読み書き可能)上に存在し、対応するセッターは保存時に /Info.Producer に変更を永続化します。XMP の pdf:Producer の値は、XmpMetadata の pdf_producer として別途取得できます。
embedded_fonts がテキストに現れるフォントしか返さないのはなぜですか?
フォントリストはページのレンダリング済みテキストスパンから導出されるため、そのページでグリフを描画するために実際に使用されたフォントが反映されます。サブセット検出は PDF の規約に従い、6 文字タグ++(例: ABCDEF+Helvetica)で行われます。
fonts_to_json が返す JSON スキーマはどのようなものですか?
name、type、encoding、isEmbedded、isSubset、size フィールドを持つオブジェクトの JSON 配列です。Go バインディングが Font 構造体にアンマーシャルするのと同じ形式です。
メタデータ抽出は高速ですか? はい。PDF Oxide の抽出コアは、ベンチマークコーパスで平均約 0.8 ms、p99 で 9 ms、合格率 100% で動作します。
関連ページ
- テキスト抽出 – ページからテキストコンテンツを抽出する
- 注釈の抽出 – ブックマークと注釈にアクセスする
- フォームデータの抽出 – フォームフィールドデータを抽出する
- 画像の抽出 – 埋め込み画像とページ要素アクセサー