mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-08 07:35:01 +03:00
Implement font fallback in layout_line
Co-authored-by: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
6cc9306f00
commit
4249b5687e
@ -13,13 +13,12 @@ use core_foundation::{
|
||||
array::CFIndex,
|
||||
attributed_string::{CFAttributedStringRef, CFMutableAttributedString},
|
||||
base::{CFRange, TCFType},
|
||||
number::CFNumber,
|
||||
string::CFString,
|
||||
};
|
||||
use core_graphics::{
|
||||
base::CGGlyph, color_space::CGColorSpace, context::CGContext, geometry::CGAffineTransform,
|
||||
};
|
||||
use core_text::{line::CTLine, string_attributes::kCTFontAttributeName};
|
||||
use core_text::{font::CTFont, line::CTLine, string_attributes::kCTFontAttributeName};
|
||||
use font_kit::{
|
||||
canvas::RasterizationOptions, handle::Handle, hinting::HintingOptions, source::SystemSource,
|
||||
sources::mem::MemSource,
|
||||
@ -91,7 +90,7 @@ impl platform::FontSystem for FontSystem {
|
||||
}
|
||||
|
||||
fn layout_line(&self, text: &str, font_size: f32, runs: &[(usize, RunStyle)]) -> LineLayout {
|
||||
self.0.read().layout_line(text, font_size, runs)
|
||||
self.0.write().layout_line(text, font_size, runs)
|
||||
}
|
||||
|
||||
fn wrap_line(&self, text: &str, font_id: FontId, font_size: f32, width: f32) -> Vec<usize> {
|
||||
@ -149,6 +148,19 @@ impl FontSystemState {
|
||||
self.fonts[font_id.0].glyph_for_char(ch)
|
||||
}
|
||||
|
||||
fn id_for_font(&mut self, requested_font: font_kit::font::Font) -> FontId {
|
||||
// TODO: don't allocate the postscript name
|
||||
// Note: Coretext always returns a Some option for postscript_name
|
||||
let requested_font_name = requested_font.postscript_name();
|
||||
for (id, font) in self.fonts.iter().enumerate() {
|
||||
if font.postscript_name() == requested_font_name {
|
||||
return FontId(id);
|
||||
}
|
||||
}
|
||||
self.fonts.push(requested_font);
|
||||
FontId(self.fonts.len() - 1)
|
||||
}
|
||||
|
||||
fn rasterize_glyph(
|
||||
&self,
|
||||
font_id: FontId,
|
||||
@ -217,9 +229,12 @@ impl FontSystemState {
|
||||
}
|
||||
}
|
||||
|
||||
fn layout_line(&self, text: &str, font_size: f32, runs: &[(usize, RunStyle)]) -> LineLayout {
|
||||
let font_id_attr_name = CFString::from_static_string("zed_font_id");
|
||||
|
||||
fn layout_line(
|
||||
&mut self,
|
||||
text: &str,
|
||||
font_size: f32,
|
||||
runs: &[(usize, RunStyle)],
|
||||
) -> LineLayout {
|
||||
// Construct the attributed string, converting UTF8 ranges to UTF16 ranges.
|
||||
let mut string = CFMutableAttributedString::new();
|
||||
{
|
||||
@ -269,11 +284,6 @@ impl FontSystemState {
|
||||
kCTFontAttributeName,
|
||||
&font.native_font().clone_with_font_size(font_size as f64),
|
||||
);
|
||||
string.set_attribute(
|
||||
cf_range,
|
||||
font_id_attr_name.as_concrete_TypeRef(),
|
||||
&CFNumber::from(font_id.0 as i64),
|
||||
);
|
||||
}
|
||||
|
||||
if utf16_end == utf16_line_len {
|
||||
@ -287,15 +297,15 @@ impl FontSystemState {
|
||||
|
||||
let mut runs = Vec::new();
|
||||
for run in line.glyph_runs().into_iter() {
|
||||
let font_id = FontId(
|
||||
run.attributes()
|
||||
.unwrap()
|
||||
.get(&font_id_attr_name)
|
||||
.downcast::<CFNumber>()
|
||||
.unwrap()
|
||||
.to_i64()
|
||||
.unwrap() as usize,
|
||||
);
|
||||
let attributes = run.attributes().unwrap();
|
||||
let font = unsafe {
|
||||
let native_font = attributes
|
||||
.get(kCTFontAttributeName)
|
||||
.downcast::<CTFont>()
|
||||
.unwrap();
|
||||
font_kit::font::Font::from_native_font(native_font)
|
||||
};
|
||||
let font_id = self.id_for_font(font);
|
||||
|
||||
let mut ix_converter = StringIndexConverter::new(text);
|
||||
let mut glyphs = Vec::new();
|
||||
|
Loading…
Reference in New Issue
Block a user