Checkpoint
This commit is contained in:
parent
12ba10bc2c
commit
08464ee26e
9 changed files with 121 additions and 62 deletions
|
@ -6,8 +6,8 @@ mod mac;
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyWindowHandle, Bounds, DevicePixels, Font, FontId, FontMetrics, GlyphId, LineLayout,
|
AnyWindowHandle, Bounds, DevicePixels, Font, FontId, FontMetrics, GlyphId, MonochromeSprite,
|
||||||
MonochromeSprite, Pixels, Point, Result, Scene, SharedString, Size,
|
Pixels, Point, RasterizedGlyphId, Result, Scene, ShapedLine, SharedString, Size,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use async_task::Runnable;
|
use async_task::Runnable;
|
||||||
|
@ -146,6 +146,8 @@ pub trait PlatformWindow {
|
||||||
fn on_appearance_changed(&self, callback: Box<dyn FnMut()>);
|
fn on_appearance_changed(&self, callback: Box<dyn FnMut()>);
|
||||||
fn is_topmost_for_position(&self, position: Point<Pixels>) -> bool;
|
fn is_topmost_for_position(&self, position: Point<Pixels>) -> bool;
|
||||||
fn draw(&self, scene: Scene);
|
fn draw(&self, scene: Scene);
|
||||||
|
|
||||||
|
fn glyph_atlas(&self) -> Arc<dyn PlatformAtlas<RasterizedGlyphId>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlatformDispatcher: Send + Sync {
|
pub trait PlatformDispatcher: Send + Sync {
|
||||||
|
@ -170,7 +172,7 @@ pub trait PlatformTextSystem: Send + Sync {
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
options: RasterizationOptions,
|
options: RasterizationOptions,
|
||||||
) -> Option<(Bounds<u32>, Vec<u8>)>;
|
) -> Option<(Bounds<u32>, Vec<u8>)>;
|
||||||
fn layout_line(&self, text: &str, font_size: Pixels, runs: &[(usize, FontId)]) -> LineLayout;
|
fn layout_line(&self, text: &str, font_size: Pixels, runs: &[(usize, FontId)]) -> ShapedLine;
|
||||||
fn wrap_line(
|
fn wrap_line(
|
||||||
&self,
|
&self,
|
||||||
text: &str,
|
text: &str,
|
||||||
|
@ -180,11 +182,11 @@ pub trait PlatformTextSystem: Send + Sync {
|
||||||
) -> Vec<usize>;
|
) -> Vec<usize>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlatformAtlas<Key> {
|
pub trait PlatformAtlas<Key>: Send + Sync {
|
||||||
fn get_or_insert_with(
|
fn get_or_insert_with(
|
||||||
&self,
|
&self,
|
||||||
key: Key,
|
key: Key,
|
||||||
build: impl FnOnce() -> (Size<DevicePixels>, Vec<u8>),
|
build: &dyn Fn() -> (Size<DevicePixels>, Vec<u8>),
|
||||||
) -> AtlasTile;
|
) -> AtlasTile;
|
||||||
|
|
||||||
fn clear(&self);
|
fn clear(&self);
|
||||||
|
|
|
@ -1,35 +1,54 @@
|
||||||
use crate::{AtlasTextureId, AtlasTile, Bounds, DevicePixels, PlatformAtlas, Point, Size};
|
use crate::{AtlasTextureId, AtlasTile, Bounds, DevicePixels, PlatformAtlas, Point, Size};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
use derive_more::{Deref, DerefMut};
|
||||||
use etagere::BucketedAtlasAllocator;
|
use etagere::BucketedAtlasAllocator;
|
||||||
use foreign_types::ForeignType;
|
use foreign_types::ForeignType;
|
||||||
use metal::{Device, TextureDescriptor, TextureDescriptorRef};
|
use metal::{Device, TextureDescriptor};
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
|
use parking_lot::Mutex;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
|
||||||
pub struct MetalAtlas<Key>(RwLock<MetalAtlasState<Key>>);
|
pub struct MetalAtlas<Key>(Mutex<MetalAtlasState<Key>>);
|
||||||
|
|
||||||
|
impl<Key> MetalAtlas<Key> {
|
||||||
|
pub fn new(
|
||||||
|
size: Size<DevicePixels>,
|
||||||
|
pixel_format: metal::MTLPixelFormat,
|
||||||
|
device: Device,
|
||||||
|
) -> Self {
|
||||||
|
let texture_descriptor = metal::TextureDescriptor::new();
|
||||||
|
texture_descriptor.set_pixel_format(pixel_format);
|
||||||
|
texture_descriptor.set_width(size.width.into());
|
||||||
|
texture_descriptor.set_height(size.height.into());
|
||||||
|
MetalAtlas(Mutex::new(MetalAtlasState {
|
||||||
|
device: AssertSend(device),
|
||||||
|
texture_descriptor: AssertSend(texture_descriptor),
|
||||||
|
textures: Default::default(),
|
||||||
|
tiles_by_key: Default::default(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct MetalAtlasState<Key> {
|
struct MetalAtlasState<Key> {
|
||||||
device: Device,
|
device: AssertSend<Device>,
|
||||||
texture_descriptor: TextureDescriptor,
|
texture_descriptor: AssertSend<TextureDescriptor>,
|
||||||
textures: Vec<MetalAtlasTexture>,
|
textures: Vec<MetalAtlasTexture>,
|
||||||
tiles_by_key: HashMap<Key, AtlasTile>,
|
tiles_by_key: HashMap<Key, AtlasTile>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Key> PlatformAtlas<Key> for MetalAtlas<Key>
|
impl<Key> PlatformAtlas<Key> for MetalAtlas<Key>
|
||||||
where
|
where
|
||||||
Key: Eq + Hash,
|
Key: Eq + Hash + Send,
|
||||||
{
|
{
|
||||||
fn get_or_insert_with(
|
fn get_or_insert_with(
|
||||||
&self,
|
&self,
|
||||||
key: Key,
|
key: Key,
|
||||||
build: impl FnOnce() -> (Size<DevicePixels>, Vec<u8>),
|
build: &dyn Fn() -> (Size<DevicePixels>, Vec<u8>),
|
||||||
) -> AtlasTile {
|
) -> AtlasTile {
|
||||||
let lock = self.0.upgradable_read();
|
let mut lock = self.0.lock();
|
||||||
if let Some(tile) = lock.tiles_by_key.get(&key) {
|
if let Some(tile) = lock.tiles_by_key.get(&key) {
|
||||||
return tile.clone();
|
return tile.clone();
|
||||||
} else {
|
} else {
|
||||||
let mut lock = RwLockUpgradableReadGuard::upgrade(lock);
|
|
||||||
let (size, bytes) = build();
|
let (size, bytes) = build();
|
||||||
lock.textures
|
lock.textures
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
|
@ -45,7 +64,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear(&self) {
|
fn clear(&self) {
|
||||||
self.0.write().tiles_by_key.clear();
|
self.0.lock().tiles_by_key.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +81,7 @@ impl<Key> MetalAtlasState<Key> {
|
||||||
{
|
{
|
||||||
let descriptor = unsafe {
|
let descriptor = unsafe {
|
||||||
let descriptor_ptr: *mut metal::MTLTextureDescriptor =
|
let descriptor_ptr: *mut metal::MTLTextureDescriptor =
|
||||||
msg_send![self.texture_descriptor, copy];
|
msg_send![*self.texture_descriptor, copy];
|
||||||
metal::TextureDescriptor::from_ptr(descriptor_ptr)
|
metal::TextureDescriptor::from_ptr(descriptor_ptr)
|
||||||
};
|
};
|
||||||
descriptor.set_width(min_size.width.into());
|
descriptor.set_width(min_size.width.into());
|
||||||
|
@ -78,7 +97,7 @@ impl<Key> MetalAtlasState<Key> {
|
||||||
let atlas_texture = MetalAtlasTexture {
|
let atlas_texture = MetalAtlasTexture {
|
||||||
id: AtlasTextureId(self.textures.len()),
|
id: AtlasTextureId(self.textures.len()),
|
||||||
allocator: etagere::BucketedAtlasAllocator::new(size.into()),
|
allocator: etagere::BucketedAtlasAllocator::new(size.into()),
|
||||||
metal_texture,
|
metal_texture: AssertSend(metal_texture),
|
||||||
};
|
};
|
||||||
self.textures.push(atlas_texture);
|
self.textures.push(atlas_texture);
|
||||||
self.textures.last_mut().unwrap()
|
self.textures.last_mut().unwrap()
|
||||||
|
@ -88,7 +107,7 @@ impl<Key> MetalAtlasState<Key> {
|
||||||
struct MetalAtlasTexture {
|
struct MetalAtlasTexture {
|
||||||
id: AtlasTextureId,
|
id: AtlasTextureId,
|
||||||
allocator: BucketedAtlasAllocator,
|
allocator: BucketedAtlasAllocator,
|
||||||
metal_texture: metal::Texture,
|
metal_texture: AssertSend<metal::Texture>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetalAtlasTexture {
|
impl MetalAtlasTexture {
|
||||||
|
@ -162,3 +181,8 @@ impl From<etagere::Rectangle> for Bounds<DevicePixels> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deref, DerefMut)]
|
||||||
|
struct AssertSend<T>(T);
|
||||||
|
|
||||||
|
unsafe impl<T> Send for AssertSend<T> {}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::{point, size, DevicePixels, MonochromeSprite, Quad, Scene, Size};
|
use crate::{
|
||||||
|
point, size, DevicePixels, MetalAtlas, MonochromeSprite, Quad, RasterizedGlyphId, Scene, Size,
|
||||||
|
};
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
base::{NO, YES},
|
base::{NO, YES},
|
||||||
|
@ -7,7 +9,7 @@ use cocoa::{
|
||||||
};
|
};
|
||||||
use metal::{CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange};
|
use metal::{CommandQueue, MTLPixelFormat, MTLResourceOptions, NSRange};
|
||||||
use objc::{self, msg_send, sel, sel_impl};
|
use objc::{self, msg_send, sel, sel_impl};
|
||||||
use std::{ffi::c_void, mem, ptr};
|
use std::{ffi::c_void, mem, ptr, sync::Arc};
|
||||||
|
|
||||||
const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib"));
|
const SHADERS_METALLIB: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/shaders.metallib"));
|
||||||
const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value.
|
const INSTANCE_BUFFER_SIZE: usize = 8192 * 1024; // This is an arbitrary decision. There's probably a more optimal value.
|
||||||
|
@ -19,6 +21,7 @@ pub struct MetalRenderer {
|
||||||
quad_pipeline_state: metal::RenderPipelineState,
|
quad_pipeline_state: metal::RenderPipelineState,
|
||||||
unit_vertices: metal::Buffer,
|
unit_vertices: metal::Buffer,
|
||||||
instances: metal::Buffer,
|
instances: metal::Buffer,
|
||||||
|
glyph_atlas: Arc<MetalAtlas<RasterizedGlyphId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MetalRenderer {
|
impl MetalRenderer {
|
||||||
|
@ -88,6 +91,15 @@ impl MetalRenderer {
|
||||||
);
|
);
|
||||||
|
|
||||||
let command_queue = device.new_command_queue();
|
let command_queue = device.new_command_queue();
|
||||||
|
let glyph_atlas = Arc::new(MetalAtlas::new(
|
||||||
|
Size {
|
||||||
|
width: DevicePixels(1024),
|
||||||
|
height: DevicePixels(1024),
|
||||||
|
},
|
||||||
|
MTLPixelFormat::A8Unorm,
|
||||||
|
device.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
device,
|
device,
|
||||||
layer,
|
layer,
|
||||||
|
@ -95,6 +107,7 @@ impl MetalRenderer {
|
||||||
quad_pipeline_state,
|
quad_pipeline_state,
|
||||||
unit_vertices,
|
unit_vertices,
|
||||||
instances,
|
instances,
|
||||||
|
glyph_atlas,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +115,10 @@ impl MetalRenderer {
|
||||||
&*self.layer
|
&*self.layer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn glyph_atlas(&self) -> &Arc<MetalAtlas<RasterizedGlyphId>> {
|
||||||
|
&self.glyph_atlas
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self, scene: &mut Scene) {
|
pub fn draw(&mut self, scene: &mut Scene) {
|
||||||
let layer = self.layer.clone();
|
let layer = self.layer.clone();
|
||||||
let viewport_size = layer.drawable_size();
|
let viewport_size = layer.drawable_size();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
point, px, size, Bounds, Font, FontFeatures, FontId, FontMetrics, FontStyle, FontWeight, Glyph,
|
point, px, size, Bounds, Font, FontFeatures, FontId, FontMetrics, FontStyle, FontWeight,
|
||||||
GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RasterizationOptions, Result, Run,
|
GlyphId, Pixels, PlatformTextSystem, Point, RasterizationOptions, Result, ShapedGlyph,
|
||||||
SharedString, Size,
|
ShapedLine, ShapedRun, SharedString, Size,
|
||||||
};
|
};
|
||||||
use cocoa::appkit::{CGFloat, CGPoint};
|
use cocoa::appkit::{CGFloat, CGPoint};
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
@ -161,7 +161,7 @@ impl PlatformTextSystem for MacTextSystem {
|
||||||
text: &str,
|
text: &str,
|
||||||
font_size: Pixels,
|
font_size: Pixels,
|
||||||
font_runs: &[(usize, FontId)],
|
font_runs: &[(usize, FontId)],
|
||||||
) -> LineLayout {
|
) -> ShapedLine {
|
||||||
self.0.write().layout_line(text, font_size, font_runs)
|
self.0.write().layout_line(text, font_size, font_runs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ impl MacTextSystemState {
|
||||||
text: &str,
|
text: &str,
|
||||||
font_size: Pixels,
|
font_size: Pixels,
|
||||||
font_runs: &[(usize, FontId)],
|
font_runs: &[(usize, FontId)],
|
||||||
) -> LineLayout {
|
) -> ShapedLine {
|
||||||
// Construct the attributed string, converting UTF8 ranges to UTF16 ranges.
|
// Construct the attributed string, converting UTF8 ranges to UTF16 ranges.
|
||||||
let mut string = CFMutableAttributedString::new();
|
let mut string = CFMutableAttributedString::new();
|
||||||
{
|
{
|
||||||
|
@ -409,7 +409,7 @@ impl MacTextSystemState {
|
||||||
{
|
{
|
||||||
let glyph_utf16_ix = usize::try_from(*glyph_utf16_ix).unwrap();
|
let glyph_utf16_ix = usize::try_from(*glyph_utf16_ix).unwrap();
|
||||||
ix_converter.advance_to_utf16_ix(glyph_utf16_ix);
|
ix_converter.advance_to_utf16_ix(glyph_utf16_ix);
|
||||||
glyphs.push(Glyph {
|
glyphs.push(ShapedGlyph {
|
||||||
id: (*glyph_id).into(),
|
id: (*glyph_id).into(),
|
||||||
position: point(position.x as f32, position.y as f32).map(px),
|
position: point(position.x as f32, position.y as f32).map(px),
|
||||||
index: ix_converter.utf8_ix,
|
index: ix_converter.utf8_ix,
|
||||||
|
@ -417,11 +417,11 @@ impl MacTextSystemState {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
runs.push(Run { font_id, glyphs })
|
runs.push(ShapedRun { font_id, glyphs })
|
||||||
}
|
}
|
||||||
|
|
||||||
let typographic_bounds = line.get_typographic_bounds();
|
let typographic_bounds = line.get_typographic_bounds();
|
||||||
LineLayout {
|
ShapedLine {
|
||||||
width: typographic_bounds.width.into(),
|
width: typographic_bounds.width.into(),
|
||||||
ascent: typographic_bounds.ascent.into(),
|
ascent: typographic_bounds.ascent.into(),
|
||||||
descent: typographic_bounds.descent.into(),
|
descent: typographic_bounds.descent.into(),
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use super::{ns_string, MetalRenderer, NSRange};
|
use super::{ns_string, MetalRenderer, NSRange};
|
||||||
use crate::{
|
use crate::{
|
||||||
point, px, size, AnyWindowHandle, Bounds, Event, KeyDownEvent, Keystroke, MacScreen, Modifiers,
|
point, px, size, AnyWindowHandle, Bounds, Event, KeyDownEvent, Keystroke, MacScreen,
|
||||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMovedEvent, MouseUpEvent, NSRectExt,
|
MetalAtlas, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMovedEvent,
|
||||||
Pixels, Platform, PlatformDispatcher, PlatformInputHandler, PlatformScreen, PlatformWindow,
|
MouseUpEvent, NSRectExt, Pixels, Platform, PlatformAtlas, PlatformDispatcher,
|
||||||
Point, Scene, Size, Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions,
|
PlatformInputHandler, PlatformScreen, PlatformWindow, Point, RasterizedGlyphId, Scene, Size,
|
||||||
WindowPromptLevel,
|
Timer, WindowAppearance, WindowBounds, WindowKind, WindowOptions, WindowPromptLevel,
|
||||||
};
|
};
|
||||||
use block::ConcreteBlock;
|
use block::ConcreteBlock;
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
|
@ -20,6 +20,7 @@ use core_graphics::display::CGRect;
|
||||||
use ctor::ctor;
|
use ctor::ctor;
|
||||||
use foreign_types::ForeignTypeRef;
|
use foreign_types::ForeignTypeRef;
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
|
use metal::{MTLPixelFormat, TextureDescriptor};
|
||||||
use objc::{
|
use objc::{
|
||||||
class,
|
class,
|
||||||
declare::ClassDecl,
|
declare::ClassDecl,
|
||||||
|
@ -885,6 +886,10 @@ impl PlatformWindow for MacWindow {
|
||||||
let _: () = msg_send![this.native_window.contentView(), setNeedsDisplay: YES];
|
let _: () = msg_send![this.native_window.contentView(), setNeedsDisplay: YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn glyph_atlas(&self) -> Arc<dyn PlatformAtlas<RasterizedGlyphId>> {
|
||||||
|
self.0.lock().renderer.glyph_atlas().clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_scale_factor(native_window: id) -> f32 {
|
fn get_scale_factor(native_window: id) -> f32 {
|
||||||
|
|
|
@ -346,28 +346,35 @@ impl From<u32> for GlyphId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug)]
|
||||||
|
pub struct ShapedLine {
|
||||||
|
pub font_size: Pixels,
|
||||||
|
pub width: Pixels,
|
||||||
|
pub ascent: Pixels,
|
||||||
|
pub descent: Pixels,
|
||||||
|
pub runs: Vec<ShapedRun>,
|
||||||
|
pub len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ShapedRun {
|
||||||
|
pub font_id: FontId,
|
||||||
|
pub glyphs: Vec<ShapedGlyph>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Glyph {
|
pub struct ShapedGlyph {
|
||||||
pub id: GlyphId,
|
pub id: GlyphId,
|
||||||
pub position: Point<Pixels>,
|
pub position: Point<Pixels>,
|
||||||
pub index: usize,
|
pub index: usize,
|
||||||
pub is_emoji: bool,
|
pub is_emoji: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
pub struct LineLayout {
|
pub struct RasterizedGlyphId {
|
||||||
pub font_size: Pixels,
|
font_id: FontId,
|
||||||
pub width: Pixels,
|
glyph_id: GlyphId,
|
||||||
pub ascent: Pixels,
|
font_size: Pixels,
|
||||||
pub descent: Pixels,
|
|
||||||
pub runs: Vec<Run>,
|
|
||||||
pub len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Run {
|
|
||||||
pub font_id: FontId,
|
|
||||||
pub glyphs: Vec<Glyph>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
black, point, px, Bounds, FontId, Hsla, Layout, LineLayout, Pixels, Point, Run, RunStyle,
|
black, point, px, Bounds, FontId, Hsla, Layout, Pixels, Point, RunStyle, ShapedBoundary,
|
||||||
ShapedBoundary, UnderlineStyle, WindowContext,
|
ShapedLine, ShapedRun, UnderlineStyle, WindowContext,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct Line {
|
pub struct Line {
|
||||||
layout: Arc<LineLayout>,
|
layout: Arc<ShapedLine>,
|
||||||
style_runs: SmallVec<[StyleRun; 32]>,
|
style_runs: SmallVec<[StyleRun; 32]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ struct StyleRun {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Line {
|
impl Line {
|
||||||
pub fn new(layout: Arc<LineLayout>, runs: &[(usize, RunStyle)]) -> Self {
|
pub fn new(layout: Arc<ShapedLine>, runs: &[(usize, RunStyle)]) -> Self {
|
||||||
let mut style_runs = SmallVec::new();
|
let mut style_runs = SmallVec::new();
|
||||||
for (len, style) in runs {
|
for (len, style) in runs {
|
||||||
style_runs.push(StyleRun {
|
style_runs.push(StyleRun {
|
||||||
|
@ -32,7 +32,7 @@ impl Line {
|
||||||
Self { layout, style_runs }
|
Self { layout, style_runs }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn runs(&self) -> &[Run] {
|
pub fn runs(&self) -> &[ShapedRun] {
|
||||||
&self.layout.runs
|
&self.layout.runs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{FontId, Glyph, LineLayout, Pixels, PlatformTextSystem, Run};
|
use crate::{FontId, Pixels, PlatformTextSystem, ShapedGlyph, ShapedLine, ShapedRun};
|
||||||
use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard};
|
use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -9,8 +9,8 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) struct TextLayoutCache {
|
pub(crate) struct TextLayoutCache {
|
||||||
prev_frame: Mutex<HashMap<CacheKeyValue, Arc<LineLayout>>>,
|
prev_frame: Mutex<HashMap<CacheKeyValue, Arc<ShapedLine>>>,
|
||||||
curr_frame: RwLock<HashMap<CacheKeyValue, Arc<LineLayout>>>,
|
curr_frame: RwLock<HashMap<CacheKeyValue, Arc<ShapedLine>>>,
|
||||||
platform_text_system: Arc<dyn PlatformTextSystem>,
|
platform_text_system: Arc<dyn PlatformTextSystem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ impl TextLayoutCache {
|
||||||
text: &'a str,
|
text: &'a str,
|
||||||
font_size: Pixels,
|
font_size: Pixels,
|
||||||
runs: &[(usize, FontId)],
|
runs: &[(usize, FontId)],
|
||||||
) -> Arc<LineLayout> {
|
) -> Arc<ShapedLine> {
|
||||||
let key = &CacheKeyRef {
|
let key = &CacheKeyRef {
|
||||||
text,
|
text,
|
||||||
font_size,
|
font_size,
|
||||||
|
@ -146,8 +146,8 @@ pub struct ShapedBoundary {
|
||||||
pub glyph_ix: usize,
|
pub glyph_ix: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Run {
|
impl ShapedRun {
|
||||||
pub fn glyphs(&self) -> &[Glyph] {
|
pub fn glyphs(&self) -> &[ShapedGlyph] {
|
||||||
&self.glyphs
|
&self.glyphs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
px, AnyView, AppContext, AvailableSpace, Bounds, Context, Effect, Element, EntityId, Handle,
|
px, AnyView, AppContext, AvailableSpace, Bounds, Context, Effect, Element, EntityId, FontId,
|
||||||
LayoutId, MainThread, MainThreadOnly, Pixels, PlatformWindow, Point, Reference, Scene, Size,
|
GlyphId, Handle, LayoutId, MainThread, MainThreadOnly, Pixels, PlatformAtlas, PlatformWindow,
|
||||||
StackContext, StackingOrder, Style, TaffyLayoutEngine, WeakHandle, WindowOptions,
|
Point, RasterizedGlyphId, Reference, Scene, Size, StackContext, StackingOrder, Style,
|
||||||
|
TaffyLayoutEngine, WeakHandle, WindowOptions,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
@ -14,6 +15,7 @@ pub struct AnyWindow {}
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
handle: AnyWindowHandle,
|
handle: AnyWindowHandle,
|
||||||
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
|
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
|
||||||
|
glyph_atlas: Arc<dyn PlatformAtlas<RasterizedGlyphId>>,
|
||||||
rem_size: Pixels,
|
rem_size: Pixels,
|
||||||
content_size: Size<Pixels>,
|
content_size: Size<Pixels>,
|
||||||
layout_engine: TaffyLayoutEngine,
|
layout_engine: TaffyLayoutEngine,
|
||||||
|
@ -31,6 +33,7 @@ impl Window {
|
||||||
cx: &mut MainThread<AppContext>,
|
cx: &mut MainThread<AppContext>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let platform_window = cx.platform().open_window(handle, options);
|
let platform_window = cx.platform().open_window(handle, options);
|
||||||
|
let glyph_atlas = platform_window.glyph_atlas();
|
||||||
let mouse_position = platform_window.mouse_position();
|
let mouse_position = platform_window.mouse_position();
|
||||||
let content_size = platform_window.content_size();
|
let content_size = platform_window.content_size();
|
||||||
let scale_factor = platform_window.scale_factor();
|
let scale_factor = platform_window.scale_factor();
|
||||||
|
@ -53,6 +56,7 @@ impl Window {
|
||||||
Window {
|
Window {
|
||||||
handle,
|
handle,
|
||||||
platform_window,
|
platform_window,
|
||||||
|
glyph_atlas,
|
||||||
rem_size: px(16.),
|
rem_size: px(16.),
|
||||||
content_size,
|
content_size,
|
||||||
layout_engine: TaffyLayoutEngine::new(),
|
layout_engine: TaffyLayoutEngine::new(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue