///|
fn pdf_space_number_array_object(
values : ArrayView[Double],
) -> @syntax.PdfObject {
PdfArray([ for value in values => PdfReal(value) ])
}
///|
fn pdf_space_point_object(point : PdfTristimulusPoint) -> @syntax.PdfObject {
PdfArray([PdfReal(point.x), PdfReal(point.y), PdfReal(point.z)])
}
///|
fn pdf_space_indexed_find(
table : ArrayView[(Int, Array[Int])],
index : Int,
) -> Array[Int]? {
for entry in table {
if entry.0 == index {
break Some(entry.1)
}
} nobreak {
None
}
}
///|
fn pdf_space_indexed_lookup_bytes(
table : ArrayView[(Int, Array[Int])],
) -> (Int, @core.PdfBytes)? {
guard table.length() > 0 else { return None }
let components = table[0].1.length()
let mut hival = table[0].0
let mut valid = components > 0
for entry in table {
if entry.0 < 0 || entry.1.length() != components {
valid = false
} else if entry.0 > hival {
hival = entry.0
}
}
guard valid else { return None }
let output = Array::make((hival + 1) * components, b'\x00')
let mut position = 0
for index in 0..<=hival {
match pdf_space_indexed_find(table, index) {
Some(values) =>
for value in values {
if value < 0 || value > 255 {
return None
}
output[position] = value.to_byte()
position += 1
}
None => return None
}
}
Some((hival, Bytes::from_array(output)))
}
///|
fn pdf_space_empty_dictionary(object : @syntax.PdfObject) -> Bool {
match object {
PdfDictionary(entries) => entries.length() == 0
_ => false
}
}
///|
/// Convert a parsed colour space back into a PDF object.
///
/// Returns `None` when the colour space cannot be serialized losslessly, such
/// as an indexed table with invalid component values or a base colour space that
/// itself cannot be represented.
pub fn pdf_object_of_colour_space(space : PdfColourSpace) -> @syntax.PdfObject? {
match space {
PdfDeviceGray => Some(PdfNameObject(pdf_space_device_gray_name))
PdfDeviceRGB => Some(PdfNameObject(pdf_space_device_rgb_name))
PdfDeviceCMYK => Some(PdfNameObject(pdf_space_device_cmyk_name))
PdfCalGray(whitepoint, blackpoint, gamma) =>
Some(
PdfArray([
PdfNameObject(pdf_space_calgray_name),
PdfDictionary([
(pdf_space_whitepoint_key(), pdf_space_point_object(whitepoint)),
(pdf_space_blackpoint_key(), pdf_space_point_object(blackpoint)),
(pdf_space_gamma_key(), PdfReal(gamma)),
]),
]),
)
PdfCalRGB(whitepoint, blackpoint, gamma, matrix) =>
Some(
PdfArray([
PdfNameObject(pdf_space_calrgb_name),
PdfDictionary([
(pdf_space_whitepoint_key(), pdf_space_point_object(whitepoint)),
(pdf_space_blackpoint_key(), pdf_space_point_object(blackpoint)),
(pdf_space_gamma_key(), pdf_space_number_array_object(gamma)),
(pdf_space_matrix_key(), pdf_space_number_array_object(matrix)),
]),
]),
)
PdfLab(whitepoint, blackpoint, range) =>
Some(
PdfArray([
PdfNameObject(pdf_space_lab_name),
PdfDictionary([
(pdf_space_whitepoint_key(), pdf_space_point_object(whitepoint)),
(pdf_space_blackpoint_key(), pdf_space_point_object(blackpoint)),
(pdf_space_range_key(), pdf_space_number_array_object(range)),
]),
]),
)
PdfICCBased(_, _, _, _, stream_object) =>
Some(PdfArray([PdfNameObject(pdf_space_iccbased_name), stream_object]))
PdfIndexed(base, table) =>
match
(
pdf_space_indexed_component_count(base),
pdf_object_of_colour_space(base),
pdf_space_indexed_lookup_bytes(table),
) {
(Some(_), Some(base_object), Some((hival, lookup))) =>
Some(
PdfArray([
PdfNameObject(pdf_space_indexed_name),
base_object,
PdfInteger(hival),
PdfString(lookup),
]),
)
_ => None
}
PdfPattern => Some(PdfNameObject(pdf_space_pattern_name))
PdfPatternWithBaseColourSpace(base) =>
match pdf_object_of_colour_space(base) {
Some(base_object) =>
Some(PdfArray([PdfNameObject(pdf_space_pattern_name), base_object]))
None => None
}
PdfSeparation(name, alternate, tint) =>
match pdf_object_of_colour_space(alternate) {
Some(alternate_object) =>
Some(
PdfArray([
PdfNameObject(pdf_space_separation_name),
PdfNameObject(name),
alternate_object,
tint,
]),
)
None => None
}
PdfDeviceN(names, alternate, tint, attributes) =>
match pdf_object_of_colour_space(alternate) {
Some(alternate_object) => {
let values : Array[@syntax.PdfObject] = [
PdfNameObject(pdf_space_device_n_name),
PdfArray([ for name in names => PdfNameObject(name) ]),
alternate_object,
tint,
]
if !pdf_space_empty_dictionary(attributes) {
values.push(attributes)
}
Some(PdfArray(values))
}
None => None
}
}
}
///|
/// Serialize a colour space for writing into a PDF object graph.
///
/// This delegates to `pdf_object_of_colour_space` and returns `PdfNull` when
/// the parsed colour space is not representable as a valid PDF object.
pub fn PdfDocument::write_colour_space(
_self : PdfDocument,
space : PdfColourSpace,
) -> @syntax.PdfObject {
match pdf_object_of_colour_space(space) {
Some(object) => object
None => PdfNull
}
}
///|
/// Compatibility wrapper for `PdfDocument::write_colour_space`.
pub fn pdf_write_colour_space(
document : PdfDocument,
space : PdfColourSpace,
) -> @syntax.PdfObject {
document.write_colour_space(space)
}