From 4f19f0f4deed1274e08c13e1f03901bd88fa7eae Mon Sep 17 00:00:00 2001 From: Billy Messenger <60663878+BillyDM@users.noreply.github.com> Date: Mon, 29 Jul 2024 12:20:48 -0500 Subject: [PATCH] fix the mess merge conflicts made --- src/text_render.rs | 184 +++++++++++++++++++++++++++++++-------------- 1 file changed, 129 insertions(+), 55 deletions(-) diff --git a/src/text_render.rs b/src/text_render.rs index 025bab6..4800b6b 100644 --- a/src/text_render.rs +++ b/src/text_render.rs @@ -77,7 +77,10 @@ impl TextRenderer { let mut clip_and_add_glyph = |details: &GlyphDetails, mut x: i32, mut y: i32, - bounds: TextBounds, + bounds_min_x: i32, + bounds_min_y: i32, + bounds_max_x: i32, + bounds_max_y: i32, color: Color, metadata: usize, color_mode: ColorMode| { @@ -89,11 +92,6 @@ impl TextRenderer { let mut width = details.width as i32; let mut height = details.height as i32; - let bounds_min_x = bounds.left.max(0); - let bounds_min_y = bounds.top.max(0); - let bounds_max_x = bounds.right.min(resolution.width as i32); - let bounds_max_y = bounds.bottom.min(resolution.height as i32); - // Starts beyond right edge or ends beyond left edge let max_x = x + width; if x > bounds_max_x || max_x < bounds_min_x { @@ -158,6 +156,127 @@ impl TextRenderer { let bounds_max_x = text_area.bounds.right.min(resolution.width as i32); let bounds_max_y = text_area.bounds.bottom.min(resolution.height as i32); + #[cfg(feature = "custom-glyphs")] + for glyph in text_area.custom_glyphs.iter() { + let (cache_key, x, y) = cosmic_text::CacheKey::new( + custom_glyph_font_id, + glyph.id, + glyph.size, + (text_area.left + glyph.left, text_area.top + glyph.top), + custom_glyph_flags, + ); + + if atlas.mask_atlas.glyph_cache.contains(&cache_key) { + atlas.mask_atlas.promote(cache_key); + } else if atlas.color_atlas.glyph_cache.contains(&cache_key) { + atlas.color_atlas.promote(cache_key); + } else { + let input = CustomGlyphInput { + id: glyph.id, + size: glyph.size, + scale: text_area.scale, + x_bin: cache_key.x_bin, + y_bin: cache_key.y_bin, + }; + + let (gpu_cache, atlas_id, inner, width, height) = if let Some(output) = + rasterize_custom_glyph(input) + { + let mut inner = atlas.inner_for_content_mut(output.content_type); + + // Find a position in the packer + let allocation = loop { + match inner.try_allocate(output.width as usize, output.height as usize) + { + Some(a) => break a, + None => { + if !atlas.grow( + device, + queue, + font_system, + cache, + output.content_type, + ) { + return Err(PrepareError::AtlasFull); + } + + inner = atlas.inner_for_content_mut(output.content_type); + } + } + }; + let atlas_min = allocation.rectangle.min; + + queue.write_texture( + ImageCopyTexture { + texture: &inner.texture, + mip_level: 0, + origin: Origin3d { + x: atlas_min.x as u32, + y: atlas_min.y as u32, + z: 0, + }, + aspect: TextureAspect::All, + }, + &output.data, + ImageDataLayout { + offset: 0, + bytes_per_row: Some(output.width * inner.num_channels() as u32), + rows_per_image: None, + }, + Extent3d { + width: output.width, + height: output.height, + depth_or_array_layers: 1, + }, + ); + + ( + GpuCacheStatus::InAtlas { + x: atlas_min.x as u16, + y: atlas_min.y as u16, + content_type: output.content_type, + }, + Some(allocation.id), + inner, + output.width, + output.height, + ) + } else { + let inner = &mut atlas.color_atlas; + (GpuCacheStatus::SkipRasterization, None, inner, 0, 0) + }; + + inner.put( + cache_key, + GlyphDetails { + width: width as u16, + height: height as u16, + gpu_cache, + atlas_id, + top: 0, + left: 0, + }, + ); + } + + let details = atlas.glyph(&cache_key).unwrap(); + + let color = glyph.color.unwrap_or(text_area.default_color); + + clip_and_add_glyph( + details, + x, + y, + bounds_min_x, + bounds_min_y, + bounds_max_x, + bounds_max_y, + color, + glyph.metadata, + atlas.color_mode, + ); + } + let is_run_visible = |run: &cosmic_text::LayoutRun| { let start_y = (text_area.top + run.line_top) as i32; let end_y = (text_area.top + run.line_top + run.line_height) as i32; @@ -290,54 +409,6 @@ impl TextRenderer { let y = (run.line_y * text_area.scale).round() as i32 + physical_glyph.y - details.top as i32; - let (mut atlas_x, mut atlas_y, content_type) = match details.gpu_cache { - GpuCacheStatus::InAtlas { x, y, content_type } => (x, y, content_type), - GpuCacheStatus::SkipRasterization => continue, - }; - - let mut width = details.width as i32; - let mut height = details.height as i32; - - // Starts beyond right edge or ends beyond left edge - let max_x = x + width; - if x > bounds_max_x || max_x < bounds_min_x { - continue; - } - - // Starts beyond bottom edge or ends beyond top edge - let max_y = y + height; - if y > bounds_max_y || max_y < bounds_min_y { - continue; - } - - // Clip left ege - if x < bounds_min_x { - let right_shift = bounds_min_x - x; - - x = bounds_min_x; - width = max_x - bounds_min_x; - atlas_x += right_shift as u16; - } - - // Clip right edge - if x + width > bounds_max_x { - width = bounds_max_x - x; - } - - // Clip top edge - if y < bounds_min_y { - let bottom_shift = bounds_min_y - y; - - y = bounds_min_y; - height = max_y - bounds_min_y; - atlas_y += bottom_shift as u16; - } - - // Clip bottom edge - if y + height > bounds_max_y { - height = bounds_max_y - y; - } - let color = match glyph.color_opt { Some(some) => some, None => text_area.default_color, @@ -347,7 +418,10 @@ impl TextRenderer { atlas.glyph(&physical_glyph.cache_key).unwrap(), x, y, - text_area.bounds, + bounds_min_x, + bounds_min_y, + bounds_max_x, + bounds_max_y, color, glyph.metadata, atlas.color_mode,