Detailed changes
@@ -478,6 +478,10 @@ impl Pixels {
Self(self.0.round())
}
+ pub fn floor(&self) -> Self {
+ Self(self.0.floor())
+ }
+
pub fn to_device_pixels(&self, scale: f32) -> DevicePixels {
DevicePixels((self.0 * scale).ceil() as u32)
}
@@ -10,7 +10,7 @@ pub type StackingOrder = SmallVec<[u32; 16]>;
#[derive(Debug)]
pub struct Scene {
- scale_factor: f32,
+ pub(crate) scale_factor: f32,
pub(crate) layers: BTreeMap<StackingOrder, SceneLayer>,
}
@@ -29,8 +29,8 @@ impl Scene {
}
}
- pub fn insert(&mut self, order: StackingOrder, primitive: impl Into<Primitive>) {
- let layer = self.layers.entry(order).or_default();
+ pub fn insert(&mut self, stacking_order: StackingOrder, primitive: impl Into<Primitive>) {
+ let layer = self.layers.entry(stacking_order).or_default();
let primitive = primitive.into();
match primitive {
@@ -1,10 +1,12 @@
use crate::{
- black, point, px, Bounds, FontId, Hsla, Layout, Pixels, Point, RasterizedGlyphId, RunStyle,
- ShapedBoundary, ShapedLine, ShapedRun, UnderlineStyle, WindowContext,
+ black, point, px, Bounds, FontId, Hsla, Layout, MonochromeSprite, Pixels, Point,
+ RasterizedGlyphId, RunStyle, ShapedBoundary, ShapedLine, ShapedRun, UnderlineStyle,
+ WindowContext,
};
use anyhow::Result;
use smallvec::SmallVec;
use std::sync::Arc;
+use util::ResultExt;
#[derive(Default, Debug, Clone)]
pub struct Line {
@@ -174,7 +176,28 @@ impl Line {
// origin: glyph_origin,
// });
} else {
- todo!()
+ if let Some((tile, bounds)) = cx
+ .rasterize_glyph(
+ run.font_id,
+ glyph.id,
+ self.layout.font_size,
+ cx.scale_factor(),
+ glyph_origin,
+ )
+ .log_err()
+ {
+ let layer_id = cx.current_layer_id();
+ cx.scene().insert(
+ layer_id,
+ MonochromeSprite {
+ order: layout.order,
+ bounds,
+ color,
+ tile,
+ },
+ );
+ }
+
// cx.scene().insert(Symbol {
// order: layout.order,
// origin,
@@ -22,7 +22,7 @@ pub struct Window {
layout_engine: TaffyLayoutEngine,
pub(crate) root_view: Option<AnyView<()>>,
mouse_position: Point<Pixels>,
- current_stacking_order: StackingOrder,
+ current_layer_id: StackingOrder,
pub(crate) scene: Scene,
pub(crate) dirty: bool,
}
@@ -63,7 +63,7 @@ impl Window {
layout_engine: TaffyLayoutEngine::new(),
root_view: None,
mouse_position,
- current_stacking_order: SmallVec::new(),
+ current_layer_id: SmallVec::new(),
scene: Scene::new(scale_factor),
dirty: true,
}
@@ -122,6 +122,10 @@ impl<'a, 'w> WindowContext<'a, 'w> {
.map(Into::into)?)
}
+ pub fn scale_factor(&self) -> f32 {
+ self.window.scene.scale_factor
+ }
+
pub fn rem_size(&self) -> Pixels {
self.window.rem_size
}
@@ -135,14 +139,14 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
pub fn stack<R>(&mut self, order: u32, f: impl FnOnce(&mut Self) -> R) -> R {
- self.window.current_stacking_order.push(order);
+ self.window.current_layer_id.push(order);
let result = f(self);
- self.window.current_stacking_order.pop();
+ self.window.current_layer_id.pop();
result
}
- pub fn current_stack_order(&self) -> StackingOrder {
- self.window.current_stacking_order.clone()
+ pub fn current_layer_id(&self) -> StackingOrder {
+ self.window.current_layer_id.clone()
}
pub fn run_on_main<R>(
@@ -169,7 +173,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
font_size: Pixels,
scale_factor: f32,
target_position: Point<Pixels>,
- ) -> Result<(AtlasTile, Point<DevicePixels>)> {
+ ) -> Result<(AtlasTile, Bounds<Pixels>)> {
let target_position = target_position * scale_factor;
let subpixel_variant = Point {
x: (target_position.x.0.fract() * SUBPIXEL_VARIANTS as f32).floor() as u8,
@@ -192,7 +196,14 @@ impl<'a, 'w> WindowContext<'a, 'w> {
Ok((bounds.size, pixels))
})?;
- Ok((tile, offset))
+ // Align bounding box surrounding glyph to pixel grid
+ let mut origin = (target_position * scale_factor).map(|p| p.floor());
+ // Position glyph within bounding box
+ origin += offset.map(|o| px(u32::from(o) as f32));
+ let size = tile.bounds_in_atlas.size.map(|b| px(b.0 as f32));
+ let bounds = Bounds { origin, size };
+
+ Ok((tile, bounds))
}
pub(crate) fn draw(&mut self) -> Result<()> {