mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
Make frames serializable 📚
This also makes serialization support non-optional since it's too much feature-management for too little benefit.
This commit is contained in:
parent
df58a4d89b
commit
72478946c2
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
# General
|
# General
|
||||||
.vscode
|
.vscode
|
||||||
_things
|
_things
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
# Tests and benchmarks
|
# Tests and benchmarks
|
||||||
tests/png
|
tests/png
|
||||||
|
@ -8,7 +8,6 @@ edition = "2018"
|
|||||||
default = ["fs"]
|
default = ["fs"]
|
||||||
fs = ["fontdock/fs"]
|
fs = ["fontdock/fs"]
|
||||||
cli = ["fs", "anyhow"]
|
cli = ["fs", "anyhow"]
|
||||||
# serde = []
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["bench"]
|
members = ["bench"]
|
||||||
@ -22,7 +21,7 @@ debug = 0
|
|||||||
opt-level = 2
|
opt-level = 2
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fontdock = { path = "../fontdock", default-features = false }
|
fontdock = { path = "../fontdock", features = ["serde"], default-features = false }
|
||||||
image = { version = "0.23", default-features = false, features = ["jpeg", "png"] }
|
image = { version = "0.23", default-features = false, features = ["jpeg", "png"] }
|
||||||
miniz_oxide = "0.3"
|
miniz_oxide = "0.3"
|
||||||
pdf-writer = { path = "../pdf-writer" }
|
pdf-writer = { path = "../pdf-writer" }
|
||||||
@ -32,7 +31,7 @@ unicode-bidi = "0.3.5"
|
|||||||
unicode-xid = "0.2"
|
unicode-xid = "0.2"
|
||||||
xi-unicode = "0.3"
|
xi-unicode = "0.3"
|
||||||
anyhow = { version = "1", optional = true }
|
anyhow = { version = "1", optional = true }
|
||||||
serde = { version = "1", features = ["derive"], optional = true }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
walkdir = "2"
|
walkdir = "2"
|
||||||
|
@ -3,6 +3,7 @@ unstable_features = true
|
|||||||
overflow_delimited_expr = true
|
overflow_delimited_expr = true
|
||||||
spaces_around_ranges = true
|
spaces_around_ranges = true
|
||||||
use_field_init_shorthand = true
|
use_field_init_shorthand = true
|
||||||
|
merge_derives = false
|
||||||
|
|
||||||
max_width = 90
|
max_width = 90
|
||||||
struct_lit_width = 40
|
struct_lit_width = 40
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
use std::fmt::{self, Debug, Display, Formatter};
|
use std::fmt::{self, Debug, Display, Formatter};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A color in a dynamic format.
|
/// A color in a dynamic format.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Color {
|
pub enum Color {
|
||||||
/// An 8-bit RGBA color: `#423abaff`.
|
/// An 8-bit RGBA color: `#423abaff`.
|
||||||
Rgba(RgbaColor),
|
Rgba(RgbaColor),
|
||||||
@ -27,7 +29,7 @@ impl Debug for Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An 8-bit RGBA color: `#423abaff`.
|
/// An 8-bit RGBA color: `#423abaff`.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct RgbaColor {
|
pub struct RgbaColor {
|
||||||
/// Red channel.
|
/// Red channel.
|
||||||
pub r: u8,
|
pub r: u8,
|
||||||
|
11
src/diag.rs
11
src/diag.rs
@ -5,10 +5,12 @@
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::syntax::Span;
|
use crate::syntax::Span;
|
||||||
|
|
||||||
/// The result of some pass: Some output `T` and diagnostics.
|
/// The result of some pass: Some output `T` and diagnostics.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Pass<T> {
|
pub struct Pass<T> {
|
||||||
/// The output of this compilation pass.
|
/// The output of this compilation pass.
|
||||||
pub output: T,
|
pub output: T,
|
||||||
@ -31,8 +33,7 @@ impl<T> Pass<T> {
|
|||||||
pub type DiagSet = BTreeSet<Diag>;
|
pub type DiagSet = BTreeSet<Diag>;
|
||||||
|
|
||||||
/// A diagnostic with severity level and message.
|
/// A diagnostic with severity level and message.
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
|
||||||
pub struct Diag {
|
pub struct Diag {
|
||||||
/// The source code location.
|
/// The source code location.
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
@ -61,8 +62,8 @@ impl Display for Diag {
|
|||||||
|
|
||||||
/// How severe / important a diagnostic is.
|
/// How severe / important a diagnostic is.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub enum Level {
|
pub enum Level {
|
||||||
Warning,
|
Warning,
|
||||||
Error,
|
Error,
|
||||||
|
@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
|
|||||||
use fontdock::{FaceId, FontSource};
|
use fontdock::{FaceId, FontSource};
|
||||||
use image::io::Reader as ImageReader;
|
use image::io::Reader as ImageReader;
|
||||||
use image::{DynamicImage, GenericImageView, ImageFormat};
|
use image::{DynamicImage, GenericImageView, ImageFormat};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "fs")]
|
#[cfg(feature = "fs")]
|
||||||
use fontdock::{FsIndex, FsSource};
|
use fontdock::{FsIndex, FsSource};
|
||||||
@ -72,6 +73,7 @@ pub struct ResourceLoader {
|
|||||||
|
|
||||||
/// A unique identifier for a resource.
|
/// A unique identifier for a resource.
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct ResourceId(usize);
|
pub struct ResourceId(usize);
|
||||||
|
|
||||||
impl ResourceLoader {
|
impl ResourceLoader {
|
||||||
|
@ -10,7 +10,7 @@ use super::Value;
|
|||||||
pub type Slot = Rc<RefCell<Value>>;
|
pub type Slot = Rc<RefCell<Value>>;
|
||||||
|
|
||||||
/// A stack of scopes.
|
/// A stack of scopes.
|
||||||
#[derive(Debug, Default, Clone, PartialEq)]
|
#[derive(Default, Debug, Clone, PartialEq)]
|
||||||
pub struct Scopes<'a> {
|
pub struct Scopes<'a> {
|
||||||
/// The active scope.
|
/// The active scope.
|
||||||
pub top: Scope,
|
pub top: Scope,
|
||||||
|
@ -69,7 +69,7 @@ impl Display for Angle {
|
|||||||
impl Debug for Angle {
|
impl Debug for Angle {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
let unit = AngularUnit::Deg;
|
let unit = AngularUnit::Deg;
|
||||||
write!(f, "{:?}{:?}", self.to_unit(unit), unit)
|
write!(f, "{}{}", self.to_unit(unit), unit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ impl Sum for Angle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Different units of angular measurement.
|
/// Different units of angular measurement.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub enum AngularUnit {
|
pub enum AngularUnit {
|
||||||
/// Radians.
|
/// Radians.
|
||||||
Rad,
|
Rad,
|
||||||
@ -161,12 +161,6 @@ impl Display for AngularUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for AngularUnit {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
Display::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// An absolute length.
|
/// An absolute length.
|
||||||
#[derive(Default, Copy, Clone, PartialEq, PartialOrd)]
|
#[derive(Default, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
pub struct Length {
|
pub struct Length {
|
||||||
/// The length in raw units.
|
/// The length in raw units.
|
||||||
raw: f64,
|
raw: f64,
|
||||||
@ -192,7 +195,7 @@ impl Sum for Length {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Different units of length measurement.
|
/// Different units of length measurement.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub enum LengthUnit {
|
pub enum LengthUnit {
|
||||||
/// Points.
|
/// Points.
|
||||||
Pt,
|
Pt,
|
||||||
@ -227,12 +230,6 @@ impl Display for LengthUnit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for LengthUnit {
|
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
|
||||||
Display::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A bezier path.
|
/// A bezier path.
|
||||||
#[derive(Default, Debug, Clone, PartialEq)]
|
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(transparent)]
|
||||||
pub struct Path(pub Vec<PathElement>);
|
pub struct Path(pub Vec<PathElement>);
|
||||||
|
|
||||||
/// An element in a bezier path.
|
/// An element in a bezier path.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum PathElement {
|
pub enum PathElement {
|
||||||
MoveTo(Point),
|
MoveTo(Point),
|
||||||
LineTo(Point),
|
LineTo(Point),
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A point in 2D.
|
/// A point in 2D.
|
||||||
#[derive(Default, Copy, Clone, PartialEq)]
|
#[derive(Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
/// The x coordinate.
|
/// The x coordinate.
|
||||||
pub x: Length,
|
pub x: Length,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A size in 2D.
|
/// A size in 2D.
|
||||||
#[derive(Default, Copy, Clone, PartialEq)]
|
#[derive(Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Size {
|
pub struct Size {
|
||||||
/// The width.
|
/// The width.
|
||||||
pub width: Length,
|
pub width: Length,
|
||||||
|
@ -12,7 +12,7 @@ pub struct BackgroundNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The kind of shape to use as a background.
|
/// The kind of shape to use as a background.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub enum BackgroundShape {
|
pub enum BackgroundShape {
|
||||||
Rect,
|
Rect,
|
||||||
Ellipse,
|
Ellipse,
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
use fontdock::FaceId;
|
use fontdock::FaceId;
|
||||||
use ttf_parser::GlyphId;
|
|
||||||
|
|
||||||
use crate::color::Color;
|
use crate::color::Color;
|
||||||
use crate::env::ResourceId;
|
use crate::env::ResourceId;
|
||||||
use crate::geom::{Length, Path, Point, Size};
|
use crate::geom::{Length, Path, Point, Size};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// A finished layout with elements at fixed positions.
|
/// A finished layout with elements at fixed positions.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
/// The size of the frame.
|
/// The size of the frame.
|
||||||
pub size: Size,
|
pub size: Size,
|
||||||
@ -37,7 +38,7 @@ impl Frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The building block frames are composed of.
|
/// The building block frames are composed of.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Element {
|
pub enum Element {
|
||||||
/// Shaped text.
|
/// Shaped text.
|
||||||
Text(Text),
|
Text(Text),
|
||||||
@ -48,7 +49,7 @@ pub enum Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A run of shaped text.
|
/// A run of shaped text.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Text {
|
pub struct Text {
|
||||||
/// The font face the glyphs are contained in.
|
/// The font face the glyphs are contained in.
|
||||||
pub face_id: FaceId,
|
pub face_id: FaceId,
|
||||||
@ -61,10 +62,10 @@ pub struct Text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A glyph in a run of shaped text.
|
/// A glyph in a run of shaped text.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Glyph {
|
pub struct Glyph {
|
||||||
/// The glyph's ID in the face.
|
/// The glyph's ID in the face.
|
||||||
pub id: GlyphId,
|
pub id: u16,
|
||||||
/// The advance width of the glyph.
|
/// The advance width of the glyph.
|
||||||
pub x_advance: Length,
|
pub x_advance: Length,
|
||||||
/// The horizontal offset of the glyph.
|
/// The horizontal offset of the glyph.
|
||||||
@ -76,7 +77,7 @@ impl Text {
|
|||||||
pub fn encode_glyphs_be(&self) -> Vec<u8> {
|
pub fn encode_glyphs_be(&self) -> Vec<u8> {
|
||||||
let mut bytes = Vec::with_capacity(2 * self.glyphs.len());
|
let mut bytes = Vec::with_capacity(2 * self.glyphs.len());
|
||||||
for glyph in &self.glyphs {
|
for glyph in &self.glyphs {
|
||||||
let id = glyph.id.0;
|
let id = glyph.id;
|
||||||
bytes.push((id >> 8) as u8);
|
bytes.push((id >> 8) as u8);
|
||||||
bytes.push((id & 0xff) as u8);
|
bytes.push((id & 0xff) as u8);
|
||||||
}
|
}
|
||||||
@ -85,7 +86,7 @@ impl Text {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A shape with some kind of fill.
|
/// A shape with some kind of fill.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Geometry {
|
pub struct Geometry {
|
||||||
/// The shape to draw.
|
/// The shape to draw.
|
||||||
pub shape: Shape,
|
pub shape: Shape,
|
||||||
@ -98,7 +99,7 @@ pub struct Geometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Some shape.
|
/// Some shape.
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Shape {
|
pub enum Shape {
|
||||||
/// A rectangle with its origin in the topleft corner.
|
/// A rectangle with its origin in the topleft corner.
|
||||||
Rect(Size),
|
Rect(Size),
|
||||||
@ -109,7 +110,7 @@ pub enum Shape {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The kind of graphic fill to be applied to a [`Shape`].
|
/// The kind of graphic fill to be applied to a [`Shape`].
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum Fill {
|
pub enum Fill {
|
||||||
/// The fill is a color.
|
/// The fill is a color.
|
||||||
Color(Color),
|
Color(Color),
|
||||||
@ -118,7 +119,7 @@ pub enum Fill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An image element.
|
/// An image element.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
/// The image resource.
|
/// The image resource.
|
||||||
pub res: ResourceId,
|
pub res: ResourceId,
|
||||||
|
@ -18,6 +18,7 @@ use crate::util::SliceExt;
|
|||||||
/// This type contains owned or borrowed shaped text runs, which can be
|
/// This type contains owned or borrowed shaped text runs, which can be
|
||||||
/// measured, used to reshape substrings more quickly and converted into a
|
/// measured, used to reshape substrings more quickly and converted into a
|
||||||
/// frame.
|
/// frame.
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ShapedText<'a> {
|
pub struct ShapedText<'a> {
|
||||||
/// The text that was shaped.
|
/// The text that was shaped.
|
||||||
pub text: &'a str,
|
pub text: &'a str,
|
||||||
@ -53,6 +54,7 @@ pub struct ShapedGlyph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A visual side.
|
/// A visual side.
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
enum Side {
|
enum Side {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
@ -77,7 +79,11 @@ impl<'a> ShapedText<'a> {
|
|||||||
for glyph in group {
|
for glyph in group {
|
||||||
let x_advance = face.convert(glyph.x_advance).scale(self.props.size);
|
let x_advance = face.convert(glyph.x_advance).scale(self.props.size);
|
||||||
let x_offset = face.convert(glyph.x_offset).scale(self.props.size);
|
let x_offset = face.convert(glyph.x_offset).scale(self.props.size);
|
||||||
text.glyphs.push(Glyph { id: glyph.glyph_id, x_advance, x_offset });
|
text.glyphs.push(Glyph {
|
||||||
|
id: glyph.glyph_id.0,
|
||||||
|
x_advance,
|
||||||
|
x_offset,
|
||||||
|
});
|
||||||
offset += x_advance;
|
offset += x_advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,15 +37,15 @@ impl Node {
|
|||||||
/// Desugar markup into a function call.
|
/// Desugar markup into a function call.
|
||||||
pub fn desugar(&self) -> Option<CallExpr> {
|
pub fn desugar(&self) -> Option<CallExpr> {
|
||||||
match *self {
|
match *self {
|
||||||
Node::Text(_) => None,
|
Self::Text(_) => None,
|
||||||
Node::Space => None,
|
Self::Space => None,
|
||||||
Node::Linebreak(span) => Some(call(span, Self::LINEBREAK)),
|
Self::Linebreak(span) => Some(call(span, Self::LINEBREAK)),
|
||||||
Node::Parbreak(span) => Some(call(span, Self::PARBREAK)),
|
Self::Parbreak(span) => Some(call(span, Self::PARBREAK)),
|
||||||
Node::Strong(span) => Some(call(span, Self::STRONG)),
|
Self::Strong(span) => Some(call(span, Self::STRONG)),
|
||||||
Node::Emph(span) => Some(call(span, Self::EMPH)),
|
Self::Emph(span) => Some(call(span, Self::EMPH)),
|
||||||
Self::Heading(ref heading) => Some(heading.desugar()),
|
Self::Heading(ref heading) => Some(heading.desugar()),
|
||||||
Self::Raw(ref raw) => Some(raw.desugar()),
|
Self::Raw(ref raw) => Some(raw.desugar()),
|
||||||
Node::Expr(_) => None,
|
Self::Expr(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,15 @@ use std::cell::Cell;
|
|||||||
use std::fmt::{self, Debug, Display, Formatter};
|
use std::fmt::{self, Debug, Display, Formatter};
|
||||||
use std::ops::{Add, Range};
|
use std::ops::{Add, Range};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static CMP_SPANS: Cell<bool> = Cell::new(true);
|
static CMP_SPANS: Cell<bool> = Cell::new(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A value with the span it corresponds to in the source code.
|
/// A value with the span it corresponds to in the source code.
|
||||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct Spanned<T> {
|
pub struct Spanned<T> {
|
||||||
/// The spanned value.
|
/// The spanned value.
|
||||||
pub v: T,
|
pub v: T,
|
||||||
@ -53,8 +55,7 @@ impl<T: Debug> Debug for Spanned<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Bounds of a slice of source code.
|
/// Bounds of a slice of source code.
|
||||||
#[derive(Copy, Clone, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
|
||||||
pub struct Span {
|
pub struct Span {
|
||||||
/// The inclusive start position.
|
/// The inclusive start position.
|
||||||
pub start: Pos,
|
pub start: Pos,
|
||||||
@ -158,8 +159,7 @@ impl Debug for Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A byte position in source code.
|
/// A byte position in source code.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
|
||||||
pub struct Pos(pub u32);
|
pub struct Pos(pub u32);
|
||||||
|
|
||||||
impl Pos {
|
impl Pos {
|
||||||
@ -208,8 +208,7 @@ impl Debug for Pos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A one-indexed line-column position in source code.
|
/// A one-indexed line-column position in source code.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
|
|
||||||
pub struct Location {
|
pub struct Location {
|
||||||
/// The one-indexed line.
|
/// The one-indexed line.
|
||||||
pub line: u32,
|
pub line: u32,
|
||||||
|
@ -11,7 +11,7 @@ use tiny_skia::{
|
|||||||
Color, ColorU8, FillRule, FilterQuality, Paint, Pattern, Pixmap, Rect, SpreadMode,
|
Color, ColorU8, FillRule, FilterQuality, Paint, Pattern, Pixmap, Rect, SpreadMode,
|
||||||
Transform,
|
Transform,
|
||||||
};
|
};
|
||||||
use ttf_parser::OutlineBuilder;
|
use ttf_parser::{GlyphId, OutlineBuilder};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
use typst::color;
|
use typst::color;
|
||||||
@ -425,7 +425,7 @@ fn draw_text(canvas: &mut Pixmap, env: &Env, ts: Transform, shaped: &Text) {
|
|||||||
|
|
||||||
// Try drawing SVG if present.
|
// Try drawing SVG if present.
|
||||||
if let Some(tree) = ttf
|
if let Some(tree) = ttf
|
||||||
.glyph_svg_image(glyph.id)
|
.glyph_svg_image(GlyphId(glyph.id))
|
||||||
.and_then(|data| std::str::from_utf8(data).ok())
|
.and_then(|data| std::str::from_utf8(data).ok())
|
||||||
.map(|svg| {
|
.map(|svg| {
|
||||||
let viewbox = format!("viewBox=\"0 0 {0} {0}\" xmlns", units_per_em);
|
let viewbox = format!("viewBox=\"0 0 {0} {0}\" xmlns", units_per_em);
|
||||||
@ -448,7 +448,7 @@ fn draw_text(canvas: &mut Pixmap, env: &Env, ts: Transform, shaped: &Text) {
|
|||||||
} else {
|
} else {
|
||||||
// Otherwise, draw normal outline.
|
// Otherwise, draw normal outline.
|
||||||
let mut builder = WrappedPathBuilder(tiny_skia::PathBuilder::new());
|
let mut builder = WrappedPathBuilder(tiny_skia::PathBuilder::new());
|
||||||
if ttf.outline_glyph(glyph.id, &mut builder).is_some() {
|
if ttf.outline_glyph(GlyphId(glyph.id), &mut builder).is_some() {
|
||||||
let path = builder.0.finish().unwrap();
|
let path = builder.0.finish().unwrap();
|
||||||
let ts = ts.pre_scale(s, -s);
|
let ts = ts.pre_scale(s, -s);
|
||||||
let mut paint = convert_typst_fill(shaped.color);
|
let mut paint = convert_typst_fill(shaped.color);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user