From e82aa66245935f0aaac61e667a38dce9b5662f42 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 17 Mar 2016 19:50:42 -0700 Subject: [PATCH] Implement more glue methods. --- ports/geckolib/bindings.rs | 11 ++++- ports/geckolib/glue.rs | 94 +++++++++++++++++++++++++++++--------- ports/geckolib/wrapper.rs | 2 +- 3 files changed, 84 insertions(+), 23 deletions(-) diff --git a/ports/geckolib/bindings.rs b/ports/geckolib/bindings.rs index ba761f17d78..545e30d00f7 100644 --- a/ports/geckolib/bindings.rs +++ b/ports/geckolib/bindings.rs @@ -28,6 +28,7 @@ pub type intptr_t = int64_t; pub type uintptr_t = uint64_t; pub type intmax_t = ::libc::c_long; pub type uintmax_t = ::libc::c_ulong; +pub enum nsIAtom { } pub enum nsINode { } pub type RawGeckoNode = nsINode; pub enum Element { } @@ -35,6 +36,7 @@ pub type RawGeckoElement = Element; pub enum nsIDocument { } pub type RawGeckoDocument = nsIDocument; pub enum ServoNodeData { } +pub enum ServoComputedValues { } pub enum RawServoStyleSheet { } pub enum RawServoStyleSet { } extern "C" { @@ -72,7 +74,8 @@ extern "C" { pub fn Servo_StylesheetFromUTF8Bytes(bytes: *const uint8_t, length: uint32_t) -> *mut RawServoStyleSheet; - pub fn Servo_ReleaseStylesheet(sheet: *mut RawServoStyleSheet); + pub fn Servo_AddRefStyleSheet(sheet: *mut RawServoStyleSheet); + pub fn Servo_ReleaseStyleSheet(sheet: *mut RawServoStyleSheet); pub fn Servo_AppendStyleSheet(sheet: *mut RawServoStyleSheet, set: *mut RawServoStyleSet); pub fn Servo_PrependStyleSheet(sheet: *mut RawServoStyleSheet, @@ -82,6 +85,12 @@ extern "C" { pub fn Servo_StyleSheetHasRules(sheet: *mut RawServoStyleSheet) -> bool; pub fn Servo_InitStyleSet() -> *mut RawServoStyleSet; pub fn Servo_DropStyleSet(set: *mut RawServoStyleSet); + pub fn Servo_GetComputedValues(element: *mut RawGeckoElement) + -> *mut ServoComputedValues; + pub fn Servo_GetComputedValuesForAnonymousBox(pseudoTag: *mut nsIAtom) + -> *mut ServoComputedValues; + pub fn Servo_AddRefComputedValues(arg1: *mut ServoComputedValues); + pub fn Servo_ReleaseComputedValues(arg1: *mut ServoComputedValues); pub fn Gecko_GetAttrAsUTF8(element: *mut RawGeckoElement, ns: *const uint8_t, name: *const uint8_t, length: *mut uint32_t) diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 510e39cc041..56c8d9e146c 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -5,24 +5,28 @@ #![allow(unsafe_code)] use app_units::Au; -use bindings::RawGeckoDocument; -use bindings::{ServoNodeData, RawServoStyleSet, RawServoStyleSheet, uint8_t, uint32_t}; +use bindings::{RawGeckoDocument, RawGeckoElement}; +use bindings::{RawServoStyleSet, RawServoStyleSheet, ServoComputedValues, ServoNodeData}; +use bindings::{nsIAtom, uint8_t, uint32_t}; use data::PerDocumentStyleData; use euclid::Size2D; +use properties::GeckoComputedValues; use selector_impl::{SharedStyleContext, Stylesheet}; +use std::marker::PhantomData; use std::mem::{forget, transmute}; +use std::ptr; use std::slice; use std::str::from_utf8_unchecked; use std::sync::{Arc, Mutex}; use style::context::{ReflowGoal, StylistWrapper}; -use style::dom::{TDocument, TNode}; +use style::dom::{TDocument, TElement, TNode}; use style::error_reporting::StdoutErrorReporter; use style::parallel; use style::stylesheets::Origin; use traversal::RecalcStyleOnly; use url::Url; use util::arc_ptr_eq; -use wrapper::{GeckoDocument, GeckoNode, NonOpaqueStyleData}; +use wrapper::{GeckoDocument, GeckoElement, GeckoNode, NonOpaqueStyleData}; /* * For Gecko->Servo function calls, we need to redeclare the same signature that was declared in @@ -82,23 +86,39 @@ pub extern "C" fn Servo_StylesheetFromUTF8Bytes(bytes: *const uint8_t, } } -fn with_arc_stylesheet(raw: *mut RawServoStyleSheet, cb: F) -> Output - where F: FnOnce(&Arc) -> Output { - let owned = unsafe { consume_arc_stylesheet(raw) }; - let result = cb(&owned); - forget(owned); - result +struct ArcHelpers { + phantom1: PhantomData, + phantom2: PhantomData, } -unsafe fn consume_arc_stylesheet(raw: *mut RawServoStyleSheet) -> Arc { - transmute(raw) +impl ArcHelpers { + fn with(raw: *mut GeckoType, cb: F) -> Output + where F: FnOnce(&Arc) -> Output { + let owned = unsafe { Self::into(raw) }; + let result = cb(&owned); + forget(owned); + result + } + + unsafe fn into(ptr: *mut GeckoType) -> Arc { + transmute(ptr) + } + + unsafe fn addref(ptr: *mut GeckoType) { + Self::with(ptr, |arc| forget(arc.clone())); + } + + unsafe fn release(ptr: *mut GeckoType) { + let _ = Self::into(ptr); + } } #[no_mangle] pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet, raw_data: *mut RawServoStyleSet) { + type Helpers = ArcHelpers; let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - with_arc_stylesheet(raw_sheet, |sheet| { + Helpers::with(raw_sheet, |sheet| { data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.push(sheet.clone()); data.stylesheets_changed = true; @@ -108,8 +128,9 @@ pub extern "C" fn Servo_AppendStyleSheet(raw_sheet: *mut RawServoStyleSheet, #[no_mangle] pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet, raw_data: *mut RawServoStyleSet) { + type Helpers = ArcHelpers; let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - with_arc_stylesheet(raw_sheet, |sheet| { + Helpers::with(raw_sheet, |sheet| { data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets.insert(0, sheet.clone()); data.stylesheets_changed = true; @@ -119,8 +140,9 @@ pub extern "C" fn Servo_PrependStyleSheet(raw_sheet: *mut RawServoStyleSheet, #[no_mangle] pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet, raw_data: *mut RawServoStyleSet) { + type Helpers = ArcHelpers; let data = PerDocumentStyleData::borrow_mut_from_raw(raw_data); - with_arc_stylesheet(raw_sheet, |sheet| { + Helpers::with(raw_sheet, |sheet| { data.stylesheets.retain(|x| !arc_ptr_eq(x, sheet)); data.stylesheets_changed = true; }); @@ -128,15 +150,46 @@ pub extern "C" fn Servo_RemoveStyleSheet(raw_sheet: *mut RawServoStyleSheet, #[no_mangle] pub extern "C" fn Servo_StyleSheetHasRules(raw_sheet: *mut RawServoStyleSheet) -> bool { - with_arc_stylesheet(raw_sheet, |sheet| !sheet.rules.is_empty()) + type Helpers = ArcHelpers; + Helpers::with(raw_sheet, |sheet| !sheet.rules.is_empty()) } +#[no_mangle] +pub extern "C" fn Servo_AddRefStyleSheet(sheet: *mut RawServoStyleSheet) -> () { + type Helpers = ArcHelpers; + unsafe { Helpers::addref(sheet) }; +} #[no_mangle] -pub extern "C" fn Servo_ReleaseStylesheet(sheet: *mut RawServoStyleSheet) -> () { - unsafe { - let _ = consume_arc_stylesheet(sheet); - } +pub extern "C" fn Servo_ReleaseStyleSheet(sheet: *mut RawServoStyleSheet) -> () { + type Helpers = ArcHelpers; + unsafe { Helpers::release(sheet) }; +} + +#[no_mangle] +pub extern "C" fn Servo_GetComputedValues(element: *mut RawGeckoElement) + -> *mut ServoComputedValues { + let node = unsafe { GeckoElement::from_raw(element).as_node() }; + let arc_cv = node.borrow_data().map(|data| data.style.clone()); + arc_cv.map_or(ptr::null_mut(), |arc| unsafe { transmute(arc) }) +} + +#[no_mangle] +pub extern "C" fn Servo_GetComputedValuesForAnonymousBox(_: *mut nsIAtom) + -> *mut ServoComputedValues { + unimplemented!(); +} + +#[no_mangle] +pub extern "C" fn Servo_AddRefComputedValues(ptr: *mut ServoComputedValues) -> () { + type Helpers = ArcHelpers; + unsafe { Helpers::addref(ptr) }; +} + +#[no_mangle] +pub extern "C" fn Servo_ReleaseComputedValues(ptr: *mut ServoComputedValues) -> () { + type Helpers = ArcHelpers; + unsafe { Helpers::release(ptr) }; } #[no_mangle] @@ -145,7 +198,6 @@ pub extern "C" fn Servo_InitStyleSet() -> *mut RawServoStyleSet { Box::into_raw(data) as *mut RawServoStyleSet } - #[no_mangle] pub extern "C" fn Servo_DropStyleSet(data: *mut RawServoStyleSet) -> () { unsafe { diff --git a/ports/geckolib/wrapper.rs b/ports/geckolib/wrapper.rs index bdf9cea4259..7262f91e47e 100644 --- a/ports/geckolib/wrapper.rs +++ b/ports/geckolib/wrapper.rs @@ -300,7 +300,7 @@ pub struct GeckoElement<'le> { } impl<'le> GeckoElement<'le> { - unsafe fn from_raw(el: *mut RawGeckoElement) -> GeckoElement<'le> { + pub unsafe fn from_raw(el: *mut RawGeckoElement) -> GeckoElement<'le> { GeckoElement { element: el, chain: PhantomData,