Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify FontHandle and rename it to PlatformFont #32101

Merged
merged 3 commits into from Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 1 addition & 2 deletions components/canvas/canvas_data.rs
Expand Up @@ -14,7 +14,6 @@ use font_kit::font::Font;
use font_kit::metrics::Metrics;
use font_kit::properties::{Properties, Stretch, Style, Weight};
use font_kit::source::SystemSource;
use gfx::font::FontHandleMethods;
use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context::FontContext;
use gfx::font_template::FontTemplateRefMethods;
Expand Down Expand Up @@ -502,7 +501,7 @@ impl<'a> CanvasData<'a> {
.first(font_context)
.expect("couldn't find font");
let font = font.borrow_mut();
Font::from_bytes(font.handle.template().data(), 0)
Font::from_bytes(font.template.data(), 0)
.ok()
.or_else(|| load_system_font_from_style(Some(style)))
})
Expand Down
22 changes: 12 additions & 10 deletions components/gfx/font.rs
Expand Up @@ -27,7 +27,7 @@ use webrender_api::FontInstanceKey;
use crate::font_cache_thread::FontIdentifier;
use crate::font_context::{FontContext, FontSource};
use crate::font_template::{FontTemplateDescriptor, FontTemplateRef};
use crate::platform::font::{FontHandle, FontTable};
use crate::platform::font::{FontTable, PlatformFont};
pub use crate::platform::font_list::fallback_font_families;
use crate::text::glyph::{ByteIndex, GlyphData, GlyphId, GlyphStore};
use crate::text::shaping::ShaperMethods;
Expand All @@ -47,18 +47,17 @@ pub const LAST_RESORT_GLYPH_ADVANCE: FractionalPixel = 10.0;

static TEXT_SHAPING_PERFORMANCE_COUNTER: AtomicUsize = AtomicUsize::new(0);

// FontHandle encapsulates access to the platform's font API,
// PlatformFont encapsulates access to the platform's font API,
// e.g. quartz, FreeType. It provides access to metrics and tables
// needed by the text shaper as well as access to the underlying font
// resources needed by the graphics layer to draw glyphs.

