Skip to content

Commit

Permalink
Fix font rendering scaling and spacing
Browse files Browse the repository at this point in the history
  • Loading branch information
fredizzimo committed Apr 23, 2023
1 parent 322a90c commit 428f16d
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 28 deletions.
20 changes: 14 additions & 6 deletions src/renderer/fonts/atlas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl TextureFormat {

pub struct AtlasCoordinate {
pub rect: Rect<f32>,
pub dst_rect: Rect<f32>,
pub texture_id: u32,
}

Expand Down Expand Up @@ -129,12 +130,12 @@ impl AtlasTexture {
self.current_pos.y += self.current_row_height;
self.current_row_height = 0;
};
let mut rect = Rect::new(self.current_pos, Size2D::new(width - 1, height - 1)).to_f32();
rect = rect.translate(Vector2D::new(0.5, 0.5));
rect = rect.scale(
1.0 / self.texture_size.width as f32,
1.0 / self.texture_size.height as f32,
);
let rect = Rect::new(self.current_pos, Size2D::new(width, height))
.to_f32()
.scale(
1.0 / self.texture_size.width as f32,
1.0 / self.texture_size.height as f32,
);

let row_start_byte = (self.current_pos.x * self.bytes_per_pixel) as usize;
let row_end_byte = ((self.current_pos.x + width) * self.bytes_per_pixel) as usize;
Expand All @@ -150,8 +151,15 @@ impl AtlasTexture {
self.current_row_height = self.current_row_height.max(height);
self.dirty = true;

// TODO: Take the scale into account, check if it applies to bot the position and size, or just the size
let dst_rect = Rect::new(
Point2D::new(glyph.left, -glyph.top),
Size2D::new(glyph.width as f32, glyph.height as f32),
);

AtlasCoordinate {
rect,
dst_rect,
texture_id: 0,
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/fonts/caching_shaper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,9 @@ impl CachingShaper {
self.metrics().underline_offset as u64
}

pub fn y_adjustment(&mut self) -> u64 {
pub fn y_adjustment(&mut self) -> f32 {
let metrics = self.metrics();
(metrics.ascent + metrics.leading).ceil() as u64
metrics.ascent + metrics.leading
}

fn build_clusters(
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/grid_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ impl GridRenderer {
tracy_zone!("draw_foreground");
let debug = SETTINGS.get::<RendererSettings>().debug_renderer;
let (x, y) = grid_position * self.font_dimensions;
let (x, y) = (x as f32, y as f32);
let width = cell_width * self.font_dimensions.width;

let style = style.as_ref().unwrap_or(&self.default_style);
Expand Down Expand Up @@ -209,9 +210,9 @@ impl GridRenderer {
let trimmed = text.trim_start();
let leading_spaces = text.len() - trimmed.len();
let trimmed = trimmed.trim_end();
let x_adjustment = leading_spaces as u64 * self.font_dimensions.width;
let x_adjustment = (leading_spaces as u64 * self.font_dimensions.width) as f32;

let base_position = Vector2D::new((x + x_adjustment) as f32, (y + y_adjustment) as f32);
let base_position = Vector2D::new(x + x_adjustment, y + y_adjustment);

if !trimmed.is_empty() {
for glyph in self
Expand Down
6 changes: 3 additions & 3 deletions src/renderer/pipeline/glyph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ use wgpu::*;
#[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)]
pub struct GlyphFragment {
pub position: [f32; 2],
pub width: f32,
pub rect: [f32; 4],
pub color: [f32; 4],
pub uv: [f32; 4],
pub texture: u32,
}

impl GlyphFragment {
const ATTRIBS: [VertexAttribute; 5] = vertex_attr_array![1 => Float32x2, 2 => Float32, 3 => Float32x4, 4 => Float32x4, 5 => Uint32];
const ATTRIBS: [VertexAttribute; 4] =
vertex_attr_array![1 => Float32x4, 2 => Float32x4, 3 => Float32x4, 4 => Uint32];

fn desc<'a>() -> VertexBufferLayout<'a> {
VertexBufferLayout {
Expand Down
14 changes: 8 additions & 6 deletions src/renderer/rendered_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use skia_safe::{
};
*/
use csscolorparser::Color;
use euclid::default::{Point2D, Rect, Size2D};
use euclid::default::{Point2D, Rect, Size2D, Vector2D};

use super::fonts::caching_shaper::CachingShaper;
use crate::{
Expand Down Expand Up @@ -315,12 +315,14 @@ impl RenderedWindow {
let new_fragments = lines.iter().flat_map(|(y, line)| {
line.glyphs.iter().filter_map(|placeholder| {
if let Some(coord) = shaper.get_glyph_coordinate(placeholder.id) {
let translate = Vector2D::new(
pixel_region.min_x() + placeholder.position[0],
*y + pixel_region.min_y() + placeholder.position[1],
);
let rect = coord.dst_rect.translate(translate);

Some(GlyphFragment {
position: [
placeholder.position[0] + pixel_region.min_x(),
*y + pixel_region.min_y(),
],
width: placeholder.width,
rect: [rect.min_x(), rect.min_y(), rect.width(), rect.height()],
color: placeholder.color,
texture: coord.texture_id,
uv: [
Expand Down
19 changes: 10 additions & 9 deletions src/renderer/shaders/glyph.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ struct VertexInput {
@location(0) position: vec2<f32>,
};
struct InstanceInput {
@location(1) position: vec2<f32>,
@location(2) width: f32,
@location(3) color: vec4<f32>,
@location(4) uv: vec4<f32>,
@location(5) texture: u32,
@location(1) rect: vec4<f32>,
@location(2) color: vec4<f32>,
@location(3) uv: vec4<f32>,
@location(4) texture: u32,
};

struct VertexOutput {
Expand All @@ -36,16 +35,18 @@ fn vs_main(
instance: InstanceInput,
) -> VertexOutput {
var out: VertexOutput;
let box = vec2<f32>(model.position.x * instance.width, model.position.y * camera.row_height) + instance.position;

let position = vec4<f32>(box, 0.0, 1.0);
let instance_origin = instance.rect.xy;
let instance_size = instance.rect.zw;
let pos = instance_origin + instance_size * model.position;
out.clip_position = camera.view_proj * vec4(pos, 0.0, 1.0);

let uv_origin = instance.uv.xy;
let uv_size = instance.uv.zw;
out.uv = uv_origin + uv_size * model.position;

out.clip_position = camera.view_proj * position;
out.color = instance.color;
out.uv = uv_origin + uv_size * model.position;

return out;
}

Expand Down

0 comments on commit 428f16d

Please sign in to comment.