зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #7013 - Make the Ahem font available to test-css and test-wpt tests (from servo:user-stylesheets); r=mbrubeck
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. Source-Repo: https://github.com/servo/servo Source-Revision: 08987e3eda370e3eb00876c7f5efdebf3ba0265a
This commit is contained in:
Родитель
47428352a3
Коммит
5a1ac2d8f1
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -462,6 +462,14 @@ dependencies = [
|
|||
"winapi 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getopts"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gfx"
|
||||
version = "0.0.1"
|
||||
|
@ -1521,6 +1529,7 @@ dependencies = [
|
|||
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"html5ever 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||
"js 0.1.0 (git+https://github.com/servo/rust-mozjs)",
|
||||
|
|
|
@ -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;
|
||||
|
@ -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())
|
||||
|
|
|
@ -53,3 +53,4 @@ serde = "0.4"
|
|||
serde_macros = "0.4"
|
||||
string_cache = "0.1"
|
||||
lazy_static = "0.1"
|
||||
getopts = "0.2.11"
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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};
|
||||
|
@ -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.
|
||||
|
@ -172,9 +174,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) -> ! {
|
||||
|
@ -241,6 +243,7 @@ pub fn default_opts() -> Opts {
|
|||
nonincremental_layout: false,
|
||||
nossl: false,
|
||||
userscripts: None,
|
||||
user_stylesheets: Vec::new(),
|
||||
output_file: None,
|
||||
replace_surrogates: false,
|
||||
gc_profile: false,
|
||||
|
@ -278,37 +281,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 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 getopts::getopts(args, &opts) {
|
||||
let opt_match = match opts.parse(args) {
|
||||
Ok(m) => m,
|
||||
Err(f) => args_fail(&f.to_string()),
|
||||
};
|
||||
|
@ -330,12 +334,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) => {
|
||||
|
@ -407,6 +411,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,
|
||||
|
@ -420,6 +435,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"),
|
||||
gc_profile: debug_options.contains(&"gc-profile"),
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
@font-face {
|
||||
font-family: Ahem;
|
||||
src: url(ahem/AHEM____.TTF);
|
||||
}
|
Двоичный файл не отображается.
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Двоичный файл не отображается.
|
@ -0,0 +1 @@
|
|||
The files in this directory are copied from http://www.w3.org/Style/CSS/Test/Fonts/Ahem/
|
|
@ -0,0 +1,36 @@
|
|||
The Ahem font in this directory belongs to the public domain. In
|
||||
jurisdictions that do not recognize public domain ownership of these
|
||||
files, the following Creative Commons Zero declaration applies:
|
||||
|
||||
<http://labs.creativecommons.org/licenses/zero-waive/1.0/us/legalcode>
|
||||
|
||||
which is quoted below:
|
||||
|
||||
The person who has associated a work with this document (the "Work")
|
||||
affirms that he or she (the "Affirmer") is the/an author or owner of
|
||||
the Work. The Work may be any work of authorship, including a
|
||||
database.
|
||||
|
||||
The Affirmer hereby fully, permanently and irrevocably waives and
|
||||
relinquishes all of her or his copyright and related or neighboring
|
||||
legal rights in the Work available under any federal or state law,
|
||||
treaty or contract, including but not limited to moral rights,
|
||||
publicity and privacy rights, rights protecting against unfair
|
||||
competition and any rights protecting the extraction, dissemination
|
||||
and reuse of data, whether such rights are present or future, vested
|
||||
or contingent (the "Waiver"). The Affirmer makes the Waiver for the
|
||||
benefit of the public at large and to the detriment of the Affirmer's
|
||||
heirs or successors.
|
||||
|
||||
The Affirmer understands and intends that the Waiver has the effect
|
||||
of eliminating and entirely removing from the Affirmer's control all
|
||||
the copyright and related or neighboring legal rights previously held
|
||||
by the Affirmer in the Work, to that extent making the Work freely
|
||||
available to the public for any and all uses and purposes without
|
||||
restriction of any kind, including commercial use and uses in media
|
||||
and formats or by methods that have not yet been invented or
|
||||
conceived. Should the Waiver for any reason be judged legally
|
||||
ineffective in any jurisdiction, the Affirmer hereby grants a free,
|
||||
full, permanent, irrevocable, nonexclusive and worldwide license for
|
||||
all her or his copyright and related or neighboring legal rights in
|
||||
the Work.
|
|
@ -0,0 +1,30 @@
|
|||
The Ahem font was developed by Todd Fahrner to help test writers
|
||||
develop predictable tests. The font's em square is exactly square.
|
||||
Its ascent and descent is exactly the size of the em square. This
|
||||
means that the font's extent is exactly the same as its line-height,
|
||||
meaning that it can be exactly aligned with padding, borders, margins,
|
||||
and so forth.
|
||||
|
||||
The font's alphabetic baseline is 0.2em above its bottom, and 0.8em
|
||||
below its top. The font has an x-height of 0.8em.
|
||||
|
||||
The font has four glyphs:
|
||||
|
||||
'X' U+0058 A square exactly 1em in height and width.
|
||||
|
||||
'p' U+0070 A rectangle exactly 0.2em high, 1em wide, and aligned so
|
||||
that its top is flush with the baseline.
|
||||
|
||||
'É' U+00C9 A rectangle exactly 0.8em high, 1em wide, and aligned so
|
||||
that its bottom is flush with the baseline.
|
||||
|
||||
' ' U+0020 A transparent space exactly 1em high and wide.
|
||||
|
||||
Most other US-ASCII characters in the font have the same glyph as X.
|
||||
|
||||
The Ahem font belongs to the public domain as described in COPYING.
|
||||
|
||||
Acknowledgements: The font was originally created by Todd Fahrner in
|
||||
the late 90s, and was updated by Paul Nelson in the mid 2000s. The
|
||||
changes were the introduction of x-height information to the OS/2
|
||||
table and the addition of the space and non-breaking space glyphs.
|
|
@ -19,6 +19,7 @@
|
|||
extern crate png;
|
||||
extern crate test;
|
||||
extern crate url;
|
||||
extern crate util;
|
||||
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
|
@ -257,6 +258,7 @@ fn capture(reftest: &Reftest, side: usize) -> (u32, u32, Vec<u8>) {
|
|||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::null())
|
||||
.args(&reftest.servo_args[..])
|
||||
.arg("--user-stylesheet").arg(util::resource_files::resources_dir_path().join("ahem.css"))
|
||||
// Allows pixel perfect rendering of Ahem font and the HTML canvas for reftests.
|
||||
.arg("-Z")
|
||||
.arg("disable-text-aa,disable-canvas-aa")
|
||||
|
|
Загрузка…
Ссылка в новой задаче