Skip to content

Commit

Permalink
Auto merge of #7013 - servo:user-stylesheets, r=mbrubeck
Browse files Browse the repository at this point in the history
Make the Ahem font available to test-css and test-wpt tests.

Add support for user stylesheets, and provide one to tests with an `@font-face` rule for it.

Fix #6195.

Many previously-failing tests now pass, and a few previously-passing now fail.

Among the latter, `font-family-013.htm` and `fonts-013.htm` are testing that the Ahem font is not used for characters it doesn’t have a glyph for. They were passing because Ahem was not available at all, and now fail because we don’t implement font fallback correctly.

The others also use Ahem, but I don’t understand yet what’s going on exactly.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7013)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Aug 7, 2015
2 parents da06c2d + 8764f99 commit 8bc1f60
Show file tree
Hide file tree
Showing 472 changed files with 123 additions and 1,484 deletions.
21 changes: 15 additions & 6 deletions components/layout/layout_task.rs
Expand Up @@ -297,6 +297,14 @@ impl<'a> DerefMut for RWGuard<'a> {
}
}

fn add_font_face_rules(stylesheet: &Stylesheet, device: &Device, font_cache_task: &FontCacheTask) {
for font_face in stylesheet.effective_rules(&device).font_face() {
for source in font_face.sources.iter() {
font_cache_task.add_web_font(font_face.family.clone(), source.clone());
}
}
}

