|
3 | 3 |
|
4 | 4 | // cspell:ignore Noto fontconfig |
5 | 5 |
|
6 | | -use crate::PhysicalLength; |
7 | 6 | use core::num::NonZeroUsize; |
8 | 7 | use femtovg::TextContext; |
9 | | -use i_slint_common::sharedfontique::{self, parley}; |
10 | | -use i_slint_core::{ |
11 | | - graphics::FontRequest, |
12 | | - items::{TextHorizontalAlignment, TextVerticalAlignment, TextWrap}, |
13 | | - lengths::LogicalLength, |
14 | | -}; |
| 8 | +use i_slint_core::textlayout::sharedparley::parley; |
15 | 9 | use std::cell::RefCell; |
16 | 10 | use std::collections::HashMap; |
17 | 11 |
|
18 | | -pub const DEFAULT_FONT_SIZE: LogicalLength = LogicalLength::new(12.); |
19 | | - |
20 | 12 | pub struct FontCache { |
21 | 13 | pub(crate) text_context: femtovg::TextContext, |
22 | 14 | fonts: HashMap<(u64, u32), femtovg::FontId>, |
@@ -45,109 +37,3 @@ impl FontCache { |
45 | 37 | thread_local! { |
46 | 38 | pub static FONT_CACHE: RefCell<FontCache> = RefCell::new(Default::default()) |
47 | 39 | } |
48 | | - |
49 | | -pub struct LayoutOptions { |
50 | | - pub max_width: Option<LogicalLength>, |
51 | | - pub max_height: Option<LogicalLength>, |
52 | | - pub horizontal_align: TextHorizontalAlignment, |
53 | | - pub vertical_align: TextVerticalAlignment, |
54 | | - pub stroke: Option<sharedfontique::BrushTextStrokeStyle>, |
55 | | - pub selection: Option<std::ops::Range<usize>>, |
56 | | - pub font_request: Option<FontRequest>, |
57 | | - pub text_wrap: TextWrap, |
58 | | -} |
59 | | - |
60 | | -impl Default for LayoutOptions { |
61 | | - fn default() -> Self { |
62 | | - Self { |
63 | | - max_width: None, |
64 | | - max_height: None, |
65 | | - horizontal_align: TextHorizontalAlignment::Left, |
66 | | - vertical_align: TextVerticalAlignment::Top, |
67 | | - stroke: None, |
68 | | - selection: None, |
69 | | - font_request: None, |
70 | | - text_wrap: TextWrap::WordWrap, |
71 | | - } |
72 | | - } |
73 | | -} |
74 | | - |
75 | | -pub fn layout(text: &str, scale_factor: f32, options: LayoutOptions) -> Layout { |
76 | | - let mut font_context = sharedfontique::font_context(); |
77 | | - let mut layout_context = sharedfontique::layout_context(); |
78 | | - |
79 | | - let mut builder = layout_context.ranged_builder(&mut font_context, text, scale_factor, true); |
80 | | - if let Some(ref font_request) = options.font_request { |
81 | | - if let Some(family) = &font_request.family { |
82 | | - builder.push_default(parley::StyleProperty::FontStack( |
83 | | - parley::style::FontStack::Single(parley::style::FontFamily::Named( |
84 | | - family.as_str().into(), |
85 | | - )), |
86 | | - )); |
87 | | - } |
88 | | - if let Some(weight) = font_request.weight { |
89 | | - builder.push_default(parley::StyleProperty::FontWeight( |
90 | | - parley::style::FontWeight::new(weight as f32), |
91 | | - )); |
92 | | - } |
93 | | - if let Some(letter_spacing) = font_request.letter_spacing { |
94 | | - builder.push_default(parley::StyleProperty::LetterSpacing(letter_spacing.get())); |
95 | | - } |
96 | | - builder.push_default(parley::StyleProperty::FontStyle(if font_request.italic { |
97 | | - parley::style::FontStyle::Italic |
98 | | - } else { |
99 | | - parley::style::FontStyle::Normal |
100 | | - })); |
101 | | - } |
102 | | - let pixel_size = options |
103 | | - .font_request |
104 | | - .and_then(|font_request| font_request.pixel_size) |
105 | | - .unwrap_or(DEFAULT_FONT_SIZE); |
106 | | - builder.push_default(parley::StyleProperty::FontSize(pixel_size.get())); |
107 | | - builder.push_default(parley::StyleProperty::WordBreak(match options.text_wrap { |
108 | | - TextWrap::NoWrap => parley::style::WordBreakStrength::KeepAll, |
109 | | - TextWrap::WordWrap => parley::style::WordBreakStrength::Normal, |
110 | | - TextWrap::CharWrap => parley::style::WordBreakStrength::BreakAll, |
111 | | - })); |
112 | | - |
113 | | - builder.push_default(parley::StyleProperty::Brush(sharedfontique::Brush { |
114 | | - stroke: options.stroke, |
115 | | - ..Default::default() |
116 | | - })); |
117 | | - if let Some(selection) = options.selection { |
118 | | - builder.push( |
119 | | - parley::StyleProperty::Brush(sharedfontique::Brush { |
120 | | - stroke: options.stroke, |
121 | | - is_selected: true, |
122 | | - }), |
123 | | - selection, |
124 | | - ); |
125 | | - } |
126 | | - |
127 | | - let mut layout: parley::Layout<sharedfontique::Brush> = builder.build(text); |
128 | | - layout.break_all_lines(options.max_width.map(|max_width| max_width.get())); |
129 | | - layout.align( |
130 | | - options.max_width.map(|max_width| max_width.get()), |
131 | | - match options.horizontal_align { |
132 | | - TextHorizontalAlignment::Left => parley::Alignment::Left, |
133 | | - TextHorizontalAlignment::Center => parley::Alignment::Middle, |
134 | | - TextHorizontalAlignment::Right => parley::Alignment::Right, |
135 | | - }, |
136 | | - parley::AlignmentOptions::default(), |
137 | | - ); |
138 | | - |
139 | | - let y_offset = match (options.max_height, options.vertical_align) { |
140 | | - (Some(max_height), TextVerticalAlignment::Center) => { |
141 | | - (max_height.get() - layout.height()) / 2.0 |
142 | | - } |
143 | | - (Some(max_height), TextVerticalAlignment::Bottom) => max_height.get() - layout.height(), |
144 | | - (None, _) | (Some(_), TextVerticalAlignment::Top) => 0.0, |
145 | | - }; |
146 | | - |
147 | | - Layout { inner: layout, y_offset } |
148 | | -} |
149 | | - |
150 | | -pub struct Layout { |
151 | | - pub inner: parley::Layout<sharedfontique::Brush>, |
152 | | - pub y_offset: f32, |
153 | | -} |
0 commit comments