Skip to content

Commit

Permalink
Rounding text rendering coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
ecton committed Dec 5, 2024
1 parent 1a96d37 commit 8c00d66
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 22 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
properly sets the line height based.
- `MeasuredText`'s metrics are now more accurate. The wrong value for the
baseline was being used, leading to slightly incorrect measurements.
- Drawing text now rounds the line origin and translations to the nearest whole
pixel to avoid subpixel rendering of text. While this removes a level of
fidelity that was possible, it seems like the most commonly desired behavior.
If subpixel text rendering is desired, please open an issue as this could be
something that could be re-enabled on `Text`.

## v0.11.0 (2024-09-14)

Expand Down
39 changes: 18 additions & 21 deletions src/drawing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ mod text {
use std::sync::Arc;

use figures::units::{Px, UPx};
use figures::{Fraction, Round, ScreenScale, ScreenUnit, UnscaledUnit};
use figures::{Round, ScreenScale, ScreenUnit, UnscaledUnit};
use intentional::Assert;

use super::{
Expand Down Expand Up @@ -454,21 +454,22 @@ mod text {
text: impl Into<Drawable<&'a MeasuredText<Unit>, Unit>>,
origin: TextOrigin<Unit>,
) where
Unit: ScreenUnit,
Unit: ScreenUnit + Round,
{
let text = text.into();
let scaling_factor = self.effective_scale;
let translation = text.translation;
let translation = text.translation.into_px(self.effective_scale);
let origin = match origin {
TextOrigin::TopLeft => Point::default(),
TextOrigin::Center => {
(Point::from(text.source.size).into_px(scaling_factor) / 2).round()
}
TextOrigin::FirstBaseline => {
Point::new(Px::ZERO, text.source.line_height.into_px(scaling_factor))
Point::from(text.source.size).into_px(self.effective_scale) / 2
}
TextOrigin::Custom(offset) => offset.into_px(scaling_factor),
};
TextOrigin::FirstBaseline => Point::new(
Px::ZERO,
text.source.line_height.into_px(self.effective_scale),
),
TextOrigin::Custom(offset) => offset.into_px(self.effective_scale),
}
.round();
for glyph in &text.source.glyphs {
let GlyphBlit::Visible {
blit,
Expand All @@ -488,7 +489,6 @@ mod text {
cached,
self.clip_index,
self.clip.current.origin,
scaling_factor,
self.graphics,
&mut self.data.vertices,
&mut self.data.indices,
Expand All @@ -511,7 +511,7 @@ mod text {
) where
Unit: ScreenUnit,
{
let scaling_factor = self.effective_scale;
let translation = translation.into_px(self.effective_scale);
map_each_glyph(
buffer,
default_color,
Expand All @@ -535,7 +535,6 @@ mod text {
&cached,
self.clip_index,
self.graphics.clip.current.origin,
scaling_factor,
&ProtoGraphics::new(
self.graphics.device,
self.graphics.queue,
Expand All @@ -553,26 +552,24 @@ mod text {
}

#[allow(clippy::too_many_arguments)]
fn render_one_glyph<Unit>(
translation: Point<Unit>,
fn render_one_glyph(
translation: Point<Px>,
rotation: Option<Angle>,
scale: Option<Point<f32>>,
opacity: Option<f32>,
blit: TextureBlit<Px>,
cached: &CachedGlyphHandle,
clip_index: u32,
clip_origin: Point<UPx>,
dpi_scale: Fraction,
graphics: &impl KludgineGraphics,
vertices: &mut VertexCollection<i32>,
indices: &mut Vec<u32>,
textures: &mut HashMap<TextureId, Arc<wgpu::BindGroup>, DefaultHasher>,
commands: &mut Vec<Command>,
) where
Unit: ScreenUnit,
{
let translation =
(clip_origin.into_signed() + translation.into_px(dpi_scale)).map(Px::into_unscaled);
) {
let translation = (clip_origin.into_signed() + translation)
.round()
.map(Px::into_unscaled);
let corners: [u32; 4] = array::from_fn(|index| {
let vertex = &blit.verticies[index];
vertices.get_or_insert(Vertex {
Expand Down
2 changes: 1 addition & 1 deletion src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ pub(crate) fn map_each_glyph(

let buffer = buffer.unwrap_or_else(|| kludgine.text.scratch.as_ref().expect("no buffer"));
for run in buffer.layout_runs() {
let run_origin = Point::new(Px::ZERO, Px::from(run.line_y)) - relative_to;
let run_origin = (Point::new(Px::ZERO, Px::from(run.line_y)) - relative_to).round();
for glyph in run.glyphs {
let physical =
glyph.physical((run_origin.x.into_float(), run_origin.y.into_float()), 1.);
Expand Down

0 comments on commit 8c00d66

Please sign in to comment.