Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/pdf-cmap/src/to_unicode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl FromPdfObject for ToUnicodeMap {
/// Propagates malformed CMap streams. Unsupported names and other values decode to an
/// empty map, which falls back the same way an absent entry does.
fn from_pdf_object(context: ObjectContext<'_, impl ObjectAccess + ?Sized>) -> ReadResult<Self> {
let value = context.object().value();
let value = context.object();
if matches!(value, ObjectVariant::Stream(_)) {
return ToUnicodeCMap::from_pdf_object(context).map(Self::CMap);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/pdf-cmap/src/type0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl PdfCMap for Type0EncodingCMap {
impl FromPdfObject for Type0EncodingCMap {
/// Decodes an embedded stream or predefined name using the active object traversal.
fn from_pdf_object(context: ObjectContext<'_, impl ObjectAccess + ?Sized>) -> ReadResult<Self> {
match context.object().value() {
match context.object() {
ObjectVariant::Stream(_) => {
let context = context.stream()?;
Ok(Self::from_bytes(context.stream().raw_data())?)
Expand Down
2 changes: 1 addition & 1 deletion crates/pdf-color-space/src/color_space_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
/// decode-depth limit and cycle detection bound maliciously nested definitions.
impl FromPdfObject for ColorSpace {
fn from_pdf_object(context: ObjectContext<'_, impl ObjectAccess + ?Sized>) -> ReadResult<Self> {
let value = context.object().value();
let value = context.object();
let ObjectVariant::Array(array) = value else {
return Ok(Self::try_from(value.try_bytes(context.source())?)?);
};
Expand Down
2 changes: 1 addition & 1 deletion crates/pdf-color-space/src/device_n_color_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub struct DeviceNColorSpace {
impl FromPdfObject for DeviceNColorSpace {
fn from_pdf_object(context: ObjectContext<'_, impl ObjectAccess + ?Sized>) -> ReadResult<Self> {
let mut array = context.array()?;
let [_, names, _, tint_transform, ..] = array.array().as_slice() else {
let [_, names, _, tint_transform, ..] = array.array() else {
return Err(ColorSpaceError::InvalidColorSpace {
description: format!(
"/DeviceN requires [/DeviceN names alternateSpace tintTransform] with an optional attributes dictionary; found {} element(s)",
Expand Down
2 changes: 1 addition & 1 deletion crates/pdf-color-space/src/indexed_color_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct IndexedColorSpace {
impl FromPdfObject for IndexedColorSpace {
fn from_pdf_object(context: ObjectContext<'_, impl ObjectAccess + ?Sized>) -> ReadResult<Self> {
let mut array = context.array()?;
let [_, _, _, lookup] = array.array().as_slice() else {
let [_, _, _, lookup] = array.array() else {
return Err(ColorSpaceError::InvalidColorSpace {
description: format!(
"/Indexed requires 4 elements, found {}",
Expand Down
2 changes: 1 addition & 1 deletion crates/pdf-color-space/src/separation_color_space.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct SeparationColorSpace {
impl FromPdfObject for SeparationColorSpace {
fn from_pdf_object(context: ObjectContext<'_, impl ObjectAccess + ?Sized>) -> ReadResult<Self> {
let mut array = context.array()?;
let [_, name, _, tint_transform] = array.array().as_slice() else {
let [_, name, _, tint_transform] = array.array() else {
return Err(ColorSpaceError::InvalidColorSpace {
description: format!(
"/Separation requires 4 elements, found {}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::{
error::PdfOperatorError,
operands::Operands,
operator_trait::PdfOperator,
operator_trait::{OperandContext, PdfOperator},
pdf_operator_backend::{BackendError, PdfOperatorBackend},
variants::PdfOperatorVariant,
};
use pdf_object_reader::ReadResult;

/// Modifies the current clipping path by intersecting it with the current path, using the non-zero winding number rule to determine the region to clip.
#[derive(Debug, Clone, PartialEq, Default)]
Expand All @@ -15,7 +14,7 @@ impl PdfOperator for ClipNonZero {

const OPERAND_COUNT: Option<usize> = Some(0);

fn read(_operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
fn read(_operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
Ok(PdfOperatorVariant::ClipNonZero(Self))
}

Expand All @@ -33,7 +32,7 @@ impl PdfOperator for ClipEvenOdd {

const OPERAND_COUNT: Option<usize> = Some(0);

fn read(_operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
fn read(_operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
Ok(PdfOperatorVariant::ClipEvenOdd(Self))
}

Expand Down
131 changes: 46 additions & 85 deletions crates/pdf-content-stream-operators/src/color_operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ use std::sync::Arc;

use crate::{
error::PdfOperatorError,
operands::Operands,
operator_trait::PdfOperator,
operator_trait::{OperandContext, PdfOperator},
pdf_operator_backend::{BackendError, PdfOperatorBackend},
variants::PdfOperatorVariant,
};
use pdf_object_reader::object_resolver::PassthroughResolver;
use pdf_object_reader::{ReadResult, pdf_string::PdfString};

/// Sets the fill color to a grayscale value.
/// The gray level applies to subsequent fill operations.
Expand All @@ -33,10 +32,8 @@ impl PdfOperator for SetGrayFill {

const OPERAND_COUNT: Option<usize> = Some(1);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let gray = operands
.take_next()?
.try_number::<f32>(&PassthroughResolver)?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let gray = operands.at(0)?;
Ok(PdfOperatorVariant::SetGrayFill(Self::new(gray)))
}

Expand Down Expand Up @@ -64,10 +61,8 @@ impl PdfOperator for SetGrayStroke {

const OPERAND_COUNT: Option<usize> = Some(1);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let gray = operands
.take_next()?
.try_number::<f32>(&PassthroughResolver)?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let gray = operands.at(0)?;
Ok(PdfOperatorVariant::SetGrayStroke(Self::new(gray)))
}

Expand Down Expand Up @@ -104,8 +99,8 @@ impl PdfOperator for SetRGBFill {

const OPERAND_COUNT: Option<usize> = Some(3);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let [r, g, b] = operands.try_array_of::<f32, 3>()?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let [r, g, b] = operands.read_array()?;
Ok(PdfOperatorVariant::SetRGBFill(Self::new(r, g, b)))
}

Expand Down Expand Up @@ -137,8 +132,8 @@ impl PdfOperator for SetRGBStroke {

const OPERAND_COUNT: Option<usize> = Some(3);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let [r, g, b] = operands.try_array_of::<f32, 3>()?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let [r, g, b] = operands.read_array()?;
Ok(PdfOperatorVariant::SetRGBStroke(Self::new(r, g, b)))
}

Expand Down Expand Up @@ -177,8 +172,8 @@ impl PdfOperator for SetCMYKFill {

const OPERAND_COUNT: Option<usize> = Some(4);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let [c, m, y, k] = operands.try_array_of::<f32, 4>()?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let [c, m, y, k] = operands.read_array()?;
Ok(PdfOperatorVariant::SetCMYKFill(Self::new(c, m, y, k)))
}

Expand Down Expand Up @@ -212,8 +207,8 @@ impl PdfOperator for SetCMYKStroke {

const OPERAND_COUNT: Option<usize> = Some(4);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let [c, m, y, k] = operands.try_array_of::<f32, 4>()?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let [c, m, y, k] = operands.read_array()?;
Ok(PdfOperatorVariant::SetCMYKStroke(Self::new(c, m, y, k)))
}

Expand All @@ -239,8 +234,8 @@ impl PdfOperator for SetStrokeColorSpace {
const NAME: &'static [u8] = b"CS";
const OPERAND_COUNT: Option<usize> = Some(1);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let name = operands.get_string_bytes()?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let name = operands.at::<PdfString>(0)?.bytes;
Ok(PdfOperatorVariant::SetStrokeColorSpace(Self::new(name)))
}

Expand All @@ -266,8 +261,8 @@ impl PdfOperator for SetNonStrokingColorSpace {
const NAME: &'static [u8] = b"cs";
const OPERAND_COUNT: Option<usize> = Some(1);

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let name = operands.get_string_bytes()?;
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let name = operands.at::<PdfString>(0)?.bytes;
Ok(PdfOperatorVariant::SetNonStrokingColorSpace(Self::new(
name,
)))
Expand Down Expand Up @@ -301,28 +296,17 @@ impl PdfOperator for SetStrokingColor {
const NAME: &'static [u8] = b"SCN";
const OPERAND_COUNT: Option<usize> = None;

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let mut values = vec![];
while let Some(value) = operands.peek_next() {
if value.is_name() {
break;
}
let v = operands
.take_next()?
.try_number::<f32>(&PassthroughResolver)?;
values.push(v);
}

fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
// The pattern name should come last, after the numeric color components
let pattern = if operands
.peek_next()
.map(|obj| obj.is_name())
.unwrap_or(false)
{
operands.get_string_bytes().ok()
} else {
None
};
let count = operands
.array()
.iter()
.take_while(|value| !value.is_name())
.count();
let values = (0..count)
.map(|index| operands.at(index))
.collect::<ReadResult<_>>()?;
let pattern = operands.at::<PdfString>(count).ok().map(|name| name.bytes);

Ok(PdfOperatorVariant::SetStrokingColor(Self::new(
values, pattern,
Expand Down Expand Up @@ -361,28 +345,17 @@ impl PdfOperator for SetNonStrokingColor {
const NAME: &'static [u8] = b"scn";
const OPERAND_COUNT: Option<usize> = None;

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let mut values = vec![];
while let Some(value) = operands.peek_next() {
if value.is_name() {
break;
}
let v = operands
.take_next()?
.try_number::<f32>(&PassthroughResolver)?;
values.push(v);
}

fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
// The pattern name should come last, after the numeric color components
let pattern = if operands
.peek_next()
.map(|obj| obj.is_name())
.unwrap_or(false)
{
operands.get_string_bytes().ok()
} else {
None
};
let count = operands
.array()
.iter()
.take_while(|value| !value.is_name())
.count();
let values = (0..count)
.map(|index| operands.at(index))
.collect::<ReadResult<_>>()?;
let pattern = operands.at::<PdfString>(count).ok().map(|name| name.bytes);

Ok(PdfOperatorVariant::SetNonStrokingColor(Self::new(
values, pattern,
Expand Down Expand Up @@ -414,22 +387,16 @@ impl PdfOperator for SetNonStrokingColorSc {
Ok(())
}

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let mut values = vec![];
while operands.peek_next().is_some() {
values.push(
operands
.take_next()?
.try_number::<f32>(&PassthroughResolver)?,
);
}
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let values: Vec<f32> = operands.read_all()?;

if values.is_empty() {
return Err(PdfOperatorError::OperandCountMismatch {
operator: "sc".to_string(),
expected: 1,
actual: 0,
});
}
.into());
}

Ok(PdfOperatorVariant::SetNonStrokingColor(
Expand All @@ -454,22 +421,16 @@ impl PdfOperator for SetStrokingColorSc {
Ok(())
}

fn read(operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
let mut values = vec![];
while operands.peek_next().is_some() {
values.push(
operands
.take_next()?
.try_number::<f32>(&PassthroughResolver)?,
);
}
fn read(operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
let values: Vec<f32> = operands.read_all()?;

if values.is_empty() {
return Err(PdfOperatorError::OperandCountMismatch {
operator: "SC".to_string(),
expected: 1,
actual: 0,
});
}
.into());
}

Ok(PdfOperatorVariant::SetStrokingColor(SetStrokingColor::new(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use crate::{
error::PdfOperatorError,
operands::Operands,
operator_trait::PdfOperator,
operator_trait::{OperandContext, PdfOperator},
pdf_operator_backend::{BackendError, PdfOperatorBackend},
variants::PdfOperatorVariant,
};
use pdf_object_reader::ReadResult;

/// Begins a compatibility section (BX).
///
Expand All @@ -22,7 +21,7 @@ impl PdfOperator for BeginCompatibility {

const OPERAND_COUNT: Option<usize> = Some(0);

fn read(_operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
fn read(_operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
Ok(PdfOperatorVariant::BeginCompatibility(BeginCompatibility))
}

Expand All @@ -40,7 +39,7 @@ impl PdfOperator for EndCompatibility {

const OPERAND_COUNT: Option<usize> = Some(0);

fn read(_operands: &mut Operands) -> Result<PdfOperatorVariant, PdfOperatorError> {
fn read(_operands: &mut OperandContext<'_, '_>) -> ReadResult<PdfOperatorVariant> {
Ok(PdfOperatorVariant::EndCompatibility(EndCompatibility))
}

Expand Down
7 changes: 0 additions & 7 deletions crates/pdf-content-stream-operators/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ pub enum PdfOperatorError {
UnsupportedOperator(&'static str),
#[error("Unknown PDF operator '{0}'")]
UnknownOperator(String),
#[error("Missing operand; expected {expected}")]
OperandMissing { expected: &'static str },
#[error("Invalid operand type; expected {expected}, found {found}")]
OperandTypeMismatch {
expected: &'static str,
found: &'static str,
},
#[error("Invalid operand value; expected {expected}, found '{found}'")]
InvalidOperandValue {
expected: &'static str,
Expand Down
Loading
Loading