summaryrefslogtreecommitdiff
path: root/src/library/deco.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-15 11:11:57 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-15 11:11:57 +0100
commitae38be9097bbb32142ef776e77e627ac12379000 (patch)
treef365a348d4c77d2d607d37fee3bc65a601d00a64 /src/library/deco.rs
parentfe21c4d399d291e75165b664762f0aa8bdc4724a (diff)
Set Rules Episode IV: A New Fold
Diffstat (limited to 'src/library/deco.rs')
-rw-r--r--src/library/deco.rs133
1 files changed, 0 insertions, 133 deletions
diff --git a/src/library/deco.rs b/src/library/deco.rs
deleted file mode 100644
index d12f60b0..00000000
--- a/src/library/deco.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-use super::prelude::*;
-use crate::util::EcoString;
-
-/// `strike`: Typeset striken-through text.
-pub fn strike(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- line_impl(args, LineKind::Strikethrough)
-}
-
-/// `underline`: Typeset underlined text.
-pub fn underline(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- line_impl(args, LineKind::Underline)
-}
-
-/// `overline`: Typeset text with an overline.
-pub fn overline(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- line_impl(args, LineKind::Overline)
-}
-
-fn line_impl(args: &mut Args, kind: LineKind) -> TypResult<Value> {
- let stroke = args.named("stroke")?.or_else(|| args.find());
- let thickness = args.named::<Linear>("thickness")?.or_else(|| args.find());
- let offset = args.named("offset")?;
- let extent = args.named("extent")?.unwrap_or_default();
- let body: Node = args.expect("body")?;
- Ok(Value::Node(body.decorated(Decoration::Line(
- LineDecoration { kind, stroke, thickness, offset, extent },
- ))))
-}
-
-/// `link`: Typeset text as a link.
-pub fn link(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
- let url = args.expect::<EcoString>("url")?;
- let body = args.find().unwrap_or_else(|| {
- let mut text = url.as_str();
- for prefix in ["mailto:", "tel:"] {
- text = text.trim_start_matches(prefix);
- }
- Node::Text(text.into())
- });
- Ok(Value::Node(body.decorated(Decoration::Link(url))))
-}
-
-/// A decoration for a frame.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub enum Decoration {
- /// A link to an external resource.
- Link(EcoString),
- /// An underline/strikethrough/overline decoration.
- Line(LineDecoration),
-}
-
-impl Decoration {
- /// Apply a decoration to a child's frame.
- pub fn apply(&self, ctx: &LayoutContext, frame: &mut Frame) {
- match self {
- Decoration::Link(href) => {
- let link = Element::Link(href.to_string(), frame.size);
- frame.push(Point::zero(), link);
- }
- Decoration::Line(line) => {
- line.apply(ctx, frame);
- }
- }
- }
-}
-
-/// Defines a line that is positioned over, under or on top of text.
-#[derive(Debug, Clone, Eq, PartialEq, Hash)]
-pub struct LineDecoration {
- /// The kind of line.
- pub kind: LineKind,
- /// Stroke color of the line, defaults to the text color if `None`.
- pub stroke: Option<Paint>,
- /// Thickness of the line's strokes (dependent on scaled font size), read
- /// from the font tables if `None`.
- pub thickness: Option<Linear>,
- /// Position of the line relative to the baseline (dependent on scaled font
- /// size), read from the font tables if `None`.
- pub offset: Option<Linear>,
- /// Amount that the line will be longer or shorter than its associated text
- /// (dependent on scaled font size).
- pub extent: Linear,
-}
-
-/// The kind of line decoration.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum LineKind {
- /// A line under text.
- Underline,
- /// A line through text.
- Strikethrough,
- /// A line over text.
- Overline,
-}
-
-impl LineDecoration {
- /// Apply a line decoration to a all text elements in a frame.
- pub fn apply(&self, ctx: &LayoutContext, frame: &mut Frame) {
- for i in 0 .. frame.elements.len() {
- let (pos, child) = &frame.elements[i];
- if let Element::Text(text) = child {
- let face = ctx.fonts.get(text.face_id);
- let metrics = match self.kind {
- LineKind::Underline => face.underline,
- LineKind::Strikethrough => face.strikethrough,
- LineKind::Overline => face.overline,
- };
-
- let thickness = self
- .thickness
- .map(|s| s.resolve(text.size))
- .unwrap_or(metrics.thickness.to_length(text.size));
-
- let stroke = Stroke {
- paint: self.stroke.unwrap_or(text.fill),
- thickness,
- };
-
- let offset = self
- .offset
- .map(|s| s.resolve(text.size))
- .unwrap_or(-metrics.position.to_length(text.size));
-
- let extent = self.extent.resolve(text.size);
-
- let subpos = Point::new(pos.x - extent, pos.y + offset);
- let target = Point::new(text.width() + 2.0 * extent, Length::zero());
- let shape = Shape::stroked(Geometry::Line(target), stroke);
- frame.push(subpos, Element::Shape(shape));
- }
- }
- }
-}