mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
layout: Add a FontMetricsProvider
for resolving font-relative units (#31966)
The only font relative unit that Servo knows how to resolve currently is `rem` (relative to the root font size). This is because Stylo cannot do any font queries. This adds a mechanism to allow this, exposing the ability to properly render `ex` units in Servo. This change only allows resolving some font size relative units thoug, as Servo doesn't collect all the FontMetrics it needs to resolve them all. This capability will be added in followup changes. Some new tests fail: - ex-unit-001.html: This test fails because Servo does not yet have support for setting the weight using @font-face rules on web fonts. - ex-unit-004.html: This test fails because Servo does not yet have support for setting the Unicode range of a web font using @font-face rules. - first-available-font-001.html: This test fails because the above two feature are missing.
This commit is contained in:
parent
24c3a2df1e
commit
fe8b23d14a
98 changed files with 208 additions and 232 deletions
|
@ -12,7 +12,7 @@ use msg::constellation_msg::PipelineId;
|
|||
use net_traits::image_cache::{
|
||||
ImageCache, ImageCacheResult, ImageOrMetadataAvailable, UsePlaceholder,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use parking_lot::{ReentrantMutex, RwLock};
|
||||
use script_layout_interface::{PendingImage, PendingImageState};
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use style::context::SharedStyleContext;
|
||||
|
@ -20,6 +20,8 @@ use style::dom::OpaqueNode;
|
|||
|
||||
use crate::display_list::WebRenderImageInfo;
|
||||
|
||||
thread_local!(static FONT_CONTEXT: RefCell<Option<FontContext<FontCacheThread>>> = RefCell::new(None));
|
||||
|
||||
pub struct LayoutContext<'a> {
|
||||
pub id: PipelineId,
|
||||
pub use_rayon: bool,
|
||||
|
@ -28,8 +30,8 @@ pub struct LayoutContext<'a> {
|
|||
/// Bits shared by the layout and style system.
|
||||
pub style_context: SharedStyleContext<'a>,
|
||||
|
||||
/// Interface to the font cache thread.
|
||||
pub font_cache_thread: Mutex<FontCacheThread>,
|
||||
/// A FontContext to be used during layout.
|
||||
pub font_cache_thread: Arc<ReentrantMutex<FontCacheThread>>,
|
||||
|
||||
/// Reference to the script thread image cache.
|
||||
pub image_cache: Arc<dyn ImageCache>,
|
||||
|
@ -131,19 +133,27 @@ impl<'a> LayoutContext<'a> {
|
|||
None | Some(ImageOrMetadataAvailable::MetadataAvailable(_)) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_font_context<F, R>(&self, callback: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut FontContext<FontCacheThread>) -> R,
|
||||
{
|
||||
with_thread_local_font_context(&self.font_cache_thread, callback)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) type LayoutFontContext = FontContext<FontCacheThread>;
|
||||
|
||||
thread_local!(static FONT_CONTEXT: RefCell<Option<LayoutFontContext>> = RefCell::new(None));
|
||||
|
||||
pub(crate) fn with_thread_local_font_context<F, R>(layout_context: &LayoutContext, f: F) -> R
|
||||
pub fn with_thread_local_font_context<F, R>(
|
||||
font_cache_thread: &ReentrantMutex<FontCacheThread>,
|
||||
callback: F,
|
||||
) -> R
|
||||
where
|
||||
F: FnOnce(&mut LayoutFontContext) -> R,
|
||||
F: FnOnce(&mut FontContext<FontCacheThread>) -> R,
|
||||
{
|
||||
FONT_CONTEXT.with(|font_context| {
|
||||
f(font_context.borrow_mut().get_or_insert_with(|| {
|
||||
FontContext::new(layout_context.font_cache_thread.lock().unwrap().clone())
|
||||
}))
|
||||
callback(
|
||||
font_context
|
||||
.borrow_mut()
|
||||
.get_or_insert_with(|| FontContext::new(font_cache_thread.lock().clone())),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1597,11 +1597,10 @@ impl InlineFormattingContext {
|
|||
|
||||
// It's unfortunate that it isn't possible to get this during IFC text processing, but in
|
||||
// that situation the style of the containing block is unknown.
|
||||
let default_font_metrics =
|
||||
crate::context::with_thread_local_font_context(layout_context, |font_context| {
|
||||
get_font_for_first_font_for_style(style, font_context)
|
||||
.map(|font| font.borrow().metrics.clone())
|
||||
});
|
||||
let default_font_metrics = layout_context.with_font_context(|font_context| {
|
||||
get_font_for_first_font_for_style(style, font_context)
|
||||
.map(|font| font.borrow().metrics.clone())
|
||||
});
|
||||
|
||||
let mut ifc = InlineFormattingContextState {
|
||||
positioning_context,
|
||||
|
@ -1725,7 +1724,7 @@ impl InlineFormattingContext {
|
|||
// For the purposes of `text-transform: capitalize` the start of the IFC is a word boundary.
|
||||
let mut on_word_boundary = true;
|
||||
|
||||
crate::context::with_thread_local_font_context(layout_context, |font_context| {
|
||||
layout_context.with_font_context(|font_context| {
|
||||
let mut linebreaker = None;
|
||||
self.foreach(|iter_item| match iter_item {
|
||||
InlineFormattingContextIterItem::Item(InlineLevelBox::TextRun(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue