diff --git a/Cargo.lock b/Cargo.lock index 26659a805..a9881fcf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4201,7 +4201,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.5.5" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=7c20aa7#7c20aa7fad405845c5bd5cdcc2a232cdc2a4687d" +source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=1109d52#1109d52f65ae8f00d75f43445908bff48807c0c5" dependencies = [ "ahash 0.8.12", "anyhow", @@ -4224,7 +4224,7 @@ dependencies = [ [[package]] name = "opencadgraph" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=1543a5a#1543a5aeb0b871a2f23a3b55117c7f5af1e1d229" +source = "git+https://github.com/HakanSeven12/opencadgraph.git?rev=3c4af1c#3c4af1c3bdebc968630ad3c28046173bed0aa200" dependencies = [ "opencadkernel", "serde_json", @@ -4233,7 +4233,7 @@ dependencies = [ [[package]] name = "opencadkernel" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=d71a828#d71a8284f0388025e07f219c7b8f6bb86e7188ec" +source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=8a246b0#8a246b0026fb9c626a39a6ba8ccf681f1bf0461e" dependencies = [ "cavalier_contours", "opencadcodec", @@ -4244,7 +4244,7 @@ dependencies = [ [[package]] name = "opencadkernel-constraints" version = "0.1.0" -source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=d71a828#d71a8284f0388025e07f219c7b8f6bb86e7188ec" +source = "git+https://github.com/HakanSeven12/opencadkernel.git?rev=8a246b0#8a246b0026fb9c626a39a6ba8ccf681f1bf0461e" dependencies = [ "nalgebra", ] diff --git a/Cargo.toml b/Cargo.toml index 7ad93dc7e..d6cc5899f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,10 +33,10 @@ rfd = "0.17" clap = { version = "4", features = ["derive", "string"] } env_logger = "0.11" log = "0.4" -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "7c20aa7", features = ["serde"] } -kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "d71a828", features = ["acis", "offset"] } -kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "d71a828" } -graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "1543a5a" } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "1109d52", features = ["serde"] } +kernel = { package = "opencadkernel", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "8a246b0", features = ["acis", "offset"] } +kernel-constraints = { package = "opencadkernel-constraints", git = "https://github.com/HakanSeven12/opencadkernel.git", rev = "8a246b0" } +graph = { package = "opencadgraph", git = "https://github.com/HakanSeven12/opencadgraph.git", rev = "3c4af1c" } dwg-thumbnailer = { path = "crates/dwg-thumbnailer" } flate2 = "1" image = { version = "0.25", default-features = false, features = ["png", "jpeg", "bmp", "tiff"] } diff --git a/crates/ocs_plugin_api/Cargo.toml b/crates/ocs_plugin_api/Cargo.toml index 91efdc937..e160ec5d1 100644 --- a/crates/ocs_plugin_api/Cargo.toml +++ b/crates/ocs_plugin_api/Cargo.toml @@ -15,7 +15,7 @@ serde_json = { version = "1", optional = true } # Pulled in only by the `host` feature, which adds the `opencadcodec`-typed # `HostApi` runtime surface. The default crate stays dependency-free so engine # crates and external tooling can depend on the manifest/ribbon contract cheaply. -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "7c20aa7", optional = true, features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "1109d52", optional = true, features = ["serde"] } # Runtime IPC and serialization (host feature only). interprocess = { version = "2", optional = true } @@ -39,7 +39,7 @@ serde_json = "1" serde = { version = "1", features = ["derive"] } cargo-lock = "11" # opencadcodec is scanned at build time to generate the embedded type registry. -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "7c20aa7", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "1109d52", features = ["serde"] } [dev-dependencies] serde_json = "1" diff --git a/crates/ocs_web_worker/Cargo.toml b/crates/ocs_web_worker/Cargo.toml index 229386607..8dc3430c2 100644 --- a/crates/ocs_web_worker/Cargo.toml +++ b/crates/ocs_web_worker/Cargo.toml @@ -8,7 +8,7 @@ publish = false crate-type = ["cdylib"] [dependencies] -codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "7c20aa7", features = ["serde"] } +codec = { package = "opencadcodec", git = "https://github.com/HakanSeven12/opencadcodec.git", rev = "1109d52", features = ["serde"] } bincode = "1.3" serde = { version = "1", features = ["derive"] } console_error_panic_hook = "0.1" diff --git a/plugins/opencad-python/Cargo.lock b/plugins/opencad-python/Cargo.lock index 039e59eaf..fe0b3cc43 100644 --- a/plugins/opencad-python/Cargo.lock +++ b/plugins/opencad-python/Cargo.lock @@ -1265,7 +1265,7 @@ dependencies = [ [[package]] name = "opencadcodec" version = "0.5.5" -source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=7c20aa7#7c20aa7fad405845c5bd5cdcc2a232cdc2a4687d" +source = "git+https://github.com/HakanSeven12/opencadcodec.git?rev=1109d52#1109d52f65ae8f00d75f43445908bff48807c0c5" dependencies = [ "ahash 0.8.12", "anyhow", diff --git a/src/entities/text_support.rs b/src/entities/text_support.rs index 1682852d3..a80735e18 100644 --- a/src/entities/text_support.rs +++ b/src/entities/text_support.rs @@ -214,7 +214,7 @@ pub fn text_local_bounds( max_y = max_y.max(sy); } } - cursor_x += glyph.advance + face.letter_spacing(); + cursor_x += glyph.advance + face.spacing_after(ch); } None => { cursor_x += 6.0 + face.letter_spacing(); @@ -964,7 +964,7 @@ pub fn measure_word( let mut w = 0.0_f32; for ch in text.chars() { w += match face.glyph(ch) { - Some(g) => (g.advance + face.letter_spacing() * state.tracking) * scale, + Some(g) => (g.advance + face.spacing_after(ch) * state.tracking) * scale, None => (6.0 + face.letter_spacing() * state.tracking) * scale, }; } @@ -2315,7 +2315,7 @@ pub fn layout_mtext(opts: &MTextRenderOpts) -> MTextLayout { for (ci, ch) in text.chars().enumerate() { let adv = match face.glyph(ch) { Some(g) => { - (g.advance + face.letter_spacing() * tracking) * scale + (g.advance + face.spacing_after(ch) * tracking) * scale } None => (6.0 + face.letter_spacing() * tracking) * scale, }; diff --git a/src/scene/text/font_face.rs b/src/scene/text/font_face.rs index 42d29cbdb..10041a874 100644 --- a/src/scene/text/font_face.rs +++ b/src/scene/text/font_face.rs @@ -158,6 +158,25 @@ impl Face { } } + /// [`letter_spacing`](Self::letter_spacing) after the glyph drawn for + /// `ch`: a stroke font's tracking belongs to its own glyphs only. A + /// big-font glyph's advance already carries its gap and a TrueType + /// stand-in's its side bearings, so tracking them too spread CJK text + /// by a third of the height per character (#1470). + pub fn spacing_after(&self, ch: char) -> f32 { + match self { + Face::Lff(f) if f.glyph(ch).is_none() => 0.0, + Face::WithBig { primary, big } => { + if ttf_glyph::is_full_width(ch) && shx::bigfont_glyph(big, ch).is_some() { + 0.0 + } else { + primary.spacing_after(ch) + } + } + _ => self.letter_spacing(), + } + } + /// Width of a space (9-unit). pub fn word_spacing(&self) -> f32 { match self { diff --git a/src/scene/text/glyph_quads.rs b/src/scene/text/glyph_quads.rs index 2256a5da1..ffe4d5109 100644 --- a/src/scene/text/glyph_quads.rs +++ b/src/scene/text/glyph_quads.rs @@ -143,12 +143,14 @@ pub fn layout_glyph_quads( uv_min: e.uv_min, uv_max: e.uv_max, }); - cursor_x += e.advance + face.letter_spacing() * tracking; + cursor_x += e.advance + face.spacing_after(ch) * tracking; } None => { // No ink (whitespace glyph) or atlas full: advance only. - let adv = face.glyph(ch).map(|g| g.advance).unwrap_or(6.0); - cursor_x += adv + face.letter_spacing() * tracking; + cursor_x += match face.glyph(ch) { + Some(g) => g.advance + face.spacing_after(ch) * tracking, + None => 6.0 + face.letter_spacing() * tracking, + }; } } } diff --git a/src/scene/text/lff.rs b/src/scene/text/lff.rs index 8f93a3a73..0fe1f877b 100644 --- a/src/scene/text/lff.rs +++ b/src/scene/text/lff.rs @@ -441,7 +441,7 @@ pub fn tessellate_text_run( Some(glyph) => { emit_glyph(out, &glyph.strokes, *cursor_x); emit_fill(fill_tris, &glyph.fill_tris, *cursor_x); - *cursor_x += glyph.advance + face.letter_spacing() * tracking; + *cursor_x += glyph.advance + face.spacing_after(ch) * tracking; } None => { warn_missing_glyph(font_name, ch); @@ -470,7 +470,7 @@ pub fn tessellate_text_run( Some(glyph) => { emit_glyph(&mut out, &glyph.strokes, cursor_x); emit_fill(&mut fill_tris, &glyph.fill_tris, cursor_x); - cursor_x += glyph.advance + face.letter_spacing() * tracking; + cursor_x += glyph.advance + face.spacing_after(*c) * tracking; } None => { warn_missing_glyph(font_name, *c);