From 15fd256302cc4401e0c4e2d154d473bfaa16223d Mon Sep 17 00:00:00 2001 From: Utsav Oza Date: Wed, 3 Jun 2020 15:47:44 +0530 Subject: [PATCH] Store resolved font style in canvas context state --- components/layout/query.rs | 21 ++++++----- components/layout_2020/query.rs | 12 +++++-- components/layout_thread/lib.rs | 15 ++++---- components/layout_thread_2020/lib.rs | 6 ++-- components/script/canvas_state.rs | 35 +++++++++++++------ components/script/dom/bindings/trace.rs | 2 ++ .../script/dom/canvasrenderingcontext2d.rs | 3 +- .../dom/offscreencanvasrenderingcontext2d.rs | 13 +++---- components/script/dom/window.rs | 11 +++--- components/script_layout_interface/message.rs | 6 ++-- components/script_layout_interface/rpc.rs | 6 ++-- 11 files changed, 81 insertions(+), 49 deletions(-) diff --git a/components/layout/query.rs b/components/layout/query.rs index fb73e8d1e41..56b1fc7d0f8 100644 --- a/components/layout/query.rs +++ b/components/layout/query.rs @@ -40,9 +40,10 @@ use style::computed_values::visibility::T as Visibility; use style::context::{QuirksMode, SharedStyleContext, StyleContext, ThreadLocalStyleContext}; use style::dom::TElement; use style::logical_geometry::{BlockFlowDirection, InlineBaseDirection, WritingMode}; +use style::properties::style_structs::{self, Font}; use style::properties::{ - parse_one_declaration_into, style_structs, ComputedValues, Importance, LonghandId, - PropertyDeclarationBlock, PropertyDeclarationId, PropertyId, SourcePropertyDeclaration, + parse_one_declaration_into, ComputedValues, Importance, LonghandId, PropertyDeclarationBlock, + PropertyDeclarationId, PropertyId, SourcePropertyDeclaration, }; use style::selector_parser::PseudoElement; use style::shared_lock::SharedRwLock; @@ -80,7 +81,7 @@ pub struct LayoutThreadData { pub resolved_style_response: String, /// A queued response for the resolved font style for canvas. - pub parse_font_response: Option>, + pub resolved_font_style_response: Option>, /// A queued response for the offset parent/rect of a node. pub offset_parent_response: OffsetParentResponse, @@ -179,10 +180,10 @@ impl LayoutRPC for LayoutRPCImpl { ResolvedStyleResponse(rw_data.resolved_style_response.clone()) } - fn parsed_font(&self) -> Option> { + fn resolved_font_style(&self) -> Option> { let &LayoutRPCImpl(ref rw_data) = self; let rw_data = rw_data.lock().unwrap(); - rw_data.parse_font_response.clone() + rw_data.resolved_font_style_response.clone() } fn offset_parent(&self) -> OffsetParentResponse { @@ -800,14 +801,14 @@ where ) } -pub fn process_parse_font_request<'dom, E>( +pub fn process_resolved_font_style_request<'dom, E>( context: &LayoutContext, node: E, value: &str, property: &PropertyId, url_data: ServoUrl, shared_lock: &SharedRwLock, -) -> Option> +) -> Option> where E: LayoutNode<'dom>, { @@ -846,12 +847,14 @@ where }; // 3. Resolve the parsed value with resolved styles of the parent element - Some(resolve_for_declarations::( + let computed_values = resolve_for_declarations::( &context.style_context, Some(&*parent_style), declarations, shared_lock, - )) + ); + + Some(computed_values.clone_font()) } /// Return the resolved value of property for a given (pseudo)element. diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index 704dad8db56..a8a27a30faa 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -28,7 +28,8 @@ use style::computed_values::position::T as Position; use style::context::{StyleContext, ThreadLocalStyleContext}; use style::dom::OpaqueNode; use style::dom::TElement; -use style::properties::{ComputedValues, LonghandId, PropertyDeclarationId, PropertyId}; +use style::properties::style_structs::Font; +use style::properties::{LonghandId, PropertyDeclarationId, PropertyId}; use style::selector_parser::PseudoElement; use style::stylist::RuleInclusion; use style::traversal::resolve_style; @@ -66,6 +67,9 @@ pub struct LayoutThreadData { /// A queued response for the resolved style property of an element. pub resolved_style_response: String, + /// A queued response for the resolved font style for canvas. + pub resolved_font_style_response: Option>, + /// A queued response for the offset parent/rect of a node. pub offset_parent_response: OffsetParentResponse, @@ -140,8 +144,10 @@ impl LayoutRPC for LayoutRPCImpl { ResolvedStyleResponse(rw_data.resolved_style_response.clone()) } - fn parsed_font(&self) -> Option> { - unimplemented!() + fn resolved_font_style(&self) -> Option> { + let &LayoutRPCImpl(ref rw_data) = self; + let rw_data = rw_data.lock().unwrap(); + rw_data.resolved_font_style_response.clone() } fn offset_parent(&self) -> OffsetParentResponse { diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 9ae955789a9..14dbfc0c80e 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -52,8 +52,9 @@ use layout::parallel; use layout::query::{ process_client_rect_query, process_content_box_request, process_content_boxes_request, process_element_inner_text_query, process_node_scroll_area_request, - process_node_scroll_id_request, process_offset_parent_query, process_parse_font_request, - process_resolved_style_request, LayoutRPCImpl, LayoutThreadData, + process_node_scroll_id_request, process_offset_parent_query, + process_resolved_font_style_request, process_resolved_style_request, LayoutRPCImpl, + LayoutThreadData, }; use layout::sequential; use layout::traversal::{ @@ -558,7 +559,7 @@ impl LayoutThread { scroll_id_response: None, scroll_area_response: Rect::zero(), resolved_style_response: String::new(), - parse_font_response: None, + resolved_font_style_response: None, offset_parent_response: OffsetParentResponse::empty(), scroll_offsets: HashMap::new(), text_index_response: TextIndexResponse(None), @@ -1232,8 +1233,8 @@ impl LayoutThread { &QueryMsg::ElementInnerTextQuery(_) => { rw_data.element_inner_text_response = String::new(); }, - &QueryMsg::ParseFontQuery(..) => { - rw_data.parse_font_response = None; + &QueryMsg::ResolvedFontStyleQuery(..) => { + rw_data.resolved_font_style_response = None; }, &QueryMsg::InnerWindowDimensionsQuery(_) => { rw_data.inner_window_dimensions_response = None; @@ -1555,10 +1556,10 @@ impl LayoutThread { rw_data.resolved_style_response = process_resolved_style_request(context, node, pseudo, property, root_flow); }, - &QueryMsg::ParseFontQuery(node, ref property, ref value) => { + &QueryMsg::ResolvedFontStyleQuery(node, ref property, ref value) => { let node = unsafe { ServoLayoutNode::new(&node) }; let url = self.url.clone(); - rw_data.parse_font_response = process_parse_font_request( + rw_data.resolved_font_style_response = process_resolved_font_style_request( context, node, value, diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index ae154e0dd4d..bdfb75a2323 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -914,7 +914,9 @@ impl LayoutThread { &QueryMsg::ResolvedStyleQuery(_, _, _) => { rw_data.resolved_style_response = String::new(); }, - &QueryMsg::ParseFontQuery(_, _, _) => unimplemented!(), + &QueryMsg::ResolvedFontStyleQuery(_, _, _) => { + rw_data.resolved_font_style_response = None; + }, &QueryMsg::OffsetParentQuery(_) => { rw_data.offset_parent_response = OffsetParentResponse::empty(); }, @@ -1207,7 +1209,7 @@ impl LayoutThread { fragment_tree, ); }, - &QueryMsg::ParseFontQuery(_, _, _) => unimplemented!(), + &QueryMsg::ResolvedFontStyleQuery(_, _, _) => unimplemented!(), &QueryMsg::OffsetParentQuery(node) => { rw_data.offset_parent_response = process_offset_parent_query(node); }, diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index 5550ff10fc3..dc40ad3203d 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -49,6 +49,7 @@ use std::cell::Cell; use std::fmt; use std::str::FromStr; use std::sync::Arc; +use style::properties::style_structs::Font; #[unrooted_must_root_lint::must_root] #[derive(Clone, JSTraceable, MallocSizeOf)] @@ -86,6 +87,7 @@ pub(crate) struct CanvasContextState { shadow_offset_y: f64, shadow_blur: f64, shadow_color: RGBA, + font_style: Option, } impl CanvasContextState { @@ -106,6 +108,7 @@ impl CanvasContextState { shadow_offset_y: 0.0, shadow_blur: 0.0, shadow_color: RGBA::transparent(), + font_style: None, } } } @@ -987,9 +990,18 @@ impl CanvasState { } // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext - pub fn fill_text(&self, text: DOMString, x: f64, y: f64, max_width: Option) { - let is_max_width_finite = max_width.map_or(true, |max_width| max_width.is_finite()); - if !(x.is_finite() && y.is_finite() && is_max_width_finite) { + pub fn fill_text( + &self, + _canvas: Option<&HTMLCanvasElement>, + text: DOMString, + x: f64, + y: f64, + max_width: Option, + ) { + if !x.is_finite() || !y.is_finite() { + return; + } + if max_width.map_or(false, |max_width| !max_width.is_finite() || max_width <= 0.) { return; } @@ -1008,14 +1020,17 @@ impl CanvasState { // https://html.spec.whatwg.org/multipage/#dom-context-2d-font pub fn set_font(&self, canvas: Option<&HTMLCanvasElement>, value: DOMString) { - let _resolved_font = if let Some(element) = canvas { - let node = element.upcast::(); - let window = window_from_node(&*node); - window.parse_font_query(&node, value.to_string()) - } else { - None + let canvas = match canvas { + Some(element) => element, + None => return, }; - unimplemented!() + let node = canvas.upcast::(); + let window = window_from_node(&*canvas); + let font_style = match window.resolved_font_style_query(&node, value.to_string()) { + Some(value) => value, + None => return, // syntax error + }; + self.state.borrow_mut().font_style = Some((*font_style).clone()); } // https://html.spec.whatwg.org/multipage/#dom-context-2d-font diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 1f6d15a191a..f80a7e57c93 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -144,6 +144,7 @@ use style::context::QuirksMode; use style::dom::OpaqueNode; use style::element_state::*; use style::media_queries::MediaList; +use style::properties::style_structs::Font; use style::properties::PropertyDeclarationBlock; use style::selector_parser::{PseudoElement, Snapshot}; use style::shared_lock::{Locked as StyleLocked, SharedRwLock as StyleSharedRwLock}; @@ -479,6 +480,7 @@ unsafe_no_jsmanaged_fields!(NetworkError); unsafe_no_jsmanaged_fields!(Atom, Prefix, LocalName, Namespace, QualName); unsafe_no_jsmanaged_fields!(TrustedPromise); unsafe_no_jsmanaged_fields!(PropertyDeclarationBlock); +unsafe_no_jsmanaged_fields!(Font); // These three are interdependent, if you plan to put jsmanaged data // in one of these make sure it is propagated properly to containing structs unsafe_no_jsmanaged_fields!(DocumentActivity, WindowSizeData, WindowSizeType); diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 3e0df6bb4b9..c8838fe283e 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -288,7 +288,8 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D { // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option) { - self.canvas_state.fill_text(text, x, y, max_width); + self.canvas_state + .fill_text(self.canvas.as_ref().map(|c| &**c), text, x, y, max_width); self.mark_as_dirty(); } diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs index d36785d71f6..ee9c010c391 100644 --- a/components/script/dom/offscreencanvasrenderingcontext2d.rs +++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs @@ -60,11 +60,6 @@ impl OffscreenCanvasRenderingContext2D { )); reflect_dom_object(boxed, global) } - /* - pub fn get_canvas_state(&self) -> Ref { - self.canvas_state.borrow() - } - */ pub fn set_canvas_bitmap_dimensions(&self, size: Size2D) { self.canvas_state.set_bitmap_dimensions(size); @@ -249,7 +244,13 @@ impl OffscreenCanvasRenderingContext2DMethods for OffscreenCanvasRenderingContex // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option) { - self.canvas_state.fill_text(text, x, y, max_width) + self.canvas_state.fill_text( + self.htmlcanvas.as_ref().map(|c| &**c), + text, + x, + y, + max_width, + ) } // https://html.spec.whatwg.org/multipage/#textmetrics diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 25198c7e16e..d7fde4f27d5 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -137,7 +137,8 @@ use style::dom::OpaqueNode; use style::error_reporting::{ContextualParseError, ParseErrorReporter}; use style::media_queries; use style::parser::ParserContext as CssParserContext; -use style::properties::{ComputedValues, PropertyId, ShorthandId}; +use style::properties::style_structs::Font; +use style::properties::{PropertyId, ShorthandId}; use style::selector_parser::PseudoElement; use style::str::HTML_SPACE_CHARACTERS; use style::stylesheets::CssRuleType; @@ -1848,16 +1849,16 @@ impl Window { ) } - pub fn parse_font_query(&self, node: &Node, value: String) -> Option> { + pub fn resolved_font_style_query(&self, node: &Node, value: String) -> Option> { let id = PropertyId::Shorthand(ShorthandId::Font); - if !self.layout_reflow(QueryMsg::ParseFontQuery( + if !self.layout_reflow(QueryMsg::ResolvedFontStyleQuery( node.to_trusted_node_address(), id, value, )) { return None; } - self.layout_rpc.parsed_font() + self.layout_rpc.resolved_font_style() } pub fn layout(&self) -> &dyn LayoutRPC { @@ -2513,11 +2514,11 @@ fn debug_reflow_events(id: PipelineId, reflow_goal: &ReflowGoal, reason: &Reflow &QueryMsg::NodeScrollGeometryQuery(_n) => "\tNodeScrollGeometryQuery", &QueryMsg::NodeScrollIdQuery(_n) => "\tNodeScrollIdQuery", &QueryMsg::ResolvedStyleQuery(_, _, _) => "\tResolvedStyleQuery", + &QueryMsg::ResolvedFontStyleQuery(..) => "\nResolvedFontStyleQuery", &QueryMsg::OffsetParentQuery(_n) => "\tOffsetParentQuery", &QueryMsg::StyleQuery => "\tStyleQuery", &QueryMsg::TextIndexQuery(..) => "\tTextIndexQuery", &QueryMsg::ElementInnerTextQuery(_) => "\tElementInnerTextQuery", - &QueryMsg::ParseFontQuery(..) => "\nParseFontQuery", &QueryMsg::InnerWindowDimensionsQuery(_) => "\tInnerWindowDimensionsQuery", }, }; diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index 5cd6c66345f..724cd2b79e7 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -117,7 +117,7 @@ pub enum QueryMsg { ResolvedStyleQuery(TrustedNodeAddress, Option, PropertyId), StyleQuery, ElementInnerTextQuery(TrustedNodeAddress), - ParseFontQuery(TrustedNodeAddress, PropertyId, String), + ResolvedFontStyleQuery(TrustedNodeAddress, PropertyId, String), InnerWindowDimensionsQuery(BrowsingContextId), } @@ -146,7 +146,7 @@ impl ReflowGoal { QueryMsg::NodeScrollGeometryQuery(_) | QueryMsg::NodeScrollIdQuery(_) | QueryMsg::ResolvedStyleQuery(..) | - QueryMsg::ParseFontQuery(..) | + QueryMsg::ResolvedFontStyleQuery(..) | QueryMsg::OffsetParentQuery(_) | QueryMsg::StyleQuery => false, }, @@ -168,7 +168,7 @@ impl ReflowGoal { QueryMsg::NodeScrollGeometryQuery(_) | QueryMsg::NodeScrollIdQuery(_) | QueryMsg::ResolvedStyleQuery(..) | - QueryMsg::ParseFontQuery(..) | + QueryMsg::ResolvedFontStyleQuery(..) | QueryMsg::OffsetParentQuery(_) | QueryMsg::InnerWindowDimensionsQuery(_) | QueryMsg::StyleQuery => false, diff --git a/components/script_layout_interface/rpc.rs b/components/script_layout_interface/rpc.rs index f21982475cb..232fecabe6b 100644 --- a/components/script_layout_interface/rpc.rs +++ b/components/script_layout_interface/rpc.rs @@ -7,7 +7,7 @@ use euclid::default::Rect; use euclid::Size2D; use script_traits::UntrustedNodeAddress; use servo_arc::Arc; -use style::properties::ComputedValues; +use style::properties::style_structs::Font; use style_traits::CSSPixel; use webrender_api::ExternalScrollId; @@ -32,8 +32,8 @@ pub trait LayoutRPC { fn node_scroll_id(&self) -> NodeScrollIdResponse; /// Query layout for the resolved value of a given CSS property fn resolved_style(&self) -> ResolvedStyleResponse; - /// Query layout to get the parsed font property for canvas. - fn parsed_font(&self) -> Option>; + /// Query layout to get the resolved font style for canvas. + fn resolved_font_style(&self) -> Option>; fn offset_parent(&self) -> OffsetParentResponse; fn text_index(&self) -> TextIndexResponse; /// Requests the list of nodes from the given point.