More cleanup
This commit is contained in:
@@ -795,9 +795,7 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
|
||||
}
|
||||
}
|
||||
DisplayItem::Text(text) => {
|
||||
if (self.scale_factor - 1.0).abs() <= f32::EPSILON
|
||||
&& text.glyphs.iter().all(|glyph| glyph.cache_key.is_some())
|
||||
{
|
||||
if text.glyphs.iter().all(|glyph| glyph.cache_key.is_some()) {
|
||||
continue;
|
||||
}
|
||||
if let Some(uploaded) =
|
||||
@@ -1070,9 +1068,6 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
|
||||
logical_size: UiSize,
|
||||
perf: &mut AtlasTextPerfStats,
|
||||
) -> Option<UploadedAtlasText> {
|
||||
if (self.scale_factor - 1.0).abs() > f32::EPSILON {
|
||||
return None;
|
||||
}
|
||||
let mut vertices = Vec::new();
|
||||
let mut clip_stack = Vec::new();
|
||||
let mut active_clip = ActiveClip::default();
|
||||
@@ -1104,7 +1099,8 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
|
||||
if active_clip.rect_active && logical_clip_rect.is_none() {
|
||||
continue;
|
||||
}
|
||||
let clip_rect = logical_clip_rect.map(rect_to_pixel_rect);
|
||||
let clip_rect = logical_clip_rect
|
||||
.map(|rect| scale_rect_to_pixel_rect(rect, self.scale_factor));
|
||||
|
||||
// Only iterate glyphs whose lines fall within the clip rect.
|
||||
// For large text nodes (e.g. full Cargo.lock) this reduces
|
||||
@@ -1115,7 +1111,10 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
|
||||
perf.glyphs_clip_culled += (all_count - visible.len()) as u32;
|
||||
|
||||
for glyph in visible {
|
||||
let Some(cache_key) = glyph.cache_key else {
|
||||
let Some(cache_key) = glyph
|
||||
.cache_key
|
||||
.map(|cache_key| scale_glyph_cache_key(cache_key, self.scale_factor))
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let resolved_color = resolve_glyph_color(glyph.color, text.default_color);
|
||||
@@ -1124,9 +1123,12 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Glyph positions are LOCAL; add text.origin for absolute screen coords.
|
||||
let abs_x = (text.origin.x + glyph.position.x).round() as i32;
|
||||
let abs_y = (text.origin.y + glyph.position.y).round() as i32;
|
||||
// Atlas glyphs are rasterized in device pixels while scene geometry remains
|
||||
// logical. Build and clip in device space, then convert back for vertices.
|
||||
let abs_x =
|
||||
((text.origin.x + glyph.position.x) * self.scale_factor).round() as i32;
|
||||
let abs_y =
|
||||
((text.origin.y + glyph.position.y) * self.scale_factor).round() as i32;
|
||||
let glyph_rect = PixelRect {
|
||||
left: abs_x + atlas_glyph.placement_left,
|
||||
top: abs_y - atlas_glyph.placement_top,
|
||||
@@ -1142,6 +1144,7 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
|
||||
atlas_glyph.atlas_rect,
|
||||
clip_rect,
|
||||
logical_size,
|
||||
self.scale_factor,
|
||||
resolved_color,
|
||||
active_clip,
|
||||
);
|
||||
@@ -1872,6 +1875,7 @@ fn push_glyph_vertices(
|
||||
atlas_rect: AtlasRect,
|
||||
clip_rect: Option<PixelRect>,
|
||||
logical_size: UiSize,
|
||||
scale_factor: f32,
|
||||
color: Color,
|
||||
clip: ActiveClip,
|
||||
) {
|
||||
@@ -1879,10 +1883,15 @@ fn push_glyph_vertices(
|
||||
return;
|
||||
};
|
||||
|
||||
let left = to_ndc_x(dest_rect.left as f32, logical_size.width.max(1.0));
|
||||
let right = to_ndc_x(dest_rect.right as f32, logical_size.width.max(1.0));
|
||||
let top = to_ndc_y(dest_rect.top as f32, logical_size.height.max(1.0));
|
||||
let bottom = to_ndc_y(dest_rect.bottom as f32, logical_size.height.max(1.0));
|
||||
let scale_factor = scale_factor.max(1.0);
|
||||
let logical_left = dest_rect.left as f32 / scale_factor;
|
||||
let logical_top = dest_rect.top as f32 / scale_factor;
|
||||
let logical_right = dest_rect.right as f32 / scale_factor;
|
||||
let logical_bottom = dest_rect.bottom as f32 / scale_factor;
|
||||
let left = to_ndc_x(logical_left, logical_size.width.max(1.0));
|
||||
let right = to_ndc_x(logical_right, logical_size.width.max(1.0));
|
||||
let top = to_ndc_y(logical_top, logical_size.height.max(1.0));
|
||||
let bottom = to_ndc_y(logical_bottom, logical_size.height.max(1.0));
|
||||
|
||||
let color = color_to_f32(color);
|
||||
let clip_rect = clip_rect_array(clip);
|
||||
@@ -1890,7 +1899,7 @@ fn push_glyph_vertices(
|
||||
vertices.extend_from_slice(&[
|
||||
TextVertex {
|
||||
position: [left, top],
|
||||
world_position: [dest_rect.left as f32, dest_rect.top as f32],
|
||||
world_position: [logical_left, logical_top],
|
||||
uv: [uv_rect.0, uv_rect.1],
|
||||
color,
|
||||
clip_rect,
|
||||
@@ -1899,7 +1908,7 @@ fn push_glyph_vertices(
|
||||
},
|
||||
TextVertex {
|
||||
position: [left, bottom],
|
||||
world_position: [dest_rect.left as f32, dest_rect.bottom as f32],
|
||||
world_position: [logical_left, logical_bottom],
|
||||
uv: [uv_rect.0, uv_rect.3],
|
||||
color,
|
||||
clip_rect,
|
||||
@@ -1908,7 +1917,7 @@ fn push_glyph_vertices(
|
||||
},
|
||||
TextVertex {
|
||||
position: [right, top],
|
||||
world_position: [dest_rect.right as f32, dest_rect.top as f32],
|
||||
world_position: [logical_right, logical_top],
|
||||
uv: [uv_rect.2, uv_rect.1],
|
||||
color,
|
||||
clip_rect,
|
||||
@@ -1917,7 +1926,7 @@ fn push_glyph_vertices(
|
||||
},
|
||||
TextVertex {
|
||||
position: [right, top],
|
||||
world_position: [dest_rect.right as f32, dest_rect.top as f32],
|
||||
world_position: [logical_right, logical_top],
|
||||
uv: [uv_rect.2, uv_rect.1],
|
||||
color,
|
||||
clip_rect,
|
||||
@@ -1926,7 +1935,7 @@ fn push_glyph_vertices(
|
||||
},
|
||||
TextVertex {
|
||||
position: [left, bottom],
|
||||
world_position: [dest_rect.left as f32, dest_rect.bottom as f32],
|
||||
world_position: [logical_left, logical_bottom],
|
||||
uv: [uv_rect.0, uv_rect.3],
|
||||
color,
|
||||
clip_rect,
|
||||
@@ -1935,7 +1944,7 @@ fn push_glyph_vertices(
|
||||
},
|
||||
TextVertex {
|
||||
position: [right, bottom],
|
||||
world_position: [dest_rect.right as f32, dest_rect.bottom as f32],
|
||||
world_position: [logical_right, logical_bottom],
|
||||
uv: [uv_rect.2, uv_rect.3],
|
||||
color,
|
||||
clip_rect,
|
||||
@@ -2484,12 +2493,22 @@ fn pixel_rect_tuple(rect: PixelRect) -> (i32, i32, i32, i32) {
|
||||
(rect.left, rect.top, rect.right, rect.bottom)
|
||||
}
|
||||
|
||||
fn scale_glyph_cache_key(cache_key: CacheKey, scale_factor: f32) -> CacheKey {
|
||||
CacheKey {
|
||||
font_size_bits: (f32::from_bits(cache_key.font_size_bits) * scale_factor.max(1.0))
|
||||
.to_bits(),
|
||||
..cache_key
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{
|
||||
ActiveClip, blend_rgba, build_text_vertices, build_vertices, clip_rect_array,
|
||||
push_clip_state, rounded_clip_arrays, text_texture_key,
|
||||
ActiveClip, AtlasRect, PixelRect, blend_rgba, build_text_vertices, build_vertices,
|
||||
clip_rect_array, push_clip_state, push_glyph_vertices, rounded_clip_arrays,
|
||||
scale_glyph_cache_key, text_texture_key,
|
||||
};
|
||||
use cosmic_text::{CacheKey, CacheKeyFlags, SubpixelBin, fontdb};
|
||||
use ruin_ui::{ClipRegion, Color, Point, PreparedText, Rect, SceneSnapshot, UiSize};
|
||||
|
||||
#[test]
|
||||
@@ -2568,6 +2587,58 @@ mod tests {
|
||||
assert_ne!(first, different_pixel);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scale_glyph_cache_key_scales_font_size_only() {
|
||||
let key = CacheKey {
|
||||
font_id: fontdb::ID::dummy(),
|
||||
glyph_id: 42,
|
||||
font_size_bits: 13.0_f32.to_bits(),
|
||||
x_bin: SubpixelBin::One,
|
||||
y_bin: SubpixelBin::Two,
|
||||
font_weight: fontdb::Weight::BOLD,
|
||||
flags: CacheKeyFlags::FAKE_ITALIC,
|
||||
};
|
||||
|
||||
let scaled = scale_glyph_cache_key(key, 2.0);
|
||||
|
||||
assert_eq!(f32::from_bits(scaled.font_size_bits), 26.0);
|
||||
assert_eq!(scaled.font_id, key.font_id);
|
||||
assert_eq!(scaled.glyph_id, key.glyph_id);
|
||||
assert_eq!(scaled.x_bin, key.x_bin);
|
||||
assert_eq!(scaled.y_bin, key.y_bin);
|
||||
assert_eq!(scaled.font_weight, key.font_weight);
|
||||
assert_eq!(scaled.flags, key.flags);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scaled_atlas_vertices_convert_device_pixels_to_logical_space() {
|
||||
let mut vertices = Vec::new();
|
||||
push_glyph_vertices(
|
||||
&mut vertices,
|
||||
PixelRect {
|
||||
left: 20,
|
||||
top: 10,
|
||||
right: 40,
|
||||
bottom: 30,
|
||||
},
|
||||
AtlasRect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 20,
|
||||
height: 20,
|
||||
},
|
||||
None,
|
||||
UiSize::new(100.0, 100.0),
|
||||
2.0,
|
||||
Color::rgb(0xFF, 0xFF, 0xFF),
|
||||
ActiveClip::default(),
|
||||
);
|
||||
|
||||
assert_eq!(vertices.len(), 6);
|
||||
assert_eq!(vertices[0].world_position, [10.0, 5.0]);
|
||||
assert_eq!(vertices[5].world_position, [20.0, 15.0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_clip_with_empty_intersection_stays_clipped() {
|
||||
let mut clip_stack = Vec::new();
|
||||
|
||||
Reference in New Issue
Block a user