mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-07 02:38:53 +03:00
Checkpoint
This commit is contained in:
parent
e9a84a21e4
commit
96f9c67e77
@ -35,7 +35,7 @@ impl<S: 'static> Element for Div<S> {
|
||||
let style = self.computed_style();
|
||||
let pop_text_style = style
|
||||
.text_style(cx)
|
||||
.map(|style| cx.push_text_style(style))
|
||||
.map(|style| cx.push_text_style(style.clone()))
|
||||
.is_some();
|
||||
|
||||
let children = self
|
||||
@ -63,7 +63,7 @@ impl<S: 'static> Element for Div<S> {
|
||||
let style = self.computed_style();
|
||||
let pop_text_style = style
|
||||
.text_style(cx)
|
||||
.map(|style| cx.push_text_style(style))
|
||||
.map(|style| cx.push_text_style(style.clone()))
|
||||
.is_some();
|
||||
style.paint_background(bounds, cx);
|
||||
// self.interaction_handlers().paint(order, bounds, cx);
|
||||
|
@ -6,8 +6,8 @@ mod mac;
|
||||
mod test;
|
||||
|
||||
use crate::{
|
||||
AnyWindowHandle, Bounds, FontFeatures, FontId, FontStyle, FontWeight, GlyphId, LineLayout,
|
||||
Pixels, Point, Result, RunStyle, Scene, SharedString, Size,
|
||||
AnyWindowHandle, Bounds, Font, FontId, FontMetrics, GlyphId, LineLayout, Pixels, Point, Result,
|
||||
RunStyle, Scene, SharedString, Size,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use async_task::Runnable;
|
||||
@ -156,8 +156,8 @@ pub trait PlatformDispatcher: Send + Sync {
|
||||
pub trait PlatformTextSystem: Send + Sync {
|
||||
fn add_fonts(&self, fonts: &[Arc<Vec<u8>>]) -> Result<()>;
|
||||
fn all_font_families(&self) -> Vec<String>;
|
||||
fn select_font(&self, descriptor: FontDescriptor) -> Result<FontId>;
|
||||
fn font_metrics(&self, font_id: FontId) -> FontMetrics;
|
||||
fn select_font(&self, descriptor: Font) -> Result<FontId>;
|
||||
fn font_metrics(&self, font_id: FontId) -> Arc<FontMetrics>;
|
||||
fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Bounds<f32>>;
|
||||
fn advance(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Size<f32>>;
|
||||
fn glyph_for_char(&self, font_id: FontId, ch: char) -> Option<GlyphId>;
|
||||
@ -397,24 +397,3 @@ impl ClipboardItem {
|
||||
hasher.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct FontDescriptor {
|
||||
family: SharedString,
|
||||
features: FontFeatures,
|
||||
weight: FontWeight,
|
||||
style: FontStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct FontMetrics {
|
||||
pub units_per_em: u32,
|
||||
pub ascent: f32,
|
||||
pub descent: f32,
|
||||
pub line_gap: f32,
|
||||
pub underline_position: f32,
|
||||
pub underline_thickness: f32,
|
||||
pub cap_height: f32,
|
||||
pub x_height: f32,
|
||||
pub bounding_box: Bounds<f32>,
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
platform::FontDescriptor, point, px, size, Bounds, FontFeatures, FontId, FontMetrics,
|
||||
FontStyle, FontWeight, Glyph, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point,
|
||||
RasterizationOptions, Result, Run, RunStyle, SharedString, Size,
|
||||
point, px, size, Bounds, Font, FontFeatures, FontId, FontMetrics, FontStyle, FontWeight, Glyph,
|
||||
GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RasterizationOptions, Result, Run,
|
||||
RunStyle, SharedString, Size,
|
||||
};
|
||||
use cocoa::appkit::{CGFloat, CGPoint};
|
||||
use collections::HashMap;
|
||||
@ -18,6 +18,7 @@ use core_graphics::{
|
||||
};
|
||||
use core_text::{font::CTFont, line::CTLine, string_attributes::kCTFontAttributeName};
|
||||
use font_kit::{
|
||||
font::Font as FontKitFont,
|
||||
handle::Handle,
|
||||
hinting::HintingOptions,
|
||||
metrics::Metrics,
|
||||
@ -44,8 +45,9 @@ pub struct MacTextSystem(RwLock<TextSystemState>);
|
||||
struct TextSystemState {
|
||||
memory_source: MemSource,
|
||||
system_source: SystemSource,
|
||||
fonts: Vec<font_kit::font::Font>,
|
||||
font_selections: HashMap<FontDescriptor, FontId>,
|
||||
fonts: Vec<FontKitFont>,
|
||||
font_selections: HashMap<Font, FontId>,
|
||||
font_metrics: HashMap<FontId, Arc<FontMetrics>>,
|
||||
font_ids_by_postscript_name: HashMap<String, FontId>,
|
||||
font_ids_by_family_name: HashMap<SharedString, SmallVec<[FontId; 4]>>,
|
||||
postscript_names_by_font_id: HashMap<FontId, String>,
|
||||
@ -58,6 +60,7 @@ impl MacTextSystem {
|
||||
system_source: SystemSource::new(),
|
||||
fonts: Vec::new(),
|
||||
font_selections: HashMap::default(),
|
||||
font_metrics: HashMap::default(),
|
||||
font_ids_by_postscript_name: HashMap::default(),
|
||||
font_ids_by_family_name: HashMap::default(),
|
||||
postscript_names_by_font_id: HashMap::default(),
|
||||
@ -84,21 +87,21 @@ impl PlatformTextSystem for MacTextSystem {
|
||||
.expect("core text should never return an error")
|
||||
}
|
||||
|
||||
fn select_font(&self, descriptor: FontDescriptor) -> Result<FontId> {
|
||||
fn select_font(&self, font: Font) -> Result<FontId> {
|
||||
let lock = self.0.upgradable_read();
|
||||
if let Some(font_id) = lock.font_selections.get(&descriptor) {
|
||||
if let Some(font_id) = lock.font_selections.get(&font) {
|
||||
Ok(*font_id)
|
||||
} else {
|
||||
let mut lock = parking_lot::RwLockUpgradableReadGuard::upgrade(lock);
|
||||
let candidates =
|
||||
if let Some(font_ids) = lock.font_ids_by_family_name.get(&descriptor.family) {
|
||||
font_ids.as_slice()
|
||||
} else {
|
||||
let font_ids = lock.load_family(&descriptor.family, descriptor.features)?;
|
||||
lock.font_ids_by_family_name
|
||||
.insert(descriptor.family.clone(), font_ids);
|
||||
lock.font_ids_by_family_name[&descriptor.family].as_ref()
|
||||
};
|
||||
let candidates = if let Some(font_ids) = lock.font_ids_by_family_name.get(&font.family)
|
||||
{
|
||||
font_ids.as_slice()
|
||||
} else {
|
||||
let font_ids = lock.load_family(&font.family, font.features)?;
|
||||
lock.font_ids_by_family_name
|
||||
.insert(font.family.clone(), font_ids);
|
||||
lock.font_ids_by_family_name[&font.family].as_ref()
|
||||
};
|
||||
|
||||
let candidate_properties = candidates
|
||||
.iter()
|
||||
@ -108,8 +111,8 @@ impl PlatformTextSystem for MacTextSystem {
|
||||
let ix = font_kit::matching::find_best_match(
|
||||
&candidate_properties,
|
||||
&font_kit::properties::Properties {
|
||||
style: descriptor.style.into(),
|
||||
weight: descriptor.weight.into(),
|
||||
style: font.style.into(),
|
||||
weight: font.weight.into(),
|
||||
stretch: Default::default(),
|
||||
},
|
||||
)?;
|
||||
@ -118,8 +121,16 @@ impl PlatformTextSystem for MacTextSystem {
|
||||
}
|
||||
}
|
||||
|
||||
fn font_metrics(&self, font_id: FontId) -> FontMetrics {
|
||||
self.0.read().font_metrics(font_id)
|
||||
fn font_metrics(&self, font_id: FontId) -> Arc<FontMetrics> {
|
||||
let lock = self.0.upgradable_read();
|
||||
if let Some(metrics) = lock.font_metrics.get(&font_id) {
|
||||
metrics.clone()
|
||||
} else {
|
||||
let mut lock = parking_lot::RwLockUpgradableReadGuard::upgrade(lock);
|
||||
let metrics: Arc<FontMetrics> = Arc::new(lock.fonts[font_id.0].metrics().into());
|
||||
lock.font_metrics.insert(font_id, metrics.clone());
|
||||
metrics
|
||||
}
|
||||
}
|
||||
|
||||
fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Bounds<f32>> {
|
||||
@ -203,46 +214,6 @@ impl TextSystemState {
|
||||
Ok(font_ids)
|
||||
}
|
||||
|
||||
// fn select_font(
|
||||
// &mut self,
|
||||
// family: &SharedString,
|
||||
// weight: FontWeight,
|
||||
// style: FontStyle,
|
||||
// features: FontFeatures,
|
||||
// ) -> Result<FontId> {
|
||||
// let candidates = if let Some(font_ids) = self.font_ids_by_family_name.get(family) {
|
||||
// font_ids
|
||||
// } else {
|
||||
// let font_ids = if let Some(font_ids) = self.font_ids_by_family_name.get(family) {
|
||||
// font_ids.as_slice()
|
||||
// } else {
|
||||
// self.font_ids_by_family_name
|
||||
// .insert(family.clone())
|
||||
// .or_insert(font_ids).as_slice()
|
||||
// };
|
||||
|
||||
// };
|
||||
|
||||
// let font_properties = candidates
|
||||
// .iter()
|
||||
// .map(|font_id| self.fonts[font_id.0].properties())
|
||||
// .collect::<SmallVec<[_; 4]>>();
|
||||
|
||||
// // let idx = font_kit::matching::find_best_match(
|
||||
// // &candidates,
|
||||
// // &font_kit::properties::Properties {
|
||||
// // style: style.into(),
|
||||
// // weight: weight.into(),
|
||||
// // stretch: Default::default(),
|
||||
// // },
|
||||
// // )?;
|
||||
// // Ok(font_ids[idx])
|
||||
// }
|
||||
|
||||
fn font_metrics(&self, font_id: FontId) -> FontMetrics {
|
||||
self.fonts[font_id.0].metrics().into()
|
||||
}
|
||||
|
||||
fn typographic_bounds(&self, font_id: FontId, glyph_id: GlyphId) -> Result<Bounds<f32>> {
|
||||
Ok(self.fonts[font_id.0]
|
||||
.typographic_bounds(glyph_id.into())?
|
||||
@ -393,30 +364,30 @@ impl TextSystemState {
|
||||
string.replace_str(&CFString::new(text), CFRange::init(0, 0));
|
||||
let utf16_line_len = string.char_len() as usize;
|
||||
|
||||
let last_run: RefCell<Option<(usize, FontId)>> = Default::default();
|
||||
let last_run: RefCell<Option<(usize, Font)>> = Default::default();
|
||||
let font_runs = runs
|
||||
.iter()
|
||||
.filter_map(|(len, style)| {
|
||||
let mut last_run = last_run.borrow_mut();
|
||||
if let Some((last_len, last_font_id)) = last_run.as_mut() {
|
||||
if style.font_id == *last_font_id {
|
||||
if let Some((last_len, last_font)) = last_run.as_mut() {
|
||||
if style.font == *last_font {
|
||||
*last_len += *len;
|
||||
None
|
||||
} else {
|
||||
let result = (*last_len, *last_font_id);
|
||||
let result = (*last_len, last_font.clone());
|
||||
*last_len = *len;
|
||||
*last_font_id = style.font_id;
|
||||
*last_font = style.font.clone();
|
||||
Some(result)
|
||||
}
|
||||
} else {
|
||||
*last_run = Some((*len, style.font_id));
|
||||
*last_run = Some((*len, style.font.clone()));
|
||||
None
|
||||
}
|
||||
})
|
||||
.chain(std::iter::from_fn(|| last_run.borrow_mut().take()));
|
||||
|
||||
let mut ix_converter = StringIndexConverter::new(text);
|
||||
for (run_len, font_id) in font_runs {
|
||||
for (run_len, font_descriptor) in font_runs {
|
||||
let utf8_end = ix_converter.utf8_ix + run_len;
|
||||
let utf16_start = ix_converter.utf16_ix;
|
||||
|
||||
@ -429,7 +400,9 @@ impl TextSystemState {
|
||||
|
||||
let cf_range =
|
||||
CFRange::init(utf16_start as isize, (utf16_end - utf16_start) as isize);
|
||||
let font = &self.fonts[font_id.0];
|
||||
|
||||
let font_id = self.font_selections[&font_descriptor];
|
||||
let font: &FontKitFont = &self.fonts[font_id.0];
|
||||
unsafe {
|
||||
string.set_attribute(
|
||||
cf_range,
|
||||
|
@ -1,7 +1,8 @@
|
||||
use crate::{
|
||||
rems, AbsoluteLength, Bounds, Corners, CornersRefinement, DefiniteLength, Edges,
|
||||
EdgesRefinement, FontStyle, FontWeight, Hsla, Length, Pixels, Point, PointRefinement, Rems,
|
||||
Result, RunStyle, SharedString, Size, SizeRefinement, ViewContext, WindowContext,
|
||||
EdgesRefinement, Font, FontFeatures, FontStyle, FontWeight, Hsla, Length, Pixels, Point,
|
||||
PointRefinement, Rems, Result, RunStyle, SharedString, Size, SizeRefinement, ViewContext,
|
||||
WindowContext,
|
||||
};
|
||||
use refineable::Refineable;
|
||||
pub use taffy::style::{
|
||||
@ -88,17 +89,8 @@ pub struct Style {
|
||||
#[refineable]
|
||||
pub corner_radii: Corners<AbsoluteLength>,
|
||||
|
||||
/// The color of text within this element. Cascades to children unless overridden.
|
||||
pub text_color: Option<Hsla>,
|
||||
|
||||
/// The font size in rems.
|
||||
pub font_size: Option<Rems>,
|
||||
|
||||
pub font_family: Option<SharedString>,
|
||||
|
||||
pub font_weight: Option<FontWeight>,
|
||||
|
||||
pub font_style: Option<FontStyle>,
|
||||
/// TEXT
|
||||
pub text: TextStyleRefinement,
|
||||
}
|
||||
|
||||
#[derive(Refineable, Clone, Debug)]
|
||||
@ -106,6 +98,7 @@ pub struct Style {
|
||||
pub struct TextStyle {
|
||||
pub color: Hsla,
|
||||
pub font_family: SharedString,
|
||||
pub font_features: FontFeatures,
|
||||
pub font_size: Rems,
|
||||
pub font_weight: FontWeight,
|
||||
pub font_style: FontStyle,
|
||||
@ -117,6 +110,7 @@ impl Default for TextStyle {
|
||||
TextStyle {
|
||||
color: Hsla::default(),
|
||||
font_family: SharedString::default(),
|
||||
font_features: FontFeatures::default(),
|
||||
font_size: rems(1.),
|
||||
font_weight: FontWeight::default(),
|
||||
font_style: FontStyle::default(),
|
||||
@ -151,7 +145,12 @@ impl TextStyle {
|
||||
|
||||
pub fn to_run(&self) -> RunStyle {
|
||||
RunStyle {
|
||||
font_id: todo!(),
|
||||
font: Font {
|
||||
family: self.font_family.clone(),
|
||||
features: Default::default(),
|
||||
weight: self.font_weight,
|
||||
style: self.font_style,
|
||||
},
|
||||
color: self.color,
|
||||
underline: self.underline.clone(),
|
||||
}
|
||||
@ -170,24 +169,12 @@ pub struct HighlightStyle {
|
||||
impl Eq for HighlightStyle {}
|
||||
|
||||
impl Style {
|
||||
pub fn text_style(&self, _cx: &WindowContext) -> Option<TextStyleRefinement> {
|
||||
if self.text_color.is_none()
|
||||
&& self.font_size.is_none()
|
||||
&& self.font_family.is_none()
|
||||
&& self.font_weight.is_none()
|
||||
&& self.font_style.is_none()
|
||||
{
|
||||
return None;
|
||||
pub fn text_style(&self, _cx: &WindowContext) -> Option<&TextStyleRefinement> {
|
||||
if self.text.is_some() {
|
||||
Some(&self.text)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
Some(TextStyleRefinement {
|
||||
color: self.text_color,
|
||||
font_family: self.font_family.clone(),
|
||||
font_size: self.font_size,
|
||||
font_weight: self.font_weight,
|
||||
font_style: self.font_style,
|
||||
underline: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Paints the background of an element styled with this style.
|
||||
@ -244,11 +231,7 @@ impl Default for Style {
|
||||
fill: None,
|
||||
border_color: None,
|
||||
corner_radii: Corners::default(),
|
||||
text_color: None,
|
||||
font_size: Some(rems(1.)),
|
||||
font_family: None,
|
||||
font_weight: None,
|
||||
font_style: None,
|
||||
text: TextStyleRefinement::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
self as gpui3, relative, rems, AlignItems, Display, Fill, FlexDirection, Hsla, JustifyContent,
|
||||
Length, Position, SharedString, Style, Styled,
|
||||
Length, Position, SharedString, Style, StyleRefinement, Styled, TextStyleRefinement,
|
||||
};
|
||||
|
||||
pub trait StyleHelpers: Styled<Style = Style> {
|
||||
@ -213,12 +213,16 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
self
|
||||
}
|
||||
|
||||
fn text_color<C>(mut self, color: C) -> Self
|
||||
fn text_style(&mut self) -> &mut Option<TextStyleRefinement> {
|
||||
let style: &mut StyleRefinement = self.declared_style();
|
||||
&mut style.text
|
||||
}
|
||||
|
||||
fn text_color(mut self, color: impl Into<Hsla>) -> Self
|
||||
where
|
||||
C: Into<Hsla>,
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().text_color = Some(color.into());
|
||||
self.text_style().get_or_insert_with(Default::default).color = Some(color.into());
|
||||
self
|
||||
}
|
||||
|
||||
@ -226,7 +230,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(0.75));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(0.75));
|
||||
self
|
||||
}
|
||||
|
||||
@ -234,7 +240,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(0.875));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(0.875));
|
||||
self
|
||||
}
|
||||
|
||||
@ -242,7 +250,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(1.0));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(1.0));
|
||||
self
|
||||
}
|
||||
|
||||
@ -250,7 +260,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(1.125));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(1.125));
|
||||
self
|
||||
}
|
||||
|
||||
@ -258,7 +270,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(1.25));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(1.25));
|
||||
self
|
||||
}
|
||||
|
||||
@ -266,7 +280,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(1.5));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(1.5));
|
||||
self
|
||||
}
|
||||
|
||||
@ -274,7 +290,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_size = Some(rems(1.875));
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_size = Some(rems(1.875));
|
||||
self
|
||||
}
|
||||
|
||||
@ -282,7 +300,9 @@ pub trait StyleHelpers: Styled<Style = Style> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.declared_style().font_family = Some(family_name.into());
|
||||
self.text_style()
|
||||
.get_or_insert_with(Default::default)
|
||||
.font_family = Some(family_name.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,9 @@ pub use font_features::*;
|
||||
use line_wrapper::*;
|
||||
pub use text_layout_cache::*;
|
||||
|
||||
use crate::{Hsla, Pixels, PlatformTextSystem, Point, Result, Size, UnderlineStyle};
|
||||
use crate::{
|
||||
Bounds, Hsla, Pixels, PlatformTextSystem, Point, Result, SharedString, Size, UnderlineStyle,
|
||||
};
|
||||
use collections::HashMap;
|
||||
use core::fmt;
|
||||
use parking_lot::Mutex;
|
||||
@ -26,64 +28,25 @@ pub struct FontFamilyId(pub usize);
|
||||
pub struct TextSystem {
|
||||
text_layout_cache: Arc<TextLayoutCache>,
|
||||
platform_text_system: Arc<dyn PlatformTextSystem>,
|
||||
wrapper_pool: Mutex<HashMap<(FontId, Pixels), Vec<LineWrapper>>>,
|
||||
wrapper_pool: Mutex<HashMap<(Font, Pixels), Vec<LineWrapper>>>,
|
||||
}
|
||||
|
||||
impl TextSystem {
|
||||
pub fn new(platform_text_system: Arc<dyn PlatformTextSystem>) -> Self {
|
||||
TextSystem {
|
||||
// font_cache: Arc::new(FontCache::new(platform_text_system.clone())),
|
||||
text_layout_cache: Arc::new(TextLayoutCache::new(platform_text_system.clone())),
|
||||
platform_text_system,
|
||||
wrapper_pool: Mutex::new(HashMap::default()),
|
||||
platform_text_system,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn font_family_name(&self, family_id: FontFamilyId) -> Result<Arc<str>> {
|
||||
todo!()
|
||||
// self.font_cache.family_name(family_id)
|
||||
pub fn select_font(&self, descriptor: impl Into<Font>) -> Result<FontId> {
|
||||
self.platform_text_system.select_font(descriptor.into())
|
||||
}
|
||||
|
||||
pub fn load_font_family(
|
||||
&self,
|
||||
names: &[&str],
|
||||
features: &FontFeatures,
|
||||
) -> Result<FontFamilyId> {
|
||||
todo!()
|
||||
// self.font_cache.load_family(names, features)
|
||||
}
|
||||
|
||||
/// Returns an arbitrary font family that is available on the system.
|
||||
pub fn known_existing_font_family(&self) -> FontFamilyId {
|
||||
todo!()
|
||||
// self.font_cache.known_existing_family()
|
||||
}
|
||||
|
||||
pub fn default_font(&self, family_id: FontFamilyId) -> FontId {
|
||||
todo!()
|
||||
// self.font_cache.default_font(family_id)
|
||||
}
|
||||
|
||||
pub fn select_font(
|
||||
&self,
|
||||
family_id: FontFamilyId,
|
||||
weight: FontWeight,
|
||||
style: FontStyle,
|
||||
) -> Result<FontId> {
|
||||
todo!()
|
||||
// self.font_cache.select_font(family_id, weight, style)
|
||||
}
|
||||
|
||||
// pub fn read_font_metric<F, T>(&self, font_id: FontId, f: F) -> T
|
||||
// where
|
||||
// F: FnOnce(&FontMetrics) -> T,
|
||||
// T: 'static,
|
||||
// {
|
||||
// todo!()
|
||||
// // self.font_cache.read_metric(font_id, f)
|
||||
// }
|
||||
|
||||
pub fn bounding_box(&self, font_id: FontId, font_size: Pixels) -> Size<Pixels> {
|
||||
let metrics = self.platform_text_system.font_metrics(font_id);
|
||||
|
||||
todo!()
|
||||
// self.font_cache.bounding_box(font_id, font_size)
|
||||
}
|
||||
@ -146,11 +109,11 @@ impl TextSystem {
|
||||
self.text_layout_cache.finish_frame()
|
||||
}
|
||||
|
||||
pub fn line_wrapper(self: &Arc<Self>, font_id: FontId, font_size: Pixels) -> LineWrapperHandle {
|
||||
pub fn line_wrapper(self: &Arc<Self>, font: Font, font_size: Pixels) -> LineWrapperHandle {
|
||||
let lock = &mut self.wrapper_pool.lock();
|
||||
let wrappers = lock.entry((font_id, font_size)).or_default();
|
||||
let wrappers = lock.entry((font.clone(), font_size)).or_default();
|
||||
let wrapper = wrappers.pop().unwrap_or_else(|| {
|
||||
LineWrapper::new(font_id, font_size, self.platform_text_system.clone())
|
||||
LineWrapper::new(font, font_size, self.platform_text_system.clone())
|
||||
});
|
||||
|
||||
LineWrapperHandle {
|
||||
@ -170,7 +133,7 @@ impl Drop for LineWrapperHandle {
|
||||
let mut state = self.text_system.wrapper_pool.lock();
|
||||
let wrapper = self.wrapper.take().unwrap();
|
||||
state
|
||||
.get_mut(&(wrapper.font_id, wrapper.font_size))
|
||||
.get_mut(&(wrapper.font.clone(), wrapper.font_size))
|
||||
.unwrap()
|
||||
.push(wrapper);
|
||||
}
|
||||
@ -256,8 +219,8 @@ impl Display for FontStyle {
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct RunStyle {
|
||||
pub font: Font,
|
||||
pub color: Hsla,
|
||||
pub font_id: FontId,
|
||||
pub underline: Option<UnderlineStyle>,
|
||||
}
|
||||
|
||||
@ -305,3 +268,40 @@ pub struct Run {
|
||||
pub font_id: FontId,
|
||||
pub glyphs: Vec<Glyph>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub struct Font {
|
||||
pub family: SharedString,
|
||||
pub features: FontFeatures,
|
||||
pub weight: FontWeight,
|
||||
pub style: FontStyle,
|
||||
}
|
||||
|
||||
pub fn font(family: impl Into<SharedString>) -> Font {
|
||||
Font {
|
||||
family: family.into(),
|
||||
features: FontFeatures::default(),
|
||||
weight: FontWeight::default(),
|
||||
style: FontStyle::default(),
|
||||
}
|
||||
}
|
||||
|
||||
impl Font {
|
||||
pub fn bold(mut self) -> Self {
|
||||
self.weight = FontWeight::BOLD;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct FontMetrics {
|
||||
pub units_per_em: u32,
|
||||
pub ascent: f32,
|
||||
pub descent: f32,
|
||||
pub line_gap: f32,
|
||||
pub underline_position: f32,
|
||||
pub underline_thickness: f32,
|
||||
pub cap_height: f32,
|
||||
pub x_height: f32,
|
||||
pub bounding_box: Bounds<f32>,
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
use super::FontId;
|
||||
use crate::{px, Line, Pixels, PlatformTextSystem, RunStyle, ShapedBoundary};
|
||||
use crate::{px, Font, Line, Pixels, PlatformTextSystem, RunStyle, ShapedBoundary};
|
||||
use collections::HashMap;
|
||||
use std::{iter, sync::Arc};
|
||||
|
||||
pub struct LineWrapper {
|
||||
text_system: Arc<dyn PlatformTextSystem>,
|
||||
pub(crate) font_id: FontId,
|
||||
pub(crate) font: Font,
|
||||
pub(crate) font_size: Pixels,
|
||||
cached_ascii_char_widths: [Option<Pixels>; 128],
|
||||
cached_other_char_widths: HashMap<char, Pixels>,
|
||||
@ -14,14 +13,10 @@ pub struct LineWrapper {
|
||||
impl LineWrapper {
|
||||
pub const MAX_INDENT: u32 = 256;
|
||||
|
||||
pub fn new(
|
||||
font_id: FontId,
|
||||
font_size: Pixels,
|
||||
text_system: Arc<dyn PlatformTextSystem>,
|
||||
) -> Self {
|
||||
pub fn new(font: Font, font_size: Pixels, text_system: Arc<dyn PlatformTextSystem>) -> Self {
|
||||
Self {
|
||||
text_system,
|
||||
font_id,
|
||||
font,
|
||||
font_size,
|
||||
cached_ascii_char_widths: [None; 128],
|
||||
cached_other_char_widths: HashMap::default(),
|
||||
@ -190,7 +185,7 @@ impl LineWrapper {
|
||||
&[(
|
||||
1,
|
||||
RunStyle {
|
||||
font_id: self.font_id,
|
||||
font: self.font.clone(),
|
||||
color: Default::default(),
|
||||
underline: Default::default(),
|
||||
},
|
||||
@ -215,21 +210,17 @@ impl Boundary {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{App, FontFeatures, FontWeight};
|
||||
use crate::{font, App};
|
||||
|
||||
#[test]
|
||||
fn test_wrap_line() {
|
||||
App::test().run(|cx| {
|
||||
let text_system = cx.text_system().clone();
|
||||
let family = text_system
|
||||
.load_font_family(&["Courier"], &Default::default())
|
||||
.unwrap();
|
||||
let font_id = text_system
|
||||
.select_font(family, Default::default(), Default::default())
|
||||
.unwrap();
|
||||
|
||||
let mut wrapper =
|
||||
LineWrapper::new(font_id, px(16.), text_system.platform_text_system.clone());
|
||||
let mut wrapper = LineWrapper::new(
|
||||
font("Courier"),
|
||||
px(16.),
|
||||
text_system.platform_text_system.clone(),
|
||||
);
|
||||
assert_eq!(
|
||||
wrapper
|
||||
.wrap_line("aa bbb cccc ddddd eeee", px(72.))
|
||||
@ -290,21 +281,13 @@ mod tests {
|
||||
App::test().run(|cx| {
|
||||
let text_system = cx.text_system().clone();
|
||||
|
||||
let family = text_system
|
||||
.load_font_family(&["Helvetica"], &FontFeatures::default())
|
||||
.unwrap();
|
||||
let font_id = text_system
|
||||
.select_font(family, Default::default(), Default::default())
|
||||
.unwrap();
|
||||
let normal = RunStyle {
|
||||
font_id,
|
||||
font: font("Helvetica"),
|
||||
color: Default::default(),
|
||||
underline: Default::default(),
|
||||
};
|
||||
let bold = RunStyle {
|
||||
font_id: text_system
|
||||
.select_font(family, FontWeight::BOLD, Default::default())
|
||||
.unwrap(),
|
||||
font: font("Helvetica").bold(),
|
||||
color: Default::default(),
|
||||
underline: Default::default(),
|
||||
};
|
||||
@ -317,13 +300,16 @@ mod tests {
|
||||
(4, normal.clone()),
|
||||
(5, bold.clone()),
|
||||
(6, normal.clone()),
|
||||
(1, bold),
|
||||
(7, normal),
|
||||
(1, bold.clone()),
|
||||
(7, normal.clone()),
|
||||
],
|
||||
);
|
||||
|
||||
let mut wrapper =
|
||||
LineWrapper::new(font_id, px(16.), text_system.platform_text_system.clone());
|
||||
let mut wrapper = LineWrapper::new(
|
||||
normal.font,
|
||||
px(16.),
|
||||
text_system.platform_text_system.clone(),
|
||||
);
|
||||
assert_eq!(
|
||||
wrapper
|
||||
.wrap_shaped_line(text, &line, px(72.))
|
||||
|
@ -139,7 +139,7 @@ impl<'a> PartialEq for CacheKeyRef<'a> {
|
||||
&& self.runs.len() == other.runs.len()
|
||||
&& self.runs.iter().zip(other.runs.iter()).all(
|
||||
|((len_a, style_a), (len_b, style_b))| {
|
||||
len_a == len_b && style_a.font_id == style_b.font_id
|
||||
len_a == len_b && style_a.font == style_b.font
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -151,7 +151,7 @@ impl<'a> Hash for CacheKeyRef<'a> {
|
||||
self.font_size.hash(state);
|
||||
for (len, style_id) in self.runs {
|
||||
len.hash(state);
|
||||
style_id.font_id.hash(state);
|
||||
style_id.font.hash(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user