Bug 1341724 - Part 2: stylo: Add bindings for fetching font metrics from Gecko; r?heycam
MozReview-Commit-ID: BkPNq22ruwU
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -307,17 +307,17 @@ nsLayoutStatics::Initialize()
MediaDecoder::InitStatics();
PromiseDebugging::Init();
mozilla::dom::WebCryptoThreadPool::Initialize();
#ifdef MOZ_STYLO
- Servo_Initialize();
+ InitializeServo();
#endif
#ifndef MOZ_WIDGET_ANDROID
// On Android, we instantiate it when constructing AndroidBridge.
MediaPrefs::GetSingleton();
#endif
return NS_OK;
@@ -325,17 +325,17 @@ nsLayoutStatics::Initialize()
void
nsLayoutStatics::Shutdown()
{
// Don't need to shutdown nsWindowMemoryReporter, that will be done by the
// memory reporter manager.
#ifdef MOZ_STYLO
- Servo_Shutdown();
+ ShutdownServo();
#endif
nsMessageManagerScriptExecutor::Shutdown();
nsFocusManager::Shutdown();
#ifdef MOZ_XUL
nsXULPopupManager::Shutdown();
#endif
StorageObserver::Shutdown();
--- a/layout/style/ServoBindings.cpp
+++ b/layout/style/ServoBindings.cpp
@@ -21,30 +21,32 @@
#include "nsIContentInlines.h"
#include "nsIDOMNode.h"
#include "nsIDocument.h"
#include "nsIFrame.h"
#include "nsINode.h"
#include "nsIPresShell.h"
#include "nsIPresShellInlines.h"
#include "nsIPrincipal.h"
+#include "nsFontMetrics.h"
#include "nsMappedAttributes.h"
#include "nsMediaFeatures.h"
#include "nsNameSpaceManager.h"
#include "nsNetUtil.h"
#include "nsRuleNode.h"
#include "nsString.h"
#include "nsStyleStruct.h"
#include "nsStyleUtil.h"
#include "nsTArray.h"
#include "mozilla/EffectCompositor.h"
#include "mozilla/EffectSet.h"
#include "mozilla/EventStates.h"
#include "mozilla/Keyframe.h"
+#include "mozilla/Mutex.h"
#include "mozilla/ServoElementSnapshot.h"
#include "mozilla/ServoRestyleManager.h"
#include "mozilla/StyleAnimationValue.h"
#include "mozilla/SystemGroup.h"
#include "mozilla/DeclarationBlockInlines.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ElementInlines.h"
#include "mozilla/dom/HTMLTableCellElement.h"
@@ -1542,16 +1544,57 @@ Gecko_GetBaseSize(nsIAtom* aLanguage)
sizes.mDefaultSerifSize = prefs.mDefaultSerifFont.size;
sizes.mDefaultSansSerifSize = prefs.mDefaultSansSerifFont.size;
sizes.mDefaultMonospaceSize = prefs.mDefaultMonospaceFont.size;
sizes.mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
sizes.mDefaultFantasySize = prefs.mDefaultFantasyFont.size;
return sizes;
}
+static Mutex* sServoFontMetricsLock = nullptr;
+
+void
+InitializeServo()
+{
+ Servo_Initialize();
+
+ sServoFontMetricsLock = new Mutex("Gecko_GetFontMetrics");
+}
+
+void
+ShutdownServo()
+{
+ delete sServoFontMetricsLock;
+ Servo_Shutdown();
+}
+
+GeckoFontMetrics
+Gecko_GetFontMetrics(RawGeckoPresContextBorrowed aPresContext,
+ bool aIsVertical,
+ const nsStyleFont* aFont,
+ nscoord aFontSize,
+ bool aUseUserFontSet)
+{
+ MutexAutoLock lock(*sServoFontMetricsLock);
+ aPresContext->SetUsesExChUnits(true);
+ GeckoFontMetrics ret;
+ // Safe because we are locked, and this function is only
+ // ever called from Servo parallel traversal
+ MOZ_ASSERT(ServoStyleSet::IsInServoTraversal());
+ nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
+ RefPtr<nsFontMetrics> fm = nsRuleNode::GetMetricsFor(presContext, aIsVertical,
+ aFont, aFontSize,
+ aUseUserFontSet);
+ ret.mXSize = fm->XHeight();
+ gfxFloat zeroWidth = fm->GetThebesFontGroup()->GetFirstValidFont()->
+ GetMetrics(fm->Orientation()).zeroOrAveCharWidth;
+ ret.mChSize = ceil(aPresContext->AppUnitsPerDevPixel() * zeroWidth);
+ return ret;
+}
+
void
Gecko_LoadStyleSheet(css::Loader* aLoader,
ServoStyleSheet* aParent,
RawServoStyleSheetBorrowed aChildSheet,
RawGeckoURLExtraData* aBaseURLData,
const uint8_t* aURLString,
uint32_t aURLStringLength,
const uint8_t* aMediaString,
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -377,16 +377,30 @@ void Gecko_CSSValue_SetInt(nsCSSValueBor
void Gecko_CSSValue_Drop(nsCSSValueBorrowedMut css_value);
NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
bool Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id);
void Gecko_nsStyleFont_SetLang(nsStyleFont* font, nsIAtom* atom);
void Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource);
FontSizePrefs Gecko_GetBaseSize(nsIAtom* lang);
+struct GeckoFontMetrics
+{
+ nscoord mChSize;
+ nscoord mXSize;
+};
+
+GeckoFontMetrics Gecko_GetFontMetrics(RawGeckoPresContextBorrowed pres_context,
+ bool is_vertical,
+ const nsStyleFont* font,
+ nscoord font_size,
+ bool use_user_font_set);
+void InitializeServo();
+void ShutdownServo();
+
const nsMediaFeature* Gecko_GetMediaFeatures();
// Font face rule
// Creates and returns a new (already-addrefed) nsCSSFontFaceRule object.
nsCSSFontFaceRule* Gecko_CSSFontFaceRule_Create();
void Gecko_CSSFontFaceRule_GetCssText(const nsCSSFontFaceRule* rule, nsAString* result);
NS_DECL_FFI_REFCOUNTING(nsCSSFontFaceRule, CSSFontFaceRule);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -609,26 +609,26 @@ static nscoord CalcLengthWith(const nsCS
// CSS2.1 specifies that this unit scales to the computed font
// size, not the em-width in the font metrics, despite the name.
aConditions.SetFontSizeDependency(aFontSize);
return ScaleCoordRound(aValue, float(aFontSize));
}
case eCSSUnit_XHeight: {
aPresContext->SetUsesExChUnits(true);
RefPtr<nsFontMetrics> fm =
- GetMetricsFor(aPresContext, aStyleContext, styleFont,
- aFontSize, aUseUserFontSet);
+ nsRuleNode::GetMetricsFor(aPresContext, aStyleContext, styleFont,
+ aFontSize, aUseUserFontSet);
aConditions.SetUncacheable();
return ScaleCoordRound(aValue, float(fm->XHeight()));
}
case eCSSUnit_Char: {
aPresContext->SetUsesExChUnits(true);
RefPtr<nsFontMetrics> fm =
- GetMetricsFor(aPresContext, aStyleContext, styleFont,
- aFontSize, aUseUserFontSet);
+ nsRuleNode::GetMetricsFor(aPresContext, aStyleContext, styleFont,
+ aFontSize, aUseUserFontSet);
gfxFloat zeroWidth =
fm->GetThebesFontGroup()->GetFirstValidFont()->
GetMetrics(fm->Orientation()).zeroOrAveCharWidth;
aConditions.SetUncacheable();
return ScaleCoordRound(aValue, ceil(aPresContext->AppUnitsPerDevPixel() *
zeroWidth));
}
--- a/servo/components/style/build_gecko.rs
+++ b/servo/components/style/build_gecko.rs
@@ -330,16 +330,17 @@ mod bindings {
"FontFamilyList",
"FontFamilyListRefCnt",
"FontFamilyName",
"FontFamilyType",
"FontSizePrefs",
"FragmentOrURL",
"FrameRequestCallback",
"GeckoParserExtraData",
+ "GeckoFontMetrics",
"gfxAlternateValue",
"gfxFontFeature",
"gfxFontVariation",
"GridNamedArea",
"HalfCorner",
"Image",
"ImageURL",
"Keyframe",
@@ -607,16 +608,17 @@ mod bindings {
"RawGeckoStyleAnimationList",
"RawGeckoURLExtraData",
"RefPtr",
"CSSPseudoClassType",
"TraversalRootBehavior",
"FontFamilyList",
"FontFamilyType",
"FontSizePrefs",
+ "GeckoFontMetrics",
"Keyframe",
"ServoBundledURI",
"ServoElementSnapshot",
"SheetParsingMode",
"StyleBasicShape",
"StyleBasicShapeType",
"StyleShapeSource",
"nsCSSFontFaceRule",
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -19,16 +19,17 @@ use gecko_bindings::structs::RawGeckoPre
use gecko_bindings::structs::RawGeckoStyleAnimationList;
use gecko_bindings::structs::RawGeckoURLExtraData;
use gecko_bindings::structs::RefPtr;
use gecko_bindings::structs::CSSPseudoClassType;
use gecko_bindings::structs::TraversalRootBehavior;
use gecko_bindings::structs::FontFamilyList;
use gecko_bindings::structs::FontFamilyType;
use gecko_bindings::structs::FontSizePrefs;
+use gecko_bindings::structs::GeckoFontMetrics;
use gecko_bindings::structs::Keyframe;
use gecko_bindings::structs::ServoBundledURI;
use gecko_bindings::structs::ServoElementSnapshot;
use gecko_bindings::structs::SheetParsingMode;
use gecko_bindings::structs::StyleBasicShape;
use gecko_bindings::structs::StyleBasicShapeType;
use gecko_bindings::structs::StyleShapeSource;
use gecko_bindings::structs::nsCSSFontFaceRule;
@@ -1020,16 +1021,22 @@ extern "C" {
extern "C" {
pub fn Gecko_nsStyleFont_CopyLangFrom(aFont: *mut nsStyleFont,
aSource: *const nsStyleFont);
}
extern "C" {
pub fn Gecko_GetBaseSize(lang: *mut nsIAtom) -> FontSizePrefs;
}
extern "C" {
+ pub fn Gecko_GetFontMetrics(pres_context: RawGeckoPresContextBorrowed,
+ is_vertical: bool, font: *const nsStyleFont,
+ font_size: nscoord, use_user_font_set: bool)
+ -> GeckoFontMetrics;
+}
+extern "C" {
pub fn Gecko_GetMediaFeatures() -> *const nsMediaFeature;
}
extern "C" {
pub fn Gecko_CSSFontFaceRule_Create() -> *mut nsCSSFontFaceRule;
}
extern "C" {
pub fn Gecko_CSSFontFaceRule_GetCssText(rule: *const nsCSSFontFaceRule,
result: *mut nsAString);
--- a/servo/components/style/gecko_bindings/structs_debug.rs
+++ b/servo/components/style/gecko_bindings/structs_debug.rs
@@ -26817,16 +26817,43 @@ pub mod root {
concat ! (
"Alignment of field: " , stringify ! ( FontSizePrefs ) ,
"::" , stringify ! ( mDefaultFantasySize ) ));
}
impl Clone for FontSizePrefs {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct GeckoFontMetrics {
+ pub mChSize: root::nscoord,
+ pub mXSize: root::nscoord,
+ }
+ #[test]
+ fn bindgen_test_layout_GeckoFontMetrics() {
+ assert_eq!(::std::mem::size_of::<GeckoFontMetrics>() , 8usize , concat
+ ! ( "Size of: " , stringify ! ( GeckoFontMetrics ) ));
+ assert_eq! (::std::mem::align_of::<GeckoFontMetrics>() , 4usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( GeckoFontMetrics ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const GeckoFontMetrics ) ) . mChSize as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( GeckoFontMetrics )
+ , "::" , stringify ! ( mChSize ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const GeckoFontMetrics ) ) . mXSize as *
+ const _ as usize } , 4usize , concat ! (
+ "Alignment of field: " , stringify ! ( GeckoFontMetrics )
+ , "::" , stringify ! ( mXSize ) ));
+ }
+ impl Clone for GeckoFontMetrics {
+ fn clone(&self) -> Self { *self }
+ }
+ #[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct nsROCSSPrimitiveValue([u8; 0]);
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsIDOMCSSFontFaceRule {
pub _base: root::nsISupports,
}
#[repr(C)]
--- a/servo/components/style/gecko_bindings/structs_release.rs
+++ b/servo/components/style/gecko_bindings/structs_release.rs
@@ -26204,16 +26204,43 @@ pub mod root {
concat ! (
"Alignment of field: " , stringify ! ( FontSizePrefs ) ,
"::" , stringify ! ( mDefaultFantasySize ) ));
}
impl Clone for FontSizePrefs {
fn clone(&self) -> Self { *self }
}
#[repr(C)]
+ #[derive(Debug, Copy)]
+ pub struct GeckoFontMetrics {
+ pub mChSize: root::nscoord,
+ pub mXSize: root::nscoord,
+ }
+ #[test]
+ fn bindgen_test_layout_GeckoFontMetrics() {
+ assert_eq!(::std::mem::size_of::<GeckoFontMetrics>() , 8usize , concat
+ ! ( "Size of: " , stringify ! ( GeckoFontMetrics ) ));
+ assert_eq! (::std::mem::align_of::<GeckoFontMetrics>() , 4usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( GeckoFontMetrics ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const GeckoFontMetrics ) ) . mChSize as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( GeckoFontMetrics )
+ , "::" , stringify ! ( mChSize ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const GeckoFontMetrics ) ) . mXSize as *
+ const _ as usize } , 4usize , concat ! (
+ "Alignment of field: " , stringify ! ( GeckoFontMetrics )
+ , "::" , stringify ! ( mXSize ) ));
+ }
+ impl Clone for GeckoFontMetrics {
+ fn clone(&self) -> Self { *self }
+ }
+ #[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct nsROCSSPrimitiveValue([u8; 0]);
#[repr(C)]
#[derive(Debug, Copy)]
pub struct nsIDOMCSSFontFaceRule {
pub _base: root::nsISupports,
}
#[repr(C)]