pub trait FontHandleMethods: Sized {
pub trait PlatformFontMethods: Sized {
fn new_from_template(
template: FontTemplateRef,
pt_size: Option<Au>,
) -> Result<Self, &'static str>;

fn template(&self) -> FontTemplateRef;
fn family_name(&self) -> Option<String>;
fn face_name(&self) -> Option<String>;

Expand Down Expand Up @@ -161,7 +160,8 @@ impl<'a> From<&'a FontStyleStruct> for FontDescriptor {

#[derive(Debug)]
pub struct Font {
pub handle: FontHandle,
pub handle: PlatformFont,
pub template: FontTemplateRef,
pub metrics: FontMetrics,
pub descriptor: FontDescriptor,
shaper: Option<Shaper>,
Expand All @@ -177,28 +177,30 @@ pub struct Font {

impl Font {
pub fn new(
handle: FontHandle,
template: FontTemplateRef,
descriptor: FontDescriptor,
font_key: FontInstanceKey,
synthesized_small_caps: Option<FontRef>,
) -> Font {
) -> Result<Font, &'static str> {
let handle = PlatformFont::new_from_template(template.clone(), Some(descriptor.pt_size))?;
let metrics = handle.metrics();

Font {
Ok(Font {
handle,
template,
shaper: None,
descriptor,
metrics,
shape_cache: RefCell::new(HashMap::new()),
glyph_advance_cache: RefCell::new(HashMap::new()),
font_key,
synthesized_small_caps,
}
})
}

/// A unique identifier for the font, allowing comparison.
pub fn identifier(&self) -> FontIdentifier {
self.handle.template().borrow().identifier.clone()
self.template.borrow().identifier.clone()
}
}

Expand Down
13 changes: 4 additions & 9 deletions components/gfx/font_context.rs
Expand Up @@ -17,14 +17,11 @@ use style::computed_values::font_variant_caps::T as FontVariantCaps;
use style::properties::style_structs::Font as FontStyleStruct;
use webrender_api::{FontInstanceKey, FontKey};

use crate::font::{
Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontHandleMethods, FontRef,
};
use crate::font::{Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontRef};
use crate::font_cache_thread::FontTemplateAndWebRenderFontKey;
#[cfg(target_os = "macos")]
use crate::font_template::FontTemplate;
use crate::font_template::FontTemplateDescriptor;
use crate::platform::font::FontHandle;

static SMALL_CAPS_SCALE_FACTOR: f32 = 0.8; // Matches FireFox (see gfxFont.h)

Expand Down Expand Up @@ -214,17 +211,15 @@ impl<S: FontSource> FontContext<S> {
descriptor: FontDescriptor,
synthesized_small_caps: Option<FontRef>,
) -> Result<Font, &'static str> {
let handle = FontHandle::new_from_template(info.font_template, Some(descriptor.pt_size))?;

let font_instance_key = self
.font_source
.get_font_instance(info.font_key, descriptor.pt_size);
Ok(Font::new(
handle,
Font::new(
info.font_template,
descriptor,
font_instance_key,
synthesized_small_caps,
))
)
}
}

Expand Down
8 changes: 4 additions & 4 deletions components/gfx/font_template.rs
Expand Up @@ -16,9 +16,9 @@ use style::properties::style_structs::Font as FontStyleStruct;
use style::values::computed::font::FontWeight;
use webrender_api::NativeFontHandle;

use crate::font::FontHandleMethods;
use crate::font::PlatformFontMethods;
use crate::font_cache_thread::FontIdentifier;
use crate::platform::font::FontHandle;
use crate::platform::font::PlatformFont;

/// A reference to a [`FontTemplate`] with shared ownership and mutability.
pub(crate) type FontTemplateRef = Rc<RefCell<FontTemplate>>;
Expand Down Expand Up @@ -191,10 +191,10 @@ impl FontTemplateRefMethods for FontTemplateRef {
return Err("Invalid font template");
}

let handle = FontHandleMethods::new_from_template(self.clone(), None);
let handle = PlatformFontMethods::new_from_template(self.clone(), None);
let mut template = self.borrow_mut();
template.is_valid = handle.is_ok();
let handle: FontHandle = handle?;
let handle: PlatformFont = handle?;
template.descriptor = Some(FontTemplateDescriptor::new(
handle.boldness(),
handle.stretchiness(),
Expand Down
32 changes: 16 additions & 16 deletions components/gfx/platform/freetype/font.rs
Expand Up @@ -4,6 +4,7 @@

use std::ffi::CString;
use std::os::raw::{c_char, c_long};
use std::sync::Arc;
use std::{mem, ptr};

use app_units::Au;
Expand All @@ -23,7 +24,7 @@ use style::values::computed::font::FontStyle;
use super::c_str_to_string;
use super::library_handle::FreeTypeLibraryHandle;
use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, GPOS, GSUB,
FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, PlatformFontMethods, GPOS, GSUB,
KERN,
};
use crate::font_cache_thread::FontIdentifier;
Expand Down Expand Up @@ -70,15 +71,18 @@ struct OS2Table {

#[derive(Debug)]
#[allow(unused)]
pub struct FontHandle {
// The template contains the font data, which must stay valid for the
// lifetime of the platform [`FT_Face`], if it's created via [`FT_Memory_Face`].
font_template: FontTemplateRef,
pub struct PlatformFont {
/// The font data itself, which must stay valid for the lifetime of the
/// platform [`FT_Face`], if it's created via [`FT_Memory_Face`]. A reference
mrobinson marked this conversation as resolved.
Show resolved Hide resolved
/// to this data is also stored in the [`crate::font::Font`] that holds
/// this [`PlatformFont`], but if it's ever separated from it's font,
/// this ensures the data stays alive.
font_data: Option<Arc<Vec<u8>>>,
face: FT_Face,
can_do_fast_shaping: bool,
}

impl Drop for FontHandle {
impl Drop for PlatformFont {
fn drop(&mut self) {
assert!(!self.face.is_null());
unsafe {
Expand Down Expand Up @@ -134,22 +138,22 @@ fn create_face(template: &FontTemplateRef, pt_size: Option<Au>) -> Result<FT_Fac
}

if let Some(s) = pt_size {
FontHandle::set_char_size(face, s)?
PlatformFont::set_char_size(face, s)?
}

Ok(face)
}
}

impl FontHandleMethods for FontHandle {
impl PlatformFontMethods for PlatformFont {
fn new_from_template(
template: FontTemplateRef,
pt_size: Option<Au>,
) -> Result<FontHandle, &'static str> {
) -> Result<PlatformFont, &'static str> {
let face = create_face(&template, pt_size)?;
let mut handle = FontHandle {
let mut handle = PlatformFont {
face,
font_template: template.clone(),
font_data: template.borrow().data_if_in_memory(),
can_do_fast_shaping: false,
};
// TODO (#11310): Implement basic support for GPOS and GSUB.
Expand All @@ -158,10 +162,6 @@ impl FontHandleMethods for FontHandle {
Ok(handle)
}

fn template(&self) -> FontTemplateRef {
self.font_template.clone()
}

fn family_name(&self) -> Option<String> {
unsafe {
let family_name = (*self.face).family_name;
Expand Down Expand Up @@ -362,7 +362,7 @@ impl FontHandleMethods for FontHandle {
}
}

impl<'a> FontHandle {
impl<'a> PlatformFont {
fn set_char_size(face: FT_Face, pt_size: Au) -> Result<(), &'static str> {
let char_size = pt_size.to_f64_px() * 64.0 + 0.5;

Expand Down
18 changes: 10 additions & 8 deletions components/gfx/platform/macos/font.rs
Expand Up @@ -22,7 +22,7 @@ use style::values::computed::font::{FontStretch, FontStyle, FontWeight};

use super::font_template::CoreTextFontTemplateMethods;
use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, GPOS, GSUB,
FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, PlatformFontMethods, GPOS, GSUB,
KERN,
};
use crate::font_template::FontTemplateRef;
Expand Down Expand Up @@ -52,14 +52,16 @@ impl FontTableMethods for FontTable {
}

#[derive(Debug)]
pub struct FontHandle {
font_template: FontTemplateRef,
pub struct PlatformFont {
ctfont: CTFont,
/// A reference to this data used to create this [`PlatformFont`], ensuring the
/// data stays alive of the lifetime of this struct.
data: Option<Arc<Vec<u8>>>,
h_kern_subtable: Option<CachedKernTable>,
can_do_fast_shaping: bool,
}

impl FontHandle {
impl PlatformFont {
/// Cache all the data needed for basic horizontal kerning. This is used only as a fallback or
/// fast path (when the GPOS table is missing or unnecessary) so it needn't handle every case.
fn find_h_kern_subtable(&self) -> Option<CachedKernTable> {
Expand Down Expand Up @@ -154,11 +156,11 @@ impl fmt::Debug for CachedKernTable {
}
}

impl FontHandleMethods for FontHandle {
impl PlatformFontMethods for PlatformFont {
fn new_from_template(
font_template: FontTemplateRef,
pt_size: Option<Au>,
) -> Result<FontHandle, &'static str> {
) -> Result<PlatformFont, &'static str> {
let size = match pt_size {
Some(s) => s.to_f64_px(),
None => 0.0,
Expand All @@ -167,8 +169,8 @@ impl FontHandleMethods for FontHandle {
return Err("Could not generate CTFont for FontTemplateData");
};

let mut handle = FontHandle {
font_template,
let mut handle = PlatformFont {
data: font_template.data_if_in_memory(),
ctfont: core_text_font.clone_with_font_size(size),
h_kern_subtable: None,
can_do_fast_shaping: false,
Expand Down
27 changes: 14 additions & 13 deletions components/gfx/platform/windows/font.rs
Expand Up @@ -18,7 +18,7 @@ use style::values::computed::font::FontStyle as StyleFontStyle;
use style::values::specified::font::FontStretchKeyword;

use crate::font::{
FontHandleMethods, FontMetrics, FontTableMethods, FontTableTag, FractionalPixel,
FontMetrics, FontTableMethods, FontTableTag, FractionalPixel, PlatformFontMethods,
};
use crate::font_cache_thread::FontIdentifier;
use crate::font_template::{FontTemplateRef, FontTemplateRefMethods};
Expand Down Expand Up @@ -198,9 +198,11 @@ impl FontInfo {
}

#[derive(Debug)]
pub struct FontHandle {
font_template: FontTemplateRef,
pub struct PlatformFont {
face: Nondebug<FontFace>,
/// A reference to this data used to create this [`PlatformFont`], ensuring the
/// data stays alive of the lifetime of this struct.
data: Option<Arc<Vec<u8>>>,
info: FontInfo,
em_size: f32,
du_to_px: f32,
Expand All @@ -222,9 +224,7 @@ impl<T> Deref for Nondebug<T> {
}
}

impl FontHandle {}

impl FontHandleMethods for FontHandle {
impl PlatformFontMethods for PlatformFont {
fn new_from_template(
font_template: FontTemplateRef,
pt_size: Option<Au>,
Expand All @@ -234,8 +234,12 @@ impl FontHandleMethods for FontHandle {
FontIdentifier::Web(_) => None,
};

let (face, info) = match direct_write_font {
Some(font) => (font.create_font_face(), FontInfo::new_from_font(&font)?),
let (face, info, data) = match direct_write_font {
Some(font) => (
font.create_font_face(),
FontInfo::new_from_font(&font)?,
None,
),
None => {
let bytes = font_template.data();
let font_file =
Expand All @@ -257,20 +261,17 @@ impl FontHandleMethods for FontHandle {
let design_units_to_pixels = 1. / design_units_per_pixel;
let scaled_design_units_to_pixels = em_size / design_units_per_pixel;

Ok(FontHandle {
Ok(PlatformFont {
font_template,
face: Nondebug(face),
data,
info,
em_size,
du_to_px: design_units_to_pixels,
scaled_du_to_px: scaled_design_units_to_pixels,
})
}

fn template(&self) -> FontTemplateRef {
self.font_template.clone()
}

fn family_name(&self) -> Option<String> {
Some(self.info.family_name.clone())
}
Expand Down