mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Make all fields of Frame
private
This commit is contained in:
parent
ed6550fdb0
commit
6e3b1a2c80
@ -611,19 +611,24 @@ impl<'a, 'b> PageExporter<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn export(mut self, frame: &Frame) -> Page {
|
fn export(mut self, frame: &Frame) -> Page {
|
||||||
|
let size = frame.size();
|
||||||
|
|
||||||
// Make the coordinate system start at the top-left.
|
// Make the coordinate system start at the top-left.
|
||||||
self.bottom = frame.size.y.to_f32();
|
self.bottom = size.y.to_f32();
|
||||||
self.transform(Transform {
|
self.transform(Transform {
|
||||||
sx: Ratio::one(),
|
sx: Ratio::one(),
|
||||||
ky: Ratio::zero(),
|
ky: Ratio::zero(),
|
||||||
kx: Ratio::zero(),
|
kx: Ratio::zero(),
|
||||||
sy: Ratio::new(-1.0),
|
sy: Ratio::new(-1.0),
|
||||||
tx: Length::zero(),
|
tx: Length::zero(),
|
||||||
ty: frame.size.y,
|
ty: size.y,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Encode the page into the content stream.
|
||||||
self.write_frame(frame);
|
self.write_frame(frame);
|
||||||
|
|
||||||
Page {
|
Page {
|
||||||
size: frame.size,
|
size,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
id: self.page_ref,
|
id: self.page_ref,
|
||||||
links: self.links,
|
links: self.links,
|
||||||
@ -648,7 +653,7 @@ impl<'a, 'b> PageExporter<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for &(pos, ref element) in &frame.elements {
|
for &(pos, ref element) in frame.elements() {
|
||||||
let x = pos.x.to_f32();
|
let x = pos.x.to_f32();
|
||||||
let y = pos.y.to_f32();
|
let y = pos.y.to_f32();
|
||||||
match *element {
|
match *element {
|
||||||
@ -669,8 +674,9 @@ impl<'a, 'b> PageExporter<'a, 'b> {
|
|||||||
self.transform(translation.pre_concat(group.transform));
|
self.transform(translation.pre_concat(group.transform));
|
||||||
|
|
||||||
if group.clips {
|
if group.clips {
|
||||||
let w = group.frame.size.x.to_f32();
|
let size = group.frame.size();
|
||||||
let h = group.frame.size.y.to_f32();
|
let w = size.x.to_f32();
|
||||||
|
let h = size.y.to_f32();
|
||||||
self.content.move_to(0.0, 0.0);
|
self.content.move_to(0.0, 0.0);
|
||||||
self.content.line_to(w, 0.0);
|
self.content.line_to(w, 0.0);
|
||||||
self.content.line_to(w, h);
|
self.content.line_to(w, h);
|
||||||
|
@ -23,8 +23,9 @@ use crate::Context;
|
|||||||
/// compilation so that fonts and images can be rendered and rendering artifacts
|
/// compilation so that fonts and images can be rendered and rendering artifacts
|
||||||
/// can be cached.
|
/// can be cached.
|
||||||
pub fn render(ctx: &Context, frame: &Frame, pixel_per_pt: f32) -> sk::Pixmap {
|
pub fn render(ctx: &Context, frame: &Frame, pixel_per_pt: f32) -> sk::Pixmap {
|
||||||
let pxw = (pixel_per_pt * frame.size.x.to_f32()).round().max(1.0) as u32;
|
let size = frame.size();
|
||||||
let pxh = (pixel_per_pt * frame.size.y.to_f32()).round().max(1.0) as u32;
|
let pxw = (pixel_per_pt * size.x.to_f32()).round().max(1.0) as u32;
|
||||||
|
let pxh = (pixel_per_pt * size.y.to_f32()).round().max(1.0) as u32;
|
||||||
|
|
||||||
let mut canvas = sk::Pixmap::new(pxw, pxh).unwrap();
|
let mut canvas = sk::Pixmap::new(pxw, pxh).unwrap();
|
||||||
canvas.fill(sk::Color::WHITE);
|
canvas.fill(sk::Color::WHITE);
|
||||||
@ -43,7 +44,7 @@ fn render_frame(
|
|||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
frame: &Frame,
|
frame: &Frame,
|
||||||
) {
|
) {
|
||||||
for (pos, element) in &frame.elements {
|
for (pos, element) in frame.elements() {
|
||||||
let x = pos.x.to_f32();
|
let x = pos.x.to_f32();
|
||||||
let y = pos.y.to_f32();
|
let y = pos.y.to_f32();
|
||||||
let ts = ts.pre_translate(x, y);
|
let ts = ts.pre_translate(x, y);
|
||||||
@ -80,8 +81,9 @@ fn render_group(
|
|||||||
let mut mask = mask;
|
let mut mask = mask;
|
||||||
let mut storage;
|
let mut storage;
|
||||||
if group.clips {
|
if group.clips {
|
||||||
let w = group.frame.size.x.to_f32();
|
let size = group.frame.size();
|
||||||
let h = group.frame.size.y.to_f32();
|
let w = size.x.to_f32();
|
||||||
|
let h = size.y.to_f32();
|
||||||
if let Some(path) = sk::Rect::from_xywh(0.0, 0.0, w, h)
|
if let Some(path) = sk::Rect::from_xywh(0.0, 0.0, w, h)
|
||||||
.map(sk::PathBuilder::from_rect)
|
.map(sk::PathBuilder::from_rect)
|
||||||
.and_then(|path| path.transform(ts))
|
.and_then(|path| path.transform(ts))
|
||||||
|
141
src/frame.rs
141
src/frame.rs
@ -17,38 +17,65 @@ use crate::util::{EcoString, MaybeShared};
|
|||||||
#[derive(Default, Clone, Eq, PartialEq)]
|
#[derive(Default, Clone, Eq, PartialEq)]
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
/// The size of the frame.
|
/// The size of the frame.
|
||||||
pub size: Size,
|
size: Size,
|
||||||
/// The baseline of the frame measured from the top. If this is `None`, the
|
/// The baseline of the frame measured from the top. If this is `None`, the
|
||||||
/// frame's implicit baseline is at the bottom.
|
/// frame's implicit baseline is at the bottom.
|
||||||
pub baseline: Option<Length>,
|
baseline: Option<Length>,
|
||||||
/// The elements composing this layout.
|
|
||||||
pub elements: Vec<(Point, Element)>,
|
|
||||||
/// The semantic role of the frame.
|
/// The semantic role of the frame.
|
||||||
role: Option<Role>,
|
role: Option<Role>,
|
||||||
|
/// The elements composing this layout.
|
||||||
|
elements: Vec<(Point, Element)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Accessors and setters.
|
||||||
impl Frame {
|
impl Frame {
|
||||||
/// Create a new, empty frame.
|
/// Create a new, empty frame.
|
||||||
|
///
|
||||||
|
/// Panics the size is not finite.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn new(size: Size) -> Self {
|
pub fn new(size: Size) -> Self {
|
||||||
assert!(size.is_finite());
|
assert!(size.is_finite());
|
||||||
Self {
|
Self {
|
||||||
size,
|
size,
|
||||||
baseline: None,
|
baseline: None,
|
||||||
elements: vec![],
|
|
||||||
role: None,
|
role: None,
|
||||||
|
elements: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The size of the frame.
|
||||||
|
pub fn size(&self) -> Size {
|
||||||
|
self.size
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The size of the frame, mutably.
|
||||||
|
pub fn size_mut(&mut self) -> &mut Size {
|
||||||
|
&mut self.size
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the size of the frame.
|
||||||
|
pub fn set_size(&mut self, size: Size) {
|
||||||
|
self.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The width of the frame.
|
||||||
|
pub fn width(&self) -> Length {
|
||||||
|
self.size.x
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The height of the frame.
|
||||||
|
pub fn height(&self) -> Length {
|
||||||
|
self.size.y
|
||||||
|
}
|
||||||
|
|
||||||
/// The baseline of the frame.
|
/// The baseline of the frame.
|
||||||
pub fn baseline(&self) -> Length {
|
pub fn baseline(&self) -> Length {
|
||||||
self.baseline.unwrap_or(self.size.y)
|
self.baseline.unwrap_or(self.size.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The layer the next item will be added on. This corresponds to the number
|
/// Set the frame's baseline from the top.
|
||||||
/// of elements in the frame.
|
pub fn set_baseline(&mut self, baseline: Length) {
|
||||||
pub fn layer(&self) -> usize {
|
self.baseline = Some(baseline);
|
||||||
self.elements.len()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The role of the frame.
|
/// The role of the frame.
|
||||||
@ -56,9 +83,36 @@ impl Frame {
|
|||||||
self.role
|
self.role
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the frame has comparatively few elements.
|
/// An iterator over the elements inside this frame alongside their
|
||||||
pub fn is_light(&self) -> bool {
|
/// positions relative to the top-left of the frame.
|
||||||
self.elements.len() <= 5
|
pub fn elements(&self) -> std::slice::Iter<'_, (Point, Element)> {
|
||||||
|
self.elements.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Recover the text inside of the frame and its children.
|
||||||
|
pub fn text(&self) -> EcoString {
|
||||||
|
let mut text = EcoString::new();
|
||||||
|
for (_, element) in &self.elements {
|
||||||
|
match element {
|
||||||
|
Element::Text(content) => {
|
||||||
|
for glyph in &content.glyphs {
|
||||||
|
text.push(glyph.c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Element::Group(group) => text.push_str(&group.frame.text()),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Inserting elements and subframes.
|
||||||
|
impl Frame {
|
||||||
|
/// The layer the next item will be added on. This corresponds to the number
|
||||||
|
/// of elements in the frame.
|
||||||
|
pub fn layer(&self) -> usize {
|
||||||
|
self.elements.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add an element at a position in the foreground.
|
/// Add an element at a position in the foreground.
|
||||||
@ -66,6 +120,14 @@ impl Frame {
|
|||||||
self.elements.push((pos, element));
|
self.elements.push((pos, element));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Insert an element at the given layer in the frame.
|
||||||
|
///
|
||||||
|
/// This panics if the layer is greater than the number of layers present.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn insert(&mut self, layer: usize, pos: Point, element: Element) {
|
||||||
|
self.elements.insert(layer, (pos, element));
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a frame.
|
/// Add a frame.
|
||||||
///
|
///
|
||||||
/// Automatically decides whether to inline the frame or to include it as a
|
/// Automatically decides whether to inline the frame or to include it as a
|
||||||
@ -105,11 +167,17 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert an element at the given layer in the frame.
|
/// Whether the frame has comparatively few elements.
|
||||||
///
|
fn is_light(&self) -> bool {
|
||||||
/// This panics if the layer is greater than the number of layers present.
|
self.elements.len() <= 5
|
||||||
pub fn insert(&mut self, layer: usize, pos: Point, element: Element) {
|
}
|
||||||
self.elements.insert(layer, (pos, element));
|
}
|
||||||
|
|
||||||
|
/// Modify the frame.
|
||||||
|
impl Frame {
|
||||||
|
/// Remove all elements from the frame.
|
||||||
|
pub fn clear(&mut self) {
|
||||||
|
self.elements.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize the frame to a new size, distributing new space according to the
|
/// Resize the frame to a new size, distributing new space according to the
|
||||||
@ -137,11 +205,6 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Arbitrarily transform the contents of the frame.
|
|
||||||
pub fn transform(&mut self, transform: Transform) {
|
|
||||||
self.group(|g| g.transform = transform);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Apply the given role to the frame if it doesn't already have one.
|
/// Apply the given role to the frame if it doesn't already have one.
|
||||||
pub fn apply_role(&mut self, role: Role) {
|
pub fn apply_role(&mut self, role: Role) {
|
||||||
if self.role.map_or(true, Role::is_weak) {
|
if self.role.map_or(true, Role::is_weak) {
|
||||||
@ -149,13 +212,23 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Link the whole frame to a resource.
|
||||||
|
pub fn link(&mut self, dest: Destination) {
|
||||||
|
self.push(Point::zero(), Element::Link(dest, self.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Arbitrarily transform the contents of the frame.
|
||||||
|
pub fn transform(&mut self, transform: Transform) {
|
||||||
|
self.group(|g| g.transform = transform);
|
||||||
|
}
|
||||||
|
|
||||||
/// Clip the contents of a frame to its size.
|
/// Clip the contents of a frame to its size.
|
||||||
pub fn clip(&mut self) {
|
pub fn clip(&mut self) {
|
||||||
self.group(|g| g.clips = true);
|
self.group(|g| g.clips = true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrap the frame's contents in a group and modify that group with `f`.
|
/// Wrap the frame's contents in a group and modify that group with `f`.
|
||||||
pub fn group<F>(&mut self, f: F)
|
fn group<F>(&mut self, f: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut Group),
|
F: FnOnce(&mut Group),
|
||||||
{
|
{
|
||||||
@ -165,28 +238,6 @@ impl Frame {
|
|||||||
wrapper.push(Point::zero(), Element::Group(group));
|
wrapper.push(Point::zero(), Element::Group(group));
|
||||||
*self = wrapper;
|
*self = wrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Link the whole frame to a resource.
|
|
||||||
pub fn link(&mut self, dest: Destination) {
|
|
||||||
self.push(Point::zero(), Element::Link(dest, self.size));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Recover the text inside of the frame and its children.
|
|
||||||
pub fn text(&self) -> EcoString {
|
|
||||||
let mut text = EcoString::new();
|
|
||||||
for (_, element) in &self.elements {
|
|
||||||
match element {
|
|
||||||
Element::Text(content) => {
|
|
||||||
for glyph in &content.glyphs {
|
|
||||||
text.push(glyph.c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Element::Group(group) => text.push_str(&group.frame.text()),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
text
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Frame {
|
impl Debug for Frame {
|
||||||
|
@ -22,11 +22,7 @@ impl Layout for HideNode {
|
|||||||
|
|
||||||
// Clear the frames.
|
// Clear the frames.
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
*frame = Arc::new({
|
Arc::make_mut(frame).clear();
|
||||||
let mut empty = Frame::new(frame.size);
|
|
||||||
empty.baseline = frame.baseline;
|
|
||||||
empty
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(frames)
|
Ok(frames)
|
||||||
|
@ -104,7 +104,7 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
|
|||||||
let target = regions.expand.select(regions.first, Size::zero());
|
let target = regions.expand.select(regions.first, Size::zero());
|
||||||
target.x.max(target.y)
|
target.x.max(target.y)
|
||||||
} else {
|
} else {
|
||||||
let size = frames[0].size;
|
let size = frames[0].size();
|
||||||
let desired = size.x.max(size.y);
|
let desired = size.x.max(size.y);
|
||||||
desired.min(regions.first.x).min(regions.first.y)
|
desired.min(regions.first.x).min(regions.first.y)
|
||||||
};
|
};
|
||||||
@ -146,8 +146,8 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let outset = styles.get(Self::OUTSET).relative_to(frame.size);
|
let outset = styles.get(Self::OUTSET).relative_to(frame.size());
|
||||||
let size = frame.size + outset.sum_by_axis();
|
let size = frame.size() + outset.sum_by_axis();
|
||||||
|
|
||||||
let radius = styles
|
let radius = styles
|
||||||
.get(Self::RADIUS)
|
.get(Self::RADIUS)
|
||||||
|
@ -33,7 +33,7 @@ impl Layout for MoveNode {
|
|||||||
|
|
||||||
let delta = self.delta.resolve(styles);
|
let delta = self.delta.resolve(styles);
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
let delta = delta.zip(frame.size).map(|(d, s)| d.relative_to(s));
|
let delta = delta.zip(frame.size()).map(|(d, s)| d.relative_to(s));
|
||||||
Arc::make_mut(frame).translate(delta.to_point());
|
Arc::make_mut(frame).translate(delta.to_point());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ impl<const T: TransformKind> Layout for TransformNode<T> {
|
|||||||
let mut frames = self.child.layout(ctx, regions, styles)?;
|
let mut frames = self.child.layout(ctx, regions, styles)?;
|
||||||
|
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
let Spec { x, y } = origin.zip(frame.size).map(|(o, s)| o.position(s));
|
let Spec { x, y } = origin.zip(frame.size()).map(|(o, s)| o.position(s));
|
||||||
let transform = Transform::translate(x, y)
|
let transform = Transform::translate(x, y)
|
||||||
.pre_concat(self.transform)
|
.pre_concat(self.transform)
|
||||||
.pre_concat(Transform::translate(-x, -y));
|
.pre_concat(Transform::translate(-x, -y));
|
||||||
|
@ -47,7 +47,7 @@ impl Layout for AlignNode {
|
|||||||
for (region, frame) in regions.iter().zip(&mut frames) {
|
for (region, frame) in regions.iter().zip(&mut frames) {
|
||||||
// Align in the target size. The target size depends on whether we
|
// Align in the target size. The target size depends on whether we
|
||||||
// should expand.
|
// should expand.
|
||||||
let target = regions.expand.select(region, frame.size);
|
let target = regions.expand.select(region, frame.size());
|
||||||
let aligns = self
|
let aligns = self
|
||||||
.aligns
|
.aligns
|
||||||
.map(|align| align.resolve(styles))
|
.map(|align| align.resolve(styles))
|
||||||
|
@ -80,10 +80,10 @@ impl Layout for ColumnsNode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !regions.expand.y {
|
if !regions.expand.y {
|
||||||
output.size.y.set_max(frame.size.y);
|
output.size_mut().y.set_max(frame.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
let width = frame.size.x;
|
let width = frame.width();
|
||||||
let x = if dir.is_positive() {
|
let x = if dir.is_positive() {
|
||||||
cursor
|
cursor
|
||||||
} else {
|
} else {
|
||||||
|
@ -189,7 +189,7 @@ impl FlowLayouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grow our size, shrink the region and save the frame for later.
|
// Grow our size, shrink the region and save the frame for later.
|
||||||
let size = frame.size;
|
let size = frame.size();
|
||||||
self.used.y += size.y;
|
self.used.y += size.y;
|
||||||
self.used.x.set_max(size.x);
|
self.used.x.set_max(size.x);
|
||||||
self.regions.first.y -= size.y;
|
self.regions.first.y -= size.y;
|
||||||
@ -231,10 +231,10 @@ impl FlowLayouter {
|
|||||||
}
|
}
|
||||||
FlowItem::Frame(frame, aligns) => {
|
FlowItem::Frame(frame, aligns) => {
|
||||||
ruler = ruler.max(aligns.y);
|
ruler = ruler.max(aligns.y);
|
||||||
let x = aligns.x.position(size.x - frame.size.x);
|
let x = aligns.x.position(size.x - frame.width());
|
||||||
let y = offset + ruler.position(size.y - self.used.y);
|
let y = offset + ruler.position(size.y - self.used.y);
|
||||||
let pos = Point::new(x, y);
|
let pos = Point::new(x, y);
|
||||||
offset += frame.size.y;
|
offset += frame.height();
|
||||||
output.push_frame(pos, frame);
|
output.push_frame(pos, frame);
|
||||||
}
|
}
|
||||||
FlowItem::Placed(frame) => {
|
FlowItem::Placed(frame) => {
|
||||||
|
@ -304,7 +304,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let frame = node.layout(self.ctx, &pod, self.styles)?.remove(0);
|
let frame = node.layout(self.ctx, &pod, self.styles)?.remove(0);
|
||||||
resolved.set_max(frame.size.x);
|
resolved.set_max(frame.width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +376,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
let mut sizes = node
|
let mut sizes = node
|
||||||
.layout(self.ctx, &pod, self.styles)?
|
.layout(self.ctx, &pod, self.styles)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|frame| frame.size.y);
|
.map(|frame| frame.height());
|
||||||
self.ctx.pins.unfreeze();
|
self.ctx.pins.unfreeze();
|
||||||
|
|
||||||
// For each region, we want to know the maximum height any
|
// For each region, we want to know the maximum height any
|
||||||
@ -432,7 +432,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
let frame = self.layout_single_row(resolved, y)?;
|
let frame = self.layout_single_row(resolved, y)?;
|
||||||
|
|
||||||
// Skip to fitting region.
|
// Skip to fitting region.
|
||||||
let height = frame.size.y;
|
let height = frame.height();
|
||||||
while !self.regions.first.y.fits(height) && !self.regions.in_last() {
|
while !self.regions.first.y.fits(height) && !self.regions.in_last() {
|
||||||
self.finish_region()?;
|
self.finish_region()?;
|
||||||
|
|
||||||
@ -533,8 +533,8 @@ impl<'a> GridLayouter<'a> {
|
|||||||
|
|
||||||
/// Push a row frame into the current region.
|
/// Push a row frame into the current region.
|
||||||
fn push_row(&mut self, frame: Frame) {
|
fn push_row(&mut self, frame: Frame) {
|
||||||
self.regions.first.y -= frame.size.y;
|
self.regions.first.y -= frame.height();
|
||||||
self.used.y += frame.size.y;
|
self.used.y += frame.height();
|
||||||
self.lrows.push(Row::Frame(frame));
|
self.lrows.push(Row::Frame(frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ impl<'a> GridLayouter<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let height = frame.size.y;
|
let height = frame.height();
|
||||||
output.push_frame(pos, frame);
|
output.push_frame(pos, frame);
|
||||||
pos.y += height;
|
pos.y += height;
|
||||||
}
|
}
|
||||||
|
@ -40,13 +40,13 @@ impl Layout for PadNode {
|
|||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
// Apply the padding inversely such that the grown size padded
|
// Apply the padding inversely such that the grown size padded
|
||||||
// yields the frame's size.
|
// yields the frame's size.
|
||||||
let padded = grow(frame.size, padding);
|
let padded = grow(frame.size(), padding);
|
||||||
let padding = padding.relative_to(padded);
|
let padding = padding.relative_to(padded);
|
||||||
let offset = Point::new(padding.left, padding.top);
|
let offset = Point::new(padding.left, padding.top);
|
||||||
|
|
||||||
// Grow the frame and translate everything in the frame inwards.
|
// Grow the frame and translate everything in the frame inwards.
|
||||||
let frame = Arc::make_mut(frame);
|
let frame = Arc::make_mut(frame);
|
||||||
frame.size = padded;
|
frame.set_size(padded);
|
||||||
frame.translate(offset);
|
frame.translate(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ impl PageNode {
|
|||||||
|
|
||||||
// Realize overlays.
|
// Realize overlays.
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
let size = frame.size;
|
let size = frame.size();
|
||||||
let pad = padding.resolve(styles).relative_to(size);
|
let pad = padding.resolve(styles).relative_to(size);
|
||||||
let pw = size.x - pad.left - pad.right;
|
let pw = size.x - pad.left - pad.right;
|
||||||
let py = size.y - pad.bottom;
|
let py = size.y - pad.bottom;
|
||||||
|
@ -201,7 +201,7 @@ impl<'a> StackLayouter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Grow our size, shrink the region and save the frame for later.
|
// Grow our size, shrink the region and save the frame for later.
|
||||||
let size = frame.size.to_gen(self.axis);
|
let size = frame.size().to_gen(self.axis);
|
||||||
self.used.main += size.main;
|
self.used.main += size.main;
|
||||||
self.used.cross.set_max(size.cross);
|
self.used.cross.set_max(size.cross);
|
||||||
*self.regions.first.get_mut(self.axis) -= size.main;
|
*self.regions.first.get_mut(self.axis) -= size.main;
|
||||||
@ -248,7 +248,7 @@ impl<'a> StackLayouter<'a> {
|
|||||||
|
|
||||||
// Align along the block axis.
|
// Align along the block axis.
|
||||||
let parent = size.get(self.axis);
|
let parent = size.get(self.axis);
|
||||||
let child = frame.size.get(self.axis);
|
let child = frame.size().get(self.axis);
|
||||||
let block = ruler.position(parent - self.used.main)
|
let block = ruler.position(parent - self.used.main)
|
||||||
+ if self.dir.is_positive() {
|
+ if self.dir.is_positive() {
|
||||||
cursor
|
cursor
|
||||||
|
@ -66,8 +66,8 @@ impl Layout for RexNode {
|
|||||||
let mut backend = FrameBackend {
|
let mut backend = FrameBackend {
|
||||||
frame: {
|
frame: {
|
||||||
let mut frame = Frame::new(size);
|
let mut frame = Frame::new(size);
|
||||||
|
frame.set_baseline(baseline);
|
||||||
frame.apply_role(Role::Formula);
|
frame.apply_role(Role::Formula);
|
||||||
frame.baseline = Some(baseline);
|
|
||||||
frame
|
frame
|
||||||
},
|
},
|
||||||
baseline,
|
baseline,
|
||||||
|
@ -336,7 +336,7 @@ impl<'a> Item<'a> {
|
|||||||
match self {
|
match self {
|
||||||
Self::Text(shaped) => shaped.width,
|
Self::Text(shaped) => shaped.width,
|
||||||
Self::Absolute(v) => *v,
|
Self::Absolute(v) => *v,
|
||||||
Self::Frame(frame) => frame.size.x,
|
Self::Frame(frame) => frame.width(),
|
||||||
Self::Fractional(_) | Self::Repeat(_, _) | Self::Pin(_) => Length::zero(),
|
Self::Fractional(_) | Self::Repeat(_, _) | Self::Pin(_) => Length::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1071,7 +1071,7 @@ fn stack(
|
|||||||
// Stack the lines into one frame per region.
|
// Stack the lines into one frame per region.
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let frame = commit(p, ctx, line, ®ions, width)?;
|
let frame = commit(p, ctx, line, ®ions, width)?;
|
||||||
let height = frame.size.y;
|
let height = frame.size().y;
|
||||||
|
|
||||||
while !regions.first.y.fits(height) && !regions.in_last() {
|
while !regions.first.y.fits(height) && !regions.in_last() {
|
||||||
finished.push(Arc::new(output));
|
finished.push(Arc::new(output));
|
||||||
@ -1082,11 +1082,11 @@ fn stack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
output.size.y += p.leading;
|
output.size_mut().y += p.leading;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pos = Point::with_y(output.size.y);
|
let pos = Point::with_y(output.height());
|
||||||
output.size.y += height;
|
output.size_mut().y += height;
|
||||||
output.push_frame(pos, frame);
|
output.push_frame(pos, frame);
|
||||||
|
|
||||||
regions.first.y -= height + p.leading;
|
regions.first.y -= height + p.leading;
|
||||||
@ -1156,9 +1156,9 @@ fn commit(
|
|||||||
let mut frames = vec![];
|
let mut frames = vec![];
|
||||||
for item in reordered {
|
for item in reordered {
|
||||||
let mut push = |offset: &mut Length, frame: MaybeShared<Frame>| {
|
let mut push = |offset: &mut Length, frame: MaybeShared<Frame>| {
|
||||||
let width = frame.size.x;
|
let width = frame.width();
|
||||||
top.set_max(frame.baseline());
|
top.set_max(frame.baseline());
|
||||||
bottom.set_max(frame.size.y - frame.baseline());
|
bottom.set_max(frame.size().y - frame.baseline());
|
||||||
frames.push((*offset, frame));
|
frames.push((*offset, frame));
|
||||||
*offset += width;
|
*offset += width;
|
||||||
};
|
};
|
||||||
@ -1179,23 +1179,24 @@ fn commit(
|
|||||||
}
|
}
|
||||||
Item::Repeat(node, styles) => {
|
Item::Repeat(node, styles) => {
|
||||||
let before = offset;
|
let before = offset;
|
||||||
let width = Fraction::one().share(fr, remaining);
|
let fill = Fraction::one().share(fr, remaining);
|
||||||
let size = Size::new(width, regions.base.y);
|
let size = Size::new(fill, regions.base.y);
|
||||||
let pod = Regions::one(size, regions.base, Spec::new(false, false));
|
let pod = Regions::one(size, regions.base, Spec::new(false, false));
|
||||||
let frame = node.layout(ctx, &pod, *styles)?.remove(0);
|
let frame = node.layout(ctx, &pod, *styles)?.remove(0);
|
||||||
let count = (width / frame.size.x).floor();
|
let width = frame.width();
|
||||||
let remaining = width % frame.size.x;
|
let count = (fill / width).floor();
|
||||||
|
let remaining = fill % width;
|
||||||
let apart = remaining / (count - 1.0);
|
let apart = remaining / (count - 1.0);
|
||||||
if count == 1.0 {
|
if count == 1.0 {
|
||||||
offset += p.align.position(remaining);
|
offset += p.align.position(remaining);
|
||||||
}
|
}
|
||||||
if frame.size.x > Length::zero() {
|
if width > Length::zero() {
|
||||||
for _ in 0 .. (count as usize).min(1000) {
|
for _ in 0 .. (count as usize).min(1000) {
|
||||||
push(&mut offset, MaybeShared::Shared(frame.clone()));
|
push(&mut offset, MaybeShared::Shared(frame.clone()));
|
||||||
offset += apart;
|
offset += apart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset = before + width;
|
offset = before + fill;
|
||||||
}
|
}
|
||||||
Item::Pin(idx) => {
|
Item::Pin(idx) => {
|
||||||
let mut frame = Frame::new(Size::zero());
|
let mut frame = Frame::new(Size::zero());
|
||||||
@ -1212,7 +1213,7 @@ fn commit(
|
|||||||
|
|
||||||
let size = Size::new(width, top + bottom);
|
let size = Size::new(width, top + bottom);
|
||||||
let mut output = Frame::new(size);
|
let mut output = Frame::new(size);
|
||||||
output.baseline = Some(top);
|
output.set_baseline(top);
|
||||||
|
|
||||||
// Construct the line's frame.
|
// Construct the line's frame.
|
||||||
for (offset, frame) in frames {
|
for (offset, frame) in frames {
|
||||||
|
@ -84,7 +84,7 @@ impl<'a> ShapedText<'a> {
|
|||||||
|
|
||||||
let mut offset = Length::zero();
|
let mut offset = Length::zero();
|
||||||
let mut frame = Frame::new(size);
|
let mut frame = Frame::new(size);
|
||||||
frame.baseline = Some(top);
|
frame.set_baseline(top);
|
||||||
|
|
||||||
let shift = self.styles.get(TextNode::BASELINE);
|
let shift = self.styles.get(TextNode::BASELINE);
|
||||||
let lang = self.styles.get(TextNode::LANG);
|
let lang = self.styles.get(TextNode::LANG);
|
||||||
@ -103,7 +103,7 @@ impl<'a> ShapedText<'a> {
|
|||||||
id: glyph.glyph_id,
|
id: glyph.glyph_id,
|
||||||
x_advance: glyph.x_advance
|
x_advance: glyph.x_advance
|
||||||
+ if glyph.is_justifiable() {
|
+ if glyph.is_justifiable() {
|
||||||
frame.size.x += justification;
|
frame.size_mut().x += justification;
|
||||||
Em::from_length(justification, self.size)
|
Em::from_length(justification, self.size)
|
||||||
} else {
|
} else {
|
||||||
Em::zero()
|
Em::zero()
|
||||||
@ -120,6 +120,7 @@ impl<'a> ShapedText<'a> {
|
|||||||
fill,
|
fill,
|
||||||
glyphs,
|
glyphs,
|
||||||
};
|
};
|
||||||
|
|
||||||
let text_layer = frame.layer();
|
let text_layer = frame.layer();
|
||||||
let width = text.width();
|
let width = text.width();
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@ impl Layout for SizedNode {
|
|||||||
|
|
||||||
// Ensure frame size matches regions size if expansion is on.
|
// Ensure frame size matches regions size if expansion is on.
|
||||||
let frame = &mut frames[0];
|
let frame = &mut frames[0];
|
||||||
let target = regions.expand.select(regions.first, frame.size);
|
let target = regions.expand.select(regions.first, frame.size());
|
||||||
Arc::make_mut(frame).resize(target, Align::LEFT_TOP);
|
Arc::make_mut(frame).resize(target, Align::LEFT_TOP);
|
||||||
|
|
||||||
Ok(frames)
|
Ok(frames)
|
||||||
@ -391,7 +391,7 @@ impl Layout for FillNode {
|
|||||||
) -> TypResult<Vec<Arc<Frame>>> {
|
) -> TypResult<Vec<Arc<Frame>>> {
|
||||||
let mut frames = self.child.layout(ctx, regions, styles)?;
|
let mut frames = self.child.layout(ctx, regions, styles)?;
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
let shape = Geometry::Rect(frame.size).filled(self.fill);
|
let shape = Geometry::Rect(frame.size()).filled(self.fill);
|
||||||
Arc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape));
|
Arc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape));
|
||||||
}
|
}
|
||||||
Ok(frames)
|
Ok(frames)
|
||||||
@ -416,7 +416,7 @@ impl Layout for StrokeNode {
|
|||||||
) -> TypResult<Vec<Arc<Frame>>> {
|
) -> TypResult<Vec<Arc<Frame>>> {
|
||||||
let mut frames = self.child.layout(ctx, regions, styles)?;
|
let mut frames = self.child.layout(ctx, regions, styles)?;
|
||||||
for frame in &mut frames {
|
for frame in &mut frames {
|
||||||
let shape = Geometry::Rect(frame.size).stroked(self.stroke);
|
let shape = Geometry::Rect(frame.size()).stroked(self.stroke);
|
||||||
Arc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape));
|
Arc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape));
|
||||||
}
|
}
|
||||||
Ok(frames)
|
Ok(frames)
|
||||||
|
@ -299,7 +299,7 @@ fn locate_in_frame(
|
|||||||
frame: &Frame,
|
frame: &Frame,
|
||||||
ts: Transform,
|
ts: Transform,
|
||||||
) {
|
) {
|
||||||
for &(pos, ref element) in &frame.elements {
|
for &(pos, ref element) in frame.elements() {
|
||||||
match element {
|
match element {
|
||||||
Element::Group(group) => {
|
Element::Group(group) => {
|
||||||
let ts = ts
|
let ts = ts
|
||||||
|
@ -538,8 +538,8 @@ fn render(ctx: &mut Context, frames: &[Arc<Frame>]) -> sk::Pixmap {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|frame| {
|
.map(|frame| {
|
||||||
let limit = Length::cm(100.0);
|
let limit = Length::cm(100.0);
|
||||||
if frame.size.x > limit || frame.size.y > limit {
|
if frame.width() > limit || frame.height() > limit {
|
||||||
panic!("overlarge frame: {:?}", frame.size);
|
panic!("overlarge frame: {:?}", frame.size());
|
||||||
}
|
}
|
||||||
typst::export::render(ctx, frame, pixel_per_pt)
|
typst::export::render(ctx, frame, pixel_per_pt)
|
||||||
})
|
})
|
||||||
@ -579,7 +579,7 @@ fn render_links(
|
|||||||
ctx: &Context,
|
ctx: &Context,
|
||||||
frame: &Frame,
|
frame: &Frame,
|
||||||
) {
|
) {
|
||||||
for (pos, element) in &frame.elements {
|
for (pos, element) in frame.elements() {
|
||||||
let ts = ts.pre_translate(pos.x.to_pt() as f32, pos.y.to_pt() as f32);
|
let ts = ts.pre_translate(pos.x.to_pt() as f32, pos.y.to_pt() as f32);
|
||||||
match *element {
|
match *element {
|
||||||
Element::Group(ref group) => {
|
Element::Group(ref group) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user