Skip to content
1 change: 1 addition & 0 deletions internal/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ path = "lib.rs"
[features]
default = []
shared-fontique = ["dep:fontique", "dep:ttf-parser"]
color-parsing = []

[dependencies]
ttf-parser = { workspace = true, optional = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,58 @@

use std::collections::HashMap;

use crate::literals::parse_color_literal;
/// Returns `0xaarrggbb`
pub fn parse_color_literal(str: &str) -> Option<u32> {
if !str.starts_with('#') {
return None;
}
if !str.is_ascii() {
return None;
}
let str = &str[1..];
let (r, g, b, a) = match str.len() {
3 => (
u8::from_str_radix(&str[0..=0], 16).ok()? * 0x11,
u8::from_str_radix(&str[1..=1], 16).ok()? * 0x11,
u8::from_str_radix(&str[2..=2], 16).ok()? * 0x11,
255u8,
),
4 => (
u8::from_str_radix(&str[0..=0], 16).ok()? * 0x11,
u8::from_str_radix(&str[1..=1], 16).ok()? * 0x11,
u8::from_str_radix(&str[2..=2], 16).ok()? * 0x11,
u8::from_str_radix(&str[3..=3], 16).ok()? * 0x11,
),
6 => (
u8::from_str_radix(&str[0..2], 16).ok()?,
u8::from_str_radix(&str[2..4], 16).ok()?,
u8::from_str_radix(&str[4..6], 16).ok()?,
255u8,
),
8 => (
u8::from_str_radix(&str[0..2], 16).ok()?,
u8::from_str_radix(&str[2..4], 16).ok()?,
u8::from_str_radix(&str[4..6], 16).ok()?,
u8::from_str_radix(&str[6..8], 16).ok()?,
),
_ => return None,
};
Some((a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32))
}

#[test]
fn test_parse_color_literal() {
assert_eq!(parse_color_literal("#abc"), Some(0xffaabbcc));
assert_eq!(parse_color_literal("#ABC"), Some(0xffaabbcc));
assert_eq!(parse_color_literal("#AbC"), Some(0xffaabbcc));
assert_eq!(parse_color_literal("#AbCd"), Some(0xddaabbcc));
assert_eq!(parse_color_literal("#01234567"), Some(0x67012345));
assert_eq!(parse_color_literal("#012345"), Some(0xff012345));
assert_eq!(parse_color_literal("_01234567"), None);
assert_eq!(parse_color_literal("→↓←"), None);
assert_eq!(parse_color_literal("#→↓←"), None);
assert_eq!(parse_color_literal("#1234567890"), None);
}

static NAMED_COLORS: std::sync::OnceLock<HashMap<&'static str, u32>> = std::sync::OnceLock::new();

Expand Down
4 changes: 3 additions & 1 deletion internal/common/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

#![doc = include_str!("README.md")]
#![doc(html_logo_url = "https://slint.dev/logo/slint-logo-square-light.svg")]
#![cfg_attr(not(feature = "shared-fontique"), no_std)]
#![cfg_attr(not(any(feature = "shared-fontique", feature = "color-parsing")), no_std)]

pub mod builtin_structs;
#[cfg(feature = "color-parsing")]
pub mod color_parsing;
pub mod enums;
pub mod key_codes;

Expand Down
2 changes: 1 addition & 1 deletion internal/compiler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ experimental-library-module = []
default = []

[dependencies]
i-slint-common = { workspace = true, features = ["default"] }
i-slint-common = { workspace = true, features = ["default", "color-parsing"] }

num_enum = "0.7"
strum = { workspace = true }
Expand Down
53 changes: 0 additions & 53 deletions internal/compiler/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,59 +7,6 @@ use itertools::Itertools;
use smol_str::SmolStr;
use strum::IntoEnumIterator;

/// Returns `0xaarrggbb`
pub fn parse_color_literal(str: &str) -> Option<u32> {
if !str.starts_with('#') {
return None;
}
if !str.is_ascii() {
return None;
}
let str = &str[1..];
let (r, g, b, a) = match str.len() {
3 => (
u8::from_str_radix(&str[0..=0], 16).ok()? * 0x11,
u8::from_str_radix(&str[1..=1], 16).ok()? * 0x11,
u8::from_str_radix(&str[2..=2], 16).ok()? * 0x11,
255u8,
),
4 => (
u8::from_str_radix(&str[0..=0], 16).ok()? * 0x11,
u8::from_str_radix(&str[1..=1], 16).ok()? * 0x11,
u8::from_str_radix(&str[2..=2], 16).ok()? * 0x11,
u8::from_str_radix(&str[3..=3], 16).ok()? * 0x11,
),
6 => (
u8::from_str_radix(&str[0..2], 16).ok()?,
u8::from_str_radix(&str[2..4], 16).ok()?,
u8::from_str_radix(&str[4..6], 16).ok()?,
255u8,
),
8 => (
u8::from_str_radix(&str[0..2], 16).ok()?,
u8::from_str_radix(&str[2..4], 16).ok()?,
u8::from_str_radix(&str[4..6], 16).ok()?,
u8::from_str_radix(&str[6..8], 16).ok()?,
),
_ => return None,
};
Some((a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32))
}

#[test]
fn test_parse_color_literal() {
assert_eq!(parse_color_literal("#abc"), Some(0xffaabbcc));
assert_eq!(parse_color_literal("#ABC"), Some(0xffaabbcc));
assert_eq!(parse_color_literal("#AbC"), Some(0xffaabbcc));
assert_eq!(parse_color_literal("#AbCd"), Some(0xddaabbcc));
assert_eq!(parse_color_literal("#01234567"), Some(0x67012345));
assert_eq!(parse_color_literal("#012345"), Some(0xff012345));
assert_eq!(parse_color_literal("_01234567"), None);
assert_eq!(parse_color_literal("→↓←"), None);
assert_eq!(parse_color_literal("#→↓←"), None);
assert_eq!(parse_color_literal("#1234567890"), None);
}

pub fn unescape_string(string: &str) -> Option<SmolStr> {
if string.contains('\n') {
// FIXME: new line in string literal not yet supported
Expand Down
8 changes: 3 additions & 5 deletions internal/compiler/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ use crate::typeregister::TypeRegister;
use smol_str::{SmolStr, ToSmolStr};
use std::cell::RefCell;

mod named_colors;

pub use named_colors::named_colors;
pub use i_slint_common::color_parsing::named_colors;

/// Contains information which allow to lookup identifier in expressions
pub struct LookupCtx<'a> {
Expand Down Expand Up @@ -619,15 +617,15 @@ impl LookupObject for ColorSpecific {
_ctx: &LookupCtx,
f: &mut impl FnMut(&SmolStr, LookupResult) -> Option<R>,
) -> Option<R> {
for (name, c) in named_colors::named_colors().iter() {
for (name, c) in named_colors().iter() {
if let Some(r) = f(&SmolStr::new_static(name), Self::as_result(*c)) {
return Some(r);
}
}
None
}
fn lookup(&self, _ctx: &LookupCtx, name: &SmolStr) -> Option<LookupResult> {
named_colors::named_colors().get(name.as_str()).map(|c| Self::as_result(*c))
named_colors().get(name.as_str()).map(|c| Self::as_result(*c))
}
}
impl ColorSpecific {
Expand Down
2 changes: 1 addition & 1 deletion internal/compiler/passes/resolving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl Expression {
),
),
SyntaxKind::ColorLiteral => Some(
crate::literals::parse_color_literal(token.text())
i_slint_common::color_parsing::parse_color_literal(token.text())
.map(|i| Expression::Cast {
from: Box::new(Expression::NumberLiteral(i as _, Unit::None)),
to: Type::Color,
Expand Down
5 changes: 3 additions & 2 deletions internal/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ raw-window-handle-06 = ["dep:raw-window-handle-06"]

experimental = []

experimental-rich-text = ["dep:pulldown-cmark"]
experimental-rich-text = ["dep:pulldown-cmark", "dep:htmlparser"]

unstable-wgpu-26 = ["dep:wgpu-26"]
unstable-wgpu-27 = ["dep:wgpu-27"]
Expand All @@ -76,7 +76,7 @@ tr = ["dep:tr"]

default = ["std", "unicode"]

shared-parley = ["shared-fontique", "dep:parley"]
shared-parley = ["shared-fontique", "dep:parley", "dep:skrifa", "experimental-rich-text", "i-slint-common/color-parsing"]

[dependencies]
i-slint-common = { workspace = true, features = ["default"] }
Expand Down Expand Up @@ -134,6 +134,7 @@ wgpu-27 = { workspace = true, optional = true }
tr = { workspace = true, optional = true }

webbrowser = { version = "1.0.6", optional = true }
htmlparser = { version = "0.2.1", optional = true }

[target.'cfg(target_family = "unix")'.dependencies]
gettext-rs = { version = "0.7.1", optional = true, features = ["gettext-system"] }
Expand Down
Loading