Skip to content

Commit

Permalink
Make frames serializable 📚
Browse files Browse the repository at this point in the history
This also makes serialization support non-optional since it's too much feature-management for too little benefit.
  • Loading branch information
laurmaedje committed Apr 21, 2021
1 parent df58a4d commit 7247894
Show file tree
Hide file tree
Showing 18 changed files with 71 additions and 61 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# General
.vscode
_things
desktop.ini

# Tests and benchmarks
tests/png
Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2018"
default = ["fs"]
fs = ["fontdock/fs"]
cli = ["fs", "anyhow"]
# serde = []

[workspace]
members = ["bench"]
Expand All @@ -22,7 +21,7 @@ debug = 0
opt-level = 2

[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"] }
miniz_oxide = "0.3"
pdf-writer = { path = "../pdf-writer" }
Expand All @@ -32,7 +31,7 @@ unicode-bidi = "0.3.5"
unicode-xid = "0.2"
xi-unicode = "0.3"
anyhow = { version = "1", optional = true }
serde = { version = "1", features = ["derive"], optional = true }
serde = { version = "1", features = ["derive"] }

[dev-dependencies]
walkdir = "2"
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ unstable_features = true
overflow_delimited_expr = true
spaces_around_ranges = true
use_field_init_shorthand = true
merge_derives = false

max_width = 90
struct_lit_width = 40
Expand Down
6 changes: 4 additions & 2 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
use std::fmt::{self, Debug, Display, Formatter};
use std::str::FromStr;

use serde::{Deserialize, Serialize};

/// A color in a dynamic format.
#[derive(Copy, Clone, Eq, PartialEq)]
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum Color {
/// An 8-bit RGBA color: `#423abaff`.
Rgba(RgbaColor),
Expand All @@ -27,7 +29,7 @@ impl Debug for Color {
}

/// An 8-bit RGBA color: `#423abaff`.
#[derive(Copy, Clone, Eq, PartialEq)]
#[derive(Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct RgbaColor {
/// Red channel.
pub r: u8,
Expand Down
11 changes: 6 additions & 5 deletions src/diag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
use std::collections::BTreeSet;
use std::fmt::{self, Display, Formatter};

use serde::{Deserialize, Serialize};

use crate::syntax::Span;

/// 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> {
/// The output of this compilation pass.
pub output: T,
Expand All @@ -31,8 +33,7 @@ impl<T> Pass<T> {
pub type DiagSet = BTreeSet<Diag>;

/// A diagnostic with severity level and message.
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct Diag {
/// The source code location.
pub span: Span,
Expand Down Expand Up @@ -61,8 +62,8 @@ impl Display for Diag {

/// How severe / important a diagnostic is.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Level {
Warning,
Error,
Expand Down
2 changes: 2 additions & 0 deletions src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::path::{Path, PathBuf};
use fontdock::{FaceId, FontSource};
use image::io::Reader as ImageReader;
use image::{DynamicImage, GenericImageView, ImageFormat};
use serde::{Deserialize, Serialize};

#[cfg(feature = "fs")]
use fontdock::{FsIndex, FsSource};
Expand Down Expand Up @@ -72,6 +73,7 @@ pub struct ResourceLoader {

/// A unique identifier for a resource.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
pub struct ResourceId(usize);

impl ResourceLoader {
Expand Down
2 changes: 1 addition & 1 deletion src/eval/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::Value;
pub type Slot = Rc<RefCell<Value>>;

/// A stack of scopes.
#[derive(Debug, Default, Clone, PartialEq)]
#[derive(Default, Debug, Clone, PartialEq)]
pub struct Scopes<'a> {
/// The active scope.
pub top: Scope,
Expand Down
10 changes: 2 additions & 8 deletions src/geom/angle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl Display for Angle {
impl Debug for Angle {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let unit = AngularUnit::Deg;
write!(f, "{:?}{:?}", self.to_unit(unit), unit)
write!(f, "{}{}", self.to_unit(unit), unit)
}
}

Expand Down Expand Up @@ -134,7 +134,7 @@ impl Sum for Angle {
}
}
/// Different units of angular measurement.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum AngularUnit {
/// Radians.
Rad,
Expand All @@ -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)]
mod tests {
use super::*;
Expand Down
13 changes: 5 additions & 8 deletions src/geom/length.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use super::*;

use serde::{Deserialize, Serialize};

/// An absolute length.
#[derive(Default, Copy, Clone, PartialEq, PartialOrd)]
#[derive(Default, Copy, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Length {
/// The length in raw units.
raw: f64,
Expand Down Expand Up @@ -192,7 +195,7 @@ impl Sum for Length {
}

/// Different units of length measurement.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub enum LengthUnit {
/// Points.
Pt,
Expand Down Expand Up @@ -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)]
mod tests {
use super::*;
Expand Down
7 changes: 5 additions & 2 deletions src/geom/path.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use super::*;

use serde::{Deserialize, Serialize};

/// A bezier path.
#[derive(Default, Debug, Clone, PartialEq)]
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Path(pub Vec<PathElement>);

/// An element in a bezier path.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PathElement {
MoveTo(Point),
LineTo(Point),
Expand Down
4 changes: 3 additions & 1 deletion src/geom/point.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::*;

use serde::{Deserialize, Serialize};

/// A point in 2D.
#[derive(Default, Copy, Clone, PartialEq)]
#[derive(Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub struct Point {
/// The x coordinate.
pub x: Length,
Expand Down
4 changes: 3 additions & 1 deletion src/geom/size.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use super::*;

use serde::{Deserialize, Serialize};

/// A size in 2D.
#[derive(Default, Copy, Clone, PartialEq)]
#[derive(Default, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub struct Size {
/// The width.
pub width: Length,
Expand Down
2 changes: 1 addition & 1 deletion src/layout/background.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct BackgroundNode {
}

/// The kind of shape to use as a background.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum BackgroundShape {
Rect,
Ellipse,
Expand Down
23 changes: 12 additions & 11 deletions src/layout/frame.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use fontdock::FaceId;
use ttf_parser::GlyphId;

use crate::color::Color;
use crate::env::ResourceId;
use crate::geom::{Length, Path, Point, Size};

use serde::{Deserialize, Serialize};

/// A finished layout with elements at fixed positions.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Frame {
/// The size of the frame.
pub size: Size,
Expand Down Expand Up @@ -37,7 +38,7 @@ impl Frame {
}

/// The building block frames are composed of.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Element {
/// Shaped text.
Text(Text),
Expand All @@ -48,7 +49,7 @@ pub enum Element {
}

/// A run of shaped text.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Text {
/// The font face the glyphs are contained in.
pub face_id: FaceId,
Expand All @@ -61,10 +62,10 @@ pub struct Text {
}

/// A glyph in a run of shaped text.
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub struct Glyph {
/// The glyph's ID in the face.
pub id: GlyphId,
pub id: u16,
/// The advance width of the glyph.
pub x_advance: Length,
/// The horizontal offset of the glyph.
Expand All @@ -76,7 +77,7 @@ impl Text {
pub fn encode_glyphs_be(&self) -> Vec<u8> {
let mut bytes = Vec::with_capacity(2 * self.glyphs.len());
for glyph in &self.glyphs {
let id = glyph.id.0;
let id = glyph.id;
bytes.push((id >> 8) as u8);
bytes.push((id & 0xff) as u8);
}
Expand All @@ -85,7 +86,7 @@ impl Text {
}

/// A shape with some kind of fill.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Geometry {
/// The shape to draw.
pub shape: Shape,
Expand All @@ -98,7 +99,7 @@ pub struct Geometry {
}

/// Some shape.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Shape {
/// A rectangle with its origin in the topleft corner.
Rect(Size),
Expand All @@ -109,7 +110,7 @@ pub enum 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 {
/// The fill is a color.
Color(Color),
Expand All @@ -118,7 +119,7 @@ pub enum Fill {
}

/// An image element.
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
pub struct Image {
/// The image resource.
pub res: ResourceId,
Expand Down
8 changes: 7 additions & 1 deletion src/layout/shaping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use crate::util::SliceExt;
/// This type contains owned or borrowed shaped text runs, which can be
/// measured, used to reshape substrings more quickly and converted into a
/// frame.
#[derive(Clone)]
pub struct ShapedText<'a> {
/// The text that was shaped.
pub text: &'a str,
Expand Down Expand Up @@ -53,6 +54,7 @@ pub struct ShapedGlyph {
}

/// A visual side.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
enum Side {
Left,
Right,
Expand All @@ -77,7 +79,11 @@ impl<'a> ShapedText<'a> {
for glyph in group {
let x_advance = face.convert(glyph.x_advance).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;
}

Expand Down
14 changes: 7 additions & 7 deletions src/syntax/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ impl Node {
/// Desugar markup into a function call.
pub fn desugar(&self) -> Option<CallExpr> {
match *self {
Node::Text(_) => None,
Node::Space => None,
Node::Linebreak(span) => Some(call(span, Self::LINEBREAK)),
Node::Parbreak(span) => Some(call(span, Self::PARBREAK)),
Node::Strong(span) => Some(call(span, Self::STRONG)),
Node::Emph(span) => Some(call(span, Self::EMPH)),
Self::Text(_) => None,
Self::Space => None,
Self::Linebreak(span) => Some(call(span, Self::LINEBREAK)),
Self::Parbreak(span) => Some(call(span, Self::PARBREAK)),
Self::Strong(span) => Some(call(span, Self::STRONG)),
Self::Emph(span) => Some(call(span, Self::EMPH)),
Self::Heading(ref heading) => Some(heading.desugar()),
Self::Raw(ref raw) => Some(raw.desugar()),
Node::Expr(_) => None,
Self::Expr(_) => None,
}
}
}
Expand Down
Loading

0 comments on commit 7247894

Please sign in to comment.