mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-18 08:02:27 +00:00
Checkpoint
This commit is contained in:
parent
9e7a579365
commit
88ae4679d1
5 changed files with 36 additions and 45 deletions
|
@ -5,7 +5,7 @@ mod mac;
|
|||
mod test;
|
||||
|
||||
use crate::{
|
||||
AnyWindowHandle, Bounds, DevicePixels, Event, Executor, Font, FontId, FontMetrics,
|
||||
AnyWindowHandle, Bounds, DevicePixels, Event, Executor, Font, FontId, FontMetrics, FontRun,
|
||||
GlobalPixels, GlyphId, LineLayout, Pixels, Point, RenderGlyphParams, RenderImageParams,
|
||||
RenderSvgParams, Result, Scene, SharedString, Size,
|
||||
};
|
||||
|
@ -171,7 +171,7 @@ pub trait PlatformTextSystem: Send + Sync {
|
|||
fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option<GlyphId>;
|
||||
fn glyph_raster_bounds(&self, params: &RenderGlyphParams) -> Result<Bounds<DevicePixels>>;
|
||||
fn rasterize_glyph(&self, params: &RenderGlyphParams) -> Result<(Size<DevicePixels>, 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: &[FontRun]) -> LineLayout;
|
||||
fn wrap_line(
|
||||
&self,
|
||||
text: &str,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
point, px, size, Bounds, DevicePixels, Font, FontFeatures, FontId, FontMetrics, FontStyle,
|
||||
FontWeight, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RenderGlyphParams, Result,
|
||||
ShapedGlyph, ShapedRun, SharedString, Size, SUBPIXEL_VARIANTS,
|
||||
point, px, size, Bounds, DevicePixels, Font, FontFeatures, FontId, FontMetrics, FontRun,
|
||||
FontStyle, FontWeight, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point,
|
||||
RenderGlyphParams, Result, ShapedGlyph, ShapedRun, SharedString, Size, SUBPIXEL_VARIANTS,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use cocoa::appkit::{CGFloat, CGPoint};
|
||||
|
@ -149,12 +149,7 @@ impl PlatformTextSystem for MacTextSystem {
|
|||
self.0.read().rasterize_glyph(glyph_id)
|
||||
}
|
||||
|
||||
fn layout_line(
|
||||
&self,
|
||||
text: &str,
|
||||
font_size: Pixels,
|
||||
font_runs: &[(usize, FontId)],
|
||||
) -> LineLayout {
|
||||
fn layout_line(&self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout {
|
||||
self.0.write().layout_line(text, font_size, font_runs)
|
||||
}
|
||||
|
||||
|
@ -337,12 +332,7 @@ impl MacTextSystemState {
|
|||
}
|
||||
}
|
||||
|
||||
fn layout_line(
|
||||
&mut self,
|
||||
text: &str,
|
||||
font_size: Pixels,
|
||||
font_runs: &[(usize, FontId)],
|
||||
) -> LineLayout {
|
||||
fn layout_line(&mut self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout {
|
||||
// Construct the attributed string, converting UTF8 ranges to UTF16 ranges.
|
||||
let mut string = CFMutableAttributedString::new();
|
||||
{
|
||||
|
@ -350,8 +340,8 @@ impl MacTextSystemState {
|
|||
let utf16_line_len = string.char_len() as usize;
|
||||
|
||||
let mut ix_converter = StringIndexConverter::new(text);
|
||||
for (run_len, font_id) in font_runs {
|
||||
let utf8_end = ix_converter.utf8_ix + run_len;
|
||||
for run in font_runs {
|
||||
let utf8_end = ix_converter.utf8_ix + run.len;
|
||||
let utf16_start = ix_converter.utf16_ix;
|
||||
|
||||
if utf16_start >= utf16_line_len {
|
||||
|
@ -364,7 +354,7 @@ impl MacTextSystemState {
|
|||
let cf_range =
|
||||
CFRange::init(utf16_start as isize, (utf16_end - utf16_start) as isize);
|
||||
|
||||
let font: &FontKitFont = &self.fonts[font_id.0];
|
||||
let font: &FontKitFont = &self.fonts[run.font_id.0];
|
||||
unsafe {
|
||||
string.set_attribute(
|
||||
cf_range,
|
||||
|
|
|
@ -40,7 +40,7 @@ pub struct TextSystem {
|
|||
font_ids_by_font: RwLock<HashMap<Font, FontId>>,
|
||||
font_metrics: RwLock<HashMap<FontId, FontMetrics>>,
|
||||
wrapper_pool: Mutex<HashMap<FontIdWithSize, Vec<LineWrapper>>>,
|
||||
font_runs_pool: Mutex<Vec<Vec<(usize, FontId)>>>,
|
||||
font_runs_pool: Mutex<Vec<Vec<FontRun>>>,
|
||||
}
|
||||
|
||||
impl TextSystem {
|
||||
|
@ -153,8 +153,7 @@ impl TextSystem {
|
|||
wrap_width: Option<Pixels>,
|
||||
) -> Result<SmallVec<[Line; 1]>> {
|
||||
let mut runs = runs.iter().cloned().peekable();
|
||||
let mut font_runs: Vec<(usize, FontId)> =
|
||||
self.font_runs_pool.lock().pop().unwrap_or_default();
|
||||
let mut font_runs = self.font_runs_pool.lock().pop().unwrap_or_default();
|
||||
|
||||
let mut lines = SmallVec::new();
|
||||
let mut line_start = 0;
|
||||
|
@ -173,13 +172,13 @@ impl TextSystem {
|
|||
let run_len_within_line = cmp::min(line_end, run_start + run.len) - run_start;
|
||||
|
||||
if last_font == Some(run.font.clone()) {
|
||||
font_runs.last_mut().unwrap().0 += run_len_within_line;
|
||||
font_runs.last_mut().unwrap().len += run_len_within_line;
|
||||
} else {
|
||||
last_font = Some(run.font.clone());
|
||||
font_runs.push((
|
||||
run_len_within_line,
|
||||
self.platform_text_system.font_id(&run.font)?,
|
||||
));
|
||||
font_runs.push(FontRun {
|
||||
len: run_len_within_line,
|
||||
font_id: self.platform_text_system.font_id(&run.font)?,
|
||||
});
|
||||
}
|
||||
|
||||
if decoration_runs.last().map_or(false, |last_run| {
|
||||
|
|
|
@ -178,7 +178,7 @@ impl LineLayoutCache {
|
|||
&self,
|
||||
text: &SharedString,
|
||||
font_size: Pixels,
|
||||
runs: &[(usize, FontId)],
|
||||
runs: &[FontRun],
|
||||
wrap_width: Option<Pixels>,
|
||||
) -> Arc<WrappedLineLayout> {
|
||||
let key = &CacheKeyRef {
|
||||
|
@ -219,6 +219,12 @@ impl LineLayoutCache {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct FontRun {
|
||||
pub(crate) len: usize,
|
||||
pub(crate) font_id: FontId,
|
||||
}
|
||||
|
||||
trait AsCacheKeyRef {
|
||||
fn as_cache_key_ref(&self) -> CacheKeyRef;
|
||||
}
|
||||
|
@ -227,15 +233,15 @@ trait AsCacheKeyRef {
|
|||
struct CacheKey {
|
||||
text: SharedString,
|
||||
font_size: Pixels,
|
||||
runs: SmallVec<[(usize, FontId); 1]>,
|
||||
runs: SmallVec<[FontRun; 1]>,
|
||||
wrap_width: Option<Pixels>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
struct CacheKeyRef<'a> {
|
||||
text: &'a str,
|
||||
font_size: Pixels,
|
||||
runs: &'a [(usize, FontId)],
|
||||
runs: &'a [FontRun],
|
||||
wrap_width: Option<Pixels>,
|
||||
}
|
||||
|
||||
|
@ -287,14 +293,3 @@ impl<'a> AsCacheKeyRef for CacheKeyRef<'a> {
|
|||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for CacheKeyRef<'a> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.text.hash(state);
|
||||
self.font_size.hash(state);
|
||||
for (len, font_id) in self.runs {
|
||||
len.hash(state);
|
||||
font_id.hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{px, FontId, Pixels, PlatformTextSystem};
|
||||
use crate::{px, FontId, FontRun, Pixels, PlatformTextSystem};
|
||||
use collections::HashMap;
|
||||
use std::{iter, sync::Arc};
|
||||
|
||||
|
@ -112,7 +112,14 @@ impl LineWrapper {
|
|||
let mut buffer = [0; 4];
|
||||
let buffer = c.encode_utf8(&mut buffer);
|
||||
self.platform_text_system
|
||||
.layout_line(buffer, self.font_size, &[(1, self.font_id)])
|
||||
.layout_line(
|
||||
buffer,
|
||||
self.font_size,
|
||||
&[FontRun {
|
||||
len: 1,
|
||||
font_id: self.font_id,
|
||||
}],
|
||||
)
|
||||
.width
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue