mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
app: remove old TEXT_CTX and replace with parley new pattern
This commit is contained in:
@@ -115,7 +115,6 @@ impl God {
|
|||||||
// Abort the application on panic right away
|
// Abort the application on panic right away
|
||||||
std::panic::set_hook(Box::new(panic_hook));
|
std::panic::set_hook(Box::new(panic_hook));
|
||||||
|
|
||||||
text::init_txt_ctx();
|
|
||||||
let file_logging_guard = logger::setup_logging();
|
let file_logging_guard = logger::setup_logging();
|
||||||
|
|
||||||
info!(target: "main", "Creating the app");
|
info!(target: "main", "Creating the app");
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use crate::{
|
|||||||
gfx::Point,
|
gfx::Point,
|
||||||
mesh::Color,
|
mesh::Color,
|
||||||
prop::{PropertyAtomicGuard, PropertyColor, PropertyFloat32, PropertyStr},
|
prop::{PropertyAtomicGuard, PropertyColor, PropertyFloat32, PropertyStr},
|
||||||
text::{TextContext, TEXT_CTX},
|
text,
|
||||||
};
|
};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
@@ -111,8 +111,7 @@ impl Editor {
|
|||||||
underlines.push(compose_start..compose_end);
|
underlines.push(compose_start..compose_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut txt_ctx = TEXT_CTX.get().await;
|
self.layout = text::make_layout(
|
||||||
self.layout = txt_ctx.make_layout(
|
|
||||||
&self.state.text,
|
&self.state.text,
|
||||||
text_color,
|
text_color,
|
||||||
font_size,
|
font_size,
|
||||||
@@ -175,7 +174,7 @@ impl Editor {
|
|||||||
|
|
||||||
pub fn driver<'a>(
|
pub fn driver<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
_txt_ctx: &'a mut TextContext,
|
_layout_ctx: &'a mut parley::LayoutContext<Color>,
|
||||||
) -> Option<parley::PlainEditorDriver<'a, Color>> {
|
) -> Option<parley::PlainEditorDriver<'a, Color>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use crate::{
|
|||||||
gfx::Point,
|
gfx::Point,
|
||||||
mesh::Color,
|
mesh::Color,
|
||||||
prop::{PropertyAtomicGuard, PropertyColor, PropertyFloat32, PropertyStr},
|
prop::{PropertyAtomicGuard, PropertyColor, PropertyFloat32, PropertyStr},
|
||||||
text::{TextContext, FONT_STACK, TEXT_CTX},
|
text::{self, FONT_STACK},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
@@ -83,9 +83,11 @@ impl Editor {
|
|||||||
styles.insert(parley::StyleProperty::OverflowWrap(parley::OverflowWrap::Anywhere));
|
styles.insert(parley::StyleProperty::OverflowWrap(parley::OverflowWrap::Anywhere));
|
||||||
*self.editor.edit_styles() = styles;
|
*self.editor.edit_styles() = styles;
|
||||||
|
|
||||||
let mut txt_ctx = TEXT_CTX.get().await;
|
let mut font_ctx = text::GLOBAL_FONT_CTX.clone();
|
||||||
let (font_ctx, layout_ctx) = txt_ctx.borrow();
|
text::THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
self.editor.refresh_layout(font_ctx, layout_ctx);
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
|
self.editor.refresh_layout(&mut font_ctx, &mut layout_ctx);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&self) -> &parley::Layout<Color> {
|
pub fn layout(&self) -> &parley::Layout<Color> {
|
||||||
@@ -106,19 +108,20 @@ impl Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert(&mut self, txt: &str, atom: &mut PropertyAtomicGuard) {
|
pub async fn insert(&mut self, txt: &str, atom: &mut PropertyAtomicGuard) {
|
||||||
let mut txt_ctx = TEXT_CTX.get().await;
|
text::THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
let (font_ctx, layout_ctx) = txt_ctx.borrow();
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
let mut drv = self.editor.driver(font_ctx, layout_ctx);
|
let mut drv = self.driver(&mut layout_ctx);
|
||||||
drv.insert_or_replace_selection(&txt);
|
drv.insert_or_replace_selection(&txt);
|
||||||
self.on_buffer_changed(atom).await;
|
self.on_buffer_changed(atom).await;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn driver<'a>(
|
pub fn driver<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
txt_ctx: &'a mut TextContext,
|
layout_ctx: &'a mut parley::LayoutContext<Color>,
|
||||||
) -> Option<parley::PlainEditorDriver<'a, Color>> {
|
) -> Option<parley::PlainEditorDriver<'a, Color>> {
|
||||||
let (font_ctx, layout_ctx) = txt_ctx.borrow();
|
let mut font_ctx = text::GLOBAL_FONT_CTX.clone();
|
||||||
Some(self.editor.driver(font_ctx, layout_ctx))
|
Some(self.editor.driver(&mut font_ctx, layout_ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_width(&mut self, w: f32) {
|
pub fn set_width(&mut self, w: f32) {
|
||||||
@@ -141,10 +144,11 @@ impl Editor {
|
|||||||
/// Android uses byte indexes whereas parley has its own things. So this API is a compromise
|
/// Android uses byte indexes whereas parley has its own things. So this API is a compromise
|
||||||
/// between them both.
|
/// between them both.
|
||||||
pub async fn set_selection(&mut self, select_start: usize, select_end: usize) {
|
pub async fn set_selection(&mut self, select_start: usize, select_end: usize) {
|
||||||
let mut txt_ctx = TEXT_CTX.get().await;
|
text::THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
let (font_ctx, layout_ctx) = txt_ctx.borrow();
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
let mut drv = self.editor.driver(font_ctx, layout_ctx);
|
let mut drv = self.driver(&mut layout_ctx);
|
||||||
drv.select_byte_range(select_start, select_end);
|
drv.select_byte_range(select_start, select_end);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
@@ -16,12 +16,15 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use async_lock::Mutex as AsyncMutex;
|
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
ops::Range,
|
ops::Range,
|
||||||
sync::{Arc, OnceLock},
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use fontique::{Collection, CollectionOptions, SourceCache, SourceCacheOptions};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
use crate::{mesh::Color, util::spawn_thread};
|
use crate::{mesh::Color, util::spawn_thread};
|
||||||
|
|
||||||
pub mod atlas;
|
pub mod atlas;
|
||||||
@@ -30,107 +33,84 @@ pub use editor::Editor;
|
|||||||
mod render;
|
mod render;
|
||||||
pub use render::{render_layout, render_layout_with_opts, DebugRenderOptions};
|
pub use render::{render_layout, render_layout_with_opts, DebugRenderOptions};
|
||||||
|
|
||||||
use darkfi::system::CondVar;
|
// Global shared FontContext (thread-safe via internal Arc<Mutex<>>)
|
||||||
|
pub static GLOBAL_FONT_CTX: Lazy<parley::FontContext> = Lazy::new(|| {
|
||||||
pub struct AsyncGlobal<T> {
|
let collection = Collection::new(CollectionOptions {
|
||||||
cv: CondVar,
|
shared: true,
|
||||||
val: OnceLock<AsyncMutex<T>>,
|
system_fonts: false,
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> AsyncGlobal<T> {
|
|
||||||
const fn new() -> Self {
|
|
||||||
Self { cv: CondVar::new(), val: OnceLock::new() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set(&self, val: T) {
|
|
||||||
self.val.set(AsyncMutex::new(val)).ok().unwrap();
|
|
||||||
self.cv.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get<'a>(&'a self) -> async_lock::MutexGuard<'a, T> {
|
|
||||||
self.cv.wait().await;
|
|
||||||
self.val.get().unwrap().lock().await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub static TEXT_CTX: AsyncGlobal<TextContext> = AsyncGlobal::new();
|
|
||||||
|
|
||||||
pub fn init_txt_ctx() {
|
|
||||||
spawn_thread("init_txt_ctx", || {
|
|
||||||
// This is quite slow. It takes 300ms
|
|
||||||
let txt_ctx = TextContext::new();
|
|
||||||
TEXT_CTX.set(txt_ctx);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let source_cache = SourceCache::new(SourceCacheOptions {
|
||||||
|
shared: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut font_ctx = parley::FontContext { collection, source_cache };
|
||||||
|
|
||||||
|
let font_data = include_bytes!("../../ibm-plex-mono-regular.otf") as &[u8];
|
||||||
|
font_ctx.collection.register_fonts(
|
||||||
|
peniko::Blob::new(Arc::new(font_data)),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
|
||||||
|
let font_data = include_bytes!("../../NotoColorEmoji.ttf") as &[u8];
|
||||||
|
font_ctx.collection.register_fonts(
|
||||||
|
peniko::Blob::new(Arc::new(font_data)),
|
||||||
|
None
|
||||||
|
);
|
||||||
|
|
||||||
|
font_ctx
|
||||||
|
});
|
||||||
|
|
||||||
|
// Thread-local LayoutContext
|
||||||
|
thread_local! {
|
||||||
|
pub static THREAD_LAYOUT_CTX: RefCell<parley::LayoutContext<'static, Color>> =
|
||||||
|
RefCell::new(parley::LayoutContext::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializing this is expensive ~300ms, but storage is ~2kb.
|
// Public constants
|
||||||
/// It has to be created once and reused. Currently we use thread local storage.
|
pub const FONT_STACK: &[parley::FontFamily<'_>] = &[
|
||||||
pub struct TextContext {
|
parley::FontFamily::Named(std::borrow::Cow::Borrowed("IBM Plex Mono")),
|
||||||
font_ctx: parley::FontContext,
|
parley::FontFamily::Named(std::borrow::Cow::Borrowed("Noto Color Emoji")),
|
||||||
layout_ctx: parley::LayoutContext<Color>,
|
];
|
||||||
|
|
||||||
|
// FREE FUNCTIONS (no TextContext wrapper!)
|
||||||
|
pub fn make_layout(
|
||||||
|
text: &str,
|
||||||
|
text_color: Color,
|
||||||
|
font_size: f32,
|
||||||
|
lineheight: f32,
|
||||||
|
window_scale: f32,
|
||||||
|
width: Option<f32>,
|
||||||
|
underlines: &[Range<usize>],
|
||||||
|
) -> parley::Layout<Color> {
|
||||||
|
make_layout2(
|
||||||
|
text,
|
||||||
|
text_color,
|
||||||
|
font_size,
|
||||||
|
lineheight,
|
||||||
|
window_scale,
|
||||||
|
width,
|
||||||
|
underlines,
|
||||||
|
&[],
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextContext {
|
pub fn make_layout2(
|
||||||
fn new() -> Self {
|
text: &str,
|
||||||
let layout_ctx = parley::LayoutContext::new();
|
text_color: Color,
|
||||||
let mut font_ctx = parley::FontContext::new();
|
font_size: f32,
|
||||||
|
lineheight: f32,
|
||||||
|
window_scale: f32,
|
||||||
|
width: Option<f32>,
|
||||||
|
underlines: &[Range<usize>],
|
||||||
|
foreground_colors: &[(Range<usize>, Color)],
|
||||||
|
) -> parley::Layout<Color> {
|
||||||
|
THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
|
let mut font_ctx = GLOBAL_FONT_CTX.clone();
|
||||||
|
|
||||||
let font_data = include_bytes!("../../ibm-plex-mono-regular.otf") as &[u8];
|
|
||||||
let _font_inf =
|
|
||||||
font_ctx.collection.register_fonts(peniko::Blob::new(Arc::new(font_data)), None);
|
|
||||||
|
|
||||||
let font_data = include_bytes!("../../NotoColorEmoji.ttf") as &[u8];
|
|
||||||
let _font_inf =
|
|
||||||
font_ctx.collection.register_fonts(peniko::Blob::new(Arc::new(font_data)), None);
|
|
||||||
|
|
||||||
//for (family_id, _) in font_inf {
|
|
||||||
// let family_name = font_ctx.collection.family_name(family_id).unwrap();
|
|
||||||
// trace!(target: "text", "Loaded font: {family_name}");
|
|
||||||
//}
|
|
||||||
|
|
||||||
Self { font_ctx, layout_ctx }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
pub fn borrow(&mut self) -> (&mut parley::FontContext, &mut parley::LayoutContext<Color>) {
|
|
||||||
(&mut self.font_ctx, &mut self.layout_ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn make_layout(
|
|
||||||
&mut self,
|
|
||||||
text: &str,
|
|
||||||
text_color: Color,
|
|
||||||
font_size: f32,
|
|
||||||
lineheight: f32,
|
|
||||||
window_scale: f32,
|
|
||||||
width: Option<f32>,
|
|
||||||
underlines: &[Range<usize>],
|
|
||||||
) -> parley::Layout<Color> {
|
|
||||||
self.make_layout2(
|
|
||||||
text,
|
|
||||||
text_color,
|
|
||||||
font_size,
|
|
||||||
lineheight,
|
|
||||||
window_scale,
|
|
||||||
width,
|
|
||||||
underlines,
|
|
||||||
&[],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn make_layout2(
|
|
||||||
&mut self,
|
|
||||||
text: &str,
|
|
||||||
text_color: Color,
|
|
||||||
font_size: f32,
|
|
||||||
lineheight: f32,
|
|
||||||
window_scale: f32,
|
|
||||||
width: Option<f32>,
|
|
||||||
underlines: &[Range<usize>],
|
|
||||||
foreground_colors: &[(Range<usize>, Color)],
|
|
||||||
) -> parley::Layout<Color> {
|
|
||||||
let mut builder =
|
let mut builder =
|
||||||
self.layout_ctx.ranged_builder(&mut self.font_ctx, &text, window_scale, false);
|
layout_ctx.ranged_builder(&mut font_ctx, text, window_scale, false);
|
||||||
builder.push_default(parley::LineHeight::FontSizeRelative(lineheight));
|
builder.push_default(parley::LineHeight::FontSizeRelative(lineheight));
|
||||||
builder.push_default(parley::StyleProperty::FontSize(font_size));
|
builder.push_default(parley::StyleProperty::FontSize(font_size));
|
||||||
builder.push_default(parley::StyleProperty::FontStack(parley::FontStack::List(
|
builder.push_default(parley::StyleProperty::FontStack(parley::FontStack::List(
|
||||||
@@ -147,14 +127,9 @@ impl TextContext {
|
|||||||
builder.push(parley::StyleProperty::Brush(*color), range.clone());
|
builder.push(parley::StyleProperty::Brush(*color), range.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut layout: parley::Layout<Color> = builder.build(&text);
|
let mut layout: parley::Layout<Color> = builder.build(text);
|
||||||
layout.break_all_lines(width);
|
layout.break_all_lines(width);
|
||||||
layout.align(width, parley::Alignment::Start, parley::AlignmentOptions::default());
|
layout.align(width, parley::Alignment::Start, parley::AlignmentOptions::default());
|
||||||
layout
|
layout
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const FONT_STACK: &[parley::FontFamily<'_>] = &[
|
|
||||||
parley::FontFamily::Named(std::borrow::Cow::Borrowed("IBM Plex Mono")),
|
|
||||||
parley::FontFamily::Named(std::borrow::Cow::Borrowed("Noto Color Emoji")),
|
|
||||||
];
|
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ impl PrivMessage {
|
|||||||
|
|
||||||
fn cache_txt_layout(
|
fn cache_txt_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
txt_ctx: &mut text::TextContext,
|
|
||||||
clip: &Rectangle,
|
clip: &Rectangle,
|
||||||
line_height: f32,
|
line_height: f32,
|
||||||
timestamp_width: f32,
|
timestamp_width: f32,
|
||||||
@@ -130,7 +129,7 @@ impl PrivMessage {
|
|||||||
let nick_color = select_nick_color(&self.nick, nick_colors);
|
let nick_color = select_nick_color(&self.nick, nick_colors);
|
||||||
|
|
||||||
let txt_layout = if self.nick == "NOTICE" {
|
let txt_layout = if self.nick == "NOTICE" {
|
||||||
txt_ctx.make_layout(
|
text::make_layout(
|
||||||
&linetext,
|
&linetext,
|
||||||
text_color,
|
text_color,
|
||||||
self.font_size,
|
self.font_size,
|
||||||
@@ -142,7 +141,7 @@ impl PrivMessage {
|
|||||||
} else {
|
} else {
|
||||||
let body_color = if self.confirmed { text_color } else { UNCONF_COLOR };
|
let body_color = if self.confirmed { text_color } else { UNCONF_COLOR };
|
||||||
let nick_end = self.nick.len() + 1;
|
let nick_end = self.nick.len() + 1;
|
||||||
txt_ctx.make_layout2(
|
text::make_layout2(
|
||||||
&linetext,
|
&linetext,
|
||||||
body_color,
|
body_color,
|
||||||
self.font_size,
|
self.font_size,
|
||||||
@@ -173,11 +172,9 @@ impl PrivMessage {
|
|||||||
return instrs.clone()
|
return instrs.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
|
|
||||||
// Timestamp layout
|
// Timestamp layout
|
||||||
let timestr = Self::gen_timestr(self.timestamp);
|
let timestr = Self::gen_timestr(self.timestamp);
|
||||||
let timestamp_layout = txt_ctx.make_layout(
|
let timestamp_layout = text::make_layout(
|
||||||
×tr,
|
×tr,
|
||||||
timestamp_color,
|
timestamp_color,
|
||||||
self.timestamp_font_size,
|
self.timestamp_font_size,
|
||||||
@@ -188,7 +185,6 @@ impl PrivMessage {
|
|||||||
);
|
);
|
||||||
|
|
||||||
self.cache_txt_layout(
|
self.cache_txt_layout(
|
||||||
&mut txt_ctx,
|
|
||||||
clip,
|
clip,
|
||||||
line_height,
|
line_height,
|
||||||
timestamp_width,
|
timestamp_width,
|
||||||
@@ -196,8 +192,6 @@ impl PrivMessage {
|
|||||||
text_color,
|
text_color,
|
||||||
);
|
);
|
||||||
|
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
let mut all_instrs = vec![];
|
let mut all_instrs = vec![];
|
||||||
|
|
||||||
// Draw selection background if selected
|
// Draw selection background if selected
|
||||||
@@ -307,8 +301,7 @@ impl DateMessage {
|
|||||||
|
|
||||||
let datestr = Self::datestr(self.timestamp);
|
let datestr = Self::datestr(self.timestamp);
|
||||||
|
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
let layout = text::make_layout(
|
||||||
let layout = txt_ctx.make_layout(
|
|
||||||
&datestr,
|
&datestr,
|
||||||
timestamp_color,
|
timestamp_color,
|
||||||
self.font_size,
|
self.font_size,
|
||||||
@@ -317,7 +310,6 @@ impl DateMessage {
|
|||||||
None,
|
None,
|
||||||
&[],
|
&[],
|
||||||
);
|
);
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
let mut instrs = text::render_layout(&layout, render_api, gfxtag!("chatview_datemsg"));
|
let mut instrs = text::render_layout(&layout, render_api, gfxtag!("chatview_datemsg"));
|
||||||
// Cache the instructions
|
// Cache the instructions
|
||||||
@@ -519,9 +511,8 @@ impl FileMessage {
|
|||||||
let file_strs = Self::filestr(&self.file_url, &self.status);
|
let file_strs = Self::filestr(&self.file_url, &self.status);
|
||||||
|
|
||||||
let mut layouts = Vec::with_capacity(file_strs.len());
|
let mut layouts = Vec::with_capacity(file_strs.len());
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
for file_str in &file_strs {
|
for file_str in &file_strs {
|
||||||
let layout = txt_ctx.make_layout(
|
let layout = text::make_layout(
|
||||||
file_str,
|
file_str,
|
||||||
color,
|
color,
|
||||||
self.font_size,
|
self.font_size,
|
||||||
@@ -532,7 +523,6 @@ impl FileMessage {
|
|||||||
);
|
);
|
||||||
layouts.push(layout);
|
layouts.push(layout);
|
||||||
}
|
}
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
all_instrs
|
all_instrs
|
||||||
.push(DrawInstruction::Move(Point::new(timestamp_width + Self::BOX_PADDING_X, 0.)));
|
.push(DrawInstruction::Move(Point::new(timestamp_width + Self::BOX_PADDING_X, 0.)));
|
||||||
@@ -654,7 +644,6 @@ impl Message {
|
|||||||
|
|
||||||
fn cache_txt_layout(
|
fn cache_txt_layout(
|
||||||
&mut self,
|
&mut self,
|
||||||
txt_ctx: &mut text::TextContext,
|
|
||||||
clip: &Rectangle,
|
clip: &Rectangle,
|
||||||
line_height: f32,
|
line_height: f32,
|
||||||
timestamp_width: f32,
|
timestamp_width: f32,
|
||||||
@@ -664,7 +653,6 @@ impl Message {
|
|||||||
match self {
|
match self {
|
||||||
Self::Priv(m) => {
|
Self::Priv(m) => {
|
||||||
m.cache_txt_layout(
|
m.cache_txt_layout(
|
||||||
txt_ctx,
|
|
||||||
clip,
|
clip,
|
||||||
line_height,
|
line_height,
|
||||||
timestamp_width,
|
timestamp_width,
|
||||||
@@ -871,16 +859,13 @@ impl MessageBuffer {
|
|||||||
height += msg_spacing;
|
height += msg_spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
msg.cache_txt_layout(
|
msg.cache_txt_layout(
|
||||||
&mut txt_ctx,
|
|
||||||
&rect,
|
&rect,
|
||||||
line_height,
|
line_height,
|
||||||
timestamp_width,
|
timestamp_width,
|
||||||
&nick_colors,
|
&nick_colors,
|
||||||
text_color,
|
text_color,
|
||||||
);
|
);
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
height += msg.height(line_height);
|
height += msg.height(line_height);
|
||||||
}
|
}
|
||||||
@@ -939,16 +924,13 @@ impl MessageBuffer {
|
|||||||
text,
|
text,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
msg.cache_txt_layout(
|
msg.cache_txt_layout(
|
||||||
&mut txt_ctx,
|
|
||||||
&rect,
|
&rect,
|
||||||
line_height,
|
line_height,
|
||||||
timestamp_width,
|
timestamp_width,
|
||||||
&nick_colors,
|
&nick_colors,
|
||||||
text_color,
|
text_color,
|
||||||
);
|
);
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
if self.msgs.is_empty() {
|
if self.msgs.is_empty() {
|
||||||
self.msgs.push(msg);
|
self.msgs.push(msg);
|
||||||
@@ -1012,16 +994,13 @@ impl MessageBuffer {
|
|||||||
text,
|
text,
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
msg.cache_txt_layout(
|
msg.cache_txt_layout(
|
||||||
&mut txt_ctx,
|
|
||||||
rect,
|
rect,
|
||||||
line_height,
|
line_height,
|
||||||
timestamp_width,
|
timestamp_width,
|
||||||
&nick_colors,
|
&nick_colors,
|
||||||
text_color,
|
text_color,
|
||||||
);
|
);
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
let msg_height = msg.height(self.line_height.get());
|
let msg_height = msg.height(self.line_height.get());
|
||||||
self.msgs.push(msg);
|
self.msgs.push(msg);
|
||||||
|
|||||||
@@ -501,6 +501,7 @@ impl BaseEdit {
|
|||||||
|
|
||||||
async fn handle_shortcut(
|
async fn handle_shortcut(
|
||||||
&self,
|
&self,
|
||||||
|
layout_ctx: &mut parley::LayoutContext<Color>,
|
||||||
key: char,
|
key: char,
|
||||||
mods: &KeyMods,
|
mods: &KeyMods,
|
||||||
atom: &mut PropertyAtomicGuard,
|
atom: &mut PropertyAtomicGuard,
|
||||||
@@ -516,9 +517,8 @@ impl BaseEdit {
|
|||||||
match key {
|
match key {
|
||||||
'a' => {
|
'a' => {
|
||||||
if action_mod {
|
if action_mod {
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
let mut editor = self.lock_editor().await;
|
let mut editor = self.lock_editor().await;
|
||||||
let mut drv = editor.driver(&mut txt_ctx).unwrap();
|
let mut drv = editor.driver(layout_ctx);
|
||||||
|
|
||||||
drv.select_all();
|
drv.select_all();
|
||||||
if let Some(seltext) = editor.selected_text() {
|
if let Some(seltext) = editor.selected_text() {
|
||||||
@@ -553,6 +553,7 @@ impl BaseEdit {
|
|||||||
|
|
||||||
async fn handle_key(
|
async fn handle_key(
|
||||||
&self,
|
&self,
|
||||||
|
layout_ctx: &mut parley::LayoutContext<Color>,
|
||||||
key: &KeyCode,
|
key: &KeyCode,
|
||||||
mods: &KeyMods,
|
mods: &KeyMods,
|
||||||
atom: &mut PropertyAtomicGuard,
|
atom: &mut PropertyAtomicGuard,
|
||||||
@@ -565,9 +566,8 @@ impl BaseEdit {
|
|||||||
|
|
||||||
t!("handle_key({:?}, {:?}) action_mod={action_mod}", key, mods);
|
t!("handle_key({:?}, {:?}) action_mod={action_mod}", key, mods);
|
||||||
|
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
let mut editor = self.lock_editor().await;
|
let mut editor = self.lock_editor().await;
|
||||||
let mut drv = editor.driver(&mut txt_ctx).unwrap();
|
let mut drv = editor.driver(layout_ctx);
|
||||||
|
|
||||||
match key {
|
match key {
|
||||||
KeyCode::Left => {
|
KeyCode::Left => {
|
||||||
@@ -1594,7 +1594,10 @@ impl UIObject for BaseEdit {
|
|||||||
if repeat {
|
if repeat {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return self.handle_shortcut(key, &mods, atom).await
|
return text::THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
|
self.handle_shortcut(&mut layout_ctx, key, &mods, atom).await
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do nothing
|
// Do nothing
|
||||||
@@ -1637,9 +1640,10 @@ impl UIObject for BaseEdit {
|
|||||||
|
|
||||||
let mut is_handled = false;
|
let mut is_handled = false;
|
||||||
for _ in 0..actions {
|
for _ in 0..actions {
|
||||||
if self.handle_key(&key, &mods, atom).await {
|
is_handled = text::THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
is_handled = true;
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
}
|
self.handle_key(&mut layout_ctx, &key, &mods, atom).await
|
||||||
|
});
|
||||||
}
|
}
|
||||||
is_handled
|
is_handled
|
||||||
}
|
}
|
||||||
@@ -1680,12 +1684,12 @@ impl UIObject for BaseEdit {
|
|||||||
// Move mouse pos within this widget
|
// Move mouse pos within this widget
|
||||||
self.abs_to_local(&mut mouse_pos);
|
self.abs_to_local(&mut mouse_pos);
|
||||||
|
|
||||||
{
|
text::THREAD_LAYOUT_CTX.with(|layout_ctx| {
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
let mut layout_ctx = layout_ctx.borrow_mut();
|
||||||
let mut editor = self.lock_editor().await;
|
let mut editor = self.lock_editor().await;
|
||||||
let mut drv = editor.driver(&mut txt_ctx).unwrap();
|
let mut drv = editor.driver(&mut layout_ctx);
|
||||||
drv.move_to_point(mouse_pos.x, mouse_pos.y);
|
drv.move_to_point(mouse_pos.x, mouse_pos.y);
|
||||||
}
|
});
|
||||||
|
|
||||||
if !self.select_text.is_null(0).unwrap() {
|
if !self.select_text.is_null(0).unwrap() {
|
||||||
self.select_text.clone().set_null(atom, Role::Internal, 0).unwrap();
|
self.select_text.clone().set_null(atom, Role::Internal, 0).unwrap();
|
||||||
|
|||||||
@@ -68,11 +68,8 @@ impl EmojiMeshes {
|
|||||||
/// Make mesh for this emoji centered at (0, 0)
|
/// Make mesh for this emoji centered at (0, 0)
|
||||||
async fn gen_emoji_mesh(&self, emoji: &str) -> DrawMesh {
|
async fn gen_emoji_mesh(&self, emoji: &str) -> DrawMesh {
|
||||||
//d!("rendering emoji: '{emoji}'");
|
//d!("rendering emoji: '{emoji}'");
|
||||||
let mut txt_ctx = text::TEXT_CTX.get().await;
|
|
||||||
|
|
||||||
// The params here don't actually matter since we're talking about BMP fixed sizes
|
// The params here don't actually matter since we're talking about BMP fixed sizes
|
||||||
let layout = txt_ctx.make_layout(emoji, COLOR_WHITE, self.emoji_size, 1., 1., None, &[]);
|
let layout = text::make_layout(emoji, COLOR_WHITE, self.emoji_size, 1., 1., None, &[]);
|
||||||
drop(txt_ctx);
|
|
||||||
|
|
||||||
let instrs = text::render_layout(&layout, &self.render_api, gfxtag!("emoji_mesh"));
|
let instrs = text::render_layout(&layout, &self.render_api, gfxtag!("emoji_mesh"));
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use crate::{
|
|||||||
PropertyRect, PropertyStr, PropertyUint32, Role,
|
PropertyRect, PropertyStr, PropertyUint32, Role,
|
||||||
},
|
},
|
||||||
scene::{Pimpl, SceneNodeWeak},
|
scene::{Pimpl, SceneNodeWeak},
|
||||||
text::{self, TEXT_CTX},
|
text,
|
||||||
util::i18n::I18nBabelFish,
|
util::i18n::I18nBabelFish,
|
||||||
ExecutorPtr,
|
ExecutorPtr,
|
||||||
};
|
};
|
||||||
@@ -123,10 +123,7 @@ impl Text {
|
|||||||
text
|
text
|
||||||
};
|
};
|
||||||
|
|
||||||
let layout = {
|
let layout = text::make_layout(&text, text_color, font_size, lineheight, window_scale, None, &[]);
|
||||||
let mut txt_ctx = TEXT_CTX.get().await;
|
|
||||||
txt_ctx.make_layout(&text, text_color, font_size, lineheight, window_scale, None, &[])
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut debug_opts = text::DebugRenderOptions::OFF;
|
let mut debug_opts = text::DebugRenderOptions::OFF;
|
||||||
if self.debug.get() {
|
if self.debug.get() {
|
||||||
|
|||||||
Reference in New Issue
Block a user