#[cfg(feature = "write")]
use lopdf::Object;
#[cfg(feature = "write")]
use crate::appearance_writer::{AppearanceColor, AppearanceStreamBuilder};
#[cfg(feature = "write")]
use super::types::AnnotSubtype;
#[cfg(feature = "write")]
use super::AnnotationBuilder;
#[cfg(feature = "write")]
impl AnnotationBuilder {
pub(super) fn default_appearance(&self, builder: &mut AppearanceStreamBuilder, w: f64, h: f64) {
let stroke = self.color.unwrap_or(AppearanceColor::new(0.0, 0.0, 0.0));
let needs_gs = self.opacity.is_some() || matches!(self.subtype, AnnotSubtype::Highlight);
if needs_gs {
builder.save_state();
builder.ops_push_raw(lopdf::content::Operation::new(
"gs",
vec![Object::Name(b"GS0".to_vec())],
));
}
match self.subtype {
AnnotSubtype::Square => {
if let Some(ref fill) = self.interior_color {
builder.filled_stroked_rect(fill, &stroke, self.border_width);
} else {
builder.stroked_rect(&stroke, self.border_width);
}
}
AnnotSubtype::Circle => {
builder.save_state();
if let Some(ref fill) = self.interior_color {
builder.set_fill_color(fill);
}
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width);
builder.ellipse();
if self.interior_color.is_some() {
builder.fill_and_stroke();
} else {
builder.stroke();
}
builder.restore_state();
}
AnnotSubtype::Line => {
builder.save_state();
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width);
if let Some(ref dash) = self.dash_pattern {
builder.set_dash_pattern(dash, 0.0);
}
if let Some(ref l) = self.line_endpoints {
let lx1 = l[0] - self.rect.x0;
let ly1 = l[1] - self.rect.y0;
let lx2 = l[2] - self.rect.x0;
let ly2 = l[3] - self.rect.y0;
builder.line(lx1, ly1, lx2, ly2);
} else {
builder.line(0.0, h / 2.0, w, h / 2.0);
}
builder.stroke();
builder.restore_state();
}
AnnotSubtype::Highlight => {
let fill = self.color.unwrap_or(AppearanceColor::new(1.0, 1.0, 0.0));
builder.filled_rect(&fill);
}
AnnotSubtype::Underline => {
builder.save_state();
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width.max(0.5));
builder.line(0.0, 0.0, w, 0.0);
builder.stroke();
builder.restore_state();
}
AnnotSubtype::StrikeOut => {
builder.save_state();
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width.max(0.5));
builder.line(0.0, h / 2.0, w, h / 2.0);
builder.stroke();
builder.restore_state();
}
AnnotSubtype::Squiggly => {
builder.save_state();
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width.max(0.5));
let step = 4.0;
let amp = 2.0;
builder.move_to(0.0, amp);
let mut x = 0.0;
let mut up = false;
while x < w {
x += step;
let y = if up { amp } else { 0.0 };
builder.line_to(x.min(w), y);
up = !up;
}
builder.stroke();
builder.restore_state();
}
AnnotSubtype::Ink => {
builder.save_state();
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width);
if let Some(ref ink) = self.ink_list {
for path in ink {
if path.len() >= 2 {
let x0 = path[0] - self.rect.x0;
let y0 = path[1] - self.rect.y0;
builder.move_to(x0, y0);
let mut i = 2;
while i + 1 < path.len() {
let x = path[i] - self.rect.x0;
let y = path[i + 1] - self.rect.y0;
builder.line_to(x, y);
i += 2;
}
builder.stroke();
}
}
}
builder.restore_state();
}
AnnotSubtype::Polygon | AnnotSubtype::PolyLine => {
builder.save_state();
if let Some(ref fill) = self.interior_color {
builder.set_fill_color(fill);
}
builder.set_stroke_color(&stroke);
builder.set_line_width(self.border_width);
if let Some(ref dash) = self.dash_pattern {
builder.set_dash_pattern(dash, 0.0);
}
if let Some(ref verts) = self.vertices {
if verts.len() >= 2 {
let x0 = verts[0] - self.rect.x0;
let y0 = verts[1] - self.rect.y0;
builder.move_to(x0, y0);
let mut i = 2;
while i + 1 < verts.len() {
let x = verts[i] - self.rect.x0;
let y = verts[i + 1] - self.rect.y0;
builder.line_to(x, y);
i += 2;
}
}
}
let is_polygon = matches!(self.subtype, AnnotSubtype::Polygon);
if is_polygon {
builder.close_path();
if self.interior_color.is_some() {
builder.fill_and_stroke();
} else {
builder.stroke();
}
} else {
builder.stroke();
}
builder.restore_state();
}
AnnotSubtype::FreeText => {
let white = AppearanceColor::new(1.0, 1.0, 1.0);
builder.filled_stroked_rect(&white, &stroke, self.border_width);
if let Some(ref text) = self.contents {
let text_color = self.color.unwrap_or(AppearanceColor::new(0.0, 0.0, 0.0));
let margin = self.border_width + 2.0;
builder.text(text, "Helv", 12.0, margin, h - margin - 12.0, &text_color);
}
}
AnnotSubtype::Text => {
let fill = AppearanceColor::new(1.0, 1.0, 0.6); builder.filled_stroked_rect(&fill, &stroke, self.border_width);
}
AnnotSubtype::Stamp => {
let red = AppearanceColor::new(1.0, 0.0, 0.0);
builder.stroked_rect(&red, 2.0);
if let Some(ref name) = self.icon_name {
builder.text(name, "Helv", 18.0, 4.0, h / 2.0 - 9.0, &red);
}
}
AnnotSubtype::Link => {
}
}
if needs_gs {
builder.restore_state();
}
}
}