mirror of https://github.com/stelzo/typst.git
148 lines
4.0 KiB
Rust
148 lines
4.0 KiB
Rust
//! Extension traits.
|
|
|
|
use crate::prelude::*;
|
|
|
|
/// Additional methods on content.
|
|
pub trait ContentExt {
|
|
/// Make this content strong.
|
|
fn strong(self) -> Self;
|
|
|
|
/// Make this content emphasized.
|
|
fn emph(self) -> Self;
|
|
|
|
/// Underline this content.
|
|
fn underlined(self) -> Self;
|
|
|
|
/// Force a size for this content.
|
|
fn boxed(self, sizing: Axes<Option<Rel<Length>>>) -> Self;
|
|
|
|
/// Set alignments for this content.
|
|
fn aligned(self, aligns: Axes<Option<GenAlign>>) -> Self;
|
|
|
|
/// Pad this content at the sides.
|
|
fn padded(self, padding: Sides<Rel<Length>>) -> Self;
|
|
|
|
/// Transform this content's contents without affecting layout.
|
|
fn moved(self, delta: Axes<Rel<Length>>) -> Self;
|
|
|
|
/// Fill the frames resulting from a content.
|
|
fn filled(self, fill: Paint) -> Self;
|
|
|
|
/// Stroke the frames resulting from a content.
|
|
fn stroked(self, stroke: Stroke) -> Self;
|
|
}
|
|
|
|
impl ContentExt for Content {
|
|
fn strong(self) -> Self {
|
|
crate::text::StrongNode(self).pack()
|
|
}
|
|
|
|
fn emph(self) -> Self {
|
|
crate::text::EmphNode(self).pack()
|
|
}
|
|
|
|
fn underlined(self) -> Self {
|
|
crate::text::DecoNode::<{ crate::text::UNDERLINE }>(self).pack()
|
|
}
|
|
|
|
fn boxed(self, sizing: Axes<Option<Rel<Length>>>) -> Self {
|
|
crate::layout::BoxNode { sizing, child: self }.pack()
|
|
}
|
|
|
|
fn aligned(self, aligns: Axes<Option<GenAlign>>) -> Self {
|
|
crate::layout::AlignNode { aligns, child: self }.pack()
|
|
}
|
|
|
|
fn padded(self, padding: Sides<Rel<Length>>) -> Self {
|
|
crate::layout::PadNode { padding, child: self }.pack()
|
|
}
|
|
|
|
fn moved(self, delta: Axes<Rel<Length>>) -> Self {
|
|
crate::layout::MoveNode { delta, child: self }.pack()
|
|
}
|
|
|
|
fn filled(self, fill: Paint) -> Self {
|
|
FillNode { fill, child: self }.pack()
|
|
}
|
|
|
|
fn stroked(self, stroke: Stroke) -> Self {
|
|
StrokeNode { stroke, child: self }.pack()
|
|
}
|
|
}
|
|
|
|
/// Additional methods for style maps.
|
|
pub trait StyleMapExt {
|
|
/// Set a font family composed of a preferred family and existing families
|
|
/// from a style chain.
|
|
fn set_family(&mut self, preferred: crate::text::FontFamily, existing: StyleChain);
|
|
}
|
|
|
|
impl StyleMapExt for StyleMap {
|
|
fn set_family(&mut self, preferred: crate::text::FontFamily, existing: StyleChain) {
|
|
self.set(
|
|
crate::text::TextNode::FAMILY,
|
|
crate::text::FallbackList(
|
|
std::iter::once(preferred)
|
|
.chain(existing.get(crate::text::TextNode::FAMILY).0.iter().cloned())
|
|
.collect(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Fill the frames resulting from content.
|
|
#[derive(Debug, Hash)]
|
|
struct FillNode {
|
|
/// How to fill the frames resulting from the `child`.
|
|
fill: Paint,
|
|
/// The content whose frames should be filled.
|
|
child: Content,
|
|
}
|
|
|
|
#[node(Layout)]
|
|
impl FillNode {}
|
|
|
|
impl Layout for FillNode {
|
|
fn layout(
|
|
&self,
|
|
vt: &mut Vt,
|
|
styles: StyleChain,
|
|
regions: &Regions,
|
|
) -> SourceResult<Fragment> {
|
|
let mut fragment = self.child.layout(vt, styles, regions)?;
|
|
for frame in &mut fragment {
|
|
let shape = Geometry::Rect(frame.size()).filled(self.fill);
|
|
frame.prepend(Point::zero(), Element::Shape(shape));
|
|
}
|
|
Ok(fragment)
|
|
}
|
|
}
|
|
|
|
/// Stroke the frames resulting from content.
|
|
#[derive(Debug, Hash)]
|
|
struct StrokeNode {
|
|
/// How to stroke the frames resulting from the `child`.
|
|
stroke: Stroke,
|
|
/// The content whose frames should be stroked.
|
|
child: Content,
|
|
}
|
|
|
|
#[node(Layout)]
|
|
impl StrokeNode {}
|
|
|
|
impl Layout for StrokeNode {
|
|
fn layout(
|
|
&self,
|
|
vt: &mut Vt,
|
|
styles: StyleChain,
|
|
regions: &Regions,
|
|
) -> SourceResult<Fragment> {
|
|
let mut fragment = self.child.layout(vt, styles, regions)?;
|
|
for frame in &mut fragment {
|
|
let shape = Geometry::Rect(frame.size()).stroked(self.stroke);
|
|
frame.prepend(Point::zero(), Element::Shape(shape));
|
|
}
|
|
Ok(fragment)
|
|
}
|
|
}
|