impl LayoutTask {
/// Creates a new `LayoutTask` structure.
fn new(id: PipelineId,
Expand Down Expand Up @@ -336,6 +344,11 @@ impl LayoutTask {
let image_cache_receiver =
ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_image_cache_receiver);

let stylist = box Stylist::new(device);
for user_or_user_agent_stylesheet in stylist.stylesheets() {
add_font_face_rules(user_or_user_agent_stylesheet, &stylist.device, &font_cache_task);
}

LayoutTask {
id: id,
url: url,
Expand All @@ -362,7 +375,7 @@ impl LayoutTask {
constellation_chan: constellation_chan,
screen_size: screen_size,
stacking_context: None,
stylist: box Stylist::new(device),
stylist: stylist,
parallel_traversal: parallel_traversal,
dirty: Rect::zero(),
generation: 0,
Expand Down Expand Up @@ -735,11 +748,7 @@ impl LayoutTask {
let mut rw_data = self.lock_rw_data(possibly_locked_rw_data);

if mq.evaluate(&rw_data.stylist.device) {
for font_face in sheet.effective_rules(&rw_data.stylist.device).font_face() {
for source in font_face.sources.iter() {
self.font_cache_task.add_web_font(font_face.family.clone(), source.clone());
}
}
add_font_face_rules(&sheet, &rw_data.stylist.device, &self.font_cache_task);
rw_data.stylist.add_stylesheet(sheet);
}

Expand Down
9 changes: 9 additions & 0 deletions components/servo/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions components/style/selector_matching.rs
Expand Up @@ -12,6 +12,7 @@ use selectors::Element;
use std::process;
use smallvec::VecLike;
use util::resource_files::read_resource_file;
use util::opts;

use legacy::PresentationalHintSynthesis;
use media_queries::Device;
Expand Down Expand Up @@ -76,9 +77,18 @@ impl Stylist {
}
}
}
for &(ref contents, ref url) in &opts::get().user_stylesheets {
stylist.add_stylesheet(Stylesheet::from_bytes(
&contents, url.clone(), None, None, Origin::User));
}
stylist
}

#[inline]
pub fn stylesheets(&self) -> &[Stylesheet] {
&self.stylesheets
}

pub fn constrain_viewport(&self) -> Option<ViewportConstraints> {
let cascaded_rule = self.stylesheets.iter()
.flat_map(|s| s.effective_rules(&self.device).viewport())
Expand Down
1 change: 1 addition & 0 deletions components/util/Cargo.toml
Expand Up @@ -53,3 +53,4 @@ serde = "0.4"
serde_macros = "0.4"
string_cache = "0.1"
lazy_static = "0.1"
getopts = "0.2.11"
1 change: 0 additions & 1 deletion components/util/lib.rs
Expand Up @@ -14,7 +14,6 @@
#![feature(optin_builtin_traits)]
#![feature(path_ext)]
#![feature(plugin)]
#![feature(rustc_private)]
#![feature(slice_splits)]
#![feature(step_by)]
#![feature(step_trait)]
Expand Down
90 changes: 53 additions & 37 deletions components/util/opts.rs
Expand Up @@ -8,13 +8,13 @@
use geometry::ScreenPx;

use euclid::size::{Size2D, TypedSize2D};
use getopts;
use getopts::Options;
use num_cpus;
use std::collections::HashSet;
use std::cmp;
use std::env;
use std::io::{self, Write};
use std::fs::PathExt;
use std::io::{self, Read, Write};
use std::fs::{File, PathExt};
use std::path::Path;
use std::process;
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
Expand Down Expand Up @@ -66,6 +66,8 @@ pub struct Opts {
/// won't be loaded
pub userscripts: Option<String>,

pub user_stylesheets: Vec<(Vec<u8>, Url)>,

pub output_file: Option<String>,

/// Replace unpaires surrogates in DOM strings with U+FFFD.
Expand Down Expand Up @@ -169,9 +171,9 @@ pub struct Opts {
pub exit_after_load: bool,
}

fn print_usage(app: &str, opts: &[getopts::OptGroup]) {
fn print_usage(app: &str, opts: &Options) {
let message = format!("Usage: {} [ options ... ] [URL]\n\twhere options include", app);
println!("{}", getopts::usage(&message, opts));
println!("{}", opts.usage(&message));
}

pub fn print_debug_usage(app: &str) -> ! {
Expand Down Expand Up @@ -237,6 +239,7 @@ pub fn default_opts() -> Opts {
nonincremental_layout: false,
nossl: false,
userscripts: None,
user_stylesheets: Vec::new(),
output_file: None,
replace_surrogates: false,
headless: true,
Expand Down Expand Up @@ -273,37 +276,38 @@ pub fn default_opts() -> Opts {
pub fn from_cmdline_args(args: &[String]) {
let (app_name, args) = args.split_first().unwrap();

let opts = vec!(
getopts::optflag("c", "cpu", "CPU painting (default)"),
getopts::optflag("g", "gpu", "GPU painting"),
getopts::optopt("o", "output", "Output file", "output.png"),
getopts::optopt("s", "size", "Size of tiles", "512"),
getopts::optopt("", "device-pixel-ratio", "Device pixels per px", ""),
getopts::optflag("e", "experimental", "Enable experimental web features"),
getopts::optopt("t", "threads", "Number of paint threads", "1"),
getopts::optflagopt("p", "profile", "Profiler flag and output interval", "10"),
getopts::optflagopt("m", "memory-profile", "Memory profiler flag and output interval", "10"),
getopts::optflag("x", "exit", "Exit after load flag"),
getopts::optopt("y", "layout-threads", "Number of threads to use for layout", "1"),
getopts::optflag("i", "nonincremental-layout", "Enable to turn off incremental layout."),
getopts::optflag("", "no-ssl", "Disables ssl certificate verification."),
getopts::optflagopt("", "userscripts",
"Uses userscripts in resources/user-agent-js, or a specified full path",""),
getopts::optflag("z", "headless", "Headless mode"),
getopts::optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure"),
getopts::optflagopt("", "devtools", "Start remote devtools server on port", "6000"),
getopts::optflagopt("", "webdriver", "Start remote WebDriver server on port", "7000"),
getopts::optopt("", "resolution", "Set window resolution.", "800x600"),
getopts::optopt("u", "user-agent", "Set custom user agent string", "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)"),
getopts::optflag("M", "multiprocess", "Run in multiprocess mode"),
getopts::optopt("Z", "debug",
"A comma-separated string of debug options. Pass help to show available options.", ""),
getopts::optflag("h", "help", "Print this message"),
getopts::optopt("", "resources-path", "Path to find static resources", "/home/servo/resources"),
getopts::optflag("", "sniff-mime-types" , "Enable MIME sniffing"),
);

let opt_match = match getopts::getopts(args, &opts) {
let mut opts = Options::new();
opts.optflag("c", "cpu", "CPU painting (default)");
opts.optflag("g", "gpu", "GPU painting");
opts.optopt("o", "output", "Output file", "output.png");
opts.optopt("s", "size", "Size of tiles", "512");
opts.optopt("", "device-pixel-ratio", "Device pixels per px", "");
opts.optflag("e", "experimental", "Enable experimental web features");
opts.optopt("t", "threads", "Number of paint threads", "1");
opts.optflagopt("p", "profile", "Profiler flag and output interval", "10");
opts.optflagopt("m", "memory-profile", "Memory profiler flag and output interval", "10");
opts.optflag("x", "exit", "Exit after load flag");
opts.optopt("y", "layout-threads", "Number of threads to use for layout", "1");
opts.optflag("i", "nonincremental-layout", "Enable to turn off incremental layout.");
opts.optflag("", "no-ssl", "Disables ssl certificate verification.");
opts.optflagopt("", "userscripts",
"Uses userscripts in resources/user-agent-js, or a specified full path","");
opts.optmulti("", "user-stylesheet",
"A user stylesheet to be added to every document", "file.css");
opts.optflag("z", "headless", "Headless mode");
opts.optflag("f", "hard-fail", "Exit on task failure instead of displaying about:failure");
opts.optflagopt("", "devtools", "Start remote devtools server on port", "6000");
opts.optflagopt("", "webdriver", "Start remote WebDriver server on port", "7000");
opts.optopt("", "resolution", "Set window resolution.", "800x600");
opts.optopt("u", "user-agent", "Set custom user agent string", "NCSA Mosaic/1.0 (X11;SunOS 4.1.4 sun4m)");
opts.optflag("M", "multiprocess", "Run in multiprocess mode");
opts.optopt("Z", "debug",
"A comma-separated string of debug options. Pass help to show available options.", "");
opts.optflag("h", "help", "Print this message");
opts.optopt("", "resources-path", "Path to find static resources", "/home/servo/resources");
opts.optflag("", "sniff-mime-types" , "Enable MIME sniffing");

let opt_match = match opts.parse(args) {
Ok(m) => m,
Err(f) => args_fail(&f.to_string()),
};
Expand All @@ -325,12 +329,12 @@ pub fn from_cmdline_args(args: &[String]) {
print_debug_usage(app_name)
}

let cwd = env::current_dir().unwrap();
let url = if opt_match.free.is_empty() {
print_usage(app_name, &opts);
args_fail("servo asks that you provide a URL")
} else {
let ref url = opt_match.free[0];
let cwd = env::current_dir().unwrap();
match Url::parse(url) {
Ok(url) => url,
Err(url::ParseError::RelativeUrlWithoutBase) => {
Expand Down Expand Up @@ -402,6 +406,17 @@ pub fn from_cmdline_args(args: &[String]) {
}
};

let user_stylesheets = opt_match.opt_strs("user-stylesheet").iter().map(|filename| {
let path = cwd.join(filename);
let url = Url::from_file_path(&path).unwrap();
let mut contents = Vec::new();
File::open(path)
.unwrap_or_else(|err| args_fail(&format!("Couldn’t open {}: {}", filename, err)))
.read_to_end(&mut contents)
.unwrap_or_else(|err| args_fail(&format!("Couldn’t read {}: {}", filename, err)));
(contents, url)
}).collect();

let opts = Opts {
url: Some(url),
paint_threads: paint_threads,
Expand All @@ -415,6 +430,7 @@ pub fn from_cmdline_args(args: &[String]) {
nonincremental_layout: nonincremental_layout,
nossl: nossl,
userscripts: opt_match.opt_default("userscripts", ""),
user_stylesheets: user_stylesheets,
output_file: opt_match.opt_str("o"),
replace_surrogates: debug_options.contains(&"replace-surrogates"),
headless: opt_match.opt_present("z"),
Expand Down
4 changes: 4 additions & 0 deletions resources/ahem.css
@@ -0,0 +1,4 @@
@font-face {
font-family: Ahem;
src: url(ahem/AHEM____.TTF);
}
File renamed without changes.
Binary file added resources/ahem/Ahem.ps
Binary file not shown.
Binary file added resources/ahem/Ahem.sit
Binary file not shown.
1 change: 1 addition & 0 deletions resources/ahem/COPIED-FROM
@@ -0,0 +1 @@
The files in this directory are copied from http://www.w3.org/Style/CSS/Test/Fonts/Ahem/
File renamed without changes.
File renamed without changes.
4 changes: 0 additions & 4 deletions tests/ref/background_image_position_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
font-family: 'ahem';
margin: 0;
Expand Down
5 changes: 0 additions & 5 deletions tests/ref/css/ahem.css
@@ -1,8 +1,3 @@
@font-face {
font-family: 'ahem';
src: url(../fonts/ahem/ahem.ttf);
}

body {
font-family: 'ahem';
font-size: 100px;
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/fixed_width_overrides_child_intrinsic_width_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url('fonts/ahem/ahem.ttf');
}
body {
font-family: 'ahem';
font-size: 100px;
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/float_intrinsic_width_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url('fonts/ahem/ahem.ttf');
}
body {
font-family: 'ahem';
font-size: 100px;
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/float_right_intrinsic_width_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
.fr {
float: right;
}
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/float_table_a.html
Expand Up @@ -4,10 +4,6 @@
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta charset="UTF-8">
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
margin: 0;
}
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/img_block_display_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
margin: 0;
font-family: 'ahem';
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/inline_block_baseline_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
font-family: 'ahem';
font-size: 400px;
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/inline_block_img_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style>
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
margin: 0;
padding: 0;
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/inline_block_margin_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
font-family: 'ahem';
font-size: 100px;
Expand Down
4 changes: 0 additions & 4 deletions tests/ref/inline_block_with_margin_a.html
Expand Up @@ -2,10 +2,6 @@
<html>
<head>
<style type="text/css">
@font-face {
font-family: 'ahem';
src: url(fonts/ahem/ahem.ttf);
}
body {
margin: 0;
font-family: 'ahem';
Expand Down

0 comments on commit 8bc1f60

Please sign in to comment.