chore(deps): move pf-console-ui from skia-safe 0.87 to 0.99
Twelve skia-safe releases (0.88 … 0.99), carrying Skia milestones 140 through 150, every one of them breaking under 0.x semver. Only three of those changes actually reach this crate — the Vulkan surface/backend-texture path, the textlayout/paragraph typography and RuntimeEffect all came through untouched: * m143 (skia-safe 0.91) DELETED SkPath's mutating API. `Path::new()` followed by `move_to`/`line_to`/`arc_to`/`close` no longer compiles at all — geometry is built through `PathBuilder` now and frozen with `snapshot()`/`detach()`. That is the entire error list: 34 E0599s over eight call sites (the hint-bar triangles and the PlayStation triangle in `glyphs.rs`, the chevron / space / backspace / check icons in `widgets.rs`, the padlock shackle in `screens/home.rs`). Each becomes a `PathBuilder` detached at the draw call, so the path is still built and thrown away once per draw exactly as before. * 0.93 deprecated the `gradient_shader` module in favour of `gradient`. Only a warning, but the Format/clippy gate runs `-D warnings`, so it is a hard break for us. The three gradients — the panel stroke in `theme.rs`, the connect-overlay vignette in `shell/overlays.rs`, the host monogram in `screens/home.rs` — now build a `gradient::Gradient` from `gradient::Colors::new_evenly_spaced` plus `Interpolation::default()`. That default (unpremul interpolation, destination colour space, shorter hue) is what the old `flags: None` argument mapped to, so the pixels do not move. The new API takes `Color4f` directly, which drops the `.to_color()` 8-bit round-trip the old signature forced. * 0.98 deprecated `vk::BackendContext::new` in favour of a builder (upstream #1292). `skia_overlay.rs` now calls `BackendContext::new_builder(...)` + `build()`, passing `max_api_version: None` so Skia keeps deriving its cap from `vkEnumerateInstanceVersion()` — bit-for-bit what `new()` passed. `build()` is the unsafe half, so the SAFETY proof moved down onto it. `ash` is untouched and stays on the workspace's exact `=0.38.0+1.3.281` pin: skia-safe lists ash only as a DEV dependency, so the bump cannot reach it. The prebuilt-binary assumption still holds — verified from the build log, not from the release page: skia-bindings printed `DOWNLOAD AND INSTALL SUCCEEDED` for `skia-binaries-a25a0fdb7d90429aa2d1-x86_64-unknown-linux-gnu-jpegd-jpege-pdf-textlayout-vulkan`, so no CI leg compiles Skia from source. The asset name DID change: `jpeg` joined skia-safe's default feature set between 0.87 and 0.99, so `jpegd-jpege` is now in the name. We take defaults, so the JPEG codecs came along — which is a fix in disguise, since `screens/library.rs` hands host poster art straight to `Image::from_encoded`, and JPEG posters used to fall out as "undecodable". The Cargo.toml comment now records the verified asset names and the silent-source- build trap for the next bump. Verified on 192.168.1.21, x86_64-unknown-linux-gnu, toolchain 1.96.0: cargo build -p pf-console-ui exit 0 cargo clippy -p pf-console-ui --all-targets -- -D warnings exit 0 cargo test -p pf-console-ui 82 passed, 1 ignored cargo fmt --all --check exit 0
This commit is contained in:
Generated
+8
-63
@@ -3454,7 +3454,7 @@ version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f"
|
||||
dependencies = [
|
||||
"toml_edit 0.25.13+spec-1.1.0",
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4524,15 +4524,6 @@ dependencies = [
|
||||
"syn 3.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.1.1"
|
||||
@@ -4636,30 +4627,28 @@ checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
|
||||
|
||||
[[package]]
|
||||
name = "skia-bindings"
|
||||
version = "0.87.0"
|
||||
version = "0.99.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "704242769235d2ffe66a2a0a3002661262fc4af08d32807c362d7b0160ee703c"
|
||||
checksum = "3e2d1c3ebd697c0cbded0145e9204a38fa6b268446051b7196d0a096414ea7f3"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
"flate2",
|
||||
"heck",
|
||||
"lazy_static",
|
||||
"pkg-config",
|
||||
"regex",
|
||||
"serde_json",
|
||||
"tar",
|
||||
"toml 0.8.23",
|
||||
"toml 1.1.4+spec-1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "skia-safe"
|
||||
version = "0.87.0"
|
||||
version = "0.99.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f7d94f3e7537c71ad4cf132eb26e3be8c8a886ed3649c4525c089041fc312b2"
|
||||
checksum = "9f512ac418a64194842dd05566320805dad1c957c521039db2486fd6368865bc"
|
||||
dependencies = [
|
||||
"bitflags 2.13.1",
|
||||
"lazy_static",
|
||||
"skia-bindings",
|
||||
]
|
||||
|
||||
@@ -5039,18 +5028,6 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned 0.6.9",
|
||||
"toml_datetime 0.6.11",
|
||||
"toml_edit 0.22.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.12+spec-1.1.0"
|
||||
@@ -5059,7 +5036,7 @@ checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned 1.1.1",
|
||||
"serde_spanned",
|
||||
"toml_datetime 0.7.5+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
@@ -5074,22 +5051,13 @@ checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned 1.1.1",
|
||||
"serde_spanned",
|
||||
"toml_datetime 1.1.1+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.5+spec-1.1.0"
|
||||
@@ -5108,20 +5076,6 @@ dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned 0.6.9",
|
||||
"toml_datetime 0.6.11",
|
||||
"toml_write",
|
||||
"winnow 0.7.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.25.13+spec-1.1.0"
|
||||
@@ -5143,12 +5097,6 @@ dependencies = [
|
||||
"winnow 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_write"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
@@ -6169,9 +6117,6 @@ name = "winnow"
|
||||
version = "0.7.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
|
||||
@@ -22,7 +22,18 @@ pf-client-core = { path = "../pf-client-core", default-features = false }
|
||||
# the typography the console library needs (~15 MB stripped, prebuilt binaries exist for
|
||||
# this feature set on x86_64-unknown-linux-gnu AND x86_64-pc-windows-msvc — a source
|
||||
# build is never triggered on either).
|
||||
skia-safe = { version = "0.87", features = ["vulkan", "textlayout"] }
|
||||
#
|
||||
# The prebuilt-binary claim is the whole reason this dep is affordable, so re-verify it on
|
||||
# EVERY bump: the build log must say `DOWNLOAD AND INSTALL SUCCEEDED`. skia-bindings does not
|
||||
# fail when no matching asset exists — it silently falls back to a gn/ninja build of Skia from
|
||||
# source, which turns a 2-minute CI leg into a multi-hour one. Verified at 0.99.0, both targets:
|
||||
# skia-binaries-a25a0fdb7d90429aa2d1-<target>-jpegd-jpege-pdf-textlayout-vulkan.tar.gz
|
||||
# ⚠ The asset name CHANGED across this bump — at 0.87 it was `<target>-pdf-textlayout-vulkan`,
|
||||
# because `jpeg` was not yet in skia-safe's DEFAULT feature set (0.87: binary-cache, embed-icudtl,
|
||||
# pdf; 0.99: + jpeg). We take defaults, so the JPEG codecs came along with the bump. That is a
|
||||
# feature here rather than bloat: `screens/library.rs` feeds host poster art straight to
|
||||
# `Image::from_encoded`, which silently returned `None` for JPEG posters before.
|
||||
skia-safe = { version = "0.99", features = ["vulkan", "textlayout"] }
|
||||
ash = { version = "0.38", features = ["loaded"] }
|
||||
|
||||
anyhow = "1"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
use crate::theme::{fg, Fonts, W};
|
||||
use punktfunk_core::config::GamepadPref;
|
||||
use skia_safe::{Canvas, Paint, Path, Point, RRect, Rect};
|
||||
use skia_safe::{Canvas, Paint, PathBuilder, Point, RRect, Rect};
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
pub(crate) enum GlyphStyle {
|
||||
@@ -294,12 +294,12 @@ fn draw_glyph(
|
||||
let r = BADGE_D * k / 2.0;
|
||||
let (cx, cyf) = ((x + r) as f32, cy as f32);
|
||||
let (tw, th) = ((5.5 * k) as f32, (4.5 * k) as f32);
|
||||
let mut up = Path::new();
|
||||
let mut up = PathBuilder::new();
|
||||
up.move_to((cx, cyf - th));
|
||||
up.line_to((cx - tw, cyf + th));
|
||||
up.line_to((cx + tw, cyf + th));
|
||||
up.close();
|
||||
canvas.draw_path(&up, &Paint::new(fg(0.85), None));
|
||||
canvas.draw_path(&up.detach(), &Paint::new(fg(0.85), None));
|
||||
}
|
||||
Resolved::Adjust => {
|
||||
// ◀ ▶ — two small solid triangles.
|
||||
@@ -308,18 +308,18 @@ fn draw_glyph(
|
||||
let (tw, th) = ((4.5 * k) as f32, (5.5 * k) as f32);
|
||||
let gap = (2.6 * k) as f32;
|
||||
let paint = Paint::new(fg(0.85), None);
|
||||
let mut left = Path::new();
|
||||
let mut left = PathBuilder::new();
|
||||
left.move_to((cx - gap, cyf - th));
|
||||
left.line_to((cx - gap - tw, cyf));
|
||||
left.line_to((cx - gap, cyf + th));
|
||||
left.close();
|
||||
canvas.draw_path(&left, &paint);
|
||||
let mut right = Path::new();
|
||||
canvas.draw_path(&left.detach(), &paint);
|
||||
let mut right = PathBuilder::new();
|
||||
right.move_to((cx + gap, cyf - th));
|
||||
right.line_to((cx + gap + tw, cyf));
|
||||
right.line_to((cx + gap, cyf + th));
|
||||
right.close();
|
||||
canvas.draw_path(&right, &paint);
|
||||
canvas.draw_path(&right.detach(), &paint);
|
||||
}
|
||||
Resolved::Key(text) => {
|
||||
let w = keycap_w(fonts, text, k);
|
||||
@@ -377,12 +377,12 @@ fn draw_ps_shape(canvas: &Canvas, face: Face, center: Point, r: f32, stroke: f32
|
||||
}
|
||||
Face::Y => {
|
||||
// △
|
||||
let mut tri = Path::new();
|
||||
let mut tri = PathBuilder::new();
|
||||
tri.move_to((cx, cy - r * 1.2));
|
||||
tri.line_to((cx + r * 1.15, cy + r * 0.85));
|
||||
tri.line_to((cx - r * 1.15, cy + r * 0.85));
|
||||
tri.close();
|
||||
canvas.draw_path(&tri, &p);
|
||||
canvas.draw_path(&tri.detach(), &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::pointer::{Pointer, PointerKind};
|
||||
use crate::screens::{ConnectIntent, Ctx, Outbox, Screen};
|
||||
use crate::theme::{accent, fg, Fonts, PanelStroke, ONLINE_GREEN, W};
|
||||
use pf_client_core::gamepad::{MenuDir, MenuEvent, MenuPulse};
|
||||
use skia_safe::{Canvas, Color4f, MaskFilter, Paint, Path, Point, RRect, Rect};
|
||||
use skia_safe::{Canvas, Color4f, MaskFilter, Paint, PathBuilder, Point, RRect, Rect};
|
||||
|
||||
const TILE_W: f64 = 340.0;
|
||||
const TILE_H: f64 = 224.0;
|
||||
@@ -526,18 +526,20 @@ fn draw_monogram(canvas: &Canvas, fonts: &Fonts, name: &str, filled: bool, x: f6
|
||||
let rr = RRect::new_rect_xy(badge, (15.0 * k) as f32, (15.0 * k) as f32);
|
||||
if filled {
|
||||
let mut p = Paint::default();
|
||||
p.set_shader(skia_safe::gradient_shader::linear(
|
||||
let colors = [accent(1.0), accent(0.68)];
|
||||
p.set_shader(skia_safe::gradient::shaders::linear_gradient(
|
||||
(
|
||||
Point::new(badge.left, badge.top),
|
||||
Point::new(badge.left, badge.bottom),
|
||||
),
|
||||
skia_safe::gradient_shader::GradientShaderColors::Colors(&[
|
||||
accent(1.0).to_color(),
|
||||
accent(0.68).to_color(),
|
||||
]),
|
||||
None,
|
||||
skia_safe::TileMode::Clamp,
|
||||
None,
|
||||
&skia_safe::gradient::Gradient::new(
|
||||
skia_safe::gradient::Colors::new_evenly_spaced(
|
||||
&colors,
|
||||
skia_safe::TileMode::Clamp,
|
||||
None,
|
||||
),
|
||||
skia_safe::gradient::Interpolation::default(),
|
||||
),
|
||||
None,
|
||||
));
|
||||
canvas.draw_rrect(rr, &p);
|
||||
@@ -586,7 +588,7 @@ fn draw_lock(canvas: &Canvas, x: f64, y: f64, k: f64) {
|
||||
p.set_style(skia_safe::PaintStyle::Stroke);
|
||||
p.set_stroke_width((1.6 * k) as f32);
|
||||
p.set_anti_alias(true);
|
||||
let mut shackle = Path::new();
|
||||
let mut shackle = PathBuilder::new();
|
||||
let (cx, r) = (x + body_w / 2.0, 3.2 * k);
|
||||
shackle.move_to(((cx - r) as f32, body_top as f32));
|
||||
shackle.arc_to(
|
||||
@@ -600,7 +602,7 @@ fn draw_lock(canvas: &Canvas, x: f64, y: f64, k: f64) {
|
||||
180.0,
|
||||
false,
|
||||
);
|
||||
canvas.draw_path(&shackle, &p);
|
||||
canvas.draw_path(&shackle.detach(), &p);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::anim::{approach, ease_out_cubic};
|
||||
use crate::glyphs::{hint_bar, Hint, HintKey};
|
||||
use crate::theme::{fg, Fonts, PanelStroke, W};
|
||||
use skia_safe::{gradient_shader, Canvas, Paint, Point, Rect, TileMode};
|
||||
use skia_safe::{gradient, Canvas, Paint, Point, Rect, TileMode};
|
||||
|
||||
use super::{Shell, BOTTOM_BAND};
|
||||
|
||||
@@ -170,16 +170,16 @@ impl Shell {
|
||||
// A soft pool of shade under the centre seats the text against a bright field —
|
||||
// dark on a dark palette, light on a pale one, so it always separates.
|
||||
let mut vignette = Paint::default();
|
||||
vignette.set_shader(gradient_shader::radial(
|
||||
Point::new(cx as f32, (h / 2.0) as f32),
|
||||
(w.max(h) * 0.42) as f32,
|
||||
gradient_shader::GradientShaderColors::Colors(&[
|
||||
crate::theme::shade(0.5).to_color(),
|
||||
crate::theme::shade(0.0).to_color(),
|
||||
]),
|
||||
None,
|
||||
TileMode::Clamp,
|
||||
None,
|
||||
let shades = [crate::theme::shade(0.5), crate::theme::shade(0.0)];
|
||||
vignette.set_shader(gradient::shaders::radial_gradient(
|
||||
(
|
||||
Point::new(cx as f32, (h / 2.0) as f32),
|
||||
(w.max(h) * 0.42) as f32,
|
||||
),
|
||||
&gradient::Gradient::new(
|
||||
gradient::Colors::new_evenly_spaced(&shades, TileMode::Clamp, None),
|
||||
gradient::Interpolation::default(),
|
||||
),
|
||||
None,
|
||||
));
|
||||
canvas.draw_rect(Rect::from_wh(w as f32, h as f32), &vignette);
|
||||
|
||||
@@ -236,21 +236,25 @@ impl Overlay for SkiaOverlay {
|
||||
}
|
||||
}
|
||||
};
|
||||
let backend_builder = skvk::BackendContext::new_builder(
|
||||
shared.instance.handle().as_raw() as _,
|
||||
shared.physical_device.as_raw() as _,
|
||||
shared.device.handle().as_raw() as _,
|
||||
(
|
||||
shared.queue.as_raw() as _,
|
||||
shared.queue_family_index as usize,
|
||||
),
|
||||
&get_proc,
|
||||
// `None` leaves Skia's `fMaxAPIVersion` at its `0` sentinel, so it caps entry-point
|
||||
// validation at whatever `vkEnumerateInstanceVersion()` reports — byte-for-byte what
|
||||
// the (now removed) `BackendContext::new` did. The presenter owns the instance and its
|
||||
// `VkApplicationInfo`, so pinning a version here would just duplicate its choice.
|
||||
None,
|
||||
);
|
||||
// SAFETY: the instance/physical-device/device handles come from `shared`, which owns them
|
||||
// and outlives this backend context, and `get_proc` above resolves through those same
|
||||
// handles. Skia stores them but does not take ownership — teardown stays ours.
|
||||
let backend = unsafe {
|
||||
skvk::BackendContext::new(
|
||||
shared.instance.handle().as_raw() as _,
|
||||
shared.physical_device.as_raw() as _,
|
||||
shared.device.handle().as_raw() as _,
|
||||
(
|
||||
shared.queue.as_raw() as _,
|
||||
shared.queue_family_index as usize,
|
||||
),
|
||||
&get_proc,
|
||||
)
|
||||
};
|
||||
let backend = unsafe { backend_builder.build() };
|
||||
let mut context = gpu::direct_contexts::make_vulkan(&backend, None)
|
||||
.ok_or_else(|| anyhow!("Skia DirectContext over the shared device"))?;
|
||||
context.set_resource_cache_limit(RESOURCE_CACHE_BYTES);
|
||||
|
||||
@@ -10,8 +10,8 @@ use skia_safe::textlayout::{
|
||||
FontCollection, ParagraphBuilder, ParagraphStyle, TextAlign, TextStyle, TypefaceFontProvider,
|
||||
};
|
||||
use skia_safe::{
|
||||
gradient_shader, Canvas, Color4f, Font, FontMgr, FontStyle, MaskFilter, Paint, PathEffect,
|
||||
Point, RRect, Rect, TileMode, Typeface,
|
||||
gradient, Canvas, Color4f, Font, FontMgr, FontStyle, MaskFilter, Paint, PathEffect, Point,
|
||||
RRect, Rect, TileMode, Typeface,
|
||||
};
|
||||
|
||||
// --- Ink ----------------------------------------------------------------------------------
|
||||
@@ -166,18 +166,16 @@ pub(crate) fn panel(
|
||||
sp.set_color4f(accent(alpha), None);
|
||||
}
|
||||
PanelStroke::Gradient | PanelStroke::GradientDashed => {
|
||||
sp.set_shader(gradient_shader::linear(
|
||||
let colors = [fg(0.22), fg(0.04)];
|
||||
sp.set_shader(gradient::shaders::linear_gradient(
|
||||
(
|
||||
Point::new(rect.left, rect.top),
|
||||
Point::new(rect.left, rect.bottom),
|
||||
),
|
||||
gradient_shader::GradientShaderColors::Colors(&[
|
||||
fg(0.22).to_color(),
|
||||
fg(0.04).to_color(),
|
||||
]),
|
||||
None,
|
||||
TileMode::Clamp,
|
||||
None,
|
||||
&gradient::Gradient::new(
|
||||
gradient::Colors::new_evenly_spaced(&colors, TileMode::Clamp, None),
|
||||
gradient::Interpolation::default(),
|
||||
),
|
||||
None,
|
||||
));
|
||||
if matches!(stroke, PanelStroke::GradientDashed) {
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::library::{BUMP_C, BUMP_K};
|
||||
use crate::pointer::{Pointer, PointerKind};
|
||||
use crate::theme::{accent, fg, Fonts, PanelStroke, W};
|
||||
use pf_client_core::gamepad::{MenuDir, MenuEvent, MenuPulse};
|
||||
use skia_safe::{Canvas, Paint, Path, RRect, Rect};
|
||||
use skia_safe::{Canvas, Paint, PathBuilder, RRect, Rect};
|
||||
|
||||
// --- Menu list -----------------------------------------------------------------------------
|
||||
|
||||
@@ -479,11 +479,11 @@ fn chevron(canvas: &Canvas, x: f64, cy: f64, r: f64, left: bool, alpha: f32) {
|
||||
p.set_stroke_width((1.8 * r / 4.0) as f32);
|
||||
p.set_stroke_cap(skia_safe::PaintCap::Round);
|
||||
p.set_anti_alias(true);
|
||||
let mut path = Path::new();
|
||||
let mut path = PathBuilder::new();
|
||||
path.move_to(((x - dir * r / 2.0) as f32, (cy - r) as f32));
|
||||
path.line_to(((x + dir * r / 2.0) as f32, cy as f32));
|
||||
path.line_to(((x - dir * r / 2.0) as f32, (cy + r) as f32));
|
||||
canvas.draw_path(&path, &p);
|
||||
canvas.draw_path(&path.detach(), &p);
|
||||
}
|
||||
|
||||
// --- On-screen keyboard ----------------------------------------------------------------------
|
||||
@@ -785,12 +785,12 @@ fn draw_space_icon(canvas: &Canvas, cx: f64, cy: f64, k: f64, ink: skia_safe::Co
|
||||
// ⎵ — an underline bracket.
|
||||
let (w, h) = (16.0 * k, 5.0 * k);
|
||||
let p = stroke_paint(ink, (1.6 * k) as f32);
|
||||
let mut path = Path::new();
|
||||
let mut path = PathBuilder::new();
|
||||
path.move_to(((cx - w / 2.0) as f32, (cy - h / 2.0) as f32));
|
||||
path.line_to(((cx - w / 2.0) as f32, (cy + h / 2.0) as f32));
|
||||
path.line_to(((cx + w / 2.0) as f32, (cy + h / 2.0) as f32));
|
||||
path.line_to(((cx + w / 2.0) as f32, (cy - h / 2.0) as f32));
|
||||
canvas.draw_path(&path, &p);
|
||||
canvas.draw_path(&path.detach(), &p);
|
||||
}
|
||||
|
||||
fn draw_backspace_icon(canvas: &Canvas, cx: f64, cy: f64, k: f64, ink: skia_safe::Color4f) {
|
||||
@@ -799,14 +799,14 @@ fn draw_backspace_icon(canvas: &Canvas, cx: f64, cy: f64, k: f64, ink: skia_safe
|
||||
let nose = 6.0 * k;
|
||||
let p = stroke_paint(ink, (1.6 * k) as f32);
|
||||
let (l, r, t, b) = (cx - w / 2.0, cx + w / 2.0, cy - h / 2.0, cy + h / 2.0);
|
||||
let mut path = Path::new();
|
||||
let mut path = PathBuilder::new();
|
||||
path.move_to(((l + nose) as f32, t as f32));
|
||||
path.line_to((r as f32, t as f32));
|
||||
path.line_to((r as f32, b as f32));
|
||||
path.line_to(((l + nose) as f32, b as f32));
|
||||
path.line_to((l as f32, cy as f32));
|
||||
path.close();
|
||||
canvas.draw_path(&path, &p);
|
||||
canvas.draw_path(&path.detach(), &p);
|
||||
let (xc, xr) = (cx + nose / 2.0, 2.6 * k);
|
||||
canvas.draw_line(
|
||||
((xc - xr) as f32, (cy - xr) as f32),
|
||||
@@ -823,11 +823,11 @@ fn draw_backspace_icon(canvas: &Canvas, cx: f64, cy: f64, k: f64, ink: skia_safe
|
||||
fn draw_check(canvas: &Canvas, cx: f64, cy: f64, k: f64, ink: skia_safe::Color4f) {
|
||||
let p = stroke_paint(ink, (1.8 * k) as f32);
|
||||
let r = 5.0 * k;
|
||||
let mut path = Path::new();
|
||||
let mut path = PathBuilder::new();
|
||||
path.move_to(((cx - r) as f32, cy as f32));
|
||||
path.line_to(((cx - r * 0.25) as f32, (cy + r * 0.7) as f32));
|
||||
path.line_to(((cx + r) as f32, (cy - r * 0.7) as f32));
|
||||
canvas.draw_path(&path, &p);
|
||||
canvas.draw_path(&path.detach(), &p);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user