From 25696dc6cf79da499d466646cc4b0b30e5225d6a Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 21 Mar 2023 19:21:16 +0000 Subject: [PATCH 01/19] add support for color font --- Cargo.toml | 1 + src/atlas.rs | 51 +++++++++++++--- src/glyphs.rs | 109 +++++++++++++++++++++++++++++---- src/lib.rs | 158 ++++++++++++++++++++++++++++++++++++++++++++---- src/prim.rs | 3 + src/shader.wgsl | 58 ++++++++++++++---- tests/tests.rs | 6 +- 7 files changed, 339 insertions(+), 47 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 234f37b..9496f13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "6b1dbb529a2396378c05e452b5dc82376ee25040" } [dev-dependencies] png = "0.17.6" diff --git a/src/atlas.rs b/src/atlas.rs index 0c47beb..90f0352 100644 --- a/src/atlas.rs +++ b/src/atlas.rs @@ -7,12 +7,18 @@ struct ImageData { data: Vec, } +pub enum AtlasContent { + Mask, + Color, +} + pub struct Atlas { packer: Packer, new_data: Vec, pub atlas_texture: wgpu::Texture, area_used: i32, did_clear: bool, + content: AtlasContent, } impl Atlas { @@ -42,14 +48,37 @@ impl Atlas { sample_count: 1, dimension: wgpu::TextureDimension::D2, format: wgpu::TextureFormat::R8Unorm, - usage: wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING, + usage: wgpu::TextureUsages::COPY_SRC + | wgpu::TextureUsages::COPY_DST + | wgpu::TextureUsages::TEXTURE_BINDING, label: Some("atlas_texture"), view_formats: &[wgpu::TextureFormat::R8Unorm], } } - pub fn new(device: &wgpu::Device) -> Self { - let atlas_texture = device.create_texture(&Self::get_texture_desc()); + pub fn new(device: &wgpu::Device, content: AtlasContent) -> Self { + let texture_size = wgpu::Extent3d { + width: Atlas::ATLAS_SIZE, + height: Atlas::ATLAS_SIZE, + depth_or_array_layers: 1, + }; + let format = match content { + AtlasContent::Mask => wgpu::TextureFormat::R8Unorm, + AtlasContent::Color => wgpu::TextureFormat::Rgba8Unorm, + }; + let desc = wgpu::TextureDescriptor { + size: texture_size, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + format, + usage: wgpu::TextureUsages::COPY_SRC + | wgpu::TextureUsages::COPY_DST + | wgpu::TextureUsages::TEXTURE_BINDING, + label: Some("atlas_texture"), + view_formats: &[format], + }; + let atlas_texture = device.create_texture(&desc); Self { packer: Packer::new(Atlas::get_packer_config()), @@ -57,6 +86,7 @@ impl Atlas { atlas_texture, area_used: 0, did_clear: false, + content, } } @@ -81,7 +111,7 @@ impl Atlas { let sz = Atlas::ATLAS_SIZE as usize; - let data = vec![0_u8;sz * sz]; + let data = vec![0_u8; sz * sz]; let buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("atlas temp buffer"), @@ -100,7 +130,7 @@ impl Atlas { buffer: &buffer, layout: wgpu::ImageDataLayout { offset: 0, - bytes_per_row: std::num::NonZeroU32::new(sz as u32), + bytes_per_row: std::num::NonZeroU32::new((sz * 4) as u32), rows_per_image: None, }, }, @@ -119,14 +149,19 @@ impl Atlas { for data in &self.new_data { // Pad data to wgpu::COPY_BYTES_PER_ROW_ALIGNMENT let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as i32; - let padding = (align - data.rect.width % align) % align; - let padded_width = data.rect.width + padding; + let pixels = match self.content { + AtlasContent::Mask => 1, + AtlasContent::Color => 4, + }; + let width = data.rect.width * pixels; + let padding = (align - width % align) % align; + let padded_width = width + padding; let mut padded_data = vec![]; padded_data.reserve((padded_width * data.rect.height) as usize); let mut i = 0; for _ in 0..data.rect.height { - for _ in 0..data.rect.width { + for _ in 0..width { padded_data.push(data.data[i]); i += 1; } diff --git a/src/glyphs.rs b/src/glyphs.rs index 258a0cb..8e32c62 100644 --- a/src/glyphs.rs +++ b/src/glyphs.rs @@ -1,4 +1,5 @@ -use crate::atlas::Atlas; +use crate::atlas::{Atlas, AtlasContent}; +use cosmic_text::{SubpixelBin, SwashContent, SwashImage}; use rect_packer::Rect; use std::collections::HashMap; @@ -8,10 +9,21 @@ pub struct GlyphInfo { pub metrics: fontdue::Metrics, } +#[derive(Copy, Clone, Debug)] +pub struct AtlasInfo { + pub rect: Option, + pub left: i32, + pub top: i32, + pub colored: bool, +} + pub struct GlyphCache { - pub atlas: Atlas, + pub mask_atlas: Atlas, + pub color_atlas: Atlas, pub font: fontdue::Font, info: HashMap<(char, u32), GlyphInfo>, + atlas_infos: HashMap<(cosmic_text::fontdb::ID, u16, u32, SubpixelBin), AtlasInfo>, + svg_infos: HashMap, HashMap<(u32, u32), AtlasInfo>>, } impl GlyphCache { @@ -23,12 +35,84 @@ impl GlyphCache { let font = include_bytes!("fonts/Anodina-Regular.ttf") as &[u8]; Self { - atlas: Atlas::new(device), + mask_atlas: Atlas::new(device, AtlasContent::Mask), + color_atlas: Atlas::new(device, AtlasContent::Color), font: fontdue::Font::from_bytes(font, settings).unwrap(), info: HashMap::new(), + atlas_infos: HashMap::new(), + svg_infos: HashMap::new(), } } + pub fn get_svg_mask( + &mut self, + hash: &[u8], + width: u32, + height: u32, + image: impl FnOnce() -> Vec, + ) -> AtlasInfo { + if !self.svg_infos.contains_key(hash) { + self.svg_infos.insert(hash.to_vec(), HashMap::new()); + } + + { + let svg_infos = self.svg_infos.get(hash).unwrap(); + if let Some(info) = svg_infos.get(&(width, height)) { + return info.clone(); + } + } + + let data = image(); + let rect = self.color_atlas.add_region(&data, width, height); + let info = AtlasInfo { + rect, + left: 0, + top: 0, + colored: true, + }; + + let svg_infos = self.svg_infos.get_mut(hash).unwrap(); + svg_infos.insert((width, height), info.clone()); + + info + } + + pub fn get_glyph_mask<'a>( + &mut self, + font_id: cosmic_text::fontdb::ID, + glyph_id: u16, + size: u32, + subpx: SubpixelBin, + image: impl FnOnce() -> SwashImage, + ) -> AtlasInfo { + let key = (font_id, glyph_id, size, subpx); + if let Some(rect) = self.atlas_infos.get(&key) { + return *rect; + } + + let image = image(); + let rect = match image.content { + SwashContent::Mask => self.mask_atlas.add_region( + &image.data, + image.placement.width, + image.placement.height, + ), + SwashContent::SubpixelMask | SwashContent::Color => self.color_atlas.add_region( + &image.data, + image.placement.width, + image.placement.height, + ), + }; + let info = AtlasInfo { + rect, + left: image.placement.left, + top: image.placement.top, + colored: image.content != SwashContent::Mask, + }; + self.atlas_infos.insert(key, info); + info + } + pub fn get_glyph(&mut self, c: char, size: f32) -> GlyphInfo { let factor = 65536.0; @@ -53,7 +137,7 @@ impl GlyphCache { */ let rect = - self.atlas + self.mask_atlas .add_region(&data, metrics.width as u32, metrics.height as u32); let info = GlyphInfo { rect, metrics }; @@ -65,19 +149,20 @@ impl GlyphCache { } pub fn update(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder) { - self.atlas.update(device, encoder); + self.mask_atlas.update(device, encoder); + self.color_atlas.update(device, encoder); } - pub fn create_view(&self) -> wgpu::TextureView { - self.atlas.create_view() - } - - pub fn usage(&self) -> f32 { - self.atlas.usage() + pub fn check_usage(&mut self) { + if self.mask_atlas.usage() > 0.7 || self.color_atlas.usage() > 0.7 { + self.clear(); + } } pub fn clear(&mut self) { self.info.clear(); - self.atlas.clear(); + self.mask_atlas.clear(); + self.color_atlas.clear(); + self.atlas_infos.clear(); } } diff --git a/src/lib.rs b/src/lib.rs index c30e4b6..c85dd09 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,4 @@ +use cosmic_text::{SubpixelBin, SwashImage}; use fontdue::layout::{CoordinateSystem, Layout, LayoutSettings, TextStyle}; mod path; @@ -120,6 +121,16 @@ impl Vger { wgpu::BindGroupLayoutEntry { binding: 2, visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Texture { + multisampled: false, + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + }, + count: None, + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + visibility: wgpu::ShaderStages::FRAGMENT, ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), count: None, }, @@ -129,7 +140,8 @@ impl Vger { let glyph_cache = GlyphCache::new(device); - let texture_view = glyph_cache.create_view(); + let mask_texture_view = glyph_cache.mask_atlas.create_view(); + let color_texture_view = glyph_cache.color_atlas.create_view(); let uniforms = GPUVec::new_uniforms(device, "uniforms"); @@ -146,10 +158,14 @@ impl Vger { uniforms.bind_group_entry(0), wgpu::BindGroupEntry { binding: 1, - resource: wgpu::BindingResource::TextureView(&texture_view), + resource: wgpu::BindingResource::TextureView(&mask_texture_view), }, wgpu::BindGroupEntry { binding: 2, + resource: wgpu::BindingResource::TextureView(&color_texture_view), + }, + wgpu::BindGroupEntry { + binding: 3, resource: wgpu::BindingResource::Sampler(&glyph_sampler), }, ], @@ -294,12 +310,7 @@ impl Vger { queue.submit(Some(encoder.finish())); // If we're getting close to full, reset the glyph cache. - let usage = self.glyph_cache.usage(); - // println!("glyph cache usage {}", usage); - if usage > 0.7 { - // println!("clearing glyph cache"); - self.glyph_cache.clear(); - } + self.glyph_cache.check_usage(); } fn render(&mut self, prim: Prim) { @@ -436,10 +447,10 @@ impl Vger { prim.width = width; prim.paint = paint_index.index as u32; prim.quad_bounds = [ - ap.x.min(bp.x), - ap.y.min(bp.y), - ap.x.max(bp.x), - ap.y.max(bp.y), + ap.x.min(bp.x) - width * 2.0, + ap.y.min(bp.y) - width * 2.0, + ap.x.max(bp.x) + width * 2.0, + ap.y.max(bp.y) + width * 2.0, ]; prim.tex_bounds = prim.quad_bounds; prim.xform = self.add_xform() as u32; @@ -560,6 +571,81 @@ impl Vger { ); } + pub fn render_glyph<'a>( + &mut self, + x: f32, + y: f32, + font_id: cosmic_text::fontdb::ID, + glyph_id: u16, + size: u32, + subpx: SubpixelBin, + image: impl FnOnce() -> SwashImage, + paint_index: PaintIndex, + ) { + let info = self + .glyph_cache + .get_glyph_mask(font_id, glyph_id, size, subpx, image); + if let Some(rect) = info.rect { + let mut prim = Prim::default(); + prim.prim_type = if info.colored { + PrimType::ColorGlyph + } else { + PrimType::Glyph + } as u32; + + let x = x + info.left as f32; + let y = y - info.top as f32; + prim.quad_bounds = [x, y, x + rect.width as f32, y + rect.height as f32]; + + prim.tex_bounds = [ + rect.x as f32, + rect.y as f32, + (rect.x + rect.width) as f32, + (rect.y + rect.height) as f32, + ]; + prim.paint = paint_index.index as u32; + + self.render(prim); + } + } + + pub fn render_svg( + &mut self, + x: f32, + y: f32, + hash: &[u8], + width: u32, + height: u32, + image: impl FnOnce() -> Vec, + paint_index: Option, + ) { + let info = self.glyph_cache.get_svg_mask(hash, width, height, image); + if let Some(rect) = info.rect { + let mut prim = Prim::default(); + prim.prim_type = if info.colored { + PrimType::ColorGlyph + } else { + PrimType::Glyph + } as u32; + + let x = x + info.left as f32; + let y = y - info.top as f32; + prim.quad_bounds = [x, y, x + rect.width as f32, y + rect.height as f32]; + + prim.tex_bounds = [ + rect.x as f32, + rect.y as f32, + (rect.x + rect.width) as f32, + (rect.y + rect.height) as f32, + ]; + if let Some(paint_index) = paint_index { + prim.paint = paint_index.index as u32; + } + + self.render(prim); + } + } + /// Renders text. pub fn text(&mut self, text: &str, size: u32, color: Color, max_width: Option) { self.setup_layout(text, size, max_width); @@ -592,7 +678,7 @@ impl Vger { (glyph.y + glyph.height as f32) / scale, ]; // println!("quad_bounds: {:?}", prim.quad_bounds); - + prim.tex_bounds = [ rect.x as f32, (rect.y + rect.height) as f32, @@ -801,3 +887,49 @@ impl Vger { )) } } + +#[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[repr(u8)] +pub enum SubpixelOffset { + Zero = 0, + Quarter = 1, + Half = 2, + ThreeQuarters = 3, +} + +impl Default for SubpixelOffset { + fn default() -> Self { + SubpixelOffset::Zero + } +} + +impl SubpixelOffset { + // Skia quantizes subpixel offsets into 1/4 increments. + // Given the absolute position, return the quantized increment + pub fn quantize(pos: f32) -> Self { + // Following the conventions of Gecko and Skia, we want + // to quantize the subpixel position, such that abs(pos) gives: + // [0.0, 0.125) -> Zero + // [0.125, 0.375) -> Quarter + // [0.375, 0.625) -> Half + // [0.625, 0.875) -> ThreeQuarters, + // [0.875, 1.0) -> Zero + // The unit tests below check for this. + let apos = ((pos - pos.floor()) * 8.0) as i32; + match apos { + 1..=2 => SubpixelOffset::Quarter, + 3..=4 => SubpixelOffset::Half, + 5..=6 => SubpixelOffset::ThreeQuarters, + _ => SubpixelOffset::Zero, + } + } + + pub fn to_f32(self) -> f32 { + match self { + SubpixelOffset::Zero => 0.0, + SubpixelOffset::Quarter => 0.25, + SubpixelOffset::Half => 0.5, + SubpixelOffset::ThreeQuarters => 0.75, + } + } +} diff --git a/src/prim.rs b/src/prim.rs index 52713c9..30820ed 100644 --- a/src/prim.rs +++ b/src/prim.rs @@ -28,6 +28,9 @@ pub enum PrimType { /// Text rendering. Glyph, + /// Colored glyph e.g. emoji. + ColorGlyph, + /// Path fills. PathFill, } diff --git a/src/shader.wgsl b/src/shader.wgsl index c8f2b40..2a7ecd5 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -27,8 +27,11 @@ const vgerWire = 7; /// Text rendering. const vgerGlyph = 8; +/// Text rendering. +const vgerColorGlyph = 9; + /// Path fills. -const vgerPathFill = 9; +const vgerPathFill = 10; struct Prim { @@ -103,12 +106,13 @@ fn sdBox(p: vec2, b: vec2, r: f32) -> f32 return length(max(d,vec2(0.0, 0.0))) + min(max(d.x,d.y),0.0)-r; } -fn sdSegment(p: vec2, a: vec2, b: vec2) -> f32 +fn sdSegment(p: vec2, a: vec2, b: vec2, width: f32) -> f32 { - let pa = p-a; - let ba = b-a; - let h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); - return length( pa - ba*h ); + var dir = a-b; + let lngth = length(dir); + dir = dir / lngth; + let proj = max(0.0, min(lngth, dot((a - p), dir))) * dir; + return length( (a - p) - proj ) - (width / 2.0); } fn sdSegment2(p: vec2, a: vec2, b: vec2, width: f32) -> f32 @@ -336,7 +340,11 @@ fn sdPrimBounds(prim: Prim) -> BBox { b.min = prim.cv0; b.max = prim.cv1; } - case 9u: { // vgerPathFill + case 9u: { // vgerColorGlyph + b.min = prim.cv0; + b.max = prim.cv1; + } + case 10u: { // vgerPathFill b.min = vec2(1e10, 1e10); b.max = -b.min; for(var i: i32 = 0; i < i32(prim.count * 3u); i = i+1) { @@ -425,7 +433,12 @@ fn sdPrim(prim: Prim, p: vec2, filterWidth: f32) -> f32 { let size = prim.cv1 - prim.cv0; d = sdBox(p - center, 0.5*size, prim.radius); } - case 9u: { // vgerPathFill + case 9u: { // vgerColorGlyph + let center = 0.5*(prim.cv1 + prim.cv0); + let size = prim.cv1 - prim.cv0; + d = sdBox(p - center, 0.5*size, prim.radius); + } + case 10u: { // vgerPathFill for(var i=0; i(q, 0.0, 1.0)).xy; - out.position = vec4(2.0 * out.p / uniforms.size - 1.0, 0.0, 1.0); + out.position = vec4((2.0 * out.p / uniforms.size - 1.0) * vec2(1.0, -1.0), 0.0, 1.0); return out; } @@ -604,6 +617,10 @@ var glyph_atlas: texture_2d; @group(1) @binding(2) +var color_atlas: texture_2d; + +@group(1) +@binding(3) var samp : sampler; // sRGB to linear conversion for one channel. @@ -627,17 +644,36 @@ fn fs_main( // Look up glyph alpha (if not a glyph, still have to because of wgsl). // let a = textureSample(glyph_atlas, samp, (in.t+0.5)/1024.0).r; - let a = textureLoad(glyph_atlas, vec2(in.t), 0).r; + let mask = textureLoad(glyph_atlas, vec2(in.t), 0); + let color_mask = textureLoad(color_atlas, vec2(in.t), 0); let s = scissor_mask(scissor, in.p); if(prim.prim_type == 8u) { // vgerGlyph + if (mask.r <= 0.0) { + discard; + } + + let c = paint.inner_color; + + // XXX: using toLinear is a bit of a guess. Gets us closer + // to matching the glyph atlas in the output. + var color = vec4(c.rgb, mask.r); + + //if(glow) { + // color.a *= paint.glow; + //} + + return s * color; + } + + if(prim.prim_type == 9u) { // vgerColorGlyph let c = paint.inner_color; // XXX: using toLinear is a bit of a guess. Gets us closer // to matching the glyph atlas in the output. - var color = vec4(c.rgb, toLinear(a)); + var color = vec4(color_mask.rgb, c.a * color_mask.a); //if(glow) { // color.a *= paint.glow; diff --git a/tests/tests.rs b/tests/tests.rs index 9b408ce..eb107cd 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -283,7 +283,7 @@ fn text_small() { let atlas_png_name = "text_small_atlas.png"; save_png( - &vger.glyph_cache.atlas.atlas_texture, + &vger.glyph_cache.mask_atlas.atlas_texture, &vger::atlas::Atlas::get_texture_desc(), &device, &queue, @@ -308,7 +308,7 @@ fn text_scale() { let atlas_png_name = "text_scale_atlas.png"; save_png( - &vger.glyph_cache.atlas.atlas_texture, + &vger.glyph_cache.mask_atlas.atlas_texture, &vger::atlas::Atlas::get_texture_desc(), &device, &queue, @@ -342,7 +342,7 @@ fn text_box() { let atlas_png_name = "text_box_atlas.png"; save_png( - &vger.glyph_cache.atlas.atlas_texture, + &vger.glyph_cache.mask_atlas.atlas_texture, &vger::atlas::Atlas::get_texture_desc(), &device, &queue, From 45d5111ac9701811bb569b250840f3acbb2aefdc Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Wed, 22 Mar 2023 19:13:25 +0000 Subject: [PATCH 02/19] bump cosmic-text --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9496f13..4aa39f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "6b1dbb529a2396378c05e452b5dc82376ee25040" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "52578fe7d9f4db40044b7fee04bf2185ad61fcd7" } [dev-dependencies] png = "0.17.6" From f08f9ce1147e1fe7b3bc22d5f42e69d2c1cdb6f7 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 28 Mar 2023 19:18:07 +0100 Subject: [PATCH 03/19] make y subpixel --- Cargo.toml | 2 +- src/glyphs.rs | 12 ++++++++++-- src/lib.rs | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4aa39f4..fe5d929 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "52578fe7d9f4db40044b7fee04bf2185ad61fcd7" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "f3cf3681c8870e999120afb5e04f2539ed89839e" } [dev-dependencies] png = "0.17.6" diff --git a/src/glyphs.rs b/src/glyphs.rs index 8e32c62..fc37f36 100644 --- a/src/glyphs.rs +++ b/src/glyphs.rs @@ -22,7 +22,15 @@ pub struct GlyphCache { pub color_atlas: Atlas, pub font: fontdue::Font, info: HashMap<(char, u32), GlyphInfo>, - atlas_infos: HashMap<(cosmic_text::fontdb::ID, u16, u32, SubpixelBin), AtlasInfo>, + atlas_infos: HashMap< + ( + cosmic_text::fontdb::ID, + u16, + u32, + (SubpixelBin, SubpixelBin), + ), + AtlasInfo, + >, svg_infos: HashMap, HashMap<(u32, u32), AtlasInfo>>, } @@ -82,7 +90,7 @@ impl GlyphCache { font_id: cosmic_text::fontdb::ID, glyph_id: u16, size: u32, - subpx: SubpixelBin, + subpx: (SubpixelBin, SubpixelBin), image: impl FnOnce() -> SwashImage, ) -> AtlasInfo { let key = (font_id, glyph_id, size, subpx); diff --git a/src/lib.rs b/src/lib.rs index c85dd09..0371788 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -578,7 +578,7 @@ impl Vger { font_id: cosmic_text::fontdb::ID, glyph_id: u16, size: u32, - subpx: SubpixelBin, + subpx: (SubpixelBin, SubpixelBin), image: impl FnOnce() -> SwashImage, paint_index: PaintIndex, ) { From 201d63cf23ac11b3c88690984cdcd665966aae7a Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 30 Mar 2023 20:14:32 +0100 Subject: [PATCH 04/19] add scissor --- src/atlas.rs | 2 +- src/lib.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/atlas.rs b/src/atlas.rs index 90f0352..a122f50 100644 --- a/src/atlas.rs +++ b/src/atlas.rs @@ -22,7 +22,7 @@ pub struct Atlas { } impl Atlas { - pub const ATLAS_SIZE: u32 = 1024; + pub const ATLAS_SIZE: u32 = 4096; pub const RECT_PADDING: i32 = 6; fn get_packer_config() -> rect_packer::Config { diff --git a/src/lib.rs b/src/lib.rs index 0371788..73031b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -604,6 +604,7 @@ impl Vger { (rect.y + rect.height) as f32, ]; prim.paint = paint_index.index as u32; + prim.scissor = self.add_scissor() as u32; self.render(prim); } @@ -641,6 +642,7 @@ impl Vger { if let Some(paint_index) = paint_index { prim.paint = paint_index.index as u32; } + prim.scissor = self.add_scissor() as u32; self.render(prim); } From 3fcccf1c53ce670e8a45b4eb17f39735ab21eca5 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 30 Mar 2023 20:58:33 +0100 Subject: [PATCH 05/19] bump cosmic-text --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fe5d929..22064e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "f3cf3681c8870e999120afb5e04f2539ed89839e" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "8537081d1faafb01f0d1a5662f8cca3cca23efa2" } [dev-dependencies] png = "0.17.6" From ad587e7c7da177fcebeebe1bb0715db3001300ff Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 30 Mar 2023 21:27:25 +0100 Subject: [PATCH 06/19] change text through sampler --- src/lib.rs | 19 +++++++++++++++++++ src/shader.wgsl | 11 ++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 73031b8..59acbdb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -134,6 +134,12 @@ impl Vger { ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), count: None, }, + wgpu::BindGroupLayoutEntry { + binding: 4, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + }, ], label: Some("uniform_bind_group_layout"), }); @@ -149,6 +155,15 @@ impl Vger { label: Some("glyph"), mag_filter: wgpu::FilterMode::Linear, min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Linear, + ..Default::default() + }); + + let color_glyph_sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("color_glyph"), + mag_filter: wgpu::FilterMode::Linear, + min_filter: wgpu::FilterMode::Linear, + mipmap_filter: wgpu::FilterMode::Linear, ..Default::default() }); @@ -168,6 +183,10 @@ impl Vger { binding: 3, resource: wgpu::BindingResource::Sampler(&glyph_sampler), }, + wgpu::BindGroupEntry { + binding: 4, + resource: wgpu::BindingResource::Sampler(&color_glyph_sampler), + }, ], label: Some("vger bind group"), }); diff --git a/src/shader.wgsl b/src/shader.wgsl index 2a7ecd5..417bf3f 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -623,6 +623,10 @@ var color_atlas: texture_2d; @binding(3) var samp : sampler; +@group(1) +@binding(4) +var color_samp : sampler; + // sRGB to linear conversion for one channel. fn toLinear(s: f32) -> f32 { @@ -644,8 +648,9 @@ fn fs_main( // Look up glyph alpha (if not a glyph, still have to because of wgsl). // let a = textureSample(glyph_atlas, samp, (in.t+0.5)/1024.0).r; - let mask = textureLoad(glyph_atlas, vec2(in.t), 0); - let color_mask = textureLoad(color_atlas, vec2(in.t), 0); + // let mask = textureLoad(glyph_atlas, vec2(in.t), 0); + let mask = textureSample(glyph_atlas, samp, in.t/4096.0); + let color_mask = textureSample(color_atlas, color_samp, in.t/4096.0); let s = scissor_mask(scissor, in.p); @@ -658,7 +663,7 @@ fn fs_main( // XXX: using toLinear is a bit of a guess. Gets us closer // to matching the glyph atlas in the output. - var color = vec4(c.rgb, mask.r); + var color = vec4(c.rgb, c.a * mask.r); //if(glow) { // color.a *= paint.glow; From fa81bb72b3b627c5a6aa39749db23ab026618999 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 6 Apr 2023 20:56:59 +0100 Subject: [PATCH 07/19] add support for override color svg --- src/lib.rs | 6 +++--- src/prim.rs | 3 +++ src/shader.wgsl | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 59acbdb..b6cb314 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -642,10 +642,10 @@ impl Vger { let info = self.glyph_cache.get_svg_mask(hash, width, height, image); if let Some(rect) = info.rect { let mut prim = Prim::default(); - prim.prim_type = if info.colored { - PrimType::ColorGlyph + prim.prim_type = if paint_index.is_some() { + PrimType::OverrideColorSvg } else { - PrimType::Glyph + PrimType::ColorGlyph } as u32; let x = x + info.left as f32; diff --git a/src/prim.rs b/src/prim.rs index 30820ed..3437b7f 100644 --- a/src/prim.rs +++ b/src/prim.rs @@ -33,6 +33,9 @@ pub enum PrimType { /// Path fills. PathFill, + + /// Svg with override color + OverrideColorSvg, } #[derive(Copy, Clone, Default)] diff --git a/src/shader.wgsl b/src/shader.wgsl index 417bf3f..9744a26 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -33,6 +33,9 @@ const vgerColorGlyph = 9; /// Path fills. const vgerPathFill = 10; +/// Svg with override color +const overrideColorSvg = 11; + struct Prim { /// Min and max coordinates of the quad we're rendering. @@ -351,6 +354,10 @@ fn sdPrimBounds(prim: Prim) -> BBox { b = expand(b, cvs.cvs[i32(prim.start)+i]); } } + case 11u: { // overrideColorSvg + b.min = prim.cv0; + b.max = prim.cv1; + } default: {} } return b; @@ -476,6 +483,11 @@ fn sdPrim(prim: Prim, p: vec2, filterWidth: f32) -> f32 { d = d * s; break; } + case 11u: { // overrideColorSvg + let center = 0.5*(prim.cv1 + prim.cv0); + let size = prim.cv1 - prim.cv0; + d = sdBox(p - center, 0.5*size, prim.radius); + } default: { } } return d; @@ -686,6 +698,21 @@ fn fs_main( return s * color; } + + if(prim.prim_type == 11u) { // overrideColorSvg + + let c = paint.inner_color; + + // XXX: using toLinear is a bit of a guess. Gets us closer + // to matching the glyph atlas in the output. + var color = vec4(c.rgb, c.a * color_mask.a); + + //if(glow) { + // color.a *= paint.glow; + //} + + return s * color; + } let d = sdPrim(prim, in.t, fw); let color = apply(paint, in.t); From 0def344b26c97cbab76503d80fd0f1de83c6d41e Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 14 Apr 2023 19:41:28 +0100 Subject: [PATCH 08/19] use only the same xform --- src/lib.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b6cb314..17929e7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -276,6 +276,7 @@ impl Vger { self.scissor_stack.push(Scissor::new()); self.paint_count = 0; self.xform_count = 0; + self.add_xform(); self.scissor_count = 0; self.pen = LocalPoint::zero(); } @@ -352,7 +353,6 @@ impl Vger { prim.paint = paint_index.index as u32; prim.quad_bounds = [c.x - radius, c.y - radius, c.x + radius, c.y + radius]; prim.tex_bounds = prim.quad_bounds; - prim.xform = self.add_xform() as u32; prim.scissor = self.add_scissor() as u32; self.render(prim); @@ -389,7 +389,6 @@ impl Vger { c.y + radius + width, ]; prim.tex_bounds = prim.quad_bounds; - prim.xform = self.add_xform() as u32; prim.scissor = self.add_scissor() as u32; self.render(prim); @@ -415,7 +414,6 @@ impl Vger { prim.paint = paint_index.index as u32; prim.quad_bounds = [min.x, min.y, max.x, max.y]; prim.tex_bounds = prim.quad_bounds; - prim.xform = self.add_xform() as u32; prim.scissor = self.add_scissor() as u32; self.render(prim); @@ -441,7 +439,6 @@ impl Vger { prim.paint = paint_index.index as u32; prim.quad_bounds = [min.x - width, min.y - width, max.x + width, max.y + width]; prim.tex_bounds = prim.quad_bounds; - prim.xform = self.add_xform() as u32; prim.scissor = self.add_scissor() as u32; self.render(prim); @@ -472,7 +469,6 @@ impl Vger { ap.y.max(bp.y) + width * 2.0, ]; prim.tex_bounds = prim.quad_bounds; - prim.xform = self.add_xform() as u32; prim.scissor = self.add_scissor() as u32; self.render(prim); @@ -507,7 +503,6 @@ impl Vger { ap.y.max(bp.y).max(cp.y) + width, ]; prim.tex_bounds = prim.quad_bounds; - prim.xform = self.add_xform() as u32; prim.scissor = self.add_scissor() as u32; self.render(prim); @@ -533,7 +528,6 @@ impl Vger { /// Fills a path. pub fn fill(&mut self, paint_index: PaintIndex) { - let xform = self.add_xform(); let scissor = self.add_scissor(); self.path_scanner.init(); @@ -542,7 +536,6 @@ impl Vger { let mut prim = Prim::default(); prim.prim_type = PrimType::PathFill as u32; prim.paint = paint_index.index as u32; - prim.xform = xform as u32; prim.scissor = scissor as u32; prim.start = self.scenes[self.cur_scene].cvs.len() as u32; @@ -675,7 +668,6 @@ impl Vger { let scaled_size = size as f32 * scale; let paint = self.color_paint(color); - let xform = self.add_xform() as u32; let scissor = self.add_scissor() as u32; let mut prims = vec![]; @@ -687,7 +679,6 @@ impl Vger { if let Some(rect) = info.rect { let mut prim = Prim::default(); prim.prim_type = PrimType::Glyph as u32; - prim.xform = xform; prim.scissor = scissor; assert!(glyph.width == rect.width as usize); assert!(glyph.height == rect.height as usize); From 58e34b0ffdbd5ee7627943b93bf33deb5e6c94bc Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Thu, 20 Apr 2023 19:22:58 +0100 Subject: [PATCH 09/19] Bezier path width fix --- src/shader.wgsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shader.wgsl b/src/shader.wgsl index 9744a26..483f98d 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -421,7 +421,7 @@ fn sdPrim(prim: Prim, p: vec2, filterWidth: f32) -> f32 { d = abs(sdBox(p - center, 0.5*size, prim.radius)) - prim.width/2.0; } case 4u: { // vgerBezier - d = sdBezierApprox(p, prim.cv0, prim.cv1, prim.cv2) - prim.width; + d = sdBezierApprox(p, prim.cv0, prim.cv1, prim.cv2) - prim.width/2.0; } case 5u: { // vgerSegment d = sdSegment2(p, prim.cv0, prim.cv1, prim.width); From 44803a328ef12983fb0df446cc901fff897df92d Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 21 Apr 2023 22:08:30 +0100 Subject: [PATCH 10/19] bump cosmic-text --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 22064e1..75a5de2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,8 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "8537081d1faafb01f0d1a5662f8cca3cca23efa2" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "5344eab79a6f805a56e4fd3374edc695d9e73bdf" } +# cosmic-text = { path = "../cosmic-text" } [dev-dependencies] png = "0.17.6" From 30c8d18ec900dcbd8dcf6bc6e2a726ae135f89d5 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Sun, 7 May 2023 16:36:36 +0100 Subject: [PATCH 11/19] bupm cosmic-text --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 75a5de2..e2d02cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "5344eab79a6f805a56e4fd3374edc695d9e73bdf" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "67e910c3e02a1dbf7a5e9ec5652b2e69c95d28c7" } # cosmic-text = { path = "../cosmic-text" } [dev-dependencies] From af4e4396b57ad49569f281053fddd1cdc573ac43 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 12 May 2023 19:39:50 +0100 Subject: [PATCH 12/19] bump comic-text --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e2d02cf..7ca224b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,8 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "67e910c3e02a1dbf7a5e9ec5652b2e69c95d28c7" } -# cosmic-text = { path = "../cosmic-text" } +# cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "5cbf0621f6052412701ad16c5095dfe39227cb4e" } +cosmic-text = { path = "../cosmic-text" } [dev-dependencies] png = "0.17.6" From 663a9e16c50be941370c23c99302b3de2db215c4 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 12 May 2023 19:47:12 +0100 Subject: [PATCH 13/19] bump cosmic-text --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7ca224b..982c951 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,8 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -# cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "5cbf0621f6052412701ad16c5095dfe39227cb4e" } -cosmic-text = { path = "../cosmic-text" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "5cbf0621f6052412701ad16c5095dfe39227cb4e" } +# cosmic-text = { path = "../cosmic-text" } [dev-dependencies] png = "0.17.6" From aa84d85c9f7df9da6ef47a2b6d43fe6909023b9b Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Wed, 17 May 2023 20:04:14 +0100 Subject: [PATCH 14/19] bump cosmic-text --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 982c951..42c3ce9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "5cbf0621f6052412701ad16c5095dfe39227cb4e" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "88bda037195ed21402eba66d85602728d99cbb48" } # cosmic-text = { path = "../cosmic-text" } [dev-dependencies] From 43f9ae2d2f2da9a9d3d7f35690032a2fa8a4dac1 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Tue, 30 May 2023 21:32:41 +0100 Subject: [PATCH 15/19] add z index --- src/gpu_vec.rs | 4 ++++ src/lib.rs | 12 +++++++++++- src/scene.rs | 12 ++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/gpu_vec.rs b/src/gpu_vec.rs index 8f0f7c3..86a12d0 100644 --- a/src/gpu_vec.rs +++ b/src/gpu_vec.rs @@ -95,6 +95,10 @@ impl GPUVec { self.data.clear(); } + pub fn append(&mut self, values: &mut Vec) { + self.data.append(values); + } + pub fn push(&mut self, value: T) { self.data.push(value); } diff --git a/src/lib.rs b/src/lib.rs index 17929e7..3bfdf39 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,6 +67,7 @@ pub struct Vger { scenes: [Scene; 3], cur_scene: usize, cur_layer: usize, + cur_z_index: i32, tx_stack: Vec, scissor_stack: Vec, device_px_ratio: f32, @@ -242,6 +243,7 @@ impl Vger { scenes, cur_scene: 0, cur_layer: 0, + cur_z_index: 0, tx_stack: vec![], scissor_stack: vec![], device_px_ratio: 1.0, @@ -334,7 +336,11 @@ impl Vger { } fn render(&mut self, prim: Prim) { - self.scenes[self.cur_scene].prims[self.cur_layer].push(prim); + let prims = self.scenes[self.cur_scene] + .depthed_prims + .entry(self.cur_z_index) + .or_default(); + prims.push(prim); } /// Fills a circle. @@ -858,6 +864,10 @@ impl Vger { } } + pub fn set_z_index(&mut self, z_index: i32) { + self.cur_z_index = z_index; + } + /// Resets the current scissor rect. pub fn reset_scissor(&mut self) { if let Some(m) = self.scissor_stack.last_mut() { diff --git a/src/scene.rs b/src/scene.rs index 0470033..27e179d 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use crate::*; pub const MAX_LAYERS: usize = 4; @@ -5,6 +7,7 @@ pub const MAX_LAYERS: usize = 4; type Mat4x4 = [f32; 16]; pub(crate) struct Scene { + pub depthed_prims: HashMap>, pub prims: [GPUVec; MAX_LAYERS], pub cvs: GPUVec, pub xforms: GPUVec, @@ -40,6 +43,7 @@ impl Scene { ]; Self { + depthed_prims: HashMap::new(), prims, cvs, xforms, @@ -87,6 +91,13 @@ impl Scene { } pub fn update(&mut self, device: &wgpu::Device, queue: &wgpu::Queue) { + let mut keys: Vec = self.depthed_prims.keys().copied().collect(); + keys.sort(); + for z_index in keys { + let mut prims = self.depthed_prims.remove(&z_index).unwrap(); + self.prims[0].append(&mut prims); + } + for i in 0..4 { self.prims[i].update(device, queue); } @@ -97,6 +108,7 @@ impl Scene { } pub fn clear(&mut self) { + self.depthed_prims.clear(); for i in 0..4 { self.prims[i].clear(); } From 8182b13ce636785b7e8a9453ff4277485f1e9658 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Fri, 2 Jun 2023 19:04:41 +0100 Subject: [PATCH 16/19] bump cosmic-text --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 42c3ce9..d14eee7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "88bda037195ed21402eba66d85602728d99cbb48" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "fa0efccc67b0ff362056198fc931bd24f68d3fb8" } # cosmic-text = { path = "../cosmic-text" } [dev-dependencies] From 0116da1bca0dbce1e71cac17a67dbbf474740c22 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Mon, 12 Jun 2023 21:11:07 +0100 Subject: [PATCH 17/19] bump cosmic-text --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index d14eee7..80d606b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" rand = "0.7.3" -cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "fa0efccc67b0ff362056198fc931bd24f68d3fb8" } +cosmic-text = { git = "https://github.com/lapce/cosmic-text", rev = "25f260eced296296ca22d22a04cbb3026f5fe2a2" } # cosmic-text = { path = "../cosmic-text" } [dev-dependencies] From c272ceecbfdc1eea310fd132173155629db63ed5 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Sat, 1 Jul 2023 13:29:24 +0100 Subject: [PATCH 18/19] fill fix --- src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 3bfdf39..6f85583 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -571,6 +571,8 @@ impl Vger { self.render(prim); } + + self.path_scanner.segments.clear(); } fn setup_layout(&mut self, text: &str, size: u32, max_width: Option) { From df20ad0137d7c7207b0e3374949db73999bd13f1 Mon Sep 17 00:00:00 2001 From: Dongdong Zhou Date: Sun, 21 Jul 2024 10:18:05 +0100 Subject: [PATCH 19/19] update wgpu --- Cargo.toml | 2 +- src/atlas.rs | 7 +++---- src/glyphs.rs | 6 +++--- src/lib.rs | 26 ++++++++++++-------------- src/path.rs | 2 +- tests/common.rs | 21 +++++++++------------ 6 files changed, 29 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 80d606b..f2e8607 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -wgpu = "0.15.1" +wgpu = "22.0.0" euclid = "0.22.7" fontdue = "0.7.2" rect_packer = "0.2.1" diff --git a/src/atlas.rs b/src/atlas.rs index a122f50..b96b321 100644 --- a/src/atlas.rs +++ b/src/atlas.rs @@ -130,7 +130,7 @@ impl Atlas { buffer: &buffer, layout: wgpu::ImageDataLayout { offset: 0, - bytes_per_row: std::num::NonZeroU32::new((sz * 4) as u32), + bytes_per_row: Some((sz * 4) as u32), rows_per_image: None, }, }, @@ -156,8 +156,7 @@ impl Atlas { let width = data.rect.width * pixels; let padding = (align - width % align) % align; let padded_width = width + padding; - let mut padded_data = vec![]; - padded_data.reserve((padded_width * data.rect.height) as usize); + let mut padded_data = Vec::with_capacity((padded_width * data.rect.height) as usize); let mut i = 0; for _ in 0..data.rect.height { @@ -189,7 +188,7 @@ impl Atlas { buffer: &buffer, layout: wgpu::ImageDataLayout { offset: 0, - bytes_per_row: std::num::NonZeroU32::new(padded_width as u32), + bytes_per_row: Some(padded_width as u32), rows_per_image: None, }, }, diff --git a/src/glyphs.rs b/src/glyphs.rs index fc37f36..8b2f8be 100644 --- a/src/glyphs.rs +++ b/src/glyphs.rs @@ -66,7 +66,7 @@ impl GlyphCache { { let svg_infos = self.svg_infos.get(hash).unwrap(); if let Some(info) = svg_infos.get(&(width, height)) { - return info.clone(); + return *info; } } @@ -80,12 +80,12 @@ impl GlyphCache { }; let svg_infos = self.svg_infos.get_mut(hash).unwrap(); - svg_infos.insert((width, height), info.clone()); + svg_infos.insert((width, height), info); info } - pub fn get_glyph_mask<'a>( + pub fn get_glyph_mask( &mut self, font_id: cosmic_text::fontdb::ID, glyph_id: u16, diff --git a/src/lib.rs b/src/lib.rs index 6f85583..e6015ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -214,6 +214,7 @@ impl Vger { module: &shader, entry_point: "vs_main", buffers: &[], + compilation_options: Default::default(), }, fragment: Some(wgpu::FragmentState { module: &shader, @@ -226,6 +227,7 @@ impl Vger { }), write_mask: wgpu::ColorWrites::ALL, })], + compilation_options: Default::default(), }), primitive: wgpu::PrimitiveState { cull_mode: None, @@ -235,6 +237,7 @@ impl Vger { depth_stencil: None, multisample: wgpu::MultisampleState::default(), multiview: None, + cache: None, }); let layout = Layout::new(CoordinateSystem::PositiveYUp); @@ -546,8 +549,8 @@ impl Vger { prim.start = self.scenes[self.cur_scene].cvs.len() as u32; let mut x_interval = Interval { - a: std::f32::MAX, - b: std::f32::MIN, + a: f32::MAX, + b: f32::MIN, }; let mut index = self.path_scanner.first; @@ -591,7 +594,8 @@ impl Vger { ); } - pub fn render_glyph<'a>( + #[allow(clippy::too_many_arguments)] + pub fn render_glyph( &mut self, x: f32, y: f32, @@ -630,6 +634,7 @@ impl Vger { } } + #[allow(clippy::too_many_arguments)] pub fn render_svg( &mut self, x: f32, @@ -747,8 +752,7 @@ impl Vger { size: u32, max_width: Option, ) -> Vec { - let mut rects = vec![]; - rects.reserve(text.len()); + let mut rects = Vec::with_capacity(text.len()); self.setup_layout(text, size, max_width); @@ -776,8 +780,7 @@ impl Vger { self.setup_layout(text, size, max_width); let s = 1.0 / self.device_px_ratio; - let mut rects = vec![]; - rects.reserve(text.len()); + let mut rects = Vec::with_capacity(text.len()); let glyphs = self.layout.glyphs(); @@ -912,21 +915,16 @@ impl Vger { } } -#[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +#[derive(Hash, Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Default)] #[repr(u8)] pub enum SubpixelOffset { + #[default] Zero = 0, Quarter = 1, Half = 2, ThreeQuarters = 3, } -impl Default for SubpixelOffset { - fn default() -> Self { - SubpixelOffset::Zero - } -} - impl SubpixelOffset { // Skia quantizes subpixel offsets into 1/4 increments. // Given the absolute position, return the quantized increment diff --git a/src/path.rs b/src/path.rs index 2bb927a..b62d379 100644 --- a/src/path.rs +++ b/src/path.rs @@ -111,7 +111,7 @@ impl PathScanner { } pub fn next(&mut self) -> bool { - let y = self.nodes[self.index as usize].coord; + let y = self.nodes[self.index].coord; self.interval.a = y; let n = self.nodes.len(); diff --git a/tests/common.rs b/tests/common.rs index 1e589d5..27dcddb 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,13 +1,14 @@ use futures::executor::block_on; use std::fs::File; use vger::*; +use wgpu::StoreOp; pub async fn setup() -> (wgpu::Device, wgpu::Queue) { let instance_desc = wgpu::InstanceDescriptor::default(); let instance = wgpu::Instance::new(instance_desc); - let adapter = wgpu::util::initialize_adapter_from_env_or_default(&instance, wgpu::Backends::all(), None) + let adapter = wgpu::util::initialize_adapter_from_env_or_default(&instance, None) .await .expect("No suitable GPU adapters found on the system!"); @@ -17,11 +18,7 @@ pub async fn setup() -> (wgpu::Device, wgpu::Queue) { let trace_dir = std::env::var("WGPU_TRACE"); adapter .request_device( - &wgpu::DeviceDescriptor { - label: None, - features: wgpu::Features::default(), - limits: wgpu::Limits::default(), - }, + &wgpu::DeviceDescriptor::default(), trace_dir.ok().as_ref().map(std::path::Path::new), ) .await @@ -60,8 +57,8 @@ pub async fn create_png( let mut png_encoder = png::Encoder::new( File::create(png_output_path).unwrap(), - texture_extent.width as u32, - texture_extent.height as u32, + texture_extent.width, + texture_extent.height, ); png_encoder.set_depth(png::BitDepth::Eight); png_encoder.set_color(match texture_descriptor.format { @@ -115,9 +112,7 @@ fn get_texture_data( buffer: &output_buffer, layout: wgpu::ImageDataLayout { offset: 0, - bytes_per_row: Some( - std::num::NonZeroU32::new(texture_extent.width * bytes_per_pixel).unwrap(), - ), + bytes_per_row: Some(texture_extent.width * bytes_per_pixel), rows_per_image: None, }, }, @@ -173,10 +168,12 @@ pub fn render_test( resolve_target: None, ops: wgpu::Operations { load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), - store: true, + store: StoreOp::Store, }, })], depth_stencil_attachment: None, + occlusion_query_set: None, + timestamp_writes: None, }; vger.encode(device, &desc, queue);