mirror of
https://github.com/slint-ui/slint.git
synced 2025-12-04 09:02:55 +00:00
Generate registration code for custom fonts imported in .60 files
This removes the need to manually register fonts. This is initially applied to the printer demo, but the other demos and removal of the public manual registration API will come in follow-up commits.
This commit is contained in:
parent
c301cc22b5
commit
f7ce1ba8b4
13 changed files with 138 additions and 30 deletions
|
|
@ -15,9 +15,6 @@ if (NOT TARGET SixtyFPS::SixtyFPS)
|
|||
endif()
|
||||
|
||||
add_executable(printerdemo main.cpp)
|
||||
target_compile_definitions(printerdemo PRIVATE
|
||||
FONTS_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../ui/fonts\"
|
||||
)
|
||||
if (MSVC)
|
||||
target_compile_options(printerdemo PRIVATE /bigobj)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -22,12 +22,6 @@ struct InkLevelModel : sixtyfps::Model<InkLevel>
|
|||
|
||||
int main()
|
||||
{
|
||||
if (auto error = sixtyfps::register_font_from_path(FONTS_DIR "/NotoSans-Regular.ttf")) {
|
||||
fprintf(stderr, "Error registering Noto Sans Regular font: %s\n", error->data());
|
||||
}
|
||||
if (auto error = sixtyfps::register_font_from_path(FONTS_DIR "/NotoSans-Bold.ttf")) {
|
||||
fprintf(stderr, "Error registering Noto Sans Bold font: %s\n", error->data());
|
||||
}
|
||||
auto printer_demo = MainWindow::create();
|
||||
printer_demo->set_ink_levels(std::make_shared<InkLevelModel>());
|
||||
printer_demo->on_quit([] { std::exit(0); });
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ endif()
|
|||
|
||||
add_executable(printerdemo_interpreted main.cpp)
|
||||
target_compile_definitions(printerdemo_interpreted PRIVATE
|
||||
FONTS_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../ui/fonts\"
|
||||
SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"
|
||||
)
|
||||
if (MSVC)
|
||||
|
|
|
|||
|
|
@ -35,13 +35,6 @@ private:
|
|||
|
||||
int main()
|
||||
{
|
||||
if (auto error = sixtyfps::register_font_from_path(FONTS_DIR "/NotoSans-Regular.ttf")) {
|
||||
fprintf(stderr, "Error registering Noto Sans Regular font: %s\n", error->data());
|
||||
}
|
||||
if (auto error = sixtyfps::register_font_from_path(FONTS_DIR "/NotoSans-Bold.ttf")) {
|
||||
fprintf(stderr, "Error registering Noto Sans Bold font: %s\n", error->data());
|
||||
}
|
||||
|
||||
sixtyfps::interpreter::ComponentCompiler compiler;
|
||||
auto definition = compiler.build_from_path(SOURCE_DIR "/../ui/printerdemo.60");
|
||||
|
||||
|
|
|
|||
|
|
@ -12,14 +12,6 @@ LICENSE END */
|
|||
const path = require("path");
|
||||
let sixtyfps = require("sixtyfps");
|
||||
|
||||
try {
|
||||
for (font_file of ["NotoSans-Regular.ttf", "NotoSans-Bold.ttf"]) {
|
||||
sixtyfps.register_font_from_path(path.resolve(__dirname, "../ui/fonts", font_file));
|
||||
}
|
||||
} catch (load_exception) {
|
||||
console.error(load_exception);
|
||||
}
|
||||
|
||||
let demo = require("../ui/printerdemo.60");
|
||||
let window = new demo.MainWindow();
|
||||
|
||||
|
|
|
|||
|
|
@ -41,11 +41,6 @@ pub fn main() {
|
|||
#[cfg(all(debug_assertions, target_arch = "wasm32"))]
|
||||
console_error_panic_hook::set_once();
|
||||
|
||||
sixtyfps::register_font_from_memory(include_bytes!("../ui/fonts/NotoSans-Regular.ttf"))
|
||||
.expect("error registering noto sans regular");
|
||||
sixtyfps::register_font_from_memory(include_bytes!("../ui/fonts/NotoSans-Bold.ttf"))
|
||||
.expect("error registering noto sans bold");
|
||||
|
||||
let main_window = MainWindow::new();
|
||||
main_window.set_ink_levels(sixtyfps::VecModel::from_slice(&[
|
||||
InkLevel { color: sixtyfps::Color::from_rgb_u8(0, 255, 255), level: 0.40 },
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ import { HomePage } from "./home_page.60";
|
|||
import { InkLevel, InkPage } from "./ink_page.60";
|
||||
import { SettingsPage } from "./settings_page.60";
|
||||
|
||||
import "./fonts/NotoSans-Regular.ttf";
|
||||
import "./fonts/NotoSans-Bold.ttf";
|
||||
|
||||
SideBarIcon := Rectangle {
|
||||
property <bool> active;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ pub enum BuiltinFunction {
|
|||
ColorDarker,
|
||||
Rgb,
|
||||
ImplicitItemSize,
|
||||
RegisterCustomFontByPath,
|
||||
RegisterCustomFontByMemory,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -119,6 +121,12 @@ impl BuiltinFunction {
|
|||
return_type: Box::new(Type::Color),
|
||||
args: vec![Type::Int32, Type::Int32, Type::Int32, Type::Float32],
|
||||
},
|
||||
BuiltinFunction::RegisterCustomFontByPath => {
|
||||
Type::Function { return_type: Box::new(Type::Void), args: vec![Type::String] }
|
||||
}
|
||||
BuiltinFunction::RegisterCustomFontByMemory => {
|
||||
Type::Function { return_type: Box::new(Type::Void), args: vec![Type::Int32] }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1439,6 +1439,12 @@ fn compile_expression(
|
|||
BuiltinFunction::Rgb => {
|
||||
"[](int r, int g, int b, float a) {{ return sixtyfps::Color::from_argb_uint8(std::clamp(a * 255., 0., 255.), std::clamp(r, 0, 255), std::clamp(g, 0, 255), std::clamp(b, 0, 255)); }}".into()
|
||||
}
|
||||
BuiltinFunction::RegisterCustomFontByPath => {
|
||||
panic!("internal error: RegisterCustomFontByPath can only be evaluated from within a FunctionCall expression")
|
||||
}
|
||||
BuiltinFunction::RegisterCustomFontByMemory => {
|
||||
panic!("embedding fonts is not supported in C++ yet")
|
||||
}
|
||||
},
|
||||
Expression::ElementReference(_) => todo!("Element references are only supported in the context of built-in function calls at the moment"),
|
||||
Expression::MemberFunction { .. } => panic!("member function expressions must not appear in the code generator anymore"),
|
||||
|
|
@ -1574,6 +1580,16 @@ fn compile_expression(
|
|||
panic!("internal error: argument to ImplicitItemSize must be an element")
|
||||
}
|
||||
}
|
||||
Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByPath) => {
|
||||
if arguments.len() != 1 {
|
||||
panic!("internal error: incorrect argument count to RegisterCustomFontByPath call");
|
||||
}
|
||||
if let Expression::StringLiteral(font_path) = &arguments[0] {
|
||||
format!("sixtyfps::register_font_from_path(\"{}\");", font_path)
|
||||
} else {
|
||||
panic!("internal error: argument to RegisterCustomFontByPath must be a string literal")
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let mut args = arguments.iter().map(|e| compile_expression(e, component));
|
||||
|
||||
|
|
|
|||
|
|
@ -1123,6 +1123,12 @@ fn compile_expression(expr: &Expression, component: &Rc<Component>) -> TokenStre
|
|||
sixtyfps::re_exports::Color::from_argb_u8(a, r, g, b)
|
||||
}))
|
||||
}
|
||||
BuiltinFunction::RegisterCustomFontByPath => {
|
||||
panic!("internal error: BuiltinFunction::RegisterCustomFontByPath can only be compiled as part of a FunctionCall expression")
|
||||
}
|
||||
BuiltinFunction::RegisterCustomFontByMemory => {
|
||||
panic!("internal error: BuiltinFunction::RegisterCustomFontByMemory can only be compiled as part of a FunctionCall expression")
|
||||
}
|
||||
},
|
||||
Expression::ElementReference(_) => todo!("Element references are only supported in the context of built-in function calls at the moment"),
|
||||
Expression::MemberFunction{ .. } => panic!("member function expressions must not appear in the code generator anymore"),
|
||||
|
|
@ -1232,6 +1238,28 @@ fn compile_expression(expr: &Expression, component: &Rc<Component>) -> TokenStre
|
|||
panic!("internal error: argument to ImplicitItemSize must be an element")
|
||||
}
|
||||
}
|
||||
Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByPath) => {
|
||||
if arguments.len() != 1 {
|
||||
panic!("internal error: incorrect argument count to RegisterCustomFontByPath call");
|
||||
}
|
||||
if let Expression::StringLiteral(path) = &arguments[0] {
|
||||
quote!(sixtyfps::register_font_from_path(&std::path::PathBuf::from(#path)))
|
||||
} else {
|
||||
panic!("internal error: argument to RegisterCustomFontByPath must be a string literal")
|
||||
}
|
||||
}
|
||||
Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByMemory) => {
|
||||
if arguments.len() != 1 {
|
||||
panic!("internal error: incorrect argument count to RegisterCustomFontByMemory call");
|
||||
}
|
||||
if let Expression::NumberLiteral(resource_id, _) = &arguments[0] {
|
||||
let resource_id: usize = *resource_id as _;
|
||||
let symbol = format_ident!("SFPS_EMBEDDED_RESOURCE_{}", resource_id);
|
||||
quote!(sixtyfps::register_font_from_memory(#symbol.into()))
|
||||
} else {
|
||||
panic!("internal error: argument to RegisterCustomFontByMemory must be a number")
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let f = compile_expression(function, &component);
|
||||
let a = arguments.iter().map(|a| compile_expression(a, &component));
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ mod passes {
|
|||
pub mod apply_default_properties_from_style;
|
||||
pub mod check_expressions;
|
||||
pub mod clip;
|
||||
pub mod collect_custom_fonts;
|
||||
pub mod collect_globals;
|
||||
pub mod collect_structs;
|
||||
pub mod compile_paths;
|
||||
|
|
@ -192,6 +193,11 @@ pub async fn run_passes(
|
|||
passes::collect_globals::collect_globals(&doc.root_component, diag);
|
||||
passes::collect_structs::collect_structs(&doc.root_component, diag);
|
||||
passes::generate_item_indices::generate_item_indices(&doc.root_component);
|
||||
passes::collect_custom_fonts::collect_custom_fonts(
|
||||
&doc.root_component,
|
||||
std::iter::once(&*doc).chain(type_loader.all_documents()),
|
||||
compiler_config.embed_resources,
|
||||
);
|
||||
}
|
||||
|
||||
mod library {
|
||||
|
|
|
|||
67
sixtyfps_compiler/passes/collect_custom_fonts.rs
Normal file
67
sixtyfps_compiler/passes/collect_custom_fonts.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* LICENSE BEGIN
|
||||
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
||||
Copyright (c) 2020 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
||||
Copyright (c) 2020 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-only
|
||||
This file is also available under commercial licensing terms.
|
||||
Please contact info@sixtyfps.io for more information.
|
||||
LICENSE END */
|
||||
|
||||
//! Passes that fills the root component used_global
|
||||
|
||||
use crate::{
|
||||
expression_tree::{BuiltinFunction, Expression, Unit},
|
||||
object_tree::*,
|
||||
};
|
||||
use std::collections::BTreeSet;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Fill the root_component's used_globals
|
||||
pub fn collect_custom_fonts<'a>(
|
||||
root_component: &Rc<Component>,
|
||||
all_docs: impl Iterator<Item = &'a crate::object_tree::Document> + 'a,
|
||||
embed_fonts: bool,
|
||||
) {
|
||||
let mut all_fonts = BTreeSet::new();
|
||||
|
||||
for doc in all_docs {
|
||||
all_fonts.extend(doc.custom_fonts.iter())
|
||||
}
|
||||
|
||||
let registration_function = if embed_fonts {
|
||||
Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByMemory)
|
||||
} else {
|
||||
Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByPath)
|
||||
};
|
||||
|
||||
let prepare_font_registration_argument: Box<dyn Fn(&String) -> Expression> = if embed_fonts {
|
||||
Box::new(|font_path| {
|
||||
Expression::NumberLiteral(
|
||||
{
|
||||
let mut resources = root_component.embedded_file_resources.borrow_mut();
|
||||
let resource_id = match resources.get(font_path) {
|
||||
Some(id) => *id,
|
||||
None => {
|
||||
let id = resources.len();
|
||||
resources.insert(font_path.clone(), id);
|
||||
id
|
||||
}
|
||||
};
|
||||
resource_id as _
|
||||
},
|
||||
Unit::None,
|
||||
)
|
||||
})
|
||||
} else {
|
||||
Box::new(|font_path| Expression::StringLiteral(font_path.clone()))
|
||||
};
|
||||
|
||||
root_component.setup_code.borrow_mut().extend(all_fonts.into_iter().map(|font_path| {
|
||||
Expression::FunctionCall {
|
||||
function: Box::new(registration_function.clone()),
|
||||
arguments: vec![prepare_font_registration_argument(font_path)],
|
||||
source_location: None,
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
@ -421,6 +421,17 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) ->
|
|||
panic!("internal error: argument to ImplicitItemWidth must be an element")
|
||||
}
|
||||
}
|
||||
Expression::BuiltinFunctionReference(BuiltinFunction::RegisterCustomFontByPath) => {
|
||||
if arguments.len() != 1 {
|
||||
panic!("internal error: incorrect argument count to RegisterCustomFontByPath")
|
||||
}
|
||||
if let Value::String(s) = eval_expression(&arguments[0], local_context) {
|
||||
crate::register_font_from_path(&std::path::PathBuf::from(s.as_str())).ok().unwrap();
|
||||
Value::Void
|
||||
} else {
|
||||
panic!("Argument not a string");
|
||||
}
|
||||
}
|
||||
_ => panic!("call of something not a callback"),
|
||||
}
|
||||
Expression::SelfAssignment { lhs, rhs, op } => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue