Store resolved font style in canvas context state

This commit is contained in:
Utsav Oza 2020-06-03 15:47:44 +05:30
parent 5493424d9a
commit 15fd256302
11 changed files with 81 additions and 49 deletions

View file

@ -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<Font>,
}
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<f64>) {
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<f64>,
) {
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::<Node>();
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::<Node>();
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

View file

@ -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);

View file

@ -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<f64>) {
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();
}

View file

@ -60,11 +60,6 @@ impl OffscreenCanvasRenderingContext2D {
));
reflect_dom_object(boxed, global)
}
/*
pub fn get_canvas_state(&self) -> Ref<CanvasState> {
self.canvas_state.borrow()
}
*/
pub fn set_canvas_bitmap_dimensions(&self, size: Size2D<u64>) {
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<f64>) {
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

View file

@ -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<ServoArc<ComputedValues>> {
pub fn resolved_font_style_query(&self, node: &Node, value: String) -> Option<ServoArc<Font>> {
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",
},
};