summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/model.rs59
-rw-r--r--src/layout/text.rs25
2 files changed, 59 insertions, 25 deletions
diff --git a/src/layout/model.rs b/src/layout/model.rs
index 343205ec..7e899f2e 100644
--- a/src/layout/model.rs
+++ b/src/layout/model.rs
@@ -5,12 +5,13 @@
use std::future::Future;
use std::pin::Pin;
use smallvec::smallvec;
+use toddle::query::FontStyle;
use crate::{Pass, Feedback};
use crate::GlobalFontLoader;
use crate::style::{LayoutStyle, PageStyle, TextStyle};
use crate::size::{Size, Size2D};
-use crate::syntax::{Model, SyntaxModel, Node};
+use crate::syntax::{Model, SyntaxModel, Node, Decoration};
use crate::syntax::span::{Span, Spanned};
use super::line::{LineLayouter, LineContext};
use super::text::{layout_text, TextContext};
@@ -47,7 +48,7 @@ pub struct LayoutContext<'a> {
/// Whether the layout that is to be created will be nested in a parent
/// container.
pub nested: bool,
- /// Whether to debug render a box around the layout.
+ /// Whether to render debug boxs around layouts if `nested` is true.
pub debug: bool,
}
@@ -118,7 +119,7 @@ impl<'a> ModelLayouter<'a> {
axes: ctx.axes,
alignment: ctx.alignment,
repeat: ctx.repeat,
- debug: ctx.debug,
+ debug: ctx.debug && ctx.nested,
line_spacing: ctx.style.text.line_spacing(),
}),
style: ctx.style.clone(),
@@ -137,7 +138,6 @@ impl<'a> ModelLayouter<'a> {
style: &self.style,
spaces: self.layouter.remaining(),
nested: true,
- debug: false,
.. self.ctx
}).await;
@@ -157,29 +157,48 @@ impl<'a> ModelLayouter<'a> {
) -> DynFuture<'r, ()> { Box::pin(async move {
use Node::*;
- for node in &model.nodes {
- match &node.v {
+ for Spanned { v: node, span } in &model.nodes {
+ let decorate = |this: &mut ModelLayouter, deco| {
+ this.feedback.decos.push(Spanned::new(deco, *span));
+ };
+
+ match node {
Space => self.layout_space(),
Newline => self.layout_paragraph(),
- Text(text) => self.layout_text(text).await,
- ToggleItalic => self.style.text.variant.style.toggle(),
+ Text(text) => {
+ if self.style.text.variant.style == FontStyle::Italic {
+ decorate(self, Decoration::Italic);
+ }
+
+ if self.style.text.bolder {
+ decorate(self, Decoration::Bold);
+ }
+
+ if self.style.text.monospace {
+ decorate(self, Decoration::Monospace);
+ }
+
+ self.layout_text(text).await;
+ }
+
+ ToggleItalic => {
+ self.style.text.variant.style.toggle();
+ decorate(self, Decoration::Italic);
+ }
+
ToggleBolder => {
- let fac = if self.style.text.bolder { -1 } else { 1 };
- self.style.text.variant.weight.0 += 300 * fac;
self.style.text.bolder = !self.style.text.bolder;
+ decorate(self, Decoration::Bold);
}
+
ToggleMonospace => {
- let list = &mut self.style.text.fallback.list;
- match list.get(0).map(|s| s.as_str()) {
- Some("monospace") => { list.remove(0); },
- _ => list.insert(0, "monospace".to_string()),
- }
- self.style.text.fallback.flatten();
+ self.style.text.monospace = !self.style.text.monospace;
+ decorate(self, Decoration::Monospace);
}
Node::Model(model) => {
- self.layout(Spanned::new(model.as_ref(), node.span)).await;
+ self.layout(Spanned::new(model.as_ref(), *span)).await;
}
}
}
@@ -195,7 +214,7 @@ impl<'a> ModelLayouter<'a> {
fn execute_command<'r>(
&'r mut self,
command: Command<'r>,
- span: Span,
+ model_span: Span,
) -> DynFuture<'r, ()> { Box::pin(async move {
use Command::*;
@@ -213,7 +232,7 @@ impl<'a> ModelLayouter<'a> {
BreakParagraph => self.layout_paragraph(),
BreakPage => {
if self.ctx.nested {
- self.feedback.errors.push(err!(span;
+ self.feedback.errors.push(err!(model_span;
"page break cannot be issued from nested context"));
} else {
self.layouter.finish_space(true)
@@ -226,7 +245,7 @@ impl<'a> ModelLayouter<'a> {
}
SetPageStyle(style) => {
if self.ctx.nested {
- self.feedback.errors.push(err!(span;
+ self.feedback.errors.push(err!(model_span;
"page style cannot be changed from nested context"));
} else {
self.style.page = style;
diff --git a/src/layout/text.rs b/src/layout/text.rs
index c6fa45d1..614d59fd 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -113,13 +113,28 @@ impl<'a> TextLayouter<'a> {
async fn select_font(&mut self, c: char) -> Option<(FontIndex, Size)> {
let mut loader = self.ctx.loader.borrow_mut();
- let query = FontQuery {
- fallback: &self.ctx.style.fallback,
- variant: self.ctx.style.variant,
- c,
+ let mut variant = self.ctx.style.variant;
+ if self.ctx.style.bolder {
+ variant.weight.0 += 300;
+ }
+
+ let queried = if self.ctx.style.monospace {
+ loader.get(FontQuery {
+ // FIXME: This is a hack.
+ fallback: std::iter::once("source code pro")
+ .chain(self.ctx.style.fallback.iter()),
+ variant,
+ c,
+ }).await
+ } else {
+ loader.get(FontQuery {
+ fallback: self.ctx.style.fallback.iter(),
+ variant,
+ c,
+ }).await
};
- if let Some((font, index)) = loader.get(query).await {
+ if let Some((font, index)) = queried {
// Determine the width of the char.
let header = font.read_table::<Header>().ok()?;
let font_unit_ratio = 1.0 / (header.units_per_em as f32);