appcore_filemaker/
text_padding.rs1use serde::{Deserialize, Serialize};
14
15use crate::{ErrorCode, FileMakerError, Insets, Length, Rect, Result, Size, TextLayout, Unit};
16
17#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
19#[serde(default, deny_unknown_fields)]
20pub struct TextBlockPadding {
21 pub top: Length,
23 pub right: Length,
25 pub bottom: Length,
27 pub left: Length,
29}
30
31impl Default for TextBlockPadding {
32 fn default() -> Self {
33 let zero = Length::Absolute(Unit::ZERO);
34 Self {
35 top: zero,
36 right: zero,
37 bottom: zero,
38 left: zero,
39 }
40 }
41}
42
43impl TextBlockPadding {
44 pub(crate) fn resolve(self, width: Unit, height: Unit, logical_unit: Unit) -> Result<Insets> {
45 let resolve = |value: Length, percent_base: Unit| {
46 value
47 .resolve(percent_base, logical_unit)?
48 .ok_or_else(|| padding_error("text block padding cannot be auto"))
49 };
50 Ok(Insets {
51 top: resolve(self.top, height)?,
52 right: resolve(self.right, width)?,
53 bottom: resolve(self.bottom, height)?,
54 left: resolve(self.left, width)?,
55 })
56 }
57}
58
59impl TextLayout {
60 pub fn outer_measured(&self) -> Result<Size> {
62 Size::new(
63 self.measured
64 .width
65 .checked_add(self.padding.left.checked_add(self.padding.right)?)?,
66 self.measured
67 .height
68 .checked_add(self.padding.top.checked_add(self.padding.bottom)?)?,
69 )
70 }
71
72 pub fn content_bounds(&self, bounds: Rect) -> Result<Rect> {
74 let x = bounds.origin.x.checked_add(self.padding.left)?;
75 let y = bounds.origin.y.checked_add(self.padding.top)?;
76 let width = bounds
77 .size
78 .width
79 .checked_sub(self.padding.left.checked_add(self.padding.right)?)?;
80 let height = bounds
81 .size
82 .height
83 .checked_sub(self.padding.top.checked_add(self.padding.bottom)?)?;
84 if width <= Unit::ZERO || height <= Unit::ZERO {
85 return Err(padding_error("text block padding leaves no content area"));
86 }
87 Rect::new(x, y, width, height)
88 }
89}
90
91fn padding_error(message: &'static str) -> FileMakerError {
92 FileMakerError::new(ErrorCode::LayoutInvalid, message)
93}